@jr2/orchestrator 0.5.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/console/components/app.ts +55 -15
- package/console/components/bottom-drawer.ts +259 -0
- package/console/components/drawer.ts +14 -6
- package/console/components/fleet.ts +36 -13
- package/console/components/machine-pane.ts +61 -5
- package/console/components/nav.ts +54 -8
- package/console/conversation.ts +161 -0
- package/console/login.ts +123 -0
- package/console/main.ts +600 -60
- package/console/store.ts +611 -64
- package/console/style.css +231 -0
- package/docs/agents-block.md +2 -2
- package/docs/concepts/agents-and-turns.md +142 -29
- package/docs/concepts/architecture.md +60 -34
- package/docs/concepts/callers-and-hooks.md +205 -0
- package/docs/concepts/charts.md +13 -8
- package/docs/concepts/composition.md +10 -1
- package/docs/concepts/converge.md +7 -2
- package/docs/concepts/durable-runs.md +43 -16
- package/docs/concepts/effects.md +133 -50
- package/docs/concepts/gates.md +95 -25
- package/docs/concepts/machines-and-workflows.md +14 -4
- package/docs/concepts/pools-and-sources.md +193 -17
- package/docs/concepts/secrets-and-trust.md +186 -62
- package/docs/concepts/the-menu.md +14 -0
- package/docs/concepts/workspaces.md +135 -56
- package/docs/get-started/a-model-decides.md +14 -13
- package/docs/get-started/an-agent-in-a-sandbox.md +46 -35
- package/docs/get-started/connect-a-model.md +1 -1
- package/docs/get-started/create-an-instance.md +17 -14
- package/docs/get-started/have-your-assistant-write-a-machine.md +111 -40
- package/docs/get-started/install.md +4 -0
- package/docs/guides/add-tools-to-the-sandbox.md +72 -15
- package/docs/guides/answer-a-gate-from-a-forge.md +304 -0
- package/docs/guides/answer-a-gate.md +74 -37
- package/docs/guides/bind-open-parts.md +29 -12
- package/docs/guides/call-an-mcp-tool-from-a-machine.md +572 -0
- package/docs/guides/cancel-a-run.md +26 -16
- package/docs/guides/cut-a-worktree.md +560 -0
- package/docs/guides/fix-a-failed-converge.md +19 -7
- package/docs/guides/give-a-caller-a-scope.md +203 -0
- package/docs/guides/give-an-agent-mcp-tools.md +422 -0
- package/docs/guides/iterate-on-a-machine-on-kind.md +10 -9
- package/docs/guides/let-an-agent-write-a-chart.md +14 -7
- package/docs/guides/look-inside-a-sandbox.md +115 -42
- package/docs/guides/move-from-kind-to-a-shared-cluster.md +16 -0
- package/docs/guides/open-the-console.md +63 -14
- package/docs/guides/push-and-sign-a-branch.md +67 -21
- package/docs/guides/read-a-conversation.md +225 -0
- package/docs/guides/run-a-chart-by-name.md +17 -16
- package/docs/guides/run-a-command-or-call-a-url.md +84 -41
- package/docs/guides/run-one-worker-per-item.md +34 -27
- package/docs/guides/set-an-agents-access-and-dials.md +69 -22
- package/docs/guides/size-a-workspace.md +19 -6
- package/docs/guides/start-a-run-for-each-alert.md +290 -0
- package/docs/guides/start-a-run-from-a-run.md +18 -16
- package/docs/guides/start-a-run.md +24 -18
- package/docs/guides/steer-an-agent.md +332 -0
- package/docs/guides/use-a-hosted-provider.md +7 -1
- package/docs/guides/watch-a-run.md +146 -117
- package/docs/guides/write-a-hook-kind.md +238 -0
- package/docs/guides/write-a-tool-as-an-mcp-server.md +351 -0
- package/docs/guides/write-a-workflow.md +18 -8
- package/docs/llms.txt +110 -23
- package/docs/reference/authoring-surface/agent.md +35 -12
- package/docs/reference/authoring-surface/answer.md +20 -4
- package/docs/reference/authoring-surface/arg.md +28 -6
- package/docs/reference/authoring-surface/basic.md +1 -1
- package/docs/reference/authoring-surface/bearer.md +1 -1
- package/docs/reference/authoring-surface/branchname.md +15 -0
- package/docs/reference/authoring-surface/carry.md +23 -0
- package/docs/reference/authoring-surface/chartschema.md +1 -1
- package/docs/reference/authoring-surface/chartschemafor.md +1 -1
- package/docs/reference/authoring-surface/command.md +37 -22
- package/docs/reference/authoring-surface/customize.md +4 -1
- package/docs/reference/authoring-surface/defineconfig.md +1 -1
- package/docs/reference/authoring-surface/defineevent.md +1 -1
- package/docs/reference/authoring-surface/dispatch.md +5 -4
- package/docs/reference/authoring-surface/fail.md +18 -5
- package/docs/reference/authoring-surface/file.md +37 -17
- package/docs/reference/authoring-surface/frompick.md +1 -1
- package/docs/reference/authoring-surface/gate.md +118 -0
- package/docs/reference/authoring-surface/group-agents.md +15 -0
- package/docs/reference/authoring-surface/group-charts.md +16 -0
- package/docs/reference/authoring-surface/group-composition.md +25 -0
- package/docs/reference/authoring-surface/group-config.md +17 -0
- package/docs/reference/authoring-surface/group-effects.md +48 -0
- package/docs/reference/authoring-surface/group-failure.md +13 -0
- package/docs/reference/authoring-surface/group-gates.md +16 -0
- package/docs/reference/authoring-surface/group-machine-and-events.md +15 -0
- package/docs/reference/authoring-surface/group-steering.md +12 -0
- package/docs/reference/authoring-surface/group-types-these-signatures-name.md +137 -0
- package/docs/reference/authoring-surface/group-workspaces-and-repos.md +15 -0
- package/docs/reference/authoring-surface/http.md +109 -9
- package/docs/reference/authoring-surface/isfailure.md +1 -1
- package/docs/reference/authoring-surface/isready.md +14 -0
- package/docs/reference/authoring-surface/jr2setup.md +14 -4
- package/docs/reference/authoring-surface/mcp.md +107 -0
- package/docs/reference/authoring-surface/open.md +41 -8
- package/docs/reference/authoring-surface/openbody.md +1 -1
- package/docs/reference/authoring-surface/paramsof.md +23 -5
- package/docs/reference/authoring-surface/pool.md +79 -11
- package/docs/reference/authoring-surface/push.md +31 -13
- package/docs/reference/authoring-surface/readyof.md +21 -0
- package/docs/reference/authoring-surface/reread.md +19 -0
- package/docs/reference/authoring-surface/secret.md +26 -5
- package/docs/reference/authoring-surface/sentby.md +1 -1
- package/docs/reference/authoring-surface/skip.md +22 -0
- package/docs/reference/authoring-surface/source.md +59 -4
- package/docs/reference/authoring-surface/steer.md +93 -0
- package/docs/reference/authoring-surface/text.md +1 -1
- package/docs/reference/authoring-surface/type-agentdefinition.md +16 -3
- package/docs/reference/authoring-surface/type-agentmcpserver.md +54 -0
- package/docs/reference/authoring-surface/type-agentslots.md +4 -1
- package/docs/reference/authoring-surface/type-anyframepath.md +14 -0
- package/docs/reference/authoring-surface/type-anyworktreepath.md +15 -0
- package/docs/reference/authoring-surface/type-bindactors.md +14 -0
- package/docs/reference/authoring-surface/type-binding.md +6 -7
- package/docs/reference/authoring-surface/type-caller.md +40 -0
- package/docs/reference/authoring-surface/type-callerrecord.md +32 -0
- package/docs/reference/authoring-surface/type-carry.md +19 -0
- package/docs/reference/authoring-surface/type-chainlink.md +3 -3
- package/docs/reference/authoring-surface/type-commandinput.md +4 -3
- package/docs/reference/authoring-surface/type-commandoptions.md +0 -22
- package/docs/reference/authoring-surface/type-commandoutput.md +23 -5
- package/docs/reference/authoring-surface/type-customize.md +20 -3
- package/docs/reference/authoring-surface/type-delivered.md +17 -0
- package/docs/reference/authoring-surface/type-deliveredevent.md +18 -0
- package/docs/reference/authoring-surface/type-dispatchdefinition.md +4 -3
- package/docs/reference/authoring-surface/type-dispatchoutput.md +9 -2
- package/docs/reference/authoring-surface/type-doorlessinput.md +19 -0
- package/docs/reference/authoring-surface/type-effectbinding.md +12 -2
- package/docs/reference/authoring-surface/type-filebody.md +4 -8
- package/docs/reference/authoring-surface/type-framepath.md +14 -0
- package/docs/reference/authoring-surface/type-gatebinding.md +15 -0
- package/docs/reference/authoring-surface/type-gatehooks.md +12 -0
- package/docs/reference/authoring-surface/type-gatelook.md +37 -0
- package/docs/reference/authoring-surface/type-gateoutcome.md +32 -0
- package/docs/reference/authoring-surface/type-gatereply.md +19 -0
- package/docs/reference/authoring-surface/type-gateslot.md +21 -0
- package/docs/reference/authoring-surface/type-gateslotinput.md +13 -0
- package/docs/reference/authoring-surface/type-gateslotparts.md +18 -0
- package/docs/reference/authoring-surface/type-gateslots.md +12 -0
- package/docs/reference/authoring-surface/type-gatetypesat.md +13 -0
- package/docs/reference/authoring-surface/type-hostinjectedinput.md +3 -5
- package/docs/reference/authoring-surface/type-httpdefinition.md +6 -3
- package/docs/reference/authoring-surface/type-httpfileinput.md +20 -0
- package/docs/reference/authoring-surface/type-httpoutput.md +8 -2
- package/docs/reference/authoring-surface/type-jr2config.md +37 -2
- package/docs/reference/authoring-surface/type-lateroutcome.md +21 -0
- package/docs/reference/authoring-surface/type-lends.md +5 -1
- package/docs/reference/authoring-surface/type-lookoutput.md +14 -0
- package/docs/reference/authoring-surface/type-mcpcalloutput.md +78 -0
- package/docs/reference/authoring-surface/type-mcpnotreturned.md +42 -0
- package/docs/reference/authoring-surface/type-mcpoptions.md +47 -0
- package/docs/reference/authoring-surface/type-mcpoutput.md +50 -0
- package/docs/reference/authoring-surface/type-mcpreadoutput.md +53 -0
- package/docs/reference/authoring-surface/type-mcpremoteserver.md +50 -0
- package/docs/reference/authoring-surface/type-mcpserver.md +41 -0
- package/docs/reference/authoring-surface/type-mcpstdioserver.md +42 -0
- package/docs/reference/authoring-surface/type-namedsecret.md +4 -4
- package/docs/reference/authoring-surface/type-namestart.md +77 -0
- package/docs/reference/authoring-surface/type-noslotworkspaceoptions.md +1 -6
- package/docs/reference/authoring-surface/type-notworktreekeys.md +12 -0
- package/docs/reference/authoring-surface/type-openbodydeclaration.md +1 -1
- package/docs/reference/authoring-surface/type-openbodyoutput.md +1 -1
- package/docs/reference/authoring-surface/type-opencommandinput.md +7 -2
- package/docs/reference/authoring-surface/type-permissivenoslotworkspaceoptions.md +1 -6
- package/docs/reference/authoring-surface/type-permissiveworkspaceoptions.md +5 -10
- package/docs/reference/authoring-surface/type-poolnextinput.md +22 -0
- package/docs/reference/authoring-surface/type-poolspec.md +11 -6
- package/docs/reference/authoring-surface/type-pushinput.md +22 -3
- package/docs/reference/authoring-surface/type-pushoutput.md +33 -8
- package/docs/reference/authoring-surface/type-pushsourcespec.md +38 -0
- package/docs/reference/authoring-surface/type-readsourcespec.md +47 -0
- package/docs/reference/authoring-surface/type-reposlot.md +6 -6
- package/docs/reference/authoring-surface/type-reread.md +18 -0
- package/docs/reference/authoring-surface/type-runsconfig.md +41 -0
- package/docs/reference/authoring-surface/type-sandboxoptions.md +11 -4
- package/docs/reference/authoring-surface/type-sender.md +26 -1
- package/docs/reference/authoring-surface/type-sendercallerfield.md +14 -0
- package/docs/reference/authoring-surface/type-size.md +1 -1
- package/docs/reference/authoring-surface/type-skip.md +19 -0
- package/docs/reference/authoring-surface/type-slothandles.md +5 -13
- package/docs/reference/authoring-surface/type-sourcehooks.md +23 -0
- package/docs/reference/authoring-surface/type-sourcein.md +25 -0
- package/docs/reference/authoring-surface/type-sourcereply.md +18 -0
- package/docs/reference/authoring-surface/type-sourcespec.md +26 -17
- package/docs/reference/authoring-surface/type-sourceverdict.md +49 -0
- package/docs/reference/authoring-surface/type-standingpoolmachine.md +12 -0
- package/docs/reference/authoring-surface/type-standingpoolspec.md +51 -0
- package/docs/reference/authoring-surface/type-steerargs.md +20 -0
- package/docs/reference/authoring-surface/type-thinkinglevel.md +1 -1
- package/docs/reference/authoring-surface/type-usercontainer.md +1 -1
- package/docs/reference/authoring-surface/type-workspaced.md +30 -9
- package/docs/reference/authoring-surface/type-workspacehandles.md +5 -6
- package/docs/reference/authoring-surface/type-workspaceoptions.md +1 -13
- package/docs/reference/authoring-surface/type-worktreefound.md +16 -0
- package/docs/reference/authoring-surface/type-worktreeinput.md +56 -0
- package/docs/reference/authoring-surface/type-worktreekey.md +14 -0
- package/docs/reference/authoring-surface/type-worktreeoptions.md +29 -0
- package/docs/reference/authoring-surface/type-worktreeoutput.md +45 -0
- package/docs/reference/authoring-surface/type-worktreepath.md +16 -0
- package/docs/reference/authoring-surface/type-worktreeready.md +37 -0
- package/docs/reference/authoring-surface/type-worktreerefused.md +21 -0
- package/docs/reference/authoring-surface/workspace.md +66 -38
- package/docs/reference/authoring-surface/worktree.md +71 -0
- package/docs/reference/authoring-surface.md +88 -147
- package/docs/reference/cli.md +413 -74
- package/docs/reference/config.md +248 -6
- package/docs/reference/decisions/0001-operator-owned-generic-sandbox.md +10 -9
- package/docs/reference/decisions/0002-duplex-streaming-actor.md +81 -14
- package/docs/reference/decisions/0004-worktree-provisioning-model.md +27 -21
- package/docs/reference/decisions/0005-sandbox-pod-composition.md +39 -25
- package/docs/reference/decisions/0006-agent-control-surface.md +6 -3
- package/docs/reference/decisions/0007-durable-machine-state.md +1 -1
- package/docs/reference/decisions/0009-cli-and-instance-interface.md +150 -49
- package/docs/reference/decisions/0010-bdd-acceptance-tests.md +5 -3
- package/docs/reference/decisions/0011-workflow-defined-events.md +256 -12
- package/docs/reference/decisions/0012-workspace-wrapper-machine.md +39 -32
- package/docs/reference/decisions/0013-the-agent-reaches-its-machine-through-a-container-it-cannot-read.md +54 -30
- package/docs/reference/decisions/0014-observation-is-open-run-state-is-not.md +53 -27
- package/docs/reference/decisions/0015-authoring-surface-absorbs-the-mechanism.md +26 -16
- package/docs/reference/decisions/0016-agent-turn-mechanics-are-internal.md +9 -7
- package/docs/reference/decisions/0017-pool-over-a-source-port.md +226 -10
- package/docs/reference/decisions/0018-instance-agents-are-definitions-jr2-assembles-the-harness.md +15 -7
- package/docs/reference/decisions/0019-one-converging-command-against-the-current-context.md +53 -27
- package/docs/reference/decisions/0021-workspace-continuity-is-a-lease-that-answers-back.md +16 -2
- package/docs/reference/decisions/0022-observation-is-a-level-triggered-feed.md +4 -4
- package/docs/reference/decisions/0023-the-harness-prints-the-conversation.md +124 -43
- package/docs/reference/decisions/0024-an-agents-turn-ends-with-the-state-that-asked-for-it.md +36 -38
- package/docs/reference/decisions/0025-cancel-ends-a-run-stop-parks-it.md +10 -5
- package/docs/reference/decisions/0027-the-harness-is-jr2s-own-server-flue-retires-the-wire-stays.md +16 -7
- package/docs/reference/decisions/0028-what-an-agent-may-do-to-the-workspace-is-part-of-its-definition.md +36 -19
- package/docs/reference/decisions/0029-a-menu-is-fixed-for-a-conversation-and-a-turn-is-told-its-allowed-picks.md +18 -10
- package/docs/reference/decisions/0030-a-snapshot-names-the-machine-it-was-written-under.md +3 -2
- package/docs/reference/decisions/0031-menu-only-agents-run-on-the-instance-harness.md +23 -15
- package/docs/reference/decisions/0032-the-console-unlocks-with-a-callers-credential.md +101 -0
- package/docs/reference/decisions/0033-a-machine-declares-the-input-that-starts-it.md +22 -22
- package/docs/reference/decisions/0034-the-console-renders-with-preact-and-the-server-erases-the-types.md +6 -6
- package/docs/reference/decisions/0037-an-instance-builds-its-sandbox-images-jr2-injects-the-harness.md +13 -12
- package/docs/reference/decisions/0049-a-machine-carries-its-parts-and-composes-by-invoke.md +23 -23
- package/docs/reference/decisions/0050-what-code-names-config-declares-what-the-cli-names-discovery-finds.md +6 -1
- package/docs/reference/decisions/0051-a-repo-is-a-slot-on-the-workspace-and-a-cache-on-the-node.md +57 -46
- package/docs/reference/decisions/0052-a-sandbox-lands-where-an-ordinary-pod-lands-and-the-cache-follows-it.md +5 -0
- package/docs/reference/decisions/0053-a-fetch-inside-the-pod-asks-the-node-cache-and-the-cache-asks-the-remote.md +20 -8
- package/docs/reference/decisions/0054-the-kit-ships-machines-and-a-shipped-machine-leaves-its-parts-open.md +55 -40
- package/docs/reference/decisions/0055-a-release-is-a-pushed-tag-and-the-publish-guard-is-the-credential.md +14 -13
- package/docs/reference/decisions/0057-a-turn-is-its-frame-its-dials-and-whether-it-continues.md +31 -24
- package/docs/reference/decisions/0058-a-harness-answers-the-orchestrator-alone.md +18 -10
- package/docs/reference/decisions/0059-a-harness-holds-stand-ins-and-the-custodian-holds-the-keys.md +137 -86
- package/docs/reference/decisions/0062-jr2-briefs-the-agent-on-its-seat-never-on-its-task.md +165 -91
- package/docs/reference/decisions/0063-the-orchestrator-watches-the-cluster.md +7 -7
- package/docs/reference/decisions/0064-a-workspace-waits-for-capacity.md +2 -2
- package/docs/reference/decisions/0065-a-persist-survives-a-crash-and-history-is-kept-for-a-set-time.md +109 -0
- package/docs/reference/decisions/0066-a-model-tier-runs-a-real-model-and-a-change-to-what-it-reads-runs-the-tier.md +53 -23
- package/docs/reference/decisions/0067-an-effect-is-an-actor-slot-and-runs-at-most-once-unless-marked-idempotent.md +221 -153
- package/docs/reference/decisions/0068-an-effector-holds-an-effects-secrets-and-signs-its-wire.md +161 -96
- package/docs/reference/decisions/0069-the-orchestrator-is-a-kit-image-and-an-instance-publishes-its-assembly.md +32 -9
- package/docs/reference/decisions/0070-a-machine-lends-its-parts-to-a-chart.md +48 -33
- package/docs/reference/decisions/0071-a-run-starts-a-run-through-a-dispatch-effect.md +56 -30
- package/docs/reference/decisions/0072-the-docs-ship-inside-the-kit-and-an-instances-agents-md-indexes-them.md +35 -25
- package/docs/reference/decisions/0073-a-machine-fails-a-run-with-fail-and-an-uncaught-failure-ends-it-failed.md +1 -1
- package/docs/reference/decisions/0075-a-machine-cuts-a-worktree-and-the-workspace-only-clones.md +296 -0
- package/docs/reference/decisions/0076-an-agents-control-credential-lives-only-where-no-workspace-code-runs.md +347 -0
- package/docs/reference/decisions/0077-jr2-requires-landlock-on-every-sandbox-node.md +79 -0
- package/docs/reference/decisions/0078-a-caller-comes-from-one-authenticator-seam-and-acts-within-its-scopes.md +285 -0
- package/docs/reference/decisions/0079-an-agent-holds-mcp-tools-a-machine-calls-them-as-an-effect-and-the-machine-is-the-approval.md +198 -0
- package/docs/reference/decisions.md +9 -4
- package/docs/reference/glossary.md +138 -45
- package/docs/reference/hooks.md +1077 -0
- package/docs/reference/http-api.md +988 -123
- package/docs/reference/machines.md +0 -1
- package/docs/why.md +7 -5
- package/package.json +10 -3
- package/src/actor.ts +194 -42
- package/src/agent.ts +56 -6
- package/src/ambient.ts +3 -5
- package/src/assembly-checks.ts +530 -4
- package/src/callers.ts +245 -0
- package/src/chart.ts +238 -26
- package/src/charts.ts +9 -2
- package/src/config.ts +566 -7
- package/src/conversations.ts +453 -0
- package/src/custodian.lua +17 -5
- package/src/custodian.ts +257 -77
- package/src/customize.ts +154 -7
- package/src/dispatch-effect.ts +142 -26
- package/src/durability.ts +2 -0
- package/src/duration.ts +20 -0
- package/src/effect-checks.ts +52 -4
- package/src/effect.ts +401 -132
- package/src/effector-wire.ts +278 -30
- package/src/fail.ts +17 -4
- package/src/gate-brand.ts +16 -0
- package/src/gate.ts +634 -48
- package/src/harness-client.ts +84 -35
- package/src/harness-env.ts +33 -0
- package/src/held-secrets.ts +197 -39
- package/src/holds.ts +5 -2
- package/src/hook-kinds/discord.ts +92 -0
- package/src/hook-kinds/door.ts +107 -0
- package/src/hook-kinds/github.ts +89 -0
- package/src/hook-kinds/gitlab.ts +72 -0
- package/src/hook-kinds/hook.ts +7 -0
- package/src/hook-kinds/index.ts +465 -0
- package/src/hook-kinds/slack.ts +151 -0
- package/src/hook-kinds/webhook.ts +113 -0
- package/src/hooks.ts +506 -0
- package/src/http-effect.ts +164 -70
- package/src/http.ts +933 -99
- package/src/index.ts +30 -5
- package/src/instance.ts +196 -26
- package/src/internal.ts +23 -3
- package/src/kube-client.ts +6 -3
- package/src/machine-doc.ts +29 -5
- package/src/mcp-effect.ts +424 -0
- package/src/model-keys.ts +24 -0
- package/src/mount-digest.ts +41 -7
- package/src/names.ts +82 -7
- package/src/notices.ts +576 -59
- package/src/open-body.ts +110 -30
- package/src/open-effect.ts +17 -4
- package/src/open.ts +40 -7
- package/src/parts.ts +125 -35
- package/src/party.ts +35 -1
- package/src/pick.ts +43 -9
- package/src/pool.ts +1172 -172
- package/src/registration.ts +249 -17
- package/src/repo-identity.ts +7 -3
- package/src/repos.ts +20 -2
- package/src/run-host.ts +1614 -190
- package/src/run-list.ts +191 -0
- package/src/sandbox-effect.ts +217 -66
- package/src/sandbox-kube.ts +116 -21
- package/src/secret-placement.ts +248 -35
- package/src/server.ts +53 -4
- package/src/setup.ts +158 -38
- package/src/snapshot-store.ts +565 -48
- package/src/steer.ts +111 -0
- package/src/stub-harness.ts +6 -2
- package/src/tokens.ts +362 -46
- package/src/vocabulary.ts +23 -4
- package/src/wire.ts +27 -10
- package/src/workspace.ts +314 -259
- package/src/worktree.ts +249 -0
- package/docs/reference/authoring-surface/type-noslotspec.md +0 -26
- package/docs/reference/authoring-surface/type-workspacespec.md +0 -37
- package/docs/reference/decisions/0032-the-console-unlocks-with-the-instance-token.md +0 -61
- package/docs/reference/decisions/0065-a-persist-survives-a-crash-and-history-is-a-week.md +0 -65
package/src/run-list.ts
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// The run listing (ADR-0009): what `GET /runs` reads of its query, the summary of one run, and the
|
|
2
|
+
// cursor of a page. The live runs come from the host's registry and the ended runs from the store's
|
|
3
|
+
// listing columns (`SnapshotStore.ended`); `RunHost.history` joins the two halves in one order,
|
|
4
|
+
// newest start first, so a page is the same whichever half its runs are in.
|
|
5
|
+
|
|
6
|
+
import type { RunStarter } from "./callers.ts";
|
|
7
|
+
import { periodMs } from "./duration.ts";
|
|
8
|
+
import type { DispatchedBy } from "./registration.ts";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* One run as `GET /runs` lists it (ADR-0009): a summary, not the whole `RunStatus`. `status` is
|
|
12
|
+
* `active` for a live run, else the store's word for how it ended. `reason` says why, where the
|
|
13
|
+
* Machine did not: the host's reason (`drifted`, `lost`, ADR-0030), the Failure's reason
|
|
14
|
+
* (`failed`, ADR-0073) or the fault (`error`). `endedAt` is the terminal write of an ended run.
|
|
15
|
+
* `openGates` counts the Gates open now, so it is 0 for an ended run. `placing` names the child
|
|
16
|
+
* paths of the Workspaces that wait for capacity (ADR-0064), and `dispatchedBy` the run that
|
|
17
|
+
* started this one (ADR-0071).
|
|
18
|
+
*/
|
|
19
|
+
export type RunSummary = {
|
|
20
|
+
runId: string;
|
|
21
|
+
workflow: string;
|
|
22
|
+
status: ShownStatus;
|
|
23
|
+
reason?: string;
|
|
24
|
+
startedBy?: RunStarter;
|
|
25
|
+
startedAt: string;
|
|
26
|
+
endedAt?: string;
|
|
27
|
+
assembly?: string;
|
|
28
|
+
openGates: number;
|
|
29
|
+
placing?: string[];
|
|
30
|
+
dispatchedBy?: DispatchedBy;
|
|
31
|
+
/** The space guard deleted the run's kept conversations (ADR-0065); the row stays. */
|
|
32
|
+
swept?: "conversation swept: no space";
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/** A page of the listing: the runs, and the cursor of the next page when there is one. */
|
|
36
|
+
export type RunPage = { runs: RunSummary[]; next?: string };
|
|
37
|
+
|
|
38
|
+
/** How a run ended, as the store writes it (ADR-0065, ADR-0025, ADR-0030, ADR-0073, ADR-0074). */
|
|
39
|
+
export type EndedStatus = "done" | "failed" | "error" | "cancelled" | "lost" | "drifted";
|
|
40
|
+
|
|
41
|
+
/** The statuses of an ended run, as the store writes them. xstate's `stopped` is not one: it is
|
|
42
|
+
* mechanism, and a cancel ends the run `cancelled` (ADR-0025). */
|
|
43
|
+
export const ENDED_STATUSES: readonly EndedStatus[] = ["done", "failed", "error", "cancelled", "lost", "drifted"];
|
|
44
|
+
|
|
45
|
+
/** The status of a live run: the Machine's own word. */
|
|
46
|
+
export const LIVE_STATUS = "active";
|
|
47
|
+
|
|
48
|
+
/** A run status as jr2 shows it, on every route and feed: {@link LIVE_STATUS} while the run is
|
|
49
|
+
* live, else how it ended. The store's own `live` and xstate's `stopped` are never shown. */
|
|
50
|
+
export type ShownStatus = typeof LIVE_STATUS | EndedStatus;
|
|
51
|
+
|
|
52
|
+
/** A word that the store wrote for an ended run. */
|
|
53
|
+
export function isEndedStatus(word: string): word is EndedStatus {
|
|
54
|
+
return (ENDED_STATUSES as readonly string[]).includes(word);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The shown status of a store row: `live` shows as {@link LIVE_STATUS}, and an ended word as
|
|
59
|
+
* itself. jr2 writes no other word. A row with another word is a defect in the store, so it shows
|
|
60
|
+
* as `error`: it is not live, and nothing can say how it ended.
|
|
61
|
+
*/
|
|
62
|
+
export function shownOfRow(word: string): ShownStatus {
|
|
63
|
+
if (word === "live") return LIVE_STATUS;
|
|
64
|
+
return isEndedStatus(word) ? word : "error";
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** How many runs a page holds when the query names no `limit`, and the most it can name. */
|
|
68
|
+
export const RUNS_PAGE_DEFAULT = 50;
|
|
69
|
+
export const RUNS_PAGE_MAX = 500;
|
|
70
|
+
|
|
71
|
+
/** The query of `GET /runs`, read. `ended` is the ended statuses to list, or `undefined` for none. */
|
|
72
|
+
export type RunListQuery = {
|
|
73
|
+
live: boolean;
|
|
74
|
+
ended?: readonly EndedStatus[];
|
|
75
|
+
workflow?: string;
|
|
76
|
+
since?: string;
|
|
77
|
+
after?: { startedAt: string; runId: string };
|
|
78
|
+
limit: number;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/** An ISO-8601 date, or a date and time with an optional zone. */
|
|
82
|
+
const ISO_TIME = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:?\d{2})?)?$/;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Read the query of `GET /runs`, or the refusal's text. `status` is `live` (the default), `ended`,
|
|
86
|
+
* `all`, or a comma list of statuses and the two words; `since` is a duration back from `now`
|
|
87
|
+
* (`"2h"`, `"7d"`) or an ISO-8601 time; `cursor` is a page's `next`; `limit` is 1 to
|
|
88
|
+
* {@link RUNS_PAGE_MAX}.
|
|
89
|
+
*/
|
|
90
|
+
export function parseRunListQuery(
|
|
91
|
+
q: { status?: string; workflow?: string; since?: string; cursor?: string; limit?: string },
|
|
92
|
+
now: number,
|
|
93
|
+
): RunListQuery | { error: string } {
|
|
94
|
+
let live = false;
|
|
95
|
+
const ended = new Set<EndedStatus>();
|
|
96
|
+
for (const word of (q.status ?? "live").split(",").map((w) => w.trim())) {
|
|
97
|
+
if (word === "live" || word === LIVE_STATUS) live = true;
|
|
98
|
+
else if (word === "ended") for (const s of ENDED_STATUSES) ended.add(s);
|
|
99
|
+
else if (word === "all") {
|
|
100
|
+
live = true;
|
|
101
|
+
for (const s of ENDED_STATUSES) ended.add(s);
|
|
102
|
+
} else if (isEndedStatus(word)) ended.add(word);
|
|
103
|
+
else {
|
|
104
|
+
return {
|
|
105
|
+
error: `status "${word}" is not one jr2 lists — use live, ended, all, or a comma list of ${[LIVE_STATUS, ...ENDED_STATUSES].join(", ")}`,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
let since: string | undefined;
|
|
110
|
+
if (q.since !== undefined) {
|
|
111
|
+
const back = periodMs(q.since);
|
|
112
|
+
// Only an ISO-8601 shape reaches `Date.parse`: it reads other text leniently, so `7` would be
|
|
113
|
+
// a time in 2001 and list the whole history.
|
|
114
|
+
const at = back !== undefined ? now - back : ISO_TIME.test(q.since) ? Date.parse(q.since) : Number.NaN;
|
|
115
|
+
if (!Number.isFinite(at)) {
|
|
116
|
+
return { error: `since "${q.since}" is not a duration (such as 2h or 7d) or an ISO-8601 time` };
|
|
117
|
+
}
|
|
118
|
+
// A duration longer than the clock goes back lists every run, as the sweep's `Math.max(0, …)`:
|
|
119
|
+
// a time before 1970 is outside what `Date` can print at its far end.
|
|
120
|
+
since = new Date(Math.max(at, 0)).toISOString();
|
|
121
|
+
}
|
|
122
|
+
let after: RunListQuery["after"];
|
|
123
|
+
if (q.cursor !== undefined) {
|
|
124
|
+
after = decodeCursor(q.cursor);
|
|
125
|
+
if (!after) return { error: "cursor is not one that GET /runs gave — use the next of the page before" };
|
|
126
|
+
}
|
|
127
|
+
let limit = RUNS_PAGE_DEFAULT;
|
|
128
|
+
if (q.limit !== undefined) {
|
|
129
|
+
limit = Number(q.limit);
|
|
130
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > RUNS_PAGE_MAX) {
|
|
131
|
+
return { error: `limit is a whole number from 1 to ${RUNS_PAGE_MAX}` };
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
live,
|
|
136
|
+
...(ended.size ? { ended: [...ended] } : {}),
|
|
137
|
+
...(q.workflow !== undefined && q.workflow !== "" ? { workflow: q.workflow } : {}),
|
|
138
|
+
...(since !== undefined ? { since } : {}),
|
|
139
|
+
...(after ? { after } : {}),
|
|
140
|
+
limit,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** The cursor after `run`: its start and its id, which order the listing. Opaque to a reader. */
|
|
145
|
+
export function encodeCursor(run: { startedAt: string; runId: string }): string {
|
|
146
|
+
return Buffer.from(JSON.stringify([run.startedAt, run.runId])).toString("base64url");
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** A cursor read back, or undefined when it is not one that {@link encodeCursor} made. */
|
|
150
|
+
export function decodeCursor(cursor: string): { startedAt: string; runId: string } | undefined {
|
|
151
|
+
try {
|
|
152
|
+
const value = JSON.parse(Buffer.from(cursor, "base64url").toString("utf8")) as unknown;
|
|
153
|
+
if (!Array.isArray(value) || value.length !== 2) return undefined;
|
|
154
|
+
const [startedAt, runId] = value as unknown[];
|
|
155
|
+
if (typeof startedAt !== "string" || typeof runId !== "string") return undefined;
|
|
156
|
+
if (!Number.isFinite(Date.parse(startedAt))) return undefined;
|
|
157
|
+
return { startedAt, runId };
|
|
158
|
+
} catch {
|
|
159
|
+
return undefined;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** The listing's order: the newest start first, then the larger run id. */
|
|
164
|
+
export function newestFirst(a: RunSummary, b: RunSummary): number {
|
|
165
|
+
if (a.startedAt !== b.startedAt) return a.startedAt < b.startedAt ? 1 : -1;
|
|
166
|
+
return a.runId < b.runId ? 1 : a.runId > b.runId ? -1 : 0;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** Whether `run` comes after the cursor `after` in the order. */
|
|
170
|
+
export function isAfter(
|
|
171
|
+
run: { startedAt: string; runId: string },
|
|
172
|
+
after: { startedAt: string; runId: string },
|
|
173
|
+
): boolean {
|
|
174
|
+
return run.startedAt < after.startedAt || (run.startedAt === after.startedAt && run.runId < after.runId);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/** The child paths of every Workspace in `placing` (ADR-0064), at any depth, off the state values
|
|
178
|
+
* alone. The root in `placing` is the empty path. */
|
|
179
|
+
export function placingOf(value: unknown, children: readonly PlacingChild[]): string[] {
|
|
180
|
+
return [...(value === "placing" ? [""] : []), ...placingIn(children, [])];
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** The part of a `RunChild` that {@link placingOf} reads. */
|
|
184
|
+
export type PlacingChild = { id: string; value: unknown; children: readonly PlacingChild[] };
|
|
185
|
+
|
|
186
|
+
function placingIn(children: readonly PlacingChild[], path: string[]): string[] {
|
|
187
|
+
return children.flatMap((child) => {
|
|
188
|
+
const here = [...path, child.id];
|
|
189
|
+
return [...(child.value === "placing" ? [here.join("/")] : []), ...placingIn(child.children, here)];
|
|
190
|
+
});
|
|
191
|
+
}
|