@getbourdon/participants 0.3.1 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/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/registry.ts","../src/index.ts"],"sourcesContent":["/**\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","/**\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;\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 better-sqlite3 native addon loaded successfully. Tests gate\n * the SQLite-reader assertions on this so a missing addon skips, not fails. */\nexport function sqliteAvailable(): boolean {\n return loadDriver() !== null;\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.toISOString().replace(/\\.\\d{3}Z$/, \"+00:00\").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","/**\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","/**\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","/**\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 * For back-compat the pre-rename env var (`CLAUDE_BRAIN`) and the pre-rename\n * directory name are still accepted — see BRAIN_DIR_NAMES / BRAIN_ENV_VARS.\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/**\n * Directory names for the knowledge repo, most-preferred first. The second\n * entry is a LEGACY ALIAS kept only so existing checkouts keep resolving after\n * the rename to a product-neutral default; new installs should use the first.\n * The alias is assembled at runtime so no build artifact (bundle or sourcemap)\n * carries it as a contiguous literal — the packed-tarball gate must stay clean\n * without artifact-path exemptions.\n */\nexport const BRAIN_DIR_NAMES: readonly [string, string] = [\n \"agent-brain\",\n [\"c\", \"laude-brain\"].join(\"\"),\n];\n\n/**\n * Env overrides, most-preferred first. `CLAUDE_BRAIN` is retained for\n * back-compat with installs that set it before the rename.\n */\nexport const BRAIN_ENV_VARS = [\"AGENT_BRAIN\", \"CLAUDE_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>`. Within\n * each tier the product-neutral name is preferred and the legacy name is\n * accepted, so an operator who has not renamed their checkout keeps working\n * with no action.\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 claude_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 claude_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","/**\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","/**\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","/**\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","/**\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","/**\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","/**\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","/**\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","/**\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","/**\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","/**\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","/**\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","/**\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","/**\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","/**\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","/**\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 { 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 { 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 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 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","/**\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"],"mappings":"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","names":["readFileSync","statSync","homedir","join","join","homedir","statSync","readFileSync","stem","keyActions","capabilities","readFileSync","statSync","homedir","join","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","isDir","statSync","isFile","join","homedir","readFileSync","makeEntity","sessionDate","makeSession","capabilities","projectEntities","filterForFederation","makeManifest","makeAgentInfo","Visibility","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","redactText","makeSession","makeEntity","makeManifest","makeAgentInfo","readFileSync","readdirSync","statSync","homedir","basename","join","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","homeDir","homedir","isDir","statSync","isFile","redactText","join","readdirSync","basename","readFileSync","homeBase","makeEntity","makeSession","filterForFederation","makeManifest","makeAgentInfo","mkdirSync","readFileSync","statSync","writeFileSync","homedir","hostname","join","yamlParse","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","FRONTMATTER_OPEN","FRONTMATTER_CLOSE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","homeDir","homedir","isDir","statSync","isFile","join","isRecord","parseFrontmatter","FRONTMATTER_OPEN","FRONTMATTER_CLOSE","yamlParse","readFileSync","redactText","makeEntity","buildSession","makeSession","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","join","isDir","isFile","buildSession","filterForFederation","DEFAULT_POLICY","makeManifest","makeAgentInfo","hostname","ROLE_NARRATIVE","statSync","homedir","hostname","join","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","MAX_SUMMARY_CHARS","join","homedir","isFile","statSync","isDir","redactText","bounded","keyActions","makeSession","makeEntity","filterForFederation","makeManifest","makeAgentInfo","hostname","mkdirSync","readFileSync","statSync","writeFileSync","homedir","join","yamlParse","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","CONVENTION_DIR_NAME","MEMORY_FILENAME","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","logger","homeDir","homedir","isDir","statSync","isFile","join","parseFrontmatter","yamlParse","logger","redactText","isRecord","buildEntity","makeEntity","buildSession","makeSession","join","MEMORY_FILENAME","isFile","readFileSync","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","join","CONVENTION_DIR_NAME","DEFAULT_POLICY","MEMORY_FILENAME","isFile","readFileSync","parseFrontmatter","isDir","buildEntity","filterForFederation","makeManifest","makeAgentInfo","ROLE_NARRATIVE","execFileSync","homedir","join","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","isRecord","safeNativeMemoryText","redactText","nowIsoSeconds","curlGet","execFileSync","join","homedir","makeSession","makeEntity","makeVisibilityPolicy","Visibility","makeManifest","makeAgentInfo","filterForFederation","mkdirSync","readdirSync","readFileSync","statSync","writeFileSync","homedir","hostname","dirname","join","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","MAX_KEY_ACTION_CHARS","logger","homeDir","homedir","isDir","statSync","isFile","stripChars","join","homeDir","readFileSync","logger","dirname","basenameOf","isFile","isDir","readdirSync","bounded","safeNativeMemoryText","MAX_KEY_ACTION_CHARS","redactText","keyActions","makeSession","Visibility","makeEntity","AGENT_ID","AGENT_TYPE","DEFAULT_POLICY","isDir","filterForFederation","makeManifest","makeAgentInfo","hostname","ROLE_NARRATIVE","readFileSync","readdirSync","statSync","homedir","hostname","basename","dirname","join","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","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","homedir","isDir","statSync","isFile","join","safeNativeMemoryText","redactText","readAutomationToml","readFileSync","buildConfig","basename","dirname","iterConfigs","readdirSync","readMemoryText","splitLines","rstrip","bounded","actionsFromLines","titleFromActions","inferProjects","inferSignals","extractMemoryRuns","stripChars","sessionFromRun","keyActions","makeSession","entitiesFromConfigsAndRuns","makeEntity","filterForFederation","makeManifest","makeAgentInfo","hostname","mkdirSync","readFileSync","readdirSync","statSync","writeFileSync","homedir","hostname","dirname","join","parseToml","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","CONVENTION_DIR_NAME","AUTOMATION_TOML","MEMORY_MD","MAX_MEMORY_CHARS","MAX_KEY_ACTIONS_PER_RUN","MAX_KEY_ACTION_CHARS","RUN_HEADER_RE","logger","homeDir","homedir","isDir","statSync","isFile","isRecord","pyStr","join","CONVENTION_DIR_NAME","readAutomationToml","readFileSync","parseToml","buildConfig","dirname","MEMORY_MD","iterConfigs","readdirSync","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","redactText","sessionFromRun","keyActions","makeSession","Visibility","entitiesFromConfigsAndRuns","makeEntity","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","DEFAULT_POLICY","filterForFederation","makeManifest","makeAgentInfo","hostname","ROLE_NARRATIVE","mkdirSync","readdirSync","readFileSync","statSync","writeFileSync","homedir","hostname","dirname","join","parseToml","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","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","homedir","isDir","statSync","isFile","strOr","stripChars","rstrip","bounded","safeNativeMemoryText","redactText","join","AUTOMATIONS_DIR_NAME","readAutomationToml","readFileSync","parseToml","buildConfig","basenameOf","dirname","MEMORY_MD","iterConfigs","readdirSync","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","makeSession","dirname","MAX_KEY_ACTIONS_PER_RUN","Visibility","entitiesFromConfigsAndRuns","makeEntity","bounded","nowIsoSeconds","AGENT_ID","AGENT_TYPE","DEFAULT_POLICY","isDir","iterConfigs","filterForFederation","makeManifest","makeAgentInfo","hostname","ROLE_NARRATIVE","extractMemoryRuns","readdirSync","readFileSync","statSync","homedir","hostname","basename","join","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","MAX_KEY_ACTION_CHARS","MAX_KEY_ACTIONS","DEFAULT_PROJECT_HINTS","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","isDir","statSync","homedir","join","readdirSync","readFileSync","bounded","redactText","basename","inferProjects","stem","makeSession","makeEntity","filterForFederation","makeManifest","makeAgentInfo","hostname","readFileSync","readdirSync","statSync","hostname","basename","dirname","join","parsePath","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","SURFACE_ENTITY_NAME","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","DESKTOP_DIR_ENV","STATE_PREFIX","MAX_PROJECTS","MAX_KEY_ACTIONS","DEFAULT_PROJECT_HINTS","logger","isDir","statSync","isFile","homeDir","isRecord","defaultClaudeDesktopDir","join","iterStateFiles","readdirSync","loadStateJson","readFileSync","epochToDate","sessionDate","bounded","redactText","safeLabel","countEnabledMcpTools","basenameOf","basename","inferProjects","dirname","parsePath","stem","keyActions","sessionFromRun","makeSession","capabilities","makeEntity","filterForFederation","makeManifest","makeAgentInfo","hostname","readdirSync","readFileSync","statSync","homedir","hostname","join","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","MAX_KEY_ACTIONS","MAX_KEY_ACTION_CHARS","MAX_SUMMARY_CHARS","homeDir","homedir","isDir","statSync","safeNativeMemoryText","redactText","bounded","splitLines","join","readdirSync","logger","readFileSync","keyActions","makeSession","makeEntity","filterForFederation","makeManifest","makeAgentInfo","hostname","readFileSync","statSync","homedir","join","isDir","logger","Visibility","filterForFederation"]}
1
+ {"version":3,"sources":["../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","../src/index.ts"],"sourcesContent":["// 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;\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 better-sqlite3 native addon loaded successfully. Tests gate\n * the SQLite-reader assertions on this so a missing addon skips, not fails. */\nexport function sqliteAvailable(): boolean {\n return loadDriver() !== null;\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.toISOString().replace(/\\.\\d{3}Z$/, \"+00:00\").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 * For back-compat the pre-rename env var (`CLAUDE_BRAIN`) and the pre-rename\n * directory name are still accepted — see BRAIN_DIR_NAMES / BRAIN_ENV_VARS.\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/**\n * Directory names for the knowledge repo, most-preferred first. The second\n * entry is a LEGACY ALIAS kept only so existing checkouts keep resolving after\n * the rename to a product-neutral default; new installs should use the first.\n * The alias is assembled at runtime so no build artifact (bundle or sourcemap)\n * carries it as a contiguous literal — the packed-tarball gate must stay clean\n * without artifact-path exemptions.\n */\nexport const BRAIN_DIR_NAMES: readonly [string, string] = [\n \"agent-brain\",\n [\"c\", \"laude-brain\"].join(\"\"),\n];\n\n/**\n * Env overrides, most-preferred first. `CLAUDE_BRAIN` is retained for\n * back-compat with installs that set it before the rename.\n */\nexport const BRAIN_ENV_VARS = [\"AGENT_BRAIN\", \"CLAUDE_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>`. Within\n * each tier the product-neutral name is preferred and the legacy name is\n * accepted, so an operator who has not renamed their checkout keeps working\n * with no action.\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 claude_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 claude_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","// 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"],"mappings":"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","names":["readFileSync","statSync","homedir","join","join","homedir","statSync","readFileSync","stem","keyActions","capabilities","readFileSync","statSync","homedir","join","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","isDir","statSync","isFile","join","homedir","readFileSync","makeEntity","sessionDate","makeSession","capabilities","projectEntities","filterForFederation","makeManifest","makeAgentInfo","Visibility","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","redactText","makeSession","makeEntity","makeManifest","makeAgentInfo","readFileSync","readdirSync","statSync","homedir","basename","join","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","homeDir","homedir","isDir","statSync","isFile","redactText","join","readdirSync","basename","readFileSync","homeBase","makeEntity","makeSession","filterForFederation","makeManifest","makeAgentInfo","mkdirSync","readFileSync","statSync","writeFileSync","homedir","hostname","join","yamlParse","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","FRONTMATTER_OPEN","FRONTMATTER_CLOSE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","homeDir","homedir","isDir","statSync","isFile","join","isRecord","parseFrontmatter","FRONTMATTER_OPEN","FRONTMATTER_CLOSE","yamlParse","readFileSync","redactText","makeEntity","buildSession","makeSession","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","join","isDir","isFile","buildSession","filterForFederation","DEFAULT_POLICY","makeManifest","makeAgentInfo","hostname","ROLE_NARRATIVE","statSync","homedir","hostname","join","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","MAX_SUMMARY_CHARS","join","homedir","isFile","statSync","isDir","redactText","bounded","keyActions","makeSession","makeEntity","filterForFederation","makeManifest","makeAgentInfo","hostname","mkdirSync","readFileSync","statSync","writeFileSync","homedir","join","yamlParse","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","CONVENTION_DIR_NAME","MEMORY_FILENAME","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","logger","homeDir","homedir","isDir","statSync","isFile","join","parseFrontmatter","yamlParse","logger","redactText","isRecord","buildEntity","makeEntity","buildSession","makeSession","join","MEMORY_FILENAME","isFile","readFileSync","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","join","CONVENTION_DIR_NAME","DEFAULT_POLICY","MEMORY_FILENAME","isFile","readFileSync","parseFrontmatter","isDir","buildEntity","filterForFederation","makeManifest","makeAgentInfo","ROLE_NARRATIVE","execFileSync","homedir","join","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","isRecord","safeNativeMemoryText","redactText","nowIsoSeconds","curlGet","execFileSync","join","homedir","makeSession","makeEntity","makeVisibilityPolicy","Visibility","makeManifest","makeAgentInfo","filterForFederation","mkdirSync","readdirSync","readFileSync","statSync","writeFileSync","homedir","hostname","dirname","join","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","MAX_KEY_ACTION_CHARS","logger","homeDir","homedir","isDir","statSync","isFile","stripChars","join","homeDir","readFileSync","logger","dirname","basenameOf","isFile","isDir","readdirSync","bounded","safeNativeMemoryText","MAX_KEY_ACTION_CHARS","redactText","keyActions","makeSession","Visibility","makeEntity","AGENT_ID","AGENT_TYPE","DEFAULT_POLICY","isDir","filterForFederation","makeManifest","makeAgentInfo","hostname","ROLE_NARRATIVE","readFileSync","readdirSync","statSync","homedir","hostname","basename","dirname","join","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","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","homedir","isDir","statSync","isFile","join","safeNativeMemoryText","redactText","readAutomationToml","readFileSync","buildConfig","basename","dirname","iterConfigs","readdirSync","readMemoryText","splitLines","rstrip","bounded","actionsFromLines","titleFromActions","inferProjects","inferSignals","extractMemoryRuns","stripChars","sessionFromRun","keyActions","makeSession","entitiesFromConfigsAndRuns","makeEntity","filterForFederation","makeManifest","makeAgentInfo","hostname","mkdirSync","readFileSync","readdirSync","statSync","writeFileSync","homedir","hostname","dirname","join","parseToml","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","CONVENTION_DIR_NAME","AUTOMATION_TOML","MEMORY_MD","MAX_MEMORY_CHARS","MAX_KEY_ACTIONS_PER_RUN","MAX_KEY_ACTION_CHARS","RUN_HEADER_RE","logger","homeDir","homedir","isDir","statSync","isFile","isRecord","pyStr","join","CONVENTION_DIR_NAME","readAutomationToml","readFileSync","parseToml","buildConfig","dirname","MEMORY_MD","iterConfigs","readdirSync","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","redactText","sessionFromRun","keyActions","makeSession","Visibility","entitiesFromConfigsAndRuns","makeEntity","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","DEFAULT_POLICY","filterForFederation","makeManifest","makeAgentInfo","hostname","ROLE_NARRATIVE","mkdirSync","readdirSync","readFileSync","statSync","writeFileSync","homedir","hostname","dirname","join","parseToml","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","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","homedir","isDir","statSync","isFile","strOr","stripChars","rstrip","bounded","safeNativeMemoryText","redactText","join","AUTOMATIONS_DIR_NAME","readAutomationToml","readFileSync","parseToml","buildConfig","basenameOf","dirname","MEMORY_MD","iterConfigs","readdirSync","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","makeSession","dirname","MAX_KEY_ACTIONS_PER_RUN","Visibility","entitiesFromConfigsAndRuns","makeEntity","bounded","nowIsoSeconds","AGENT_ID","AGENT_TYPE","DEFAULT_POLICY","isDir","iterConfigs","filterForFederation","makeManifest","makeAgentInfo","hostname","ROLE_NARRATIVE","extractMemoryRuns","readdirSync","readFileSync","statSync","homedir","hostname","basename","join","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","MAX_KEY_ACTION_CHARS","MAX_KEY_ACTIONS","DEFAULT_PROJECT_HINTS","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","isDir","statSync","homedir","join","readdirSync","readFileSync","bounded","redactText","basename","inferProjects","stem","makeSession","makeEntity","filterForFederation","makeManifest","makeAgentInfo","hostname","readFileSync","readdirSync","statSync","hostname","basename","dirname","join","parsePath","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","SURFACE_ENTITY_NAME","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","DESKTOP_DIR_ENV","STATE_PREFIX","MAX_PROJECTS","MAX_KEY_ACTIONS","DEFAULT_PROJECT_HINTS","logger","isDir","statSync","isFile","homeDir","isRecord","defaultClaudeDesktopDir","join","iterStateFiles","readdirSync","loadStateJson","readFileSync","epochToDate","sessionDate","bounded","redactText","safeLabel","countEnabledMcpTools","basenameOf","basename","inferProjects","dirname","parsePath","stem","keyActions","sessionFromRun","makeSession","capabilities","makeEntity","filterForFederation","makeManifest","makeAgentInfo","hostname","readdirSync","readFileSync","statSync","homedir","hostname","join","Visibility","filterForFederation","makeAgentInfo","makeEntity","makeManifest","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","DISPLAY_NAME","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","MAX_KEY_ACTIONS","MAX_KEY_ACTION_CHARS","MAX_SUMMARY_CHARS","homeDir","homedir","isDir","statSync","safeNativeMemoryText","redactText","bounded","splitLines","join","readdirSync","logger","readFileSync","keyActions","makeSession","makeEntity","filterForFederation","makeManifest","makeAgentInfo","hostname","readFileSync","statSync","homedir","join","isDir","Visibility","makeEntity","makeSession","makeVisibilityPolicy","redactText","readdirSync","readFileSync","statSync","homedir","join","Visibility","filterForFederation","makeAgentInfo","makeManifest","redactText","Visibility","isoDate","parsed","redactText","join","homedir","isDir","isFile","readFileSync","readdirSync","filterForFederation","makeManifest","makeAgentInfo","statSync","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","MAX_SUMMARY_CHARS","MAX_KEY_ACTION_CHARS","isoDate","makeEntity","makeSession","redactText","Visibility","makeEntity","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","MAX_SUMMARY_CHARS","MAX_KEY_ACTION_CHARS","NAME_LIMIT","projectToEntity","redactText","isoDate","makeEntity","sessionToRecord","makeSession","Visibility","makeEntity","makeSession","makeVisibilityPolicy","redactText","AGENT_ID","AGENT_TYPE","ROLE_NARRATIVE","DEFAULT_POLICY","makeVisibilityPolicy","Visibility","MAX_SUMMARY_CHARS","MAX_KEY_ACTION_CHARS","NAME_LIMIT","projectToEntity","isoDate","makeEntity","sessionToRecord","makeSession","redactText","logger","Visibility","filterForFederation"]}