atabey 0.0.6 → 0.0.8
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 +4 -4
- package/README.md +35 -33
- package/bin/cli.js +2 -2
- package/bin/validate-agent-army.js +6 -6
- package/dist/framework-mcp/src/constants.js +1 -1
- package/dist/framework-mcp/src/constants.js.map +1 -1
- package/dist/framework-mcp/src/index.js +29 -5
- package/dist/framework-mcp/src/index.js.map +1 -1
- package/dist/framework-mcp/src/resources/index.d.ts +10 -0
- package/dist/framework-mcp/src/resources/index.js +59 -0
- package/dist/framework-mcp/src/resources/index.js.map +1 -0
- package/dist/framework-mcp/src/tools/control_plane/locking.js +3 -3
- package/dist/framework-mcp/src/tools/control_plane/locking.js.map +1 -1
- package/dist/framework-mcp/src/tools/control_plane/registry.js +3 -2
- package/dist/framework-mcp/src/tools/control_plane/registry.js.map +1 -1
- package/dist/framework-mcp/src/tools/definitions.js +33 -1
- package/dist/framework-mcp/src/tools/definitions.js.map +1 -1
- package/dist/framework-mcp/src/tools/file_system/batch_surgical_edit.d.ts +1 -1
- package/dist/framework-mcp/src/tools/file_system/batch_surgical_edit.js +8 -3
- package/dist/framework-mcp/src/tools/file_system/batch_surgical_edit.js.map +1 -1
- package/dist/framework-mcp/src/tools/file_system/patch_file.d.ts +1 -1
- package/dist/framework-mcp/src/tools/file_system/patch_file.js +8 -3
- package/dist/framework-mcp/src/tools/file_system/patch_file.js.map +1 -1
- package/dist/framework-mcp/src/tools/file_system/read_file.js +3 -3
- package/dist/framework-mcp/src/tools/file_system/read_file.js.map +1 -1
- package/dist/framework-mcp/src/tools/file_system/replace_text.d.ts +1 -1
- package/dist/framework-mcp/src/tools/file_system/replace_text.js +8 -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 +10 -5
- package/dist/framework-mcp/src/tools/file_system/write_file.js.map +1 -1
- package/dist/framework-mcp/src/tools/framework/audit_deps.js +2 -2
- package/dist/framework-mcp/src/tools/framework/audit_deps.js.map +1 -1
- package/dist/framework-mcp/src/tools/framework/run_tests.js +2 -2
- package/dist/framework-mcp/src/tools/framework/run_tests.js.map +1 -1
- package/dist/framework-mcp/src/tools/framework/submit_plan.d.ts +10 -0
- package/dist/framework-mcp/src/tools/framework/submit_plan.js +14 -0
- package/dist/framework-mcp/src/tools/framework/submit_plan.js.map +1 -0
- package/dist/framework-mcp/src/tools/framework/update_memory.js +1 -1
- package/dist/framework-mcp/src/tools/framework/update_memory.js.map +1 -1
- package/dist/framework-mcp/src/tools/index.js +2 -0
- package/dist/framework-mcp/src/tools/index.js.map +1 -1
- package/dist/framework-mcp/src/tools/memory/get_insights.js +1 -1
- package/dist/framework-mcp/src/tools/memory/get_insights.js.map +1 -1
- package/dist/framework-mcp/src/tools/messaging/log_action.js +1 -1
- package/dist/framework-mcp/src/tools/messaging/log_action.js.map +1 -1
- package/dist/framework-mcp/src/tools/messaging/send_message.js +5 -5
- package/dist/framework-mcp/src/tools/messaging/send_message.js.map +1 -1
- 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/quality/check_lint.js +2 -2
- package/dist/framework-mcp/src/tools/quality/check_lint.js.map +1 -1
- package/dist/framework-mcp/src/tools/search/get_gaps.js +1 -1
- package/dist/framework-mcp/src/tools/search/get_gaps.js.map +1 -1
- package/dist/framework-mcp/src/tools/search/grep_search.js +3 -3
- package/dist/framework-mcp/src/tools/search/grep_search.js.map +1 -1
- package/dist/framework-mcp/src/tools/types.d.ts +1 -0
- package/dist/framework-mcp/src/utils/compliance.d.ts +6 -0
- package/dist/framework-mcp/src/utils/compliance.js +158 -5
- package/dist/framework-mcp/src/utils/compliance.js.map +1 -1
- package/dist/framework-mcp/src/utils/permissions.d.ts +12 -0
- package/dist/framework-mcp/src/utils/permissions.js +72 -0
- package/dist/framework-mcp/src/utils/permissions.js.map +1 -0
- package/dist/framework-mcp/tests/tools/file_system/compliance-risk.test.d.ts +1 -0
- package/dist/framework-mcp/tests/tools/file_system/compliance-risk.test.js +84 -0
- package/dist/framework-mcp/tests/tools/file_system/compliance-risk.test.js.map +1 -0
- package/dist/framework-mcp/tests/tools/file_system/file_system_tools.test.js +31 -31
- package/dist/framework-mcp/tests/tools/file_system/file_system_tools.test.js.map +1 -1
- package/dist/framework-mcp/tests/tools/file_system/permissions.test.d.ts +1 -0
- package/dist/framework-mcp/tests/tools/file_system/permissions.test.js +92 -0
- package/dist/framework-mcp/tests/tools/file_system/permissions.test.js.map +1 -0
- package/dist/framework-mcp/tests/tools/messaging/send_message.test.js +5 -5
- package/dist/framework-mcp/tests/tools/messaging/send_message.test.js.map +1 -1
- package/dist/src/cli/adapters/core.js +13 -20
- package/dist/src/cli/adapters/core.js.map +1 -1
- package/dist/src/cli/adapters/scaffold.js +2 -2
- package/dist/src/cli/adapters/scaffold.js.map +1 -1
- package/dist/src/cli/commands/check.js +5 -3
- package/dist/src/cli/commands/check.js.map +1 -1
- package/dist/src/cli/commands/compliance.js +2 -2
- package/dist/src/cli/commands/compliance.js.map +1 -1
- package/dist/src/cli/commands/contract.js +2 -2
- package/dist/src/cli/commands/contract.js.map +1 -1
- package/dist/src/cli/commands/dashboard.d.ts +5 -0
- package/dist/src/cli/commands/dashboard.js +124 -0
- package/dist/src/cli/commands/dashboard.js.map +1 -0
- package/dist/src/cli/commands/explorer.js +3 -3
- package/dist/src/cli/commands/explorer.js.map +1 -1
- package/dist/src/cli/commands/git.js +3 -3
- package/dist/src/cli/commands/git.js.map +1 -1
- package/dist/src/cli/commands/init/create-agent.d.ts +4 -0
- package/dist/src/cli/commands/init/create-agent.js +59 -0
- package/dist/src/cli/commands/init/create-agent.js.map +1 -0
- package/dist/src/cli/commands/init/scaffold-core.d.ts +1 -0
- package/dist/src/cli/commands/init/scaffold-core.js +11 -7
- package/dist/src/cli/commands/init/scaffold-core.js.map +1 -1
- package/dist/src/cli/commands/init/scaffold-docs.d.ts +1 -0
- package/dist/src/cli/commands/init/scaffold-docs.js +4 -6
- package/dist/src/cli/commands/init/scaffold-docs.js.map +1 -1
- package/dist/src/cli/commands/init/scaffold-ops.js +4 -4
- package/dist/src/cli/commands/init/scaffold-ops.js.map +1 -1
- package/dist/src/cli/commands/init/scaffold-standards.js +10 -8
- package/dist/src/cli/commands/init/scaffold-standards.js.map +1 -1
- package/dist/src/cli/commands/init.js +26 -10
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/knowledge.js +3 -3
- package/dist/src/cli/commands/knowledge.js.map +1 -1
- package/dist/src/cli/commands/lint.js +2 -2
- package/dist/src/cli/commands/lint.js.map +1 -1
- package/dist/src/cli/commands/log.js +6 -28
- package/dist/src/cli/commands/log.js.map +1 -1
- package/dist/src/cli/commands/orchestrate.d.ts +10 -17
- package/dist/src/cli/commands/orchestrate.js +92 -341
- package/dist/src/cli/commands/orchestrate.js.map +1 -1
- package/dist/src/cli/commands/plan.d.ts +5 -0
- package/dist/src/cli/commands/plan.js +80 -59
- package/dist/src/cli/commands/plan.js.map +1 -1
- package/dist/src/cli/commands/script.js +3 -3
- package/dist/src/cli/commands/script.js.map +1 -1
- package/dist/src/cli/commands/security.js +2 -2
- package/dist/src/cli/commands/security.js.map +1 -1
- package/dist/src/cli/commands/status.js +65 -8
- package/dist/src/cli/commands/status.js.map +1 -1
- package/dist/src/cli/commands/trace.d.ts +4 -0
- package/dist/src/cli/commands/trace.js +83 -2
- package/dist/src/cli/commands/trace.js.map +1 -1
- package/dist/src/cli/index.js +68 -18
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/cli/shims.js +14 -14
- package/dist/src/cli/utils/claude.js +1 -1
- package/dist/src/cli/utils/claude.js.map +1 -1
- package/dist/src/cli/utils/compliance.js +7 -1
- package/dist/src/cli/utils/compliance.js.map +1 -1
- package/dist/src/cli/utils/fs.js +1 -1
- package/dist/src/cli/utils/fs.js.map +1 -1
- package/dist/src/cli/utils/i18n.d.ts +1 -0
- package/dist/src/cli/utils/i18n.js +2 -0
- package/dist/src/cli/utils/i18n.js.map +1 -1
- package/dist/src/cli/utils/memory.d.ts +12 -3
- package/dist/src/cli/utils/memory.js +39 -31
- package/dist/src/cli/utils/memory.js.map +1 -1
- package/dist/src/cli/utils/pkg.js +2 -2
- package/dist/src/cli/utils/pkg.js.map +1 -1
- package/dist/src/cli/utils/schemas.d.ts +8 -8
- package/dist/src/cli/utils/ui.js +4 -4
- package/dist/src/cli/utils/ui.js.map +1 -1
- package/dist/src/contracts/tasks.d.ts +2 -2
- package/dist/src/dashboard/vite.config.d.ts +2 -0
- package/dist/src/dashboard/vite.config.js +16 -0
- package/dist/src/dashboard/vite.config.js.map +1 -0
- package/dist/src/modules/adapters/definitions.js +10 -10
- package/dist/src/modules/adapters/definitions.js.map +1 -1
- package/dist/src/modules/adapters/shared.js +4 -4
- package/dist/src/modules/adapters/shared.js.map +1 -1
- package/dist/src/modules/agents/definitions.d.ts +19 -0
- package/dist/src/modules/agents/definitions.js +74 -21
- package/dist/src/modules/agents/definitions.js.map +1 -1
- package/dist/src/modules/agents/registry/backend.js +8 -0
- package/dist/src/modules/agents/registry/backend.js.map +1 -1
- package/dist/src/modules/agents/registry/database.js +7 -0
- package/dist/src/modules/agents/registry/database.js.map +1 -1
- package/dist/src/modules/agents/registry/devops.js +6 -0
- package/dist/src/modules/agents/registry/devops.js.map +1 -1
- package/dist/src/modules/agents/registry/frontend.js +8 -0
- package/dist/src/modules/agents/registry/frontend.js.map +1 -1
- package/dist/src/modules/agents/registry/security.js +6 -0
- package/dist/src/modules/agents/registry/security.js.map +1 -1
- package/dist/src/modules/agents/types.d.ts +2 -0
- package/dist/src/modules/engines/evaluation-engine.d.ts +11 -0
- package/dist/src/modules/engines/evaluation-engine.js +103 -0
- package/dist/src/modules/engines/evaluation-engine.js.map +1 -0
- package/dist/src/modules/engines/health-engine.d.ts +16 -0
- package/dist/src/modules/engines/health-engine.js +50 -0
- package/dist/src/modules/engines/health-engine.js.map +1 -0
- package/dist/src/modules/engines/planning-engine.d.ts +25 -0
- package/dist/src/modules/engines/planning-engine.js +79 -0
- package/dist/src/modules/engines/planning-engine.js.map +1 -0
- package/dist/src/modules/engines/risk-engine.d.ts +18 -0
- package/dist/src/modules/engines/risk-engine.js +106 -0
- package/dist/src/modules/engines/risk-engine.js.map +1 -0
- package/dist/src/modules/engines/routing-engine.d.ts +11 -0
- package/dist/src/modules/engines/routing-engine.js +74 -0
- package/dist/src/modules/engines/routing-engine.js.map +1 -0
- package/dist/src/modules/engines/types.d.ts +47 -0
- package/dist/src/modules/engines/types.js +2 -0
- package/dist/src/modules/engines/types.js.map +1 -0
- package/dist/src/shared/constants.d.ts +6 -2
- package/dist/src/shared/constants.js +5 -1
- package/dist/src/shared/constants.js.map +1 -1
- package/dist/src/shared/fs.d.ts +1 -0
- package/dist/src/shared/fs.js +4 -0
- package/dist/src/shared/fs.js.map +1 -1
- package/dist/src/shared/storage.d.ts +60 -0
- package/dist/src/shared/storage.js +208 -0
- package/dist/src/shared/storage.js.map +1 -0
- package/dist/tests/adapter.test.js +3 -2
- package/dist/tests/adapter.test.js.map +1 -1
- package/dist/tests/agent-memory-v2.test.d.ts +1 -0
- package/dist/tests/agent-memory-v2.test.js +68 -0
- package/dist/tests/agent-memory-v2.test.js.map +1 -0
- package/dist/tests/agents-definitions.test.js +42 -0
- package/dist/tests/agents-definitions.test.js.map +1 -1
- package/dist/tests/integration/hermes_locking.test.js +7 -10
- package/dist/tests/integration/hermes_locking.test.js.map +1 -1
- package/dist/tests/orchestrate.test.js +5 -1
- package/dist/tests/orchestrate.test.js.map +1 -1
- package/dist/tests/orchestrator-dependencies.test.d.ts +1 -0
- package/dist/tests/orchestrator-dependencies.test.js +52 -0
- package/dist/tests/orchestrator-dependencies.test.js.map +1 -0
- package/dist/tests/plan.test.d.ts +1 -0
- package/dist/tests/plan.test.js +63 -0
- package/dist/tests/plan.test.js.map +1 -0
- package/dist/tests/planning-engine.test.d.ts +1 -0
- package/dist/tests/planning-engine.test.js +50 -0
- package/dist/tests/planning-engine.test.js.map +1 -0
- package/dist/tests/status-cost.test.d.ts +1 -0
- package/dist/tests/status-cost.test.js +54 -0
- package/dist/tests/status-cost.test.js.map +1 -0
- package/dist/tests/status.test.js +8 -7
- package/dist/tests/status.test.js.map +1 -1
- package/dist/tests/trace-replay.test.d.ts +1 -0
- package/dist/tests/trace-replay.test.js +65 -0
- package/dist/tests/trace-replay.test.js.map +1 -0
- package/dist/tests/trace.test.js +14 -7
- package/dist/tests/trace.test.js.map +1 -1
- package/dist/ui/assets/index-Bkt7APzu.css +1 -0
- package/dist/ui/assets/index-CeX-06mI.js +49 -0
- package/dist/ui/index.html +14 -0
- package/framework-mcp/dist/constants.js +1 -1
- package/framework-mcp/{src/constants.ts → dist/framework-mcp/src/constants.js} +4 -18
- package/framework-mcp/{src/index.ts → dist/framework-mcp/src/index.js} +52 -53
- package/framework-mcp/dist/framework-mcp/src/resources/index.js +58 -0
- package/framework-mcp/{src/tools/control_plane/locking.ts → dist/framework-mcp/src/tools/control_plane/locking.js} +14 -21
- package/framework-mcp/{src/tools/control_plane/registry.ts → dist/framework-mcp/src/tools/control_plane/registry.js} +8 -11
- package/framework-mcp/{src/tools/definitions.ts → dist/framework-mcp/src/tools/definitions.js} +35 -5
- package/framework-mcp/{src/tools/file_system/batch_surgical_edit.ts → dist/framework-mcp/src/tools/file_system/batch_surgical_edit.js} +16 -31
- package/framework-mcp/{src/tools/file_system/patch_file.ts → dist/framework-mcp/src/tools/file_system/patch_file.js} +9 -14
- package/framework-mcp/{src/tools/file_system/read_file.ts → dist/framework-mcp/src/tools/file_system/read_file.js} +9 -16
- package/framework-mcp/{src/tools/file_system/replace_text.ts → dist/framework-mcp/src/tools/file_system/replace_text.js} +13 -17
- package/framework-mcp/{src/tools/file_system/write_file.ts → dist/framework-mcp/src/tools/file_system/write_file.js} +14 -16
- package/framework-mcp/{src/tools/framework/audit_deps.ts → dist/framework-mcp/src/tools/framework/audit_deps.js} +9 -17
- package/framework-mcp/{src/tools/framework/get_status.ts → dist/framework-mcp/src/tools/framework/get_status.js} +1 -3
- package/framework-mcp/{src/tools/framework/orchestrate.ts → dist/framework-mcp/src/tools/framework/orchestrate.js} +1 -3
- package/framework-mcp/{src/tools/framework/run_tests.ts → dist/framework-mcp/src/tools/framework/run_tests.js} +9 -12
- package/framework-mcp/dist/framework-mcp/src/tools/framework/submit_plan.js +13 -0
- package/framework-mcp/{src/tools/framework/update_contract_hash.ts → dist/framework-mcp/src/tools/framework/update_contract_hash.js} +1 -3
- package/framework-mcp/{src/tools/framework/update_memory.ts → dist/framework-mcp/src/tools/framework/update_memory.js} +2 -4
- package/framework-mcp/{src/tools/index.ts → dist/framework-mcp/src/tools/index.js} +5 -7
- package/framework-mcp/{src/tools/memory/get_insights.ts → dist/framework-mcp/src/tools/memory/get_insights.js} +4 -11
- package/framework-mcp/{src/tools/memory/read_memory.ts → dist/framework-mcp/src/tools/memory/read_memory.js} +3 -6
- package/framework-mcp/{src/tools/messaging/log_action.ts → dist/framework-mcp/src/tools/messaging/log_action.js} +2 -8
- package/framework-mcp/{src/tools/messaging/send_message.ts → dist/framework-mcp/src/tools/messaging/send_message.js} +19 -22
- package/framework-mcp/{src/tools/observability/check_ports.ts → dist/framework-mcp/src/tools/observability/check_ports.js} +6 -10
- package/framework-mcp/{src/tools/observability/get_health.ts → dist/framework-mcp/src/tools/observability/get_health.js} +1 -6
- package/framework-mcp/{src/tools/quality/check_lint.ts → dist/framework-mcp/src/tools/quality/check_lint.js} +3 -9
- package/framework-mcp/{src/tools/search/get_gaps.ts → dist/framework-mcp/src/tools/search/get_gaps.js} +12 -18
- package/framework-mcp/{src/tools/search/get_map.ts → dist/framework-mcp/src/tools/search/get_map.js} +14 -19
- package/framework-mcp/{src/tools/search/grep_search.ts → dist/framework-mcp/src/tools/search/grep_search.js} +26 -26
- package/framework-mcp/{src/tools/search/list_dir.ts → dist/framework-mcp/src/tools/search/list_dir.js} +4 -10
- package/framework-mcp/{src/tools/shell/run_command.ts → dist/framework-mcp/src/tools/shell/run_command.js} +1 -11
- package/framework-mcp/dist/framework-mcp/src/tools/types.js +1 -0
- package/framework-mcp/{src/utils/cli.ts → dist/framework-mcp/src/utils/cli.js} +25 -19
- package/framework-mcp/dist/framework-mcp/src/utils/compliance.js +231 -0
- package/framework-mcp/{src/utils/fs.ts → dist/framework-mcp/src/utils/fs.js} +9 -10
- package/framework-mcp/{src/utils/metrics.ts → dist/framework-mcp/src/utils/metrics.js} +11 -28
- package/framework-mcp/dist/framework-mcp/src/utils/permissions.js +71 -0
- package/framework-mcp/{src/utils/security.ts → dist/framework-mcp/src/utils/security.js} +9 -15
- package/framework-mcp/dist/index.js +29 -5
- package/framework-mcp/dist/resources/index.js +58 -0
- package/{src/cli/adapters/core.ts → framework-mcp/dist/src/cli/adapters/core.js} +21 -41
- package/{src/cli/adapters/index.ts → framework-mcp/dist/src/cli/adapters/index.js} +1 -1
- package/{src/cli/adapters/paths.ts → framework-mcp/dist/src/cli/adapters/paths.js} +19 -53
- package/{src/cli/adapters/scaffold.ts → framework-mcp/dist/src/cli/adapters/scaffold.js} +18 -42
- package/{src/cli/adapters/utils.ts → framework-mcp/dist/src/cli/adapters/utils.js} +19 -31
- package/{src/cli/commands/approve.ts → framework-mcp/dist/src/cli/commands/approve.js} +15 -25
- package/{src/cli/commands/check.ts → framework-mcp/dist/src/cli/commands/check.js} +36 -43
- package/{src/cli/commands/compliance.ts → framework-mcp/dist/src/cli/commands/compliance.js} +10 -15
- package/{src/cli/commands/contract.ts → framework-mcp/dist/src/cli/commands/contract.js} +13 -31
- package/framework-mcp/dist/src/cli/commands/dashboard.js +123 -0
- package/{src/cli/commands/explorer.ts → framework-mcp/dist/src/cli/commands/explorer.js} +14 -17
- package/{src/cli/commands/git.ts → framework-mcp/dist/src/cli/commands/git.js} +15 -14
- package/framework-mcp/dist/src/cli/commands/init/create-agent.js +58 -0
- package/{src/cli/commands/init/scaffold-core.ts → framework-mcp/dist/src/cli/commands/init/scaffold-core.js} +35 -59
- package/framework-mcp/dist/src/cli/commands/init/scaffold-docs.js +34 -0
- package/{src/cli/commands/init/scaffold-ops.ts → framework-mcp/dist/src/cli/commands/init/scaffold-ops.js} +19 -22
- package/{src/cli/commands/init/scaffold-standards.ts → framework-mcp/dist/src/cli/commands/init/scaffold-standards.js} +20 -20
- package/{src/cli/commands/init.ts → framework-mcp/dist/src/cli/commands/init.js} +51 -77
- package/{src/cli/commands/knowledge.ts → framework-mcp/dist/src/cli/commands/knowledge.js} +9 -11
- package/{src/cli/commands/lint.ts → framework-mcp/dist/src/cli/commands/lint.js} +5 -6
- package/framework-mcp/dist/src/cli/commands/log.js +10 -0
- package/{src/cli/commands/memory.ts → framework-mcp/dist/src/cli/commands/memory.js} +1 -3
- package/framework-mcp/dist/src/cli/commands/orchestrate.js +159 -0
- package/framework-mcp/dist/src/cli/commands/plan.js +117 -0
- package/{src/cli/commands/script.ts → framework-mcp/dist/src/cli/commands/script.js} +6 -7
- package/{src/cli/commands/security.ts → framework-mcp/dist/src/cli/commands/security.js} +6 -8
- package/framework-mcp/dist/src/cli/commands/status.js +97 -0
- package/framework-mcp/dist/src/cli/commands/trace.js +109 -0
- package/{src/cli/index.ts → framework-mcp/dist/src/cli/index.js} +80 -64
- package/{src/cli/shims.ts → framework-mcp/dist/src/cli/shims.js} +15 -15
- package/{src/cli/utils/claude.ts → framework-mcp/dist/src/cli/utils/claude.js} +8 -15
- package/{src/cli/utils/compliance.ts → framework-mcp/dist/src/cli/utils/compliance.js} +18 -36
- package/{src/cli/utils/config-schema.ts → framework-mcp/dist/src/cli/utils/config-schema.js} +0 -6
- package/{src/cli/utils/fs.ts → framework-mcp/dist/src/cli/utils/fs.js} +34 -67
- package/{src/cli/utils/i18n.ts → framework-mcp/dist/src/cli/utils/i18n.js} +3 -17
- package/{src/cli/utils/memory.ts → framework-mcp/dist/src/cli/utils/memory.js} +87 -114
- package/{src/cli/utils/pkg.ts → framework-mcp/dist/src/cli/utils/pkg.js} +120 -155
- package/{src/cli/utils/schemas.ts → framework-mcp/dist/src/cli/utils/schemas.js} +0 -3
- package/{src/cli/utils/string.ts → framework-mcp/dist/src/cli/utils/string.js} +18 -24
- package/{src/cli/utils/time.ts → framework-mcp/dist/src/cli/utils/time.js} +4 -4
- package/{src/cli/utils/ui.ts → framework-mcp/dist/src/cli/utils/ui.js} +9 -17
- package/{src/contracts/tasks.ts → framework-mcp/dist/src/contracts/tasks.js} +0 -6
- package/framework-mcp/dist/src/dashboard/vite.config.js +15 -0
- package/framework-mcp/dist/src/modules/adapters/definitions.js +140 -0
- package/framework-mcp/dist/src/modules/adapters/registry.js +18 -0
- package/{src/modules/adapters/shared.ts → framework-mcp/dist/src/modules/adapters/shared.js} +9 -25
- package/framework-mcp/dist/src/modules/adapters/types.js +1 -0
- package/{src/modules/agents/definitions.ts → framework-mcp/dist/src/modules/agents/definitions.js} +158 -161
- package/{src/modules/agents/registry/analyst.ts → framework-mcp/dist/src/modules/agents/registry/analyst.js} +9 -14
- package/{src/modules/agents/registry/architect.ts → framework-mcp/dist/src/modules/agents/registry/architect.js} +9 -14
- package/{src/modules/agents/registry/backend.ts → framework-mcp/dist/src/modules/agents/registry/backend.js} +16 -13
- package/{src/modules/agents/registry/database.ts → framework-mcp/dist/src/modules/agents/registry/database.js} +16 -14
- package/{src/modules/agents/registry/devops.ts → framework-mcp/dist/src/modules/agents/registry/devops.js} +15 -14
- package/{src/modules/agents/registry/explorer.ts → framework-mcp/dist/src/modules/agents/registry/explorer.js} +9 -14
- package/{src/modules/agents/registry/frontend.ts → framework-mcp/dist/src/modules/agents/registry/frontend.js} +17 -14
- package/{src/modules/agents/registry/git.ts → framework-mcp/dist/src/modules/agents/registry/git.js} +9 -14
- package/{src/modules/agents/registry/manager.ts → framework-mcp/dist/src/modules/agents/registry/manager.js} +10 -15
- package/{src/modules/agents/registry/mobile.ts → framework-mcp/dist/src/modules/agents/registry/mobile.js} +9 -14
- package/{src/modules/agents/registry/native.ts → framework-mcp/dist/src/modules/agents/registry/native.js} +9 -14
- package/{src/modules/agents/registry/quality.ts → framework-mcp/dist/src/modules/agents/registry/quality.js} +9 -14
- package/{src/modules/agents/registry/security.ts → framework-mcp/dist/src/modules/agents/registry/security.js} +15 -14
- package/framework-mcp/dist/src/modules/agents/types.js +1 -0
- package/framework-mcp/dist/src/modules/engines/evaluation-engine.js +102 -0
- package/framework-mcp/dist/src/modules/engines/health-engine.js +49 -0
- package/framework-mcp/dist/src/modules/engines/planning-engine.js +78 -0
- package/framework-mcp/dist/src/modules/engines/risk-engine.js +105 -0
- package/framework-mcp/dist/src/modules/engines/routing-engine.js +73 -0
- package/framework-mcp/dist/src/modules/engines/types.js +1 -0
- package/{src/modules/skills/definitions.ts → framework-mcp/dist/src/modules/skills/definitions.js} +0 -1
- package/{src/shared/constants.ts → framework-mcp/dist/src/shared/constants.js} +40 -71
- package/{src/shared/errors.ts → framework-mcp/dist/src/shared/errors.js} +10 -17
- package/{src/shared/fs.ts → framework-mcp/dist/src/shared/fs.js} +14 -13
- package/{src/shared/logger.ts → framework-mcp/dist/src/shared/logger.js} +28 -51
- package/framework-mcp/dist/src/shared/storage.js +207 -0
- package/framework-mcp/dist/src/shared/types.js +12 -0
- package/framework-mcp/dist/tools/control_plane/locking.js +3 -3
- package/framework-mcp/dist/tools/control_plane/registry.js +3 -2
- package/framework-mcp/dist/tools/definitions.js +33 -1
- package/framework-mcp/dist/tools/file_system/batch_surgical_edit.js +8 -3
- package/framework-mcp/dist/tools/file_system/patch_file.js +8 -3
- package/framework-mcp/dist/tools/file_system/read_file.js +3 -3
- package/framework-mcp/dist/tools/file_system/replace_text.js +8 -3
- package/framework-mcp/dist/tools/file_system/write_file.js +10 -5
- package/framework-mcp/dist/tools/framework/audit_deps.js +2 -2
- package/framework-mcp/dist/tools/framework/run_tests.js +2 -2
- package/framework-mcp/dist/tools/framework/submit_plan.js +13 -0
- package/framework-mcp/dist/tools/framework/update_memory.js +1 -1
- package/framework-mcp/dist/tools/index.js +2 -0
- package/framework-mcp/dist/tools/memory/get_insights.js +1 -1
- package/framework-mcp/dist/tools/messaging/log_action.js +1 -1
- package/framework-mcp/dist/tools/messaging/send_message.js +5 -5
- package/framework-mcp/dist/tools/observability/check_ports.js +1 -1
- package/framework-mcp/dist/tools/quality/check_lint.js +2 -2
- package/framework-mcp/dist/tools/search/get_gaps.js +1 -1
- package/framework-mcp/dist/tools/search/grep_search.js +3 -3
- package/framework-mcp/dist/utils/compliance.js +158 -5
- package/framework-mcp/dist/utils/permissions.js +71 -0
- package/framework-mcp/package.json +7 -1
- package/mcp.json +1 -1
- package/package.json +10 -6
- package/templates/prompts/contract-design-recipe.md +1 -1
- package/templates/prompts/db-management-recipe.md +3 -3
- package/templates/prompts/deployment-recipe.md +3 -3
- package/templates/prompts/performance-optimization-recipe.md +3 -3
- package/templates/prompts/pull-request-template.md +2 -2
- package/templates/prompts/security-audit-recipe.md +3 -3
- package/templates/standards/crud-governance.md +1 -1
- package/templates/standards/deployment-standards.md +1 -1
- package/templates/standards/governance-standards.md +1 -1
- package/templates/standards/llm-governance.md +1 -1
- package/templates/standards/nextjs-standards.md +13 -0
- package/templates/standards/observability-standards.md +1 -1
- package/templates/standards/security-audit-standards.md +1 -1
- package/templates/standards/security-standards.md +1 -1
- package/templates/standards/testing-standards.md +1 -1
- package/templates/standards/vite-standards.md +13 -0
- package/framework-mcp/package-lock.json +0 -1191
- package/framework-mcp/src/declarations.d.ts +0 -17
- package/framework-mcp/src/tools/types.ts +0 -89
- package/framework-mcp/src/utils/compliance.ts +0 -95
- package/framework-mcp/tests/tools/file_system/file_system_tools.test.ts +0 -212
- package/framework-mcp/tests/tools/messaging/send_message.test.ts +0 -136
- package/framework-mcp/tests/tools/quality/check_lint.test.ts +0 -46
- package/framework-mcp/tests/tools/shell/run_command.test.ts +0 -55
- package/framework-mcp/tsconfig.json +0 -14
- package/src/cli/commands/init/scaffold-docs.ts +0 -44
- package/src/cli/commands/log.ts +0 -37
- package/src/cli/commands/orchestrate.ts +0 -450
- package/src/cli/commands/plan.ts +0 -113
- package/src/cli/commands/status.ts +0 -44
- package/src/cli/commands/trace.ts +0 -31
- package/src/modules/adapters/definitions.ts +0 -171
- package/src/modules/adapters/registry.ts +0 -27
- package/src/modules/adapters/types.ts +0 -16
- package/src/modules/agents/types.ts +0 -37
- package/src/schema/agent-lifecycle-schema.json +0 -59
- package/src/shared/types.ts +0 -20
- /package/{src/contracts/index.ts → framework-mcp/dist/src/contracts/index.js} +0 -0
|
@@ -0,0 +1,231 @@
|
|
|
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")) {
|
|
28
|
+
errors.push(`[ERROR] Corporate Compliance Breach: 'console.${name}' usage is forbidden at line ${sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1}.`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// 2. No Explicit Any Policy
|
|
34
|
+
if (ts.isTypeReferenceNode(node)) {
|
|
35
|
+
if (ts.isIdentifier(node.typeName) && node.typeName.text === "any") {
|
|
36
|
+
if (!filePath.includes("definitions.ts") && !filePath.includes("types.ts")) {
|
|
37
|
+
errors.push(`[ERROR] Corporate Compliance Breach: 'any' type is forbidden at line ${sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1}.`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// 3. Zero UI Library Policy (No @chakra-ui, mui, @shadcn)
|
|
42
|
+
if (ts.isImportDeclaration(node)) {
|
|
43
|
+
const moduleSpecifier = node.moduleSpecifier;
|
|
44
|
+
if (ts.isStringLiteral(moduleSpecifier)) {
|
|
45
|
+
const forbiddenLibs = ["@chakra-ui", "mui", "@shadcn", "antd", "bootstrap"];
|
|
46
|
+
const lib = forbiddenLibs.find(l => moduleSpecifier.text.includes(l));
|
|
47
|
+
if (lib) {
|
|
48
|
+
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.`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Handle 'any' as a keyword type (e.g., parameter: any)
|
|
53
|
+
if (node.kind === ts.SyntaxKind.AnyKeyword) {
|
|
54
|
+
if (!filePath.includes("definitions.ts") && !filePath.includes("types.ts")) {
|
|
55
|
+
errors.push(`[ERROR] Corporate Compliance Breach: 'any' keyword is forbidden at line ${sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1}.`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
ts.forEachChild(node, visit);
|
|
59
|
+
}
|
|
60
|
+
visit(sourceFile);
|
|
61
|
+
// 3. Hardcoded Secrets & PII Guard
|
|
62
|
+
const piiKeywords = [
|
|
63
|
+
{ regex: /API_KEY\s*=\s*['"][^'"]+['"]/i, msg: "Hardcoded API Key" },
|
|
64
|
+
{ regex: /SECRET\s*=\s*['"][^'"]+['"]/i, msg: "Hardcoded Secret" },
|
|
65
|
+
{ regex: /PASSWORD\s*=\s*['"][^'"]+['"]/i, msg: "Hardcoded Password" },
|
|
66
|
+
{ regex: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/, msg: "PII Detected: Email Address" },
|
|
67
|
+
{ regex: /\b\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}\b/, msg: "PII Detected: Credit Card Pattern" }
|
|
68
|
+
];
|
|
69
|
+
for (const { regex, msg } of piiKeywords) {
|
|
70
|
+
if (regex.test(content)) {
|
|
71
|
+
// Allow emails in specific files like README or package.json
|
|
72
|
+
if (msg.includes("Email") && (filePath.endsWith("README.md") || filePath.endsWith("package.json") || filePath.includes("CONTRIBUTING"))) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
errors.push(`[ERROR] Corporate Compliance Breach: ${msg} detected.`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (errors.length > 0) {
|
|
79
|
+
throw new Error(errors.join("\n"));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
export function isHighRiskOperation(content, filePath) {
|
|
83
|
+
const fileName = filePath.toLowerCase();
|
|
84
|
+
// 1. Database Deletions / Table Drops
|
|
85
|
+
if (fileName.endsWith(".sql") || fileName.endsWith(".ts") || fileName.endsWith(".js") || fileName.endsWith(".go")) {
|
|
86
|
+
const dropRegex = /\b(DROP\s+(DATABASE|TABLE|SCHEMA|VIEW|INDEX)|TRUNCATE\s+TABLE)\b/i;
|
|
87
|
+
if (dropRegex.test(content)) {
|
|
88
|
+
return { isRisk: true, reason: "Database structural deletion detected (DROP/TRUNCATE)" };
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// 2. Package Updates
|
|
92
|
+
if (fileName.endsWith("package.json")) {
|
|
93
|
+
return { isRisk: true, reason: "Dependency/package update operation detected" };
|
|
94
|
+
}
|
|
95
|
+
// 3. Deployment / Infrastructure Scripts
|
|
96
|
+
if (fileName.includes("deploy") ||
|
|
97
|
+
fileName.includes("dockerfile") ||
|
|
98
|
+
fileName.includes("docker-compose") ||
|
|
99
|
+
fileName.includes("k8s") ||
|
|
100
|
+
fileName.includes("kubernetes") ||
|
|
101
|
+
fileName.includes("github/workflows")) {
|
|
102
|
+
return { isRisk: true, reason: "Infrastructure or deployment script mutation detected" };
|
|
103
|
+
}
|
|
104
|
+
return { isRisk: false };
|
|
105
|
+
}
|
|
106
|
+
export async function verifyRiskAndAwaitApproval(projectRoot, content, filePath) {
|
|
107
|
+
const assessment = isHighRiskOperation(content, filePath);
|
|
108
|
+
if (!assessment.isRisk) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const frameworkDir = resolveFrameworkDir(projectRoot);
|
|
112
|
+
const absoluteFrameworkPath = path.isAbsolute(frameworkDir)
|
|
113
|
+
? frameworkDir
|
|
114
|
+
: path.resolve(projectRoot, frameworkDir);
|
|
115
|
+
const statusPath = path.join(absoluteFrameworkPath, "memory", "status.json");
|
|
116
|
+
const statePath = path.join(absoluteFrameworkPath, "memory", "state.json");
|
|
117
|
+
const messagesDir = path.join(absoluteFrameworkPath, "messages");
|
|
118
|
+
const managerMsgPath = path.join(messagesDir, "manager.json");
|
|
119
|
+
let activeAgent = null;
|
|
120
|
+
let traceId = "UNKNOWN";
|
|
121
|
+
// 1. Resolve traceId from state.json
|
|
122
|
+
if (fs.existsSync(statePath)) {
|
|
123
|
+
try {
|
|
124
|
+
const state = JSON.parse(fs.readFileSync(statePath, "utf8"));
|
|
125
|
+
if (state && state.traceId) {
|
|
126
|
+
traceId = state.traceId;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch { /* ignore */ }
|
|
130
|
+
}
|
|
131
|
+
// 2. Resolve active agent from status.json
|
|
132
|
+
let statusData = {};
|
|
133
|
+
if (fs.existsSync(statusPath)) {
|
|
134
|
+
try {
|
|
135
|
+
statusData = JSON.parse(fs.readFileSync(statusPath, "utf8"));
|
|
136
|
+
for (const [agentName, info] of Object.entries(statusData)) {
|
|
137
|
+
if (info.state === "EXECUTING") {
|
|
138
|
+
activeAgent = agentName.startsWith("@") ? agentName : `@${agentName}`;
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch { /* ignore */ }
|
|
144
|
+
}
|
|
145
|
+
if (!activeAgent) {
|
|
146
|
+
throw new Error(`Security Exception: High-risk operation blocked. ${assessment.reason}. (No active executing agent found)`);
|
|
147
|
+
}
|
|
148
|
+
// 3. Update active agent status to WAITING_FOR_APPROVAL
|
|
149
|
+
const originalTask = statusData[activeAgent.replace("@", "")]?.task || statusData[activeAgent]?.task || "Executing task";
|
|
150
|
+
const statusKey = activeAgent.replace("@", "");
|
|
151
|
+
statusData[statusKey] = {
|
|
152
|
+
state: "WAITING_FOR_APPROVAL",
|
|
153
|
+
task: `[PAUSED] Waiting for approval: ${assessment.reason} on ${filePath}`
|
|
154
|
+
};
|
|
155
|
+
try {
|
|
156
|
+
fs.writeFileSync(statusPath, JSON.stringify(statusData, null, 2));
|
|
157
|
+
}
|
|
158
|
+
catch { /* ignore */ }
|
|
159
|
+
// 4. Create and append ALERT message to messages/manager.json
|
|
160
|
+
if (!fs.existsSync(messagesDir)) {
|
|
161
|
+
fs.mkdirSync(messagesDir, { recursive: true });
|
|
162
|
+
}
|
|
163
|
+
const alertMsg = {
|
|
164
|
+
timestamp: new Date().toISOString(),
|
|
165
|
+
from: activeAgent,
|
|
166
|
+
to: "@manager",
|
|
167
|
+
category: "ALERT",
|
|
168
|
+
content: `High-risk operation: ${assessment.reason} on ${filePath}`,
|
|
169
|
+
traceId: traceId,
|
|
170
|
+
status: "PENDING",
|
|
171
|
+
priority: "HIGH",
|
|
172
|
+
requiresApproval: true,
|
|
173
|
+
action: `MUTATION:${filePath}`
|
|
174
|
+
};
|
|
175
|
+
try {
|
|
176
|
+
fs.appendFileSync(managerMsgPath, JSON.stringify(alertMsg) + "\n");
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
statusData[statusKey] = { state: "EXECUTING", task: originalTask };
|
|
180
|
+
fs.writeFileSync(statusPath, JSON.stringify(statusData, null, 2));
|
|
181
|
+
throw new Error(`Security Exception: Failed to queue approval request. ${String(err)}`, { cause: err });
|
|
182
|
+
}
|
|
183
|
+
// 5. Polling Loop: Wait for approval (up to 60 seconds)
|
|
184
|
+
const pollIntervalMs = 500;
|
|
185
|
+
const timeoutMs = 60000;
|
|
186
|
+
const start = Date.now();
|
|
187
|
+
while (Date.now() - start < timeoutMs) {
|
|
188
|
+
// Non-blocking wait
|
|
189
|
+
await new Promise(resolve => setTimeout(resolve, pollIntervalMs));
|
|
190
|
+
if (fs.existsSync(managerMsgPath)) {
|
|
191
|
+
try {
|
|
192
|
+
const contentStr = fs.readFileSync(managerMsgPath, "utf8").trim();
|
|
193
|
+
const lines = contentStr.split("\n");
|
|
194
|
+
let isApproved = false;
|
|
195
|
+
let isDenied = false;
|
|
196
|
+
for (const line of lines) {
|
|
197
|
+
if (!line.trim())
|
|
198
|
+
continue;
|
|
199
|
+
const parsed = JSON.parse(line);
|
|
200
|
+
if (parsed.traceId === traceId && parsed.category === "ALERT" && parsed.action === `MUTATION:${filePath}`) {
|
|
201
|
+
if (parsed.status === "APPROVED") {
|
|
202
|
+
isApproved = true;
|
|
203
|
+
}
|
|
204
|
+
else if (parsed.status === "PROCESSED" || parsed.status === "DENIED") {
|
|
205
|
+
isDenied = true;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (isApproved) {
|
|
210
|
+
statusData[statusKey] = { state: "EXECUTING", task: originalTask };
|
|
211
|
+
fs.writeFileSync(statusPath, JSON.stringify(statusData, null, 2));
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
if (isDenied) {
|
|
215
|
+
throw new Error("Security Exception: High-risk operation was explicitly DENIED by user.");
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
catch (err) {
|
|
219
|
+
if (err.message.includes("explicitly DENIED")) {
|
|
220
|
+
throw err;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
statusData[statusKey] = { state: "EXECUTING", task: originalTask };
|
|
226
|
+
try {
|
|
227
|
+
fs.writeFileSync(statusPath, JSON.stringify(statusData, null, 2));
|
|
228
|
+
}
|
|
229
|
+
catch { /* ignore */ }
|
|
230
|
+
throw new Error(`Security Exception: High-risk operation timed out waiting for approval. (${assessment.reason})`);
|
|
231
|
+
}
|
|
@@ -1,36 +1,35 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
|
-
|
|
4
3
|
/**
|
|
5
4
|
* Ensures directory existence.
|
|
6
5
|
*/
|
|
7
|
-
export function ensureDir(dirPath
|
|
6
|
+
export function ensureDir(dirPath) {
|
|
8
7
|
if (!fs.existsSync(dirPath)) {
|
|
9
8
|
fs.mkdirSync(dirPath, { recursive: true });
|
|
10
9
|
}
|
|
11
10
|
}
|
|
12
|
-
|
|
13
11
|
/**
|
|
14
12
|
* Atomically writes a text file.
|
|
15
13
|
*/
|
|
16
|
-
export function writeTextFileAtomic(filePath
|
|
14
|
+
export function writeTextFileAtomic(filePath, content) {
|
|
17
15
|
const dir = path.dirname(filePath);
|
|
18
16
|
ensureDir(dir);
|
|
19
|
-
|
|
20
17
|
const tempPath = `${filePath}.${Math.random().toString(36).slice(2, 9)}.tmp`;
|
|
21
18
|
const finalContent = content.endsWith("\n") ? content : `${content}\n`;
|
|
22
|
-
|
|
23
19
|
try {
|
|
24
20
|
fs.writeFileSync(tempPath, finalContent, "utf8");
|
|
25
21
|
fs.renameSync(tempPath, filePath);
|
|
26
|
-
}
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
27
24
|
if (fs.existsSync(tempPath)) {
|
|
28
|
-
try {
|
|
25
|
+
try {
|
|
26
|
+
fs.unlinkSync(tempPath);
|
|
27
|
+
}
|
|
28
|
+
catch { /* ignore */ }
|
|
29
29
|
}
|
|
30
30
|
throw err;
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
-
|
|
34
33
|
/**
|
|
35
34
|
* Atomically appends to a file (if supported by OS) or simulates it.
|
|
36
35
|
* Note: Real atomic append on POSIX is a single write() call with O_APPEND.
|
|
@@ -38,7 +37,7 @@ export function writeTextFileAtomic(filePath: string, content: string): void {
|
|
|
38
37
|
* as the risk of corruption is lower than a full rewrite, but for logs
|
|
39
38
|
* it's acceptable.
|
|
40
39
|
*/
|
|
41
|
-
export function appendFileSafe(filePath
|
|
40
|
+
export function appendFileSafe(filePath, content) {
|
|
42
41
|
const dir = path.dirname(filePath);
|
|
43
42
|
ensureDir(dir);
|
|
44
43
|
fs.appendFileSync(filePath, content, "utf8");
|
|
@@ -1,31 +1,17 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { resolveFrameworkDir } from "./security.js";
|
|
4
|
-
/**
|
|
5
|
-
* Token and Metric Tracker for Agent Atabey.
|
|
6
|
-
* Estimates token usage and logs operational costs.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
interface MetricEntry {
|
|
10
|
-
timestamp: string;
|
|
11
|
-
agent: string;
|
|
12
|
-
action: string;
|
|
13
|
-
estimatedTokens: number;
|
|
14
|
-
error?: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
4
|
export const Metrics = {
|
|
18
5
|
/**
|
|
19
6
|
* Estimates tokens based on character count (rough heuristic: 1 token ~= 4 chars).
|
|
20
7
|
*/
|
|
21
|
-
estimateTokens: (text
|
|
8
|
+
estimateTokens: (text) => {
|
|
22
9
|
return Math.ceil(text.length / 4);
|
|
23
10
|
},
|
|
24
|
-
|
|
25
11
|
/**
|
|
26
12
|
* Logs the token usage and action to the observability metrics file.
|
|
27
13
|
*/
|
|
28
|
-
logUsage: (projectRoot
|
|
14
|
+
logUsage: (projectRoot, agent, action, tokens) => {
|
|
29
15
|
Metrics.saveMetric(projectRoot, {
|
|
30
16
|
timestamp: new Date().toISOString(),
|
|
31
17
|
agent,
|
|
@@ -33,11 +19,10 @@ export const Metrics = {
|
|
|
33
19
|
estimatedTokens: tokens
|
|
34
20
|
});
|
|
35
21
|
},
|
|
36
|
-
|
|
37
22
|
/**
|
|
38
23
|
* Logs an error occurrence to the observability metrics file.
|
|
39
24
|
*/
|
|
40
|
-
logError: (projectRoot
|
|
25
|
+
logError: (projectRoot, agent, action, error) => {
|
|
41
26
|
Metrics.saveMetric(projectRoot, {
|
|
42
27
|
timestamp: new Date().toISOString(),
|
|
43
28
|
agent,
|
|
@@ -46,28 +31,26 @@ export const Metrics = {
|
|
|
46
31
|
error
|
|
47
32
|
});
|
|
48
33
|
},
|
|
49
|
-
|
|
50
34
|
/**
|
|
51
35
|
* Internal helper to save metric entries.
|
|
52
36
|
*/
|
|
53
|
-
saveMetric: (projectRoot
|
|
37
|
+
saveMetric: (projectRoot, entry) => {
|
|
54
38
|
const frameworkDir = resolveFrameworkDir(projectRoot);
|
|
55
39
|
const metricsPath = path.join(projectRoot, frameworkDir, "observability/metrics.json");
|
|
56
40
|
try {
|
|
57
41
|
const metricsDir = path.dirname(metricsPath);
|
|
58
|
-
if (!fs.existsSync(metricsDir))
|
|
59
|
-
|
|
60
|
-
let currentMetrics
|
|
42
|
+
if (!fs.existsSync(metricsDir))
|
|
43
|
+
fs.mkdirSync(metricsDir, { recursive: true });
|
|
44
|
+
let currentMetrics = [];
|
|
61
45
|
if (fs.existsSync(metricsPath)) {
|
|
62
46
|
currentMetrics = JSON.parse(fs.readFileSync(metricsPath, "utf8"));
|
|
63
47
|
}
|
|
64
|
-
|
|
65
48
|
currentMetrics.push(entry);
|
|
66
|
-
|
|
67
49
|
// Keep only last 100 entries to save space
|
|
68
|
-
if (currentMetrics.length > 100)
|
|
69
|
-
|
|
50
|
+
if (currentMetrics.length > 100)
|
|
51
|
+
currentMetrics.shift();
|
|
70
52
|
fs.writeFileSync(metricsPath, JSON.stringify(currentMetrics, null, 2));
|
|
71
|
-
}
|
|
53
|
+
}
|
|
54
|
+
catch { /* ignore: metrics should not block the main process */ }
|
|
72
55
|
}
|
|
73
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
|
+
}
|
|
@@ -2,37 +2,33 @@ import path from "path";
|
|
|
2
2
|
import fs from "fs";
|
|
3
3
|
import { FRAMEWORK, MCP, UNIFIED_HUB_DIR } from "../constants.js"; // New import
|
|
4
4
|
import os from "os"; // Need os.homedir()
|
|
5
|
-
|
|
6
5
|
/**
|
|
7
6
|
* Validates and resolves a user-provided path to prevent path traversal attacks.
|
|
8
7
|
* Ensures the resolved path stays within the project root boundary.
|
|
9
8
|
*/
|
|
10
|
-
export function safePath(projectRoot
|
|
9
|
+
export function safePath(projectRoot, userPath) {
|
|
11
10
|
const resolved = path.resolve(projectRoot, userPath);
|
|
12
11
|
const normalizedRoot = path.resolve(projectRoot);
|
|
13
|
-
|
|
14
12
|
if (!resolved.startsWith(normalizedRoot + path.sep) && resolved !== normalizedRoot) {
|
|
15
13
|
throw new Error(`Access denied: path "${userPath}" escapes project root.`);
|
|
16
14
|
}
|
|
17
|
-
|
|
18
15
|
return resolved;
|
|
19
16
|
}
|
|
20
|
-
|
|
21
17
|
/**
|
|
22
18
|
* Resolves the active framework directory.
|
|
23
19
|
* Priority: ATABEY_TEST_DIR (env) -> package.json `atabey.frameworkDir` -> `.atabey` -> other adapter dirs -> global HOME.
|
|
24
20
|
*/
|
|
25
|
-
export function resolveFrameworkDir(projectRoot
|
|
21
|
+
export function resolveFrameworkDir(projectRoot) {
|
|
26
22
|
// For test environments, use the explicitly set test directory.
|
|
27
23
|
const testDir = process.env[MCP.TEST_DIR_ENV];
|
|
28
|
-
if (testDir)
|
|
29
|
-
|
|
24
|
+
if (testDir)
|
|
25
|
+
return testDir;
|
|
30
26
|
// 1. Authoritative source: read from package.json if present
|
|
31
27
|
try {
|
|
32
28
|
const pkgPath = path.join(projectRoot, "package.json");
|
|
33
29
|
if (fs.existsSync(pkgPath)) {
|
|
34
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"))
|
|
35
|
-
const atabeyConfig = pkg["atabey"]
|
|
30
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
31
|
+
const atabeyConfig = pkg["atabey"];
|
|
36
32
|
if (atabeyConfig && typeof atabeyConfig["frameworkDir"] === "string") {
|
|
37
33
|
// Ensure the path is relative if it's within the project, otherwise use as-is.
|
|
38
34
|
const resolvedDir = path.resolve(projectRoot, atabeyConfig["frameworkDir"]);
|
|
@@ -42,24 +38,22 @@ export function resolveFrameworkDir(projectRoot: string): string {
|
|
|
42
38
|
return atabeyConfig["frameworkDir"];
|
|
43
39
|
}
|
|
44
40
|
}
|
|
45
|
-
}
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
46
43
|
// ignore — fall through to filesystem scan
|
|
47
44
|
}
|
|
48
|
-
|
|
49
45
|
// 2. Filesystem scan in projectRoot for common framework directories
|
|
50
46
|
const localCandidates = [
|
|
51
47
|
FRAMEWORK.CORE_DIR, // .atabey
|
|
52
|
-
UNIFIED_HUB_DIR,
|
|
48
|
+
UNIFIED_HUB_DIR, // .agents
|
|
53
49
|
// Add other adapter specific directories if needed, or remove if unified is strictly enforced
|
|
54
50
|
];
|
|
55
|
-
|
|
56
51
|
for (const candidate of localCandidates) {
|
|
57
52
|
const candidatePath = path.join(projectRoot, candidate);
|
|
58
53
|
if (fs.existsSync(candidatePath)) {
|
|
59
54
|
return candidate;
|
|
60
55
|
}
|
|
61
56
|
}
|
|
62
|
-
|
|
63
57
|
// 3. Fallback to global home directory.
|
|
64
58
|
const homeDir = os.homedir();
|
|
65
59
|
return path.join(homeDir, FRAMEWORK.CORE_DIR);
|
|
@@ -4,8 +4,9 @@ import path from "path";
|
|
|
4
4
|
import { fileURLToPath } from "url";
|
|
5
5
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
6
6
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
7
|
-
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
7
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
8
8
|
import { TOOLS, toolHandlers } from "./tools/index.js";
|
|
9
|
+
import { RESOURCES, handleReadResource } from "./resources/index.js";
|
|
9
10
|
// ─── Server Setup ─────────────────────────────────────────────────
|
|
10
11
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
11
12
|
// Robustly find package.json by walking up from __dirname
|
|
@@ -28,6 +29,7 @@ const server = new Server({
|
|
|
28
29
|
}, {
|
|
29
30
|
capabilities: {
|
|
30
31
|
tools: {},
|
|
32
|
+
resources: {},
|
|
31
33
|
},
|
|
32
34
|
});
|
|
33
35
|
// Basic Schema Validator for Required Fields
|
|
@@ -51,6 +53,28 @@ server.setRequestHandler(ListToolsRequestSchema, async (request) => {
|
|
|
51
53
|
}
|
|
52
54
|
return { tools: TOOLS };
|
|
53
55
|
});
|
|
56
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
57
|
+
return { resources: RESOURCES };
|
|
58
|
+
});
|
|
59
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
60
|
+
const uri = request.params.uri;
|
|
61
|
+
try {
|
|
62
|
+
const content = await handleReadResource(uri);
|
|
63
|
+
return {
|
|
64
|
+
contents: [
|
|
65
|
+
{
|
|
66
|
+
uri,
|
|
67
|
+
mimeType: "text/markdown",
|
|
68
|
+
text: content,
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
75
|
+
throw new Error(`Failed to read resource: ${message}`, { cause: error });
|
|
76
|
+
}
|
|
77
|
+
});
|
|
54
78
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
55
79
|
const req = request;
|
|
56
80
|
const { name, arguments: args } = req.params;
|
|
@@ -65,15 +89,15 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
65
89
|
if (!handler) {
|
|
66
90
|
return {
|
|
67
91
|
isError: true,
|
|
68
|
-
content: [{ type: "text", text:
|
|
92
|
+
content: [{ type: "text", text: `[ERROR] Unknown tool: ${name}` }],
|
|
69
93
|
};
|
|
70
94
|
}
|
|
71
|
-
//
|
|
95
|
+
// [SECURITY] Runtime Validation
|
|
72
96
|
const validationError = validateArgs(name, args || {});
|
|
73
97
|
if (validationError) {
|
|
74
98
|
return {
|
|
75
99
|
isError: true,
|
|
76
|
-
content: [{ type: "text", text:
|
|
100
|
+
content: [{ type: "text", text: `[ERROR] Validation Error: ${validationError}` }],
|
|
77
101
|
};
|
|
78
102
|
}
|
|
79
103
|
return await handler(projectRoot, args || {});
|
|
@@ -82,7 +106,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
82
106
|
const message = error instanceof Error ? error.message : "Unknown error occurred";
|
|
83
107
|
return {
|
|
84
108
|
isError: true,
|
|
85
|
-
content: [{ type: "text", text:
|
|
109
|
+
content: [{ type: "text", text: `[ERROR] Execution failed: ${message}` }],
|
|
86
110
|
};
|
|
87
111
|
}
|
|
88
112
|
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Storage } from "../../../src/shared/storage.js";
|
|
2
|
+
/**
|
|
3
|
+
* [DATA] MCP Resource Definitions
|
|
4
|
+
*/
|
|
5
|
+
export const RESOURCES = [
|
|
6
|
+
{
|
|
7
|
+
uri: "atabey://army/status",
|
|
8
|
+
name: "Agent Army Status",
|
|
9
|
+
description: "Real-time state and active tasks of all specialized agents.",
|
|
10
|
+
mimeType: "text/markdown"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
uri: "atabey://plan/active",
|
|
14
|
+
name: "Active Execution Plan",
|
|
15
|
+
description: "The current DAG of tasks and their completion status.",
|
|
16
|
+
mimeType: "text/markdown"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
uri: "atabey://memory/project",
|
|
20
|
+
name: "Project Memory",
|
|
21
|
+
description: "The central source of truth for project context (PROJECT_MEMORY.md).",
|
|
22
|
+
mimeType: "text/markdown"
|
|
23
|
+
}
|
|
24
|
+
];
|
|
25
|
+
export async function handleReadResource(uri) {
|
|
26
|
+
if (uri === "atabey://army/status") {
|
|
27
|
+
const agents = Storage.getAllAgents();
|
|
28
|
+
let md = "# [AI] Agent Army Status\n\n| Agent | State | Active Task | Last Updated |\n| :--- | :--- | :--- | :--- |\n";
|
|
29
|
+
agents.forEach((a) => {
|
|
30
|
+
md += `| @${a.name} | ${a.state} | ${a.task} | ${a.last_updated} |\n`;
|
|
31
|
+
});
|
|
32
|
+
return md;
|
|
33
|
+
}
|
|
34
|
+
if (uri === "atabey://plan/active") {
|
|
35
|
+
const tasks = Storage.getTasks();
|
|
36
|
+
let md = "# 📋 Active Execution Plan\n\n| ID | Task | Agent | Status | Dependencies |\n| :--- | :--- | :--- | :--- | :--- |\n";
|
|
37
|
+
tasks.forEach((t) => {
|
|
38
|
+
const deps = t.dependencies.join(", ") || "-";
|
|
39
|
+
md += `| ${t.id} | ${t.description} | ${t.agent} | ${t.status} | ${deps} |\n`;
|
|
40
|
+
});
|
|
41
|
+
return md;
|
|
42
|
+
}
|
|
43
|
+
if (uri === "atabey://memory/project") {
|
|
44
|
+
const fs = await import("fs");
|
|
45
|
+
const path = await import("path");
|
|
46
|
+
const { getFrameworkDir } = await import("../../../src/cli/utils/memory.js");
|
|
47
|
+
const projectRoot = process.env.ATABEY_PROJECT_ROOT || process.cwd();
|
|
48
|
+
const fwDir = getFrameworkDir();
|
|
49
|
+
const p = path.isAbsolute(fwDir)
|
|
50
|
+
? path.join(fwDir, "memory", "PROJECT_MEMORY.md")
|
|
51
|
+
: path.join(projectRoot, fwDir, "memory", "PROJECT_MEMORY.md");
|
|
52
|
+
if (fs.existsSync(p)) {
|
|
53
|
+
return fs.readFileSync(p, "utf8");
|
|
54
|
+
}
|
|
55
|
+
return "Project memory not found. Run 'atabey init' first.";
|
|
56
|
+
}
|
|
57
|
+
throw new Error(`Unknown resource URI: ${uri}`);
|
|
58
|
+
}
|