governance-sdk 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +559 -0
- package/dist/agent-identity-ed25519.d.ts +80 -0
- package/dist/agent-identity-ed25519.d.ts.map +1 -0
- package/dist/agent-identity-ed25519.js +134 -0
- package/dist/agent-identity-ed25519.js.map +1 -0
- package/dist/agent-identity.d.ts +65 -0
- package/dist/agent-identity.d.ts.map +1 -0
- package/dist/agent-identity.js +85 -0
- package/dist/agent-identity.js.map +1 -0
- package/dist/audit-integrity.d.ts +78 -0
- package/dist/audit-integrity.d.ts.map +1 -0
- package/dist/audit-integrity.js +173 -0
- package/dist/audit-integrity.js.map +1 -0
- package/dist/behavioral-scorer.d.ts +72 -0
- package/dist/behavioral-scorer.d.ts.map +1 -0
- package/dist/behavioral-scorer.js +223 -0
- package/dist/behavioral-scorer.js.map +1 -0
- package/dist/cli/init.d.ts +11 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +217 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/compliance-articles.d.ts +71 -0
- package/dist/compliance-articles.d.ts.map +1 -0
- package/dist/compliance-articles.js +201 -0
- package/dist/compliance-articles.js.map +1 -0
- package/dist/compliance.d.ts +24 -0
- package/dist/compliance.d.ts.map +1 -0
- package/dist/compliance.js +183 -0
- package/dist/compliance.js.map +1 -0
- package/dist/conditions/builtins.d.ts +17 -0
- package/dist/conditions/builtins.d.ts.map +1 -0
- package/dist/conditions/builtins.js +213 -0
- package/dist/conditions/builtins.js.map +1 -0
- package/dist/conditions/postprocess.d.ts +12 -0
- package/dist/conditions/postprocess.d.ts.map +1 -0
- package/dist/conditions/postprocess.js +33 -0
- package/dist/conditions/postprocess.js.map +1 -0
- package/dist/conditions/preprocess.d.ts +12 -0
- package/dist/conditions/preprocess.d.ts.map +1 -0
- package/dist/conditions/preprocess.js +47 -0
- package/dist/conditions/preprocess.js.map +1 -0
- package/dist/conditions/process.d.ts +14 -0
- package/dist/conditions/process.d.ts.map +1 -0
- package/dist/conditions/process.js +78 -0
- package/dist/conditions/process.js.map +1 -0
- package/dist/conditions/sensitive-patterns.d.ts +13 -0
- package/dist/conditions/sensitive-patterns.d.ts.map +1 -0
- package/dist/conditions/sensitive-patterns.js +42 -0
- package/dist/conditions/sensitive-patterns.js.map +1 -0
- package/dist/dry-run.d.ts +85 -0
- package/dist/dry-run.d.ts.map +1 -0
- package/dist/dry-run.js +132 -0
- package/dist/dry-run.js.map +1 -0
- package/dist/eval-red-team.d.ts +69 -0
- package/dist/eval-red-team.d.ts.map +1 -0
- package/dist/eval-red-team.js +205 -0
- package/dist/eval-red-team.js.map +1 -0
- package/dist/eval-scorer.d.ts +56 -0
- package/dist/eval-scorer.d.ts.map +1 -0
- package/dist/eval-scorer.js +148 -0
- package/dist/eval-scorer.js.map +1 -0
- package/dist/eval-trace.d.ts +30 -0
- package/dist/eval-trace.d.ts.map +1 -0
- package/dist/eval-trace.js +129 -0
- package/dist/eval-trace.js.map +1 -0
- package/dist/eval-types.d.ts +108 -0
- package/dist/eval-types.d.ts.map +1 -0
- package/dist/eval-types.js +14 -0
- package/dist/eval-types.js.map +1 -0
- package/dist/events.d.ts +57 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +81 -0
- package/dist/events.js.map +1 -0
- package/dist/federation-types.d.ts +58 -0
- package/dist/federation-types.d.ts.map +1 -0
- package/dist/federation-types.js +8 -0
- package/dist/federation-types.js.map +1 -0
- package/dist/federation.d.ts +42 -0
- package/dist/federation.d.ts.map +1 -0
- package/dist/federation.js +158 -0
- package/dist/federation.js.map +1 -0
- package/dist/index.d.ts +142 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +273 -0
- package/dist/index.js.map +1 -0
- package/dist/injection-benchmark.d.ts +62 -0
- package/dist/injection-benchmark.d.ts.map +1 -0
- package/dist/injection-benchmark.js +201 -0
- package/dist/injection-benchmark.js.map +1 -0
- package/dist/injection-classifier.d.ts +69 -0
- package/dist/injection-classifier.d.ts.map +1 -0
- package/dist/injection-classifier.js +98 -0
- package/dist/injection-classifier.js.map +1 -0
- package/dist/injection-detect.d.ts +59 -0
- package/dist/injection-detect.d.ts.map +1 -0
- package/dist/injection-detect.js +175 -0
- package/dist/injection-detect.js.map +1 -0
- package/dist/injection-patterns-ext.d.ts +7 -0
- package/dist/injection-patterns-ext.d.ts.map +1 -0
- package/dist/injection-patterns-ext.js +71 -0
- package/dist/injection-patterns-ext.js.map +1 -0
- package/dist/injection-patterns.d.ts +15 -0
- package/dist/injection-patterns.d.ts.map +1 -0
- package/dist/injection-patterns.js +361 -0
- package/dist/injection-patterns.js.map +1 -0
- package/dist/iso-42001-articles.d.ts +34 -0
- package/dist/iso-42001-articles.d.ts.map +1 -0
- package/dist/iso-42001-articles.js +147 -0
- package/dist/iso-42001-articles.js.map +1 -0
- package/dist/iso-42001.d.ts +18 -0
- package/dist/iso-42001.d.ts.map +1 -0
- package/dist/iso-42001.js +156 -0
- package/dist/iso-42001.js.map +1 -0
- package/dist/kill-switch.d.ts +56 -0
- package/dist/kill-switch.d.ts.map +1 -0
- package/dist/kill-switch.js +173 -0
- package/dist/kill-switch.js.map +1 -0
- package/dist/metrics.d.ts +58 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +81 -0
- package/dist/metrics.js.map +1 -0
- package/dist/monorepo-detect.d.ts +30 -0
- package/dist/monorepo-detect.d.ts.map +1 -0
- package/dist/monorepo-detect.js +107 -0
- package/dist/monorepo-detect.js.map +1 -0
- package/dist/nist-ai-rmf-articles.d.ts +40 -0
- package/dist/nist-ai-rmf-articles.d.ts.map +1 -0
- package/dist/nist-ai-rmf-articles.js +156 -0
- package/dist/nist-ai-rmf-articles.js.map +1 -0
- package/dist/nist-ai-rmf.d.ts +20 -0
- package/dist/nist-ai-rmf.d.ts.map +1 -0
- package/dist/nist-ai-rmf.js +176 -0
- package/dist/nist-ai-rmf.js.map +1 -0
- package/dist/otel-hooks.d.ts +67 -0
- package/dist/otel-hooks.d.ts.map +1 -0
- package/dist/otel-hooks.js +100 -0
- package/dist/otel-hooks.js.map +1 -0
- package/dist/owasp-agentic-articles.d.ts +42 -0
- package/dist/owasp-agentic-articles.d.ts.map +1 -0
- package/dist/owasp-agentic-articles.js +236 -0
- package/dist/owasp-agentic-articles.js.map +1 -0
- package/dist/owasp-agentic.d.ts +20 -0
- package/dist/owasp-agentic.d.ts.map +1 -0
- package/dist/owasp-agentic.js +205 -0
- package/dist/owasp-agentic.js.map +1 -0
- package/dist/plugins/a2a-types.d.ts +241 -0
- package/dist/plugins/a2a-types.d.ts.map +1 -0
- package/dist/plugins/a2a-types.js +14 -0
- package/dist/plugins/a2a-types.js.map +1 -0
- package/dist/plugins/a2a.d.ts +37 -0
- package/dist/plugins/a2a.d.ts.map +1 -0
- package/dist/plugins/a2a.js +160 -0
- package/dist/plugins/a2a.js.map +1 -0
- package/dist/plugins/anthropic-types.d.ts +188 -0
- package/dist/plugins/anthropic-types.d.ts.map +1 -0
- package/dist/plugins/anthropic-types.js +8 -0
- package/dist/plugins/anthropic-types.js.map +1 -0
- package/dist/plugins/anthropic.d.ts +32 -0
- package/dist/plugins/anthropic.d.ts.map +1 -0
- package/dist/plugins/anthropic.js +131 -0
- package/dist/plugins/anthropic.js.map +1 -0
- package/dist/plugins/autogen-types.d.ts +121 -0
- package/dist/plugins/autogen-types.d.ts.map +1 -0
- package/dist/plugins/autogen-types.js +13 -0
- package/dist/plugins/autogen-types.js.map +1 -0
- package/dist/plugins/autogen.d.ts +41 -0
- package/dist/plugins/autogen.d.ts.map +1 -0
- package/dist/plugins/autogen.js +131 -0
- package/dist/plugins/autogen.js.map +1 -0
- package/dist/plugins/bedrock-types.d.ts +246 -0
- package/dist/plugins/bedrock-types.d.ts.map +1 -0
- package/dist/plugins/bedrock-types.js +8 -0
- package/dist/plugins/bedrock-types.js.map +1 -0
- package/dist/plugins/bedrock.d.ts +43 -0
- package/dist/plugins/bedrock.d.ts.map +1 -0
- package/dist/plugins/bedrock.js +155 -0
- package/dist/plugins/bedrock.js.map +1 -0
- package/dist/plugins/cloudflare-ai-types.d.ts +85 -0
- package/dist/plugins/cloudflare-ai-types.d.ts.map +1 -0
- package/dist/plugins/cloudflare-ai-types.js +10 -0
- package/dist/plugins/cloudflare-ai-types.js.map +1 -0
- package/dist/plugins/cloudflare-ai.d.ts +32 -0
- package/dist/plugins/cloudflare-ai.d.ts.map +1 -0
- package/dist/plugins/cloudflare-ai.js +108 -0
- package/dist/plugins/cloudflare-ai.js.map +1 -0
- package/dist/plugins/composio-types.d.ts +96 -0
- package/dist/plugins/composio-types.d.ts.map +1 -0
- package/dist/plugins/composio-types.js +13 -0
- package/dist/plugins/composio-types.js.map +1 -0
- package/dist/plugins/composio.d.ts +37 -0
- package/dist/plugins/composio.d.ts.map +1 -0
- package/dist/plugins/composio.js +118 -0
- package/dist/plugins/composio.js.map +1 -0
- package/dist/plugins/crewai-types.d.ts +153 -0
- package/dist/plugins/crewai-types.d.ts.map +1 -0
- package/dist/plugins/crewai-types.js +10 -0
- package/dist/plugins/crewai-types.js.map +1 -0
- package/dist/plugins/crewai.d.ts +37 -0
- package/dist/plugins/crewai.d.ts.map +1 -0
- package/dist/plugins/crewai.js +127 -0
- package/dist/plugins/crewai.js.map +1 -0
- package/dist/plugins/deno-types.d.ts +68 -0
- package/dist/plugins/deno-types.d.ts.map +1 -0
- package/dist/plugins/deno-types.js +8 -0
- package/dist/plugins/deno-types.js.map +1 -0
- package/dist/plugins/deno.d.ts +37 -0
- package/dist/plugins/deno.d.ts.map +1 -0
- package/dist/plugins/deno.js +129 -0
- package/dist/plugins/deno.js.map +1 -0
- package/dist/plugins/e2b-types.d.ts +140 -0
- package/dist/plugins/e2b-types.d.ts.map +1 -0
- package/dist/plugins/e2b-types.js +8 -0
- package/dist/plugins/e2b-types.js.map +1 -0
- package/dist/plugins/e2b.d.ts +43 -0
- package/dist/plugins/e2b.d.ts.map +1 -0
- package/dist/plugins/e2b.js +157 -0
- package/dist/plugins/e2b.js.map +1 -0
- package/dist/plugins/genkit-types.d.ts +88 -0
- package/dist/plugins/genkit-types.d.ts.map +1 -0
- package/dist/plugins/genkit-types.js +11 -0
- package/dist/plugins/genkit-types.js.map +1 -0
- package/dist/plugins/genkit.d.ts +35 -0
- package/dist/plugins/genkit.d.ts.map +1 -0
- package/dist/plugins/genkit.js +143 -0
- package/dist/plugins/genkit.js.map +1 -0
- package/dist/plugins/langchain.d.ts +130 -0
- package/dist/plugins/langchain.d.ts.map +1 -0
- package/dist/plugins/langchain.js +172 -0
- package/dist/plugins/langchain.js.map +1 -0
- package/dist/plugins/llamaindex-types.d.ts +86 -0
- package/dist/plugins/llamaindex-types.d.ts.map +1 -0
- package/dist/plugins/llamaindex-types.js +11 -0
- package/dist/plugins/llamaindex-types.js.map +1 -0
- package/dist/plugins/llamaindex.d.ts +36 -0
- package/dist/plugins/llamaindex.d.ts.map +1 -0
- package/dist/plugins/llamaindex.js +131 -0
- package/dist/plugins/llamaindex.js.map +1 -0
- package/dist/plugins/mastra-processor-types.d.ts +126 -0
- package/dist/plugins/mastra-processor-types.d.ts.map +1 -0
- package/dist/plugins/mastra-processor-types.js +11 -0
- package/dist/plugins/mastra-processor-types.js.map +1 -0
- package/dist/plugins/mastra-processor.d.ts +32 -0
- package/dist/plugins/mastra-processor.d.ts.map +1 -0
- package/dist/plugins/mastra-processor.js +126 -0
- package/dist/plugins/mastra-processor.js.map +1 -0
- package/dist/plugins/mastra.d.ts +100 -0
- package/dist/plugins/mastra.d.ts.map +1 -0
- package/dist/plugins/mastra.js +143 -0
- package/dist/plugins/mastra.js.map +1 -0
- package/dist/plugins/mcp-annotations.d.ts +54 -0
- package/dist/plugins/mcp-annotations.d.ts.map +1 -0
- package/dist/plugins/mcp-annotations.js +110 -0
- package/dist/plugins/mcp-annotations.js.map +1 -0
- package/dist/plugins/mcp-chain-audit.d.ts +74 -0
- package/dist/plugins/mcp-chain-audit.d.ts.map +1 -0
- package/dist/plugins/mcp-chain-audit.js +134 -0
- package/dist/plugins/mcp-chain-audit.js.map +1 -0
- package/dist/plugins/mcp-trust.d.ts +59 -0
- package/dist/plugins/mcp-trust.d.ts.map +1 -0
- package/dist/plugins/mcp-trust.js +100 -0
- package/dist/plugins/mcp-trust.js.map +1 -0
- package/dist/plugins/mcp-types.d.ts +183 -0
- package/dist/plugins/mcp-types.d.ts.map +1 -0
- package/dist/plugins/mcp-types.js +12 -0
- package/dist/plugins/mcp-types.js.map +1 -0
- package/dist/plugins/mcp.d.ts +41 -0
- package/dist/plugins/mcp.d.ts.map +1 -0
- package/dist/plugins/mcp.js +228 -0
- package/dist/plugins/mcp.js.map +1 -0
- package/dist/plugins/mistral-types.d.ts +72 -0
- package/dist/plugins/mistral-types.d.ts.map +1 -0
- package/dist/plugins/mistral-types.js +8 -0
- package/dist/plugins/mistral-types.js.map +1 -0
- package/dist/plugins/mistral.d.ts +32 -0
- package/dist/plugins/mistral.d.ts.map +1 -0
- package/dist/plugins/mistral.js +133 -0
- package/dist/plugins/mistral.js.map +1 -0
- package/dist/plugins/ollama-types.d.ts +76 -0
- package/dist/plugins/ollama-types.d.ts.map +1 -0
- package/dist/plugins/ollama-types.js +8 -0
- package/dist/plugins/ollama-types.js.map +1 -0
- package/dist/plugins/ollama.d.ts +32 -0
- package/dist/plugins/ollama.d.ts.map +1 -0
- package/dist/plugins/ollama.js +130 -0
- package/dist/plugins/ollama.js.map +1 -0
- package/dist/plugins/openai-agents-types.d.ts +130 -0
- package/dist/plugins/openai-agents-types.d.ts.map +1 -0
- package/dist/plugins/openai-agents-types.js +12 -0
- package/dist/plugins/openai-agents-types.js.map +1 -0
- package/dist/plugins/openai-agents.d.ts +37 -0
- package/dist/plugins/openai-agents.d.ts.map +1 -0
- package/dist/plugins/openai-agents.js +151 -0
- package/dist/plugins/openai-agents.js.map +1 -0
- package/dist/plugins/semantic-kernel-types.d.ts +103 -0
- package/dist/plugins/semantic-kernel-types.d.ts.map +1 -0
- package/dist/plugins/semantic-kernel-types.js +13 -0
- package/dist/plugins/semantic-kernel-types.js.map +1 -0
- package/dist/plugins/semantic-kernel.d.ts +37 -0
- package/dist/plugins/semantic-kernel.d.ts.map +1 -0
- package/dist/plugins/semantic-kernel.js +149 -0
- package/dist/plugins/semantic-kernel.js.map +1 -0
- package/dist/plugins/vercel-ai.d.ts +134 -0
- package/dist/plugins/vercel-ai.d.ts.map +1 -0
- package/dist/plugins/vercel-ai.js +130 -0
- package/dist/plugins/vercel-ai.js.map +1 -0
- package/dist/policy-builder.d.ts +52 -0
- package/dist/policy-builder.d.ts.map +1 -0
- package/dist/policy-builder.js +108 -0
- package/dist/policy-builder.js.map +1 -0
- package/dist/policy-compose-presets.d.ts +18 -0
- package/dist/policy-compose-presets.d.ts.map +1 -0
- package/dist/policy-compose-presets.js +52 -0
- package/dist/policy-compose-presets.js.map +1 -0
- package/dist/policy-compose.d.ts +66 -0
- package/dist/policy-compose.d.ts.map +1 -0
- package/dist/policy-compose.js +163 -0
- package/dist/policy-compose.js.map +1 -0
- package/dist/policy-presets-extended.d.ts +35 -0
- package/dist/policy-presets-extended.d.ts.map +1 -0
- package/dist/policy-presets-extended.js +137 -0
- package/dist/policy-presets-extended.js.map +1 -0
- package/dist/policy-presets.d.ts +77 -0
- package/dist/policy-presets.d.ts.map +1 -0
- package/dist/policy-presets.js +164 -0
- package/dist/policy-presets.js.map +1 -0
- package/dist/policy-stage-defaults.d.ts +8 -0
- package/dist/policy-stage-defaults.d.ts.map +1 -0
- package/dist/policy-stage-defaults.js +34 -0
- package/dist/policy-stage-defaults.js.map +1 -0
- package/dist/policy-yaml.d.ts +23 -0
- package/dist/policy-yaml.d.ts.map +1 -0
- package/dist/policy-yaml.js +216 -0
- package/dist/policy-yaml.js.map +1 -0
- package/dist/policy.d.ts +124 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +161 -0
- package/dist/policy.js.map +1 -0
- package/dist/remote-enforce.d.ts +44 -0
- package/dist/remote-enforce.d.ts.map +1 -0
- package/dist/remote-enforce.js +99 -0
- package/dist/remote-enforce.js.map +1 -0
- package/dist/repo-patterns.d.ts +32 -0
- package/dist/repo-patterns.d.ts.map +1 -0
- package/dist/repo-patterns.js +222 -0
- package/dist/repo-patterns.js.map +1 -0
- package/dist/sandbox.d.ts +68 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/sandbox.js +124 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/scorer-dimensions.d.ts +10 -0
- package/dist/scorer-dimensions.d.ts.map +1 -0
- package/dist/scorer-dimensions.js +184 -0
- package/dist/scorer-dimensions.js.map +1 -0
- package/dist/scorer.d.ts +27 -0
- package/dist/scorer.d.ts.map +1 -0
- package/dist/scorer.js +138 -0
- package/dist/scorer.js.map +1 -0
- package/dist/storage-postgres-schema.d.ts +47 -0
- package/dist/storage-postgres-schema.d.ts.map +1 -0
- package/dist/storage-postgres-schema.js +134 -0
- package/dist/storage-postgres-schema.js.map +1 -0
- package/dist/storage-postgres.d.ts +41 -0
- package/dist/storage-postgres.d.ts.map +1 -0
- package/dist/storage-postgres.js +180 -0
- package/dist/storage-postgres.js.map +1 -0
- package/dist/storage.d.ts +65 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +85 -0
- package/dist/storage.js.map +1 -0
- package/dist/supply-chain-sbom.d.ts +72 -0
- package/dist/supply-chain-sbom.d.ts.map +1 -0
- package/dist/supply-chain-sbom.js +73 -0
- package/dist/supply-chain-sbom.js.map +1 -0
- package/dist/supply-chain.d.ts +61 -0
- package/dist/supply-chain.d.ts.map +1 -0
- package/dist/supply-chain.js +95 -0
- package/dist/supply-chain.js.map +1 -0
- package/dist/token-types.d.ts +77 -0
- package/dist/token-types.d.ts.map +1 -0
- package/dist/token-types.js +31 -0
- package/dist/token-types.js.map +1 -0
- package/dist/types.d.ts +71 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +361 -0
package/dist/policy.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy Engine — before-action enforcement for AI agents.
|
|
3
|
+
*
|
|
4
|
+
* Evaluates rules in priority order against enforcement contexts.
|
|
5
|
+
* Preset builders are in policy-presets.ts.
|
|
6
|
+
*/
|
|
7
|
+
import { getBuiltinConditions } from "./conditions/builtins.js";
|
|
8
|
+
import { getDefaultStage } from "./policy-stage-defaults.js";
|
|
9
|
+
/**
|
|
10
|
+
* Create a standalone policy engine for before-action enforcement.
|
|
11
|
+
*
|
|
12
|
+
* Each engine has its own isolated condition registry — built-in conditions
|
|
13
|
+
* are registered automatically, and custom conditions can be added via
|
|
14
|
+
* `config.conditions` or `engine.registerCondition()`.
|
|
15
|
+
*
|
|
16
|
+
* @param config - Rules, default outcome, and custom conditions
|
|
17
|
+
* @returns A PolicyEngine with evaluate, addRule, removeRule, getRules, and condition management
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* const engine = createPolicyEngine({
|
|
22
|
+
* rules: [blockTools(['shell_exec'])],
|
|
23
|
+
* conditions: [{ name: 'geo_fence', description: 'Block by region', evaluator: myEval }],
|
|
24
|
+
* });
|
|
25
|
+
* const decision = engine.evaluate({ agentId: 'a1', action: 'tool_call', tool: 'shell_exec' });
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export function createPolicyEngine(config = {}) {
|
|
29
|
+
// Instance-scoped condition registry — fully isolated per engine
|
|
30
|
+
const registry = new Map();
|
|
31
|
+
function evaluateCondition(condition, ctx) {
|
|
32
|
+
// Inline custom evaluators (params.evaluate is a function)
|
|
33
|
+
const evalFn = condition.params?.evaluate;
|
|
34
|
+
if (typeof evalFn === "function") {
|
|
35
|
+
const r = evalFn(ctx);
|
|
36
|
+
if (r && typeof r === "object" && typeof r.then === "function") {
|
|
37
|
+
throw new Error("Custom policy evaluator returned a Promise — evaluators must be synchronous.");
|
|
38
|
+
}
|
|
39
|
+
return r;
|
|
40
|
+
}
|
|
41
|
+
const entry = registry.get(condition.type);
|
|
42
|
+
if (!entry) {
|
|
43
|
+
throw new Error(`Unknown condition type "${condition.type}" — register it via engine.registerCondition()`);
|
|
44
|
+
}
|
|
45
|
+
return entry.evaluator(ctx, condition.params);
|
|
46
|
+
}
|
|
47
|
+
// Register built-in conditions
|
|
48
|
+
for (const def of getBuiltinConditions(evaluateCondition)) {
|
|
49
|
+
registry.set(def.name, def);
|
|
50
|
+
}
|
|
51
|
+
// Register any custom conditions from config
|
|
52
|
+
for (const entry of config.conditions ?? []) {
|
|
53
|
+
registry.set(entry.name, entry);
|
|
54
|
+
}
|
|
55
|
+
const rules = [...(config.rules ?? [])];
|
|
56
|
+
const defaultOutcome = config.defaultOutcome ?? "allow";
|
|
57
|
+
function evaluate(ctx) {
|
|
58
|
+
const active = rules.filter((r) => r.enabled).sort((a, b) => b.priority - a.priority);
|
|
59
|
+
for (const rule of active) {
|
|
60
|
+
if (evaluateCondition(rule.condition, ctx)) {
|
|
61
|
+
return {
|
|
62
|
+
blocked: rule.outcome === "block" || rule.outcome === "require_approval",
|
|
63
|
+
reason: rule.reason,
|
|
64
|
+
ruleId: rule.id,
|
|
65
|
+
outcome: rule.outcome,
|
|
66
|
+
evaluatedAt: new Date().toISOString(),
|
|
67
|
+
rulesEvaluated: active.length,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
blocked: defaultOutcome === "block",
|
|
73
|
+
reason: "No policy rules matched",
|
|
74
|
+
ruleId: null,
|
|
75
|
+
outcome: defaultOutcome,
|
|
76
|
+
evaluatedAt: new Date().toISOString(),
|
|
77
|
+
rulesEvaluated: active.length,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function addRule(rule) {
|
|
81
|
+
const idx = rules.findIndex((r) => r.id === rule.id);
|
|
82
|
+
if (idx >= 0)
|
|
83
|
+
rules[idx] = rule;
|
|
84
|
+
else
|
|
85
|
+
rules.push(rule);
|
|
86
|
+
}
|
|
87
|
+
function removeRule(ruleId) {
|
|
88
|
+
const idx = rules.findIndex((r) => r.id === ruleId);
|
|
89
|
+
if (idx >= 0)
|
|
90
|
+
rules.splice(idx, 1);
|
|
91
|
+
}
|
|
92
|
+
function evaluateStage(ctx, stage) {
|
|
93
|
+
const active = rules
|
|
94
|
+
.filter((r) => r.enabled && (r.stage ?? getDefaultStage(r.condition.type)) === stage)
|
|
95
|
+
.sort((a, b) => b.priority - a.priority);
|
|
96
|
+
for (const rule of active) {
|
|
97
|
+
if (evaluateCondition(rule.condition, ctx)) {
|
|
98
|
+
return {
|
|
99
|
+
blocked: rule.outcome === "block" || rule.outcome === "require_approval",
|
|
100
|
+
reason: rule.reason,
|
|
101
|
+
ruleId: rule.id,
|
|
102
|
+
outcome: rule.outcome,
|
|
103
|
+
evaluatedAt: new Date().toISOString(),
|
|
104
|
+
rulesEvaluated: active.length,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
blocked: defaultOutcome === "block",
|
|
110
|
+
reason: "No policy rules matched",
|
|
111
|
+
ruleId: null,
|
|
112
|
+
outcome: defaultOutcome,
|
|
113
|
+
evaluatedAt: new Date().toISOString(),
|
|
114
|
+
rulesEvaluated: active.length,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function getRules(stage) {
|
|
118
|
+
if (stage)
|
|
119
|
+
return rules.filter((r) => (r.stage ?? getDefaultStage(r.condition.type)) === stage);
|
|
120
|
+
return [...rules];
|
|
121
|
+
}
|
|
122
|
+
function registerCondition(entry, opts) {
|
|
123
|
+
if (registry.has(entry.name) && !opts?.override) {
|
|
124
|
+
throw new Error(`Condition type "${entry.name}" is already registered. Use { override: true } to replace.`);
|
|
125
|
+
}
|
|
126
|
+
registry.set(entry.name, entry);
|
|
127
|
+
}
|
|
128
|
+
function unregisterCondition(name) {
|
|
129
|
+
return registry.delete(name);
|
|
130
|
+
}
|
|
131
|
+
function getRegisteredCondition(name) {
|
|
132
|
+
return registry.get(name);
|
|
133
|
+
}
|
|
134
|
+
function getRegisteredConditions() {
|
|
135
|
+
return [...registry.values()];
|
|
136
|
+
}
|
|
137
|
+
function clearConditionRegistry(opts) {
|
|
138
|
+
registry.clear();
|
|
139
|
+
if (opts?.keepBuiltins) {
|
|
140
|
+
for (const def of getBuiltinConditions(evaluateCondition)) {
|
|
141
|
+
registry.set(def.name, def);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
evaluate,
|
|
147
|
+
evaluateStage,
|
|
148
|
+
addRule,
|
|
149
|
+
removeRule,
|
|
150
|
+
getRules,
|
|
151
|
+
get ruleCount() { return rules.filter((r) => r.enabled).length; },
|
|
152
|
+
registerCondition,
|
|
153
|
+
unregisterCondition,
|
|
154
|
+
getRegisteredCondition,
|
|
155
|
+
getRegisteredConditions,
|
|
156
|
+
clearConditionRegistry,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
// ─── Re-export presets ──────────────────────────────────────────
|
|
160
|
+
export { blockTools, allowOnlyTools, requireApproval, tokenBudget, rateLimit, requireLevel, requireSequence, timeWindow, } from "./policy-presets.js";
|
|
161
|
+
//# sourceMappingURL=policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remote Enforcement — proxy enforce() and register() to Lua Governance Cloud.
|
|
3
|
+
*
|
|
4
|
+
* When serverUrl is configured, these functions POST to the remote API
|
|
5
|
+
* instead of evaluating locally. All other methods (audit, score, policies)
|
|
6
|
+
* continue to work locally.
|
|
7
|
+
*/
|
|
8
|
+
import type { EnforcementContext, EnforcementDecision } from "./policy.js";
|
|
9
|
+
import type { AgentRegistration, GovernanceAssessment } from "./types.js";
|
|
10
|
+
export interface RemoteConfig {
|
|
11
|
+
serverUrl: string;
|
|
12
|
+
apiKey: string;
|
|
13
|
+
/** Request timeout in milliseconds (default: 30000) */
|
|
14
|
+
timeout?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface RemoteRegisterResult {
|
|
17
|
+
id: string;
|
|
18
|
+
score: number;
|
|
19
|
+
level: number;
|
|
20
|
+
status: string;
|
|
21
|
+
assessment: GovernanceAssessment;
|
|
22
|
+
}
|
|
23
|
+
/** Error thrown when remote API returns a non-OK response */
|
|
24
|
+
export declare class RemoteEnforcementError extends Error {
|
|
25
|
+
readonly statusCode: number;
|
|
26
|
+
readonly responseBody: string;
|
|
27
|
+
constructor(message: string, statusCode: number, responseBody: string);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Create a remote enforcer that proxies calls to Lua Governance Cloud.
|
|
31
|
+
*
|
|
32
|
+
* @param config - Remote server URL and API key
|
|
33
|
+
* @returns Object with remote enforce and register functions
|
|
34
|
+
*/
|
|
35
|
+
export declare function createRemoteEnforcer(config: RemoteConfig): {
|
|
36
|
+
enforce: (ctx: EnforcementContext, stage?: "preprocess" | "process" | "postprocess") => Promise<EnforcementDecision>;
|
|
37
|
+
register: (input: AgentRegistration) => Promise<RemoteRegisterResult>;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Validate remote config — throws if serverUrl is set but apiKey is missing,
|
|
41
|
+
* or if serverUrl is not a valid http/https URL.
|
|
42
|
+
*/
|
|
43
|
+
export declare function validateRemoteConfig(serverUrl?: string, apiKey?: string): void;
|
|
44
|
+
//# sourceMappingURL=remote-enforce.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-enforce.d.ts","sourceRoot":"","sources":["../src/remote-enforce.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAI1E,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,oBAAoB,CAAC;CAClC;AAED,6DAA6D;AAC7D,qBAAa,sBAAuB,SAAQ,KAAK;aAG7B,UAAU,EAAE,MAAM;aAClB,YAAY,EAAE,MAAM;gBAFpC,OAAO,EAAE,MAAM,EACC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM;CAKvC;AAID;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY;mBAMhD,kBAAkB,UACf,YAAY,GAAG,SAAS,GAAG,aAAa,KAC/C,OAAO,CAAC,mBAAmB,CAAC;sBAmCM,iBAAiB,KAAG,OAAO,CAAC,oBAAoB,CAAC;EAoBvF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAc9E"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remote Enforcement — proxy enforce() and register() to Lua Governance Cloud.
|
|
3
|
+
*
|
|
4
|
+
* When serverUrl is configured, these functions POST to the remote API
|
|
5
|
+
* instead of evaluating locally. All other methods (audit, score, policies)
|
|
6
|
+
* continue to work locally.
|
|
7
|
+
*/
|
|
8
|
+
/** Error thrown when remote API returns a non-OK response */
|
|
9
|
+
export class RemoteEnforcementError extends Error {
|
|
10
|
+
statusCode;
|
|
11
|
+
responseBody;
|
|
12
|
+
constructor(message, statusCode, responseBody) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.statusCode = statusCode;
|
|
15
|
+
this.responseBody = responseBody;
|
|
16
|
+
this.name = "RemoteEnforcementError";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
// ─── Remote Enforcer ────────────────────────────────────────────
|
|
20
|
+
/**
|
|
21
|
+
* Create a remote enforcer that proxies calls to Lua Governance Cloud.
|
|
22
|
+
*
|
|
23
|
+
* @param config - Remote server URL and API key
|
|
24
|
+
* @returns Object with remote enforce and register functions
|
|
25
|
+
*/
|
|
26
|
+
export function createRemoteEnforcer(config) {
|
|
27
|
+
const { serverUrl, apiKey } = config;
|
|
28
|
+
const timeout = config.timeout ?? 30_000;
|
|
29
|
+
const baseUrl = serverUrl.replace(/\/$/, "");
|
|
30
|
+
async function remoteEnforce(ctx, stage) {
|
|
31
|
+
const endpoint = stage
|
|
32
|
+
? `${baseUrl}/api/v1/enforce/${stage}`
|
|
33
|
+
: `${baseUrl}/api/v1/enforce`;
|
|
34
|
+
const response = await fetch(endpoint, {
|
|
35
|
+
method: "POST",
|
|
36
|
+
headers: {
|
|
37
|
+
"Content-Type": "application/json",
|
|
38
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
39
|
+
},
|
|
40
|
+
body: JSON.stringify(ctx),
|
|
41
|
+
signal: AbortSignal.timeout(timeout),
|
|
42
|
+
});
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
const body = await response.text();
|
|
45
|
+
throw new RemoteEnforcementError(`Remote enforce failed: ${response.status} ${response.statusText}`, response.status, body);
|
|
46
|
+
}
|
|
47
|
+
const body = await response.json();
|
|
48
|
+
// API returns { decision: {...}, duration, operationId } — unwrap if nested
|
|
49
|
+
return "decision" in body && body.decision && typeof body.decision === "object" && "blocked" in body.decision
|
|
50
|
+
? body.decision
|
|
51
|
+
: body;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Remote register is a local-only operation — the API auto-registers
|
|
55
|
+
* agents on first enforce call, so no dedicated endpoint exists.
|
|
56
|
+
* Returns a synthetic result so callers can use agent.id in enforce().
|
|
57
|
+
*/
|
|
58
|
+
async function remoteRegister(input) {
|
|
59
|
+
return {
|
|
60
|
+
id: input.name,
|
|
61
|
+
score: 0,
|
|
62
|
+
level: 0,
|
|
63
|
+
status: "registered",
|
|
64
|
+
assessment: {
|
|
65
|
+
agentId: input.name,
|
|
66
|
+
agentName: input.name,
|
|
67
|
+
compositeScore: 0,
|
|
68
|
+
level: { level: 0, label: "pending", autonomy: "none", minScore: 0, maxScore: 0 },
|
|
69
|
+
status: "registered",
|
|
70
|
+
dimensions: [],
|
|
71
|
+
recommendations: [],
|
|
72
|
+
assessedAt: new Date().toISOString(),
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
return { enforce: remoteEnforce, register: remoteRegister };
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Validate remote config — throws if serverUrl is set but apiKey is missing,
|
|
80
|
+
* or if serverUrl is not a valid http/https URL.
|
|
81
|
+
*/
|
|
82
|
+
export function validateRemoteConfig(serverUrl, apiKey) {
|
|
83
|
+
if (!serverUrl)
|
|
84
|
+
return;
|
|
85
|
+
if (!apiKey) {
|
|
86
|
+
throw new Error("apiKey is required when serverUrl is configured");
|
|
87
|
+
}
|
|
88
|
+
let parsed;
|
|
89
|
+
try {
|
|
90
|
+
parsed = new URL(serverUrl);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
throw new Error(`Invalid serverUrl: "${serverUrl}" is not a valid URL`);
|
|
94
|
+
}
|
|
95
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
96
|
+
throw new Error(`Invalid serverUrl protocol "${parsed.protocol}" — only http: and https: are allowed`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=remote-enforce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-enforce.js","sourceRoot":"","sources":["../src/remote-enforce.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository scanning patterns — detects agent capabilities from source code.
|
|
3
|
+
*
|
|
4
|
+
* Pure pattern matching. No I/O, no network, no dependencies.
|
|
5
|
+
* Feed it file contents, get capability detection results.
|
|
6
|
+
*/
|
|
7
|
+
/** Detection result for a single capability */
|
|
8
|
+
export interface CapabilityDetection {
|
|
9
|
+
capability: "hasAuth" | "hasGuardrails" | "hasObservability" | "hasAuditLog";
|
|
10
|
+
detected: boolean;
|
|
11
|
+
confidence: number;
|
|
12
|
+
evidence: string[];
|
|
13
|
+
}
|
|
14
|
+
/** Full repo scan result */
|
|
15
|
+
export interface RepoScanResult {
|
|
16
|
+
detections: CapabilityDetection[];
|
|
17
|
+
framework: string | null;
|
|
18
|
+
tools: string[];
|
|
19
|
+
channels: string[];
|
|
20
|
+
dependencies: string[];
|
|
21
|
+
scannedFiles: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Scan file contents for agent capabilities.
|
|
25
|
+
* Feed this a Map of filePath → fileContent.
|
|
26
|
+
*/
|
|
27
|
+
export declare function scanRepoContents(fileContents: Map<string, string>): RepoScanResult;
|
|
28
|
+
/** Files worth scanning — skip node_modules, dist, tests, assets. */
|
|
29
|
+
export declare const SCAN_GLOBS: string[];
|
|
30
|
+
/** Files to skip even if they match globs. */
|
|
31
|
+
export declare const SCAN_IGNORE: RegExp[];
|
|
32
|
+
//# sourceMappingURL=repo-patterns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo-patterns.d.ts","sourceRoot":"","sources":["../src/repo-patterns.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,+CAA+C;AAC/C,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,SAAS,GAAG,eAAe,GAAG,kBAAkB,GAAG,aAAa,CAAC;IAC7E,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,4BAA4B;AAC5B,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,mBAAmB,EAAE,CAAC;IAClC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAqMD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,cAAc,CAuBlF;AAED,qEAAqE;AACrE,eAAO,MAAM,UAAU,UAUtB,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,WAAW,UASvB,CAAC"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository scanning patterns — detects agent capabilities from source code.
|
|
3
|
+
*
|
|
4
|
+
* Pure pattern matching. No I/O, no network, no dependencies.
|
|
5
|
+
* Feed it file contents, get capability detection results.
|
|
6
|
+
*/
|
|
7
|
+
// ── Auth patterns ───────────────────────────────────────────────
|
|
8
|
+
const AUTH_PATTERNS = [
|
|
9
|
+
{ pattern: /(?:@clerk|@auth0|next-auth|@supabase\/auth|passport|lucia-auth|better-auth)/, weight: 0.9, label: "Auth library import" },
|
|
10
|
+
{ pattern: /(?:withAuth|requireAuth|authenticate|isAuthenticated|verifyToken|getSession)\s*\(/, weight: 0.8, label: "Auth middleware call" },
|
|
11
|
+
{ pattern: /(?:Bearer|Authorization|JWT|oauth|OIDC|SSO)\b/i, weight: 0.5, label: "Auth protocol reference" },
|
|
12
|
+
{ pattern: /(?:signIn|signUp|signOut|login|logout|createUser)\s*[=(]/, weight: 0.6, label: "Auth flow function" },
|
|
13
|
+
{ pattern: /(?:middleware|auth)\.(ts|js|tsx)/, weight: 0.4, label: "Auth middleware file" },
|
|
14
|
+
{ pattern: /(?:RBAC|ACL|role|permission).*(?:check|verify|require)/i, weight: 0.7, label: "Access control logic" },
|
|
15
|
+
{ pattern: /(?:apiKey|api_key|API_KEY|serviceKey|service_key)/, weight: 0.5, label: "API key pattern" },
|
|
16
|
+
];
|
|
17
|
+
// ── Guardrail patterns ──────────────────────────────────────────
|
|
18
|
+
const GUARDRAIL_PATTERNS = [
|
|
19
|
+
{ pattern: /(?:@lua\/governance|createGovernance|gov\.enforce)/, weight: 0.95, label: "Lua Governance SDK" },
|
|
20
|
+
{ pattern: /(?:guardrail|guard|safety|filter|sanitize|validate)(?:Input|Output|Response|Request)/i, weight: 0.7, label: "Guardrail function" },
|
|
21
|
+
{ pattern: /(?:zod|yup|joi|superstruct|valibot)/, weight: 0.5, label: "Schema validation library" },
|
|
22
|
+
{ pattern: /(?:z\.object|z\.string|z\.number|z\.array)\s*\(/, weight: 0.6, label: "Zod schema usage" },
|
|
23
|
+
{ pattern: /(?:contentFilter|toxicity|moderation|safety)(?:Check|Filter|Guard)/i, weight: 0.8, label: "Content safety filter" },
|
|
24
|
+
{ pattern: /(?:rateLimit|rateLimiter|throttle)\s*\(/, weight: 0.6, label: "Rate limiting" },
|
|
25
|
+
{ pattern: /(?:injection|xss|sql|csrf).*(?:detect|prevent|guard|filter)/i, weight: 0.7, label: "Injection prevention" },
|
|
26
|
+
{ pattern: /(?:maxTokens|max_tokens|token_limit|tokenBudget)/, weight: 0.5, label: "Token budget control" },
|
|
27
|
+
];
|
|
28
|
+
// ── Observability patterns ──────────────────────────────────────
|
|
29
|
+
const OBSERVABILITY_PATTERNS = [
|
|
30
|
+
{ pattern: /(?:@opentelemetry|opentelemetry|otel)/, weight: 0.9, label: "OpenTelemetry" },
|
|
31
|
+
{ pattern: /(?:@sentry|sentry|Sentry\.init)/, weight: 0.8, label: "Sentry" },
|
|
32
|
+
{ pattern: /(?:@datadog|dd-trace|datadog)/, weight: 0.8, label: "Datadog" },
|
|
33
|
+
{ pattern: /(?:pino|winston|bunyan|loglevel|consola)\b/, weight: 0.6, label: "Structured logging" },
|
|
34
|
+
{ pattern: /(?:trace|span|tracer|instrument)(?:\.start|\.end|\s*\()/, weight: 0.7, label: "Tracing instrumentation" },
|
|
35
|
+
{ pattern: /(?:prometheus|grafana|newrelic|axiom|betterstack)/, weight: 0.7, label: "Monitoring platform" },
|
|
36
|
+
{ pattern: /(?:langfuse|langsmith|helicone|braintrust)/, weight: 0.8, label: "AI observability" },
|
|
37
|
+
{ pattern: /(?:metrics|histogram|counter|gauge)\.(?:record|inc|observe)/, weight: 0.6, label: "Metrics recording" },
|
|
38
|
+
];
|
|
39
|
+
// ── Audit log patterns ──────────────────────────────────────────
|
|
40
|
+
const AUDIT_PATTERNS = [
|
|
41
|
+
{ pattern: /(?:audit|auditLog|audit_log|createAuditEvent)/, weight: 0.9, label: "Audit log reference" },
|
|
42
|
+
{ pattern: /(?:gov\.audit|audit\.log|auditTrail)\s*[.(]/, weight: 0.95, label: "Audit logging call" },
|
|
43
|
+
{ pattern: /(?:eventType|event_type).*(?:created|updated|deleted|accessed)/i, weight: 0.6, label: "Event type tracking" },
|
|
44
|
+
{ pattern: /(?:immutable|tamper|hash.*chain|integrity).*(?:log|event|record)/i, weight: 0.7, label: "Tamper-evident logging" },
|
|
45
|
+
{ pattern: /(?:GDPR|SOC\s*2|HIPAA|compliance).*(?:log|audit|record)/i, weight: 0.6, label: "Compliance logging" },
|
|
46
|
+
];
|
|
47
|
+
// ── Framework detection ─────────────────────────────────────────
|
|
48
|
+
// Order matters — first match wins. Lua before Mastra (Lua uses Mastra under the hood).
|
|
49
|
+
const FRAMEWORK_PATTERNS = [
|
|
50
|
+
{ pattern: /["']lua-cli["']|LuaAgent|LuaTool|LuaSkill/, framework: "lua" },
|
|
51
|
+
{ pattern: /["']@mastra\/core["']|["']mastra["']/, framework: "mastra" },
|
|
52
|
+
{ pattern: /["']langchain["']|["']@langchain\//, framework: "langchain" },
|
|
53
|
+
{ pattern: /["']crewai["']/, framework: "crewai" },
|
|
54
|
+
{ pattern: /["']autogen["']/, framework: "autogen" },
|
|
55
|
+
{ pattern: /["']openai["'].*(?:agent|assistant)/i, framework: "openai" },
|
|
56
|
+
{ pattern: /["']@vercel\/ai["']|["']ai["']/, framework: "vercel-ai" },
|
|
57
|
+
{ pattern: /["']@modelcontextprotocol\//, framework: "mcp" },
|
|
58
|
+
{ pattern: /["']@aws-sdk\/client-bedrock["']/, framework: "bedrock" },
|
|
59
|
+
{ pattern: /["']@genkit-ai\//, framework: "genkit" },
|
|
60
|
+
{ pattern: /["']@anthropic-ai\/sdk["']/, framework: "anthropic" },
|
|
61
|
+
];
|
|
62
|
+
// ── Tool detection ──────────────────────────────────────────────
|
|
63
|
+
const GENERIC_TOOL_PATTERNS = [
|
|
64
|
+
// Generic: createTool("name"), defineTool("name"), tool("name")
|
|
65
|
+
/(?:createTool|defineTool|tool)\s*\(\s*["'`]([^"'`]+)["'`]/g,
|
|
66
|
+
// MCP: server.tool("name")
|
|
67
|
+
/server\.tool\s*\(\s*["'`]([^"'`]+)["'`]/g,
|
|
68
|
+
// Mastra/generic: createTool({ id: "name" }) or new Tool({ id: "name" })
|
|
69
|
+
/(?:createTool|new\s+Tool)\s*\(\s*\{[^}]*id\s*:\s*["'`]([^"'`]+)["'`]/g,
|
|
70
|
+
// Vercel AI: tools.name = ...
|
|
71
|
+
/tools\.([a-z][a-z0-9_]+)\s*=/g,
|
|
72
|
+
];
|
|
73
|
+
// Lua agents: class FooTool implements LuaTool { name = "foo_bar" }
|
|
74
|
+
// name is always within a few lines of `implements LuaTool`
|
|
75
|
+
const LUA_TOOL_NAME_PATTERN = /implements\s+LuaTool\s*\{[\s\n]*name\s*=\s*["'`]([^"'`]+)["'`]/g;
|
|
76
|
+
// ── Channel detection ───────────────────────────────────────────
|
|
77
|
+
const CHANNEL_PATTERNS = [
|
|
78
|
+
// Lua agent channels — detected from preprocessors, channel refs, env vars
|
|
79
|
+
{ pattern: /Lua\.request\.channel\s*===?\s*["']slack["']|SLACK_BOT_TOKEN|SLACK_.*CHANNEL/i, channel: "slack" },
|
|
80
|
+
{ pattern: /Lua\.request\.channel\s*===?\s*["']email["']|emailIngestion|email.*[Pp]reProcessor/, channel: "email" },
|
|
81
|
+
{ pattern: /Lua\.request\.channel\s*===?\s*["']whatsapp["']|WHATSAPP_.*TOKEN/, channel: "whatsapp" },
|
|
82
|
+
// Generic SDK/library patterns
|
|
83
|
+
{ pattern: /(?:@slack\/web-api|@slack\/bolt|SlackApp|WebClient)\b/, channel: "slack" },
|
|
84
|
+
{ pattern: /(?:nodemailer|@sendgrid|ses\.send|resend|postmark)\b/i, channel: "email" },
|
|
85
|
+
{ pattern: /(?:twilio.*whatsapp|whatsapp.*api)/i, channel: "whatsapp" },
|
|
86
|
+
{ pattern: /(?:twilio.*sms|sendSms|messagebird)/i, channel: "sms" },
|
|
87
|
+
{ pattern: /(?:discord\.js|@discordjs|DiscordClient)/i, channel: "discord" },
|
|
88
|
+
{ pattern: /(?:telegraf|node-telegram|Telegraf)\b/, channel: "telegram" },
|
|
89
|
+
{ pattern: /(?:@microsoft\/teams|botframework)\b/, channel: "teams" },
|
|
90
|
+
{ pattern: /(?:webhook|webhookUrl|sendWebhook|notifyWebhook)/i, channel: "webhook" },
|
|
91
|
+
{ pattern: /(?:express\(\)|fastify\(|new\s+Hono|new\s+Elysia)/, channel: "api" },
|
|
92
|
+
];
|
|
93
|
+
// ── Public API ──────────────────────────────────────────────────
|
|
94
|
+
/** Score a capability against file contents. Returns 0-1 confidence. */
|
|
95
|
+
function scoreCapability(fileContents, patterns) {
|
|
96
|
+
const evidence = [];
|
|
97
|
+
let totalWeight = 0;
|
|
98
|
+
for (const [filePath, content] of fileContents) {
|
|
99
|
+
for (const p of patterns) {
|
|
100
|
+
if (p.pattern.test(content)) {
|
|
101
|
+
evidence.push(`${p.label} in ${filePath}`);
|
|
102
|
+
totalWeight += p.weight;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Normalize: 2+ strong signals = high confidence
|
|
107
|
+
const confidence = Math.min(1, totalWeight / 2);
|
|
108
|
+
return { confidence, evidence };
|
|
109
|
+
}
|
|
110
|
+
/** Detect framework from package.json or source files. */
|
|
111
|
+
function detectFramework(fileContents) {
|
|
112
|
+
for (const [, content] of fileContents) {
|
|
113
|
+
for (const f of FRAMEWORK_PATTERNS) {
|
|
114
|
+
if (f.pattern.test(content))
|
|
115
|
+
return f.framework;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
/** Extract tool names from source code. */
|
|
121
|
+
function extractTools(fileContents, framework) {
|
|
122
|
+
const tools = new Set();
|
|
123
|
+
const patterns = framework === "lua"
|
|
124
|
+
? [LUA_TOOL_NAME_PATTERN, ...GENERIC_TOOL_PATTERNS]
|
|
125
|
+
: GENERIC_TOOL_PATTERNS;
|
|
126
|
+
for (const [, content] of fileContents) {
|
|
127
|
+
for (const pattern of patterns) {
|
|
128
|
+
pattern.lastIndex = 0;
|
|
129
|
+
let match;
|
|
130
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
131
|
+
const name = match[1];
|
|
132
|
+
if (isValidToolName(name))
|
|
133
|
+
tools.add(name);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return [...tools];
|
|
138
|
+
}
|
|
139
|
+
/** Filter obvious false positives from tool name extraction. */
|
|
140
|
+
function isValidToolName(name) {
|
|
141
|
+
if (name.length < 2 || name.length > 64)
|
|
142
|
+
return false;
|
|
143
|
+
// Common JS identifiers that aren't tool names
|
|
144
|
+
if (/^(id|name|type|key|value|data|error|result|input|output|config|options|default)$/.test(name))
|
|
145
|
+
return false;
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
/** Detect communication channels from source code. */
|
|
149
|
+
function extractChannels(fileContents) {
|
|
150
|
+
const channels = new Set();
|
|
151
|
+
for (const [, content] of fileContents) {
|
|
152
|
+
for (const { pattern, channel } of CHANNEL_PATTERNS) {
|
|
153
|
+
if (pattern.test(content)) {
|
|
154
|
+
channels.add(channel);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return [...channels];
|
|
159
|
+
}
|
|
160
|
+
/** Extract dependencies from package.json content. */
|
|
161
|
+
function extractDeps(packageJson) {
|
|
162
|
+
try {
|
|
163
|
+
const pkg = JSON.parse(packageJson);
|
|
164
|
+
return [
|
|
165
|
+
...Object.keys(pkg.dependencies ?? {}),
|
|
166
|
+
...Object.keys(pkg.devDependencies ?? {}),
|
|
167
|
+
];
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
return [];
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Scan file contents for agent capabilities.
|
|
175
|
+
* Feed this a Map of filePath → fileContent.
|
|
176
|
+
*/
|
|
177
|
+
export function scanRepoContents(fileContents) {
|
|
178
|
+
const auth = scoreCapability(fileContents, AUTH_PATTERNS);
|
|
179
|
+
const guardrails = scoreCapability(fileContents, GUARDRAIL_PATTERNS);
|
|
180
|
+
const observability = scoreCapability(fileContents, OBSERVABILITY_PATTERNS);
|
|
181
|
+
const auditLog = scoreCapability(fileContents, AUDIT_PATTERNS);
|
|
182
|
+
const pkgContent = fileContents.get("package.json") ?? "";
|
|
183
|
+
const deps = extractDeps(pkgContent);
|
|
184
|
+
const framework = detectFramework(fileContents);
|
|
185
|
+
return {
|
|
186
|
+
detections: [
|
|
187
|
+
{ capability: "hasAuth", detected: auth.confidence >= 0.4, confidence: auth.confidence, evidence: auth.evidence },
|
|
188
|
+
{ capability: "hasGuardrails", detected: guardrails.confidence >= 0.4, confidence: guardrails.confidence, evidence: guardrails.evidence },
|
|
189
|
+
{ capability: "hasObservability", detected: observability.confidence >= 0.4, confidence: observability.confidence, evidence: observability.evidence },
|
|
190
|
+
{ capability: "hasAuditLog", detected: auditLog.confidence >= 0.4, confidence: auditLog.confidence, evidence: auditLog.evidence },
|
|
191
|
+
],
|
|
192
|
+
framework,
|
|
193
|
+
tools: extractTools(fileContents, framework),
|
|
194
|
+
channels: extractChannels(fileContents),
|
|
195
|
+
dependencies: deps,
|
|
196
|
+
scannedFiles: fileContents.size,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
/** Files worth scanning — skip node_modules, dist, tests, assets. */
|
|
200
|
+
export const SCAN_GLOBS = [
|
|
201
|
+
"package.json",
|
|
202
|
+
"src/**/*.ts",
|
|
203
|
+
"src/**/*.tsx",
|
|
204
|
+
"src/**/*.js",
|
|
205
|
+
"lib/**/*.ts",
|
|
206
|
+
"app/**/*.ts",
|
|
207
|
+
"app/**/*.tsx",
|
|
208
|
+
"middleware.ts",
|
|
209
|
+
"middleware.js",
|
|
210
|
+
];
|
|
211
|
+
/** Files to skip even if they match globs. */
|
|
212
|
+
export const SCAN_IGNORE = [
|
|
213
|
+
/node_modules/,
|
|
214
|
+
/\.next/,
|
|
215
|
+
/dist\//,
|
|
216
|
+
/\.test\./,
|
|
217
|
+
/\.spec\./,
|
|
218
|
+
/\.d\.ts$/,
|
|
219
|
+
/__tests__/,
|
|
220
|
+
/coverage\//,
|
|
221
|
+
];
|
|
222
|
+
//# sourceMappingURL=repo-patterns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo-patterns.js","sourceRoot":"","sources":["../src/repo-patterns.ts"],"names":[],"mappings":"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"}
|