@intentic/sandbox-contract 1.344.0 → 1.346.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/README.md +27 -9
- package/dist/contracts/accounts.contract.d.ts +24 -80
- package/dist/contracts/accounts.contract.d.ts.map +1 -1
- package/dist/contracts/agent.contract.d.ts +247 -8
- package/dist/contracts/agent.contract.d.ts.map +1 -1
- package/dist/contracts/agent.contract.js +13 -2
- package/dist/contracts/agent.contract.js.map +1 -1
- package/dist/contracts/agents.contract.d.ts +1570 -33
- package/dist/contracts/agents.contract.d.ts.map +1 -1
- package/dist/contracts/agents.contract.js +47 -4
- package/dist/contracts/agents.contract.js.map +1 -1
- package/dist/contracts/device.contract.d.ts +244 -1
- package/dist/contracts/device.contract.d.ts.map +1 -1
- package/dist/contracts/device.contract.js +5 -1
- package/dist/contracts/device.contract.js.map +1 -1
- package/dist/contracts/endpoints.contract.d.ts +2 -1
- package/dist/contracts/endpoints.contract.d.ts.map +1 -1
- package/dist/contracts/endpoints.contract.js +1 -0
- package/dist/contracts/endpoints.contract.js.map +1 -1
- package/dist/contracts/providers.contract.d.ts +0 -1
- package/dist/contracts/providers.contract.d.ts.map +1 -1
- package/dist/contracts/push.contract.d.ts +11 -0
- package/dist/contracts/push.contract.d.ts.map +1 -1
- package/dist/contracts/push.contract.js +10 -1
- package/dist/contracts/push.contract.js.map +1 -1
- package/dist/contracts/runner.contract.d.ts +149 -123
- package/dist/contracts/runner.contract.d.ts.map +1 -1
- package/dist/contracts/secrets.contract.d.ts +169 -0
- package/dist/contracts/secrets.contract.d.ts.map +1 -1
- package/dist/contracts/secrets.contract.js +35 -0
- package/dist/contracts/secrets.contract.js.map +1 -1
- package/dist/contracts/sessions.contract.d.ts +2 -0
- package/dist/contracts/sessions.contract.d.ts.map +1 -1
- package/dist/contracts/settings.contract.d.ts +37 -0
- package/dist/contracts/settings.contract.d.ts.map +1 -1
- package/dist/contracts/system.contract.d.ts +235 -31
- package/dist/contracts/system.contract.d.ts.map +1 -1
- package/dist/contracts/translator.contract.d.ts +24 -80
- package/dist/contracts/translator.contract.d.ts.map +1 -1
- package/dist/contracts/workspace.contract.d.ts +11 -0
- package/dist/contracts/workspace.contract.d.ts.map +1 -1
- package/dist/contracts/workspace.contract.js +11 -1
- package/dist/contracts/workspace.contract.js.map +1 -1
- package/dist/events/agent-events.d.ts +60 -0
- package/dist/events/agent-events.d.ts.map +1 -1
- package/dist/events/agent-events.js +44 -38
- package/dist/events/agent-events.js.map +1 -1
- package/dist/events/agent-transcript.d.ts +727 -0
- package/dist/events/agent-transcript.d.ts.map +1 -0
- package/dist/events/agent-transcript.js +34 -0
- package/dist/events/agent-transcript.js.map +1 -0
- package/dist/events/agent-words.d.ts +5 -0
- package/dist/events/agent-words.d.ts.map +1 -1
- package/dist/events/agent-words.js +9 -0
- package/dist/events/agent-words.js.map +1 -1
- package/dist/events/failure-rows.d.ts +14 -0
- package/dist/events/failure-rows.d.ts.map +1 -0
- package/dist/events/failure-rows.js +109 -0
- package/dist/events/failure-rows.js.map +1 -0
- package/dist/events/requests.d.ts +143 -0
- package/dist/events/requests.d.ts.map +1 -1
- package/dist/events/requests.js +35 -1
- package/dist/events/requests.js.map +1 -1
- package/dist/events/sandbox-notice.d.ts +23 -0
- package/dist/events/sandbox-notice.d.ts.map +1 -1
- package/dist/events/sandbox-notice.js +2 -0
- package/dist/events/sandbox-notice.js.map +1 -1
- package/dist/events/system-events.d.ts +156 -0
- package/dist/events/system-events.d.ts.map +1 -1
- package/dist/events/system-events.js +7 -1
- package/dist/events/system-events.js.map +1 -1
- package/dist/events/transcript.d.ts +20 -720
- package/dist/events/transcript.d.ts.map +1 -1
- package/dist/events/transcript.js +17 -19
- package/dist/events/transcript.js.map +1 -1
- package/dist/ids/conversation-ids.d.ts +2 -0
- package/dist/ids/conversation-ids.d.ts.map +1 -1
- package/dist/ids/conversation-ids.js +2 -0
- package/dist/ids/conversation-ids.js.map +1 -1
- package/dist/ids/row-ids.d.ts +3 -0
- package/dist/ids/row-ids.d.ts.map +1 -0
- package/dist/ids/row-ids.js +11 -0
- package/dist/ids/row-ids.js.map +1 -0
- package/dist/index.d.ts +2296 -199
- package/dist/index.d.ts.map +1 -1
- package/dist/models/agent-lanes.d.ts.map +1 -1
- package/dist/models/agent-lanes.js +6 -7
- package/dist/models/agent-lanes.js.map +1 -1
- package/dist/models/agent-standing.d.ts +6 -19
- package/dist/models/agent-standing.d.ts.map +1 -1
- package/dist/models/agent-standing.js +14 -38
- package/dist/models/agent-standing.js.map +1 -1
- package/dist/models/model-pins.d.ts +3 -0
- package/dist/models/model-pins.d.ts.map +1 -1
- package/dist/models/model-pins.js +2 -0
- package/dist/models/model-pins.js.map +1 -1
- package/dist/models/plan-pools.d.ts +26 -4
- package/dist/models/plan-pools.d.ts.map +1 -1
- package/dist/models/plan-pools.js +159 -40
- package/dist/models/plan-pools.js.map +1 -1
- package/dist/netd/generated/wire.d.ts +5 -0
- package/dist/netd/generated/wire.d.ts.map +1 -1
- package/dist/policy/command-classes.d.ts +1 -1
- package/dist/policy/command-classes.d.ts.map +1 -1
- package/dist/policy/command-classes.js +2 -2
- package/dist/policy/command-classes.js.map +1 -1
- package/dist/policy/keyring-origins.d.ts +27 -0
- package/dist/policy/keyring-origins.d.ts.map +1 -0
- package/dist/policy/keyring-origins.js +213 -0
- package/dist/policy/keyring-origins.js.map +1 -0
- package/dist/policy/keyring-seal.d.ts +9 -0
- package/dist/policy/keyring-seal.d.ts.map +1 -1
- package/dist/policy/keyring-seal.js +18 -6
- package/dist/policy/keyring-seal.js.map +1 -1
- package/dist/policy/safety-policy.d.ts +1 -1
- package/dist/policy/safety-policy.d.ts.map +1 -1
- package/dist/policy/safety-policy.js +1 -1
- package/dist/policy/safety-policy.js.map +1 -1
- package/dist/policy/turned-away.d.ts +1 -0
- package/dist/policy/turned-away.d.ts.map +1 -1
- package/dist/policy/turned-away.js +10 -0
- package/dist/policy/turned-away.js.map +1 -1
- package/dist/protocol/doors/host-protocol.d.ts +1 -0
- package/dist/protocol/doors/host-protocol.d.ts.map +1 -1
- package/dist/protocol/doors/host-protocol.js +1 -0
- package/dist/protocol/doors/host-protocol.js.map +1 -1
- package/dist/protocol/doors/runner-protocol.d.ts +1 -0
- package/dist/protocol/doors/runner-protocol.d.ts.map +1 -1
- package/dist/protocol/doors/runner-protocol.js +1 -0
- package/dist/protocol/doors/runner-protocol.js.map +1 -1
- package/dist/protocol/doors/webext-links.d.ts +1 -0
- package/dist/protocol/doors/webext-links.d.ts.map +1 -1
- package/dist/protocol/doors/webext-links.js +1 -0
- package/dist/protocol/doors/webext-links.js.map +1 -1
- package/dist/protocol/peer-dial.d.ts +2 -0
- package/dist/protocol/peer-dial.d.ts.map +1 -1
- package/dist/protocol/peer-dial.js +62 -29
- package/dist/protocol/peer-dial.js.map +1 -1
- package/dist/protocol/raw/raw-json-routes.d.ts +179 -1
- package/dist/protocol/raw/raw-json-routes.d.ts.map +1 -1
- package/dist/protocol/raw/raw-json-routes.js +5 -0
- package/dist/protocol/raw/raw-json-routes.js.map +1 -1
- package/dist/protocol/raw/raw-routes.d.ts +35 -0
- package/dist/protocol/raw/raw-routes.d.ts.map +1 -1
- package/dist/protocol/raw/raw-routes.js +9 -0
- package/dist/protocol/raw/raw-routes.js.map +1 -1
- package/dist/schemas/agent-next.d.ts +21 -0
- package/dist/schemas/agent-next.d.ts.map +1 -0
- package/dist/schemas/agent-next.js +21 -0
- package/dist/schemas/agent-next.js.map +1 -0
- package/dist/schemas/agent-place.d.ts +10 -0
- package/dist/schemas/agent-place.d.ts.map +1 -0
- package/dist/schemas/agent-place.js +15 -0
- package/dist/schemas/agent-place.js.map +1 -0
- package/dist/schemas/agent-search.d.ts +45 -0
- package/dist/schemas/agent-search.d.ts.map +1 -0
- package/dist/schemas/agent-search.js +28 -0
- package/dist/schemas/agent-search.js.map +1 -0
- package/dist/schemas/agent.d.ts +120 -78
- package/dist/schemas/agent.d.ts.map +1 -1
- package/dist/schemas/agent.js +40 -49
- package/dist/schemas/agent.js.map +1 -1
- package/dist/schemas/agents-list.d.ts +54 -0
- package/dist/schemas/agents-list.d.ts.map +1 -1
- package/dist/schemas/agents.d.ts +165 -59
- package/dist/schemas/agents.d.ts.map +1 -1
- package/dist/schemas/agents.js +25 -50
- package/dist/schemas/agents.js.map +1 -1
- package/dist/schemas/attach.d.ts +8 -0
- package/dist/schemas/attach.d.ts.map +1 -0
- package/dist/schemas/attach.js +14 -0
- package/dist/schemas/attach.js.map +1 -0
- package/dist/schemas/command-admission.d.ts +71 -0
- package/dist/schemas/command-admission.d.ts.map +1 -0
- package/dist/schemas/command-admission.js +27 -0
- package/dist/schemas/command-admission.js.map +1 -0
- package/dist/schemas/compose-overlay.d.ts +9 -0
- package/dist/schemas/compose-overlay.d.ts.map +1 -0
- package/dist/schemas/compose-overlay.js +11 -0
- package/dist/schemas/compose-overlay.js.map +1 -0
- package/dist/schemas/composer-drafts.d.ts +169 -0
- package/dist/schemas/composer-drafts.d.ts.map +1 -0
- package/dist/schemas/composer-drafts.js +60 -0
- package/dist/schemas/composer-drafts.js.map +1 -0
- package/dist/schemas/conversation-links.d.ts +44 -0
- package/dist/schemas/conversation-links.d.ts.map +1 -0
- package/dist/schemas/conversation-links.js +35 -0
- package/dist/schemas/conversation-links.js.map +1 -0
- package/dist/schemas/data-protection.d.ts +1 -1
- package/dist/schemas/data-protection.d.ts.map +1 -1
- package/dist/schemas/device-commands.d.ts +63 -0
- package/dist/schemas/device-commands.d.ts.map +1 -0
- package/dist/schemas/device-commands.js +42 -0
- package/dist/schemas/device-commands.js.map +1 -0
- package/dist/schemas/device-folder.d.ts +11 -0
- package/dist/schemas/device-folder.d.ts.map +1 -1
- package/dist/schemas/device-folder.js +1 -0
- package/dist/schemas/device-folder.js.map +1 -1
- package/dist/schemas/devices.d.ts +18 -68
- package/dist/schemas/devices.d.ts.map +1 -1
- package/dist/schemas/devices.js +8 -45
- package/dist/schemas/devices.js.map +1 -1
- package/dist/schemas/environment.d.ts.map +1 -1
- package/dist/schemas/environment.js.map +1 -1
- package/dist/schemas/hosts.d.ts +29 -0
- package/dist/schemas/hosts.d.ts.map +1 -1
- package/dist/schemas/hosts.js +23 -0
- package/dist/schemas/hosts.js.map +1 -1
- package/dist/schemas/keyring-native.d.ts +137 -0
- package/dist/schemas/keyring-native.d.ts.map +1 -0
- package/dist/schemas/keyring-native.js +69 -0
- package/dist/schemas/keyring-native.js.map +1 -0
- package/dist/schemas/keyring.d.ts +413 -0
- package/dist/schemas/keyring.d.ts.map +1 -1
- package/dist/schemas/keyring.js +139 -4
- package/dist/schemas/keyring.js.map +1 -1
- package/dist/schemas/phone-passwords.d.ts +186 -0
- package/dist/schemas/phone-passwords.d.ts.map +1 -0
- package/dist/schemas/phone-passwords.js +25 -0
- package/dist/schemas/phone-passwords.js.map +1 -0
- package/dist/schemas/privacy-egress.d.ts +41 -0
- package/dist/schemas/privacy-egress.d.ts.map +1 -0
- package/dist/schemas/privacy-egress.js +30 -0
- package/dist/schemas/privacy-egress.js.map +1 -0
- package/dist/schemas/privacy.d.ts +1 -0
- package/dist/schemas/privacy.d.ts.map +1 -1
- package/dist/schemas/privacy.js +1 -0
- package/dist/schemas/privacy.js.map +1 -1
- package/dist/schemas/providers/plan-limits.d.ts +76 -130
- package/dist/schemas/providers/plan-limits.d.ts.map +1 -1
- package/dist/schemas/providers/plan-limits.js +36 -23
- package/dist/schemas/providers/plan-limits.js.map +1 -1
- package/dist/schemas/providers/provider-oauth.d.ts +24 -82
- package/dist/schemas/providers/provider-oauth.d.ts.map +1 -1
- package/dist/schemas/providers/provider-oauth.js +1 -6
- package/dist/schemas/providers/provider-oauth.js.map +1 -1
- package/dist/schemas/providers/refusals.d.ts +64 -0
- package/dist/schemas/providers/refusals.d.ts.map +1 -0
- package/dist/schemas/providers/refusals.js +33 -0
- package/dist/schemas/providers/refusals.js.map +1 -0
- package/dist/schemas/providers/usage.d.ts +1 -0
- package/dist/schemas/providers/usage.d.ts.map +1 -1
- package/dist/schemas/providers/usage.js +1 -0
- package/dist/schemas/providers/usage.js.map +1 -1
- package/dist/schemas/push.d.ts +13 -0
- package/dist/schemas/push.d.ts.map +1 -1
- package/dist/schemas/push.js +11 -1
- package/dist/schemas/push.js.map +1 -1
- package/dist/schemas/sandbox-passwords.d.ts +288 -0
- package/dist/schemas/sandbox-passwords.d.ts.map +1 -0
- package/dist/schemas/sandbox-passwords.js +66 -0
- package/dist/schemas/sandbox-passwords.js.map +1 -0
- package/dist/schemas/secrets.d.ts +2 -0
- package/dist/schemas/secrets.d.ts.map +1 -1
- package/dist/schemas/secrets.js +4 -0
- package/dist/schemas/secrets.js.map +1 -1
- package/dist/schemas/sessions.js +1 -1
- package/dist/schemas/sessions.js.map +1 -1
- package/dist/schemas/settings-savings.d.ts +709 -0
- package/dist/schemas/settings-savings.d.ts.map +1 -0
- package/dist/schemas/settings-savings.js +53 -0
- package/dist/schemas/settings-savings.js.map +1 -0
- package/dist/schemas/settings.d.ts +7 -671
- package/dist/schemas/settings.d.ts.map +1 -1
- package/dist/schemas/settings.js +5 -50
- package/dist/schemas/settings.js.map +1 -1
- package/dist/schemas/system.d.ts +16 -0
- package/dist/schemas/system.d.ts.map +1 -1
- package/dist/schemas/system.js +11 -0
- package/dist/schemas/system.js.map +1 -1
- package/dist/schemas/terminal.d.ts +5 -0
- package/dist/schemas/terminal.d.ts.map +1 -1
- package/dist/schemas/terminal.js +4 -0
- package/dist/schemas/terminal.js.map +1 -1
- package/dist/schemas/work-assurance.d.ts +24 -0
- package/dist/schemas/work-assurance.d.ts.map +1 -0
- package/dist/schemas/work-assurance.js +23 -0
- package/dist/schemas/work-assurance.js.map +1 -0
- package/dist/schemas/workspace/workspace-tree.d.ts +23 -0
- package/dist/schemas/workspace/workspace-tree.d.ts.map +1 -1
- package/dist/schemas/workspace/workspace-tree.js +20 -0
- package/dist/schemas/workspace/workspace-tree.js.map +1 -1
- package/dist/state/auth-state.d.ts +4 -0
- package/dist/state/auth-state.d.ts.map +1 -0
- package/dist/state/auth-state.js +37 -0
- package/dist/state/auth-state.js.map +1 -0
- package/dist/state/definition.d.ts +12 -0
- package/dist/state/definition.d.ts.map +1 -1
- package/dist/state/runtime-state.d.ts +3 -0
- package/dist/state/runtime-state.d.ts.map +1 -1
- package/dist/state/runtime-state.js +1 -0
- package/dist/state/runtime-state.js.map +1 -1
- package/dist/state/sandbox-build.d.ts +20 -0
- package/dist/state/sandbox-build.d.ts.map +1 -0
- package/dist/state/sandbox-build.js +43 -0
- package/dist/state/sandbox-build.js.map +1 -0
- package/dist/state/ways-back.d.ts +4 -0
- package/dist/state/ways-back.d.ts.map +1 -0
- package/dist/state/ways-back.js +8 -0
- package/dist/state/ways-back.js.map +1 -0
- package/dist/text/land-rows.d.ts +14 -0
- package/dist/text/land-rows.d.ts.map +1 -0
- package/dist/text/land-rows.js +86 -0
- package/dist/text/land-rows.js.map +1 -0
- package/dist/text/transcript-fold.d.ts +4 -2
- package/dist/text/transcript-fold.d.ts.map +1 -1
- package/dist/text/transcript-fold.js +21 -187
- package/dist/text/transcript-fold.js.map +1 -1
- package/dist/webext/index.d.ts +1 -0
- package/dist/webext/index.d.ts.map +1 -1
- package/dist/webext/index.js +1 -0
- package/dist/webext/index.js.map +1 -1
- package/package.json +7 -6
- package/src/contracts/agent.contract.ts +13 -1
- package/src/contracts/agents.contract.ts +53 -28
- package/src/contracts/device.contract.ts +16 -0
- package/src/contracts/endpoints.contract.ts +3 -0
- package/src/contracts/push.contract.ts +23 -1
- package/src/contracts/secrets.contract.ts +39 -0
- package/src/contracts/workspace.contract.ts +16 -0
- package/src/events/agent-events.ts +99 -79
- package/src/events/agent-transcript.ts +48 -0
- package/src/events/agent-words.ts +13 -0
- package/src/events/failure-rows.ts +148 -0
- package/src/events/requests.ts +41 -3
- package/src/events/sandbox-notice.ts +14 -2
- package/src/events/system-events.ts +14 -4
- package/src/events/transcript.ts +30 -28
- package/src/ids/conversation-ids.ts +7 -0
- package/src/ids/project-dir.test.ts +2 -2
- package/src/ids/project-dir.ts +4 -4
- package/src/ids/row-ids.ts +20 -0
- package/src/models/agent-lanes.ts +16 -24
- package/src/models/agent-runtimes.ts +2 -2
- package/src/models/agent-standing.ts +38 -95
- package/src/models/model-pins.test.ts +31 -1
- package/src/models/model-pins.ts +17 -0
- package/src/models/plan-pools.test.ts +274 -31
- package/src/models/plan-pools.ts +294 -79
- package/src/netd/generated/netd-wire.json +25 -0
- package/src/netd/generated/wire.ts +1 -1
- package/src/policy/command-classes.ts +2 -2
- package/src/policy/keyring-origins.test.ts +132 -0
- package/src/policy/keyring-origins.ts +287 -0
- package/src/policy/keyring-seal.test.ts +37 -2
- package/src/policy/keyring-seal.ts +33 -7
- package/src/policy/safety-policy.ts +1 -1
- package/src/policy/tests/safety-policy.test.ts +1 -1
- package/src/policy/turned-away.ts +15 -0
- package/src/protocol/doors/host-protocol.ts +3 -0
- package/src/protocol/doors/runner-protocol.ts +4 -1
- package/src/protocol/doors/webext-links.ts +3 -0
- package/src/protocol/peer-dial.test.ts +90 -4
- package/src/protocol/peer-dial.ts +83 -39
- package/src/protocol/raw/raw-json-routes.ts +13 -0
- package/src/protocol/raw/raw-routes.ts +13 -1
- package/src/schemas/agent-next.ts +34 -0
- package/src/schemas/agent-place.ts +22 -0
- package/src/schemas/agent-search.ts +51 -0
- package/src/schemas/agent.ts +63 -90
- package/src/schemas/agents.ts +55 -99
- package/src/schemas/attach.ts +23 -0
- package/src/schemas/command-admission.ts +57 -0
- package/src/schemas/compose-overlay.test.ts +35 -0
- package/src/schemas/compose-overlay.ts +19 -0
- package/src/schemas/composer-drafts.ts +86 -0
- package/src/schemas/conversation-links.ts +62 -0
- package/src/schemas/data-protection.ts +1 -1
- package/src/schemas/device-commands.ts +89 -0
- package/src/schemas/device-folder.ts +9 -0
- package/src/schemas/devices.ts +28 -110
- package/src/schemas/environment.ts +8 -9
- package/src/schemas/hosts.ts +60 -0
- package/src/schemas/keyring-native.test.ts +13 -0
- package/src/schemas/keyring-native.ts +101 -0
- package/src/schemas/keyring.ts +202 -4
- package/src/schemas/machine-presence.test.ts +33 -0
- package/src/schemas/phone-passwords.ts +51 -0
- package/src/schemas/privacy-egress.test.ts +83 -0
- package/src/schemas/privacy-egress.ts +86 -0
- package/src/schemas/privacy.ts +4 -0
- package/src/schemas/project-delivery.ts +1 -1
- package/src/schemas/providers/plan-limits.test.ts +16 -0
- package/src/schemas/providers/plan-limits.ts +55 -49
- package/src/schemas/providers/provider-oauth.ts +1 -13
- package/src/schemas/providers/refusals.ts +62 -0
- package/src/schemas/providers/usage.ts +2 -0
- package/src/schemas/push.ts +19 -3
- package/src/schemas/sandbox-passwords.ts +88 -0
- package/src/schemas/secrets.ts +4 -0
- package/src/schemas/sessions.ts +1 -1
- package/src/schemas/settings-savings.ts +125 -0
- package/src/schemas/settings.ts +10 -116
- package/src/schemas/system.ts +15 -0
- package/src/schemas/terminal.ts +8 -0
- package/src/schemas/work-assurance.ts +36 -0
- package/src/schemas/workspace/workspace-tree.ts +32 -0
- package/src/state/auth-state.ts +89 -0
- package/src/state/runtime-state.ts +10 -4
- package/src/state/sandbox-build.test.ts +95 -0
- package/src/state/sandbox-build.ts +96 -0
- package/src/state/ways-back.test.ts +36 -0
- package/src/state/ways-back.ts +19 -0
- package/src/state/workspace-state.ts +1 -1
- package/src/text/land-rows.ts +111 -0
- package/src/text/transcript-fold.test.ts +105 -9
- package/src/text/transcript-fold.ts +30 -232
- package/src/webext/index.ts +2 -0
- package/dist/events/undelivered.d.ts +0 -6
- package/dist/events/undelivered.d.ts.map +0 -1
- package/dist/events/undelivered.js +0 -9
- package/dist/events/undelivered.js.map +0 -1
- package/dist/state/history-state.d.ts +0 -3
- package/dist/state/history-state.d.ts.map +0 -1
- package/dist/state/history-state.js +0 -137
- package/dist/state/history-state.js.map +0 -1
- package/src/events/undelivered.ts +0 -15
- package/src/state/history-state.ts +0 -270
package/src/schemas/agent.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { TurnErrandSchema } from "./speaker.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { CONVERSATION_ID } from "../ids/conversation-ids.js";
|
|
3
|
+
import { CONVERSATION_ID, CONVERSATION_TITLE_MAX } from "../ids/conversation-ids.js";
|
|
4
4
|
import { canonicalHarness } from "../models/agent-catalog.js";
|
|
5
5
|
import { ModelRoleSchema } from "../models/model-roles.js";
|
|
6
6
|
import { NATIVE_PROVIDERS } from "../models/provider-specs.js";
|
|
7
7
|
import { AgentPlacementSchema } from "../protocol/doors/runner-protocol.js";
|
|
8
8
|
import { MENTION_LIMIT } from "../text/mentions.js";
|
|
9
9
|
import { entryId } from "./internal.js";
|
|
10
|
+
import { FRESH_OF_DESCRIPTION, FreshOfSchema, freshOfIssues } from "./conversation-links.js";
|
|
10
11
|
// Agent runtimes the daemon can serve: native providers have dedicated adapters, `endpoint/<id>` names an installed
|
|
11
12
|
// endpoint capability, anything else is an ACP agent capability id. A bare string, not an enum, so an unknown id is a
|
|
12
13
|
// clean error, not a contract change.
|
|
@@ -66,81 +67,29 @@ export const AgentOriginSchema = z.object({
|
|
|
66
67
|
author: z.string().optional(),
|
|
67
68
|
});
|
|
68
69
|
export type AgentOrigin = z.infer<typeof AgentOriginSchema>;
|
|
69
|
-
// The class of thing asking to start a session, the admission policy's key space; derived daemon-side, never sent by a
|
|
70
|
-
// client. Chat and loops are absent since both begin with the owner's own click.
|
|
71
|
-
export const WakeSourceSchema = z.enum(["schedule", "event", "listener", "webchat", "issues", "workspace", "workflow"]);
|
|
72
|
-
export type WakeSource = z.infer<typeof WakeSourceSchema>;
|
|
73
|
-
// One admission verdict the owner can configure: let it run, hold it for approval, or refuse it outright.
|
|
74
|
-
export const AdmissionRuleSchema = z.enum(["allow", "hold", "deny"]);
|
|
75
|
-
export type AdmissionRule = z.infer<typeof AdmissionRuleSchema>;
|
|
76
|
-
// Where a command would run; the same string means different things on each machine (rm -rf /usr is recoverable here,
|
|
77
|
-
// fatal on a laptop). Read with a locus (command-classes.ts CommandContext); callers must state one rather than
|
|
78
|
-
// default.
|
|
79
|
-
export const CommandLocusSchema = z.enum([
|
|
80
|
-
// This sandbox's own shell: a disposable container, /work a git worktree, /history every other agent's.
|
|
81
|
-
"sandbox",
|
|
82
|
-
// One of the owner's own computers, reached through the machine agent. Nothing here is disposable.
|
|
83
|
-
"device",
|
|
84
|
-
]);
|
|
85
|
-
export type CommandLocus = z.infer<typeof CommandLocusSchema>;
|
|
86
|
-
// What kind of thing a shell command is, the command gate's key space under the admission floor; gates one command
|
|
87
|
-
// inside an already-running session. Six classes, chosen because each is hard or impossible to undo somewhere.
|
|
88
|
-
export const CommandClassSchema = z.enum([
|
|
89
|
-
// Rewrites or discards committed work: force-push, hard reset, force-delete a branch, clean -f, filter-branch.
|
|
90
|
-
"git.destructive",
|
|
91
|
-
// Moves a checkout to another branch. Only ever matches in a tree the conversation SHARES with its owner: inside
|
|
92
|
-
// its own copy a conversation may stand where it likes, and the drift that causes is reported, not refused.
|
|
93
|
-
"git.branch-switch",
|
|
94
|
-
// Recursive-force deletion (`rm -rf`), and its spelling in a script (`fs.rm(p, { recursive: true })`).
|
|
95
|
-
"files.destructive",
|
|
96
|
-
// State nothing recovers at this locus; which roots count (/, /history in the sandbox) depends on the locus.
|
|
97
|
-
"system.destructive",
|
|
98
|
-
// A container volume or its data; the sandbox's blast radius (nested engine) differs sharply from a device's.
|
|
99
|
-
"container.state",
|
|
100
|
-
// Reads credential material: a secret reference, or a file confirmed to actually hold one.
|
|
101
|
-
"secrets.access",
|
|
102
|
-
// Publishes outward and irreversibly: npm/pnpm/yarn/cargo publish, gh release create, docker push.
|
|
103
|
-
"package.publish",
|
|
104
|
-
// A network program (curl, nc, ssh, scp, …) or interpreter one-liner aimed at a non-loopback or run-time-built
|
|
105
|
-
// destination, the general exfiltration channel under the per-provider actionRules.
|
|
106
|
-
"network.outbound",
|
|
107
|
-
]);
|
|
108
|
-
export type CommandClass = z.infer<typeof CommandClassSchema>;
|
|
109
|
-
// Workspace-wide admission floor per wake source, consulted on every outside-driven wake; composes with per-automation
|
|
110
|
-
// overrides most-restrictive-wins. `workflow` is allow|deny only, since a hold there is indistinguishable from a CI
|
|
111
|
-
// runner's timeout.
|
|
112
|
-
export const AdmissionPolicySchema = z.object({
|
|
113
|
-
schedule: AdmissionRuleSchema.default("allow"),
|
|
114
|
-
event: AdmissionRuleSchema.default("allow"),
|
|
115
|
-
listener: AdmissionRuleSchema.default("allow"),
|
|
116
|
-
webchat: AdmissionRuleSchema.default("allow"),
|
|
117
|
-
// Defaults to hold, unlike the others: a bug-report wake has full repo powers and a stranger's stack trace as its
|
|
118
|
-
// brief.
|
|
119
|
-
issues: AdmissionRuleSchema.default("hold"),
|
|
120
|
-
workspace: AdmissionRuleSchema.default("allow"),
|
|
121
|
-
workflow: z.enum(["allow", "deny"]).default("allow"),
|
|
122
|
-
});
|
|
123
|
-
export type AdmissionPolicy = z.infer<typeof AdmissionPolicySchema>;
|
|
124
70
|
// How tool calls are gated, the Claude Agent SDK's PermissionMode narrowed to the three the composer offers. Both a
|
|
125
71
|
// turn input and the payload of the `mode` frame, since the agent can move itself between them mid-turn. The SDK's
|
|
126
72
|
// acceptEdits is not one of them: only `default` asks a person here, so it would differ from bypassPermissions in name
|
|
127
73
|
// alone.
|
|
128
74
|
export const PermissionModeSchema = z.enum(["default", "plan", "bypassPermissions"]);
|
|
129
75
|
export type PermissionMode = z.infer<typeof PermissionModeSchema>;
|
|
130
|
-
//
|
|
131
|
-
|
|
132
|
-
export const ForkedFromSchema = z.object({
|
|
133
|
-
conversationId: ConversationIdSchema,
|
|
134
|
-
index: z.number().int().nonnegative(),
|
|
135
|
-
// Which files this fork opened on; kept so the fork can still say it later, not only right after the click.
|
|
136
|
-
files: z.enum(["then", "now"]),
|
|
137
|
-
});
|
|
138
|
-
export type ForkedFrom = z.infer<typeof ForkedFromSchema>;
|
|
76
|
+
// How one conversation relates to another (a fork's cut, a fresh session's origin): conversation-links.ts.
|
|
77
|
+
export * from "./conversation-links.js";
|
|
139
78
|
// The turn's fields before the cross-field refinements below, so a subset (TurnProfileSchema) can be picked from them.
|
|
140
79
|
// How many files one turn may carry. A batch of a person's queued messages joins their files, so the admission splits a
|
|
141
80
|
// batch rather than build a turn past this (turn-admission.ts, together): a turn the daemon makes must parse back.
|
|
142
81
|
export const ATTACHMENT_LIMIT = 20;
|
|
143
82
|
|
|
83
|
+
// Where a fork is cut from, as the client that cut it names it (its first turn, or a draft no turn has started yet).
|
|
84
|
+
export const ForkOfSchema = z.object({
|
|
85
|
+
conversationId: ConversationIdSchema.describe("The conversation this one was cut from."),
|
|
86
|
+
keep: z.number().int().nonnegative().describe("How many of that conversation's messages to copy in before this turn runs."),
|
|
87
|
+
files: z
|
|
88
|
+
.enum(["then", "now"])
|
|
89
|
+
.describe(
|
|
90
|
+
'Which files the fork opens on: "now" is the workspace as it stands, "then" is the files as they were at the cut, which needs a private copy.',
|
|
91
|
+
),
|
|
92
|
+
});
|
|
144
93
|
const AgentTurnFieldsSchema = z.object({
|
|
145
94
|
prompt: z.string().describe("What to say to the agent. May be empty if you are only attaching files."),
|
|
146
95
|
errand: TurnErrandSchema.optional().describe(
|
|
@@ -158,7 +107,7 @@ const AgentTurnFieldsSchema = z.object({
|
|
|
158
107
|
// Seeds a fresh registry entry's title; an existing entry's title always wins over this.
|
|
159
108
|
title: z
|
|
160
109
|
.string()
|
|
161
|
-
.max(
|
|
110
|
+
.max(CONVERSATION_TITLE_MAX)
|
|
162
111
|
.optional()
|
|
163
112
|
.describe("A title for a conversation this turn is opening. Ignored for a conversation that already has one."),
|
|
164
113
|
// Already uploaded via /workspace/upload; Claude reads them via Read, Codex gets images as native input.
|
|
@@ -250,18 +199,9 @@ const AgentTurnFieldsSchema = z.object({
|
|
|
250
199
|
// the new session from its own conversationId-keyed record.
|
|
251
200
|
// Where a fork was cut from, on its first turn only; requires conversationId, and files:"then" implies
|
|
252
201
|
// isolated.
|
|
253
|
-
forkOf:
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
keep: z.number().int().nonnegative().describe("How many of that conversation's messages to copy in before this turn runs."),
|
|
257
|
-
files: z
|
|
258
|
-
.enum(["then", "now"])
|
|
259
|
-
.describe(
|
|
260
|
-
'Which files the fork opens on: "now" is the workspace as it stands, "then" is the files as they were at the cut, which needs a private copy.',
|
|
261
|
-
),
|
|
262
|
-
})
|
|
263
|
-
.optional()
|
|
264
|
-
.describe("Where this conversation was cut from, on its first turn only. Only the client knows this, so only the client can say it."),
|
|
202
|
+
forkOf: ForkOfSchema.optional().describe("Where this conversation was cut from, on its first turn only. Only the client knows this, so only the client can say it."),
|
|
203
|
+
// A fresh session's origin, on its first turn only; requires an isolated conversationId the registry has never seen.
|
|
204
|
+
freshOf: FreshOfSchema.optional().describe(FRESH_OF_DESCRIPTION),
|
|
265
205
|
// The browser sends the chosen model per turn; the provider token is the sandbox's own stored credential.
|
|
266
206
|
model: z.string().optional().describe("Which model to use. Leave it out for the provider's default."),
|
|
267
207
|
// Audience only, never model routing: `runRole` is what fills a model in. A run somebody pressed and is
|
|
@@ -327,6 +267,15 @@ const AgentTurnFieldsSchema = z.object({
|
|
|
327
267
|
.describe(
|
|
328
268
|
"Hold this message until then (epoch milliseconds) instead of starting a turn now: a time you chose, or the reopen of an allowance you know is spent. It waits in the conversation's queue, where it can be sent early, reworded, rescheduled or removed, and goes by itself at that instant, even for a conversation this message opens or one whose turn is running now. Ignored when already past; at most a month ahead.",
|
|
329
269
|
),
|
|
270
|
+
// Why `sendAt` is the instant it is, when it is not a time somebody chose: the composer booked the message for the
|
|
271
|
+
// spent allowance's reopen. Kept with the booking (`reopenOf` on the queue), so every window can tell an allowance
|
|
272
|
+
// wait from an appointment without matching instants against whatever the usage feed says now.
|
|
273
|
+
sendAtReopen: z
|
|
274
|
+
.literal(true)
|
|
275
|
+
.optional()
|
|
276
|
+
.describe(
|
|
277
|
+
"Says `sendAt` is the reopen of the allowance this message would be refused by, not a time you chose. Recorded with the booking (the queue's `reopenOf` names the account it waits for), so every window can say the message waits on an allowance, and see when the conversation has moved somewhere with room. Only with `sendAt`.",
|
|
278
|
+
),
|
|
330
279
|
// The other scheduled send: work that builds on another agent's, held until that agent's work is in the workspace.
|
|
331
280
|
// Held in the queue like `sendAt`; the queue's `after` is this. Never both: a hold waits on exactly one thing.
|
|
332
281
|
sendAfter: ConversationIdSchema.optional().describe(
|
|
@@ -362,6 +311,7 @@ export const AgentTurnSchema = AgentTurnFieldsSchema
|
|
|
362
311
|
.refine((turn) => turn.forkOf?.files !== "then" || turn.isolated === true, {
|
|
363
312
|
message: 'forkOf.files "then" requires isolated',
|
|
364
313
|
})
|
|
314
|
+
.superRefine(freshOfIssues)
|
|
365
315
|
.refine((turn) => turn.sendAt === undefined || turn.sendAfter === undefined, {
|
|
366
316
|
message: "sendAt and sendAfter are two different holds: name one",
|
|
367
317
|
})
|
|
@@ -372,6 +322,16 @@ export type AgentTurn = z.infer<typeof AgentTurnSchema>;
|
|
|
372
322
|
// What `agent.run` takes: a turn, plus the one field only a request carries and no stored turn keeps. A daemon from before
|
|
373
323
|
// `continues` reads past it and takes `prompt` as the words, which is why a client still sends some.
|
|
374
324
|
export const AgentRunSchema = AgentTurnSchema.safeExtend({
|
|
325
|
+
// Request-only like `continues`: the draft goes in the same step that takes the message, so it is cleared exactly
|
|
326
|
+
// once, by the send itself, and a window that closes before its own clear arrives leaves no ghost of sent words.
|
|
327
|
+
draft: z
|
|
328
|
+
.number()
|
|
329
|
+
.int()
|
|
330
|
+
.positive()
|
|
331
|
+
.optional()
|
|
332
|
+
.describe(
|
|
333
|
+
"The revision of your composer draft for this conversation these words were sent from (`agents.drafts`). The sandbox clears that draft as it takes the message, unless it has been written again since. Leave it out to leave your draft as it is.",
|
|
334
|
+
),
|
|
375
335
|
continues: z
|
|
376
336
|
.literal(true)
|
|
377
337
|
.optional()
|
|
@@ -514,6 +474,25 @@ export type MessageReceipt = z.infer<typeof MessageReceiptSchema>;
|
|
|
514
474
|
// a job that ended, a land that broke something), or another agent (a child reporting back).
|
|
515
475
|
export const MessageVoiceSchema = z.enum(["person", "sandbox", "agent"]);
|
|
516
476
|
export type MessageVoice = z.infer<typeof MessageVoiceSchema>;
|
|
477
|
+
// The account a message booked for an allowance's reopen waits on: what it waits out, which the booking's instant alone
|
|
478
|
+
// cannot say once the chat has moved somewhere with room.
|
|
479
|
+
export const QueuedReopenSchema = z.object({
|
|
480
|
+
agent: AgentProviderSchema.describe("The provider whose allowance it waits out."),
|
|
481
|
+
account: z
|
|
482
|
+
.string()
|
|
483
|
+
.optional()
|
|
484
|
+
.describe("Which of its accounts. Absent when none was named, and every account of the provider read spent."),
|
|
485
|
+
});
|
|
486
|
+
export type QueuedReopen = z.infer<typeof QueuedReopenSchema>;
|
|
487
|
+
// Who a person's waiting message goes on, as its request names it now.
|
|
488
|
+
export const QueuedServingSchema = z.object({
|
|
489
|
+
agent: AgentProviderSchema.describe("The provider."),
|
|
490
|
+
harness: AgentHarnessSchema.describe("The agentic loop."),
|
|
491
|
+
model: z.string().optional().describe("The model. Absent when it named none, and takes the conversation's own."),
|
|
492
|
+
effort: z.string().optional().describe("How hard it thinks, where the model offers a choice."),
|
|
493
|
+
account: z.string().optional().describe("The account that pays for it. Absent when it named none, and goes on the conversation's own."),
|
|
494
|
+
});
|
|
495
|
+
export type QueuedServing = z.infer<typeof QueuedServingSchema>;
|
|
517
496
|
// One message waiting for the conversation's next turn, as every window shows it.
|
|
518
497
|
export const QueuedMessageSchema = z.object({
|
|
519
498
|
id: z.string().describe("The message's id: what its sender named it, or what the sandbox did."),
|
|
@@ -533,6 +512,12 @@ export const QueuedMessageSchema = z.object({
|
|
|
533
512
|
after: ConversationIdSchema.optional().describe(
|
|
534
513
|
"The conversation whose finished work must land before this message goes out by itself, in place of `until`.",
|
|
535
514
|
),
|
|
515
|
+
reopenOf: QueuedReopenSchema.optional().describe(
|
|
516
|
+
"The allowance this message's `until` waits out: it was booked for that account's reopen, by the composer or by the sandbox holding words it would not send into a spent allowance, rather than for a time somebody chose. Absent on any other booking, and from sandboxes older than the field.",
|
|
517
|
+
),
|
|
518
|
+
serves: QueuedServingSchema.optional().describe(
|
|
519
|
+
"Who serves the turn this message starts: the provider, loop, model, effort and account it was sent under, or was moved to since (`agent.queueReroute`, an account switch). Only on a person's words; the sandbox's and an agent's own go on wherever the conversation runs when they go. Absent from sandboxes older than the field.",
|
|
520
|
+
),
|
|
536
521
|
continues: z
|
|
537
522
|
.literal(true)
|
|
538
523
|
.optional()
|
|
@@ -586,15 +571,3 @@ export const QueueResumedSchema = z.object({
|
|
|
586
571
|
),
|
|
587
572
|
});
|
|
588
573
|
export type QueueResumed = z.infer<typeof QueueResumedSchema>;
|
|
589
|
-
// Attaches to a conversation's newest run (live, or finished within retention); no cursor to resume from, the head
|
|
590
|
-
// carries all rows. `run` names what the client was watching, so a newer run's head id tells it to catch up.
|
|
591
|
-
export const AttachTurnSchema = z.object({
|
|
592
|
-
conversationId: ConversationIdSchema.describe("Which conversation to watch."),
|
|
593
|
-
run: z
|
|
594
|
-
.string()
|
|
595
|
-
.optional()
|
|
596
|
-
.describe(
|
|
597
|
-
"The run you were watching. The stream opens on the conversation's newest run whatever you name: if a newer turn has started since, the head names that one instead, and its rows are that turn's.",
|
|
598
|
-
),
|
|
599
|
-
});
|
|
600
|
-
export type AttachTurn = z.infer<typeof AttachTurnSchema>;
|
package/src/schemas/agents.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
// agents: the conversation fleet
|
|
2
2
|
import { LandingDeliverySchema } from "./project-delivery.js";
|
|
3
|
+
import { AgentNextSchema } from "./agent-next.js";
|
|
3
4
|
import { z } from "zod";
|
|
4
|
-
import { AgentHarnessSchema, AgentOriginSchema, AgentProviderSchema, ConversationQueueSchema, ForkedFromSchema } from "./agent.js";
|
|
5
|
+
import { AgentHarnessSchema, AgentOriginSchema, AgentProviderSchema, ConversationQueueSchema, ForkedFromSchema, FreshSessionSchema } from "./agent.js";
|
|
5
6
|
import { LoopStateSchema } from "./loops.js";
|
|
6
7
|
import { LimitPolicySchema, RetryPolicySchema, RoomPolicySchema, TurnBreakPolicySchema, TurnBreakSchema } from "./turn-break.js";
|
|
7
8
|
import { KeepWarmSchema } from "./keep-warm.js";
|
|
8
9
|
import { AgentNeedSchema } from "./needs.js";
|
|
9
10
|
import { EMOJI_MAX_LENGTH, isSingleEmoji } from "../text/emoji.js";
|
|
10
11
|
import { ProgramAskSchema } from "../events/requests.js";
|
|
12
|
+
import { ReviewTallySchema, TurnProofSchema } from "./work-assurance.js";
|
|
11
13
|
// A fleet agent is any conversation with a registry entry, keyed by conversationId. Isolated ones own a git worktree
|
|
12
14
|
// (branch agent/<id>); workspace conversations have none, but both share one status/activity/cost lifecycle.
|
|
13
15
|
|
|
@@ -62,8 +64,7 @@ export const AgentAttentionSchema = z.object({
|
|
|
62
64
|
// A missing capability on a card from before needs (docs/architecture/needs.md); lets the lane say "setup needed" rather than a generic
|
|
63
65
|
// pause.
|
|
64
66
|
capability: z.boolean().describe("It needs something connected that is not connected yet."),
|
|
65
|
-
// A gated credential parked on a named person's click; the one pause the board's reader may not be able to clear
|
|
66
|
-
// themselves.
|
|
67
|
+
// A gated credential parked on a named person's click; the one pause the board's reader may not be able to clear themselves.
|
|
67
68
|
credential: z
|
|
68
69
|
.boolean()
|
|
69
70
|
.describe("It is waiting for a named person to release a credential. The one pause that may not be yours to clear, whatever your role."),
|
|
@@ -101,22 +102,8 @@ export const UnfinishedWorkSchema = z.object({
|
|
|
101
102
|
),
|
|
102
103
|
});
|
|
103
104
|
export type UnfinishedWork = z.infer<typeof UnfinishedWorkSchema>;
|
|
104
|
-
// What
|
|
105
|
-
|
|
106
|
-
export const TurnProofSchema = z.object({
|
|
107
|
-
at: z.number().describe("When the turn that left this ended, in milliseconds."),
|
|
108
|
-
verification: z
|
|
109
|
-
.enum(["verified", "unproven", "failing", "no-code"])
|
|
110
|
-
.describe(
|
|
111
|
-
"Verified: a check it ran passed after its last edit to code. Failing: the last one it ran failed. Unproven: it changed code and ran nothing that checked it. No-code: it changed nothing a check could speak to.",
|
|
112
|
-
),
|
|
113
|
-
check: z.string().optional().describe("The command that spoke, when one did, so a targeted test is never read as the whole suite."),
|
|
114
|
-
unviewed: z
|
|
115
|
-
.number()
|
|
116
|
-
.optional()
|
|
117
|
-
.describe("How many rendered files it changed (pages, components, styles) without looking at the result afterwards. Absent when none."),
|
|
118
|
-
});
|
|
119
|
-
export type TurnProof = z.infer<typeof TurnProofSchema>;
|
|
105
|
+
// What has looked at a conversation's work (its last turn's own checks, its latest code review): work-assurance.ts.
|
|
106
|
+
export * from "./work-assurance.js";
|
|
120
107
|
// How many entries each of a reach's lists carries; past it, the list's `…More` count says how many were left out.
|
|
121
108
|
export const TURN_REACH_LIST_MAX = 10;
|
|
122
109
|
// Where the last turn's work went when it went somewhere other than its own branch, read off what the turn touched and
|
|
@@ -175,8 +162,7 @@ export type TurnReach = z.infer<typeof TurnReachSchema>;
|
|
|
175
162
|
// A landing's commit message: subject plus the two trailer sentences a changelog repo gets. One schema, not three
|
|
176
163
|
// duplicated fields, since both the live roster and the review carrier must read the same shape and can't disagree.
|
|
177
164
|
export const LandedMessageSchema = z.object({
|
|
178
|
-
// Written from the landed diff, not the opening prompt: a session that drifts from its title still needs an
|
|
179
|
-
// accurate subject.
|
|
165
|
+
// Written from the landed diff, not the opening prompt: a session that drifts from its title still needs an accurate subject.
|
|
180
166
|
subject: z
|
|
181
167
|
.string()
|
|
182
168
|
.describe(
|
|
@@ -189,8 +175,7 @@ export const LandedMessageSchema = z.object({
|
|
|
189
175
|
.describe(
|
|
190
176
|
"The same change said to somebody who uses the product, for a repository that keeps a changelog. Usually absent, because most changes are not ones a user would notice.",
|
|
191
177
|
),
|
|
192
|
-
// Nearly always absent (removals only); required and mechanically guaranteed when a landing shrinks a wire-contract
|
|
193
|
-
// lock.
|
|
178
|
+
// Nearly always absent (removals only); required and mechanically guaranteed when a landing shrinks a wire-contract lock.
|
|
194
179
|
breaking: z
|
|
195
180
|
.string()
|
|
196
181
|
.optional()
|
|
@@ -220,8 +205,7 @@ export const LandedMessageStepSchema = z.object({
|
|
|
220
205
|
status: z
|
|
221
206
|
.enum(["asking", "answered", "refused", "skipped"])
|
|
222
207
|
.describe("How this one went. Skipped means it was not asked at all, because it refused a few minutes ago and the walk stepped over it."),
|
|
223
|
-
// Epoch ms it started; client-measures an in-flight step's ticking display. Absent for `skipped`, which cost no
|
|
224
|
-
// time.
|
|
208
|
+
// Epoch ms it started; client-measures an in-flight step's ticking display. Absent for `skipped`, which cost no time.
|
|
225
209
|
at: z.number().optional().describe("When it started being asked, in milliseconds. Absent for one that was skipped, which cost no time."),
|
|
226
210
|
ms: z.number().optional().describe("How long it took. Absent while it is still being asked."),
|
|
227
211
|
reason: z.string().optional().describe("Why it refused, in its own words."),
|
|
@@ -297,31 +281,41 @@ export const AgentSummarySchema = z.object({
|
|
|
297
281
|
status: AgentStatusSchema.describe(
|
|
298
282
|
"What it is doing. Stopping and stopped are the two halves of somebody pressing stop, because a cancel is not instant; dismissing is the same window for a question waved away, which ends the turn too but owes the user nothing; resuming means the sandbox is already putting right whatever killed the turn; landing means its work is being carried into the workspace right now, and nothing may act on its branch until that settles.",
|
|
299
283
|
),
|
|
300
|
-
// Sentence the last turn died on; carried since `error` status alone isn't an answer, especially for an unwatched
|
|
301
|
-
// run.
|
|
284
|
+
// Sentence the last turn died on; carried since `error` status alone isn't an answer, especially for an unwatched run.
|
|
302
285
|
failure: z
|
|
303
286
|
.string()
|
|
304
287
|
.optional()
|
|
305
288
|
.describe(
|
|
306
289
|
"Why the last turn failed, in the words it died on. Absent unless it did, and cleared the moment it runs again. Carried here because the word error on its own is not an answer, least of all for a run nobody was watching.",
|
|
307
290
|
),
|
|
308
|
-
// The error frame's own code, so the board can distinguish e.g. a rate limit from a crash the way chat already
|
|
309
|
-
// does.
|
|
291
|
+
// The error frame's own code, so the board can distinguish e.g. a rate limit from a crash the way chat already does.
|
|
310
292
|
failureCode: z
|
|
311
293
|
.string()
|
|
312
294
|
.optional()
|
|
313
295
|
.describe(
|
|
314
296
|
"Which kind of failure it was, as the turn's own error frame coded it. Absent for a failure nothing could classify, which reads as the plain red line it is.",
|
|
315
297
|
),
|
|
298
|
+
// Who worded `failure`, as the turn's error frame said (its `own`): a card leads with those words only when they are
|
|
299
|
+
// the sandbox's own sentence, as the chat's notice does (failureView), and with its kind's line otherwise.
|
|
300
|
+
failureOwn: z
|
|
301
|
+
.boolean()
|
|
302
|
+
.optional()
|
|
303
|
+
.describe(
|
|
304
|
+
"Whether `failure` is the sandbox's own sentence rather than the provider's or the harness's words. Absent for theirs, and for an ending recorded before it was said.",
|
|
305
|
+
),
|
|
316
306
|
// Epoch seconds the spent allowance reopens; absent means genuinely unknown (Grok, Cursor) — never guess one.
|
|
317
307
|
limitResetsAt: z.number().optional().describe("When the spent allowance reopens, in epoch seconds. Absent when the provider publishes no instant."),
|
|
318
308
|
limitHeld: z.boolean().optional().describe("Whether the refused turn is held whole, so sending again re-runs it instead of appending to it."),
|
|
319
|
-
//
|
|
320
|
-
//
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
309
|
+
// What a sandbox older than `next` (before 1.343.0) said in its place, read so the editor can derive `next` from it
|
|
310
|
+
// (agentStatus-standing.ts, withNext): the hosted editor meets such a sandbox for as long as it stays off the release
|
|
311
|
+
// that dropped them, which carried a Breaking-Note and so is never taken by itself. No sandbox sends them since.
|
|
312
|
+
limitScheduled: z.boolean().optional().describe("Sent only by sandboxes older than `next`: whether the held turn was booked to go again by itself."),
|
|
313
|
+
limitMoving: z.string().optional().describe("Sent only by sandboxes older than `next`: the account a booked move was taking the held turn to."),
|
|
314
|
+
limitNextAt: z.number().optional().describe("Sent only by sandboxes older than `next`: when the booked re-run went, in epoch seconds."),
|
|
315
|
+
// The one answer to "does it go by itself, and when" (agent-next.ts), derived from what it holds every time it is read.
|
|
316
|
+
next: AgentNextSchema.optional().describe(
|
|
317
|
+
"What carries it on next with nobody pressing anything, and when: a held turn re-run, a message held for memory, or messages booked for later. Absent when only a press moves it.",
|
|
318
|
+
),
|
|
325
319
|
provider: AgentProviderSchema.describe("Which model provider it runs on."),
|
|
326
320
|
harness: AgentHarnessSchema.describe("Which agentic loop it runs on."),
|
|
327
321
|
// Latched with the conversation, so the card can say where work runs without asking anything else.
|
|
@@ -414,6 +408,10 @@ export const AgentSummarySchema = z.object({
|
|
|
414
408
|
forkedFrom: ForkedFromSchema.optional().describe(
|
|
415
409
|
"The conversation this one was cut from. Recorded once and never cleared: it is the relationship, not a pending state.",
|
|
416
410
|
),
|
|
411
|
+
// Recorded once on a fresh session's first turn and never cleared; `startedBy` names the same origin as its parent.
|
|
412
|
+
fresh: FreshSessionSchema.optional().describe(
|
|
413
|
+
"Set on a conversation started on another conversation's work without its messages (a code review, a test pass, a person's own ask): which one, for what, and when. Absent for every other conversation.",
|
|
414
|
+
),
|
|
417
415
|
// Root repo's short base sha; per-repo bases stay daemon-internal.
|
|
418
416
|
base: z.string().optional().describe("The commit its private copy started from, shortened."),
|
|
419
417
|
costUsd: z.number().optional().describe("What it has cost so far, in dollars. A subagent's spend is its own and is not folded in here."),
|
|
@@ -484,7 +482,8 @@ export const AgentSummarySchema = z.object({
|
|
|
484
482
|
.describe(
|
|
485
483
|
"When somebody last opened it, in milliseconds. Newer activity than this is what makes it unread. Kept by the sandbox rather than by a browser, so clearing site data or picking up a phone does not resurrect every badge.",
|
|
486
484
|
),
|
|
487
|
-
//
|
|
485
|
+
// Derived from the drafts the sandbox holds (composer-drafts.ts), or reported by a client that keeps its own, so the
|
|
486
|
+
// unattended archive sweep never files away a conversation somebody is still writing to.
|
|
488
487
|
unsentAt: z
|
|
489
488
|
.number()
|
|
490
489
|
.optional()
|
|
@@ -521,10 +520,10 @@ export const AgentSummarySchema = z.object({
|
|
|
521
520
|
.describe(
|
|
522
521
|
"The last attempt to bring its work into the workspace failed, and why. Cleared by the next land that goes through. Absent when nothing failed, and from a sandbox older than it.",
|
|
523
522
|
),
|
|
524
|
-
// The land's own last word on the owner's folder, for a
|
|
523
|
+
// The land's own last word on the owner's folder, for a sandbox made for one folder: written there,
|
|
525
524
|
// partly kept out, waiting for the computer, or refused (schemas/project-delivery.ts).
|
|
526
525
|
delivery: LandingDeliverySchema.optional().describe(
|
|
527
|
-
"What became of its last land in the folder on the owner's computer, for a
|
|
526
|
+
"What became of its last land in the folder on the owner's computer, for a sandbox made for one folder. Absent for any other land, and from a sandbox older than it.",
|
|
528
527
|
),
|
|
529
528
|
// Only the causes that still hold, re-read live (conversations/land/standing.ts), never the stored report's own list: a
|
|
530
529
|
// blocker the user has since cleared is not something to offer them an action about.
|
|
@@ -543,6 +542,10 @@ export const AgentSummarySchema = z.object({
|
|
|
543
542
|
proof: TurnProofSchema.optional().describe(
|
|
544
543
|
"What its last turn showed of its work: whether a check it ran passed after its last edit, and whether it looked at interface files it changed. Absent until a turn that edited or checked anything has ended.",
|
|
545
544
|
),
|
|
545
|
+
// Written by the settle of the turn that reported a review, from its review frames; never asked of the model.
|
|
546
|
+
review: ReviewTallySchema.optional().describe(
|
|
547
|
+
"The latest code review this conversation reported: how many findings, and how many are still open. Absent until one has.",
|
|
548
|
+
),
|
|
546
549
|
// Written by the turn's own settle from its tool calls and a read of the clones and installs it could have touched;
|
|
547
550
|
// replaced by every turn, so it says where the LAST turn's work went.
|
|
548
551
|
reach: TurnReachSchema.optional().describe(
|
|
@@ -750,6 +753,19 @@ export const AgentTranscriptQuerySchema = AgentIdSchema.extend({
|
|
|
750
753
|
.optional()
|
|
751
754
|
.describe("Return the messages before this position in the record: the `from` of the page below. Absent asks for the most recent turns."),
|
|
752
755
|
turns: z.coerce.number().int().min(1).max(200).optional().describe("How many of the user's turns to return, newest first. Absent takes the daemon's default."),
|
|
756
|
+
// Reading forward from the reader's cursor, checked by the row it names: a rewind since reuses positions.
|
|
757
|
+
after: z.coerce
|
|
758
|
+
.number()
|
|
759
|
+
.int()
|
|
760
|
+
.nonnegative()
|
|
761
|
+
.optional()
|
|
762
|
+
.describe(
|
|
763
|
+
"Return what the record holds from this position on: the `through` of the reader's last page. Answered `continuous` when it still runs through there; otherwise with its latest page. Ignored beside `before`.",
|
|
764
|
+
),
|
|
765
|
+
afterRow: z
|
|
766
|
+
.string()
|
|
767
|
+
.optional()
|
|
768
|
+
.describe("The `rowId` of the row just before `after`, as the reader holds it: how a record rewound since is told apart from one that only grew."),
|
|
753
769
|
});
|
|
754
770
|
|
|
755
771
|
// Fills in what a page counted instead of carrying: a delegation's own calls, addressed by the card's id, which is
|
|
@@ -801,53 +817,6 @@ export const AgentsRemovedSchema = z.object({
|
|
|
801
817
|
),
|
|
802
818
|
});
|
|
803
819
|
export type AgentsRemoved = z.infer<typeof AgentsRemovedSchema>;
|
|
804
|
-
// Searches only speech, both sides of the conversation, never thinking, tool output or protocol text, which would
|
|
805
|
-
// otherwise match nearly the whole board. Two-char minimum; `caseSensitive` off means case-insensitive, matching
|
|
806
|
-
// workspace search's own switch.
|
|
807
|
-
export const AgentSearchQuerySchema = z.object({
|
|
808
|
-
query: z
|
|
809
|
-
.string()
|
|
810
|
-
.trim()
|
|
811
|
-
.min(2)
|
|
812
|
-
.describe(
|
|
813
|
-
"What to look for. Searched against what was said, both sides of the conversation, and nothing else: not the thinking, not the tool output, which between them name nearly every identifier in the workspace and would return most of the board.",
|
|
814
|
-
),
|
|
815
|
-
caseSensitive: z.stringbool().optional().describe("Whether capitals matter."),
|
|
816
|
-
});
|
|
817
|
-
// Why a row survived the filter: the matched line, windowed, and who said it. `speaker` rides with the text since agent
|
|
818
|
-
// prose alone can read as something the user typed.
|
|
819
|
-
export const SpeakerSchema = z.enum(["user", "agent"]);
|
|
820
|
-
export type Speaker = z.infer<typeof SpeakerSchema>;
|
|
821
|
-
export const MatchSnippetSchema = z.object({
|
|
822
|
-
text: z.string().describe("The matching line, with a little either side of it."),
|
|
823
|
-
speaker: SpeakerSchema.describe(
|
|
824
|
-
"Who said it. Carried with the words rather than beside them, because a line of the agent's prose under a card reads as something you typed until the row says otherwise.",
|
|
825
|
-
),
|
|
826
|
-
});
|
|
827
|
-
export type MatchSnippet = z.infer<typeof MatchSnippetSchema>;
|
|
828
|
-
// One matching agent and its evidence; `snippet` is absent for a title match, which the card already shows.
|
|
829
|
-
export const AgentMatchSchema = z.object({
|
|
830
|
-
id: z.string().describe("Which conversation matched."),
|
|
831
|
-
snippet: MatchSnippetSchema.optional().describe(
|
|
832
|
-
"Why, in its own words. Absent when the title was the match, which the card already shows: repeating it underneath is noise where evidence was wanted.",
|
|
833
|
-
),
|
|
834
|
-
});
|
|
835
|
-
export type AgentMatch = z.infer<typeof AgentMatchSchema>;
|
|
836
|
-
// How many agents were actually read, so the board can say a search saw less than the whole fleet.
|
|
837
|
-
export const AgentSearchResultSchema = z.object({
|
|
838
|
-
matches: z.array(AgentMatchSchema).describe("What matched, from the live fleet and the archive together."),
|
|
839
|
-
scanned: z
|
|
840
|
-
.number()
|
|
841
|
-
.describe(
|
|
842
|
-
"How many conversations were actually read, so a screen can say when a search saw less than everything rather than implying it saw all of it.",
|
|
843
|
-
),
|
|
844
|
-
indexing: z
|
|
845
|
-
.boolean()
|
|
846
|
-
.describe(
|
|
847
|
-
"Whether what was said is still being read in the background. True means this answer can still grow, so a screen must say it is incomplete rather than presenting it as the whole list.",
|
|
848
|
-
),
|
|
849
|
-
});
|
|
850
|
-
export type AgentSearchResult = z.infer<typeof AgentSearchResultSchema>;
|
|
851
820
|
// The user-chosen display title, bounded like sanitizeTitle's own cap.
|
|
852
821
|
export const AgentRenameSchema = z.object({
|
|
853
822
|
id: z.string().min(1).describe("Which conversation."),
|
|
@@ -871,19 +840,6 @@ export const AgentReactSchema = z.object({
|
|
|
871
840
|
.describe("The mark to leave, as the emoji character itself. Exactly one: a chip has room for one mark, and a press is one press."),
|
|
872
841
|
on: z.boolean().describe("Whether to add your mark or take it back. Saying what you want rather than flipping what is there, so pressing twice lands where pressing once did."),
|
|
873
842
|
});
|
|
874
|
-
// Bounded just above the handoff's per-message render cap, so a line too long to carry whole doesn't reach the agent
|
|
875
|
-
// truncated.
|
|
876
|
-
export const AgentPlaceSchema = z.object({
|
|
877
|
-
id: z.string().min(1).describe("Which conversation."),
|
|
878
|
-
text: z
|
|
879
|
-
.string()
|
|
880
|
-
.trim()
|
|
881
|
-
.min(1)
|
|
882
|
-
.max(8_000)
|
|
883
|
-
.describe(
|
|
884
|
-
"The words to put in the agent's mouth. Bounded just above what the next turn can carry whole, because a line too long to be handed over intact would reach the agent truncated and quietly break the very thing this is for.",
|
|
885
|
-
),
|
|
886
|
-
});
|
|
887
843
|
// `null` clears the override back to inheriting the sandbox setting, so an agent doesn't hold a frozen copy that stops
|
|
888
844
|
// following it.
|
|
889
845
|
export const AgentAutoLandSchema = z.object({
|
|
@@ -895,7 +851,7 @@ export const AgentAutoLandSchema = z.object({
|
|
|
895
851
|
"Whether its work merges automatically when a turn finishes. Null clears the override and goes back to following the sandbox-wide setting, so a conversation does not sit holding a frozen copy of a default it has quietly stopped following.",
|
|
896
852
|
),
|
|
897
853
|
});
|
|
898
|
-
// A composer's unsent words, reported by
|
|
854
|
+
// A composer's unsent words, reported by a client that keeps them to itself rather than writing them as a draft.
|
|
899
855
|
export const AgentUnsentSchema = z.object({
|
|
900
856
|
id: z.string().min(1).describe("Which conversation."),
|
|
901
857
|
at: z
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ConversationIdSchema } from "./agent.js";
|
|
3
|
+
|
|
4
|
+
// Attaches to a conversation's newest run (live, or finished within retention); no cursor to resume from, the head
|
|
5
|
+
// carries all rows. `run` names what the client was watching, so a newer run's head id tells it to catch up.
|
|
6
|
+
export const AttachTurnSchema = z.object({
|
|
7
|
+
conversationId: ConversationIdSchema.describe("Which conversation to watch."),
|
|
8
|
+
run: z
|
|
9
|
+
.string()
|
|
10
|
+
.optional()
|
|
11
|
+
.describe(
|
|
12
|
+
"The run you were watching. The stream opens on the conversation's newest run whatever you name: if a newer turn has started since, the head names that one instead, and its rows are that turn's.",
|
|
13
|
+
),
|
|
14
|
+
// The next run after one the reader saw end, which the conversation's queue starts a moment after: waited for here,
|
|
15
|
+
// where the start is an event, rather than looked for by a client asking again on a timer.
|
|
16
|
+
after: z
|
|
17
|
+
.string()
|
|
18
|
+
.optional()
|
|
19
|
+
.describe(
|
|
20
|
+
"A run you already watched to its end. The stream opens on the first run after it, waiting a few seconds for one to start (the message the conversation's queue sends next) before answering that nothing runs.",
|
|
21
|
+
),
|
|
22
|
+
});
|
|
23
|
+
export type AttachTurn = z.infer<typeof AttachTurnSchema>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
// The class of thing asking to start a session, the admission policy's key space; derived daemon-side, never sent by a
|
|
4
|
+
// client. Chat and loops are absent since both begin with the owner's own click.
|
|
5
|
+
export const WakeSourceSchema = z.enum(["schedule", "event", "listener", "webchat", "issues", "workspace", "workflow"]);
|
|
6
|
+
export type WakeSource = z.infer<typeof WakeSourceSchema>;
|
|
7
|
+
// One admission verdict the owner can configure: let it run, hold it for approval, or refuse it outright.
|
|
8
|
+
export const AdmissionRuleSchema = z.enum(["allow", "hold", "deny"]);
|
|
9
|
+
export type AdmissionRule = z.infer<typeof AdmissionRuleSchema>;
|
|
10
|
+
// Where a command would run; the same string means different things on each machine (rm -rf /usr is recoverable here,
|
|
11
|
+
// fatal on a laptop). Read with a locus (command-classes.ts CommandContext); callers must state one rather than
|
|
12
|
+
// default.
|
|
13
|
+
export const CommandLocusSchema = z.enum([
|
|
14
|
+
// This sandbox's own shell: a disposable container, /work a git worktree, /history every other agent's.
|
|
15
|
+
"sandbox",
|
|
16
|
+
// One of the owner's own computers, reached through the machine agent. Nothing here is disposable.
|
|
17
|
+
"device",
|
|
18
|
+
]);
|
|
19
|
+
export type CommandLocus = z.infer<typeof CommandLocusSchema>;
|
|
20
|
+
// What kind of thing a shell command is, the command gate's key space under the admission floor; gates one command
|
|
21
|
+
// inside an already-running session. Six classes, chosen because each is hard or impossible to undo somewhere.
|
|
22
|
+
export const CommandClassSchema = z.enum([
|
|
23
|
+
// Rewrites or discards committed work: force-push, hard reset, force-delete a branch, clean -f, filter-branch.
|
|
24
|
+
"git.destructive",
|
|
25
|
+
// Moves a checkout to another branch. Only ever matches in a tree the conversation SHARES with its owner: inside
|
|
26
|
+
// its own copy a conversation may stand where it likes, and the drift that causes is reported, not refused.
|
|
27
|
+
"git.branch-switch",
|
|
28
|
+
// Recursive-force deletion (`rm -rf`), and its spelling in a script (`fs.rm(p, { recursive: true })`).
|
|
29
|
+
"files.destructive",
|
|
30
|
+
// State nothing recovers at this locus; which roots count (/, /history in the sandbox) depends on the locus.
|
|
31
|
+
"system.destructive",
|
|
32
|
+
// A container volume or its data; the sandbox's blast radius (nested engine) differs sharply from a device's.
|
|
33
|
+
"container.state",
|
|
34
|
+
// Reads credential material: a secret reference, or a file confirmed to actually hold one.
|
|
35
|
+
"secrets.access",
|
|
36
|
+
// Publishes outward and irreversibly: npm/pnpm/yarn/cargo publish, gh release create, docker push.
|
|
37
|
+
"package.publish",
|
|
38
|
+
// A network program (curl, nc, ssh, scp, …) or interpreter one-liner aimed at a non-loopback or run-time-built
|
|
39
|
+
// destination, the general exfiltration channel under the per-provider actionRules.
|
|
40
|
+
"network.outbound",
|
|
41
|
+
]);
|
|
42
|
+
export type CommandClass = z.infer<typeof CommandClassSchema>;
|
|
43
|
+
// Workspace-wide admission floor per wake source, consulted on every outside-driven wake; composes with per-automation
|
|
44
|
+
// overrides most-restrictive-wins. `workflow` is allow|deny only, since a hold there is indistinguishable from a CI
|
|
45
|
+
// runner's timeout.
|
|
46
|
+
export const AdmissionPolicySchema = z.object({
|
|
47
|
+
schedule: AdmissionRuleSchema.default("allow"),
|
|
48
|
+
event: AdmissionRuleSchema.default("allow"),
|
|
49
|
+
listener: AdmissionRuleSchema.default("allow"),
|
|
50
|
+
webchat: AdmissionRuleSchema.default("allow"),
|
|
51
|
+
// Defaults to hold, unlike the others: a bug-report wake has full repo powers and a stranger's stack trace as its
|
|
52
|
+
// brief.
|
|
53
|
+
issues: AdmissionRuleSchema.default("hold"),
|
|
54
|
+
workspace: AdmissionRuleSchema.default("allow"),
|
|
55
|
+
workflow: z.enum(["allow", "deny"]).default("allow"),
|
|
56
|
+
});
|
|
57
|
+
export type AdmissionPolicy = z.infer<typeof AdmissionPolicySchema>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { packageRoot } from "@intentic/constants/node";
|
|
5
|
+
import { ComposedOverlayLineSchema } from "./compose-overlay.js";
|
|
6
|
+
|
|
7
|
+
// The lines a target image's composer prints, as examples: golden/compose-overlay.json, which ic's reader is held to
|
|
8
|
+
// (_sandbox/ic/src/sandbox/composition.rs). This is the TS half: each is a line the contract reads, its hash its overlay's.
|
|
9
|
+
|
|
10
|
+
interface ComposeCase {
|
|
11
|
+
readonly name: string;
|
|
12
|
+
readonly base: string;
|
|
13
|
+
readonly line: unknown;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// SAFETY: the golden is this package's own file; the assertions below fail on any field it lacks.
|
|
17
|
+
const GOLDEN = JSON.parse(readFileSync(join(packageRoot(import.meta.url), "golden", "compose-overlay.json"), "utf8")) as { readonly cases: readonly ComposeCase[] };
|
|
18
|
+
|
|
19
|
+
test("every golden line is a composer's line, its hash the overlay's own and its FROM the base it was asked for", () => {
|
|
20
|
+
expect(GOLDEN.cases.length).toBeGreaterThan(2);
|
|
21
|
+
for (const { base, line } of GOLDEN.cases) {
|
|
22
|
+
const read = ComposedOverlayLineSchema.parse(line);
|
|
23
|
+
expect(line).toEqual(read);
|
|
24
|
+
if (read.overlay === null) {
|
|
25
|
+
expect(read.hash).toBeUndefined();
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
expect(read.hash).toBe(createHash("sha256").update(read.overlay).digest("hex"));
|
|
29
|
+
expect(read.overlay).toContain(`\nFROM ${base}\n`);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test("a line in another format is not one this contract reads", () => {
|
|
34
|
+
expect(ComposedOverlayLineSchema.safeParse({ compose: 2, overlay: null }).success).toBe(false);
|
|
35
|
+
});
|