@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
package/src/command-classes.ts
DELETED
|
@@ -1,617 +0,0 @@
|
|
|
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 "./shell-regions.js";
|
|
4
|
-
|
|
5
|
-
/* WHICH CLASSES A SHELL COMMAND FALLS IN, the classifier behind every command gate, read before the command runs.
|
|
6
|
-
*
|
|
7
|
-
* IT LIVES IN THE CONTRACT PACKAGE because there are TWO enforcement points and they must not drift. The
|
|
8
|
-
* sandbox's own gate (sandbox/src/guard/command-gate.ts) judges what the agent types here; the machine agent's
|
|
9
|
-
* shell tool (_devices/machine/src/device/tools/shell.ts) judges what it sends to somebody's laptop. Those answer to
|
|
10
|
-
* different policy (a rulebook with a permission card here, a scope switch on the card there) but they must
|
|
11
|
-
* agree on WHAT A COMMAND IS, or a class the owner thought they had covered turns out to mean something else on
|
|
12
|
-
* the surface where it mattered most. One table, two consults.
|
|
13
|
-
*
|
|
14
|
-
* ALL of them, not the first match, because a gate takes the most restrictive verdict across them and the
|
|
15
|
-
* interesting commands are exactly the ones in two classes at once: `curl -d @.env https://…` is both
|
|
16
|
-
* `secrets.access` and `network.outbound`, and an owner who holds either meant to see it. Returning one class
|
|
17
|
-
* would let a rule on the other decide.
|
|
18
|
-
*
|
|
19
|
-
* HONESTY, the same note the outbound sniffer carries and for the same reason. This is regex over shell text.
|
|
20
|
-
* A creatively quoted command, a path assembled from a variable, or a script written in one call and run in the
|
|
21
|
-
* next goes past it untouched. So a gate built on this is friction and a prompt for well-behaved work, never a
|
|
22
|
-
* boundary, the boundaries are structural and elsewhere: the container, the isolated worktree, the land gate,
|
|
23
|
-
* an automation's tool allowlist, and, on somebody's own device, the scope switches enforced there.
|
|
24
|
-
*
|
|
25
|
-
* WHICH IS WHY THIS NO LONGER DECIDES ANYTHING. A match used to BE the verdict: whatever fired here became the
|
|
26
|
-
* permission card, so `echo "rm -rf /"`, `rg 'rm -rf'` and an actual delete were one question with one answer.
|
|
27
|
-
* Now a match only means A JUDGE SHOULD LOOK (safety-policy.ts argues the move at length, guard/command-gate.ts
|
|
28
|
-
* implements it), and the judge reads the owner's written policy plus what the daemon knows about the turn.
|
|
29
|
-
* That changes what these patterns should optimise for: being OVER-inclusive is close to free, because a false
|
|
30
|
-
* positive now costs one model call rather than one interruption, and a miss still costs everything. Anyone
|
|
31
|
-
* tuning a pattern below should widen rather than narrow it.
|
|
32
|
-
*
|
|
33
|
-
* WITH ONE EXCEPTION, AND IT IS WHY `live` EXISTS. The hard rule (safety-policy.ts hardRuleClasses) still turns
|
|
34
|
-
* a match straight into an interruption nothing can waive, so for the classes it covers a false positive costs
|
|
35
|
-
* exactly what it always did. That left the old failure standing in the one place it could not be argued out
|
|
36
|
-
* of: `echo "rm -rf /" >> notes.md` and `rg 'rm -rf /'` were un-waivable cards over a string. So every match
|
|
37
|
-
* carries whether a shell would RUN the fragment or merely print, search or write it (shell-regions.ts), and
|
|
38
|
-
* only the hard rule reads that bit. The tables stay over-inclusive; the un-waivable tier stops firing on text.
|
|
39
|
-
*
|
|
40
|
-
* AND IT IS ASKED OF A PLACE. `rm -rf /usr` ends a laptop and costs a container nothing, because a container is
|
|
41
|
-
* rebuilt from an image; a Docker volume here is a dev database the agent made and there is the owner's data.
|
|
42
|
-
* Half the tables below therefore have two answers, chosen by CommandContext.locus, and the caller must say
|
|
43
|
-
* which machine it is asking about. schemas/agent.ts CommandLocus argues the split.
|
|
44
|
-
*
|
|
45
|
-
* Matching is deliberately UNANCHORED, substrings, not line starts. Another PreToolUse hook may have rewrapped
|
|
46
|
-
* the command by the time this reads it (agent-terminals.ts wraps every Bash call in bin/tmux-run), and the
|
|
47
|
-
* agent's own line survives verbatim inside that wrapper. Nothing the wrapper adds is in any class below.
|
|
48
|
-
*
|
|
49
|
-
* `[^|;&]*` in a pattern keeps a flag tied to the verb before it, so a later command in a pipeline cannot lend
|
|
50
|
-
* its flags to an earlier one, `git push origin | grep -f patterns` is not a force-push.
|
|
51
|
-
*
|
|
52
|
-
* IT REPORTS WHERE, not just whether (matchCommand below). A permission card holding four hundred characters of
|
|
53
|
-
* shell has to answer one question before anything else on it can be read: which part of this is the part that
|
|
54
|
-
* stopped it. That answer only exists here, at the moment a pattern fires, and re-deriving it in the browser
|
|
55
|
-
* would be a second classifier with all the ways to disagree with this one. So every table hands back offsets
|
|
56
|
-
* and the card marks them; `classifyCommand` is the same walk with the offsets dropped.
|
|
57
|
-
*
|
|
58
|
-
* AND IT TAKES A FACT WHERE THE CALLER HAS ONE (CommandContext below). Every table here is a pattern over text,
|
|
59
|
-
* which is exactly the right instrument for a verb — `git push --force` means what it says, and no amount of
|
|
60
|
-
* looking at the repository makes it mean less. It is the WRONG instrument on its own for a class defined by a
|
|
61
|
-
* FILE: `secrets.access` fires on `~/.npmrc` because that path usually holds a token, and "usually" left this
|
|
62
|
-
* raising cards over registry config, over `.env` files holding a port number, over `~/.ssh/known_hosts`, and
|
|
63
|
-
* over files that were not there at all. Those cards are not near misses, they are noise, and noise is what
|
|
64
|
-
* teaches an owner to answer a card without reading it. A caller that can open the file (guard/credential-
|
|
65
|
-
* files.ts, on the sandbox that is about to run the command) answers the question the pattern could only guess
|
|
66
|
-
* at, and only ever in the direction of dropping a class it positively cleared — see credentialReads.
|
|
67
|
-
*/
|
|
68
|
-
|
|
69
|
-
// A half-open slice of the command text, in UTF-16 code units, the offsets a renderer slices with.
|
|
70
|
-
export interface CommandSpan {
|
|
71
|
-
readonly start: number;
|
|
72
|
-
readonly end: number;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/* One class the command fell in, and the fragments that put it there. `spans` is never empty: a class with
|
|
76
|
-
* nothing to point at is a class this walk does not report. */
|
|
77
|
-
export interface CommandMatch {
|
|
78
|
-
readonly commandClass: CommandClass;
|
|
79
|
-
readonly spans: readonly CommandSpan[];
|
|
80
|
-
/* Would a shell RUN any of those fragments, or are they all text — a heredoc body, a comment, a quoted
|
|
81
|
-
* argument to echo or a grep (shell-regions.ts says how that is decided and how wrong it is allowed to be)?
|
|
82
|
-
*
|
|
83
|
-
* ONLY THE HARD RULE READS THIS, and that is the whole point of it being a flag on the match rather than a
|
|
84
|
-
* filter over the tables. A mention still puts the command in the class, still reaches the judge, and is
|
|
85
|
-
* still marked on the card: the judge is the tier that can tell a README from a delete, and taking the
|
|
86
|
-
* class away would take the question away from it. What a mention must NOT do is trip the one tier that
|
|
87
|
-
* cannot be argued with, which is what `echo "rm -rf /" >> notes.md` used to do. */
|
|
88
|
-
readonly live: boolean;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/* WHAT THE CALLER CAN CHECK THAT THE PATTERNS CANNOT. Optional everywhere: absent ⇒ every table answers from
|
|
92
|
-
* the command text alone, which is what the browser, the machine agent and every test that does not care get. */
|
|
93
|
-
export interface CommandContext {
|
|
94
|
-
/* WHERE THIS COMMAND WOULD RUN, and it is the one field with no default. Half this catalog means something
|
|
95
|
-
* different on a disposable container than on somebody's laptop — which directories are roots, whether a
|
|
96
|
-
* Docker volume is a dev database or their data — and a default would be one of those two answers applied
|
|
97
|
-
* silently to the other machine. Callers state it; schemas/agent.ts CommandLocus argues the split. */
|
|
98
|
-
readonly locus: CommandLocus;
|
|
99
|
-
/* Does the file at this path — as the command spells it, `~/.npmrc`, `.env`, `/work/app/.env.local` — hold
|
|
100
|
-
* credential material? (credential-material.ts says what that means; the caller says how to read a file.)
|
|
101
|
-
*
|
|
102
|
-
* THREE ANSWERS, and the third is the important one. `true` ⇒ it does. `false` ⇒ it was opened and read and
|
|
103
|
-
* there is no credential in it, or there is no such file. `undefined` ⇒ COULD NOT TELL: a path built from a
|
|
104
|
-
* variable, a glob, a directory, a file on another machine, an unreadable one. Only `false` drops a class;
|
|
105
|
-
* a rule that fell back to "no" whenever nobody could look would be a rule that quietly stopped applying
|
|
106
|
-
* exactly where checking was hardest. */
|
|
107
|
-
readonly holdsSecret?: (path: string) => boolean | undefined;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/* The `g` twin of a table's patterns, built once. The tables are written WITHOUT `g` because a lastIndex that
|
|
111
|
-
* survives a call is the classic way a shared regex starts skipping every other match, and `test` is what the
|
|
112
|
-
* verdict path wants. `matchAll` demands one, so the twins live here instead of being flagged in place.
|
|
113
|
-
* (`matchAll` clones the regex it is given, so these stay stateless too.) */
|
|
114
|
-
const globally = (patterns: readonly RegExp[]): readonly RegExp[] => patterns.map((pattern) => new RegExp(pattern.source, `${pattern.flags}g`));
|
|
115
|
-
|
|
116
|
-
// Every occurrence of every pattern, as spans over `command`. The WHOLE match, not a capture group: a pattern
|
|
117
|
-
// here is written to span the consequence (`git push … --force`, `curl … https://`), and cutting it back to a
|
|
118
|
-
// group would point at the flag while leaving the verb it belongs to unmarked.
|
|
119
|
-
const spansOf = (patterns: readonly RegExp[], command: string): CommandSpan[] =>
|
|
120
|
-
patterns.flatMap((pattern) => [...command.matchAll(pattern)].map((match) => ({ start: match.index, end: match.index + match[0].length })));
|
|
121
|
-
|
|
122
|
-
/* Sorted, with overlaps folded together. Two patterns firing on one fragment is ordinary here (a script's
|
|
123
|
-
* recursive delete matches both the with-a-literal-path pattern and the any-path one), and handing a renderer
|
|
124
|
-
* overlapping ranges makes it either double-paint or reinvent this. Adjacency is NOT merged: touching spans
|
|
125
|
-
* from genuinely different fragments read correctly as two marks.
|
|
126
|
-
*
|
|
127
|
-
* EXPORTED because a caller that marks SEVERAL classes at once needs it too, and the overlap it has to fold is
|
|
128
|
-
* across classes rather than within one: `rm -rf /work` is both files.destructive and system.destructive on the
|
|
129
|
-
* same characters, and a card that painted both would hand its renderer two ranges over one fragment. The
|
|
130
|
-
* command gate marks every matched class now (guard/command-gate.ts says why), so this is the second caller. */
|
|
131
|
-
export const mergeSpans = (spans: readonly CommandSpan[]): CommandSpan[] => {
|
|
132
|
-
const merged: CommandSpan[] = [];
|
|
133
|
-
for (const span of [...spans].sort((left, right) => left.start - right.start || left.end - right.end)) {
|
|
134
|
-
const last = merged.at(-1);
|
|
135
|
-
if (last !== undefined && span.start < last.end) {
|
|
136
|
-
merged[merged.length - 1] = { start: last.start, end: Math.max(last.end, span.end) };
|
|
137
|
-
continue;
|
|
138
|
-
}
|
|
139
|
-
merged.push(span);
|
|
140
|
-
}
|
|
141
|
-
return merged;
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
const GIT_DESTRUCTIVE = [
|
|
145
|
-
/\bgit\s+push\b[^|;&]*\s(?:-f\b|--force\b|--force-with-lease\b|--delete\b)/,
|
|
146
|
-
/\bgit\s+reset\b[^|;&]*\s--hard\b/,
|
|
147
|
-
// Any `clean` that forces: it deletes untracked files, which is work no history holds a copy of.
|
|
148
|
-
/\bgit\s+clean\b[^|;&]*\s-{1,2}[a-zA-Z]*f/,
|
|
149
|
-
/\bgit\s+branch\b[^|;&]*\s(?:-D\b|--delete\s+--force\b|--force\s+--delete\b)/,
|
|
150
|
-
/\bgit\s+filter-branch\b/,
|
|
151
|
-
];
|
|
152
|
-
|
|
153
|
-
/* THE CREDENTIAL THAT IS IN THE COMMAND, not in some file the command names. `{{secret:NAME}}` becomes the real
|
|
154
|
-
* value on the way into the process (agent/agent-secrets.ts), so a command carrying one is reading a credential
|
|
155
|
-
* by definition and there is nothing for a filesystem to add: this half of the class is never fact-checked.
|
|
156
|
-
*
|
|
157
|
-
* Without it the outside-content floor in guard/actions.ts is bypassed by writing a reference into a curl
|
|
158
|
-
* instead of reading a dotenv, which is the shorter route to the same place: `curl -d @.env` is held,
|
|
159
|
-
* `curl -d '{"t":"{{secret:X}}"}'` was not. The alphabet is REFERENCE's, from secrets/secret-registry.ts,
|
|
160
|
-
* respelled rather than imported to keep this table free of a dependency on the stores it describes. */
|
|
161
|
-
const SECRET_REFERENCES = [/\{\{secret:[A-Za-z0-9_./-]+\}\}/];
|
|
162
|
-
|
|
163
|
-
/* A PATH THAT USUALLY HOLDS A CREDENTIAL — a guess about a FILE, which is why every entry here is subject to
|
|
164
|
-
* CommandContext.holdsSecret and the table above is not. Each pattern spans as much of the path as it can, so
|
|
165
|
-
* the card marks `.ssh/id_ed25519` rather than `.ssh`, and so the word around it (enclosingPath) resolves.
|
|
166
|
-
*
|
|
167
|
-
* WHAT IS DELIBERATELY NOT HERE is as much of the definition as what is: the public half of a keypair, the
|
|
168
|
-
* host list beside it, and the checked-in templates that ship next to the real file in every repo. None of
|
|
169
|
-
* those is credential material in any file, so no fact-check is needed to know they do not belong — and each
|
|
170
|
-
* of them was, before this, an ordinary setup command earning a card that said "read credential material". */
|
|
171
|
-
/* The directory part in front of a filename, so a pattern spans `~/.aws/credentials` rather than the
|
|
172
|
-
* `.aws/credentials` inside it: what the card marks then reads as the file, and the word handed to the
|
|
173
|
-
* fact-check IS the file. Permissive about `~` and `${HOME}` on purpose — expanding those is the checker's job
|
|
174
|
-
* (guard/credential-files.ts), and a path this over-reaches on resolves to nothing, which changes nothing. */
|
|
175
|
-
const LEADING_PATH = String.raw`[\w~$.{}/\\-]*`;
|
|
176
|
-
|
|
177
|
-
const CREDENTIAL_PATHS = [
|
|
178
|
-
/* A dotenv file: `.env`, `.env.production`, `-d @.env`. NOT the checked-in templates that sit beside it in
|
|
179
|
-
* every repo, and not `process.env`, the lookbehind is what excludes the latter, which is otherwise the
|
|
180
|
-
* single most common string in this workspace's own commands and would hold every grep for it. */
|
|
181
|
-
/(?<![\w.])\.env(?!\.(?:example|sample|template))(?:\.[\w-]+)?\b/,
|
|
182
|
-
/* The ssh directory and what is under it, EXCEPT the three members that are public by design.
|
|
183
|
-
* `ssh-keyscan github.com >> ~/.ssh/known_hosts` is the first thing an agent does on a fresh box, `.pub` is
|
|
184
|
-
* the half of a keypair you are supposed to hand out, and `~/.ssh/config` is host aliases. The bare
|
|
185
|
-
* directory still counts (`cp -r ~/.ssh /tmp` is the copy that matters, and it names no file at all), which
|
|
186
|
-
* is why the lookaheads sit outside the optional path tail rather than inside it: an exclusion inside an
|
|
187
|
-
* optional group is one the regex backtracks around, matching `.ssh` and reporting the class anyway. */
|
|
188
|
-
/\.ssh(?!\w)(?!\/(?:known_hosts|config|authorized_keys|environment)(?!\w))(?!\/[\w.-]*\.pub(?!\w))(?:\/[\w.\-/]*)?/,
|
|
189
|
-
// A private key by its conventional name. `.pub` beside it is the public half and is not this.
|
|
190
|
-
/\bid_(?:rsa|dsa|ecdsa|ed25519)\b(?!\.pub\b)/,
|
|
191
|
-
new RegExp(String.raw`${LEADING_PATH}\.aws/credentials\b`),
|
|
192
|
-
// An npmrc, but not the checked-in template beside it — the `.env` exclusion, which this had been missing.
|
|
193
|
-
new RegExp(String.raw`${LEADING_PATH}\.npmrc(?!\.(?:example|sample|template))\b`),
|
|
194
|
-
new RegExp(String.raw`${LEADING_PATH}\.git-credentials\b`),
|
|
195
|
-
new RegExp(String.raw`${LEADING_PATH}\.credentials\.json\b`),
|
|
196
|
-
];
|
|
197
|
-
|
|
198
|
-
const PACKAGE_PUBLISH = [
|
|
199
|
-
/\b(?:npm|pnpm|yarn|bun)\s+publish\b/,
|
|
200
|
-
/\bcargo\s+publish\b/,
|
|
201
|
-
/\bgh\s+release\s+create\b/,
|
|
202
|
-
/\bdocker\s+push\b/,
|
|
203
|
-
/\btwine\s+upload\b/,
|
|
204
|
-
];
|
|
205
|
-
|
|
206
|
-
/* The loopback hosts, as a WHOLE HOST rather than a prefix. `localhost\b` reads as an exemption for
|
|
207
|
-
* `localhost.attacker.com`, because a `.` is a word boundary, and for `localhost@attacker.com`, where the
|
|
208
|
-
* loopback name is a URL's userinfo and curl connects to whatever follows the `@`. Either one is a host an
|
|
209
|
-
* attacker registers, so a prefix test hands it the exemption meant for this container talking to itself, and
|
|
210
|
-
* with it the outside-content envelope and the turn's taint bit: outsideSourceOf (guard/outside-results.ts) is
|
|
211
|
-
* built on this class, so a response judged loopback is never wrapped and never marks the turn. The trailing
|
|
212
|
-
* lookahead is what makes it a whole host, the port is optional, and a URL's authority can only end at one of
|
|
213
|
-
* `/?#`, whitespace, or a closing quote. */
|
|
214
|
-
const LOOPBACK = String.raw`(?:localhost|127\.0\.0\.1|0\.0\.0\.0|\[::1\])(?::\d+)?(?=[/?#\s'"\x60]|$)`;
|
|
215
|
-
|
|
216
|
-
// The sandbox talks to itself over loopback constantly, the host bridge, a dev server the agent just started,
|
|
217
|
-
// and none of that leaves the container, so the class is about reaching OUT rather than about curl.
|
|
218
|
-
const NETWORK_OUTBOUND = [
|
|
219
|
-
new RegExp(String.raw`\b(?:curl|wget)\b[^|;&]*\bhttps?://(?!${LOOPBACK})`),
|
|
220
|
-
/* The JS execution backend's curl: a literal non-loopback URL handed to `fetch(`. The classifier reads
|
|
221
|
-
* scripts with the same substring honesty it reads shell (the gate feeds it both, see command-gate's
|
|
222
|
-
* EXECUTION_SOURCES), so an owner's rule about reaching out covers both ways of doing it, and the
|
|
223
|
-
* outside-content seam wraps what a fetching script brings back exactly as it wraps a fetching curl's. A
|
|
224
|
-
* URL assembled at runtime walks past this, as the header already admits for shell variables. */
|
|
225
|
-
new RegExp(String.raw`\bfetch\(\s*['"\x60]https?://(?!${LOOPBACK})`),
|
|
226
|
-
];
|
|
227
|
-
|
|
228
|
-
/* --- rm, parsed once ------------------------------------------------------------------------------------
|
|
229
|
-
*
|
|
230
|
-
* ONE PARSE, TWO CLASSES. `rm -rf build` and `rm -rf /` are the same verb with the same flags and wildly
|
|
231
|
-
* different consequences, and the whole reason the second is a class of its own is that its default differs:
|
|
232
|
-
* deleting a build directory is ordinary work in a disposable container, and deleting the root it sits in is
|
|
233
|
-
* the thing nothing here undoes. Splitting them needs the OPERANDS, not just the flags, so the invocation is
|
|
234
|
-
* taken apart once and both classes read the same result rather than two regexes drifting apart.
|
|
235
|
-
*
|
|
236
|
-
* An invocation ends at a pipeline separator: everything after `|`, `;`, `&`, or a newline belongs to the next
|
|
237
|
-
* command and must not be read as this one's targets. */
|
|
238
|
-
const RM_INVOCATION = /\brm\s+([^|;&\n]*)/g;
|
|
239
|
-
|
|
240
|
-
interface RmInvocation {
|
|
241
|
-
readonly recursive: boolean;
|
|
242
|
-
readonly force: boolean;
|
|
243
|
-
readonly operands: readonly string[];
|
|
244
|
-
// Where this invocation sits in the command, so a card can point at `rm -rf /work` rather than at the whole
|
|
245
|
-
// line it was buried in. The invocation as matched, verb through last operand.
|
|
246
|
-
readonly span: CommandSpan;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// A shell word with its quoting removed, so `"/work"`, `'/work'` and `/work` are one operand and not three.
|
|
250
|
-
const unquote = (word: string): string => word.replace(/^['"`]|['"`]$/g, "");
|
|
251
|
-
|
|
252
|
-
const parseRm = (command: string): RmInvocation[] => {
|
|
253
|
-
const parsed: RmInvocation[] = [];
|
|
254
|
-
for (const invocation of command.matchAll(RM_INVOCATION)) {
|
|
255
|
-
let recursive = false;
|
|
256
|
-
let force = false;
|
|
257
|
-
const operands: string[] = [];
|
|
258
|
-
for (const word of (invocation[1] as string).trim().split(/\s+/)) {
|
|
259
|
-
if (word === "") {
|
|
260
|
-
continue;
|
|
261
|
-
}
|
|
262
|
-
// A long flag is one whole word; a short cluster is a bag of letters. `--force` must not be read as
|
|
263
|
-
// the letters f-o-r-c-e, or every `rm --force` would look recursive too.
|
|
264
|
-
if (word.startsWith("--")) {
|
|
265
|
-
recursive ||= word === "--recursive";
|
|
266
|
-
force ||= word === "--force";
|
|
267
|
-
continue;
|
|
268
|
-
}
|
|
269
|
-
if (word.startsWith("-")) {
|
|
270
|
-
recursive ||= /[rR]/.test(word);
|
|
271
|
-
force ||= word.includes("f");
|
|
272
|
-
continue;
|
|
273
|
-
}
|
|
274
|
-
operands.push(unquote(word));
|
|
275
|
-
}
|
|
276
|
-
parsed.push({ recursive, force, operands, span: { start: invocation.index, end: invocation.index + invocation[0].trimEnd().length } });
|
|
277
|
-
}
|
|
278
|
-
return parsed;
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
/* A TARGET THAT IS A ROOT RATHER THAN SOMETHING INSIDE ONE. This is the whole difference between the two
|
|
282
|
-
* deletion classes, so it is deliberately a short, closed list of whole names rather than a clever heuristic.
|
|
283
|
-
*
|
|
284
|
-
* AND IT IS A DIFFERENT LIST PER LOCUS, because "root" means "the thing nothing here brings back" and the two
|
|
285
|
-
* machines answer that very differently. Everything below is measured against one question: after this delete,
|
|
286
|
-
* what restores it?
|
|
287
|
-
*
|
|
288
|
-
* `/tmp` is deliberately absent from both. It is scratch by definition and emptying it is a chore, not an
|
|
289
|
-
* incident. */
|
|
290
|
-
|
|
291
|
-
/* IN THIS SANDBOX: two entries, and the shortness is the point rather than an oversight.
|
|
292
|
-
*
|
|
293
|
-
* `` the filesystem root itself (what trimTarget normalizes `/` to). Nothing restores it.
|
|
294
|
-
* /history every OTHER conversation's worktrees and logs. THIS turn cannot recreate them at any price,
|
|
295
|
-
* which is exactly what makes it a root here and the reason it outranks anything in /work.
|
|
296
|
-
*
|
|
297
|
-
* WHAT IS DELIBERATELY NOT HERE, and each was hard-ruled before this: `/usr`, `/etc`, `/bin`, `/var`, `/opt`
|
|
298
|
-
* and the rest of the container's OS come back with the image — recreating this sandbox is a documented
|
|
299
|
-
* operation, not a catastrophe. `/work` is a git worktree whose delta lands as uncommitted changes, and it is
|
|
300
|
-
* also the directory an agent has the most legitimate reason to clear. `/Users`, `/Applications`, `/System`,
|
|
301
|
-
* `/Library` and a Windows drive do not exist in this container at all, so holding them here bought nothing and
|
|
302
|
-
* cost a card. All of them are still files.destructive, still triaged, still judged — they have simply stopped
|
|
303
|
-
* being un-waivable. */
|
|
304
|
-
const SANDBOX_ROOTS = new Set(["", HISTORY_ROOT]);
|
|
305
|
-
|
|
306
|
-
/* ON THE OWNER'S OWN COMPUTER: the full list, because nothing there is rebuilt from an image and there is no
|
|
307
|
-
* checkpoint under any of it. The filesystem root, the top-level directories an OS keeps, both of this
|
|
308
|
-
* product's own trees (a device may be running one), a home directory however it is spelled, and a Windows
|
|
309
|
-
* drive. Unchanged from what this catalog held before the split. */
|
|
310
|
-
const DEVICE_ROOTS = new Set([
|
|
311
|
-
"",
|
|
312
|
-
WORKSPACE_ROOT,
|
|
313
|
-
HISTORY_ROOT,
|
|
314
|
-
"/home",
|
|
315
|
-
"/root",
|
|
316
|
-
"/etc",
|
|
317
|
-
"/usr",
|
|
318
|
-
"/var",
|
|
319
|
-
"/opt",
|
|
320
|
-
"/boot",
|
|
321
|
-
"/bin",
|
|
322
|
-
"/sbin",
|
|
323
|
-
"/lib",
|
|
324
|
-
"/lib64",
|
|
325
|
-
"/srv",
|
|
326
|
-
"/dev",
|
|
327
|
-
"/sys",
|
|
328
|
-
"/proc",
|
|
329
|
-
"/mnt",
|
|
330
|
-
"/media",
|
|
331
|
-
"/Users",
|
|
332
|
-
"/Applications",
|
|
333
|
-
"/System",
|
|
334
|
-
"/Library",
|
|
335
|
-
]);
|
|
336
|
-
|
|
337
|
-
const rootsAt = (locus: CommandLocus): ReadonlySet<string> => (locus === "sandbox" ? SANDBOX_ROOTS : DEVICE_ROOTS);
|
|
338
|
-
|
|
339
|
-
const HOME_ALIAS = /^(?:~|\$HOME|\$\{HOME\}|%USERPROFILE%)$/;
|
|
340
|
-
const WINDOWS_DRIVE = /^[A-Za-z]:$/;
|
|
341
|
-
|
|
342
|
-
/* `/work`, `/work/` and `/work/*` are one target said three ways: a trailing separator or wildcard says
|
|
343
|
-
* "everything in it", which is what deleting the directory means anyway. A BARE `*` is left alone on purpose,
|
|
344
|
-
* it is relative to whatever the shell is standing in, and `rm -rf *` in a build directory is the ordinary
|
|
345
|
-
* case this class exists to stay out of the way of. */
|
|
346
|
-
const trimTarget = (operand: string): string => operand.replace(/[/\\]\*+$/, "").replace(/[/\\]+$/, "");
|
|
347
|
-
|
|
348
|
-
const isRootTarget = (operand: string, locus: CommandLocus): boolean => {
|
|
349
|
-
const target = trimTarget(operand);
|
|
350
|
-
/* A home directory and a Windows drive are roots on a DEVICE only. In the container `~` is the agent's own
|
|
351
|
-
* scratch home, rebuilt with the image, and `C:` is not a path that exists. */
|
|
352
|
-
if (HOME_ALIAS.test(target) || WINDOWS_DRIVE.test(target)) {
|
|
353
|
-
return locus === "device";
|
|
354
|
-
}
|
|
355
|
-
// Only an absolute path can name a root, and `""` is the root itself. A relative path is inside whatever
|
|
356
|
-
// the shell is standing in, which this cannot know and must not guess about.
|
|
357
|
-
return target === "" ? operand.startsWith("/") || operand.startsWith("\\") : rootsAt(locus).has(target);
|
|
358
|
-
};
|
|
359
|
-
|
|
360
|
-
/* --- the JS execution backend's own deletes -------------------------------------------------------------
|
|
361
|
-
*
|
|
362
|
-
* THE SAME CONSEQUENCE, SPELLED IN NODE. The gate feeds this classifier the `mcp__code__run` script as well as
|
|
363
|
-
* the shell line (command-gate's EXECUTION_SOURCES), so `execSync("rm -rf /work")` inside a script already
|
|
364
|
-
* lands in the shell patterns above by substring. `fs.rmSync("/work", { recursive: true, force: true })` did
|
|
365
|
-
* not, and it is the shorter way to write the same afternoon's worth of lost work: the rule an owner wrote
|
|
366
|
-
* about deleting recursively has to mean the same thing on both backends or it does not mean much.
|
|
367
|
-
*
|
|
368
|
-
* RECURSIVE ALONE IS ENOUGH HERE, where the shell form needs recursive AND force. That is not an inconsistency:
|
|
369
|
-
* `rm -r` without `-f` stops on the first prompt and a script has no terminal to answer one, so the shell's
|
|
370
|
-
* recoverable spelling really is recoverable. `fs.rm(p, { recursive: true })` prompts nobody and deletes the
|
|
371
|
-
* tree, so the recoverable spelling does not exist on this side.
|
|
372
|
-
*
|
|
373
|
-
* TWO PATTERNS PER SPELLING, and the split matters: whether the script deletes recursively AT ALL is a
|
|
374
|
-
* different question from WHICH PATH it deletes, and only the first can be answered when the path is a
|
|
375
|
-
* variable. `rm(target, { recursive: true })` is files.destructive with no literal to read, and demanding one
|
|
376
|
-
* (as the first draft did) let exactly the ordinary way of writing it through.
|
|
377
|
-
*
|
|
378
|
-
* The header's honesty note applies here too, and one limit is worth naming: `[^)]*` cannot cross a closing
|
|
379
|
-
* paren, so `fs.rmSync(join(a, b), { recursive: true })` walks past. Same class of gap as a shell path built
|
|
380
|
-
* from a variable, and the same answer: this is friction for well-behaved work, not a boundary. */
|
|
381
|
-
const NODE_RECURSIVE_RM = /\b(?:rm|rmSync|rmdir|rmdirSync)\s*\([^)]*?recursive\s*:\s*true/;
|
|
382
|
-
const NODE_RECURSIVE_RM_PATH = /\b(?:rm|rmSync|rmdir|rmdirSync)\s*\(\s*(['"`])([^'"`]*)\1[^)]*?recursive\s*:\s*true/g;
|
|
383
|
-
// rimraf's whole purpose is the recursive force delete, so the call itself is the match; no options to read.
|
|
384
|
-
const RIMRAF = /\brimraf(?:\.sync|Sync|\.native|\.rimraf)?\s*\(/;
|
|
385
|
-
const RIMRAF_PATH = /\brimraf(?:\.sync|Sync|\.native|\.rimraf)?\s*\(\s*(['"`])([^'"`]*)\1/g;
|
|
386
|
-
|
|
387
|
-
// Where a script deletes a tree, however the path reaches it. Empty ⇒ it does not.
|
|
388
|
-
const recursiveDeletes = (program: string): CommandSpan[] => spansOf(globally([NODE_RECURSIVE_RM, RIMRAF]), program);
|
|
389
|
-
|
|
390
|
-
/* The literal paths a script hands to a recursive delete, each with the call it sits in. Empty when every path
|
|
391
|
-
* it deletes is computed, which is the honest answer rather than a guess: the class above already holds, only
|
|
392
|
-
* the root question goes unasked.
|
|
393
|
-
*
|
|
394
|
-
* The two `_PATH` patterns are already global, so they are used directly; matchAll clones them either way. */
|
|
395
|
-
const nodeDeleteTargets = (program: string): { readonly target: string; readonly span: CommandSpan }[] =>
|
|
396
|
-
[...program.matchAll(NODE_RECURSIVE_RM_PATH), ...program.matchAll(RIMRAF_PATH)].map((match) => ({
|
|
397
|
-
target: match[2] as string,
|
|
398
|
-
span: { start: match.index, end: match.index + match[0].length },
|
|
399
|
-
}));
|
|
400
|
-
|
|
401
|
-
/* --- state nothing brings back -------------------------------------------------------------------------
|
|
402
|
-
*
|
|
403
|
-
* THE CLASS WITH A FLOOR UNDER IT (guard/actions.ts commandRun holds it even where the owner wrote no rule),
|
|
404
|
-
* so its membership is chosen against a hard question: does anything in this product bring the state back?
|
|
405
|
-
*
|
|
406
|
-
* A worktree is restored from git, a checkpoint restores the tree, a container is recreated from its image,
|
|
407
|
-
* an npm package is re-installed. None of that reaches a formatted disk, a deleted Docker volume, or a home
|
|
408
|
-
* directory that is no longer there. Those are the members. Deliberately NOT members: `docker rm` (recreate
|
|
409
|
-
* it), `docker image prune` (pull it again), `git reset --hard` (that is git.destructive, and the reflog has
|
|
410
|
-
* it), `rm -rf node_modules` (install it again). The point of a floor is that it is rare enough to be worth
|
|
411
|
-
* stopping for; a floor that fires on ordinary work is one people learn to click through. */
|
|
412
|
-
/* A BLOCK DEVICE, FORMATTED, WIPED OR OVERWRITTEN. The only membership of system.destructive that does not
|
|
413
|
-
* depend on where the command runs: there is no image, checkpoint or worktree behind a disk at either locus,
|
|
414
|
-
* and this is what the shipped safety policy has always told the owner it holds unconditionally.
|
|
415
|
-
*
|
|
416
|
-
* `dd` only counts when it is pointed AT a device: reading one into a file is how an image is taken, and
|
|
417
|
-
* holding a backup would be exactly the wrong lesson. */
|
|
418
|
-
const BLOCK_DEVICE = [
|
|
419
|
-
/\bmkfs(?:\.\w+)?\b/,
|
|
420
|
-
/\bwipefs\b/,
|
|
421
|
-
/\bblkdiscard\b/,
|
|
422
|
-
/\bsgdisk\b[^|;&]*\s(?:--zap-all|-Z)\b/,
|
|
423
|
-
/\bdd\b[^|;&]*\bof=(?:\/dev\/|['"`]\/dev\/)/,
|
|
424
|
-
/\bshred\b[^|;&]*\s\/dev\//,
|
|
425
|
-
// A redirect straight onto a disk device, which is the same wipe without the ceremony.
|
|
426
|
-
/>\s*\/dev\/(?:[shv]d[a-z]|nvme\d|disk\d|mmcblk\d)/,
|
|
427
|
-
];
|
|
428
|
-
|
|
429
|
-
/* CONTAINER STATE THAT IS DATA RATHER THAN IMAGE, its own class (container.state) because the two loci
|
|
430
|
-
* disagree about it more sharply than about anything else in this catalog.
|
|
431
|
-
*
|
|
432
|
-
* IN THIS SANDBOX these reach the NESTED engine — the host's Docker socket is never mounted, see
|
|
433
|
-
* capabilities/handlers/docker.ts — so the volumes in reach are the ones the agent itself created, and tearing
|
|
434
|
-
* down a smoke-test stack it just brought up is ordinary work. Holding it as an un-waivable card was the
|
|
435
|
-
* concrete complaint that produced this split: `docker volume rm` on a throwaway test container is not the
|
|
436
|
-
* class of thing a person needs woken for.
|
|
437
|
-
*
|
|
438
|
-
* ON SOMEBODY'S OWN COMPUTER a named volume IS the database, and the owner's policy says never. It stays
|
|
439
|
-
* hard-ruled there (safety-policy.ts hardRuleClasses), and the machine's own `destructive` scope sits under
|
|
440
|
-
* that (machine/src/device/tools/shell.ts GATED_CLASSES), which is the part that is a boundary rather than
|
|
441
|
-
* friction. */
|
|
442
|
-
const CONTAINER_STATE = [
|
|
443
|
-
/\b(?:docker|podman)\s+volume\s+(?:rm|remove|prune)\b/,
|
|
444
|
-
/\b(?:docker|podman)\s+system\s+prune\b/,
|
|
445
|
-
/\b(?:docker(?:\s+compose|-compose)?|podman-compose)\s+down\b[^|;&]*\s(?:-v\b|--volumes\b)/,
|
|
446
|
-
];
|
|
447
|
-
|
|
448
|
-
const recursiveForceRms = (command: string): CommandSpan[] =>
|
|
449
|
-
parseRm(command)
|
|
450
|
-
.filter((invocation) => invocation.recursive && invocation.force)
|
|
451
|
-
.map((invocation) => invocation.span);
|
|
452
|
-
|
|
453
|
-
/* A recursive delete aimed at a root, in either spelling the gate can be handed: the shell's `rm -rf /` and
|
|
454
|
-
* the script's `fs.rmSync("/", { recursive: true })`. Which targets count as roots is the locus's answer, so
|
|
455
|
-
* `rm -rf /usr` is this class on a laptop and merely files.destructive in a container built from an image. */
|
|
456
|
-
const rootDeletes = (program: string, locus: CommandLocus): CommandSpan[] => [
|
|
457
|
-
...parseRm(program)
|
|
458
|
-
.filter((invocation) => invocation.recursive && invocation.force && invocation.operands.some((operand) => isRootTarget(operand, locus)))
|
|
459
|
-
.map((invocation) => invocation.span),
|
|
460
|
-
...nodeDeleteTargets(program)
|
|
461
|
-
.filter((delete_) => isRootTarget(delete_.target, locus))
|
|
462
|
-
.map((delete_) => delete_.span),
|
|
463
|
-
];
|
|
464
|
-
|
|
465
|
-
// The `g` twins, built once at load rather than per call: a card is minted per held command and a classify runs
|
|
466
|
-
// per command the agent types, so recompiling seven tables of patterns each time is work with no reader.
|
|
467
|
-
const GIT_DESTRUCTIVE_G = globally(GIT_DESTRUCTIVE);
|
|
468
|
-
const SECRET_REFERENCES_G = globally(SECRET_REFERENCES);
|
|
469
|
-
const CREDENTIAL_PATHS_G = globally(CREDENTIAL_PATHS);
|
|
470
|
-
const PACKAGE_PUBLISH_G = globally(PACKAGE_PUBLISH);
|
|
471
|
-
const NETWORK_OUTBOUND_G = globally(NETWORK_OUTBOUND);
|
|
472
|
-
const BLOCK_DEVICE_G = globally(BLOCK_DEVICE);
|
|
473
|
-
const CONTAINER_STATE_G = globally(CONTAINER_STATE);
|
|
474
|
-
|
|
475
|
-
/* THE PATH A MATCHED FRAGMENT SITS IN, so the oracle is asked about the file the command would actually open
|
|
476
|
-
* rather than about the suffix that fired: `sed 's/…/' ~/.npmrc` fires on `.npmrc` and must ask about
|
|
477
|
-
* `~/.npmrc`, `curl -d @.env` fires on `.env` and must ask about `.env`.
|
|
478
|
-
*
|
|
479
|
-
* The shell word around the span, widened to whitespace or a separator on both sides, with the decoration a
|
|
480
|
-
* shell puts in FRONT of a path removed: a redirect's arrow, curl's `@` file-body marker, a `--flag=` prefix.
|
|
481
|
-
*
|
|
482
|
-
* DELIBERATELY DUMB, and it can afford to be: a word this gets wrong resolves to a path the caller cannot read,
|
|
483
|
-
* which is `undefined`, which leaves the class exactly where the pattern put it. The failure mode is the old
|
|
484
|
-
* behaviour, not a hole. */
|
|
485
|
-
const WORD_EDGE = /[\s'"`;|&()]/;
|
|
486
|
-
const enclosingPath = (command: string, span: CommandSpan): string => {
|
|
487
|
-
let start = span.start;
|
|
488
|
-
while (start > 0 && !WORD_EDGE.test(command[start - 1] as string)) {
|
|
489
|
-
start -= 1;
|
|
490
|
-
}
|
|
491
|
-
let end = span.end;
|
|
492
|
-
while (end < command.length && !WORD_EDGE.test(command[end] as string)) {
|
|
493
|
-
end += 1;
|
|
494
|
-
}
|
|
495
|
-
return command
|
|
496
|
-
.slice(start, end)
|
|
497
|
-
.replace(/^-{1,2}[\w-]+=/, "")
|
|
498
|
-
.replace(/^[@<>=]+/, "");
|
|
499
|
-
};
|
|
500
|
-
|
|
501
|
-
/* A WORD THAT IS A PATTERN RATHER THAN A PATH, dropped before the table's guess about a FILE is believed at all.
|
|
502
|
-
*
|
|
503
|
-
* The table reads shell text looking for filenames, and a search command carries something that looks exactly
|
|
504
|
-
* like one and is not: `rg 'process\.env\.(INTENTIC_[A-Z]+)' --type ts .` names no file and opens nothing, and
|
|
505
|
-
* it earned a card reading "this command would read credential material" over a grep of this workspace's own
|
|
506
|
-
* source. The `.env` in it survives the dotenv pattern's `process.env` exclusion for one reason: the lookbehind
|
|
507
|
-
* sees the REGEX'S BACKSLASH rather than the `s` of `process`, and a backslash is neither a word character nor a
|
|
508
|
-
* dot. Every credential-shaped name has the same hole — `rg '\.npmrc'`, `rg '\.ssh/id_ed25519'` — so it is fixed
|
|
509
|
-
* once here rather than seven times in the table.
|
|
510
|
-
*
|
|
511
|
-
* THE ESCAPED DOT IS THE TELL. `\.` is how a regex spells a literal dot, and a POSIX path never needs it. The
|
|
512
|
-
* one thing that spells `\.` and IS a path is Windows (`type C:\Users\me\.env`), which the machine agent's shell
|
|
513
|
-
* really does see — and there the other backslashes are SEPARATORS, each followed by a path segment rather than
|
|
514
|
-
* by the character it escapes. That is the whole discrimination.
|
|
515
|
-
*
|
|
516
|
-
* A CHARACTER CLASS and a CLASS ESCAPE are the other two tells, and both are nearly free: `[…]` is legal in a
|
|
517
|
-
* filename and never in one anybody writes, and `\w`, `\d`, `\b` mean nothing to a shell. The class escapes are
|
|
518
|
-
* matched only where a word character does NOT follow, which is what keeps `\dev` and `\swap` (Windows
|
|
519
|
-
* directories) out of them. The word edges (WORD_EDGE) already cut a word at the `(`, `|` and quotes carrying
|
|
520
|
-
* the rest of a regex's syntax, so these are what is left of it by the time a word reaches here.
|
|
521
|
-
*
|
|
522
|
-
* Judged on the ENCLOSING WORD, the same word the fact-check would have asked the filesystem about, so a
|
|
523
|
-
* pattern and a path are told apart once and both consults see the same answer. */
|
|
524
|
-
const CHARACTER_CLASS = /\[[^\]]*\]/;
|
|
525
|
-
const CLASS_ESCAPE = /\\[wdsbWDSB](?!\w)/;
|
|
526
|
-
const ESCAPED_DOT = /\\\./;
|
|
527
|
-
const PATH_SEPARATOR = /\\\w/;
|
|
528
|
-
const namesAPattern = (word: string): boolean =>
|
|
529
|
-
CHARACTER_CLASS.test(word) || CLASS_ESCAPE.test(word) || (ESCAPED_DOT.test(word) && !PATH_SEPARATOR.test(word));
|
|
530
|
-
|
|
531
|
-
/* WHERE A COMMAND READS CREDENTIAL MATERIAL: every secret reference in it, plus every credential-shaped path the
|
|
532
|
-
* context did not positively clear.
|
|
533
|
-
*
|
|
534
|
-
* `!== false` is the whole fact-check, and the comparison is written against `false` rather than for `true` on
|
|
535
|
-
* purpose: `undefined` (nobody could look) has to behave like `true` (there is a credential in there), or the
|
|
536
|
-
* class would evaporate on every caller without a filesystem. */
|
|
537
|
-
const credentialReads = (command: string, context: CommandContext): CommandSpan[] => [
|
|
538
|
-
...spansOf(SECRET_REFERENCES_G, command),
|
|
539
|
-
...spansOf(CREDENTIAL_PATHS_G, command).filter((span) => {
|
|
540
|
-
const word = enclosingPath(command, span);
|
|
541
|
-
return !namesAPattern(word) && context.holdsSecret?.(word) !== false;
|
|
542
|
-
}),
|
|
543
|
-
];
|
|
544
|
-
|
|
545
|
-
// WHERE each class fires, one entry per class. Empty ⇒ the command is not in it, so membership and evidence are
|
|
546
|
-
// the same walk and cannot disagree: there is no way to be held for a class with nothing to show for it.
|
|
547
|
-
const MATCHES: Readonly<Record<CommandClass, (command: string, context: CommandContext) => CommandSpan[]>> = {
|
|
548
|
-
"git.destructive": (command) => spansOf(GIT_DESTRUCTIVE_G, command),
|
|
549
|
-
"files.destructive": (command) => [...recursiveForceRms(command), ...recursiveDeletes(command)],
|
|
550
|
-
"system.destructive": (command, context) => [...spansOf(BLOCK_DEVICE_G, command), ...rootDeletes(command, context.locus)],
|
|
551
|
-
"container.state": (command) => spansOf(CONTAINER_STATE_G, command),
|
|
552
|
-
"secrets.access": credentialReads,
|
|
553
|
-
"package.publish": (command) => spansOf(PACKAGE_PUBLISH_G, command),
|
|
554
|
-
"network.outbound": (command) => spansOf(NETWORK_OUTBOUND_G, command),
|
|
555
|
-
};
|
|
556
|
-
|
|
557
|
-
/* Every class the command falls in AND the fragments that put it there, in the catalog's own order so a card and
|
|
558
|
-
* a log name them the same way twice. The primitive; classifyCommand is this with the offsets dropped.
|
|
559
|
-
*
|
|
560
|
-
* `context` is REQUIRED, unlike before: its `locus` decides what half of this catalog means (see
|
|
561
|
-
* CommandContext), and the fact-check is the optional part of it.
|
|
562
|
-
*
|
|
563
|
-
* THE INERT SCAN RUNS ONCE, here, and is handed to every class rather than being redone per table: it walks the
|
|
564
|
-
* whole command, and seven walks would be six more than the answer needs. A class with no live span is still
|
|
565
|
-
* reported — `live` rides on the match and only the hard rule reads it (shell-regions.ts argues why). */
|
|
566
|
-
export const matchCommand = (command: string, context: CommandContext): CommandMatch[] => {
|
|
567
|
-
const regions = inertRegions(command);
|
|
568
|
-
return CommandClassSchema.options.flatMap((commandClass) => {
|
|
569
|
-
const spans = mergeSpans(MATCHES[commandClass](command, context));
|
|
570
|
-
return spans.length === 0 ? [] : [{ commandClass, spans, live: spans.some((span) => isLive(span, regions)) }];
|
|
571
|
-
});
|
|
572
|
-
};
|
|
573
|
-
|
|
574
|
-
// Every class the command falls in, for the callers that only take a verdict from it (the gate's rulebook
|
|
575
|
-
// consult, the machine agent's scope switch).
|
|
576
|
-
export const classifyCommand = (command: string, context: CommandContext): CommandClass[] =>
|
|
577
|
-
matchCommand(command, context).map((match) => match.commandClass);
|
|
578
|
-
|
|
579
|
-
// What the card says the command would DO. The class name is a settings key, not a sentence to show a person.
|
|
580
|
-
export const COMMAND_CLASS_LABELS: Readonly<Record<CommandClass, string>> = {
|
|
581
|
-
"git.destructive": "rewrite or discard git history",
|
|
582
|
-
"files.destructive": "delete files recursively",
|
|
583
|
-
"system.destructive": "wipe a disk, or delete a whole root directory",
|
|
584
|
-
"container.state": "delete a container volume or the data in it",
|
|
585
|
-
"secrets.access": "read credential material",
|
|
586
|
-
"package.publish": "publish or release a package",
|
|
587
|
-
"network.outbound": "send a request out to the internet",
|
|
588
|
-
};
|
|
589
|
-
|
|
590
|
-
/* THE PATTERNS BEHIND EACH CLASS, IN WORDS, for the one reader that is a person rather than a gate: the Safety
|
|
591
|
-
* page's "What gets stopped" panel (editor/web/.../AgentSafetyRules.vue). A card says which class fired; this
|
|
592
|
-
* says what the class is, so an owner can see the whole catalog without reading this file.
|
|
593
|
-
*
|
|
594
|
-
* PROSE RATHER THAN THE REGEXES THEMSELVES, deliberately. A `/\b(?:docker|podman)\s+volume\s+(?:rm|remove|prune)\b/`
|
|
595
|
-
* on a settings page is a worse answer to "what stops my commands" than "docker volume rm, remove, prune" is,
|
|
596
|
-
* and rendering source at somebody implies they can edit it. Pinned to the tables by the conformance test in
|
|
597
|
-
* command-classes.test.ts, so a pattern added without a line here fails the suite rather than going unlisted. */
|
|
598
|
-
export const COMMAND_CLASS_PATTERNS: Readonly<Record<CommandClass, readonly string[]>> = {
|
|
599
|
-
"git.destructive": ["git push --force / -f / --force-with-lease / --delete", "git reset --hard", "git clean -f", "git branch -D", "git filter-branch"],
|
|
600
|
-
"files.destructive": ["rm -rf <path>", "fs.rm / rmSync / rmdir with recursive: true", "rimraf(<path>)"],
|
|
601
|
-
"system.destructive": [
|
|
602
|
-
"mkfs, wipefs, blkdiscard, sgdisk --zap-all",
|
|
603
|
-
"dd of=/dev/…, shred /dev/…, > /dev/sda",
|
|
604
|
-
"rm -rf aimed at a root directory",
|
|
605
|
-
],
|
|
606
|
-
"container.state": ["docker / podman volume rm, remove, prune", "docker / podman system prune", "docker compose down -v"],
|
|
607
|
-
"secrets.access": ["a {{secret:NAME}} reference in the command", ".env, .ssh/*, id_rsa, .aws/credentials, .npmrc, .git-credentials"],
|
|
608
|
-
"package.publish": ["npm / pnpm / yarn / bun publish", "cargo publish", "gh release create", "docker push", "twine upload"],
|
|
609
|
-
"network.outbound": ["curl / wget to a non-loopback https:// host", 'fetch("https://…") in a script'],
|
|
610
|
-
};
|
|
611
|
-
|
|
612
|
-
/* No verdict set lives here any more. Which classes are worth stopping for is a POLICY question now, and it is
|
|
613
|
-
* answered in two places that are honest about being different: safety-policy.ts's hardRuleClasses for the
|
|
614
|
-
* things nothing recovers at a given locus, and the owner's own written policy for everything else. The machine
|
|
615
|
-
* agent keeps its own set beside its scope switches (machine/src/device/tools/shell.ts), because "which
|
|
616
|
-
* commands need the destructive switch" is a question about that capability card rather than about this
|
|
617
|
-
* catalog. */
|