@intentic/sandbox-contract 1.248.0 → 1.250.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 +6 -0
- package/dist/contracts/skills.contract.d.ts.map +1 -1
- package/dist/contracts/skills.contract.js +13 -4
- 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 +429 -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/{model-order.js → models/model-order.js} +2 -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 +92 -0
- package/dist/schemas/devices.d.ts.map +1 -1
- package/dist/schemas/devices.js +12 -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 +11 -9
- package/dist/schemas/settings.d.ts.map +1 -1
- package/dist/schemas/settings.js +22 -7
- 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 +21 -19
- 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} +54 -40
- package/src/models/model-order.ts +171 -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 +103 -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 +182 -602
- 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 +63 -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-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,395 @@
|
|
|
1
|
+
import { HISTORY_ROOT, WORKSPACE_ROOT } from "@intentic/constants";
|
|
2
|
+
import { type CommandClass, CommandClassSchema, type CommandLocus } from "../schemas/agent.js";
|
|
3
|
+
import { inertRegions, isLive } from "../text/shell-regions.js";
|
|
4
|
+
|
|
5
|
+
// Classifies a shell command, shared by the sandbox gate and the machine agent's shell tool so they can't drift on what
|
|
6
|
+
// a class means. A match now only means a judge should look, not a verdict, so tables should be over-inclusive, except
|
|
7
|
+
// the hard-rule classes, which read `live` instead.
|
|
8
|
+
|
|
9
|
+
// A half-open slice of the command text, in UTF-16 code units, the offsets a renderer slices with.
|
|
10
|
+
export interface CommandSpan {
|
|
11
|
+
readonly start: number;
|
|
12
|
+
readonly end: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// One class the command fell in, and the fragments that put it there. `spans` is never empty: a class with nothing to
|
|
16
|
+
// point at is not reported.
|
|
17
|
+
export interface CommandMatch {
|
|
18
|
+
readonly commandClass: CommandClass;
|
|
19
|
+
readonly spans: readonly CommandSpan[];
|
|
20
|
+
// Whether a shell would run the fragment, vs text; only the hard rule ever reads this bit.
|
|
21
|
+
readonly live: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// What the caller can check that the patterns cannot. Optional everywhere: absent means every table answers from the
|
|
25
|
+
// command text alone.
|
|
26
|
+
export interface CommandContext {
|
|
27
|
+
// Where this command would run, with no default: half this catalog means something different per machine.
|
|
28
|
+
readonly locus: CommandLocus;
|
|
29
|
+
// true/false/undefined for holding a credential; only false drops a class, undefined still counts as a hit.
|
|
30
|
+
readonly holdsSecret?: (path: string) => boolean | undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// The `g` twin of a table's patterns, built once: the tables stay flag-free since a surviving lastIndex is how a shared
|
|
34
|
+
// regex starts skipping matches, and `test` (the verdict path) wants that. matchAll demands `g`.
|
|
35
|
+
const globally = (patterns: readonly RegExp[]): readonly RegExp[] => patterns.map((pattern) => new RegExp(pattern.source, `${pattern.flags}g`));
|
|
36
|
+
|
|
37
|
+
// Every occurrence of every pattern, as spans over `command`. The whole match, not a capture group: a pattern spans the
|
|
38
|
+
// consequence (`git push … --force`), and a group would leave the verb it belongs to unmarked.
|
|
39
|
+
const spansOf = (patterns: readonly RegExp[], command: string): CommandSpan[] =>
|
|
40
|
+
patterns.flatMap((pattern) => [...command.matchAll(pattern)].map((match) => ({ start: match.index, end: match.index + match[0].length })));
|
|
41
|
+
|
|
42
|
+
// Sorted, with overlaps folded (not adjacency: touching spans from different fragments stay two marks). Exported since
|
|
43
|
+
// a caller marking several classes at once must also fold overlap across classes, not just within one.
|
|
44
|
+
export const mergeSpans = (spans: readonly CommandSpan[]): CommandSpan[] => {
|
|
45
|
+
const merged: CommandSpan[] = [];
|
|
46
|
+
for (const span of [...spans].sort((left, right) => left.start - right.start || left.end - right.end)) {
|
|
47
|
+
const last = merged.at(-1);
|
|
48
|
+
if (last !== undefined && span.start < last.end) {
|
|
49
|
+
merged[merged.length - 1] = { start: last.start, end: Math.max(last.end, span.end) };
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
merged.push(span);
|
|
53
|
+
}
|
|
54
|
+
return merged;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const GIT_DESTRUCTIVE = [
|
|
58
|
+
/\bgit\s+push\b[^|;&]*\s(?:-f\b|--force\b|--force-with-lease\b|--delete\b)/,
|
|
59
|
+
/\bgit\s+reset\b[^|;&]*\s--hard\b/,
|
|
60
|
+
// Any `clean` that forces: it deletes untracked files, which is work no history holds a copy of.
|
|
61
|
+
/\bgit\s+clean\b[^|;&]*\s-{1,2}[a-zA-Z]*f/,
|
|
62
|
+
/\bgit\s+branch\b[^|;&]*\s(?:-D\b|--delete\s+--force\b|--force\s+--delete\b)/,
|
|
63
|
+
/\bgit\s+filter-branch\b/,
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
// The credential is IN the command, not in a file; there is nothing for a filesystem to fact-check here.
|
|
67
|
+
const SECRET_REFERENCES = [/\{\{secret:[A-Za-z0-9_./-]+\}\}/];
|
|
68
|
+
|
|
69
|
+
// A path that usually holds a credential, a guess about a FILE, so every entry here is subject to holdsSecret.
|
|
70
|
+
// The directory in front of a filename, so a pattern spans the whole path, not just the file inside it.
|
|
71
|
+
const LEADING_PATH = String.raw`[\w~$.{}/\\-]*`;
|
|
72
|
+
|
|
73
|
+
const CREDENTIAL_PATHS = [
|
|
74
|
+
// A dotenv file, not the checked-in templates beside it and not `process.env` (excluded by the lookbehind).
|
|
75
|
+
/(?<![\w.])\.env(?!\.(?:example|sample|template))(?:\.[\w-]+)?\b/,
|
|
76
|
+
// The ssh directory and what's under it, except the three public-by-design members (.pub, known_hosts, config).
|
|
77
|
+
/\.ssh(?!\w)(?!\/(?:known_hosts|config|authorized_keys|environment)(?!\w))(?!\/[\w.-]*\.pub(?!\w))(?:\/[\w.\-/]*)?/,
|
|
78
|
+
// A private key by its conventional name; `.pub` beside it is the public half and is not this.
|
|
79
|
+
/\bid_(?:rsa|dsa|ecdsa|ed25519)\b(?!\.pub\b)/,
|
|
80
|
+
new RegExp(String.raw`${LEADING_PATH}\.aws/credentials\b`),
|
|
81
|
+
// An npmrc, but not the checked-in template beside it, the same exclusion `.env` has.
|
|
82
|
+
new RegExp(String.raw`${LEADING_PATH}\.npmrc(?!\.(?:example|sample|template))\b`),
|
|
83
|
+
new RegExp(String.raw`${LEADING_PATH}\.git-credentials\b`),
|
|
84
|
+
new RegExp(String.raw`${LEADING_PATH}\.credentials\.json\b`),
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
const PACKAGE_PUBLISH = [
|
|
88
|
+
/\b(?:npm|pnpm|yarn|bun)\s+publish\b/,
|
|
89
|
+
/\bcargo\s+publish\b/,
|
|
90
|
+
/\bgh\s+release\s+create\b/,
|
|
91
|
+
/\bdocker\s+push\b/,
|
|
92
|
+
/\btwine\s+upload\b/,
|
|
93
|
+
];
|
|
94
|
+
|
|
95
|
+
// The loopback hosts, as a whole host not a prefix: localhost.attacker.com must not inherit the exemption.
|
|
96
|
+
const LOOPBACK = String.raw`(?:localhost|127\.0\.0\.1|0\.0\.0\.0|\[::1\])(?::\d+)?(?=[/?#\s'"\x60]|$)`;
|
|
97
|
+
|
|
98
|
+
// Loopback traffic never leaves the container, so this class means reaching OUT, not curl specifically.
|
|
99
|
+
const NETWORK_OUTBOUND = [
|
|
100
|
+
new RegExp(String.raw`\b(?:curl|wget)\b[^|;&]*\bhttps?://(?!${LOOPBACK})`),
|
|
101
|
+
// The JS backend's own curl: a literal non-loopback URL handed to fetch(); a runtime-built URL walks past it.
|
|
102
|
+
new RegExp(String.raw`\bfetch\(\s*['"\x60]https?://(?!${LOOPBACK})`),
|
|
103
|
+
];
|
|
104
|
+
|
|
105
|
+
// One parse feeds both rm classes, since only the operand tells build-dir from root apart.
|
|
106
|
+
const RM_INVOCATION = /\brm\s+([^|;&\n]*)/g;
|
|
107
|
+
|
|
108
|
+
interface RmInvocation {
|
|
109
|
+
readonly recursive: boolean;
|
|
110
|
+
readonly force: boolean;
|
|
111
|
+
readonly operands: readonly string[];
|
|
112
|
+
// Where this invocation sits, verb through last operand, so a card can point at just this delete.
|
|
113
|
+
readonly span: CommandSpan;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// A shell word with its quoting removed, so "/work", '/work' and /work are one operand, not three.
|
|
117
|
+
const unquote = (word: string): string => word.replace(/^['"`]|['"`]$/g, "");
|
|
118
|
+
|
|
119
|
+
const parseRm = (command: string): RmInvocation[] => {
|
|
120
|
+
const parsed: RmInvocation[] = [];
|
|
121
|
+
for (const invocation of command.matchAll(RM_INVOCATION)) {
|
|
122
|
+
let recursive = false;
|
|
123
|
+
let force = false;
|
|
124
|
+
const operands: string[] = [];
|
|
125
|
+
for (const word of (invocation[1] as string).trim().split(/\s+/)) {
|
|
126
|
+
if (word === "") {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
// A long flag is one whole word; a short cluster is a bag of letters, so --force isn't read as f-o-r-c-e.
|
|
130
|
+
if (word.startsWith("--")) {
|
|
131
|
+
recursive ||= word === "--recursive";
|
|
132
|
+
force ||= word === "--force";
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
if (word.startsWith("-")) {
|
|
136
|
+
recursive ||= /[rR]/.test(word);
|
|
137
|
+
force ||= word.includes("f");
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
operands.push(unquote(word));
|
|
141
|
+
}
|
|
142
|
+
parsed.push({ recursive, force, operands, span: { start: invocation.index, end: invocation.index + invocation[0].trimEnd().length } });
|
|
143
|
+
}
|
|
144
|
+
return parsed;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// A target that is a root vs inside one: a closed list per locus, since "root" differs per machine.
|
|
148
|
+
|
|
149
|
+
// Two entries: the root itself, and /history, since no other conversation's data is recoverable here.
|
|
150
|
+
const SANDBOX_ROOTS = new Set(["", HISTORY_ROOT]);
|
|
151
|
+
|
|
152
|
+
// The full list: nothing on a real machine is rebuilt from an image, so every top-level OS directory counts.
|
|
153
|
+
const DEVICE_ROOTS = new Set([
|
|
154
|
+
"",
|
|
155
|
+
WORKSPACE_ROOT,
|
|
156
|
+
HISTORY_ROOT,
|
|
157
|
+
"/home",
|
|
158
|
+
"/root",
|
|
159
|
+
"/etc",
|
|
160
|
+
"/usr",
|
|
161
|
+
"/var",
|
|
162
|
+
"/opt",
|
|
163
|
+
"/boot",
|
|
164
|
+
"/bin",
|
|
165
|
+
"/sbin",
|
|
166
|
+
"/lib",
|
|
167
|
+
"/lib64",
|
|
168
|
+
"/srv",
|
|
169
|
+
"/dev",
|
|
170
|
+
"/sys",
|
|
171
|
+
"/proc",
|
|
172
|
+
"/mnt",
|
|
173
|
+
"/media",
|
|
174
|
+
"/Users",
|
|
175
|
+
"/Applications",
|
|
176
|
+
"/System",
|
|
177
|
+
"/Library",
|
|
178
|
+
]);
|
|
179
|
+
|
|
180
|
+
const rootsAt = (locus: CommandLocus): ReadonlySet<string> => (locus === "sandbox" ? SANDBOX_ROOTS : DEVICE_ROOTS);
|
|
181
|
+
|
|
182
|
+
const HOME_ALIAS = /^(?:~|\$HOME|\$\{HOME\}|%USERPROFILE%)$/;
|
|
183
|
+
const WINDOWS_DRIVE = /^[A-Za-z]:$/;
|
|
184
|
+
|
|
185
|
+
// A trailing separator or wildcard means "everything in it"; a bare * is left alone (relative to cwd).
|
|
186
|
+
const trimTarget = (operand: string): string => operand.replace(/[/\\]\*+$/, "").replace(/[/\\]+$/, "");
|
|
187
|
+
|
|
188
|
+
const isRootTarget = (operand: string, locus: CommandLocus): boolean => {
|
|
189
|
+
const target = trimTarget(operand);
|
|
190
|
+
// Home directory/Windows drive are roots only on a device: the sandbox's ~ is scratch, rebuilt with the image.
|
|
191
|
+
if (HOME_ALIAS.test(target) || WINDOWS_DRIVE.test(target)) {
|
|
192
|
+
return locus === "device";
|
|
193
|
+
}
|
|
194
|
+
// Only an absolute path can be a root; a relative path is relative to a cwd this cannot know or guess.
|
|
195
|
+
return target === "" ? operand.startsWith("/") || operand.startsWith("\\") : rootsAt(locus).has(target);
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
// Node spellings of the same deletes; recursive alone is enough, since a script has no prompt to interrupt it.
|
|
199
|
+
const NODE_RECURSIVE_RM = /\b(?:rm|rmSync|rmdir|rmdirSync)\s*\([^)]*?recursive\s*:\s*true/;
|
|
200
|
+
const NODE_RECURSIVE_RM_PATH = /\b(?:rm|rmSync|rmdir|rmdirSync)\s*\(\s*(['"`])([^'"`]*)\1[^)]*?recursive\s*:\s*true/g;
|
|
201
|
+
// rimraf's whole purpose is the recursive force delete, so the call itself is the match; no options to read.
|
|
202
|
+
const RIMRAF = /\brimraf(?:\.sync|Sync|\.native|\.rimraf)?\s*\(/;
|
|
203
|
+
const RIMRAF_PATH = /\brimraf(?:\.sync|Sync|\.native|\.rimraf)?\s*\(\s*(['"`])([^'"`]*)\1/g;
|
|
204
|
+
|
|
205
|
+
// Where a script deletes a tree, however the path reaches it. Empty means it does not.
|
|
206
|
+
const recursiveDeletes = (program: string): CommandSpan[] => spansOf(globally([NODE_RECURSIVE_RM, RIMRAF]), program);
|
|
207
|
+
|
|
208
|
+
// The literal paths a script hands to a recursive delete, each with its call. Empty when every path is computed, the
|
|
209
|
+
// honest answer: the class above still holds, only the root question goes unasked.
|
|
210
|
+
const nodeDeleteTargets = (program: string): { readonly target: string; readonly span: CommandSpan }[] =>
|
|
211
|
+
[...program.matchAll(NODE_RECURSIVE_RM_PATH), ...program.matchAll(RIMRAF_PATH)].map((match) => ({
|
|
212
|
+
target: match[2] as string,
|
|
213
|
+
span: { start: match.index, end: match.index + match[0].length },
|
|
214
|
+
}));
|
|
215
|
+
|
|
216
|
+
// Membership: does anything here bring the state back? A worktree, checkpoint or image restore doesn't count.
|
|
217
|
+
// A block device wiped or overwritten, independent of locus; dd only counts writing to it, not reading one.
|
|
218
|
+
const BLOCK_DEVICE = [
|
|
219
|
+
/\bmkfs(?:\.\w+)?\b/,
|
|
220
|
+
/\bwipefs\b/,
|
|
221
|
+
/\bblkdiscard\b/,
|
|
222
|
+
/\bsgdisk\b[^|;&]*\s(?:--zap-all|-Z)\b/,
|
|
223
|
+
/\bdd\b[^|;&]*\bof=(?:\/dev\/|['"`]\/dev\/)/,
|
|
224
|
+
/\bshred\b[^|;&]*\s\/dev\//,
|
|
225
|
+
// A redirect straight onto a disk device: the same wipe without the ceremony.
|
|
226
|
+
/>\s*\/dev\/(?:[shv]d[a-z]|nvme\d|disk\d|mmcblk\d)/,
|
|
227
|
+
];
|
|
228
|
+
|
|
229
|
+
// Container data, not image: ordinary here (the agent's own nested volumes); still hard-ruled on a real device.
|
|
230
|
+
const CONTAINER_STATE = [
|
|
231
|
+
/\b(?:docker|podman)\s+volume\s+(?:rm|remove|prune)\b/,
|
|
232
|
+
/\b(?:docker|podman)\s+system\s+prune\b/,
|
|
233
|
+
/\b(?:docker(?:\s+compose|-compose)?|podman-compose)\s+down\b[^|;&]*\s(?:-v\b|--volumes\b)/,
|
|
234
|
+
];
|
|
235
|
+
|
|
236
|
+
const recursiveForceRms = (command: string): CommandSpan[] =>
|
|
237
|
+
parseRm(command)
|
|
238
|
+
.filter((invocation) => invocation.recursive && invocation.force)
|
|
239
|
+
.map((invocation) => invocation.span);
|
|
240
|
+
|
|
241
|
+
// A recursive delete aimed at a root, in either spelling the gate is handed (shell or script). Which targets count as
|
|
242
|
+
// roots is the locus's answer.
|
|
243
|
+
const rootDeletes = (program: string, locus: CommandLocus): CommandSpan[] => [
|
|
244
|
+
...parseRm(program)
|
|
245
|
+
.filter((invocation) => invocation.recursive && invocation.force && invocation.operands.some((operand) => isRootTarget(operand, locus)))
|
|
246
|
+
.map((invocation) => invocation.span),
|
|
247
|
+
...nodeDeleteTargets(program)
|
|
248
|
+
.filter((delete_) => isRootTarget(delete_.target, locus))
|
|
249
|
+
.map((delete_) => delete_.span),
|
|
250
|
+
];
|
|
251
|
+
|
|
252
|
+
// The g twins, built once at load: a card is minted per command held, classify runs per command typed.
|
|
253
|
+
const GIT_DESTRUCTIVE_G = globally(GIT_DESTRUCTIVE);
|
|
254
|
+
const SECRET_REFERENCES_G = globally(SECRET_REFERENCES);
|
|
255
|
+
const CREDENTIAL_PATHS_G = globally(CREDENTIAL_PATHS);
|
|
256
|
+
const PACKAGE_PUBLISH_G = globally(PACKAGE_PUBLISH);
|
|
257
|
+
const NETWORK_OUTBOUND_G = globally(NETWORK_OUTBOUND);
|
|
258
|
+
const BLOCK_DEVICE_G = globally(BLOCK_DEVICE);
|
|
259
|
+
const CONTAINER_STATE_G = globally(CONTAINER_STATE);
|
|
260
|
+
|
|
261
|
+
// The word a matched fragment sits in, so the fact-check asks about the file the command would actually open, not the
|
|
262
|
+
// suffix that fired. A wrong guess just resolves to an unreadable path, the old behaviour, not a hole.
|
|
263
|
+
const WORD_EDGE = /[\s'"`;|&()]/;
|
|
264
|
+
const enclosingPath = (command: string, span: CommandSpan): string => {
|
|
265
|
+
let start = span.start;
|
|
266
|
+
while (start > 0 && !WORD_EDGE.test(command[start - 1] as string)) {
|
|
267
|
+
start -= 1;
|
|
268
|
+
}
|
|
269
|
+
let end = span.end;
|
|
270
|
+
while (end < command.length && !WORD_EDGE.test(command[end] as string)) {
|
|
271
|
+
end += 1;
|
|
272
|
+
}
|
|
273
|
+
return command
|
|
274
|
+
.slice(start, end)
|
|
275
|
+
.replace(/^-{1,2}[\w-]+=/, "")
|
|
276
|
+
.replace(/^[@<>=]+/, "");
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
// Tells a search pattern from a real path before trusting the table's filename guess: an escaped dot, a character
|
|
280
|
+
// class, or a class escape marks a regex, not a path, except on a Windows path spelled the same way.
|
|
281
|
+
const CHARACTER_CLASS = /\[[^\]]*\]/;
|
|
282
|
+
const CLASS_ESCAPE = /\\[wdsbWDSB](?!\w)/;
|
|
283
|
+
const ESCAPED_DOT = /\\\./;
|
|
284
|
+
const PATH_SEPARATOR = /\\\w/;
|
|
285
|
+
const namesAPattern = (word: string): boolean =>
|
|
286
|
+
CHARACTER_CLASS.test(word) || CLASS_ESCAPE.test(word) || (ESCAPED_DOT.test(word) && !PATH_SEPARATOR.test(word));
|
|
287
|
+
|
|
288
|
+
// Every secret reference plus every credential-shaped path the context didn't positively clear. Compared against
|
|
289
|
+
// `false`, not `true`: an `undefined` (could not check) must still count as a hit.
|
|
290
|
+
const credentialReads = (command: string, context: CommandContext): CommandSpan[] => [
|
|
291
|
+
...spansOf(SECRET_REFERENCES_G, command),
|
|
292
|
+
...spansOf(CREDENTIAL_PATHS_G, command).filter((span) => {
|
|
293
|
+
const word = enclosingPath(command, span);
|
|
294
|
+
return !namesAPattern(word) && context.holdsSecret?.(word) !== false;
|
|
295
|
+
}),
|
|
296
|
+
];
|
|
297
|
+
|
|
298
|
+
// One function per class; empty means the command is not in it, so membership and evidence are the same walk.
|
|
299
|
+
const MATCHES: Readonly<Record<CommandClass, (command: string, context: CommandContext) => CommandSpan[]>> = {
|
|
300
|
+
"git.destructive": (command) => spansOf(GIT_DESTRUCTIVE_G, command),
|
|
301
|
+
"files.destructive": (command) => [...recursiveForceRms(command), ...recursiveDeletes(command)],
|
|
302
|
+
"system.destructive": (command, context) => [...spansOf(BLOCK_DEVICE_G, command), ...rootDeletes(command, context.locus)],
|
|
303
|
+
"container.state": (command) => spansOf(CONTAINER_STATE_G, command),
|
|
304
|
+
"secrets.access": credentialReads,
|
|
305
|
+
"package.publish": (command) => spansOf(PACKAGE_PUBLISH_G, command),
|
|
306
|
+
"network.outbound": (command) => spansOf(NETWORK_OUTBOUND_G, command),
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
// Every class the command falls in, with its fragments, in the catalog's own order. `context` is now required: its
|
|
310
|
+
// locus decides what half the catalog means, and the inert scan runs once, shared by every class.
|
|
311
|
+
export const matchCommand = (command: string, context: CommandContext): CommandMatch[] => {
|
|
312
|
+
const regions = inertRegions(command);
|
|
313
|
+
return CommandClassSchema.options.flatMap((commandClass) => {
|
|
314
|
+
const spans = mergeSpans(MATCHES[commandClass](command, context));
|
|
315
|
+
return spans.length === 0 ? [] : [{ commandClass, spans, live: spans.some((span) => isLive(span, regions)) }];
|
|
316
|
+
});
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
// Every class the command falls in, for callers that only need a verdict (a rulebook consult, a scope switch).
|
|
320
|
+
export const classifyCommand = (command: string, context: CommandContext): CommandClass[] =>
|
|
321
|
+
matchCommand(command, context).map((match) => match.commandClass);
|
|
322
|
+
|
|
323
|
+
// What the card says the command would do. The class name is a settings key, not a sentence to show a person.
|
|
324
|
+
export const COMMAND_CLASS_LABELS: Readonly<Record<CommandClass, string>> = {
|
|
325
|
+
"git.destructive": "rewrite or discard git history",
|
|
326
|
+
"files.destructive": "delete files recursively",
|
|
327
|
+
"system.destructive": "wipe a disk, or delete a whole root directory",
|
|
328
|
+
"container.state": "delete a container volume or the data in it",
|
|
329
|
+
"secrets.access": "read credential material",
|
|
330
|
+
"package.publish": "publish or release a package",
|
|
331
|
+
"network.outbound": "send a request out to the internet",
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
// One fragment that fires a class, split so `code` is shell or script alone (highlightable) and `qualifier` carries
|
|
335
|
+
// what narrows it, in prose: a sentence with a command inside it is unhighlightable.
|
|
336
|
+
export interface CommandPattern {
|
|
337
|
+
/** The literal a shell or a script would carry. Highlightable on its own; never a sentence. */
|
|
338
|
+
readonly code: string;
|
|
339
|
+
/** What narrows it, or the spellings folded into it. Prose, and rendered as prose. */
|
|
340
|
+
readonly qualifier?: string;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// The catalog's patterns for the Safety page's human panel; one fragment per entry, not one line per regex.
|
|
344
|
+
export const COMMAND_CLASS_PATTERNS: Readonly<Record<CommandClass, readonly CommandPattern[]>> = {
|
|
345
|
+
"git.destructive": [
|
|
346
|
+
{ code: "git push --force", qualifier: "also -f and --force-with-lease" },
|
|
347
|
+
{ code: "git push --delete" },
|
|
348
|
+
{ code: "git reset --hard" },
|
|
349
|
+
{ code: "git clean -f" },
|
|
350
|
+
{ code: "git branch -D" },
|
|
351
|
+
{ code: "git filter-branch" },
|
|
352
|
+
],
|
|
353
|
+
"files.destructive": [
|
|
354
|
+
{ code: "rm -rf <path>" },
|
|
355
|
+
{ code: "fs.rm(<path>, { recursive: true })", qualifier: "also rmSync, rmdir, rmdirSync" },
|
|
356
|
+
{ code: "rimraf(<path>)" },
|
|
357
|
+
],
|
|
358
|
+
"system.destructive": [
|
|
359
|
+
{ code: "mkfs" },
|
|
360
|
+
{ code: "wipefs" },
|
|
361
|
+
{ code: "blkdiscard" },
|
|
362
|
+
{ code: "sgdisk --zap-all" },
|
|
363
|
+
{ code: "dd of=/dev/…" },
|
|
364
|
+
{ code: "shred /dev/…" },
|
|
365
|
+
{ code: "> /dev/sda" },
|
|
366
|
+
{ code: "rm -rf /", qualifier: "only when the target is a root, listed below" },
|
|
367
|
+
],
|
|
368
|
+
"container.state": [
|
|
369
|
+
{ code: "docker volume rm", qualifier: "also remove, prune, and podman for any of these" },
|
|
370
|
+
{ code: "docker system prune" },
|
|
371
|
+
{ code: "docker compose down -v" },
|
|
372
|
+
],
|
|
373
|
+
"secrets.access": [
|
|
374
|
+
{ code: "{{secret:NAME}}", qualifier: "a stored secret, used in the command itself" },
|
|
375
|
+
{ code: ".env" },
|
|
376
|
+
{ code: ".ssh/*" },
|
|
377
|
+
{ code: "id_rsa" },
|
|
378
|
+
{ code: ".aws/credentials" },
|
|
379
|
+
{ code: ".npmrc" },
|
|
380
|
+
{ code: ".git-credentials" },
|
|
381
|
+
],
|
|
382
|
+
"package.publish": [
|
|
383
|
+
{ code: "npm publish", qualifier: "also pnpm, yarn, bun" },
|
|
384
|
+
{ code: "cargo publish" },
|
|
385
|
+
{ code: "gh release create" },
|
|
386
|
+
{ code: "docker push" },
|
|
387
|
+
{ code: "twine upload" },
|
|
388
|
+
],
|
|
389
|
+
"network.outbound": [
|
|
390
|
+
{ code: "curl https://…", qualifier: "also wget; loopback does not count" },
|
|
391
|
+
{ code: 'fetch("https://…")', qualifier: "in a script" },
|
|
392
|
+
],
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
// No verdict set lives here: which classes stop a command is now a policy question, answered elsewhere.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { CommandRun } from "../schemas/ci.js";
|
|
2
|
+
|
|
3
|
+
// The heading over a settled run, shown both on the workspace card and in a phone notification, so the two must agree
|
|
4
|
+
// on wording. `subject` is what ran, in the clicked button's own words ("Checks", "Push", "Publish").
|
|
5
|
+
export interface FollowRunOptions<R extends CommandRun> {
|
|
6
|
+
// The wait between "is it done yet" questions.
|
|
7
|
+
readonly intervalMs: number;
|
|
8
|
+
// Stop following, not stop the run: resolves undefined rather than throwing.
|
|
9
|
+
readonly signal?: AbortSignal | undefined;
|
|
10
|
+
// Every state read, settled or not, for a surface that draws progress.
|
|
11
|
+
readonly onState?: ((run: R) => void) | undefined;
|
|
12
|
+
// A poll that failed, not a run that failed: the run is still going, and following continues.
|
|
13
|
+
readonly onError?: ((cause: unknown) => void) | undefined;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const sleep = (ms: number, signal: AbortSignal | undefined): Promise<void> =>
|
|
17
|
+
new Promise((resolve) => {
|
|
18
|
+
const timer = setTimeout(done, ms);
|
|
19
|
+
function done(): void {
|
|
20
|
+
clearTimeout(timer);
|
|
21
|
+
signal?.removeEventListener("abort", done);
|
|
22
|
+
resolve();
|
|
23
|
+
}
|
|
24
|
+
signal?.addEventListener("abort", done, { once: true });
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// Follows a run to its verdict: reads state until it is no longer running. The one shared loop, so a dropped poll isn't
|
|
28
|
+
// handled differently by every caller; reads once immediately, so an already-settled run returns without a wait.
|
|
29
|
+
export const followCommandRun = async <R extends CommandRun>(read: () => Promise<R>, options: FollowRunOptions<R>): Promise<R | undefined> => {
|
|
30
|
+
const { intervalMs, signal, onState, onError } = options;
|
|
31
|
+
for (;;) {
|
|
32
|
+
if (signal?.aborted === true) {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const run = await read();
|
|
37
|
+
onState?.(run);
|
|
38
|
+
if (run.status !== "running") {
|
|
39
|
+
return run;
|
|
40
|
+
}
|
|
41
|
+
} catch (cause) {
|
|
42
|
+
onError?.(cause);
|
|
43
|
+
}
|
|
44
|
+
await sleep(intervalMs, signal);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const commandRunOutcome = (run: Pick<CommandRun, "status" | "timedOut">, subject: string): string => {
|
|
49
|
+
if (run.timedOut === true) {
|
|
50
|
+
return `${subject} timed out`;
|
|
51
|
+
}
|
|
52
|
+
switch (run.status) {
|
|
53
|
+
case "error":
|
|
54
|
+
return `${subject} couldn't run`;
|
|
55
|
+
case "cancelled":
|
|
56
|
+
return `${subject} stopped`;
|
|
57
|
+
case "failed":
|
|
58
|
+
return `${subject} failed`;
|
|
59
|
+
case "passed":
|
|
60
|
+
return `${subject} passed`;
|
|
61
|
+
default:
|
|
62
|
+
// idle reaches a card only when the command was cleared between click and request; it says so.
|
|
63
|
+
return `${subject} didn't run`;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
// One shared list (daemon, OpenAPI, site, mint form); widens downward except editor, its own narrow slice.
|
|
4
|
+
export const CONTROL_SCOPES = ["editor", "read", "drive", "land"] as const;
|
|
5
|
+
export type ControlScope = (typeof CONTROL_SCOPES)[number];
|
|
6
|
+
export const ControlScopeSchema = z.enum(CONTROL_SCOPES);
|
|
7
|
+
|
|
8
|
+
export interface ControlScopeReach {
|
|
9
|
+
readonly scope: ControlScope;
|
|
10
|
+
// What a token at this rung reaches, in one sentence a person minting one can act on.
|
|
11
|
+
readonly reach: string;
|
|
12
|
+
// The reason the rung exists, or the cost of holding it.
|
|
13
|
+
readonly note: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Derived in the daemon from the same role floors a member holds (read=viewer, drive=collaborator).
|
|
17
|
+
export const CONTROL_SCOPE_REACH: readonly ControlScopeReach[] = [
|
|
18
|
+
{
|
|
19
|
+
scope: "editor",
|
|
20
|
+
reach: "One conversation: run a turn, answer a card it parked on, read transcripts, search the tree.",
|
|
21
|
+
note: "What an editor bridge holds. It cannot see the fleet and it cannot land work.",
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
scope: "read",
|
|
25
|
+
reach: "Everything a viewer sees: the fleet, transcripts, files, git state, CI runs, listening ports. Changes nothing.",
|
|
26
|
+
note: "The one genuinely narrow rung, which is why it exists separately rather than as a politeness.",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
scope: "drive",
|
|
30
|
+
reach: "Everything read sees, plus what a collaborator does: start, answer, steer and stop turns, rename and archive agents.",
|
|
31
|
+
note: "Stops short of anything that moves code into the main tree. A stolen token at this rung is the agent's reach.",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
scope: "land",
|
|
35
|
+
reach: "Everything drive does, plus merging a conversation's worktree into the main tree, and discarding or purging one.",
|
|
36
|
+
note: "Separate because the usual arrangement is a program that works and a person who decides.",
|
|
37
|
+
},
|
|
38
|
+
];
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { describe, expect, test } from "vitest";
|
|
2
2
|
import { holdsCredentialMaterial, maskCredentialMaterial } from "./credential-material.js";
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* are the ones that have to be exactly right, and every "yes" case is a real file's real shape. */
|
|
4
|
+
// The two directions aren't symmetric: a miss just raises an extra card, a wrong clear un-gates a real credential read.
|
|
5
|
+
// The "no" cases have to be exactly right; every "yes" case is a real file's real shape.
|
|
7
6
|
|
|
8
7
|
describe("files that hold a credential", () => {
|
|
9
8
|
test("an npmrc with a token", () => {
|
|
@@ -27,8 +26,6 @@ describe("files that hold a credential", () => {
|
|
|
27
26
|
}
|
|
28
27
|
});
|
|
29
28
|
|
|
30
|
-
// `.git-credentials` is nothing but these lines, and a dotenv hides the same secret inside a connection
|
|
31
|
-
// string, where no key names it.
|
|
32
29
|
test("a password carried in a URL", () => {
|
|
33
30
|
expect(holdsCredentialMaterial("https://radarsu:ghp_S8kQ2mVx@github.com\n")).toBe(true);
|
|
34
31
|
expect(holdsCredentialMaterial("DATABASE_URL=postgres://app:Rk29fPqz@db.internal:5432/app\n")).toBe(true);
|
|
@@ -42,7 +39,6 @@ describe("files that hold a credential", () => {
|
|
|
42
39
|
expect(holdsCredentialMaterial('{"accessToken":"ya29.a0AfB_bJq2Lm","expiresAt":1767000000}')).toBe(true);
|
|
43
40
|
});
|
|
44
41
|
|
|
45
|
-
// The issuers whose tokens announce themselves, found without any key naming them.
|
|
46
42
|
test("a token that carries its own prefix", () => {
|
|
47
43
|
for (const text of [
|
|
48
44
|
"ghp_16C7e42F292c6912E7710c838347Ae178B4a",
|
|
@@ -56,8 +52,6 @@ describe("files that hold a credential", () => {
|
|
|
56
52
|
});
|
|
57
53
|
|
|
58
54
|
describe("files that do not", () => {
|
|
59
|
-
/* THE FILE THAT STARTED THIS. An npmrc is the most-named credential path in this workspace's own commands
|
|
60
|
-
* and most of them are three lines of registry config. */
|
|
61
55
|
test("an npmrc with only registry config", () => {
|
|
62
56
|
expect(holdsCredentialMaterial("registry=https://registry.npmjs.org/\nengine-strict=true\nstore-dir=/root/.pnpm-store\n")).toBe(
|
|
63
57
|
false,
|
|
@@ -68,8 +62,6 @@ describe("files that do not", () => {
|
|
|
68
62
|
expect(holdsCredentialMaterial("PORT=3000\nNODE_ENV=development\nVITE_API_URL=http://localhost:8080\nLOG_LEVEL=debug\n")).toBe(false);
|
|
69
63
|
});
|
|
70
64
|
|
|
71
|
-
/* THE TEMPLATE THAT IS STILL A TEMPLATE. A key named `TOKEN` proves nothing on its own — half the dotenvs
|
|
72
|
-
* in a monorepo are this file, waiting for someone to fill them in. */
|
|
73
65
|
test("a dotenv whose credential keys are still placeholders", () => {
|
|
74
66
|
expect(
|
|
75
67
|
holdsCredentialMaterial(
|
|
@@ -88,8 +80,6 @@ describe("files that do not", () => {
|
|
|
88
80
|
).toBe(false);
|
|
89
81
|
});
|
|
90
82
|
|
|
91
|
-
// The public half of a keypair, and the host list beside it: named in the same directory, credential
|
|
92
|
-
// material in neither.
|
|
93
83
|
test("the public files an ssh directory is full of", () => {
|
|
94
84
|
expect(holdsCredentialMaterial("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH1x radarsu@omen\n")).toBe(false);
|
|
95
85
|
expect(holdsCredentialMaterial("github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzr\n")).toBe(false);
|
|
@@ -102,8 +92,6 @@ describe("files that do not", () => {
|
|
|
102
92
|
);
|
|
103
93
|
});
|
|
104
94
|
|
|
105
|
-
// A dev default is a real password in the strictest reading and nothing this class exists to stop; the
|
|
106
|
-
// length floor is what draws that line.
|
|
107
95
|
test("a dev-compose default is not what the card is for", () => {
|
|
108
96
|
expect(holdsCredentialMaterial("POSTGRES_PASSWORD=dev\nREDIS_PASSWORD=x\n")).toBe(false);
|
|
109
97
|
});
|
|
@@ -113,15 +101,13 @@ describe("files that do not", () => {
|
|
|
113
101
|
expect(holdsCredentialMaterial("\n\n# nothing here\n")).toBe(false);
|
|
114
102
|
});
|
|
115
103
|
|
|
116
|
-
// A URL with a port is not a URL with a password: `user:pass@` needs both halves and the `@`.
|
|
117
104
|
test("an ordinary url is not userinfo", () => {
|
|
118
105
|
expect(holdsCredentialMaterial("API=http://localhost:8080/v1\nSENTRY_DSN=https://abc123@o1.ingest.sentry.io/1\n")).toBe(false);
|
|
119
106
|
});
|
|
120
107
|
});
|
|
121
108
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
* than protecting it. Every case below asserts both halves — the value is gone, the file is still readable. */
|
|
109
|
+
// The same table applied to masking, not detection: what matters is what SURVIVES (structure, keys, comments), since
|
|
110
|
+
// this runs over files an agent legitimately edits.
|
|
125
111
|
describe("masking what a credential file holds", () => {
|
|
126
112
|
test("a dotenv keeps its keys, its shape and its comments", () => {
|
|
127
113
|
const masked = maskCredentialMaterial(
|
|
@@ -130,9 +116,6 @@ describe("masking what a credential file holds", () => {
|
|
|
130
116
|
expect(masked).toBe(["# staging", "PORT=3000", "NODE_ENV=production", 'STRIPE_SECRET="***"', "MAX_TOKENS=8192"].join("\n"));
|
|
131
117
|
});
|
|
132
118
|
|
|
133
|
-
/* THE ROUND TRIP THE WHOLE THING RESTS ON. A deferred value holds no credential and is the one thing a
|
|
134
|
-
* rewritten file must come back with intact: masking `{{secret:X}}` would have the model paste `***` over
|
|
135
|
-
* this workspace's own convention for a file that must not hold a credential. */
|
|
136
119
|
test("a placeholder and a secret reference come back untouched", () => {
|
|
137
120
|
const template = ["GITHUB_TOKEN=", "NPM_TOKEN=${NPM_TOKEN}", "API_KEY=<your-api-key>", "STRIPE_SECRET={{secret:STRIPE}}"].join("\n");
|
|
138
121
|
expect(maskCredentialMaterial(template)).toBe(template);
|
|
@@ -143,14 +126,12 @@ describe("masking what a credential file holds", () => {
|
|
|
143
126
|
expect(masked).toBe("-----BEGIN OPENSSH PRIVATE KEY-----\n***\n-----END OPENSSH PRIVATE KEY-----\n");
|
|
144
127
|
});
|
|
145
128
|
|
|
146
|
-
// A connection string with the host blanked is one nobody can debug, and the host is not the secret.
|
|
147
129
|
test("a url keeps everything but the password", () => {
|
|
148
130
|
expect(maskCredentialMaterial("DATABASE_URL=postgres://app:Rk29fPqz@db.internal:5432/app\n")).toBe(
|
|
149
131
|
"DATABASE_URL=postgres://app:***@db.internal:5432/app\n",
|
|
150
132
|
);
|
|
151
133
|
});
|
|
152
134
|
|
|
153
|
-
// No key names these, and none is needed: the issuer is in the token.
|
|
154
135
|
test("an issued token goes wherever it appears", () => {
|
|
155
136
|
expect(maskCredentialMaterial("gh auth: ghp_16C7e42F292c6912E7710c838347Ae178B4a expired")).toBe("gh auth: *** expired");
|
|
156
137
|
expect(maskCredentialMaterial("//registry.npmjs.org/:_authToken=npm_wCq3nTvR8xLm2ZbKp7HdJyE4sUaF6gN0iQ1t")).toBe(
|
|
@@ -158,8 +139,6 @@ describe("masking what a credential file holds", () => {
|
|
|
158
139
|
);
|
|
159
140
|
});
|
|
160
141
|
|
|
161
|
-
/* WHAT IT MUST NOT TOUCH, the other half of the bargain: this pass only ever runs over a result whose input
|
|
162
|
-
* named a credential file, and such a file is still mostly configuration the model has to read. */
|
|
163
142
|
test("the ordinary contents of a config file survive", () => {
|
|
164
143
|
for (const text of [
|
|
165
144
|
"registry=https://registry.npmjs.org/\nengine-strict=true\n",
|
|
@@ -172,7 +151,6 @@ describe("masking what a credential file holds", () => {
|
|
|
172
151
|
}
|
|
173
152
|
});
|
|
174
153
|
|
|
175
|
-
// The point of the pass, stated as the property the gate now depends on: what comes back holds nothing.
|
|
176
154
|
test("what comes back no longer holds credential material", () => {
|
|
177
155
|
for (const text of [
|
|
178
156
|
"//registry.npmjs.org/:_authToken=npm_wCq3nTvR8xLm2ZbKp7HdJyE4sUaF6gN0iQ1t\n",
|