@runcore-sh/runcore 0.1.8 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access/manifest.d.ts +59 -0
- package/dist/access/manifest.d.ts.map +1 -0
- package/dist/access/manifest.js +251 -0
- package/dist/access/manifest.js.map +1 -0
- package/dist/activity/log.d.ts +1 -1
- package/dist/activity/log.d.ts.map +1 -1
- package/dist/agents/autonomous.d.ts.map +1 -1
- package/dist/agents/autonomous.js +38 -0
- package/dist/agents/autonomous.js.map +1 -1
- package/dist/agents/governance.d.ts +70 -0
- package/dist/agents/governance.d.ts.map +1 -0
- package/dist/agents/governance.js +220 -0
- package/dist/agents/governance.js.map +1 -0
- package/dist/agents/governed-spawn.d.ts +83 -0
- package/dist/agents/governed-spawn.d.ts.map +1 -0
- package/dist/agents/governed-spawn.js +186 -0
- package/dist/agents/governed-spawn.js.map +1 -0
- package/dist/agents/heartbeat.d.ts +91 -0
- package/dist/agents/heartbeat.d.ts.map +1 -0
- package/dist/agents/heartbeat.js +323 -0
- package/dist/agents/heartbeat.js.map +1 -0
- package/dist/agents/index.d.ts +4 -1
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +6 -1
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/spawn-policy.d.ts +45 -0
- package/dist/agents/spawn-policy.d.ts.map +1 -0
- package/dist/agents/spawn-policy.js +202 -0
- package/dist/agents/spawn-policy.js.map +1 -0
- package/dist/alert.d.ts +16 -0
- package/dist/alert.d.ts.map +1 -0
- package/dist/alert.js +70 -0
- package/dist/alert.js.map +1 -0
- package/dist/cli.js +261 -32
- package/dist/cli.js.map +1 -1
- package/dist/credentials/store.d.ts +1 -1
- package/dist/credentials/store.d.ts.map +1 -1
- package/dist/credentials/store.js +14 -3
- package/dist/credentials/store.js.map +1 -1
- package/dist/crystallizer.d.ts +56 -0
- package/dist/crystallizer.d.ts.map +1 -0
- package/dist/crystallizer.js +159 -0
- package/dist/crystallizer.js.map +1 -0
- package/dist/distiller.d.ts +48 -0
- package/dist/distiller.d.ts.map +1 -0
- package/dist/distiller.js +140 -0
- package/dist/distiller.js.map +1 -0
- package/dist/files/deep-index.d.ts +59 -0
- package/dist/files/deep-index.d.ts.map +1 -0
- package/dist/files/deep-index.js +337 -0
- package/dist/files/deep-index.js.map +1 -0
- package/dist/files/import.d.ts +44 -0
- package/dist/files/import.d.ts.map +1 -0
- package/dist/files/import.js +213 -0
- package/dist/files/import.js.map +1 -0
- package/dist/files/index-local.d.ts +37 -0
- package/dist/files/index-local.d.ts.map +1 -0
- package/dist/files/index-local.js +198 -0
- package/dist/files/index-local.js.map +1 -0
- package/dist/google/auth.d.ts +2 -0
- package/dist/google/auth.d.ts.map +1 -1
- package/dist/google/auth.js +2 -0
- package/dist/google/auth.js.map +1 -1
- package/dist/integrations/gate.d.ts +40 -0
- package/dist/integrations/gate.d.ts.map +1 -0
- package/dist/integrations/gate.js +100 -0
- package/dist/integrations/gate.js.map +1 -0
- package/dist/lib/audit.d.ts +43 -0
- package/dist/lib/audit.d.ts.map +1 -0
- package/dist/lib/audit.js +120 -0
- package/dist/lib/audit.js.map +1 -0
- package/dist/lib/brain-io.d.ts.map +1 -1
- package/dist/lib/brain-io.js +52 -0
- package/dist/lib/brain-io.js.map +1 -1
- package/dist/lib/dpapi.d.ts +14 -0
- package/dist/lib/dpapi.d.ts.map +1 -0
- package/dist/lib/dpapi.js +104 -0
- package/dist/lib/dpapi.js.map +1 -0
- package/dist/lib/glob-match.d.ts +22 -0
- package/dist/lib/glob-match.d.ts.map +1 -0
- package/dist/lib/glob-match.js +64 -0
- package/dist/lib/glob-match.js.map +1 -0
- package/dist/lib/locked.d.ts +40 -0
- package/dist/lib/locked.d.ts.map +1 -0
- package/dist/lib/locked.js +130 -0
- package/dist/lib/locked.js.map +1 -0
- package/dist/llm/complete.d.ts.map +1 -1
- package/dist/llm/complete.js +5 -2
- package/dist/llm/complete.js.map +1 -1
- package/dist/llm/fetch-guard.d.ts +16 -0
- package/dist/llm/fetch-guard.d.ts.map +1 -0
- package/dist/llm/fetch-guard.js +61 -0
- package/dist/llm/fetch-guard.js.map +1 -0
- package/dist/llm/guard.d.ts +40 -0
- package/dist/llm/guard.d.ts.map +1 -0
- package/dist/llm/guard.js +88 -0
- package/dist/llm/guard.js.map +1 -0
- package/dist/llm/membrane.d.ts +46 -0
- package/dist/llm/membrane.d.ts.map +1 -0
- package/dist/llm/membrane.js +123 -0
- package/dist/llm/membrane.js.map +1 -0
- package/dist/llm/providers/index.d.ts +5 -1
- package/dist/llm/providers/index.d.ts.map +1 -1
- package/dist/llm/providers/index.js +8 -1
- package/dist/llm/providers/index.js.map +1 -1
- package/dist/llm/redact.d.ts +39 -0
- package/dist/llm/redact.d.ts.map +1 -0
- package/dist/llm/redact.js +155 -0
- package/dist/llm/redact.js.map +1 -0
- package/dist/llm/sensitive-registry.d.ts +33 -0
- package/dist/llm/sensitive-registry.d.ts.map +1 -0
- package/dist/llm/sensitive-registry.js +106 -0
- package/dist/llm/sensitive-registry.js.map +1 -0
- package/dist/mcp-server.d.ts +11 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +520 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/mdns.d.ts +17 -0
- package/dist/mdns.d.ts.map +1 -0
- package/dist/mdns.js +110 -0
- package/dist/mdns.js.map +1 -0
- package/dist/nerve/push.d.ts +26 -0
- package/dist/nerve/push.d.ts.map +1 -0
- package/dist/nerve/push.js +170 -0
- package/dist/nerve/push.js.map +1 -0
- package/dist/nerve/state.d.ts +35 -0
- package/dist/nerve/state.d.ts.map +1 -0
- package/dist/nerve/state.js +257 -0
- package/dist/nerve/state.js.map +1 -0
- package/dist/posture/engine.d.ts +41 -0
- package/dist/posture/engine.d.ts.map +1 -0
- package/dist/posture/engine.js +217 -0
- package/dist/posture/engine.js.map +1 -0
- package/dist/posture/index.d.ts +11 -0
- package/dist/posture/index.d.ts.map +1 -0
- package/dist/posture/index.js +10 -0
- package/dist/posture/index.js.map +1 -0
- package/dist/posture/middleware.d.ts +30 -0
- package/dist/posture/middleware.d.ts.map +1 -0
- package/dist/posture/middleware.js +92 -0
- package/dist/posture/middleware.js.map +1 -0
- package/dist/posture/types.d.ts +61 -0
- package/dist/posture/types.d.ts.map +1 -0
- package/dist/posture/types.js +48 -0
- package/dist/posture/types.js.map +1 -0
- package/dist/resend/inbox.d.ts +23 -0
- package/dist/resend/inbox.d.ts.map +1 -0
- package/dist/resend/inbox.js +198 -0
- package/dist/resend/inbox.js.map +1 -0
- package/dist/resend/webhooks.d.ts +30 -0
- package/dist/resend/webhooks.d.ts.map +1 -0
- package/dist/resend/webhooks.js +244 -0
- package/dist/resend/webhooks.js.map +1 -0
- package/dist/server.d.ts +5 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +773 -58
- package/dist/server.js.map +1 -1
- package/dist/settings.d.ts +14 -1
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +32 -1
- package/dist/settings.js.map +1 -1
- package/dist/tier/bond.d.ts +51 -0
- package/dist/tier/bond.d.ts.map +1 -0
- package/dist/tier/bond.js +154 -0
- package/dist/tier/bond.js.map +1 -0
- package/dist/tier/freeze.d.ts +21 -0
- package/dist/tier/freeze.d.ts.map +1 -0
- package/dist/tier/freeze.js +73 -0
- package/dist/tier/freeze.js.map +1 -0
- package/dist/tier/gate.d.ts +11 -0
- package/dist/tier/gate.d.ts.map +1 -0
- package/dist/tier/gate.js +25 -0
- package/dist/tier/gate.js.map +1 -0
- package/dist/tier/heartbeat.d.ts +22 -0
- package/dist/tier/heartbeat.d.ts.map +1 -0
- package/dist/tier/heartbeat.js +128 -0
- package/dist/tier/heartbeat.js.map +1 -0
- package/dist/tier/token.d.ts +22 -0
- package/dist/tier/token.d.ts.map +1 -0
- package/dist/tier/token.js +100 -0
- package/dist/tier/token.js.map +1 -0
- package/dist/tier/types.d.ts +44 -0
- package/dist/tier/types.d.ts.map +1 -0
- package/dist/tier/types.js +61 -0
- package/dist/tier/types.js.map +1 -0
- package/dist/updater.d.ts +32 -0
- package/dist/updater.d.ts.map +1 -0
- package/dist/updater.js +145 -0
- package/dist/updater.js.map +1 -0
- package/dist/vault/policy.d.ts +42 -0
- package/dist/vault/policy.d.ts.map +1 -0
- package/dist/vault/policy.js +159 -0
- package/dist/vault/policy.js.map +1 -0
- package/dist/vault/store.d.ts +6 -0
- package/dist/vault/store.d.ts.map +1 -1
- package/dist/vault/store.js +15 -5
- package/dist/vault/store.js.map +1 -1
- package/dist/vault/transfer.d.ts +33 -0
- package/dist/vault/transfer.d.ts.map +1 -0
- package/dist/vault/transfer.js +187 -0
- package/dist/vault/transfer.js.map +1 -0
- package/dist/voucher.d.ts +39 -0
- package/dist/voucher.d.ts.map +1 -0
- package/dist/voucher.js +105 -0
- package/dist/voucher.js.map +1 -0
- package/dist/webhooks/handlers.d.ts +10 -0
- package/dist/webhooks/handlers.d.ts.map +1 -1
- package/dist/webhooks/handlers.js +53 -0
- package/dist/webhooks/handlers.js.map +1 -1
- package/dist/webhooks/index.d.ts +2 -2
- package/dist/webhooks/index.d.ts.map +1 -1
- package/dist/webhooks/index.js +2 -2
- package/dist/webhooks/index.js.map +1 -1
- package/dist/webhooks/verify.d.ts +8 -0
- package/dist/webhooks/verify.d.ts.map +1 -1
- package/dist/webhooks/verify.js +56 -0
- package/dist/webhooks/verify.js.map +1 -1
- package/package.json +8 -2
- package/public/board.html +8 -3
- package/public/browser.html +8 -3
- package/public/library.html +8 -3
- package/public/observatory.html +8 -3
- package/public/ops.html +8 -3
- package/public/registry.html +627 -0
- package/public/roadmap.html +975 -0
|
@@ -6,6 +6,7 @@ import { openRouterProvider } from "./openrouter.js";
|
|
|
6
6
|
import { anthropicProvider } from "./anthropic.js";
|
|
7
7
|
import { openAIProvider } from "./openai.js";
|
|
8
8
|
import { ollamaProvider } from "./ollama.js";
|
|
9
|
+
import { assertProviderAllowed } from "../guard.js";
|
|
9
10
|
import { createLogger } from "../../utils/logger.js";
|
|
10
11
|
const log = createLogger("llm.providers");
|
|
11
12
|
// ── Registry ────────────────────────────────────────────────────────────────
|
|
@@ -15,8 +16,13 @@ const providers = new Map([
|
|
|
15
16
|
["openai", openAIProvider],
|
|
16
17
|
["ollama", ollamaProvider],
|
|
17
18
|
]);
|
|
18
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* Get a provider by name. Throws if unknown.
|
|
21
|
+
* Enforces privateMode — cloud providers are blocked when private mode is on.
|
|
22
|
+
*/
|
|
19
23
|
export function getProvider(name) {
|
|
24
|
+
// Guard: block cloud providers in private mode BEFORE returning the provider
|
|
25
|
+
assertProviderAllowed(name);
|
|
20
26
|
const provider = providers.get(name);
|
|
21
27
|
if (!provider)
|
|
22
28
|
throw new Error(`Unknown LLM provider: ${name}`);
|
|
@@ -44,4 +50,5 @@ export { anthropicProvider } from "./anthropic.js";
|
|
|
44
50
|
export { openAIProvider } from "./openai.js";
|
|
45
51
|
export { ollamaProvider } from "./ollama.js";
|
|
46
52
|
export { LLMError, classifyApiError } from "../errors.js";
|
|
53
|
+
export { PrivateModeError, isPrivateMode } from "../guard.js";
|
|
47
54
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/llm/providers/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,MAAM,GAAG,GAAG,YAAY,CAAC,eAAe,CAAC,CAAC;AAE1C,+EAA+E;AAE/E,MAAM,SAAS,GAAG,IAAI,GAAG,CAA4B;IACnD,CAAC,YAAY,EAAE,kBAAkB,CAAC;IAClC,CAAC,WAAW,EAAE,iBAAiB,CAAC;IAChC,CAAC,QAAQ,EAAE,cAAc,CAAC;IAC1B,CAAC,QAAQ,EAAE,cAAc,CAAC;CAC3B,CAAC,CAAC;AAEH
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/llm/providers/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,MAAM,GAAG,GAAG,YAAY,CAAC,eAAe,CAAC,CAAC;AAE1C,+EAA+E;AAE/E,MAAM,SAAS,GAAG,IAAI,GAAG,CAA4B;IACnD,CAAC,YAAY,EAAE,kBAAkB,CAAC;IAClC,CAAC,WAAW,EAAE,iBAAiB,CAAC;IAChC,CAAC,QAAQ,EAAE,cAAc,CAAC;IAC1B,CAAC,QAAQ,EAAE,cAAc,CAAC;CAC3B,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,IAAkB;IAC5C,6EAA6E;IAC7E,qBAAqB,CAAC,IAAI,CAAC,CAAC;IAE5B,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC;IAChE,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,gBAAgB,CAAC,QAAqB;IACpD,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACvC,GAAG,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,aAAa;IAC3B,OAAO,CAAC,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;AAC/B,CAAC;AAED,qFAAqF;AACrF,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,CAAC,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE;QACtD,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC/C,OAAO,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACjC,CAAC,CAAC,CACH,CAAC;IACF,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAqB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;AAC9D,CAAC;AAKD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sensitive data redaction for outbound LLM requests.
|
|
3
|
+
* Pattern-based detection — if it looks like a secret, redact it before network egress.
|
|
4
|
+
* Runs inside the fetch guard, after message assembly, before the wire.
|
|
5
|
+
*
|
|
6
|
+
* When a PrivacyMembrane is active, delegates to it for reversible typed-placeholder
|
|
7
|
+
* redaction. Falls back to one-way [REDACTED:category] replacement otherwise.
|
|
8
|
+
*/
|
|
9
|
+
import type { PrivacyMembrane } from "./membrane.js";
|
|
10
|
+
/** Set the active PrivacyMembrane for reversible redaction. */
|
|
11
|
+
export declare function setActiveMembrane(membrane: PrivacyMembrane): void;
|
|
12
|
+
/** Get the active membrane (or null if none). */
|
|
13
|
+
export declare function getActiveMembrane(): PrivacyMembrane | null;
|
|
14
|
+
/**
|
|
15
|
+
* Rehydrate placeholders in an LLM response back to original values.
|
|
16
|
+
* No-op if no membrane is active.
|
|
17
|
+
*/
|
|
18
|
+
export declare function rehydrateResponse(text: string): string;
|
|
19
|
+
/** Track redaction stats per request for audit logging. */
|
|
20
|
+
interface RedactionStats {
|
|
21
|
+
totalRedactions: number;
|
|
22
|
+
categories: Record<string, number>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Redact sensitive patterns from a string (one-way fallback).
|
|
26
|
+
* Returns the cleaned string and stats about what was redacted.
|
|
27
|
+
*/
|
|
28
|
+
export declare function redactSensitive(text: string): {
|
|
29
|
+
cleaned: string;
|
|
30
|
+
stats: RedactionStats;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Redact sensitive data from an LLM request body (JSON string).
|
|
34
|
+
* When a membrane is active, delegates to it for reversible redaction.
|
|
35
|
+
* Otherwise falls back to one-way pattern replacement.
|
|
36
|
+
*/
|
|
37
|
+
export declare function redactRequestBody(bodyStr: string): string;
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=redact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../../src/llm/redact.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AASrD,+DAA+D;AAC/D,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAGjE;AAED,iDAAiD;AACjD,wBAAgB,iBAAiB,IAAI,eAAe,GAAG,IAAI,CAE1D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGtD;AAoCD,2DAA2D;AAC3D,UAAU,cAAc;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,cAAc,CAAA;CAAE,CA0BxF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAqEzD"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sensitive data redaction for outbound LLM requests.
|
|
3
|
+
* Pattern-based detection — if it looks like a secret, redact it before network egress.
|
|
4
|
+
* Runs inside the fetch guard, after message assembly, before the wire.
|
|
5
|
+
*
|
|
6
|
+
* When a PrivacyMembrane is active, delegates to it for reversible typed-placeholder
|
|
7
|
+
* redaction. Falls back to one-way [REDACTED:category] replacement otherwise.
|
|
8
|
+
*/
|
|
9
|
+
import { createLogger } from "../utils/logger.js";
|
|
10
|
+
const log = createLogger("llm.redact");
|
|
11
|
+
// --- Active membrane (singleton, set at startup) ---
|
|
12
|
+
let activeMembrane = null;
|
|
13
|
+
/** Set the active PrivacyMembrane for reversible redaction. */
|
|
14
|
+
export function setActiveMembrane(membrane) {
|
|
15
|
+
activeMembrane = membrane;
|
|
16
|
+
log.info("PrivacyMembrane activated");
|
|
17
|
+
}
|
|
18
|
+
/** Get the active membrane (or null if none). */
|
|
19
|
+
export function getActiveMembrane() {
|
|
20
|
+
return activeMembrane;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Rehydrate placeholders in an LLM response back to original values.
|
|
24
|
+
* No-op if no membrane is active.
|
|
25
|
+
*/
|
|
26
|
+
export function rehydrateResponse(text) {
|
|
27
|
+
if (!activeMembrane)
|
|
28
|
+
return text;
|
|
29
|
+
return activeMembrane.rehydrate(text);
|
|
30
|
+
}
|
|
31
|
+
// --- One-way fallback (original behavior) ---
|
|
32
|
+
/** Placeholder for redacted content. Includes the category so the LLM knows what was removed. */
|
|
33
|
+
function placeholder(category) {
|
|
34
|
+
return `[REDACTED:${category}]`;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Redaction rules: [pattern, category, description].
|
|
38
|
+
* Order matters — more specific patterns first to avoid partial matches.
|
|
39
|
+
*/
|
|
40
|
+
const RULES = [
|
|
41
|
+
// SSN: 123-45-6789 or 123 45 6789
|
|
42
|
+
[/\b\d{3}[-\s]\d{2}[-\s]\d{4}\b/g, "SSN"],
|
|
43
|
+
// Credit card: 13-19 digits, optionally grouped by spaces or dashes
|
|
44
|
+
[/\b(?:\d[ -]*?){13,19}\b/g, "CARD"],
|
|
45
|
+
// API keys: common prefixes (sk-, pk-, api-, key-, token_)
|
|
46
|
+
[/\b(?:sk|pk|api|key|token)[_-][A-Za-z0-9_-]{20,}\b/g, "API_KEY"],
|
|
47
|
+
// Bearer tokens in content (not headers — those are legitimate)
|
|
48
|
+
[/\bBearer\s+[A-Za-z0-9_.-]{20,}\b/g, "BEARER_TOKEN"],
|
|
49
|
+
// AWS access keys: AKIA + 16 alphanumeric
|
|
50
|
+
[/\bAKIA[0-9A-Z]{16}\b/g, "AWS_KEY"],
|
|
51
|
+
// Private keys (PEM blocks)
|
|
52
|
+
[/-----BEGIN\s+(RSA\s+)?PRIVATE\s+KEY-----[\s\S]*?-----END\s+(RSA\s+)?PRIVATE\s+KEY-----/g, "PRIVATE_KEY"],
|
|
53
|
+
// Generic long hex/base64 secrets (40+ chars, likely tokens)
|
|
54
|
+
[/\b[A-Fa-f0-9]{40,}\b/g, "HEX_SECRET"],
|
|
55
|
+
];
|
|
56
|
+
/**
|
|
57
|
+
* Redact sensitive patterns from a string (one-way fallback).
|
|
58
|
+
* Returns the cleaned string and stats about what was redacted.
|
|
59
|
+
*/
|
|
60
|
+
export function redactSensitive(text) {
|
|
61
|
+
const stats = { totalRedactions: 0, categories: {} };
|
|
62
|
+
let cleaned = text;
|
|
63
|
+
for (const [pattern, category] of RULES) {
|
|
64
|
+
// Reset lastIndex for global patterns
|
|
65
|
+
pattern.lastIndex = 0;
|
|
66
|
+
const matches = cleaned.match(pattern);
|
|
67
|
+
if (matches) {
|
|
68
|
+
// Filter out false positives: skip short numeric sequences for CARD rule
|
|
69
|
+
const validMatches = category === "CARD"
|
|
70
|
+
? matches.filter((m) => m.replace(/[\s-]/g, "").length >= 13)
|
|
71
|
+
: matches;
|
|
72
|
+
if (validMatches.length > 0) {
|
|
73
|
+
for (const match of validMatches) {
|
|
74
|
+
cleaned = cleaned.replace(match, placeholder(category));
|
|
75
|
+
}
|
|
76
|
+
stats.totalRedactions += validMatches.length;
|
|
77
|
+
stats.categories[category] = (stats.categories[category] ?? 0) + validMatches.length;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
pattern.lastIndex = 0;
|
|
81
|
+
}
|
|
82
|
+
return { cleaned, stats };
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Redact sensitive data from an LLM request body (JSON string).
|
|
86
|
+
* When a membrane is active, delegates to it for reversible redaction.
|
|
87
|
+
* Otherwise falls back to one-way pattern replacement.
|
|
88
|
+
*/
|
|
89
|
+
export function redactRequestBody(bodyStr) {
|
|
90
|
+
let parsed;
|
|
91
|
+
try {
|
|
92
|
+
parsed = JSON.parse(bodyStr);
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return bodyStr; // not JSON, pass through
|
|
96
|
+
}
|
|
97
|
+
// Only process if it looks like an LLM API request (has messages array)
|
|
98
|
+
const messages = parsed.messages;
|
|
99
|
+
if (!Array.isArray(messages))
|
|
100
|
+
return bodyStr;
|
|
101
|
+
// Delegate to membrane when active (reversible typed placeholders)
|
|
102
|
+
if (activeMembrane) {
|
|
103
|
+
for (const msg of messages) {
|
|
104
|
+
if (typeof msg.content === "string") {
|
|
105
|
+
msg.content = activeMembrane.apply(msg.content);
|
|
106
|
+
}
|
|
107
|
+
if (Array.isArray(msg.content)) {
|
|
108
|
+
for (const block of msg.content) {
|
|
109
|
+
if (block.type === "text" && typeof block.text === "string") {
|
|
110
|
+
block.text = activeMembrane.apply(block.text);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return JSON.stringify(parsed);
|
|
116
|
+
}
|
|
117
|
+
// Fallback: one-way redaction
|
|
118
|
+
let totalRedactions = 0;
|
|
119
|
+
const allCategories = {};
|
|
120
|
+
for (const msg of messages) {
|
|
121
|
+
if (typeof msg.content === "string") {
|
|
122
|
+
const { cleaned, stats } = redactSensitive(msg.content);
|
|
123
|
+
if (stats.totalRedactions > 0) {
|
|
124
|
+
msg.content = cleaned;
|
|
125
|
+
totalRedactions += stats.totalRedactions;
|
|
126
|
+
for (const [cat, count] of Object.entries(stats.categories)) {
|
|
127
|
+
allCategories[cat] = (allCategories[cat] ?? 0) + count;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Handle Anthropic-style content blocks: [{ type: "text", text: "..." }]
|
|
132
|
+
if (Array.isArray(msg.content)) {
|
|
133
|
+
for (const block of msg.content) {
|
|
134
|
+
if (block.type === "text" && typeof block.text === "string") {
|
|
135
|
+
const { cleaned, stats } = redactSensitive(block.text);
|
|
136
|
+
if (stats.totalRedactions > 0) {
|
|
137
|
+
block.text = cleaned;
|
|
138
|
+
totalRedactions += stats.totalRedactions;
|
|
139
|
+
for (const [cat, count] of Object.entries(stats.categories)) {
|
|
140
|
+
allCategories[cat] = (allCategories[cat] ?? 0) + count;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (totalRedactions > 0) {
|
|
148
|
+
log.warn("Redacted sensitive data from outbound LLM request", {
|
|
149
|
+
redactions: totalRedactions,
|
|
150
|
+
categories: allCategories,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
return JSON.stringify(parsed);
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=redact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.js","sourceRoot":"","sources":["../../src/llm/redact.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SensitiveRegistry — loads sensitive terms from brain/knowledge/sensitive.yaml
|
|
3
|
+
* plus built-in pattern rules (SSN, cards, API keys, etc.).
|
|
4
|
+
*
|
|
5
|
+
* Terms are sorted longest-first so longer matches take priority.
|
|
6
|
+
* Hand-rolled YAML parse — no external dependency.
|
|
7
|
+
*/
|
|
8
|
+
export interface SensitiveTerm {
|
|
9
|
+
value: string;
|
|
10
|
+
category: string;
|
|
11
|
+
}
|
|
12
|
+
export interface SensitivePattern {
|
|
13
|
+
pattern: RegExp;
|
|
14
|
+
category: string;
|
|
15
|
+
}
|
|
16
|
+
export declare class SensitiveRegistry {
|
|
17
|
+
private terms;
|
|
18
|
+
private customPatterns;
|
|
19
|
+
private loaded;
|
|
20
|
+
/** All built-in + custom regex patterns. */
|
|
21
|
+
get patterns(): SensitivePattern[];
|
|
22
|
+
/** All explicit terms, sorted longest-first. */
|
|
23
|
+
get sensitiveTerms(): SensitiveTerm[];
|
|
24
|
+
/** Load sensitive.yaml from brain/knowledge/. Graceful if missing. */
|
|
25
|
+
load(brainRoot: string): Promise<void>;
|
|
26
|
+
get isLoaded(): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Hand-rolled YAML parser for our simple format.
|
|
29
|
+
* Expects a list of entries with `value`, `category`, and optionally `pattern` fields.
|
|
30
|
+
*/
|
|
31
|
+
private parseYaml;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=sensitive-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sensitive-registry.d.ts","sourceRoot":"","sources":["../../src/llm/sensitive-registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAaD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,cAAc,CAA0B;IAChD,OAAO,CAAC,MAAM,CAAS;IAEvB,4CAA4C;IAC5C,IAAI,QAAQ,IAAI,gBAAgB,EAAE,CAEjC;IAED,gDAAgD;IAChD,IAAI,cAAc,IAAI,aAAa,EAAE,CAEpC;IAED,sEAAsE;IAChE,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB5C,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED;;;OAGG;IACH,OAAO,CAAC,SAAS;CA2ClB"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SensitiveRegistry — loads sensitive terms from brain/knowledge/sensitive.yaml
|
|
3
|
+
* plus built-in pattern rules (SSN, cards, API keys, etc.).
|
|
4
|
+
*
|
|
5
|
+
* Terms are sorted longest-first so longer matches take priority.
|
|
6
|
+
* Hand-rolled YAML parse — no external dependency.
|
|
7
|
+
*/
|
|
8
|
+
import { readFile } from "node:fs/promises";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { createLogger } from "../utils/logger.js";
|
|
11
|
+
const log = createLogger("llm.sensitive-registry");
|
|
12
|
+
/** Built-in patterns — carried over from redact.ts */
|
|
13
|
+
const BUILTIN_PATTERNS = [
|
|
14
|
+
{ pattern: /\b\d{3}[-\s]\d{2}[-\s]\d{4}\b/g, category: "SSN" },
|
|
15
|
+
{ pattern: /\b(?:\d[ -]*?){13,19}\b/g, category: "CARD" },
|
|
16
|
+
{ pattern: /\b(?:sk|pk|api|key|token)[_-][A-Za-z0-9_-]{20,}\b/g, category: "API_KEY" },
|
|
17
|
+
{ pattern: /\bBearer\s+[A-Za-z0-9_.-]{20,}\b/g, category: "BEARER_TOKEN" },
|
|
18
|
+
{ pattern: /\bAKIA[0-9A-Z]{16}\b/g, category: "AWS_KEY" },
|
|
19
|
+
{ pattern: /-----BEGIN\s+(RSA\s+)?PRIVATE\s+KEY-----[\s\S]*?-----END\s+(RSA\s+)?PRIVATE\s+KEY-----/g, category: "PRIVATE_KEY" },
|
|
20
|
+
{ pattern: /\b[A-Fa-f0-9]{40,}\b/g, category: "HEX_SECRET" },
|
|
21
|
+
];
|
|
22
|
+
export class SensitiveRegistry {
|
|
23
|
+
terms = [];
|
|
24
|
+
customPatterns = [];
|
|
25
|
+
loaded = false;
|
|
26
|
+
/** All built-in + custom regex patterns. */
|
|
27
|
+
get patterns() {
|
|
28
|
+
return [...BUILTIN_PATTERNS, ...this.customPatterns];
|
|
29
|
+
}
|
|
30
|
+
/** All explicit terms, sorted longest-first. */
|
|
31
|
+
get sensitiveTerms() {
|
|
32
|
+
return this.terms;
|
|
33
|
+
}
|
|
34
|
+
/** Load sensitive.yaml from brain/knowledge/. Graceful if missing. */
|
|
35
|
+
async load(brainRoot) {
|
|
36
|
+
const filePath = join(brainRoot, "knowledge", "sensitive.yaml");
|
|
37
|
+
try {
|
|
38
|
+
const raw = await readFile(filePath, "utf-8");
|
|
39
|
+
this.parseYaml(raw);
|
|
40
|
+
this.loaded = true;
|
|
41
|
+
log.info("Loaded sensitive registry", {
|
|
42
|
+
terms: this.terms.length,
|
|
43
|
+
customPatterns: this.customPatterns.length,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
if (err.code === "ENOENT") {
|
|
48
|
+
log.debug("No sensitive.yaml found — using built-in patterns only");
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
log.warn("Failed to parse sensitive.yaml — using built-in patterns only", { error: err.message });
|
|
52
|
+
}
|
|
53
|
+
this.loaded = true; // graceful degradation
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
get isLoaded() {
|
|
57
|
+
return this.loaded;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Hand-rolled YAML parser for our simple format.
|
|
61
|
+
* Expects a list of entries with `value`, `category`, and optionally `pattern` fields.
|
|
62
|
+
*/
|
|
63
|
+
parseYaml(raw) {
|
|
64
|
+
const terms = [];
|
|
65
|
+
const customPatterns = [];
|
|
66
|
+
// Split into entries by "- " at start of line (top-level list items)
|
|
67
|
+
const entries = raw.split(/^(?=\s*- )/m).filter((s) => s.trim());
|
|
68
|
+
for (const entry of entries) {
|
|
69
|
+
const lines = entry.split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
70
|
+
let value;
|
|
71
|
+
let category;
|
|
72
|
+
let pattern;
|
|
73
|
+
for (const line of lines) {
|
|
74
|
+
// Strip leading "- " for the first field in a list item
|
|
75
|
+
const cleaned = line.replace(/^-\s*/, "");
|
|
76
|
+
const kvMatch = cleaned.match(/^(\w+)\s*:\s*(.+)$/);
|
|
77
|
+
if (!kvMatch)
|
|
78
|
+
continue;
|
|
79
|
+
const [, key, val] = kvMatch;
|
|
80
|
+
const unquoted = val.replace(/^["']|["']$/g, "").trim();
|
|
81
|
+
if (key === "value")
|
|
82
|
+
value = unquoted;
|
|
83
|
+
else if (key === "category")
|
|
84
|
+
category = unquoted;
|
|
85
|
+
else if (key === "pattern")
|
|
86
|
+
pattern = unquoted;
|
|
87
|
+
}
|
|
88
|
+
if (pattern && category) {
|
|
89
|
+
try {
|
|
90
|
+
customPatterns.push({ pattern: new RegExp(pattern, "g"), category: category.toUpperCase() });
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
log.warn("Invalid regex in sensitive.yaml", { pattern, category });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else if (value && category) {
|
|
97
|
+
terms.push({ value, category: category.toUpperCase() });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// Sort terms longest-first so longer matches take priority
|
|
101
|
+
terms.sort((a, b) => b.value.length - a.value.length);
|
|
102
|
+
this.terms = terms;
|
|
103
|
+
this.customPatterns = customPatterns;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=sensitive-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sensitive-registry.js","sourceRoot":"","sources":["../../src/llm/sensitive-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Core Brain MCP Server — exposes Brain memory and knowledge to Claude Code.
|
|
4
|
+
* stdio-only transport. No network port. All logging to stderr.
|
|
5
|
+
*
|
|
6
|
+
* Tools: memory_retrieve, memory_learn, memory_list, read_brain_file,
|
|
7
|
+
* get_settings, list_locked, list_rooms
|
|
8
|
+
* Resources: brain://memory/*, brain://identity, brain://operations
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=mcp-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG"}
|