@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/core/packet-wire.js
CHANGED
|
@@ -4,17 +4,12 @@
|
|
|
4
4
|
// digest tool imports it to write byte-identical packetNNN.{system,user}.md
|
|
5
5
|
// files. No second implementation, no drift.
|
|
6
6
|
//
|
|
7
|
-
// Format
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
// sees consistent framing across every section it might receive. Sections
|
|
14
|
-
// with no content are omitted entirely (no empty headers in the wire).
|
|
15
|
-
import { MimetypeBinary } from "../content/index.js";
|
|
16
|
-
import { renderAddress } from "./plurnk-uri.js";
|
|
17
|
-
import { encodePathParens } from "./path-decode.js";
|
|
7
|
+
// Format and omission rules are owned by {§packet-markdown}. Section producers
|
|
8
|
+
// supply names and typed content; this projection preserves their ordered evidence.
|
|
9
|
+
import { Validator } from "@plurnk/plurnk-contracts";
|
|
10
|
+
import { renderTarget } from "./plurnk-uri.js";
|
|
11
|
+
import LogBody from "./LogBody.js";
|
|
12
|
+
import { assertEditReceipt, assertResourceEffects, } from "../content/index.js";
|
|
18
13
|
const editReceiptRevisionChars = () => {
|
|
19
14
|
const raw = process.env.PLURNK_SERVICE_EDIT_RECEIPT_REVISION_CHARS;
|
|
20
15
|
const value = Number(raw);
|
|
@@ -23,9 +18,22 @@ const editReceiptRevisionChars = () => {
|
|
|
23
18
|
}
|
|
24
19
|
return value;
|
|
25
20
|
};
|
|
21
|
+
const previewBounds = () => {
|
|
22
|
+
const rawLines = process.env.PLURNK_SERVICE_PREVIEW_LINES;
|
|
23
|
+
const rawChars = process.env.PLURNK_SERVICE_PREVIEW_CHARS;
|
|
24
|
+
const lines = Number(rawLines);
|
|
25
|
+
const chars = Number(rawChars);
|
|
26
|
+
if (!Number.isSafeInteger(lines) || lines < 1) {
|
|
27
|
+
throw new Error(`PLURNK_SERVICE_PREVIEW_LINES must be a positive safe integer, got ${JSON.stringify(rawLines)}`);
|
|
28
|
+
}
|
|
29
|
+
if (!Number.isSafeInteger(chars) || chars < 1) {
|
|
30
|
+
throw new Error(`PLURNK_SERVICE_PREVIEW_CHARS must be a positive safe integer, got ${JSON.stringify(rawChars)}`);
|
|
31
|
+
}
|
|
32
|
+
return { lines, chars };
|
|
33
|
+
};
|
|
26
34
|
export default class PacketWire {
|
|
27
|
-
// Render the sections in `slot` to one ChatMessage.content
|
|
28
|
-
// render in list order; empties are omitted (no empty headers on the wire);
|
|
35
|
+
// {§packet-markdown} Render the sections in `slot` to one ChatMessage.content
|
|
36
|
+
// string. Sections render in list order; empties are omitted (no empty headers on the wire);
|
|
29
37
|
// each is `## {header}\n\n{content}` (or bare content when header is null),
|
|
30
38
|
// trailing newlines stripped, joined with a blank line.
|
|
31
39
|
static renderSlot(sections, slot) {
|
|
@@ -45,15 +53,35 @@ export default class PacketWire {
|
|
|
45
53
|
const header = typeof s.header === "string" && s.header.length > 0 ? s.header : null;
|
|
46
54
|
return (header ? `## ${header}\n\n${s.content}` : s.content).replace(/\n+$/, "");
|
|
47
55
|
}
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
// Durable operation failures render as terse pointers to the log rows that
|
|
57
|
+
// own their exact RFC 9457 results.
|
|
58
|
+
static renderFailurePointers(failures) {
|
|
59
|
+
const rows = Array.isArray(failures) ? failures : [];
|
|
60
|
+
return rows
|
|
61
|
+
.filter((row) => typeof row.status === "number" && typeof row.coordinate === "string")
|
|
62
|
+
.map((row) => `* ${row.status} log:///${row.coordinate}`)
|
|
63
|
+
.join("\n");
|
|
55
64
|
}
|
|
56
|
-
//
|
|
65
|
+
// Non-terminal model-facing observations are deliberately separate from
|
|
66
|
+
// operation failures. Producer messages are normalized and bounded by the
|
|
67
|
+
// shared preview limit; typed positions remain legible.
|
|
68
|
+
static renderNotices(notices) {
|
|
69
|
+
const observations = Array.isArray(notices) ? notices : [];
|
|
70
|
+
return observations.map((notice) => {
|
|
71
|
+
const kind = typeof notice.kind === "string" ? notice.kind : "notice";
|
|
72
|
+
const rawMessage = typeof notice.message === "string"
|
|
73
|
+
? notice.message.replace(/\s+/g, " ").trim()
|
|
74
|
+
: "";
|
|
75
|
+
const message = rawMessage.length > 0
|
|
76
|
+
? PacketWire.#preview(rawMessage).text
|
|
77
|
+
: "";
|
|
78
|
+
const position = notice.position?.type === "content-offset"
|
|
79
|
+
? ` @ ${String(notice.position.line)}:${String(notice.position.column)}`
|
|
80
|
+
: "";
|
|
81
|
+
return `* ${kind}${message.length > 0 ? `: ${message}` : ""}${position}`;
|
|
82
|
+
}).join("\n");
|
|
83
|
+
}
|
|
84
|
+
// The Child Streams / Active Child Workers sections ({§child-orientation}) — the OPPOSITE of advice: terse
|
|
57
85
|
// `* <status> <path>` pointers (same shape as the errors section) to the live things the worker holds,
|
|
58
86
|
// so the model SEES its open streams + unconcluded workers each turn and reasons for itself (READ /
|
|
59
87
|
// OPEN / KILL via the path). Orienting state, never an instruction. "" when none → section omitted.
|
|
@@ -62,10 +90,14 @@ export default class PacketWire {
|
|
|
62
90
|
return items.map((r) => `* ${String(r.status)} ${String(r.path)}`).join("\n");
|
|
63
91
|
}
|
|
64
92
|
// The git section content: the working-tree summary. "" when absent.
|
|
65
|
-
static renderGit(git) {
|
|
66
|
-
|
|
93
|
+
static renderGit(git, assignedBranch = null) {
|
|
94
|
+
const status = git === null || git === undefined ? "" : PacketWire.#renderGitState(git);
|
|
95
|
+
const assignment = assignedBranch === null
|
|
96
|
+
? ""
|
|
97
|
+
: `assigned branch \`${assignedBranch}\` — commit any project changes and leave the checkout clean before concluding`;
|
|
98
|
+
return [status, assignment].filter((line) => line.length > 0).join("\n");
|
|
67
99
|
}
|
|
68
|
-
// The log section's content: the model's curated rows as a fenced `jsonplurnk` array (§jsonplurnk).
|
|
100
|
+
// The log section's content: the model's curated rows as a fenced `jsonplurnk` array ({§jsonplurnk}).
|
|
69
101
|
// Data only — no prose leads the fence (the log carries rules for no one). Empty log → ""
|
|
70
102
|
// (the section is omitted).
|
|
71
103
|
static renderLog(entries, countTokens) {
|
|
@@ -73,9 +105,9 @@ export default class PacketWire {
|
|
|
73
105
|
if (log.length === 0)
|
|
74
106
|
return "";
|
|
75
107
|
const items = PacketWire.#renderLogEntries(log, countTokens);
|
|
76
|
-
// The opening fence is DYNAMIC — one backtick longer than the longest run in
|
|
77
|
-
// code sample inside a body can never close the block early (CommonMark closes
|
|
78
|
-
// a line of ≥ its own length). §jsonplurnk-dynamic-fence
|
|
108
|
+
// The opening fence is DYNAMIC — one backtick longer than the longest run in the rendered
|
|
109
|
+
// entries — so a code sample inside a body can never close the block early (CommonMark closes
|
|
110
|
+
// a fence only on a line of ≥ its own length). {§jsonplurnk-dynamic-fence}
|
|
79
111
|
const longestTicks = Math.max(0, ...[...items.matchAll(/`+/g)].map((m) => m[0].length));
|
|
80
112
|
const fence = "`".repeat(Math.max(3, longestTicks + 1));
|
|
81
113
|
return `${fence}jsonplurnk\n[\n${items}\n]\n${fence}`;
|
|
@@ -97,64 +129,8 @@ export default class PacketWire {
|
|
|
97
129
|
{ role: "user", content: PacketWire.renderSlot(sections, "user") },
|
|
98
130
|
];
|
|
99
131
|
}
|
|
100
|
-
// Measure the curatable log section's budget subtotals from the STRUCTURED
|
|
101
|
-
// log (the foldable unit), using the provider's tokenizer — meta lines and
|
|
102
|
-
// fences included, matching what ships. Feeds the per-turn rollup (chronological;
|
|
103
|
-
// the grinder folds the newest turn) and the FOLD unit (heaviest entries) — the
|
|
104
|
-
// two budget levers the model can pull (§tokenomics {§tokenomics-turn-totals},
|
|
105
|
-
// {§tokenomics-largest-entries}). Build-time only; the stored log section is
|
|
106
|
-
// the rendered result. §tokenomics-render-weight-budget
|
|
107
|
-
static measureLogBudget(entries, countTokens) {
|
|
108
|
-
const logEntries = Array.isArray(entries) ? entries : [];
|
|
109
|
-
const logBody = logEntries.length > 0 ? PacketWire.renderLog(logEntries, countTokens) : "";
|
|
110
|
-
const HEAVIEST_COUNT = 5;
|
|
111
|
-
const currentLoop = logEntries.reduce((max, e) => {
|
|
112
|
-
const l = typeof e.coordinate === "string" ? Number(e.coordinate.split("/")[0]) : NaN;
|
|
113
|
-
return Number.isFinite(l) && l > max ? l : max;
|
|
114
|
-
}, 0);
|
|
115
|
-
const byTurn = new Map();
|
|
116
|
-
const perEntry = [];
|
|
117
|
-
for (const e of logEntries) {
|
|
118
|
-
// Two weights, two purposes (#466 — one labeled semantic per number): the row's FULL
|
|
119
|
-
// render (meta line + fences + body) composes the turn rollup — the room the turn takes in
|
|
120
|
-
// the packet; the heaviest list carries the row's BODY weight — the FOLD unit, the SAME
|
|
121
|
-
// number the row's own `tokens` shows, so the budget and the log can never disagree
|
|
122
|
-
// about one row. A row ranks ONLY when a FOLD would actually reclaim it: a bodyless
|
|
123
|
-
// row has nothing to fold, an already-folded row is already reclaimed (its price is
|
|
124
|
-
// an OPEN's cost), and the current loop's foisted preview is refused (§prompt-fold-
|
|
125
|
-
// illegal) — listing any of these sells the model a lever that 403s or no-ops.
|
|
126
|
-
const bodyPrice = [];
|
|
127
|
-
const weight = countTokens(PacketWire.#renderLogEntries([e], countTokens, bodyPrice));
|
|
128
|
-
const coordinate = typeof e.coordinate === "string" ? e.coordinate : null;
|
|
129
|
-
const op = typeof e.op === "string" && e.op.length > 0 ? e.op : null;
|
|
130
|
-
// Turn = the loop_seq/turn_seq prefix of the coordinate
|
|
131
|
-
// (log:///<loop_seq>/<turn_seq>/<sequence>); the sequence drops off.
|
|
132
|
-
if (coordinate !== null) {
|
|
133
|
-
const turn = coordinate.split("/").slice(0, 2).join("/");
|
|
134
|
-
byTurn.set(turn, (byTurn.get(turn) ?? 0) + weight);
|
|
135
|
-
}
|
|
136
|
-
const path = PacketWire.#entryPath(coordinate, op);
|
|
137
|
-
const isPreview = e.target?.scheme === "prompt" && e.origin === "plurnk" && op === "READ"
|
|
138
|
-
&& coordinate !== null && Number(coordinate.split("/")[0]) === currentLoop;
|
|
139
|
-
const foldable = e.folded !== true && !isPreview;
|
|
140
|
-
if (path !== null && foldable && (bodyPrice[0] ?? 0) > 0)
|
|
141
|
-
perEntry.push({ path, tokens: bodyPrice[0] });
|
|
142
|
-
}
|
|
143
|
-
return {
|
|
144
|
-
entries: logEntries.length,
|
|
145
|
-
tokens: logBody ? countTokens(`## Plurnk Service Log\n\n${logBody}`) : 0,
|
|
146
|
-
byTurn: [...byTurn.entries()]
|
|
147
|
-
.map(([turn, tokens]) => ({ turn, tokens }))
|
|
148
|
-
.toSorted((a, b) => {
|
|
149
|
-
const [al, at] = a.turn.split("/").map(Number);
|
|
150
|
-
const [bl, bt] = b.turn.split("/").map(Number);
|
|
151
|
-
return al - bl || at - bt;
|
|
152
|
-
}),
|
|
153
|
-
largest: perEntry.toSorted((a, b) => b.tokens - a.tokens).slice(0, HEAVIEST_COUNT),
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
132
|
// Number each line of body as `<N>:<line>` — a bare `N:` prefix, NO separator whitespace
|
|
157
|
-
// (
|
|
133
|
+
// ({§render-rule-line-navigable-prefix}): the leading digit prevents column-zero fence collisions and gives
|
|
158
134
|
// the model line refs for free (`READ<42-46>`), while the absence of any separator means a
|
|
159
135
|
// reproduced line has nothing between `N:` and the content to copy — the hard-tab separator used
|
|
160
136
|
// to leak into edit bodies and corrupt indentation. The content's OWN leading whitespace is
|
|
@@ -162,32 +138,25 @@ export default class PacketWire {
|
|
|
162
138
|
// Used for READ@200 content; index-preview numbering is the framework's
|
|
163
139
|
// job now (baked into the preview string — see renderHeredoc).
|
|
164
140
|
static #numberLines(body, start = 1) {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
const trailingNewline = body.endsWith("\n");
|
|
168
|
-
const source = trailingNewline ? body.slice(0, -1) : body;
|
|
169
|
-
const numbered = source.split("\n").map((line, i) => `${start + i}:${line}`).join("\n");
|
|
170
|
-
return trailingNewline ? `${numbered}\n` : numbered;
|
|
141
|
+
let line = start;
|
|
142
|
+
return body.replace(/(^|\r\n|\r|\n)(?=[\s\S])/g, (separator) => `${separator}${line++}:`);
|
|
171
143
|
}
|
|
172
144
|
// The single content-body renderer EVERY output-emitting op routes through, so the line-number
|
|
173
|
-
// convention the model orients on can't drift
|
|
174
|
-
// prefix from `startLine`;
|
|
175
|
-
//
|
|
176
|
-
static #renderContentBody(fence, content,
|
|
145
|
+
// convention the model orients on can't drift. Every textual body receives
|
|
146
|
+
// the `N:` prefix from `startLine`; matchers consume canonical content before
|
|
147
|
+
// this presentation projection. Empty content produces no body.
|
|
148
|
+
static #renderContentBody(fence, content, startLine = 1) {
|
|
177
149
|
if (content.length === 0)
|
|
178
150
|
return "";
|
|
179
|
-
//
|
|
180
|
-
//
|
|
181
|
-
|
|
182
|
-
// (one source-line prefix). Render verbatim. §render-rule-line-navigable-prefix
|
|
183
|
-
const rendered = MimetypeBinary.isLineNavigableMimetype(mimetype) && startLine !== null
|
|
151
|
+
// `startLine === null` means the producer already supplied numbered
|
|
152
|
+
// content; re-numbering would duplicate its coordinates.
|
|
153
|
+
const rendered = startLine !== null
|
|
184
154
|
? PacketWire.#numberLines(content, startLine)
|
|
185
155
|
: content;
|
|
186
156
|
return PacketWire.#wrapHeredocBody(fence, rendered);
|
|
187
157
|
}
|
|
188
|
-
// Tolerant JSON parser for log entries' rx/tx
|
|
189
|
-
// pre-parses application/json mimetypes
|
|
190
|
-
// strings (legacy paths, manual tests). Returns null on parse failure.
|
|
158
|
+
// Tolerant JSON parser for log entries' persisted rx/tx strings. The engine
|
|
159
|
+
// pre-parses application/json mimetypes; malformed stored text is not JSON.
|
|
191
160
|
static #safeParse(s) {
|
|
192
161
|
try {
|
|
193
162
|
return JSON.parse(s);
|
|
@@ -197,8 +166,7 @@ export default class PacketWire {
|
|
|
197
166
|
}
|
|
198
167
|
}
|
|
199
168
|
// Stable JSON: keys sorted alphabetically so the same meta produces the
|
|
200
|
-
// same string across turns — prefix-cache friendly.
|
|
201
|
-
// plugins/helpers.js canonicalJson.
|
|
169
|
+
// same string across turns — prefix-cache friendly.
|
|
202
170
|
static #canonicalJson(obj) {
|
|
203
171
|
const keys = Object.keys(obj).sort();
|
|
204
172
|
const sorted = {};
|
|
@@ -206,107 +174,81 @@ export default class PacketWire {
|
|
|
206
174
|
sorted[k] = obj[k];
|
|
207
175
|
return JSON.stringify(sorted);
|
|
208
176
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
177
|
+
static #receiptMeta(value) {
|
|
178
|
+
const receipt = assertEditReceipt(value);
|
|
179
|
+
const head = {
|
|
180
|
+
rev: receipt.revision.slice(0, editReceiptRevisionChars()),
|
|
181
|
+
extent: `${receipt.unit} ${receipt.before}->${receipt.after}`,
|
|
182
|
+
};
|
|
183
|
+
if ("effect" in receipt) {
|
|
184
|
+
return {
|
|
185
|
+
...head,
|
|
186
|
+
change: `-${receipt.effect.removed} +${receipt.effect.inserted}`,
|
|
187
|
+
range: `${receipt.effect.requested} ${receipt.effect.source}->${receipt.effect.result}`,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
return {
|
|
191
|
+
...head,
|
|
192
|
+
disposition: receipt.disposition,
|
|
193
|
+
requested: receipt.requested,
|
|
194
|
+
...(receipt.replacement === undefined
|
|
195
|
+
? {}
|
|
196
|
+
: {
|
|
197
|
+
change: `-${receipt.replacement.removed} +${receipt.replacement.inserted}`,
|
|
198
|
+
replacement: `${receipt.replacement.requested} ${receipt.replacement.source}->${receipt.replacement.result}`,
|
|
199
|
+
}),
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
// Wrap a body in heredoc fences. The fence is FIXED (`<<BODY`/`BODY`), never the
|
|
203
|
+
// target: every body line is `N:`-prefixed, so a bare fence line can never occur
|
|
204
|
+
// inside a body, and a fixed fence gives the model nothing address-shaped to
|
|
205
|
+
// mimic back as op syntax — identity lives in the adjacent meta JSON. Leading
|
|
206
|
+
// `\n` always (separates the opening fence from the first body character).
|
|
207
|
+
// Trailing `\n` only when the body doesn't already end with one — otherwise you
|
|
208
|
+
// get a doubled newline that renders as a blank line before the closing fence,
|
|
209
|
+
// which reads as "the content has a trailing blank line" when actually it
|
|
216
210
|
// doesn't. The body's own whitespace decides the shape.
|
|
217
211
|
static #wrapHeredocBody(fence, body) {
|
|
218
212
|
const sep = body.endsWith("\n") ? "" : "\n";
|
|
219
|
-
return
|
|
220
|
-
}
|
|
221
|
-
// Heredoc block for one channel of one entry. Fence is `URI#channel`
|
|
222
|
-
// (the `<<:::FENCE` packet-rendering marker per wrapHeredocBody — a
|
|
223
|
-
// projection is read-only context, NOT an emittable op, so it must not
|
|
224
|
-
// wear the DSL op-fence; that conflation was the demo.sh corruption bug).
|
|
225
|
-
// When `channel` is null/empty the fence is path-only —
|
|
226
|
-
// this is the default-channel convention: the absence of `#channel` is
|
|
227
|
-
// the addressing of the scheme's default channel, not a missing field.
|
|
228
|
-
// Body is a mimetypes preview, rendered VERBATIM — the framework owns its
|
|
229
|
-
// formatting (N: line numbers for text, source-annotated outline for
|
|
230
|
-
// symbols, correct start-line for tail slices) and bakes it into the
|
|
231
|
-
// preview string as of mimetypes 0.7.3, so the service must not re-number
|
|
232
|
-
// it (re-numbering would double-prefix text and mis-number symbol
|
|
233
|
-
// outlines — plurnk-mimetypes#8).
|
|
234
|
-
static #renderHeredoc(uri, channel, body) {
|
|
235
|
-
const fence = channel ? `${uri}#${channel}` : uri;
|
|
236
|
-
return PacketWire.#wrapHeredocBody(fence, body);
|
|
237
|
-
}
|
|
238
|
-
// Render a (scheme, pathname) tuple as the URI the model should SEE.
|
|
239
|
-
// Null scheme → bare pathname. The `file` scheme never reaches this
|
|
240
|
-
// function because Dispatcher.#extractTarget normalizes it to null at the
|
|
241
|
-
// storage boundary; storage and wire output are uniform on this.
|
|
242
|
-
static #renderModelUri(scheme, pathname) {
|
|
243
|
-
const path = pathname ?? "";
|
|
244
|
-
// #370 — a null scheme is a workspace file, whose member key is /rel but whose MODEL-FACING
|
|
245
|
-
// form is the bare relative path (the catalog lists data/users.json; FIND returns it; the
|
|
246
|
-
// model types it). Rendering /data/users.json minted a second spelling of the same file.
|
|
247
|
-
if (scheme === null || scheme === undefined)
|
|
248
|
-
return encodePathParens(path.replace(/^\//, ""));
|
|
249
|
-
return renderAddress(scheme, path);
|
|
213
|
+
return `<<BODY\n${body}${sep}BODY`;
|
|
250
214
|
}
|
|
251
215
|
// Render one Log entry → a single bullet line carrying the meta JSON.
|
|
252
216
|
// No body, no fence — every meaningful field is in the JSON. Naming
|
|
253
217
|
// follows the uniform principle: `path` is identity (this log row's
|
|
254
|
-
// own URI), `target` is the URI the
|
|
255
|
-
//
|
|
256
|
-
//
|
|
218
|
+
// own URI), `target` is the URI in the statement's target slot. COPY/MOVE
|
|
219
|
+
// retain their source and destination selections separately from ordered
|
|
220
|
+
// applied `effects`.
|
|
257
221
|
//
|
|
258
|
-
// On error, status >= 400 signals the failure;
|
|
259
|
-
// the next packet's
|
|
260
|
-
// meta will gain tokensBefore/After + linesBefore/After to convey
|
|
261
|
-
// change scope without carrying the body content.)
|
|
222
|
+
// On error, status >= 400 signals the failure; Problem Details live on
|
|
223
|
+
// this durable row and the next packet's Errors section points here.
|
|
262
224
|
//
|
|
263
|
-
// Per-entry render: one meta JSON line plus
|
|
264
|
-
//
|
|
265
|
-
//
|
|
266
|
-
//
|
|
267
|
-
//
|
|
268
|
-
// 2. Every other op → re-emit tx as a heredoc in the model's native
|
|
269
|
-
// syntax. The model wrote this; mirror it back so the log is a true
|
|
270
|
-
// record of its actions instead of a row of opaque status codes.
|
|
271
|
-
// The log:/// handle the model sees for an entry — its FOLD target
|
|
272
|
-
// (§open-fold) and the label the budget's heaviest-entries readout reuses,
|
|
273
|
-
// so the readout names an entry exactly as the log does.
|
|
225
|
+
// Per-entry render: one meta JSON line plus the row's canonical body.
|
|
226
|
+
// LogBody owns tx/rx storage interpretation; packet projection owns only
|
|
227
|
+
// visibility, previewing, mimetype rendering, and metadata.
|
|
228
|
+
// The log:/// handle the model sees for an entry.
|
|
229
|
+
// ({§open-fold}).
|
|
274
230
|
static #entryPath(coordinate, op) {
|
|
275
231
|
if (coordinate === null)
|
|
276
232
|
return null;
|
|
277
233
|
return op !== null ? `log:///${coordinate}/${op}` : `log:///${coordinate}`;
|
|
278
234
|
}
|
|
279
|
-
//
|
|
280
|
-
//
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
// §arrival-law (#566): a model-COMPOSED op body — a PLAN/SEND/WORK/FORK's text or an EXEC
|
|
295
|
-
// command — renders PREVIEW-bounded, so the model can never compose an unbounded OPEN log row.
|
|
296
|
-
// run42: an unclosed `<<PLAN` swallowed a 57k-char runaway into ONE 29k open row the grinder is
|
|
297
|
-
// forbidden to fold (op NOT IN … 'PLAN') — a permanent budget bomb that pushed the packet past
|
|
298
|
-
// the physical window and gated out the recovery. CONTENT ops are exempt and render FULL —
|
|
299
|
-
// READ/FIND (retrieved bytes; capping a READ would break its `<start,end>` slice contract) and
|
|
300
|
-
// EDIT/COPY/MOVE spans (the resulting file content the model inspects). The verbatim emission
|
|
301
|
-
// always survives in the folded `model` mirror, so nothing is lost; a cut states the true extent.
|
|
302
|
-
static #renderAuthoredBody(logAddr, body, preNumbered) {
|
|
303
|
-
const arrival = PacketWire.#arrivalPreview(body);
|
|
304
|
-
const rendered = preNumbered
|
|
305
|
-
? PacketWire.#wrapHeredocBody(logAddr, arrival.text)
|
|
306
|
-
: PacketWire.#renderContentBody(logAddr, arrival.text, "text/plain");
|
|
307
|
-
return arrival.cut ? `${rendered}\n… preview — the full body is ${body.split("\n").length} line(s)` : rendered;
|
|
235
|
+
// One preview function for every bounded model-facing projection. Lines
|
|
236
|
+
// protect ordinary documents and chars protect a single-line bomb.
|
|
237
|
+
static #preview(text) {
|
|
238
|
+
const { lines: maxLines, chars: maxChars } = previewBounds();
|
|
239
|
+
let lineEnd = text.length;
|
|
240
|
+
let newline = -1;
|
|
241
|
+
for (let line = 0; line < maxLines; line++) {
|
|
242
|
+
newline = text.indexOf("\n", newline + 1);
|
|
243
|
+
if (newline === -1)
|
|
244
|
+
break;
|
|
245
|
+
if (line === maxLines - 1)
|
|
246
|
+
lineEnd = newline + 1;
|
|
247
|
+
}
|
|
248
|
+
const end = Math.min(text.length, lineEnd, maxChars);
|
|
249
|
+
return { text: text.slice(0, end), cut: end < text.length };
|
|
308
250
|
}
|
|
309
|
-
static #renderLogEntries(entries, countTokens
|
|
251
|
+
static #renderLogEntries(entries, countTokens) {
|
|
310
252
|
return entries.map((e) => {
|
|
311
253
|
const meta = {};
|
|
312
254
|
const coordinate = typeof e.coordinate === "string" ? e.coordinate : null;
|
|
@@ -322,214 +264,197 @@ export default class PacketWire {
|
|
|
322
264
|
&& e.attrs !== null && typeof e.attrs === "object"
|
|
323
265
|
&& e.attrs.kind === "entry_materialized";
|
|
324
266
|
const renderedOp = materializedEntry ? "READ" : op;
|
|
267
|
+
const modelEmission = op === null
|
|
268
|
+
&& e.attrs !== null && typeof e.attrs === "object"
|
|
269
|
+
&& e.attrs.kind === "model_emission";
|
|
325
270
|
const path = PacketWire.#entryPath(coordinate, renderedOp);
|
|
326
271
|
if (path !== null)
|
|
327
272
|
meta.path = path;
|
|
328
273
|
if (typeof e.origin === "string")
|
|
329
274
|
meta.origin = e.origin;
|
|
330
|
-
// §env-delta: the
|
|
331
|
-
//
|
|
275
|
+
// {§env-delta-attribution}: render the causal worker address or
|
|
276
|
+
// subsystem token when present; absence means the owning worker.
|
|
332
277
|
if (typeof e.source === "string" && e.source.length > 0)
|
|
333
|
-
meta.
|
|
278
|
+
meta.source = e.source;
|
|
334
279
|
if (renderedOp !== null)
|
|
335
280
|
meta.op = renderedOp;
|
|
281
|
+
if (modelEmission)
|
|
282
|
+
meta.kind = "model_emission";
|
|
283
|
+
if (e.source === "file" && e.attrs !== null && typeof e.attrs === "object" && "git" in e.attrs) {
|
|
284
|
+
const git = e.attrs.git;
|
|
285
|
+
if (typeof git !== "string" || git.length !== 2) {
|
|
286
|
+
throw new TypeError("A source=file log row carries malformed Git XY metadata.");
|
|
287
|
+
}
|
|
288
|
+
meta.git = git;
|
|
289
|
+
}
|
|
336
290
|
if (typeof e.status === "number")
|
|
337
291
|
meta.status = e.status;
|
|
292
|
+
const tx = (typeof e.tx === "string" ? PacketWire.#safeParse(e.tx) : e.tx);
|
|
338
293
|
const target = PacketWire.#renderActionTarget(e.target);
|
|
339
|
-
if (
|
|
340
|
-
|
|
341
|
-
|
|
294
|
+
if (op === "COPY" || op === "MOVE") {
|
|
295
|
+
const source = PacketWire.#renderSelection(e.target ?? tx?.target, tx?.lineMarker);
|
|
296
|
+
const destinationBody = tx?.body !== null && typeof tx?.body === "object"
|
|
297
|
+
? tx.body
|
|
298
|
+
: null;
|
|
299
|
+
const destination = PacketWire.#renderSelection(destinationBody?.target, destinationBody?.lineMarker);
|
|
300
|
+
if (source !== null)
|
|
301
|
+
meta.source = source;
|
|
302
|
+
if (destination !== null)
|
|
303
|
+
meta.destination = destination;
|
|
304
|
+
if (typeof e.status === "number"
|
|
305
|
+
&& e.status < 400
|
|
306
|
+
&& (source === null || destination === null)) {
|
|
307
|
+
throw new Error(`A successful ${op} log row must retain both operand selections.`);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
if (target !== null)
|
|
312
|
+
meta.target = target;
|
|
313
|
+
}
|
|
314
|
+
// EXEC's output is a separate stream entry ({§exec-stream}); its address rides in a
|
|
342
315
|
// `stream` link, distinct from `target` (the cwd / executable path it ran in).
|
|
343
316
|
if (op === "EXEC" && e.attrs !== null && typeof e.attrs === "object" && typeof e.attrs.stream === "string") {
|
|
344
317
|
meta.stream = e.attrs.stream;
|
|
345
318
|
}
|
|
346
319
|
// Parse rx once — reused for the matcher/items enrichment and the body.
|
|
347
320
|
const rx = (typeof e.rx === "string" ? PacketWire.#safeParse(e.rx) : e.rx);
|
|
348
|
-
// §log-row-self-explains — a
|
|
349
|
-
//
|
|
350
|
-
// status; the message buried in an rx no render shows) is what sent the wildcard model
|
|
351
|
-
// theorizing "SEND[409] probably means bad request?" for 201s, and the jumbo model
|
|
352
|
-
// chasing a phantom "engine error" off a message-less item. The row IS the model's op
|
|
353
|
-
// result — it states its own why; the errors section stays a terse pointer at it.
|
|
321
|
+
// {§log-row-self-explains} — a failed operation projects its exact
|
|
322
|
+
// Problem on the row meta line; Errors remains only an index.
|
|
354
323
|
if (typeof e.status === "number" && e.status >= 400 && rx !== null && typeof rx === "object") {
|
|
355
|
-
const
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
meta.error = text;
|
|
324
|
+
const problem = rx.problem;
|
|
325
|
+
Validator.assertProblemDetails(problem);
|
|
326
|
+
meta.problem = problem;
|
|
359
327
|
}
|
|
360
|
-
//
|
|
361
|
-
//
|
|
362
|
-
|
|
363
|
-
// nor weigh a re-FIND. `matches` when the dispatch tallied it; else a FIND
|
|
364
|
-
// body is a JSON array whose length IS the count.
|
|
365
|
-
let items = null;
|
|
328
|
+
// {§retrieval-packet-metadata}: one extent/coordinate owner plus
|
|
329
|
+
// only FIND aggregates that add information beyond that extent.
|
|
330
|
+
let findItems = null;
|
|
366
331
|
if (op === "READ" || op === "FIND") {
|
|
367
|
-
const
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
332
|
+
const findMatcher = op === "FIND"
|
|
333
|
+
&& tx !== null
|
|
334
|
+
&& tx !== undefined
|
|
335
|
+
&& typeof tx === "object"
|
|
336
|
+
&& tx.body !== null
|
|
337
|
+
&& typeof tx.body === "object";
|
|
338
|
+
if (findMatcher) {
|
|
339
|
+
const body = tx?.body;
|
|
340
|
+
if (body !== null && typeof body === "object" && typeof body.raw === "string") {
|
|
341
|
+
meta.matcher = body.raw;
|
|
342
|
+
}
|
|
377
343
|
}
|
|
378
|
-
|
|
344
|
+
if (op === "FIND" && rx !== null && typeof rx === "object" && typeof rx.content === "string") {
|
|
379
345
|
const parsed = PacketWire.#safeParse(rx.content);
|
|
380
346
|
if (Array.isArray(parsed))
|
|
381
|
-
|
|
347
|
+
findItems = parsed.length;
|
|
382
348
|
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
349
|
+
const range = rx !== null && typeof rx === "object" && rx.range !== undefined
|
|
350
|
+
? rx.range
|
|
351
|
+
: undefined;
|
|
352
|
+
const problemOwnsRange = typeof e.status === "number"
|
|
353
|
+
&& e.status >= 400
|
|
354
|
+
&& meta.problem !== null
|
|
355
|
+
&& typeof meta.problem === "object"
|
|
356
|
+
&& Object.hasOwn(meta.problem, "range");
|
|
357
|
+
if (problemOwnsRange) {
|
|
358
|
+
Validator.assertRangeExtent(meta.problem.range);
|
|
387
359
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
// an open row that's what a FOLD would save, for a folded row what an OPEN would cost.
|
|
391
|
-
// "" ⇒ genuinely no body (an empty FIND, an empty EDIT span, a @204).
|
|
392
|
-
let body = "";
|
|
393
|
-
if (op === "FIND" && e.status === 200 && items === 0) {
|
|
394
|
-
// Empty FIND result → no body. items:0 already says "empty"; rendering [] under a
|
|
395
|
-
// fence is redundant noise. (The always-foisted empty known:///** / unknown:///**
|
|
396
|
-
// workspace rows are the common case.)
|
|
397
|
-
body = "";
|
|
398
|
-
}
|
|
399
|
-
else if ((op === "READ" || op === "FIND") && e.status === 200 &&
|
|
400
|
-
rx !== null && typeof rx === "object" && typeof rx.content === "string" && rx.content.length > 0) {
|
|
401
|
-
// READ@200 / FIND@200: the content READ pulled, or the catalog rows / matched
|
|
402
|
-
// entries FIND returned (§render-rule-find-renders-result) — the turn-0 foisted
|
|
403
|
-
// FIND(scheme:///**) reaches the packet here, as does the exec-stream injector's
|
|
404
|
-
// foisted READ of the channel. #renderContentBody applies the line-number convention
|
|
405
|
-
// (§render-rule-line-navigable-prefix / §render-rule-tree-navigable-verbatim).
|
|
406
|
-
const mimetype = typeof rx.mimetype === "string" ? rx.mimetype : "text/plain";
|
|
407
|
-
// startLine === null is the matcher-result signal (already source-numbered → verbatim);
|
|
408
|
-
// a number numbers from it; absent → 1 (whole-content default).
|
|
409
|
-
const start = rx.startLine === null ? null : (typeof rx.startLine === "number" ? rx.startLine : 1);
|
|
410
|
-
// §arrival-law — a foisted READ of a prompt path is PUSHED content (user- or
|
|
411
|
-
// sibling-authored); the render-side preview bounds it like any arrival, closing
|
|
412
|
-
// the single-line char-bomb the line-slice alone cannot cut (line markers cannot
|
|
413
|
-
// cut mid-line; the render can). Model-authored READs stay self-invited — untouched.
|
|
414
|
-
const promptPush = e.origin === "plurnk" && op === "READ"
|
|
415
|
-
&& e.target !== null && typeof e.target === "object" && e.target.scheme === "prompt";
|
|
416
|
-
const streamPush = e.origin === "plurnk" && op === "READ" && mimetype === "text/stream";
|
|
417
|
-
if (promptPush || streamPush) {
|
|
418
|
-
const arrival = PacketWire.#arrivalPreview(rx.content);
|
|
419
|
-
body = PacketWire.#renderContentBody(target ?? `log:///${coordinate}`, arrival.text, mimetype, start);
|
|
420
|
-
if (arrival.cut) {
|
|
421
|
-
const noun = streamPush ? "stream output" : "prompt";
|
|
422
|
-
body += `\n… arrival preview — the full ${noun} is ${rx.content.split("\n").length} line(s), ${rx.content.length} chars: READ ${target}`;
|
|
423
|
-
}
|
|
360
|
+
if (range !== undefined && !problemOwnsRange) {
|
|
361
|
+
meta.range = Validator.assertRangeExtent(range);
|
|
424
362
|
}
|
|
425
|
-
else {
|
|
426
|
-
|
|
363
|
+
else if (op === "READ" && rx !== null && typeof rx === "object" && rx.region !== undefined) {
|
|
364
|
+
meta.region = Validator.assertTextRegion(rx.region);
|
|
427
365
|
}
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
366
|
+
// These are underlying selected-content weights, distinct from
|
|
367
|
+
// the emitted body's generic `tokens` measurement.
|
|
368
|
+
if (op === "FIND" && rx !== null && typeof rx === "object" && typeof rx.itemsTokenTotal === "number" && rx.itemsTokenTotal > 0) {
|
|
369
|
+
meta.itemsTokenTotal = rx.itemsTokenTotal;
|
|
370
|
+
}
|
|
371
|
+
if (op === "FIND"
|
|
372
|
+
&& rx !== null
|
|
373
|
+
&& typeof rx === "object"
|
|
374
|
+
&& typeof rx.returnedItemsTokenTotal === "number"
|
|
375
|
+
&& rx.returnedItemsTokenTotal > 0
|
|
376
|
+
&& rx.returnedItemsTokenTotal !== rx.itemsTokenTotal) {
|
|
377
|
+
meta.returnedItemsTokenTotal = rx.returnedItemsTokenTotal;
|
|
378
|
+
}
|
|
379
|
+
if (findMatcher
|
|
380
|
+
&& range !== null
|
|
381
|
+
&& typeof range === "object"
|
|
382
|
+
&& range.unit === "resource"
|
|
383
|
+
&& rx !== null
|
|
384
|
+
&& typeof rx === "object"
|
|
385
|
+
&& typeof rx.matchLocationCount === "number"
|
|
386
|
+
&& rx.matchLocationCount > 0) {
|
|
387
|
+
meta.matchLocationCount = rx.matchLocationCount;
|
|
439
388
|
}
|
|
440
|
-
meta.rev = receipt.revision.slice(0, editReceiptRevisionChars());
|
|
441
|
-
meta.extent = `${receipt.unit} ${receipt.before}→${receipt.after}`;
|
|
442
|
-
meta.change = `-${effect.removed} +${effect.inserted}`;
|
|
443
|
-
meta.range = `${effect.requested} ${effect.source}→${effect.result}`;
|
|
444
|
-
if (effect.context.length > 0)
|
|
445
|
-
body = PacketWire.#wrapHeredocBody(target ?? `log:///${coordinate}`, effect.context);
|
|
446
|
-
}
|
|
447
|
-
else if ((op === "EDIT" || op === "COPY" || op === "MOVE") && rx !== null && typeof rx === "object" && (typeof rx.receipt === "string" || typeof rx.span === "string" || typeof rx.body === "string")) {
|
|
448
|
-
// EDIT renders its bounded effect receipt; COPY/MOVE and environment-delta
|
|
449
|
-
// EDITs retain their resulting span. Each is already line-addressed where
|
|
450
|
-
// appropriate, so wrapping is verbatim.
|
|
451
|
-
const r = rx;
|
|
452
|
-
const span = typeof r.receipt === "string" ? r.receipt : typeof r.span === "string" ? r.span : (r.body ?? "");
|
|
453
|
-
// An EDIT/COPY/MOVE span is the RESULTING file content — bytes the model inspects to
|
|
454
|
-
// confirm its edit landed, CONTENT not composed directive text — so it renders FULL
|
|
455
|
-
// like READ/FIND (#566). Grinder-foldable (not PLAN-exempt), so a large span reclaims.
|
|
456
|
-
if (span.length > 0)
|
|
457
|
-
body = PacketWire.#wrapHeredocBody(target ?? `log:///${coordinate}`, span);
|
|
458
389
|
}
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
390
|
+
// {§edit-result-receipt-projection} {§edit-result-copy-move-effects}
|
|
391
|
+
// Mutations expose compact, validated outcome metadata. EDIT owns
|
|
392
|
+
// one receipt; COPY/MOVE own ordered resource effects whose
|
|
393
|
+
// optional receipts describe scoped textual materializations.
|
|
394
|
+
if (op === "EDIT" && rx !== null && typeof rx === "object" && Object.hasOwn(rx, "receipt")) {
|
|
395
|
+
Object.assign(meta, PacketWire.#receiptMeta(rx.receipt));
|
|
464
396
|
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
if (opBody.length > 0)
|
|
477
|
-
body = PacketWire.#renderAuthoredBody(path ?? `log:///${coordinate}`, opBody, false);
|
|
478
|
-
// §worker-scheme-collect: an injected SEND (a child worker's concluded deliverable surfaced in
|
|
479
|
-
// the parent) has no authored tx body — its payload is the deliverable in rx (a raw string,
|
|
480
|
-
// not the {status} envelope a model SEND gets). Surface it so a child's 2xx reaches the
|
|
481
|
-
// parent OPEN (born-open at the insert), never a bodyless `*` row.
|
|
482
|
-
else if (op === "SEND" && opBody.length === 0 && typeof e.rx === "string" && e.rx.length > 0) {
|
|
483
|
-
// §arrival-law — the deliverable is PUSHED content: preview-bounded, never whole-by-default.
|
|
484
|
-
const arrival = PacketWire.#arrivalPreview(e.rx);
|
|
485
|
-
body = PacketWire.#renderContentBody(path ?? `log:///${coordinate}`, arrival.text, "text/plain");
|
|
486
|
-
if (arrival.cut)
|
|
487
|
-
body += `\n… arrival preview — the full deliverable is ${e.rx.split("\n").length} lines: READ worker://${(e.target && typeof e.target === "object" && "pathname" in e.target ? String(e.target.pathname ?? "") : "").replace(/^\//, "")}`;
|
|
488
|
-
}
|
|
397
|
+
if ((op === "COPY" || op === "MOVE")
|
|
398
|
+
&& rx !== null
|
|
399
|
+
&& typeof rx === "object"
|
|
400
|
+
&& Object.hasOwn(rx, "effects")) {
|
|
401
|
+
meta.effects = assertResourceEffects(rx.effects).map((effect) => ({
|
|
402
|
+
target: effect.target,
|
|
403
|
+
action: effect.action,
|
|
404
|
+
...(effect.receipt === undefined
|
|
405
|
+
? {}
|
|
406
|
+
: PacketWire.#receiptMeta(effect.receipt)),
|
|
407
|
+
}));
|
|
489
408
|
}
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
409
|
+
// The canonical full body is shared with READ(log://), FIND(log://),
|
|
410
|
+
// and search derivation. READ/FIND already own selection bounds and
|
|
411
|
+
// render complete; every other body uses this one preview projection.
|
|
412
|
+
const fullBody = LogBody.resolve({
|
|
413
|
+
op,
|
|
414
|
+
attrs: e.attrs,
|
|
415
|
+
tx: e.tx,
|
|
416
|
+
rx: e.rx,
|
|
417
|
+
mimetypeTx: typeof e.mimetype_tx === "string" ? e.mimetype_tx : undefined,
|
|
418
|
+
mimetypeRx: typeof e.mimetype_rx === "string" ? e.mimetype_rx : undefined,
|
|
419
|
+
});
|
|
420
|
+
const emptyFind = op === "FIND" && e.status === 200 && findItems === 0;
|
|
421
|
+
const previewExempt = op === "READ" || op === "FIND";
|
|
422
|
+
const projection = previewExempt
|
|
423
|
+
? { text: fullBody.content, cut: false }
|
|
424
|
+
: PacketWire.#preview(fullBody.content);
|
|
425
|
+
const resourceBody = op === "READ" || op === "FIND" || op === "EDIT"
|
|
426
|
+
|| op === "prompt";
|
|
427
|
+
const bodyFence = resourceBody ? (target ?? path) : path;
|
|
428
|
+
if (projection.cut && path === null) {
|
|
429
|
+
throw new Error("a previewed log body requires an addressable log path");
|
|
499
430
|
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
// what it produced. Line-numbered like all content (the parser reports errors by line,
|
|
503
|
-
// so the model can reason about its own syntax error). Folded by default → just the
|
|
504
|
-
// meta line until OPENed; the turn-0 exemplar is born open (the worked example).
|
|
505
|
-
if (rx !== null && typeof rx === "object" && typeof rx.content === "string" && rx.content.length > 0) {
|
|
506
|
-
const mimetype = typeof rx.mimetype === "string" ? rx.mimetype : "text/vnd.plurnk";
|
|
507
|
-
body = PacketWire.#renderContentBody(path ?? `log:///${coordinate}`, rx.content, mimetype);
|
|
508
|
-
}
|
|
431
|
+
if (projection.cut) {
|
|
432
|
+
meta.overflow = `Body content truncated. Full body: ${path}`;
|
|
509
433
|
}
|
|
434
|
+
const body = emptyFind || projection.text.length === 0
|
|
435
|
+
? ""
|
|
436
|
+
: PacketWire.#renderContentBody(bodyFence ?? `log:///${coordinate}`, projection.text, fullBody.startLine);
|
|
510
437
|
// tokens on EVERY row (0 when there's genuinely no body) so the model can always weigh
|
|
511
|
-
// it; for a folded row this is the room an OPEN would add.
|
|
512
|
-
if (items !== null)
|
|
513
|
-
meta.items = items;
|
|
438
|
+
// it; for a folded row this is the room an OPEN would add.
|
|
514
439
|
// 0 for a genuinely empty body — never call countTokens("") (some providers return
|
|
515
440
|
// undefined for it, which JSON.stringify would drop, leaving the row with no tokens).
|
|
516
441
|
meta.tokens = body.length > 0 ? countTokens(body) : 0;
|
|
517
|
-
|
|
518
|
-
// lines
|
|
519
|
-
//
|
|
520
|
-
|
|
521
|
-
if (body.length > 0) {
|
|
442
|
+
// lines beside tokens on a non-retrieval row with a navigable body — the count of
|
|
443
|
+
// `N:`-numbered lines (fences and unnumbered prose don't count), so the model can plan
|
|
444
|
+
// a <start,end> slice before paying for an OPEN. READ/FIND own typed extents instead.
|
|
445
|
+
if (body.length > 0 && op !== "READ" && op !== "FIND") {
|
|
522
446
|
const navigable = body.split("\n").filter((l) => /^\d+:/.test(l)).length;
|
|
523
447
|
if (navigable > 0)
|
|
524
448
|
meta.lines = navigable;
|
|
525
449
|
}
|
|
526
|
-
// §jsonplurnk —
|
|
527
|
-
//
|
|
528
|
-
//
|
|
529
|
-
//
|
|
530
|
-
// raw `body` value (unescaped, delimited by its <<:::tag … :::tag fence). §jsonplurnk
|
|
450
|
+
// {§jsonplurnk} — `display` describes the three body states: `none` carries an explicit
|
|
451
|
+
// empty JSON string, `folded` withholds an existing body, and `open` appends that body as
|
|
452
|
+
// the format's one non-JSON value (a raw, tagged heredoc). The explicit empty body keeps
|
|
453
|
+
// every state self-describing; OPEN/FOLD remain friendly no-ops on `none`.
|
|
531
454
|
const display = body.length === 0 ? "none" : e.folded === true ? "folded" : "open";
|
|
532
455
|
meta.display = display;
|
|
456
|
+
if (display === "none")
|
|
457
|
+
meta.body = "";
|
|
533
458
|
const obj = PacketWire.#canonicalJson(meta);
|
|
534
459
|
return display === "open" ? obj.replace(/\}$/, `,"body":\n${body}\n}`) : obj;
|
|
535
460
|
}).join(",\n");
|
|
@@ -537,41 +462,36 @@ export default class PacketWire {
|
|
|
537
462
|
static #renderActionTarget(target) {
|
|
538
463
|
if (target === null || target === undefined)
|
|
539
464
|
return null;
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
465
|
+
return renderTarget({
|
|
466
|
+
scheme: target.scheme,
|
|
467
|
+
hostname: target.hostname,
|
|
468
|
+
port: target.port,
|
|
469
|
+
pathname: target.pathname,
|
|
470
|
+
query: target.query,
|
|
471
|
+
fragment: target.fragment,
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
static #renderSelection(target, marker) {
|
|
475
|
+
if (target === null || target === undefined)
|
|
476
|
+
return null;
|
|
477
|
+
const address = target.kind === "local" && typeof target.raw === "string"
|
|
478
|
+
? renderTarget({ scheme: null, pathname: target.raw })
|
|
479
|
+
: target.scheme === "file"
|
|
480
|
+
? renderTarget({ scheme: null, pathname: target.pathname ?? "" })
|
|
481
|
+
: PacketWire.#renderActionTarget(target);
|
|
482
|
+
if (address === null || address.length === 0)
|
|
550
483
|
return null;
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
const
|
|
554
|
-
|
|
484
|
+
if (marker === null || marker === undefined)
|
|
485
|
+
return address;
|
|
486
|
+
const validation = Validator.validateLineMarker(marker);
|
|
487
|
+
if (!validation.valid) {
|
|
488
|
+
throw new TypeError("A COPY/MOVE operand contains an invalid line marker.");
|
|
489
|
+
}
|
|
490
|
+
return `${address}<${marker.marks.join(",")}>`;
|
|
555
491
|
}
|
|
556
492
|
static #renderGitState(git) {
|
|
557
493
|
const sync = git.ahead > 0 || git.behind > 0 ? ` (↑${git.ahead} ↓${git.behind})` : "";
|
|
558
494
|
return `branch \`${git.branch}\`${sync} — ${git.staged} staged, ${git.unstaged} unstaged, ${git.untracked} untracked`;
|
|
559
495
|
}
|
|
560
|
-
static #renderTelemetryErrors(errors) {
|
|
561
|
-
// Uniform projection off the formal TelemetryEvent envelope (grammar TelemetryEvent.json):
|
|
562
|
-
// render each error by its typed `position`, never by sniffing `kind`. A LogCoordinate is a
|
|
563
|
-
// terse `<status> log:///<coord>` link to the row (the row holds the term + detail); a
|
|
564
|
-
// ContentOffset points the model at the line in its own born-OPEN emission (§model-entry).
|
|
565
|
-
// No JSON dump — the packet teaches, the row carries the body.
|
|
566
|
-
return errors.map((e) => {
|
|
567
|
-
const ev = e;
|
|
568
|
-
const pos = ev.position;
|
|
569
|
-
if (pos?.type === "log-coordinate")
|
|
570
|
-
return `* ${ev.status ?? ""} log:///${pos.coordinate}`.replace(/ +/g, " ");
|
|
571
|
-
if (pos?.type === "content-offset")
|
|
572
|
-
return `* ${ev.kind ?? "error"} ${pos.line}:${pos.column}`;
|
|
573
|
-
return `* ${ev.kind ?? "error"}`;
|
|
574
|
-
}).join("\n");
|
|
575
|
-
}
|
|
576
496
|
}
|
|
577
497
|
//# sourceMappingURL=packet-wire.js.map
|