@runcore-sh/runcore 0.1.8 → 0.1.9

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 (173) hide show
  1. package/dist/access/manifest.d.ts +59 -0
  2. package/dist/access/manifest.d.ts.map +1 -0
  3. package/dist/access/manifest.js +251 -0
  4. package/dist/access/manifest.js.map +1 -0
  5. package/dist/activity/log.d.ts +1 -1
  6. package/dist/activity/log.d.ts.map +1 -1
  7. package/dist/agents/autonomous.d.ts.map +1 -1
  8. package/dist/agents/autonomous.js +38 -0
  9. package/dist/agents/autonomous.js.map +1 -1
  10. package/dist/agents/governance.d.ts +70 -0
  11. package/dist/agents/governance.d.ts.map +1 -0
  12. package/dist/agents/governance.js +220 -0
  13. package/dist/agents/governance.js.map +1 -0
  14. package/dist/agents/governed-spawn.d.ts +83 -0
  15. package/dist/agents/governed-spawn.d.ts.map +1 -0
  16. package/dist/agents/governed-spawn.js +186 -0
  17. package/dist/agents/governed-spawn.js.map +1 -0
  18. package/dist/agents/heartbeat.d.ts +91 -0
  19. package/dist/agents/heartbeat.d.ts.map +1 -0
  20. package/dist/agents/heartbeat.js +323 -0
  21. package/dist/agents/heartbeat.js.map +1 -0
  22. package/dist/agents/index.d.ts +4 -1
  23. package/dist/agents/index.d.ts.map +1 -1
  24. package/dist/agents/index.js +6 -1
  25. package/dist/agents/index.js.map +1 -1
  26. package/dist/agents/spawn-policy.d.ts +45 -0
  27. package/dist/agents/spawn-policy.d.ts.map +1 -0
  28. package/dist/agents/spawn-policy.js +202 -0
  29. package/dist/agents/spawn-policy.js.map +1 -0
  30. package/dist/alert.d.ts +16 -0
  31. package/dist/alert.d.ts.map +1 -0
  32. package/dist/alert.js +70 -0
  33. package/dist/alert.js.map +1 -0
  34. package/dist/cli.js +35 -27
  35. package/dist/cli.js.map +1 -1
  36. package/dist/credentials/store.d.ts +1 -1
  37. package/dist/credentials/store.d.ts.map +1 -1
  38. package/dist/credentials/store.js +14 -3
  39. package/dist/credentials/store.js.map +1 -1
  40. package/dist/crystallizer.d.ts +56 -0
  41. package/dist/crystallizer.d.ts.map +1 -0
  42. package/dist/crystallizer.js +159 -0
  43. package/dist/crystallizer.js.map +1 -0
  44. package/dist/distiller.d.ts +48 -0
  45. package/dist/distiller.d.ts.map +1 -0
  46. package/dist/distiller.js +140 -0
  47. package/dist/distiller.js.map +1 -0
  48. package/dist/google/auth.d.ts +2 -0
  49. package/dist/google/auth.d.ts.map +1 -1
  50. package/dist/google/auth.js +2 -0
  51. package/dist/google/auth.js.map +1 -1
  52. package/dist/integrations/gate.d.ts +40 -0
  53. package/dist/integrations/gate.d.ts.map +1 -0
  54. package/dist/integrations/gate.js +100 -0
  55. package/dist/integrations/gate.js.map +1 -0
  56. package/dist/lib/audit.d.ts +43 -0
  57. package/dist/lib/audit.d.ts.map +1 -0
  58. package/dist/lib/audit.js +120 -0
  59. package/dist/lib/audit.js.map +1 -0
  60. package/dist/lib/brain-io.d.ts.map +1 -1
  61. package/dist/lib/brain-io.js +52 -0
  62. package/dist/lib/brain-io.js.map +1 -1
  63. package/dist/lib/dpapi.d.ts +14 -0
  64. package/dist/lib/dpapi.d.ts.map +1 -0
  65. package/dist/lib/dpapi.js +104 -0
  66. package/dist/lib/dpapi.js.map +1 -0
  67. package/dist/lib/glob-match.d.ts +22 -0
  68. package/dist/lib/glob-match.d.ts.map +1 -0
  69. package/dist/lib/glob-match.js +64 -0
  70. package/dist/lib/glob-match.js.map +1 -0
  71. package/dist/lib/locked.d.ts +40 -0
  72. package/dist/lib/locked.d.ts.map +1 -0
  73. package/dist/lib/locked.js +130 -0
  74. package/dist/lib/locked.js.map +1 -0
  75. package/dist/llm/complete.d.ts.map +1 -1
  76. package/dist/llm/complete.js +5 -2
  77. package/dist/llm/complete.js.map +1 -1
  78. package/dist/llm/fetch-guard.d.ts +16 -0
  79. package/dist/llm/fetch-guard.d.ts.map +1 -0
  80. package/dist/llm/fetch-guard.js +61 -0
  81. package/dist/llm/fetch-guard.js.map +1 -0
  82. package/dist/llm/guard.d.ts +40 -0
  83. package/dist/llm/guard.d.ts.map +1 -0
  84. package/dist/llm/guard.js +88 -0
  85. package/dist/llm/guard.js.map +1 -0
  86. package/dist/llm/membrane.d.ts +46 -0
  87. package/dist/llm/membrane.d.ts.map +1 -0
  88. package/dist/llm/membrane.js +123 -0
  89. package/dist/llm/membrane.js.map +1 -0
  90. package/dist/llm/providers/index.d.ts +5 -1
  91. package/dist/llm/providers/index.d.ts.map +1 -1
  92. package/dist/llm/providers/index.js +8 -1
  93. package/dist/llm/providers/index.js.map +1 -1
  94. package/dist/llm/redact.d.ts +39 -0
  95. package/dist/llm/redact.d.ts.map +1 -0
  96. package/dist/llm/redact.js +155 -0
  97. package/dist/llm/redact.js.map +1 -0
  98. package/dist/llm/sensitive-registry.d.ts +33 -0
  99. package/dist/llm/sensitive-registry.d.ts.map +1 -0
  100. package/dist/llm/sensitive-registry.js +106 -0
  101. package/dist/llm/sensitive-registry.js.map +1 -0
  102. package/dist/mcp-server.d.ts +11 -0
  103. package/dist/mcp-server.d.ts.map +1 -0
  104. package/dist/mcp-server.js +520 -0
  105. package/dist/mcp-server.js.map +1 -0
  106. package/dist/mdns.d.ts +17 -0
  107. package/dist/mdns.d.ts.map +1 -0
  108. package/dist/mdns.js +110 -0
  109. package/dist/mdns.js.map +1 -0
  110. package/dist/nerve/push.d.ts +26 -0
  111. package/dist/nerve/push.d.ts.map +1 -0
  112. package/dist/nerve/push.js +170 -0
  113. package/dist/nerve/push.js.map +1 -0
  114. package/dist/nerve/state.d.ts +35 -0
  115. package/dist/nerve/state.d.ts.map +1 -0
  116. package/dist/nerve/state.js +257 -0
  117. package/dist/nerve/state.js.map +1 -0
  118. package/dist/resend/inbox.d.ts +23 -0
  119. package/dist/resend/inbox.d.ts.map +1 -0
  120. package/dist/resend/inbox.js +198 -0
  121. package/dist/resend/inbox.js.map +1 -0
  122. package/dist/resend/webhooks.d.ts +30 -0
  123. package/dist/resend/webhooks.d.ts.map +1 -0
  124. package/dist/resend/webhooks.js +244 -0
  125. package/dist/resend/webhooks.js.map +1 -0
  126. package/dist/server.d.ts +2 -0
  127. package/dist/server.d.ts.map +1 -1
  128. package/dist/server.js +585 -16
  129. package/dist/server.js.map +1 -1
  130. package/dist/settings.d.ts +14 -1
  131. package/dist/settings.d.ts.map +1 -1
  132. package/dist/settings.js +32 -1
  133. package/dist/settings.js.map +1 -1
  134. package/dist/updater.d.ts +32 -0
  135. package/dist/updater.d.ts.map +1 -0
  136. package/dist/updater.js +145 -0
  137. package/dist/updater.js.map +1 -0
  138. package/dist/vault/policy.d.ts +42 -0
  139. package/dist/vault/policy.d.ts.map +1 -0
  140. package/dist/vault/policy.js +159 -0
  141. package/dist/vault/policy.js.map +1 -0
  142. package/dist/vault/store.d.ts +6 -0
  143. package/dist/vault/store.d.ts.map +1 -1
  144. package/dist/vault/store.js +15 -5
  145. package/dist/vault/store.js.map +1 -1
  146. package/dist/vault/transfer.d.ts +33 -0
  147. package/dist/vault/transfer.d.ts.map +1 -0
  148. package/dist/vault/transfer.js +187 -0
  149. package/dist/vault/transfer.js.map +1 -0
  150. package/dist/voucher.d.ts +39 -0
  151. package/dist/voucher.d.ts.map +1 -0
  152. package/dist/voucher.js +105 -0
  153. package/dist/voucher.js.map +1 -0
  154. package/dist/webhooks/handlers.d.ts +10 -0
  155. package/dist/webhooks/handlers.d.ts.map +1 -1
  156. package/dist/webhooks/handlers.js +53 -0
  157. package/dist/webhooks/handlers.js.map +1 -1
  158. package/dist/webhooks/index.d.ts +2 -2
  159. package/dist/webhooks/index.d.ts.map +1 -1
  160. package/dist/webhooks/index.js +2 -2
  161. package/dist/webhooks/index.js.map +1 -1
  162. package/dist/webhooks/verify.d.ts +8 -0
  163. package/dist/webhooks/verify.d.ts.map +1 -1
  164. package/dist/webhooks/verify.js +56 -0
  165. package/dist/webhooks/verify.js.map +1 -1
  166. package/package.json +8 -2
  167. package/public/board.html +8 -3
  168. package/public/browser.html +8 -3
  169. package/public/library.html +8 -3
  170. package/public/observatory.html +8 -3
  171. package/public/ops.html +8 -3
  172. package/public/registry.html +627 -0
  173. package/public/roadmap.html +975 -0
@@ -16,6 +16,10 @@ import { readFileSync, appendFileSync, mkdirSync, existsSync, } from "node:fs";
16
16
  import { dirname } from "node:path";
17
17
  import { createLogger } from "../utils/logger.js";
18
18
  import { getEncryptionKey, getWriteEncryptionKey } from "./key-store.js";
19
+ import { logAccess, logAccessSync } from "./audit.js";
20
+ import { assertNotLocked, toBrainRelativePath } from "./locked.js";
21
+ import { getAuditContext } from "./audit.js";
22
+ import { getManifest, canRead, canWrite } from "../access/manifest.js";
19
23
  const log = createLogger("brain-io");
20
24
  import { shouldEncryptFile } from "./encryption-config.js";
21
25
  import { encryptLine, decryptLine, isEncryptedLine, encryptFile, decryptFile, isEncryptedFile, } from "./encryption.js";
@@ -32,6 +36,37 @@ function writeKey(filePath) {
32
36
  return null;
33
37
  return getWriteEncryptionKey();
34
38
  }
39
+ // ── Access enforcement ───────────────────────────────────────────────────────
40
+ /**
41
+ * Assert that the current instance (from AuditContext) has access to the path.
42
+ * No-op when instanceName is undefined (backward compatible).
43
+ * Checks the instance's access manifest; logs denied access to audit.
44
+ *
45
+ * @param absolutePath - Absolute file path
46
+ * @param operation - "read" or "write"
47
+ */
48
+ function assertAccess(absolutePath, operation) {
49
+ const ctx = getAuditContext();
50
+ if (!ctx?.instanceName)
51
+ return; // No instance context — skip check
52
+ const relPath = toBrainRelativePath(absolutePath);
53
+ if (relPath === null)
54
+ return; // Not a brain path
55
+ const manifest = getManifest(ctx.instanceName);
56
+ if (!manifest)
57
+ return; // No manifest loaded — skip (permissive for unknown instances)
58
+ const allowed = operation === "read"
59
+ ? canRead(manifest, relPath)
60
+ : canWrite(manifest, relPath);
61
+ if (!allowed) {
62
+ log.warn("Access denied by manifest", {
63
+ instance: ctx.instanceName,
64
+ path: relPath,
65
+ operation,
66
+ });
67
+ throw new Error(`Access denied: ${ctx.instanceName} cannot ${operation} ${relPath}`);
68
+ }
69
+ }
35
70
  // ── Async JSONL (per-line) I/O ───────────────────────────────────────────────
36
71
  /**
37
72
  * Read a JSONL file, decrypting each line if needed.
@@ -39,6 +74,9 @@ function writeKey(filePath) {
39
74
  * Empty/whitespace lines are filtered out.
40
75
  */
41
76
  export async function readBrainLines(filePath) {
77
+ assertNotLocked(filePath);
78
+ assertAccess(filePath, "read");
79
+ logAccess(filePath, "readBrainLines");
42
80
  let raw;
43
81
  try {
44
82
  raw = await readFile(filePath, "utf-8");
@@ -68,6 +106,8 @@ export async function readBrainLines(filePath) {
68
106
  * The line should be a JSON string (not newline-terminated).
69
107
  */
70
108
  export async function appendBrainLine(filePath, jsonLine) {
109
+ assertNotLocked(filePath);
110
+ assertAccess(filePath, "write");
71
111
  const key = writeKey(filePath);
72
112
  const line = key ? encryptLine(jsonLine, key) : jsonLine;
73
113
  await appendFile(filePath, line + "\n", "utf-8");
@@ -77,6 +117,8 @@ export async function appendBrainLine(filePath, jsonLine) {
77
117
  * Used for compaction/rotation where the whole file is rewritten.
78
118
  */
79
119
  export async function writeBrainLines(filePath, jsonLines) {
120
+ assertNotLocked(filePath);
121
+ assertAccess(filePath, "write");
80
122
  const key = writeKey(filePath);
81
123
  const output = jsonLines
82
124
  .map((l) => (key ? encryptLine(l, key) : l))
@@ -89,6 +131,9 @@ export async function writeBrainLines(filePath, jsonLines) {
89
131
  * Returns the plaintext content. Falls back to raw content if not encrypted.
90
132
  */
91
133
  export async function readBrainFile(filePath) {
134
+ assertNotLocked(filePath);
135
+ assertAccess(filePath, "read");
136
+ logAccess(filePath, "readBrainFile");
92
137
  const raw = await readFile(filePath, "utf-8");
93
138
  const key = readKey(filePath);
94
139
  if (key && isEncryptedFile(raw)) {
@@ -101,6 +146,8 @@ export async function readBrainFile(filePath) {
101
146
  * Creates parent directories if needed.
102
147
  */
103
148
  export async function writeBrainFile(filePath, content) {
149
+ assertNotLocked(filePath);
150
+ assertAccess(filePath, "write");
104
151
  await mkdir(dirname(filePath), { recursive: true });
105
152
  const key = writeKey(filePath);
106
153
  const output = key ? encryptFile(content, key) : content;
@@ -111,6 +158,9 @@ export async function writeBrainFile(filePath, content) {
111
158
  * Synchronously read a JSONL file, decrypting each line if needed.
112
159
  */
113
160
  export function readBrainLinesSync(filePath) {
161
+ assertNotLocked(filePath);
162
+ assertAccess(filePath, "read");
163
+ logAccessSync(filePath, "readBrainLinesSync");
114
164
  let raw;
115
165
  try {
116
166
  raw = readFileSync(filePath, "utf-8");
@@ -139,6 +189,8 @@ export function readBrainLinesSync(filePath) {
139
189
  * Synchronously append a single line to a JSONL file, encrypting if enabled.
140
190
  */
141
191
  export function appendBrainLineSync(filePath, jsonLine) {
192
+ assertNotLocked(filePath);
193
+ assertAccess(filePath, "write");
142
194
  const key = writeKey(filePath);
143
195
  const line = key ? encryptLine(jsonLine, key) : jsonLine;
144
196
  appendFileSync(filePath, line + "\n", "utf-8");
@@ -1 +1 @@
1
- {"version":3,"file":"brain-io.js","sourceRoot":"","sources":["../../src/lib/brain-io.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"brain-io.js","sourceRoot":"","sources":["../../src/lib/brain-io.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * DPAPI wrapper — encrypts/decrypts data using Windows Data Protection API.
3
+ * Keys are tied to the current Windows user account.
4
+ * Falls back to plaintext on non-Windows or if DPAPI is unavailable.
5
+ */
6
+ /**
7
+ * Read a session key file. Tries DPAPI-protected format first (.dpapi),
8
+ * falls back to plaintext hex. If plaintext found, migrates to DPAPI.
9
+ * Returns the raw key as a Buffer, or null if not found.
10
+ */
11
+ export declare function readSessionKey(keyPath: string): Promise<Buffer | null>;
12
+ /** Check if DPAPI is available on this system. */
13
+ export declare function isDpapiAvailable(): boolean;
14
+ //# sourceMappingURL=dpapi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dpapi.d.ts","sourceRoot":"","sources":["../../src/lib/dpapi.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkDH;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAuC5E;AAED,kDAAkD;AAClD,wBAAgB,gBAAgB,IAAI,OAAO,CAQ1C"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * DPAPI wrapper — encrypts/decrypts data using Windows Data Protection API.
3
+ * Keys are tied to the current Windows user account.
4
+ * Falls back to plaintext on non-Windows or if DPAPI is unavailable.
5
+ */
6
+ import { execSync } from "node:child_process";
7
+ import { readFile, writeFile, realpath } from "node:fs/promises";
8
+ import { existsSync } from "node:fs";
9
+ const IS_WINDOWS = process.platform === "win32";
10
+ /** Encode a PowerShell script as base64 UTF-16LE for -EncodedCommand. */
11
+ function encodePS(script) {
12
+ return Buffer.from(script, "utf16le").toString("base64");
13
+ }
14
+ /** Run a PowerShell script reliably via -EncodedCommand. */
15
+ function runPS(script) {
16
+ const encoded = encodePS(script);
17
+ return execSync(`powershell -NoProfile -EncodedCommand ${encoded}`, { encoding: "utf-8", windowsHide: true }).trim();
18
+ }
19
+ /** DPAPI-protect a Buffer, returns base64-encoded ciphertext. */
20
+ function dpapiProtect(data) {
21
+ const b64Input = data.toString("base64");
22
+ return runPS(`
23
+ Add-Type -AssemblyName System.Security
24
+ $bytes = [Convert]::FromBase64String("${b64Input}")
25
+ $enc = [System.Security.Cryptography.ProtectedData]::Protect(
26
+ $bytes, [byte[]]@(),
27
+ [System.Security.Cryptography.DataProtectionScope]::CurrentUser
28
+ )
29
+ [Convert]::ToBase64String($enc)
30
+ `);
31
+ }
32
+ /** DPAPI-unprotect a base64-encoded ciphertext, returns Buffer. */
33
+ function dpapiUnprotect(b64Ciphertext) {
34
+ const result = runPS(`
35
+ Add-Type -AssemblyName System.Security
36
+ $enc = [Convert]::FromBase64String("${b64Ciphertext}")
37
+ $dec = [System.Security.Cryptography.ProtectedData]::Unprotect(
38
+ $enc, [byte[]]@(),
39
+ [System.Security.Cryptography.DataProtectionScope]::CurrentUser
40
+ )
41
+ [Convert]::ToBase64String($dec)
42
+ `);
43
+ return Buffer.from(result, "base64");
44
+ }
45
+ /**
46
+ * Read a session key file. Tries DPAPI-protected format first (.dpapi),
47
+ * falls back to plaintext hex. If plaintext found, migrates to DPAPI.
48
+ * Returns the raw key as a Buffer, or null if not found.
49
+ */
50
+ export async function readSessionKey(keyPath) {
51
+ // Resolve symlinks so .dpapi file lands next to the real key
52
+ let resolvedPath = keyPath;
53
+ try {
54
+ resolvedPath = await realpath(keyPath);
55
+ }
56
+ catch {
57
+ // realpath fails if file doesn't exist — use original
58
+ }
59
+ const dpapiPath = resolvedPath + ".dpapi";
60
+ // Try DPAPI-protected version first
61
+ if (IS_WINDOWS && existsSync(dpapiPath)) {
62
+ try {
63
+ const b64 = (await readFile(dpapiPath, "utf-8")).trim();
64
+ if (b64.length > 0)
65
+ return dpapiUnprotect(b64);
66
+ }
67
+ catch {
68
+ // DPAPI decrypt failed — fall through to plaintext
69
+ }
70
+ }
71
+ // Try plaintext hex file
72
+ if (!existsSync(resolvedPath))
73
+ return null;
74
+ const hex = (await readFile(resolvedPath, "utf-8")).trim();
75
+ if (!/^[0-9a-f]{64}$/i.test(hex))
76
+ return null;
77
+ const key = Buffer.from(hex, "hex");
78
+ // Migrate: protect with DPAPI and save
79
+ if (IS_WINDOWS) {
80
+ try {
81
+ const protected64 = dpapiProtect(key);
82
+ await writeFile(dpapiPath, protected64, "utf-8");
83
+ // Don't delete the plaintext yet — Dash may still need it
84
+ // until Dash also uses this reader
85
+ }
86
+ catch {
87
+ // DPAPI not available — keep using plaintext
88
+ }
89
+ }
90
+ return key;
91
+ }
92
+ /** Check if DPAPI is available on this system. */
93
+ export function isDpapiAvailable() {
94
+ if (!IS_WINDOWS)
95
+ return false;
96
+ try {
97
+ dpapiProtect(Buffer.from("test"));
98
+ return true;
99
+ }
100
+ catch {
101
+ return false;
102
+ }
103
+ }
104
+ //# sourceMappingURL=dpapi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dpapi.js","sourceRoot":"","sources":["../../src/lib/dpapi.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Minimal glob matcher for brain-relative paths.
3
+ *
4
+ * Supports:
5
+ * - `**` — match any number of path segments (including zero)
6
+ * - `*` — match a single path segment (no slashes)
7
+ * - exact — literal string match
8
+ *
9
+ * No external dependencies. Used by vault policy + access manifests.
10
+ */
11
+ /**
12
+ * Test whether a brain-relative path matches a glob pattern.
13
+ *
14
+ * @param pattern - Glob pattern (e.g. "memory/**", "identity/*.md", "ops/audit.jsonl")
15
+ * @param path - Brain-relative path with forward slashes (e.g. "memory/semantic.jsonl")
16
+ */
17
+ export declare function matchGlob(pattern: string, path: string): boolean;
18
+ /**
19
+ * Test whether a path matches ANY of the given glob patterns.
20
+ */
21
+ export declare function matchAnyGlob(patterns: string[], path: string): boolean;
22
+ //# sourceMappingURL=glob-match.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glob-match.d.ts","sourceRoot":"","sources":["../../src/lib/glob-match.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAqCH;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAIhE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtE"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Minimal glob matcher for brain-relative paths.
3
+ *
4
+ * Supports:
5
+ * - `**` — match any number of path segments (including zero)
6
+ * - `*` — match a single path segment (no slashes)
7
+ * - exact — literal string match
8
+ *
9
+ * No external dependencies. Used by vault policy + access manifests.
10
+ */
11
+ /**
12
+ * Convert a glob pattern to a RegExp.
13
+ * Patterns are matched against forward-slash-normalized brain-relative paths.
14
+ */
15
+ function globToRegex(pattern) {
16
+ // Normalize
17
+ const p = pattern.replace(/\\/g, "/").replace(/\/+$/, "");
18
+ let regex = "^";
19
+ let i = 0;
20
+ while (i < p.length) {
21
+ if (p[i] === "*" && p[i + 1] === "*") {
22
+ // ** — match any depth (including zero segments)
23
+ // Consume trailing slash if present
24
+ i += 2;
25
+ if (p[i] === "/")
26
+ i++;
27
+ regex += "(?:.+/)?";
28
+ }
29
+ else if (p[i] === "*") {
30
+ // * — match single segment (no slashes)
31
+ regex += "[^/]+";
32
+ i++;
33
+ }
34
+ else if (".+?^${}()|[]\\".includes(p[i])) {
35
+ // Escape regex special chars
36
+ regex += "\\" + p[i];
37
+ i++;
38
+ }
39
+ else {
40
+ regex += p[i];
41
+ i++;
42
+ }
43
+ }
44
+ regex += "$";
45
+ return new RegExp(regex);
46
+ }
47
+ /**
48
+ * Test whether a brain-relative path matches a glob pattern.
49
+ *
50
+ * @param pattern - Glob pattern (e.g. "memory/**", "identity/*.md", "ops/audit.jsonl")
51
+ * @param path - Brain-relative path with forward slashes (e.g. "memory/semantic.jsonl")
52
+ */
53
+ export function matchGlob(pattern, path) {
54
+ const normalized = path.replace(/\\/g, "/");
55
+ const re = globToRegex(pattern);
56
+ return re.test(normalized);
57
+ }
58
+ /**
59
+ * Test whether a path matches ANY of the given glob patterns.
60
+ */
61
+ export function matchAnyGlob(patterns, path) {
62
+ return patterns.some((p) => matchGlob(p, path));
63
+ }
64
+ //# sourceMappingURL=glob-match.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glob-match.js","sourceRoot":"","sources":["../../src/lib/glob-match.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;GAGG;AACH,SAAS,WAAW,CAAC,OAAe;IAClC,YAAY;IACZ,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAE1D,IAAI,KAAK,GAAG,GAAG,CAAC;IAChB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;QACpB,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACrC,iDAAiD;YACjD,oCAAoC;YACpC,CAAC,IAAI,CAAC,CAAC;YACP,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG;gBAAE,CAAC,EAAE,CAAC;YACtB,KAAK,IAAI,UAAU,CAAC;QACtB,CAAC;aAAM,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACxB,wCAAwC;YACxC,KAAK,IAAI,OAAO,CAAC;YACjB,CAAC,EAAE,CAAC;QACN,CAAC;aAAM,IAAI,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3C,6BAA6B;YAC7B,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACrB,CAAC,EAAE,CAAC;QACN,CAAC;aAAM,CAAC;YACN,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YACd,CAAC,EAAE,CAAC;QACN,CAAC;IACH,CAAC;IACD,KAAK,IAAI,GAAG,CAAC;IAEb,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,OAAe,EAAE,IAAY;IACrD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC5C,MAAM,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAChC,OAAO,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,QAAkB,EAAE,IAAY;IAC3D,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAClD,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Centralized .locked file enforcement for brain paths.
3
+ *
4
+ * Shared by both MCP server (stdio) and direct file access (brain-io).
5
+ * Ensures locked paths are consistently protected regardless of access channel.
6
+ *
7
+ * Lock rules:
8
+ * - Exact path match (e.g. "identity/human.json")
9
+ * - Filename-only match (e.g. ".session-key" matches "identity/.session-key")
10
+ * - Directory prefix match (e.g. "identity/" matches "identity/foo.md")
11
+ */
12
+ /**
13
+ * Read brain/.locked and merge with hardcoded minimums. Caches result.
14
+ * Safe to call multiple times — returns cached paths after first load.
15
+ */
16
+ export declare function loadLockedPaths(): Promise<string[]>;
17
+ /**
18
+ * Synchronous variant — reads .locked file on first call, caches after.
19
+ */
20
+ export declare function loadLockedPathsSync(): string[];
21
+ /** Force reload of locked paths (e.g. when listing current locks). */
22
+ export declare function reloadLockedPaths(): Promise<string[]>;
23
+ /** Get the currently cached locked paths. Loads synchronously if not yet cached. */
24
+ export declare function getLockedPaths(): string[];
25
+ /**
26
+ * Check if a brain-relative path (forward slashes) is locked.
27
+ * Matches exact paths, filename-only, and directory prefixes.
28
+ */
29
+ export declare function isLocked(relPath: string): boolean;
30
+ /**
31
+ * Convert an absolute file path to a brain-relative path.
32
+ * Returns null if the path is not under brain/.
33
+ */
34
+ export declare function toBrainRelativePath(absolutePath: string): string | null;
35
+ /**
36
+ * Assert that an absolute path is not locked. Throws if locked.
37
+ * No-op for paths outside brain/.
38
+ */
39
+ export declare function assertNotLocked(absolutePath: string): void;
40
+ //# sourceMappingURL=locked.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locked.d.ts","sourceRoot":"","sources":["../../src/lib/locked.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAgBH;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAezD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,EAAE,CAkB9C;AAED,sEAAsE;AACtE,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAG3D;AAED,oFAAoF;AACpF,wBAAgB,cAAc,IAAI,MAAM,EAAE,CAGzC;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAajD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASvE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAM1D"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Centralized .locked file enforcement for brain paths.
3
+ *
4
+ * Shared by both MCP server (stdio) and direct file access (brain-io).
5
+ * Ensures locked paths are consistently protected regardless of access channel.
6
+ *
7
+ * Lock rules:
8
+ * - Exact path match (e.g. "identity/human.json")
9
+ * - Filename-only match (e.g. ".session-key" matches "identity/.session-key")
10
+ * - Directory prefix match (e.g. "identity/" matches "identity/foo.md")
11
+ */
12
+ import { readFile } from "node:fs/promises";
13
+ import { readFileSync, existsSync } from "node:fs";
14
+ import { join, relative, resolve } from "node:path";
15
+ const BRAIN_DIR = resolve(process.cwd(), "brain");
16
+ const LOCKED_FILE = join(BRAIN_DIR, ".locked");
17
+ /** Hardcoded minimum locked paths (always locked even without .locked file). */
18
+ const HARDCODED_LOCKED = [".session-key", "human.json"];
19
+ /** Cached locked paths (relative to brain/, forward slashes). */
20
+ let lockedPaths = [];
21
+ let loaded = false;
22
+ /**
23
+ * Read brain/.locked and merge with hardcoded minimums. Caches result.
24
+ * Safe to call multiple times — returns cached paths after first load.
25
+ */
26
+ export async function loadLockedPaths() {
27
+ const paths = new Set(HARDCODED_LOCKED);
28
+ try {
29
+ const raw = await readFile(LOCKED_FILE, "utf-8");
30
+ for (const line of raw.split("\n")) {
31
+ const trimmed = line.trim();
32
+ if (!trimmed || trimmed.startsWith("#"))
33
+ continue;
34
+ paths.add(trimmed.replace(/\\/g, "/"));
35
+ }
36
+ }
37
+ catch {
38
+ // .locked file doesn't exist — use hardcoded only
39
+ }
40
+ lockedPaths = Array.from(paths);
41
+ loaded = true;
42
+ return lockedPaths;
43
+ }
44
+ /**
45
+ * Synchronous variant — reads .locked file on first call, caches after.
46
+ */
47
+ export function loadLockedPathsSync() {
48
+ if (loaded)
49
+ return lockedPaths;
50
+ const paths = new Set(HARDCODED_LOCKED);
51
+ try {
52
+ if (existsSync(LOCKED_FILE)) {
53
+ const raw = readFileSync(LOCKED_FILE, "utf-8");
54
+ for (const line of raw.split("\n")) {
55
+ const trimmed = line.trim();
56
+ if (!trimmed || trimmed.startsWith("#"))
57
+ continue;
58
+ paths.add(trimmed.replace(/\\/g, "/"));
59
+ }
60
+ }
61
+ }
62
+ catch {
63
+ // .locked file doesn't exist — use hardcoded only
64
+ }
65
+ lockedPaths = Array.from(paths);
66
+ loaded = true;
67
+ return lockedPaths;
68
+ }
69
+ /** Force reload of locked paths (e.g. when listing current locks). */
70
+ export async function reloadLockedPaths() {
71
+ loaded = false;
72
+ return loadLockedPaths();
73
+ }
74
+ /** Get the currently cached locked paths. Loads synchronously if not yet cached. */
75
+ export function getLockedPaths() {
76
+ if (!loaded)
77
+ loadLockedPathsSync();
78
+ return lockedPaths;
79
+ }
80
+ /**
81
+ * Check if a brain-relative path (forward slashes) is locked.
82
+ * Matches exact paths, filename-only, and directory prefixes.
83
+ */
84
+ export function isLocked(relPath) {
85
+ if (!loaded)
86
+ loadLockedPathsSync();
87
+ const normalized = relPath.replace(/\\/g, "/");
88
+ for (const locked of lockedPaths) {
89
+ // Exact match
90
+ if (normalized === locked)
91
+ return true;
92
+ // Filename-only match (e.g. ".session-key" matches "identity/.session-key")
93
+ const filename = normalized.split("/").pop() ?? "";
94
+ if (filename === locked)
95
+ return true;
96
+ // Directory prefix match (e.g. locked="identity/" matches "identity/foo.md")
97
+ if (locked.endsWith("/") && normalized.startsWith(locked))
98
+ return true;
99
+ }
100
+ return false;
101
+ }
102
+ /**
103
+ * Convert an absolute file path to a brain-relative path.
104
+ * Returns null if the path is not under brain/.
105
+ */
106
+ export function toBrainRelativePath(absolutePath) {
107
+ try {
108
+ const rel = relative(BRAIN_DIR, absolutePath);
109
+ // Escapes brain/ — not a brain path
110
+ if (rel.startsWith("..") || rel.startsWith("/"))
111
+ return null;
112
+ return rel.replace(/\\/g, "/");
113
+ }
114
+ catch {
115
+ return null;
116
+ }
117
+ }
118
+ /**
119
+ * Assert that an absolute path is not locked. Throws if locked.
120
+ * No-op for paths outside brain/.
121
+ */
122
+ export function assertNotLocked(absolutePath) {
123
+ const rel = toBrainRelativePath(absolutePath);
124
+ if (rel === null)
125
+ return; // Not a brain path — no lock applies
126
+ if (isLocked(rel)) {
127
+ throw new Error(`🔒 Locked: ${rel} — access denied`);
128
+ }
129
+ }
130
+ //# sourceMappingURL=locked.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locked.js","sourceRoot":"","sources":["../../src/lib/locked.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"complete.d.ts","sourceRoot":"","sources":["../../src/llm/complete.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AASzD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,YAAY,CAAC;IACvB,mCAAmC;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAGhF"}
1
+ {"version":3,"file":"complete.d.ts","sourceRoot":"","sources":["../../src/llm/complete.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAUzD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,YAAY,CAAC;IACvB,mCAAmC;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAGhF"}
@@ -8,6 +8,7 @@ import { getProvider } from "./providers/index.js";
8
8
  import { completeChatCached } from "./cache.js";
9
9
  import { LLMError } from "./errors.js";
10
10
  import { withRetry } from "./retry.js";
11
+ import { rehydrateResponse } from "./redact.js";
11
12
  import { createLogger } from "../utils/logger.js";
12
13
  const log = createLogger("llm");
13
14
  /**
@@ -29,10 +30,11 @@ async function completeChatUncached(options) {
29
30
  messageCount: options.messages.length,
30
31
  });
31
32
  try {
32
- return await withRetry(() => {
33
+ const raw = await withRetry(() => {
33
34
  const timeout = AbortSignal.timeout(60_000);
34
35
  return provider.completeChat(options.messages, options.model, timeout);
35
36
  }, { maxRetries: 3, baseDelayMs: 1_000, maxDelayMs: 30_000 });
37
+ return rehydrateResponse(raw);
36
38
  }
37
39
  catch (err) {
38
40
  // On credit/billing errors from cloud providers, try Ollama as a fallback
@@ -44,10 +46,11 @@ async function completeChatUncached(options) {
44
46
  provider: options.provider,
45
47
  status: err.statusCode,
46
48
  });
47
- return withRetry(() => {
49
+ const fallbackRaw = await withRetry(() => {
48
50
  const fallbackTimeout = AbortSignal.timeout(120_000);
49
51
  return ollama.completeChat(options.messages, undefined, fallbackTimeout);
50
52
  }, { maxRetries: 3, baseDelayMs: 1_000, maxDelayMs: 30_000 });
53
+ return rehydrateResponse(fallbackRaw);
51
54
  }
52
55
  }
53
56
  throw err;
@@ -1 +1 @@
1
- {"version":3,"file":"complete.js","sourceRoot":"","sources":["../../src/llm/complete.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;AAYhC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA4B;IAC7D,IAAI,OAAO,CAAC,OAAO;QAAE,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC1D,OAAO,kBAAkB,CAAC,OAAO,EAAE,oBAAoB,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;AAC/E,CAAC;AAED,2EAA2E;AAC3E,KAAK,UAAU,oBAAoB,CAAC,OAA4B;IAC9D,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAE/C,GAAG,CAAC,KAAK,CAAC,oBAAoB,EAAE;QAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,SAAS;QACjC,YAAY,EAAE,OAAO,CAAC,QAAQ,CAAC,MAAM;KACtC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,OAAO,MAAM,SAAS,CACpB,GAAG,EAAE;YACH,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC5C,OAAO,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACzE,CAAC,EACD,EAAE,UAAU,EAAE,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,CAC1D,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,0EAA0E;QAC1E,IAAI,GAAG,YAAY,QAAQ,IAAI,GAAG,CAAC,cAAc,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACnF,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;YACrC,MAAM,eAAe,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;YACnD,IAAI,eAAe,EAAE,CAAC;gBACpB,GAAG,CAAC,IAAI,CAAC,0DAA0D,EAAE;oBACnE,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,MAAM,EAAE,GAAG,CAAC,UAAU;iBACvB,CAAC,CAAC;gBACH,OAAO,SAAS,CACd,GAAG,EAAE;oBACH,MAAM,eAAe,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;oBACrD,OAAO,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;gBAC3E,CAAC,EACD,EAAE,UAAU,EAAE,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,CAC1D,CAAC;YACJ,CAAC;QACH,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"complete.js","sourceRoot":"","sources":["../../src/llm/complete.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;AAYhC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA4B;IAC7D,IAAI,OAAO,CAAC,OAAO;QAAE,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC1D,OAAO,kBAAkB,CAAC,OAAO,EAAE,oBAAoB,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;AAC/E,CAAC;AAED,2EAA2E;AAC3E,KAAK,UAAU,oBAAoB,CAAC,OAA4B;IAC9D,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAE/C,GAAG,CAAC,KAAK,CAAC,oBAAoB,EAAE;QAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,SAAS;QACjC,YAAY,EAAE,OAAO,CAAC,QAAQ,CAAC,MAAM;KACtC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,SAAS,CACzB,GAAG,EAAE;YACH,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC5C,OAAO,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACzE,CAAC,EACD,EAAE,UAAU,EAAE,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,CAC1D,CAAC;QACF,OAAO,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,0EAA0E;QAC1E,IAAI,GAAG,YAAY,QAAQ,IAAI,GAAG,CAAC,cAAc,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACnF,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;YACrC,MAAM,eAAe,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;YACnD,IAAI,eAAe,EAAE,CAAC;gBACpB,GAAG,CAAC,IAAI,CAAC,0DAA0D,EAAE;oBACnE,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,MAAM,EAAE,GAAG,CAAC,UAAU;iBACvB,CAAC,CAAC;gBACH,MAAM,WAAW,GAAG,MAAM,SAAS,CACjC,GAAG,EAAE;oBACH,MAAM,eAAe,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;oBACrD,OAAO,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;gBAC3E,CAAC,EACD,EAAE,UAAU,EAAE,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,CAC1D,CAAC;gBACF,OAAO,iBAAiB,CAAC,WAAW,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Global fetch interceptor — defense-in-depth for privateMode + sensitive data redaction.
3
+ *
4
+ * Two layers:
5
+ * 1. privateMode enforcement — blocks outbound requests to known cloud LLM API hosts.
6
+ * 2. Sensitive data redaction — strips secrets/PII from LLM request bodies before network egress.
7
+ *
8
+ * The function-level guard in guard.ts → assertProviderAllowed() remains the
9
+ * primary enforcement. This is the safety net.
10
+ */
11
+ /**
12
+ * Monkey-patch globalThis.fetch to block cloud LLM hosts in privateMode.
13
+ * Safe to call multiple times — only installs once.
14
+ */
15
+ export declare function installFetchGuard(): void;
16
+ //# sourceMappingURL=fetch-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-guard.d.ts","sourceRoot":"","sources":["../../src/llm/fetch-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAuBH;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAiCxC"}