@astrosheep/keiyaku 4.6.7 → 4.6.9
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/README.md +46 -16
- package/build/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/build/plugins/claude/skills/keiyaku/SKILL.md +5 -6
- package/build/plugins/claude/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/plugins/claude/skills/keiyaku-akuma/references/automation.md +8 -8
- package/build/plugins/claude/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/claude/skills/keiyaku-bind/SKILL.md +9 -9
- package/build/plugins/claude/skills/keiyaku-debt/SKILL.md +91 -0
- package/build/plugins/claude/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/plugins/codex/.codex-plugin/plugin.json +1 -1
- package/build/plugins/codex/skills/keiyaku/SKILL.md +5 -6
- package/build/plugins/codex/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/plugins/codex/skills/keiyaku-akuma/references/automation.md +8 -8
- package/build/plugins/codex/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/codex/skills/keiyaku-bind/SKILL.md +9 -9
- package/build/plugins/codex/skills/keiyaku-debt/SKILL.md +91 -0
- package/build/plugins/codex/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/plugins/opencode/index.js +1 -1
- package/build/plugins/opencode/skills/keiyaku/SKILL.md +5 -6
- package/build/plugins/opencode/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/plugins/opencode/skills/keiyaku-akuma/references/automation.md +8 -8
- package/build/plugins/opencode/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/plugins/opencode/skills/keiyaku-bind/SKILL.md +9 -9
- package/build/plugins/opencode/skills/keiyaku-debt/SKILL.md +91 -0
- package/build/plugins/opencode/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/plugins/pi/keiyaku.ts +0 -5
- package/build/skills/keiyaku/SKILL.md +5 -6
- package/build/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/skills/keiyaku-akuma/references/automation.md +8 -8
- package/build/skills/keiyaku-babysit/SKILL.md +1 -1
- package/build/skills/keiyaku-bind/SKILL.md +9 -9
- package/build/skills/keiyaku-debt/SKILL.md +91 -0
- package/build/skills/keiyaku-workflow/SKILL.md +2 -2
- package/build/src/akuma/akuma-call.d.ts +2 -0
- package/build/src/akuma/akuma-call.js +8 -2
- package/build/src/akuma/akuma-instance.d.ts +14 -1
- package/build/src/akuma/akuma-instance.js +37 -7
- package/build/src/akuma/akuma-observe.d.ts +33 -8
- package/build/src/akuma/akuma-observe.js +89 -63
- package/build/src/akuma/akuma-owner.d.ts +14 -2
- package/build/src/akuma/akuma-owner.js +49 -35
- package/build/src/akuma/akuma-selection-execution.js +9 -1
- package/build/src/akuma/akuma-stream.d.ts +22 -0
- package/build/src/akuma/akuma-stream.js +116 -0
- package/build/src/akuma/akuma-wait.d.ts +1 -40
- package/build/src/akuma/akuma-wait.js +23 -84
- package/build/src/akuma/akuma.d.ts +52 -16
- package/build/src/akuma/akuma.js +10 -10
- package/build/src/akuma/allowed.d.ts +7 -12
- package/build/src/akuma/allowed.js +13 -4
- package/build/src/akuma/archetype.d.ts +7 -15
- package/build/src/akuma/archetype.js +36 -35
- package/build/src/akuma/body-supervisor.d.ts +5 -5
- package/build/src/akuma/body-supervisor.js +22 -20
- package/build/src/akuma/body.d.ts +5 -3
- package/build/src/akuma/body.js +57 -8
- package/build/src/akuma/call-request.d.ts +30 -32
- package/build/src/akuma/call-request.js +10 -3
- package/build/src/akuma/caller.d.ts +39 -0
- package/build/src/akuma/caller.js +36 -0
- package/build/src/akuma/dispatch-association.d.ts +0 -1
- package/build/src/akuma/dispatch-association.js +0 -3
- package/build/src/akuma/heart/activity-schema.d.ts +12 -0
- package/build/src/akuma/heart/activity-schema.js +6 -0
- package/build/src/akuma/heart/facts.d.ts +16 -12
- package/build/src/akuma/heart/facts.js +8 -0
- package/build/src/akuma/heart/index.d.ts +61 -9
- package/build/src/akuma/heart/index.js +89 -24
- package/build/src/akuma/heart/rows.d.ts +3 -3
- package/build/src/akuma/heart/rows.js +5 -3
- package/build/src/akuma/heart/soul.d.ts +10 -1
- package/build/src/akuma/heart/soul.js +34 -24
- package/build/src/akuma/heart/storage.d.ts +20 -0
- package/build/src/akuma/heart/storage.js +62 -3
- package/build/src/akuma/heart/timeline.d.ts +7 -0
- package/build/src/akuma/heart/timeline.js +10 -0
- package/build/src/akuma/identity.d.ts +0 -1
- package/build/src/akuma/identity.js +2 -5
- package/build/src/akuma/index.d.ts +6 -2
- package/build/src/akuma/index.js +1 -0
- package/build/src/akuma/nuke.js +6 -28
- package/build/src/akuma/projection.d.ts +25 -11
- package/build/src/akuma/projection.js +24 -7
- package/build/src/akuma/provider-recipe.d.ts +18 -6
- package/build/src/akuma/provider-recipe.js +24 -1
- package/build/src/akuma/provider.d.ts +31 -10
- package/build/src/akuma/provider.js +105 -14
- package/build/src/akuma/providers/acp/events.js +29 -19
- package/build/src/akuma/providers/acp/index.js +2 -3
- package/build/src/akuma/providers/claude/events.js +110 -69
- package/build/src/akuma/providers/claude/index.d.ts +2 -2
- package/build/src/akuma/providers/claude/index.js +4 -8
- package/build/src/akuma/providers/codex-app-server/events.js +17 -2
- package/build/src/akuma/providers/codex-app-server/index.js +17 -11
- package/build/src/akuma/providers/decode.d.ts +33 -0
- package/build/src/akuma/providers/decode.js +65 -0
- package/build/src/akuma/providers/execution-environment.d.ts +2 -1
- package/build/src/akuma/providers/execution-environment.js +3 -0
- package/build/src/akuma/providers/grok-build/index.js +16 -48
- package/build/src/akuma/providers/index.js +2 -0
- package/build/src/akuma/providers/lifecycle.d.ts +9 -0
- package/build/src/akuma/providers/lifecycle.js +10 -0
- package/build/src/akuma/providers/opencode-sdk/event-stream.d.ts +3 -3
- package/build/src/akuma/providers/opencode-sdk/event-stream.js +2 -25
- package/build/src/akuma/providers/opencode-sdk/events.d.ts +7 -43
- package/build/src/akuma/providers/opencode-sdk/events.js +146 -296
- package/build/src/akuma/providers/opencode-sdk/index.js +270 -431
- package/build/src/akuma/providers/opencode-sdk/native-http.d.ts +9 -0
- package/build/src/akuma/providers/opencode-sdk/native-http.js +69 -0
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +42 -36
- package/build/src/akuma/providers/opencode-sdk/session.js +75 -84
- package/build/src/akuma/providers/paseo/events.d.ts +33 -0
- package/build/src/akuma/providers/paseo/events.js +204 -0
- package/build/src/akuma/providers/paseo/index.d.ts +9 -0
- package/build/src/akuma/providers/paseo/index.js +357 -0
- package/build/src/akuma/providers/pi/events.d.ts +2 -0
- package/build/src/akuma/providers/pi/events.js +36 -38
- package/build/src/akuma/providers/pi/index.js +21 -35
- package/build/src/akuma/publication.d.ts +2 -0
- package/build/src/akuma/publication.js +5 -0
- package/build/src/akuma/request-lifecycle.d.ts +4 -2
- package/build/src/akuma/request-lifecycle.js +27 -12
- package/build/src/akuma/request-rendezvous.js +38 -55
- package/build/src/akuma/request-serve.d.ts +1 -1
- package/build/src/akuma/request-serve.js +77 -113
- package/build/src/akuma/requests.d.ts +3 -1
- package/build/src/akuma/requests.js +32 -0
- package/build/src/akuma/selection-observation.d.ts +129 -53
- package/build/src/akuma/selection-observation.js +3 -9
- package/build/src/akuma/turn-drive.d.ts +3 -0
- package/build/src/akuma/turn-drive.js +28 -10
- package/build/src/akuma-body.js +12 -22
- package/build/src/cli/akuma-caller.d.ts +3 -0
- package/build/src/cli/akuma-caller.js +31 -0
- package/build/src/cli/commands/akuma-grammar.js +10 -16
- package/build/src/cli/commands/akuma.js +25 -55
- package/build/src/cli/commands/contract-grammar.d.ts +9 -7
- package/build/src/cli/commands/contract-grammar.js +40 -47
- package/build/src/cli/commands/contract-help.d.ts +17 -7
- package/build/src/cli/commands/contract-help.js +50 -11
- package/build/src/cli/commands/contract.js +34 -63
- package/build/src/cli/commands/debt-grammar.d.ts +19 -0
- package/build/src/cli/commands/debt-grammar.js +323 -0
- package/build/src/cli/commands/debt-query.d.ts +5 -0
- package/build/src/cli/commands/{task-query.js → debt-query.js} +9 -9
- package/build/src/cli/commands/{task.d.ts → debt.d.ts} +2 -2
- package/build/src/cli/commands/{task.js → debt.js} +87 -164
- package/build/src/cli/coordinates.d.ts +1 -1
- package/build/src/cli/coordinates.js +1 -1
- package/build/src/cli/parse.d.ts +5 -5
- package/build/src/cli/parse.js +17 -16
- package/build/src/cli/render/akuma-activity.d.ts +11 -83
- package/build/src/cli/render/akuma-activity.js +20 -382
- package/build/src/cli/render/catalog.d.ts +4 -7
- package/build/src/cli/render/catalog.js +5 -5
- package/build/src/cli/render/contract-history.js +3 -6
- package/build/src/cli/render/contract.js +17 -52
- package/build/src/cli/render/debt.d.ts +28 -0
- package/build/src/cli/render/{task.js → debt.js} +55 -133
- package/build/src/cli/render/kanshi.js +28 -28
- package/build/src/cli/render/marks.d.ts +5 -5
- package/build/src/cli/render/marks.js +4 -10
- package/build/src/cli/render/nuke.js +1 -1
- package/build/src/cli/render/receipt.js +3 -10
- package/build/src/cli/runtime.d.ts +1 -1
- package/build/src/cli/runtime.js +14 -20
- package/build/src/cli/scan.d.ts +1 -1
- package/build/src/cli/selectors.d.ts +3 -6
- package/build/src/cli/selectors.js +22 -53
- package/build/src/cli/usage.d.ts +1 -1
- package/build/src/cli/usage.js +4 -4
- package/build/src/contract-worktree.js +3 -3
- package/build/src/debt/board.d.ts +160 -0
- package/build/src/{task → debt}/board.js +89 -89
- package/build/src/debt/catalog.d.ts +11 -0
- package/build/src/debt/catalog.js +59 -0
- package/build/src/{task → debt}/context.d.ts +1 -1
- package/build/src/{task → debt}/context.js +1 -1
- package/build/src/{task → debt}/created-observation.d.ts +6 -10
- package/build/src/{task → debt}/created-observation.js +7 -7
- package/build/src/debt/document.d.ts +37 -0
- package/build/src/{task → debt}/document.js +37 -37
- package/build/src/debt/identity.d.ts +21 -0
- package/build/src/{task → debt}/identity.js +35 -35
- package/build/src/debt/index.d.ts +111 -0
- package/build/src/debt/index.js +203 -0
- package/build/src/{task → debt}/input.d.ts +8 -8
- package/build/src/{task → debt}/input.js +21 -21
- package/build/src/debt/lifecycle-operations.d.ts +6 -0
- package/build/src/{task → debt}/lifecycle-operations.js +27 -31
- package/build/src/debt/mutation-result.d.ts +981 -0
- package/build/src/debt/mutation-result.js +109 -0
- package/build/src/debt/mutation.d.ts +424 -0
- package/build/src/debt/mutation.js +223 -0
- package/build/src/debt/operation-types.d.ts +71 -0
- package/build/src/debt/operations.d.ts +28 -0
- package/build/src/{task → debt}/operations.js +59 -60
- package/build/src/debt/query.d.ts +76 -0
- package/build/src/{task → debt}/query.js +55 -55
- package/build/src/{task → debt}/store.d.ts +13 -13
- package/build/src/{task → debt}/store.js +58 -49
- package/build/src/debt/view.d.ts +4 -0
- package/build/src/debt/view.js +7 -0
- package/build/src/dispatch/index.d.ts +3 -3
- package/build/src/dispatch/index.js +1 -2
- package/build/src/git/observe.d.ts +6 -2
- package/build/src/git/observe.js +6 -2
- package/build/src/identity/coordinates.d.ts +1 -1
- package/build/src/index.d.ts +17 -17
- package/build/src/index.js +11 -11
- package/build/src/kanshi/index.d.ts +2 -2
- package/build/src/kanshi/read.js +54 -39
- package/build/src/kanshi/report.d.ts +7 -7
- package/build/src/kanshi/select.js +4 -4
- package/build/src/library/address.js +2 -4
- package/build/src/library/akuma-creation.d.ts +5 -1
- package/build/src/library/akuma-creation.js +27 -47
- package/build/src/library/akumas.d.ts +7 -7
- package/build/src/library/akumas.js +13 -9
- package/build/src/library/bind.d.ts +17 -17
- package/build/src/library/bind.js +16 -12
- package/build/src/library/contract-address.d.ts +9 -0
- package/build/src/library/contract-address.js +71 -0
- package/build/src/library/contract-composition.d.ts +4 -7
- package/build/src/library/contract-composition.js +6 -18
- package/build/src/library/contract-creation.d.ts +3 -5
- package/build/src/library/contract-creation.js +24 -22
- package/build/src/library/contract-execution.js +21 -26
- package/build/src/library/contract-outcomes.d.ts +2 -14
- package/build/src/library/contract-outcomes.js +2 -13
- package/build/src/library/contract-types.d.ts +38 -4
- package/build/src/library/delivery.d.ts +0 -2
- package/build/src/library/delivery.js +2 -5
- package/build/src/library/input.d.ts +2 -2
- package/build/src/library/input.js +5 -5
- package/build/src/library/invocation.js +2 -2
- package/build/src/library/keiyaku.d.ts +0 -5
- package/build/src/library/keiyaku.js +6 -12
- package/build/src/library/nuke.js +3 -3
- package/build/src/library/outcome.d.ts +626 -625
- package/build/src/library/outcome.js +13 -3
- package/build/src/library/reconcile.js +8 -16
- package/build/src/library/refusal.d.ts +2 -2
- package/build/src/library/repo.d.ts +3 -2
- package/build/src/library/repo.js +10 -5
- package/build/src/library/selection.d.ts +5 -8
- package/build/src/library/selection.js +22 -73
- package/build/src/plugin/akuma-signals.d.ts +2 -0
- package/build/src/plugin/akuma-signals.js +4 -0
- package/build/src/plugin/public.d.ts +32 -2
- package/build/src/plugin/runtime.js +5 -3
- package/build/src/protocol/amend.js +3 -2
- package/build/src/protocol/attempt.js +3 -8
- package/build/src/protocol/bind.d.ts +2 -2
- package/build/src/protocol/bind.js +1 -1
- package/build/src/protocol/deliver.js +3 -3
- package/build/src/protocol/operations.d.ts +1 -3
- package/build/src/protocol/operations.js +0 -8
- package/build/src/protocol/outcome.d.ts +1 -2
- package/build/src/protocol/outcome.js +1 -13
- package/build/src/protocol/placement.js +3 -10
- package/build/src/protocol/read/status.js +31 -70
- package/build/src/protocol/reintegrate.js +3 -10
- package/build/src/protocol/review.js +3 -3
- package/build/src/protocol/run.d.ts +5 -1
- package/build/src/protocol/run.js +3 -3
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/build/src/settlement/fence.d.ts +3 -3
- package/build/src/settlement/fence.js +4 -4
- package/build/src/settlement/holder.d.ts +16 -16
- package/build/src/settlement/holder.js +69 -63
- package/build/src/settlement/settle.d.ts +5 -5
- package/build/src/settlement/settle.js +53 -53
- package/package.json +19 -9
- package/plugins/paseo/plugin/index.server.ts +17 -0
- package/plugins/paseo/plugin/paseo-plugin.json +4 -0
- package/plugins/paseo/plugin/server/attach.ts +52 -0
- package/plugins/paseo/plugin/server/keiyaku.ts +44 -0
- package/plugins/paseo/plugin/server/message.ts +60 -0
- package/plugins/paseo/plugin/server/mirror.ts +193 -0
- package/plugins/paseo/plugin/server/model.ts +14 -0
- package/plugins/paseo/plugin/server/provider.ts +276 -0
- package/plugins/paseo/plugin/server/sdk-worker.ts +237 -0
- package/plugins/paseo/plugin/server/sdk.ts +289 -0
- package/plugins/paseo/plugin/server/stop.ts +26 -0
- package/plugins/paseo/plugin/server/transport.ts +35 -0
- package/plugins/paseo/plugin/shared/attach-rpc.ts +10 -0
- package/plugins/paseo/plugin/shared/refresh-rpc.ts +6 -0
- package/plugins/paseo/plugin/tsconfig.json +6 -0
- package/plugins/pi/keiyaku.ts +57 -0
- package/skills/keiyaku/SKILL.md +43 -0
- package/skills/keiyaku-akuma/SKILL.md +130 -0
- package/skills/keiyaku-akuma/references/automation.md +269 -0
- package/skills/keiyaku-babysit/SKILL.md +65 -0
- package/skills/keiyaku-bind/SKILL.md +216 -0
- package/skills/keiyaku-bind/agents/openai.yaml +4 -0
- package/skills/keiyaku-debt/SKILL.md +91 -0
- package/skills/keiyaku-workflow/SKILL.md +129 -0
- package/build/plugins/claude/skills/keiyaku-task/SKILL.md +0 -104
- package/build/plugins/codex/skills/keiyaku-task/SKILL.md +0 -104
- package/build/plugins/opencode/skills/keiyaku-task/SKILL.md +0 -104
- package/build/skills/keiyaku-task/SKILL.md +0 -104
- package/build/src/cli/commands/amend.d.ts +0 -12
- package/build/src/cli/commands/amend.js +0 -10
- package/build/src/cli/commands/bind.d.ts +0 -11
- package/build/src/cli/commands/bind.js +0 -23
- package/build/src/cli/commands/task-grammar.d.ts +0 -19
- package/build/src/cli/commands/task-grammar.js +0 -384
- package/build/src/cli/commands/task-query.d.ts +0 -5
- package/build/src/cli/render/task.d.ts +0 -41
- package/build/src/dispatch/association.d.ts +0 -1
- package/build/src/dispatch/association.js +0 -1
- package/build/src/task/board.d.ts +0 -168
- package/build/src/task/catalog.d.ts +0 -11
- package/build/src/task/catalog.js +0 -59
- package/build/src/task/compose-language.d.ts +0 -57
- package/build/src/task/compose-language.js +0 -364
- package/build/src/task/compose-parser.d.ts +0 -32
- package/build/src/task/compose-parser.js +0 -180
- package/build/src/task/compose.d.ts +0 -16
- package/build/src/task/compose.js +0 -189
- package/build/src/task/document.d.ts +0 -39
- package/build/src/task/identity.d.ts +0 -21
- package/build/src/task/index.d.ts +0 -138
- package/build/src/task/index.js +0 -269
- package/build/src/task/lifecycle-operations.d.ts +0 -6
- package/build/src/task/mutation-result.d.ts +0 -1726
- package/build/src/task/mutation-result.js +0 -198
- package/build/src/task/mutation.d.ts +0 -590
- package/build/src/task/mutation.js +0 -262
- package/build/src/task/operation-types.d.ts +0 -71
- package/build/src/task/operations.d.ts +0 -28
- package/build/src/task/query.d.ts +0 -76
- package/build/src/task/view.d.ts +0 -4
- package/build/src/task/view.js +0 -7
- /package/build/src/{task → debt}/operation-types.js +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { parsePublicHistoryId } from "../identity.js";
|
|
2
|
+
import { decodeRuntimeModel, withoutModel } from "../provider-recipe.js";
|
|
2
3
|
import { answeredTurnFact, endBodyFact, finishBodyFact, deleteStopControl, insertActivityFact, insertTurnEndFact, insertTurnStartFact, insertPauseControl, insertKillFact, insertSessionFact, insertStopControl, killFactForBody, latestBodyFact, latestKillFact, latestSessionFact, latestTurnFactForBody, lastAnsweredTurnFact, pauseFact, sessionFactForCoordinate, stopFact, turnFact, } from "./rows.js";
|
|
3
|
-
import { insertTellDeliveryFact, dispositionSnapshotProven, insertTellBindingFact, insertTellDispositionSnapshot,
|
|
4
|
-
import { activityFactSlice, statusFacts, readStatusBatch, decodeTimelineBatch, lastActivityAt as readLastActivityAt, pruneActivityFacts, } from "./timeline.js";
|
|
5
|
-
import { isHeartAbsent, readSealFromLeash, withHeartTransaction, withReadOnlyHeart } from "./storage.js";
|
|
6
|
-
import { soulFact } from "./soul.js";
|
|
4
|
+
import { insertTellDeliveryFact, dispositionSnapshotProven, insertTellBindingFact, insertTellDispositionSnapshot, insertTellReceiptFact, insertUndeliveredTellReceipts, latestOpenTellDisposition, openBoundTurns, openTellDispositionIds, pendingTellFacts, hasPendingTell, resolveTellDispositionSnapshot, tellDispositionResolved, tellFact, tellIdsForFence, turnParticipants, } from "./tells.js";
|
|
5
|
+
import { activityFactSlice, statusFacts, readStatusBatch, decodeTimelineBatch, timelineDataVersion, lastActivityAt as readLastActivityAt, pruneActivityFacts, } from "./timeline.js";
|
|
6
|
+
import { createHeartReader, isHeartAbsent, readSealFromLeash, recordPendingTell, withHeartTransaction, withReadOnlyHeart, } from "./storage.js";
|
|
7
|
+
import { setSoulModel, soulFact } from "./soul.js";
|
|
7
8
|
import { AkumaBusyError, HeartAuthorityCorruptionError } from "./facts.js";
|
|
8
9
|
export { HeartAbsentError, HeldAkumaLeash, classifyHeartSchema, initializeHeart, isHeartAbsent, probeLeash, } from "./storage.js";
|
|
9
10
|
export { admitRequest, beginRequest, isRequestInputConflict, readNonterminalRequests, readRequest, refuseRequest, reserveRequest, serveRequest, serveUpstreamRequest, unproveRequest, voidRequest, } from "./request-authority.js";
|
|
@@ -50,12 +51,57 @@ export async function appendActivity(paths, input) {
|
|
|
50
51
|
return sequence;
|
|
51
52
|
});
|
|
52
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Admit one runtime-model observation from the Body that is actually running.
|
|
56
|
+
* The model is the one mutable member of an otherwise frozen recipe, so only
|
|
57
|
+
* the exact latest Running Body may move it: evidence that arrives after that
|
|
58
|
+
* Body settled, or from a superseded Body, is refused rather than applied.
|
|
59
|
+
*/
|
|
60
|
+
export async function recordCurrentModel(paths, input) {
|
|
61
|
+
const model = decodeRuntimeModel(input.model);
|
|
62
|
+
return await withHeartTransaction(paths, (heart) => {
|
|
63
|
+
const body = latestBodyFact(heart);
|
|
64
|
+
if (body === null || body.sequence !== input.bodySequence || body.end !== undefined || body.hung !== undefined) {
|
|
65
|
+
return "not-current-body";
|
|
66
|
+
}
|
|
67
|
+
return setSoulModel(heart, model) ? "recorded" : "unchanged";
|
|
68
|
+
});
|
|
69
|
+
}
|
|
53
70
|
export async function activitySlice(paths) {
|
|
54
71
|
return await withReadOnlyHeart(paths, (heart) => activityFactSlice(heart));
|
|
55
72
|
}
|
|
56
73
|
export async function readStatusFacts(paths, input, signal) {
|
|
57
74
|
return await withReadOnlyHeart(paths, (heart) => statusFacts(heart, input), signal);
|
|
58
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* One operation-owned reader of the retained timeline. It keeps its read
|
|
78
|
+
* custody between observations, skips decoding when the same connection's
|
|
79
|
+
* change counter still names the observed snapshot, and renews that gate
|
|
80
|
+
* whenever a replaced Heart gives it a new connection.
|
|
81
|
+
*/
|
|
82
|
+
export function createTimelineReader(paths) {
|
|
83
|
+
const reader = createHeartReader(paths);
|
|
84
|
+
let generation = -1;
|
|
85
|
+
let version;
|
|
86
|
+
return {
|
|
87
|
+
clear: reader.clear,
|
|
88
|
+
async read(signal) {
|
|
89
|
+
// Publication follows COMMIT, so a failed read never leaves a memo behind.
|
|
90
|
+
return await reader.read((heart) => {
|
|
91
|
+
const current = reader.generation();
|
|
92
|
+
if (current !== generation) {
|
|
93
|
+
generation = current;
|
|
94
|
+
version = undefined;
|
|
95
|
+
}
|
|
96
|
+
const observed = timelineDataVersion(heart);
|
|
97
|
+
if (version !== undefined && observed === version)
|
|
98
|
+
return { changed: false };
|
|
99
|
+
version = observed;
|
|
100
|
+
return { changed: true, born: soulFact(heart) !== null, slice: activityFactSlice(heart) };
|
|
101
|
+
}, signal);
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
59
105
|
// Each query returns a fixed set of scalar columns; compare JSON columns as text.
|
|
60
106
|
function sameRawRows(left, right) {
|
|
61
107
|
if (left.length !== right.length)
|
|
@@ -75,16 +121,24 @@ function sameStatusBatch(left, right) {
|
|
|
75
121
|
sameRawRows(left.tells.deliveries, right.tells.deliveries) &&
|
|
76
122
|
sameRawRows(left.tells.bindings, right.tells.bindings));
|
|
77
123
|
}
|
|
78
|
-
/** One
|
|
124
|
+
/** One observer owns its connection and successful decoded frontier. */
|
|
79
125
|
export function createStatusFactReader(paths) {
|
|
126
|
+
const reader = createHeartReader(paths);
|
|
80
127
|
let memo;
|
|
81
128
|
return {
|
|
129
|
+
life: (signal) => readLifeSnapshot(paths, signal, reader.read),
|
|
130
|
+
tellOutcome: (id, signal) => reader.read((heart) => {
|
|
131
|
+
const tell = tellFact(heart, id);
|
|
132
|
+
const end = tell?.binding === undefined ? undefined : turnFact(heart, tell.binding.turnSequence)?.end;
|
|
133
|
+
return { tell, end };
|
|
134
|
+
}, signal),
|
|
82
135
|
clear() {
|
|
136
|
+
reader.clear();
|
|
83
137
|
memo = undefined;
|
|
84
138
|
},
|
|
85
139
|
async read(input, signal) {
|
|
86
140
|
try {
|
|
87
|
-
const next = await
|
|
141
|
+
const next = await reader.read((heart) => {
|
|
88
142
|
const batch = readStatusBatch(heart, input);
|
|
89
143
|
if (memo !== undefined && sameStatusBatch(batch, memo.batch))
|
|
90
144
|
return memo;
|
|
@@ -95,6 +149,7 @@ export function createStatusFactReader(paths) {
|
|
|
95
149
|
return next.facts;
|
|
96
150
|
}
|
|
97
151
|
catch (error) {
|
|
152
|
+
reader.clear();
|
|
98
153
|
memo = undefined;
|
|
99
154
|
throw error;
|
|
100
155
|
}
|
|
@@ -102,9 +157,9 @@ export function createStatusFactReader(paths) {
|
|
|
102
157
|
};
|
|
103
158
|
}
|
|
104
159
|
/** Lifecycle probes do not load narration, Tell bodies, or delivery histories. */
|
|
105
|
-
export async function readLifeSnapshot(paths, signal) {
|
|
160
|
+
export async function readLifeSnapshot(paths, signal, read = (body, signal) => withReadOnlyHeart(paths, body, signal)) {
|
|
106
161
|
try {
|
|
107
|
-
return await
|
|
162
|
+
return await read((heart) => ({
|
|
108
163
|
soul: soulFact(heart),
|
|
109
164
|
latestBody: latestBodyFact(heart),
|
|
110
165
|
latestSession: latestSessionFact(heart),
|
|
@@ -138,9 +193,7 @@ export async function recordTell(paths, tell, options = {}) {
|
|
|
138
193
|
const running = body !== null && body.end === undefined && body.hung === undefined;
|
|
139
194
|
if (tell.schemaJson !== undefined && running && options.interrupt !== true)
|
|
140
195
|
throw new AkumaBusyError();
|
|
141
|
-
|
|
142
|
-
pruneActivityFacts(heart, ACTIVITY_LIMIT);
|
|
143
|
-
return { kind: "recorded", tell: { sequence, ...tell, state: "pending", deliveries: [] } };
|
|
196
|
+
return recordPendingTell(heart, tell);
|
|
144
197
|
});
|
|
145
198
|
}
|
|
146
199
|
export async function readTell(paths, id) {
|
|
@@ -256,18 +309,6 @@ export async function requestPause(paths, at, signal) {
|
|
|
256
309
|
return { kind: "requested", body };
|
|
257
310
|
}, signal);
|
|
258
311
|
}
|
|
259
|
-
export async function stopRequested(paths, bodySequence) {
|
|
260
|
-
return await withReadOnlyHeart(paths, (heart) => {
|
|
261
|
-
const target = stopFact(heart);
|
|
262
|
-
return target !== null && (bodySequence === undefined || target.bodySequence === bodySequence);
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
export async function pauseRequested(paths, bodySequence) {
|
|
266
|
-
return await withReadOnlyHeart(paths, (heart) => {
|
|
267
|
-
const target = pauseFact(heart);
|
|
268
|
-
return target !== null && (bodySequence === undefined || target.bodySequence === bodySequence);
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
312
|
export async function breakBody(paths, input) {
|
|
272
313
|
await withHeartTransaction(paths, (heart) => endBodyFact(heart, input));
|
|
273
314
|
}
|
|
@@ -335,6 +376,27 @@ export async function finishBodyIfIdle(paths, input) {
|
|
|
335
376
|
return { kind: "finished" };
|
|
336
377
|
});
|
|
337
378
|
}
|
|
379
|
+
export function createBodyHeartReader(paths) {
|
|
380
|
+
const reader = createHeartReader(paths);
|
|
381
|
+
return {
|
|
382
|
+
clear: reader.clear,
|
|
383
|
+
async read() {
|
|
384
|
+
try {
|
|
385
|
+
return await reader.read((heart) => ({
|
|
386
|
+
soul: soulFact(heart),
|
|
387
|
+
pending: pendingTellFacts(heart),
|
|
388
|
+
stop: stopFact(heart),
|
|
389
|
+
pause: pauseFact(heart),
|
|
390
|
+
}));
|
|
391
|
+
}
|
|
392
|
+
catch (error) {
|
|
393
|
+
if (isHeartAbsent(error))
|
|
394
|
+
return { soul: null, pending: [], stop: null, pause: null };
|
|
395
|
+
throw error;
|
|
396
|
+
}
|
|
397
|
+
},
|
|
398
|
+
};
|
|
399
|
+
}
|
|
338
400
|
export async function readHeart(paths) {
|
|
339
401
|
try {
|
|
340
402
|
return await withReadOnlyHeart(paths, (heart) => ({
|
|
@@ -380,12 +442,15 @@ export async function readForkPoint(paths, historyId) {
|
|
|
380
442
|
const recipe = sessionFactForCoordinate(heart, outcome.session);
|
|
381
443
|
if (recipe === null)
|
|
382
444
|
throw new Error(`Akuma fork point ${historyId} has no session recipe`);
|
|
445
|
+
// The source's current model is the admitted child selection. The session
|
|
446
|
+
// row's obsolete copy is dropped, and an absent current model stays absent.
|
|
447
|
+
const current = soulFact(heart)?.options.model;
|
|
383
448
|
return {
|
|
384
449
|
historyId: outcome.historyId,
|
|
385
450
|
session: outcome.session,
|
|
386
451
|
provider: recipe.provider,
|
|
387
452
|
cwd: recipe.cwd,
|
|
388
|
-
options: recipe.options,
|
|
453
|
+
options: { ...withoutModel(recipe.options), ...(current === undefined ? {} : { model: current }) },
|
|
389
454
|
};
|
|
390
455
|
});
|
|
391
456
|
}
|
|
@@ -41,11 +41,11 @@ export declare const sessionAdmissionSchema: z.ZodObject<{
|
|
|
41
41
|
}>>;
|
|
42
42
|
systemPrompt: z.ZodOptional<z.ZodString>;
|
|
43
43
|
systemPromptMode: z.ZodOptional<z.ZodEnum<{
|
|
44
|
-
append: "append";
|
|
45
44
|
replace: "replace";
|
|
45
|
+
append: "append";
|
|
46
46
|
}>>;
|
|
47
47
|
}, z.core.$strip>, z.ZodTransform<Readonly<{
|
|
48
|
-
systemPromptMode?: "
|
|
48
|
+
systemPromptMode?: "replace" | "append";
|
|
49
49
|
systemPrompt?: string;
|
|
50
50
|
network?: "disabled" | "enabled";
|
|
51
51
|
effort?: string;
|
|
@@ -55,7 +55,7 @@ export declare const sessionAdmissionSchema: z.ZodObject<{
|
|
|
55
55
|
effort?: string | undefined;
|
|
56
56
|
network?: "disabled" | "enabled" | undefined;
|
|
57
57
|
systemPrompt?: string | undefined;
|
|
58
|
-
systemPromptMode?: "
|
|
58
|
+
systemPromptMode?: "replace" | "append" | undefined;
|
|
59
59
|
}>>;
|
|
60
60
|
admittedAt: z.ZodString;
|
|
61
61
|
}, z.core.$strict>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { providerOptionsSchema } from "../provider-recipe.js";
|
|
2
|
+
import { providerOptionsSchema, withoutModel } from "../provider-recipe.js";
|
|
3
3
|
import { resumeCoordinateSchema } from "../coordinate.js";
|
|
4
4
|
import { decodeResumeCoordinate, encodeResumeCoordinate as encodeCoordinate } from "../coordinate.js";
|
|
5
5
|
import { agentEventSchema } from "./activity-schema.js";
|
|
@@ -32,7 +32,7 @@ export function encodeSessionRow(session) {
|
|
|
32
32
|
session.provider,
|
|
33
33
|
encodeResumeCoordinate(session.coordinate),
|
|
34
34
|
session.cwd,
|
|
35
|
-
json(session.options),
|
|
35
|
+
json(withoutModel(session.options)),
|
|
36
36
|
session.admittedAt,
|
|
37
37
|
];
|
|
38
38
|
}
|
|
@@ -45,7 +45,9 @@ export function decodeSessionRow(row) {
|
|
|
45
45
|
provider: row.provider,
|
|
46
46
|
coordinate: resumeCoordinate(parsed(row.coordinate_json)),
|
|
47
47
|
cwd: row.cwd,
|
|
48
|
-
|
|
48
|
+
// A session's own model copy is obsolete: the Soul owns the one current
|
|
49
|
+
// model, so an old row never re-admits the model it happened to start with.
|
|
50
|
+
options: withoutModel(parsed(row.options_json)),
|
|
49
51
|
admittedAt: row.admitted_at,
|
|
50
52
|
};
|
|
51
53
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DatabaseSync } from "node:sqlite";
|
|
2
|
-
import type
|
|
2
|
+
import { type Soul, type SoulRow } from "./facts.js";
|
|
3
3
|
export declare function decodeSoulSeed(value: unknown): Omit<Soul, "createdAt">;
|
|
4
4
|
export declare function decodeSoul(value: unknown): Soul;
|
|
5
5
|
export declare function encodeSoul(soul: Soul): string;
|
|
@@ -7,3 +7,12 @@ export declare function encodeSoulRow(soul: Soul): readonly [string];
|
|
|
7
7
|
export declare function decodeSoulRow(row: SoulRow): Soul;
|
|
8
8
|
export declare function soulFact(database: DatabaseSync): Soul | null;
|
|
9
9
|
export declare function insertSoulFact(database: DatabaseSync, soul: Soul): void;
|
|
10
|
+
/**
|
|
11
|
+
* Replace only the current-model member of the singleton Soul and report
|
|
12
|
+
* whether the stored value actually moved. Every other raw member is carried
|
|
13
|
+
* through byte-identically: the codec normalizes recipe options, origin and
|
|
14
|
+
* allowed, so decoding and re-encoding a whole Soul here would silently
|
|
15
|
+
* rewrite fields this update never touched. A Soul this build cannot read is
|
|
16
|
+
* refused rather than mutated.
|
|
17
|
+
*/
|
|
18
|
+
export declare function setSoulModel(database: DatabaseSync, model: string | undefined): boolean;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { decodeAkumaCaller } from "../caller.js";
|
|
1
2
|
import { parseAkuId } from "../identity.js";
|
|
2
3
|
import { decodeProviderOptions, decodeProviderRecipe } from "../provider-recipe.js";
|
|
4
|
+
import { akumaOriginSchema } from "./facts.js";
|
|
3
5
|
import { historicalAllowedActions } from "../allowed.js";
|
|
4
6
|
function record(value) {
|
|
5
7
|
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
@@ -20,29 +22,6 @@ function soulAkuIdentity(value, what) {
|
|
|
20
22
|
throw new Error(`Akuma soul ${what} is not an Akuma identity coordinate`, { cause: error });
|
|
21
23
|
}
|
|
22
24
|
}
|
|
23
|
-
function decodeOrigin(value) {
|
|
24
|
-
const origin = record(value);
|
|
25
|
-
if (origin === null)
|
|
26
|
-
throw new Error("Akuma soul origin must be an object");
|
|
27
|
-
if (origin.kind === "direct") {
|
|
28
|
-
return { kind: "direct" };
|
|
29
|
-
}
|
|
30
|
-
if (origin.kind === "request") {
|
|
31
|
-
return {
|
|
32
|
-
kind: "request",
|
|
33
|
-
parent: soulAkuIdentity(origin.parent, "request parent").id,
|
|
34
|
-
requestId: nonblank(origin.requestId, "request requestId"),
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
if (origin.kind === "fork") {
|
|
38
|
-
return {
|
|
39
|
-
kind: "fork",
|
|
40
|
-
parent: soulAkuIdentity(origin.parent, "fork parent").id,
|
|
41
|
-
at: nonblank(origin.at, "fork at"),
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
throw new Error("Akuma soul origin must be direct, request, or fork");
|
|
45
|
-
}
|
|
46
25
|
export function decodeSoulSeed(value) {
|
|
47
26
|
const soul = record(value);
|
|
48
27
|
if (soul === null)
|
|
@@ -55,6 +34,7 @@ export function decodeSoulSeed(value) {
|
|
|
55
34
|
const description = soul.description === undefined ? undefined : nonblank(soul.description, "description");
|
|
56
35
|
const provider = decodeProviderRecipe(soul.provider);
|
|
57
36
|
const options = decodeProviderOptions(soul.options);
|
|
37
|
+
const caller = decodeAkumaCaller(soul.caller);
|
|
58
38
|
return {
|
|
59
39
|
id,
|
|
60
40
|
archetype,
|
|
@@ -62,7 +42,8 @@ export function decodeSoulSeed(value) {
|
|
|
62
42
|
provider,
|
|
63
43
|
options,
|
|
64
44
|
cwd: nonblank(soul.cwd, "cwd"),
|
|
65
|
-
origin:
|
|
45
|
+
origin: akumaOriginSchema.parse(soul.origin),
|
|
46
|
+
...(caller === undefined ? {} : { caller }),
|
|
66
47
|
allowed: historicalAllowedActions(soul.allowed),
|
|
67
48
|
};
|
|
68
49
|
}
|
|
@@ -97,3 +78,32 @@ export function soulFact(database) {
|
|
|
97
78
|
export function insertSoulFact(database, soul) {
|
|
98
79
|
database.prepare("INSERT INTO soul(singleton, soul_json) VALUES (1, ?)").run(...encodeSoulRow(soul));
|
|
99
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Replace only the current-model member of the singleton Soul and report
|
|
83
|
+
* whether the stored value actually moved. Every other raw member is carried
|
|
84
|
+
* through byte-identically: the codec normalizes recipe options, origin and
|
|
85
|
+
* allowed, so decoding and re-encoding a whole Soul here would silently
|
|
86
|
+
* rewrite fields this update never touched. A Soul this build cannot read is
|
|
87
|
+
* refused rather than mutated.
|
|
88
|
+
*/
|
|
89
|
+
export function setSoulModel(database, model) {
|
|
90
|
+
const row = database.prepare("SELECT soul_json FROM soul WHERE singleton = 1").get();
|
|
91
|
+
if (row === undefined)
|
|
92
|
+
throw new Error("Akuma soul is absent");
|
|
93
|
+
const raw = JSON.parse(row.soul_json);
|
|
94
|
+
decodeSoul(raw);
|
|
95
|
+
const soul = record(raw);
|
|
96
|
+
const options = record(soul.options);
|
|
97
|
+
if (options === null)
|
|
98
|
+
throw new Error("Akuma soul options must be an object");
|
|
99
|
+
const current = options.model;
|
|
100
|
+
if (model === undefined ? current === undefined : current === model)
|
|
101
|
+
return false;
|
|
102
|
+
const next = { ...options };
|
|
103
|
+
if (model === undefined)
|
|
104
|
+
delete next.model;
|
|
105
|
+
else
|
|
106
|
+
next.model = model;
|
|
107
|
+
database.prepare("UPDATE soul SET soul_json = ? WHERE singleton = 1").run(JSON.stringify({ ...soul, options: next }));
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
@@ -9,7 +9,27 @@ export declare class HeartAbsentError extends Error {
|
|
|
9
9
|
export declare function isHeartAbsent(error: unknown): error is HeartAbsentError;
|
|
10
10
|
export declare function classifyHeartSchema(paths: AkumaPaths): Promise<"current" | "unsupported">;
|
|
11
11
|
export declare function withReadOnlyHeart<T>(paths: AkumaPaths, body: (database: DatabaseSync) => T, signal?: AbortSignal): Promise<T>;
|
|
12
|
+
export type HeartRead = <T>(body: (database: DatabaseSync) => T, signal?: AbortSignal) => Promise<T>;
|
|
13
|
+
export type HeartReader = Readonly<{
|
|
14
|
+
read: HeartRead;
|
|
15
|
+
clear(): void;
|
|
16
|
+
/** Counts opened connections, so a caller's own reuse cannot survive a replaced Heart. */
|
|
17
|
+
generation(): number;
|
|
18
|
+
}>;
|
|
19
|
+
/**
|
|
20
|
+
* A bounded observer owns its connection between observations, never a
|
|
21
|
+
* transaction: each read settles the transaction it began, and a removed or
|
|
22
|
+
* replaced Heart invalidates the retained custody through file identity.
|
|
23
|
+
* Release never interrupts an executing read; it settles after the current
|
|
24
|
+
* observation, so a caller may release while a pull is still in flight.
|
|
25
|
+
*/
|
|
26
|
+
export declare function createHeartReader(paths: AkumaPaths): HeartReader;
|
|
12
27
|
export declare function withHeartTransaction<T>(paths: AkumaPaths, body: (database: DatabaseSync) => T, signal?: AbortSignal): Promise<T>;
|
|
28
|
+
/** Insert one already-admitted pending Tell into an already-open Heart transaction. */
|
|
29
|
+
export declare function recordPendingTell(heart: DatabaseSync, tell: Omit<TellFact, "sequence" | "state" | "deliveries" | "binding">): Readonly<{
|
|
30
|
+
kind: "recorded";
|
|
31
|
+
tell: TellFact;
|
|
32
|
+
}>;
|
|
13
33
|
export declare function initializeHeart(paths: AkumaPaths): Promise<void>;
|
|
14
34
|
export declare class HeldAkumaLeash {
|
|
15
35
|
private readonly database;
|
|
@@ -112,6 +112,61 @@ export async function withReadOnlyHeart(paths, body, signal) {
|
|
|
112
112
|
database.close();
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* A bounded observer owns its connection between observations, never a
|
|
117
|
+
* transaction: each read settles the transaction it began, and a removed or
|
|
118
|
+
* replaced Heart invalidates the retained custody through file identity.
|
|
119
|
+
* Release never interrupts an executing read; it settles after the current
|
|
120
|
+
* observation, so a caller may release while a pull is still in flight.
|
|
121
|
+
*/
|
|
122
|
+
export function createHeartReader(paths) {
|
|
123
|
+
let database;
|
|
124
|
+
let identity;
|
|
125
|
+
let tail = Promise.resolve();
|
|
126
|
+
let opened = 0;
|
|
127
|
+
const release = () => {
|
|
128
|
+
const retained = database;
|
|
129
|
+
database = undefined;
|
|
130
|
+
identity = undefined;
|
|
131
|
+
try {
|
|
132
|
+
retained?.close();
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
// A connection already released by its own failed read stays released.
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
const clear = () => {
|
|
139
|
+
tail = tail.then(release, release);
|
|
140
|
+
};
|
|
141
|
+
const read = (body, signal) => {
|
|
142
|
+
const pending = tail.then(async () => {
|
|
143
|
+
try {
|
|
144
|
+
signal?.throwIfAborted();
|
|
145
|
+
const current = await lstat(paths.heart).catch((error) => {
|
|
146
|
+
if (error.code === "ENOENT")
|
|
147
|
+
throw new HeartAbsentError(paths.heart, { cause: error });
|
|
148
|
+
throw error;
|
|
149
|
+
});
|
|
150
|
+
if (identity?.dev !== current.dev || identity?.ino !== current.ino)
|
|
151
|
+
release();
|
|
152
|
+
if (database === undefined) {
|
|
153
|
+
database = await openHeart(paths.heart, "ro");
|
|
154
|
+
identity = current;
|
|
155
|
+
opened += 1;
|
|
156
|
+
}
|
|
157
|
+
await beginTransaction(database, "read", signal);
|
|
158
|
+
return finishTransaction(database, body);
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
release();
|
|
162
|
+
throw error;
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
tail = pending.catch(() => undefined);
|
|
166
|
+
return pending;
|
|
167
|
+
};
|
|
168
|
+
return { read, clear, generation: () => opened };
|
|
169
|
+
}
|
|
115
170
|
export async function withHeartTransaction(paths, body, signal) {
|
|
116
171
|
signal?.throwIfAborted();
|
|
117
172
|
const database = await openHeart(paths.heart, "rw");
|
|
@@ -142,6 +197,12 @@ function finishTransaction(database, body) {
|
|
|
142
197
|
throw error;
|
|
143
198
|
}
|
|
144
199
|
}
|
|
200
|
+
/** Insert one already-admitted pending Tell into an already-open Heart transaction. */
|
|
201
|
+
export function recordPendingTell(heart, tell) {
|
|
202
|
+
const sequence = insertTellFact(heart, tell);
|
|
203
|
+
pruneActivityFacts(heart, ACTIVITY_LIMIT);
|
|
204
|
+
return { kind: "recorded", tell: { sequence, ...tell, state: "pending", deliveries: [] } };
|
|
205
|
+
}
|
|
145
206
|
export async function initializeHeart(paths) {
|
|
146
207
|
const heart = new DatabaseSync(paths.heart);
|
|
147
208
|
try {
|
|
@@ -258,9 +319,7 @@ export class HeldAkumaLeash {
|
|
|
258
319
|
deletePauseControl(heart);
|
|
259
320
|
if (soulFact(heart) === null)
|
|
260
321
|
return { kind: "not-born" };
|
|
261
|
-
|
|
262
|
-
pruneActivityFacts(heart, ACTIVITY_LIMIT);
|
|
263
|
-
return { kind: "recorded", tell: { sequence, ...tell, state: "pending", deliveries: [] } };
|
|
322
|
+
return recordPendingTell(heart, tell);
|
|
264
323
|
});
|
|
265
324
|
}
|
|
266
325
|
release() {
|
|
@@ -37,4 +37,11 @@ export declare function readStatusBatch(database: DatabaseSync, input: StatusFac
|
|
|
37
37
|
};
|
|
38
38
|
export declare function statusFacts(database: DatabaseSync, input: StatusFactInput): readonly TimelineFact[];
|
|
39
39
|
export declare function activityFactSlice(database: DatabaseSync): ActivityFactSlice;
|
|
40
|
+
/**
|
|
41
|
+
* SQLite's cross-connection change counter, sampled inside the read
|
|
42
|
+
* transaction. It identifies exactly the snapshot that transaction decodes: a
|
|
43
|
+
* commit from another connection during the read cannot be mistaken for this
|
|
44
|
+
* one and skipped, because the next transaction reports a new counter.
|
|
45
|
+
*/
|
|
46
|
+
export declare function timelineDataVersion(database: DatabaseSync): number;
|
|
40
47
|
export {};
|
|
@@ -124,3 +124,13 @@ export function activityFactSlice(database) {
|
|
|
124
124
|
highest: bounds.highest,
|
|
125
125
|
};
|
|
126
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* SQLite's cross-connection change counter, sampled inside the read
|
|
129
|
+
* transaction. It identifies exactly the snapshot that transaction decodes: a
|
|
130
|
+
* commit from another connection during the read cannot be mistaken for this
|
|
131
|
+
* one and skipped, because the next transaction reports a new counter.
|
|
132
|
+
*/
|
|
133
|
+
export function timelineDataVersion(database) {
|
|
134
|
+
const row = database.prepare("PRAGMA data_version").get();
|
|
135
|
+
return row?.data_version ?? 0;
|
|
136
|
+
}
|
|
@@ -22,9 +22,6 @@ export const akumaPathsSchema = z
|
|
|
22
22
|
requests: pathText,
|
|
23
23
|
})
|
|
24
24
|
.strict();
|
|
25
|
-
export function archetypeName(value) {
|
|
26
|
-
return validateAkumaName(value);
|
|
27
|
-
}
|
|
28
25
|
function suffixSegment(value) {
|
|
29
26
|
if (!HEX8.test(value))
|
|
30
27
|
throw new TypeError("Akuma suffix must be lower hex8");
|
|
@@ -33,7 +30,7 @@ function suffixSegment(value) {
|
|
|
33
30
|
export function akuId(input) {
|
|
34
31
|
return identityCoordinate({
|
|
35
32
|
family: "aku",
|
|
36
|
-
segments: [
|
|
33
|
+
segments: [validateAkumaName(input.archetype), suffixSegment(input.suffix)],
|
|
37
34
|
});
|
|
38
35
|
}
|
|
39
36
|
export function parseAkuId(value) {
|
|
@@ -94,7 +91,7 @@ export async function ensureAkumaRunRoot(worldRoot) {
|
|
|
94
91
|
return runRoot;
|
|
95
92
|
}
|
|
96
93
|
export async function allocateAkumaDirectory(input) {
|
|
97
|
-
const archetype =
|
|
94
|
+
const archetype = validateAkumaName(input.archetype);
|
|
98
95
|
const runRoot = await ensureAkumaRunRoot(input.worldRoot);
|
|
99
96
|
for (;;) {
|
|
100
97
|
const suffix = suffixSegment(input.draw?.() ?? randomBytes(4).toString("hex"));
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
export type {
|
|
1
|
+
export type { AkumaCaller } from "./caller.js";
|
|
2
|
+
export type { AkumaOrigin } from "./heart/index.js";
|
|
3
|
+
export { AkumaArchetypeError, listArchetypeDefinitions } from "./archetype.js";
|
|
4
|
+
export type { ArchetypeCatalog, ArchetypeCatalogInput, ArchetypeCatalogRow } from "./archetype.js";
|
|
2
5
|
export { AkumaBusyError, AkumaDecodeError, AkumaNotBornError, AkumaProviderError } from "./akuma-errors.js";
|
|
3
6
|
export { Akuma } from "./akuma-instance.js";
|
|
4
|
-
export type { AkumaAskOptions, AkumaBirthInput, AkumaHistoryOptions, AkumaIdleOptions, AkumaIdleResult, AkumaSignalOptions, AkumaTellOptions, } from "./akuma-instance.js";
|
|
7
|
+
export type { AkumaAskOptions, AkumaBirthInput, AkumaHistoryOptions, AkumaHostOptions, AkumaIdleOptions, AkumaIdleResult, AkumaSignalOptions, AkumaTellOptions, } from "./akuma-instance.js";
|
|
8
|
+
export type { AkumaStreamSnapshot } from "./akuma-stream.js";
|
|
5
9
|
export type { InterruptReceipt } from "./akuma-owner.js";
|
|
6
10
|
export type { AkumaStatus } from "./akuma.js";
|
|
7
11
|
export { ALLOWED_ACTIONS } from "./allowed.js";
|
package/build/src/akuma/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { AkumaArchetypeError, listArchetypeDefinitions } from "./archetype.js";
|
|
1
2
|
export { AkumaBusyError, AkumaDecodeError, AkumaNotBornError, AkumaProviderError } from "./akuma-errors.js";
|
|
2
3
|
export { Akuma } from "./akuma-instance.js";
|
|
3
4
|
export { ALLOWED_ACTIONS } from "./allowed.js";
|
package/build/src/akuma/nuke.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { lstat, readdir, rm, rmdir } from "node:fs/promises";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import { nukeAliases } from "../alias/index.js";
|
|
4
|
+
import { knownAkuma } from "./akuma.js";
|
|
4
5
|
import { settleAkumaKill } from "./akuma-owner.js";
|
|
5
6
|
import { acquireLeash } from "./control.js";
|
|
6
7
|
import { classifyHeartSchema, readHeart } from "./heart/index.js";
|
|
7
|
-
import {
|
|
8
|
+
import { akumaRunRoot } from "./identity.js";
|
|
8
9
|
export class AkumaResetStopError extends Error {
|
|
9
10
|
constructor(message) {
|
|
10
11
|
super(message);
|
|
@@ -105,6 +106,7 @@ async function removeKnownRequestChannel(path) {
|
|
|
105
106
|
async function removeAkumaEntry(entry) {
|
|
106
107
|
await removeKnownRequestChannel(entry.paths.requests);
|
|
107
108
|
for (const path of [
|
|
109
|
+
join(entry.paths.directory, "request-entry.json"),
|
|
108
110
|
entry.paths.log,
|
|
109
111
|
`${entry.paths.heart}-wal`,
|
|
110
112
|
`${entry.paths.heart}-shm`,
|
|
@@ -136,34 +138,10 @@ async function removeEmptyAkumaRunRoot(world) {
|
|
|
136
138
|
await removeEmptyDirectory(dirname(runRoot));
|
|
137
139
|
}
|
|
138
140
|
async function nukeAkumaEntries(world) {
|
|
139
|
-
const runRoot = akumaRunRoot(world);
|
|
140
|
-
let names;
|
|
141
|
-
try {
|
|
142
|
-
names = (await readdir(runRoot, { withFileTypes: true }))
|
|
143
|
-
.filter((entry) => entry.isDirectory())
|
|
144
|
-
.map((entry) => entry.name)
|
|
145
|
-
.sort();
|
|
146
|
-
}
|
|
147
|
-
catch (error) {
|
|
148
|
-
if (error.code === "ENOENT")
|
|
149
|
-
names = [];
|
|
150
|
-
else
|
|
151
|
-
throw error;
|
|
152
|
-
}
|
|
153
141
|
const entries = [];
|
|
154
|
-
for (const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
physical = akuIdFromDirectoryName(name);
|
|
158
|
-
}
|
|
159
|
-
catch {
|
|
160
|
-
// The run root can contain bytes not produced by Keiyaku. Preserve them.
|
|
161
|
-
continue;
|
|
162
|
-
}
|
|
163
|
-
const paths = akumaPaths({ runRoot, archetype: physical.archetype, suffix: physical.suffix });
|
|
164
|
-
if (!(await hasAkumaCustody(paths)))
|
|
165
|
-
continue;
|
|
166
|
-
entries.push({ id: physical.id, paths });
|
|
142
|
+
for (const entry of (await knownAkuma(world)).rows) {
|
|
143
|
+
if (await hasAkumaCustody(entry.paths))
|
|
144
|
+
entries.push(entry);
|
|
167
145
|
}
|
|
168
146
|
return entries;
|
|
169
147
|
}
|