@brightbeamai/chap-coordinator 0.2.8

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.
Files changed (53) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +271 -0
  3. package/dist/api-C3nkEk-B.d.cts +260 -0
  4. package/dist/api-CmSvlIqO.d.ts +260 -0
  5. package/dist/api.cjs +125 -0
  6. package/dist/api.cjs.map +1 -0
  7. package/dist/api.d.cts +4 -0
  8. package/dist/api.d.ts +4 -0
  9. package/dist/api.js +98 -0
  10. package/dist/api.js.map +1 -0
  11. package/dist/index.cjs +2804 -0
  12. package/dist/index.cjs.map +1 -0
  13. package/dist/index.d.cts +175 -0
  14. package/dist/index.d.ts +175 -0
  15. package/dist/index.js +2762 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/jsonrpc.cjs +103 -0
  18. package/dist/jsonrpc.cjs.map +1 -0
  19. package/dist/jsonrpc.d.cts +65 -0
  20. package/dist/jsonrpc.d.ts +65 -0
  21. package/dist/jsonrpc.js +76 -0
  22. package/dist/jsonrpc.js.map +1 -0
  23. package/dist/methods.cjs +19 -0
  24. package/dist/methods.cjs.map +1 -0
  25. package/dist/methods.d.cts +455 -0
  26. package/dist/methods.d.ts +455 -0
  27. package/dist/methods.js +1 -0
  28. package/dist/methods.js.map +1 -0
  29. package/dist/patch.cjs +277 -0
  30. package/dist/patch.cjs.map +1 -0
  31. package/dist/patch.d.cts +29 -0
  32. package/dist/patch.d.ts +29 -0
  33. package/dist/patch.js +250 -0
  34. package/dist/patch.js.map +1 -0
  35. package/dist/storage/sqlite.cjs +94 -0
  36. package/dist/storage/sqlite.cjs.map +1 -0
  37. package/dist/storage/sqlite.d.cts +67 -0
  38. package/dist/storage/sqlite.d.ts +67 -0
  39. package/dist/storage/sqlite.js +76 -0
  40. package/dist/storage/sqlite.js.map +1 -0
  41. package/dist/storage/store.cjs +45 -0
  42. package/dist/storage/store.cjs.map +1 -0
  43. package/dist/storage/store.d.cts +53 -0
  44. package/dist/storage/store.d.ts +53 -0
  45. package/dist/storage/store.js +20 -0
  46. package/dist/storage/store.js.map +1 -0
  47. package/dist/types.cjs +34 -0
  48. package/dist/types.cjs.map +1 -0
  49. package/dist/types.d.cts +287 -0
  50. package/dist/types.d.ts +287 -0
  51. package/dist/types.js +9 -0
  52. package/dist/types.js.map +1 -0
  53. package/package.json +52 -0
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/storage/sqlite.ts
21
+ var sqlite_exports = {};
22
+ __export(sqlite_exports, {
23
+ SqliteStore: () => SqliteStore
24
+ });
25
+ module.exports = __toCommonJS(sqlite_exports);
26
+ var SqliteStore = class {
27
+ db;
28
+ stmtLoad;
29
+ stmtSave;
30
+ stmtDelete;
31
+ constructor(path, options = {}) {
32
+ let Database;
33
+ try {
34
+ Database = require("better-sqlite3");
35
+ } catch (err) {
36
+ throw new Error(
37
+ "SqliteStore requires the `better-sqlite3` package. Install it with `npm install better-sqlite3` or use MemoryStore for non-persistent workloads."
38
+ );
39
+ }
40
+ this.db = new Database(path);
41
+ if (path !== ":memory:" && options.wal !== false) {
42
+ this.db.pragma("journal_mode = WAL");
43
+ }
44
+ this.db.exec(`
45
+ CREATE TABLE IF NOT EXISTS chap_workspaces (
46
+ id TEXT PRIMARY KEY,
47
+ data TEXT NOT NULL,
48
+ version INTEGER NOT NULL,
49
+ updated_at TEXT NOT NULL
50
+ );
51
+ CREATE INDEX IF NOT EXISTS idx_chap_workspaces_updated_at
52
+ ON chap_workspaces (updated_at);
53
+ `);
54
+ this.stmtLoad = this.db.prepare(
55
+ "SELECT id, data, version, updated_at FROM chap_workspaces"
56
+ );
57
+ this.stmtSave = this.db.prepare(
58
+ "INSERT INTO chap_workspaces (id, data, version, updated_at) VALUES (?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET data = excluded.data, version = excluded.version, updated_at = excluded.updated_at"
59
+ );
60
+ this.stmtDelete = this.db.prepare(
61
+ "DELETE FROM chap_workspaces WHERE id = ?"
62
+ );
63
+ }
64
+ load() {
65
+ const rows = this.stmtLoad.all();
66
+ const out = [];
67
+ for (const r of rows) {
68
+ try {
69
+ out.push({ id: r.id, data: JSON.parse(r.data), version: r.version, updated_at: r.updated_at });
70
+ } catch {
71
+ }
72
+ }
73
+ return out;
74
+ }
75
+ save(record) {
76
+ this.stmtSave.run(
77
+ record.id,
78
+ JSON.stringify(record.data),
79
+ record.version,
80
+ record.updated_at
81
+ );
82
+ }
83
+ delete(id) {
84
+ this.stmtDelete.run(id);
85
+ }
86
+ close() {
87
+ this.db.close();
88
+ }
89
+ };
90
+ // Annotate the CommonJS export names for ESM import in node:
91
+ 0 && (module.exports = {
92
+ SqliteStore
93
+ });
94
+ //# sourceMappingURL=sqlite.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/storage/sqlite.ts"],"sourcesContent":["/**\n * SQLite-backed store using better-sqlite3.\n *\n * Schema:\n * CREATE TABLE chap_workspaces (\n * id TEXT PRIMARY KEY,\n * data TEXT NOT NULL, -- JSON.stringify of snapshot\n * version INTEGER NOT NULL,\n * updated_at TEXT NOT NULL -- ISO-8601\n * )\n *\n * Usage:\n * import { Coordinator } from \"@brightbeamai/chap-coordinator\";\n * import { SqliteStore } from \"@brightbeamai/chap-coordinator/storage/sqlite\";\n *\n * const coord = new Coordinator({\n * store: new SqliteStore(\"./chap.db\"),\n * });\n *\n * Pass `\":memory:\"` for an in-memory SQLite instance (faster than the\n * MemoryStore for tests that need transactional semantics).\n *\n * better-sqlite3 is declared as an optionalDependency. If the binary\n * cannot be built (rare on Linux/macOS, common on locked-down CI), the\n * SqliteStore import will throw with a clear message and applications\n * can fall back to MemoryStore or another implementation.\n */\n\nimport type { Store, WorkspaceRecord } from \"./store.js\";\n\n// better-sqlite3 has no published types in its own package, but the\n// `@types/better-sqlite3` package provides them. We require a structural\n// subset so the file type-checks even if the typings are absent.\ninterface SqliteDatabase {\n exec(sql: string): unknown;\n prepare(sql: string): SqliteStatement;\n pragma(name: string, options?: { simple?: boolean }): unknown;\n close(): void;\n}\ninterface SqliteStatement {\n run(...params: unknown[]): { changes: number; lastInsertRowid: number | bigint };\n get(...params: unknown[]): unknown;\n all(...params: unknown[]): unknown[];\n}\n\nexport interface SqliteStoreOptions {\n /**\n * Enable WAL journal mode for better concurrent-read performance.\n * Default true. Set false for `:memory:` databases or when the\n * filesystem does not support WAL (some network filesystems).\n */\n wal?: boolean;\n}\n\nexport class SqliteStore implements Store {\n readonly db: SqliteDatabase;\n private readonly stmtLoad: SqliteStatement;\n private readonly stmtSave: SqliteStatement;\n private readonly stmtDelete: SqliteStatement;\n\n constructor(path: string, options: SqliteStoreOptions = {}) {\n let Database: new (path: string) => SqliteDatabase;\n try {\n // require() is used so the dependency stays optional. ESM consumers\n // can still load this file; the actual import is dynamic.\n Database = require(\"better-sqlite3\");\n } catch (err) {\n throw new Error(\n \"SqliteStore requires the `better-sqlite3` package. \" +\n \"Install it with `npm install better-sqlite3` \" +\n \"or use MemoryStore for non-persistent workloads.\",\n );\n }\n\n this.db = new Database(path);\n if (path !== \":memory:\" && options.wal !== false) {\n this.db.pragma(\"journal_mode = WAL\");\n }\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS chap_workspaces (\n id TEXT PRIMARY KEY,\n data TEXT NOT NULL,\n version INTEGER NOT NULL,\n updated_at TEXT NOT NULL\n );\n CREATE INDEX IF NOT EXISTS idx_chap_workspaces_updated_at\n ON chap_workspaces (updated_at);\n `);\n\n this.stmtLoad = this.db.prepare(\n \"SELECT id, data, version, updated_at FROM chap_workspaces\",\n );\n this.stmtSave = this.db.prepare(\n \"INSERT INTO chap_workspaces (id, data, version, updated_at) \" +\n \"VALUES (?, ?, ?, ?) \" +\n \"ON CONFLICT(id) DO UPDATE SET \" +\n \"data = excluded.data, \" +\n \"version = excluded.version, \" +\n \"updated_at = excluded.updated_at\",\n );\n this.stmtDelete = this.db.prepare(\n \"DELETE FROM chap_workspaces WHERE id = ?\",\n );\n }\n\n load(): WorkspaceRecord[] {\n const rows = this.stmtLoad.all() as Array<{\n id: string;\n data: string;\n version: number;\n updated_at: string;\n }>;\n const out: WorkspaceRecord[] = [];\n for (const r of rows) {\n try {\n out.push({ id: r.id, data: JSON.parse(r.data), version: r.version, updated_at: r.updated_at });\n } catch {\n // A single unreadable row must not discard every other workspace; skip it.\n }\n }\n return out;\n }\n\n save(record: WorkspaceRecord): void {\n this.stmtSave.run(\n record.id,\n JSON.stringify(record.data),\n record.version,\n record.updated_at,\n );\n }\n\n delete(id: string): void {\n this.stmtDelete.run(id);\n }\n\n close(): void {\n this.db.close();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAsDO,IAAM,cAAN,MAAmC;AAAA,EAC/B;AAAA,EACQ;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,MAAc,UAA8B,CAAC,GAAG;AAC1D,QAAI;AACJ,QAAI;AAGF,iBAAW,QAAQ,gBAAgB;AAAA,IACrC,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR;AAAA,MAGF;AAAA,IACF;AAEA,SAAK,KAAK,IAAI,SAAS,IAAI;AAC3B,QAAI,SAAS,cAAc,QAAQ,QAAQ,OAAO;AAChD,WAAK,GAAG,OAAO,oBAAoB;AAAA,IACrC;AACA,SAAK,GAAG,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KASZ;AAED,SAAK,WAAW,KAAK,GAAG;AAAA,MACtB;AAAA,IACF;AACA,SAAK,WAAW,KAAK,GAAG;AAAA,MACtB;AAAA,IAMF;AACA,SAAK,aAAa,KAAK,GAAG;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAA0B;AACxB,UAAM,OAAO,KAAK,SAAS,IAAI;AAM/B,UAAM,MAAyB,CAAC;AAChC,eAAW,KAAK,MAAM;AACpB,UAAI;AACF,YAAI,KAAK,EAAE,IAAI,EAAE,IAAI,MAAM,KAAK,MAAM,EAAE,IAAI,GAAG,SAAS,EAAE,SAAS,YAAY,EAAE,WAAW,CAAC;AAAA,MAC/F,QAAQ;AAAA,MAER;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,KAAK,QAA+B;AAClC,SAAK,SAAS;AAAA,MACZ,OAAO;AAAA,MACP,KAAK,UAAU,OAAO,IAAI;AAAA,MAC1B,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,OAAO,IAAkB;AACvB,SAAK,WAAW,IAAI,EAAE;AAAA,EACxB;AAAA,EAEA,QAAc;AACZ,SAAK,GAAG,MAAM;AAAA,EAChB;AACF;","names":[]}
@@ -0,0 +1,67 @@
1
+ import { Store, WorkspaceRecord } from './store.cjs';
2
+
3
+ /**
4
+ * SQLite-backed store using better-sqlite3.
5
+ *
6
+ * Schema:
7
+ * CREATE TABLE chap_workspaces (
8
+ * id TEXT PRIMARY KEY,
9
+ * data TEXT NOT NULL, -- JSON.stringify of snapshot
10
+ * version INTEGER NOT NULL,
11
+ * updated_at TEXT NOT NULL -- ISO-8601
12
+ * )
13
+ *
14
+ * Usage:
15
+ * import { Coordinator } from "@brightbeamai/chap-coordinator";
16
+ * import { SqliteStore } from "@brightbeamai/chap-coordinator/storage/sqlite";
17
+ *
18
+ * const coord = new Coordinator({
19
+ * store: new SqliteStore("./chap.db"),
20
+ * });
21
+ *
22
+ * Pass `":memory:"` for an in-memory SQLite instance (faster than the
23
+ * MemoryStore for tests that need transactional semantics).
24
+ *
25
+ * better-sqlite3 is declared as an optionalDependency. If the binary
26
+ * cannot be built (rare on Linux/macOS, common on locked-down CI), the
27
+ * SqliteStore import will throw with a clear message and applications
28
+ * can fall back to MemoryStore or another implementation.
29
+ */
30
+
31
+ interface SqliteDatabase {
32
+ exec(sql: string): unknown;
33
+ prepare(sql: string): SqliteStatement;
34
+ pragma(name: string, options?: {
35
+ simple?: boolean;
36
+ }): unknown;
37
+ close(): void;
38
+ }
39
+ interface SqliteStatement {
40
+ run(...params: unknown[]): {
41
+ changes: number;
42
+ lastInsertRowid: number | bigint;
43
+ };
44
+ get(...params: unknown[]): unknown;
45
+ all(...params: unknown[]): unknown[];
46
+ }
47
+ interface SqliteStoreOptions {
48
+ /**
49
+ * Enable WAL journal mode for better concurrent-read performance.
50
+ * Default true. Set false for `:memory:` databases or when the
51
+ * filesystem does not support WAL (some network filesystems).
52
+ */
53
+ wal?: boolean;
54
+ }
55
+ declare class SqliteStore implements Store {
56
+ readonly db: SqliteDatabase;
57
+ private readonly stmtLoad;
58
+ private readonly stmtSave;
59
+ private readonly stmtDelete;
60
+ constructor(path: string, options?: SqliteStoreOptions);
61
+ load(): WorkspaceRecord[];
62
+ save(record: WorkspaceRecord): void;
63
+ delete(id: string): void;
64
+ close(): void;
65
+ }
66
+
67
+ export { SqliteStore, type SqliteStoreOptions };
@@ -0,0 +1,67 @@
1
+ import { Store, WorkspaceRecord } from './store.js';
2
+
3
+ /**
4
+ * SQLite-backed store using better-sqlite3.
5
+ *
6
+ * Schema:
7
+ * CREATE TABLE chap_workspaces (
8
+ * id TEXT PRIMARY KEY,
9
+ * data TEXT NOT NULL, -- JSON.stringify of snapshot
10
+ * version INTEGER NOT NULL,
11
+ * updated_at TEXT NOT NULL -- ISO-8601
12
+ * )
13
+ *
14
+ * Usage:
15
+ * import { Coordinator } from "@brightbeamai/chap-coordinator";
16
+ * import { SqliteStore } from "@brightbeamai/chap-coordinator/storage/sqlite";
17
+ *
18
+ * const coord = new Coordinator({
19
+ * store: new SqliteStore("./chap.db"),
20
+ * });
21
+ *
22
+ * Pass `":memory:"` for an in-memory SQLite instance (faster than the
23
+ * MemoryStore for tests that need transactional semantics).
24
+ *
25
+ * better-sqlite3 is declared as an optionalDependency. If the binary
26
+ * cannot be built (rare on Linux/macOS, common on locked-down CI), the
27
+ * SqliteStore import will throw with a clear message and applications
28
+ * can fall back to MemoryStore or another implementation.
29
+ */
30
+
31
+ interface SqliteDatabase {
32
+ exec(sql: string): unknown;
33
+ prepare(sql: string): SqliteStatement;
34
+ pragma(name: string, options?: {
35
+ simple?: boolean;
36
+ }): unknown;
37
+ close(): void;
38
+ }
39
+ interface SqliteStatement {
40
+ run(...params: unknown[]): {
41
+ changes: number;
42
+ lastInsertRowid: number | bigint;
43
+ };
44
+ get(...params: unknown[]): unknown;
45
+ all(...params: unknown[]): unknown[];
46
+ }
47
+ interface SqliteStoreOptions {
48
+ /**
49
+ * Enable WAL journal mode for better concurrent-read performance.
50
+ * Default true. Set false for `:memory:` databases or when the
51
+ * filesystem does not support WAL (some network filesystems).
52
+ */
53
+ wal?: boolean;
54
+ }
55
+ declare class SqliteStore implements Store {
56
+ readonly db: SqliteDatabase;
57
+ private readonly stmtLoad;
58
+ private readonly stmtSave;
59
+ private readonly stmtDelete;
60
+ constructor(path: string, options?: SqliteStoreOptions);
61
+ load(): WorkspaceRecord[];
62
+ save(record: WorkspaceRecord): void;
63
+ delete(id: string): void;
64
+ close(): void;
65
+ }
66
+
67
+ export { SqliteStore, type SqliteStoreOptions };
@@ -0,0 +1,76 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // src/storage/sqlite.ts
9
+ var SqliteStore = class {
10
+ db;
11
+ stmtLoad;
12
+ stmtSave;
13
+ stmtDelete;
14
+ constructor(path, options = {}) {
15
+ let Database;
16
+ try {
17
+ Database = __require("better-sqlite3");
18
+ } catch (err) {
19
+ throw new Error(
20
+ "SqliteStore requires the `better-sqlite3` package. Install it with `npm install better-sqlite3` or use MemoryStore for non-persistent workloads."
21
+ );
22
+ }
23
+ this.db = new Database(path);
24
+ if (path !== ":memory:" && options.wal !== false) {
25
+ this.db.pragma("journal_mode = WAL");
26
+ }
27
+ this.db.exec(`
28
+ CREATE TABLE IF NOT EXISTS chap_workspaces (
29
+ id TEXT PRIMARY KEY,
30
+ data TEXT NOT NULL,
31
+ version INTEGER NOT NULL,
32
+ updated_at TEXT NOT NULL
33
+ );
34
+ CREATE INDEX IF NOT EXISTS idx_chap_workspaces_updated_at
35
+ ON chap_workspaces (updated_at);
36
+ `);
37
+ this.stmtLoad = this.db.prepare(
38
+ "SELECT id, data, version, updated_at FROM chap_workspaces"
39
+ );
40
+ this.stmtSave = this.db.prepare(
41
+ "INSERT INTO chap_workspaces (id, data, version, updated_at) VALUES (?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET data = excluded.data, version = excluded.version, updated_at = excluded.updated_at"
42
+ );
43
+ this.stmtDelete = this.db.prepare(
44
+ "DELETE FROM chap_workspaces WHERE id = ?"
45
+ );
46
+ }
47
+ load() {
48
+ const rows = this.stmtLoad.all();
49
+ const out = [];
50
+ for (const r of rows) {
51
+ try {
52
+ out.push({ id: r.id, data: JSON.parse(r.data), version: r.version, updated_at: r.updated_at });
53
+ } catch {
54
+ }
55
+ }
56
+ return out;
57
+ }
58
+ save(record) {
59
+ this.stmtSave.run(
60
+ record.id,
61
+ JSON.stringify(record.data),
62
+ record.version,
63
+ record.updated_at
64
+ );
65
+ }
66
+ delete(id) {
67
+ this.stmtDelete.run(id);
68
+ }
69
+ close() {
70
+ this.db.close();
71
+ }
72
+ };
73
+ export {
74
+ SqliteStore
75
+ };
76
+ //# sourceMappingURL=sqlite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/storage/sqlite.ts"],"sourcesContent":["/**\n * SQLite-backed store using better-sqlite3.\n *\n * Schema:\n * CREATE TABLE chap_workspaces (\n * id TEXT PRIMARY KEY,\n * data TEXT NOT NULL, -- JSON.stringify of snapshot\n * version INTEGER NOT NULL,\n * updated_at TEXT NOT NULL -- ISO-8601\n * )\n *\n * Usage:\n * import { Coordinator } from \"@brightbeamai/chap-coordinator\";\n * import { SqliteStore } from \"@brightbeamai/chap-coordinator/storage/sqlite\";\n *\n * const coord = new Coordinator({\n * store: new SqliteStore(\"./chap.db\"),\n * });\n *\n * Pass `\":memory:\"` for an in-memory SQLite instance (faster than the\n * MemoryStore for tests that need transactional semantics).\n *\n * better-sqlite3 is declared as an optionalDependency. If the binary\n * cannot be built (rare on Linux/macOS, common on locked-down CI), the\n * SqliteStore import will throw with a clear message and applications\n * can fall back to MemoryStore or another implementation.\n */\n\nimport type { Store, WorkspaceRecord } from \"./store.js\";\n\n// better-sqlite3 has no published types in its own package, but the\n// `@types/better-sqlite3` package provides them. We require a structural\n// subset so the file type-checks even if the typings are absent.\ninterface SqliteDatabase {\n exec(sql: string): unknown;\n prepare(sql: string): SqliteStatement;\n pragma(name: string, options?: { simple?: boolean }): unknown;\n close(): void;\n}\ninterface SqliteStatement {\n run(...params: unknown[]): { changes: number; lastInsertRowid: number | bigint };\n get(...params: unknown[]): unknown;\n all(...params: unknown[]): unknown[];\n}\n\nexport interface SqliteStoreOptions {\n /**\n * Enable WAL journal mode for better concurrent-read performance.\n * Default true. Set false for `:memory:` databases or when the\n * filesystem does not support WAL (some network filesystems).\n */\n wal?: boolean;\n}\n\nexport class SqliteStore implements Store {\n readonly db: SqliteDatabase;\n private readonly stmtLoad: SqliteStatement;\n private readonly stmtSave: SqliteStatement;\n private readonly stmtDelete: SqliteStatement;\n\n constructor(path: string, options: SqliteStoreOptions = {}) {\n let Database: new (path: string) => SqliteDatabase;\n try {\n // require() is used so the dependency stays optional. ESM consumers\n // can still load this file; the actual import is dynamic.\n Database = require(\"better-sqlite3\");\n } catch (err) {\n throw new Error(\n \"SqliteStore requires the `better-sqlite3` package. \" +\n \"Install it with `npm install better-sqlite3` \" +\n \"or use MemoryStore for non-persistent workloads.\",\n );\n }\n\n this.db = new Database(path);\n if (path !== \":memory:\" && options.wal !== false) {\n this.db.pragma(\"journal_mode = WAL\");\n }\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS chap_workspaces (\n id TEXT PRIMARY KEY,\n data TEXT NOT NULL,\n version INTEGER NOT NULL,\n updated_at TEXT NOT NULL\n );\n CREATE INDEX IF NOT EXISTS idx_chap_workspaces_updated_at\n ON chap_workspaces (updated_at);\n `);\n\n this.stmtLoad = this.db.prepare(\n \"SELECT id, data, version, updated_at FROM chap_workspaces\",\n );\n this.stmtSave = this.db.prepare(\n \"INSERT INTO chap_workspaces (id, data, version, updated_at) \" +\n \"VALUES (?, ?, ?, ?) \" +\n \"ON CONFLICT(id) DO UPDATE SET \" +\n \"data = excluded.data, \" +\n \"version = excluded.version, \" +\n \"updated_at = excluded.updated_at\",\n );\n this.stmtDelete = this.db.prepare(\n \"DELETE FROM chap_workspaces WHERE id = ?\",\n );\n }\n\n load(): WorkspaceRecord[] {\n const rows = this.stmtLoad.all() as Array<{\n id: string;\n data: string;\n version: number;\n updated_at: string;\n }>;\n const out: WorkspaceRecord[] = [];\n for (const r of rows) {\n try {\n out.push({ id: r.id, data: JSON.parse(r.data), version: r.version, updated_at: r.updated_at });\n } catch {\n // A single unreadable row must not discard every other workspace; skip it.\n }\n }\n return out;\n }\n\n save(record: WorkspaceRecord): void {\n this.stmtSave.run(\n record.id,\n JSON.stringify(record.data),\n record.version,\n record.updated_at,\n );\n }\n\n delete(id: string): void {\n this.stmtDelete.run(id);\n }\n\n close(): void {\n this.db.close();\n }\n}\n"],"mappings":";;;;;;;;AAsDO,IAAM,cAAN,MAAmC;AAAA,EAC/B;AAAA,EACQ;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,MAAc,UAA8B,CAAC,GAAG;AAC1D,QAAI;AACJ,QAAI;AAGF,iBAAW,UAAQ,gBAAgB;AAAA,IACrC,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR;AAAA,MAGF;AAAA,IACF;AAEA,SAAK,KAAK,IAAI,SAAS,IAAI;AAC3B,QAAI,SAAS,cAAc,QAAQ,QAAQ,OAAO;AAChD,WAAK,GAAG,OAAO,oBAAoB;AAAA,IACrC;AACA,SAAK,GAAG,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KASZ;AAED,SAAK,WAAW,KAAK,GAAG;AAAA,MACtB;AAAA,IACF;AACA,SAAK,WAAW,KAAK,GAAG;AAAA,MACtB;AAAA,IAMF;AACA,SAAK,aAAa,KAAK,GAAG;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAA0B;AACxB,UAAM,OAAO,KAAK,SAAS,IAAI;AAM/B,UAAM,MAAyB,CAAC;AAChC,eAAW,KAAK,MAAM;AACpB,UAAI;AACF,YAAI,KAAK,EAAE,IAAI,EAAE,IAAI,MAAM,KAAK,MAAM,EAAE,IAAI,GAAG,SAAS,EAAE,SAAS,YAAY,EAAE,WAAW,CAAC;AAAA,MAC/F,QAAQ;AAAA,MAER;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,KAAK,QAA+B;AAClC,SAAK,SAAS;AAAA,MACZ,OAAO;AAAA,MACP,KAAK,UAAU,OAAO,IAAI;AAAA,MAC1B,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,OAAO,IAAkB;AACvB,SAAK,WAAW,IAAI,EAAE;AAAA,EACxB;AAAA,EAEA,QAAc;AACZ,SAAK,GAAG,MAAM;AAAA,EAChB;AACF;","names":[]}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/storage/store.ts
21
+ var store_exports = {};
22
+ __export(store_exports, {
23
+ MemoryStore: () => MemoryStore
24
+ });
25
+ module.exports = __toCommonJS(store_exports);
26
+ var MemoryStore = class {
27
+ records = /* @__PURE__ */ new Map();
28
+ load() {
29
+ return Array.from(this.records.values());
30
+ }
31
+ save(record) {
32
+ this.records.set(record.id, record);
33
+ }
34
+ delete(id) {
35
+ this.records.delete(id);
36
+ }
37
+ close() {
38
+ this.records.clear();
39
+ }
40
+ };
41
+ // Annotate the CommonJS export names for ESM import in node:
42
+ 0 && (module.exports = {
43
+ MemoryStore
44
+ });
45
+ //# sourceMappingURL=store.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/storage/store.ts"],"sourcesContent":["/**\n * Pluggable persistence for the Coordinator.\n *\n * A Store persists workspace state between process restarts. Coordinators\n * call `store.save(workspaceId, snapshot)` after every mutation that\n * appends to the audit chain, and `store.load()` on startup to restore.\n *\n * Two implementations ship in-tree:\n * - MemoryStore (default, no persistence; existing behaviour)\n * - SqliteStore (real SQLite via better-sqlite3, opt-in)\n *\n * Third-party stores (Postgres, Redis, etc.) implement this interface.\n *\n * Stores hold per-workspace JSON snapshots, not a decomposed relational\n * model. The Coordinator's snapshot/restore methods produce JSON-safe\n * payloads; this is fast for workspaces in the low-thousands of audit\n * entries and trades query flexibility for simplicity. Production\n * deployments needing rich query semantics should project the audit log\n * into their own analytics store via the `onAudit` listener.\n */\n\nexport interface WorkspaceRecord {\n /** Workspace identifier. */\n id: string;\n /** JSON-serialisable payload produced by `Coordinator.snapshot()`. */\n data: unknown;\n /** Monotonically increasing version for optimistic concurrency. */\n version: number;\n /** Wall-clock timestamp of the last write, ISO-8601. */\n updated_at: string;\n}\n\nexport interface Store {\n /** Load all workspace records into memory. Called once on coordinator start. */\n load(): Promise<WorkspaceRecord[]> | WorkspaceRecord[];\n\n /** Persist one workspace record. Called after every mutation. */\n save(record: WorkspaceRecord): Promise<void> | void;\n\n /** Remove one workspace. Used by `workspace.delete` semantics (not in v0.2). */\n delete(id: string): Promise<void> | void;\n\n /** Release resources. Idempotent. */\n close?(): Promise<void> | void;\n}\n\n/**\n * In-memory store. Default behaviour: no persistence, fast tests.\n * State lives in a Map; closing it discards everything.\n */\nexport class MemoryStore implements Store {\n private records = new Map<string, WorkspaceRecord>();\n\n load(): WorkspaceRecord[] {\n return Array.from(this.records.values());\n }\n\n save(record: WorkspaceRecord): void {\n this.records.set(record.id, record);\n }\n\n delete(id: string): void {\n this.records.delete(id);\n }\n\n close(): void {\n this.records.clear();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAkDO,IAAM,cAAN,MAAmC;AAAA,EAChC,UAAU,oBAAI,IAA6B;AAAA,EAEnD,OAA0B;AACxB,WAAO,MAAM,KAAK,KAAK,QAAQ,OAAO,CAAC;AAAA,EACzC;AAAA,EAEA,KAAK,QAA+B;AAClC,SAAK,QAAQ,IAAI,OAAO,IAAI,MAAM;AAAA,EACpC;AAAA,EAEA,OAAO,IAAkB;AACvB,SAAK,QAAQ,OAAO,EAAE;AAAA,EACxB;AAAA,EAEA,QAAc;AACZ,SAAK,QAAQ,MAAM;AAAA,EACrB;AACF;","names":[]}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Pluggable persistence for the Coordinator.
3
+ *
4
+ * A Store persists workspace state between process restarts. Coordinators
5
+ * call `store.save(workspaceId, snapshot)` after every mutation that
6
+ * appends to the audit chain, and `store.load()` on startup to restore.
7
+ *
8
+ * Two implementations ship in-tree:
9
+ * - MemoryStore (default, no persistence; existing behaviour)
10
+ * - SqliteStore (real SQLite via better-sqlite3, opt-in)
11
+ *
12
+ * Third-party stores (Postgres, Redis, etc.) implement this interface.
13
+ *
14
+ * Stores hold per-workspace JSON snapshots, not a decomposed relational
15
+ * model. The Coordinator's snapshot/restore methods produce JSON-safe
16
+ * payloads; this is fast for workspaces in the low-thousands of audit
17
+ * entries and trades query flexibility for simplicity. Production
18
+ * deployments needing rich query semantics should project the audit log
19
+ * into their own analytics store via the `onAudit` listener.
20
+ */
21
+ interface WorkspaceRecord {
22
+ /** Workspace identifier. */
23
+ id: string;
24
+ /** JSON-serialisable payload produced by `Coordinator.snapshot()`. */
25
+ data: unknown;
26
+ /** Monotonically increasing version for optimistic concurrency. */
27
+ version: number;
28
+ /** Wall-clock timestamp of the last write, ISO-8601. */
29
+ updated_at: string;
30
+ }
31
+ interface Store {
32
+ /** Load all workspace records into memory. Called once on coordinator start. */
33
+ load(): Promise<WorkspaceRecord[]> | WorkspaceRecord[];
34
+ /** Persist one workspace record. Called after every mutation. */
35
+ save(record: WorkspaceRecord): Promise<void> | void;
36
+ /** Remove one workspace. Used by `workspace.delete` semantics (not in v0.2). */
37
+ delete(id: string): Promise<void> | void;
38
+ /** Release resources. Idempotent. */
39
+ close?(): Promise<void> | void;
40
+ }
41
+ /**
42
+ * In-memory store. Default behaviour: no persistence, fast tests.
43
+ * State lives in a Map; closing it discards everything.
44
+ */
45
+ declare class MemoryStore implements Store {
46
+ private records;
47
+ load(): WorkspaceRecord[];
48
+ save(record: WorkspaceRecord): void;
49
+ delete(id: string): void;
50
+ close(): void;
51
+ }
52
+
53
+ export { MemoryStore, type Store, type WorkspaceRecord };
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Pluggable persistence for the Coordinator.
3
+ *
4
+ * A Store persists workspace state between process restarts. Coordinators
5
+ * call `store.save(workspaceId, snapshot)` after every mutation that
6
+ * appends to the audit chain, and `store.load()` on startup to restore.
7
+ *
8
+ * Two implementations ship in-tree:
9
+ * - MemoryStore (default, no persistence; existing behaviour)
10
+ * - SqliteStore (real SQLite via better-sqlite3, opt-in)
11
+ *
12
+ * Third-party stores (Postgres, Redis, etc.) implement this interface.
13
+ *
14
+ * Stores hold per-workspace JSON snapshots, not a decomposed relational
15
+ * model. The Coordinator's snapshot/restore methods produce JSON-safe
16
+ * payloads; this is fast for workspaces in the low-thousands of audit
17
+ * entries and trades query flexibility for simplicity. Production
18
+ * deployments needing rich query semantics should project the audit log
19
+ * into their own analytics store via the `onAudit` listener.
20
+ */
21
+ interface WorkspaceRecord {
22
+ /** Workspace identifier. */
23
+ id: string;
24
+ /** JSON-serialisable payload produced by `Coordinator.snapshot()`. */
25
+ data: unknown;
26
+ /** Monotonically increasing version for optimistic concurrency. */
27
+ version: number;
28
+ /** Wall-clock timestamp of the last write, ISO-8601. */
29
+ updated_at: string;
30
+ }
31
+ interface Store {
32
+ /** Load all workspace records into memory. Called once on coordinator start. */
33
+ load(): Promise<WorkspaceRecord[]> | WorkspaceRecord[];
34
+ /** Persist one workspace record. Called after every mutation. */
35
+ save(record: WorkspaceRecord): Promise<void> | void;
36
+ /** Remove one workspace. Used by `workspace.delete` semantics (not in v0.2). */
37
+ delete(id: string): Promise<void> | void;
38
+ /** Release resources. Idempotent. */
39
+ close?(): Promise<void> | void;
40
+ }
41
+ /**
42
+ * In-memory store. Default behaviour: no persistence, fast tests.
43
+ * State lives in a Map; closing it discards everything.
44
+ */
45
+ declare class MemoryStore implements Store {
46
+ private records;
47
+ load(): WorkspaceRecord[];
48
+ save(record: WorkspaceRecord): void;
49
+ delete(id: string): void;
50
+ close(): void;
51
+ }
52
+
53
+ export { MemoryStore, type Store, type WorkspaceRecord };
@@ -0,0 +1,20 @@
1
+ // src/storage/store.ts
2
+ var MemoryStore = class {
3
+ records = /* @__PURE__ */ new Map();
4
+ load() {
5
+ return Array.from(this.records.values());
6
+ }
7
+ save(record) {
8
+ this.records.set(record.id, record);
9
+ }
10
+ delete(id) {
11
+ this.records.delete(id);
12
+ }
13
+ close() {
14
+ this.records.clear();
15
+ }
16
+ };
17
+ export {
18
+ MemoryStore
19
+ };
20
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/storage/store.ts"],"sourcesContent":["/**\n * Pluggable persistence for the Coordinator.\n *\n * A Store persists workspace state between process restarts. Coordinators\n * call `store.save(workspaceId, snapshot)` after every mutation that\n * appends to the audit chain, and `store.load()` on startup to restore.\n *\n * Two implementations ship in-tree:\n * - MemoryStore (default, no persistence; existing behaviour)\n * - SqliteStore (real SQLite via better-sqlite3, opt-in)\n *\n * Third-party stores (Postgres, Redis, etc.) implement this interface.\n *\n * Stores hold per-workspace JSON snapshots, not a decomposed relational\n * model. The Coordinator's snapshot/restore methods produce JSON-safe\n * payloads; this is fast for workspaces in the low-thousands of audit\n * entries and trades query flexibility for simplicity. Production\n * deployments needing rich query semantics should project the audit log\n * into their own analytics store via the `onAudit` listener.\n */\n\nexport interface WorkspaceRecord {\n /** Workspace identifier. */\n id: string;\n /** JSON-serialisable payload produced by `Coordinator.snapshot()`. */\n data: unknown;\n /** Monotonically increasing version for optimistic concurrency. */\n version: number;\n /** Wall-clock timestamp of the last write, ISO-8601. */\n updated_at: string;\n}\n\nexport interface Store {\n /** Load all workspace records into memory. Called once on coordinator start. */\n load(): Promise<WorkspaceRecord[]> | WorkspaceRecord[];\n\n /** Persist one workspace record. Called after every mutation. */\n save(record: WorkspaceRecord): Promise<void> | void;\n\n /** Remove one workspace. Used by `workspace.delete` semantics (not in v0.2). */\n delete(id: string): Promise<void> | void;\n\n /** Release resources. Idempotent. */\n close?(): Promise<void> | void;\n}\n\n/**\n * In-memory store. Default behaviour: no persistence, fast tests.\n * State lives in a Map; closing it discards everything.\n */\nexport class MemoryStore implements Store {\n private records = new Map<string, WorkspaceRecord>();\n\n load(): WorkspaceRecord[] {\n return Array.from(this.records.values());\n }\n\n save(record: WorkspaceRecord): void {\n this.records.set(record.id, record);\n }\n\n delete(id: string): void {\n this.records.delete(id);\n }\n\n close(): void {\n this.records.clear();\n }\n}\n"],"mappings":";AAkDO,IAAM,cAAN,MAAmC;AAAA,EAChC,UAAU,oBAAI,IAA6B;AAAA,EAEnD,OAA0B;AACxB,WAAO,MAAM,KAAK,KAAK,QAAQ,OAAO,CAAC;AAAA,EACzC;AAAA,EAEA,KAAK,QAA+B;AAClC,SAAK,QAAQ,IAAI,OAAO,IAAI,MAAM;AAAA,EACpC;AAAA,EAEA,OAAO,IAAkB;AACvB,SAAK,QAAQ,OAAO,EAAE;AAAA,EACxB;AAAA,EAEA,QAAc;AACZ,SAAK,QAAQ,MAAM;AAAA,EACrB;AACF;","names":[]}
package/dist/types.cjs ADDED
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/types.ts
21
+ var types_exports = {};
22
+ __export(types_exports, {
23
+ modeLE: () => modeLE
24
+ });
25
+ module.exports = __toCommonJS(types_exports);
26
+ function modeLE(a, ceiling) {
27
+ const order = { shadow: 0, trial: 1, production: 2 };
28
+ return order[a] <= order[ceiling];
29
+ }
30
+ // Annotate the CommonJS export names for ESM import in node:
31
+ 0 && (module.exports = {
32
+ modeLE
33
+ });
34
+ //# sourceMappingURL=types.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["/**\n * @brightbeamai/chap-coordinator. type vocabulary\n *\n * Wire-shape and in-memory types for the Coordinator. The schemas at\n * schemas/ are the normative wire types; these mirror them in\n * TypeScript for in-process use.\n */\n\nexport type ParticipantUri = string;\nexport type WorkspaceId = string;\nexport type TaskId = string;\nexport type ArtefactId = string;\n\nexport type ParticipantType = \"human\" | \"agent\" | \"service\" | \"group\" | \"workspace\";\n\nexport interface Envelope {\n jsonrpc: \"2.0\";\n id?: string | number;\n method?: string;\n params?: Record<string, unknown>;\n result?: unknown;\n error?: { code: number; message: string; data?: unknown };\n /** security-signed/1.0: top-level signature, signed over JCS of the\n * envelope with this field removed. Form: ``ed25519:<kid>:<b64>``. */\n sig?: string;\n}\n\nexport type Mode = \"shadow\" | \"trial\" | \"production\";\nexport type WorkspaceState = \"active\" | \"paused\" | \"closed\";\nexport type PauseScope = \"task\" | \"participant\" | \"workspace\";\n\nexport type TaskState =\n | \"created\"\n | \"in_progress\"\n | \"review_requested\"\n | \"completed\"\n | \"declined\"\n | \"abstained\"\n | \"escalated\"\n | \"superseded\"\n | \"paused\"\n | \"cancelled\";\n\n// ============================================================\n// Key records (security-signed/1.0)\n// ============================================================\n\nexport interface Jwk {\n kty: \"OKP\";\n crv: \"Ed25519\";\n kid: string;\n x: string;\n use?: string;\n alg?: string;\n}\n\n/** A participant's JWK plus the validity window. Lookup by\n * (participant, kid, ts) so historical envelopes verify across\n * rotation per security-signed/1.0 S3-S5. */\nexport interface KeyRecord {\n jwk: Jwk;\n kid: string;\n valid_from: string; // ISO timestamp; inclusive\n valid_until?: string; // ISO timestamp; exclusive; absent = unbounded\n revoked_at?: string;\n revoked_reason?: string;\n}\n\n// ============================================================\n// Participants\n// ============================================================\n\nexport interface Member {\n uri: ParticipantUri;\n type: ParticipantType;\n role: string;\n joined: string;\n display_name?: string;\n capabilities?: Record<string, unknown>;\n scopes?: string[];\n keys: KeyRecord[];\n paused: boolean; // control.pause scope=participant\n oidc_sub?: string;\n oidc_auth_time?: number; // unix seconds\n vc_holder?: string;\n}\n\n// ============================================================\n// Routing hints\n// ============================================================\n\nexport interface TaskRoutingHints {\n criticality?: \"low\" | \"medium\" | \"high\" | \"critical\";\n deadline?: string;\n max_cost_usd?: number;\n risk_tier?: string;\n [extra: string]: unknown;\n}\n\nexport interface ArtefactRoutingHints {\n confidence?: number | string;\n model_id?: string;\n cost_consumed_usd?: number;\n latency_ms?: number;\n [extra: string]: unknown;\n}\n\n// ============================================================\n// JSON Patch (RFC 6902)\n// ============================================================\n\nexport interface JsonPatchOp {\n op: \"add\" | \"replace\" | \"remove\" | \"copy\" | \"move\" | \"test\";\n path: string;\n value?: unknown;\n from?: string;\n}\n\n// ============================================================\n// Override artefact (review/1.0)\n// ============================================================\n\nexport interface OverrideArtefact {\n id: ArtefactId;\n task_id: TaskId;\n reviewer: ParticipantUri;\n based_on_artefact: unknown;\n diff: JsonPatchOp[];\n result: unknown;\n rationale: string;\n tags: string[];\n policy_refs: string[];\n ts: string;\n logical_id?: string;\n instance_id?: string;\n intent_preserved?: boolean;\n}\n\n// ============================================================\n// Route decision artefact (routing/1.0)\n// ============================================================\n\nexport interface RouteDecisionArtefact {\n id: ArtefactId;\n kind: \"route_decision\";\n decision_type: \"task.route\" | \"review.depth\" | \"escalate.auto\";\n outcome: unknown;\n produced_by: ParticipantUri;\n produced_at: string;\n task?: TaskId;\n policy_id?: string;\n hints_observed: Record<string, unknown>;\n rationale: string;\n // Auxiliary fields per decision_type:\n // task.route: alternatives_considered\n // review.depth: sampling_probability\n // escalate.auto: escalation_target\n [extra: string]: unknown;\n}\n\n// ============================================================\n// Snapshot artefact (control/1.0)\n// ============================================================\n\nexport interface SnapshotArtefact {\n id: ArtefactId;\n kind: \"snapshot\";\n ts: string;\n by: ParticipantUri;\n workspace: WorkspaceId;\n audit_seq: number;\n label?: string;\n include: string[];\n state: Record<string, unknown>;\n}\n\n// ============================================================\n// Whisper (whisper/1.0)\n// ============================================================\n\nexport interface WhisperPrompt {\n id: ArtefactId;\n task_id: TaskId;\n asker: ParticipantUri;\n askee: ParticipantUri[];\n question: string;\n options?: Array<{ id: string; label?: string }>;\n asked_at: string;\n deadline_ms: number;\n default_if_lapsed: unknown;\n urgency: \"low\" | \"medium\" | \"high\";\n state: \"pending\" | \"answered\" | \"lapsed\";\n answered_at?: string;\n answered_by?: ParticipantUri;\n answer_option?: string;\n answer_text?: string;\n comment?: string;\n default_applied?: unknown;\n}\n\n// ============================================================\n// Deliberation (deliberation/1.0)\n// ============================================================\n\nexport interface DeliberationVote {\n ts: string;\n voter: ParticipantUri;\n vote: \"yea\" | \"nay\" | \"abstain\";\n weight?: number;\n comment?: string;\n veto_invoked?: boolean;\n}\n\nexport interface Deliberation {\n id: string;\n task_id?: TaskId;\n opener: ParticipantUri;\n participants: ParticipantUri[];\n rule: string; // raw rule string\n question?: string;\n weights?: Record<ParticipantUri, number>;\n veto?: Record<ParticipantUri, boolean>;\n deadline?: string;\n state: \"open\" | \"closed\" | \"lapsed\";\n comments: { ts: string; from: ParticipantUri; text: string }[];\n votes: DeliberationVote[];\n outcome?: {\n outcome: \"approved\" | \"rejected\" | \"error\";\n rule: string;\n tally?: { yea: number; nay: number };\n vetoes?: ParticipantUri[];\n reason?: string;\n };\n opened_at: string;\n}\n\n// ============================================================\n// Handoff (handoff/1.0)\n// ============================================================\n\nexport interface HandoffTaskItem {\n task_id: TaskId;\n title?: string;\n status_summary?: string;\n next_action?: string;\n blockers?: string[];\n}\n\nexport interface Handoff {\n id: string;\n proposer: ParticipantUri;\n recipient: ParticipantUri; // single URI or \"group:...\"\n proposed_at: string;\n tasks: HandoffTaskItem[];\n summary?: string;\n context_links: string[];\n state: \"proposed\" | \"accepted\" | \"declined\";\n resolved_at?: string;\n accepted_by?: ParticipantUri;\n accepted_task_ids?: TaskId[];\n accept_comment?: string;\n decline_reason?: string;\n decline_suggested_target?: ParticipantUri;\n}\n\n// ============================================================\n// Review decision (review/1.0)\n// ============================================================\n\nexport interface ReviewDecision {\n reviewer: ParticipantUri;\n kind: \"approve\" | \"reject\" | \"override\" | \"abstain\";\n ts: string;\n comment?: string;\n tags?: string[];\n override_artefact_id?: ArtefactId;\n abstain_category?: string;\n}\n\n// ============================================================\n// Task\n// ============================================================\n\nexport interface Task {\n id: TaskId;\n kind: string;\n state: TaskState;\n assignee: ParticipantUri;\n delegator: ParticipantUri;\n input: Record<string, unknown>;\n output?: unknown;\n confidence?: number | string;\n deadline?: string;\n created_at: string;\n updated_at: string;\n mode: Mode;\n review_required?: boolean;\n routing_hints?: TaskRoutingHints;\n artefact_routing_hints?: ArtefactRoutingHints;\n review?: {\n requested_at: string;\n requested_to: ParticipantUri[];\n rule: string;\n deadline?: string;\n decisions: ReviewDecision[];\n };\n history: { ts: string; from: ParticipantUri; state: TaskState; note?: string }[];\n supersedes?: TaskId;\n superseded_by?: TaskId;\n parent?: TaskId;\n paused: boolean;\n /** Transient: holds the artefact passed to review.request so\n * decide.override can use it as the patch base. */\n pending_artefact?: unknown;\n}\n\n// ============================================================\n// Audit\n// ============================================================\n\nexport interface AuditEntry {\n seq: number;\n arrived: string;\n envelope: Envelope;\n prev_hash?: string;\n}\n\n// ============================================================\n// Workspace\n// ============================================================\n\nexport interface Workspace {\n id: WorkspaceId;\n created: string;\n state: WorkspaceState;\n profiles: string[];\n mode: Mode;\n mode_ceiling: Mode;\n routing_policy_uri?: string;\n step_up_window_sec: number;\n members: Map<ParticipantUri, Member>;\n tasks: Map<TaskId, Task>;\n overrides: Map<ArtefactId, OverrideArtefact>;\n whispers: Map<string, WhisperPrompt>;\n deliberations: Map<string, Deliberation>;\n handoffs: Map<string, Handoff>;\n snapshots: Map<ArtefactId, SnapshotArtefact>;\n route_decisions: Map<ArtefactId, RouteDecisionArtefact>;\n audit: AuditEntry[];\n chain_head?: string;\n chain_enabled: boolean;\n}\n\n/**\n * Listener callback invoked synchronously when an envelope is appended\n * to the workspace audit log.\n */\nexport type AuditListener = (workspace: Workspace, entry: AuditEntry) => void;\n\n/** True iff mode `a` is <= ceiling. */\nexport function modeLE(a: Mode, ceiling: Mode): boolean {\n const order: Record<Mode, number> = { shadow: 0, trial: 1, production: 2 };\n return order[a] <= order[ceiling];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAwWO,SAAS,OAAO,GAAS,SAAwB;AACtD,QAAM,QAA8B,EAAE,QAAQ,GAAG,OAAO,GAAG,YAAY,EAAE;AACzE,SAAO,MAAM,CAAC,KAAK,MAAM,OAAO;AAClC;","names":[]}