@intentic/sandbox-contract 1.248.0 → 1.249.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -15
- package/dist/chores/chores.d.ts.map +1 -1
- package/dist/chores/chores.js.map +1 -1
- package/dist/chores/digest.d.ts.map +1 -1
- package/dist/chores/digest.js.map +1 -1
- package/dist/chores/extension-update.d.ts.map +1 -1
- package/dist/chores/extension-update.js.map +1 -1
- package/dist/chores/fix-deps.d.ts.map +1 -1
- package/dist/chores/fix-deps.js.map +1 -1
- package/dist/chores/index.d.ts +2 -2
- package/dist/chores/index.d.ts.map +1 -1
- package/dist/chores/index.js +1 -1
- package/dist/chores/index.js.map +1 -1
- package/dist/chores/probes.d.ts.map +1 -1
- package/dist/chores/probes.js.map +1 -1
- package/dist/chores/prompt.d.ts.map +1 -1
- package/dist/chores/prompt.js.map +1 -1
- package/dist/chores/stack.d.ts.map +1 -1
- package/dist/chores/stack.js.map +1 -1
- package/dist/chores/verdict.d.ts +7 -1
- package/dist/chores/verdict.d.ts.map +1 -1
- package/dist/chores/verdict.js +8 -0
- package/dist/chores/verdict.js.map +1 -1
- package/dist/contracts/accounts.contract.d.ts.map +1 -1
- package/dist/contracts/accounts.contract.js.map +1 -1
- package/dist/contracts/activity.contract.d.ts +1 -0
- package/dist/contracts/activity.contract.d.ts.map +1 -1
- package/dist/contracts/agent.contract.d.ts +12 -205
- package/dist/contracts/agent.contract.d.ts.map +1 -1
- package/dist/contracts/agent.contract.js +2 -1
- package/dist/contracts/agent.contract.js.map +1 -1
- package/dist/contracts/agents.contract.d.ts +228 -54
- package/dist/contracts/agents.contract.d.ts.map +1 -1
- package/dist/contracts/agents.contract.js +11 -2
- package/dist/contracts/agents.contract.js.map +1 -1
- package/dist/contracts/automations.contract.d.ts +35 -17
- package/dist/contracts/automations.contract.d.ts.map +1 -1
- package/dist/contracts/automations.contract.js +10 -1
- package/dist/contracts/automations.contract.js.map +1 -1
- package/dist/contracts/capabilities.contract.d.ts +0 -12
- package/dist/contracts/capabilities.contract.d.ts.map +1 -1
- package/dist/contracts/capabilities.contract.js +1 -1
- package/dist/contracts/capabilities.contract.js.map +1 -1
- package/dist/contracts/chores.contract.d.ts.map +1 -1
- package/dist/contracts/chores.contract.js.map +1 -1
- package/dist/contracts/ci.contract.d.ts +9 -0
- package/dist/contracts/ci.contract.d.ts.map +1 -1
- package/dist/contracts/endpoints.contract.d.ts.map +1 -1
- package/dist/contracts/endpoints.contract.js.map +1 -1
- package/dist/contracts/exit.contract.d.ts.map +1 -1
- package/dist/contracts/exit.contract.js +1 -1
- package/dist/contracts/exit.contract.js.map +1 -1
- package/dist/contracts/extensions.contract.d.ts.map +1 -1
- package/dist/contracts/extensions.contract.js.map +1 -1
- package/dist/contracts/git.contract.d.ts +45 -6
- package/dist/contracts/git.contract.d.ts.map +1 -1
- package/dist/contracts/git.contract.js +9 -9
- package/dist/contracts/git.contract.js.map +1 -1
- package/dist/contracts/host.contract.d.ts +2 -0
- package/dist/contracts/host.contract.d.ts.map +1 -1
- package/dist/contracts/host.contract.js.map +1 -1
- package/dist/contracts/intentic.contract.js +1 -1
- package/dist/contracts/intentic.contract.js.map +1 -1
- package/dist/contracts/logs.contract.d.ts.map +1 -1
- package/dist/contracts/logs.contract.js.map +1 -1
- package/dist/contracts/loops.contract.d.ts.map +1 -1
- package/dist/contracts/loops.contract.js.map +1 -1
- package/dist/contracts/personas.contract.d.ts +1 -0
- package/dist/contracts/personas.contract.d.ts.map +1 -1
- package/dist/contracts/personas.contract.js +1 -1
- package/dist/contracts/personas.contract.js.map +1 -1
- package/dist/contracts/providers.contract.d.ts.map +1 -1
- package/dist/contracts/providers.contract.js.map +1 -1
- package/dist/contracts/runner.contract.d.ts +97 -171
- package/dist/contracts/runner.contract.d.ts.map +1 -1
- package/dist/contracts/runner.contract.js +2 -2
- package/dist/contracts/runner.contract.js.map +1 -1
- package/dist/contracts/safety.contract.d.ts.map +1 -1
- package/dist/contracts/safety.contract.js +1 -1
- package/dist/contracts/safety.contract.js.map +1 -1
- package/dist/contracts/secrets.contract.d.ts.map +1 -1
- package/dist/contracts/secrets.contract.js.map +1 -1
- package/dist/contracts/sessions.contract.d.ts +2 -41
- package/dist/contracts/sessions.contract.d.ts.map +1 -1
- package/dist/contracts/sessions.contract.js +1 -1
- package/dist/contracts/sessions.contract.js.map +1 -1
- package/dist/contracts/settings.contract.d.ts +8 -18
- package/dist/contracts/settings.contract.d.ts.map +1 -1
- package/dist/contracts/settings.contract.js.map +1 -1
- package/dist/contracts/share.contract.d.ts.map +1 -1
- package/dist/contracts/share.contract.js.map +1 -1
- package/dist/contracts/skills.contract.d.ts.map +1 -1
- package/dist/contracts/skills.contract.js.map +1 -1
- package/dist/contracts/system.contract.d.ts +49 -73
- package/dist/contracts/system.contract.d.ts.map +1 -1
- package/dist/contracts/system.contract.js +12 -2
- package/dist/contracts/system.contract.js.map +1 -1
- package/dist/contracts/usage.contract.d.ts.map +1 -1
- package/dist/contracts/usage.contract.js.map +1 -1
- package/dist/contracts/vpn.contract.d.ts.map +1 -1
- package/dist/contracts/vpn.contract.js +1 -1
- package/dist/contracts/vpn.contract.js.map +1 -1
- package/dist/contracts/webext.contract.d.ts.map +1 -1
- package/dist/contracts/webext.contract.js.map +1 -1
- package/dist/contracts/workflows.contract.d.ts +7 -6
- package/dist/contracts/workflows.contract.d.ts.map +1 -1
- package/dist/contracts/workflows.contract.js +12 -3
- package/dist/contracts/workflows.contract.js.map +1 -1
- package/dist/contracts/workspace.contract.d.ts.map +1 -1
- package/dist/contracts/workspace.contract.js.map +1 -1
- package/dist/events/agent-events.d.ts +1237 -0
- package/dist/events/agent-events.d.ts.map +1 -0
- package/dist/events/agent-events.js +226 -0
- package/dist/events/agent-events.js.map +1 -0
- package/dist/events/cards.d.ts +404 -0
- package/dist/events/cards.d.ts.map +1 -0
- package/dist/events/cards.js +179 -0
- package/dist/events/cards.js.map +1 -0
- package/dist/events/resume.d.ts +23 -0
- package/dist/events/resume.d.ts.map +1 -0
- package/dist/events/resume.js +31 -0
- package/dist/events/resume.js.map +1 -0
- package/dist/events/system-events.d.ts +615 -0
- package/dist/events/system-events.d.ts.map +1 -0
- package/dist/events/system-events.js +64 -0
- package/dist/events/system-events.js.map +1 -0
- package/dist/events/transcript.d.ts +1755 -0
- package/dist/events/transcript.d.ts.map +1 -0
- package/dist/events/transcript.js +205 -0
- package/dist/events/transcript.js.map +1 -0
- package/dist/ids/conversation-ids.d.ts +8 -0
- package/dist/ids/conversation-ids.d.ts.map +1 -0
- package/dist/{conversation-ids.js → ids/conversation-ids.js} +13 -0
- package/dist/ids/conversation-ids.js.map +1 -0
- package/dist/ids/hostnames.d.ts.map +1 -0
- package/dist/ids/hostnames.js.map +1 -0
- package/dist/ids/session-names.d.ts.map +1 -0
- package/dist/ids/session-names.js.map +1 -0
- package/dist/ids/share-paths.d.ts.map +1 -0
- package/dist/ids/share-paths.js.map +1 -0
- package/dist/{tunnel-ids.d.ts → ids/tunnel-ids.d.ts} +1 -0
- package/dist/ids/tunnel-ids.d.ts.map +1 -0
- package/dist/{tunnel-ids.js → ids/tunnel-ids.js} +1 -0
- package/dist/ids/tunnel-ids.js.map +1 -0
- package/dist/index.d.ts +423 -450
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +54 -46
- package/dist/index.js.map +1 -1
- package/dist/{agent-catalog.d.ts → models/agent-catalog.d.ts} +2 -2
- package/dist/models/agent-catalog.d.ts.map +1 -0
- package/dist/models/agent-catalog.js.map +1 -0
- package/dist/models/agent-runtimes.d.ts.map +1 -0
- package/dist/models/agent-runtimes.js.map +1 -0
- package/dist/{fast-tier.d.ts → models/fast-tier.d.ts} +1 -1
- package/dist/models/fast-tier.d.ts.map +1 -0
- package/dist/models/fast-tier.js.map +1 -0
- package/dist/models/model-order.d.ts.map +1 -0
- package/dist/models/model-order.js.map +1 -0
- package/dist/{model-pins.d.ts → models/model-pins.d.ts} +1 -1
- package/dist/models/model-pins.d.ts.map +1 -0
- package/dist/models/model-pins.js.map +1 -0
- package/dist/{model-roles.d.ts → models/model-roles.d.ts} +0 -33
- package/dist/models/model-roles.d.ts.map +1 -0
- package/dist/{model-roles.js → models/model-roles.js} +0 -35
- package/dist/models/model-roles.js.map +1 -0
- package/dist/{plan-pools.d.ts → models/plan-pools.d.ts} +1 -1
- package/dist/models/plan-pools.d.ts.map +1 -0
- package/dist/models/plan-pools.js.map +1 -0
- package/dist/models/prompt-complexity.d.ts.map +1 -0
- package/dist/models/prompt-complexity.js.map +1 -0
- package/dist/models/provider-specs.d.ts.map +1 -0
- package/dist/models/provider-specs.js.map +1 -0
- package/dist/policy/approvals-execution.d.ts.map +1 -0
- package/dist/policy/approvals-execution.js.map +1 -0
- package/dist/{batch-runs.d.ts → policy/batch-runs.d.ts} +5 -1
- package/dist/policy/batch-runs.d.ts.map +1 -0
- package/dist/{batch-runs.js → policy/batch-runs.js} +10 -7
- package/dist/policy/batch-runs.js.map +1 -0
- package/dist/policy/capability-env.d.ts.map +1 -0
- package/dist/policy/capability-env.js.map +1 -0
- package/dist/policy/capability-secrets.d.ts.map +1 -0
- package/dist/policy/capability-secrets.js.map +1 -0
- package/dist/{card-status.d.ts → policy/card-status.d.ts} +2 -2
- package/dist/policy/card-status.d.ts.map +1 -0
- package/dist/{card-status.js → policy/card-status.js} +1 -5
- package/dist/policy/card-status.js.map +1 -0
- package/dist/{command-classes.d.ts → policy/command-classes.d.ts} +6 -2
- package/dist/policy/command-classes.d.ts.map +1 -0
- package/dist/{command-classes.js → policy/command-classes.js} +48 -11
- package/dist/policy/command-classes.js.map +1 -0
- package/dist/{command-run.d.ts → policy/command-run.d.ts} +1 -1
- package/dist/policy/command-run.d.ts.map +1 -0
- package/dist/policy/command-run.js.map +1 -0
- package/dist/policy/control-scopes.d.ts +16 -0
- package/dist/policy/control-scopes.d.ts.map +1 -0
- package/dist/policy/control-scopes.js +26 -0
- package/dist/policy/control-scopes.js.map +1 -0
- package/dist/policy/credential-material.d.ts.map +1 -0
- package/dist/policy/credential-material.js.map +1 -0
- package/dist/policy/needs-action.d.ts.map +1 -0
- package/dist/policy/needs-action.js.map +1 -0
- package/dist/policy/output-fields.d.ts.map +1 -0
- package/dist/policy/output-fields.js.map +1 -0
- package/dist/policy/overlay-lint.d.ts.map +1 -0
- package/dist/policy/overlay-lint.js.map +1 -0
- package/dist/policy/owner-ticket.d.ts.map +1 -0
- package/dist/{owner-ticket.js → policy/owner-ticket.js} +1 -1
- package/dist/policy/owner-ticket.js.map +1 -0
- package/dist/{safety-policy.d.ts → policy/safety-policy.d.ts} +6 -5
- package/dist/policy/safety-policy.d.ts.map +1 -0
- package/dist/{safety-policy.js → policy/safety-policy.js} +12 -12
- package/dist/policy/safety-policy.js.map +1 -0
- package/dist/policy/search-globs.d.ts.map +1 -0
- package/dist/policy/search-globs.js.map +1 -0
- package/dist/protocol/container-requirements.d.ts +20 -0
- package/dist/protocol/container-requirements.d.ts.map +1 -0
- package/dist/protocol/container-requirements.js +23 -0
- package/dist/protocol/container-requirements.js.map +1 -0
- package/dist/{host-protocol.d.ts → protocol/host-protocol.d.ts} +1 -0
- package/dist/protocol/host-protocol.d.ts.map +1 -0
- package/dist/{host-protocol.js → protocol/host-protocol.js} +1 -0
- package/dist/protocol/host-protocol.js.map +1 -0
- package/dist/protocol/ingress-contract.d.ts.map +1 -0
- package/dist/{ingress-contract.js → protocol/ingress-contract.js} +1 -1
- package/dist/protocol/ingress-contract.js.map +1 -0
- package/dist/protocol/ingress-protocol.d.ts.map +1 -0
- package/dist/protocol/ingress-protocol.js.map +1 -0
- package/dist/protocol/listener-protocol.d.ts.map +1 -0
- package/dist/{listener-protocol.js → protocol/listener-protocol.js} +1 -1
- package/dist/protocol/listener-protocol.js.map +1 -0
- package/dist/{peer-dial.d.ts → protocol/peer-dial.d.ts} +4 -1
- package/dist/protocol/peer-dial.d.ts.map +1 -0
- package/dist/{peer-dial.js → protocol/peer-dial.js} +51 -10
- package/dist/protocol/peer-dial.js.map +1 -0
- package/dist/protocol/peer-mcp-server.d.ts.map +1 -0
- package/dist/protocol/peer-mcp-server.js.map +1 -0
- package/dist/protocol/request-id.d.ts.map +1 -0
- package/dist/protocol/request-id.js.map +1 -0
- package/dist/protocol/routes.d.ts.map +1 -0
- package/dist/protocol/routes.js.map +1 -0
- package/dist/{runner-protocol.d.ts → protocol/runner-protocol.d.ts} +1 -0
- package/dist/protocol/runner-protocol.d.ts.map +1 -0
- package/dist/{runner-protocol.js → protocol/runner-protocol.js} +2 -1
- package/dist/protocol/runner-protocol.js.map +1 -0
- package/dist/protocol/sse.d.ts.map +1 -0
- package/dist/protocol/sse.js.map +1 -0
- package/dist/{terminal-protocol.d.ts → protocol/terminal-protocol.d.ts} +1 -3
- package/dist/protocol/terminal-protocol.d.ts.map +1 -0
- package/dist/protocol/terminal-protocol.js.map +1 -0
- package/dist/protocol/webext-links.d.ts.map +1 -0
- package/dist/protocol/webext-links.js.map +1 -0
- package/dist/{webext-protocol.d.ts → protocol/webext-protocol.d.ts} +1 -0
- package/dist/protocol/webext-protocol.d.ts.map +1 -0
- package/dist/{webext-protocol.js → protocol/webext-protocol.js} +1 -0
- package/dist/protocol/webext-protocol.js.map +1 -0
- package/dist/schemas/activity.d.ts +2 -0
- package/dist/schemas/activity.d.ts.map +1 -1
- package/dist/schemas/activity.js +4 -0
- package/dist/schemas/activity.js.map +1 -1
- package/dist/schemas/agent.d.ts +16 -4
- package/dist/schemas/agent.d.ts.map +1 -1
- package/dist/schemas/agent.js +21 -4
- package/dist/schemas/agent.js.map +1 -1
- package/dist/schemas/agents.d.ts +17 -4
- package/dist/schemas/agents.d.ts.map +1 -1
- package/dist/schemas/agents.js +15 -4
- package/dist/schemas/agents.js.map +1 -1
- package/dist/schemas/approvals.d.ts.map +1 -1
- package/dist/schemas/approvals.js.map +1 -1
- package/dist/schemas/automations.d.ts +54 -28
- package/dist/schemas/automations.d.ts.map +1 -1
- package/dist/schemas/automations.js +26 -8
- package/dist/schemas/automations.js.map +1 -1
- package/dist/schemas/capabilities.d.ts +0 -8
- package/dist/schemas/capabilities.d.ts.map +1 -1
- package/dist/schemas/capabilities.js +0 -4
- package/dist/schemas/capabilities.js.map +1 -1
- package/dist/schemas/ci.d.ts +10 -0
- package/dist/schemas/ci.d.ts.map +1 -1
- package/dist/schemas/ci.js +9 -1
- package/dist/schemas/ci.js.map +1 -1
- package/dist/schemas/codebase-health.d.ts.map +1 -1
- package/dist/schemas/codebase-health.js.map +1 -1
- package/dist/schemas/devices.d.ts +90 -0
- package/dist/schemas/devices.d.ts.map +1 -1
- package/dist/schemas/devices.js +10 -1
- package/dist/schemas/devices.js.map +1 -1
- package/dist/schemas/engines.d.ts.map +1 -1
- package/dist/schemas/engines.js.map +1 -1
- package/dist/schemas/environment.d.ts.map +1 -1
- package/dist/schemas/environment.js.map +1 -1
- package/dist/schemas/exit.d.ts.map +1 -1
- package/dist/schemas/exit.js.map +1 -1
- package/dist/schemas/extension-updates.d.ts.map +1 -1
- package/dist/schemas/extension-updates.js.map +1 -1
- package/dist/schemas/git-history.d.ts.map +1 -1
- package/dist/schemas/git-history.js.map +1 -1
- package/dist/schemas/git.d.ts +80 -16
- package/dist/schemas/git.d.ts.map +1 -1
- package/dist/schemas/git.js +37 -25
- package/dist/schemas/git.js.map +1 -1
- package/dist/schemas/history.d.ts.map +1 -1
- package/dist/schemas/history.js.map +1 -1
- package/dist/schemas/hosts.d.ts.map +1 -1
- package/dist/schemas/hosts.js.map +1 -1
- package/dist/schemas/inventory.d.ts.map +1 -1
- package/dist/schemas/inventory.js.map +1 -1
- package/dist/schemas/issues.d.ts +0 -1
- package/dist/schemas/issues.d.ts.map +1 -1
- package/dist/schemas/issues.js +0 -1
- package/dist/schemas/issues.js.map +1 -1
- package/dist/schemas/logs.d.ts.map +1 -1
- package/dist/schemas/logs.js.map +1 -1
- package/dist/schemas/loops.d.ts.map +1 -1
- package/dist/schemas/loops.js +1 -1
- package/dist/schemas/loops.js.map +1 -1
- package/dist/schemas/maintenance.d.ts.map +1 -1
- package/dist/schemas/maintenance.js.map +1 -1
- package/dist/schemas/marketplace.d.ts +0 -4
- package/dist/schemas/marketplace.d.ts.map +1 -1
- package/dist/schemas/panels.d.ts.map +1 -1
- package/dist/schemas/panels.js.map +1 -1
- package/dist/schemas/personas.d.ts +2 -1
- package/dist/schemas/personas.d.ts.map +1 -1
- package/dist/schemas/personas.js +6 -2
- package/dist/schemas/personas.js.map +1 -1
- package/dist/schemas/plan-limits.d.ts +2 -4
- package/dist/schemas/plan-limits.d.ts.map +1 -1
- package/dist/schemas/plan-limits.js +5 -8
- package/dist/schemas/plan-limits.js.map +1 -1
- package/dist/schemas/ports.d.ts.map +1 -1
- package/dist/schemas/ports.js.map +1 -1
- package/dist/schemas/provider-oauth.d.ts.map +1 -1
- package/dist/schemas/provider-oauth.js.map +1 -1
- package/dist/schemas/provider-subscriptions.d.ts +1 -1
- package/dist/schemas/provider-subscriptions.d.ts.map +1 -1
- package/dist/schemas/provider-subscriptions.js +1 -1
- package/dist/schemas/provider-subscriptions.js.map +1 -1
- package/dist/schemas/public.d.ts.map +1 -1
- package/dist/schemas/public.js.map +1 -1
- package/dist/schemas/push.d.ts.map +1 -1
- package/dist/schemas/push.js.map +1 -1
- package/dist/schemas/secrets.d.ts.map +1 -1
- package/dist/schemas/secrets.js.map +1 -1
- package/dist/schemas/settings.d.ts +6 -9
- package/dist/schemas/settings.d.ts.map +1 -1
- package/dist/schemas/settings.js +16 -5
- package/dist/schemas/settings.js.map +1 -1
- package/dist/schemas/share.d.ts.map +1 -1
- package/dist/schemas/share.js.map +1 -1
- package/dist/schemas/shared.d.ts +4 -0
- package/dist/schemas/shared.d.ts.map +1 -1
- package/dist/schemas/shared.js +3 -0
- package/dist/schemas/shared.js.map +1 -1
- package/dist/schemas/system.d.ts +6 -0
- package/dist/schemas/system.d.ts.map +1 -1
- package/dist/schemas/system.js +10 -0
- package/dist/schemas/system.js.map +1 -1
- package/dist/schemas/terminal.d.ts.map +1 -1
- package/dist/schemas/terminal.js.map +1 -1
- package/dist/schemas/usage.d.ts.map +1 -1
- package/dist/schemas/usage.js.map +1 -1
- package/dist/schemas/vpn.d.ts.map +1 -1
- package/dist/schemas/vpn.js.map +1 -1
- package/dist/schemas/webext.d.ts.map +1 -1
- package/dist/schemas/webext.js.map +1 -1
- package/dist/schemas/workflows.d.ts +66 -9
- package/dist/schemas/workflows.d.ts.map +1 -1
- package/dist/schemas/workflows.js +6 -5
- package/dist/schemas/workflows.js.map +1 -1
- package/dist/schemas/workspace-repos.d.ts.map +1 -1
- package/dist/schemas/workspace-repos.js.map +1 -1
- package/dist/schemas/workspace-search.d.ts.map +1 -1
- package/dist/schemas/workspace-search.js.map +1 -1
- package/dist/schemas/workspace-setup.d.ts.map +1 -1
- package/dist/schemas/workspace-setup.js.map +1 -1
- package/dist/schemas/workspace-tree.d.ts.map +1 -1
- package/dist/schemas/workspace-tree.js.map +1 -1
- package/dist/state/arrival.d.ts.map +1 -0
- package/dist/{arrival.js → state/arrival.js} +1 -1
- package/dist/state/arrival.js.map +1 -0
- package/dist/state/contract-lock.d.ts.map +1 -0
- package/dist/{contract-lock.js → state/contract-lock.js} +1 -1
- package/dist/state/contract-lock.js.map +1 -0
- package/dist/{definition.d.ts → state/definition.d.ts} +21 -17
- package/dist/state/definition.d.ts.map +1 -0
- package/dist/{definition.js → state/definition.js} +4 -4
- package/dist/state/definition.js.map +1 -0
- package/dist/state/history-state.d.ts.map +1 -0
- package/dist/{history-state.js → state/history-state.js} +1 -0
- package/dist/state/history-state.js.map +1 -0
- package/dist/state/runtime-state.d.ts.map +1 -0
- package/dist/state/runtime-state.js.map +1 -0
- package/dist/state/starter.d.ts.map +1 -0
- package/dist/state/starter.js.map +1 -0
- package/dist/state/state-portability.d.ts.map +1 -0
- package/dist/state/state-portability.js.map +1 -0
- package/dist/state/versions.d.ts.map +1 -0
- package/dist/state/versions.js.map +1 -0
- package/dist/{workspace-state.d.ts → state/workspace-state.d.ts} +8 -0
- package/dist/state/workspace-state.d.ts.map +1 -0
- package/dist/{workspace-state.js → state/workspace-state.js} +25 -0
- package/dist/state/workspace-state.js.map +1 -0
- package/dist/{documents.d.ts → text/documents.d.ts} +1 -1
- package/dist/text/documents.d.ts.map +1 -0
- package/dist/{documents.js → text/documents.js} +1 -1
- package/dist/text/documents.js.map +1 -0
- package/dist/text/embed.d.ts.map +1 -0
- package/dist/text/embed.js.map +1 -0
- package/dist/text/mentions.d.ts.map +1 -0
- package/dist/text/mentions.js.map +1 -0
- package/dist/text/model-answer.d.ts +3 -0
- package/dist/text/model-answer.d.ts.map +1 -0
- package/dist/text/model-answer.js +3 -0
- package/dist/text/model-answer.js.map +1 -0
- package/dist/text/path-refs.d.ts.map +1 -0
- package/dist/text/path-refs.js.map +1 -0
- package/dist/{shell-regions.d.ts → text/shell-regions.d.ts} +1 -1
- package/dist/text/shell-regions.d.ts.map +1 -0
- package/dist/text/shell-regions.js.map +1 -0
- package/dist/text/title.d.ts.map +1 -0
- package/dist/text/title.js.map +1 -0
- package/dist/{transcript-fold.d.ts → text/transcript-fold.d.ts} +2 -1
- package/dist/text/transcript-fold.d.ts.map +1 -0
- package/dist/{transcript-fold.js → text/transcript-fold.js} +2 -16
- package/dist/text/transcript-fold.js.map +1 -0
- package/dist/text/whisper.d.ts +3 -0
- package/dist/text/whisper.d.ts.map +1 -0
- package/dist/text/whisper.js +11 -0
- package/dist/text/whisper.js.map +1 -0
- package/dist/{workflow-faults.d.ts → text/workflow-faults.d.ts} +1 -1
- package/dist/text/workflow-faults.d.ts.map +1 -0
- package/dist/{workflow-faults.js → text/workflow-faults.js} +1 -1
- package/dist/text/workflow-faults.js.map +1 -0
- package/package.json +70 -70
- package/src/chores/chores.test.ts +4 -10
- package/src/chores/chores.ts +148 -392
- package/src/chores/digest.ts +8 -28
- package/src/chores/extension-update.ts +3 -8
- package/src/chores/fix-deps.ts +4 -18
- package/src/chores/index.ts +2 -2
- package/src/chores/probes.test.ts +7 -43
- package/src/chores/probes.ts +62 -167
- package/src/chores/prompt.ts +10 -34
- package/src/chores/stack.test.ts +6 -45
- package/src/chores/stack.ts +27 -118
- package/src/chores/verdict.test.ts +101 -80
- package/src/chores/verdict.ts +54 -99
- package/src/contracts/accounts.contract.ts +4 -19
- package/src/contracts/agent.contract.ts +7 -22
- package/src/contracts/agents.contract.ts +25 -71
- package/src/contracts/automations.contract.ts +14 -30
- package/src/contracts/capabilities.contract.ts +8 -35
- package/src/contracts/chores.contract.ts +4 -15
- package/src/contracts/endpoints.contract.ts +5 -22
- package/src/contracts/exit.contract.ts +7 -30
- package/src/contracts/extensions.contract.ts +8 -30
- package/src/contracts/git.contract.ts +25 -49
- package/src/contracts/host.contract.ts +9 -44
- package/src/contracts/intentic.contract.ts +1 -1
- package/src/contracts/logs.contract.ts +3 -13
- package/src/contracts/loops.contract.ts +9 -40
- package/src/contracts/personas.contract.ts +10 -35
- package/src/contracts/providers.contract.ts +4 -17
- package/src/contracts/runner.contract.ts +12 -39
- package/src/contracts/safety.contract.ts +5 -14
- package/src/contracts/secrets.contract.ts +4 -22
- package/src/contracts/sessions.contract.ts +1 -1
- package/src/contracts/settings.contract.ts +4 -10
- package/src/contracts/share.contract.ts +3 -9
- package/src/contracts/skills.contract.ts +4 -15
- package/src/contracts/system.contract.ts +26 -52
- package/src/contracts/usage.contract.ts +7 -21
- package/src/contracts/vpn.contract.ts +9 -16
- package/src/contracts/webext.contract.ts +9 -25
- package/src/contracts/workflows.contract.ts +34 -58
- package/src/contracts/workspace.contract.ts +19 -50
- package/src/events/agent-events.ts +345 -0
- package/src/events/cards.ts +286 -0
- package/src/{events.test.ts → events/resume.test.ts} +4 -19
- package/src/events/resume.ts +60 -0
- package/src/events/system-events.ts +139 -0
- package/src/events/transcript.ts +320 -0
- package/src/{conversation-ids.test.ts → ids/conversation-ids.test.ts} +25 -13
- package/src/ids/conversation-ids.ts +178 -0
- package/src/ids/hostnames.ts +129 -0
- package/src/ids/session-names.ts +29 -0
- package/src/ids/share-paths.ts +43 -0
- package/src/{tunnel-ids.test.ts → ids/tunnel-ids.test.ts} +1 -14
- package/src/ids/tunnel-ids.ts +29 -0
- package/src/index.ts +71 -87
- package/src/{agent-catalog.test.ts → models/agent-catalog.test.ts} +19 -93
- package/src/models/agent-catalog.ts +174 -0
- package/src/models/agent-runtimes.ts +201 -0
- package/src/models/capability-ledger.test.ts +84 -0
- package/src/{fast-tier.test.ts → models/fast-tier.test.ts} +7 -18
- package/src/models/fast-tier.ts +36 -0
- package/src/{model-order.test.ts → models/model-order.test.ts} +19 -40
- package/src/models/model-order.ts +163 -0
- package/src/{model-pins.test.ts → models/model-pins.test.ts} +12 -46
- package/src/models/model-pins.ts +57 -0
- package/src/models/model-roles.test.ts +38 -0
- package/src/models/model-roles.ts +180 -0
- package/src/{plan-pools.test.ts → models/plan-pools.test.ts} +6 -11
- package/src/models/plan-pools.ts +65 -0
- package/src/{prompt-complexity.test.ts → models/prompt-complexity.test.ts} +8 -60
- package/src/models/prompt-complexity.ts +215 -0
- package/src/{provider-specs.test.ts → models/provider-specs.test.ts} +18 -47
- package/src/models/provider-specs.ts +272 -0
- package/src/policy/approvals-execution.ts +58 -0
- package/src/{batch-runs.test.ts → policy/batch-runs.test.ts} +4 -20
- package/src/policy/batch-runs.ts +137 -0
- package/src/policy/capability-secrets.ts +5 -0
- package/src/{card-status.ts → policy/card-status.ts} +11 -26
- package/src/{command-classes.test.ts → policy/command-classes.test.ts} +11 -118
- package/src/policy/command-classes.ts +395 -0
- package/src/policy/command-run.ts +65 -0
- package/src/policy/control-scopes.ts +38 -0
- package/src/{credential-material.test.ts → policy/credential-material.test.ts} +4 -26
- package/src/policy/credential-material.ts +91 -0
- package/src/policy/needs-action.ts +5 -0
- package/src/policy/output-fields.ts +86 -0
- package/src/policy/overlay-lint.ts +100 -0
- package/src/{owner-ticket.test.ts → policy/owner-ticket.test.ts} +1 -1
- package/src/{owner-ticket.ts → policy/owner-ticket.ts} +9 -31
- package/src/policy/safety-policy.test.ts +84 -0
- package/src/policy/safety-policy.ts +142 -0
- package/src/policy/search-globs.ts +60 -0
- package/src/protocol/container-requirements.test.ts +72 -0
- package/src/protocol/container-requirements.ts +58 -0
- package/src/protocol/host-protocol.ts +29 -0
- package/src/protocol/ingress-contract.ts +103 -0
- package/src/{ingress-protocol.test.ts → protocol/ingress-protocol.test.ts} +25 -90
- package/src/protocol/ingress-protocol.ts +441 -0
- package/src/protocol/listener-protocol.ts +75 -0
- package/src/{peer-dial.test.ts → protocol/peer-dial.test.ts} +52 -1
- package/src/protocol/peer-dial.ts +207 -0
- package/src/{peer-mcp-server.ts → protocol/peer-mcp-server.ts} +16 -41
- package/src/protocol/request-id.ts +5 -0
- package/src/{routes.test.ts → protocol/routes.test.ts} +14 -22
- package/src/protocol/routes.ts +159 -0
- package/src/protocol/runner-protocol.ts +197 -0
- package/src/protocol/terminal-protocol.ts +13 -0
- package/src/protocol/webext-links.ts +50 -0
- package/src/protocol/webext-protocol.ts +24 -0
- package/src/schemas/activity.ts +22 -30
- package/src/schemas/agent.ts +130 -238
- package/src/schemas/agents.ts +165 -483
- package/src/schemas/approvals.ts +23 -71
- package/src/schemas/automations.ts +142 -250
- package/src/schemas/capabilities.ts +127 -414
- package/src/schemas/ci.ts +56 -108
- package/src/schemas/codebase-health.ts +7 -11
- package/src/schemas/devices.ts +98 -321
- package/src/schemas/engines.ts +16 -44
- package/src/schemas/environment.ts +41 -91
- package/src/schemas/exit.ts +24 -81
- package/src/schemas/extension-updates.ts +42 -87
- package/src/schemas/git-history.ts +30 -84
- package/src/schemas/git.ts +141 -256
- package/src/schemas/history.ts +14 -40
- package/src/schemas/hosts.ts +9 -15
- package/src/schemas/inventory.ts +8 -10
- package/src/schemas/issues.ts +66 -134
- package/src/schemas/logs.ts +15 -34
- package/src/schemas/loops.ts +46 -163
- package/src/schemas/maintenance.ts +47 -172
- package/src/schemas/panels.ts +20 -45
- package/src/schemas/personas.ts +50 -200
- package/src/schemas/plan-limits.ts +58 -197
- package/src/schemas/ports.ts +14 -32
- package/src/schemas/provider-oauth.ts +23 -76
- package/src/schemas/provider-subscriptions.ts +4 -13
- package/src/schemas/public.ts +4 -15
- package/src/schemas/push.ts +8 -36
- package/src/schemas/secrets.ts +20 -64
- package/src/schemas/settings.ts +175 -600
- package/src/schemas/share.ts +14 -32
- package/src/schemas/shared.ts +14 -13
- package/src/schemas/system.ts +46 -78
- package/src/schemas/terminal.ts +41 -120
- package/src/schemas/usage.ts +44 -233
- package/src/schemas/version-seam.test.ts +9 -26
- package/src/schemas/vpn.ts +27 -64
- package/src/schemas/webext.ts +22 -53
- package/src/schemas/workflows.ts +57 -183
- package/src/schemas/workspace-repos.ts +12 -24
- package/src/schemas/workspace-search.ts +17 -35
- package/src/schemas/workspace-setup.ts +4 -11
- package/src/schemas/workspace-tree.ts +32 -91
- package/src/state/arrival.ts +109 -0
- package/src/state/contract-lock.test.ts +17 -0
- package/src/state/contract-lock.ts +49 -0
- package/src/state/definition.ts +143 -0
- package/src/state/history-state.ts +103 -0
- package/src/{runtime-state.test.ts → state/runtime-state.test.ts} +3 -10
- package/src/state/runtime-state.ts +62 -0
- package/src/state/starter.ts +5 -0
- package/src/state/state-portability.ts +27 -0
- package/src/state/versions.ts +26 -0
- package/src/{workspace-state.test.ts → state/workspace-state.test.ts} +65 -172
- package/src/state/workspace-state.ts +669 -0
- package/src/{documents.test.ts → text/documents.test.ts} +1 -1
- package/src/text/documents.ts +42 -0
- package/src/text/embed.ts +132 -0
- package/src/text/mentions.ts +21 -0
- package/src/text/model-answer.ts +9 -0
- package/src/text/path-refs.ts +39 -0
- package/src/text/shell-regions.ts +224 -0
- package/src/{title.test.ts → text/title.test.ts} +13 -32
- package/src/text/title.ts +202 -0
- package/src/{transcript-fold.test.ts → text/transcript-fold.test.ts} +5 -83
- package/src/{transcript-fold.ts → text/transcript-fold.ts} +65 -170
- package/src/text/whisper.test.ts +19 -0
- package/src/text/whisper.ts +17 -0
- package/src/{workflow-faults.test.ts → text/workflow-faults.test.ts} +6 -24
- package/src/{workflow-faults.ts → text/workflow-faults.ts} +20 -60
- package/dist/agent-catalog.d.ts.map +0 -1
- package/dist/agent-catalog.js.map +0 -1
- package/dist/agent-runtimes.d.ts.map +0 -1
- package/dist/agent-runtimes.js.map +0 -1
- package/dist/approvals-execution.d.ts.map +0 -1
- package/dist/approvals-execution.js.map +0 -1
- package/dist/arrival.d.ts.map +0 -1
- package/dist/arrival.js.map +0 -1
- package/dist/batch-runs.d.ts.map +0 -1
- package/dist/batch-runs.js.map +0 -1
- package/dist/capability-env.d.ts.map +0 -1
- package/dist/capability-env.js.map +0 -1
- package/dist/capability-secrets.d.ts.map +0 -1
- package/dist/capability-secrets.js.map +0 -1
- package/dist/card-status.d.ts.map +0 -1
- package/dist/card-status.js.map +0 -1
- package/dist/command-classes.d.ts.map +0 -1
- package/dist/command-classes.js.map +0 -1
- package/dist/command-run.d.ts.map +0 -1
- package/dist/command-run.js.map +0 -1
- package/dist/contract-lock.d.ts.map +0 -1
- package/dist/contract-lock.js.map +0 -1
- package/dist/conversation-ids.d.ts +0 -4
- package/dist/conversation-ids.d.ts.map +0 -1
- package/dist/conversation-ids.js.map +0 -1
- package/dist/credential-material.d.ts.map +0 -1
- package/dist/credential-material.js.map +0 -1
- package/dist/definition.d.ts.map +0 -1
- package/dist/definition.js.map +0 -1
- package/dist/documents.d.ts.map +0 -1
- package/dist/documents.js.map +0 -1
- package/dist/embed.d.ts.map +0 -1
- package/dist/embed.js.map +0 -1
- package/dist/events.d.ts +0 -4336
- package/dist/events.d.ts.map +0 -1
- package/dist/events.js +0 -725
- package/dist/events.js.map +0 -1
- package/dist/fast-tier.d.ts.map +0 -1
- package/dist/fast-tier.js.map +0 -1
- package/dist/history-state.d.ts.map +0 -1
- package/dist/history-state.js.map +0 -1
- package/dist/host-protocol.d.ts.map +0 -1
- package/dist/host-protocol.js.map +0 -1
- package/dist/hostnames.d.ts.map +0 -1
- package/dist/hostnames.js.map +0 -1
- package/dist/ingress-contract.d.ts.map +0 -1
- package/dist/ingress-contract.js.map +0 -1
- package/dist/ingress-protocol.d.ts.map +0 -1
- package/dist/ingress-protocol.js.map +0 -1
- package/dist/listener-protocol.d.ts.map +0 -1
- package/dist/listener-protocol.js.map +0 -1
- package/dist/mentions.d.ts.map +0 -1
- package/dist/mentions.js.map +0 -1
- package/dist/model-order.d.ts.map +0 -1
- package/dist/model-order.js.map +0 -1
- package/dist/model-pins.d.ts.map +0 -1
- package/dist/model-pins.js.map +0 -1
- package/dist/model-roles.d.ts.map +0 -1
- package/dist/model-roles.js.map +0 -1
- package/dist/needs-action.d.ts.map +0 -1
- package/dist/needs-action.js.map +0 -1
- package/dist/output-fields.d.ts.map +0 -1
- package/dist/output-fields.js.map +0 -1
- package/dist/overlay-lint.d.ts.map +0 -1
- package/dist/overlay-lint.js.map +0 -1
- package/dist/owner-ticket.d.ts.map +0 -1
- package/dist/owner-ticket.js.map +0 -1
- package/dist/path-refs.d.ts.map +0 -1
- package/dist/path-refs.js.map +0 -1
- package/dist/peer-dial.d.ts.map +0 -1
- package/dist/peer-dial.js.map +0 -1
- package/dist/peer-mcp-server.d.ts.map +0 -1
- package/dist/peer-mcp-server.js.map +0 -1
- package/dist/plan-pools.d.ts.map +0 -1
- package/dist/plan-pools.js.map +0 -1
- package/dist/prompt-complexity.d.ts.map +0 -1
- package/dist/prompt-complexity.js.map +0 -1
- package/dist/provider-specs.d.ts.map +0 -1
- package/dist/provider-specs.js.map +0 -1
- package/dist/request-id.d.ts.map +0 -1
- package/dist/request-id.js.map +0 -1
- package/dist/routes.d.ts.map +0 -1
- package/dist/routes.js.map +0 -1
- package/dist/runner-protocol.d.ts.map +0 -1
- package/dist/runner-protocol.js.map +0 -1
- package/dist/runtime-state.d.ts.map +0 -1
- package/dist/runtime-state.js.map +0 -1
- package/dist/safety-policy.d.ts.map +0 -1
- package/dist/safety-policy.js.map +0 -1
- package/dist/search-globs.d.ts.map +0 -1
- package/dist/search-globs.js.map +0 -1
- package/dist/session-names.d.ts.map +0 -1
- package/dist/session-names.js.map +0 -1
- package/dist/share-paths.d.ts.map +0 -1
- package/dist/share-paths.js.map +0 -1
- package/dist/shell-regions.d.ts.map +0 -1
- package/dist/shell-regions.js.map +0 -1
- package/dist/sse.d.ts.map +0 -1
- package/dist/sse.js.map +0 -1
- package/dist/starter.d.ts.map +0 -1
- package/dist/starter.js.map +0 -1
- package/dist/state-portability.d.ts.map +0 -1
- package/dist/state-portability.js.map +0 -1
- package/dist/terminal-protocol.d.ts.map +0 -1
- package/dist/terminal-protocol.js.map +0 -1
- package/dist/title.d.ts.map +0 -1
- package/dist/title.js.map +0 -1
- package/dist/transcript-fold.d.ts.map +0 -1
- package/dist/transcript-fold.js.map +0 -1
- package/dist/tunnel-ids.d.ts.map +0 -1
- package/dist/tunnel-ids.js.map +0 -1
- package/dist/versions.d.ts.map +0 -1
- package/dist/versions.js.map +0 -1
- package/dist/webext-links.d.ts.map +0 -1
- package/dist/webext-links.js.map +0 -1
- package/dist/webext-protocol.d.ts.map +0 -1
- package/dist/webext-protocol.js.map +0 -1
- package/dist/workflow-faults.d.ts.map +0 -1
- package/dist/workflow-faults.js.map +0 -1
- package/dist/workspace-state.d.ts.map +0 -1
- package/dist/workspace-state.js.map +0 -1
- package/src/agent-catalog.ts +0 -316
- package/src/agent-runtimes.ts +0 -419
- package/src/approvals-execution.ts +0 -96
- package/src/arrival.ts +0 -160
- package/src/batch-runs.ts +0 -188
- package/src/capability-ledger.test.ts +0 -140
- package/src/capability-secrets.ts +0 -20
- package/src/command-classes.ts +0 -617
- package/src/command-run.ts +0 -78
- package/src/contract-lock.test.ts +0 -23
- package/src/contract-lock.ts +0 -66
- package/src/conversation-ids.ts +0 -207
- package/src/credential-material.ts +0 -181
- package/src/definition.ts +0 -207
- package/src/documents.ts +0 -67
- package/src/embed.ts +0 -164
- package/src/events.ts +0 -1870
- package/src/fast-tier.ts +0 -72
- package/src/history-state.ts +0 -174
- package/src/host-protocol.ts +0 -36
- package/src/hostnames.ts +0 -180
- package/src/ingress-contract.ts +0 -157
- package/src/ingress-protocol.ts +0 -625
- package/src/listener-protocol.ts +0 -96
- package/src/mentions.ts +0 -25
- package/src/model-order.ts +0 -262
- package/src/model-pins.ts +0 -132
- package/src/model-roles.test.ts +0 -52
- package/src/model-roles.ts +0 -320
- package/src/needs-action.ts +0 -14
- package/src/output-fields.ts +0 -111
- package/src/overlay-lint.ts +0 -116
- package/src/path-refs.ts +0 -59
- package/src/peer-dial.ts +0 -163
- package/src/plan-pools.ts +0 -92
- package/src/prompt-complexity.ts +0 -334
- package/src/provider-specs.ts +0 -432
- package/src/request-id.ts +0 -41
- package/src/routes.ts +0 -219
- package/src/runner-protocol.ts +0 -239
- package/src/runtime-state.ts +0 -140
- package/src/safety-policy.test.ts +0 -88
- package/src/safety-policy.ts +0 -258
- package/src/search-globs.ts +0 -76
- package/src/session-names.ts +0 -44
- package/src/share-paths.ts +0 -68
- package/src/shell-regions.ts +0 -289
- package/src/starter.ts +0 -13
- package/src/state-portability.ts +0 -56
- package/src/terminal-protocol.ts +0 -16
- package/src/title.ts +0 -267
- package/src/tunnel-ids.ts +0 -57
- package/src/versions.ts +0 -48
- package/src/webext-links.ts +0 -90
- package/src/webext-protocol.ts +0 -27
- package/src/workspace-state.ts +0 -1090
- /package/dist/{hostnames.d.ts → ids/hostnames.d.ts} +0 -0
- /package/dist/{hostnames.js → ids/hostnames.js} +0 -0
- /package/dist/{session-names.d.ts → ids/session-names.d.ts} +0 -0
- /package/dist/{session-names.js → ids/session-names.js} +0 -0
- /package/dist/{share-paths.d.ts → ids/share-paths.d.ts} +0 -0
- /package/dist/{share-paths.js → ids/share-paths.js} +0 -0
- /package/dist/{agent-catalog.js → models/agent-catalog.js} +0 -0
- /package/dist/{agent-runtimes.d.ts → models/agent-runtimes.d.ts} +0 -0
- /package/dist/{agent-runtimes.js → models/agent-runtimes.js} +0 -0
- /package/dist/{fast-tier.js → models/fast-tier.js} +0 -0
- /package/dist/{model-order.d.ts → models/model-order.d.ts} +0 -0
- /package/dist/{model-order.js → models/model-order.js} +0 -0
- /package/dist/{model-pins.js → models/model-pins.js} +0 -0
- /package/dist/{plan-pools.js → models/plan-pools.js} +0 -0
- /package/dist/{prompt-complexity.d.ts → models/prompt-complexity.d.ts} +0 -0
- /package/dist/{prompt-complexity.js → models/prompt-complexity.js} +0 -0
- /package/dist/{provider-specs.d.ts → models/provider-specs.d.ts} +0 -0
- /package/dist/{provider-specs.js → models/provider-specs.js} +0 -0
- /package/dist/{approvals-execution.d.ts → policy/approvals-execution.d.ts} +0 -0
- /package/dist/{approvals-execution.js → policy/approvals-execution.js} +0 -0
- /package/dist/{capability-env.d.ts → policy/capability-env.d.ts} +0 -0
- /package/dist/{capability-env.js → policy/capability-env.js} +0 -0
- /package/dist/{capability-secrets.d.ts → policy/capability-secrets.d.ts} +0 -0
- /package/dist/{capability-secrets.js → policy/capability-secrets.js} +0 -0
- /package/dist/{command-run.js → policy/command-run.js} +0 -0
- /package/dist/{credential-material.d.ts → policy/credential-material.d.ts} +0 -0
- /package/dist/{credential-material.js → policy/credential-material.js} +0 -0
- /package/dist/{needs-action.d.ts → policy/needs-action.d.ts} +0 -0
- /package/dist/{needs-action.js → policy/needs-action.js} +0 -0
- /package/dist/{output-fields.d.ts → policy/output-fields.d.ts} +0 -0
- /package/dist/{output-fields.js → policy/output-fields.js} +0 -0
- /package/dist/{overlay-lint.d.ts → policy/overlay-lint.d.ts} +0 -0
- /package/dist/{overlay-lint.js → policy/overlay-lint.js} +0 -0
- /package/dist/{owner-ticket.d.ts → policy/owner-ticket.d.ts} +0 -0
- /package/dist/{search-globs.d.ts → policy/search-globs.d.ts} +0 -0
- /package/dist/{search-globs.js → policy/search-globs.js} +0 -0
- /package/dist/{ingress-contract.d.ts → protocol/ingress-contract.d.ts} +0 -0
- /package/dist/{ingress-protocol.d.ts → protocol/ingress-protocol.d.ts} +0 -0
- /package/dist/{ingress-protocol.js → protocol/ingress-protocol.js} +0 -0
- /package/dist/{listener-protocol.d.ts → protocol/listener-protocol.d.ts} +0 -0
- /package/dist/{peer-mcp-server.d.ts → protocol/peer-mcp-server.d.ts} +0 -0
- /package/dist/{peer-mcp-server.js → protocol/peer-mcp-server.js} +0 -0
- /package/dist/{request-id.d.ts → protocol/request-id.d.ts} +0 -0
- /package/dist/{request-id.js → protocol/request-id.js} +0 -0
- /package/dist/{routes.d.ts → protocol/routes.d.ts} +0 -0
- /package/dist/{routes.js → protocol/routes.js} +0 -0
- /package/dist/{sse.d.ts → protocol/sse.d.ts} +0 -0
- /package/dist/{sse.js → protocol/sse.js} +0 -0
- /package/dist/{terminal-protocol.js → protocol/terminal-protocol.js} +0 -0
- /package/dist/{webext-links.d.ts → protocol/webext-links.d.ts} +0 -0
- /package/dist/{webext-links.js → protocol/webext-links.js} +0 -0
- /package/dist/{arrival.d.ts → state/arrival.d.ts} +0 -0
- /package/dist/{contract-lock.d.ts → state/contract-lock.d.ts} +0 -0
- /package/dist/{history-state.d.ts → state/history-state.d.ts} +0 -0
- /package/dist/{runtime-state.d.ts → state/runtime-state.d.ts} +0 -0
- /package/dist/{runtime-state.js → state/runtime-state.js} +0 -0
- /package/dist/{starter.d.ts → state/starter.d.ts} +0 -0
- /package/dist/{starter.js → state/starter.js} +0 -0
- /package/dist/{state-portability.d.ts → state/state-portability.d.ts} +0 -0
- /package/dist/{state-portability.js → state/state-portability.js} +0 -0
- /package/dist/{versions.d.ts → state/versions.d.ts} +0 -0
- /package/dist/{versions.js → state/versions.js} +0 -0
- /package/dist/{embed.d.ts → text/embed.d.ts} +0 -0
- /package/dist/{embed.js → text/embed.js} +0 -0
- /package/dist/{mentions.d.ts → text/mentions.d.ts} +0 -0
- /package/dist/{mentions.js → text/mentions.js} +0 -0
- /package/dist/{path-refs.d.ts → text/path-refs.d.ts} +0 -0
- /package/dist/{path-refs.js → text/path-refs.js} +0 -0
- /package/dist/{shell-regions.js → text/shell-regions.js} +0 -0
- /package/dist/{title.d.ts → text/title.d.ts} +0 -0
- /package/dist/{title.js → text/title.js} +0 -0
- /package/src/{hostnames.test.ts → ids/hostnames.test.ts} +0 -0
- /package/src/{share-paths.test.ts → ids/share-paths.test.ts} +0 -0
- /package/src/{capability-env.ts → policy/capability-env.ts} +0 -0
- /package/src/{overlay-lint.test.ts → policy/overlay-lint.test.ts} +0 -0
- /package/src/{search-globs.test.ts → policy/search-globs.test.ts} +0 -0
- /package/src/{ingress-contract.test.ts → protocol/ingress-contract.test.ts} +0 -0
- /package/src/{peer-mcp-server.test.ts → protocol/peer-mcp-server.test.ts} +0 -0
- /package/src/{sse.ts → protocol/sse.ts} +0 -0
- /package/src/{versions.test.ts → state/versions.test.ts} +0 -0
- /package/src/{embed.test.ts → text/embed.test.ts} +0 -0
- /package/src/{mentions.test.ts → text/mentions.test.ts} +0 -0
- /package/src/{path-refs.test.ts → text/path-refs.test.ts} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, test } from "vitest";
|
|
2
2
|
import { documentOf, documentTitle, isDocumentPath, isPlanDocumentPath } from "./documents.js";
|
|
3
|
-
import { PLAN_DOCUMENTS_DIR } from "
|
|
3
|
+
import { PLAN_DOCUMENTS_DIR } from "../state/workspace-state.js";
|
|
4
4
|
|
|
5
5
|
const write = (path: string, newText: string, extra: { oldText?: string; truncated?: boolean } = {}) => [
|
|
6
6
|
{ type: "diff" as const, path, newText, ...extra },
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { CardDocument, ToolCallContent } from "../events/cards.js";
|
|
2
|
+
import { planParts } from "./title.js";
|
|
3
|
+
import { PLAN_DOCUMENTS_DIR } from "../state/workspace-state.js";
|
|
4
|
+
|
|
5
|
+
// A document is a turn's output for a person to read, distinct from a file changed for the machine; only a whole-file
|
|
6
|
+
// write counts, an Edit's fragment stays a diff. Shared here so the daemon (parked-card logic) and the browser
|
|
7
|
+
// (tool-card rendering) can't drift on what counts as one.
|
|
8
|
+
|
|
9
|
+
// Markdown only: the chat's prose pipeline renders it; a .txt report is better left as a plain-text box.
|
|
10
|
+
const DOCUMENT_EXTENSIONS = [".md", ".markdown"];
|
|
11
|
+
|
|
12
|
+
export const isDocumentPath = (path: string): boolean => {
|
|
13
|
+
const lower = path.toLowerCase();
|
|
14
|
+
return DOCUMENT_EXTENSIONS.some((extension) => lower.endsWith(extension));
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// Matched by directory, not name (a mint-fresh phrase like `map-of-this-wiggly-spring.md` carries no signal). The
|
|
18
|
+
// directory is declared in workspace-state.ts, the one exception to its lock.
|
|
19
|
+
export const isPlanDocumentPath = (path: string): boolean => path.startsWith(`${PLAN_DOCUMENTS_DIR}/`);
|
|
20
|
+
|
|
21
|
+
// The opening heading (planParts) when there is one, else the file name; never the path, which is the CLI's mint and
|
|
22
|
+
// tells the reader nothing.
|
|
23
|
+
export const documentTitle = (markdown: string, path: string): string => planParts(markdown).title ?? path.split("/").pop() ?? path;
|
|
24
|
+
|
|
25
|
+
// Reads the call's structured diff, not its result text: a Write's whole file already rides the frame as newText
|
|
26
|
+
// (capped, truncated flags it). Works even for a published transcript with no workspace behind it.
|
|
27
|
+
export const documentOf = (name: string, content: readonly ToolCallContent[] | undefined): CardDocument | undefined => {
|
|
28
|
+
if (name.toLowerCase() !== "write") {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
const diff = content?.find((entry) => entry.type === "diff" && isDocumentPath(entry.path));
|
|
32
|
+
if (diff === undefined || diff.type !== "diff") {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
path: diff.path,
|
|
37
|
+
title: documentTitle(diff.newText, diff.path),
|
|
38
|
+
markdown: diff.newText,
|
|
39
|
+
...(diff.truncated === true ? { truncated: true } : {}),
|
|
40
|
+
...(isPlanDocumentPath(diff.path) ? { plan: true } : {}),
|
|
41
|
+
};
|
|
42
|
+
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// The zod-free half of an embed's wire, shared by the two embeds (webchat-widget, issue-sdk) and the daemon's
|
|
2
|
+
// public-door.ts. No imports, ever: this bundles into someone else's page, and the contract's barrel would drag in zod
|
|
3
|
+
// (measured at 1.1 MB for two strings).
|
|
4
|
+
|
|
5
|
+
// Where an embed talks to: the daemon it came from, and the automation it is the public face of.
|
|
6
|
+
export interface EmbedEndpoint {
|
|
7
|
+
readonly base: string;
|
|
8
|
+
readonly automationId: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// The server's own refusal sentence ({"error": ...}), shown verbatim: it names exactly what to fix (e.g. "origin not
|
|
12
|
+
// allowed").
|
|
13
|
+
export class EmbedError extends Error {
|
|
14
|
+
constructor(
|
|
15
|
+
message: string,
|
|
16
|
+
readonly status: number,
|
|
17
|
+
) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.name = "EmbedError";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const embedFailure = async (response: Response): Promise<EmbedError> => {
|
|
24
|
+
const body = (await response.json().catch(() => undefined)) as { error?: unknown } | undefined;
|
|
25
|
+
return new EmbedError(typeof body?.error === "string" ? body.error : `request failed (${response.status})`, response.status);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// One route of a public door: `<base>/<slug>/<automation>/<path>`, the daemon's own spelling.
|
|
29
|
+
export const embedUrl = ({ base, automationId }: EmbedEndpoint, slug: string, path: string): string =>
|
|
30
|
+
`${base}/${slug}/${encodeURIComponent(automationId)}/${path}`;
|
|
31
|
+
|
|
32
|
+
// One GET against a public door, answered as JSON or refused with the server's own sentence.
|
|
33
|
+
export const fetchEmbedJson = async <T>(url: string): Promise<T> => {
|
|
34
|
+
const response = await fetch(url);
|
|
35
|
+
if (!response.ok) {
|
|
36
|
+
throw await embedFailure(response);
|
|
37
|
+
}
|
|
38
|
+
return (await response.json()) as T;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// Find a nonce whose SHA-256 of `salt:nonce` has `difficulty` leading zero bits, signed to one caller's id so it can't
|
|
42
|
+
// be replayed elsewhere. Solved on the main thread, not a Worker: a host's CSP may forbid the blob: URL a Worker needs.
|
|
43
|
+
export interface PowChallenge {
|
|
44
|
+
readonly salt: string;
|
|
45
|
+
readonly difficulty: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const fetchEmbedChallenge = (endpoint: EmbedEndpoint, slug: string, param: string, id: string): Promise<PowChallenge> =>
|
|
49
|
+
fetchEmbedJson<PowChallenge>(`${embedUrl(endpoint, slug, "challenge")}?${param}=${encodeURIComponent(id)}`);
|
|
50
|
+
|
|
51
|
+
const BATCH = 512;
|
|
52
|
+
|
|
53
|
+
// Leading zero bits of a digest, up to `wanted`. Stops at the first non-zero byte, so a miss costs one byte.
|
|
54
|
+
const leadingZeroBits = (digest: Uint8Array, wanted: number): number => {
|
|
55
|
+
let bits = 0;
|
|
56
|
+
for (const byte of digest) {
|
|
57
|
+
if (byte !== 0) {
|
|
58
|
+
// Math.clz32 counts 32-bit leading zeros; the byte sits in the low 8, so 24 are structural.
|
|
59
|
+
return bits + Math.clz32(byte) - 24;
|
|
60
|
+
}
|
|
61
|
+
bits += 8;
|
|
62
|
+
if (bits >= wanted) {
|
|
63
|
+
return bits;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return bits;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// Resolves to `<salt>:<nonce>`, so the daemon can re-derive the challenge without storing one. insecure is for an
|
|
70
|
+
// http:// page: crypto.subtle needs a secure context, and the fix is the site's TLS.
|
|
71
|
+
export const solveProofOfWork = async (challenge: PowChallenge, insecure: string, onProgress?: (attempts: number) => void): Promise<string> => {
|
|
72
|
+
if (crypto.subtle === undefined) {
|
|
73
|
+
throw new Error(insecure);
|
|
74
|
+
}
|
|
75
|
+
const encoder = new TextEncoder();
|
|
76
|
+
for (let nonce = 0; ; nonce += 1) {
|
|
77
|
+
const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", encoder.encode(`${challenge.salt}:${nonce}`)));
|
|
78
|
+
if (leadingZeroBits(digest, challenge.difficulty) >= challenge.difficulty) {
|
|
79
|
+
return `${challenge.salt}:${nonce}`;
|
|
80
|
+
}
|
|
81
|
+
if (nonce % BATCH === BATCH - 1) {
|
|
82
|
+
onProgress?.(nonce + 1);
|
|
83
|
+
// Hands the main thread back so the page (and the "checking..." line) keeps painting.
|
|
84
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// localStorage can throw (Safari private mode, blocked storage); the embed still works, just minting a fresh id per
|
|
90
|
+
// load. Silent by design: an embed must never put an error in the console.
|
|
91
|
+
export const readStored = (name: string): string | undefined => {
|
|
92
|
+
try {
|
|
93
|
+
return window.localStorage.getItem(name) ?? undefined;
|
|
94
|
+
} catch {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export const writeStored = (name: string, value: string): void => {
|
|
100
|
+
try {
|
|
101
|
+
window.localStorage.setItem(name, value);
|
|
102
|
+
} catch {
|
|
103
|
+
// No storage: this load keeps the value in memory, the next one mints another.
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// A per-browser id, not identity and not a secret: it threads a visitor's messages into one conversation, or bounds a
|
|
108
|
+
// rate window per tab.
|
|
109
|
+
export const storedId = (name: string): string => {
|
|
110
|
+
const existing = readStored(name);
|
|
111
|
+
if (existing !== undefined && existing !== "") {
|
|
112
|
+
return existing;
|
|
113
|
+
}
|
|
114
|
+
const minted = crypto.randomUUID();
|
|
115
|
+
writeStored(name, minted);
|
|
116
|
+
return minted;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// The daemon to talk to is this script's own origin, the one thing a copy-paste can't get wrong; data-base overrides it
|
|
120
|
+
// behind a reverse proxy. currentScript is read at module scope, valid only synchronously; querySelector is the
|
|
121
|
+
// fallback.
|
|
122
|
+
export const embedScript = (srcMatch: string): HTMLScriptElement | null =>
|
|
123
|
+
(document.currentScript as HTMLScriptElement | null) ?? document.querySelector<HTMLScriptElement>(`script[src*="${srcMatch}"]`);
|
|
124
|
+
|
|
125
|
+
// Undefined with no automation id, the one mistake worth flagging: otherwise the embed is silently absent.
|
|
126
|
+
export const embedEndpointOf = (script: HTMLScriptElement): EmbedEndpoint | undefined => {
|
|
127
|
+
const automationId = script.dataset["automation"];
|
|
128
|
+
if (automationId === undefined || automationId === "") {
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
return { automationId, base: (script.dataset["base"] ?? new URL(script.src, window.location.href).origin).replace(/\/$/, "") };
|
|
132
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Two readers of the same @-mention text: the composer resolves a path into a Read-tool attachment, the fold draws
|
|
2
|
+
// uploaded files as chips and hides inline mentions since they're already visible in the words. One tokenizer keeps
|
|
3
|
+
// them in agreement.
|
|
4
|
+
|
|
5
|
+
// Broad on purpose, including invalid mentions: old turns persisted these candidates in the attachment field, and the
|
|
6
|
+
// fold needs the same broad set to hide them.
|
|
7
|
+
export const mentionedPathTokens = (text: string): string[] => {
|
|
8
|
+
const paths = new Set<string>();
|
|
9
|
+
for (const match of text.matchAll(/(?:^|\s)@([^\s@]+)/g)) {
|
|
10
|
+
const token = (match[1] as string).replace(/[.,;:!?)]+$/, ``);
|
|
11
|
+
if (token.includes(`/`) || token.includes(`.`)) {
|
|
12
|
+
paths.add(token);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return [...paths];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// Excludes a copied pnpm script prefix (`@scope/package:test:`), which shares the opening shape but is not a file;
|
|
19
|
+
// accepting it creates a phantom attachment.
|
|
20
|
+
const PACKAGE_SCRIPT = /^[^/]+\/[^/]+:[^/]+$/u;
|
|
21
|
+
export const mentionPaths = (text: string): string[] => mentionedPathTokens(text).filter((token) => !PACKAGE_SCRIPT.test(token));
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Four callers ask a model for a one-line answer and always strip what wraps it (a code fence, a label prefix, a list
|
|
2
|
+
// bullet) rather than reject it. The label pattern isn't shared, since each caller strips a different word. Lives here,
|
|
3
|
+
// not beside a caller, since the callers span two daemon subsystems that can't import each other.
|
|
4
|
+
|
|
5
|
+
// A fenced block's open (with/without a language) and close; `.replace` only, `g` makes test/exec stateful.
|
|
6
|
+
export const FENCE = /^```[\w-]*\n?|\n?```$/gu;
|
|
7
|
+
|
|
8
|
+
// A leading list marker, for the answer returned as a list of one.
|
|
9
|
+
export const BULLET = /^[-*]\s+/u;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// A prose path reference is loosely anchored (a working prefix, a worktree's absolute prefix) but ends in the real
|
|
2
|
+
// workspace-relative path. Resolved by matching shorter tails against the tree; the browser and daemon run the
|
|
3
|
+
// identical rule so they can't disagree.
|
|
4
|
+
|
|
5
|
+
// Leading segments a reference may exceed the workspace by; a worktree's own lead is 3 segments.
|
|
6
|
+
const MAX_DROPS = 6;
|
|
7
|
+
// Never cut to a bare filename: one name can match a hundred files in a monorepo, worse than not linking.
|
|
8
|
+
const MIN_SEGMENTS = 2;
|
|
9
|
+
// Enough candidates for a picker; a reference matching more than this is ambiguous by any measure.
|
|
10
|
+
export const MAX_REF_CANDIDATES = 10;
|
|
11
|
+
|
|
12
|
+
// Tails ordered longest (most specific) first. root is the container workspace root: a path under it is the answer
|
|
13
|
+
// minus that lead; a path under any other absolute root (a worktree) mirrors the same layout below its own lead.
|
|
14
|
+
export const referenceTails = (raw: string, root: string): readonly string[] => {
|
|
15
|
+
const normalized = raw.replaceAll(`\\`, `/`).replace(/^\.\//, ``);
|
|
16
|
+
const anchored = normalized.startsWith(`${root}/`) ? normalized.slice(root.length + 1) : normalized.replace(/^\/+/, ``);
|
|
17
|
+
const segments = anchored.split(`/`).filter((segment) => segment !== `` && segment !== `.`);
|
|
18
|
+
const tails: string[] = [];
|
|
19
|
+
for (let drop = 0; drop <= MAX_DROPS && segments.length - drop >= MIN_SEGMENTS; drop++) {
|
|
20
|
+
tails.push(segments.slice(drop).join(`/`));
|
|
21
|
+
}
|
|
22
|
+
return tails;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// Segment-boundary matches only, best (shallowest) first: pages/Foo.vue means the app's page, not a copy nested in a
|
|
26
|
+
// fixture tree. The daemon's glob only anchors at the string level, so the boundary is enforced here.
|
|
27
|
+
export const rankRefCandidates = (tail: string, paths: readonly string[]): readonly string[] =>
|
|
28
|
+
paths
|
|
29
|
+
.filter((path) => path === tail || path.endsWith(`/${tail}`))
|
|
30
|
+
.toSorted((a, b) => a.split(`/`).length - b.split(`/`).length || a.length - b.length || (a < b ? -1 : 1))
|
|
31
|
+
.slice(0, MAX_REF_CANDIDATES);
|
|
32
|
+
|
|
33
|
+
// The one change-vs-tests rule, shared by every surface that needs it. Convention-based (.test./.spec., __tests__ dirs,
|
|
34
|
+
// e2e-harness, runner configs); never bare "contains test", which would flag testimonials/ or latest.ts.
|
|
35
|
+
const TEST_DIRS = new Set([`__tests__`, `__fixtures__`, `__mocks__`, `__snapshots__`]);
|
|
36
|
+
const TEST_FILE =
|
|
37
|
+
/(?:^|\/)(?:[^/]+\.(?:test|spec)\.[^/.]+|[^/]*\.e2e\.[^/]+|e2e-harness\.[^/]+|(?:vitest|jest|playwright)(?:\.[\w-]+)*\.config\.[^/]+)$/;
|
|
38
|
+
|
|
39
|
+
export const isTestPath = (path: string): boolean => TEST_FILE.test(path) || path.split(`/`).some((segment) => TEST_DIRS.has(segment));
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
// Marks command text that is not a program, so the un-waivable hard-rule tier stops firing inside comments, heredoc
|
|
2
|
+
// bodies, and quoted arguments of verbs that can't execute them (echo, grep, a -m message). Missing a region costs one
|
|
3
|
+
// judge call; inventing one only skips the hard rule, never the judge. sed/awk/perl are excluded: each can run its own
|
|
4
|
+
// argument.
|
|
5
|
+
|
|
6
|
+
import type { CommandSpan } from "../policy/command-classes.js";
|
|
7
|
+
|
|
8
|
+
// Verbs whose quoted argument this scanner treats as text; each prints or matches it, none executes it.
|
|
9
|
+
const QUOTING_VERBS: ReadonlySet<string> = new Set([
|
|
10
|
+
"echo",
|
|
11
|
+
"printf",
|
|
12
|
+
"rg",
|
|
13
|
+
"grep",
|
|
14
|
+
"egrep",
|
|
15
|
+
"fgrep",
|
|
16
|
+
"ack",
|
|
17
|
+
"ag",
|
|
18
|
+
"ripgrep",
|
|
19
|
+
]);
|
|
20
|
+
|
|
21
|
+
// A message flag (git's -m, etc.): the quoted argument is prose, whatever verb precedes it.
|
|
22
|
+
const MESSAGE_FLAGS: ReadonlySet<string> = new Set(["-m", "--message", "-am", "--body", "-b"]);
|
|
23
|
+
|
|
24
|
+
// Where an unquoted word ends: whitespace, a pipeline/list operator, a redirect, a paren.
|
|
25
|
+
const WORD_END = /[\s;|&<>()]/;
|
|
26
|
+
|
|
27
|
+
// A variable-assignment prefix (`FOO=bar cmd`), skipped when looking for the verb.
|
|
28
|
+
const ASSIGNMENT = /^[A-Za-z_][A-Za-z0-9_]*=/;
|
|
29
|
+
|
|
30
|
+
// `<<EOF`, `<<-EOF`, quoted or not; the delimiter's quoting only affects expansion, not classification here.
|
|
31
|
+
const HEREDOC_OPEN = /<<-?\s*(['"]?)([A-Za-z_][A-Za-z0-9_]*)\1/g;
|
|
32
|
+
|
|
33
|
+
// Found in their own pass, first: a heredoc body is line-oriented and can hold anything, an odd quote count in it would
|
|
34
|
+
// desync the word scanner.
|
|
35
|
+
const heredocBodies = (command: string): CommandSpan[] => {
|
|
36
|
+
const bodies: CommandSpan[] = [];
|
|
37
|
+
for (const open of command.matchAll(HEREDOC_OPEN)) {
|
|
38
|
+
const indented = command.slice(open.index, open.index + 3).startsWith("<<-");
|
|
39
|
+
const newline = command.indexOf("\n", open.index + open[0].length);
|
|
40
|
+
if (newline === -1) {
|
|
41
|
+
// An unterminated heredoc (nothing after the opener): no body to mark.
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const start = newline + 1;
|
|
45
|
+
const terminator = new RegExp(`^${indented ? "[ \\t]*" : ""}${open[2] as string}[ \\t]*$`, "m");
|
|
46
|
+
const rest = command.slice(start);
|
|
47
|
+
const end = terminator.exec(rest)?.index;
|
|
48
|
+
// An unterminated body runs to the end of the command, same as the shell would read it.
|
|
49
|
+
bodies.push({ start, end: end === undefined ? command.length : start + end });
|
|
50
|
+
}
|
|
51
|
+
return bodies;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// Is this offset inside an already-found span? Heredoc bodies are skipped wholesale by the word scan.
|
|
55
|
+
const within = (spans: readonly CommandSpan[], offset: number): CommandSpan | undefined =>
|
|
56
|
+
spans.find((span) => offset >= span.start && offset < span.end);
|
|
57
|
+
|
|
58
|
+
// A substitution inside double quotes, the one thing that turns a quoted argument back into a program.
|
|
59
|
+
const EXPANDS = /\$\(|`/;
|
|
60
|
+
|
|
61
|
+
// The span covers the quotes too, so a match anywhere in `"rm -rf /"` reads as contained.
|
|
62
|
+
interface QuotedSegment {
|
|
63
|
+
readonly span: CommandSpan;
|
|
64
|
+
// A double-quoted substitution is not text and never becomes a region; single quotes never set this.
|
|
65
|
+
readonly expands: boolean;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
interface ShellWord {
|
|
69
|
+
readonly start: number;
|
|
70
|
+
// The word with quoting removed, compared against a verb name or a flag.
|
|
71
|
+
readonly text: string;
|
|
72
|
+
readonly quoted: readonly QuotedSegment[];
|
|
73
|
+
// Does this word begin a simple command? True for the first word after a separator or at the start.
|
|
74
|
+
readonly opensCommand: boolean;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// A verb by its bare name: `/bin/echo` and `./echo` are both echo, the path says nothing new.
|
|
78
|
+
const bareVerb = (text: string): string => text.slice(Math.max(text.lastIndexOf("/"), text.lastIndexOf("\\")) + 1);
|
|
79
|
+
|
|
80
|
+
// Every list/pipeline operator; past one, the next word is a verb again.
|
|
81
|
+
const SEPARATORS = new Set(["\n", ";", "|", "&", "(", ")"]);
|
|
82
|
+
const BLANKS = new Set([" ", "\t", "\r"]);
|
|
83
|
+
|
|
84
|
+
// An unbalanced quote runs to the end of the command, as a shell waiting for more input would, keeping the caller
|
|
85
|
+
// advancing.
|
|
86
|
+
const readQuoted = (command: string, open: number): QuotedSegment & { readonly text: string; readonly end: number } => {
|
|
87
|
+
const quote = command[open] as string;
|
|
88
|
+
const close = command.indexOf(quote, open + 1);
|
|
89
|
+
const end = close === -1 ? command.length : close + 1;
|
|
90
|
+
const text = command.slice(open + 1, close === -1 ? command.length : close);
|
|
91
|
+
return { span: { start: open, end }, expands: quote === '"' && EXPANDS.test(text), text, end };
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// end === start can't happen: the caller only enters here on a character that is neither blank nor a separator.
|
|
95
|
+
const readWord = (command: string, start: number): { readonly word: Omit<ShellWord, "opensCommand">; readonly end: number } => {
|
|
96
|
+
const quoted: QuotedSegment[] = [];
|
|
97
|
+
let text = "";
|
|
98
|
+
let index = start;
|
|
99
|
+
while (index < command.length && !WORD_END.test(command[index] as string)) {
|
|
100
|
+
const char = command[index] as string;
|
|
101
|
+
if (char === "'" || char === '"') {
|
|
102
|
+
const segment = readQuoted(command, index);
|
|
103
|
+
quoted.push({ span: segment.span, expands: segment.expands });
|
|
104
|
+
text += segment.text;
|
|
105
|
+
index = segment.end;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (char === "\\") {
|
|
109
|
+
text += command[index + 1] ?? "";
|
|
110
|
+
index += 2;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
text += char;
|
|
114
|
+
index += 1;
|
|
115
|
+
}
|
|
116
|
+
return { word: { start, text, quoted }, end: index };
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// A scanner, not a parser: tracks quoting and the separators that start a new command, nothing about control flow,
|
|
120
|
+
// functions or expansion.
|
|
121
|
+
const scanWords = (command: string, skip: readonly CommandSpan[]): ShellWord[] => {
|
|
122
|
+
const words: ShellWord[] = [];
|
|
123
|
+
let index = 0;
|
|
124
|
+
let opensCommand = true;
|
|
125
|
+
while (index < command.length) {
|
|
126
|
+
const skipped = within(skip, index);
|
|
127
|
+
if (skipped !== undefined) {
|
|
128
|
+
index = skipped.end;
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
const char = command[index] as string;
|
|
132
|
+
if (SEPARATORS.has(char)) {
|
|
133
|
+
opensCommand = true;
|
|
134
|
+
index += 1;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (BLANKS.has(char)) {
|
|
138
|
+
index += 1;
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (char === "#") {
|
|
142
|
+
// Runs to end of line; only reached at a word boundary, so `a#b` is one word.
|
|
143
|
+
const newline = command.indexOf("\n", index);
|
|
144
|
+
index = newline === -1 ? command.length : newline;
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
const { word, end } = readWord(command, index);
|
|
148
|
+
// A stray character, neither separator nor word (e.g. a bad redirect): step over it so the loop advances.
|
|
149
|
+
index = end === index ? index + 1 : end;
|
|
150
|
+
if (end !== word.start) {
|
|
151
|
+
words.push({ ...word, opensCommand });
|
|
152
|
+
opensCommand = false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return words;
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
// Unsorted and possibly overlapping; callers only ask containment of them. Computed once per command by the classifier
|
|
159
|
+
// and shared across every table.
|
|
160
|
+
export const inertRegions = (command: string): CommandSpan[] => {
|
|
161
|
+
const bodies = heredocBodies(command);
|
|
162
|
+
const regions: CommandSpan[] = [...bodies];
|
|
163
|
+
const words = scanWords(command, bodies);
|
|
164
|
+
// Found again here, where quoting state lives: a `#` inside a quoted string isn't a comment.
|
|
165
|
+
let quotingVerb = false;
|
|
166
|
+
let previous: ShellWord | undefined;
|
|
167
|
+
for (const word of words) {
|
|
168
|
+
if (word.opensCommand) {
|
|
169
|
+
quotingVerb = QUOTING_VERBS.has(bareVerb(word.text));
|
|
170
|
+
previous = undefined;
|
|
171
|
+
}
|
|
172
|
+
// An env assignment before the verb (`LC_ALL=C grep`) isn't the verb; re-read the next word instead.
|
|
173
|
+
if (word.opensCommand && ASSIGNMENT.test(word.text) && word.quoted.length === 0) {
|
|
174
|
+
quotingVerb = false;
|
|
175
|
+
previous = undefined;
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
const afterMessageFlag = previous !== undefined && MESSAGE_FLAGS.has(previous.text);
|
|
179
|
+
if (quotingVerb || afterMessageFlag) {
|
|
180
|
+
regions.push(...word.quoted.filter((segment) => !segment.expands).map((segment) => segment.span));
|
|
181
|
+
}
|
|
182
|
+
previous = word;
|
|
183
|
+
}
|
|
184
|
+
regions.push(...commentRegions(command, bodies));
|
|
185
|
+
return regions;
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
// Its own walk: the word scan needs what's inside a quote, this only needs to be past it. Sharing readQuoted keeps both
|
|
189
|
+
// agreeing on where one ends.
|
|
190
|
+
const commentRegions = (command: string, skip: readonly CommandSpan[]): CommandSpan[] => {
|
|
191
|
+
const comments: CommandSpan[] = [];
|
|
192
|
+
let index = 0;
|
|
193
|
+
while (index < command.length) {
|
|
194
|
+
const skipped = within(skip, index);
|
|
195
|
+
if (skipped !== undefined) {
|
|
196
|
+
index = skipped.end;
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
const char = command[index] as string;
|
|
200
|
+
if (char === "'" || char === '"') {
|
|
201
|
+
index = readQuoted(command, index).end;
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
if (char === "\\") {
|
|
205
|
+
index += 2;
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
// A word boundary before it is what makes it a comment, not part of a word.
|
|
209
|
+
if (char === "#" && (index === 0 || WORD_END.test(command[index - 1] as string))) {
|
|
210
|
+
const newline = command.indexOf("\n", index);
|
|
211
|
+
const end = newline === -1 ? command.length : newline;
|
|
212
|
+
comments.push({ start: index, end });
|
|
213
|
+
index = end;
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
index += 1;
|
|
217
|
+
}
|
|
218
|
+
return comments;
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
// Judged on where the fragment starts, not whether the whole match is contained: every pattern begins at the verb, so
|
|
222
|
+
// the start is what's found. A verb outside every region stays live no matter what follows it.
|
|
223
|
+
export const isLive = (span: CommandSpan, regions: readonly CommandSpan[]): boolean =>
|
|
224
|
+
!regions.some((region) => span.start >= region.start && span.start < region.end);
|
|
@@ -1,26 +1,20 @@
|
|
|
1
1
|
import { expect, test } from "vitest";
|
|
2
|
-
import { AgentTurnSchema } from "
|
|
2
|
+
import { AgentTurnSchema } from "../schemas/agent.js";
|
|
3
3
|
import { deriveTitle } from "./title.js";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
* 40) got wrong in a way a user notices: the title named the paste instead of the work, spent the budget on
|
|
7
|
-
* politeness, or stopped mid-syllable. */
|
|
5
|
+
// Titles deriveTitle produces; every case here is a shape a naive collapse-and-cut-at-40 rule got noticeably wrong.
|
|
8
6
|
|
|
9
7
|
test("spends the budget on the ask rather than on the politeness in front of it", () => {
|
|
10
|
-
// `Can you please fix the auth…` is what the naive cut produced: three of its five words are ceremony.
|
|
11
8
|
expect(deriveTitle("Can you please fix the auth tests?")).toBe("Fix the auth tests?");
|
|
12
9
|
expect(deriveTitle("Hey, can you please look at the flaky test")).toBe("Look at the flaky test");
|
|
13
10
|
});
|
|
14
11
|
|
|
15
12
|
test("keeps a greeting whole when peeling it off would leave a fragment", () => {
|
|
16
|
-
// `Hi there` is not a conversation about `there`, and `So what?` is not one about `what?`: a one-word
|
|
17
|
-
// remnant means the opener was carrying the sentence, so the line stands as the user wrote it.
|
|
18
13
|
expect(deriveTitle("Hi there")).toBe("Hi there");
|
|
19
14
|
expect(deriveTitle("So what?")).toBe("So what?");
|
|
20
15
|
});
|
|
21
16
|
|
|
22
17
|
test("titles a pasted stack trace after the sentence the user wrote around it", () => {
|
|
23
|
-
// The paste is evidence, not the ask. Titling from it gives every one of the day's pastes the same name.
|
|
24
18
|
const prompt = [
|
|
25
19
|
"The build is broken again.",
|
|
26
20
|
"",
|
|
@@ -34,14 +28,11 @@ test("titles a pasted stack trace after the sentence the user wrote around it",
|
|
|
34
28
|
});
|
|
35
29
|
|
|
36
30
|
test("skips a greeting line and takes the ask from the line below it", () => {
|
|
37
|
-
// A line that unwinds to nothing was throat-clearing; the ask is further down. The naive rule stopped at
|
|
38
|
-
// the greeting and named every such conversation `Hey, quick one -`.
|
|
39
31
|
expect(deriveTitle("Hey, quick one —\n\nWhy does the tab title truncate mid-word?")).toBe("Why does the tab title truncate mid-word?");
|
|
40
32
|
});
|
|
41
33
|
|
|
42
34
|
test("keeps an ask that fits the registry's 80-character budget instead of cutting at 40", () => {
|
|
43
|
-
//
|
|
44
|
-
// room for twice that. The stored title matches what the registry and the rename input accept.
|
|
35
|
+
// Matches the registry's stored-title budget, not an arbitrary length.
|
|
45
36
|
const prompt = "In intentic-app/web when conflicts happen during rebase show a resolution banner";
|
|
46
37
|
|
|
47
38
|
expect(deriveTitle(prompt)).toBe(prompt);
|
|
@@ -53,26 +44,20 @@ test("cuts on a word boundary instead of mid-syllable", () => {
|
|
|
53
44
|
const kept = title.slice(0, -1);
|
|
54
45
|
|
|
55
46
|
expect(title.endsWith("…")).toBe(true);
|
|
56
|
-
// The old rule sliced at exactly 40, ending this title inside `mid-word`. Every word that survives has to
|
|
57
|
-
// be a whole one, so what precedes the ellipsis must stop where the prompt itself has a break.
|
|
58
47
|
expect(prompt.startsWith(kept)).toBe(true);
|
|
59
48
|
expect(prompt[kept.length]).toBe(" ");
|
|
60
49
|
});
|
|
61
50
|
|
|
62
51
|
test("keeps a cut it cannot put on a word boundary inside the budget anyway", () => {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
* character is not a cosmetic overflow, it is a 400 on the turn carrying the name, and it wedged the
|
|
66
|
-
* conversation for good: the browser stores the derived title before it sends, so every retry re-sent the
|
|
67
|
-
* same rejected one. */
|
|
52
|
+
// The clamp alone ends the title when no boundary is late enough; overshooting the schema's cap even by one char
|
|
53
|
+
// wedges every retry, since the browser stores the title before sending.
|
|
68
54
|
const prompt = `In one of the sandboxes I have experienced "CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS" limit of 20. Make it configurable in sandbox settings somewhere at /sandbox/agent`;
|
|
69
55
|
const title = deriveTitle(prompt);
|
|
70
56
|
|
|
71
57
|
expect(title.endsWith("…")).toBe(true);
|
|
72
|
-
//
|
|
73
|
-
// apart is the entire bug, and a second copy of the number is how they drift.
|
|
58
|
+
// Checked against the contract, not a repeated literal: a second copy of the cap is how it would drift.
|
|
74
59
|
expect(AgentTurnSchema.safeParse({ prompt, title }).success).toBe(true);
|
|
75
|
-
// Not a property of that one sentence: any token wide enough to swallow the window
|
|
60
|
+
// Not a property of that one sentence: any token wide enough to swallow the window triggers it.
|
|
76
61
|
const wide = `Investigate ${"X".repeat(120)} please`;
|
|
77
62
|
expect(AgentTurnSchema.safeParse({ prompt: wide, title: deriveTitle(wide) }).success).toBe(true);
|
|
78
63
|
});
|
|
@@ -80,14 +65,14 @@ test("keeps a cut it cannot put on a word boundary inside the budget anyway", ()
|
|
|
80
65
|
test("keeps a link's last meaningful segment rather than its host and scaffolding", () => {
|
|
81
66
|
const title = deriveTitle("Look at https://gitlab.com/radarsu/intentic/-/merge_requests/42 and tell me what broke");
|
|
82
67
|
|
|
83
|
-
// A numeric tail alone (
|
|
68
|
+
// A numeric tail alone ("42") would name nothing, so the segment above it comes along.
|
|
84
69
|
expect(title).toContain("merge_requests/42");
|
|
85
70
|
expect(title).not.toContain("gitlab.com");
|
|
86
71
|
});
|
|
87
72
|
|
|
88
73
|
test("collapses a deep path to its basename and leaves a shallow one alone", () => {
|
|
89
74
|
expect(deriveTitle("Refactor _editor/web/src/composables/chat/conversation.ts")).toBe("Refactor conversation.ts");
|
|
90
|
-
// Two segments already read as a place; collapsing
|
|
75
|
+
// Two segments already read as a place; collapsing would lose the reference's only context.
|
|
91
76
|
expect(deriveTitle("Refactor src/foo.ts")).toBe("Refactor src/foo.ts");
|
|
92
77
|
});
|
|
93
78
|
|
|
@@ -96,7 +81,7 @@ test("ends on the first sentence when the prompt keeps going", () => {
|
|
|
96
81
|
});
|
|
97
82
|
|
|
98
83
|
test("does not mistake an abbreviation for the end of a sentence", () => {
|
|
99
|
-
//
|
|
84
|
+
// Would otherwise cut to `i.e`, naming nothing.
|
|
100
85
|
expect(deriveTitle("i.e. the derived title should survive")).toBe("i.e. the derived title should survive");
|
|
101
86
|
});
|
|
102
87
|
|
|
@@ -106,12 +91,11 @@ test("leaves casing alone when the opening word carries meaning in its casing",
|
|
|
106
91
|
});
|
|
107
92
|
|
|
108
93
|
test("names a prompt that is nothing but a paste after what was pasted", () => {
|
|
109
|
-
// Returning empty here would render a nameless tab; the first line of the paste at least says what it is.
|
|
110
94
|
expect(deriveTitle("```ts\nconst x = 1;\n```")).toBe("const x = 1;");
|
|
111
95
|
});
|
|
112
96
|
|
|
113
97
|
test("never returns empty for a prompt that has any content at all", () => {
|
|
114
|
-
// A greeting with no ask
|
|
98
|
+
// A greeting with no ask, and a prompt with no letters at all: both still must name a tab.
|
|
115
99
|
expect(deriveTitle("Hey!")).toBe("Hey!");
|
|
116
100
|
expect(deriveTitle("!!!")).toBe("!!!");
|
|
117
101
|
});
|
|
@@ -121,8 +105,6 @@ test("reads past quoted material to the user's own words", () => {
|
|
|
121
105
|
});
|
|
122
106
|
|
|
123
107
|
test("skips past-work narration to the instruction behind it", () => {
|
|
124
|
-
// `We have recently added…` is the scene, not the ask: titling from it names every such conversation
|
|
125
|
-
// after last week's work. The instruction further in is what the conversation is about.
|
|
126
108
|
expect(deriveTitle("We have recently added iq map and iq deps commands. Now let's also add a health contract for the daemon.")).toBe(
|
|
127
109
|
"Add a health contract for the daemon",
|
|
128
110
|
);
|
|
@@ -134,13 +116,12 @@ test("skips narration to an outright question", () => {
|
|
|
134
116
|
});
|
|
135
117
|
|
|
136
118
|
test("keeps narration when nothing behind it is unmistakably the ask", () => {
|
|
137
|
-
//
|
|
119
|
+
// Not worth skipping for: a vague follow-up like "it" is worse context than the sentence before it.
|
|
138
120
|
expect(deriveTitle("We migrated the board to SSE last week. It feels slower since.")).toBe("We migrated the board to SSE last week");
|
|
139
121
|
});
|
|
140
122
|
|
|
141
123
|
test("keeps a declarative problem report even when advice follows it", () => {
|
|
142
|
-
// Only
|
|
143
|
-
// pointer: `Check the broadcast path` names a step, not the conversation.
|
|
124
|
+
// Only narration is skippable; an imperative like "Check the broadcast path" names a step, not the ask.
|
|
144
125
|
expect(deriveTitle("The fleet board flickers when agents land. Check the broadcast path.")).toBe("The fleet board flickers when agents land");
|
|
145
126
|
});
|
|
146
127
|
|