@humwick/server 0.130.1 → 0.130.2
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 +5 -0
- package/docs/guides/tools-administration.md +4 -0
- package/docs/guides/tools-coordination.md +1 -0
- package/docs/guides/tools-tasks.md +8 -0
- package/docs/guides/workflows.md +58 -0
- package/docs/openapi.json +414 -1
- package/package.json +8 -17
- package/public/assets/{MessageBubble-BWpoBjl4.js → MessageBubble-BWLqMGKG.js} +2 -2
- package/public/assets/{PlanGraphPanel-C0auck3n.js → PlanGraphPanel-3TlIQpjk.js} +2 -2
- package/public/assets/{TraceView-DBnOx7AQ.js → TraceView-Wimm0Czv.js} +2 -2
- package/public/assets/{VaultDecisionCard-0kp2oNBC.js → VaultDecisionCard-Bau_vNax.js} +2 -2
- package/public/assets/{activity-yLztXEBt.js → activity-CrSurn-r.js} +2 -2
- package/public/assets/{agent-lineage-BbJDR1dW.js → agent-lineage-CknAJKcb.js} +2 -2
- package/public/assets/agent-liveness-CaNwK0Zf.js +2 -0
- package/public/assets/{agent-name-CTZBrSD9.js → agent-name-DKbiIhBo.js} +2 -2
- package/public/assets/agent-profiles-DwF6EQ4R.js +2 -0
- package/public/assets/{agent-project-badge-9TqzUUYE.js → agent-project-badge-Diz4Sjjb.js} +2 -2
- package/public/assets/{agent-tools-D4n40pn8.js → agent-tools-CRhpRQza.js} +2 -2
- package/public/assets/{agent-type-icon-D6FUarOf.js → agent-type-icon-LrUEU3lB.js} +2 -2
- package/public/assets/{agents-BYDslkJc.js → agents-B-v66C-4.js} +2 -2
- package/public/assets/{analytics-B-XSbEMC.js → analytics-BqCb-LKi.js} +2 -2
- package/public/assets/{artifact-viewer-DdWIfV6M.js → artifact-viewer-kf4pGuAR.js} +2 -2
- package/public/assets/{artifacts-oBOqks-2.js → artifacts-D32zyw4Y.js} +2 -2
- package/public/assets/{artifacts-DPN1q4pA.js → artifacts-DJevXcvg.js} +2 -2
- package/public/assets/{automation-4KcRFXEu.js → automation-BpRajx_5.js} +2 -2
- package/public/assets/{backlog-Cw9xPTCF.js → backlog-D_UjTdzX.js} +2 -2
- package/public/assets/{busy-health-CTu32MZt.js → busy-health-N3VEh4ao.js} +2 -2
- package/public/assets/{channels-BiXzg1G9.js → channels-9jopungq.js} +2 -2
- package/public/assets/{chat-Ctk2qwvA.js → chat-CSXrTB3C.js} +2 -2
- package/public/assets/{code-preview-Bm1wWqAp.js → code-preview-p1NnmqK0.js} +2 -2
- package/public/assets/{connectors-C36ax4Vw.js → connectors-CZdqlDNL.js} +2 -2
- package/public/assets/{cosmos-Jj9LK2Wf.js → cosmos-BgdsE4dG.js} +2 -2
- package/public/assets/{crate-agent-H6S7-B9T.js → crate-agent-30aXTKva.js} +2 -2
- package/public/assets/{dependency-graph-Cd1E23wa.js → dependency-graph-B_jvw2GE.js} +2 -2
- package/public/assets/{deploys-Bwfq146q.js → deploys-DoN6bAb5.js} +2 -2
- package/public/assets/{display-CfO7rTuF.js → display-BrKWFGJz.js} +2 -2
- package/public/assets/{files-DhhZI2Ih.js → files-D6XEu8Ng.js} +2 -2
- package/public/assets/{fleet-B_rFEbnL.js → fleet-C7jQWbw2.js} +2 -2
- package/public/assets/{fleet-metrics-BkHP-P3R.js → fleet-metrics-BiDs3MLx.js} +2 -2
- package/public/assets/{formatted-body-Cm1RrzmN.js → formatted-body-CQBwc1fb.js} +3 -3
- package/public/assets/{formatted-body-impl-DQiOuOD1.js → formatted-body-impl-DyG0WsQS.js} +2 -2
- package/public/assets/{host-providers-dialog-CHqwXTov.js → host-providers-dialog-DKaW31dN.js} +2 -2
- package/public/assets/index-CRHep3M9.js +15 -0
- package/public/assets/index-MYAIwYTX.css +2 -0
- package/public/assets/{insights-fH1EL-qZ.js → insights-CzrtkpOE.js} +2 -2
- package/public/assets/{integrations-C5Oix6ng.js → integrations-aVsUmigt.js} +2 -2
- package/public/assets/{issue-ref-chip-ODyondIa.js → issue-ref-chip-BnSlM_95.js} +2 -2
- package/public/assets/{log-viewer-Cvfy6PW7.js → log-viewer-qe7Ee47Z.js} +2 -2
- package/public/assets/{maintenance-D8CDH5wZ.js → maintenance-NfjqFZAk.js} +2 -2
- package/public/assets/{managed-agents-egllbpij.js → managed-agents-BiH0HgaE.js} +2 -2
- package/public/assets/{markdown-preview-CYSFgVgK.js → markdown-preview-BixaT3Xr.js} +3 -3
- package/public/assets/{markdown-preview-impl-BteVIjX4.js → markdown-preview-impl-DNGlWIS3.js} +2 -2
- package/public/assets/{memory-C8WmXsyr.js → memory-DNsCl6UX.js} +2 -2
- package/public/assets/{messages-BzQdqlO6.js → messages-DopU1L1X.js} +2 -2
- package/public/assets/{orchestrators-B1HxzkNw.js → orchestrators-Cq7ckLQT.js} +2 -2
- package/public/assets/{overview-DCUnI4Z7.js → overview-C1DCTzzV.js} +2 -2
- package/public/assets/{pairs-ftCd2XcD.js → pairs-DE_m6rrE.js} +2 -2
- package/public/assets/{profile-icon-B2zH8DMH.js → profile-icon-B3rfh77F.js} +2 -2
- package/public/assets/project-profile-instructions-DQWZE0kA.js +2 -0
- package/public/assets/projects-Br2Bd2h1.js +2 -0
- package/public/assets/{prompt-settings-Bftq9czX.js → prompt-settings-BKvFsvGD.js} +2 -2
- package/public/assets/provider-display-DsuWMvVL.js +2 -0
- package/public/assets/{registry-DWCU5c8q.js → registry-Cw38_6gW.js} +2 -2
- package/public/assets/run-card-CpKqRbhg.js +2 -0
- package/public/assets/scroll-text-BKXS1ahr.js +2 -0
- package/public/assets/{secrets-C7GIUATz.js → secrets-DxI-vzSq.js} +2 -2
- package/public/assets/{service-access-settings-C3aujqTG.js → service-access-settings-D9s_VJbd.js} +2 -2
- package/public/assets/{settings-C6sZ9eBa.js → settings-CKZTVGIx.js} +2 -2
- package/public/assets/{shipping-Bu8p1gEw.js → shipping-B9YtnwtG.js} +2 -2
- package/public/assets/{stats-V9Z-GxUd.js → stats-DyUBKyWI.js} +2 -2
- package/public/assets/{status-dot-CVv0iGHL.js → status-dot-DYqlEUhJ.js} +2 -2
- package/public/assets/{store-BvtFdlGX.js → store-DcClXLH0.js} +3 -3
- package/public/assets/{tasks-CXU75HRF.js → tasks-Bh7Chr4-.js} +2 -2
- package/public/assets/{teams-BPf976zb.js → teams-bowI7qVY.js} +2 -2
- package/public/assets/{terminal-viewer-DE9BOe-8.js → terminal-viewer-BgVLHdsU.js} +3 -3
- package/public/assets/{terminal-viewer-impl-D04pjmGh.js → terminal-viewer-impl-Dz22UPy6.js} +2 -2
- package/public/assets/token-estimate-Co-Jdphh.js +2 -0
- package/public/assets/{use-agent-terminal-B1yR456R.js → use-agent-terminal-DSQQ-iY7.js} +2 -2
- package/public/assets/{use-decisions-D-S4tpDf.js → use-decisions-samMQhQf.js} +2 -2
- package/public/assets/use-project-list-59LheVP7.js +2 -0
- package/public/assets/{use-selectors-CnrAk2YP.js → use-selectors-BZa25xEB.js} +2 -2
- package/public/assets/{user-avatar-nBFIcR4M.js → user-avatar-DHxlvUvV.js} +2 -2
- package/public/assets/versioned-prompt-editor-BmED5DnJ.js +8 -0
- package/public/assets/{work-queue-TCjJxeT-.js → work-queue-CSvpuNLz.js} +2 -2
- package/public/assets/{workflow-marker-Cf3Hf2fN.js → workflow-marker-DAZcj5qt.js} +2 -2
- package/public/assets/{workflows-CXQX20Qj.js → workflows-DdmxRSyg.js} +2 -2
- package/public/assets/{workspaces-qSYzKYMA.js → workspaces-BxeKfVuF.js} +2 -2
- package/public/cosmos.html +4 -4
- package/public/index.html +31 -29
- package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/runner/plugins/claude/hooks/gate-run-guard.provisioned.mjs +31 -1
- package/runner/src/adapters/claude-effort.ts +2 -4
- package/runner/src/adapters/codex-launch-config.ts +4 -5
- package/runner/src/adapters/codex.ts +1 -1
- package/runner/src/adapters/opencode-provider.ts +7 -22
- package/runner/src/adapters/opencode.ts +4 -4
- package/runner/src/agent-runner/credentials.ts +42 -12
- package/runner/src/agent-runner/inbox.ts +27 -0
- package/runner/src/agent-runner/lifecycle-milestones.ts +0 -2
- package/runner/src/bin/claude.ts +4 -0
- package/runner/src/bin/codex.ts +4 -0
- package/runner/src/bin/opencode.ts +4 -0
- package/runner/src/index.ts +5 -2
- package/runner/src/provider-setup.ts +34 -0
- package/runner/src/providers.ts +2 -1
- package/runner/src/runner-core.ts +18 -23
- package/runner/src/spawn-input.ts +2 -1
- package/runner/src/test-run-dedup.ts +59 -56
- package/scripts/cd-config.ts +8 -0
- package/scripts/gate-run-lease.ts +10 -7
- package/scripts/gate.sh +5 -1
- package/src/branch-land-notice.ts +93 -0
- package/src/branch-landed.ts +7 -76
- package/src/bus.ts +19 -20
- package/src/cd-deploy-notify.ts +30 -2
- package/src/cd-host-lag-notify.ts +7 -6
- package/src/ci/incidents.ts +2 -2
- package/src/ci/monitor.ts +5 -8
- package/src/ci/root-missing.ts +2 -7
- package/src/ci/transition-notify.ts +7 -39
- package/src/cli/cd-pauses.ts +19 -0
- package/src/cli/orchestrator.ts +1 -1
- package/src/cli/state.ts +2 -19
- package/src/cli/task-edit.ts +22 -0
- package/src/cli/task.ts +3 -1
- package/src/cli/workflow.ts +8 -2
- package/src/commands-db.ts +3 -3
- package/src/config-store-write.ts +13 -1
- package/src/config-store.ts +25 -14
- package/src/db/activity-async.ts +6 -1
- package/src/db/activity-write-ops.ts +12 -1
- package/src/db/activity.ts +1 -14
- package/src/db/agent-search.ts +1 -15
- package/src/db/agents-async.ts +52 -5
- package/src/db/agents-write-ops.ts +12 -3
- package/src/db/agents.ts +81 -54
- package/src/db/ci-incidents-async.ts +5 -5
- package/src/db/ci-incidents-write-ops.ts +2 -2
- package/src/db/command-row.ts +10 -2
- package/src/db/commands-list-query.ts +2 -0
- package/src/db/commands-spawn-read.ts +1 -1
- package/src/db/config-store-write-ops.ts +7 -2
- package/src/db/continuation-archives-async.ts +5 -0
- package/src/db/continuation-archives-write-ops.ts +7 -0
- package/src/db/continuations.ts +2 -2
- package/src/db/db-writer-worker.ts +8 -1
- package/src/db/deploy-events-async.ts +1 -0
- package/src/db/deploy-events-read-ops.ts +2 -1
- package/src/db/deploy-events.ts +35 -4
- package/src/db/hosts-registration.ts +10 -2
- package/src/db/hosts.ts +9 -6
- package/src/db/inbox.ts +0 -14
- package/src/db/index.ts +2 -0
- package/src/db/integrations-async.ts +8 -0
- package/src/db/integrations-ops.ts +15 -0
- package/src/db/integrations.ts +15 -21
- package/src/db/issue-lifecycle.ts +3 -4
- package/src/db/issue-refs-async.ts +20 -0
- package/src/db/issue-refs-write-ops.ts +29 -0
- package/src/db/issue-refs.ts +7 -8
- package/src/db/long-running-work.ts +2 -2
- package/src/db/main-connection-writes.ts +23 -2
- package/src/db/maintenance-job-reconcile.ts +61 -0
- package/src/db/maintenance-job-runs-async.ts +14 -0
- package/src/db/maintenance-job-write-ops.ts +9 -0
- package/src/db/mappers.ts +2 -14
- package/src/db/merge-lease.ts +1 -15
- package/src/db/migrations.ts +7 -15
- package/src/db/orchestrators.ts +4 -72
- package/src/db/pairs.ts +1 -13
- package/src/db/project-profile-instructions.ts +50 -0
- package/src/db/prompt-versions.ts +9 -2
- package/src/db/provider-config-history.ts +8 -3
- package/src/db/provider-model-seed.ts +34 -0
- package/src/db/read-op-marshaling-fixtures.ts +5 -0
- package/src/db/read-ops.ts +4 -0
- package/src/db/routing-policy.ts +2 -3
- package/src/db/schema.ts +9 -3
- package/src/db/spawn-delegation-state.ts +11 -4
- package/src/db/stats-async.ts +4 -3
- package/src/db/task-entity.ts +23 -2
- package/src/db/task-list.ts +3 -1
- package/src/db/tasks.ts +1 -17
- package/src/db/timer-ingress.ts +7 -1
- package/src/db/token-db-write-ops.ts +17 -0
- package/src/db/token-standing.ts +15 -11
- package/src/db/workflow-contact.ts +1 -1
- package/src/db/workflow-task-read-ops.ts +30 -0
- package/src/db/write-ops.ts +6 -0
- package/src/db/writer-gateway.ts +17 -11
- package/src/dispatch-availability.ts +10 -6
- package/src/ephemeral/{landing-ingress-proof-worker.ts → landing-ingress-proof.test-fixture.ts} +4 -2
- package/src/host/disk-alert.ts +121 -0
- package/src/lifecycle-manager.ts +3 -2
- package/src/maintenance/cd-watcher.ts +3 -3
- package/src/maintenance/critical-job-watchdog.ts +16 -17
- package/src/maintenance/index.ts +1 -0
- package/src/maintenance/jobs.ts +3 -2
- package/src/maintenance/scheduler.ts +84 -128
- package/src/maintenance/stalled-delivery-pager.ts +6 -5
- package/src/maintenance/workspaces.ts +1 -1
- package/src/managed-policy.ts +31 -27
- package/src/mcp/index.ts +5 -2
- package/src/mcp/output-descriptions.ts +8 -8
- package/src/mcp/presentation.ts +4 -4
- package/src/mcp/project-profile-instructions.ts +32 -0
- package/src/mcp/tool-groups.ts +1 -1
- package/src/mcp/tools-spawn.ts +4 -3
- package/src/mcp-agent-action.ts +1 -2
- package/src/mcp-issue-ref-tools.ts +12 -11
- package/src/mcp-maintenance-tools.ts +2 -2
- package/src/mcp-profile-trust-tools.ts +4 -4
- package/src/mcp-provider-catalog.ts +2 -2
- package/src/mcp-task-tools.ts +11 -5
- package/src/mcp-team-template-tools.ts +3 -3
- package/src/mcp-workflow-tools.ts +10 -3
- package/src/notification-types.ts +2 -1
- package/src/operator-alarm.ts +26 -11
- package/src/project-instructions.ts +4 -0
- package/src/project-profile-instruction-text.ts +6 -0
- package/src/project-profile-instructions.ts +20 -0
- package/src/provider-catalog-store.ts +3 -49
- package/src/provider-config-store.ts +12 -11
- package/src/provider-model-seed.ts +1 -18
- package/src/provider-quota-config-store.ts +5 -4
- package/src/provider-secrets.test-fixture.ts +3 -3
- package/src/recipe-runner.ts +2 -2
- package/src/repo-config-source.ts +10 -4
- package/src/routes/agent-profiles.ts +6 -6
- package/src/routes/agents-spawn.ts +1 -1
- package/src/routes/agents.ts +6 -6
- package/src/routes/commands-listing.ts +4 -0
- package/src/routes/commands.ts +2 -2
- package/src/routes/continuation-archives.ts +2 -2
- package/src/routes/index.ts +10 -1
- package/src/routes/integrations.ts +24 -50
- package/src/routes/issue-refs.ts +7 -7
- package/src/routes/orchestrator-bootstrap.ts +1 -1
- package/src/routes/orchestrator-host-registration.ts +2 -2
- package/src/routes/orchestrator-host-utilization.ts +3 -1
- package/src/routes/orchestrator-proxy.ts +2 -2
- package/src/routes/orchestrator.ts +2 -2
- package/src/routes/project-profile-instructions.ts +27 -0
- package/src/routes/project-trust.ts +2 -2
- package/src/routes/provider-config.ts +6 -6
- package/src/routes/provider-quota-config.ts +2 -2
- package/src/routes/settings.ts +5 -5
- package/src/routes/stats.ts +6 -6
- package/src/routes/task-http.ts +15 -1
- package/src/routes/task-issues.ts +11 -26
- package/src/routes/tasks.ts +22 -53
- package/src/routes/team-templates.ts +5 -5
- package/src/routes/teams-config.ts +2 -2
- package/src/routes/tokens.ts +12 -5
- package/src/routes/workflows.ts +20 -5
- package/src/routing-policy-normalize.ts +1 -2
- package/src/routing-step-defaults.ts +0 -2
- package/src/runner-token-mint-limit.ts +63 -0
- package/src/runtime-grant.ts +4 -2
- package/src/runtime-tokens.ts +39 -7
- package/src/security.ts +13 -20
- package/src/server-background.ts +1 -1
- package/src/server.ts +5 -2
- package/src/services/host-utilization.ts +23 -0
- package/src/services/idle-epics.ts +5 -6
- package/src/services/issue-lifecycle.ts +57 -61
- package/src/services/issue-refs.ts +9 -13
- package/src/services/kernel-timers-cutover-chaos-worker.ts +10 -7
- package/src/services/kernel-timers-ingress.ts +1 -1
- package/src/services/landed-ancestry.ts +19 -3
- package/src/services/memory-areas.ts +15 -51
- package/src/services/plan-ci-notice.ts +57 -0
- package/src/services/plan-ci-recovery.ts +2 -55
- package/src/services/plan-wake-digest.ts +1 -0
- package/src/services/profile-trust.ts +4 -3
- package/src/services/project-config-read.ts +70 -0
- package/src/services/project-profile-instructions.ts +54 -0
- package/src/services/provisioning-harness/budget-baseline.json +4 -4
- package/src/services/restart-spawn.ts +61 -49
- package/src/services/self-care-state.ts +2 -1
- package/src/services/self-effort.ts +5 -5
- package/src/services/send-message.ts +5 -1
- package/src/services/spawn-agent.ts +13 -2
- package/src/services/spawn-chain-inspector.ts +6 -13
- package/src/services/spawn-policy.ts +68 -0
- package/src/services/spawn-tree-cleanup.ts +2 -2
- package/src/services/task-dispatch.ts +3 -0
- package/src/services/task-state-reconcile.ts +6 -14
- package/src/services/team-templates.ts +9 -8
- package/src/services/transient-agent-reaper.ts +3 -1
- package/src/services/workflow-auto-start.ts +25 -13
- package/src/services/workflow-ci-main.ts +1 -1
- package/src/services/workflow-deferred-cleanup.ts +4 -2
- package/src/services/workflow-effect-driver.ts +2 -0
- package/src/services/workflow-effects.ts +18 -11
- package/src/services/workflow-land-notice.ts +10 -0
- package/src/services/workflow-pause-text.ts +43 -0
- package/src/services/workflow-reconcile.ts +13 -11
- package/src/services/workflow-run-view.ts +2 -0
- package/src/services/workflow-runs.ts +29 -13
- package/src/services/workflow-supervisor-state.ts +5 -0
- package/src/services/workflow-supervisor.ts +7 -3
- package/src/settings/registry.ts +1 -2
- package/src/spawn-command.ts +4 -4
- package/src/spawn-models.ts +10 -12
- package/src/spawn-placement.ts +1 -1
- package/src/spawn-targets.ts +1 -1
- package/src/startup-context-injection.ts +1 -0
- package/src/state-adoption/cd-cutover.ts +53 -7
- package/src/state-adoption/fleet-cutover.ts +35 -0
- package/src/state-adoption/fleet-plan.ts +36 -0
- package/src/state-adoption/index.ts +2 -2
- package/src/state-adoption/linux-plan.ts +2 -2
- package/src/state-adoption/linux.ts +2 -2
- package/src/state-adoption/macos-plan.ts +2 -2
- package/src/state-adoption/macos.ts +1 -1
- package/src/steward.ts +7 -6
- package/src/task-dispatch-live.ts +1 -1
- package/src/task-dispatcher.ts +1 -1
- package/src/teams-config-store.ts +4 -3
- package/src/token-db-write.ts +10 -0
- package/src/workspace-command-settle.ts +2 -1
- package/src/workspace-steward-wake.ts +2 -2
- package/node_modules/@humwick/kernel/LICENSE +0 -167
- package/node_modules/@humwick/kernel/async-entity-persistence.ts +0 -344
- package/node_modules/@humwick/kernel/async-event-log.ts +0 -107
- package/node_modules/@humwick/kernel/automations.pilot.ts +0 -147
- package/node_modules/@humwick/kernel/config.ts +0 -111
- package/node_modules/@humwick/kernel/contract.ts +0 -572
- package/node_modules/@humwick/kernel/control-authz.ts +0 -281
- package/node_modules/@humwick/kernel/control.ts +0 -645
- package/node_modules/@humwick/kernel/effects.ts +0 -493
- package/node_modules/@humwick/kernel/event-log.ts +0 -319
- package/node_modules/@humwick/kernel/http-transport.ts +0 -384
- package/node_modules/@humwick/kernel/identity-grammar.ts +0 -20
- package/node_modules/@humwick/kernel/identity.ts +0 -248
- package/node_modules/@humwick/kernel/index.ts +0 -28
- package/node_modules/@humwick/kernel/kernel-persistence.ts +0 -181
- package/node_modules/@humwick/kernel/landing-incident.ts +0 -306
- package/node_modules/@humwick/kernel/landing.ts +0 -953
- package/node_modules/@humwick/kernel/manifest-validation.ts +0 -460
- package/node_modules/@humwick/kernel/mcp-transport.ts +0 -109
- package/node_modules/@humwick/kernel/message-authority-chaos-worker.ts +0 -200
- package/node_modules/@humwick/kernel/message-authority.ts +0 -281
- package/node_modules/@humwick/kernel/module-host.ts +0 -722
- package/node_modules/@humwick/kernel/openapi-init.ts +0 -14
- package/node_modules/@humwick/kernel/package.json +0 -39
- package/node_modules/@humwick/kernel/persistence-schema.ts +0 -248
- package/node_modules/@humwick/kernel/persistence.ts +0 -510
- package/node_modules/@humwick/kernel/registry.ts +0 -60
- package/node_modules/@humwick/kernel/sqlite-kernel-persistence.ts +0 -499
- package/node_modules/@humwick/kernel/sqlite-module-host.ts +0 -87
- package/node_modules/@humwick/kernel/timers-chaos-worker.ts +0 -186
- package/node_modules/@humwick/kernel/timers.pilot.ts +0 -1411
- package/node_modules/@humwick/kernel/workflow-activation.ts +0 -25
- package/node_modules/@humwick/kernel/workflow-backstop.ts +0 -40
- package/node_modules/@humwick/kernel/workflow-cancel-tree.ts +0 -20
- package/node_modules/@humwick/kernel/workflow-chaos-worker.ts +0 -213
- package/node_modules/@humwick/kernel/workflow-composition.ts +0 -231
- package/node_modules/@humwick/kernel/workflow-container.ts +0 -72
- package/node_modules/@humwick/kernel/workflow-control.test-fixture.ts +0 -42
- package/node_modules/@humwick/kernel/workflow-control.ts +0 -178
- package/node_modules/@humwick/kernel/workflow-definition.ts +0 -507
- package/node_modules/@humwick/kernel/workflow-dispatch.ts +0 -60
- package/node_modules/@humwick/kernel/workflow-foreach.ts +0 -167
- package/node_modules/@humwick/kernel/workflow-journal-codec.ts +0 -339
- package/node_modules/@humwick/kernel/workflow-journal.ts +0 -922
- package/node_modules/@humwick/kernel/workflow-lane.ts +0 -48
- package/node_modules/@humwick/kernel/workflow-lease-owner.ts +0 -60
- package/node_modules/@humwick/kernel/workflow-recovery.test-fixture.ts +0 -19
- package/node_modules/@humwick/kernel/workflow-runtime.ts +0 -938
- package/node_modules/@humwick/kernel/workflow-script.ts +0 -11
- package/node_modules/@humwick/kernel/workflow-state.ts +0 -299
- package/node_modules/@humwick/kernel/workflow-step-commit.ts +0 -195
- package/node_modules/@humwick/kernel/workflow-transitions.ts +0 -317
- package/node_modules/@humwick/kernel/workflow-values.ts +0 -153
- package/node_modules/@humwick/kernel/workflow.pilot.ts +0 -376
- package/node_modules/@humwick/offload/LICENSE +0 -167
- package/node_modules/@humwick/offload/README.md +0 -57
- package/node_modules/@humwick/offload/dist/async-runner.d.ts +0 -18
- package/node_modules/@humwick/offload/dist/async-runner.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/async-runner.js +0 -158
- package/node_modules/@humwick/offload/dist/async-runner.js.map +0 -1
- package/node_modules/@humwick/offload/dist/envelope.d.ts +0 -25
- package/node_modules/@humwick/offload/dist/envelope.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/envelope.js +0 -80
- package/node_modules/@humwick/offload/dist/envelope.js.map +0 -1
- package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts +0 -10
- package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/fixtures/worker-task.js +0 -59
- package/node_modules/@humwick/offload/dist/fixtures/worker-task.js.map +0 -1
- package/node_modules/@humwick/offload/dist/index.d.ts +0 -5
- package/node_modules/@humwick/offload/dist/index.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/index.js +0 -5
- package/node_modules/@humwick/offload/dist/index.js.map +0 -1
- package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts +0 -62
- package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/subprocess-runner.js +0 -295
- package/node_modules/@humwick/offload/dist/subprocess-runner.js.map +0 -1
- package/node_modules/@humwick/offload/dist/types.d.ts +0 -111
- package/node_modules/@humwick/offload/dist/types.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/types.js +0 -176
- package/node_modules/@humwick/offload/dist/types.js.map +0 -1
- package/node_modules/@humwick/offload/dist/worker-pool.d.ts +0 -23
- package/node_modules/@humwick/offload/dist/worker-pool.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/worker-pool.js +0 -435
- package/node_modules/@humwick/offload/dist/worker-pool.js.map +0 -1
- package/node_modules/@humwick/offload/dist/worker-runtime.d.ts +0 -2
- package/node_modules/@humwick/offload/dist/worker-runtime.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/worker-runtime.js +0 -27
- package/node_modules/@humwick/offload/dist/worker-runtime.js.map +0 -1
- package/node_modules/@humwick/offload/dist/worker.d.ts +0 -5
- package/node_modules/@humwick/offload/dist/worker.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/worker.js +0 -1
- package/node_modules/@humwick/offload/dist/worker.js.map +0 -1
- package/node_modules/@humwick/offload/package.json +0 -42
- package/node_modules/@humwick/offload/src/async-runner.ts +0 -170
- package/node_modules/@humwick/offload/src/envelope.ts +0 -92
- package/node_modules/@humwick/offload/src/fixtures/worker-task.ts +0 -49
- package/node_modules/@humwick/offload/src/index.ts +0 -4
- package/node_modules/@humwick/offload/src/subprocess-runner.ts +0 -334
- package/node_modules/@humwick/offload/src/types.ts +0 -235
- package/node_modules/@humwick/offload/src/worker-pool.ts +0 -463
- package/node_modules/@humwick/offload/src/worker-runtime.ts +0 -32
- package/node_modules/@humwick/offload/src/worker.ts +0 -5
- package/public/assets/agent-liveness-DyqxfB-t.js +0 -2
- package/public/assets/agent-profiles-BpI_jTxq.js +0 -2
- package/public/assets/index-B7ZerHLY.css +0 -2
- package/public/assets/index-BU3uWo2t.js +0 -15
- package/public/assets/projects-B_lmcqfO.js +0 -2
- package/public/assets/provider-display-DbLWpP3j.js +0 -2
- package/public/assets/run-card-CO_bguQf.js +0 -2
- package/public/assets/use-project-list-B-T2Bnnn.js +0 -2
- package/public/assets/versioned-prompt-editor-Diu8BIaM.js +0 -8
- package/runner/src/gate-run-lease-probe.ts +0 -38
- package/src/db/claude-catalog-reconcile.ts +0 -27
- package/src/routing-model-aliases.ts +0 -21
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
# PolyForm Shield License 1.0.0
|
|
2
|
-
|
|
3
|
-
<https://polyformproject.org/licenses/shield/1.0.0>
|
|
4
|
-
|
|
5
|
-
## Acceptance
|
|
6
|
-
|
|
7
|
-
In order to get any license under these terms, you must agree
|
|
8
|
-
to them as both strict obligations and conditions to all
|
|
9
|
-
your licenses.
|
|
10
|
-
|
|
11
|
-
## Copyright License
|
|
12
|
-
|
|
13
|
-
The licensor grants you a copyright license for the
|
|
14
|
-
software to do everything you might do with the software
|
|
15
|
-
that would otherwise infringe the licensor's copyright
|
|
16
|
-
in it for any permitted purpose. However, you may
|
|
17
|
-
only distribute the software according to [Distribution
|
|
18
|
-
License](#distribution-license) and make changes or new works
|
|
19
|
-
based on the software according to [Changes and New Works
|
|
20
|
-
License](#changes-and-new-works-license).
|
|
21
|
-
|
|
22
|
-
## Distribution License
|
|
23
|
-
|
|
24
|
-
The licensor grants you an additional copyright license
|
|
25
|
-
to distribute copies of the software. Your license
|
|
26
|
-
to distribute covers distributing the software with
|
|
27
|
-
changes and new works permitted by [Changes and New Works
|
|
28
|
-
License](#changes-and-new-works-license).
|
|
29
|
-
|
|
30
|
-
## Notices
|
|
31
|
-
|
|
32
|
-
You must ensure that anyone who gets a copy of any part of
|
|
33
|
-
the software from you also gets a copy of these terms or the
|
|
34
|
-
URL for them above, as well as copies of any plain-text lines
|
|
35
|
-
beginning with `Required Notice:` that the licensor provided
|
|
36
|
-
with the software. For example:
|
|
37
|
-
|
|
38
|
-
> Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
|
|
39
|
-
|
|
40
|
-
## Changes and New Works License
|
|
41
|
-
|
|
42
|
-
The licensor grants you an additional copyright license to
|
|
43
|
-
make changes and new works based on the software for any
|
|
44
|
-
permitted purpose.
|
|
45
|
-
|
|
46
|
-
## Patent License
|
|
47
|
-
|
|
48
|
-
The licensor grants you a patent license for the software that
|
|
49
|
-
covers patent claims the licensor can license, or becomes able
|
|
50
|
-
to license, that you would infringe by using the software.
|
|
51
|
-
|
|
52
|
-
## Noncompete
|
|
53
|
-
|
|
54
|
-
Any purpose is a permitted purpose, except for providing any
|
|
55
|
-
product that competes with the software or any product the
|
|
56
|
-
licensor or any of its affiliates provides using the software.
|
|
57
|
-
|
|
58
|
-
## Competition
|
|
59
|
-
|
|
60
|
-
Goods and services compete even when they provide functionality
|
|
61
|
-
through different kinds of interfaces or for different technical
|
|
62
|
-
platforms. Applications can compete with services, libraries
|
|
63
|
-
with plugins, frameworks with development tools, and so on,
|
|
64
|
-
even if they're written in different programming languages
|
|
65
|
-
or for different computer architectures. Goods and services
|
|
66
|
-
compete even when provided free of charge. If you market a
|
|
67
|
-
product as a practical substitute for the software or another
|
|
68
|
-
product, it definitely competes.
|
|
69
|
-
|
|
70
|
-
## New Products
|
|
71
|
-
|
|
72
|
-
If you are using the software to provide a product that does
|
|
73
|
-
not compete, but the licensor or any of its affiliates brings
|
|
74
|
-
your product into competition by providing a new version of
|
|
75
|
-
the software or another product using the software, you may
|
|
76
|
-
continue using versions of the software available under these
|
|
77
|
-
terms beforehand to provide your competing product, but not
|
|
78
|
-
any later versions.
|
|
79
|
-
|
|
80
|
-
## Discontinued Products
|
|
81
|
-
|
|
82
|
-
You may begin using the software to compete with a product
|
|
83
|
-
or service that the licensor or any of its affiliates has
|
|
84
|
-
stopped providing, unless the licensor includes a plain-text
|
|
85
|
-
line beginning with `Licensor Line of Business:` with the
|
|
86
|
-
software that mentions that line of business. For example:
|
|
87
|
-
|
|
88
|
-
> Licensor Line of Business: YoyodyneCMS Content Management
|
|
89
|
-
System (http://example.com/cms)
|
|
90
|
-
|
|
91
|
-
## Sales of Business
|
|
92
|
-
|
|
93
|
-
If the licensor or any of its affiliates sells a line of
|
|
94
|
-
business developing the software or using the software
|
|
95
|
-
to provide a product, the buyer can also enforce
|
|
96
|
-
[Noncompete](#noncompete) for that product.
|
|
97
|
-
|
|
98
|
-
## Fair Use
|
|
99
|
-
|
|
100
|
-
You may have "fair use" rights for the software under the
|
|
101
|
-
law. These terms do not limit them.
|
|
102
|
-
|
|
103
|
-
## No Other Rights
|
|
104
|
-
|
|
105
|
-
These terms do not allow you to sublicense or transfer any of
|
|
106
|
-
your licenses to anyone else, or prevent the licensor from
|
|
107
|
-
granting licenses to anyone else. These terms do not imply
|
|
108
|
-
any other licenses.
|
|
109
|
-
|
|
110
|
-
## Patent Defense
|
|
111
|
-
|
|
112
|
-
If you make any written claim that the software infringes or
|
|
113
|
-
contributes to infringement of any patent, your patent license
|
|
114
|
-
for the software granted under these terms ends immediately. If
|
|
115
|
-
your company makes such a claim, your patent license ends
|
|
116
|
-
immediately for work on behalf of your company.
|
|
117
|
-
|
|
118
|
-
## Violations
|
|
119
|
-
|
|
120
|
-
The first time you are notified in writing that you have
|
|
121
|
-
violated any of these terms, or done anything with the software
|
|
122
|
-
not covered by your licenses, your licenses can nonetheless
|
|
123
|
-
continue if you come into full compliance with these terms,
|
|
124
|
-
and take practical steps to correct past violations, within
|
|
125
|
-
32 days of receiving notice. Otherwise, all your licenses
|
|
126
|
-
end immediately.
|
|
127
|
-
|
|
128
|
-
## No Liability
|
|
129
|
-
|
|
130
|
-
***As far as the law allows, the software comes as is, without
|
|
131
|
-
any warranty or condition, and the licensor will not be liable
|
|
132
|
-
to you for any damages arising out of these terms or the use
|
|
133
|
-
or nature of the software, under any kind of legal claim.***
|
|
134
|
-
|
|
135
|
-
## Definitions
|
|
136
|
-
|
|
137
|
-
The **licensor** is the individual or entity offering these
|
|
138
|
-
terms, and the **software** is the software the licensor makes
|
|
139
|
-
available under these terms.
|
|
140
|
-
|
|
141
|
-
A **product** can be a good or service, or a combination
|
|
142
|
-
of them.
|
|
143
|
-
|
|
144
|
-
**You** refers to the individual or entity agreeing to these
|
|
145
|
-
terms.
|
|
146
|
-
|
|
147
|
-
**Your company** is any legal entity, sole proprietorship,
|
|
148
|
-
or other kind of organization that you work for, plus all
|
|
149
|
-
its affiliates.
|
|
150
|
-
|
|
151
|
-
**Affiliates** means the other organizations than an
|
|
152
|
-
organization has control over, is under the control of, or is
|
|
153
|
-
under common control with.
|
|
154
|
-
|
|
155
|
-
**Control** means ownership of substantially all the assets of
|
|
156
|
-
an entity, or the power to direct its management and policies
|
|
157
|
-
by vote, contract, or otherwise. Control can be direct or
|
|
158
|
-
indirect.
|
|
159
|
-
|
|
160
|
-
**Your licenses** are all the licenses granted to you for the
|
|
161
|
-
software under these terms.
|
|
162
|
-
|
|
163
|
-
**Use** means anything you do with the software requiring one
|
|
164
|
-
of your licenses.
|
|
165
|
-
|
|
166
|
-
Required Notice: Copyright 2026 Exelerus AB
|
|
167
|
-
Licensor Line of Business: provider-independent runtimes and coordination software for teams of AI agents
|
|
@@ -1,344 +0,0 @@
|
|
|
1
|
-
import { Buffer } from "node:buffer";
|
|
2
|
-
import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
|
|
3
|
-
import type { EntityListOptions, EntityPage, EntityStore, EntityStores, ModuleDefinition, ModuleManifest, Scope } from "./contract";
|
|
4
|
-
import type { KernelEntityMutation, KernelEntityStoredRow, KernelPersistence, KernelStoredValue } from "./kernel-persistence";
|
|
5
|
-
import { assertValidManifest } from "./manifest-validation";
|
|
6
|
-
import {
|
|
7
|
-
EntityConflictError,
|
|
8
|
-
EntityNotFoundError,
|
|
9
|
-
EntitySessionClosedError,
|
|
10
|
-
type EntityRawListOptions,
|
|
11
|
-
type EntityRawPage,
|
|
12
|
-
type EntityRawRow,
|
|
13
|
-
} from "./persistence";
|
|
14
|
-
import {
|
|
15
|
-
buildModuleEntityCatalog,
|
|
16
|
-
decodeField,
|
|
17
|
-
encodeField,
|
|
18
|
-
entityCatalogOf,
|
|
19
|
-
type EntityField,
|
|
20
|
-
type EntityTable,
|
|
21
|
-
} from "./persistence-schema";
|
|
22
|
-
|
|
23
|
-
type EntityValue = Record<string, unknown>;
|
|
24
|
-
|
|
25
|
-
interface RowState {
|
|
26
|
-
readonly table: EntityTable;
|
|
27
|
-
readonly key: unknown;
|
|
28
|
-
readonly expectedVersion: number | null;
|
|
29
|
-
value?: EntityValue;
|
|
30
|
-
deleted?: boolean;
|
|
31
|
-
mutation?: "put" | "delete";
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function keyIdentity(table: EntityTable, key: unknown): string {
|
|
35
|
-
const encoded = encodeField(table.key, key);
|
|
36
|
-
const parts = [table.name, typeof encoded, String(encoded)];
|
|
37
|
-
return parts.map((part) => `${part.length}:${part}`).join("");
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function decodedValue(table: EntityTable, row: KernelEntityStoredRow): EntityValue {
|
|
41
|
-
const value: EntityValue = {};
|
|
42
|
-
for (const field of table.fields) {
|
|
43
|
-
const decoded = decodeField(field, row.values[field.name]);
|
|
44
|
-
if (decoded !== undefined) value[field.name] = decoded;
|
|
45
|
-
}
|
|
46
|
-
return table.decl.schema.parse(value) as EntityValue;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function sign(secret: Buffer, body: string): string {
|
|
50
|
-
return createHmac("sha256", secret).update(body).digest("base64url");
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function encodeCursor(secret: Buffer, table: EntityTable, scope: Scope, key: KernelStoredValue): string {
|
|
54
|
-
const body = Buffer.from(JSON.stringify({ v: 3, module: table.moduleId, entity: table.entityName, scope, type: typeof key, key: typeof key === "bigint" ? key.toString() : key })).toString("base64url");
|
|
55
|
-
return `${body}.${sign(secret, body)}`;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function decodeCursor(secret: Buffer, table: EntityTable, scope: Scope, cursor: string): KernelStoredValue {
|
|
59
|
-
try {
|
|
60
|
-
const split = cursor.lastIndexOf(".");
|
|
61
|
-
if (split < 0) throw new Error();
|
|
62
|
-
const body = cursor.slice(0, split);
|
|
63
|
-
const actual = Buffer.from(cursor.slice(split + 1));
|
|
64
|
-
const expected = Buffer.from(sign(secret, body));
|
|
65
|
-
if (actual.length !== expected.length || !timingSafeEqual(actual, expected)) throw new Error();
|
|
66
|
-
const value = JSON.parse(Buffer.from(body, "base64url").toString("utf8")) as { v: number; module: string; entity: string; scope: string; type: string; key: KernelStoredValue };
|
|
67
|
-
if (value.v !== 3 || value.module !== table.moduleId || value.entity !== table.entityName || value.scope !== scope) throw new Error();
|
|
68
|
-
if (value.type === "bigint") return BigInt(value.key as string);
|
|
69
|
-
if (value.type !== typeof value.key) throw new Error();
|
|
70
|
-
return value.key;
|
|
71
|
-
} catch {
|
|
72
|
-
throw new TypeError(`invalid cursor for entity '${table.moduleId}.${table.entityName}'`);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function pageSize(limit: number | undefined): number {
|
|
77
|
-
const resolved = limit ?? 50;
|
|
78
|
-
if (!Number.isInteger(resolved) || resolved < 1 || resolved > 200) {
|
|
79
|
-
throw new RangeError("entity page limit must be an integer from 1 to 200");
|
|
80
|
-
}
|
|
81
|
-
return resolved;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function compareKeys(table: EntityTable, left: unknown, right: unknown): number {
|
|
85
|
-
const a = encodeField(table.key, left);
|
|
86
|
-
const b = encodeField(table.key, right);
|
|
87
|
-
return a === b ? 0 : a! < b! ? -1 : 1;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function matchesWhere(value: EntityValue, where: ReadonlyMap<EntityField, unknown>): boolean {
|
|
91
|
-
for (const [field, expected] of where) {
|
|
92
|
-
if (encodeField(field, value[field.name]) !== encodeField(field, expected)) return false;
|
|
93
|
-
}
|
|
94
|
-
return true;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export interface AsyncEntitySession<E> {
|
|
98
|
-
readonly entities: EntityStores<E>;
|
|
99
|
-
readonly pendingMutations: number;
|
|
100
|
-
seal(): void;
|
|
101
|
-
discard(): void;
|
|
102
|
-
mutations(): readonly KernelEntityMutation[];
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
class AsyncEntitySessionRuntime<E> implements AsyncEntitySession<E> {
|
|
106
|
-
readonly entities: EntityStores<E>;
|
|
107
|
-
readonly #states = new Map<string, RowState>();
|
|
108
|
-
#closed = false;
|
|
109
|
-
#finished = false;
|
|
110
|
-
|
|
111
|
-
constructor(
|
|
112
|
-
readonly port: KernelPersistence,
|
|
113
|
-
readonly ready: Promise<void>,
|
|
114
|
-
readonly scope: Scope,
|
|
115
|
-
readonly cursorSecret: Buffer,
|
|
116
|
-
tables: ReadonlyMap<string, EntityTable>,
|
|
117
|
-
) {
|
|
118
|
-
this.entities = Object.freeze(Object.fromEntries(
|
|
119
|
-
[...tables].map(([name, table]) => [name, this.#store(table)]),
|
|
120
|
-
)) as EntityStores<E>;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
get pendingMutations(): number {
|
|
124
|
-
return [...this.#states.values()].filter((state) => state.mutation !== undefined).length;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
#assertOpen(): void {
|
|
128
|
-
if (this.#closed) throw new EntitySessionClosedError();
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
async #read(table: EntityTable, key: unknown): Promise<RowState> {
|
|
132
|
-
const identity = keyIdentity(table, key);
|
|
133
|
-
const known = this.#states.get(identity);
|
|
134
|
-
if (known) return known;
|
|
135
|
-
await this.ready;
|
|
136
|
-
const row = await this.port.entityPoint({ entity: entityCatalogOf(table), scope: this.scope, key: encodeField(table.key, key) });
|
|
137
|
-
const state: RowState = { table, key, expectedVersion: row?.version ?? null, value: row ? decodedValue(table, row) : undefined };
|
|
138
|
-
this.#states.set(identity, state);
|
|
139
|
-
return state;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
#remember(table: EntityTable, row: KernelEntityStoredRow): RowState {
|
|
143
|
-
const value = decodedValue(table, row);
|
|
144
|
-
const key = value[table.key.name];
|
|
145
|
-
const identity = keyIdentity(table, key);
|
|
146
|
-
const known = this.#states.get(identity);
|
|
147
|
-
if (known) return known;
|
|
148
|
-
const state: RowState = { table, key, expectedVersion: row.version, value };
|
|
149
|
-
this.#states.set(identity, state);
|
|
150
|
-
return state;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
#store(table: EntityTable): EntityStore {
|
|
154
|
-
return {
|
|
155
|
-
get: async (key) => {
|
|
156
|
-
this.#assertOpen();
|
|
157
|
-
const state = await this.#read(table, key);
|
|
158
|
-
return state.deleted ? undefined : state.value;
|
|
159
|
-
},
|
|
160
|
-
list: async (options) => this.#list(table, options as EntityListOptions<EntityValue> | undefined),
|
|
161
|
-
create: async (input) => {
|
|
162
|
-
this.#assertOpen();
|
|
163
|
-
const value = table.decl.schema.parse(input) as EntityValue;
|
|
164
|
-
const key = value[table.key.name];
|
|
165
|
-
const state = await this.#read(table, key);
|
|
166
|
-
if (!state.deleted && state.value !== undefined) throw new EntityConflictError(table.moduleId, table.entityName, key);
|
|
167
|
-
state.value = value;
|
|
168
|
-
state.deleted = false;
|
|
169
|
-
state.mutation = "put";
|
|
170
|
-
return value;
|
|
171
|
-
},
|
|
172
|
-
update: async (key, patch) => {
|
|
173
|
-
this.#assertOpen();
|
|
174
|
-
const state = await this.#read(table, key);
|
|
175
|
-
if (state.deleted || !state.value) throw new EntityNotFoundError(table.moduleId, table.entityName, key);
|
|
176
|
-
const value = table.decl.schema.parse({ ...state.value, ...patch }) as EntityValue;
|
|
177
|
-
if (keyIdentity(table, value[table.key.name]) !== keyIdentity(table, key)) throw new TypeError(`entity key '${table.key.name}' cannot be changed`);
|
|
178
|
-
state.value = value;
|
|
179
|
-
state.mutation = "put";
|
|
180
|
-
return value;
|
|
181
|
-
},
|
|
182
|
-
delete: async (key) => {
|
|
183
|
-
this.#assertOpen();
|
|
184
|
-
const state = await this.#read(table, key);
|
|
185
|
-
if (state.deleted || !state.value) return false;
|
|
186
|
-
state.deleted = true;
|
|
187
|
-
state.value = undefined;
|
|
188
|
-
state.mutation = state.expectedVersion === null ? undefined : "delete";
|
|
189
|
-
return true;
|
|
190
|
-
},
|
|
191
|
-
} as EntityStore;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
async #list(table: EntityTable, options: EntityListOptions<EntityValue> | undefined): Promise<EntityPage<EntityValue>> {
|
|
195
|
-
this.#assertOpen();
|
|
196
|
-
await this.ready;
|
|
197
|
-
const limit = pageSize(options?.limit);
|
|
198
|
-
const where: Record<string, KernelStoredValue> = {};
|
|
199
|
-
const parsedWhere = new Map<EntityField, unknown>();
|
|
200
|
-
for (const [name, raw] of Object.entries(options?.where ?? {})) {
|
|
201
|
-
const field = table.fieldByName.get(name);
|
|
202
|
-
if (!field) throw new TypeError(`unknown where field '${name}' on '${table.moduleId}.${table.entityName}'`);
|
|
203
|
-
const parsed = field.schema.parse(raw);
|
|
204
|
-
parsedWhere.set(field, parsed);
|
|
205
|
-
where[name] = encodeField(field, parsed);
|
|
206
|
-
}
|
|
207
|
-
const after = options?.cursor ? decodeCursor(this.cursorSecret, table, this.scope, options.cursor) : undefined;
|
|
208
|
-
const stagedCount = [...this.#states.values()].filter((state) => state.table === table && state.mutation).length;
|
|
209
|
-
const rows = await this.port.entityList({ entity: entityCatalogOf(table), scope: this.scope, where, ...(after !== undefined ? { after } : {}), limit: limit + stagedCount + 1 });
|
|
210
|
-
const candidates = new Map<string, EntityValue>();
|
|
211
|
-
for (const row of rows) {
|
|
212
|
-
const state = this.#remember(table, row);
|
|
213
|
-
if (!state.deleted && state.value && matchesWhere(state.value, parsedWhere)) candidates.set(keyIdentity(table, state.key), state.value);
|
|
214
|
-
}
|
|
215
|
-
for (const state of this.#states.values()) {
|
|
216
|
-
if (state.table !== table || state.deleted || !state.value || !matchesWhere(state.value, parsedWhere)) continue;
|
|
217
|
-
if (after !== undefined && compareKeys(table, state.key, decodeField(table.key, after)) <= 0) continue;
|
|
218
|
-
candidates.set(keyIdentity(table, state.key), state.value);
|
|
219
|
-
}
|
|
220
|
-
const sorted = [...candidates.values()].sort((a, b) => compareKeys(table, a[table.key.name], b[table.key.name]));
|
|
221
|
-
const page = sorted.slice(0, limit);
|
|
222
|
-
const last = page.at(-1);
|
|
223
|
-
return {
|
|
224
|
-
items: page,
|
|
225
|
-
...(sorted.length > limit && last ? { cursor: encodeCursor(this.cursorSecret, table, this.scope, encodeField(table.key, last[table.key.name])) } : {}),
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
seal(): void {
|
|
230
|
-
if (this.#finished) throw new EntitySessionClosedError();
|
|
231
|
-
this.#closed = true;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
mutations(): readonly KernelEntityMutation[] {
|
|
235
|
-
if (!this.#closed || this.#finished) throw new EntitySessionClosedError();
|
|
236
|
-
const result: KernelEntityMutation[] = [];
|
|
237
|
-
for (const state of this.#states.values()) {
|
|
238
|
-
if (!state.mutation) continue;
|
|
239
|
-
const entity = entityCatalogOf(state.table);
|
|
240
|
-
if (state.mutation === "delete") {
|
|
241
|
-
result.push({ kind: "delete", entity, scope: this.scope, key: encodeField(state.table.key, state.key), logicalKey: state.key as string | number | bigint | boolean, expectedVersion: state.expectedVersion });
|
|
242
|
-
} else {
|
|
243
|
-
const values = Object.fromEntries(state.table.fields.map((field) => [field.name, encodeField(field, state.value![field.name])]));
|
|
244
|
-
result.push({ kind: "put", entity, scope: this.scope, key: encodeField(state.table.key, state.key), logicalKey: state.key as string | number | bigint | boolean, expectedVersion: state.expectedVersion, values });
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
this.#finished = true;
|
|
248
|
-
return Object.freeze(result);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
discard(): void {
|
|
252
|
-
if (this.#finished) throw new EntitySessionClosedError();
|
|
253
|
-
this.#closed = true;
|
|
254
|
-
this.#states.clear();
|
|
255
|
-
this.#finished = true;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
export class AsyncEntityPersistence {
|
|
260
|
-
readonly #tables = new Map<string, ReadonlyMap<string, EntityTable>>();
|
|
261
|
-
readonly #ready = new Map<string, Promise<void>>();
|
|
262
|
-
readonly #cursorSecret = randomBytes(32);
|
|
263
|
-
|
|
264
|
-
constructor(readonly port: KernelPersistence) {}
|
|
265
|
-
|
|
266
|
-
register<M extends ModuleManifest>(module: ModuleDefinition<M>): Promise<void> {
|
|
267
|
-
assertValidManifest(module);
|
|
268
|
-
if (this.#tables.has(module.id)) throw new Error(`module '${module.id}' entity persistence is already installed`);
|
|
269
|
-
const { catalog, tables } = buildModuleEntityCatalog(module);
|
|
270
|
-
this.#tables.set(module.id, tables);
|
|
271
|
-
const ready = this.port.installModule(structuredClone(catalog));
|
|
272
|
-
this.#ready.set(module.id, ready);
|
|
273
|
-
return ready;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
begin<M extends ModuleManifest>(module: ModuleDefinition<M>, scope: Scope): AsyncEntitySession<M["entities"]> {
|
|
277
|
-
const tables = this.#tables.get(module.id);
|
|
278
|
-
const ready = this.#ready.get(module.id);
|
|
279
|
-
if (!tables || !ready) throw new Error(`module '${module.id}' entity persistence is not installed`);
|
|
280
|
-
return new AsyncEntitySessionRuntime(this.port, ready, scope, this.#cursorSecret, tables);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
ready(moduleId: string): Promise<void> {
|
|
284
|
-
const ready = this.#ready.get(moduleId);
|
|
285
|
-
if (!ready) throw new Error(`module '${moduleId}' entity persistence is not installed`);
|
|
286
|
-
return ready;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
#lookupTable(moduleId: string, entityName: string): EntityTable | undefined {
|
|
290
|
-
return this.#tables.get(moduleId)?.get(entityName);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
#rawRow(table: EntityTable, scope: Scope, row: KernelEntityStoredRow): EntityRawRow {
|
|
294
|
-
const fields = decodedValue(table, row);
|
|
295
|
-
return {
|
|
296
|
-
module: table.moduleId,
|
|
297
|
-
entity: table.entityName,
|
|
298
|
-
scope,
|
|
299
|
-
key: fields[table.key.name],
|
|
300
|
-
version: row.version,
|
|
301
|
-
createdAt: row.createdAt,
|
|
302
|
-
updatedAt: row.updatedAt,
|
|
303
|
-
fields,
|
|
304
|
-
};
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
async readEntity(moduleId: string, entityName: string, scope: Scope, key: unknown): Promise<EntityRawRow | undefined> {
|
|
308
|
-
const table = this.#lookupTable(moduleId, entityName);
|
|
309
|
-
if (!table) return undefined;
|
|
310
|
-
await this.ready(moduleId);
|
|
311
|
-
const parsedKey = table.key.schema.parse(key);
|
|
312
|
-
const row = await this.port.entityPoint({ entity: entityCatalogOf(table), scope, key: encodeField(table.key, parsedKey) });
|
|
313
|
-
return row ? this.#rawRow(table, scope, row) : undefined;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
async listEntity(moduleId: string, entityName: string, scope: Scope, options: EntityRawListOptions = {}): Promise<EntityRawPage> {
|
|
317
|
-
const table = this.#lookupTable(moduleId, entityName);
|
|
318
|
-
if (!table) return { items: [] };
|
|
319
|
-
await this.ready(moduleId);
|
|
320
|
-
const limit = pageSize(options.limit);
|
|
321
|
-
const where: Record<string, KernelStoredValue> = {};
|
|
322
|
-
for (const [name, raw] of Object.entries(options.where ?? {})) {
|
|
323
|
-
const field = table.fieldByName.get(name);
|
|
324
|
-
if (!field) throw new TypeError(`unknown where field '${name}' on '${moduleId}.${entityName}'`);
|
|
325
|
-
where[name] = encodeField(field, field.schema.parse(raw));
|
|
326
|
-
}
|
|
327
|
-
const after = options.cursor ? decodeCursor(this.#cursorSecret, table, scope, options.cursor) : undefined;
|
|
328
|
-
const rows = await this.port.entityList({
|
|
329
|
-
entity: entityCatalogOf(table),
|
|
330
|
-
scope,
|
|
331
|
-
where,
|
|
332
|
-
...(after !== undefined ? { after } : {}),
|
|
333
|
-
limit: limit + 1,
|
|
334
|
-
});
|
|
335
|
-
const items = rows.slice(0, limit).map((row) => this.#rawRow(table, scope, row));
|
|
336
|
-
const last = items.at(-1);
|
|
337
|
-
return {
|
|
338
|
-
items,
|
|
339
|
-
...(rows.length > limit && last
|
|
340
|
-
? { cursor: encodeCursor(this.#cursorSecret, table, scope, encodeField(table.key, last.key)) }
|
|
341
|
-
: {}),
|
|
342
|
-
};
|
|
343
|
-
}
|
|
344
|
-
}
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { isDeepStrictEqual } from "node:util";
|
|
2
|
-
import type * as z from "zod";
|
|
3
|
-
import type { EventWriter, ModuleDefinition, ModuleManifest, Scope } from "./contract";
|
|
4
|
-
import { EventSessionClosedError, EventTopicMismatchError, UndeclaredEventError } from "./event-log";
|
|
5
|
-
import type { KernelEventAppend, KernelPersistence } from "./kernel-persistence";
|
|
6
|
-
|
|
7
|
-
interface PendingEvent {
|
|
8
|
-
readonly name: string;
|
|
9
|
-
readonly payload: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function normalizeJsonSafe(value: unknown): unknown {
|
|
13
|
-
if (typeof value === "number") return Object.is(value, -0) ? 0 : value;
|
|
14
|
-
if (Array.isArray(value)) return value.map(normalizeJsonSafe);
|
|
15
|
-
if (value !== null && typeof value === "object" && Object.getPrototypeOf(value) === Object.prototype) {
|
|
16
|
-
return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined).map(([key, entry]) => [key, normalizeJsonSafe(entry)]));
|
|
17
|
-
}
|
|
18
|
-
return value;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function encodePayload(value: unknown, name: string): string {
|
|
22
|
-
try {
|
|
23
|
-
const encoded = JSON.stringify(value);
|
|
24
|
-
if (encoded === undefined || !isDeepStrictEqual(JSON.parse(encoded) as unknown, normalizeJsonSafe(value))) {
|
|
25
|
-
throw new TypeError("value changes during JSON encoding");
|
|
26
|
-
}
|
|
27
|
-
return encoded;
|
|
28
|
-
} catch (error) {
|
|
29
|
-
throw new TypeError(`event '${name}' payload must be JSON-safe: ${error instanceof Error ? error.message : String(error)}`);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export interface AsyncEventSession<E> {
|
|
34
|
-
readonly events: EventWriter<E>;
|
|
35
|
-
readonly pendingEvents: number;
|
|
36
|
-
seal(): void;
|
|
37
|
-
discard(): void;
|
|
38
|
-
appends(createdAt: number): readonly KernelEventAppend[];
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
class AsyncEventSessionRuntime<E> implements AsyncEventSession<E> {
|
|
42
|
-
readonly events: EventWriter<E>;
|
|
43
|
-
readonly #buffer: PendingEvent[] = [];
|
|
44
|
-
#closed = false;
|
|
45
|
-
#finished = false;
|
|
46
|
-
|
|
47
|
-
constructor(readonly scope: Scope, readonly moduleId: string, readonly schemas: ReadonlyMap<string, z.ZodType>) {
|
|
48
|
-
const prefix = `${moduleId}.`;
|
|
49
|
-
this.events = {
|
|
50
|
-
emit: async (name: string, payload: unknown) => {
|
|
51
|
-
if (this.#closed) throw new EventSessionClosedError();
|
|
52
|
-
if (!name.startsWith(prefix) || name.length === prefix.length) throw new EventTopicMismatchError(moduleId, name);
|
|
53
|
-
const schema = schemas.get(name);
|
|
54
|
-
if (!schema) throw new UndeclaredEventError(moduleId, name);
|
|
55
|
-
this.#buffer.push({ name, payload: encodePayload(schema.parse(payload), name) });
|
|
56
|
-
},
|
|
57
|
-
} as unknown as EventWriter<E>;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
get pendingEvents(): number { return this.#buffer.length; }
|
|
61
|
-
|
|
62
|
-
seal(): void {
|
|
63
|
-
if (this.#finished) throw new EventSessionClosedError();
|
|
64
|
-
this.#closed = true;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
appends(createdAt: number): readonly KernelEventAppend[] {
|
|
68
|
-
if (!this.#closed || this.#finished) throw new EventSessionClosedError();
|
|
69
|
-
this.#finished = true;
|
|
70
|
-
return Object.freeze(this.#buffer.map((event) => Object.freeze({
|
|
71
|
-
scope: this.scope,
|
|
72
|
-
moduleId: this.moduleId,
|
|
73
|
-
name: event.name,
|
|
74
|
-
payload: event.payload,
|
|
75
|
-
createdAt,
|
|
76
|
-
})));
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
discard(): void {
|
|
80
|
-
if (this.#finished) throw new EventSessionClosedError();
|
|
81
|
-
this.#closed = true;
|
|
82
|
-
this.#buffer.length = 0;
|
|
83
|
-
this.#finished = true;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export class AsyncEventLogPersistence {
|
|
88
|
-
readonly #modules = new Map<string, ReadonlyMap<string, z.ZodType>>();
|
|
89
|
-
constructor(readonly port: KernelPersistence) {}
|
|
90
|
-
|
|
91
|
-
register<M extends ModuleManifest>(module: ModuleDefinition<M>): void {
|
|
92
|
-
if (this.#modules.has(module.id)) throw new Error(`module '${module.id}' event log is already installed`);
|
|
93
|
-
this.#modules.set(module.id, new Map(Object.entries(module.events ?? {}) as Array<[string, z.ZodType]>));
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
begin<M extends ModuleManifest>(module: ModuleDefinition<M>, scope: Scope): AsyncEventSession<NonNullable<M["events"]>> {
|
|
97
|
-
const schemas = this.#modules.get(module.id);
|
|
98
|
-
if (!schemas) throw new Error(`module '${module.id}' event log is not installed`);
|
|
99
|
-
return new AsyncEventSessionRuntime(scope, module.id, schemas);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
replay(scope: Scope, since: number, limit: number, moduleId?: string) {
|
|
103
|
-
return this.port.replayEvents(scope, since, limit, moduleId);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
highWater(scope: Scope) { return this.port.eventHighWater(scope); }
|
|
107
|
-
}
|