atabey 0.0.22 → 0.0.25
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 +6 -1
- package/README.md +3 -3
- package/dist/atabey/src/cli/commands/dashboard.js +20 -19
- package/dist/atabey/src/cli/commands/dashboard.js.map +1 -1
- package/dist/atabey/src/cli/commands/index-codebase.js +1 -1
- package/dist/atabey/src/cli/commands/index-codebase.js.map +1 -1
- package/dist/atabey/src/cli/commands/init/scaffold-core.js +10 -1
- package/dist/atabey/src/cli/commands/init/scaffold-core.js.map +1 -1
- package/dist/atabey/src/cli/commands/init/scaffold-docs.js +2 -2
- package/dist/atabey/src/cli/commands/init/scaffold-docs.js.map +1 -1
- package/dist/atabey/src/cli/commands/init/scaffold-standards.js +1 -1
- package/dist/atabey/src/cli/commands/init.js +12 -18
- package/dist/atabey/src/cli/commands/init.js.map +1 -1
- package/dist/atabey/src/cli/commands/mcp.js +1 -1
- package/dist/atabey/src/cli/commands/mcp.js.map +1 -1
- package/dist/atabey/src/cli/commands/orchestrate.d.ts +8 -8
- package/dist/atabey/src/cli/index.js +50 -3
- package/dist/atabey/src/cli/index.js.map +1 -1
- package/dist/atabey/src/cli/utils/config-schema.d.ts +19 -19
- package/dist/atabey/src/cli/utils/i18n.d.ts +9 -4
- package/dist/atabey/src/cli/utils/i18n.js +26 -31
- package/dist/atabey/src/cli/utils/i18n.js.map +1 -1
- package/dist/atabey/src/cli/utils/pkg.js +3 -2
- package/dist/atabey/src/cli/utils/pkg.js.map +1 -1
- package/dist/atabey/src/cli/utils/schemas.d.ts +6 -6
- package/dist/atabey/src/cli/utils/validate-registry.js +5 -4
- package/dist/atabey/src/cli/utils/validate-registry.js.map +1 -1
- package/dist/atabey/src/contracts/tasks.d.ts +4 -4
- package/dist/atabey/src/modules/agents/registry/manager.js +1 -1
- package/dist/atabey/src/modules/agents/registry/security.js +1 -1
- package/dist/atabey/src/modules/agents/registry/security.js.map +1 -1
- package/dist/atabey/src/modules/contracts/api.d.ts +6 -6
- package/dist/atabey/src/modules/engines/agent-executor.js +82 -47
- package/dist/atabey/src/modules/engines/agent-executor.js.map +1 -1
- package/dist/atabey/src/modules/engines/agent-loop.d.ts +5 -2
- package/dist/atabey/src/modules/engines/agent-loop.js +39 -13
- package/dist/atabey/src/modules/engines/agent-loop.js.map +1 -1
- package/dist/atabey/src/modules/engines/file-lock.d.ts +18 -8
- package/dist/atabey/src/modules/engines/file-lock.js +95 -101
- package/dist/atabey/src/modules/engines/file-lock.js.map +1 -1
- package/dist/atabey/src/modules/engines/policy-engine.js +5 -3
- package/dist/atabey/src/modules/engines/policy-engine.js.map +1 -1
- package/dist/atabey/src/modules/engines/routing-engine.d.ts +3 -0
- package/dist/atabey/src/modules/engines/routing-engine.js +14 -4
- package/dist/atabey/src/modules/engines/routing-engine.js.map +1 -1
- package/dist/atabey/src/modules/engines/sandbox.d.ts +31 -0
- package/dist/atabey/src/modules/engines/sandbox.js +57 -0
- package/dist/atabey/src/modules/engines/sandbox.js.map +1 -0
- package/dist/atabey/src/modules/engines/worker-pool.d.ts +8 -0
- package/dist/atabey/src/modules/engines/worker-pool.js +9 -0
- package/dist/atabey/src/modules/engines/worker-pool.js.map +1 -0
- package/dist/atabey/src/modules/engines/worker-script.d.ts +8 -0
- package/dist/atabey/src/modules/engines/worker-script.js +99 -0
- package/dist/atabey/src/modules/engines/worker-script.js.map +1 -0
- package/dist/atabey/src/modules/memory/core.js +1 -1
- package/dist/atabey/src/modules/memory/core.js.map +1 -1
- package/dist/atabey/src/shared/file-lock.d.ts +1 -0
- package/dist/atabey/src/shared/file-lock.js +2 -0
- package/dist/atabey/src/shared/file-lock.js.map +1 -0
- package/dist/atabey/src/shared/job-queue.d.ts +1 -0
- package/dist/atabey/src/shared/job-queue.js +2 -0
- package/dist/atabey/src/shared/job-queue.js.map +1 -0
- package/dist/atabey/src/shared/resilience.d.ts +1 -0
- package/dist/atabey/src/shared/resilience.js +2 -0
- package/dist/atabey/src/shared/resilience.js.map +1 -0
- package/dist/atabey/src/shared/sandbox-runtime.d.ts +1 -0
- package/dist/atabey/src/shared/sandbox-runtime.js +2 -0
- package/dist/atabey/src/shared/sandbox-runtime.js.map +1 -0
- package/dist/atabey/src/shared/sandbox.d.ts +1 -0
- package/dist/atabey/src/shared/sandbox.js +2 -0
- package/dist/atabey/src/shared/sandbox.js.map +1 -0
- package/dist/atabey/src/shared/storage.d.ts +8 -0
- package/dist/atabey/src/shared/storage.js +51 -40
- package/dist/atabey/src/shared/storage.js.map +1 -1
- package/dist/atabey/src/shared/worker-pool.d.ts +1 -0
- package/dist/atabey/src/shared/worker-pool.js +2 -0
- package/dist/atabey/src/shared/worker-pool.js.map +1 -0
- package/dist/atabey-mcp/src/mcp/utils/auto-rollback.js +114 -5
- package/dist/atabey-mcp/src/mcp/utils/auto-rollback.js.map +1 -1
- package/dist/atabey-mcp/src/mcp/utils/loop-detector.d.ts +1 -0
- package/dist/atabey-mcp/src/mcp/utils/loop-detector.js +57 -6
- package/dist/atabey-mcp/src/mcp/utils/loop-detector.js.map +1 -1
- package/dist/atabey-mcp/src/shared/storage.d.ts +9 -0
- package/dist/atabey-mcp/src/shared/storage.js +51 -0
- package/dist/atabey-mcp/src/shared/storage.js.map +1 -1
- package/dist/shared/src/audit-chain.d.ts +51 -0
- package/dist/shared/src/audit-chain.js +85 -0
- package/dist/shared/src/audit-chain.js.map +1 -0
- package/dist/shared/src/audit.d.ts +8 -0
- package/dist/shared/src/audit.js +82 -18
- package/dist/shared/src/audit.js.map +1 -1
- package/dist/shared/src/file-lock.d.ts +85 -0
- package/dist/shared/src/file-lock.js +246 -0
- package/dist/shared/src/file-lock.js.map +1 -0
- package/dist/shared/src/index.d.ts +9 -0
- package/dist/shared/src/index.js +9 -0
- package/dist/shared/src/index.js.map +1 -1
- package/dist/shared/src/job-queue.d.ts +53 -0
- package/dist/shared/src/job-queue.js +127 -0
- package/dist/shared/src/job-queue.js.map +1 -0
- package/dist/shared/src/policy-gate.d.ts +42 -0
- package/dist/shared/src/policy-gate.js +148 -0
- package/dist/shared/src/policy-gate.js.map +1 -0
- package/dist/shared/src/resilience.d.ts +84 -0
- package/dist/shared/src/resilience.js +217 -0
- package/dist/shared/src/resilience.js.map +1 -0
- package/dist/shared/src/sandbox-fs.d.ts +28 -0
- package/dist/shared/src/sandbox-fs.js +148 -0
- package/dist/shared/src/sandbox-fs.js.map +1 -0
- package/dist/shared/src/sandbox-runtime.d.ts +85 -0
- package/dist/shared/src/sandbox-runtime.js +250 -0
- package/dist/shared/src/sandbox-runtime.js.map +1 -0
- package/dist/shared/src/sandbox.d.ts +54 -0
- package/dist/shared/src/sandbox.js +179 -0
- package/dist/shared/src/sandbox.js.map +1 -0
- package/dist/shared/src/worker-pool.d.ts +52 -0
- package/dist/shared/src/worker-pool.js +210 -0
- package/dist/shared/src/worker-pool.js.map +1 -0
- package/dist/shared/src/worker-thread.d.ts +21 -0
- package/dist/shared/src/worker-thread.js +67 -0
- package/dist/shared/src/worker-thread.js.map +1 -0
- package/dist/src/cli/commands/approve.d.ts +1 -0
- package/dist/src/cli/commands/approve.js +64 -0
- package/dist/src/cli/commands/approve.js.map +1 -0
- package/dist/src/cli/commands/check.d.ts +1 -0
- package/dist/src/cli/commands/check.js +339 -0
- package/dist/src/cli/commands/check.js.map +1 -0
- package/dist/src/cli/commands/compliance.d.ts +5 -0
- package/dist/src/cli/commands/compliance.js +43 -0
- package/dist/src/cli/commands/compliance.js.map +1 -0
- package/dist/src/cli/commands/contract.d.ts +10 -0
- package/dist/src/cli/commands/contract.js +52 -0
- package/dist/src/cli/commands/contract.js.map +1 -0
- 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 +5 -0
- package/dist/src/cli/commands/dashboard.js +753 -0
- package/dist/src/cli/commands/dashboard.js.map +1 -0
- package/dist/src/cli/commands/explorer.d.ts +2 -0
- package/dist/src/cli/commands/explorer.js +44 -0
- package/dist/src/cli/commands/explorer.js.map +1 -0
- package/dist/src/cli/commands/git.d.ts +2 -0
- package/dist/src/cli/commands/git.js +40 -0
- package/dist/src/cli/commands/git.js.map +1 -0
- package/dist/src/cli/commands/index-codebase.d.ts +4 -0
- package/dist/src/cli/commands/index-codebase.js +63 -0
- package/dist/src/cli/commands/index-codebase.js.map +1 -0
- 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 +13 -0
- package/dist/src/cli/commands/init/scaffold-core.js +188 -0
- package/dist/src/cli/commands/init/scaffold-core.js.map +1 -0
- package/dist/src/cli/commands/init/scaffold-docs.d.ts +4 -0
- package/dist/src/cli/commands/init/scaffold-docs.js +36 -0
- package/dist/src/cli/commands/init/scaffold-docs.js.map +1 -0
- package/dist/src/cli/commands/init/scaffold-ops.d.ts +1 -0
- package/dist/src/cli/commands/init/scaffold-ops.js +81 -0
- package/dist/src/cli/commands/init/scaffold-ops.js.map +1 -0
- package/dist/src/cli/commands/init/scaffold-standards.d.ts +2 -0
- package/dist/src/cli/commands/init/scaffold-standards.js +84 -0
- package/dist/src/cli/commands/init/scaffold-standards.js.map +1 -0
- package/dist/src/cli/commands/init.d.ts +11 -0
- package/dist/src/cli/commands/init.js +371 -0
- package/dist/src/cli/commands/init.js.map +1 -0
- package/dist/src/cli/commands/knowledge.d.ts +2 -0
- package/dist/src/cli/commands/knowledge.js +16 -0
- package/dist/src/cli/commands/knowledge.js.map +1 -0
- package/dist/src/cli/commands/lint.d.ts +4 -0
- package/dist/src/cli/commands/lint.js +24 -0
- package/dist/src/cli/commands/lint.js.map +1 -0
- package/dist/src/cli/commands/log.d.ts +10 -0
- package/dist/src/cli/commands/log.js +14 -0
- package/dist/src/cli/commands/log.js.map +1 -0
- package/dist/src/cli/commands/mcp.d.ts +11 -0
- package/dist/src/cli/commands/mcp.js +128 -0
- package/dist/src/cli/commands/mcp.js.map +1 -0
- package/dist/src/cli/commands/memory.d.ts +1 -0
- package/dist/src/cli/commands/memory.js +5 -0
- package/dist/src/cli/commands/memory.js.map +1 -0
- package/dist/src/cli/commands/orchestrate.d.ts +62 -0
- package/dist/src/cli/commands/orchestrate.js +263 -0
- package/dist/src/cli/commands/orchestrate.js.map +1 -0
- package/dist/src/cli/commands/plan.d.ts +11 -0
- package/dist/src/cli/commands/plan.js +120 -0
- package/dist/src/cli/commands/plan.js.map +1 -0
- package/dist/src/cli/commands/quickstart.d.ts +9 -0
- package/dist/src/cli/commands/quickstart.js +60 -0
- package/dist/src/cli/commands/quickstart.js.map +1 -0
- package/dist/src/cli/commands/script.d.ts +1 -0
- package/dist/src/cli/commands/script.js +28 -0
- package/dist/src/cli/commands/script.js.map +1 -0
- package/dist/src/cli/commands/security.d.ts +1 -0
- package/dist/src/cli/commands/security.js +34 -0
- package/dist/src/cli/commands/security.js.map +1 -0
- package/dist/src/cli/commands/status.d.ts +4 -0
- package/dist/src/cli/commands/status.js +122 -0
- package/dist/src/cli/commands/status.js.map +1 -0
- package/dist/src/cli/commands/trace.d.ts +10 -0
- package/dist/src/cli/commands/trace.js +108 -0
- package/dist/src/cli/commands/trace.js.map +1 -0
- package/dist/src/cli/index.d.ts +2 -0
- package/dist/src/cli/index.js +289 -0
- package/dist/src/cli/index.js.map +1 -0
- package/dist/src/cli/platforms/core.d.ts +16 -0
- package/dist/src/cli/platforms/core.js +77 -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.d.ts +1 -0
- package/dist/src/cli/shims.js +67 -0
- package/dist/src/cli/shims.js.map +1 -0
- package/dist/src/cli/utils/claude.d.ts +8 -0
- package/dist/src/cli/utils/claude.js +58 -0
- package/dist/src/cli/utils/claude.js.map +1 -0
- package/dist/src/cli/utils/compliance.d.ts +42 -0
- package/dist/src/cli/utils/compliance.js +150 -0
- package/dist/src/cli/utils/compliance.js.map +1 -0
- package/dist/src/cli/utils/config-schema.d.ts +256 -0
- package/dist/src/cli/utils/config-schema.js +67 -0
- package/dist/src/cli/utils/config-schema.js.map +1 -0
- package/dist/src/cli/utils/fs.d.ts +10 -0
- package/dist/src/cli/utils/fs.js +139 -0
- package/dist/src/cli/utils/fs.js.map +1 -0
- package/dist/src/cli/utils/i18n.d.ts +21 -0
- package/dist/src/cli/utils/i18n.js +36 -0
- package/dist/src/cli/utils/i18n.js.map +1 -0
- package/dist/src/cli/utils/memory.d.ts +45 -0
- package/dist/src/cli/utils/memory.js +339 -0
- package/dist/src/cli/utils/memory.js.map +1 -0
- package/dist/src/cli/utils/pkg.d.ts +42 -0
- package/dist/src/cli/utils/pkg.js +281 -0
- package/dist/src/cli/utils/pkg.js.map +1 -0
- package/dist/src/cli/utils/quality.d.ts +25 -0
- package/dist/src/cli/utils/quality.js +61 -0
- package/dist/src/cli/utils/quality.js.map +1 -0
- package/dist/src/cli/utils/schemas.d.ts +49 -0
- package/dist/src/cli/utils/schemas.js +20 -0
- package/dist/src/cli/utils/schemas.js.map +1 -0
- package/dist/src/cli/utils/string.d.ts +7 -0
- package/dist/src/cli/utils/string.js +50 -0
- package/dist/src/cli/utils/string.js.map +1 -0
- package/dist/src/cli/utils/time.d.ts +2 -0
- package/dist/src/cli/utils/time.js +28 -0
- package/dist/src/cli/utils/time.js.map +1 -0
- package/dist/src/cli/utils/ui.d.ts +53 -0
- package/dist/src/cli/utils/ui.js +101 -0
- package/dist/src/cli/utils/ui.js.map +1 -0
- package/dist/src/cli/utils/validate-registry.d.ts +4 -0
- package/dist/src/cli/utils/validate-registry.js +130 -0
- package/dist/src/cli/utils/validate-registry.js.map +1 -0
- package/dist/src/contracts/index.d.ts +1 -0
- package/dist/src/contracts/index.js +2 -0
- package/dist/src/contracts/index.js.map +1 -0
- package/dist/src/contracts/tasks.d.ts +44 -0
- package/dist/src/contracts/tasks.js +21 -0
- package/dist/src/contracts/tasks.js.map +1 -0
- package/dist/src/modules/agents/definitions.d.ts +26 -0
- package/dist/src/modules/agents/definitions.js +559 -0
- package/dist/src/modules/agents/definitions.js.map +1 -0
- package/dist/src/modules/agents/registry/analyst.d.ts +2 -0
- package/dist/src/modules/agents/registry/analyst.js +40 -0
- package/dist/src/modules/agents/registry/analyst.js.map +1 -0
- package/dist/src/modules/agents/registry/architect.d.ts +2 -0
- package/dist/src/modules/agents/registry/architect.js +43 -0
- package/dist/src/modules/agents/registry/architect.js.map +1 -0
- package/dist/src/modules/agents/registry/backend.d.ts +2 -0
- package/dist/src/modules/agents/registry/backend.js +51 -0
- package/dist/src/modules/agents/registry/backend.js.map +1 -0
- package/dist/src/modules/agents/registry/database.d.ts +2 -0
- package/dist/src/modules/agents/registry/database.js +46 -0
- package/dist/src/modules/agents/registry/database.js.map +1 -0
- package/dist/src/modules/agents/registry/devops.d.ts +2 -0
- package/dist/src/modules/agents/registry/devops.js +46 -0
- package/dist/src/modules/agents/registry/devops.js.map +1 -0
- package/dist/src/modules/agents/registry/explorer.d.ts +2 -0
- package/dist/src/modules/agents/registry/explorer.js +38 -0
- package/dist/src/modules/agents/registry/explorer.js.map +1 -0
- package/dist/src/modules/agents/registry/frontend.d.ts +2 -0
- package/dist/src/modules/agents/registry/frontend.js +53 -0
- package/dist/src/modules/agents/registry/frontend.js.map +1 -0
- package/dist/src/modules/agents/registry/git.d.ts +2 -0
- package/dist/src/modules/agents/registry/git.js +37 -0
- package/dist/src/modules/agents/registry/git.js.map +1 -0
- package/dist/src/modules/agents/registry/manager.d.ts +2 -0
- package/dist/src/modules/agents/registry/manager.js +65 -0
- package/dist/src/modules/agents/registry/manager.js.map +1 -0
- package/dist/src/modules/agents/registry/mobile.d.ts +2 -0
- package/dist/src/modules/agents/registry/mobile.js +42 -0
- package/dist/src/modules/agents/registry/mobile.js.map +1 -0
- package/dist/src/modules/agents/registry/native.d.ts +2 -0
- package/dist/src/modules/agents/registry/native.js +42 -0
- package/dist/src/modules/agents/registry/native.js.map +1 -0
- package/dist/src/modules/agents/registry/quality.d.ts +2 -0
- package/dist/src/modules/agents/registry/quality.js +44 -0
- package/dist/src/modules/agents/registry/quality.js.map +1 -0
- package/dist/src/modules/agents/registry/security.d.ts +2 -0
- package/dist/src/modules/agents/registry/security.js +43 -0
- package/dist/src/modules/agents/registry/security.js.map +1 -0
- package/dist/src/modules/agents/types.d.ts +33 -0
- package/dist/src/modules/agents/types.js +2 -0
- package/dist/src/modules/agents/types.js.map +1 -0
- 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 +46 -0
- package/dist/src/modules/engines/agent-executor.js +241 -0
- package/dist/src/modules/engines/agent-executor.js.map +1 -0
- package/dist/src/modules/engines/agent-loop.d.ts +34 -0
- package/dist/src/modules/engines/agent-loop.js +102 -0
- package/dist/src/modules/engines/agent-loop.js.map +1 -0
- package/dist/src/modules/engines/contract-engine.d.ts +46 -0
- package/dist/src/modules/engines/contract-engine.js +116 -0
- package/dist/src/modules/engines/contract-engine.js.map +1 -0
- package/dist/src/modules/engines/crud-governance.d.ts +66 -0
- package/dist/src/modules/engines/crud-governance.js +219 -0
- package/dist/src/modules/engines/crud-governance.js.map +1 -0
- package/dist/src/modules/engines/discovery-engine.d.ts +42 -0
- package/dist/src/modules/engines/discovery-engine.js +161 -0
- package/dist/src/modules/engines/discovery-engine.js.map +1 -0
- package/dist/src/modules/engines/evaluation-engine.d.ts +18 -0
- package/dist/src/modules/engines/evaluation-engine.js +171 -0
- package/dist/src/modules/engines/evaluation-engine.js.map +1 -0
- package/dist/src/modules/engines/file-lock.d.ts +41 -0
- package/dist/src/modules/engines/file-lock.js +168 -0
- package/dist/src/modules/engines/file-lock.js.map +1 -0
- package/dist/src/modules/engines/health-engine.d.ts +22 -0
- package/dist/src/modules/engines/health-engine.js +127 -0
- package/dist/src/modules/engines/health-engine.js.map +1 -0
- package/dist/src/modules/engines/phase-engine.d.ts +82 -0
- package/dist/src/modules/engines/phase-engine.js +211 -0
- package/dist/src/modules/engines/phase-engine.js.map +1 -0
- package/dist/src/modules/engines/planning-engine.d.ts +25 -0
- package/dist/src/modules/engines/planning-engine.js +80 -0
- package/dist/src/modules/engines/planning-engine.js.map +1 -0
- package/dist/src/modules/engines/policy-engine.d.ts +63 -0
- package/dist/src/modules/engines/policy-engine.js +186 -0
- package/dist/src/modules/engines/policy-engine.js.map +1 -0
- package/dist/src/modules/engines/quality-gate.d.ts +31 -0
- package/dist/src/modules/engines/quality-gate.js +95 -0
- package/dist/src/modules/engines/quality-gate.js.map +1 -0
- package/dist/src/modules/engines/risk-engine.d.ts +34 -0
- package/dist/src/modules/engines/risk-engine.js +201 -0
- package/dist/src/modules/engines/risk-engine.js.map +1 -0
- package/dist/src/modules/engines/routing-engine.d.ts +96 -0
- package/dist/src/modules/engines/routing-engine.js +505 -0
- package/dist/src/modules/engines/routing-engine.js.map +1 -0
- package/dist/src/modules/engines/session-engine.d.ts +68 -0
- package/dist/src/modules/engines/session-engine.js +141 -0
- package/dist/src/modules/engines/session-engine.js.map +1 -0
- package/dist/src/modules/engines/types.d.ts +51 -0
- package/dist/src/modules/engines/types.js +2 -0
- package/dist/src/modules/engines/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/llm-provider.d.ts +87 -0
- package/dist/src/modules/providers/llm-provider.js +242 -0
- package/dist/src/modules/providers/llm-provider.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 +104 -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 +70 -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/modules/skills/definitions.d.ts +48 -0
- package/dist/src/modules/skills/definitions.js +71 -0
- package/dist/src/modules/skills/definitions.js.map +1 -0
- package/dist/src/shared/audit.d.ts +1 -0
- package/dist/src/shared/audit.js +2 -0
- package/dist/src/shared/audit.js.map +1 -0
- package/dist/src/shared/constants.d.ts +1 -0
- package/dist/src/shared/constants.js +2 -0
- package/dist/src/shared/constants.js.map +1 -0
- package/dist/src/shared/errors.d.ts +1 -0
- package/dist/src/shared/errors.js +2 -0
- package/dist/src/shared/errors.js.map +1 -0
- package/dist/src/shared/fs.d.ts +1 -0
- package/dist/src/shared/fs.js +2 -0
- package/dist/src/shared/fs.js.map +1 -0
- package/dist/src/shared/lock.d.ts +1 -0
- package/dist/src/shared/lock.js +2 -0
- package/dist/src/shared/lock.js.map +1 -0
- package/dist/src/shared/logger.d.ts +1 -0
- package/dist/src/shared/logger.js +2 -0
- package/dist/src/shared/logger.js.map +1 -0
- package/dist/src/shared/pii.d.ts +1 -0
- package/dist/src/shared/pii.js +2 -0
- package/dist/src/shared/pii.js.map +1 -0
- package/dist/src/shared/retention.d.ts +1 -0
- package/dist/src/shared/retention.js +2 -0
- package/dist/src/shared/retention.js.map +1 -0
- package/dist/src/shared/storage.d.ts +141 -0
- package/dist/src/shared/storage.js +332 -0
- package/dist/src/shared/storage.js.map +1 -0
- package/dist/src/shared/string.d.ts +1 -0
- package/dist/src/shared/string.js +2 -0
- package/dist/src/shared/string.js.map +1 -0
- package/dist/src/shared/types.d.ts +1 -0
- package/dist/src/shared/types.js +2 -0
- package/dist/src/shared/types.js.map +1 -0
- package/package.json +3 -5
- package/templates/full/ATABEY_FULL.md +5 -3
- package/templates/prompts/new-feature-recipe.md +1 -1
- package/templates/standards/architecture-standards.md +1 -1
- package/templates/standards/governance-standards.md +3 -3
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PolicyGate — single decision point for mutating / sensitive operations.
|
|
3
|
+
*
|
|
4
|
+
* Phase 0 foundation for enterprise hard-gate security.
|
|
5
|
+
* Every MCP mutating tool should call evaluateToolCall() before side effects.
|
|
6
|
+
*
|
|
7
|
+
* Decision is pure (no I/O) except optional hooks; MCP layer may enrich with
|
|
8
|
+
* project-specific RBAC before/after this gate.
|
|
9
|
+
*/
|
|
10
|
+
/** Tools that mutate disk, process state, or external systems. */
|
|
11
|
+
export const MUTATING_TOOLS = new Set([
|
|
12
|
+
"write_file",
|
|
13
|
+
"replace_text",
|
|
14
|
+
"patch_file",
|
|
15
|
+
"batch_surgical_edit",
|
|
16
|
+
"run_shell_command",
|
|
17
|
+
"compress_files",
|
|
18
|
+
"decompress_files",
|
|
19
|
+
"delete_knowledge",
|
|
20
|
+
"update_project_memory",
|
|
21
|
+
"store_knowledge",
|
|
22
|
+
"update_contract_hash",
|
|
23
|
+
]);
|
|
24
|
+
/** Path-like arg keys commonly used by tools. */
|
|
25
|
+
const PATH_KEYS = ["path", "file", "filePath", "target", "output", "source", "archive"];
|
|
26
|
+
/** Relative path segments that must never be written by agents by default. */
|
|
27
|
+
const PROTECTED_PATH_PATTERNS = [
|
|
28
|
+
/(^|\/)\.env(\.|$)/i,
|
|
29
|
+
/(^|\/)\.env\.[^/]+$/i,
|
|
30
|
+
/(^|\/)\.ssh(\/|$)/i,
|
|
31
|
+
/(^|\/)\.gnupg(\/|$)/i,
|
|
32
|
+
/(^|\/)id_rsa$/i,
|
|
33
|
+
/(^|\/)id_ed25519$/i,
|
|
34
|
+
/(^|\/)credentials\.json$/i,
|
|
35
|
+
/(^|\/)\.aws\/credentials$/i,
|
|
36
|
+
/(^|\/)\.npmrc$/i,
|
|
37
|
+
/(^|\/)\.netrc$/i,
|
|
38
|
+
];
|
|
39
|
+
function allow(code = "ALLOW", reason = "Allowed") {
|
|
40
|
+
return { effect: "allow", code, reason };
|
|
41
|
+
}
|
|
42
|
+
function deny(code, reason) {
|
|
43
|
+
return { effect: "deny", code, reason };
|
|
44
|
+
}
|
|
45
|
+
function collectPaths(args) {
|
|
46
|
+
const paths = [];
|
|
47
|
+
for (const key of PATH_KEYS) {
|
|
48
|
+
const v = args[key];
|
|
49
|
+
if (typeof v === "string" && v.trim())
|
|
50
|
+
paths.push(v.trim());
|
|
51
|
+
}
|
|
52
|
+
// batch_surgical_edit
|
|
53
|
+
if (Array.isArray(args.edits)) {
|
|
54
|
+
for (const edit of args.edits) {
|
|
55
|
+
if (edit && typeof edit === "object" && typeof edit.path === "string") {
|
|
56
|
+
paths.push(edit.path.trim());
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return paths;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Normalize agent id to @name form.
|
|
64
|
+
*/
|
|
65
|
+
export function normalizeAgentId(agent) {
|
|
66
|
+
const a = (agent || "mcp-client").trim();
|
|
67
|
+
if (!a)
|
|
68
|
+
return "@mcp-client";
|
|
69
|
+
return a.startsWith("@") ? a : `@${a}`;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Evaluate a tool call against baseline hard rules (path safety, recon, shell meta).
|
|
73
|
+
* Does NOT replace full RBAC matrix — call permissions layer separately or wrap here later.
|
|
74
|
+
*/
|
|
75
|
+
export function evaluateToolCall(input) {
|
|
76
|
+
const tool = input.tool;
|
|
77
|
+
const agent = normalizeAgentId(input.agent);
|
|
78
|
+
const tier = input.tier;
|
|
79
|
+
const args = input.args || {};
|
|
80
|
+
if (!tool) {
|
|
81
|
+
return deny("DENY_UNKNOWN_TOOL", "Missing tool name");
|
|
82
|
+
}
|
|
83
|
+
const isMutating = MUTATING_TOOLS.has(tool);
|
|
84
|
+
// Path safety for any tool that carries paths (read or write)
|
|
85
|
+
const paths = collectPaths(args);
|
|
86
|
+
for (const p of paths) {
|
|
87
|
+
if (!p) {
|
|
88
|
+
return deny("DENY_EMPTY_PATH", "Empty path argument is not allowed");
|
|
89
|
+
}
|
|
90
|
+
// Null bytes / obvious traversal
|
|
91
|
+
if (p.includes("\0")) {
|
|
92
|
+
return deny("DENY_PATH_TRAVERSAL", "Path contains illegal null byte");
|
|
93
|
+
}
|
|
94
|
+
// Windows + POSIX traversal
|
|
95
|
+
if (p.includes("..")) {
|
|
96
|
+
// Allow only if not used as parent segment — simple hard deny for Phase 0
|
|
97
|
+
const segments = p.replace(/\\/g, "/").split("/");
|
|
98
|
+
if (segments.some((s) => s === "..")) {
|
|
99
|
+
return deny("DENY_PATH_TRAVERSAL", `Path traversal denied for "${p}". Paths must stay inside the project root.`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Absolute paths that look like host escapes (MCP should still safePath; belt-and-suspenders)
|
|
103
|
+
if (p.startsWith("/") || /^[A-Za-z]:[\\/]/.test(p)) {
|
|
104
|
+
// Absolute can be OK if still under project after safePath — flag high-risk patterns only
|
|
105
|
+
if (p.startsWith("/etc") ||
|
|
106
|
+
p.startsWith("/usr") ||
|
|
107
|
+
p.startsWith("/bin") ||
|
|
108
|
+
p.startsWith("/sbin") ||
|
|
109
|
+
p.includes("/.ssh") ||
|
|
110
|
+
p.startsWith("/System")) {
|
|
111
|
+
return deny("DENY_ABSOLUTE_ESCAPE", `Absolute system path denied: "${p}"`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (isMutating) {
|
|
115
|
+
const normalized = p.replace(/\\/g, "/");
|
|
116
|
+
for (const re of PROTECTED_PATH_PATTERNS) {
|
|
117
|
+
if (re.test(normalized)) {
|
|
118
|
+
return deny("DENY_PROTECTED_PATH", `Write/mutate denied for protected path "${p}". Secrets and credential files are blocked by PolicyGate.`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Recon agents: no mutating tools (matrix may later grant exceptions — Phase 0 hard deny)
|
|
124
|
+
if (isMutating && tier === "recon") {
|
|
125
|
+
return deny("DENY_RECON_MUTATION", `Agent ${agent} (tier: recon) cannot invoke mutating tool "${tool}".`);
|
|
126
|
+
}
|
|
127
|
+
// Shell metacharacters (defense in depth; shell tool also checks)
|
|
128
|
+
if (tool === "run_shell_command") {
|
|
129
|
+
const command = String(args.command ?? "");
|
|
130
|
+
if (/[;&|><$`\n\r]/.test(command)) {
|
|
131
|
+
return deny("DENY_SHELL_METACHAR", "Shell metacharacters are forbidden to prevent command injection.");
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return allow();
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* True when decision is allow.
|
|
138
|
+
*/
|
|
139
|
+
export function isAllowed(decision) {
|
|
140
|
+
return decision.effect === "allow";
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Format decision for MCP error payloads.
|
|
144
|
+
*/
|
|
145
|
+
export function formatPolicyDenial(decision) {
|
|
146
|
+
return `[POLICY_GATE] ${decision.code}: ${decision.reason}`;
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=policy-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-gate.js","sourceRoot":"","sources":["../../../../shared/src/policy-gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Polly-style resilience primitives — no external deps.
|
|
3
|
+
*
|
|
4
|
+
* - withRetry: exponential backoff + jitter for transient failures
|
|
5
|
+
* - CircuitBreaker: closed → open → half-open state machine
|
|
6
|
+
* - withResilience: compose retry + circuit breaker
|
|
7
|
+
*
|
|
8
|
+
* Typical use: LLM provider rate limits, timeouts, 5xx, network blips.
|
|
9
|
+
*/
|
|
10
|
+
export type CircuitState = "closed" | "open" | "half-open";
|
|
11
|
+
export interface RetryOptions {
|
|
12
|
+
/** Max attempts including the first try. Default: 3 */
|
|
13
|
+
maxAttempts?: number;
|
|
14
|
+
/** Initial delay in ms. Default: 100 */
|
|
15
|
+
baseDelayMs?: number;
|
|
16
|
+
/** Cap on delay in ms. Default: 10_000 */
|
|
17
|
+
maxDelayMs?: number;
|
|
18
|
+
/** Exponential factor. Default: 2 */
|
|
19
|
+
factor?: number;
|
|
20
|
+
/** Add random jitter [0, delay). Default: true */
|
|
21
|
+
jitter?: boolean;
|
|
22
|
+
/** Return true to retry this error. Default: retry all */
|
|
23
|
+
retryIf?: (error: unknown, attempt: number) => boolean;
|
|
24
|
+
/** Optional hook before each sleep */
|
|
25
|
+
onRetry?: (error: unknown, attempt: number, delayMs: number) => void;
|
|
26
|
+
/** Optional abort signal */
|
|
27
|
+
signal?: AbortSignal;
|
|
28
|
+
}
|
|
29
|
+
export interface CircuitBreakerOptions {
|
|
30
|
+
/** Failures in closed state before opening. Default: 5 */
|
|
31
|
+
failureThreshold?: number;
|
|
32
|
+
/** Successes in half-open before closing. Default: 2 */
|
|
33
|
+
successThreshold?: number;
|
|
34
|
+
/** Time to wait in open before half-open probe. Default: 30_000 */
|
|
35
|
+
openMs?: number;
|
|
36
|
+
/** Optional name for error messages */
|
|
37
|
+
name?: string;
|
|
38
|
+
}
|
|
39
|
+
export declare class CircuitOpenError extends Error {
|
|
40
|
+
readonly circuit: string;
|
|
41
|
+
readonly retryAfterMs: number;
|
|
42
|
+
constructor(circuit: string, retryAfterMs: number);
|
|
43
|
+
}
|
|
44
|
+
export declare class CircuitBreaker {
|
|
45
|
+
private state;
|
|
46
|
+
private failures;
|
|
47
|
+
private successes;
|
|
48
|
+
private openedAt;
|
|
49
|
+
private readonly failureThreshold;
|
|
50
|
+
private readonly successThreshold;
|
|
51
|
+
private readonly openMs;
|
|
52
|
+
private readonly name;
|
|
53
|
+
constructor(options?: CircuitBreakerOptions);
|
|
54
|
+
getState(): CircuitState;
|
|
55
|
+
getStats(): {
|
|
56
|
+
state: CircuitState;
|
|
57
|
+
failures: number;
|
|
58
|
+
successes: number;
|
|
59
|
+
name: string;
|
|
60
|
+
};
|
|
61
|
+
/** Manual reset (e.g. after operator intervention). */
|
|
62
|
+
reset(): void;
|
|
63
|
+
exec<T>(fn: () => Promise<T>): Promise<T>;
|
|
64
|
+
private maybeTransitionToHalfOpen;
|
|
65
|
+
private onSuccess;
|
|
66
|
+
private onFailure;
|
|
67
|
+
private trip;
|
|
68
|
+
}
|
|
69
|
+
export declare function computeBackoffDelay(attempt: number, options?: Pick<RetryOptions, "baseDelayMs" | "maxDelayMs" | "factor" | "jitter">): number;
|
|
70
|
+
export declare function withRetry<T>(fn: (attempt: number) => Promise<T>, options?: RetryOptions): Promise<T>;
|
|
71
|
+
export interface ResilienceOptions {
|
|
72
|
+
retry?: RetryOptions;
|
|
73
|
+
circuitBreaker?: CircuitBreaker;
|
|
74
|
+
/** If true, CircuitOpenError is not retried (default true). */
|
|
75
|
+
skipRetryOnOpenCircuit?: boolean;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Execute `fn` through optional circuit breaker + retry with exponential backoff.
|
|
79
|
+
*/
|
|
80
|
+
export declare function withResilience<T>(fn: (attempt: number) => Promise<T>, options?: ResilienceOptions): Promise<T>;
|
|
81
|
+
/** Heuristic: retry rate limits, timeouts, and common transient network errors. */
|
|
82
|
+
export declare function isTransientError(error: unknown): boolean;
|
|
83
|
+
export declare function getCircuitBreaker(name: string, options?: CircuitBreakerOptions): CircuitBreaker;
|
|
84
|
+
export declare function resetAllCircuitBreakers(): void;
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Polly-style resilience primitives — no external deps.
|
|
3
|
+
*
|
|
4
|
+
* - withRetry: exponential backoff + jitter for transient failures
|
|
5
|
+
* - CircuitBreaker: closed → open → half-open state machine
|
|
6
|
+
* - withResilience: compose retry + circuit breaker
|
|
7
|
+
*
|
|
8
|
+
* Typical use: LLM provider rate limits, timeouts, 5xx, network blips.
|
|
9
|
+
*/
|
|
10
|
+
export class CircuitOpenError extends Error {
|
|
11
|
+
circuit;
|
|
12
|
+
retryAfterMs;
|
|
13
|
+
constructor(circuit, retryAfterMs) {
|
|
14
|
+
super(`[CircuitBreaker:${circuit}] Circuit is OPEN — rejecting call. Retry after ~${retryAfterMs}ms`);
|
|
15
|
+
this.name = "CircuitOpenError";
|
|
16
|
+
this.circuit = circuit;
|
|
17
|
+
this.retryAfterMs = retryAfterMs;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class CircuitBreaker {
|
|
21
|
+
state = "closed";
|
|
22
|
+
failures = 0;
|
|
23
|
+
successes = 0;
|
|
24
|
+
openedAt = 0;
|
|
25
|
+
failureThreshold;
|
|
26
|
+
successThreshold;
|
|
27
|
+
openMs;
|
|
28
|
+
name;
|
|
29
|
+
constructor(options = {}) {
|
|
30
|
+
this.failureThreshold = options.failureThreshold ?? 5;
|
|
31
|
+
this.successThreshold = options.successThreshold ?? 2;
|
|
32
|
+
this.openMs = options.openMs ?? 30_000;
|
|
33
|
+
this.name = options.name ?? "default";
|
|
34
|
+
}
|
|
35
|
+
getState() {
|
|
36
|
+
this.maybeTransitionToHalfOpen();
|
|
37
|
+
return this.state;
|
|
38
|
+
}
|
|
39
|
+
getStats() {
|
|
40
|
+
return {
|
|
41
|
+
state: this.getState(),
|
|
42
|
+
failures: this.failures,
|
|
43
|
+
successes: this.successes,
|
|
44
|
+
name: this.name,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/** Manual reset (e.g. after operator intervention). */
|
|
48
|
+
reset() {
|
|
49
|
+
this.state = "closed";
|
|
50
|
+
this.failures = 0;
|
|
51
|
+
this.successes = 0;
|
|
52
|
+
this.openedAt = 0;
|
|
53
|
+
}
|
|
54
|
+
async exec(fn) {
|
|
55
|
+
this.maybeTransitionToHalfOpen();
|
|
56
|
+
if (this.state === "open") {
|
|
57
|
+
const retryAfterMs = Math.max(0, this.openMs - (Date.now() - this.openedAt));
|
|
58
|
+
throw new CircuitOpenError(this.name, retryAfterMs);
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
const result = await fn();
|
|
62
|
+
this.onSuccess();
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
this.onFailure();
|
|
67
|
+
throw err;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
maybeTransitionToHalfOpen() {
|
|
71
|
+
if (this.state === "open" && Date.now() - this.openedAt >= this.openMs) {
|
|
72
|
+
this.state = "half-open";
|
|
73
|
+
this.successes = 0;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
onSuccess() {
|
|
77
|
+
if (this.state === "half-open") {
|
|
78
|
+
this.successes++;
|
|
79
|
+
if (this.successes >= this.successThreshold) {
|
|
80
|
+
this.state = "closed";
|
|
81
|
+
this.failures = 0;
|
|
82
|
+
this.successes = 0;
|
|
83
|
+
}
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// closed: decay failure count on success
|
|
87
|
+
this.failures = 0;
|
|
88
|
+
}
|
|
89
|
+
onFailure() {
|
|
90
|
+
this.failures++;
|
|
91
|
+
this.successes = 0;
|
|
92
|
+
if (this.state === "half-open") {
|
|
93
|
+
this.trip();
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (this.failures >= this.failureThreshold) {
|
|
97
|
+
this.trip();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
trip() {
|
|
101
|
+
this.state = "open";
|
|
102
|
+
this.openedAt = Date.now();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export function computeBackoffDelay(attempt, options = {}) {
|
|
106
|
+
const base = options.baseDelayMs ?? 100;
|
|
107
|
+
const max = options.maxDelayMs ?? 10_000;
|
|
108
|
+
const factor = options.factor ?? 2;
|
|
109
|
+
const jitter = options.jitter !== false;
|
|
110
|
+
// attempt is 1-based for first retry after failure → attempt 1 => base * factor^0
|
|
111
|
+
const exp = Math.max(0, attempt - 1);
|
|
112
|
+
let delay = Math.min(max, base * Math.pow(factor, exp));
|
|
113
|
+
if (jitter) {
|
|
114
|
+
delay = Math.floor(Math.random() * delay);
|
|
115
|
+
}
|
|
116
|
+
return delay;
|
|
117
|
+
}
|
|
118
|
+
export async function withRetry(fn, options = {}) {
|
|
119
|
+
const maxAttempts = Math.max(1, options.maxAttempts ?? 3);
|
|
120
|
+
const retryIf = options.retryIf ?? (() => true);
|
|
121
|
+
let lastError;
|
|
122
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
123
|
+
if (options.signal?.aborted) {
|
|
124
|
+
throw options.signal.reason ?? new Error("Aborted");
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
return await fn(attempt);
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
lastError = err;
|
|
131
|
+
const isLast = attempt >= maxAttempts;
|
|
132
|
+
if (isLast || !retryIf(err, attempt)) {
|
|
133
|
+
throw err;
|
|
134
|
+
}
|
|
135
|
+
const delay = computeBackoffDelay(attempt, options);
|
|
136
|
+
options.onRetry?.(err, attempt, delay);
|
|
137
|
+
await sleep(delay, options.signal);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
throw lastError;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Execute `fn` through optional circuit breaker + retry with exponential backoff.
|
|
144
|
+
*/
|
|
145
|
+
export async function withResilience(fn, options = {}) {
|
|
146
|
+
const breaker = options.circuitBreaker;
|
|
147
|
+
const skipOpen = options.skipRetryOnOpenCircuit !== false;
|
|
148
|
+
const retryOpts = {
|
|
149
|
+
...options.retry,
|
|
150
|
+
retryIf: (err, attempt) => {
|
|
151
|
+
if (skipOpen && err instanceof CircuitOpenError)
|
|
152
|
+
return false;
|
|
153
|
+
return options.retry?.retryIf ? options.retry.retryIf(err, attempt) : true;
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
return withRetry(async (attempt) => {
|
|
157
|
+
if (breaker) {
|
|
158
|
+
return breaker.exec(() => fn(attempt));
|
|
159
|
+
}
|
|
160
|
+
return fn(attempt);
|
|
161
|
+
}, retryOpts);
|
|
162
|
+
}
|
|
163
|
+
/** Heuristic: retry rate limits, timeouts, and common transient network errors. */
|
|
164
|
+
export function isTransientError(error) {
|
|
165
|
+
if (error instanceof CircuitOpenError)
|
|
166
|
+
return false;
|
|
167
|
+
if (!error)
|
|
168
|
+
return false;
|
|
169
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
170
|
+
const lower = msg.toLowerCase();
|
|
171
|
+
const code = error.code;
|
|
172
|
+
const status = error.status;
|
|
173
|
+
if (status === 429 || status === 502 || status === 503 || status === 504)
|
|
174
|
+
return true;
|
|
175
|
+
if (code === "ETIMEDOUT" || code === "ECONNRESET" || code === "EAI_AGAIN" || code === "ENOTFOUND") {
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
if (lower.includes("rate limit") ||
|
|
179
|
+
lower.includes("too many requests") ||
|
|
180
|
+
lower.includes("timeout") ||
|
|
181
|
+
lower.includes("temporar") ||
|
|
182
|
+
lower.includes("econnreset") ||
|
|
183
|
+
lower.includes("socket hang up")) {
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
/** Shared breakers for common services (lazy). */
|
|
189
|
+
const breakers = new Map();
|
|
190
|
+
export function getCircuitBreaker(name, options) {
|
|
191
|
+
let b = breakers.get(name);
|
|
192
|
+
if (!b) {
|
|
193
|
+
b = new CircuitBreaker({ name, ...options });
|
|
194
|
+
breakers.set(name, b);
|
|
195
|
+
}
|
|
196
|
+
return b;
|
|
197
|
+
}
|
|
198
|
+
export function resetAllCircuitBreakers() {
|
|
199
|
+
for (const b of breakers.values())
|
|
200
|
+
b.reset();
|
|
201
|
+
breakers.clear();
|
|
202
|
+
}
|
|
203
|
+
function sleep(ms, signal) {
|
|
204
|
+
return new Promise((resolve, reject) => {
|
|
205
|
+
if (signal?.aborted) {
|
|
206
|
+
reject(signal.reason ?? new Error("Aborted"));
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const timer = setTimeout(resolve, ms);
|
|
210
|
+
const onAbort = () => {
|
|
211
|
+
clearTimeout(timer);
|
|
212
|
+
reject(signal?.reason ?? new Error("Aborted"));
|
|
213
|
+
};
|
|
214
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=resilience.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resilience.js","sourceRoot":"","sources":["../../../../shared/src/resilience.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAkCH,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACvB,OAAO,CAAS;IAChB,YAAY,CAAS;IAErC,YAAY,OAAe,EAAE,YAAoB;QAC7C,KAAK,CACD,mBAAmB,OAAO,oDAAoD,YAAY,IAAI,CACjG,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACrC,CAAC;CACJ;AAED,MAAM,OAAO,cAAc;IACf,KAAK,GAAiB,QAAQ,CAAC;IAC/B,QAAQ,GAAG,CAAC,CAAC;IACb,SAAS,GAAG,CAAC,CAAC;IACd,QAAQ,GAAG,CAAC,CAAC;IACJ,gBAAgB,CAAS;IACzB,gBAAgB,CAAS;IACzB,MAAM,CAAS;IACf,IAAI,CAAS;IAE9B,YAAY,UAAiC,EAAE;QAC3C,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,CAAC,CAAC;QACtD,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC;QACvC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC;IAC1C,CAAC;IAEM,QAAQ;QACX,IAAI,CAAC,yBAAyB,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAEM,QAAQ;QAMX,OAAO;YACH,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE;YACtB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,IAAI,EAAE,IAAI,CAAC,IAAI;SAClB,CAAC;IACN,CAAC;IAED,uDAAuD;IAChD,KAAK;QACR,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC;QACtB,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;IACtB,CAAC;IAEM,KAAK,CAAC,IAAI,CAAI,EAAoB;QACrC,IAAI,CAAC,yBAAyB,EAAE,CAAC;QAEjC,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YACxB,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC7E,MAAM,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QACxD,CAAC;QAED,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,CAAC;YAC1B,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,OAAO,MAAM,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,MAAM,GAAG,CAAC;QACd,CAAC;IACL,CAAC;IAEO,yBAAyB;QAC7B,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACrE,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC;YACzB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QACvB,CAAC;IACL,CAAC;IAEO,SAAS;QACb,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YAC7B,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBAC1C,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC;gBACtB,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;gBAClB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;YACvB,CAAC;YACD,OAAO;QACX,CAAC;QACD,yCAAyC;QACzC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;IACtB,CAAC;IAEO,SAAS;QACb,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QACnB,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YAC7B,IAAI,CAAC,IAAI,EAAE,CAAC;YACZ,OAAO;QACX,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACzC,IAAI,CAAC,IAAI,EAAE,CAAC;QAChB,CAAC;IACL,CAAC;IAEO,IAAI;QACR,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC;QACpB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC/B,CAAC;CACJ;AAED,MAAM,UAAU,mBAAmB,CAC/B,OAAe,EACf,UAAkF,EAAE;IAEpF,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,IAAI,GAAG,CAAC;IACxC,MAAM,GAAG,GAAG,OAAO,CAAC,UAAU,IAAI,MAAM,CAAC;IACzC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,KAAK,KAAK,CAAC;IAExC,kFAAkF;IAClF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC;IACrC,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IACxD,IAAI,MAAM,EAAE,CAAC;QACT,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAC3B,EAAmC,EACnC,UAAwB,EAAE;IAE1B,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAEhD,IAAI,SAAkB,CAAC;IACvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QACtD,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;YAC1B,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,CAAC;YACD,OAAO,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,SAAS,GAAG,GAAG,CAAC;YAChB,MAAM,MAAM,GAAG,OAAO,IAAI,WAAW,CAAC;YACtC,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,CAAC;gBACnC,MAAM,GAAG,CAAC;YACd,CAAC;YACD,MAAM,KAAK,GAAG,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACpD,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;YACvC,MAAM,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC;IACL,CAAC;IACD,MAAM,SAAS,CAAC;AACpB,CAAC;AASD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAChC,EAAmC,EACnC,UAA6B,EAAE;IAE/B,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC;IACvC,MAAM,QAAQ,GAAG,OAAO,CAAC,sBAAsB,KAAK,KAAK,CAAC;IAE1D,MAAM,SAAS,GAAiB;QAC5B,GAAG,OAAO,CAAC,KAAK;QAChB,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE;YACtB,IAAI,QAAQ,IAAI,GAAG,YAAY,gBAAgB;gBAAE,OAAO,KAAK,CAAC;YAC9D,OAAO,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC/E,CAAC;KACJ,CAAC;IAEF,OAAO,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QAC/B,IAAI,OAAO,EAAE,CAAC;YACV,OAAO,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC,EAAE,SAAS,CAAC,CAAC;AAClB,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC3C,IAAI,KAAK,YAAY,gBAAgB;QAAE,OAAO,KAAK,CAAC;IACpD,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAEzB,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACnE,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAChC,MAAM,IAAI,GAAI,KAA2B,CAAC,IAAI,CAAC;IAC/C,MAAM,MAAM,GAAI,KAA6B,CAAC,MAAM,CAAC;IAErD,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IACtF,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,YAAY,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;QAChG,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,IACI,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC;QAC5B,KAAK,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QACnC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC;QACzB,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC1B,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC;QAC5B,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAClC,CAAC;QACC,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,kDAAkD;AAClD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA0B,CAAC;AAEnD,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,OAA+B;IAC3E,IAAI,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC3B,IAAI,CAAC,CAAC,EAAE,CAAC;QACL,CAAC,GAAG,IAAI,cAAc,CAAC,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;QAC7C,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,CAAC,CAAC;AACb,CAAC;AAED,MAAM,UAAU,uBAAuB;IACnC,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,MAAM,EAAE;QAAE,CAAC,CAAC,KAAK,EAAE,CAAC;IAC7C,QAAQ,CAAC,KAAK,EAAE,CAAC;AACrB,CAAC;AAED,SAAS,KAAK,CAAC,EAAU,EAAE,MAAoB;IAC3C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACnC,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;YAClB,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;YAC9C,OAAO;QACX,CAAC;QACD,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACtC,MAAM,OAAO,GAAG,GAAG,EAAE;YACjB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,MAAM,EAAE,MAAM,IAAI,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;QACnD,CAAC,CAAC;QACF,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sandboxed filesystem mutations — Phase 1.2.
|
|
3
|
+
*
|
|
4
|
+
* - Always holds AtomicFileLock (try/finally).
|
|
5
|
+
* - When runtime=container: write via container stdin → /workspace/<path>
|
|
6
|
+
* - When runtime=uid|none: write on host under projectRoot (safePath caller responsibility)
|
|
7
|
+
* - ATABEY_SANDBOX_REQUIRED=true rejects writes if isolation is none
|
|
8
|
+
*/
|
|
9
|
+
import { type SandboxRuntimeConfig } from "./sandbox-runtime.js";
|
|
10
|
+
export interface SandboxFsWriteResult {
|
|
11
|
+
absolutePath: string;
|
|
12
|
+
relativePath: string;
|
|
13
|
+
runtime: SandboxRuntimeConfig["effectiveMode"];
|
|
14
|
+
isolationLabel: string;
|
|
15
|
+
bytes: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Normalize user path to a project-relative POSIX path.
|
|
19
|
+
* Absolute paths are accepted only if they resolve inside projectRoot.
|
|
20
|
+
*/
|
|
21
|
+
export declare function assertSafeRelativePath(userPath: string, projectRoot?: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Write file content under project root using the active sandbox runtime.
|
|
24
|
+
*/
|
|
25
|
+
export declare function writeFileInSandbox(projectRoot: string, userPath: string, content: string, options?: {
|
|
26
|
+
ownerId?: string;
|
|
27
|
+
timeoutMs?: number;
|
|
28
|
+
}): Promise<SandboxFsWriteResult>;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sandboxed filesystem mutations — Phase 1.2.
|
|
3
|
+
*
|
|
4
|
+
* - Always holds AtomicFileLock (try/finally).
|
|
5
|
+
* - When runtime=container: write via container stdin → /workspace/<path>
|
|
6
|
+
* - When runtime=uid|none: write on host under projectRoot (safePath caller responsibility)
|
|
7
|
+
* - ATABEY_SANDBOX_REQUIRED=true rejects writes if isolation is none
|
|
8
|
+
*/
|
|
9
|
+
import fs from "fs";
|
|
10
|
+
import path from "path";
|
|
11
|
+
import { AtomicFileLock } from "./file-lock.js";
|
|
12
|
+
import { resolveSandboxRuntimeConfig, runInSandbox, SandboxRequiredError, } from "./sandbox-runtime.js";
|
|
13
|
+
/**
|
|
14
|
+
* Normalize user path to a project-relative POSIX path.
|
|
15
|
+
* Absolute paths are accepted only if they resolve inside projectRoot.
|
|
16
|
+
*/
|
|
17
|
+
export function assertSafeRelativePath(userPath, projectRoot) {
|
|
18
|
+
if (!userPath || !userPath.trim()) {
|
|
19
|
+
throw new Error("[SANDBOX_FS] Empty path is not allowed");
|
|
20
|
+
}
|
|
21
|
+
const trimmed = userPath.trim();
|
|
22
|
+
if (trimmed.includes("\0")) {
|
|
23
|
+
throw new Error("[SANDBOX_FS] Illegal null byte in path");
|
|
24
|
+
}
|
|
25
|
+
let rel = trimmed.replace(/\\/g, "/");
|
|
26
|
+
// Absolute path → must live under projectRoot
|
|
27
|
+
if (path.isAbsolute(trimmed) || rel.startsWith("/")) {
|
|
28
|
+
if (!projectRoot) {
|
|
29
|
+
throw new Error(`[SANDBOX_FS] Absolute paths require projectRoot: "${userPath}"`);
|
|
30
|
+
}
|
|
31
|
+
const root = path.resolve(projectRoot);
|
|
32
|
+
const abs = path.resolve(trimmed);
|
|
33
|
+
if (!abs.startsWith(root + path.sep) && abs !== root) {
|
|
34
|
+
throw new Error(`[SANDBOX_FS] Absolute path escapes project root: "${userPath}"`);
|
|
35
|
+
}
|
|
36
|
+
rel = path.relative(root, abs).replace(/\\/g, "/");
|
|
37
|
+
if (!rel || rel === ".") {
|
|
38
|
+
throw new Error("[SANDBOX_FS] Path resolves to project root; refuse write");
|
|
39
|
+
}
|
|
40
|
+
if (rel.startsWith("..")) {
|
|
41
|
+
throw new Error(`[SANDBOX_FS] Path traversal denied: "${userPath}"`);
|
|
42
|
+
}
|
|
43
|
+
return rel;
|
|
44
|
+
}
|
|
45
|
+
// Relative: reject .. segments
|
|
46
|
+
const parts = [];
|
|
47
|
+
for (const seg of rel.split("/")) {
|
|
48
|
+
if (!seg || seg === ".")
|
|
49
|
+
continue;
|
|
50
|
+
if (seg === "..") {
|
|
51
|
+
throw new Error(`[SANDBOX_FS] Path traversal denied: "${userPath}"`);
|
|
52
|
+
}
|
|
53
|
+
parts.push(seg);
|
|
54
|
+
}
|
|
55
|
+
if (parts.length === 0) {
|
|
56
|
+
throw new Error("[SANDBOX_FS] Path resolves to project root; refuse write");
|
|
57
|
+
}
|
|
58
|
+
return parts.join("/");
|
|
59
|
+
}
|
|
60
|
+
function shellSingleQuote(s) {
|
|
61
|
+
// Safe for sh single-quoted strings
|
|
62
|
+
return `'${s.replace(/'/g, `'\\''`)}'`;
|
|
63
|
+
}
|
|
64
|
+
function createLock(projectRoot) {
|
|
65
|
+
return new AtomicFileLock({
|
|
66
|
+
projectRoot,
|
|
67
|
+
locksDir: path.join(projectRoot, ".atabey", "locks"),
|
|
68
|
+
ttlMs: 5 * 60 * 1000,
|
|
69
|
+
timeoutMs: 15_000,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function hostWriteAtomic(absolutePath, content) {
|
|
73
|
+
const dir = path.dirname(absolutePath);
|
|
74
|
+
if (!fs.existsSync(dir)) {
|
|
75
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
76
|
+
}
|
|
77
|
+
// Write exact bytes (callers decide trailing newline — patch/replace need fidelity)
|
|
78
|
+
const tempPath = `${absolutePath}.${Math.random().toString(36).slice(2, 9)}.tmp`;
|
|
79
|
+
try {
|
|
80
|
+
fs.writeFileSync(tempPath, content, "utf8");
|
|
81
|
+
fs.renameSync(tempPath, absolutePath);
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
try {
|
|
85
|
+
if (fs.existsSync(tempPath))
|
|
86
|
+
fs.unlinkSync(tempPath);
|
|
87
|
+
}
|
|
88
|
+
catch { /* ignore */ }
|
|
89
|
+
throw err;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Write file content under project root using the active sandbox runtime.
|
|
94
|
+
*/
|
|
95
|
+
export async function writeFileInSandbox(projectRoot, userPath, content, options) {
|
|
96
|
+
const root = path.resolve(projectRoot);
|
|
97
|
+
const relativePath = assertSafeRelativePath(userPath, root);
|
|
98
|
+
const absolutePath = path.resolve(root, relativePath);
|
|
99
|
+
// Belt-and-suspenders: stay inside root
|
|
100
|
+
if (!absolutePath.startsWith(root + path.sep) && absolutePath !== root) {
|
|
101
|
+
throw new Error(`[SANDBOX_FS] Resolved path escapes project root: "${userPath}"`);
|
|
102
|
+
}
|
|
103
|
+
const cfg = resolveSandboxRuntimeConfig(root, options?.timeoutMs);
|
|
104
|
+
if (cfg.required && cfg.effectiveMode === "none") {
|
|
105
|
+
throw new SandboxRequiredError("[SANDBOX_REQUIRED] File write blocked: no sandbox isolation available. " +
|
|
106
|
+
"Set ATABEY_SANDBOX_RUNTIME=container (Podman/Docker) or uid, or disable ATABEY_SANDBOX_REQUIRED.");
|
|
107
|
+
}
|
|
108
|
+
const owner = options?.ownerId || process.env.ATABEY_ACTIVE_AGENT || "mcp-writer";
|
|
109
|
+
const lock = createLock(root);
|
|
110
|
+
const posixRel = relativePath.split(path.sep).join("/");
|
|
111
|
+
return lock.withLock(relativePath, owner, async () => {
|
|
112
|
+
if (cfg.effectiveMode === "container" && cfg.engine !== "none") {
|
|
113
|
+
const dir = path.posix.dirname(posixRel);
|
|
114
|
+
const script = dir === "."
|
|
115
|
+
? `cat > ${shellSingleQuote(posixRel)}`
|
|
116
|
+
: `mkdir -p ${shellSingleQuote(dir)} && cat > ${shellSingleQuote(posixRel)}`;
|
|
117
|
+
const result = await runInSandbox({
|
|
118
|
+
command: "sh",
|
|
119
|
+
args: ["-c", script],
|
|
120
|
+
projectRoot: root,
|
|
121
|
+
timeoutMs: options?.timeoutMs ?? cfg.timeoutMs,
|
|
122
|
+
stdin: content,
|
|
123
|
+
});
|
|
124
|
+
if (result.code !== 0) {
|
|
125
|
+
throw new Error(`[SANDBOX_FS] Container write failed (code ${result.code}): ${result.stderr || result.stdout}`.trim());
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
absolutePath,
|
|
129
|
+
relativePath,
|
|
130
|
+
runtime: "container",
|
|
131
|
+
isolationLabel: result.isolationLabel,
|
|
132
|
+
bytes: Buffer.byteLength(content, "utf8"),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
// uid | none — host write confined to project root
|
|
136
|
+
hostWriteAtomic(absolutePath, content);
|
|
137
|
+
return {
|
|
138
|
+
absolutePath,
|
|
139
|
+
relativePath,
|
|
140
|
+
runtime: cfg.effectiveMode,
|
|
141
|
+
isolationLabel: cfg.effectiveMode === "uid"
|
|
142
|
+
? "uid host write (project-bound)"
|
|
143
|
+
: "host write (project-bound)",
|
|
144
|
+
bytes: Buffer.byteLength(content, "utf8"),
|
|
145
|
+
};
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=sandbox-fs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-fs.js","sourceRoot":"","sources":["../../../../shared/src/sandbox-fs.ts"],"names":[],"mappings":"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"}
|