atabey 0.0.11 → 0.0.13
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 +52 -249
- package/PRIVACY.md +161 -0
- package/README.md +355 -140
- package/bin/completion.sh +30 -0
- package/bin/{validate-agent-army.js → validate-al-registry.js} +6 -6
- package/dist/framework-mcp/src/index.js +14 -2
- package/dist/framework-mcp/src/index.js.map +1 -1
- package/dist/framework-mcp/src/resources/index.js +5 -5
- package/dist/framework-mcp/src/resources/index.js.map +1 -1
- package/dist/framework-mcp/src/tools/control_plane/locking.d.ts +1 -1
- package/dist/framework-mcp/src/tools/control_plane/locking.js +11 -9
- package/dist/framework-mcp/src/tools/control_plane/locking.js.map +1 -1
- package/dist/framework-mcp/src/tools/definitions.d.ts +5 -0
- package/dist/framework-mcp/src/tools/definitions.js +116 -241
- package/dist/framework-mcp/src/tools/definitions.js.map +1 -1
- package/dist/framework-mcp/src/tools/file_system/batch_surgical_edit.js +4 -4
- package/dist/framework-mcp/src/tools/file_system/batch_surgical_edit.js.map +1 -1
- package/dist/framework-mcp/src/tools/file_system/read_file.js +1 -1
- package/dist/framework-mcp/src/tools/file_system/replace_text.js +3 -3
- package/dist/framework-mcp/src/tools/file_system/replace_text.js.map +1 -1
- package/dist/framework-mcp/src/tools/file_system/write_file.d.ts +1 -1
- package/dist/framework-mcp/src/tools/file_system/write_file.js +4 -4
- package/dist/framework-mcp/src/tools/file_system/write_file.js.map +1 -1
- package/dist/framework-mcp/src/tools/framework/audit_deps.js +1 -1
- package/dist/framework-mcp/src/tools/framework/audit_deps.js.map +1 -1
- package/dist/framework-mcp/src/tools/framework/submit_plan.d.ts +4 -3
- package/dist/framework-mcp/src/tools/framework/submit_plan.js.map +1 -1
- package/dist/framework-mcp/src/tools/gateway/llm_gateway_query.d.ts +19 -0
- package/dist/framework-mcp/src/tools/gateway/llm_gateway_query.js +138 -0
- package/dist/framework-mcp/src/tools/gateway/llm_gateway_query.js.map +1 -0
- package/dist/framework-mcp/src/tools/gateway/llm_gateway_status.d.ts +8 -0
- package/dist/framework-mcp/src/tools/gateway/llm_gateway_status.js +91 -0
- package/dist/framework-mcp/src/tools/gateway/llm_gateway_status.js.map +1 -0
- package/dist/framework-mcp/src/tools/index.d.ts +2 -0
- package/dist/framework-mcp/src/tools/index.js +81 -17
- package/dist/framework-mcp/src/tools/index.js.map +1 -1
- package/dist/framework-mcp/src/tools/memory/delete_knowledge.d.ts +8 -0
- package/dist/framework-mcp/src/tools/memory/delete_knowledge.js +29 -0
- package/dist/framework-mcp/src/tools/memory/delete_knowledge.js.map +1 -0
- package/dist/framework-mcp/src/tools/memory/read_memory.js +1 -1
- package/dist/framework-mcp/src/tools/memory/read_memory.js.map +1 -1
- package/dist/framework-mcp/src/tools/memory/search_knowledge.d.ts +8 -0
- package/dist/framework-mcp/src/tools/memory/search_knowledge.js +49 -0
- package/dist/framework-mcp/src/tools/memory/search_knowledge.js.map +1 -0
- package/dist/framework-mcp/src/tools/memory/store_knowledge.d.ts +10 -0
- package/dist/framework-mcp/src/tools/memory/store_knowledge.js +31 -0
- package/dist/framework-mcp/src/tools/memory/store_knowledge.js.map +1 -0
- package/dist/framework-mcp/src/tools/messaging/ask_human.d.ts +6 -0
- package/dist/framework-mcp/src/tools/messaging/ask_human.js +31 -0
- package/dist/framework-mcp/src/tools/messaging/ask_human.js.map +1 -0
- package/dist/framework-mcp/src/tools/observability/check_ports.js +1 -1
- package/dist/framework-mcp/src/tools/observability/check_ports.js.map +1 -1
- package/dist/framework-mcp/src/tools/observability/get_health.js +1 -1
- package/dist/framework-mcp/src/tools/quality/analyze_code_quality.d.ts +11 -0
- package/dist/framework-mcp/src/tools/quality/analyze_code_quality.js +166 -0
- package/dist/framework-mcp/src/tools/quality/analyze_code_quality.js.map +1 -0
- package/dist/framework-mcp/src/tools/quality/check_architecture_compliance.d.ts +11 -0
- package/dist/framework-mcp/src/tools/quality/check_architecture_compliance.js +135 -0
- package/dist/framework-mcp/src/tools/quality/check_architecture_compliance.js.map +1 -0
- package/dist/framework-mcp/src/tools/schemas.d.ts +439 -0
- package/dist/framework-mcp/src/tools/schemas.js +183 -0
- package/dist/framework-mcp/src/tools/schemas.js.map +1 -0
- package/dist/framework-mcp/src/tools/search/get_map.js +2 -2
- package/dist/framework-mcp/src/tools/search/get_map.js.map +1 -1
- package/dist/framework-mcp/src/tools/search/grep_search.js +10 -7
- package/dist/framework-mcp/src/tools/search/grep_search.js.map +1 -1
- package/dist/framework-mcp/src/tools/shell/run_command.js +72 -7
- package/dist/framework-mcp/src/tools/shell/run_command.js.map +1 -1
- package/dist/framework-mcp/src/tools/types.d.ts +10 -9
- package/dist/framework-mcp/src/utils/compliance.d.ts +10 -0
- package/dist/framework-mcp/src/utils/compliance.js +102 -41
- package/dist/framework-mcp/src/utils/compliance.js.map +1 -1
- package/dist/framework-mcp/src/utils/fs.d.ts +10 -7
- package/dist/framework-mcp/src/utils/fs.js +10 -7
- package/dist/framework-mcp/src/utils/fs.js.map +1 -1
- package/dist/framework-mcp/src/utils/types.d.ts +8 -0
- package/dist/framework-mcp/src/utils/types.js +4 -0
- package/dist/framework-mcp/src/utils/types.js.map +1 -1
- package/dist/framework-mcp/src/utils/zod-to-mcp.d.ts +10 -0
- package/dist/framework-mcp/src/utils/zod-to-mcp.js +80 -0
- package/dist/framework-mcp/src/utils/zod-to-mcp.js.map +1 -0
- package/dist/framework-mcp/tests/tools/file_system/file_system_tools.test.js +4 -4
- package/dist/framework-mcp/tests/tools/file_system/file_system_tools.test.js.map +1 -1
- package/dist/framework-mcp/tests/tools/messaging/send_message.test.js +17 -16
- package/dist/framework-mcp/tests/tools/messaging/send_message.test.js.map +1 -1
- package/dist/src/cli/adapters/core.js +2 -1
- package/dist/src/cli/adapters/core.js.map +1 -1
- package/dist/src/cli/adapters/scaffold.js +2 -1
- package/dist/src/cli/adapters/scaffold.js.map +1 -1
- package/dist/src/cli/commands/check.js +17 -17
- package/dist/src/cli/commands/check.js.map +1 -1
- package/dist/src/cli/commands/compliance.d.ts +5 -1
- package/dist/src/cli/commands/compliance.js +34 -42
- package/dist/src/cli/commands/compliance.js.map +1 -1
- package/dist/src/cli/commands/contract.js +6 -5
- package/dist/src/cli/commands/contract.js.map +1 -1
- package/dist/src/cli/commands/coverage.d.ts +1 -0
- package/dist/src/cli/commands/coverage.js +121 -0
- package/dist/src/cli/commands/coverage.js.map +1 -0
- package/dist/src/cli/commands/dashboard.d.ts +1 -1
- package/dist/src/cli/commands/dashboard.js +479 -39
- package/dist/src/cli/commands/dashboard.js.map +1 -1
- package/dist/src/cli/commands/explorer.js +8 -7
- package/dist/src/cli/commands/explorer.js.map +1 -1
- package/dist/src/cli/commands/gateway.d.ts +1 -0
- package/dist/src/cli/commands/gateway.js +172 -0
- package/dist/src/cli/commands/gateway.js.map +1 -0
- package/dist/src/cli/commands/git.js +8 -9
- package/dist/src/cli/commands/git.js.map +1 -1
- package/dist/src/cli/commands/index-codebase.d.ts +4 -0
- package/dist/src/cli/commands/index-codebase.js +52 -0
- package/dist/src/cli/commands/index-codebase.js.map +1 -0
- package/dist/src/cli/commands/init/create-agent.js +3 -3
- package/dist/src/cli/commands/init/create-agent.js.map +1 -1
- package/dist/src/cli/commands/init/scaffold-core.d.ts +1 -1
- package/dist/src/cli/commands/init/scaffold-core.js +7 -6
- package/dist/src/cli/commands/init/scaffold-core.js.map +1 -1
- package/dist/src/cli/commands/init/scaffold-docs.js +4 -3
- package/dist/src/cli/commands/init/scaffold-docs.js.map +1 -1
- package/dist/src/cli/commands/init/scaffold-ops.js +3 -3
- package/dist/src/cli/commands/init/scaffold-ops.js.map +1 -1
- package/dist/src/cli/commands/init/scaffold-standards.js +11 -7
- package/dist/src/cli/commands/init/scaffold-standards.js.map +1 -1
- package/dist/src/cli/commands/init.d.ts +2 -0
- package/dist/src/cli/commands/init.js +127 -45
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/knowledge.js +5 -32
- package/dist/src/cli/commands/knowledge.js.map +1 -1
- package/dist/src/cli/commands/lint.js +5 -4
- package/dist/src/cli/commands/lint.js.map +1 -1
- package/dist/src/cli/commands/mcp.d.ts +11 -0
- package/dist/src/cli/commands/mcp.js +130 -0
- package/dist/src/cli/commands/mcp.js.map +1 -0
- package/dist/src/cli/commands/orchestrate.d.ts +10 -9
- package/dist/src/cli/commands/orchestrate.js +132 -66
- package/dist/src/cli/commands/orchestrate.js.map +1 -1
- package/dist/src/cli/commands/plan.js +16 -14
- package/dist/src/cli/commands/plan.js.map +1 -1
- package/dist/src/cli/commands/quickstart.d.ts +9 -0
- package/dist/src/cli/commands/quickstart.js +72 -0
- package/dist/src/cli/commands/quickstart.js.map +1 -0
- package/dist/src/cli/commands/script.js +6 -5
- package/dist/src/cli/commands/script.js.map +1 -1
- package/dist/src/cli/commands/security.js +5 -8
- package/dist/src/cli/commands/security.js.map +1 -1
- package/dist/src/cli/commands/status.js +23 -19
- package/dist/src/cli/commands/status.js.map +1 -1
- package/dist/src/cli/commands/trace.d.ts +2 -0
- package/dist/src/cli/commands/trace.js +59 -61
- package/dist/src/cli/commands/trace.js.map +1 -1
- package/dist/src/cli/index.js +236 -294
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/cli/platforms/core.d.ts +12 -0
- package/dist/src/cli/platforms/core.js +73 -0
- package/dist/src/cli/platforms/core.js.map +1 -0
- package/dist/src/cli/platforms/index.d.ts +5 -0
- package/dist/src/cli/platforms/index.js +6 -0
- package/dist/src/cli/platforms/index.js.map +1 -0
- package/dist/src/cli/platforms/paths.d.ts +15 -0
- package/dist/src/cli/platforms/paths.js +102 -0
- package/dist/src/cli/platforms/paths.js.map +1 -0
- package/dist/src/cli/platforms/scaffold.d.ts +2 -0
- package/dist/src/cli/platforms/scaffold.js +73 -0
- package/dist/src/cli/platforms/scaffold.js.map +1 -0
- package/dist/src/cli/platforms/utils.d.ts +4 -0
- package/dist/src/cli/platforms/utils.js +76 -0
- package/dist/src/cli/platforms/utils.js.map +1 -0
- package/dist/src/cli/shims.js +5 -5
- package/dist/src/cli/utils/claude.js +2 -1
- package/dist/src/cli/utils/claude.js.map +1 -1
- package/dist/src/cli/utils/compliance.d.ts +10 -9
- package/dist/src/cli/utils/compliance.js +10 -171
- package/dist/src/cli/utils/compliance.js.map +1 -1
- package/dist/src/cli/utils/fs.d.ts +3 -3
- package/dist/src/cli/utils/fs.js +8 -7
- package/dist/src/cli/utils/fs.js.map +1 -1
- package/dist/src/cli/utils/i18n.d.ts +5 -0
- package/dist/src/cli/utils/i18n.js +5 -0
- package/dist/src/cli/utils/i18n.js.map +1 -1
- package/dist/src/cli/utils/memory.js +9 -6
- package/dist/src/cli/utils/memory.js.map +1 -1
- package/dist/src/cli/utils/pkg.js +8 -7
- package/dist/src/cli/utils/pkg.js.map +1 -1
- package/dist/src/cli/utils/schemas.d.ts +4 -4
- package/dist/src/cli/utils/ui.d.ts +23 -0
- package/dist/src/cli/utils/ui.js +42 -0
- package/dist/src/cli/utils/ui.js.map +1 -1
- package/dist/src/contracts/tasks.d.ts +4 -4
- package/dist/src/dashboard/src/hooks/useApi.d.ts +18 -0
- package/dist/src/dashboard/src/hooks/useApi.js +47 -0
- package/dist/src/dashboard/src/hooks/useApi.js.map +1 -0
- package/dist/src/dashboard/src/hooks/useSSE.d.ts +12 -0
- package/dist/src/dashboard/src/hooks/useSSE.js +60 -0
- package/dist/src/dashboard/src/hooks/useSSE.js.map +1 -0
- package/dist/src/modules/adapters/shared.js +3 -3
- package/dist/src/modules/adapters/shared.js.map +1 -1
- package/dist/src/modules/agents/definitions.d.ts +5 -13
- package/dist/src/modules/agents/definitions.js +179 -78
- package/dist/src/modules/agents/definitions.js.map +1 -1
- package/dist/src/modules/agents/registry/analyst.js +2 -1
- package/dist/src/modules/agents/registry/analyst.js.map +1 -1
- package/dist/src/modules/agents/registry/architect.js +1 -0
- package/dist/src/modules/agents/registry/architect.js.map +1 -1
- package/dist/src/modules/agents/registry/backend.js +8 -6
- package/dist/src/modules/agents/registry/backend.js.map +1 -1
- package/dist/src/modules/agents/registry/database.js.map +1 -1
- package/dist/src/modules/agents/registry/devops.js.map +1 -1
- package/dist/src/modules/agents/registry/explorer.js +2 -0
- package/dist/src/modules/agents/registry/explorer.js.map +1 -1
- package/dist/src/modules/agents/registry/frontend.js +8 -6
- package/dist/src/modules/agents/registry/frontend.js.map +1 -1
- package/dist/src/modules/agents/registry/git.js.map +1 -1
- package/dist/src/modules/agents/registry/manager.js +11 -4
- package/dist/src/modules/agents/registry/manager.js.map +1 -1
- package/dist/src/modules/agents/registry/mobile.js +7 -5
- package/dist/src/modules/agents/registry/mobile.js.map +1 -1
- package/dist/src/modules/agents/registry/native.js +7 -5
- package/dist/src/modules/agents/registry/native.js.map +1 -1
- package/dist/src/modules/agents/registry/quality.js +11 -8
- package/dist/src/modules/agents/registry/quality.js.map +1 -1
- package/dist/src/modules/agents/registry/security.js.map +1 -1
- package/dist/src/modules/contracts/api.d.ts +178 -0
- package/dist/src/modules/contracts/api.js +56 -0
- package/dist/src/modules/contracts/api.js.map +1 -0
- package/dist/src/modules/contracts/index.d.ts +5 -0
- package/dist/src/modules/contracts/index.js +6 -0
- package/dist/src/modules/contracts/index.js.map +1 -0
- package/dist/src/modules/engines/agent-executor.d.ts +50 -0
- package/dist/src/modules/engines/agent-executor.js +188 -0
- package/dist/src/modules/engines/agent-executor.js.map +1 -0
- package/dist/src/modules/engines/health-engine.d.ts +7 -1
- package/dist/src/modules/engines/health-engine.js +85 -8
- package/dist/src/modules/engines/health-engine.js.map +1 -1
- package/dist/src/modules/engines/planning-engine.d.ts +1 -1
- package/dist/src/modules/engines/planning-engine.js +5 -4
- package/dist/src/modules/engines/planning-engine.js.map +1 -1
- package/dist/src/modules/engines/quality-gate.d.ts +23 -0
- package/dist/src/modules/engines/quality-gate.js +85 -0
- package/dist/src/modules/engines/quality-gate.js.map +1 -0
- package/dist/src/modules/engines/risk-engine.js +6 -6
- package/dist/src/modules/engines/risk-engine.js.map +1 -1
- package/dist/src/modules/engines/routing-engine.d.ts +59 -1
- package/dist/src/modules/engines/routing-engine.js +353 -25
- package/dist/src/modules/engines/routing-engine.js.map +1 -1
- package/dist/src/modules/engines/types.d.ts +7 -3
- package/dist/src/modules/gateway/circuit-breaker.d.ts +40 -0
- package/dist/src/modules/gateway/circuit-breaker.js +163 -0
- package/dist/src/modules/gateway/circuit-breaker.js.map +1 -0
- package/dist/src/modules/gateway/cost-tracker.d.ts +55 -0
- package/dist/src/modules/gateway/cost-tracker.js +127 -0
- package/dist/src/modules/gateway/cost-tracker.js.map +1 -0
- package/dist/src/modules/gateway/gateway.d.ts +68 -0
- package/dist/src/modules/gateway/gateway.js +235 -0
- package/dist/src/modules/gateway/gateway.js.map +1 -0
- package/dist/src/modules/gateway/index.d.ts +19 -0
- package/dist/src/modules/gateway/index.js +19 -0
- package/dist/src/modules/gateway/index.js.map +1 -0
- package/dist/src/modules/gateway/load-balancer.d.ts +86 -0
- package/dist/src/modules/gateway/load-balancer.js +230 -0
- package/dist/src/modules/gateway/load-balancer.js.map +1 -0
- package/dist/src/modules/gateway/providers/anthropic.d.ts +14 -0
- package/dist/src/modules/gateway/providers/anthropic.js +169 -0
- package/dist/src/modules/gateway/providers/anthropic.js.map +1 -0
- package/dist/src/modules/gateway/providers/base.d.ts +38 -0
- package/dist/src/modules/gateway/providers/base.js +42 -0
- package/dist/src/modules/gateway/providers/base.js.map +1 -0
- package/dist/src/modules/gateway/providers/google.d.ts +18 -0
- package/dist/src/modules/gateway/providers/google.js +176 -0
- package/dist/src/modules/gateway/providers/google.js.map +1 -0
- package/dist/src/modules/gateway/providers/grok.d.ts +14 -0
- package/dist/src/modules/gateway/providers/grok.js +166 -0
- package/dist/src/modules/gateway/providers/grok.js.map +1 -0
- package/dist/src/modules/gateway/providers/index.d.ts +21 -0
- package/dist/src/modules/gateway/providers/index.js +38 -0
- package/dist/src/modules/gateway/providers/index.js.map +1 -0
- package/dist/src/modules/gateway/providers/ollama.d.ts +23 -0
- package/dist/src/modules/gateway/providers/ollama.js +187 -0
- package/dist/src/modules/gateway/providers/ollama.js.map +1 -0
- package/dist/src/modules/gateway/providers/openai.d.ts +14 -0
- package/dist/src/modules/gateway/providers/openai.js +170 -0
- package/dist/src/modules/gateway/providers/openai.js.map +1 -0
- package/dist/src/modules/gateway/rate-limiter.d.ts +41 -0
- package/dist/src/modules/gateway/rate-limiter.js +119 -0
- package/dist/src/modules/gateway/rate-limiter.js.map +1 -0
- package/dist/src/modules/gateway/types.d.ts +114 -0
- package/dist/src/modules/gateway/types.js +8 -0
- package/dist/src/modules/gateway/types.js.map +1 -0
- package/dist/src/modules/memory/core.d.ts +42 -0
- package/dist/src/modules/memory/core.js +100 -0
- package/dist/src/modules/memory/core.js.map +1 -0
- package/dist/src/modules/memory/embedding.d.ts +28 -0
- package/dist/src/modules/memory/embedding.js +131 -0
- package/dist/src/modules/memory/embedding.js.map +1 -0
- package/dist/src/modules/memory/types.d.ts +18 -0
- package/dist/src/modules/memory/types.js +2 -0
- package/dist/src/modules/memory/types.js.map +1 -0
- package/dist/src/modules/memory/vector-store.d.ts +13 -0
- package/dist/src/modules/memory/vector-store.js +75 -0
- package/dist/src/modules/memory/vector-store.js.map +1 -0
- package/dist/src/modules/providers/definitions.d.ts +9 -0
- package/dist/src/modules/providers/definitions.js +141 -0
- package/dist/src/modules/providers/definitions.js.map +1 -0
- package/dist/src/modules/providers/registry.d.ts +12 -0
- package/dist/src/modules/providers/registry.js +19 -0
- package/dist/src/modules/providers/registry.js.map +1 -0
- package/dist/src/modules/providers/shared.d.ts +1 -0
- package/dist/src/modules/providers/shared.js +105 -0
- package/dist/src/modules/providers/shared.js.map +1 -0
- package/dist/src/modules/providers/types.d.ts +14 -0
- package/dist/src/modules/providers/types.js +2 -0
- package/dist/src/modules/providers/types.js.map +1 -0
- package/dist/src/modules/skills/adapter-skills.d.ts +68 -0
- package/dist/src/modules/skills/adapter-skills.js +450 -0
- package/dist/src/modules/skills/adapter-skills.js.map +1 -0
- package/dist/src/shared/audit.d.ts +105 -0
- package/dist/src/shared/audit.js +220 -0
- package/dist/src/shared/audit.js.map +1 -0
- package/dist/src/shared/constants.d.ts +11 -11
- package/dist/src/shared/constants.js +3 -3
- package/dist/src/shared/constants.js.map +1 -1
- package/dist/src/shared/fs.js +4 -2
- package/dist/src/shared/fs.js.map +1 -1
- package/dist/src/shared/lock.d.ts +82 -0
- package/dist/src/shared/lock.js +160 -0
- package/dist/src/shared/lock.js.map +1 -0
- package/dist/src/shared/logger.d.ts +2 -0
- package/dist/src/shared/logger.js +15 -5
- package/dist/src/shared/logger.js.map +1 -1
- package/dist/src/shared/pii.d.ts +37 -0
- package/dist/src/shared/pii.js +122 -0
- package/dist/src/shared/pii.js.map +1 -0
- package/dist/src/shared/retention.d.ts +63 -0
- package/dist/src/shared/retention.js +171 -0
- package/dist/src/shared/retention.js.map +1 -0
- package/dist/src/shared/storage.d.ts +13 -11
- package/dist/src/shared/storage.js +18 -14
- package/dist/src/shared/storage.js.map +1 -1
- package/dist/src/shared/string.d.ts +1 -0
- package/dist/src/shared/string.js +30 -0
- package/dist/src/shared/string.js.map +1 -0
- package/dist/src/shared/types.d.ts +8 -0
- package/dist/src/shared/types.js +4 -0
- package/dist/src/shared/types.js.map +1 -1
- package/dist/tests/adapter.test.js +3 -2
- package/dist/tests/adapter.test.js.map +1 -1
- package/dist/tests/adapters/paths.test.js +4 -4
- package/dist/tests/adapters/paths.test.js.map +1 -1
- package/dist/tests/cli/commands/check.test.d.ts +1 -0
- package/dist/tests/cli/commands/check.test.js +9 -0
- package/dist/tests/cli/commands/check.test.js.map +1 -0
- package/dist/tests/cli/commands/coverage.test.d.ts +1 -0
- package/dist/tests/cli/commands/coverage.test.js +9 -0
- package/dist/tests/cli/commands/coverage.test.js.map +1 -0
- package/dist/tests/cli/commands/dashboard-coverage.test.d.ts +1 -0
- package/dist/tests/cli/commands/dashboard-coverage.test.js +88 -0
- package/dist/tests/cli/commands/dashboard-coverage.test.js.map +1 -0
- package/dist/tests/cli/commands/exports.test.d.ts +1 -0
- package/dist/tests/cli/commands/exports.test.js +61 -0
- package/dist/tests/cli/commands/exports.test.js.map +1 -0
- package/dist/tests/cli/commands/lint.test.d.ts +1 -0
- package/dist/tests/cli/commands/lint.test.js +9 -0
- package/dist/tests/cli/commands/lint.test.js.map +1 -0
- package/dist/tests/cli/init/adapter_init.test.js +4 -5
- package/dist/tests/cli/init/adapter_init.test.js.map +1 -1
- package/dist/tests/cli/init/unified_init.test.js +5 -7
- package/dist/tests/cli/init/unified_init.test.js.map +1 -1
- package/dist/tests/core-memory.test.d.ts +1 -0
- package/dist/tests/core-memory.test.js +78 -0
- package/dist/tests/core-memory.test.js.map +1 -0
- package/dist/tests/dashboard.test.d.ts +1 -0
- package/dist/tests/dashboard.test.js +116 -0
- package/dist/tests/dashboard.test.js.map +1 -0
- package/dist/tests/fs-utils.test.js +5 -5
- package/dist/tests/fs-utils.test.js.map +1 -1
- package/dist/tests/integration/agent_flow.test.js +24 -10
- package/dist/tests/integration/agent_flow.test.js.map +1 -1
- package/dist/tests/modules/adapters/adapters.test.js +2 -2
- package/dist/tests/modules/adapters/adapters.test.js.map +1 -1
- package/dist/tests/modules/contracts/contracts.test.d.ts +1 -0
- package/dist/tests/modules/contracts/contracts.test.js +73 -0
- package/dist/tests/modules/contracts/contracts.test.js.map +1 -0
- package/dist/tests/modules/engines/agent-executor.test.d.ts +1 -0
- package/dist/tests/modules/engines/agent-executor.test.js +61 -0
- package/dist/tests/modules/engines/agent-executor.test.js.map +1 -0
- package/dist/tests/modules/engines/evaluation-engine.test.d.ts +1 -0
- package/dist/tests/modules/engines/evaluation-engine.test.js +45 -0
- package/dist/tests/modules/engines/evaluation-engine.test.js.map +1 -0
- package/dist/tests/modules/engines/health-engine.test.d.ts +1 -0
- package/dist/tests/modules/engines/health-engine.test.js +56 -0
- package/dist/tests/modules/engines/health-engine.test.js.map +1 -0
- package/dist/tests/modules/engines/planning-engine.test.d.ts +1 -0
- package/dist/tests/modules/engines/planning-engine.test.js +75 -0
- package/dist/tests/modules/engines/planning-engine.test.js.map +1 -0
- package/dist/tests/modules/engines/risk-engine.test.d.ts +1 -0
- package/dist/tests/modules/engines/risk-engine.test.js +61 -0
- package/dist/tests/modules/engines/risk-engine.test.js.map +1 -0
- package/dist/tests/modules/engines/routing-engine.test.d.ts +1 -0
- package/dist/tests/modules/engines/routing-engine.test.js +56 -0
- package/dist/tests/modules/engines/routing-engine.test.js.map +1 -0
- package/dist/tests/modules/gateway/circuit-breaker.test.d.ts +1 -0
- package/dist/tests/modules/gateway/circuit-breaker.test.js +124 -0
- package/dist/tests/modules/gateway/circuit-breaker.test.js.map +1 -0
- package/dist/tests/modules/gateway/cost-tracker.test.d.ts +1 -0
- package/dist/tests/modules/gateway/cost-tracker.test.js +74 -0
- package/dist/tests/modules/gateway/cost-tracker.test.js.map +1 -0
- package/dist/tests/modules/gateway/load-balancer.test.d.ts +1 -0
- package/dist/tests/modules/gateway/load-balancer.test.js +70 -0
- package/dist/tests/modules/gateway/load-balancer.test.js.map +1 -0
- package/dist/tests/modules/gateway/rate-limiter.test.d.ts +1 -0
- package/dist/tests/modules/gateway/rate-limiter.test.js +62 -0
- package/dist/tests/modules/gateway/rate-limiter.test.js.map +1 -0
- package/dist/tests/modules/memory/vector-store.test.d.ts +1 -0
- package/dist/tests/modules/memory/vector-store.test.js +109 -0
- package/dist/tests/modules/memory/vector-store.test.js.map +1 -0
- package/dist/tests/orchestrator-dependencies.test.js +40 -22
- package/dist/tests/orchestrator-dependencies.test.js.map +1 -1
- package/dist/tests/planning-engine.test.js +9 -8
- package/dist/tests/planning-engine.test.js.map +1 -1
- package/dist/tests/risk-engine.test.d.ts +1 -0
- package/dist/tests/risk-engine.test.js +44 -0
- package/dist/tests/risk-engine.test.js.map +1 -0
- package/dist/tests/shared/audit.test.d.ts +1 -0
- package/dist/tests/shared/audit.test.js +53 -0
- package/dist/tests/shared/audit.test.js.map +1 -0
- package/dist/tests/status-cost.test.js +15 -24
- package/dist/tests/status-cost.test.js.map +1 -1
- package/dist/tests/status.test.js +16 -17
- package/dist/tests/status.test.js.map +1 -1
- package/dist/tests/storage-operations.test.d.ts +1 -0
- package/dist/tests/storage-operations.test.js +116 -0
- package/dist/tests/storage-operations.test.js.map +1 -0
- package/dist/tests/trace-replay.test.js +34 -40
- package/dist/tests/trace-replay.test.js.map +1 -1
- package/dist/ui/assets/index-B-d2ejS8.js +519 -0
- package/dist/ui/assets/index-CyXywq5G.css +1 -0
- package/dist/ui/index.html +2 -2
- package/dist/vitest.config.js +5 -5
- package/dist/vitest.config.js.map +1 -1
- package/framework-mcp/README.md +339 -25
- package/framework-mcp/dist/dashboard/assets/index-BAPGLiWE.js +267 -0
- package/framework-mcp/dist/dashboard/index.html +15 -0
- package/framework-mcp/dist/framework-mcp/src/constants.js +64 -0
- package/framework-mcp/dist/framework-mcp/src/index.js +156 -0
- package/framework-mcp/dist/framework-mcp/src/resources/index.js +58 -0
- package/framework-mcp/dist/framework-mcp/src/tools/control_plane/locking.js +84 -0
- package/framework-mcp/dist/framework-mcp/src/tools/control_plane/registry.js +35 -0
- package/framework-mcp/dist/framework-mcp/src/tools/definitions.js +197 -0
- package/framework-mcp/dist/framework-mcp/src/tools/file_system/batch_surgical_edit.js +64 -0
- package/framework-mcp/dist/framework-mcp/src/tools/file_system/patch_file.js +34 -0
- package/framework-mcp/dist/framework-mcp/src/tools/file_system/read_file.js +51 -0
- package/framework-mcp/dist/framework-mcp/src/tools/file_system/replace_text.js +50 -0
- package/framework-mcp/dist/framework-mcp/src/tools/file_system/write_file.js +55 -0
- package/framework-mcp/dist/framework-mcp/src/tools/framework/audit_deps.js +41 -0
- package/framework-mcp/dist/framework-mcp/src/tools/framework/get_status.js +5 -0
- package/framework-mcp/dist/framework-mcp/src/tools/framework/orchestrate.js +5 -0
- package/framework-mcp/dist/framework-mcp/src/tools/framework/run_tests.js +27 -0
- package/framework-mcp/dist/framework-mcp/src/tools/framework/submit_plan.js +13 -0
- package/framework-mcp/dist/framework-mcp/src/tools/framework/update_contract_hash.js +5 -0
- package/framework-mcp/dist/framework-mcp/src/tools/framework/update_memory.js +8 -0
- package/framework-mcp/dist/framework-mcp/src/tools/gateway/llm_gateway_query.js +137 -0
- package/framework-mcp/dist/framework-mcp/src/tools/gateway/llm_gateway_status.js +90 -0
- package/framework-mcp/dist/framework-mcp/src/tools/index.js +126 -0
- package/framework-mcp/dist/framework-mcp/src/tools/memory/delete_knowledge.js +28 -0
- package/framework-mcp/dist/framework-mcp/src/tools/memory/get_insights.js +22 -0
- package/framework-mcp/dist/framework-mcp/src/tools/memory/read_memory.js +28 -0
- package/framework-mcp/dist/framework-mcp/src/tools/memory/search_knowledge.js +48 -0
- package/framework-mcp/dist/framework-mcp/src/tools/memory/store_knowledge.js +30 -0
- package/framework-mcp/dist/framework-mcp/src/tools/messaging/ask_human.js +30 -0
- package/framework-mcp/dist/framework-mcp/src/tools/messaging/log_action.js +22 -0
- package/framework-mcp/dist/framework-mcp/src/tools/messaging/send_message.js +94 -0
- package/framework-mcp/dist/framework-mcp/src/tools/observability/check_ports.js +26 -0
- package/framework-mcp/dist/framework-mcp/src/tools/observability/get_health.js +19 -0
- package/framework-mcp/dist/framework-mcp/src/tools/quality/analyze_code_quality.js +165 -0
- package/framework-mcp/dist/framework-mcp/src/tools/quality/check_architecture_compliance.js +134 -0
- package/framework-mcp/dist/framework-mcp/src/tools/quality/check_lint.js +30 -0
- package/framework-mcp/dist/framework-mcp/src/tools/schemas.js +182 -0
- package/framework-mcp/dist/framework-mcp/src/tools/search/get_gaps.js +48 -0
- package/framework-mcp/dist/framework-mcp/src/tools/search/get_map.js +43 -0
- package/framework-mcp/dist/framework-mcp/src/tools/search/grep_search.js +78 -0
- package/framework-mcp/dist/framework-mcp/src/tools/search/list_dir.js +28 -0
- package/framework-mcp/dist/framework-mcp/src/tools/shell/run_command.js +121 -0
- package/framework-mcp/dist/framework-mcp/src/tools/types.js +1 -0
- package/framework-mcp/dist/framework-mcp/src/utils/cli.js +59 -0
- package/framework-mcp/dist/framework-mcp/src/utils/compliance.js +292 -0
- package/framework-mcp/dist/framework-mcp/src/utils/errors.js +68 -0
- package/framework-mcp/dist/framework-mcp/src/utils/fs.js +47 -0
- package/framework-mcp/dist/framework-mcp/src/utils/memory.js +74 -0
- package/framework-mcp/dist/framework-mcp/src/utils/metrics.js +56 -0
- package/framework-mcp/dist/framework-mcp/src/utils/permissions.js +71 -0
- package/framework-mcp/dist/framework-mcp/src/utils/security.js +60 -0
- package/framework-mcp/dist/framework-mcp/src/utils/storage.js +207 -0
- package/framework-mcp/dist/framework-mcp/src/utils/types.js +16 -0
- package/framework-mcp/dist/framework-mcp/src/utils/zod-to-mcp.js +79 -0
- package/framework-mcp/dist/index.js +14 -2
- package/framework-mcp/dist/src/cli/utils/memory.js +279 -0
- package/framework-mcp/dist/src/cli/utils/time.js +27 -0
- package/framework-mcp/dist/src/cli/utils/ui.js +100 -0
- package/framework-mcp/dist/src/modules/memory/core.js +99 -0
- package/framework-mcp/dist/src/modules/memory/embedding.js +130 -0
- package/framework-mcp/dist/src/modules/memory/types.js +1 -0
- package/framework-mcp/dist/src/modules/memory/vector-store.js +74 -0
- package/framework-mcp/dist/src/shared/constants.js +187 -0
- package/framework-mcp/dist/src/shared/fs.js +53 -0
- package/framework-mcp/dist/src/shared/logger.js +126 -0
- package/framework-mcp/dist/src/shared/pii.js +121 -0
- package/framework-mcp/dist/src/shared/storage.js +211 -0
- package/framework-mcp/dist/src/shared/types.js +16 -0
- package/framework-mcp/dist/tools/definitions.js +79 -247
- package/framework-mcp/dist/tools/index.js +37 -0
- package/framework-mcp/dist/tools/schemas.js +133 -0
- package/framework-mcp/dist/utils/types.js +4 -0
- package/framework-mcp/dist/utils/zod-to-mcp.js +77 -0
- package/framework-mcp/package.json +2 -2
- package/mcp.json +5 -4
- package/package.json +19 -17
- package/templates/full/ATABEY_FULL.md +515 -0
- package/templates/standards/crud-governance.md +1 -1
- package/templates/standards/logging-and-secrets.md +1 -1
- package/templates/standards/performance-standards.md +2 -2
- package/templates/standards/quality-standards.md +1 -1
- package/dist/ui/assets/index-Bkt7APzu.css +0 -1
- package/dist/ui/assets/index-CeX-06mI.js +0 -49
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { resolveFrameworkDir } from "./security.js";
|
|
5
|
+
/**
|
|
6
|
+
* Enterprise Compliance Guardrail
|
|
7
|
+
* Checks content against corporate standards using AST analysis before allowing file mutations.
|
|
8
|
+
*/
|
|
9
|
+
export function verifyCorporateCompliance(content, filePath) {
|
|
10
|
+
// Skip compliance checks for non-source files or specific ignored files
|
|
11
|
+
if (filePath.endsWith(".json") || filePath.endsWith(".md") || filePath.endsWith(".env.example")) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
|
|
15
|
+
const errors = [];
|
|
16
|
+
/**
|
|
17
|
+
* Recursive AST Visitor
|
|
18
|
+
*/
|
|
19
|
+
function visit(node) {
|
|
20
|
+
// 1. Zero Console Policy
|
|
21
|
+
if (ts.isPropertyAccessExpression(node)) {
|
|
22
|
+
const expression = node.expression;
|
|
23
|
+
const name = node.name.text;
|
|
24
|
+
if (ts.isIdentifier(expression) && expression.text === "console") {
|
|
25
|
+
if (["log", "warn", "error"].includes(name)) {
|
|
26
|
+
// Check if file is exempt
|
|
27
|
+
if (!filePath.includes("logger.ts") && !filePath.includes("check.ts") && !filePath.includes("cli.ts") && !filePath.includes("compliance.ts")) {
|
|
28
|
+
errors.push(`[ERROR] Corporate Compliance Breach: 'console.${name}' usage is forbidden at line ${sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1}.`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// 2. Unsafe DOM Policy (Avoid XSS)
|
|
33
|
+
if (name === "innerHTML" || name === "outerHTML") {
|
|
34
|
+
errors.push(`[ERROR] Corporate Compliance Breach: Unsafe usage of '${name}' detected at line ${sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1}. Avoid XSS.`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// 3. No Explicit Any Policy
|
|
38
|
+
if (ts.isTypeReferenceNode(node)) {
|
|
39
|
+
if (ts.isIdentifier(node.typeName) && node.typeName.text === "any") {
|
|
40
|
+
if (!filePath.includes("definitions.ts") && !filePath.includes("types.ts")) {
|
|
41
|
+
errors.push(`[ERROR] Corporate Compliance Breach: 'any' type is forbidden at line ${sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1}.`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// 4. Zero UI Library Policy
|
|
46
|
+
if (ts.isImportDeclaration(node)) {
|
|
47
|
+
const moduleSpecifier = node.moduleSpecifier;
|
|
48
|
+
if (ts.isStringLiteral(moduleSpecifier)) {
|
|
49
|
+
const forbiddenLibs = ["@chakra-ui", "mui", "@shadcn", "antd", "bootstrap"];
|
|
50
|
+
const lib = forbiddenLibs.find(l => moduleSpecifier.text.includes(l));
|
|
51
|
+
if (lib) {
|
|
52
|
+
errors.push(`[ERROR] Corporate Compliance Breach: External UI library '${lib}' usage is FORBIDDEN at line ${sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1}. Build atomic components manually instead.`);
|
|
53
|
+
}
|
|
54
|
+
// 5. Secure CLI Policy (No direct child_process)
|
|
55
|
+
if (moduleSpecifier.text === "child_process") {
|
|
56
|
+
errors.push(`[ERROR] Corporate Compliance Breach: Direct 'child_process' usage is forbidden at line ${sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1}. Use secure framework APIs.`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Handle 'any' as a keyword type
|
|
61
|
+
if (node.kind === ts.SyntaxKind.AnyKeyword) {
|
|
62
|
+
if (!filePath.includes("definitions.ts") && !filePath.includes("types.ts")) {
|
|
63
|
+
errors.push(`[ERROR] Corporate Compliance Breach: 'any' keyword is forbidden at line ${sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1}.`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// 6. SQL Safety Policy (Kysely only)
|
|
67
|
+
if (ts.isTaggedTemplateExpression(node)) {
|
|
68
|
+
const tag = node.tag;
|
|
69
|
+
if (ts.isIdentifier(tag) && tag.text === "sql") {
|
|
70
|
+
errors.push(`[ERROR] Corporate Compliance Breach: Raw SQL tagged template detected at line ${sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1}. Use Kysely query builder.`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// 7. Atomic FS Policy (No raw fs mutations)
|
|
74
|
+
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {
|
|
75
|
+
const prop = node.expression;
|
|
76
|
+
if (ts.isIdentifier(prop.expression) && prop.expression.text === "fs") {
|
|
77
|
+
if (["writeFileSync", "appendFileSync"].includes(prop.name.text)) {
|
|
78
|
+
// Lock files are exempt
|
|
79
|
+
const args = node.arguments;
|
|
80
|
+
const firstArgText = args.length > 0 ? args[0].getText(sourceFile).toLowerCase() : "";
|
|
81
|
+
if (!firstArgText.includes("lock")) {
|
|
82
|
+
errors.push(`[ERROR] Corporate Compliance Breach: Raw 'fs.${prop.name.text}' mutation detected at line ${sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1}. Use atomic utilities instead.`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
ts.forEachChild(node, visit);
|
|
88
|
+
}
|
|
89
|
+
visit(sourceFile);
|
|
90
|
+
// 8. Hardcoded Secrets & PII Guard
|
|
91
|
+
const piiKeywords = [
|
|
92
|
+
{ regex: /API_KEY\s*=\s*['"][^'"]+['"]/i, msg: "Hardcoded API Key" },
|
|
93
|
+
{ regex: /SECRET\s*=\s*['"][^'"]+['"]/i, msg: "Hardcoded Secret" },
|
|
94
|
+
{ regex: /PASSWORD\s*=\s*['"][^'"]+['"]/i, msg: "Hardcoded Password" },
|
|
95
|
+
{ regex: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/, msg: "PII Detected: Email Address" },
|
|
96
|
+
{ regex: /\b\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}\b/, msg: "PII Detected: Credit Card Pattern" }
|
|
97
|
+
];
|
|
98
|
+
for (const { regex, msg } of piiKeywords) {
|
|
99
|
+
if (regex.test(content)) {
|
|
100
|
+
if (msg.includes("Email") && (filePath.endsWith("README.md") || filePath.endsWith("package.json") || filePath.includes("CONTRIBUTING"))) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
errors.push(`[ERROR] Corporate Compliance Breach: ${msg} detected.`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (errors.length > 0) {
|
|
107
|
+
throw new Error(errors.join("\n"));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Enterprise Compliance Scanner
|
|
112
|
+
* Scans a directory for compliance issues.
|
|
113
|
+
*/
|
|
114
|
+
export function scanProjectCompliance(targetDir = "src") {
|
|
115
|
+
const issues = [];
|
|
116
|
+
if (!fs.existsSync(targetDir))
|
|
117
|
+
return [];
|
|
118
|
+
const files = getAllFiles(targetDir);
|
|
119
|
+
for (const file of files) {
|
|
120
|
+
// Skip exempt files
|
|
121
|
+
if (file.includes("compliance") || file.includes("definitions") || file.includes("logger") || file.includes("cli/index.ts"))
|
|
122
|
+
continue;
|
|
123
|
+
const content = fs.readFileSync(file, "utf8");
|
|
124
|
+
try {
|
|
125
|
+
verifyCorporateCompliance(content, file);
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
const errorLines = err.message.split("\n");
|
|
129
|
+
for (const errorLine of errorLines) {
|
|
130
|
+
const match = errorLine.match(/line (\d+)\./);
|
|
131
|
+
const line = match ? parseInt(match[1]) : 0;
|
|
132
|
+
issues.push({ file, line, rule: errorLine });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Technical Debt (TODO/FIXME)
|
|
136
|
+
const lines = content.split("\n");
|
|
137
|
+
lines.forEach((line, index) => {
|
|
138
|
+
if (/\b(TODO|FIXME)\b/i.test(line)) {
|
|
139
|
+
issues.push({ file, line: index + 1, rule: "Unresolved Technical Debt (TODO/FIXME) found" });
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
return issues;
|
|
144
|
+
}
|
|
145
|
+
function getAllFiles(dirPath, arrayOfFiles = []) {
|
|
146
|
+
const files = fs.readdirSync(dirPath);
|
|
147
|
+
files.forEach((file) => {
|
|
148
|
+
const fullPath = path.join(dirPath, file);
|
|
149
|
+
if (fs.statSync(fullPath).isDirectory()) {
|
|
150
|
+
if (file !== "node_modules" && !file.startsWith(".")) {
|
|
151
|
+
arrayOfFiles = getAllFiles(fullPath, arrayOfFiles);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
const ext = path.extname(fullPath);
|
|
156
|
+
if ([".ts", ".tsx", ".js", ".jsx"].includes(ext)) {
|
|
157
|
+
arrayOfFiles.push(fullPath);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
return arrayOfFiles;
|
|
162
|
+
}
|
|
163
|
+
export function isHighRiskOperation(content, filePath) {
|
|
164
|
+
const fileName = filePath.toLowerCase();
|
|
165
|
+
// 1. Database Deletions
|
|
166
|
+
if (fileName.endsWith(".sql") || fileName.endsWith(".ts") || fileName.endsWith(".js") || fileName.endsWith(".go")) {
|
|
167
|
+
const dropRegex = /\b(DROP\s+(DATABASE|TABLE|SCHEMA|VIEW|INDEX)|TRUNCATE\s+TABLE)\b/i;
|
|
168
|
+
if (dropRegex.test(content)) {
|
|
169
|
+
return { isRisk: true, reason: "Database structural deletion detected (DROP/TRUNCATE)" };
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// 2. Package Updates
|
|
173
|
+
if (fileName.endsWith("package.json")) {
|
|
174
|
+
return { isRisk: true, reason: "Dependency/package update operation detected" };
|
|
175
|
+
}
|
|
176
|
+
// 3. Deployment Scripts
|
|
177
|
+
if (fileName.includes("deploy") ||
|
|
178
|
+
fileName.includes("dockerfile") ||
|
|
179
|
+
fileName.includes("docker-compose") ||
|
|
180
|
+
fileName.includes("k8s") ||
|
|
181
|
+
fileName.includes("github/workflows")) {
|
|
182
|
+
return { isRisk: true, reason: "Infrastructure or deployment script mutation detected" };
|
|
183
|
+
}
|
|
184
|
+
return { isRisk: false };
|
|
185
|
+
}
|
|
186
|
+
export async function verifyRiskAndAwaitApproval(projectRoot, content, filePath) {
|
|
187
|
+
const assessment = isHighRiskOperation(content, filePath);
|
|
188
|
+
if (!assessment.isRisk) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
const frameworkDir = resolveFrameworkDir(projectRoot);
|
|
192
|
+
const absoluteFrameworkPath = path.isAbsolute(frameworkDir)
|
|
193
|
+
? frameworkDir
|
|
194
|
+
: path.resolve(projectRoot, frameworkDir);
|
|
195
|
+
const statusPath = path.join(absoluteFrameworkPath, "memory", "status.json");
|
|
196
|
+
const statePath = path.join(absoluteFrameworkPath, "memory", "state.json");
|
|
197
|
+
const messagesDir = path.join(absoluteFrameworkPath, "messages");
|
|
198
|
+
const managerMsgPath = path.join(messagesDir, "manager.json");
|
|
199
|
+
let activeAgent = null;
|
|
200
|
+
let traceId = "UNKNOWN";
|
|
201
|
+
if (fs.existsSync(statePath)) {
|
|
202
|
+
try {
|
|
203
|
+
const state = JSON.parse(fs.readFileSync(statePath, "utf8"));
|
|
204
|
+
if (state && state.traceId)
|
|
205
|
+
traceId = state.traceId;
|
|
206
|
+
}
|
|
207
|
+
catch { /* ignore */ }
|
|
208
|
+
}
|
|
209
|
+
let statusData = {};
|
|
210
|
+
if (fs.existsSync(statusPath)) {
|
|
211
|
+
try {
|
|
212
|
+
statusData = JSON.parse(fs.readFileSync(statusPath, "utf8"));
|
|
213
|
+
for (const [agentName, info] of Object.entries(statusData)) {
|
|
214
|
+
if (info.state === "EXECUTING") {
|
|
215
|
+
activeAgent = agentName.startsWith("@") ? agentName : `@${agentName}`;
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
catch { /* ignore */ }
|
|
221
|
+
}
|
|
222
|
+
if (!activeAgent)
|
|
223
|
+
throw new Error(`Security Exception: High-risk operation blocked. ${assessment.reason}.`);
|
|
224
|
+
const statusKey = activeAgent.replace("@", "");
|
|
225
|
+
const originalTask = statusData[statusKey]?.task || "Executing task";
|
|
226
|
+
statusData[statusKey] = {
|
|
227
|
+
state: "WAITING_FOR_APPROVAL",
|
|
228
|
+
task: `[PAUSED] Waiting for approval: ${assessment.reason} on ${filePath}`
|
|
229
|
+
};
|
|
230
|
+
try {
|
|
231
|
+
fs.writeFileSync(statusPath, JSON.stringify(statusData, null, 2));
|
|
232
|
+
}
|
|
233
|
+
catch { /* ignore */ }
|
|
234
|
+
if (!fs.existsSync(messagesDir))
|
|
235
|
+
fs.mkdirSync(messagesDir, { recursive: true });
|
|
236
|
+
const alertMsg = {
|
|
237
|
+
timestamp: new Date().toISOString(),
|
|
238
|
+
from: activeAgent,
|
|
239
|
+
to: "@manager",
|
|
240
|
+
category: "ALERT",
|
|
241
|
+
content: `High-risk operation: ${assessment.reason} on ${filePath}`,
|
|
242
|
+
traceId: traceId,
|
|
243
|
+
status: "PENDING",
|
|
244
|
+
priority: "HIGH",
|
|
245
|
+
requiresApproval: true,
|
|
246
|
+
action: `MUTATION:${filePath}`
|
|
247
|
+
};
|
|
248
|
+
try {
|
|
249
|
+
fs.appendFileSync(managerMsgPath, JSON.stringify(alertMsg) + "\n");
|
|
250
|
+
}
|
|
251
|
+
catch (err) {
|
|
252
|
+
statusData[statusKey] = { state: "EXECUTING", task: originalTask };
|
|
253
|
+
fs.writeFileSync(statusPath, JSON.stringify(statusData, null, 2));
|
|
254
|
+
throw new Error("Security Exception: Failed to queue approval request.", { cause: err });
|
|
255
|
+
}
|
|
256
|
+
const pollIntervalMs = 500;
|
|
257
|
+
const timeoutMs = 60000;
|
|
258
|
+
const start = Date.now();
|
|
259
|
+
while (Date.now() - start < timeoutMs) {
|
|
260
|
+
await new Promise(resolve => setTimeout(resolve, pollIntervalMs));
|
|
261
|
+
if (fs.existsSync(managerMsgPath)) {
|
|
262
|
+
try {
|
|
263
|
+
const lines = fs.readFileSync(managerMsgPath, "utf8").trim().split("\n");
|
|
264
|
+
for (const line of lines) {
|
|
265
|
+
if (!line.trim())
|
|
266
|
+
continue;
|
|
267
|
+
const parsed = JSON.parse(line);
|
|
268
|
+
if (parsed.traceId === traceId && parsed.category === "ALERT" && parsed.action === `MUTATION:${filePath}`) {
|
|
269
|
+
if (parsed.status === "APPROVED") {
|
|
270
|
+
statusData[statusKey] = { state: "EXECUTING", task: originalTask };
|
|
271
|
+
fs.writeFileSync(statusPath, JSON.stringify(statusData, null, 2));
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
else if (parsed.status === "PROCESSED" || parsed.status === "DENIED") {
|
|
275
|
+
throw new Error("Security Exception: High-risk operation was explicitly DENIED.");
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
catch (err) {
|
|
281
|
+
if (err.message.includes("explicitly DENIED"))
|
|
282
|
+
throw err;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
statusData[statusKey] = { state: "EXECUTING", task: originalTask };
|
|
287
|
+
try {
|
|
288
|
+
fs.writeFileSync(statusPath, JSON.stringify(statusData, null, 2));
|
|
289
|
+
}
|
|
290
|
+
catch { /* ignore */ }
|
|
291
|
+
throw new Error("Security Exception: High-risk operation timed out waiting for approval.");
|
|
292
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enterprise Base Error class for the Agent Atabey Framework.
|
|
3
|
+
*/
|
|
4
|
+
export class AtabeyBaseError extends Error {
|
|
5
|
+
code;
|
|
6
|
+
timestamp;
|
|
7
|
+
details;
|
|
8
|
+
solution;
|
|
9
|
+
constructor(message, code = "ATABEY_INTERNAL_ERROR", details, solution) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = this.constructor.name;
|
|
12
|
+
this.code = code;
|
|
13
|
+
this.timestamp = new Date();
|
|
14
|
+
this.details = details;
|
|
15
|
+
this.solution = solution;
|
|
16
|
+
// Ensure proper prototype chain and capture stack trace
|
|
17
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
18
|
+
if (Error.captureStackTrace) {
|
|
19
|
+
Error.captureStackTrace(this, this.constructor);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Converts the error into a structured JSON log format.
|
|
24
|
+
*/
|
|
25
|
+
toJSON() {
|
|
26
|
+
return {
|
|
27
|
+
name: this.name,
|
|
28
|
+
message: this.message,
|
|
29
|
+
code: this.code,
|
|
30
|
+
timestamp: this.timestamp.toISOString(),
|
|
31
|
+
details: this.details,
|
|
32
|
+
solution: this.solution,
|
|
33
|
+
stack: this.stack,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Thrown when configuration loading or validation fails.
|
|
39
|
+
*/
|
|
40
|
+
export class ConfigurationError extends AtabeyBaseError {
|
|
41
|
+
constructor(message, details, solution) {
|
|
42
|
+
super(message, "CONFIGURATION_ERROR", details, solution);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Thrown when data schema or payload validation fails.
|
|
47
|
+
*/
|
|
48
|
+
export class ValidationError extends AtabeyBaseError {
|
|
49
|
+
constructor(message, details, solution) {
|
|
50
|
+
super(message, "VALIDATION_ERROR", details, solution);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Thrown when adapter initialization or execution fails.
|
|
55
|
+
*/
|
|
56
|
+
export class AdapterError extends AtabeyBaseError {
|
|
57
|
+
constructor(message, adapterId, details, solution) {
|
|
58
|
+
super(`Adapter '${adapterId}' failure: ${message}`, "ADAPTER_ERROR", details, solution);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Thrown when orchestration or agent communication fails.
|
|
63
|
+
*/
|
|
64
|
+
export class OrchestrationError extends AtabeyBaseError {
|
|
65
|
+
constructor(message, details, solution) {
|
|
66
|
+
super(message, "ORCHESTRATION_ERROR", details, solution);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
/**
|
|
4
|
+
* Ensures directory existence.
|
|
5
|
+
*/
|
|
6
|
+
export function ensureDir(dirPath) {
|
|
7
|
+
if (!fs.existsSync(dirPath)) {
|
|
8
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Atomically writes a text file.
|
|
13
|
+
* Uses a temp file + rename pattern to prevent partial writes.
|
|
14
|
+
* Compatible with src/shared/fs.ts writeTextFile API.
|
|
15
|
+
*/
|
|
16
|
+
export function writeTextFile(filePath, content) {
|
|
17
|
+
const dir = path.dirname(filePath);
|
|
18
|
+
ensureDir(dir);
|
|
19
|
+
const tempPath = `${filePath}.${Math.random().toString(36).slice(2, 9)}.tmp`;
|
|
20
|
+
const finalContent = content.endsWith("\n") ? content : `${content}\n`;
|
|
21
|
+
try {
|
|
22
|
+
fs.writeFileSync(tempPath, finalContent, "utf8");
|
|
23
|
+
fs.renameSync(tempPath, filePath);
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
if (fs.existsSync(tempPath)) {
|
|
27
|
+
try {
|
|
28
|
+
fs.unlinkSync(tempPath);
|
|
29
|
+
}
|
|
30
|
+
catch { /* ignore */ }
|
|
31
|
+
}
|
|
32
|
+
throw err;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** @deprecated Use writeTextFile instead */
|
|
36
|
+
export const writeTextFileAtomic = writeTextFile;
|
|
37
|
+
/**
|
|
38
|
+
* Appends content to a file. Creates parent directories if missing.
|
|
39
|
+
* Compatible with src/shared/fs.ts appendFile API.
|
|
40
|
+
*/
|
|
41
|
+
export function appendFile(filePath, content) {
|
|
42
|
+
const dir = path.dirname(filePath);
|
|
43
|
+
ensureDir(dir);
|
|
44
|
+
fs.appendFileSync(filePath, content, "utf8");
|
|
45
|
+
}
|
|
46
|
+
/** @deprecated Use appendFile instead */
|
|
47
|
+
export const appendFileSafe = appendFile;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import os from "os";
|
|
3
|
+
import path from "path";
|
|
4
|
+
const CWD = process.cwd();
|
|
5
|
+
const HOME = os.homedir();
|
|
6
|
+
const FRAMEWORK = {
|
|
7
|
+
CORE_DIR: ".atabey",
|
|
8
|
+
};
|
|
9
|
+
const FRAMEWORK_DIR_CANDIDATES = [
|
|
10
|
+
".atabey",
|
|
11
|
+
".agents",
|
|
12
|
+
".claude",
|
|
13
|
+
".gemini",
|
|
14
|
+
".grok",
|
|
15
|
+
".cursor",
|
|
16
|
+
];
|
|
17
|
+
const MCP = {
|
|
18
|
+
TEST_DIR_ENV: "ATABEY_TEST_DIR",
|
|
19
|
+
};
|
|
20
|
+
function findFrameworkDir(basePath) {
|
|
21
|
+
try {
|
|
22
|
+
const pkgPath = path.join(basePath, "package.json");
|
|
23
|
+
if (fs.existsSync(pkgPath)) {
|
|
24
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
25
|
+
if (pkg.atabey && typeof pkg.atabey.frameworkDir === "string") {
|
|
26
|
+
const customDir = path.join(basePath, pkg.atabey.frameworkDir);
|
|
27
|
+
if (fs.existsSync(customDir))
|
|
28
|
+
return customDir;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// ignore
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
export function isFrameworkDevelopmentRepo() {
|
|
38
|
+
try {
|
|
39
|
+
const pkgPath = path.join(CWD, "package.json");
|
|
40
|
+
if (fs.existsSync(pkgPath)) {
|
|
41
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
42
|
+
if (pkg.name === "atabey") {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// ignore
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
export function getConfigDir() {
|
|
53
|
+
const localDir = findFrameworkDir(CWD);
|
|
54
|
+
if (localDir)
|
|
55
|
+
return localDir;
|
|
56
|
+
// Check for standard local directories if package.json doesn't specify
|
|
57
|
+
const localCandidates = [...FRAMEWORK_DIR_CANDIDATES, ".agent"];
|
|
58
|
+
for (const cand of localCandidates) {
|
|
59
|
+
const p = path.join(CWD, cand);
|
|
60
|
+
if (fs.existsSync(p))
|
|
61
|
+
return p;
|
|
62
|
+
}
|
|
63
|
+
// In dev repo, don't fall back to global dir. Point to local default.
|
|
64
|
+
if (isFrameworkDevelopmentRepo()) {
|
|
65
|
+
return path.join(CWD, FRAMEWORK.CORE_DIR);
|
|
66
|
+
}
|
|
67
|
+
return path.join(HOME, FRAMEWORK.CORE_DIR);
|
|
68
|
+
}
|
|
69
|
+
export function getFrameworkDir() {
|
|
70
|
+
const testDir = process.env[MCP.TEST_DIR_ENV];
|
|
71
|
+
if (testDir)
|
|
72
|
+
return testDir;
|
|
73
|
+
return getConfigDir();
|
|
74
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { resolveFrameworkDir } from "./security.js";
|
|
4
|
+
export const Metrics = {
|
|
5
|
+
/**
|
|
6
|
+
* Estimates tokens based on character count (rough heuristic: 1 token ~= 4 chars).
|
|
7
|
+
*/
|
|
8
|
+
estimateTokens: (text) => {
|
|
9
|
+
return Math.ceil(text.length / 4);
|
|
10
|
+
},
|
|
11
|
+
/**
|
|
12
|
+
* Logs the token usage and action to the observability metrics file.
|
|
13
|
+
*/
|
|
14
|
+
logUsage: (projectRoot, agent, action, tokens) => {
|
|
15
|
+
Metrics.saveMetric(projectRoot, {
|
|
16
|
+
timestamp: new Date().toISOString(),
|
|
17
|
+
agent,
|
|
18
|
+
action,
|
|
19
|
+
estimatedTokens: tokens
|
|
20
|
+
});
|
|
21
|
+
},
|
|
22
|
+
/**
|
|
23
|
+
* Logs an error occurrence to the observability metrics file.
|
|
24
|
+
*/
|
|
25
|
+
logError: (projectRoot, agent, action, error) => {
|
|
26
|
+
Metrics.saveMetric(projectRoot, {
|
|
27
|
+
timestamp: new Date().toISOString(),
|
|
28
|
+
agent,
|
|
29
|
+
action: `ERROR: ${action}`,
|
|
30
|
+
estimatedTokens: 0,
|
|
31
|
+
error
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
/**
|
|
35
|
+
* Internal helper to save metric entries.
|
|
36
|
+
*/
|
|
37
|
+
saveMetric: (projectRoot, entry) => {
|
|
38
|
+
const frameworkDir = resolveFrameworkDir(projectRoot);
|
|
39
|
+
const metricsPath = path.join(projectRoot, frameworkDir, "observability/metrics.json");
|
|
40
|
+
try {
|
|
41
|
+
const metricsDir = path.dirname(metricsPath);
|
|
42
|
+
if (!fs.existsSync(metricsDir))
|
|
43
|
+
fs.mkdirSync(metricsDir, { recursive: true });
|
|
44
|
+
let currentMetrics = [];
|
|
45
|
+
if (fs.existsSync(metricsPath)) {
|
|
46
|
+
currentMetrics = JSON.parse(fs.readFileSync(metricsPath, "utf8"));
|
|
47
|
+
}
|
|
48
|
+
currentMetrics.push(entry);
|
|
49
|
+
// Keep only last 100 entries to save space
|
|
50
|
+
if (currentMetrics.length > 100)
|
|
51
|
+
currentMetrics.shift();
|
|
52
|
+
fs.writeFileSync(metricsPath, JSON.stringify(currentMetrics, null, 2));
|
|
53
|
+
}
|
|
54
|
+
catch { /* ignore: metrics should not block the main process */ }
|
|
55
|
+
}
|
|
56
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { resolveFrameworkDir } from "./security.js";
|
|
4
|
+
function globToRegex(glob) {
|
|
5
|
+
const escaped = glob.replace(/[.+^${}()|[\]\\]/g, "\\$&");
|
|
6
|
+
const step1 = escaped.replace(/\*\*/g, "__DBL_STR__");
|
|
7
|
+
const step2 = step1.replace(/\*/g, "[^/]*");
|
|
8
|
+
const regexStr = "^" + step2.replace(/__DBL_STR__/g, ".*") + "$";
|
|
9
|
+
return new RegExp(regexStr);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Validates if the active agent has write permission for the target file.
|
|
13
|
+
* Automatically identifies the active agent by checking the status.json store
|
|
14
|
+
* for the agent in the "EXECUTING" state.
|
|
15
|
+
*/
|
|
16
|
+
export function verifyWritePermission(projectRoot, targetFilePath) {
|
|
17
|
+
const frameworkDir = resolveFrameworkDir(projectRoot);
|
|
18
|
+
const absoluteFrameworkPath = path.isAbsolute(frameworkDir)
|
|
19
|
+
? frameworkDir
|
|
20
|
+
: path.resolve(projectRoot, frameworkDir);
|
|
21
|
+
const matrixPath = path.join(absoluteFrameworkPath, "permission-matrix.json");
|
|
22
|
+
// If no permission matrix exists, skip enforcement (default allow)
|
|
23
|
+
if (!fs.existsSync(matrixPath)) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
let matrix;
|
|
27
|
+
try {
|
|
28
|
+
matrix = JSON.parse(fs.readFileSync(matrixPath, "utf8"));
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
throw new Error(`Failed to parse permission-matrix.json: ${String(e)}`, { cause: e });
|
|
32
|
+
}
|
|
33
|
+
// Determine the active agent from status.json
|
|
34
|
+
const statusPath = path.join(absoluteFrameworkPath, "memory", "status.json");
|
|
35
|
+
let activeAgent = null;
|
|
36
|
+
if (fs.existsSync(statusPath)) {
|
|
37
|
+
try {
|
|
38
|
+
const status = JSON.parse(fs.readFileSync(statusPath, "utf8"));
|
|
39
|
+
// Find an agent that is currently in the EXECUTING state
|
|
40
|
+
for (const [agentName, info] of Object.entries(status)) {
|
|
41
|
+
const data = info;
|
|
42
|
+
if (data.state === "EXECUTING") {
|
|
43
|
+
activeAgent = agentName.startsWith("@") ? agentName : `@${agentName}`;
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
// Log warning but don't crash, default to allowing if status can't be parsed
|
|
50
|
+
process.stderr.write(`[Permissions] Warning: Failed to read status.json: ${String(e)}\n`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// If no active executing agent is found, default to allowing
|
|
54
|
+
if (!activeAgent) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const agentRules = matrix[activeAgent];
|
|
58
|
+
// If no rules defined for the agent, default to allowing
|
|
59
|
+
if (!agentRules || !agentRules.write) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// Resolve target path relative to project root for glob matching
|
|
63
|
+
const relativeTargetPath = path.relative(projectRoot, path.resolve(projectRoot, targetFilePath));
|
|
64
|
+
const allowed = agentRules.write.some(glob => {
|
|
65
|
+
const regex = globToRegex(glob);
|
|
66
|
+
return regex.test(relativeTargetPath);
|
|
67
|
+
});
|
|
68
|
+
if (!allowed) {
|
|
69
|
+
throw new Error(`Permission Denied: Agent ${activeAgent} is not authorized to write to "${relativeTargetPath}". Matrix rules restrict writes to: [${agentRules.write.join(", ")}].`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import { FRAMEWORK, MCP, UNIFIED_HUB_DIR } from "../constants.js"; // New import
|
|
4
|
+
import os from "os"; // Need os.homedir()
|
|
5
|
+
/**
|
|
6
|
+
* Validates and resolves a user-provided path to prevent path traversal attacks.
|
|
7
|
+
* Ensures the resolved path stays within the project root boundary.
|
|
8
|
+
*/
|
|
9
|
+
export function safePath(projectRoot, userPath) {
|
|
10
|
+
const resolved = path.resolve(projectRoot, userPath);
|
|
11
|
+
const normalizedRoot = path.resolve(projectRoot);
|
|
12
|
+
if (!resolved.startsWith(normalizedRoot + path.sep) && resolved !== normalizedRoot) {
|
|
13
|
+
throw new Error(`Access denied: path "${userPath}" escapes project root.`);
|
|
14
|
+
}
|
|
15
|
+
return resolved;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Resolves the active framework directory.
|
|
19
|
+
* Priority: ATABEY_TEST_DIR (env) -> package.json `atabey.frameworkDir` -> `.atabey` -> other adapter dirs -> global HOME.
|
|
20
|
+
*/
|
|
21
|
+
export function resolveFrameworkDir(projectRoot) {
|
|
22
|
+
// For test environments, use the explicitly set test directory.
|
|
23
|
+
const testDir = process.env[MCP.TEST_DIR_ENV];
|
|
24
|
+
if (testDir)
|
|
25
|
+
return testDir;
|
|
26
|
+
// 1. Authoritative source: read from package.json if present
|
|
27
|
+
try {
|
|
28
|
+
const pkgPath = path.join(projectRoot, "package.json");
|
|
29
|
+
if (fs.existsSync(pkgPath)) {
|
|
30
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
31
|
+
const atabeyConfig = pkg["atabey"];
|
|
32
|
+
if (atabeyConfig && typeof atabeyConfig["frameworkDir"] === "string") {
|
|
33
|
+
// Ensure the path is relative if it's within the project, otherwise use as-is.
|
|
34
|
+
const resolvedDir = path.resolve(projectRoot, atabeyConfig["frameworkDir"]);
|
|
35
|
+
if (resolvedDir.startsWith(path.resolve(projectRoot))) {
|
|
36
|
+
return path.relative(projectRoot, resolvedDir);
|
|
37
|
+
}
|
|
38
|
+
return atabeyConfig["frameworkDir"];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// ignore — fall through to filesystem scan
|
|
44
|
+
}
|
|
45
|
+
// 2. Filesystem scan in projectRoot for common framework directories
|
|
46
|
+
const localCandidates = [
|
|
47
|
+
FRAMEWORK.CORE_DIR, // .atabey
|
|
48
|
+
UNIFIED_HUB_DIR, // .agents
|
|
49
|
+
// Add other adapter specific directories if needed, or remove if unified is strictly enforced
|
|
50
|
+
];
|
|
51
|
+
for (const candidate of localCandidates) {
|
|
52
|
+
const candidatePath = path.join(projectRoot, candidate);
|
|
53
|
+
if (fs.existsSync(candidatePath)) {
|
|
54
|
+
return candidate;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// 3. Fallback to global home directory.
|
|
58
|
+
const homeDir = os.homedir();
|
|
59
|
+
return path.join(homeDir, FRAMEWORK.CORE_DIR);
|
|
60
|
+
}
|