@intentic/sandbox-contract 1.248.0 → 1.249.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 +18 -15
- package/dist/chores/chores.d.ts.map +1 -1
- package/dist/chores/chores.js.map +1 -1
- package/dist/chores/digest.d.ts.map +1 -1
- package/dist/chores/digest.js.map +1 -1
- package/dist/chores/extension-update.d.ts.map +1 -1
- package/dist/chores/extension-update.js.map +1 -1
- package/dist/chores/fix-deps.d.ts.map +1 -1
- package/dist/chores/fix-deps.js.map +1 -1
- package/dist/chores/index.d.ts +2 -2
- package/dist/chores/index.d.ts.map +1 -1
- package/dist/chores/index.js +1 -1
- package/dist/chores/index.js.map +1 -1
- package/dist/chores/probes.d.ts.map +1 -1
- package/dist/chores/probes.js.map +1 -1
- package/dist/chores/prompt.d.ts.map +1 -1
- package/dist/chores/prompt.js.map +1 -1
- package/dist/chores/stack.d.ts.map +1 -1
- package/dist/chores/stack.js.map +1 -1
- package/dist/chores/verdict.d.ts +7 -1
- package/dist/chores/verdict.d.ts.map +1 -1
- package/dist/chores/verdict.js +8 -0
- package/dist/chores/verdict.js.map +1 -1
- package/dist/contracts/accounts.contract.d.ts.map +1 -1
- package/dist/contracts/accounts.contract.js.map +1 -1
- package/dist/contracts/activity.contract.d.ts +1 -0
- package/dist/contracts/activity.contract.d.ts.map +1 -1
- package/dist/contracts/agent.contract.d.ts +12 -205
- package/dist/contracts/agent.contract.d.ts.map +1 -1
- package/dist/contracts/agent.contract.js +2 -1
- package/dist/contracts/agent.contract.js.map +1 -1
- package/dist/contracts/agents.contract.d.ts +228 -54
- package/dist/contracts/agents.contract.d.ts.map +1 -1
- package/dist/contracts/agents.contract.js +11 -2
- package/dist/contracts/agents.contract.js.map +1 -1
- package/dist/contracts/automations.contract.d.ts +35 -17
- package/dist/contracts/automations.contract.d.ts.map +1 -1
- package/dist/contracts/automations.contract.js +10 -1
- package/dist/contracts/automations.contract.js.map +1 -1
- package/dist/contracts/capabilities.contract.d.ts +0 -12
- package/dist/contracts/capabilities.contract.d.ts.map +1 -1
- package/dist/contracts/capabilities.contract.js +1 -1
- package/dist/contracts/capabilities.contract.js.map +1 -1
- package/dist/contracts/chores.contract.d.ts.map +1 -1
- package/dist/contracts/chores.contract.js.map +1 -1
- package/dist/contracts/ci.contract.d.ts +9 -0
- package/dist/contracts/ci.contract.d.ts.map +1 -1
- package/dist/contracts/endpoints.contract.d.ts.map +1 -1
- package/dist/contracts/endpoints.contract.js.map +1 -1
- package/dist/contracts/exit.contract.d.ts.map +1 -1
- package/dist/contracts/exit.contract.js +1 -1
- package/dist/contracts/exit.contract.js.map +1 -1
- package/dist/contracts/extensions.contract.d.ts.map +1 -1
- package/dist/contracts/extensions.contract.js.map +1 -1
- package/dist/contracts/git.contract.d.ts +45 -6
- package/dist/contracts/git.contract.d.ts.map +1 -1
- package/dist/contracts/git.contract.js +9 -9
- package/dist/contracts/git.contract.js.map +1 -1
- package/dist/contracts/host.contract.d.ts +2 -0
- package/dist/contracts/host.contract.d.ts.map +1 -1
- package/dist/contracts/host.contract.js.map +1 -1
- package/dist/contracts/intentic.contract.js +1 -1
- package/dist/contracts/intentic.contract.js.map +1 -1
- package/dist/contracts/logs.contract.d.ts.map +1 -1
- package/dist/contracts/logs.contract.js.map +1 -1
- package/dist/contracts/loops.contract.d.ts.map +1 -1
- package/dist/contracts/loops.contract.js.map +1 -1
- package/dist/contracts/personas.contract.d.ts +1 -0
- package/dist/contracts/personas.contract.d.ts.map +1 -1
- package/dist/contracts/personas.contract.js +1 -1
- package/dist/contracts/personas.contract.js.map +1 -1
- package/dist/contracts/providers.contract.d.ts.map +1 -1
- package/dist/contracts/providers.contract.js.map +1 -1
- package/dist/contracts/runner.contract.d.ts +97 -171
- package/dist/contracts/runner.contract.d.ts.map +1 -1
- package/dist/contracts/runner.contract.js +2 -2
- package/dist/contracts/runner.contract.js.map +1 -1
- package/dist/contracts/safety.contract.d.ts.map +1 -1
- package/dist/contracts/safety.contract.js +1 -1
- package/dist/contracts/safety.contract.js.map +1 -1
- package/dist/contracts/secrets.contract.d.ts.map +1 -1
- package/dist/contracts/secrets.contract.js.map +1 -1
- package/dist/contracts/sessions.contract.d.ts +2 -41
- package/dist/contracts/sessions.contract.d.ts.map +1 -1
- package/dist/contracts/sessions.contract.js +1 -1
- package/dist/contracts/sessions.contract.js.map +1 -1
- package/dist/contracts/settings.contract.d.ts +8 -18
- package/dist/contracts/settings.contract.d.ts.map +1 -1
- package/dist/contracts/settings.contract.js.map +1 -1
- package/dist/contracts/share.contract.d.ts.map +1 -1
- package/dist/contracts/share.contract.js.map +1 -1
- package/dist/contracts/skills.contract.d.ts.map +1 -1
- package/dist/contracts/skills.contract.js.map +1 -1
- package/dist/contracts/system.contract.d.ts +49 -73
- package/dist/contracts/system.contract.d.ts.map +1 -1
- package/dist/contracts/system.contract.js +12 -2
- package/dist/contracts/system.contract.js.map +1 -1
- package/dist/contracts/usage.contract.d.ts.map +1 -1
- package/dist/contracts/usage.contract.js.map +1 -1
- package/dist/contracts/vpn.contract.d.ts.map +1 -1
- package/dist/contracts/vpn.contract.js +1 -1
- package/dist/contracts/vpn.contract.js.map +1 -1
- package/dist/contracts/webext.contract.d.ts.map +1 -1
- package/dist/contracts/webext.contract.js.map +1 -1
- package/dist/contracts/workflows.contract.d.ts +7 -6
- package/dist/contracts/workflows.contract.d.ts.map +1 -1
- package/dist/contracts/workflows.contract.js +12 -3
- package/dist/contracts/workflows.contract.js.map +1 -1
- package/dist/contracts/workspace.contract.d.ts.map +1 -1
- package/dist/contracts/workspace.contract.js.map +1 -1
- package/dist/events/agent-events.d.ts +1237 -0
- package/dist/events/agent-events.d.ts.map +1 -0
- package/dist/events/agent-events.js +226 -0
- package/dist/events/agent-events.js.map +1 -0
- package/dist/events/cards.d.ts +404 -0
- package/dist/events/cards.d.ts.map +1 -0
- package/dist/events/cards.js +179 -0
- package/dist/events/cards.js.map +1 -0
- package/dist/events/resume.d.ts +23 -0
- package/dist/events/resume.d.ts.map +1 -0
- package/dist/events/resume.js +31 -0
- package/dist/events/resume.js.map +1 -0
- package/dist/events/system-events.d.ts +615 -0
- package/dist/events/system-events.d.ts.map +1 -0
- package/dist/events/system-events.js +64 -0
- package/dist/events/system-events.js.map +1 -0
- package/dist/events/transcript.d.ts +1755 -0
- package/dist/events/transcript.d.ts.map +1 -0
- package/dist/events/transcript.js +205 -0
- package/dist/events/transcript.js.map +1 -0
- package/dist/ids/conversation-ids.d.ts +8 -0
- package/dist/ids/conversation-ids.d.ts.map +1 -0
- package/dist/{conversation-ids.js → ids/conversation-ids.js} +13 -0
- package/dist/ids/conversation-ids.js.map +1 -0
- package/dist/ids/hostnames.d.ts.map +1 -0
- package/dist/ids/hostnames.js.map +1 -0
- package/dist/ids/session-names.d.ts.map +1 -0
- package/dist/ids/session-names.js.map +1 -0
- package/dist/ids/share-paths.d.ts.map +1 -0
- package/dist/ids/share-paths.js.map +1 -0
- package/dist/{tunnel-ids.d.ts → ids/tunnel-ids.d.ts} +1 -0
- package/dist/ids/tunnel-ids.d.ts.map +1 -0
- package/dist/{tunnel-ids.js → ids/tunnel-ids.js} +1 -0
- package/dist/ids/tunnel-ids.js.map +1 -0
- package/dist/index.d.ts +423 -450
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +54 -46
- package/dist/index.js.map +1 -1
- package/dist/{agent-catalog.d.ts → models/agent-catalog.d.ts} +2 -2
- package/dist/models/agent-catalog.d.ts.map +1 -0
- package/dist/models/agent-catalog.js.map +1 -0
- package/dist/models/agent-runtimes.d.ts.map +1 -0
- package/dist/models/agent-runtimes.js.map +1 -0
- package/dist/{fast-tier.d.ts → models/fast-tier.d.ts} +1 -1
- package/dist/models/fast-tier.d.ts.map +1 -0
- package/dist/models/fast-tier.js.map +1 -0
- package/dist/models/model-order.d.ts.map +1 -0
- package/dist/models/model-order.js.map +1 -0
- package/dist/{model-pins.d.ts → models/model-pins.d.ts} +1 -1
- package/dist/models/model-pins.d.ts.map +1 -0
- package/dist/models/model-pins.js.map +1 -0
- package/dist/{model-roles.d.ts → models/model-roles.d.ts} +0 -33
- package/dist/models/model-roles.d.ts.map +1 -0
- package/dist/{model-roles.js → models/model-roles.js} +0 -35
- package/dist/models/model-roles.js.map +1 -0
- package/dist/{plan-pools.d.ts → models/plan-pools.d.ts} +1 -1
- package/dist/models/plan-pools.d.ts.map +1 -0
- package/dist/models/plan-pools.js.map +1 -0
- package/dist/models/prompt-complexity.d.ts.map +1 -0
- package/dist/models/prompt-complexity.js.map +1 -0
- package/dist/models/provider-specs.d.ts.map +1 -0
- package/dist/models/provider-specs.js.map +1 -0
- package/dist/policy/approvals-execution.d.ts.map +1 -0
- package/dist/policy/approvals-execution.js.map +1 -0
- package/dist/{batch-runs.d.ts → policy/batch-runs.d.ts} +5 -1
- package/dist/policy/batch-runs.d.ts.map +1 -0
- package/dist/{batch-runs.js → policy/batch-runs.js} +10 -7
- package/dist/policy/batch-runs.js.map +1 -0
- package/dist/policy/capability-env.d.ts.map +1 -0
- package/dist/policy/capability-env.js.map +1 -0
- package/dist/policy/capability-secrets.d.ts.map +1 -0
- package/dist/policy/capability-secrets.js.map +1 -0
- package/dist/{card-status.d.ts → policy/card-status.d.ts} +2 -2
- package/dist/policy/card-status.d.ts.map +1 -0
- package/dist/{card-status.js → policy/card-status.js} +1 -5
- package/dist/policy/card-status.js.map +1 -0
- package/dist/{command-classes.d.ts → policy/command-classes.d.ts} +6 -2
- package/dist/policy/command-classes.d.ts.map +1 -0
- package/dist/{command-classes.js → policy/command-classes.js} +48 -11
- package/dist/policy/command-classes.js.map +1 -0
- package/dist/{command-run.d.ts → policy/command-run.d.ts} +1 -1
- package/dist/policy/command-run.d.ts.map +1 -0
- package/dist/policy/command-run.js.map +1 -0
- package/dist/policy/control-scopes.d.ts +16 -0
- package/dist/policy/control-scopes.d.ts.map +1 -0
- package/dist/policy/control-scopes.js +26 -0
- package/dist/policy/control-scopes.js.map +1 -0
- package/dist/policy/credential-material.d.ts.map +1 -0
- package/dist/policy/credential-material.js.map +1 -0
- package/dist/policy/needs-action.d.ts.map +1 -0
- package/dist/policy/needs-action.js.map +1 -0
- package/dist/policy/output-fields.d.ts.map +1 -0
- package/dist/policy/output-fields.js.map +1 -0
- package/dist/policy/overlay-lint.d.ts.map +1 -0
- package/dist/policy/overlay-lint.js.map +1 -0
- package/dist/policy/owner-ticket.d.ts.map +1 -0
- package/dist/{owner-ticket.js → policy/owner-ticket.js} +1 -1
- package/dist/policy/owner-ticket.js.map +1 -0
- package/dist/{safety-policy.d.ts → policy/safety-policy.d.ts} +6 -5
- package/dist/policy/safety-policy.d.ts.map +1 -0
- package/dist/{safety-policy.js → policy/safety-policy.js} +12 -12
- package/dist/policy/safety-policy.js.map +1 -0
- package/dist/policy/search-globs.d.ts.map +1 -0
- package/dist/policy/search-globs.js.map +1 -0
- package/dist/protocol/container-requirements.d.ts +20 -0
- package/dist/protocol/container-requirements.d.ts.map +1 -0
- package/dist/protocol/container-requirements.js +23 -0
- package/dist/protocol/container-requirements.js.map +1 -0
- package/dist/{host-protocol.d.ts → protocol/host-protocol.d.ts} +1 -0
- package/dist/protocol/host-protocol.d.ts.map +1 -0
- package/dist/{host-protocol.js → protocol/host-protocol.js} +1 -0
- package/dist/protocol/host-protocol.js.map +1 -0
- package/dist/protocol/ingress-contract.d.ts.map +1 -0
- package/dist/{ingress-contract.js → protocol/ingress-contract.js} +1 -1
- package/dist/protocol/ingress-contract.js.map +1 -0
- package/dist/protocol/ingress-protocol.d.ts.map +1 -0
- package/dist/protocol/ingress-protocol.js.map +1 -0
- package/dist/protocol/listener-protocol.d.ts.map +1 -0
- package/dist/{listener-protocol.js → protocol/listener-protocol.js} +1 -1
- package/dist/protocol/listener-protocol.js.map +1 -0
- package/dist/{peer-dial.d.ts → protocol/peer-dial.d.ts} +4 -1
- package/dist/protocol/peer-dial.d.ts.map +1 -0
- package/dist/{peer-dial.js → protocol/peer-dial.js} +51 -10
- package/dist/protocol/peer-dial.js.map +1 -0
- package/dist/protocol/peer-mcp-server.d.ts.map +1 -0
- package/dist/protocol/peer-mcp-server.js.map +1 -0
- package/dist/protocol/request-id.d.ts.map +1 -0
- package/dist/protocol/request-id.js.map +1 -0
- package/dist/protocol/routes.d.ts.map +1 -0
- package/dist/protocol/routes.js.map +1 -0
- package/dist/{runner-protocol.d.ts → protocol/runner-protocol.d.ts} +1 -0
- package/dist/protocol/runner-protocol.d.ts.map +1 -0
- package/dist/{runner-protocol.js → protocol/runner-protocol.js} +2 -1
- package/dist/protocol/runner-protocol.js.map +1 -0
- package/dist/protocol/sse.d.ts.map +1 -0
- package/dist/protocol/sse.js.map +1 -0
- package/dist/{terminal-protocol.d.ts → protocol/terminal-protocol.d.ts} +1 -3
- package/dist/protocol/terminal-protocol.d.ts.map +1 -0
- package/dist/protocol/terminal-protocol.js.map +1 -0
- package/dist/protocol/webext-links.d.ts.map +1 -0
- package/dist/protocol/webext-links.js.map +1 -0
- package/dist/{webext-protocol.d.ts → protocol/webext-protocol.d.ts} +1 -0
- package/dist/protocol/webext-protocol.d.ts.map +1 -0
- package/dist/{webext-protocol.js → protocol/webext-protocol.js} +1 -0
- package/dist/protocol/webext-protocol.js.map +1 -0
- package/dist/schemas/activity.d.ts +2 -0
- package/dist/schemas/activity.d.ts.map +1 -1
- package/dist/schemas/activity.js +4 -0
- package/dist/schemas/activity.js.map +1 -1
- package/dist/schemas/agent.d.ts +16 -4
- package/dist/schemas/agent.d.ts.map +1 -1
- package/dist/schemas/agent.js +21 -4
- package/dist/schemas/agent.js.map +1 -1
- package/dist/schemas/agents.d.ts +17 -4
- package/dist/schemas/agents.d.ts.map +1 -1
- package/dist/schemas/agents.js +15 -4
- package/dist/schemas/agents.js.map +1 -1
- package/dist/schemas/approvals.d.ts.map +1 -1
- package/dist/schemas/approvals.js.map +1 -1
- package/dist/schemas/automations.d.ts +54 -28
- package/dist/schemas/automations.d.ts.map +1 -1
- package/dist/schemas/automations.js +26 -8
- package/dist/schemas/automations.js.map +1 -1
- package/dist/schemas/capabilities.d.ts +0 -8
- package/dist/schemas/capabilities.d.ts.map +1 -1
- package/dist/schemas/capabilities.js +0 -4
- package/dist/schemas/capabilities.js.map +1 -1
- package/dist/schemas/ci.d.ts +10 -0
- package/dist/schemas/ci.d.ts.map +1 -1
- package/dist/schemas/ci.js +9 -1
- package/dist/schemas/ci.js.map +1 -1
- package/dist/schemas/codebase-health.d.ts.map +1 -1
- package/dist/schemas/codebase-health.js.map +1 -1
- package/dist/schemas/devices.d.ts +90 -0
- package/dist/schemas/devices.d.ts.map +1 -1
- package/dist/schemas/devices.js +10 -1
- package/dist/schemas/devices.js.map +1 -1
- package/dist/schemas/engines.d.ts.map +1 -1
- package/dist/schemas/engines.js.map +1 -1
- package/dist/schemas/environment.d.ts.map +1 -1
- package/dist/schemas/environment.js.map +1 -1
- package/dist/schemas/exit.d.ts.map +1 -1
- package/dist/schemas/exit.js.map +1 -1
- package/dist/schemas/extension-updates.d.ts.map +1 -1
- package/dist/schemas/extension-updates.js.map +1 -1
- package/dist/schemas/git-history.d.ts.map +1 -1
- package/dist/schemas/git-history.js.map +1 -1
- package/dist/schemas/git.d.ts +80 -16
- package/dist/schemas/git.d.ts.map +1 -1
- package/dist/schemas/git.js +37 -25
- package/dist/schemas/git.js.map +1 -1
- package/dist/schemas/history.d.ts.map +1 -1
- package/dist/schemas/history.js.map +1 -1
- package/dist/schemas/hosts.d.ts.map +1 -1
- package/dist/schemas/hosts.js.map +1 -1
- package/dist/schemas/inventory.d.ts.map +1 -1
- package/dist/schemas/inventory.js.map +1 -1
- package/dist/schemas/issues.d.ts +0 -1
- package/dist/schemas/issues.d.ts.map +1 -1
- package/dist/schemas/issues.js +0 -1
- package/dist/schemas/issues.js.map +1 -1
- package/dist/schemas/logs.d.ts.map +1 -1
- package/dist/schemas/logs.js.map +1 -1
- package/dist/schemas/loops.d.ts.map +1 -1
- package/dist/schemas/loops.js +1 -1
- package/dist/schemas/loops.js.map +1 -1
- package/dist/schemas/maintenance.d.ts.map +1 -1
- package/dist/schemas/maintenance.js.map +1 -1
- package/dist/schemas/marketplace.d.ts +0 -4
- package/dist/schemas/marketplace.d.ts.map +1 -1
- package/dist/schemas/panels.d.ts.map +1 -1
- package/dist/schemas/panels.js.map +1 -1
- package/dist/schemas/personas.d.ts +2 -1
- package/dist/schemas/personas.d.ts.map +1 -1
- package/dist/schemas/personas.js +6 -2
- package/dist/schemas/personas.js.map +1 -1
- package/dist/schemas/plan-limits.d.ts +2 -4
- package/dist/schemas/plan-limits.d.ts.map +1 -1
- package/dist/schemas/plan-limits.js +5 -8
- package/dist/schemas/plan-limits.js.map +1 -1
- package/dist/schemas/ports.d.ts.map +1 -1
- package/dist/schemas/ports.js.map +1 -1
- package/dist/schemas/provider-oauth.d.ts.map +1 -1
- package/dist/schemas/provider-oauth.js.map +1 -1
- package/dist/schemas/provider-subscriptions.d.ts +1 -1
- package/dist/schemas/provider-subscriptions.d.ts.map +1 -1
- package/dist/schemas/provider-subscriptions.js +1 -1
- package/dist/schemas/provider-subscriptions.js.map +1 -1
- package/dist/schemas/public.d.ts.map +1 -1
- package/dist/schemas/public.js.map +1 -1
- package/dist/schemas/push.d.ts.map +1 -1
- package/dist/schemas/push.js.map +1 -1
- package/dist/schemas/secrets.d.ts.map +1 -1
- package/dist/schemas/secrets.js.map +1 -1
- package/dist/schemas/settings.d.ts +6 -9
- package/dist/schemas/settings.d.ts.map +1 -1
- package/dist/schemas/settings.js +16 -5
- package/dist/schemas/settings.js.map +1 -1
- package/dist/schemas/share.d.ts.map +1 -1
- package/dist/schemas/share.js.map +1 -1
- package/dist/schemas/shared.d.ts +4 -0
- package/dist/schemas/shared.d.ts.map +1 -1
- package/dist/schemas/shared.js +3 -0
- package/dist/schemas/shared.js.map +1 -1
- package/dist/schemas/system.d.ts +6 -0
- package/dist/schemas/system.d.ts.map +1 -1
- package/dist/schemas/system.js +10 -0
- package/dist/schemas/system.js.map +1 -1
- package/dist/schemas/terminal.d.ts.map +1 -1
- package/dist/schemas/terminal.js.map +1 -1
- package/dist/schemas/usage.d.ts.map +1 -1
- package/dist/schemas/usage.js.map +1 -1
- package/dist/schemas/vpn.d.ts.map +1 -1
- package/dist/schemas/vpn.js.map +1 -1
- package/dist/schemas/webext.d.ts.map +1 -1
- package/dist/schemas/webext.js.map +1 -1
- package/dist/schemas/workflows.d.ts +66 -9
- package/dist/schemas/workflows.d.ts.map +1 -1
- package/dist/schemas/workflows.js +6 -5
- package/dist/schemas/workflows.js.map +1 -1
- package/dist/schemas/workspace-repos.d.ts.map +1 -1
- package/dist/schemas/workspace-repos.js.map +1 -1
- package/dist/schemas/workspace-search.d.ts.map +1 -1
- package/dist/schemas/workspace-search.js.map +1 -1
- package/dist/schemas/workspace-setup.d.ts.map +1 -1
- package/dist/schemas/workspace-setup.js.map +1 -1
- package/dist/schemas/workspace-tree.d.ts.map +1 -1
- package/dist/schemas/workspace-tree.js.map +1 -1
- package/dist/state/arrival.d.ts.map +1 -0
- package/dist/{arrival.js → state/arrival.js} +1 -1
- package/dist/state/arrival.js.map +1 -0
- package/dist/state/contract-lock.d.ts.map +1 -0
- package/dist/{contract-lock.js → state/contract-lock.js} +1 -1
- package/dist/state/contract-lock.js.map +1 -0
- package/dist/{definition.d.ts → state/definition.d.ts} +21 -17
- package/dist/state/definition.d.ts.map +1 -0
- package/dist/{definition.js → state/definition.js} +4 -4
- package/dist/state/definition.js.map +1 -0
- package/dist/state/history-state.d.ts.map +1 -0
- package/dist/{history-state.js → state/history-state.js} +1 -0
- package/dist/state/history-state.js.map +1 -0
- package/dist/state/runtime-state.d.ts.map +1 -0
- package/dist/state/runtime-state.js.map +1 -0
- package/dist/state/starter.d.ts.map +1 -0
- package/dist/state/starter.js.map +1 -0
- package/dist/state/state-portability.d.ts.map +1 -0
- package/dist/state/state-portability.js.map +1 -0
- package/dist/state/versions.d.ts.map +1 -0
- package/dist/state/versions.js.map +1 -0
- package/dist/{workspace-state.d.ts → state/workspace-state.d.ts} +8 -0
- package/dist/state/workspace-state.d.ts.map +1 -0
- package/dist/{workspace-state.js → state/workspace-state.js} +25 -0
- package/dist/state/workspace-state.js.map +1 -0
- package/dist/{documents.d.ts → text/documents.d.ts} +1 -1
- package/dist/text/documents.d.ts.map +1 -0
- package/dist/{documents.js → text/documents.js} +1 -1
- package/dist/text/documents.js.map +1 -0
- package/dist/text/embed.d.ts.map +1 -0
- package/dist/text/embed.js.map +1 -0
- package/dist/text/mentions.d.ts.map +1 -0
- package/dist/text/mentions.js.map +1 -0
- package/dist/text/model-answer.d.ts +3 -0
- package/dist/text/model-answer.d.ts.map +1 -0
- package/dist/text/model-answer.js +3 -0
- package/dist/text/model-answer.js.map +1 -0
- package/dist/text/path-refs.d.ts.map +1 -0
- package/dist/text/path-refs.js.map +1 -0
- package/dist/{shell-regions.d.ts → text/shell-regions.d.ts} +1 -1
- package/dist/text/shell-regions.d.ts.map +1 -0
- package/dist/text/shell-regions.js.map +1 -0
- package/dist/text/title.d.ts.map +1 -0
- package/dist/text/title.js.map +1 -0
- package/dist/{transcript-fold.d.ts → text/transcript-fold.d.ts} +2 -1
- package/dist/text/transcript-fold.d.ts.map +1 -0
- package/dist/{transcript-fold.js → text/transcript-fold.js} +2 -16
- package/dist/text/transcript-fold.js.map +1 -0
- package/dist/text/whisper.d.ts +3 -0
- package/dist/text/whisper.d.ts.map +1 -0
- package/dist/text/whisper.js +11 -0
- package/dist/text/whisper.js.map +1 -0
- package/dist/{workflow-faults.d.ts → text/workflow-faults.d.ts} +1 -1
- package/dist/text/workflow-faults.d.ts.map +1 -0
- package/dist/{workflow-faults.js → text/workflow-faults.js} +1 -1
- package/dist/text/workflow-faults.js.map +1 -0
- package/package.json +70 -70
- package/src/chores/chores.test.ts +4 -10
- package/src/chores/chores.ts +148 -392
- package/src/chores/digest.ts +8 -28
- package/src/chores/extension-update.ts +3 -8
- package/src/chores/fix-deps.ts +4 -18
- package/src/chores/index.ts +2 -2
- package/src/chores/probes.test.ts +7 -43
- package/src/chores/probes.ts +62 -167
- package/src/chores/prompt.ts +10 -34
- package/src/chores/stack.test.ts +6 -45
- package/src/chores/stack.ts +27 -118
- package/src/chores/verdict.test.ts +101 -80
- package/src/chores/verdict.ts +54 -99
- package/src/contracts/accounts.contract.ts +4 -19
- package/src/contracts/agent.contract.ts +7 -22
- package/src/contracts/agents.contract.ts +25 -71
- package/src/contracts/automations.contract.ts +14 -30
- package/src/contracts/capabilities.contract.ts +8 -35
- package/src/contracts/chores.contract.ts +4 -15
- package/src/contracts/endpoints.contract.ts +5 -22
- package/src/contracts/exit.contract.ts +7 -30
- package/src/contracts/extensions.contract.ts +8 -30
- package/src/contracts/git.contract.ts +25 -49
- package/src/contracts/host.contract.ts +9 -44
- package/src/contracts/intentic.contract.ts +1 -1
- package/src/contracts/logs.contract.ts +3 -13
- package/src/contracts/loops.contract.ts +9 -40
- package/src/contracts/personas.contract.ts +10 -35
- package/src/contracts/providers.contract.ts +4 -17
- package/src/contracts/runner.contract.ts +12 -39
- package/src/contracts/safety.contract.ts +5 -14
- package/src/contracts/secrets.contract.ts +4 -22
- package/src/contracts/sessions.contract.ts +1 -1
- package/src/contracts/settings.contract.ts +4 -10
- package/src/contracts/share.contract.ts +3 -9
- package/src/contracts/skills.contract.ts +4 -15
- package/src/contracts/system.contract.ts +26 -52
- package/src/contracts/usage.contract.ts +7 -21
- package/src/contracts/vpn.contract.ts +9 -16
- package/src/contracts/webext.contract.ts +9 -25
- package/src/contracts/workflows.contract.ts +34 -58
- package/src/contracts/workspace.contract.ts +19 -50
- package/src/events/agent-events.ts +345 -0
- package/src/events/cards.ts +286 -0
- package/src/{events.test.ts → events/resume.test.ts} +4 -19
- package/src/events/resume.ts +60 -0
- package/src/events/system-events.ts +139 -0
- package/src/events/transcript.ts +320 -0
- package/src/{conversation-ids.test.ts → ids/conversation-ids.test.ts} +25 -13
- package/src/ids/conversation-ids.ts +178 -0
- package/src/ids/hostnames.ts +129 -0
- package/src/ids/session-names.ts +29 -0
- package/src/ids/share-paths.ts +43 -0
- package/src/{tunnel-ids.test.ts → ids/tunnel-ids.test.ts} +1 -14
- package/src/ids/tunnel-ids.ts +29 -0
- package/src/index.ts +71 -87
- package/src/{agent-catalog.test.ts → models/agent-catalog.test.ts} +19 -93
- package/src/models/agent-catalog.ts +174 -0
- package/src/models/agent-runtimes.ts +201 -0
- package/src/models/capability-ledger.test.ts +84 -0
- package/src/{fast-tier.test.ts → models/fast-tier.test.ts} +7 -18
- package/src/models/fast-tier.ts +36 -0
- package/src/{model-order.test.ts → models/model-order.test.ts} +19 -40
- package/src/models/model-order.ts +163 -0
- package/src/{model-pins.test.ts → models/model-pins.test.ts} +12 -46
- package/src/models/model-pins.ts +57 -0
- package/src/models/model-roles.test.ts +38 -0
- package/src/models/model-roles.ts +180 -0
- package/src/{plan-pools.test.ts → models/plan-pools.test.ts} +6 -11
- package/src/models/plan-pools.ts +65 -0
- package/src/{prompt-complexity.test.ts → models/prompt-complexity.test.ts} +8 -60
- package/src/models/prompt-complexity.ts +215 -0
- package/src/{provider-specs.test.ts → models/provider-specs.test.ts} +18 -47
- package/src/models/provider-specs.ts +272 -0
- package/src/policy/approvals-execution.ts +58 -0
- package/src/{batch-runs.test.ts → policy/batch-runs.test.ts} +4 -20
- package/src/policy/batch-runs.ts +137 -0
- package/src/policy/capability-secrets.ts +5 -0
- package/src/{card-status.ts → policy/card-status.ts} +11 -26
- package/src/{command-classes.test.ts → policy/command-classes.test.ts} +11 -118
- package/src/policy/command-classes.ts +395 -0
- package/src/policy/command-run.ts +65 -0
- package/src/policy/control-scopes.ts +38 -0
- package/src/{credential-material.test.ts → policy/credential-material.test.ts} +4 -26
- package/src/policy/credential-material.ts +91 -0
- package/src/policy/needs-action.ts +5 -0
- package/src/policy/output-fields.ts +86 -0
- package/src/policy/overlay-lint.ts +100 -0
- package/src/{owner-ticket.test.ts → policy/owner-ticket.test.ts} +1 -1
- package/src/{owner-ticket.ts → policy/owner-ticket.ts} +9 -31
- package/src/policy/safety-policy.test.ts +84 -0
- package/src/policy/safety-policy.ts +142 -0
- package/src/policy/search-globs.ts +60 -0
- package/src/protocol/container-requirements.test.ts +72 -0
- package/src/protocol/container-requirements.ts +58 -0
- package/src/protocol/host-protocol.ts +29 -0
- package/src/protocol/ingress-contract.ts +103 -0
- package/src/{ingress-protocol.test.ts → protocol/ingress-protocol.test.ts} +25 -90
- package/src/protocol/ingress-protocol.ts +441 -0
- package/src/protocol/listener-protocol.ts +75 -0
- package/src/{peer-dial.test.ts → protocol/peer-dial.test.ts} +52 -1
- package/src/protocol/peer-dial.ts +207 -0
- package/src/{peer-mcp-server.ts → protocol/peer-mcp-server.ts} +16 -41
- package/src/protocol/request-id.ts +5 -0
- package/src/{routes.test.ts → protocol/routes.test.ts} +14 -22
- package/src/protocol/routes.ts +159 -0
- package/src/protocol/runner-protocol.ts +197 -0
- package/src/protocol/terminal-protocol.ts +13 -0
- package/src/protocol/webext-links.ts +50 -0
- package/src/protocol/webext-protocol.ts +24 -0
- package/src/schemas/activity.ts +22 -30
- package/src/schemas/agent.ts +130 -238
- package/src/schemas/agents.ts +165 -483
- package/src/schemas/approvals.ts +23 -71
- package/src/schemas/automations.ts +142 -250
- package/src/schemas/capabilities.ts +127 -414
- package/src/schemas/ci.ts +56 -108
- package/src/schemas/codebase-health.ts +7 -11
- package/src/schemas/devices.ts +98 -321
- package/src/schemas/engines.ts +16 -44
- package/src/schemas/environment.ts +41 -91
- package/src/schemas/exit.ts +24 -81
- package/src/schemas/extension-updates.ts +42 -87
- package/src/schemas/git-history.ts +30 -84
- package/src/schemas/git.ts +141 -256
- package/src/schemas/history.ts +14 -40
- package/src/schemas/hosts.ts +9 -15
- package/src/schemas/inventory.ts +8 -10
- package/src/schemas/issues.ts +66 -134
- package/src/schemas/logs.ts +15 -34
- package/src/schemas/loops.ts +46 -163
- package/src/schemas/maintenance.ts +47 -172
- package/src/schemas/panels.ts +20 -45
- package/src/schemas/personas.ts +50 -200
- package/src/schemas/plan-limits.ts +58 -197
- package/src/schemas/ports.ts +14 -32
- package/src/schemas/provider-oauth.ts +23 -76
- package/src/schemas/provider-subscriptions.ts +4 -13
- package/src/schemas/public.ts +4 -15
- package/src/schemas/push.ts +8 -36
- package/src/schemas/secrets.ts +20 -64
- package/src/schemas/settings.ts +175 -600
- package/src/schemas/share.ts +14 -32
- package/src/schemas/shared.ts +14 -13
- package/src/schemas/system.ts +46 -78
- package/src/schemas/terminal.ts +41 -120
- package/src/schemas/usage.ts +44 -233
- package/src/schemas/version-seam.test.ts +9 -26
- package/src/schemas/vpn.ts +27 -64
- package/src/schemas/webext.ts +22 -53
- package/src/schemas/workflows.ts +57 -183
- package/src/schemas/workspace-repos.ts +12 -24
- package/src/schemas/workspace-search.ts +17 -35
- package/src/schemas/workspace-setup.ts +4 -11
- package/src/schemas/workspace-tree.ts +32 -91
- package/src/state/arrival.ts +109 -0
- package/src/state/contract-lock.test.ts +17 -0
- package/src/state/contract-lock.ts +49 -0
- package/src/state/definition.ts +143 -0
- package/src/state/history-state.ts +103 -0
- package/src/{runtime-state.test.ts → state/runtime-state.test.ts} +3 -10
- package/src/state/runtime-state.ts +62 -0
- package/src/state/starter.ts +5 -0
- package/src/state/state-portability.ts +27 -0
- package/src/state/versions.ts +26 -0
- package/src/{workspace-state.test.ts → state/workspace-state.test.ts} +65 -172
- package/src/state/workspace-state.ts +669 -0
- package/src/{documents.test.ts → text/documents.test.ts} +1 -1
- package/src/text/documents.ts +42 -0
- package/src/text/embed.ts +132 -0
- package/src/text/mentions.ts +21 -0
- package/src/text/model-answer.ts +9 -0
- package/src/text/path-refs.ts +39 -0
- package/src/text/shell-regions.ts +224 -0
- package/src/{title.test.ts → text/title.test.ts} +13 -32
- package/src/text/title.ts +202 -0
- package/src/{transcript-fold.test.ts → text/transcript-fold.test.ts} +5 -83
- package/src/{transcript-fold.ts → text/transcript-fold.ts} +65 -170
- package/src/text/whisper.test.ts +19 -0
- package/src/text/whisper.ts +17 -0
- package/src/{workflow-faults.test.ts → text/workflow-faults.test.ts} +6 -24
- package/src/{workflow-faults.ts → text/workflow-faults.ts} +20 -60
- package/dist/agent-catalog.d.ts.map +0 -1
- package/dist/agent-catalog.js.map +0 -1
- package/dist/agent-runtimes.d.ts.map +0 -1
- package/dist/agent-runtimes.js.map +0 -1
- package/dist/approvals-execution.d.ts.map +0 -1
- package/dist/approvals-execution.js.map +0 -1
- package/dist/arrival.d.ts.map +0 -1
- package/dist/arrival.js.map +0 -1
- package/dist/batch-runs.d.ts.map +0 -1
- package/dist/batch-runs.js.map +0 -1
- package/dist/capability-env.d.ts.map +0 -1
- package/dist/capability-env.js.map +0 -1
- package/dist/capability-secrets.d.ts.map +0 -1
- package/dist/capability-secrets.js.map +0 -1
- package/dist/card-status.d.ts.map +0 -1
- package/dist/card-status.js.map +0 -1
- package/dist/command-classes.d.ts.map +0 -1
- package/dist/command-classes.js.map +0 -1
- package/dist/command-run.d.ts.map +0 -1
- package/dist/command-run.js.map +0 -1
- package/dist/contract-lock.d.ts.map +0 -1
- package/dist/contract-lock.js.map +0 -1
- package/dist/conversation-ids.d.ts +0 -4
- package/dist/conversation-ids.d.ts.map +0 -1
- package/dist/conversation-ids.js.map +0 -1
- package/dist/credential-material.d.ts.map +0 -1
- package/dist/credential-material.js.map +0 -1
- package/dist/definition.d.ts.map +0 -1
- package/dist/definition.js.map +0 -1
- package/dist/documents.d.ts.map +0 -1
- package/dist/documents.js.map +0 -1
- package/dist/embed.d.ts.map +0 -1
- package/dist/embed.js.map +0 -1
- package/dist/events.d.ts +0 -4336
- package/dist/events.d.ts.map +0 -1
- package/dist/events.js +0 -725
- package/dist/events.js.map +0 -1
- package/dist/fast-tier.d.ts.map +0 -1
- package/dist/fast-tier.js.map +0 -1
- package/dist/history-state.d.ts.map +0 -1
- package/dist/history-state.js.map +0 -1
- package/dist/host-protocol.d.ts.map +0 -1
- package/dist/host-protocol.js.map +0 -1
- package/dist/hostnames.d.ts.map +0 -1
- package/dist/hostnames.js.map +0 -1
- package/dist/ingress-contract.d.ts.map +0 -1
- package/dist/ingress-contract.js.map +0 -1
- package/dist/ingress-protocol.d.ts.map +0 -1
- package/dist/ingress-protocol.js.map +0 -1
- package/dist/listener-protocol.d.ts.map +0 -1
- package/dist/listener-protocol.js.map +0 -1
- package/dist/mentions.d.ts.map +0 -1
- package/dist/mentions.js.map +0 -1
- package/dist/model-order.d.ts.map +0 -1
- package/dist/model-order.js.map +0 -1
- package/dist/model-pins.d.ts.map +0 -1
- package/dist/model-pins.js.map +0 -1
- package/dist/model-roles.d.ts.map +0 -1
- package/dist/model-roles.js.map +0 -1
- package/dist/needs-action.d.ts.map +0 -1
- package/dist/needs-action.js.map +0 -1
- package/dist/output-fields.d.ts.map +0 -1
- package/dist/output-fields.js.map +0 -1
- package/dist/overlay-lint.d.ts.map +0 -1
- package/dist/overlay-lint.js.map +0 -1
- package/dist/owner-ticket.d.ts.map +0 -1
- package/dist/owner-ticket.js.map +0 -1
- package/dist/path-refs.d.ts.map +0 -1
- package/dist/path-refs.js.map +0 -1
- package/dist/peer-dial.d.ts.map +0 -1
- package/dist/peer-dial.js.map +0 -1
- package/dist/peer-mcp-server.d.ts.map +0 -1
- package/dist/peer-mcp-server.js.map +0 -1
- package/dist/plan-pools.d.ts.map +0 -1
- package/dist/plan-pools.js.map +0 -1
- package/dist/prompt-complexity.d.ts.map +0 -1
- package/dist/prompt-complexity.js.map +0 -1
- package/dist/provider-specs.d.ts.map +0 -1
- package/dist/provider-specs.js.map +0 -1
- package/dist/request-id.d.ts.map +0 -1
- package/dist/request-id.js.map +0 -1
- package/dist/routes.d.ts.map +0 -1
- package/dist/routes.js.map +0 -1
- package/dist/runner-protocol.d.ts.map +0 -1
- package/dist/runner-protocol.js.map +0 -1
- package/dist/runtime-state.d.ts.map +0 -1
- package/dist/runtime-state.js.map +0 -1
- package/dist/safety-policy.d.ts.map +0 -1
- package/dist/safety-policy.js.map +0 -1
- package/dist/search-globs.d.ts.map +0 -1
- package/dist/search-globs.js.map +0 -1
- package/dist/session-names.d.ts.map +0 -1
- package/dist/session-names.js.map +0 -1
- package/dist/share-paths.d.ts.map +0 -1
- package/dist/share-paths.js.map +0 -1
- package/dist/shell-regions.d.ts.map +0 -1
- package/dist/shell-regions.js.map +0 -1
- package/dist/sse.d.ts.map +0 -1
- package/dist/sse.js.map +0 -1
- package/dist/starter.d.ts.map +0 -1
- package/dist/starter.js.map +0 -1
- package/dist/state-portability.d.ts.map +0 -1
- package/dist/state-portability.js.map +0 -1
- package/dist/terminal-protocol.d.ts.map +0 -1
- package/dist/terminal-protocol.js.map +0 -1
- package/dist/title.d.ts.map +0 -1
- package/dist/title.js.map +0 -1
- package/dist/transcript-fold.d.ts.map +0 -1
- package/dist/transcript-fold.js.map +0 -1
- package/dist/tunnel-ids.d.ts.map +0 -1
- package/dist/tunnel-ids.js.map +0 -1
- package/dist/versions.d.ts.map +0 -1
- package/dist/versions.js.map +0 -1
- package/dist/webext-links.d.ts.map +0 -1
- package/dist/webext-links.js.map +0 -1
- package/dist/webext-protocol.d.ts.map +0 -1
- package/dist/webext-protocol.js.map +0 -1
- package/dist/workflow-faults.d.ts.map +0 -1
- package/dist/workflow-faults.js.map +0 -1
- package/dist/workspace-state.d.ts.map +0 -1
- package/dist/workspace-state.js.map +0 -1
- package/src/agent-catalog.ts +0 -316
- package/src/agent-runtimes.ts +0 -419
- package/src/approvals-execution.ts +0 -96
- package/src/arrival.ts +0 -160
- package/src/batch-runs.ts +0 -188
- package/src/capability-ledger.test.ts +0 -140
- package/src/capability-secrets.ts +0 -20
- package/src/command-classes.ts +0 -617
- package/src/command-run.ts +0 -78
- package/src/contract-lock.test.ts +0 -23
- package/src/contract-lock.ts +0 -66
- package/src/conversation-ids.ts +0 -207
- package/src/credential-material.ts +0 -181
- package/src/definition.ts +0 -207
- package/src/documents.ts +0 -67
- package/src/embed.ts +0 -164
- package/src/events.ts +0 -1870
- package/src/fast-tier.ts +0 -72
- package/src/history-state.ts +0 -174
- package/src/host-protocol.ts +0 -36
- package/src/hostnames.ts +0 -180
- package/src/ingress-contract.ts +0 -157
- package/src/ingress-protocol.ts +0 -625
- package/src/listener-protocol.ts +0 -96
- package/src/mentions.ts +0 -25
- package/src/model-order.ts +0 -262
- package/src/model-pins.ts +0 -132
- package/src/model-roles.test.ts +0 -52
- package/src/model-roles.ts +0 -320
- package/src/needs-action.ts +0 -14
- package/src/output-fields.ts +0 -111
- package/src/overlay-lint.ts +0 -116
- package/src/path-refs.ts +0 -59
- package/src/peer-dial.ts +0 -163
- package/src/plan-pools.ts +0 -92
- package/src/prompt-complexity.ts +0 -334
- package/src/provider-specs.ts +0 -432
- package/src/request-id.ts +0 -41
- package/src/routes.ts +0 -219
- package/src/runner-protocol.ts +0 -239
- package/src/runtime-state.ts +0 -140
- package/src/safety-policy.test.ts +0 -88
- package/src/safety-policy.ts +0 -258
- package/src/search-globs.ts +0 -76
- package/src/session-names.ts +0 -44
- package/src/share-paths.ts +0 -68
- package/src/shell-regions.ts +0 -289
- package/src/starter.ts +0 -13
- package/src/state-portability.ts +0 -56
- package/src/terminal-protocol.ts +0 -16
- package/src/title.ts +0 -267
- package/src/tunnel-ids.ts +0 -57
- package/src/versions.ts +0 -48
- package/src/webext-links.ts +0 -90
- package/src/webext-protocol.ts +0 -27
- package/src/workspace-state.ts +0 -1090
- /package/dist/{hostnames.d.ts → ids/hostnames.d.ts} +0 -0
- /package/dist/{hostnames.js → ids/hostnames.js} +0 -0
- /package/dist/{session-names.d.ts → ids/session-names.d.ts} +0 -0
- /package/dist/{session-names.js → ids/session-names.js} +0 -0
- /package/dist/{share-paths.d.ts → ids/share-paths.d.ts} +0 -0
- /package/dist/{share-paths.js → ids/share-paths.js} +0 -0
- /package/dist/{agent-catalog.js → models/agent-catalog.js} +0 -0
- /package/dist/{agent-runtimes.d.ts → models/agent-runtimes.d.ts} +0 -0
- /package/dist/{agent-runtimes.js → models/agent-runtimes.js} +0 -0
- /package/dist/{fast-tier.js → models/fast-tier.js} +0 -0
- /package/dist/{model-order.d.ts → models/model-order.d.ts} +0 -0
- /package/dist/{model-order.js → models/model-order.js} +0 -0
- /package/dist/{model-pins.js → models/model-pins.js} +0 -0
- /package/dist/{plan-pools.js → models/plan-pools.js} +0 -0
- /package/dist/{prompt-complexity.d.ts → models/prompt-complexity.d.ts} +0 -0
- /package/dist/{prompt-complexity.js → models/prompt-complexity.js} +0 -0
- /package/dist/{provider-specs.d.ts → models/provider-specs.d.ts} +0 -0
- /package/dist/{provider-specs.js → models/provider-specs.js} +0 -0
- /package/dist/{approvals-execution.d.ts → policy/approvals-execution.d.ts} +0 -0
- /package/dist/{approvals-execution.js → policy/approvals-execution.js} +0 -0
- /package/dist/{capability-env.d.ts → policy/capability-env.d.ts} +0 -0
- /package/dist/{capability-env.js → policy/capability-env.js} +0 -0
- /package/dist/{capability-secrets.d.ts → policy/capability-secrets.d.ts} +0 -0
- /package/dist/{capability-secrets.js → policy/capability-secrets.js} +0 -0
- /package/dist/{command-run.js → policy/command-run.js} +0 -0
- /package/dist/{credential-material.d.ts → policy/credential-material.d.ts} +0 -0
- /package/dist/{credential-material.js → policy/credential-material.js} +0 -0
- /package/dist/{needs-action.d.ts → policy/needs-action.d.ts} +0 -0
- /package/dist/{needs-action.js → policy/needs-action.js} +0 -0
- /package/dist/{output-fields.d.ts → policy/output-fields.d.ts} +0 -0
- /package/dist/{output-fields.js → policy/output-fields.js} +0 -0
- /package/dist/{overlay-lint.d.ts → policy/overlay-lint.d.ts} +0 -0
- /package/dist/{overlay-lint.js → policy/overlay-lint.js} +0 -0
- /package/dist/{owner-ticket.d.ts → policy/owner-ticket.d.ts} +0 -0
- /package/dist/{search-globs.d.ts → policy/search-globs.d.ts} +0 -0
- /package/dist/{search-globs.js → policy/search-globs.js} +0 -0
- /package/dist/{ingress-contract.d.ts → protocol/ingress-contract.d.ts} +0 -0
- /package/dist/{ingress-protocol.d.ts → protocol/ingress-protocol.d.ts} +0 -0
- /package/dist/{ingress-protocol.js → protocol/ingress-protocol.js} +0 -0
- /package/dist/{listener-protocol.d.ts → protocol/listener-protocol.d.ts} +0 -0
- /package/dist/{peer-mcp-server.d.ts → protocol/peer-mcp-server.d.ts} +0 -0
- /package/dist/{peer-mcp-server.js → protocol/peer-mcp-server.js} +0 -0
- /package/dist/{request-id.d.ts → protocol/request-id.d.ts} +0 -0
- /package/dist/{request-id.js → protocol/request-id.js} +0 -0
- /package/dist/{routes.d.ts → protocol/routes.d.ts} +0 -0
- /package/dist/{routes.js → protocol/routes.js} +0 -0
- /package/dist/{sse.d.ts → protocol/sse.d.ts} +0 -0
- /package/dist/{sse.js → protocol/sse.js} +0 -0
- /package/dist/{terminal-protocol.js → protocol/terminal-protocol.js} +0 -0
- /package/dist/{webext-links.d.ts → protocol/webext-links.d.ts} +0 -0
- /package/dist/{webext-links.js → protocol/webext-links.js} +0 -0
- /package/dist/{arrival.d.ts → state/arrival.d.ts} +0 -0
- /package/dist/{contract-lock.d.ts → state/contract-lock.d.ts} +0 -0
- /package/dist/{history-state.d.ts → state/history-state.d.ts} +0 -0
- /package/dist/{runtime-state.d.ts → state/runtime-state.d.ts} +0 -0
- /package/dist/{runtime-state.js → state/runtime-state.js} +0 -0
- /package/dist/{starter.d.ts → state/starter.d.ts} +0 -0
- /package/dist/{starter.js → state/starter.js} +0 -0
- /package/dist/{state-portability.d.ts → state/state-portability.d.ts} +0 -0
- /package/dist/{state-portability.js → state/state-portability.js} +0 -0
- /package/dist/{versions.d.ts → state/versions.d.ts} +0 -0
- /package/dist/{versions.js → state/versions.js} +0 -0
- /package/dist/{embed.d.ts → text/embed.d.ts} +0 -0
- /package/dist/{embed.js → text/embed.js} +0 -0
- /package/dist/{mentions.d.ts → text/mentions.d.ts} +0 -0
- /package/dist/{mentions.js → text/mentions.js} +0 -0
- /package/dist/{path-refs.d.ts → text/path-refs.d.ts} +0 -0
- /package/dist/{path-refs.js → text/path-refs.js} +0 -0
- /package/dist/{shell-regions.js → text/shell-regions.js} +0 -0
- /package/dist/{title.d.ts → text/title.d.ts} +0 -0
- /package/dist/{title.js → text/title.js} +0 -0
- /package/src/{hostnames.test.ts → ids/hostnames.test.ts} +0 -0
- /package/src/{share-paths.test.ts → ids/share-paths.test.ts} +0 -0
- /package/src/{capability-env.ts → policy/capability-env.ts} +0 -0
- /package/src/{overlay-lint.test.ts → policy/overlay-lint.test.ts} +0 -0
- /package/src/{search-globs.test.ts → policy/search-globs.test.ts} +0 -0
- /package/src/{ingress-contract.test.ts → protocol/ingress-contract.test.ts} +0 -0
- /package/src/{peer-mcp-server.test.ts → protocol/peer-mcp-server.test.ts} +0 -0
- /package/src/{sse.ts → protocol/sse.ts} +0 -0
- /package/src/{versions.test.ts → state/versions.test.ts} +0 -0
- /package/src/{embed.test.ts → text/embed.test.ts} +0 -0
- /package/src/{mentions.test.ts → text/mentions.test.ts} +0 -0
- /package/src/{path-refs.test.ts → text/path-refs.test.ts} +0 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
// The one outbound socket a peer (machine agent, webext, runner) holds to its sandbox: hello carries the enrollment
|
|
2
|
+
// token in the frame, then the link is pure oRPC. Reconnects on backoff after any drop except a revoked enrollment
|
|
3
|
+
// (code 1008), which never retries.
|
|
4
|
+
|
|
5
|
+
// Reconnect backoff: fast floor for a restart, low cap so a reopened laptop is back within a minute.
|
|
6
|
+
export const PEER_LINK_BACKOFF = { floorMs: 1_000, capMs: 30_000, stableMs: 60_000 } as const;
|
|
7
|
+
|
|
8
|
+
/* HOW LONG A SOCKET MAY SAY NOTHING before this side calls the link dead, as a multiple of the door's own
|
|
9
|
+
* heartbeat: the hub pings every live peer on an interval (peer-hub.ts), so a socket with nothing on it for
|
|
10
|
+
* three heartbeats is not quiet, it is gone.
|
|
11
|
+
*
|
|
12
|
+
* WHY A PEER NEEDS THIS AT ALL — a close event is not guaranteed, and the loop below has nothing else to react
|
|
13
|
+
* to. The socket that taught us is a loopback one: a machine agent dialling a sandbox container on its own
|
|
14
|
+
* machine through Docker Desktop's port relay. The container was recreated; the relay was not, so it held the
|
|
15
|
+
* agent's TCP connection open with nothing behind it. No FIN, no error, no close event — the agent held an open
|
|
16
|
+
* socket to a daemon that had never heard of it for 25 hours, its Devices card offline the whole time, every
|
|
17
|
+
* control on that card dead, and the only cure anyone found was re-running setup by hand. Any path with a
|
|
18
|
+
* middlebox in it (a NAT, a tunnel, a userland proxy, a laptop's suspended wifi) can do this to a socket with
|
|
19
|
+
* nothing to say, and the middlebox is never the side that notices. The peer is. */
|
|
20
|
+
export const PEER_LINK_SILENCE_HEARTBEATS = 3;
|
|
21
|
+
export const peerLinkSilenceMs = (heartbeatMs: number): number => heartbeatMs * PEER_LINK_SILENCE_HEARTBEATS;
|
|
22
|
+
|
|
23
|
+
// The sandbox closes with this when the token is not enrolled: a decision, not a fault, and one that never heals.
|
|
24
|
+
const UNAUTHORIZED = 1008;
|
|
25
|
+
|
|
26
|
+
// WebSocket spec's readyState value for open, named so a fake socket need not import the real class.
|
|
27
|
+
const OPEN = 1;
|
|
28
|
+
|
|
29
|
+
// Structural interface a browser's WebSocket, node's global one, and a test's fake all satisfy without a cast.
|
|
30
|
+
export interface SocketLike {
|
|
31
|
+
readonly readyState: number;
|
|
32
|
+
/* `message` is here for the watchdog alone, which needs no more than the fact that one arrived: what is IN
|
|
33
|
+
* the frames belongs to the oRPC handler `attach` hands the socket to, and a listener added here does not
|
|
34
|
+
* take it from that one (both runtimes' sockets fan an event out to every listener). */
|
|
35
|
+
addEventListener(type: "open" | "close" | "error" | "message", listener: (event: { readonly code?: number }) => void): void;
|
|
36
|
+
send(data: string): void;
|
|
37
|
+
close(code?: number, reason?: string): void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface PeerDialSpec<S extends SocketLike> {
|
|
41
|
+
// Resolves the address for this attempt, not once at startup; undefined ends the loop (pairing forgotten). `said`
|
|
42
|
+
// logs once open; a resolution outliving `signal`'s abort opens nothing.
|
|
43
|
+
readonly open: (signal: AbortSignal) => Promise<{ readonly socket: S; readonly said?: string } | undefined>;
|
|
44
|
+
// First frame sent on open: the enrollment token plus whatever the door's hello schema asks for.
|
|
45
|
+
readonly hello: () => Promise<Record<string, unknown>> | Record<string, unknown>;
|
|
46
|
+
// Hand the open socket to the oRPC handler serving the door's contract.
|
|
47
|
+
readonly attach: (socket: S) => void;
|
|
48
|
+
// The retry ladder: how long to wait after a drop, given how long the socket had held.
|
|
49
|
+
readonly backoff: { readonly next: (heldMs: number) => number };
|
|
50
|
+
/* How long this socket may hear nothing before the link is presumed dead: `peerLinkSilenceMs` of the
|
|
51
|
+
* heartbeat the door's own hub pings on. Required rather than defaulted, because the number belongs to the
|
|
52
|
+
* door and a peer that quietly inherited someone else's would be guessing about the one deadline that
|
|
53
|
+
* decides whether it ever notices a dead link. */
|
|
54
|
+
readonly silenceMs: number;
|
|
55
|
+
readonly log: (message: string) => void;
|
|
56
|
+
// Sandbox refused the enrollment (1008); the loop has already stopped, this is where the peer says so.
|
|
57
|
+
readonly revoked: () => void;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface PeerLink {
|
|
61
|
+
// Resolves when the loop is asked to stop or refused for good; never rejects, a connection error is a retry.
|
|
62
|
+
readonly done: Promise<void>;
|
|
63
|
+
readonly stop: (reason?: string) => void;
|
|
64
|
+
// "connecting" covers a dial in flight and a retry waiting on the ladder: nobody should start another.
|
|
65
|
+
readonly state: () => "open" | "connecting" | "closed";
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export const dialPeer = <S extends SocketLike>(spec: PeerDialSpec<S>): PeerLink => {
|
|
69
|
+
const stopping = new AbortController();
|
|
70
|
+
let socket: S | undefined;
|
|
71
|
+
let waiting = false;
|
|
72
|
+
let openedAt: number | undefined;
|
|
73
|
+
// The live attempt's watchdog, reachable from `stop`: a stopped link that left a timer armed is a process
|
|
74
|
+
// the runtime keeps alive for a socket nobody holds any more.
|
|
75
|
+
let disarmWatchdog: () => void = () => undefined;
|
|
76
|
+
let resolveDone: () => void = () => undefined;
|
|
77
|
+
const done = new Promise<void>((resolve) => {
|
|
78
|
+
resolveDone = resolve;
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const open = async (): Promise<void> => {
|
|
82
|
+
waiting = true;
|
|
83
|
+
const attempt = await spec.open(stopping.signal);
|
|
84
|
+
waiting = false;
|
|
85
|
+
// Aborted while resolving: nothing to open, `done` settled; a socket handed over late is closed, not dialled.
|
|
86
|
+
if (stopping.signal.aborted) {
|
|
87
|
+
attempt?.socket.close(1000, "stopping");
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (attempt === undefined) {
|
|
91
|
+
stopping.abort();
|
|
92
|
+
resolveDone();
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const ws = attempt.socket;
|
|
96
|
+
socket = ws;
|
|
97
|
+
|
|
98
|
+
let watchdog: ReturnType<typeof setTimeout> | undefined;
|
|
99
|
+
const disarm = (): void => {
|
|
100
|
+
if (watchdog !== undefined) {
|
|
101
|
+
clearTimeout(watchdog);
|
|
102
|
+
watchdog = undefined;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
disarmWatchdog = disarm;
|
|
106
|
+
|
|
107
|
+
/* THIS ATTEMPT'S DROP, taken by whichever side notices first: the far end's close frame, or the
|
|
108
|
+
* watchdog. Latched, because a socket the watchdog abandoned may still emit its close minutes later,
|
|
109
|
+
* and two redials on one link is two loops racing to hold the same door. */
|
|
110
|
+
let dropped = false;
|
|
111
|
+
const drop = (said: string): void => {
|
|
112
|
+
if (dropped) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
dropped = true;
|
|
116
|
+
disarm();
|
|
117
|
+
if (socket === ws) {
|
|
118
|
+
socket = undefined;
|
|
119
|
+
}
|
|
120
|
+
if (stopping.signal.aborted) {
|
|
121
|
+
resolveDone();
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const delay = spec.backoff.next(openedAt === undefined ? 0 : Date.now() - openedAt);
|
|
125
|
+
openedAt = undefined;
|
|
126
|
+
spec.log(`${said}; reconnecting in ${Math.round(delay / 1000)}s`);
|
|
127
|
+
waiting = true;
|
|
128
|
+
setTimeout(() => void open(), delay);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const arm = (): void => {
|
|
132
|
+
disarm();
|
|
133
|
+
watchdog = setTimeout(() => {
|
|
134
|
+
/* ABANDONED, not closed politely. A close frame sent to an end that is gone waits on a reply
|
|
135
|
+
* that never comes — CLOSING is the state this watchdog exists to escape — so `close` is called
|
|
136
|
+
* for the runtime's sake and the redial does not wait on an event that may never fire. */
|
|
137
|
+
ws.close(1000, "no heartbeat");
|
|
138
|
+
drop(`nothing heard for ${Math.round(spec.silenceMs / 1000)}s`);
|
|
139
|
+
}, spec.silenceMs);
|
|
140
|
+
};
|
|
141
|
+
// Armed from the DIAL rather than the open, because a socket that never finishes connecting hangs the
|
|
142
|
+
// same way and reads the same from outside: "connecting", forever, with nothing coming.
|
|
143
|
+
arm();
|
|
144
|
+
// Every frame is proof the far end is there, and the hub's heartbeat is what guarantees there are some.
|
|
145
|
+
ws.addEventListener("message", arm);
|
|
146
|
+
|
|
147
|
+
ws.addEventListener("open", () => {
|
|
148
|
+
if (dropped) {
|
|
149
|
+
return; // abandoned mid-connect: this socket is already closed and its replacement is on the ladder
|
|
150
|
+
}
|
|
151
|
+
openedAt = Date.now();
|
|
152
|
+
arm();
|
|
153
|
+
spec.attach(ws);
|
|
154
|
+
const send = (hello: Record<string, unknown>): void => {
|
|
155
|
+
ws.send(JSON.stringify(hello));
|
|
156
|
+
if (attempt.said !== undefined) {
|
|
157
|
+
spec.log(attempt.said);
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
// Sent synchronously when possible so a test can read it the same tick; an async hello still follows.
|
|
161
|
+
const hello = spec.hello();
|
|
162
|
+
if (hello instanceof Promise) {
|
|
163
|
+
void hello.then(send);
|
|
164
|
+
} else {
|
|
165
|
+
send(hello);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
ws.addEventListener("close", (event) => {
|
|
170
|
+
/* A revocation is answered here rather than through `drop`: it is the one close that ends the loop
|
|
171
|
+
* instead of feeding the ladder, and it must still land on a socket the watchdog abandoned first —
|
|
172
|
+
* an owner who revoked a peer has said so, whether or not this side had already given up on it. */
|
|
173
|
+
if (event.code === UNAUTHORIZED) {
|
|
174
|
+
dropped = true;
|
|
175
|
+
disarm();
|
|
176
|
+
if (socket === ws) {
|
|
177
|
+
socket = undefined;
|
|
178
|
+
}
|
|
179
|
+
stopping.abort();
|
|
180
|
+
resolveDone();
|
|
181
|
+
spec.revoked();
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
drop(`disconnected (${event.code ?? "no code"})`);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// Always followed by a close event that owns the retry; this only records a cause the close code can't carry.
|
|
188
|
+
ws.addEventListener("error", () => spec.log("connection error"));
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
void open();
|
|
192
|
+
|
|
193
|
+
return {
|
|
194
|
+
done,
|
|
195
|
+
stop: (reason = "stopping") => {
|
|
196
|
+
stopping.abort();
|
|
197
|
+
waiting = false;
|
|
198
|
+
disarmWatchdog();
|
|
199
|
+
// Forgotten before the close frame arrives, so `state` reads closed the moment the peer asked.
|
|
200
|
+
const held = socket;
|
|
201
|
+
socket = undefined;
|
|
202
|
+
held?.close(1000, reason);
|
|
203
|
+
resolveDone();
|
|
204
|
+
},
|
|
205
|
+
state: () => (socket?.readyState === OPEN ? "open" : socket !== undefined || waiting ? "connecting" : "closed"),
|
|
206
|
+
};
|
|
207
|
+
};
|
|
@@ -1,45 +1,22 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { MCP_PROTOCOL_VERSION } from "./host-protocol.js";
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* the entire tool surface: what a device or a browser can do is decided by the build installed on it, and a
|
|
8
|
-
* peer that upgrades learns new tools without anything changing in the sandbox. That is the reason for the
|
|
9
|
-
* split; the alternative (schemas in the daemon, execution on the peer) makes every new tool a coordinated
|
|
10
|
-
* release of two products.
|
|
11
|
-
*
|
|
12
|
-
* The protocol implemented is the subset a Streamable HTTP client actually uses against a stateless server:
|
|
13
|
-
* initialize, tools/list, tools/call, ping, and notifications (which get no reply). Anything else answers
|
|
14
|
-
* "method not found", which is the correct JSON-RPC response and not an error worth logging.
|
|
15
|
-
*
|
|
16
|
-
* A FAILED TOOL IS NOT A FAILED CALL. Every error, a refused scope, a missing file, a command that exited 1, an
|
|
17
|
-
* argument that does not typecheck, comes back as a normal result with isError, because that is what a model can
|
|
18
|
-
* read and act on; a JSON-RPC error surfaces as a transport fault and invites a retry loop against a peer that
|
|
19
|
-
* will refuse it exactly the same way the second time.
|
|
20
|
-
*
|
|
21
|
-
* EACH TOOL'S ARGUMENTS ARE DESCRIBED ONCE. The zod schema a tool is built with is what the model is shown
|
|
22
|
-
* (`tools/list` publishes it as JSON Schema) AND what an arriving call is checked against, so the advertised
|
|
23
|
-
* shape and the accepted one cannot drift, the failure mode of writing both by hand, where a renamed field
|
|
24
|
-
* keeps validating and the model keeps being told about the old name. A handler receives its arguments typed. */
|
|
4
|
+
// The MCP server a peer (device, browser) runs; the daemon forwards JSON-RPC verbatim, so the tool table here is the
|
|
5
|
+
// whole surface. A failed tool returns isError, never a JSON-RPC error. Each tool's zod schema is both what tools/list
|
|
6
|
+
// advertises and what a call is checked against.
|
|
25
7
|
|
|
26
8
|
export interface McpTool<Ctx> {
|
|
27
9
|
readonly name: string;
|
|
28
10
|
readonly description: string;
|
|
29
|
-
// JSON Schema for `tools/list`, derived from the zod schema once at module load
|
|
11
|
+
// JSON Schema for `tools/list`, derived from the zod schema once at module load, not per request.
|
|
30
12
|
readonly inputSchema: Record<string, unknown>;
|
|
31
13
|
readonly call: (args: unknown, ctx: Ctx) => Promise<Record<string, unknown>>;
|
|
32
14
|
}
|
|
33
15
|
|
|
34
16
|
export const textResult = (text: string, isError = false): Record<string, unknown> => ({ content: [{ type: "text", text }], isError });
|
|
35
17
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
* the parse is what re-establishes the type at the boundary. `Ctx` is what the peer hands every call beside
|
|
39
|
-
* its arguments: a device's live grant, nothing for a browser.
|
|
40
|
-
*
|
|
41
|
-
* `$schema` is dropped: the enclosing tool entry already says what this document is, and MCP clients read the
|
|
42
|
-
* keywords rather than the dialect declaration. */
|
|
18
|
+
// Builds one tool from a single zod schema; the generic carries its type to the handler, and `McpTool` erases it again
|
|
19
|
+
// since the dispatch table holds every tool. `$schema` is dropped from the JSON Schema output as redundant.
|
|
43
20
|
export const tool = <Schema extends z.ZodType, Ctx>(spec: {
|
|
44
21
|
readonly name: string;
|
|
45
22
|
readonly description: string;
|
|
@@ -53,15 +30,14 @@ export const tool = <Schema extends z.ZodType, Ctx>(spec: {
|
|
|
53
30
|
inputSchema,
|
|
54
31
|
call: async (args, ctx) => {
|
|
55
32
|
const parsed = spec.input.safeParse(args);
|
|
56
|
-
// Readable enough for a model to fix its own call: which field, and what was expected
|
|
33
|
+
// Readable enough for a model to fix its own call: which field, and what was expected.
|
|
57
34
|
return parsed.success ? await spec.run(parsed.data, ctx) : textResult(z.prettifyError(parsed.error), true);
|
|
58
35
|
},
|
|
59
36
|
};
|
|
60
37
|
};
|
|
61
38
|
|
|
62
|
-
// What the peer's audit log is told about one call:
|
|
63
|
-
//
|
|
64
|
-
// with no message; one that threw carries what it said, and whether it was the peer's own refusal.
|
|
39
|
+
// What the peer's audit log is told about one call: arguments verbatim (redaction is the peer's job) and how it ended.
|
|
40
|
+
// isError is `ok: false` with no message; a throw carries its message and whether it was a refusal.
|
|
65
41
|
export interface McpAuditEntry {
|
|
66
42
|
readonly tool: string;
|
|
67
43
|
readonly args: Record<string, unknown>;
|
|
@@ -72,21 +48,20 @@ export interface McpAuditEntry {
|
|
|
72
48
|
export interface McpServerSpec<Ctx> {
|
|
73
49
|
readonly serverInfo: () => { readonly name: string; readonly version: string };
|
|
74
50
|
readonly tools: readonly McpTool<Ctx>[];
|
|
75
|
-
//
|
|
51
|
+
// Message for an unknown tool, phrased in the peer's own vocabulary.
|
|
76
52
|
readonly noSuchTool: (name: string) => string;
|
|
77
|
-
// Whether a thrown error is
|
|
78
|
-
//
|
|
53
|
+
// Whether a thrown error is the peer's own refusal (a disabled switch, an ungranted site) rather than a tool
|
|
54
|
+
// failure.
|
|
79
55
|
readonly refused: (error: unknown) => boolean;
|
|
80
56
|
readonly errorMessage: (error: unknown) => string;
|
|
81
|
-
//
|
|
82
|
-
// never fail the answer, so a rejection here is swallowed.
|
|
57
|
+
// Called with every outcome; best-effort, a logging failure here must never fail the answer.
|
|
83
58
|
readonly audit: (entry: McpAuditEntry) => Promise<void> | void;
|
|
84
59
|
}
|
|
85
60
|
|
|
86
61
|
const isRecord = (value: unknown): value is Record<string, unknown> => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
87
62
|
|
|
88
|
-
//
|
|
89
|
-
//
|
|
63
|
+
// Handles one JSON-RPC message; returns undefined for a notification. `ctx` is read per call, so a grant pushed
|
|
64
|
+
// mid-session takes effect on the next call.
|
|
90
65
|
export const createMcpServer = <Ctx>(spec: McpServerSpec<Ctx>): ((message: unknown, ctx: Ctx) => Promise<Record<string, unknown> | undefined>) => {
|
|
91
66
|
const byName = new Map(spec.tools.map((entry) => [entry.name, entry]));
|
|
92
67
|
const listing = spec.tools.map(({ name, description, inputSchema }) => ({ name, description, inputSchema }));
|
|
@@ -94,7 +69,7 @@ export const createMcpServer = <Ctx>(spec: McpServerSpec<Ctx>): ((message: unkno
|
|
|
94
69
|
try {
|
|
95
70
|
await spec.audit(entry);
|
|
96
71
|
} catch {
|
|
97
|
-
//
|
|
72
|
+
// Silent: this log is for a human, never a control.
|
|
98
73
|
}
|
|
99
74
|
};
|
|
100
75
|
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Correlates a browser call to the daemon request that served it; a token only, never a security boundary.
|
|
2
|
+
export const REQUEST_ID_HEADER = "x-intentic-request-id";
|
|
3
|
+
|
|
4
|
+
// Confirms daemon CORS accepts this header before sending; no evidence here means don't send, unlike supportsRoute.
|
|
5
|
+
export const REQUEST_ID_EVIDENCE_ROUTE = "logs.report";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { eventIterator, oc } from "@orpc/contract";
|
|
2
2
|
import { describe, expect, it } from "vitest";
|
|
3
3
|
import { z } from "zod";
|
|
4
|
-
import { SANDBOX_ROUTE_NAMES, SANDBOX_ROUTE_SHAPES, SANDBOX_ROUTES, sandboxRouteName } from "
|
|
4
|
+
import { SANDBOX_ROUTE_NAMES, SANDBOX_ROUTE_SHAPES, SANDBOX_ROUTES, sandboxRouteName } from "../index.js";
|
|
5
5
|
import { contractRoutes, routeNameForRequest, routeShapes } from "./routes.js";
|
|
6
6
|
|
|
7
7
|
const fixture = {
|
|
@@ -14,7 +14,7 @@ const fixture = {
|
|
|
14
14
|
},
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
// A contract whose one route carries real schemas, so
|
|
17
|
+
// A contract whose one route carries real schemas, so its shape can change between builds.
|
|
18
18
|
const shaped = (output: z.ZodType) => ({ vpn: { list: oc.route({ method: "GET", path: "/vpn" }).output(output) } });
|
|
19
19
|
|
|
20
20
|
describe(`contractRoutes`, () => {
|
|
@@ -77,8 +77,6 @@ describe(`routeShapes`, () => {
|
|
|
77
77
|
it(`changes the fingerprint when a field is added`, () => {
|
|
78
78
|
const before = routeShapes(shaped(z.object({ a: z.string() })))[`vpn.list`];
|
|
79
79
|
const after = routeShapes(shaped(z.object({ a: z.string(), b: z.number() })))[`vpn.list`];
|
|
80
|
-
// A fingerprint is a string, and saying so is what makes the line below mean something: with `before`
|
|
81
|
-
// undefined and `after` a real shape, "they differ" is true for the wrong reason.
|
|
82
80
|
expect(before).toEqual(expect.any(String));
|
|
83
81
|
expect(after).not.toBe(before);
|
|
84
82
|
});
|
|
@@ -96,8 +94,7 @@ describe(`routeShapes`, () => {
|
|
|
96
94
|
});
|
|
97
95
|
|
|
98
96
|
it(`reads a defaulted field differently on the way in than on the way out`, () => {
|
|
99
|
-
// `.default()` makes a field optional
|
|
100
|
-
// wire shapes. Reading both directions the same way would call them identical.
|
|
97
|
+
// `.default()` makes a field optional on input, required on output: same declaration, two shapes.
|
|
101
98
|
const one = z.object({ a: z.string().default(`x`) });
|
|
102
99
|
const asOutput = routeShapes(shaped(one))[`vpn.list`];
|
|
103
100
|
const asInput = routeShapes({ vpn: { list: oc.route({ method: "GET", path: "/vpn" }).input(one) } })[`vpn.list`];
|
|
@@ -106,8 +103,8 @@ describe(`routeShapes`, () => {
|
|
|
106
103
|
});
|
|
107
104
|
|
|
108
105
|
it(`treats a route declaring no schemas as a shape of its own`, () => {
|
|
109
|
-
//
|
|
110
|
-
//
|
|
106
|
+
// All three fixture routes declare nothing, so all three share one shape; giving one an output later is a real
|
|
107
|
+
// change.
|
|
111
108
|
const shapes = routeShapes(fixture);
|
|
112
109
|
expect(Object.keys(shapes).toSorted()).toEqual([`system.killTerminal`, `vpn.connect`, `vpn.list`]);
|
|
113
110
|
expect(new Set(Object.values(shapes)).size).toBe(1);
|
|
@@ -115,10 +112,8 @@ describe(`routeShapes`, () => {
|
|
|
115
112
|
});
|
|
116
113
|
|
|
117
114
|
it(`omits a route whose shape cannot be expressed rather than failing the walk`, () => {
|
|
118
|
-
// An oRPC event iterator wraps its output in an opaque type with no schema
|
|
119
|
-
//
|
|
120
|
-
// "assume compatible". The two neighbours still get fingerprinted, which is the part that matters: one
|
|
121
|
-
// unexpressable route must not cost the whole walk.
|
|
115
|
+
// An oRPC event iterator wraps its output in an opaque type with no schema, so `watch` here keeps its name but
|
|
116
|
+
// no shape.
|
|
122
117
|
const withStream = {
|
|
123
118
|
vpn: {
|
|
124
119
|
list: fixture.vpn.list,
|
|
@@ -137,15 +132,13 @@ describe(`routeShapes`, () => {
|
|
|
137
132
|
describe(`the real sandbox contract`, () => {
|
|
138
133
|
it(`fingerprints all but the streaming routes`, () => {
|
|
139
134
|
const unshaped = SANDBOX_ROUTE_NAMES.filter((name) => !(name in SANDBOX_ROUTE_SHAPES));
|
|
140
|
-
// oRPC
|
|
141
|
-
//
|
|
142
|
-
// a route that quietly lost its shape check, which is worth failing a test over.
|
|
135
|
+
// oRPC gives an event iterator's output no schema, so these can't be fingerprinted; named rather than counted
|
|
136
|
+
// so a new one added here fails the test.
|
|
143
137
|
expect(unshaped.toSorted()).toEqual([
|
|
144
138
|
`agent.attach`,
|
|
145
139
|
`capabilities.add`,
|
|
146
|
-
// The three
|
|
147
|
-
//
|
|
148
|
-
// the free providers and can fail with something the user has to read at each step.
|
|
140
|
+
// The three exit moves stream since bringing an exit up dials and verifies over tens of seconds, failing at
|
|
141
|
+
// any step.
|
|
149
142
|
`exit.rotate`,
|
|
150
143
|
`exit.start`,
|
|
151
144
|
`exit.use`,
|
|
@@ -153,8 +146,8 @@ describe(`the real sandbox contract`, () => {
|
|
|
153
146
|
`intentic.run`,
|
|
154
147
|
`system.events`,
|
|
155
148
|
`system.manageDeviceSandbox`,
|
|
156
|
-
// The device
|
|
157
|
-
//
|
|
149
|
+
// The device agent updates or restarts itself; the stream dies with the process, so lines arrive as they
|
|
150
|
+
// happen.
|
|
158
151
|
`system.runDeviceAgentFlow`,
|
|
159
152
|
`vpn.connect`,
|
|
160
153
|
]);
|
|
@@ -171,8 +164,7 @@ describe(`the real sandbox contract`, () => {
|
|
|
171
164
|
});
|
|
172
165
|
|
|
173
166
|
it(`covers every oc.route in the contract`, () => {
|
|
174
|
-
// Guards
|
|
175
|
-
// silently advertise fewer routes than the daemon serves.
|
|
167
|
+
// Guards against a contract nesting deeper than group → procedure, which would silently under-report routes.
|
|
176
168
|
expect(SANDBOX_ROUTES.length).toBeGreaterThan(100);
|
|
177
169
|
});
|
|
178
170
|
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
// Named route surface of the daemon's contract (`<group>.<route>`), derived automatically so nothing here is
|
|
4
|
+
// hand-maintained. The daemon advertises which routes it implements (the /events hello frame); the browser diffs that
|
|
5
|
+
// against its own contract so an old daemon's gap is a named feature check, not a silent 404.
|
|
6
|
+
|
|
7
|
+
// Structural shape of `~orpc.route`, the metadata oRPC attaches to every `oc.route(...)` procedure; read this way since
|
|
8
|
+
// oRPC's internal types aren't public.
|
|
9
|
+
interface ContractProcedureLike {
|
|
10
|
+
readonly "~orpc": { readonly route?: { readonly method?: string; readonly path?: string } };
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const procedureRoute = (value: unknown): { method: string; path: string } | undefined => {
|
|
14
|
+
if (typeof value !== "object" || value === null || !("~orpc" in value)) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
const { route } = (value as ContractProcedureLike)["~orpc"];
|
|
18
|
+
if (route?.method === undefined || route.path === undefined) {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
return { method: route.method, path: route.path };
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// One advertised route: contract name plus wire shape, matched back to a concrete request path by routeNameForRequest.
|
|
25
|
+
export interface ContractRoute {
|
|
26
|
+
readonly name: string;
|
|
27
|
+
readonly method: string;
|
|
28
|
+
// oRPC path template with `{param}` placeholders, e.g. `/system/terminals/{name}`.
|
|
29
|
+
readonly path: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Walks a contract object (group → procedure) into a flat route list, sorted by name for a stable diff.
|
|
33
|
+
export const contractRoutes = (contract: Record<string, unknown>): ContractRoute[] => {
|
|
34
|
+
const routes: ContractRoute[] = [];
|
|
35
|
+
for (const [group, procedures] of Object.entries(contract)) {
|
|
36
|
+
if (typeof procedures !== "object" || procedures === null) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
for (const [name, procedure] of Object.entries(procedures as Record<string, unknown>)) {
|
|
40
|
+
const route = procedureRoute(procedure);
|
|
41
|
+
if (route !== undefined) {
|
|
42
|
+
routes.push({ name: `${group}.${name}`, method: route.method, path: route.path });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return routes.toSorted((a, b) => a.name.localeCompare(b.name));
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// Route names alone miss payload drift: a route present on both sides can still have a different schema between builds.
|
|
50
|
+
// Each route also carries a fingerprint of its input/output schema, computed automatically so nothing here is a
|
|
51
|
+
// hand-bumped version number.
|
|
52
|
+
|
|
53
|
+
// Schemas oRPC hangs off a procedure, read structurally like `route` above since they're internal metadata, not public.
|
|
54
|
+
interface ContractSchemasLike {
|
|
55
|
+
readonly "~orpc": { readonly inputSchema?: unknown; readonly outputSchema?: unknown };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// JSON Schema keywords whose array value is a set; reordering a z.object's fields must not read as drift.
|
|
59
|
+
const UNORDERED = new Set(["required", "enum", "anyOf", "oneOf", "allOf"]);
|
|
60
|
+
|
|
61
|
+
// Canonicalizes JSON: object keys and set-valued arrays (UNORDERED) sorted, everything else left as written, so a
|
|
62
|
+
// cosmetic edit doesn't fingerprint as a payload change. Positional arrays like a tuple's `prefixItems` stay ordered,
|
|
63
|
+
// or distinct shapes would collide.
|
|
64
|
+
const canonical = (value: unknown, key?: string): unknown => {
|
|
65
|
+
if (Array.isArray(value)) {
|
|
66
|
+
const items = value.map((item) => canonical(item));
|
|
67
|
+
return key !== undefined && UNORDERED.has(key) ? items.toSorted((a, b) => JSON.stringify(a).localeCompare(JSON.stringify(b))) : items;
|
|
68
|
+
}
|
|
69
|
+
if (typeof value !== "object" || value === null) {
|
|
70
|
+
return value;
|
|
71
|
+
}
|
|
72
|
+
const entries = Object.entries(value as Record<string, unknown>).toSorted(([a], [b]) => a.localeCompare(b));
|
|
73
|
+
return entries.map(([name, nested]) => [name, canonical(nested, name)]);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// FNV-1a over the canonical JSON, base36; not cryptographic, since this is only a drift signal and a collision costs
|
|
77
|
+
// one missed warning, nothing more.
|
|
78
|
+
const fingerprint = (value: unknown): string => {
|
|
79
|
+
const text = JSON.stringify(canonical(value));
|
|
80
|
+
let hash = 0x811c9dc5;
|
|
81
|
+
for (let i = 0; i < text.length; i++) {
|
|
82
|
+
hash ^= text.charCodeAt(i);
|
|
83
|
+
hash = Math.imul(hash, 0x01000193) >>> 0;
|
|
84
|
+
}
|
|
85
|
+
return hash.toString(36);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
// One route's wire shape, or undefined if it can't be expressed (a streaming route with no underlying schema). `io`
|
|
89
|
+
// matters: a `.default()` field is optional in and required out, so both directions must be read separately.
|
|
90
|
+
const procedureShape = (value: unknown): string | undefined => {
|
|
91
|
+
if (typeof value !== "object" || value === null || !("~orpc" in value)) {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
const { inputSchema, outputSchema } = (value as ContractSchemasLike)["~orpc"];
|
|
95
|
+
try {
|
|
96
|
+
return fingerprint({
|
|
97
|
+
in: inputSchema === undefined ? undefined : z.toJSONSchema(inputSchema as z.ZodType, { io: "input" }),
|
|
98
|
+
out: outputSchema === undefined ? undefined : z.toJSONSchema(outputSchema as z.ZodType, { io: "output" }),
|
|
99
|
+
});
|
|
100
|
+
} catch {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// Every route whose shape this build can express, as name → fingerprint. A separate map from ContractRoute since
|
|
106
|
+
// existence and shape are advertised, and checked, independently.
|
|
107
|
+
export const routeShapes = (contract: Record<string, unknown>): Record<string, string> => {
|
|
108
|
+
const shapes: Record<string, string> = {};
|
|
109
|
+
for (const [group, procedures] of Object.entries(contract)) {
|
|
110
|
+
if (typeof procedures !== "object" || procedures === null) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
for (const [name, procedure] of Object.entries(procedures as Record<string, unknown>)) {
|
|
114
|
+
if (procedureRoute(procedure) === undefined) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
const shape = procedureShape(procedure);
|
|
118
|
+
if (shape !== undefined) {
|
|
119
|
+
shapes[`${group}.${name}`] = shape;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return shapes;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// Matches a concrete path against a route template segment-wise; `{param}` matches exactly one segment, so length must
|
|
127
|
+
// match too.
|
|
128
|
+
const pathMatches = (template: string, path: string): boolean => {
|
|
129
|
+
const wanted = template.split("/");
|
|
130
|
+
const actual = path.split("/");
|
|
131
|
+
if (wanted.length !== actual.length) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
return wanted.every((segment, index) => (segment.startsWith("{") && segment.endsWith("}") ? actual[index] !== "" : segment === actual[index]));
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// The contract route a request belongs to, or undefined for a hand-written daemon route (/health, /workspace/raw) never
|
|
138
|
+
// gated by the contract. Query string stripped first.
|
|
139
|
+
export const routeNameForRequest = (routes: readonly ContractRoute[], method: string, pathWithQuery: string): string | undefined => {
|
|
140
|
+
const path = pathWithQuery.split("?")[0] ?? pathWithQuery;
|
|
141
|
+
const upper = method.toUpperCase();
|
|
142
|
+
return routes.find((route) => route.method.toUpperCase() === upper && pathMatches(route.path, path))?.name;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
// The route a typed client call belongs to; oRPC addresses a procedure by contract position (`['git','stashApply']`),
|
|
146
|
+
// so this is a lookup, not a match.
|
|
147
|
+
export const routeForProcedure = (routes: readonly ContractRoute[], procedure: readonly string[]): ContractRoute | undefined =>
|
|
148
|
+
routes.find((route) => route.name === procedure.join("."));
|
|
149
|
+
|
|
150
|
+
// Fills each `{param}` in the route template from the matching input field, so a permission gate checks the real path,
|
|
151
|
+
// not a template a glob would still match unfilled. An unmatched param keeps its placeholder, the safe failure since a
|
|
152
|
+
// literal grant won't match braces.
|
|
153
|
+
export const requestPathFor = (route: ContractRoute, input: unknown): string => {
|
|
154
|
+
const fields = typeof input === "object" && input !== null ? (input as Record<string, unknown>) : {};
|
|
155
|
+
return route.path.replace(/\{([^}]+)\}/g, (placeholder, name: string) => {
|
|
156
|
+
const value = fields[name];
|
|
157
|
+
return value === undefined ? placeholder : encodeURIComponent(String(value));
|
|
158
|
+
});
|
|
159
|
+
};
|