usertrust 0.1.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.
Files changed (149) hide show
  1. package/dist/audit/canonical.d.ts +7 -0
  2. package/dist/audit/canonical.d.ts.map +1 -0
  3. package/dist/audit/canonical.js +24 -0
  4. package/dist/audit/canonical.js.map +1 -0
  5. package/dist/audit/chain.d.ts +33 -0
  6. package/dist/audit/chain.d.ts.map +1 -0
  7. package/dist/audit/chain.js +285 -0
  8. package/dist/audit/chain.js.map +1 -0
  9. package/dist/audit/entropy.d.ts +95 -0
  10. package/dist/audit/entropy.d.ts.map +1 -0
  11. package/dist/audit/entropy.js +229 -0
  12. package/dist/audit/entropy.js.map +1 -0
  13. package/dist/audit/merkle.d.ts +87 -0
  14. package/dist/audit/merkle.d.ts.map +1 -0
  15. package/dist/audit/merkle.js +315 -0
  16. package/dist/audit/merkle.js.map +1 -0
  17. package/dist/audit/rotation.d.ts +61 -0
  18. package/dist/audit/rotation.d.ts.map +1 -0
  19. package/dist/audit/rotation.js +160 -0
  20. package/dist/audit/rotation.js.map +1 -0
  21. package/dist/audit/verify.d.ts +20 -0
  22. package/dist/audit/verify.d.ts.map +1 -0
  23. package/dist/audit/verify.js +73 -0
  24. package/dist/audit/verify.js.map +1 -0
  25. package/dist/board/board.d.ts +67 -0
  26. package/dist/board/board.d.ts.map +1 -0
  27. package/dist/board/board.js +191 -0
  28. package/dist/board/board.js.map +1 -0
  29. package/dist/board/concerns.d.ts +59 -0
  30. package/dist/board/concerns.d.ts.map +1 -0
  31. package/dist/board/concerns.js +149 -0
  32. package/dist/board/concerns.js.map +1 -0
  33. package/dist/board/director.d.ts +49 -0
  34. package/dist/board/director.d.ts.map +1 -0
  35. package/dist/board/director.js +127 -0
  36. package/dist/board/director.js.map +1 -0
  37. package/dist/cli/health.d.ts +8 -0
  38. package/dist/cli/health.d.ts.map +1 -0
  39. package/dist/cli/health.js +119 -0
  40. package/dist/cli/health.js.map +1 -0
  41. package/dist/cli/init.d.ts +8 -0
  42. package/dist/cli/init.d.ts.map +1 -0
  43. package/dist/cli/init.js +67 -0
  44. package/dist/cli/init.js.map +1 -0
  45. package/dist/cli/inspect.d.ts +8 -0
  46. package/dist/cli/inspect.d.ts.map +1 -0
  47. package/dist/cli/inspect.js +114 -0
  48. package/dist/cli/inspect.js.map +1 -0
  49. package/dist/cli/main.d.ts +3 -0
  50. package/dist/cli/main.d.ts.map +1 -0
  51. package/dist/cli/main.js +35 -0
  52. package/dist/cli/main.js.map +1 -0
  53. package/dist/cli/snapshot.d.ts +10 -0
  54. package/dist/cli/snapshot.d.ts.map +1 -0
  55. package/dist/cli/snapshot.js +61 -0
  56. package/dist/cli/snapshot.js.map +1 -0
  57. package/dist/cli/tb.d.ts +8 -0
  58. package/dist/cli/tb.d.ts.map +1 -0
  59. package/dist/cli/tb.js +43 -0
  60. package/dist/cli/tb.js.map +1 -0
  61. package/dist/cli/verify.d.ts +7 -0
  62. package/dist/cli/verify.d.ts.map +1 -0
  63. package/dist/cli/verify.js +32 -0
  64. package/dist/cli/verify.js.map +1 -0
  65. package/dist/config.d.ts +12 -0
  66. package/dist/config.d.ts.map +1 -0
  67. package/dist/config.js +34 -0
  68. package/dist/config.js.map +1 -0
  69. package/dist/detect.d.ts +18 -0
  70. package/dist/detect.d.ts.map +1 -0
  71. package/dist/detect.js +49 -0
  72. package/dist/detect.js.map +1 -0
  73. package/dist/govern.d.ts +75 -0
  74. package/dist/govern.d.ts.map +1 -0
  75. package/dist/govern.js +581 -0
  76. package/dist/govern.js.map +1 -0
  77. package/dist/index.d.ts +6 -0
  78. package/dist/index.d.ts.map +1 -0
  79. package/dist/index.js +8 -0
  80. package/dist/index.js.map +1 -0
  81. package/dist/ledger/client.d.ts +89 -0
  82. package/dist/ledger/client.d.ts.map +1 -0
  83. package/dist/ledger/client.js +417 -0
  84. package/dist/ledger/client.js.map +1 -0
  85. package/dist/ledger/engine.d.ts +68 -0
  86. package/dist/ledger/engine.d.ts.map +1 -0
  87. package/dist/ledger/engine.js +142 -0
  88. package/dist/ledger/engine.js.map +1 -0
  89. package/dist/ledger/pricing.d.ts +35 -0
  90. package/dist/ledger/pricing.d.ts.map +1 -0
  91. package/dist/ledger/pricing.js +142 -0
  92. package/dist/ledger/pricing.js.map +1 -0
  93. package/dist/memory/patterns.d.ts +35 -0
  94. package/dist/memory/patterns.d.ts.map +1 -0
  95. package/dist/memory/patterns.js +152 -0
  96. package/dist/memory/patterns.js.map +1 -0
  97. package/dist/policy/decay.d.ts +95 -0
  98. package/dist/policy/decay.d.ts.map +1 -0
  99. package/dist/policy/decay.js +133 -0
  100. package/dist/policy/decay.js.map +1 -0
  101. package/dist/policy/default-rules.d.ts +21 -0
  102. package/dist/policy/default-rules.d.ts.map +1 -0
  103. package/dist/policy/default-rules.js +60 -0
  104. package/dist/policy/default-rules.js.map +1 -0
  105. package/dist/policy/gate.d.ts +116 -0
  106. package/dist/policy/gate.d.ts.map +1 -0
  107. package/dist/policy/gate.js +227 -0
  108. package/dist/policy/gate.js.map +1 -0
  109. package/dist/policy/pii.d.ts +28 -0
  110. package/dist/policy/pii.d.ts.map +1 -0
  111. package/dist/policy/pii.js +124 -0
  112. package/dist/policy/pii.js.map +1 -0
  113. package/dist/proxy.d.ts +33 -0
  114. package/dist/proxy.d.ts.map +1 -0
  115. package/dist/proxy.js +36 -0
  116. package/dist/proxy.js.map +1 -0
  117. package/dist/resilience/circuit.d.ts +87 -0
  118. package/dist/resilience/circuit.d.ts.map +1 -0
  119. package/dist/resilience/circuit.js +167 -0
  120. package/dist/resilience/circuit.js.map +1 -0
  121. package/dist/resilience/scope.d.ts +97 -0
  122. package/dist/resilience/scope.d.ts.map +1 -0
  123. package/dist/resilience/scope.js +244 -0
  124. package/dist/resilience/scope.js.map +1 -0
  125. package/dist/shared/constants.d.ts +7 -0
  126. package/dist/shared/constants.d.ts.map +1 -0
  127. package/dist/shared/constants.js +7 -0
  128. package/dist/shared/constants.js.map +1 -0
  129. package/dist/shared/errors.d.ts +31 -0
  130. package/dist/shared/errors.d.ts.map +1 -0
  131. package/dist/shared/errors.js +61 -0
  132. package/dist/shared/errors.js.map +1 -0
  133. package/dist/shared/ids.d.ts +7 -0
  134. package/dist/shared/ids.d.ts.map +1 -0
  135. package/dist/shared/ids.js +31 -0
  136. package/dist/shared/ids.js.map +1 -0
  137. package/dist/shared/types.d.ts +162 -0
  138. package/dist/shared/types.d.ts.map +1 -0
  139. package/dist/shared/types.js +41 -0
  140. package/dist/shared/types.js.map +1 -0
  141. package/dist/snapshot/checkpoint.d.ts +22 -0
  142. package/dist/snapshot/checkpoint.d.ts.map +1 -0
  143. package/dist/snapshot/checkpoint.js +172 -0
  144. package/dist/snapshot/checkpoint.js.map +1 -0
  145. package/dist/streaming.d.ts +44 -0
  146. package/dist/streaming.d.ts.map +1 -0
  147. package/dist/streaming.js +123 -0
  148. package/dist/streaming.js.map +1 -0
  149. package/package.json +54 -0
@@ -0,0 +1,22 @@
1
+ export interface SnapshotMeta {
2
+ name: string;
3
+ timestamp: string;
4
+ files: string[];
5
+ size: number;
6
+ }
7
+ /**
8
+ * Create a snapshot of the vault state.
9
+ * Captures audit/, policies/, patterns/, usertrust.config.json, and leases.json.
10
+ * Excludes tigerbeetle/, snapshots/, and dlq/.
11
+ */
12
+ export declare function createSnapshot(vaultPath: string, name: string): Promise<SnapshotMeta>;
13
+ /**
14
+ * Restore the vault state from a named snapshot.
15
+ * Overwrites existing files with snapshot contents.
16
+ */
17
+ export declare function restoreSnapshot(vaultPath: string, name: string): Promise<void>;
18
+ /**
19
+ * List all snapshots in the vault, sorted by timestamp (oldest first).
20
+ */
21
+ export declare function listSnapshots(vaultPath: string): Promise<SnapshotMeta[]>;
22
+ //# sourceMappingURL=checkpoint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint.d.ts","sourceRoot":"","sources":["../../src/snapshot/checkpoint.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACb;AA6GD;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA6B3F;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBpF;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CA2B9E"}
@@ -0,0 +1,172 @@
1
+ import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
2
+ import { join, relative, resolve } from "node:path";
3
+ // ── Constants ──
4
+ const SNAPSHOTS_DIR = "snapshots";
5
+ /** Directories to exclude from snapshots */
6
+ const EXCLUDED_DIRS = new Set(["tigerbeetle", "snapshots", "dlq"]);
7
+ /** Files/directories to include in snapshots */
8
+ const INCLUDED_PATHS = new Set([
9
+ "audit",
10
+ "policies",
11
+ "patterns",
12
+ "usertrust.config.json",
13
+ "leases.json",
14
+ ]);
15
+ // ── Internals ──
16
+ /**
17
+ * Recursively collect all files under a directory, returning relative paths.
18
+ */
19
+ async function collectFiles(basePath, currentPath) {
20
+ const results = [];
21
+ let entries;
22
+ try {
23
+ entries = await readdir(currentPath, { withFileTypes: true, encoding: "utf-8" });
24
+ }
25
+ catch {
26
+ return results;
27
+ }
28
+ for (const entry of entries) {
29
+ const fullPath = join(currentPath, entry.name);
30
+ const relPath = relative(basePath, fullPath);
31
+ if (entry.isDirectory()) {
32
+ const nested = await collectFiles(basePath, fullPath);
33
+ results.push(...nested);
34
+ }
35
+ else if (entry.isFile()) {
36
+ results.push(relPath);
37
+ }
38
+ }
39
+ return results;
40
+ }
41
+ /**
42
+ * Gather all files from the vault that should be included in a snapshot.
43
+ */
44
+ async function gatherVaultFiles(vaultPath) {
45
+ const allFiles = [];
46
+ let topEntries;
47
+ try {
48
+ topEntries = await readdir(vaultPath, { withFileTypes: true, encoding: "utf-8" });
49
+ }
50
+ catch {
51
+ return allFiles;
52
+ }
53
+ for (const entry of topEntries) {
54
+ const name = entry.name;
55
+ if (EXCLUDED_DIRS.has(name)) {
56
+ continue;
57
+ }
58
+ if (!INCLUDED_PATHS.has(name)) {
59
+ continue;
60
+ }
61
+ const fullPath = join(vaultPath, name);
62
+ if (entry.isDirectory()) {
63
+ const nested = await collectFiles(vaultPath, fullPath);
64
+ allFiles.push(...nested);
65
+ }
66
+ else if (entry.isFile()) {
67
+ allFiles.push(name);
68
+ }
69
+ }
70
+ return allFiles.sort();
71
+ }
72
+ function snapshotsDir(vaultPath) {
73
+ return join(vaultPath, SNAPSHOTS_DIR);
74
+ }
75
+ function snapshotFilePath(vaultPath, name) {
76
+ return join(snapshotsDir(vaultPath), `${name}.json`);
77
+ }
78
+ function validateSnapshotName(name) {
79
+ if (name.includes("/") ||
80
+ name.includes("\\") ||
81
+ name.includes("..") ||
82
+ name.includes("\0") ||
83
+ name.trim() === "") {
84
+ throw new Error(`Invalid snapshot name: ${name}`);
85
+ }
86
+ }
87
+ // ── Public API ──
88
+ /**
89
+ * Create a snapshot of the vault state.
90
+ * Captures audit/, policies/, patterns/, usertrust.config.json, and leases.json.
91
+ * Excludes tigerbeetle/, snapshots/, and dlq/.
92
+ */
93
+ export async function createSnapshot(vaultPath, name) {
94
+ validateSnapshotName(name);
95
+ const files = await gatherVaultFiles(vaultPath);
96
+ const entries = {};
97
+ let totalSize = 0;
98
+ for (const relPath of files) {
99
+ const fullPath = join(vaultPath, relPath);
100
+ const content = await readFile(fullPath);
101
+ entries[relPath] = content.toString("base64");
102
+ totalSize += content.length;
103
+ }
104
+ const meta = {
105
+ name,
106
+ timestamp: new Date().toISOString(),
107
+ files,
108
+ size: totalSize,
109
+ };
110
+ const payload = { meta, entries };
111
+ const dir = snapshotsDir(vaultPath);
112
+ await mkdir(dir, { recursive: true });
113
+ const filePath = snapshotFilePath(vaultPath, name);
114
+ await writeFile(filePath, JSON.stringify(payload, null, "\t"), "utf-8");
115
+ return meta;
116
+ }
117
+ /**
118
+ * Restore the vault state from a named snapshot.
119
+ * Overwrites existing files with snapshot contents.
120
+ */
121
+ export async function restoreSnapshot(vaultPath, name) {
122
+ validateSnapshotName(name);
123
+ const filePath = snapshotFilePath(vaultPath, name);
124
+ const raw = await readFile(filePath, "utf-8");
125
+ const payload = JSON.parse(raw);
126
+ for (const [relPath, b64Content] of Object.entries(payload.entries)) {
127
+ if (relPath === "" || relPath === ".") {
128
+ throw new Error("Invalid empty path in snapshot entry");
129
+ }
130
+ const fullPath = join(vaultPath, relPath);
131
+ const resolvedPath = resolve(fullPath);
132
+ const resolvedVault = resolve(vaultPath);
133
+ if (!resolvedPath.startsWith(`${resolvedVault}/`)) {
134
+ throw new Error(`Path traversal detected in snapshot: ${relPath}`);
135
+ }
136
+ const dir = join(fullPath, "..");
137
+ await mkdir(dir, { recursive: true });
138
+ const content = Buffer.from(b64Content, "base64");
139
+ await writeFile(fullPath, content);
140
+ }
141
+ }
142
+ /**
143
+ * List all snapshots in the vault, sorted by timestamp (oldest first).
144
+ */
145
+ export async function listSnapshots(vaultPath) {
146
+ const dir = snapshotsDir(vaultPath);
147
+ let dirEntries;
148
+ try {
149
+ dirEntries = await readdir(dir, { withFileTypes: true, encoding: "utf-8" });
150
+ }
151
+ catch {
152
+ return [];
153
+ }
154
+ const metas = [];
155
+ for (const entry of dirEntries) {
156
+ const name = entry.name;
157
+ if (!entry.isFile() || !name.endsWith(".json")) {
158
+ continue;
159
+ }
160
+ try {
161
+ const raw = await readFile(join(dir, name), "utf-8");
162
+ const payload = JSON.parse(raw);
163
+ metas.push(payload.meta);
164
+ }
165
+ catch {
166
+ // Skip corrupt snapshot files
167
+ }
168
+ }
169
+ metas.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
170
+ return metas;
171
+ }
172
+ //# sourceMappingURL=checkpoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoint.js","sourceRoot":"","sources":["../../src/snapshot/checkpoint.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBpD,kBAAkB;AAElB,MAAM,aAAa,GAAG,WAAW,CAAC;AAElC,4CAA4C;AAC5C,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,aAAa,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC;AAEnE,gDAAgD;AAChD,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;IAC9B,OAAO;IACP,UAAU;IACV,UAAU;IACV,uBAAuB;IACvB,aAAa;CACb,CAAC,CAAC;AAEH,kBAAkB;AAElB;;GAEG;AACH,KAAK,UAAU,YAAY,CAAC,QAAgB,EAAE,WAAmB;IAChE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACJ,OAAO,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IAClF,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,OAAO,CAAC;IAChB,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,IAAc,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAE7C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACtD,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QACzB,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;IACF,CAAC;IAED,OAAO,OAAO,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,gBAAgB,CAAC,SAAiB;IAChD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,IAAI,UAAoB,CAAC;IACzB,IAAI,CAAC;QACJ,UAAU,GAAG,MAAM,OAAO,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IACnF,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAc,CAAC;QAClC,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,SAAS;QACV,CAAC;QACD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,SAAS;QACV,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAEvC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YACvD,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QAC1B,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAC3B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;IACF,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;AACxB,CAAC;AAED,SAAS,YAAY,CAAC,SAAiB;IACtC,OAAO,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,gBAAgB,CAAC,SAAiB,EAAE,IAAY;IACxD,OAAO,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC;AACtD,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAY;IACzC,IACC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAClB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QACnB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QACnB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QACnB,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EACjB,CAAC;QACF,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;AACF,CAAC;AAED,mBAAmB;AAEnB;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,SAAiB,EAAE,IAAY;IACnE,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC3B,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAChD,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,KAAK,MAAM,OAAO,IAAI,KAAK,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACzC,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC9C,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,MAAM,IAAI,GAAiB;QAC1B,IAAI;QACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,KAAK;QACL,IAAI,EAAE,SAAS;KACf,CAAC;IAEF,MAAM,OAAO,GAAoB,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAEnD,MAAM,GAAG,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IACpC,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEtC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACnD,MAAM,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;IAExE,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,SAAiB,EAAE,IAAY;IACpE,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAC3B,MAAM,QAAQ,GAAG,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACnD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAoB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoB,CAAC;IAEpE,KAAK,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACrE,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,KAAK,GAAG,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC1C,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QACvC,MAAM,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,aAAa,GAAG,CAAC,EAAE,CAAC;YACnD,MAAM,IAAI,KAAK,CAAC,wCAAwC,OAAO,EAAE,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACjC,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAClD,MAAM,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC;AACF,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAAiB;IACpD,MAAM,GAAG,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IACpC,IAAI,UAAoB,CAAC;IACzB,IAAI,CAAC;QACJ,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IAC7E,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,CAAC;IACX,CAAC;IAED,MAAM,KAAK,GAAmB,EAAE,CAAC;IAEjC,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAc,CAAC;QAClC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAChD,SAAS;QACV,CAAC;QACD,IAAI,CAAC;YACJ,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;YACrD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoB,CAAC;YACnD,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC;YACR,8BAA8B;QAC/B,CAAC;IACF,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC7D,OAAO,KAAK,CAAC;AACd,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * streaming.ts — Streaming Token Accumulator + GovernedStream Factory
3
+ *
4
+ * Per-provider token accumulation for streaming LLM calls. The SDK taps
5
+ * the stream via an async generator that counts tokens without modifying
6
+ * the yielded data.
7
+ *
8
+ * Provider-specific extraction:
9
+ * - Anthropic: message_start (input_tokens), message_delta (output_tokens)
10
+ * - OpenAI: usage field on final chunk (prompt_tokens, completion_tokens)
11
+ * - Google: usageMetadata field (promptTokenCount, candidatesTokenCount)
12
+ *
13
+ * Usage:
14
+ * ```ts
15
+ * const governed = createGovernedStream(stream, "anthropic", resolveGov, rejectGov);
16
+ * for await (const chunk of governed) { process(chunk); }
17
+ * const receipt = await governed.governance;
18
+ * ```
19
+ */
20
+ import type { GovernanceReceipt, LLMClientKind } from "./shared/types.js";
21
+ export interface StreamUsage {
22
+ inputTokens: number;
23
+ outputTokens: number;
24
+ }
25
+ export interface GovernedStream<T> extends AsyncIterable<T> {
26
+ /** Resolves with the governance receipt when the stream completes */
27
+ governance: Promise<GovernanceReceipt>;
28
+ }
29
+ /**
30
+ * Wraps a provider stream with token counting.
31
+ * Yields all chunks unchanged. Calls onComplete with accumulated usage
32
+ * when the stream ends, or onError on failure.
33
+ */
34
+ export declare function wrapStream<T>(stream: AsyncIterable<T>, kind: LLMClientKind, onComplete: (usage: StreamUsage) => void, onError: (error: unknown) => void): AsyncIterable<T>;
35
+ /**
36
+ * Creates a GovernedStream: an AsyncIterable that also exposes a `.governance`
37
+ * promise resolving to the GovernanceReceipt after the stream completes.
38
+ *
39
+ * - `resolveGovernance` is called with final usage when the stream ends.
40
+ * It should POST the actual cost and return the receipt.
41
+ * - `rejectGovernance` is called on stream error. It should VOID the hold.
42
+ */
43
+ export declare function createGovernedStream<T>(stream: AsyncIterable<T>, kind: LLMClientKind, resolveGovernance: (usage: StreamUsage) => Promise<GovernanceReceipt>, rejectGovernance: (error: unknown) => void): GovernedStream<T>;
44
+ //# sourceMappingURL=streaming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../src/streaming.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAI1E,MAAM,WAAW,WAAW;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc,CAAC,CAAC,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC;IAC1D,qEAAqE;IACrE,UAAU,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACvC;AAqDD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAC3B,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EACxB,IAAI,EAAE,aAAa,EACnB,UAAU,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,EACxC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAC/B,aAAa,CAAC,CAAC,CAAC,CAElB;AA6BD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EACrC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EACxB,IAAI,EAAE,aAAa,EACnB,iBAAiB,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,iBAAiB,CAAC,EACrE,gBAAgB,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GACxC,cAAc,CAAC,CAAC,CAAC,CA8BnB"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * streaming.ts — Streaming Token Accumulator + GovernedStream Factory
3
+ *
4
+ * Per-provider token accumulation for streaming LLM calls. The SDK taps
5
+ * the stream via an async generator that counts tokens without modifying
6
+ * the yielded data.
7
+ *
8
+ * Provider-specific extraction:
9
+ * - Anthropic: message_start (input_tokens), message_delta (output_tokens)
10
+ * - OpenAI: usage field on final chunk (prompt_tokens, completion_tokens)
11
+ * - Google: usageMetadata field (promptTokenCount, candidatesTokenCount)
12
+ *
13
+ * Usage:
14
+ * ```ts
15
+ * const governed = createGovernedStream(stream, "anthropic", resolveGov, rejectGov);
16
+ * for await (const chunk of governed) { process(chunk); }
17
+ * const receipt = await governed.governance;
18
+ * ```
19
+ */
20
+ // ── Token extraction ──
21
+ function extractTokensFromChunk(chunk, kind) {
22
+ if (chunk == null || typeof chunk !== "object") {
23
+ return { inputTokens: 0, outputTokens: 0 };
24
+ }
25
+ const c = chunk;
26
+ if (kind === "anthropic") {
27
+ if (c.type === "message_start" && c.message != null && typeof c.message === "object") {
28
+ const msg = c.message;
29
+ if (msg.usage != null && typeof msg.usage === "object") {
30
+ const usage = msg.usage;
31
+ return { inputTokens: usage.input_tokens ?? 0, outputTokens: 0 };
32
+ }
33
+ }
34
+ if (c.type === "message_delta") {
35
+ if (c.usage != null && typeof c.usage === "object") {
36
+ const usage = c.usage;
37
+ return { inputTokens: 0, outputTokens: usage.output_tokens ?? 0 };
38
+ }
39
+ }
40
+ return { inputTokens: 0, outputTokens: 0 };
41
+ }
42
+ if (kind === "openai") {
43
+ if (c.usage != null && typeof c.usage === "object") {
44
+ const usage = c.usage;
45
+ return {
46
+ inputTokens: usage.prompt_tokens ?? 0,
47
+ outputTokens: usage.completion_tokens ?? 0,
48
+ };
49
+ }
50
+ return { inputTokens: 0, outputTokens: 0 };
51
+ }
52
+ // google
53
+ if (c.usageMetadata != null && typeof c.usageMetadata === "object") {
54
+ const meta = c.usageMetadata;
55
+ return {
56
+ inputTokens: meta.promptTokenCount ?? 0,
57
+ outputTokens: meta.candidatesTokenCount ?? 0,
58
+ };
59
+ }
60
+ return { inputTokens: 0, outputTokens: 0 };
61
+ }
62
+ // ── Stream wrapper ──
63
+ /**
64
+ * Wraps a provider stream with token counting.
65
+ * Yields all chunks unchanged. Calls onComplete with accumulated usage
66
+ * when the stream ends, or onError on failure.
67
+ */
68
+ export function wrapStream(stream, kind, onComplete, onError) {
69
+ return wrapStreamImpl(stream, kind, onComplete, onError);
70
+ }
71
+ async function* wrapStreamImpl(stream, kind, onComplete, onError) {
72
+ let inputTokens = 0;
73
+ let outputTokens = 0;
74
+ try {
75
+ for await (const chunk of stream) {
76
+ const tokens = extractTokensFromChunk(chunk, kind);
77
+ // Use latest non-zero value (providers report cumulative or final)
78
+ if (tokens.inputTokens > 0)
79
+ inputTokens = tokens.inputTokens;
80
+ if (tokens.outputTokens > 0)
81
+ outputTokens = tokens.outputTokens;
82
+ yield chunk;
83
+ }
84
+ onComplete({ inputTokens, outputTokens });
85
+ }
86
+ catch (err) {
87
+ onError(err);
88
+ throw err;
89
+ }
90
+ }
91
+ // ── GovernedStream factory ──
92
+ /**
93
+ * Creates a GovernedStream: an AsyncIterable that also exposes a `.governance`
94
+ * promise resolving to the GovernanceReceipt after the stream completes.
95
+ *
96
+ * - `resolveGovernance` is called with final usage when the stream ends.
97
+ * It should POST the actual cost and return the receipt.
98
+ * - `rejectGovernance` is called on stream error. It should VOID the hold.
99
+ */
100
+ export function createGovernedStream(stream, kind, resolveGovernance, rejectGovernance) {
101
+ let governanceResolve;
102
+ let governanceReject;
103
+ const governancePromise = new Promise((resolve, reject) => {
104
+ governanceResolve = resolve;
105
+ governanceReject = reject;
106
+ });
107
+ const wrapped = wrapStream(stream, kind, (usage) => {
108
+ resolveGovernance(usage)
109
+ .then((receipt) => {
110
+ governanceResolve(receipt);
111
+ })
112
+ .catch((err) => {
113
+ governanceReject(err);
114
+ });
115
+ }, (error) => {
116
+ rejectGovernance(error);
117
+ governanceReject(error);
118
+ });
119
+ return Object.assign(wrapped, {
120
+ governance: governancePromise,
121
+ });
122
+ }
123
+ //# sourceMappingURL=streaming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming.js","sourceRoot":"","sources":["../src/streaming.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "usertrust",
3
+ "version": "0.1.0",
4
+ "description": "Financial governance for AI agents. Every LLM call becomes an immutable, auditable transaction.",
5
+ "license": "Apache-2.0",
6
+ "author": "Usertools, Inc. <hello@usertools.ai> (https://usertrust.ai)",
7
+ "homepage": "https://usertrust.ai",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/usertools-ai/usertrust.git",
11
+ "directory": "packages/core"
12
+ },
13
+ "bugs": "https://github.com/usertools-ai/usertrust/issues",
14
+ "keywords": [
15
+ "ai",
16
+ "governance",
17
+ "llm",
18
+ "audit",
19
+ "financial",
20
+ "agent",
21
+ "budget",
22
+ "token",
23
+ "anthropic",
24
+ "openai",
25
+ "tigerbeetle",
26
+ "ledger"
27
+ ],
28
+ "type": "module",
29
+ "main": "dist/index.js",
30
+ "types": "dist/index.d.ts",
31
+ "bin": { "usertrust": "./dist/cli/main.js" },
32
+ "exports": {
33
+ ".": { "import": "./dist/index.js", "types": "./dist/index.d.ts" }
34
+ },
35
+ "dependencies": {
36
+ "tigerbeetle-node": "^0.16.0",
37
+ "minimatch": "^10.0.0",
38
+ "zod": "^3.23.0",
39
+ "yaml": "^2.7.0"
40
+ },
41
+ "scripts": {
42
+ "build": "tsc",
43
+ "prepublishOnly": "tsc"
44
+ },
45
+ "files": ["dist"],
46
+ "peerDependencies": {
47
+ "@anthropic-ai/sdk": ">=0.30.0",
48
+ "openai": ">=4.70.0"
49
+ },
50
+ "peerDependenciesMeta": {
51
+ "@anthropic-ai/sdk": { "optional": true },
52
+ "openai": { "optional": true }
53
+ }
54
+ }