@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
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: workspace
|
|
3
|
-
description: "Run a body Machine in a Sandbox: a pod of its own, with a
|
|
3
|
+
description: "Run a body Machine in a Sandbox: a pod of its own, with a clone of each Repo Slot."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# `workspace`
|
|
7
7
|
|
|
8
|
-
Function, in `@jr2/orchestrator/src/workspace.ts`. It is an export of `@jr2/orchestrator`,
|
|
8
|
+
Function, in `@jr2/orchestrator/src/workspace.ts`. It is an export of `@jr2/orchestrator`, in the [Workspaces and Repos](group-workspaces-and-repos.md) group of the [Authoring surface](../authoring-surface.md) page.
|
|
9
9
|
|
|
10
10
|
## Overload 1
|
|
11
11
|
|
|
@@ -20,30 +20,33 @@ function workspace<
|
|
|
20
20
|
): WorkspaceMachine<WithoutEmptyIndex<z.infer<TSchema>>, OutputFrom<TBody>, TBody, TSlots>
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
Run a body Machine in a Sandbox: a pod of its own, with a
|
|
24
|
-
|
|
23
|
+
Run a body Machine in a Sandbox: a pod of its own, with a clone of each Repo Slot. The result is
|
|
24
|
+
a Machine. Register it as a Workflow, or invoke it from another Machine as
|
|
25
25
|
an actor slot.
|
|
26
26
|
|
|
27
27
|
When a run enters it, the Workspace makes the Sandbox and waits for room on a node, with no
|
|
28
|
-
deadline. It clones each Repo Slot
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
deadline. It clones each Repo Slot to `/work/<slot>/default`, on the Binding's base, and makes no
|
|
29
|
+
Worktree: the body cuts each Worktree that it needs with `worktree()`. A slot that is only read
|
|
30
|
+
needs no cut. No work happens in `default/`. Then it runs the body with the run input plus
|
|
31
|
+
`workspace`, the handles (see [`Workspaced`](type-workspaced.md)). The Agents with Working tools and the `command` Effects in the body run in that Sandbox. An Agent
|
|
31
32
|
with `workspace: "none"` runs on the Instance Harness. When the body reaches a final state, the
|
|
32
|
-
Workspace deletes the Sandbox, and its output is the body's output. Push
|
|
33
|
+
Workspace deletes the Sandbox, and its output is the body's output. Push each branch before
|
|
33
34
|
then: jr2 deletes the Sandbox's commits with it.
|
|
34
35
|
|
|
36
|
+
The author chooses how many Agents work in a Workspace. Agents in one Worktree share git, as
|
|
37
|
+
people in one checkout do. Each coder that needs its own branch gets its own Worktree of the one
|
|
38
|
+
clone.
|
|
39
|
+
|
|
35
40
|
Leave out `repos` for a Workspace with no Repo Slot: its Agents and `command` Effects share
|
|
36
|
-
`/work`, as the steps of one job share a folder,
|
|
37
|
-
`
|
|
38
|
-
|
|
39
|
-
need a Repo Slot, so jr2 refuses them there. jr2 deletes `/work` with the Sandbox: send what
|
|
41
|
+
`/work`, as the steps of one job share a folder. The body's input is then `Workspaced<RunInput, never>`. An `http` Effect sends a
|
|
42
|
+
file of `/work` with `file(path)`. A `worktree()`, a `push`, and a `command` with an Effect secret in its
|
|
43
|
+
`env`, need a Repo Slot, so jr2 refuses them there. jr2 deletes `/work` with the Sandbox: send what
|
|
40
44
|
must stay before the body ends.
|
|
41
45
|
|
|
42
46
|
Give each run a different branch, so that two runs do not push to one branch. Make it from a
|
|
43
47
|
field of the run input, or from `instanceId` when the run input has no field that is different
|
|
44
|
-
for each run: ``
|
|
45
|
-
`
|
|
46
|
-
`workspace()` gets `instanceId` from jr2. A `workspace()` that a different Machine invokes gets
|
|
48
|
+
for each run: ``branch: `fix/${context.instanceId}` `` in the input of the cut. Add
|
|
49
|
+
`HostInjectedInput` to the body's input type to read it. Only a root `workspace()` gets `instanceId` from jr2. A `workspace()` that a different Machine invokes gets
|
|
47
50
|
it only when its parent gives it.
|
|
48
51
|
|
|
49
52
|
The Sandbox is Lost when its pod is evicted or its node goes. Then the body gets the event
|
|
@@ -67,7 +70,7 @@ It refuses, when you call it:
|
|
|
67
70
|
- a body with its own `input`: ``workspace(): the body "<id>" declares its own run input, which
|
|
68
71
|
nothing will ever serve or enforce — the wrapper feeds the body the run input PLUS the injected
|
|
69
72
|
`workspace` handles, so the body's schema is not the door. Move it to the wrapper:
|
|
70
|
-
workspace(body, { input
|
|
73
|
+
workspace(body, { input }) (ADR-0033).``
|
|
71
74
|
- an empty `image`: ``workspace(): `image` must be a non-empty string (got <value>) — either a
|
|
72
75
|
`file:` URL to a docker context this module ships (`import.meta.resolve("./image")`) or a
|
|
73
76
|
registry ref (ADR-0037).``
|
|
@@ -77,9 +80,7 @@ It refuses, when you call it:
|
|
|
77
80
|
`repos: { app: "https://…" }` — or `open` whole, for a map the consumer names; leave it out
|
|
78
81
|
for a Workspace with no Repo Slot (ADR-0051).``
|
|
79
82
|
- a bad Repo Slot name or value (see [`RepoSlot`](type-reposlot.md))
|
|
80
|
-
- a `
|
|
81
|
-
`spec` must be a function from the run input to the spec — spec: ({ input }) => ({ branch }) —
|
|
82
|
-
and only a Workspace with no Repo Slot may leave it out (ADR-0051).``
|
|
83
|
+
- a `workGroup` that is not a gid: ``workspace(): `workGroup` must be a gid (got <value>)``
|
|
83
84
|
- a bad `secrets` list: ``workspace(): `secrets` must be a list of distinct names from
|
|
84
85
|
jr2.config.ts's `secrets` list (got <value>) — secrets: ["JIRA_TOKEN"] (ADR-0059).``
|
|
85
86
|
- a bad `effector`: ``workspace(): `effector` is { image } — a `file:` URL to a docker context
|
|
@@ -95,19 +96,16 @@ It refuses, when you call it:
|
|
|
95
96
|
(ADR-0060)``, or the same text for `resources.limits.<key>`. The other texts are in
|
|
96
97
|
[`Size`](type-size.md).
|
|
97
98
|
|
|
98
|
-
And when a run enters it, a
|
|
99
|
-
|
|
100
|
-
does `jr2 run --input` carry every field this workflow's workspace()
|
|
101
|
-
Repo Slot, a spec with a `branch` or a `reviewSha`: ``workspace spec invalid: <field> (the
|
|
102
|
-
Workspace has no Repo Slot, so it has no branch and no review Worktree; its spec gives only
|
|
103
|
-
workGroup) …``
|
|
99
|
+
And when a run enters it, a per-run Repo Slot's mapper that gives no `url`, or a bad `ref`:
|
|
100
|
+
``workspace invalid: repos.<slot> mapper returned <fields> — the mapper derives from run
|
|
101
|
+
input; does `jr2 run --input` carry every field this workflow's workspace() slot reads?``
|
|
104
102
|
|
|
105
103
|
**Parameters**
|
|
106
104
|
|
|
107
105
|
- `body`: The Machine to run in the Sandbox. Its input is `Workspaced<RunInput, Slots>`.
|
|
108
106
|
- `options` ([`WorkspaceOptions`](type-workspaceoptions.md) | [`NoSlotWorkspaceOptions`](type-noslotworkspaceoptions.md)): What the Sandbox is made of (`image`, `user`, `resources`, `effector`), the
|
|
109
|
-
Repo Slots it clones (`repos`), the Held secrets it can use (`secrets`), the
|
|
110
|
-
(`
|
|
107
|
+
Repo Slots it clones (`repos`), the Held secrets it can use (`secrets`), the pod's `fsGroup`
|
|
108
|
+
(`workGroup`), and the run input (`input`).
|
|
111
109
|
|
|
112
110
|
**Returns**: A Machine whose input is the run input and whose output is the body's output.
|
|
113
111
|
|
|
@@ -118,8 +116,10 @@ import { z } from "zod";
|
|
|
118
116
|
import {
|
|
119
117
|
command,
|
|
120
118
|
fail,
|
|
119
|
+
isReady,
|
|
121
120
|
jr2Setup,
|
|
122
121
|
workspace,
|
|
122
|
+
worktree,
|
|
123
123
|
type CommandOutput,
|
|
124
124
|
type Workspaced,
|
|
125
125
|
} from "@jr2/orchestrator";
|
|
@@ -127,23 +127,36 @@ import {
|
|
|
127
127
|
const runInput = z.object({ ticket: z.string(), repo: z.string() });
|
|
128
128
|
type BodyInput = Workspaced<z.infer<typeof runInput>, "app" | "docs">;
|
|
129
129
|
|
|
130
|
+
// The Worktree of this run. An Agent or a command that only reads `docs` uses `/work/docs/default`.
|
|
131
|
+
const buildTree = (context: BodyInput) => `${context.workspace.repos.app}/build` as const;
|
|
132
|
+
|
|
130
133
|
const passed = (output: CommandOutput): boolean =>
|
|
131
134
|
output.outcome === "exited" && output.code === 0;
|
|
132
135
|
|
|
133
136
|
const body = jr2Setup({
|
|
134
|
-
types: {} as { input: BodyInput },
|
|
137
|
+
types: {} as { input: BodyInput; context: BodyInput },
|
|
135
138
|
actors: {
|
|
136
|
-
|
|
139
|
+
cut: worktree(),
|
|
140
|
+
build: command(["npm", "run", "build"]),
|
|
137
141
|
fail: fail(),
|
|
138
142
|
},
|
|
139
143
|
}).createMachine({
|
|
140
144
|
id: "build",
|
|
145
|
+
context: ({ input }) => input,
|
|
141
146
|
on: { "workspace.lost": ".lost" },
|
|
142
|
-
initial: "
|
|
147
|
+
initial: "cutting",
|
|
143
148
|
states: {
|
|
149
|
+
cutting: {
|
|
150
|
+
invoke: {
|
|
151
|
+
src: "cut",
|
|
152
|
+
input: ({ context }) => ({ path: buildTree(context), branch: `fix/${context.ticket}` }),
|
|
153
|
+
onDone: [{ guard: ({ event }) => isReady(event.output), target: "building" }, { target: "notCut" }],
|
|
154
|
+
},
|
|
155
|
+
},
|
|
144
156
|
building: {
|
|
145
157
|
invoke: {
|
|
146
158
|
src: "build",
|
|
159
|
+
input: ({ context }) => ({ worktree: buildTree(context) }),
|
|
147
160
|
onDone: [
|
|
148
161
|
{ guard: ({ event }) => passed(event.output), target: "built" },
|
|
149
162
|
{ target: "broken" },
|
|
@@ -152,6 +165,7 @@ const body = jr2Setup({
|
|
|
152
165
|
},
|
|
153
166
|
built: { type: "final" },
|
|
154
167
|
broken: { invoke: { src: "fail", input: { reason: "npm run build did not pass" } } },
|
|
168
|
+
notCut: { invoke: { src: "fail", input: { reason: "the Worktree was not cut" } } },
|
|
155
169
|
lost: { invoke: { src: "fail", input: { reason: "the Sandbox is gone" } } },
|
|
156
170
|
},
|
|
157
171
|
});
|
|
@@ -164,7 +178,6 @@ export const machine = workspace(body, {
|
|
|
164
178
|
app: ({ input }) => input.repo,
|
|
165
179
|
docs: { url: "https://github.com/you/docs.git", ref: "main" },
|
|
166
180
|
},
|
|
167
|
-
spec: ({ input }) => ({ branch: `fix/${input.ticket}` }),
|
|
168
181
|
});
|
|
169
182
|
```
|
|
170
183
|
|
|
@@ -175,9 +188,12 @@ import { z } from "zod";
|
|
|
175
188
|
import {
|
|
176
189
|
command,
|
|
177
190
|
fail,
|
|
191
|
+
isReady,
|
|
178
192
|
jr2Setup,
|
|
179
193
|
workspace,
|
|
194
|
+
worktree,
|
|
180
195
|
type CommandOutput,
|
|
196
|
+
type HostInjectedInput,
|
|
181
197
|
type Workspaced,
|
|
182
198
|
} from "@jr2/orchestrator";
|
|
183
199
|
|
|
@@ -187,18 +203,30 @@ const passed = (output: CommandOutput): boolean =>
|
|
|
187
203
|
// The run input has no field that is different for each run, so the branch comes from
|
|
188
204
|
// `instanceId`.
|
|
189
205
|
const runInput = z.object({});
|
|
206
|
+
type BodyInput = Workspaced<z.infer<typeof runInput> & HostInjectedInput, "app">;
|
|
207
|
+
|
|
208
|
+
const nightlyTree = (context: BodyInput) => `${context.workspace.repos.app}/nightly` as const;
|
|
190
209
|
|
|
191
210
|
const body = jr2Setup({
|
|
192
|
-
types: {} as { input:
|
|
193
|
-
actors: { test: command(["npm", "test"]
|
|
211
|
+
types: {} as { input: BodyInput; context: BodyInput },
|
|
212
|
+
actors: { cut: worktree(), test: command(["npm", "test"]), fail: fail() },
|
|
194
213
|
}).createMachine({
|
|
195
214
|
id: "nightly",
|
|
215
|
+
context: ({ input }) => input,
|
|
196
216
|
on: { "workspace.lost": ".lost" },
|
|
197
|
-
initial: "
|
|
217
|
+
initial: "cutting",
|
|
198
218
|
states: {
|
|
219
|
+
cutting: {
|
|
220
|
+
invoke: {
|
|
221
|
+
src: "cut",
|
|
222
|
+
input: ({ context }) => ({ path: nightlyTree(context), branch: `nightly/${context.instanceId}` }),
|
|
223
|
+
onDone: [{ guard: ({ event }) => isReady(event.output), target: "testing" }, { target: "notCut" }],
|
|
224
|
+
},
|
|
225
|
+
},
|
|
199
226
|
testing: {
|
|
200
227
|
invoke: {
|
|
201
228
|
src: "test",
|
|
229
|
+
input: ({ context }) => ({ worktree: nightlyTree(context) }),
|
|
202
230
|
onDone: [
|
|
203
231
|
{ guard: ({ event }) => passed(event.output), target: "tested" },
|
|
204
232
|
{ target: "red" },
|
|
@@ -207,6 +235,7 @@ const body = jr2Setup({
|
|
|
207
235
|
},
|
|
208
236
|
tested: { type: "final" },
|
|
209
237
|
red: { invoke: { src: "fail", input: { reason: "npm test did not pass" } } },
|
|
238
|
+
notCut: { invoke: { src: "fail", input: { reason: "the Worktree was not cut" } } },
|
|
210
239
|
lost: { invoke: { src: "fail", input: { reason: "the Sandbox is gone" } } },
|
|
211
240
|
},
|
|
212
241
|
});
|
|
@@ -215,7 +244,6 @@ export const machine = workspace(body, {
|
|
|
215
244
|
input: runInput,
|
|
216
245
|
image: "docker.io/library/node:24",
|
|
217
246
|
repos: { app: "https://github.com/you/app.git" },
|
|
218
|
-
spec: ({ input }) => ({ branch: `fix/${input.instanceId}` }),
|
|
219
247
|
});
|
|
220
248
|
```
|
|
221
249
|
|
|
@@ -234,10 +262,10 @@ export const machine = workspace(body, {
|
|
|
234
262
|
function workspace<
|
|
235
263
|
TBody extends AnyStateMachine,
|
|
236
264
|
TSlots extends string = never,
|
|
237
|
-
TInput =
|
|
265
|
+
TInput = DoorlessInput<TBody>,
|
|
238
266
|
>(
|
|
239
267
|
body: TBody & BodyAcceptsSlots<TBody, TSlots>,
|
|
240
|
-
options: PermissiveWorkspaceOptions<TSlots, TInput
|
|
268
|
+
options: PermissiveWorkspaceOptions<TSlots, Exclude<TInput, undefined>> | PermissiveNoSlotWorkspaceOptions,
|
|
241
269
|
): WorkspaceMachine<TInput, OutputFrom<TBody>, TBody, TSlots>
|
|
242
270
|
```
|
|
243
271
|
|
|
@@ -249,7 +277,7 @@ what it refuses.
|
|
|
249
277
|
|
|
250
278
|
- `body`: The Machine to run in the Sandbox. Its input is the input of the Workspace plus
|
|
251
279
|
`workspace`, the handles.
|
|
252
|
-
- `options` ([`PermissiveWorkspaceOptions`](type-permissiveworkspaceoptions.md) | [`PermissiveNoSlotWorkspaceOptions`](type-permissivenoslotworkspaceoptions.md)): The options of the Sandbox
|
|
280
|
+
- `options` ([`PermissiveWorkspaceOptions`](type-permissiveworkspaceoptions.md) | [`PermissiveNoSlotWorkspaceOptions`](type-permissivenoslotworkspaceoptions.md)): The options of the Sandbox. There is no `input`.
|
|
253
281
|
|
|
254
282
|
**Returns**: A Machine whose input is the run input and whose output is the body's output.
|
|
255
283
|
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: worktree
|
|
3
|
+
description: "Make a `worktree` Effect: it cuts a Worktree of a Repo Slot, or reads the one that is there."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# `worktree`
|
|
7
|
+
|
|
8
|
+
Function, in `@jr2/orchestrator/src/worktree.ts`. It is an export of `@jr2/orchestrator`, in the [Effects](group-effects.md) group of the [Authoring surface](../authoring-surface.md) page.
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
function worktree(options: WorktreeOptions = {}): EffectLogic<WorktreeInput, WorktreeOutput>
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Make a `worktree` Effect: it cuts a Worktree of a Repo Slot, or reads the one that is there. Put it
|
|
15
|
+
in `actors`, and invoke it from a `workspace()` body.
|
|
16
|
+
|
|
17
|
+
With `{ path, branch, from? }`, the branch resolves in this order, after a fetch: a local branch;
|
|
18
|
+
`origin/<branch>`, tracked; a new branch from `from` or the Binding's base, with no upstream. With
|
|
19
|
+
`{ path, detach }`, the Worktree is forced to that commit and cleaned, each time. `path` is exactly
|
|
20
|
+
`/work/<slot>/<name>`. Each outcome is output: `ready`, `refused`, `unknown`.
|
|
21
|
+
|
|
22
|
+
`expect` says if the branch can exist: `worktree({ expect: "new" })` refuses a branch that exists,
|
|
23
|
+
and `worktree({ expect: "existing" })` refuses a branch that does not exist. A run cannot change it.
|
|
24
|
+
|
|
25
|
+
A cut needs a Repo Slot. Under a Workspace with no Repo Slot, `jr2 up` refuses it, and the invoke
|
|
26
|
+
fails with `worktree "<slot>" runs under a Workspace with no Repo Slot: a cut makes a Worktree of a
|
|
27
|
+
Repo Slot, and there is none — declare one: repos: { app: "<url>" } (ADR-0075)`.
|
|
28
|
+
|
|
29
|
+
**Parameters**
|
|
30
|
+
|
|
31
|
+
- `options` ([`WorktreeOptions`](type-worktreeoptions.md)): Optional. `expect`, and `timeout`, how long the fetch and the cut can take.
|
|
32
|
+
Default: `"10m"`.
|
|
33
|
+
|
|
34
|
+
**Returns**: The actor logic of the Effect's slot. Its output is a [`WorktreeOutput`](type-worktreeoutput.md).
|
|
35
|
+
|
|
36
|
+
**Example**
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import { fail, isReady, jr2Setup, worktree, type Workspaced } from "@jr2/orchestrator";
|
|
40
|
+
|
|
41
|
+
type BodyInput = Workspaced<{ branch: string }, "app">;
|
|
42
|
+
const tree = (context: BodyInput) => `${context.workspace.repos.app}/fix` as const;
|
|
43
|
+
|
|
44
|
+
export const body = jr2Setup({
|
|
45
|
+
types: {} as { input: BodyInput; context: BodyInput },
|
|
46
|
+
actors: { cut: worktree({ expect: "new" }), fail: fail() },
|
|
47
|
+
}).createMachine({
|
|
48
|
+
context: ({ input }) => input,
|
|
49
|
+
on: { "workspace.lost": ".notCut" },
|
|
50
|
+
initial: "cutting",
|
|
51
|
+
states: {
|
|
52
|
+
cutting: {
|
|
53
|
+
invoke: {
|
|
54
|
+
src: "cut",
|
|
55
|
+
input: ({ context }) => ({ path: tree(context), branch: context.branch }),
|
|
56
|
+
// The last arm has no guard: it takes `refused`, `unknown` and each later outcome.
|
|
57
|
+
onDone: [{ guard: ({ event }) => isReady(event.output), target: "done" }, { target: "notCut" }],
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
done: { type: "final" },
|
|
61
|
+
notCut: { invoke: { src: "fail", input: { reason: "the Worktree was not cut" } } },
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**See also**
|
|
67
|
+
|
|
68
|
+
- [Cut a Worktree](../../guides/cut-a-worktree.md)
|
|
69
|
+
- [Workspaces](../../concepts/workspaces.md)
|
|
70
|
+
- [Effects](../../concepts/effects.md)
|
|
71
|
+
- [ADR-0075: A Machine cuts a Worktree, and the Workspace only clones](../decisions/0075-a-machine-cuts-a-worktree-and-the-workspace-only-clones.md)
|