@getbourdon/participants 0.5.5 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/base.ts","../src/sqlite-base.ts","../src/network-base.ts","../src/readers/hermes.ts","../src/readers/claude-code.ts","../src/readers/github-copilot.ts","../src/readers/cursor.ts","../src/readers/copilot.ts","../src/readers/copilot-cli.ts","../src/readers/cascade.ts","../src/readers/openclaw.ts","../src/readers/claude-code-automations.ts","../src/readers/codex-automations.ts","../src/readers/copilot-automations.ts","../src/readers/cursor-automations.ts","../src/readers/claude-desktop-code.ts","../src/readers/claude-desktop-cowork.ts","../src/readers/copilot-vscode.ts","../src/readers/codex-sessions.ts","../src/readers/bolt.ts","../src/export-store-base.ts","../src/readers/lovable.ts","../src/readers/v0.ts","../src/registry.ts"],"sourcesContent":["// SPDX-License-Identifier: BUSL-1.1\n/**\n * @getbourdon/participants — the external-agent → L5 reader layer (BUSL-1.1).\n *\n * Each participant normalizes a foreign agent's native memory store into a\n * visibility-filtered, redacted L5 manifest. Reader categories:\n * - SQLite (read-only, better-sqlite3 mode=ro): {@link HermesParticipant},\n * {@link CursorParticipant}, {@link CopilotCliParticipant}\n * - file / convention: {@link ClaudeCodeParticipant},\n * {@link CopilotParticipant}, {@link CascadeParticipant}\n * - network (TTL cache + lazy AuthProvider): {@link GitHubCopilotParticipant}\n * - network + quarantined-class (handshake gate): {@link OpenClawParticipant}\n *\n * Four invariants enforced in code, not by trust: visibility-filter-before-\n * emission, deterministic exportL5, healthCheck never throws, redact every\n * native string. Discovery is a static registry ({@link discoverParticipants}).\n *\n * Python (`pip install bourdon`) is the oracle; this mirror asserts against the\n * @getbourdon/conformance `native_stores` fixtures (output shape only).\n * Still deferred: codex (the ~2.6k-line turn-compiler reader) lands in a\n * follow-on slice.\n */\n\n// Contract surface: Protocol interface, errors, AgentStore + HealthStatus.\nexport {\n CONTRACT_VERSION,\n SPEC_VERSION,\n ParticipantError,\n ParticipantDiscoveryError,\n ParticipantExportError,\n ParticipantVersionMismatchError,\n isParticipant,\n loadProjectHints,\n PROJECT_HINTS_ENV,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"./base.js\";\n\n// SQLite read-only primitives.\nexport {\n sqliteAvailable,\n openReadonly,\n tryOpenReadonly,\n tableExists,\n tableColumns,\n epochToIsoDate,\n epochToIsoDatetime,\n projectKeyFromCwd,\n friendlyLabel,\n type OpenReadonlyOptions,\n type SqliteDatabase,\n} from \"./sqlite-base.js\";\n\n// Network base: TTL cache, AuthProvider, degrade-to-stale-cache, auth boundary.\nexport {\n NETWORK_CONTRACT_VERSION,\n DEFAULT_CACHE_TTL_SECONDS,\n NetworkUnavailable,\n ParticipantAuthError,\n NetworkParticipant,\n PayloadCache,\n CacheEntry,\n envAuthProvider,\n defaultCacheRoot,\n type AuthProvider,\n type NetworkParticipantOptions,\n} from \"./network-base.js\";\n\n// Readers.\nexport { HermesParticipant } from \"./readers/hermes.js\";\nexport { ClaudeCodeParticipant } from \"./readers/claude-code.js\";\nexport { GitHubCopilotParticipant, ghTokenProvider } from \"./readers/github-copilot.js\";\nexport { CursorParticipant } from \"./readers/cursor.js\";\nexport { CopilotParticipant } from \"./readers/copilot.js\";\nexport { CopilotCliParticipant } from \"./readers/copilot-cli.js\";\nexport { CascadeParticipant } from \"./readers/cascade.js\";\nexport {\n OpenClawParticipant,\n OpenClawApiClient,\n verifyInstance,\n MIN_PATCHED_VERSION,\n} from \"./readers/openclaw.js\";\n// Background-run \"automations\" variants (publish automation-run memory as L5 evidence).\nexport { ClaudeCodeAutomationsParticipant } from \"./readers/claude-code-automations.js\";\nexport { CodexAutomationsParticipant } from \"./readers/codex-automations.js\";\nexport { CopilotAutomationsParticipant } from \"./readers/copilot-automations.js\";\nexport { CursorAutomationsParticipant } from \"./readers/cursor-automations.js\";\n// Claude desktop surfaces + VS Code Copilot.\nexport { ClaudeDesktopCodeParticipant } from \"./readers/claude-desktop-code.js\";\nexport { ClaudeDesktopCoworkParticipant } from \"./readers/claude-desktop-cowork.js\";\nexport { CopilotVscodeParticipant } from \"./readers/copilot-vscode.js\";\n// Codex session-index title lookup (NOT the full codex reader — only the\n// tray/presence `session_id -> thread_name` surface).\nexport {\n DEFAULT_RECENT_THREAD_LIMIT,\n DEFAULT_TITLE_LIMIT,\n parseSessionIndex,\n recentSessionThreads,\n resolveCodexHome,\n sessionThreadTitles,\n} from \"./readers/codex-sessions.js\";\nexport type { RecentThread } from \"./readers/codex-sessions.js\";\n\n// Discovery (static registry).\nexport {\n FIRST_PARTY,\n discoverParticipants,\n resolvePluginParticipants,\n type ParticipantCtor,\n} from \"./registry.js\";\n\n// Re-exported from @getbourdon/l5 for convenience (the L5 model + serialization\n// the readers build on; only this output shape is the parity contract).\nexport {\n Visibility,\n applyVisibility,\n filterForFederation,\n toDict,\n validateManifest,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\n\n// The JSON export-store family — cloud builders that persist nothing locally\n// and federate through an exported directory. The shared mechanics live in\n// export-store-base.ts; each reader keeps its OWN entity/session mapper,\n// because the oracle's three differ in ways that are not cosmetic.\nexport {\n ExportStoreParticipant,\n isoDate,\n parseVisibility,\n safeStr,\n safeStrList,\n type ExportStoreConfig,\n} from \"./export-store-base.js\";\nexport { BOLT_CONFIG, BoltParticipant } from \"./readers/bolt.js\";\nexport { LOVABLE_CONFIG, LovableParticipant } from \"./readers/lovable.js\";\nexport { V0_CONFIG, V0Participant } from \"./readers/v0.js\";\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Bourdon participant base — the Protocol → TS interface, errors, and the\n * AgentStore / HealthStatus types. Faithful port of `participants/base.py`.\n *\n * The L5 dataclass model (AgentInfo/Entity/Session/VisibilityPolicy/L5Manifest),\n * the `toDict` omission rules, and the visibility helpers all live in\n * `@getbourdon/l5` and are reused verbatim — only THAT output shape is the parity\n * contract. This module owns the participant CONTRACT surface around them.\n *\n * Contract semantics (enforced by every reader, asserted by the conformance\n * fixtures, never by trust):\n * 1. visibility filter BEFORE emission (`filterForFederation`) — private wins.\n * 2. deterministic / idempotent `exportL5` — same store → identical `toDict`.\n * 3. `healthCheck` NEVER throws — catch-all → degraded/blocked.\n * 4. every native string through `@getbourdon/redaction` before it enters L5.\n */\n\nimport type { L5ManifestModel, SessionModel } from \"@getbourdon/l5\";\n\n/** Tied to Bourdon spec v0.1 — same literals as the Python oracle. */\nexport const CONTRACT_VERSION = \"0.1\";\nexport const SPEC_VERSION = \"0.1\";\n\n// -- Errors -------------------------------------------------------------------\n\n/** Base class for participant errors. */\nexport class ParticipantError extends Error {\n constructor(message?: string) {\n super(message);\n this.name = new.target.name;\n }\n}\n\n/** Raised by `discover()` when the native store cannot be found or read.\n * Non-fatal: L6 skips this agent rather than aborting the whole export. */\nexport class ParticipantDiscoveryError extends ParticipantError {}\n\n/** Raised by `exportL5()` / `exportSessions()` when an export fails mid-op\n * (the store WAS present — distinct from a discovery miss). */\nexport class ParticipantExportError extends ParticipantError {}\n\n/** Raised when the native store's version is outside the supported range.\n * Subtype of discovery error (a version mismatch is a discovery-time miss). */\nexport class ParticipantVersionMismatchError extends ParticipantDiscoveryError {}\n\n// -- Data types ---------------------------------------------------------------\n\n/** Metadata describing the native agent store. Returned by `discover()`. */\nexport interface AgentStore {\n path: string;\n version: string;\n metadata: Record<string, unknown>;\n}\n\n/** Returned by `healthCheck()`. Consumed by the `bourdon doctor` CLI. */\nexport interface HealthStatus {\n status: \"ok\" | \"degraded\" | \"blocked\";\n reason?: string;\n details: Record<string, unknown>;\n /** A human-runnable command to remedy a non-ok status. */\n proposedFix?: string;\n}\n\n// -- Protocol -----------------------------------------------------------------\n\n/**\n * Structural interface every participant must satisfy (the Python\n * `@runtime_checkable Protocol`). Duck-typed at registration: a class is a\n * participant iff it has `agentId` + `agentType` + `exportL5` + `healthCheck`.\n *\n * Optional members (`displayName`, a `defaultNativePath` static) are documented\n * here as in the Python Protocol; discovery + the setup wizard fall back to\n * sensible defaults when absent.\n */\nexport interface BourdonParticipant {\n agentId: string;\n agentType: string;\n nativePath: string;\n\n /** Human-friendly label (e.g. \"GitHub Copilot\"). Optional. */\n displayName?: string;\n\n /** Quarantined-class marker (Python `QUARANTINED_CLASS`). When true, the CLI\n * requires `--i-understand-the-risk` to register the agent trusted, and its\n * exports are staged for operator review rather than written to the live\n * store (spec D6: quarantine follows the content, not the invoker). Absent =\n * a normal, non-quarantined participant. Read by `bourdon agent add/set-tier`\n * (cli/src/commands/federation.ts). */\n quarantinedClass?: boolean;\n\n /** Confirm the native store exists; return metadata. Throws\n * {@link ParticipantDiscoveryError} when missing/unreadable. */\n discover(): AgentStore;\n\n /** Build the L5 manifest from native memory, applying the visibility filter\n * BEFORE return. Deterministic — same store yields the same manifest. */\n exportL5(since?: Date): L5ManifestModel;\n\n /** Export recent sessions in normalized schema. */\n exportSessions(since?: Date, limit?: number): SessionModel[];\n\n /** Return ok / degraded / blocked with a reason. MUST NOT throw. */\n healthCheck(): HealthStatus;\n}\n\n/**\n * Tiny structural guard mirroring Python's `_PARTICIPANT_MARKER_ATTRS`\n * duck-type: a value is a participant iff it carries the four marker members.\n */\nexport function isParticipant(obj: unknown): obj is BourdonParticipant {\n if (obj === null || typeof obj !== \"object\") return false;\n const o = obj as Record<string, unknown>;\n return (\n typeof o[\"agentId\"] === \"string\" &&\n typeof o[\"agentType\"] === \"string\" &&\n typeof o[\"exportL5\"] === \"function\" &&\n typeof o[\"healthCheck\"] === \"function\"\n );\n}\n\n/**\n * Environment variable holding the deployment's own project-name recognition\n * vocabulary, as a comma-separated list (e.g.\n * `BOURDON_PROJECT_HINTS=\"Acme Portal,Widget API,internal-tools\"`).\n */\nexport const PROJECT_HINTS_ENV = \"BOURDON_PROJECT_HINTS\";\n\n/**\n * Project-name hints used to tag sessions with a project focus.\n *\n * Bourdon ships **no** project roster of its own — the `defaults` a reader\n * passes are limited to product-neutral names (this product, plus the agent\n * surfaces it federates). A deployment that wants its own projects recognized\n * sets {@link PROJECT_HINTS_ENV}; those entries are appended to `defaults`.\n *\n * Matching downstream is case-insensitive substring matching, so entries are\n * de-duplicated case-insensitively here while preserving first-seen order and\n * the original casing (which is what gets emitted as the project name).\n *\n * Mirrors Python `participants.base.load_project_hints`.\n */\nexport function loadProjectHints(\n defaults: readonly string[] = [],\n): readonly string[] {\n const hints: string[] = [];\n const seen = new Set<string>();\n const raw = process.env[PROJECT_HINTS_ENV] ?? \"\";\n for (const candidate of [...defaults, ...raw.split(\",\")]) {\n const name = candidate.trim();\n if (!name) continue;\n const key = name.toLowerCase();\n if (seen.has(key)) continue;\n seen.add(key);\n hints.push(name);\n }\n return hints;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Shared read-only SQLite + normalization helpers — port of\n * `participants/_sqlite_base.py`.\n *\n * A SQLite-backed participant (hermes today; cursor/copilot_cli in the follow-on\n * slice) reads a foreign agent's native DB read-only so a live writer's lock can\n * never block the export, probes the schema defensively (native schemas drift\n * across versions), and turns epoch timestamps + paths into the L5 shapes.\n *\n * `better-sqlite3` is a NATIVE addon. It is loaded lazily through `createRequire`\n * inside a try/catch so this package — and the file/network readers — keep\n * working even on a toolchain where the addon failed to build: in that case\n * {@link sqliteAvailable} returns false and the sqlite readers degrade rather\n * than crashing import. Nothing here applies visibility or builds manifests;\n * that stays in the participant (per PARTICIPANT_CONTRACT.md).\n */\n\nimport { statSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\n\nimport type DatabaseT from \"better-sqlite3\";\n\n/** A better-sqlite3 connection (re-exported type alias for reader signatures). */\nexport type SqliteDatabase = DatabaseT.Database;\n\n// `import.meta.url` in ESM; esbuild empties it in the CJS bundle, where the\n// native `__filename` global is the real path — fall back to it so createRequire\n// resolves better-sqlite3 from either module format.\ndeclare const __filename: string | undefined;\nconst moduleUrl =\n (typeof import.meta !== \"undefined\" && import.meta.url) ||\n (typeof __filename !== \"undefined\" ? __filename : process.cwd());\nconst nodeRequire = createRequire(moduleUrl);\n\nlet driver: typeof DatabaseT | null | undefined;\nlet nativeAvailable: boolean | undefined;\n\n/** Lazily resolve the better-sqlite3 constructor, or null if the addon is\n * unavailable (failed native build). Cached after the first attempt. */\nfunction loadDriver(): typeof DatabaseT | null {\n if (driver !== undefined) return driver;\n try {\n driver = nodeRequire(\"better-sqlite3\") as typeof DatabaseT;\n } catch {\n driver = null;\n }\n return driver;\n}\n\n/** True when the native addon can open and close a disposable in-memory DB. */\nexport function sqliteAvailable(): boolean {\n if (nativeAvailable !== undefined) return nativeAvailable;\n const Ctor = loadDriver();\n if (!Ctor) return (nativeAvailable = false);\n try {\n const probe = new Ctor(\":memory:\");\n probe.close();\n nativeAvailable = true;\n } catch {\n nativeAvailable = false;\n }\n return nativeAvailable;\n}\n\nexport interface OpenReadonlyOptions {\n /** `immutable=1`: skip locks + ignore the WAL. Only for genuinely static\n * snapshots; against a live writer it risks stale reads / SQLITE_CORRUPT. */\n immutable?: boolean;\n /** SQLite busy-timeout in milliseconds (Python's `timeout=2.0` seconds). */\n timeoutMs?: number;\n}\n\n// -- Read-only connection -----------------------------------------------------\n\n/**\n * Open a SQLite DB read-only so a live writer is never disturbed. The default\n * (`immutable` omitted) is the safe `mode=ro`: it respects SQLite locking and\n * reads the `-wal` sidecar of a live, actively-writing agent. Raises on a\n * genuine open failure; callers wanting the never-raises contract use\n * {@link tryOpenReadonly}.\n */\nexport function openReadonly(dbPath: string, opts: OpenReadonlyOptions = {}): SqliteDatabase {\n const Ctor = loadDriver();\n if (!Ctor) {\n throw new Error(\"better-sqlite3 native addon is not available\");\n }\n // better-sqlite3 maps `{readonly:true}` to SQLITE_OPEN_READONLY. There is no\n // first-class `immutable=1` knob; for our static snapshots `readonly` is\n // sufficient (we never open a concurrently-written fixture DB).\n return new Ctor(dbPath, {\n readonly: true,\n fileMustExist: true,\n timeout: opts.timeoutMs ?? 2000,\n });\n}\n\n/**\n * Like {@link openReadonly} but returns null instead of raising — for the\n * export/health path where a missing or corrupt DB must degrade to \"no rows\".\n */\nexport function tryOpenReadonly(\n dbPath: string,\n opts: OpenReadonlyOptions = {},\n): SqliteDatabase | null {\n try {\n if (!statSync(dbPath).isFile()) return null;\n } catch {\n return null;\n }\n try {\n return openReadonly(dbPath, opts);\n } catch {\n return null;\n }\n}\n\n// -- Defensive schema probes --------------------------------------------------\n\n/** True if `name` is a table in the connected DB (swallows errors → false). */\nexport function tableExists(db: SqliteDatabase, name: string): boolean {\n try {\n const row = db\n .prepare(\"SELECT 1 FROM sqlite_master WHERE type='table' AND name=? LIMIT 1\")\n .get(name);\n return row !== undefined;\n } catch {\n return false;\n }\n}\n\n/** Column names for `table` (empty set if absent / on error). PRAGMA cannot be\n * parameterized, matching the Python f-string. */\nexport function tableColumns(db: SqliteDatabase, table: string): Set<string> {\n try {\n const rows = db.prepare(`PRAGMA table_info(${table})`).all() as Array<{ name: string }>;\n return new Set(rows.map((r) => r.name));\n } catch {\n return new Set<string>();\n }\n}\n\n// -- Normalization ------------------------------------------------------------\n\nfunction toFiniteNumber(value: unknown): number | null {\n if (value === null || value === undefined) return null;\n const n = typeof value === \"number\" ? value : Number(value);\n return Number.isFinite(n) ? n : null;\n}\n\n/**\n * Convert epoch seconds (number/string) to an ISO `YYYY-MM-DD` UTC date, or\n * null for missing/unparseable values. Mirrors `epoch_to_iso_date`.\n */\nexport function epochToIsoDate(value: unknown): string | null {\n const n = toFiniteNumber(value);\n if (n === null) return null;\n const d = new Date(n * 1000);\n if (Number.isNaN(d.getTime())) return null;\n return d.toISOString().slice(0, 10);\n}\n\n/**\n * Convert epoch seconds to a full ISO 8601 UTC datetime, or null. The offset is\n * rendered `+00:00` (Python `datetime(...).isoformat()` style) rather than `Z`.\n */\nexport function epochToIsoDatetime(value: unknown): string | null {\n const n = toFiniteNumber(value);\n if (n === null) return null;\n const d = new Date(n * 1000);\n if (Number.isNaN(d.getTime())) return null;\n return d\n .toISOString()\n .replace(/\\.\\d{3}Z$/, \"+00:00\")\n .replace(/Z$/, \"+00:00\");\n}\n\nfunction basenameOf(p: string): string {\n const trimmed = p.replace(/[\\\\/]+$/, \"\");\n const parts = trimmed.split(/[\\\\/]/);\n return parts[parts.length - 1] ?? \"\";\n}\n\n/**\n * Derive a lowercase project key from a working-directory path: the basename\n * lowercased, or null when the cwd is empty or its basename is \"generic\"\n * (carries no project identity). Mirrors `project_key_from_cwd`.\n */\nexport function projectKeyFromCwd(\n cwd: string | null | undefined,\n genericNames: ReadonlySet<string> = new Set(),\n): string | null {\n if (!cwd) return null;\n const name = basenameOf(cwd).trim().toLowerCase();\n if (!name || genericNames.has(name)) return null;\n return name;\n}\n\n/** Turn a slug-ish key (`my-cool_project`) into a Title Case label. */\nexport function friendlyLabel(key: string): string {\n return key\n .replace(/[-_]+/g, \" \")\n .trim()\n .replace(/\\S+/g, (w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase());\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Network-shaped participant base — port of `participants/_network_base.py`\n * (v0.3 adapter contract). Same `exportL5` / `exportSessions` half as a file\n * participant; only the discovery half differs (fetch from an authenticated\n * API). The base provides the three guarantees so adapters don't reimplement:\n *\n * 1. Local TTL cache under `~/.cache/bourdon/<slug>/payload.json` storing ONLY\n * `{fetched_at, payload}` — NEVER the token. A cache hit = zero network.\n * 2. Graceful degradation: network down → serve the most recent cached payload\n * (even expired) and report `degraded` (not silence).\n * 3. Auth boundary: an injected lazy {@link AuthProvider} (env / keychain).\n * An invalid token (401/403 non-ratelimit) ALWAYS propagates as `blocked`\n * and is NEVER masked by stale cache; a missing token serves stale when a\n * cache exists, else blocks; rate-limit degrades.\n *\n * A subclass sets `participantSlug` / `agentId` / `agentType` (+ `nativePath`)\n * and implements `fetchPayload(token)` + `payloadToL5(payload)` (pure, no I/O).\n */\n\nimport { mkdirSync, readFileSync, renameSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport type { L5ManifestModel, SessionModel } from \"@getbourdon/l5\";\n\nimport {\n ParticipantError,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"./base.js\";\n\nexport const NETWORK_CONTRACT_VERSION = \"0.3\";\n/** Default cache TTL — adapters override via `cacheTtlSeconds`. */\nexport const DEFAULT_CACHE_TTL_SECONDS = 15 * 60; // 15 minutes\n\n// -- Network-specific errors --------------------------------------------------\n\n/** Transport failure / timeout / 5xx / rate-limit — recoverable via cache fallback. */\nexport class NetworkUnavailable extends ParticipantError {}\n\n/** 401/403 / missing credential — NOT recoverable via cache. The user must fix\n * auth; surfaced as `blocked`, never silently served from stale cache (stale\n * data would mask a broken token indefinitely). */\nexport class ParticipantAuthError extends ParticipantError {}\n\n// -- Auth provider ------------------------------------------------------------\n\n/** A zero-arg callable returning the token string, or null if no credential is\n * available. Kept a callable (not a bare string) so the token is fetched lazily\n * at call time and never sits in the participant's fields or the cache. */\nexport type AuthProvider = () => string | null;\n\n/** Auth provider that reads a token from an environment variable. */\nexport function envAuthProvider(varName: string): AuthProvider {\n return () => process.env[varName] || null;\n}\n\n// -- Cache --------------------------------------------------------------------\n\n/** `$XDG_CACHE_HOME/bourdon` or `~/.cache/bourdon`. */\nexport function defaultCacheRoot(): string {\n const xdg = process.env.XDG_CACHE_HOME;\n const base = xdg ? xdg : join(homedir(), \".cache\");\n return join(base, \"bourdon\");\n}\n\n/** A cached payload + the wall-clock time it was fetched (epoch seconds). */\nexport class CacheEntry {\n constructor(\n readonly fetchedAt: number,\n readonly payload: Record<string, unknown>,\n ) {}\n\n get ageSeconds(): number {\n return Math.max(0, Date.now() / 1000 - this.fetchedAt);\n }\n\n isFresh(ttlSeconds: number): boolean {\n return this.ageSeconds < ttlSeconds;\n }\n}\n\n/**\n * A tiny JSON file cache, one file per participant slug. Stores only\n * `{fetched_at, payload}` — never the auth token. Read/write are best-effort: a\n * corrupt or unwritable cache degrades to \"no cache\", never raises.\n */\nexport class PayloadCache {\n readonly slug: string;\n readonly root: string;\n readonly path: string;\n\n constructor(slug: string, rootDir?: string) {\n this.slug = slug;\n this.root = join(rootDir ?? defaultCacheRoot(), slug);\n this.path = join(this.root, \"payload.json\");\n }\n\n read(): CacheEntry | null {\n let raw: unknown;\n try {\n raw = JSON.parse(readFileSync(this.path, \"utf8\"));\n } catch {\n return null;\n }\n if (typeof raw !== \"object\" || raw === null || !(\"payload\" in raw)) return null;\n const obj = raw as Record<string, unknown>;\n let fetchedAt = Number(obj[\"fetched_at\"] ?? 0);\n if (!Number.isFinite(fetchedAt)) fetchedAt = 0;\n const payload = obj[\"payload\"];\n if (typeof payload !== \"object\" || payload === null || Array.isArray(payload)) return null;\n return new CacheEntry(fetchedAt, payload as Record<string, unknown>);\n }\n\n write(payload: Record<string, unknown>): void {\n try {\n mkdirSync(this.root, { recursive: true });\n const tmp = `${this.path}.tmp`;\n writeFileSync(tmp, JSON.stringify({ fetched_at: Date.now() / 1000, payload }), \"utf8\");\n renameSync(tmp, this.path); // atomic\n } catch {\n /* best-effort; a write failure degrades to \"no cache\" */\n }\n }\n}\n\nexport interface NetworkParticipantOptions {\n authProvider?: AuthProvider | null;\n cacheRoot?: string;\n}\n\n// -- Base participant ---------------------------------------------------------\n\n/**\n * Base for participants whose native state lives behind an authenticated API.\n * Caching, degradation, the auth boundary, and the\n * `discover`/`exportL5`/`exportSessions`/`healthCheck` plumbing live here;\n * subclasses provide only `fetchPayload` + `payloadToL5`.\n */\nexport abstract class NetworkParticipant implements BourdonParticipant {\n participantSlug = \"network\";\n agentId = \"network\";\n agentType = \"other\";\n cacheTtlSeconds: number = DEFAULT_CACHE_TTL_SECONDS;\n nativePath = \"network://\";\n\n protected readonly authProvider: AuthProvider | null;\n private readonly cacheRoot?: string;\n private cacheInstance?: PayloadCache;\n\n constructor(opts: NetworkParticipantOptions = {}) {\n this.authProvider = opts.authProvider ?? null;\n this.cacheRoot = opts.cacheRoot;\n }\n\n /** Lazily built so it reads the SUBCLASS's `participantSlug` — subclass field\n * initializers run after `super()`, so building the cache in the constructor\n * would capture the base \"network\" slug instead. */\n protected get cache(): PayloadCache {\n if (!this.cacheInstance) {\n this.cacheInstance = new PayloadCache(this.participantSlug, this.cacheRoot);\n }\n return this.cacheInstance;\n }\n\n // -- Subclass hooks ---------------------------------------------------------\n\n /** Do the authenticated API call; return a JSON-serializable dict. Raise\n * {@link NetworkUnavailable} on transport/5xx/rate-limit (→ cache fallback) or\n * {@link ParticipantAuthError} on 401/403 (→ blocked, no fallback). */\n abstract fetchPayload(token: string): Record<string, unknown>;\n\n /** Normalize a (fresh or cached) payload into an L5 manifest. Pure, no I/O. */\n abstract payloadToL5(payload: Record<string, unknown>): L5ManifestModel;\n\n // -- Core fetch-with-cache-and-degrade -------------------------------------\n\n /**\n * Resolve (payload, source) where source is 'cache' | 'network' | 'stale-cache'.\n * 1. Fresh cache hit → 'cache' (no network)\n * 2. Miss/expired + token → 'network' (fetch + refresh cache)\n * 3. Net fails + any cache → 'stale-cache' (serve last good payload)\n * 4. Net fails + no cache → raise\n * Auth errors are never swallowed — they propagate so health surfaces\n * 'blocked' rather than serving stale data behind a dead token.\n */\n protected getPayload(): { payload: Record<string, unknown>; source: string } {\n const cached = this.cache.read();\n if (cached !== null && cached.isFresh(this.cacheTtlSeconds)) {\n return { payload: cached.payload, source: \"cache\" };\n }\n\n const token = this.authProvider ? this.authProvider() : null;\n if (!token) {\n // No credential: if we have any cache, serve it stale; else blocked.\n if (cached !== null) return { payload: cached.payload, source: \"stale-cache\" };\n throw new ParticipantAuthError(\n `${this.participantSlug}: no auth token available and no cache`,\n );\n }\n\n let payload: Record<string, unknown>;\n try {\n payload = this.fetchPayload(token);\n } catch (err) {\n if (err instanceof ParticipantAuthError) throw err; // never mask a bad token\n if (err instanceof NetworkUnavailable) {\n if (cached !== null) return { payload: cached.payload, source: \"stale-cache\" };\n throw err;\n }\n throw err;\n }\n\n this.cache.write(payload);\n return { payload, source: \"network\" };\n }\n\n // -- Participant protocol ---------------------------------------------------\n\n discover(): AgentStore {\n const { source } = this.getPayload();\n return {\n path: this.nativePath,\n version: `${this.participantSlug}-network-v1`,\n metadata: { source, contract_version: NETWORK_CONTRACT_VERSION },\n };\n }\n\n exportL5(_since?: Date): L5ManifestModel {\n const { payload } = this.getPayload();\n return this.payloadToL5(payload);\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const manifest = this.exportL5(since);\n let sessions = manifest.recent_sessions ?? [];\n if (since) {\n const cutoff = since.toISOString().slice(0, 10);\n sessions = sessions.filter((s) => (s.date || \"\") >= cutoff);\n }\n return sessions.slice(0, limit);\n }\n\n healthCheck(): HealthStatus {\n let source: string;\n try {\n source = this.getPayload().source;\n } catch (err) {\n if (err instanceof ParticipantAuthError) {\n return {\n status: \"blocked\",\n reason: String(err.message),\n details: { participant: this.participantSlug },\n proposedFix:\n `Provide a valid credential for ${this.participantSlug} ` +\n \"(see the adapter docs for the auth path) and re-run `bourdon export-all`.\",\n };\n }\n if (err instanceof NetworkUnavailable) {\n return {\n status: \"degraded\",\n reason: `network unavailable and no cache: ${err.message}`,\n details: { participant: this.participantSlug },\n proposedFix: \"Check connectivity, then re-run `bourdon export-all`.\",\n };\n }\n // Defense in depth: health_check must NEVER raise. An adapter's\n // fetchPayload should only raise the two contract errors; anything else is\n // reported as blocked rather than propagated.\n return {\n status: \"blocked\",\n reason: `unexpected error resolving payload: ${String(err)}`,\n details: { participant: this.participantSlug },\n proposedFix:\n `${this.participantSlug} raised an unexpected error during healthCheck; ` +\n \"its fetchPayload should only raise ParticipantAuthError / NetworkUnavailable.\",\n };\n }\n\n const cached = this.cache.read();\n const details: Record<string, unknown> = { participant: this.participantSlug, source };\n if (cached !== null) {\n details[\"cache_age_seconds\"] = Math.round(cached.ageSeconds * 10) / 10;\n details[\"cache_fetched_at\"] = new Date(cached.fetchedAt * 1000)\n .toISOString()\n .replace(/\\.\\d{3}Z$/, \"+00:00\");\n }\n if (source === \"stale-cache\") {\n return {\n status: \"degraded\",\n reason: \"serving stale cache (network unavailable or no token)\",\n details,\n proposedFix: \"Restore connectivity / refresh the token to update.\",\n };\n }\n return { status: \"ok\", details };\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Hermes participant — normalize Hermes Agent (Nous Research) memory + sessions\n * into L5. Port of `participants/hermes.py`.\n *\n * Reads two surfaces under `~/.hermes/` (override `$HERMES_HOME`):\n * * `state.db` — a SQLite store (`sessions` + `messages` tables). Recent\n * non-archived sessions + project entities (from cwd basename) come from it.\n * * `memories/{memory.md,user.md}` — durable cross-session facts (one\n * Markdown bullet/line per memory). The highest-signal entities.\n *\n * Read-only (`mode=ro`), deterministic, visibility-enforced-before-emission,\n * and redaction on every native string. `healthCheck` never throws; `discover`\n * raises only {@link ParticipantDiscoveryError}.\n */\n\nimport { readFileSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n CONTRACT_VERSION,\n ParticipantDiscoveryError,\n SPEC_VERSION,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\nimport {\n epochToIsoDate,\n friendlyLabel,\n projectKeyFromCwd,\n tableColumns,\n tableExists,\n tryOpenReadonly,\n type SqliteDatabase,\n} from \"../sqlite-base.js\";\n\nconst AGENT_ID = \"hermes\";\nconst AGENT_TYPE = \"code-assistant\";\nconst DISPLAY_NAME = \"Hermes Agent\";\nconst ROLE_NARRATIVE =\n \"General-purpose tool-calling assistant (Nous Research). Operates across CLI, \" +\n \"TUI, and messaging gateways (Slack/Telegram/Discord/WhatsApp); runs terminal, \" +\n \"file, web, and delegation toolsets. Carries durable cross-session memory and a \" +\n \"curated skill library. Federates session + memory context, not vendor account.\";\n\nconst DEFAULT_SESSION_LIMIT = 100;\n\n/** Hermes memory stores live as Markdown under `~/.hermes/memories/`. */\nconst MEMORY_FILENAMES = [\"memory.md\", \"user.md\"] as const;\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"secret\", \"health\", \"family\", \"legal\"],\n team_tags: [\"hermes-memory\", \"hermes-session\", \"hermes-project\"],\n});\n\n/** cwd basenames that carry no project identity. */\nconst GENERIC_PROJECT_NAMES = new Set([\n \"\",\n \"root\",\n \"home\",\n \"tmp\",\n \"temp\",\n \"desktop\",\n \"documents\",\n \"downloads\",\n \"src\",\n]);\n\n// -- Path resolution ----------------------------------------------------------\n\n/**\n * Conventional Hermes home used by the setup wizard's detection.\n * Precedence: explicit `home` > `$HERMES_HOME` > `~/.hermes`.\n */\nexport function defaultNativePath(home?: string): string {\n if (home) return join(home, \".hermes\");\n const env = process.env.HERMES_HOME;\n if (env) return env;\n return join(homedir(), \".hermes\");\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\n// -- Text helpers -------------------------------------------------------------\n\ninterface SessionRecord {\n id: string;\n source: string;\n model: unknown;\n title: string | null;\n cwd: string | null;\n date: string;\n messageCount: number;\n toolCallCount: number;\n}\n\n/** Redact secrets, collapse whitespace, and clamp length. */\nfunction bounded(value: string, limit = 240): string {\n const cleaned = redactText((value || \"\").replace(/\\s+/g, \" \").trim(), limit);\n return cleaned.trim();\n}\n\nfunction projectKey(cwd: string | null | undefined): string | null {\n return projectKeyFromCwd(cwd, GENERIC_PROJECT_NAMES);\n}\n\n// -- SQLite (read-only) -------------------------------------------------------\n\n/** Pull recent, non-archived sessions newest-first. Never raises. */\nfunction collectSessionRows(stateDb: string, limit = DEFAULT_SESSION_LIMIT): SessionRecord[] {\n if (!isFile(stateDb)) return [];\n const conn = tryOpenReadonly(stateDb);\n if (!conn) return [];\n const out: SessionRecord[] = [];\n try {\n if (!tableExists(conn, \"sessions\")) return [];\n // `archived` may be absent in older schemas — guard the column.\n const cols = tableColumns(conn, \"sessions\");\n const archivedClause = cols.has(\"archived\") ? \"WHERE COALESCE(archived, 0) = 0\" : \"\";\n const rows = conn\n .prepare(\n `SELECT id, source, model, title, cwd, started_at, ended_at,\n message_count, tool_call_count\n FROM sessions\n ${archivedClause}\n ORDER BY started_at DESC\n LIMIT ?`,\n )\n .all(limit) as Array<Record<string, unknown>>;\n for (const r of rows) {\n const day = epochToIsoDate(r[\"started_at\"]);\n if (!day) continue;\n out.push({\n id: String(r[\"id\"]),\n source: String(r[\"source\"] ?? \"\").toLowerCase(),\n model: r[\"model\"],\n title: (r[\"title\"] as string | null) ?? null,\n cwd: (r[\"cwd\"] as string | null) ?? null,\n date: day,\n messageCount: Number(r[\"message_count\"] ?? 0) || 0,\n toolCallCount: Number(r[\"tool_call_count\"] ?? 0) || 0,\n });\n }\n } catch {\n /* degrade to whatever rows we gathered */\n } finally {\n conn.close();\n }\n return out;\n}\n\n/** Distinct tool names used in a session, for key_actions evidence. */\nfunction toolNamesForSession(conn: SqliteDatabase, sessionId: string): string[] {\n if (!tableExists(conn, \"messages\")) return [];\n try {\n const rows = conn\n .prepare(\n `SELECT DISTINCT tool_name FROM messages\n WHERE session_id = ? AND tool_name IS NOT NULL AND tool_name != ''`,\n )\n .all(sessionId) as Array<{ tool_name: string }>;\n const names = new Set<string>();\n for (const r of rows) {\n if (r.tool_name) names.add(r.tool_name);\n }\n return [...names].sort();\n } catch {\n return [];\n }\n}\n\n// -- Memory parsing -----------------------------------------------------------\n\nconst BULLET_RE = /^\\s*[-*]\\s+(.*)$/;\n\n/** Return memory entries (one per bullet / non-empty line). Never raises. */\nfunction parseMemoryFile(path: string): string[] {\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch {\n return [];\n }\n const entries: string[] = [];\n for (const line of text.split(/\\r?\\n/)) {\n const m = BULLET_RE.exec(line);\n const candidate = m ? (m[1] ?? \"\") : line.trim();\n if (candidate && !candidate.startsWith(\"#\")) entries.push(candidate);\n }\n return entries;\n}\n\n/** Map memory store name → list of entry strings. */\nfunction collectMemoryEntries(home: string): Array<[string, string[]]> {\n const memDir = join(home, \"memories\");\n const result: Array<[string, string[]]> = [];\n if (!isDir(memDir)) return result;\n for (const fname of MEMORY_FILENAMES) {\n const path = join(memDir, fname);\n if (isFile(path)) {\n const entries = parseMemoryFile(path);\n if (entries.length) {\n const stem = fname.replace(/\\.md$/, \"\");\n result.push([stem, entries]);\n }\n }\n }\n return result;\n}\n\n// -- Entity / session builders ------------------------------------------------\n\nfunction buildSession(record: SessionRecord, toolNames: string[]): SessionModel {\n const key = projectKey(record.cwd);\n const focus: string[] = [];\n if (key) focus.push(key);\n const keyActions: string[] = [];\n if (record.title) keyActions.push(bounded(record.title, 160));\n if (toolNames.length) {\n keyActions.push(\"Tools: \" + toolNames.slice(0, 8).join(\", \"));\n } else if (record.toolCallCount) {\n keyActions.push(`${record.toolCallCount} tool call(s)`);\n }\n return makeSession({\n date: record.date,\n cwd: record.cwd || undefined,\n project_focus: focus,\n key_actions: keyActions,\n visibility: Visibility.TEAM,\n });\n}\n\n/** Turn a single memory line into a team-visibility entity. */\nfunction memoryEntity(store: string, entry: string): EntityModel {\n const tag = store === \"user\" ? \"hermes-user-memory\" : \"hermes-memory\";\n return makeEntity({\n name: bounded(entry, 80),\n type: store === \"user\" ? \"preference\" : \"fact\",\n summary: bounded(entry, 240),\n tags: [tag],\n visibility: Visibility.TEAM,\n });\n}\n\nfunction projectEntities(records: SessionRecord[]): EntityModel[] {\n const counts = new Map<string, number>();\n for (const r of records) {\n const key = projectKey(r.cwd);\n if (key) counts.set(key, (counts.get(key) ?? 0) + 1);\n }\n const entities: EntityModel[] = [];\n for (const [key, count] of counts) {\n let last: string | undefined;\n for (const r of records) {\n if (projectKey(r.cwd) === key) {\n if (last === undefined || r.date > last) last = r.date;\n }\n }\n entities.push(\n makeEntity({\n name: friendlyLabel(key),\n type: \"project\",\n summary: `Workspace observed across ${count} Hermes session(s).`,\n aliases: [key],\n last_touched: last,\n tags: [\"hermes-project\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n return entities;\n}\n\n// -- Participant --------------------------------------------------------------\n\n/** External participant for local Hermes Agent memory + sessions. */\nexport class HermesParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n displayName = DISPLAY_NAME;\n nativePath: string;\n\n private readonly home: string | null;\n\n static defaultNativePath(home?: string): string {\n return defaultNativePath(home);\n }\n\n /** `hermesHome` is the `.hermes` directory itself (matching the Python ctor). */\n constructor(hermesHome?: string) {\n if (hermesHome) {\n this.home = hermesHome;\n } else {\n const path = defaultNativePath();\n this.home = isDir(path) ? path : null;\n }\n this.nativePath = this.home ?? join(homedir(), \".hermes\");\n }\n\n private sources(): Record<string, string | null> {\n const home = this.home;\n const stateDb = home ? join(home, \"state.db\") : null;\n const memDir = home ? join(home, \"memories\") : null;\n const skillsDir = home ? join(home, \"skills\") : null;\n return {\n hermes_home: home,\n state_db: stateDb && isFile(stateDb) ? stateDb : null,\n memories_dir: memDir && isDir(memDir) ? memDir : null,\n skills_dir: skillsDir && isDir(skillsDir) ? skillsDir : null,\n };\n }\n\n discover(): AgentStore {\n const sources = this.sources();\n if (!Object.values(sources).some((v) => v)) {\n throw new ParticipantDiscoveryError(\n \"No Hermes memory sources found. Expected ~/.hermes/ (set $HERMES_HOME to override).\",\n );\n }\n if (!sources[\"state_db\"] && !sources[\"memories_dir\"]) {\n throw new ParticipantDiscoveryError(\n `Hermes home '${this.nativePath}' exists but has no state.db or memories/ — ` +\n \"nothing to federate yet.\",\n );\n }\n return {\n path: this.nativePath,\n version: \"hermes-home-v1\",\n metadata: { sources },\n };\n }\n\n exportSessions(since?: Date, limit = DEFAULT_SESSION_LIMIT): SessionModel[] {\n if (this.home === null) return [];\n const stateDb = join(this.home, \"state.db\");\n const cutoff = since ? since.toISOString().slice(0, 10) : null;\n const records = collectSessionRows(stateDb, limit);\n if (!records.length) return [];\n const conn = tryOpenReadonly(stateDb);\n const out: SessionModel[] = [];\n try {\n for (const rec of records) {\n if (cutoff && rec.date < cutoff) continue;\n const tools = conn ? toolNamesForSession(conn, rec.id) : [];\n out.push(buildSession(rec, tools));\n }\n } finally {\n if (conn) conn.close();\n }\n return out;\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const store = this.discover();\n const sources = (store.metadata[\"sources\"] ?? {}) as Record<string, string | null>;\n const capabilities = Object.entries(sources)\n .filter(([k, v]) => v && k !== \"hermes_home\")\n .map(([k]) => k)\n .sort();\n\n const home = this.home;\n const records = home ? collectSessionRows(join(home, \"state.db\"), DEFAULT_SESSION_LIMIT) : [];\n\n // Entities: project workspaces + memory-derived facts/preferences.\n const entities: EntityModel[] = projectEntities(records);\n const seen = new Set<string>();\n for (const e of entities) {\n seen.add(`${e.type || \"topic\"}\\u0000${e.name.toLowerCase()}`);\n }\n if (home) {\n for (const [storeName, entries] of collectMemoryEntries(home)) {\n for (const entry of entries) {\n const ent = memoryEntity(storeName, entry);\n const key = `${ent.type || \"topic\"}\\u0000${ent.name.toLowerCase()}`;\n if (seen.has(key)) continue;\n seen.add(key);\n entities.push(ent);\n }\n }\n }\n\n // Visibility enforced here, before emission (contract requirement).\n const visible = filterForFederation(entities, DEFAULT_POLICY);\n\n const sessions = this.exportSessions(\n since ?? new Date(0),\n DEFAULT_SESSION_LIMIT,\n );\n\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: this.agentId,\n type: this.agentType,\n role_narrative: ROLE_NARRATIVE,\n spec_version_compat: CONTRACT_VERSION,\n }),\n last_updated: new Date().toISOString(),\n capabilities,\n recent_sessions: sessions,\n known_entities: visible,\n visibility_policy: DEFAULT_POLICY,\n });\n }\n\n healthCheck(): HealthStatus {\n const details: Record<string, unknown> = {\n hermes_home: this.nativePath,\n state_db: \"missing\",\n memories_dir: \"missing\",\n skills_dir: \"missing\",\n };\n try {\n if (this.home === null) {\n return {\n status: \"blocked\",\n reason: \"~/.hermes/ not found — Hermes Agent not installed here\",\n details,\n proposedFix:\n \"Install Hermes Agent and run a session once, then `bourdon export-all`.\",\n };\n }\n const sources = this.sources();\n for (const key of [\"state_db\", \"memories_dir\", \"skills_dir\"] as const) {\n if (sources[key]) details[key] = sources[key];\n }\n if (sources[\"state_db\"]) {\n const records = collectSessionRows(join(this.home, \"state.db\"), 1);\n if (records.length) return { status: \"ok\", details };\n return {\n status: \"degraded\",\n reason: \"state.db present but no readable sessions yet\",\n details,\n proposedFix: \"Run at least one Hermes session, then `bourdon export-all`.\",\n };\n }\n if (sources[\"memories_dir\"]) {\n return {\n status: \"degraded\",\n reason: \"memories/ present but state.db missing — session history unavailable\",\n details,\n };\n }\n return {\n status: \"blocked\",\n reason: \"Hermes home has neither state.db nor memories/\",\n details,\n proposedFix: \"Run a Hermes session to populate ~/.hermes/state.db.\",\n };\n } catch (err) {\n // healthCheck must NEVER raise (contract).\n return {\n status: \"degraded\",\n reason: `unexpected error: ${String(err)}`,\n details,\n };\n }\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Claude Code participant — reads agent-brain + auto-memory + MCP knowledge\n * graph. Port of `participants/claude_code.py`.\n *\n * Three optional sources (the participant degrades gracefully):\n * 1. agent-brain/ — git-synced markdown records\n * 2. ~/.claude/projects/<ws>/memory/ — per-machine auto-memory frontmatter\n * 3. ~/claude-memory/memory.jsonl — MCP knowledge-graph JSONL\n *\n * Only these names are read; a notes folder under any other name is never\n * scanned unless the user points `AGENT_BRAIN` at it.\n *\n * Privacy: entities typed `person` (+ family/contact variants) and observations\n * containing credential-like strings default to PRIVATE and are filtered before\n * federation. Entities are deduped by case-insensitive name and sorted\n * alphabetically.\n */\n\nimport { readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { homedir, hostname } from \"node:os\";\nimport { basename, join } from \"node:path\";\n\nimport { parse as yamlParse } from \"yaml\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { containsSecret } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\n\nconst AGENT_ID = \"claude-code\";\nconst AGENT_TYPE = \"code-assistant\";\nconst ROLE_NARRATIVE =\n \"Agentic manager and code-assistant. Coordinates the agent fleet, \" +\n \"reviews PRs, and consults on architectural decisions. Capable of authoring \" +\n \"code but typically reviews + delegates to specialised code-assistants like \" +\n \"Codex for prime-code execution.\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.PUBLIC,\n private_tags: [\"personal\", \"financial\", \"credential\", \"health\", \"family\", \"legal\"],\n team_tags: [\"internal-roadmap\"],\n});\n\n/** Entity-type slugs that default to PRIVATE unless explicitly promoted. */\nconst PRIVATE_BY_DEFAULT_TYPES = new Set([\n \"person\",\n \"user\",\n \"individual\",\n \"contact\",\n \"family-member\",\n \"family_member\",\n]);\n\nconst MAX_SUMMARY_CHARS = 500;\nconst MAX_OBSERVATIONS_IN_SUMMARY = 2;\n\n// -- Path resolution ----------------------------------------------------------\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\n/** Directory names for the knowledge repo. Only these are scanned. */\nexport const BRAIN_DIR_NAMES: readonly [string] = [\"agent-brain\"];\n\n/** Env override pointing at the knowledge repo explicitly. */\nexport const BRAIN_ENV_VARS = [\"AGENT_BRAIN\"] as const;\n\n/**\n * Locate the knowledge repo using the documented precedence order.\n *\n * Explicit env override wins; then `$HOME/<name>`; then `$CWD/<name>`. No\n * other directory name is ever scanned.\n */\nfunction resolveBrainPath(): string | null {\n for (const varName of BRAIN_ENV_VARS) {\n const envOverride = process.env[varName];\n if (envOverride && isDir(envOverride)) return envOverride;\n }\n\n for (const base of [homeDir(), process.cwd()]) {\n for (const name of BRAIN_DIR_NAMES) {\n const candidate = join(base, name);\n if (isDir(candidate)) return candidate;\n }\n }\n\n return null;\n}\n\nfunction homeDir(): string {\n // os.homedir() can throw under some sandboxes; stay defensive so import +\n // construction never crash even when HOME points at an unreadable path.\n try {\n return homedir();\n } catch {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n }\n}\n\nfunction resolveAutoMemoryPath(): string | null {\n try {\n const base = join(homeDir(), \".claude\", \"projects\");\n if (!isDir(base)) return null;\n for (const child of readdirSync(base)) {\n const memMarker = join(base, child, \"memory\", \"MEMORY.md\");\n if (isFile(memMarker)) return join(base, child, \"memory\");\n }\n } catch {\n return null;\n }\n return null;\n}\n\nfunction resolveKnowledgeGraphPath(): string | null {\n const candidate = join(homeDir(), \"claude-memory\", \"memory.jsonl\");\n return isFile(candidate) ? candidate : null;\n}\n\n// -- Privacy scrubbing --------------------------------------------------------\n\nfunction isPrivateType(entityType: string | null | undefined): boolean {\n if (!entityType) return false;\n const normalized = entityType.split(\"/\").pop()?.trim().toLowerCase() ?? \"\";\n return PRIVATE_BY_DEFAULT_TYPES.has(normalized);\n}\n\n// -- YAML frontmatter ---------------------------------------------------------\n\nconst FRONTMATTER_OPEN = \"---\\n\";\nconst FRONTMATTER_CLOSE = \"\\n---\\n\";\n\nfunction parseFrontmatter(text: string): { frontmatter: Record<string, unknown>; body: string } {\n if (!text.startsWith(FRONTMATTER_OPEN)) return { frontmatter: {}, body: text };\n const end = text.indexOf(FRONTMATTER_CLOSE, FRONTMATTER_OPEN.length);\n if (end === -1) return { frontmatter: {}, body: text };\n const fmText = text.slice(FRONTMATTER_OPEN.length, end);\n const body = text.slice(end + FRONTMATTER_CLOSE.length);\n let parsed: unknown;\n try {\n parsed = yamlParse(fmText);\n } catch {\n return { frontmatter: {}, body: text };\n }\n const fm =\n typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : {};\n return { frontmatter: fm, body };\n}\n\n// -- Parser: agent-brain PROJECTS + LOG ---------------------------------------\n\nconst H1_RE = /^#[ \\t]+(.+?)[ \\t]*$/m;\nconst STATUS_SECTION_RE = /^##[ \\t]+(?:Current[ \\t]+)?Status[^\\n]*$/im;\nconst STATUS_DATE_RE = /\\b(\\d{4}-\\d{2}-\\d{2})\\b/;\nconst TITLE_SPLIT_RE = /\\s*[-—–:]+\\s+/;\n\nfunction extractH1Title(body: string): string | null {\n const match = H1_RE.exec(body);\n if (!match) return null;\n const title = (match[1] ?? \"\").trim();\n const head = title.split(TITLE_SPLIT_RE)[0] ?? title;\n return head.trim();\n}\n\nfunction extractFirstParagraph(body: string, maxChars = MAX_SUMMARY_CHARS): string {\n const paragraph: string[] = [];\n for (const line of body.split(/\\r?\\n/)) {\n const stripped = line.trim();\n if (!stripped) {\n if (paragraph.length) break;\n continue;\n }\n if (stripped.startsWith(\"#\")) continue;\n paragraph.push(stripped);\n if (paragraph.reduce((acc, s) => acc + s.length + 1, 0) > maxChars) break;\n }\n return paragraph.join(\" \").trim().slice(0, maxChars).trim();\n}\n\nfunction extractStatusTag(body: string): string[] {\n const match = STATUS_SECTION_RE.exec(body);\n if (!match) return [];\n const region = body.slice(match.index, match.index + 400).toLowerCase();\n const tags: string[] = [];\n for (const keyword of [\"archived\", \"canceled\", \"cancelled\", \"active\", \"shipped\", \"blocked\"]) {\n if (region.includes(keyword)) tags.push(keyword.replace(\"cancelled\", \"canceled\"));\n }\n return [...new Set(tags)];\n}\n\nconst END_OF_LIFE_TAGS = new Set([\"archived\", \"canceled\"]);\n\nfunction extractStatusDate(body: string): string | null {\n const match = STATUS_SECTION_RE.exec(body);\n if (!match) return null;\n const region = body.slice(match.index, match.index + 400);\n const dateMatch = STATUS_DATE_RE.exec(region);\n return dateMatch ? (dateMatch[1] ?? null) : null;\n}\n\nfunction parseProjectOverview(overviewPath: string): EntityModel | null {\n let text: string;\n try {\n text = readFileSync(overviewPath, \"utf8\");\n } catch {\n return null;\n }\n const { body } = parseFrontmatter(text);\n const title = extractH1Title(body) || basename(join(overviewPath, \"..\"));\n const summary = extractFirstParagraph(body);\n const tags = extractStatusTag(body);\n\n let validTo: string | null = null;\n if (tags.some((t) => END_OF_LIFE_TAGS.has(t))) {\n validTo = extractStatusDate(body);\n if (validTo === null) {\n try {\n const mtime = statSync(overviewPath).mtime;\n validTo = mtime.toISOString().slice(0, 10);\n } catch {\n validTo = null;\n }\n }\n }\n\n return makeEntity({\n name: title,\n type: \"project\",\n summary: summary || undefined,\n tags,\n valid_to: validTo ?? undefined,\n });\n}\n\nfunction parseProjectsDir(brainPath: string): EntityModel[] {\n const projectsDir = join(brainPath, \"PROJECTS\");\n if (!isDir(projectsDir)) return [];\n const entities: EntityModel[] = [];\n for (const name of readdirSync(projectsDir).sort()) {\n const projectDir = join(projectsDir, name);\n if (!isDir(projectDir)) continue;\n const overview = join(projectDir, \"OVERVIEW.md\");\n if (!isFile(overview)) continue;\n const entity = parseProjectOverview(overview);\n if (entity) entities.push(entity);\n }\n return entities;\n}\n\nconst LOG_FILENAME_RE = /^(\\d{4}-\\d{2}-\\d{2})(?:-(\\w+?))?(?:-.*)?\\.md$/;\n\nfunction parseLogFile(logPath: string): SessionModel | null {\n const m = LOG_FILENAME_RE.exec(basename(logPath));\n if (!m) return null;\n const sessionDate = m[1] ?? \"\";\n let text: string;\n try {\n text = readFileSync(logPath, \"utf8\");\n } catch {\n return null;\n }\n const { body } = parseFrontmatter(text);\n const headline = extractFirstParagraph(body, 250);\n return makeSession({\n date: sessionDate,\n key_actions: headline ? [headline] : [],\n files_touched: [`LOG/${basename(logPath)}`],\n });\n}\n\nfunction parseLogsDir(brainPath: string, since?: Date, limit = 100): SessionModel[] {\n const logDir = join(brainPath, \"LOG\");\n if (!isDir(logDir)) return [];\n const candidates: Array<[string, string]> = [];\n for (const fname of readdirSync(logDir)) {\n if (!fname.endsWith(\".md\")) continue;\n const m = LOG_FILENAME_RE.exec(fname);\n if (!m) continue;\n const d = m[1] ?? \"\";\n if (since) {\n if (d < since.toISOString().slice(0, 10)) continue;\n }\n candidates.push([d, join(logDir, fname)]);\n }\n candidates.sort((a, b) => (a[0] < b[0] ? 1 : a[0] > b[0] ? -1 : 0)); // newest first\n const sessions: SessionModel[] = [];\n for (const [, logFile] of candidates.slice(0, limit)) {\n const session = parseLogFile(logFile);\n if (session) sessions.push(session);\n }\n return sessions;\n}\n\n// -- Parser: auto-memory ------------------------------------------------------\n\nfunction parseAutoMemoryEntity(mdPath: string): EntityModel | null {\n let text: string;\n try {\n text = readFileSync(mdPath, \"utf8\");\n } catch {\n return null;\n }\n const { frontmatter, body } = parseFrontmatter(text);\n const name =\n (frontmatter[\"name\"] as string | undefined) ||\n extractH1Title(body) ||\n basename(mdPath).replace(/\\.md$/, \"\");\n const entityType = frontmatter[\"type\"] as string | undefined;\n const summaryRaw =\n (frontmatter[\"description\"] as string | undefined) || extractFirstParagraph(body);\n const rawTags = frontmatter[\"tags\"];\n const tags = Array.isArray(rawTags) ? rawTags.map((t) => String(t)) : [];\n\n const visibility = isPrivateType(entityType) ? Visibility.PRIVATE : undefined;\n\n return makeEntity({\n name: String(name),\n type: entityType ? String(entityType) : undefined,\n summary: summaryRaw ? String(summaryRaw).slice(0, MAX_SUMMARY_CHARS).trim() : undefined,\n tags,\n visibility,\n });\n}\n\nfunction parseAutoMemory(memoryPath: string): EntityModel[] {\n if (!isDir(memoryPath)) return [];\n const entities: EntityModel[] = [];\n for (const fname of readdirSync(memoryPath).sort()) {\n if (!fname.endsWith(\".md\") || fname === \"MEMORY.md\") continue;\n const entity = parseAutoMemoryEntity(join(memoryPath, fname));\n if (entity) entities.push(entity);\n }\n return entities;\n}\n\n// -- Parser: knowledge graph JSONL --------------------------------------------\n\nfunction graphEntityToBourdonEntity(record: Record<string, unknown>): EntityModel | null {\n const name = record[\"name\"];\n if (!name || typeof name !== \"string\") return null;\n const entityTypeSlug = (record[\"entityType\"] as string | undefined) || \"\";\n const normalizedType = entityTypeSlug ? (entityTypeSlug.split(\"/\").pop() ?? null) : null;\n const observations = Array.isArray(record[\"observations\"])\n ? (record[\"observations\"] as unknown[])\n : [];\n\n const safeObs: string[] = [];\n for (const obs of observations.slice(0, MAX_OBSERVATIONS_IN_SUMMARY)) {\n if (typeof obs !== \"string\") continue;\n safeObs.push(containsSecret(obs) ? \"[redacted -- contains credential-like content]\" : obs);\n }\n const joined = safeObs.join(\" | \").slice(0, MAX_SUMMARY_CHARS).trim();\n const summary = joined || undefined;\n\n const hasCredObs = observations.some((o) => typeof o === \"string\" && containsSecret(o));\n const visibility = isPrivateType(entityTypeSlug) || hasCredObs ? Visibility.PRIVATE : undefined;\n\n const tags =\n normalizedType && normalizedType !== name.toLowerCase() ? [normalizedType] : [];\n\n return makeEntity({\n name,\n type: normalizedType ?? undefined,\n summary,\n tags,\n visibility,\n });\n}\n\nfunction parseKnowledgeGraph(graphPath: string): EntityModel[] {\n if (!isFile(graphPath)) return [];\n let raw: string;\n try {\n raw = readFileSync(graphPath, \"utf8\");\n } catch {\n return [];\n }\n const entities: EntityModel[] = [];\n for (const lineRaw of raw.split(/\\r?\\n/)) {\n const line = lineRaw.trim();\n if (!line) continue;\n let record: unknown;\n try {\n record = JSON.parse(line);\n } catch {\n continue; // skip malformed JSONL (logged at WARNING in the oracle)\n }\n if (typeof record !== \"object\" || record === null) continue;\n const rec = record as Record<string, unknown>;\n if (rec[\"type\"] !== \"entity\") continue;\n const entity = graphEntityToBourdonEntity(rec);\n if (entity) entities.push(entity);\n }\n return entities;\n}\n\n// -- Dedupe + merge -----------------------------------------------------------\n\nconst VIS_ORDER: Record<string, number> = {\n [Visibility.PRIVATE]: 0,\n [Visibility.TEAM]: 1,\n [Visibility.PUBLIC]: 2,\n none: 3,\n};\n\nfunction visRank(v: Visibility | null | undefined): number {\n return v == null ? VIS_ORDER[\"none\"]! : VIS_ORDER[v]!;\n}\n\nfunction mergeEntities(into: EntityModel, other: EntityModel): EntityModel {\n if (!into.type && other.type) into.type = other.type;\n if (other.summary && other.summary.trim() && other.summary.length > (into.summary?.length ?? 0)) {\n into.summary = other.summary;\n }\n into.tags = [...new Set([...(into.tags ?? []), ...(other.tags ?? [])])];\n into.aliases = [...new Set([...(into.aliases ?? []), ...(other.aliases ?? [])])];\n if (other.last_touched && (into.last_touched == null || other.last_touched > into.last_touched)) {\n into.last_touched = other.last_touched;\n }\n // Temporal validity: the widest window either source supports. Dropping\n // these silently republished end-of-life entities as though still active.\n if (other.valid_from && (into.valid_from == null || other.valid_from < into.valid_from)) {\n into.valid_from = other.valid_from;\n }\n if (other.valid_to && (into.valid_to == null || other.valid_to > into.valid_to)) {\n into.valid_to = other.valid_to;\n }\n if (visRank(other.visibility) < visRank(into.visibility)) {\n into.visibility = other.visibility;\n }\n return into;\n}\n\n/**\n * Merge multiple entity lists into one, deduping by case-insensitive name.\n * The fresh copy carries EVERY field (mirroring the oracle's `replace()`):\n * a hand-kept field list here once dropped valid_from/valid_to, so archived\n * projects federated as though still active.\n */\nfunction dedupeEntities(sourceLists: EntityModel[][]): EntityModel[] {\n const byKey = new Map<string, EntityModel>();\n for (const source of sourceLists) {\n for (const entity of source) {\n const key = entity.name.trim().toLowerCase();\n if (!key) continue;\n const existing = byKey.get(key);\n if (existing) {\n mergeEntities(existing, entity);\n } else {\n byKey.set(\n key,\n makeEntity({\n ...entity,\n aliases: [...(entity.aliases ?? [])],\n tags: [...(entity.tags ?? [])],\n }),\n );\n }\n }\n }\n return [...byKey.values()].sort((a, b) => {\n const an = a.name.toLowerCase();\n const bn = b.name.toLowerCase();\n return an < bn ? -1 : an > bn ? 1 : 0;\n });\n}\n\n// -- Participant --------------------------------------------------------------\n\n/** External participant for Anthropic's Claude Code CLI. */\nexport class ClaudeCodeParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n nativePath: string;\n\n /** Public so a hermetic test can seed the discovered sources directly (path\n * RESOLUTION is not the parity contract — only the export output shape is). */\n brainPath: string | null;\n autoMemoryPath: string | null;\n knowledgeGraphPath: string | null;\n\n static defaultNativePath(home?: string): string {\n return join(home ?? homeDir(), \".claude\");\n }\n\n constructor() {\n this.nativePath = join(homeDir(), BRAIN_DIR_NAMES[0]); // primary anchor\n this.brainPath = resolveBrainPath();\n this.autoMemoryPath = resolveAutoMemoryPath();\n this.knowledgeGraphPath = resolveKnowledgeGraphPath();\n }\n\n discover(): AgentStore {\n const sources = {\n agent_brain: this.brainPath,\n auto_memory: this.autoMemoryPath,\n knowledge_graph: this.knowledgeGraphPath,\n };\n if (!Object.values(sources).some((v) => v)) {\n throw new ParticipantDiscoveryError(\n \"No Claude Code memory sources found. Expected one of: ~/agent-brain/, \" +\n \"~/.claude/projects/*/memory/, ~/claude-memory/memory.jsonl.\",\n );\n }\n return {\n path: this.nativePath,\n version: \"claude-code-memory-v1\",\n metadata: { sources },\n };\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const store = this.discover(); // re-raises on missing\n const sources = store.metadata[\"sources\"] as Record<string, string | null>;\n const capabilities = Object.entries(sources)\n .filter(([, v]) => v)\n .map(([k]) => k)\n .sort();\n\n const autoMemoryEntities = this.autoMemoryPath ? parseAutoMemory(this.autoMemoryPath) : [];\n const graphEntities = this.knowledgeGraphPath\n ? parseKnowledgeGraph(this.knowledgeGraphPath)\n : [];\n const projectEntities = this.brainPath ? parseProjectsDir(this.brainPath) : [];\n\n // Priority: auto-memory > graph > brain projects (first wins on collision).\n const allEntities = dedupeEntities([autoMemoryEntities, graphEntities, projectEntities]);\n\n // Visibility filter — private entities never leave this function.\n const visibleEntities = filterForFederation(allEntities, DEFAULT_POLICY);\n\n const sessions = this.brainPath ? parseLogsDir(this.brainPath, since) : [];\n\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: this.agentId,\n type: this.agentType,\n instance: hostname() || \"unknown\",\n spec_version_compat: `>=${SPEC_VERSION}`,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: new Date().toISOString(),\n capabilities,\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: DEFAULT_POLICY,\n });\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n if (!this.brainPath) return [];\n return parseLogsDir(this.brainPath, since, limit);\n }\n\n healthCheck(): HealthStatus {\n try {\n const present = [this.brainPath, this.autoMemoryPath, this.knowledgeGraphPath].filter(\n (p) => p !== null,\n ).length;\n const details = {\n agent_brain: this.brainPath ?? \"missing\",\n auto_memory: this.autoMemoryPath ?? \"missing\",\n knowledge_graph: this.knowledgeGraphPath ?? \"missing\",\n };\n if (present === 3) return { status: \"ok\", details };\n if (present === 0) {\n return {\n status: \"blocked\",\n reason: \"No Claude Code memory sources found on this machine\",\n details,\n proposedFix:\n \"Run `bourdon setup` to wire the SessionEnd hook and bootstrap \" +\n \"~/agent-library/, then open Claude Code once to populate ~/.claude/projects/.\",\n };\n }\n return {\n status: \"degraded\",\n reason: `${present}/3 Claude Code memory sources found`,\n details,\n proposedFix:\n \"Run `bourdon setup` to (re-)wire missing sources, or set the AGENT_BRAIN \" +\n \"env var to point at your agent-brain checkout.\",\n };\n } catch (err) {\n return {\n status: \"degraded\",\n reason: `unexpected error: ${String(err)}`,\n details: {},\n };\n }\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * GitHub-embedded Copilot participant — the v0.3 network-adapter reference.\n * Port of `participants/github_copilot.py`.\n *\n * Cloud-side Copilot (PR review, `@copilot` comments) persists nothing on the\n * user's machine — its state lives on github.com. This adapter federates it by\n * reading the user's GitHub activity over the REST API. The\n * {@link NetworkParticipant} base provides the cache, degradation, and auth\n * boundary; this class provides only the GitHub-specific fetch + payload→L5.\n *\n * Auth: a token with `repo` + `read:user` scope, sourced from `$GITHUB_TOKEN` /\n * `$GH_TOKEN`, else `gh auth token`. Fetched lazily; never stored in the cache\n * or the manifest.\n */\n\nimport { execFileSync } from \"node:child_process\";\n\nimport {\n Visibility,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport { SPEC_VERSION } from \"../base.js\";\nimport {\n NetworkParticipant,\n NetworkUnavailable,\n ParticipantAuthError,\n type AuthProvider,\n type NetworkParticipantOptions,\n} from \"../network-base.js\";\n\nconst AGENT_ID = \"github-copilot\";\nconst AGENT_TYPE = \"code-assistant\";\nconst PARTICIPANT_SLUG = \"github-copilot\";\nconst DISPLAY_NAME = \"GitHub Copilot (cloud)\";\nconst ROLE_NARRATIVE =\n \"Cloud-side GitHub Copilot: PR review and @copilot-authored comments/\" +\n \"suggestions that live on github.com, not on the user's machine. Federated \" +\n \"via the GitHub REST API rather than a local artifact.\";\n\nconst GITHUB_API_ROOT = \"https://api.github.com\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"secret\"],\n team_tags: [\"github-copilot\", \"pull-request\"],\n});\n\n// -- Auth resolution ----------------------------------------------------------\n\n/** Resolve a GitHub token: env var first, then the `gh` CLI keychain. */\nexport function ghTokenProvider(): string | null {\n for (const varName of [\"GITHUB_TOKEN\", \"GH_TOKEN\"]) {\n const val = process.env[varName];\n if (val) return val;\n }\n try {\n const out = execFileSync(\"gh\", [\"auth\", \"token\"], {\n encoding: \"utf8\",\n timeout: 5000,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n });\n const token = out.trim();\n if (token) return token;\n } catch {\n /* gh missing / not logged in */\n }\n return null;\n}\n\n// -- HTTP ---------------------------------------------------------------------\n\ninterface HttpResponse {\n status: number;\n headers: Record<string, string>;\n body: string;\n}\n\n/**\n * Synchronous GET via a tiny `curl` shell-out (the base class's fetch contract\n * is synchronous, matching the Python urllib reference). Returns parsed JSON.\n * Classifies failures into the two contract errors: rate-limit / 5xx /\n * transport / non-JSON → {@link NetworkUnavailable}; 401/403 →\n * {@link ParticipantAuthError}. Never raises anything else.\n */\nfunction githubGet(path: string, token: string, timeoutSec = 10): unknown {\n const url = path.startsWith(\"http\") ? path : `${GITHUB_API_ROOT}${path}`;\n let resp: HttpResponse;\n try {\n resp = curlGet(url, token, timeoutSec);\n } catch (err) {\n throw new NetworkUnavailable(`GitHub API unreachable: ${String(err)}`);\n }\n\n const remaining = resp.headers[\"x-ratelimit-remaining\"];\n if (resp.status === 429 || (resp.status === 403 && String(remaining) === \"0\")) {\n throw new NetworkUnavailable(`GitHub API ${resp.status}: rate-limited`);\n }\n if (resp.status === 401 || resp.status === 403) {\n throw new ParticipantAuthError(`GitHub API ${resp.status}: token invalid or lacks scope`);\n }\n if (resp.status >= 500) {\n throw new NetworkUnavailable(`GitHub API ${resp.status}`);\n }\n if (resp.status >= 400) {\n throw new NetworkUnavailable(`GitHub API ${resp.status}`);\n }\n try {\n return JSON.parse(resp.body);\n } catch (err) {\n // A 200 with a non-JSON body (captive portal / proxy splash) is a degraded\n // condition, not a hard crash.\n throw new NetworkUnavailable(`GitHub API returned a non-JSON body: ${String(err)}`);\n }\n}\n\nfunction curlGet(url: string, token: string, timeoutSec: number): HttpResponse {\n // `-sS` quiet but show errors; `-D -` dumps headers to stdout before the body;\n // `-w` appends the status code on its own trailing line for parsing.\n const raw = execFileSync(\n \"curl\",\n [\n \"-sS\",\n \"-D\",\n \"-\",\n \"-o\",\n \"-\",\n \"--max-time\",\n String(timeoutSec),\n \"-H\",\n `Authorization: Bearer ${token}`,\n \"-H\",\n \"Accept: application/vnd.github+json\",\n \"-H\",\n \"X-GitHub-Api-Version: 2022-11-28\",\n \"-H\",\n \"User-Agent: bourdon-github-copilot-participant\",\n \"-w\",\n \"\\n__BOURDON_STATUS__%{http_code}\",\n url,\n ],\n { encoding: \"utf8\", timeout: (timeoutSec + 2) * 1000, maxBuffer: 8 * 1024 * 1024 },\n );\n\n const statusMatch = /\\n__BOURDON_STATUS__(\\d+)$/.exec(raw);\n const status = statusMatch ? Number(statusMatch[1]) : 0;\n const withoutStatus = statusMatch ? raw.slice(0, statusMatch.index) : raw;\n\n // Split header block from body (last header section before body).\n const headerBodySplit = withoutStatus.indexOf(\"\\r\\n\\r\\n\");\n let headerBlock = \"\";\n let body = withoutStatus;\n if (headerBodySplit >= 0) {\n headerBlock = withoutStatus.slice(0, headerBodySplit);\n body = withoutStatus.slice(headerBodySplit + 4);\n } else {\n const lfSplit = withoutStatus.indexOf(\"\\n\\n\");\n if (lfSplit >= 0) {\n headerBlock = withoutStatus.slice(0, lfSplit);\n body = withoutStatus.slice(lfSplit + 2);\n }\n }\n\n const headers: Record<string, string> = {};\n for (const line of headerBlock.split(/\\r?\\n/)) {\n const idx = line.indexOf(\":\");\n if (idx > 0) {\n headers[line.slice(0, idx).trim().toLowerCase()] = line.slice(idx + 1).trim();\n }\n }\n return { status, headers, body };\n}\n\n// -- Participant --------------------------------------------------------------\n\n/** Federates cloud-side GitHub Copilot activity via the GitHub REST API. */\nexport class GitHubCopilotParticipant extends NetworkParticipant {\n override participantSlug = PARTICIPANT_SLUG;\n override agentId = AGENT_ID;\n override agentType = AGENT_TYPE;\n override nativePath = GITHUB_API_ROOT;\n displayName = DISPLAY_NAME;\n\n private readonly maxResults: number;\n\n constructor(opts: NetworkParticipantOptions & { maxResults?: number } = {}) {\n super({\n authProvider: opts.authProvider ?? ghTokenProvider,\n cacheRoot: opts.cacheRoot,\n });\n this.maxResults = opts.maxResults ?? 50;\n }\n\n static defaultNativePath(): string {\n return GITHUB_API_ROOT;\n }\n\n override fetchPayload(token: string): Record<string, unknown> {\n // Identify the authenticated user (also validates the token early).\n const me = githubGet(\"/user\", token);\n const login = me && typeof me === \"object\" ? (me as Record<string, unknown>)[\"login\"] : null;\n\n // PRs that involve the user where Copilot is a commenter/reviewer.\n const q = \"is:pr involves:@me commenter:copilot\";\n const encoded = encodeURIComponent(q);\n const search = githubGet(\n `/search/issues?q=${encoded}&sort=updated&per_page=${this.maxResults}`,\n token,\n );\n const items =\n search && typeof search === \"object\"\n ? ((search as Record<string, unknown>)[\"items\"] ?? [])\n : [];\n\n return {\n fetched_user: login ?? null,\n fetched_at: new Date().toISOString(),\n items,\n };\n }\n\n override payloadToL5(payload: Record<string, unknown>): L5ManifestModel {\n const items = Array.isArray(payload[\"items\"]) ? (payload[\"items\"] as unknown[]) : [];\n const sessions: SessionModel[] = [];\n const entities = new Map<string, EntityModel>();\n\n for (const item of items) {\n if (typeof item !== \"object\" || item === null) continue;\n const it = item as Record<string, unknown>;\n const repo = repoFromItem(it);\n const title = redactText(String(it[\"title\"] ?? \"\"), 160);\n const number = it[\"number\"];\n const updated = isoDate(it[\"updated_at\"]);\n const focus = repo ? [repo] : [];\n\n sessions.push(\n makeSession({\n date: updated || \"1970-01-01\",\n cwd: repo ? `github.com/${repo}` : undefined,\n project_focus: focus,\n key_actions: number != null ? [`PR #${String(number)}: ${title}`] : [title],\n visibility: Visibility.TEAM,\n }),\n );\n\n if (repo && !entities.has(repo)) {\n entities.set(\n repo,\n makeEntity({\n name: repo,\n type: \"repository\",\n summary: \"GitHub repo with Copilot PR activity.\",\n aliases: repo.includes(\"/\") ? [repo.split(\"/\").pop() ?? \"\"] : [],\n last_touched: updated ?? undefined,\n tags: [\"github-copilot\", \"pull-request\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n\n // Keep sessions newest-first, bounded.\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: this.agentId,\n type: this.agentType,\n role_narrative: ROLE_NARRATIVE,\n instance: (payload[\"fetched_user\"] as string | null | undefined) ?? undefined,\n }),\n last_updated: new Date().toISOString(),\n capabilities: [\"github-search\", \"pull-request-comments\"],\n recent_sessions: sessions.slice(0, this.maxResults),\n known_entities: [...entities.values()],\n visibility_policy: DEFAULT_POLICY,\n });\n }\n}\n\n// -- Helpers ------------------------------------------------------------------\n\nfunction repoFromItem(item: Record<string, unknown>): string | null {\n const repoUrl = item[\"repository_url\"];\n if (typeof repoUrl === \"string\" && repoUrl.includes(\"/repos/\")) {\n return repoUrl.split(\"/repos/\")[1] ?? null;\n }\n return null;\n}\n\nfunction isoDate(value: unknown): string | null {\n if (typeof value === \"string\" && value.length >= 10) return value.slice(0, 10);\n return null;\n}\n\n// Re-export the provider type for adapters/tests that inject auth.\nexport type { AuthProvider };\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Cursor participant — reads Cursor's (the AI-first IDE) SQLite-backed\n * workspace/composer state and normalizes it into L5. Port of\n * `participants/cursor.py` + the extraction helper `participants/_cursor_sqlite.py`.\n *\n * Cursor stores workspace state in `state.vscdb` SQLite DBs at platform-specific\n * paths (`~/.config/Cursor/`, `~/Library/Application Support/Cursor/`,\n * `%APPDATA%/Cursor/`). This reader discovers those stores, reads the `ItemTable`\n * key/value rows read-only, parses the composer/chat records into sessions +\n * project/topic entities, and merges curated `.cursor/memory/short-index.json`\n * entities alongside them.\n *\n * SQLite access: the Python oracle copies each DB (+ its `-wal`/`-shm`\n * companions) to a tmp file and opens it read-write so SQLite folds the WAL into\n * a consistent snapshot. The TS mirror instead leans on {@link tryOpenReadonly}\n * (`mode=ro`), which respects SQLite locking and reads the `-wal` sidecar of a\n * live writer — the same consistent view without the copy. Read-only,\n * deterministic, visibility-enforced-before-emission, redaction on every native\n * string; `healthCheck` never throws.\n */\n\nimport { readFileSync, readdirSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { basename, join } from \"node:path\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\nimport { tableExists, tryOpenReadonly } from \"../sqlite-base.js\";\n\nconst AGENT_ID = \"cursor\";\nconst AGENT_TYPE = \"code-assistant\";\nconst ROLE_NARRATIVE =\n \"AI-first IDE. Bourdon reads the SQLite-backed composer/workspace \" +\n \"state to surface recent sessions and project entities to other agents.\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"credential\", \"secret\"],\n team_tags: [\"cursor\", \"workspace\", \"sqlite\"],\n});\n\nconst TOPIC_MIN_MENTIONS = 3;\n\n// -- Defensive fs helpers -----------------------------------------------------\n\nfunction homeDir(): string {\n try {\n return homedir();\n } catch {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n }\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\n/** Redact credential-like content and cap length (redaction SSOT). */\nfunction scrubText(value: string, limit = 256): string {\n return redactText(value, limit);\n}\n\n// -- Extraction data shapes ---------------------------------------------------\n\ninterface CursorSessionMemory {\n date: string;\n cwd: string;\n keyActions: string[];\n filesTouched: string[];\n}\n\ninterface CursorEntityMemory {\n name: string;\n entityType: string;\n aliases: string[];\n summary: string;\n tags: string[];\n lastUpdated: string;\n}\n\ninterface CursorSQLiteMemories {\n sessions: CursorSessionMemory[];\n entities: CursorEntityMemory[];\n databasesScanned: string[];\n malformedRecords: number;\n}\n\n// -- Path resolution ----------------------------------------------------------\n\n/**\n * Platform-specific Cursor data dir (the SQLite workspace state lives here),\n * `$CURSOR_DIR` override first. Returns null on an unrecognized platform (or\n * Windows without `%APPDATA%`). Mirrors `default_cursor_dir`.\n */\nexport function defaultCursorDir(): string | null {\n const env = process.env.CURSOR_DIR;\n if (env) return env;\n switch (process.platform) {\n case \"darwin\":\n return join(homeDir(), \"Library\", \"Application Support\", \"Cursor\");\n case \"linux\":\n return join(homeDir(), \".config\", \"Cursor\");\n case \"win32\": {\n const appdata = process.env.APPDATA;\n return appdata ? join(appdata, \"Cursor\") : null;\n }\n default:\n return null;\n }\n}\n\n/** Candidate `state.vscdb` paths under a Cursor data dir that actually exist. */\nfunction iterStateDbs(root: string): string[] {\n const candidates: string[] = [\n join(root, \"state.vscdb\"),\n join(root, \"User\", \"globalStorage\", \"state.vscdb\"),\n ];\n const workspaceStorage = join(root, \"User\", \"workspaceStorage\");\n if (isDir(workspaceStorage)) {\n let children: string[] = [];\n try {\n children = readdirSync(workspaceStorage).sort();\n } catch {\n children = [];\n }\n for (const child of children) {\n candidates.push(join(workspaceStorage, child, \"state.vscdb\"));\n }\n }\n return candidates.filter((p) => isFile(p));\n}\n\n// -- SQLite ItemTable read (read-only) ----------------------------------------\n\n/**\n * Read the `(key, value)` rows of the `ItemTable`, JSON-decoding each value.\n * Returns the decoded records plus a count of values that failed to parse.\n * Never raises — a locked/corrupt/unreadable DB degrades to \"no rows\".\n */\nfunction readItemTable(dbPath: string): { records: Array<[string, unknown]>; malformed: number } {\n const records: Array<[string, unknown]> = [];\n let malformed = 0;\n\n const conn = tryOpenReadonly(dbPath);\n if (!conn) return { records, malformed };\n\n let rows: Array<{ key: unknown; value: unknown }>;\n try {\n if (!tableExists(conn, \"ItemTable\")) return { records, malformed };\n rows = conn.prepare(\"SELECT key, value FROM ItemTable\").all() as Array<{\n key: unknown;\n value: unknown;\n }>;\n } catch {\n // Locked (Windows holds a write lock on a live DB), corrupt, or otherwise\n // unreadable — skip this DB, never crash the whole export. The caller still\n // records it as scanned.\n return { records, malformed };\n } finally {\n conn.close();\n }\n\n for (const row of rows) {\n const raw = row.value;\n let text: string | null = null;\n if (typeof raw === \"string\") text = raw;\n else if (raw instanceof Uint8Array) text = Buffer.from(raw).toString(\"utf8\");\n if (text === null) {\n malformed += 1;\n continue;\n }\n let value: unknown;\n try {\n value = JSON.parse(text);\n } catch {\n malformed += 1;\n continue;\n }\n records.push([String(row.key), value]);\n }\n return { records, malformed };\n}\n\n// -- Record parsing -----------------------------------------------------------\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction firstString(value: Record<string, unknown>, keys: readonly string[]): string {\n for (const key of keys) {\n const candidate = value[key];\n if (typeof candidate === \"string\" && candidate.trim()) return candidate.trim();\n }\n return \"\";\n}\n\nfunction firstMessageText(messages: unknown): string {\n if (!Array.isArray(messages)) return \"\";\n for (const message of messages) {\n if (!isRecord(message)) continue;\n // Python uses `content or text` — fall back whenever content is falsy\n // (incl. \"\"), not just null/undefined. `||` matches; `??` would drop a\n // {content:\"\", text:\"...\"} record and silently lose the session.\n const content = message[\"content\"] || message[\"text\"];\n if (typeof content === \"string\" && content.trim()) return content.trim();\n }\n return \"\";\n}\n\nfunction looksLikeComposerRecord(key: string, value: unknown): boolean {\n const loweredKey = key.toLowerCase();\n if (loweredKey.includes(\"composer\") || loweredKey.includes(\"aichat\") || loweredKey.includes(\"chat\")) {\n return true;\n }\n if (isRecord(value)) {\n const joinedKeys = Object.keys(value).join(\" \").toLowerCase();\n return joinedKeys.includes(\"message\") && (joinedKeys.includes(\"workspace\") || joinedKeys.includes(\"file\"));\n }\n return false;\n}\n\n/**\n * Parse a calendar date as written from an ISO-ish string (no tz conversion,\n * mirroring `datetime.fromisoformat(...).date()`) or an epoch number.\n */\nfunction parseDate(value: unknown): string {\n if (typeof value === \"string\") {\n const normalized = value.replaceAll(\"Z\", \"+00:00\");\n const m = /^(\\d{4}-\\d{2}-\\d{2})([T ].*)?$/.exec(normalized);\n if (!m) return \"\";\n const datePart = m[1] ?? \"\";\n // Reject calendar-impossible days (e.g. 2024-02-30): Python's\n // `datetime.fromisoformat` raises on these, but `new Date` silently rolls\n // the month over. Round-trip the date and require it to survive unchanged.\n const dayProbe = new Date(`${datePart}T00:00:00Z`);\n if (Number.isNaN(dayProbe.getTime()) || dayProbe.toISOString().slice(0, 10) !== datePart) {\n return \"\";\n }\n // Validate the full value parses as a real datetime; take the date as written.\n const probe = new Date(m[2] ? normalized.replace(\" \", \"T\") : `${datePart}T00:00:00`);\n if (Number.isNaN(probe.getTime())) return \"\";\n return datePart;\n }\n if (typeof value === \"number\" && Number.isFinite(value)) {\n const timestamp = value > 10_000_000_000 ? value / 1000 : value;\n const dt = new Date(timestamp * 1000);\n if (Number.isNaN(dt.getTime())) return \"\";\n return dt.toISOString().slice(0, 10);\n }\n return \"\";\n}\n\nfunction dateFromRecord(value: Record<string, unknown>): string {\n for (const key of [\"createdAt\", \"timestamp\", \"updatedAt\", \"lastUpdatedAt\", \"time\"]) {\n const parsed = parseDate(value[key]);\n if (parsed) return parsed;\n }\n return new Date().toISOString().slice(0, 10);\n}\n\nfunction stringsFromList(values: unknown[]): string[] {\n const strings: string[] = [];\n for (const item of values) {\n if (typeof item === \"string\" && item.trim()) {\n strings.push(item.trim());\n } else if (isRecord(item)) {\n const path = firstString(item, [\"path\", \"file\", \"uri\", \"relativePath\"]);\n if (path) strings.push(path);\n }\n }\n return strings;\n}\n\nfunction dedupe(values: string[]): string[] {\n const seen = new Set<string>();\n const out: string[] = [];\n for (const value of values) {\n if (!seen.has(value)) {\n seen.add(value);\n out.push(value);\n }\n }\n return out;\n}\n\nfunction extractFiles(value: Record<string, unknown>): string[] {\n const files: string[] = [];\n for (const key of [\"files\", \"filePaths\", \"filesTouched\", \"references\"]) {\n const candidate = value[key];\n if (Array.isArray(candidate)) files.push(...stringsFromList(candidate));\n }\n const messages = value[\"messages\"];\n if (Array.isArray(messages)) {\n for (const message of messages) {\n if (isRecord(message)) files.push(...extractFiles(message));\n }\n }\n return dedupe(files);\n}\n\nfunction recordToSession(key: string, value: unknown): CursorSessionMemory | null {\n if (!looksLikeComposerRecord(key, value)) return null;\n if (!isRecord(value)) return null;\n\n let cwd = firstString(value, [\"workspacePath\", \"workspace\", \"cwd\", \"folder\", \"rootPath\"]);\n if (!cwd && isRecord(value[\"workspace\"])) {\n cwd = firstString(value[\"workspace\"], [\"path\", \"folder\", \"cwd\"]);\n }\n if (!cwd) cwd = \"\";\n\n let action = firstString(value, [\"title\", \"text\", \"prompt\", \"summary\", \"name\"]);\n if (!action) action = firstMessageText(value[\"messages\"]);\n if (!action) return null;\n\n return {\n date: dateFromRecord(value),\n cwd,\n keyActions: [scrubText(action)],\n filesTouched: extractFiles(value),\n };\n}\n\nfunction projectName(cwd: string): string {\n if (!cwd) return \"\";\n const name = basename(cwd).trim();\n return name && name !== \".\" && name !== \"/\" ? name : \"\";\n}\n\n// -- Topic-entity inference ---------------------------------------------------\n\nconst STRIP_CHARS = new Set([\n \".\", \",\", \";\", \":\", \"!\", \"?\", '\"', \"'\", \"`\", \"(\", \")\", \"[\", \"]\", \"{\", \"}\", \"#\", \"-\", \"/\",\n]);\n\nfunction stripChars(token: string): string {\n let start = 0;\n let end = token.length;\n while (start < end && STRIP_CHARS.has(token[start]!)) start += 1;\n while (end > start && STRIP_CHARS.has(token[end - 1]!)) end -= 1;\n return token.slice(start, end);\n}\n\nconst TOPIC_STOPWORDS = new Set([\n \"the\", \"and\", \"for\", \"with\", \"this\", \"that\", \"from\", \"have\", \"will\",\n \"are\", \"was\", \"been\", \"not\", \"but\", \"all\", \"can\", \"has\", \"its\",\n \"add\", \"use\", \"set\", \"get\", \"new\", \"fix\", \"run\", \"now\", \"also\",\n \"into\", \"make\", \"just\", \"like\", \"need\", \"want\", \"work\", \"code\",\n \"file\", \"test\", \"data\", \"type\", \"should\", \"would\", \"could\",\n]);\n\n/** Extract recurring topic entities from session key_actions (in place). */\nfunction addTopicEntities(\n sessions: CursorSessionMemory[],\n entities: Map<string, CursorEntityMemory>,\n): void {\n const wordCounts = new Map<string, number>();\n const wordLatest = new Map<string, string>();\n\n for (const session of sessions) {\n for (const action of session.keyActions) {\n const words = new Set<string>();\n for (const token of action.toLowerCase().split(/\\s+/)) {\n const cleaned = stripChars(token);\n if (cleaned.length >= 4 && !TOPIC_STOPWORDS.has(cleaned) && /^\\p{L}+$/u.test(cleaned)) {\n words.add(cleaned);\n }\n }\n for (const word of words) {\n wordCounts.set(word, (wordCounts.get(word) ?? 0) + 1);\n if (session.date) {\n const prev = wordLatest.get(word);\n if (prev === undefined || session.date > prev) wordLatest.set(word, session.date);\n }\n }\n }\n }\n\n for (const [word, count] of wordCounts) {\n if (count >= TOPIC_MIN_MENTIONS && !entities.has(word)) {\n entities.set(word, {\n name: word,\n entityType: \"topic\",\n aliases: [],\n summary: `Recurring topic across ${count} Cursor sessions.`,\n tags: [\"cursor\", \"topic\", \"inferred\"],\n lastUpdated: wordLatest.get(word) ?? \"\",\n });\n }\n }\n}\n\n// -- Top-level extraction -----------------------------------------------------\n\nfunction extractCursorMemories(cursorDir: string | null = null): CursorSQLiteMemories {\n const root = cursorDir ?? defaultCursorDir();\n if (root === null || !isDir(root)) {\n return { sessions: [], entities: [], databasesScanned: [], malformedRecords: 0 };\n }\n\n const sessions: CursorSessionMemory[] = [];\n const entitiesByName = new Map<string, CursorEntityMemory>();\n const databasesScanned: string[] = [];\n let malformedRecords = 0;\n const projectLatest = new Map<string, string>();\n\n for (const dbPath of iterStateDbs(root)) {\n databasesScanned.push(dbPath);\n const { records, malformed } = readItemTable(dbPath);\n malformedRecords += malformed;\n for (const [key, value] of records) {\n const parsedSession = recordToSession(key, value);\n if (parsedSession === null) continue;\n sessions.push(parsedSession);\n\n const name = projectName(parsedSession.cwd);\n if (!name) continue;\n\n const prev = projectLatest.get(name) ?? \"\";\n if (!projectLatest.has(name) || (parsedSession.date && parsedSession.date > prev)) {\n projectLatest.set(name, parsedSession.date);\n }\n const existing = entitiesByName.get(name);\n const aliasSet = new Set<string>(parsedSession.cwd ? [parsedSession.cwd] : []);\n if (existing) {\n for (const a of existing.aliases) aliasSet.add(a);\n }\n entitiesByName.set(name, {\n name: scrubText(name, 120),\n entityType: \"project\",\n aliases: [...aliasSet].sort(),\n summary: scrubText(`Cursor workspace inferred from ${parsedSession.cwd}.`),\n tags: [\"cursor\", \"workspace\", \"sqlite\"],\n lastUpdated: projectLatest.get(name) ?? \"\",\n });\n }\n }\n\n addTopicEntities(sessions, entitiesByName);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n\n return {\n sessions,\n entities: [...entitiesByName.values()],\n databasesScanned,\n malformedRecords,\n };\n}\n\n// -- Short-index integration --------------------------------------------------\n\n/** Read a short-index.json and return its normalized entry dicts. */\nfunction readShortIndex(path: string): Array<Record<string, unknown>> {\n if (!isFile(path)) return [];\n let payload: unknown;\n try {\n const raw = readFileSync(path, \"utf8\").replace(/^\\uFEFF/, \"\"); // utf-8-sig: strip BOM\n payload = JSON.parse(raw);\n } catch {\n // Python logs a warning here; swallow + skip so a bad file never crashes export.\n return [];\n }\n if (!isRecord(payload)) return [];\n const entries = payload[\"entries\"];\n if (!Array.isArray(entries)) return [];\n return entries.filter(\n (e): e is Record<string, unknown> => isRecord(e) && Boolean(e[\"topic_key\"]),\n );\n}\n\n/** Merge workspace + global short-index files into Entity objects. */\nfunction shortIndexToEntities(\n workspaceRoot: string | null,\n _cursorDir: string | null,\n): EntityModel[] {\n const paths: string[] = [];\n if (workspaceRoot) {\n paths.push(join(workspaceRoot, \".cursor\", \"memory\", \"short-index.json\"));\n }\n const cursorHome = process.env.CURSOR_DIR ? process.env.CURSOR_DIR : null;\n const homeBase = cursorHome ?? join(homeDir(), \".cursor\");\n paths.push(join(homeBase, \"memory\", \"short-index.json\"));\n\n const merged = new Map<string, Record<string, unknown>>();\n for (const path of paths) {\n for (const entry of readShortIndex(path)) {\n const key = String(entry[\"topic_key\"]).trim().toLowerCase();\n merged.set(key, entry);\n }\n }\n\n const entities: EntityModel[] = [];\n for (const entry of merged.values()) {\n const nameRaw =\n entry[\"topic_name\"] !== undefined ? entry[\"topic_name\"] : (entry[\"topic_key\"] ?? \"\");\n const name = String(nameRaw).trim();\n if (!name) continue;\n\n const aliasesRaw =\n \"triggers\" in entry ? entry[\"triggers\"] : \"aliases\" in entry ? entry[\"aliases\"] : [];\n const aliases = Array.isArray(aliasesRaw)\n ? aliasesRaw.map((a) => String(a).trim()).filter((s) => s.length > 0)\n : [];\n\n const summary = String(entry[\"summary\"] ?? \"\").trim();\n\n const tagsRaw = entry[\"tags\"] ?? [];\n const tags = Array.isArray(tagsRaw)\n ? tagsRaw.map((t) => String(t).trim()).filter((s) => s.length > 0)\n : [];\n tags.push(\"short-index\");\n\n const access = String(entry[\"access_level\"] ?? \"team\").trim().toLowerCase();\n const visibility =\n access === \"private\"\n ? Visibility.PRIVATE\n : access === \"public\"\n ? Visibility.PUBLIC\n : Visibility.TEAM;\n\n const lastTouched = String(entry[\"last_updated\"] ?? \"\");\n\n entities.push(\n makeEntity({\n name,\n type: \"topic\",\n aliases,\n summary: summary || undefined,\n tags,\n last_touched: lastTouched || undefined,\n visibility,\n }),\n );\n }\n return entities;\n}\n\n// -- Conversion helpers -------------------------------------------------------\n\nfunction toSession(raw: CursorSessionMemory): SessionModel {\n return makeSession({\n date: raw.date || \"\",\n cwd: raw.cwd || undefined,\n project_focus: [],\n key_actions: [...raw.keyActions],\n files_touched: [...raw.filesTouched],\n });\n}\n\nfunction toEntity(raw: CursorEntityMemory): EntityModel {\n return makeEntity({\n name: raw.name,\n type: raw.entityType || undefined,\n aliases: [...raw.aliases],\n summary: raw.summary || undefined,\n tags: [...raw.tags],\n last_touched: raw.lastUpdated || undefined,\n });\n}\n\n/** Current UTC time, seconds precision + `+00:00` (Python `isoformat(timespec=\"seconds\")`). */\nfunction nowIsoSeconds(): string {\n return new Date().toISOString().replace(/\\.\\d{3}Z$/, \"+00:00\");\n}\n\n// -- Participant --------------------------------------------------------------\n\n/** External participant for Cursor's SQLite workspace state. */\nexport class CursorParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n\n private readonly cursorDir: string | null;\n private readonly workspaceRoot: string | null;\n private readonly policy: VisibilityPolicyModel = DEFAULT_POLICY;\n\n /**\n * Conventional Cursor config dir (`~/.cursor`) used by the setup wizard. The\n * wizard probes `~/.cursor` for presence; the SQLite workspace state that\n * `exportL5` actually reads lives at {@link defaultCursorDir}. Detection and\n * extraction intentionally use different anchors.\n */\n static defaultNativePath(home?: string): string {\n return join(home ?? homeDir(), \".cursor\");\n }\n\n constructor(cursorDir?: string | null, workspaceRoot?: string | null) {\n this.cursorDir = cursorDir ?? null;\n this.workspaceRoot = workspaceRoot ?? null;\n }\n\n get nativePath(): string {\n const path = this.cursorDir ?? defaultCursorDir();\n return path ?? \"\";\n }\n\n discover(): AgentStore {\n const path = this.cursorDir ?? defaultCursorDir();\n if (path === null || !isDir(path)) {\n throw new ParticipantDiscoveryError(\n `Cursor data directory not found at ${path === null ? \"None\" : `'${path}'`}. ` +\n \"Pass an explicit cursor_dir to CursorParticipant() if Cursor stores its \" +\n \"state somewhere non-standard.\",\n );\n }\n const dbs = iterStateDbs(path);\n const dbDetails = dbs.map((db) => {\n let size: number;\n try {\n size = statSync(db).size;\n } catch {\n size = -1;\n }\n return { path: db, size_bytes: size };\n });\n\n return {\n path,\n version: \"unknown\",\n metadata: {\n platform_default: defaultCursorDir() ?? \"None\",\n databases_found: dbs.length,\n databases: dbDetails,\n },\n };\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const memories = this.extract();\n const out: SessionModel[] = [];\n const sinceIso = since ? since.toISOString().slice(0, 10) : null;\n for (const raw of memories.sessions) {\n if (sinceIso && raw.date && raw.date < sinceIso) continue;\n out.push(toSession(raw));\n if (out.length >= limit) break;\n }\n return out;\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const memories = this.extract();\n let sessions = memories.sessions.map(toSession);\n if (since) {\n const sinceIso = since.toISOString().slice(0, 10);\n sessions = sessions.filter((s) => !s.date || s.date >= sinceIso);\n }\n\n const entities = memories.entities.map(toEntity);\n const shortIndexEntities = shortIndexToEntities(this.workspaceRoot, this.cursorDir);\n const seenNames = new Set(entities.map((e) => e.name.toLowerCase()));\n for (const si of shortIndexEntities) {\n const key = si.name.toLowerCase();\n if (!seenNames.has(key)) {\n entities.push(si);\n seenNames.add(key);\n }\n }\n const visibleEntities = filterForFederation(entities, this.policy);\n\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n role_narrative: ROLE_NARRATIVE,\n spec_version_compat: SPEC_VERSION,\n }),\n last_updated: nowIsoSeconds(),\n capabilities: [\"composer-history\", \"workspace-state\"],\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: this.policy,\n });\n }\n\n healthCheck(): HealthStatus {\n const path = this.cursorDir ?? defaultCursorDir();\n if (path === null) {\n return {\n status: \"blocked\",\n reason: \"Cursor data directory not resolvable on this platform.\",\n details: {},\n proposedFix:\n \"Install Cursor (https://cursor.sh) and open it once. \" +\n \"Set CURSOR_DIR if Cursor stores state outside the default location.\",\n };\n }\n if (!isDir(path)) {\n return {\n status: \"blocked\",\n reason: `Cursor data directory not present at ${path}.`,\n details: { expected_path: path },\n proposedFix:\n \"Install Cursor and open it once to create the data directory, \" +\n \"or set CURSOR_DIR to the actual location.\",\n };\n }\n let memories: CursorSQLiteMemories;\n try {\n memories = this.extract();\n } catch (err) {\n // health check must not raise.\n return {\n status: \"degraded\",\n reason: \"Cursor data directory present but extraction failed.\",\n details: { error: String(err) },\n proposedFix:\n \"Close Cursor (its SQLite stores may be locked) then re-run \" +\n \"`bourdon cursor export`. If extraction still fails, file an \" +\n \"issue with the error above.\",\n };\n }\n if (memories.databasesScanned.length === 0) {\n return {\n status: \"degraded\",\n reason: \"No Cursor SQLite stores found under the data directory.\",\n details: { path },\n proposedFix:\n \"Open Cursor and use it for at least one chat session, then \" +\n \"re-run `bourdon cursor export`.\",\n };\n }\n return {\n status: \"ok\",\n details: {\n databases_scanned: memories.databasesScanned.length,\n sessions_extracted: memories.sessions.length,\n entities_extracted: memories.entities.length,\n malformed_records: memories.malformedRecords,\n },\n };\n }\n\n private extract(): CursorSQLiteMemories {\n return extractCursorMemories(this.cursorDir);\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * GitHub Copilot (local convention) participant — reads the convention-based\n * memory file at `~/.copilot-bourdon/memory.md`. Port of `participants/copilot.py`.\n *\n * Copilot has no accessible local session index (its reasoning is cloud-side and\n * its native memory is not exposed on disk), so — like the Codex pre-distillation\n * fallback — this reader normalizes a user-maintained convention file into a\n * Bourdon L5 manifest. The file is YAML front-matter (structured `entities:` /\n * `sessions:`) followed by an optional freeform markdown body that Copilot Chat\n * reads as plain context but this reader ignores.\n *\n * NOT the cloud GitHub-Copilot network adapter ({@link GitHubCopilotParticipant})\n * and NOT the Copilot CLI SQLite reader.\n *\n * Paths checked (in order):\n * 1. `COPILOT_BOURDON_HOME` env-var override\n * 2. `~/.copilot-bourdon/` (default convention path)\n *\n * Defensive throughout: a missing convention directory raises\n * {@link ParticipantDiscoveryError} from `discover()`; malformed YAML degrades to\n * an empty manifest rather than raising; `healthCheck` never throws.\n */\n\nimport { mkdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport { homedir, hostname } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { parse as yamlParse } from \"yaml\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\n\nconst AGENT_ID = \"copilot\";\nconst AGENT_TYPE = \"code-assistant\";\nconst DISPLAY_NAME = \"GitHub Copilot\";\nconst ROLE_NARRATIVE =\n \"Inline completion and chat assistant present across every IDE the team uses. \" +\n \"Works alongside the human at the keystroke level -- the ambient layer that \" +\n \"recognises what is being typed before a full turn is even formed. Bourdon \" +\n \"gives Copilot cross-session entity awareness it would otherwise lack entirely.\";\n\n// Convention directory and file names. Override dir with COPILOT_BOURDON_HOME.\nconst CONVENTION_DIR_NAME = \".copilot-bourdon\";\nconst MEMORY_FILENAME = \"memory.md\";\n\n// Front-matter delimiters (mirrors claude-code's parseFrontmatter conventions).\nconst FRONTMATTER_OPEN = \"---\\n\";\nconst FRONTMATTER_CLOSE = \"\\n---\\n\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"health\", \"family\", \"legal\"],\n team_tags: [\"copilot-memory\", \"workspace\", \"copilot\"],\n});\n\n/** Minimal logger so a degraded read is visible without pulling in a dep\n * (matches the registry's logging idiom). */\nconst logger = {\n warn(msg: string): void {\n // eslint-disable-next-line no-console\n console.warn(`[bourdon.participants] ${msg}`);\n },\n};\n\n/** Starter template written by `bourdon copilot init`. */\nconst MEMORY_TEMPLATE = `---\n# Copilot Bourdon Memory\n# Edit this file to give Copilot cross-session entity awareness.\n# The YAML front-matter is parsed by \\`bourdon copilot export\\`.\n# The markdown body below the closing \\`---\\` is freeform context for Copilot Chat.\n\nentities: []\n\nsessions: []\n---\n\n# Copilot notes\n\nAdd project notes, preferences, or anything else you want Copilot Chat to\nremember here. This section is freeform -- the participant only reads the YAML\nfront-matter above.\n`;\n\n// -- fs helpers ---------------------------------------------------------------\n\nfunction homeDir(): string {\n // os.homedir() can throw under some sandboxes; stay defensive so import +\n // construction never crash even when HOME points at an unreadable path.\n try {\n return homedir();\n } catch {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n }\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\n// -- Path helpers -------------------------------------------------------------\n\n/**\n * Return the conventional `~/.copilot-bourdon/` directory path. Respects the\n * `COPILOT_BOURDON_HOME` env-var override (returned verbatim, even if absent;\n * the directory is not created here).\n */\nexport function defaultCopilotBourdonDir(): string {\n const env = process.env.COPILOT_BOURDON_HOME;\n if (env) return env;\n return join(homeDir(), CONVENTION_DIR_NAME);\n}\n\n/** Return the path to the convention memory file. */\nexport function defaultCopilotMemoryPath(copilotDir?: string | null): string {\n return join(copilotDir || defaultCopilotBourdonDir(), MEMORY_FILENAME);\n}\n\n// -- Coercion helpers (mirror Python str() / isinstance filtering) ------------\n\n/** Mirror Python `str(value)` for the value types YAML yields here. The `yaml`\n * lib parses timestamps into JS `Date`; Python's `yaml.safe_load` yields\n * `date`/`datetime` whose `str()` is ISO-ish, so a Date is rendered as its ISO\n * date (date-only callers slice to 10 anyway). */\nfunction coerceStr(v: unknown): string {\n if (v instanceof Date) return v.toISOString().slice(0, 10);\n return String(v);\n}\n\n/** Mirror Python `str(raw.get(key) or \"\") or None`. */\nfunction strOrUndef(v: unknown): string | undefined {\n const s = coerceStr((v as unknown) || \"\");\n return s || undefined;\n}\n\n/** Mirror `[str(x) for x in raw if isinstance(x, str) and x.strip()]`. */\nfunction strList(v: unknown): string[] {\n if (!Array.isArray(v)) return [];\n return v.filter((x): x is string => typeof x === \"string\" && x.trim() !== \"\");\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nfunction asArray(v: unknown): unknown[] {\n return Array.isArray(v) ? v : [];\n}\n\n// -- YAML frontmatter ---------------------------------------------------------\n\n/**\n * Extract and parse the YAML front-matter block from memory file text. Returns\n * an empty object when the file has no front-matter or when the YAML cannot be\n * parsed (logged at WARNING in the oracle; never raises here either).\n */\nfunction parseFrontmatter(text: string, source?: string): Record<string, unknown> {\n if (!text.startsWith(FRONTMATTER_OPEN)) return {};\n const end = text.indexOf(FRONTMATTER_CLOSE, FRONTMATTER_OPEN.length);\n if (end === -1) return {};\n const fmText = text.slice(FRONTMATTER_OPEN.length, end);\n let parsed: unknown;\n try {\n parsed = yamlParse(fmText);\n } catch (err) {\n const where = source ? ` in ${source}` : \"\";\n const detail = String(err).replace(/\\n/g, \" \").slice(0, 200);\n logger.warn(\n `CopilotParticipant: malformed YAML frontmatter${where}; ` +\n `treating as no-frontmatter (${detail})`,\n );\n return {};\n }\n return isRecord(parsed) ? parsed : {};\n}\n\n/**\n * Read and parse a copilot-bourdon memory file. Returns an empty object on any\n * I/O or parse error — the participant degrades to an empty manifest.\n */\nfunction readMemoryFile(path: string): Record<string, unknown> {\n if (!isFile(path)) return {};\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch (err) {\n logger.warn(`CopilotParticipant: cannot read ${path}: ${String(err)}`);\n return {};\n }\n return parseFrontmatter(text, path);\n}\n\n// -- Entity / Session converters ----------------------------------------------\n\n/** Convert a raw YAML entity record to a Bourdon Entity. Skips malformed\n * entries (oracle logs at DEBUG). Never raises. */\nfunction buildEntity(raw: unknown): EntityModel | null {\n if (!isRecord(raw)) return null;\n const name = raw[\"name\"];\n if (typeof name !== \"string\" || name.trim() === \"\") return null;\n\n const summaryRaw = raw[\"summary\"] || \"\";\n const summary = summaryRaw ? redactText(coerceStr(summaryRaw)) : undefined;\n\n return makeEntity({\n name: name.trim(),\n type: strOrUndef(raw[\"type\"]),\n aliases: strList(raw[\"aliases\"]),\n summary,\n last_touched: strOrUndef(raw[\"last_touched\"]),\n tags: strList(raw[\"tags\"]),\n valid_from: strOrUndef(raw[\"valid_from\"]),\n valid_to: strOrUndef(raw[\"valid_to\"]),\n });\n}\n\n/** Convert a raw YAML session record to a Bourdon Session. Skips malformed\n * entries (oracle logs at DEBUG). Never raises. */\nfunction buildSession(raw: unknown): SessionModel | null {\n if (!isRecord(raw)) return null;\n const dateVal = raw[\"date\"];\n if (!dateVal) return null;\n const dateStr = coerceStr(dateVal).slice(0, 10); // keep YYYY-MM-DD prefix only\n\n return makeSession({\n date: dateStr,\n cwd: strOrUndef(raw[\"cwd\"]),\n project_focus: strList(raw[\"project_focus\"]),\n key_actions: strList(raw[\"key_actions\"]),\n files_touched: strList(raw[\"files_touched\"]),\n });\n}\n\n// -- Diagnostics --------------------------------------------------------------\n\n/** Diagnostic summary of the copilot-bourdon memory file (`bourdon copilot\n * doctor`). Never raises. */\nexport function inspectCopilotMemory(copilotDir?: string | null): Record<string, unknown> {\n const memPath = defaultCopilotMemoryPath(copilotDir);\n const report: Record<string, unknown> = {\n path: memPath,\n present: isFile(memPath),\n readable: false,\n frontmatter_valid: false,\n entity_count: 0,\n session_count: 0,\n error: null,\n };\n if (!isFile(memPath)) {\n report[\"error\"] = \"missing\";\n return report;\n }\n let text: string;\n try {\n text = readFileSync(memPath, \"utf8\");\n report[\"readable\"] = true;\n } catch (err) {\n report[\"error\"] = String(err);\n return report;\n }\n\n const data = parseFrontmatter(text, memPath);\n if (Object.keys(data).length > 0) report[\"frontmatter_valid\"] = true;\n report[\"entity_count\"] = asArray(data[\"entities\"]).length;\n report[\"session_count\"] = asArray(data[\"sessions\"]).length;\n return report;\n}\n\n// -- Participant --------------------------------------------------------------\n\n/**\n * External participant for GitHub Copilot via `~/.copilot-bourdon/memory.md`.\n * Implements {@link BourdonParticipant} structurally.\n */\nexport class CopilotParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n displayName = DISPLAY_NAME;\n nativePath: string;\n\n /** Conventional `~/.copilot-bourdon` dir used by the setup wizard's detection. */\n static defaultNativePath(home?: string): string {\n if (home !== undefined) return join(home, CONVENTION_DIR_NAME);\n return defaultCopilotBourdonDir();\n }\n\n private readonly copilotDir: string | null;\n\n constructor(copilotDir?: string | null) {\n this.copilotDir = copilotDir ?? null;\n this.nativePath = this.copilotDir || defaultCopilotBourdonDir();\n }\n\n discover(): AgentStore {\n const path = this.copilotDir || defaultCopilotBourdonDir();\n if (!isDir(path)) {\n throw new ParticipantDiscoveryError(\n `Copilot convention directory not found at '${path}'. ` +\n \"Run `bourdon copilot init` to create it with a starter template, \" +\n \"or create ~/.copilot-bourdon/memory.md manually.\",\n );\n }\n const memPath = join(path, MEMORY_FILENAME);\n return {\n path,\n version: \"convention-v1\",\n metadata: {\n memory_file: memPath,\n memory_file_present: isFile(memPath),\n },\n };\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const data = this.read();\n const sinceIso = since ? since.toISOString().slice(0, 10) : null;\n const sessions: SessionModel[] = [];\n for (const raw of asArray(data[\"sessions\"])) {\n const session = buildSession(raw);\n if (session === null) continue;\n if (sinceIso && session.date && session.date < sinceIso) continue;\n sessions.push(session);\n if (sessions.length >= limit) break;\n }\n return sessions;\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const data = this.read();\n\n const entities: EntityModel[] = [];\n for (const raw of asArray(data[\"entities\"])) {\n const entity = buildEntity(raw);\n if (entity !== null) entities.push(entity);\n }\n const visibleEntities = filterForFederation(entities, DEFAULT_POLICY);\n\n const sinceIso = since ? since.toISOString().slice(0, 10) : null;\n const sessions: SessionModel[] = [];\n for (const raw of asArray(data[\"sessions\"])) {\n const session = buildSession(raw);\n if (session === null) continue;\n if (sinceIso && session.date && session.date < sinceIso) continue;\n sessions.push(session);\n }\n\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: hostname() || \"unknown\",\n spec_version_compat: `>=${SPEC_VERSION}`,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: new Date().toISOString(),\n capabilities: [\"inline-completion\", \"chat\", \"pr-review\", \"convention-memory\"],\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: DEFAULT_POLICY,\n });\n }\n\n healthCheck(): HealthStatus {\n const path = this.copilotDir || defaultCopilotBourdonDir();\n if (!isDir(path)) {\n return {\n status: \"blocked\",\n reason:\n `Convention directory ${path} not found. ` +\n \"Run `bourdon copilot init` to create it.\",\n details: { expected_path: path },\n proposedFix: \"Run `bourdon copilot init` to create the convention directory.\",\n };\n }\n const memPath = join(path, MEMORY_FILENAME);\n if (!isFile(memPath)) {\n return {\n status: \"degraded\",\n reason:\n `Memory file ${memPath} not found. ` +\n \"Run `bourdon copilot init` to write a starter template.\",\n details: { expected_memory_file: memPath },\n proposedFix: \"Run `bourdon copilot init` to write the starter memory.md template.\",\n };\n }\n let data: Record<string, unknown>;\n try {\n data = this.read();\n } catch (err) {\n logger.warn(`CopilotParticipant health_check failed: ${String(err)}`);\n return {\n status: \"degraded\",\n reason: \"Memory file present but could not be parsed.\",\n details: { error: String(err) },\n proposedFix:\n `Inspect ${memPath} for malformed YAML front-matter. ` +\n \"The opening and closing `---` fences must wrap a valid YAML \" +\n \"block. See docs/agent-integration-status.md for the schema.\",\n };\n }\n return {\n status: \"ok\",\n details: {\n memory_file: memPath,\n entity_count: asArray(data[\"entities\"]).length,\n session_count: asArray(data[\"sessions\"]).length,\n },\n };\n }\n\n // -- Internal ---------------------------------------------------------------\n\n private read(): Record<string, unknown> {\n return readMemoryFile(defaultCopilotMemoryPath(this.copilotDir));\n }\n}\n\n// -- Init helper --------------------------------------------------------------\n\n/**\n * Create `~/.copilot-bourdon/memory.md` with a starter template. Returns the\n * written path. Throws when the file already exists unless `force` is true.\n */\nexport function initMemoryFile(copilotDir?: string | null, force = false): string {\n const targetDir = copilotDir || defaultCopilotBourdonDir();\n mkdirSync(targetDir, { recursive: true });\n const memPath = join(targetDir, MEMORY_FILENAME);\n if (isFile(memPath) && !force) {\n throw new Error(`${memPath} already exists. Pass --force to overwrite.`);\n }\n writeFileSync(memPath, MEMORY_TEMPLATE, \"utf8\");\n return memPath;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * GitHub Copilot CLI participant — normalize the `copilot` terminal agent's\n * SQLite session store into L5. Port of `participants/copilot_cli.py`.\n *\n * Copilot CLI stores session history in a SQLite database at\n * `~/.copilot/session-store.db` (override `$COPILOT_CLI_HOME`). This is distinct\n * from:\n * - the VS Code Copilot Chat extension (`github-copilot` network reader)\n * - the `~/.copilot-bourdon/memory.md` convention-file participant (`copilot`)\n * - GitHub-embedded Copilot (no local state)\n *\n * The schema (schema_version 4) carries `sessions` / `turns` / `checkpoints`\n * plus `session_files` / `session_refs` / `dynamic_context_items`. The reader\n * opens the DB read-only (`mode=ro` via {@link tryOpenReadonly}) so a live\n * writer's lock can never block the export, probes each table defensively (a\n * missing table degrades to \"no rows\" rather than raising), redacts every native\n * string, applies the visibility filter BEFORE emission, and is deterministic.\n * `healthCheck` never throws.\n */\n\nimport { statSync } from \"node:fs\";\nimport { homedir, hostname } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\nimport { tryOpenReadonly, type SqliteDatabase } from \"../sqlite-base.js\";\n\nconst AGENT_ID = \"copilot-cli\";\nconst AGENT_TYPE = \"code-assistant\";\nconst DISPLAY_NAME = \"GitHub Copilot CLI\";\nconst ROLE_NARRATIVE =\n \"Terminal-native Copilot agent with full filesystem + tool access. \" +\n \"Runs multi-turn sessions with checkpoints, file edits, and git \" +\n \"operations. The CLI surface has the deepest tool integration of \" +\n \"all Copilot surfaces — shell, grep, edit, git — and persists \" +\n \"rich session history locally in SQLite.\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"health\", \"family\", \"legal\"],\n team_tags: [\"copilot-cli\", \"copilot\", \"terminal\", \"workspace\"],\n});\n\nconst DB_FILENAME = \"session-store.db\";\nconst COPILOT_DIR_NAME = \".copilot\";\nconst MAX_SUMMARY_CHARS = 260;\nconst MAX_KEY_ACTIONS = 6;\nconst MAX_KEY_ACTION_CHARS = 280;\n\n// -- Path resolution ----------------------------------------------------------\n\n/**\n * Conventional `~/.copilot/` directory. Respects the `COPILOT_CLI_HOME`\n * environment-variable override (mirrors `default_copilot_cli_dir`).\n */\nexport function defaultCopilotCliDir(): string {\n const env = process.env.COPILOT_CLI_HOME;\n if (env) return env;\n return join(homedir(), COPILOT_DIR_NAME);\n}\n\n/** Path to `session-store.db` under the given (or conventional) copilot dir. */\nfunction defaultCopilotCliDbPath(copilotDir?: string | null): string {\n return join(copilotDir ?? defaultCopilotCliDir(), DB_FILENAME);\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\n// -- Text helpers -------------------------------------------------------------\n\n/** Redact secrets + clamp to the native-memory limit (`_safe_native_memory_text`). */\nfunction safeNativeMemoryText(value: string, limit = 180): string {\n return redactText(value, limit);\n}\n\n/**\n * Collapse whitespace and clamp with a single-char ellipsis (mirrors the\n * oracle's `_bounded`). NOTE: distinct from {@link redactText}'s `...` clamp —\n * this one uses `…` (U+2026) and does no redaction.\n */\nfunction bounded(value: string, limit: number): string {\n const normalized = value.split(/\\s+/).filter(Boolean).join(\" \");\n if (normalized.length <= limit) return normalized;\n return normalized.slice(0, limit - 1).replace(/\\s+$/, \"\") + \"…\";\n}\n\n// -- SQLite (read-only) -------------------------------------------------------\n\n/** Run a query and return rows as plain objects. Never raises (a missing table\n * or any SQLite error degrades to `[]`, matching the oracle's `_query_db`). */\nfunction queryDb(\n db: SqliteDatabase,\n sql: string,\n params: unknown[] = [],\n): Array<Record<string, unknown>> {\n try {\n return db.prepare(sql).all(...params) as Array<Record<string, unknown>>;\n } catch {\n return [];\n }\n}\n\nfunction extractSessions(db: SqliteDatabase, since?: string | null): Array<Record<string, unknown>> {\n let sql = \"SELECT id, cwd, repository, branch, summary, created_at, updated_at FROM sessions\";\n const params: unknown[] = [];\n if (since) {\n sql += \" WHERE created_at >= ?\";\n params.push(since);\n }\n sql += \" ORDER BY created_at DESC LIMIT 200\";\n return queryDb(db, sql, params);\n}\n\nfunction extractSessionFiles(db: SqliteDatabase, sessionId: string): string[] {\n const rows = queryDb(\n db,\n \"SELECT file_path FROM session_files WHERE session_id = ? LIMIT 20\",\n [sessionId],\n );\n const out: string[] = [];\n for (const r of rows) {\n const fp = r[\"file_path\"];\n if (fp) out.push(String(fp));\n }\n return out;\n}\n\nfunction extractSessionRefs(\n db: SqliteDatabase,\n sessionId: string,\n): Array<{ ref_type: string; ref_value: string }> {\n const rows = queryDb(\n db,\n \"SELECT ref_type, ref_value FROM session_refs WHERE session_id = ?\",\n [sessionId],\n );\n return rows.map((r) => ({\n ref_type: String(r[\"ref_type\"] ?? \"\"),\n ref_value: String(r[\"ref_value\"] ?? \"\"),\n }));\n}\n\nfunction extractCheckpoints(db: SqliteDatabase, sessionId: string): Array<Record<string, unknown>> {\n return queryDb(\n db,\n \"SELECT checkpoint_number, title, overview FROM checkpoints \" +\n \"WHERE session_id = ? ORDER BY checkpoint_number\",\n [sessionId],\n );\n}\n\nfunction extractDynamicContext(db: SqliteDatabase): Array<Record<string, unknown>> {\n return queryDb(\n db,\n \"SELECT repository, branch, src, name, description, content, read_count, count \" +\n \"FROM dynamic_context_items ORDER BY count DESC LIMIT 50\",\n );\n}\n\nfunction extractTurnCount(db: SqliteDatabase, sessionId: string): number {\n const rows = queryDb(db, \"SELECT COUNT(*) as cnt FROM turns WHERE session_id = ?\", [sessionId]);\n const first = rows[0];\n return first ? Number(first[\"cnt\"] ?? 0) || 0 : 0;\n}\n\n// -- Conversion to Bourdon types ----------------------------------------------\n\nfunction sessionToBourdon(\n raw: Record<string, unknown>,\n files: string[],\n refs: Array<{ ref_type: string; ref_value: string }>,\n checkpoints: Array<Record<string, unknown>>,\n turnCount: number,\n): SessionModel {\n const created = raw[\"created_at\"] ? String(raw[\"created_at\"]) : \"\";\n const dateStr = created ? created.slice(0, 10) : \"\";\n\n const keyActions: string[] = [];\n if (raw[\"summary\"]) {\n keyActions.push(bounded(safeNativeMemoryText(String(raw[\"summary\"])), MAX_KEY_ACTION_CHARS));\n }\n for (const cp of checkpoints.slice(0, 3)) {\n if (cp[\"title\"]) {\n keyActions.push(\n bounded(`checkpoint: ${safeNativeMemoryText(String(cp[\"title\"]))}`, MAX_KEY_ACTION_CHARS),\n );\n }\n }\n if (turnCount) {\n keyActions.push(`turns: ${turnCount}`);\n }\n for (const ref of refs.slice(0, 3)) {\n const refLabel = `${ref.ref_type}: ${ref.ref_value}`;\n keyActions.push(bounded(refLabel, MAX_KEY_ACTION_CHARS));\n }\n\n const projectFocus: string[] = [];\n if (raw[\"repository\"]) projectFocus.push(String(raw[\"repository\"]));\n\n return makeSession({\n date: dateStr,\n cwd: raw[\"cwd\"] ? String(raw[\"cwd\"]) : undefined,\n project_focus: projectFocus,\n key_actions: keyActions.slice(0, MAX_KEY_ACTIONS),\n files_touched: files.slice(0, 20),\n visibility: Visibility.TEAM,\n });\n}\n\nfunction entitiesFromSessionsAndContext(\n sessions: Array<Record<string, unknown>>,\n dynamicContext: Array<Record<string, unknown>>,\n): EntityModel[] {\n const entities = new Map<string, EntityModel>();\n\n // Repositories as project entities.\n for (const raw of sessions) {\n const repo = raw[\"repository\"] ? String(raw[\"repository\"]) : \"\";\n if (repo && !entities.has(repo)) {\n const created = raw[\"created_at\"] ? String(raw[\"created_at\"]) : \"\";\n const lastTouched = created.slice(0, 10) || null;\n entities.set(\n repo,\n makeEntity({\n name: repo,\n type: \"project\",\n summary: \"Repository worked on via Copilot CLI.\",\n last_touched: lastTouched ?? undefined,\n tags: [\"copilot-cli\", \"project\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n\n // Dynamic context items as knowledge entities.\n for (const ctx of dynamicContext) {\n const name = ctx[\"name\"] ? String(ctx[\"name\"]) : \"\";\n if (!name || entities.has(name)) continue;\n const desc = ctx[\"description\"] ? String(ctx[\"description\"]) : \"\";\n const content = ctx[\"content\"] ? String(ctx[\"content\"]) : \"\";\n let summaryText = desc || content;\n if (summaryText) {\n summaryText = bounded(safeNativeMemoryText(summaryText), MAX_SUMMARY_CHARS);\n }\n entities.set(\n name,\n makeEntity({\n name,\n type: \"dynamic-context\",\n summary: summaryText || undefined,\n last_touched: undefined,\n tags: [\"copilot-cli\", \"dynamic-context\", ctx[\"src\"] ? String(ctx[\"src\"]) : \"unknown\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n\n return [...entities.values()];\n}\n\n/** UTC ISO datetime with `+00:00` offset (matching Python `isoformat`). */\nfunction toUtcIso(d: Date): string {\n return d.toISOString().replace(/\\.\\d{3}Z$/, \"+00:00\").replace(/Z$/, \"+00:00\");\n}\n\n// -- Participant --------------------------------------------------------------\n\n/**\n * External participant for GitHub Copilot CLI (`~/.copilot/session-store.db`).\n * Reads the SQLite database read-only (never locks the live db).\n */\nexport class CopilotCliParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n displayName = DISPLAY_NAME;\n nativePath: string;\n\n private readonly copilotDir: string | null;\n\n /** Conventional `~/.copilot` dir used by the setup wizard's detection. */\n static defaultNativePath(home?: string): string {\n if (home) return join(home, COPILOT_DIR_NAME);\n return defaultCopilotCliDir();\n }\n\n constructor(copilotDir?: string) {\n this.copilotDir = copilotDir ?? null;\n this.nativePath = this.copilotDir ?? defaultCopilotCliDir();\n }\n\n // -- Protocol surface -------------------------------------------------------\n\n discover(): AgentStore {\n const dbPath = defaultCopilotCliDbPath(this.copilotDir);\n if (!isFile(dbPath)) {\n throw new ParticipantDiscoveryError(\n `Copilot CLI session-store.db not found at ${dbPath}. ` +\n \"The Copilot CLI agent must be run at least once to create this database.\",\n );\n }\n let dbSize = 0;\n try {\n dbSize = statSync(dbPath).size;\n } catch {\n dbSize = 0;\n }\n return {\n path: dirname(dbPath),\n version: \"schema-v4\",\n metadata: { db_path: dbPath, db_size_bytes: dbSize },\n };\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const dbPath = defaultCopilotCliDbPath(this.copilotDir);\n const db = tryOpenReadonly(dbPath);\n if (!db) return [];\n try {\n const sinceIso = since ? toUtcIso(since) : null;\n const rawSessions = extractSessions(db, sinceIso);\n const sessions: SessionModel[] = [];\n for (const raw of rawSessions.slice(0, limit)) {\n const sid = String(raw[\"id\"]);\n const files = extractSessionFiles(db, sid);\n const refs = extractSessionRefs(db, sid);\n const checkpoints = extractCheckpoints(db, sid);\n const turnCount = extractTurnCount(db, sid);\n sessions.push(sessionToBourdon(raw, files, refs, checkpoints, turnCount));\n }\n return sessions;\n } finally {\n db.close();\n }\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const dbPath = defaultCopilotCliDbPath(this.copilotDir);\n const db = tryOpenReadonly(dbPath);\n if (!db) return this.emptyManifest();\n try {\n const sinceIso = since ? toUtcIso(since) : null;\n const rawSessions = extractSessions(db, sinceIso);\n const dynamicContext = extractDynamicContext(db);\n\n const sessions: SessionModel[] = [];\n for (const raw of rawSessions.slice(0, 100)) {\n const sid = String(raw[\"id\"]);\n const files = extractSessionFiles(db, sid);\n const refs = extractSessionRefs(db, sid);\n const checkpoints = extractCheckpoints(db, sid);\n const turnCount = extractTurnCount(db, sid);\n sessions.push(sessionToBourdon(raw, files, refs, checkpoints, turnCount));\n }\n\n const entities = entitiesFromSessionsAndContext(rawSessions, dynamicContext);\n const visibleEntities = filterForFederation(entities, DEFAULT_POLICY);\n\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: hostname() || \"unknown\",\n spec_version_compat: `>=${SPEC_VERSION}`,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: new Date().toISOString(),\n capabilities: [\n \"terminal-agent\",\n \"file-edit\",\n \"shell-execution\",\n \"git-operations\",\n \"multi-turn-sessions\",\n \"checkpoints\",\n \"dynamic-context\",\n ],\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: DEFAULT_POLICY,\n });\n } finally {\n db.close();\n }\n }\n\n healthCheck(): HealthStatus {\n try {\n const copilotDir = this.copilotDir ?? defaultCopilotCliDir();\n if (!isDir(copilotDir)) {\n return {\n status: \"blocked\",\n reason: `Copilot CLI directory not found at ${copilotDir}.`,\n details: { expected_path: copilotDir },\n proposedFix:\n \"Run the Copilot CLI agent (`copilot` or `gh copilot`) at least once \" +\n \"to create the session store.\",\n };\n }\n const dbPath = defaultCopilotCliDbPath(copilotDir);\n if (!isFile(dbPath)) {\n return {\n status: \"blocked\",\n reason: `session-store.db not found at ${dbPath}.`,\n details: { expected_db: dbPath },\n proposedFix:\n \"Run the Copilot CLI agent at least once. The session-store.db is \" +\n \"created on first use.\",\n };\n }\n const db = tryOpenReadonly(dbPath);\n if (!db) {\n return {\n status: \"degraded\",\n reason: \"Cannot copy session-store.db for reading.\",\n details: { db_path: dbPath },\n proposedFix: \"Check file permissions on the session-store.db.\",\n };\n }\n try {\n const rawSessions = extractSessions(db);\n const dynamicContext = extractDynamicContext(db);\n const totalTurns = queryDb(db, \"SELECT COUNT(*) as cnt FROM turns\");\n const first = totalTurns[0];\n let dbSize = 0;\n try {\n dbSize = statSync(dbPath).size;\n } catch {\n dbSize = 0;\n }\n return {\n status: \"ok\",\n details: {\n db_path: dbPath,\n db_size_bytes: dbSize,\n session_count: rawSessions.length,\n total_turns: first ? Number(first[\"cnt\"] ?? 0) || 0 : 0,\n dynamic_context_items: dynamicContext.length,\n },\n };\n } finally {\n db.close();\n }\n } catch (err) {\n // healthCheck must NEVER raise (contract).\n return {\n status: \"degraded\",\n reason: `unexpected error: ${String(err)}`,\n details: {},\n };\n }\n }\n\n // -- Internal ---------------------------------------------------------------\n\n private emptyManifest(): L5ManifestModel {\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: hostname() || \"unknown\",\n spec_version_compat: `>=${SPEC_VERSION}`,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: new Date().toISOString(),\n capabilities: [],\n recent_sessions: [],\n known_entities: [],\n visibility_policy: DEFAULT_POLICY,\n });\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Cascade (Windsurf) participant — convention-file reader. Port of\n * `participants/cascade.py`.\n *\n * Cascade's internal state is not exposed on the filesystem in a standardized\n * format (like cloud Copilot). Instead this participant uses a CONVENTION FILE:\n * Cascade maintains a structured memory file at `~/.cascade-bourdon/memory.md`\n * with YAML front-matter carrying `entities` + `sessions`. Cascade owns that\n * projection explicitly (it writes what it knows at session end); the\n * participant normalizes the front-matter into an L5 manifest for federation.\n *\n * Privacy: entity/session summaries pass through the redaction SSOT; the\n * visibility policy (private_tags) filters PRIVATE entities before emission.\n */\n\nimport { mkdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { parse as yamlParse } from \"yaml\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { REDACTED, SENSITIVE_PATTERNS, redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\n\n// -- Constants -----------------------------------------------------------------\n\nconst AGENT_ID = \"cascade\";\nconst AGENT_TYPE = \"code-assistant\";\nconst DISPLAY_NAME = \"Cascade (Windsurf)\";\nconst ROLE_NARRATIVE =\n \"Agentic AI coding assistant embedded in Windsurf IDE. \" +\n \"Operates with multi-step planning, tool use (file editing, terminal, \" +\n \"browser preview, code search), persistent memory, and workspace-level \" +\n \"context awareness. Specializes in pair-programming workflows with \" +\n \"concurrent read-plan-execute cycles.\";\n\nconst CONVENTION_DIR_NAME = \".cascade-bourdon\";\nconst MEMORY_FILENAME = \"memory.md\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.PUBLIC,\n private_tags: [\"personal\", \"credential\", \"financial\", \"secret\", \"private\"],\n});\n\n/**\n * The native-memory sensitive-pattern set, extended with Cascade-specific\n * triggers (`secret`, `sk_test_*`). A match anywhere drops the WHOLE string to\n * the redaction sentinel (see {@link scrubCredential}). All non-global so they\n * are safe to reuse across `.test()`.\n */\nconst CASCADE_SENSITIVE_PATTERNS: readonly RegExp[] = [\n ...SENSITIVE_PATTERNS,\n /\\bsecret\\b/i,\n /sk[_-]test[_-]/i,\n];\n\n/** Minimal logger so a malformed-frontmatter warning is visible without a dep. */\nconst logger = {\n warn(msg: string): void {\n // eslint-disable-next-line no-console\n console.warn(`[bourdon.participants] ${msg}`);\n },\n};\n\n// -- Path helpers --------------------------------------------------------------\n\nfunction homeDir(): string {\n // os.homedir() can throw under some sandboxes; stay defensive so import +\n // construction never crash even when HOME points at an unreadable path.\n try {\n return homedir();\n } catch {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n }\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\n/** Return the default Cascade-Bourdon convention directory (`~/.cascade-bourdon`). */\nexport function defaultCascadeDir(): string {\n return join(homeDir(), CONVENTION_DIR_NAME);\n}\n\n/** Return the default path to the Cascade memory file. */\nexport function defaultCascadeMemoryPath(): string {\n return join(defaultCascadeDir(), MEMORY_FILENAME);\n}\n\n// -- Front-matter --------------------------------------------------------------\n\n/**\n * Extract YAML front-matter from a `---` fenced block. Returns an empty object\n * when the text has no valid front-matter. On YAML parse failure logs at WARNING\n * (with the source path when provided) and treats it as no-frontmatter.\n *\n * NOTE: this is the Cascade-specific fence parse (`startswith(\"---\")` +\n * `find(\"---\", 3)`), distinct from the claude-code reader's `---\\n` variant —\n * preserved faithfully from the oracle.\n */\nfunction parseFrontmatter(text: string, source?: string): Record<string, unknown> {\n if (!text.startsWith(\"---\")) return {};\n const end = text.indexOf(\"---\", 3);\n if (end === -1) return {};\n const yamlBlock = text.slice(3, end).trim();\n if (!yamlBlock) return {};\n let data: unknown;\n try {\n data = yamlParse(yamlBlock);\n } catch (exc) {\n const where = source ? ` in ${source}` : \"\";\n const detail = String(exc).replace(/\\n/g, \" \").slice(0, 200);\n logger.warn(\n `CascadeParticipant: malformed YAML frontmatter${where}; ` +\n `treating as no-frontmatter (${detail})`,\n );\n return {};\n }\n return typeof data === \"object\" && data !== null && !Array.isArray(data)\n ? (data as Record<string, unknown>)\n : {};\n}\n\n// -- Redaction -----------------------------------------------------------------\n\n/**\n * Redact + truncate native-memory text. Same semantics as the codex reader's\n * `_safe_native_memory_text` (the redaction SSOT), extended with Cascade-\n * specific patterns (`secret`, `sk_test_*`): if any match, drop the whole string\n * to the redaction sentinel; otherwise scrub + cap via {@link redactText}.\n */\nfunction scrubCredential(text: string): string {\n if (!text) return text;\n if (CASCADE_SENSITIVE_PATTERNS.some((p) => p.test(text))) {\n return REDACTED;\n }\n return redactText(text);\n}\n\n// -- Builders ------------------------------------------------------------------\n\n/** Python `list(x or [])`: copy a list verbatim, char-split a string, else []. */\nfunction asList(v: unknown): string[] {\n if (!v) return [];\n if (Array.isArray(v)) return v as string[];\n if (typeof v === \"string\") return Array.from(v);\n return [];\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/** Build an Entity from a raw front-matter dict entry. Returns null on invalid. */\nfunction buildEntity(raw: unknown): EntityModel | null {\n if (!isRecord(raw)) return null;\n const name = raw[\"name\"];\n if (typeof name !== \"string\" || !name.trim()) return null;\n\n let summary: string | undefined;\n const rawSummary = raw[\"summary\"];\n if (typeof rawSummary === \"string\") summary = scrubCredential(rawSummary);\n\n return makeEntity({\n name: name.trim(),\n type: typeof raw[\"type\"] === \"string\" ? (raw[\"type\"] as string) : undefined,\n summary,\n aliases: asList(raw[\"aliases\"]),\n tags: asList(raw[\"tags\"]),\n last_touched: raw[\"last_touched\"] ? String(raw[\"last_touched\"]) : undefined,\n valid_from: raw[\"valid_from\"] ? String(raw[\"valid_from\"]) : undefined,\n valid_to: raw[\"valid_to\"] ? String(raw[\"valid_to\"]) : undefined,\n visibility: undefined,\n });\n}\n\n/** Build a Session from a raw front-matter dict entry. Returns null on invalid. */\nfunction buildSession(raw: unknown): SessionModel | null {\n if (!isRecord(raw)) return null;\n const dateVal = raw[\"date\"];\n if (!dateVal) return null;\n // Normalize datetime strings to date-only (YYYY-MM-DD).\n const dateStr = String(dateVal).slice(0, 10);\n\n return makeSession({\n date: dateStr,\n cwd: raw[\"cwd\"] == null ? undefined : (raw[\"cwd\"] as string),\n key_actions: asList(raw[\"key_actions\"]),\n files_touched: asList(raw[\"files_touched\"]),\n project_focus: asList(raw[\"project_focus\"]),\n visibility: undefined,\n });\n}\n\n/**\n * Mirror `datetime.fromisoformat(date)` on a date-only string for the `since`\n * filter. Returns the UTC midnight Date, or null on a ValueError-equivalent\n * (the caller keeps the session when this is null, matching `except ValueError`).\n */\nfunction parseSessionDate(date: string): Date | null {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(date)) return null;\n const ms = Date.parse(`${date}T00:00:00Z`);\n return Number.isNaN(ms) ? null : new Date(ms);\n}\n\nfunction buildSessions(rawSessions: unknown, since?: Date): SessionModel[] {\n const list = Array.isArray(rawSessions) ? rawSessions : [];\n const sessions: SessionModel[] = [];\n for (const raw of list) {\n const session = buildSession(raw);\n if (session === null) continue;\n if (since !== undefined) {\n const d = parseSessionDate(session.date);\n if (d !== null && d.getTime() < since.getTime()) continue;\n }\n sessions.push(session);\n }\n return sessions;\n}\n\n// -- Diagnostics ---------------------------------------------------------------\n\n/** Diagnostic inspection of the Cascade memory file: presence + content stats. */\nfunction inspectCascadeMemory(cascadeDir: string): Record<string, unknown> {\n const memoryPath = join(cascadeDir, MEMORY_FILENAME);\n if (!isFile(memoryPath)) return { present: false, error: \"missing\" };\n\n let text: string;\n try {\n text = readFileSync(memoryPath, \"utf8\");\n } catch (e) {\n return { present: true, readable: false, error: String(e) };\n }\n\n const data = parseFrontmatter(text, memoryPath);\n if (Object.keys(data).length === 0) {\n return {\n present: true,\n readable: true,\n frontmatter_valid: false,\n entity_count: 0,\n session_count: 0,\n };\n }\n\n const entities = data[\"entities\"];\n const sessions = data[\"sessions\"];\n return {\n present: true,\n readable: true,\n frontmatter_valid: true,\n entity_count: Array.isArray(entities) ? entities.length : 0,\n session_count: Array.isArray(sessions) ? sessions.length : 0,\n };\n}\n\n// -- Init helper ---------------------------------------------------------------\n\nconst MEMORY_TEMPLATE = `---\nentities:\n - name: Example Project\n type: project\n summary: Replace with real project summaries\n tags: [project]\nsessions:\n - date: \"{today}\"\n cwd: /path/to/workspace\n key_actions:\n - Initialized Cascade Bourdon memory\n files_touched: []\n project_focus: []\n---\n\n# Cascade Bourdon Memory\n\nThis file is maintained by Cascade (Windsurf) for cross-agent memory federation.\nEdit the YAML front-matter to update entities and sessions.\nCascade will update this file at session end when instructed.\n`;\n\n/**\n * Create a starter memory.md in the Cascade-Bourdon convention directory.\n *\n * @param cascadeDir Override the convention directory (default `~/.cascade-bourdon`).\n * @param force Overwrite an existing file; otherwise throws.\n * @returns the path to the created memory file.\n */\nexport function initMemoryFile(cascadeDir?: string, force = false): string {\n const targetDir = cascadeDir ?? defaultCascadeDir();\n mkdirSync(targetDir, { recursive: true });\n const memoryPath = join(targetDir, MEMORY_FILENAME);\n\n if (isFile(memoryPath) && !force) {\n throw new Error(\n `Memory file already exists: ${memoryPath}. Use force=True to overwrite.`,\n );\n }\n\n const today = new Date().toISOString().slice(0, 10);\n const content = MEMORY_TEMPLATE.replace(\"{today}\", today);\n writeFileSync(memoryPath, content, \"utf8\");\n return memoryPath;\n}\n\n// -- Participant ---------------------------------------------------------------\n\n/**\n * Convention-based Bourdon participant for Cascade (Windsurf). Reads structured\n * memory from `~/.cascade-bourdon/memory.md` and normalizes it into L5.\n */\nexport class CascadeParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n displayName = DISPLAY_NAME;\n\n private readonly dir: string;\n private readonly policy: VisibilityPolicyModel;\n\n static defaultNativePath(home?: string): string {\n if (home !== undefined) return join(home, CONVENTION_DIR_NAME);\n return defaultCascadeDir();\n }\n\n constructor(cascadeDir?: string, policy?: VisibilityPolicyModel) {\n this.dir = cascadeDir ?? defaultCascadeDir();\n this.policy = policy ?? DEFAULT_POLICY;\n }\n\n /** Path to the Cascade-Bourdon convention directory. */\n get nativePath(): string {\n return this.dir;\n }\n\n private memoryPath(): string {\n return join(this.dir, MEMORY_FILENAME);\n }\n\n private readFrontmatter(): Record<string, unknown> {\n const path = this.memoryPath();\n if (!isFile(path)) return {};\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch {\n return {};\n }\n return parseFrontmatter(text, path);\n }\n\n discover(): AgentStore {\n if (!isDir(this.dir)) {\n throw new ParticipantDiscoveryError(\n `Cascade-Bourdon directory not found: ${this.dir}`,\n );\n }\n const memoryPresent = isFile(this.memoryPath());\n return {\n path: this.dir,\n version: \"unknown\",\n metadata: {\n memory_file: this.memoryPath(),\n memory_file_present: memoryPresent,\n },\n };\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const data = this.readFrontmatter();\n\n // Build entities.\n const rawEntities = data[\"entities\"];\n const entityList = Array.isArray(rawEntities) ? rawEntities : [];\n const entities: EntityModel[] = [];\n for (const raw of entityList) {\n const entity = buildEntity(raw);\n if (entity !== null) entities.push(entity);\n }\n\n // Build sessions (since-filtered).\n const sessions = buildSessions(data[\"sessions\"], since);\n\n // Apply visibility policy — filter out PRIVATE entities before emission.\n const visibleEntities = filterForFederation(entities, this.policy);\n\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: new Date().toISOString(),\n known_entities: visibleEntities,\n recent_sessions: sessions,\n capabilities: [\"chat\", \"code-editing\", \"terminal\", \"planning\", \"search\"],\n });\n }\n\n exportSessions(since?: Date, limit?: number): SessionModel[] {\n const data = this.readFrontmatter();\n const sessions = buildSessions(data[\"sessions\"], since);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n if (limit !== undefined) return sessions.slice(0, limit);\n return sessions;\n }\n\n healthCheck(): HealthStatus {\n if (!isDir(this.dir)) {\n return {\n status: \"blocked\",\n reason: \"Cascade-Bourdon directory not found\",\n details: { expected_path: this.dir },\n proposedFix:\n \"Run `bourdon cascade init` to create the convention directory + starter memory.md.\",\n };\n }\n\n const report = inspectCascadeMemory(this.dir);\n if (!report[\"present\"]) {\n return {\n status: \"degraded\",\n reason: \"Memory file not found; run `bourdon cascade init` to create it\",\n details: report,\n proposedFix:\n \"Run `bourdon cascade init` to write the starter memory.md template.\",\n };\n }\n\n if (!report[\"readable\"]) {\n return {\n status: \"degraded\",\n reason: `Memory file not readable: ${String(report[\"error\"])}`,\n details: report,\n proposedFix:\n `Check filesystem permissions on ${join(this.dir, \"memory.md\")} ` +\n \"(should be readable by your user).\",\n };\n }\n\n if (!report[\"frontmatter_valid\"]) {\n return {\n status: \"degraded\",\n reason: \"Memory file has no valid YAML front-matter\",\n details: report,\n proposedFix:\n `Inspect ${join(this.dir, \"memory.md\")} -- the opening and closing ` +\n \"`---` fences must wrap a valid YAML block. Run \" +\n \"`bourdon cascade init --force` to reset to the template \" +\n \"(WARNING: this overwrites existing content).\",\n };\n }\n\n return {\n status: \"ok\",\n details: report,\n };\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * OpenClaw participant — network-shaped, QUARANTINED-CLASS. Port of\n * `participants/openclaw.py` (v0.9.0, spec R4/D9).\n *\n * OpenClaw is the highest-demand adapter target in the ecosystem and also its\n * highest-risk agent class: CVE-2026-25253 (one-click RCE, CVSS 8.8, first\n * patched in 2026.1.29), tens of thousands of internet-exposed instances (~93%\n * without authentication), ClawHub's malicious-skill problem, and auth disabled\n * by default on port 8080. Bourdon therefore treats OpenClaw differently from\n * every on-disk participant:\n *\n * 1. **Network-shaped** — state is read from the OpenClaw instance's local\n * HTTP API, not on-disk artifacts. Because the {@link BourdonParticipant}\n * contract is SYNCHRONOUS (`discover`/`exportL5` return values, not\n * Promises) and `fetch` is async, the reads go through a tiny synchronous\n * `curl` shell-out (the same idiom as the github-copilot reader).\n * 2. **Hard handshake gate** — {@link OpenClawParticipant.discover} refuses to\n * talk to an instance that is unpatched (< 2026.1.29) or has authentication\n * disabled. These are refusals with exact reasons AND fixes, not warnings,\n * and every read re-runs the gate.\n * 3. **Quarantined-class** — `quarantinedClass = true`: registering the agent\n * trusted requires `--i-understand-the-risk`, and exports stage for\n * operator review (spec D6: quarantine follows the content, not the\n * invoker). Its content federates under TEAM, never PUBLIC.\n *\n * We gate on instance hygiene (version, auth) — NOT on auditing the user's\n * installed skills; that's ClawSecure et al.'s job (spec non-goal 3).\n */\n\nimport { execFileSync } from \"node:child_process\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\n\n// -- Constants -----------------------------------------------------------------\n\nconst AGENT_ID = \"openclaw\";\nconst AGENT_TYPE = \"other\";\nconst DISPLAY_NAME = \"OpenClaw (quarantined)\";\nconst ROLE_NARRATIVE =\n \"OpenClaw personal AI assistant — federated as a QUARANTINED member: \" +\n \"its reads are limited to granted namespaces and its writes are staged \" +\n \"for operator review.\";\n\n/** First OpenClaw release that patches CVE-2026-25253 (one-click RCE). */\nexport const MIN_PATCHED_VERSION = \"2026.1.29\";\n\nconst DEFAULT_OPENCLAW_URL = \"http://127.0.0.1:8080\";\n\nconst SESSION_LIMIT = 50;\nconst ENTITY_LIMIT = 100;\n\n// -- Helpers -------------------------------------------------------------------\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/**\n * `_safe_native_memory_text(v)` in Python == `redact_text(v, limit=180)`. The\n * TS redaction SSOT exposes `redactText(value, limit = 180)` (positional), so\n * we pass the cap explicitly to make the surface's 180-char limit load-bearing.\n */\nfunction safeNativeMemoryText(value: string): string {\n return redactText(value, 180);\n}\n\n/**\n * `\"2026.1.29\"` -> `[2026, 1, 29]`. Tolerates suffixes like `\"2026.1.29-beta\"`;\n * returns null when nothing numeric parses. Faithful port of `_parse_version`.\n */\nfunction parseVersion(value: string): number[] | null {\n const parts: number[] = [];\n for (const chunk of String(value ?? \"\").trim().split(\".\")) {\n const match = /^(\\d+)/.exec(chunk);\n if (!match) break;\n parts.push(Number(match[1]));\n }\n return parts.length > 0 ? parts : null;\n}\n\n/** Tuple comparison mirroring Python's `tuple < tuple` (lexicographic, shorter\n * is smaller when it is a prefix). */\nfunction versionLessThan(a: number[], b: number[]): boolean {\n const n = Math.max(a.length, b.length);\n for (let i = 0; i < n; i += 1) {\n const av = i < a.length ? (a[i] as number) : undefined;\n const bv = i < b.length ? (b[i] as number) : undefined;\n if (av === undefined) return true; // a is a shorter prefix of b\n if (bv === undefined) return false; // b is a shorter prefix of a\n if (av < bv) return true;\n if (av > bv) return false;\n }\n return false;\n}\n\n/** `_status_version`: first non-empty of version / openclaw_version / app_version. */\nfunction statusVersion(status: Record<string, unknown>): string {\n for (const key of [\"version\", \"openclaw_version\", \"app_version\"]) {\n const value = status[key];\n if (typeof value === \"string\" && value.trim()) return value.trim();\n }\n return \"\";\n}\n\n/** `_status_auth_enabled`: auth_enabled / authEnabled / auth.enabled. */\nfunction statusAuthEnabled(status: Record<string, unknown>): boolean {\n for (const key of [\"auth_enabled\", \"authEnabled\"]) {\n if (key in status) return Boolean(status[key]);\n }\n const auth = status[\"auth\"];\n if (isRecord(auth)) return Boolean(auth[\"enabled\"]);\n return false;\n}\n\n/**\n * Hard handshake preconditions (spec D9). Returns the version on success.\n * Raises {@link ParticipantDiscoveryError} with the exact reason AND the fix —\n * these are refusals, not warnings.\n */\nexport function verifyInstance(status: Record<string, unknown>, url: string): string {\n const version = statusVersion(status);\n const parsed = parseVersion(version);\n const minimum = parseVersion(MIN_PATCHED_VERSION) as number[];\n if (parsed === null) {\n throw new ParticipantDiscoveryError(\n `OpenClaw at ${url} did not report a parseable version ` +\n `(got ${JSON.stringify(version)}). Refusing handshake: cannot verify the ` +\n `CVE-2026-25253 patch level. Fix: upgrade OpenClaw to ` +\n `>= ${MIN_PATCHED_VERSION} and ensure /api/status reports it.`,\n );\n }\n if (versionLessThan(parsed, minimum)) {\n throw new ParticipantDiscoveryError(\n `OpenClaw at ${url} runs ${version}, which predates the ` +\n `CVE-2026-25253 patch (one-click RCE, CVSS 8.8). Refusing ` +\n `handshake. Fix: upgrade OpenClaw to >= ${MIN_PATCHED_VERSION}.`,\n );\n }\n if (!statusAuthEnabled(status)) {\n throw new ParticipantDiscoveryError(\n `OpenClaw at ${url} has authentication DISABLED (the exposed-` +\n \"instance default). Refusing handshake. Fix: enable auth in \" +\n \"your OpenClaw config (set auth.enabled=true / OPENCLAW_AUTH=1), \" +\n \"restart the instance, and set OPENCLAW_TOKEN for Bourdon.\",\n );\n }\n return version;\n}\n\n/**\n * Mirror `_before`: return true when `dateText` is strictly before `since`.\n * Reproduces `datetime.fromisoformat(dateText.replace(\"Z\",\"+00:00\"))` with the\n * naive→UTC coercion, and returns false on a parse (ValueError) miss so the\n * caller keeps the session.\n */\nfunction before(dateText: string, since: Date): boolean {\n const parsed = fromIsoformatUtc(dateText.replace(/Z/g, \"+00:00\"));\n if (parsed === null) return false; // ValueError -> keep\n return parsed.getTime() < since.getTime();\n}\n\n/**\n * A best-effort `datetime.fromisoformat` for the two shapes OpenClaw emits\n * (date-only and datetime, with or without an offset). A naive value (no\n * offset) is interpreted as UTC — matching the Python `parsed.replace(\n * tzinfo=timezone.utc)`. Returns null on an unparseable value.\n */\nfunction fromIsoformatUtc(text: string): Date | null {\n const value = text.trim();\n if (!value) return null;\n const hasOffset = /[+-]\\d{2}:?\\d{2}$/.test(value);\n // date-only ISO is already interpreted as UTC midnight by Date.parse;\n // a naive datetime (\"...T..\") must be pinned to UTC with a trailing Z.\n const normalized = hasOffset || !value.includes(\"T\") ? value : `${value}Z`;\n const ms = Date.parse(normalized);\n return Number.isNaN(ms) ? null : new Date(ms);\n}\n\n/** Python `str(now_utc, \"%Y-%m-%dT%H:%M:%SZ\")` — second precision, Z suffix. */\nfunction nowIsoSeconds(): string {\n return new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\");\n}\n\n// -- HTTP ----------------------------------------------------------------------\n\ninterface CurlResponse {\n status: number;\n body: string;\n}\n\n/**\n * Synchronous GET via a tiny `curl` shell-out — the base contract is\n * synchronous (matching the Python `urllib` reference), so `fetch` cannot be\n * used. `-w` appends the HTTP status on a trailing sentinel line for parsing.\n * Throws when curl itself fails (connection refused / timeout / DNS), which the\n * caller maps to \"instance unreachable\".\n */\nfunction curlGet(url: string, token: string | undefined, timeoutSec: number): CurlResponse {\n const args = [\"-sS\", \"-o\", \"-\", \"--max-time\", String(timeoutSec)];\n if (token) {\n args.push(\"-H\", `Authorization: Bearer ${token}`);\n }\n args.push(\"-w\", \"\\n__BOURDON_STATUS__%{http_code}\", url);\n\n const raw = execFileSync(\"curl\", args, {\n encoding: \"utf8\",\n timeout: (timeoutSec + 2) * 1000,\n maxBuffer: 8 * 1024 * 1024,\n });\n\n const statusMatch = /\\n__BOURDON_STATUS__(\\d+)$/.exec(raw);\n const status = statusMatch ? Number(statusMatch[1]) : 0;\n const body = statusMatch ? raw.slice(0, statusMatch.index) : raw;\n return { status, body };\n}\n\n/**\n * Minimal HTTP client for a local OpenClaw instance. Read-only: status,\n * sessions, memories. Failures raise {@link ParticipantDiscoveryError} with the\n * reason — the participant decides how to surface them.\n *\n * Error mapping (faithful to the Python `urllib` client): an HTTP >= 400\n * response -> \"returned HTTP {code}\"; a transport failure / timeout / non-JSON\n * body -> \"instance unreachable at {url}\".\n */\nexport class OpenClawApiClient {\n readonly url: string;\n private readonly token: string | undefined;\n readonly timeout: number;\n\n constructor(url: string, token?: string, timeout = 5.0) {\n this.url = url.replace(/\\/+$/, \"\");\n this.token = token;\n this.timeout = timeout;\n }\n\n private get(path: string): unknown {\n let resp: CurlResponse;\n try {\n resp = curlGet(this.url + path, this.token, this.timeout);\n } catch (err) {\n throw new ParticipantDiscoveryError(\n `OpenClaw instance unreachable at ${this.url} (${String(err)})`,\n );\n }\n if (resp.status >= 400) {\n throw new ParticipantDiscoveryError(\n `OpenClaw API ${path} returned HTTP ${resp.status}`,\n );\n }\n if (resp.status === 0) {\n throw new ParticipantDiscoveryError(\n `OpenClaw instance unreachable at ${this.url} (no HTTP response)`,\n );\n }\n try {\n return JSON.parse(resp.body);\n } catch (err) {\n throw new ParticipantDiscoveryError(\n `OpenClaw instance unreachable at ${this.url} (${String(err)})`,\n );\n }\n }\n\n status(): Record<string, unknown> {\n const data = this.get(\"/api/status\");\n return isRecord(data) ? data : {};\n }\n\n sessions(): Record<string, unknown>[] {\n return this.readCollection(\"/api/sessions\", \"sessions\");\n }\n\n memories(): Record<string, unknown>[] {\n return this.readCollection(\"/api/memories\", \"memories\");\n }\n\n /** Shared `sessions()`/`memories()` body: try/except-returns-[], unwrap the\n * `{ \"<key>\": [...] }` envelope, and keep only object rows. */\n private readCollection(path: string, key: string): Record<string, unknown>[] {\n let data: unknown;\n try {\n data = this.get(path);\n } catch (err) {\n if (err instanceof ParticipantDiscoveryError) return [];\n throw err;\n }\n if (isRecord(data)) {\n data = data[key] || [];\n }\n if (!Array.isArray(data)) return [];\n return data.filter(isRecord);\n }\n}\n\n// -- Participant ---------------------------------------------------------------\n\n/** Bourdon participant for OpenClaw (quarantined class). */\nexport class OpenClawParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n displayName = DISPLAY_NAME;\n /** Trust marker consumed by `bourdon agent add/set-tier` + export-all:\n * registering as trusted needs --i-understand-the-risk; exports stage. */\n quarantinedClass = true;\n\n readonly url: string;\n private readonly client: OpenClawApiClient;\n\n static defaultNativePath(home?: string): string {\n // Network-shaped: shown in the wizard for orientation only. The actual\n // store is the instance API (OPENCLAW_URL).\n return join(home ?? homedir(), \".openclaw\");\n }\n\n constructor(url?: string, token?: string, client?: OpenClawApiClient) {\n this.url = (url || process.env.OPENCLAW_URL || DEFAULT_OPENCLAW_URL).replace(/\\/+$/, \"\");\n this.client = client ?? new OpenClawApiClient(this.url, token ?? process.env.OPENCLAW_TOKEN);\n }\n\n get nativePath(): string {\n return this.url;\n }\n\n // -- protocol ----------------------------------------------------------------\n\n discover(): AgentStore {\n const status = this.client.status();\n const version = verifyInstance(status, this.url);\n return {\n path: this.url,\n version,\n metadata: { auth_enabled: true, transport: \"http\" },\n };\n }\n\n exportSessions(since?: Date, limit: number = SESSION_LIMIT): SessionModel[] {\n this.discover(); // handshake gate applies to every read\n const sessions: SessionModel[] = [];\n for (const row of this.client.sessions()) {\n const date = String(row[\"updated_at\"] || row[\"started_at\"] || row[\"date\"] || \"\").trim();\n if (!date) continue;\n if (since !== undefined && before(date, since)) continue;\n const title = safeNativeMemoryText(String(row[\"title\"] || row[\"summary\"] || \"\"));\n const projects = Array.isArray(row[\"projects\"]) ? row[\"projects\"].slice(0, 5) : [];\n sessions.push(\n makeSession({\n date,\n cwd: undefined,\n project_focus: projects.map((p) => safeNativeMemoryText(String(p))),\n key_actions: title ? [title] : [],\n }),\n );\n if (sessions.length >= limit) break;\n }\n return sessions;\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const store = this.discover();\n const entities: EntityModel[] = [];\n for (const row of this.client.memories().slice(0, ENTITY_LIMIT)) {\n const name = safeNativeMemoryText(String(row[\"name\"] || row[\"title\"] || \"\"));\n if (!name) continue;\n const tags = Array.isArray(row[\"tags\"]) ? row[\"tags\"].slice(0, 8) : [];\n entities.push(\n makeEntity({\n name,\n type: String(row[\"type\"] || \"topic\"),\n summary: safeNativeMemoryText(String(row[\"summary\"] || \"\")),\n tags: tags.map((t) => safeNativeMemoryText(String(t))),\n }),\n );\n }\n // Quarantined-class content defaults to TEAM, never PUBLIC: it only\n // federates beyond the local library after an explicit operator promotion\n // AND a team-level read.\n const policy: VisibilityPolicyModel = makeVisibilityPolicy({ default: Visibility.TEAM });\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: this.url,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: nowIsoSeconds(),\n capabilities: [`openclaw ${store.version}`],\n recent_sessions: this.exportSessions(since),\n known_entities: filterForFederation(entities, policy),\n visibility_policy: policy,\n });\n }\n\n healthCheck(): HealthStatus {\n let store: AgentStore;\n try {\n store = this.discover();\n } catch (exc) {\n if (exc instanceof ParticipantDiscoveryError) {\n const reason = exc.message;\n let fix = \"see the refusal reason above\";\n if (reason.includes(\"upgrade OpenClaw\")) {\n fix = `upgrade the OpenClaw instance to >= ${MIN_PATCHED_VERSION}`;\n } else if (reason.includes(\"authentication DISABLED\")) {\n fix = \"enable auth on the OpenClaw instance, then set OPENCLAW_TOKEN\";\n } else if (reason.includes(\"unreachable\")) {\n fix =\n \"start OpenClaw locally or set OPENCLAW_URL to the instance address\";\n }\n return { status: \"blocked\", reason, proposedFix: fix, details: {} };\n }\n // health_check must never raise.\n return {\n status: \"degraded\",\n reason: exc instanceof Error ? exc.message : String(exc),\n details: {},\n };\n }\n return {\n status: \"ok\",\n details: { url: this.url, version: store.version, quarantined: true },\n };\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Claude Code automations participant — publishes background-run memory as L5\n * evidence. Port of `participants/claude_code_automations.py`.\n *\n * Convention-file reader over the `~/.claude/automations/<id>/` tree:\n * automation.toml — id, name, status, schedule (rrule), kind, cwds\n * memory.md — dated bullet entries, one block per run\n *\n * Each `automation.toml` becomes a known Entity (`type: automation`); each dated\n * section of `memory.md` becomes a recent Session. Mirrors the Codex automation\n * publisher — it covers the federation gap that the interactive-only\n * `claude-code` participant leaves behind (automations whose work never touches\n * agent-brain / auto-memory / the MCP knowledge graph).\n *\n * Privacy: every native string routes through the redaction SSOT\n * (`redactText`, == the oracle's `_safe_native_memory_text`); the visibility\n * policy filters PRIVATE entities before emission. `healthCheck` never throws.\n */\n\nimport {\n mkdirSync,\n readdirSync,\n readFileSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir, hostname } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport { parse as parseToml } from \"smol-toml\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n loadProjectHints,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\n\n// -- Constants -----------------------------------------------------------------\n\nconst AGENT_ID = \"claude-code-automations\";\nconst AGENT_TYPE = \"other\";\nconst ROLE_NARRATIVE =\n \"Publishes read-only Claude Code automation run memory into Bourdon so \" +\n \"scheduled /loop continuations, CronCreate jobs, GitHub Action runs of \" +\n \"claude-code-action, and /schedule remote-routine summaries become \" +\n \"visible alongside interactive Claude Code sessions.\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"health\", \"family\", \"legal\"],\n team_tags: [\"claude-code-automation\", \"automation\", \"workspace\"],\n});\n\nconst AUTOMATIONS_DIR_NAME = \"automations\";\nconst AUTOMATION_TOML = \"automation.toml\";\nconst MEMORY_MD = \"memory.md\";\nconst MAX_MEMORY_CHARS = 160_000;\nconst MAX_KEY_ACTIONS_PER_RUN = 6;\nconst MAX_KEY_ACTION_CHARS = 280;\n\n/** `^(\\d{4}-\\d{2}-\\d{2})(?:\\b|$)(.*)$` — anchored, non-global (safe to reuse). */\nconst RUN_HEADER_RE = /^(\\d{4}-\\d{2}-\\d{2})(?:\\b|$)(.*)$/;\nconst BULLET_RE = /^[-*]\\s+(.*)$/;\n/** Chars stripped from a run-header suffix (space, hyphen, colon, em-dash). */\nconst HEADER_SUFFIX_STRIP = \" -:—\";\n\n// Product-neutral defaults only: this product plus the agent surfaces Bourdon\n// federates. A deployment adds its own project roster via the\n// `BOURDON_PROJECT_HINTS` env var (comma-separated) — see `loadProjectHints`.\nconst DEFAULT_PROJECT_HINTS: readonly string[] = [\n \"Bourdon\",\n \"Cursor\",\n \"Copilot\",\n \"Codex\",\n \"Cascade\",\n];\n\n/** Signal-class name → case-insensitive, NON-GLOBAL matcher. */\nconst SIGNAL_PATTERNS: ReadonlyArray<readonly [string, RegExp]> = [\n [\"human-dashboard-action\", /\\b(human|dashboard|manual)\\b/i],\n [\"release-gate\", /\\b(release|store|app review|play console|testflight)\\b/i],\n [\"billing-drift\", /\\b(billing|stripe|revenuecat|iap|subscription)\\b/i],\n [\"memory-coverage-gap\", /\\b(memory|l5|manifest|federated|bourdon)\\b/i],\n [\"launch-decision\", /\\b(launch|go-live|pricing|prod|production)\\b/i],\n [\"ci-signal\", /\\b(github action|workflow run|ci failure|gh action)\\b/i],\n];\n\n/** Minimal logger so a degraded read is visible without pulling in a dep. */\nconst logger = {\n warn(msg: string): void {\n // eslint-disable-next-line no-console\n console.warn(`[bourdon.participants] ${msg}`);\n },\n};\n\n// -- Types ---------------------------------------------------------------------\n\ninterface AutomationConfig {\n automationId: string;\n name: string;\n status: string;\n rrule: string;\n kind: string;\n cwds: string[];\n /** Path to the automation.toml file. */\n path: string;\n /** Path to memory.md, or null when it is not a regular file. */\n memoryPath: string | null;\n}\n\ninterface AutomationRun {\n automation: AutomationConfig;\n date: string;\n title: string;\n keyActions: string[];\n projects: string[];\n signals: string[];\n}\n\n/** Summary of a {@link mergeAutomationTree} call. */\nexport interface MergeResult {\n automationsSeen: number;\n automationsCreated: number;\n bulletsAdded: number;\n sectionsCreated: number;\n skipped: string[];\n}\n\n// -- fs helpers ----------------------------------------------------------------\n\nfunction homeDir(): string {\n // os.homedir() can throw under some sandboxes; stay defensive so import +\n // construction never crash even when HOME points at an unreadable path.\n try {\n return homedir();\n } catch {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n }\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\nfunction exists(p: string): boolean {\n try {\n statSync(p);\n return true;\n } catch {\n return false;\n }\n}\n\n// -- Python-semantic string helpers -------------------------------------------\n\n/** Python truthiness for the value kinds YAML/TOML yield here. */\nfunction truthy(v: unknown): boolean {\n if (v === undefined || v === null || v === false || v === 0 || v === \"\") return false;\n if (Array.isArray(v)) return v.length > 0;\n if (typeof v === \"object\") return Object.keys(v as object).length > 0;\n return true;\n}\n\n/** Mirror Python `str(value)` for the scalar types encountered here. */\nfunction pyStr(v: unknown): string {\n if (v === true) return \"True\";\n if (v === false) return \"False\";\n if (v === null || v === undefined) return \"None\";\n return String(v);\n}\n\n/** Mirror `str(a or b)` — pick `a` if truthy else `b`, then `str()`. */\nfunction strOr(a: unknown, b: unknown): string {\n return pyStr(truthy(a) ? a : b);\n}\n\n/** Python `str.rstrip()` — drop trailing whitespace. */\nfunction rstrip(s: string): string {\n return s.replace(/\\s+$/, \"\");\n}\n\n/** Python `str.strip(chars)` — strip any of `chars` from both ends. */\nfunction stripChars(s: string, chars: string): string {\n let start = 0;\n let end = s.length;\n while (start < end && chars.includes(s[start]!)) start++;\n while (end > start && chars.includes(s[end - 1]!)) end--;\n return s.slice(start, end);\n}\n\n/** Approximate Python `str.splitlines()` (no trailing empty for a final EOL). */\nfunction splitLines(s: string): string[] {\n const parts = s.split(/\\r\\n|\\r|\\n/);\n if (parts.length > 0 && parts[parts.length - 1] === \"\") parts.pop();\n return parts;\n}\n\n// -- Path resolution -----------------------------------------------------------\n\n/**\n * Default Claude Code automations directory. Precedence:\n * 1. explicit `claudeHome` argument (tests)\n * 2. `CLAUDE_HOME` env var\n * 3. `~/.claude/` (conventional per-user default)\n */\nexport function defaultClaudeCodeAutomationsDir(claudeHome?: string): string {\n if (claudeHome !== undefined) return join(claudeHome, AUTOMATIONS_DIR_NAME);\n const env = process.env.CLAUDE_HOME;\n if (env) return join(env, AUTOMATIONS_DIR_NAME);\n return join(homeDir(), \".claude\", AUTOMATIONS_DIR_NAME);\n}\n\n// -- TOML config parsing -------------------------------------------------------\n\nfunction readAutomationToml(path: string): Record<string, unknown> {\n let raw: unknown;\n try {\n raw = parseToml(readFileSync(path, \"utf8\"));\n } catch (exc) {\n logger.warn(\n `ClaudeCodeAutomationsParticipant: cannot parse ${path}: ${String(exc)}`,\n );\n return {};\n }\n return typeof raw === \"object\" && raw !== null && !Array.isArray(raw)\n ? (raw as Record<string, unknown>)\n : {};\n}\n\nfunction buildConfig(tomlPath: string): AutomationConfig | null {\n const raw = readAutomationToml(tomlPath);\n const parent = dirname(tomlPath);\n const parentName = basenameOf(parent);\n\n const automationId = strOr(raw[\"id\"], parentName).trim();\n if (!automationId) return null;\n\n const name = strOr(raw[\"name\"], automationId).trim();\n const status = strOr(raw[\"status\"], \"UNKNOWN\").trim().toUpperCase();\n const rrule = strOr(raw[\"rrule\"], \"\").trim();\n const kind = strOr(raw[\"kind\"], \"\").trim();\n\n const cwdsRaw: unknown = truthy(raw[\"cwds\"]) ? raw[\"cwds\"] : [];\n const cwds: string[] = [];\n // Faithful to `for cwd in cwds_raw if isinstance(cwd, str) and cwd.strip()`:\n // arrays iterate elements, a string iterates characters. Other (non-iterable)\n // types yield no cwds here (the oracle would raise; see port notes).\n if (Array.isArray(cwdsRaw)) {\n for (const cwd of cwdsRaw) {\n if (typeof cwd === \"string\" && cwd.trim()) cwds.push(cwd);\n }\n } else if (typeof cwdsRaw === \"string\") {\n for (const ch of cwdsRaw) {\n if (ch.trim()) cwds.push(ch);\n }\n }\n\n const memoryPath = join(parent, MEMORY_MD);\n return {\n automationId,\n name,\n status,\n rrule,\n kind,\n cwds,\n path: tomlPath,\n memoryPath: isFile(memoryPath) ? memoryPath : null,\n };\n}\n\n/** `os.path.basename` that also handles a trailing separator like Path.name. */\nfunction basenameOf(p: string): string {\n const cleaned = p.replace(/[/\\\\]+$/, \"\");\n const idx = Math.max(cleaned.lastIndexOf(\"/\"), cleaned.lastIndexOf(\"\\\\\"));\n return idx === -1 ? cleaned : cleaned.slice(idx + 1);\n}\n\nfunction iterConfigs(automationsDir: string): AutomationConfig[] {\n const configs: AutomationConfig[] = [];\n if (!isDir(automationsDir)) return configs;\n // Mirror `sorted(dir.glob(\"*/automation.toml\"))`: one directory level deep,\n // sorted by full path (== sorted by subdir name given the shared prefix).\n const tomlPaths: string[] = [];\n let entries: string[];\n try {\n entries = readdirSync(automationsDir);\n } catch {\n return configs;\n }\n for (const entry of entries) {\n const sub = join(automationsDir, entry);\n if (!isDir(sub)) continue;\n const tomlPath = join(sub, AUTOMATION_TOML);\n if (isFile(tomlPath)) tomlPaths.push(tomlPath);\n }\n tomlPaths.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n for (const tomlPath of tomlPaths) {\n const config = buildConfig(tomlPath);\n if (config !== null) configs.push(config);\n }\n return configs;\n}\n\n// -- memory.md → runs ----------------------------------------------------------\n\nfunction readMemoryText(path: string | null): string {\n if (path === null) return \"\";\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch (exc) {\n logger.warn(\n `ClaudeCodeAutomationsParticipant: cannot read ${path}: ${String(exc)}`,\n );\n return \"\";\n }\n return text.slice(-MAX_MEMORY_CHARS);\n}\n\nfunction extractMemoryRuns(config: AutomationConfig): AutomationRun[] {\n const text = readMemoryText(config.memoryPath);\n if (!text) return [];\n\n const chunks: Array<[string, string[]]> = [];\n let currentDate = \"\";\n let currentLines: string[] = [];\n for (const rawLine of splitLines(text)) {\n const line = rstrip(rawLine);\n const match = RUN_HEADER_RE.exec(line.trim());\n if (match) {\n if (currentDate) chunks.push([currentDate, currentLines]);\n currentDate = match[1]!;\n const suffix = stripChars(match[2] ?? \"\", HEADER_SUFFIX_STRIP);\n currentLines = suffix ? [suffix] : [];\n continue;\n }\n if (currentDate) currentLines.push(line);\n }\n if (currentDate) chunks.push([currentDate, currentLines]);\n\n const runs: AutomationRun[] = [];\n for (const [runDate, lines] of chunks) {\n const actions = actionsFromLines(lines);\n if (actions.length === 0) continue;\n const body = actions.join(\" \");\n const title = titleFromActions(config, actions);\n runs.push({\n automation: config,\n date: runDate,\n title,\n keyActions: actions,\n projects: inferProjects(body),\n signals: inferSignals(body),\n });\n }\n return runs;\n}\n\nfunction actionsFromLines(lines: string[]): string[] {\n const actions: string[] = [];\n for (const line of lines) {\n let cleaned = line.trim();\n if (!cleaned) continue;\n cleaned = removePrefix(cleaned, \"- \").trim();\n const lowered = cleaned.toLowerCase();\n if (!cleaned || lowered.startsWith(\"runtime\")) continue;\n if (lowered === \"first run\" || lowered === \"follow-up\") continue;\n if (lowered.startsWith(\"run:\")) cleaned = cleaned.slice(4).trim();\n const safe = bounded(safeNativeMemoryText(cleaned), MAX_KEY_ACTION_CHARS);\n if (safe && !actions.includes(safe)) actions.push(safe);\n if (actions.length >= MAX_KEY_ACTIONS_PER_RUN) break;\n }\n return actions;\n}\n\n/** Python `str.removeprefix`. */\nfunction removePrefix(s: string, prefix: string): string {\n return s.startsWith(prefix) ? s.slice(prefix.length) : s;\n}\n\n/** The oracle's `_safe_native_memory_text(v)` == `redactText(v, 180)`. */\nfunction safeNativeMemoryText(value: string): string {\n return redactText(value, 180);\n}\n\nfunction titleFromActions(config: AutomationConfig, actions: string[]): string {\n if (actions.length === 0) return config.name;\n const first = actions[0]!;\n const prefix = `${config.name}: `;\n if (first.startsWith(prefix)) return bounded(first, 120);\n return bounded(prefix + first, 120);\n}\n\nfunction inferProjects(text: string): string[] {\n const projects: string[] = [];\n const lowered = text.toLowerCase();\n const seen = new Set<string>();\n for (const project of loadProjectHints(DEFAULT_PROJECT_HINTS)) {\n const key = project.toLowerCase();\n if (lowered.includes(key) && !seen.has(key)) {\n projects.push(project);\n seen.add(key);\n }\n }\n return projects;\n}\n\nfunction inferSignals(text: string): string[] {\n const signals: string[] = [];\n for (const [name, pattern] of SIGNAL_PATTERNS) {\n if (pattern.test(text)) signals.push(name);\n }\n return signals;\n}\n\n/** `\" \".join(value.split())`, then cap at `limit` with a `...` tail (limit-1). */\nfunction bounded(value: string, limit: number): string {\n const normalized = value.trim().replace(/\\s+/g, \" \");\n if (normalized.length <= limit) return normalized;\n return rstrip(normalized.slice(0, limit - 1)) + \"...\";\n}\n\n// -- run → session / entities --------------------------------------------------\n\nfunction sessionFromRun(run: AutomationRun): SessionModel {\n const config = run.automation;\n const keyActions = [\n `automation_id: ${config.automationId}`,\n `run: ${run.title}`,\n ...run.keyActions,\n ];\n const filesTouched = [config.path];\n if (config.memoryPath !== null) filesTouched.push(config.memoryPath);\n return makeSession({\n date: run.date,\n cwd: config.cwds.length > 0 ? config.cwds[0] : dirname(config.path),\n project_focus: [...run.projects],\n key_actions: keyActions.slice(0, MAX_KEY_ACTIONS_PER_RUN + 2),\n files_touched: filesTouched,\n visibility: Visibility.TEAM,\n });\n}\n\nfunction entitiesFromConfigsAndRuns(\n configs: AutomationConfig[],\n runs: AutomationRun[],\n): EntityModel[] {\n // Insertion-ordered map (Python dict) — configs first, then run projects +\n // signals via setdefault (first-wins).\n const byName = new Map<string, EntityModel>();\n\n for (const config of configs) {\n byName.set(\n config.automationId,\n makeEntity({\n name: config.automationId,\n type: \"automation\",\n summary: bounded(\n `Claude Code automation '${config.name}' (${config.status}). ` +\n `Schedule: ${config.rrule || \"unspecified\"}.`,\n 260,\n ),\n last_touched: undefined,\n tags: [\"claude-code-automation\", \"automation\", config.status.toLowerCase()],\n visibility: Visibility.TEAM,\n }),\n );\n }\n\n for (const run of runs) {\n for (const project of run.projects) {\n if (!byName.has(project)) {\n byName.set(\n project,\n makeEntity({\n name: project,\n type: \"project\",\n summary: \"Project mentioned by Claude Code automation run memory.\",\n last_touched: run.date,\n tags: [\"claude-code-automation\", \"automation-evidence\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n for (const signal of run.signals) {\n if (!byName.has(signal)) {\n byName.set(\n signal,\n makeEntity({\n name: signal,\n type: \"automation-signal\",\n summary: \"Signal class inferred from Claude Code automation run memory.\",\n last_touched: run.date,\n tags: [\"claude-code-automation\", \"automation-signal\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n }\n return [...byName.values()];\n}\n\n// -- memory.md section merge (ingestion utility) -------------------------------\n\n/**\n * Split memory.md text into `[date_header, bullets]` sections. Tolerates\n * `2026-06-03`, `2026-06-03 -- subtitle`, and same-line `2026-06-03 run: ...`.\n * Content before the first date header is discarded.\n */\nfunction parseMemorySections(text: string): Array<[string, string[]]> {\n const sections: Array<[string, string[]]> = [];\n let currentDate = \"\";\n let currentBullets: string[] = [];\n for (const rawLine of splitLines(text)) {\n const line = rstrip(rawLine);\n const match = RUN_HEADER_RE.exec(line.trim());\n if (match) {\n if (currentDate) sections.push([currentDate, currentBullets]);\n currentDate = match[1]!;\n const suffix = stripChars(match[2] ?? \"\", HEADER_SUFFIX_STRIP);\n currentBullets = [];\n if (suffix) currentBullets.push(suffix);\n continue;\n }\n if (!currentDate) continue;\n const bulletMatch = BULLET_RE.exec(line.trim());\n if (bulletMatch) currentBullets.push((bulletMatch[1] ?? \"\").trim());\n }\n if (currentDate) sections.push([currentDate, currentBullets]);\n return sections;\n}\n\n/** Render `[date, bullets]` sections back to memory.md form. */\nfunction serializeSections(sections: Array<[string, string[]]>): string {\n const blocks: string[] = [];\n for (const [dateStr, bullets] of sections) {\n const lines = [dateStr, ...bullets.map((b) => `- ${b}`)];\n blocks.push(lines.join(\"\\n\"));\n }\n return blocks.join(\"\\n\\n\") + \"\\n\";\n}\n\nconst AUTOMATION_ID_RE = /^[A-Za-z0-9._-]+$/;\n\n/**\n * Merge an `automations/<id>/` tree from `sourceDir` into `destDir`. Copies new\n * automations wholesale (stubbing automation.toml when absent) and merges\n * memory.md bullets per-date (exact-string dedupe). Idempotent. Designed for\n * ingesting GitHub Action workflow artifacts.\n */\nexport function mergeAutomationTree(\n sourceDir: string,\n destDir: string,\n defaultKind = \"github-action\",\n): MergeResult {\n if (!isDir(sourceDir)) {\n throw new Error(`merge source not found: ${sourceDir}`);\n }\n mkdirSync(destDir, { recursive: true });\n\n let seen = 0;\n let created = 0;\n let bulletsAdded = 0;\n let sectionsCreated = 0;\n const skipped: string[] = [];\n\n const srcEntries = readdirSync(sourceDir).sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n for (const entry of srcEntries) {\n const srcIdDir = join(sourceDir, entry);\n if (!isDir(srcIdDir)) continue;\n seen += 1;\n const automationId = entry;\n if (!AUTOMATION_ID_RE.test(automationId)) {\n skipped.push(automationId);\n continue;\n }\n\n const destIdDir = join(destDir, automationId);\n const srcToml = join(srcIdDir, AUTOMATION_TOML);\n const srcMemory = join(srcIdDir, MEMORY_MD);\n\n if (!exists(destIdDir)) {\n mkdirSync(destIdDir, { recursive: true });\n created += 1;\n if (isFile(srcToml)) {\n writeFileSync(join(destIdDir, AUTOMATION_TOML), readFileSync(srcToml, \"utf8\"), \"utf8\");\n } else {\n writeFileSync(\n join(destIdDir, AUTOMATION_TOML),\n `version = 1\\n` +\n `id = \"${automationId}\"\\n` +\n `name = \"${automationId}\"\\n` +\n `status = \"ACTIVE\"\\n` +\n `kind = \"${defaultKind}\"\\n` +\n `rrule = \"\"\\n` +\n `cwds = []\\n`,\n \"utf8\",\n );\n }\n }\n\n if (!isFile(srcMemory)) continue;\n\n const srcSections = parseMemorySections(readFileSync(srcMemory, \"utf8\"));\n const destMemory = join(destIdDir, MEMORY_MD);\n const destSections: Array<[string, string[]]> = isFile(destMemory)\n ? parseMemorySections(readFileSync(destMemory, \"utf8\"))\n : [];\n // `dict(dest_sections)` — last-wins on duplicate dates; the list refs are\n // shared with destSections so appends via `existing` are reflected.\n const destByDate = new Map<string, string[]>();\n for (const [dateStr, bullets] of destSections) destByDate.set(dateStr, bullets);\n\n for (const [dateStr, bullets] of srcSections) {\n if (!destByDate.has(dateStr)) {\n const fresh: string[] = [];\n destByDate.set(dateStr, fresh);\n destSections.push([dateStr, fresh]);\n sectionsCreated += 1;\n }\n const existing = destByDate.get(dateStr)!;\n for (const bullet of bullets) {\n if (!existing.includes(bullet)) {\n existing.push(bullet);\n bulletsAdded += 1;\n }\n }\n }\n\n destSections.sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0));\n writeFileSync(destMemory, serializeSections(destSections), \"utf8\");\n }\n\n return {\n automationsSeen: seen,\n automationsCreated: created,\n bulletsAdded,\n sectionsCreated,\n skipped,\n };\n}\n\n// -- Participant ---------------------------------------------------------------\n\n/** External participant for Claude Code automation memory artifacts. */\nexport class ClaudeCodeAutomationsParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n nativePath: string;\n\n private readonly automationsDir: string;\n private readonly policy: VisibilityPolicyModel;\n\n /**\n * Conventional Claude Code automations dir (`~/.claude/automations`). Provided\n * for protocol uniformity — the setup wizard wires the parent `claude-code`\n * participant and skips `-automations` sub-surfaces.\n */\n static defaultNativePath(home?: string): string {\n return defaultClaudeCodeAutomationsDir(home);\n }\n\n constructor(automationsDir?: string, claudeHome?: string) {\n this.automationsDir = automationsDir ?? defaultClaudeCodeAutomationsDir(claudeHome);\n this.nativePath = this.automationsDir;\n this.policy = DEFAULT_POLICY;\n }\n\n discover(): AgentStore {\n if (!isDir(this.automationsDir)) {\n throw new ParticipantDiscoveryError(\n `Claude Code automations directory not found at ${this.automationsDir}.`,\n );\n }\n const configs = iterConfigs(this.automationsDir);\n return {\n path: this.automationsDir,\n version: \"unknown\",\n metadata: {\n automations: configs.length,\n with_memory: configs.filter((c) => c.memoryPath !== null).length,\n },\n };\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const sessions = this.runs(undefined, since).map(sessionFromRun);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n return sessions.slice(0, limit);\n }\n\n exportL5(since?: Date): L5ManifestModel {\n if (!isDir(this.automationsDir)) {\n throw new ParticipantDiscoveryError(\n `Claude Code automations directory not found at ${this.automationsDir}.`,\n );\n }\n const configs = iterConfigs(this.automationsDir);\n const runs = this.runs(configs, since);\n const sessions = runs.map(sessionFromRun);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n const entities = entitiesFromConfigsAndRuns(configs, runs);\n const visibleEntities = filterForFederation(entities, this.policy);\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: hostname(),\n spec_version_compat: SPEC_VERSION,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: new Date().toISOString(),\n capabilities: [\"claude-code-automation-memory\", \"run-summary-publication\"],\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: this.policy,\n });\n }\n\n healthCheck(): HealthStatus {\n if (!isDir(this.automationsDir)) {\n return {\n status: \"blocked\",\n reason: `Claude Code automations directory not found at ${this.automationsDir}.`,\n details: { automations_dir: this.automationsDir },\n proposedFix:\n \"Create the automations directory and an automation.toml: \" +\n \"mkdir -p ~/.claude/automations/<id> && \" +\n \"$HOME/.claude/hooks/automation-memory-append.sh <id> '...'\",\n };\n }\n const configs = iterConfigs(this.automationsDir);\n const runs = this.runs(configs);\n const hasConfigs = configs.length > 0;\n const status: HealthStatus[\"status\"] = hasConfigs ? \"ok\" : \"degraded\";\n const details = {\n automations_dir: this.automationsDir,\n automation_count: configs.length,\n memory_files: configs.filter((c) => c.memoryPath !== null).length,\n runs_extracted: runs.length,\n active_automations: configs.filter((c) => c.status === \"ACTIVE\").length,\n };\n if (hasConfigs) {\n return { status, details };\n }\n return {\n status,\n reason: \"No automation.toml files found.\",\n details,\n proposedFix: \"Add Claude Code automation.toml files.\",\n };\n }\n\n private runs(configs?: AutomationConfig[], since?: Date): AutomationRun[] {\n const runCutoff = since ? since.toISOString().slice(0, 10) : null;\n const runs: AutomationRun[] = [];\n for (const config of configs ?? iterConfigs(this.automationsDir)) {\n for (const run of extractMemoryRuns(config)) {\n if (runCutoff && run.date < runCutoff) continue;\n runs.push(run);\n }\n }\n runs.sort((a, b) => {\n if (a.date !== b.date) return a.date < b.date ? 1 : -1;\n const ai = a.automation.automationId;\n const bi = b.automation.automationId;\n if (ai !== bi) return ai < bi ? 1 : -1;\n return 0;\n });\n return runs;\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Codex automations participant — publishes read-only Codex background/automation\n * run memory into Bourdon as L5 evidence. Port of\n * `participants/codex_automations.py`.\n *\n * Store convention (NOT SQLite, NOT network): a CONVENTION-FILE directory tree at\n * `~/.codex/automations/<id>/`, each holding an `automation.toml` config and an\n * optional `memory.md` run log. The reader parses the TOML config and extracts\n * dated \"runs\" from the markdown memory, normalizing them into L5 sessions +\n * entities (the automation itself, plus inferred projects and signal classes).\n *\n * Source-resolution order for the automations dir:\n * 1. explicit `automationsDir` constructor arg\n * 2. `codexHome` constructor arg → `<codexHome>/automations`\n * 3. `CODEX_HOME` env-var → `$CODEX_HOME/automations`\n * 4. `~/.codex/automations` (default convention path)\n *\n * Privacy: every native string routes through the redaction SSOT\n * (`redactText(v, 180)` == the oracle's `_safe_native_memory_text`); the\n * visibility policy filters PRIVATE entities before emission. Defensive\n * throughout — a missing dir raises {@link ParticipantDiscoveryError} from\n * `discover()`, malformed TOML/markdown degrades to empty rather than raising,\n * and `healthCheck` never throws.\n *\n * NOTE: does NOT depend on the full codex reader — only the redaction helper it\n * imports (`_safe_native_memory_text`, reproduced inline as {@link safeNativeMemoryText}).\n */\n\nimport { readFileSync, readdirSync, statSync } from \"node:fs\";\nimport { homedir, hostname } from \"node:os\";\nimport { basename, dirname, join } from \"node:path\";\n\nimport { parse as tomlParse } from \"smol-toml\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n loadProjectHints,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\n\n// -- Constants -----------------------------------------------------------------\n\nconst AGENT_ID = \"codex-automations\";\nconst AGENT_TYPE = \"other\";\nconst ROLE_NARRATIVE =\n \"Publishes read-only Codex automation run memory into Bourdon so background \" +\n \"monitors, digests, and recurring checks are visible alongside interactive \" +\n \"agent sessions.\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"health\", \"family\", \"legal\"],\n team_tags: [\"codex-automation\", \"automation\", \"workspace\"],\n});\n\nconst AUTOMATIONS_DIR_NAME = \"automations\";\nconst AUTOMATION_TOML = \"automation.toml\";\nconst MEMORY_MD = \"memory.md\";\nconst MAX_MEMORY_CHARS = 160_000;\nconst MAX_KEY_ACTIONS_PER_RUN = 6;\nconst MAX_KEY_ACTION_CHARS = 280;\nconst RUN_HEADER_RE = /^(\\d{4}-\\d{2}-\\d{2})(?:\\b|$)(.*)$/;\n// Product-neutral defaults only: this product plus the agent surfaces Bourdon\n// federates. A deployment adds its own project roster via the\n// `BOURDON_PROJECT_HINTS` env var (comma-separated) — see `loadProjectHints`.\nconst DEFAULT_PROJECT_HINTS: readonly string[] = [\"Bourdon\", \"Cursor\", \"Copilot\"];\nconst SIGNAL_PATTERNS: readonly (readonly [string, RegExp])[] = [\n [\"human-dashboard-action\", /\\b(human|dashboard|manual)\\b/i],\n [\"release-gate\", /\\b(release|store|app review|play console|testflight)\\b/i],\n [\"billing-drift\", /\\b(billing|stripe|revenuecat|iap|subscription)\\b/i],\n [\"memory-coverage-gap\", /\\b(memory|l5|manifest|federated|bourdon)\\b/i],\n [\"launch-decision\", /\\b(launch|go-live|pricing|prod|production)\\b/i],\n];\n\n/** Minimal logger so a degraded parse is visible without pulling in a dep. */\nconst logger = {\n warn(msg: string): void {\n // eslint-disable-next-line no-console\n console.warn(`[bourdon.participants] ${msg}`);\n },\n};\n\n// -- Data records --------------------------------------------------------------\n\ninterface AutomationConfig {\n automationId: string;\n name: string;\n status: string;\n rrule: string;\n kind: string;\n cwds: string[];\n path: string;\n /** memory.md path, or null when absent. */\n memoryPath: string | null;\n}\n\ninterface AutomationRun {\n automation: AutomationConfig;\n date: string;\n title: string;\n keyActions: string[];\n projects: string[];\n signals: string[];\n}\n\n// -- fs helpers ----------------------------------------------------------------\n\nfunction homeDir(): string {\n // os.homedir() can throw under some sandboxes; stay defensive so import +\n // construction never crash even when HOME points at an unreadable path.\n try {\n return homedir();\n } catch {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n }\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\n// -- Path resolution -----------------------------------------------------------\n\n/** Return the default Codex automations directory (source-resolution order). */\nexport function defaultCodexAutomationsDir(codexHome?: string): string {\n if (codexHome !== undefined && codexHome !== null) {\n return join(codexHome, AUTOMATIONS_DIR_NAME);\n }\n const env = process.env.CODEX_HOME;\n if (env) return join(env, AUTOMATIONS_DIR_NAME);\n return join(homeDir(), \".codex\", AUTOMATIONS_DIR_NAME);\n}\n\n// -- Redaction -----------------------------------------------------------------\n\n/**\n * Thin wrapper over the redaction SSOT (the oracle's `_safe_native_memory_text`,\n * `redact_text(value, limit=180)`).\n */\nfunction safeNativeMemoryText(value: string): string {\n return redactText(value, 180);\n}\n\n// -- Coercion helpers (mirror Python str() / truthiness) -----------------------\n\n/** Mirror Python `str(a or b)`: use `a` when truthy, else `b`, then stringify. */\nfunction pyStrOr(a: unknown, b: string): string {\n return String(a ? a : b);\n}\n\n// -- TOML config ---------------------------------------------------------------\n\n/** Read + parse an automation.toml. Returns {} on any I/O or parse error. */\nfunction readAutomationToml(path: string): Record<string, unknown> {\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch (exc) {\n logger.warn(`CodexAutomationsParticipant: cannot parse ${path}: ${String(exc)}`);\n return {};\n }\n try {\n const parsed = tomlParse(text) as unknown;\n return typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : {};\n } catch (exc) {\n logger.warn(`CodexAutomationsParticipant: cannot parse ${path}: ${String(exc)}`);\n return {};\n }\n}\n\n/** Build an AutomationConfig from a toml path. Returns null on an empty id. */\nfunction buildConfig(tomlPath: string): AutomationConfig | null {\n const raw = readAutomationToml(tomlPath);\n const parentName = basename(dirname(tomlPath));\n\n const automationId = pyStrOr(raw[\"id\"], parentName).trim();\n if (!automationId) return null;\n\n const name = pyStrOr(raw[\"name\"], automationId).trim();\n const status = pyStrOr(raw[\"status\"], \"UNKNOWN\").trim().toUpperCase();\n const rrule = pyStrOr(raw[\"rrule\"], \"\").trim();\n const kind = pyStrOr(raw[\"kind\"], \"\").trim();\n\n const cwdsRaw = raw[\"cwds\"];\n const cwds: string[] = Array.isArray(cwdsRaw)\n ? cwdsRaw.filter((cwd): cwd is string => typeof cwd === \"string\" && cwd.trim() !== \"\")\n : [];\n\n const memoryPath = join(dirname(tomlPath), MEMORY_MD);\n return {\n automationId,\n name,\n status,\n rrule,\n kind,\n cwds,\n path: tomlPath,\n memoryPath: isFile(memoryPath) ? memoryPath : null,\n };\n}\n\n/**\n * Enumerate the `<id>/automation.toml` files, sorted (mirrors Python's sorted-glob).\n * The varying path segment is the immediate sub-directory, so sorting the\n * resulting toml paths reproduces the oracle's ordering.\n */\nfunction iterConfigs(automationsDir: string): AutomationConfig[] {\n if (!isDir(automationsDir)) return [];\n let entries: string[];\n try {\n entries = readdirSync(automationsDir);\n } catch {\n return [];\n }\n const tomlPaths: string[] = [];\n for (const entry of entries) {\n const tomlPath = join(automationsDir, entry, AUTOMATION_TOML);\n if (isFile(tomlPath)) tomlPaths.push(tomlPath);\n }\n tomlPaths.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n const configs: AutomationConfig[] = [];\n for (const tomlPath of tomlPaths) {\n const config = buildConfig(tomlPath);\n if (config !== null) configs.push(config);\n }\n return configs;\n}\n\n// -- Memory extraction ---------------------------------------------------------\n\n/** Read the memory file, returning at most the last MAX_MEMORY_CHARS characters. */\nfunction readMemoryText(path: string | null): string {\n if (path === null) return \"\";\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch (exc) {\n logger.warn(`CodexAutomationsParticipant: cannot read ${path}: ${String(exc)}`);\n return \"\";\n }\n return text.length > MAX_MEMORY_CHARS ? text.slice(-MAX_MEMORY_CHARS) : text;\n}\n\n/** Split into lines the way Python's str.splitlines() does (best-effort). */\nfunction splitLines(text: string): string[] {\n // Python splitlines includes ASCII record separators; this explicit set preserves parity.\n // eslint-disable-next-line no-control-regex\n return text.split(/\\r\\n|[\\n\\r\\u000B\\u000C\\u001C\\u001D\\u001E\\u0085\\u2028\\u2029]/u);\n}\n\n/** Python `str.rstrip()` — strip trailing whitespace only. */\nfunction rstrip(s: string): string {\n return s.replace(/\\s+$/, \"\");\n}\n\n/** Python `\" \".join(value.split())` — collapse all whitespace runs. */\nfunction collapseWhitespace(value: string): string {\n return value\n .split(/\\s+/)\n .filter((p) => p.length > 0)\n .join(\" \");\n}\n\n/** Port of `_bounded`: collapse whitespace then cap with a `...` ellipsis. */\nfunction bounded(value: string, limit: number): string {\n const normalized = collapseWhitespace(value);\n if (normalized.length <= limit) return normalized;\n return rstrip(normalized.slice(0, limit - 1)) + \"...\";\n}\n\nfunction actionsFromLines(lines: string[]): string[] {\n const actions: string[] = [];\n for (const line of lines) {\n let cleaned = line.trim();\n if (!cleaned) continue;\n cleaned = (cleaned.startsWith(\"- \") ? cleaned.slice(2) : cleaned).trim();\n const lowered = cleaned.toLowerCase();\n if (!cleaned || lowered.startsWith(\"runtime\")) continue;\n if (lowered === \"first run\" || lowered === \"follow-up\") continue;\n if (lowered.startsWith(\"run:\")) cleaned = cleaned.slice(4).trim();\n const safe = bounded(safeNativeMemoryText(cleaned), MAX_KEY_ACTION_CHARS);\n if (safe && !actions.includes(safe)) actions.push(safe);\n if (actions.length >= MAX_KEY_ACTIONS_PER_RUN) break;\n }\n return actions;\n}\n\nfunction titleFromActions(config: AutomationConfig, actions: string[]): string {\n if (actions.length === 0) return config.name;\n const first = actions[0] as string;\n const prefix = `${config.name}: `;\n if (first.startsWith(prefix)) return bounded(first, 120);\n return bounded(prefix + first, 120);\n}\n\nfunction inferProjects(text: string): string[] {\n const projects: string[] = [];\n const lowered = text.toLowerCase();\n const seen = new Set<string>();\n for (const project of loadProjectHints(DEFAULT_PROJECT_HINTS)) {\n const key = project.toLowerCase();\n if (lowered.includes(key) && !seen.has(key)) {\n projects.push(project);\n seen.add(key);\n }\n }\n return projects;\n}\n\nfunction inferSignals(text: string): string[] {\n const signals: string[] = [];\n for (const [name, pattern] of SIGNAL_PATTERNS) {\n if (pattern.test(text)) signals.push(name);\n }\n return signals;\n}\n\nfunction extractMemoryRuns(config: AutomationConfig): AutomationRun[] {\n const text = readMemoryText(config.memoryPath);\n if (!text) return [];\n\n const chunks: Array<[string, string[]]> = [];\n let currentDate = \"\";\n let currentLines: string[] = [];\n for (const rawLine of splitLines(text)) {\n const line = rstrip(rawLine);\n const match = RUN_HEADER_RE.exec(line.trim());\n if (match) {\n if (currentDate) chunks.push([currentDate, currentLines]);\n currentDate = match[1] as string;\n const suffix = stripChars((match[2] as string).trim(), \" -:—\");\n currentLines = suffix ? [suffix] : [];\n continue;\n }\n if (currentDate) currentLines.push(line);\n }\n if (currentDate) chunks.push([currentDate, currentLines]);\n\n const runs: AutomationRun[] = [];\n for (const [runDate, lines] of chunks) {\n const actions = actionsFromLines(lines);\n if (actions.length === 0) continue;\n const body = actions.join(\" \");\n const title = titleFromActions(config, actions);\n runs.push({\n automation: config,\n date: runDate,\n title,\n keyActions: actions,\n projects: inferProjects(body),\n signals: inferSignals(body),\n });\n }\n return runs;\n}\n\n/** Python `str.strip(chars)` — strip any of `chars` from both ends. */\nfunction stripChars(s: string, chars: string): string {\n let start = 0;\n let end = s.length;\n while (start < end && chars.includes(s[start] as string)) start++;\n while (end > start && chars.includes(s[end - 1] as string)) end--;\n return s.slice(start, end);\n}\n\n// -- L5 assembly ---------------------------------------------------------------\n\nfunction sessionFromRun(run: AutomationRun): SessionModel {\n const config = run.automation;\n const keyActions = [\n `automation_id: ${config.automationId}`,\n `run: ${run.title}`,\n ...run.keyActions,\n ];\n const filesTouched = [config.path];\n if (config.memoryPath !== null) filesTouched.push(config.memoryPath);\n return makeSession({\n date: run.date,\n cwd: config.cwds.length > 0 ? (config.cwds[0] as string) : dirname(config.path),\n project_focus: [...run.projects],\n key_actions: keyActions.slice(0, MAX_KEY_ACTIONS_PER_RUN + 2),\n files_touched: filesTouched,\n visibility: Visibility.TEAM,\n });\n}\n\nfunction entitiesFromConfigsAndRuns(\n configs: AutomationConfig[],\n runs: AutomationRun[],\n): EntityModel[] {\n const byName = new Map<string, EntityModel>();\n for (const config of configs) {\n byName.set(\n config.automationId,\n makeEntity({\n name: config.automationId,\n type: \"automation\",\n summary: bounded(\n `Codex automation '${config.name}' (${config.status}). ` +\n `Schedule: ${config.rrule || \"unspecified\"}.`,\n 260,\n ),\n last_touched: undefined,\n tags: [\"codex-automation\", \"automation\", config.status.toLowerCase()],\n visibility: Visibility.TEAM,\n }),\n );\n }\n\n for (const run of runs) {\n for (const project of run.projects) {\n if (!byName.has(project)) {\n byName.set(\n project,\n makeEntity({\n name: project,\n type: \"project\",\n summary: \"Project mentioned by Codex automation run memory.\",\n last_touched: run.date,\n tags: [\"codex-automation\", \"automation-evidence\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n for (const signal of run.signals) {\n if (!byName.has(signal)) {\n byName.set(\n signal,\n makeEntity({\n name: signal,\n type: \"automation-signal\",\n summary: \"Signal class inferred from Codex automation run memory.\",\n last_touched: run.date,\n tags: [\"codex-automation\", \"automation-signal\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n }\n return [...byName.values()];\n}\n\n// -- Participant ---------------------------------------------------------------\n\n/**\n * External participant for Codex automation memory artifacts. Reads\n * `~/.codex/automations/<id>/{automation.toml,memory.md}` and normalizes dated\n * runs into an L5 manifest.\n */\nexport class CodexAutomationsParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n\n private readonly automationsDir: string;\n private readonly policy: VisibilityPolicyModel;\n\n /**\n * Conventional Codex automations dir (`~/.codex/automations`). Provided for\n * protocol uniformity — the setup wizard wires the parent `codex` participant\n * and skips `-automations` sub-surfaces rather than detecting this one.\n */\n static defaultNativePath(home?: string): string {\n return defaultCodexAutomationsDir(home);\n }\n\n constructor(automationsDir?: string, codexHome?: string) {\n this.automationsDir = automationsDir ?? defaultCodexAutomationsDir(codexHome);\n this.policy = DEFAULT_POLICY;\n }\n\n get nativePath(): string {\n return this.automationsDir;\n }\n\n discover(): AgentStore {\n if (!isDir(this.automationsDir)) {\n throw new ParticipantDiscoveryError(\n `Codex automations directory not found at ${this.automationsDir}.`,\n );\n }\n const configs = iterConfigs(this.automationsDir);\n return {\n path: this.automationsDir,\n version: \"unknown\",\n metadata: {\n automations: configs.length,\n with_memory: configs.filter((c) => c.memoryPath !== null).length,\n },\n };\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const sessions = this.runs(undefined, since).map(sessionFromRun);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n return sessions.slice(0, limit);\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const configs = iterConfigs(this.automationsDir);\n const runs = this.runs(configs, since);\n const sessions = runs.map(sessionFromRun);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n const entities = entitiesFromConfigsAndRuns(configs, runs);\n const visibleEntities = filterForFederation(entities, this.policy);\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: hostname(),\n spec_version_compat: SPEC_VERSION,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: new Date().toISOString(),\n capabilities: [\"codex-automation-memory\", \"run-summary-publication\"],\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: this.policy,\n });\n }\n\n healthCheck(): HealthStatus {\n if (!isDir(this.automationsDir)) {\n return {\n status: \"blocked\",\n reason: `Codex automations directory not found at ${this.automationsDir}.`,\n details: { automations_dir: this.automationsDir },\n proposedFix: \"Create Codex automations or pass --automations-dir.\",\n };\n }\n const configs = iterConfigs(this.automationsDir);\n const runs = this.runs(configs);\n const hasConfigs = configs.length > 0;\n return {\n status: hasConfigs ? \"ok\" : \"degraded\",\n reason: hasConfigs ? undefined : \"No automation.toml files found.\",\n details: {\n automations_dir: this.automationsDir,\n automation_count: configs.length,\n memory_files: configs.filter((c) => c.memoryPath !== null).length,\n runs_extracted: runs.length,\n active_automations: configs.filter((c) => c.status === \"ACTIVE\").length,\n },\n proposedFix: hasConfigs ? undefined : \"Add Codex automation.toml files.\",\n };\n }\n\n // -- Internal ---------------------------------------------------------------\n\n private runs(configs?: AutomationConfig[], since?: Date): AutomationRun[] {\n const runCutoff = since ? since.toISOString().slice(0, 10) : null;\n const runs: AutomationRun[] = [];\n for (const config of configs ?? iterConfigs(this.automationsDir)) {\n for (const run of extractMemoryRuns(config)) {\n if (runCutoff && run.date < runCutoff) continue;\n runs.push(run);\n }\n }\n runs.sort((a, b) => {\n if (a.date !== b.date) return a.date < b.date ? 1 : -1;\n const ai = a.automation.automationId;\n const bi = b.automation.automationId;\n if (ai !== bi) return ai < bi ? 1 : -1;\n return 0;\n });\n return runs;\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * GitHub Copilot · Automations participant — convention-file reader. Port of\n * `participants/copilot_automations.py`.\n *\n * GitHub Copilot can be triggered by GitHub Actions workflows, scheduled tasks,\n * and event-driven automations (issue triage, PR review, etc.). These run on a\n * separate memory surface from both the CLI agent and the VS Code extension.\n * Copilot automations have no standardized local state dump, so — mirroring the\n * codex-automations reader — this participant uses a CONVENTION directory:\n *\n * ~/.copilot-bourdon/automations/<automation-id>/\n * automation.toml — id, name, status, trigger, kind, repos\n * memory.md — dated bullet entries, one block per run\n *\n * Each `automation.toml` describes a recurring automation; each dated section of\n * `memory.md` captures what happened in that run. Users or CI scripts maintain\n * these files.\n *\n * Path resolution (matches the oracle):\n * 1. `COPILOT_AUTOMATIONS_HOME` env-var override (verbatim, → /automations skipped:\n * the override IS the automations dir).\n * 2. `~/.copilot-bourdon/automations/` (default convention path).\n *\n * Defensive throughout: a missing automations directory raises\n * {@link ParticipantDiscoveryError} from `discover()`; a malformed\n * `automation.toml` or unreadable `memory.md` is logged and skipped rather than\n * raising; `healthCheck` never throws.\n */\n\nimport { mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from \"node:fs\";\nimport { homedir, hostname } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport { parse as parseToml } from \"smol-toml\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\n\n// -- Constants -----------------------------------------------------------------\n\nconst AGENT_ID = \"copilot-automations\";\nconst AGENT_TYPE = \"other\";\nconst DISPLAY_NAME = \"GitHub Copilot · Automations\";\nconst ROLE_NARRATIVE =\n \"Publishes read-only Copilot automation run memory into Bourdon so \" +\n \"GitHub Actions-triggered Copilot tasks, scheduled PR reviews, issue \" +\n \"triage, and other event-driven Copilot work are visible alongside \" +\n \"interactive agent sessions.\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"health\", \"family\", \"legal\"],\n team_tags: [\"copilot-automation\", \"automation\", \"github-actions\", \"workspace\"],\n});\n\nconst CONVENTION_DIR_NAME = \".copilot-bourdon\";\nconst AUTOMATIONS_DIR = \"automations\";\nconst AUTOMATION_TOML = \"automation.toml\";\nconst MEMORY_MD = \"memory.md\";\nconst MAX_MEMORY_CHARS = 160_000;\nconst MAX_KEY_ACTIONS_PER_RUN = 6;\nconst MAX_KEY_ACTION_CHARS = 280;\n/** `^(\\d{4}-\\d{2}-\\d{2})(?:\\b|$)(.*)$` — the dated run header. */\nconst RUN_HEADER_RE = /^(\\d{4}-\\d{2}-\\d{2})(?:\\b|$)(.*)$/;\n\n/** Starter template for `bourdon copilot-automations init`. */\nconst AUTOMATION_TOML_TEMPLATE = `# Copilot Automation definition\n# Edit this file to describe a recurring Copilot automation.\n\nid = \"{automation_id}\"\nname = \"{name}\"\nstatus = \"ACTIVE\"\ntrigger = \"workflow_dispatch\" # or: schedule, issue_comment, pull_request, etc.\nkind = \"pr-review\" # or: issue-triage, code-generation, test-review, etc.\nrepos = [] # list of repositories this automation targets\n`;\n\nconst MEMORY_MD_TEMPLATE = `# {name} — Run Memory\n\nRecord automation run outcomes here. Each dated section is parsed by Bourdon.\n\n# Format:\n# YYYY-MM-DD <optional title>\n# - bullet point of what happened\n# - another action or outcome\n\n`;\n\n/** Minimal logger so a degraded parse is visible without pulling in a dep\n * (matches the sibling readers' logging idiom). */\nconst logger = {\n warn(msg: string): void {\n // eslint-disable-next-line no-console\n console.warn(`[bourdon.participants] ${msg}`);\n },\n};\n\n// -- Records -------------------------------------------------------------------\n\ninterface AutomationConfig {\n automationId: string;\n name: string;\n status: string;\n trigger: string;\n kind: string;\n repos: string[];\n path: string;\n memoryPath: string | null;\n}\n\ninterface AutomationRun {\n automation: AutomationConfig;\n date: string;\n title: string;\n keyActions: string[];\n repos: string[];\n}\n\n// -- fs helpers ----------------------------------------------------------------\n\nfunction homeDir(): string {\n // os.homedir() can throw under some sandboxes; stay defensive so import +\n // construction never crash even when HOME points at an unreadable path.\n try {\n return homedir();\n } catch {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n }\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/** Python truthiness for the scalar/array types TOML yields. */\nfunction pyTruthy(v: unknown): boolean {\n if (v === null || v === undefined || v === false) return false;\n if (typeof v === \"string\") return v.length > 0;\n if (typeof v === \"number\") return v !== 0;\n if (Array.isArray(v)) return v.length > 0;\n return true;\n}\n\n/** Mirror Python `str(value)` for the value types encountered here. */\nfunction pyStr(v: unknown): string {\n if (typeof v === \"string\") return v;\n if (typeof v === \"boolean\") return v ? \"True\" : \"False\";\n if (v === null || v === undefined) return \"None\";\n return String(v);\n}\n\n// -- Path helpers --------------------------------------------------------------\n\n/**\n * Return the conventional `~/.copilot-bourdon/automations/` directory. Respects\n * the `COPILOT_AUTOMATIONS_HOME` env-var override (returned verbatim — the\n * override IS the automations dir, no `/automations` suffix is appended).\n */\nexport function defaultCopilotAutomationsDir(copilotBourdonDir?: string | null): string {\n const env = process.env.COPILOT_AUTOMATIONS_HOME;\n if (env) return env;\n const base = copilotBourdonDir || join(homeDir(), CONVENTION_DIR_NAME);\n return join(base, AUTOMATIONS_DIR);\n}\n\n// -- Config / memory parsing ---------------------------------------------------\n\nfunction readAutomationToml(path: string): Record<string, unknown> {\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch (exc) {\n logger.warn(`CopilotAutomationsParticipant: cannot parse ${path}: ${String(exc)}`);\n return {};\n }\n try {\n const parsed = parseToml(text) as unknown;\n return isRecord(parsed) ? parsed : {};\n } catch (exc) {\n logger.warn(`CopilotAutomationsParticipant: cannot parse ${path}: ${String(exc)}`);\n return {};\n }\n}\n\nfunction buildConfig(tomlPath: string): AutomationConfig | null {\n const raw = readAutomationToml(tomlPath);\n const parentDir = dirname(tomlPath);\n const parentName = parentDir.split(/[\\\\/]/).filter(Boolean).pop() ?? \"\";\n\n const automationId = pyStr(pyTruthy(raw[\"id\"]) ? raw[\"id\"] : parentName).trim();\n if (!automationId) return null;\n\n const name = pyStr(pyTruthy(raw[\"name\"]) ? raw[\"name\"] : automationId).trim();\n const status = pyStr(pyTruthy(raw[\"status\"]) ? raw[\"status\"] : \"UNKNOWN\")\n .trim()\n .toUpperCase();\n const trigger = pyStr(pyTruthy(raw[\"trigger\"]) ? raw[\"trigger\"] : \"\").trim();\n const kind = pyStr(pyTruthy(raw[\"kind\"]) ? raw[\"kind\"] : \"\").trim();\n\n const reposRaw = pyTruthy(raw[\"repos\"]) ? raw[\"repos\"] : [];\n const reposIter: unknown[] = Array.isArray(reposRaw)\n ? reposRaw\n : typeof reposRaw === \"string\"\n ? Array.from(reposRaw)\n : [];\n const repos = reposIter.filter((r): r is string => typeof r === \"string\" && r.trim() !== \"\");\n\n const memoryPath = join(parentDir, MEMORY_MD);\n return {\n automationId,\n name,\n status,\n trigger,\n kind,\n repos,\n path: tomlPath,\n memoryPath: isFile(memoryPath) ? memoryPath : null,\n };\n}\n\nfunction iterConfigs(automationsDir: string): AutomationConfig[] {\n const configs: AutomationConfig[] = [];\n if (!isDir(automationsDir)) return configs;\n\n let entries: string[];\n try {\n entries = readdirSync(automationsDir);\n } catch {\n return configs;\n }\n\n // Mirror `sorted(Path.glob(\"*/automation.toml\"))`: one directory level deep,\n // sorted by path. NOTE pathlib glob MATCHES dot-prefixed dirs (unlike shell\n // glob / glob.glob) — do NOT skip them, or dot-named automations under-report.\n const tomlPaths: string[] = [];\n for (const entry of entries) {\n const candidate = join(automationsDir, entry, AUTOMATION_TOML);\n if (isFile(candidate)) tomlPaths.push(candidate);\n }\n tomlPaths.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n\n for (const tomlPath of tomlPaths) {\n const config = buildConfig(tomlPath);\n if (config !== null) configs.push(config);\n }\n return configs;\n}\n\n/** Python `str.splitlines()` for the common line boundaries. Empty input → []. */\nfunction splitLines(text: string): string[] {\n if (text.length === 0) return [];\n // Python splitlines includes ASCII record separators; this explicit set preserves parity.\n return text.split(\n // eslint-disable-next-line no-control-regex\n /\\r\\n|\\r|\\n|\\u000B|\\u000C|\\u001C|\\u001D|\\u001E|\\u0085|\\u2028|\\u2029/u,\n );\n}\n\n/** Python `str.rstrip()` — strip trailing whitespace. */\nfunction rstrip(s: string): string {\n return s.replace(/\\s+$/u, \"\");\n}\n\n/** Python `str.strip(chars)` — strip the given char set from both ends. */\nfunction stripChars(s: string, chars: string): string {\n let start = 0;\n let end = s.length;\n while (start < end && chars.includes(s[start]!)) start++;\n while (end > start && chars.includes(s[end - 1]!)) end--;\n return s.slice(start, end);\n}\n\nfunction extractMemoryRuns(config: AutomationConfig): AutomationRun[] {\n if (config.memoryPath === null) return [];\n let text: string;\n try {\n text = readFileSync(config.memoryPath, \"utf8\");\n } catch (exc) {\n logger.warn(`CopilotAutomationsParticipant: cannot read ${config.memoryPath}: ${String(exc)}`);\n return [];\n }\n\n text = text.slice(-MAX_MEMORY_CHARS);\n const chunks: Array<[string, string[]]> = [];\n let currentDate = \"\";\n let currentLines: string[] = [];\n\n for (const rawLine of splitLines(text)) {\n const line = rstrip(rawLine);\n const match = RUN_HEADER_RE.exec(line.trim());\n if (match) {\n if (currentDate) chunks.push([currentDate, currentLines]);\n currentDate = match[1]!;\n const suffix = stripChars((match[2] ?? \"\").trim(), \" -:—\");\n currentLines = suffix ? [suffix] : [];\n continue;\n }\n if (currentDate) currentLines.push(line);\n }\n if (currentDate) chunks.push([currentDate, currentLines]);\n\n const runs: AutomationRun[] = [];\n for (const [runDate, lines] of chunks) {\n const actions = actionsFromLines(lines);\n if (actions.length === 0) continue;\n const title = titleFromActions(config, actions);\n runs.push({\n automation: config,\n date: runDate,\n title,\n keyActions: actions,\n repos: config.repos,\n });\n }\n return runs;\n}\n\nfunction actionsFromLines(lines: string[]): string[] {\n const actions: string[] = [];\n for (const line of lines) {\n let cleaned = line.trim();\n if (!cleaned) continue;\n cleaned = (cleaned.startsWith(\"- \") ? cleaned.slice(2) : cleaned).trim();\n if (!cleaned || cleaned.toLowerCase().startsWith(\"runtime\")) continue;\n const safe = bounded(safeNativeMemoryText(cleaned), MAX_KEY_ACTION_CHARS);\n if (safe && !actions.includes(safe)) actions.push(safe);\n if (actions.length >= MAX_KEY_ACTIONS_PER_RUN) break;\n }\n return actions;\n}\n\nfunction titleFromActions(config: AutomationConfig, actions: string[]): string {\n if (actions.length === 0) return config.name;\n const first = actions[0]!;\n const prefix = `${config.name}: `;\n if (first.startsWith(prefix)) return bounded(first, 120);\n return bounded(prefix + first, 120);\n}\n\n/** `\" \".join(value.split())` + ellipsis truncation. */\nfunction bounded(value: string, limit: number): string {\n const normalized = value\n .split(/\\s+/u)\n .filter((x) => x.length > 0)\n .join(\" \");\n if (normalized.length <= limit) return normalized;\n return rstrip(normalized.slice(0, limit - 1)) + \"…\";\n}\n\n/** Python `_safe_native_memory_text(v)` == `redactText(v, 180)`. */\nfunction safeNativeMemoryText(value: string): string {\n return redactText(value, 180);\n}\n\n// -- Conversion to Bourdon types ----------------------------------------------\n\nfunction sessionFromRun(run: AutomationRun): SessionModel {\n const config = run.automation;\n const keyActions = [\n `automation: ${config.automationId}`,\n config.trigger ? `trigger: ${config.trigger}` : `kind: ${config.kind}`,\n `run: ${run.title}`,\n ...run.keyActions,\n ];\n return makeSession({\n date: run.date,\n cwd: dirname(config.path),\n project_focus: [...run.repos],\n key_actions: keyActions.slice(0, MAX_KEY_ACTIONS_PER_RUN + 3),\n files_touched: [config.path],\n visibility: Visibility.TEAM,\n });\n}\n\nfunction entitiesFromConfigsAndRuns(\n configs: AutomationConfig[],\n runs: AutomationRun[],\n): EntityModel[] {\n const entities = new Map<string, EntityModel>();\n\n for (const config of configs) {\n entities.set(\n config.automationId,\n makeEntity({\n name: config.automationId,\n type: \"automation\",\n summary: bounded(\n `Copilot automation '${config.name}' (${config.status}). ` +\n `Trigger: ${config.trigger || \"unspecified\"}. ` +\n `Kind: ${config.kind || \"unspecified\"}.`,\n 260,\n ),\n last_touched: undefined,\n tags: [\"copilot-automation\", \"automation\", config.status.toLowerCase()],\n visibility: Visibility.TEAM,\n }),\n );\n }\n\n // Repos mentioned across all runs (setdefault: first-write-wins).\n for (const run of runs) {\n for (const repo of run.repos) {\n if (!entities.has(repo)) {\n entities.set(\n repo,\n makeEntity({\n name: repo,\n type: \"project\",\n summary: \"Repository targeted by Copilot automation.\",\n last_touched: run.date,\n tags: [\"copilot-automation\", \"project\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n }\n\n return [...entities.values()];\n}\n\n// -- Participant ---------------------------------------------------------------\n\n/**\n * Convention-based Bourdon participant for Copilot automation memory artifacts.\n * Users or CI scripts maintain `automation.toml` + `memory.md` files at\n * `~/.copilot-bourdon/automations/<id>/`.\n */\nexport class CopilotAutomationsParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n displayName = DISPLAY_NAME;\n\n private readonly automationsDir: string;\n private readonly policy: VisibilityPolicyModel;\n\n /** Conventional automations dir (`~/.copilot-bourdon/automations`). Does NOT\n * consult `COPILOT_AUTOMATIONS_HOME` (matches Python `default_native_path`). */\n static defaultNativePath(home?: string): string {\n const base = join(home ?? homeDir(), CONVENTION_DIR_NAME);\n return join(base, AUTOMATIONS_DIR);\n }\n\n constructor(automationsDir?: string | null) {\n this.automationsDir = automationsDir ?? defaultCopilotAutomationsDir();\n this.policy = DEFAULT_POLICY;\n }\n\n get nativePath(): string {\n return this.automationsDir;\n }\n\n // -- Protocol surface -------------------------------------------------------\n\n discover(): AgentStore {\n if (!isDir(this.automationsDir)) {\n throw new ParticipantDiscoveryError(\n `Copilot automations directory not found at ${this.automationsDir}. ` +\n \"Run `bourdon copilot-automations init <name>` to create one.\",\n );\n }\n const configs = iterConfigs(this.automationsDir);\n return {\n path: this.automationsDir,\n version: \"convention-v1\",\n metadata: {\n automations: configs.length,\n with_memory: configs.filter((c) => c.memoryPath !== null).length,\n },\n };\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const sessions = this.runs(undefined, since).map(sessionFromRun);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n return sessions.slice(0, limit);\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const configs = iterConfigs(this.automationsDir);\n const runs = this.runs(configs, since);\n const sessions = runs.map(sessionFromRun);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n const entities = entitiesFromConfigsAndRuns(configs, runs);\n const visibleEntities = filterForFederation(entities, this.policy);\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: hostname() || \"unknown\",\n spec_version_compat: `>=${SPEC_VERSION}`,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: new Date().toISOString(),\n capabilities: [\"copilot-automation-memory\", \"run-summary-publication\"],\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: this.policy,\n });\n }\n\n healthCheck(): HealthStatus {\n if (!isDir(this.automationsDir)) {\n return {\n status: \"blocked\",\n reason: `Copilot automations directory not found at ${this.automationsDir}.`,\n details: { automations_dir: this.automationsDir },\n proposedFix: \"Run `bourdon copilot-automations init <name>` to create an automation.\",\n };\n }\n const configs = iterConfigs(this.automationsDir);\n const runs = this.runs(configs);\n const hasConfigs = configs.length > 0;\n return {\n status: hasConfigs ? \"ok\" : \"degraded\",\n reason: hasConfigs ? undefined : \"No automation.toml files found.\",\n details: {\n automations_dir: this.automationsDir,\n automation_count: configs.length,\n memory_files: configs.filter((c) => c.memoryPath !== null).length,\n runs_extracted: runs.length,\n active_automations: configs.filter((c) => c.status === \"ACTIVE\").length,\n },\n proposedFix: hasConfigs\n ? undefined\n : \"Run `bourdon copilot-automations init <name>` to create an automation, \" +\n \"or add automation.toml files manually.\",\n };\n }\n\n // -- Internal ---------------------------------------------------------------\n\n private runs(configs?: AutomationConfig[], since?: Date): AutomationRun[] {\n const runCutoff = since ? since.toISOString().slice(0, 10) : null;\n const out: AutomationRun[] = [];\n for (const config of configs ?? iterConfigs(this.automationsDir)) {\n for (const run of extractMemoryRuns(config)) {\n if (runCutoff && run.date < runCutoff) continue;\n out.push(run);\n }\n }\n // sorted(key=(date, automation_id), reverse=True)\n out.sort((a, b) => {\n if (a.date !== b.date) return a.date < b.date ? 1 : -1;\n const ai = a.automation.automationId;\n const bi = b.automation.automationId;\n if (ai !== bi) return ai < bi ? 1 : -1;\n return 0;\n });\n return out;\n }\n}\n\n// -- Init helper ---------------------------------------------------------------\n\n/**\n * Create an automation scaffold at `<automationsDir>/<id>/`. Returns the path\n * of the created automation directory. Throws when `automation.toml` already\n * exists unless `force` is true.\n */\nexport function initAutomation(\n automationsDir?: string | null,\n automationId = \"my-automation\",\n name = \"My Copilot Automation\",\n force = false,\n): string {\n const targetDir = join(automationsDir || defaultCopilotAutomationsDir(), automationId);\n const tomlPath = join(targetDir, AUTOMATION_TOML);\n const memoryPath = join(targetDir, MEMORY_MD);\n\n if (isFile(tomlPath) && !force) {\n throw new Error(`${tomlPath} already exists. Pass --force to overwrite.`);\n }\n\n mkdirSync(targetDir, { recursive: true });\n writeFileSync(\n tomlPath,\n AUTOMATION_TOML_TEMPLATE.replace(\"{automation_id}\", automationId).replace(\"{name}\", name),\n \"utf8\",\n );\n if (!isFile(memoryPath) || force) {\n writeFileSync(memoryPath, MEMORY_MD_TEMPLATE.replace(\"{name}\", name), \"utf8\");\n }\n return targetDir;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Cursor automations participant — publish background agent run memory as L5\n * evidence. Port of `participants/cursor_automations.py`.\n *\n * Reads the `~/.cursor/automations/<id>/` CONVENTION (file-based, no SQLite):\n *\n * automation.toml — id, name, status, schedule (rrule), kind, cwds\n * memory.md — dated bullet entries, one block per run\n *\n * Each `automation.toml` becomes a known Entity; each dated section of\n * `memory.md` becomes a recent Session. This covers the federation gap the\n * interactive-only `cursor` participant leaves behind: Cursor Cloud Agent\n * background tasks whose work never touches the interactive SQLite state.\n *\n * Path resolution (default dir):\n * 1. explicit `cursorHome` ctor arg → `<cursorHome>/automations`\n * 2. `CURSOR_DIR` or `CURSOR_HOME` env → `<env>/automations`\n * 3. `~/.cursor/automations`\n *\n * Redaction: every native action string passes through the redaction SSOT\n * (`redactText(v, 180)` == Python `_safe_native_memory_text`). Visibility policy\n * filters PRIVATE entities BEFORE emission. `healthCheck` never throws.\n */\n\nimport { mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport { homedir, hostname } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport { parse as parseToml } from \"smol-toml\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n loadProjectHints,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\n\n// -- Constants -----------------------------------------------------------------\n\nconst AGENT_ID = \"cursor-automations\";\nconst AGENT_TYPE = \"other\";\nconst ROLE_NARRATIVE =\n \"Publishes read-only Cursor Cloud Agent automation run memory into Bourdon \" +\n \"so background PR reviews, code generation tasks, and scheduled agent runs \" +\n \"become visible alongside interactive Cursor IDE sessions.\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"health\", \"family\", \"legal\"],\n team_tags: [\"cursor-automation\", \"automation\", \"workspace\"],\n});\n\nconst AUTOMATIONS_DIR_NAME = \"automations\";\nconst AUTOMATION_TOML = \"automation.toml\";\nconst MEMORY_MD = \"memory.md\";\nconst MAX_MEMORY_CHARS = 160_000;\nconst MAX_KEY_ACTIONS_PER_RUN = 6;\nconst MAX_KEY_ACTION_CHARS = 280;\n\n/** `^(YYYY-MM-DD)(?:\\b|$)(rest)$` — matches a run-header line (post `.strip()`). */\nconst RUN_HEADER_RE = /^(\\d{4}-\\d{2}-\\d{2})(?:\\b|$)(.*)$/;\n/** Chars stripped from a run-header suffix (space, hyphen, colon, em-dash). */\nconst HEADER_SUFFIX_STRIP = \" -:—\";\n\n// Product-neutral defaults only: this product plus the agent surfaces Bourdon\n// federates. A deployment adds its own project roster via the\n// `BOURDON_PROJECT_HINTS` env var (comma-separated) — see `loadProjectHints`.\nconst DEFAULT_PROJECT_HINTS: readonly string[] = [\n \"Bourdon\",\n \"Cursor\",\n \"Copilot\",\n \"Codex\",\n \"Cascade\",\n];\n\nconst SIGNAL_PATTERNS: ReadonlyArray<readonly [string, RegExp]> = [\n [\"human-dashboard-action\", /\\b(human|dashboard|manual)\\b/i],\n [\"release-gate\", /\\b(release|store|app review|play console|testflight)\\b/i],\n [\"billing-drift\", /\\b(billing|stripe|revenuecat|iap|subscription)\\b/i],\n [\"memory-coverage-gap\", /\\b(memory|l5|manifest|federated|bourdon)\\b/i],\n [\"launch-decision\", /\\b(launch|go-live|pricing|prod|production)\\b/i],\n [\"ci-signal\", /\\b(github action|workflow run|ci|cd|deploy|pipeline)\\b/i],\n];\n\n/** `^[-*]\\s+(rest)$` — a markdown bullet line (used by the merge path). */\nconst BULLET_RE = /^[-*]\\s+(.*)$/;\n/** `^[A-Za-z0-9._-]+$` — a filesystem-safe automation id (merge validation). */\nconst VALID_ID_RE = /^[A-Za-z0-9._-]+$/;\n\n// -- Data shapes ---------------------------------------------------------------\n\ninterface AutomationConfig {\n automationId: string;\n name: string;\n status: string;\n rrule: string;\n kind: string;\n cwds: string[];\n /** Absolute path to the automation.toml. */\n path: string;\n /** Absolute path to memory.md, or null when it is not a readable file. */\n memoryPath: string | null;\n}\n\ninterface AutomationRun {\n automation: AutomationConfig;\n date: string;\n title: string;\n keyActions: string[];\n projects: string[];\n signals: string[];\n}\n\n/** Summary of a {@link mergeAutomationTree} call. */\nexport interface MergeResult {\n automationsSeen: number;\n automationsCreated: number;\n bulletsAdded: number;\n sectionsCreated: number;\n skipped: string[];\n}\n\n// -- Minimal logger ------------------------------------------------------------\n\nconst logger = {\n warn(msg: string): void {\n // eslint-disable-next-line no-console\n console.warn(`[bourdon.participants] ${msg}`);\n },\n};\n\n// -- fs helpers ----------------------------------------------------------------\n\nfunction homeDir(): string {\n // os.homedir() can throw under some sandboxes; stay defensive so import +\n // construction never crash even when HOME points at an unreadable path.\n try {\n return homedir();\n } catch {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n }\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\n// -- Python-idiom helpers ------------------------------------------------------\n\n/** Python truthiness for the scalar types read here (str / int / None). */\nfunction pyFalsy(v: unknown): boolean {\n return v === undefined || v === null || v === \"\" || v === 0 || v === false;\n}\n\n/** Mirror Python `str(raw.get(key) or fallback)`. */\nfunction strOr(v: unknown, fallback: string): string {\n return String(pyFalsy(v) ? fallback : v);\n}\n\n/** Mirror Python `str.strip(chars)` — strip a fixed char SET from both ends. */\nfunction stripChars(s: string, chars: string): string {\n let start = 0;\n let end = s.length;\n while (start < end && chars.includes(s[start]!)) start++;\n while (end > start && chars.includes(s[end - 1]!)) end--;\n return s.slice(start, end);\n}\n\n/** Mirror Python `str.rstrip()` (trailing whitespace only). */\nfunction rstrip(s: string): string {\n return s.replace(/\\s+$/, \"\");\n}\n\n/**\n * Mirror Python `_bounded`: collapse all whitespace to single spaces, trim, and\n * cap at `limit` with a trailing ellipsis. NOTE the exact truncation form —\n * `normalized[: limit - 1].rstrip() + \"...\"` — which is DISTINCT from\n * `redactText`'s `limit - 3` tail. Do not conflate the two.\n */\nfunction bounded(value: string, limit: number): string {\n const trimmed = value.trim();\n const normalized = trimmed === \"\" ? \"\" : trimmed.split(/\\s+/).join(\" \");\n if (normalized.length <= limit) return normalized;\n return rstrip(normalized.slice(0, limit - 1)) + \"...\";\n}\n\n/** `_safe_native_memory_text(v)` == `redactText(v, 180)` (positional). */\nfunction safeNativeMemoryText(value: string): string {\n return redactText(value, 180);\n}\n\n// -- Path helpers --------------------------------------------------------------\n\n/** Return the default Cursor automations directory. */\nexport function defaultCursorAutomationsDir(cursorHome?: string | null): string {\n if (cursorHome !== undefined && cursorHome !== null) {\n return join(cursorHome, AUTOMATIONS_DIR_NAME);\n }\n const env = process.env.CURSOR_DIR || process.env.CURSOR_HOME;\n if (env) return join(env, AUTOMATIONS_DIR_NAME);\n return join(homeDir(), \".cursor\", AUTOMATIONS_DIR_NAME);\n}\n\n// -- TOML + memory parsing -----------------------------------------------------\n\nfunction readAutomationToml(path: string): Record<string, unknown> {\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch (exc) {\n logger.warn(`CursorAutomationsParticipant: cannot parse ${path}: ${String(exc)}`);\n return {};\n }\n try {\n const parsed = parseToml(text);\n return typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : {};\n } catch (exc) {\n logger.warn(`CursorAutomationsParticipant: cannot parse ${path}: ${String(exc)}`);\n return {};\n }\n}\n\nfunction buildConfig(tomlPath: string): AutomationConfig | null {\n const raw = readAutomationToml(tomlPath);\n const parentName = basenameOf(dirname(tomlPath));\n const automationId = strOr(raw[\"id\"], parentName).trim();\n if (!automationId) return null;\n const name = strOr(raw[\"name\"], automationId).trim();\n const status = strOr(raw[\"status\"], \"UNKNOWN\").trim().toUpperCase();\n const rrule = strOr(raw[\"rrule\"], \"\").trim();\n const kind = strOr(raw[\"kind\"], \"\").trim();\n\n const cwdsRaw = raw[\"cwds\"];\n const cwds: string[] = [];\n if (Array.isArray(cwdsRaw)) {\n for (const cwd of cwdsRaw) {\n if (typeof cwd === \"string\" && cwd.trim()) cwds.push(cwd);\n }\n } else if (typeof cwdsRaw === \"string\") {\n for (const ch of cwdsRaw) {\n if (ch.trim()) cwds.push(ch);\n }\n }\n\n const memoryPath = join(dirname(tomlPath), MEMORY_MD);\n return {\n automationId,\n name,\n status,\n rrule,\n kind,\n cwds,\n path: tomlPath,\n memoryPath: isFile(memoryPath) ? memoryPath : null,\n };\n}\n\n/** `os.path.basename` on a (possibly trailing-slash-free) dir path. */\nfunction basenameOf(p: string): string {\n const parts = p.split(/[\\\\/]+/).filter((x) => x !== \"\");\n return parts.length ? parts[parts.length - 1]! : \"\";\n}\n\n/**\n * Enumerate `<dir>/*​/automation.toml`, sorted by full path. Mirrors Python's\n * `sorted(dir.glob(\"*​/automation.toml\"))` — pathlib's `*` does NOT match names\n * beginning with a dot, so dot-prefixed automation dirs are skipped.\n */\nfunction iterConfigs(automationsDir: string): AutomationConfig[] {\n const configs: AutomationConfig[] = [];\n if (!isDir(automationsDir)) return configs;\n let names: string[];\n try {\n names = readdirSync(automationsDir);\n } catch {\n return configs;\n }\n const tomlPaths: string[] = [];\n for (const name of names) {\n // pathlib `Path.glob(\"*\")` MATCHES dot-prefixed dirs — do NOT skip them.\n const tomlPath = join(automationsDir, name, AUTOMATION_TOML);\n if (isFile(tomlPath)) tomlPaths.push(tomlPath);\n }\n tomlPaths.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n for (const tomlPath of tomlPaths) {\n const config = buildConfig(tomlPath);\n if (config !== null) configs.push(config);\n }\n return configs;\n}\n\nfunction readMemoryText(path: string | null): string {\n if (path === null) return \"\";\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch (exc) {\n logger.warn(`CursorAutomationsParticipant: cannot read ${path}: ${String(exc)}`);\n return \"\";\n }\n return text.slice(-MAX_MEMORY_CHARS);\n}\n\nfunction extractMemoryRuns(config: AutomationConfig): AutomationRun[] {\n const text = readMemoryText(config.memoryPath);\n if (!text) return [];\n\n const chunks: Array<[string, string[]]> = [];\n let currentDate = \"\";\n let currentLines: string[] = [];\n for (const rawLine of text.split(/\\r?\\n/)) {\n const line = rstrip(rawLine);\n const match = RUN_HEADER_RE.exec(line.trim());\n if (match) {\n if (currentDate) chunks.push([currentDate, currentLines]);\n currentDate = match[1]!;\n const suffix = stripChars(match[2]!.trim(), HEADER_SUFFIX_STRIP);\n currentLines = suffix ? [suffix] : [];\n continue;\n }\n if (currentDate) currentLines.push(line);\n }\n if (currentDate) chunks.push([currentDate, currentLines]);\n\n const runs: AutomationRun[] = [];\n for (const [runDate, lines] of chunks) {\n const actions = actionsFromLines(lines);\n if (actions.length === 0) continue;\n const body = actions.join(\" \");\n const title = titleFromActions(config, actions);\n runs.push({\n automation: config,\n date: runDate,\n title,\n keyActions: actions,\n projects: inferProjects(body),\n signals: inferSignals(body),\n });\n }\n return runs;\n}\n\nfunction actionsFromLines(lines: string[]): string[] {\n const actions: string[] = [];\n for (const line of lines) {\n let cleaned = line.trim();\n if (!cleaned) continue;\n cleaned = (cleaned.startsWith(\"- \") ? cleaned.slice(2) : cleaned).trim();\n const lowered = cleaned.toLowerCase();\n if (!cleaned || lowered.startsWith(\"runtime\")) continue;\n if (lowered === \"first run\" || lowered === \"follow-up\") continue;\n if (lowered.startsWith(\"run:\")) cleaned = cleaned.slice(4).trim();\n const safe = bounded(safeNativeMemoryText(cleaned), MAX_KEY_ACTION_CHARS);\n if (safe && !actions.includes(safe)) actions.push(safe);\n if (actions.length >= MAX_KEY_ACTIONS_PER_RUN) break;\n }\n return actions;\n}\n\nfunction titleFromActions(config: AutomationConfig, actions: string[]): string {\n if (actions.length === 0) return config.name;\n const first = actions[0]!;\n const prefix = `${config.name}: `;\n if (first.startsWith(prefix)) return bounded(first, 120);\n return bounded(prefix + first, 120);\n}\n\nfunction inferProjects(text: string): string[] {\n const projects: string[] = [];\n const lowered = text.toLowerCase();\n const seen = new Set<string>();\n for (const project of loadProjectHints(DEFAULT_PROJECT_HINTS)) {\n const key = project.toLowerCase();\n if (lowered.includes(key) && !seen.has(key)) {\n projects.push(project);\n seen.add(key);\n }\n }\n return projects;\n}\n\nfunction inferSignals(text: string): string[] {\n const signals: string[] = [];\n for (const [name, pattern] of SIGNAL_PATTERNS) {\n if (pattern.test(text)) signals.push(name);\n }\n return signals;\n}\n\n// -- Merge / ingest ------------------------------------------------------------\n\n/** Split memory.md text into (date_header, list_of_bullets) sections. */\nfunction parseMemorySections(text: string): Array<[string, string[]]> {\n const sections: Array<[string, string[]]> = [];\n let currentDate = \"\";\n let currentBullets: string[] = [];\n for (const rawLine of text.split(/\\r?\\n/)) {\n const line = rstrip(rawLine);\n const match = RUN_HEADER_RE.exec(line.trim());\n if (match) {\n if (currentDate) sections.push([currentDate, currentBullets]);\n currentDate = match[1]!;\n const suffix = stripChars(match[2]!.trim(), HEADER_SUFFIX_STRIP);\n currentBullets = [];\n if (suffix) currentBullets.push(suffix);\n continue;\n }\n if (!currentDate) continue;\n const bulletMatch = BULLET_RE.exec(line.trim());\n if (bulletMatch) currentBullets.push(bulletMatch[1]!.trim());\n }\n if (currentDate) sections.push([currentDate, currentBullets]);\n return sections;\n}\n\n/** Render a list of (date, bullets) back to memory.md form. */\nfunction serializeSections(sections: Array<[string, string[]]>): string {\n const blocks: string[] = [];\n for (const [dateStr, bullets] of sections) {\n const lines = [dateStr, ...bullets.map((b) => `- ${b}`)];\n blocks.push(lines.join(\"\\n\"));\n }\n return blocks.join(\"\\n\\n\") + \"\\n\";\n}\n\n/**\n * Merge an automations tree from `sourceDir` into `destDir`. Idempotent —\n * calling twice on the same source is a no-op. Throws when `sourceDir` is not a\n * directory (Python `FileNotFoundError`).\n */\nexport function mergeAutomationTree(\n sourceDir: string,\n destDir: string,\n defaultKind = \"cursor-cloud-agent\",\n): MergeResult {\n if (!isDir(sourceDir)) {\n throw new Error(`merge source not found: ${sourceDir}`);\n }\n mkdirSync(destDir, { recursive: true });\n\n let seen = 0;\n let created = 0;\n let bulletsAdded = 0;\n let sectionsCreated = 0;\n const skipped: string[] = [];\n\n const entries = readdirSync(sourceDir).sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n for (const entryName of entries) {\n const srcIdDir = join(sourceDir, entryName);\n if (!isDir(srcIdDir)) continue;\n seen += 1;\n const automationId = entryName;\n if (!VALID_ID_RE.test(automationId)) {\n skipped.push(automationId);\n continue;\n }\n\n const destIdDir = join(destDir, automationId);\n const srcToml = join(srcIdDir, AUTOMATION_TOML);\n const srcMemory = join(srcIdDir, MEMORY_MD);\n\n if (!existsPath(destIdDir)) {\n mkdirSync(destIdDir, { recursive: true });\n created += 1;\n if (isFile(srcToml)) {\n writeFileSync(join(destIdDir, AUTOMATION_TOML), readFileSync(srcToml, \"utf8\"), \"utf8\");\n } else {\n writeFileSync(\n join(destIdDir, AUTOMATION_TOML),\n `version = 1\\nid = \"${automationId}\"\\n` +\n `name = \"${automationId}\"\\nstatus = \"ACTIVE\"\\n` +\n `kind = \"${defaultKind}\"\\nrrule = \"\"\\ncwds = []\\n`,\n \"utf8\",\n );\n }\n }\n\n if (!isFile(srcMemory)) continue;\n\n const srcSections = parseMemorySections(readFileSync(srcMemory, \"utf8\"));\n const destMemory = join(destIdDir, MEMORY_MD);\n const destSections: Array<[string, string[]]> = isFile(destMemory)\n ? parseMemorySections(readFileSync(destMemory, \"utf8\"))\n : [];\n // Map date -> bullets list (SAME array refs as destSections; last wins on\n // duplicate dates, matching Python `dict(dest_sections)`).\n const destByDate = new Map<string, string[]>();\n for (const [d, b] of destSections) destByDate.set(d, b);\n\n for (const [dateStr, bullets] of srcSections) {\n if (!destByDate.has(dateStr)) {\n const fresh: string[] = [];\n destByDate.set(dateStr, fresh);\n destSections.push([dateStr, fresh]);\n sectionsCreated += 1;\n }\n const existing = destByDate.get(dateStr)!;\n for (const bullet of bullets) {\n if (!existing.includes(bullet)) {\n existing.push(bullet);\n bulletsAdded += 1;\n }\n }\n }\n\n destSections.sort((x, y) => (x[0] < y[0] ? -1 : x[0] > y[0] ? 1 : 0));\n writeFileSync(destMemory, serializeSections(destSections), \"utf8\");\n }\n\n return {\n automationsSeen: seen,\n automationsCreated: created,\n bulletsAdded,\n sectionsCreated,\n skipped,\n };\n}\n\nfunction existsPath(p: string): boolean {\n try {\n statSync(p);\n return true;\n } catch {\n return false;\n }\n}\n\n// -- Init helper ---------------------------------------------------------------\n\nconst INIT_TOML_TEMPLATE = `id = \"{automation_id}\"\nname = \"{automation_id}\"\nstatus = \"ACTIVE\"\nrrule = \"\"\nkind = \"\"\ncwds = []\n`;\n\nconst INIT_MEMORY_TEMPLATE = `# {automation_id}\n#\n# Append dated sections below. Each YYYY-MM-DD header starts a new run;\n# bullets under it become key_actions in the L5 manifest.\n#\n# Example:\n# 2026-06-01\n# - Reviewed open PRs in Bourdon and Northwind.\n# - No critical issues found.\n`;\n\n/** Create a starter automation directory with toml + memory.md. */\nexport function initAutomationsDir(\n automationsDir?: string | null,\n automationId = \"cursor-cloud-agent\",\n force = false,\n): string {\n const base = automationsDir || defaultCursorAutomationsDir();\n const target = join(base, automationId);\n if (existsPath(target) && !force) {\n throw new Error(`${target} already exists. Pass --force to overwrite.`);\n }\n mkdirSync(target, { recursive: true });\n writeFileSync(\n join(target, AUTOMATION_TOML),\n INIT_TOML_TEMPLATE.split(\"{automation_id}\").join(automationId),\n \"utf8\",\n );\n writeFileSync(\n join(target, MEMORY_MD),\n INIT_MEMORY_TEMPLATE.split(\"{automation_id}\").join(automationId),\n \"utf8\",\n );\n return target;\n}\n\n// -- L5 helpers ----------------------------------------------------------------\n\nfunction sessionFromRun(run: AutomationRun): SessionModel {\n const config = run.automation;\n const keyActions = [\n `automation_id: ${config.automationId}`,\n `run: ${run.title}`,\n ...run.keyActions,\n ];\n const filesTouched = [config.path];\n if (config.memoryPath !== null) filesTouched.push(config.memoryPath);\n return makeSession({\n date: run.date,\n cwd: config.cwds.length ? config.cwds[0]! : dirname(config.path),\n project_focus: [...run.projects],\n key_actions: keyActions.slice(0, MAX_KEY_ACTIONS_PER_RUN + 2),\n files_touched: filesTouched,\n visibility: Visibility.TEAM,\n });\n}\n\nfunction entitiesFromConfigsAndRuns(\n configs: AutomationConfig[],\n runs: AutomationRun[],\n): EntityModel[] {\n const entitiesByName = new Map<string, EntityModel>();\n for (const config of configs) {\n entitiesByName.set(\n config.automationId,\n makeEntity({\n name: config.automationId,\n type: \"automation\",\n summary: bounded(\n `Cursor automation '${config.name}' (${config.status}). ` +\n `Schedule: ${config.rrule || \"unspecified\"}.`,\n 260,\n ),\n last_touched: null,\n tags: [\"cursor-automation\", \"automation\", config.status.toLowerCase()],\n visibility: Visibility.TEAM,\n }),\n );\n }\n for (const run of runs) {\n for (const project of run.projects) {\n if (!entitiesByName.has(project)) {\n entitiesByName.set(\n project,\n makeEntity({\n name: project,\n type: \"project\",\n summary: \"Project mentioned by Cursor automation run memory.\",\n last_touched: run.date,\n tags: [\"cursor-automation\", \"automation-evidence\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n for (const signal of run.signals) {\n if (!entitiesByName.has(signal)) {\n entitiesByName.set(\n signal,\n makeEntity({\n name: signal,\n type: \"automation-signal\",\n summary: \"Signal class inferred from Cursor automation run memory.\",\n last_touched: run.date,\n tags: [\"cursor-automation\", \"automation-signal\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n }\n return [...entitiesByName.values()];\n}\n\n/** `datetime.now(timezone.utc).isoformat(timespec=\"seconds\")` form. */\nfunction nowIsoSeconds(): string {\n return new Date().toISOString().replace(/\\.\\d+Z$/, \"+00:00\");\n}\n\n// -- Participant ---------------------------------------------------------------\n\n/** External participant for Cursor Cloud Agent automation memory artifacts. */\nexport class CursorAutomationsParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n\n private readonly automationsDir: string;\n private readonly policy: VisibilityPolicyModel;\n\n constructor(automationsDir?: string | null, cursorHome?: string | null) {\n this.automationsDir =\n automationsDir || defaultCursorAutomationsDir(cursorHome ?? undefined);\n this.policy = DEFAULT_POLICY;\n }\n\n get nativePath(): string {\n return this.automationsDir;\n }\n\n discover(): AgentStore {\n if (!isDir(this.automationsDir)) {\n throw new ParticipantDiscoveryError(\n `Cursor automations directory not found at ${this.automationsDir}.`,\n );\n }\n const configs = iterConfigs(this.automationsDir);\n return {\n path: this.automationsDir,\n version: \"unknown\",\n metadata: {\n automations: configs.length,\n with_memory: configs.filter((c) => c.memoryPath !== null).length,\n },\n };\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const sessions = this.runs(undefined, since).map(sessionFromRun);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n return sessions.slice(0, limit);\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const configs = iterConfigs(this.automationsDir);\n const runs = this.runs(configs, since);\n const sessions = runs.map(sessionFromRun);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n const entities = entitiesFromConfigsAndRuns(configs, runs);\n const visibleEntities = filterForFederation(entities, this.policy);\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: hostname(),\n spec_version_compat: SPEC_VERSION,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: nowIsoSeconds(),\n capabilities: [\"cursor-automation-memory\", \"run-summary-publication\"],\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: this.policy,\n });\n }\n\n healthCheck(): HealthStatus {\n if (!isDir(this.automationsDir)) {\n return {\n status: \"blocked\",\n reason: `Cursor automations directory not found at ${this.automationsDir}.`,\n details: { automations_dir: this.automationsDir },\n proposedFix: \"Create Cursor automations or pass --automations-dir.\",\n };\n }\n const configs = iterConfigs(this.automationsDir);\n const runs = this.runs(configs);\n const hasConfigs = configs.length > 0;\n const details = {\n automations_dir: this.automationsDir,\n automation_count: configs.length,\n memory_files: configs.filter((c) => c.memoryPath !== null).length,\n runs_extracted: runs.length,\n active_automations: configs.filter((c) => c.status === \"ACTIVE\").length,\n };\n if (hasConfigs) {\n return { status: \"ok\", details };\n }\n return {\n status: \"degraded\",\n reason: \"No automation.toml files found.\",\n details,\n proposedFix: \"Add Cursor automation.toml files.\",\n };\n }\n\n private runs(configs?: AutomationConfig[], since?: Date): AutomationRun[] {\n const runCutoff = since ? since.toISOString().slice(0, 10) : null;\n const runs: AutomationRun[] = [];\n for (const config of configs ?? iterConfigs(this.automationsDir)) {\n for (const run of extractMemoryRuns(config)) {\n if (runCutoff && run.date < runCutoff) continue;\n runs.push(run);\n }\n }\n // Sort by (date, automationId) DESCENDING (Python reverse=True on the tuple).\n runs.sort((a, b) => {\n if (a.date !== b.date) return a.date > b.date ? -1 : 1;\n const ai = a.automation.automationId;\n const bi = b.automation.automationId;\n return ai > bi ? -1 : ai < bi ? 1 : 0;\n });\n return runs;\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Claude Desktop · Code participant — the Claude desktop app's GUI \"Claude Code\"\n * surface. Port of `participants/claude_desktop_code.py` (+ the shared\n * `participants/_claude_desktop.py` helpers it needs).\n *\n * The desktop GUI's Claude Code keeps **metadata-only** state on disk — there is\n * no transcript. State files live at:\n *\n * <desktop>/claude-code-sessions/<accountUUID>/<orgUUID>/local_<id>.json\n *\n * This participant emits **recognition metadata only** and routes every emitted\n * string through the shared redactor + a length cap (defense in depth): title,\n * cwd→project, model, effort, `enabledMcpTools` *count*, timestamps. It never\n * emits `planPath` contents or any free-form text beyond the redacted title.\n *\n * Distinct from the interactive-CLI {@link ClaudeCodeParticipant} and the richer\n * Co-Work surface. Convention: file/JSON reader (no SQLite, no network).\n */\n\nimport { readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { homedir, hostname } from \"node:os\";\nimport { basename, join, parse as parsePath } from \"node:path\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n loadProjectHints,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\n\n// -- Constants ----------------------------------------------------------------\n\nconst AGENT_ID = \"claude-desktop-code\";\nconst AGENT_TYPE = \"code-assistant\";\nconst DISPLAY_NAME = \"Claude Desktop · Code\";\nconst SURFACE_ENTITY_NAME = \"Claude Desktop Code\";\nconst ROLE_NARRATIVE =\n \"Claude desktop app, GUI Claude Code. Bourdon reads the metadata-only \" +\n \"per-conversation local state to surface recognition metadata -- title, \" +\n \"project, model, effort, capability counts -- never conversation content \" +\n \"-- so desktop Claude Code work is visible to other agents.\";\n\n// Environment override (tests + non-standard installs). Takes precedence over\n// the platform default but not over an explicit `home` argument.\nconst DESKTOP_DIR_ENV = \"BOURDON_CLAUDE_DESKTOP_DIR\";\n\n// Sub-store directory name under the desktop dir.\nconst CODE_STORE = \"claude-code-sessions\";\n\n// State filename prefix shared by both desktop stores (`local_<uuid>.json`).\nconst STATE_PREFIX = \"local_\";\nconst STATE_FILE_RE = /^local_.*\\.json$/;\n\n// Caps -- keep emitted metadata small and bounded.\nconst MAX_KEY_ACTION_CHARS = 280;\nconst MAX_PROJECTS = 6;\nconst MAX_KEY_ACTIONS = 6;\n\n// Product-neutral defaults only: this product plus the agent surfaces Bourdon\n// federates. A deployment adds its own project roster via the\n// `BOURDON_PROJECT_HINTS` env var (comma-separated) — see `loadProjectHints`.\nconst DEFAULT_PROJECT_HINTS: readonly string[] = [\n \"Bourdon\",\n \"Cursor\",\n \"Copilot\",\n \"Codex\",\n \"Cascade\",\n];\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"health\", \"family\", \"legal\"],\n team_tags: [\"claude-desktop\", \"claude-desktop-code\", \"agent-surface\", \"workspace\"],\n});\n\n// -- fs helpers ---------------------------------------------------------------\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\n// -- Desktop-dir resolution (`_claude_desktop.default_claude_desktop_dir`) -----\n\nfunction homeBase(home?: string): string {\n // Mirror Python's `home or Path.home()`. os.homedir() can throw under some\n // sandboxes; stay defensive so import + construction never crash.\n if (home !== undefined) return home;\n try {\n return homedir();\n } catch {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n }\n}\n\n/**\n * Resolve the Claude desktop application-support directory. Returns `null` only\n * on an unrecognized platform with no env override (callers treat that as\n * \"blocked\" rather than crashing).\n *\n * Precedence: `BOURDON_CLAUDE_DESKTOP_DIR` env → platform default anchored on\n * `home` (defaults to homedir).\n */\nexport function defaultClaudeDesktopDir(home?: string): string | null {\n const env = process.env[DESKTOP_DIR_ENV];\n if (env) return env;\n\n const base = homeBase(home);\n if (process.platform === \"darwin\") {\n return join(base, \"Library\", \"Application Support\", \"Claude\");\n }\n if (process.platform === \"win32\") {\n // When an explicit home is provided (tests), keep everything under it so the\n // fake tree is self-contained; otherwise honor %APPDATA%.\n if (home === undefined) {\n const appdata = process.env.APPDATA;\n if (appdata) return join(appdata, \"Claude\");\n }\n return join(base, \"AppData\", \"Roaming\", \"Claude\");\n }\n if (process.platform === \"linux\") {\n return join(base, \".config\", \"Claude\");\n }\n return null;\n}\n\n// -- State-file globbing (`_claude_desktop.iter_state_files`) ------------------\n\n/**\n * Return every `local_*.json` under `<store_dir>/<acct>/<org>/`, sorted by path.\n * Never raises when the store dir is absent (returns `[]`) so health checks can\n * distinguish \"store missing\" from \"store empty\".\n */\nfunction iterStateFiles(storeDir: string): string[] {\n if (!isDir(storeDir)) return [];\n const out: string[] = [];\n let accts: string[];\n try {\n accts = readdirSync(storeDir);\n } catch {\n return out;\n }\n for (const acct of accts) {\n const acctDir = join(storeDir, acct);\n if (!isDir(acctDir)) continue;\n let orgs: string[];\n try {\n orgs = readdirSync(acctDir);\n } catch {\n continue;\n }\n for (const org of orgs) {\n const orgDir = join(acctDir, org);\n if (!isDir(orgDir)) continue;\n let names: string[];\n try {\n names = readdirSync(orgDir);\n } catch {\n continue;\n }\n for (const name of names) {\n if (name.startsWith(STATE_PREFIX) && STATE_FILE_RE.test(name)) {\n out.push(join(orgDir, name));\n }\n }\n }\n }\n out.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n return out;\n}\n\n/**\n * Read + parse one `local_*.json` state file. Returns the parsed object, or\n * `null` on any read/parse failure or if the top-level JSON is not an object.\n * Never raises — malformed files are counted and skipped by callers.\n */\nfunction loadStateJson(path: string): Record<string, unknown> | null {\n let raw: string;\n try {\n raw = readFileSync(path, \"utf8\");\n } catch {\n return null;\n }\n let data: unknown;\n try {\n data = JSON.parse(raw);\n } catch {\n return null;\n }\n if (typeof data !== \"object\" || data === null || Array.isArray(data)) return null;\n return data as Record<string, unknown>;\n}\n\n// -- Scalar helpers -----------------------------------------------------------\n\n/**\n * Convert an epoch timestamp to a UTC `YYYY-MM-DD` string. Accepts ms (`> 1e12`)\n * or seconds; ints, floats, and numeric strings are tolerated. Returns `\"\"` on\n * anything unparseable (bools are rejected explicitly, as in Python).\n */\nfunction epochToDate(value: unknown): string {\n if (typeof value === \"boolean\") return \"\"; // bool is an int subclass in Py — reject\n let num: number | null = null;\n if (typeof value === \"number\") {\n num = value;\n } else if (typeof value === \"string\" && value.trim()) {\n const parsed = Number(value.trim());\n num = Number.isNaN(parsed) ? null : parsed;\n }\n if (num === null || !Number.isFinite(num)) return \"\";\n const seconds = num > 1e12 ? num / 1000 : num;\n try {\n const d = new Date(seconds * 1000);\n const iso = d.toISOString();\n return iso.slice(0, 10);\n } catch {\n return \"\";\n }\n}\n\n/** Pick a session date from `createdAt` then `lastActivityAt`. */\nfunction sessionDate(state: Record<string, unknown>): string {\n for (const key of [\"createdAt\", \"lastActivityAt\"] as const) {\n const parsed = epochToDate(state[key]);\n if (parsed) return parsed;\n }\n return \"\";\n}\n\n/**\n * Redact credential-like text + strip links, then cap to `limit` chars. Runs\n * through the redaction SSOT first so a planted secret becomes the sentinel\n * *before* truncation can split it. Mirrors `_safe_native_memory_text(v, limit)`.\n */\nfunction bounded(value: string, limit: number = MAX_KEY_ACTION_CHARS): string {\n return redactText(value, limit);\n}\n\n/** Coerce a scalar to a bounded, redacted display string (\"\" if empty). */\nfunction safeLabel(value: unknown, limit: number = MAX_KEY_ACTION_CHARS): string {\n if (value === null || value === undefined) return \"\";\n const text = String(value).trim();\n if (!text) return \"\";\n return bounded(text, limit);\n}\n\n/**\n * Count `true` values in an `enabledMcpTools` mapping. Keys are\n * `\"<serverUUID>:<tool>\"` and are NOT emitted — only the count of enabled\n * entries is surfaced, so no tool names or server identifiers leak.\n */\nfunction countEnabledMcpTools(enabled: unknown): number {\n if (typeof enabled !== \"object\" || enabled === null || Array.isArray(enabled)) return 0;\n let count = 0;\n for (const v of Object.values(enabled as Record<string, unknown>)) {\n if (v === true) count += 1;\n }\n return count;\n}\n\nfunction baseName(pathValue: unknown): string {\n if (typeof pathValue !== \"string\" || !pathValue.trim()) return \"\";\n const name = basename(pathValue.trim()).trim();\n return name && name !== \".\" && name !== \"/\" && name !== \"\\\\\" ? name : \"\";\n}\n\n/**\n * Infer project names from cwd + user-selected folders (basenames only), plus a\n * project-hint substring match. No file contents / no full paths — only\n * directory basenames and recognized labels. Order-preserving + de-duplicated.\n */\nfunction inferProjects(state: Record<string, unknown>): string[] {\n const projects: string[] = [];\n const seen = new Set<string>();\n\n const add = (name: string): void => {\n const cleaned = name.trim();\n if (cleaned && !seen.has(cleaned.toLowerCase())) {\n projects.push(cleaned);\n seen.add(cleaned.toLowerCase());\n }\n };\n\n const pathStrings: string[] = [];\n const cwd = state[\"cwd\"];\n if (typeof cwd === \"string\" && cwd.trim()) pathStrings.push(cwd);\n const folders = state[\"userSelectedFolders\"];\n if (Array.isArray(folders)) {\n for (const f of folders) {\n if (typeof f === \"string\" && f.trim()) pathStrings.push(f);\n }\n }\n\n for (const rawPath of pathStrings) {\n const base = baseName(rawPath);\n if (base) add(base);\n }\n\n const haystack = pathStrings.join(\" \").toLowerCase();\n for (const hint of loadProjectHints(DEFAULT_PROJECT_HINTS)) {\n if (haystack.includes(hint.toLowerCase())) add(hint);\n }\n\n return projects.slice(0, MAX_PROJECTS);\n}\n\n// -- Normalized conversation --------------------------------------------------\n\ninterface CodeConversation {\n convId: string;\n date: string;\n cwd: string;\n title: string;\n model: string;\n effort: string;\n permissionMode: string;\n isArchived: boolean;\n mcpToolCount: number;\n projects: string[];\n}\n\nfunction conversationFromState(\n statePath: string,\n state: Record<string, unknown>,\n): CodeConversation {\n const sessionId = state[\"sessionId\"];\n const stem = parsePath(statePath).name;\n return {\n convId: String(sessionId || stem),\n date: sessionDate(state),\n cwd: safeLabel(state[\"cwd\"], 300),\n title: safeLabel(state[\"title\"], 160) || \"(untitled conversation)\",\n model: safeLabel(state[\"model\"], 80),\n effort: safeLabel(state[\"effort\"], 40),\n permissionMode: safeLabel(state[\"permissionMode\"], 40),\n isArchived: Boolean(state[\"isArchived\"]),\n mcpToolCount: countEnabledMcpTools(state[\"enabledMcpTools\"]),\n projects: inferProjects(state),\n };\n}\n\nfunction keyActions(conv: CodeConversation): string[] {\n const actions: string[] = [bounded(conv.title, 160)];\n if (conv.model) actions.push(bounded(`model: ${conv.model}`, 120));\n if (conv.effort) actions.push(bounded(`effort: ${conv.effort}`, 60));\n if (conv.permissionMode) actions.push(bounded(`permission: ${conv.permissionMode}`, 80));\n if (conv.mcpToolCount) actions.push(`mcp-tools: ${conv.mcpToolCount}`);\n return actions.slice(0, MAX_KEY_ACTIONS);\n}\n\nfunction sessionFromConversation(conv: CodeConversation): SessionModel {\n return makeSession({\n date: conv.date,\n cwd: conv.cwd || undefined,\n project_focus: [...conv.projects],\n key_actions: keyActions(conv),\n files_touched: [], // never list user files -- privacy\n visibility: Visibility.TEAM,\n });\n}\n\nfunction capabilities(convs: CodeConversation[]): string[] {\n let maxMcp = 0;\n for (const conv of convs) if (conv.mcpToolCount > maxMcp) maxMcp = conv.mcpToolCount;\n return [AGENT_ID, `mcp-tools:${maxMcp}`];\n}\n\nfunction entitiesFromConversations(convs: CodeConversation[]): EntityModel[] {\n let lastSeen: string | undefined;\n for (const conv of convs) {\n if (lastSeen === undefined || conv.date > lastSeen) lastSeen = conv.date;\n }\n\n const entities = new Map<string, EntityModel>();\n entities.set(\n SURFACE_ENTITY_NAME,\n makeEntity({\n name: SURFACE_ENTITY_NAME,\n type: \"agent-surface\",\n summary: bounded(\n \"Claude desktop app GUI Claude Code surface (metadata-only federation).\",\n 260,\n ),\n last_touched: lastSeen,\n tags: [\"claude-desktop\", \"claude-desktop-code\", \"agent-surface\"],\n visibility: Visibility.TEAM,\n }),\n );\n for (const conv of convs) {\n for (const project of conv.projects) {\n if (!entities.has(project)) {\n entities.set(\n project,\n makeEntity({\n name: project,\n type: \"project\",\n summary: \"Project inferred from a Claude Desktop Code conversation cwd.\",\n last_touched: conv.date || undefined,\n tags: [\"claude-desktop\", \"claude-desktop-code\", \"project\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n }\n return [...entities.values()];\n}\n\n// -- Participant --------------------------------------------------------------\n\n/**\n * External participant for the Claude desktop app's GUI Claude Code surface.\n * File/JSON reader — metadata-only, no transcript, no SQLite, no network.\n */\nexport class ClaudeDesktopCodeParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n displayName = DISPLAY_NAME;\n\n private readonly storeDir: string;\n private readonly policy: VisibilityPolicyModel;\n\n /**\n * The Claude Code sub-store dir the setup wizard probes for presence. Resolves\n * to `<desktop>/claude-code-sessions`. Falls back to a non-existent sentinel\n * under `home` on an unrecognized platform so the wizard reports \"not found\".\n */\n static defaultNativePath(home?: string): string {\n const desktop = defaultClaudeDesktopDir(home);\n if (desktop === null) return join(homeBase(home), \"Claude\", CODE_STORE);\n return join(desktop, CODE_STORE);\n }\n\n constructor(storeDir?: string, home?: string) {\n this.storeDir = storeDir ?? ClaudeDesktopCodeParticipant.defaultNativePath(home);\n this.policy = DEFAULT_POLICY;\n }\n\n get nativePath(): string {\n return this.storeDir;\n }\n\n discover(): AgentStore {\n if (!isDir(this.storeDir)) {\n throw new ParticipantDiscoveryError(\n `Claude Desktop Code store not found at ${this.storeDir}.`,\n );\n }\n const stateFiles = iterStateFiles(this.storeDir);\n return {\n path: this.storeDir,\n version: \"unknown\",\n metadata: { conversations: stateFiles.length },\n };\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const convs = this.conversations(since);\n const sessions = convs.map(sessionFromConversation);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n return sessions.slice(0, limit);\n }\n\n exportL5(since?: Date): L5ManifestModel {\n if (!isDir(this.storeDir)) {\n throw new ParticipantDiscoveryError(\n `Claude Desktop Code store not found at ${this.storeDir}.`,\n );\n }\n const convs = this.conversations(since);\n const sessions = convs.map(sessionFromConversation);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n const entities = entitiesFromConversations(convs);\n const visibleEntities = filterForFederation(entities, this.policy);\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: hostname(),\n spec_version_compat: SPEC_VERSION,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: new Date().toISOString(),\n capabilities: capabilities(convs),\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: this.policy,\n });\n }\n\n healthCheck(): HealthStatus {\n if (!isDir(this.storeDir)) {\n return {\n status: \"blocked\",\n reason: `Claude Desktop Code store not found at ${this.storeDir}.`,\n details: { store_dir: this.storeDir },\n proposedFix:\n \"Install the Claude desktop app and open a Claude Code conversation \" +\n \"once. Set BOURDON_CLAUDE_DESKTOP_DIR if the app stores state in a \" +\n \"non-standard location.\",\n };\n }\n let stateFiles: string[];\n let convs: CodeConversation[];\n let malformed: number;\n try {\n stateFiles = iterStateFiles(this.storeDir);\n const collected = this.collectConversations();\n convs = collected.convs;\n malformed = collected.malformed;\n } catch (exc) {\n return {\n status: \"degraded\",\n reason: \"Code store present but extraction failed.\",\n details: { error: String(exc) },\n proposedFix:\n \"Close the Claude desktop app (its state files may be locked) and \" +\n \"re-run `bourdon claude-desktop-code export`.\",\n };\n }\n if (stateFiles.length === 0) {\n return {\n status: \"degraded\",\n reason: \"No Claude Code conversations found under the store directory.\",\n details: { store_dir: this.storeDir },\n proposedFix:\n \"Open a Claude Code conversation in the Claude desktop app, then \" +\n \"re-run `bourdon claude-desktop-code export`.\",\n };\n }\n return {\n status: \"ok\",\n details: {\n store_dir: this.storeDir,\n conversation_count: stateFiles.length,\n conversations_extracted: convs.length,\n malformed_records: malformed,\n },\n };\n }\n\n // -- Internal ---------------------------------------------------------------\n\n private collectConversations(): { convs: CodeConversation[]; malformed: number } {\n const convs: CodeConversation[] = [];\n let malformed = 0;\n for (const statePath of iterStateFiles(this.storeDir)) {\n const state = loadStateJson(statePath);\n if (state === null) {\n malformed += 1;\n continue;\n }\n convs.push(conversationFromState(statePath, state));\n }\n return { convs, malformed };\n }\n\n private conversations(since?: Date): CodeConversation[] {\n let { convs } = this.collectConversations();\n if (since !== undefined) {\n const cutoff = since.toISOString().slice(0, 10);\n convs = convs.filter((conv) => !conv.date || conv.date >= cutoff);\n }\n // Reverse tuple sort: (date, convId) descending.\n convs.sort((a, b) => {\n if (a.date !== b.date) return a.date < b.date ? 1 : -1;\n if (a.convId !== b.convId) return a.convId < b.convId ? 1 : -1;\n return 0;\n });\n return convs;\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Claude Desktop · Co-Work participant — the richest of the two Claude-desktop\n * surfaces. Port of `participants/claude_desktop_cowork.py` (+ the shared\n * `participants/_claude_desktop.py` extraction helpers, inlined here).\n *\n * The desktop app stores each Co-Work / local-agent run as a state file plus a\n * sibling audit transcript:\n *\n * <desktop>/local-agent-mode-sessions/<acct>/<org>/local_<id>.json (state)\n * <desktop>/local-agent-mode-sessions/<acct>/<org>/local_<id>/audit.jsonl\n *\n * This participant emits **recognition metadata only**. From the state file it\n * reads surface scalars (title, cwd, model, permission mode, timestamps,\n * `enabledMcpTools` *count*, `userSelectedFolders` *basenames*). From the\n * sibling `audit.jsonl` it reads ONLY the `system`/`init` capability *counts*\n * and the `result` safe scalars (cost, turns, error flag). It NEVER reads\n * conversation content. Every emitted string passes through the redaction SSOT\n * + a length cap, and TEAM entities are visibility-filtered before emission.\n *\n * Storage kind: file/convention (glob + JSON + JSONL), so this reads like the\n * claude-code / cascade file readers — no SQLite, no network.\n */\n\nimport { readFileSync, readdirSync, statSync } from \"node:fs\";\nimport { hostname } from \"node:os\";\nimport { basename, dirname, join, parse as parsePath } from \"node:path\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n loadProjectHints,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\n\n// -- Constants -----------------------------------------------------------------\n\nconst AGENT_ID = \"claude-desktop-cowork\";\nconst AGENT_TYPE = \"code-assistant\";\nconst DISPLAY_NAME = \"Claude Desktop · Co-Work\";\nconst SURFACE_ENTITY_NAME = \"Claude Desktop Co-Work\";\nconst ROLE_NARRATIVE =\n \"Claude desktop app, Co-Work / local-agent mode. Bourdon reads the \" +\n \"per-run local state and audit transcript to surface recognition metadata \" +\n \"-- title, project, model, turn/cost scalars, capability counts -- never \" +\n \"conversation content -- so Co-Work runs are visible to other agents.\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"health\", \"family\", \"legal\"],\n team_tags: [\"claude-desktop\", \"claude-desktop-cowork\", \"agent-surface\", \"workspace\"],\n});\n\n// Environment override (tests + non-standard installs). Takes precedence over\n// the platform default but not over an explicit `home` argument.\nconst DESKTOP_DIR_ENV = \"BOURDON_CLAUDE_DESKTOP_DIR\";\n\n// Sub-store directory name under the desktop dir.\nconst COWORK_STORE = \"local-agent-mode-sessions\";\n\n// State filename prefix (`local_<uuid>.json`).\nconst STATE_PREFIX = \"local_\";\n\nconst MAX_PROJECTS = 6;\nconst MAX_KEY_ACTIONS = 8;\n// audit.jsonl can be large; only the (small) init + result lines are needed, so\n// bound how much to scan before giving up.\nconst MAX_AUDIT_LINES = 50_000;\n\n// Product-neutral defaults only: this product plus the agent surfaces Bourdon\n// federates. A deployment adds its own project roster via the\n// `BOURDON_PROJECT_HINTS` env var (comma-separated) — see `loadProjectHints`.\nconst DEFAULT_PROJECT_HINTS: readonly string[] = [\n \"Bourdon\",\n \"Cursor\",\n \"Copilot\",\n \"Codex\",\n \"Cascade\",\n];\n\n/** Minimal logger so a malformed-file warning is visible without a dep. */\nconst logger = {\n warn(msg: string): void {\n // eslint-disable-next-line no-console\n console.warn(`[bourdon.participants] ${msg}`);\n },\n};\n\n// -- fs helpers ----------------------------------------------------------------\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\nfunction homeDir(): string {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/** Current UTC time at seconds precision + `+00:00` offset — mirrors Python's\n * `datetime.now(timezone.utc).isoformat(timespec=\"seconds\")`. */\nfunction isoSeconds(): string {\n return new Date().toISOString().replace(/\\.\\d{3}Z$/, \"+00:00\");\n}\n\n// -- Desktop dir resolution ----------------------------------------------------\n\n/**\n * Resolve the Claude desktop application-support directory.\n *\n * Precedence:\n * 1. `BOURDON_CLAUDE_DESKTOP_DIR` env var.\n * 2. Platform default, anchored on `home` (defaults to homedir):\n * * macOS -- `<home>/Library/Application Support/Claude`\n * * Windows -- `%APPDATA%/Claude` (falls back to `<home>/AppData/Roaming/Claude`)\n * * Linux -- `<home>/.config/Claude`\n *\n * Returns `null` only on an unrecognized platform with no env override.\n */\nfunction defaultClaudeDesktopDir(home?: string): string | null {\n const env = process.env[DESKTOP_DIR_ENV];\n if (env) return env;\n\n const base = home || homeDir();\n const plat = process.platform;\n if (plat === \"darwin\") {\n return join(base, \"Library\", \"Application Support\", \"Claude\");\n }\n if (plat.startsWith(\"win\")) {\n // When an explicit home is provided (tests), keep everything under it;\n // otherwise honor %APPDATA%.\n if (home === undefined) {\n const appdata = process.env.APPDATA;\n if (appdata) return join(appdata, \"Claude\");\n }\n return join(base, \"AppData\", \"Roaming\", \"Claude\");\n }\n if (plat.startsWith(\"linux\")) {\n return join(base, \".config\", \"Claude\");\n }\n return null;\n}\n\n/**\n * Return every `local_*.json` under `<store_dir>/<acct>/<org>/`, globbing across\n * all account/org UUID directories. Returns `[]` (never throws) when the store\n * dir is absent so health checks can distinguish \"missing\" from \"empty\".\n */\nfunction iterStateFiles(storeDir: string): string[] {\n if (!isDir(storeDir)) return [];\n const out: string[] = [];\n let accounts: string[];\n try {\n accounts = readdirSync(storeDir);\n } catch {\n return [];\n }\n for (const acct of accounts) {\n const acctDir = join(storeDir, acct);\n if (!isDir(acctDir)) continue;\n let orgs: string[];\n try {\n orgs = readdirSync(acctDir);\n } catch {\n continue;\n }\n for (const org of orgs) {\n const orgDir = join(acctDir, org);\n if (!isDir(orgDir)) continue;\n let entries: string[];\n try {\n entries = readdirSync(orgDir);\n } catch {\n continue;\n }\n for (const name of entries) {\n if (name.startsWith(STATE_PREFIX) && name.endsWith(\".json\")) {\n out.push(join(orgDir, name));\n }\n }\n }\n }\n out.sort();\n return out;\n}\n\n/**\n * Read + parse one `local_*.json` state file. Returns the parsed object, or\n * `null` on any read/parse failure or if the top-level JSON is not an object.\n * Never throws -- malformed files are counted and skipped by callers.\n */\nfunction loadStateJson(path: string): Record<string, unknown> | null {\n let raw: string;\n try {\n raw = readFileSync(path, \"utf8\");\n } catch (exc) {\n logger.warn(`claude-desktop: cannot read ${path}: ${String(exc)}`);\n return null;\n }\n let data: unknown;\n try {\n data = JSON.parse(raw);\n } catch (exc) {\n logger.warn(`claude-desktop: cannot parse ${path}: ${String(exc)}`);\n return null;\n }\n return isRecord(data) ? data : null;\n}\n\n// -- Scalar/date helpers -------------------------------------------------------\n\n/**\n * Convert an epoch timestamp to a UTC `YYYY-MM-DD` string. Accepts ms (`> 1e12`)\n * or seconds; ints, floats, and numeric strings are tolerated. Returns `\"\"` on\n * anything unparseable (bool is rejected explicitly).\n */\nfunction epochToDate(value: unknown): string {\n if (typeof value === \"boolean\") return \"\";\n let num: number | null = null;\n if (typeof value === \"number\") {\n num = value;\n } else if (typeof value === \"string\" && value.trim()) {\n const n = Number(value.trim());\n num = Number.isNaN(n) ? null : n;\n }\n if (num === null || Number.isNaN(num)) return \"\";\n const seconds = num > 1e12 ? num / 1000 : num;\n try {\n const d = new Date(seconds * 1000);\n if (Number.isNaN(d.getTime())) return \"\";\n return d.toISOString().slice(0, 10);\n } catch {\n return \"\";\n }\n}\n\n/** Pick a session date from `createdAt` then `lastActivityAt`. */\nfunction sessionDate(state: Record<string, unknown>): string {\n for (const key of [\"createdAt\", \"lastActivityAt\"]) {\n const parsed = epochToDate(state[key]);\n if (parsed) return parsed;\n }\n return \"\";\n}\n\n/** Redact credential-like text + strip links, then cap to `limit` chars. */\nfunction bounded(value: string, limit = 280): string {\n return redactText(value, limit);\n}\n\n/** Coerce a scalar to a bounded, redacted display string (\"\" if empty). */\nfunction safeLabel(value: unknown, limit = 280): string {\n if (value === null || value === undefined) return \"\";\n const text = String(value).trim();\n if (!text) return \"\";\n return bounded(text, limit);\n}\n\n/**\n * Count `true` values in an `enabledMcpTools` mapping. Keys are\n * `\"<serverUUID>:<tool>\"` and are NOT emitted -- only the count leaks.\n */\nfunction countEnabledMcpTools(enabled: unknown): number {\n if (!isRecord(enabled)) return 0;\n let n = 0;\n for (const v of Object.values(enabled)) {\n if (v === true) n += 1;\n }\n return n;\n}\n\nfunction basenameOf(pathValue: unknown): string {\n if (typeof pathValue !== \"string\" || !pathValue.trim()) return \"\";\n const name = basename(pathValue.trim()).trim();\n return name && name !== \".\" && name !== \"/\" && name !== \"\\\\\" ? name : \"\";\n}\n\n/**\n * Infer project names from cwd + user-selected folders (basenames only), plus a\n * project-hint substring match. Order-preserving + case-insensitively deduped.\n * No file contents and no full paths are emitted.\n */\nfunction inferProjects(state: Record<string, unknown>): string[] {\n const projects: string[] = [];\n const seen = new Set<string>();\n\n const add = (name: string): void => {\n const cleaned = name.trim();\n if (cleaned && !seen.has(cleaned.toLowerCase())) {\n projects.push(cleaned);\n seen.add(cleaned.toLowerCase());\n }\n };\n\n const pathStrings: string[] = [];\n const cwd = state[\"cwd\"];\n if (typeof cwd === \"string\" && cwd.trim()) pathStrings.push(cwd);\n const folders = state[\"userSelectedFolders\"];\n if (Array.isArray(folders)) {\n for (const f of folders) {\n if (typeof f === \"string\" && f.trim()) pathStrings.push(f);\n }\n }\n\n for (const raw of pathStrings) {\n const base = basenameOf(raw);\n if (base) add(base);\n }\n\n const haystack = pathStrings.join(\" \").toLowerCase();\n for (const hint of loadProjectHints(DEFAULT_PROJECT_HINTS)) {\n if (haystack.includes(hint.toLowerCase())) add(hint);\n }\n\n return projects.slice(0, MAX_PROJECTS);\n}\n\n// -- audit.jsonl safe-scalar extraction ----------------------------------------\n\n/** Sibling transcript dir: `local_<id>.json` -> `local_<id>/`. */\nfunction runDirFor(statePath: string): string {\n return join(dirname(statePath), parsePath(statePath).name);\n}\n\n/**\n * Pull safe scalars from one audit record into `out` (in place). Only the\n * `system`/`init` and `result` record types contribute; every other record\n * (user/assistant/etc.) is ignored -- their bodies are never touched.\n */\nfunction absorbAuditRecord(record: Record<string, unknown>, out: Record<string, unknown>): void {\n const recType = record[\"type\"];\n const subtype = record[\"subtype\"];\n\n if (recType === \"system\" && subtype === \"init\") {\n // Counts only -- never the tool/skill/command names themselves.\n const pairs: ReadonlyArray<readonly [string, string]> = [\n [\"tools\", \"init_tools\"],\n [\"mcp_servers\", \"init_mcp_servers\"],\n [\"skills\", \"init_skills\"],\n [\"plugins\", \"init_plugins\"],\n [\"slash_commands\", \"init_slash_commands\"],\n ];\n for (const [srcKey, dstKey] of pairs) {\n const value = record[srcKey];\n if (Array.isArray(value)) out[dstKey] = value.length;\n }\n const version = record[\"claude_code_version\"];\n if (version !== null && version !== undefined) {\n out[\"claude_code_version\"] = safeLabel(version, 40);\n }\n return;\n }\n\n if (recType === \"result\") {\n // The `result` *text* field (free-form summary) is deliberately NOT read.\n for (const key of [\"total_cost_usd\", \"num_turns\", \"is_error\", \"duration_ms\"]) {\n if (key in record) out[key] = record[key];\n }\n const stopReason = record[\"stop_reason\"];\n if (stopReason !== null && stopReason !== undefined) {\n out[\"stop_reason\"] = safeLabel(stopReason, 40);\n }\n }\n}\n\n/**\n * Extract ONLY the safe scalars from a Co-Work `audit.jsonl` transcript. Reads\n * line-by-line, tolerantly. A missing, unreadable, or locked file yields an\n * empty object -- never an error. NEVER reads user/assistant message bodies.\n */\nfunction readAuditScalars(runDir: string): Record<string, unknown> {\n const auditPath = join(runDir, \"audit.jsonl\");\n if (!isFile(auditPath)) return {};\n\n const out: Record<string, unknown> = {};\n let raw: string;\n try {\n raw = readFileSync(auditPath, \"utf8\");\n } catch (exc) {\n logger.warn(`claude-desktop: cannot read ${auditPath}: ${String(exc)}`);\n return out;\n }\n\n let lineNo = 0;\n for (const rawLine of raw.split(/\\r?\\n/)) {\n if (lineNo >= MAX_AUDIT_LINES) break;\n lineNo += 1;\n const line = rawLine.trim();\n if (!line || line[0] !== \"{\") continue;\n let record: unknown;\n try {\n record = JSON.parse(line);\n } catch {\n continue;\n }\n if (!isRecord(record)) continue;\n absorbAuditRecord(record, out);\n }\n return out;\n}\n\n// -- Run model -----------------------------------------------------------------\n\n/** Normalized, privacy-redacted view of a single Co-Work run. */\ninterface CoworkRun {\n runId: string;\n date: string;\n cwd: string;\n title: string;\n model: string;\n permissionMode: string;\n isArchived: boolean;\n mcpToolCount: number;\n projects: string[];\n numTurns: number | null;\n totalCostUsd: number | null;\n isError: boolean | null;\n initCounts: Record<string, number>;\n}\n\nfunction runFromState(statePath: string, state: Record<string, unknown>): CoworkRun {\n const audit = readAuditScalars(runDirFor(statePath));\n\n const title = safeLabel(state[\"title\"], 160) || \"(untitled run)\";\n const model = safeLabel(state[\"model\"], 80);\n const permissionMode = safeLabel(state[\"permissionMode\"], 40);\n\n const numTurnsRaw = audit[\"num_turns\"];\n const costRaw = audit[\"total_cost_usd\"];\n const isErrorRaw = audit[\"is_error\"];\n\n const initCounts: Record<string, number> = {};\n for (const [k, v] of Object.entries(audit)) {\n if (k.startsWith(\"init_\") && typeof v === \"number\" && Number.isInteger(v)) {\n initCounts[k] = v;\n }\n }\n\n const stem = parsePath(statePath).name;\n const sid = state[\"sessionId\"];\n\n return {\n runId: String(sid || stem),\n date: sessionDate(state),\n cwd: safeLabel(state[\"cwd\"], 300),\n title,\n model,\n permissionMode,\n isArchived: Boolean(state[\"isArchived\"]),\n mcpToolCount: countEnabledMcpTools(state[\"enabledMcpTools\"]),\n projects: inferProjects(state),\n numTurns: typeof numTurnsRaw === \"number\" && Number.isInteger(numTurnsRaw) ? numTurnsRaw : null,\n totalCostUsd: typeof costRaw === \"number\" ? costRaw : null,\n isError: typeof isErrorRaw === \"boolean\" ? isErrorRaw : null,\n initCounts,\n };\n}\n\n/**\n * Build the bounded, redacted key-action list for a run:\n * `[title, \"model: ...\", \"permission: ...\", \"<n> turns\", \"$<cost>\", \"error\",\n * \"mcp-tools: <n>\"]` -- all metadata, never content.\n */\nfunction keyActions(run: CoworkRun): string[] {\n const actions: string[] = [bounded(run.title, 160)];\n if (run.model) actions.push(bounded(`model: ${run.model}`, 120));\n if (run.permissionMode) actions.push(bounded(`permission: ${run.permissionMode}`, 80));\n if (run.numTurns !== null) actions.push(`${run.numTurns} turns`);\n if (run.totalCostUsd !== null) actions.push(`$${run.totalCostUsd.toFixed(2)}`);\n if (run.isError) actions.push(\"error\");\n if (run.mcpToolCount) actions.push(`mcp-tools: ${run.mcpToolCount}`);\n return actions.slice(0, MAX_KEY_ACTIONS);\n}\n\nfunction sessionFromRun(run: CoworkRun): SessionModel {\n return makeSession({\n date: run.date,\n cwd: run.cwd || undefined, // run.cwd or None -- privacy: never empty string\n project_focus: [...run.projects],\n key_actions: keyActions(run),\n files_touched: [], // never list user files -- privacy\n visibility: Visibility.TEAM,\n });\n}\n\n/** Manifest-level capability *counts* only (no names). */\nfunction capabilities(runs: CoworkRun[]): string[] {\n const caps: string[] = [AGENT_ID];\n const maxMcp = runs.length ? Math.max(...runs.map((r) => r.mcpToolCount)) : 0;\n caps.push(`mcp-tools:${maxMcp}`);\n const bestTools = runs.length ? Math.max(...runs.map((r) => r.initCounts[\"init_tools\"] ?? 0)) : 0;\n if (bestTools) caps.push(`tools:${bestTools}`);\n const bestSkills = runs.length\n ? Math.max(...runs.map((r) => r.initCounts[\"init_skills\"] ?? 0))\n : 0;\n if (bestSkills) caps.push(`skills:${bestSkills}`);\n return caps;\n}\n\nfunction entitiesFromRuns(runs: CoworkRun[]): EntityModel[] {\n const lastSeen = runs.length\n ? runs.map((r) => r.date).reduce((a, b) => (a > b ? a : b))\n : null;\n\n const entities = new Map<string, EntityModel>();\n entities.set(\n SURFACE_ENTITY_NAME,\n makeEntity({\n name: SURFACE_ENTITY_NAME,\n type: \"agent-surface\",\n summary: bounded(\n \"Claude desktop app Co-Work / local-agent mode surface \" +\n \"(metadata-only federation).\",\n 260,\n ),\n last_touched: lastSeen,\n tags: [\"claude-desktop\", \"claude-desktop-cowork\", \"agent-surface\"],\n visibility: Visibility.TEAM,\n }),\n );\n\n for (const run of runs) {\n for (const project of run.projects) {\n if (!entities.has(project)) {\n entities.set(\n project,\n makeEntity({\n name: project,\n type: \"project\",\n summary: \"Project inferred from a Claude Desktop Co-Work run cwd.\",\n last_touched: run.date || undefined, // run.date or None\n tags: [\"claude-desktop\", \"claude-desktop-cowork\", \"project\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n }\n\n return [...entities.values()];\n}\n\n// -- Participant ---------------------------------------------------------------\n\n/** External participant for the Claude desktop app's Co-Work surface. */\nexport class ClaudeDesktopCoworkParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n displayName = DISPLAY_NAME;\n\n private readonly storeDir: string;\n private readonly policy: VisibilityPolicyModel;\n\n /**\n * The Co-Work sub-store dir the setup wizard probes for presence. Resolves to\n * `<desktop>/local-agent-mode-sessions`. When the desktop dir cannot be\n * resolved on this platform, falls back to a non-existent sentinel under\n * `home` so the wizard reports \"not found\" rather than crashing.\n */\n static defaultNativePath(home?: string): string {\n const desktop = defaultClaudeDesktopDir(home);\n if (desktop === null) return join(home || homeDir(), \"Claude\", COWORK_STORE);\n return join(desktop, COWORK_STORE);\n }\n\n constructor(storeDir?: string, home?: string) {\n this.storeDir = storeDir || ClaudeDesktopCoworkParticipant.defaultNativePath(home);\n this.policy = DEFAULT_POLICY;\n }\n\n get nativePath(): string {\n return this.storeDir;\n }\n\n // -- Protocol surface --------------------------------------------------------\n\n discover(): AgentStore {\n if (!isDir(this.storeDir)) {\n throw new ParticipantDiscoveryError(\n `Claude Desktop Co-Work store not found at ${this.storeDir}.`,\n );\n }\n const stateFiles = iterStateFiles(this.storeDir);\n return {\n path: this.storeDir,\n version: \"unknown\",\n metadata: { runs: stateFiles.length },\n };\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const runs = this.runs(since);\n const sessions = runs.map(sessionFromRun);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n return sessions.slice(0, limit);\n }\n\n exportL5(since?: Date): L5ManifestModel {\n if (!isDir(this.storeDir)) {\n throw new ParticipantDiscoveryError(\n `Claude Desktop Co-Work store not found at ${this.storeDir}.`,\n );\n }\n const runs = this.runs(since);\n const sessions = runs.map(sessionFromRun);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n const entities = entitiesFromRuns(runs);\n const visibleEntities = filterForFederation(entities, this.policy);\n\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: hostname(),\n spec_version_compat: SPEC_VERSION,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: isoSeconds(),\n capabilities: capabilities(runs),\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: this.policy,\n });\n }\n\n healthCheck(): HealthStatus {\n if (!isDir(this.storeDir)) {\n return {\n status: \"blocked\",\n reason: `Claude Desktop Co-Work store not found at ${this.storeDir}.`,\n details: { store_dir: this.storeDir },\n proposedFix:\n \"Install the Claude desktop app and run a Co-Work / local-agent \" +\n \"session once. Set BOURDON_CLAUDE_DESKTOP_DIR if the app stores \" +\n \"state in a non-standard location.\",\n };\n }\n\n let stateFiles: string[];\n let runs: CoworkRun[];\n let malformed: number;\n try {\n stateFiles = iterStateFiles(this.storeDir);\n [runs, malformed] = this.collectRuns();\n } catch (exc) {\n logger.warn(`ClaudeDesktopCoworkParticipant health_check failed: ${String(exc)}`);\n return {\n status: \"degraded\",\n reason: \"Co-Work store present but extraction failed.\",\n details: { error: String(exc) },\n proposedFix:\n \"Close the Claude desktop app (its state files may be locked) and \" +\n \"re-run `bourdon claude-desktop-cowork export`.\",\n };\n }\n\n if (stateFiles.length === 0) {\n return {\n status: \"degraded\",\n reason: \"No Co-Work runs found under the store directory.\",\n details: { store_dir: this.storeDir },\n proposedFix:\n \"Run a Co-Work / local-agent session in the Claude desktop app, \" +\n \"then re-run `bourdon claude-desktop-cowork export`.\",\n };\n }\n\n return {\n status: \"ok\",\n details: {\n store_dir: this.storeDir,\n run_count: stateFiles.length,\n runs_extracted: runs.length,\n malformed_records: malformed,\n runs_with_scalars: runs.filter((r) => r.numTurns !== null).length,\n },\n };\n }\n\n // -- Internal ----------------------------------------------------------------\n\n private collectRuns(): [CoworkRun[], number] {\n const runs: CoworkRun[] = [];\n let malformed = 0;\n for (const statePath of iterStateFiles(this.storeDir)) {\n const state = loadStateJson(statePath);\n if (state === null) {\n malformed += 1;\n continue;\n }\n runs.push(runFromState(statePath, state));\n }\n return [runs, malformed];\n }\n\n private runs(since?: Date): CoworkRun[] {\n const [runs] = this.collectRuns();\n let filtered = runs;\n if (since !== undefined) {\n const cutoff = new Date(since.getTime()).toISOString().slice(0, 10);\n filtered = runs.filter((run) => !run.date || run.date >= cutoff);\n }\n filtered.sort((a, b) => {\n if (a.date !== b.date) return a.date < b.date ? 1 : -1;\n if (a.runId !== b.runId) return a.runId < b.runId ? 1 : -1;\n return 0;\n });\n return filtered;\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * GitHub Copilot · VS Code participant — reads the GUI Copilot Chat extension's\n * per-workspace transcripts + repo-scoped memory. Port of\n * `participants/copilot_vscode.py`.\n *\n * VS Code's Copilot Chat extension stores per-workspace data at\n * `<workspaceStorage>/<hash>/GitHub.copilot-chat/`:\n * - `transcripts/<session-uuid>.jsonl` — event stream per chat session\n * - `memory-tool/memories/**\\/*.md` — per-repo memory (markdown bullets)\n *\n * This is a FILE/CONVENTION reader (not SQLite, not network): it walks the\n * workspaceStorage tree read-only, parses JSONL transcripts + markdown memory\n * files, aggregates across every workspace hash, redacts every native string,\n * applies the visibility filter BEFORE emission, and is deterministic.\n * `healthCheck` never throws.\n *\n * Distinct from:\n * - `copilot` (convention-file at `~/.copilot-bourdon/memory.md`)\n * - `copilot-cli` (terminal agent, `~/.copilot/session-store.db`, SQLite)\n * - `github-copilot` (network reader — GitHub-embedded Copilot)\n */\n\nimport { readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { homedir, hostname, platform } from \"node:os\";\nimport { join, relative } from \"node:path\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\n\nconst AGENT_ID = \"copilot-vscode\";\nconst AGENT_TYPE = \"code-assistant\";\nconst DISPLAY_NAME = \"GitHub Copilot · VS Code\";\nconst ROLE_NARRATIVE =\n \"VS Code integrated Copilot Chat — the GUI surface for inline completion, \" +\n \"chat, plan mode, ask mode, and explore mode. Persists per-workspace \" +\n \"transcripts and repo-scoped memory locally. The most widely-used Copilot \" +\n \"surface by session count.\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"health\", \"family\", \"legal\"],\n team_tags: [\"copilot-vscode\", \"copilot\", \"vscode\", \"workspace\"],\n});\n\nconst COPILOT_CHAT_EXT = \"GitHub.copilot-chat\";\nconst TRANSCRIPTS_DIR = \"transcripts\";\nconst MEMORY_TOOL_DIR = \"memory-tool\";\nconst MAX_KEY_ACTIONS = 6;\nconst MAX_KEY_ACTION_CHARS = 280;\nconst MAX_SUMMARY_CHARS = 260;\nconst MAX_TRANSCRIPT_EVENTS = 500; // cap per file to avoid loading multi-MB transcripts fully\n\n// -- fs helpers ---------------------------------------------------------------\n\nfunction homeDir(): string {\n // os.homedir() can throw under some sandboxes; stay defensive so import +\n // construction never crash even when HOME points at an unreadable path.\n try {\n return homedir();\n } catch {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n }\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\n/** Redact secrets + clamp to the native-memory limit (`_safe_native_memory_text`). */\nfunction safeNativeMemoryText(value: string, limit = 180): string {\n return redactText(value, limit);\n}\n\n/**\n * Collapse whitespace and clamp with a single-char ellipsis (mirrors the\n * oracle's `_bounded`). Distinct from {@link redactText}'s `...` clamp — this\n * one uses `…` (U+2026) and does no redaction.\n */\nfunction bounded(value: string, limit: number): string {\n const normalized = value.split(/\\s+/).filter(Boolean).join(\" \");\n if (normalized.length <= limit) return normalized;\n return normalized.slice(0, limit - 1).replace(/\\s+$/, \"\") + \"…\";\n}\n\n/** Python `str.splitlines()` — split on \\r\\n, \\r, or \\n. */\nfunction splitLines(text: string): string[] {\n return text.split(/\\r\\n|\\r|\\n/);\n}\n\n// -- Path resolution ----------------------------------------------------------\n\n/**\n * Return the VS Code workspaceStorage path for this platform, or null when it\n * cannot be resolved (Windows without `%APPDATA%`). Respects the\n * `COPILOT_VSCODE_STORAGE` environment-variable override. Mirrors\n * `default_vscode_workspace_storage_dir`.\n */\nexport function defaultVscodeWorkspaceStorageDir(): string | null {\n const env = process.env.COPILOT_VSCODE_STORAGE;\n if (env) return env;\n\n // Map Node's os.platform() onto Python's platform.system().\n const system = platform();\n if (system === \"win32\") {\n const appdata = process.env.APPDATA;\n if (appdata) return join(appdata, \"Code\", \"User\", \"workspaceStorage\");\n return null;\n }\n if (system === \"darwin\") {\n return join(\n homeDir(),\n \"Library\",\n \"Application Support\",\n \"Code\",\n \"User\",\n \"workspaceStorage\",\n );\n }\n // Linux / WSL — check the Windows path under /mnt/c if WSL, else native.\n const wslPath = \"/mnt/c/Users\";\n if (isDir(wslPath)) {\n try {\n for (const candidate of readdirSync(wslPath)) {\n try {\n const ws = join(\n wslPath,\n candidate,\n \"AppData\",\n \"Roaming\",\n \"Code\",\n \"User\",\n \"workspaceStorage\",\n );\n if (isDir(ws)) return ws;\n } catch {\n continue;\n }\n }\n } catch {\n // fall through to native Linux\n }\n }\n const config = process.env.XDG_CONFIG_HOME || join(homeDir(), \".config\");\n return join(config, \"Code\", \"User\", \"workspaceStorage\");\n}\n\n/** Find all workspace hashes that contain Copilot Chat data. */\nfunction findCopilotChatDirs(workspaceStorage: string): string[] {\n if (!isDir(workspaceStorage)) return [];\n const dirs: string[] = [];\n try {\n for (const wsHash of readdirSync(workspaceStorage)) {\n const chatDir = join(workspaceStorage, wsHash, COPILOT_CHAT_EXT);\n if (isDir(chatDir)) dirs.push(chatDir);\n }\n } catch (exc) {\n logger.warn(`CopilotVscodeParticipant: cannot scan workspace storage: ${String(exc)}`);\n }\n return dirs;\n}\n\n/** Minimal logger so a scan warning is visible without a dep. */\nconst logger = {\n warn(msg: string): void {\n // eslint-disable-next-line no-console\n console.warn(`[bourdon.participants] ${msg}`);\n },\n};\n\n// -- Transcript parsing -------------------------------------------------------\n\ninterface TranscriptInfo {\n transcript_path: string;\n session_id: string;\n start_time: string | null;\n producer: unknown;\n copilot_version: unknown;\n vscode_version: unknown;\n user_messages: string[];\n turn_count: number;\n}\n\n/**\n * Parse a JSONL transcript file into a session summary. Returns null on any\n * read/empty error. Never raises.\n */\nfunction parseTranscript(path: string): TranscriptInfo | null {\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch {\n return null;\n }\n\n const lines = text.trim() ? splitLines(text.trim()) : [];\n if (lines.length === 0) return null;\n\n const info: TranscriptInfo = {\n transcript_path: path,\n session_id: stem(path),\n start_time: null,\n producer: null,\n copilot_version: null,\n vscode_version: null,\n user_messages: [],\n turn_count: 0,\n };\n\n let turnCount = 0;\n const userMsgs: string[] = [];\n\n for (const line of lines.slice(0, MAX_TRANSCRIPT_EVENTS)) {\n let event: unknown;\n try {\n event = JSON.parse(line);\n } catch {\n continue;\n }\n if (typeof event !== \"object\" || event === null) continue;\n const ev = event as Record<string, unknown>;\n const eventType = ev[\"type\"];\n const dataRaw = ev[\"data\"];\n const data =\n typeof dataRaw === \"object\" && dataRaw !== null\n ? (dataRaw as Record<string, unknown>)\n : {};\n\n if (eventType === \"session.start\") {\n info.start_time = data[\"startTime\"] == null ? null : String(data[\"startTime\"]);\n info.producer = data[\"producer\"] ?? null;\n info.copilot_version = data[\"copilotVersion\"] ?? null;\n info.vscode_version = data[\"vscodeVersion\"] ?? null;\n } else if (eventType === \"user.message\") {\n const content = data[\"content\"] ? String(data[\"content\"]) : \"\";\n if (content) {\n // Truncate long messages but keep enough for entity extraction.\n userMsgs.push(content.slice(0, 200));\n }\n } else if (eventType === \"assistant.turn_end\") {\n turnCount += 1;\n }\n }\n\n info.user_messages = userMsgs.slice(0, 20);\n info.turn_count = turnCount;\n return info;\n}\n\n/** Basename minus final extension (Python `Path.stem`). */\nfunction stem(p: string): string {\n const base = p.replace(/[\\\\/]+$/, \"\").split(/[\\\\/]/).pop() ?? \"\";\n return base.replace(/\\.[^.]+$/, \"\");\n}\n\n// -- Memory-tool parsing ------------------------------------------------------\n\ninterface MemoryFile {\n name: string;\n content: string;\n path: string;\n bullet_count: number;\n}\n\n/** Recursively collect `*.md` files under `dir`, sorted for determinism. */\nfunction walkMarkdown(dir: string): string[] {\n const out: string[] = [];\n let entries: string[];\n try {\n entries = readdirSync(dir).sort();\n } catch {\n return out;\n }\n for (const name of entries) {\n const full = join(dir, name);\n if (isDir(full)) {\n out.push(...walkMarkdown(full));\n } else if (name.endsWith(\".md\")) {\n out.push(full);\n }\n }\n return out;\n}\n\n/**\n * Parse memory-tool markdown files from a Copilot Chat workspace. Each file is a\n * bulleted list of learned facts. Returns a list of {name, content, path, ...}.\n */\nfunction parseMemoryFiles(chatDir: string): MemoryFile[] {\n const memoryDir = join(chatDir, MEMORY_TOOL_DIR, \"memories\");\n if (!isDir(memoryDir)) return [];\n\n const memories: MemoryFile[] = [];\n for (const mdFile of walkMarkdown(memoryDir)) {\n let text: string;\n try {\n text = readFileSync(mdFile, \"utf8\");\n } catch {\n continue;\n }\n if (!text.trim()) continue;\n // Name from relative path (e.g. \"repo/mobile-scaffold\"), suffix stripped,\n // backslashes normalized to forward slashes.\n const rel = relative(memoryDir, mdFile);\n const name = rel.replace(/\\.[^./\\\\]*$/, \"\").replace(/\\\\/g, \"/\");\n const bulletCount = text.split(\"\\n- \").length - 1 + (text.startsWith(\"- \") ? 1 : 0);\n memories.push({ name, content: text, path: mdFile, bullet_count: bulletCount });\n }\n return memories;\n}\n\n// -- Conversion to Bourdon types ----------------------------------------------\n\nfunction sessionFromTranscript(info: TranscriptInfo): SessionModel {\n const start = info.start_time ?? \"\";\n const dateStr = start ? start.slice(0, 10) : \"\";\n\n const keyActions: string[] = [];\n const msgs = info.user_messages ?? [];\n if (msgs.length > 0) {\n keyActions.push(bounded(safeNativeMemoryText(String(msgs[0])), MAX_KEY_ACTION_CHARS));\n }\n if (info.turn_count) keyActions.push(`turns: ${info.turn_count}`);\n if (info.copilot_version) keyActions.push(`copilot: ${String(info.copilot_version)}`);\n if (info.producer) keyActions.push(`mode: ${String(info.producer)}`);\n\n return makeSession({\n date: dateStr,\n cwd: undefined,\n project_focus: [],\n key_actions: keyActions.slice(0, MAX_KEY_ACTIONS),\n files_touched: [],\n visibility: Visibility.TEAM,\n });\n}\n\nfunction entitiesFromMemories(memories: MemoryFile[]): EntityModel[] {\n const entities: EntityModel[] = [];\n for (const mem of memories) {\n const bullets: string[] = [];\n for (const line of splitLines(mem.content)) {\n const stripped = line.trim();\n if (stripped.startsWith(\"- \")) {\n bullets.push(stripped.slice(2).trim());\n if (bullets.length === 3) break;\n }\n }\n let summary: string | undefined =\n bullets.length > 0 ? bullets.join(\"; \") : undefined;\n if (summary) summary = bounded(safeNativeMemoryText(summary), MAX_SUMMARY_CHARS);\n\n entities.push(\n makeEntity({\n name: mem.name,\n type: \"vscode-memory\",\n summary,\n last_touched: undefined,\n tags: [\"copilot-vscode\", \"memory-tool\", \"repo-memory\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n return entities;\n}\n\nfunction entitiesFromTranscripts(transcripts: TranscriptInfo[]): EntityModel[] {\n // Simple frequency-based extraction from first messages (insertion-ordered).\n const topicCounts = new Map<string, number>();\n for (const info of transcripts) {\n const msgs = info.user_messages ?? [];\n if (msgs.length > 0) {\n const first = String(msgs[0]).slice(0, 100);\n const slashMatch = /^\\/(\\S+)/.exec(first);\n if (slashMatch) {\n const topic = `copilot-command:${slashMatch[1]}`;\n topicCounts.set(topic, (topicCounts.get(topic) ?? 0) + 1);\n }\n }\n }\n\n // sorted(items, key=lambda x: -x[1])[:10] — stable, so ties keep insertion order.\n const ordered = [...topicCounts.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 10);\n\n const entities: EntityModel[] = [];\n for (const [topic, count] of ordered) {\n entities.push(\n makeEntity({\n name: topic,\n type: \"vscode-capability\",\n summary: `VS Code Copilot command used ${count} time(s).`,\n tags: [\"copilot-vscode\", \"capability\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n return entities;\n}\n\n// -- Participant --------------------------------------------------------------\n\n/**\n * External participant for GitHub Copilot in VS Code. Reads transcripts and\n * memory-tool files from VS Code's workspaceStorage read-only, aggregating\n * across all workspace hashes.\n */\nexport class CopilotVscodeParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n displayName = DISPLAY_NAME;\n\n private readonly workspaceStorage: string | null;\n\n /** The workspaceStorage dir the setup wizard probes for presence. */\n static defaultNativePath(home?: string): string {\n if (home !== undefined) {\n return join(home, \".config\", \"Code\", \"User\", \"workspaceStorage\");\n }\n let ws: string | null;\n try {\n ws = defaultVscodeWorkspaceStorageDir();\n } catch {\n ws = null;\n }\n if (ws !== null) return ws;\n return join(homeDir(), \".config\", \"Code\", \"User\", \"workspaceStorage\");\n }\n\n constructor(workspaceStorage?: string) {\n this.workspaceStorage = workspaceStorage ?? null;\n }\n\n get nativePath(): string {\n return this.workspaceStorage ?? defaultVscodeWorkspaceStorageDir() ?? \"\";\n }\n\n private resolveWs(): string | null {\n return this.workspaceStorage ?? defaultVscodeWorkspaceStorageDir();\n }\n\n // -- Protocol surface -------------------------------------------------------\n\n discover(): AgentStore {\n const ws = this.resolveWs();\n if (ws === null || !isDir(ws)) {\n throw new ParticipantDiscoveryError(\n `VS Code workspaceStorage not found at ${ws ?? \"None\"}. ` +\n \"Install VS Code with the GitHub Copilot Chat extension.\",\n );\n }\n const chatDirs = findCopilotChatDirs(ws);\n if (chatDirs.length === 0) {\n throw new ParticipantDiscoveryError(\n `No GitHub.copilot-chat data found under ${ws}. ` +\n \"Open VS Code and use Copilot Chat at least once.\",\n );\n }\n return {\n path: ws,\n version: \"transcript-v1\",\n metadata: {\n workspace_count: chatDirs.length,\n workspace_storage_path: ws,\n },\n };\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const sinceIso = since ? since.toISOString().slice(0, 10) : null;\n const transcripts = this.allTranscripts();\n const sessions: SessionModel[] = [];\n for (const info of transcripts) {\n const session = sessionFromTranscript(info);\n if (sinceIso && session.date && session.date < sinceIso) continue;\n sessions.push(session);\n if (sessions.length >= limit) break;\n }\n return sessions;\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const transcripts = this.allTranscripts();\n const memories = this.allMemories();\n\n const sinceIso = since ? since.toISOString().slice(0, 10) : null;\n const sessions: SessionModel[] = [];\n for (const info of transcripts) {\n const session = sessionFromTranscript(info);\n if (sinceIso && session.date && session.date < sinceIso) continue;\n sessions.push(session);\n }\n\n const entities = [\n ...entitiesFromMemories(memories),\n ...entitiesFromTranscripts(transcripts),\n ];\n const visibleEntities = filterForFederation(entities, DEFAULT_POLICY);\n\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: hostname() || \"unknown\",\n spec_version_compat: `>=${SPEC_VERSION}`,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: new Date().toISOString(),\n capabilities: [\n \"inline-completion\",\n \"chat\",\n \"plan-mode\",\n \"ask-mode\",\n \"explore-mode\",\n \"memory-tool\",\n \"workspace-scoped\",\n ],\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: DEFAULT_POLICY,\n });\n }\n\n healthCheck(): HealthStatus {\n try {\n const ws = this.resolveWs();\n if (ws === null || !isDir(ws)) {\n return {\n status: \"blocked\",\n reason: `VS Code workspaceStorage not found at ${ws ?? \"None\"}.`,\n details: { expected_path: ws ?? \"None\" },\n proposedFix:\n \"Install VS Code and the GitHub Copilot Chat extension. \" +\n \"Set COPILOT_VSCODE_STORAGE if VS Code stores data elsewhere.\",\n };\n }\n const chatDirs = findCopilotChatDirs(ws);\n if (chatDirs.length === 0) {\n return {\n status: \"degraded\",\n reason: \"No Copilot Chat data found in any workspace.\",\n details: { workspace_storage: ws },\n proposedFix:\n \"Open VS Code and start a Copilot Chat conversation, \" +\n \"then re-run `bourdon copilot-vscode export`.\",\n };\n }\n const transcripts = this.allTranscripts();\n const memories = this.allMemories();\n return {\n status: \"ok\",\n details: {\n workspace_storage: ws,\n workspace_count: chatDirs.length,\n transcript_count: transcripts.length,\n memory_file_count: memories.length,\n total_turns: transcripts.reduce((acc, t) => acc + (t.turn_count || 0), 0),\n },\n };\n } catch (err) {\n // healthCheck must NEVER raise (contract).\n return {\n status: \"degraded\",\n reason: `unexpected error: ${String(err)}`,\n details: {},\n };\n }\n }\n\n // -- Internal ---------------------------------------------------------------\n\n /** Collect and parse all transcripts across all workspaces. */\n private allTranscripts(): TranscriptInfo[] {\n const ws = this.resolveWs();\n if (ws === null) return [];\n const chatDirs = findCopilotChatDirs(ws);\n const transcripts: TranscriptInfo[] = [];\n for (const chatDir of chatDirs) {\n const transcriptDir = join(chatDir, TRANSCRIPTS_DIR);\n if (!isDir(transcriptDir)) continue;\n let files: string[];\n try {\n files = readdirSync(transcriptDir).sort();\n } catch {\n continue;\n }\n for (const fname of files) {\n if (!fname.endsWith(\".jsonl\")) continue;\n const info = parseTranscript(join(transcriptDir, fname));\n if (info !== null) transcripts.push(info);\n }\n }\n // Sort by start_time descending (missing → \"\").\n transcripts.sort((a, b) => {\n const av = a.start_time ?? \"\";\n const bv = b.start_time ?? \"\";\n return av < bv ? 1 : av > bv ? -1 : 0;\n });\n return transcripts;\n }\n\n /** Collect all memory-tool files across all workspaces. */\n private allMemories(): MemoryFile[] {\n const ws = this.resolveWs();\n if (ws === null) return [];\n const chatDirs = findCopilotChatDirs(ws);\n const memories: MemoryFile[] = [];\n for (const chatDir of chatDirs) {\n memories.push(...parseMemoryFiles(chatDir));\n }\n return memories;\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Codex session-index title lookup — narrow port of the three\n * `session_thread_titles` helpers in `participants/codex.py`.\n *\n * SCOPE (deliberately tiny): this is NOT the Codex participant/reader (the\n * ~2.6k-line turn-compiler still lands in a follow-on slice). It ports ONLY the\n * surface the tray/presence join needs — a `session_id -> human thread title`\n * map read from `~/.codex/session_index.jsonl`.\n *\n * Why only the index: `session_thread_titles()` runs on EVERY tray refresh, so\n * it must never touch rollout files. One small JSONL read, newest-first, done.\n * It covers Codex CLI sessions AND ChatGPT-app threads — the app's Work and\n * Codex modes share `~/.codex`, so `thread_name` is the human title for both.\n *\n * PRIVACY: titles are raw user text. Callers that EXPORT them MUST route them\n * through the audited redaction pipeline (`redactField` in\n * `mcp-server/src/agents-export.ts`, == Python's `_redact_field`), exactly like\n * every other emitted string. This module deliberately does NOT redact — the\n * redaction happens at the single audited egress point so it can't be\n * double-applied or silently skipped.\n *\n * Best-effort by construction: a missing dir, an unreadable file, or a corrupt\n * line degrades to fewer/no titles. Nothing here throws.\n */\n\nimport { readFileSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\n/** Default number of index records considered (newest-first). */\nexport const DEFAULT_TITLE_LIMIT = 200;\n\n/** Default number of threads on the tray codex card (newest-first). */\nexport const DEFAULT_RECENT_THREAD_LIMIT = 5;\n\n/** Collapse internal whitespace runs — mirrors Python `_normalize_text`. */\nfunction normalizeText(value: string): string {\n return value.trim().replace(/\\s+/g, \" \");\n}\n\nfunction isDir(path: string): boolean {\n try {\n return statSync(path).isDirectory();\n } catch {\n return false;\n }\n}\n\n/**\n * Locate `~/.codex/` (the primary Codex store), or null.\n *\n * Resolution order, mirroring `_resolve_codex_home()` exactly:\n * 1. `$CODEX_HOME` — **only if that directory already exists**\n * 2. `~/.codex` — only if it exists\n * 3. `null`\n *\n * ⚠ FOOTGUN (preserved for parity, do not \"fix\" without changing Python too):\n * step 1 is a silent fallback, not a pin. If `$CODEX_HOME` points at a path that\n * does not exist yet, the env var is IGNORED and this returns the developer's\n * REAL `~/.codex`. A sandbox/test that sets `CODEX_HOME` to a temp path without\n * `mkdir`-ing it first looks isolated but reads live data. Always create the\n * directory before setting the variable.\n */\nexport function resolveCodexHome(baseHome?: string | null): string | null {\n const env = process.env.CODEX_HOME;\n if (env) {\n // Existence check FIRST — see the footgun note above.\n if (isDir(env)) return env;\n }\n const home = baseHome ? baseHome : homedir();\n const candidate = join(home, \".codex\");\n return isDir(candidate) ? candidate : null;\n}\n\n/**\n * Read `session_index.jsonl`, newest-first by `updated_at`.\n *\n * Port of `_parse_session_index()`. Per-line JSON parse: a malformed line is\n * WARNED and SKIPPED — it never aborts the scan (one bad append must not blind\n * the tray to every other session). An unreadable file warns and yields `[]`.\n * Only records that are objects with a string `id` are kept.\n */\nexport function parseSessionIndex(\n path: string,\n limit?: number | null,\n): Record<string, unknown>[] {\n let text: string;\n try {\n if (!statSync(path).isFile()) return [];\n text = readFileSync(path, \"utf8\");\n } catch (exc) {\n // Covers both \"missing\" (Python's `is_file()` guard) and OSError-on-read.\n if (existsQuiet(path)) console.warn(`Failed to read ${path}: ${String(exc)}`);\n return [];\n }\n\n const entries: Record<string, unknown>[] = [];\n const lines = text.split(/\\r?\\n/);\n for (let i = 0; i < lines.length; i += 1) {\n const line = lines[i]!.trim();\n if (!line) continue;\n let record: unknown;\n try {\n record = JSON.parse(line);\n } catch (exc) {\n console.warn(`Skipping malformed JSONL in ${path}:${i + 1} -- ${String(exc)}`);\n continue;\n }\n if (\n record !== null &&\n typeof record === \"object\" &&\n !Array.isArray(record) &&\n typeof (record as Record<string, unknown>).id === \"string\"\n ) {\n entries.push(record as Record<string, unknown>);\n }\n }\n\n // Descending by `updated_at` (missing key sorts as \"\"), stable on ties —\n // mirrors Python's `sort(key=..., reverse=True)` on a stable sort.\n entries.sort((a, b) => {\n const ua = String(a.updated_at ?? \"\");\n const ub = String(b.updated_at ?? \"\");\n return ua < ub ? 1 : ua > ub ? -1 : 0;\n });\n return limit !== undefined && limit !== null ? entries.slice(0, limit) : entries;\n}\n\n/** True if the path exists at all (distinguishes \"missing\" from \"unreadable\"). */\nfunction existsQuiet(path: string): boolean {\n try {\n statSync(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Map full Codex session id → human thread title, newest-first.\n *\n * Port of `session_thread_titles()`. Reads ONLY `session_index.jsonl` — no\n * rollout I/O, because this runs on every tray refresh. A missing/malformed\n * index yields `{}`.\n *\n * NEWEST WINS: entries are already sorted newest-first and the insert is a\n * `setdefault` equivalent, so the freshest `thread_name` for a repeated id is\n * the one kept.\n *\n * Titles are RAW USER TEXT — see the module note; the exporter redacts.\n */\nexport function sessionThreadTitles(\n codexHome?: string | null,\n opts: { limit?: number } = {},\n): Record<string, string> {\n const limit = opts.limit ?? DEFAULT_TITLE_LIMIT;\n const home =\n codexHome === undefined || codexHome === null ? resolveCodexHome() : codexHome;\n if (home === null) return {};\n\n const titles: Record<string, string> = {};\n for (const entry of parseSessionIndex(join(home, \"session_index.jsonl\"), limit)) {\n const sid = entry.id;\n const name = entry.thread_name;\n if (\n typeof sid === \"string\" &&\n sid &&\n typeof name === \"string\" &&\n name.trim() &&\n !(sid in titles) // setdefault: first (== newest) wins\n ) {\n titles[sid] = normalizeText(name);\n }\n }\n return titles;\n}\n\n/** One row of the tray codex card. NOTE: `instance`, never a full session id. */\nexport interface RecentThread {\n instance: string;\n title: string | null;\n updated_at: string | null;\n}\n\n/**\n * Newest-first `[{instance, title, updated_at}]` for the tray codex card.\n *\n * Port of `recent_session_threads()`. Independent of PRESENCE: ChatGPT-app\n * threads fire no presence hooks, so this is the only way they surface.\n *\n * Emits only the 8-char `instance` prefix — parity with `presence.summarize`:\n * a full session id never leaves the local read path. Titles are RAW USER TEXT;\n * the exporter redacts them (see `sessionThreadTitles`).\n */\nexport function recentSessionThreads(\n codexHome?: string | null,\n opts: { limit?: number } = {},\n): RecentThread[] {\n const limit = opts.limit ?? DEFAULT_RECENT_THREAD_LIMIT;\n const home =\n codexHome === undefined || codexHome === null ? resolveCodexHome() : codexHome;\n if (home === null) return [];\n\n const threads: RecentThread[] = [];\n for (const entry of parseSessionIndex(join(home, \"session_index.jsonl\"), limit)) {\n const sid = entry.id;\n if (typeof sid !== \"string\" || !sid) continue;\n const name = entry.thread_name;\n const title =\n typeof name === \"string\" && name.trim() ? normalizeText(name) : null;\n const updated = String(entry.updated_at ?? \"\");\n threads.push({\n instance: sid.slice(0, 8),\n title,\n updated_at: updated || null,\n });\n }\n return threads;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * StackBlitz Bolt.new participant — port of `participants/bolt.py`.\n *\n * Bolt.new builds and runs full-stack apps in WebContainers, in the browser,\n * so nothing useful lands on the user's machine. It federates through an\n * export directory; see {@link ExportStoreParticipant} for the store layout\n * and the mechanics this shares with Lovable and v0.\n */\n\nimport {\n Visibility,\n makeEntity,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ExportStoreParticipant,\n isoDate,\n parseVisibility,\n safeStr,\n safeStrList,\n type ExportStoreConfig,\n} from \"../export-store-base.js\";\n\ntype Dict = Record<string, unknown>;\n\nexport const AGENT_ID = \"bolt\";\nexport const AGENT_TYPE = \"code-assistant\";\nexport const ROLE_NARRATIVE =\n \"StackBlitz Bolt.new in-browser AI development environment. Builds, executes, \" +\n \"and iterates full-stack applications in WebContainers from chat. Bourdon \" +\n \"reads exported project and session state so other agents recognize what \" +\n \"Bolt.new has developed.\";\n\nexport const DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"credential\", \"secret\", \"client-confidential\", \"private\"],\n team_tags: [\"bolt\", \"project\", \"webcontainer\", \"stackblitz\"],\n});\n\nconst MAX_SUMMARY_CHARS = 320;\nconst MAX_KEY_ACTION_CHARS = 300;\nconst NAME_LIMIT = 80;\n\n/**\n * One `projects.json` record to an Entity.\n *\n * Bolt caps the name at 80 characters, falls back to a generated summary when\n * the record has no description, and inserts its own tag only when absent —\n * all three differ from Lovable's mapper, deliberately. See the note in\n * export-store-base.ts.\n */\nexport function projectToEntity(record: Dict): EntityModel | null {\n const rawName = record.name;\n if (typeof rawName !== \"string\" || !rawName) return null;\n const name = safeStr(rawName, NAME_LIMIT);\n if (!name) return null;\n\n const summary = safeStr(record.description ?? \"\", MAX_SUMMARY_CHARS) || `Bolt.new project ${name}`;\n\n const tags = safeStrList(record.tags, 40);\n if (!tags.includes(\"bolt\")) tags.unshift(\"bolt\");\n\n const updated = isoDate(record.updated_at);\n const archived = Boolean(record.archived ?? false);\n\n return makeEntity({\n name,\n type: \"project\",\n summary,\n tags,\n last_touched: updated,\n valid_from: isoDate(record.created_at),\n valid_to: archived ? updated : null,\n visibility: parseVisibility(record.visibility),\n });\n}\n\n/** One `sessions/<id>.json` record to a Session, or null with no usable date. */\nexport function sessionToRecord(record: Dict, fallbackDate: string | null): SessionModel | null {\n const date = isoDate(record.date) ?? fallbackDate;\n if (!date) return null;\n const project = String(record.project ?? \"\").trim();\n return makeSession({\n date,\n cwd: null, // cloud agent: there is no local working directory to name\n project_focus: project ? [redactText(project, 120)] : [],\n key_actions: safeStrList(record.key_actions, MAX_KEY_ACTION_CHARS),\n files_touched: safeStrList(record.files_touched),\n visibility: parseVisibility(record.visibility),\n });\n}\n\nexport const BOLT_CONFIG: ExportStoreConfig = {\n agentId: AGENT_ID,\n agentType: AGENT_TYPE,\n displayName: \"Bolt.new\",\n directoryName: \".bolt\",\n stateEnvVar: \"BOLT_STATE_DIR\",\n roleNarrative: ROLE_NARRATIVE,\n capabilities: [\"in-browser-dev\", \"webcontainers\", \"full-stack-generation\"],\n policy: DEFAULT_POLICY,\n label: \"Bolt.new\",\n initCommand: \"bourdon bolt init\",\n projectToEntity,\n sessionToRecord,\n};\n\nexport class BoltParticipant extends ExportStoreParticipant {\n constructor(options: { stateDir?: string; env?: NodeJS.ProcessEnv } = {}) {\n super(BOLT_CONFIG, options);\n }\n\n static defaultNativePath(home?: string): string {\n return ExportStoreParticipant.defaultNativePath(\".bolt\", home);\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Shared mechanics for the \"JSON export store\" participant family.\n *\n * Bolt.new, Lovable and v0 are cloud builders that persist nothing useful on\n * the user's machine, so each federates through a directory the user exports\n * into:\n *\n * $<AGENT>_STATE_DIR/ (default: ~/.<agent>/)\n * projects.json array of project records, or {projects: [...]}\n * sessions/<id>.json one JSON document per session\n *\n * The oracle implements this three times (`participants/{bolt,lovable,v0}.py`,\n * ~1,130 lines). The store layout, the date parser, the visibility parser, the\n * loader's error semantics and the health-check ladder are identical across\n * all three, so they live here once.\n *\n * ⚠ What is NOT shared: each reader's `projectToEntity` / `sessionToRecord`.\n * They look similar and are not the same — Lovable caps a project name at 120\n * characters where Bolt caps at 80, emits a NULL summary where Bolt emits a\n * `\"Bolt.new project <name>\"` fallback, and appends its own tag\n * unconditionally where Bolt inserts only if absent (so Lovable really can\n * emit a duplicate tag). Those differences are the oracle's behaviour and the\n * mirror reproduces them rather than tidying them into agreement; each reader\n * supplies its own mapper.\n */\n\nimport { readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeManifest,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport { ParticipantDiscoveryError, ParticipantExportError, SPEC_VERSION, type AgentStore, type HealthStatus } from \"./base.js\";\n\ntype Dict = Record<string, unknown>;\n\nconst VISIBILITY_VALUES = new Set<string>(Object.values(Visibility) as string[]);\n\n/**\n * `_parse_visibility`: a recognized visibility string, else null (meaning\n * \"inherit the policy default\"), never a throw.\n */\nexport function parseVisibility(raw: unknown): Visibility | null {\n if (typeof raw !== \"string\") return null;\n const value = raw.trim().toLowerCase();\n return VISIBILITY_VALUES.has(value) ? (value as Visibility) : null;\n}\n\n/**\n * `_iso_date`: normalize to a bare `YYYY-MM-DD`, or null if unparseable.\n *\n * Accepts a full ISO timestamp (trailing `Z` included) and reduces it to its\n * date, which is what every L5 date field carries.\n */\nexport function isoDate(raw: unknown): string | null {\n if (typeof raw !== \"string\" || !raw.trim()) return null;\n const text = raw.trim();\n if (text.includes(\"T\")) {\n const parsed = new Date(text.replace(/Z$/, \"+00:00\"));\n if (Number.isNaN(parsed.getTime())) return null;\n return parsed.toISOString().slice(0, 10);\n }\n // Python's strptime(\"%Y-%m-%d\") rejects anything else, including a real\n // date in another format — matched here rather than letting Date() guess.\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(text)) return null;\n const parsed = new Date(`${text}T00:00:00Z`);\n if (Number.isNaN(parsed.getTime())) return null;\n // Rejects 2026-02-31, which the regex alone would accept.\n return parsed.toISOString().slice(0, 10) === text ? text : null;\n}\n\n/** `_safe_str`: trim, then route through the redaction SSOT. \"\" stays \"\". */\nexport function safeStr(raw: unknown, limit = 240): string {\n if (raw === null || raw === undefined) return \"\";\n const text = String(raw).trim();\n return text ? redactText(text, limit) : \"\";\n}\n\n/** `_str_list` in the Bolt/v0 spelling: redact every item, drop the empties. */\nexport function safeStrList(raw: unknown, limit = 200): string[] {\n if (!Array.isArray(raw)) return [];\n const out: string[] = [];\n for (const item of raw) {\n const cleaned = safeStr(item, limit);\n if (cleaned) out.push(cleaned);\n }\n return out;\n}\n\nexport interface ExportStoreConfig {\n agentId: string;\n agentType: string;\n displayName: string;\n /** Directory name under $HOME, e.g. `.bolt`. */\n directoryName: string;\n /** Environment variable that overrides the state directory. */\n stateEnvVar: string;\n roleNarrative: string;\n capabilities: string[];\n policy: VisibilityPolicyModel;\n /** Human label used in error and health text, e.g. \"Bolt.new\". */\n label: string;\n /** The `bourdon <x> init` verb named in remediation text. */\n initCommand: string;\n projectToEntity: (record: Dict) => EntityModel | null;\n sessionToRecord: (record: Dict, fallbackDate: string | null) => SessionModel | null;\n}\n\nexport class ExportStoreParticipant {\n readonly agentId: string;\n readonly agentType: string;\n readonly displayName: string;\n private readonly config: ExportStoreConfig;\n private readonly stateDir: string | undefined;\n private readonly env: NodeJS.ProcessEnv;\n\n constructor(config: ExportStoreConfig, options: { stateDir?: string; env?: NodeJS.ProcessEnv } = {}) {\n this.config = config;\n this.agentId = config.agentId;\n this.agentType = config.agentType;\n this.displayName = config.displayName;\n this.stateDir = options.stateDir;\n this.env = options.env ?? process.env;\n }\n\n static defaultNativePath(directoryName: string, home?: string): string {\n return join(home ?? homedir(), directoryName);\n }\n\n get nativePath(): string {\n return this.resolveStateDir();\n }\n\n private resolveStateDir(): string {\n if (this.stateDir !== undefined) return this.stateDir;\n const override = (this.env[this.config.stateEnvVar] ?? \"\").trim();\n if (override) return override;\n return ExportStoreParticipant.defaultNativePath(this.config.directoryName);\n }\n\n private requireStateDir(): string {\n const dir = this.resolveStateDir();\n if (!isDir(dir)) {\n throw new ParticipantDiscoveryError(\n `${this.config.label} state directory not found at '${dir}'.`,\n );\n }\n return dir;\n }\n\n /**\n * `projects.json`, accepting either a bare array or `{projects: [...]}`.\n *\n * A MISSING file is empty (the store may legitimately hold only sessions);\n * a PRESENT but unreadable or wrongly-shaped file throws. The distinction is\n * the point: absence is a state, corruption is an error.\n */\n private loadProjects(stateDir: string): Dict[] {\n const path = join(stateDir, \"projects.json\");\n if (!isFile(path)) return [];\n let payload: unknown;\n try {\n payload = JSON.parse(stripBom(readFileSync(path, \"utf-8\")));\n } catch (exc) {\n throw new ParticipantExportError(\n `${this.config.label} projects store present but unreadable at ${path}: ${\n exc instanceof Error ? exc.message : String(exc)\n }`,\n );\n }\n if (Array.isArray(payload)) return payload.filter(isDict);\n if (isDict(payload) && Array.isArray(payload.projects)) return payload.projects.filter(isDict);\n throw new ParticipantExportError(\n `${this.config.label} projects store at ${path} must be a JSON array or object with projects list.`,\n );\n }\n\n private sessionFiles(stateDir: string): string[] {\n const dir = join(stateDir, \"sessions\");\n if (!isDir(dir)) return [];\n return readdirSync(dir)\n .filter((f) => f.endsWith(\".json\"))\n .sort()\n .map((f) => join(dir, f));\n }\n\n /** Newest first. An unreadable session is skipped, never fatal. */\n private loadSessions(stateDir: string): SessionModel[] {\n const out: SessionModel[] = [];\n for (const path of this.sessionFiles(stateDir)) {\n let payload: unknown;\n try {\n payload = JSON.parse(stripBom(readFileSync(path, \"utf-8\")));\n } catch {\n continue;\n }\n if (!isDict(payload)) continue;\n const session = this.config.sessionToRecord(payload, null);\n if (session !== null) out.push(session);\n }\n out.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n return out;\n }\n\n discover(): AgentStore {\n const stateDir = this.resolveStateDir();\n if (!isDir(stateDir)) {\n throw new ParticipantDiscoveryError(\n `${this.config.label} state directory not found at '${stateDir}'. ` +\n `Create it and add a projects.json export or run \\`${this.config.initCommand}\\`.`,\n );\n }\n return {\n path: stateDir,\n version: \"export-v1\",\n metadata: {\n projects_file: isFile(join(stateDir, \"projects.json\")),\n session_files: this.sessionFiles(stateDir).length,\n env_override: Boolean((this.env[this.config.stateEnvVar] ?? \"\").trim()),\n },\n };\n }\n\n exportSessions(since: Date, limit = 100): SessionModel[] {\n const stateDir = this.requireStateDir();\n const sinceIso = since.toISOString().slice(0, 10);\n // `limit` is honoured, not decorative: a caller asking for 5 gets 5.\n return this.loadSessions(stateDir)\n .filter((s) => s.date >= sinceIso)\n .slice(0, limit);\n }\n\n exportL5(since?: Date | null): L5ManifestModel {\n const stateDir = this.requireStateDir();\n\n let sessions = this.loadSessions(stateDir);\n if (since !== undefined && since !== null) {\n const sinceIso = since.toISOString().slice(0, 10);\n sessions = sessions.filter((s) => s.date >= sinceIso);\n }\n\n const entities: EntityModel[] = [];\n const seen = new Set<string>();\n for (const record of this.loadProjects(stateDir)) {\n const entity = this.config.projectToEntity(record);\n if (entity === null) continue;\n const key = entity.name.toLowerCase();\n if (seen.has(key)) continue;\n seen.add(key);\n entities.push(entity);\n }\n\n // The PII guardrail, and it belongs HERE: L6 trusts whatever a participant\n // emits, so an entity that resolves to PRIVATE must never leave this\n // function. Filtering downstream would be too late.\n const visibleEntities = filterForFederation(entities, this.config.policy);\n\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: this.config.agentId,\n type: this.config.agentType,\n role_narrative: this.config.roleNarrative,\n spec_version_compat: SPEC_VERSION,\n }),\n last_updated: new Date().toISOString().replace(/\\.\\d{3}Z$/, \"+00:00\"),\n capabilities: [...this.config.capabilities],\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: this.config.policy,\n });\n }\n\n /** MUST NOT throw: the L6 server calls this in a polling loop. */\n healthCheck(): HealthStatus {\n try {\n const stateDir = this.resolveStateDir();\n if (!isDir(stateDir)) {\n return {\n status: \"blocked\",\n reason: `${this.config.label} state directory not found at '${stateDir}'.`,\n details: { expected: stateDir },\n proposedFix: `Run \\`${this.config.initCommand}\\` or create ${stateDir} and add projects.json.`,\n };\n }\n const projectsFile = join(stateDir, \"projects.json\");\n const sessionFiles = this.sessionFiles(stateDir);\n if (!isFile(projectsFile) && sessionFiles.length === 0) {\n return {\n status: \"degraded\",\n reason: \"State directory exists but contains no projects.json or sessions.\",\n details: { path: stateDir },\n proposedFix: `Run \\`${this.config.initCommand}\\` or export projects into projects.json.`,\n };\n }\n // Parse both, so a corrupt store reports degraded here instead of\n // throwing later inside a federation read.\n this.loadProjects(stateDir);\n this.loadSessions(stateDir);\n return {\n status: \"ok\",\n details: {\n path: stateDir,\n projects_file: isFile(projectsFile),\n session_files: sessionFiles.length,\n },\n };\n } catch (exc) {\n return {\n status: \"degraded\",\n reason: exc instanceof Error ? exc.message : String(exc),\n details: {},\n proposedFix: `Inspect ${this.resolveStateDirSafe()}/projects.json for syntax errors.`,\n };\n }\n }\n\n private resolveStateDirSafe(): string {\n try {\n return this.resolveStateDir();\n } catch {\n return `~/${this.config.directoryName}`;\n }\n }\n}\n\n// -- helpers ------------------------------------------------------------------\n\nfunction isDict(v: unknown): v is Dict {\n return v !== null && typeof v === \"object\" && !Array.isArray(v);\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\n/** Python reads these with `encoding=\"utf-8-sig\"`, so a BOM is not a parse error. */\nfunction stripBom(text: string): string {\n return text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Lovable participant — port of `participants/lovable.py`.\n *\n * Lovable builds full-stack web apps from chat in the cloud, so nothing useful\n * lands on the user's machine. It federates through an export directory; see\n * {@link ExportStoreParticipant} for the store layout and the mechanics this\n * shares with Bolt.new and v0.\n *\n * ⚠ The mapper below is NOT Bolt's with the names swapped, and must not be\n * refactored into it. Lovable's oracle differs in four ways, each reproduced\n * exactly here:\n *\n * 1. the project name is capped at 120 characters, not 80;\n * 2. a record with no description yields a NULL summary, where Bolt\n * synthesizes `\"Bolt.new project <name>\"`;\n * 3. the `\"lovable\"` tag is APPENDED unconditionally, so a record that\n * already carries it ends up with it twice — Bolt inserts only if absent;\n * 4. `updated_at` falls back to `created_at`, where Bolt leaves\n * `last_touched` null.\n *\n * (3) also means the tag lands LAST rather than first. None of this is\n * defensible design; all of it is what the oracle does, and the mirror's job\n * is to agree with the oracle, not to improve on it. Fixing any of it is an\n * oracle-side change the conformance fixtures would have to absorb first.\n */\n\nimport {\n Visibility,\n makeEntity,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ExportStoreParticipant,\n isoDate,\n parseVisibility,\n safeStrList,\n type ExportStoreConfig,\n} from \"../export-store-base.js\";\n\ntype Dict = Record<string, unknown>;\n\nexport const AGENT_ID = \"lovable\";\nexport const AGENT_TYPE = \"code-assistant\";\nexport const ROLE_NARRATIVE =\n \"Cloud app-building agent. Designs, builds, and iterates full-stack web \" +\n \"applications from chat. Bourdon reads exported project and session state \" +\n \"so other agents recognize what Lovable has built.\";\n\nexport const DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"credential\", \"secret\", \"client-confidential\"],\n team_tags: [\"lovable\", \"project\", \"client\"],\n});\n\nconst MAX_SUMMARY_CHARS = 320;\nconst MAX_KEY_ACTION_CHARS = 300;\nconst NAME_LIMIT = 120;\n\n/** One `projects.json` record to an Entity. See the four notes in the header. */\nexport function projectToEntity(record: Dict): EntityModel | null {\n const name = String(record.name ?? \"\").trim();\n if (!name) return null;\n\n const summary = record.description;\n // (2) absent description -> null, not a synthesized sentence.\n const summaryText =\n summary === null || summary === undefined || summary === \"\"\n ? null\n : redactText(String(summary), MAX_SUMMARY_CHARS);\n\n // (3) unconditional append: a record already tagged \"lovable\" gets it twice.\n const tags = safeStrList(record.tags);\n tags.push(\"lovable\");\n\n const archived = Boolean(record.archived);\n // (4) updated_at falls back to created_at.\n const updated = isoDate(record.updated_at) ?? isoDate(record.created_at);\n\n return makeEntity({\n name: redactText(name, NAME_LIMIT), // (1) 120, not 80\n type: \"project\",\n summary: summaryText,\n tags,\n last_touched: updated,\n valid_from: isoDate(record.created_at),\n valid_to: archived ? updated : null,\n visibility: parseVisibility(record.visibility),\n });\n}\n\n/** One `sessions/<id>.json` record to a Session, or null with no usable date. */\nexport function sessionToRecord(record: Dict, fallbackDate: string | null): SessionModel | null {\n const date = isoDate(record.date) ?? fallbackDate;\n if (!date) return null;\n const project = String(record.project ?? \"\").trim();\n return makeSession({\n date,\n cwd: null, // cloud agent: there is no local working directory to name\n project_focus: project ? [redactText(project, 120)] : [],\n key_actions: safeStrList(record.key_actions, MAX_KEY_ACTION_CHARS),\n // ⚠ No limit, so these are NOT redacted — the oracle's behaviour. Bolt and\n // v0 redact the same field. Flagged, not silently corrected.\n files_touched: safeStrList(record.files_touched),\n visibility: parseVisibility(record.visibility),\n });\n}\n\nexport const LOVABLE_CONFIG: ExportStoreConfig = {\n agentId: AGENT_ID,\n agentType: AGENT_TYPE,\n displayName: \"Lovable\",\n directoryName: \".lovable\",\n stateEnvVar: \"LOVABLE_STATE_DIR\",\n roleNarrative: ROLE_NARRATIVE,\n capabilities: [\"app-building\", \"full-stack-generation\", \"deploy-preview\"],\n policy: DEFAULT_POLICY,\n label: \"Lovable\",\n initCommand: \"bourdon lovable init\",\n projectToEntity,\n sessionToRecord,\n};\n\nexport class LovableParticipant extends ExportStoreParticipant {\n constructor(options: { stateDir?: string; env?: NodeJS.ProcessEnv } = {}) {\n super(LOVABLE_CONFIG, options);\n }\n\n static defaultNativePath(home?: string): string {\n return ExportStoreParticipant.defaultNativePath(\".lovable\", home);\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Vercel v0 participant — port of `participants/v0.py`.\n *\n * v0 generates React / Next.js / Tailwind UI and full-stack web apps from\n * chat, entirely server-side, so nothing useful lands on the user's machine.\n * It federates through an export directory; see {@link ExportStoreParticipant}\n * for the store layout and the mechanics this shares with Bolt.new and\n * Lovable. The mapper below is byte-for-byte Bolt's rule with v0's own name\n * and tag — that is the oracle's shape, not a shortcut taken here.\n */\n\nimport {\n Visibility,\n makeEntity,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ExportStoreParticipant,\n isoDate,\n parseVisibility,\n safeStr,\n safeStrList,\n type ExportStoreConfig,\n} from \"../export-store-base.js\";\n\ntype Dict = Record<string, unknown>;\n\nexport const AGENT_ID = \"v0\";\nexport const AGENT_TYPE = \"code-assistant\";\nexport const ROLE_NARRATIVE =\n \"Vercel v0 generative UI and full-stack web builder. Designs and iterates \" +\n \"React, Next.js, and Tailwind components and web applications from chat. \" +\n \"Bourdon reads exported project and session state so other agents recognize \" +\n \"what v0 has designed and constructed.\";\n\nexport const DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"credential\", \"secret\", \"client-confidential\", \"private\"],\n team_tags: [\"v0\", \"project\", \"client\", \"ui\", \"component\"],\n});\n\nconst MAX_SUMMARY_CHARS = 320;\nconst MAX_KEY_ACTION_CHARS = 300;\nconst NAME_LIMIT = 80;\n\n/**\n * One `projects.json` record to an Entity.\n *\n * Caps the name at 80 characters, falls back to a generated summary when the\n * record has no description, and inserts its own tag only when absent. All\n * three differ from Lovable's mapper, deliberately. See the note in\n * export-store-base.ts.\n */\nexport function projectToEntity(record: Dict): EntityModel | null {\n const rawName = record.name;\n if (typeof rawName !== \"string\" || !rawName) return null;\n const name = safeStr(rawName, NAME_LIMIT);\n if (!name) return null;\n\n const summary = safeStr(record.description ?? \"\", MAX_SUMMARY_CHARS) || `v0 project ${name}`;\n\n const tags = safeStrList(record.tags, 40);\n if (!tags.includes(\"v0\")) tags.unshift(\"v0\");\n\n const updated = isoDate(record.updated_at);\n const archived = Boolean(record.archived ?? false);\n\n return makeEntity({\n name,\n type: \"project\",\n summary,\n tags,\n last_touched: updated,\n valid_from: isoDate(record.created_at),\n valid_to: archived ? updated : null,\n visibility: parseVisibility(record.visibility),\n });\n}\n\n/** One `sessions/<id>.json` record to a Session, or null with no usable date. */\nexport function sessionToRecord(record: Dict, fallbackDate: string | null): SessionModel | null {\n const date = isoDate(record.date) ?? fallbackDate;\n if (!date) return null;\n const project = String(record.project ?? \"\").trim();\n return makeSession({\n date,\n cwd: null, // cloud agent: there is no local working directory to name\n project_focus: project ? [redactText(project, 120)] : [],\n key_actions: safeStrList(record.key_actions, MAX_KEY_ACTION_CHARS),\n files_touched: safeStrList(record.files_touched),\n visibility: parseVisibility(record.visibility),\n });\n}\n\nexport const V0_CONFIG: ExportStoreConfig = {\n agentId: AGENT_ID,\n agentType: AGENT_TYPE,\n displayName: \"Vercel v0\",\n directoryName: \".v0\",\n stateEnvVar: \"V0_STATE_DIR\",\n roleNarrative: ROLE_NARRATIVE,\n capabilities: [\"generative-ui\", \"full-stack-web\", \"react-nextjs\"],\n policy: DEFAULT_POLICY,\n label: \"v0\",\n initCommand: \"bourdon v0 init\",\n projectToEntity,\n sessionToRecord,\n};\n\nexport class V0Participant extends ExportStoreParticipant {\n constructor(options: { stateDir?: string; env?: NodeJS.ProcessEnv } = {}) {\n super(V0_CONFIG, options);\n }\n\n static defaultNativePath(home?: string): string {\n return ExportStoreParticipant.defaultNativePath(\".v0\", home);\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Participant discovery — a STATIC TS registry replacing Python's `pkgutil`\n * package scan + entry-point duck-type (`participants/__init__.py`).\n *\n * Python scans the `participants/` package at runtime and duck-types each class\n * by `_PARTICIPANT_MARKER_ATTRS`. A filesystem package scan does not survive\n * bundling (`npx bourdon` is a single file), so the JS side declares an explicit\n * {@link FIRST_PARTY} array. The three preserved invariants:\n * - output sorted by `agentId`\n * - first-wins dedupe on `agentId`\n * - log-and-skip a participant that throws on construction (one broken reader\n * must NOT abort discovery / crash the CLI)\n *\n * The marker-attr duck-typing collapses into the {@link BourdonParticipant}\n * interface conformance (checked structurally via {@link isParticipant}).\n */\n\nimport { isParticipant, type BourdonParticipant } from \"./base.js\";\nimport { BoltParticipant } from \"./readers/bolt.js\";\nimport { CascadeParticipant } from \"./readers/cascade.js\";\nimport { ClaudeCodeParticipant } from \"./readers/claude-code.js\";\nimport { ClaudeCodeAutomationsParticipant } from \"./readers/claude-code-automations.js\";\nimport { ClaudeDesktopCodeParticipant } from \"./readers/claude-desktop-code.js\";\nimport { ClaudeDesktopCoworkParticipant } from \"./readers/claude-desktop-cowork.js\";\nimport { CodexAutomationsParticipant } from \"./readers/codex-automations.js\";\nimport { CopilotParticipant } from \"./readers/copilot.js\";\nimport { CopilotAutomationsParticipant } from \"./readers/copilot-automations.js\";\nimport { CopilotCliParticipant } from \"./readers/copilot-cli.js\";\nimport { CopilotVscodeParticipant } from \"./readers/copilot-vscode.js\";\nimport { CursorParticipant } from \"./readers/cursor.js\";\nimport { CursorAutomationsParticipant } from \"./readers/cursor-automations.js\";\nimport { LovableParticipant } from \"./readers/lovable.js\";\nimport { V0Participant } from \"./readers/v0.js\";\nimport { GitHubCopilotParticipant } from \"./readers/github-copilot.js\";\nimport { HermesParticipant } from \"./readers/hermes.js\";\nimport { OpenClawParticipant } from \"./readers/openclaw.js\";\n\n/** A zero-arg-constructible participant class. */\nexport type ParticipantCtor = new () => BourdonParticipant;\n\n/**\n * The first-party reader registry. Order here is irrelevant — discovery sorts by\n * `agentId`. Covers the base agents, their background-run \"automations\" variants,\n * the Claude-desktop surfaces, and the quarantined-class openclaw network reader.\n * codex — the ~2.6k-line turn-compiler reader — is the only one still deferred.\n */\nexport const FIRST_PARTY: ParticipantCtor[] = [\n BoltParticipant as unknown as ParticipantCtor,\n CascadeParticipant as unknown as ParticipantCtor,\n ClaudeCodeParticipant as unknown as ParticipantCtor,\n ClaudeCodeAutomationsParticipant as unknown as ParticipantCtor,\n ClaudeDesktopCodeParticipant as unknown as ParticipantCtor,\n ClaudeDesktopCoworkParticipant as unknown as ParticipantCtor,\n CodexAutomationsParticipant as unknown as ParticipantCtor,\n CopilotParticipant as unknown as ParticipantCtor,\n CopilotAutomationsParticipant as unknown as ParticipantCtor,\n CopilotCliParticipant as unknown as ParticipantCtor,\n CopilotVscodeParticipant as unknown as ParticipantCtor,\n CursorParticipant as unknown as ParticipantCtor,\n CursorAutomationsParticipant as unknown as ParticipantCtor,\n LovableParticipant as unknown as ParticipantCtor,\n V0Participant as unknown as ParticipantCtor,\n GitHubCopilotParticipant as unknown as ParticipantCtor,\n HermesParticipant as unknown as ParticipantCtor,\n OpenClawParticipant as unknown as ParticipantCtor,\n];\n\n/** Minimal logger so a skipped participant is visible without a dep. */\nconst logger = {\n warn(msg: string): void {\n // eslint-disable-next-line no-console\n console.warn(`[bourdon.participants] ${msg}`);\n },\n};\n\n/**\n * Instantiate each registered participant, duck-type the contract, sort by\n * `agentId`, and first-wins dedupe. A class that throws on construction is\n * logged and skipped — never propagated.\n */\nexport function discoverParticipants(\n ctors: ParticipantCtor[] = FIRST_PARTY,\n): BourdonParticipant[] {\n const found = new Map<string, BourdonParticipant>();\n for (const Ctor of [...ctors, ...resolvePluginParticipants()]) {\n let instance: BourdonParticipant;\n try {\n instance = new Ctor();\n } catch (err) {\n logger.warn(\n `Skipping participant ${Ctor.name || \"<anonymous>\"}: construction failed: ${String(err)}`,\n );\n continue;\n }\n if (!isParticipant(instance)) continue;\n if (!found.has(instance.agentId)) found.set(instance.agentId, instance);\n }\n return [...found.values()].sort((a, b) =>\n a.agentId < b.agentId ? -1 : a.agentId > b.agentId ? 1 : 0,\n );\n}\n\n/**\n * Optional Layer 2: third-party plugins declared via a `package.json`\n * `\"bourdon\": { participants: { ... } }` field. Gated behind `BOURDON_PLUGINS=1`\n * and a no-op today (no external participant exists yet) — the resolver ships so\n * the seam is wired, defaulted off so `npx bourdon` stays predictable.\n */\nexport function resolvePluginParticipants(): ParticipantCtor[] {\n if (process.env.BOURDON_PLUGINS !== \"1\") return [];\n // No external participant package exists yet; the resolver is intentionally a\n // no-op stub. When one ships, resolve its declared ctors here.\n return [];\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,iBAAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACqBO,IAAM,mBAAmB;AACzB,IAAM,eAAe;AAKrB,IAAM,mBAAN,cAA+B,MAAM;AAAA,EAC1C,YAAY,SAAkB;AAC5B,UAAM,OAAO;AACb,SAAK,OAAO,WAAW;AAAA,EACzB;AACF;AAIO,IAAM,4BAAN,cAAwC,iBAAiB;AAAC;AAI1D,IAAM,yBAAN,cAAqC,iBAAiB;AAAC;AAIvD,IAAM,kCAAN,cAA8C,0BAA0B;AAAC;AAkEzE,SAAS,cAAc,KAAyC;AACrE,MAAI,QAAQ,QAAQ,OAAO,QAAQ,SAAU,QAAO;AACpD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,SAAS,MAAM,YACxB,OAAO,EAAE,WAAW,MAAM,YAC1B,OAAO,EAAE,UAAU,MAAM,cACzB,OAAO,EAAE,aAAa,MAAM;AAEhC;AAOO,IAAM,oBAAoB;AAgB1B,SAAS,iBACd,WAA8B,CAAC,GACZ;AACnB,QAAM,QAAkB,CAAC;AACzB,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,MAAM,QAAQ,IAAI,iBAAiB,KAAK;AAC9C,aAAW,aAAa,CAAC,GAAG,UAAU,GAAG,IAAI,MAAM,GAAG,CAAC,GAAG;AACxD,UAAM,OAAO,UAAU,KAAK;AAC5B,QAAI,CAAC,KAAM;AACX,UAAM,MAAM,KAAK,YAAY;AAC7B,QAAI,KAAK,IAAI,GAAG,EAAG;AACnB,SAAK,IAAI,GAAG;AACZ,UAAM,KAAK,IAAI;AAAA,EACjB;AACA,SAAO;AACT;;;AC3IA,qBAAyB;AACzB,yBAA8B;AAnB9B;AA8BA,IAAM,YACH,OAAO,gBAAgB,eAAe,YAAY,QAClD,OAAO,eAAe,cAAc,aAAa,QAAQ,IAAI;AAChE,IAAM,kBAAc,kCAAc,SAAS;AAE3C,IAAI;AACJ,IAAI;AAIJ,SAAS,aAAsC;AAC7C,MAAI,WAAW,OAAW,QAAO;AACjC,MAAI;AACF,aAAS,YAAY,gBAAgB;AAAA,EACvC,QAAQ;AACN,aAAS;AAAA,EACX;AACA,SAAO;AACT;AAGO,SAAS,kBAA2B;AACzC,MAAI,oBAAoB,OAAW,QAAO;AAC1C,QAAM,OAAO,WAAW;AACxB,MAAI,CAAC,KAAM,QAAQ,kBAAkB;AACrC,MAAI;AACF,UAAM,QAAQ,IAAI,KAAK,UAAU;AACjC,UAAM,MAAM;AACZ,sBAAkB;AAAA,EACpB,QAAQ;AACN,sBAAkB;AAAA,EACpB;AACA,SAAO;AACT;AAmBO,SAAS,aAAa,QAAgB,OAA4B,CAAC,GAAmB;AAC3F,QAAM,OAAO,WAAW;AACxB,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AAIA,SAAO,IAAI,KAAK,QAAQ;AAAA,IACtB,UAAU;AAAA,IACV,eAAe;AAAA,IACf,SAAS,KAAK,aAAa;AAAA,EAC7B,CAAC;AACH;AAMO,SAAS,gBACd,QACA,OAA4B,CAAC,GACN;AACvB,MAAI;AACF,QAAI,KAAC,yBAAS,MAAM,EAAE,OAAO,EAAG,QAAO;AAAA,EACzC,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI;AACF,WAAO,aAAa,QAAQ,IAAI;AAAA,EAClC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKO,SAAS,YAAY,IAAoB,MAAuB;AACrE,MAAI;AACF,UAAM,MAAM,GACT,QAAQ,mEAAmE,EAC3E,IAAI,IAAI;AACX,WAAO,QAAQ;AAAA,EACjB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAIO,SAAS,aAAa,IAAoB,OAA4B;AAC3E,MAAI;AACF,UAAM,OAAO,GAAG,QAAQ,qBAAqB,KAAK,GAAG,EAAE,IAAI;AAC3D,WAAO,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAAA,EACxC,QAAQ;AACN,WAAO,oBAAI,IAAY;AAAA,EACzB;AACF;AAIA,SAAS,eAAe,OAA+B;AACrD,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,QAAM,IAAI,OAAO,UAAU,WAAW,QAAQ,OAAO,KAAK;AAC1D,SAAO,OAAO,SAAS,CAAC,IAAI,IAAI;AAClC;AAMO,SAAS,eAAe,OAA+B;AAC5D,QAAM,IAAI,eAAe,KAAK;AAC9B,MAAI,MAAM,KAAM,QAAO;AACvB,QAAM,IAAI,IAAI,KAAK,IAAI,GAAI;AAC3B,MAAI,OAAO,MAAM,EAAE,QAAQ,CAAC,EAAG,QAAO;AACtC,SAAO,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AACpC;AAMO,SAAS,mBAAmB,OAA+B;AAChE,QAAM,IAAI,eAAe,KAAK;AAC9B,MAAI,MAAM,KAAM,QAAO;AACvB,QAAM,IAAI,IAAI,KAAK,IAAI,GAAI;AAC3B,MAAI,OAAO,MAAM,EAAE,QAAQ,CAAC,EAAG,QAAO;AACtC,SAAO,EACJ,YAAY,EACZ,QAAQ,aAAa,QAAQ,EAC7B,QAAQ,MAAM,QAAQ;AAC3B;AAEA,SAAS,WAAW,GAAmB;AACrC,QAAM,UAAU,EAAE,QAAQ,WAAW,EAAE;AACvC,QAAM,QAAQ,QAAQ,MAAM,OAAO;AACnC,SAAO,MAAM,MAAM,SAAS,CAAC,KAAK;AACpC;AAOO,SAAS,kBACd,KACA,eAAoC,oBAAI,IAAI,GAC7B;AACf,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,OAAO,WAAW,GAAG,EAAE,KAAK,EAAE,YAAY;AAChD,MAAI,CAAC,QAAQ,aAAa,IAAI,IAAI,EAAG,QAAO;AAC5C,SAAO;AACT;AAGO,SAAS,cAAc,KAAqB;AACjD,SAAO,IACJ,QAAQ,UAAU,GAAG,EACrB,KAAK,EACL,QAAQ,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,EAAE,MAAM,CAAC,EAAE,YAAY,CAAC;AAChF;;;ACxLA,IAAAC,kBAAmE;AACnE,qBAAwB;AACxB,uBAAqB;AAWd,IAAM,2BAA2B;AAEjC,IAAM,4BAA4B,KAAK;AAKvC,IAAM,qBAAN,cAAiC,iBAAiB;AAAC;AAKnD,IAAM,uBAAN,cAAmC,iBAAiB;AAAC;AAUrD,SAAS,gBAAgB,SAA+B;AAC7D,SAAO,MAAM,QAAQ,IAAI,OAAO,KAAK;AACvC;AAKO,SAAS,mBAA2B;AACzC,QAAM,MAAM,QAAQ,IAAI;AACxB,QAAM,OAAO,MAAM,UAAM,2BAAK,wBAAQ,GAAG,QAAQ;AACjD,aAAO,uBAAK,MAAM,SAAS;AAC7B;AAGO,IAAM,aAAN,MAAiB;AAAA,EACtB,YACW,WACA,SACT;AAFS;AACA;AAAA,EACR;AAAA,EAFQ;AAAA,EACA;AAAA,EAGX,IAAI,aAAqB;AACvB,WAAO,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,MAAO,KAAK,SAAS;AAAA,EACvD;AAAA,EAEA,QAAQ,YAA6B;AACnC,WAAO,KAAK,aAAa;AAAA,EAC3B;AACF;AAOO,IAAM,eAAN,MAAmB;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,MAAc,SAAkB;AAC1C,SAAK,OAAO;AACZ,SAAK,WAAO,uBAAK,WAAW,iBAAiB,GAAG,IAAI;AACpD,SAAK,WAAO,uBAAK,KAAK,MAAM,cAAc;AAAA,EAC5C;AAAA,EAEA,OAA0B;AACxB,QAAI;AACJ,QAAI;AACF,YAAM,KAAK,UAAM,8BAAa,KAAK,MAAM,MAAM,CAAC;AAAA,IAClD,QAAQ;AACN,aAAO;AAAA,IACT;AACA,QAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,EAAE,aAAa,KAAM,QAAO;AAC3E,UAAM,MAAM;AACZ,QAAI,YAAY,OAAO,IAAI,YAAY,KAAK,CAAC;AAC7C,QAAI,CAAC,OAAO,SAAS,SAAS,EAAG,aAAY;AAC7C,UAAM,UAAU,IAAI,SAAS;AAC7B,QAAI,OAAO,YAAY,YAAY,YAAY,QAAQ,MAAM,QAAQ,OAAO,EAAG,QAAO;AACtF,WAAO,IAAI,WAAW,WAAW,OAAkC;AAAA,EACrE;AAAA,EAEA,MAAM,SAAwC;AAC5C,QAAI;AACF,qCAAU,KAAK,MAAM,EAAE,WAAW,KAAK,CAAC;AACxC,YAAM,MAAM,GAAG,KAAK,IAAI;AACxB,yCAAc,KAAK,KAAK,UAAU,EAAE,YAAY,KAAK,IAAI,IAAI,KAAM,QAAQ,CAAC,GAAG,MAAM;AACrF,sCAAW,KAAK,KAAK,IAAI;AAAA,IAC3B,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAeO,IAAe,qBAAf,MAAgE;AAAA,EACrE,kBAAkB;AAAA,EAClB,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,kBAA0B;AAAA,EAC1B,aAAa;AAAA,EAEM;AAAA,EACF;AAAA,EACT;AAAA,EAER,YAAY,OAAkC,CAAC,GAAG;AAChD,SAAK,eAAe,KAAK,gBAAgB;AACzC,SAAK,YAAY,KAAK;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAc,QAAsB;AAClC,QAAI,CAAC,KAAK,eAAe;AACvB,WAAK,gBAAgB,IAAI,aAAa,KAAK,iBAAiB,KAAK,SAAS;AAAA,IAC5E;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBU,aAAmE;AAC3E,UAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,QAAI,WAAW,QAAQ,OAAO,QAAQ,KAAK,eAAe,GAAG;AAC3D,aAAO,EAAE,SAAS,OAAO,SAAS,QAAQ,QAAQ;AAAA,IACpD;AAEA,UAAM,QAAQ,KAAK,eAAe,KAAK,aAAa,IAAI;AACxD,QAAI,CAAC,OAAO;AAEV,UAAI,WAAW,KAAM,QAAO,EAAE,SAAS,OAAO,SAAS,QAAQ,cAAc;AAC7E,YAAM,IAAI;AAAA,QACR,GAAG,KAAK,eAAe;AAAA,MACzB;AAAA,IACF;AAEA,QAAI;AACJ,QAAI;AACF,gBAAU,KAAK,aAAa,KAAK;AAAA,IACnC,SAAS,KAAK;AACZ,UAAI,eAAe,qBAAsB,OAAM;AAC/C,UAAI,eAAe,oBAAoB;AACrC,YAAI,WAAW,KAAM,QAAO,EAAE,SAAS,OAAO,SAAS,QAAQ,cAAc;AAC7E,cAAM;AAAA,MACR;AACA,YAAM;AAAA,IACR;AAEA,SAAK,MAAM,MAAM,OAAO;AACxB,WAAO,EAAE,SAAS,QAAQ,UAAU;AAAA,EACtC;AAAA;AAAA,EAIA,WAAuB;AACrB,UAAM,EAAE,OAAO,IAAI,KAAK,WAAW;AACnC,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,SAAS,GAAG,KAAK,eAAe;AAAA,MAChC,UAAU,EAAE,QAAQ,kBAAkB,yBAAyB;AAAA,IACjE;AAAA,EACF;AAAA,EAEA,SAAS,QAAgC;AACvC,UAAM,EAAE,QAAQ,IAAI,KAAK,WAAW;AACpC,WAAO,KAAK,YAAY,OAAO;AAAA,EACjC;AAAA,EAEA,eAAe,OAAc,QAAQ,KAAqB;AACxD,UAAM,WAAW,KAAK,SAAS,KAAK;AACpC,QAAI,WAAW,SAAS,mBAAmB,CAAC;AAC5C,QAAI,OAAO;AACT,YAAM,SAAS,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE;AAC9C,iBAAW,SAAS,OAAO,CAAC,OAAO,EAAE,QAAQ,OAAO,MAAM;AAAA,IAC5D;AACA,WAAO,SAAS,MAAM,GAAG,KAAK;AAAA,EAChC;AAAA,EAEA,cAA4B;AAC1B,QAAI;AACJ,QAAI;AACF,eAAS,KAAK,WAAW,EAAE;AAAA,IAC7B,SAAS,KAAK;AACZ,UAAI,eAAe,sBAAsB;AACvC,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,QAAQ,OAAO,IAAI,OAAO;AAAA,UAC1B,SAAS,EAAE,aAAa,KAAK,gBAAgB;AAAA,UAC7C,aACE,kCAAkC,KAAK,eAAe;AAAA,QAE1D;AAAA,MACF;AACA,UAAI,eAAe,oBAAoB;AACrC,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,QAAQ,qCAAqC,IAAI,OAAO;AAAA,UACxD,SAAS,EAAE,aAAa,KAAK,gBAAgB;AAAA,UAC7C,aAAa;AAAA,QACf;AAAA,MACF;AAIA,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ,uCAAuC,OAAO,GAAG,CAAC;AAAA,QAC1D,SAAS,EAAE,aAAa,KAAK,gBAAgB;AAAA,QAC7C,aACE,GAAG,KAAK,eAAe;AAAA,MAE3B;AAAA,IACF;AAEA,UAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,UAAM,UAAmC,EAAE,aAAa,KAAK,iBAAiB,OAAO;AACrF,QAAI,WAAW,MAAM;AACnB,cAAQ,mBAAmB,IAAI,KAAK,MAAM,OAAO,aAAa,EAAE,IAAI;AACpE,cAAQ,kBAAkB,IAAI,IAAI,KAAK,OAAO,YAAY,GAAI,EAC3D,YAAY,EACZ,QAAQ,aAAa,QAAQ;AAAA,IAClC;AACA,QAAI,WAAW,eAAe;AAC5B,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR;AAAA,QACA,aAAa;AAAA,MACf;AAAA,IACF;AACA,WAAO,EAAE,QAAQ,MAAM,QAAQ;AAAA,EACjC;AACF;;;AC3RA,IAAAC,kBAAuC;AACvC,IAAAC,kBAAwB;AACxB,IAAAC,oBAAqB;AAErB,gBAYO;AACP,uBAA2B;AAoB3B,IAAM,WAAW;AACjB,IAAM,aAAa;AACnB,IAAM,eAAe;AACrB,IAAM,iBACJ;AAKF,IAAM,wBAAwB;AAG9B,IAAM,mBAAmB,CAAC,aAAa,SAAS;AAEhD,IAAM,qBAAwC,gCAAqB;AAAA,EACjE,SAAS,qBAAW;AAAA,EACpB,cAAc,CAAC,YAAY,aAAa,cAAc,UAAU,UAAU,UAAU,OAAO;AAAA,EAC3F,WAAW,CAAC,iBAAiB,kBAAkB,gBAAgB;AACjE,CAAC;AAGD,IAAM,wBAAwB,oBAAI,IAAI;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAQM,SAAS,kBAAkB,MAAuB;AACvD,MAAI,KAAM,YAAO,wBAAK,MAAM,SAAS;AACrC,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,IAAK,QAAO;AAChB,aAAO,4BAAK,yBAAQ,GAAG,SAAS;AAClC;AAEA,SAAS,MAAM,GAAoB;AACjC,MAAI;AACF,eAAO,0BAAS,CAAC,EAAE,YAAY;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,OAAO,GAAoB;AAClC,MAAI;AACF,eAAO,0BAAS,CAAC,EAAE,OAAO;AAAA,EAC5B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAgBA,SAAS,QAAQ,OAAe,QAAQ,KAAa;AACnD,QAAM,cAAU,8BAAY,SAAS,IAAI,QAAQ,QAAQ,GAAG,EAAE,KAAK,GAAG,KAAK;AAC3E,SAAO,QAAQ,KAAK;AACtB;AAEA,SAAS,WAAW,KAA+C;AACjE,SAAO,kBAAkB,KAAK,qBAAqB;AACrD;AAKA,SAAS,mBAAmB,SAAiB,QAAQ,uBAAwC;AAC3F,MAAI,CAAC,OAAO,OAAO,EAAG,QAAO,CAAC;AAC9B,QAAM,OAAO,gBAAgB,OAAO;AACpC,MAAI,CAAC,KAAM,QAAO,CAAC;AACnB,QAAM,MAAuB,CAAC;AAC9B,MAAI;AACF,QAAI,CAAC,YAAY,MAAM,UAAU,EAAG,QAAO,CAAC;AAE5C,UAAM,OAAO,aAAa,MAAM,UAAU;AAC1C,UAAM,iBAAiB,KAAK,IAAI,UAAU,IAAI,oCAAoC;AAClF,UAAM,OAAO,KACV;AAAA,MACC;AAAA;AAAA;AAAA,WAGG,cAAc;AAAA;AAAA;AAAA,IAGnB,EACC,IAAI,KAAK;AACZ,eAAW,KAAK,MAAM;AACpB,YAAM,MAAM,eAAe,EAAE,YAAY,CAAC;AAC1C,UAAI,CAAC,IAAK;AACV,UAAI,KAAK;AAAA,QACP,IAAI,OAAO,EAAE,IAAI,CAAC;AAAA,QAClB,QAAQ,OAAO,EAAE,QAAQ,KAAK,EAAE,EAAE,YAAY;AAAA,QAC9C,OAAO,EAAE,OAAO;AAAA,QAChB,OAAQ,EAAE,OAAO,KAAuB;AAAA,QACxC,KAAM,EAAE,KAAK,KAAuB;AAAA,QACpC,MAAM;AAAA,QACN,cAAc,OAAO,EAAE,eAAe,KAAK,CAAC,KAAK;AAAA,QACjD,eAAe,OAAO,EAAE,iBAAiB,KAAK,CAAC,KAAK;AAAA,MACtD,CAAC;AAAA,IACH;AAAA,EACF,QAAQ;AAAA,EAER,UAAE;AACA,SAAK,MAAM;AAAA,EACb;AACA,SAAO;AACT;AAGA,SAAS,oBAAoB,MAAsB,WAA6B;AAC9E,MAAI,CAAC,YAAY,MAAM,UAAU,EAAG,QAAO,CAAC;AAC5C,MAAI;AACF,UAAM,OAAO,KACV;AAAA,MACC;AAAA;AAAA,IAEF,EACC,IAAI,SAAS;AAChB,UAAM,QAAQ,oBAAI,IAAY;AAC9B,eAAW,KAAK,MAAM;AACpB,UAAI,EAAE,UAAW,OAAM,IAAI,EAAE,SAAS;AAAA,IACxC;AACA,WAAO,CAAC,GAAG,KAAK,EAAE,KAAK;AAAA,EACzB,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAIA,IAAM,YAAY;AAGlB,SAAS,gBAAgB,MAAwB;AAC/C,MAAI;AACJ,MAAI;AACF,eAAO,8BAAa,MAAM,MAAM;AAAA,EAClC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACA,QAAM,UAAoB,CAAC;AAC3B,aAAW,QAAQ,KAAK,MAAM,OAAO,GAAG;AACtC,UAAM,IAAI,UAAU,KAAK,IAAI;AAC7B,UAAM,YAAY,IAAK,EAAE,CAAC,KAAK,KAAM,KAAK,KAAK;AAC/C,QAAI,aAAa,CAAC,UAAU,WAAW,GAAG,EAAG,SAAQ,KAAK,SAAS;AAAA,EACrE;AACA,SAAO;AACT;AAGA,SAAS,qBAAqB,MAAyC;AACrE,QAAM,aAAS,wBAAK,MAAM,UAAU;AACpC,QAAM,SAAoC,CAAC;AAC3C,MAAI,CAAC,MAAM,MAAM,EAAG,QAAO;AAC3B,aAAW,SAAS,kBAAkB;AACpC,UAAM,WAAO,wBAAK,QAAQ,KAAK;AAC/B,QAAI,OAAO,IAAI,GAAG;AAChB,YAAM,UAAU,gBAAgB,IAAI;AACpC,UAAI,QAAQ,QAAQ;AAClB,cAAMC,QAAO,MAAM,QAAQ,SAAS,EAAE;AACtC,eAAO,KAAK,CAACA,OAAM,OAAO,CAAC;AAAA,MAC7B;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAIA,SAAS,aAAa,QAAuB,WAAmC;AAC9E,QAAM,MAAM,WAAW,OAAO,GAAG;AACjC,QAAM,QAAkB,CAAC;AACzB,MAAI,IAAK,OAAM,KAAK,GAAG;AACvB,QAAMC,cAAuB,CAAC;AAC9B,MAAI,OAAO,MAAO,CAAAA,YAAW,KAAK,QAAQ,OAAO,OAAO,GAAG,CAAC;AAC5D,MAAI,UAAU,QAAQ;AACpB,IAAAA,YAAW,KAAK,YAAY,UAAU,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC;AAAA,EAC9D,WAAW,OAAO,eAAe;AAC/B,IAAAA,YAAW,KAAK,GAAG,OAAO,aAAa,eAAe;AAAA,EACxD;AACA,aAAO,uBAAY;AAAA,IACjB,MAAM,OAAO;AAAA,IACb,KAAK,OAAO,OAAO;AAAA,IACnB,eAAe;AAAA,IACf,aAAaA;AAAA,IACb,YAAY,qBAAW;AAAA,EACzB,CAAC;AACH;AAGA,SAAS,aAAa,OAAe,OAA4B;AAC/D,QAAM,MAAM,UAAU,SAAS,uBAAuB;AACtD,aAAO,sBAAW;AAAA,IAChB,MAAM,QAAQ,OAAO,EAAE;AAAA,IACvB,MAAM,UAAU,SAAS,eAAe;AAAA,IACxC,SAAS,QAAQ,OAAO,GAAG;AAAA,IAC3B,MAAM,CAAC,GAAG;AAAA,IACV,YAAY,qBAAW;AAAA,EACzB,CAAC;AACH;AAEA,SAAS,gBAAgB,SAAyC;AAChE,QAAM,SAAS,oBAAI,IAAoB;AACvC,aAAW,KAAK,SAAS;AACvB,UAAM,MAAM,WAAW,EAAE,GAAG;AAC5B,QAAI,IAAK,QAAO,IAAI,MAAM,OAAO,IAAI,GAAG,KAAK,KAAK,CAAC;AAAA,EACrD;AACA,QAAM,WAA0B,CAAC;AACjC,aAAW,CAAC,KAAK,KAAK,KAAK,QAAQ;AACjC,QAAI;AACJ,eAAW,KAAK,SAAS;AACvB,UAAI,WAAW,EAAE,GAAG,MAAM,KAAK;AAC7B,YAAI,SAAS,UAAa,EAAE,OAAO,KAAM,QAAO,EAAE;AAAA,MACpD;AAAA,IACF;AACA,aAAS;AAAA,UACP,sBAAW;AAAA,QACT,MAAM,cAAc,GAAG;AAAA,QACvB,MAAM;AAAA,QACN,SAAS,6BAA6B,KAAK;AAAA,QAC3C,SAAS,CAAC,GAAG;AAAA,QACb,cAAc;AAAA,QACd,MAAM,CAAC,gBAAgB;AAAA,QACvB,YAAY,qBAAW;AAAA,MACzB,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAKO,IAAM,oBAAN,MAAsD;AAAA,EAC3D,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,cAAc;AAAA,EACd;AAAA,EAEiB;AAAA,EAEjB,OAAO,kBAAkB,MAAuB;AAC9C,WAAO,kBAAkB,IAAI;AAAA,EAC/B;AAAA;AAAA,EAGA,YAAY,YAAqB;AAC/B,QAAI,YAAY;AACd,WAAK,OAAO;AAAA,IACd,OAAO;AACL,YAAM,OAAO,kBAAkB;AAC/B,WAAK,OAAO,MAAM,IAAI,IAAI,OAAO;AAAA,IACnC;AACA,SAAK,aAAa,KAAK,YAAQ,4BAAK,yBAAQ,GAAG,SAAS;AAAA,EAC1D;AAAA,EAEQ,UAAyC;AAC/C,UAAM,OAAO,KAAK;AAClB,UAAM,UAAU,WAAO,wBAAK,MAAM,UAAU,IAAI;AAChD,UAAM,SAAS,WAAO,wBAAK,MAAM,UAAU,IAAI;AAC/C,UAAM,YAAY,WAAO,wBAAK,MAAM,QAAQ,IAAI;AAChD,WAAO;AAAA,MACL,aAAa;AAAA,MACb,UAAU,WAAW,OAAO,OAAO,IAAI,UAAU;AAAA,MACjD,cAAc,UAAU,MAAM,MAAM,IAAI,SAAS;AAAA,MACjD,YAAY,aAAa,MAAM,SAAS,IAAI,YAAY;AAAA,IAC1D;AAAA,EACF;AAAA,EAEA,WAAuB;AACrB,UAAM,UAAU,KAAK,QAAQ;AAC7B,QAAI,CAAC,OAAO,OAAO,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG;AAC1C,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,QAAI,CAAC,QAAQ,UAAU,KAAK,CAAC,QAAQ,cAAc,GAAG;AACpD,YAAM,IAAI;AAAA,QACR,gBAAgB,KAAK,UAAU;AAAA,MAEjC;AAAA,IACF;AACA,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,SAAS;AAAA,MACT,UAAU,EAAE,QAAQ;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,eAAe,OAAc,QAAQ,uBAAuC;AAC1E,QAAI,KAAK,SAAS,KAAM,QAAO,CAAC;AAChC,UAAM,cAAU,wBAAK,KAAK,MAAM,UAAU;AAC1C,UAAM,SAAS,QAAQ,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE,IAAI;AAC1D,UAAM,UAAU,mBAAmB,SAAS,KAAK;AACjD,QAAI,CAAC,QAAQ,OAAQ,QAAO,CAAC;AAC7B,UAAM,OAAO,gBAAgB,OAAO;AACpC,UAAM,MAAsB,CAAC;AAC7B,QAAI;AACF,iBAAW,OAAO,SAAS;AACzB,YAAI,UAAU,IAAI,OAAO,OAAQ;AACjC,cAAM,QAAQ,OAAO,oBAAoB,MAAM,IAAI,EAAE,IAAI,CAAC;AAC1D,YAAI,KAAK,aAAa,KAAK,KAAK,CAAC;AAAA,MACnC;AAAA,IACF,UAAE;AACA,UAAI,KAAM,MAAK,MAAM;AAAA,IACvB;AACA,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,OAA+B;AACtC,UAAM,QAAQ,KAAK,SAAS;AAC5B,UAAM,UAAW,MAAM,SAAS,SAAS,KAAK,CAAC;AAC/C,UAAMC,gBAAe,OAAO,QAAQ,OAAO,EACxC,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,MAAM,aAAa,EAC3C,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,EACd,KAAK;AAER,UAAM,OAAO,KAAK;AAClB,UAAM,UAAU,OAAO,uBAAmB,wBAAK,MAAM,UAAU,GAAG,qBAAqB,IAAI,CAAC;AAG5F,UAAM,WAA0B,gBAAgB,OAAO;AACvD,UAAM,OAAO,oBAAI,IAAY;AAC7B,eAAW,KAAK,UAAU;AACxB,WAAK,IAAI,GAAG,EAAE,QAAQ,OAAO,KAAS,EAAE,KAAK,YAAY,CAAC,EAAE;AAAA,IAC9D;AACA,QAAI,MAAM;AACR,iBAAW,CAAC,WAAW,OAAO,KAAK,qBAAqB,IAAI,GAAG;AAC7D,mBAAW,SAAS,SAAS;AAC3B,gBAAM,MAAM,aAAa,WAAW,KAAK;AACzC,gBAAM,MAAM,GAAG,IAAI,QAAQ,OAAO,KAAS,IAAI,KAAK,YAAY,CAAC;AACjE,cAAI,KAAK,IAAI,GAAG,EAAG;AACnB,eAAK,IAAI,GAAG;AACZ,mBAAS,KAAK,GAAG;AAAA,QACnB;AAAA,MACF;AAAA,IACF;AAGA,UAAM,cAAU,+BAAoB,UAAU,cAAc;AAE5D,UAAM,WAAW,KAAK;AAAA,MACpB,SAAS,oBAAI,KAAK,CAAC;AAAA,MACnB;AAAA,IACF;AAEA,eAAO,wBAAa;AAAA,MAClB,cAAc;AAAA,MACd,WAAO,yBAAc;AAAA,QACnB,IAAI,KAAK;AAAA,QACT,MAAM,KAAK;AAAA,QACX,gBAAgB;AAAA,QAChB,qBAAqB;AAAA,MACvB,CAAC;AAAA,MACD,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,MACrC,cAAAA;AAAA,MACA,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,mBAAmB;AAAA,IACrB,CAAC;AAAA,EACH;AAAA,EAEA,cAA4B;AAC1B,UAAM,UAAmC;AAAA,MACvC,aAAa,KAAK;AAAA,MAClB,UAAU;AAAA,MACV,cAAc;AAAA,MACd,YAAY;AAAA,IACd;AACA,QAAI;AACF,UAAI,KAAK,SAAS,MAAM;AACtB,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR;AAAA,UACA,aACE;AAAA,QACJ;AAAA,MACF;AACA,YAAM,UAAU,KAAK,QAAQ;AAC7B,iBAAW,OAAO,CAAC,YAAY,gBAAgB,YAAY,GAAY;AACrE,YAAI,QAAQ,GAAG,EAAG,SAAQ,GAAG,IAAI,QAAQ,GAAG;AAAA,MAC9C;AACA,UAAI,QAAQ,UAAU,GAAG;AACvB,cAAM,UAAU,uBAAmB,wBAAK,KAAK,MAAM,UAAU,GAAG,CAAC;AACjE,YAAI,QAAQ,OAAQ,QAAO,EAAE,QAAQ,MAAM,QAAQ;AACnD,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR;AAAA,UACA,aAAa;AAAA,QACf;AAAA,MACF;AACA,UAAI,QAAQ,cAAc,GAAG;AAC3B,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR;AAAA,QACA,aAAa;AAAA,MACf;AAAA,IACF,SAAS,KAAK;AAEZ,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ,qBAAqB,OAAO,GAAG,CAAC;AAAA,QACxC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACvdA,IAAAC,kBAAoD;AACpD,IAAAC,kBAAkC;AAClC,IAAAC,oBAA+B;AAE/B,kBAAmC;AAEnC,IAAAC,aAYO;AACP,IAAAC,oBAA+B;AAU/B,IAAMC,YAAW;AACjB,IAAMC,cAAa;AACnB,IAAMC,kBACJ;AAKF,IAAMC,sBAAwC,iCAAqB;AAAA,EACjE,SAAS,sBAAW;AAAA,EACpB,cAAc,CAAC,YAAY,aAAa,cAAc,UAAU,UAAU,OAAO;AAAA,EACjF,WAAW,CAAC,kBAAkB;AAChC,CAAC;AAGD,IAAM,2BAA2B,oBAAI,IAAI;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,oBAAoB;AAC1B,IAAM,8BAA8B;AAIpC,SAASC,OAAM,GAAoB;AACjC,MAAI;AACF,eAAO,0BAAS,CAAC,EAAE,YAAY;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASC,QAAO,GAAoB;AAClC,MAAI;AACF,eAAO,0BAAS,CAAC,EAAE,OAAO;AAAA,EAC5B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,IAAM,kBAAqC,CAAC,aAAa;AAGzD,IAAM,iBAAiB,CAAC,aAAa;AAQ5C,SAAS,mBAAkC;AACzC,aAAW,WAAW,gBAAgB;AACpC,UAAM,cAAc,QAAQ,IAAI,OAAO;AACvC,QAAI,eAAeD,OAAM,WAAW,EAAG,QAAO;AAAA,EAChD;AAEA,aAAW,QAAQ,CAAC,QAAQ,GAAG,QAAQ,IAAI,CAAC,GAAG;AAC7C,eAAW,QAAQ,iBAAiB;AAClC,YAAM,gBAAY,wBAAK,MAAM,IAAI;AACjC,UAAIA,OAAM,SAAS,EAAG,QAAO;AAAA,IAC/B;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,UAAkB;AAGzB,MAAI;AACF,eAAO,yBAAQ;AAAA,EACjB,QAAQ;AACN,WAAO,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe;AAAA,EACxD;AACF;AAEA,SAAS,wBAAuC;AAC9C,MAAI;AACF,UAAM,WAAO,wBAAK,QAAQ,GAAG,WAAW,UAAU;AAClD,QAAI,CAACA,OAAM,IAAI,EAAG,QAAO;AACzB,eAAW,aAAS,6BAAY,IAAI,GAAG;AACrC,YAAM,gBAAY,wBAAK,MAAM,OAAO,UAAU,WAAW;AACzD,UAAIC,QAAO,SAAS,EAAG,YAAO,wBAAK,MAAM,OAAO,QAAQ;AAAA,IAC1D;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,4BAA2C;AAClD,QAAM,gBAAY,wBAAK,QAAQ,GAAG,iBAAiB,cAAc;AACjE,SAAOA,QAAO,SAAS,IAAI,YAAY;AACzC;AAIA,SAAS,cAAc,YAAgD;AACrE,MAAI,CAAC,WAAY,QAAO;AACxB,QAAM,aAAa,WAAW,MAAM,GAAG,EAAE,IAAI,GAAG,KAAK,EAAE,YAAY,KAAK;AACxE,SAAO,yBAAyB,IAAI,UAAU;AAChD;AAIA,IAAM,mBAAmB;AACzB,IAAM,oBAAoB;AAE1B,SAAS,iBAAiB,MAAsE;AAC9F,MAAI,CAAC,KAAK,WAAW,gBAAgB,EAAG,QAAO,EAAE,aAAa,CAAC,GAAG,MAAM,KAAK;AAC7E,QAAM,MAAM,KAAK,QAAQ,mBAAmB,iBAAiB,MAAM;AACnE,MAAI,QAAQ,GAAI,QAAO,EAAE,aAAa,CAAC,GAAG,MAAM,KAAK;AACrD,QAAM,SAAS,KAAK,MAAM,iBAAiB,QAAQ,GAAG;AACtD,QAAM,OAAO,KAAK,MAAM,MAAM,kBAAkB,MAAM;AACtD,MAAI;AACJ,MAAI;AACF,iBAAS,YAAAC,OAAU,MAAM;AAAA,EAC3B,QAAQ;AACN,WAAO,EAAE,aAAa,CAAC,GAAG,MAAM,KAAK;AAAA,EACvC;AACA,QAAM,KACJ,OAAO,WAAW,YAAY,WAAW,QAAQ,CAAC,MAAM,QAAQ,MAAM,IACjE,SACD,CAAC;AACP,SAAO,EAAE,aAAa,IAAI,KAAK;AACjC;AAIA,IAAM,QAAQ;AACd,IAAM,oBAAoB;AAC1B,IAAM,iBAAiB;AACvB,IAAM,iBAAiB;AAEvB,SAAS,eAAe,MAA6B;AACnD,QAAM,QAAQ,MAAM,KAAK,IAAI;AAC7B,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,SAAS,MAAM,CAAC,KAAK,IAAI,KAAK;AACpC,QAAM,OAAO,MAAM,MAAM,cAAc,EAAE,CAAC,KAAK;AAC/C,SAAO,KAAK,KAAK;AACnB;AAEA,SAAS,sBAAsB,MAAc,WAAW,mBAA2B;AACjF,QAAM,YAAsB,CAAC;AAC7B,aAAW,QAAQ,KAAK,MAAM,OAAO,GAAG;AACtC,UAAM,WAAW,KAAK,KAAK;AAC3B,QAAI,CAAC,UAAU;AACb,UAAI,UAAU,OAAQ;AACtB;AAAA,IACF;AACA,QAAI,SAAS,WAAW,GAAG,EAAG;AAC9B,cAAU,KAAK,QAAQ;AACvB,QAAI,UAAU,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,SAAS,GAAG,CAAC,IAAI,SAAU;AAAA,EACtE;AACA,SAAO,UAAU,KAAK,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ,EAAE,KAAK;AAC5D;AAEA,SAAS,iBAAiB,MAAwB;AAChD,QAAM,QAAQ,kBAAkB,KAAK,IAAI;AACzC,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,QAAM,SAAS,KAAK,MAAM,MAAM,OAAO,MAAM,QAAQ,GAAG,EAAE,YAAY;AACtE,QAAM,OAAiB,CAAC;AACxB,aAAW,WAAW,CAAC,YAAY,YAAY,aAAa,UAAU,WAAW,SAAS,GAAG;AAC3F,QAAI,OAAO,SAAS,OAAO,EAAG,MAAK,KAAK,QAAQ,QAAQ,aAAa,UAAU,CAAC;AAAA,EAClF;AACA,SAAO,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC;AAC1B;AAEA,IAAM,mBAAmB,oBAAI,IAAI,CAAC,YAAY,UAAU,CAAC;AAEzD,SAAS,kBAAkB,MAA6B;AACtD,QAAM,QAAQ,kBAAkB,KAAK,IAAI;AACzC,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,SAAS,KAAK,MAAM,MAAM,OAAO,MAAM,QAAQ,GAAG;AACxD,QAAM,YAAY,eAAe,KAAK,MAAM;AAC5C,SAAO,YAAa,UAAU,CAAC,KAAK,OAAQ;AAC9C;AAEA,SAAS,qBAAqB,cAA0C;AACtE,MAAI;AACJ,MAAI;AACF,eAAO,8BAAa,cAAc,MAAM;AAAA,EAC1C,QAAQ;AACN,WAAO;AAAA,EACT;AACA,QAAM,EAAE,KAAK,IAAI,iBAAiB,IAAI;AACtC,QAAM,QAAQ,eAAe,IAAI,SAAK,gCAAS,wBAAK,cAAc,IAAI,CAAC;AACvE,QAAM,UAAU,sBAAsB,IAAI;AAC1C,QAAM,OAAO,iBAAiB,IAAI;AAElC,MAAI,UAAyB;AAC7B,MAAI,KAAK,KAAK,CAAC,MAAM,iBAAiB,IAAI,CAAC,CAAC,GAAG;AAC7C,cAAU,kBAAkB,IAAI;AAChC,QAAI,YAAY,MAAM;AACpB,UAAI;AACF,cAAM,YAAQ,0BAAS,YAAY,EAAE;AACrC,kBAAU,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE;AAAA,MAC3C,QAAQ;AACN,kBAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAEA,aAAO,uBAAW;AAAA,IAChB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS,WAAW;AAAA,IACpB;AAAA,IACA,UAAU,WAAW;AAAA,EACvB,CAAC;AACH;AAEA,SAAS,iBAAiB,WAAkC;AAC1D,QAAM,kBAAc,wBAAK,WAAW,UAAU;AAC9C,MAAI,CAACF,OAAM,WAAW,EAAG,QAAO,CAAC;AACjC,QAAM,WAA0B,CAAC;AACjC,aAAW,YAAQ,6BAAY,WAAW,EAAE,KAAK,GAAG;AAClD,UAAM,iBAAa,wBAAK,aAAa,IAAI;AACzC,QAAI,CAACA,OAAM,UAAU,EAAG;AACxB,UAAM,eAAW,wBAAK,YAAY,aAAa;AAC/C,QAAI,CAACC,QAAO,QAAQ,EAAG;AACvB,UAAM,SAAS,qBAAqB,QAAQ;AAC5C,QAAI,OAAQ,UAAS,KAAK,MAAM;AAAA,EAClC;AACA,SAAO;AACT;AAEA,IAAM,kBAAkB;AAExB,SAAS,aAAa,SAAsC;AAC1D,QAAM,IAAI,gBAAgB,SAAK,4BAAS,OAAO,CAAC;AAChD,MAAI,CAAC,EAAG,QAAO;AACf,QAAME,eAAc,EAAE,CAAC,KAAK;AAC5B,MAAI;AACJ,MAAI;AACF,eAAO,8BAAa,SAAS,MAAM;AAAA,EACrC,QAAQ;AACN,WAAO;AAAA,EACT;AACA,QAAM,EAAE,KAAK,IAAI,iBAAiB,IAAI;AACtC,QAAM,WAAW,sBAAsB,MAAM,GAAG;AAChD,aAAO,wBAAY;AAAA,IACjB,MAAMA;AAAA,IACN,aAAa,WAAW,CAAC,QAAQ,IAAI,CAAC;AAAA,IACtC,eAAe,CAAC,WAAO,4BAAS,OAAO,CAAC,EAAE;AAAA,EAC5C,CAAC;AACH;AAEA,SAAS,aAAa,WAAmB,OAAc,QAAQ,KAAqB;AAClF,QAAM,aAAS,wBAAK,WAAW,KAAK;AACpC,MAAI,CAACH,OAAM,MAAM,EAAG,QAAO,CAAC;AAC5B,QAAM,aAAsC,CAAC;AAC7C,aAAW,aAAS,6BAAY,MAAM,GAAG;AACvC,QAAI,CAAC,MAAM,SAAS,KAAK,EAAG;AAC5B,UAAM,IAAI,gBAAgB,KAAK,KAAK;AACpC,QAAI,CAAC,EAAG;AACR,UAAM,IAAI,EAAE,CAAC,KAAK;AAClB,QAAI,OAAO;AACT,UAAI,IAAI,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE,EAAG;AAAA,IAC5C;AACA,eAAW,KAAK,CAAC,OAAG,wBAAK,QAAQ,KAAK,CAAC,CAAC;AAAA,EAC1C;AACA,aAAW,KAAK,CAAC,GAAG,MAAO,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,CAAE;AAClE,QAAM,WAA2B,CAAC;AAClC,aAAW,CAAC,EAAE,OAAO,KAAK,WAAW,MAAM,GAAG,KAAK,GAAG;AACpD,UAAM,UAAU,aAAa,OAAO;AACpC,QAAI,QAAS,UAAS,KAAK,OAAO;AAAA,EACpC;AACA,SAAO;AACT;AAIA,SAAS,sBAAsB,QAAoC;AACjE,MAAI;AACJ,MAAI;AACF,eAAO,8BAAa,QAAQ,MAAM;AAAA,EACpC,QAAQ;AACN,WAAO;AAAA,EACT;AACA,QAAM,EAAE,aAAa,KAAK,IAAI,iBAAiB,IAAI;AACnD,QAAM,OACH,YAAY,MAAM,KACnB,eAAe,IAAI,SACnB,4BAAS,MAAM,EAAE,QAAQ,SAAS,EAAE;AACtC,QAAM,aAAa,YAAY,MAAM;AACrC,QAAM,aACH,YAAY,aAAa,KAA4B,sBAAsB,IAAI;AAClF,QAAM,UAAU,YAAY,MAAM;AAClC,QAAM,OAAO,MAAM,QAAQ,OAAO,IAAI,QAAQ,IAAI,CAAC,MAAM,OAAO,CAAC,CAAC,IAAI,CAAC;AAEvE,QAAM,aAAa,cAAc,UAAU,IAAI,sBAAW,UAAU;AAEpE,aAAO,uBAAW;AAAA,IAChB,MAAM,OAAO,IAAI;AAAA,IACjB,MAAM,aAAa,OAAO,UAAU,IAAI;AAAA,IACxC,SAAS,aAAa,OAAO,UAAU,EAAE,MAAM,GAAG,iBAAiB,EAAE,KAAK,IAAI;AAAA,IAC9E;AAAA,IACA;AAAA,EACF,CAAC;AACH;AAEA,SAAS,gBAAgB,YAAmC;AAC1D,MAAI,CAACA,OAAM,UAAU,EAAG,QAAO,CAAC;AAChC,QAAM,WAA0B,CAAC;AACjC,aAAW,aAAS,6BAAY,UAAU,EAAE,KAAK,GAAG;AAClD,QAAI,CAAC,MAAM,SAAS,KAAK,KAAK,UAAU,YAAa;AACrD,UAAM,SAAS,0BAAsB,wBAAK,YAAY,KAAK,CAAC;AAC5D,QAAI,OAAQ,UAAS,KAAK,MAAM;AAAA,EAClC;AACA,SAAO;AACT;AAIA,SAAS,2BAA2B,QAAqD;AACvF,QAAM,OAAO,OAAO,MAAM;AAC1B,MAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO;AAC9C,QAAM,iBAAkB,OAAO,YAAY,KAA4B;AACvE,QAAM,iBAAiB,iBAAkB,eAAe,MAAM,GAAG,EAAE,IAAI,KAAK,OAAQ;AACpF,QAAM,eAAe,MAAM,QAAQ,OAAO,cAAc,CAAC,IACpD,OAAO,cAAc,IACtB,CAAC;AAEL,QAAM,UAAoB,CAAC;AAC3B,aAAW,OAAO,aAAa,MAAM,GAAG,2BAA2B,GAAG;AACpE,QAAI,OAAO,QAAQ,SAAU;AAC7B,YAAQ,SAAK,kCAAe,GAAG,IAAI,mDAAmD,GAAG;AAAA,EAC3F;AACA,QAAM,SAAS,QAAQ,KAAK,KAAK,EAAE,MAAM,GAAG,iBAAiB,EAAE,KAAK;AACpE,QAAM,UAAU,UAAU;AAE1B,QAAM,aAAa,aAAa,KAAK,CAAC,MAAM,OAAO,MAAM,gBAAY,kCAAe,CAAC,CAAC;AACtF,QAAM,aAAa,cAAc,cAAc,KAAK,aAAa,sBAAW,UAAU;AAEtF,QAAM,OACJ,kBAAkB,mBAAmB,KAAK,YAAY,IAAI,CAAC,cAAc,IAAI,CAAC;AAEhF,aAAO,uBAAW;AAAA,IAChB;AAAA,IACA,MAAM,kBAAkB;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACH;AAEA,SAAS,oBAAoB,WAAkC;AAC7D,MAAI,CAACC,QAAO,SAAS,EAAG,QAAO,CAAC;AAChC,MAAI;AACJ,MAAI;AACF,cAAM,8BAAa,WAAW,MAAM;AAAA,EACtC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACA,QAAM,WAA0B,CAAC;AACjC,aAAW,WAAW,IAAI,MAAM,OAAO,GAAG;AACxC,UAAM,OAAO,QAAQ,KAAK;AAC1B,QAAI,CAAC,KAAM;AACX,QAAI;AACJ,QAAI;AACF,eAAS,KAAK,MAAM,IAAI;AAAA,IAC1B,QAAQ;AACN;AAAA,IACF;AACA,QAAI,OAAO,WAAW,YAAY,WAAW,KAAM;AACnD,UAAM,MAAM;AACZ,QAAI,IAAI,MAAM,MAAM,SAAU;AAC9B,UAAM,SAAS,2BAA2B,GAAG;AAC7C,QAAI,OAAQ,UAAS,KAAK,MAAM;AAAA,EAClC;AACA,SAAO;AACT;AAIA,IAAM,YAAoC;AAAA,EACxC,CAAC,sBAAW,OAAO,GAAG;AAAA,EACtB,CAAC,sBAAW,IAAI,GAAG;AAAA,EACnB,CAAC,sBAAW,MAAM,GAAG;AAAA,EACrB,MAAM;AACR;AAEA,SAAS,QAAQ,GAA0C;AACzD,SAAO,KAAK,OAAO,UAAU,MAAM,IAAK,UAAU,CAAC;AACrD;AAEA,SAAS,cAAc,MAAmB,OAAiC;AACzE,MAAI,CAAC,KAAK,QAAQ,MAAM,KAAM,MAAK,OAAO,MAAM;AAChD,MAAI,MAAM,WAAW,MAAM,QAAQ,KAAK,KAAK,MAAM,QAAQ,UAAU,KAAK,SAAS,UAAU,IAAI;AAC/F,SAAK,UAAU,MAAM;AAAA,EACvB;AACA,OAAK,OAAO,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAI,KAAK,QAAQ,CAAC,GAAI,GAAI,MAAM,QAAQ,CAAC,CAAE,CAAC,CAAC;AACtE,OAAK,UAAU,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAI,KAAK,WAAW,CAAC,GAAI,GAAI,MAAM,WAAW,CAAC,CAAE,CAAC,CAAC;AAC/E,MAAI,MAAM,iBAAiB,KAAK,gBAAgB,QAAQ,MAAM,eAAe,KAAK,eAAe;AAC/F,SAAK,eAAe,MAAM;AAAA,EAC5B;AAGA,MAAI,MAAM,eAAe,KAAK,cAAc,QAAQ,MAAM,aAAa,KAAK,aAAa;AACvF,SAAK,aAAa,MAAM;AAAA,EAC1B;AACA,MAAI,MAAM,aAAa,KAAK,YAAY,QAAQ,MAAM,WAAW,KAAK,WAAW;AAC/E,SAAK,WAAW,MAAM;AAAA,EACxB;AACA,MAAI,QAAQ,MAAM,UAAU,IAAI,QAAQ,KAAK,UAAU,GAAG;AACxD,SAAK,aAAa,MAAM;AAAA,EAC1B;AACA,SAAO;AACT;AAQA,SAAS,eAAe,aAA6C;AACnE,QAAM,QAAQ,oBAAI,IAAyB;AAC3C,aAAW,UAAU,aAAa;AAChC,eAAW,UAAU,QAAQ;AAC3B,YAAM,MAAM,OAAO,KAAK,KAAK,EAAE,YAAY;AAC3C,UAAI,CAAC,IAAK;AACV,YAAM,WAAW,MAAM,IAAI,GAAG;AAC9B,UAAI,UAAU;AACZ,sBAAc,UAAU,MAAM;AAAA,MAChC,OAAO;AACL,cAAM;AAAA,UACJ;AAAA,cACA,uBAAW;AAAA,YACT,GAAG;AAAA,YACH,SAAS,CAAC,GAAI,OAAO,WAAW,CAAC,CAAE;AAAA,YACnC,MAAM,CAAC,GAAI,OAAO,QAAQ,CAAC,CAAE;AAAA,UAC/B,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO,CAAC,GAAG,MAAM,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM;AACxC,UAAM,KAAK,EAAE,KAAK,YAAY;AAC9B,UAAM,KAAK,EAAE,KAAK,YAAY;AAC9B,WAAO,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI;AAAA,EACtC,CAAC;AACH;AAKO,IAAM,wBAAN,MAA0D;AAAA,EAC/D,UAAUL;AAAA,EACV,YAAYC;AAAA,EACZ;AAAA;AAAA;AAAA,EAIA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,OAAO,kBAAkB,MAAuB;AAC9C,eAAO,wBAAK,QAAQ,QAAQ,GAAG,SAAS;AAAA,EAC1C;AAAA,EAEA,cAAc;AACZ,SAAK,iBAAa,wBAAK,QAAQ,GAAG,gBAAgB,CAAC,CAAC;AACpD,SAAK,YAAY,iBAAiB;AAClC,SAAK,iBAAiB,sBAAsB;AAC5C,SAAK,qBAAqB,0BAA0B;AAAA,EACtD;AAAA,EAEA,WAAuB;AACrB,UAAM,UAAU;AAAA,MACd,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,MAClB,iBAAiB,KAAK;AAAA,IACxB;AACA,QAAI,CAAC,OAAO,OAAO,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG;AAC1C,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AACA,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,SAAS;AAAA,MACT,UAAU,EAAE,QAAQ;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,SAAS,OAA+B;AACtC,UAAM,QAAQ,KAAK,SAAS;AAC5B,UAAM,UAAU,MAAM,SAAS,SAAS;AACxC,UAAMO,gBAAe,OAAO,QAAQ,OAAO,EACxC,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EACnB,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,EACd,KAAK;AAER,UAAM,qBAAqB,KAAK,iBAAiB,gBAAgB,KAAK,cAAc,IAAI,CAAC;AACzF,UAAM,gBAAgB,KAAK,qBACvB,oBAAoB,KAAK,kBAAkB,IAC3C,CAAC;AACL,UAAMC,mBAAkB,KAAK,YAAY,iBAAiB,KAAK,SAAS,IAAI,CAAC;AAG7E,UAAM,cAAc,eAAe,CAAC,oBAAoB,eAAeA,gBAAe,CAAC;AAGvF,UAAM,sBAAkB,gCAAoB,aAAaN,eAAc;AAEvE,UAAM,WAAW,KAAK,YAAY,aAAa,KAAK,WAAW,KAAK,IAAI,CAAC;AAEzE,eAAO,yBAAa;AAAA,MAClB,cAAc;AAAA,MACd,WAAO,0BAAc;AAAA,QACnB,IAAI,KAAK;AAAA,QACT,MAAM,KAAK;AAAA,QACX,cAAU,0BAAS,KAAK;AAAA,QACxB,qBAAqB,KAAK,YAAY;AAAA,QACtC,gBAAgBD;AAAA,MAClB,CAAC;AAAA,MACD,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,MACrC,cAAAM;AAAA,MACA,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,mBAAmBL;AAAA,IACrB,CAAC;AAAA,EACH;AAAA,EAEA,eAAe,OAAc,QAAQ,KAAqB;AACxD,QAAI,CAAC,KAAK,UAAW,QAAO,CAAC;AAC7B,WAAO,aAAa,KAAK,WAAW,OAAO,KAAK;AAAA,EAClD;AAAA,EAEA,cAA4B;AAC1B,QAAI;AACF,YAAM,UAAU,CAAC,KAAK,WAAW,KAAK,gBAAgB,KAAK,kBAAkB,EAAE;AAAA,QAC7E,CAAC,MAAM,MAAM;AAAA,MACf,EAAE;AACF,YAAM,UAAU;AAAA,QACd,aAAa,KAAK,aAAa;AAAA,QAC/B,aAAa,KAAK,kBAAkB;AAAA,QACpC,iBAAiB,KAAK,sBAAsB;AAAA,MAC9C;AACA,UAAI,YAAY,EAAG,QAAO,EAAE,QAAQ,MAAM,QAAQ;AAClD,UAAI,YAAY,GAAG;AACjB,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR;AAAA,UACA,aACE;AAAA,QAEJ;AAAA,MACF;AACA,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ,GAAG,OAAO;AAAA,QAClB;AAAA,QACA,aACE;AAAA,MAEJ;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ,qBAAqB,OAAO,GAAG,CAAC;AAAA,QACxC,SAAS,CAAC;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACF;;;ACjmBA,gCAA6B;AAE7B,IAAAO,aAWO;AACP,IAAAC,oBAA2B;AAW3B,IAAMC,YAAW;AACjB,IAAMC,cAAa;AACnB,IAAM,mBAAmB;AACzB,IAAMC,gBAAe;AACrB,IAAMC,kBACJ;AAIF,IAAM,kBAAkB;AAExB,IAAMC,sBAAwC,iCAAqB;AAAA,EACjE,SAAS,sBAAW;AAAA,EACpB,cAAc,CAAC,YAAY,aAAa,cAAc,QAAQ;AAAA,EAC9D,WAAW,CAAC,kBAAkB,cAAc;AAC9C,CAAC;AAKM,SAAS,kBAAiC;AAC/C,aAAW,WAAW,CAAC,gBAAgB,UAAU,GAAG;AAClD,UAAM,MAAM,QAAQ,IAAI,OAAO;AAC/B,QAAI,IAAK,QAAO;AAAA,EAClB;AACA,MAAI;AACF,UAAM,UAAM,wCAAa,MAAM,CAAC,QAAQ,OAAO,GAAG;AAAA,MAChD,UAAU;AAAA,MACV,SAAS;AAAA,MACT,OAAO,CAAC,UAAU,QAAQ,QAAQ;AAAA,IACpC,CAAC;AACD,UAAM,QAAQ,IAAI,KAAK;AACvB,QAAI,MAAO,QAAO;AAAA,EACpB,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAiBA,SAAS,UAAU,MAAc,OAAe,aAAa,IAAa;AACxE,QAAM,MAAM,KAAK,WAAW,MAAM,IAAI,OAAO,GAAG,eAAe,GAAG,IAAI;AACtE,MAAI;AACJ,MAAI;AACF,WAAO,QAAQ,KAAK,OAAO,UAAU;AAAA,EACvC,SAAS,KAAK;AACZ,UAAM,IAAI,mBAAmB,2BAA2B,OAAO,GAAG,CAAC,EAAE;AAAA,EACvE;AAEA,QAAM,YAAY,KAAK,QAAQ,uBAAuB;AACtD,MAAI,KAAK,WAAW,OAAQ,KAAK,WAAW,OAAO,OAAO,SAAS,MAAM,KAAM;AAC7E,UAAM,IAAI,mBAAmB,cAAc,KAAK,MAAM,gBAAgB;AAAA,EACxE;AACA,MAAI,KAAK,WAAW,OAAO,KAAK,WAAW,KAAK;AAC9C,UAAM,IAAI,qBAAqB,cAAc,KAAK,MAAM,gCAAgC;AAAA,EAC1F;AACA,MAAI,KAAK,UAAU,KAAK;AACtB,UAAM,IAAI,mBAAmB,cAAc,KAAK,MAAM,EAAE;AAAA,EAC1D;AACA,MAAI,KAAK,UAAU,KAAK;AACtB,UAAM,IAAI,mBAAmB,cAAc,KAAK,MAAM,EAAE;AAAA,EAC1D;AACA,MAAI;AACF,WAAO,KAAK,MAAM,KAAK,IAAI;AAAA,EAC7B,SAAS,KAAK;AAGZ,UAAM,IAAI,mBAAmB,wCAAwC,OAAO,GAAG,CAAC,EAAE;AAAA,EACpF;AACF;AAEA,SAAS,QAAQ,KAAa,OAAe,YAAkC;AAG7E,QAAM,UAAM;AAAA,IACV;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO,UAAU;AAAA,MACjB;AAAA,MACA,yBAAyB,KAAK;AAAA,MAC9B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,EAAE,UAAU,QAAQ,UAAU,aAAa,KAAK,KAAM,WAAW,IAAI,OAAO,KAAK;AAAA,EACnF;AAEA,QAAM,cAAc,6BAA6B,KAAK,GAAG;AACzD,QAAM,SAAS,cAAc,OAAO,YAAY,CAAC,CAAC,IAAI;AACtD,QAAM,gBAAgB,cAAc,IAAI,MAAM,GAAG,YAAY,KAAK,IAAI;AAGtE,QAAM,kBAAkB,cAAc,QAAQ,UAAU;AACxD,MAAI,cAAc;AAClB,MAAI,OAAO;AACX,MAAI,mBAAmB,GAAG;AACxB,kBAAc,cAAc,MAAM,GAAG,eAAe;AACpD,WAAO,cAAc,MAAM,kBAAkB,CAAC;AAAA,EAChD,OAAO;AACL,UAAM,UAAU,cAAc,QAAQ,MAAM;AAC5C,QAAI,WAAW,GAAG;AAChB,oBAAc,cAAc,MAAM,GAAG,OAAO;AAC5C,aAAO,cAAc,MAAM,UAAU,CAAC;AAAA,IACxC;AAAA,EACF;AAEA,QAAM,UAAkC,CAAC;AACzC,aAAW,QAAQ,YAAY,MAAM,OAAO,GAAG;AAC7C,UAAM,MAAM,KAAK,QAAQ,GAAG;AAC5B,QAAI,MAAM,GAAG;AACX,cAAQ,KAAK,MAAM,GAAG,GAAG,EAAE,KAAK,EAAE,YAAY,CAAC,IAAI,KAAK,MAAM,MAAM,CAAC,EAAE,KAAK;AAAA,IAC9E;AAAA,EACF;AACA,SAAO,EAAE,QAAQ,SAAS,KAAK;AACjC;AAKO,IAAM,2BAAN,cAAuC,mBAAmB;AAAA,EACtD,kBAAkB;AAAA,EAClB,UAAUJ;AAAA,EACV,YAAYC;AAAA,EACZ,aAAa;AAAA,EACtB,cAAcC;AAAA,EAEG;AAAA,EAEjB,YAAY,OAA4D,CAAC,GAAG;AAC1E,UAAM;AAAA,MACJ,cAAc,KAAK,gBAAgB;AAAA,MACnC,WAAW,KAAK;AAAA,IAClB,CAAC;AACD,SAAK,aAAa,KAAK,cAAc;AAAA,EACvC;AAAA,EAEA,OAAO,oBAA4B;AACjC,WAAO;AAAA,EACT;AAAA,EAES,aAAa,OAAwC;AAE5D,UAAM,KAAK,UAAU,SAAS,KAAK;AACnC,UAAM,QAAQ,MAAM,OAAO,OAAO,WAAY,GAA+B,OAAO,IAAI;AAGxF,UAAM,IAAI;AACV,UAAM,UAAU,mBAAmB,CAAC;AACpC,UAAM,SAAS;AAAA,MACb,oBAAoB,OAAO,0BAA0B,KAAK,UAAU;AAAA,MACpE;AAAA,IACF;AACA,UAAM,QACJ,UAAU,OAAO,WAAW,WACtB,OAAmC,OAAO,KAAK,CAAC,IAClD,CAAC;AAEP,WAAO;AAAA,MACL,cAAc,SAAS;AAAA,MACvB,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAAA,EAES,YAAY,SAAmD;AACtE,UAAM,QAAQ,MAAM,QAAQ,QAAQ,OAAO,CAAC,IAAK,QAAQ,OAAO,IAAkB,CAAC;AACnF,UAAM,WAA2B,CAAC;AAClC,UAAM,WAAW,oBAAI,IAAyB;AAE9C,eAAW,QAAQ,OAAO;AACxB,UAAI,OAAO,SAAS,YAAY,SAAS,KAAM;AAC/C,YAAM,KAAK;AACX,YAAM,OAAO,aAAa,EAAE;AAC5B,YAAM,YAAQ,8BAAW,OAAO,GAAG,OAAO,KAAK,EAAE,GAAG,GAAG;AACvD,YAAM,SAAS,GAAG,QAAQ;AAC1B,YAAM,UAAU,QAAQ,GAAG,YAAY,CAAC;AACxC,YAAM,QAAQ,OAAO,CAAC,IAAI,IAAI,CAAC;AAE/B,eAAS;AAAA,YACP,wBAAY;AAAA,UACV,MAAM,WAAW;AAAA,UACjB,KAAK,OAAO,cAAc,IAAI,KAAK;AAAA,UACnC,eAAe;AAAA,UACf,aAAa,UAAU,OAAO,CAAC,OAAO,OAAO,MAAM,CAAC,KAAK,KAAK,EAAE,IAAI,CAAC,KAAK;AAAA,UAC1E,YAAY,sBAAW;AAAA,QACzB,CAAC;AAAA,MACH;AAEA,UAAI,QAAQ,CAAC,SAAS,IAAI,IAAI,GAAG;AAC/B,iBAAS;AAAA,UACP;AAAA,cACA,uBAAW;AAAA,YACT,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,SAAS,KAAK,SAAS,GAAG,IAAI,CAAC,KAAK,MAAM,GAAG,EAAE,IAAI,KAAK,EAAE,IAAI,CAAC;AAAA,YAC/D,cAAc,WAAW;AAAA,YACzB,MAAM,CAAC,kBAAkB,cAAc;AAAA,YACvC,YAAY,sBAAW;AAAA,UACzB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAGA,aAAS,KAAK,CAAC,GAAG,MAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE,OAAO,KAAK,CAAE;AAExE,eAAO,yBAAa;AAAA,MAClB,cAAc;AAAA,MACd,WAAO,0BAAc;AAAA,QACnB,IAAI,KAAK;AAAA,QACT,MAAM,KAAK;AAAA,QACX,gBAAgBC;AAAA,QAChB,UAAW,QAAQ,cAAc,KAAmC;AAAA,MACtE,CAAC;AAAA,MACD,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,MACrC,cAAc,CAAC,iBAAiB,uBAAuB;AAAA,MACvD,iBAAiB,SAAS,MAAM,GAAG,KAAK,UAAU;AAAA,MAClD,gBAAgB,CAAC,GAAG,SAAS,OAAO,CAAC;AAAA,MACrC,mBAAmBC;AAAA,IACrB,CAAC;AAAA,EACH;AACF;AAIA,SAAS,aAAa,MAA8C;AAClE,QAAM,UAAU,KAAK,gBAAgB;AACrC,MAAI,OAAO,YAAY,YAAY,QAAQ,SAAS,SAAS,GAAG;AAC9D,WAAO,QAAQ,MAAM,SAAS,EAAE,CAAC,KAAK;AAAA,EACxC;AACA,SAAO;AACT;AAEA,SAAS,QAAQ,OAA+B;AAC9C,MAAI,OAAO,UAAU,YAAY,MAAM,UAAU,GAAI,QAAO,MAAM,MAAM,GAAG,EAAE;AAC7E,SAAO;AACT;;;AC1RA,IAAAC,kBAAoD;AACpD,IAAAC,kBAAwB;AACxB,IAAAC,oBAA+B;AAE/B,IAAAC,aAYO;AACP,IAAAC,oBAA2B;AAW3B,IAAMC,YAAW;AACjB,IAAMC,cAAa;AACnB,IAAMC,kBACJ;AAGF,IAAMC,sBAAwC,iCAAqB;AAAA,EACjE,SAAS,sBAAW;AAAA,EACpB,cAAc,CAAC,YAAY,cAAc,QAAQ;AAAA,EACjD,WAAW,CAAC,UAAU,aAAa,QAAQ;AAC7C,CAAC;AAED,IAAM,qBAAqB;AAI3B,SAASC,WAAkB;AACzB,MAAI;AACF,eAAO,yBAAQ;AAAA,EACjB,QAAQ;AACN,WAAO,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe;AAAA,EACxD;AACF;AAEA,SAASC,OAAM,GAAoB;AACjC,MAAI;AACF,eAAO,0BAAS,CAAC,EAAE,YAAY;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASC,QAAO,GAAoB;AAClC,MAAI;AACF,eAAO,0BAAS,CAAC,EAAE,OAAO;AAAA,EAC5B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,SAAS,UAAU,OAAe,QAAQ,KAAa;AACrD,aAAO,8BAAW,OAAO,KAAK;AAChC;AAkCO,SAAS,mBAAkC;AAChD,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,IAAK,QAAO;AAChB,UAAQ,QAAQ,UAAU;AAAA,IACxB,KAAK;AACH,iBAAO,wBAAKF,SAAQ,GAAG,WAAW,uBAAuB,QAAQ;AAAA,IACnE,KAAK;AACH,iBAAO,wBAAKA,SAAQ,GAAG,WAAW,QAAQ;AAAA,IAC5C,KAAK,SAAS;AACZ,YAAM,UAAU,QAAQ,IAAI;AAC5B,aAAO,cAAU,wBAAK,SAAS,QAAQ,IAAI;AAAA,IAC7C;AAAA,IACA;AACE,aAAO;AAAA,EACX;AACF;AAGA,SAAS,aAAa,MAAwB;AAC5C,QAAM,aAAuB;AAAA,QAC3B,wBAAK,MAAM,aAAa;AAAA,QACxB,wBAAK,MAAM,QAAQ,iBAAiB,aAAa;AAAA,EACnD;AACA,QAAM,uBAAmB,wBAAK,MAAM,QAAQ,kBAAkB;AAC9D,MAAIC,OAAM,gBAAgB,GAAG;AAC3B,QAAI,WAAqB,CAAC;AAC1B,QAAI;AACF,qBAAW,6BAAY,gBAAgB,EAAE,KAAK;AAAA,IAChD,QAAQ;AACN,iBAAW,CAAC;AAAA,IACd;AACA,eAAW,SAAS,UAAU;AAC5B,iBAAW,SAAK,wBAAK,kBAAkB,OAAO,aAAa,CAAC;AAAA,IAC9D;AAAA,EACF;AACA,SAAO,WAAW,OAAO,CAAC,MAAMC,QAAO,CAAC,CAAC;AAC3C;AASA,SAAS,cAAc,QAA0E;AAC/F,QAAM,UAAoC,CAAC;AAC3C,MAAI,YAAY;AAEhB,QAAM,OAAO,gBAAgB,MAAM;AACnC,MAAI,CAAC,KAAM,QAAO,EAAE,SAAS,UAAU;AAEvC,MAAI;AACJ,MAAI;AACF,QAAI,CAAC,YAAY,MAAM,WAAW,EAAG,QAAO,EAAE,SAAS,UAAU;AACjE,WAAO,KAAK,QAAQ,kCAAkC,EAAE,IAAI;AAAA,EAI9D,QAAQ;AAIN,WAAO,EAAE,SAAS,UAAU;AAAA,EAC9B,UAAE;AACA,SAAK,MAAM;AAAA,EACb;AAEA,aAAW,OAAO,MAAM;AACtB,UAAM,MAAM,IAAI;AAChB,QAAI,OAAsB;AAC1B,QAAI,OAAO,QAAQ,SAAU,QAAO;AAAA,aAC3B,eAAe,WAAY,QAAO,OAAO,KAAK,GAAG,EAAE,SAAS,MAAM;AAC3E,QAAI,SAAS,MAAM;AACjB,mBAAa;AACb;AAAA,IACF;AACA,QAAI;AACJ,QAAI;AACF,cAAQ,KAAK,MAAM,IAAI;AAAA,IACzB,QAAQ;AACN,mBAAa;AACb;AAAA,IACF;AACA,YAAQ,KAAK,CAAC,OAAO,IAAI,GAAG,GAAG,KAAK,CAAC;AAAA,EACvC;AACA,SAAO,EAAE,SAAS,UAAU;AAC9B;AAIA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,YAAY,OAAgC,MAAiC;AACpF,aAAW,OAAO,MAAM;AACtB,UAAM,YAAY,MAAM,GAAG;AAC3B,QAAI,OAAO,cAAc,YAAY,UAAU,KAAK,EAAG,QAAO,UAAU,KAAK;AAAA,EAC/E;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,UAA2B;AACnD,MAAI,CAAC,MAAM,QAAQ,QAAQ,EAAG,QAAO;AACrC,aAAW,WAAW,UAAU;AAC9B,QAAI,CAAC,SAAS,OAAO,EAAG;AAIxB,UAAM,UAAU,QAAQ,SAAS,KAAK,QAAQ,MAAM;AACpD,QAAI,OAAO,YAAY,YAAY,QAAQ,KAAK,EAAG,QAAO,QAAQ,KAAK;AAAA,EACzE;AACA,SAAO;AACT;AAEA,SAAS,wBAAwB,KAAa,OAAyB;AACrE,QAAM,aAAa,IAAI,YAAY;AACnC,MAAI,WAAW,SAAS,UAAU,KAAK,WAAW,SAAS,QAAQ,KAAK,WAAW,SAAS,MAAM,GAAG;AACnG,WAAO;AAAA,EACT;AACA,MAAI,SAAS,KAAK,GAAG;AACnB,UAAM,aAAa,OAAO,KAAK,KAAK,EAAE,KAAK,GAAG,EAAE,YAAY;AAC5D,WAAO,WAAW,SAAS,SAAS,MAAM,WAAW,SAAS,WAAW,KAAK,WAAW,SAAS,MAAM;AAAA,EAC1G;AACA,SAAO;AACT;AAMA,SAAS,UAAU,OAAwB;AACzC,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,aAAa,MAAM,WAAW,KAAK,QAAQ;AACjD,UAAM,IAAI,iCAAiC,KAAK,UAAU;AAC1D,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,WAAW,EAAE,CAAC,KAAK;AAIzB,UAAM,WAAW,oBAAI,KAAK,GAAG,QAAQ,YAAY;AACjD,QAAI,OAAO,MAAM,SAAS,QAAQ,CAAC,KAAK,SAAS,YAAY,EAAE,MAAM,GAAG,EAAE,MAAM,UAAU;AACxF,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,IAAI,KAAK,EAAE,CAAC,IAAI,WAAW,QAAQ,KAAK,GAAG,IAAI,GAAG,QAAQ,WAAW;AACnF,QAAI,OAAO,MAAM,MAAM,QAAQ,CAAC,EAAG,QAAO;AAC1C,WAAO;AAAA,EACT;AACA,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,GAAG;AACvD,UAAM,YAAY,QAAQ,OAAiB,QAAQ,MAAO;AAC1D,UAAM,KAAK,IAAI,KAAK,YAAY,GAAI;AACpC,QAAI,OAAO,MAAM,GAAG,QAAQ,CAAC,EAAG,QAAO;AACvC,WAAO,GAAG,YAAY,EAAE,MAAM,GAAG,EAAE;AAAA,EACrC;AACA,SAAO;AACT;AAEA,SAAS,eAAe,OAAwC;AAC9D,aAAW,OAAO,CAAC,aAAa,aAAa,aAAa,iBAAiB,MAAM,GAAG;AAClF,UAAM,SAAS,UAAU,MAAM,GAAG,CAAC;AACnC,QAAI,OAAQ,QAAO;AAAA,EACrB;AACA,UAAO,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AAC7C;AAEA,SAAS,gBAAgB,QAA6B;AACpD,QAAM,UAAoB,CAAC;AAC3B,aAAW,QAAQ,QAAQ;AACzB,QAAI,OAAO,SAAS,YAAY,KAAK,KAAK,GAAG;AAC3C,cAAQ,KAAK,KAAK,KAAK,CAAC;AAAA,IAC1B,WAAW,SAAS,IAAI,GAAG;AACzB,YAAM,OAAO,YAAY,MAAM,CAAC,QAAQ,QAAQ,OAAO,cAAc,CAAC;AACtE,UAAI,KAAM,SAAQ,KAAK,IAAI;AAAA,IAC7B;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,OAAO,QAA4B;AAC1C,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,MAAgB,CAAC;AACvB,aAAW,SAAS,QAAQ;AAC1B,QAAI,CAAC,KAAK,IAAI,KAAK,GAAG;AACpB,WAAK,IAAI,KAAK;AACd,UAAI,KAAK,KAAK;AAAA,IAChB;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,aAAa,OAA0C;AAC9D,QAAM,QAAkB,CAAC;AACzB,aAAW,OAAO,CAAC,SAAS,aAAa,gBAAgB,YAAY,GAAG;AACtE,UAAM,YAAY,MAAM,GAAG;AAC3B,QAAI,MAAM,QAAQ,SAAS,EAAG,OAAM,KAAK,GAAG,gBAAgB,SAAS,CAAC;AAAA,EACxE;AACA,QAAM,WAAW,MAAM,UAAU;AACjC,MAAI,MAAM,QAAQ,QAAQ,GAAG;AAC3B,eAAW,WAAW,UAAU;AAC9B,UAAI,SAAS,OAAO,EAAG,OAAM,KAAK,GAAG,aAAa,OAAO,CAAC;AAAA,IAC5D;AAAA,EACF;AACA,SAAO,OAAO,KAAK;AACrB;AAEA,SAAS,gBAAgB,KAAa,OAA4C;AAChF,MAAI,CAAC,wBAAwB,KAAK,KAAK,EAAG,QAAO;AACjD,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAE7B,MAAI,MAAM,YAAY,OAAO,CAAC,iBAAiB,aAAa,OAAO,UAAU,UAAU,CAAC;AACxF,MAAI,CAAC,OAAO,SAAS,MAAM,WAAW,CAAC,GAAG;AACxC,UAAM,YAAY,MAAM,WAAW,GAAG,CAAC,QAAQ,UAAU,KAAK,CAAC;AAAA,EACjE;AACA,MAAI,CAAC,IAAK,OAAM;AAEhB,MAAI,SAAS,YAAY,OAAO,CAAC,SAAS,QAAQ,UAAU,WAAW,MAAM,CAAC;AAC9E,MAAI,CAAC,OAAQ,UAAS,iBAAiB,MAAM,UAAU,CAAC;AACxD,MAAI,CAAC,OAAQ,QAAO;AAEpB,SAAO;AAAA,IACL,MAAM,eAAe,KAAK;AAAA,IAC1B;AAAA,IACA,YAAY,CAAC,UAAU,MAAM,CAAC;AAAA,IAC9B,cAAc,aAAa,KAAK;AAAA,EAClC;AACF;AAEA,SAAS,YAAY,KAAqB;AACxC,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,WAAO,4BAAS,GAAG,EAAE,KAAK;AAChC,SAAO,QAAQ,SAAS,OAAO,SAAS,MAAM,OAAO;AACvD;AAIA,IAAM,cAAc,oBAAI,IAAI;AAAA,EAC1B;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AAAA,EAAK;AACvF,CAAC;AAED,SAAS,WAAW,OAAuB;AACzC,MAAI,QAAQ;AACZ,MAAI,MAAM,MAAM;AAChB,SAAO,QAAQ,OAAO,YAAY,IAAI,MAAM,KAAK,CAAE,EAAG,UAAS;AAC/D,SAAO,MAAM,SAAS,YAAY,IAAI,MAAM,MAAM,CAAC,CAAE,EAAG,QAAO;AAC/D,SAAO,MAAM,MAAM,OAAO,GAAG;AAC/B;AAEA,IAAM,kBAAkB,oBAAI,IAAI;AAAA,EAC9B;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAC7D;AAAA,EAAO;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EACzD;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EACxD;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EACxD;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAU;AAAA,EAAS;AACrD,CAAC;AAGD,SAAS,iBACP,UACA,UACM;AACN,QAAM,aAAa,oBAAI,IAAoB;AAC3C,QAAM,aAAa,oBAAI,IAAoB;AAE3C,aAAW,WAAW,UAAU;AAC9B,eAAW,UAAU,QAAQ,YAAY;AACvC,YAAM,QAAQ,oBAAI,IAAY;AAC9B,iBAAW,SAAS,OAAO,YAAY,EAAE,MAAM,KAAK,GAAG;AACrD,cAAM,UAAU,WAAW,KAAK;AAChC,YAAI,QAAQ,UAAU,KAAK,CAAC,gBAAgB,IAAI,OAAO,KAAK,WAAC,aAAS,GAAC,EAAC,KAAK,OAAO,GAAG;AACrF,gBAAM,IAAI,OAAO;AAAA,QACnB;AAAA,MACF;AACA,iBAAW,QAAQ,OAAO;AACxB,mBAAW,IAAI,OAAO,WAAW,IAAI,IAAI,KAAK,KAAK,CAAC;AACpD,YAAI,QAAQ,MAAM;AAChB,gBAAM,OAAO,WAAW,IAAI,IAAI;AAChC,cAAI,SAAS,UAAa,QAAQ,OAAO,KAAM,YAAW,IAAI,MAAM,QAAQ,IAAI;AAAA,QAClF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,aAAW,CAAC,MAAM,KAAK,KAAK,YAAY;AACtC,QAAI,SAAS,sBAAsB,CAAC,SAAS,IAAI,IAAI,GAAG;AACtD,eAAS,IAAI,MAAM;AAAA,QACjB,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,SAAS,CAAC;AAAA,QACV,SAAS,0BAA0B,KAAK;AAAA,QACxC,MAAM,CAAC,UAAU,SAAS,UAAU;AAAA,QACpC,aAAa,WAAW,IAAI,IAAI,KAAK;AAAA,MACvC,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAIA,SAAS,sBAAsB,YAA2B,MAA4B;AACpF,QAAM,OAAO,aAAa,iBAAiB;AAC3C,MAAI,SAAS,QAAQ,CAACD,OAAM,IAAI,GAAG;AACjC,WAAO,EAAE,UAAU,CAAC,GAAG,UAAU,CAAC,GAAG,kBAAkB,CAAC,GAAG,kBAAkB,EAAE;AAAA,EACjF;AAEA,QAAM,WAAkC,CAAC;AACzC,QAAM,iBAAiB,oBAAI,IAAgC;AAC3D,QAAM,mBAA6B,CAAC;AACpC,MAAI,mBAAmB;AACvB,QAAM,gBAAgB,oBAAI,IAAoB;AAE9C,aAAW,UAAU,aAAa,IAAI,GAAG;AACvC,qBAAiB,KAAK,MAAM;AAC5B,UAAM,EAAE,SAAS,UAAU,IAAI,cAAc,MAAM;AACnD,wBAAoB;AACpB,eAAW,CAAC,KAAK,KAAK,KAAK,SAAS;AAClC,YAAM,gBAAgB,gBAAgB,KAAK,KAAK;AAChD,UAAI,kBAAkB,KAAM;AAC5B,eAAS,KAAK,aAAa;AAE3B,YAAM,OAAO,YAAY,cAAc,GAAG;AAC1C,UAAI,CAAC,KAAM;AAEX,YAAM,OAAO,cAAc,IAAI,IAAI,KAAK;AACxC,UAAI,CAAC,cAAc,IAAI,IAAI,KAAM,cAAc,QAAQ,cAAc,OAAO,MAAO;AACjF,sBAAc,IAAI,MAAM,cAAc,IAAI;AAAA,MAC5C;AACA,YAAM,WAAW,eAAe,IAAI,IAAI;AACxC,YAAM,WAAW,IAAI,IAAY,cAAc,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;AAC7E,UAAI,UAAU;AACZ,mBAAW,KAAK,SAAS,QAAS,UAAS,IAAI,CAAC;AAAA,MAClD;AACA,qBAAe,IAAI,MAAM;AAAA,QACvB,MAAM,UAAU,MAAM,GAAG;AAAA,QACzB,YAAY;AAAA,QACZ,SAAS,CAAC,GAAG,QAAQ,EAAE,KAAK;AAAA,QAC5B,SAAS,UAAU,kCAAkC,cAAc,GAAG,GAAG;AAAA,QACzE,MAAM,CAAC,UAAU,aAAa,QAAQ;AAAA,QACtC,aAAa,cAAc,IAAI,IAAI,KAAK;AAAA,MAC1C,CAAC;AAAA,IACH;AAAA,EACF;AAEA,mBAAiB,UAAU,cAAc;AACzC,WAAS,KAAK,CAAC,GAAG,MAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE,OAAO,KAAK,CAAE;AAExE,SAAO;AAAA,IACL;AAAA,IACA,UAAU,CAAC,GAAG,eAAe,OAAO,CAAC;AAAA,IACrC;AAAA,IACA;AAAA,EACF;AACF;AAKA,SAAS,eAAe,MAA8C;AACpE,MAAI,CAACC,QAAO,IAAI,EAAG,QAAO,CAAC;AAC3B,MAAI;AACJ,MAAI;AACF,UAAM,UAAM,8BAAa,MAAM,MAAM,EAAE,QAAQ,WAAW,EAAE;AAC5D,cAAU,KAAK,MAAM,GAAG;AAAA,EAC1B,QAAQ;AAEN,WAAO,CAAC;AAAA,EACV;AACA,MAAI,CAAC,SAAS,OAAO,EAAG,QAAO,CAAC;AAChC,QAAM,UAAU,QAAQ,SAAS;AACjC,MAAI,CAAC,MAAM,QAAQ,OAAO,EAAG,QAAO,CAAC;AACrC,SAAO,QAAQ;AAAA,IACb,CAAC,MAAoC,SAAS,CAAC,KAAK,QAAQ,EAAE,WAAW,CAAC;AAAA,EAC5E;AACF;AAGA,SAAS,qBACP,eACA,YACe;AACf,QAAM,QAAkB,CAAC;AACzB,MAAI,eAAe;AACjB,UAAM,SAAK,wBAAK,eAAe,WAAW,UAAU,kBAAkB,CAAC;AAAA,EACzE;AACA,QAAM,aAAa,QAAQ,IAAI,aAAa,QAAQ,IAAI,aAAa;AACrE,QAAMC,YAAW,kBAAc,wBAAKH,SAAQ,GAAG,SAAS;AACxD,QAAM,SAAK,wBAAKG,WAAU,UAAU,kBAAkB,CAAC;AAEvD,QAAM,SAAS,oBAAI,IAAqC;AACxD,aAAW,QAAQ,OAAO;AACxB,eAAW,SAAS,eAAe,IAAI,GAAG;AACxC,YAAM,MAAM,OAAO,MAAM,WAAW,CAAC,EAAE,KAAK,EAAE,YAAY;AAC1D,aAAO,IAAI,KAAK,KAAK;AAAA,IACvB;AAAA,EACF;AAEA,QAAM,WAA0B,CAAC;AACjC,aAAW,SAAS,OAAO,OAAO,GAAG;AACnC,UAAM,UACJ,MAAM,YAAY,MAAM,SAAY,MAAM,YAAY,IAAK,MAAM,WAAW,KAAK;AACnF,UAAM,OAAO,OAAO,OAAO,EAAE,KAAK;AAClC,QAAI,CAAC,KAAM;AAEX,UAAM,aACJ,cAAc,QAAQ,MAAM,UAAU,IAAI,aAAa,QAAQ,MAAM,SAAS,IAAI,CAAC;AACrF,UAAM,UAAU,MAAM,QAAQ,UAAU,IACpC,WAAW,IAAI,CAAC,MAAM,OAAO,CAAC,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,IAClE,CAAC;AAEL,UAAM,UAAU,OAAO,MAAM,SAAS,KAAK,EAAE,EAAE,KAAK;AAEpD,UAAM,UAAU,MAAM,MAAM,KAAK,CAAC;AAClC,UAAM,OAAO,MAAM,QAAQ,OAAO,IAC9B,QAAQ,IAAI,CAAC,MAAM,OAAO,CAAC,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,IAC/D,CAAC;AACL,SAAK,KAAK,aAAa;AAEvB,UAAM,SAAS,OAAO,MAAM,cAAc,KAAK,MAAM,EAAE,KAAK,EAAE,YAAY;AAC1E,UAAM,aACJ,WAAW,YACP,sBAAW,UACX,WAAW,WACT,sBAAW,SACX,sBAAW;AAEnB,UAAM,cAAc,OAAO,MAAM,cAAc,KAAK,EAAE;AAEtD,aAAS;AAAA,UACP,uBAAW;AAAA,QACT;AAAA,QACA,MAAM;AAAA,QACN;AAAA,QACA,SAAS,WAAW;AAAA,QACpB;AAAA,QACA,cAAc,eAAe;AAAA,QAC7B;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAIA,SAAS,UAAU,KAAwC;AACzD,aAAO,wBAAY;AAAA,IACjB,MAAM,IAAI,QAAQ;AAAA,IAClB,KAAK,IAAI,OAAO;AAAA,IAChB,eAAe,CAAC;AAAA,IAChB,aAAa,CAAC,GAAG,IAAI,UAAU;AAAA,IAC/B,eAAe,CAAC,GAAG,IAAI,YAAY;AAAA,EACrC,CAAC;AACH;AAEA,SAAS,SAAS,KAAsC;AACtD,aAAO,uBAAW;AAAA,IAChB,MAAM,IAAI;AAAA,IACV,MAAM,IAAI,cAAc;AAAA,IACxB,SAAS,CAAC,GAAG,IAAI,OAAO;AAAA,IACxB,SAAS,IAAI,WAAW;AAAA,IACxB,MAAM,CAAC,GAAG,IAAI,IAAI;AAAA,IAClB,cAAc,IAAI,eAAe;AAAA,EACnC,CAAC;AACH;AAGA,SAAS,gBAAwB;AAC/B,UAAO,oBAAI,KAAK,GAAE,YAAY,EAAE,QAAQ,aAAa,QAAQ;AAC/D;AAKO,IAAM,oBAAN,MAAsD;AAAA,EAC3D,UAAUP;AAAA,EACV,YAAYC;AAAA,EAEK;AAAA,EACA;AAAA,EACA,SAAgCE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQjD,OAAO,kBAAkB,MAAuB;AAC9C,eAAO,wBAAK,QAAQC,SAAQ,GAAG,SAAS;AAAA,EAC1C;AAAA,EAEA,YAAY,WAA2B,eAA+B;AACpE,SAAK,YAAY,aAAa;AAC9B,SAAK,gBAAgB,iBAAiB;AAAA,EACxC;AAAA,EAEA,IAAI,aAAqB;AACvB,UAAM,OAAO,KAAK,aAAa,iBAAiB;AAChD,WAAO,QAAQ;AAAA,EACjB;AAAA,EAEA,WAAuB;AACrB,UAAM,OAAO,KAAK,aAAa,iBAAiB;AAChD,QAAI,SAAS,QAAQ,CAACC,OAAM,IAAI,GAAG;AACjC,YAAM,IAAI;AAAA,QACR,sCAAsC,SAAS,OAAO,SAAS,IAAI,IAAI,GAAG;AAAA,MAG5E;AAAA,IACF;AACA,UAAM,MAAM,aAAa,IAAI;AAC7B,UAAM,YAAY,IAAI,IAAI,CAAC,OAAO;AAChC,UAAI;AACJ,UAAI;AACF,mBAAO,0BAAS,EAAE,EAAE;AAAA,MACtB,QAAQ;AACN,eAAO;AAAA,MACT;AACA,aAAO,EAAE,MAAM,IAAI,YAAY,KAAK;AAAA,IACtC,CAAC;AAED,WAAO;AAAA,MACL;AAAA,MACA,SAAS;AAAA,MACT,UAAU;AAAA,QACR,kBAAkB,iBAAiB,KAAK;AAAA,QACxC,iBAAiB,IAAI;AAAA,QACrB,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF;AAAA,EAEA,eAAe,OAAc,QAAQ,KAAqB;AACxD,UAAM,WAAW,KAAK,QAAQ;AAC9B,UAAM,MAAsB,CAAC;AAC7B,UAAM,WAAW,QAAQ,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE,IAAI;AAC5D,eAAW,OAAO,SAAS,UAAU;AACnC,UAAI,YAAY,IAAI,QAAQ,IAAI,OAAO,SAAU;AACjD,UAAI,KAAK,UAAU,GAAG,CAAC;AACvB,UAAI,IAAI,UAAU,MAAO;AAAA,IAC3B;AACA,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,OAA+B;AACtC,UAAM,WAAW,KAAK,QAAQ;AAC9B,QAAI,WAAW,SAAS,SAAS,IAAI,SAAS;AAC9C,QAAI,OAAO;AACT,YAAM,WAAW,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE;AAChD,iBAAW,SAAS,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,QAAQ,QAAQ;AAAA,IACjE;AAEA,UAAM,WAAW,SAAS,SAAS,IAAI,QAAQ;AAC/C,UAAM,qBAAqB,qBAAqB,KAAK,eAAe,KAAK,SAAS;AAClF,UAAM,YAAY,IAAI,IAAI,SAAS,IAAI,CAAC,MAAM,EAAE,KAAK,YAAY,CAAC,CAAC;AACnE,eAAW,MAAM,oBAAoB;AACnC,YAAM,MAAM,GAAG,KAAK,YAAY;AAChC,UAAI,CAAC,UAAU,IAAI,GAAG,GAAG;AACvB,iBAAS,KAAK,EAAE;AAChB,kBAAU,IAAI,GAAG;AAAA,MACnB;AAAA,IACF;AACA,UAAM,sBAAkB,gCAAoB,UAAU,KAAK,MAAM;AAEjE,eAAO,yBAAa;AAAA,MAClB,cAAc;AAAA,MACd,WAAO,0BAAc;AAAA,QACnB,IAAIL;AAAA,QACJ,MAAMC;AAAA,QACN,gBAAgBC;AAAA,QAChB,qBAAqB;AAAA,MACvB,CAAC;AAAA,MACD,cAAc,cAAc;AAAA,MAC5B,cAAc,CAAC,oBAAoB,iBAAiB;AAAA,MACpD,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,mBAAmB,KAAK;AAAA,IAC1B,CAAC;AAAA,EACH;AAAA,EAEA,cAA4B;AAC1B,UAAM,OAAO,KAAK,aAAa,iBAAiB;AAChD,QAAI,SAAS,MAAM;AACjB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,SAAS,CAAC;AAAA,QACV,aACE;AAAA,MAEJ;AAAA,IACF;AACA,QAAI,CAACG,OAAM,IAAI,GAAG;AAChB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ,wCAAwC,IAAI;AAAA,QACpD,SAAS,EAAE,eAAe,KAAK;AAAA,QAC/B,aACE;AAAA,MAEJ;AAAA,IACF;AACA,QAAI;AACJ,QAAI;AACF,iBAAW,KAAK,QAAQ;AAAA,IAC1B,SAAS,KAAK;AAEZ,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,SAAS,EAAE,OAAO,OAAO,GAAG,EAAE;AAAA,QAC9B,aACE;AAAA,MAGJ;AAAA,IACF;AACA,QAAI,SAAS,iBAAiB,WAAW,GAAG;AAC1C,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,SAAS,EAAE,KAAK;AAAA,QAChB,aACE;AAAA,MAEJ;AAAA,IACF;AACA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,mBAAmB,SAAS,iBAAiB;AAAA,QAC7C,oBAAoB,SAAS,SAAS;AAAA,QACtC,oBAAoB,SAAS,SAAS;AAAA,QACtC,mBAAmB,SAAS;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,UAAgC;AACtC,WAAO,sBAAsB,KAAK,SAAS;AAAA,EAC7C;AACF;;;ACzuBA,IAAAG,kBAAiE;AACjE,IAAAC,kBAAkC;AAClC,IAAAC,oBAAqB;AAErB,IAAAC,eAAmC;AAEnC,IAAAC,aAYO;AACP,IAAAC,oBAA2B;AAU3B,IAAMC,YAAW;AACjB,IAAMC,cAAa;AACnB,IAAMC,gBAAe;AACrB,IAAMC,kBACJ;AAMF,IAAM,sBAAsB;AAC5B,IAAM,kBAAkB;AAGxB,IAAMC,oBAAmB;AACzB,IAAMC,qBAAoB;AAE1B,IAAMC,sBAAwC,iCAAqB;AAAA,EACjE,SAAS,sBAAW;AAAA,EACpB,cAAc,CAAC,YAAY,aAAa,cAAc,UAAU,UAAU,OAAO;AAAA,EACjF,WAAW,CAAC,kBAAkB,aAAa,SAAS;AACtD,CAAC;AAID,IAAM,SAAS;AAAA,EACb,KAAK,KAAmB;AAEtB,YAAQ,KAAK,0BAA0B,GAAG,EAAE;AAAA,EAC9C;AACF;AAuBA,SAASC,WAAkB;AAGzB,MAAI;AACF,eAAO,yBAAQ;AAAA,EACjB,QAAQ;AACN,WAAO,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe;AAAA,EACxD;AACF;AAEA,SAASC,OAAM,GAAoB;AACjC,MAAI;AACF,eAAO,0BAAS,CAAC,EAAE,YAAY;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASC,QAAO,GAAoB;AAClC,MAAI;AACF,eAAO,0BAAS,CAAC,EAAE,OAAO;AAAA,EAC5B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AASO,SAAS,2BAAmC;AACjD,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,IAAK,QAAO;AAChB,aAAO,wBAAKF,SAAQ,GAAG,mBAAmB;AAC5C;AAGO,SAAS,yBAAyB,YAAoC;AAC3E,aAAO,wBAAK,cAAc,yBAAyB,GAAG,eAAe;AACvE;AAQA,SAAS,UAAU,GAAoB;AACrC,MAAI,aAAa,KAAM,QAAO,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AACzD,SAAO,OAAO,CAAC;AACjB;AAGA,SAAS,WAAW,GAAgC;AAClD,QAAM,IAAI,UAAW,KAAiB,EAAE;AACxC,SAAO,KAAK;AACd;AAGA,SAAS,QAAQ,GAAsB;AACrC,MAAI,CAAC,MAAM,QAAQ,CAAC,EAAG,QAAO,CAAC;AAC/B,SAAO,EAAE,OAAO,CAAC,MAAmB,OAAO,MAAM,YAAY,EAAE,KAAK,MAAM,EAAE;AAC9E;AAEA,SAASG,UAAS,GAA0C;AAC1D,SAAO,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC;AAChE;AAEA,SAAS,QAAQ,GAAuB;AACtC,SAAO,MAAM,QAAQ,CAAC,IAAI,IAAI,CAAC;AACjC;AASA,SAASC,kBAAiB,MAAc,QAA0C;AAChF,MAAI,CAAC,KAAK,WAAWC,iBAAgB,EAAG,QAAO,CAAC;AAChD,QAAM,MAAM,KAAK,QAAQC,oBAAmBD,kBAAiB,MAAM;AACnE,MAAI,QAAQ,GAAI,QAAO,CAAC;AACxB,QAAM,SAAS,KAAK,MAAMA,kBAAiB,QAAQ,GAAG;AACtD,MAAI;AACJ,MAAI;AACF,iBAAS,aAAAE,OAAU,MAAM;AAAA,EAC3B,SAAS,KAAK;AACZ,UAAM,QAAQ,SAAS,OAAO,MAAM,KAAK;AACzC,UAAM,SAAS,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,MAAM,GAAG,GAAG;AAC3D,WAAO;AAAA,MACL,iDAAiD,KAAK,iCACrB,MAAM;AAAA,IACzC;AACA,WAAO,CAAC;AAAA,EACV;AACA,SAAOJ,UAAS,MAAM,IAAI,SAAS,CAAC;AACtC;AAMA,SAAS,eAAe,MAAuC;AAC7D,MAAI,CAACD,QAAO,IAAI,EAAG,QAAO,CAAC;AAC3B,MAAI;AACJ,MAAI;AACF,eAAO,8BAAa,MAAM,MAAM;AAAA,EAClC,SAAS,KAAK;AACZ,WAAO,KAAK,mCAAmC,IAAI,KAAK,OAAO,GAAG,CAAC,EAAE;AACrE,WAAO,CAAC;AAAA,EACV;AACA,SAAOE,kBAAiB,MAAM,IAAI;AACpC;AAMA,SAAS,YAAY,KAAkC;AACrD,MAAI,CAACD,UAAS,GAAG,EAAG,QAAO;AAC3B,QAAM,OAAO,IAAI,MAAM;AACvB,MAAI,OAAO,SAAS,YAAY,KAAK,KAAK,MAAM,GAAI,QAAO;AAE3D,QAAM,aAAa,IAAI,SAAS,KAAK;AACrC,QAAM,UAAU,iBAAa,8BAAW,UAAU,UAAU,CAAC,IAAI;AAEjE,aAAO,uBAAW;AAAA,IAChB,MAAM,KAAK,KAAK;AAAA,IAChB,MAAM,WAAW,IAAI,MAAM,CAAC;AAAA,IAC5B,SAAS,QAAQ,IAAI,SAAS,CAAC;AAAA,IAC/B;AAAA,IACA,cAAc,WAAW,IAAI,cAAc,CAAC;AAAA,IAC5C,MAAM,QAAQ,IAAI,MAAM,CAAC;AAAA,IACzB,YAAY,WAAW,IAAI,YAAY,CAAC;AAAA,IACxC,UAAU,WAAW,IAAI,UAAU,CAAC;AAAA,EACtC,CAAC;AACH;AAIA,SAASK,cAAa,KAAmC;AACvD,MAAI,CAACL,UAAS,GAAG,EAAG,QAAO;AAC3B,QAAM,UAAU,IAAI,MAAM;AAC1B,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,UAAU,UAAU,OAAO,EAAE,MAAM,GAAG,EAAE;AAE9C,aAAO,wBAAY;AAAA,IACjB,MAAM;AAAA,IACN,KAAK,WAAW,IAAI,KAAK,CAAC;AAAA,IAC1B,eAAe,QAAQ,IAAI,eAAe,CAAC;AAAA,IAC3C,aAAa,QAAQ,IAAI,aAAa,CAAC;AAAA,IACvC,eAAe,QAAQ,IAAI,eAAe,CAAC;AAAA,EAC7C,CAAC;AACH;AA2CO,IAAM,qBAAN,MAAuD;AAAA,EAC5D,UAAUM;AAAA,EACV,YAAYC;AAAA,EACZ,cAAcC;AAAA,EACd;AAAA;AAAA,EAGA,OAAO,kBAAkB,MAAuB;AAC9C,QAAI,SAAS,OAAW,YAAO,wBAAK,MAAM,mBAAmB;AAC7D,WAAO,yBAAyB;AAAA,EAClC;AAAA,EAEiB;AAAA,EAEjB,YAAY,YAA4B;AACtC,SAAK,aAAa,cAAc;AAChC,SAAK,aAAa,KAAK,cAAc,yBAAyB;AAAA,EAChE;AAAA,EAEA,WAAuB;AACrB,UAAM,OAAO,KAAK,cAAc,yBAAyB;AACzD,QAAI,CAACC,OAAM,IAAI,GAAG;AAChB,YAAM,IAAI;AAAA,QACR,8CAA8C,IAAI;AAAA,MAGpD;AAAA,IACF;AACA,UAAM,cAAU,wBAAK,MAAM,eAAe;AAC1C,WAAO;AAAA,MACL;AAAA,MACA,SAAS;AAAA,MACT,UAAU;AAAA,QACR,aAAa;AAAA,QACb,qBAAqBC,QAAO,OAAO;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,eAAe,OAAc,QAAQ,KAAqB;AACxD,UAAM,OAAO,KAAK,KAAK;AACvB,UAAM,WAAW,QAAQ,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE,IAAI;AAC5D,UAAM,WAA2B,CAAC;AAClC,eAAW,OAAO,QAAQ,KAAK,UAAU,CAAC,GAAG;AAC3C,YAAM,UAAUC,cAAa,GAAG;AAChC,UAAI,YAAY,KAAM;AACtB,UAAI,YAAY,QAAQ,QAAQ,QAAQ,OAAO,SAAU;AACzD,eAAS,KAAK,OAAO;AACrB,UAAI,SAAS,UAAU,MAAO;AAAA,IAChC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,OAA+B;AACtC,UAAM,OAAO,KAAK,KAAK;AAEvB,UAAM,WAA0B,CAAC;AACjC,eAAW,OAAO,QAAQ,KAAK,UAAU,CAAC,GAAG;AAC3C,YAAM,SAAS,YAAY,GAAG;AAC9B,UAAI,WAAW,KAAM,UAAS,KAAK,MAAM;AAAA,IAC3C;AACA,UAAM,sBAAkB,gCAAoB,UAAUC,eAAc;AAEpE,UAAM,WAAW,QAAQ,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE,IAAI;AAC5D,UAAM,WAA2B,CAAC;AAClC,eAAW,OAAO,QAAQ,KAAK,UAAU,CAAC,GAAG;AAC3C,YAAM,UAAUD,cAAa,GAAG;AAChC,UAAI,YAAY,KAAM;AACtB,UAAI,YAAY,QAAQ,QAAQ,QAAQ,OAAO,SAAU;AACzD,eAAS,KAAK,OAAO;AAAA,IACvB;AAEA,eAAO,yBAAa;AAAA,MAClB,cAAc;AAAA,MACd,WAAO,0BAAc;AAAA,QACnB,IAAIL;AAAA,QACJ,MAAMC;AAAA,QACN,cAAU,0BAAS,KAAK;AAAA,QACxB,qBAAqB,KAAK,YAAY;AAAA,QACtC,gBAAgBM;AAAA,MAClB,CAAC;AAAA,MACD,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,MACrC,cAAc,CAAC,qBAAqB,QAAQ,aAAa,mBAAmB;AAAA,MAC5E,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,mBAAmBD;AAAA,IACrB,CAAC;AAAA,EACH;AAAA,EAEA,cAA4B;AAC1B,UAAM,OAAO,KAAK,cAAc,yBAAyB;AACzD,QAAI,CAACH,OAAM,IAAI,GAAG;AAChB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QACE,wBAAwB,IAAI;AAAA,QAE9B,SAAS,EAAE,eAAe,KAAK;AAAA,QAC/B,aAAa;AAAA,MACf;AAAA,IACF;AACA,UAAM,cAAU,wBAAK,MAAM,eAAe;AAC1C,QAAI,CAACC,QAAO,OAAO,GAAG;AACpB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QACE,eAAe,OAAO;AAAA,QAExB,SAAS,EAAE,sBAAsB,QAAQ;AAAA,QACzC,aAAa;AAAA,MACf;AAAA,IACF;AACA,QAAI;AACJ,QAAI;AACF,aAAO,KAAK,KAAK;AAAA,IACnB,SAAS,KAAK;AACZ,aAAO,KAAK,2CAA2C,OAAO,GAAG,CAAC,EAAE;AACpE,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,SAAS,EAAE,OAAO,OAAO,GAAG,EAAE;AAAA,QAC9B,aACE,WAAW,OAAO;AAAA,MAGtB;AAAA,IACF;AACA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,aAAa;AAAA,QACb,cAAc,QAAQ,KAAK,UAAU,CAAC,EAAE;AAAA,QACxC,eAAe,QAAQ,KAAK,UAAU,CAAC,EAAE;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIQ,OAAgC;AACtC,WAAO,eAAe,yBAAyB,KAAK,UAAU,CAAC;AAAA,EACjE;AACF;;;AC3aA,IAAAI,kBAAyB;AACzB,IAAAC,kBAAkC;AAClC,IAAAC,oBAA8B;AAE9B,IAAAC,aAYO;AACP,IAAAC,oBAA2B;AAW3B,IAAMC,YAAW;AACjB,IAAMC,cAAa;AACnB,IAAMC,gBAAe;AACrB,IAAMC,kBACJ;AAMF,IAAMC,sBAAwC,iCAAqB;AAAA,EACjE,SAAS,sBAAW;AAAA,EACpB,cAAc,CAAC,YAAY,aAAa,cAAc,UAAU,UAAU,OAAO;AAAA,EACjF,WAAW,CAAC,eAAe,WAAW,YAAY,WAAW;AAC/D,CAAC;AAED,IAAM,cAAc;AACpB,IAAM,mBAAmB;AACzB,IAAMC,qBAAoB;AAC1B,IAAM,kBAAkB;AACxB,IAAM,uBAAuB;AAQtB,SAAS,uBAA+B;AAC7C,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,IAAK,QAAO;AAChB,aAAO,4BAAK,yBAAQ,GAAG,gBAAgB;AACzC;AAGA,SAAS,wBAAwB,YAAoC;AACnE,aAAO,wBAAK,cAAc,qBAAqB,GAAG,WAAW;AAC/D;AAEA,SAASC,QAAO,GAAoB;AAClC,MAAI;AACF,eAAO,0BAAS,CAAC,EAAE,OAAO;AAAA,EAC5B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASC,OAAM,GAAoB;AACjC,MAAI;AACF,eAAO,0BAAS,CAAC,EAAE,YAAY;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,SAAS,qBAAqB,OAAe,QAAQ,KAAa;AAChE,aAAO,8BAAW,OAAO,KAAK;AAChC;AAOA,SAASC,SAAQ,OAAe,OAAuB;AACrD,QAAM,aAAa,MAAM,MAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAC9D,MAAI,WAAW,UAAU,MAAO,QAAO;AACvC,SAAO,WAAW,MAAM,GAAG,QAAQ,CAAC,EAAE,QAAQ,QAAQ,EAAE,IAAI;AAC9D;AAMA,SAAS,QACP,IACA,KACA,SAAoB,CAAC,GACW;AAChC,MAAI;AACF,WAAO,GAAG,QAAQ,GAAG,EAAE,IAAI,GAAG,MAAM;AAAA,EACtC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,SAAS,gBAAgB,IAAoB,OAAuD;AAClG,MAAI,MAAM;AACV,QAAM,SAAoB,CAAC;AAC3B,MAAI,OAAO;AACT,WAAO;AACP,WAAO,KAAK,KAAK;AAAA,EACnB;AACA,SAAO;AACP,SAAO,QAAQ,IAAI,KAAK,MAAM;AAChC;AAEA,SAAS,oBAAoB,IAAoB,WAA6B;AAC5E,QAAM,OAAO;AAAA,IACX;AAAA,IACA;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AACA,QAAM,MAAgB,CAAC;AACvB,aAAW,KAAK,MAAM;AACpB,UAAM,KAAK,EAAE,WAAW;AACxB,QAAI,GAAI,KAAI,KAAK,OAAO,EAAE,CAAC;AAAA,EAC7B;AACA,SAAO;AACT;AAEA,SAAS,mBACP,IACA,WACgD;AAChD,QAAM,OAAO;AAAA,IACX;AAAA,IACA;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AACA,SAAO,KAAK,IAAI,CAAC,OAAO;AAAA,IACtB,UAAU,OAAO,EAAE,UAAU,KAAK,EAAE;AAAA,IACpC,WAAW,OAAO,EAAE,WAAW,KAAK,EAAE;AAAA,EACxC,EAAE;AACJ;AAEA,SAAS,mBAAmB,IAAoB,WAAmD;AACjG,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IAEA,CAAC,SAAS;AAAA,EACZ;AACF;AAEA,SAAS,sBAAsB,IAAoD;AACjF,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EAEF;AACF;AAEA,SAAS,iBAAiB,IAAoB,WAA2B;AACvE,QAAM,OAAO,QAAQ,IAAI,0DAA0D,CAAC,SAAS,CAAC;AAC9F,QAAM,QAAQ,KAAK,CAAC;AACpB,SAAO,QAAQ,OAAO,MAAM,KAAK,KAAK,CAAC,KAAK,IAAI;AAClD;AAIA,SAAS,iBACP,KACA,OACA,MACA,aACA,WACc;AACd,QAAM,UAAU,IAAI,YAAY,IAAI,OAAO,IAAI,YAAY,CAAC,IAAI;AAChE,QAAM,UAAU,UAAU,QAAQ,MAAM,GAAG,EAAE,IAAI;AAEjD,QAAMC,cAAuB,CAAC;AAC9B,MAAI,IAAI,SAAS,GAAG;AAClB,IAAAA,YAAW,KAAKD,SAAQ,qBAAqB,OAAO,IAAI,SAAS,CAAC,CAAC,GAAG,oBAAoB,CAAC;AAAA,EAC7F;AACA,aAAW,MAAM,YAAY,MAAM,GAAG,CAAC,GAAG;AACxC,QAAI,GAAG,OAAO,GAAG;AACf,MAAAC,YAAW;AAAA,QACTD,SAAQ,eAAe,qBAAqB,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,oBAAoB;AAAA,MAC1F;AAAA,IACF;AAAA,EACF;AACA,MAAI,WAAW;AACb,IAAAC,YAAW,KAAK,UAAU,SAAS,EAAE;AAAA,EACvC;AACA,aAAW,OAAO,KAAK,MAAM,GAAG,CAAC,GAAG;AAClC,UAAM,WAAW,GAAG,IAAI,QAAQ,KAAK,IAAI,SAAS;AAClD,IAAAA,YAAW,KAAKD,SAAQ,UAAU,oBAAoB,CAAC;AAAA,EACzD;AAEA,QAAM,eAAyB,CAAC;AAChC,MAAI,IAAI,YAAY,EAAG,cAAa,KAAK,OAAO,IAAI,YAAY,CAAC,CAAC;AAElE,aAAO,wBAAY;AAAA,IACjB,MAAM;AAAA,IACN,KAAK,IAAI,KAAK,IAAI,OAAO,IAAI,KAAK,CAAC,IAAI;AAAA,IACvC,eAAe;AAAA,IACf,aAAaC,YAAW,MAAM,GAAG,eAAe;AAAA,IAChD,eAAe,MAAM,MAAM,GAAG,EAAE;AAAA,IAChC,YAAY,sBAAW;AAAA,EACzB,CAAC;AACH;AAEA,SAAS,+BACP,UACA,gBACe;AACf,QAAM,WAAW,oBAAI,IAAyB;AAG9C,aAAW,OAAO,UAAU;AAC1B,UAAM,OAAO,IAAI,YAAY,IAAI,OAAO,IAAI,YAAY,CAAC,IAAI;AAC7D,QAAI,QAAQ,CAAC,SAAS,IAAI,IAAI,GAAG;AAC/B,YAAM,UAAU,IAAI,YAAY,IAAI,OAAO,IAAI,YAAY,CAAC,IAAI;AAChE,YAAM,cAAc,QAAQ,MAAM,GAAG,EAAE,KAAK;AAC5C,eAAS;AAAA,QACP;AAAA,YACA,uBAAW;AAAA,UACT,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,cAAc,eAAe;AAAA,UAC7B,MAAM,CAAC,eAAe,SAAS;AAAA,UAC/B,YAAY,sBAAW;AAAA,QACzB,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAGA,aAAW,OAAO,gBAAgB;AAChC,UAAM,OAAO,IAAI,MAAM,IAAI,OAAO,IAAI,MAAM,CAAC,IAAI;AACjD,QAAI,CAAC,QAAQ,SAAS,IAAI,IAAI,EAAG;AACjC,UAAM,OAAO,IAAI,aAAa,IAAI,OAAO,IAAI,aAAa,CAAC,IAAI;AAC/D,UAAM,UAAU,IAAI,SAAS,IAAI,OAAO,IAAI,SAAS,CAAC,IAAI;AAC1D,QAAI,cAAc,QAAQ;AAC1B,QAAI,aAAa;AACf,oBAAcD,SAAQ,qBAAqB,WAAW,GAAGH,kBAAiB;AAAA,IAC5E;AACA,aAAS;AAAA,MACP;AAAA,UACA,uBAAW;AAAA,QACT;AAAA,QACA,MAAM;AAAA,QACN,SAAS,eAAe;AAAA,QACxB,cAAc;AAAA,QACd,MAAM,CAAC,eAAe,mBAAmB,IAAI,KAAK,IAAI,OAAO,IAAI,KAAK,CAAC,IAAI,SAAS;AAAA,QACpF,YAAY,sBAAW;AAAA,MACzB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO,CAAC,GAAG,SAAS,OAAO,CAAC;AAC9B;AAGA,SAAS,SAAS,GAAiB;AACjC,SAAO,EAAE,YAAY,EAAE,QAAQ,aAAa,QAAQ,EAAE,QAAQ,MAAM,QAAQ;AAC9E;AAQO,IAAM,wBAAN,MAA0D;AAAA,EAC/D,UAAUL;AAAA,EACV,YAAYC;AAAA,EACZ,cAAcC;AAAA,EACd;AAAA,EAEiB;AAAA;AAAA,EAGjB,OAAO,kBAAkB,MAAuB;AAC9C,QAAI,KAAM,YAAO,wBAAK,MAAM,gBAAgB;AAC5C,WAAO,qBAAqB;AAAA,EAC9B;AAAA,EAEA,YAAY,YAAqB;AAC/B,SAAK,aAAa,cAAc;AAChC,SAAK,aAAa,KAAK,cAAc,qBAAqB;AAAA,EAC5D;AAAA;AAAA,EAIA,WAAuB;AACrB,UAAM,SAAS,wBAAwB,KAAK,UAAU;AACtD,QAAI,CAACI,QAAO,MAAM,GAAG;AACnB,YAAM,IAAI;AAAA,QACR,6CAA6C,MAAM;AAAA,MAErD;AAAA,IACF;AACA,QAAI,SAAS;AACb,QAAI;AACF,mBAAS,0BAAS,MAAM,EAAE;AAAA,IAC5B,QAAQ;AACN,eAAS;AAAA,IACX;AACA,WAAO;AAAA,MACL,UAAM,2BAAQ,MAAM;AAAA,MACpB,SAAS;AAAA,MACT,UAAU,EAAE,SAAS,QAAQ,eAAe,OAAO;AAAA,IACrD;AAAA,EACF;AAAA,EAEA,eAAe,OAAc,QAAQ,KAAqB;AACxD,UAAM,SAAS,wBAAwB,KAAK,UAAU;AACtD,UAAM,KAAK,gBAAgB,MAAM;AACjC,QAAI,CAAC,GAAI,QAAO,CAAC;AACjB,QAAI;AACF,YAAM,WAAW,QAAQ,SAAS,KAAK,IAAI;AAC3C,YAAM,cAAc,gBAAgB,IAAI,QAAQ;AAChD,YAAM,WAA2B,CAAC;AAClC,iBAAW,OAAO,YAAY,MAAM,GAAG,KAAK,GAAG;AAC7C,cAAM,MAAM,OAAO,IAAI,IAAI,CAAC;AAC5B,cAAM,QAAQ,oBAAoB,IAAI,GAAG;AACzC,cAAM,OAAO,mBAAmB,IAAI,GAAG;AACvC,cAAM,cAAc,mBAAmB,IAAI,GAAG;AAC9C,cAAM,YAAY,iBAAiB,IAAI,GAAG;AAC1C,iBAAS,KAAK,iBAAiB,KAAK,OAAO,MAAM,aAAa,SAAS,CAAC;AAAA,MAC1E;AACA,aAAO;AAAA,IACT,UAAE;AACA,SAAG,MAAM;AAAA,IACX;AAAA,EACF;AAAA,EAEA,SAAS,OAA+B;AACtC,UAAM,SAAS,wBAAwB,KAAK,UAAU;AACtD,UAAM,KAAK,gBAAgB,MAAM;AACjC,QAAI,CAAC,GAAI,QAAO,KAAK,cAAc;AACnC,QAAI;AACF,YAAM,WAAW,QAAQ,SAAS,KAAK,IAAI;AAC3C,YAAM,cAAc,gBAAgB,IAAI,QAAQ;AAChD,YAAM,iBAAiB,sBAAsB,EAAE;AAE/C,YAAM,WAA2B,CAAC;AAClC,iBAAW,OAAO,YAAY,MAAM,GAAG,GAAG,GAAG;AAC3C,cAAM,MAAM,OAAO,IAAI,IAAI,CAAC;AAC5B,cAAM,QAAQ,oBAAoB,IAAI,GAAG;AACzC,cAAM,OAAO,mBAAmB,IAAI,GAAG;AACvC,cAAM,cAAc,mBAAmB,IAAI,GAAG;AAC9C,cAAM,YAAY,iBAAiB,IAAI,GAAG;AAC1C,iBAAS,KAAK,iBAAiB,KAAK,OAAO,MAAM,aAAa,SAAS,CAAC;AAAA,MAC1E;AAEA,YAAM,WAAW,+BAA+B,aAAa,cAAc;AAC3E,YAAM,sBAAkB,gCAAoB,UAAUF,eAAc;AAEpE,iBAAO,yBAAa;AAAA,QAClB,cAAc;AAAA,QACd,WAAO,0BAAc;AAAA,UACnB,IAAIJ;AAAA,UACJ,MAAMC;AAAA,UACN,cAAU,0BAAS,KAAK;AAAA,UACxB,qBAAqB,KAAK,YAAY;AAAA,UACtC,gBAAgBE;AAAA,QAClB,CAAC;AAAA,QACD,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,QACrC,cAAc;AAAA,UACZ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,iBAAiB;AAAA,QACjB,gBAAgB;AAAA,QAChB,mBAAmBC;AAAA,MACrB,CAAC;AAAA,IACH,UAAE;AACA,SAAG,MAAM;AAAA,IACX;AAAA,EACF;AAAA,EAEA,cAA4B;AAC1B,QAAI;AACF,YAAM,aAAa,KAAK,cAAc,qBAAqB;AAC3D,UAAI,CAACG,OAAM,UAAU,GAAG;AACtB,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,QAAQ,sCAAsC,UAAU;AAAA,UACxD,SAAS,EAAE,eAAe,WAAW;AAAA,UACrC,aACE;AAAA,QAEJ;AAAA,MACF;AACA,YAAM,SAAS,wBAAwB,UAAU;AACjD,UAAI,CAACD,QAAO,MAAM,GAAG;AACnB,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,QAAQ,iCAAiC,MAAM;AAAA,UAC/C,SAAS,EAAE,aAAa,OAAO;AAAA,UAC/B,aACE;AAAA,QAEJ;AAAA,MACF;AACA,YAAM,KAAK,gBAAgB,MAAM;AACjC,UAAI,CAAC,IAAI;AACP,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,SAAS,EAAE,SAAS,OAAO;AAAA,UAC3B,aAAa;AAAA,QACf;AAAA,MACF;AACA,UAAI;AACF,cAAM,cAAc,gBAAgB,EAAE;AACtC,cAAM,iBAAiB,sBAAsB,EAAE;AAC/C,cAAM,aAAa,QAAQ,IAAI,mCAAmC;AAClE,cAAM,QAAQ,WAAW,CAAC;AAC1B,YAAI,SAAS;AACb,YAAI;AACF,uBAAS,0BAAS,MAAM,EAAE;AAAA,QAC5B,QAAQ;AACN,mBAAS;AAAA,QACX;AACA,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,SAAS;AAAA,YACT,eAAe;AAAA,YACf,eAAe,YAAY;AAAA,YAC3B,aAAa,QAAQ,OAAO,MAAM,KAAK,KAAK,CAAC,KAAK,IAAI;AAAA,YACtD,uBAAuB,eAAe;AAAA,UACxC;AAAA,QACF;AAAA,MACF,UAAE;AACA,WAAG,MAAM;AAAA,MACX;AAAA,IACF,SAAS,KAAK;AAEZ,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ,qBAAqB,OAAO,GAAG,CAAC;AAAA,QACxC,SAAS,CAAC;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIQ,gBAAiC;AACvC,eAAO,yBAAa;AAAA,MAClB,cAAc;AAAA,MACd,WAAO,0BAAc;AAAA,QACnB,IAAIN;AAAA,QACJ,MAAMC;AAAA,QACN,cAAU,0BAAS,KAAK;AAAA,QACxB,qBAAqB,KAAK,YAAY;AAAA,QACtC,gBAAgBE;AAAA,MAClB,CAAC;AAAA,MACD,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,MACrC,cAAc,CAAC;AAAA,MACf,iBAAiB,CAAC;AAAA,MAClB,gBAAgB,CAAC;AAAA,MACjB,mBAAmBC;AAAA,IACrB,CAAC;AAAA,EACH;AACF;;;AC5eA,IAAAM,kBAAiE;AACjE,IAAAC,kBAAwB;AACxB,IAAAC,oBAAqB;AAErB,IAAAC,eAAmC;AAEnC,IAAAC,aAYO;AACP,IAAAC,oBAAyD;AAYzD,IAAMC,YAAW;AACjB,IAAMC,cAAa;AACnB,IAAMC,gBAAe;AACrB,IAAMC,kBACJ;AAMF,IAAMC,uBAAsB;AAC5B,IAAMC,mBAAkB;AAExB,IAAMC,sBAAwC,iCAAqB;AAAA,EACjE,SAAS,sBAAW;AAAA,EACpB,cAAc,CAAC,YAAY,cAAc,aAAa,UAAU,SAAS;AAC3E,CAAC;AAQD,IAAM,6BAAgD;AAAA,EACpD,GAAG;AAAA,EACH;AAAA,EACA;AACF;AAGA,IAAMC,UAAS;AAAA,EACb,KAAK,KAAmB;AAEtB,YAAQ,KAAK,0BAA0B,GAAG,EAAE;AAAA,EAC9C;AACF;AAIA,SAASC,WAAkB;AAGzB,MAAI;AACF,eAAO,yBAAQ;AAAA,EACjB,QAAQ;AACN,WAAO,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe;AAAA,EACxD;AACF;AAEA,SAASC,OAAM,GAAoB;AACjC,MAAI;AACF,eAAO,0BAAS,CAAC,EAAE,YAAY;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASC,QAAO,GAAoB;AAClC,MAAI;AACF,eAAO,0BAAS,CAAC,EAAE,OAAO;AAAA,EAC5B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,oBAA4B;AAC1C,aAAO,wBAAKF,SAAQ,GAAGJ,oBAAmB;AAC5C;AAkBA,SAASO,kBAAiB,MAAc,QAA0C;AAChF,MAAI,CAAC,KAAK,WAAW,KAAK,EAAG,QAAO,CAAC;AACrC,QAAM,MAAM,KAAK,QAAQ,OAAO,CAAC;AACjC,MAAI,QAAQ,GAAI,QAAO,CAAC;AACxB,QAAM,YAAY,KAAK,MAAM,GAAG,GAAG,EAAE,KAAK;AAC1C,MAAI,CAAC,UAAW,QAAO,CAAC;AACxB,MAAI;AACJ,MAAI;AACF,eAAO,aAAAC,OAAU,SAAS;AAAA,EAC5B,SAAS,KAAK;AACZ,UAAM,QAAQ,SAAS,OAAO,MAAM,KAAK;AACzC,UAAM,SAAS,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,MAAM,GAAG,GAAG;AAC3D,IAAAC,QAAO;AAAA,MACL,iDAAiD,KAAK,iCACrB,MAAM;AAAA,IACzC;AACA,WAAO,CAAC;AAAA,EACV;AACA,SAAO,OAAO,SAAS,YAAY,SAAS,QAAQ,CAAC,MAAM,QAAQ,IAAI,IAClE,OACD,CAAC;AACP;AAUA,SAAS,gBAAgB,MAAsB;AAC7C,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI,2BAA2B,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,GAAG;AACxD,WAAO;AAAA,EACT;AACA,aAAO,8BAAW,IAAI;AACxB;AAKA,SAAS,OAAO,GAAsB;AACpC,MAAI,CAAC,EAAG,QAAO,CAAC;AAChB,MAAI,MAAM,QAAQ,CAAC,EAAG,QAAO;AAC7B,MAAI,OAAO,MAAM,SAAU,QAAO,MAAM,KAAK,CAAC;AAC9C,SAAO,CAAC;AACV;AAEA,SAASC,UAAS,GAA0C;AAC1D,SAAO,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC;AAChE;AAGA,SAASC,aAAY,KAAkC;AACrD,MAAI,CAACD,UAAS,GAAG,EAAG,QAAO;AAC3B,QAAM,OAAO,IAAI,MAAM;AACvB,MAAI,OAAO,SAAS,YAAY,CAAC,KAAK,KAAK,EAAG,QAAO;AAErD,MAAI;AACJ,QAAM,aAAa,IAAI,SAAS;AAChC,MAAI,OAAO,eAAe,SAAU,WAAU,gBAAgB,UAAU;AAExE,aAAO,uBAAW;AAAA,IAChB,MAAM,KAAK,KAAK;AAAA,IAChB,MAAM,OAAO,IAAI,MAAM,MAAM,WAAY,IAAI,MAAM,IAAe;AAAA,IAClE;AAAA,IACA,SAAS,OAAO,IAAI,SAAS,CAAC;AAAA,IAC9B,MAAM,OAAO,IAAI,MAAM,CAAC;AAAA,IACxB,cAAc,IAAI,cAAc,IAAI,OAAO,IAAI,cAAc,CAAC,IAAI;AAAA,IAClE,YAAY,IAAI,YAAY,IAAI,OAAO,IAAI,YAAY,CAAC,IAAI;AAAA,IAC5D,UAAU,IAAI,UAAU,IAAI,OAAO,IAAI,UAAU,CAAC,IAAI;AAAA,IACtD,YAAY;AAAA,EACd,CAAC;AACH;AAGA,SAASE,cAAa,KAAmC;AACvD,MAAI,CAACF,UAAS,GAAG,EAAG,QAAO;AAC3B,QAAM,UAAU,IAAI,MAAM;AAC1B,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,UAAU,OAAO,OAAO,EAAE,MAAM,GAAG,EAAE;AAE3C,aAAO,wBAAY;AAAA,IACjB,MAAM;AAAA,IACN,KAAK,IAAI,KAAK,KAAK,OAAO,SAAa,IAAI,KAAK;AAAA,IAChD,aAAa,OAAO,IAAI,aAAa,CAAC;AAAA,IACtC,eAAe,OAAO,IAAI,eAAe,CAAC;AAAA,IAC1C,eAAe,OAAO,IAAI,eAAe,CAAC;AAAA,IAC1C,YAAY;AAAA,EACd,CAAC;AACH;AAOA,SAAS,iBAAiB,MAA2B;AACnD,MAAI,CAAC,sBAAsB,KAAK,IAAI,EAAG,QAAO;AAC9C,QAAM,KAAK,KAAK,MAAM,GAAG,IAAI,YAAY;AACzC,SAAO,OAAO,MAAM,EAAE,IAAI,OAAO,IAAI,KAAK,EAAE;AAC9C;AAEA,SAAS,cAAc,aAAsB,OAA8B;AACzE,QAAM,OAAO,MAAM,QAAQ,WAAW,IAAI,cAAc,CAAC;AACzD,QAAM,WAA2B,CAAC;AAClC,aAAW,OAAO,MAAM;AACtB,UAAM,UAAUE,cAAa,GAAG;AAChC,QAAI,YAAY,KAAM;AACtB,QAAI,UAAU,QAAW;AACvB,YAAM,IAAI,iBAAiB,QAAQ,IAAI;AACvC,UAAI,MAAM,QAAQ,EAAE,QAAQ,IAAI,MAAM,QAAQ,EAAG;AAAA,IACnD;AACA,aAAS,KAAK,OAAO;AAAA,EACvB;AACA,SAAO;AACT;AAKA,SAAS,qBAAqB,YAA6C;AACzE,QAAM,iBAAa,wBAAK,YAAYC,gBAAe;AACnD,MAAI,CAACC,QAAO,UAAU,EAAG,QAAO,EAAE,SAAS,OAAO,OAAO,UAAU;AAEnE,MAAI;AACJ,MAAI;AACF,eAAO,8BAAa,YAAY,MAAM;AAAA,EACxC,SAAS,GAAG;AACV,WAAO,EAAE,SAAS,MAAM,UAAU,OAAO,OAAO,OAAO,CAAC,EAAE;AAAA,EAC5D;AAEA,QAAM,OAAOP,kBAAiB,MAAM,UAAU;AAC9C,MAAI,OAAO,KAAK,IAAI,EAAE,WAAW,GAAG;AAClC,WAAO;AAAA,MACL,SAAS;AAAA,MACT,UAAU;AAAA,MACV,mBAAmB;AAAA,MACnB,cAAc;AAAA,MACd,eAAe;AAAA,IACjB;AAAA,EACF;AAEA,QAAM,WAAW,KAAK,UAAU;AAChC,QAAM,WAAW,KAAK,UAAU;AAChC,SAAO;AAAA,IACL,SAAS;AAAA,IACT,UAAU;AAAA,IACV,mBAAmB;AAAA,IACnB,cAAc,MAAM,QAAQ,QAAQ,IAAI,SAAS,SAAS;AAAA,IAC1D,eAAe,MAAM,QAAQ,QAAQ,IAAI,SAAS,SAAS;AAAA,EAC7D;AACF;AAwDO,IAAM,qBAAN,MAAuD;AAAA,EAC5D,UAAUQ;AAAA,EACV,YAAYC;AAAA,EACZ,cAAcC;AAAA,EAEG;AAAA,EACA;AAAA,EAEjB,OAAO,kBAAkB,MAAuB;AAC9C,QAAI,SAAS,OAAW,YAAO,wBAAK,MAAMC,oBAAmB;AAC7D,WAAO,kBAAkB;AAAA,EAC3B;AAAA,EAEA,YAAY,YAAqB,QAAgC;AAC/D,SAAK,MAAM,cAAc,kBAAkB;AAC3C,SAAK,SAAS,UAAUC;AAAA,EAC1B;AAAA;AAAA,EAGA,IAAI,aAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,aAAqB;AAC3B,eAAO,wBAAK,KAAK,KAAKC,gBAAe;AAAA,EACvC;AAAA,EAEQ,kBAA2C;AACjD,UAAM,OAAO,KAAK,WAAW;AAC7B,QAAI,CAACC,QAAO,IAAI,EAAG,QAAO,CAAC;AAC3B,QAAI;AACJ,QAAI;AACF,iBAAO,8BAAa,MAAM,MAAM;AAAA,IAClC,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AACA,WAAOC,kBAAiB,MAAM,IAAI;AAAA,EACpC;AAAA,EAEA,WAAuB;AACrB,QAAI,CAACC,OAAM,KAAK,GAAG,GAAG;AACpB,YAAM,IAAI;AAAA,QACR,wCAAwC,KAAK,GAAG;AAAA,MAClD;AAAA,IACF;AACA,UAAM,gBAAgBF,QAAO,KAAK,WAAW,CAAC;AAC9C,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,SAAS;AAAA,MACT,UAAU;AAAA,QACR,aAAa,KAAK,WAAW;AAAA,QAC7B,qBAAqB;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,SAAS,OAA+B;AACtC,UAAM,OAAO,KAAK,gBAAgB;AAGlC,UAAM,cAAc,KAAK,UAAU;AACnC,UAAM,aAAa,MAAM,QAAQ,WAAW,IAAI,cAAc,CAAC;AAC/D,UAAM,WAA0B,CAAC;AACjC,eAAW,OAAO,YAAY;AAC5B,YAAM,SAASG,aAAY,GAAG;AAC9B,UAAI,WAAW,KAAM,UAAS,KAAK,MAAM;AAAA,IAC3C;AAGA,UAAM,WAAW,cAAc,KAAK,UAAU,GAAG,KAAK;AAGtD,UAAM,sBAAkB,gCAAoB,UAAU,KAAK,MAAM;AAEjE,eAAO,yBAAa;AAAA,MAClB,cAAc;AAAA,MACd,WAAO,0BAAc;AAAA,QACnB,IAAIT;AAAA,QACJ,MAAMC;AAAA,QACN,gBAAgBS;AAAA,MAClB,CAAC;AAAA,MACD,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,MACrC,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,cAAc,CAAC,QAAQ,gBAAgB,YAAY,YAAY,QAAQ;AAAA,IACzE,CAAC;AAAA,EACH;AAAA,EAEA,eAAe,OAAc,OAAgC;AAC3D,UAAM,OAAO,KAAK,gBAAgB;AAClC,UAAM,WAAW,cAAc,KAAK,UAAU,GAAG,KAAK;AACtD,aAAS,KAAK,CAAC,GAAG,MAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE,OAAO,KAAK,CAAE;AACxE,QAAI,UAAU,OAAW,QAAO,SAAS,MAAM,GAAG,KAAK;AACvD,WAAO;AAAA,EACT;AAAA,EAEA,cAA4B;AAC1B,QAAI,CAACF,OAAM,KAAK,GAAG,GAAG;AACpB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,SAAS,EAAE,eAAe,KAAK,IAAI;AAAA,QACnC,aACE;AAAA,MACJ;AAAA,IACF;AAEA,UAAM,SAAS,qBAAqB,KAAK,GAAG;AAC5C,QAAI,CAAC,OAAO,SAAS,GAAG;AACtB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,aACE;AAAA,MACJ;AAAA,IACF;AAEA,QAAI,CAAC,OAAO,UAAU,GAAG;AACvB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ,6BAA6B,OAAO,OAAO,OAAO,CAAC,CAAC;AAAA,QAC5D,SAAS;AAAA,QACT,aACE,uCAAmC,wBAAK,KAAK,KAAK,WAAW,CAAC;AAAA,MAElE;AAAA,IACF;AAEA,QAAI,CAAC,OAAO,mBAAmB,GAAG;AAChC,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,aACE,eAAW,wBAAK,KAAK,KAAK,WAAW,CAAC;AAAA,MAI1C;AAAA,IACF;AAEA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS;AAAA,IACX;AAAA,EACF;AACF;;;AC7cA,IAAAG,6BAA6B;AAC7B,IAAAC,kBAAwB;AACxB,IAAAC,oBAAqB;AAErB,IAAAC,aAYO;AACP,IAAAC,oBAA2B;AAY3B,IAAMC,YAAW;AACjB,IAAMC,cAAa;AACnB,IAAMC,gBAAe;AACrB,IAAMC,kBACJ;AAKK,IAAM,sBAAsB;AAEnC,IAAM,uBAAuB;AAE7B,IAAM,gBAAgB;AACtB,IAAM,eAAe;AAIrB,SAASC,UAAS,GAA0C;AAC1D,SAAO,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC;AAChE;AAOA,SAASC,sBAAqB,OAAuB;AACnD,aAAO,8BAAW,OAAO,GAAG;AAC9B;AAMA,SAAS,aAAa,OAAgC;AACpD,QAAM,QAAkB,CAAC;AACzB,aAAW,SAAS,OAAO,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG;AACzD,UAAM,QAAQ,SAAS,KAAK,KAAK;AACjC,QAAI,CAAC,MAAO;AACZ,UAAM,KAAK,OAAO,MAAM,CAAC,CAAC,CAAC;AAAA,EAC7B;AACA,SAAO,MAAM,SAAS,IAAI,QAAQ;AACpC;AAIA,SAAS,gBAAgB,GAAa,GAAsB;AAC1D,QAAM,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;AACrC,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG;AAC7B,UAAM,KAAK,IAAI,EAAE,SAAU,EAAE,CAAC,IAAe;AAC7C,UAAM,KAAK,IAAI,EAAE,SAAU,EAAE,CAAC,IAAe;AAC7C,QAAI,OAAO,OAAW,QAAO;AAC7B,QAAI,OAAO,OAAW,QAAO;AAC7B,QAAI,KAAK,GAAI,QAAO;AACpB,QAAI,KAAK,GAAI,QAAO;AAAA,EACtB;AACA,SAAO;AACT;AAGA,SAAS,cAAc,QAAyC;AAC9D,aAAW,OAAO,CAAC,WAAW,oBAAoB,aAAa,GAAG;AAChE,UAAM,QAAQ,OAAO,GAAG;AACxB,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAG,QAAO,MAAM,KAAK;AAAA,EACnE;AACA,SAAO;AACT;AAGA,SAAS,kBAAkB,QAA0C;AACnE,aAAW,OAAO,CAAC,gBAAgB,aAAa,GAAG;AACjD,QAAI,OAAO,OAAQ,QAAO,QAAQ,OAAO,GAAG,CAAC;AAAA,EAC/C;AACA,QAAM,OAAO,OAAO,MAAM;AAC1B,MAAID,UAAS,IAAI,EAAG,QAAO,QAAQ,KAAK,SAAS,CAAC;AAClD,SAAO;AACT;AAOO,SAAS,eAAe,QAAiC,KAAqB;AACnF,QAAM,UAAU,cAAc,MAAM;AACpC,QAAM,SAAS,aAAa,OAAO;AACnC,QAAM,UAAU,aAAa,mBAAmB;AAChD,MAAI,WAAW,MAAM;AACnB,UAAM,IAAI;AAAA,MACR,eAAe,GAAG,4CACR,KAAK,UAAU,OAAO,CAAC,oGAEzB,mBAAmB;AAAA,IAC7B;AAAA,EACF;AACA,MAAI,gBAAgB,QAAQ,OAAO,GAAG;AACpC,UAAM,IAAI;AAAA,MACR,eAAe,GAAG,SAAS,OAAO,wHAEU,mBAAmB;AAAA,IACjE;AAAA,EACF;AACA,MAAI,CAAC,kBAAkB,MAAM,GAAG;AAC9B,UAAM,IAAI;AAAA,MACR,eAAe,GAAG;AAAA,IAIpB;AAAA,EACF;AACA,SAAO;AACT;AAQA,SAAS,OAAO,UAAkB,OAAsB;AACtD,QAAM,SAAS,iBAAiB,SAAS,QAAQ,MAAM,QAAQ,CAAC;AAChE,MAAI,WAAW,KAAM,QAAO;AAC5B,SAAO,OAAO,QAAQ,IAAI,MAAM,QAAQ;AAC1C;AAQA,SAAS,iBAAiB,MAA2B;AACnD,QAAM,QAAQ,KAAK,KAAK;AACxB,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,YAAY,oBAAoB,KAAK,KAAK;AAGhD,QAAM,aAAa,aAAa,CAAC,MAAM,SAAS,GAAG,IAAI,QAAQ,GAAG,KAAK;AACvE,QAAM,KAAK,KAAK,MAAM,UAAU;AAChC,SAAO,OAAO,MAAM,EAAE,IAAI,OAAO,IAAI,KAAK,EAAE;AAC9C;AAGA,SAASE,iBAAwB;AAC/B,UAAO,oBAAI,KAAK,GAAE,YAAY,EAAE,QAAQ,aAAa,GAAG;AAC1D;AAgBA,SAASC,SAAQ,KAAa,OAA2B,YAAkC;AACzF,QAAM,OAAO,CAAC,OAAO,MAAM,KAAK,cAAc,OAAO,UAAU,CAAC;AAChE,MAAI,OAAO;AACT,SAAK,KAAK,MAAM,yBAAyB,KAAK,EAAE;AAAA,EAClD;AACA,OAAK,KAAK,MAAM,oCAAoC,GAAG;AAEvD,QAAM,UAAM,yCAAa,QAAQ,MAAM;AAAA,IACrC,UAAU;AAAA,IACV,UAAU,aAAa,KAAK;AAAA,IAC5B,WAAW,IAAI,OAAO;AAAA,EACxB,CAAC;AAED,QAAM,cAAc,6BAA6B,KAAK,GAAG;AACzD,QAAM,SAAS,cAAc,OAAO,YAAY,CAAC,CAAC,IAAI;AACtD,QAAM,OAAO,cAAc,IAAI,MAAM,GAAG,YAAY,KAAK,IAAI;AAC7D,SAAO,EAAE,QAAQ,KAAK;AACxB;AAWO,IAAM,oBAAN,MAAwB;AAAA,EACpB;AAAA,EACQ;AAAA,EACR;AAAA,EAET,YAAY,KAAa,OAAgB,UAAU,GAAK;AACtD,SAAK,MAAM,IAAI,QAAQ,QAAQ,EAAE;AACjC,SAAK,QAAQ;AACb,SAAK,UAAU;AAAA,EACjB;AAAA,EAEQ,IAAI,MAAuB;AACjC,QAAI;AACJ,QAAI;AACF,aAAOA,SAAQ,KAAK,MAAM,MAAM,KAAK,OAAO,KAAK,OAAO;AAAA,IAC1D,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR,oCAAoC,KAAK,GAAG,KAAK,OAAO,GAAG,CAAC;AAAA,MAC9D;AAAA,IACF;AACA,QAAI,KAAK,UAAU,KAAK;AACtB,YAAM,IAAI;AAAA,QACR,gBAAgB,IAAI,kBAAkB,KAAK,MAAM;AAAA,MACnD;AAAA,IACF;AACA,QAAI,KAAK,WAAW,GAAG;AACrB,YAAM,IAAI;AAAA,QACR,oCAAoC,KAAK,GAAG;AAAA,MAC9C;AAAA,IACF;AACA,QAAI;AACF,aAAO,KAAK,MAAM,KAAK,IAAI;AAAA,IAC7B,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR,oCAAoC,KAAK,GAAG,KAAK,OAAO,GAAG,CAAC;AAAA,MAC9D;AAAA,IACF;AAAA,EACF;AAAA,EAEA,SAAkC;AAChC,UAAM,OAAO,KAAK,IAAI,aAAa;AACnC,WAAOH,UAAS,IAAI,IAAI,OAAO,CAAC;AAAA,EAClC;AAAA,EAEA,WAAsC;AACpC,WAAO,KAAK,eAAe,iBAAiB,UAAU;AAAA,EACxD;AAAA,EAEA,WAAsC;AACpC,WAAO,KAAK,eAAe,iBAAiB,UAAU;AAAA,EACxD;AAAA;AAAA;AAAA,EAIQ,eAAe,MAAc,KAAwC;AAC3E,QAAI;AACJ,QAAI;AACF,aAAO,KAAK,IAAI,IAAI;AAAA,IACtB,SAAS,KAAK;AACZ,UAAI,eAAe,0BAA2B,QAAO,CAAC;AACtD,YAAM;AAAA,IACR;AACA,QAAIA,UAAS,IAAI,GAAG;AAClB,aAAO,KAAK,GAAG,KAAK,CAAC;AAAA,IACvB;AACA,QAAI,CAAC,MAAM,QAAQ,IAAI,EAAG,QAAO,CAAC;AAClC,WAAO,KAAK,OAAOA,SAAQ;AAAA,EAC7B;AACF;AAKO,IAAM,sBAAN,MAAwD;AAAA,EAC7D,UAAUJ;AAAA,EACV,YAAYC;AAAA,EACZ,cAAcC;AAAA;AAAA;AAAA,EAGd,mBAAmB;AAAA,EAEV;AAAA,EACQ;AAAA,EAEjB,OAAO,kBAAkB,MAAuB;AAG9C,eAAO,wBAAK,YAAQ,yBAAQ,GAAG,WAAW;AAAA,EAC5C;AAAA,EAEA,YAAY,KAAc,OAAgB,QAA4B;AACpE,SAAK,OAAO,OAAO,QAAQ,IAAI,gBAAgB,sBAAsB,QAAQ,QAAQ,EAAE;AACvF,SAAK,SAAS,UAAU,IAAI,kBAAkB,KAAK,KAAK,SAAS,QAAQ,IAAI,cAAc;AAAA,EAC7F;AAAA,EAEA,IAAI,aAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAIA,WAAuB;AACrB,UAAM,SAAS,KAAK,OAAO,OAAO;AAClC,UAAM,UAAU,eAAe,QAAQ,KAAK,GAAG;AAC/C,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX;AAAA,MACA,UAAU,EAAE,cAAc,MAAM,WAAW,OAAO;AAAA,IACpD;AAAA,EACF;AAAA,EAEA,eAAe,OAAc,QAAgB,eAA+B;AAC1E,SAAK,SAAS;AACd,UAAM,WAA2B,CAAC;AAClC,eAAW,OAAO,KAAK,OAAO,SAAS,GAAG;AACxC,YAAM,OAAO,OAAO,IAAI,YAAY,KAAK,IAAI,YAAY,KAAK,IAAI,MAAM,KAAK,EAAE,EAAE,KAAK;AACtF,UAAI,CAAC,KAAM;AACX,UAAI,UAAU,UAAa,OAAO,MAAM,KAAK,EAAG;AAChD,YAAM,QAAQG,sBAAqB,OAAO,IAAI,OAAO,KAAK,IAAI,SAAS,KAAK,EAAE,CAAC;AAC/E,YAAM,WAAW,MAAM,QAAQ,IAAI,UAAU,CAAC,IAAI,IAAI,UAAU,EAAE,MAAM,GAAG,CAAC,IAAI,CAAC;AACjF,eAAS;AAAA,YACP,wBAAY;AAAA,UACV;AAAA,UACA,KAAK;AAAA,UACL,eAAe,SAAS,IAAI,CAAC,MAAMA,sBAAqB,OAAO,CAAC,CAAC,CAAC;AAAA,UAClE,aAAa,QAAQ,CAAC,KAAK,IAAI,CAAC;AAAA,QAClC,CAAC;AAAA,MACH;AACA,UAAI,SAAS,UAAU,MAAO;AAAA,IAChC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,OAA+B;AACtC,UAAM,QAAQ,KAAK,SAAS;AAC5B,UAAM,WAA0B,CAAC;AACjC,eAAW,OAAO,KAAK,OAAO,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG;AAC/D,YAAM,OAAOA,sBAAqB,OAAO,IAAI,MAAM,KAAK,IAAI,OAAO,KAAK,EAAE,CAAC;AAC3E,UAAI,CAAC,KAAM;AACX,YAAM,OAAO,MAAM,QAAQ,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,EAAE,MAAM,GAAG,CAAC,IAAI,CAAC;AACrE,eAAS;AAAA,YACP,uBAAW;AAAA,UACT;AAAA,UACA,MAAM,OAAO,IAAI,MAAM,KAAK,OAAO;AAAA,UACnC,SAASA,sBAAqB,OAAO,IAAI,SAAS,KAAK,EAAE,CAAC;AAAA,UAC1D,MAAM,KAAK,IAAI,CAAC,MAAMA,sBAAqB,OAAO,CAAC,CAAC,CAAC;AAAA,QACvD,CAAC;AAAA,MACH;AAAA,IACF;AAIA,UAAM,aAAgC,iCAAqB,EAAE,SAAS,sBAAW,KAAK,CAAC;AACvF,eAAO,yBAAa;AAAA,MAClB,cAAc;AAAA,MACd,WAAO,0BAAc;AAAA,QACnB,IAAIL;AAAA,QACJ,MAAMC;AAAA,QACN,UAAU,KAAK;AAAA,QACf,gBAAgBE;AAAA,MAClB,CAAC;AAAA,MACD,cAAcG,eAAc;AAAA,MAC5B,cAAc,CAAC,YAAY,MAAM,OAAO,EAAE;AAAA,MAC1C,iBAAiB,KAAK,eAAe,KAAK;AAAA,MAC1C,oBAAgB,gCAAoB,UAAU,MAAM;AAAA,MACpD,mBAAmB;AAAA,IACrB,CAAC;AAAA,EACH;AAAA,EAEA,cAA4B;AAC1B,QAAI;AACJ,QAAI;AACF,cAAQ,KAAK,SAAS;AAAA,IACxB,SAAS,KAAK;AACZ,UAAI,eAAe,2BAA2B;AAC5C,cAAM,SAAS,IAAI;AACnB,YAAI,MAAM;AACV,YAAI,OAAO,SAAS,kBAAkB,GAAG;AACvC,gBAAM,uCAAuC,mBAAmB;AAAA,QAClE,WAAW,OAAO,SAAS,yBAAyB,GAAG;AACrD,gBAAM;AAAA,QACR,WAAW,OAAO,SAAS,aAAa,GAAG;AACzC,gBACE;AAAA,QACJ;AACA,eAAO,EAAE,QAAQ,WAAW,QAAQ,aAAa,KAAK,SAAS,CAAC,EAAE;AAAA,MACpE;AAEA,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QACvD,SAAS,CAAC;AAAA,MACZ;AAAA,IACF;AACA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS,EAAE,KAAK,KAAK,KAAK,SAAS,MAAM,SAAS,aAAa,KAAK;AAAA,IACtE;AAAA,EACF;AACF;;;AC5aA,IAAAE,kBAMO;AACP,IAAAC,kBAAkC;AAClC,IAAAC,oBAA8B;AAE9B,IAAAC,aAYO;AACP,IAAAC,oBAA2B;AAE3B,uBAAmC;AAanC,IAAMC,YAAW;AACjB,IAAMC,cAAa;AACnB,IAAMC,kBACJ;AAKF,IAAMC,sBAAwC,iCAAqB;AAAA,EACjE,SAAS,sBAAW;AAAA,EACpB,cAAc,CAAC,YAAY,aAAa,cAAc,UAAU,UAAU,OAAO;AAAA,EACjF,WAAW,CAAC,0BAA0B,cAAc,WAAW;AACjE,CAAC;AAED,IAAM,uBAAuB;AAC7B,IAAM,kBAAkB;AACxB,IAAM,YAAY;AAClB,IAAM,mBAAmB;AACzB,IAAM,0BAA0B;AAChC,IAAMC,wBAAuB;AAG7B,IAAM,gBAAgB;AAGtB,IAAM,sBAAsB;AAK5B,IAAM,wBAA2C;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGA,IAAM,kBAA4D;AAAA,EAChE,CAAC,0BAA0B,+BAA+B;AAAA,EAC1D,CAAC,gBAAgB,yDAAyD;AAAA,EAC1E,CAAC,iBAAiB,mDAAmD;AAAA,EACrE,CAAC,uBAAuB,6CAA6C;AAAA,EACrE,CAAC,mBAAmB,+CAA+C;AAAA,EACnE,CAAC,aAAa,wDAAwD;AACxE;AAGA,IAAMC,UAAS;AAAA,EACb,KAAK,KAAmB;AAEtB,YAAQ,KAAK,0BAA0B,GAAG,EAAE;AAAA,EAC9C;AACF;AAqCA,SAASC,WAAkB;AAGzB,MAAI;AACF,eAAO,yBAAQ;AAAA,EACjB,QAAQ;AACN,WAAO,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe;AAAA,EACxD;AACF;AAEA,SAASC,OAAM,GAAoB;AACjC,MAAI;AACF,eAAO,0BAAS,CAAC,EAAE,YAAY;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASC,QAAO,GAAoB;AAClC,MAAI;AACF,eAAO,0BAAS,CAAC,EAAE,OAAO;AAAA,EAC5B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAcA,SAAS,OAAO,GAAqB;AACnC,MAAI,MAAM,UAAa,MAAM,QAAQ,MAAM,SAAS,MAAM,KAAK,MAAM,GAAI,QAAO;AAChF,MAAI,MAAM,QAAQ,CAAC,EAAG,QAAO,EAAE,SAAS;AACxC,MAAI,OAAO,MAAM,SAAU,QAAO,OAAO,KAAK,CAAW,EAAE,SAAS;AACpE,SAAO;AACT;AAGA,SAAS,MAAM,GAAoB;AACjC,MAAI,MAAM,KAAM,QAAO;AACvB,MAAI,MAAM,MAAO,QAAO;AACxB,MAAI,MAAM,QAAQ,MAAM,OAAW,QAAO;AAC1C,SAAO,OAAO,CAAC;AACjB;AAGA,SAAS,MAAM,GAAY,GAAoB;AAC7C,SAAO,MAAM,OAAO,CAAC,IAAI,IAAI,CAAC;AAChC;AAGA,SAAS,OAAO,GAAmB;AACjC,SAAO,EAAE,QAAQ,QAAQ,EAAE;AAC7B;AAGA,SAASC,YAAW,GAAW,OAAuB;AACpD,MAAI,QAAQ;AACZ,MAAI,MAAM,EAAE;AACZ,SAAO,QAAQ,OAAO,MAAM,SAAS,EAAE,KAAK,CAAE,EAAG;AACjD,SAAO,MAAM,SAAS,MAAM,SAAS,EAAE,MAAM,CAAC,CAAE,EAAG;AACnD,SAAO,EAAE,MAAM,OAAO,GAAG;AAC3B;AAGA,SAAS,WAAW,GAAqB;AACvC,QAAM,QAAQ,EAAE,MAAM,YAAY;AAClC,MAAI,MAAM,SAAS,KAAK,MAAM,MAAM,SAAS,CAAC,MAAM,GAAI,OAAM,IAAI;AAClE,SAAO;AACT;AAUO,SAAS,gCAAgC,YAA6B;AAC3E,MAAI,eAAe,OAAW,YAAO,wBAAK,YAAY,oBAAoB;AAC1E,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,IAAK,YAAO,wBAAK,KAAK,oBAAoB;AAC9C,aAAO,wBAAKC,SAAQ,GAAG,WAAW,oBAAoB;AACxD;AAIA,SAAS,mBAAmB,MAAuC;AACjE,MAAI;AACJ,MAAI;AACF,cAAM,iBAAAC,WAAU,8BAAa,MAAM,MAAM,CAAC;AAAA,EAC5C,SAAS,KAAK;AACZ,IAAAC,QAAO;AAAA,MACL,kDAAkD,IAAI,KAAK,OAAO,GAAG,CAAC;AAAA,IACxE;AACA,WAAO,CAAC;AAAA,EACV;AACA,SAAO,OAAO,QAAQ,YAAY,QAAQ,QAAQ,CAAC,MAAM,QAAQ,GAAG,IAC/D,MACD,CAAC;AACP;AAEA,SAAS,YAAY,UAA2C;AAC9D,QAAM,MAAM,mBAAmB,QAAQ;AACvC,QAAM,aAAS,2BAAQ,QAAQ;AAC/B,QAAM,aAAaC,YAAW,MAAM;AAEpC,QAAM,eAAe,MAAM,IAAI,IAAI,GAAG,UAAU,EAAE,KAAK;AACvD,MAAI,CAAC,aAAc,QAAO;AAE1B,QAAM,OAAO,MAAM,IAAI,MAAM,GAAG,YAAY,EAAE,KAAK;AACnD,QAAM,SAAS,MAAM,IAAI,QAAQ,GAAG,SAAS,EAAE,KAAK,EAAE,YAAY;AAClE,QAAM,QAAQ,MAAM,IAAI,OAAO,GAAG,EAAE,EAAE,KAAK;AAC3C,QAAM,OAAO,MAAM,IAAI,MAAM,GAAG,EAAE,EAAE,KAAK;AAEzC,QAAM,UAAmB,OAAO,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,IAAI,CAAC;AAC9D,QAAM,OAAiB,CAAC;AAIxB,MAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,eAAW,OAAO,SAAS;AACzB,UAAI,OAAO,QAAQ,YAAY,IAAI,KAAK,EAAG,MAAK,KAAK,GAAG;AAAA,IAC1D;AAAA,EACF,WAAW,OAAO,YAAY,UAAU;AACtC,eAAW,MAAM,SAAS;AACxB,UAAI,GAAG,KAAK,EAAG,MAAK,KAAK,EAAE;AAAA,IAC7B;AAAA,EACF;AAEA,QAAM,iBAAa,wBAAK,QAAQ,SAAS;AACzC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN,YAAYC,QAAO,UAAU,IAAI,aAAa;AAAA,EAChD;AACF;AAGA,SAASD,YAAW,GAAmB;AACrC,QAAM,UAAU,EAAE,QAAQ,WAAW,EAAE;AACvC,QAAM,MAAM,KAAK,IAAI,QAAQ,YAAY,GAAG,GAAG,QAAQ,YAAY,IAAI,CAAC;AACxE,SAAO,QAAQ,KAAK,UAAU,QAAQ,MAAM,MAAM,CAAC;AACrD;AAEA,SAAS,YAAY,gBAA4C;AAC/D,QAAM,UAA8B,CAAC;AACrC,MAAI,CAACE,OAAM,cAAc,EAAG,QAAO;AAGnC,QAAM,YAAsB,CAAC;AAC7B,MAAI;AACJ,MAAI;AACF,kBAAU,6BAAY,cAAc;AAAA,EACtC,QAAQ;AACN,WAAO;AAAA,EACT;AACA,aAAW,SAAS,SAAS;AAC3B,UAAM,UAAM,wBAAK,gBAAgB,KAAK;AACtC,QAAI,CAACA,OAAM,GAAG,EAAG;AACjB,UAAM,eAAW,wBAAK,KAAK,eAAe;AAC1C,QAAID,QAAO,QAAQ,EAAG,WAAU,KAAK,QAAQ;AAAA,EAC/C;AACA,YAAU,KAAK,CAAC,GAAG,MAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAE;AACrD,aAAW,YAAY,WAAW;AAChC,UAAM,SAAS,YAAY,QAAQ;AACnC,QAAI,WAAW,KAAM,SAAQ,KAAK,MAAM;AAAA,EAC1C;AACA,SAAO;AACT;AAIA,SAAS,eAAe,MAA6B;AACnD,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI;AACJ,MAAI;AACF,eAAO,8BAAa,MAAM,MAAM;AAAA,EAClC,SAAS,KAAK;AACZ,IAAAF,QAAO;AAAA,MACL,iDAAiD,IAAI,KAAK,OAAO,GAAG,CAAC;AAAA,IACvE;AACA,WAAO;AAAA,EACT;AACA,SAAO,KAAK,MAAM,CAAC,gBAAgB;AACrC;AAEA,SAAS,kBAAkB,QAA2C;AACpE,QAAM,OAAO,eAAe,OAAO,UAAU;AAC7C,MAAI,CAAC,KAAM,QAAO,CAAC;AAEnB,QAAM,SAAoC,CAAC;AAC3C,MAAI,cAAc;AAClB,MAAI,eAAyB,CAAC;AAC9B,aAAW,WAAW,WAAW,IAAI,GAAG;AACtC,UAAM,OAAO,OAAO,OAAO;AAC3B,UAAM,QAAQ,cAAc,KAAK,KAAK,KAAK,CAAC;AAC5C,QAAI,OAAO;AACT,UAAI,YAAa,QAAO,KAAK,CAAC,aAAa,YAAY,CAAC;AACxD,oBAAc,MAAM,CAAC;AACrB,YAAM,SAASH,YAAW,MAAM,CAAC,KAAK,IAAI,mBAAmB;AAC7D,qBAAe,SAAS,CAAC,MAAM,IAAI,CAAC;AACpC;AAAA,IACF;AACA,QAAI,YAAa,cAAa,KAAK,IAAI;AAAA,EACzC;AACA,MAAI,YAAa,QAAO,KAAK,CAAC,aAAa,YAAY,CAAC;AAExD,QAAM,OAAwB,CAAC;AAC/B,aAAW,CAAC,SAAS,KAAK,KAAK,QAAQ;AACrC,UAAM,UAAU,iBAAiB,KAAK;AACtC,QAAI,QAAQ,WAAW,EAAG;AAC1B,UAAM,OAAO,QAAQ,KAAK,GAAG;AAC7B,UAAM,QAAQ,iBAAiB,QAAQ,OAAO;AAC9C,SAAK,KAAK;AAAA,MACR,YAAY;AAAA,MACZ,MAAM;AAAA,MACN;AAAA,MACA,YAAY;AAAA,MACZ,UAAU,cAAc,IAAI;AAAA,MAC5B,SAAS,aAAa,IAAI;AAAA,IAC5B,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,OAA2B;AACnD,QAAM,UAAoB,CAAC;AAC3B,aAAW,QAAQ,OAAO;AACxB,QAAI,UAAU,KAAK,KAAK;AACxB,QAAI,CAAC,QAAS;AACd,cAAU,aAAa,SAAS,IAAI,EAAE,KAAK;AAC3C,UAAM,UAAU,QAAQ,YAAY;AACpC,QAAI,CAAC,WAAW,QAAQ,WAAW,SAAS,EAAG;AAC/C,QAAI,YAAY,eAAe,YAAY,YAAa;AACxD,QAAI,QAAQ,WAAW,MAAM,EAAG,WAAU,QAAQ,MAAM,CAAC,EAAE,KAAK;AAChE,UAAM,OAAOO,SAAQC,sBAAqB,OAAO,GAAGC,qBAAoB;AACxE,QAAI,QAAQ,CAAC,QAAQ,SAAS,IAAI,EAAG,SAAQ,KAAK,IAAI;AACtD,QAAI,QAAQ,UAAU,wBAAyB;AAAA,EACjD;AACA,SAAO;AACT;AAGA,SAAS,aAAa,GAAW,QAAwB;AACvD,SAAO,EAAE,WAAW,MAAM,IAAI,EAAE,MAAM,OAAO,MAAM,IAAI;AACzD;AAGA,SAASD,sBAAqB,OAAuB;AACnD,aAAO,8BAAW,OAAO,GAAG;AAC9B;AAEA,SAAS,iBAAiB,QAA0B,SAA2B;AAC7E,MAAI,QAAQ,WAAW,EAAG,QAAO,OAAO;AACxC,QAAM,QAAQ,QAAQ,CAAC;AACvB,QAAM,SAAS,GAAG,OAAO,IAAI;AAC7B,MAAI,MAAM,WAAW,MAAM,EAAG,QAAOD,SAAQ,OAAO,GAAG;AACvD,SAAOA,SAAQ,SAAS,OAAO,GAAG;AACpC;AAEA,SAAS,cAAc,MAAwB;AAC7C,QAAM,WAAqB,CAAC;AAC5B,QAAM,UAAU,KAAK,YAAY;AACjC,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,WAAW,iBAAiB,qBAAqB,GAAG;AAC7D,UAAM,MAAM,QAAQ,YAAY;AAChC,QAAI,QAAQ,SAAS,GAAG,KAAK,CAAC,KAAK,IAAI,GAAG,GAAG;AAC3C,eAAS,KAAK,OAAO;AACrB,WAAK,IAAI,GAAG;AAAA,IACd;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,aAAa,MAAwB;AAC5C,QAAM,UAAoB,CAAC;AAC3B,aAAW,CAAC,MAAM,OAAO,KAAK,iBAAiB;AAC7C,QAAI,QAAQ,KAAK,IAAI,EAAG,SAAQ,KAAK,IAAI;AAAA,EAC3C;AACA,SAAO;AACT;AAGA,SAASA,SAAQ,OAAe,OAAuB;AACrD,QAAM,aAAa,MAAM,KAAK,EAAE,QAAQ,QAAQ,GAAG;AACnD,MAAI,WAAW,UAAU,MAAO,QAAO;AACvC,SAAO,OAAO,WAAW,MAAM,GAAG,QAAQ,CAAC,CAAC,IAAI;AAClD;AAIA,SAAS,eAAe,KAAkC;AACxD,QAAM,SAAS,IAAI;AACnB,QAAMG,cAAa;AAAA,IACjB,kBAAkB,OAAO,YAAY;AAAA,IACrC,QAAQ,IAAI,KAAK;AAAA,IACjB,GAAG,IAAI;AAAA,EACT;AACA,QAAM,eAAe,CAAC,OAAO,IAAI;AACjC,MAAI,OAAO,eAAe,KAAM,cAAa,KAAK,OAAO,UAAU;AACnE,aAAO,wBAAY;AAAA,IACjB,MAAM,IAAI;AAAA,IACV,KAAK,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,QAAI,2BAAQ,OAAO,IAAI;AAAA,IAClE,eAAe,CAAC,GAAG,IAAI,QAAQ;AAAA,IAC/B,aAAaA,YAAW,MAAM,GAAG,0BAA0B,CAAC;AAAA,IAC5D,eAAe;AAAA,IACf,YAAY,sBAAW;AAAA,EACzB,CAAC;AACH;AAEA,SAAS,2BACP,SACA,MACe;AAGf,QAAM,SAAS,oBAAI,IAAyB;AAE5C,aAAW,UAAU,SAAS;AAC5B,WAAO;AAAA,MACL,OAAO;AAAA,UACP,uBAAW;AAAA,QACT,MAAM,OAAO;AAAA,QACb,MAAM;AAAA,QACN,SAASH;AAAA,UACP,2BAA2B,OAAO,IAAI,MAAM,OAAO,MAAM,gBAC1C,OAAO,SAAS,aAAa;AAAA,UAC5C;AAAA,QACF;AAAA,QACA,cAAc;AAAA,QACd,MAAM,CAAC,0BAA0B,cAAc,OAAO,OAAO,YAAY,CAAC;AAAA,QAC1E,YAAY,sBAAW;AAAA,MACzB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,aAAW,OAAO,MAAM;AACtB,eAAW,WAAW,IAAI,UAAU;AAClC,UAAI,CAAC,OAAO,IAAI,OAAO,GAAG;AACxB,eAAO;AAAA,UACL;AAAA,cACA,uBAAW;AAAA,YACT,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,cAAc,IAAI;AAAA,YAClB,MAAM,CAAC,0BAA0B,qBAAqB;AAAA,YACtD,YAAY,sBAAW;AAAA,UACzB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AACA,eAAW,UAAU,IAAI,SAAS;AAChC,UAAI,CAAC,OAAO,IAAI,MAAM,GAAG;AACvB,eAAO;AAAA,UACL;AAAA,cACA,uBAAW;AAAA,YACT,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,cAAc,IAAI;AAAA,YAClB,MAAM,CAAC,0BAA0B,mBAAmB;AAAA,YACpD,YAAY,sBAAW;AAAA,UACzB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO,CAAC,GAAG,OAAO,OAAO,CAAC;AAC5B;AAiJO,IAAM,mCAAN,MAAqE;AAAA,EAC1E,UAAUI;AAAA,EACV,YAAYC;AAAA,EACZ;AAAA,EAEiB;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjB,OAAO,kBAAkB,MAAuB;AAC9C,WAAO,gCAAgC,IAAI;AAAA,EAC7C;AAAA,EAEA,YAAY,gBAAyB,YAAqB;AACxD,SAAK,iBAAiB,kBAAkB,gCAAgC,UAAU;AAClF,SAAK,aAAa,KAAK;AACvB,SAAK,SAASC;AAAA,EAChB;AAAA,EAEA,WAAuB;AACrB,QAAI,CAACC,OAAM,KAAK,cAAc,GAAG;AAC/B,YAAM,IAAI;AAAA,QACR,kDAAkD,KAAK,cAAc;AAAA,MACvE;AAAA,IACF;AACA,UAAM,UAAU,YAAY,KAAK,cAAc;AAC/C,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,SAAS;AAAA,MACT,UAAU;AAAA,QACR,aAAa,QAAQ;AAAA,QACrB,aAAa,QAAQ,OAAO,CAAC,MAAM,EAAE,eAAe,IAAI,EAAE;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AAAA,EAEA,eAAe,OAAc,QAAQ,KAAqB;AACxD,UAAM,WAAW,KAAK,KAAK,QAAW,KAAK,EAAE,IAAI,cAAc;AAC/D,aAAS,KAAK,CAAC,GAAG,MAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE,OAAO,KAAK,CAAE;AACxE,WAAO,SAAS,MAAM,GAAG,KAAK;AAAA,EAChC;AAAA,EAEA,SAAS,OAA+B;AACtC,QAAI,CAACA,OAAM,KAAK,cAAc,GAAG;AAC/B,YAAM,IAAI;AAAA,QACR,kDAAkD,KAAK,cAAc;AAAA,MACvE;AAAA,IACF;AACA,UAAM,UAAU,YAAY,KAAK,cAAc;AAC/C,UAAM,OAAO,KAAK,KAAK,SAAS,KAAK;AACrC,UAAM,WAAW,KAAK,IAAI,cAAc;AACxC,aAAS,KAAK,CAAC,GAAG,MAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE,OAAO,KAAK,CAAE;AACxE,UAAM,WAAW,2BAA2B,SAAS,IAAI;AACzD,UAAM,sBAAkB,gCAAoB,UAAU,KAAK,MAAM;AACjE,eAAO,yBAAa;AAAA,MAClB,cAAc;AAAA,MACd,WAAO,0BAAc;AAAA,QACnB,IAAIH;AAAA,QACJ,MAAMC;AAAA,QACN,cAAU,0BAAS;AAAA,QACnB,qBAAqB;AAAA,QACrB,gBAAgBG;AAAA,MAClB,CAAC;AAAA,MACD,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,MACrC,cAAc,CAAC,iCAAiC,yBAAyB;AAAA,MACzE,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,mBAAmB,KAAK;AAAA,IAC1B,CAAC;AAAA,EACH;AAAA,EAEA,cAA4B;AAC1B,QAAI,CAACD,OAAM,KAAK,cAAc,GAAG;AAC/B,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ,kDAAkD,KAAK,cAAc;AAAA,QAC7E,SAAS,EAAE,iBAAiB,KAAK,eAAe;AAAA,QAChD,aACE;AAAA,MAGJ;AAAA,IACF;AACA,UAAM,UAAU,YAAY,KAAK,cAAc;AAC/C,UAAM,OAAO,KAAK,KAAK,OAAO;AAC9B,UAAM,aAAa,QAAQ,SAAS;AACpC,UAAM,SAAiC,aAAa,OAAO;AAC3D,UAAM,UAAU;AAAA,MACd,iBAAiB,KAAK;AAAA,MACtB,kBAAkB,QAAQ;AAAA,MAC1B,cAAc,QAAQ,OAAO,CAAC,MAAM,EAAE,eAAe,IAAI,EAAE;AAAA,MAC3D,gBAAgB,KAAK;AAAA,MACrB,oBAAoB,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ,EAAE;AAAA,IACnE;AACA,QAAI,YAAY;AACd,aAAO,EAAE,QAAQ,QAAQ;AAAA,IAC3B;AACA,WAAO;AAAA,MACL;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EAEQ,KAAK,SAA8B,OAA+B;AACxE,UAAM,YAAY,QAAQ,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE,IAAI;AAC7D,UAAM,OAAwB,CAAC;AAC/B,eAAW,UAAU,WAAW,YAAY,KAAK,cAAc,GAAG;AAChE,iBAAW,OAAO,kBAAkB,MAAM,GAAG;AAC3C,YAAI,aAAa,IAAI,OAAO,UAAW;AACvC,aAAK,KAAK,GAAG;AAAA,MACf;AAAA,IACF;AACA,SAAK,KAAK,CAAC,GAAG,MAAM;AAClB,UAAI,EAAE,SAAS,EAAE,KAAM,QAAO,EAAE,OAAO,EAAE,OAAO,IAAI;AACpD,YAAM,KAAK,EAAE,WAAW;AACxB,YAAM,KAAK,EAAE,WAAW;AACxB,UAAI,OAAO,GAAI,QAAO,KAAK,KAAK,IAAI;AACpC,aAAO;AAAA,IACT,CAAC;AACD,WAAO;AAAA,EACT;AACF;;;ACxwBA,IAAAE,mBAAoD;AACpD,IAAAC,mBAAkC;AAClC,IAAAC,qBAAwC;AAExC,IAAAC,oBAAmC;AAEnC,IAAAC,cAYO;AACP,IAAAC,qBAA2B;AAa3B,IAAMC,aAAW;AACjB,IAAMC,eAAa;AACnB,IAAMC,mBACJ;AAIF,IAAMC,sBAAwC,kCAAqB;AAAA,EACjE,SAAS,uBAAW;AAAA,EACpB,cAAc,CAAC,YAAY,aAAa,cAAc,UAAU,UAAU,OAAO;AAAA,EACjF,WAAW,CAAC,oBAAoB,cAAc,WAAW;AAC3D,CAAC;AAED,IAAMC,wBAAuB;AAC7B,IAAMC,mBAAkB;AACxB,IAAMC,aAAY;AAClB,IAAMC,oBAAmB;AACzB,IAAMC,2BAA0B;AAChC,IAAMC,wBAAuB;AAC7B,IAAMC,iBAAgB;AAItB,IAAMC,yBAA2C,CAAC,WAAW,UAAU,SAAS;AAChF,IAAMC,mBAA0D;AAAA,EAC9D,CAAC,0BAA0B,+BAA+B;AAAA,EAC1D,CAAC,gBAAgB,yDAAyD;AAAA,EAC1E,CAAC,iBAAiB,mDAAmD;AAAA,EACrE,CAAC,uBAAuB,6CAA6C;AAAA,EACrE,CAAC,mBAAmB,+CAA+C;AACrE;AAGA,IAAMC,UAAS;AAAA,EACb,KAAK,KAAmB;AAEtB,YAAQ,KAAK,0BAA0B,GAAG,EAAE;AAAA,EAC9C;AACF;AA2BA,SAASC,WAAkB;AAGzB,MAAI;AACF,eAAO,0BAAQ;AAAA,EACjB,QAAQ;AACN,WAAO,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe;AAAA,EACxD;AACF;AAEA,SAASC,OAAM,GAAoB;AACjC,MAAI;AACF,eAAO,2BAAS,CAAC,EAAE,YAAY;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASC,QAAO,GAAoB;AAClC,MAAI;AACF,eAAO,2BAAS,CAAC,EAAE,OAAO;AAAA,EAC5B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKO,SAAS,2BAA2B,WAA4B;AACrE,MAAI,cAAc,UAAa,cAAc,MAAM;AACjD,eAAO,yBAAK,WAAWZ,qBAAoB;AAAA,EAC7C;AACA,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,IAAK,YAAO,yBAAK,KAAKA,qBAAoB;AAC9C,aAAO,yBAAKU,SAAQ,GAAG,UAAUV,qBAAoB;AACvD;AAQA,SAASa,sBAAqB,OAAuB;AACnD,aAAO,+BAAW,OAAO,GAAG;AAC9B;AAKA,SAAS,QAAQ,GAAY,GAAmB;AAC9C,SAAO,OAAO,IAAI,IAAI,CAAC;AACzB;AAKA,SAASC,oBAAmB,MAAuC;AACjE,MAAI;AACJ,MAAI;AACF,eAAO,+BAAa,MAAM,MAAM;AAAA,EAClC,SAAS,KAAK;AACZ,IAAAL,QAAO,KAAK,6CAA6C,IAAI,KAAK,OAAO,GAAG,CAAC,EAAE;AAC/E,WAAO,CAAC;AAAA,EACV;AACA,MAAI;AACF,UAAM,aAAS,kBAAAM,OAAU,IAAI;AAC7B,WAAO,OAAO,WAAW,YAAY,WAAW,QAAQ,CAAC,MAAM,QAAQ,MAAM,IACxE,SACD,CAAC;AAAA,EACP,SAAS,KAAK;AACZ,IAAAN,QAAO,KAAK,6CAA6C,IAAI,KAAK,OAAO,GAAG,CAAC,EAAE;AAC/E,WAAO,CAAC;AAAA,EACV;AACF;AAGA,SAASO,aAAY,UAA2C;AAC9D,QAAM,MAAMF,oBAAmB,QAAQ;AACvC,QAAM,iBAAa,iCAAS,4BAAQ,QAAQ,CAAC;AAE7C,QAAM,eAAe,QAAQ,IAAI,IAAI,GAAG,UAAU,EAAE,KAAK;AACzD,MAAI,CAAC,aAAc,QAAO;AAE1B,QAAM,OAAO,QAAQ,IAAI,MAAM,GAAG,YAAY,EAAE,KAAK;AACrD,QAAM,SAAS,QAAQ,IAAI,QAAQ,GAAG,SAAS,EAAE,KAAK,EAAE,YAAY;AACpE,QAAM,QAAQ,QAAQ,IAAI,OAAO,GAAG,EAAE,EAAE,KAAK;AAC7C,QAAM,OAAO,QAAQ,IAAI,MAAM,GAAG,EAAE,EAAE,KAAK;AAE3C,QAAM,UAAU,IAAI,MAAM;AAC1B,QAAM,OAAiB,MAAM,QAAQ,OAAO,IACxC,QAAQ,OAAO,CAAC,QAAuB,OAAO,QAAQ,YAAY,IAAI,KAAK,MAAM,EAAE,IACnF,CAAC;AAEL,QAAM,iBAAa,6BAAK,4BAAQ,QAAQ,GAAGZ,UAAS;AACpD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN,YAAYU,QAAO,UAAU,IAAI,aAAa;AAAA,EAChD;AACF;AAOA,SAASK,aAAY,gBAA4C;AAC/D,MAAI,CAACN,OAAM,cAAc,EAAG,QAAO,CAAC;AACpC,MAAI;AACJ,MAAI;AACF,kBAAU,8BAAY,cAAc;AAAA,EACtC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACA,QAAM,YAAsB,CAAC;AAC7B,aAAW,SAAS,SAAS;AAC3B,UAAM,eAAW,yBAAK,gBAAgB,OAAOV,gBAAe;AAC5D,QAAIW,QAAO,QAAQ,EAAG,WAAU,KAAK,QAAQ;AAAA,EAC/C;AACA,YAAU,KAAK,CAAC,GAAG,MAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAE;AACrD,QAAM,UAA8B,CAAC;AACrC,aAAW,YAAY,WAAW;AAChC,UAAM,SAASI,aAAY,QAAQ;AACnC,QAAI,WAAW,KAAM,SAAQ,KAAK,MAAM;AAAA,EAC1C;AACA,SAAO;AACT;AAKA,SAASE,gBAAe,MAA6B;AACnD,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI;AACJ,MAAI;AACF,eAAO,+BAAa,MAAM,MAAM;AAAA,EAClC,SAAS,KAAK;AACZ,IAAAT,QAAO,KAAK,4CAA4C,IAAI,KAAK,OAAO,GAAG,CAAC,EAAE;AAC9E,WAAO;AAAA,EACT;AACA,SAAO,KAAK,SAASN,oBAAmB,KAAK,MAAM,CAACA,iBAAgB,IAAI;AAC1E;AAGA,SAASgB,YAAW,MAAwB;AAG1C,SAAO,KAAK,MAAM,8DAA8D;AAClF;AAGA,SAASC,QAAO,GAAmB;AACjC,SAAO,EAAE,QAAQ,QAAQ,EAAE;AAC7B;AAGA,SAAS,mBAAmB,OAAuB;AACjD,SAAO,MACJ,MAAM,KAAK,EACX,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,EAC1B,KAAK,GAAG;AACb;AAGA,SAASC,SAAQ,OAAe,OAAuB;AACrD,QAAM,aAAa,mBAAmB,KAAK;AAC3C,MAAI,WAAW,UAAU,MAAO,QAAO;AACvC,SAAOD,QAAO,WAAW,MAAM,GAAG,QAAQ,CAAC,CAAC,IAAI;AAClD;AAEA,SAASE,kBAAiB,OAA2B;AACnD,QAAM,UAAoB,CAAC;AAC3B,aAAW,QAAQ,OAAO;AACxB,QAAI,UAAU,KAAK,KAAK;AACxB,QAAI,CAAC,QAAS;AACd,eAAW,QAAQ,WAAW,IAAI,IAAI,QAAQ,MAAM,CAAC,IAAI,SAAS,KAAK;AACvE,UAAM,UAAU,QAAQ,YAAY;AACpC,QAAI,CAAC,WAAW,QAAQ,WAAW,SAAS,EAAG;AAC/C,QAAI,YAAY,eAAe,YAAY,YAAa;AACxD,QAAI,QAAQ,WAAW,MAAM,EAAG,WAAU,QAAQ,MAAM,CAAC,EAAE,KAAK;AAChE,UAAM,OAAOD,SAAQR,sBAAqB,OAAO,GAAGR,qBAAoB;AACxE,QAAI,QAAQ,CAAC,QAAQ,SAAS,IAAI,EAAG,SAAQ,KAAK,IAAI;AACtD,QAAI,QAAQ,UAAUD,yBAAyB;AAAA,EACjD;AACA,SAAO;AACT;AAEA,SAASmB,kBAAiB,QAA0B,SAA2B;AAC7E,MAAI,QAAQ,WAAW,EAAG,QAAO,OAAO;AACxC,QAAM,QAAQ,QAAQ,CAAC;AACvB,QAAM,SAAS,GAAG,OAAO,IAAI;AAC7B,MAAI,MAAM,WAAW,MAAM,EAAG,QAAOF,SAAQ,OAAO,GAAG;AACvD,SAAOA,SAAQ,SAAS,OAAO,GAAG;AACpC;AAEA,SAASG,eAAc,MAAwB;AAC7C,QAAM,WAAqB,CAAC;AAC5B,QAAM,UAAU,KAAK,YAAY;AACjC,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,WAAW,iBAAiBjB,sBAAqB,GAAG;AAC7D,UAAM,MAAM,QAAQ,YAAY;AAChC,QAAI,QAAQ,SAAS,GAAG,KAAK,CAAC,KAAK,IAAI,GAAG,GAAG;AAC3C,eAAS,KAAK,OAAO;AACrB,WAAK,IAAI,GAAG;AAAA,IACd;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAASkB,cAAa,MAAwB;AAC5C,QAAM,UAAoB,CAAC;AAC3B,aAAW,CAAC,MAAM,OAAO,KAAKjB,kBAAiB;AAC7C,QAAI,QAAQ,KAAK,IAAI,EAAG,SAAQ,KAAK,IAAI;AAAA,EAC3C;AACA,SAAO;AACT;AAEA,SAASkB,mBAAkB,QAA2C;AACpE,QAAM,OAAOR,gBAAe,OAAO,UAAU;AAC7C,MAAI,CAAC,KAAM,QAAO,CAAC;AAEnB,QAAM,SAAoC,CAAC;AAC3C,MAAI,cAAc;AAClB,MAAI,eAAyB,CAAC;AAC9B,aAAW,WAAWC,YAAW,IAAI,GAAG;AACtC,UAAM,OAAOC,QAAO,OAAO;AAC3B,UAAM,QAAQd,eAAc,KAAK,KAAK,KAAK,CAAC;AAC5C,QAAI,OAAO;AACT,UAAI,YAAa,QAAO,KAAK,CAAC,aAAa,YAAY,CAAC;AACxD,oBAAc,MAAM,CAAC;AACrB,YAAM,SAASqB,YAAY,MAAM,CAAC,EAAa,KAAK,GAAG,WAAM;AAC7D,qBAAe,SAAS,CAAC,MAAM,IAAI,CAAC;AACpC;AAAA,IACF;AACA,QAAI,YAAa,cAAa,KAAK,IAAI;AAAA,EACzC;AACA,MAAI,YAAa,QAAO,KAAK,CAAC,aAAa,YAAY,CAAC;AAExD,QAAM,OAAwB,CAAC;AAC/B,aAAW,CAAC,SAAS,KAAK,KAAK,QAAQ;AACrC,UAAM,UAAUL,kBAAiB,KAAK;AACtC,QAAI,QAAQ,WAAW,EAAG;AAC1B,UAAM,OAAO,QAAQ,KAAK,GAAG;AAC7B,UAAM,QAAQC,kBAAiB,QAAQ,OAAO;AAC9C,SAAK,KAAK;AAAA,MACR,YAAY;AAAA,MACZ,MAAM;AAAA,MACN;AAAA,MACA,YAAY;AAAA,MACZ,UAAUC,eAAc,IAAI;AAAA,MAC5B,SAASC,cAAa,IAAI;AAAA,IAC5B,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAGA,SAASE,YAAW,GAAW,OAAuB;AACpD,MAAI,QAAQ;AACZ,MAAI,MAAM,EAAE;AACZ,SAAO,QAAQ,OAAO,MAAM,SAAS,EAAE,KAAK,CAAW,EAAG;AAC1D,SAAO,MAAM,SAAS,MAAM,SAAS,EAAE,MAAM,CAAC,CAAW,EAAG;AAC5D,SAAO,EAAE,MAAM,OAAO,GAAG;AAC3B;AAIA,SAASC,gBAAe,KAAkC;AACxD,QAAM,SAAS,IAAI;AACnB,QAAMC,cAAa;AAAA,IACjB,kBAAkB,OAAO,YAAY;AAAA,IACrC,QAAQ,IAAI,KAAK;AAAA,IACjB,GAAG,IAAI;AAAA,EACT;AACA,QAAM,eAAe,CAAC,OAAO,IAAI;AACjC,MAAI,OAAO,eAAe,KAAM,cAAa,KAAK,OAAO,UAAU;AACnE,aAAO,yBAAY;AAAA,IACjB,MAAM,IAAI;AAAA,IACV,KAAK,OAAO,KAAK,SAAS,IAAK,OAAO,KAAK,CAAC,QAAe,4BAAQ,OAAO,IAAI;AAAA,IAC9E,eAAe,CAAC,GAAG,IAAI,QAAQ;AAAA,IAC/B,aAAaA,YAAW,MAAM,GAAGzB,2BAA0B,CAAC;AAAA,IAC5D,eAAe;AAAA,IACf,YAAY,uBAAW;AAAA,EACzB,CAAC;AACH;AAEA,SAAS0B,4BACP,SACA,MACe;AACf,QAAM,SAAS,oBAAI,IAAyB;AAC5C,aAAW,UAAU,SAAS;AAC5B,WAAO;AAAA,MACL,OAAO;AAAA,UACP,wBAAW;AAAA,QACT,MAAM,OAAO;AAAA,QACb,MAAM;AAAA,QACN,SAAST;AAAA,UACP,qBAAqB,OAAO,IAAI,MAAM,OAAO,MAAM,gBACpC,OAAO,SAAS,aAAa;AAAA,UAC5C;AAAA,QACF;AAAA,QACA,cAAc;AAAA,QACd,MAAM,CAAC,oBAAoB,cAAc,OAAO,OAAO,YAAY,CAAC;AAAA,QACpE,YAAY,uBAAW;AAAA,MACzB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,aAAW,OAAO,MAAM;AACtB,eAAW,WAAW,IAAI,UAAU;AAClC,UAAI,CAAC,OAAO,IAAI,OAAO,GAAG;AACxB,eAAO;AAAA,UACL;AAAA,cACA,wBAAW;AAAA,YACT,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,cAAc,IAAI;AAAA,YAClB,MAAM,CAAC,oBAAoB,qBAAqB;AAAA,YAChD,YAAY,uBAAW;AAAA,UACzB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AACA,eAAW,UAAU,IAAI,SAAS;AAChC,UAAI,CAAC,OAAO,IAAI,MAAM,GAAG;AACvB,eAAO;AAAA,UACL;AAAA,cACA,wBAAW;AAAA,YACT,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,cAAc,IAAI;AAAA,YAClB,MAAM,CAAC,oBAAoB,mBAAmB;AAAA,YAC9C,YAAY,uBAAW;AAAA,UACzB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO,CAAC,GAAG,OAAO,OAAO,CAAC;AAC5B;AASO,IAAM,8BAAN,MAAgE;AAAA,EACrE,UAAUzB;AAAA,EACV,YAAYC;AAAA,EAEK;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjB,OAAO,kBAAkB,MAAuB;AAC9C,WAAO,2BAA2B,IAAI;AAAA,EACxC;AAAA,EAEA,YAAY,gBAAyB,WAAoB;AACvD,SAAK,iBAAiB,kBAAkB,2BAA2B,SAAS;AAC5E,SAAK,SAASE;AAAA,EAChB;AAAA,EAEA,IAAI,aAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,WAAuB;AACrB,QAAI,CAACY,OAAM,KAAK,cAAc,GAAG;AAC/B,YAAM,IAAI;AAAA,QACR,4CAA4C,KAAK,cAAc;AAAA,MACjE;AAAA,IACF;AACA,UAAM,UAAUM,aAAY,KAAK,cAAc;AAC/C,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,SAAS;AAAA,MACT,UAAU;AAAA,QACR,aAAa,QAAQ;AAAA,QACrB,aAAa,QAAQ,OAAO,CAAC,MAAM,EAAE,eAAe,IAAI,EAAE;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AAAA,EAEA,eAAe,OAAc,QAAQ,KAAqB;AACxD,UAAM,WAAW,KAAK,KAAK,QAAW,KAAK,EAAE,IAAIW,eAAc;AAC/D,aAAS,KAAK,CAAC,GAAG,MAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE,OAAO,KAAK,CAAE;AACxE,WAAO,SAAS,MAAM,GAAG,KAAK;AAAA,EAChC;AAAA,EAEA,SAAS,OAA+B;AACtC,UAAM,UAAUX,aAAY,KAAK,cAAc;AAC/C,UAAM,OAAO,KAAK,KAAK,SAAS,KAAK;AACrC,UAAM,WAAW,KAAK,IAAIW,eAAc;AACxC,aAAS,KAAK,CAAC,GAAG,MAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE,OAAO,KAAK,CAAE;AACxE,UAAM,WAAWE,4BAA2B,SAAS,IAAI;AACzD,UAAM,sBAAkB,iCAAoB,UAAU,KAAK,MAAM;AACjE,eAAO,0BAAa;AAAA,MAClB,cAAc;AAAA,MACd,WAAO,2BAAc;AAAA,QACnB,IAAIlC;AAAA,QACJ,MAAMC;AAAA,QACN,cAAU,2BAAS;AAAA,QACnB,qBAAqB;AAAA,QACrB,gBAAgBC;AAAA,MAClB,CAAC;AAAA,MACD,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,MACrC,cAAc,CAAC,2BAA2B,yBAAyB;AAAA,MACnE,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,mBAAmB,KAAK;AAAA,IAC1B,CAAC;AAAA,EACH;AAAA,EAEA,cAA4B;AAC1B,QAAI,CAACa,OAAM,KAAK,cAAc,GAAG;AAC/B,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ,4CAA4C,KAAK,cAAc;AAAA,QACvE,SAAS,EAAE,iBAAiB,KAAK,eAAe;AAAA,QAChD,aAAa;AAAA,MACf;AAAA,IACF;AACA,UAAM,UAAUM,aAAY,KAAK,cAAc;AAC/C,UAAM,OAAO,KAAK,KAAK,OAAO;AAC9B,UAAM,aAAa,QAAQ,SAAS;AACpC,WAAO;AAAA,MACL,QAAQ,aAAa,OAAO;AAAA,MAC5B,QAAQ,aAAa,SAAY;AAAA,MACjC,SAAS;AAAA,QACP,iBAAiB,KAAK;AAAA,QACtB,kBAAkB,QAAQ;AAAA,QAC1B,cAAc,QAAQ,OAAO,CAAC,MAAM,EAAE,eAAe,IAAI,EAAE;AAAA,QAC3D,gBAAgB,KAAK;AAAA,QACrB,oBAAoB,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ,EAAE;AAAA,MACnE;AAAA,MACA,aAAa,aAAa,SAAY;AAAA,IACxC;AAAA,EACF;AAAA;AAAA,EAIQ,KAAK,SAA8B,OAA+B;AACxE,UAAM,YAAY,QAAQ,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE,IAAI;AAC7D,UAAM,OAAwB,CAAC;AAC/B,eAAW,UAAU,WAAWA,aAAY,KAAK,cAAc,GAAG;AAChE,iBAAW,OAAOS,mBAAkB,MAAM,GAAG;AAC3C,YAAI,aAAa,IAAI,OAAO,UAAW;AACvC,aAAK,KAAK,GAAG;AAAA,MACf;AAAA,IACF;AACA,SAAK,KAAK,CAAC,GAAG,MAAM;AAClB,UAAI,EAAE,SAAS,EAAE,KAAM,QAAO,EAAE,OAAO,EAAE,OAAO,IAAI;AACpD,YAAM,KAAK,EAAE,WAAW;AACxB,YAAM,KAAK,EAAE,WAAW;AACxB,UAAI,OAAO,GAAI,QAAO,KAAK,KAAK,IAAI;AACpC,aAAO;AAAA,IACT,CAAC;AACD,WAAO;AAAA,EACT;AACF;;;AC5jBA,IAAAK,mBAA8E;AAC9E,IAAAC,mBAAkC;AAClC,IAAAC,qBAA8B;AAE9B,IAAAC,oBAAmC;AAEnC,IAAAC,cAYO;AACP,IAAAC,qBAA2B;AAY3B,IAAMC,aAAW;AACjB,IAAMC,eAAa;AACnB,IAAMC,gBAAe;AACrB,IAAMC,mBACJ;AAKF,IAAMC,uBAAwC,kCAAqB;AAAA,EACjE,SAAS,uBAAW;AAAA,EACpB,cAAc,CAAC,YAAY,aAAa,cAAc,UAAU,UAAU,OAAO;AAAA,EACjF,WAAW,CAAC,sBAAsB,cAAc,kBAAkB,WAAW;AAC/E,CAAC;AAED,IAAMC,uBAAsB;AAC5B,IAAM,kBAAkB;AACxB,IAAMC,mBAAkB;AACxB,IAAMC,aAAY;AAClB,IAAMC,oBAAmB;AACzB,IAAMC,2BAA0B;AAChC,IAAMC,wBAAuB;AAE7B,IAAMC,iBAAgB;AA2BtB,IAAMC,UAAS;AAAA,EACb,KAAK,KAAmB;AAEtB,YAAQ,KAAK,0BAA0B,GAAG,EAAE;AAAA,EAC9C;AACF;AAyBA,SAASC,WAAkB;AAGzB,MAAI;AACF,eAAO,0BAAQ;AAAA,EACjB,QAAQ;AACN,WAAO,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe;AAAA,EACxD;AACF;AAEA,SAASC,OAAM,GAAoB;AACjC,MAAI;AACF,eAAO,2BAAS,CAAC,EAAE,YAAY;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASC,QAAO,GAAoB;AAClC,MAAI;AACF,eAAO,2BAAS,CAAC,EAAE,OAAO;AAAA,EAC5B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASC,UAAS,GAA0C;AAC1D,SAAO,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC;AAChE;AAGA,SAAS,SAAS,GAAqB;AACrC,MAAI,MAAM,QAAQ,MAAM,UAAa,MAAM,MAAO,QAAO;AACzD,MAAI,OAAO,MAAM,SAAU,QAAO,EAAE,SAAS;AAC7C,MAAI,OAAO,MAAM,SAAU,QAAO,MAAM;AACxC,MAAI,MAAM,QAAQ,CAAC,EAAG,QAAO,EAAE,SAAS;AACxC,SAAO;AACT;AAGA,SAASC,OAAM,GAAoB;AACjC,MAAI,OAAO,MAAM,SAAU,QAAO;AAClC,MAAI,OAAO,MAAM,UAAW,QAAO,IAAI,SAAS;AAChD,MAAI,MAAM,QAAQ,MAAM,OAAW,QAAO;AAC1C,SAAO,OAAO,CAAC;AACjB;AASO,SAAS,6BAA6B,mBAA2C;AACtF,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,IAAK,QAAO;AAChB,QAAM,OAAO,yBAAqB,yBAAKJ,SAAQ,GAAGK,oBAAmB;AACrE,aAAO,yBAAK,MAAM,eAAe;AACnC;AAIA,SAASC,oBAAmB,MAAuC;AACjE,MAAI;AACJ,MAAI;AACF,eAAO,+BAAa,MAAM,MAAM;AAAA,EAClC,SAAS,KAAK;AACZ,IAAAP,QAAO,KAAK,+CAA+C,IAAI,KAAK,OAAO,GAAG,CAAC,EAAE;AACjF,WAAO,CAAC;AAAA,EACV;AACA,MAAI;AACF,UAAM,aAAS,kBAAAQ,OAAU,IAAI;AAC7B,WAAOJ,UAAS,MAAM,IAAI,SAAS,CAAC;AAAA,EACtC,SAAS,KAAK;AACZ,IAAAJ,QAAO,KAAK,+CAA+C,IAAI,KAAK,OAAO,GAAG,CAAC,EAAE;AACjF,WAAO,CAAC;AAAA,EACV;AACF;AAEA,SAASS,aAAY,UAA2C;AAC9D,QAAM,MAAMF,oBAAmB,QAAQ;AACvC,QAAM,gBAAY,4BAAQ,QAAQ;AAClC,QAAM,aAAa,UAAU,MAAM,OAAO,EAAE,OAAO,OAAO,EAAE,IAAI,KAAK;AAErE,QAAM,eAAeF,OAAM,SAAS,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,UAAU,EAAE,KAAK;AAC9E,MAAI,CAAC,aAAc,QAAO;AAE1B,QAAM,OAAOA,OAAM,SAAS,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,IAAI,YAAY,EAAE,KAAK;AAC5E,QAAM,SAASA,OAAM,SAAS,IAAI,QAAQ,CAAC,IAAI,IAAI,QAAQ,IAAI,SAAS,EACrE,KAAK,EACL,YAAY;AACf,QAAM,UAAUA,OAAM,SAAS,IAAI,SAAS,CAAC,IAAI,IAAI,SAAS,IAAI,EAAE,EAAE,KAAK;AAC3E,QAAM,OAAOA,OAAM,SAAS,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,IAAI,EAAE,EAAE,KAAK;AAElE,QAAM,WAAW,SAAS,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC;AAC1D,QAAM,YAAuB,MAAM,QAAQ,QAAQ,IAC/C,WACA,OAAO,aAAa,WAClB,MAAM,KAAK,QAAQ,IACnB,CAAC;AACP,QAAM,QAAQ,UAAU,OAAO,CAAC,MAAmB,OAAO,MAAM,YAAY,EAAE,KAAK,MAAM,EAAE;AAE3F,QAAM,iBAAa,yBAAK,WAAWK,UAAS;AAC5C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN,YAAYP,QAAO,UAAU,IAAI,aAAa;AAAA,EAChD;AACF;AAEA,SAASQ,aAAY,gBAA4C;AAC/D,QAAM,UAA8B,CAAC;AACrC,MAAI,CAACT,OAAM,cAAc,EAAG,QAAO;AAEnC,MAAI;AACJ,MAAI;AACF,kBAAU,8BAAY,cAAc;AAAA,EACtC,QAAQ;AACN,WAAO;AAAA,EACT;AAKA,QAAM,YAAsB,CAAC;AAC7B,aAAW,SAAS,SAAS;AAC3B,UAAM,gBAAY,yBAAK,gBAAgB,OAAOU,gBAAe;AAC7D,QAAIT,QAAO,SAAS,EAAG,WAAU,KAAK,SAAS;AAAA,EACjD;AACA,YAAU,KAAK,CAAC,GAAG,MAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAE;AAErD,aAAW,YAAY,WAAW;AAChC,UAAM,SAASM,aAAY,QAAQ;AACnC,QAAI,WAAW,KAAM,SAAQ,KAAK,MAAM;AAAA,EAC1C;AACA,SAAO;AACT;AAGA,SAASI,YAAW,MAAwB;AAC1C,MAAI,KAAK,WAAW,EAAG,QAAO,CAAC;AAE/B,SAAO,KAAK;AAAA;AAAA,IAEV;AAAA,EACF;AACF;AAGA,SAASC,QAAO,GAAmB;AACjC,SAAO,EAAE,QAAQ,SAAS,EAAE;AAC9B;AAGA,SAASC,YAAW,GAAW,OAAuB;AACpD,MAAI,QAAQ;AACZ,MAAI,MAAM,EAAE;AACZ,SAAO,QAAQ,OAAO,MAAM,SAAS,EAAE,KAAK,CAAE,EAAG;AACjD,SAAO,MAAM,SAAS,MAAM,SAAS,EAAE,MAAM,CAAC,CAAE,EAAG;AACnD,SAAO,EAAE,MAAM,OAAO,GAAG;AAC3B;AAEA,SAASC,mBAAkB,QAA2C;AACpE,MAAI,OAAO,eAAe,KAAM,QAAO,CAAC;AACxC,MAAI;AACJ,MAAI;AACF,eAAO,+BAAa,OAAO,YAAY,MAAM;AAAA,EAC/C,SAAS,KAAK;AACZ,IAAAhB,QAAO,KAAK,8CAA8C,OAAO,UAAU,KAAK,OAAO,GAAG,CAAC,EAAE;AAC7F,WAAO,CAAC;AAAA,EACV;AAEA,SAAO,KAAK,MAAM,CAACiB,iBAAgB;AACnC,QAAM,SAAoC,CAAC;AAC3C,MAAI,cAAc;AAClB,MAAI,eAAyB,CAAC;AAE9B,aAAW,WAAWJ,YAAW,IAAI,GAAG;AACtC,UAAM,OAAOC,QAAO,OAAO;AAC3B,UAAM,QAAQI,eAAc,KAAK,KAAK,KAAK,CAAC;AAC5C,QAAI,OAAO;AACT,UAAI,YAAa,QAAO,KAAK,CAAC,aAAa,YAAY,CAAC;AACxD,oBAAc,MAAM,CAAC;AACrB,YAAM,SAASH,aAAY,MAAM,CAAC,KAAK,IAAI,KAAK,GAAG,WAAM;AACzD,qBAAe,SAAS,CAAC,MAAM,IAAI,CAAC;AACpC;AAAA,IACF;AACA,QAAI,YAAa,cAAa,KAAK,IAAI;AAAA,EACzC;AACA,MAAI,YAAa,QAAO,KAAK,CAAC,aAAa,YAAY,CAAC;AAExD,QAAM,OAAwB,CAAC;AAC/B,aAAW,CAAC,SAAS,KAAK,KAAK,QAAQ;AACrC,UAAM,UAAUI,kBAAiB,KAAK;AACtC,QAAI,QAAQ,WAAW,EAAG;AAC1B,UAAM,QAAQC,kBAAiB,QAAQ,OAAO;AAC9C,SAAK,KAAK;AAAA,MACR,YAAY;AAAA,MACZ,MAAM;AAAA,MACN;AAAA,MACA,YAAY;AAAA,MACZ,OAAO,OAAO;AAAA,IAChB,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,SAASD,kBAAiB,OAA2B;AACnD,QAAM,UAAoB,CAAC;AAC3B,aAAW,QAAQ,OAAO;AACxB,QAAI,UAAU,KAAK,KAAK;AACxB,QAAI,CAAC,QAAS;AACd,eAAW,QAAQ,WAAW,IAAI,IAAI,QAAQ,MAAM,CAAC,IAAI,SAAS,KAAK;AACvE,QAAI,CAAC,WAAW,QAAQ,YAAY,EAAE,WAAW,SAAS,EAAG;AAC7D,UAAM,OAAOE,SAAQC,sBAAqB,OAAO,GAAGC,qBAAoB;AACxE,QAAI,QAAQ,CAAC,QAAQ,SAAS,IAAI,EAAG,SAAQ,KAAK,IAAI;AACtD,QAAI,QAAQ,UAAUC,yBAAyB;AAAA,EACjD;AACA,SAAO;AACT;AAEA,SAASJ,kBAAiB,QAA0B,SAA2B;AAC7E,MAAI,QAAQ,WAAW,EAAG,QAAO,OAAO;AACxC,QAAM,QAAQ,QAAQ,CAAC;AACvB,QAAM,SAAS,GAAG,OAAO,IAAI;AAC7B,MAAI,MAAM,WAAW,MAAM,EAAG,QAAOC,SAAQ,OAAO,GAAG;AACvD,SAAOA,SAAQ,SAAS,OAAO,GAAG;AACpC;AAGA,SAASA,SAAQ,OAAe,OAAuB;AACrD,QAAM,aAAa,MAChB,MAAM,MAAM,EACZ,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,EAC1B,KAAK,GAAG;AACX,MAAI,WAAW,UAAU,MAAO,QAAO;AACvC,SAAOP,QAAO,WAAW,MAAM,GAAG,QAAQ,CAAC,CAAC,IAAI;AAClD;AAGA,SAASQ,sBAAqB,OAAuB;AACnD,aAAO,+BAAW,OAAO,GAAG;AAC9B;AAIA,SAASG,gBAAe,KAAkC;AACxD,QAAM,SAAS,IAAI;AACnB,QAAMC,cAAa;AAAA,IACjB,eAAe,OAAO,YAAY;AAAA,IAClC,OAAO,UAAU,YAAY,OAAO,OAAO,KAAK,SAAS,OAAO,IAAI;AAAA,IACpE,QAAQ,IAAI,KAAK;AAAA,IACjB,GAAG,IAAI;AAAA,EACT;AACA,aAAO,yBAAY;AAAA,IACjB,MAAM,IAAI;AAAA,IACV,SAAK,4BAAQ,OAAO,IAAI;AAAA,IACxB,eAAe,CAAC,GAAG,IAAI,KAAK;AAAA,IAC5B,aAAaA,YAAW,MAAM,GAAGF,2BAA0B,CAAC;AAAA,IAC5D,eAAe,CAAC,OAAO,IAAI;AAAA,IAC3B,YAAY,uBAAW;AAAA,EACzB,CAAC;AACH;AAEA,SAASG,4BACP,SACA,MACe;AACf,QAAM,WAAW,oBAAI,IAAyB;AAE9C,aAAW,UAAU,SAAS;AAC5B,aAAS;AAAA,MACP,OAAO;AAAA,UACP,wBAAW;AAAA,QACT,MAAM,OAAO;AAAA,QACb,MAAM;AAAA,QACN,SAASN;AAAA,UACP,uBAAuB,OAAO,IAAI,MAAM,OAAO,MAAM,eACvC,OAAO,WAAW,aAAa,WAClC,OAAO,QAAQ,aAAa;AAAA,UACvC;AAAA,QACF;AAAA,QACA,cAAc;AAAA,QACd,MAAM,CAAC,sBAAsB,cAAc,OAAO,OAAO,YAAY,CAAC;AAAA,QACtE,YAAY,uBAAW;AAAA,MACzB,CAAC;AAAA,IACH;AAAA,EACF;AAGA,aAAW,OAAO,MAAM;AACtB,eAAW,QAAQ,IAAI,OAAO;AAC5B,UAAI,CAAC,SAAS,IAAI,IAAI,GAAG;AACvB,iBAAS;AAAA,UACP;AAAA,cACA,wBAAW;AAAA,YACT,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,cAAc,IAAI;AAAA,YAClB,MAAM,CAAC,sBAAsB,SAAS;AAAA,YACtC,YAAY,uBAAW;AAAA,UACzB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,CAAC,GAAG,SAAS,OAAO,CAAC;AAC9B;AASO,IAAM,gCAAN,MAAkE;AAAA,EACvE,UAAUO;AAAA,EACV,YAAYC;AAAA,EACZ,cAAcC;AAAA,EAEG;AAAA,EACA;AAAA;AAAA;AAAA,EAIjB,OAAO,kBAAkB,MAAuB;AAC9C,UAAM,WAAO,yBAAK,QAAQ7B,SAAQ,GAAGK,oBAAmB;AACxD,eAAO,yBAAK,MAAM,eAAe;AAAA,EACnC;AAAA,EAEA,YAAY,gBAAgC;AAC1C,SAAK,iBAAiB,kBAAkB,6BAA6B;AACrE,SAAK,SAASyB;AAAA,EAChB;AAAA,EAEA,IAAI,aAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAIA,WAAuB;AACrB,QAAI,CAAC7B,OAAM,KAAK,cAAc,GAAG;AAC/B,YAAM,IAAI;AAAA,QACR,8CAA8C,KAAK,cAAc;AAAA,MAEnE;AAAA,IACF;AACA,UAAM,UAAUS,aAAY,KAAK,cAAc;AAC/C,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,SAAS;AAAA,MACT,UAAU;AAAA,QACR,aAAa,QAAQ;AAAA,QACrB,aAAa,QAAQ,OAAO,CAAC,MAAM,EAAE,eAAe,IAAI,EAAE;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AAAA,EAEA,eAAe,OAAc,QAAQ,KAAqB;AACxD,UAAM,WAAW,KAAK,KAAK,QAAW,KAAK,EAAE,IAAIc,eAAc;AAC/D,aAAS,KAAK,CAAC,GAAG,MAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE,OAAO,KAAK,CAAE;AACxE,WAAO,SAAS,MAAM,GAAG,KAAK;AAAA,EAChC;AAAA,EAEA,SAAS,OAA+B;AACtC,UAAM,UAAUd,aAAY,KAAK,cAAc;AAC/C,UAAM,OAAO,KAAK,KAAK,SAAS,KAAK;AACrC,UAAM,WAAW,KAAK,IAAIc,eAAc;AACxC,aAAS,KAAK,CAAC,GAAG,MAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE,OAAO,KAAK,CAAE;AACxE,UAAM,WAAWE,4BAA2B,SAAS,IAAI;AACzD,UAAM,sBAAkB,iCAAoB,UAAU,KAAK,MAAM;AACjE,eAAO,0BAAa;AAAA,MAClB,cAAc;AAAA,MACd,WAAO,2BAAc;AAAA,QACnB,IAAIC;AAAA,QACJ,MAAMC;AAAA,QACN,cAAU,2BAAS,KAAK;AAAA,QACxB,qBAAqB,KAAK,YAAY;AAAA,QACtC,gBAAgBG;AAAA,MAClB,CAAC;AAAA,MACD,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,MACrC,cAAc,CAAC,6BAA6B,yBAAyB;AAAA,MACrE,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,mBAAmB,KAAK;AAAA,IAC1B,CAAC;AAAA,EACH;AAAA,EAEA,cAA4B;AAC1B,QAAI,CAAC9B,OAAM,KAAK,cAAc,GAAG;AAC/B,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ,8CAA8C,KAAK,cAAc;AAAA,QACzE,SAAS,EAAE,iBAAiB,KAAK,eAAe;AAAA,QAChD,aAAa;AAAA,MACf;AAAA,IACF;AACA,UAAM,UAAUS,aAAY,KAAK,cAAc;AAC/C,UAAM,OAAO,KAAK,KAAK,OAAO;AAC9B,UAAM,aAAa,QAAQ,SAAS;AACpC,WAAO;AAAA,MACL,QAAQ,aAAa,OAAO;AAAA,MAC5B,QAAQ,aAAa,SAAY;AAAA,MACjC,SAAS;AAAA,QACP,iBAAiB,KAAK;AAAA,QACtB,kBAAkB,QAAQ;AAAA,QAC1B,cAAc,QAAQ,OAAO,CAAC,MAAM,EAAE,eAAe,IAAI,EAAE;AAAA,QAC3D,gBAAgB,KAAK;AAAA,QACrB,oBAAoB,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ,EAAE;AAAA,MACnE;AAAA,MACA,aAAa,aACT,SACA;AAAA,IAEN;AAAA,EACF;AAAA;AAAA,EAIQ,KAAK,SAA8B,OAA+B;AACxE,UAAM,YAAY,QAAQ,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE,IAAI;AAC7D,UAAM,MAAuB,CAAC;AAC9B,eAAW,UAAU,WAAWA,aAAY,KAAK,cAAc,GAAG;AAChE,iBAAW,OAAOK,mBAAkB,MAAM,GAAG;AAC3C,YAAI,aAAa,IAAI,OAAO,UAAW;AACvC,YAAI,KAAK,GAAG;AAAA,MACd;AAAA,IACF;AAEA,QAAI,KAAK,CAAC,GAAG,MAAM;AACjB,UAAI,EAAE,SAAS,EAAE,KAAM,QAAO,EAAE,OAAO,EAAE,OAAO,IAAI;AACpD,YAAM,KAAK,EAAE,WAAW;AACxB,YAAM,KAAK,EAAE,WAAW;AACxB,UAAI,OAAO,GAAI,QAAO,KAAK,KAAK,IAAI;AACpC,aAAO;AAAA,IACT,CAAC;AACD,WAAO;AAAA,EACT;AACF;;;ACpjBA,IAAAiB,mBAA8E;AAC9E,IAAAC,mBAAkC;AAClC,IAAAC,qBAA8B;AAE9B,IAAAC,oBAAmC;AAEnC,IAAAC,cAYO;AACP,IAAAC,qBAA2B;AAa3B,IAAMC,aAAW;AACjB,IAAMC,eAAa;AACnB,IAAMC,mBACJ;AAIF,IAAMC,uBAAwC,kCAAqB;AAAA,EACjE,SAAS,uBAAW;AAAA,EACpB,cAAc,CAAC,YAAY,aAAa,cAAc,UAAU,UAAU,OAAO;AAAA,EACjF,WAAW,CAAC,qBAAqB,cAAc,WAAW;AAC5D,CAAC;AAED,IAAMC,wBAAuB;AAC7B,IAAMC,mBAAkB;AACxB,IAAMC,aAAY;AAClB,IAAMC,oBAAmB;AACzB,IAAMC,2BAA0B;AAChC,IAAMC,wBAAuB;AAG7B,IAAMC,iBAAgB;AAEtB,IAAMC,uBAAsB;AAK5B,IAAMC,yBAA2C;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAMC,mBAA4D;AAAA,EAChE,CAAC,0BAA0B,+BAA+B;AAAA,EAC1D,CAAC,gBAAgB,yDAAyD;AAAA,EAC1E,CAAC,iBAAiB,mDAAmD;AAAA,EACrE,CAAC,uBAAuB,6CAA6C;AAAA,EACrE,CAAC,mBAAmB,+CAA+C;AAAA,EACnE,CAAC,aAAa,yDAAyD;AACzE;AA0CA,IAAMC,UAAS;AAAA,EACb,KAAK,KAAmB;AAEtB,YAAQ,KAAK,0BAA0B,GAAG,EAAE;AAAA,EAC9C;AACF;AAIA,SAASC,WAAkB;AAGzB,MAAI;AACF,eAAO,0BAAQ;AAAA,EACjB,QAAQ;AACN,WAAO,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe;AAAA,EACxD;AACF;AAEA,SAASC,QAAM,GAAoB;AACjC,MAAI;AACF,eAAO,2BAAS,CAAC,EAAE,YAAY;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASC,SAAO,GAAoB;AAClC,MAAI;AACF,eAAO,2BAAS,CAAC,EAAE,OAAO;AAAA,EAC5B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,SAAS,QAAQ,GAAqB;AACpC,SAAO,MAAM,UAAa,MAAM,QAAQ,MAAM,MAAM,MAAM,KAAK,MAAM;AACvE;AAGA,SAASC,OAAM,GAAY,UAA0B;AACnD,SAAO,OAAO,QAAQ,CAAC,IAAI,WAAW,CAAC;AACzC;AAGA,SAASC,YAAW,GAAW,OAAuB;AACpD,MAAI,QAAQ;AACZ,MAAI,MAAM,EAAE;AACZ,SAAO,QAAQ,OAAO,MAAM,SAAS,EAAE,KAAK,CAAE,EAAG;AACjD,SAAO,MAAM,SAAS,MAAM,SAAS,EAAE,MAAM,CAAC,CAAE,EAAG;AACnD,SAAO,EAAE,MAAM,OAAO,GAAG;AAC3B;AAGA,SAASC,QAAO,GAAmB;AACjC,SAAO,EAAE,QAAQ,QAAQ,EAAE;AAC7B;AAQA,SAASC,SAAQ,OAAe,OAAuB;AACrD,QAAM,UAAU,MAAM,KAAK;AAC3B,QAAM,aAAa,YAAY,KAAK,KAAK,QAAQ,MAAM,KAAK,EAAE,KAAK,GAAG;AACtE,MAAI,WAAW,UAAU,MAAO,QAAO;AACvC,SAAOD,QAAO,WAAW,MAAM,GAAG,QAAQ,CAAC,CAAC,IAAI;AAClD;AAGA,SAASE,sBAAqB,OAAuB;AACnD,aAAO,+BAAW,OAAO,GAAG;AAC9B;AAKO,SAAS,4BAA4B,YAAoC;AAC9E,MAAI,eAAe,UAAa,eAAe,MAAM;AACnD,eAAO,yBAAK,YAAYC,qBAAoB;AAAA,EAC9C;AACA,QAAM,MAAM,QAAQ,IAAI,cAAc,QAAQ,IAAI;AAClD,MAAI,IAAK,YAAO,yBAAK,KAAKA,qBAAoB;AAC9C,aAAO,yBAAKR,SAAQ,GAAG,WAAWQ,qBAAoB;AACxD;AAIA,SAASC,oBAAmB,MAAuC;AACjE,MAAI;AACJ,MAAI;AACF,eAAO,+BAAa,MAAM,MAAM;AAAA,EAClC,SAAS,KAAK;AACZ,IAAAV,QAAO,KAAK,8CAA8C,IAAI,KAAK,OAAO,GAAG,CAAC,EAAE;AAChF,WAAO,CAAC;AAAA,EACV;AACA,MAAI;AACF,UAAM,aAAS,kBAAAW,OAAU,IAAI;AAC7B,WAAO,OAAO,WAAW,YAAY,WAAW,QAAQ,CAAC,MAAM,QAAQ,MAAM,IACxE,SACD,CAAC;AAAA,EACP,SAAS,KAAK;AACZ,IAAAX,QAAO,KAAK,8CAA8C,IAAI,KAAK,OAAO,GAAG,CAAC,EAAE;AAChF,WAAO,CAAC;AAAA,EACV;AACF;AAEA,SAASY,aAAY,UAA2C;AAC9D,QAAM,MAAMF,oBAAmB,QAAQ;AACvC,QAAM,aAAaG,gBAAW,4BAAQ,QAAQ,CAAC;AAC/C,QAAM,eAAeT,OAAM,IAAI,IAAI,GAAG,UAAU,EAAE,KAAK;AACvD,MAAI,CAAC,aAAc,QAAO;AAC1B,QAAM,OAAOA,OAAM,IAAI,MAAM,GAAG,YAAY,EAAE,KAAK;AACnD,QAAM,SAASA,OAAM,IAAI,QAAQ,GAAG,SAAS,EAAE,KAAK,EAAE,YAAY;AAClE,QAAM,QAAQA,OAAM,IAAI,OAAO,GAAG,EAAE,EAAE,KAAK;AAC3C,QAAM,OAAOA,OAAM,IAAI,MAAM,GAAG,EAAE,EAAE,KAAK;AAEzC,QAAM,UAAU,IAAI,MAAM;AAC1B,QAAM,OAAiB,CAAC;AACxB,MAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,eAAW,OAAO,SAAS;AACzB,UAAI,OAAO,QAAQ,YAAY,IAAI,KAAK,EAAG,MAAK,KAAK,GAAG;AAAA,IAC1D;AAAA,EACF,WAAW,OAAO,YAAY,UAAU;AACtC,eAAW,MAAM,SAAS;AACxB,UAAI,GAAG,KAAK,EAAG,MAAK,KAAK,EAAE;AAAA,IAC7B;AAAA,EACF;AAEA,QAAM,iBAAa,6BAAK,4BAAQ,QAAQ,GAAGU,UAAS;AACpD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN,YAAYX,SAAO,UAAU,IAAI,aAAa;AAAA,EAChD;AACF;AAGA,SAASU,YAAW,GAAmB;AACrC,QAAM,QAAQ,EAAE,MAAM,QAAQ,EAAE,OAAO,CAAC,MAAM,MAAM,EAAE;AACtD,SAAO,MAAM,SAAS,MAAM,MAAM,SAAS,CAAC,IAAK;AACnD;AAOA,SAASE,aAAY,gBAA4C;AAC/D,QAAM,UAA8B,CAAC;AACrC,MAAI,CAACb,QAAM,cAAc,EAAG,QAAO;AACnC,MAAI;AACJ,MAAI;AACF,gBAAQ,8BAAY,cAAc;AAAA,EACpC,QAAQ;AACN,WAAO;AAAA,EACT;AACA,QAAM,YAAsB,CAAC;AAC7B,aAAW,QAAQ,OAAO;AAExB,UAAM,eAAW,yBAAK,gBAAgB,MAAMc,gBAAe;AAC3D,QAAIb,SAAO,QAAQ,EAAG,WAAU,KAAK,QAAQ;AAAA,EAC/C;AACA,YAAU,KAAK,CAAC,GAAG,MAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAE;AACrD,aAAW,YAAY,WAAW;AAChC,UAAM,SAASS,aAAY,QAAQ;AACnC,QAAI,WAAW,KAAM,SAAQ,KAAK,MAAM;AAAA,EAC1C;AACA,SAAO;AACT;AAEA,SAASK,gBAAe,MAA6B;AACnD,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI;AACJ,MAAI;AACF,eAAO,+BAAa,MAAM,MAAM;AAAA,EAClC,SAAS,KAAK;AACZ,IAAAjB,QAAO,KAAK,6CAA6C,IAAI,KAAK,OAAO,GAAG,CAAC,EAAE;AAC/E,WAAO;AAAA,EACT;AACA,SAAO,KAAK,MAAM,CAACkB,iBAAgB;AACrC;AAEA,SAASC,mBAAkB,QAA2C;AACpE,QAAM,OAAOF,gBAAe,OAAO,UAAU;AAC7C,MAAI,CAAC,KAAM,QAAO,CAAC;AAEnB,QAAM,SAAoC,CAAC;AAC3C,MAAI,cAAc;AAClB,MAAI,eAAyB,CAAC;AAC9B,aAAW,WAAW,KAAK,MAAM,OAAO,GAAG;AACzC,UAAM,OAAOX,QAAO,OAAO;AAC3B,UAAM,QAAQc,eAAc,KAAK,KAAK,KAAK,CAAC;AAC5C,QAAI,OAAO;AACT,UAAI,YAAa,QAAO,KAAK,CAAC,aAAa,YAAY,CAAC;AACxD,oBAAc,MAAM,CAAC;AACrB,YAAM,SAASf,YAAW,MAAM,CAAC,EAAG,KAAK,GAAGgB,oBAAmB;AAC/D,qBAAe,SAAS,CAAC,MAAM,IAAI,CAAC;AACpC;AAAA,IACF;AACA,QAAI,YAAa,cAAa,KAAK,IAAI;AAAA,EACzC;AACA,MAAI,YAAa,QAAO,KAAK,CAAC,aAAa,YAAY,CAAC;AAExD,QAAM,OAAwB,CAAC;AAC/B,aAAW,CAAC,SAAS,KAAK,KAAK,QAAQ;AACrC,UAAM,UAAUC,kBAAiB,KAAK;AACtC,QAAI,QAAQ,WAAW,EAAG;AAC1B,UAAM,OAAO,QAAQ,KAAK,GAAG;AAC7B,UAAM,QAAQC,kBAAiB,QAAQ,OAAO;AAC9C,SAAK,KAAK;AAAA,MACR,YAAY;AAAA,MACZ,MAAM;AAAA,MACN;AAAA,MACA,YAAY;AAAA,MACZ,UAAUC,eAAc,IAAI;AAAA,MAC5B,SAASC,cAAa,IAAI;AAAA,IAC5B,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,SAASH,kBAAiB,OAA2B;AACnD,QAAM,UAAoB,CAAC;AAC3B,aAAW,QAAQ,OAAO;AACxB,QAAI,UAAU,KAAK,KAAK;AACxB,QAAI,CAAC,QAAS;AACd,eAAW,QAAQ,WAAW,IAAI,IAAI,QAAQ,MAAM,CAAC,IAAI,SAAS,KAAK;AACvE,UAAM,UAAU,QAAQ,YAAY;AACpC,QAAI,CAAC,WAAW,QAAQ,WAAW,SAAS,EAAG;AAC/C,QAAI,YAAY,eAAe,YAAY,YAAa;AACxD,QAAI,QAAQ,WAAW,MAAM,EAAG,WAAU,QAAQ,MAAM,CAAC,EAAE,KAAK;AAChE,UAAM,OAAOf,SAAQC,sBAAqB,OAAO,GAAGkB,qBAAoB;AACxE,QAAI,QAAQ,CAAC,QAAQ,SAAS,IAAI,EAAG,SAAQ,KAAK,IAAI;AACtD,QAAI,QAAQ,UAAUC,yBAAyB;AAAA,EACjD;AACA,SAAO;AACT;AAEA,SAASJ,kBAAiB,QAA0B,SAA2B;AAC7E,MAAI,QAAQ,WAAW,EAAG,QAAO,OAAO;AACxC,QAAM,QAAQ,QAAQ,CAAC;AACvB,QAAM,SAAS,GAAG,OAAO,IAAI;AAC7B,MAAI,MAAM,WAAW,MAAM,EAAG,QAAOhB,SAAQ,OAAO,GAAG;AACvD,SAAOA,SAAQ,SAAS,OAAO,GAAG;AACpC;AAEA,SAASiB,eAAc,MAAwB;AAC7C,QAAM,WAAqB,CAAC;AAC5B,QAAM,UAAU,KAAK,YAAY;AACjC,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,WAAW,iBAAiBI,sBAAqB,GAAG;AAC7D,UAAM,MAAM,QAAQ,YAAY;AAChC,QAAI,QAAQ,SAAS,GAAG,KAAK,CAAC,KAAK,IAAI,GAAG,GAAG;AAC3C,eAAS,KAAK,OAAO;AACrB,WAAK,IAAI,GAAG;AAAA,IACd;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAASH,cAAa,MAAwB;AAC5C,QAAM,UAAoB,CAAC;AAC3B,aAAW,CAAC,MAAM,OAAO,KAAKI,kBAAiB;AAC7C,QAAI,QAAQ,KAAK,IAAI,EAAG,SAAQ,KAAK,IAAI;AAAA,EAC3C;AACA,SAAO;AACT;AA4LA,SAASC,gBAAe,KAAkC;AACxD,QAAM,SAAS,IAAI;AACnB,QAAMC,cAAa;AAAA,IACjB,kBAAkB,OAAO,YAAY;AAAA,IACrC,QAAQ,IAAI,KAAK;AAAA,IACjB,GAAG,IAAI;AAAA,EACT;AACA,QAAM,eAAe,CAAC,OAAO,IAAI;AACjC,MAAI,OAAO,eAAe,KAAM,cAAa,KAAK,OAAO,UAAU;AACnE,aAAO,yBAAY;AAAA,IACjB,MAAM,IAAI;AAAA,IACV,KAAK,OAAO,KAAK,SAAS,OAAO,KAAK,CAAC,QAAK,4BAAQ,OAAO,IAAI;AAAA,IAC/D,eAAe,CAAC,GAAG,IAAI,QAAQ;AAAA,IAC/B,aAAaA,YAAW,MAAM,GAAGC,2BAA0B,CAAC;AAAA,IAC5D,eAAe;AAAA,IACf,YAAY,uBAAW;AAAA,EACzB,CAAC;AACH;AAEA,SAASC,4BACP,SACA,MACe;AACf,QAAM,iBAAiB,oBAAI,IAAyB;AACpD,aAAW,UAAU,SAAS;AAC5B,mBAAe;AAAA,MACb,OAAO;AAAA,UACP,wBAAW;AAAA,QACT,MAAM,OAAO;AAAA,QACb,MAAM;AAAA,QACN,SAASC;AAAA,UACP,sBAAsB,OAAO,IAAI,MAAM,OAAO,MAAM,gBACrC,OAAO,SAAS,aAAa;AAAA,UAC5C;AAAA,QACF;AAAA,QACA,cAAc;AAAA,QACd,MAAM,CAAC,qBAAqB,cAAc,OAAO,OAAO,YAAY,CAAC;AAAA,QACrE,YAAY,uBAAW;AAAA,MACzB,CAAC;AAAA,IACH;AAAA,EACF;AACA,aAAW,OAAO,MAAM;AACtB,eAAW,WAAW,IAAI,UAAU;AAClC,UAAI,CAAC,eAAe,IAAI,OAAO,GAAG;AAChC,uBAAe;AAAA,UACb;AAAA,cACA,wBAAW;AAAA,YACT,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,cAAc,IAAI;AAAA,YAClB,MAAM,CAAC,qBAAqB,qBAAqB;AAAA,YACjD,YAAY,uBAAW;AAAA,UACzB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AACA,eAAW,UAAU,IAAI,SAAS;AAChC,UAAI,CAAC,eAAe,IAAI,MAAM,GAAG;AAC/B,uBAAe;AAAA,UACb;AAAA,cACA,wBAAW;AAAA,YACT,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,cAAc,IAAI;AAAA,YAClB,MAAM,CAAC,qBAAqB,mBAAmB;AAAA,YAC/C,YAAY,uBAAW;AAAA,UACzB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO,CAAC,GAAG,eAAe,OAAO,CAAC;AACpC;AAGA,SAASC,iBAAwB;AAC/B,UAAO,oBAAI,KAAK,GAAE,YAAY,EAAE,QAAQ,WAAW,QAAQ;AAC7D;AAKO,IAAM,+BAAN,MAAiE;AAAA,EACtE,UAAUC;AAAA,EACV,YAAYC;AAAA,EAEK;AAAA,EACA;AAAA,EAEjB,YAAY,gBAAgC,YAA4B;AACtE,SAAK,iBACH,kBAAkB,4BAA4B,cAAc,MAAS;AACvE,SAAK,SAASC;AAAA,EAChB;AAAA,EAEA,IAAI,aAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,WAAuB;AACrB,QAAI,CAACC,QAAM,KAAK,cAAc,GAAG;AAC/B,YAAM,IAAI;AAAA,QACR,6CAA6C,KAAK,cAAc;AAAA,MAClE;AAAA,IACF;AACA,UAAM,UAAUC,aAAY,KAAK,cAAc;AAC/C,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,SAAS;AAAA,MACT,UAAU;AAAA,QACR,aAAa,QAAQ;AAAA,QACrB,aAAa,QAAQ,OAAO,CAAC,MAAM,EAAE,eAAe,IAAI,EAAE;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AAAA,EAEA,eAAe,OAAc,QAAQ,KAAqB;AACxD,UAAM,WAAW,KAAK,KAAK,QAAW,KAAK,EAAE,IAAIV,eAAc;AAC/D,aAAS,KAAK,CAAC,GAAG,MAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE,OAAO,KAAK,CAAE;AACxE,WAAO,SAAS,MAAM,GAAG,KAAK;AAAA,EAChC;AAAA,EAEA,SAAS,OAA+B;AACtC,UAAM,UAAUU,aAAY,KAAK,cAAc;AAC/C,UAAM,OAAO,KAAK,KAAK,SAAS,KAAK;AACrC,UAAM,WAAW,KAAK,IAAIV,eAAc;AACxC,aAAS,KAAK,CAAC,GAAG,MAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE,OAAO,KAAK,CAAE;AACxE,UAAM,WAAWG,4BAA2B,SAAS,IAAI;AACzD,UAAM,sBAAkB,iCAAoB,UAAU,KAAK,MAAM;AACjE,eAAO,0BAAa;AAAA,MAClB,cAAc;AAAA,MACd,WAAO,2BAAc;AAAA,QACnB,IAAIG;AAAA,QACJ,MAAMC;AAAA,QACN,cAAU,2BAAS;AAAA,QACnB,qBAAqB;AAAA,QACrB,gBAAgBI;AAAA,MAClB,CAAC;AAAA,MACD,cAAcN,eAAc;AAAA,MAC5B,cAAc,CAAC,4BAA4B,yBAAyB;AAAA,MACpE,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,mBAAmB,KAAK;AAAA,IAC1B,CAAC;AAAA,EACH;AAAA,EAEA,cAA4B;AAC1B,QAAI,CAACI,QAAM,KAAK,cAAc,GAAG;AAC/B,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ,6CAA6C,KAAK,cAAc;AAAA,QACxE,SAAS,EAAE,iBAAiB,KAAK,eAAe;AAAA,QAChD,aAAa;AAAA,MACf;AAAA,IACF;AACA,UAAM,UAAUC,aAAY,KAAK,cAAc;AAC/C,UAAM,OAAO,KAAK,KAAK,OAAO;AAC9B,UAAM,aAAa,QAAQ,SAAS;AACpC,UAAM,UAAU;AAAA,MACd,iBAAiB,KAAK;AAAA,MACtB,kBAAkB,QAAQ;AAAA,MAC1B,cAAc,QAAQ,OAAO,CAAC,MAAM,EAAE,eAAe,IAAI,EAAE;AAAA,MAC3D,gBAAgB,KAAK;AAAA,MACrB,oBAAoB,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ,EAAE;AAAA,IACnE;AACA,QAAI,YAAY;AACd,aAAO,EAAE,QAAQ,MAAM,QAAQ;AAAA,IACjC;AACA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR;AAAA,MACA,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EAEQ,KAAK,SAA8B,OAA+B;AACxE,UAAM,YAAY,QAAQ,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE,IAAI;AAC7D,UAAM,OAAwB,CAAC;AAC/B,eAAW,UAAU,WAAWA,aAAY,KAAK,cAAc,GAAG;AAChE,iBAAW,OAAOE,mBAAkB,MAAM,GAAG;AAC3C,YAAI,aAAa,IAAI,OAAO,UAAW;AACvC,aAAK,KAAK,GAAG;AAAA,MACf;AAAA,IACF;AAEA,SAAK,KAAK,CAAC,GAAG,MAAM;AAClB,UAAI,EAAE,SAAS,EAAE,KAAM,QAAO,EAAE,OAAO,EAAE,OAAO,KAAK;AACrD,YAAM,KAAK,EAAE,WAAW;AACxB,YAAM,KAAK,EAAE,WAAW;AACxB,aAAO,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI;AAAA,IACtC,CAAC;AACD,WAAO;AAAA,EACT;AACF;;;AC/wBA,IAAAC,mBAAoD;AACpD,IAAAC,mBAAkC;AAClC,IAAAC,qBAAmD;AAEnD,IAAAC,cAYO;AACP,IAAAC,qBAA2B;AAa3B,IAAMC,aAAW;AACjB,IAAMC,eAAa;AACnB,IAAMC,gBAAe;AACrB,IAAM,sBAAsB;AAC5B,IAAMC,mBACJ;AAOF,IAAM,kBAAkB;AAGxB,IAAM,aAAa;AAGnB,IAAM,eAAe;AACrB,IAAM,gBAAgB;AAGtB,IAAMC,wBAAuB;AAC7B,IAAM,eAAe;AACrB,IAAMC,mBAAkB;AAKxB,IAAMC,yBAA2C;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAMC,uBAAwC,kCAAqB;AAAA,EACjE,SAAS,uBAAW;AAAA,EACpB,cAAc,CAAC,YAAY,aAAa,cAAc,UAAU,UAAU,OAAO;AAAA,EACjF,WAAW,CAAC,kBAAkB,uBAAuB,iBAAiB,WAAW;AACnF,CAAC;AAID,SAASC,QAAM,GAAoB;AACjC,MAAI;AACF,eAAO,2BAAS,CAAC,EAAE,YAAY;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAIA,SAAS,SAAS,MAAuB;AAGvC,MAAI,SAAS,OAAW,QAAO;AAC/B,MAAI;AACF,eAAO,0BAAQ;AAAA,EACjB,QAAQ;AACN,WAAO,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe;AAAA,EACxD;AACF;AAUO,SAAS,wBAAwB,MAA8B;AACpE,QAAM,MAAM,QAAQ,IAAI,eAAe;AACvC,MAAI,IAAK,QAAO;AAEhB,QAAM,OAAO,SAAS,IAAI;AAC1B,MAAI,QAAQ,aAAa,UAAU;AACjC,eAAO,yBAAK,MAAM,WAAW,uBAAuB,QAAQ;AAAA,EAC9D;AACA,MAAI,QAAQ,aAAa,SAAS;AAGhC,QAAI,SAAS,QAAW;AACtB,YAAM,UAAU,QAAQ,IAAI;AAC5B,UAAI,QAAS,YAAO,yBAAK,SAAS,QAAQ;AAAA,IAC5C;AACA,eAAO,yBAAK,MAAM,WAAW,WAAW,QAAQ;AAAA,EAClD;AACA,MAAI,QAAQ,aAAa,SAAS;AAChC,eAAO,yBAAK,MAAM,WAAW,QAAQ;AAAA,EACvC;AACA,SAAO;AACT;AASA,SAAS,eAAe,UAA4B;AAClD,MAAI,CAACA,QAAM,QAAQ,EAAG,QAAO,CAAC;AAC9B,QAAM,MAAgB,CAAC;AACvB,MAAI;AACJ,MAAI;AACF,gBAAQ,8BAAY,QAAQ;AAAA,EAC9B,QAAQ;AACN,WAAO;AAAA,EACT;AACA,aAAW,QAAQ,OAAO;AACxB,UAAM,cAAU,yBAAK,UAAU,IAAI;AACnC,QAAI,CAACA,QAAM,OAAO,EAAG;AACrB,QAAI;AACJ,QAAI;AACF,iBAAO,8BAAY,OAAO;AAAA,IAC5B,QAAQ;AACN;AAAA,IACF;AACA,eAAW,OAAO,MAAM;AACtB,YAAM,aAAS,yBAAK,SAAS,GAAG;AAChC,UAAI,CAACA,QAAM,MAAM,EAAG;AACpB,UAAI;AACJ,UAAI;AACF,oBAAQ,8BAAY,MAAM;AAAA,MAC5B,QAAQ;AACN;AAAA,MACF;AACA,iBAAW,QAAQ,OAAO;AACxB,YAAI,KAAK,WAAW,YAAY,KAAK,cAAc,KAAK,IAAI,GAAG;AAC7D,cAAI,SAAK,yBAAK,QAAQ,IAAI,CAAC;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,MAAI,KAAK,CAAC,GAAG,MAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAE;AAC/C,SAAO;AACT;AAOA,SAAS,cAAc,MAA8C;AACnE,MAAI;AACJ,MAAI;AACF,cAAM,+BAAa,MAAM,MAAM;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI;AACJ,MAAI;AACF,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,MAAM,QAAQ,IAAI,EAAG,QAAO;AAC7E,SAAO;AACT;AASA,SAAS,YAAY,OAAwB;AAC3C,MAAI,OAAO,UAAU,UAAW,QAAO;AACvC,MAAI,MAAqB;AACzB,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM;AAAA,EACR,WAAW,OAAO,UAAU,YAAY,MAAM,KAAK,GAAG;AACpD,UAAM,SAAS,OAAO,MAAM,KAAK,CAAC;AAClC,UAAM,OAAO,MAAM,MAAM,IAAI,OAAO;AAAA,EACtC;AACA,MAAI,QAAQ,QAAQ,CAAC,OAAO,SAAS,GAAG,EAAG,QAAO;AAClD,QAAM,UAAU,MAAM,OAAO,MAAM,MAAO;AAC1C,MAAI;AACF,UAAM,IAAI,IAAI,KAAK,UAAU,GAAI;AACjC,UAAM,MAAM,EAAE,YAAY;AAC1B,WAAO,IAAI,MAAM,GAAG,EAAE;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,SAAS,YAAY,OAAwC;AAC3D,aAAW,OAAO,CAAC,aAAa,gBAAgB,GAAY;AAC1D,UAAM,SAAS,YAAY,MAAM,GAAG,CAAC;AACrC,QAAI,OAAQ,QAAO;AAAA,EACrB;AACA,SAAO;AACT;AAOA,SAASC,SAAQ,OAAe,QAAgBL,uBAA8B;AAC5E,aAAO,+BAAW,OAAO,KAAK;AAChC;AAGA,SAAS,UAAU,OAAgB,QAAgBA,uBAA8B;AAC/E,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,QAAM,OAAO,OAAO,KAAK,EAAE,KAAK;AAChC,MAAI,CAAC,KAAM,QAAO;AAClB,SAAOK,SAAQ,MAAM,KAAK;AAC5B;AAOA,SAAS,qBAAqB,SAA0B;AACtD,MAAI,OAAO,YAAY,YAAY,YAAY,QAAQ,MAAM,QAAQ,OAAO,EAAG,QAAO;AACtF,MAAI,QAAQ;AACZ,aAAW,KAAK,OAAO,OAAO,OAAkC,GAAG;AACjE,QAAI,MAAM,KAAM,UAAS;AAAA,EAC3B;AACA,SAAO;AACT;AAEA,SAAS,SAAS,WAA4B;AAC5C,MAAI,OAAO,cAAc,YAAY,CAAC,UAAU,KAAK,EAAG,QAAO;AAC/D,QAAM,WAAO,6BAAS,UAAU,KAAK,CAAC,EAAE,KAAK;AAC7C,SAAO,QAAQ,SAAS,OAAO,SAAS,OAAO,SAAS,OAAO,OAAO;AACxE;AAOA,SAASC,eAAc,OAA0C;AAC/D,QAAM,WAAqB,CAAC;AAC5B,QAAM,OAAO,oBAAI,IAAY;AAE7B,QAAM,MAAM,CAAC,SAAuB;AAClC,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,WAAW,CAAC,KAAK,IAAI,QAAQ,YAAY,CAAC,GAAG;AAC/C,eAAS,KAAK,OAAO;AACrB,WAAK,IAAI,QAAQ,YAAY,CAAC;AAAA,IAChC;AAAA,EACF;AAEA,QAAM,cAAwB,CAAC;AAC/B,QAAM,MAAM,MAAM,KAAK;AACvB,MAAI,OAAO,QAAQ,YAAY,IAAI,KAAK,EAAG,aAAY,KAAK,GAAG;AAC/D,QAAM,UAAU,MAAM,qBAAqB;AAC3C,MAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,eAAW,KAAK,SAAS;AACvB,UAAI,OAAO,MAAM,YAAY,EAAE,KAAK,EAAG,aAAY,KAAK,CAAC;AAAA,IAC3D;AAAA,EACF;AAEA,aAAW,WAAW,aAAa;AACjC,UAAM,OAAO,SAAS,OAAO;AAC7B,QAAI,KAAM,KAAI,IAAI;AAAA,EACpB;AAEA,QAAM,WAAW,YAAY,KAAK,GAAG,EAAE,YAAY;AACnD,aAAW,QAAQ,iBAAiBJ,sBAAqB,GAAG;AAC1D,QAAI,SAAS,SAAS,KAAK,YAAY,CAAC,EAAG,KAAI,IAAI;AAAA,EACrD;AAEA,SAAO,SAAS,MAAM,GAAG,YAAY;AACvC;AAiBA,SAAS,sBACP,WACA,OACkB;AAClB,QAAM,YAAY,MAAM,WAAW;AACnC,QAAMK,YAAO,mBAAAC,OAAU,SAAS,EAAE;AAClC,SAAO;AAAA,IACL,QAAQ,OAAO,aAAaD,KAAI;AAAA,IAChC,MAAM,YAAY,KAAK;AAAA,IACvB,KAAK,UAAU,MAAM,KAAK,GAAG,GAAG;AAAA,IAChC,OAAO,UAAU,MAAM,OAAO,GAAG,GAAG,KAAK;AAAA,IACzC,OAAO,UAAU,MAAM,OAAO,GAAG,EAAE;AAAA,IACnC,QAAQ,UAAU,MAAM,QAAQ,GAAG,EAAE;AAAA,IACrC,gBAAgB,UAAU,MAAM,gBAAgB,GAAG,EAAE;AAAA,IACrD,YAAY,QAAQ,MAAM,YAAY,CAAC;AAAA,IACvC,cAAc,qBAAqB,MAAM,iBAAiB,CAAC;AAAA,IAC3D,UAAUD,eAAc,KAAK;AAAA,EAC/B;AACF;AAEA,SAAS,WAAW,MAAkC;AACpD,QAAM,UAAoB,CAACD,SAAQ,KAAK,OAAO,GAAG,CAAC;AACnD,MAAI,KAAK,MAAO,SAAQ,KAAKA,SAAQ,UAAU,KAAK,KAAK,IAAI,GAAG,CAAC;AACjE,MAAI,KAAK,OAAQ,SAAQ,KAAKA,SAAQ,WAAW,KAAK,MAAM,IAAI,EAAE,CAAC;AACnE,MAAI,KAAK,eAAgB,SAAQ,KAAKA,SAAQ,eAAe,KAAK,cAAc,IAAI,EAAE,CAAC;AACvF,MAAI,KAAK,aAAc,SAAQ,KAAK,cAAc,KAAK,YAAY,EAAE;AACrE,SAAO,QAAQ,MAAM,GAAGJ,gBAAe;AACzC;AAEA,SAAS,wBAAwB,MAAsC;AACrE,aAAO,yBAAY;AAAA,IACjB,MAAM,KAAK;AAAA,IACX,KAAK,KAAK,OAAO;AAAA,IACjB,eAAe,CAAC,GAAG,KAAK,QAAQ;AAAA,IAChC,aAAa,WAAW,IAAI;AAAA,IAC5B,eAAe,CAAC;AAAA;AAAA,IAChB,YAAY,uBAAW;AAAA,EACzB,CAAC;AACH;AAEA,SAAS,aAAa,OAAqC;AACzD,MAAI,SAAS;AACb,aAAW,QAAQ,MAAO,KAAI,KAAK,eAAe,OAAQ,UAAS,KAAK;AACxE,SAAO,CAACL,YAAU,aAAa,MAAM,EAAE;AACzC;AAEA,SAAS,0BAA0B,OAA0C;AAC3E,MAAI;AACJ,aAAW,QAAQ,OAAO;AACxB,QAAI,aAAa,UAAa,KAAK,OAAO,SAAU,YAAW,KAAK;AAAA,EACtE;AAEA,QAAM,WAAW,oBAAI,IAAyB;AAC9C,WAAS;AAAA,IACP;AAAA,QACA,wBAAW;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAASS;AAAA,QACP;AAAA,QACA;AAAA,MACF;AAAA,MACA,cAAc;AAAA,MACd,MAAM,CAAC,kBAAkB,uBAAuB,eAAe;AAAA,MAC/D,YAAY,uBAAW;AAAA,IACzB,CAAC;AAAA,EACH;AACA,aAAW,QAAQ,OAAO;AACxB,eAAW,WAAW,KAAK,UAAU;AACnC,UAAI,CAAC,SAAS,IAAI,OAAO,GAAG;AAC1B,iBAAS;AAAA,UACP;AAAA,cACA,wBAAW;AAAA,YACT,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,cAAc,KAAK,QAAQ;AAAA,YAC3B,MAAM,CAAC,kBAAkB,uBAAuB,SAAS;AAAA,YACzD,YAAY,uBAAW;AAAA,UACzB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO,CAAC,GAAG,SAAS,OAAO,CAAC;AAC9B;AAQO,IAAM,+BAAN,MAAM,8BAA2D;AAAA,EACtE,UAAUT;AAAA,EACV,YAAYC;AAAA,EACZ,cAAcC;AAAA,EAEG;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjB,OAAO,kBAAkB,MAAuB;AAC9C,UAAM,UAAU,wBAAwB,IAAI;AAC5C,QAAI,YAAY,KAAM,YAAO,yBAAK,SAAS,IAAI,GAAG,UAAU,UAAU;AACtE,eAAO,yBAAK,SAAS,UAAU;AAAA,EACjC;AAAA,EAEA,YAAY,UAAmB,MAAe;AAC5C,SAAK,WAAW,YAAY,8BAA6B,kBAAkB,IAAI;AAC/E,SAAK,SAASK;AAAA,EAChB;AAAA,EAEA,IAAI,aAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,WAAuB;AACrB,QAAI,CAACC,QAAM,KAAK,QAAQ,GAAG;AACzB,YAAM,IAAI;AAAA,QACR,0CAA0C,KAAK,QAAQ;AAAA,MACzD;AAAA,IACF;AACA,UAAM,aAAa,eAAe,KAAK,QAAQ;AAC/C,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,SAAS;AAAA,MACT,UAAU,EAAE,eAAe,WAAW,OAAO;AAAA,IAC/C;AAAA,EACF;AAAA,EAEA,eAAe,OAAc,QAAQ,KAAqB;AACxD,UAAM,QAAQ,KAAK,cAAc,KAAK;AACtC,UAAM,WAAW,MAAM,IAAI,uBAAuB;AAClD,aAAS,KAAK,CAAC,GAAG,MAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE,OAAO,KAAK,CAAE;AACxE,WAAO,SAAS,MAAM,GAAG,KAAK;AAAA,EAChC;AAAA,EAEA,SAAS,OAA+B;AACtC,QAAI,CAACA,QAAM,KAAK,QAAQ,GAAG;AACzB,YAAM,IAAI;AAAA,QACR,0CAA0C,KAAK,QAAQ;AAAA,MACzD;AAAA,IACF;AACA,UAAM,QAAQ,KAAK,cAAc,KAAK;AACtC,UAAM,WAAW,MAAM,IAAI,uBAAuB;AAClD,aAAS,KAAK,CAAC,GAAG,MAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE,OAAO,KAAK,CAAE;AACxE,UAAM,WAAW,0BAA0B,KAAK;AAChD,UAAM,sBAAkB,iCAAoB,UAAU,KAAK,MAAM;AACjE,eAAO,0BAAa;AAAA,MAClB,cAAc;AAAA,MACd,WAAO,2BAAc;AAAA,QACnB,IAAIR;AAAA,QACJ,MAAMC;AAAA,QACN,cAAU,2BAAS;AAAA,QACnB,qBAAqB;AAAA,QACrB,gBAAgBE;AAAA,MAClB,CAAC;AAAA,MACD,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,MACrC,cAAc,aAAa,KAAK;AAAA,MAChC,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,mBAAmB,KAAK;AAAA,IAC1B,CAAC;AAAA,EACH;AAAA,EAEA,cAA4B;AAC1B,QAAI,CAACK,QAAM,KAAK,QAAQ,GAAG;AACzB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ,0CAA0C,KAAK,QAAQ;AAAA,QAC/D,SAAS,EAAE,WAAW,KAAK,SAAS;AAAA,QACpC,aACE;AAAA,MAGJ;AAAA,IACF;AACA,QAAI;AACJ,QAAI;AACJ,QAAI;AACJ,QAAI;AACF,mBAAa,eAAe,KAAK,QAAQ;AACzC,YAAM,YAAY,KAAK,qBAAqB;AAC5C,cAAQ,UAAU;AAClB,kBAAY,UAAU;AAAA,IACxB,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,SAAS,EAAE,OAAO,OAAO,GAAG,EAAE;AAAA,QAC9B,aACE;AAAA,MAEJ;AAAA,IACF;AACA,QAAI,WAAW,WAAW,GAAG;AAC3B,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,SAAS,EAAE,WAAW,KAAK,SAAS;AAAA,QACpC,aACE;AAAA,MAEJ;AAAA,IACF;AACA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,WAAW,KAAK;AAAA,QAChB,oBAAoB,WAAW;AAAA,QAC/B,yBAAyB,MAAM;AAAA,QAC/B,mBAAmB;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIQ,uBAAyE;AAC/E,UAAM,QAA4B,CAAC;AACnC,QAAI,YAAY;AAChB,eAAW,aAAa,eAAe,KAAK,QAAQ,GAAG;AACrD,YAAM,QAAQ,cAAc,SAAS;AACrC,UAAI,UAAU,MAAM;AAClB,qBAAa;AACb;AAAA,MACF;AACA,YAAM,KAAK,sBAAsB,WAAW,KAAK,CAAC;AAAA,IACpD;AACA,WAAO,EAAE,OAAO,UAAU;AAAA,EAC5B;AAAA,EAEQ,cAAc,OAAkC;AACtD,QAAI,EAAE,MAAM,IAAI,KAAK,qBAAqB;AAC1C,QAAI,UAAU,QAAW;AACvB,YAAM,SAAS,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE;AAC9C,cAAQ,MAAM,OAAO,CAAC,SAAS,CAAC,KAAK,QAAQ,KAAK,QAAQ,MAAM;AAAA,IAClE;AAEA,UAAM,KAAK,CAAC,GAAG,MAAM;AACnB,UAAI,EAAE,SAAS,EAAE,KAAM,QAAO,EAAE,OAAO,EAAE,OAAO,IAAI;AACpD,UAAI,EAAE,WAAW,EAAE,OAAQ,QAAO,EAAE,SAAS,EAAE,SAAS,IAAI;AAC5D,aAAO;AAAA,IACT,CAAC;AACD,WAAO;AAAA,EACT;AACF;;;ACzjBA,IAAAK,mBAAoD;AACpD,IAAAC,mBAAyB;AACzB,IAAAC,qBAA4D;AAE5D,IAAAC,cAYO;AACP,IAAAC,qBAA2B;AAa3B,IAAMC,aAAW;AACjB,IAAMC,eAAa;AACnB,IAAMC,gBAAe;AACrB,IAAMC,uBAAsB;AAC5B,IAAMC,mBACJ;AAKF,IAAMC,uBAAwC,kCAAqB;AAAA,EACjE,SAAS,uBAAW;AAAA,EACpB,cAAc,CAAC,YAAY,aAAa,cAAc,UAAU,UAAU,OAAO;AAAA,EACjF,WAAW,CAAC,kBAAkB,yBAAyB,iBAAiB,WAAW;AACrF,CAAC;AAID,IAAMC,mBAAkB;AAGxB,IAAM,eAAe;AAGrB,IAAMC,gBAAe;AAErB,IAAMC,gBAAe;AACrB,IAAMC,mBAAkB;AAGxB,IAAM,kBAAkB;AAKxB,IAAMC,yBAA2C;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGA,IAAMC,UAAS;AAAA,EACb,KAAK,KAAmB;AAEtB,YAAQ,KAAK,0BAA0B,GAAG,EAAE;AAAA,EAC9C;AACF;AAIA,SAASC,QAAM,GAAoB;AACjC,MAAI;AACF,eAAO,2BAAS,CAAC,EAAE,YAAY;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASC,SAAO,GAAoB;AAClC,MAAI;AACF,eAAO,2BAAS,CAAC,EAAE,OAAO;AAAA,EAC5B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASC,WAAkB;AACzB,SAAO,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe;AACxD;AAEA,SAASC,UAAS,GAA0C;AAC1D,SAAO,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC;AAChE;AAIA,SAAS,aAAqB;AAC5B,UAAO,oBAAI,KAAK,GAAE,YAAY,EAAE,QAAQ,aAAa,QAAQ;AAC/D;AAgBA,SAASC,yBAAwB,MAA8B;AAC7D,QAAM,MAAM,QAAQ,IAAIV,gBAAe;AACvC,MAAI,IAAK,QAAO;AAEhB,QAAM,OAAO,QAAQQ,SAAQ;AAC7B,QAAM,OAAO,QAAQ;AACrB,MAAI,SAAS,UAAU;AACrB,eAAO,yBAAK,MAAM,WAAW,uBAAuB,QAAQ;AAAA,EAC9D;AACA,MAAI,KAAK,WAAW,KAAK,GAAG;AAG1B,QAAI,SAAS,QAAW;AACtB,YAAM,UAAU,QAAQ,IAAI;AAC5B,UAAI,QAAS,YAAO,yBAAK,SAAS,QAAQ;AAAA,IAC5C;AACA,eAAO,yBAAK,MAAM,WAAW,WAAW,QAAQ;AAAA,EAClD;AACA,MAAI,KAAK,WAAW,OAAO,GAAG;AAC5B,eAAO,yBAAK,MAAM,WAAW,QAAQ;AAAA,EACvC;AACA,SAAO;AACT;AAOA,SAASG,gBAAe,UAA4B;AAClD,MAAI,CAACL,QAAM,QAAQ,EAAG,QAAO,CAAC;AAC9B,QAAM,MAAgB,CAAC;AACvB,MAAI;AACJ,MAAI;AACF,mBAAW,8BAAY,QAAQ;AAAA,EACjC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACA,aAAW,QAAQ,UAAU;AAC3B,UAAM,cAAU,yBAAK,UAAU,IAAI;AACnC,QAAI,CAACA,QAAM,OAAO,EAAG;AACrB,QAAI;AACJ,QAAI;AACF,iBAAO,8BAAY,OAAO;AAAA,IAC5B,QAAQ;AACN;AAAA,IACF;AACA,eAAW,OAAO,MAAM;AACtB,YAAM,aAAS,yBAAK,SAAS,GAAG;AAChC,UAAI,CAACA,QAAM,MAAM,EAAG;AACpB,UAAI;AACJ,UAAI;AACF,sBAAU,8BAAY,MAAM;AAAA,MAC9B,QAAQ;AACN;AAAA,MACF;AACA,iBAAW,QAAQ,SAAS;AAC1B,YAAI,KAAK,WAAWL,aAAY,KAAK,KAAK,SAAS,OAAO,GAAG;AAC3D,cAAI,SAAK,yBAAK,QAAQ,IAAI,CAAC;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,MAAI,KAAK;AACT,SAAO;AACT;AAOA,SAASW,eAAc,MAA8C;AACnE,MAAI;AACJ,MAAI;AACF,cAAM,+BAAa,MAAM,MAAM;AAAA,EACjC,SAAS,KAAK;AACZ,IAAAP,QAAO,KAAK,+BAA+B,IAAI,KAAK,OAAO,GAAG,CAAC,EAAE;AACjE,WAAO;AAAA,EACT;AACA,MAAI;AACJ,MAAI;AACF,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,SAAS,KAAK;AACZ,IAAAA,QAAO,KAAK,gCAAgC,IAAI,KAAK,OAAO,GAAG,CAAC,EAAE;AAClE,WAAO;AAAA,EACT;AACA,SAAOI,UAAS,IAAI,IAAI,OAAO;AACjC;AASA,SAASI,aAAY,OAAwB;AAC3C,MAAI,OAAO,UAAU,UAAW,QAAO;AACvC,MAAI,MAAqB;AACzB,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM;AAAA,EACR,WAAW,OAAO,UAAU,YAAY,MAAM,KAAK,GAAG;AACpD,UAAM,IAAI,OAAO,MAAM,KAAK,CAAC;AAC7B,UAAM,OAAO,MAAM,CAAC,IAAI,OAAO;AAAA,EACjC;AACA,MAAI,QAAQ,QAAQ,OAAO,MAAM,GAAG,EAAG,QAAO;AAC9C,QAAM,UAAU,MAAM,OAAO,MAAM,MAAO;AAC1C,MAAI;AACF,UAAM,IAAI,IAAI,KAAK,UAAU,GAAI;AACjC,QAAI,OAAO,MAAM,EAAE,QAAQ,CAAC,EAAG,QAAO;AACtC,WAAO,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AAAA,EACpC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,SAASC,aAAY,OAAwC;AAC3D,aAAW,OAAO,CAAC,aAAa,gBAAgB,GAAG;AACjD,UAAM,SAASD,aAAY,MAAM,GAAG,CAAC;AACrC,QAAI,OAAQ,QAAO;AAAA,EACrB;AACA,SAAO;AACT;AAGA,SAASE,SAAQ,OAAe,QAAQ,KAAa;AACnD,aAAO,+BAAW,OAAO,KAAK;AAChC;AAGA,SAASC,WAAU,OAAgB,QAAQ,KAAa;AACtD,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,QAAM,OAAO,OAAO,KAAK,EAAE,KAAK;AAChC,MAAI,CAAC,KAAM,QAAO;AAClB,SAAOD,SAAQ,MAAM,KAAK;AAC5B;AAMA,SAASE,sBAAqB,SAA0B;AACtD,MAAI,CAACR,UAAS,OAAO,EAAG,QAAO;AAC/B,MAAI,IAAI;AACR,aAAW,KAAK,OAAO,OAAO,OAAO,GAAG;AACtC,QAAI,MAAM,KAAM,MAAK;AAAA,EACvB;AACA,SAAO;AACT;AAEA,SAASS,YAAW,WAA4B;AAC9C,MAAI,OAAO,cAAc,YAAY,CAAC,UAAU,KAAK,EAAG,QAAO;AAC/D,QAAM,WAAO,6BAAS,UAAU,KAAK,CAAC,EAAE,KAAK;AAC7C,SAAO,QAAQ,SAAS,OAAO,SAAS,OAAO,SAAS,OAAO,OAAO;AACxE;AAOA,SAASC,eAAc,OAA0C;AAC/D,QAAM,WAAqB,CAAC;AAC5B,QAAM,OAAO,oBAAI,IAAY;AAE7B,QAAM,MAAM,CAAC,SAAuB;AAClC,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,WAAW,CAAC,KAAK,IAAI,QAAQ,YAAY,CAAC,GAAG;AAC/C,eAAS,KAAK,OAAO;AACrB,WAAK,IAAI,QAAQ,YAAY,CAAC;AAAA,IAChC;AAAA,EACF;AAEA,QAAM,cAAwB,CAAC;AAC/B,QAAM,MAAM,MAAM,KAAK;AACvB,MAAI,OAAO,QAAQ,YAAY,IAAI,KAAK,EAAG,aAAY,KAAK,GAAG;AAC/D,QAAM,UAAU,MAAM,qBAAqB;AAC3C,MAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,eAAW,KAAK,SAAS;AACvB,UAAI,OAAO,MAAM,YAAY,EAAE,KAAK,EAAG,aAAY,KAAK,CAAC;AAAA,IAC3D;AAAA,EACF;AAEA,aAAW,OAAO,aAAa;AAC7B,UAAM,OAAOD,YAAW,GAAG;AAC3B,QAAI,KAAM,KAAI,IAAI;AAAA,EACpB;AAEA,QAAM,WAAW,YAAY,KAAK,GAAG,EAAE,YAAY;AACnD,aAAW,QAAQ,iBAAiBd,sBAAqB,GAAG;AAC1D,QAAI,SAAS,SAAS,KAAK,YAAY,CAAC,EAAG,KAAI,IAAI;AAAA,EACrD;AAEA,SAAO,SAAS,MAAM,GAAGF,aAAY;AACvC;AAKA,SAAS,UAAU,WAA2B;AAC5C,aAAO,6BAAK,4BAAQ,SAAS,OAAG,mBAAAkB,OAAU,SAAS,EAAE,IAAI;AAC3D;AAOA,SAAS,kBAAkB,QAAiC,KAAoC;AAC9F,QAAM,UAAU,OAAO,MAAM;AAC7B,QAAM,UAAU,OAAO,SAAS;AAEhC,MAAI,YAAY,YAAY,YAAY,QAAQ;AAE9C,UAAM,QAAkD;AAAA,MACtD,CAAC,SAAS,YAAY;AAAA,MACtB,CAAC,eAAe,kBAAkB;AAAA,MAClC,CAAC,UAAU,aAAa;AAAA,MACxB,CAAC,WAAW,cAAc;AAAA,MAC1B,CAAC,kBAAkB,qBAAqB;AAAA,IAC1C;AACA,eAAW,CAAC,QAAQ,MAAM,KAAK,OAAO;AACpC,YAAM,QAAQ,OAAO,MAAM;AAC3B,UAAI,MAAM,QAAQ,KAAK,EAAG,KAAI,MAAM,IAAI,MAAM;AAAA,IAChD;AACA,UAAM,UAAU,OAAO,qBAAqB;AAC5C,QAAI,YAAY,QAAQ,YAAY,QAAW;AAC7C,UAAI,qBAAqB,IAAIJ,WAAU,SAAS,EAAE;AAAA,IACpD;AACA;AAAA,EACF;AAEA,MAAI,YAAY,UAAU;AAExB,eAAW,OAAO,CAAC,kBAAkB,aAAa,YAAY,aAAa,GAAG;AAC5E,UAAI,OAAO,OAAQ,KAAI,GAAG,IAAI,OAAO,GAAG;AAAA,IAC1C;AACA,UAAM,aAAa,OAAO,aAAa;AACvC,QAAI,eAAe,QAAQ,eAAe,QAAW;AACnD,UAAI,aAAa,IAAIA,WAAU,YAAY,EAAE;AAAA,IAC/C;AAAA,EACF;AACF;AAOA,SAAS,iBAAiB,QAAyC;AACjE,QAAM,gBAAY,yBAAK,QAAQ,aAAa;AAC5C,MAAI,CAACT,SAAO,SAAS,EAAG,QAAO,CAAC;AAEhC,QAAM,MAA+B,CAAC;AACtC,MAAI;AACJ,MAAI;AACF,cAAM,+BAAa,WAAW,MAAM;AAAA,EACtC,SAAS,KAAK;AACZ,IAAAF,QAAO,KAAK,+BAA+B,SAAS,KAAK,OAAO,GAAG,CAAC,EAAE;AACtE,WAAO;AAAA,EACT;AAEA,MAAI,SAAS;AACb,aAAW,WAAW,IAAI,MAAM,OAAO,GAAG;AACxC,QAAI,UAAU,gBAAiB;AAC/B,cAAU;AACV,UAAM,OAAO,QAAQ,KAAK;AAC1B,QAAI,CAAC,QAAQ,KAAK,CAAC,MAAM,IAAK;AAC9B,QAAI;AACJ,QAAI;AACF,eAAS,KAAK,MAAM,IAAI;AAAA,IAC1B,QAAQ;AACN;AAAA,IACF;AACA,QAAI,CAACI,UAAS,MAAM,EAAG;AACvB,sBAAkB,QAAQ,GAAG;AAAA,EAC/B;AACA,SAAO;AACT;AAqBA,SAAS,aAAa,WAAmB,OAA2C;AAClF,QAAM,QAAQ,iBAAiB,UAAU,SAAS,CAAC;AAEnD,QAAM,QAAQO,WAAU,MAAM,OAAO,GAAG,GAAG,KAAK;AAChD,QAAM,QAAQA,WAAU,MAAM,OAAO,GAAG,EAAE;AAC1C,QAAM,iBAAiBA,WAAU,MAAM,gBAAgB,GAAG,EAAE;AAE5D,QAAM,cAAc,MAAM,WAAW;AACrC,QAAM,UAAU,MAAM,gBAAgB;AACtC,QAAM,aAAa,MAAM,UAAU;AAEnC,QAAM,aAAqC,CAAC;AAC5C,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC1C,QAAI,EAAE,WAAW,OAAO,KAAK,OAAO,MAAM,YAAY,OAAO,UAAU,CAAC,GAAG;AACzE,iBAAW,CAAC,IAAI;AAAA,IAClB;AAAA,EACF;AAEA,QAAMK,YAAO,mBAAAD,OAAU,SAAS,EAAE;AAClC,QAAM,MAAM,MAAM,WAAW;AAE7B,SAAO;AAAA,IACL,OAAO,OAAO,OAAOC,KAAI;AAAA,IACzB,MAAMP,aAAY,KAAK;AAAA,IACvB,KAAKE,WAAU,MAAM,KAAK,GAAG,GAAG;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY,QAAQ,MAAM,YAAY,CAAC;AAAA,IACvC,cAAcC,sBAAqB,MAAM,iBAAiB,CAAC;AAAA,IAC3D,UAAUE,eAAc,KAAK;AAAA,IAC7B,UAAU,OAAO,gBAAgB,YAAY,OAAO,UAAU,WAAW,IAAI,cAAc;AAAA,IAC3F,cAAc,OAAO,YAAY,WAAW,UAAU;AAAA,IACtD,SAAS,OAAO,eAAe,YAAY,aAAa;AAAA,IACxD;AAAA,EACF;AACF;AAOA,SAASG,YAAW,KAA0B;AAC5C,QAAM,UAAoB,CAACP,SAAQ,IAAI,OAAO,GAAG,CAAC;AAClD,MAAI,IAAI,MAAO,SAAQ,KAAKA,SAAQ,UAAU,IAAI,KAAK,IAAI,GAAG,CAAC;AAC/D,MAAI,IAAI,eAAgB,SAAQ,KAAKA,SAAQ,eAAe,IAAI,cAAc,IAAI,EAAE,CAAC;AACrF,MAAI,IAAI,aAAa,KAAM,SAAQ,KAAK,GAAG,IAAI,QAAQ,QAAQ;AAC/D,MAAI,IAAI,iBAAiB,KAAM,SAAQ,KAAK,IAAI,IAAI,aAAa,QAAQ,CAAC,CAAC,EAAE;AAC7E,MAAI,IAAI,QAAS,SAAQ,KAAK,OAAO;AACrC,MAAI,IAAI,aAAc,SAAQ,KAAK,cAAc,IAAI,YAAY,EAAE;AACnE,SAAO,QAAQ,MAAM,GAAGZ,gBAAe;AACzC;AAEA,SAASoB,gBAAe,KAA8B;AACpD,aAAO,yBAAY;AAAA,IACjB,MAAM,IAAI;AAAA,IACV,KAAK,IAAI,OAAO;AAAA;AAAA,IAChB,eAAe,CAAC,GAAG,IAAI,QAAQ;AAAA,IAC/B,aAAaD,YAAW,GAAG;AAAA,IAC3B,eAAe,CAAC;AAAA;AAAA,IAChB,YAAY,uBAAW;AAAA,EACzB,CAAC;AACH;AAGA,SAASE,cAAa,MAA6B;AACjD,QAAM,OAAiB,CAAC9B,UAAQ;AAChC,QAAM,SAAS,KAAK,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,IAAI;AAC5E,OAAK,KAAK,aAAa,MAAM,EAAE;AAC/B,QAAM,YAAY,KAAK,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,CAAC,MAAM,EAAE,WAAW,YAAY,KAAK,CAAC,CAAC,IAAI;AAChG,MAAI,UAAW,MAAK,KAAK,SAAS,SAAS,EAAE;AAC7C,QAAM,aAAa,KAAK,SACpB,KAAK,IAAI,GAAG,KAAK,IAAI,CAAC,MAAM,EAAE,WAAW,aAAa,KAAK,CAAC,CAAC,IAC7D;AACJ,MAAI,WAAY,MAAK,KAAK,UAAU,UAAU,EAAE;AAChD,SAAO;AACT;AAEA,SAAS,iBAAiB,MAAkC;AAC1D,QAAM,WAAW,KAAK,SAClB,KAAK,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,MAAO,IAAI,IAAI,IAAI,CAAE,IACxD;AAEJ,QAAM,WAAW,oBAAI,IAAyB;AAC9C,WAAS;AAAA,IACPG;AAAA,QACA,wBAAW;AAAA,MACT,MAAMA;AAAA,MACN,MAAM;AAAA,MACN,SAASkB;AAAA,QACP;AAAA,QAEA;AAAA,MACF;AAAA,MACA,cAAc;AAAA,MACd,MAAM,CAAC,kBAAkB,yBAAyB,eAAe;AAAA,MACjE,YAAY,uBAAW;AAAA,IACzB,CAAC;AAAA,EACH;AAEA,aAAW,OAAO,MAAM;AACtB,eAAW,WAAW,IAAI,UAAU;AAClC,UAAI,CAAC,SAAS,IAAI,OAAO,GAAG;AAC1B,iBAAS;AAAA,UACP;AAAA,cACA,wBAAW;AAAA,YACT,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,cAAc,IAAI,QAAQ;AAAA;AAAA,YAC1B,MAAM,CAAC,kBAAkB,yBAAyB,SAAS;AAAA,YAC3D,YAAY,uBAAW;AAAA,UACzB,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,CAAC,GAAG,SAAS,OAAO,CAAC;AAC9B;AAKO,IAAM,iCAAN,MAAM,gCAA6D;AAAA,EACxE,UAAUrB;AAAA,EACV,YAAYC;AAAA,EACZ,cAAcC;AAAA,EAEG;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQjB,OAAO,kBAAkB,MAAuB;AAC9C,UAAM,UAAUc,yBAAwB,IAAI;AAC5C,QAAI,YAAY,KAAM,YAAO,yBAAK,QAAQF,SAAQ,GAAG,UAAU,YAAY;AAC3E,eAAO,yBAAK,SAAS,YAAY;AAAA,EACnC;AAAA,EAEA,YAAY,UAAmB,MAAe;AAC5C,SAAK,WAAW,YAAY,gCAA+B,kBAAkB,IAAI;AACjF,SAAK,SAAST;AAAA,EAChB;AAAA,EAEA,IAAI,aAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAIA,WAAuB;AACrB,QAAI,CAACO,QAAM,KAAK,QAAQ,GAAG;AACzB,YAAM,IAAI;AAAA,QACR,6CAA6C,KAAK,QAAQ;AAAA,MAC5D;AAAA,IACF;AACA,UAAM,aAAaK,gBAAe,KAAK,QAAQ;AAC/C,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,SAAS;AAAA,MACT,UAAU,EAAE,MAAM,WAAW,OAAO;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,eAAe,OAAc,QAAQ,KAAqB;AACxD,UAAM,OAAO,KAAK,KAAK,KAAK;AAC5B,UAAM,WAAW,KAAK,IAAIY,eAAc;AACxC,aAAS,KAAK,CAAC,GAAG,MAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE,OAAO,KAAK,CAAE;AACxE,WAAO,SAAS,MAAM,GAAG,KAAK;AAAA,EAChC;AAAA,EAEA,SAAS,OAA+B;AACtC,QAAI,CAACjB,QAAM,KAAK,QAAQ,GAAG;AACzB,YAAM,IAAI;AAAA,QACR,6CAA6C,KAAK,QAAQ;AAAA,MAC5D;AAAA,IACF;AACA,UAAM,OAAO,KAAK,KAAK,KAAK;AAC5B,UAAM,WAAW,KAAK,IAAIiB,eAAc;AACxC,aAAS,KAAK,CAAC,GAAG,MAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE,OAAO,KAAK,CAAE;AACxE,UAAM,WAAW,iBAAiB,IAAI;AACtC,UAAM,sBAAkB,iCAAoB,UAAU,KAAK,MAAM;AAEjE,eAAO,0BAAa;AAAA,MAClB,cAAc;AAAA,MACd,WAAO,2BAAc;AAAA,QACnB,IAAI7B;AAAA,QACJ,MAAMC;AAAA,QACN,cAAU,2BAAS;AAAA,QACnB,qBAAqB;AAAA,QACrB,gBAAgBG;AAAA,MAClB,CAAC;AAAA,MACD,cAAc,WAAW;AAAA,MACzB,cAAc0B,cAAa,IAAI;AAAA,MAC/B,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,mBAAmB,KAAK;AAAA,IAC1B,CAAC;AAAA,EACH;AAAA,EAEA,cAA4B;AAC1B,QAAI,CAAClB,QAAM,KAAK,QAAQ,GAAG;AACzB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ,6CAA6C,KAAK,QAAQ;AAAA,QAClE,SAAS,EAAE,WAAW,KAAK,SAAS;AAAA,QACpC,aACE;AAAA,MAGJ;AAAA,IACF;AAEA,QAAI;AACJ,QAAI;AACJ,QAAI;AACJ,QAAI;AACF,mBAAaK,gBAAe,KAAK,QAAQ;AACzC,OAAC,MAAM,SAAS,IAAI,KAAK,YAAY;AAAA,IACvC,SAAS,KAAK;AACZ,MAAAN,QAAO,KAAK,uDAAuD,OAAO,GAAG,CAAC,EAAE;AAChF,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,SAAS,EAAE,OAAO,OAAO,GAAG,EAAE;AAAA,QAC9B,aACE;AAAA,MAEJ;AAAA,IACF;AAEA,QAAI,WAAW,WAAW,GAAG;AAC3B,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,SAAS,EAAE,WAAW,KAAK,SAAS;AAAA,QACpC,aACE;AAAA,MAEJ;AAAA,IACF;AAEA,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,WAAW,KAAK;AAAA,QAChB,WAAW,WAAW;AAAA,QACtB,gBAAgB,KAAK;AAAA,QACrB,mBAAmB;AAAA,QACnB,mBAAmB,KAAK,OAAO,CAAC,MAAM,EAAE,aAAa,IAAI,EAAE;AAAA,MAC7D;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIQ,cAAqC;AAC3C,UAAM,OAAoB,CAAC;AAC3B,QAAI,YAAY;AAChB,eAAW,aAAaM,gBAAe,KAAK,QAAQ,GAAG;AACrD,YAAM,QAAQC,eAAc,SAAS;AACrC,UAAI,UAAU,MAAM;AAClB,qBAAa;AACb;AAAA,MACF;AACA,WAAK,KAAK,aAAa,WAAW,KAAK,CAAC;AAAA,IAC1C;AACA,WAAO,CAAC,MAAM,SAAS;AAAA,EACzB;AAAA,EAEQ,KAAK,OAA2B;AACtC,UAAM,CAAC,IAAI,IAAI,KAAK,YAAY;AAChC,QAAI,WAAW;AACf,QAAI,UAAU,QAAW;AACvB,YAAM,SAAS,IAAI,KAAK,MAAM,QAAQ,CAAC,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AAClE,iBAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,IAAI,QAAQ,MAAM;AAAA,IACjE;AACA,aAAS,KAAK,CAAC,GAAG,MAAM;AACtB,UAAI,EAAE,SAAS,EAAE,KAAM,QAAO,EAAE,OAAO,EAAE,OAAO,IAAI;AACpD,UAAI,EAAE,UAAU,EAAE,MAAO,QAAO,EAAE,QAAQ,EAAE,QAAQ,IAAI;AACxD,aAAO;AAAA,IACT,CAAC;AACD,WAAO;AAAA,EACT;AACF;;;AC/sBA,IAAAa,mBAAoD;AACpD,IAAAC,mBAA4C;AAC5C,IAAAC,qBAA+B;AAE/B,IAAAC,cAYO;AACP,IAAAC,qBAA2B;AAU3B,IAAMC,aAAW;AACjB,IAAMC,eAAa;AACnB,IAAMC,iBAAe;AACrB,IAAMC,mBACJ;AAKF,IAAMC,uBAAwC,kCAAqB;AAAA,EACjE,SAAS,uBAAW;AAAA,EACpB,cAAc,CAAC,YAAY,aAAa,cAAc,UAAU,UAAU,OAAO;AAAA,EACjF,WAAW,CAAC,kBAAkB,WAAW,UAAU,WAAW;AAChE,CAAC;AAED,IAAM,mBAAmB;AACzB,IAAM,kBAAkB;AACxB,IAAM,kBAAkB;AACxB,IAAMC,mBAAkB;AACxB,IAAMC,wBAAuB;AAC7B,IAAMC,qBAAoB;AAC1B,IAAM,wBAAwB;AAI9B,SAASC,YAAkB;AAGzB,MAAI;AACF,eAAO,0BAAQ;AAAA,EACjB,QAAQ;AACN,WAAO,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe;AAAA,EACxD;AACF;AAEA,SAASC,QAAM,GAAoB;AACjC,MAAI;AACF,eAAO,2BAAS,CAAC,EAAE,YAAY;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,SAASC,sBAAqB,OAAe,QAAQ,KAAa;AAChE,aAAO,+BAAW,OAAO,KAAK;AAChC;AAOA,SAASC,SAAQ,OAAe,OAAuB;AACrD,QAAM,aAAa,MAAM,MAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAC9D,MAAI,WAAW,UAAU,MAAO,QAAO;AACvC,SAAO,WAAW,MAAM,GAAG,QAAQ,CAAC,EAAE,QAAQ,QAAQ,EAAE,IAAI;AAC9D;AAGA,SAASC,YAAW,MAAwB;AAC1C,SAAO,KAAK,MAAM,YAAY;AAChC;AAUO,SAAS,mCAAkD;AAChE,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,IAAK,QAAO;AAGhB,QAAM,aAAS,2BAAS;AACxB,MAAI,WAAW,SAAS;AACtB,UAAM,UAAU,QAAQ,IAAI;AAC5B,QAAI,QAAS,YAAO,yBAAK,SAAS,QAAQ,QAAQ,kBAAkB;AACpE,WAAO;AAAA,EACT;AACA,MAAI,WAAW,UAAU;AACvB,eAAO;AAAA,MACLJ,UAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU;AAChB,MAAIC,QAAM,OAAO,GAAG;AAClB,QAAI;AACF,iBAAW,iBAAa,8BAAY,OAAO,GAAG;AAC5C,YAAI;AACF,gBAAM,SAAK;AAAA,YACT;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AACA,cAAIA,QAAM,EAAE,EAAG,QAAO;AAAA,QACxB,QAAQ;AACN;AAAA,QACF;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,QAAM,SAAS,QAAQ,IAAI,uBAAmB,yBAAKD,UAAQ,GAAG,SAAS;AACvE,aAAO,yBAAK,QAAQ,QAAQ,QAAQ,kBAAkB;AACxD;AAGA,SAAS,oBAAoB,kBAAoC;AAC/D,MAAI,CAACC,QAAM,gBAAgB,EAAG,QAAO,CAAC;AACtC,QAAM,OAAiB,CAAC;AACxB,MAAI;AACF,eAAW,cAAU,8BAAY,gBAAgB,GAAG;AAClD,YAAM,cAAU,yBAAK,kBAAkB,QAAQ,gBAAgB;AAC/D,UAAIA,QAAM,OAAO,EAAG,MAAK,KAAK,OAAO;AAAA,IACvC;AAAA,EACF,SAAS,KAAK;AACZ,IAAAI,QAAO,KAAK,4DAA4D,OAAO,GAAG,CAAC,EAAE;AAAA,EACvF;AACA,SAAO;AACT;AAGA,IAAMA,UAAS;AAAA,EACb,KAAK,KAAmB;AAEtB,YAAQ,KAAK,0BAA0B,GAAG,EAAE;AAAA,EAC9C;AACF;AAmBA,SAAS,gBAAgB,MAAqC;AAC5D,MAAI;AACJ,MAAI;AACF,eAAO,+BAAa,MAAM,MAAM;AAAA,EAClC,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,KAAK,KAAK,IAAID,YAAW,KAAK,KAAK,CAAC,IAAI,CAAC;AACvD,MAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,QAAM,OAAuB;AAAA,IAC3B,iBAAiB;AAAA,IACjB,YAAY,KAAK,IAAI;AAAA,IACrB,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe,CAAC;AAAA,IAChB,YAAY;AAAA,EACd;AAEA,MAAI,YAAY;AAChB,QAAM,WAAqB,CAAC;AAE5B,aAAW,QAAQ,MAAM,MAAM,GAAG,qBAAqB,GAAG;AACxD,QAAI;AACJ,QAAI;AACF,cAAQ,KAAK,MAAM,IAAI;AAAA,IACzB,QAAQ;AACN;AAAA,IACF;AACA,QAAI,OAAO,UAAU,YAAY,UAAU,KAAM;AACjD,UAAM,KAAK;AACX,UAAM,YAAY,GAAG,MAAM;AAC3B,UAAM,UAAU,GAAG,MAAM;AACzB,UAAM,OACJ,OAAO,YAAY,YAAY,YAAY,OACtC,UACD,CAAC;AAEP,QAAI,cAAc,iBAAiB;AACjC,WAAK,aAAa,KAAK,WAAW,KAAK,OAAO,OAAO,OAAO,KAAK,WAAW,CAAC;AAC7E,WAAK,WAAW,KAAK,UAAU,KAAK;AACpC,WAAK,kBAAkB,KAAK,gBAAgB,KAAK;AACjD,WAAK,iBAAiB,KAAK,eAAe,KAAK;AAAA,IACjD,WAAW,cAAc,gBAAgB;AACvC,YAAM,UAAU,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS,CAAC,IAAI;AAC5D,UAAI,SAAS;AAEX,iBAAS,KAAK,QAAQ,MAAM,GAAG,GAAG,CAAC;AAAA,MACrC;AAAA,IACF,WAAW,cAAc,sBAAsB;AAC7C,mBAAa;AAAA,IACf;AAAA,EACF;AAEA,OAAK,gBAAgB,SAAS,MAAM,GAAG,EAAE;AACzC,OAAK,aAAa;AAClB,SAAO;AACT;AAGA,SAAS,KAAK,GAAmB;AAC/B,QAAM,OAAO,EAAE,QAAQ,WAAW,EAAE,EAAE,MAAM,OAAO,EAAE,IAAI,KAAK;AAC9D,SAAO,KAAK,QAAQ,YAAY,EAAE;AACpC;AAYA,SAAS,aAAa,KAAuB;AAC3C,QAAM,MAAgB,CAAC;AACvB,MAAI;AACJ,MAAI;AACF,kBAAU,8BAAY,GAAG,EAAE,KAAK;AAAA,EAClC,QAAQ;AACN,WAAO;AAAA,EACT;AACA,aAAW,QAAQ,SAAS;AAC1B,UAAM,WAAO,yBAAK,KAAK,IAAI;AAC3B,QAAIH,QAAM,IAAI,GAAG;AACf,UAAI,KAAK,GAAG,aAAa,IAAI,CAAC;AAAA,IAChC,WAAW,KAAK,SAAS,KAAK,GAAG;AAC/B,UAAI,KAAK,IAAI;AAAA,IACf;AAAA,EACF;AACA,SAAO;AACT;AAMA,SAAS,iBAAiB,SAA+B;AACvD,QAAM,gBAAY,yBAAK,SAAS,iBAAiB,UAAU;AAC3D,MAAI,CAACA,QAAM,SAAS,EAAG,QAAO,CAAC;AAE/B,QAAM,WAAyB,CAAC;AAChC,aAAW,UAAU,aAAa,SAAS,GAAG;AAC5C,QAAI;AACJ,QAAI;AACF,iBAAO,+BAAa,QAAQ,MAAM;AAAA,IACpC,QAAQ;AACN;AAAA,IACF;AACA,QAAI,CAAC,KAAK,KAAK,EAAG;AAGlB,UAAM,UAAM,6BAAS,WAAW,MAAM;AACtC,UAAM,OAAO,IAAI,QAAQ,eAAe,EAAE,EAAE,QAAQ,OAAO,GAAG;AAC9D,UAAM,cAAc,KAAK,MAAM,MAAM,EAAE,SAAS,KAAK,KAAK,WAAW,IAAI,IAAI,IAAI;AACjF,aAAS,KAAK,EAAE,MAAM,SAAS,MAAM,MAAM,QAAQ,cAAc,YAAY,CAAC;AAAA,EAChF;AACA,SAAO;AACT;AAIA,SAAS,sBAAsB,MAAoC;AACjE,QAAM,QAAQ,KAAK,cAAc;AACjC,QAAM,UAAU,QAAQ,MAAM,MAAM,GAAG,EAAE,IAAI;AAE7C,QAAMK,cAAuB,CAAC;AAC9B,QAAM,OAAO,KAAK,iBAAiB,CAAC;AACpC,MAAI,KAAK,SAAS,GAAG;AACnB,IAAAA,YAAW,KAAKH,SAAQD,sBAAqB,OAAO,KAAK,CAAC,CAAC,CAAC,GAAGJ,qBAAoB,CAAC;AAAA,EACtF;AACA,MAAI,KAAK,WAAY,CAAAQ,YAAW,KAAK,UAAU,KAAK,UAAU,EAAE;AAChE,MAAI,KAAK,gBAAiB,CAAAA,YAAW,KAAK,YAAY,OAAO,KAAK,eAAe,CAAC,EAAE;AACpF,MAAI,KAAK,SAAU,CAAAA,YAAW,KAAK,SAAS,OAAO,KAAK,QAAQ,CAAC,EAAE;AAEnE,aAAO,yBAAY;AAAA,IACjB,MAAM;AAAA,IACN,KAAK;AAAA,IACL,eAAe,CAAC;AAAA,IAChB,aAAaA,YAAW,MAAM,GAAGT,gBAAe;AAAA,IAChD,eAAe,CAAC;AAAA,IAChB,YAAY,uBAAW;AAAA,EACzB,CAAC;AACH;AAEA,SAAS,qBAAqB,UAAuC;AACnE,QAAM,WAA0B,CAAC;AACjC,aAAW,OAAO,UAAU;AAC1B,UAAM,UAAoB,CAAC;AAC3B,eAAW,QAAQO,YAAW,IAAI,OAAO,GAAG;AAC1C,YAAM,WAAW,KAAK,KAAK;AAC3B,UAAI,SAAS,WAAW,IAAI,GAAG;AAC7B,gBAAQ,KAAK,SAAS,MAAM,CAAC,EAAE,KAAK,CAAC;AACrC,YAAI,QAAQ,WAAW,EAAG;AAAA,MAC5B;AAAA,IACF;AACA,QAAI,UACF,QAAQ,SAAS,IAAI,QAAQ,KAAK,IAAI,IAAI;AAC5C,QAAI,QAAS,WAAUD,SAAQD,sBAAqB,OAAO,GAAGH,kBAAiB;AAE/E,aAAS;AAAA,UACP,wBAAW;AAAA,QACT,MAAM,IAAI;AAAA,QACV,MAAM;AAAA,QACN;AAAA,QACA,cAAc;AAAA,QACd,MAAM,CAAC,kBAAkB,eAAe,aAAa;AAAA,QACrD,YAAY,uBAAW;AAAA,MACzB,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,wBAAwB,aAA8C;AAE7E,QAAM,cAAc,oBAAI,IAAoB;AAC5C,aAAW,QAAQ,aAAa;AAC9B,UAAM,OAAO,KAAK,iBAAiB,CAAC;AACpC,QAAI,KAAK,SAAS,GAAG;AACnB,YAAM,QAAQ,OAAO,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG;AAC1C,YAAM,aAAa,WAAW,KAAK,KAAK;AACxC,UAAI,YAAY;AACd,cAAM,QAAQ,mBAAmB,WAAW,CAAC,CAAC;AAC9C,oBAAY,IAAI,QAAQ,YAAY,IAAI,KAAK,KAAK,KAAK,CAAC;AAAA,MAC1D;AAAA,IACF;AAAA,EACF;AAGA,QAAM,UAAU,CAAC,GAAG,YAAY,QAAQ,CAAC,EACtC,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAC1B,MAAM,GAAG,EAAE;AAEd,QAAM,WAA0B,CAAC;AACjC,aAAW,CAAC,OAAO,KAAK,KAAK,SAAS;AACpC,aAAS;AAAA,UACP,wBAAW;AAAA,QACT,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,gCAAgC,KAAK;AAAA,QAC9C,MAAM,CAAC,kBAAkB,YAAY;AAAA,QACrC,YAAY,uBAAW;AAAA,MACzB,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AASO,IAAM,2BAAN,MAA6D;AAAA,EAClE,UAAUP;AAAA,EACV,YAAYC;AAAA,EACZ,cAAcC;AAAA,EAEG;AAAA;AAAA,EAGjB,OAAO,kBAAkB,MAAuB;AAC9C,QAAI,SAAS,QAAW;AACtB,iBAAO,yBAAK,MAAM,WAAW,QAAQ,QAAQ,kBAAkB;AAAA,IACjE;AACA,QAAI;AACJ,QAAI;AACF,WAAK,iCAAiC;AAAA,IACxC,QAAQ;AACN,WAAK;AAAA,IACP;AACA,QAAI,OAAO,KAAM,QAAO;AACxB,eAAO,yBAAKM,UAAQ,GAAG,WAAW,QAAQ,QAAQ,kBAAkB;AAAA,EACtE;AAAA,EAEA,YAAY,kBAA2B;AACrC,SAAK,mBAAmB,oBAAoB;AAAA,EAC9C;AAAA,EAEA,IAAI,aAAqB;AACvB,WAAO,KAAK,oBAAoB,iCAAiC,KAAK;AAAA,EACxE;AAAA,EAEQ,YAA2B;AACjC,WAAO,KAAK,oBAAoB,iCAAiC;AAAA,EACnE;AAAA;AAAA,EAIA,WAAuB;AACrB,UAAM,KAAK,KAAK,UAAU;AAC1B,QAAI,OAAO,QAAQ,CAACC,QAAM,EAAE,GAAG;AAC7B,YAAM,IAAI;AAAA,QACR,yCAAyC,MAAM,MAAM;AAAA,MAEvD;AAAA,IACF;AACA,UAAM,WAAW,oBAAoB,EAAE;AACvC,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,IAAI;AAAA,QACR,2CAA2C,EAAE;AAAA,MAE/C;AAAA,IACF;AACA,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,QACR,iBAAiB,SAAS;AAAA,QAC1B,wBAAwB;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,eAAe,OAAc,QAAQ,KAAqB;AACxD,UAAM,WAAW,QAAQ,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE,IAAI;AAC5D,UAAM,cAAc,KAAK,eAAe;AACxC,UAAM,WAA2B,CAAC;AAClC,eAAW,QAAQ,aAAa;AAC9B,YAAM,UAAU,sBAAsB,IAAI;AAC1C,UAAI,YAAY,QAAQ,QAAQ,QAAQ,OAAO,SAAU;AACzD,eAAS,KAAK,OAAO;AACrB,UAAI,SAAS,UAAU,MAAO;AAAA,IAChC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,OAA+B;AACtC,UAAM,cAAc,KAAK,eAAe;AACxC,UAAM,WAAW,KAAK,YAAY;AAElC,UAAM,WAAW,QAAQ,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE,IAAI;AAC5D,UAAM,WAA2B,CAAC;AAClC,eAAW,QAAQ,aAAa;AAC9B,YAAM,UAAU,sBAAsB,IAAI;AAC1C,UAAI,YAAY,QAAQ,QAAQ,QAAQ,OAAO,SAAU;AACzD,eAAS,KAAK,OAAO;AAAA,IACvB;AAEA,UAAM,WAAW;AAAA,MACf,GAAG,qBAAqB,QAAQ;AAAA,MAChC,GAAG,wBAAwB,WAAW;AAAA,IACxC;AACA,UAAM,sBAAkB,iCAAoB,UAAUL,gBAAc;AAEpE,eAAO,0BAAa;AAAA,MAClB,cAAc;AAAA,MACd,WAAO,2BAAc;AAAA,QACnB,IAAIJ;AAAA,QACJ,MAAMC;AAAA,QACN,cAAU,2BAAS,KAAK;AAAA,QACxB,qBAAqB,KAAK,YAAY;AAAA,QACtC,gBAAgBE;AAAA,MAClB,CAAC;AAAA,MACD,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,MACrC,cAAc;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,mBAAmBC;AAAA,IACrB,CAAC;AAAA,EACH;AAAA,EAEA,cAA4B;AAC1B,QAAI;AACF,YAAM,KAAK,KAAK,UAAU;AAC1B,UAAI,OAAO,QAAQ,CAACK,QAAM,EAAE,GAAG;AAC7B,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,QAAQ,yCAAyC,MAAM,MAAM;AAAA,UAC7D,SAAS,EAAE,eAAe,MAAM,OAAO;AAAA,UACvC,aACE;AAAA,QAEJ;AAAA,MACF;AACA,YAAM,WAAW,oBAAoB,EAAE;AACvC,UAAI,SAAS,WAAW,GAAG;AACzB,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,SAAS,EAAE,mBAAmB,GAAG;AAAA,UACjC,aACE;AAAA,QAEJ;AAAA,MACF;AACA,YAAM,cAAc,KAAK,eAAe;AACxC,YAAM,WAAW,KAAK,YAAY;AAClC,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,mBAAmB;AAAA,UACnB,iBAAiB,SAAS;AAAA,UAC1B,kBAAkB,YAAY;AAAA,UAC9B,mBAAmB,SAAS;AAAA,UAC5B,aAAa,YAAY,OAAO,CAAC,KAAK,MAAM,OAAO,EAAE,cAAc,IAAI,CAAC;AAAA,QAC1E;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AAEZ,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ,qBAAqB,OAAO,GAAG,CAAC;AAAA,QACxC,SAAS,CAAC;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA,EAKQ,iBAAmC;AACzC,UAAM,KAAK,KAAK,UAAU;AAC1B,QAAI,OAAO,KAAM,QAAO,CAAC;AACzB,UAAM,WAAW,oBAAoB,EAAE;AACvC,UAAM,cAAgC,CAAC;AACvC,eAAW,WAAW,UAAU;AAC9B,YAAM,oBAAgB,yBAAK,SAAS,eAAe;AACnD,UAAI,CAACA,QAAM,aAAa,EAAG;AAC3B,UAAI;AACJ,UAAI;AACF,oBAAQ,8BAAY,aAAa,EAAE,KAAK;AAAA,MAC1C,QAAQ;AACN;AAAA,MACF;AACA,iBAAW,SAAS,OAAO;AACzB,YAAI,CAAC,MAAM,SAAS,QAAQ,EAAG;AAC/B,cAAM,OAAO,oBAAgB,yBAAK,eAAe,KAAK,CAAC;AACvD,YAAI,SAAS,KAAM,aAAY,KAAK,IAAI;AAAA,MAC1C;AAAA,IACF;AAEA,gBAAY,KAAK,CAAC,GAAG,MAAM;AACzB,YAAM,KAAK,EAAE,cAAc;AAC3B,YAAM,KAAK,EAAE,cAAc;AAC3B,aAAO,KAAK,KAAK,IAAI,KAAK,KAAK,KAAK;AAAA,IACtC,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,cAA4B;AAClC,UAAM,KAAK,KAAK,UAAU;AAC1B,QAAI,OAAO,KAAM,QAAO,CAAC;AACzB,UAAM,WAAW,oBAAoB,EAAE;AACvC,UAAM,WAAyB,CAAC;AAChC,eAAW,WAAW,UAAU;AAC9B,eAAS,KAAK,GAAG,iBAAiB,OAAO,CAAC;AAAA,IAC5C;AACA,WAAO;AAAA,EACT;AACF;;;ACnmBA,IAAAM,mBAAuC;AACvC,IAAAC,mBAAwB;AACxB,IAAAC,qBAAqB;AAGd,IAAM,sBAAsB;AAG5B,IAAM,8BAA8B;AAG3C,SAAS,cAAc,OAAuB;AAC5C,SAAO,MAAM,KAAK,EAAE,QAAQ,QAAQ,GAAG;AACzC;AAEA,SAASC,QAAM,MAAuB;AACpC,MAAI;AACF,eAAO,2BAAS,IAAI,EAAE,YAAY;AAAA,EACpC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAiBO,SAAS,iBAAiB,UAAyC;AACxE,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,KAAK;AAEP,QAAIA,QAAM,GAAG,EAAG,QAAO;AAAA,EACzB;AACA,QAAM,OAAO,WAAW,eAAW,0BAAQ;AAC3C,QAAM,gBAAY,yBAAK,MAAM,QAAQ;AACrC,SAAOA,QAAM,SAAS,IAAI,YAAY;AACxC;AAUO,SAAS,kBACd,MACA,OAC2B;AAC3B,MAAI;AACJ,MAAI;AACF,QAAI,KAAC,2BAAS,IAAI,EAAE,OAAO,EAAG,QAAO,CAAC;AACtC,eAAO,+BAAa,MAAM,MAAM;AAAA,EAClC,SAAS,KAAK;AAEZ,QAAI,YAAY,IAAI,EAAG,SAAQ,KAAK,kBAAkB,IAAI,KAAK,OAAO,GAAG,CAAC,EAAE;AAC5E,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,UAAqC,CAAC;AAC5C,QAAM,QAAQ,KAAK,MAAM,OAAO;AAChC,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,GAAG;AACxC,UAAM,OAAO,MAAM,CAAC,EAAG,KAAK;AAC5B,QAAI,CAAC,KAAM;AACX,QAAI;AACJ,QAAI;AACF,eAAS,KAAK,MAAM,IAAI;AAAA,IAC1B,SAAS,KAAK;AACZ,cAAQ,KAAK,+BAA+B,IAAI,IAAI,IAAI,CAAC,OAAO,OAAO,GAAG,CAAC,EAAE;AAC7E;AAAA,IACF;AACA,QACE,WAAW,QACX,OAAO,WAAW,YAClB,CAAC,MAAM,QAAQ,MAAM,KACrB,OAAQ,OAAmC,OAAO,UAClD;AACA,cAAQ,KAAK,MAAiC;AAAA,IAChD;AAAA,EACF;AAIA,UAAQ,KAAK,CAAC,GAAG,MAAM;AACrB,UAAM,KAAK,OAAO,EAAE,cAAc,EAAE;AACpC,UAAM,KAAK,OAAO,EAAE,cAAc,EAAE;AACpC,WAAO,KAAK,KAAK,IAAI,KAAK,KAAK,KAAK;AAAA,EACtC,CAAC;AACD,SAAO,UAAU,UAAa,UAAU,OAAO,QAAQ,MAAM,GAAG,KAAK,IAAI;AAC3E;AAGA,SAAS,YAAY,MAAuB;AAC1C,MAAI;AACF,mCAAS,IAAI;AACb,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAeO,SAAS,oBACd,WACA,OAA2B,CAAC,GACJ;AACxB,QAAM,QAAQ,KAAK,SAAS;AAC5B,QAAM,OACJ,cAAc,UAAa,cAAc,OAAO,iBAAiB,IAAI;AACvE,MAAI,SAAS,KAAM,QAAO,CAAC;AAE3B,QAAM,SAAiC,CAAC;AACxC,aAAW,SAAS,sBAAkB,yBAAK,MAAM,qBAAqB,GAAG,KAAK,GAAG;AAC/E,UAAM,MAAM,MAAM;AAClB,UAAM,OAAO,MAAM;AACnB,QACE,OAAO,QAAQ,YACf,OACA,OAAO,SAAS,YAChB,KAAK,KAAK,KACV,EAAE,OAAO,SACT;AACA,aAAO,GAAG,IAAI,cAAc,IAAI;AAAA,IAClC;AAAA,EACF;AACA,SAAO;AACT;AAmBO,SAAS,qBACd,WACA,OAA2B,CAAC,GACZ;AAChB,QAAM,QAAQ,KAAK,SAAS;AAC5B,QAAM,OACJ,cAAc,UAAa,cAAc,OAAO,iBAAiB,IAAI;AACvE,MAAI,SAAS,KAAM,QAAO,CAAC;AAE3B,QAAM,UAA0B,CAAC;AACjC,aAAW,SAAS,sBAAkB,yBAAK,MAAM,qBAAqB,GAAG,KAAK,GAAG;AAC/E,UAAM,MAAM,MAAM;AAClB,QAAI,OAAO,QAAQ,YAAY,CAAC,IAAK;AACrC,UAAM,OAAO,MAAM;AACnB,UAAM,QACJ,OAAO,SAAS,YAAY,KAAK,KAAK,IAAI,cAAc,IAAI,IAAI;AAClE,UAAM,UAAU,OAAO,MAAM,cAAc,EAAE;AAC7C,YAAQ,KAAK;AAAA,MACX,UAAU,IAAI,MAAM,GAAG,CAAC;AAAA,MACxB;AAAA,MACA,YAAY,WAAW;AAAA,IACzB,CAAC;AAAA,EACH;AACA,SAAO;AACT;;;ACjNA,IAAAC,cAQO;AACP,IAAAC,qBAA2B;;;ACQ3B,IAAAC,mBAAoD;AACpD,IAAAC,mBAAwB;AACxB,IAAAC,qBAAqB;AAErB,IAAAC,cASO;AACP,IAAAC,qBAA2B;AAM3B,IAAM,oBAAoB,IAAI,IAAY,OAAO,OAAO,sBAAU,CAAa;AAMxE,SAAS,gBAAgB,KAAiC;AAC/D,MAAI,OAAO,QAAQ,SAAU,QAAO;AACpC,QAAM,QAAQ,IAAI,KAAK,EAAE,YAAY;AACrC,SAAO,kBAAkB,IAAI,KAAK,IAAK,QAAuB;AAChE;AAQO,SAASC,SAAQ,KAA6B;AACnD,MAAI,OAAO,QAAQ,YAAY,CAAC,IAAI,KAAK,EAAG,QAAO;AACnD,QAAM,OAAO,IAAI,KAAK;AACtB,MAAI,KAAK,SAAS,GAAG,GAAG;AACtB,UAAMC,UAAS,IAAI,KAAK,KAAK,QAAQ,MAAM,QAAQ,CAAC;AACpD,QAAI,OAAO,MAAMA,QAAO,QAAQ,CAAC,EAAG,QAAO;AAC3C,WAAOA,QAAO,YAAY,EAAE,MAAM,GAAG,EAAE;AAAA,EACzC;AAGA,MAAI,CAAC,sBAAsB,KAAK,IAAI,EAAG,QAAO;AAC9C,QAAM,SAAS,oBAAI,KAAK,GAAG,IAAI,YAAY;AAC3C,MAAI,OAAO,MAAM,OAAO,QAAQ,CAAC,EAAG,QAAO;AAE3C,SAAO,OAAO,YAAY,EAAE,MAAM,GAAG,EAAE,MAAM,OAAO,OAAO;AAC7D;AAGO,SAAS,QAAQ,KAAc,QAAQ,KAAa;AACzD,MAAI,QAAQ,QAAQ,QAAQ,OAAW,QAAO;AAC9C,QAAM,OAAO,OAAO,GAAG,EAAE,KAAK;AAC9B,SAAO,WAAO,+BAAW,MAAM,KAAK,IAAI;AAC1C;AAGO,SAAS,YAAY,KAAc,QAAQ,KAAe;AAC/D,MAAI,CAAC,MAAM,QAAQ,GAAG,EAAG,QAAO,CAAC;AACjC,QAAM,MAAgB,CAAC;AACvB,aAAW,QAAQ,KAAK;AACtB,UAAM,UAAU,QAAQ,MAAM,KAAK;AACnC,QAAI,QAAS,KAAI,KAAK,OAAO;AAAA,EAC/B;AACA,SAAO;AACT;AAqBO,IAAM,yBAAN,MAAM,wBAAuB;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACQ;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,QAA2B,UAA0D,CAAC,GAAG;AACnG,SAAK,SAAS;AACd,SAAK,UAAU,OAAO;AACtB,SAAK,YAAY,OAAO;AACxB,SAAK,cAAc,OAAO;AAC1B,SAAK,WAAW,QAAQ;AACxB,SAAK,MAAM,QAAQ,OAAO,QAAQ;AAAA,EACpC;AAAA,EAEA,OAAO,kBAAkB,eAAuB,MAAuB;AACrE,eAAO,yBAAK,YAAQ,0BAAQ,GAAG,aAAa;AAAA,EAC9C;AAAA,EAEA,IAAI,aAAqB;AACvB,WAAO,KAAK,gBAAgB;AAAA,EAC9B;AAAA,EAEQ,kBAA0B;AAChC,QAAI,KAAK,aAAa,OAAW,QAAO,KAAK;AAC7C,UAAM,YAAY,KAAK,IAAI,KAAK,OAAO,WAAW,KAAK,IAAI,KAAK;AAChE,QAAI,SAAU,QAAO;AACrB,WAAO,wBAAuB,kBAAkB,KAAK,OAAO,aAAa;AAAA,EAC3E;AAAA,EAEQ,kBAA0B;AAChC,UAAM,MAAM,KAAK,gBAAgB;AACjC,QAAI,CAACC,QAAM,GAAG,GAAG;AACf,YAAM,IAAI;AAAA,QACR,GAAG,KAAK,OAAO,KAAK,kCAAkC,GAAG;AAAA,MAC3D;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,aAAa,UAA0B;AAC7C,UAAM,WAAO,yBAAK,UAAU,eAAe;AAC3C,QAAI,CAACC,SAAO,IAAI,EAAG,QAAO,CAAC;AAC3B,QAAI;AACJ,QAAI;AACF,gBAAU,KAAK,MAAM,aAAS,+BAAa,MAAM,OAAO,CAAC,CAAC;AAAA,IAC5D,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR,GAAG,KAAK,OAAO,KAAK,6CAA6C,IAAI,KACnE,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CACjD;AAAA,MACF;AAAA,IACF;AACA,QAAI,MAAM,QAAQ,OAAO,EAAG,QAAO,QAAQ,OAAO,MAAM;AACxD,QAAI,OAAO,OAAO,KAAK,MAAM,QAAQ,QAAQ,QAAQ,EAAG,QAAO,QAAQ,SAAS,OAAO,MAAM;AAC7F,UAAM,IAAI;AAAA,MACR,GAAG,KAAK,OAAO,KAAK,sBAAsB,IAAI;AAAA,IAChD;AAAA,EACF;AAAA,EAEQ,aAAa,UAA4B;AAC/C,UAAM,UAAM,yBAAK,UAAU,UAAU;AACrC,QAAI,CAACD,QAAM,GAAG,EAAG,QAAO,CAAC;AACzB,eAAO,8BAAY,GAAG,EACnB,OAAO,CAAC,MAAM,EAAE,SAAS,OAAO,CAAC,EACjC,KAAK,EACL,IAAI,CAAC,UAAM,yBAAK,KAAK,CAAC,CAAC;AAAA,EAC5B;AAAA;AAAA,EAGQ,aAAa,UAAkC;AACrD,UAAM,MAAsB,CAAC;AAC7B,eAAW,QAAQ,KAAK,aAAa,QAAQ,GAAG;AAC9C,UAAI;AACJ,UAAI;AACF,kBAAU,KAAK,MAAM,aAAS,+BAAa,MAAM,OAAO,CAAC,CAAC;AAAA,MAC5D,QAAQ;AACN;AAAA,MACF;AACA,UAAI,CAAC,OAAO,OAAO,EAAG;AACtB,YAAM,UAAU,KAAK,OAAO,gBAAgB,SAAS,IAAI;AACzD,UAAI,YAAY,KAAM,KAAI,KAAK,OAAO;AAAA,IACxC;AACA,QAAI,KAAK,CAAC,GAAG,MAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE,OAAO,KAAK,CAAE;AACnE,WAAO;AAAA,EACT;AAAA,EAEA,WAAuB;AACrB,UAAM,WAAW,KAAK,gBAAgB;AACtC,QAAI,CAACA,QAAM,QAAQ,GAAG;AACpB,YAAM,IAAI;AAAA,QACR,GAAG,KAAK,OAAO,KAAK,kCAAkC,QAAQ,wDACP,KAAK,OAAO,WAAW;AAAA,MAChF;AAAA,IACF;AACA,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,QACR,eAAeC,aAAO,yBAAK,UAAU,eAAe,CAAC;AAAA,QACrD,eAAe,KAAK,aAAa,QAAQ,EAAE;AAAA,QAC3C,cAAc,SAAS,KAAK,IAAI,KAAK,OAAO,WAAW,KAAK,IAAI,KAAK,CAAC;AAAA,MACxE;AAAA,IACF;AAAA,EACF;AAAA,EAEA,eAAe,OAAa,QAAQ,KAAqB;AACvD,UAAM,WAAW,KAAK,gBAAgB;AACtC,UAAM,WAAW,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE;AAEhD,WAAO,KAAK,aAAa,QAAQ,EAC9B,OAAO,CAAC,MAAM,EAAE,QAAQ,QAAQ,EAChC,MAAM,GAAG,KAAK;AAAA,EACnB;AAAA,EAEA,SAAS,OAAsC;AAC7C,UAAM,WAAW,KAAK,gBAAgB;AAEtC,QAAI,WAAW,KAAK,aAAa,QAAQ;AACzC,QAAI,UAAU,UAAa,UAAU,MAAM;AACzC,YAAM,WAAW,MAAM,YAAY,EAAE,MAAM,GAAG,EAAE;AAChD,iBAAW,SAAS,OAAO,CAAC,MAAM,EAAE,QAAQ,QAAQ;AAAA,IACtD;AAEA,UAAM,WAA0B,CAAC;AACjC,UAAM,OAAO,oBAAI,IAAY;AAC7B,eAAW,UAAU,KAAK,aAAa,QAAQ,GAAG;AAChD,YAAM,SAAS,KAAK,OAAO,gBAAgB,MAAM;AACjD,UAAI,WAAW,KAAM;AACrB,YAAM,MAAM,OAAO,KAAK,YAAY;AACpC,UAAI,KAAK,IAAI,GAAG,EAAG;AACnB,WAAK,IAAI,GAAG;AACZ,eAAS,KAAK,MAAM;AAAA,IACtB;AAKA,UAAM,sBAAkB,iCAAoB,UAAU,KAAK,OAAO,MAAM;AAExE,eAAO,0BAAa;AAAA,MAClB,cAAc;AAAA,MACd,WAAO,2BAAc;AAAA,QACnB,IAAI,KAAK,OAAO;AAAA,QAChB,MAAM,KAAK,OAAO;AAAA,QAClB,gBAAgB,KAAK,OAAO;AAAA,QAC5B,qBAAqB;AAAA,MACvB,CAAC;AAAA,MACD,eAAc,oBAAI,KAAK,GAAE,YAAY,EAAE,QAAQ,aAAa,QAAQ;AAAA,MACpE,cAAc,CAAC,GAAG,KAAK,OAAO,YAAY;AAAA,MAC1C,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,mBAAmB,KAAK,OAAO;AAAA,IACjC,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,cAA4B;AAC1B,QAAI;AACF,YAAM,WAAW,KAAK,gBAAgB;AACtC,UAAI,CAACD,QAAM,QAAQ,GAAG;AACpB,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,QAAQ,GAAG,KAAK,OAAO,KAAK,kCAAkC,QAAQ;AAAA,UACtE,SAAS,EAAE,UAAU,SAAS;AAAA,UAC9B,aAAa,SAAS,KAAK,OAAO,WAAW,gBAAgB,QAAQ;AAAA,QACvE;AAAA,MACF;AACA,YAAM,mBAAe,yBAAK,UAAU,eAAe;AACnD,YAAM,eAAe,KAAK,aAAa,QAAQ;AAC/C,UAAI,CAACC,SAAO,YAAY,KAAK,aAAa,WAAW,GAAG;AACtD,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,SAAS,EAAE,MAAM,SAAS;AAAA,UAC1B,aAAa,SAAS,KAAK,OAAO,WAAW;AAAA,QAC/C;AAAA,MACF;AAGA,WAAK,aAAa,QAAQ;AAC1B,WAAK,aAAa,QAAQ;AAC1B,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,MAAM;AAAA,UACN,eAAeA,SAAO,YAAY;AAAA,UAClC,eAAe,aAAa;AAAA,QAC9B;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QACvD,SAAS,CAAC;AAAA,QACV,aAAa,WAAW,KAAK,oBAAoB,CAAC;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,sBAA8B;AACpC,QAAI;AACF,aAAO,KAAK,gBAAgB;AAAA,IAC9B,QAAQ;AACN,aAAO,KAAK,KAAK,OAAO,aAAa;AAAA,IACvC;AAAA,EACF;AACF;AAIA,SAAS,OAAO,GAAuB;AACrC,SAAO,MAAM,QAAQ,OAAO,MAAM,YAAY,CAAC,MAAM,QAAQ,CAAC;AAChE;AAEA,SAASD,QAAM,GAAoB;AACjC,MAAI;AACF,eAAO,2BAAS,CAAC,EAAE,YAAY;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAASC,SAAO,GAAoB;AAClC,MAAI;AACF,eAAO,2BAAS,CAAC,EAAE,OAAO;AAAA,EAC5B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,SAAS,SAAS,MAAsB;AACtC,SAAO,KAAK,WAAW,CAAC,MAAM,QAAS,KAAK,MAAM,CAAC,IAAI;AACzD;;;AD1UO,IAAMC,aAAW;AACjB,IAAMC,eAAa;AACnB,IAAMC,mBACX;AAKK,IAAMC,uBAAwC,kCAAqB;AAAA,EACxE,SAAS,uBAAW;AAAA,EACpB,cAAc,CAAC,YAAY,cAAc,UAAU,uBAAuB,SAAS;AAAA,EACnF,WAAW,CAAC,QAAQ,WAAW,gBAAgB,YAAY;AAC7D,CAAC;AAED,IAAMC,qBAAoB;AAC1B,IAAMC,wBAAuB;AAC7B,IAAM,aAAa;AAUZ,SAAS,gBAAgB,QAAkC;AAChE,QAAM,UAAU,OAAO;AACvB,MAAI,OAAO,YAAY,YAAY,CAAC,QAAS,QAAO;AACpD,QAAM,OAAO,QAAQ,SAAS,UAAU;AACxC,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,UAAU,QAAQ,OAAO,eAAe,IAAID,kBAAiB,KAAK,oBAAoB,IAAI;AAEhG,QAAM,OAAO,YAAY,OAAO,MAAM,EAAE;AACxC,MAAI,CAAC,KAAK,SAAS,MAAM,EAAG,MAAK,QAAQ,MAAM;AAE/C,QAAM,UAAUE,SAAQ,OAAO,UAAU;AACzC,QAAM,WAAW,QAAQ,OAAO,YAAY,KAAK;AAEjD,aAAO,wBAAW;AAAA,IAChB;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd,YAAYA,SAAQ,OAAO,UAAU;AAAA,IACrC,UAAU,WAAW,UAAU;AAAA,IAC/B,YAAY,gBAAgB,OAAO,UAAU;AAAA,EAC/C,CAAC;AACH;AAGO,SAAS,gBAAgB,QAAc,cAAkD;AAC9F,QAAM,OAAOA,SAAQ,OAAO,IAAI,KAAK;AACrC,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,UAAU,OAAO,OAAO,WAAW,EAAE,EAAE,KAAK;AAClD,aAAO,yBAAY;AAAA,IACjB;AAAA,IACA,KAAK;AAAA;AAAA,IACL,eAAe,UAAU,KAAC,+BAAW,SAAS,GAAG,CAAC,IAAI,CAAC;AAAA,IACvD,aAAa,YAAY,OAAO,aAAaD,qBAAoB;AAAA,IACjE,eAAe,YAAY,OAAO,aAAa;AAAA,IAC/C,YAAY,gBAAgB,OAAO,UAAU;AAAA,EAC/C,CAAC;AACH;AAEO,IAAM,cAAiC;AAAA,EAC5C,SAASL;AAAA,EACT,WAAWC;AAAA,EACX,aAAa;AAAA,EACb,eAAe;AAAA,EACf,aAAa;AAAA,EACb,eAAeC;AAAA,EACf,cAAc,CAAC,kBAAkB,iBAAiB,uBAAuB;AAAA,EACzE,QAAQC;AAAA,EACR,OAAO;AAAA,EACP,aAAa;AAAA,EACb;AAAA,EACA;AACF;AAEO,IAAM,kBAAN,cAA8B,uBAAuB;AAAA,EAC1D,YAAY,UAA0D,CAAC,GAAG;AACxE,UAAM,aAAa,OAAO;AAAA,EAC5B;AAAA,EAEA,OAAO,kBAAkB,MAAuB;AAC9C,WAAO,uBAAuB,kBAAkB,SAAS,IAAI;AAAA,EAC/D;AACF;;;AE/FA,IAAAI,cAQO;AACP,IAAAC,qBAA2B;AAYpB,IAAMC,aAAW;AACjB,IAAMC,eAAa;AACnB,IAAMC,mBACX;AAIK,IAAMC,uBAAwC,kCAAqB;AAAA,EACxE,SAAS,uBAAW;AAAA,EACpB,cAAc,CAAC,YAAY,cAAc,UAAU,qBAAqB;AAAA,EACxE,WAAW,CAAC,WAAW,WAAW,QAAQ;AAC5C,CAAC;AAED,IAAMC,qBAAoB;AAC1B,IAAMC,wBAAuB;AAC7B,IAAMC,cAAa;AAGZ,SAASC,iBAAgB,QAAkC;AAChE,QAAM,OAAO,OAAO,OAAO,QAAQ,EAAE,EAAE,KAAK;AAC5C,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,UAAU,OAAO;AAEvB,QAAM,cACJ,YAAY,QAAQ,YAAY,UAAa,YAAY,KACrD,WACA,+BAAW,OAAO,OAAO,GAAGH,kBAAiB;AAGnD,QAAM,OAAO,YAAY,OAAO,IAAI;AACpC,OAAK,KAAK,SAAS;AAEnB,QAAM,WAAW,QAAQ,OAAO,QAAQ;AAExC,QAAM,UAAUI,SAAQ,OAAO,UAAU,KAAKA,SAAQ,OAAO,UAAU;AAEvE,aAAO,wBAAW;AAAA,IAChB,UAAM,+BAAW,MAAMF,WAAU;AAAA;AAAA,IACjC,MAAM;AAAA,IACN,SAAS;AAAA,IACT;AAAA,IACA,cAAc;AAAA,IACd,YAAYE,SAAQ,OAAO,UAAU;AAAA,IACrC,UAAU,WAAW,UAAU;AAAA,IAC/B,YAAY,gBAAgB,OAAO,UAAU;AAAA,EAC/C,CAAC;AACH;AAGO,SAASC,iBAAgB,QAAc,cAAkD;AAC9F,QAAM,OAAOD,SAAQ,OAAO,IAAI,KAAK;AACrC,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,UAAU,OAAO,OAAO,WAAW,EAAE,EAAE,KAAK;AAClD,aAAO,yBAAY;AAAA,IACjB;AAAA,IACA,KAAK;AAAA;AAAA,IACL,eAAe,UAAU,KAAC,+BAAW,SAAS,GAAG,CAAC,IAAI,CAAC;AAAA,IACvD,aAAa,YAAY,OAAO,aAAaH,qBAAoB;AAAA;AAAA;AAAA,IAGjE,eAAe,YAAY,OAAO,aAAa;AAAA,IAC/C,YAAY,gBAAgB,OAAO,UAAU;AAAA,EAC/C,CAAC;AACH;AAEO,IAAM,iBAAoC;AAAA,EAC/C,SAASL;AAAA,EACT,WAAWC;AAAA,EACX,aAAa;AAAA,EACb,eAAe;AAAA,EACf,aAAa;AAAA,EACb,eAAeC;AAAA,EACf,cAAc,CAAC,gBAAgB,yBAAyB,gBAAgB;AAAA,EACxE,QAAQC;AAAA,EACR,OAAO;AAAA,EACP,aAAa;AAAA,EACb,iBAAAI;AAAA,EACA,iBAAAE;AACF;AAEO,IAAM,qBAAN,cAAiC,uBAAuB;AAAA,EAC7D,YAAY,UAA0D,CAAC,GAAG;AACxE,UAAM,gBAAgB,OAAO;AAAA,EAC/B;AAAA,EAEA,OAAO,kBAAkB,MAAuB;AAC9C,WAAO,uBAAuB,kBAAkB,YAAY,IAAI;AAAA,EAClE;AACF;;;AC7HA,IAAAC,cAQO;AACP,IAAAC,qBAA2B;AAapB,IAAMC,aAAW;AACjB,IAAMC,eAAa;AACnB,IAAMC,mBACX;AAKK,IAAMC,uBAAwC,kCAAqB;AAAA,EACxE,SAAS,uBAAW;AAAA,EACpB,cAAc,CAAC,YAAY,cAAc,UAAU,uBAAuB,SAAS;AAAA,EACnF,WAAW,CAAC,MAAM,WAAW,UAAU,MAAM,WAAW;AAC1D,CAAC;AAED,IAAMC,qBAAoB;AAC1B,IAAMC,yBAAuB;AAC7B,IAAMC,cAAa;AAUZ,SAASC,iBAAgB,QAAkC;AAChE,QAAM,UAAU,OAAO;AACvB,MAAI,OAAO,YAAY,YAAY,CAAC,QAAS,QAAO;AACpD,QAAM,OAAO,QAAQ,SAASD,WAAU;AACxC,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,UAAU,QAAQ,OAAO,eAAe,IAAIF,kBAAiB,KAAK,cAAc,IAAI;AAE1F,QAAM,OAAO,YAAY,OAAO,MAAM,EAAE;AACxC,MAAI,CAAC,KAAK,SAAS,IAAI,EAAG,MAAK,QAAQ,IAAI;AAE3C,QAAM,UAAUI,SAAQ,OAAO,UAAU;AACzC,QAAM,WAAW,QAAQ,OAAO,YAAY,KAAK;AAEjD,aAAO,wBAAW;AAAA,IAChB;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd,YAAYA,SAAQ,OAAO,UAAU;AAAA,IACrC,UAAU,WAAW,UAAU;AAAA,IAC/B,YAAY,gBAAgB,OAAO,UAAU;AAAA,EAC/C,CAAC;AACH;AAGO,SAASC,iBAAgB,QAAc,cAAkD;AAC9F,QAAM,OAAOD,SAAQ,OAAO,IAAI,KAAK;AACrC,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,UAAU,OAAO,OAAO,WAAW,EAAE,EAAE,KAAK;AAClD,aAAO,yBAAY;AAAA,IACjB;AAAA,IACA,KAAK;AAAA;AAAA,IACL,eAAe,UAAU,KAAC,+BAAW,SAAS,GAAG,CAAC,IAAI,CAAC;AAAA,IACvD,aAAa,YAAY,OAAO,aAAaH,sBAAoB;AAAA,IACjE,eAAe,YAAY,OAAO,aAAa;AAAA,IAC/C,YAAY,gBAAgB,OAAO,UAAU;AAAA,EAC/C,CAAC;AACH;AAEO,IAAM,YAA+B;AAAA,EAC1C,SAASL;AAAA,EACT,WAAWC;AAAA,EACX,aAAa;AAAA,EACb,eAAe;AAAA,EACf,aAAa;AAAA,EACb,eAAeC;AAAA,EACf,cAAc,CAAC,iBAAiB,kBAAkB,cAAc;AAAA,EAChE,QAAQC;AAAA,EACR,OAAO;AAAA,EACP,aAAa;AAAA,EACb,iBAAAI;AAAA,EACA,iBAAAE;AACF;AAEO,IAAM,gBAAN,cAA4B,uBAAuB;AAAA,EACxD,YAAY,UAA0D,CAAC,GAAG;AACxE,UAAM,WAAW,OAAO;AAAA,EAC1B;AAAA,EAEA,OAAO,kBAAkB,MAAuB;AAC9C,WAAO,uBAAuB,kBAAkB,OAAO,IAAI;AAAA,EAC7D;AACF;;;AC7EO,IAAM,cAAiC;AAAA,EAC5C;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;AACF;AAGA,IAAMC,UAAS;AAAA,EACb,KAAK,KAAmB;AAEtB,YAAQ,KAAK,0BAA0B,GAAG,EAAE;AAAA,EAC9C;AACF;AAOO,SAAS,qBACd,QAA2B,aACL;AACtB,QAAM,QAAQ,oBAAI,IAAgC;AAClD,aAAW,QAAQ,CAAC,GAAG,OAAO,GAAG,0BAA0B,CAAC,GAAG;AAC7D,QAAI;AACJ,QAAI;AACF,iBAAW,IAAI,KAAK;AAAA,IACtB,SAAS,KAAK;AACZ,MAAAA,QAAO;AAAA,QACL,wBAAwB,KAAK,QAAQ,aAAa,0BAA0B,OAAO,GAAG,CAAC;AAAA,MACzF;AACA;AAAA,IACF;AACA,QAAI,CAAC,cAAc,QAAQ,EAAG;AAC9B,QAAI,CAAC,MAAM,IAAI,SAAS,OAAO,EAAG,OAAM,IAAI,SAAS,SAAS,QAAQ;AAAA,EACxE;AACA,SAAO,CAAC,GAAG,MAAM,OAAO,CAAC,EAAE;AAAA,IAAK,CAAC,GAAG,MAClC,EAAE,UAAU,EAAE,UAAU,KAAK,EAAE,UAAU,EAAE,UAAU,IAAI;AAAA,EAC3D;AACF;AAQO,SAAS,4BAA+C;AAC7D,MAAI,QAAQ,IAAI,oBAAoB,IAAK,QAAO,CAAC;AAGjD,SAAO,CAAC;AACV;;;AxBAA,IAAAC,cAUO;","names":["isoDate","import_node_fs","import_node_fs","import_node_os","import_node_path","stem","keyActions","capabilities","import_node_fs","import_node_os","import_node_path","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","isDir","isFile","yamlParse","sessionDate","capabilities","projectEntities","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","DEFAULT_POLICY","import_node_fs","import_node_os","import_node_path","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","homeDir","isDir","isFile","homeBase","import_node_fs","import_node_os","import_node_path","import_yaml","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","FRONTMATTER_OPEN","FRONTMATTER_CLOSE","DEFAULT_POLICY","homeDir","isDir","isFile","isRecord","parseFrontmatter","FRONTMATTER_OPEN","FRONTMATTER_CLOSE","yamlParse","buildSession","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","isDir","isFile","buildSession","DEFAULT_POLICY","ROLE_NARRATIVE","import_node_fs","import_node_os","import_node_path","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","DEFAULT_POLICY","MAX_SUMMARY_CHARS","isFile","isDir","bounded","keyActions","import_node_fs","import_node_os","import_node_path","import_yaml","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","CONVENTION_DIR_NAME","MEMORY_FILENAME","DEFAULT_POLICY","logger","homeDir","isDir","isFile","parseFrontmatter","yamlParse","logger","isRecord","buildEntity","buildSession","MEMORY_FILENAME","isFile","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","CONVENTION_DIR_NAME","DEFAULT_POLICY","MEMORY_FILENAME","isFile","parseFrontmatter","isDir","buildEntity","ROLE_NARRATIVE","import_node_child_process","import_node_os","import_node_path","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","isRecord","safeNativeMemoryText","nowIsoSeconds","curlGet","import_node_fs","import_node_os","import_node_path","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","MAX_KEY_ACTION_CHARS","logger","homeDir","isDir","isFile","stripChars","homeDir","parseToml","logger","basenameOf","isFile","isDir","bounded","safeNativeMemoryText","MAX_KEY_ACTION_CHARS","keyActions","AGENT_ID","AGENT_TYPE","DEFAULT_POLICY","isDir","ROLE_NARRATIVE","import_node_fs","import_node_os","import_node_path","import_smol_toml","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","AUTOMATIONS_DIR_NAME","AUTOMATION_TOML","MEMORY_MD","MAX_MEMORY_CHARS","MAX_KEY_ACTIONS_PER_RUN","MAX_KEY_ACTION_CHARS","RUN_HEADER_RE","DEFAULT_PROJECT_HINTS","SIGNAL_PATTERNS","logger","homeDir","isDir","isFile","safeNativeMemoryText","readAutomationToml","tomlParse","buildConfig","iterConfigs","readMemoryText","splitLines","rstrip","bounded","actionsFromLines","titleFromActions","inferProjects","inferSignals","extractMemoryRuns","stripChars","sessionFromRun","keyActions","entitiesFromConfigsAndRuns","import_node_fs","import_node_os","import_node_path","import_smol_toml","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","DEFAULT_POLICY","CONVENTION_DIR_NAME","AUTOMATION_TOML","MEMORY_MD","MAX_MEMORY_CHARS","MAX_KEY_ACTIONS_PER_RUN","MAX_KEY_ACTION_CHARS","RUN_HEADER_RE","logger","homeDir","isDir","isFile","isRecord","pyStr","CONVENTION_DIR_NAME","readAutomationToml","parseToml","buildConfig","MEMORY_MD","iterConfigs","AUTOMATION_TOML","splitLines","rstrip","stripChars","extractMemoryRuns","MAX_MEMORY_CHARS","RUN_HEADER_RE","actionsFromLines","titleFromActions","bounded","safeNativeMemoryText","MAX_KEY_ACTION_CHARS","MAX_KEY_ACTIONS_PER_RUN","sessionFromRun","keyActions","entitiesFromConfigsAndRuns","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","DEFAULT_POLICY","ROLE_NARRATIVE","import_node_fs","import_node_os","import_node_path","import_smol_toml","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","AUTOMATIONS_DIR_NAME","AUTOMATION_TOML","MEMORY_MD","MAX_MEMORY_CHARS","MAX_KEY_ACTIONS_PER_RUN","MAX_KEY_ACTION_CHARS","RUN_HEADER_RE","HEADER_SUFFIX_STRIP","DEFAULT_PROJECT_HINTS","SIGNAL_PATTERNS","logger","homeDir","isDir","isFile","strOr","stripChars","rstrip","bounded","safeNativeMemoryText","AUTOMATIONS_DIR_NAME","readAutomationToml","parseToml","buildConfig","basenameOf","MEMORY_MD","iterConfigs","AUTOMATION_TOML","readMemoryText","MAX_MEMORY_CHARS","extractMemoryRuns","RUN_HEADER_RE","HEADER_SUFFIX_STRIP","actionsFromLines","titleFromActions","inferProjects","inferSignals","MAX_KEY_ACTION_CHARS","MAX_KEY_ACTIONS_PER_RUN","DEFAULT_PROJECT_HINTS","SIGNAL_PATTERNS","sessionFromRun","keyActions","MAX_KEY_ACTIONS_PER_RUN","entitiesFromConfigsAndRuns","bounded","nowIsoSeconds","AGENT_ID","AGENT_TYPE","DEFAULT_POLICY","isDir","iterConfigs","ROLE_NARRATIVE","extractMemoryRuns","import_node_fs","import_node_os","import_node_path","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","MAX_KEY_ACTION_CHARS","MAX_KEY_ACTIONS","DEFAULT_PROJECT_HINTS","DEFAULT_POLICY","isDir","bounded","inferProjects","stem","parsePath","import_node_fs","import_node_os","import_node_path","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","SURFACE_ENTITY_NAME","ROLE_NARRATIVE","DEFAULT_POLICY","DESKTOP_DIR_ENV","STATE_PREFIX","MAX_PROJECTS","MAX_KEY_ACTIONS","DEFAULT_PROJECT_HINTS","logger","isDir","isFile","homeDir","isRecord","defaultClaudeDesktopDir","iterStateFiles","loadStateJson","epochToDate","sessionDate","bounded","safeLabel","countEnabledMcpTools","basenameOf","inferProjects","parsePath","stem","keyActions","sessionFromRun","capabilities","import_node_fs","import_node_os","import_node_path","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","DEFAULT_POLICY","MAX_KEY_ACTIONS","MAX_KEY_ACTION_CHARS","MAX_SUMMARY_CHARS","homeDir","isDir","safeNativeMemoryText","bounded","splitLines","logger","keyActions","import_node_fs","import_node_os","import_node_path","isDir","import_l5","import_redaction","import_node_fs","import_node_os","import_node_path","import_l5","import_redaction","isoDate","parsed","isDir","isFile","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","MAX_SUMMARY_CHARS","MAX_KEY_ACTION_CHARS","isoDate","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","MAX_SUMMARY_CHARS","MAX_KEY_ACTION_CHARS","NAME_LIMIT","projectToEntity","isoDate","sessionToRecord","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","MAX_SUMMARY_CHARS","MAX_KEY_ACTION_CHARS","NAME_LIMIT","projectToEntity","isoDate","sessionToRecord","logger","import_l5"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/base.ts","../src/sqlite-base.ts","../src/network-base.ts","../src/readers/hermes.ts","../src/readers/claude-code.ts","../src/skills.ts","../src/skill-index.ts","../src/skill-shares.ts","../src/readers/github-copilot.ts","../src/readers/cursor.ts","../src/readers/copilot.ts","../src/readers/copilot-cli.ts","../src/readers/cascade.ts","../src/readers/openclaw.ts","../src/readers/claude-code-automations.ts","../src/readers/codex-automations.ts","../src/readers/copilot-automations.ts","../src/readers/cursor-automations.ts","../src/readers/claude-desktop-code.ts","../src/readers/claude-desktop-cowork.ts","../src/readers/copilot-vscode.ts","../src/readers/codex-sessions.ts","../src/skill-store.ts","../src/skill-proposals.ts","../src/readers/bolt.ts","../src/export-store-base.ts","../src/readers/lovable.ts","../src/readers/v0.ts","../src/registry.ts"],"sourcesContent":["// SPDX-License-Identifier: BUSL-1.1\n/**\n * @getbourdon/participants — the external-agent → L5 reader layer (BUSL-1.1).\n *\n * Each participant normalizes a foreign agent's native memory store into a\n * visibility-filtered, redacted L5 manifest. Reader categories:\n * - SQLite (read-only, better-sqlite3 mode=ro): {@link HermesParticipant},\n * {@link CursorParticipant}, {@link CopilotCliParticipant}\n * - file / convention: {@link ClaudeCodeParticipant},\n * {@link CopilotParticipant}, {@link CascadeParticipant}\n * - network (TTL cache + lazy AuthProvider): {@link GitHubCopilotParticipant}\n * - network + quarantined-class (handshake gate): {@link OpenClawParticipant}\n *\n * Four invariants enforced in code, not by trust: visibility-filter-before-\n * emission, deterministic exportL5, healthCheck never throws, redact every\n * native string. Discovery is a static registry ({@link discoverParticipants}).\n *\n * Python (`pip install bourdon`) is the oracle; this mirror asserts against the\n * @getbourdon/conformance `native_stores` fixtures (output shape only).\n * Still deferred: codex (the ~2.6k-line turn-compiler reader) lands in a\n * follow-on slice.\n */\n\n// Contract surface: Protocol interface, errors, AgentStore + HealthStatus.\nexport {\n CONTRACT_VERSION,\n SPEC_VERSION,\n ParticipantError,\n ParticipantDiscoveryError,\n ParticipantExportError,\n ParticipantVersionMismatchError,\n isParticipant,\n loadProjectHints,\n PROJECT_HINTS_ENV,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"./base.js\";\n\n// SQLite read-only primitives.\nexport {\n sqliteAvailable,\n openReadonly,\n tryOpenReadonly,\n tableExists,\n tableColumns,\n epochToIsoDate,\n epochToIsoDatetime,\n projectKeyFromCwd,\n friendlyLabel,\n type OpenReadonlyOptions,\n type SqliteDatabase,\n} from \"./sqlite-base.js\";\n\n// Network base: TTL cache, AuthProvider, degrade-to-stale-cache, auth boundary.\nexport {\n NETWORK_CONTRACT_VERSION,\n DEFAULT_CACHE_TTL_SECONDS,\n NetworkUnavailable,\n ParticipantAuthError,\n NetworkParticipant,\n PayloadCache,\n CacheEntry,\n envAuthProvider,\n defaultCacheRoot,\n type AuthProvider,\n type NetworkParticipantOptions,\n} from \"./network-base.js\";\n\n// Readers.\nexport { HermesParticipant } from \"./readers/hermes.js\";\nexport { ClaudeCodeParticipant } from \"./readers/claude-code.js\";\nexport { GitHubCopilotParticipant, ghTokenProvider } from \"./readers/github-copilot.js\";\nexport { CursorParticipant } from \"./readers/cursor.js\";\nexport { CopilotParticipant } from \"./readers/copilot.js\";\nexport { CopilotCliParticipant } from \"./readers/copilot-cli.js\";\nexport { CascadeParticipant } from \"./readers/cascade.js\";\nexport {\n OpenClawParticipant,\n OpenClawApiClient,\n verifyInstance,\n MIN_PATCHED_VERSION,\n} from \"./readers/openclaw.js\";\n// Background-run \"automations\" variants (publish automation-run memory as L5 evidence).\nexport { ClaudeCodeAutomationsParticipant } from \"./readers/claude-code-automations.js\";\nexport { CodexAutomationsParticipant } from \"./readers/codex-automations.js\";\nexport { CopilotAutomationsParticipant } from \"./readers/copilot-automations.js\";\nexport { CursorAutomationsParticipant } from \"./readers/cursor-automations.js\";\n// Claude desktop surfaces + VS Code Copilot.\nexport { ClaudeDesktopCodeParticipant } from \"./readers/claude-desktop-code.js\";\nexport { ClaudeDesktopCoworkParticipant } from \"./readers/claude-desktop-cowork.js\";\nexport { CopilotVscodeParticipant } from \"./readers/copilot-vscode.js\";\n// Codex session-index title lookup (NOT the full codex reader — only the\n// tray/presence `session_id -> thread_name` surface).\nexport {\n DEFAULT_RECENT_THREAD_LIMIT,\n DEFAULT_TITLE_LIMIT,\n parseSessionIndex,\n recentSessionThreads,\n resolveCodexHome,\n sessionThreadTitles,\n} from \"./readers/codex-sessions.js\";\nexport type { RecentThread } from \"./readers/codex-sessions.js\";\n\n// Skill readers (plan 005: advertise local skills as L5 SkillRefs, discovery only).\nexport {\n CROSS_AGENT_LOCK_NAME,\n LIST_ALL,\n LIST_APPROVED,\n LIST_OFF,\n MAX_LOCK_BYTES,\n MAX_PATH_HINT_CHARS,\n MAX_SKILL_REFS,\n MAX_SKIPPED_FILES,\n ORIGIN_AUTHORED,\n ORIGIN_INSTALLED,\n SCOPE_PROJECT,\n SCOPE_USER,\n SKILL_PROJECTS_ENV,\n SKILL_READERS,\n SKILL_REF_VISIBILITY,\n SKILLS_ADVERTISE_ENV,\n SKILLS_NO_ADVERTISE_ENV,\n STORE_AGENT,\n STORE_CROSS_AGENT,\n VIA_COPY,\n VIA_LINK,\n advertisedSkills,\n claudeCodeSkillSources,\n codexSkillSources,\n crossAgentSkillSources,\n cursorSkillSources,\n localSkills,\n originFromLockEntry,\n readInstallLock,\n resolveAdvertisedFolder,\n scanSkillSources,\n skillSourcesForAgent,\n skillProjects,\n skillsAdvertisingEnabled,\n skillsListingMode,\n userHome,\n type LocalSkill,\n type ScanSkillSourcesOptions,\n type SkillAdvertiser,\n type SkillFolderFilter,\n type SkillScanReport,\n type SkillSource,\n type SkillSourceOptions,\n type SkillsListingMode,\n type SkippedSkill,\n} from \"./skills.js\";\n// Per-skill share approvals: which local skills a participant may list.\nexport {\n KIND_SKILL,\n MAX_SHARES_BYTES,\n SHARE_ACTOR,\n SHARES_FILENAME,\n SHARES_VERSION,\n SkillShareError,\n addShare,\n defaultSharesLibrary,\n loadShares,\n removeShares,\n shareAppliesTo,\n shareFolderKey,\n shareKey,\n shareSourceKey,\n shareToDict,\n sharesPath,\n type AddShareOptions,\n type SkillShare,\n} from \"./skill-shares.js\";\nexport {\n MAX_REFERENCE_FILE_BYTES,\n MAX_REFERENCE_FILES,\n MAX_SKILL_BODY_BYTES,\n MAX_SKILL_TOTAL_BYTES,\n SKILL_BODY_NAME,\n SKIP_REASONS,\n SkillContentError,\n TEXT_FILE_SUFFIXES,\n codePointSlice,\n computeContentSha256,\n parseFrontMatter,\n pyStrip,\n readSkillFolder,\n scanLocalSkill,\n type LocalSkillScan,\n type SkillContent,\n type SkillFrontMatter,\n type SkippedFile,\n} from \"./skill-index.js\";\n\n// The shared skill store (plan 005: <library>/skills, written only by promotion).\nexport {\n DEFAULT_SKILL_VISIBILITY,\n FILES_DIRNAME,\n INDEX_ROW_NAME,\n InvalidSkillRowError,\n MAX_INDEX_ROW_BYTES,\n SKILL_INDEX_SPEC_VERSION,\n SKILL_STORE_WRITE_POLICY,\n SKILLS_DIRNAME,\n SkillIndexError,\n SkillIndexRow,\n SkillNameCollisionError,\n SkillNotFoundError,\n SkillVersionConflictError,\n VERSIONS_DIRNAME,\n getSkillRow,\n listSkillRows,\n listSkillVersions,\n loadIndexRow,\n promoteSkill,\n readSharedSkill,\n setSkillValidTo,\n skillDir,\n skillsRoot,\n suggestAvailableName,\n validateIndexRow,\n validateSkillName,\n verifySharedSkill,\n writeIndexRow,\n type PromoteSkillOptions,\n type PromotionResult,\n} from \"./skill-store.js\";\n\n// Skill proposals (plan 005, phase 4: the human approval gate before promotion).\nexport {\n BALLOT_OPTIONS,\n CONTENT_DIRNAME,\n PROPOSALS_DIRNAME,\n PROPOSER_QUARANTINED,\n PROPOSER_TRUSTED,\n ProposalDigestMismatchError,\n ProposalNotFoundError as SkillProposalNotFoundError,\n ProposalStateError,\n RECORD_NAME,\n SKILL_PROPOSAL_LIMITS,\n STATUS_APPROVED,\n STATUS_PENDING,\n STATUS_REJECTED,\n SkillProposalError,\n advisoryTally,\n approveProposal,\n collisionFor,\n createProposal,\n isProposalId,\n listProposals,\n loadProposal,\n openAdvisoryBallot,\n proposalFromDict,\n proposalSummary,\n proposalToDict,\n proposalsRoot,\n readProposalContent,\n rejectProposal,\n retireSharedSkill,\n rollbackSharedSkill,\n type AdvisoryTally,\n type ApprovalResult,\n type ApproveProposalOptions,\n type CreateProposalOptions,\n type RejectProposalOptions,\n type RollbackResult,\n type SkillProposal,\n} from \"./skill-proposals.js\";\n\n// Discovery (static registry).\nexport {\n FIRST_PARTY,\n discoverParticipants,\n resolvePluginParticipants,\n type ParticipantCtor,\n} from \"./registry.js\";\n\n// Re-exported from @getbourdon/l5 for convenience (the L5 model + serialization\n// the readers build on; only this output shape is the parity contract).\nexport {\n Visibility,\n applyVisibility,\n filterForFederation,\n toDict,\n validateManifest,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type SkillRefModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\n\n// The JSON export-store family — cloud builders that persist nothing locally\n// and federate through an exported directory. The shared mechanics live in\n// export-store-base.ts; each reader keeps its OWN entity/session mapper,\n// because the oracle's three differ in ways that are not cosmetic.\nexport {\n ExportStoreParticipant,\n isoDate,\n parseVisibility,\n safeStr,\n safeStrList,\n type ExportStoreConfig,\n} from \"./export-store-base.js\";\nexport { BOLT_CONFIG, BoltParticipant } from \"./readers/bolt.js\";\nexport { LOVABLE_CONFIG, LovableParticipant } from \"./readers/lovable.js\";\nexport { V0_CONFIG, V0Participant } from \"./readers/v0.js\";\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Bourdon participant base — the Protocol → TS interface, errors, and the\n * AgentStore / HealthStatus types. Faithful port of `participants/base.py`.\n *\n * The L5 dataclass model (AgentInfo/Entity/Session/VisibilityPolicy/L5Manifest),\n * the `toDict` omission rules, and the visibility helpers all live in\n * `@getbourdon/l5` and are reused verbatim — only THAT output shape is the parity\n * contract. This module owns the participant CONTRACT surface around them.\n *\n * Contract semantics (enforced by every reader, asserted by the conformance\n * fixtures, never by trust):\n * 1. visibility filter BEFORE emission (`filterForFederation`) — private wins.\n * 2. deterministic / idempotent `exportL5` — same store → identical `toDict`.\n * 3. `healthCheck` NEVER throws — catch-all → degraded/blocked.\n * 4. every native string through `@getbourdon/redaction` before it enters L5.\n */\n\nimport type { L5ManifestModel, SessionModel } from \"@getbourdon/l5\";\n\n/** Tied to Bourdon spec v0.1 — same literals as the Python oracle. */\nexport const CONTRACT_VERSION = \"0.1\";\nexport const SPEC_VERSION = \"0.1\";\n\n// -- Errors -------------------------------------------------------------------\n\n/** Base class for participant errors. */\nexport class ParticipantError extends Error {\n constructor(message?: string) {\n super(message);\n this.name = new.target.name;\n }\n}\n\n/** Raised by `discover()` when the native store cannot be found or read.\n * Non-fatal: L6 skips this agent rather than aborting the whole export. */\nexport class ParticipantDiscoveryError extends ParticipantError {}\n\n/** Raised by `exportL5()` / `exportSessions()` when an export fails mid-op\n * (the store WAS present — distinct from a discovery miss). */\nexport class ParticipantExportError extends ParticipantError {}\n\n/** Raised when the native store's version is outside the supported range.\n * Subtype of discovery error (a version mismatch is a discovery-time miss). */\nexport class ParticipantVersionMismatchError extends ParticipantDiscoveryError {}\n\n// -- Data types ---------------------------------------------------------------\n\n/** Metadata describing the native agent store. Returned by `discover()`. */\nexport interface AgentStore {\n path: string;\n version: string;\n metadata: Record<string, unknown>;\n}\n\n/** Returned by `healthCheck()`. Consumed by the `bourdon doctor` CLI. */\nexport interface HealthStatus {\n status: \"ok\" | \"degraded\" | \"blocked\";\n reason?: string;\n details: Record<string, unknown>;\n /** A human-runnable command to remedy a non-ok status. */\n proposedFix?: string;\n}\n\n// -- Protocol -----------------------------------------------------------------\n\n/**\n * Structural interface every participant must satisfy (the Python\n * `@runtime_checkable Protocol`). Duck-typed at registration: a class is a\n * participant iff it has `agentId` + `agentType` + `exportL5` + `healthCheck`.\n *\n * Optional members (`displayName`, a `defaultNativePath` static) are documented\n * here as in the Python Protocol; discovery + the setup wizard fall back to\n * sensible defaults when absent.\n */\nexport interface BourdonParticipant {\n agentId: string;\n agentType: string;\n nativePath: string;\n\n /** Human-friendly label (e.g. \"GitHub Copilot\"). Optional. */\n displayName?: string;\n\n /** Quarantined-class marker (Python `QUARANTINED_CLASS`). When true, the CLI\n * requires `--i-understand-the-risk` to register the agent trusted, and its\n * exports are staged for operator review rather than written to the live\n * store (spec D6: quarantine follows the content, not the invoker). Absent =\n * a normal, non-quarantined participant. Read by `bourdon agent add/set-tier`\n * (cli/src/commands/federation.ts). */\n quarantinedClass?: boolean;\n\n /** Confirm the native store exists; return metadata. Throws\n * {@link ParticipantDiscoveryError} when missing/unreadable. */\n discover(): AgentStore;\n\n /** Build the L5 manifest from native memory, applying the visibility filter\n * BEFORE return. Deterministic — same store yields the same manifest. */\n exportL5(since?: Date): L5ManifestModel;\n\n /** Export recent sessions in normalized schema. */\n exportSessions(since?: Date, limit?: number): SessionModel[];\n\n /** Return ok / degraded / blocked with a reason. MUST NOT throw. */\n healthCheck(): HealthStatus;\n}\n\n/**\n * Tiny structural guard mirroring Python's `_PARTICIPANT_MARKER_ATTRS`\n * duck-type: a value is a participant iff it carries the four marker members.\n */\nexport function isParticipant(obj: unknown): obj is BourdonParticipant {\n if (obj === null || typeof obj !== \"object\") return false;\n const o = obj as Record<string, unknown>;\n return (\n typeof o[\"agentId\"] === \"string\" &&\n typeof o[\"agentType\"] === \"string\" &&\n typeof o[\"exportL5\"] === \"function\" &&\n typeof o[\"healthCheck\"] === \"function\"\n );\n}\n\n/**\n * Environment variable holding the deployment's own project-name recognition\n * vocabulary, as a comma-separated list (e.g.\n * `BOURDON_PROJECT_HINTS=\"Acme Portal,Widget API,internal-tools\"`).\n */\nexport const PROJECT_HINTS_ENV = \"BOURDON_PROJECT_HINTS\";\n\n/**\n * Project-name hints used to tag sessions with a project focus.\n *\n * Bourdon ships **no** project roster of its own — the `defaults` a reader\n * passes are limited to product-neutral names (this product, plus the agent\n * surfaces it federates). A deployment that wants its own projects recognized\n * sets {@link PROJECT_HINTS_ENV}; those entries are appended to `defaults`.\n *\n * Matching downstream is case-insensitive substring matching, so entries are\n * de-duplicated case-insensitively here while preserving first-seen order and\n * the original casing (which is what gets emitted as the project name).\n *\n * Mirrors Python `participants.base.load_project_hints`.\n */\nexport function loadProjectHints(\n defaults: readonly string[] = [],\n): readonly string[] {\n const hints: string[] = [];\n const seen = new Set<string>();\n const raw = process.env[PROJECT_HINTS_ENV] ?? \"\";\n for (const candidate of [...defaults, ...raw.split(\",\")]) {\n const name = candidate.trim();\n if (!name) continue;\n const key = name.toLowerCase();\n if (seen.has(key)) continue;\n seen.add(key);\n hints.push(name);\n }\n return hints;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Shared read-only SQLite + normalization helpers — port of\n * `participants/_sqlite_base.py`.\n *\n * A SQLite-backed participant (hermes today; cursor/copilot_cli in the follow-on\n * slice) reads a foreign agent's native DB read-only so a live writer's lock can\n * never block the export, probes the schema defensively (native schemas drift\n * across versions), and turns epoch timestamps + paths into the L5 shapes.\n *\n * `better-sqlite3` is a NATIVE addon. It is loaded lazily through `createRequire`\n * inside a try/catch so this package — and the file/network readers — keep\n * working even on a toolchain where the addon failed to build: in that case\n * {@link sqliteAvailable} returns false and the sqlite readers degrade rather\n * than crashing import. Nothing here applies visibility or builds manifests;\n * that stays in the participant (per PARTICIPANT_CONTRACT.md).\n */\n\nimport { statSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\n\nimport type DatabaseT from \"better-sqlite3\";\n\n/** A better-sqlite3 connection (re-exported type alias for reader signatures). */\nexport type SqliteDatabase = DatabaseT.Database;\n\n// `import.meta.url` in ESM; esbuild empties it in the CJS bundle, where the\n// native `__filename` global is the real path — fall back to it so createRequire\n// resolves better-sqlite3 from either module format.\ndeclare const __filename: string | undefined;\nconst moduleUrl =\n (typeof import.meta !== \"undefined\" && import.meta.url) ||\n (typeof __filename !== \"undefined\" ? __filename : process.cwd());\nconst nodeRequire = createRequire(moduleUrl);\n\nlet driver: typeof DatabaseT | null | undefined;\nlet nativeAvailable: boolean | undefined;\n\n/** Lazily resolve the better-sqlite3 constructor, or null if the addon is\n * unavailable (failed native build). Cached after the first attempt. */\nfunction loadDriver(): typeof DatabaseT | null {\n if (driver !== undefined) return driver;\n try {\n driver = nodeRequire(\"better-sqlite3\") as typeof DatabaseT;\n } catch {\n driver = null;\n }\n return driver;\n}\n\n/** True when the native addon can open and close a disposable in-memory DB. */\nexport function sqliteAvailable(): boolean {\n if (nativeAvailable !== undefined) return nativeAvailable;\n const Ctor = loadDriver();\n if (!Ctor) return (nativeAvailable = false);\n try {\n const probe = new Ctor(\":memory:\");\n probe.close();\n nativeAvailable = true;\n } catch {\n nativeAvailable = false;\n }\n return nativeAvailable;\n}\n\nexport interface OpenReadonlyOptions {\n /** `immutable=1`: skip locks + ignore the WAL. Only for genuinely static\n * snapshots; against a live writer it risks stale reads / SQLITE_CORRUPT. */\n immutable?: boolean;\n /** SQLite busy-timeout in milliseconds (Python's `timeout=2.0` seconds). */\n timeoutMs?: number;\n}\n\n// -- Read-only connection -----------------------------------------------------\n\n/**\n * Open a SQLite DB read-only so a live writer is never disturbed. The default\n * (`immutable` omitted) is the safe `mode=ro`: it respects SQLite locking and\n * reads the `-wal` sidecar of a live, actively-writing agent. Raises on a\n * genuine open failure; callers wanting the never-raises contract use\n * {@link tryOpenReadonly}.\n */\nexport function openReadonly(dbPath: string, opts: OpenReadonlyOptions = {}): SqliteDatabase {\n const Ctor = loadDriver();\n if (!Ctor) {\n throw new Error(\"better-sqlite3 native addon is not available\");\n }\n // better-sqlite3 maps `{readonly:true}` to SQLITE_OPEN_READONLY. There is no\n // first-class `immutable=1` knob; for our static snapshots `readonly` is\n // sufficient (we never open a concurrently-written fixture DB).\n return new Ctor(dbPath, {\n readonly: true,\n fileMustExist: true,\n timeout: opts.timeoutMs ?? 2000,\n });\n}\n\n/**\n * Like {@link openReadonly} but returns null instead of raising — for the\n * export/health path where a missing or corrupt DB must degrade to \"no rows\".\n */\nexport function tryOpenReadonly(\n dbPath: string,\n opts: OpenReadonlyOptions = {},\n): SqliteDatabase | null {\n try {\n if (!statSync(dbPath).isFile()) return null;\n } catch {\n return null;\n }\n try {\n return openReadonly(dbPath, opts);\n } catch {\n return null;\n }\n}\n\n// -- Defensive schema probes --------------------------------------------------\n\n/** True if `name` is a table in the connected DB (swallows errors → false). */\nexport function tableExists(db: SqliteDatabase, name: string): boolean {\n try {\n const row = db\n .prepare(\"SELECT 1 FROM sqlite_master WHERE type='table' AND name=? LIMIT 1\")\n .get(name);\n return row !== undefined;\n } catch {\n return false;\n }\n}\n\n/** Column names for `table` (empty set if absent / on error). PRAGMA cannot be\n * parameterized, matching the Python f-string. */\nexport function tableColumns(db: SqliteDatabase, table: string): Set<string> {\n try {\n const rows = db.prepare(`PRAGMA table_info(${table})`).all() as Array<{ name: string }>;\n return new Set(rows.map((r) => r.name));\n } catch {\n return new Set<string>();\n }\n}\n\n// -- Normalization ------------------------------------------------------------\n\nfunction toFiniteNumber(value: unknown): number | null {\n if (value === null || value === undefined) return null;\n const n = typeof value === \"number\" ? value : Number(value);\n return Number.isFinite(n) ? n : null;\n}\n\n/**\n * Convert epoch seconds (number/string) to an ISO `YYYY-MM-DD` UTC date, or\n * null for missing/unparseable values. Mirrors `epoch_to_iso_date`.\n */\nexport function epochToIsoDate(value: unknown): string | null {\n const n = toFiniteNumber(value);\n if (n === null) return null;\n const d = new Date(n * 1000);\n if (Number.isNaN(d.getTime())) return null;\n return d.toISOString().slice(0, 10);\n}\n\n/**\n * Convert epoch seconds to a full ISO 8601 UTC datetime, or null. The offset is\n * rendered `+00:00` (Python `datetime(...).isoformat()` style) rather than `Z`.\n */\nexport function epochToIsoDatetime(value: unknown): string | null {\n const n = toFiniteNumber(value);\n if (n === null) return null;\n const d = new Date(n * 1000);\n if (Number.isNaN(d.getTime())) return null;\n return d\n .toISOString()\n .replace(/\\.\\d{3}Z$/, \"+00:00\")\n .replace(/Z$/, \"+00:00\");\n}\n\nfunction basenameOf(p: string): string {\n const trimmed = p.replace(/[\\\\/]+$/, \"\");\n const parts = trimmed.split(/[\\\\/]/);\n return parts[parts.length - 1] ?? \"\";\n}\n\n/**\n * Derive a lowercase project key from a working-directory path: the basename\n * lowercased, or null when the cwd is empty or its basename is \"generic\"\n * (carries no project identity). Mirrors `project_key_from_cwd`.\n */\nexport function projectKeyFromCwd(\n cwd: string | null | undefined,\n genericNames: ReadonlySet<string> = new Set(),\n): string | null {\n if (!cwd) return null;\n const name = basenameOf(cwd).trim().toLowerCase();\n if (!name || genericNames.has(name)) return null;\n return name;\n}\n\n/** Turn a slug-ish key (`my-cool_project`) into a Title Case label. */\nexport function friendlyLabel(key: string): string {\n return key\n .replace(/[-_]+/g, \" \")\n .trim()\n .replace(/\\S+/g, (w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase());\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Network-shaped participant base — port of `participants/_network_base.py`\n * (v0.3 adapter contract). Same `exportL5` / `exportSessions` half as a file\n * participant; only the discovery half differs (fetch from an authenticated\n * API). The base provides the three guarantees so adapters don't reimplement:\n *\n * 1. Local TTL cache under `~/.cache/bourdon/<slug>/payload.json` storing ONLY\n * `{fetched_at, payload}` — NEVER the token. A cache hit = zero network.\n * 2. Graceful degradation: network down → serve the most recent cached payload\n * (even expired) and report `degraded` (not silence).\n * 3. Auth boundary: an injected lazy {@link AuthProvider} (env / keychain).\n * An invalid token (401/403 non-ratelimit) ALWAYS propagates as `blocked`\n * and is NEVER masked by stale cache; a missing token serves stale when a\n * cache exists, else blocks; rate-limit degrades.\n *\n * A subclass sets `participantSlug` / `agentId` / `agentType` (+ `nativePath`)\n * and implements `fetchPayload(token)` + `payloadToL5(payload)` (pure, no I/O).\n */\n\nimport { mkdirSync, readFileSync, renameSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport type { L5ManifestModel, SessionModel } from \"@getbourdon/l5\";\n\nimport {\n ParticipantError,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"./base.js\";\n\nexport const NETWORK_CONTRACT_VERSION = \"0.3\";\n/** Default cache TTL — adapters override via `cacheTtlSeconds`. */\nexport const DEFAULT_CACHE_TTL_SECONDS = 15 * 60; // 15 minutes\n\n// -- Network-specific errors --------------------------------------------------\n\n/** Transport failure / timeout / 5xx / rate-limit — recoverable via cache fallback. */\nexport class NetworkUnavailable extends ParticipantError {}\n\n/** 401/403 / missing credential — NOT recoverable via cache. The user must fix\n * auth; surfaced as `blocked`, never silently served from stale cache (stale\n * data would mask a broken token indefinitely). */\nexport class ParticipantAuthError extends ParticipantError {}\n\n// -- Auth provider ------------------------------------------------------------\n\n/** A zero-arg callable returning the token string, or null if no credential is\n * available. Kept a callable (not a bare string) so the token is fetched lazily\n * at call time and never sits in the participant's fields or the cache. */\nexport type AuthProvider = () => string | null;\n\n/** Auth provider that reads a token from an environment variable. */\nexport function envAuthProvider(varName: string): AuthProvider {\n return () => process.env[varName] || null;\n}\n\n// -- Cache --------------------------------------------------------------------\n\n/** `$XDG_CACHE_HOME/bourdon` or `~/.cache/bourdon`. */\nexport function defaultCacheRoot(): string {\n const xdg = process.env.XDG_CACHE_HOME;\n const base = xdg ? xdg : join(homedir(), \".cache\");\n return join(base, \"bourdon\");\n}\n\n/** A cached payload + the wall-clock time it was fetched (epoch seconds). */\nexport class CacheEntry {\n constructor(\n readonly fetchedAt: number,\n readonly payload: Record<string, unknown>,\n ) {}\n\n get ageSeconds(): number {\n return Math.max(0, Date.now() / 1000 - this.fetchedAt);\n }\n\n isFresh(ttlSeconds: number): boolean {\n return this.ageSeconds < ttlSeconds;\n }\n}\n\n/**\n * A tiny JSON file cache, one file per participant slug. Stores only\n * `{fetched_at, payload}` — never the auth token. Read/write are best-effort: a\n * corrupt or unwritable cache degrades to \"no cache\", never raises.\n */\nexport class PayloadCache {\n readonly slug: string;\n readonly root: string;\n readonly path: string;\n\n constructor(slug: string, rootDir?: string) {\n this.slug = slug;\n this.root = join(rootDir ?? defaultCacheRoot(), slug);\n this.path = join(this.root, \"payload.json\");\n }\n\n read(): CacheEntry | null {\n let raw: unknown;\n try {\n raw = JSON.parse(readFileSync(this.path, \"utf8\"));\n } catch {\n return null;\n }\n if (typeof raw !== \"object\" || raw === null || !(\"payload\" in raw)) return null;\n const obj = raw as Record<string, unknown>;\n let fetchedAt = Number(obj[\"fetched_at\"] ?? 0);\n if (!Number.isFinite(fetchedAt)) fetchedAt = 0;\n const payload = obj[\"payload\"];\n if (typeof payload !== \"object\" || payload === null || Array.isArray(payload)) return null;\n return new CacheEntry(fetchedAt, payload as Record<string, unknown>);\n }\n\n write(payload: Record<string, unknown>): void {\n try {\n mkdirSync(this.root, { recursive: true });\n const tmp = `${this.path}.tmp`;\n writeFileSync(tmp, JSON.stringify({ fetched_at: Date.now() / 1000, payload }), \"utf8\");\n renameSync(tmp, this.path); // atomic\n } catch {\n /* best-effort; a write failure degrades to \"no cache\" */\n }\n }\n}\n\nexport interface NetworkParticipantOptions {\n authProvider?: AuthProvider | null;\n cacheRoot?: string;\n}\n\n// -- Base participant ---------------------------------------------------------\n\n/**\n * Base for participants whose native state lives behind an authenticated API.\n * Caching, degradation, the auth boundary, and the\n * `discover`/`exportL5`/`exportSessions`/`healthCheck` plumbing live here;\n * subclasses provide only `fetchPayload` + `payloadToL5`.\n */\nexport abstract class NetworkParticipant implements BourdonParticipant {\n participantSlug = \"network\";\n agentId = \"network\";\n agentType = \"other\";\n cacheTtlSeconds: number = DEFAULT_CACHE_TTL_SECONDS;\n nativePath = \"network://\";\n\n protected readonly authProvider: AuthProvider | null;\n private readonly cacheRoot?: string;\n private cacheInstance?: PayloadCache;\n\n constructor(opts: NetworkParticipantOptions = {}) {\n this.authProvider = opts.authProvider ?? null;\n this.cacheRoot = opts.cacheRoot;\n }\n\n /** Lazily built so it reads the SUBCLASS's `participantSlug` — subclass field\n * initializers run after `super()`, so building the cache in the constructor\n * would capture the base \"network\" slug instead. */\n protected get cache(): PayloadCache {\n if (!this.cacheInstance) {\n this.cacheInstance = new PayloadCache(this.participantSlug, this.cacheRoot);\n }\n return this.cacheInstance;\n }\n\n // -- Subclass hooks ---------------------------------------------------------\n\n /** Do the authenticated API call; return a JSON-serializable dict. Raise\n * {@link NetworkUnavailable} on transport/5xx/rate-limit (→ cache fallback) or\n * {@link ParticipantAuthError} on 401/403 (→ blocked, no fallback). */\n abstract fetchPayload(token: string): Record<string, unknown>;\n\n /** Normalize a (fresh or cached) payload into an L5 manifest. Pure, no I/O. */\n abstract payloadToL5(payload: Record<string, unknown>): L5ManifestModel;\n\n // -- Core fetch-with-cache-and-degrade -------------------------------------\n\n /**\n * Resolve (payload, source) where source is 'cache' | 'network' | 'stale-cache'.\n * 1. Fresh cache hit → 'cache' (no network)\n * 2. Miss/expired + token → 'network' (fetch + refresh cache)\n * 3. Net fails + any cache → 'stale-cache' (serve last good payload)\n * 4. Net fails + no cache → raise\n * Auth errors are never swallowed — they propagate so health surfaces\n * 'blocked' rather than serving stale data behind a dead token.\n */\n protected getPayload(): { payload: Record<string, unknown>; source: string } {\n const cached = this.cache.read();\n if (cached !== null && cached.isFresh(this.cacheTtlSeconds)) {\n return { payload: cached.payload, source: \"cache\" };\n }\n\n const token = this.authProvider ? this.authProvider() : null;\n if (!token) {\n // No credential: if we have any cache, serve it stale; else blocked.\n if (cached !== null) return { payload: cached.payload, source: \"stale-cache\" };\n throw new ParticipantAuthError(\n `${this.participantSlug}: no auth token available and no cache`,\n );\n }\n\n let payload: Record<string, unknown>;\n try {\n payload = this.fetchPayload(token);\n } catch (err) {\n if (err instanceof ParticipantAuthError) throw err; // never mask a bad token\n if (err instanceof NetworkUnavailable) {\n if (cached !== null) return { payload: cached.payload, source: \"stale-cache\" };\n throw err;\n }\n throw err;\n }\n\n this.cache.write(payload);\n return { payload, source: \"network\" };\n }\n\n // -- Participant protocol ---------------------------------------------------\n\n discover(): AgentStore {\n const { source } = this.getPayload();\n return {\n path: this.nativePath,\n version: `${this.participantSlug}-network-v1`,\n metadata: { source, contract_version: NETWORK_CONTRACT_VERSION },\n };\n }\n\n exportL5(_since?: Date): L5ManifestModel {\n const { payload } = this.getPayload();\n return this.payloadToL5(payload);\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const manifest = this.exportL5(since);\n let sessions = manifest.recent_sessions ?? [];\n if (since) {\n const cutoff = since.toISOString().slice(0, 10);\n sessions = sessions.filter((s) => (s.date || \"\") >= cutoff);\n }\n return sessions.slice(0, limit);\n }\n\n healthCheck(): HealthStatus {\n let source: string;\n try {\n source = this.getPayload().source;\n } catch (err) {\n if (err instanceof ParticipantAuthError) {\n return {\n status: \"blocked\",\n reason: String(err.message),\n details: { participant: this.participantSlug },\n proposedFix:\n `Provide a valid credential for ${this.participantSlug} ` +\n \"(see the adapter docs for the auth path) and re-run `bourdon export-all`.\",\n };\n }\n if (err instanceof NetworkUnavailable) {\n return {\n status: \"degraded\",\n reason: `network unavailable and no cache: ${err.message}`,\n details: { participant: this.participantSlug },\n proposedFix: \"Check connectivity, then re-run `bourdon export-all`.\",\n };\n }\n // Defense in depth: health_check must NEVER raise. An adapter's\n // fetchPayload should only raise the two contract errors; anything else is\n // reported as blocked rather than propagated.\n return {\n status: \"blocked\",\n reason: `unexpected error resolving payload: ${String(err)}`,\n details: { participant: this.participantSlug },\n proposedFix:\n `${this.participantSlug} raised an unexpected error during healthCheck; ` +\n \"its fetchPayload should only raise ParticipantAuthError / NetworkUnavailable.\",\n };\n }\n\n const cached = this.cache.read();\n const details: Record<string, unknown> = { participant: this.participantSlug, source };\n if (cached !== null) {\n details[\"cache_age_seconds\"] = Math.round(cached.ageSeconds * 10) / 10;\n details[\"cache_fetched_at\"] = new Date(cached.fetchedAt * 1000)\n .toISOString()\n .replace(/\\.\\d{3}Z$/, \"+00:00\");\n }\n if (source === \"stale-cache\") {\n return {\n status: \"degraded\",\n reason: \"serving stale cache (network unavailable or no token)\",\n details,\n proposedFix: \"Restore connectivity / refresh the token to update.\",\n };\n }\n return { status: \"ok\", details };\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Hermes participant — normalize Hermes Agent (Nous Research) memory + sessions\n * into L5. Port of `participants/hermes.py`.\n *\n * Reads two surfaces under `~/.hermes/` (override `$HERMES_HOME`):\n * * `state.db` — a SQLite store (`sessions` + `messages` tables). Recent\n * non-archived sessions + project entities (from cwd basename) come from it.\n * * `memories/{memory.md,user.md}` — durable cross-session facts (one\n * Markdown bullet/line per memory). The highest-signal entities.\n *\n * Read-only (`mode=ro`), deterministic, visibility-enforced-before-emission,\n * and redaction on every native string. `healthCheck` never throws; `discover`\n * raises only {@link ParticipantDiscoveryError}.\n */\n\nimport { readFileSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n CONTRACT_VERSION,\n ParticipantDiscoveryError,\n SPEC_VERSION,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\nimport {\n epochToIsoDate,\n friendlyLabel,\n projectKeyFromCwd,\n tableColumns,\n tableExists,\n tryOpenReadonly,\n type SqliteDatabase,\n} from \"../sqlite-base.js\";\n\nconst AGENT_ID = \"hermes\";\nconst AGENT_TYPE = \"code-assistant\";\nconst DISPLAY_NAME = \"Hermes Agent\";\nconst ROLE_NARRATIVE =\n \"General-purpose tool-calling assistant (Nous Research). Operates across CLI, \" +\n \"TUI, and messaging gateways (Slack/Telegram/Discord/WhatsApp); runs terminal, \" +\n \"file, web, and delegation toolsets. Carries durable cross-session memory and a \" +\n \"curated skill library. Federates session + memory context, not vendor account.\";\n\nconst DEFAULT_SESSION_LIMIT = 100;\n\n/** Hermes memory stores live as Markdown under `~/.hermes/memories/`. */\nconst MEMORY_FILENAMES = [\"memory.md\", \"user.md\"] as const;\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"secret\", \"health\", \"family\", \"legal\"],\n team_tags: [\"hermes-memory\", \"hermes-session\", \"hermes-project\"],\n});\n\n/** cwd basenames that carry no project identity. */\nconst GENERIC_PROJECT_NAMES = new Set([\n \"\",\n \"root\",\n \"home\",\n \"tmp\",\n \"temp\",\n \"desktop\",\n \"documents\",\n \"downloads\",\n \"src\",\n]);\n\n// -- Path resolution ----------------------------------------------------------\n\n/**\n * Conventional Hermes home used by the setup wizard's detection.\n * Precedence: explicit `home` > `$HERMES_HOME` > `~/.hermes`.\n */\nexport function defaultNativePath(home?: string): string {\n if (home) return join(home, \".hermes\");\n const env = process.env.HERMES_HOME;\n if (env) return env;\n return join(homedir(), \".hermes\");\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\n// -- Text helpers -------------------------------------------------------------\n\ninterface SessionRecord {\n id: string;\n source: string;\n model: unknown;\n title: string | null;\n cwd: string | null;\n date: string;\n messageCount: number;\n toolCallCount: number;\n}\n\n/** Redact secrets, collapse whitespace, and clamp length. */\nfunction bounded(value: string, limit = 240): string {\n const cleaned = redactText((value || \"\").replace(/\\s+/g, \" \").trim(), limit);\n return cleaned.trim();\n}\n\nfunction projectKey(cwd: string | null | undefined): string | null {\n return projectKeyFromCwd(cwd, GENERIC_PROJECT_NAMES);\n}\n\n// -- SQLite (read-only) -------------------------------------------------------\n\n/** Pull recent, non-archived sessions newest-first. Never raises. */\nfunction collectSessionRows(stateDb: string, limit = DEFAULT_SESSION_LIMIT): SessionRecord[] {\n if (!isFile(stateDb)) return [];\n const conn = tryOpenReadonly(stateDb);\n if (!conn) return [];\n const out: SessionRecord[] = [];\n try {\n if (!tableExists(conn, \"sessions\")) return [];\n // `archived` may be absent in older schemas — guard the column.\n const cols = tableColumns(conn, \"sessions\");\n const archivedClause = cols.has(\"archived\") ? \"WHERE COALESCE(archived, 0) = 0\" : \"\";\n const rows = conn\n .prepare(\n `SELECT id, source, model, title, cwd, started_at, ended_at,\n message_count, tool_call_count\n FROM sessions\n ${archivedClause}\n ORDER BY started_at DESC\n LIMIT ?`,\n )\n .all(limit) as Array<Record<string, unknown>>;\n for (const r of rows) {\n const day = epochToIsoDate(r[\"started_at\"]);\n if (!day) continue;\n out.push({\n id: String(r[\"id\"]),\n source: String(r[\"source\"] ?? \"\").toLowerCase(),\n model: r[\"model\"],\n title: (r[\"title\"] as string | null) ?? null,\n cwd: (r[\"cwd\"] as string | null) ?? null,\n date: day,\n messageCount: Number(r[\"message_count\"] ?? 0) || 0,\n toolCallCount: Number(r[\"tool_call_count\"] ?? 0) || 0,\n });\n }\n } catch {\n /* degrade to whatever rows we gathered */\n } finally {\n conn.close();\n }\n return out;\n}\n\n/** Distinct tool names used in a session, for key_actions evidence. */\nfunction toolNamesForSession(conn: SqliteDatabase, sessionId: string): string[] {\n if (!tableExists(conn, \"messages\")) return [];\n try {\n const rows = conn\n .prepare(\n `SELECT DISTINCT tool_name FROM messages\n WHERE session_id = ? AND tool_name IS NOT NULL AND tool_name != ''`,\n )\n .all(sessionId) as Array<{ tool_name: string }>;\n const names = new Set<string>();\n for (const r of rows) {\n if (r.tool_name) names.add(r.tool_name);\n }\n return [...names].sort();\n } catch {\n return [];\n }\n}\n\n// -- Memory parsing -----------------------------------------------------------\n\nconst BULLET_RE = /^\\s*[-*]\\s+(.*)$/;\n\n/** Return memory entries (one per bullet / non-empty line). Never raises. */\nfunction parseMemoryFile(path: string): string[] {\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch {\n return [];\n }\n const entries: string[] = [];\n for (const line of text.split(/\\r?\\n/)) {\n const m = BULLET_RE.exec(line);\n const candidate = m ? (m[1] ?? \"\") : line.trim();\n if (candidate && !candidate.startsWith(\"#\")) entries.push(candidate);\n }\n return entries;\n}\n\n/** Map memory store name → list of entry strings. */\nfunction collectMemoryEntries(home: string): Array<[string, string[]]> {\n const memDir = join(home, \"memories\");\n const result: Array<[string, string[]]> = [];\n if (!isDir(memDir)) return result;\n for (const fname of MEMORY_FILENAMES) {\n const path = join(memDir, fname);\n if (isFile(path)) {\n const entries = parseMemoryFile(path);\n if (entries.length) {\n const stem = fname.replace(/\\.md$/, \"\");\n result.push([stem, entries]);\n }\n }\n }\n return result;\n}\n\n// -- Entity / session builders ------------------------------------------------\n\nfunction buildSession(record: SessionRecord, toolNames: string[]): SessionModel {\n const key = projectKey(record.cwd);\n const focus: string[] = [];\n if (key) focus.push(key);\n const keyActions: string[] = [];\n if (record.title) keyActions.push(bounded(record.title, 160));\n if (toolNames.length) {\n keyActions.push(\"Tools: \" + toolNames.slice(0, 8).join(\", \"));\n } else if (record.toolCallCount) {\n keyActions.push(`${record.toolCallCount} tool call(s)`);\n }\n return makeSession({\n date: record.date,\n cwd: record.cwd || undefined,\n project_focus: focus,\n key_actions: keyActions,\n visibility: Visibility.TEAM,\n });\n}\n\n/** Turn a single memory line into a team-visibility entity. */\nfunction memoryEntity(store: string, entry: string): EntityModel {\n const tag = store === \"user\" ? \"hermes-user-memory\" : \"hermes-memory\";\n return makeEntity({\n name: bounded(entry, 80),\n type: store === \"user\" ? \"preference\" : \"fact\",\n summary: bounded(entry, 240),\n tags: [tag],\n visibility: Visibility.TEAM,\n });\n}\n\nfunction projectEntities(records: SessionRecord[]): EntityModel[] {\n const counts = new Map<string, number>();\n for (const r of records) {\n const key = projectKey(r.cwd);\n if (key) counts.set(key, (counts.get(key) ?? 0) + 1);\n }\n const entities: EntityModel[] = [];\n for (const [key, count] of counts) {\n let last: string | undefined;\n for (const r of records) {\n if (projectKey(r.cwd) === key) {\n if (last === undefined || r.date > last) last = r.date;\n }\n }\n entities.push(\n makeEntity({\n name: friendlyLabel(key),\n type: \"project\",\n summary: `Workspace observed across ${count} Hermes session(s).`,\n aliases: [key],\n last_touched: last,\n tags: [\"hermes-project\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n return entities;\n}\n\n// -- Participant --------------------------------------------------------------\n\n/** External participant for local Hermes Agent memory + sessions. */\nexport class HermesParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n displayName = DISPLAY_NAME;\n nativePath: string;\n\n private readonly home: string | null;\n\n static defaultNativePath(home?: string): string {\n return defaultNativePath(home);\n }\n\n /** `hermesHome` is the `.hermes` directory itself (matching the Python ctor). */\n constructor(hermesHome?: string) {\n if (hermesHome) {\n this.home = hermesHome;\n } else {\n const path = defaultNativePath();\n this.home = isDir(path) ? path : null;\n }\n this.nativePath = this.home ?? join(homedir(), \".hermes\");\n }\n\n private sources(): Record<string, string | null> {\n const home = this.home;\n const stateDb = home ? join(home, \"state.db\") : null;\n const memDir = home ? join(home, \"memories\") : null;\n const skillsDir = home ? join(home, \"skills\") : null;\n return {\n hermes_home: home,\n state_db: stateDb && isFile(stateDb) ? stateDb : null,\n memories_dir: memDir && isDir(memDir) ? memDir : null,\n skills_dir: skillsDir && isDir(skillsDir) ? skillsDir : null,\n };\n }\n\n discover(): AgentStore {\n const sources = this.sources();\n if (!Object.values(sources).some((v) => v)) {\n throw new ParticipantDiscoveryError(\n \"No Hermes memory sources found. Expected ~/.hermes/ (set $HERMES_HOME to override).\",\n );\n }\n if (!sources[\"state_db\"] && !sources[\"memories_dir\"]) {\n throw new ParticipantDiscoveryError(\n `Hermes home '${this.nativePath}' exists but has no state.db or memories/ — ` +\n \"nothing to federate yet.\",\n );\n }\n return {\n path: this.nativePath,\n version: \"hermes-home-v1\",\n metadata: { sources },\n };\n }\n\n exportSessions(since?: Date, limit = DEFAULT_SESSION_LIMIT): SessionModel[] {\n if (this.home === null) return [];\n const stateDb = join(this.home, \"state.db\");\n const cutoff = since ? since.toISOString().slice(0, 10) : null;\n const records = collectSessionRows(stateDb, limit);\n if (!records.length) return [];\n const conn = tryOpenReadonly(stateDb);\n const out: SessionModel[] = [];\n try {\n for (const rec of records) {\n if (cutoff && rec.date < cutoff) continue;\n const tools = conn ? toolNamesForSession(conn, rec.id) : [];\n out.push(buildSession(rec, tools));\n }\n } finally {\n if (conn) conn.close();\n }\n return out;\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const store = this.discover();\n const sources = (store.metadata[\"sources\"] ?? {}) as Record<string, string | null>;\n const capabilities = Object.entries(sources)\n .filter(([k, v]) => v && k !== \"hermes_home\")\n .map(([k]) => k)\n .sort();\n\n const home = this.home;\n const records = home ? collectSessionRows(join(home, \"state.db\"), DEFAULT_SESSION_LIMIT) : [];\n\n // Entities: project workspaces + memory-derived facts/preferences.\n const entities: EntityModel[] = projectEntities(records);\n const seen = new Set<string>();\n for (const e of entities) {\n seen.add(`${e.type || \"topic\"}\\u0000${e.name.toLowerCase()}`);\n }\n if (home) {\n for (const [storeName, entries] of collectMemoryEntries(home)) {\n for (const entry of entries) {\n const ent = memoryEntity(storeName, entry);\n const key = `${ent.type || \"topic\"}\\u0000${ent.name.toLowerCase()}`;\n if (seen.has(key)) continue;\n seen.add(key);\n entities.push(ent);\n }\n }\n }\n\n // Visibility enforced here, before emission (contract requirement).\n const visible = filterForFederation(entities, DEFAULT_POLICY);\n\n const sessions = this.exportSessions(\n since ?? new Date(0),\n DEFAULT_SESSION_LIMIT,\n );\n\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: this.agentId,\n type: this.agentType,\n role_narrative: ROLE_NARRATIVE,\n spec_version_compat: CONTRACT_VERSION,\n }),\n last_updated: new Date().toISOString(),\n capabilities,\n recent_sessions: sessions,\n known_entities: visible,\n visibility_policy: DEFAULT_POLICY,\n });\n }\n\n healthCheck(): HealthStatus {\n const details: Record<string, unknown> = {\n hermes_home: this.nativePath,\n state_db: \"missing\",\n memories_dir: \"missing\",\n skills_dir: \"missing\",\n };\n try {\n if (this.home === null) {\n return {\n status: \"blocked\",\n reason: \"~/.hermes/ not found — Hermes Agent not installed here\",\n details,\n proposedFix:\n \"Install Hermes Agent and run a session once, then `bourdon export-all`.\",\n };\n }\n const sources = this.sources();\n for (const key of [\"state_db\", \"memories_dir\", \"skills_dir\"] as const) {\n if (sources[key]) details[key] = sources[key];\n }\n if (sources[\"state_db\"]) {\n const records = collectSessionRows(join(this.home, \"state.db\"), 1);\n if (records.length) return { status: \"ok\", details };\n return {\n status: \"degraded\",\n reason: \"state.db present but no readable sessions yet\",\n details,\n proposedFix: \"Run at least one Hermes session, then `bourdon export-all`.\",\n };\n }\n if (sources[\"memories_dir\"]) {\n return {\n status: \"degraded\",\n reason: \"memories/ present but state.db missing — session history unavailable\",\n details,\n };\n }\n return {\n status: \"blocked\",\n reason: \"Hermes home has neither state.db nor memories/\",\n details,\n proposedFix: \"Run a Hermes session to populate ~/.hermes/state.db.\",\n };\n } catch (err) {\n // healthCheck must NEVER raise (contract).\n return {\n status: \"degraded\",\n reason: `unexpected error: ${String(err)}`,\n details,\n };\n }\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Claude Code participant — reads agent-brain + auto-memory + MCP knowledge\n * graph. Port of `participants/claude_code.py`.\n *\n * Three optional sources (the participant degrades gracefully):\n * 1. agent-brain/ — git-synced markdown records\n * 2. ~/.claude/projects/<ws>/memory/ — per-machine auto-memory frontmatter\n * 3. ~/claude-memory/memory.jsonl — MCP knowledge-graph JSONL\n *\n * Only these names are read; a notes folder under any other name is never\n * scanned unless the user points `AGENT_BRAIN` at it.\n *\n * Privacy: entities typed `person` (+ family/contact variants) and observations\n * containing credential-like strings default to PRIVATE and are filtered before\n * federation. Entities are deduped by case-insensitive name and sorted\n * alphabetically.\n */\n\nimport { readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { homedir, hostname } from \"node:os\";\nimport { basename, join } from \"node:path\";\n\nimport { parse as yamlParse } from \"yaml\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type SkillRefModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { containsSecret } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\nimport {\n advertisedSkills,\n claudeCodeSkillSources,\n crossAgentSkillSources,\n scanSkillSources,\n type SkillScanReport,\n type SkillSource,\n} from \"../skills.js\";\n\nconst AGENT_ID = \"claude-code\";\nconst AGENT_TYPE = \"code-assistant\";\nconst ROLE_NARRATIVE =\n \"Agentic manager and code-assistant. Coordinates the agent fleet, \" +\n \"reviews PRs, and consults on architectural decisions. Capable of authoring \" +\n \"code but typically reviews + delegates to specialised code-assistants like \" +\n \"Codex for prime-code execution.\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.PUBLIC,\n private_tags: [\"personal\", \"financial\", \"credential\", \"health\", \"family\", \"legal\"],\n team_tags: [\"internal-roadmap\"],\n});\n\n/** Entity-type slugs that default to PRIVATE unless explicitly promoted. */\nconst PRIVATE_BY_DEFAULT_TYPES = new Set([\n \"person\",\n \"user\",\n \"individual\",\n \"contact\",\n \"family-member\",\n \"family_member\",\n]);\n\nconst MAX_SUMMARY_CHARS = 500;\nconst MAX_OBSERVATIONS_IN_SUMMARY = 2;\n\n// -- Path resolution ----------------------------------------------------------\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\n/** Directory names for the knowledge repo. Only these are scanned. */\nexport const BRAIN_DIR_NAMES: readonly [string] = [\"agent-brain\"];\n\n/** Env override pointing at the knowledge repo explicitly. */\nexport const BRAIN_ENV_VARS = [\"AGENT_BRAIN\"] as const;\n\n/**\n * Locate the knowledge repo using the documented precedence order.\n *\n * Explicit env override wins; then `$HOME/<name>`; then `$CWD/<name>`. No\n * other directory name is ever scanned.\n */\nfunction resolveBrainPath(): string | null {\n for (const varName of BRAIN_ENV_VARS) {\n const envOverride = process.env[varName];\n if (envOverride && isDir(envOverride)) return envOverride;\n }\n\n for (const base of [homeDir(), process.cwd()]) {\n for (const name of BRAIN_DIR_NAMES) {\n const candidate = join(base, name);\n if (isDir(candidate)) return candidate;\n }\n }\n\n return null;\n}\n\nfunction homeDir(): string {\n // os.homedir() can throw under some sandboxes; stay defensive so import +\n // construction never crash even when HOME points at an unreadable path.\n try {\n return homedir();\n } catch {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n }\n}\n\nfunction resolveAutoMemoryPath(): string | null {\n try {\n const base = join(homeDir(), \".claude\", \"projects\");\n if (!isDir(base)) return null;\n for (const child of readdirSync(base)) {\n const memMarker = join(base, child, \"memory\", \"MEMORY.md\");\n if (isFile(memMarker)) return join(base, child, \"memory\");\n }\n } catch {\n return null;\n }\n return null;\n}\n\nfunction resolveKnowledgeGraphPath(): string | null {\n const candidate = join(homeDir(), \"claude-memory\", \"memory.jsonl\");\n return isFile(candidate) ? candidate : null;\n}\n\n// -- Privacy scrubbing --------------------------------------------------------\n\nfunction isPrivateType(entityType: string | null | undefined): boolean {\n if (!entityType) return false;\n const normalized = entityType.split(\"/\").pop()?.trim().toLowerCase() ?? \"\";\n return PRIVATE_BY_DEFAULT_TYPES.has(normalized);\n}\n\n// -- YAML frontmatter ---------------------------------------------------------\n\nconst FRONTMATTER_OPEN = \"---\\n\";\nconst FRONTMATTER_CLOSE = \"\\n---\\n\";\n\nfunction parseFrontmatter(text: string): { frontmatter: Record<string, unknown>; body: string } {\n if (!text.startsWith(FRONTMATTER_OPEN)) return { frontmatter: {}, body: text };\n const end = text.indexOf(FRONTMATTER_CLOSE, FRONTMATTER_OPEN.length);\n if (end === -1) return { frontmatter: {}, body: text };\n const fmText = text.slice(FRONTMATTER_OPEN.length, end);\n const body = text.slice(end + FRONTMATTER_CLOSE.length);\n let parsed: unknown;\n try {\n parsed = yamlParse(fmText);\n } catch {\n return { frontmatter: {}, body: text };\n }\n const fm =\n typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : {};\n return { frontmatter: fm, body };\n}\n\n// -- Parser: agent-brain PROJECTS + LOG ---------------------------------------\n\nconst H1_RE = /^#[ \\t]+(.+?)[ \\t]*$/m;\nconst STATUS_SECTION_RE = /^##[ \\t]+(?:Current[ \\t]+)?Status[^\\n]*$/im;\nconst STATUS_DATE_RE = /\\b(\\d{4}-\\d{2}-\\d{2})\\b/;\nconst TITLE_SPLIT_RE = /\\s*[-—–:]+\\s+/;\n\nfunction extractH1Title(body: string): string | null {\n const match = H1_RE.exec(body);\n if (!match) return null;\n const title = (match[1] ?? \"\").trim();\n const head = title.split(TITLE_SPLIT_RE)[0] ?? title;\n return head.trim();\n}\n\nfunction extractFirstParagraph(body: string, maxChars = MAX_SUMMARY_CHARS): string {\n const paragraph: string[] = [];\n for (const line of body.split(/\\r?\\n/)) {\n const stripped = line.trim();\n if (!stripped) {\n if (paragraph.length) break;\n continue;\n }\n if (stripped.startsWith(\"#\")) continue;\n paragraph.push(stripped);\n if (paragraph.reduce((acc, s) => acc + s.length + 1, 0) > maxChars) break;\n }\n return paragraph.join(\" \").trim().slice(0, maxChars).trim();\n}\n\nfunction extractStatusTag(body: string): string[] {\n const match = STATUS_SECTION_RE.exec(body);\n if (!match) return [];\n const region = body.slice(match.index, match.index + 400).toLowerCase();\n const tags: string[] = [];\n for (const keyword of [\"archived\", \"canceled\", \"cancelled\", \"active\", \"shipped\", \"blocked\"]) {\n if (region.includes(keyword)) tags.push(keyword.replace(\"cancelled\", \"canceled\"));\n }\n return [...new Set(tags)];\n}\n\nconst END_OF_LIFE_TAGS = new Set([\"archived\", \"canceled\"]);\n\nfunction extractStatusDate(body: string): string | null {\n const match = STATUS_SECTION_RE.exec(body);\n if (!match) return null;\n const region = body.slice(match.index, match.index + 400);\n const dateMatch = STATUS_DATE_RE.exec(region);\n return dateMatch ? (dateMatch[1] ?? null) : null;\n}\n\nfunction parseProjectOverview(overviewPath: string): EntityModel | null {\n let text: string;\n try {\n text = readFileSync(overviewPath, \"utf8\");\n } catch {\n return null;\n }\n const { body } = parseFrontmatter(text);\n const title = extractH1Title(body) || basename(join(overviewPath, \"..\"));\n const summary = extractFirstParagraph(body);\n const tags = extractStatusTag(body);\n\n let validTo: string | null = null;\n if (tags.some((t) => END_OF_LIFE_TAGS.has(t))) {\n validTo = extractStatusDate(body);\n if (validTo === null) {\n try {\n const mtime = statSync(overviewPath).mtime;\n validTo = mtime.toISOString().slice(0, 10);\n } catch {\n validTo = null;\n }\n }\n }\n\n return makeEntity({\n name: title,\n type: \"project\",\n summary: summary || undefined,\n tags,\n valid_to: validTo ?? undefined,\n });\n}\n\nfunction parseProjectsDir(brainPath: string): EntityModel[] {\n const projectsDir = join(brainPath, \"PROJECTS\");\n if (!isDir(projectsDir)) return [];\n const entities: EntityModel[] = [];\n for (const name of readdirSync(projectsDir).sort()) {\n const projectDir = join(projectsDir, name);\n if (!isDir(projectDir)) continue;\n const overview = join(projectDir, \"OVERVIEW.md\");\n if (!isFile(overview)) continue;\n const entity = parseProjectOverview(overview);\n if (entity) entities.push(entity);\n }\n return entities;\n}\n\nconst LOG_FILENAME_RE = /^(\\d{4}-\\d{2}-\\d{2})(?:-(\\w+?))?(?:-.*)?\\.md$/;\n\nfunction parseLogFile(logPath: string): SessionModel | null {\n const m = LOG_FILENAME_RE.exec(basename(logPath));\n if (!m) return null;\n const sessionDate = m[1] ?? \"\";\n let text: string;\n try {\n text = readFileSync(logPath, \"utf8\");\n } catch {\n return null;\n }\n const { body } = parseFrontmatter(text);\n const headline = extractFirstParagraph(body, 250);\n return makeSession({\n date: sessionDate,\n key_actions: headline ? [headline] : [],\n files_touched: [`LOG/${basename(logPath)}`],\n });\n}\n\nfunction parseLogsDir(brainPath: string, since?: Date, limit = 100): SessionModel[] {\n const logDir = join(brainPath, \"LOG\");\n if (!isDir(logDir)) return [];\n const candidates: Array<[string, string]> = [];\n for (const fname of readdirSync(logDir)) {\n if (!fname.endsWith(\".md\")) continue;\n const m = LOG_FILENAME_RE.exec(fname);\n if (!m) continue;\n const d = m[1] ?? \"\";\n if (since) {\n if (d < since.toISOString().slice(0, 10)) continue;\n }\n candidates.push([d, join(logDir, fname)]);\n }\n candidates.sort((a, b) => (a[0] < b[0] ? 1 : a[0] > b[0] ? -1 : 0)); // newest first\n const sessions: SessionModel[] = [];\n for (const [, logFile] of candidates.slice(0, limit)) {\n const session = parseLogFile(logFile);\n if (session) sessions.push(session);\n }\n return sessions;\n}\n\n// -- Parser: auto-memory ------------------------------------------------------\n\nfunction parseAutoMemoryEntity(mdPath: string): EntityModel | null {\n let text: string;\n try {\n text = readFileSync(mdPath, \"utf8\");\n } catch {\n return null;\n }\n const { frontmatter, body } = parseFrontmatter(text);\n const name =\n (frontmatter[\"name\"] as string | undefined) ||\n extractH1Title(body) ||\n basename(mdPath).replace(/\\.md$/, \"\");\n const entityType = frontmatter[\"type\"] as string | undefined;\n const summaryRaw =\n (frontmatter[\"description\"] as string | undefined) || extractFirstParagraph(body);\n const rawTags = frontmatter[\"tags\"];\n const tags = Array.isArray(rawTags) ? rawTags.map((t) => String(t)) : [];\n\n const visibility = isPrivateType(entityType) ? Visibility.PRIVATE : undefined;\n\n return makeEntity({\n name: String(name),\n type: entityType ? String(entityType) : undefined,\n summary: summaryRaw ? String(summaryRaw).slice(0, MAX_SUMMARY_CHARS).trim() : undefined,\n tags,\n visibility,\n });\n}\n\nfunction parseAutoMemory(memoryPath: string): EntityModel[] {\n if (!isDir(memoryPath)) return [];\n const entities: EntityModel[] = [];\n for (const fname of readdirSync(memoryPath).sort()) {\n if (!fname.endsWith(\".md\") || fname === \"MEMORY.md\") continue;\n const entity = parseAutoMemoryEntity(join(memoryPath, fname));\n if (entity) entities.push(entity);\n }\n return entities;\n}\n\n// -- Parser: knowledge graph JSONL --------------------------------------------\n\nfunction graphEntityToBourdonEntity(record: Record<string, unknown>): EntityModel | null {\n const name = record[\"name\"];\n if (!name || typeof name !== \"string\") return null;\n const entityTypeSlug = (record[\"entityType\"] as string | undefined) || \"\";\n const normalizedType = entityTypeSlug ? (entityTypeSlug.split(\"/\").pop() ?? null) : null;\n const observations = Array.isArray(record[\"observations\"])\n ? (record[\"observations\"] as unknown[])\n : [];\n\n const safeObs: string[] = [];\n for (const obs of observations.slice(0, MAX_OBSERVATIONS_IN_SUMMARY)) {\n if (typeof obs !== \"string\") continue;\n safeObs.push(containsSecret(obs) ? \"[redacted -- contains credential-like content]\" : obs);\n }\n const joined = safeObs.join(\" | \").slice(0, MAX_SUMMARY_CHARS).trim();\n const summary = joined || undefined;\n\n const hasCredObs = observations.some((o) => typeof o === \"string\" && containsSecret(o));\n const visibility = isPrivateType(entityTypeSlug) || hasCredObs ? Visibility.PRIVATE : undefined;\n\n const tags =\n normalizedType && normalizedType !== name.toLowerCase() ? [normalizedType] : [];\n\n return makeEntity({\n name,\n type: normalizedType ?? undefined,\n summary,\n tags,\n visibility,\n });\n}\n\nfunction parseKnowledgeGraph(graphPath: string): EntityModel[] {\n if (!isFile(graphPath)) return [];\n let raw: string;\n try {\n raw = readFileSync(graphPath, \"utf8\");\n } catch {\n return [];\n }\n const entities: EntityModel[] = [];\n for (const lineRaw of raw.split(/\\r?\\n/)) {\n const line = lineRaw.trim();\n if (!line) continue;\n let record: unknown;\n try {\n record = JSON.parse(line);\n } catch {\n continue; // skip malformed JSONL (logged at WARNING in the oracle)\n }\n if (typeof record !== \"object\" || record === null) continue;\n const rec = record as Record<string, unknown>;\n if (rec[\"type\"] !== \"entity\") continue;\n const entity = graphEntityToBourdonEntity(rec);\n if (entity) entities.push(entity);\n }\n return entities;\n}\n\n// -- Dedupe + merge -----------------------------------------------------------\n\nconst VIS_ORDER: Record<string, number> = {\n [Visibility.PRIVATE]: 0,\n [Visibility.TEAM]: 1,\n [Visibility.PUBLIC]: 2,\n none: 3,\n};\n\nfunction visRank(v: Visibility | null | undefined): number {\n return v == null ? VIS_ORDER[\"none\"]! : VIS_ORDER[v]!;\n}\n\nfunction mergeEntities(into: EntityModel, other: EntityModel): EntityModel {\n if (!into.type && other.type) into.type = other.type;\n if (other.summary && other.summary.trim() && other.summary.length > (into.summary?.length ?? 0)) {\n into.summary = other.summary;\n }\n into.tags = [...new Set([...(into.tags ?? []), ...(other.tags ?? [])])];\n into.aliases = [...new Set([...(into.aliases ?? []), ...(other.aliases ?? [])])];\n if (other.last_touched && (into.last_touched == null || other.last_touched > into.last_touched)) {\n into.last_touched = other.last_touched;\n }\n // Temporal validity: the widest window either source supports. Dropping\n // these silently republished end-of-life entities as though still active.\n if (other.valid_from && (into.valid_from == null || other.valid_from < into.valid_from)) {\n into.valid_from = other.valid_from;\n }\n if (other.valid_to && (into.valid_to == null || other.valid_to > into.valid_to)) {\n into.valid_to = other.valid_to;\n }\n if (visRank(other.visibility) < visRank(into.visibility)) {\n into.visibility = other.visibility;\n }\n return into;\n}\n\n/**\n * Merge multiple entity lists into one, deduping by case-insensitive name.\n * The fresh copy carries EVERY field (mirroring the oracle's `replace()`):\n * a hand-kept field list here once dropped valid_from/valid_to, so archived\n * projects federated as though still active.\n */\nfunction dedupeEntities(sourceLists: EntityModel[][]): EntityModel[] {\n const byKey = new Map<string, EntityModel>();\n for (const source of sourceLists) {\n for (const entity of source) {\n const key = entity.name.trim().toLowerCase();\n if (!key) continue;\n const existing = byKey.get(key);\n if (existing) {\n mergeEntities(existing, entity);\n } else {\n byKey.set(\n key,\n makeEntity({\n ...entity,\n aliases: [...(entity.aliases ?? [])],\n tags: [...(entity.tags ?? [])],\n }),\n );\n }\n }\n }\n return [...byKey.values()].sort((a, b) => {\n const an = a.name.toLowerCase();\n const bn = b.name.toLowerCase();\n return an < bn ? -1 : an > bn ? 1 : 0;\n });\n}\n\n// -- Participant --------------------------------------------------------------\n\n/** External participant for Anthropic's Claude Code CLI. */\nexport class ClaudeCodeParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n nativePath: string;\n\n /** Public so a hermetic test can seed the discovered sources directly (path\n * RESOLUTION is not the parity contract — only the export output shape is). */\n brainPath: string | null;\n autoMemoryPath: string | null;\n knowledgeGraphPath: string | null;\n\n static defaultNativePath(home?: string): string {\n return join(home ?? homeDir(), \".claude\");\n }\n\n /**\n * Explicit skill directories; `null` = the defaults (see skills.ts), read\n * only for shared skills unless `BOURDON_SKILLS_ADVERTISE` lists all.\n * Explicit sources list every skill in them.\n */\n private readonly explicitSkillSources: readonly SkillSource[] | null;\n\n constructor(options: { skillSources?: readonly SkillSource[] | null } = {}) {\n this.nativePath = join(homeDir(), BRAIN_DIR_NAMES[0]); // primary anchor\n this.brainPath = resolveBrainPath();\n this.autoMemoryPath = resolveAutoMemoryPath();\n this.knowledgeGraphPath = resolveKnowledgeGraphPath();\n this.explicitSkillSources = options.skillSources == null ? null : [...options.skillSources];\n }\n\n // -- Skills (plan 005: discovery only) -----------------------------------------\n\n /**\n * `~/.claude/skills` (or the config-dir override) and the cross-agent store,\n * plus the opted-in projects' `.claude/skills` and `.agents/skills`.\n */\n /** Built with explicit skill sources: this participant lists all of them. */\n hasExplicitSkillSources(): boolean {\n return this.explicitSkillSources !== null;\n }\n\n skillSources(): SkillSource[] {\n if (this.explicitSkillSources !== null) return [...this.explicitSkillSources];\n return [...claudeCodeSkillSources(), ...crossAgentSkillSources()];\n }\n\n /** Advertised skills plus the skills that could not be advertised. */\n scanSkills(): SkillScanReport {\n return scanSkillSources(this.skillSources());\n }\n\n exportSkills(): SkillRefModel[] {\n return this.scanSkills().refs;\n }\n\n discover(): AgentStore {\n const sources = {\n agent_brain: this.brainPath,\n auto_memory: this.autoMemoryPath,\n knowledge_graph: this.knowledgeGraphPath,\n };\n if (!Object.values(sources).some((v) => v)) {\n throw new ParticipantDiscoveryError(\n \"No Claude Code memory sources found. Expected one of: ~/agent-brain/, \" +\n \"~/.claude/projects/*/memory/, ~/claude-memory/memory.jsonl.\",\n );\n }\n return {\n path: this.nativePath,\n version: \"claude-code-memory-v1\",\n metadata: { sources },\n };\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const store = this.discover(); // re-raises on missing\n const sources = store.metadata[\"sources\"] as Record<string, string | null>;\n const capabilities = Object.entries(sources)\n .filter(([, v]) => v)\n .map(([k]) => k)\n .sort();\n\n const autoMemoryEntities = this.autoMemoryPath ? parseAutoMemory(this.autoMemoryPath) : [];\n const graphEntities = this.knowledgeGraphPath\n ? parseKnowledgeGraph(this.knowledgeGraphPath)\n : [];\n const projectEntities = this.brainPath ? parseProjectsDir(this.brainPath) : [];\n\n // Priority: auto-memory > graph > brain projects (first wins on collision).\n const allEntities = dedupeEntities([autoMemoryEntities, graphEntities, projectEntities]);\n\n // Visibility filter — private entities never leave this function.\n const visibleEntities = filterForFederation(allEntities, DEFAULT_POLICY);\n\n const sessions = this.brainPath ? parseLogsDir(this.brainPath, since) : [];\n\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: this.agentId,\n type: this.agentType,\n instance: hostname() || \"unknown\",\n spec_version_compat: `>=${SPEC_VERSION}`,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: new Date().toISOString(),\n capabilities,\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: DEFAULT_POLICY,\n skills: advertisedSkills(this),\n });\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n if (!this.brainPath) return [];\n return parseLogsDir(this.brainPath, since, limit);\n }\n\n healthCheck(): HealthStatus {\n try {\n const present = [this.brainPath, this.autoMemoryPath, this.knowledgeGraphPath].filter(\n (p) => p !== null,\n ).length;\n const details = {\n agent_brain: this.brainPath ?? \"missing\",\n auto_memory: this.autoMemoryPath ?? \"missing\",\n knowledge_graph: this.knowledgeGraphPath ?? \"missing\",\n };\n if (present === 3) return { status: \"ok\", details };\n if (present === 0) {\n return {\n status: \"blocked\",\n reason: \"No Claude Code memory sources found on this machine\",\n details,\n proposedFix:\n \"Run `bourdon setup` to wire the SessionEnd hook and bootstrap \" +\n \"~/agent-library/, then open Claude Code once to populate ~/.claude/projects/.\",\n };\n }\n return {\n status: \"degraded\",\n reason: `${present}/3 Claude Code memory sources found`,\n details,\n proposedFix:\n \"Run `bourdon setup` to (re-)wire missing sources, or set the AGENT_BRAIN \" +\n \"env var to point at your agent-brain checkout.\",\n };\n } catch (err) {\n return {\n status: \"degraded\",\n reason: `unexpected error: ${String(err)}`,\n details: {},\n };\n }\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Skill readers: advertise the local skills an agent can see in its L5\n * manifest (plan 005, discovery side). Port of `participants/_skills.py`.\n *\n * A participant that knows where its agent keeps skills (a folder per skill\n * holding a `SKILL.md` with `name` / `description` front matter) lists them as\n * `SkillRef` rows: name, description and a content hash. Nothing is shared or\n * promoted here; the body never enters the manifest.\n *\n * Two kinds of skill directory:\n * - **The agent's own** (`~/.claude/skills`, `$CODEX_HOME/skills`,\n * `~/.cursor/skills` and their project forms).\n * - **The cross-agent store**, `~/.agents/skills` (and `<project>/.agents/skills`):\n * a vendor-neutral directory no single agent owns. The cross-agent skills\n * installer CLI keeps its installs there and records each one in\n * `~/.agents/.skill-lock.json`; people also write skills there by hand. Refs\n * from it carry `store: cross_agent`. Every skill-reading participant reads\n * it with its own directories; a reader of several manifests collapses the\n * copies (`collectAdvertisedSkills` in @getbourdon/federation).\n *\n * One skill, one ref per manifest: when an agent's own folder holds a skill\n * that is also in the cross-agent store, the agent-folder ref is kept and\n * records the store copy in `also_in` (`via: copy` for a copy with the same\n * `content_sha256`, `via: link` for a link into the store); the store's own ref\n * is then left out. A link counts only when it resolves to a direct child\n * folder of the store at the same scope, and the skill is then read through\n * the store's own path, never through the link. Any other link is skipped.\n *\n * Provenance (user-level store only): a skill with an entry in the installer\n * lock carries `origin: {kind: installed, ...}`; one without carries\n * `origin: {kind: authored}`. Nothing else is read from the lock, and a\n * missing, linked, oversized or malformed lock never fails a scan.\n *\n * Scope: one skill at a time. By default a participant lists only the skills\n * the person approved one by one with `bourdon skills share` (stored locally\n * in `<library>/.skill-shares.json`, see skill-shares.ts), and only while the\n * folder still hashes to the approved content; no other skill folder is read.\n * `BOURDON_SKILLS_ADVERTISE` set to an on value lists every skill; an off\n * value or an unrecognised one lists none, shared or not. A caller that builds\n * a participant with explicit `skillSources` lists every skill in them\n * ({@link skillsListingMode}). The directories: user-level skill directories,\n * and a project's directories\n * only when the project is named in `BOURDON_SKILL_PROJECTS` (absolute paths\n * separated by the platform's path delimiter). Disallowed files are skipped\n * and flagged, never fatal; no link is followed; no absolute path reaches the\n * manifest (`path_hint` starts at a symbolic root); refs are emitted as\n * `team`.\n */\n\nimport { lstatSync, readdirSync, readFileSync, realpathSync, type Dirent, type Stats } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { basename, delimiter, dirname, isAbsolute, join, normalize } from \"node:path\";\n\nimport {\n Visibility,\n makeSkillRef,\n type SkillOriginModel,\n type SkillRefModel,\n} from \"@getbourdon/l5\";\nimport { containsSecret } from \"@getbourdon/redaction\";\n\nimport {\n SkillContentError,\n codePointLength,\n codePointSlice,\n compareUtf8,\n isPathLinkOrReparse,\n pyStrip,\n scanLocalSkill,\n} from \"./skill-index.js\";\nimport { loadShares, shareAppliesTo } from \"./skill-shares.js\";\n\n/** Opt-in list of project roots whose skill directories may be indexed. */\nexport const SKILL_PROJECTS_ENV = \"BOURDON_SKILL_PROJECTS\";\n\n/**\n * The listing switch for every participant. Skill descriptions are free text\n * and can name private projects, clients or infrastructure, so by default\n * (unset or empty) only the skills approved one by one are listed. `1` /\n * `true` / `yes` / `on` list every skill; `0` / `false` / `no` / `off` list\n * none, approved or not, and so does any other value (fail closed): a typo\n * never lists anything.\n */\nexport const SKILLS_ADVERTISE_ENV = \"BOURDON_SKILLS_ADVERTISE\";\n\n/**\n * Turns named participants off in every mode: agent ids separated by commas\n * (or whitespace), e.g. `codex,cursor`. Matching ignores case.\n */\nexport const SKILLS_NO_ADVERTISE_ENV = \"BOURDON_SKILLS_NO_ADVERTISE\";\n\n/** {@link skillsListingMode} results. */\nexport const LIST_ALL = \"all\";\nexport const LIST_APPROVED = \"approved\";\nexport const LIST_OFF = \"off\";\nexport type SkillsListingMode = typeof LIST_ALL | typeof LIST_APPROVED | typeof LIST_OFF;\n\nconst ADVERTISE_ON: ReadonlySet<string> = new Set([\"1\", \"true\", \"yes\", \"on\"]);\nconst ADVERTISE_OFF: ReadonlySet<string> = new Set([\"0\", \"false\", \"no\", \"off\"]);\n// A run of str.split() whitespace.\n// eslint-disable-next-line no-control-regex\nconst PY_WHITESPACE_RUN = /[\\t\\n\\v\\f\\r\\x1c-\\x1f \\x85\\xa0\\u1680\\u2000-\\u200a\\u2028\\u2029\\u202f\\u205f\\u3000]+/;\n\n/** Every advertised ref carries this visibility. */\nexport const SKILL_REF_VISIBILITY = Visibility.TEAM;\n\n/** The L5 schema bounds (`skills.maxItems` and the `SkillRef` fields). */\nexport const MAX_SKILL_REFS = 512;\nexport const MAX_SKIPPED_FILES = 32;\nexport const MAX_PATH_HINT_CHARS = 255;\nexport const MAX_PROJECT_NAME_CHARS = 128;\nexport const MAX_ORIGIN_SOURCE_CHARS = 255;\nexport const MAX_ORIGIN_URL_CHARS = 512;\nexport const MAX_ORIGIN_SOURCE_TYPE_CHARS = 32;\n\n/** An installer lock larger than this is not read (origin is then omitted). */\nexport const MAX_LOCK_BYTES = 4 * 1024 * 1024;\n\nexport const SCOPE_USER = \"user\";\nexport const SCOPE_PROJECT = \"project\";\n\n/** Whose directory a skill folder sits in; `agent` is the default and never written. */\nexport const STORE_AGENT = \"agent\";\nexport const STORE_CROSS_AGENT = \"cross_agent\";\n\nexport const VIA_COPY = \"copy\";\nexport const VIA_LINK = \"link\";\n\nexport const ORIGIN_INSTALLED = \"installed\";\nexport const ORIGIN_AUTHORED = \"authored\";\n\n/** The cross-agent installer's lock file, beside the user-level store. */\nexport const CROSS_AGENT_LOCK_NAME = \".skill-lock.json\";\n\n// Kept in step with $defs/SkillRef.origin in the L5 schema.\nconst ORIGIN_SOURCE_RE = /^[A-Za-z0-9][A-Za-z0-9._~/:+-]*$/;\nconst ORIGIN_SOURCE_TYPE_RE = /^[a-z0-9][a-z0-9_-]*$/;\nconst ORIGIN_URL_RE = /^https?:\\/\\/[^\\s/?#@]+(\\/[^\\s?#]*)?$/;\n\n/**\n * One directory a reader indexes, one skill per child folder. `label` is the\n * symbolic form of `root` that `path_hint` starts with; it never contains an\n * absolute path. `store` says whose directory it is; `lockFile` is the\n * installer lock that records where the store's skills came from.\n */\nexport interface SkillSource {\n root: string;\n scope: string;\n label: string;\n project?: string | null;\n store?: string;\n lockFile?: string | null;\n}\n\n/** A skill (or a whole skills directory) that was not advertised, and why. */\nexport interface SkippedSkill {\n pathHint: string;\n scope: string;\n reason: string;\n project?: string | null;\n}\n\nexport interface SkillScanReport {\n refs: SkillRefModel[];\n skipped: SkippedSkill[];\n}\n\nfunction warn(message: string): void {\n console.warn(`[bourdon.participants] ${message}`);\n}\n\n/** The home directory user-level skill directories are found under. */\nexport function userHome(): string {\n return homedir();\n}\n\n// -- sources ------------------------------------------------------------------\n\nfunction expandUser(path: string): string {\n if (path === \"~\") return userHome();\n if (path.startsWith(\"~/\") || path.startsWith(\"~\\\\\")) return join(userHome(), path.slice(2));\n return path;\n}\n\nfunction isAbsoluteProjectPath(path: string): boolean {\n if (process.platform === \"win32\") {\n // A Windows path is absolute only with a drive and a root, or as UNC.\n return /^[A-Za-z]:[\\\\/]/.test(path) || /^[\\\\/]{2}[^\\\\/]/.test(path);\n }\n return isAbsolute(path);\n}\n\nfunction pathKey(path: string): string {\n const normalized = normalize(path);\n const trimmed = normalized.replace(/[\\\\/]+$/, \"\");\n return trimmed === \"\" || /^[A-Za-z]:$/.test(trimmed) ? normalized : trimmed;\n}\n\n/**\n * Project roots opted in through {@link SKILL_PROJECTS_ENV}, in order. Only\n * absolute paths count: a relative entry is ignored (and logged) rather than\n * resolved against whatever directory the export happens to run in.\n */\nexport function skillProjects(): string[] {\n const raw = process.env[SKILL_PROJECTS_ENV] ?? \"\";\n const projects: string[] = [];\n const seen = new Set<string>();\n for (const entry of raw.split(delimiter)) {\n const text = pyStrip(entry);\n if (!text) continue;\n const path = expandUser(text);\n if (!isAbsoluteProjectPath(path)) {\n warn(`${SKILL_PROJECTS_ENV}: ignoring relative entry (use an absolute path)`);\n continue;\n }\n const key = pathKey(path);\n if (seen.has(key)) continue;\n seen.add(key);\n projects.push(key);\n }\n return projects;\n}\n\nfunction projectName(project: string): string {\n const name = basename(pathKey(project)) || \"project\";\n return codePointSlice(name, MAX_PROJECT_NAME_CHARS);\n}\n\nfunction projectSources(\n projects: readonly string[] | undefined,\n relative: string,\n store: string = STORE_AGENT,\n): SkillSource[] {\n const chosen = projects === undefined ? skillProjects() : [...projects];\n return chosen.map((project) => ({\n root: join(project, ...relative.split(\"/\")),\n scope: SCOPE_PROJECT,\n label: relative,\n project: projectName(project),\n store,\n lockFile: null,\n }));\n}\n\nfunction homeOverride(...names: string[]): [string, string] | null {\n for (const name of names) {\n const value = process.env[name];\n if (value) return [expandUser(value), `$${name}`];\n }\n return null;\n}\n\nexport interface SkillSourceOptions {\n /** The home directory to use instead of {@link userHome}. */\n home?: string;\n /** Project roots instead of {@link skillProjects}. */\n projects?: readonly string[];\n}\n\n/**\n * Claude Code: `<config dir>/skills` and, on opt-in, `<project>/.claude/skills`.\n * The config directory is `CLAUDE_CONFIG_DIR` (Claude Code's own override),\n * else `CLAUDE_HOME`, else `~/.claude`.\n */\nexport function claudeCodeSkillSources(options: SkillSourceOptions = {}): SkillSource[] {\n const override = homeOverride(\"CLAUDE_CONFIG_DIR\", \"CLAUDE_HOME\");\n let user: SkillSource;\n if (override !== null) {\n const [configDir, label] = override;\n user = { root: join(configDir, \"skills\"), scope: SCOPE_USER, label: `${label}/skills` };\n } else {\n const base = options.home ?? userHome();\n user = { root: join(base, \".claude\", \"skills\"), scope: SCOPE_USER, label: \"~/.claude/skills\" };\n }\n return [user, ...projectSources(options.projects, \".claude/skills\")];\n}\n\n/**\n * Codex: `$CODEX_HOME/skills`. `codexHome` is an explicit Codex home, if one\n * was given; otherwise `CODEX_HOME`, else `~/.codex`. Codex keeps its bundled\n * skills in a hidden `.system` folder there, which is not indexed. The mirror\n * has no Codex participant yet; this is the source a Codex reader would use.\n */\nexport function codexSkillSources(\n options: { codexHome?: string | null; home?: string } = {},\n): SkillSource[] {\n if (options.codexHome != null) {\n return [\n { root: join(options.codexHome, \"skills\"), scope: SCOPE_USER, label: \"$CODEX_HOME/skills\" },\n ];\n }\n const override = homeOverride(\"CODEX_HOME\");\n if (override !== null) {\n const [root, label] = override;\n return [{ root: join(root, \"skills\"), scope: SCOPE_USER, label: `${label}/skills` }];\n }\n const base = options.home ?? userHome();\n return [{ root: join(base, \".codex\", \"skills\"), scope: SCOPE_USER, label: \"~/.codex/skills\" }];\n}\n\n/**\n * Cursor: `~/.cursor/skills` and, on opt-in, `<project>/.cursor/skills`.\n * `CURSOR_HOME` overrides `~/.cursor`. `~/.cursor/skills-cursor` holds\n * Cursor's own built-in skills and is not indexed.\n */\nexport function cursorSkillSources(options: SkillSourceOptions = {}): SkillSource[] {\n const override = homeOverride(\"CURSOR_HOME\");\n let user: SkillSource;\n if (override !== null) {\n const [root, label] = override;\n user = { root: join(root, \"skills\"), scope: SCOPE_USER, label: `${label}/skills` };\n } else {\n const base = options.home ?? userHome();\n user = { root: join(base, \".cursor\", \"skills\"), scope: SCOPE_USER, label: \"~/.cursor/skills\" };\n }\n return [user, ...projectSources(options.projects, \".cursor/skills\")];\n}\n\n/**\n * The vendor-neutral store: `~/.agents/skills` and, on opt-in,\n * `<project>/.agents/skills`. The user-level store comes with the installer\n * lock for provenance; no lock is read for a project store.\n */\nexport function crossAgentSkillSources(options: SkillSourceOptions = {}): SkillSource[] {\n const base = options.home ?? userHome();\n const agentsDir = join(base, \".agents\");\n const user: SkillSource = {\n root: join(agentsDir, \"skills\"),\n scope: SCOPE_USER,\n label: \"~/.agents/skills\",\n store: STORE_CROSS_AGENT,\n lockFile: join(agentsDir, CROSS_AGENT_LOCK_NAME),\n };\n return [user, ...projectSources(options.projects, \".agents/skills\", STORE_CROSS_AGENT)];\n}\n\n// -- installer lock -------------------------------------------------------------\n\ntype LockEntry = Record<string, unknown>;\n\nfunction isDict(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nconst STRICT_UTF8 = new TextDecoder(\"utf-8\", { fatal: true, ignoreBOM: true });\n\n/**\n * The `skills` table of the installer lock, keyed by skill name. An empty map\n * when there is no lock (every store skill is then `authored`); `null` when a\n * lock exists but cannot be trusted or parsed (a link, not a regular file, too\n * large, not JSON, or without a `skills` mapping), in which case origin is left\n * off rather than guessed.\n */\nexport function readInstallLock(path: string): Map<string, LockEntry> | null {\n let info: Stats;\n try {\n info = lstatSync(path);\n } catch (err) {\n return (err as NodeJS.ErrnoException).code === \"ENOENT\" ? new Map() : null;\n }\n let data: unknown;\n try {\n if (isPathLinkOrReparse(path, info) || !info.isFile()) return null;\n if (info.size > MAX_LOCK_BYTES) return null;\n data = JSON.parse(STRICT_UTF8.decode(readFileSync(path)));\n } catch {\n return null;\n }\n if (!isDict(data)) return null;\n const skills = data.skills;\n if (!isDict(skills)) return null;\n const table = new Map<string, LockEntry>();\n for (const [name, entry] of Object.entries(skills)) {\n if (isDict(entry)) table.set(name, entry);\n }\n return table;\n}\n\nfunction cleanSource(value: unknown): string | null {\n if (typeof value !== \"string\") return null;\n const text = pyStrip(value);\n if (!text || codePointLength(text) > MAX_ORIGIN_SOURCE_CHARS) return null;\n if (!ORIGIN_SOURCE_RE.test(text) || containsSecret(text)) return null;\n return text;\n}\n\nfunction cleanSourceType(value: unknown): string | null {\n if (typeof value !== \"string\") return null;\n const text = pyStrip(value);\n if (!text || codePointLength(text) > MAX_ORIGIN_SOURCE_TYPE_CHARS) return null;\n return ORIGIN_SOURCE_TYPE_RE.test(text) ? text : null;\n}\n\n// urllib.parse.urlsplit: leading C0 control/space stripped, tab/CR/LF removed.\n// eslint-disable-next-line no-control-regex\nconst URL_LEADING_JUNK_RE = /^[\\x00-\\x20]+/;\nconst URL_UNSAFE_RE = /[\\t\\r\\n]/g;\nconst URL_SCHEME_RE = /^([A-Za-z][A-Za-z0-9+.-]*):/;\n\n/** The scheme, netloc and path of `value` as Python's `urlsplit` reads them, or null on its ValueError. */\nfunction urlSplit(value: string): { scheme: string; netloc: string; path: string } | null {\n let url = value.replace(URL_LEADING_JUNK_RE, \"\").replace(URL_UNSAFE_RE, \"\");\n let scheme = \"\";\n const schemeMatch = URL_SCHEME_RE.exec(url);\n if (schemeMatch) {\n scheme = (schemeMatch[1] ?? \"\").toLowerCase();\n url = url.slice(schemeMatch[0].length);\n }\n let netloc = \"\";\n if (url.startsWith(\"//\")) {\n const rest = url.slice(2);\n const delim = rest.search(/[/?#]/);\n netloc = delim === -1 ? rest : rest.slice(0, delim);\n url = delim === -1 ? \"\" : rest.slice(delim);\n if (netloc.includes(\"[\") !== netloc.includes(\"]\")) return null;\n }\n const hash = url.indexOf(\"#\");\n if (hash !== -1) url = url.slice(0, hash);\n const query = url.indexOf(\"?\");\n if (query !== -1) url = url.slice(0, query);\n return { scheme, netloc, path: url };\n}\n\nfunction urlHostname(netloc: string): string | null {\n const hostinfo = netloc.slice(netloc.lastIndexOf(\"@\") + 1);\n let host: string;\n if (hostinfo.startsWith(\"[\")) {\n const close = hostinfo.indexOf(\"]\");\n host = close === -1 ? \"\" : hostinfo.slice(1, close);\n } else {\n const colon = hostinfo.indexOf(\":\");\n host = colon === -1 ? hostinfo : hostinfo.slice(0, colon);\n }\n return host ? host.toLowerCase() : null;\n}\n\n/** An http(s) URL without credentials; query string and fragment dropped. */\nfunction cleanSourceUrl(value: unknown): string | null {\n if (typeof value !== \"string\") return null;\n const parts = urlSplit(pyStrip(value));\n if (parts === null) return null;\n if ((parts.scheme !== \"http\" && parts.scheme !== \"https\") || !urlHostname(parts.netloc)) {\n return null;\n }\n // Credentials in the URL: drop it rather than try to repair it.\n if (parts.netloc.includes(\"@\")) return null;\n const url = `${parts.scheme}://${parts.netloc}${parts.path}`;\n if (codePointLength(url) > MAX_ORIGIN_URL_CHARS || !ORIGIN_URL_RE.test(url)) return null;\n return containsSecret(url) ? null : url;\n}\n\n// datetime.fromisoformat (3.11+): extended or basic date, any one-character\n// separator, then HH[:MM[:SS[.f+]]] or the basic forms, then an optional offset.\nconst ISO_DATE_RE = /^(\\d{4})-?(\\d{2})-?(\\d{2})/;\nconst ISO_TIME_RE = /^(\\d{2})(?::?(\\d{2})(?::?(\\d{2})(?:[.,](\\d+))?)?)?/;\nconst ISO_OFFSET_RE = /^([+-])(\\d{2})(?::?(\\d{2})(?::?(\\d{2})(?:\\.(\\d+))?)?)?$/;\n\nfunction daysInMonth(year: number, month: number): number {\n const leap = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n return [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month - 1] ?? 0;\n}\n\nfunction pad(value: number, width: number): string {\n return String(value).padStart(width, \"0\");\n}\n\nfunction cleanTimestamp(value: unknown): string | null {\n if (typeof value !== \"string\" || codePointLength(value) > 64) return null;\n let text = pyStrip(value);\n if (text.endsWith(\"Z\") || text.endsWith(\"z\")) text = `${text.slice(0, -1)}+00:00`;\n const date = ISO_DATE_RE.exec(text);\n if (!date) return null;\n const extendedDate = date[0].includes(\"-\");\n if (extendedDate && date[0].length !== 10) return null;\n if (!extendedDate && date[0].length !== 8) return null;\n const [year, month, day] = [Number(date[1]), Number(date[2]), Number(date[3])];\n if (year < 1 || month < 1 || month > 12 || day < 1 || day > daysInMonth(year, month)) {\n return null;\n }\n let rest = text.slice(date[0].length);\n let [hour, minute, second] = [0, 0, 0];\n let offsetSeconds = 0;\n if (rest.length > 0) {\n const separator = Array.from(rest)[0] ?? \"\";\n rest = rest.slice(separator.length);\n const time = ISO_TIME_RE.exec(rest);\n if (!time) return null;\n hour = Number(time[1]);\n minute = time[2] === undefined ? 0 : Number(time[2]);\n second = time[3] === undefined ? 0 : Number(time[3]);\n if (hour > 23 || minute > 59 || second > 59) return null;\n rest = rest.slice(time[0].length);\n if (rest.length > 0) {\n const offset = ISO_OFFSET_RE.exec(rest);\n if (!offset) return null;\n const oh = Number(offset[2]);\n const om = offset[3] === undefined ? 0 : Number(offset[3]);\n const os = offset[4] === undefined ? 0 : Number(offset[4]);\n if (oh > 23 || om > 59 || os > 59) return null;\n offsetSeconds = (offset[1] === \"-\" ? -1 : 1) * (oh * 3600 + om * 60 + os);\n }\n }\n const moment = new Date(0);\n moment.setUTCFullYear(year, month - 1, day);\n moment.setUTCHours(hour, minute, second, 0);\n const utc = new Date(moment.getTime() - offsetSeconds * 1000);\n const utcYear = utc.getUTCFullYear();\n if (utcYear < 1 || utcYear > 9999) return null;\n return (\n `${pad(utcYear, 4)}-${pad(utc.getUTCMonth() + 1, 2)}-${pad(utc.getUTCDate(), 2)}` +\n `T${pad(utc.getUTCHours(), 2)}:${pad(utc.getUTCMinutes(), 2)}:${pad(utc.getUTCSeconds(), 2)}Z`\n );\n}\n\n/**\n * `installed` with the lock entry's sanitised source fields, else `authored`.\n * Reads only `source`, `sourceType`, `sourceUrl` and `updatedAt`; a field\n * that is missing, of the wrong type or fails its check is left out.\n */\nexport function originFromLockEntry(entry: LockEntry | null | undefined): SkillOriginModel {\n if (entry == null) return { kind: ORIGIN_AUTHORED };\n return {\n kind: ORIGIN_INSTALLED,\n source: cleanSource(entry.source),\n source_type: cleanSourceType(entry.sourceType),\n source_url: cleanSourceUrl(entry.sourceUrl),\n updated_at: cleanTimestamp(entry.updatedAt),\n };\n}\n\n// -- scanning -----------------------------------------------------------------\n\n/** A ref plus what the assembly step needs to know about it. */\ninterface Found {\n source: SkillSource;\n folder: string;\n ref: SkillRefModel;\n /** The store skill an agent folder copies or links. */\n represents: Found | null;\n represented: boolean;\n}\n\n/** A scanned cross-agent store that agent folders are matched against. */\ninterface Store {\n source: SkillSource;\n realRoot: string | null;\n byFolder: Map<string, Found>;\n byHash: Map<string, Found>;\n}\n\nfunction sourceStore(source: SkillSource): string {\n return source.store ?? STORE_AGENT;\n}\n\nfunction skip(report: SkillScanReport, source: SkillSource, hint: string, reason: string): void {\n report.skipped.push({\n pathHint: hint,\n scope: source.scope,\n reason,\n project: source.project ?? null,\n });\n}\n\nfunction listSource(source: SkillSource, report: SkillScanReport): Dirent[] | null {\n const root = source.root;\n let info: Stats;\n try {\n info = lstatSync(root);\n } catch {\n return null; // no such directory: the agent simply has no skills here\n }\n if (isPathLinkOrReparse(root, info)) {\n skip(report, source, source.label, \"skills directory is a link; links are not followed\");\n return null;\n }\n if (!info.isDirectory()) return null;\n try {\n return readdirSync(root, { withFileTypes: true }).sort((a, b) => compareUtf8(a.name, b.name));\n } catch {\n skip(report, source, source.label, \"skills directory cannot be listed\");\n return null;\n }\n}\n\nfunction makeRef(\n source: SkillSource,\n hint: string,\n folder: string,\n report: SkillScanReport,\n): SkillRefModel | null {\n if (codePointLength(hint) > MAX_PATH_HINT_CHARS) {\n skip(report, source, codePointSlice(hint, MAX_PATH_HINT_CHARS), \"path is too long\");\n return null;\n }\n let scan;\n try {\n scan = scanLocalSkill(folder);\n } catch (err) {\n if (err instanceof SkillContentError) {\n skip(report, source, hint, err.problems.join(\"; \"));\n } else {\n skip(report, source, hint, \"skill folder cannot be read\");\n }\n return null;\n }\n return makeSkillRef({\n name: scan.frontMatter.name,\n description: scan.frontMatter.description,\n content_sha256: scan.contentSha256,\n scope: source.scope,\n path_hint: hint,\n project: source.project ?? null,\n skipped_files: scan.skipped.slice(0, MAX_SKIPPED_FILES).map((item) => ({\n path: codePointSlice(item.path, MAX_PATH_HINT_CHARS),\n reason: item.reason,\n })),\n visibility: SKILL_REF_VISIBILITY,\n store: sourceStore(source) === STORE_CROSS_AGENT ? STORE_CROSS_AGENT : null,\n });\n}\n\nfunction realPath(path: string): string | null {\n try {\n return realpathSync(path);\n } catch {\n return null;\n }\n}\n\nfunction normCase(path: string): string {\n const normalized = normalize(path);\n return process.platform === \"win32\" ? normalized.toLowerCase() : normalized;\n}\n\n/**\n * The store folder a linked agent skill folder resolves to, if any. Only the\n * link's target path is resolved; nothing behind it is read. It counts only\n * when it is a direct child of the store root and that child is itself a real\n * folder, so the skill is then read through the store's own path.\n */\nfunction storeMember(link: string, store: Store | null): string | null {\n if (store === null || store.realRoot === null) return null;\n const target = realPath(link);\n if (target === null) return null;\n const name = basename(target);\n if (!name || normCase(dirname(target)) !== normCase(store.realRoot)) return null;\n const member = join(store.source.root, name);\n let info: Stats;\n try {\n info = lstatSync(member);\n } catch {\n return null;\n }\n if (isPathLinkOrReparse(member, info) || !info.isDirectory()) return null;\n return name;\n}\n\n/** Which child folders of a source to read: absent reads every one. */\nexport type SkillFolderFilter = (source: SkillSource, folderName: string) => boolean;\n\nfunction scanStore(\n source: SkillSource,\n report: SkillScanReport,\n wanted: ReadonlySet<string> | null = null,\n): [Store, Found[]] {\n const store: Store = { source, realRoot: null, byFolder: new Map(), byHash: new Map() };\n const found: Found[] = [];\n const children = listSource(source, report);\n if (children === null) return [store, found];\n store.realRoot = realPath(source.root);\n const lock = source.lockFile ? readInstallLock(source.lockFile) : null;\n for (const entry of children) {\n if (entry.name.startsWith(\".\")) continue; // tool-managed (a .git checkout), not a skill\n if (wanted !== null && !wanted.has(entry.name)) continue; // not asked for: not read\n const hint = `${source.label}/${entry.name}`;\n const path = join(source.root, entry.name);\n try {\n if (isPathLinkOrReparse(path)) {\n skip(report, source, hint, \"skill folder is a link; links are not followed\");\n continue;\n }\n if (!entry.isDirectory()) continue;\n } catch {\n skip(report, source, hint, \"skill folder cannot be read\");\n continue;\n }\n const ref = makeRef(source, hint, path, report);\n if (ref === null) continue;\n if (lock !== null) {\n const lockEntry = lock.get(entry.name) ?? lock.get(ref.name);\n ref.origin = originFromLockEntry(lockEntry);\n }\n const item: Found = { source, folder: entry.name, ref, represents: null, represented: false };\n found.push(item);\n store.byFolder.set(entry.name, item);\n if (!store.byHash.has(ref.content_sha256)) store.byHash.set(ref.content_sha256, item);\n }\n return [store, found];\n}\n\nfunction scanAgentDir(\n source: SkillSource,\n report: SkillScanReport,\n store: Store | null,\n include: SkillFolderFilter | null = null,\n): Found[] {\n const found: Found[] = [];\n const children = listSource(source, report);\n if (children === null) return found;\n for (const entry of children) {\n if (entry.name.startsWith(\".\")) continue; // agent-managed (bundled) skills, not the user's\n if (include !== null && !include(source, entry.name)) continue; // not asked for: not read\n const hint = `${source.label}/${entry.name}`;\n const path = join(source.root, entry.name);\n let isLink: boolean;\n try {\n isLink = isPathLinkOrReparse(path);\n if (!isLink && !entry.isDirectory()) continue; // a loose file beside the skill folders\n } catch {\n skip(report, source, hint, \"skill folder cannot be read\");\n continue;\n }\n if (isLink) {\n const member = storeMember(path, store);\n if (store === null || member === null) {\n skip(report, source, hint, \"skill folder is a link; links are not followed\");\n continue;\n }\n const shared = store.byFolder.get(member);\n if (shared === undefined) {\n skip(report, source, hint, \"skill folder links to a cross-agent skill that is not advertised\");\n continue;\n }\n if (codePointLength(hint) > MAX_PATH_HINT_CHARS) {\n skip(report, source, codePointSlice(hint, MAX_PATH_HINT_CHARS), \"path is too long\");\n continue;\n }\n const linked = makeSkillRef({\n ...shared.ref,\n scope: source.scope,\n project: source.project ?? null,\n path_hint: hint,\n store: null,\n also_in: { path_hint: shared.ref.path_hint, via: VIA_LINK },\n });\n found.push({ source, folder: entry.name, ref: linked, represents: shared, represented: false });\n continue;\n }\n const ref = makeRef(source, hint, path, report);\n if (ref === null) continue;\n const copy = store !== null ? (store.byHash.get(ref.content_sha256) ?? null) : null;\n let advertised = ref;\n if (copy !== null) {\n advertised = makeSkillRef({\n ...ref,\n also_in: { path_hint: copy.ref.path_hint, via: VIA_COPY },\n origin: copy.ref.origin ?? null,\n });\n }\n found.push({ source, folder: entry.name, ref: advertised, represents: copy, represented: false });\n }\n return found;\n}\n\nfunction childNames(root: string): string[] {\n try {\n return readdirSync(root);\n } catch {\n return [];\n }\n}\n\n/**\n * Store folders that an included agent folder links to. Only link targets are\n * resolved (no skill file is read), so a link the caller asked for is still\n * read through the store's own folder.\n */\nfunction linkedStoreMembers(\n storeSource: SkillSource,\n agentSources: readonly SkillSource[],\n include: SkillFolderFilter,\n): Set<string> {\n const members = new Set<string>();\n const realRoot = realPath(storeSource.root);\n if (realRoot === null) return members;\n for (const source of agentSources) {\n if (\n source.scope !== storeSource.scope ||\n (source.project ?? null) !== (storeSource.project ?? null)\n ) {\n continue;\n }\n for (const name of childNames(source.root)) {\n if (name.startsWith(\".\") || !include(source, name)) continue;\n const path = join(source.root, name);\n let target: string | null;\n try {\n if (!isPathLinkOrReparse(path)) continue;\n target = realPath(path);\n } catch {\n continue;\n }\n if (target === null) continue;\n const member = basename(target);\n if (member && normCase(dirname(target)) === normCase(realRoot)) members.add(member);\n }\n }\n return members;\n}\n\nexport interface ScanSkillSourcesOptions {\n /**\n * Limits the scan to the child folders it accepts; every other folder is\n * passed over unread. A store folder that an accepted agent folder links to\n * is read too, so the link resolves as in a full scan. An accepted agent\n * folder that is a copy of a store folder the scan did not read carries no\n * `also_in`.\n */\n include?: SkillFolderFilter | null;\n}\n\n/**\n * Index every source; one ref per skill, first occurrence of a name wins per\n * store and scope. Cross-agent stores are scanned first so the agent's own\n * folders can be matched against them (`also_in`). Refs come back with the\n * agent's own folders first, in source order, then the cross-agent store\n * skills that no advertised agent folder already represents.\n */\nexport function scanSkillSources(\n sources: Iterable<SkillSource>,\n options: ScanSkillSourcesOptions = {},\n): SkillScanReport {\n const include = options.include ?? null;\n const ordered = [...sources];\n const report: SkillScanReport = { refs: [], skipped: [] };\n const stores = new Map<string, Store>();\n const perSource = new Map<number, Found[]>();\n const storeKey = (source: SkillSource): string =>\n JSON.stringify([source.scope, source.project ?? null]);\n const agentSources = ordered.filter((source) => sourceStore(source) !== STORE_CROSS_AGENT);\n\n ordered.forEach((source, index) => {\n if (sourceStore(source) !== STORE_CROSS_AGENT) return;\n const key = storeKey(source);\n if (stores.has(key)) return; // one store per scope; a repeat would only duplicate it\n let wanted: Set<string> | null = null;\n if (include !== null) {\n wanted = linkedStoreMembers(source, agentSources, include);\n for (const name of childNames(source.root)) {\n if (include(source, name)) wanted.add(name);\n }\n }\n const [store, found] = scanStore(source, report, wanted);\n stores.set(key, store);\n perSource.set(index, found);\n });\n ordered.forEach((source, index) => {\n if (sourceStore(source) === STORE_CROSS_AGENT) return;\n perSource.set(\n index,\n scanAgentDir(source, report, stores.get(storeKey(source)) ?? null, include),\n );\n });\n\n const seen = new Map<string, string>();\n const indexed = ordered.map((source, index) => [index, source] as const);\n const agentFirst = [\n ...indexed.filter(([, source]) => sourceStore(source) !== STORE_CROSS_AGENT),\n ...indexed.filter(([, source]) => sourceStore(source) === STORE_CROSS_AGENT),\n ];\n for (const [index, source] of agentFirst) {\n for (const item of perSource.get(index) ?? []) {\n if (item.represented) continue;\n const ref = item.ref;\n const nameKey = JSON.stringify([\n ref.store ?? STORE_AGENT,\n ref.scope,\n ref.project ?? null,\n ref.name,\n ]);\n const advertisedAt = seen.get(nameKey);\n if (advertisedAt !== undefined) {\n skip(\n report,\n source,\n ref.path_hint,\n `duplicate skill name '${ref.name}' (advertised: ${advertisedAt})`,\n );\n continue;\n }\n if (report.refs.length >= MAX_SKILL_REFS) {\n skip(report, source, ref.path_hint, `more than ${MAX_SKILL_REFS} skills`);\n continue;\n }\n seen.set(nameKey, ref.path_hint);\n report.refs.push(ref);\n if (item.represents !== null) item.represents.represented = true;\n }\n }\n return report;\n}\n\n/** A participant that advertises skills (plan 005). */\nexport interface SkillAdvertiser {\n agentId: string;\n exportSkills(): SkillRefModel[];\n /**\n * Whether the participant was built with explicit `skillSources`, which\n * lists every skill in them ({@link skillsListingMode}). Absent = no.\n */\n hasExplicitSkillSources?(): boolean;\n /**\n * The directories the reader indexes. When present, the default\n * (approved-only) mode reads just the approved folders in them; without it\n * the reader's own scan runs and only approved refs are kept.\n */\n skillSources?(): SkillSource[];\n}\n\nfunction perAgentOff(agentId: string): boolean {\n const quiet = process.env[SKILLS_NO_ADVERTISE_ENV] ?? \"\";\n const names = new Set(\n pyStrip(quiet.replaceAll(\",\", \" \"))\n .split(PY_WHITESPACE_RUN)\n .map((item) => pyStrip(item).toLowerCase())\n .filter((item) => item !== \"\"),\n );\n return names.has(pyStrip(agentId).toLowerCase());\n}\n\n/**\n * Which skills the participant `agentId` may list in its manifest.\n *\n * - {@link LIST_APPROVED}: {@link SKILLS_ADVERTISE_ENV} unset or empty: only\n * the skills approved one by one (`bourdon skills share`) whose folder still\n * hashes to the approved content.\n * - {@link LIST_ALL}: an on value; or, while the variable is unset, a\n * participant built with explicit `skillSources` (the caller chose what to\n * index).\n * - {@link LIST_OFF}: an off value, or any unrecognised one (fail closed):\n * nothing is listed, approved or not.\n *\n * {@link SKILLS_NO_ADVERTISE_ENV} turns named participants off in every mode.\n */\nexport function skillsListingMode(\n agentId: string,\n options: { explicitSources?: boolean } = {},\n): SkillsListingMode {\n const raw = process.env[SKILLS_ADVERTISE_ENV];\n const value = pyStrip(raw ?? \"\").toLowerCase();\n let mode: SkillsListingMode;\n if (ADVERTISE_ON.has(value)) {\n mode = LIST_ALL;\n } else if (value === \"\") {\n mode = options.explicitSources ? LIST_ALL : LIST_APPROVED;\n } else {\n if (!ADVERTISE_OFF.has(value)) {\n warn(\n `${SKILLS_ADVERTISE_ENV}=${JSON.stringify(raw)} is not a recognised on/off value; ` +\n \"not listing skills\",\n );\n }\n return LIST_OFF;\n }\n return perAgentOff(agentId) ? LIST_OFF : mode;\n}\n\n/**\n * Whether the participant `agentId` lists every skill it can see: true only\n * in {@link LIST_ALL} mode ({@link skillsListingMode}). In the default mode a\n * participant lists only the skills shared one by one.\n */\nexport function skillsAdvertisingEnabled(\n agentId: string,\n options: { explicitSources?: boolean } = {},\n): boolean {\n return skillsListingMode(agentId, options) === LIST_ALL;\n}\n\n/**\n * Approved-only mode: the participant's skills that hold a current approval.\n * Reads only the approved folders (and a store folder an approved link points\n * at); with nothing approved, nothing is read.\n */\nfunction sharedRefs(participant: SkillAdvertiser, agentId: string): SkillRefModel[] {\n const shares = loadShares().filter((share) => shareAppliesTo(share, agentId));\n if (shares.length === 0) return [];\n const approved = new Set(\n shares.map((s) => JSON.stringify([s.scope, s.project, s.pathHint, s.contentSha256])),\n );\n const hints = new Set(shares.map((s) => JSON.stringify([s.scope, s.project, s.pathHint])));\n let refs: SkillRefModel[];\n if (typeof participant.skillSources === \"function\") {\n const include: SkillFolderFilter = (source, name) =>\n hints.has(JSON.stringify([source.scope, source.project ?? null, `${source.label}/${name}`]));\n refs = scanSkillSources(participant.skillSources(), { include }).refs;\n } else {\n // A reader without skill sources: its own scan, approved refs kept.\n refs = [...participant.exportSkills()];\n }\n return refs.filter((ref) =>\n approved.has(\n JSON.stringify([ref.scope, ref.project ?? null, ref.path_hint, ref.content_sha256]),\n ),\n );\n}\n\n/**\n * The refs `participant`'s manifest carries, for `exportL5`.\n *\n * Follows {@link skillsListingMode}: nothing, and no skill directory read,\n * when off; by default only the skills with a current approval, reading only\n * their folders; every skill the reader sees when listing all. A participant\n * built with explicit `skillSources` lists all unless turned off. A failure\n * here never fails an export: skills are an addition to the manifest, not a\n * reason to lose its memory rows. Private refs are dropped, as private\n * entities are.\n */\nexport function advertisedSkills(participant: SkillAdvertiser): SkillRefModel[] {\n const agentId = String(participant.agentId ?? \"\");\n const explicitSources = participant.hasExplicitSkillSources?.() === true;\n const mode = skillsListingMode(agentId, { explicitSources });\n if (mode === LIST_OFF) return [];\n let refs: SkillRefModel[];\n try {\n refs = mode === LIST_APPROVED ? sharedRefs(participant, agentId) : [...participant.exportSkills()];\n } catch (err) {\n warn(`skill readers: ${agentId} skipped skill export: ${String(err)}`);\n return [];\n }\n return refs.filter((ref) => ref.visibility !== Visibility.PRIVATE);\n}\n\n// -- proposal side: back from an advertised ref to its folder -----------------\n\n/**\n * The default skill directories of a built-in skill-reading participant.\n *\n * The same directories the participant's own export reads (its user-level\n * directory honouring its home override, the opted-in projects, and the\n * cross-agent store). `null` for an agent with no skill reader here, so a skill\n * it advertises can be listed but not proposed from this machine.\n */\nexport function skillSourcesForAgent(agentId: string): SkillSource[] | null {\n const builders: Record<string, () => SkillSource[]> = {\n \"claude-code\": () => claudeCodeSkillSources(),\n codex: () => codexSkillSources(),\n cursor: () => cursorSkillSources(),\n };\n const build = Object.hasOwn(builders, agentId) ? builders[agentId] : undefined;\n if (build === undefined) return null;\n return [...build(), ...crossAgentSkillSources()];\n}\n\nfunction folderForHint(\n sources: readonly SkillSource[],\n pathHint: string,\n scope: unknown,\n project: unknown,\n): string | null {\n for (const source of sources) {\n if (source.scope !== scope || (source.project ?? null) !== (project ?? null)) continue;\n const prefix = `${source.label}/`;\n if (!pathHint.startsWith(prefix)) continue;\n const folder = pathHint.slice(prefix.length);\n if (\n !folder ||\n folder === \".\" ||\n folder === \"..\" ||\n folder.includes(\"/\") ||\n folder.includes(\"\\\\\")\n ) {\n return null;\n }\n return join(source.root, folder);\n }\n return null;\n}\n\n/**\n * The folder an advertised ref was scanned from, found through `sources` only.\n *\n * `ref` is a SkillRef as it sits in a manifest. Its `path_hint` is matched\n * against each source's symbolic label (same scope and project), so the result\n * is always one direct child of a directory the reader indexes; a path from\n * anywhere else cannot be produced. A ref that is a link into the cross-agent\n * store resolves to the store's own folder, as the reader read it. `null` when\n * nothing matches.\n */\nexport function resolveAdvertisedFolder(\n sources: readonly SkillSource[],\n ref: Readonly<Record<string, unknown>>,\n): string | null {\n const hint = ref.path_hint;\n if (typeof hint !== \"string\") return null;\n const scope = ref.scope;\n const project = ref.project;\n const alsoIn = ref.also_in;\n const isCrossAgent = (s: SkillSource): boolean => s.store === STORE_CROSS_AGENT;\n if (isDict(alsoIn) && alsoIn.via === VIA_LINK) {\n const storeHint = alsoIn.path_hint;\n if (typeof storeHint !== \"string\") return null;\n return folderForHint(sources.filter(isCrossAgent), storeHint, scope, project);\n }\n const chosen =\n ref.store === STORE_CROSS_AGENT\n ? sources.filter(isCrossAgent)\n : sources.filter((s) => !isCrossAgent(s));\n return folderForHint(chosen, hint, scope, project);\n}\n\n// -- the local share commands: what this machine's readers can see -------------\n\n/** The built-in skill readers, in listing order. */\nexport const SKILL_READERS = [\"claude-code\", \"codex\", \"cursor\"] as const;\n\n/**\n * One skill folder a built-in reader sees, for `bourdon skills available|share`.\n *\n * `agent` is the reader that owns the folder, or `null` for a cross-agent\n * store folder; `agents` names every reader that sees it. Local use only:\n * `folder` is an absolute path and never leaves the terminal command that\n * asked for it.\n */\nexport interface LocalSkill {\n ref: SkillRefModel;\n agent: string | null;\n agents: string[];\n folder: string;\n /** `agent` or `cross_agent`. */\n store: string;\n}\n\n/**\n * Every skill folder the built-in readers see on this machine (each one is\n * read). The same directories the readers' exports use: user-level, opted-in\n * projects and the cross-agent store. One row per folder; a store folder seen\n * by several readers is one row naming them all. `agent` keeps the folders\n * that one reader sees.\n */\nexport function localSkills(agent: string | null = null): LocalSkill[] {\n const rows = new Map<string, LocalSkill>();\n for (const reader of SKILL_READERS) {\n if (agent !== null && reader !== agent) continue;\n const sources = skillSourcesForAgent(reader) ?? [];\n for (const ref of scanSkillSources(sources).refs) {\n const owner = ref.store === STORE_CROSS_AGENT ? null : reader;\n const store = ref.store || STORE_AGENT;\n const key = JSON.stringify([owner, store, ref.scope, ref.project ?? null, ref.path_hint]);\n const row = rows.get(key);\n if (row !== undefined) {\n if (!row.agents.includes(reader)) row.agents.push(reader);\n continue;\n }\n const alsoIn = ref.also_in\n ? { path_hint: ref.also_in.path_hint, via: ref.also_in.via }\n : null;\n const folder = resolveAdvertisedFolder(sources, {\n path_hint: ref.path_hint,\n scope: ref.scope,\n project: ref.project ?? null,\n store: ref.store ?? null,\n also_in: alsoIn,\n });\n if (folder !== null) rows.set(key, { ref, agent: owner, agents: [reader], folder, store });\n }\n }\n return [...rows.values()];\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Reader-side skill folder scan (plan 005). Port of the parts of the engine's\n * `core/skill_index.py` a participant needs to advertise a local skill: the\n * text-only content rules, the no-follow folder walk, front-matter parsing,\n * the `content_sha256` framing and `scan_local_skill` (skip and flag).\n *\n * `readSkillFolder` is the promotion-side twin of `scanLocalSkill`: it refuses\n * a folder that breaks any rule instead of skipping files. The library-level\n * shared store (index rows, versions, promotion) is in `skill-store.ts`. Both\n * use the same limits and name rule, so a hash computed here compares\n * directly with a shared skill's.\n *\n * Rules a v1 shared skill must meet (anything else is skipped and flagged):\n * - `SKILL.md` plus markdown, plain text and template files only;\n * - no links, no hidden entries, bounded depth and path length, no paths that\n * differ only in case;\n * - UTF-8 text without NUL bytes, no interpreter line, no credential-like text;\n * - per-file and total size caps, at most {@link MAX_REFERENCE_FILES} reference files.\n */\n\nimport { createHash } from \"node:crypto\";\nimport { lstatSync, readdirSync, readFileSync, type Dirent, type Stats } from \"node:fs\";\nimport { basename, join } from \"node:path\";\n\nimport { l5Schema } from \"@getbourdon/l5\";\nimport { containsSecret } from \"@getbourdon/redaction\";\nimport { parse as yamlParse } from \"yaml\";\n\nexport const SKILL_BODY_NAME = \"SKILL.md\";\n\n/** Reference-file types a v1 shared skill may carry: markdown, plain text and templates. */\nexport const TEXT_FILE_SUFFIXES: ReadonlySet<string> = new Set([\n \".md\",\n \".markdown\",\n \".txt\",\n \".tmpl\",\n \".tpl\",\n \".template\",\n \".j2\",\n \".jinja\",\n \".jinja2\",\n \".mustache\",\n]);\n\nexport const MAX_SKILL_BODY_BYTES = 128 * 1024;\nexport const MAX_REFERENCE_FILE_BYTES = 256 * 1024;\nexport const MAX_REFERENCE_FILES = 64;\nexport const MAX_SKILL_TOTAL_BYTES = 2 * 1024 * 1024;\nconst MAX_PATH_DEPTH = 8;\nconst MAX_REL_PATH_CHARS = 255;\nconst FRONT_MATTER_FENCE = \"---\";\n\n/**\n * Why a reader left a file out of an advertised skill. `limit` means the\n * file-count or total-size cap was reached; every other code names the content\n * rule the file breaks.\n */\nexport const SKIP_REASONS: ReadonlySet<string> = new Set([\n \"credential\",\n \"duplicate_case\",\n \"file_type\",\n \"hidden\",\n \"limit\",\n \"link\",\n \"not_text\",\n \"path\",\n \"script\",\n \"too_large\",\n \"unreadable\",\n]);\n\ninterface SchemaNode {\n [key: string]: unknown;\n properties?: Record<string, SchemaNode>;\n pattern?: string;\n maxLength?: number;\n}\n\n// The skill name and description rules, read from the L5 schema's SkillRef\n// (the same values as the shared skill index schema's).\nfunction skillRefProp(name: string): SchemaNode {\n const skillRef = (l5Schema.$defs as Record<string, SchemaNode | undefined>).SkillRef;\n const found = skillRef?.properties?.[name];\n if (found === undefined) throw new Error(`L5 schema: SkillRef is missing ${name}`);\n return found;\n}\n\nconst NAME_PATTERN = String(skillRefProp(\"name\").pattern);\nconst NAME_RE = new RegExp(`^(?:${NAME_PATTERN})$`);\nconst NAME_MAX = Number(skillRefProp(\"name\").maxLength);\nconst DESCRIPTION_MAX = Number(skillRefProp(\"description\").maxLength);\n/** Longest skill name, in code points. */\nexport const SKILL_NAME_MAX = NAME_MAX;\n/** Longest front-matter description, in code points. */\nexport const SKILL_DESCRIPTION_MAX = DESCRIPTION_MAX;\n\n// -- errors -------------------------------------------------------------------\n\n/**\n * A skill folder cannot be advertised (or shared) as it stands. `problems`\n * lists every offending path with the reason; content is never echoed back.\n */\nexport class SkillContentError extends Error {\n readonly problems: string[];\n\n constructor(problems: string[]) {\n super(`skill folder cannot be shared: ${problems.join(\"; \")}`);\n this.name = \"SkillContentError\";\n this.problems = [...problems];\n }\n}\n\n// -- Python string semantics ----------------------------------------------------\n\n// str.isspace() characters, for str.strip().\nconst PY_SPACE =\n \"\\\\t\\\\n\\\\v\\\\f\\\\r\\\\x1c-\\\\x1f \\\\x85\\\\xa0\\\\u1680\\\\u2000-\\\\u200a\\\\u2028\\\\u2029\\\\u202f\\\\u205f\\\\u3000\";\nconst PY_STRIP_RE = new RegExp(`^[${PY_SPACE}]+|[${PY_SPACE}]+$`, \"g\");\n// str.splitlines() boundaries.\n// eslint-disable-next-line no-control-regex\nconst PY_LINE_BREAK_RE = /\\r\\n|[\\n\\r\\v\\f\\x1c\\x1d\\x1e\\x85\\u2028\\u2029]/;\n\n/** Python `str.strip()` with no argument. */\nexport function pyStrip(text: string): string {\n return text.replace(PY_STRIP_RE, \"\");\n}\n\n/** Length in code points, as Python's `len(str)`. */\nexport function codePointLength(text: string): number {\n let n = 0;\n for (const _ of text) n += 1;\n return n;\n}\n\n/** The first `limit` code points, as Python's `text[:limit]`. */\nexport function codePointSlice(text: string, limit: number): string {\n if (text.length <= limit) return text;\n return Array.from(text).slice(0, limit).join(\"\");\n}\n\n/** Approximates Python `str.casefold()` (full case folding, e.g. ß -> ss). */\nfunction casefold(text: string): string {\n return text.toUpperCase().toLowerCase();\n}\n\n/** Code-point order (Python's str order), via the UTF-8 bytes. */\nexport function compareUtf8(a: string, b: string): number {\n return Buffer.compare(Buffer.from(a, \"utf8\"), Buffer.from(b, \"utf8\"));\n}\n\nconst UTF8 = new TextDecoder(\"utf-8\", { fatal: true, ignoreBOM: true });\n\nfunction decodeUtf8(data: Uint8Array): string | null {\n try {\n return UTF8.decode(data);\n } catch {\n return null;\n }\n}\n\n/** Whether `path` is a symbolic link (on Windows, a junction or symlink reparse point). */\nexport function isPathLinkOrReparse(path: string, stats?: Stats): boolean {\n const inspected = stats ?? lstatSync(path);\n return inspected.isSymbolicLink();\n}\n\n// -- front matter -------------------------------------------------------------\n\nexport interface SkillFrontMatter {\n name: string;\n description: string;\n}\n\n/** Why `value` is not a valid skill name (`label` names the field), or null. */\nexport function skillNameError(value: unknown, label = \"name\"): string | null {\n if (typeof value !== \"string\") return `${label} must be a string`;\n const length = codePointLength(value);\n if (length < 1 || length > NAME_MAX) return `${label} must be 1..${NAME_MAX} characters`;\n if (!NAME_RE.test(value)) return `${label} must match ${NAME_PATTERN}`;\n return null;\n}\n\n/** Extract `name` and `description` from a `SKILL.md` body. Throws {@link SkillContentError}. */\nexport function parseFrontMatter(body: Uint8Array | string): SkillFrontMatter {\n let text: string;\n if (typeof body === \"string\") {\n text = body;\n } else {\n const decoded = decodeUtf8(body);\n if (decoded === null) throw new SkillContentError([`${SKILL_BODY_NAME}: not UTF-8 text`]);\n text = decoded;\n }\n if (text.startsWith(\"\\ufeff\")) text = text.slice(1);\n const lines = text.split(PY_LINE_BREAK_RE);\n if (lines.length === 0 || pyStrip(lines[0] ?? \"\") !== FRONT_MATTER_FENCE) {\n throw new SkillContentError([`${SKILL_BODY_NAME}: missing YAML front matter`]);\n }\n let end = -1;\n for (let i = 1; i < lines.length; i++) {\n if (pyStrip(lines[i] ?? \"\") === FRONT_MATTER_FENCE) {\n end = i;\n break;\n }\n }\n if (end === -1) throw new SkillContentError([`${SKILL_BODY_NAME}: front matter is not closed`]);\n let meta: unknown;\n try {\n meta = yamlParse(lines.slice(1, end).join(\"\\n\"), {\n version: \"1.1\",\n uniqueKeys: false,\n logLevel: \"silent\",\n });\n } catch {\n throw new SkillContentError([`${SKILL_BODY_NAME}: front matter is not valid YAML`]);\n }\n if (meta === null || typeof meta !== \"object\" || Array.isArray(meta) || meta instanceof Date) {\n throw new SkillContentError([`${SKILL_BODY_NAME}: front matter must be a mapping`]);\n }\n const record = meta as Record<string, unknown>;\n const problems: string[] = [];\n const name = record.name;\n const error = skillNameError(name);\n if (error !== null) problems.push(`${SKILL_BODY_NAME}: front matter ${error}`);\n let description = record.description;\n if (typeof description === \"string\") description = pyStrip(description);\n if (\n typeof description !== \"string\" ||\n codePointLength(description) < 1 ||\n codePointLength(description) > DESCRIPTION_MAX\n ) {\n problems.push(\n `${SKILL_BODY_NAME}: front matter description must be 1..${DESCRIPTION_MAX} characters`,\n );\n }\n if (problems.length > 0) throw new SkillContentError(problems);\n return { name: name as string, description: description as string };\n}\n\n// -- content hash -------------------------------------------------------------\n\n/**\n * Hash a skill's files as the schema's `content_sha256` defines: entries sorted\n * by the UTF-8 bytes of their POSIX path relative to the skill folder, each\n * framed as `path \\0 len(bytes) \\0 bytes`.\n */\nexport function computeContentSha256(entries: Iterable<readonly [string, Uint8Array]>): string {\n const digest = createHash(\"sha256\");\n const sorted = [...entries].sort(([a], [b]) => compareUtf8(a, b));\n for (const [path, data] of sorted) {\n digest.update(Buffer.from(path, \"utf8\"));\n digest.update(Buffer.from([0]));\n digest.update(Buffer.from(String(data.length), \"ascii\"));\n digest.update(Buffer.from([0]));\n digest.update(data);\n }\n return digest.digest(\"hex\");\n}\n\n// -- folder walk ----------------------------------------------------------------\n\n/** `[reason code, message]` for one text rule a file breaks. */\ntype TextProblem = readonly [string, string];\n\nfunction textProblems(data: Uint8Array): TextProblem[] {\n const text = decodeUtf8(data);\n if (text === null) return [[\"not_text\", \"not UTF-8 text\"]];\n if (text.includes(\"\\x00\")) return [[\"not_text\", \"contains NUL bytes\"]];\n const found: TextProblem[] = [];\n const unprefixed = text.startsWith(\"\\ufeff\") ? text.slice(1) : text;\n if (unprefixed.startsWith(\"#!\")) {\n found.push([\"script\", \"starts with an interpreter line; scripts are not shared\"]);\n }\n if (containsSecret(text)) found.push([\"credential\", \"contains credential-like text\"]);\n return found;\n}\n\ninterface WalkFound {\n rel: string;\n path: string;\n size: number;\n}\n\ninterface WalkProblem {\n rel: string;\n code: string;\n message: string;\n}\n\n/**\n * List a skill folder's regular files without following any link. `found` holds\n * every regular file that passed the structural rules; `problems` names every\n * entry that did not.\n */\nfunction walkSkillFolder(root: string): { found: WalkFound[]; problems: WalkProblem[] } {\n const problems: WalkProblem[] = [];\n const found: WalkFound[] = [];\n const seenCasefold = new Map<string, string>();\n\n const walk = (directory: string, parts: string[]): void => {\n let entries: Dirent[];\n try {\n entries = readdirSync(directory, { withFileTypes: true });\n } catch {\n problems.push({ rel: parts.join(\"/\") || \".\", code: \"unreadable\", message: \"cannot be listed\" });\n return;\n }\n entries.sort((a, b) => compareUtf8(a.name, b.name));\n for (const entry of entries) {\n const relParts = [...parts, entry.name];\n const rel = relParts.join(\"/\");\n const path = join(directory, entry.name);\n let info: Stats;\n try {\n info = lstatSync(path);\n } catch {\n problems.push({ rel, code: \"unreadable\", message: \"cannot be read\" });\n continue;\n }\n if (isPathLinkOrReparse(path, info)) {\n problems.push({ rel, code: \"link\", message: \"links are not shared\" });\n continue;\n }\n if (entry.name.startsWith(\".\")) {\n problems.push({ rel, code: \"hidden\", message: \"hidden files and folders are not shared\" });\n continue;\n }\n if (relParts.length > MAX_PATH_DEPTH || codePointLength(rel) > MAX_REL_PATH_CHARS) {\n problems.push({ rel, code: \"path\", message: \"path is too deep or too long\" });\n continue;\n }\n const folded = casefold(rel);\n const previous = seenCasefold.get(folded);\n if (previous !== undefined) {\n problems.push({\n rel,\n code: \"duplicate_case\",\n message: `differs only in case from ${previous}`,\n });\n continue;\n }\n seenCasefold.set(folded, rel);\n if (info.isDirectory()) {\n walk(path, relParts);\n } else if (info.isFile()) {\n found.push({ rel, path, size: info.size });\n } else {\n problems.push({ rel, code: \"file_type\", message: \"not a regular file\" });\n }\n }\n };\n\n walk(root, []);\n return { found, problems };\n}\n\n/** Python `PurePosixPath(rel).suffix`. */\nfunction posixSuffix(rel: string): string {\n const name = rel.slice(rel.lastIndexOf(\"/\") + 1);\n const i = name.lastIndexOf(\".\");\n return i > 0 && i < name.length - 1 ? name.slice(i) : \"\";\n}\n\n/**\n * Read one listed file under the type and size rules, then check its text.\n * `data` is null when the file is refused before reading.\n */\nfunction readCandidate(\n rel: string,\n path: string,\n size: number,\n): { data: Uint8Array | null; problems: TextProblem[] } {\n const isBody = rel === SKILL_BODY_NAME;\n if (!isBody && !TEXT_FILE_SUFFIXES.has(posixSuffix(rel).toLowerCase())) {\n return {\n data: null,\n problems: [\n [\"file_type\", \"file type is not shared in v1 (markdown, text and templates only)\"],\n ],\n };\n }\n const cap = isBody ? MAX_SKILL_BODY_BYTES : MAX_REFERENCE_FILE_BYTES;\n if (size > cap) {\n return { data: null, problems: [[\"too_large\", `${size} bytes exceeds the ${cap}-byte limit`]] };\n }\n let data: Uint8Array;\n try {\n data = readFileSync(path);\n } catch {\n return { data: null, problems: [[\"unreadable\", \"cannot be read\"]] };\n }\n if (data.length > cap) {\n return {\n data: null,\n problems: [[\"too_large\", `${data.length} bytes exceeds the ${cap}-byte limit`]],\n };\n }\n return { data, problems: textProblems(data) };\n}\n\n// -- reader-side scan -----------------------------------------------------------\n\n/** One file a reader left out of a local skill, and why (a {@link SKIP_REASONS} code). */\nexport interface SkippedFile {\n path: string;\n reason: string;\n}\n\n/**\n * What a participant reader can advertise about one local skill folder. `files`\n * is the shareable part (`SKILL.md` plus every reference file that passes the\n * v1 content rules); `skipped` lists the rest. The hash covers `files` only.\n */\nexport interface LocalSkillScan {\n frontMatter: SkillFrontMatter;\n files: ReadonlyArray<readonly [string, Uint8Array]>;\n skipped: readonly SkippedFile[];\n contentSha256: string;\n}\n\nfunction isRealDirectory(path: string): boolean {\n let info: Stats;\n try {\n info = lstatSync(path);\n } catch {\n return false;\n }\n return !isPathLinkOrReparse(path, info) && info.isDirectory();\n}\n\n/**\n * Scan one local skill folder for discovery: skip and flag, don't refuse.\n *\n * A disallowed reference file (a script, a binary, a link, a hidden file,\n * credential-like text) is left out and reported in `skipped` instead of making\n * the whole skill disappear. Only a `SKILL.md` that is missing, unreadable or\n * itself breaks a content rule throws {@link SkillContentError}, because then\n * there is nothing safe to advertise. Nothing is followed through a link and\n * nothing is modified.\n */\nexport function scanLocalSkill(folder: string): LocalSkillScan {\n if (!isRealDirectory(folder)) {\n throw new SkillContentError([`${basename(folder) || folder}: not a real directory`]);\n }\n const { found, problems } = walkSkillFolder(folder);\n const skipped: SkippedFile[] = problems.map((p) => ({ path: p.rel, reason: p.code }));\n\n const bodyEntry = found.find((item) => item.rel === SKILL_BODY_NAME);\n if (bodyEntry === undefined) throw new SkillContentError([`${SKILL_BODY_NAME}: missing`]);\n const body = readCandidate(bodyEntry.rel, bodyEntry.path, bodyEntry.size);\n if (body.data === null || body.problems.length > 0) {\n throw new SkillContentError(body.problems.map(([, message]) => `${SKILL_BODY_NAME}: ${message}`));\n }\n const frontMatter = parseFrontMatter(body.data);\n\n const files: Array<readonly [string, Uint8Array]> = [[SKILL_BODY_NAME, body.data]];\n let total = body.data.length;\n for (const { rel, path, size } of found) {\n if (rel === SKILL_BODY_NAME) continue;\n if (files.length - 1 >= MAX_REFERENCE_FILES) {\n skipped.push({ path: rel, reason: \"limit\" });\n continue;\n }\n const candidate = readCandidate(rel, path, size);\n if (candidate.data === null || candidate.problems.length > 0) {\n skipped.push({ path: rel, reason: candidate.problems[0]?.[0] ?? \"unreadable\" });\n continue;\n }\n if (total + candidate.data.length > MAX_SKILL_TOTAL_BYTES) {\n skipped.push({ path: rel, reason: \"limit\" });\n continue;\n }\n total += candidate.data.length;\n files.push([rel, candidate.data]);\n }\n\n files.sort(([a], [b]) => compareUtf8(a, b));\n skipped.sort((a, b) => compareUtf8(a.path, b.path));\n return { frontMatter, files, skipped, contentSha256: computeContentSha256(files) };\n}\n\n// -- promotion-side read --------------------------------------------------------\n\n/** A validated skill: front matter plus every file, `SKILL.md` included, sorted by path. */\nexport interface SkillContent {\n frontMatter: SkillFrontMatter;\n files: ReadonlyArray<readonly [string, Uint8Array]>;\n}\n\n/** The `SKILL.md` bytes of `content`. */\nexport function skillContentBody(content: SkillContent): Uint8Array {\n const body = content.files.find(([rel]) => rel === SKILL_BODY_NAME);\n if (body === undefined) throw new SkillContentError([`${SKILL_BODY_NAME}: missing`]);\n return body[1];\n}\n\n/**\n * Read a skill folder and enforce every v1 content rule (the oracle's\n * `read_skill_folder`). Throws {@link SkillContentError} listing every problem\n * found. The folder is read in place and never modified; links are reported,\n * never followed.\n */\nexport function readSkillFolder(folder: string): SkillContent {\n if (!isRealDirectory(folder)) {\n throw new SkillContentError([`${basename(folder) || folder}: not a real directory`]);\n }\n const { found, problems: walkProblems } = walkSkillFolder(folder);\n const problems = walkProblems.map((p) => `${p.rel}: ${p.message}`);\n\n if (!found.some((item) => item.rel === SKILL_BODY_NAME)) {\n problems.push(`${SKILL_BODY_NAME}: missing`);\n }\n const references = found.filter((item) => item.rel !== SKILL_BODY_NAME);\n if (references.length > MAX_REFERENCE_FILES) {\n problems.push(\n `${references.length} reference files exceed the limit of ${MAX_REFERENCE_FILES}`,\n );\n }\n\n let total = 0;\n const files: Array<readonly [string, Uint8Array]> = [];\n for (const { rel, path, size } of found) {\n const candidate = readCandidate(rel, path, size);\n for (const [, message] of candidate.problems) problems.push(`${rel}: ${message}`);\n if (candidate.data === null) continue;\n total += candidate.data.length;\n files.push([rel, candidate.data]);\n }\n if (total > MAX_SKILL_TOTAL_BYTES) {\n problems.push(`skill totals ${total} bytes, over the ${MAX_SKILL_TOTAL_BYTES}-byte limit`);\n }\n\n let frontMatter: SkillFrontMatter | null = null;\n const body = files.find(([rel]) => rel === SKILL_BODY_NAME)?.[1];\n if (body !== undefined) {\n try {\n frontMatter = parseFrontMatter(body);\n } catch (err) {\n if (!(err instanceof SkillContentError)) throw err;\n // A body that is not UTF-8 was already reported by the text check.\n if (decodeUtf8(body) !== null) problems.push(...err.problems);\n }\n }\n if (problems.length > 0 || frontMatter === null) {\n throw new SkillContentError(problems.length > 0 ? problems : [`${SKILL_BODY_NAME}: unreadable`]);\n }\n files.sort(([a], [b]) => compareUtf8(a, b));\n return { frontMatter, files };\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Per-skill share approvals: which local skills a participant may list. Port\n * of the engine's `core/skill_shares.py`.\n *\n * Like approving a hook, a skill is listed in an agent's L5 manifest only\n * after the person at this machine approves that one skill (`bourdon skills\n * share`). Each approval pins the exact content approved: a skill whose folder\n * has changed since is not listed again until it is re-approved.\n *\n * Layout (interoperable with the engine: either side reads what the other wrote):\n *\n * <library>/.skill-shares.json\n *\n * {\n * \"version\": 1,\n * \"approvals\": [\n * {\n * \"kind\": \"skill\",\n * \"source\": {\n * \"agent\": \"alice\", // null: any reader of a cross-agent store skill\n * \"store\": \"agent\", // \"agent\" | \"cross_agent\"\n * \"scope\": \"user\", // \"user\" | \"project\"\n * \"project\": null, // the project's folder name, for scope \"project\"\n * \"path_hint\": \"~/.alice/skills/release-checklist\"\n * },\n * \"item\": \"release-checklist\",\n * \"content_sha256\": \"<64 hex>\",\n * \"approved_at\": \"2026-10-15T08:00:00Z\",\n * \"actor\": \"operator\"\n * }\n * ]\n * }\n *\n * An approval is identified by `(kind, source, item, content_sha256)`. Only\n * `kind: \"skill\"` is written today; an entry of a kind this version does not\n * know is kept untouched on rewrite (and never treated as an approval).\n * Approving an item again from the same source replaces its earlier approval,\n * so a re-approved edit does not leave the old content approved.\n *\n * Load-bearing rules:\n *\n * - **Local only.** The file sits beside the library's other local state and\n * is never synced: nothing in this package stages a library for the network,\n * and the engine's sync stages only `agents/*.l5.yaml`.\n * - **No absolute paths.** A share names its folder by the reader's symbolic\n * `path_hint` (`~/...`, `$ENV_VAR/...` or project-relative), never by where\n * it sits on disk.\n * - **Corruption means no approvals.** A missing, linked, oversized or\n * unparseable file reads as no shares at all, and a malformed entry is\n * dropped; reading never throws, so an export never fails here.\n * - **Writes are locked** with the same cross-process lock the library's other\n * writers use, and replace the file atomically.\n *\n * Nothing here is reachable over MCP; the terminal commands are the only\n * writers, and they ask the person at the keyboard to confirm.\n */\n\nimport { randomBytes } from \"node:crypto\";\nimport {\n closeSync,\n existsSync,\n fsyncSync,\n lstatSync,\n mkdirSync,\n openSync,\n readFileSync,\n renameSync,\n rmSync,\n statSync,\n writeSync,\n type Stats,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { basename, dirname, join } from \"node:path\";\n\nimport { withManifestLock } from \"@getbourdon/federation\";\n\nimport { codePointLength, isPathLinkOrReparse } from \"./skill-index.js\";\n\nexport const SHARES_FILENAME = \".skill-shares.json\";\nexport const SHARES_VERSION = 1;\n/** The only approval kind written by this version. */\nexport const KIND_SKILL = \"skill\";\n/** Who approved a share. Only the operator's terminal writes this file. */\nexport const SHARE_ACTOR = \"operator\";\n/** A shares file larger than this is not read (it then holds no approvals). */\nexport const MAX_SHARES_BYTES = 4 * 1024 * 1024;\n\nconst STORES: ReadonlySet<string> = new Set([\"agent\", \"cross_agent\"]);\nconst SCOPES: ReadonlySet<string> = new Set([\"user\", \"project\"]);\nconst SHA_RE = /^[0-9a-f]{64}$/;\nconst MAX_FIELD_CHARS = 255;\n\ntype Dict = Record<string, unknown>;\n\n/** A share cannot be recorded (the file is unsafe to write, or the share is invalid). */\nexport class SkillShareError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SkillShareError\";\n }\n}\n\n/** One approval: this skill folder, with exactly this content, may be listed. */\nexport interface SkillShare {\n name: string;\n agent: string | null;\n store: string;\n scope: string;\n project: string | null;\n pathHint: string;\n contentSha256: string;\n approvedAt: string;\n actor: string;\n}\n\n/** The skill folder a share is about, whoever reads it (a comparable key). */\nexport function shareFolderKey(share: SkillShare): string {\n return JSON.stringify([share.store, share.scope, share.project, share.pathHint]);\n}\n\n/** The reader source: the same folder as read by the same reader. */\nexport function shareSourceKey(share: SkillShare): string {\n return JSON.stringify([share.agent, share.store, share.scope, share.project, share.pathHint]);\n}\n\n/** The approval's identity: `(kind, source, item, content_sha256)`. */\nexport function shareKey(share: SkillShare): string {\n return JSON.stringify([\n KIND_SKILL,\n [share.agent, share.store, share.scope, share.project, share.pathHint],\n share.name,\n share.contentSha256,\n ]);\n}\n\n/** What a new approval replaces: the same item from the same source, any content. */\nfunction shareReplaces(share: SkillShare): string {\n return JSON.stringify([\n KIND_SKILL,\n [share.agent, share.store, share.scope, share.project, share.pathHint],\n share.name,\n ]);\n}\n\n/**\n * Whether the participant `agentId` may list the skill under `share`. A share\n * of an agent's own folder applies to that agent; a share of a cross-agent\n * store skill with no `agent` applies to every reader of the store.\n */\nexport function shareAppliesTo(share: SkillShare, agentId: string): boolean {\n return share.agent === null || share.agent === agentId;\n}\n\n/** The on-disk record, in the engine's key order. */\nexport function shareToDict(share: SkillShare): Dict {\n return {\n kind: KIND_SKILL,\n source: {\n agent: share.agent,\n store: share.store,\n scope: share.scope,\n project: share.project,\n path_hint: share.pathHint,\n },\n item: share.name,\n content_sha256: share.contentSha256,\n approved_at: share.approvedAt,\n actor: share.actor,\n };\n}\n\n/**\n * The library whose shares the participants' exports read. Resolved at call\n * time (not import time) so a relocated home is honoured.\n */\nexport function defaultSharesLibrary(): string {\n return join(homedir(), \"agent-library\");\n}\n\nexport function sharesPath(libraryPath?: string | null): string {\n return join(libraryPath ?? defaultSharesLibrary(), SHARES_FILENAME);\n}\n\nfunction nowIso(): string {\n return `${new Date().toISOString().slice(0, 19)}Z`;\n}\n\nfunction isDict(value: unknown): value is Dict {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nclass BadEntry extends Error {}\n\nfunction text(value: unknown, optional = false): string | null {\n if (value === null && optional) return null;\n if (typeof value !== \"string\" || !value || codePointLength(value) > MAX_FIELD_CHARS) {\n throw new BadEntry(\"bad field\");\n }\n return value;\n}\n\n/** One `kind: \"skill\"` entry; throws for anything malformed. */\nfunction shareFrom(data: unknown): SkillShare {\n if (!isDict(data) || data.kind !== KIND_SKILL) throw new BadEntry(\"not a skill approval\");\n const source = data.source;\n if (!isDict(source)) throw new BadEntry(\"no source\");\n const store = source.store;\n const scope = source.scope;\n const sha = data.content_sha256;\n if (\n typeof store !== \"string\" ||\n !STORES.has(store) ||\n typeof scope !== \"string\" ||\n !SCOPES.has(scope)\n ) {\n throw new BadEntry(\"bad store or scope\");\n }\n if (typeof sha !== \"string\" || !SHA_RE.test(sha)) throw new BadEntry(\"bad content hash\");\n const pathHint = text(source.path_hint) as string;\n if (\n pathHint.startsWith(\"/\") ||\n pathHint.startsWith(\"\\\\\") ||\n Array.from(pathHint).slice(0, 3).join(\"\").includes(\":\")\n ) {\n throw new BadEntry(\"absolute path\");\n }\n const agent = text(source.agent ?? null, true);\n if (agent === null && store !== \"cross_agent\") {\n throw new BadEntry(\"an agent's own folder needs its agent\");\n }\n const project = text(source.project ?? null, true);\n if ((scope === \"project\") !== (project !== null)) {\n throw new BadEntry(\"project and scope disagree\");\n }\n return {\n name: text(data.item) as string,\n agent,\n store,\n scope,\n project,\n pathHint,\n contentSha256: sha,\n approvedAt: text(data.approved_at) as string,\n actor: text(data.actor) as string,\n };\n}\n\n/** An entry of an approval kind this version does not write: kept, never used. */\nfunction isOtherKind(item: unknown): boolean {\n const kind = isDict(item) ? item.kind : undefined;\n return typeof kind === \"string\" && kind !== KIND_SKILL;\n}\n\nfunction warn(message: string): void {\n console.warn(`[bourdon.participants] ${message}`);\n}\n\nconst STRICT_UTF8 = new TextDecoder(\"utf-8\", { fatal: true, ignoreBOM: true });\n\n/** The `approvals` list, or `null` when the file is missing or cannot be trusted. */\nfunction readRaw(path: string): unknown[] | null {\n let info: Stats;\n try {\n info = lstatSync(path);\n } catch (exc) {\n if ((exc as NodeJS.ErrnoException).code !== \"ENOENT\") {\n warn(`skill shares: ${SHARES_FILENAME} cannot be read; listing no skills`);\n }\n return null;\n }\n try {\n if (isPathLinkOrReparse(path, info) || !info.isFile()) throw new BadEntry(\"not a regular file\");\n if (info.size > MAX_SHARES_BYTES) throw new BadEntry(\"too large\");\n const data: unknown = JSON.parse(STRICT_UTF8.decode(readFileSync(path)));\n // Python's `!=`: `1.0` and `true` equal 1 there as well.\n if (!isDict(data) || (data.version !== SHARES_VERSION && data.version !== true)) {\n throw new BadEntry(\"unknown layout\");\n }\n const approvals = data.approvals;\n if (!Array.isArray(approvals)) throw new BadEntry(\"no approvals list\");\n return approvals;\n } catch {\n warn(`skill shares: ${SHARES_FILENAME} is unreadable; listing no skills`);\n return null;\n }\n}\n\n/**\n * Every readable approval, in file order. Never throws.\n *\n * A missing file is no approvals. So is a file that is a link, not a regular\n * file, too large, not JSON or of an unknown layout; a malformed entry is\n * dropped and the rest are kept.\n */\nexport function loadShares(libraryPath?: string | null): SkillShare[] {\n const raw = readRaw(sharesPath(libraryPath));\n if (raw === null) return [];\n const shares: SkillShare[] = [];\n for (const item of raw) {\n if (isOtherKind(item)) continue;\n try {\n shares.push(shareFrom(item));\n } catch {\n warn(`skill shares: dropping a malformed entry in ${SHARES_FILENAME}`);\n }\n }\n return shares;\n}\n\nfunction otherKinds(path: string): unknown[] {\n return (readRaw(path) ?? []).filter(isOtherKind);\n}\n\n/** Python `json.dumps(..., indent=2)`: the default `ensure_ascii` escapes. */\nfunction pyJsonDumps(value: unknown): string {\n return JSON.stringify(value, null, 2).replace(\n /[\\u007f-￿]/g,\n (ch) => `\\\\u${ch.charCodeAt(0).toString(16).padStart(4, \"0\")}`,\n );\n}\n\nfunction write(path: string, shares: readonly SkillShare[]): void {\n const approvals = [...otherKinds(path), ...shares.map(shareToDict)];\n const payload = { version: SHARES_VERSION, approvals };\n const body = `${pyJsonDumps(payload)}\\n`;\n const temp = join(dirname(path), `.${basename(path)}.${randomBytes(6).toString(\"hex\")}.tmp`);\n try {\n const fd = openSync(temp, \"wx\");\n try {\n writeSync(fd, Buffer.from(body, \"utf8\"));\n fsyncSync(fd);\n } finally {\n closeSync(fd);\n }\n renameSync(temp, path);\n } finally {\n if (existsSync(temp)) rmSync(temp, { force: true });\n }\n}\n\nfunction checkWritable(path: string): void {\n let info: Stats;\n try {\n info = lstatSync(path);\n } catch (exc) {\n if ((exc as NodeJS.ErrnoException).code === \"ENOENT\") return;\n throw exc;\n }\n if (isPathLinkOrReparse(path, info) || !info.isFile()) {\n throw new SkillShareError(`${SHARES_FILENAME} must be a regular file, not a link`);\n }\n}\n\nexport interface AddShareOptions {\n name: string;\n agent: string | null;\n store: string;\n scope: string;\n project: string | null;\n pathHint: string;\n contentSha256: string;\n approvedAt?: string | null;\n}\n\n/**\n * Record one approval, replacing earlier approvals of the same item from the\n * same source. An unreadable shares file is replaced: it held no usable\n * approvals.\n */\nexport function addShare(\n libraryPath: string | null | undefined,\n options: AddShareOptions,\n): SkillShare {\n let share: SkillShare;\n try {\n share = shareFrom(\n shareToDict({\n name: options.name,\n agent: options.agent,\n store: options.store,\n scope: options.scope,\n project: options.project,\n pathHint: options.pathHint,\n contentSha256: options.contentSha256,\n approvedAt: options.approvedAt || nowIso(),\n actor: SHARE_ACTOR,\n }),\n );\n } catch (exc) {\n throw new SkillShareError(`invalid share: ${exc instanceof Error ? exc.message : String(exc)}`);\n }\n const path = sharesPath(libraryPath);\n mkdirSync(dirname(path), { recursive: true });\n const replaces = shareReplaces(share);\n withManifestLock(path, () => {\n checkWritable(path);\n const kept = loadShares(dirname(path)).filter((item) => shareReplaces(item) !== replaces);\n write(path, [...kept, share]);\n });\n return share;\n}\n\nfunction isDirectory(path: string): boolean {\n try {\n return statSync(path).isDirectory();\n } catch {\n return false;\n }\n}\n\n/** Remove the shares whose {@link shareKey} is in `keys`; how many went. */\nexport function removeShares(\n libraryPath: string | null | undefined,\n keys: Iterable<string>,\n): number {\n const wanted = new Set(keys);\n const path = sharesPath(libraryPath);\n if (!isDirectory(dirname(path))) return 0;\n return withManifestLock(path, () => {\n checkWritable(path);\n const current = loadShares(dirname(path));\n const kept = current.filter((item) => !wanted.has(shareKey(item)));\n const removed = current.length - kept.length;\n if (removed) write(path, kept);\n return removed;\n });\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * GitHub-embedded Copilot participant — the v0.3 network-adapter reference.\n * Port of `participants/github_copilot.py`.\n *\n * Cloud-side Copilot (PR review, `@copilot` comments) persists nothing on the\n * user's machine — its state lives on github.com. This adapter federates it by\n * reading the user's GitHub activity over the REST API. The\n * {@link NetworkParticipant} base provides the cache, degradation, and auth\n * boundary; this class provides only the GitHub-specific fetch + payload→L5.\n *\n * Auth: a token with `repo` + `read:user` scope, sourced from `$GITHUB_TOKEN` /\n * `$GH_TOKEN`, else `gh auth token`. Fetched lazily; never stored in the cache\n * or the manifest.\n */\n\nimport { execFileSync } from \"node:child_process\";\n\nimport {\n Visibility,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport { SPEC_VERSION } from \"../base.js\";\nimport {\n NetworkParticipant,\n NetworkUnavailable,\n ParticipantAuthError,\n type AuthProvider,\n type NetworkParticipantOptions,\n} from \"../network-base.js\";\n\nconst AGENT_ID = \"github-copilot\";\nconst AGENT_TYPE = \"code-assistant\";\nconst PARTICIPANT_SLUG = \"github-copilot\";\nconst DISPLAY_NAME = \"GitHub Copilot (cloud)\";\nconst ROLE_NARRATIVE =\n \"Cloud-side GitHub Copilot: PR review and @copilot-authored comments/\" +\n \"suggestions that live on github.com, not on the user's machine. Federated \" +\n \"via the GitHub REST API rather than a local artifact.\";\n\nconst GITHUB_API_ROOT = \"https://api.github.com\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"secret\"],\n team_tags: [\"github-copilot\", \"pull-request\"],\n});\n\n// -- Auth resolution ----------------------------------------------------------\n\n/** Resolve a GitHub token: env var first, then the `gh` CLI keychain. */\nexport function ghTokenProvider(): string | null {\n for (const varName of [\"GITHUB_TOKEN\", \"GH_TOKEN\"]) {\n const val = process.env[varName];\n if (val) return val;\n }\n try {\n const out = execFileSync(\"gh\", [\"auth\", \"token\"], {\n encoding: \"utf8\",\n timeout: 5000,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n });\n const token = out.trim();\n if (token) return token;\n } catch {\n /* gh missing / not logged in */\n }\n return null;\n}\n\n// -- HTTP ---------------------------------------------------------------------\n\ninterface HttpResponse {\n status: number;\n headers: Record<string, string>;\n body: string;\n}\n\n/**\n * Synchronous GET via a tiny `curl` shell-out (the base class's fetch contract\n * is synchronous, matching the Python urllib reference). Returns parsed JSON.\n * Classifies failures into the two contract errors: rate-limit / 5xx /\n * transport / non-JSON → {@link NetworkUnavailable}; 401/403 →\n * {@link ParticipantAuthError}. Never raises anything else.\n */\nfunction githubGet(path: string, token: string, timeoutSec = 10): unknown {\n const url = path.startsWith(\"http\") ? path : `${GITHUB_API_ROOT}${path}`;\n let resp: HttpResponse;\n try {\n resp = curlGet(url, token, timeoutSec);\n } catch (err) {\n throw new NetworkUnavailable(`GitHub API unreachable: ${String(err)}`);\n }\n\n const remaining = resp.headers[\"x-ratelimit-remaining\"];\n if (resp.status === 429 || (resp.status === 403 && String(remaining) === \"0\")) {\n throw new NetworkUnavailable(`GitHub API ${resp.status}: rate-limited`);\n }\n if (resp.status === 401 || resp.status === 403) {\n throw new ParticipantAuthError(`GitHub API ${resp.status}: token invalid or lacks scope`);\n }\n if (resp.status >= 500) {\n throw new NetworkUnavailable(`GitHub API ${resp.status}`);\n }\n if (resp.status >= 400) {\n throw new NetworkUnavailable(`GitHub API ${resp.status}`);\n }\n try {\n return JSON.parse(resp.body);\n } catch (err) {\n // A 200 with a non-JSON body (captive portal / proxy splash) is a degraded\n // condition, not a hard crash.\n throw new NetworkUnavailable(`GitHub API returned a non-JSON body: ${String(err)}`);\n }\n}\n\nfunction curlGet(url: string, token: string, timeoutSec: number): HttpResponse {\n // `-sS` quiet but show errors; `-D -` dumps headers to stdout before the body;\n // `-w` appends the status code on its own trailing line for parsing.\n const raw = execFileSync(\n \"curl\",\n [\n \"-sS\",\n \"-D\",\n \"-\",\n \"-o\",\n \"-\",\n \"--max-time\",\n String(timeoutSec),\n \"-H\",\n `Authorization: Bearer ${token}`,\n \"-H\",\n \"Accept: application/vnd.github+json\",\n \"-H\",\n \"X-GitHub-Api-Version: 2022-11-28\",\n \"-H\",\n \"User-Agent: bourdon-github-copilot-participant\",\n \"-w\",\n \"\\n__BOURDON_STATUS__%{http_code}\",\n url,\n ],\n { encoding: \"utf8\", timeout: (timeoutSec + 2) * 1000, maxBuffer: 8 * 1024 * 1024 },\n );\n\n const statusMatch = /\\n__BOURDON_STATUS__(\\d+)$/.exec(raw);\n const status = statusMatch ? Number(statusMatch[1]) : 0;\n const withoutStatus = statusMatch ? raw.slice(0, statusMatch.index) : raw;\n\n // Split header block from body (last header section before body).\n const headerBodySplit = withoutStatus.indexOf(\"\\r\\n\\r\\n\");\n let headerBlock = \"\";\n let body = withoutStatus;\n if (headerBodySplit >= 0) {\n headerBlock = withoutStatus.slice(0, headerBodySplit);\n body = withoutStatus.slice(headerBodySplit + 4);\n } else {\n const lfSplit = withoutStatus.indexOf(\"\\n\\n\");\n if (lfSplit >= 0) {\n headerBlock = withoutStatus.slice(0, lfSplit);\n body = withoutStatus.slice(lfSplit + 2);\n }\n }\n\n const headers: Record<string, string> = {};\n for (const line of headerBlock.split(/\\r?\\n/)) {\n const idx = line.indexOf(\":\");\n if (idx > 0) {\n headers[line.slice(0, idx).trim().toLowerCase()] = line.slice(idx + 1).trim();\n }\n }\n return { status, headers, body };\n}\n\n// -- Participant --------------------------------------------------------------\n\n/** Federates cloud-side GitHub Copilot activity via the GitHub REST API. */\nexport class GitHubCopilotParticipant extends NetworkParticipant {\n override participantSlug = PARTICIPANT_SLUG;\n override agentId = AGENT_ID;\n override agentType = AGENT_TYPE;\n override nativePath = GITHUB_API_ROOT;\n displayName = DISPLAY_NAME;\n\n private readonly maxResults: number;\n\n constructor(opts: NetworkParticipantOptions & { maxResults?: number } = {}) {\n super({\n authProvider: opts.authProvider ?? ghTokenProvider,\n cacheRoot: opts.cacheRoot,\n });\n this.maxResults = opts.maxResults ?? 50;\n }\n\n static defaultNativePath(): string {\n return GITHUB_API_ROOT;\n }\n\n override fetchPayload(token: string): Record<string, unknown> {\n // Identify the authenticated user (also validates the token early).\n const me = githubGet(\"/user\", token);\n const login = me && typeof me === \"object\" ? (me as Record<string, unknown>)[\"login\"] : null;\n\n // PRs that involve the user where Copilot is a commenter/reviewer.\n const q = \"is:pr involves:@me commenter:copilot\";\n const encoded = encodeURIComponent(q);\n const search = githubGet(\n `/search/issues?q=${encoded}&sort=updated&per_page=${this.maxResults}`,\n token,\n );\n const items =\n search && typeof search === \"object\"\n ? ((search as Record<string, unknown>)[\"items\"] ?? [])\n : [];\n\n return {\n fetched_user: login ?? null,\n fetched_at: new Date().toISOString(),\n items,\n };\n }\n\n override payloadToL5(payload: Record<string, unknown>): L5ManifestModel {\n const items = Array.isArray(payload[\"items\"]) ? (payload[\"items\"] as unknown[]) : [];\n const sessions: SessionModel[] = [];\n const entities = new Map<string, EntityModel>();\n\n for (const item of items) {\n if (typeof item !== \"object\" || item === null) continue;\n const it = item as Record<string, unknown>;\n const repo = repoFromItem(it);\n const title = redactText(String(it[\"title\"] ?? \"\"), 160);\n const number = it[\"number\"];\n const updated = isoDate(it[\"updated_at\"]);\n const focus = repo ? [repo] : [];\n\n sessions.push(\n makeSession({\n date: updated || \"1970-01-01\",\n cwd: repo ? `github.com/${repo}` : undefined,\n project_focus: focus,\n key_actions: number != null ? [`PR #${String(number)}: ${title}`] : [title],\n visibility: Visibility.TEAM,\n }),\n );\n\n if (repo && !entities.has(repo)) {\n entities.set(\n repo,\n makeEntity({\n name: repo,\n type: \"repository\",\n summary: \"GitHub repo with Copilot PR activity.\",\n aliases: repo.includes(\"/\") ? [repo.split(\"/\").pop() ?? \"\"] : [],\n last_touched: updated ?? undefined,\n tags: [\"github-copilot\", \"pull-request\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n\n // Keep sessions newest-first, bounded.\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: this.agentId,\n type: this.agentType,\n role_narrative: ROLE_NARRATIVE,\n instance: (payload[\"fetched_user\"] as string | null | undefined) ?? undefined,\n }),\n last_updated: new Date().toISOString(),\n capabilities: [\"github-search\", \"pull-request-comments\"],\n recent_sessions: sessions.slice(0, this.maxResults),\n known_entities: [...entities.values()],\n visibility_policy: DEFAULT_POLICY,\n });\n }\n}\n\n// -- Helpers ------------------------------------------------------------------\n\nfunction repoFromItem(item: Record<string, unknown>): string | null {\n const repoUrl = item[\"repository_url\"];\n if (typeof repoUrl === \"string\" && repoUrl.includes(\"/repos/\")) {\n return repoUrl.split(\"/repos/\")[1] ?? null;\n }\n return null;\n}\n\nfunction isoDate(value: unknown): string | null {\n if (typeof value === \"string\" && value.length >= 10) return value.slice(0, 10);\n return null;\n}\n\n// Re-export the provider type for adapters/tests that inject auth.\nexport type { AuthProvider };\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Cursor participant — reads Cursor's (the AI-first IDE) SQLite-backed\n * workspace/composer state and normalizes it into L5. Port of\n * `participants/cursor.py` + the extraction helper `participants/_cursor_sqlite.py`.\n *\n * Cursor stores workspace state in `state.vscdb` SQLite DBs at platform-specific\n * paths (`~/.config/Cursor/`, `~/Library/Application Support/Cursor/`,\n * `%APPDATA%/Cursor/`). This reader discovers those stores, reads the `ItemTable`\n * key/value rows read-only, parses the composer/chat records into sessions +\n * project/topic entities, and merges curated `.cursor/memory/short-index.json`\n * entities alongside them.\n *\n * SQLite access: the Python oracle copies each DB (+ its `-wal`/`-shm`\n * companions) to a tmp file and opens it read-write so SQLite folds the WAL into\n * a consistent snapshot. The TS mirror instead leans on {@link tryOpenReadonly}\n * (`mode=ro`), which respects SQLite locking and reads the `-wal` sidecar of a\n * live writer — the same consistent view without the copy. Read-only,\n * deterministic, visibility-enforced-before-emission, redaction on every native\n * string; `healthCheck` never throws.\n */\n\nimport { readFileSync, readdirSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { basename, join } from \"node:path\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type SkillRefModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\nimport {\n advertisedSkills,\n crossAgentSkillSources,\n cursorSkillSources,\n scanSkillSources,\n type SkillScanReport,\n type SkillSource,\n} from \"../skills.js\";\nimport { tableExists, tryOpenReadonly } from \"../sqlite-base.js\";\n\nconst AGENT_ID = \"cursor\";\nconst AGENT_TYPE = \"code-assistant\";\nconst ROLE_NARRATIVE =\n \"AI-first IDE. Bourdon reads the SQLite-backed composer/workspace \" +\n \"state to surface recent sessions and project entities to other agents.\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"credential\", \"secret\"],\n team_tags: [\"cursor\", \"workspace\", \"sqlite\"],\n});\n\nconst TOPIC_MIN_MENTIONS = 3;\n\n// -- Defensive fs helpers -----------------------------------------------------\n\nfunction homeDir(): string {\n try {\n return homedir();\n } catch {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n }\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\n/** Redact credential-like content and cap length (redaction SSOT). */\nfunction scrubText(value: string, limit = 256): string {\n return redactText(value, limit);\n}\n\n// -- Extraction data shapes ---------------------------------------------------\n\ninterface CursorSessionMemory {\n date: string;\n cwd: string;\n keyActions: string[];\n filesTouched: string[];\n}\n\ninterface CursorEntityMemory {\n name: string;\n entityType: string;\n aliases: string[];\n summary: string;\n tags: string[];\n lastUpdated: string;\n}\n\ninterface CursorSQLiteMemories {\n sessions: CursorSessionMemory[];\n entities: CursorEntityMemory[];\n databasesScanned: string[];\n malformedRecords: number;\n}\n\n// -- Path resolution ----------------------------------------------------------\n\n/**\n * Platform-specific Cursor data dir (the SQLite workspace state lives here),\n * `$CURSOR_DIR` override first. Returns null on an unrecognized platform (or\n * Windows without `%APPDATA%`). Mirrors `default_cursor_dir`.\n */\nexport function defaultCursorDir(): string | null {\n const env = process.env.CURSOR_DIR;\n if (env) return env;\n switch (process.platform) {\n case \"darwin\":\n return join(homeDir(), \"Library\", \"Application Support\", \"Cursor\");\n case \"linux\":\n return join(homeDir(), \".config\", \"Cursor\");\n case \"win32\": {\n const appdata = process.env.APPDATA;\n return appdata ? join(appdata, \"Cursor\") : null;\n }\n default:\n return null;\n }\n}\n\n/** Candidate `state.vscdb` paths under a Cursor data dir that actually exist. */\nfunction iterStateDbs(root: string): string[] {\n const candidates: string[] = [\n join(root, \"state.vscdb\"),\n join(root, \"User\", \"globalStorage\", \"state.vscdb\"),\n ];\n const workspaceStorage = join(root, \"User\", \"workspaceStorage\");\n if (isDir(workspaceStorage)) {\n let children: string[] = [];\n try {\n children = readdirSync(workspaceStorage).sort();\n } catch {\n children = [];\n }\n for (const child of children) {\n candidates.push(join(workspaceStorage, child, \"state.vscdb\"));\n }\n }\n return candidates.filter((p) => isFile(p));\n}\n\n// -- SQLite ItemTable read (read-only) ----------------------------------------\n\n/**\n * Read the `(key, value)` rows of the `ItemTable`, JSON-decoding each value.\n * Returns the decoded records plus a count of values that failed to parse.\n * Never raises — a locked/corrupt/unreadable DB degrades to \"no rows\".\n */\nfunction readItemTable(dbPath: string): { records: Array<[string, unknown]>; malformed: number } {\n const records: Array<[string, unknown]> = [];\n let malformed = 0;\n\n const conn = tryOpenReadonly(dbPath);\n if (!conn) return { records, malformed };\n\n let rows: Array<{ key: unknown; value: unknown }>;\n try {\n if (!tableExists(conn, \"ItemTable\")) return { records, malformed };\n rows = conn.prepare(\"SELECT key, value FROM ItemTable\").all() as Array<{\n key: unknown;\n value: unknown;\n }>;\n } catch {\n // Locked (Windows holds a write lock on a live DB), corrupt, or otherwise\n // unreadable — skip this DB, never crash the whole export. The caller still\n // records it as scanned.\n return { records, malformed };\n } finally {\n conn.close();\n }\n\n for (const row of rows) {\n const raw = row.value;\n let text: string | null = null;\n if (typeof raw === \"string\") text = raw;\n else if (raw instanceof Uint8Array) text = Buffer.from(raw).toString(\"utf8\");\n if (text === null) {\n malformed += 1;\n continue;\n }\n let value: unknown;\n try {\n value = JSON.parse(text);\n } catch {\n malformed += 1;\n continue;\n }\n records.push([String(row.key), value]);\n }\n return { records, malformed };\n}\n\n// -- Record parsing -----------------------------------------------------------\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction firstString(value: Record<string, unknown>, keys: readonly string[]): string {\n for (const key of keys) {\n const candidate = value[key];\n if (typeof candidate === \"string\" && candidate.trim()) return candidate.trim();\n }\n return \"\";\n}\n\nfunction firstMessageText(messages: unknown): string {\n if (!Array.isArray(messages)) return \"\";\n for (const message of messages) {\n if (!isRecord(message)) continue;\n // Python uses `content or text` — fall back whenever content is falsy\n // (incl. \"\"), not just null/undefined. `||` matches; `??` would drop a\n // {content:\"\", text:\"...\"} record and silently lose the session.\n const content = message[\"content\"] || message[\"text\"];\n if (typeof content === \"string\" && content.trim()) return content.trim();\n }\n return \"\";\n}\n\nfunction looksLikeComposerRecord(key: string, value: unknown): boolean {\n const loweredKey = key.toLowerCase();\n if (loweredKey.includes(\"composer\") || loweredKey.includes(\"aichat\") || loweredKey.includes(\"chat\")) {\n return true;\n }\n if (isRecord(value)) {\n const joinedKeys = Object.keys(value).join(\" \").toLowerCase();\n return joinedKeys.includes(\"message\") && (joinedKeys.includes(\"workspace\") || joinedKeys.includes(\"file\"));\n }\n return false;\n}\n\n/**\n * Parse a calendar date as written from an ISO-ish string (no tz conversion,\n * mirroring `datetime.fromisoformat(...).date()`) or an epoch number.\n */\nfunction parseDate(value: unknown): string {\n if (typeof value === \"string\") {\n const normalized = value.replaceAll(\"Z\", \"+00:00\");\n const m = /^(\\d{4}-\\d{2}-\\d{2})([T ].*)?$/.exec(normalized);\n if (!m) return \"\";\n const datePart = m[1] ?? \"\";\n // Reject calendar-impossible days (e.g. 2024-02-30): Python's\n // `datetime.fromisoformat` raises on these, but `new Date` silently rolls\n // the month over. Round-trip the date and require it to survive unchanged.\n const dayProbe = new Date(`${datePart}T00:00:00Z`);\n if (Number.isNaN(dayProbe.getTime()) || dayProbe.toISOString().slice(0, 10) !== datePart) {\n return \"\";\n }\n // Validate the full value parses as a real datetime; take the date as written.\n const probe = new Date(m[2] ? normalized.replace(\" \", \"T\") : `${datePart}T00:00:00`);\n if (Number.isNaN(probe.getTime())) return \"\";\n return datePart;\n }\n if (typeof value === \"number\" && Number.isFinite(value)) {\n const timestamp = value > 10_000_000_000 ? value / 1000 : value;\n const dt = new Date(timestamp * 1000);\n if (Number.isNaN(dt.getTime())) return \"\";\n return dt.toISOString().slice(0, 10);\n }\n return \"\";\n}\n\nfunction dateFromRecord(value: Record<string, unknown>): string {\n for (const key of [\"createdAt\", \"timestamp\", \"updatedAt\", \"lastUpdatedAt\", \"time\"]) {\n const parsed = parseDate(value[key]);\n if (parsed) return parsed;\n }\n return new Date().toISOString().slice(0, 10);\n}\n\nfunction stringsFromList(values: unknown[]): string[] {\n const strings: string[] = [];\n for (const item of values) {\n if (typeof item === \"string\" && item.trim()) {\n strings.push(item.trim());\n } else if (isRecord(item)) {\n const path = firstString(item, [\"path\", \"file\", \"uri\", \"relativePath\"]);\n if (path) strings.push(path);\n }\n }\n return strings;\n}\n\nfunction dedupe(values: string[]): string[] {\n const seen = new Set<string>();\n const out: string[] = [];\n for (const value of values) {\n if (!seen.has(value)) {\n seen.add(value);\n out.push(value);\n }\n }\n return out;\n}\n\nfunction extractFiles(value: Record<string, unknown>): string[] {\n const files: string[] = [];\n for (const key of [\"files\", \"filePaths\", \"filesTouched\", \"references\"]) {\n const candidate = value[key];\n if (Array.isArray(candidate)) files.push(...stringsFromList(candidate));\n }\n const messages = value[\"messages\"];\n if (Array.isArray(messages)) {\n for (const message of messages) {\n if (isRecord(message)) files.push(...extractFiles(message));\n }\n }\n return dedupe(files);\n}\n\nfunction recordToSession(key: string, value: unknown): CursorSessionMemory | null {\n if (!looksLikeComposerRecord(key, value)) return null;\n if (!isRecord(value)) return null;\n\n let cwd = firstString(value, [\"workspacePath\", \"workspace\", \"cwd\", \"folder\", \"rootPath\"]);\n if (!cwd && isRecord(value[\"workspace\"])) {\n cwd = firstString(value[\"workspace\"], [\"path\", \"folder\", \"cwd\"]);\n }\n if (!cwd) cwd = \"\";\n\n let action = firstString(value, [\"title\", \"text\", \"prompt\", \"summary\", \"name\"]);\n if (!action) action = firstMessageText(value[\"messages\"]);\n if (!action) return null;\n\n return {\n date: dateFromRecord(value),\n cwd,\n keyActions: [scrubText(action)],\n filesTouched: extractFiles(value),\n };\n}\n\nfunction projectName(cwd: string): string {\n if (!cwd) return \"\";\n const name = basename(cwd).trim();\n return name && name !== \".\" && name !== \"/\" ? name : \"\";\n}\n\n// -- Topic-entity inference ---------------------------------------------------\n\nconst STRIP_CHARS = new Set([\n \".\", \",\", \";\", \":\", \"!\", \"?\", '\"', \"'\", \"`\", \"(\", \")\", \"[\", \"]\", \"{\", \"}\", \"#\", \"-\", \"/\",\n]);\n\nfunction stripChars(token: string): string {\n let start = 0;\n let end = token.length;\n while (start < end && STRIP_CHARS.has(token[start]!)) start += 1;\n while (end > start && STRIP_CHARS.has(token[end - 1]!)) end -= 1;\n return token.slice(start, end);\n}\n\nconst TOPIC_STOPWORDS = new Set([\n \"the\", \"and\", \"for\", \"with\", \"this\", \"that\", \"from\", \"have\", \"will\",\n \"are\", \"was\", \"been\", \"not\", \"but\", \"all\", \"can\", \"has\", \"its\",\n \"add\", \"use\", \"set\", \"get\", \"new\", \"fix\", \"run\", \"now\", \"also\",\n \"into\", \"make\", \"just\", \"like\", \"need\", \"want\", \"work\", \"code\",\n \"file\", \"test\", \"data\", \"type\", \"should\", \"would\", \"could\",\n]);\n\n/** Extract recurring topic entities from session key_actions (in place). */\nfunction addTopicEntities(\n sessions: CursorSessionMemory[],\n entities: Map<string, CursorEntityMemory>,\n): void {\n const wordCounts = new Map<string, number>();\n const wordLatest = new Map<string, string>();\n\n for (const session of sessions) {\n for (const action of session.keyActions) {\n const words = new Set<string>();\n for (const token of action.toLowerCase().split(/\\s+/)) {\n const cleaned = stripChars(token);\n if (cleaned.length >= 4 && !TOPIC_STOPWORDS.has(cleaned) && /^\\p{L}+$/u.test(cleaned)) {\n words.add(cleaned);\n }\n }\n for (const word of words) {\n wordCounts.set(word, (wordCounts.get(word) ?? 0) + 1);\n if (session.date) {\n const prev = wordLatest.get(word);\n if (prev === undefined || session.date > prev) wordLatest.set(word, session.date);\n }\n }\n }\n }\n\n for (const [word, count] of wordCounts) {\n if (count >= TOPIC_MIN_MENTIONS && !entities.has(word)) {\n entities.set(word, {\n name: word,\n entityType: \"topic\",\n aliases: [],\n summary: `Recurring topic across ${count} Cursor sessions.`,\n tags: [\"cursor\", \"topic\", \"inferred\"],\n lastUpdated: wordLatest.get(word) ?? \"\",\n });\n }\n }\n}\n\n// -- Top-level extraction -----------------------------------------------------\n\nfunction extractCursorMemories(cursorDir: string | null = null): CursorSQLiteMemories {\n const root = cursorDir ?? defaultCursorDir();\n if (root === null || !isDir(root)) {\n return { sessions: [], entities: [], databasesScanned: [], malformedRecords: 0 };\n }\n\n const sessions: CursorSessionMemory[] = [];\n const entitiesByName = new Map<string, CursorEntityMemory>();\n const databasesScanned: string[] = [];\n let malformedRecords = 0;\n const projectLatest = new Map<string, string>();\n\n for (const dbPath of iterStateDbs(root)) {\n databasesScanned.push(dbPath);\n const { records, malformed } = readItemTable(dbPath);\n malformedRecords += malformed;\n for (const [key, value] of records) {\n const parsedSession = recordToSession(key, value);\n if (parsedSession === null) continue;\n sessions.push(parsedSession);\n\n const name = projectName(parsedSession.cwd);\n if (!name) continue;\n\n const prev = projectLatest.get(name) ?? \"\";\n if (!projectLatest.has(name) || (parsedSession.date && parsedSession.date > prev)) {\n projectLatest.set(name, parsedSession.date);\n }\n const existing = entitiesByName.get(name);\n const aliasSet = new Set<string>(parsedSession.cwd ? [parsedSession.cwd] : []);\n if (existing) {\n for (const a of existing.aliases) aliasSet.add(a);\n }\n entitiesByName.set(name, {\n name: scrubText(name, 120),\n entityType: \"project\",\n aliases: [...aliasSet].sort(),\n summary: scrubText(`Cursor workspace inferred from ${parsedSession.cwd}.`),\n tags: [\"cursor\", \"workspace\", \"sqlite\"],\n lastUpdated: projectLatest.get(name) ?? \"\",\n });\n }\n }\n\n addTopicEntities(sessions, entitiesByName);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n\n return {\n sessions,\n entities: [...entitiesByName.values()],\n databasesScanned,\n malformedRecords,\n };\n}\n\n// -- Short-index integration --------------------------------------------------\n\n/** Read a short-index.json and return its normalized entry dicts. */\nfunction readShortIndex(path: string): Array<Record<string, unknown>> {\n if (!isFile(path)) return [];\n let payload: unknown;\n try {\n const raw = readFileSync(path, \"utf8\").replace(/^\\uFEFF/, \"\"); // utf-8-sig: strip BOM\n payload = JSON.parse(raw);\n } catch {\n // Python logs a warning here; swallow + skip so a bad file never crashes export.\n return [];\n }\n if (!isRecord(payload)) return [];\n const entries = payload[\"entries\"];\n if (!Array.isArray(entries)) return [];\n return entries.filter(\n (e): e is Record<string, unknown> => isRecord(e) && Boolean(e[\"topic_key\"]),\n );\n}\n\n/** Merge workspace + global short-index files into Entity objects. */\nfunction shortIndexToEntities(\n workspaceRoot: string | null,\n _cursorDir: string | null,\n): EntityModel[] {\n const paths: string[] = [];\n if (workspaceRoot) {\n paths.push(join(workspaceRoot, \".cursor\", \"memory\", \"short-index.json\"));\n }\n const cursorHome = process.env.CURSOR_DIR ? process.env.CURSOR_DIR : null;\n const homeBase = cursorHome ?? join(homeDir(), \".cursor\");\n paths.push(join(homeBase, \"memory\", \"short-index.json\"));\n\n const merged = new Map<string, Record<string, unknown>>();\n for (const path of paths) {\n for (const entry of readShortIndex(path)) {\n const key = String(entry[\"topic_key\"]).trim().toLowerCase();\n merged.set(key, entry);\n }\n }\n\n const entities: EntityModel[] = [];\n for (const entry of merged.values()) {\n const nameRaw =\n entry[\"topic_name\"] !== undefined ? entry[\"topic_name\"] : (entry[\"topic_key\"] ?? \"\");\n const name = String(nameRaw).trim();\n if (!name) continue;\n\n const aliasesRaw =\n \"triggers\" in entry ? entry[\"triggers\"] : \"aliases\" in entry ? entry[\"aliases\"] : [];\n const aliases = Array.isArray(aliasesRaw)\n ? aliasesRaw.map((a) => String(a).trim()).filter((s) => s.length > 0)\n : [];\n\n const summary = String(entry[\"summary\"] ?? \"\").trim();\n\n const tagsRaw = entry[\"tags\"] ?? [];\n const tags = Array.isArray(tagsRaw)\n ? tagsRaw.map((t) => String(t).trim()).filter((s) => s.length > 0)\n : [];\n tags.push(\"short-index\");\n\n const access = String(entry[\"access_level\"] ?? \"team\").trim().toLowerCase();\n const visibility =\n access === \"private\"\n ? Visibility.PRIVATE\n : access === \"public\"\n ? Visibility.PUBLIC\n : Visibility.TEAM;\n\n const lastTouched = String(entry[\"last_updated\"] ?? \"\");\n\n entities.push(\n makeEntity({\n name,\n type: \"topic\",\n aliases,\n summary: summary || undefined,\n tags,\n last_touched: lastTouched || undefined,\n visibility,\n }),\n );\n }\n return entities;\n}\n\n// -- Conversion helpers -------------------------------------------------------\n\nfunction toSession(raw: CursorSessionMemory): SessionModel {\n return makeSession({\n date: raw.date || \"\",\n cwd: raw.cwd || undefined,\n project_focus: [],\n key_actions: [...raw.keyActions],\n files_touched: [...raw.filesTouched],\n });\n}\n\nfunction toEntity(raw: CursorEntityMemory): EntityModel {\n return makeEntity({\n name: raw.name,\n type: raw.entityType || undefined,\n aliases: [...raw.aliases],\n summary: raw.summary || undefined,\n tags: [...raw.tags],\n last_touched: raw.lastUpdated || undefined,\n });\n}\n\n/** Current UTC time, seconds precision + `+00:00` (Python `isoformat(timespec=\"seconds\")`). */\nfunction nowIsoSeconds(): string {\n return new Date().toISOString().replace(/\\.\\d{3}Z$/, \"+00:00\");\n}\n\n// -- Participant --------------------------------------------------------------\n\n/** External participant for Cursor's SQLite workspace state. */\nexport class CursorParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n\n private readonly cursorDir: string | null;\n private readonly workspaceRoot: string | null;\n private readonly policy: VisibilityPolicyModel = DEFAULT_POLICY;\n\n /**\n * Conventional Cursor config dir (`~/.cursor`) used by the setup wizard. The\n * wizard probes `~/.cursor` for presence; the SQLite workspace state that\n * `exportL5` actually reads lives at {@link defaultCursorDir}. Detection and\n * extraction intentionally use different anchors.\n */\n static defaultNativePath(home?: string): string {\n return join(home ?? homeDir(), \".cursor\");\n }\n\n /**\n * Explicit skill directories; `null` = the defaults (see skills.ts), read\n * only for shared skills unless `BOURDON_SKILLS_ADVERTISE` lists all.\n * Explicit sources list every skill in them.\n * `workspaceRoot` does not opt a project in: that takes an explicit\n * `BOURDON_SKILL_PROJECTS` entry, or explicit sources.\n */\n private readonly explicitSkillSources: readonly SkillSource[] | null;\n\n constructor(\n cursorDir?: string | null,\n workspaceRoot?: string | null,\n options: { skillSources?: readonly SkillSource[] | null } = {},\n ) {\n this.cursorDir = cursorDir ?? null;\n this.workspaceRoot = workspaceRoot ?? null;\n this.explicitSkillSources = options.skillSources == null ? null : [...options.skillSources];\n }\n\n // -- Skills (plan 005: discovery only) -----------------------------------------\n\n /**\n * `~/.cursor/skills` (not the built-in `skills-cursor`) and the cross-agent\n * store, plus the opted-in projects' `.cursor/skills` and `.agents/skills`.\n */\n /** Built with explicit skill sources: this participant lists all of them. */\n hasExplicitSkillSources(): boolean {\n return this.explicitSkillSources !== null;\n }\n\n skillSources(): SkillSource[] {\n if (this.explicitSkillSources !== null) return [...this.explicitSkillSources];\n return [...cursorSkillSources(), ...crossAgentSkillSources()];\n }\n\n /** Advertised skills plus the skills that could not be advertised. */\n scanSkills(): SkillScanReport {\n return scanSkillSources(this.skillSources());\n }\n\n exportSkills(): SkillRefModel[] {\n return this.scanSkills().refs;\n }\n\n get nativePath(): string {\n const path = this.cursorDir ?? defaultCursorDir();\n return path ?? \"\";\n }\n\n discover(): AgentStore {\n const path = this.cursorDir ?? defaultCursorDir();\n if (path === null || !isDir(path)) {\n throw new ParticipantDiscoveryError(\n `Cursor data directory not found at ${path === null ? \"None\" : `'${path}'`}. ` +\n \"Pass an explicit cursor_dir to CursorParticipant() if Cursor stores its \" +\n \"state somewhere non-standard.\",\n );\n }\n const dbs = iterStateDbs(path);\n const dbDetails = dbs.map((db) => {\n let size: number;\n try {\n size = statSync(db).size;\n } catch {\n size = -1;\n }\n return { path: db, size_bytes: size };\n });\n\n return {\n path,\n version: \"unknown\",\n metadata: {\n platform_default: defaultCursorDir() ?? \"None\",\n databases_found: dbs.length,\n databases: dbDetails,\n },\n };\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const memories = this.extract();\n const out: SessionModel[] = [];\n const sinceIso = since ? since.toISOString().slice(0, 10) : null;\n for (const raw of memories.sessions) {\n if (sinceIso && raw.date && raw.date < sinceIso) continue;\n out.push(toSession(raw));\n if (out.length >= limit) break;\n }\n return out;\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const memories = this.extract();\n let sessions = memories.sessions.map(toSession);\n if (since) {\n const sinceIso = since.toISOString().slice(0, 10);\n sessions = sessions.filter((s) => !s.date || s.date >= sinceIso);\n }\n\n const entities = memories.entities.map(toEntity);\n const shortIndexEntities = shortIndexToEntities(this.workspaceRoot, this.cursorDir);\n const seenNames = new Set(entities.map((e) => e.name.toLowerCase()));\n for (const si of shortIndexEntities) {\n const key = si.name.toLowerCase();\n if (!seenNames.has(key)) {\n entities.push(si);\n seenNames.add(key);\n }\n }\n const visibleEntities = filterForFederation(entities, this.policy);\n\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n role_narrative: ROLE_NARRATIVE,\n spec_version_compat: SPEC_VERSION,\n }),\n last_updated: nowIsoSeconds(),\n capabilities: [\"composer-history\", \"workspace-state\"],\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: this.policy,\n skills: advertisedSkills(this),\n });\n }\n\n healthCheck(): HealthStatus {\n const path = this.cursorDir ?? defaultCursorDir();\n if (path === null) {\n return {\n status: \"blocked\",\n reason: \"Cursor data directory not resolvable on this platform.\",\n details: {},\n proposedFix:\n \"Install Cursor (https://cursor.sh) and open it once. \" +\n \"Set CURSOR_DIR if Cursor stores state outside the default location.\",\n };\n }\n if (!isDir(path)) {\n return {\n status: \"blocked\",\n reason: `Cursor data directory not present at ${path}.`,\n details: { expected_path: path },\n proposedFix:\n \"Install Cursor and open it once to create the data directory, \" +\n \"or set CURSOR_DIR to the actual location.\",\n };\n }\n let memories: CursorSQLiteMemories;\n try {\n memories = this.extract();\n } catch (err) {\n // health check must not raise.\n return {\n status: \"degraded\",\n reason: \"Cursor data directory present but extraction failed.\",\n details: { error: String(err) },\n proposedFix:\n \"Close Cursor (its SQLite stores may be locked) then re-run \" +\n \"`bourdon cursor export`. If extraction still fails, file an \" +\n \"issue with the error above.\",\n };\n }\n if (memories.databasesScanned.length === 0) {\n return {\n status: \"degraded\",\n reason: \"No Cursor SQLite stores found under the data directory.\",\n details: { path },\n proposedFix:\n \"Open Cursor and use it for at least one chat session, then \" +\n \"re-run `bourdon cursor export`.\",\n };\n }\n return {\n status: \"ok\",\n details: {\n databases_scanned: memories.databasesScanned.length,\n sessions_extracted: memories.sessions.length,\n entities_extracted: memories.entities.length,\n malformed_records: memories.malformedRecords,\n },\n };\n }\n\n private extract(): CursorSQLiteMemories {\n return extractCursorMemories(this.cursorDir);\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * GitHub Copilot (local convention) participant — reads the convention-based\n * memory file at `~/.copilot-bourdon/memory.md`. Port of `participants/copilot.py`.\n *\n * Copilot has no accessible local session index (its reasoning is cloud-side and\n * its native memory is not exposed on disk), so — like the Codex pre-distillation\n * fallback — this reader normalizes a user-maintained convention file into a\n * Bourdon L5 manifest. The file is YAML front-matter (structured `entities:` /\n * `sessions:`) followed by an optional freeform markdown body that Copilot Chat\n * reads as plain context but this reader ignores.\n *\n * NOT the cloud GitHub-Copilot network adapter ({@link GitHubCopilotParticipant})\n * and NOT the Copilot CLI SQLite reader.\n *\n * Paths checked (in order):\n * 1. `COPILOT_BOURDON_HOME` env-var override\n * 2. `~/.copilot-bourdon/` (default convention path)\n *\n * Defensive throughout: a missing convention directory raises\n * {@link ParticipantDiscoveryError} from `discover()`; malformed YAML degrades to\n * an empty manifest rather than raising; `healthCheck` never throws.\n */\n\nimport { mkdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport { homedir, hostname } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { parse as yamlParse } from \"yaml\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\n\nconst AGENT_ID = \"copilot\";\nconst AGENT_TYPE = \"code-assistant\";\nconst DISPLAY_NAME = \"GitHub Copilot\";\nconst ROLE_NARRATIVE =\n \"Inline completion and chat assistant present across every IDE the team uses. \" +\n \"Works alongside the human at the keystroke level -- the ambient layer that \" +\n \"recognises what is being typed before a full turn is even formed. Bourdon \" +\n \"gives Copilot cross-session entity awareness it would otherwise lack entirely.\";\n\n// Convention directory and file names. Override dir with COPILOT_BOURDON_HOME.\nconst CONVENTION_DIR_NAME = \".copilot-bourdon\";\nconst MEMORY_FILENAME = \"memory.md\";\n\n// Front-matter delimiters (mirrors claude-code's parseFrontmatter conventions).\nconst FRONTMATTER_OPEN = \"---\\n\";\nconst FRONTMATTER_CLOSE = \"\\n---\\n\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"health\", \"family\", \"legal\"],\n team_tags: [\"copilot-memory\", \"workspace\", \"copilot\"],\n});\n\n/** Minimal logger so a degraded read is visible without pulling in a dep\n * (matches the registry's logging idiom). */\nconst logger = {\n warn(msg: string): void {\n // eslint-disable-next-line no-console\n console.warn(`[bourdon.participants] ${msg}`);\n },\n};\n\n/** Starter template written by `bourdon copilot init`. */\nconst MEMORY_TEMPLATE = `---\n# Copilot Bourdon Memory\n# Edit this file to give Copilot cross-session entity awareness.\n# The YAML front-matter is parsed by \\`bourdon copilot export\\`.\n# The markdown body below the closing \\`---\\` is freeform context for Copilot Chat.\n\nentities: []\n\nsessions: []\n---\n\n# Copilot notes\n\nAdd project notes, preferences, or anything else you want Copilot Chat to\nremember here. This section is freeform -- the participant only reads the YAML\nfront-matter above.\n`;\n\n// -- fs helpers ---------------------------------------------------------------\n\nfunction homeDir(): string {\n // os.homedir() can throw under some sandboxes; stay defensive so import +\n // construction never crash even when HOME points at an unreadable path.\n try {\n return homedir();\n } catch {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n }\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\n// -- Path helpers -------------------------------------------------------------\n\n/**\n * Return the conventional `~/.copilot-bourdon/` directory path. Respects the\n * `COPILOT_BOURDON_HOME` env-var override (returned verbatim, even if absent;\n * the directory is not created here).\n */\nexport function defaultCopilotBourdonDir(): string {\n const env = process.env.COPILOT_BOURDON_HOME;\n if (env) return env;\n return join(homeDir(), CONVENTION_DIR_NAME);\n}\n\n/** Return the path to the convention memory file. */\nexport function defaultCopilotMemoryPath(copilotDir?: string | null): string {\n return join(copilotDir || defaultCopilotBourdonDir(), MEMORY_FILENAME);\n}\n\n// -- Coercion helpers (mirror Python str() / isinstance filtering) ------------\n\n/** Mirror Python `str(value)` for the value types YAML yields here. The `yaml`\n * lib parses timestamps into JS `Date`; Python's `yaml.safe_load` yields\n * `date`/`datetime` whose `str()` is ISO-ish, so a Date is rendered as its ISO\n * date (date-only callers slice to 10 anyway). */\nfunction coerceStr(v: unknown): string {\n if (v instanceof Date) return v.toISOString().slice(0, 10);\n return String(v);\n}\n\n/** Mirror Python `str(raw.get(key) or \"\") or None`. */\nfunction strOrUndef(v: unknown): string | undefined {\n const s = coerceStr((v as unknown) || \"\");\n return s || undefined;\n}\n\n/** Mirror `[str(x) for x in raw if isinstance(x, str) and x.strip()]`. */\nfunction strList(v: unknown): string[] {\n if (!Array.isArray(v)) return [];\n return v.filter((x): x is string => typeof x === \"string\" && x.trim() !== \"\");\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nfunction asArray(v: unknown): unknown[] {\n return Array.isArray(v) ? v : [];\n}\n\n// -- YAML frontmatter ---------------------------------------------------------\n\n/**\n * Extract and parse the YAML front-matter block from memory file text. Returns\n * an empty object when the file has no front-matter or when the YAML cannot be\n * parsed (logged at WARNING in the oracle; never raises here either).\n */\nfunction parseFrontmatter(text: string, source?: string): Record<string, unknown> {\n if (!text.startsWith(FRONTMATTER_OPEN)) return {};\n const end = text.indexOf(FRONTMATTER_CLOSE, FRONTMATTER_OPEN.length);\n if (end === -1) return {};\n const fmText = text.slice(FRONTMATTER_OPEN.length, end);\n let parsed: unknown;\n try {\n parsed = yamlParse(fmText);\n } catch (err) {\n const where = source ? ` in ${source}` : \"\";\n const detail = String(err).replace(/\\n/g, \" \").slice(0, 200);\n logger.warn(\n `CopilotParticipant: malformed YAML frontmatter${where}; ` +\n `treating as no-frontmatter (${detail})`,\n );\n return {};\n }\n return isRecord(parsed) ? parsed : {};\n}\n\n/**\n * Read and parse a copilot-bourdon memory file. Returns an empty object on any\n * I/O or parse error — the participant degrades to an empty manifest.\n */\nfunction readMemoryFile(path: string): Record<string, unknown> {\n if (!isFile(path)) return {};\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch (err) {\n logger.warn(`CopilotParticipant: cannot read ${path}: ${String(err)}`);\n return {};\n }\n return parseFrontmatter(text, path);\n}\n\n// -- Entity / Session converters ----------------------------------------------\n\n/** Convert a raw YAML entity record to a Bourdon Entity. Skips malformed\n * entries (oracle logs at DEBUG). Never raises. */\nfunction buildEntity(raw: unknown): EntityModel | null {\n if (!isRecord(raw)) return null;\n const name = raw[\"name\"];\n if (typeof name !== \"string\" || name.trim() === \"\") return null;\n\n const summaryRaw = raw[\"summary\"] || \"\";\n const summary = summaryRaw ? redactText(coerceStr(summaryRaw)) : undefined;\n\n return makeEntity({\n name: name.trim(),\n type: strOrUndef(raw[\"type\"]),\n aliases: strList(raw[\"aliases\"]),\n summary,\n last_touched: strOrUndef(raw[\"last_touched\"]),\n tags: strList(raw[\"tags\"]),\n valid_from: strOrUndef(raw[\"valid_from\"]),\n valid_to: strOrUndef(raw[\"valid_to\"]),\n });\n}\n\n/** Convert a raw YAML session record to a Bourdon Session. Skips malformed\n * entries (oracle logs at DEBUG). Never raises. */\nfunction buildSession(raw: unknown): SessionModel | null {\n if (!isRecord(raw)) return null;\n const dateVal = raw[\"date\"];\n if (!dateVal) return null;\n const dateStr = coerceStr(dateVal).slice(0, 10); // keep YYYY-MM-DD prefix only\n\n return makeSession({\n date: dateStr,\n cwd: strOrUndef(raw[\"cwd\"]),\n project_focus: strList(raw[\"project_focus\"]),\n key_actions: strList(raw[\"key_actions\"]),\n files_touched: strList(raw[\"files_touched\"]),\n });\n}\n\n// -- Diagnostics --------------------------------------------------------------\n\n/** Diagnostic summary of the copilot-bourdon memory file (`bourdon copilot\n * doctor`). Never raises. */\nexport function inspectCopilotMemory(copilotDir?: string | null): Record<string, unknown> {\n const memPath = defaultCopilotMemoryPath(copilotDir);\n const report: Record<string, unknown> = {\n path: memPath,\n present: isFile(memPath),\n readable: false,\n frontmatter_valid: false,\n entity_count: 0,\n session_count: 0,\n error: null,\n };\n if (!isFile(memPath)) {\n report[\"error\"] = \"missing\";\n return report;\n }\n let text: string;\n try {\n text = readFileSync(memPath, \"utf8\");\n report[\"readable\"] = true;\n } catch (err) {\n report[\"error\"] = String(err);\n return report;\n }\n\n const data = parseFrontmatter(text, memPath);\n if (Object.keys(data).length > 0) report[\"frontmatter_valid\"] = true;\n report[\"entity_count\"] = asArray(data[\"entities\"]).length;\n report[\"session_count\"] = asArray(data[\"sessions\"]).length;\n return report;\n}\n\n// -- Participant --------------------------------------------------------------\n\n/**\n * External participant for GitHub Copilot via `~/.copilot-bourdon/memory.md`.\n * Implements {@link BourdonParticipant} structurally.\n */\nexport class CopilotParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n displayName = DISPLAY_NAME;\n nativePath: string;\n\n /** Conventional `~/.copilot-bourdon` dir used by the setup wizard's detection. */\n static defaultNativePath(home?: string): string {\n if (home !== undefined) return join(home, CONVENTION_DIR_NAME);\n return defaultCopilotBourdonDir();\n }\n\n private readonly copilotDir: string | null;\n\n constructor(copilotDir?: string | null) {\n this.copilotDir = copilotDir ?? null;\n this.nativePath = this.copilotDir || defaultCopilotBourdonDir();\n }\n\n discover(): AgentStore {\n const path = this.copilotDir || defaultCopilotBourdonDir();\n if (!isDir(path)) {\n throw new ParticipantDiscoveryError(\n `Copilot convention directory not found at '${path}'. ` +\n \"Run `bourdon copilot init` to create it with a starter template, \" +\n \"or create ~/.copilot-bourdon/memory.md manually.\",\n );\n }\n const memPath = join(path, MEMORY_FILENAME);\n return {\n path,\n version: \"convention-v1\",\n metadata: {\n memory_file: memPath,\n memory_file_present: isFile(memPath),\n },\n };\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const data = this.read();\n const sinceIso = since ? since.toISOString().slice(0, 10) : null;\n const sessions: SessionModel[] = [];\n for (const raw of asArray(data[\"sessions\"])) {\n const session = buildSession(raw);\n if (session === null) continue;\n if (sinceIso && session.date && session.date < sinceIso) continue;\n sessions.push(session);\n if (sessions.length >= limit) break;\n }\n return sessions;\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const data = this.read();\n\n const entities: EntityModel[] = [];\n for (const raw of asArray(data[\"entities\"])) {\n const entity = buildEntity(raw);\n if (entity !== null) entities.push(entity);\n }\n const visibleEntities = filterForFederation(entities, DEFAULT_POLICY);\n\n const sinceIso = since ? since.toISOString().slice(0, 10) : null;\n const sessions: SessionModel[] = [];\n for (const raw of asArray(data[\"sessions\"])) {\n const session = buildSession(raw);\n if (session === null) continue;\n if (sinceIso && session.date && session.date < sinceIso) continue;\n sessions.push(session);\n }\n\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: hostname() || \"unknown\",\n spec_version_compat: `>=${SPEC_VERSION}`,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: new Date().toISOString(),\n capabilities: [\"inline-completion\", \"chat\", \"pr-review\", \"convention-memory\"],\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: DEFAULT_POLICY,\n });\n }\n\n healthCheck(): HealthStatus {\n const path = this.copilotDir || defaultCopilotBourdonDir();\n if (!isDir(path)) {\n return {\n status: \"blocked\",\n reason:\n `Convention directory ${path} not found. ` +\n \"Run `bourdon copilot init` to create it.\",\n details: { expected_path: path },\n proposedFix: \"Run `bourdon copilot init` to create the convention directory.\",\n };\n }\n const memPath = join(path, MEMORY_FILENAME);\n if (!isFile(memPath)) {\n return {\n status: \"degraded\",\n reason:\n `Memory file ${memPath} not found. ` +\n \"Run `bourdon copilot init` to write a starter template.\",\n details: { expected_memory_file: memPath },\n proposedFix: \"Run `bourdon copilot init` to write the starter memory.md template.\",\n };\n }\n let data: Record<string, unknown>;\n try {\n data = this.read();\n } catch (err) {\n logger.warn(`CopilotParticipant health_check failed: ${String(err)}`);\n return {\n status: \"degraded\",\n reason: \"Memory file present but could not be parsed.\",\n details: { error: String(err) },\n proposedFix:\n `Inspect ${memPath} for malformed YAML front-matter. ` +\n \"The opening and closing `---` fences must wrap a valid YAML \" +\n \"block. See docs/agent-integration-status.md for the schema.\",\n };\n }\n return {\n status: \"ok\",\n details: {\n memory_file: memPath,\n entity_count: asArray(data[\"entities\"]).length,\n session_count: asArray(data[\"sessions\"]).length,\n },\n };\n }\n\n // -- Internal ---------------------------------------------------------------\n\n private read(): Record<string, unknown> {\n return readMemoryFile(defaultCopilotMemoryPath(this.copilotDir));\n }\n}\n\n// -- Init helper --------------------------------------------------------------\n\n/**\n * Create `~/.copilot-bourdon/memory.md` with a starter template. Returns the\n * written path. Throws when the file already exists unless `force` is true.\n */\nexport function initMemoryFile(copilotDir?: string | null, force = false): string {\n const targetDir = copilotDir || defaultCopilotBourdonDir();\n mkdirSync(targetDir, { recursive: true });\n const memPath = join(targetDir, MEMORY_FILENAME);\n if (isFile(memPath) && !force) {\n throw new Error(`${memPath} already exists. Pass --force to overwrite.`);\n }\n writeFileSync(memPath, MEMORY_TEMPLATE, \"utf8\");\n return memPath;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * GitHub Copilot CLI participant — normalize the `copilot` terminal agent's\n * SQLite session store into L5. Port of `participants/copilot_cli.py`.\n *\n * Copilot CLI stores session history in a SQLite database at\n * `~/.copilot/session-store.db` (override `$COPILOT_CLI_HOME`). This is distinct\n * from:\n * - the VS Code Copilot Chat extension (`github-copilot` network reader)\n * - the `~/.copilot-bourdon/memory.md` convention-file participant (`copilot`)\n * - GitHub-embedded Copilot (no local state)\n *\n * The schema (schema_version 4) carries `sessions` / `turns` / `checkpoints`\n * plus `session_files` / `session_refs` / `dynamic_context_items`. The reader\n * opens the DB read-only (`mode=ro` via {@link tryOpenReadonly}) so a live\n * writer's lock can never block the export, probes each table defensively (a\n * missing table degrades to \"no rows\" rather than raising), redacts every native\n * string, applies the visibility filter BEFORE emission, and is deterministic.\n * `healthCheck` never throws.\n */\n\nimport { statSync } from \"node:fs\";\nimport { homedir, hostname } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\nimport { tryOpenReadonly, type SqliteDatabase } from \"../sqlite-base.js\";\n\nconst AGENT_ID = \"copilot-cli\";\nconst AGENT_TYPE = \"code-assistant\";\nconst DISPLAY_NAME = \"GitHub Copilot CLI\";\nconst ROLE_NARRATIVE =\n \"Terminal-native Copilot agent with full filesystem + tool access. \" +\n \"Runs multi-turn sessions with checkpoints, file edits, and git \" +\n \"operations. The CLI surface has the deepest tool integration of \" +\n \"all Copilot surfaces — shell, grep, edit, git — and persists \" +\n \"rich session history locally in SQLite.\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"health\", \"family\", \"legal\"],\n team_tags: [\"copilot-cli\", \"copilot\", \"terminal\", \"workspace\"],\n});\n\nconst DB_FILENAME = \"session-store.db\";\nconst COPILOT_DIR_NAME = \".copilot\";\nconst MAX_SUMMARY_CHARS = 260;\nconst MAX_KEY_ACTIONS = 6;\nconst MAX_KEY_ACTION_CHARS = 280;\n\n// -- Path resolution ----------------------------------------------------------\n\n/**\n * Conventional `~/.copilot/` directory. Respects the `COPILOT_CLI_HOME`\n * environment-variable override (mirrors `default_copilot_cli_dir`).\n */\nexport function defaultCopilotCliDir(): string {\n const env = process.env.COPILOT_CLI_HOME;\n if (env) return env;\n return join(homedir(), COPILOT_DIR_NAME);\n}\n\n/** Path to `session-store.db` under the given (or conventional) copilot dir. */\nfunction defaultCopilotCliDbPath(copilotDir?: string | null): string {\n return join(copilotDir ?? defaultCopilotCliDir(), DB_FILENAME);\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\n// -- Text helpers -------------------------------------------------------------\n\n/** Redact secrets + clamp to the native-memory limit (`_safe_native_memory_text`). */\nfunction safeNativeMemoryText(value: string, limit = 180): string {\n return redactText(value, limit);\n}\n\n/**\n * Collapse whitespace and clamp with a single-char ellipsis (mirrors the\n * oracle's `_bounded`). NOTE: distinct from {@link redactText}'s `...` clamp —\n * this one uses `…` (U+2026) and does no redaction.\n */\nfunction bounded(value: string, limit: number): string {\n const normalized = value.split(/\\s+/).filter(Boolean).join(\" \");\n if (normalized.length <= limit) return normalized;\n return normalized.slice(0, limit - 1).replace(/\\s+$/, \"\") + \"…\";\n}\n\n// -- SQLite (read-only) -------------------------------------------------------\n\n/** Run a query and return rows as plain objects. Never raises (a missing table\n * or any SQLite error degrades to `[]`, matching the oracle's `_query_db`). */\nfunction queryDb(\n db: SqliteDatabase,\n sql: string,\n params: unknown[] = [],\n): Array<Record<string, unknown>> {\n try {\n return db.prepare(sql).all(...params) as Array<Record<string, unknown>>;\n } catch {\n return [];\n }\n}\n\nfunction extractSessions(db: SqliteDatabase, since?: string | null): Array<Record<string, unknown>> {\n let sql = \"SELECT id, cwd, repository, branch, summary, created_at, updated_at FROM sessions\";\n const params: unknown[] = [];\n if (since) {\n sql += \" WHERE created_at >= ?\";\n params.push(since);\n }\n sql += \" ORDER BY created_at DESC LIMIT 200\";\n return queryDb(db, sql, params);\n}\n\nfunction extractSessionFiles(db: SqliteDatabase, sessionId: string): string[] {\n const rows = queryDb(\n db,\n \"SELECT file_path FROM session_files WHERE session_id = ? LIMIT 20\",\n [sessionId],\n );\n const out: string[] = [];\n for (const r of rows) {\n const fp = r[\"file_path\"];\n if (fp) out.push(String(fp));\n }\n return out;\n}\n\nfunction extractSessionRefs(\n db: SqliteDatabase,\n sessionId: string,\n): Array<{ ref_type: string; ref_value: string }> {\n const rows = queryDb(\n db,\n \"SELECT ref_type, ref_value FROM session_refs WHERE session_id = ?\",\n [sessionId],\n );\n return rows.map((r) => ({\n ref_type: String(r[\"ref_type\"] ?? \"\"),\n ref_value: String(r[\"ref_value\"] ?? \"\"),\n }));\n}\n\nfunction extractCheckpoints(db: SqliteDatabase, sessionId: string): Array<Record<string, unknown>> {\n return queryDb(\n db,\n \"SELECT checkpoint_number, title, overview FROM checkpoints \" +\n \"WHERE session_id = ? ORDER BY checkpoint_number\",\n [sessionId],\n );\n}\n\nfunction extractDynamicContext(db: SqliteDatabase): Array<Record<string, unknown>> {\n return queryDb(\n db,\n \"SELECT repository, branch, src, name, description, content, read_count, count \" +\n \"FROM dynamic_context_items ORDER BY count DESC LIMIT 50\",\n );\n}\n\nfunction extractTurnCount(db: SqliteDatabase, sessionId: string): number {\n const rows = queryDb(db, \"SELECT COUNT(*) as cnt FROM turns WHERE session_id = ?\", [sessionId]);\n const first = rows[0];\n return first ? Number(first[\"cnt\"] ?? 0) || 0 : 0;\n}\n\n// -- Conversion to Bourdon types ----------------------------------------------\n\nfunction sessionToBourdon(\n raw: Record<string, unknown>,\n files: string[],\n refs: Array<{ ref_type: string; ref_value: string }>,\n checkpoints: Array<Record<string, unknown>>,\n turnCount: number,\n): SessionModel {\n const created = raw[\"created_at\"] ? String(raw[\"created_at\"]) : \"\";\n const dateStr = created ? created.slice(0, 10) : \"\";\n\n const keyActions: string[] = [];\n if (raw[\"summary\"]) {\n keyActions.push(bounded(safeNativeMemoryText(String(raw[\"summary\"])), MAX_KEY_ACTION_CHARS));\n }\n for (const cp of checkpoints.slice(0, 3)) {\n if (cp[\"title\"]) {\n keyActions.push(\n bounded(`checkpoint: ${safeNativeMemoryText(String(cp[\"title\"]))}`, MAX_KEY_ACTION_CHARS),\n );\n }\n }\n if (turnCount) {\n keyActions.push(`turns: ${turnCount}`);\n }\n for (const ref of refs.slice(0, 3)) {\n const refLabel = `${ref.ref_type}: ${ref.ref_value}`;\n keyActions.push(bounded(refLabel, MAX_KEY_ACTION_CHARS));\n }\n\n const projectFocus: string[] = [];\n if (raw[\"repository\"]) projectFocus.push(String(raw[\"repository\"]));\n\n return makeSession({\n date: dateStr,\n cwd: raw[\"cwd\"] ? String(raw[\"cwd\"]) : undefined,\n project_focus: projectFocus,\n key_actions: keyActions.slice(0, MAX_KEY_ACTIONS),\n files_touched: files.slice(0, 20),\n visibility: Visibility.TEAM,\n });\n}\n\nfunction entitiesFromSessionsAndContext(\n sessions: Array<Record<string, unknown>>,\n dynamicContext: Array<Record<string, unknown>>,\n): EntityModel[] {\n const entities = new Map<string, EntityModel>();\n\n // Repositories as project entities.\n for (const raw of sessions) {\n const repo = raw[\"repository\"] ? String(raw[\"repository\"]) : \"\";\n if (repo && !entities.has(repo)) {\n const created = raw[\"created_at\"] ? String(raw[\"created_at\"]) : \"\";\n const lastTouched = created.slice(0, 10) || null;\n entities.set(\n repo,\n makeEntity({\n name: repo,\n type: \"project\",\n summary: \"Repository worked on via Copilot CLI.\",\n last_touched: lastTouched ?? undefined,\n tags: [\"copilot-cli\", \"project\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n\n // Dynamic context items as knowledge entities.\n for (const ctx of dynamicContext) {\n const name = ctx[\"name\"] ? String(ctx[\"name\"]) : \"\";\n if (!name || entities.has(name)) continue;\n const desc = ctx[\"description\"] ? String(ctx[\"description\"]) : \"\";\n const content = ctx[\"content\"] ? String(ctx[\"content\"]) : \"\";\n let summaryText = desc || content;\n if (summaryText) {\n summaryText = bounded(safeNativeMemoryText(summaryText), MAX_SUMMARY_CHARS);\n }\n entities.set(\n name,\n makeEntity({\n name,\n type: \"dynamic-context\",\n summary: summaryText || undefined,\n last_touched: undefined,\n tags: [\"copilot-cli\", \"dynamic-context\", ctx[\"src\"] ? String(ctx[\"src\"]) : \"unknown\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n\n return [...entities.values()];\n}\n\n/** UTC ISO datetime with `+00:00` offset (matching Python `isoformat`). */\nfunction toUtcIso(d: Date): string {\n return d.toISOString().replace(/\\.\\d{3}Z$/, \"+00:00\").replace(/Z$/, \"+00:00\");\n}\n\n// -- Participant --------------------------------------------------------------\n\n/**\n * External participant for GitHub Copilot CLI (`~/.copilot/session-store.db`).\n * Reads the SQLite database read-only (never locks the live db).\n */\nexport class CopilotCliParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n displayName = DISPLAY_NAME;\n nativePath: string;\n\n private readonly copilotDir: string | null;\n\n /** Conventional `~/.copilot` dir used by the setup wizard's detection. */\n static defaultNativePath(home?: string): string {\n if (home) return join(home, COPILOT_DIR_NAME);\n return defaultCopilotCliDir();\n }\n\n constructor(copilotDir?: string) {\n this.copilotDir = copilotDir ?? null;\n this.nativePath = this.copilotDir ?? defaultCopilotCliDir();\n }\n\n // -- Protocol surface -------------------------------------------------------\n\n discover(): AgentStore {\n const dbPath = defaultCopilotCliDbPath(this.copilotDir);\n if (!isFile(dbPath)) {\n throw new ParticipantDiscoveryError(\n `Copilot CLI session-store.db not found at ${dbPath}. ` +\n \"The Copilot CLI agent must be run at least once to create this database.\",\n );\n }\n let dbSize = 0;\n try {\n dbSize = statSync(dbPath).size;\n } catch {\n dbSize = 0;\n }\n return {\n path: dirname(dbPath),\n version: \"schema-v4\",\n metadata: { db_path: dbPath, db_size_bytes: dbSize },\n };\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const dbPath = defaultCopilotCliDbPath(this.copilotDir);\n const db = tryOpenReadonly(dbPath);\n if (!db) return [];\n try {\n const sinceIso = since ? toUtcIso(since) : null;\n const rawSessions = extractSessions(db, sinceIso);\n const sessions: SessionModel[] = [];\n for (const raw of rawSessions.slice(0, limit)) {\n const sid = String(raw[\"id\"]);\n const files = extractSessionFiles(db, sid);\n const refs = extractSessionRefs(db, sid);\n const checkpoints = extractCheckpoints(db, sid);\n const turnCount = extractTurnCount(db, sid);\n sessions.push(sessionToBourdon(raw, files, refs, checkpoints, turnCount));\n }\n return sessions;\n } finally {\n db.close();\n }\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const dbPath = defaultCopilotCliDbPath(this.copilotDir);\n const db = tryOpenReadonly(dbPath);\n if (!db) return this.emptyManifest();\n try {\n const sinceIso = since ? toUtcIso(since) : null;\n const rawSessions = extractSessions(db, sinceIso);\n const dynamicContext = extractDynamicContext(db);\n\n const sessions: SessionModel[] = [];\n for (const raw of rawSessions.slice(0, 100)) {\n const sid = String(raw[\"id\"]);\n const files = extractSessionFiles(db, sid);\n const refs = extractSessionRefs(db, sid);\n const checkpoints = extractCheckpoints(db, sid);\n const turnCount = extractTurnCount(db, sid);\n sessions.push(sessionToBourdon(raw, files, refs, checkpoints, turnCount));\n }\n\n const entities = entitiesFromSessionsAndContext(rawSessions, dynamicContext);\n const visibleEntities = filterForFederation(entities, DEFAULT_POLICY);\n\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: hostname() || \"unknown\",\n spec_version_compat: `>=${SPEC_VERSION}`,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: new Date().toISOString(),\n capabilities: [\n \"terminal-agent\",\n \"file-edit\",\n \"shell-execution\",\n \"git-operations\",\n \"multi-turn-sessions\",\n \"checkpoints\",\n \"dynamic-context\",\n ],\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: DEFAULT_POLICY,\n });\n } finally {\n db.close();\n }\n }\n\n healthCheck(): HealthStatus {\n try {\n const copilotDir = this.copilotDir ?? defaultCopilotCliDir();\n if (!isDir(copilotDir)) {\n return {\n status: \"blocked\",\n reason: `Copilot CLI directory not found at ${copilotDir}.`,\n details: { expected_path: copilotDir },\n proposedFix:\n \"Run the Copilot CLI agent (`copilot` or `gh copilot`) at least once \" +\n \"to create the session store.\",\n };\n }\n const dbPath = defaultCopilotCliDbPath(copilotDir);\n if (!isFile(dbPath)) {\n return {\n status: \"blocked\",\n reason: `session-store.db not found at ${dbPath}.`,\n details: { expected_db: dbPath },\n proposedFix:\n \"Run the Copilot CLI agent at least once. The session-store.db is \" +\n \"created on first use.\",\n };\n }\n const db = tryOpenReadonly(dbPath);\n if (!db) {\n return {\n status: \"degraded\",\n reason: \"Cannot copy session-store.db for reading.\",\n details: { db_path: dbPath },\n proposedFix: \"Check file permissions on the session-store.db.\",\n };\n }\n try {\n const rawSessions = extractSessions(db);\n const dynamicContext = extractDynamicContext(db);\n const totalTurns = queryDb(db, \"SELECT COUNT(*) as cnt FROM turns\");\n const first = totalTurns[0];\n let dbSize = 0;\n try {\n dbSize = statSync(dbPath).size;\n } catch {\n dbSize = 0;\n }\n return {\n status: \"ok\",\n details: {\n db_path: dbPath,\n db_size_bytes: dbSize,\n session_count: rawSessions.length,\n total_turns: first ? Number(first[\"cnt\"] ?? 0) || 0 : 0,\n dynamic_context_items: dynamicContext.length,\n },\n };\n } finally {\n db.close();\n }\n } catch (err) {\n // healthCheck must NEVER raise (contract).\n return {\n status: \"degraded\",\n reason: `unexpected error: ${String(err)}`,\n details: {},\n };\n }\n }\n\n // -- Internal ---------------------------------------------------------------\n\n private emptyManifest(): L5ManifestModel {\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: hostname() || \"unknown\",\n spec_version_compat: `>=${SPEC_VERSION}`,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: new Date().toISOString(),\n capabilities: [],\n recent_sessions: [],\n known_entities: [],\n visibility_policy: DEFAULT_POLICY,\n });\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Cascade (Windsurf) participant — convention-file reader. Port of\n * `participants/cascade.py`.\n *\n * Cascade's internal state is not exposed on the filesystem in a standardized\n * format (like cloud Copilot). Instead this participant uses a CONVENTION FILE:\n * Cascade maintains a structured memory file at `~/.cascade-bourdon/memory.md`\n * with YAML front-matter carrying `entities` + `sessions`. Cascade owns that\n * projection explicitly (it writes what it knows at session end); the\n * participant normalizes the front-matter into an L5 manifest for federation.\n *\n * Privacy: entity/session summaries pass through the redaction SSOT; the\n * visibility policy (private_tags) filters PRIVATE entities before emission.\n */\n\nimport { mkdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { parse as yamlParse } from \"yaml\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { REDACTED, SENSITIVE_PATTERNS, redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\n\n// -- Constants -----------------------------------------------------------------\n\nconst AGENT_ID = \"cascade\";\nconst AGENT_TYPE = \"code-assistant\";\nconst DISPLAY_NAME = \"Cascade (Windsurf)\";\nconst ROLE_NARRATIVE =\n \"Agentic AI coding assistant embedded in Windsurf IDE. \" +\n \"Operates with multi-step planning, tool use (file editing, terminal, \" +\n \"browser preview, code search), persistent memory, and workspace-level \" +\n \"context awareness. Specializes in pair-programming workflows with \" +\n \"concurrent read-plan-execute cycles.\";\n\nconst CONVENTION_DIR_NAME = \".cascade-bourdon\";\nconst MEMORY_FILENAME = \"memory.md\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.PUBLIC,\n private_tags: [\"personal\", \"credential\", \"financial\", \"secret\", \"private\"],\n});\n\n/**\n * The native-memory sensitive-pattern set, extended with Cascade-specific\n * triggers (`secret`, `sk_test_*`). A match anywhere drops the WHOLE string to\n * the redaction sentinel (see {@link scrubCredential}). All non-global so they\n * are safe to reuse across `.test()`.\n */\nconst CASCADE_SENSITIVE_PATTERNS: readonly RegExp[] = [\n ...SENSITIVE_PATTERNS,\n /\\bsecret\\b/i,\n /sk[_-]test[_-]/i,\n];\n\n/** Minimal logger so a malformed-frontmatter warning is visible without a dep. */\nconst logger = {\n warn(msg: string): void {\n // eslint-disable-next-line no-console\n console.warn(`[bourdon.participants] ${msg}`);\n },\n};\n\n// -- Path helpers --------------------------------------------------------------\n\nfunction homeDir(): string {\n // os.homedir() can throw under some sandboxes; stay defensive so import +\n // construction never crash even when HOME points at an unreadable path.\n try {\n return homedir();\n } catch {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n }\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\n/** Return the default Cascade-Bourdon convention directory (`~/.cascade-bourdon`). */\nexport function defaultCascadeDir(): string {\n return join(homeDir(), CONVENTION_DIR_NAME);\n}\n\n/** Return the default path to the Cascade memory file. */\nexport function defaultCascadeMemoryPath(): string {\n return join(defaultCascadeDir(), MEMORY_FILENAME);\n}\n\n// -- Front-matter --------------------------------------------------------------\n\n/**\n * Extract YAML front-matter from a `---` fenced block. Returns an empty object\n * when the text has no valid front-matter. On YAML parse failure logs at WARNING\n * (with the source path when provided) and treats it as no-frontmatter.\n *\n * NOTE: this is the Cascade-specific fence parse (`startswith(\"---\")` +\n * `find(\"---\", 3)`), distinct from the claude-code reader's `---\\n` variant —\n * preserved faithfully from the oracle.\n */\nfunction parseFrontmatter(text: string, source?: string): Record<string, unknown> {\n if (!text.startsWith(\"---\")) return {};\n const end = text.indexOf(\"---\", 3);\n if (end === -1) return {};\n const yamlBlock = text.slice(3, end).trim();\n if (!yamlBlock) return {};\n let data: unknown;\n try {\n data = yamlParse(yamlBlock);\n } catch (exc) {\n const where = source ? ` in ${source}` : \"\";\n const detail = String(exc).replace(/\\n/g, \" \").slice(0, 200);\n logger.warn(\n `CascadeParticipant: malformed YAML frontmatter${where}; ` +\n `treating as no-frontmatter (${detail})`,\n );\n return {};\n }\n return typeof data === \"object\" && data !== null && !Array.isArray(data)\n ? (data as Record<string, unknown>)\n : {};\n}\n\n// -- Redaction -----------------------------------------------------------------\n\n/**\n * Redact + truncate native-memory text. Same semantics as the codex reader's\n * `_safe_native_memory_text` (the redaction SSOT), extended with Cascade-\n * specific patterns (`secret`, `sk_test_*`): if any match, drop the whole string\n * to the redaction sentinel; otherwise scrub + cap via {@link redactText}.\n */\nfunction scrubCredential(text: string): string {\n if (!text) return text;\n if (CASCADE_SENSITIVE_PATTERNS.some((p) => p.test(text))) {\n return REDACTED;\n }\n return redactText(text);\n}\n\n// -- Builders ------------------------------------------------------------------\n\n/** Python `list(x or [])`: copy a list verbatim, char-split a string, else []. */\nfunction asList(v: unknown): string[] {\n if (!v) return [];\n if (Array.isArray(v)) return v as string[];\n if (typeof v === \"string\") return Array.from(v);\n return [];\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/** Build an Entity from a raw front-matter dict entry. Returns null on invalid. */\nfunction buildEntity(raw: unknown): EntityModel | null {\n if (!isRecord(raw)) return null;\n const name = raw[\"name\"];\n if (typeof name !== \"string\" || !name.trim()) return null;\n\n let summary: string | undefined;\n const rawSummary = raw[\"summary\"];\n if (typeof rawSummary === \"string\") summary = scrubCredential(rawSummary);\n\n return makeEntity({\n name: name.trim(),\n type: typeof raw[\"type\"] === \"string\" ? (raw[\"type\"] as string) : undefined,\n summary,\n aliases: asList(raw[\"aliases\"]),\n tags: asList(raw[\"tags\"]),\n last_touched: raw[\"last_touched\"] ? String(raw[\"last_touched\"]) : undefined,\n valid_from: raw[\"valid_from\"] ? String(raw[\"valid_from\"]) : undefined,\n valid_to: raw[\"valid_to\"] ? String(raw[\"valid_to\"]) : undefined,\n visibility: undefined,\n });\n}\n\n/** Build a Session from a raw front-matter dict entry. Returns null on invalid. */\nfunction buildSession(raw: unknown): SessionModel | null {\n if (!isRecord(raw)) return null;\n const dateVal = raw[\"date\"];\n if (!dateVal) return null;\n // Normalize datetime strings to date-only (YYYY-MM-DD).\n const dateStr = String(dateVal).slice(0, 10);\n\n return makeSession({\n date: dateStr,\n cwd: raw[\"cwd\"] == null ? undefined : (raw[\"cwd\"] as string),\n key_actions: asList(raw[\"key_actions\"]),\n files_touched: asList(raw[\"files_touched\"]),\n project_focus: asList(raw[\"project_focus\"]),\n visibility: undefined,\n });\n}\n\n/**\n * Mirror `datetime.fromisoformat(date)` on a date-only string for the `since`\n * filter. Returns the UTC midnight Date, or null on a ValueError-equivalent\n * (the caller keeps the session when this is null, matching `except ValueError`).\n */\nfunction parseSessionDate(date: string): Date | null {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(date)) return null;\n const ms = Date.parse(`${date}T00:00:00Z`);\n return Number.isNaN(ms) ? null : new Date(ms);\n}\n\nfunction buildSessions(rawSessions: unknown, since?: Date): SessionModel[] {\n const list = Array.isArray(rawSessions) ? rawSessions : [];\n const sessions: SessionModel[] = [];\n for (const raw of list) {\n const session = buildSession(raw);\n if (session === null) continue;\n if (since !== undefined) {\n const d = parseSessionDate(session.date);\n if (d !== null && d.getTime() < since.getTime()) continue;\n }\n sessions.push(session);\n }\n return sessions;\n}\n\n// -- Diagnostics ---------------------------------------------------------------\n\n/** Diagnostic inspection of the Cascade memory file: presence + content stats. */\nfunction inspectCascadeMemory(cascadeDir: string): Record<string, unknown> {\n const memoryPath = join(cascadeDir, MEMORY_FILENAME);\n if (!isFile(memoryPath)) return { present: false, error: \"missing\" };\n\n let text: string;\n try {\n text = readFileSync(memoryPath, \"utf8\");\n } catch (e) {\n return { present: true, readable: false, error: String(e) };\n }\n\n const data = parseFrontmatter(text, memoryPath);\n if (Object.keys(data).length === 0) {\n return {\n present: true,\n readable: true,\n frontmatter_valid: false,\n entity_count: 0,\n session_count: 0,\n };\n }\n\n const entities = data[\"entities\"];\n const sessions = data[\"sessions\"];\n return {\n present: true,\n readable: true,\n frontmatter_valid: true,\n entity_count: Array.isArray(entities) ? entities.length : 0,\n session_count: Array.isArray(sessions) ? sessions.length : 0,\n };\n}\n\n// -- Init helper ---------------------------------------------------------------\n\nconst MEMORY_TEMPLATE = `---\nentities:\n - name: Example Project\n type: project\n summary: Replace with real project summaries\n tags: [project]\nsessions:\n - date: \"{today}\"\n cwd: /path/to/workspace\n key_actions:\n - Initialized Cascade Bourdon memory\n files_touched: []\n project_focus: []\n---\n\n# Cascade Bourdon Memory\n\nThis file is maintained by Cascade (Windsurf) for cross-agent memory federation.\nEdit the YAML front-matter to update entities and sessions.\nCascade will update this file at session end when instructed.\n`;\n\n/**\n * Create a starter memory.md in the Cascade-Bourdon convention directory.\n *\n * @param cascadeDir Override the convention directory (default `~/.cascade-bourdon`).\n * @param force Overwrite an existing file; otherwise throws.\n * @returns the path to the created memory file.\n */\nexport function initMemoryFile(cascadeDir?: string, force = false): string {\n const targetDir = cascadeDir ?? defaultCascadeDir();\n mkdirSync(targetDir, { recursive: true });\n const memoryPath = join(targetDir, MEMORY_FILENAME);\n\n if (isFile(memoryPath) && !force) {\n throw new Error(\n `Memory file already exists: ${memoryPath}. Use force=True to overwrite.`,\n );\n }\n\n const today = new Date().toISOString().slice(0, 10);\n const content = MEMORY_TEMPLATE.replace(\"{today}\", today);\n writeFileSync(memoryPath, content, \"utf8\");\n return memoryPath;\n}\n\n// -- Participant ---------------------------------------------------------------\n\n/**\n * Convention-based Bourdon participant for Cascade (Windsurf). Reads structured\n * memory from `~/.cascade-bourdon/memory.md` and normalizes it into L5.\n */\nexport class CascadeParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n displayName = DISPLAY_NAME;\n\n private readonly dir: string;\n private readonly policy: VisibilityPolicyModel;\n\n static defaultNativePath(home?: string): string {\n if (home !== undefined) return join(home, CONVENTION_DIR_NAME);\n return defaultCascadeDir();\n }\n\n constructor(cascadeDir?: string, policy?: VisibilityPolicyModel) {\n this.dir = cascadeDir ?? defaultCascadeDir();\n this.policy = policy ?? DEFAULT_POLICY;\n }\n\n /** Path to the Cascade-Bourdon convention directory. */\n get nativePath(): string {\n return this.dir;\n }\n\n private memoryPath(): string {\n return join(this.dir, MEMORY_FILENAME);\n }\n\n private readFrontmatter(): Record<string, unknown> {\n const path = this.memoryPath();\n if (!isFile(path)) return {};\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch {\n return {};\n }\n return parseFrontmatter(text, path);\n }\n\n discover(): AgentStore {\n if (!isDir(this.dir)) {\n throw new ParticipantDiscoveryError(\n `Cascade-Bourdon directory not found: ${this.dir}`,\n );\n }\n const memoryPresent = isFile(this.memoryPath());\n return {\n path: this.dir,\n version: \"unknown\",\n metadata: {\n memory_file: this.memoryPath(),\n memory_file_present: memoryPresent,\n },\n };\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const data = this.readFrontmatter();\n\n // Build entities.\n const rawEntities = data[\"entities\"];\n const entityList = Array.isArray(rawEntities) ? rawEntities : [];\n const entities: EntityModel[] = [];\n for (const raw of entityList) {\n const entity = buildEntity(raw);\n if (entity !== null) entities.push(entity);\n }\n\n // Build sessions (since-filtered).\n const sessions = buildSessions(data[\"sessions\"], since);\n\n // Apply visibility policy — filter out PRIVATE entities before emission.\n const visibleEntities = filterForFederation(entities, this.policy);\n\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: new Date().toISOString(),\n known_entities: visibleEntities,\n recent_sessions: sessions,\n capabilities: [\"chat\", \"code-editing\", \"terminal\", \"planning\", \"search\"],\n });\n }\n\n exportSessions(since?: Date, limit?: number): SessionModel[] {\n const data = this.readFrontmatter();\n const sessions = buildSessions(data[\"sessions\"], since);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n if (limit !== undefined) return sessions.slice(0, limit);\n return sessions;\n }\n\n healthCheck(): HealthStatus {\n if (!isDir(this.dir)) {\n return {\n status: \"blocked\",\n reason: \"Cascade-Bourdon directory not found\",\n details: { expected_path: this.dir },\n proposedFix:\n \"Run `bourdon cascade init` to create the convention directory + starter memory.md.\",\n };\n }\n\n const report = inspectCascadeMemory(this.dir);\n if (!report[\"present\"]) {\n return {\n status: \"degraded\",\n reason: \"Memory file not found; run `bourdon cascade init` to create it\",\n details: report,\n proposedFix:\n \"Run `bourdon cascade init` to write the starter memory.md template.\",\n };\n }\n\n if (!report[\"readable\"]) {\n return {\n status: \"degraded\",\n reason: `Memory file not readable: ${String(report[\"error\"])}`,\n details: report,\n proposedFix:\n `Check filesystem permissions on ${join(this.dir, \"memory.md\")} ` +\n \"(should be readable by your user).\",\n };\n }\n\n if (!report[\"frontmatter_valid\"]) {\n return {\n status: \"degraded\",\n reason: \"Memory file has no valid YAML front-matter\",\n details: report,\n proposedFix:\n `Inspect ${join(this.dir, \"memory.md\")} -- the opening and closing ` +\n \"`---` fences must wrap a valid YAML block. Run \" +\n \"`bourdon cascade init --force` to reset to the template \" +\n \"(WARNING: this overwrites existing content).\",\n };\n }\n\n return {\n status: \"ok\",\n details: report,\n };\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * OpenClaw participant — network-shaped, QUARANTINED-CLASS. Port of\n * `participants/openclaw.py` (v0.9.0, spec R4/D9).\n *\n * OpenClaw is the highest-demand adapter target in the ecosystem and also its\n * highest-risk agent class: CVE-2026-25253 (one-click RCE, CVSS 8.8, first\n * patched in 2026.1.29), tens of thousands of internet-exposed instances (~93%\n * without authentication), ClawHub's malicious-skill problem, and auth disabled\n * by default on port 8080. Bourdon therefore treats OpenClaw differently from\n * every on-disk participant:\n *\n * 1. **Network-shaped** — state is read from the OpenClaw instance's local\n * HTTP API, not on-disk artifacts. Because the {@link BourdonParticipant}\n * contract is SYNCHRONOUS (`discover`/`exportL5` return values, not\n * Promises) and `fetch` is async, the reads go through a tiny synchronous\n * `curl` shell-out (the same idiom as the github-copilot reader).\n * 2. **Hard handshake gate** — {@link OpenClawParticipant.discover} refuses to\n * talk to an instance that is unpatched (< 2026.1.29) or has authentication\n * disabled. These are refusals with exact reasons AND fixes, not warnings,\n * and every read re-runs the gate.\n * 3. **Quarantined-class** — `quarantinedClass = true`: registering the agent\n * trusted requires `--i-understand-the-risk`, and exports stage for\n * operator review (spec D6: quarantine follows the content, not the\n * invoker). Its content federates under TEAM, never PUBLIC.\n *\n * We gate on instance hygiene (version, auth) — NOT on auditing the user's\n * installed skills; that's ClawSecure et al.'s job (spec non-goal 3).\n */\n\nimport { execFileSync } from \"node:child_process\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\n\n// -- Constants -----------------------------------------------------------------\n\nconst AGENT_ID = \"openclaw\";\nconst AGENT_TYPE = \"other\";\nconst DISPLAY_NAME = \"OpenClaw (quarantined)\";\nconst ROLE_NARRATIVE =\n \"OpenClaw personal AI assistant — federated as a QUARANTINED member: \" +\n \"its reads are limited to granted namespaces and its writes are staged \" +\n \"for operator review.\";\n\n/** First OpenClaw release that patches CVE-2026-25253 (one-click RCE). */\nexport const MIN_PATCHED_VERSION = \"2026.1.29\";\n\nconst DEFAULT_OPENCLAW_URL = \"http://127.0.0.1:8080\";\n\nconst SESSION_LIMIT = 50;\nconst ENTITY_LIMIT = 100;\n\n// -- Helpers -------------------------------------------------------------------\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/**\n * `_safe_native_memory_text(v)` in Python == `redact_text(v, limit=180)`. The\n * TS redaction SSOT exposes `redactText(value, limit = 180)` (positional), so\n * we pass the cap explicitly to make the surface's 180-char limit load-bearing.\n */\nfunction safeNativeMemoryText(value: string): string {\n return redactText(value, 180);\n}\n\n/**\n * `\"2026.1.29\"` -> `[2026, 1, 29]`. Tolerates suffixes like `\"2026.1.29-beta\"`;\n * returns null when nothing numeric parses. Faithful port of `_parse_version`.\n */\nfunction parseVersion(value: string): number[] | null {\n const parts: number[] = [];\n for (const chunk of String(value ?? \"\").trim().split(\".\")) {\n const match = /^(\\d+)/.exec(chunk);\n if (!match) break;\n parts.push(Number(match[1]));\n }\n return parts.length > 0 ? parts : null;\n}\n\n/** Tuple comparison mirroring Python's `tuple < tuple` (lexicographic, shorter\n * is smaller when it is a prefix). */\nfunction versionLessThan(a: number[], b: number[]): boolean {\n const n = Math.max(a.length, b.length);\n for (let i = 0; i < n; i += 1) {\n const av = i < a.length ? (a[i] as number) : undefined;\n const bv = i < b.length ? (b[i] as number) : undefined;\n if (av === undefined) return true; // a is a shorter prefix of b\n if (bv === undefined) return false; // b is a shorter prefix of a\n if (av < bv) return true;\n if (av > bv) return false;\n }\n return false;\n}\n\n/** `_status_version`: first non-empty of version / openclaw_version / app_version. */\nfunction statusVersion(status: Record<string, unknown>): string {\n for (const key of [\"version\", \"openclaw_version\", \"app_version\"]) {\n const value = status[key];\n if (typeof value === \"string\" && value.trim()) return value.trim();\n }\n return \"\";\n}\n\n/** `_status_auth_enabled`: auth_enabled / authEnabled / auth.enabled. */\nfunction statusAuthEnabled(status: Record<string, unknown>): boolean {\n for (const key of [\"auth_enabled\", \"authEnabled\"]) {\n if (key in status) return Boolean(status[key]);\n }\n const auth = status[\"auth\"];\n if (isRecord(auth)) return Boolean(auth[\"enabled\"]);\n return false;\n}\n\n/**\n * Hard handshake preconditions (spec D9). Returns the version on success.\n * Raises {@link ParticipantDiscoveryError} with the exact reason AND the fix —\n * these are refusals, not warnings.\n */\nexport function verifyInstance(status: Record<string, unknown>, url: string): string {\n const version = statusVersion(status);\n const parsed = parseVersion(version);\n const minimum = parseVersion(MIN_PATCHED_VERSION) as number[];\n if (parsed === null) {\n throw new ParticipantDiscoveryError(\n `OpenClaw at ${url} did not report a parseable version ` +\n `(got ${JSON.stringify(version)}). Refusing handshake: cannot verify the ` +\n `CVE-2026-25253 patch level. Fix: upgrade OpenClaw to ` +\n `>= ${MIN_PATCHED_VERSION} and ensure /api/status reports it.`,\n );\n }\n if (versionLessThan(parsed, minimum)) {\n throw new ParticipantDiscoveryError(\n `OpenClaw at ${url} runs ${version}, which predates the ` +\n `CVE-2026-25253 patch (one-click RCE, CVSS 8.8). Refusing ` +\n `handshake. Fix: upgrade OpenClaw to >= ${MIN_PATCHED_VERSION}.`,\n );\n }\n if (!statusAuthEnabled(status)) {\n throw new ParticipantDiscoveryError(\n `OpenClaw at ${url} has authentication DISABLED (the exposed-` +\n \"instance default). Refusing handshake. Fix: enable auth in \" +\n \"your OpenClaw config (set auth.enabled=true / OPENCLAW_AUTH=1), \" +\n \"restart the instance, and set OPENCLAW_TOKEN for Bourdon.\",\n );\n }\n return version;\n}\n\n/**\n * Mirror `_before`: return true when `dateText` is strictly before `since`.\n * Reproduces `datetime.fromisoformat(dateText.replace(\"Z\",\"+00:00\"))` with the\n * naive→UTC coercion, and returns false on a parse (ValueError) miss so the\n * caller keeps the session.\n */\nfunction before(dateText: string, since: Date): boolean {\n const parsed = fromIsoformatUtc(dateText.replace(/Z/g, \"+00:00\"));\n if (parsed === null) return false; // ValueError -> keep\n return parsed.getTime() < since.getTime();\n}\n\n/**\n * A best-effort `datetime.fromisoformat` for the two shapes OpenClaw emits\n * (date-only and datetime, with or without an offset). A naive value (no\n * offset) is interpreted as UTC — matching the Python `parsed.replace(\n * tzinfo=timezone.utc)`. Returns null on an unparseable value.\n */\nfunction fromIsoformatUtc(text: string): Date | null {\n const value = text.trim();\n if (!value) return null;\n const hasOffset = /[+-]\\d{2}:?\\d{2}$/.test(value);\n // date-only ISO is already interpreted as UTC midnight by Date.parse;\n // a naive datetime (\"...T..\") must be pinned to UTC with a trailing Z.\n const normalized = hasOffset || !value.includes(\"T\") ? value : `${value}Z`;\n const ms = Date.parse(normalized);\n return Number.isNaN(ms) ? null : new Date(ms);\n}\n\n/** Python `str(now_utc, \"%Y-%m-%dT%H:%M:%SZ\")` — second precision, Z suffix. */\nfunction nowIsoSeconds(): string {\n return new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\");\n}\n\n// -- HTTP ----------------------------------------------------------------------\n\ninterface CurlResponse {\n status: number;\n body: string;\n}\n\n/**\n * Synchronous GET via a tiny `curl` shell-out — the base contract is\n * synchronous (matching the Python `urllib` reference), so `fetch` cannot be\n * used. `-w` appends the HTTP status on a trailing sentinel line for parsing.\n * Throws when curl itself fails (connection refused / timeout / DNS), which the\n * caller maps to \"instance unreachable\".\n */\nfunction curlGet(url: string, token: string | undefined, timeoutSec: number): CurlResponse {\n const args = [\"-sS\", \"-o\", \"-\", \"--max-time\", String(timeoutSec)];\n if (token) {\n args.push(\"-H\", `Authorization: Bearer ${token}`);\n }\n args.push(\"-w\", \"\\n__BOURDON_STATUS__%{http_code}\", url);\n\n const raw = execFileSync(\"curl\", args, {\n encoding: \"utf8\",\n timeout: (timeoutSec + 2) * 1000,\n maxBuffer: 8 * 1024 * 1024,\n });\n\n const statusMatch = /\\n__BOURDON_STATUS__(\\d+)$/.exec(raw);\n const status = statusMatch ? Number(statusMatch[1]) : 0;\n const body = statusMatch ? raw.slice(0, statusMatch.index) : raw;\n return { status, body };\n}\n\n/**\n * Minimal HTTP client for a local OpenClaw instance. Read-only: status,\n * sessions, memories. Failures raise {@link ParticipantDiscoveryError} with the\n * reason — the participant decides how to surface them.\n *\n * Error mapping (faithful to the Python `urllib` client): an HTTP >= 400\n * response -> \"returned HTTP {code}\"; a transport failure / timeout / non-JSON\n * body -> \"instance unreachable at {url}\".\n */\nexport class OpenClawApiClient {\n readonly url: string;\n private readonly token: string | undefined;\n readonly timeout: number;\n\n constructor(url: string, token?: string, timeout = 5.0) {\n this.url = url.replace(/\\/+$/, \"\");\n this.token = token;\n this.timeout = timeout;\n }\n\n private get(path: string): unknown {\n let resp: CurlResponse;\n try {\n resp = curlGet(this.url + path, this.token, this.timeout);\n } catch (err) {\n throw new ParticipantDiscoveryError(\n `OpenClaw instance unreachable at ${this.url} (${String(err)})`,\n );\n }\n if (resp.status >= 400) {\n throw new ParticipantDiscoveryError(\n `OpenClaw API ${path} returned HTTP ${resp.status}`,\n );\n }\n if (resp.status === 0) {\n throw new ParticipantDiscoveryError(\n `OpenClaw instance unreachable at ${this.url} (no HTTP response)`,\n );\n }\n try {\n return JSON.parse(resp.body);\n } catch (err) {\n throw new ParticipantDiscoveryError(\n `OpenClaw instance unreachable at ${this.url} (${String(err)})`,\n );\n }\n }\n\n status(): Record<string, unknown> {\n const data = this.get(\"/api/status\");\n return isRecord(data) ? data : {};\n }\n\n sessions(): Record<string, unknown>[] {\n return this.readCollection(\"/api/sessions\", \"sessions\");\n }\n\n memories(): Record<string, unknown>[] {\n return this.readCollection(\"/api/memories\", \"memories\");\n }\n\n /** Shared `sessions()`/`memories()` body: try/except-returns-[], unwrap the\n * `{ \"<key>\": [...] }` envelope, and keep only object rows. */\n private readCollection(path: string, key: string): Record<string, unknown>[] {\n let data: unknown;\n try {\n data = this.get(path);\n } catch (err) {\n if (err instanceof ParticipantDiscoveryError) return [];\n throw err;\n }\n if (isRecord(data)) {\n data = data[key] || [];\n }\n if (!Array.isArray(data)) return [];\n return data.filter(isRecord);\n }\n}\n\n// -- Participant ---------------------------------------------------------------\n\n/** Bourdon participant for OpenClaw (quarantined class). */\nexport class OpenClawParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n displayName = DISPLAY_NAME;\n /** Trust marker consumed by `bourdon agent add/set-tier` + export-all:\n * registering as trusted needs --i-understand-the-risk; exports stage. */\n quarantinedClass = true;\n\n readonly url: string;\n private readonly client: OpenClawApiClient;\n\n static defaultNativePath(home?: string): string {\n // Network-shaped: shown in the wizard for orientation only. The actual\n // store is the instance API (OPENCLAW_URL).\n return join(home ?? homedir(), \".openclaw\");\n }\n\n constructor(url?: string, token?: string, client?: OpenClawApiClient) {\n this.url = (url || process.env.OPENCLAW_URL || DEFAULT_OPENCLAW_URL).replace(/\\/+$/, \"\");\n this.client = client ?? new OpenClawApiClient(this.url, token ?? process.env.OPENCLAW_TOKEN);\n }\n\n get nativePath(): string {\n return this.url;\n }\n\n // -- protocol ----------------------------------------------------------------\n\n discover(): AgentStore {\n const status = this.client.status();\n const version = verifyInstance(status, this.url);\n return {\n path: this.url,\n version,\n metadata: { auth_enabled: true, transport: \"http\" },\n };\n }\n\n exportSessions(since?: Date, limit: number = SESSION_LIMIT): SessionModel[] {\n this.discover(); // handshake gate applies to every read\n const sessions: SessionModel[] = [];\n for (const row of this.client.sessions()) {\n const date = String(row[\"updated_at\"] || row[\"started_at\"] || row[\"date\"] || \"\").trim();\n if (!date) continue;\n if (since !== undefined && before(date, since)) continue;\n const title = safeNativeMemoryText(String(row[\"title\"] || row[\"summary\"] || \"\"));\n const projects = Array.isArray(row[\"projects\"]) ? row[\"projects\"].slice(0, 5) : [];\n sessions.push(\n makeSession({\n date,\n cwd: undefined,\n project_focus: projects.map((p) => safeNativeMemoryText(String(p))),\n key_actions: title ? [title] : [],\n }),\n );\n if (sessions.length >= limit) break;\n }\n return sessions;\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const store = this.discover();\n const entities: EntityModel[] = [];\n for (const row of this.client.memories().slice(0, ENTITY_LIMIT)) {\n const name = safeNativeMemoryText(String(row[\"name\"] || row[\"title\"] || \"\"));\n if (!name) continue;\n const tags = Array.isArray(row[\"tags\"]) ? row[\"tags\"].slice(0, 8) : [];\n entities.push(\n makeEntity({\n name,\n type: String(row[\"type\"] || \"topic\"),\n summary: safeNativeMemoryText(String(row[\"summary\"] || \"\")),\n tags: tags.map((t) => safeNativeMemoryText(String(t))),\n }),\n );\n }\n // Quarantined-class content defaults to TEAM, never PUBLIC: it only\n // federates beyond the local library after an explicit operator promotion\n // AND a team-level read.\n const policy: VisibilityPolicyModel = makeVisibilityPolicy({ default: Visibility.TEAM });\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: this.url,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: nowIsoSeconds(),\n capabilities: [`openclaw ${store.version}`],\n recent_sessions: this.exportSessions(since),\n known_entities: filterForFederation(entities, policy),\n visibility_policy: policy,\n });\n }\n\n healthCheck(): HealthStatus {\n let store: AgentStore;\n try {\n store = this.discover();\n } catch (exc) {\n if (exc instanceof ParticipantDiscoveryError) {\n const reason = exc.message;\n let fix = \"see the refusal reason above\";\n if (reason.includes(\"upgrade OpenClaw\")) {\n fix = `upgrade the OpenClaw instance to >= ${MIN_PATCHED_VERSION}`;\n } else if (reason.includes(\"authentication DISABLED\")) {\n fix = \"enable auth on the OpenClaw instance, then set OPENCLAW_TOKEN\";\n } else if (reason.includes(\"unreachable\")) {\n fix =\n \"start OpenClaw locally or set OPENCLAW_URL to the instance address\";\n }\n return { status: \"blocked\", reason, proposedFix: fix, details: {} };\n }\n // health_check must never raise.\n return {\n status: \"degraded\",\n reason: exc instanceof Error ? exc.message : String(exc),\n details: {},\n };\n }\n return {\n status: \"ok\",\n details: { url: this.url, version: store.version, quarantined: true },\n };\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Claude Code automations participant — publishes background-run memory as L5\n * evidence. Port of `participants/claude_code_automations.py`.\n *\n * Convention-file reader over the `~/.claude/automations/<id>/` tree:\n * automation.toml — id, name, status, schedule (rrule), kind, cwds\n * memory.md — dated bullet entries, one block per run\n *\n * Each `automation.toml` becomes a known Entity (`type: automation`); each dated\n * section of `memory.md` becomes a recent Session. Mirrors the Codex automation\n * publisher — it covers the federation gap that the interactive-only\n * `claude-code` participant leaves behind (automations whose work never touches\n * agent-brain / auto-memory / the MCP knowledge graph).\n *\n * Privacy: every native string routes through the redaction SSOT\n * (`redactText`, == the oracle's `_safe_native_memory_text`); the visibility\n * policy filters PRIVATE entities before emission. `healthCheck` never throws.\n */\n\nimport {\n mkdirSync,\n readdirSync,\n readFileSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir, hostname } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport { parse as parseToml } from \"smol-toml\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n loadProjectHints,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\n\n// -- Constants -----------------------------------------------------------------\n\nconst AGENT_ID = \"claude-code-automations\";\nconst AGENT_TYPE = \"other\";\nconst ROLE_NARRATIVE =\n \"Publishes read-only Claude Code automation run memory into Bourdon so \" +\n \"scheduled /loop continuations, CronCreate jobs, GitHub Action runs of \" +\n \"claude-code-action, and /schedule remote-routine summaries become \" +\n \"visible alongside interactive Claude Code sessions.\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"health\", \"family\", \"legal\"],\n team_tags: [\"claude-code-automation\", \"automation\", \"workspace\"],\n});\n\nconst AUTOMATIONS_DIR_NAME = \"automations\";\nconst AUTOMATION_TOML = \"automation.toml\";\nconst MEMORY_MD = \"memory.md\";\nconst MAX_MEMORY_CHARS = 160_000;\nconst MAX_KEY_ACTIONS_PER_RUN = 6;\nconst MAX_KEY_ACTION_CHARS = 280;\n\n/** `^(\\d{4}-\\d{2}-\\d{2})(?:\\b|$)(.*)$` — anchored, non-global (safe to reuse). */\nconst RUN_HEADER_RE = /^(\\d{4}-\\d{2}-\\d{2})(?:\\b|$)(.*)$/;\nconst BULLET_RE = /^[-*]\\s+(.*)$/;\n/** Chars stripped from a run-header suffix (space, hyphen, colon, em-dash). */\nconst HEADER_SUFFIX_STRIP = \" -:—\";\n\n// Product-neutral defaults only: this product plus the agent surfaces Bourdon\n// federates. A deployment adds its own project roster via the\n// `BOURDON_PROJECT_HINTS` env var (comma-separated) — see `loadProjectHints`.\nconst DEFAULT_PROJECT_HINTS: readonly string[] = [\n \"Bourdon\",\n \"Cursor\",\n \"Copilot\",\n \"Codex\",\n \"Cascade\",\n];\n\n/** Signal-class name → case-insensitive, NON-GLOBAL matcher. */\nconst SIGNAL_PATTERNS: ReadonlyArray<readonly [string, RegExp]> = [\n [\"human-dashboard-action\", /\\b(human|dashboard|manual)\\b/i],\n [\"release-gate\", /\\b(release|store|app review|play console|testflight)\\b/i],\n [\"billing-drift\", /\\b(billing|stripe|revenuecat|iap|subscription)\\b/i],\n [\"memory-coverage-gap\", /\\b(memory|l5|manifest|federated|bourdon)\\b/i],\n [\"launch-decision\", /\\b(launch|go-live|pricing|prod|production)\\b/i],\n [\"ci-signal\", /\\b(github action|workflow run|ci failure|gh action)\\b/i],\n];\n\n/** Minimal logger so a degraded read is visible without pulling in a dep. */\nconst logger = {\n warn(msg: string): void {\n // eslint-disable-next-line no-console\n console.warn(`[bourdon.participants] ${msg}`);\n },\n};\n\n// -- Types ---------------------------------------------------------------------\n\ninterface AutomationConfig {\n automationId: string;\n name: string;\n status: string;\n rrule: string;\n kind: string;\n cwds: string[];\n /** Path to the automation.toml file. */\n path: string;\n /** Path to memory.md, or null when it is not a regular file. */\n memoryPath: string | null;\n}\n\ninterface AutomationRun {\n automation: AutomationConfig;\n date: string;\n title: string;\n keyActions: string[];\n projects: string[];\n signals: string[];\n}\n\n/** Summary of a {@link mergeAutomationTree} call. */\nexport interface MergeResult {\n automationsSeen: number;\n automationsCreated: number;\n bulletsAdded: number;\n sectionsCreated: number;\n skipped: string[];\n}\n\n// -- fs helpers ----------------------------------------------------------------\n\nfunction homeDir(): string {\n // os.homedir() can throw under some sandboxes; stay defensive so import +\n // construction never crash even when HOME points at an unreadable path.\n try {\n return homedir();\n } catch {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n }\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\nfunction exists(p: string): boolean {\n try {\n statSync(p);\n return true;\n } catch {\n return false;\n }\n}\n\n// -- Python-semantic string helpers -------------------------------------------\n\n/** Python truthiness for the value kinds YAML/TOML yield here. */\nfunction truthy(v: unknown): boolean {\n if (v === undefined || v === null || v === false || v === 0 || v === \"\") return false;\n if (Array.isArray(v)) return v.length > 0;\n if (typeof v === \"object\") return Object.keys(v as object).length > 0;\n return true;\n}\n\n/** Mirror Python `str(value)` for the scalar types encountered here. */\nfunction pyStr(v: unknown): string {\n if (v === true) return \"True\";\n if (v === false) return \"False\";\n if (v === null || v === undefined) return \"None\";\n return String(v);\n}\n\n/** Mirror `str(a or b)` — pick `a` if truthy else `b`, then `str()`. */\nfunction strOr(a: unknown, b: unknown): string {\n return pyStr(truthy(a) ? a : b);\n}\n\n/** Python `str.rstrip()` — drop trailing whitespace. */\nfunction rstrip(s: string): string {\n return s.replace(/\\s+$/, \"\");\n}\n\n/** Python `str.strip(chars)` — strip any of `chars` from both ends. */\nfunction stripChars(s: string, chars: string): string {\n let start = 0;\n let end = s.length;\n while (start < end && chars.includes(s[start]!)) start++;\n while (end > start && chars.includes(s[end - 1]!)) end--;\n return s.slice(start, end);\n}\n\n/** Approximate Python `str.splitlines()` (no trailing empty for a final EOL). */\nfunction splitLines(s: string): string[] {\n const parts = s.split(/\\r\\n|\\r|\\n/);\n if (parts.length > 0 && parts[parts.length - 1] === \"\") parts.pop();\n return parts;\n}\n\n// -- Path resolution -----------------------------------------------------------\n\n/**\n * Default Claude Code automations directory. Precedence:\n * 1. explicit `claudeHome` argument (tests)\n * 2. `CLAUDE_HOME` env var\n * 3. `~/.claude/` (conventional per-user default)\n */\nexport function defaultClaudeCodeAutomationsDir(claudeHome?: string): string {\n if (claudeHome !== undefined) return join(claudeHome, AUTOMATIONS_DIR_NAME);\n const env = process.env.CLAUDE_HOME;\n if (env) return join(env, AUTOMATIONS_DIR_NAME);\n return join(homeDir(), \".claude\", AUTOMATIONS_DIR_NAME);\n}\n\n// -- TOML config parsing -------------------------------------------------------\n\nfunction readAutomationToml(path: string): Record<string, unknown> {\n let raw: unknown;\n try {\n raw = parseToml(readFileSync(path, \"utf8\"));\n } catch (exc) {\n logger.warn(\n `ClaudeCodeAutomationsParticipant: cannot parse ${path}: ${String(exc)}`,\n );\n return {};\n }\n return typeof raw === \"object\" && raw !== null && !Array.isArray(raw)\n ? (raw as Record<string, unknown>)\n : {};\n}\n\nfunction buildConfig(tomlPath: string): AutomationConfig | null {\n const raw = readAutomationToml(tomlPath);\n const parent = dirname(tomlPath);\n const parentName = basenameOf(parent);\n\n const automationId = strOr(raw[\"id\"], parentName).trim();\n if (!automationId) return null;\n\n const name = strOr(raw[\"name\"], automationId).trim();\n const status = strOr(raw[\"status\"], \"UNKNOWN\").trim().toUpperCase();\n const rrule = strOr(raw[\"rrule\"], \"\").trim();\n const kind = strOr(raw[\"kind\"], \"\").trim();\n\n const cwdsRaw: unknown = truthy(raw[\"cwds\"]) ? raw[\"cwds\"] : [];\n const cwds: string[] = [];\n // Faithful to `for cwd in cwds_raw if isinstance(cwd, str) and cwd.strip()`:\n // arrays iterate elements, a string iterates characters. Other (non-iterable)\n // types yield no cwds here (the oracle would raise; see port notes).\n if (Array.isArray(cwdsRaw)) {\n for (const cwd of cwdsRaw) {\n if (typeof cwd === \"string\" && cwd.trim()) cwds.push(cwd);\n }\n } else if (typeof cwdsRaw === \"string\") {\n for (const ch of cwdsRaw) {\n if (ch.trim()) cwds.push(ch);\n }\n }\n\n const memoryPath = join(parent, MEMORY_MD);\n return {\n automationId,\n name,\n status,\n rrule,\n kind,\n cwds,\n path: tomlPath,\n memoryPath: isFile(memoryPath) ? memoryPath : null,\n };\n}\n\n/** `os.path.basename` that also handles a trailing separator like Path.name. */\nfunction basenameOf(p: string): string {\n const cleaned = p.replace(/[/\\\\]+$/, \"\");\n const idx = Math.max(cleaned.lastIndexOf(\"/\"), cleaned.lastIndexOf(\"\\\\\"));\n return idx === -1 ? cleaned : cleaned.slice(idx + 1);\n}\n\nfunction iterConfigs(automationsDir: string): AutomationConfig[] {\n const configs: AutomationConfig[] = [];\n if (!isDir(automationsDir)) return configs;\n // Mirror `sorted(dir.glob(\"*/automation.toml\"))`: one directory level deep,\n // sorted by full path (== sorted by subdir name given the shared prefix).\n const tomlPaths: string[] = [];\n let entries: string[];\n try {\n entries = readdirSync(automationsDir);\n } catch {\n return configs;\n }\n for (const entry of entries) {\n const sub = join(automationsDir, entry);\n if (!isDir(sub)) continue;\n const tomlPath = join(sub, AUTOMATION_TOML);\n if (isFile(tomlPath)) tomlPaths.push(tomlPath);\n }\n tomlPaths.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n for (const tomlPath of tomlPaths) {\n const config = buildConfig(tomlPath);\n if (config !== null) configs.push(config);\n }\n return configs;\n}\n\n// -- memory.md → runs ----------------------------------------------------------\n\nfunction readMemoryText(path: string | null): string {\n if (path === null) return \"\";\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch (exc) {\n logger.warn(\n `ClaudeCodeAutomationsParticipant: cannot read ${path}: ${String(exc)}`,\n );\n return \"\";\n }\n return text.slice(-MAX_MEMORY_CHARS);\n}\n\nfunction extractMemoryRuns(config: AutomationConfig): AutomationRun[] {\n const text = readMemoryText(config.memoryPath);\n if (!text) return [];\n\n const chunks: Array<[string, string[]]> = [];\n let currentDate = \"\";\n let currentLines: string[] = [];\n for (const rawLine of splitLines(text)) {\n const line = rstrip(rawLine);\n const match = RUN_HEADER_RE.exec(line.trim());\n if (match) {\n if (currentDate) chunks.push([currentDate, currentLines]);\n currentDate = match[1]!;\n const suffix = stripChars(match[2] ?? \"\", HEADER_SUFFIX_STRIP);\n currentLines = suffix ? [suffix] : [];\n continue;\n }\n if (currentDate) currentLines.push(line);\n }\n if (currentDate) chunks.push([currentDate, currentLines]);\n\n const runs: AutomationRun[] = [];\n for (const [runDate, lines] of chunks) {\n const actions = actionsFromLines(lines);\n if (actions.length === 0) continue;\n const body = actions.join(\" \");\n const title = titleFromActions(config, actions);\n runs.push({\n automation: config,\n date: runDate,\n title,\n keyActions: actions,\n projects: inferProjects(body),\n signals: inferSignals(body),\n });\n }\n return runs;\n}\n\nfunction actionsFromLines(lines: string[]): string[] {\n const actions: string[] = [];\n for (const line of lines) {\n let cleaned = line.trim();\n if (!cleaned) continue;\n cleaned = removePrefix(cleaned, \"- \").trim();\n const lowered = cleaned.toLowerCase();\n if (!cleaned || lowered.startsWith(\"runtime\")) continue;\n if (lowered === \"first run\" || lowered === \"follow-up\") continue;\n if (lowered.startsWith(\"run:\")) cleaned = cleaned.slice(4).trim();\n const safe = bounded(safeNativeMemoryText(cleaned), MAX_KEY_ACTION_CHARS);\n if (safe && !actions.includes(safe)) actions.push(safe);\n if (actions.length >= MAX_KEY_ACTIONS_PER_RUN) break;\n }\n return actions;\n}\n\n/** Python `str.removeprefix`. */\nfunction removePrefix(s: string, prefix: string): string {\n return s.startsWith(prefix) ? s.slice(prefix.length) : s;\n}\n\n/** The oracle's `_safe_native_memory_text(v)` == `redactText(v, 180)`. */\nfunction safeNativeMemoryText(value: string): string {\n return redactText(value, 180);\n}\n\nfunction titleFromActions(config: AutomationConfig, actions: string[]): string {\n if (actions.length === 0) return config.name;\n const first = actions[0]!;\n const prefix = `${config.name}: `;\n if (first.startsWith(prefix)) return bounded(first, 120);\n return bounded(prefix + first, 120);\n}\n\nfunction inferProjects(text: string): string[] {\n const projects: string[] = [];\n const lowered = text.toLowerCase();\n const seen = new Set<string>();\n for (const project of loadProjectHints(DEFAULT_PROJECT_HINTS)) {\n const key = project.toLowerCase();\n if (lowered.includes(key) && !seen.has(key)) {\n projects.push(project);\n seen.add(key);\n }\n }\n return projects;\n}\n\nfunction inferSignals(text: string): string[] {\n const signals: string[] = [];\n for (const [name, pattern] of SIGNAL_PATTERNS) {\n if (pattern.test(text)) signals.push(name);\n }\n return signals;\n}\n\n/** `\" \".join(value.split())`, then cap at `limit` with a `...` tail (limit-1). */\nfunction bounded(value: string, limit: number): string {\n const normalized = value.trim().replace(/\\s+/g, \" \");\n if (normalized.length <= limit) return normalized;\n return rstrip(normalized.slice(0, limit - 1)) + \"...\";\n}\n\n// -- run → session / entities --------------------------------------------------\n\nfunction sessionFromRun(run: AutomationRun): SessionModel {\n const config = run.automation;\n const keyActions = [\n `automation_id: ${config.automationId}`,\n `run: ${run.title}`,\n ...run.keyActions,\n ];\n const filesTouched = [config.path];\n if (config.memoryPath !== null) filesTouched.push(config.memoryPath);\n return makeSession({\n date: run.date,\n cwd: config.cwds.length > 0 ? config.cwds[0] : dirname(config.path),\n project_focus: [...run.projects],\n key_actions: keyActions.slice(0, MAX_KEY_ACTIONS_PER_RUN + 2),\n files_touched: filesTouched,\n visibility: Visibility.TEAM,\n });\n}\n\nfunction entitiesFromConfigsAndRuns(\n configs: AutomationConfig[],\n runs: AutomationRun[],\n): EntityModel[] {\n // Insertion-ordered map (Python dict) — configs first, then run projects +\n // signals via setdefault (first-wins).\n const byName = new Map<string, EntityModel>();\n\n for (const config of configs) {\n byName.set(\n config.automationId,\n makeEntity({\n name: config.automationId,\n type: \"automation\",\n summary: bounded(\n `Claude Code automation '${config.name}' (${config.status}). ` +\n `Schedule: ${config.rrule || \"unspecified\"}.`,\n 260,\n ),\n last_touched: undefined,\n tags: [\"claude-code-automation\", \"automation\", config.status.toLowerCase()],\n visibility: Visibility.TEAM,\n }),\n );\n }\n\n for (const run of runs) {\n for (const project of run.projects) {\n if (!byName.has(project)) {\n byName.set(\n project,\n makeEntity({\n name: project,\n type: \"project\",\n summary: \"Project mentioned by Claude Code automation run memory.\",\n last_touched: run.date,\n tags: [\"claude-code-automation\", \"automation-evidence\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n for (const signal of run.signals) {\n if (!byName.has(signal)) {\n byName.set(\n signal,\n makeEntity({\n name: signal,\n type: \"automation-signal\",\n summary: \"Signal class inferred from Claude Code automation run memory.\",\n last_touched: run.date,\n tags: [\"claude-code-automation\", \"automation-signal\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n }\n return [...byName.values()];\n}\n\n// -- memory.md section merge (ingestion utility) -------------------------------\n\n/**\n * Split memory.md text into `[date_header, bullets]` sections. Tolerates\n * `2026-06-03`, `2026-06-03 -- subtitle`, and same-line `2026-06-03 run: ...`.\n * Content before the first date header is discarded.\n */\nfunction parseMemorySections(text: string): Array<[string, string[]]> {\n const sections: Array<[string, string[]]> = [];\n let currentDate = \"\";\n let currentBullets: string[] = [];\n for (const rawLine of splitLines(text)) {\n const line = rstrip(rawLine);\n const match = RUN_HEADER_RE.exec(line.trim());\n if (match) {\n if (currentDate) sections.push([currentDate, currentBullets]);\n currentDate = match[1]!;\n const suffix = stripChars(match[2] ?? \"\", HEADER_SUFFIX_STRIP);\n currentBullets = [];\n if (suffix) currentBullets.push(suffix);\n continue;\n }\n if (!currentDate) continue;\n const bulletMatch = BULLET_RE.exec(line.trim());\n if (bulletMatch) currentBullets.push((bulletMatch[1] ?? \"\").trim());\n }\n if (currentDate) sections.push([currentDate, currentBullets]);\n return sections;\n}\n\n/** Render `[date, bullets]` sections back to memory.md form. */\nfunction serializeSections(sections: Array<[string, string[]]>): string {\n const blocks: string[] = [];\n for (const [dateStr, bullets] of sections) {\n const lines = [dateStr, ...bullets.map((b) => `- ${b}`)];\n blocks.push(lines.join(\"\\n\"));\n }\n return blocks.join(\"\\n\\n\") + \"\\n\";\n}\n\nconst AUTOMATION_ID_RE = /^[A-Za-z0-9._-]+$/;\n\n/**\n * Merge an `automations/<id>/` tree from `sourceDir` into `destDir`. Copies new\n * automations wholesale (stubbing automation.toml when absent) and merges\n * memory.md bullets per-date (exact-string dedupe). Idempotent. Designed for\n * ingesting GitHub Action workflow artifacts.\n */\nexport function mergeAutomationTree(\n sourceDir: string,\n destDir: string,\n defaultKind = \"github-action\",\n): MergeResult {\n if (!isDir(sourceDir)) {\n throw new Error(`merge source not found: ${sourceDir}`);\n }\n mkdirSync(destDir, { recursive: true });\n\n let seen = 0;\n let created = 0;\n let bulletsAdded = 0;\n let sectionsCreated = 0;\n const skipped: string[] = [];\n\n const srcEntries = readdirSync(sourceDir).sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n for (const entry of srcEntries) {\n const srcIdDir = join(sourceDir, entry);\n if (!isDir(srcIdDir)) continue;\n seen += 1;\n const automationId = entry;\n if (!AUTOMATION_ID_RE.test(automationId)) {\n skipped.push(automationId);\n continue;\n }\n\n const destIdDir = join(destDir, automationId);\n const srcToml = join(srcIdDir, AUTOMATION_TOML);\n const srcMemory = join(srcIdDir, MEMORY_MD);\n\n if (!exists(destIdDir)) {\n mkdirSync(destIdDir, { recursive: true });\n created += 1;\n if (isFile(srcToml)) {\n writeFileSync(join(destIdDir, AUTOMATION_TOML), readFileSync(srcToml, \"utf8\"), \"utf8\");\n } else {\n writeFileSync(\n join(destIdDir, AUTOMATION_TOML),\n `version = 1\\n` +\n `id = \"${automationId}\"\\n` +\n `name = \"${automationId}\"\\n` +\n `status = \"ACTIVE\"\\n` +\n `kind = \"${defaultKind}\"\\n` +\n `rrule = \"\"\\n` +\n `cwds = []\\n`,\n \"utf8\",\n );\n }\n }\n\n if (!isFile(srcMemory)) continue;\n\n const srcSections = parseMemorySections(readFileSync(srcMemory, \"utf8\"));\n const destMemory = join(destIdDir, MEMORY_MD);\n const destSections: Array<[string, string[]]> = isFile(destMemory)\n ? parseMemorySections(readFileSync(destMemory, \"utf8\"))\n : [];\n // `dict(dest_sections)` — last-wins on duplicate dates; the list refs are\n // shared with destSections so appends via `existing` are reflected.\n const destByDate = new Map<string, string[]>();\n for (const [dateStr, bullets] of destSections) destByDate.set(dateStr, bullets);\n\n for (const [dateStr, bullets] of srcSections) {\n if (!destByDate.has(dateStr)) {\n const fresh: string[] = [];\n destByDate.set(dateStr, fresh);\n destSections.push([dateStr, fresh]);\n sectionsCreated += 1;\n }\n const existing = destByDate.get(dateStr)!;\n for (const bullet of bullets) {\n if (!existing.includes(bullet)) {\n existing.push(bullet);\n bulletsAdded += 1;\n }\n }\n }\n\n destSections.sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0));\n writeFileSync(destMemory, serializeSections(destSections), \"utf8\");\n }\n\n return {\n automationsSeen: seen,\n automationsCreated: created,\n bulletsAdded,\n sectionsCreated,\n skipped,\n };\n}\n\n// -- Participant ---------------------------------------------------------------\n\n/** External participant for Claude Code automation memory artifacts. */\nexport class ClaudeCodeAutomationsParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n nativePath: string;\n\n private readonly automationsDir: string;\n private readonly policy: VisibilityPolicyModel;\n\n /**\n * Conventional Claude Code automations dir (`~/.claude/automations`). Provided\n * for protocol uniformity — the setup wizard wires the parent `claude-code`\n * participant and skips `-automations` sub-surfaces.\n */\n static defaultNativePath(home?: string): string {\n return defaultClaudeCodeAutomationsDir(home);\n }\n\n constructor(automationsDir?: string, claudeHome?: string) {\n this.automationsDir = automationsDir ?? defaultClaudeCodeAutomationsDir(claudeHome);\n this.nativePath = this.automationsDir;\n this.policy = DEFAULT_POLICY;\n }\n\n discover(): AgentStore {\n if (!isDir(this.automationsDir)) {\n throw new ParticipantDiscoveryError(\n `Claude Code automations directory not found at ${this.automationsDir}.`,\n );\n }\n const configs = iterConfigs(this.automationsDir);\n return {\n path: this.automationsDir,\n version: \"unknown\",\n metadata: {\n automations: configs.length,\n with_memory: configs.filter((c) => c.memoryPath !== null).length,\n },\n };\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const sessions = this.runs(undefined, since).map(sessionFromRun);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n return sessions.slice(0, limit);\n }\n\n exportL5(since?: Date): L5ManifestModel {\n if (!isDir(this.automationsDir)) {\n throw new ParticipantDiscoveryError(\n `Claude Code automations directory not found at ${this.automationsDir}.`,\n );\n }\n const configs = iterConfigs(this.automationsDir);\n const runs = this.runs(configs, since);\n const sessions = runs.map(sessionFromRun);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n const entities = entitiesFromConfigsAndRuns(configs, runs);\n const visibleEntities = filterForFederation(entities, this.policy);\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: hostname(),\n spec_version_compat: SPEC_VERSION,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: new Date().toISOString(),\n capabilities: [\"claude-code-automation-memory\", \"run-summary-publication\"],\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: this.policy,\n });\n }\n\n healthCheck(): HealthStatus {\n if (!isDir(this.automationsDir)) {\n return {\n status: \"blocked\",\n reason: `Claude Code automations directory not found at ${this.automationsDir}.`,\n details: { automations_dir: this.automationsDir },\n proposedFix:\n \"Create the automations directory and an automation.toml: \" +\n \"mkdir -p ~/.claude/automations/<id> && \" +\n \"$HOME/.claude/hooks/automation-memory-append.sh <id> '...'\",\n };\n }\n const configs = iterConfigs(this.automationsDir);\n const runs = this.runs(configs);\n const hasConfigs = configs.length > 0;\n const status: HealthStatus[\"status\"] = hasConfigs ? \"ok\" : \"degraded\";\n const details = {\n automations_dir: this.automationsDir,\n automation_count: configs.length,\n memory_files: configs.filter((c) => c.memoryPath !== null).length,\n runs_extracted: runs.length,\n active_automations: configs.filter((c) => c.status === \"ACTIVE\").length,\n };\n if (hasConfigs) {\n return { status, details };\n }\n return {\n status,\n reason: \"No automation.toml files found.\",\n details,\n proposedFix: \"Add Claude Code automation.toml files.\",\n };\n }\n\n private runs(configs?: AutomationConfig[], since?: Date): AutomationRun[] {\n const runCutoff = since ? since.toISOString().slice(0, 10) : null;\n const runs: AutomationRun[] = [];\n for (const config of configs ?? iterConfigs(this.automationsDir)) {\n for (const run of extractMemoryRuns(config)) {\n if (runCutoff && run.date < runCutoff) continue;\n runs.push(run);\n }\n }\n runs.sort((a, b) => {\n if (a.date !== b.date) return a.date < b.date ? 1 : -1;\n const ai = a.automation.automationId;\n const bi = b.automation.automationId;\n if (ai !== bi) return ai < bi ? 1 : -1;\n return 0;\n });\n return runs;\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Codex automations participant — publishes read-only Codex background/automation\n * run memory into Bourdon as L5 evidence. Port of\n * `participants/codex_automations.py`.\n *\n * Store convention (NOT SQLite, NOT network): a CONVENTION-FILE directory tree at\n * `~/.codex/automations/<id>/`, each holding an `automation.toml` config and an\n * optional `memory.md` run log. The reader parses the TOML config and extracts\n * dated \"runs\" from the markdown memory, normalizing them into L5 sessions +\n * entities (the automation itself, plus inferred projects and signal classes).\n *\n * Source-resolution order for the automations dir:\n * 1. explicit `automationsDir` constructor arg\n * 2. `codexHome` constructor arg → `<codexHome>/automations`\n * 3. `CODEX_HOME` env-var → `$CODEX_HOME/automations`\n * 4. `~/.codex/automations` (default convention path)\n *\n * Privacy: every native string routes through the redaction SSOT\n * (`redactText(v, 180)` == the oracle's `_safe_native_memory_text`); the\n * visibility policy filters PRIVATE entities before emission. Defensive\n * throughout — a missing dir raises {@link ParticipantDiscoveryError} from\n * `discover()`, malformed TOML/markdown degrades to empty rather than raising,\n * and `healthCheck` never throws.\n *\n * NOTE: does NOT depend on the full codex reader — only the redaction helper it\n * imports (`_safe_native_memory_text`, reproduced inline as {@link safeNativeMemoryText}).\n */\n\nimport { readFileSync, readdirSync, statSync } from \"node:fs\";\nimport { homedir, hostname } from \"node:os\";\nimport { basename, dirname, join } from \"node:path\";\n\nimport { parse as tomlParse } from \"smol-toml\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n loadProjectHints,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\n\n// -- Constants -----------------------------------------------------------------\n\nconst AGENT_ID = \"codex-automations\";\nconst AGENT_TYPE = \"other\";\nconst ROLE_NARRATIVE =\n \"Publishes read-only Codex automation run memory into Bourdon so background \" +\n \"monitors, digests, and recurring checks are visible alongside interactive \" +\n \"agent sessions.\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"health\", \"family\", \"legal\"],\n team_tags: [\"codex-automation\", \"automation\", \"workspace\"],\n});\n\nconst AUTOMATIONS_DIR_NAME = \"automations\";\nconst AUTOMATION_TOML = \"automation.toml\";\nconst MEMORY_MD = \"memory.md\";\nconst MAX_MEMORY_CHARS = 160_000;\nconst MAX_KEY_ACTIONS_PER_RUN = 6;\nconst MAX_KEY_ACTION_CHARS = 280;\nconst RUN_HEADER_RE = /^(\\d{4}-\\d{2}-\\d{2})(?:\\b|$)(.*)$/;\n// Product-neutral defaults only: this product plus the agent surfaces Bourdon\n// federates. A deployment adds its own project roster via the\n// `BOURDON_PROJECT_HINTS` env var (comma-separated) — see `loadProjectHints`.\nconst DEFAULT_PROJECT_HINTS: readonly string[] = [\"Bourdon\", \"Cursor\", \"Copilot\"];\nconst SIGNAL_PATTERNS: readonly (readonly [string, RegExp])[] = [\n [\"human-dashboard-action\", /\\b(human|dashboard|manual)\\b/i],\n [\"release-gate\", /\\b(release|store|app review|play console|testflight)\\b/i],\n [\"billing-drift\", /\\b(billing|stripe|revenuecat|iap|subscription)\\b/i],\n [\"memory-coverage-gap\", /\\b(memory|l5|manifest|federated|bourdon)\\b/i],\n [\"launch-decision\", /\\b(launch|go-live|pricing|prod|production)\\b/i],\n];\n\n/** Minimal logger so a degraded parse is visible without pulling in a dep. */\nconst logger = {\n warn(msg: string): void {\n // eslint-disable-next-line no-console\n console.warn(`[bourdon.participants] ${msg}`);\n },\n};\n\n// -- Data records --------------------------------------------------------------\n\ninterface AutomationConfig {\n automationId: string;\n name: string;\n status: string;\n rrule: string;\n kind: string;\n cwds: string[];\n path: string;\n /** memory.md path, or null when absent. */\n memoryPath: string | null;\n}\n\ninterface AutomationRun {\n automation: AutomationConfig;\n date: string;\n title: string;\n keyActions: string[];\n projects: string[];\n signals: string[];\n}\n\n// -- fs helpers ----------------------------------------------------------------\n\nfunction homeDir(): string {\n // os.homedir() can throw under some sandboxes; stay defensive so import +\n // construction never crash even when HOME points at an unreadable path.\n try {\n return homedir();\n } catch {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n }\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\n// -- Path resolution -----------------------------------------------------------\n\n/** Return the default Codex automations directory (source-resolution order). */\nexport function defaultCodexAutomationsDir(codexHome?: string): string {\n if (codexHome !== undefined && codexHome !== null) {\n return join(codexHome, AUTOMATIONS_DIR_NAME);\n }\n const env = process.env.CODEX_HOME;\n if (env) return join(env, AUTOMATIONS_DIR_NAME);\n return join(homeDir(), \".codex\", AUTOMATIONS_DIR_NAME);\n}\n\n// -- Redaction -----------------------------------------------------------------\n\n/**\n * Thin wrapper over the redaction SSOT (the oracle's `_safe_native_memory_text`,\n * `redact_text(value, limit=180)`).\n */\nfunction safeNativeMemoryText(value: string): string {\n return redactText(value, 180);\n}\n\n// -- Coercion helpers (mirror Python str() / truthiness) -----------------------\n\n/** Mirror Python `str(a or b)`: use `a` when truthy, else `b`, then stringify. */\nfunction pyStrOr(a: unknown, b: string): string {\n return String(a ? a : b);\n}\n\n// -- TOML config ---------------------------------------------------------------\n\n/** Read + parse an automation.toml. Returns {} on any I/O or parse error. */\nfunction readAutomationToml(path: string): Record<string, unknown> {\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch (exc) {\n logger.warn(`CodexAutomationsParticipant: cannot parse ${path}: ${String(exc)}`);\n return {};\n }\n try {\n const parsed = tomlParse(text) as unknown;\n return typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : {};\n } catch (exc) {\n logger.warn(`CodexAutomationsParticipant: cannot parse ${path}: ${String(exc)}`);\n return {};\n }\n}\n\n/** Build an AutomationConfig from a toml path. Returns null on an empty id. */\nfunction buildConfig(tomlPath: string): AutomationConfig | null {\n const raw = readAutomationToml(tomlPath);\n const parentName = basename(dirname(tomlPath));\n\n const automationId = pyStrOr(raw[\"id\"], parentName).trim();\n if (!automationId) return null;\n\n const name = pyStrOr(raw[\"name\"], automationId).trim();\n const status = pyStrOr(raw[\"status\"], \"UNKNOWN\").trim().toUpperCase();\n const rrule = pyStrOr(raw[\"rrule\"], \"\").trim();\n const kind = pyStrOr(raw[\"kind\"], \"\").trim();\n\n const cwdsRaw = raw[\"cwds\"];\n const cwds: string[] = Array.isArray(cwdsRaw)\n ? cwdsRaw.filter((cwd): cwd is string => typeof cwd === \"string\" && cwd.trim() !== \"\")\n : [];\n\n const memoryPath = join(dirname(tomlPath), MEMORY_MD);\n return {\n automationId,\n name,\n status,\n rrule,\n kind,\n cwds,\n path: tomlPath,\n memoryPath: isFile(memoryPath) ? memoryPath : null,\n };\n}\n\n/**\n * Enumerate the `<id>/automation.toml` files, sorted (mirrors Python's sorted-glob).\n * The varying path segment is the immediate sub-directory, so sorting the\n * resulting toml paths reproduces the oracle's ordering.\n */\nfunction iterConfigs(automationsDir: string): AutomationConfig[] {\n if (!isDir(automationsDir)) return [];\n let entries: string[];\n try {\n entries = readdirSync(automationsDir);\n } catch {\n return [];\n }\n const tomlPaths: string[] = [];\n for (const entry of entries) {\n const tomlPath = join(automationsDir, entry, AUTOMATION_TOML);\n if (isFile(tomlPath)) tomlPaths.push(tomlPath);\n }\n tomlPaths.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n const configs: AutomationConfig[] = [];\n for (const tomlPath of tomlPaths) {\n const config = buildConfig(tomlPath);\n if (config !== null) configs.push(config);\n }\n return configs;\n}\n\n// -- Memory extraction ---------------------------------------------------------\n\n/** Read the memory file, returning at most the last MAX_MEMORY_CHARS characters. */\nfunction readMemoryText(path: string | null): string {\n if (path === null) return \"\";\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch (exc) {\n logger.warn(`CodexAutomationsParticipant: cannot read ${path}: ${String(exc)}`);\n return \"\";\n }\n return text.length > MAX_MEMORY_CHARS ? text.slice(-MAX_MEMORY_CHARS) : text;\n}\n\n/** Split into lines the way Python's str.splitlines() does (best-effort). */\nfunction splitLines(text: string): string[] {\n // Python splitlines includes ASCII record separators; this explicit set preserves parity.\n // eslint-disable-next-line no-control-regex\n return text.split(/\\r\\n|[\\n\\r\\u000B\\u000C\\u001C\\u001D\\u001E\\u0085\\u2028\\u2029]/u);\n}\n\n/** Python `str.rstrip()` — strip trailing whitespace only. */\nfunction rstrip(s: string): string {\n return s.replace(/\\s+$/, \"\");\n}\n\n/** Python `\" \".join(value.split())` — collapse all whitespace runs. */\nfunction collapseWhitespace(value: string): string {\n return value\n .split(/\\s+/)\n .filter((p) => p.length > 0)\n .join(\" \");\n}\n\n/** Port of `_bounded`: collapse whitespace then cap with a `...` ellipsis. */\nfunction bounded(value: string, limit: number): string {\n const normalized = collapseWhitespace(value);\n if (normalized.length <= limit) return normalized;\n return rstrip(normalized.slice(0, limit - 1)) + \"...\";\n}\n\nfunction actionsFromLines(lines: string[]): string[] {\n const actions: string[] = [];\n for (const line of lines) {\n let cleaned = line.trim();\n if (!cleaned) continue;\n cleaned = (cleaned.startsWith(\"- \") ? cleaned.slice(2) : cleaned).trim();\n const lowered = cleaned.toLowerCase();\n if (!cleaned || lowered.startsWith(\"runtime\")) continue;\n if (lowered === \"first run\" || lowered === \"follow-up\") continue;\n if (lowered.startsWith(\"run:\")) cleaned = cleaned.slice(4).trim();\n const safe = bounded(safeNativeMemoryText(cleaned), MAX_KEY_ACTION_CHARS);\n if (safe && !actions.includes(safe)) actions.push(safe);\n if (actions.length >= MAX_KEY_ACTIONS_PER_RUN) break;\n }\n return actions;\n}\n\nfunction titleFromActions(config: AutomationConfig, actions: string[]): string {\n if (actions.length === 0) return config.name;\n const first = actions[0] as string;\n const prefix = `${config.name}: `;\n if (first.startsWith(prefix)) return bounded(first, 120);\n return bounded(prefix + first, 120);\n}\n\nfunction inferProjects(text: string): string[] {\n const projects: string[] = [];\n const lowered = text.toLowerCase();\n const seen = new Set<string>();\n for (const project of loadProjectHints(DEFAULT_PROJECT_HINTS)) {\n const key = project.toLowerCase();\n if (lowered.includes(key) && !seen.has(key)) {\n projects.push(project);\n seen.add(key);\n }\n }\n return projects;\n}\n\nfunction inferSignals(text: string): string[] {\n const signals: string[] = [];\n for (const [name, pattern] of SIGNAL_PATTERNS) {\n if (pattern.test(text)) signals.push(name);\n }\n return signals;\n}\n\nfunction extractMemoryRuns(config: AutomationConfig): AutomationRun[] {\n const text = readMemoryText(config.memoryPath);\n if (!text) return [];\n\n const chunks: Array<[string, string[]]> = [];\n let currentDate = \"\";\n let currentLines: string[] = [];\n for (const rawLine of splitLines(text)) {\n const line = rstrip(rawLine);\n const match = RUN_HEADER_RE.exec(line.trim());\n if (match) {\n if (currentDate) chunks.push([currentDate, currentLines]);\n currentDate = match[1] as string;\n const suffix = stripChars((match[2] as string).trim(), \" -:—\");\n currentLines = suffix ? [suffix] : [];\n continue;\n }\n if (currentDate) currentLines.push(line);\n }\n if (currentDate) chunks.push([currentDate, currentLines]);\n\n const runs: AutomationRun[] = [];\n for (const [runDate, lines] of chunks) {\n const actions = actionsFromLines(lines);\n if (actions.length === 0) continue;\n const body = actions.join(\" \");\n const title = titleFromActions(config, actions);\n runs.push({\n automation: config,\n date: runDate,\n title,\n keyActions: actions,\n projects: inferProjects(body),\n signals: inferSignals(body),\n });\n }\n return runs;\n}\n\n/** Python `str.strip(chars)` — strip any of `chars` from both ends. */\nfunction stripChars(s: string, chars: string): string {\n let start = 0;\n let end = s.length;\n while (start < end && chars.includes(s[start] as string)) start++;\n while (end > start && chars.includes(s[end - 1] as string)) end--;\n return s.slice(start, end);\n}\n\n// -- L5 assembly ---------------------------------------------------------------\n\nfunction sessionFromRun(run: AutomationRun): SessionModel {\n const config = run.automation;\n const keyActions = [\n `automation_id: ${config.automationId}`,\n `run: ${run.title}`,\n ...run.keyActions,\n ];\n const filesTouched = [config.path];\n if (config.memoryPath !== null) filesTouched.push(config.memoryPath);\n return makeSession({\n date: run.date,\n cwd: config.cwds.length > 0 ? (config.cwds[0] as string) : dirname(config.path),\n project_focus: [...run.projects],\n key_actions: keyActions.slice(0, MAX_KEY_ACTIONS_PER_RUN + 2),\n files_touched: filesTouched,\n visibility: Visibility.TEAM,\n });\n}\n\nfunction entitiesFromConfigsAndRuns(\n configs: AutomationConfig[],\n runs: AutomationRun[],\n): EntityModel[] {\n const byName = new Map<string, EntityModel>();\n for (const config of configs) {\n byName.set(\n config.automationId,\n makeEntity({\n name: config.automationId,\n type: \"automation\",\n summary: bounded(\n `Codex automation '${config.name}' (${config.status}). ` +\n `Schedule: ${config.rrule || \"unspecified\"}.`,\n 260,\n ),\n last_touched: undefined,\n tags: [\"codex-automation\", \"automation\", config.status.toLowerCase()],\n visibility: Visibility.TEAM,\n }),\n );\n }\n\n for (const run of runs) {\n for (const project of run.projects) {\n if (!byName.has(project)) {\n byName.set(\n project,\n makeEntity({\n name: project,\n type: \"project\",\n summary: \"Project mentioned by Codex automation run memory.\",\n last_touched: run.date,\n tags: [\"codex-automation\", \"automation-evidence\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n for (const signal of run.signals) {\n if (!byName.has(signal)) {\n byName.set(\n signal,\n makeEntity({\n name: signal,\n type: \"automation-signal\",\n summary: \"Signal class inferred from Codex automation run memory.\",\n last_touched: run.date,\n tags: [\"codex-automation\", \"automation-signal\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n }\n return [...byName.values()];\n}\n\n// -- Participant ---------------------------------------------------------------\n\n/**\n * External participant for Codex automation memory artifacts. Reads\n * `~/.codex/automations/<id>/{automation.toml,memory.md}` and normalizes dated\n * runs into an L5 manifest.\n */\nexport class CodexAutomationsParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n\n private readonly automationsDir: string;\n private readonly policy: VisibilityPolicyModel;\n\n /**\n * Conventional Codex automations dir (`~/.codex/automations`). Provided for\n * protocol uniformity — the setup wizard wires the parent `codex` participant\n * and skips `-automations` sub-surfaces rather than detecting this one.\n */\n static defaultNativePath(home?: string): string {\n return defaultCodexAutomationsDir(home);\n }\n\n constructor(automationsDir?: string, codexHome?: string) {\n this.automationsDir = automationsDir ?? defaultCodexAutomationsDir(codexHome);\n this.policy = DEFAULT_POLICY;\n }\n\n get nativePath(): string {\n return this.automationsDir;\n }\n\n discover(): AgentStore {\n if (!isDir(this.automationsDir)) {\n throw new ParticipantDiscoveryError(\n `Codex automations directory not found at ${this.automationsDir}.`,\n );\n }\n const configs = iterConfigs(this.automationsDir);\n return {\n path: this.automationsDir,\n version: \"unknown\",\n metadata: {\n automations: configs.length,\n with_memory: configs.filter((c) => c.memoryPath !== null).length,\n },\n };\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const sessions = this.runs(undefined, since).map(sessionFromRun);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n return sessions.slice(0, limit);\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const configs = iterConfigs(this.automationsDir);\n const runs = this.runs(configs, since);\n const sessions = runs.map(sessionFromRun);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n const entities = entitiesFromConfigsAndRuns(configs, runs);\n const visibleEntities = filterForFederation(entities, this.policy);\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: hostname(),\n spec_version_compat: SPEC_VERSION,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: new Date().toISOString(),\n capabilities: [\"codex-automation-memory\", \"run-summary-publication\"],\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: this.policy,\n });\n }\n\n healthCheck(): HealthStatus {\n if (!isDir(this.automationsDir)) {\n return {\n status: \"blocked\",\n reason: `Codex automations directory not found at ${this.automationsDir}.`,\n details: { automations_dir: this.automationsDir },\n proposedFix: \"Create Codex automations or pass --automations-dir.\",\n };\n }\n const configs = iterConfigs(this.automationsDir);\n const runs = this.runs(configs);\n const hasConfigs = configs.length > 0;\n return {\n status: hasConfigs ? \"ok\" : \"degraded\",\n reason: hasConfigs ? undefined : \"No automation.toml files found.\",\n details: {\n automations_dir: this.automationsDir,\n automation_count: configs.length,\n memory_files: configs.filter((c) => c.memoryPath !== null).length,\n runs_extracted: runs.length,\n active_automations: configs.filter((c) => c.status === \"ACTIVE\").length,\n },\n proposedFix: hasConfigs ? undefined : \"Add Codex automation.toml files.\",\n };\n }\n\n // -- Internal ---------------------------------------------------------------\n\n private runs(configs?: AutomationConfig[], since?: Date): AutomationRun[] {\n const runCutoff = since ? since.toISOString().slice(0, 10) : null;\n const runs: AutomationRun[] = [];\n for (const config of configs ?? iterConfigs(this.automationsDir)) {\n for (const run of extractMemoryRuns(config)) {\n if (runCutoff && run.date < runCutoff) continue;\n runs.push(run);\n }\n }\n runs.sort((a, b) => {\n if (a.date !== b.date) return a.date < b.date ? 1 : -1;\n const ai = a.automation.automationId;\n const bi = b.automation.automationId;\n if (ai !== bi) return ai < bi ? 1 : -1;\n return 0;\n });\n return runs;\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * GitHub Copilot · Automations participant — convention-file reader. Port of\n * `participants/copilot_automations.py`.\n *\n * GitHub Copilot can be triggered by GitHub Actions workflows, scheduled tasks,\n * and event-driven automations (issue triage, PR review, etc.). These run on a\n * separate memory surface from both the CLI agent and the VS Code extension.\n * Copilot automations have no standardized local state dump, so — mirroring the\n * codex-automations reader — this participant uses a CONVENTION directory:\n *\n * ~/.copilot-bourdon/automations/<automation-id>/\n * automation.toml — id, name, status, trigger, kind, repos\n * memory.md — dated bullet entries, one block per run\n *\n * Each `automation.toml` describes a recurring automation; each dated section of\n * `memory.md` captures what happened in that run. Users or CI scripts maintain\n * these files.\n *\n * Path resolution (matches the oracle):\n * 1. `COPILOT_AUTOMATIONS_HOME` env-var override (verbatim, → /automations skipped:\n * the override IS the automations dir).\n * 2. `~/.copilot-bourdon/automations/` (default convention path).\n *\n * Defensive throughout: a missing automations directory raises\n * {@link ParticipantDiscoveryError} from `discover()`; a malformed\n * `automation.toml` or unreadable `memory.md` is logged and skipped rather than\n * raising; `healthCheck` never throws.\n */\n\nimport { mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from \"node:fs\";\nimport { homedir, hostname } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport { parse as parseToml } from \"smol-toml\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\n\n// -- Constants -----------------------------------------------------------------\n\nconst AGENT_ID = \"copilot-automations\";\nconst AGENT_TYPE = \"other\";\nconst DISPLAY_NAME = \"GitHub Copilot · Automations\";\nconst ROLE_NARRATIVE =\n \"Publishes read-only Copilot automation run memory into Bourdon so \" +\n \"GitHub Actions-triggered Copilot tasks, scheduled PR reviews, issue \" +\n \"triage, and other event-driven Copilot work are visible alongside \" +\n \"interactive agent sessions.\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"health\", \"family\", \"legal\"],\n team_tags: [\"copilot-automation\", \"automation\", \"github-actions\", \"workspace\"],\n});\n\nconst CONVENTION_DIR_NAME = \".copilot-bourdon\";\nconst AUTOMATIONS_DIR = \"automations\";\nconst AUTOMATION_TOML = \"automation.toml\";\nconst MEMORY_MD = \"memory.md\";\nconst MAX_MEMORY_CHARS = 160_000;\nconst MAX_KEY_ACTIONS_PER_RUN = 6;\nconst MAX_KEY_ACTION_CHARS = 280;\n/** `^(\\d{4}-\\d{2}-\\d{2})(?:\\b|$)(.*)$` — the dated run header. */\nconst RUN_HEADER_RE = /^(\\d{4}-\\d{2}-\\d{2})(?:\\b|$)(.*)$/;\n\n/** Starter template for `bourdon copilot-automations init`. */\nconst AUTOMATION_TOML_TEMPLATE = `# Copilot Automation definition\n# Edit this file to describe a recurring Copilot automation.\n\nid = \"{automation_id}\"\nname = \"{name}\"\nstatus = \"ACTIVE\"\ntrigger = \"workflow_dispatch\" # or: schedule, issue_comment, pull_request, etc.\nkind = \"pr-review\" # or: issue-triage, code-generation, test-review, etc.\nrepos = [] # list of repositories this automation targets\n`;\n\nconst MEMORY_MD_TEMPLATE = `# {name} — Run Memory\n\nRecord automation run outcomes here. Each dated section is parsed by Bourdon.\n\n# Format:\n# YYYY-MM-DD <optional title>\n# - bullet point of what happened\n# - another action or outcome\n\n`;\n\n/** Minimal logger so a degraded parse is visible without pulling in a dep\n * (matches the sibling readers' logging idiom). */\nconst logger = {\n warn(msg: string): void {\n // eslint-disable-next-line no-console\n console.warn(`[bourdon.participants] ${msg}`);\n },\n};\n\n// -- Records -------------------------------------------------------------------\n\ninterface AutomationConfig {\n automationId: string;\n name: string;\n status: string;\n trigger: string;\n kind: string;\n repos: string[];\n path: string;\n memoryPath: string | null;\n}\n\ninterface AutomationRun {\n automation: AutomationConfig;\n date: string;\n title: string;\n keyActions: string[];\n repos: string[];\n}\n\n// -- fs helpers ----------------------------------------------------------------\n\nfunction homeDir(): string {\n // os.homedir() can throw under some sandboxes; stay defensive so import +\n // construction never crash even when HOME points at an unreadable path.\n try {\n return homedir();\n } catch {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n }\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/** Python truthiness for the scalar/array types TOML yields. */\nfunction pyTruthy(v: unknown): boolean {\n if (v === null || v === undefined || v === false) return false;\n if (typeof v === \"string\") return v.length > 0;\n if (typeof v === \"number\") return v !== 0;\n if (Array.isArray(v)) return v.length > 0;\n return true;\n}\n\n/** Mirror Python `str(value)` for the value types encountered here. */\nfunction pyStr(v: unknown): string {\n if (typeof v === \"string\") return v;\n if (typeof v === \"boolean\") return v ? \"True\" : \"False\";\n if (v === null || v === undefined) return \"None\";\n return String(v);\n}\n\n// -- Path helpers --------------------------------------------------------------\n\n/**\n * Return the conventional `~/.copilot-bourdon/automations/` directory. Respects\n * the `COPILOT_AUTOMATIONS_HOME` env-var override (returned verbatim — the\n * override IS the automations dir, no `/automations` suffix is appended).\n */\nexport function defaultCopilotAutomationsDir(copilotBourdonDir?: string | null): string {\n const env = process.env.COPILOT_AUTOMATIONS_HOME;\n if (env) return env;\n const base = copilotBourdonDir || join(homeDir(), CONVENTION_DIR_NAME);\n return join(base, AUTOMATIONS_DIR);\n}\n\n// -- Config / memory parsing ---------------------------------------------------\n\nfunction readAutomationToml(path: string): Record<string, unknown> {\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch (exc) {\n logger.warn(`CopilotAutomationsParticipant: cannot parse ${path}: ${String(exc)}`);\n return {};\n }\n try {\n const parsed = parseToml(text) as unknown;\n return isRecord(parsed) ? parsed : {};\n } catch (exc) {\n logger.warn(`CopilotAutomationsParticipant: cannot parse ${path}: ${String(exc)}`);\n return {};\n }\n}\n\nfunction buildConfig(tomlPath: string): AutomationConfig | null {\n const raw = readAutomationToml(tomlPath);\n const parentDir = dirname(tomlPath);\n const parentName = parentDir.split(/[\\\\/]/).filter(Boolean).pop() ?? \"\";\n\n const automationId = pyStr(pyTruthy(raw[\"id\"]) ? raw[\"id\"] : parentName).trim();\n if (!automationId) return null;\n\n const name = pyStr(pyTruthy(raw[\"name\"]) ? raw[\"name\"] : automationId).trim();\n const status = pyStr(pyTruthy(raw[\"status\"]) ? raw[\"status\"] : \"UNKNOWN\")\n .trim()\n .toUpperCase();\n const trigger = pyStr(pyTruthy(raw[\"trigger\"]) ? raw[\"trigger\"] : \"\").trim();\n const kind = pyStr(pyTruthy(raw[\"kind\"]) ? raw[\"kind\"] : \"\").trim();\n\n const reposRaw = pyTruthy(raw[\"repos\"]) ? raw[\"repos\"] : [];\n const reposIter: unknown[] = Array.isArray(reposRaw)\n ? reposRaw\n : typeof reposRaw === \"string\"\n ? Array.from(reposRaw)\n : [];\n const repos = reposIter.filter((r): r is string => typeof r === \"string\" && r.trim() !== \"\");\n\n const memoryPath = join(parentDir, MEMORY_MD);\n return {\n automationId,\n name,\n status,\n trigger,\n kind,\n repos,\n path: tomlPath,\n memoryPath: isFile(memoryPath) ? memoryPath : null,\n };\n}\n\nfunction iterConfigs(automationsDir: string): AutomationConfig[] {\n const configs: AutomationConfig[] = [];\n if (!isDir(automationsDir)) return configs;\n\n let entries: string[];\n try {\n entries = readdirSync(automationsDir);\n } catch {\n return configs;\n }\n\n // Mirror `sorted(Path.glob(\"*/automation.toml\"))`: one directory level deep,\n // sorted by path. NOTE pathlib glob MATCHES dot-prefixed dirs (unlike shell\n // glob / glob.glob) — do NOT skip them, or dot-named automations under-report.\n const tomlPaths: string[] = [];\n for (const entry of entries) {\n const candidate = join(automationsDir, entry, AUTOMATION_TOML);\n if (isFile(candidate)) tomlPaths.push(candidate);\n }\n tomlPaths.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n\n for (const tomlPath of tomlPaths) {\n const config = buildConfig(tomlPath);\n if (config !== null) configs.push(config);\n }\n return configs;\n}\n\n/** Python `str.splitlines()` for the common line boundaries. Empty input → []. */\nfunction splitLines(text: string): string[] {\n if (text.length === 0) return [];\n // Python splitlines includes ASCII record separators; this explicit set preserves parity.\n return text.split(\n // eslint-disable-next-line no-control-regex\n /\\r\\n|\\r|\\n|\\u000B|\\u000C|\\u001C|\\u001D|\\u001E|\\u0085|\\u2028|\\u2029/u,\n );\n}\n\n/** Python `str.rstrip()` — strip trailing whitespace. */\nfunction rstrip(s: string): string {\n return s.replace(/\\s+$/u, \"\");\n}\n\n/** Python `str.strip(chars)` — strip the given char set from both ends. */\nfunction stripChars(s: string, chars: string): string {\n let start = 0;\n let end = s.length;\n while (start < end && chars.includes(s[start]!)) start++;\n while (end > start && chars.includes(s[end - 1]!)) end--;\n return s.slice(start, end);\n}\n\nfunction extractMemoryRuns(config: AutomationConfig): AutomationRun[] {\n if (config.memoryPath === null) return [];\n let text: string;\n try {\n text = readFileSync(config.memoryPath, \"utf8\");\n } catch (exc) {\n logger.warn(`CopilotAutomationsParticipant: cannot read ${config.memoryPath}: ${String(exc)}`);\n return [];\n }\n\n text = text.slice(-MAX_MEMORY_CHARS);\n const chunks: Array<[string, string[]]> = [];\n let currentDate = \"\";\n let currentLines: string[] = [];\n\n for (const rawLine of splitLines(text)) {\n const line = rstrip(rawLine);\n const match = RUN_HEADER_RE.exec(line.trim());\n if (match) {\n if (currentDate) chunks.push([currentDate, currentLines]);\n currentDate = match[1]!;\n const suffix = stripChars((match[2] ?? \"\").trim(), \" -:—\");\n currentLines = suffix ? [suffix] : [];\n continue;\n }\n if (currentDate) currentLines.push(line);\n }\n if (currentDate) chunks.push([currentDate, currentLines]);\n\n const runs: AutomationRun[] = [];\n for (const [runDate, lines] of chunks) {\n const actions = actionsFromLines(lines);\n if (actions.length === 0) continue;\n const title = titleFromActions(config, actions);\n runs.push({\n automation: config,\n date: runDate,\n title,\n keyActions: actions,\n repos: config.repos,\n });\n }\n return runs;\n}\n\nfunction actionsFromLines(lines: string[]): string[] {\n const actions: string[] = [];\n for (const line of lines) {\n let cleaned = line.trim();\n if (!cleaned) continue;\n cleaned = (cleaned.startsWith(\"- \") ? cleaned.slice(2) : cleaned).trim();\n if (!cleaned || cleaned.toLowerCase().startsWith(\"runtime\")) continue;\n const safe = bounded(safeNativeMemoryText(cleaned), MAX_KEY_ACTION_CHARS);\n if (safe && !actions.includes(safe)) actions.push(safe);\n if (actions.length >= MAX_KEY_ACTIONS_PER_RUN) break;\n }\n return actions;\n}\n\nfunction titleFromActions(config: AutomationConfig, actions: string[]): string {\n if (actions.length === 0) return config.name;\n const first = actions[0]!;\n const prefix = `${config.name}: `;\n if (first.startsWith(prefix)) return bounded(first, 120);\n return bounded(prefix + first, 120);\n}\n\n/** `\" \".join(value.split())` + ellipsis truncation. */\nfunction bounded(value: string, limit: number): string {\n const normalized = value\n .split(/\\s+/u)\n .filter((x) => x.length > 0)\n .join(\" \");\n if (normalized.length <= limit) return normalized;\n return rstrip(normalized.slice(0, limit - 1)) + \"…\";\n}\n\n/** Python `_safe_native_memory_text(v)` == `redactText(v, 180)`. */\nfunction safeNativeMemoryText(value: string): string {\n return redactText(value, 180);\n}\n\n// -- Conversion to Bourdon types ----------------------------------------------\n\nfunction sessionFromRun(run: AutomationRun): SessionModel {\n const config = run.automation;\n const keyActions = [\n `automation: ${config.automationId}`,\n config.trigger ? `trigger: ${config.trigger}` : `kind: ${config.kind}`,\n `run: ${run.title}`,\n ...run.keyActions,\n ];\n return makeSession({\n date: run.date,\n cwd: dirname(config.path),\n project_focus: [...run.repos],\n key_actions: keyActions.slice(0, MAX_KEY_ACTIONS_PER_RUN + 3),\n files_touched: [config.path],\n visibility: Visibility.TEAM,\n });\n}\n\nfunction entitiesFromConfigsAndRuns(\n configs: AutomationConfig[],\n runs: AutomationRun[],\n): EntityModel[] {\n const entities = new Map<string, EntityModel>();\n\n for (const config of configs) {\n entities.set(\n config.automationId,\n makeEntity({\n name: config.automationId,\n type: \"automation\",\n summary: bounded(\n `Copilot automation '${config.name}' (${config.status}). ` +\n `Trigger: ${config.trigger || \"unspecified\"}. ` +\n `Kind: ${config.kind || \"unspecified\"}.`,\n 260,\n ),\n last_touched: undefined,\n tags: [\"copilot-automation\", \"automation\", config.status.toLowerCase()],\n visibility: Visibility.TEAM,\n }),\n );\n }\n\n // Repos mentioned across all runs (setdefault: first-write-wins).\n for (const run of runs) {\n for (const repo of run.repos) {\n if (!entities.has(repo)) {\n entities.set(\n repo,\n makeEntity({\n name: repo,\n type: \"project\",\n summary: \"Repository targeted by Copilot automation.\",\n last_touched: run.date,\n tags: [\"copilot-automation\", \"project\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n }\n\n return [...entities.values()];\n}\n\n// -- Participant ---------------------------------------------------------------\n\n/**\n * Convention-based Bourdon participant for Copilot automation memory artifacts.\n * Users or CI scripts maintain `automation.toml` + `memory.md` files at\n * `~/.copilot-bourdon/automations/<id>/`.\n */\nexport class CopilotAutomationsParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n displayName = DISPLAY_NAME;\n\n private readonly automationsDir: string;\n private readonly policy: VisibilityPolicyModel;\n\n /** Conventional automations dir (`~/.copilot-bourdon/automations`). Does NOT\n * consult `COPILOT_AUTOMATIONS_HOME` (matches Python `default_native_path`). */\n static defaultNativePath(home?: string): string {\n const base = join(home ?? homeDir(), CONVENTION_DIR_NAME);\n return join(base, AUTOMATIONS_DIR);\n }\n\n constructor(automationsDir?: string | null) {\n this.automationsDir = automationsDir ?? defaultCopilotAutomationsDir();\n this.policy = DEFAULT_POLICY;\n }\n\n get nativePath(): string {\n return this.automationsDir;\n }\n\n // -- Protocol surface -------------------------------------------------------\n\n discover(): AgentStore {\n if (!isDir(this.automationsDir)) {\n throw new ParticipantDiscoveryError(\n `Copilot automations directory not found at ${this.automationsDir}. ` +\n \"Run `bourdon copilot-automations init <name>` to create one.\",\n );\n }\n const configs = iterConfigs(this.automationsDir);\n return {\n path: this.automationsDir,\n version: \"convention-v1\",\n metadata: {\n automations: configs.length,\n with_memory: configs.filter((c) => c.memoryPath !== null).length,\n },\n };\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const sessions = this.runs(undefined, since).map(sessionFromRun);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n return sessions.slice(0, limit);\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const configs = iterConfigs(this.automationsDir);\n const runs = this.runs(configs, since);\n const sessions = runs.map(sessionFromRun);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n const entities = entitiesFromConfigsAndRuns(configs, runs);\n const visibleEntities = filterForFederation(entities, this.policy);\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: hostname() || \"unknown\",\n spec_version_compat: `>=${SPEC_VERSION}`,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: new Date().toISOString(),\n capabilities: [\"copilot-automation-memory\", \"run-summary-publication\"],\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: this.policy,\n });\n }\n\n healthCheck(): HealthStatus {\n if (!isDir(this.automationsDir)) {\n return {\n status: \"blocked\",\n reason: `Copilot automations directory not found at ${this.automationsDir}.`,\n details: { automations_dir: this.automationsDir },\n proposedFix: \"Run `bourdon copilot-automations init <name>` to create an automation.\",\n };\n }\n const configs = iterConfigs(this.automationsDir);\n const runs = this.runs(configs);\n const hasConfigs = configs.length > 0;\n return {\n status: hasConfigs ? \"ok\" : \"degraded\",\n reason: hasConfigs ? undefined : \"No automation.toml files found.\",\n details: {\n automations_dir: this.automationsDir,\n automation_count: configs.length,\n memory_files: configs.filter((c) => c.memoryPath !== null).length,\n runs_extracted: runs.length,\n active_automations: configs.filter((c) => c.status === \"ACTIVE\").length,\n },\n proposedFix: hasConfigs\n ? undefined\n : \"Run `bourdon copilot-automations init <name>` to create an automation, \" +\n \"or add automation.toml files manually.\",\n };\n }\n\n // -- Internal ---------------------------------------------------------------\n\n private runs(configs?: AutomationConfig[], since?: Date): AutomationRun[] {\n const runCutoff = since ? since.toISOString().slice(0, 10) : null;\n const out: AutomationRun[] = [];\n for (const config of configs ?? iterConfigs(this.automationsDir)) {\n for (const run of extractMemoryRuns(config)) {\n if (runCutoff && run.date < runCutoff) continue;\n out.push(run);\n }\n }\n // sorted(key=(date, automation_id), reverse=True)\n out.sort((a, b) => {\n if (a.date !== b.date) return a.date < b.date ? 1 : -1;\n const ai = a.automation.automationId;\n const bi = b.automation.automationId;\n if (ai !== bi) return ai < bi ? 1 : -1;\n return 0;\n });\n return out;\n }\n}\n\n// -- Init helper ---------------------------------------------------------------\n\n/**\n * Create an automation scaffold at `<automationsDir>/<id>/`. Returns the path\n * of the created automation directory. Throws when `automation.toml` already\n * exists unless `force` is true.\n */\nexport function initAutomation(\n automationsDir?: string | null,\n automationId = \"my-automation\",\n name = \"My Copilot Automation\",\n force = false,\n): string {\n const targetDir = join(automationsDir || defaultCopilotAutomationsDir(), automationId);\n const tomlPath = join(targetDir, AUTOMATION_TOML);\n const memoryPath = join(targetDir, MEMORY_MD);\n\n if (isFile(tomlPath) && !force) {\n throw new Error(`${tomlPath} already exists. Pass --force to overwrite.`);\n }\n\n mkdirSync(targetDir, { recursive: true });\n writeFileSync(\n tomlPath,\n AUTOMATION_TOML_TEMPLATE.replace(\"{automation_id}\", automationId).replace(\"{name}\", name),\n \"utf8\",\n );\n if (!isFile(memoryPath) || force) {\n writeFileSync(memoryPath, MEMORY_MD_TEMPLATE.replace(\"{name}\", name), \"utf8\");\n }\n return targetDir;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Cursor automations participant — publish background agent run memory as L5\n * evidence. Port of `participants/cursor_automations.py`.\n *\n * Reads the `~/.cursor/automations/<id>/` CONVENTION (file-based, no SQLite):\n *\n * automation.toml — id, name, status, schedule (rrule), kind, cwds\n * memory.md — dated bullet entries, one block per run\n *\n * Each `automation.toml` becomes a known Entity; each dated section of\n * `memory.md` becomes a recent Session. This covers the federation gap the\n * interactive-only `cursor` participant leaves behind: Cursor Cloud Agent\n * background tasks whose work never touches the interactive SQLite state.\n *\n * Path resolution (default dir):\n * 1. explicit `cursorHome` ctor arg → `<cursorHome>/automations`\n * 2. `CURSOR_DIR` or `CURSOR_HOME` env → `<env>/automations`\n * 3. `~/.cursor/automations`\n *\n * Redaction: every native action string passes through the redaction SSOT\n * (`redactText(v, 180)` == Python `_safe_native_memory_text`). Visibility policy\n * filters PRIVATE entities BEFORE emission. `healthCheck` never throws.\n */\n\nimport { mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport { homedir, hostname } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport { parse as parseToml } from \"smol-toml\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n loadProjectHints,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\n\n// -- Constants -----------------------------------------------------------------\n\nconst AGENT_ID = \"cursor-automations\";\nconst AGENT_TYPE = \"other\";\nconst ROLE_NARRATIVE =\n \"Publishes read-only Cursor Cloud Agent automation run memory into Bourdon \" +\n \"so background PR reviews, code generation tasks, and scheduled agent runs \" +\n \"become visible alongside interactive Cursor IDE sessions.\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"health\", \"family\", \"legal\"],\n team_tags: [\"cursor-automation\", \"automation\", \"workspace\"],\n});\n\nconst AUTOMATIONS_DIR_NAME = \"automations\";\nconst AUTOMATION_TOML = \"automation.toml\";\nconst MEMORY_MD = \"memory.md\";\nconst MAX_MEMORY_CHARS = 160_000;\nconst MAX_KEY_ACTIONS_PER_RUN = 6;\nconst MAX_KEY_ACTION_CHARS = 280;\n\n/** `^(YYYY-MM-DD)(?:\\b|$)(rest)$` — matches a run-header line (post `.strip()`). */\nconst RUN_HEADER_RE = /^(\\d{4}-\\d{2}-\\d{2})(?:\\b|$)(.*)$/;\n/** Chars stripped from a run-header suffix (space, hyphen, colon, em-dash). */\nconst HEADER_SUFFIX_STRIP = \" -:—\";\n\n// Product-neutral defaults only: this product plus the agent surfaces Bourdon\n// federates. A deployment adds its own project roster via the\n// `BOURDON_PROJECT_HINTS` env var (comma-separated) — see `loadProjectHints`.\nconst DEFAULT_PROJECT_HINTS: readonly string[] = [\n \"Bourdon\",\n \"Cursor\",\n \"Copilot\",\n \"Codex\",\n \"Cascade\",\n];\n\nconst SIGNAL_PATTERNS: ReadonlyArray<readonly [string, RegExp]> = [\n [\"human-dashboard-action\", /\\b(human|dashboard|manual)\\b/i],\n [\"release-gate\", /\\b(release|store|app review|play console|testflight)\\b/i],\n [\"billing-drift\", /\\b(billing|stripe|revenuecat|iap|subscription)\\b/i],\n [\"memory-coverage-gap\", /\\b(memory|l5|manifest|federated|bourdon)\\b/i],\n [\"launch-decision\", /\\b(launch|go-live|pricing|prod|production)\\b/i],\n [\"ci-signal\", /\\b(github action|workflow run|ci|cd|deploy|pipeline)\\b/i],\n];\n\n/** `^[-*]\\s+(rest)$` — a markdown bullet line (used by the merge path). */\nconst BULLET_RE = /^[-*]\\s+(.*)$/;\n/** `^[A-Za-z0-9._-]+$` — a filesystem-safe automation id (merge validation). */\nconst VALID_ID_RE = /^[A-Za-z0-9._-]+$/;\n\n// -- Data shapes ---------------------------------------------------------------\n\ninterface AutomationConfig {\n automationId: string;\n name: string;\n status: string;\n rrule: string;\n kind: string;\n cwds: string[];\n /** Absolute path to the automation.toml. */\n path: string;\n /** Absolute path to memory.md, or null when it is not a readable file. */\n memoryPath: string | null;\n}\n\ninterface AutomationRun {\n automation: AutomationConfig;\n date: string;\n title: string;\n keyActions: string[];\n projects: string[];\n signals: string[];\n}\n\n/** Summary of a {@link mergeAutomationTree} call. */\nexport interface MergeResult {\n automationsSeen: number;\n automationsCreated: number;\n bulletsAdded: number;\n sectionsCreated: number;\n skipped: string[];\n}\n\n// -- Minimal logger ------------------------------------------------------------\n\nconst logger = {\n warn(msg: string): void {\n // eslint-disable-next-line no-console\n console.warn(`[bourdon.participants] ${msg}`);\n },\n};\n\n// -- fs helpers ----------------------------------------------------------------\n\nfunction homeDir(): string {\n // os.homedir() can throw under some sandboxes; stay defensive so import +\n // construction never crash even when HOME points at an unreadable path.\n try {\n return homedir();\n } catch {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n }\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\n// -- Python-idiom helpers ------------------------------------------------------\n\n/** Python truthiness for the scalar types read here (str / int / None). */\nfunction pyFalsy(v: unknown): boolean {\n return v === undefined || v === null || v === \"\" || v === 0 || v === false;\n}\n\n/** Mirror Python `str(raw.get(key) or fallback)`. */\nfunction strOr(v: unknown, fallback: string): string {\n return String(pyFalsy(v) ? fallback : v);\n}\n\n/** Mirror Python `str.strip(chars)` — strip a fixed char SET from both ends. */\nfunction stripChars(s: string, chars: string): string {\n let start = 0;\n let end = s.length;\n while (start < end && chars.includes(s[start]!)) start++;\n while (end > start && chars.includes(s[end - 1]!)) end--;\n return s.slice(start, end);\n}\n\n/** Mirror Python `str.rstrip()` (trailing whitespace only). */\nfunction rstrip(s: string): string {\n return s.replace(/\\s+$/, \"\");\n}\n\n/**\n * Mirror Python `_bounded`: collapse all whitespace to single spaces, trim, and\n * cap at `limit` with a trailing ellipsis. NOTE the exact truncation form —\n * `normalized[: limit - 1].rstrip() + \"...\"` — which is DISTINCT from\n * `redactText`'s `limit - 3` tail. Do not conflate the two.\n */\nfunction bounded(value: string, limit: number): string {\n const trimmed = value.trim();\n const normalized = trimmed === \"\" ? \"\" : trimmed.split(/\\s+/).join(\" \");\n if (normalized.length <= limit) return normalized;\n return rstrip(normalized.slice(0, limit - 1)) + \"...\";\n}\n\n/** `_safe_native_memory_text(v)` == `redactText(v, 180)` (positional). */\nfunction safeNativeMemoryText(value: string): string {\n return redactText(value, 180);\n}\n\n// -- Path helpers --------------------------------------------------------------\n\n/** Return the default Cursor automations directory. */\nexport function defaultCursorAutomationsDir(cursorHome?: string | null): string {\n if (cursorHome !== undefined && cursorHome !== null) {\n return join(cursorHome, AUTOMATIONS_DIR_NAME);\n }\n const env = process.env.CURSOR_DIR || process.env.CURSOR_HOME;\n if (env) return join(env, AUTOMATIONS_DIR_NAME);\n return join(homeDir(), \".cursor\", AUTOMATIONS_DIR_NAME);\n}\n\n// -- TOML + memory parsing -----------------------------------------------------\n\nfunction readAutomationToml(path: string): Record<string, unknown> {\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch (exc) {\n logger.warn(`CursorAutomationsParticipant: cannot parse ${path}: ${String(exc)}`);\n return {};\n }\n try {\n const parsed = parseToml(text);\n return typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : {};\n } catch (exc) {\n logger.warn(`CursorAutomationsParticipant: cannot parse ${path}: ${String(exc)}`);\n return {};\n }\n}\n\nfunction buildConfig(tomlPath: string): AutomationConfig | null {\n const raw = readAutomationToml(tomlPath);\n const parentName = basenameOf(dirname(tomlPath));\n const automationId = strOr(raw[\"id\"], parentName).trim();\n if (!automationId) return null;\n const name = strOr(raw[\"name\"], automationId).trim();\n const status = strOr(raw[\"status\"], \"UNKNOWN\").trim().toUpperCase();\n const rrule = strOr(raw[\"rrule\"], \"\").trim();\n const kind = strOr(raw[\"kind\"], \"\").trim();\n\n const cwdsRaw = raw[\"cwds\"];\n const cwds: string[] = [];\n if (Array.isArray(cwdsRaw)) {\n for (const cwd of cwdsRaw) {\n if (typeof cwd === \"string\" && cwd.trim()) cwds.push(cwd);\n }\n } else if (typeof cwdsRaw === \"string\") {\n for (const ch of cwdsRaw) {\n if (ch.trim()) cwds.push(ch);\n }\n }\n\n const memoryPath = join(dirname(tomlPath), MEMORY_MD);\n return {\n automationId,\n name,\n status,\n rrule,\n kind,\n cwds,\n path: tomlPath,\n memoryPath: isFile(memoryPath) ? memoryPath : null,\n };\n}\n\n/** `os.path.basename` on a (possibly trailing-slash-free) dir path. */\nfunction basenameOf(p: string): string {\n const parts = p.split(/[\\\\/]+/).filter((x) => x !== \"\");\n return parts.length ? parts[parts.length - 1]! : \"\";\n}\n\n/**\n * Enumerate `<dir>/*​/automation.toml`, sorted by full path. Mirrors Python's\n * `sorted(dir.glob(\"*​/automation.toml\"))` — pathlib's `*` does NOT match names\n * beginning with a dot, so dot-prefixed automation dirs are skipped.\n */\nfunction iterConfigs(automationsDir: string): AutomationConfig[] {\n const configs: AutomationConfig[] = [];\n if (!isDir(automationsDir)) return configs;\n let names: string[];\n try {\n names = readdirSync(automationsDir);\n } catch {\n return configs;\n }\n const tomlPaths: string[] = [];\n for (const name of names) {\n // pathlib `Path.glob(\"*\")` MATCHES dot-prefixed dirs — do NOT skip them.\n const tomlPath = join(automationsDir, name, AUTOMATION_TOML);\n if (isFile(tomlPath)) tomlPaths.push(tomlPath);\n }\n tomlPaths.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n for (const tomlPath of tomlPaths) {\n const config = buildConfig(tomlPath);\n if (config !== null) configs.push(config);\n }\n return configs;\n}\n\nfunction readMemoryText(path: string | null): string {\n if (path === null) return \"\";\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch (exc) {\n logger.warn(`CursorAutomationsParticipant: cannot read ${path}: ${String(exc)}`);\n return \"\";\n }\n return text.slice(-MAX_MEMORY_CHARS);\n}\n\nfunction extractMemoryRuns(config: AutomationConfig): AutomationRun[] {\n const text = readMemoryText(config.memoryPath);\n if (!text) return [];\n\n const chunks: Array<[string, string[]]> = [];\n let currentDate = \"\";\n let currentLines: string[] = [];\n for (const rawLine of text.split(/\\r?\\n/)) {\n const line = rstrip(rawLine);\n const match = RUN_HEADER_RE.exec(line.trim());\n if (match) {\n if (currentDate) chunks.push([currentDate, currentLines]);\n currentDate = match[1]!;\n const suffix = stripChars(match[2]!.trim(), HEADER_SUFFIX_STRIP);\n currentLines = suffix ? [suffix] : [];\n continue;\n }\n if (currentDate) currentLines.push(line);\n }\n if (currentDate) chunks.push([currentDate, currentLines]);\n\n const runs: AutomationRun[] = [];\n for (const [runDate, lines] of chunks) {\n const actions = actionsFromLines(lines);\n if (actions.length === 0) continue;\n const body = actions.join(\" \");\n const title = titleFromActions(config, actions);\n runs.push({\n automation: config,\n date: runDate,\n title,\n keyActions: actions,\n projects: inferProjects(body),\n signals: inferSignals(body),\n });\n }\n return runs;\n}\n\nfunction actionsFromLines(lines: string[]): string[] {\n const actions: string[] = [];\n for (const line of lines) {\n let cleaned = line.trim();\n if (!cleaned) continue;\n cleaned = (cleaned.startsWith(\"- \") ? cleaned.slice(2) : cleaned).trim();\n const lowered = cleaned.toLowerCase();\n if (!cleaned || lowered.startsWith(\"runtime\")) continue;\n if (lowered === \"first run\" || lowered === \"follow-up\") continue;\n if (lowered.startsWith(\"run:\")) cleaned = cleaned.slice(4).trim();\n const safe = bounded(safeNativeMemoryText(cleaned), MAX_KEY_ACTION_CHARS);\n if (safe && !actions.includes(safe)) actions.push(safe);\n if (actions.length >= MAX_KEY_ACTIONS_PER_RUN) break;\n }\n return actions;\n}\n\nfunction titleFromActions(config: AutomationConfig, actions: string[]): string {\n if (actions.length === 0) return config.name;\n const first = actions[0]!;\n const prefix = `${config.name}: `;\n if (first.startsWith(prefix)) return bounded(first, 120);\n return bounded(prefix + first, 120);\n}\n\nfunction inferProjects(text: string): string[] {\n const projects: string[] = [];\n const lowered = text.toLowerCase();\n const seen = new Set<string>();\n for (const project of loadProjectHints(DEFAULT_PROJECT_HINTS)) {\n const key = project.toLowerCase();\n if (lowered.includes(key) && !seen.has(key)) {\n projects.push(project);\n seen.add(key);\n }\n }\n return projects;\n}\n\nfunction inferSignals(text: string): string[] {\n const signals: string[] = [];\n for (const [name, pattern] of SIGNAL_PATTERNS) {\n if (pattern.test(text)) signals.push(name);\n }\n return signals;\n}\n\n// -- Merge / ingest ------------------------------------------------------------\n\n/** Split memory.md text into (date_header, list_of_bullets) sections. */\nfunction parseMemorySections(text: string): Array<[string, string[]]> {\n const sections: Array<[string, string[]]> = [];\n let currentDate = \"\";\n let currentBullets: string[] = [];\n for (const rawLine of text.split(/\\r?\\n/)) {\n const line = rstrip(rawLine);\n const match = RUN_HEADER_RE.exec(line.trim());\n if (match) {\n if (currentDate) sections.push([currentDate, currentBullets]);\n currentDate = match[1]!;\n const suffix = stripChars(match[2]!.trim(), HEADER_SUFFIX_STRIP);\n currentBullets = [];\n if (suffix) currentBullets.push(suffix);\n continue;\n }\n if (!currentDate) continue;\n const bulletMatch = BULLET_RE.exec(line.trim());\n if (bulletMatch) currentBullets.push(bulletMatch[1]!.trim());\n }\n if (currentDate) sections.push([currentDate, currentBullets]);\n return sections;\n}\n\n/** Render a list of (date, bullets) back to memory.md form. */\nfunction serializeSections(sections: Array<[string, string[]]>): string {\n const blocks: string[] = [];\n for (const [dateStr, bullets] of sections) {\n const lines = [dateStr, ...bullets.map((b) => `- ${b}`)];\n blocks.push(lines.join(\"\\n\"));\n }\n return blocks.join(\"\\n\\n\") + \"\\n\";\n}\n\n/**\n * Merge an automations tree from `sourceDir` into `destDir`. Idempotent —\n * calling twice on the same source is a no-op. Throws when `sourceDir` is not a\n * directory (Python `FileNotFoundError`).\n */\nexport function mergeAutomationTree(\n sourceDir: string,\n destDir: string,\n defaultKind = \"cursor-cloud-agent\",\n): MergeResult {\n if (!isDir(sourceDir)) {\n throw new Error(`merge source not found: ${sourceDir}`);\n }\n mkdirSync(destDir, { recursive: true });\n\n let seen = 0;\n let created = 0;\n let bulletsAdded = 0;\n let sectionsCreated = 0;\n const skipped: string[] = [];\n\n const entries = readdirSync(sourceDir).sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n for (const entryName of entries) {\n const srcIdDir = join(sourceDir, entryName);\n if (!isDir(srcIdDir)) continue;\n seen += 1;\n const automationId = entryName;\n if (!VALID_ID_RE.test(automationId)) {\n skipped.push(automationId);\n continue;\n }\n\n const destIdDir = join(destDir, automationId);\n const srcToml = join(srcIdDir, AUTOMATION_TOML);\n const srcMemory = join(srcIdDir, MEMORY_MD);\n\n if (!existsPath(destIdDir)) {\n mkdirSync(destIdDir, { recursive: true });\n created += 1;\n if (isFile(srcToml)) {\n writeFileSync(join(destIdDir, AUTOMATION_TOML), readFileSync(srcToml, \"utf8\"), \"utf8\");\n } else {\n writeFileSync(\n join(destIdDir, AUTOMATION_TOML),\n `version = 1\\nid = \"${automationId}\"\\n` +\n `name = \"${automationId}\"\\nstatus = \"ACTIVE\"\\n` +\n `kind = \"${defaultKind}\"\\nrrule = \"\"\\ncwds = []\\n`,\n \"utf8\",\n );\n }\n }\n\n if (!isFile(srcMemory)) continue;\n\n const srcSections = parseMemorySections(readFileSync(srcMemory, \"utf8\"));\n const destMemory = join(destIdDir, MEMORY_MD);\n const destSections: Array<[string, string[]]> = isFile(destMemory)\n ? parseMemorySections(readFileSync(destMemory, \"utf8\"))\n : [];\n // Map date -> bullets list (SAME array refs as destSections; last wins on\n // duplicate dates, matching Python `dict(dest_sections)`).\n const destByDate = new Map<string, string[]>();\n for (const [d, b] of destSections) destByDate.set(d, b);\n\n for (const [dateStr, bullets] of srcSections) {\n if (!destByDate.has(dateStr)) {\n const fresh: string[] = [];\n destByDate.set(dateStr, fresh);\n destSections.push([dateStr, fresh]);\n sectionsCreated += 1;\n }\n const existing = destByDate.get(dateStr)!;\n for (const bullet of bullets) {\n if (!existing.includes(bullet)) {\n existing.push(bullet);\n bulletsAdded += 1;\n }\n }\n }\n\n destSections.sort((x, y) => (x[0] < y[0] ? -1 : x[0] > y[0] ? 1 : 0));\n writeFileSync(destMemory, serializeSections(destSections), \"utf8\");\n }\n\n return {\n automationsSeen: seen,\n automationsCreated: created,\n bulletsAdded,\n sectionsCreated,\n skipped,\n };\n}\n\nfunction existsPath(p: string): boolean {\n try {\n statSync(p);\n return true;\n } catch {\n return false;\n }\n}\n\n// -- Init helper ---------------------------------------------------------------\n\nconst INIT_TOML_TEMPLATE = `id = \"{automation_id}\"\nname = \"{automation_id}\"\nstatus = \"ACTIVE\"\nrrule = \"\"\nkind = \"\"\ncwds = []\n`;\n\nconst INIT_MEMORY_TEMPLATE = `# {automation_id}\n#\n# Append dated sections below. Each YYYY-MM-DD header starts a new run;\n# bullets under it become key_actions in the L5 manifest.\n#\n# Example:\n# 2026-06-01\n# - Reviewed open PRs in Bourdon and Northwind.\n# - No critical issues found.\n`;\n\n/** Create a starter automation directory with toml + memory.md. */\nexport function initAutomationsDir(\n automationsDir?: string | null,\n automationId = \"cursor-cloud-agent\",\n force = false,\n): string {\n const base = automationsDir || defaultCursorAutomationsDir();\n const target = join(base, automationId);\n if (existsPath(target) && !force) {\n throw new Error(`${target} already exists. Pass --force to overwrite.`);\n }\n mkdirSync(target, { recursive: true });\n writeFileSync(\n join(target, AUTOMATION_TOML),\n INIT_TOML_TEMPLATE.split(\"{automation_id}\").join(automationId),\n \"utf8\",\n );\n writeFileSync(\n join(target, MEMORY_MD),\n INIT_MEMORY_TEMPLATE.split(\"{automation_id}\").join(automationId),\n \"utf8\",\n );\n return target;\n}\n\n// -- L5 helpers ----------------------------------------------------------------\n\nfunction sessionFromRun(run: AutomationRun): SessionModel {\n const config = run.automation;\n const keyActions = [\n `automation_id: ${config.automationId}`,\n `run: ${run.title}`,\n ...run.keyActions,\n ];\n const filesTouched = [config.path];\n if (config.memoryPath !== null) filesTouched.push(config.memoryPath);\n return makeSession({\n date: run.date,\n cwd: config.cwds.length ? config.cwds[0]! : dirname(config.path),\n project_focus: [...run.projects],\n key_actions: keyActions.slice(0, MAX_KEY_ACTIONS_PER_RUN + 2),\n files_touched: filesTouched,\n visibility: Visibility.TEAM,\n });\n}\n\nfunction entitiesFromConfigsAndRuns(\n configs: AutomationConfig[],\n runs: AutomationRun[],\n): EntityModel[] {\n const entitiesByName = new Map<string, EntityModel>();\n for (const config of configs) {\n entitiesByName.set(\n config.automationId,\n makeEntity({\n name: config.automationId,\n type: \"automation\",\n summary: bounded(\n `Cursor automation '${config.name}' (${config.status}). ` +\n `Schedule: ${config.rrule || \"unspecified\"}.`,\n 260,\n ),\n last_touched: null,\n tags: [\"cursor-automation\", \"automation\", config.status.toLowerCase()],\n visibility: Visibility.TEAM,\n }),\n );\n }\n for (const run of runs) {\n for (const project of run.projects) {\n if (!entitiesByName.has(project)) {\n entitiesByName.set(\n project,\n makeEntity({\n name: project,\n type: \"project\",\n summary: \"Project mentioned by Cursor automation run memory.\",\n last_touched: run.date,\n tags: [\"cursor-automation\", \"automation-evidence\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n for (const signal of run.signals) {\n if (!entitiesByName.has(signal)) {\n entitiesByName.set(\n signal,\n makeEntity({\n name: signal,\n type: \"automation-signal\",\n summary: \"Signal class inferred from Cursor automation run memory.\",\n last_touched: run.date,\n tags: [\"cursor-automation\", \"automation-signal\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n }\n return [...entitiesByName.values()];\n}\n\n/** `datetime.now(timezone.utc).isoformat(timespec=\"seconds\")` form. */\nfunction nowIsoSeconds(): string {\n return new Date().toISOString().replace(/\\.\\d+Z$/, \"+00:00\");\n}\n\n// -- Participant ---------------------------------------------------------------\n\n/** External participant for Cursor Cloud Agent automation memory artifacts. */\nexport class CursorAutomationsParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n\n private readonly automationsDir: string;\n private readonly policy: VisibilityPolicyModel;\n\n constructor(automationsDir?: string | null, cursorHome?: string | null) {\n this.automationsDir =\n automationsDir || defaultCursorAutomationsDir(cursorHome ?? undefined);\n this.policy = DEFAULT_POLICY;\n }\n\n get nativePath(): string {\n return this.automationsDir;\n }\n\n discover(): AgentStore {\n if (!isDir(this.automationsDir)) {\n throw new ParticipantDiscoveryError(\n `Cursor automations directory not found at ${this.automationsDir}.`,\n );\n }\n const configs = iterConfigs(this.automationsDir);\n return {\n path: this.automationsDir,\n version: \"unknown\",\n metadata: {\n automations: configs.length,\n with_memory: configs.filter((c) => c.memoryPath !== null).length,\n },\n };\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const sessions = this.runs(undefined, since).map(sessionFromRun);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n return sessions.slice(0, limit);\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const configs = iterConfigs(this.automationsDir);\n const runs = this.runs(configs, since);\n const sessions = runs.map(sessionFromRun);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n const entities = entitiesFromConfigsAndRuns(configs, runs);\n const visibleEntities = filterForFederation(entities, this.policy);\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: hostname(),\n spec_version_compat: SPEC_VERSION,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: nowIsoSeconds(),\n capabilities: [\"cursor-automation-memory\", \"run-summary-publication\"],\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: this.policy,\n });\n }\n\n healthCheck(): HealthStatus {\n if (!isDir(this.automationsDir)) {\n return {\n status: \"blocked\",\n reason: `Cursor automations directory not found at ${this.automationsDir}.`,\n details: { automations_dir: this.automationsDir },\n proposedFix: \"Create Cursor automations or pass --automations-dir.\",\n };\n }\n const configs = iterConfigs(this.automationsDir);\n const runs = this.runs(configs);\n const hasConfigs = configs.length > 0;\n const details = {\n automations_dir: this.automationsDir,\n automation_count: configs.length,\n memory_files: configs.filter((c) => c.memoryPath !== null).length,\n runs_extracted: runs.length,\n active_automations: configs.filter((c) => c.status === \"ACTIVE\").length,\n };\n if (hasConfigs) {\n return { status: \"ok\", details };\n }\n return {\n status: \"degraded\",\n reason: \"No automation.toml files found.\",\n details,\n proposedFix: \"Add Cursor automation.toml files.\",\n };\n }\n\n private runs(configs?: AutomationConfig[], since?: Date): AutomationRun[] {\n const runCutoff = since ? since.toISOString().slice(0, 10) : null;\n const runs: AutomationRun[] = [];\n for (const config of configs ?? iterConfigs(this.automationsDir)) {\n for (const run of extractMemoryRuns(config)) {\n if (runCutoff && run.date < runCutoff) continue;\n runs.push(run);\n }\n }\n // Sort by (date, automationId) DESCENDING (Python reverse=True on the tuple).\n runs.sort((a, b) => {\n if (a.date !== b.date) return a.date > b.date ? -1 : 1;\n const ai = a.automation.automationId;\n const bi = b.automation.automationId;\n return ai > bi ? -1 : ai < bi ? 1 : 0;\n });\n return runs;\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Claude Desktop · Code participant — the Claude desktop app's GUI \"Claude Code\"\n * surface. Port of `participants/claude_desktop_code.py` (+ the shared\n * `participants/_claude_desktop.py` helpers it needs).\n *\n * The desktop GUI's Claude Code keeps **metadata-only** state on disk — there is\n * no transcript. State files live at:\n *\n * <desktop>/claude-code-sessions/<accountUUID>/<orgUUID>/local_<id>.json\n *\n * This participant emits **recognition metadata only** and routes every emitted\n * string through the shared redactor + a length cap (defense in depth): title,\n * cwd→project, model, effort, `enabledMcpTools` *count*, timestamps. It never\n * emits `planPath` contents or any free-form text beyond the redacted title.\n *\n * Distinct from the interactive-CLI {@link ClaudeCodeParticipant} and the richer\n * Co-Work surface. Convention: file/JSON reader (no SQLite, no network).\n */\n\nimport { readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { homedir, hostname } from \"node:os\";\nimport { basename, join, parse as parsePath } from \"node:path\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n loadProjectHints,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\n\n// -- Constants ----------------------------------------------------------------\n\nconst AGENT_ID = \"claude-desktop-code\";\nconst AGENT_TYPE = \"code-assistant\";\nconst DISPLAY_NAME = \"Claude Desktop · Code\";\nconst SURFACE_ENTITY_NAME = \"Claude Desktop Code\";\nconst ROLE_NARRATIVE =\n \"Claude desktop app, GUI Claude Code. Bourdon reads the metadata-only \" +\n \"per-conversation local state to surface recognition metadata -- title, \" +\n \"project, model, effort, capability counts -- never conversation content \" +\n \"-- so desktop Claude Code work is visible to other agents.\";\n\n// Environment override (tests + non-standard installs). Takes precedence over\n// the platform default but not over an explicit `home` argument.\nconst DESKTOP_DIR_ENV = \"BOURDON_CLAUDE_DESKTOP_DIR\";\n\n// Sub-store directory name under the desktop dir.\nconst CODE_STORE = \"claude-code-sessions\";\n\n// State filename prefix shared by both desktop stores (`local_<uuid>.json`).\nconst STATE_PREFIX = \"local_\";\nconst STATE_FILE_RE = /^local_.*\\.json$/;\n\n// Caps -- keep emitted metadata small and bounded.\nconst MAX_KEY_ACTION_CHARS = 280;\nconst MAX_PROJECTS = 6;\nconst MAX_KEY_ACTIONS = 6;\n\n// Product-neutral defaults only: this product plus the agent surfaces Bourdon\n// federates. A deployment adds its own project roster via the\n// `BOURDON_PROJECT_HINTS` env var (comma-separated) — see `loadProjectHints`.\nconst DEFAULT_PROJECT_HINTS: readonly string[] = [\n \"Bourdon\",\n \"Cursor\",\n \"Copilot\",\n \"Codex\",\n \"Cascade\",\n];\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"health\", \"family\", \"legal\"],\n team_tags: [\"claude-desktop\", \"claude-desktop-code\", \"agent-surface\", \"workspace\"],\n});\n\n// -- fs helpers ---------------------------------------------------------------\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\n// -- Desktop-dir resolution (`_claude_desktop.default_claude_desktop_dir`) -----\n\nfunction homeBase(home?: string): string {\n // Mirror Python's `home or Path.home()`. os.homedir() can throw under some\n // sandboxes; stay defensive so import + construction never crash.\n if (home !== undefined) return home;\n try {\n return homedir();\n } catch {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n }\n}\n\n/**\n * Resolve the Claude desktop application-support directory. Returns `null` only\n * on an unrecognized platform with no env override (callers treat that as\n * \"blocked\" rather than crashing).\n *\n * Precedence: `BOURDON_CLAUDE_DESKTOP_DIR` env → platform default anchored on\n * `home` (defaults to homedir).\n */\nexport function defaultClaudeDesktopDir(home?: string): string | null {\n const env = process.env[DESKTOP_DIR_ENV];\n if (env) return env;\n\n const base = homeBase(home);\n if (process.platform === \"darwin\") {\n return join(base, \"Library\", \"Application Support\", \"Claude\");\n }\n if (process.platform === \"win32\") {\n // When an explicit home is provided (tests), keep everything under it so the\n // fake tree is self-contained; otherwise honor %APPDATA%.\n if (home === undefined) {\n const appdata = process.env.APPDATA;\n if (appdata) return join(appdata, \"Claude\");\n }\n return join(base, \"AppData\", \"Roaming\", \"Claude\");\n }\n if (process.platform === \"linux\") {\n return join(base, \".config\", \"Claude\");\n }\n return null;\n}\n\n// -- State-file globbing (`_claude_desktop.iter_state_files`) ------------------\n\n/**\n * Return every `local_*.json` under `<store_dir>/<acct>/<org>/`, sorted by path.\n * Never raises when the store dir is absent (returns `[]`) so health checks can\n * distinguish \"store missing\" from \"store empty\".\n */\nfunction iterStateFiles(storeDir: string): string[] {\n if (!isDir(storeDir)) return [];\n const out: string[] = [];\n let accts: string[];\n try {\n accts = readdirSync(storeDir);\n } catch {\n return out;\n }\n for (const acct of accts) {\n const acctDir = join(storeDir, acct);\n if (!isDir(acctDir)) continue;\n let orgs: string[];\n try {\n orgs = readdirSync(acctDir);\n } catch {\n continue;\n }\n for (const org of orgs) {\n const orgDir = join(acctDir, org);\n if (!isDir(orgDir)) continue;\n let names: string[];\n try {\n names = readdirSync(orgDir);\n } catch {\n continue;\n }\n for (const name of names) {\n if (name.startsWith(STATE_PREFIX) && STATE_FILE_RE.test(name)) {\n out.push(join(orgDir, name));\n }\n }\n }\n }\n out.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n return out;\n}\n\n/**\n * Read + parse one `local_*.json` state file. Returns the parsed object, or\n * `null` on any read/parse failure or if the top-level JSON is not an object.\n * Never raises — malformed files are counted and skipped by callers.\n */\nfunction loadStateJson(path: string): Record<string, unknown> | null {\n let raw: string;\n try {\n raw = readFileSync(path, \"utf8\");\n } catch {\n return null;\n }\n let data: unknown;\n try {\n data = JSON.parse(raw);\n } catch {\n return null;\n }\n if (typeof data !== \"object\" || data === null || Array.isArray(data)) return null;\n return data as Record<string, unknown>;\n}\n\n// -- Scalar helpers -----------------------------------------------------------\n\n/**\n * Convert an epoch timestamp to a UTC `YYYY-MM-DD` string. Accepts ms (`> 1e12`)\n * or seconds; ints, floats, and numeric strings are tolerated. Returns `\"\"` on\n * anything unparseable (bools are rejected explicitly, as in Python).\n */\nfunction epochToDate(value: unknown): string {\n if (typeof value === \"boolean\") return \"\"; // bool is an int subclass in Py — reject\n let num: number | null = null;\n if (typeof value === \"number\") {\n num = value;\n } else if (typeof value === \"string\" && value.trim()) {\n const parsed = Number(value.trim());\n num = Number.isNaN(parsed) ? null : parsed;\n }\n if (num === null || !Number.isFinite(num)) return \"\";\n const seconds = num > 1e12 ? num / 1000 : num;\n try {\n const d = new Date(seconds * 1000);\n const iso = d.toISOString();\n return iso.slice(0, 10);\n } catch {\n return \"\";\n }\n}\n\n/** Pick a session date from `createdAt` then `lastActivityAt`. */\nfunction sessionDate(state: Record<string, unknown>): string {\n for (const key of [\"createdAt\", \"lastActivityAt\"] as const) {\n const parsed = epochToDate(state[key]);\n if (parsed) return parsed;\n }\n return \"\";\n}\n\n/**\n * Redact credential-like text + strip links, then cap to `limit` chars. Runs\n * through the redaction SSOT first so a planted secret becomes the sentinel\n * *before* truncation can split it. Mirrors `_safe_native_memory_text(v, limit)`.\n */\nfunction bounded(value: string, limit: number = MAX_KEY_ACTION_CHARS): string {\n return redactText(value, limit);\n}\n\n/** Coerce a scalar to a bounded, redacted display string (\"\" if empty). */\nfunction safeLabel(value: unknown, limit: number = MAX_KEY_ACTION_CHARS): string {\n if (value === null || value === undefined) return \"\";\n const text = String(value).trim();\n if (!text) return \"\";\n return bounded(text, limit);\n}\n\n/**\n * Count `true` values in an `enabledMcpTools` mapping. Keys are\n * `\"<serverUUID>:<tool>\"` and are NOT emitted — only the count of enabled\n * entries is surfaced, so no tool names or server identifiers leak.\n */\nfunction countEnabledMcpTools(enabled: unknown): number {\n if (typeof enabled !== \"object\" || enabled === null || Array.isArray(enabled)) return 0;\n let count = 0;\n for (const v of Object.values(enabled as Record<string, unknown>)) {\n if (v === true) count += 1;\n }\n return count;\n}\n\nfunction baseName(pathValue: unknown): string {\n if (typeof pathValue !== \"string\" || !pathValue.trim()) return \"\";\n const name = basename(pathValue.trim()).trim();\n return name && name !== \".\" && name !== \"/\" && name !== \"\\\\\" ? name : \"\";\n}\n\n/**\n * Infer project names from cwd + user-selected folders (basenames only), plus a\n * project-hint substring match. No file contents / no full paths — only\n * directory basenames and recognized labels. Order-preserving + de-duplicated.\n */\nfunction inferProjects(state: Record<string, unknown>): string[] {\n const projects: string[] = [];\n const seen = new Set<string>();\n\n const add = (name: string): void => {\n const cleaned = name.trim();\n if (cleaned && !seen.has(cleaned.toLowerCase())) {\n projects.push(cleaned);\n seen.add(cleaned.toLowerCase());\n }\n };\n\n const pathStrings: string[] = [];\n const cwd = state[\"cwd\"];\n if (typeof cwd === \"string\" && cwd.trim()) pathStrings.push(cwd);\n const folders = state[\"userSelectedFolders\"];\n if (Array.isArray(folders)) {\n for (const f of folders) {\n if (typeof f === \"string\" && f.trim()) pathStrings.push(f);\n }\n }\n\n for (const rawPath of pathStrings) {\n const base = baseName(rawPath);\n if (base) add(base);\n }\n\n const haystack = pathStrings.join(\" \").toLowerCase();\n for (const hint of loadProjectHints(DEFAULT_PROJECT_HINTS)) {\n if (haystack.includes(hint.toLowerCase())) add(hint);\n }\n\n return projects.slice(0, MAX_PROJECTS);\n}\n\n// -- Normalized conversation --------------------------------------------------\n\ninterface CodeConversation {\n convId: string;\n date: string;\n cwd: string;\n title: string;\n model: string;\n effort: string;\n permissionMode: string;\n isArchived: boolean;\n mcpToolCount: number;\n projects: string[];\n}\n\nfunction conversationFromState(\n statePath: string,\n state: Record<string, unknown>,\n): CodeConversation {\n const sessionId = state[\"sessionId\"];\n const stem = parsePath(statePath).name;\n return {\n convId: String(sessionId || stem),\n date: sessionDate(state),\n cwd: safeLabel(state[\"cwd\"], 300),\n title: safeLabel(state[\"title\"], 160) || \"(untitled conversation)\",\n model: safeLabel(state[\"model\"], 80),\n effort: safeLabel(state[\"effort\"], 40),\n permissionMode: safeLabel(state[\"permissionMode\"], 40),\n isArchived: Boolean(state[\"isArchived\"]),\n mcpToolCount: countEnabledMcpTools(state[\"enabledMcpTools\"]),\n projects: inferProjects(state),\n };\n}\n\nfunction keyActions(conv: CodeConversation): string[] {\n const actions: string[] = [bounded(conv.title, 160)];\n if (conv.model) actions.push(bounded(`model: ${conv.model}`, 120));\n if (conv.effort) actions.push(bounded(`effort: ${conv.effort}`, 60));\n if (conv.permissionMode) actions.push(bounded(`permission: ${conv.permissionMode}`, 80));\n if (conv.mcpToolCount) actions.push(`mcp-tools: ${conv.mcpToolCount}`);\n return actions.slice(0, MAX_KEY_ACTIONS);\n}\n\nfunction sessionFromConversation(conv: CodeConversation): SessionModel {\n return makeSession({\n date: conv.date,\n cwd: conv.cwd || undefined,\n project_focus: [...conv.projects],\n key_actions: keyActions(conv),\n files_touched: [], // never list user files -- privacy\n visibility: Visibility.TEAM,\n });\n}\n\nfunction capabilities(convs: CodeConversation[]): string[] {\n let maxMcp = 0;\n for (const conv of convs) if (conv.mcpToolCount > maxMcp) maxMcp = conv.mcpToolCount;\n return [AGENT_ID, `mcp-tools:${maxMcp}`];\n}\n\nfunction entitiesFromConversations(convs: CodeConversation[]): EntityModel[] {\n let lastSeen: string | undefined;\n for (const conv of convs) {\n if (lastSeen === undefined || conv.date > lastSeen) lastSeen = conv.date;\n }\n\n const entities = new Map<string, EntityModel>();\n entities.set(\n SURFACE_ENTITY_NAME,\n makeEntity({\n name: SURFACE_ENTITY_NAME,\n type: \"agent-surface\",\n summary: bounded(\n \"Claude desktop app GUI Claude Code surface (metadata-only federation).\",\n 260,\n ),\n last_touched: lastSeen,\n tags: [\"claude-desktop\", \"claude-desktop-code\", \"agent-surface\"],\n visibility: Visibility.TEAM,\n }),\n );\n for (const conv of convs) {\n for (const project of conv.projects) {\n if (!entities.has(project)) {\n entities.set(\n project,\n makeEntity({\n name: project,\n type: \"project\",\n summary: \"Project inferred from a Claude Desktop Code conversation cwd.\",\n last_touched: conv.date || undefined,\n tags: [\"claude-desktop\", \"claude-desktop-code\", \"project\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n }\n return [...entities.values()];\n}\n\n// -- Participant --------------------------------------------------------------\n\n/**\n * External participant for the Claude desktop app's GUI Claude Code surface.\n * File/JSON reader — metadata-only, no transcript, no SQLite, no network.\n */\nexport class ClaudeDesktopCodeParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n displayName = DISPLAY_NAME;\n\n private readonly storeDir: string;\n private readonly policy: VisibilityPolicyModel;\n\n /**\n * The Claude Code sub-store dir the setup wizard probes for presence. Resolves\n * to `<desktop>/claude-code-sessions`. Falls back to a non-existent sentinel\n * under `home` on an unrecognized platform so the wizard reports \"not found\".\n */\n static defaultNativePath(home?: string): string {\n const desktop = defaultClaudeDesktopDir(home);\n if (desktop === null) return join(homeBase(home), \"Claude\", CODE_STORE);\n return join(desktop, CODE_STORE);\n }\n\n constructor(storeDir?: string, home?: string) {\n this.storeDir = storeDir ?? ClaudeDesktopCodeParticipant.defaultNativePath(home);\n this.policy = DEFAULT_POLICY;\n }\n\n get nativePath(): string {\n return this.storeDir;\n }\n\n discover(): AgentStore {\n if (!isDir(this.storeDir)) {\n throw new ParticipantDiscoveryError(\n `Claude Desktop Code store not found at ${this.storeDir}.`,\n );\n }\n const stateFiles = iterStateFiles(this.storeDir);\n return {\n path: this.storeDir,\n version: \"unknown\",\n metadata: { conversations: stateFiles.length },\n };\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const convs = this.conversations(since);\n const sessions = convs.map(sessionFromConversation);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n return sessions.slice(0, limit);\n }\n\n exportL5(since?: Date): L5ManifestModel {\n if (!isDir(this.storeDir)) {\n throw new ParticipantDiscoveryError(\n `Claude Desktop Code store not found at ${this.storeDir}.`,\n );\n }\n const convs = this.conversations(since);\n const sessions = convs.map(sessionFromConversation);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n const entities = entitiesFromConversations(convs);\n const visibleEntities = filterForFederation(entities, this.policy);\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: hostname(),\n spec_version_compat: SPEC_VERSION,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: new Date().toISOString(),\n capabilities: capabilities(convs),\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: this.policy,\n });\n }\n\n healthCheck(): HealthStatus {\n if (!isDir(this.storeDir)) {\n return {\n status: \"blocked\",\n reason: `Claude Desktop Code store not found at ${this.storeDir}.`,\n details: { store_dir: this.storeDir },\n proposedFix:\n \"Install the Claude desktop app and open a Claude Code conversation \" +\n \"once. Set BOURDON_CLAUDE_DESKTOP_DIR if the app stores state in a \" +\n \"non-standard location.\",\n };\n }\n let stateFiles: string[];\n let convs: CodeConversation[];\n let malformed: number;\n try {\n stateFiles = iterStateFiles(this.storeDir);\n const collected = this.collectConversations();\n convs = collected.convs;\n malformed = collected.malformed;\n } catch (exc) {\n return {\n status: \"degraded\",\n reason: \"Code store present but extraction failed.\",\n details: { error: String(exc) },\n proposedFix:\n \"Close the Claude desktop app (its state files may be locked) and \" +\n \"re-run `bourdon claude-desktop-code export`.\",\n };\n }\n if (stateFiles.length === 0) {\n return {\n status: \"degraded\",\n reason: \"No Claude Code conversations found under the store directory.\",\n details: { store_dir: this.storeDir },\n proposedFix:\n \"Open a Claude Code conversation in the Claude desktop app, then \" +\n \"re-run `bourdon claude-desktop-code export`.\",\n };\n }\n return {\n status: \"ok\",\n details: {\n store_dir: this.storeDir,\n conversation_count: stateFiles.length,\n conversations_extracted: convs.length,\n malformed_records: malformed,\n },\n };\n }\n\n // -- Internal ---------------------------------------------------------------\n\n private collectConversations(): { convs: CodeConversation[]; malformed: number } {\n const convs: CodeConversation[] = [];\n let malformed = 0;\n for (const statePath of iterStateFiles(this.storeDir)) {\n const state = loadStateJson(statePath);\n if (state === null) {\n malformed += 1;\n continue;\n }\n convs.push(conversationFromState(statePath, state));\n }\n return { convs, malformed };\n }\n\n private conversations(since?: Date): CodeConversation[] {\n let { convs } = this.collectConversations();\n if (since !== undefined) {\n const cutoff = since.toISOString().slice(0, 10);\n convs = convs.filter((conv) => !conv.date || conv.date >= cutoff);\n }\n // Reverse tuple sort: (date, convId) descending.\n convs.sort((a, b) => {\n if (a.date !== b.date) return a.date < b.date ? 1 : -1;\n if (a.convId !== b.convId) return a.convId < b.convId ? 1 : -1;\n return 0;\n });\n return convs;\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Claude Desktop · Co-Work participant — the richest of the two Claude-desktop\n * surfaces. Port of `participants/claude_desktop_cowork.py` (+ the shared\n * `participants/_claude_desktop.py` extraction helpers, inlined here).\n *\n * The desktop app stores each Co-Work / local-agent run as a state file plus a\n * sibling audit transcript:\n *\n * <desktop>/local-agent-mode-sessions/<acct>/<org>/local_<id>.json (state)\n * <desktop>/local-agent-mode-sessions/<acct>/<org>/local_<id>/audit.jsonl\n *\n * This participant emits **recognition metadata only**. From the state file it\n * reads surface scalars (title, cwd, model, permission mode, timestamps,\n * `enabledMcpTools` *count*, `userSelectedFolders` *basenames*). From the\n * sibling `audit.jsonl` it reads ONLY the `system`/`init` capability *counts*\n * and the `result` safe scalars (cost, turns, error flag). It NEVER reads\n * conversation content. Every emitted string passes through the redaction SSOT\n * + a length cap, and TEAM entities are visibility-filtered before emission.\n *\n * Storage kind: file/convention (glob + JSON + JSONL), so this reads like the\n * claude-code / cascade file readers — no SQLite, no network.\n */\n\nimport { readFileSync, readdirSync, statSync } from \"node:fs\";\nimport { hostname } from \"node:os\";\nimport { basename, dirname, join, parse as parsePath } from \"node:path\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n loadProjectHints,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\n\n// -- Constants -----------------------------------------------------------------\n\nconst AGENT_ID = \"claude-desktop-cowork\";\nconst AGENT_TYPE = \"code-assistant\";\nconst DISPLAY_NAME = \"Claude Desktop · Co-Work\";\nconst SURFACE_ENTITY_NAME = \"Claude Desktop Co-Work\";\nconst ROLE_NARRATIVE =\n \"Claude desktop app, Co-Work / local-agent mode. Bourdon reads the \" +\n \"per-run local state and audit transcript to surface recognition metadata \" +\n \"-- title, project, model, turn/cost scalars, capability counts -- never \" +\n \"conversation content -- so Co-Work runs are visible to other agents.\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"health\", \"family\", \"legal\"],\n team_tags: [\"claude-desktop\", \"claude-desktop-cowork\", \"agent-surface\", \"workspace\"],\n});\n\n// Environment override (tests + non-standard installs). Takes precedence over\n// the platform default but not over an explicit `home` argument.\nconst DESKTOP_DIR_ENV = \"BOURDON_CLAUDE_DESKTOP_DIR\";\n\n// Sub-store directory name under the desktop dir.\nconst COWORK_STORE = \"local-agent-mode-sessions\";\n\n// State filename prefix (`local_<uuid>.json`).\nconst STATE_PREFIX = \"local_\";\n\nconst MAX_PROJECTS = 6;\nconst MAX_KEY_ACTIONS = 8;\n// audit.jsonl can be large; only the (small) init + result lines are needed, so\n// bound how much to scan before giving up.\nconst MAX_AUDIT_LINES = 50_000;\n\n// Product-neutral defaults only: this product plus the agent surfaces Bourdon\n// federates. A deployment adds its own project roster via the\n// `BOURDON_PROJECT_HINTS` env var (comma-separated) — see `loadProjectHints`.\nconst DEFAULT_PROJECT_HINTS: readonly string[] = [\n \"Bourdon\",\n \"Cursor\",\n \"Copilot\",\n \"Codex\",\n \"Cascade\",\n];\n\n/** Minimal logger so a malformed-file warning is visible without a dep. */\nconst logger = {\n warn(msg: string): void {\n // eslint-disable-next-line no-console\n console.warn(`[bourdon.participants] ${msg}`);\n },\n};\n\n// -- fs helpers ----------------------------------------------------------------\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\nfunction homeDir(): string {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/** Current UTC time at seconds precision + `+00:00` offset — mirrors Python's\n * `datetime.now(timezone.utc).isoformat(timespec=\"seconds\")`. */\nfunction isoSeconds(): string {\n return new Date().toISOString().replace(/\\.\\d{3}Z$/, \"+00:00\");\n}\n\n// -- Desktop dir resolution ----------------------------------------------------\n\n/**\n * Resolve the Claude desktop application-support directory.\n *\n * Precedence:\n * 1. `BOURDON_CLAUDE_DESKTOP_DIR` env var.\n * 2. Platform default, anchored on `home` (defaults to homedir):\n * * macOS -- `<home>/Library/Application Support/Claude`\n * * Windows -- `%APPDATA%/Claude` (falls back to `<home>/AppData/Roaming/Claude`)\n * * Linux -- `<home>/.config/Claude`\n *\n * Returns `null` only on an unrecognized platform with no env override.\n */\nfunction defaultClaudeDesktopDir(home?: string): string | null {\n const env = process.env[DESKTOP_DIR_ENV];\n if (env) return env;\n\n const base = home || homeDir();\n const plat = process.platform;\n if (plat === \"darwin\") {\n return join(base, \"Library\", \"Application Support\", \"Claude\");\n }\n if (plat.startsWith(\"win\")) {\n // When an explicit home is provided (tests), keep everything under it;\n // otherwise honor %APPDATA%.\n if (home === undefined) {\n const appdata = process.env.APPDATA;\n if (appdata) return join(appdata, \"Claude\");\n }\n return join(base, \"AppData\", \"Roaming\", \"Claude\");\n }\n if (plat.startsWith(\"linux\")) {\n return join(base, \".config\", \"Claude\");\n }\n return null;\n}\n\n/**\n * Return every `local_*.json` under `<store_dir>/<acct>/<org>/`, globbing across\n * all account/org UUID directories. Returns `[]` (never throws) when the store\n * dir is absent so health checks can distinguish \"missing\" from \"empty\".\n */\nfunction iterStateFiles(storeDir: string): string[] {\n if (!isDir(storeDir)) return [];\n const out: string[] = [];\n let accounts: string[];\n try {\n accounts = readdirSync(storeDir);\n } catch {\n return [];\n }\n for (const acct of accounts) {\n const acctDir = join(storeDir, acct);\n if (!isDir(acctDir)) continue;\n let orgs: string[];\n try {\n orgs = readdirSync(acctDir);\n } catch {\n continue;\n }\n for (const org of orgs) {\n const orgDir = join(acctDir, org);\n if (!isDir(orgDir)) continue;\n let entries: string[];\n try {\n entries = readdirSync(orgDir);\n } catch {\n continue;\n }\n for (const name of entries) {\n if (name.startsWith(STATE_PREFIX) && name.endsWith(\".json\")) {\n out.push(join(orgDir, name));\n }\n }\n }\n }\n out.sort();\n return out;\n}\n\n/**\n * Read + parse one `local_*.json` state file. Returns the parsed object, or\n * `null` on any read/parse failure or if the top-level JSON is not an object.\n * Never throws -- malformed files are counted and skipped by callers.\n */\nfunction loadStateJson(path: string): Record<string, unknown> | null {\n let raw: string;\n try {\n raw = readFileSync(path, \"utf8\");\n } catch (exc) {\n logger.warn(`claude-desktop: cannot read ${path}: ${String(exc)}`);\n return null;\n }\n let data: unknown;\n try {\n data = JSON.parse(raw);\n } catch (exc) {\n logger.warn(`claude-desktop: cannot parse ${path}: ${String(exc)}`);\n return null;\n }\n return isRecord(data) ? data : null;\n}\n\n// -- Scalar/date helpers -------------------------------------------------------\n\n/**\n * Convert an epoch timestamp to a UTC `YYYY-MM-DD` string. Accepts ms (`> 1e12`)\n * or seconds; ints, floats, and numeric strings are tolerated. Returns `\"\"` on\n * anything unparseable (bool is rejected explicitly).\n */\nfunction epochToDate(value: unknown): string {\n if (typeof value === \"boolean\") return \"\";\n let num: number | null = null;\n if (typeof value === \"number\") {\n num = value;\n } else if (typeof value === \"string\" && value.trim()) {\n const n = Number(value.trim());\n num = Number.isNaN(n) ? null : n;\n }\n if (num === null || Number.isNaN(num)) return \"\";\n const seconds = num > 1e12 ? num / 1000 : num;\n try {\n const d = new Date(seconds * 1000);\n if (Number.isNaN(d.getTime())) return \"\";\n return d.toISOString().slice(0, 10);\n } catch {\n return \"\";\n }\n}\n\n/** Pick a session date from `createdAt` then `lastActivityAt`. */\nfunction sessionDate(state: Record<string, unknown>): string {\n for (const key of [\"createdAt\", \"lastActivityAt\"]) {\n const parsed = epochToDate(state[key]);\n if (parsed) return parsed;\n }\n return \"\";\n}\n\n/** Redact credential-like text + strip links, then cap to `limit` chars. */\nfunction bounded(value: string, limit = 280): string {\n return redactText(value, limit);\n}\n\n/** Coerce a scalar to a bounded, redacted display string (\"\" if empty). */\nfunction safeLabel(value: unknown, limit = 280): string {\n if (value === null || value === undefined) return \"\";\n const text = String(value).trim();\n if (!text) return \"\";\n return bounded(text, limit);\n}\n\n/**\n * Count `true` values in an `enabledMcpTools` mapping. Keys are\n * `\"<serverUUID>:<tool>\"` and are NOT emitted -- only the count leaks.\n */\nfunction countEnabledMcpTools(enabled: unknown): number {\n if (!isRecord(enabled)) return 0;\n let n = 0;\n for (const v of Object.values(enabled)) {\n if (v === true) n += 1;\n }\n return n;\n}\n\nfunction basenameOf(pathValue: unknown): string {\n if (typeof pathValue !== \"string\" || !pathValue.trim()) return \"\";\n const name = basename(pathValue.trim()).trim();\n return name && name !== \".\" && name !== \"/\" && name !== \"\\\\\" ? name : \"\";\n}\n\n/**\n * Infer project names from cwd + user-selected folders (basenames only), plus a\n * project-hint substring match. Order-preserving + case-insensitively deduped.\n * No file contents and no full paths are emitted.\n */\nfunction inferProjects(state: Record<string, unknown>): string[] {\n const projects: string[] = [];\n const seen = new Set<string>();\n\n const add = (name: string): void => {\n const cleaned = name.trim();\n if (cleaned && !seen.has(cleaned.toLowerCase())) {\n projects.push(cleaned);\n seen.add(cleaned.toLowerCase());\n }\n };\n\n const pathStrings: string[] = [];\n const cwd = state[\"cwd\"];\n if (typeof cwd === \"string\" && cwd.trim()) pathStrings.push(cwd);\n const folders = state[\"userSelectedFolders\"];\n if (Array.isArray(folders)) {\n for (const f of folders) {\n if (typeof f === \"string\" && f.trim()) pathStrings.push(f);\n }\n }\n\n for (const raw of pathStrings) {\n const base = basenameOf(raw);\n if (base) add(base);\n }\n\n const haystack = pathStrings.join(\" \").toLowerCase();\n for (const hint of loadProjectHints(DEFAULT_PROJECT_HINTS)) {\n if (haystack.includes(hint.toLowerCase())) add(hint);\n }\n\n return projects.slice(0, MAX_PROJECTS);\n}\n\n// -- audit.jsonl safe-scalar extraction ----------------------------------------\n\n/** Sibling transcript dir: `local_<id>.json` -> `local_<id>/`. */\nfunction runDirFor(statePath: string): string {\n return join(dirname(statePath), parsePath(statePath).name);\n}\n\n/**\n * Pull safe scalars from one audit record into `out` (in place). Only the\n * `system`/`init` and `result` record types contribute; every other record\n * (user/assistant/etc.) is ignored -- their bodies are never touched.\n */\nfunction absorbAuditRecord(record: Record<string, unknown>, out: Record<string, unknown>): void {\n const recType = record[\"type\"];\n const subtype = record[\"subtype\"];\n\n if (recType === \"system\" && subtype === \"init\") {\n // Counts only -- never the tool/skill/command names themselves.\n const pairs: ReadonlyArray<readonly [string, string]> = [\n [\"tools\", \"init_tools\"],\n [\"mcp_servers\", \"init_mcp_servers\"],\n [\"skills\", \"init_skills\"],\n [\"plugins\", \"init_plugins\"],\n [\"slash_commands\", \"init_slash_commands\"],\n ];\n for (const [srcKey, dstKey] of pairs) {\n const value = record[srcKey];\n if (Array.isArray(value)) out[dstKey] = value.length;\n }\n const version = record[\"claude_code_version\"];\n if (version !== null && version !== undefined) {\n out[\"claude_code_version\"] = safeLabel(version, 40);\n }\n return;\n }\n\n if (recType === \"result\") {\n // The `result` *text* field (free-form summary) is deliberately NOT read.\n for (const key of [\"total_cost_usd\", \"num_turns\", \"is_error\", \"duration_ms\"]) {\n if (key in record) out[key] = record[key];\n }\n const stopReason = record[\"stop_reason\"];\n if (stopReason !== null && stopReason !== undefined) {\n out[\"stop_reason\"] = safeLabel(stopReason, 40);\n }\n }\n}\n\n/**\n * Extract ONLY the safe scalars from a Co-Work `audit.jsonl` transcript. Reads\n * line-by-line, tolerantly. A missing, unreadable, or locked file yields an\n * empty object -- never an error. NEVER reads user/assistant message bodies.\n */\nfunction readAuditScalars(runDir: string): Record<string, unknown> {\n const auditPath = join(runDir, \"audit.jsonl\");\n if (!isFile(auditPath)) return {};\n\n const out: Record<string, unknown> = {};\n let raw: string;\n try {\n raw = readFileSync(auditPath, \"utf8\");\n } catch (exc) {\n logger.warn(`claude-desktop: cannot read ${auditPath}: ${String(exc)}`);\n return out;\n }\n\n let lineNo = 0;\n for (const rawLine of raw.split(/\\r?\\n/)) {\n if (lineNo >= MAX_AUDIT_LINES) break;\n lineNo += 1;\n const line = rawLine.trim();\n if (!line || line[0] !== \"{\") continue;\n let record: unknown;\n try {\n record = JSON.parse(line);\n } catch {\n continue;\n }\n if (!isRecord(record)) continue;\n absorbAuditRecord(record, out);\n }\n return out;\n}\n\n// -- Run model -----------------------------------------------------------------\n\n/** Normalized, privacy-redacted view of a single Co-Work run. */\ninterface CoworkRun {\n runId: string;\n date: string;\n cwd: string;\n title: string;\n model: string;\n permissionMode: string;\n isArchived: boolean;\n mcpToolCount: number;\n projects: string[];\n numTurns: number | null;\n totalCostUsd: number | null;\n isError: boolean | null;\n initCounts: Record<string, number>;\n}\n\nfunction runFromState(statePath: string, state: Record<string, unknown>): CoworkRun {\n const audit = readAuditScalars(runDirFor(statePath));\n\n const title = safeLabel(state[\"title\"], 160) || \"(untitled run)\";\n const model = safeLabel(state[\"model\"], 80);\n const permissionMode = safeLabel(state[\"permissionMode\"], 40);\n\n const numTurnsRaw = audit[\"num_turns\"];\n const costRaw = audit[\"total_cost_usd\"];\n const isErrorRaw = audit[\"is_error\"];\n\n const initCounts: Record<string, number> = {};\n for (const [k, v] of Object.entries(audit)) {\n if (k.startsWith(\"init_\") && typeof v === \"number\" && Number.isInteger(v)) {\n initCounts[k] = v;\n }\n }\n\n const stem = parsePath(statePath).name;\n const sid = state[\"sessionId\"];\n\n return {\n runId: String(sid || stem),\n date: sessionDate(state),\n cwd: safeLabel(state[\"cwd\"], 300),\n title,\n model,\n permissionMode,\n isArchived: Boolean(state[\"isArchived\"]),\n mcpToolCount: countEnabledMcpTools(state[\"enabledMcpTools\"]),\n projects: inferProjects(state),\n numTurns: typeof numTurnsRaw === \"number\" && Number.isInteger(numTurnsRaw) ? numTurnsRaw : null,\n totalCostUsd: typeof costRaw === \"number\" ? costRaw : null,\n isError: typeof isErrorRaw === \"boolean\" ? isErrorRaw : null,\n initCounts,\n };\n}\n\n/**\n * Build the bounded, redacted key-action list for a run:\n * `[title, \"model: ...\", \"permission: ...\", \"<n> turns\", \"$<cost>\", \"error\",\n * \"mcp-tools: <n>\"]` -- all metadata, never content.\n */\nfunction keyActions(run: CoworkRun): string[] {\n const actions: string[] = [bounded(run.title, 160)];\n if (run.model) actions.push(bounded(`model: ${run.model}`, 120));\n if (run.permissionMode) actions.push(bounded(`permission: ${run.permissionMode}`, 80));\n if (run.numTurns !== null) actions.push(`${run.numTurns} turns`);\n if (run.totalCostUsd !== null) actions.push(`$${run.totalCostUsd.toFixed(2)}`);\n if (run.isError) actions.push(\"error\");\n if (run.mcpToolCount) actions.push(`mcp-tools: ${run.mcpToolCount}`);\n return actions.slice(0, MAX_KEY_ACTIONS);\n}\n\nfunction sessionFromRun(run: CoworkRun): SessionModel {\n return makeSession({\n date: run.date,\n cwd: run.cwd || undefined, // run.cwd or None -- privacy: never empty string\n project_focus: [...run.projects],\n key_actions: keyActions(run),\n files_touched: [], // never list user files -- privacy\n visibility: Visibility.TEAM,\n });\n}\n\n/** Manifest-level capability *counts* only (no names). */\nfunction capabilities(runs: CoworkRun[]): string[] {\n const caps: string[] = [AGENT_ID];\n const maxMcp = runs.length ? Math.max(...runs.map((r) => r.mcpToolCount)) : 0;\n caps.push(`mcp-tools:${maxMcp}`);\n const bestTools = runs.length ? Math.max(...runs.map((r) => r.initCounts[\"init_tools\"] ?? 0)) : 0;\n if (bestTools) caps.push(`tools:${bestTools}`);\n const bestSkills = runs.length\n ? Math.max(...runs.map((r) => r.initCounts[\"init_skills\"] ?? 0))\n : 0;\n if (bestSkills) caps.push(`skills:${bestSkills}`);\n return caps;\n}\n\nfunction entitiesFromRuns(runs: CoworkRun[]): EntityModel[] {\n const lastSeen = runs.length\n ? runs.map((r) => r.date).reduce((a, b) => (a > b ? a : b))\n : null;\n\n const entities = new Map<string, EntityModel>();\n entities.set(\n SURFACE_ENTITY_NAME,\n makeEntity({\n name: SURFACE_ENTITY_NAME,\n type: \"agent-surface\",\n summary: bounded(\n \"Claude desktop app Co-Work / local-agent mode surface \" +\n \"(metadata-only federation).\",\n 260,\n ),\n last_touched: lastSeen,\n tags: [\"claude-desktop\", \"claude-desktop-cowork\", \"agent-surface\"],\n visibility: Visibility.TEAM,\n }),\n );\n\n for (const run of runs) {\n for (const project of run.projects) {\n if (!entities.has(project)) {\n entities.set(\n project,\n makeEntity({\n name: project,\n type: \"project\",\n summary: \"Project inferred from a Claude Desktop Co-Work run cwd.\",\n last_touched: run.date || undefined, // run.date or None\n tags: [\"claude-desktop\", \"claude-desktop-cowork\", \"project\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n }\n }\n\n return [...entities.values()];\n}\n\n// -- Participant ---------------------------------------------------------------\n\n/** External participant for the Claude desktop app's Co-Work surface. */\nexport class ClaudeDesktopCoworkParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n displayName = DISPLAY_NAME;\n\n private readonly storeDir: string;\n private readonly policy: VisibilityPolicyModel;\n\n /**\n * The Co-Work sub-store dir the setup wizard probes for presence. Resolves to\n * `<desktop>/local-agent-mode-sessions`. When the desktop dir cannot be\n * resolved on this platform, falls back to a non-existent sentinel under\n * `home` so the wizard reports \"not found\" rather than crashing.\n */\n static defaultNativePath(home?: string): string {\n const desktop = defaultClaudeDesktopDir(home);\n if (desktop === null) return join(home || homeDir(), \"Claude\", COWORK_STORE);\n return join(desktop, COWORK_STORE);\n }\n\n constructor(storeDir?: string, home?: string) {\n this.storeDir = storeDir || ClaudeDesktopCoworkParticipant.defaultNativePath(home);\n this.policy = DEFAULT_POLICY;\n }\n\n get nativePath(): string {\n return this.storeDir;\n }\n\n // -- Protocol surface --------------------------------------------------------\n\n discover(): AgentStore {\n if (!isDir(this.storeDir)) {\n throw new ParticipantDiscoveryError(\n `Claude Desktop Co-Work store not found at ${this.storeDir}.`,\n );\n }\n const stateFiles = iterStateFiles(this.storeDir);\n return {\n path: this.storeDir,\n version: \"unknown\",\n metadata: { runs: stateFiles.length },\n };\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const runs = this.runs(since);\n const sessions = runs.map(sessionFromRun);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n return sessions.slice(0, limit);\n }\n\n exportL5(since?: Date): L5ManifestModel {\n if (!isDir(this.storeDir)) {\n throw new ParticipantDiscoveryError(\n `Claude Desktop Co-Work store not found at ${this.storeDir}.`,\n );\n }\n const runs = this.runs(since);\n const sessions = runs.map(sessionFromRun);\n sessions.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n const entities = entitiesFromRuns(runs);\n const visibleEntities = filterForFederation(entities, this.policy);\n\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: hostname(),\n spec_version_compat: SPEC_VERSION,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: isoSeconds(),\n capabilities: capabilities(runs),\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: this.policy,\n });\n }\n\n healthCheck(): HealthStatus {\n if (!isDir(this.storeDir)) {\n return {\n status: \"blocked\",\n reason: `Claude Desktop Co-Work store not found at ${this.storeDir}.`,\n details: { store_dir: this.storeDir },\n proposedFix:\n \"Install the Claude desktop app and run a Co-Work / local-agent \" +\n \"session once. Set BOURDON_CLAUDE_DESKTOP_DIR if the app stores \" +\n \"state in a non-standard location.\",\n };\n }\n\n let stateFiles: string[];\n let runs: CoworkRun[];\n let malformed: number;\n try {\n stateFiles = iterStateFiles(this.storeDir);\n [runs, malformed] = this.collectRuns();\n } catch (exc) {\n logger.warn(`ClaudeDesktopCoworkParticipant health_check failed: ${String(exc)}`);\n return {\n status: \"degraded\",\n reason: \"Co-Work store present but extraction failed.\",\n details: { error: String(exc) },\n proposedFix:\n \"Close the Claude desktop app (its state files may be locked) and \" +\n \"re-run `bourdon claude-desktop-cowork export`.\",\n };\n }\n\n if (stateFiles.length === 0) {\n return {\n status: \"degraded\",\n reason: \"No Co-Work runs found under the store directory.\",\n details: { store_dir: this.storeDir },\n proposedFix:\n \"Run a Co-Work / local-agent session in the Claude desktop app, \" +\n \"then re-run `bourdon claude-desktop-cowork export`.\",\n };\n }\n\n return {\n status: \"ok\",\n details: {\n store_dir: this.storeDir,\n run_count: stateFiles.length,\n runs_extracted: runs.length,\n malformed_records: malformed,\n runs_with_scalars: runs.filter((r) => r.numTurns !== null).length,\n },\n };\n }\n\n // -- Internal ----------------------------------------------------------------\n\n private collectRuns(): [CoworkRun[], number] {\n const runs: CoworkRun[] = [];\n let malformed = 0;\n for (const statePath of iterStateFiles(this.storeDir)) {\n const state = loadStateJson(statePath);\n if (state === null) {\n malformed += 1;\n continue;\n }\n runs.push(runFromState(statePath, state));\n }\n return [runs, malformed];\n }\n\n private runs(since?: Date): CoworkRun[] {\n const [runs] = this.collectRuns();\n let filtered = runs;\n if (since !== undefined) {\n const cutoff = new Date(since.getTime()).toISOString().slice(0, 10);\n filtered = runs.filter((run) => !run.date || run.date >= cutoff);\n }\n filtered.sort((a, b) => {\n if (a.date !== b.date) return a.date < b.date ? 1 : -1;\n if (a.runId !== b.runId) return a.runId < b.runId ? 1 : -1;\n return 0;\n });\n return filtered;\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * GitHub Copilot · VS Code participant — reads the GUI Copilot Chat extension's\n * per-workspace transcripts + repo-scoped memory. Port of\n * `participants/copilot_vscode.py`.\n *\n * VS Code's Copilot Chat extension stores per-workspace data at\n * `<workspaceStorage>/<hash>/GitHub.copilot-chat/`:\n * - `transcripts/<session-uuid>.jsonl` — event stream per chat session\n * - `memory-tool/memories/**\\/*.md` — per-repo memory (markdown bullets)\n *\n * This is a FILE/CONVENTION reader (not SQLite, not network): it walks the\n * workspaceStorage tree read-only, parses JSONL transcripts + markdown memory\n * files, aggregates across every workspace hash, redacts every native string,\n * applies the visibility filter BEFORE emission, and is deterministic.\n * `healthCheck` never throws.\n *\n * Distinct from:\n * - `copilot` (convention-file at `~/.copilot-bourdon/memory.md`)\n * - `copilot-cli` (terminal agent, `~/.copilot/session-store.db`, SQLite)\n * - `github-copilot` (network reader — GitHub-embedded Copilot)\n */\n\nimport { readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { homedir, hostname, platform } from \"node:os\";\nimport { join, relative } from \"node:path\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeEntity,\n makeManifest,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ParticipantDiscoveryError,\n SPEC_VERSION,\n type AgentStore,\n type BourdonParticipant,\n type HealthStatus,\n} from \"../base.js\";\n\nconst AGENT_ID = \"copilot-vscode\";\nconst AGENT_TYPE = \"code-assistant\";\nconst DISPLAY_NAME = \"GitHub Copilot · VS Code\";\nconst ROLE_NARRATIVE =\n \"VS Code integrated Copilot Chat — the GUI surface for inline completion, \" +\n \"chat, plan mode, ask mode, and explore mode. Persists per-workspace \" +\n \"transcripts and repo-scoped memory locally. The most widely-used Copilot \" +\n \"surface by session count.\";\n\nconst DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"financial\", \"credential\", \"health\", \"family\", \"legal\"],\n team_tags: [\"copilot-vscode\", \"copilot\", \"vscode\", \"workspace\"],\n});\n\nconst COPILOT_CHAT_EXT = \"GitHub.copilot-chat\";\nconst TRANSCRIPTS_DIR = \"transcripts\";\nconst MEMORY_TOOL_DIR = \"memory-tool\";\nconst MAX_KEY_ACTIONS = 6;\nconst MAX_KEY_ACTION_CHARS = 280;\nconst MAX_SUMMARY_CHARS = 260;\nconst MAX_TRANSCRIPT_EVENTS = 500; // cap per file to avoid loading multi-MB transcripts fully\n\n// -- fs helpers ---------------------------------------------------------------\n\nfunction homeDir(): string {\n // os.homedir() can throw under some sandboxes; stay defensive so import +\n // construction never crash even when HOME points at an unreadable path.\n try {\n return homedir();\n } catch {\n return process.env.HOME || process.env.USERPROFILE || \".\";\n }\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\n/** Redact secrets + clamp to the native-memory limit (`_safe_native_memory_text`). */\nfunction safeNativeMemoryText(value: string, limit = 180): string {\n return redactText(value, limit);\n}\n\n/**\n * Collapse whitespace and clamp with a single-char ellipsis (mirrors the\n * oracle's `_bounded`). Distinct from {@link redactText}'s `...` clamp — this\n * one uses `…` (U+2026) and does no redaction.\n */\nfunction bounded(value: string, limit: number): string {\n const normalized = value.split(/\\s+/).filter(Boolean).join(\" \");\n if (normalized.length <= limit) return normalized;\n return normalized.slice(0, limit - 1).replace(/\\s+$/, \"\") + \"…\";\n}\n\n/** Python `str.splitlines()` — split on \\r\\n, \\r, or \\n. */\nfunction splitLines(text: string): string[] {\n return text.split(/\\r\\n|\\r|\\n/);\n}\n\n// -- Path resolution ----------------------------------------------------------\n\n/**\n * Return the VS Code workspaceStorage path for this platform, or null when it\n * cannot be resolved (Windows without `%APPDATA%`). Respects the\n * `COPILOT_VSCODE_STORAGE` environment-variable override. Mirrors\n * `default_vscode_workspace_storage_dir`.\n */\nexport function defaultVscodeWorkspaceStorageDir(): string | null {\n const env = process.env.COPILOT_VSCODE_STORAGE;\n if (env) return env;\n\n // Map Node's os.platform() onto Python's platform.system().\n const system = platform();\n if (system === \"win32\") {\n const appdata = process.env.APPDATA;\n if (appdata) return join(appdata, \"Code\", \"User\", \"workspaceStorage\");\n return null;\n }\n if (system === \"darwin\") {\n return join(\n homeDir(),\n \"Library\",\n \"Application Support\",\n \"Code\",\n \"User\",\n \"workspaceStorage\",\n );\n }\n // Linux / WSL — check the Windows path under /mnt/c if WSL, else native.\n const wslPath = \"/mnt/c/Users\";\n if (isDir(wslPath)) {\n try {\n for (const candidate of readdirSync(wslPath)) {\n try {\n const ws = join(\n wslPath,\n candidate,\n \"AppData\",\n \"Roaming\",\n \"Code\",\n \"User\",\n \"workspaceStorage\",\n );\n if (isDir(ws)) return ws;\n } catch {\n continue;\n }\n }\n } catch {\n // fall through to native Linux\n }\n }\n const config = process.env.XDG_CONFIG_HOME || join(homeDir(), \".config\");\n return join(config, \"Code\", \"User\", \"workspaceStorage\");\n}\n\n/** Find all workspace hashes that contain Copilot Chat data. */\nfunction findCopilotChatDirs(workspaceStorage: string): string[] {\n if (!isDir(workspaceStorage)) return [];\n const dirs: string[] = [];\n try {\n for (const wsHash of readdirSync(workspaceStorage)) {\n const chatDir = join(workspaceStorage, wsHash, COPILOT_CHAT_EXT);\n if (isDir(chatDir)) dirs.push(chatDir);\n }\n } catch (exc) {\n logger.warn(`CopilotVscodeParticipant: cannot scan workspace storage: ${String(exc)}`);\n }\n return dirs;\n}\n\n/** Minimal logger so a scan warning is visible without a dep. */\nconst logger = {\n warn(msg: string): void {\n // eslint-disable-next-line no-console\n console.warn(`[bourdon.participants] ${msg}`);\n },\n};\n\n// -- Transcript parsing -------------------------------------------------------\n\ninterface TranscriptInfo {\n transcript_path: string;\n session_id: string;\n start_time: string | null;\n producer: unknown;\n copilot_version: unknown;\n vscode_version: unknown;\n user_messages: string[];\n turn_count: number;\n}\n\n/**\n * Parse a JSONL transcript file into a session summary. Returns null on any\n * read/empty error. Never raises.\n */\nfunction parseTranscript(path: string): TranscriptInfo | null {\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch {\n return null;\n }\n\n const lines = text.trim() ? splitLines(text.trim()) : [];\n if (lines.length === 0) return null;\n\n const info: TranscriptInfo = {\n transcript_path: path,\n session_id: stem(path),\n start_time: null,\n producer: null,\n copilot_version: null,\n vscode_version: null,\n user_messages: [],\n turn_count: 0,\n };\n\n let turnCount = 0;\n const userMsgs: string[] = [];\n\n for (const line of lines.slice(0, MAX_TRANSCRIPT_EVENTS)) {\n let event: unknown;\n try {\n event = JSON.parse(line);\n } catch {\n continue;\n }\n if (typeof event !== \"object\" || event === null) continue;\n const ev = event as Record<string, unknown>;\n const eventType = ev[\"type\"];\n const dataRaw = ev[\"data\"];\n const data =\n typeof dataRaw === \"object\" && dataRaw !== null\n ? (dataRaw as Record<string, unknown>)\n : {};\n\n if (eventType === \"session.start\") {\n info.start_time = data[\"startTime\"] == null ? null : String(data[\"startTime\"]);\n info.producer = data[\"producer\"] ?? null;\n info.copilot_version = data[\"copilotVersion\"] ?? null;\n info.vscode_version = data[\"vscodeVersion\"] ?? null;\n } else if (eventType === \"user.message\") {\n const content = data[\"content\"] ? String(data[\"content\"]) : \"\";\n if (content) {\n // Truncate long messages but keep enough for entity extraction.\n userMsgs.push(content.slice(0, 200));\n }\n } else if (eventType === \"assistant.turn_end\") {\n turnCount += 1;\n }\n }\n\n info.user_messages = userMsgs.slice(0, 20);\n info.turn_count = turnCount;\n return info;\n}\n\n/** Basename minus final extension (Python `Path.stem`). */\nfunction stem(p: string): string {\n const base = p.replace(/[\\\\/]+$/, \"\").split(/[\\\\/]/).pop() ?? \"\";\n return base.replace(/\\.[^.]+$/, \"\");\n}\n\n// -- Memory-tool parsing ------------------------------------------------------\n\ninterface MemoryFile {\n name: string;\n content: string;\n path: string;\n bullet_count: number;\n}\n\n/** Recursively collect `*.md` files under `dir`, sorted for determinism. */\nfunction walkMarkdown(dir: string): string[] {\n const out: string[] = [];\n let entries: string[];\n try {\n entries = readdirSync(dir).sort();\n } catch {\n return out;\n }\n for (const name of entries) {\n const full = join(dir, name);\n if (isDir(full)) {\n out.push(...walkMarkdown(full));\n } else if (name.endsWith(\".md\")) {\n out.push(full);\n }\n }\n return out;\n}\n\n/**\n * Parse memory-tool markdown files from a Copilot Chat workspace. Each file is a\n * bulleted list of learned facts. Returns a list of {name, content, path, ...}.\n */\nfunction parseMemoryFiles(chatDir: string): MemoryFile[] {\n const memoryDir = join(chatDir, MEMORY_TOOL_DIR, \"memories\");\n if (!isDir(memoryDir)) return [];\n\n const memories: MemoryFile[] = [];\n for (const mdFile of walkMarkdown(memoryDir)) {\n let text: string;\n try {\n text = readFileSync(mdFile, \"utf8\");\n } catch {\n continue;\n }\n if (!text.trim()) continue;\n // Name from relative path (e.g. \"repo/mobile-scaffold\"), suffix stripped,\n // backslashes normalized to forward slashes.\n const rel = relative(memoryDir, mdFile);\n const name = rel.replace(/\\.[^./\\\\]*$/, \"\").replace(/\\\\/g, \"/\");\n const bulletCount = text.split(\"\\n- \").length - 1 + (text.startsWith(\"- \") ? 1 : 0);\n memories.push({ name, content: text, path: mdFile, bullet_count: bulletCount });\n }\n return memories;\n}\n\n// -- Conversion to Bourdon types ----------------------------------------------\n\nfunction sessionFromTranscript(info: TranscriptInfo): SessionModel {\n const start = info.start_time ?? \"\";\n const dateStr = start ? start.slice(0, 10) : \"\";\n\n const keyActions: string[] = [];\n const msgs = info.user_messages ?? [];\n if (msgs.length > 0) {\n keyActions.push(bounded(safeNativeMemoryText(String(msgs[0])), MAX_KEY_ACTION_CHARS));\n }\n if (info.turn_count) keyActions.push(`turns: ${info.turn_count}`);\n if (info.copilot_version) keyActions.push(`copilot: ${String(info.copilot_version)}`);\n if (info.producer) keyActions.push(`mode: ${String(info.producer)}`);\n\n return makeSession({\n date: dateStr,\n cwd: undefined,\n project_focus: [],\n key_actions: keyActions.slice(0, MAX_KEY_ACTIONS),\n files_touched: [],\n visibility: Visibility.TEAM,\n });\n}\n\nfunction entitiesFromMemories(memories: MemoryFile[]): EntityModel[] {\n const entities: EntityModel[] = [];\n for (const mem of memories) {\n const bullets: string[] = [];\n for (const line of splitLines(mem.content)) {\n const stripped = line.trim();\n if (stripped.startsWith(\"- \")) {\n bullets.push(stripped.slice(2).trim());\n if (bullets.length === 3) break;\n }\n }\n let summary: string | undefined =\n bullets.length > 0 ? bullets.join(\"; \") : undefined;\n if (summary) summary = bounded(safeNativeMemoryText(summary), MAX_SUMMARY_CHARS);\n\n entities.push(\n makeEntity({\n name: mem.name,\n type: \"vscode-memory\",\n summary,\n last_touched: undefined,\n tags: [\"copilot-vscode\", \"memory-tool\", \"repo-memory\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n return entities;\n}\n\nfunction entitiesFromTranscripts(transcripts: TranscriptInfo[]): EntityModel[] {\n // Simple frequency-based extraction from first messages (insertion-ordered).\n const topicCounts = new Map<string, number>();\n for (const info of transcripts) {\n const msgs = info.user_messages ?? [];\n if (msgs.length > 0) {\n const first = String(msgs[0]).slice(0, 100);\n const slashMatch = /^\\/(\\S+)/.exec(first);\n if (slashMatch) {\n const topic = `copilot-command:${slashMatch[1]}`;\n topicCounts.set(topic, (topicCounts.get(topic) ?? 0) + 1);\n }\n }\n }\n\n // sorted(items, key=lambda x: -x[1])[:10] — stable, so ties keep insertion order.\n const ordered = [...topicCounts.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 10);\n\n const entities: EntityModel[] = [];\n for (const [topic, count] of ordered) {\n entities.push(\n makeEntity({\n name: topic,\n type: \"vscode-capability\",\n summary: `VS Code Copilot command used ${count} time(s).`,\n tags: [\"copilot-vscode\", \"capability\"],\n visibility: Visibility.TEAM,\n }),\n );\n }\n return entities;\n}\n\n// -- Participant --------------------------------------------------------------\n\n/**\n * External participant for GitHub Copilot in VS Code. Reads transcripts and\n * memory-tool files from VS Code's workspaceStorage read-only, aggregating\n * across all workspace hashes.\n */\nexport class CopilotVscodeParticipant implements BourdonParticipant {\n agentId = AGENT_ID;\n agentType = AGENT_TYPE;\n displayName = DISPLAY_NAME;\n\n private readonly workspaceStorage: string | null;\n\n /** The workspaceStorage dir the setup wizard probes for presence. */\n static defaultNativePath(home?: string): string {\n if (home !== undefined) {\n return join(home, \".config\", \"Code\", \"User\", \"workspaceStorage\");\n }\n let ws: string | null;\n try {\n ws = defaultVscodeWorkspaceStorageDir();\n } catch {\n ws = null;\n }\n if (ws !== null) return ws;\n return join(homeDir(), \".config\", \"Code\", \"User\", \"workspaceStorage\");\n }\n\n constructor(workspaceStorage?: string) {\n this.workspaceStorage = workspaceStorage ?? null;\n }\n\n get nativePath(): string {\n return this.workspaceStorage ?? defaultVscodeWorkspaceStorageDir() ?? \"\";\n }\n\n private resolveWs(): string | null {\n return this.workspaceStorage ?? defaultVscodeWorkspaceStorageDir();\n }\n\n // -- Protocol surface -------------------------------------------------------\n\n discover(): AgentStore {\n const ws = this.resolveWs();\n if (ws === null || !isDir(ws)) {\n throw new ParticipantDiscoveryError(\n `VS Code workspaceStorage not found at ${ws ?? \"None\"}. ` +\n \"Install VS Code with the GitHub Copilot Chat extension.\",\n );\n }\n const chatDirs = findCopilotChatDirs(ws);\n if (chatDirs.length === 0) {\n throw new ParticipantDiscoveryError(\n `No GitHub.copilot-chat data found under ${ws}. ` +\n \"Open VS Code and use Copilot Chat at least once.\",\n );\n }\n return {\n path: ws,\n version: \"transcript-v1\",\n metadata: {\n workspace_count: chatDirs.length,\n workspace_storage_path: ws,\n },\n };\n }\n\n exportSessions(since?: Date, limit = 100): SessionModel[] {\n const sinceIso = since ? since.toISOString().slice(0, 10) : null;\n const transcripts = this.allTranscripts();\n const sessions: SessionModel[] = [];\n for (const info of transcripts) {\n const session = sessionFromTranscript(info);\n if (sinceIso && session.date && session.date < sinceIso) continue;\n sessions.push(session);\n if (sessions.length >= limit) break;\n }\n return sessions;\n }\n\n exportL5(since?: Date): L5ManifestModel {\n const transcripts = this.allTranscripts();\n const memories = this.allMemories();\n\n const sinceIso = since ? since.toISOString().slice(0, 10) : null;\n const sessions: SessionModel[] = [];\n for (const info of transcripts) {\n const session = sessionFromTranscript(info);\n if (sinceIso && session.date && session.date < sinceIso) continue;\n sessions.push(session);\n }\n\n const entities = [\n ...entitiesFromMemories(memories),\n ...entitiesFromTranscripts(transcripts),\n ];\n const visibleEntities = filterForFederation(entities, DEFAULT_POLICY);\n\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: AGENT_ID,\n type: AGENT_TYPE,\n instance: hostname() || \"unknown\",\n spec_version_compat: `>=${SPEC_VERSION}`,\n role_narrative: ROLE_NARRATIVE,\n }),\n last_updated: new Date().toISOString(),\n capabilities: [\n \"inline-completion\",\n \"chat\",\n \"plan-mode\",\n \"ask-mode\",\n \"explore-mode\",\n \"memory-tool\",\n \"workspace-scoped\",\n ],\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: DEFAULT_POLICY,\n });\n }\n\n healthCheck(): HealthStatus {\n try {\n const ws = this.resolveWs();\n if (ws === null || !isDir(ws)) {\n return {\n status: \"blocked\",\n reason: `VS Code workspaceStorage not found at ${ws ?? \"None\"}.`,\n details: { expected_path: ws ?? \"None\" },\n proposedFix:\n \"Install VS Code and the GitHub Copilot Chat extension. \" +\n \"Set COPILOT_VSCODE_STORAGE if VS Code stores data elsewhere.\",\n };\n }\n const chatDirs = findCopilotChatDirs(ws);\n if (chatDirs.length === 0) {\n return {\n status: \"degraded\",\n reason: \"No Copilot Chat data found in any workspace.\",\n details: { workspace_storage: ws },\n proposedFix:\n \"Open VS Code and start a Copilot Chat conversation, \" +\n \"then re-run `bourdon copilot-vscode export`.\",\n };\n }\n const transcripts = this.allTranscripts();\n const memories = this.allMemories();\n return {\n status: \"ok\",\n details: {\n workspace_storage: ws,\n workspace_count: chatDirs.length,\n transcript_count: transcripts.length,\n memory_file_count: memories.length,\n total_turns: transcripts.reduce((acc, t) => acc + (t.turn_count || 0), 0),\n },\n };\n } catch (err) {\n // healthCheck must NEVER raise (contract).\n return {\n status: \"degraded\",\n reason: `unexpected error: ${String(err)}`,\n details: {},\n };\n }\n }\n\n // -- Internal ---------------------------------------------------------------\n\n /** Collect and parse all transcripts across all workspaces. */\n private allTranscripts(): TranscriptInfo[] {\n const ws = this.resolveWs();\n if (ws === null) return [];\n const chatDirs = findCopilotChatDirs(ws);\n const transcripts: TranscriptInfo[] = [];\n for (const chatDir of chatDirs) {\n const transcriptDir = join(chatDir, TRANSCRIPTS_DIR);\n if (!isDir(transcriptDir)) continue;\n let files: string[];\n try {\n files = readdirSync(transcriptDir).sort();\n } catch {\n continue;\n }\n for (const fname of files) {\n if (!fname.endsWith(\".jsonl\")) continue;\n const info = parseTranscript(join(transcriptDir, fname));\n if (info !== null) transcripts.push(info);\n }\n }\n // Sort by start_time descending (missing → \"\").\n transcripts.sort((a, b) => {\n const av = a.start_time ?? \"\";\n const bv = b.start_time ?? \"\";\n return av < bv ? 1 : av > bv ? -1 : 0;\n });\n return transcripts;\n }\n\n /** Collect all memory-tool files across all workspaces. */\n private allMemories(): MemoryFile[] {\n const ws = this.resolveWs();\n if (ws === null) return [];\n const chatDirs = findCopilotChatDirs(ws);\n const memories: MemoryFile[] = [];\n for (const chatDir of chatDirs) {\n memories.push(...parseMemoryFiles(chatDir));\n }\n return memories;\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Codex session-index title lookup — narrow port of the three\n * `session_thread_titles` helpers in `participants/codex.py`.\n *\n * SCOPE (deliberately tiny): this is NOT the Codex participant/reader (the\n * ~2.6k-line turn-compiler still lands in a follow-on slice). It ports ONLY the\n * surface the tray/presence join needs — a `session_id -> human thread title`\n * map read from `~/.codex/session_index.jsonl`.\n *\n * Why only the index: `session_thread_titles()` runs on EVERY tray refresh, so\n * it must never touch rollout files. One small JSONL read, newest-first, done.\n * It covers Codex CLI sessions AND ChatGPT-app threads — the app's Work and\n * Codex modes share `~/.codex`, so `thread_name` is the human title for both.\n *\n * PRIVACY: titles are raw user text. Callers that EXPORT them MUST route them\n * through the audited redaction pipeline (`redactField` in\n * `mcp-server/src/agents-export.ts`, == Python's `_redact_field`), exactly like\n * every other emitted string. This module deliberately does NOT redact — the\n * redaction happens at the single audited egress point so it can't be\n * double-applied or silently skipped.\n *\n * Best-effort by construction: a missing dir, an unreadable file, or a corrupt\n * line degrades to fewer/no titles. Nothing here throws.\n */\n\nimport { readFileSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\n/** Default number of index records considered (newest-first). */\nexport const DEFAULT_TITLE_LIMIT = 200;\n\n/** Default number of threads on the tray codex card (newest-first). */\nexport const DEFAULT_RECENT_THREAD_LIMIT = 5;\n\n/** Collapse internal whitespace runs — mirrors Python `_normalize_text`. */\nfunction normalizeText(value: string): string {\n return value.trim().replace(/\\s+/g, \" \");\n}\n\nfunction isDir(path: string): boolean {\n try {\n return statSync(path).isDirectory();\n } catch {\n return false;\n }\n}\n\n/**\n * Locate `~/.codex/` (the primary Codex store), or null.\n *\n * Resolution order, mirroring `_resolve_codex_home()` exactly:\n * 1. `$CODEX_HOME` — **only if that directory already exists**\n * 2. `~/.codex` — only if it exists\n * 3. `null`\n *\n * ⚠ FOOTGUN (preserved for parity, do not \"fix\" without changing Python too):\n * step 1 is a silent fallback, not a pin. If `$CODEX_HOME` points at a path that\n * does not exist yet, the env var is IGNORED and this returns the developer's\n * REAL `~/.codex`. A sandbox/test that sets `CODEX_HOME` to a temp path without\n * `mkdir`-ing it first looks isolated but reads live data. Always create the\n * directory before setting the variable.\n */\nexport function resolveCodexHome(baseHome?: string | null): string | null {\n const env = process.env.CODEX_HOME;\n if (env) {\n // Existence check FIRST — see the footgun note above.\n if (isDir(env)) return env;\n }\n const home = baseHome ? baseHome : homedir();\n const candidate = join(home, \".codex\");\n return isDir(candidate) ? candidate : null;\n}\n\n/**\n * Read `session_index.jsonl`, newest-first by `updated_at`.\n *\n * Port of `_parse_session_index()`. Per-line JSON parse: a malformed line is\n * WARNED and SKIPPED — it never aborts the scan (one bad append must not blind\n * the tray to every other session). An unreadable file warns and yields `[]`.\n * Only records that are objects with a string `id` are kept.\n */\nexport function parseSessionIndex(\n path: string,\n limit?: number | null,\n): Record<string, unknown>[] {\n let text: string;\n try {\n if (!statSync(path).isFile()) return [];\n text = readFileSync(path, \"utf8\");\n } catch (exc) {\n // Covers both \"missing\" (Python's `is_file()` guard) and OSError-on-read.\n if (existsQuiet(path)) console.warn(`Failed to read ${path}: ${String(exc)}`);\n return [];\n }\n\n const entries: Record<string, unknown>[] = [];\n const lines = text.split(/\\r?\\n/);\n for (let i = 0; i < lines.length; i += 1) {\n const line = lines[i]!.trim();\n if (!line) continue;\n let record: unknown;\n try {\n record = JSON.parse(line);\n } catch (exc) {\n console.warn(`Skipping malformed JSONL in ${path}:${i + 1} -- ${String(exc)}`);\n continue;\n }\n if (\n record !== null &&\n typeof record === \"object\" &&\n !Array.isArray(record) &&\n typeof (record as Record<string, unknown>).id === \"string\"\n ) {\n entries.push(record as Record<string, unknown>);\n }\n }\n\n // Descending by `updated_at` (missing key sorts as \"\"), stable on ties —\n // mirrors Python's `sort(key=..., reverse=True)` on a stable sort.\n entries.sort((a, b) => {\n const ua = String(a.updated_at ?? \"\");\n const ub = String(b.updated_at ?? \"\");\n return ua < ub ? 1 : ua > ub ? -1 : 0;\n });\n return limit !== undefined && limit !== null ? entries.slice(0, limit) : entries;\n}\n\n/** True if the path exists at all (distinguishes \"missing\" from \"unreadable\"). */\nfunction existsQuiet(path: string): boolean {\n try {\n statSync(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Map full Codex session id → human thread title, newest-first.\n *\n * Port of `session_thread_titles()`. Reads ONLY `session_index.jsonl` — no\n * rollout I/O, because this runs on every tray refresh. A missing/malformed\n * index yields `{}`.\n *\n * NEWEST WINS: entries are already sorted newest-first and the insert is a\n * `setdefault` equivalent, so the freshest `thread_name` for a repeated id is\n * the one kept.\n *\n * Titles are RAW USER TEXT — see the module note; the exporter redacts.\n */\nexport function sessionThreadTitles(\n codexHome?: string | null,\n opts: { limit?: number } = {},\n): Record<string, string> {\n const limit = opts.limit ?? DEFAULT_TITLE_LIMIT;\n const home =\n codexHome === undefined || codexHome === null ? resolveCodexHome() : codexHome;\n if (home === null) return {};\n\n const titles: Record<string, string> = {};\n for (const entry of parseSessionIndex(join(home, \"session_index.jsonl\"), limit)) {\n const sid = entry.id;\n const name = entry.thread_name;\n if (\n typeof sid === \"string\" &&\n sid &&\n typeof name === \"string\" &&\n name.trim() &&\n !(sid in titles) // setdefault: first (== newest) wins\n ) {\n titles[sid] = normalizeText(name);\n }\n }\n return titles;\n}\n\n/** One row of the tray codex card. NOTE: `instance`, never a full session id. */\nexport interface RecentThread {\n instance: string;\n title: string | null;\n updated_at: string | null;\n}\n\n/**\n * Newest-first `[{instance, title, updated_at}]` for the tray codex card.\n *\n * Port of `recent_session_threads()`. Independent of PRESENCE: ChatGPT-app\n * threads fire no presence hooks, so this is the only way they surface.\n *\n * Emits only the 8-char `instance` prefix — parity with `presence.summarize`:\n * a full session id never leaves the local read path. Titles are RAW USER TEXT;\n * the exporter redacts them (see `sessionThreadTitles`).\n */\nexport function recentSessionThreads(\n codexHome?: string | null,\n opts: { limit?: number } = {},\n): RecentThread[] {\n const limit = opts.limit ?? DEFAULT_RECENT_THREAD_LIMIT;\n const home =\n codexHome === undefined || codexHome === null ? resolveCodexHome() : codexHome;\n if (home === null) return [];\n\n const threads: RecentThread[] = [];\n for (const entry of parseSessionIndex(join(home, \"session_index.jsonl\"), limit)) {\n const sid = entry.id;\n if (typeof sid !== \"string\" || !sid) continue;\n const name = entry.thread_name;\n const title =\n typeof name === \"string\" && name.trim() ? normalizeText(name) : null;\n const updated = String(entry.updated_at ?? \"\");\n threads.push({\n instance: sid.slice(0, 8),\n title,\n updated_at: updated || null,\n });\n }\n return threads;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Shared skill store: the library-level home of federated procedural memory.\n * Port of the store half of the engine's `core/skill_index.py` (plan 005,\n * phase 1); the content rules it relies on are in `skill-index.ts`.\n *\n * Layout (one folder per shared skill, beside the per-agent manifests):\n *\n * <library>/skills/<name>/\n * SKILL.md verbatim body, as promoted\n * skill.yaml index row (the skill index schema)\n * files/... reference files, verbatim, text-only, size-capped\n * .versions/<n>/ the same three entries for each replaced version\n *\n * Load-bearing rules:\n *\n * - **Org-tier write semantics.** The store is readable by every caller allowed\n * to read the federation and writable only through {@link promoteSkill}. The\n * ordinary federation write path never touches `<library>/skills`.\n * - **One namespace, rename at promotion.** A shared name belongs to one skill.\n * Promoting under a taken name throws {@link SkillNameCollisionError} with a\n * free suggestion, unless the caller updates that skill by passing the\n * current version as `expectedVersion` (also the compare-and-swap that stops\n * two promotions from silently overwriting each other). A renamed skill keeps\n * its front-matter name in `source_name`.\n * - **Fail closed on reads.** A row that does not validate is not served.\n */\n\nimport { randomBytes } from \"node:crypto\";\nimport {\n closeSync,\n existsSync,\n fsyncSync,\n lstatSync,\n mkdirSync,\n openSync,\n readdirSync,\n readFileSync,\n renameSync,\n rmSync,\n statSync,\n writeFileSync,\n writeSync,\n type Dirent,\n} from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\n\nimport { WRITE_POLICY_READ_ONLY, withManifestLock } from \"@getbourdon/federation\";\nimport { parse as yamlParse, stringify as yamlStringify } from \"yaml\";\n\nimport {\n SKILL_BODY_NAME,\n SKILL_DESCRIPTION_MAX,\n type SkillContent,\n codePointLength,\n compareUtf8,\n computeContentSha256,\n isPathLinkOrReparse,\n parseFrontMatter,\n skillContentBody,\n skillNameError,\n} from \"./skill-index.js\";\n\ntype Dict = Record<string, unknown>;\n\nexport const SKILL_INDEX_SPEC_VERSION = \"0.1\";\nexport const SKILLS_DIRNAME = \"skills\";\nexport const INDEX_ROW_NAME = \"skill.yaml\";\nexport const FILES_DIRNAME = \"files\";\nexport const VERSIONS_DIRNAME = \".versions\";\nconst STAGING_PREFIX = \".staging-\";\nconst PROMOTION_LOCK_STEM = \".promotion\";\n\n/** The shared store behaves as org-tier memory: readable by every federation\n * reader, writable by no one through the ordinary write API. */\nexport const SKILL_STORE_WRITE_POLICY = WRITE_POLICY_READ_ONLY;\n\n/** Promotion widens nothing unless the promoting caller asks it to. */\nexport const DEFAULT_SKILL_VISIBILITY = \"private\";\n\nexport const MAX_INDEX_ROW_BYTES = 16 * 1024;\n\n// The skill index schema's rules (spec/skill_index_schema.json in the engine).\nconst ROW_FIELDS: ReadonlySet<string> = new Set([\n \"spec_version\",\n \"name\",\n \"source_name\",\n \"description\",\n \"version\",\n \"content_sha256\",\n \"source_agent\",\n \"promoted_by\",\n \"promoted_at\",\n \"proposal_id\",\n \"visibility\",\n \"valid_to\",\n \"supersedes\",\n]);\nconst REQUIRED_FIELDS = [\n \"spec_version\",\n \"name\",\n \"description\",\n \"version\",\n \"content_sha256\",\n \"source_agent\",\n \"promoted_by\",\n \"promoted_at\",\n \"visibility\",\n] as const;\nconst AGENT_ID_PATTERN = \"^[a-z0-9][a-z0-9_-]*$\";\nconst AGENT_ID_RE = new RegExp(AGENT_ID_PATTERN);\nconst AGENT_ID_MAX = 64;\nconst PROPOSAL_ID_MAX = 128;\nconst PROMOTED_AT_RE =\n /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(\\.\\d+)?(Z|([+-])(\\d{2}):(\\d{2}))$/;\nconst VISIBILITIES: ReadonlySet<string> = new Set([\"public\", \"team\", \"private\"]);\nconst DATE_RE = /^(\\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$/;\nconst SHA256_RE = /^[0-9a-f]{64}$/;\nconst NAME_LIMIT = 64;\n\n// -- errors -------------------------------------------------------------------\n\n/** Base class for every refusal the skill store raises. */\nexport class SkillIndexError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SkillIndexError\";\n }\n}\n\n/** An index row does not conform to the skill index schema. */\nexport class InvalidSkillRowError extends SkillIndexError {\n readonly errors: string[];\n\n constructor(errors: string[]) {\n super(`invalid skill index row: ${errors.join(\"; \")}`);\n this.name = \"InvalidSkillRowError\";\n this.errors = [...errors];\n }\n}\n\n/** The shared name is already taken and the caller did not ask to update it. */\nexport class SkillNameCollisionError extends SkillIndexError {\n readonly skillName: string;\n readonly existingVersion: number;\n readonly suggestedName: string | null;\n\n constructor(name: string, existingVersion: number, suggestedName: string | null) {\n const hint = suggestedName\n ? `; promote under another name (for example '${suggestedName}')`\n : \"; promote under another name\";\n super(\n `shared skill '${name}' already exists at version ${existingVersion}` +\n `${hint}, or pass expected_version=${existingVersion} to replace it`,\n );\n this.name = \"SkillNameCollisionError\";\n this.skillName = name;\n this.existingVersion = existingVersion;\n this.suggestedName = suggestedName;\n }\n}\n\n/** `expectedVersion` does not match what is in the store. */\nexport class SkillVersionConflictError extends SkillIndexError {\n readonly skillName: string;\n readonly expected: number | null;\n readonly current: number | null;\n\n constructor(name: string, expected: number | null, current: number | null) {\n super(\n `shared skill '${name}': expected version ${expected === null ? \"None\" : expected}, ` +\n `store has ${current !== null ? current : \"no such skill\"}`,\n );\n this.name = \"SkillVersionConflictError\";\n this.skillName = name;\n this.expected = expected;\n this.current = current;\n }\n}\n\n/** No shared skill (or no such version of it) exists. */\nexport class SkillNotFoundError extends SkillIndexError {\n constructor(message: string) {\n super(message);\n this.name = \"SkillNotFoundError\";\n }\n}\n\n// -- validation -----------------------------------------------------------------\n\n/** Return `name` if it is a valid shared skill name, else throw {@link SkillIndexError}. */\nexport function validateSkillName(name: unknown): string {\n const error = skillNameError(name);\n if (error !== null) throw new SkillIndexError(error);\n return name as string;\n}\n\nfunction isInt(value: unknown): value is number {\n return typeof value === \"number\" && Number.isInteger(value);\n}\n\nfunction isDict(value: unknown): value is Dict {\n return (\n value !== null && typeof value === \"object\" && !Array.isArray(value) && !(value instanceof Date)\n );\n}\n\nfunction daysInMonth(year: number, month: number): number {\n return new Date(Date.UTC(year, month, 0)).getUTCDate();\n}\n\nfunction validDate(value: unknown): boolean {\n if (typeof value !== \"string\") return false;\n const match = DATE_RE.exec(value);\n if (match === null) return false;\n const year = Number(match[1]);\n const month = Number(match[2]);\n return year >= 1 && Number(match[3]) <= daysInMonth(year, month);\n}\n\nfunction validTimestamp(value: unknown): boolean {\n if (typeof value !== \"string\") return false;\n const match = PROMOTED_AT_RE.exec(value);\n if (match === null) return false;\n const [, y, mo, d, h, mi, s] = match.map(Number) as number[];\n if (y! < 1 || mo! < 1 || mo! > 12 || d! < 1 || d! > daysInMonth(y!, mo!)) return false;\n if (h! > 23 || mi! > 59 || s! > 59) return false;\n if (match[8] !== \"Z\" && (Number(match[10]) > 23 || Number(match[11]) > 59)) return false;\n return true;\n}\n\n/**\n * Check a parsed `skill.yaml` mapping against the schema's rules. Returns every\n * violation found (empty means valid), in the oracle's order and wording.\n */\nexport function validateIndexRow(row: unknown): string[] {\n if (!isDict(row)) return [\"row must be a mapping\"];\n const errors: string[] = [];\n const keys = Object.keys(row);\n const has = (key: string): boolean => Object.hasOwn(row, key);\n\n const unknown = keys.filter((key) => !ROW_FIELDS.has(key)).sort(compareUtf8);\n if (unknown.length > 0) errors.push(`unknown fields: ${unknown.join(\", \")}`);\n const missing = REQUIRED_FIELDS.filter((key) => !has(key));\n if (missing.length > 0) errors.push(`missing required fields: ${missing.join(\", \")}`);\n\n if (has(\"spec_version\") && row.spec_version !== SKILL_INDEX_SPEC_VERSION) {\n errors.push(`spec_version must be '${SKILL_INDEX_SPEC_VERSION}'`);\n }\n if (has(\"name\")) {\n const err = skillNameError(row.name);\n if (err !== null) errors.push(err);\n }\n if (has(\"source_name\")) {\n const err = skillNameError(row.source_name, \"source_name\");\n if (err !== null) errors.push(err);\n }\n\n const description = row.description;\n if (\n has(\"description\") &&\n (typeof description !== \"string\" ||\n codePointLength(description) < 1 ||\n codePointLength(description) > SKILL_DESCRIPTION_MAX)\n ) {\n errors.push(`description must be a string of 1..${SKILL_DESCRIPTION_MAX} characters`);\n }\n\n const version = row.version;\n if (has(\"version\") && (!isInt(version) || version < 1)) {\n errors.push(\"version must be an integer >= 1\");\n }\n\n const digest = row.content_sha256;\n if (has(\"content_sha256\") && (typeof digest !== \"string\" || !SHA256_RE.test(digest))) {\n errors.push(\"content_sha256 must be 64 lowercase hex characters\");\n }\n\n for (const key of [\"source_agent\", \"promoted_by\"]) {\n const value = row[key];\n if (\n has(key) &&\n (typeof value !== \"string\" ||\n codePointLength(value) < 1 ||\n codePointLength(value) > AGENT_ID_MAX ||\n !AGENT_ID_RE.test(value))\n ) {\n errors.push(`${key} must be an agent id matching ${AGENT_ID_PATTERN}`);\n }\n }\n\n if (has(\"promoted_at\") && !validTimestamp(row.promoted_at)) {\n errors.push(\"promoted_at must be an ISO 8601 timestamp with a UTC offset\");\n }\n\n const proposalId = row.proposal_id;\n if (\n has(\"proposal_id\") &&\n (typeof proposalId !== \"string\" ||\n codePointLength(proposalId) < 1 ||\n codePointLength(proposalId) > PROPOSAL_ID_MAX)\n ) {\n errors.push(`proposal_id must be a string of 1..${PROPOSAL_ID_MAX} characters`);\n }\n\n if (has(\"visibility\") && !VISIBILITIES.has(row.visibility as string)) {\n errors.push(\"visibility must be one of private, public, team\");\n }\n\n if (has(\"valid_to\") && !validDate(row.valid_to)) {\n errors.push(\"valid_to must be an ISO 8601 date (YYYY-MM-DD)\");\n }\n\n const supersedes = row.supersedes;\n if (has(\"supersedes\")) {\n if (!isInt(supersedes) || supersedes < 1) {\n errors.push(\"supersedes must be an integer >= 1\");\n } else if (isInt(version) && supersedes !== version - 1) {\n errors.push(\"supersedes must equal version - 1\");\n }\n } else if (isInt(version) && version > 1) {\n errors.push(\"supersedes is required when version > 1\");\n }\n\n return errors;\n}\n\n// -- the index row --------------------------------------------------------------\n\n/** Today's date in UTC, `YYYY-MM-DD`. */\nfunction utcToday(): string {\n return new Date().toISOString().slice(0, 10);\n}\n\n/** One validated `skill.yaml`. */\nexport class SkillIndexRow {\n readonly specVersion: string;\n readonly name: string;\n readonly sourceName: string | null;\n readonly description: string;\n readonly version: number;\n readonly contentSha256: string;\n readonly sourceAgent: string;\n readonly promotedBy: string;\n readonly promotedAt: string;\n readonly proposalId: string | null;\n readonly visibility: string;\n readonly validTo: string | null;\n readonly supersedes: number | null;\n\n private constructor(data: Dict) {\n this.specVersion = data.spec_version as string;\n this.name = data.name as string;\n this.sourceName = (data.source_name as string | undefined) ?? null;\n this.description = data.description as string;\n this.version = data.version as number;\n this.contentSha256 = data.content_sha256 as string;\n this.sourceAgent = data.source_agent as string;\n this.promotedBy = data.promoted_by as string;\n this.promotedAt = data.promoted_at as string;\n this.proposalId = (data.proposal_id as string | undefined) ?? null;\n this.visibility = data.visibility as string;\n this.validTo = (data.valid_to as string | undefined) ?? null;\n this.supersedes = (data.supersedes as number | undefined) ?? null;\n }\n\n /** Validate `data` and build a row; throws {@link InvalidSkillRowError}. */\n static fromDict(data: unknown): SkillIndexRow {\n const errors = validateIndexRow(data);\n if (errors.length > 0) throw new InvalidSkillRowError(errors);\n return new SkillIndexRow(data as Dict);\n }\n\n /** Serialize in schema order, omitting absent optional fields. */\n toDict(): Dict {\n const out: Dict = { spec_version: this.specVersion, name: this.name };\n if (this.sourceName !== null) out.source_name = this.sourceName;\n out.description = this.description;\n out.version = this.version;\n out.content_sha256 = this.contentSha256;\n out.source_agent = this.sourceAgent;\n out.promoted_by = this.promotedBy;\n out.promoted_at = this.promotedAt;\n if (this.proposalId !== null) out.proposal_id = this.proposalId;\n out.visibility = this.visibility;\n if (this.validTo !== null) out.valid_to = this.validTo;\n if (this.supersedes !== null) out.supersedes = this.supersedes;\n return out;\n }\n\n /** False once `valid_to` is on or before `today` (UTC today by default, `YYYY-MM-DD`). */\n isActive(today?: string): boolean {\n if (this.validTo === null) return true;\n return this.validTo > (today ?? utcToday());\n }\n}\n\n/** Python's `yaml.safe_load` reads YAML 1.1 (so an unquoted timestamp is not a string). */\nfunction parseYaml11(text: string): unknown {\n return yamlParse(text, { version: \"1.1\", uniqueKeys: false, logLevel: \"silent\" });\n}\n\nconst UTF8 = new TextDecoder(\"utf-8\", { fatal: true, ignoreBOM: true });\n\n/** Read and validate one `skill.yaml`. */\nexport function loadIndexRow(path: string): SkillIndexRow {\n if (isPathLinkOrReparse(path)) {\n throw new InvalidSkillRowError([`${INDEX_ROW_NAME} must not be a link`]);\n }\n const raw = readFileSync(path);\n if (raw.length > MAX_INDEX_ROW_BYTES) {\n throw new InvalidSkillRowError([`${INDEX_ROW_NAME} exceeds ${MAX_INDEX_ROW_BYTES} bytes`]);\n }\n let data: unknown;\n try {\n data = parseYaml11(UTF8.decode(raw));\n } catch {\n throw new InvalidSkillRowError([`${INDEX_ROW_NAME} is not readable YAML`]);\n }\n return SkillIndexRow.fromDict(data);\n}\n\nfunction atomicWriteBytes(path: string, data: Uint8Array): void {\n const temp = join(dirname(path), `.${basename(path)}.${randomBytes(6).toString(\"hex\")}.tmp`);\n try {\n const fd = openSync(temp, \"wx\");\n try {\n writeSync(fd, data);\n fsyncSync(fd);\n } finally {\n closeSync(fd);\n }\n renameSync(temp, path);\n } finally {\n if (existsSync(temp)) rmSync(temp, { force: true });\n }\n}\n\nfunction renderRow(row: SkillIndexRow): Uint8Array {\n const errors = validateIndexRow(row.toDict());\n if (errors.length > 0) throw new InvalidSkillRowError(errors);\n // YAML 1.1 quoting, so a timestamp or a date stays a string for any reader.\n const text = yamlStringify(row.toDict(), {\n version: \"1.1\",\n sortMapEntries: false,\n singleQuote: true,\n });\n return Buffer.from(text, \"utf8\");\n}\n\n/** Validate `row` and write it atomically to `path`. */\nexport function writeIndexRow(path: string, row: SkillIndexRow): void {\n atomicWriteBytes(path, renderRow(row));\n}\n\n// -- library layout ---------------------------------------------------------------\n\n/** `<library>/skills` -- the shared skill store. */\nexport function skillsRoot(libraryPath: string): string {\n return join(libraryPath, SKILLS_DIRNAME);\n}\n\n/** The folder of one shared skill; `name` is validated first. */\nexport function skillDir(libraryPath: string, name: string): string {\n return join(skillsRoot(libraryPath), validateSkillName(name));\n}\n\nfunction versionDir(libraryPath: string, name: string, version: number): string {\n return join(skillDir(libraryPath, name), VERSIONS_DIRNAME, String(version));\n}\n\n/** `path` is a regular file, following links (Python `Path.is_file()`). */\nfunction isFile(path: string): boolean {\n try {\n return statSync(path).isFile();\n } catch {\n return false;\n }\n}\n\nfunction isDirectory(path: string): boolean {\n try {\n return statSync(path).isDirectory();\n } catch {\n return false;\n }\n}\n\n/**\n * The index row for `name` (the live one, or an archived `version`). Throws\n * {@link SkillNotFoundError} when absent and {@link InvalidSkillRowError} when\n * present but invalid.\n */\nexport function getSkillRow(\n libraryPath: string,\n name: string,\n version: number | null = null,\n): SkillIndexRow {\n const live = join(skillDir(libraryPath, name), INDEX_ROW_NAME);\n if (!isFile(live)) throw new SkillNotFoundError(`no shared skill named '${name}'`);\n const row = loadIndexRow(live);\n if (row.name !== name) {\n throw new InvalidSkillRowError([`row name '${row.name}' does not match its folder '${name}'`]);\n }\n if (version === null || version === row.version) return row;\n if (!isInt(version) || version < 1 || version >= row.version) {\n throw new SkillNotFoundError(`shared skill '${name}' has no version ${version}`);\n }\n const archivedPath = join(versionDir(libraryPath, name, version), INDEX_ROW_NAME);\n if (!isFile(archivedPath)) {\n throw new SkillNotFoundError(`shared skill '${name}' has no version ${version}`);\n }\n const archived = loadIndexRow(archivedPath);\n if (archived.name !== name || archived.version !== version) {\n throw new InvalidSkillRowError([`archived row for '${name}' v${version} is inconsistent`]);\n }\n return archived;\n}\n\nfunction sortedEntries(directory: string): Dirent[] {\n return readdirSync(directory, { withFileTypes: true }).sort((a, b) =>\n compareUtf8(a.name, b.name),\n );\n}\n\n/**\n * Every valid live index row, sorted by name. Retired rows are omitted unless\n * `includeRetired`. Rows that fail validation are skipped (and logged) rather\n * than served.\n */\nexport function listSkillRows(\n libraryPath: string,\n options: { includeRetired?: boolean; today?: string } = {},\n): SkillIndexRow[] {\n const root = skillsRoot(libraryPath);\n if (!isDirectory(root)) return [];\n const rows: SkillIndexRow[] = [];\n for (const child of sortedEntries(root)) {\n if (child.name.startsWith(\".\") || skillNameError(child.name) !== null) continue;\n const path = join(root, child.name);\n if (isPathLinkOrReparse(path) || !isDirectory(path)) continue;\n let row: SkillIndexRow;\n try {\n row = getSkillRow(libraryPath, child.name);\n } catch (err) {\n if (err instanceof SkillNotFoundError) continue;\n if (err instanceof InvalidSkillRowError || isOsError(err)) {\n console.warn(`[bourdon.skill_index] skipping ${child.name} (${String(err)})`);\n continue;\n }\n throw err;\n }\n if (options.includeRetired || row.isActive(options.today)) rows.push(row);\n }\n return rows;\n}\n\n/** Every version number on disk for `name`, oldest first. */\nexport function listSkillVersions(libraryPath: string, name: string): number[] {\n const live = getSkillRow(libraryPath, name);\n const archive = join(skillDir(libraryPath, name), VERSIONS_DIRNAME);\n const versions = new Set([live.version]);\n if (isDirectory(archive)) {\n for (const child of readdirSync(archive)) {\n if (/^[0-9]+$/.test(child) && isFile(join(archive, child, INDEX_ROW_NAME))) {\n versions.add(Number(child));\n }\n }\n }\n return [...versions].sort((a, b) => a - b);\n}\n\n/** A Node filesystem error (Python's `OSError`). */\nexport function isOsError(err: unknown): boolean {\n return err instanceof Error && typeof (err as NodeJS.ErrnoException).code === \"string\";\n}\n\nfunction readStoredFiles(folder: string): Array<readonly [string, Uint8Array]> {\n const entries: Array<readonly [string, Uint8Array]> = [\n [SKILL_BODY_NAME, readFileSync(join(folder, SKILL_BODY_NAME))],\n ];\n const filesRoot = join(folder, FILES_DIRNAME);\n if (!isDirectory(filesRoot)) return entries;\n // os.walk(followlinks=False): a directory's files first, then its sorted\n // subdirectories; a link to a directory is listed but never entered, a link\n // to anything else is refused.\n const walk = (directory: string, parts: string[]): void => {\n const subdirs: string[] = [];\n for (const entry of sortedEntries(directory)) {\n const path = join(directory, entry.name);\n if (entry.isDirectory() || (entry.isSymbolicLink() && isDirectory(path))) {\n if (!entry.isSymbolicLink()) subdirs.push(entry.name);\n continue;\n }\n if (entry.isSymbolicLink() || isPathLinkOrReparse(path)) {\n throw new InvalidSkillRowError([`stored file '${entry.name}' is a link`]);\n }\n entries.push([[...parts, entry.name].join(\"/\"), readFileSync(path)]);\n }\n for (const name of subdirs) walk(join(directory, name), [...parts, name]);\n };\n walk(filesRoot, []);\n return entries;\n}\n\n/** The row and the stored files of one shared skill version. */\nexport function readSharedSkill(\n libraryPath: string,\n name: string,\n version: number | null = null,\n): { row: SkillIndexRow; content: SkillContent } {\n const row = getSkillRow(libraryPath, name, version);\n const live = getSkillRow(libraryPath, name);\n const folder =\n row.version === live.version\n ? skillDir(libraryPath, name)\n : versionDir(libraryPath, name, row.version);\n const files = readStoredFiles(folder);\n const body = files.find(([rel]) => rel === SKILL_BODY_NAME)![1];\n const content: SkillContent = {\n frontMatter: parseFrontMatter(body),\n files: [...files].sort(([a], [b]) => compareUtf8(a, b)),\n };\n return { row, content };\n}\n\n/** Whether the stored files still hash to the row's `content_sha256`. */\nexport function verifySharedSkill(\n libraryPath: string,\n name: string,\n version: number | null = null,\n): boolean {\n const { row, content } = readSharedSkill(libraryPath, name, version);\n return computeContentSha256(content.files) === row.contentSha256;\n}\n\n// -- naming -----------------------------------------------------------------------\n\n/** Python `str.rstrip(\"-\")`. */\nfunction rstripDash(text: string): string {\n return text.replace(/-+$/, \"\");\n}\n\n/**\n * A free shared name derived from `name` (`name-2`, `name-3`...). Returns null\n * only if no candidate within the length limit is free.\n */\nexport function suggestAvailableName(libraryPath: string, name: string): string | null {\n validateSkillName(name);\n for (let n = 2; n < 1000; n++) {\n const suffix = `-${n}`;\n const base = rstripDash(name.slice(0, NAME_LIMIT - suffix.length)) || name.slice(0, 1);\n const candidate = base + suffix;\n if (!existsSync(join(skillsRoot(libraryPath), candidate))) return candidate;\n }\n return null;\n}\n\n// -- promotion --------------------------------------------------------------------\n\nexport interface PromotionResult {\n row: SkillIndexRow;\n /** False when the content already matched the live version (nothing written). */\n changed: boolean;\n}\n\nexport interface PromoteSkillOptions {\n sourceAgent: string;\n promotedBy: string;\n /** Shared name; defaults to the front-matter name. Another name renames at promotion. */\n name?: string | null;\n /** The live version when replacing a skill; null/absent for a new one. */\n expectedVersion?: number | null;\n visibility?: string;\n proposalId?: string | null;\n /** ISO 8601 with a UTC offset; defaults to now, to the second. */\n promotedAt?: string | null;\n}\n\n/** `datetime.now(timezone.utc).isoformat(timespec=\"seconds\")`. */\nfunction nowIso(): string {\n return `${new Date().toISOString().slice(0, 19)}+00:00`;\n}\n\nfunction writeTree(folder: string, content: SkillContent, row: SkillIndexRow): void {\n mkdirSync(folder);\n writeFileSync(join(folder, SKILL_BODY_NAME), skillContentBody(content));\n for (const [rel, data] of content.files) {\n if (rel === SKILL_BODY_NAME) continue;\n const target = join(folder, FILES_DIRNAME, ...rel.split(\"/\"));\n mkdirSync(dirname(target), { recursive: true });\n writeFileSync(target, data);\n }\n writeFileSync(join(folder, INDEX_ROW_NAME), renderRow(row));\n}\n\nfunction pathExists(path: string): boolean {\n try {\n lstatSync(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Write `content` into the shared store as a new skill or a new version.\n *\n * This is the store's only write path and performs no authorization: the\n * caller (the promotion gate) must already have established that a trusted\n * caller approved it. `content` must come from `readSkillFolder`.\n *\n * - `name` defaults to the front-matter name. Another name renames at\n * promotion; the front-matter name is then kept as `source_name`.\n * - If the name is free, `expectedVersion` must be null.\n * - If the name is taken, `expectedVersion` must equal the live version; null\n * throws {@link SkillNameCollisionError} (with a free name to suggest) and\n * any other value throws {@link SkillVersionConflictError}.\n * - Content identical to the live version is a no-op (`changed: false`).\n *\n * The previous version moves to `.versions/<n>/`. `skill.yaml` is moved out\n * first and written last, so a reader never sees a row next to the wrong body;\n * an interrupted promotion leaves the skill unlisted, with the old version\n * intact under `.versions/`.\n */\nexport function promoteSkill(\n libraryPath: string,\n content: SkillContent,\n options: PromoteSkillOptions,\n): PromotionResult {\n const frontName = content.frontMatter.name;\n const target = validateSkillName(options.name ?? frontName);\n const digest = computeContentSha256(content.files);\n const rowFields: Dict = {\n spec_version: SKILL_INDEX_SPEC_VERSION,\n name: target,\n description: content.frontMatter.description,\n content_sha256: digest,\n source_agent: options.sourceAgent,\n promoted_by: options.promotedBy,\n promoted_at: options.promotedAt || nowIso(),\n visibility: options.visibility ?? DEFAULT_SKILL_VISIBILITY,\n };\n if (target !== frontName) rowFields.source_name = frontName;\n if (options.proposalId !== undefined && options.proposalId !== null) {\n rowFields.proposal_id = options.proposalId;\n }\n const expected = options.expectedVersion ?? null;\n if (expected !== null && (!isInt(expected) || expected < 1)) {\n throw new SkillIndexError(\"expected_version must be an integer >= 1 or None\");\n }\n\n const root = skillsRoot(libraryPath);\n mkdirSync(root, { recursive: true });\n if (isPathLinkOrReparse(root)) throw new SkillIndexError(`${SKILLS_DIRNAME}/ must not be a link`);\n\n return withManifestLock(join(root, PROMOTION_LOCK_STEM), () => {\n const folder = join(root, target);\n let current: SkillIndexRow | null = null;\n if (pathExists(folder)) {\n if (isPathLinkOrReparse(folder) || !isDirectory(folder)) {\n throw new SkillIndexError(`shared skill folder '${target}' is not a real directory`);\n }\n try {\n current = getSkillRow(libraryPath, target);\n } catch (err) {\n if (!(err instanceof SkillNotFoundError)) throw err;\n throw new SkillIndexError(\n `shared skill folder '${target}' has no ${INDEX_ROW_NAME}; ` +\n \"restore it from .versions/ before promoting again\",\n );\n }\n }\n\n if (current === null) {\n if (expected !== null) throw new SkillVersionConflictError(target, expected, null);\n rowFields.version = 1;\n } else {\n if (expected === null) {\n throw new SkillNameCollisionError(\n target,\n current.version,\n suggestAvailableName(libraryPath, target),\n );\n }\n if (expected !== current.version) {\n throw new SkillVersionConflictError(target, expected, current.version);\n }\n if (current.contentSha256 === digest) return { row: current, changed: false };\n rowFields.version = current.version + 1;\n rowFields.supersedes = current.version;\n }\n\n const row = SkillIndexRow.fromDict(rowFields);\n mkdirSync(folder, { recursive: true });\n const staging = join(folder, `${STAGING_PREFIX}${randomBytes(6).toString(\"hex\")}`);\n try {\n writeTree(staging, content, row);\n if (current !== null) {\n const archive = versionDir(libraryPath, target, current.version);\n if (pathExists(archive)) {\n throw new SkillIndexError(`archive for '${target}' v${current.version} already exists`);\n }\n mkdirSync(archive, { recursive: true });\n renameSync(join(folder, INDEX_ROW_NAME), join(archive, INDEX_ROW_NAME));\n renameSync(join(folder, SKILL_BODY_NAME), join(archive, SKILL_BODY_NAME));\n if (pathExists(join(folder, FILES_DIRNAME))) {\n renameSync(join(folder, FILES_DIRNAME), join(archive, FILES_DIRNAME));\n }\n }\n renameSync(join(staging, SKILL_BODY_NAME), join(folder, SKILL_BODY_NAME));\n if (pathExists(join(staging, FILES_DIRNAME))) {\n renameSync(join(staging, FILES_DIRNAME), join(folder, FILES_DIRNAME));\n }\n renameSync(join(staging, INDEX_ROW_NAME), join(folder, INDEX_ROW_NAME));\n } finally {\n if (pathExists(staging)) rmSync(staging, { recursive: true, force: true });\n if (current === null && !pathExists(join(folder, INDEX_ROW_NAME))) {\n rmSync(folder, { recursive: true, force: true });\n }\n }\n return { row, changed: true };\n });\n}\n\n// -- retirement -----------------------------------------------------------------\n\n/** The live `skill.yaml` of `name`. */\nfunction liveRowPath(libraryPath: string, name: string): string {\n return join(skillDir(libraryPath, name), INDEX_ROW_NAME);\n}\n\n/**\n * Set (retire) or clear (restore) the live row's `valid_to`.\n *\n * Retirement is a row edit, not a new version: the body and its hash are\n * untouched, so every version stays fetchable by number. Like\n * {@link promoteSkill} this performs no authorization; the caller is the gate.\n * `expectedVersion` must equal the live version (compare-and-swap, under the\n * same lock promotion writes under).\n */\nexport function setSkillValidTo(\n libraryPath: string,\n name: string,\n validTo: string | null,\n options: { expectedVersion: number },\n): SkillIndexRow {\n if (validTo !== null && !validDate(validTo)) {\n throw new SkillIndexError(\"valid_to must be an ISO 8601 date (YYYY-MM-DD)\");\n }\n const expected = options.expectedVersion;\n if (!isInt(expected) || expected < 1) {\n throw new SkillIndexError(\"expected_version must be an integer >= 1\");\n }\n const root = skillsRoot(libraryPath);\n if (!isDirectory(root) || isPathLinkOrReparse(root)) {\n throw new SkillNotFoundError(`no shared skill named '${name}'`);\n }\n return withManifestLock(join(root, PROMOTION_LOCK_STEM), () => {\n const current = getSkillRow(libraryPath, name);\n if (current.version !== expected) {\n throw new SkillVersionConflictError(name, expected, current.version);\n }\n const fields = current.toDict();\n delete fields.valid_to;\n if (validTo !== null) fields.valid_to = validTo;\n const row = SkillIndexRow.fromDict(fields);\n writeIndexRow(liveRowPath(libraryPath, name), row);\n return row;\n });\n}\n\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Skill proposals: the approval gate in front of the shared skill library.\n * Port of the engine's `core/skill_proposals.py` (plan 005, phase 4).\n *\n * An agent *proposes* one of the skills it advertises; a person *approves* it;\n * only then does {@link promoteSkill} write it into `<library>/skills`.\n *\n * Layout (interoperable with the engine: either side reads what the other wrote):\n *\n * <library>/.skill-proposals/<proposal_id>/\n * proposal.yaml the record: what was proposed, by whom, and the decision\n * content/ a snapshot of the skill folder, taken at proposal time\n *\n * Load-bearing rules:\n *\n * - **The snapshot is what gets approved.** Proposing copies the skill's files\n * into `content/` and records their `content_sha256`. Approval re-reads that\n * snapshot, re-checks every text-only rule and refuses unless it still hashes\n * to the recorded value, so editing the agent's folder after proposing cannot\n * change what lands in the library.\n * - **One human-confirmed approval promotes.** Nothing in this module is\n * reachable over MCP except {@link createProposal}. Approval, rejection,\n * retirement and rollback are called by the operator's terminal command,\n * which asks the person at the keyboard to confirm. Consensus votes on a\n * proposal's ballot are advisory: they are shown to the approver and recorded\n * beside the decision, and never promote anything on their own.\n * - **Every decision is audited before it happens, fail-closed**, in the same\n * federation audit log the quarantine staging decisions use.\n *\n * Nothing here performs caller authorization; the callers (the MCP tool for\n * proposing, the CLI for deciding) are the gates.\n */\n\nimport { randomBytes } from \"node:crypto\";\nimport {\n closeSync,\n existsSync,\n fsyncSync,\n mkdirSync,\n openSync,\n readdirSync,\n readFileSync,\n renameSync,\n rmSync,\n statSync,\n writeFileSync,\n writeSync,\n} from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\nimport {\n ConsensusEngine,\n DECISION_ALLOW,\n DECISION_DENY,\n type FederationAudit,\n withManifestLock,\n} from \"@getbourdon/federation\";\nimport { parse as yamlParse, stringify as yamlStringify } from \"yaml\";\n\nimport {\n type SkillContent,\n computeContentSha256,\n isPathLinkOrReparse,\n readSkillFolder,\n} from \"./skill-index.js\";\nimport {\n type SkillIndexRow,\n SkillIndexError,\n SkillNotFoundError,\n getSkillRow,\n promoteSkill,\n readSharedSkill,\n setSkillValidTo,\n suggestAvailableName,\n validateSkillName,\n} from \"./skill-store.js\";\n\ntype Dict = Record<string, unknown>;\n\nexport const PROPOSALS_DIRNAME = \".skill-proposals\";\nexport const RECORD_NAME = \"proposal.yaml\";\nexport const CONTENT_DIRNAME = \"content\";\nconst CREATE_LOCK_STEM = \".create\";\nconst TMP_PREFIX = \".tmp-\";\n\nexport const STATUS_PENDING = \"pending\";\nexport const STATUS_APPROVED = \"approved\";\nexport const STATUS_REJECTED = \"rejected\";\nconst STATUSES: ReadonlySet<string> = new Set([STATUS_PENDING, STATUS_APPROVED, STATUS_REJECTED]);\n\nexport const PROPOSER_TRUSTED = \"trusted\";\nexport const PROPOSER_QUARANTINED = \"quarantined\";\n\n/** The advisory ballot's options. A ballot only informs the person deciding. */\nexport const BALLOT_OPTIONS = [\"approve\", \"reject\"] as const;\n\n/** Tunable limits. `maxPendingPerProposer`: pending proposals one proposer may\n * hold at once, so a caller cannot fill the library with snapshots nobody\n * asked for. */\nexport const SKILL_PROPOSAL_LIMITS = {\n maxPendingPerProposer: 50,\n maxReasonChars: 500,\n};\n\nconst ID_RE = /^sp-[0-9a-f]{12}$/;\n\n// -- errors -------------------------------------------------------------------\n\n/** Base class for refusals raised by the proposal gate. */\nexport class SkillProposalError extends SkillIndexError {\n constructor(message: string) {\n super(message);\n this.name = \"SkillProposalError\";\n }\n}\n\n/** No proposal with that id. */\nexport class ProposalNotFoundError extends SkillProposalError {\n constructor(message: string) {\n super(message);\n this.name = \"ProposalNotFoundError\";\n }\n}\n\n/** The proposal is not pending (it was already decided). */\nexport class ProposalStateError extends SkillProposalError {\n constructor(message: string) {\n super(message);\n this.name = \"ProposalStateError\";\n }\n}\n\n/** The snapshot no longer hashes to what was proposed, or to what the approver saw. */\nexport class ProposalDigestMismatchError extends SkillProposalError {\n constructor(message: string) {\n super(message);\n this.name = \"ProposalDigestMismatchError\";\n }\n}\n\n/** `datetime.now(timezone.utc).isoformat(timespec=\"seconds\")`. */\nfunction nowIso(): string {\n return `${new Date().toISOString().slice(0, 19)}+00:00`;\n}\n\nfunction today(): string {\n return new Date().toISOString().slice(0, 10);\n}\n\nfunction isDict(value: unknown): value is Dict {\n return (\n value !== null && typeof value === \"object\" && !Array.isArray(value) && !(value instanceof Date)\n );\n}\n\n/** Python `str()` of a scalar read from YAML. */\nfunction pyStr(value: unknown): string {\n if (value === null || value === undefined) return \"None\";\n if (value === true) return \"True\";\n if (value === false) return \"False\";\n return String(value);\n}\n\n/** Python truthiness of a YAML value. */\nfunction truthy(value: unknown): boolean {\n if (Array.isArray(value)) return value.length > 0;\n if (isDict(value)) return Object.keys(value).length > 0;\n return Boolean(value);\n}\n\n// -- the record ---------------------------------------------------------------\n\n/** One proposal record (`proposal.yaml`). Field names follow the on-disk keys. */\nexport interface SkillProposal {\n proposal_id: string;\n name: string;\n description: string;\n content_sha256: string;\n source_agent: string;\n proposed_by: string;\n proposer_tier: string;\n created_at: string;\n path_hint: string;\n scope: string;\n visibility: string;\n project: string | null;\n origin: Dict | null;\n files: Dict[];\n ballot: boolean;\n status: string;\n decision: Dict | null;\n}\n\n/** The record as written: the engine's key order, absent optionals omitted. */\nexport function proposalToDict(proposal: SkillProposal): Dict {\n const out: Dict = {\n proposal_id: proposal.proposal_id,\n status: proposal.status,\n name: proposal.name,\n description: proposal.description,\n content_sha256: proposal.content_sha256,\n source_agent: proposal.source_agent,\n path_hint: proposal.path_hint,\n scope: proposal.scope,\n };\n if (proposal.project !== null) out.project = proposal.project;\n if (proposal.origin !== null) out.origin = { ...proposal.origin };\n out.visibility = proposal.visibility;\n out.proposed_by = proposal.proposed_by;\n out.proposer_tier = proposal.proposer_tier;\n out.created_at = proposal.created_at;\n out.files = proposal.files.map((item) => ({ ...item }));\n out.ballot = proposal.ballot;\n if (proposal.decision !== null) out.decision = { ...proposal.decision };\n return out;\n}\n\n/** Parse a record; throws {@link SkillProposalError} on anything malformed. */\nexport function proposalFromDict(data: unknown): SkillProposal {\n if (!isDict(data)) throw new SkillProposalError(\"proposal record is not a mapping\");\n const required = [\n \"proposal_id\",\n \"name\",\n \"description\",\n \"content_sha256\",\n \"source_agent\",\n \"proposed_by\",\n \"proposer_tier\",\n \"created_at\",\n \"path_hint\",\n \"scope\",\n ];\n // Python evaluates the constructor's keyword arguments in order, so the\n // first missing key (or the invalid name) is the one reported.\n for (const key of required) {\n if (!Object.hasOwn(data, key)) {\n throw new SkillProposalError(`proposal record is missing '${key}'`);\n }\n if (key === \"name\") validateSkillName(data.name);\n }\n const proposal: SkillProposal = {\n proposal_id: pyStr(data.proposal_id),\n name: data.name as string,\n description: pyStr(data.description),\n content_sha256: pyStr(data.content_sha256),\n source_agent: pyStr(data.source_agent),\n proposed_by: pyStr(data.proposed_by),\n proposer_tier: pyStr(data.proposer_tier),\n created_at: pyStr(data.created_at),\n path_hint: pyStr(data.path_hint),\n scope: pyStr(data.scope),\n visibility: truthy(data.visibility) ? pyStr(data.visibility) : \"team\",\n project: (data.project as string | null | undefined) ?? null,\n origin: isDict(data.origin) ? { ...data.origin } : null,\n files: Array.isArray(data.files) ? data.files.filter(isDict).map((item) => ({ ...item })) : [],\n ballot: truthy(data.ballot ?? false),\n status: truthy(data.status) ? pyStr(data.status) : STATUS_PENDING,\n decision: isDict(data.decision) ? { ...data.decision } : null,\n };\n if (!isProposalId(proposal.proposal_id) || !STATUSES.has(proposal.status)) {\n throw new SkillProposalError(\"proposal record is malformed\");\n }\n return proposal;\n}\n\n/** The row a listing shows: no file list, no decision detail. */\nexport function proposalSummary(proposal: SkillProposal): Dict {\n const out: Dict = {\n proposal_id: proposal.proposal_id,\n status: proposal.status,\n name: proposal.name,\n description: proposal.description,\n content_sha256: proposal.content_sha256,\n source_agent: proposal.source_agent,\n proposed_by: proposal.proposed_by,\n proposer_tier: proposal.proposer_tier,\n created_at: proposal.created_at,\n file_count: Math.max(0, proposal.files.length - 1),\n };\n if (proposal.origin !== null) out.origin = { ...proposal.origin };\n return out;\n}\n\nexport function isProposalId(value: unknown): value is string {\n return typeof value === \"string\" && ID_RE.test(value);\n}\n\n/** `<library>/.skill-proposals`. */\nexport function proposalsRoot(libraryPath: string): string {\n return join(libraryPath, PROPOSALS_DIRNAME);\n}\n\nfunction proposalDir(libraryPath: string, proposalId: string): string {\n if (!isProposalId(proposalId)) {\n throw new ProposalNotFoundError(`not a proposal id: '${String(proposalId)}'`);\n }\n return join(proposalsRoot(libraryPath), proposalId);\n}\n\n/** An existing proposal's folder; the lock beside its record never creates one. */\nfunction existingProposalDir(libraryPath: string, proposalId: string): string {\n const folder = proposalDir(libraryPath, proposalId);\n if (!isDirectory(folder) || isPathLinkOrReparse(folder)) {\n throw new ProposalNotFoundError(`no skill proposal '${proposalId}'`);\n }\n return folder;\n}\n\nfunction isFile(path: string): boolean {\n try {\n return statSync(path).isFile();\n } catch {\n return false;\n }\n}\n\nfunction isDirectory(path: string): boolean {\n try {\n return statSync(path).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction writeRecord(folder: string, proposal: SkillProposal): void {\n // YAML 1.1 quoting, so a timestamp stays a string for the engine's reader.\n const text = yamlStringify(proposalToDict(proposal), {\n version: \"1.1\",\n sortMapEntries: false,\n singleQuote: true,\n lineWidth: 0,\n });\n const target = join(folder, RECORD_NAME);\n const temp = join(folder, `.${RECORD_NAME}.${randomBytes(6).toString(\"hex\")}.tmp`);\n try {\n const fd = openSync(temp, \"wx\");\n try {\n writeSync(fd, Buffer.from(text, \"utf8\"));\n fsyncSync(fd);\n } finally {\n closeSync(fd);\n }\n renameSync(temp, target);\n } finally {\n if (existsSync(temp)) rmSync(temp, { force: true });\n }\n}\n\nconst UTF8 = new TextDecoder(\"utf-8\", { fatal: true, ignoreBOM: true });\n\n/** Read one proposal; throws {@link ProposalNotFoundError} or {@link SkillProposalError}. */\nexport function loadProposal(libraryPath: string, proposalId: string): SkillProposal {\n const folder = proposalDir(libraryPath, proposalId);\n const record = join(folder, RECORD_NAME);\n // A record that is a file implies its folder exists (the link checks lstat).\n if (!isFile(record) || isPathLinkOrReparse(folder) || isPathLinkOrReparse(record)) {\n throw new ProposalNotFoundError(`no skill proposal '${proposalId}'`);\n }\n let data: unknown;\n try {\n data = yamlParse(UTF8.decode(readFileSync(record)), {\n version: \"1.1\",\n uniqueKeys: false,\n logLevel: \"silent\",\n });\n } catch {\n throw new SkillProposalError(`proposal '${proposalId}' cannot be read`);\n }\n const proposal = proposalFromDict(data);\n if (proposal.proposal_id !== proposalId) {\n throw new SkillProposalError(`proposal '${proposalId}' does not match its folder`);\n }\n return proposal;\n}\n\n/** Every readable proposal (optionally of one `status`), oldest first. */\nexport function listProposals(libraryPath: string, status: string | null = null): SkillProposal[] {\n const root = proposalsRoot(libraryPath);\n if (!isDirectory(root) || isPathLinkOrReparse(root)) return [];\n const found: SkillProposal[] = [];\n for (const child of readdirSync(root)) {\n if (!isProposalId(child)) continue;\n let proposal: SkillProposal;\n try {\n proposal = loadProposal(libraryPath, child);\n } catch (err) {\n if (err instanceof SkillIndexError) continue;\n throw err;\n }\n if (status === null || proposal.status === status) found.push(proposal);\n }\n return found.sort((a, b) =>\n a.created_at !== b.created_at\n ? a.created_at < b.created_at\n ? -1\n : 1\n : a.proposal_id < b.proposal_id\n ? -1\n : a.proposal_id > b.proposal_id\n ? 1\n : 0,\n );\n}\n\n// -- proposing ----------------------------------------------------------------\n\nfunction writeSnapshot(folder: string, content: SkillContent): void {\n const targetRoot = join(folder, CONTENT_DIRNAME);\n mkdirSync(targetRoot);\n for (const [rel, data] of content.files) {\n const target = join(targetRoot, ...rel.split(\"/\"));\n mkdirSync(dirname(target), { recursive: true });\n writeFileSync(target, data);\n }\n}\n\nexport interface CreateProposalOptions {\n /** The advertised SkillRef, as it sits in the agent's manifest. */\n ref: Readonly<Dict>;\n sourceAgent: string;\n proposedBy: string;\n proposerTier: string;\n createdAt?: string | null;\n}\n\n/**\n * Snapshot `content` into a new pending proposal.\n *\n * `content` must come from `readSkillFolder` over the folder the agent's own\n * reader resolved for `ref` (the advertised SkillRef). Returns\n * `{ proposal, created }`: proposing the same bytes of the same skill again\n * while a proposal is pending returns that proposal unchanged.\n */\nexport function createProposal(\n libraryPath: string,\n content: SkillContent,\n options: CreateProposalOptions,\n): { proposal: SkillProposal; created: boolean } {\n const { ref, sourceAgent, proposedBy, proposerTier } = options;\n if (proposerTier !== PROPOSER_TRUSTED && proposerTier !== PROPOSER_QUARANTINED) {\n throw new SkillProposalError(`unknown proposer tier '${proposerTier}'`);\n }\n const name = validateSkillName(content.frontMatter.name);\n const digest = computeContentSha256(content.files);\n const root = proposalsRoot(libraryPath);\n mkdirSync(root, { recursive: true });\n if (isPathLinkOrReparse(root)) {\n throw new SkillProposalError(`${PROPOSALS_DIRNAME}/ must not be a link`);\n }\n\n return withManifestLock(join(root, CREATE_LOCK_STEM), () => {\n const pending = listProposals(libraryPath, STATUS_PENDING);\n for (const existing of pending) {\n if (\n existing.source_agent === sourceAgent &&\n existing.name === name &&\n existing.content_sha256 === digest\n ) {\n return { proposal: existing, created: false };\n }\n }\n const mine = pending.filter((p) => p.proposed_by === proposedBy).length;\n const limit = SKILL_PROPOSAL_LIMITS.maxPendingPerProposer;\n if (mine >= limit) {\n throw new SkillProposalError(\n `'${proposedBy}' already has ${mine} pending skill proposals ` +\n `(limit ${limit}); wait for some to be decided`,\n );\n }\n\n let proposalId = `sp-${randomBytes(6).toString(\"hex\")}`;\n while (existsSync(join(root, proposalId))) {\n proposalId = `sp-${randomBytes(6).toString(\"hex\")}`;\n }\n const visibility = ref.visibility;\n const origin = ref.origin;\n const proposal: SkillProposal = {\n proposal_id: proposalId,\n name,\n description: content.frontMatter.description,\n content_sha256: digest,\n source_agent: sourceAgent,\n proposed_by: proposedBy,\n proposer_tier: proposerTier,\n created_at: options.createdAt || nowIso(),\n path_hint: truthy(ref.path_hint) ? String(ref.path_hint) : \"\",\n scope: truthy(ref.scope) ? String(ref.scope) : \"\",\n visibility:\n visibility === \"public\" || visibility === \"team\" || visibility === \"private\"\n ? visibility\n : \"team\",\n project: typeof ref.project === \"string\" ? ref.project : null,\n origin: isDict(origin) ? { ...origin } : null,\n files: content.files.map(([rel, data]) => ({ file: rel, bytes: data.length })),\n ballot: false,\n status: STATUS_PENDING,\n decision: null,\n };\n const staging = join(root, `${TMP_PREFIX}${randomBytes(6).toString(\"hex\")}`);\n try {\n mkdirSync(staging);\n writeSnapshot(staging, content);\n writeRecord(staging, proposal);\n renameSync(staging, join(root, proposalId));\n } finally {\n if (existsSync(staging)) rmSync(staging, { recursive: true, force: true });\n }\n return { proposal, created: true };\n });\n}\n\n/** The snapshot, re-checked against every content rule and its recorded hash. */\nexport function readProposalContent(libraryPath: string, proposal: SkillProposal): SkillContent {\n const folder = join(proposalDir(libraryPath, proposal.proposal_id), CONTENT_DIRNAME);\n const content = readSkillFolder(folder);\n if (computeContentSha256(content.files) !== proposal.content_sha256) {\n throw new ProposalDigestMismatchError(\n `proposal ${proposal.proposal_id}: the snapshot no longer matches ` +\n `content_sha256 ${proposal.content_sha256.slice(0, 12)}`,\n );\n }\n return content;\n}\n\n/** The shared skill already using `name`, if any (retired included). */\nexport function collisionFor(libraryPath: string, name: string): SkillIndexRow | null {\n try {\n return getSkillRow(libraryPath, name);\n } catch (err) {\n if (err instanceof SkillNotFoundError) return null;\n throw err;\n }\n}\n\n// -- the advisory ballot ------------------------------------------------------\n\nfunction engine(libraryPath: string): ConsensusEngine {\n return new ConsensusEngine(join(libraryPath, \".consensus\"));\n}\n\n/** A Node filesystem error (Python's `OSError`) or a plain `Error` the engine\n * raises for bad input (Python's `ValueError`). */\nfunction isOsOrValueError(err: unknown): boolean {\n return err instanceof Error;\n}\n\n/**\n * Open a consensus ballot under the proposal's id. Votes on it only advise.\n *\n * Returns false (and leaves the proposal without a ballot) when one cannot be\n * opened; a proposal never fails over its advisory ballot.\n */\nexport function openAdvisoryBallot(libraryPath: string, proposal: SkillProposal): boolean {\n try {\n engine(libraryPath).propose({\n topic: `Promote skill '${proposal.name}' into the shared library (advisory)`,\n options: [...BALLOT_OPTIONS],\n proposedBy: proposal.proposed_by,\n proposalId: proposal.proposal_id,\n metadata: {\n kind: \"skill_proposal\",\n advisory: true,\n content_sha256: proposal.content_sha256,\n source_agent: proposal.source_agent,\n },\n });\n } catch (err) {\n if (isOsOrValueError(err)) return false;\n throw err;\n }\n const folder = proposalDir(libraryPath, proposal.proposal_id);\n withManifestLock(join(folder, RECORD_NAME), () => {\n const current = loadProposal(libraryPath, proposal.proposal_id);\n current.ballot = true;\n writeRecord(folder, current);\n });\n proposal.ballot = true;\n return true;\n}\n\nexport type AdvisoryTally = Record<\n (typeof BALLOT_OPTIONS)[number],\n { votes: number; voters: string[] }\n>;\n\n/** Vote counts and voters on the proposal's ballot; null without one. */\nexport function advisoryTally(libraryPath: string, proposal: SkillProposal): AdvisoryTally | null {\n if (!proposal.ballot) return null;\n let tally: Dict;\n try {\n tally = engine(libraryPath).tally(proposal.proposal_id);\n } catch {\n return null;\n }\n const summary = isDict(tally.options_summary) ? tally.options_summary : {};\n const out = {} as AdvisoryTally;\n for (const option of BALLOT_OPTIONS) {\n const entry = isDict(summary[option]) ? summary[option] : {};\n const voters = Array.isArray(entry.voters) ? entry.voters : [];\n out[option] = {\n votes: Math.trunc(Number(entry.votes ?? 0)),\n voters: voters\n .map((v) => String(isDict(v) ? v.agent_id : undefined))\n .sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)),\n };\n }\n return out;\n}\n\nfunction closeBallot(\n libraryPath: string,\n proposal: SkillProposal,\n status: string,\n outcome: string,\n): void {\n if (!proposal.ballot) return;\n // The decision already landed; the ballot only advised it.\n try {\n engine(libraryPath).close(proposal.proposal_id, status, {\n decided_by_gate: \"skill approval\",\n outcome,\n });\n } catch {\n // best effort\n }\n}\n\nfunction tallyText(tally: AdvisoryTally | null): string {\n if (tally === null) return \"advisory=none\";\n return \"advisory=\" + BALLOT_OPTIONS.map((opt) => `${opt}:${tally[opt].votes}`).join(\",\");\n}\n\n// -- audit --------------------------------------------------------------------\n\n/** Audit row BEFORE the mutation, fail-closed (`required: true`). */\nfunction record(\n audit: FederationAudit | null | undefined,\n actor: string,\n op: string,\n namespace: string,\n detail: string,\n): void {\n if (!audit) return;\n audit.record(actor, op, namespace, DECISION_ALLOW, detail, { required: true });\n}\n\nfunction recordFailure(\n audit: FederationAudit | null | undefined,\n actor: string,\n op: string,\n namespace: string,\n exc: unknown,\n): void {\n if (!audit) return;\n // Best effort: the original error is the one to surface.\n try {\n const kind = exc instanceof Error ? exc.name : typeof exc;\n audit.record(actor, op, namespace, DECISION_DENY, `failed: ${kind}`);\n } catch {\n // ignored\n }\n}\n\n// -- deciding -----------------------------------------------------------------\n\nexport interface ApprovalResult {\n proposal: SkillProposal;\n row: SkillIndexRow;\n changed: boolean;\n renamedFrom: string | null;\n advisory: AdvisoryTally | null;\n}\n\nfunction checkExpected(proposal: SkillProposal, expectedSha256: string | null | undefined): void {\n if (expectedSha256 === null || expectedSha256 === undefined) return;\n const prefix = expectedSha256.trim().toLowerCase();\n if (prefix.length < 8 || !proposal.content_sha256.startsWith(prefix)) {\n throw new ProposalDigestMismatchError(\n `proposal ${proposal.proposal_id} has content_sha256 ` +\n `${proposal.content_sha256.slice(0, 12)}, not the ${prefix.slice(0, 12)} that was reviewed`,\n );\n }\n}\n\nexport interface ApproveProposalOptions {\n approvedBy: string;\n channel: string;\n /** At least 8 hex characters: pins the decision to the bytes reviewed. */\n expectedSha256?: string | null;\n name?: string | null;\n update?: boolean;\n visibility?: string | null;\n audit?: FederationAudit | null;\n}\n\n/**\n * Promote a pending proposal's snapshot into the shared library.\n *\n * This is the one human-confirmed approval. It is not exposed over MCP; the\n * operator's terminal command calls it after asking the person at the keyboard\n * to confirm (`channel` records how).\n *\n * Naming: the skill's own name by default, or `name`. When that name is taken,\n * `update: true` promotes the snapshot as the next version of the existing\n * skill; otherwise the skill is renamed to a free name and the original name is\n * reported in `renamedFrom`.\n */\nexport function approveProposal(\n libraryPath: string,\n proposalId: string,\n options: ApproveProposalOptions,\n): ApprovalResult {\n const { approvedBy, channel, audit } = options;\n const folder = existingProposalDir(libraryPath, proposalId);\n const outcome = withManifestLock(join(folder, RECORD_NAME), () => {\n const proposal = loadProposal(libraryPath, proposalId);\n if (proposal.status !== STATUS_PENDING) {\n throw new ProposalStateError(`proposal ${proposalId} is already ${proposal.status}`);\n }\n checkExpected(proposal, options.expectedSha256);\n const content = readProposalContent(libraryPath, proposal);\n\n let target = validateSkillName(options.name ?? proposal.name);\n const existing = collisionFor(libraryPath, target);\n let expectedVersion: number | null = null;\n let renamedFrom: string | null = null;\n if (existing !== null) {\n if (options.update) {\n expectedVersion = existing.version;\n } else {\n const suggestion = suggestAvailableName(libraryPath, target);\n if (suggestion === null) {\n throw new SkillProposalError(`no free name derived from '${target}'`);\n }\n renamedFrom = target;\n target = suggestion;\n }\n } else if (options.update) {\n throw new SkillNotFoundError(`no shared skill named '${target}' to update`);\n }\n\n const tally = advisoryTally(libraryPath, proposal);\n const visibility = options.visibility || proposal.visibility;\n let detail =\n `proposal=${proposalId} name=${target} content_sha256=${proposal.content_sha256} ` +\n `source_agent=${proposal.source_agent} proposed_by=${proposal.proposed_by} ` +\n `proposer_tier=${proposal.proposer_tier} channel=${channel} ${tallyText(tally)}`;\n if (renamedFrom !== null) detail += ` renamed_from=${renamedFrom}`;\n record(audit, approvedBy, \"skill.approve\", proposal.source_agent, detail);\n let result;\n try {\n result = promoteSkill(libraryPath, content, {\n sourceAgent: proposal.source_agent,\n promotedBy: approvedBy,\n name: target,\n expectedVersion,\n visibility,\n proposalId,\n });\n } catch (exc) {\n recordFailure(audit, approvedBy, \"skill.approve\", proposal.source_agent, exc);\n throw exc;\n }\n\n proposal.status = STATUS_APPROVED;\n const decision: Dict = {\n by: approvedBy,\n at: nowIso(),\n channel,\n promoted_name: result.row.name,\n promoted_version: result.row.version,\n changed: result.changed,\n };\n if (renamedFrom !== null) decision.renamed_from = renamedFrom;\n if (tally !== null) {\n decision.advisory = Object.fromEntries(BALLOT_OPTIONS.map((opt) => [opt, tally[opt].votes]));\n }\n proposal.decision = decision;\n writeRecord(folder, proposal);\n return { proposal, result, renamedFrom, tally };\n });\n closeBallot(libraryPath, outcome.proposal, \"resolved\", \"approved\");\n return {\n proposal: outcome.proposal,\n row: outcome.result.row,\n changed: outcome.result.changed,\n renamedFrom: outcome.renamedFrom,\n advisory: outcome.tally,\n };\n}\n\nexport interface RejectProposalOptions {\n rejectedBy: string;\n channel: string;\n reason?: string;\n expectedSha256?: string | null;\n audit?: FederationAudit | null;\n}\n\n// str.isspace() characters, as str.split() with no argument splits on them.\nconst PY_WHITESPACE_RUN =\n // eslint-disable-next-line no-control-regex\n /[\\t\\n\\v\\f\\r\\x1c-\\x1f \\x85\\xa0\\u1680\\u2000-\\u200a\\u2028\\u2029\\u202f\\u205f\\u3000]+/;\n\n/** Python `\" \".join(text.split())`. */\nfunction collapseWhitespace(text: string): string {\n return text\n .split(PY_WHITESPACE_RUN)\n .filter((part) => part !== \"\")\n .join(\" \");\n}\n\n/** Mark a pending proposal rejected. The snapshot is kept for the record. */\nexport function rejectProposal(\n libraryPath: string,\n proposalId: string,\n options: RejectProposalOptions,\n): SkillProposal {\n const { rejectedBy, channel, audit } = options;\n const folder = existingProposalDir(libraryPath, proposalId);\n const reason = [...collapseWhitespace(options.reason ?? \"\")]\n .slice(0, SKILL_PROPOSAL_LIMITS.maxReasonChars)\n .join(\"\");\n const proposal = withManifestLock(join(folder, RECORD_NAME), () => {\n const current = loadProposal(libraryPath, proposalId);\n if (current.status !== STATUS_PENDING) {\n throw new ProposalStateError(`proposal ${proposalId} is already ${current.status}`);\n }\n checkExpected(current, options.expectedSha256);\n const tally = advisoryTally(libraryPath, current);\n record(\n audit,\n rejectedBy,\n \"skill.reject\",\n current.source_agent,\n `proposal=${proposalId} name=${current.name} ` +\n `content_sha256=${current.content_sha256} channel=${channel} ${tallyText(tally)}`,\n );\n current.status = STATUS_REJECTED;\n const decision: Dict = { by: rejectedBy, at: nowIso(), channel };\n if (reason) decision.reason = reason;\n if (tally !== null) {\n decision.advisory = Object.fromEntries(BALLOT_OPTIONS.map((opt) => [opt, tally[opt].votes]));\n }\n current.decision = decision;\n writeRecord(folder, current);\n return current;\n });\n closeBallot(libraryPath, proposal, \"rejected\", \"rejected\");\n return proposal;\n}\n\n// -- retirement and rollback ----------------------------------------------------\n\n/**\n * Retire the live version (`valid_to`, default today). Versions are kept.\n *\n * A retired skill leaves the default index and `get_skill` without a version;\n * every version stays fetchable by number, and {@link rollbackSharedSkill}\n * brings one back.\n */\nexport function retireSharedSkill(\n libraryPath: string,\n name: string,\n options: {\n retiredBy: string;\n channel: string;\n validTo?: string | null;\n audit?: FederationAudit | null;\n },\n): SkillIndexRow {\n const { retiredBy, channel, audit } = options;\n const live = getSkillRow(libraryPath, validateSkillName(name));\n const when = options.validTo || today();\n record(\n audit,\n retiredBy,\n \"skill.retire\",\n live.sourceAgent,\n `name=${name} version=${live.version} valid_to=${when} channel=${channel}`,\n );\n try {\n return setSkillValidTo(libraryPath, name, when, { expectedVersion: live.version });\n } catch (exc) {\n recordFailure(audit, retiredBy, \"skill.retire\", live.sourceAgent, exc);\n throw exc;\n }\n}\n\nexport interface RollbackResult {\n row: SkillIndexRow;\n /** True when a new version was written. */\n changed: boolean;\n /** True when a retirement was lifted. */\n restored: boolean;\n}\n\n/**\n * Make version `toVersion`'s content current again, as a NEW version.\n *\n * History is never rewritten: rolling back to version 2 of a skill at version 4\n * writes version 5 with version 2's files (re-hashed before they are used), so\n * every version stays fetchable. Rolling back a retired skill also lifts the\n * retirement; rolling back to the live version of a retired skill only lifts it.\n */\nexport function rollbackSharedSkill(\n libraryPath: string,\n name: string,\n toVersion: number,\n options: { promotedBy: string; channel: string; audit?: FederationAudit | null },\n): RollbackResult {\n const { promotedBy, channel, audit } = options;\n validateSkillName(name);\n const live = getSkillRow(libraryPath, name);\n const { row: targetRow, content } = readSharedSkill(libraryPath, name, toVersion);\n if (computeContentSha256(content.files) !== targetRow.contentSha256) {\n throw new ProposalDigestMismatchError(\n `stored files of '${name}' v${toVersion} do not match their content_sha256`,\n );\n }\n const retired = live.validTo !== null;\n if (toVersion === live.version && !retired) {\n throw new SkillProposalError(`'${name}' is already at version ${toVersion}`);\n }\n record(\n audit,\n promotedBy,\n \"skill.rollback\",\n targetRow.sourceAgent,\n `name=${name} from_version=${live.version} to_version=${toVersion} ` +\n `content_sha256=${targetRow.contentSha256} channel=${channel}`,\n );\n try {\n let changed = false;\n let row = live;\n if (toVersion !== live.version) {\n const result = promoteSkill(libraryPath, content, {\n sourceAgent: targetRow.sourceAgent,\n promotedBy,\n name,\n expectedVersion: live.version,\n visibility: targetRow.visibility,\n proposalId: targetRow.proposalId,\n });\n changed = result.changed;\n row = result.row;\n }\n let restored = false;\n if (row.validTo !== null) {\n row = setSkillValidTo(libraryPath, name, null, { expectedVersion: row.version });\n restored = true;\n }\n return { row, changed, restored };\n } catch (exc) {\n recordFailure(audit, promotedBy, \"skill.rollback\", targetRow.sourceAgent, exc);\n throw exc;\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * StackBlitz Bolt.new participant — port of `participants/bolt.py`.\n *\n * Bolt.new builds and runs full-stack apps in WebContainers, in the browser,\n * so nothing useful lands on the user's machine. It federates through an\n * export directory; see {@link ExportStoreParticipant} for the store layout\n * and the mechanics this shares with Lovable and v0.\n */\n\nimport {\n Visibility,\n makeEntity,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ExportStoreParticipant,\n isoDate,\n parseVisibility,\n safeStr,\n safeStrList,\n type ExportStoreConfig,\n} from \"../export-store-base.js\";\n\ntype Dict = Record<string, unknown>;\n\nexport const AGENT_ID = \"bolt\";\nexport const AGENT_TYPE = \"code-assistant\";\nexport const ROLE_NARRATIVE =\n \"StackBlitz Bolt.new in-browser AI development environment. Builds, executes, \" +\n \"and iterates full-stack applications in WebContainers from chat. Bourdon \" +\n \"reads exported project and session state so other agents recognize what \" +\n \"Bolt.new has developed.\";\n\nexport const DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"credential\", \"secret\", \"client-confidential\", \"private\"],\n team_tags: [\"bolt\", \"project\", \"webcontainer\", \"stackblitz\"],\n});\n\nconst MAX_SUMMARY_CHARS = 320;\nconst MAX_KEY_ACTION_CHARS = 300;\nconst NAME_LIMIT = 80;\n\n/**\n * One `projects.json` record to an Entity.\n *\n * Bolt caps the name at 80 characters, falls back to a generated summary when\n * the record has no description, and inserts its own tag only when absent —\n * all three differ from Lovable's mapper, deliberately. See the note in\n * export-store-base.ts.\n */\nexport function projectToEntity(record: Dict): EntityModel | null {\n const rawName = record.name;\n if (typeof rawName !== \"string\" || !rawName) return null;\n const name = safeStr(rawName, NAME_LIMIT);\n if (!name) return null;\n\n const summary = safeStr(record.description ?? \"\", MAX_SUMMARY_CHARS) || `Bolt.new project ${name}`;\n\n const tags = safeStrList(record.tags, 40);\n if (!tags.includes(\"bolt\")) tags.unshift(\"bolt\");\n\n const updated = isoDate(record.updated_at);\n const archived = Boolean(record.archived ?? false);\n\n return makeEntity({\n name,\n type: \"project\",\n summary,\n tags,\n last_touched: updated,\n valid_from: isoDate(record.created_at),\n valid_to: archived ? updated : null,\n visibility: parseVisibility(record.visibility),\n });\n}\n\n/** One `sessions/<id>.json` record to a Session, or null with no usable date. */\nexport function sessionToRecord(record: Dict, fallbackDate: string | null): SessionModel | null {\n const date = isoDate(record.date) ?? fallbackDate;\n if (!date) return null;\n const project = String(record.project ?? \"\").trim();\n return makeSession({\n date,\n cwd: null, // cloud agent: there is no local working directory to name\n project_focus: project ? [redactText(project, 120)] : [],\n key_actions: safeStrList(record.key_actions, MAX_KEY_ACTION_CHARS),\n files_touched: safeStrList(record.files_touched),\n visibility: parseVisibility(record.visibility),\n });\n}\n\nexport const BOLT_CONFIG: ExportStoreConfig = {\n agentId: AGENT_ID,\n agentType: AGENT_TYPE,\n displayName: \"Bolt.new\",\n directoryName: \".bolt\",\n stateEnvVar: \"BOLT_STATE_DIR\",\n roleNarrative: ROLE_NARRATIVE,\n capabilities: [\"in-browser-dev\", \"webcontainers\", \"full-stack-generation\"],\n policy: DEFAULT_POLICY,\n label: \"Bolt.new\",\n initCommand: \"bourdon bolt init\",\n projectToEntity,\n sessionToRecord,\n};\n\nexport class BoltParticipant extends ExportStoreParticipant {\n constructor(options: { stateDir?: string; env?: NodeJS.ProcessEnv } = {}) {\n super(BOLT_CONFIG, options);\n }\n\n static defaultNativePath(home?: string): string {\n return ExportStoreParticipant.defaultNativePath(\".bolt\", home);\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Shared mechanics for the \"JSON export store\" participant family.\n *\n * Bolt.new, Lovable and v0 are cloud builders that persist nothing useful on\n * the user's machine, so each federates through a directory the user exports\n * into:\n *\n * $<AGENT>_STATE_DIR/ (default: ~/.<agent>/)\n * projects.json array of project records, or {projects: [...]}\n * sessions/<id>.json one JSON document per session\n *\n * The oracle implements this three times (`participants/{bolt,lovable,v0}.py`,\n * ~1,130 lines). The store layout, the date parser, the visibility parser, the\n * loader's error semantics and the health-check ladder are identical across\n * all three, so they live here once.\n *\n * ⚠ What is NOT shared: each reader's `projectToEntity` / `sessionToRecord`.\n * They look similar and are not the same — Lovable caps a project name at 120\n * characters where Bolt caps at 80, emits a NULL summary where Bolt emits a\n * `\"Bolt.new project <name>\"` fallback, and appends its own tag\n * unconditionally where Bolt inserts only if absent (so Lovable really can\n * emit a duplicate tag). Those differences are the oracle's behaviour and the\n * mirror reproduces them rather than tidying them into agreement; each reader\n * supplies its own mapper.\n */\n\nimport { readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport {\n Visibility,\n filterForFederation,\n makeAgentInfo,\n makeManifest,\n type EntityModel,\n type L5ManifestModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport { ParticipantDiscoveryError, ParticipantExportError, SPEC_VERSION, type AgentStore, type HealthStatus } from \"./base.js\";\n\ntype Dict = Record<string, unknown>;\n\nconst VISIBILITY_VALUES = new Set<string>(Object.values(Visibility) as string[]);\n\n/**\n * `_parse_visibility`: a recognized visibility string, else null (meaning\n * \"inherit the policy default\"), never a throw.\n */\nexport function parseVisibility(raw: unknown): Visibility | null {\n if (typeof raw !== \"string\") return null;\n const value = raw.trim().toLowerCase();\n return VISIBILITY_VALUES.has(value) ? (value as Visibility) : null;\n}\n\n/**\n * `_iso_date`: normalize to a bare `YYYY-MM-DD`, or null if unparseable.\n *\n * Accepts a full ISO timestamp (trailing `Z` included) and reduces it to its\n * date, which is what every L5 date field carries.\n */\nexport function isoDate(raw: unknown): string | null {\n if (typeof raw !== \"string\" || !raw.trim()) return null;\n const text = raw.trim();\n if (text.includes(\"T\")) {\n const parsed = new Date(text.replace(/Z$/, \"+00:00\"));\n if (Number.isNaN(parsed.getTime())) return null;\n return parsed.toISOString().slice(0, 10);\n }\n // Python's strptime(\"%Y-%m-%d\") rejects anything else, including a real\n // date in another format — matched here rather than letting Date() guess.\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(text)) return null;\n const parsed = new Date(`${text}T00:00:00Z`);\n if (Number.isNaN(parsed.getTime())) return null;\n // Rejects 2026-02-31, which the regex alone would accept.\n return parsed.toISOString().slice(0, 10) === text ? text : null;\n}\n\n/** `_safe_str`: trim, then route through the redaction SSOT. \"\" stays \"\". */\nexport function safeStr(raw: unknown, limit = 240): string {\n if (raw === null || raw === undefined) return \"\";\n const text = String(raw).trim();\n return text ? redactText(text, limit) : \"\";\n}\n\n/** `_str_list` in the Bolt/v0 spelling: redact every item, drop the empties. */\nexport function safeStrList(raw: unknown, limit = 200): string[] {\n if (!Array.isArray(raw)) return [];\n const out: string[] = [];\n for (const item of raw) {\n const cleaned = safeStr(item, limit);\n if (cleaned) out.push(cleaned);\n }\n return out;\n}\n\nexport interface ExportStoreConfig {\n agentId: string;\n agentType: string;\n displayName: string;\n /** Directory name under $HOME, e.g. `.bolt`. */\n directoryName: string;\n /** Environment variable that overrides the state directory. */\n stateEnvVar: string;\n roleNarrative: string;\n capabilities: string[];\n policy: VisibilityPolicyModel;\n /** Human label used in error and health text, e.g. \"Bolt.new\". */\n label: string;\n /** The `bourdon <x> init` verb named in remediation text. */\n initCommand: string;\n projectToEntity: (record: Dict) => EntityModel | null;\n sessionToRecord: (record: Dict, fallbackDate: string | null) => SessionModel | null;\n}\n\nexport class ExportStoreParticipant {\n readonly agentId: string;\n readonly agentType: string;\n readonly displayName: string;\n private readonly config: ExportStoreConfig;\n private readonly stateDir: string | undefined;\n private readonly env: NodeJS.ProcessEnv;\n\n constructor(config: ExportStoreConfig, options: { stateDir?: string; env?: NodeJS.ProcessEnv } = {}) {\n this.config = config;\n this.agentId = config.agentId;\n this.agentType = config.agentType;\n this.displayName = config.displayName;\n this.stateDir = options.stateDir;\n this.env = options.env ?? process.env;\n }\n\n static defaultNativePath(directoryName: string, home?: string): string {\n return join(home ?? homedir(), directoryName);\n }\n\n get nativePath(): string {\n return this.resolveStateDir();\n }\n\n private resolveStateDir(): string {\n if (this.stateDir !== undefined) return this.stateDir;\n const override = (this.env[this.config.stateEnvVar] ?? \"\").trim();\n if (override) return override;\n return ExportStoreParticipant.defaultNativePath(this.config.directoryName);\n }\n\n private requireStateDir(): string {\n const dir = this.resolveStateDir();\n if (!isDir(dir)) {\n throw new ParticipantDiscoveryError(\n `${this.config.label} state directory not found at '${dir}'.`,\n );\n }\n return dir;\n }\n\n /**\n * `projects.json`, accepting either a bare array or `{projects: [...]}`.\n *\n * A MISSING file is empty (the store may legitimately hold only sessions);\n * a PRESENT but unreadable or wrongly-shaped file throws. The distinction is\n * the point: absence is a state, corruption is an error.\n */\n private loadProjects(stateDir: string): Dict[] {\n const path = join(stateDir, \"projects.json\");\n if (!isFile(path)) return [];\n let payload: unknown;\n try {\n payload = JSON.parse(stripBom(readFileSync(path, \"utf-8\")));\n } catch (exc) {\n throw new ParticipantExportError(\n `${this.config.label} projects store present but unreadable at ${path}: ${\n exc instanceof Error ? exc.message : String(exc)\n }`,\n );\n }\n if (Array.isArray(payload)) return payload.filter(isDict);\n if (isDict(payload) && Array.isArray(payload.projects)) return payload.projects.filter(isDict);\n throw new ParticipantExportError(\n `${this.config.label} projects store at ${path} must be a JSON array or object with projects list.`,\n );\n }\n\n private sessionFiles(stateDir: string): string[] {\n const dir = join(stateDir, \"sessions\");\n if (!isDir(dir)) return [];\n return readdirSync(dir)\n .filter((f) => f.endsWith(\".json\"))\n .sort()\n .map((f) => join(dir, f));\n }\n\n /** Newest first. An unreadable session is skipped, never fatal. */\n private loadSessions(stateDir: string): SessionModel[] {\n const out: SessionModel[] = [];\n for (const path of this.sessionFiles(stateDir)) {\n let payload: unknown;\n try {\n payload = JSON.parse(stripBom(readFileSync(path, \"utf-8\")));\n } catch {\n continue;\n }\n if (!isDict(payload)) continue;\n const session = this.config.sessionToRecord(payload, null);\n if (session !== null) out.push(session);\n }\n out.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));\n return out;\n }\n\n discover(): AgentStore {\n const stateDir = this.resolveStateDir();\n if (!isDir(stateDir)) {\n throw new ParticipantDiscoveryError(\n `${this.config.label} state directory not found at '${stateDir}'. ` +\n `Create it and add a projects.json export or run \\`${this.config.initCommand}\\`.`,\n );\n }\n return {\n path: stateDir,\n version: \"export-v1\",\n metadata: {\n projects_file: isFile(join(stateDir, \"projects.json\")),\n session_files: this.sessionFiles(stateDir).length,\n env_override: Boolean((this.env[this.config.stateEnvVar] ?? \"\").trim()),\n },\n };\n }\n\n exportSessions(since: Date, limit = 100): SessionModel[] {\n const stateDir = this.requireStateDir();\n const sinceIso = since.toISOString().slice(0, 10);\n // `limit` is honoured, not decorative: a caller asking for 5 gets 5.\n return this.loadSessions(stateDir)\n .filter((s) => s.date >= sinceIso)\n .slice(0, limit);\n }\n\n exportL5(since?: Date | null): L5ManifestModel {\n const stateDir = this.requireStateDir();\n\n let sessions = this.loadSessions(stateDir);\n if (since !== undefined && since !== null) {\n const sinceIso = since.toISOString().slice(0, 10);\n sessions = sessions.filter((s) => s.date >= sinceIso);\n }\n\n const entities: EntityModel[] = [];\n const seen = new Set<string>();\n for (const record of this.loadProjects(stateDir)) {\n const entity = this.config.projectToEntity(record);\n if (entity === null) continue;\n const key = entity.name.toLowerCase();\n if (seen.has(key)) continue;\n seen.add(key);\n entities.push(entity);\n }\n\n // The PII guardrail, and it belongs HERE: L6 trusts whatever a participant\n // emits, so an entity that resolves to PRIVATE must never leave this\n // function. Filtering downstream would be too late.\n const visibleEntities = filterForFederation(entities, this.config.policy);\n\n return makeManifest({\n spec_version: SPEC_VERSION,\n agent: makeAgentInfo({\n id: this.config.agentId,\n type: this.config.agentType,\n role_narrative: this.config.roleNarrative,\n spec_version_compat: SPEC_VERSION,\n }),\n last_updated: new Date().toISOString().replace(/\\.\\d{3}Z$/, \"+00:00\"),\n capabilities: [...this.config.capabilities],\n recent_sessions: sessions,\n known_entities: visibleEntities,\n visibility_policy: this.config.policy,\n });\n }\n\n /** MUST NOT throw: the L6 server calls this in a polling loop. */\n healthCheck(): HealthStatus {\n try {\n const stateDir = this.resolveStateDir();\n if (!isDir(stateDir)) {\n return {\n status: \"blocked\",\n reason: `${this.config.label} state directory not found at '${stateDir}'.`,\n details: { expected: stateDir },\n proposedFix: `Run \\`${this.config.initCommand}\\` or create ${stateDir} and add projects.json.`,\n };\n }\n const projectsFile = join(stateDir, \"projects.json\");\n const sessionFiles = this.sessionFiles(stateDir);\n if (!isFile(projectsFile) && sessionFiles.length === 0) {\n return {\n status: \"degraded\",\n reason: \"State directory exists but contains no projects.json or sessions.\",\n details: { path: stateDir },\n proposedFix: `Run \\`${this.config.initCommand}\\` or export projects into projects.json.`,\n };\n }\n // Parse both, so a corrupt store reports degraded here instead of\n // throwing later inside a federation read.\n this.loadProjects(stateDir);\n this.loadSessions(stateDir);\n return {\n status: \"ok\",\n details: {\n path: stateDir,\n projects_file: isFile(projectsFile),\n session_files: sessionFiles.length,\n },\n };\n } catch (exc) {\n return {\n status: \"degraded\",\n reason: exc instanceof Error ? exc.message : String(exc),\n details: {},\n proposedFix: `Inspect ${this.resolveStateDirSafe()}/projects.json for syntax errors.`,\n };\n }\n }\n\n private resolveStateDirSafe(): string {\n try {\n return this.resolveStateDir();\n } catch {\n return `~/${this.config.directoryName}`;\n }\n }\n}\n\n// -- helpers ------------------------------------------------------------------\n\nfunction isDict(v: unknown): v is Dict {\n return v !== null && typeof v === \"object\" && !Array.isArray(v);\n}\n\nfunction isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\n/** Python reads these with `encoding=\"utf-8-sig\"`, so a BOM is not a parse error. */\nfunction stripBom(text: string): string {\n return text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Lovable participant — port of `participants/lovable.py`.\n *\n * Lovable builds full-stack web apps from chat in the cloud, so nothing useful\n * lands on the user's machine. It federates through an export directory; see\n * {@link ExportStoreParticipant} for the store layout and the mechanics this\n * shares with Bolt.new and v0.\n *\n * ⚠ The mapper below is NOT Bolt's with the names swapped, and must not be\n * refactored into it. Lovable's oracle differs in four ways, each reproduced\n * exactly here:\n *\n * 1. the project name is capped at 120 characters, not 80;\n * 2. a record with no description yields a NULL summary, where Bolt\n * synthesizes `\"Bolt.new project <name>\"`;\n * 3. the `\"lovable\"` tag is APPENDED unconditionally, so a record that\n * already carries it ends up with it twice — Bolt inserts only if absent;\n * 4. `updated_at` falls back to `created_at`, where Bolt leaves\n * `last_touched` null.\n *\n * (3) also means the tag lands LAST rather than first. None of this is\n * defensible design; all of it is what the oracle does, and the mirror's job\n * is to agree with the oracle, not to improve on it. Fixing any of it is an\n * oracle-side change the conformance fixtures would have to absorb first.\n */\n\nimport {\n Visibility,\n makeEntity,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ExportStoreParticipant,\n isoDate,\n parseVisibility,\n safeStrList,\n type ExportStoreConfig,\n} from \"../export-store-base.js\";\n\ntype Dict = Record<string, unknown>;\n\nexport const AGENT_ID = \"lovable\";\nexport const AGENT_TYPE = \"code-assistant\";\nexport const ROLE_NARRATIVE =\n \"Cloud app-building agent. Designs, builds, and iterates full-stack web \" +\n \"applications from chat. Bourdon reads exported project and session state \" +\n \"so other agents recognize what Lovable has built.\";\n\nexport const DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"credential\", \"secret\", \"client-confidential\"],\n team_tags: [\"lovable\", \"project\", \"client\"],\n});\n\nconst MAX_SUMMARY_CHARS = 320;\nconst MAX_KEY_ACTION_CHARS = 300;\nconst NAME_LIMIT = 120;\n\n/** One `projects.json` record to an Entity. See the four notes in the header. */\nexport function projectToEntity(record: Dict): EntityModel | null {\n const name = String(record.name ?? \"\").trim();\n if (!name) return null;\n\n const summary = record.description;\n // (2) absent description -> null, not a synthesized sentence.\n const summaryText =\n summary === null || summary === undefined || summary === \"\"\n ? null\n : redactText(String(summary), MAX_SUMMARY_CHARS);\n\n // (3) unconditional append: a record already tagged \"lovable\" gets it twice.\n const tags = safeStrList(record.tags);\n tags.push(\"lovable\");\n\n const archived = Boolean(record.archived);\n // (4) updated_at falls back to created_at.\n const updated = isoDate(record.updated_at) ?? isoDate(record.created_at);\n\n return makeEntity({\n name: redactText(name, NAME_LIMIT), // (1) 120, not 80\n type: \"project\",\n summary: summaryText,\n tags,\n last_touched: updated,\n valid_from: isoDate(record.created_at),\n valid_to: archived ? updated : null,\n visibility: parseVisibility(record.visibility),\n });\n}\n\n/** One `sessions/<id>.json` record to a Session, or null with no usable date. */\nexport function sessionToRecord(record: Dict, fallbackDate: string | null): SessionModel | null {\n const date = isoDate(record.date) ?? fallbackDate;\n if (!date) return null;\n const project = String(record.project ?? \"\").trim();\n return makeSession({\n date,\n cwd: null, // cloud agent: there is no local working directory to name\n project_focus: project ? [redactText(project, 120)] : [],\n key_actions: safeStrList(record.key_actions, MAX_KEY_ACTION_CHARS),\n // ⚠ No limit, so these are NOT redacted — the oracle's behaviour. Bolt and\n // v0 redact the same field. Flagged, not silently corrected.\n files_touched: safeStrList(record.files_touched),\n visibility: parseVisibility(record.visibility),\n });\n}\n\nexport const LOVABLE_CONFIG: ExportStoreConfig = {\n agentId: AGENT_ID,\n agentType: AGENT_TYPE,\n displayName: \"Lovable\",\n directoryName: \".lovable\",\n stateEnvVar: \"LOVABLE_STATE_DIR\",\n roleNarrative: ROLE_NARRATIVE,\n capabilities: [\"app-building\", \"full-stack-generation\", \"deploy-preview\"],\n policy: DEFAULT_POLICY,\n label: \"Lovable\",\n initCommand: \"bourdon lovable init\",\n projectToEntity,\n sessionToRecord,\n};\n\nexport class LovableParticipant extends ExportStoreParticipant {\n constructor(options: { stateDir?: string; env?: NodeJS.ProcessEnv } = {}) {\n super(LOVABLE_CONFIG, options);\n }\n\n static defaultNativePath(home?: string): string {\n return ExportStoreParticipant.defaultNativePath(\".lovable\", home);\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Vercel v0 participant — port of `participants/v0.py`.\n *\n * v0 generates React / Next.js / Tailwind UI and full-stack web apps from\n * chat, entirely server-side, so nothing useful lands on the user's machine.\n * It federates through an export directory; see {@link ExportStoreParticipant}\n * for the store layout and the mechanics this shares with Bolt.new and\n * Lovable. The mapper below is byte-for-byte Bolt's rule with v0's own name\n * and tag — that is the oracle's shape, not a shortcut taken here.\n */\n\nimport {\n Visibility,\n makeEntity,\n makeSession,\n makeVisibilityPolicy,\n type EntityModel,\n type SessionModel,\n type VisibilityPolicyModel,\n} from \"@getbourdon/l5\";\nimport { redactText } from \"@getbourdon/redaction\";\n\nimport {\n ExportStoreParticipant,\n isoDate,\n parseVisibility,\n safeStr,\n safeStrList,\n type ExportStoreConfig,\n} from \"../export-store-base.js\";\n\ntype Dict = Record<string, unknown>;\n\nexport const AGENT_ID = \"v0\";\nexport const AGENT_TYPE = \"code-assistant\";\nexport const ROLE_NARRATIVE =\n \"Vercel v0 generative UI and full-stack web builder. Designs and iterates \" +\n \"React, Next.js, and Tailwind components and web applications from chat. \" +\n \"Bourdon reads exported project and session state so other agents recognize \" +\n \"what v0 has designed and constructed.\";\n\nexport const DEFAULT_POLICY: VisibilityPolicyModel = makeVisibilityPolicy({\n default: Visibility.TEAM,\n private_tags: [\"personal\", \"credential\", \"secret\", \"client-confidential\", \"private\"],\n team_tags: [\"v0\", \"project\", \"client\", \"ui\", \"component\"],\n});\n\nconst MAX_SUMMARY_CHARS = 320;\nconst MAX_KEY_ACTION_CHARS = 300;\nconst NAME_LIMIT = 80;\n\n/**\n * One `projects.json` record to an Entity.\n *\n * Caps the name at 80 characters, falls back to a generated summary when the\n * record has no description, and inserts its own tag only when absent. All\n * three differ from Lovable's mapper, deliberately. See the note in\n * export-store-base.ts.\n */\nexport function projectToEntity(record: Dict): EntityModel | null {\n const rawName = record.name;\n if (typeof rawName !== \"string\" || !rawName) return null;\n const name = safeStr(rawName, NAME_LIMIT);\n if (!name) return null;\n\n const summary = safeStr(record.description ?? \"\", MAX_SUMMARY_CHARS) || `v0 project ${name}`;\n\n const tags = safeStrList(record.tags, 40);\n if (!tags.includes(\"v0\")) tags.unshift(\"v0\");\n\n const updated = isoDate(record.updated_at);\n const archived = Boolean(record.archived ?? false);\n\n return makeEntity({\n name,\n type: \"project\",\n summary,\n tags,\n last_touched: updated,\n valid_from: isoDate(record.created_at),\n valid_to: archived ? updated : null,\n visibility: parseVisibility(record.visibility),\n });\n}\n\n/** One `sessions/<id>.json` record to a Session, or null with no usable date. */\nexport function sessionToRecord(record: Dict, fallbackDate: string | null): SessionModel | null {\n const date = isoDate(record.date) ?? fallbackDate;\n if (!date) return null;\n const project = String(record.project ?? \"\").trim();\n return makeSession({\n date,\n cwd: null, // cloud agent: there is no local working directory to name\n project_focus: project ? [redactText(project, 120)] : [],\n key_actions: safeStrList(record.key_actions, MAX_KEY_ACTION_CHARS),\n files_touched: safeStrList(record.files_touched),\n visibility: parseVisibility(record.visibility),\n });\n}\n\nexport const V0_CONFIG: ExportStoreConfig = {\n agentId: AGENT_ID,\n agentType: AGENT_TYPE,\n displayName: \"Vercel v0\",\n directoryName: \".v0\",\n stateEnvVar: \"V0_STATE_DIR\",\n roleNarrative: ROLE_NARRATIVE,\n capabilities: [\"generative-ui\", \"full-stack-web\", \"react-nextjs\"],\n policy: DEFAULT_POLICY,\n label: \"v0\",\n initCommand: \"bourdon v0 init\",\n projectToEntity,\n sessionToRecord,\n};\n\nexport class V0Participant extends ExportStoreParticipant {\n constructor(options: { stateDir?: string; env?: NodeJS.ProcessEnv } = {}) {\n super(V0_CONFIG, options);\n }\n\n static defaultNativePath(home?: string): string {\n return ExportStoreParticipant.defaultNativePath(\".v0\", home);\n }\n}\n","// SPDX-License-Identifier: BUSL-1.1\n/**\n * Participant discovery — a STATIC TS registry replacing Python's `pkgutil`\n * package scan + entry-point duck-type (`participants/__init__.py`).\n *\n * Python scans the `participants/` package at runtime and duck-types each class\n * by `_PARTICIPANT_MARKER_ATTRS`. A filesystem package scan does not survive\n * bundling (`npx bourdon` is a single file), so the JS side declares an explicit\n * {@link FIRST_PARTY} array. The three preserved invariants:\n * - output sorted by `agentId`\n * - first-wins dedupe on `agentId`\n * - log-and-skip a participant that throws on construction (one broken reader\n * must NOT abort discovery / crash the CLI)\n *\n * The marker-attr duck-typing collapses into the {@link BourdonParticipant}\n * interface conformance (checked structurally via {@link isParticipant}).\n */\n\nimport { isParticipant, type BourdonParticipant } from \"./base.js\";\nimport { BoltParticipant } from \"./readers/bolt.js\";\nimport { CascadeParticipant } from \"./readers/cascade.js\";\nimport { ClaudeCodeParticipant } from \"./readers/claude-code.js\";\nimport { ClaudeCodeAutomationsParticipant } from \"./readers/claude-code-automations.js\";\nimport { ClaudeDesktopCodeParticipant } from \"./readers/claude-desktop-code.js\";\nimport { ClaudeDesktopCoworkParticipant } from \"./readers/claude-desktop-cowork.js\";\nimport { CodexAutomationsParticipant } from \"./readers/codex-automations.js\";\nimport { CopilotParticipant } from \"./readers/copilot.js\";\nimport { CopilotAutomationsParticipant } from \"./readers/copilot-automations.js\";\nimport { CopilotCliParticipant } from \"./readers/copilot-cli.js\";\nimport { CopilotVscodeParticipant } from \"./readers/copilot-vscode.js\";\nimport { CursorParticipant } from \"./readers/cursor.js\";\nimport { CursorAutomationsParticipant } from \"./readers/cursor-automations.js\";\nimport { LovableParticipant } from \"./readers/lovable.js\";\nimport { V0Participant } from \"./readers/v0.js\";\nimport { GitHubCopilotParticipant } from \"./readers/github-copilot.js\";\nimport { HermesParticipant } from \"./readers/hermes.js\";\nimport { OpenClawParticipant } from \"./readers/openclaw.js\";\n\n/** A zero-arg-constructible participant class. */\nexport type ParticipantCtor = new () => BourdonParticipant;\n\n/**\n * The first-party reader registry. Order here is irrelevant — discovery sorts by\n * `agentId`. Covers the base agents, their background-run \"automations\" variants,\n * the Claude-desktop surfaces, and the quarantined-class openclaw network reader.\n * codex — the ~2.6k-line turn-compiler reader — is the only one still deferred.\n */\nexport const FIRST_PARTY: ParticipantCtor[] = [\n BoltParticipant as unknown as ParticipantCtor,\n CascadeParticipant as unknown as ParticipantCtor,\n ClaudeCodeParticipant as unknown as ParticipantCtor,\n ClaudeCodeAutomationsParticipant as unknown as ParticipantCtor,\n ClaudeDesktopCodeParticipant as unknown as ParticipantCtor,\n ClaudeDesktopCoworkParticipant as unknown as ParticipantCtor,\n CodexAutomationsParticipant as unknown as ParticipantCtor,\n CopilotParticipant as unknown as ParticipantCtor,\n CopilotAutomationsParticipant as unknown as ParticipantCtor,\n CopilotCliParticipant as unknown as ParticipantCtor,\n CopilotVscodeParticipant as unknown as ParticipantCtor,\n CursorParticipant as unknown as ParticipantCtor,\n CursorAutomationsParticipant as unknown as ParticipantCtor,\n LovableParticipant as unknown as ParticipantCtor,\n V0Participant as unknown as ParticipantCtor,\n GitHubCopilotParticipant as unknown as ParticipantCtor,\n HermesParticipant as unknown as ParticipantCtor,\n OpenClawParticipant as unknown as ParticipantCtor,\n];\n\n/** Minimal logger so a skipped participant is visible without a dep. */\nconst logger = {\n warn(msg: string): void {\n // eslint-disable-next-line no-console\n console.warn(`[bourdon.participants] ${msg}`);\n },\n};\n\n/**\n * Instantiate each registered participant, duck-type the contract, sort by\n * `agentId`, and first-wins dedupe. A class that throws on construction is\n * logged and skipped — never propagated.\n */\nexport function discoverParticipants(\n ctors: ParticipantCtor[] = FIRST_PARTY,\n): BourdonParticipant[] {\n const found = new Map<string, BourdonParticipant>();\n for (const Ctor of [...ctors, ...resolvePluginParticipants()]) {\n let instance: BourdonParticipant;\n try {\n instance = new Ctor();\n } catch (err) {\n logger.warn(\n `Skipping participant ${Ctor.name || \"<anonymous>\"}: construction failed: ${String(err)}`,\n );\n continue;\n }\n if (!isParticipant(instance)) continue;\n if (!found.has(instance.agentId)) found.set(instance.agentId, instance);\n }\n return [...found.values()].sort((a, b) =>\n a.agentId < b.agentId ? -1 : a.agentId > b.agentId ? 1 : 0,\n );\n}\n\n/**\n * Optional Layer 2: third-party plugins declared via a `package.json`\n * `\"bourdon\": { participants: { ... } }` field. Gated behind `BOURDON_PLUGINS=1`\n * and a no-op today (no external participant exists yet) — the resolver ships so\n * the seam is wired, defaulted off so `npx bourdon` stays predictable.\n */\nexport function resolvePluginParticipants(): ParticipantCtor[] {\n if (process.env.BOURDON_PLUGINS !== \"1\") return [];\n // No external participant package exists yet; the resolver is intentionally a\n // no-op stub. When one ships, resolve its declared ctors here.\n return [];\n}\n"],"mappings":"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","names":["isoDate","import_node_fs","import_node_fs","import_node_os","import_node_path","text","stem","record","keyActions","capabilities","import_node_fs","import_node_os","import_node_path","import_yaml","import_l5","import_redaction","import_node_fs","import_node_os","import_node_path","import_l5","import_redaction","import_node_fs","import_node_path","import_l5","import_redaction","text","yamlParse","record","import_node_crypto","import_node_fs","import_node_os","import_node_path","warn","text","relative","isDict","STRICT_UTF8","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","isDir","isFile","text","yamlParse","sessionDate","record","capabilities","projectEntities","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","DEFAULT_POLICY","import_node_fs","import_node_os","import_node_path","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","homeDir","isDir","isFile","text","projectName","homeBase","import_node_fs","import_node_os","import_node_path","import_yaml","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","FRONTMATTER_OPEN","FRONTMATTER_CLOSE","DEFAULT_POLICY","homeDir","isDir","isFile","isRecord","parseFrontmatter","text","FRONTMATTER_OPEN","FRONTMATTER_CLOSE","yamlParse","buildSession","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","isDir","isFile","buildSession","DEFAULT_POLICY","ROLE_NARRATIVE","import_node_fs","import_node_os","import_node_path","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","DEFAULT_POLICY","MAX_SUMMARY_CHARS","isFile","isDir","bounded","keyActions","import_node_fs","import_node_os","import_node_path","import_yaml","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","CONVENTION_DIR_NAME","MEMORY_FILENAME","DEFAULT_POLICY","logger","homeDir","isDir","isFile","parseFrontmatter","text","yamlParse","logger","isRecord","buildEntity","buildSession","MEMORY_FILENAME","isFile","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","CONVENTION_DIR_NAME","DEFAULT_POLICY","MEMORY_FILENAME","isFile","text","parseFrontmatter","isDir","buildEntity","ROLE_NARRATIVE","import_node_child_process","import_node_os","import_node_path","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","isRecord","safeNativeMemoryText","text","nowIsoSeconds","curlGet","import_node_fs","import_node_os","import_node_path","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","MAX_KEY_ACTION_CHARS","logger","homeDir","isDir","isFile","stripChars","homeDir","parseToml","logger","basenameOf","isFile","isDir","text","bounded","safeNativeMemoryText","MAX_KEY_ACTION_CHARS","keyActions","AGENT_ID","AGENT_TYPE","DEFAULT_POLICY","isDir","ROLE_NARRATIVE","import_node_fs","import_node_os","import_node_path","import_smol_toml","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","AUTOMATIONS_DIR_NAME","AUTOMATION_TOML","MEMORY_MD","MAX_MEMORY_CHARS","MAX_KEY_ACTIONS_PER_RUN","MAX_KEY_ACTION_CHARS","RUN_HEADER_RE","DEFAULT_PROJECT_HINTS","SIGNAL_PATTERNS","logger","homeDir","isDir","isFile","safeNativeMemoryText","readAutomationToml","text","tomlParse","buildConfig","iterConfigs","readMemoryText","splitLines","rstrip","bounded","actionsFromLines","titleFromActions","inferProjects","inferSignals","extractMemoryRuns","stripChars","sessionFromRun","keyActions","entitiesFromConfigsAndRuns","import_node_fs","import_node_os","import_node_path","import_smol_toml","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","DEFAULT_POLICY","CONVENTION_DIR_NAME","AUTOMATION_TOML","MEMORY_MD","MAX_MEMORY_CHARS","MAX_KEY_ACTIONS_PER_RUN","MAX_KEY_ACTION_CHARS","RUN_HEADER_RE","logger","homeDir","isDir","isFile","isRecord","pyStr","CONVENTION_DIR_NAME","readAutomationToml","text","parseToml","buildConfig","MEMORY_MD","iterConfigs","AUTOMATION_TOML","splitLines","rstrip","stripChars","extractMemoryRuns","MAX_MEMORY_CHARS","RUN_HEADER_RE","actionsFromLines","titleFromActions","bounded","safeNativeMemoryText","MAX_KEY_ACTION_CHARS","MAX_KEY_ACTIONS_PER_RUN","sessionFromRun","keyActions","entitiesFromConfigsAndRuns","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","DEFAULT_POLICY","ROLE_NARRATIVE","import_node_fs","import_node_os","import_node_path","import_smol_toml","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","AUTOMATIONS_DIR_NAME","AUTOMATION_TOML","MEMORY_MD","MAX_MEMORY_CHARS","MAX_KEY_ACTIONS_PER_RUN","MAX_KEY_ACTION_CHARS","RUN_HEADER_RE","HEADER_SUFFIX_STRIP","DEFAULT_PROJECT_HINTS","SIGNAL_PATTERNS","logger","homeDir","isDir","isFile","strOr","stripChars","rstrip","bounded","safeNativeMemoryText","AUTOMATIONS_DIR_NAME","readAutomationToml","text","parseToml","buildConfig","basenameOf","MEMORY_MD","iterConfigs","AUTOMATION_TOML","readMemoryText","MAX_MEMORY_CHARS","extractMemoryRuns","RUN_HEADER_RE","HEADER_SUFFIX_STRIP","actionsFromLines","titleFromActions","inferProjects","inferSignals","MAX_KEY_ACTION_CHARS","MAX_KEY_ACTIONS_PER_RUN","DEFAULT_PROJECT_HINTS","SIGNAL_PATTERNS","sessionFromRun","keyActions","MAX_KEY_ACTIONS_PER_RUN","entitiesFromConfigsAndRuns","bounded","nowIsoSeconds","AGENT_ID","AGENT_TYPE","DEFAULT_POLICY","isDir","iterConfigs","ROLE_NARRATIVE","extractMemoryRuns","import_node_fs","import_node_os","import_node_path","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","MAX_KEY_ACTION_CHARS","MAX_KEY_ACTIONS","DEFAULT_PROJECT_HINTS","DEFAULT_POLICY","isDir","bounded","text","inferProjects","stem","parsePath","import_node_fs","import_node_os","import_node_path","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","SURFACE_ENTITY_NAME","ROLE_NARRATIVE","DEFAULT_POLICY","DESKTOP_DIR_ENV","STATE_PREFIX","MAX_PROJECTS","MAX_KEY_ACTIONS","DEFAULT_PROJECT_HINTS","logger","isDir","isFile","homeDir","isRecord","defaultClaudeDesktopDir","iterStateFiles","loadStateJson","epochToDate","sessionDate","bounded","safeLabel","text","countEnabledMcpTools","basenameOf","inferProjects","parsePath","record","stem","keyActions","sessionFromRun","capabilities","import_node_fs","import_node_os","import_node_path","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","DEFAULT_POLICY","MAX_KEY_ACTIONS","MAX_KEY_ACTION_CHARS","MAX_SUMMARY_CHARS","homeDir","isDir","safeNativeMemoryText","bounded","splitLines","text","logger","keyActions","import_node_fs","import_node_os","import_node_path","isDir","text","record","import_node_crypto","import_node_fs","import_node_path","import_federation","import_yaml","isDict","daysInMonth","today","text","yamlParse","UTF8","yamlStringify","isFile","isDirectory","nowIso","import_node_crypto","import_node_fs","import_node_path","import_federation","import_yaml","nowIso","isDict","pyStr","truthy","isDirectory","isFile","text","yamlStringify","UTF8","record","yamlParse","PY_WHITESPACE_RUN","collapseWhitespace","import_l5","import_redaction","import_node_fs","import_node_os","import_node_path","import_l5","import_redaction","isoDate","text","parsed","isDir","isFile","isDict","record","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","MAX_SUMMARY_CHARS","MAX_KEY_ACTION_CHARS","NAME_LIMIT","record","isoDate","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","MAX_SUMMARY_CHARS","MAX_KEY_ACTION_CHARS","NAME_LIMIT","projectToEntity","record","isoDate","sessionToRecord","import_l5","import_redaction","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","MAX_SUMMARY_CHARS","MAX_KEY_ACTION_CHARS","NAME_LIMIT","projectToEntity","record","isoDate","sessionToRecord","logger","import_l5"]}