@plurnk/plurnk-service 1.3.12 → 1.5.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/.env.defaults +95 -91
- package/INSTALL.md +54 -28
- package/README.md +25 -10
- package/SPEC.md +2426 -942
- package/dist/Paths.d.ts +4 -1
- package/dist/Paths.d.ts.map +1 -1
- package/dist/Paths.js +24 -23
- package/dist/Paths.js.map +1 -1
- package/dist/build-info.json +1 -1
- package/dist/content/edit-receipt.d.ts +13 -28
- package/dist/content/edit-receipt.d.ts.map +1 -1
- package/dist/content/edit-receipt.js +285 -104
- package/dist/content/edit-receipt.js.map +1 -1
- package/dist/content/edited-span.d.ts.map +1 -1
- package/dist/content/edited-span.js +2 -5
- package/dist/content/edited-span.js.map +1 -1
- package/dist/content/index.d.ts +4 -3
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +2 -1
- package/dist/content/index.js.map +1 -1
- package/dist/content/line-marker.d.ts +10 -9
- package/dist/content/line-marker.d.ts.map +1 -1
- package/dist/content/line-marker.js +8 -11
- package/dist/content/line-marker.js.map +1 -1
- package/dist/content/matcher.d.ts +15 -26
- package/dist/content/matcher.d.ts.map +1 -1
- package/dist/content/matcher.js +77 -107
- package/dist/content/matcher.js.map +1 -1
- package/dist/content/mimetype-binary.d.ts +2 -2
- package/dist/content/mimetype-binary.d.ts.map +1 -1
- package/dist/content/mimetype-binary.js +10 -10
- package/dist/content/mimetype-binary.js.map +1 -1
- package/dist/content/path-mimetype.js +3 -3
- package/dist/content/path-mimetype.js.map +1 -1
- package/dist/content/read-projector.d.ts +14 -0
- package/dist/content/read-projector.d.ts.map +1 -0
- package/dist/content/read-projector.js +86 -0
- package/dist/content/read-projector.js.map +1 -0
- package/dist/content/read-resolve.d.ts +6 -7
- package/dist/content/read-resolve.d.ts.map +1 -1
- package/dist/content/read-resolve.js +36 -59
- package/dist/content/read-resolve.js.map +1 -1
- package/dist/core/BranchReceipt.d.ts +6 -0
- package/dist/core/BranchReceipt.d.ts.map +1 -0
- package/dist/core/BranchReceipt.js +24 -0
- package/dist/core/BranchReceipt.js.map +1 -0
- package/dist/core/BudgetOverflow.d.ts +20 -0
- package/dist/core/BudgetOverflow.d.ts.map +1 -0
- package/dist/core/BudgetOverflow.js +49 -0
- package/dist/core/BudgetOverflow.js.map +1 -0
- package/dist/core/BudgetReadout.d.ts +8 -0
- package/dist/core/BudgetReadout.d.ts.map +1 -0
- package/dist/core/BudgetReadout.js +79 -0
- package/dist/core/BudgetReadout.js.map +1 -0
- package/dist/core/ChannelWrite.d.ts +31 -9
- package/dist/core/ChannelWrite.d.ts.map +1 -1
- package/dist/core/ChannelWrite.js +30 -23
- package/dist/core/ChannelWrite.js.map +1 -1
- package/dist/core/ChannelWrite.sql +14 -12
- package/dist/core/CoreSchemeServices.d.ts +18 -4
- package/dist/core/CoreSchemeServices.d.ts.map +1 -1
- package/dist/core/CoreSchemeServices.js +7 -1
- package/dist/core/CoreSchemeServices.js.map +1 -1
- package/dist/core/Dispatcher.d.ts +26 -21
- package/dist/core/Dispatcher.d.ts.map +1 -1
- package/dist/core/Dispatcher.js +1626 -671
- package/dist/core/Dispatcher.js.map +1 -1
- package/dist/core/DurableStatement.d.ts +6 -0
- package/dist/core/DurableStatement.d.ts.map +1 -0
- package/dist/core/DurableStatement.js +51 -0
- package/dist/core/DurableStatement.js.map +1 -0
- package/dist/core/Engine.d.ts +64 -29
- package/dist/core/Engine.d.ts.map +1 -1
- package/dist/core/Engine.js +1348 -835
- package/dist/core/Engine.js.map +1 -1
- package/dist/core/Engine.sql +329 -234
- package/dist/core/EnvFlags.js +1 -1
- package/dist/core/EnvFlags.js.map +1 -1
- package/dist/core/ErrorDetail.d.ts +6 -0
- package/dist/core/ErrorDetail.d.ts.map +1 -0
- package/dist/core/ErrorDetail.js +20 -0
- package/dist/core/ErrorDetail.js.map +1 -0
- package/dist/core/ExecutorRegistry.d.ts +14 -3
- package/dist/core/ExecutorRegistry.d.ts.map +1 -1
- package/dist/core/ExecutorRegistry.js +56 -30
- package/dist/core/ExecutorRegistry.js.map +1 -1
- package/dist/core/GitBranch.d.ts +20 -0
- package/dist/core/GitBranch.d.ts.map +1 -0
- package/dist/core/GitBranch.js +110 -0
- package/dist/core/GitBranch.js.map +1 -0
- package/dist/core/JournalTurn.d.ts +9 -0
- package/dist/core/JournalTurn.d.ts.map +1 -0
- package/dist/core/JournalTurn.js +14 -0
- package/dist/core/JournalTurn.js.map +1 -0
- package/dist/core/JournalTurn.sql +10 -0
- package/dist/core/LogBody.d.ts +18 -0
- package/dist/core/LogBody.d.ts.map +1 -0
- package/dist/core/LogBody.js +180 -0
- package/dist/core/LogBody.js.map +1 -0
- package/dist/core/LoopFlagsReader.d.ts +7 -0
- package/dist/core/LoopFlagsReader.d.ts.map +1 -0
- package/dist/core/LoopFlagsReader.js +33 -0
- package/dist/core/LoopFlagsReader.js.map +1 -0
- package/dist/core/LoopLifecycle.d.ts +8 -2
- package/dist/core/LoopLifecycle.d.ts.map +1 -1
- package/dist/core/LoopLifecycle.js +54 -11
- package/dist/core/LoopLifecycle.js.map +1 -1
- package/dist/core/LoopLifecycle.sql +10 -7
- package/dist/core/NoticeChannel.d.ts +13 -0
- package/dist/core/NoticeChannel.d.ts.map +1 -0
- package/dist/core/NoticeChannel.js +40 -0
- package/dist/core/NoticeChannel.js.map +1 -0
- package/dist/core/Owner.d.ts +0 -1
- package/dist/core/Owner.d.ts.map +1 -1
- package/dist/core/Owner.js +2 -5
- package/dist/core/Owner.js.map +1 -1
- package/dist/core/PacketBuilder.d.ts +27 -25
- package/dist/core/PacketBuilder.d.ts.map +1 -1
- package/dist/core/PacketBuilder.js +321 -383
- package/dist/core/PacketBuilder.js.map +1 -1
- package/dist/core/ProblemLog.d.ts +26 -0
- package/dist/core/ProblemLog.d.ts.map +1 -0
- package/dist/core/ProblemLog.js +58 -0
- package/dist/core/ProblemLog.js.map +1 -0
- package/dist/core/ProposalLifecycle.d.ts +15 -21
- package/dist/core/ProposalLifecycle.d.ts.map +1 -1
- package/dist/core/ProposalLifecycle.js +291 -78
- package/dist/core/ProposalLifecycle.js.map +1 -1
- package/dist/core/ProviderInstantiate.d.ts.map +1 -1
- package/dist/core/ProviderInstantiate.js +51 -48
- package/dist/core/ProviderInstantiate.js.map +1 -1
- package/dist/core/SchemeRegistry.d.ts +14 -8
- package/dist/core/SchemeRegistry.d.ts.map +1 -1
- package/dist/core/SchemeRegistry.js +189 -114
- package/dist/core/SchemeRegistry.js.map +1 -1
- package/dist/core/ServiceTeardown.d.ts +11 -0
- package/dist/core/ServiceTeardown.d.ts.map +1 -0
- package/dist/core/ServiceTeardown.js +70 -0
- package/dist/core/ServiceTeardown.js.map +1 -0
- package/dist/core/StoredPacket.d.ts +29 -0
- package/dist/core/StoredPacket.d.ts.map +1 -0
- package/dist/core/StoredPacket.js +147 -0
- package/dist/core/StoredPacket.js.map +1 -0
- package/dist/core/StrikeRail.d.ts +6 -3
- package/dist/core/StrikeRail.d.ts.map +1 -1
- package/dist/core/StrikeRail.js +27 -56
- package/dist/core/StrikeRail.js.map +1 -1
- package/dist/core/TerminalResult.d.ts +16 -0
- package/dist/core/TerminalResult.d.ts.map +1 -0
- package/dist/core/TerminalResult.js +49 -0
- package/dist/core/TerminalResult.js.map +1 -0
- package/dist/core/WorkerControlAddress.d.ts +17 -0
- package/dist/core/WorkerControlAddress.d.ts.map +1 -0
- package/dist/core/WorkerControlAddress.js +44 -0
- package/dist/core/WorkerControlAddress.js.map +1 -0
- package/dist/core/WorkerName.d.ts +31 -0
- package/dist/core/WorkerName.d.ts.map +1 -0
- package/dist/core/WorkerName.js +95 -0
- package/dist/core/WorkerName.js.map +1 -0
- package/dist/core/WorkerName.sql +36 -0
- package/dist/core/WorkspaceGate.d.ts +14 -0
- package/dist/core/WorkspaceGate.d.ts.map +1 -0
- package/dist/core/WorkspaceGate.js +155 -0
- package/dist/core/WorkspaceGate.js.map +1 -0
- package/dist/core/caps/CapsResolve.d.ts +5 -1
- package/dist/core/caps/CapsResolve.d.ts.map +1 -1
- package/dist/core/caps/CapsResolve.js +8 -4
- package/dist/core/caps/CapsResolve.js.map +1 -1
- package/dist/core/caps/DbChannelCaps.d.ts +5 -11
- package/dist/core/caps/DbChannelCaps.d.ts.map +1 -1
- package/dist/core/caps/DbChannelCaps.js +30 -12
- package/dist/core/caps/DbChannelCaps.js.map +1 -1
- package/dist/core/caps/DbEntryCaps.d.ts +5 -14
- package/dist/core/caps/DbEntryCaps.d.ts.map +1 -1
- package/dist/core/caps/DbEntryCaps.js +27 -8
- package/dist/core/caps/DbEntryCaps.js.map +1 -1
- package/dist/core/caps/DbNotifyCaps.d.ts +1 -1
- package/dist/core/caps/DbNotifyCaps.d.ts.map +1 -1
- package/dist/core/caps/DbNotifyCaps.js +18 -15
- package/dist/core/caps/DbNotifyCaps.js.map +1 -1
- package/dist/core/caps/DbProjectionCaps.d.ts +5 -5
- package/dist/core/caps/DbProjectionCaps.d.ts.map +1 -1
- package/dist/core/caps/DbProjectionCaps.js +21 -4
- package/dist/core/caps/DbProjectionCaps.js.map +1 -1
- package/dist/core/caps/DbSubscriptionCaps.d.ts +4 -6
- package/dist/core/caps/DbSubscriptionCaps.d.ts.map +1 -1
- package/dist/core/caps/DbSubscriptionCaps.js +75 -66
- package/dist/core/caps/DbSubscriptionCaps.js.map +1 -1
- package/dist/core/caps/DbTagCaps.d.ts +5 -12
- package/dist/core/caps/DbTagCaps.d.ts.map +1 -1
- package/dist/core/caps/DbTagCaps.js +20 -11
- package/dist/core/caps/DbTagCaps.js.map +1 -1
- package/dist/core/caps/SchemeCtxImpl.d.ts +6 -1
- package/dist/core/caps/SchemeCtxImpl.d.ts.map +1 -1
- package/dist/core/caps/SchemeCtxImpl.js +6 -6
- package/dist/core/caps/SchemeCtxImpl.js.map +1 -1
- package/dist/core/content-hash.js +1 -1
- package/dist/core/content-hash.js.map +1 -1
- package/dist/core/env-defaults.d.ts.map +1 -1
- package/dist/core/env-defaults.js.map +1 -1
- package/dist/core/fork.d.ts.map +1 -1
- package/dist/core/fork.js +55 -30
- package/dist/core/fork.js.map +1 -1
- package/dist/core/fork.sql +43 -29
- package/dist/core/git-env.d.ts +2 -0
- package/dist/core/git-env.d.ts.map +1 -1
- package/dist/core/git-env.js +13 -18
- package/dist/core/git-env.js.map +1 -1
- package/dist/core/git-iso.d.ts +3 -2
- package/dist/core/git-iso.d.ts.map +1 -1
- package/dist/core/git-iso.js +36 -27
- package/dist/core/git-iso.js.map +1 -1
- package/dist/core/git-membership.d.ts +2 -1
- package/dist/core/git-membership.d.ts.map +1 -1
- package/dist/core/git-membership.js +276 -162
- package/dist/core/git-membership.js.map +1 -1
- package/dist/core/git-state.d.ts +8 -1
- package/dist/core/git-state.d.ts.map +1 -1
- package/dist/core/git-state.js +44 -26
- package/dist/core/git-state.js.map +1 -1
- package/dist/core/namespace.d.ts +1 -0
- package/dist/core/namespace.d.ts.map +1 -1
- package/dist/core/namespace.js +20 -0
- package/dist/core/namespace.js.map +1 -1
- package/dist/core/optimistic-settlement.d.ts +2 -0
- package/dist/core/optimistic-settlement.d.ts.map +1 -0
- package/dist/core/optimistic-settlement.js +14 -0
- package/dist/core/optimistic-settlement.js.map +1 -0
- package/dist/core/owner.sql +1 -1
- package/dist/core/packet-inject.d.ts.map +1 -1
- package/dist/core/packet-inject.js +7 -11
- package/dist/core/packet-inject.js.map +1 -1
- package/dist/core/packet-wire.d.ts +3 -21
- package/dist/core/packet-wire.d.ts.map +1 -1
- package/dist/core/packet-wire.js +305 -385
- package/dist/core/packet-wire.js.map +1 -1
- package/dist/core/plurnk-uri.d.ts +12 -1
- package/dist/core/plurnk-uri.d.ts.map +1 -1
- package/dist/core/plurnk-uri.js +49 -29
- package/dist/core/plurnk-uri.js.map +1 -1
- package/dist/core/results.d.ts +18 -5
- package/dist/core/results.d.ts.map +1 -1
- package/dist/core/results.js +33 -18
- package/dist/core/results.js.map +1 -1
- package/dist/core/ruler_count.d.ts +4 -0
- package/dist/core/ruler_count.d.ts.map +1 -0
- package/dist/core/ruler_count.js +7 -0
- package/dist/core/ruler_count.js.map +1 -0
- package/dist/core/scheme-types.d.ts +3 -17
- package/dist/core/scheme-types.d.ts.map +1 -1
- package/dist/core/scheme-types.js.map +1 -1
- package/dist/core/search-gate.d.ts.map +1 -1
- package/dist/core/search-gate.js +3 -11
- package/dist/core/search-gate.js.map +1 -1
- package/dist/core/teaching-corpus.d.ts +6 -0
- package/dist/core/teaching-corpus.d.ts.map +1 -0
- package/dist/core/teaching-corpus.js +23 -0
- package/dist/core/teaching-corpus.js.map +1 -0
- package/dist/core/teaching.d.ts +0 -1
- package/dist/core/teaching.d.ts.map +1 -1
- package/dist/core/teaching.js +2 -8
- package/dist/core/teaching.js.map +1 -1
- package/dist/core/token-ruler.d.ts.map +1 -1
- package/dist/core/token-ruler.js +3 -16
- package/dist/core/token-ruler.js.map +1 -1
- package/dist/core/turn-scheduler.d.ts +1 -1
- package/dist/core/turn-scheduler.d.ts.map +1 -1
- package/dist/core/turn-scheduler.js +1 -1
- package/dist/core/turn-scheduler.js.map +1 -1
- package/dist/core/worker-cap.d.ts +2 -4
- package/dist/core/worker-cap.d.ts.map +1 -1
- package/dist/core/worker-cap.js +13 -4
- package/dist/core/worker-cap.js.map +1 -1
- package/dist/core/{run-ops.sql → worker-ops.sql} +14 -14
- package/dist/core/workspace-settings.d.ts.map +1 -1
- package/dist/core/workspace-settings.js +17 -9
- package/dist/core/workspace-settings.js.map +1 -1
- package/dist/digest/Digest.d.ts +2 -1
- package/dist/digest/Digest.d.ts.map +1 -1
- package/dist/digest/Digest.js +510 -149
- package/dist/digest/Digest.js.map +1 -1
- package/dist/digest/digest.sql +23 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -5
- package/dist/index.js.map +1 -1
- package/dist/observe/api.d.ts +6 -0
- package/dist/observe/api.d.ts.map +1 -0
- package/dist/observe/api.js +11 -0
- package/dist/observe/api.js.map +1 -0
- package/dist/observe/init.d.ts +7 -0
- package/dist/observe/init.d.ts.map +1 -0
- package/dist/observe/init.js +159 -0
- package/dist/observe/init.js.map +1 -0
- package/dist/observe/metrics.d.ts +6 -0
- package/dist/observe/metrics.d.ts.map +1 -0
- package/dist/observe/metrics.js +15 -0
- package/dist/observe/metrics.js.map +1 -0
- package/dist/observe/spans.d.ts +4 -0
- package/dist/observe/spans.d.ts.map +1 -0
- package/dist/observe/spans.js +51 -0
- package/dist/observe/spans.js.map +1 -0
- package/dist/schemes/EffectPolicy.d.ts +1 -0
- package/dist/schemes/EffectPolicy.d.ts.map +1 -1
- package/dist/schemes/EffectPolicy.js +5 -2
- package/dist/schemes/EffectPolicy.js.map +1 -1
- package/dist/schemes/Exec.d.ts +9 -14
- package/dist/schemes/Exec.d.ts.map +1 -1
- package/dist/schemes/Exec.js +402 -262
- package/dist/schemes/Exec.js.map +1 -1
- package/dist/schemes/ExecOutputScheme.d.ts +9 -9
- package/dist/schemes/ExecOutputScheme.d.ts.map +1 -1
- package/dist/schemes/ExecOutputScheme.js +49 -18
- package/dist/schemes/ExecOutputScheme.js.map +1 -1
- package/dist/schemes/File.d.ts +7 -13
- package/dist/schemes/File.d.ts.map +1 -1
- package/dist/schemes/File.js +280 -151
- package/dist/schemes/File.js.map +1 -1
- package/dist/schemes/Log.d.ts +8 -12
- package/dist/schemes/Log.d.ts.map +1 -1
- package/dist/schemes/Log.js +402 -233
- package/dist/schemes/Log.js.map +1 -1
- package/dist/schemes/Log.sql +71 -32
- package/dist/schemes/Prompt.d.ts +3 -3
- package/dist/schemes/Prompt.d.ts.map +1 -1
- package/dist/schemes/Prompt.js +10 -10
- package/dist/schemes/Prompt.js.map +1 -1
- package/dist/schemes/Skill.d.ts +2 -3
- package/dist/schemes/Skill.d.ts.map +1 -1
- package/dist/schemes/Skill.js +2 -6
- package/dist/schemes/Skill.js.map +1 -1
- package/dist/schemes/Worker.d.ts +11 -19
- package/dist/schemes/Worker.d.ts.map +1 -1
- package/dist/schemes/Worker.js +210 -89
- package/dist/schemes/Worker.js.map +1 -1
- package/dist/schemes/_entry-chunk.d.ts.map +1 -1
- package/dist/schemes/_entry-chunk.js +12 -5
- package/dist/schemes/_entry-chunk.js.map +1 -1
- package/dist/schemes/_entry-crud.d.ts +11 -9
- package/dist/schemes/_entry-crud.d.ts.map +1 -1
- package/dist/schemes/_entry-crud.js +72 -13
- package/dist/schemes/_entry-crud.js.map +1 -1
- package/dist/schemes/_entry-crud.sql +28 -10
- package/dist/schemes/_entry-find.d.ts +49 -18
- package/dist/schemes/_entry-find.d.ts.map +1 -1
- package/dist/schemes/_entry-find.js +348 -195
- package/dist/schemes/_entry-find.js.map +1 -1
- package/dist/schemes/_entry-find.sql +20 -8
- package/dist/schemes/_entry-graph.d.ts +4 -2
- package/dist/schemes/_entry-graph.d.ts.map +1 -1
- package/dist/schemes/_entry-graph.js +55 -31
- package/dist/schemes/_entry-graph.js.map +1 -1
- package/dist/schemes/_entry-graph.sql +37 -22
- package/dist/schemes/_entry-manifest.d.ts +10 -15
- package/dist/schemes/_entry-manifest.d.ts.map +1 -1
- package/dist/schemes/_entry-manifest.js +50 -268
- package/dist/schemes/_entry-manifest.js.map +1 -1
- package/dist/schemes/_entry-ops.d.ts +14 -15
- package/dist/schemes/_entry-ops.d.ts.map +1 -1
- package/dist/schemes/_entry-ops.js +121 -110
- package/dist/schemes/_entry-ops.js.map +1 -1
- package/dist/schemes/_entry-ops.sql +2 -3
- package/dist/schemes/_entry-semantic.d.ts +22 -9
- package/dist/schemes/_entry-semantic.d.ts.map +1 -1
- package/dist/schemes/_entry-semantic.js +127 -67
- package/dist/schemes/_entry-semantic.js.map +1 -1
- package/dist/schemes/_entry-semantic.sql +63 -45
- package/dist/schemes/_entry-send.d.ts +3 -4
- package/dist/schemes/_entry-send.d.ts.map +1 -1
- package/dist/schemes/_entry-send.js +48 -23
- package/dist/schemes/_entry-send.js.map +1 -1
- package/dist/schemes/_path-scope.d.ts +23 -0
- package/dist/schemes/_path-scope.d.ts.map +1 -0
- package/dist/schemes/_path-scope.js +61 -0
- package/dist/schemes/_path-scope.js.map +1 -0
- package/dist/schemes/_search-candidate.d.ts +20 -0
- package/dist/schemes/_search-candidate.d.ts.map +1 -0
- package/dist/schemes/_search-candidate.js +19 -0
- package/dist/schemes/_search-candidate.js.map +1 -0
- package/dist/schemes/_search-exclusion.d.ts +7 -0
- package/dist/schemes/_search-exclusion.d.ts.map +1 -0
- package/dist/schemes/_search-exclusion.js +23 -0
- package/dist/schemes/_search-exclusion.js.map +1 -0
- package/dist/schemes/_search-index.d.ts +6 -0
- package/dist/schemes/_search-index.d.ts.map +1 -0
- package/dist/schemes/_search-index.js +328 -0
- package/dist/schemes/_search-index.js.map +1 -0
- package/dist/schemes/cosine.js +1 -1
- package/dist/schemes/cosine.js.map +1 -1
- package/dist/schemes/exec-abort.js +3 -3
- package/dist/schemes/exec-abort.js.map +1 -1
- package/dist/schemes/exec-env.js +3 -3
- package/dist/schemes/exec-env.js.map +1 -1
- package/dist/server/BranchBatches.d.ts +49 -0
- package/dist/server/BranchBatches.d.ts.map +1 -0
- package/dist/server/BranchBatches.js +592 -0
- package/dist/server/BranchBatches.js.map +1 -0
- package/dist/server/Daemon.d.ts +39 -71
- package/dist/server/Daemon.d.ts.map +1 -1
- package/dist/server/Daemon.js +1133 -491
- package/dist/server/Daemon.js.map +1 -1
- package/dist/server/DaemonModule.d.ts +31 -0
- package/dist/server/DaemonModule.d.ts.map +1 -0
- package/dist/server/DaemonModule.js +2 -0
- package/dist/server/DaemonModule.js.map +1 -0
- package/dist/server/branch-batch.sql +154 -0
- package/dist/server/client-input.d.ts +13 -0
- package/dist/server/client-input.d.ts.map +1 -1
- package/dist/server/client-input.js +268 -57
- package/dist/server/client-input.js.map +1 -1
- package/dist/server/dispatch-as-plurnk.d.ts +1 -1
- package/dist/server/dispatch-as-plurnk.d.ts.map +1 -1
- package/dist/server/dispatch-as-plurnk.js +15 -7
- package/dist/server/dispatch-as-plurnk.js.map +1 -1
- package/dist/server/drain.sql +96 -65
- package/dist/server/envelope.d.ts +4 -7
- package/dist/server/envelope.d.ts.map +1 -1
- package/dist/server/envelope.js +118 -95
- package/dist/server/envelope.js.map +1 -1
- package/dist/server/envelope.sql +18 -23
- package/dist/server/exec-poll-backoff.js +1 -1
- package/dist/server/exec-poll-backoff.js.map +1 -1
- package/dist/server/lifecycle-recovery.sql +112 -2
- package/dist/server/logEntry.d.ts +4 -2
- package/dist/server/logEntry.d.ts.map +1 -1
- package/dist/server/logEntry.js +6 -3
- package/dist/server/logEntry.js.map +1 -1
- package/dist/server/logEntry.sql +1 -1
- package/dist/server/loop-model.d.ts.map +1 -1
- package/dist/server/loop-model.js +22 -9
- package/dist/server/loop-model.js.map +1 -1
- package/dist/server/loopDocs.d.ts.map +1 -1
- package/dist/server/loopDocs.js +5 -4
- package/dist/server/loopDocs.js.map +1 -1
- package/dist/server/seam-entry-read.sql +15 -10
- package/dist/server/seam-log-read.sql +2 -2
- package/dist/server/seam-loop.sql +1 -1
- package/dist/server/seam-proposal-list.sql +17 -7
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +79 -61
- package/dist/service.js.map +1 -1
- package/migrations/001_schema.sql +1010 -0
- package/package.json +65 -32
- package/dist/core/PluginLoader.d.ts +0 -20
- package/dist/core/PluginLoader.d.ts.map +0 -1
- package/dist/core/PluginLoader.js +0 -142
- package/dist/core/PluginLoader.js.map +0 -1
- package/dist/core/TelemetryChannel.d.ts +0 -37
- package/dist/core/TelemetryChannel.d.ts.map +0 -1
- package/dist/core/TelemetryChannel.js +0 -80
- package/dist/core/TelemetryChannel.js.map +0 -1
- package/dist/core/path-decode.d.ts +0 -3
- package/dist/core/path-decode.d.ts.map +0 -1
- package/dist/core/path-decode.js +0 -9
- package/dist/core/path-decode.js.map +0 -1
- package/dist/core/plugin-attribution.d.ts +0 -5
- package/dist/core/plugin-attribution.d.ts.map +0 -1
- package/dist/core/plugin-attribution.js +0 -39
- package/dist/core/plugin-attribution.js.map +0 -1
- package/dist/core/world-state.d.ts +0 -10
- package/dist/core/world-state.d.ts.map +0 -1
- package/dist/core/world-state.js +0 -35
- package/dist/core/world-state.js.map +0 -1
- package/dist/core/world-state.sql +0 -35
- package/dist/core/zero-pin.d.ts +0 -3
- package/dist/core/zero-pin.d.ts.map +0 -1
- package/dist/core/zero-pin.js +0 -16
- package/dist/core/zero-pin.js.map +0 -1
- package/dist/server/auto.d.ts +0 -6
- package/dist/server/auto.d.ts.map +0 -1
- package/dist/server/auto.js +0 -63
- package/dist/server/auto.js.map +0 -1
- package/dist/server/clientTurn.d.ts +0 -6
- package/dist/server/clientTurn.d.ts.map +0 -1
- package/dist/server/clientTurn.js +0 -22
- package/dist/server/clientTurn.js.map +0 -1
- package/dist/server/clientTurn.sql +0 -10
- package/dist/server/noProposals.d.ts +0 -6
- package/dist/server/noProposals.d.ts.map +0 -1
- package/dist/server/noProposals.js +0 -37
- package/dist/server/noProposals.js.map +0 -1
- package/dist/server/version-info.d.ts +0 -14
- package/dist/server/version-info.d.ts.map +0 -1
- package/dist/server/version-info.js +0 -69
- package/dist/server/version-info.js.map +0 -1
- package/migrations/0000-00-00.01_schema.sql +0 -536
- package/migrations/0004_loop-provider.sql +0 -3
- package/migrations/0005_subscription-published-channel.sql +0 -3
- package/migrations/0006_loop-max-turns.sql +0 -3
package/dist/schemes/Log.js
CHANGED
|
@@ -1,46 +1,35 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ReadResolve } from "../content/index.js";
|
|
1
|
+
import { PathSyntax, } from "@plurnk/plurnk-contracts";
|
|
3
2
|
import Matcher from "../content/matcher.js";
|
|
3
|
+
import { emptyFindFields, projectFindResult } from "./_entry-find.js";
|
|
4
4
|
import { CoreSchemeAdapterBase } from "../core/CoreSchemeServices.js";
|
|
5
|
+
import Results from "../core/results.js";
|
|
6
|
+
import LogBody from "../core/LogBody.js";
|
|
7
|
+
import EntrySemantic from "./_entry-semantic.js";
|
|
8
|
+
import EntryGraph from "./_entry-graph.js";
|
|
9
|
+
import { resolveSearchCandidates } from "./_search-candidate.js";
|
|
10
|
+
import { pathFolderSummaries, pathScope, pathScopeMatches } from "./_path-scope.js";
|
|
5
11
|
// log:///<loop_seq>/<turn_seq>/<sequence>[/<op>] — the trailing /op segment
|
|
6
12
|
// is wire-rendering self-documentation derived from the row's `op` field;
|
|
7
13
|
// parsing accepts it (or omits it) and identifies the row by coordinate. The op
|
|
8
|
-
// suffix is case-INSENSITIVE: model ops render UPPERCASE (READ/EDIT/FIND)
|
|
9
|
-
// engine-minted
|
|
10
|
-
//
|
|
11
|
-
// could not reclaim budget by folding its own error rows and spiralled to 413 (jumbo).
|
|
14
|
+
// suffix is case-INSENSITIVE: model ops render UPPERCASE (READ/EDIT/FIND) while
|
|
15
|
+
// engine-minted selectors such as `error` are lowercase. An actionless model
|
|
16
|
+
// emission has no suffix at all.
|
|
12
17
|
const COORDINATE = /^(\d+)\/(\d+)\/(\d+)(?:\/([A-Za-z]+))?$/;
|
|
13
|
-
// §log-coordinate-hierarchy — a log coordinate is a HIERARCHICAL PREFIX: `1` selects loop 1's rows,
|
|
18
|
+
// {§log-coordinate-hierarchy} — a log coordinate is a HIERARCHICAL PREFIX: `1` selects loop 1's rows,
|
|
14
19
|
// `1/2` turn 1/2's rows, `1/2/3` the one row. A full coordinate is always 3 parts, so a 1- or 2-part
|
|
15
20
|
// path is unambiguously a prefix — the trailing slash is OPTIONAL (`log:///1/2` ≡ `log:///1/2/`).
|
|
16
21
|
const PARTIAL_COORDINATE = /^\d+(?:\/\d+)?\/?$/;
|
|
17
|
-
//
|
|
18
|
-
// (§find-source-agnostic: the matcher must see exactly the content the model can retrieve).
|
|
19
|
-
// rx.content (with its own mimetype) when the op produced a body; the rx itself as compact JSON
|
|
20
|
-
// otherwise (EDIT/SEND acks — inspectable, matchable); the raw string if the rx isn't JSON.
|
|
21
|
-
const rxProjection = (rawRx) => {
|
|
22
|
-
try {
|
|
23
|
-
const rx = JSON.parse(rawRx);
|
|
24
|
-
if (typeof rx.content === "string") {
|
|
25
|
-
return { content: rx.content, mimetype: typeof rx.mimetype === "string" ? rx.mimetype : "text/plain" };
|
|
26
|
-
}
|
|
27
|
-
return { content: JSON.stringify(rx), mimetype: "application/json" };
|
|
28
|
-
}
|
|
29
|
-
catch {
|
|
30
|
-
return { content: rawRx, mimetype: "text/plain" };
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
// A log target pathname → the coordinate GLOB it scopes (§log-coordinate-hierarchy): a partial
|
|
22
|
+
// A log target pathname → the coordinate GLOB it scopes ({§log-coordinate-hierarchy}): a partial
|
|
34
23
|
// coordinate (`1`, `1/2`, with or without slash) is a prefix over its descendants; a trailing
|
|
35
24
|
// slash is the folder idiom; a full coordinate/glob passes through. null = malformed.
|
|
36
25
|
const coordinateGlob = (pathname) => {
|
|
37
26
|
if (pathname === "")
|
|
38
|
-
return "
|
|
27
|
+
return "**";
|
|
39
28
|
if (pathname.endsWith("/"))
|
|
40
|
-
return `${pathname}
|
|
29
|
+
return `${pathname}**`;
|
|
41
30
|
if (PARTIAL_COORDINATE.test(pathname))
|
|
42
|
-
return `${pathname}
|
|
43
|
-
if (parseCoordinate(pathname) !== null ||
|
|
31
|
+
return `${pathname}/**`;
|
|
32
|
+
if (parseCoordinate(pathname) !== null || PathSyntax.hasGlob(pathname))
|
|
44
33
|
return pathname;
|
|
45
34
|
return null;
|
|
46
35
|
};
|
|
@@ -54,209 +43,322 @@ const parseCoordinate = (pathname) => {
|
|
|
54
43
|
sequence: Number(match[3]),
|
|
55
44
|
};
|
|
56
45
|
};
|
|
57
|
-
|
|
58
|
-
//
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (first === 0 || first === -1)
|
|
64
|
-
return { status: 200, items: [] };
|
|
65
|
-
if (first > 0 && first <= total)
|
|
66
|
-
return { status: 200, items: [items[first - 1]] };
|
|
67
|
-
return { status: 416 };
|
|
68
|
-
}
|
|
69
|
-
const n = first === 0 ? 1 : first;
|
|
70
|
-
const m = last === -1 ? total : last;
|
|
71
|
-
if (n < 1 || n > total || m < 1 || m > total || n > m)
|
|
72
|
-
return { status: 416 };
|
|
73
|
-
return { status: 200, items: items.slice(n - 1, m) };
|
|
74
|
-
};
|
|
46
|
+
const canonicalCoordinate = (coordinate) => coordinate.replace(/\/[A-Za-z]+$/, "");
|
|
47
|
+
// A rendered log path appends `/OP` to the canonical loop/turn/item coordinate
|
|
48
|
+
// as self-documentation. Selection honors both views: ordinary path globs map
|
|
49
|
+
// the three-level resource tree, while an explicit OP segment can still filter
|
|
50
|
+
// rows (`log:///**/READ`).
|
|
51
|
+
const coordinateScopeMatches = (scope, coordinate) => pathScopeMatches(scope, coordinate) || pathScopeMatches(scope, canonicalCoordinate(coordinate));
|
|
75
52
|
export default class Log extends CoreSchemeAdapterBase {
|
|
76
53
|
static manifest = {
|
|
77
54
|
name: "log",
|
|
78
|
-
channels: {},
|
|
55
|
+
channels: {},
|
|
79
56
|
defaultChannel: "",
|
|
80
57
|
category: "logging",
|
|
81
|
-
|
|
82
|
-
//
|
|
83
|
-
// model's DB-storage curation lever (plurnk.md:10/:47 + the OP×resource matrix; §model-entry-log-curation).
|
|
84
|
-
// The model clears the gate; Log's handler surface (kill only — no edit/writeEntry) is the
|
|
85
|
-
// op-level truth, so every other mutating op still 501s.
|
|
58
|
+
// Log KILL is model-authorized curation. Other mutations remain unavailable
|
|
59
|
+
// because Log exposes no edit/writeEntry handler. {§model-entry-log-curation}
|
|
86
60
|
writableBy: ["plurnk", "model"],
|
|
87
61
|
volatile: false,
|
|
88
62
|
modelVisible: true,
|
|
89
63
|
folderScopes: true,
|
|
90
64
|
example: "<<READ(log:///1/2/3)::READ",
|
|
91
65
|
};
|
|
92
|
-
async
|
|
66
|
+
async resolveCoreRepresentation(target, ctx) {
|
|
93
67
|
const core = this.coreContext(ctx);
|
|
94
68
|
const { db, workerId } = core;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
69
|
+
const failure = (code, status, detail, extensions = {}) => ({
|
|
70
|
+
result: Results.failure("scheme:log", code, status, detail, { content: null, mimetype: null, channel: null }, extensions),
|
|
71
|
+
});
|
|
72
|
+
if (target === null) {
|
|
73
|
+
return failure("read-target-required", 400, "READ requires a log coordinate.", {
|
|
74
|
+
recovery: "Provide one exact log coordinate.",
|
|
75
|
+
retryable: false,
|
|
76
|
+
});
|
|
101
77
|
}
|
|
102
|
-
const pathname = (
|
|
78
|
+
const pathname = (target.kind === "url" ? target.pathname : target.raw).replace(/^\//, "");
|
|
103
79
|
const coord = parseCoordinate(pathname);
|
|
104
|
-
if (coord === null)
|
|
105
|
-
return
|
|
80
|
+
if (coord === null) {
|
|
81
|
+
return failure("coordinate-malformed", 400, `The log coordinate '${pathname}' is malformed.`, {
|
|
82
|
+
target: pathname,
|
|
83
|
+
recovery: "Use one exact loop/turn/sequence coordinate.",
|
|
84
|
+
retryable: false,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
106
87
|
const row = await db.log_read_by_coordinate.get({ worker_id: workerId, loop_seq: coord.loopSeq, turn_seq: coord.turnSeq, sequence: coord.sequence });
|
|
107
88
|
if (row === undefined)
|
|
108
|
-
return
|
|
109
|
-
const { content: underlyingContent, mimetype: underlyingMimetype } =
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
89
|
+
return failure("entry-not-found", 404, `No log entry exists at log:///${pathname}.`);
|
|
90
|
+
const { content: underlyingContent, mimetype: underlyingMimetype } = LogBody.resolve({
|
|
91
|
+
op: row.op,
|
|
92
|
+
attrs: row.attrs,
|
|
93
|
+
tx: row.tx,
|
|
94
|
+
rx: row.rx,
|
|
95
|
+
mimetypeTx: row.mimetype_tx,
|
|
96
|
+
mimetypeRx: row.mimetype_rx,
|
|
116
97
|
});
|
|
98
|
+
const tags = JSON.parse(row.tags);
|
|
99
|
+
if (!Array.isArray(tags) || !tags.every((tag) => typeof tag === "string")) {
|
|
100
|
+
throw new TypeError(`Log row ${pathname} contains invalid tag storage.`);
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
representation: {
|
|
104
|
+
channels: {
|
|
105
|
+
"": {
|
|
106
|
+
content: underlyingContent,
|
|
107
|
+
mimetype: underlyingMimetype,
|
|
108
|
+
state: "static",
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
tags,
|
|
112
|
+
},
|
|
113
|
+
};
|
|
117
114
|
}
|
|
118
|
-
// §log-uniform-query — FIND over the worker's log rows, on the SAME source-agnostic primitive
|
|
119
|
-
// every entry scheme runs (Matcher.matchCandidates, §find-source-agnostic): candidates are the
|
|
120
|
-
// coordinate-scoped rows
|
|
121
|
-
// dialect works on log BY CONSTRUCTION and FIND(log)
|
|
122
|
-
// ~semantic stays 501 until the pump embeds log rows (epic S5); @graph is 501 (log rows carry
|
|
123
|
-
// no symbol channels — an honest absence, not an exception).
|
|
115
|
+
// {§log-uniform-query} — FIND over the worker's log rows, on the SAME source-agnostic primitive
|
|
116
|
+
// every entry scheme runs (Matcher.matchCandidates, {§find-source-agnostic}): candidates are the
|
|
117
|
+
// coordinate-scoped rows resolved by LogBody exactly as READ shows them, so every content
|
|
118
|
+
// dialect works on log BY CONSTRUCTION and FIND(log)->READ(coordinate) composes like any scheme.
|
|
124
119
|
async find(statement, ctx) {
|
|
125
|
-
|
|
120
|
+
return this.#find(statement, this.coreContext(ctx));
|
|
121
|
+
}
|
|
122
|
+
async #find(statement, core, allowTargetless = false) {
|
|
126
123
|
const { db, workerId, mimetypes } = core;
|
|
127
|
-
const empty = (status
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
124
|
+
const empty = (status, detail, extensions = {}) => {
|
|
125
|
+
const fields = emptyFindFields();
|
|
126
|
+
if (status >= 400 && detail === undefined) {
|
|
127
|
+
throw new Error(`Log.find: selection returned status ${status} without Problem Details or a diagnostic`);
|
|
128
|
+
}
|
|
129
|
+
return status >= 400
|
|
130
|
+
? Results.failure("scheme:log", status === 404 ? "entry-not-found" : status === 416 ? "range-not-satisfiable" : status === 501 ? "matcher-not-implemented" : "find-failed", status, detail, fields, extensions)
|
|
131
|
+
: { status, ...fields };
|
|
132
|
+
};
|
|
133
|
+
if (statement.target === null && !allowTargetless) {
|
|
134
|
+
return empty(400, "FIND requires a log target.", {
|
|
135
|
+
recovery: "Provide a log coordinate, prefix, or glob.",
|
|
136
|
+
retryable: false,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
const pathname = statement.target === null
|
|
140
|
+
? ""
|
|
141
|
+
: (statement.target.kind === "url" ? statement.target.pathname : statement.target.raw).replace(/^\//, "");
|
|
133
142
|
const glob = coordinateGlob(pathname);
|
|
134
|
-
if (glob === null)
|
|
135
|
-
return empty(400
|
|
136
|
-
|
|
143
|
+
if (glob === null) {
|
|
144
|
+
return empty(400, `The log target '${pathname}' is malformed.`, {
|
|
145
|
+
target: pathname,
|
|
146
|
+
recovery: "Use a log coordinate, prefix, or glob.",
|
|
147
|
+
retryable: false,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
const scope = pathScope(glob, false);
|
|
151
|
+
if (scope.kind === "exact") {
|
|
152
|
+
const coordinate = parseCoordinate(scope.pathname);
|
|
153
|
+
if (coordinate === null)
|
|
154
|
+
throw new Error(`Exact log scope has a malformed coordinate ${JSON.stringify(scope.pathname)}`);
|
|
155
|
+
const exact = await db.log_id_by_coordinate.get({
|
|
156
|
+
worker_id: workerId,
|
|
157
|
+
loop_seq: coordinate.loopSeq,
|
|
158
|
+
turn_seq: coordinate.turnSeq,
|
|
159
|
+
sequence: coordinate.sequence,
|
|
160
|
+
});
|
|
161
|
+
if (exact === undefined) {
|
|
162
|
+
return empty(404, `No log entry exists at ${statement.target?.raw ?? `log:///${scope.pathname}`}.`, { target: statement.target?.raw ?? `log:///${scope.pathname}` });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// {§log-region-tagging} — a tag signal AND-filters the candidates ({§find-tag-filter-and-semantics}):
|
|
137
166
|
// a row survives only if it carries EVERY listed tag. No signal → the plain coordinate scope.
|
|
138
167
|
const tags = Array.isArray(statement.signal) ? statement.signal : [];
|
|
139
|
-
const
|
|
140
|
-
? await db.log_find_candidates_tagged.all({ worker_id: workerId,
|
|
141
|
-
: await db.log_find_candidates.all({ worker_id: workerId,
|
|
168
|
+
const candidateRows = tags.length > 0
|
|
169
|
+
? await db.log_find_candidates_tagged.all({ worker_id: workerId, scope_prefix: scope.candidatePrefix, tags: JSON.stringify(tags) })
|
|
170
|
+
: await db.log_find_candidates.all({ worker_id: workerId, scope_prefix: scope.candidatePrefix });
|
|
171
|
+
let rows;
|
|
172
|
+
try {
|
|
173
|
+
rows = candidateRows.filter((row) => coordinateScopeMatches(scope, row.coordinate));
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
return empty(400, `The log glob '${glob}' is malformed.`, {
|
|
177
|
+
target: glob,
|
|
178
|
+
recovery: "Correct the log glob.",
|
|
179
|
+
retryable: false,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
const candidateByCanonicalCoord = new Map(candidateRows.map((row) => [canonicalCoordinate(row.coordinate), row]));
|
|
142
183
|
const byCoord = new Map(rows.map((r) => [r.coordinate, r]));
|
|
143
|
-
const projected = rows.map((r) => ({
|
|
184
|
+
const projected = rows.map((r) => ({
|
|
185
|
+
key: r.coordinate,
|
|
186
|
+
...LogBody.resolve({
|
|
187
|
+
op: r.op,
|
|
188
|
+
attrs: r.attrs,
|
|
189
|
+
tx: r.tx,
|
|
190
|
+
rx: r.rx,
|
|
191
|
+
mimetypeTx: r.mimetype_tx,
|
|
192
|
+
mimetypeRx: r.mimetype_rx,
|
|
193
|
+
}),
|
|
194
|
+
}));
|
|
144
195
|
let matches;
|
|
145
|
-
if (statement.body ===
|
|
146
|
-
|
|
196
|
+
if (statement.body?.dialect === "semantic") {
|
|
197
|
+
if (mimetypes === undefined) {
|
|
198
|
+
return empty(501, "Semantic search requires the mimetypes capability.", {
|
|
199
|
+
stage: "semantic-search",
|
|
200
|
+
retryable: false,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
const candidateSet = resolveSearchCandidates(rows.map(({ coordinate, deep_hash }) => ({ key: coordinate, deepHash: deep_hash })));
|
|
204
|
+
if (candidateSet.state === "incomplete")
|
|
205
|
+
return empty(503, `The persistent search index covers ${candidateSet.indexed} of ${candidateSet.total} selected log results.`, {
|
|
206
|
+
search: candidateSet,
|
|
207
|
+
stage: "search-index",
|
|
208
|
+
recovery: "Wait for search indexing to complete before repeating the search.",
|
|
209
|
+
retryable: false,
|
|
210
|
+
});
|
|
211
|
+
const selection = EntrySemantic.resultSelection(statement.lineMarker);
|
|
212
|
+
const ranked = await EntrySemantic.rankCandidates(db, candidateSet.candidates, mimetypes, statement.body.raw, selection);
|
|
213
|
+
if (ranked.status !== 200) {
|
|
214
|
+
return empty(ranked.status, ranked.status === 501
|
|
215
|
+
? "Similarity-threshold search requires an embedding provider."
|
|
216
|
+
: "The requested similarity threshold is outside the supported range.", {
|
|
217
|
+
stage: "semantic-search",
|
|
218
|
+
...(selection.threshold === null ? {} : { threshold: selection.threshold }),
|
|
219
|
+
recovery: ranked.status === 501
|
|
220
|
+
? "Remove the decimal similarity threshold while embeddings are unavailable."
|
|
221
|
+
: "Use a similarity threshold greater than zero and less than one.",
|
|
222
|
+
retryable: false,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
const sourceMatches = ranked.results.map(({ key, lineStart, lineEnd }) => ({
|
|
226
|
+
key,
|
|
227
|
+
span: { lineStart, lineEnd },
|
|
228
|
+
}));
|
|
229
|
+
const readable = Matcher.addTextRegions(sourceMatches, projected);
|
|
230
|
+
matches = readable.map(({ key, matches: ranges }) => ({ pathname: key, matches: ranges }));
|
|
147
231
|
}
|
|
148
|
-
else {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
|
|
232
|
+
else if (statement.body?.dialect === "graph") {
|
|
233
|
+
const candidateSet = resolveSearchCandidates(rows.map(({ coordinate, deep_hash }) => ({ key: coordinate, deepHash: deep_hash })));
|
|
234
|
+
if (candidateSet.state === "incomplete")
|
|
235
|
+
return empty(503, `The persistent search index covers ${candidateSet.indexed} of ${candidateSet.total} selected log results.`, {
|
|
236
|
+
search: candidateSet,
|
|
237
|
+
stage: "search-index",
|
|
238
|
+
recovery: "Wait for search indexing to complete before repeating the search.",
|
|
239
|
+
retryable: false,
|
|
240
|
+
});
|
|
241
|
+
const universeRows = await db.log_find_candidates.all({ worker_id: workerId, scope_prefix: null });
|
|
242
|
+
const universe = resolveSearchCandidates(universeRows.map(({ coordinate, deep_hash }) => ({ key: coordinate, deepHash: deep_hash })));
|
|
243
|
+
if (universe.state === "incomplete")
|
|
244
|
+
return empty(503, `The persistent search index covers ${universe.indexed} of ${universe.total} log results in the relationship universe.`, {
|
|
245
|
+
search: universe,
|
|
246
|
+
stage: "search-index",
|
|
247
|
+
recovery: "Wait for search indexing to complete before repeating the search.",
|
|
248
|
+
retryable: false,
|
|
249
|
+
});
|
|
250
|
+
const graph = await EntryGraph.matchCandidates(db, universe.candidates, candidateSet.candidates, statement.body.raw);
|
|
251
|
+
if (graph.status !== 200) {
|
|
252
|
+
return empty(graph.status, `The graph matcher '${statement.body.raw}' is malformed.`, {
|
|
253
|
+
stage: "matcher",
|
|
254
|
+
dialect: "graph",
|
|
255
|
+
recovery: "Correct or remove the matcher.",
|
|
256
|
+
retryable: false,
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
const sourceMatches = graph.matches.map(({ key, lineStart, lineEnd }) => ({
|
|
260
|
+
key,
|
|
261
|
+
span: { lineStart, lineEnd },
|
|
162
262
|
}));
|
|
263
|
+
const readable = Matcher.addTextRegions(sourceMatches, projected);
|
|
264
|
+
matches = readable.map(({ key, matches: ranges }) => ({ pathname: key, matches: ranges }));
|
|
163
265
|
}
|
|
164
|
-
if (statement.
|
|
165
|
-
|
|
166
|
-
if (page.status !== 200)
|
|
167
|
-
return empty(page.status);
|
|
168
|
-
matches = page.items ?? [];
|
|
266
|
+
else if (statement.body === null) {
|
|
267
|
+
matches = projected.map(({ key }) => ({ pathname: key, matches: [] }));
|
|
169
268
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
};
|
|
269
|
+
else {
|
|
270
|
+
if (mimetypes === undefined) {
|
|
271
|
+
return empty(501, "Content matching requires the mimetypes capability.", {
|
|
272
|
+
stage: "matcher",
|
|
273
|
+
dialect: statement.body.dialect,
|
|
274
|
+
retryable: false,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
const r = await Matcher.matchCandidates(statement.body, projected, mimetypes);
|
|
278
|
+
if (r.status !== 200) {
|
|
279
|
+
if (r.problem === undefined) {
|
|
280
|
+
throw new Error(`Log.find: matcher returned status ${r.status} without Problem Details`);
|
|
281
|
+
}
|
|
282
|
+
return Results.assert({
|
|
283
|
+
status: r.status,
|
|
284
|
+
problem: r.problem,
|
|
285
|
+
...emptyFindFields(),
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
matches = r.matches.map(({ key, matches: ranges }) => ({ pathname: key, matches: ranges }));
|
|
190
289
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
const
|
|
195
|
-
const seenPath = [];
|
|
196
|
-
const seen = new Set();
|
|
197
|
-
let itemsTokenTotal = 0;
|
|
290
|
+
const folderSummaries = statement.body === null
|
|
291
|
+
? pathFolderSummaries(scope, candidateRows.map((row) => canonicalCoordinate(row.coordinate)))
|
|
292
|
+
: [];
|
|
293
|
+
const resources = [];
|
|
198
294
|
for (const m of matches) {
|
|
199
295
|
const row = byCoord.get(m.pathname);
|
|
200
296
|
if (row === undefined)
|
|
201
297
|
continue;
|
|
202
298
|
const path = `log:///${m.pathname}`;
|
|
203
|
-
const proj =
|
|
299
|
+
const proj = LogBody.resolve({
|
|
300
|
+
op: row.op,
|
|
301
|
+
attrs: row.attrs,
|
|
302
|
+
tx: row.tx,
|
|
303
|
+
rx: row.rx,
|
|
304
|
+
mimetypeTx: row.mimetype_tx,
|
|
305
|
+
mimetypeRx: row.mimetype_rx,
|
|
306
|
+
});
|
|
204
307
|
const item = {
|
|
205
308
|
path,
|
|
206
309
|
channels: { [path]: { mimetype: proj.mimetype, tokens: row.tokens, lines: proj.content.length === 0 ? 0 : proj.content.split("\n").length } },
|
|
207
310
|
};
|
|
208
|
-
|
|
209
|
-
if (!seen.has(m.pathname)) {
|
|
210
|
-
seen.add(m.pathname);
|
|
211
|
-
seenPath.push(m.pathname);
|
|
212
|
-
itemsTokenTotal += row.tokens;
|
|
213
|
-
}
|
|
311
|
+
resources.push({ item, match: m });
|
|
214
312
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
313
|
+
const scopes = [];
|
|
314
|
+
for (const folder of folderSummaries) {
|
|
315
|
+
const members = folder.pathnames.map((coordinate) => candidateByCanonicalCoord.get(coordinate)).filter((row) => row !== undefined);
|
|
316
|
+
const item = {
|
|
317
|
+
path: `log:///${folder.selector}`,
|
|
318
|
+
items: members.length,
|
|
319
|
+
tokens: members.reduce((sum, row) => sum + row.tokens, 0),
|
|
320
|
+
};
|
|
321
|
+
scopes.push(item);
|
|
322
|
+
}
|
|
323
|
+
return projectFindResult(statement, scope, resources, scopes);
|
|
219
324
|
}
|
|
220
325
|
async open(statement, ctx) {
|
|
221
326
|
return this.#setExpanded(statement, this.coreContext(ctx), 1);
|
|
222
327
|
}
|
|
223
|
-
// FOLD toggles the expanded bit only — an active subscription stays alive. §subscriptions-fold-keeps-subscription
|
|
328
|
+
// FOLD toggles the expanded bit only — an active subscription stays alive. {§subscriptions-fold-keeps-subscription}
|
|
224
329
|
async fold(statement, ctx) {
|
|
225
330
|
return this.#setExpanded(statement, this.coreContext(ctx), 0);
|
|
226
331
|
}
|
|
227
|
-
// Resolve a log:/// target — a concrete coordinate
|
|
228
|
-
//
|
|
229
|
-
|
|
230
|
-
async #resolveIds(pathname, lineMarker, ctx) {
|
|
332
|
+
// Resolve a log:/// target — a concrete coordinate or path-glob — to the matched row ids.
|
|
333
|
+
// OPEN/FOLD/KILL share this one path selection; log curation has no positional pagination.
|
|
334
|
+
async #resolveIds(pathname, ctx) {
|
|
231
335
|
const { db, workerId } = ctx;
|
|
232
336
|
const coord = parseCoordinate(pathname);
|
|
233
|
-
if (coord !== null
|
|
337
|
+
if (coord !== null) {
|
|
234
338
|
const row = await db.log_id_by_coordinate.get({ worker_id: workerId, loop_seq: coord.loopSeq, turn_seq: coord.turnSeq, sequence: coord.sequence });
|
|
235
339
|
return row === undefined ? { status: 404, ids: [] } : { status: 200, ids: [row.id] };
|
|
236
340
|
}
|
|
237
|
-
// §log-coordinate-hierarchy — one resolution for every consumer (curation here, find below).
|
|
341
|
+
// {§log-coordinate-hierarchy} — one resolution for every consumer (curation here, find below).
|
|
238
342
|
const glob = coordinateGlob(pathname);
|
|
239
343
|
if (glob === null)
|
|
240
|
-
return { status: 400, ids: [], error: `
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
344
|
+
return { status: 400, ids: [], error: `The log target '${pathname}' is malformed.` };
|
|
345
|
+
const scope = pathScope(glob, false);
|
|
346
|
+
const candidates = await db.log_match_coordinates.all({ worker_id: workerId, scope_prefix: scope.candidatePrefix });
|
|
347
|
+
let matched;
|
|
348
|
+
try {
|
|
349
|
+
matched = candidates.filter((row) => coordinateScopeMatches(scope, row.coordinate));
|
|
350
|
+
}
|
|
351
|
+
catch {
|
|
352
|
+
return { status: 400, ids: [], error: `The log glob '${glob}' is malformed.` };
|
|
353
|
+
}
|
|
354
|
+
// {§log-curation-folder-idiom} — a well-formed empty selection is a
|
|
355
|
+
// successful no-op and remains outside the error surface.
|
|
245
356
|
if (matched.length === 0)
|
|
246
357
|
return { status: 204, ids: [] };
|
|
247
|
-
|
|
248
|
-
if (lineMarker !== null) {
|
|
249
|
-
const page = paginate(matched, LineMarkerOps.firstLast(lineMarker));
|
|
250
|
-
if (page.status !== 200)
|
|
251
|
-
return { status: page.status, ids: [] };
|
|
252
|
-
selected = page.items ?? [];
|
|
253
|
-
}
|
|
254
|
-
if (selected.length === 0)
|
|
255
|
-
return { status: 404, ids: [] };
|
|
256
|
-
return { status: 200, ids: selected.map((s) => s.id) };
|
|
358
|
+
return { status: 200, ids: matched.map((row) => row.id) };
|
|
257
359
|
}
|
|
258
|
-
// §log-region-tagging — resolve OPEN[tag] to ids: candidates are the target's glob scope (the
|
|
259
|
-
// whole
|
|
360
|
+
// {§log-region-tagging} — resolve OPEN[tag] to ids: candidates are the target's glob scope (the
|
|
361
|
+
// whole worker log when targetless — a bare OPEN[tag] recalls the entire tagged working-set),
|
|
260
362
|
// AND-filtered to rows carrying EVERY listed tag. Zero matches is a no-op success (204), mirroring
|
|
261
363
|
// #resolveIds — recalling a name that tags nothing steers nothing.
|
|
262
364
|
async #resolveByTags(statement, tags, ctx) {
|
|
@@ -264,86 +366,153 @@ export default class Log extends CoreSchemeAdapterBase {
|
|
|
264
366
|
const pathname = statement.target === null ? "" : (statement.target.kind === "url" ? statement.target.pathname : statement.target.raw).replace(/^\//, "");
|
|
265
367
|
const glob = coordinateGlob(pathname);
|
|
266
368
|
if (glob === null)
|
|
267
|
-
return { status: 400, ids: [], error: `
|
|
268
|
-
const
|
|
369
|
+
return { status: 400, ids: [], error: `The log target '${pathname}' is malformed.` };
|
|
370
|
+
const scope = pathScope(glob, false);
|
|
371
|
+
const candidates = await db.log_match_coordinates_tagged.all({
|
|
372
|
+
worker_id: workerId,
|
|
373
|
+
scope_prefix: scope.candidatePrefix,
|
|
374
|
+
tags: JSON.stringify(tags),
|
|
375
|
+
});
|
|
376
|
+
let matched;
|
|
377
|
+
try {
|
|
378
|
+
matched = candidates.filter((row) => coordinateScopeMatches(scope, row.coordinate));
|
|
379
|
+
}
|
|
380
|
+
catch {
|
|
381
|
+
return { status: 400, ids: [], error: `The log glob '${glob}' is malformed.` };
|
|
382
|
+
}
|
|
269
383
|
if (matched.length === 0)
|
|
270
384
|
return { status: 204, ids: [] };
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
385
|
+
return { status: 200, ids: matched.map((row) => row.id) };
|
|
386
|
+
}
|
|
387
|
+
// A matcher-bearing curation op reuses FIND's complete source-agnostic selector with
|
|
388
|
+
// explicit all-results pagination. OPEN's tags filter candidates; FOLD's tags are withheld until
|
|
389
|
+
// after selection because they apply to the rows being folded.
|
|
390
|
+
async #resolveByMatcher(statement, filterTags, ctx) {
|
|
391
|
+
const selected = await this.#find({
|
|
392
|
+
...statement,
|
|
393
|
+
op: "FIND",
|
|
394
|
+
signal: filterTags ? statement.signal : null,
|
|
395
|
+
lineMarker: { marks: [1, -1] },
|
|
396
|
+
}, ctx, filterTags && Array.isArray(statement.signal) && statement.signal.length > 0 && statement.target === null);
|
|
397
|
+
if (selected.status !== 200)
|
|
398
|
+
return { status: selected.status, ids: [], problem: selected.problem };
|
|
399
|
+
let selectedPaths = selected.results.flatMap((item) => typeof item.path === "string" ? [item.path] : []);
|
|
400
|
+
if (selectedPaths.length === 0) {
|
|
401
|
+
if (statement.target === null) {
|
|
402
|
+
throw new Error("A successful broad log matcher selection returned no resource paths");
|
|
403
|
+
}
|
|
404
|
+
const pathname = (statement.target.kind === "url" ? statement.target.pathname : statement.target.raw).replace(/^\//, "");
|
|
405
|
+
const glob = coordinateGlob(pathname);
|
|
406
|
+
if (glob === null)
|
|
407
|
+
throw new Error(`Log matcher selected malformed target ${JSON.stringify(pathname)}`);
|
|
408
|
+
const scope = pathScope(glob, false);
|
|
409
|
+
if (scope.kind !== "exact") {
|
|
410
|
+
throw new Error("A successful broad log matcher selection returned no resource paths");
|
|
411
|
+
}
|
|
412
|
+
selectedPaths = [scope.pathname];
|
|
413
|
+
}
|
|
414
|
+
const ids = [];
|
|
415
|
+
for (const pathname of selectedPaths) {
|
|
416
|
+
const coordinate = parseCoordinate(pathname.replace(/^log:\/\/\//, "").replace(/^\//, ""));
|
|
417
|
+
if (coordinate === null)
|
|
418
|
+
throw new Error(`Log matcher selected malformed coordinate '${pathname}'`);
|
|
419
|
+
const row = await ctx.db.log_id_by_coordinate.get({
|
|
420
|
+
worker_id: ctx.workerId,
|
|
421
|
+
loop_seq: coordinate.loopSeq,
|
|
422
|
+
turn_seq: coordinate.turnSeq,
|
|
423
|
+
sequence: coordinate.sequence,
|
|
424
|
+
});
|
|
425
|
+
if (row === undefined)
|
|
426
|
+
return { status: 404, ids: [] };
|
|
427
|
+
ids.push(row.id);
|
|
428
|
+
}
|
|
429
|
+
return ids.length === 0 ? { status: 204, ids: [] } : { status: 200, ids };
|
|
430
|
+
}
|
|
431
|
+
async #applyExpanded(ids, expanded, tags, ctx) {
|
|
432
|
+
for (const id of ids)
|
|
433
|
+
await ctx.db.log_set_expanded_by_id.run({ id, expanded });
|
|
434
|
+
if (expanded === 0) {
|
|
435
|
+
for (const id of ids)
|
|
436
|
+
for (const tag of tags)
|
|
437
|
+
await ctx.db.log_write_tag.run({ log_entry_id: id, tag });
|
|
277
438
|
}
|
|
278
|
-
|
|
279
|
-
return { status: 404, ids: [] };
|
|
280
|
-
return { status: 200, ids: selected.map((s) => s.id) };
|
|
439
|
+
return { status: 200, matched: ids.length };
|
|
281
440
|
}
|
|
282
441
|
async #setExpanded(statement, ctx, expanded) {
|
|
283
442
|
const signal = Array.isArray(statement.signal) ? statement.signal : [];
|
|
284
|
-
|
|
443
|
+
if (statement.body !== null) {
|
|
444
|
+
const matched = await this.#resolveByMatcher(statement, expanded === 1, ctx);
|
|
445
|
+
if (matched.status === 204)
|
|
446
|
+
return { status: 204, matched: 0 };
|
|
447
|
+
if (matched.status !== 200) {
|
|
448
|
+
if (matched.problem !== undefined) {
|
|
449
|
+
return Results.assert({ status: matched.status, problem: matched.problem });
|
|
450
|
+
}
|
|
451
|
+
return Results.failure("scheme:log", matched.status === 404 ? "entry-not-found" : "curation-failed", matched.status, "No log entry matches the requested selection.");
|
|
452
|
+
}
|
|
453
|
+
return this.#applyExpanded(matched.ids, expanded, signal, ctx);
|
|
454
|
+
}
|
|
455
|
+
// {§log-region-tagging} — OPEN[tag] is the READ side: recall rows by tag, target optional (a bare
|
|
285
456
|
// OPEN[tag] recalls the whole tagged working-set). FOLD never resolves by tag — it is the WRITE
|
|
286
457
|
// side (it stamps the tag below), always scoped to the target region it folds.
|
|
287
458
|
if (expanded === 1 && signal.length > 0) {
|
|
288
459
|
const rt = await this.#resolveByTags(statement, signal, ctx);
|
|
289
460
|
if (rt.status === 204)
|
|
290
461
|
return { status: 204, matched: 0 };
|
|
291
|
-
if (rt.status !== 200)
|
|
292
|
-
return
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
462
|
+
if (rt.status !== 200) {
|
|
463
|
+
return Results.failure("scheme:log", "open-failed", rt.status, rt.error ?? "No log entry matches the requested selection.", {}, {
|
|
464
|
+
target: statement.target?.raw ?? null,
|
|
465
|
+
...(rt.status === 400
|
|
466
|
+
? {
|
|
467
|
+
recovery: "Use a log coordinate, prefix, or glob.",
|
|
468
|
+
retryable: false,
|
|
469
|
+
}
|
|
470
|
+
: {}),
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
return this.#applyExpanded(rt.ids, 1, signal, ctx);
|
|
474
|
+
}
|
|
475
|
+
if (statement.target === null) {
|
|
476
|
+
return Results.failure("scheme:log", "target-required", 400, `${expanded === 1 ? "OPEN" : "FOLD"} requires a log target.`, {}, {
|
|
477
|
+
recovery: "Provide a log coordinate, prefix, or glob.",
|
|
478
|
+
retryable: false,
|
|
479
|
+
});
|
|
296
480
|
}
|
|
297
|
-
if (statement.target === null)
|
|
298
|
-
return { status: 400 };
|
|
299
481
|
const pathname = (statement.target.kind === "url" ? statement.target.pathname : statement.target.raw).replace(/^\//, "");
|
|
300
|
-
const r = await this.#resolveIds(pathname,
|
|
482
|
+
const r = await this.#resolveIds(pathname, ctx);
|
|
301
483
|
if (r.status === 204)
|
|
302
484
|
return { status: 204, matched: 0 };
|
|
303
|
-
if (r.status !== 200)
|
|
304
|
-
return
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
if (expanded === 0) {
|
|
314
|
-
const previewIds = new Set();
|
|
315
|
-
for (const id of r.ids) {
|
|
316
|
-
const row = await ctx.db.log_row_target.get({ id });
|
|
317
|
-
if (row?.scheme === "prompt" && row.origin === "plurnk" && row.op === "READ" && row.loop_id === ctx.loopId)
|
|
318
|
-
previewIds.add(id);
|
|
319
|
-
}
|
|
320
|
-
if (previewIds.size > 0) {
|
|
321
|
-
ids = r.ids.filter((id) => !previewIds.has(id));
|
|
322
|
-
if (ids.length === 0)
|
|
323
|
-
return { status: 403, error: "Illegal attempt to FOLD the task preview. Use KILL if you want it removed." };
|
|
324
|
-
}
|
|
485
|
+
if (r.status !== 200) {
|
|
486
|
+
return Results.failure("scheme:log", r.status === 404 ? "entry-not-found" : "curation-failed", r.status, r.error ?? `No log entry matches '${pathname}'.`, {}, {
|
|
487
|
+
target: pathname,
|
|
488
|
+
...(r.status === 400
|
|
489
|
+
? {
|
|
490
|
+
recovery: "Use a log coordinate, prefix, or glob.",
|
|
491
|
+
retryable: false,
|
|
492
|
+
}
|
|
493
|
+
: {}),
|
|
494
|
+
});
|
|
325
495
|
}
|
|
326
|
-
|
|
327
|
-
await ctx.db.log_set_expanded_by_id.run({ id, expanded });
|
|
328
|
-
// §log-region-tagging — FOLD[tag] is the log's write-op: stamp the tags on the folded rows,
|
|
329
|
-
// additively (§edit-tags-additive). Only the rows actually folded are tagged (a preview spared
|
|
330
|
-
// above is neither folded nor tagged). OPEN with a signal never reaches here.
|
|
331
|
-
if (expanded === 0 && signal.length > 0) {
|
|
332
|
-
for (const id of ids)
|
|
333
|
-
for (const tag of signal)
|
|
334
|
-
await ctx.db.log_write_tag.run({ log_entry_id: id, tag });
|
|
335
|
-
}
|
|
336
|
-
return { status: 200, matched: ids.length };
|
|
496
|
+
return this.#applyExpanded(r.ids, expanded, signal, ctx);
|
|
337
497
|
}
|
|
338
|
-
// KILL
|
|
339
|
-
//
|
|
340
|
-
// render; the row persists). Same resolution as OPEN/FOLD, DELETE instead of flip. KILL
|
|
341
|
-
// carries no <L> result slot, so no pagination — a concrete coordinate or a path-glob.
|
|
498
|
+
// KILL shares OPEN/FOLD's address resolution, deletes instead of flipping visibility,
|
|
499
|
+
// and carries no positional scope. {§model-entry-log-curation} {§log-curation-set-selection}
|
|
342
500
|
async kill(pathname, _signal, ctx) {
|
|
343
501
|
const core = this.coreContext(ctx);
|
|
344
|
-
const r = await this.#resolveIds(pathname.replace(/^\//, ""),
|
|
345
|
-
if (r.status
|
|
346
|
-
return { status:
|
|
502
|
+
const r = await this.#resolveIds(pathname.replace(/^\//, ""), core);
|
|
503
|
+
if (r.status === 204)
|
|
504
|
+
return { status: 204 };
|
|
505
|
+
if (r.status !== 200) {
|
|
506
|
+
return Results.failure("scheme:log", r.status === 404 ? "entry-not-found" : "kill-failed", r.status, r.error ?? `No log entry matches '${pathname}'.`, {}, {
|
|
507
|
+
target: pathname,
|
|
508
|
+
...(r.status === 400
|
|
509
|
+
? {
|
|
510
|
+
recovery: "Use a log coordinate, prefix, or glob.",
|
|
511
|
+
retryable: false,
|
|
512
|
+
}
|
|
513
|
+
: {}),
|
|
514
|
+
});
|
|
515
|
+
}
|
|
347
516
|
for (const id of r.ids)
|
|
348
517
|
await core.db.log_delete_by_id.run({ id });
|
|
349
518
|
return { status: 200 };
|