bonecode 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +183 -0
- package/README.md +71 -0
- package/bin/bonecode +62 -0
- package/bone/migrations/rag_vectors.sql +258 -0
- package/bone/output/agent/.dockerignore +7 -0
- package/bone/output/agent/.env.example +36 -0
- package/bone/output/agent/.github/workflows/ci.yaml +58 -0
- package/bone/output/agent/AgentDomain.bone.map +350 -0
- package/bone/output/agent/AgentDomain.postman_collection.json +958 -0
- package/bone/output/agent/Dockerfile +22 -0
- package/bone/output/agent/README.md +47 -0
- package/bone/output/agent/admin/index.html +740 -0
- package/bone/output/agent/docker-compose.yaml +22 -0
- package/bone/output/agent/k8s/deployment.yaml +75 -0
- package/bone/output/agent/migrations/agent.sql +36 -0
- package/bone/output/agent/migrations/agent_instance.sql +36 -0
- package/bone/output/agent/migrations/audit_log.sql +18 -0
- package/bone/output/agent/migrations/build_step.sql +34 -0
- package/bone/output/agent/migrations/event_outbox.sql +31 -0
- package/bone/output/agent/migrations/plan.sql +30 -0
- package/bone/output/agent/migrations/task.sql +30 -0
- package/bone/output/agent/migrations/tool_call.sql +33 -0
- package/bone/output/agent/openapi.yaml +1116 -0
- package/bone/output/agent/package.json +36 -0
- package/bone/output/agent/schema.graphql +233 -0
- package/bone/output/agent/sdk/client.ts +231 -0
- package/bone/output/agent/src/algorithms.ts +2 -0
- package/bone/output/agent/src/audit.ts +44 -0
- package/bone/output/agent/src/auth.ts +57 -0
- package/bone/output/agent/src/cron.ts +12 -0
- package/bone/output/agent/src/db.ts +32 -0
- package/bone/output/agent/src/debug.ts +66 -0
- package/bone/output/agent/src/events.ts +243 -0
- package/bone/output/agent/src/extensions.ts +54 -0
- package/bone/output/agent/src/failure_rules.ts +323 -0
- package/bone/output/agent/src/flows.ts +168 -0
- package/bone/output/agent/src/health.ts +43 -0
- package/bone/output/agent/src/index.ts +100 -0
- package/bone/output/agent/src/logger.ts +66 -0
- package/bone/output/agent/src/metrics.ts +75 -0
- package/bone/output/agent/src/migrate.ts +352 -0
- package/bone/output/agent/src/migration_diff.ts +108 -0
- package/bone/output/agent/src/notify.ts +125 -0
- package/bone/output/agent/src/routes/agent_instance.ts +234 -0
- package/bone/output/agent/src/routes/build_step.ts +105 -0
- package/bone/output/agent/src/routes/plan.ts +91 -0
- package/bone/output/agent/src/routes/task.ts +105 -0
- package/bone/output/agent/src/routes/tool_call.ts +166 -0
- package/bone/output/agent/src/schemas.ts +384 -0
- package/bone/output/agent/src/state_machines/agent_instance.ts +24 -0
- package/bone/output/agent/src/state_machines/build_step.ts +22 -0
- package/bone/output/agent/src/state_machines/plan.ts +22 -0
- package/bone/output/agent/src/state_machines/task.ts +22 -0
- package/bone/output/agent/src/state_machines/tool_call.ts +22 -0
- package/bone/output/agent/src/tests.ts +362 -0
- package/bone/output/agent/src/websocket.ts +201 -0
- package/bone/output/agent/tsconfig.json +25 -0
- package/bone/output/rag/.dockerignore +7 -0
- package/bone/output/rag/.env.example +36 -0
- package/bone/output/rag/.github/workflows/ci.yaml +58 -0
- package/bone/output/rag/Dockerfile +22 -0
- package/bone/output/rag/RAGDomain.bone.map +287 -0
- package/bone/output/rag/RAGDomain.postman_collection.json +923 -0
- package/bone/output/rag/README.md +47 -0
- package/bone/output/rag/admin/index.html +818 -0
- package/bone/output/rag/docker-compose.yaml +22 -0
- package/bone/output/rag/k8s/deployment.yaml +75 -0
- package/bone/output/rag/migrations/audit_log.sql +18 -0
- package/bone/output/rag/migrations/code_chunk.sql +34 -0
- package/bone/output/rag/migrations/code_file.sql +33 -0
- package/bone/output/rag/migrations/event_outbox.sql +31 -0
- package/bone/output/rag/migrations/indexing_job.sql +33 -0
- package/bone/output/rag/migrations/knowledge_base.sql +35 -0
- package/bone/output/rag/migrations/memory_entry.sql +34 -0
- package/bone/output/rag/openapi.yaml +1097 -0
- package/bone/output/rag/package.json +36 -0
- package/bone/output/rag/schema.graphql +245 -0
- package/bone/output/rag/sdk/client.ts +234 -0
- package/bone/output/rag/src/algorithms.ts +2 -0
- package/bone/output/rag/src/audit.ts +37 -0
- package/bone/output/rag/src/auth.ts +57 -0
- package/bone/output/rag/src/cron.ts +12 -0
- package/bone/output/rag/src/db.ts +32 -0
- package/bone/output/rag/src/debug.ts +66 -0
- package/bone/output/rag/src/events.ts +243 -0
- package/bone/output/rag/src/extensions.ts +350 -0
- package/bone/output/rag/src/failure_rules.ts +315 -0
- package/bone/output/rag/src/flows.ts +239 -0
- package/bone/output/rag/src/health.ts +43 -0
- package/bone/output/rag/src/index.ts +95 -0
- package/bone/output/rag/src/logger.ts +66 -0
- package/bone/output/rag/src/metrics.ts +75 -0
- package/bone/output/rag/src/migrate.ts +364 -0
- package/bone/output/rag/src/migration_diff.ts +108 -0
- package/bone/output/rag/src/notify.ts +99 -0
- package/bone/output/rag/src/routes/code_chunk.ts +75 -0
- package/bone/output/rag/src/routes/code_file.ts +101 -0
- package/bone/output/rag/src/routes/indexing_job.ts +87 -0
- package/bone/output/rag/src/routes/knowledge_base.ts +230 -0
- package/bone/output/rag/src/routes/memory_entry.ts +87 -0
- package/bone/output/rag/src/schemas.ts +394 -0
- package/bone/output/rag/src/state_machines/code_file.ts +23 -0
- package/bone/output/rag/src/state_machines/indexing_job.ts +22 -0
- package/bone/output/rag/src/state_machines/knowledge_base.ts +23 -0
- package/bone/output/rag/src/state_machines/memory_entry.ts +20 -0
- package/bone/output/rag/src/tests.ts +340 -0
- package/bone/output/rag/tsconfig.json +25 -0
- package/bone/output/session/.dockerignore +7 -0
- package/bone/output/session/.env.example +36 -0
- package/bone/output/session/.github/workflows/ci.yaml +58 -0
- package/bone/output/session/Dockerfile +22 -0
- package/bone/output/session/README.md +47 -0
- package/bone/output/session/SessionDomain.bone.map +350 -0
- package/bone/output/session/SessionDomain.postman_collection.json +958 -0
- package/bone/output/session/admin/index.html +667 -0
- package/bone/output/session/docker-compose.yaml +22 -0
- package/bone/output/session/k8s/deployment.yaml +75 -0
- package/bone/output/session/migrations/audit_log.sql +18 -0
- package/bone/output/session/migrations/event_outbox.sql +31 -0
- package/bone/output/session/migrations/message.sql +31 -0
- package/bone/output/session/migrations/part.sql +28 -0
- package/bone/output/session/migrations/permission.sql +28 -0
- package/bone/output/session/migrations/project.sql +28 -0
- package/bone/output/session/migrations/session.sql +38 -0
- package/bone/output/session/openapi.yaml +1101 -0
- package/bone/output/session/package.json +36 -0
- package/bone/output/session/schema.graphql +222 -0
- package/bone/output/session/sdk/client.ts +225 -0
- package/bone/output/session/src/algorithms.ts +2 -0
- package/bone/output/session/src/audit.ts +44 -0
- package/bone/output/session/src/auth.ts +57 -0
- package/bone/output/session/src/cron.ts +12 -0
- package/bone/output/session/src/db.ts +32 -0
- package/bone/output/session/src/debug.ts +66 -0
- package/bone/output/session/src/events.ts +270 -0
- package/bone/output/session/src/extensions.ts +215 -0
- package/bone/output/session/src/failure_rules.ts +284 -0
- package/bone/output/session/src/flows.ts +168 -0
- package/bone/output/session/src/health.ts +43 -0
- package/bone/output/session/src/index.ts +100 -0
- package/bone/output/session/src/logger.ts +66 -0
- package/bone/output/session/src/metrics.ts +75 -0
- package/bone/output/session/src/migrate.ts +332 -0
- package/bone/output/session/src/migration_diff.ts +108 -0
- package/bone/output/session/src/notify.ts +112 -0
- package/bone/output/session/src/routes/message.ts +93 -0
- package/bone/output/session/src/routes/part.ts +79 -0
- package/bone/output/session/src/routes/permission.ts +79 -0
- package/bone/output/session/src/routes/project.ts +79 -0
- package/bone/output/session/src/routes/session.ts +294 -0
- package/bone/output/session/src/schemas.ts +357 -0
- package/bone/output/session/src/state_machines/session.ts +23 -0
- package/bone/output/session/src/tests.ts +326 -0
- package/bone/output/session/src/websocket.ts +201 -0
- package/bone/output/session/tsconfig.json +25 -0
- package/bone/output/workspace/.dockerignore +7 -0
- package/bone/output/workspace/.env.example +36 -0
- package/bone/output/workspace/.github/workflows/ci.yaml +58 -0
- package/bone/output/workspace/Dockerfile +22 -0
- package/bone/output/workspace/README.md +45 -0
- package/bone/output/workspace/WorkspaceDomain.bone.map +189 -0
- package/bone/output/workspace/WorkspaceDomain.postman_collection.json +621 -0
- package/bone/output/workspace/admin/index.html +485 -0
- package/bone/output/workspace/docker-compose.yaml +22 -0
- package/bone/output/workspace/k8s/deployment.yaml +75 -0
- package/bone/output/workspace/migrations/audit_log.sql +18 -0
- package/bone/output/workspace/migrations/codebase.sql +34 -0
- package/bone/output/workspace/migrations/event_outbox.sql +31 -0
- package/bone/output/workspace/migrations/snapshot.sql +32 -0
- package/bone/output/workspace/migrations/workspace.sql +33 -0
- package/bone/output/workspace/openapi.yaml +721 -0
- package/bone/output/workspace/package.json +36 -0
- package/bone/output/workspace/schema.graphql +153 -0
- package/bone/output/workspace/sdk/client.ts +155 -0
- package/bone/output/workspace/src/algorithms.ts +2 -0
- package/bone/output/workspace/src/audit.ts +37 -0
- package/bone/output/workspace/src/auth.ts +57 -0
- package/bone/output/workspace/src/cron.ts +12 -0
- package/bone/output/workspace/src/db.ts +32 -0
- package/bone/output/workspace/src/debug.ts +66 -0
- package/bone/output/workspace/src/events.ts +243 -0
- package/bone/output/workspace/src/extensions.ts +44 -0
- package/bone/output/workspace/src/failure_rules.ts +153 -0
- package/bone/output/workspace/src/health.ts +43 -0
- package/bone/output/workspace/src/index.ts +89 -0
- package/bone/output/workspace/src/logger.ts +66 -0
- package/bone/output/workspace/src/metrics.ts +75 -0
- package/bone/output/workspace/src/migrate.ts +220 -0
- package/bone/output/workspace/src/migration_diff.ts +108 -0
- package/bone/output/workspace/src/notify.ts +73 -0
- package/bone/output/workspace/src/routes/codebase.ts +87 -0
- package/bone/output/workspace/src/routes/snapshot.ts +127 -0
- package/bone/output/workspace/src/routes/workspace.ts +190 -0
- package/bone/output/workspace/src/schemas.ts +231 -0
- package/bone/output/workspace/src/state_machines/codebase.ts +21 -0
- package/bone/output/workspace/src/state_machines/snapshot.ts +20 -0
- package/bone/output/workspace/src/state_machines/workspace.ts +21 -0
- package/bone/output/workspace/src/tests.ts +249 -0
- package/bone/output/workspace/tsconfig.json +25 -0
- package/compat/opencode_adapter.ts +410 -0
- package/package.json +69 -0
- package/scripts/check_benchmark_session.js +34 -0
- package/scripts/check_finish_event.js +24 -0
- package/scripts/check_parts.js +15 -0
- package/scripts/compile.js +79 -0
- package/scripts/copy_opencode.ps1 +53 -0
- package/scripts/create_functions.sql +129 -0
- package/scripts/migrate.js +85 -0
- package/scripts/migrate_from_opencode.ts +218 -0
- package/scripts/test_agent_loop.js +101 -0
- package/scripts/test_api.ps1 +116 -0
- package/scripts/test_context_builder.js +136 -0
- package/scripts/test_context_builder.ts +97 -0
- package/scripts/test_rag.js +189 -0
- package/scripts/test_stream_events.js +36 -0
- package/scripts/test_websocket_and_saga.js +216 -0
- package/src/cli.ts +475 -0
- package/src/config.ts +162 -0
- package/src/context_builder.ts +598 -0
- package/src/engine/account/account.sql.ts +39 -0
- package/src/engine/account/account.ts +456 -0
- package/src/engine/account/repo.ts +166 -0
- package/src/engine/account/schema.ts +99 -0
- package/src/engine/account/url.ts +8 -0
- package/src/engine/acp/README.md +174 -0
- package/src/engine/acp/agent.ts +1968 -0
- package/src/engine/acp/runtime.ts +22 -0
- package/src/engine/acp/session.ts +122 -0
- package/src/engine/acp/types.ts +24 -0
- package/src/engine/agent/agent.ts +463 -0
- package/src/engine/agent/generate.txt +75 -0
- package/src/engine/agent/prompt/compaction.txt +9 -0
- package/src/engine/agent/prompt/explore.txt +18 -0
- package/src/engine/agent/prompt/scout.txt +36 -0
- package/src/engine/agent/prompt/summary.txt +11 -0
- package/src/engine/agent/prompt/title.txt +44 -0
- package/src/engine/agent/subagent-permissions.ts +34 -0
- package/src/engine/auth/index.ts +96 -0
- package/src/engine/background/background/job.ts +200 -0
- package/src/engine/background/job.ts +200 -0
- package/src/engine/bus/bus-event.ts +45 -0
- package/src/engine/bus/global.ts +22 -0
- package/src/engine/bus/index.ts +203 -0
- package/src/engine/command/command/index.ts +181 -0
- package/src/engine/command/command/template/initialize.txt +66 -0
- package/src/engine/command/command/template/review.txt +101 -0
- package/src/engine/command/index.ts +181 -0
- package/src/engine/command/template/initialize.txt +66 -0
- package/src/engine/command/template/review.txt +101 -0
- package/src/engine/config/agent.ts +172 -0
- package/src/engine/config/attachment.ts +25 -0
- package/src/engine/config/command.ts +62 -0
- package/src/engine/config/config.ts +833 -0
- package/src/engine/config/console-state.ts +14 -0
- package/src/engine/config/entry-name.ts +16 -0
- package/src/engine/config/error.ts +23 -0
- package/src/engine/config/formatter.ts +13 -0
- package/src/engine/config/layout.ts +6 -0
- package/src/engine/config/lsp.ts +43 -0
- package/src/engine/config/managed.ts +71 -0
- package/src/engine/config/markdown.ts +96 -0
- package/src/engine/config/mcp.ts +56 -0
- package/src/engine/config/model-id.ts +5 -0
- package/src/engine/config/parse.ts +79 -0
- package/src/engine/config/paths.ts +45 -0
- package/src/engine/config/permission.ts +58 -0
- package/src/engine/config/plugin.ts +84 -0
- package/src/engine/config/provider.ts +111 -0
- package/src/engine/config/reference.ts +23 -0
- package/src/engine/config/server.ts +19 -0
- package/src/engine/config/skills.ts +14 -0
- package/src/engine/config/variable.ts +90 -0
- package/src/engine/control-plane/adapters/index.ts +41 -0
- package/src/engine/control-plane/adapters/worktree.ts +96 -0
- package/src/engine/control-plane/dev/README.md +19 -0
- package/src/engine/control-plane/dev/debug-workspace-plugin.ts +73 -0
- package/src/engine/control-plane/schema.ts +14 -0
- package/src/engine/control-plane/types.ts +59 -0
- package/src/engine/control-plane/util.ts +39 -0
- package/src/engine/control-plane/workspace-adapter-runtime.ts +51 -0
- package/src/engine/control-plane/workspace-context.ts +26 -0
- package/src/engine/control-plane/workspace.sql.ts +20 -0
- package/src/engine/control-plane/workspace.ts +1072 -0
- package/src/engine/data-migration.ts +161 -0
- package/src/engine/effect/app-runtime.ts +143 -0
- package/src/engine/effect/bootstrap-runtime.ts +29 -0
- package/src/engine/effect/bridge.ts +84 -0
- package/src/engine/effect/config-service.ts +67 -0
- package/src/engine/effect/instance-ref.ts +11 -0
- package/src/engine/effect/instance-registry.ts +12 -0
- package/src/engine/effect/instance-state.ts +72 -0
- package/src/engine/effect/promise.ts +17 -0
- package/src/engine/effect/run-service.ts +47 -0
- package/src/engine/effect/runner.ts +217 -0
- package/src/engine/effect/runtime-flags.ts +74 -0
- package/src/engine/effect/service-use.ts +38 -0
- package/src/engine/env/index.ts +37 -0
- package/src/engine/event-v2-bridge.ts +89 -0
- package/src/engine/file/file/ignore.ts +81 -0
- package/src/engine/file/file/index.ts +651 -0
- package/src/engine/file/file/protected.ts +59 -0
- package/src/engine/file/file/ripgrep.ts +481 -0
- package/src/engine/file/file/watcher.ts +167 -0
- package/src/engine/file/ignore.ts +81 -0
- package/src/engine/file/index.ts +651 -0
- package/src/engine/file/protected.ts +59 -0
- package/src/engine/file/ripgrep.ts +481 -0
- package/src/engine/file/watcher.ts +167 -0
- package/src/engine/format/format/formatter.ts +404 -0
- package/src/engine/format/format/index.ts +209 -0
- package/src/engine/format/formatter.ts +404 -0
- package/src/engine/format/index.ts +209 -0
- package/src/engine/git/git/index.ts +347 -0
- package/src/engine/git/index.ts +347 -0
- package/src/engine/id/id.ts +80 -0
- package/src/engine/ide/index.ts +70 -0
- package/src/engine/image/image/image.ts +176 -0
- package/src/engine/image/image.ts +176 -0
- package/src/engine/index.ts +251 -0
- package/src/engine/installation/index.ts +327 -0
- package/src/engine/lsp/client.ts +707 -0
- package/src/engine/lsp/diagnostic.ts +29 -0
- package/src/engine/lsp/language.ts +121 -0
- package/src/engine/lsp/launch.ts +21 -0
- package/src/engine/lsp/lsp/client.ts +707 -0
- package/src/engine/lsp/lsp/diagnostic.ts +29 -0
- package/src/engine/lsp/lsp/language.ts +121 -0
- package/src/engine/lsp/lsp/launch.ts +21 -0
- package/src/engine/lsp/lsp/lsp.ts +507 -0
- package/src/engine/lsp/lsp/server.ts +2064 -0
- package/src/engine/lsp/lsp.ts +507 -0
- package/src/engine/lsp/server.ts +2064 -0
- package/src/engine/mcp/auth.ts +146 -0
- package/src/engine/mcp/index.ts +958 -0
- package/src/engine/mcp/mcp/auth.ts +146 -0
- package/src/engine/mcp/mcp/index.ts +958 -0
- package/src/engine/mcp/mcp/oauth-callback.ts +232 -0
- package/src/engine/mcp/mcp/oauth-provider.ts +214 -0
- package/src/engine/mcp/oauth-callback.ts +232 -0
- package/src/engine/mcp/oauth-provider.ts +214 -0
- package/src/engine/node.ts +6 -0
- package/src/engine/patch/index.ts +689 -0
- package/src/engine/patch/patch/index.ts +689 -0
- package/src/engine/permission/arity.ts +163 -0
- package/src/engine/permission/evaluate.ts +15 -0
- package/src/engine/permission/index.ts +306 -0
- package/src/engine/permission/permission/arity.ts +163 -0
- package/src/engine/permission/permission/evaluate.ts +15 -0
- package/src/engine/permission/permission/index.ts +306 -0
- package/src/engine/permission/permission/schema.ts +13 -0
- package/src/engine/permission/schema.ts +13 -0
- package/src/engine/plugin/azure.ts +26 -0
- package/src/engine/plugin/cloudflare.ts +76 -0
- package/src/engine/plugin/codex.ts +622 -0
- package/src/engine/plugin/digitalocean.ts +411 -0
- package/src/engine/plugin/github-copilot/copilot.ts +394 -0
- package/src/engine/plugin/github-copilot/models.ts +196 -0
- package/src/engine/plugin/index.ts +295 -0
- package/src/engine/plugin/install.ts +439 -0
- package/src/engine/plugin/loader.ts +216 -0
- package/src/engine/plugin/meta.ts +188 -0
- package/src/engine/plugin/shared.ts +323 -0
- package/src/engine/project/bootstrap-service.ts +9 -0
- package/src/engine/project/bootstrap.ts +75 -0
- package/src/engine/project/instance-context.ts +24 -0
- package/src/engine/project/instance-layer.ts +11 -0
- package/src/engine/project/instance-runtime.ts +16 -0
- package/src/engine/project/instance-store.ts +193 -0
- package/src/engine/project/project.sql.ts +17 -0
- package/src/engine/project/project.ts +537 -0
- package/src/engine/project/schema.ts +13 -0
- package/src/engine/project/vcs.ts +405 -0
- package/src/engine/provider/auth.ts +225 -0
- package/src/engine/provider/error.ts +204 -0
- package/src/engine/provider/model-status.ts +8 -0
- package/src/engine/provider/provider.ts +1843 -0
- package/src/engine/provider/schema.ts +30 -0
- package/src/engine/provider/sdk/copilot/AGENTS.md +1 -0
- package/src/engine/provider/transform.ts +1376 -0
- package/src/engine/pty/index.ts +365 -0
- package/src/engine/pty/input.ts +24 -0
- package/src/engine/pty/pty/index.ts +365 -0
- package/src/engine/pty/pty/input.ts +24 -0
- package/src/engine/pty/pty/pty.bun.ts +26 -0
- package/src/engine/pty/pty/pty.node.ts +27 -0
- package/src/engine/pty/pty/pty.ts +25 -0
- package/src/engine/pty/pty/schema.ts +14 -0
- package/src/engine/pty/pty/ticket.ts +68 -0
- package/src/engine/pty/pty.bun.ts +26 -0
- package/src/engine/pty/pty.node.ts +27 -0
- package/src/engine/pty/pty.ts +25 -0
- package/src/engine/pty/schema.ts +14 -0
- package/src/engine/pty/ticket.ts +68 -0
- package/src/engine/question/index.ts +213 -0
- package/src/engine/question/question/index.ts +213 -0
- package/src/engine/question/question/schema.ts +10 -0
- package/src/engine/question/schema.ts +10 -0
- package/src/engine/reference/reference/reference.ts +241 -0
- package/src/engine/reference/reference/repository-cache.ts +147 -0
- package/src/engine/reference/reference.ts +241 -0
- package/src/engine/reference/repository-cache.ts +147 -0
- package/src/engine/session/compaction.ts +651 -0
- package/src/engine/session/compaction_logic.ts +120 -0
- package/src/engine/session/instruction.ts +238 -0
- package/src/engine/session/instruction_loader.ts +54 -0
- package/src/engine/session/llm.ts +459 -0
- package/src/engine/session/message-error.ts +14 -0
- package/src/engine/session/message-v2.ts +1202 -0
- package/src/engine/session/message.ts +146 -0
- package/src/engine/session/overflow.ts +32 -0
- package/src/engine/session/overflow_check.ts +46 -0
- package/src/engine/session/processor.ts +823 -0
- package/src/engine/session/prompt/anthropic.txt +105 -0
- package/src/engine/session/prompt/beast.txt +147 -0
- package/src/engine/session/prompt/build-switch.txt +5 -0
- package/src/engine/session/prompt/codex.txt +79 -0
- package/src/engine/session/prompt/copilot-gpt-5.txt +143 -0
- package/src/engine/session/prompt/default.txt +105 -0
- package/src/engine/session/prompt/gemini.txt +155 -0
- package/src/engine/session/prompt/gpt.txt +107 -0
- package/src/engine/session/prompt/kimi.txt +95 -0
- package/src/engine/session/prompt/max-steps.txt +16 -0
- package/src/engine/session/prompt/plan-reminder-anthropic.txt +67 -0
- package/src/engine/session/prompt/plan.txt +26 -0
- package/src/engine/session/prompt/trinity.txt +97 -0
- package/src/engine/session/prompt.ts +671 -0
- package/src/engine/session/provider_transform.ts +187 -0
- package/src/engine/session/retry.ts +200 -0
- package/src/engine/session/retry_logic.ts +65 -0
- package/src/engine/session/revert.ts +162 -0
- package/src/engine/session/run-state.ts +153 -0
- package/src/engine/session/schema.ts +26 -0
- package/src/engine/session/session.sql.ts +137 -0
- package/src/engine/session/session.ts +1011 -0
- package/src/engine/session/status.ts +94 -0
- package/src/engine/session/summary.ts +164 -0
- package/src/engine/session/system.ts +84 -0
- package/src/engine/session/system_prompt.ts +65 -0
- package/src/engine/session/todo.ts +81 -0
- package/src/engine/session/tool_registry.ts +162 -0
- package/src/engine/share/session.ts +61 -0
- package/src/engine/share/share-next.ts +376 -0
- package/src/engine/share/share.sql.ts +13 -0
- package/src/engine/shell/shell/shell.ts +215 -0
- package/src/engine/shell/shell.ts +215 -0
- package/src/engine/skill/discovery.ts +116 -0
- package/src/engine/skill/index.ts +336 -0
- package/src/engine/skill/prompt/customize-opencode.md +377 -0
- package/src/engine/skill/skill/discovery.ts +116 -0
- package/src/engine/skill/skill/index.ts +336 -0
- package/src/engine/skill/skill/prompt/customize-opencode.md +377 -0
- package/src/engine/snapshot/index.ts +762 -0
- package/src/engine/snapshot/snapshot/index.ts +762 -0
- package/src/engine/sync/README.md +179 -0
- package/src/engine/sync/event.sql.ts +17 -0
- package/src/engine/sync/index.ts +410 -0
- package/src/engine/sync/schema.ts +11 -0
- package/src/engine/temporary.ts +33 -0
- package/src/engine/tool/apply_patch.ts +313 -0
- package/src/engine/tool/apply_patch.txt +33 -0
- package/src/engine/tool/edit.ts +711 -0
- package/src/engine/tool/edit.txt +10 -0
- package/src/engine/tool/external-directory.ts +49 -0
- package/src/engine/tool/glob.ts +103 -0
- package/src/engine/tool/glob.txt +6 -0
- package/src/engine/tool/grep.ts +156 -0
- package/src/engine/tool/grep.txt +8 -0
- package/src/engine/tool/invalid.ts +21 -0
- package/src/engine/tool/json-schema.ts +164 -0
- package/src/engine/tool/lsp.ts +113 -0
- package/src/engine/tool/lsp.txt +24 -0
- package/src/engine/tool/mcp-websearch.ts +96 -0
- package/src/engine/tool/plan-enter.txt +14 -0
- package/src/engine/tool/plan-exit.txt +13 -0
- package/src/engine/tool/plan.ts +78 -0
- package/src/engine/tool/question.ts +44 -0
- package/src/engine/tool/question.txt +10 -0
- package/src/engine/tool/read.ts +337 -0
- package/src/engine/tool/read.txt +14 -0
- package/src/engine/tool/registry.ts +472 -0
- package/src/engine/tool/repo_clone.ts +80 -0
- package/src/engine/tool/repo_clone.txt +5 -0
- package/src/engine/tool/repo_overview.ts +279 -0
- package/src/engine/tool/repo_overview.txt +4 -0
- package/src/engine/tool/schema.ts +14 -0
- package/src/engine/tool/shell/id.ts +19 -0
- package/src/engine/tool/shell/prompt.ts +295 -0
- package/src/engine/tool/shell/shell.txt +77 -0
- package/src/engine/tool/shell.ts +647 -0
- package/src/engine/tool/skill.ts +75 -0
- package/src/engine/tool/skill.txt +5 -0
- package/src/engine/tool/task.ts +337 -0
- package/src/engine/tool/task.txt +58 -0
- package/src/engine/tool/task_status.ts +179 -0
- package/src/engine/tool/task_status.txt +13 -0
- package/src/engine/tool/todo.ts +57 -0
- package/src/engine/tool/todowrite.txt +167 -0
- package/src/engine/tool/tool/apply_patch.ts +313 -0
- package/src/engine/tool/tool/apply_patch.txt +33 -0
- package/src/engine/tool/tool/edit.ts +711 -0
- package/src/engine/tool/tool/edit.txt +10 -0
- package/src/engine/tool/tool/external-directory.ts +49 -0
- package/src/engine/tool/tool/glob.ts +103 -0
- package/src/engine/tool/tool/glob.txt +6 -0
- package/src/engine/tool/tool/grep.ts +156 -0
- package/src/engine/tool/tool/grep.txt +8 -0
- package/src/engine/tool/tool/invalid.ts +21 -0
- package/src/engine/tool/tool/json-schema.ts +164 -0
- package/src/engine/tool/tool/lsp.ts +113 -0
- package/src/engine/tool/tool/lsp.txt +24 -0
- package/src/engine/tool/tool/mcp-websearch.ts +96 -0
- package/src/engine/tool/tool/plan-enter.txt +14 -0
- package/src/engine/tool/tool/plan-exit.txt +13 -0
- package/src/engine/tool/tool/plan.ts +78 -0
- package/src/engine/tool/tool/question.ts +44 -0
- package/src/engine/tool/tool/question.txt +10 -0
- package/src/engine/tool/tool/read.ts +337 -0
- package/src/engine/tool/tool/read.txt +14 -0
- package/src/engine/tool/tool/registry.ts +472 -0
- package/src/engine/tool/tool/repo_clone.ts +80 -0
- package/src/engine/tool/tool/repo_clone.txt +5 -0
- package/src/engine/tool/tool/repo_overview.ts +279 -0
- package/src/engine/tool/tool/repo_overview.txt +4 -0
- package/src/engine/tool/tool/schema.ts +14 -0
- package/src/engine/tool/tool/shell/id.ts +19 -0
- package/src/engine/tool/tool/shell/prompt.ts +295 -0
- package/src/engine/tool/tool/shell/shell.txt +77 -0
- package/src/engine/tool/tool/shell.ts +647 -0
- package/src/engine/tool/tool/skill.ts +75 -0
- package/src/engine/tool/tool/skill.txt +5 -0
- package/src/engine/tool/tool/task.ts +337 -0
- package/src/engine/tool/tool/task.txt +58 -0
- package/src/engine/tool/tool/task_status.ts +179 -0
- package/src/engine/tool/tool/task_status.txt +13 -0
- package/src/engine/tool/tool/todo.ts +57 -0
- package/src/engine/tool/tool/todowrite.txt +167 -0
- package/src/engine/tool/tool/tool.ts +164 -0
- package/src/engine/tool/tool/truncate.ts +160 -0
- package/src/engine/tool/tool/truncation-dir.ts +4 -0
- package/src/engine/tool/tool/webfetch.ts +192 -0
- package/src/engine/tool/tool/webfetch.txt +13 -0
- package/src/engine/tool/tool/websearch.ts +143 -0
- package/src/engine/tool/tool/websearch.txt +14 -0
- package/src/engine/tool/tool/write.ts +104 -0
- package/src/engine/tool/tool/write.txt +8 -0
- package/src/engine/tool/tool.ts +164 -0
- package/src/engine/tool/truncate.ts +160 -0
- package/src/engine/tool/truncation-dir.ts +4 -0
- package/src/engine/tool/webfetch.ts +192 -0
- package/src/engine/tool/webfetch.txt +13 -0
- package/src/engine/tool/websearch.ts +143 -0
- package/src/engine/tool/websearch.txt +14 -0
- package/src/engine/tool/write.ts +104 -0
- package/src/engine/tool/write.txt +8 -0
- package/src/engine/util/archive.ts +17 -0
- package/src/engine/util/bom.ts +31 -0
- package/src/engine/util/data-url.ts +9 -0
- package/src/engine/util/defer.ts +10 -0
- package/src/engine/util/effect-http-client.ts +11 -0
- package/src/engine/util/error.ts +88 -0
- package/src/engine/util/filesystem.ts +252 -0
- package/src/engine/util/format.ts +20 -0
- package/src/engine/util/iife.ts +3 -0
- package/src/engine/util/lazy.ts +20 -0
- package/src/engine/util/local-context.ts +25 -0
- package/src/engine/util/locale.ts +86 -0
- package/src/engine/util/media.ts +26 -0
- package/src/engine/util/process.ts +176 -0
- package/src/engine/util/queue.ts +32 -0
- package/src/engine/util/record.ts +3 -0
- package/src/engine/util/repository.ts +158 -0
- package/src/engine/util/rpc.ts +66 -0
- package/src/engine/util/signal.ts +12 -0
- package/src/engine/util/timeout.ts +13 -0
- package/src/engine/util/token.ts +7 -0
- package/src/engine/util/util/archive.ts +17 -0
- package/src/engine/util/util/bom.ts +31 -0
- package/src/engine/util/util/data-url.ts +9 -0
- package/src/engine/util/util/defer.ts +10 -0
- package/src/engine/util/util/effect-http-client.ts +11 -0
- package/src/engine/util/util/error.ts +88 -0
- package/src/engine/util/util/filesystem.ts +252 -0
- package/src/engine/util/util/format.ts +20 -0
- package/src/engine/util/util/iife.ts +3 -0
- package/src/engine/util/util/lazy.ts +20 -0
- package/src/engine/util/util/local-context.ts +25 -0
- package/src/engine/util/util/locale.ts +86 -0
- package/src/engine/util/util/media.ts +26 -0
- package/src/engine/util/util/process.ts +176 -0
- package/src/engine/util/util/queue.ts +32 -0
- package/src/engine/util/util/record.ts +3 -0
- package/src/engine/util/util/repository.ts +158 -0
- package/src/engine/util/util/rpc.ts +66 -0
- package/src/engine/util/util/signal.ts +12 -0
- package/src/engine/util/util/timeout.ts +13 -0
- package/src/engine/util/util/token.ts +7 -0
- package/src/engine/util/util/which.ts +14 -0
- package/src/engine/util/util/wildcard.ts +59 -0
- package/src/engine/util/which.ts +14 -0
- package/src/engine/util/wildcard.ts +59 -0
- package/src/engine/worktree/index.ts +621 -0
- package/src/rag_worker.ts +519 -0
- package/src/server.ts +201 -0
- package/src/tui.ts +637 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// Generated by BoneScript compiler. DO NOT EDIT.
|
|
2
|
+
// Implements spec/10 §4 (Telemetry Hooks)
|
|
3
|
+
|
|
4
|
+
interface Counter {
|
|
5
|
+
type: "counter";
|
|
6
|
+
value: number;
|
|
7
|
+
labels: Record<string, string>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface Histogram {
|
|
11
|
+
type: "histogram";
|
|
12
|
+
values: number[];
|
|
13
|
+
labels: Record<string, string>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface Gauge {
|
|
17
|
+
type: "gauge";
|
|
18
|
+
value: number;
|
|
19
|
+
labels: Record<string, string>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type Metric = Counter | Histogram | Gauge;
|
|
23
|
+
|
|
24
|
+
const metrics: Map<string, Metric> = new Map();
|
|
25
|
+
|
|
26
|
+
function key(name: string, labels: Record<string, string>): string {
|
|
27
|
+
const parts = Object.keys(labels).sort().map(k => `${k}="${labels[k]}"`);
|
|
28
|
+
return parts.length > 0 ? `${name}{${parts.join(",")}}` : name;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function counter(name: string, labels: Record<string, string> = {}): void {
|
|
32
|
+
const k = key(name, labels);
|
|
33
|
+
const existing = metrics.get(k);
|
|
34
|
+
if (existing && existing.type === "counter") {
|
|
35
|
+
existing.value++;
|
|
36
|
+
} else {
|
|
37
|
+
metrics.set(k, { type: "counter", value: 1, labels });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function histogram(name: string, value: number, labels: Record<string, string> = {}): void {
|
|
42
|
+
const k = key(name, labels);
|
|
43
|
+
const existing = metrics.get(k);
|
|
44
|
+
if (existing && existing.type === "histogram") {
|
|
45
|
+
existing.values.push(value);
|
|
46
|
+
} else {
|
|
47
|
+
metrics.set(k, { type: "histogram", values: [value], labels });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function gauge(name: string, value: number, labels: Record<string, string> = {}): void {
|
|
52
|
+
const k = key(name, labels);
|
|
53
|
+
metrics.set(k, { type: "gauge", value, labels });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function dump(): string {
|
|
57
|
+
const lines: string[] = [];
|
|
58
|
+
for (const [k, m] of metrics.entries()) {
|
|
59
|
+
if (m.type === "counter" || m.type === "gauge") {
|
|
60
|
+
lines.push(`${k} ${m.value}`);
|
|
61
|
+
} else {
|
|
62
|
+
const sum = m.values.reduce((a, b) => a + b, 0);
|
|
63
|
+
const count = m.values.length;
|
|
64
|
+
const avg = count > 0 ? sum / count : 0;
|
|
65
|
+
lines.push(`${k}_count ${count}`);
|
|
66
|
+
lines.push(`${k}_sum ${sum}`);
|
|
67
|
+
lines.push(`${k}_avg ${avg.toFixed(2)}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return lines.join("\n");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function reset(): void {
|
|
74
|
+
metrics.clear();
|
|
75
|
+
}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
// Generated by BoneScript compiler. DO NOT EDIT.
|
|
2
|
+
require("dotenv").config();
|
|
3
|
+
import { pool } from "./db";
|
|
4
|
+
|
|
5
|
+
async function migrate() {
|
|
6
|
+
console.log("Running migrations...");
|
|
7
|
+
const client = await pool.connect();
|
|
8
|
+
try {
|
|
9
|
+
await client.query(`-- Generated by BoneScript compiler. DO NOT EDIT.
|
|
10
|
+
-- Source: be6ae747864f48c9
|
|
11
|
+
-- Module: WorkspaceStore
|
|
12
|
+
|
|
13
|
+
CREATE TABLE IF NOT EXISTS workspaces (
|
|
14
|
+
id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
15
|
+
project_id UUID NOT NULL,
|
|
16
|
+
root_path VARCHAR NOT NULL,
|
|
17
|
+
git_remote VARCHAR NOT NULL,
|
|
18
|
+
git_branch VARCHAR NOT NULL,
|
|
19
|
+
git_commit VARCHAR NOT NULL,
|
|
20
|
+
is_dirty BOOLEAN NOT NULL,
|
|
21
|
+
file_count BIGINT NOT NULL,
|
|
22
|
+
total_size_bytes BIGINT NOT NULL,
|
|
23
|
+
config JSONB NOT NULL,
|
|
24
|
+
state VARCHAR NOT NULL,
|
|
25
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
26
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
CREATE OR REPLACE FUNCTION update_workspaces_updated_at()
|
|
31
|
+
RETURNS TRIGGER AS \$\$
|
|
32
|
+
BEGIN
|
|
33
|
+
NEW.updated_at = NOW();
|
|
34
|
+
RETURN NEW;
|
|
35
|
+
END;
|
|
36
|
+
\$\$ LANGUAGE plpgsql;
|
|
37
|
+
|
|
38
|
+
CREATE TRIGGER trg_workspaces_updated_at
|
|
39
|
+
BEFORE UPDATE ON workspaces
|
|
40
|
+
FOR EACH ROW
|
|
41
|
+
EXECUTE FUNCTION update_workspaces_updated_at();
|
|
42
|
+
`);
|
|
43
|
+
await client.query(`-- Generated by BoneScript compiler. DO NOT EDIT.
|
|
44
|
+
-- Source: be6ae747864f48c9
|
|
45
|
+
-- Module: CodebaseStore
|
|
46
|
+
|
|
47
|
+
CREATE TABLE IF NOT EXISTS codebases (
|
|
48
|
+
id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
49
|
+
workspace_id UUID NOT NULL,
|
|
50
|
+
project_id UUID NOT NULL,
|
|
51
|
+
primary_language VARCHAR NOT NULL,
|
|
52
|
+
languages JSONB NOT NULL,
|
|
53
|
+
framework VARCHAR NOT NULL,
|
|
54
|
+
build_tool VARCHAR NOT NULL,
|
|
55
|
+
test_framework VARCHAR NOT NULL,
|
|
56
|
+
entry_points JSONB NOT NULL,
|
|
57
|
+
dependencies JSONB NOT NULL,
|
|
58
|
+
analysis_version VARCHAR NOT NULL,
|
|
59
|
+
state VARCHAR NOT NULL,
|
|
60
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
61
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
CREATE OR REPLACE FUNCTION update_codebases_updated_at()
|
|
66
|
+
RETURNS TRIGGER AS \$\$
|
|
67
|
+
BEGIN
|
|
68
|
+
NEW.updated_at = NOW();
|
|
69
|
+
RETURN NEW;
|
|
70
|
+
END;
|
|
71
|
+
\$\$ LANGUAGE plpgsql;
|
|
72
|
+
|
|
73
|
+
CREATE TRIGGER trg_codebases_updated_at
|
|
74
|
+
BEFORE UPDATE ON codebases
|
|
75
|
+
FOR EACH ROW
|
|
76
|
+
EXECUTE FUNCTION update_codebases_updated_at();
|
|
77
|
+
`);
|
|
78
|
+
await client.query(`-- Generated by BoneScript compiler. DO NOT EDIT.
|
|
79
|
+
-- Source: be6ae747864f48c9
|
|
80
|
+
-- Module: SnapshotStore
|
|
81
|
+
|
|
82
|
+
CREATE TABLE IF NOT EXISTS snapshots (
|
|
83
|
+
id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
84
|
+
session_id UUID NOT NULL,
|
|
85
|
+
project_id UUID NOT NULL,
|
|
86
|
+
workspace_id UUID NOT NULL,
|
|
87
|
+
git_hash VARCHAR NOT NULL,
|
|
88
|
+
message_id UUID NOT NULL,
|
|
89
|
+
part_id UUID NOT NULL,
|
|
90
|
+
diff_summary JSONB NOT NULL,
|
|
91
|
+
files_changed BIGINT NOT NULL,
|
|
92
|
+
state VARCHAR NOT NULL,
|
|
93
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
94
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
CREATE OR REPLACE FUNCTION update_snapshots_updated_at()
|
|
99
|
+
RETURNS TRIGGER AS \$\$
|
|
100
|
+
BEGIN
|
|
101
|
+
NEW.updated_at = NOW();
|
|
102
|
+
RETURN NEW;
|
|
103
|
+
END;
|
|
104
|
+
\$\$ LANGUAGE plpgsql;
|
|
105
|
+
|
|
106
|
+
CREATE TRIGGER trg_snapshots_updated_at
|
|
107
|
+
BEFORE UPDATE ON snapshots
|
|
108
|
+
FOR EACH ROW
|
|
109
|
+
EXECUTE FUNCTION update_snapshots_updated_at();
|
|
110
|
+
`);
|
|
111
|
+
await client.query(`-- Generated by BoneScript compiler. DO NOT EDIT.
|
|
112
|
+
-- Source: be6ae747864f48c9
|
|
113
|
+
-- Module: WorkspaceStore
|
|
114
|
+
|
|
115
|
+
CREATE TABLE IF NOT EXISTS workspaces (
|
|
116
|
+
id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
117
|
+
project_id UUID NOT NULL,
|
|
118
|
+
root_path VARCHAR NOT NULL,
|
|
119
|
+
git_remote VARCHAR NOT NULL,
|
|
120
|
+
git_branch VARCHAR NOT NULL,
|
|
121
|
+
git_commit VARCHAR NOT NULL,
|
|
122
|
+
is_dirty BOOLEAN NOT NULL,
|
|
123
|
+
file_count BIGINT NOT NULL,
|
|
124
|
+
total_size_bytes BIGINT NOT NULL,
|
|
125
|
+
config JSONB NOT NULL,
|
|
126
|
+
state VARCHAR NOT NULL,
|
|
127
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
128
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
CREATE OR REPLACE FUNCTION update_workspaces_updated_at()
|
|
133
|
+
RETURNS TRIGGER AS \$\$
|
|
134
|
+
BEGIN
|
|
135
|
+
NEW.updated_at = NOW();
|
|
136
|
+
RETURN NEW;
|
|
137
|
+
END;
|
|
138
|
+
\$\$ LANGUAGE plpgsql;
|
|
139
|
+
|
|
140
|
+
CREATE TRIGGER trg_workspaces_updated_at
|
|
141
|
+
BEFORE UPDATE ON workspaces
|
|
142
|
+
FOR EACH ROW
|
|
143
|
+
EXECUTE FUNCTION update_workspaces_updated_at();
|
|
144
|
+
`);
|
|
145
|
+
await client.query(`-- Generated by BoneScript compiler. DO NOT EDIT.
|
|
146
|
+
-- Source: be6ae747864f48c9
|
|
147
|
+
-- Module: CodebaseStore
|
|
148
|
+
|
|
149
|
+
CREATE TABLE IF NOT EXISTS codebases (
|
|
150
|
+
id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
151
|
+
workspace_id UUID NOT NULL,
|
|
152
|
+
project_id UUID NOT NULL,
|
|
153
|
+
primary_language VARCHAR NOT NULL,
|
|
154
|
+
languages JSONB NOT NULL,
|
|
155
|
+
framework VARCHAR NOT NULL,
|
|
156
|
+
build_tool VARCHAR NOT NULL,
|
|
157
|
+
test_framework VARCHAR NOT NULL,
|
|
158
|
+
entry_points JSONB NOT NULL,
|
|
159
|
+
dependencies JSONB NOT NULL,
|
|
160
|
+
analysis_version VARCHAR NOT NULL,
|
|
161
|
+
state VARCHAR NOT NULL,
|
|
162
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
163
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
CREATE OR REPLACE FUNCTION update_codebases_updated_at()
|
|
168
|
+
RETURNS TRIGGER AS \$\$
|
|
169
|
+
BEGIN
|
|
170
|
+
NEW.updated_at = NOW();
|
|
171
|
+
RETURN NEW;
|
|
172
|
+
END;
|
|
173
|
+
\$\$ LANGUAGE plpgsql;
|
|
174
|
+
|
|
175
|
+
CREATE TRIGGER trg_codebases_updated_at
|
|
176
|
+
BEFORE UPDATE ON codebases
|
|
177
|
+
FOR EACH ROW
|
|
178
|
+
EXECUTE FUNCTION update_codebases_updated_at();
|
|
179
|
+
`);
|
|
180
|
+
await client.query(`-- Generated by BoneScript compiler. DO NOT EDIT.
|
|
181
|
+
-- Source: be6ae747864f48c9
|
|
182
|
+
-- Module: SnapshotStore
|
|
183
|
+
|
|
184
|
+
CREATE TABLE IF NOT EXISTS snapshots (
|
|
185
|
+
id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
|
|
186
|
+
session_id UUID NOT NULL,
|
|
187
|
+
project_id UUID NOT NULL,
|
|
188
|
+
workspace_id UUID NOT NULL,
|
|
189
|
+
git_hash VARCHAR NOT NULL,
|
|
190
|
+
message_id UUID NOT NULL,
|
|
191
|
+
part_id UUID NOT NULL,
|
|
192
|
+
diff_summary JSONB NOT NULL,
|
|
193
|
+
files_changed BIGINT NOT NULL,
|
|
194
|
+
state VARCHAR NOT NULL,
|
|
195
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
196
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
CREATE OR REPLACE FUNCTION update_snapshots_updated_at()
|
|
201
|
+
RETURNS TRIGGER AS \$\$
|
|
202
|
+
BEGIN
|
|
203
|
+
NEW.updated_at = NOW();
|
|
204
|
+
RETURN NEW;
|
|
205
|
+
END;
|
|
206
|
+
\$\$ LANGUAGE plpgsql;
|
|
207
|
+
|
|
208
|
+
CREATE TRIGGER trg_snapshots_updated_at
|
|
209
|
+
BEFORE UPDATE ON snapshots
|
|
210
|
+
FOR EACH ROW
|
|
211
|
+
EXECUTE FUNCTION update_snapshots_updated_at();
|
|
212
|
+
`);
|
|
213
|
+
console.log("Migrations complete.");
|
|
214
|
+
} finally {
|
|
215
|
+
client.release();
|
|
216
|
+
await pool.end();
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
migrate().catch(e => { console.error(e); process.exit(1); });
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// Generated by BoneScript compiler. DO NOT EDIT.
|
|
2
|
+
// Migration diff utility — compares two IR snapshots and produces ALTER statements.
|
|
3
|
+
|
|
4
|
+
import * as fs from "fs";
|
|
5
|
+
|
|
6
|
+
interface Field {
|
|
7
|
+
name: string;
|
|
8
|
+
type: string;
|
|
9
|
+
nullable: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface Model {
|
|
13
|
+
name: string;
|
|
14
|
+
fields: Field[];
|
|
15
|
+
primary_key: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function diffModels(oldModels: Model[], newModels: Model[]): string[] {
|
|
19
|
+
const statements: string[] = [];
|
|
20
|
+
const oldByName = new Map(oldModels.map(m => [m.name, m]));
|
|
21
|
+
const newByName = new Map(newModels.map(m => [m.name, m]));
|
|
22
|
+
|
|
23
|
+
// New tables
|
|
24
|
+
for (const [name, model] of newByName) {
|
|
25
|
+
if (!oldByName.has(name)) {
|
|
26
|
+
const tableName = toSnake(name) + "s";
|
|
27
|
+
statements.push(`-- New table: ${tableName}`);
|
|
28
|
+
statements.push(`-- (Generated by previous migration)`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Removed tables (warn but don't auto-drop)
|
|
33
|
+
for (const [name] of oldByName) {
|
|
34
|
+
if (!newByName.has(name)) {
|
|
35
|
+
const tableName = toSnake(name) + "s";
|
|
36
|
+
statements.push(`-- WARNING: Table ${tableName} no longer in schema. Manual DROP required.`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Modified tables
|
|
41
|
+
for (const [name, newModel] of newByName) {
|
|
42
|
+
const oldModel = oldByName.get(name);
|
|
43
|
+
if (!oldModel) continue;
|
|
44
|
+
|
|
45
|
+
const tableName = toSnake(name) + "s";
|
|
46
|
+
const oldFields = new Map(oldModel.fields.map(f => [f.name, f]));
|
|
47
|
+
const newFields = new Map(newModel.fields.map(f => [f.name, f]));
|
|
48
|
+
|
|
49
|
+
// New columns (backward-compatible)
|
|
50
|
+
for (const [fname, field] of newFields) {
|
|
51
|
+
if (!oldFields.has(fname)) {
|
|
52
|
+
const sqlType = mapType(field.type);
|
|
53
|
+
const nullability = field.nullable ? "" : " NOT NULL DEFAULT (CASE WHEN false THEN NULL ELSE NULL END)";
|
|
54
|
+
statements.push(`ALTER TABLE ${tableName} ADD COLUMN ${fname} ${sqlType}${nullability};`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Removed columns (NOT auto-dropped — backward compat)
|
|
59
|
+
for (const [fname] of oldFields) {
|
|
60
|
+
if (!newFields.has(fname)) {
|
|
61
|
+
statements.push(`-- WARNING: Column ${tableName}.${fname} removed from schema. Run manually: ALTER TABLE ${tableName} DROP COLUMN ${fname};`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Type changes
|
|
66
|
+
for (const [fname, newField] of newFields) {
|
|
67
|
+
const oldField = oldFields.get(fname);
|
|
68
|
+
if (!oldField) continue;
|
|
69
|
+
if (oldField.type !== newField.type) {
|
|
70
|
+
const sqlType = mapType(newField.type);
|
|
71
|
+
statements.push(`ALTER TABLE ${tableName} ALTER COLUMN ${fname} TYPE ${sqlType};`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return statements;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function toSnake(s: string): string {
|
|
80
|
+
return s.replace(/([a-z])([A-Z])/g, "$1_$2").toLowerCase();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function mapType(t: string): string {
|
|
84
|
+
const map: Record<string, string> = {
|
|
85
|
+
string: "VARCHAR", uint: "BIGINT", int: "BIGINT", float: "DOUBLE PRECISION",
|
|
86
|
+
bool: "BOOLEAN", timestamp: "TIMESTAMPTZ", uuid: "UUID", bytes: "BYTEA", json: "JSONB",
|
|
87
|
+
};
|
|
88
|
+
return map[t] || "JSONB";
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (require.main === module) {
|
|
92
|
+
const oldFile = process.argv[2];
|
|
93
|
+
const newFile = process.argv[3];
|
|
94
|
+
if (!oldFile || !newFile) {
|
|
95
|
+
console.error("Usage: node migration-diff.js <old-ir.json> <new-ir.json>");
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
const oldIR = JSON.parse(fs.readFileSync(oldFile, "utf-8"));
|
|
99
|
+
const newIR = JSON.parse(fs.readFileSync(newFile, "utf-8"));
|
|
100
|
+
|
|
101
|
+
const oldModels: Model[] = [];
|
|
102
|
+
const newModels: Model[] = [];
|
|
103
|
+
for (const sys of oldIR) for (const mod of sys.modules) for (const m of mod.models) oldModels.push(m);
|
|
104
|
+
for (const sys of newIR) for (const mod of sys.modules) for (const m of mod.models) newModels.push(m);
|
|
105
|
+
|
|
106
|
+
const diff = diffModels(oldModels, newModels);
|
|
107
|
+
console.log(diff.join("\n"));
|
|
108
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Generated by BoneScript compiler.
|
|
2
|
+
// Notification service — fires on event emissions.
|
|
3
|
+
// Configure NOTIFY_PROVIDER=resend|sendgrid|log (default: log)
|
|
4
|
+
// Set NOTIFY_API_KEY and NOTIFY_FROM_EMAIL in .env
|
|
5
|
+
|
|
6
|
+
import { SystemEvent } from "./events";
|
|
7
|
+
|
|
8
|
+
export type NotifyProvider = "resend" | "sendgrid" | "log";
|
|
9
|
+
|
|
10
|
+
const PROVIDER = (process.env.NOTIFY_PROVIDER || "log") as NotifyProvider;
|
|
11
|
+
const API_KEY = process.env.NOTIFY_API_KEY || "";
|
|
12
|
+
const FROM_EMAIL = process.env.NOTIFY_FROM_EMAIL || "noreply@example.com";
|
|
13
|
+
|
|
14
|
+
export interface NotifyMessage {
|
|
15
|
+
to: string;
|
|
16
|
+
subject: string;
|
|
17
|
+
body: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function sendEmail(msg: NotifyMessage): Promise<void> {
|
|
21
|
+
if (PROVIDER === "log") {
|
|
22
|
+
console.log(`[notify] ${msg.subject} → ${msg.to}`);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (PROVIDER === "resend") {
|
|
26
|
+
const res = await fetch("https://api.resend.com/emails", {
|
|
27
|
+
method: "POST",
|
|
28
|
+
headers: { "Authorization": `Bearer ${API_KEY}`, "Content-Type": "application/json" },
|
|
29
|
+
body: JSON.stringify({ from: FROM_EMAIL, to: msg.to, subject: msg.subject, html: msg.body }),
|
|
30
|
+
});
|
|
31
|
+
if (!res.ok) throw new Error(`Resend error: ${res.status}`);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (PROVIDER === "sendgrid") {
|
|
35
|
+
const res = await fetch("https://api.sendgrid.com/v3/mail/send", {
|
|
36
|
+
method: "POST",
|
|
37
|
+
headers: { "Authorization": `Bearer ${API_KEY}`, "Content-Type": "application/json" },
|
|
38
|
+
body: JSON.stringify({ personalizations: [{ to: [{ email: msg.to }] }], from: { email: FROM_EMAIL }, subject: msg.subject, content: [{ type: "text/html", value: msg.body }] }),
|
|
39
|
+
});
|
|
40
|
+
if (!res.ok) throw new Error(`SendGrid error: ${res.status}`);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Handler for WorkspaceInitialized
|
|
46
|
+
export async function notifyWorkspaceInitialized(event: SystemEvent, recipientEmail: string): Promise<void> {
|
|
47
|
+
await sendEmail({
|
|
48
|
+
to: recipientEmail,
|
|
49
|
+
subject: "WorkspaceInitialized notification",
|
|
50
|
+
body: `<p>Event <strong>WorkspaceInitialized</strong> occurred.</p><pre>${JSON.stringify(event.payload, null, 2)}</pre>`,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Handler for SnapshotCreated
|
|
55
|
+
export async function notifySnapshotCreated(event: SystemEvent, recipientEmail: string): Promise<void> {
|
|
56
|
+
await sendEmail({
|
|
57
|
+
to: recipientEmail,
|
|
58
|
+
subject: "SnapshotCreated notification",
|
|
59
|
+
body: `<p>Event <strong>SnapshotCreated</strong> occurred.</p><pre>${JSON.stringify(event.payload, null, 2)}</pre>`,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function registerNotificationHandlers(eventBus: any): void {
|
|
64
|
+
// TODO: implement recipient lookup per event type
|
|
65
|
+
// eventBus.subscribe("WorkspaceInitialized", async (event: SystemEvent) => {
|
|
66
|
+
// const recipientEmail = await lookupRecipient(event);
|
|
67
|
+
// await notifyWorkspaceInitialized(event, recipientEmail);
|
|
68
|
+
// });
|
|
69
|
+
// eventBus.subscribe("SnapshotCreated", async (event: SystemEvent) => {
|
|
70
|
+
// const recipientEmail = await lookupRecipient(event);
|
|
71
|
+
// await notifySnapshotCreated(event, recipientEmail);
|
|
72
|
+
// });
|
|
73
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Generated by BoneScript compiler. DO NOT EDIT.
|
|
2
|
+
// Service: CodebaseService
|
|
3
|
+
import { Router, Request, Response } from "express";
|
|
4
|
+
import { v4 as uuid } from "uuid";
|
|
5
|
+
import { query, queryOne, execute, pool } from "../db";
|
|
6
|
+
import { eventBus } from "../events";
|
|
7
|
+
import { requireAuth, AuthContext } from "../auth";
|
|
8
|
+
import rateLimit from "express-rate-limit";
|
|
9
|
+
import { logger } from "../logger";
|
|
10
|
+
import { counter } from "../metrics";
|
|
11
|
+
import * as __algorithms from "../algorithms";
|
|
12
|
+
const { shortestPath, topologicalSort, binarySearch, bipartiteMatching, roundRobin, weightedAverage, percentile, rankBy, consistentHash } = __algorithms as any;
|
|
13
|
+
|
|
14
|
+
import { transitionCodebase, CODEBASE_INITIAL } from "../state_machines/codebase";
|
|
15
|
+
|
|
16
|
+
export const codebasesRouter = Router();
|
|
17
|
+
|
|
18
|
+
// CREATE
|
|
19
|
+
codebasesRouter.post("/", requireAuth, async (req: Request, res: Response) => {
|
|
20
|
+
try {
|
|
21
|
+
const id = uuid();
|
|
22
|
+
const { workspace_id, project_id, primary_language, languages, framework, build_tool, test_framework, entry_points, dependencies, analysis_version } = req.body;
|
|
23
|
+
const state = CODEBASE_INITIAL;
|
|
24
|
+
const sql = `INSERT INTO codebases (id, workspace_id, project_id, primary_language, languages, framework, build_tool, test_framework, entry_points, dependencies, analysis_version, state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING *`;
|
|
25
|
+
const rows = await query(sql, [id, workspace_id, project_id, primary_language, languages, framework, build_tool, test_framework, entry_points, dependencies, analysis_version, state]);
|
|
26
|
+
counter("entity.created", { entity: "Codebase" });
|
|
27
|
+
res.status(201).json(rows[0]);
|
|
28
|
+
} catch (e: any) {
|
|
29
|
+
res.status(400).json({ error: { code: "CREATE_FAILED", message: e.message } });
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// READ
|
|
34
|
+
codebasesRouter.get("/:id", requireAuth, async (req: Request, res: Response) => {
|
|
35
|
+
try {
|
|
36
|
+
const row = await queryOne(`SELECT * FROM codebases WHERE id = $1`, [req.params.id]);
|
|
37
|
+
if (!row) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
|
|
38
|
+
res.json(row);
|
|
39
|
+
} catch (e: any) {
|
|
40
|
+
res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// LIST
|
|
45
|
+
codebasesRouter.get("/", requireAuth, async (req: Request, res: Response) => {
|
|
46
|
+
try {
|
|
47
|
+
const page = parseInt(req.query.page as string) || 1;
|
|
48
|
+
const pageSize = Math.min(parseInt(req.query.page_size as string) || 50, 100);
|
|
49
|
+
const offset = (page - 1) * pageSize;
|
|
50
|
+
const rows = await query(`SELECT codebases.*, row_to_json(workspace.*) as workspace FROM codebases LEFT JOIN workspaces workspace ON codebases.workspace_id = workspace.id ORDER BY codebases.created_at DESC LIMIT $1 OFFSET $2`, [pageSize, offset]);
|
|
51
|
+
const [{ count }] = await query(`SELECT COUNT(*) as count FROM codebases`);
|
|
52
|
+
res.json({ items: rows, total: parseInt(count), page, page_size: pageSize });
|
|
53
|
+
} catch (e: any) {
|
|
54
|
+
res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// UPDATE
|
|
59
|
+
codebasesRouter.put("/:id", requireAuth, async (req: Request, res: Response) => {
|
|
60
|
+
const fields = { ...req.body };
|
|
61
|
+
// State machine enforcement
|
|
62
|
+
if (fields.state !== undefined) {
|
|
63
|
+
const current = await queryOne<{ state: string }>(`SELECT state FROM codebases WHERE id = $1`, [req.params.id]);
|
|
64
|
+
if (!current) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
|
|
65
|
+
// Find the trigger for this state transition
|
|
66
|
+
const trigger = `${current.state}_to_${fields.state}`;
|
|
67
|
+
const tr = transitionCodebase(current.state as any, trigger);
|
|
68
|
+
if (!tr.ok) return res.status(422).json({ error: { code: "INVALID_TRANSITION", message: `Cannot transition from ${current.state} to ${fields.state}` } });
|
|
69
|
+
}
|
|
70
|
+
const sets = Object.keys(fields).map((k, i) => `${k} = $${i + 2}`).join(", ");
|
|
71
|
+
const values = Object.values(fields);
|
|
72
|
+
const sql = `UPDATE codebases SET ${sets}, updated_at = NOW() WHERE id = $1 RETURNING *`;
|
|
73
|
+
const rows = await query(sql, [req.params.id, ...values]);
|
|
74
|
+
if (rows.length === 0) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
|
|
75
|
+
res.json(rows[0]);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// DELETE
|
|
79
|
+
codebasesRouter.delete("/:id", requireAuth, async (req: Request, res: Response) => {
|
|
80
|
+
try {
|
|
81
|
+
const count = await execute(`DELETE FROM codebases WHERE id = $1`, [req.params.id]);
|
|
82
|
+
if (count === 0) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
|
|
83
|
+
res.status(204).send();
|
|
84
|
+
} catch (e: any) {
|
|
85
|
+
res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
|
|
86
|
+
}
|
|
87
|
+
});
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// Generated by BoneScript compiler. DO NOT EDIT.
|
|
2
|
+
// Service: SnapshotService
|
|
3
|
+
import { Router, Request, Response } from "express";
|
|
4
|
+
import { v4 as uuid } from "uuid";
|
|
5
|
+
import { query, queryOne, execute, pool } from "../db";
|
|
6
|
+
import { eventBus } from "../events";
|
|
7
|
+
import { requireAuth, AuthContext } from "../auth";
|
|
8
|
+
import rateLimit from "express-rate-limit";
|
|
9
|
+
import { logger } from "../logger";
|
|
10
|
+
import { counter } from "../metrics";
|
|
11
|
+
import * as __algorithms from "../algorithms";
|
|
12
|
+
const { shortestPath, topologicalSort, binarySearch, bipartiteMatching, roundRobin, weightedAverage, percentile, rankBy, consistentHash } = __algorithms as any;
|
|
13
|
+
|
|
14
|
+
import { transitionSnapshot, SNAPSHOT_INITIAL } from "../state_machines/snapshot";
|
|
15
|
+
|
|
16
|
+
export const snapshotsRouter = Router();
|
|
17
|
+
|
|
18
|
+
// CREATE
|
|
19
|
+
snapshotsRouter.post("/", requireAuth, async (req: Request, res: Response) => {
|
|
20
|
+
try {
|
|
21
|
+
const id = uuid();
|
|
22
|
+
const { session_id, project_id, workspace_id, git_hash, message_id, part_id, diff_summary, files_changed } = req.body;
|
|
23
|
+
const state = SNAPSHOT_INITIAL;
|
|
24
|
+
const sql = `INSERT INTO snapshots (id, session_id, project_id, workspace_id, git_hash, message_id, part_id, diff_summary, files_changed, state) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING *`;
|
|
25
|
+
const rows = await query(sql, [id, session_id, project_id, workspace_id, git_hash, message_id, part_id, diff_summary, files_changed, state]);
|
|
26
|
+
counter("entity.created", { entity: "Snapshot" });
|
|
27
|
+
res.status(201).json(rows[0]);
|
|
28
|
+
} catch (e: any) {
|
|
29
|
+
res.status(400).json({ error: { code: "CREATE_FAILED", message: e.message } });
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// READ
|
|
34
|
+
snapshotsRouter.get("/:id", requireAuth, async (req: Request, res: Response) => {
|
|
35
|
+
try {
|
|
36
|
+
const row = await queryOne(`SELECT * FROM snapshots WHERE id = $1`, [req.params.id]);
|
|
37
|
+
if (!row) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
|
|
38
|
+
res.json(row);
|
|
39
|
+
} catch (e: any) {
|
|
40
|
+
res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// LIST
|
|
45
|
+
snapshotsRouter.get("/", requireAuth, async (req: Request, res: Response) => {
|
|
46
|
+
try {
|
|
47
|
+
const page = parseInt(req.query.page as string) || 1;
|
|
48
|
+
const pageSize = Math.min(parseInt(req.query.page_size as string) || 50, 100);
|
|
49
|
+
const offset = (page - 1) * pageSize;
|
|
50
|
+
const rows = await query(`SELECT snapshots.*, row_to_json(workspace.*) as workspace FROM snapshots LEFT JOIN workspaces workspace ON snapshots.workspace_id = workspace.id ORDER BY snapshots.created_at DESC LIMIT $1 OFFSET $2`, [pageSize, offset]);
|
|
51
|
+
const [{ count }] = await query(`SELECT COUNT(*) as count FROM snapshots`);
|
|
52
|
+
res.json({ items: rows, total: parseInt(count), page, page_size: pageSize });
|
|
53
|
+
} catch (e: any) {
|
|
54
|
+
res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// UPDATE
|
|
59
|
+
snapshotsRouter.put("/:id", requireAuth, async (req: Request, res: Response) => {
|
|
60
|
+
const fields = { ...req.body };
|
|
61
|
+
// State machine enforcement
|
|
62
|
+
if (fields.state !== undefined) {
|
|
63
|
+
const current = await queryOne<{ state: string }>(`SELECT state FROM snapshots WHERE id = $1`, [req.params.id]);
|
|
64
|
+
if (!current) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
|
|
65
|
+
// Find the trigger for this state transition
|
|
66
|
+
const trigger = `${current.state}_to_${fields.state}`;
|
|
67
|
+
const tr = transitionSnapshot(current.state as any, trigger);
|
|
68
|
+
if (!tr.ok) return res.status(422).json({ error: { code: "INVALID_TRANSITION", message: `Cannot transition from ${current.state} to ${fields.state}` } });
|
|
69
|
+
}
|
|
70
|
+
const sets = Object.keys(fields).map((k, i) => `${k} = $${i + 2}`).join(", ");
|
|
71
|
+
const values = Object.values(fields);
|
|
72
|
+
const sql = `UPDATE snapshots SET ${sets}, updated_at = NOW() WHERE id = $1 RETURNING *`;
|
|
73
|
+
const rows = await query(sql, [req.params.id, ...values]);
|
|
74
|
+
if (rows.length === 0) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
|
|
75
|
+
res.json(rows[0]);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// DELETE
|
|
79
|
+
snapshotsRouter.delete("/:id", requireAuth, async (req: Request, res: Response) => {
|
|
80
|
+
try {
|
|
81
|
+
const count = await execute(`DELETE FROM snapshots WHERE id = $1`, [req.params.id]);
|
|
82
|
+
if (count === 0) return res.status(404).json({ error: { code: "NOT_FOUND", message: "Not found" } });
|
|
83
|
+
res.status(204).send();
|
|
84
|
+
} catch (e: any) {
|
|
85
|
+
res.status(500).json({ error: { code: "DB_ERROR", message: e.message } });
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// CAPABILITY: revert_to_snapshot [transactional]
|
|
90
|
+
snapshotsRouter.post("/revert-to-snapshot", requireAuth, async (req: Request, res: Response) => {
|
|
91
|
+
const auth: AuthContext = (req as any).auth;
|
|
92
|
+
const __client = await pool.connect();
|
|
93
|
+
try {
|
|
94
|
+
await __client.query("BEGIN");
|
|
95
|
+
// Fetch entities
|
|
96
|
+
const workspace = await queryOne(`SELECT * FROM workspaces WHERE id = $1`, [req.body.workspace_id || req.params.id]);
|
|
97
|
+
if (!workspace) {
|
|
98
|
+
return res.status(404).json({ error: { code: "NOT_FOUND", message: "workspace not found" } });
|
|
99
|
+
}
|
|
100
|
+
const snapshot = await queryOne(`SELECT * FROM snapshots WHERE id = $1`, [req.body.snapshot_id || req.params.id]);
|
|
101
|
+
if (!snapshot) {
|
|
102
|
+
return res.status(404).json({ error: { code: "NOT_FOUND", message: "snapshot not found" } });
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Preconditions
|
|
106
|
+
if (!([["ready", "dirty"]].flat().includes(workspace?.state))) {
|
|
107
|
+
return res.status(422).json({ error: { code: "PRECONDITION_FAILED", message: "workspace.state in [\\\"ready\\\", \\\"dirty\\\"]" } });
|
|
108
|
+
}
|
|
109
|
+
if (!(snapshot?.state === "committed")) {
|
|
110
|
+
return res.status(422).json({ error: { code: "PRECONDITION_FAILED", message: "snapshot.state == \\\"committed\\\"" } });
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Effects (applied in declaration order)
|
|
114
|
+
const __effect_0 = await query(`UPDATE workspaces SET is_dirty = $1, updated_at = NOW() WHERE id = $2 RETURNING *`, [false, req.body.workspace_id || req.params.id]);
|
|
115
|
+
if (!__effect_0 || __effect_0.length === 0) {
|
|
116
|
+
throw new Error("Effect failed: workspace.is_dirty = false");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
res.json({ ok: true, action: "revert_to_snapshot", entity: workspace });
|
|
120
|
+
await __client.query("COMMIT");
|
|
121
|
+
} catch (e: any) {
|
|
122
|
+
await __client.query("ROLLBACK");
|
|
123
|
+
res.status(400).json({ error: { code: "CAPABILITY_FAILED", message: e.message } });
|
|
124
|
+
} finally {
|
|
125
|
+
__client.release();
|
|
126
|
+
}
|
|
127
|
+
});
|