@getbourdon/participants 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { L5ManifestModel, SessionModel } from '@getbourdon/l5';
1
+ import { L5ManifestModel, SessionModel, VisibilityPolicyModel } from '@getbourdon/l5';
2
2
  export { EntityModel, L5ManifestModel, SessionModel, Visibility, VisibilityPolicyModel, applyVisibility, filterForFederation, toDict, validateManifest } from '@getbourdon/l5';
3
3
  import DatabaseT from 'better-sqlite3';
4
4
 
@@ -67,6 +67,13 @@ interface BourdonParticipant {
67
67
  nativePath: string;
68
68
  /** Human-friendly label (e.g. "GitHub Copilot"). Optional. */
69
69
  displayName?: string;
70
+ /** Quarantined-class marker (Python `QUARANTINED_CLASS`). When true, the CLI
71
+ * requires `--i-understand-the-risk` to register the agent trusted, and its
72
+ * exports are staged for operator review rather than written to the live
73
+ * store (spec D6: quarantine follows the content, not the invoker). Absent =
74
+ * a normal, non-quarantined participant. Read by `bourdon agent add/set-tier`
75
+ * (cli/src/commands/federation.ts). */
76
+ quarantinedClass?: boolean;
70
77
  /** Confirm the native store exists; return metadata. Throws
71
78
  * {@link ParticipantDiscoveryError} when missing/unreadable. */
72
79
  discover(): AgentStore;
@@ -356,6 +363,248 @@ declare class GitHubCopilotParticipant extends NetworkParticipant {
356
363
  payloadToL5(payload: Record<string, unknown>): L5ManifestModel;
357
364
  }
358
365
 
366
+ /**
367
+ * Cursor participant — reads Cursor's (the AI-first IDE) SQLite-backed
368
+ * workspace/composer state and normalizes it into L5. Port of
369
+ * `participants/cursor.py` + the extraction helper `participants/_cursor_sqlite.py`.
370
+ *
371
+ * Cursor stores workspace state in `state.vscdb` SQLite DBs at platform-specific
372
+ * paths (`~/.config/Cursor/`, `~/Library/Application Support/Cursor/`,
373
+ * `%APPDATA%/Cursor/`). This reader discovers those stores, reads the `ItemTable`
374
+ * key/value rows read-only, parses the composer/chat records into sessions +
375
+ * project/topic entities, and merges curated `.cursor/memory/short-index.json`
376
+ * entities alongside them.
377
+ *
378
+ * SQLite access: the Python oracle copies each DB (+ its `-wal`/`-shm`
379
+ * companions) to a tmp file and opens it read-write so SQLite folds the WAL into
380
+ * a consistent snapshot. The TS mirror instead leans on {@link tryOpenReadonly}
381
+ * (`mode=ro`), which respects SQLite locking and reads the `-wal` sidecar of a
382
+ * live writer — the same consistent view without the copy. Read-only,
383
+ * deterministic, visibility-enforced-before-emission, redaction on every native
384
+ * string; `healthCheck` never throws.
385
+ */
386
+
387
+ /** External participant for Cursor's SQLite workspace state. */
388
+ declare class CursorParticipant implements BourdonParticipant {
389
+ agentId: string;
390
+ agentType: string;
391
+ private readonly cursorDir;
392
+ private readonly workspaceRoot;
393
+ private readonly policy;
394
+ /**
395
+ * Conventional Cursor config dir (`~/.cursor`) used by the setup wizard. The
396
+ * wizard probes `~/.cursor` for presence; the SQLite workspace state that
397
+ * `exportL5` actually reads lives at {@link defaultCursorDir}. Detection and
398
+ * extraction intentionally use different anchors.
399
+ */
400
+ static defaultNativePath(home?: string): string;
401
+ constructor(cursorDir?: string | null, workspaceRoot?: string | null);
402
+ get nativePath(): string;
403
+ discover(): AgentStore;
404
+ exportSessions(since?: Date, limit?: number): SessionModel[];
405
+ exportL5(since?: Date): L5ManifestModel;
406
+ healthCheck(): HealthStatus;
407
+ private extract;
408
+ }
409
+
410
+ /**
411
+ * GitHub Copilot (local convention) participant — reads the convention-based
412
+ * memory file at `~/.copilot-bourdon/memory.md`. Port of `participants/copilot.py`.
413
+ *
414
+ * Copilot has no accessible local session index (its reasoning is cloud-side and
415
+ * its native memory is not exposed on disk), so — like the Codex pre-distillation
416
+ * fallback — this reader normalizes a user-maintained convention file into a
417
+ * Bourdon L5 manifest. The file is YAML front-matter (structured `entities:` /
418
+ * `sessions:`) followed by an optional freeform markdown body that Copilot Chat
419
+ * reads as plain context but this reader ignores.
420
+ *
421
+ * NOT the cloud GitHub-Copilot network adapter ({@link GitHubCopilotParticipant})
422
+ * and NOT the Copilot CLI SQLite reader.
423
+ *
424
+ * Paths checked (in order):
425
+ * 1. `COPILOT_BOURDON_HOME` env-var override
426
+ * 2. `~/.copilot-bourdon/` (default convention path)
427
+ *
428
+ * Defensive throughout: a missing convention directory raises
429
+ * {@link ParticipantDiscoveryError} from `discover()`; malformed YAML degrades to
430
+ * an empty manifest rather than raising; `healthCheck` never throws.
431
+ */
432
+
433
+ /**
434
+ * External participant for GitHub Copilot via `~/.copilot-bourdon/memory.md`.
435
+ * Implements {@link BourdonParticipant} structurally.
436
+ */
437
+ declare class CopilotParticipant implements BourdonParticipant {
438
+ agentId: string;
439
+ agentType: string;
440
+ displayName: string;
441
+ nativePath: string;
442
+ /** Conventional `~/.copilot-bourdon` dir used by the setup wizard's detection. */
443
+ static defaultNativePath(home?: string): string;
444
+ private readonly copilotDir;
445
+ constructor(copilotDir?: string | null);
446
+ discover(): AgentStore;
447
+ exportSessions(since?: Date, limit?: number): SessionModel[];
448
+ exportL5(since?: Date): L5ManifestModel;
449
+ healthCheck(): HealthStatus;
450
+ private read;
451
+ }
452
+
453
+ /**
454
+ * GitHub Copilot CLI participant — normalize the `copilot` terminal agent's
455
+ * SQLite session store into L5. Port of `participants/copilot_cli.py`.
456
+ *
457
+ * Copilot CLI stores session history in a SQLite database at
458
+ * `~/.copilot/session-store.db` (override `$COPILOT_CLI_HOME`). This is distinct
459
+ * from:
460
+ * - the VS Code Copilot Chat extension (`github-copilot` network reader)
461
+ * - the `~/.copilot-bourdon/memory.md` convention-file participant (`copilot`)
462
+ * - GitHub-embedded Copilot (no local state)
463
+ *
464
+ * The schema (schema_version 4) carries `sessions` / `turns` / `checkpoints`
465
+ * plus `session_files` / `session_refs` / `dynamic_context_items`. The reader
466
+ * opens the DB read-only (`mode=ro` via {@link tryOpenReadonly}) so a live
467
+ * writer's lock can never block the export, probes each table defensively (a
468
+ * missing table degrades to "no rows" rather than raising), redacts every native
469
+ * string, applies the visibility filter BEFORE emission, and is deterministic.
470
+ * `healthCheck` never throws.
471
+ */
472
+
473
+ /**
474
+ * External participant for GitHub Copilot CLI (`~/.copilot/session-store.db`).
475
+ * Reads the SQLite database read-only (never locks the live db).
476
+ */
477
+ declare class CopilotCliParticipant implements BourdonParticipant {
478
+ agentId: string;
479
+ agentType: string;
480
+ displayName: string;
481
+ nativePath: string;
482
+ private readonly copilotDir;
483
+ /** Conventional `~/.copilot` dir used by the setup wizard's detection. */
484
+ static defaultNativePath(home?: string): string;
485
+ constructor(copilotDir?: string);
486
+ discover(): AgentStore;
487
+ exportSessions(since?: Date, limit?: number): SessionModel[];
488
+ exportL5(since?: Date): L5ManifestModel;
489
+ healthCheck(): HealthStatus;
490
+ private emptyManifest;
491
+ }
492
+
493
+ /**
494
+ * Cascade (Windsurf) participant — convention-file reader. Port of
495
+ * `participants/cascade.py`.
496
+ *
497
+ * Cascade's internal state is not exposed on the filesystem in a standardized
498
+ * format (like cloud Copilot). Instead this participant uses a CONVENTION FILE:
499
+ * Cascade maintains a structured memory file at `~/.cascade-bourdon/memory.md`
500
+ * with YAML front-matter carrying `entities` + `sessions`. Cascade owns that
501
+ * projection explicitly (it writes what it knows at session end); the
502
+ * participant normalizes the front-matter into an L5 manifest for federation.
503
+ *
504
+ * Privacy: entity/session summaries pass through the redaction SSOT; the
505
+ * visibility policy (private_tags) filters PRIVATE entities before emission.
506
+ */
507
+
508
+ /**
509
+ * Convention-based Bourdon participant for Cascade (Windsurf). Reads structured
510
+ * memory from `~/.cascade-bourdon/memory.md` and normalizes it into L5.
511
+ */
512
+ declare class CascadeParticipant implements BourdonParticipant {
513
+ agentId: string;
514
+ agentType: string;
515
+ displayName: string;
516
+ private readonly dir;
517
+ private readonly policy;
518
+ static defaultNativePath(home?: string): string;
519
+ constructor(cascadeDir?: string, policy?: VisibilityPolicyModel);
520
+ /** Path to the Cascade-Bourdon convention directory. */
521
+ get nativePath(): string;
522
+ private memoryPath;
523
+ private readFrontmatter;
524
+ discover(): AgentStore;
525
+ exportL5(since?: Date): L5ManifestModel;
526
+ exportSessions(since?: Date, limit?: number): SessionModel[];
527
+ healthCheck(): HealthStatus;
528
+ }
529
+
530
+ /**
531
+ * OpenClaw participant — network-shaped, QUARANTINED-CLASS. Port of
532
+ * `participants/openclaw.py` (v0.9.0, spec R4/D9).
533
+ *
534
+ * OpenClaw is the highest-demand adapter target in the ecosystem and also its
535
+ * highest-risk agent class: CVE-2026-25253 (one-click RCE, CVSS 8.8, first
536
+ * patched in 2026.1.29), tens of thousands of internet-exposed instances (~93%
537
+ * without authentication), ClawHub's malicious-skill problem, and auth disabled
538
+ * by default on port 8080. Bourdon therefore treats OpenClaw differently from
539
+ * every on-disk participant:
540
+ *
541
+ * 1. **Network-shaped** — state is read from the OpenClaw instance's local
542
+ * HTTP API, not on-disk artifacts. Because the {@link BourdonParticipant}
543
+ * contract is SYNCHRONOUS (`discover`/`exportL5` return values, not
544
+ * Promises) and `fetch` is async, the reads go through a tiny synchronous
545
+ * `curl` shell-out (the same idiom as the github-copilot reader).
546
+ * 2. **Hard handshake gate** — {@link OpenClawParticipant.discover} refuses to
547
+ * talk to an instance that is unpatched (< 2026.1.29) or has authentication
548
+ * disabled. These are refusals with exact reasons AND fixes, not warnings,
549
+ * and every read re-runs the gate.
550
+ * 3. **Quarantined-class** — `quarantinedClass = true`: registering the agent
551
+ * trusted requires `--i-understand-the-risk`, and exports stage for
552
+ * operator review (spec D6: quarantine follows the content, not the
553
+ * invoker). Its content federates under TEAM, never PUBLIC.
554
+ *
555
+ * We gate on instance hygiene (version, auth) — NOT on auditing the user's
556
+ * installed skills; that's ClawSecure et al.'s job (spec non-goal 3).
557
+ */
558
+
559
+ /** First OpenClaw release that patches CVE-2026-25253 (one-click RCE). */
560
+ declare const MIN_PATCHED_VERSION = "2026.1.29";
561
+ /**
562
+ * Hard handshake preconditions (spec D9). Returns the version on success.
563
+ * Raises {@link ParticipantDiscoveryError} with the exact reason AND the fix —
564
+ * these are refusals, not warnings.
565
+ */
566
+ declare function verifyInstance(status: Record<string, unknown>, url: string): string;
567
+ /**
568
+ * Minimal HTTP client for a local OpenClaw instance. Read-only: status,
569
+ * sessions, memories. Failures raise {@link ParticipantDiscoveryError} with the
570
+ * reason — the participant decides how to surface them.
571
+ *
572
+ * Error mapping (faithful to the Python `urllib` client): an HTTP >= 400
573
+ * response -> "returned HTTP {code}"; a transport failure / timeout / non-JSON
574
+ * body -> "instance unreachable at {url}".
575
+ */
576
+ declare class OpenClawApiClient {
577
+ readonly url: string;
578
+ private readonly token;
579
+ readonly timeout: number;
580
+ constructor(url: string, token?: string, timeout?: number);
581
+ private get;
582
+ status(): Record<string, unknown>;
583
+ sessions(): Record<string, unknown>[];
584
+ memories(): Record<string, unknown>[];
585
+ /** Shared `sessions()`/`memories()` body: try/except-returns-[], unwrap the
586
+ * `{ "<key>": [...] }` envelope, and keep only object rows. */
587
+ private readCollection;
588
+ }
589
+ /** Bourdon participant for OpenClaw (quarantined class). */
590
+ declare class OpenClawParticipant implements BourdonParticipant {
591
+ agentId: string;
592
+ agentType: string;
593
+ displayName: string;
594
+ /** Trust marker consumed by `bourdon agent add/set-tier` + export-all:
595
+ * registering as trusted needs --i-understand-the-risk; exports stage. */
596
+ quarantinedClass: boolean;
597
+ readonly url: string;
598
+ private readonly client;
599
+ static defaultNativePath(home?: string): string;
600
+ constructor(url?: string, token?: string, client?: OpenClawApiClient);
601
+ get nativePath(): string;
602
+ discover(): AgentStore;
603
+ exportSessions(since?: Date, limit?: number): SessionModel[];
604
+ exportL5(since?: Date): L5ManifestModel;
605
+ healthCheck(): HealthStatus;
606
+ }
607
+
359
608
  /**
360
609
  * Participant discovery — a STATIC TS registry replacing Python's `pkgutil`
361
610
  * package scan + entry-point duck-type (`participants/__init__.py`).
@@ -377,8 +626,10 @@ declare class GitHubCopilotParticipant extends NetworkParticipant {
377
626
  type ParticipantCtor = new () => BourdonParticipant;
378
627
  /**
379
628
  * The first-party reader registry. Order here is irrelevant — discovery sorts by
380
- * `agentId`. (cursor / codex / copilot_cli are the heavier SQLite readers of the
381
- * follow-on slice; openclaw ships as the `@getbourdon/openclaw` plugin.)
629
+ * `agentId`. (cursor / copilot-cli are the heavier SQLite readers; copilot is the
630
+ * convention-file reader; cascade reads Windsurf; openclaw is the quarantined-
631
+ * class network reader. codex — the ~2.6k-line turn-compiler reader — is still
632
+ * deferred.)
382
633
  */
383
634
  declare const FIRST_PARTY: ParticipantCtor[];
384
635
  /**
@@ -395,4 +646,4 @@ declare function discoverParticipants(ctors?: ParticipantCtor[]): BourdonPartici
395
646
  */
396
647
  declare function resolvePluginParticipants(): ParticipantCtor[];
397
648
 
398
- export { type AgentStore, type AuthProvider, type BourdonParticipant, CONTRACT_VERSION, CacheEntry, ClaudeCodeParticipant, DEFAULT_CACHE_TTL_SECONDS, FIRST_PARTY, GitHubCopilotParticipant, type HealthStatus, HermesParticipant, NETWORK_CONTRACT_VERSION, NetworkParticipant, type NetworkParticipantOptions, NetworkUnavailable, type OpenReadonlyOptions, ParticipantAuthError, type ParticipantCtor, ParticipantDiscoveryError, ParticipantError, ParticipantExportError, ParticipantVersionMismatchError, PayloadCache, SPEC_VERSION, type SqliteDatabase, defaultCacheRoot, discoverParticipants, envAuthProvider, epochToIsoDate, epochToIsoDatetime, friendlyLabel, ghTokenProvider, isParticipant, openReadonly, projectKeyFromCwd, resolvePluginParticipants, sqliteAvailable, tableColumns, tableExists, tryOpenReadonly };
649
+ export { type AgentStore, type AuthProvider, type BourdonParticipant, CONTRACT_VERSION, CacheEntry, CascadeParticipant, ClaudeCodeParticipant, CopilotCliParticipant, CopilotParticipant, CursorParticipant, DEFAULT_CACHE_TTL_SECONDS, FIRST_PARTY, GitHubCopilotParticipant, type HealthStatus, HermesParticipant, MIN_PATCHED_VERSION, NETWORK_CONTRACT_VERSION, NetworkParticipant, type NetworkParticipantOptions, NetworkUnavailable, OpenClawApiClient, OpenClawParticipant, type OpenReadonlyOptions, ParticipantAuthError, type ParticipantCtor, ParticipantDiscoveryError, ParticipantError, ParticipantExportError, ParticipantVersionMismatchError, PayloadCache, SPEC_VERSION, type SqliteDatabase, defaultCacheRoot, discoverParticipants, envAuthProvider, epochToIsoDate, epochToIsoDatetime, friendlyLabel, ghTokenProvider, isParticipant, openReadonly, projectKeyFromCwd, resolvePluginParticipants, sqliteAvailable, tableColumns, tableExists, tryOpenReadonly, verifyInstance };
package/dist/index.d.ts CHANGED
@@ -2,10 +2,13 @@
2
2
  * @getbourdon/participants — the external-agent → L5 reader layer (BUSL-1.1).
3
3
  *
4
4
  * Each participant normalizes a foreign agent's native memory store into a
5
- * visibility-filtered, redacted L5 manifest. Three reader categories:
6
- * - SQLite (read-only, better-sqlite3 mode=ro): {@link HermesParticipant}
7
- * - file / convention: {@link ClaudeCodeParticipant}
5
+ * visibility-filtered, redacted L5 manifest. Reader categories:
6
+ * - SQLite (read-only, better-sqlite3 mode=ro): {@link HermesParticipant},
7
+ * {@link CursorParticipant}, {@link CopilotCliParticipant}
8
+ * - file / convention: {@link ClaudeCodeParticipant},
9
+ * {@link CopilotParticipant}, {@link CascadeParticipant}
8
10
  * - network (TTL cache + lazy AuthProvider): {@link GitHubCopilotParticipant}
11
+ * - network + quarantined-class (handshake gate): {@link OpenClawParticipant}
9
12
  *
10
13
  * Four invariants enforced in code, not by trust: visibility-filter-before-
11
14
  * emission, deterministic exportL5, healthCheck never throws, redact every
@@ -13,8 +16,8 @@
13
16
  *
14
17
  * Python (`pip install bourdon`) is the oracle; this mirror asserts against the
15
18
  * @getbourdon/conformance `native_stores` fixtures (output shape only).
16
- * Follow-on slice: cursor + codex (heavier SQLite) + copilot_cli; openclaw ships
17
- * as the @getbourdon/openclaw plugin.
19
+ * Still deferred: codex (the ~2.6k-line turn-compiler reader) lands in a
20
+ * follow-on slice.
18
21
  */
19
22
  export { CONTRACT_VERSION, SPEC_VERSION, ParticipantError, ParticipantDiscoveryError, ParticipantExportError, ParticipantVersionMismatchError, isParticipant, type AgentStore, type BourdonParticipant, type HealthStatus, } from "./base.js";
20
23
  export { sqliteAvailable, openReadonly, tryOpenReadonly, tableExists, tableColumns, epochToIsoDate, epochToIsoDatetime, projectKeyFromCwd, friendlyLabel, type OpenReadonlyOptions, type SqliteDatabase, } from "./sqlite-base.js";
@@ -22,5 +25,10 @@ export { NETWORK_CONTRACT_VERSION, DEFAULT_CACHE_TTL_SECONDS, NetworkUnavailable
22
25
  export { HermesParticipant } from "./readers/hermes.js";
23
26
  export { ClaudeCodeParticipant } from "./readers/claude-code.js";
24
27
  export { GitHubCopilotParticipant, ghTokenProvider } from "./readers/github-copilot.js";
28
+ export { CursorParticipant } from "./readers/cursor.js";
29
+ export { CopilotParticipant } from "./readers/copilot.js";
30
+ export { CopilotCliParticipant } from "./readers/copilot-cli.js";
31
+ export { CascadeParticipant } from "./readers/cascade.js";
32
+ export { OpenClawParticipant, OpenClawApiClient, verifyInstance, MIN_PATCHED_VERSION, } from "./readers/openclaw.js";
25
33
  export { FIRST_PARTY, discoverParticipants, resolvePluginParticipants, type ParticipantCtor, } from "./registry.js";
26
34
  export { Visibility, applyVisibility, filterForFederation, toDict, validateManifest, type EntityModel, type L5ManifestModel, type SessionModel, type VisibilityPolicyModel, } from "@getbourdon/l5";
package/dist/index.js CHANGED
@@ -2,10 +2,13 @@
2
2
  * @getbourdon/participants — the external-agent → L5 reader layer (BUSL-1.1).
3
3
  *
4
4
  * Each participant normalizes a foreign agent's native memory store into a
5
- * visibility-filtered, redacted L5 manifest. Three reader categories:
6
- * - SQLite (read-only, better-sqlite3 mode=ro): {@link HermesParticipant}
7
- * - file / convention: {@link ClaudeCodeParticipant}
5
+ * visibility-filtered, redacted L5 manifest. Reader categories:
6
+ * - SQLite (read-only, better-sqlite3 mode=ro): {@link HermesParticipant},
7
+ * {@link CursorParticipant}, {@link CopilotCliParticipant}
8
+ * - file / convention: {@link ClaudeCodeParticipant},
9
+ * {@link CopilotParticipant}, {@link CascadeParticipant}
8
10
  * - network (TTL cache + lazy AuthProvider): {@link GitHubCopilotParticipant}
11
+ * - network + quarantined-class (handshake gate): {@link OpenClawParticipant}
9
12
  *
10
13
  * Four invariants enforced in code, not by trust: visibility-filter-before-
11
14
  * emission, deterministic exportL5, healthCheck never throws, redact every
@@ -13,8 +16,8 @@
13
16
  *
14
17
  * Python (`pip install bourdon`) is the oracle; this mirror asserts against the
15
18
  * @getbourdon/conformance `native_stores` fixtures (output shape only).
16
- * Follow-on slice: cursor + codex (heavier SQLite) + copilot_cli; openclaw ships
17
- * as the @getbourdon/openclaw plugin.
19
+ * Still deferred: codex (the ~2.6k-line turn-compiler reader) lands in a
20
+ * follow-on slice.
18
21
  */
19
22
  // Contract surface: Protocol interface, errors, AgentStore + HealthStatus.
20
23
  export { CONTRACT_VERSION, SPEC_VERSION, ParticipantError, ParticipantDiscoveryError, ParticipantExportError, ParticipantVersionMismatchError, isParticipant, } from "./base.js";
@@ -26,6 +29,11 @@ export { NETWORK_CONTRACT_VERSION, DEFAULT_CACHE_TTL_SECONDS, NetworkUnavailable
26
29
  export { HermesParticipant } from "./readers/hermes.js";
27
30
  export { ClaudeCodeParticipant } from "./readers/claude-code.js";
28
31
  export { GitHubCopilotParticipant, ghTokenProvider } from "./readers/github-copilot.js";
32
+ export { CursorParticipant } from "./readers/cursor.js";
33
+ export { CopilotParticipant } from "./readers/copilot.js";
34
+ export { CopilotCliParticipant } from "./readers/copilot-cli.js";
35
+ export { CascadeParticipant } from "./readers/cascade.js";
36
+ export { OpenClawParticipant, OpenClawApiClient, verifyInstance, MIN_PATCHED_VERSION, } from "./readers/openclaw.js";
29
37
  // Discovery (static registry).
30
38
  export { FIRST_PARTY, discoverParticipants, resolvePluginParticipants, } from "./registry.js";
31
39
  // Re-exported from @getbourdon/l5 for convenience (the L5 model + serialization