atabey 0.0.13 → 0.0.15
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/ATABEY.md +1 -1
- package/PRIVACY.md +8 -14
- package/README.md +405 -56
- package/bin/cli.js +72 -5
- package/dist/framework-mcp/src/index.js +988 -63
- package/dist/framework-mcp/src/index.js.map +1 -1
- package/dist/framework-mcp/src/tools/compliance/mask_pii.d.ts +17 -0
- package/dist/framework-mcp/src/tools/compliance/mask_pii.js +56 -0
- package/dist/framework-mcp/src/tools/compliance/mask_pii.js.map +1 -0
- package/dist/framework-mcp/src/tools/definitions.js +10 -9
- package/dist/framework-mcp/src/tools/definitions.js.map +1 -1
- package/dist/framework-mcp/src/tools/framework/run_tests.js +25 -0
- package/dist/framework-mcp/src/tools/framework/run_tests.js.map +1 -1
- package/dist/framework-mcp/src/tools/index.js +7 -8
- package/dist/framework-mcp/src/tools/index.js.map +1 -1
- package/dist/framework-mcp/src/tools/messaging/approve_operation.d.ts +22 -0
- package/dist/framework-mcp/src/tools/messaging/approve_operation.js +81 -0
- package/dist/framework-mcp/src/tools/messaging/approve_operation.js.map +1 -0
- package/dist/framework-mcp/src/tools/messaging/ask_human.d.ts +15 -0
- package/dist/framework-mcp/src/tools/messaging/ask_human.js +89 -20
- package/dist/framework-mcp/src/tools/messaging/ask_human.js.map +1 -1
- package/dist/framework-mcp/src/tools/observability/check_ports.d.ts +1 -0
- package/dist/framework-mcp/src/tools/observability/check_ports.js +24 -8
- package/dist/framework-mcp/src/tools/observability/check_ports.js.map +1 -1
- package/dist/framework-mcp/src/tools/quality/analyze_code_quality.js +13 -64
- package/dist/framework-mcp/src/tools/quality/analyze_code_quality.js.map +1 -1
- package/dist/framework-mcp/src/tools/schemas.d.ts +48 -53
- package/dist/framework-mcp/src/tools/schemas.js +18 -22
- package/dist/framework-mcp/src/tools/schemas.js.map +1 -1
- package/dist/framework-mcp/src/tools/shell/run_command.js +146 -90
- package/dist/framework-mcp/src/tools/shell/run_command.js.map +1 -1
- package/dist/framework-mcp/src/tools/types.d.ts +11 -105
- package/dist/framework-mcp/src/tools/types.js +1 -0
- package/dist/framework-mcp/src/tools/types.js.map +1 -1
- package/dist/framework-mcp/src/utils/auth.d.ts +36 -0
- package/dist/framework-mcp/src/utils/auth.js +79 -0
- package/dist/framework-mcp/src/utils/auth.js.map +1 -0
- package/dist/framework-mcp/src/utils/auto-rollback.d.ts +71 -0
- package/dist/framework-mcp/src/utils/auto-rollback.js +266 -0
- package/dist/framework-mcp/src/utils/auto-rollback.js.map +1 -0
- package/dist/framework-mcp/src/utils/compliance.js +12 -4
- package/dist/framework-mcp/src/utils/compliance.js.map +1 -1
- package/dist/framework-mcp/src/utils/context-optimizer.d.ts +69 -0
- package/dist/framework-mcp/src/utils/context-optimizer.js +157 -0
- package/dist/framework-mcp/src/utils/context-optimizer.js.map +1 -0
- package/dist/framework-mcp/src/utils/discipline.d.ts +68 -0
- package/dist/framework-mcp/src/utils/discipline.js +218 -0
- package/dist/framework-mcp/src/utils/discipline.js.map +1 -0
- package/dist/framework-mcp/src/utils/finops.d.ts +143 -0
- package/dist/framework-mcp/src/utils/finops.js +326 -0
- package/dist/framework-mcp/src/utils/finops.js.map +1 -0
- package/dist/framework-mcp/src/utils/human-in-loop.d.ts +95 -0
- package/dist/framework-mcp/src/utils/human-in-loop.js +216 -0
- package/dist/framework-mcp/src/utils/human-in-loop.js.map +1 -0
- package/dist/framework-mcp/src/utils/license-scanner.d.ts +71 -0
- package/dist/framework-mcp/src/utils/license-scanner.js +284 -0
- package/dist/framework-mcp/src/utils/license-scanner.js.map +1 -0
- package/dist/framework-mcp/src/utils/loop-detector.d.ts +105 -0
- package/dist/framework-mcp/src/utils/loop-detector.js +362 -0
- package/dist/framework-mcp/src/utils/loop-detector.js.map +1 -0
- package/dist/framework-mcp/src/utils/quality.d.ts +19 -0
- package/dist/framework-mcp/src/utils/quality.js +125 -0
- package/dist/framework-mcp/src/utils/quality.js.map +1 -0
- package/dist/framework-mcp/src/utils/rules-engine.d.ts +78 -0
- package/dist/framework-mcp/src/utils/rules-engine.js +232 -0
- package/dist/framework-mcp/src/utils/rules-engine.js.map +1 -0
- package/dist/framework-mcp/src/utils/silent-router.d.ts +49 -0
- package/dist/framework-mcp/src/utils/silent-router.js +155 -0
- package/dist/framework-mcp/src/utils/silent-router.js.map +1 -0
- package/dist/framework-mcp/src/utils/storage.d.ts +1 -0
- package/dist/framework-mcp/src/utils/storage.js +2 -2
- package/dist/framework-mcp/src/utils/storage.js.map +1 -1
- package/dist/framework-mcp/src/utils/telemetry-streamer.d.ts +133 -0
- package/dist/framework-mcp/src/utils/telemetry-streamer.js +397 -0
- package/dist/framework-mcp/src/utils/telemetry-streamer.js.map +1 -0
- package/dist/framework-mcp/tests/tools/file_system/file_system_tools.test.js +2 -2
- package/dist/framework-mcp/tests/tools/file_system/file_system_tools.test.js.map +1 -1
- package/dist/framework-mcp/tests/tools/framework/run_tests.test.d.ts +1 -0
- package/dist/framework-mcp/tests/tools/framework/run_tests.test.js +49 -0
- package/dist/framework-mcp/tests/tools/framework/run_tests.test.js.map +1 -0
- package/dist/framework-mcp/tests/tools/messaging/send_message.test.js +14 -5
- package/dist/framework-mcp/tests/tools/messaging/send_message.test.js.map +1 -1
- package/dist/framework-mcp/tests/tools/observability/check_ports.test.d.ts +1 -0
- package/dist/framework-mcp/tests/tools/observability/check_ports.test.js +44 -0
- package/dist/framework-mcp/tests/tools/observability/check_ports.test.js.map +1 -0
- package/dist/framework-mcp/tests/tools/shell/run_command.test.js +44 -14
- package/dist/framework-mcp/tests/tools/shell/run_command.test.js.map +1 -1
- package/dist/framework-mcp/tests/utils/auto-rollback.test.d.ts +7 -0
- package/dist/framework-mcp/tests/utils/auto-rollback.test.js +178 -0
- package/dist/framework-mcp/tests/utils/auto-rollback.test.js.map +1 -0
- package/dist/framework-mcp/tests/utils/context-optimizer.test.d.ts +1 -0
- package/dist/framework-mcp/tests/utils/context-optimizer.test.js +62 -0
- package/dist/framework-mcp/tests/utils/context-optimizer.test.js.map +1 -0
- package/dist/framework-mcp/tests/utils/finops.test.d.ts +7 -0
- package/dist/framework-mcp/tests/utils/finops.test.js +157 -0
- package/dist/framework-mcp/tests/utils/finops.test.js.map +1 -0
- package/dist/framework-mcp/tests/utils/human-in-loop.test.d.ts +1 -0
- package/dist/framework-mcp/tests/utils/human-in-loop.test.js +59 -0
- package/dist/framework-mcp/tests/utils/human-in-loop.test.js.map +1 -0
- package/dist/framework-mcp/tests/utils/license-scanner.test.d.ts +7 -0
- package/dist/framework-mcp/tests/utils/license-scanner.test.js +131 -0
- package/dist/framework-mcp/tests/utils/license-scanner.test.js.map +1 -0
- package/dist/framework-mcp/tests/utils/loop-detector.test.d.ts +7 -0
- package/dist/framework-mcp/tests/utils/loop-detector.test.js +204 -0
- package/dist/framework-mcp/tests/utils/loop-detector.test.js.map +1 -0
- package/dist/framework-mcp/tests/utils/rules-engine.test.d.ts +1 -0
- package/dist/framework-mcp/tests/utils/rules-engine.test.js +106 -0
- package/dist/framework-mcp/tests/utils/rules-engine.test.js.map +1 -0
- package/dist/framework-mcp/tests/utils/telemetry-streamer.test.d.ts +7 -0
- package/dist/framework-mcp/tests/utils/telemetry-streamer.test.js +201 -0
- package/dist/framework-mcp/tests/utils/telemetry-streamer.test.js.map +1 -0
- package/dist/src/cli/commands/check.js +16 -1
- package/dist/src/cli/commands/check.js.map +1 -1
- package/dist/src/cli/commands/dashboard.js +188 -164
- package/dist/src/cli/commands/dashboard.js.map +1 -1
- package/dist/src/cli/commands/gateway.js +2 -2
- package/dist/src/cli/commands/gateway.js.map +1 -1
- package/dist/src/cli/commands/init/scaffold-core.d.ts +2 -0
- package/dist/src/cli/commands/init/scaffold-core.js +16 -1
- package/dist/src/cli/commands/init/scaffold-core.js.map +1 -1
- package/dist/src/cli/commands/init/scaffold-ops.js +2 -2
- package/dist/src/cli/commands/init/scaffold-ops.js.map +1 -1
- package/dist/src/cli/commands/init/scaffold-standards.js +13 -1
- package/dist/src/cli/commands/init/scaffold-standards.js.map +1 -1
- package/dist/src/cli/commands/init.d.ts +4 -0
- package/dist/src/cli/commands/init.js +94 -31
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/mcp.js +3 -1
- package/dist/src/cli/commands/mcp.js.map +1 -1
- package/dist/src/cli/commands/quickstart.d.ts +1 -1
- package/dist/src/cli/commands/quickstart.js +12 -24
- package/dist/src/cli/commands/quickstart.js.map +1 -1
- package/dist/src/cli/commands/script.js +8 -1
- package/dist/src/cli/commands/script.js.map +1 -1
- package/dist/src/cli/index.js +24 -23
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/cli/shims.js +7 -7
- package/dist/src/cli/utils/pkg.js +2 -3
- package/dist/src/cli/utils/pkg.js.map +1 -1
- package/dist/src/cli/utils/quality.d.ts +10 -0
- package/dist/src/cli/utils/quality.js +10 -0
- package/dist/src/cli/utils/quality.js.map +1 -0
- package/dist/src/modules/agents/definitions.js +45 -40
- package/dist/src/modules/agents/definitions.js.map +1 -1
- package/dist/src/modules/agents/registry/manager.js +6 -1
- package/dist/src/modules/agents/registry/manager.js.map +1 -1
- package/dist/src/modules/engines/agent-executor.d.ts +6 -10
- package/dist/src/modules/engines/agent-executor.js +63 -21
- package/dist/src/modules/engines/agent-executor.js.map +1 -1
- package/dist/src/modules/engines/agent-loop.d.ts +34 -0
- package/dist/src/modules/engines/agent-loop.js +102 -0
- package/dist/src/modules/engines/agent-loop.js.map +1 -0
- package/dist/src/modules/engines/evaluation-engine.d.ts +12 -2
- package/dist/src/modules/engines/evaluation-engine.js +78 -11
- package/dist/src/modules/engines/evaluation-engine.js.map +1 -1
- package/dist/src/modules/engines/quality-gate.d.ts +13 -5
- package/dist/src/modules/engines/quality-gate.js +39 -31
- package/dist/src/modules/engines/quality-gate.js.map +1 -1
- package/dist/src/modules/engines/routing-engine.d.ts +5 -3
- package/dist/src/modules/engines/routing-engine.js +16 -9
- package/dist/src/modules/engines/routing-engine.js.map +1 -1
- package/dist/src/modules/gateway/cost-tracker.d.ts +5 -0
- package/dist/src/modules/gateway/cost-tracker.js +71 -0
- package/dist/src/modules/gateway/cost-tracker.js.map +1 -1
- package/dist/src/modules/gateway/gateway.d.ts +4 -0
- package/dist/src/modules/gateway/gateway.js +8 -0
- package/dist/src/modules/gateway/gateway.js.map +1 -1
- package/dist/src/shared/audit.js +3 -2
- package/dist/src/shared/audit.js.map +1 -1
- package/dist/src/shared/pii.d.ts +41 -9
- package/dist/src/shared/pii.js +122 -31
- package/dist/src/shared/pii.js.map +1 -1
- package/dist/src/shared/storage.d.ts +62 -0
- package/dist/src/shared/storage.js +47 -7
- package/dist/src/shared/storage.js.map +1 -1
- package/dist/tests/embedding.test.d.ts +1 -0
- package/dist/tests/embedding.test.js +82 -0
- package/dist/tests/embedding.test.js.map +1 -0
- package/dist/tests/engines/evaluation-engine.test.d.ts +1 -0
- package/dist/tests/engines/evaluation-engine.test.js +71 -0
- package/dist/tests/engines/evaluation-engine.test.js.map +1 -0
- package/dist/tests/engines/planning-engine.test.d.ts +1 -0
- package/dist/tests/engines/planning-engine.test.js +100 -0
- package/dist/tests/engines/planning-engine.test.js.map +1 -0
- package/dist/tests/engines/quality-gate.test.d.ts +1 -0
- package/dist/tests/engines/quality-gate.test.js +59 -0
- package/dist/tests/engines/quality-gate.test.js.map +1 -0
- package/dist/tests/engines/risk-engine.test.d.ts +1 -0
- package/dist/tests/engines/risk-engine.test.js +80 -0
- package/dist/tests/engines/risk-engine.test.js.map +1 -0
- package/dist/tests/engines/routing-engine.test.d.ts +1 -0
- package/dist/tests/engines/routing-engine.test.js +78 -0
- package/dist/tests/engines/routing-engine.test.js.map +1 -0
- package/dist/tests/integration/hermes_locking.test.js +1 -0
- package/dist/tests/integration/hermes_locking.test.js.map +1 -1
- package/dist/tests/modules/engines/agent-executor.test.js +1 -1
- package/dist/tests/modules/engines/agent-executor.test.js.map +1 -1
- package/dist/tests/modules/gateway/cost-tracker.test.js +20 -1
- package/dist/tests/modules/gateway/cost-tracker.test.js.map +1 -1
- package/dist/tests/shared/lock.test.d.ts +1 -0
- package/dist/tests/shared/lock.test.js +95 -0
- package/dist/tests/shared/lock.test.js.map +1 -0
- package/dist/tests/shared/pii.test.d.ts +1 -0
- package/dist/tests/shared/pii.test.js +183 -0
- package/dist/tests/shared/pii.test.js.map +1 -0
- package/framework-mcp/README.md +307 -35
- package/framework-mcp/dist/dashboard/assets/index-B_rK57vi.js +1221 -0
- package/framework-mcp/dist/dashboard/index.html +1 -1
- package/framework-mcp/dist/framework-mcp/src/index.js +988 -63
- package/framework-mcp/dist/framework-mcp/src/tools/compliance/mask_pii.js +55 -0
- package/framework-mcp/dist/framework-mcp/src/tools/definitions.js +10 -9
- package/framework-mcp/dist/framework-mcp/src/tools/framework/run_tests.js +25 -0
- package/framework-mcp/dist/framework-mcp/src/tools/index.js +7 -8
- package/framework-mcp/dist/framework-mcp/src/tools/messaging/approve_operation.js +80 -0
- package/framework-mcp/dist/framework-mcp/src/tools/messaging/ask_human.js +89 -20
- package/framework-mcp/dist/framework-mcp/src/tools/observability/check_ports.js +24 -8
- package/framework-mcp/dist/framework-mcp/src/tools/quality/analyze_code_quality.js +13 -64
- package/framework-mcp/dist/framework-mcp/src/tools/schemas.js +18 -22
- package/framework-mcp/dist/framework-mcp/src/tools/shell/run_command.js +146 -90
- package/framework-mcp/dist/framework-mcp/src/tools/types.js +1 -0
- package/framework-mcp/dist/framework-mcp/src/utils/auth.js +78 -0
- package/framework-mcp/dist/framework-mcp/src/utils/auto-rollback.js +265 -0
- package/framework-mcp/dist/framework-mcp/src/utils/compliance.js +12 -4
- package/framework-mcp/dist/framework-mcp/src/utils/context-optimizer.js +156 -0
- package/framework-mcp/dist/framework-mcp/src/utils/discipline.js +217 -0
- package/framework-mcp/dist/framework-mcp/src/utils/finops.js +325 -0
- package/framework-mcp/dist/framework-mcp/src/utils/human-in-loop.js +215 -0
- package/framework-mcp/dist/framework-mcp/src/utils/license-scanner.js +283 -0
- package/framework-mcp/dist/framework-mcp/src/utils/loop-detector.js +361 -0
- package/framework-mcp/dist/framework-mcp/src/utils/quality.js +124 -0
- package/framework-mcp/dist/framework-mcp/src/utils/rules-engine.js +231 -0
- package/framework-mcp/dist/framework-mcp/src/utils/silent-router.js +154 -0
- package/framework-mcp/dist/framework-mcp/src/utils/storage.js +2 -2
- package/framework-mcp/dist/framework-mcp/src/utils/telemetry-streamer.js +396 -0
- package/framework-mcp/dist/src/cli/platforms/core.js +72 -0
- package/framework-mcp/dist/src/cli/platforms/index.js +5 -0
- package/framework-mcp/dist/src/cli/platforms/paths.js +101 -0
- package/framework-mcp/dist/src/cli/platforms/scaffold.js +72 -0
- package/framework-mcp/dist/src/cli/platforms/utils.js +75 -0
- package/framework-mcp/dist/src/cli/utils/claude.js +57 -0
- package/framework-mcp/dist/src/cli/utils/compliance.js +12 -0
- package/framework-mcp/dist/src/cli/utils/fs.js +138 -0
- package/framework-mcp/dist/src/cli/utils/pkg.js +282 -0
- package/framework-mcp/dist/src/cli/utils/quality.js +9 -0
- package/framework-mcp/dist/src/modules/agents/definitions.js +563 -0
- package/framework-mcp/dist/src/modules/agents/registry/analyst.js +39 -0
- package/framework-mcp/dist/src/modules/agents/registry/architect.js +42 -0
- package/framework-mcp/dist/src/modules/agents/registry/backend.js +50 -0
- package/framework-mcp/dist/src/modules/agents/registry/database.js +45 -0
- package/framework-mcp/dist/src/modules/agents/registry/devops.js +45 -0
- package/framework-mcp/dist/src/modules/agents/registry/explorer.js +37 -0
- package/framework-mcp/dist/src/modules/agents/registry/frontend.js +52 -0
- package/framework-mcp/dist/src/modules/agents/registry/git.js +36 -0
- package/framework-mcp/dist/src/modules/agents/registry/manager.js +64 -0
- package/framework-mcp/dist/src/modules/agents/registry/mobile.js +41 -0
- package/framework-mcp/dist/src/modules/agents/registry/native.js +41 -0
- package/framework-mcp/dist/src/modules/agents/registry/quality.js +43 -0
- package/framework-mcp/dist/src/modules/agents/registry/security.js +42 -0
- package/framework-mcp/dist/src/modules/agents/types.js +1 -0
- package/framework-mcp/dist/src/modules/engines/evaluation-engine.js +169 -0
- package/framework-mcp/dist/src/modules/engines/quality-gate.js +92 -0
- package/framework-mcp/dist/src/modules/engines/risk-engine.js +105 -0
- package/framework-mcp/dist/src/modules/engines/routing-engine.js +408 -0
- package/framework-mcp/dist/src/modules/engines/types.js +1 -0
- package/framework-mcp/dist/src/modules/providers/definitions.js +140 -0
- package/framework-mcp/dist/src/modules/providers/registry.js +18 -0
- package/framework-mcp/dist/src/modules/providers/shared.js +104 -0
- package/framework-mcp/dist/src/modules/providers/types.js +1 -0
- package/framework-mcp/dist/src/modules/skills/adapter-skills.js +449 -0
- package/framework-mcp/dist/src/modules/skills/definitions.js +70 -0
- package/framework-mcp/dist/src/shared/audit.js +220 -0
- package/framework-mcp/dist/src/shared/errors.js +68 -0
- package/framework-mcp/dist/src/shared/lock.js +159 -0
- package/framework-mcp/dist/src/shared/pii.js +122 -31
- package/framework-mcp/dist/src/shared/retention.js +170 -0
- package/framework-mcp/dist/src/shared/storage.js +47 -7
- package/framework-mcp/dist/src/shared/string.js +29 -0
- package/framework-mcp/package.json +8 -2
- package/mcp.json +12 -6
- package/package.json +11 -5
- package/templates/full/ATABEY_FULL.md +1 -1
- package/framework-mcp/dist/dashboard/assets/index-BAPGLiWE.js +0 -267
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ─── LICENSE / COPYRIGHT SCANNER ──────────────────────────────────
|
|
3
|
+
*
|
|
4
|
+
* Detects restrictive license blocks in AI-generated code before
|
|
5
|
+
* it reaches the developer's project. Prevents GPL, AGPL, and other
|
|
6
|
+
* copyleft license violations at the MCP middleware layer.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Recognizes SPDX license identifiers
|
|
10
|
+
* - Detects known open-source license headers (GPL, AGPL, LGPL, MPL)
|
|
11
|
+
* - Checks against corporate allowlist/blocklist
|
|
12
|
+
* - Source code similarity detection for known OSS snippets
|
|
13
|
+
* - Warning vs. blocking based on license severity
|
|
14
|
+
*
|
|
15
|
+
* License Severity:
|
|
16
|
+
* CRITICAL: GPL-3.0, AGPL-3.0 (copyleft, automatic blocking)
|
|
17
|
+
* HIGH: GPL-2.0, LGPL-3.0, MPL-2.0 (file-level copyleft)
|
|
18
|
+
* MEDIUM: MIT, Apache-2.0, BSD (permissive, allowed with attribution)
|
|
19
|
+
* LOW: CC0, Unlicense (public domain, no restrictions)
|
|
20
|
+
*/
|
|
21
|
+
declare const CONFIG: {
|
|
22
|
+
/** Enable license scanning */
|
|
23
|
+
ENABLED: boolean;
|
|
24
|
+
/** Automatically block copyleft licenses */
|
|
25
|
+
BLOCK_COPYLEFT: boolean;
|
|
26
|
+
/** SPDX blocklist – these licenses are automatically blocked */
|
|
27
|
+
BLOCKLIST: string[];
|
|
28
|
+
/** SPDX allowlist – these licenses are always allowed */
|
|
29
|
+
ALLOWLIST: string[];
|
|
30
|
+
/** Detect known OSS snippets by hash (requires snippet database) */
|
|
31
|
+
ENABLE_SNIPPET_DETECTION: boolean;
|
|
32
|
+
/** Path to snippet hash database */
|
|
33
|
+
SNIPPET_DB_PATH: string;
|
|
34
|
+
};
|
|
35
|
+
export type LicenseSeverity = "CRITICAL" | "HIGH" | "MEDIUM" | "LOW" | "UNKNOWN";
|
|
36
|
+
export interface LicenseMatch {
|
|
37
|
+
license: string;
|
|
38
|
+
severity: LicenseSeverity;
|
|
39
|
+
spdxId: string;
|
|
40
|
+
source: "header" | "spdx" | "snippet" | "comment";
|
|
41
|
+
line: number;
|
|
42
|
+
snippet: string;
|
|
43
|
+
/** Whether this license requires blocking */
|
|
44
|
+
blocked: boolean;
|
|
45
|
+
/** Whether attribution is required */
|
|
46
|
+
requiresAttribution: boolean;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Scan code content for license violations.
|
|
50
|
+
* Returns array of license matches found in the content.
|
|
51
|
+
*/
|
|
52
|
+
export declare function scanForLicenses(filePath: string, content: string): LicenseMatch[];
|
|
53
|
+
/**
|
|
54
|
+
* Validate content for license compliance before allowing file write.
|
|
55
|
+
* Returns error message if blocked, null if allowed.
|
|
56
|
+
*/
|
|
57
|
+
export declare function validateLicenseCompliance(filePath: string, content: string): string | null;
|
|
58
|
+
/**
|
|
59
|
+
* Get the severity summary of a set of license matches.
|
|
60
|
+
*/
|
|
61
|
+
export declare function getLicenseSeveritySummary(matches: LicenseMatch[]): {
|
|
62
|
+
hasBlocked: boolean;
|
|
63
|
+
highestSeverity: LicenseSeverity;
|
|
64
|
+
requiresAttribution: boolean;
|
|
65
|
+
uniqueLicenses: string[];
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Get scanner config.
|
|
69
|
+
*/
|
|
70
|
+
export declare function getLicenseScannerConfig(): typeof CONFIG;
|
|
71
|
+
export { CONFIG as LicenseScannerConfig };
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ─── LICENSE / COPYRIGHT SCANNER ──────────────────────────────────
|
|
3
|
+
*
|
|
4
|
+
* Detects restrictive license blocks in AI-generated code before
|
|
5
|
+
* it reaches the developer's project. Prevents GPL, AGPL, and other
|
|
6
|
+
* copyleft license violations at the MCP middleware layer.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Recognizes SPDX license identifiers
|
|
10
|
+
* - Detects known open-source license headers (GPL, AGPL, LGPL, MPL)
|
|
11
|
+
* - Checks against corporate allowlist/blocklist
|
|
12
|
+
* - Source code similarity detection for known OSS snippets
|
|
13
|
+
* - Warning vs. blocking based on license severity
|
|
14
|
+
*
|
|
15
|
+
* License Severity:
|
|
16
|
+
* CRITICAL: GPL-3.0, AGPL-3.0 (copyleft, automatic blocking)
|
|
17
|
+
* HIGH: GPL-2.0, LGPL-3.0, MPL-2.0 (file-level copyleft)
|
|
18
|
+
* MEDIUM: MIT, Apache-2.0, BSD (permissive, allowed with attribution)
|
|
19
|
+
* LOW: CC0, Unlicense (public domain, no restrictions)
|
|
20
|
+
*/
|
|
21
|
+
import path from "path";
|
|
22
|
+
// ─── Configuration ────────────────────────────────────────────────
|
|
23
|
+
const CONFIG = {
|
|
24
|
+
/** Enable license scanning */
|
|
25
|
+
ENABLED: process.env.ATABEY_LICENSE_SCAN !== "false",
|
|
26
|
+
/** Automatically block copyleft licenses */
|
|
27
|
+
BLOCK_COPYLEFT: process.env.ATABEY_BLOCK_COPYLEFT !== "false",
|
|
28
|
+
/** SPDX blocklist – these licenses are automatically blocked */
|
|
29
|
+
BLOCKLIST: (process.env.ATABEY_LICENSE_BLOCKLIST || "GPL-3.0,AGPL-3.0,GPL-2.0").split(",").map(l => l.trim()),
|
|
30
|
+
/** SPDX allowlist – these licenses are always allowed */
|
|
31
|
+
ALLOWLIST: (process.env.ATABEY_LICENSE_ALLOWLIST || "MIT,Apache-2.0,BSD-2-Clause,BSD-3-Clause,ISC,CC0-1.0,Unlicense").split(",").map(l => l.trim()),
|
|
32
|
+
/** Detect known OSS snippets by hash (requires snippet database) */
|
|
33
|
+
ENABLE_SNIPPET_DETECTION: process.env.ATABEY_LICENSE_SNIPPET_CHECK === "true",
|
|
34
|
+
/** Path to snippet hash database */
|
|
35
|
+
SNIPPET_DB_PATH: process.env.ATABEY_SNIPPET_DB_PATH || "",
|
|
36
|
+
};
|
|
37
|
+
const SPDX_LICENSES = {
|
|
38
|
+
// Critical – Copyleft
|
|
39
|
+
"GPL-3.0": { name: "GNU General Public License v3.0", severity: "CRITICAL", copyleft: true, requiresAttribution: true },
|
|
40
|
+
"GPL-3.0-only": { name: "GNU General Public License v3.0 only", severity: "CRITICAL", copyleft: true, requiresAttribution: true },
|
|
41
|
+
"GPL-3.0-or-later": { name: "GNU General Public License v3.0 or later", severity: "CRITICAL", copyleft: true, requiresAttribution: true },
|
|
42
|
+
"AGPL-3.0": { name: "GNU Affero General Public License v3.0", severity: "CRITICAL", copyleft: true, requiresAttribution: true },
|
|
43
|
+
"AGPL-3.0-only": { name: "GNU Affero General Public License v3.0 only", severity: "CRITICAL", copyleft: true, requiresAttribution: true },
|
|
44
|
+
"SSPL-1.0": { name: "Server Side Public License v1", severity: "CRITICAL", copyleft: true, requiresAttribution: true },
|
|
45
|
+
// High – File-level copyleft
|
|
46
|
+
"GPL-2.0": { name: "GNU General Public License v2.0", severity: "HIGH", copyleft: true, requiresAttribution: true },
|
|
47
|
+
"GPL-2.0-only": { name: "GNU General Public License v2.0 only", severity: "HIGH", copyleft: true, requiresAttribution: true },
|
|
48
|
+
"LGPL-3.0": { name: "GNU Lesser General Public License v3.0", severity: "HIGH", copyleft: true, requiresAttribution: true },
|
|
49
|
+
"LGPL-3.0-only": { name: "GNU Lesser General Public License v3.0 only", severity: "HIGH", copyleft: true, requiresAttribution: true },
|
|
50
|
+
"MPL-2.0": { name: "Mozilla Public License 2.0", severity: "HIGH", copyleft: true, requiresAttribution: true },
|
|
51
|
+
"EUPL-1.2": { name: "European Union Public License 1.2", severity: "HIGH", copyleft: true, requiresAttribution: true },
|
|
52
|
+
// Medium – Permissive
|
|
53
|
+
"MIT": { name: "MIT License", severity: "MEDIUM", copyleft: false, requiresAttribution: true },
|
|
54
|
+
"Apache-2.0": { name: "Apache License 2.0", severity: "MEDIUM", copyleft: false, requiresAttribution: true },
|
|
55
|
+
"BSD-2-Clause": { name: "BSD 2-Clause License", severity: "MEDIUM", copyleft: false, requiresAttribution: true },
|
|
56
|
+
"BSD-3-Clause": { name: "BSD 3-Clause License", severity: "MEDIUM", copyleft: false, requiresAttribution: true },
|
|
57
|
+
"ISC": { name: "ISC License", severity: "MEDIUM", copyleft: false, requiresAttribution: true },
|
|
58
|
+
// Low – Public domain
|
|
59
|
+
"CC0-1.0": { name: "Creative Commons Zero v1.0", severity: "LOW", copyleft: false, requiresAttribution: false },
|
|
60
|
+
"Unlicense": { name: "The Unlicense", severity: "LOW", copyleft: false, requiresAttribution: false },
|
|
61
|
+
};
|
|
62
|
+
// ─── License Header Patterns ──────────────────────────────────────
|
|
63
|
+
const LICENSE_HEADER_PATTERNS = [
|
|
64
|
+
{
|
|
65
|
+
name: "GNU General Public License v3.0",
|
|
66
|
+
spdxId: "GPL-3.0",
|
|
67
|
+
patterns: [
|
|
68
|
+
/GNU GENERAL PUBLIC LICENSE[\s\S]*Version 3/i,
|
|
69
|
+
/GNU General Public License v3/i,
|
|
70
|
+
/GPL-3\.0/,
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: "GNU Affero General Public License v3.0",
|
|
75
|
+
spdxId: "AGPL-3.0",
|
|
76
|
+
patterns: [
|
|
77
|
+
/GNU AFFERO GENERAL PUBLIC LICENSE/i,
|
|
78
|
+
/Affero General Public License/i,
|
|
79
|
+
/AGPL-3\.0/,
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: "GNU General Public License v2.0",
|
|
84
|
+
spdxId: "GPL-2.0",
|
|
85
|
+
patterns: [
|
|
86
|
+
/GNU GENERAL PUBLIC LICENSE[\s\S]*Version 2/i,
|
|
87
|
+
/GNU General Public License v2/i,
|
|
88
|
+
/GPL-2\.0/,
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: "MIT License",
|
|
93
|
+
spdxId: "MIT",
|
|
94
|
+
patterns: [
|
|
95
|
+
/MIT License/i,
|
|
96
|
+
/Permission is hereby granted, free of charge, to any person obtaining a copy/i,
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: "Apache License 2.0",
|
|
101
|
+
spdxId: "Apache-2.0",
|
|
102
|
+
patterns: [
|
|
103
|
+
/Apache License[\s\S]*Version 2\.0/i,
|
|
104
|
+
/Licensed under the Apache License, Version 2\.0/i,
|
|
105
|
+
/Apache-2\.0/,
|
|
106
|
+
],
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
name: "BSD 2-Clause License",
|
|
110
|
+
spdxId: "BSD-2-Clause",
|
|
111
|
+
patterns: [
|
|
112
|
+
/BSD 2-Clause/i,
|
|
113
|
+
/Redistributions of source code must retain the above copyright notice/i,
|
|
114
|
+
],
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
name: "BSD 3-Clause License",
|
|
118
|
+
spdxId: "BSD-3-Clause",
|
|
119
|
+
patterns: [
|
|
120
|
+
/BSD 3-Clause/i,
|
|
121
|
+
/BSD-3-Clause/,
|
|
122
|
+
/Neither the name of/i,
|
|
123
|
+
],
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: "Mozilla Public License 2.0",
|
|
127
|
+
spdxId: "MPL-2.0",
|
|
128
|
+
patterns: [
|
|
129
|
+
/Mozilla Public License/i,
|
|
130
|
+
/MPL-2\.0/,
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
];
|
|
134
|
+
// ─── Scanner Implementation ───────────────────────────────────────
|
|
135
|
+
/**
|
|
136
|
+
* Scan code content for license violations.
|
|
137
|
+
* Returns array of license matches found in the content.
|
|
138
|
+
*/
|
|
139
|
+
export function scanForLicenses(filePath, content) {
|
|
140
|
+
if (!CONFIG.ENABLED)
|
|
141
|
+
return [];
|
|
142
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
143
|
+
// Only scan source files
|
|
144
|
+
if (![".ts", ".tsx", ".js", ".jsx", ".py", ".go", ".java", ".rb", ".php", ".c", ".cpp", ".h", ".hpp", ".rs", ".swift", ".kt"].includes(ext)) {
|
|
145
|
+
return [];
|
|
146
|
+
}
|
|
147
|
+
const matches = [];
|
|
148
|
+
const lines = content.split("\n");
|
|
149
|
+
// 1. Check for SPDX identifiers (e.g., `SPDX-License-Identifier: MIT`)
|
|
150
|
+
const spdxRegex = /SPDX-License-Identifier:\s*([^\s\n]+)/gi;
|
|
151
|
+
let spdxMatch;
|
|
152
|
+
while ((spdxMatch = spdxRegex.exec(content)) !== null) {
|
|
153
|
+
const spdxId = spdxMatch[1].trim();
|
|
154
|
+
const lineNo = getLineNumber(content, spdxMatch.index);
|
|
155
|
+
const licenseInfo = SPDX_LICENSES[spdxId];
|
|
156
|
+
if (licenseInfo) {
|
|
157
|
+
const blocked = CONFIG.BLOCKLIST.includes(spdxId) && CONFIG.BLOCK_COPYLEFT;
|
|
158
|
+
matches.push({
|
|
159
|
+
license: licenseInfo.name,
|
|
160
|
+
severity: licenseInfo.severity,
|
|
161
|
+
spdxId,
|
|
162
|
+
source: "spdx",
|
|
163
|
+
line: lineNo,
|
|
164
|
+
snippet: spdxMatch[0].substring(0, 80),
|
|
165
|
+
blocked,
|
|
166
|
+
requiresAttribution: licenseInfo.requiresAttribution,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
// Unknown SPDX identifier
|
|
171
|
+
matches.push({
|
|
172
|
+
license: `Unknown (${spdxId})`,
|
|
173
|
+
severity: "UNKNOWN",
|
|
174
|
+
spdxId,
|
|
175
|
+
source: "spdx",
|
|
176
|
+
line: lineNo,
|
|
177
|
+
snippet: spdxMatch[0].substring(0, 80),
|
|
178
|
+
blocked: CONFIG.BLOCK_COPYLEFT,
|
|
179
|
+
requiresAttribution: true,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// 2. Check for license header patterns in the first 50 lines
|
|
184
|
+
const headerRegion = lines.slice(0, 50).join("\n");
|
|
185
|
+
for (const header of LICENSE_HEADER_PATTERNS) {
|
|
186
|
+
for (const pattern of header.patterns) {
|
|
187
|
+
const headerMatch = headerRegion.match(pattern);
|
|
188
|
+
if (headerMatch) {
|
|
189
|
+
const lineNo = getLineNumber(headerRegion, headerMatch.index);
|
|
190
|
+
const licenseInfo = SPDX_LICENSES[header.spdxId] || {
|
|
191
|
+
name: header.name,
|
|
192
|
+
severity: "UNKNOWN",
|
|
193
|
+
copyleft: true,
|
|
194
|
+
requiresAttribution: true,
|
|
195
|
+
};
|
|
196
|
+
const blocked = CONFIG.BLOCKLIST.includes(header.spdxId) && CONFIG.BLOCK_COPYLEFT;
|
|
197
|
+
// Avoid duplicates from SPDX check
|
|
198
|
+
if (!matches.some(m => m.spdxId === header.spdxId && m.source === "header")) {
|
|
199
|
+
matches.push({
|
|
200
|
+
license: header.name,
|
|
201
|
+
severity: licenseInfo.severity,
|
|
202
|
+
spdxId: header.spdxId,
|
|
203
|
+
source: "header",
|
|
204
|
+
line: lineNo,
|
|
205
|
+
snippet: headerMatch[0].substring(0, 80),
|
|
206
|
+
blocked,
|
|
207
|
+
requiresAttribution: licenseInfo.requiresAttribution,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return matches;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Validate content for license compliance before allowing file write.
|
|
218
|
+
* Returns error message if blocked, null if allowed.
|
|
219
|
+
*/
|
|
220
|
+
export function validateLicenseCompliance(filePath, content) {
|
|
221
|
+
const matches = scanForLicenses(filePath, content);
|
|
222
|
+
if (matches.length === 0)
|
|
223
|
+
return null;
|
|
224
|
+
// Check for blocked licenses
|
|
225
|
+
const blocked = matches.filter(m => m.blocked);
|
|
226
|
+
if (blocked.length > 0) {
|
|
227
|
+
const details = blocked.map(m => ` Line ${m.line}: ${m.license} (${m.spdxId}) [${m.severity}]`).join("\n");
|
|
228
|
+
return [
|
|
229
|
+
"[LICENSE] ⛔ Copyleft license detected – operation blocked",
|
|
230
|
+
"",
|
|
231
|
+
"The generated code contains copyleft-licensed content that",
|
|
232
|
+
"is incompatible with corporate IP policies:",
|
|
233
|
+
"",
|
|
234
|
+
details,
|
|
235
|
+
"",
|
|
236
|
+
`Blocked licenses: ${CONFIG.BLOCKLIST.join(", ")}`,
|
|
237
|
+
`Allowed licenses: ${CONFIG.ALLOWLIST.join(", ")}`,
|
|
238
|
+
"",
|
|
239
|
+
"Please rewrite this code without using copyleft-licensed sources.",
|
|
240
|
+
].join("\n");
|
|
241
|
+
}
|
|
242
|
+
// Check for licenses requiring attribution
|
|
243
|
+
const needsAttribution = matches.filter(m => m.requiresAttribution);
|
|
244
|
+
if (needsAttribution.length > 0) {
|
|
245
|
+
const details = needsAttribution.map(m => ` ${m.license} (${m.spdxId}) – found at line ${m.line}`).join("\n");
|
|
246
|
+
process.stderr.write(`[LICENSE] ⚠️ Attribution required for:\n${details}\n`);
|
|
247
|
+
// Don't block, just warn
|
|
248
|
+
}
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Get the severity summary of a set of license matches.
|
|
253
|
+
*/
|
|
254
|
+
export function getLicenseSeveritySummary(matches) {
|
|
255
|
+
let highestSeverity = "LOW";
|
|
256
|
+
const severityOrder = ["CRITICAL", "HIGH", "MEDIUM", "LOW", "UNKNOWN"];
|
|
257
|
+
const uniqueLicenses = new Set();
|
|
258
|
+
for (const match of matches) {
|
|
259
|
+
uniqueLicenses.add(match.spdxId);
|
|
260
|
+
const currentIdx = severityOrder.indexOf(match.severity);
|
|
261
|
+
const highestIdx = severityOrder.indexOf(highestSeverity);
|
|
262
|
+
if (currentIdx < highestIdx || highestIdx === -1) {
|
|
263
|
+
highestSeverity = match.severity;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return {
|
|
267
|
+
hasBlocked: matches.some(m => m.blocked),
|
|
268
|
+
highestSeverity,
|
|
269
|
+
requiresAttribution: matches.some(m => m.requiresAttribution),
|
|
270
|
+
uniqueLicenses: Array.from(uniqueLicenses),
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Get scanner config.
|
|
275
|
+
*/
|
|
276
|
+
export function getLicenseScannerConfig() {
|
|
277
|
+
return { ...CONFIG };
|
|
278
|
+
}
|
|
279
|
+
// ─── Helper ───────────────────────────────────────────────────────
|
|
280
|
+
function getLineNumber(content, index) {
|
|
281
|
+
return content.substring(0, index).split("\n").length;
|
|
282
|
+
}
|
|
283
|
+
export { CONFIG as LicenseScannerConfig };
|
|
284
|
+
//# sourceMappingURL=license-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license-scanner.js","sourceRoot":"","sources":["../../../../framework-mcp/src/utils/license-scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ─── LOOP DETECTOR ─────────────────────────────────────────────────
|
|
3
|
+
*
|
|
4
|
+
* Detects and prevents AI agents from entering infinite loops.
|
|
5
|
+
* Monitors call patterns across time, file paths, and tools.
|
|
6
|
+
*
|
|
7
|
+
* Detection Patterns:
|
|
8
|
+
* 1. **Consecutive Same Tool** – Same tool called N times in a row
|
|
9
|
+
* 2. **File Churn** – Same file written/read repeatedly
|
|
10
|
+
* 3. **Oscillation** – A → B → A → B alternating pattern
|
|
11
|
+
* 4. **Time-based Throttle** – Too many calls in a short window
|
|
12
|
+
* 5. **Semantic Similarity** – Similar arguments repeated (e.g., same error fix loop)
|
|
13
|
+
* 6. **Content Identity** – Same content being written repeatedly
|
|
14
|
+
*
|
|
15
|
+
* Action:
|
|
16
|
+
* - Cooldown: Block agent for N seconds
|
|
17
|
+
* - Escalate: Notify dashboard/human if loop persists
|
|
18
|
+
* - Kill: Force-stop the agent session
|
|
19
|
+
*
|
|
20
|
+
* Environment Variables:
|
|
21
|
+
* MCP_LOOP_MAX_CONSECUTIVE - Max same tool calls (default: 10)
|
|
22
|
+
* MCP_LOOP_MAX_FILE_CHURN - Max writes to same file (default: 5)
|
|
23
|
+
* MCP_LOOP_COOLDOWN_MS - Cooldown duration (default: 30000)
|
|
24
|
+
* MCP_LOOP_OSCILLATION_WINDOW - Oscillation detection window (default: 6)
|
|
25
|
+
*/
|
|
26
|
+
declare const CONFIG: {
|
|
27
|
+
/** Max consecutive same tool calls before action */
|
|
28
|
+
MAX_CONSECUTIVE: number;
|
|
29
|
+
/** Max writes to the same file before action */
|
|
30
|
+
MAX_FILE_CHURN: number;
|
|
31
|
+
/** Max reads of the same file before action */
|
|
32
|
+
MAX_FILE_READ_CHURN: number;
|
|
33
|
+
/** Oscillation pattern window (min calls to detect A→B→A→B) */
|
|
34
|
+
OSCILLATION_WINDOW: number;
|
|
35
|
+
/** Cooldown duration in ms */
|
|
36
|
+
COOLDOWN_MS: number;
|
|
37
|
+
/** Max calls to any tool in sliding window */
|
|
38
|
+
MAX_CALLS_IN_WINDOW: number;
|
|
39
|
+
/** Sliding window size in ms */
|
|
40
|
+
WINDOW_SIZE_MS: number;
|
|
41
|
+
/** Enable/disable loop detector */
|
|
42
|
+
ENABLED: boolean;
|
|
43
|
+
};
|
|
44
|
+
export interface ToolCallRecord {
|
|
45
|
+
agent: string;
|
|
46
|
+
toolName: string;
|
|
47
|
+
args: Record<string, unknown>;
|
|
48
|
+
timestamp: number;
|
|
49
|
+
/** File path involved (if applicable) */
|
|
50
|
+
filePath?: string;
|
|
51
|
+
/** Content hash for content identity detection */
|
|
52
|
+
contentHash?: string;
|
|
53
|
+
}
|
|
54
|
+
export interface LoopAlert {
|
|
55
|
+
type: "consecutive_same_tool" | "file_churn" | "oscillation" | "rate_limit" | "content_identity";
|
|
56
|
+
severity: "warning" | "critical";
|
|
57
|
+
agent: string;
|
|
58
|
+
detail: string;
|
|
59
|
+
timestamp: number;
|
|
60
|
+
cooldownUntil: number | null;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Record a tool call and check for loop patterns.
|
|
64
|
+
* Returns LoopAlert if a loop pattern is detected, null otherwise.
|
|
65
|
+
*/
|
|
66
|
+
export declare function recordAndCheck(agent: string, toolName: string, args: Record<string, unknown>): LoopAlert | null;
|
|
67
|
+
/**
|
|
68
|
+
* Check if an agent is currently in cooldown.
|
|
69
|
+
*/
|
|
70
|
+
export declare function isInCooldown(agent: string): {
|
|
71
|
+
inCooldown: boolean;
|
|
72
|
+
remainingMs: number;
|
|
73
|
+
reason: string | null;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Manually clear cooldown for an agent.
|
|
77
|
+
*/
|
|
78
|
+
export declare function clearCooldown(agent: string): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Get loop detection stats for an agent.
|
|
81
|
+
*/
|
|
82
|
+
export declare function getLoopStats(agent: string): {
|
|
83
|
+
totalCalls: number;
|
|
84
|
+
recentCalls: number;
|
|
85
|
+
inCooldown: boolean;
|
|
86
|
+
cooldownCount: number;
|
|
87
|
+
consecutiveTools: Record<string, number>;
|
|
88
|
+
fileWrites: Record<string, number>;
|
|
89
|
+
fileReads: Record<string, number>;
|
|
90
|
+
lastAlert: LoopAlert | null;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Get all agents' loop stats.
|
|
94
|
+
*/
|
|
95
|
+
export declare function getAllLoopStats(): Record<string, {
|
|
96
|
+
totalCalls: number;
|
|
97
|
+
inCooldown: boolean;
|
|
98
|
+
cooldownCount: number;
|
|
99
|
+
lastAlert: LoopAlert | null;
|
|
100
|
+
}>;
|
|
101
|
+
/**
|
|
102
|
+
* Reset all agent histories.
|
|
103
|
+
*/
|
|
104
|
+
export declare function resetLoopDetection(): void;
|
|
105
|
+
export { CONFIG as LoopDetectorConfig };
|