bonecode 1.0.0 → 1.1.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/LICENSE +21 -0
- package/README.md +64 -50
- package/bone/output/agent/.dockerignore +7 -7
- package/bone/output/agent/.env.example +36 -36
- package/bone/output/agent/.github/workflows/ci.yaml +58 -58
- package/bone/output/agent/AgentDomain.bone.map +349 -349
- package/bone/output/agent/AgentDomain.postman_collection.json +957 -957
- package/bone/output/agent/Dockerfile +22 -22
- package/bone/output/agent/README.md +47 -47
- package/bone/output/agent/admin/index.html +739 -739
- package/bone/output/agent/docker-compose.yaml +22 -22
- package/bone/output/agent/k8s/deployment.yaml +75 -75
- package/bone/output/agent/migrations/agent.sql +36 -36
- package/bone/output/agent/migrations/agent_instance.sql +36 -36
- package/bone/output/agent/migrations/audit_log.sql +18 -18
- package/bone/output/agent/migrations/build_step.sql +34 -34
- package/bone/output/agent/migrations/event_outbox.sql +31 -31
- package/bone/output/agent/migrations/plan.sql +30 -30
- package/bone/output/agent/migrations/task.sql +30 -30
- package/bone/output/agent/migrations/tool_call.sql +33 -33
- package/bone/output/agent/openapi.yaml +1116 -1116
- package/bone/output/agent/package.json +35 -35
- package/bone/output/agent/schema.graphql +233 -233
- package/bone/output/agent/sdk/client.ts +231 -231
- package/bone/output/agent/src/algorithms.ts +2 -2
- package/bone/output/agent/src/audit.ts +44 -44
- package/bone/output/agent/src/auth.ts +57 -57
- package/bone/output/agent/src/cron.ts +12 -12
- package/bone/output/agent/src/db.ts +31 -31
- package/bone/output/agent/src/debug.ts +66 -66
- package/bone/output/agent/src/events.ts +243 -243
- package/bone/output/agent/src/extensions.ts +54 -54
- package/bone/output/agent/src/failure_rules.ts +322 -322
- package/bone/output/agent/src/flows.ts +168 -168
- package/bone/output/agent/src/health.ts +43 -43
- package/bone/output/agent/src/index.ts +99 -99
- package/bone/output/agent/src/logger.ts +69 -66
- package/bone/output/agent/src/metrics.ts +75 -75
- package/bone/output/agent/src/migrate.ts +351 -351
- package/bone/output/agent/src/migration_diff.ts +108 -108
- package/bone/output/agent/src/notify.ts +125 -125
- package/bone/output/agent/src/routes/plan.ts +91 -91
- package/bone/output/agent/src/routes/task.ts +105 -105
- package/bone/output/agent/src/routes/tool_call.ts +166 -166
- package/bone/output/agent/src/schemas.ts +384 -384
- package/bone/output/agent/src/state_machines/agent_instance.ts +24 -24
- package/bone/output/agent/src/state_machines/build_step.ts +22 -22
- package/bone/output/agent/src/state_machines/plan.ts +22 -22
- package/bone/output/agent/src/state_machines/task.ts +22 -22
- package/bone/output/agent/src/state_machines/tool_call.ts +22 -22
- package/bone/output/agent/src/tests.ts +361 -361
- package/bone/output/agent/src/websocket.ts +200 -200
- package/bone/output/agent/tsconfig.json +24 -24
- package/bone/output/rag/.dockerignore +7 -7
- package/bone/output/rag/.env.example +36 -36
- package/bone/output/rag/.github/workflows/ci.yaml +58 -58
- package/bone/output/rag/Dockerfile +22 -22
- package/bone/output/rag/RAGDomain.bone.map +286 -286
- package/bone/output/rag/RAGDomain.postman_collection.json +922 -922
- package/bone/output/rag/README.md +47 -47
- package/bone/output/rag/admin/index.html +817 -817
- package/bone/output/rag/docker-compose.yaml +22 -22
- package/bone/output/rag/k8s/deployment.yaml +75 -75
- package/bone/output/rag/migrations/audit_log.sql +18 -18
- package/bone/output/rag/migrations/code_chunk.sql +34 -34
- package/bone/output/rag/migrations/code_file.sql +33 -33
- package/bone/output/rag/migrations/event_outbox.sql +31 -31
- package/bone/output/rag/migrations/indexing_job.sql +33 -33
- package/bone/output/rag/migrations/knowledge_base.sql +35 -35
- package/bone/output/rag/migrations/memory_entry.sql +34 -34
- package/bone/output/rag/openapi.yaml +1097 -1097
- package/bone/output/rag/package.json +35 -35
- package/bone/output/rag/schema.graphql +245 -245
- package/bone/output/rag/sdk/client.ts +234 -234
- package/bone/output/rag/src/algorithms.ts +2 -2
- package/bone/output/rag/src/audit.ts +37 -37
- package/bone/output/rag/src/auth.ts +57 -57
- package/bone/output/rag/src/cron.ts +12 -12
- package/bone/output/rag/src/db.ts +31 -31
- package/bone/output/rag/src/debug.ts +66 -66
- package/bone/output/rag/src/events.ts +243 -243
- package/bone/output/rag/src/extensions.ts +350 -350
- package/bone/output/rag/src/failure_rules.ts +314 -314
- package/bone/output/rag/src/flows.ts +239 -239
- package/bone/output/rag/src/health.ts +43 -43
- package/bone/output/rag/src/index.ts +94 -94
- package/bone/output/rag/src/logger.ts +69 -66
- package/bone/output/rag/src/metrics.ts +75 -75
- package/bone/output/rag/src/migrate.ts +363 -363
- package/bone/output/rag/src/migration_diff.ts +108 -108
- package/bone/output/rag/src/notify.ts +99 -99
- package/bone/output/rag/src/routes/code_chunk.ts +75 -75
- package/bone/output/rag/src/routes/code_file.ts +101 -101
- package/bone/output/rag/src/routes/indexing_job.ts +87 -87
- package/bone/output/rag/src/routes/knowledge_base.ts +230 -230
- package/bone/output/rag/src/routes/memory_entry.ts +87 -87
- package/bone/output/rag/src/schemas.ts +394 -394
- package/bone/output/rag/src/state_machines/code_file.ts +23 -23
- package/bone/output/rag/src/state_machines/indexing_job.ts +22 -22
- package/bone/output/rag/src/state_machines/knowledge_base.ts +23 -23
- package/bone/output/rag/src/state_machines/memory_entry.ts +20 -20
- package/bone/output/rag/src/tests.ts +339 -339
- package/bone/output/rag/tsconfig.json +24 -24
- package/bone/output/session/.dockerignore +7 -7
- package/bone/output/session/.env.example +36 -36
- package/bone/output/session/.github/workflows/ci.yaml +58 -58
- package/bone/output/session/Dockerfile +22 -22
- package/bone/output/session/README.md +47 -47
- package/bone/output/session/SessionDomain.bone.map +349 -349
- package/bone/output/session/SessionDomain.postman_collection.json +957 -957
- package/bone/output/session/admin/index.html +666 -666
- package/bone/output/session/docker-compose.yaml +22 -22
- package/bone/output/session/k8s/deployment.yaml +75 -75
- package/bone/output/session/migrations/audit_log.sql +18 -18
- package/bone/output/session/migrations/event_outbox.sql +31 -31
- package/bone/output/session/migrations/message.sql +31 -31
- package/bone/output/session/migrations/part.sql +28 -28
- package/bone/output/session/migrations/permission.sql +28 -28
- package/bone/output/session/migrations/project.sql +28 -28
- package/bone/output/session/migrations/session.sql +38 -38
- package/bone/output/session/openapi.yaml +1101 -1101
- package/bone/output/session/package.json +35 -35
- package/bone/output/session/schema.graphql +222 -222
- package/bone/output/session/sdk/client.ts +225 -225
- package/bone/output/session/src/algorithms.ts +2 -2
- package/bone/output/session/src/audit.ts +44 -44
- package/bone/output/session/src/auth.ts +57 -57
- package/bone/output/session/src/cron.ts +12 -12
- package/bone/output/session/src/db.ts +31 -31
- package/bone/output/session/src/debug.ts +66 -66
- package/bone/output/session/src/events.ts +270 -270
- package/bone/output/session/src/extensions.ts +215 -215
- package/bone/output/session/src/failure_rules.ts +283 -283
- package/bone/output/session/src/flows.ts +168 -168
- package/bone/output/session/src/health.ts +43 -43
- package/bone/output/session/src/index.ts +99 -99
- package/bone/output/session/src/logger.ts +67 -66
- package/bone/output/session/src/metrics.ts +75 -75
- package/bone/output/session/src/migrate.ts +331 -331
- package/bone/output/session/src/migration_diff.ts +108 -108
- package/bone/output/session/src/notify.ts +112 -112
- package/bone/output/session/src/routes/message.ts +93 -93
- package/bone/output/session/src/routes/part.ts +79 -79
- package/bone/output/session/src/routes/permission.ts +79 -79
- package/bone/output/session/src/routes/project.ts +79 -79
- package/bone/output/session/src/routes/session.ts +294 -294
- package/bone/output/session/src/schemas.ts +357 -357
- package/bone/output/session/src/state_machines/session.ts +23 -23
- package/bone/output/session/src/tests.ts +325 -325
- package/bone/output/session/src/websocket.ts +223 -200
- package/bone/output/session/tsconfig.json +24 -24
- package/bone/output/workspace/.dockerignore +7 -7
- package/bone/output/workspace/.env.example +36 -36
- package/bone/output/workspace/.github/workflows/ci.yaml +58 -58
- package/bone/output/workspace/Dockerfile +22 -22
- package/bone/output/workspace/README.md +45 -45
- package/bone/output/workspace/WorkspaceDomain.bone.map +188 -188
- package/bone/output/workspace/WorkspaceDomain.postman_collection.json +620 -620
- package/bone/output/workspace/admin/index.html +484 -484
- package/bone/output/workspace/docker-compose.yaml +22 -22
- package/bone/output/workspace/k8s/deployment.yaml +75 -75
- package/bone/output/workspace/migrations/audit_log.sql +18 -18
- package/bone/output/workspace/migrations/codebase.sql +34 -34
- package/bone/output/workspace/migrations/event_outbox.sql +31 -31
- package/bone/output/workspace/migrations/snapshot.sql +32 -32
- package/bone/output/workspace/migrations/workspace.sql +33 -33
- package/bone/output/workspace/openapi.yaml +721 -721
- package/bone/output/workspace/package.json +35 -35
- package/bone/output/workspace/schema.graphql +153 -153
- package/bone/output/workspace/sdk/client.ts +155 -155
- package/bone/output/workspace/src/algorithms.ts +2 -2
- package/bone/output/workspace/src/audit.ts +37 -37
- package/bone/output/workspace/src/auth.ts +57 -57
- package/bone/output/workspace/src/cron.ts +12 -12
- package/bone/output/workspace/src/db.ts +31 -31
- package/bone/output/workspace/src/debug.ts +66 -66
- package/bone/output/workspace/src/events.ts +243 -243
- package/bone/output/workspace/src/extensions.ts +44 -44
- package/bone/output/workspace/src/failure_rules.ts +152 -152
- package/bone/output/workspace/src/health.ts +43 -43
- package/bone/output/workspace/src/index.ts +88 -88
- package/bone/output/workspace/src/logger.ts +69 -66
- package/bone/output/workspace/src/metrics.ts +75 -75
- package/bone/output/workspace/src/migrate.ts +219 -219
- package/bone/output/workspace/src/migration_diff.ts +108 -108
- package/bone/output/workspace/src/notify.ts +73 -73
- package/bone/output/workspace/src/routes/codebase.ts +87 -87
- package/bone/output/workspace/src/routes/snapshot.ts +127 -127
- package/bone/output/workspace/src/routes/workspace.ts +190 -190
- package/bone/output/workspace/src/schemas.ts +231 -231
- package/bone/output/workspace/src/state_machines/codebase.ts +21 -21
- package/bone/output/workspace/src/state_machines/snapshot.ts +20 -20
- package/bone/output/workspace/src/state_machines/workspace.ts +21 -21
- package/bone/output/workspace/src/tests.ts +248 -248
- package/bone/output/workspace/tsconfig.json +24 -24
- package/compat/opencode_adapter.ts +94 -17
- package/package.json +15 -2
- package/src/cli.ts +66 -107
- package/src/db_adapter.ts +354 -0
- package/src/engine/account/account.sql.ts +39 -39
- package/src/engine/account/account.ts +456 -456
- package/src/engine/account/repo.ts +166 -166
- package/src/engine/account/schema.ts +99 -99
- package/src/engine/account/url.ts +8 -8
- package/src/engine/acp/README.md +174 -174
- package/src/engine/acp/agent.ts +1968 -1968
- package/src/engine/acp/runtime.ts +22 -22
- package/src/engine/acp/session.ts +122 -122
- package/src/engine/acp/types.ts +24 -24
- package/src/engine/agent/agent.ts +463 -463
- package/src/engine/agent/generate.txt +75 -75
- package/src/engine/agent/prompt/compaction.txt +9 -9
- package/src/engine/agent/prompt/explore.txt +18 -18
- package/src/engine/agent/prompt/scout.txt +36 -36
- package/src/engine/agent/prompt/summary.txt +11 -11
- package/src/engine/agent/prompt/title.txt +44 -44
- package/src/engine/agent/subagent-permissions.ts +34 -34
- package/src/engine/auth/index.ts +96 -96
- package/src/engine/background/background/job.ts +200 -200
- package/src/engine/background/job.ts +200 -200
- package/src/engine/bus/bus-event.ts +45 -45
- package/src/engine/bus/global.ts +22 -22
- package/src/engine/bus/index.ts +203 -203
- package/src/engine/command/command/index.ts +181 -181
- package/src/engine/command/command/template/initialize.txt +66 -66
- package/src/engine/command/command/template/review.txt +101 -101
- package/src/engine/command/index.ts +181 -181
- package/src/engine/command/template/initialize.txt +66 -66
- package/src/engine/command/template/review.txt +101 -101
- package/src/engine/config/agent.ts +172 -172
- package/src/engine/config/attachment.ts +25 -25
- package/src/engine/config/command.ts +62 -62
- package/src/engine/config/config.ts +833 -833
- package/src/engine/config/console-state.ts +14 -14
- package/src/engine/config/entry-name.ts +16 -16
- package/src/engine/config/error.ts +23 -23
- package/src/engine/config/formatter.ts +13 -13
- package/src/engine/config/layout.ts +6 -6
- package/src/engine/config/lsp.ts +43 -43
- package/src/engine/config/managed.ts +71 -71
- package/src/engine/config/markdown.ts +96 -96
- package/src/engine/config/mcp.ts +56 -56
- package/src/engine/config/model-id.ts +5 -5
- package/src/engine/config/parse.ts +79 -79
- package/src/engine/config/paths.ts +45 -45
- package/src/engine/config/permission.ts +58 -58
- package/src/engine/config/plugin.ts +84 -84
- package/src/engine/config/provider.ts +111 -111
- package/src/engine/config/reference.ts +23 -23
- package/src/engine/config/server.ts +19 -19
- package/src/engine/config/skills.ts +14 -14
- package/src/engine/config/variable.ts +90 -90
- package/src/engine/control-plane/adapters/index.ts +41 -41
- package/src/engine/control-plane/adapters/worktree.ts +96 -96
- package/src/engine/control-plane/dev/README.md +19 -19
- package/src/engine/control-plane/dev/debug-workspace-plugin.ts +73 -73
- package/src/engine/control-plane/schema.ts +14 -14
- package/src/engine/control-plane/types.ts +59 -59
- package/src/engine/control-plane/util.ts +39 -39
- package/src/engine/control-plane/workspace-adapter-runtime.ts +51 -51
- package/src/engine/control-plane/workspace-context.ts +26 -26
- package/src/engine/control-plane/workspace.sql.ts +20 -20
- package/src/engine/control-plane/workspace.ts +1072 -1072
- package/src/engine/data-migration.ts +161 -161
- package/src/engine/effect/app-runtime.ts +143 -143
- package/src/engine/effect/bootstrap-runtime.ts +29 -29
- package/src/engine/effect/bridge.ts +84 -84
- package/src/engine/effect/config-service.ts +67 -67
- package/src/engine/effect/instance-ref.ts +11 -11
- package/src/engine/effect/instance-registry.ts +12 -12
- package/src/engine/effect/instance-state.ts +72 -72
- package/src/engine/effect/promise.ts +17 -17
- package/src/engine/effect/run-service.ts +47 -47
- package/src/engine/effect/runner.ts +217 -217
- package/src/engine/effect/runtime-flags.ts +74 -74
- package/src/engine/effect/service-use.ts +38 -38
- package/src/engine/env/index.ts +37 -37
- package/src/engine/event-v2-bridge.ts +89 -89
- package/src/engine/file/file/ignore.ts +81 -81
- package/src/engine/file/file/index.ts +651 -651
- package/src/engine/file/file/protected.ts +59 -59
- package/src/engine/file/file/ripgrep.ts +481 -481
- package/src/engine/file/file/watcher.ts +167 -167
- package/src/engine/file/ignore.ts +81 -81
- package/src/engine/file/index.ts +651 -651
- package/src/engine/file/protected.ts +59 -59
- package/src/engine/file/ripgrep.ts +481 -481
- package/src/engine/file/watcher.ts +167 -167
- package/src/engine/format/format/formatter.ts +404 -404
- package/src/engine/format/format/index.ts +209 -209
- package/src/engine/format/formatter.ts +404 -404
- package/src/engine/format/index.ts +209 -209
- package/src/engine/git/git/index.ts +347 -347
- package/src/engine/git/index.ts +347 -347
- package/src/engine/id/id.ts +80 -80
- package/src/engine/ide/index.ts +70 -70
- package/src/engine/image/image/image.ts +176 -176
- package/src/engine/image/image.ts +176 -176
- package/src/engine/index.ts +251 -251
- package/src/engine/installation/index.ts +327 -327
- package/src/engine/lsp/client.ts +707 -707
- package/src/engine/lsp/diagnostic.ts +29 -29
- package/src/engine/lsp/language.ts +121 -121
- package/src/engine/lsp/launch.ts +21 -21
- package/src/engine/lsp/lsp/client.ts +707 -707
- package/src/engine/lsp/lsp/diagnostic.ts +29 -29
- package/src/engine/lsp/lsp/language.ts +121 -121
- package/src/engine/lsp/lsp/launch.ts +21 -21
- package/src/engine/lsp/lsp/lsp.ts +507 -507
- package/src/engine/lsp/lsp/server.ts +2064 -2064
- package/src/engine/lsp/lsp.ts +507 -507
- package/src/engine/lsp/server.ts +2064 -2064
- package/src/engine/mcp/auth.ts +146 -146
- package/src/engine/mcp/index.ts +958 -958
- package/src/engine/mcp/mcp/auth.ts +146 -146
- package/src/engine/mcp/mcp/index.ts +958 -958
- package/src/engine/mcp/mcp/oauth-callback.ts +232 -232
- package/src/engine/mcp/mcp/oauth-provider.ts +214 -214
- package/src/engine/mcp/oauth-callback.ts +232 -232
- package/src/engine/mcp/oauth-provider.ts +214 -214
- package/src/engine/node.ts +6 -6
- package/src/engine/patch/index.ts +689 -689
- package/src/engine/patch/patch/index.ts +689 -689
- package/src/engine/permission/arity.ts +163 -163
- package/src/engine/permission/evaluate.ts +15 -15
- package/src/engine/permission/index.ts +306 -306
- package/src/engine/permission/permission/arity.ts +163 -163
- package/src/engine/permission/permission/evaluate.ts +15 -15
- package/src/engine/permission/permission/index.ts +306 -306
- package/src/engine/permission/permission/schema.ts +13 -13
- package/src/engine/permission/schema.ts +13 -13
- package/src/engine/plugin/azure.ts +26 -26
- package/src/engine/plugin/cloudflare.ts +76 -76
- package/src/engine/plugin/codex.ts +622 -622
- package/src/engine/plugin/digitalocean.ts +411 -411
- package/src/engine/plugin/github-copilot/copilot.ts +394 -394
- package/src/engine/plugin/github-copilot/models.ts +196 -196
- package/src/engine/plugin/index.ts +295 -295
- package/src/engine/plugin/install.ts +439 -439
- package/src/engine/plugin/loader.ts +216 -216
- package/src/engine/plugin/meta.ts +188 -188
- package/src/engine/plugin/shared.ts +323 -323
- package/src/engine/project/bootstrap-service.ts +9 -9
- package/src/engine/project/bootstrap.ts +75 -75
- package/src/engine/project/instance-context.ts +24 -24
- package/src/engine/project/instance-layer.ts +11 -11
- package/src/engine/project/instance-runtime.ts +16 -16
- package/src/engine/project/instance-store.ts +193 -193
- package/src/engine/project/project.sql.ts +17 -17
- package/src/engine/project/project.ts +537 -537
- package/src/engine/project/schema.ts +13 -13
- package/src/engine/project/vcs.ts +405 -405
- package/src/engine/provider/auth.ts +225 -225
- package/src/engine/provider/error.ts +204 -204
- package/src/engine/provider/model-status.ts +8 -8
- package/src/engine/provider/provider.ts +1843 -1843
- package/src/engine/provider/schema.ts +30 -30
- package/src/engine/provider/transform.ts +1376 -1376
- package/src/engine/pty/index.ts +365 -365
- package/src/engine/pty/input.ts +24 -24
- package/src/engine/pty/pty/index.ts +365 -365
- package/src/engine/pty/pty/input.ts +24 -24
- package/src/engine/pty/pty/pty.bun.ts +26 -26
- package/src/engine/pty/pty/pty.node.ts +27 -27
- package/src/engine/pty/pty/pty.ts +25 -25
- package/src/engine/pty/pty/schema.ts +14 -14
- package/src/engine/pty/pty/ticket.ts +68 -68
- package/src/engine/pty/pty.bun.ts +26 -26
- package/src/engine/pty/pty.node.ts +27 -27
- package/src/engine/pty/pty.ts +25 -25
- package/src/engine/pty/schema.ts +14 -14
- package/src/engine/pty/ticket.ts +68 -68
- package/src/engine/question/index.ts +213 -213
- package/src/engine/question/question/index.ts +213 -213
- package/src/engine/question/question/schema.ts +10 -10
- package/src/engine/question/schema.ts +10 -10
- package/src/engine/reference/reference/reference.ts +241 -241
- package/src/engine/reference/reference/repository-cache.ts +147 -147
- package/src/engine/reference/reference.ts +241 -241
- package/src/engine/reference/repository-cache.ts +147 -147
- package/src/engine/session/compaction.ts +651 -651
- package/src/engine/session/instruction.ts +238 -238
- package/src/engine/session/llm.ts +459 -459
- package/src/engine/session/message-error.ts +14 -14
- package/src/engine/session/message-v2.ts +1202 -1202
- package/src/engine/session/message.ts +146 -146
- package/src/engine/session/overflow.ts +32 -32
- package/src/engine/session/processor.ts +823 -823
- package/src/engine/session/prompt/anthropic.txt +105 -105
- package/src/engine/session/prompt/beast.txt +147 -147
- package/src/engine/session/prompt/build-switch.txt +5 -5
- package/src/engine/session/prompt/codex.txt +79 -79
- package/src/engine/session/prompt/copilot-gpt-5.txt +143 -143
- package/src/engine/session/prompt/default.txt +105 -105
- package/src/engine/session/prompt/gemini.txt +155 -155
- package/src/engine/session/prompt/gpt.txt +107 -107
- package/src/engine/session/prompt/kimi.txt +95 -95
- package/src/engine/session/prompt/max-steps.txt +15 -15
- package/src/engine/session/prompt/plan-reminder-anthropic.txt +67 -67
- package/src/engine/session/prompt/plan.txt +26 -26
- package/src/engine/session/prompt/trinity.txt +97 -97
- package/src/engine/session/prompt.ts +66 -9
- package/src/engine/session/retry.ts +200 -200
- package/src/engine/session/revert.ts +162 -162
- package/src/engine/session/run-state.ts +153 -153
- package/src/engine/session/schema.ts +26 -26
- package/src/engine/session/session.sql.ts +137 -137
- package/src/engine/session/session.ts +1011 -1011
- package/src/engine/session/status.ts +94 -94
- package/src/engine/session/summary.ts +164 -164
- package/src/engine/session/system.ts +84 -84
- package/src/engine/session/todo.ts +81 -81
- package/src/engine/share/session.ts +61 -61
- package/src/engine/share/share-next.ts +376 -376
- package/src/engine/share/share.sql.ts +13 -13
- package/src/engine/shell/shell/shell.ts +215 -215
- package/src/engine/shell/shell.ts +215 -215
- package/src/engine/skill/discovery.ts +116 -116
- package/src/engine/skill/index.ts +336 -336
- package/src/engine/skill/prompt/customize-opencode.md +377 -377
- package/src/engine/skill/skill/discovery.ts +116 -116
- package/src/engine/skill/skill/index.ts +336 -336
- package/src/engine/skill/skill/prompt/customize-opencode.md +377 -377
- package/src/engine/snapshot/index.ts +762 -762
- package/src/engine/snapshot/snapshot/index.ts +762 -762
- package/src/engine/sync/README.md +179 -179
- package/src/engine/sync/event.sql.ts +17 -17
- package/src/engine/sync/index.ts +410 -410
- package/src/engine/sync/schema.ts +11 -11
- package/src/engine/temporary.ts +33 -33
- package/src/engine/tool/apply_patch.ts +313 -313
- package/src/engine/tool/apply_patch.txt +33 -33
- package/src/engine/tool/edit.ts +711 -711
- package/src/engine/tool/edit.txt +10 -10
- package/src/engine/tool/external-directory.ts +49 -49
- package/src/engine/tool/glob.ts +103 -103
- package/src/engine/tool/glob.txt +6 -6
- package/src/engine/tool/grep.ts +156 -156
- package/src/engine/tool/grep.txt +8 -8
- package/src/engine/tool/invalid.ts +21 -21
- package/src/engine/tool/json-schema.ts +164 -164
- package/src/engine/tool/lsp.ts +113 -113
- package/src/engine/tool/lsp.txt +24 -24
- package/src/engine/tool/mcp-websearch.ts +96 -96
- package/src/engine/tool/plan-enter.txt +14 -14
- package/src/engine/tool/plan-exit.txt +13 -13
- package/src/engine/tool/plan.ts +78 -78
- package/src/engine/tool/question.ts +44 -44
- package/src/engine/tool/question.txt +10 -10
- package/src/engine/tool/read.ts +337 -337
- package/src/engine/tool/read.txt +14 -14
- package/src/engine/tool/registry.ts +472 -472
- package/src/engine/tool/repo_clone.ts +80 -80
- package/src/engine/tool/repo_clone.txt +5 -5
- package/src/engine/tool/repo_overview.ts +279 -279
- package/src/engine/tool/repo_overview.txt +4 -4
- package/src/engine/tool/schema.ts +14 -14
- package/src/engine/tool/shell/id.ts +19 -19
- package/src/engine/tool/shell/prompt.ts +295 -295
- package/src/engine/tool/shell/shell.txt +77 -77
- package/src/engine/tool/shell.ts +647 -647
- package/src/engine/tool/skill.ts +75 -75
- package/src/engine/tool/skill.txt +5 -5
- package/src/engine/tool/task.ts +337 -337
- package/src/engine/tool/task.txt +58 -58
- package/src/engine/tool/task_status.ts +179 -179
- package/src/engine/tool/task_status.txt +13 -13
- package/src/engine/tool/todo.ts +57 -57
- package/src/engine/tool/todowrite.txt +167 -167
- package/src/engine/tool/tool/apply_patch.ts +313 -313
- package/src/engine/tool/tool/apply_patch.txt +33 -33
- package/src/engine/tool/tool/edit.ts +711 -711
- package/src/engine/tool/tool/edit.txt +10 -10
- package/src/engine/tool/tool/external-directory.ts +49 -49
- package/src/engine/tool/tool/glob.ts +103 -103
- package/src/engine/tool/tool/glob.txt +6 -6
- package/src/engine/tool/tool/grep.ts +156 -156
- package/src/engine/tool/tool/grep.txt +8 -8
- package/src/engine/tool/tool/invalid.ts +21 -21
- package/src/engine/tool/tool/json-schema.ts +164 -164
- package/src/engine/tool/tool/lsp.ts +113 -113
- package/src/engine/tool/tool/lsp.txt +24 -24
- package/src/engine/tool/tool/mcp-websearch.ts +96 -96
- package/src/engine/tool/tool/plan-enter.txt +14 -14
- package/src/engine/tool/tool/plan-exit.txt +13 -13
- package/src/engine/tool/tool/plan.ts +78 -78
- package/src/engine/tool/tool/question.ts +44 -44
- package/src/engine/tool/tool/question.txt +10 -10
- package/src/engine/tool/tool/read.ts +337 -337
- package/src/engine/tool/tool/read.txt +14 -14
- package/src/engine/tool/tool/registry.ts +472 -472
- package/src/engine/tool/tool/repo_clone.ts +80 -80
- package/src/engine/tool/tool/repo_clone.txt +5 -5
- package/src/engine/tool/tool/repo_overview.ts +279 -279
- package/src/engine/tool/tool/repo_overview.txt +4 -4
- package/src/engine/tool/tool/schema.ts +14 -14
- package/src/engine/tool/tool/shell/id.ts +19 -19
- package/src/engine/tool/tool/shell/prompt.ts +295 -295
- package/src/engine/tool/tool/shell/shell.txt +77 -77
- package/src/engine/tool/tool/shell.ts +647 -647
- package/src/engine/tool/tool/skill.ts +75 -75
- package/src/engine/tool/tool/skill.txt +5 -5
- package/src/engine/tool/tool/task.ts +337 -337
- package/src/engine/tool/tool/task.txt +58 -58
- package/src/engine/tool/tool/task_status.ts +179 -179
- package/src/engine/tool/tool/task_status.txt +13 -13
- package/src/engine/tool/tool/todo.ts +57 -57
- package/src/engine/tool/tool/todowrite.txt +167 -167
- package/src/engine/tool/tool/tool.ts +164 -164
- package/src/engine/tool/tool/truncate.ts +160 -160
- package/src/engine/tool/tool/truncation-dir.ts +4 -4
- package/src/engine/tool/tool/webfetch.ts +192 -192
- package/src/engine/tool/tool/webfetch.txt +13 -13
- package/src/engine/tool/tool/websearch.ts +143 -143
- package/src/engine/tool/tool/websearch.txt +14 -14
- package/src/engine/tool/tool/write.ts +104 -104
- package/src/engine/tool/tool/write.txt +8 -8
- package/src/engine/tool/tool.ts +164 -164
- package/src/engine/tool/truncate.ts +160 -160
- package/src/engine/tool/truncation-dir.ts +4 -4
- package/src/engine/tool/webfetch.ts +192 -192
- package/src/engine/tool/webfetch.txt +13 -13
- package/src/engine/tool/websearch.ts +143 -143
- package/src/engine/tool/websearch.txt +14 -14
- package/src/engine/tool/write.ts +104 -104
- package/src/engine/tool/write.txt +8 -8
- package/src/engine/util/archive.ts +17 -17
- package/src/engine/util/bom.ts +31 -31
- package/src/engine/util/data-url.ts +9 -9
- package/src/engine/util/defer.ts +10 -10
- package/src/engine/util/effect-http-client.ts +11 -11
- package/src/engine/util/error.ts +88 -88
- package/src/engine/util/filesystem.ts +252 -252
- package/src/engine/util/format.ts +20 -20
- package/src/engine/util/iife.ts +3 -3
- package/src/engine/util/lazy.ts +20 -20
- package/src/engine/util/local-context.ts +25 -25
- package/src/engine/util/locale.ts +86 -86
- package/src/engine/util/media.ts +26 -26
- package/src/engine/util/process.ts +176 -176
- package/src/engine/util/queue.ts +32 -32
- package/src/engine/util/record.ts +3 -3
- package/src/engine/util/repository.ts +158 -158
- package/src/engine/util/rpc.ts +66 -66
- package/src/engine/util/signal.ts +12 -12
- package/src/engine/util/timeout.ts +13 -13
- package/src/engine/util/token.ts +7 -7
- package/src/engine/util/util/archive.ts +17 -17
- package/src/engine/util/util/bom.ts +31 -31
- package/src/engine/util/util/data-url.ts +9 -9
- package/src/engine/util/util/defer.ts +10 -10
- package/src/engine/util/util/effect-http-client.ts +11 -11
- package/src/engine/util/util/error.ts +88 -88
- package/src/engine/util/util/filesystem.ts +252 -252
- package/src/engine/util/util/format.ts +20 -20
- package/src/engine/util/util/iife.ts +3 -3
- package/src/engine/util/util/lazy.ts +20 -20
- package/src/engine/util/util/local-context.ts +25 -25
- package/src/engine/util/util/locale.ts +86 -86
- package/src/engine/util/util/media.ts +26 -26
- package/src/engine/util/util/process.ts +176 -176
- package/src/engine/util/util/queue.ts +32 -32
- package/src/engine/util/util/record.ts +3 -3
- package/src/engine/util/util/repository.ts +158 -158
- package/src/engine/util/util/rpc.ts +66 -66
- package/src/engine/util/util/signal.ts +12 -12
- package/src/engine/util/util/timeout.ts +13 -13
- package/src/engine/util/util/token.ts +7 -7
- package/src/engine/util/util/which.ts +14 -14
- package/src/engine/util/util/wildcard.ts +59 -59
- package/src/engine/util/which.ts +14 -14
- package/src/engine/util/wildcard.ts +59 -59
- package/src/engine/worktree/index.ts +621 -621
- package/src/server.ts +121 -158
- package/src/tui.ts +485 -502
|
@@ -1,73 +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
|
-
}
|
|
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
|
+
}
|
|
@@ -1,87 +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
|
-
});
|
|
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
|
+
});
|
|
@@ -1,127 +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
|
-
});
|
|
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
|
+
});
|