@intentic/sandbox-contract 1.232.0 → 1.233.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 +7 -2
- package/dist/agent-catalog.d.ts +2 -1
- package/dist/agent-catalog.d.ts.map +1 -1
- package/dist/agent-catalog.js +1 -1
- package/dist/agent-catalog.js.map +1 -1
- package/dist/chores/chores.d.ts +1 -1
- package/dist/chores/chores.d.ts.map +1 -1
- package/dist/chores/probes.d.ts +1 -1
- package/dist/chores/probes.d.ts.map +1 -1
- package/dist/chores/stack.d.ts.map +1 -1
- package/dist/chores/stack.js +2 -1
- package/dist/chores/stack.js.map +1 -1
- package/dist/chores/verdict.d.ts +1 -1
- package/dist/chores/verdict.d.ts.map +1 -1
- package/dist/command-classes.d.ts +14 -0
- package/dist/command-classes.d.ts.map +1 -0
- package/dist/command-classes.js +168 -0
- package/dist/command-classes.js.map +1 -0
- package/dist/contracts/activity.contract.js +1 -1
- package/dist/contracts/activity.contract.js.map +1 -1
- package/dist/contracts/agent.contract.d.ts +40 -2
- package/dist/contracts/agent.contract.d.ts.map +1 -1
- package/dist/contracts/agent.contract.js +4 -1
- package/dist/contracts/agent.contract.js.map +1 -1
- package/dist/contracts/agents.contract.d.ts +24 -0
- package/dist/contracts/agents.contract.d.ts.map +1 -1
- package/dist/contracts/agents.contract.js +5 -1
- package/dist/contracts/agents.contract.js.map +1 -1
- package/dist/contracts/automations.contract.js +2 -1
- package/dist/contracts/automations.contract.js.map +1 -1
- package/dist/contracts/capabilities.contract.d.ts +63 -0
- package/dist/contracts/capabilities.contract.d.ts.map +1 -1
- package/dist/contracts/capabilities.contract.js +3 -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 +2 -1
- package/dist/contracts/chores.contract.js.map +1 -1
- package/dist/contracts/ci.contract.js +2 -1
- package/dist/contracts/ci.contract.js.map +1 -1
- package/dist/contracts/claude.contract.js +2 -1
- package/dist/contracts/claude.contract.js.map +1 -1
- package/dist/contracts/cursor.contract.js +2 -1
- package/dist/contracts/cursor.contract.js.map +1 -1
- package/dist/contracts/drafts.contract.d.ts.map +1 -1
- package/dist/contracts/drafts.contract.js +2 -1
- package/dist/contracts/drafts.contract.js.map +1 -1
- package/dist/contracts/endpoints.contract.d.ts.map +1 -1
- package/dist/contracts/endpoints.contract.js +2 -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 +2 -1
- package/dist/contracts/exit.contract.js.map +1 -1
- package/dist/contracts/extensions.contract.d.ts +42 -0
- package/dist/contracts/extensions.contract.d.ts.map +1 -1
- package/dist/contracts/extensions.contract.js +4 -1
- package/dist/contracts/extensions.contract.js.map +1 -1
- package/dist/contracts/git.contract.d.ts.map +1 -1
- package/dist/contracts/git.contract.js +4 -1
- package/dist/contracts/git.contract.js.map +1 -1
- package/dist/contracts/grok.contract.d.ts.map +1 -1
- package/dist/contracts/grok.contract.js +2 -1
- package/dist/contracts/grok.contract.js.map +1 -1
- package/dist/contracts/history.contract.d.ts.map +1 -1
- package/dist/contracts/history.contract.js +2 -1
- package/dist/contracts/history.contract.js.map +1 -1
- package/dist/contracts/host.contract.d.ts +7 -0
- package/dist/contracts/host.contract.d.ts.map +1 -1
- package/dist/contracts/host.contract.js +4 -1
- package/dist/contracts/host.contract.js.map +1 -1
- package/dist/contracts/intentic.contract.d.ts.map +1 -1
- package/dist/contracts/intentic.contract.js +2 -1
- package/dist/contracts/intentic.contract.js.map +1 -1
- package/dist/contracts/inventory.contract.js +1 -1
- package/dist/contracts/inventory.contract.js.map +1 -1
- package/dist/contracts/logs.contract.d.ts.map +1 -1
- package/dist/contracts/logs.contract.js +1 -1
- package/dist/contracts/logs.contract.js.map +1 -1
- package/dist/contracts/loops.contract.js +2 -1
- package/dist/contracts/loops.contract.js.map +1 -1
- package/dist/contracts/panels.contract.d.ts.map +1 -1
- package/dist/contracts/panels.contract.js +2 -1
- package/dist/contracts/panels.contract.js.map +1 -1
- package/dist/contracts/personas.contract.js +2 -1
- package/dist/contracts/personas.contract.js.map +1 -1
- package/dist/contracts/ports.contract.d.ts.map +1 -1
- package/dist/contracts/ports.contract.js +2 -1
- package/dist/contracts/ports.contract.js.map +1 -1
- package/dist/contracts/prepush.contract.d.ts.map +1 -1
- package/dist/contracts/prepush.contract.js +2 -1
- package/dist/contracts/prepush.contract.js.map +1 -1
- package/dist/contracts/providers.contract.d.ts.map +1 -1
- package/dist/contracts/providers.contract.js +2 -1
- package/dist/contracts/providers.contract.js.map +1 -1
- package/dist/contracts/public.contract.d.ts.map +1 -1
- package/dist/contracts/public.contract.js +2 -1
- package/dist/contracts/public.contract.js.map +1 -1
- package/dist/contracts/push.contract.d.ts.map +1 -1
- package/dist/contracts/push.contract.js +2 -1
- package/dist/contracts/push.contract.js.map +1 -1
- package/dist/contracts/runner.contract.d.ts +45 -2
- package/dist/contracts/runner.contract.d.ts.map +1 -1
- package/dist/contracts/runner.contract.js +10 -2
- package/dist/contracts/runner.contract.js.map +1 -1
- package/dist/contracts/secrets.contract.d.ts.map +1 -1
- package/dist/contracts/secrets.contract.js +2 -1
- package/dist/contracts/secrets.contract.js.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 +20 -0
- package/dist/contracts/settings.contract.d.ts.map +1 -1
- package/dist/contracts/settings.contract.js +3 -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 +2 -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 +2 -1
- package/dist/contracts/skills.contract.js.map +1 -1
- package/dist/contracts/system.contract.d.ts +31 -16
- package/dist/contracts/system.contract.d.ts.map +1 -1
- package/dist/contracts/system.contract.js +6 -1
- package/dist/contracts/system.contract.js.map +1 -1
- package/dist/contracts/translator.contract.d.ts.map +1 -1
- package/dist/contracts/translator.contract.js +4 -1
- package/dist/contracts/translator.contract.js.map +1 -1
- package/dist/contracts/usage.contract.js +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 +2 -1
- package/dist/contracts/vpn.contract.js.map +1 -1
- package/dist/contracts/webext.contract.d.ts +45 -0
- package/dist/contracts/webext.contract.d.ts.map +1 -0
- package/dist/contracts/webext.contract.js +12 -0
- package/dist/contracts/webext.contract.js.map +1 -0
- package/dist/contracts/workflows.contract.js +2 -1
- package/dist/contracts/workflows.contract.js.map +1 -1
- package/dist/contracts/workspace.contract.d.ts +2 -2
- package/dist/contracts/workspace.contract.d.ts.map +1 -1
- package/dist/contracts/workspace.contract.js +7 -1
- package/dist/contracts/workspace.contract.js.map +1 -1
- package/dist/definition-action.d.ts +7 -0
- package/dist/definition-action.d.ts.map +1 -0
- package/dist/definition-action.js +3 -0
- package/dist/definition-action.js.map +1 -0
- package/dist/definition.d.ts +124 -21
- package/dist/definition.d.ts.map +1 -1
- package/dist/definition.js +29 -7
- package/dist/definition.js.map +1 -1
- package/dist/events.d.ts +101 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +25 -1
- package/dist/events.js.map +1 -1
- package/dist/fast-tier.d.ts +1 -1
- package/dist/fast-tier.d.ts.map +1 -1
- package/dist/history-state.d.ts.map +1 -1
- package/dist/history-state.js +1 -0
- package/dist/history-state.js.map +1 -1
- package/dist/index.d.ts +355 -103
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +51 -1
- package/dist/index.js.map +1 -1
- package/dist/listener-protocol.js +1 -1
- package/dist/listener-protocol.js.map +1 -1
- package/dist/quick-model.d.ts +1 -1
- package/dist/quick-model.d.ts.map +1 -1
- package/dist/runner-protocol.d.ts +18 -0
- package/dist/runner-protocol.d.ts.map +1 -1
- package/dist/runner-protocol.js +8 -4
- package/dist/runner-protocol.js.map +1 -1
- package/dist/schemas/activity.d.ts +112 -0
- package/dist/schemas/activity.d.ts.map +1 -0
- package/dist/schemas/activity.js +70 -0
- package/dist/schemas/activity.js.map +1 -0
- package/dist/schemas/agent.d.ts +189 -0
- package/dist/schemas/agent.d.ts.map +1 -0
- package/dist/schemas/agent.js +170 -0
- package/dist/schemas/agent.js.map +1 -0
- package/dist/schemas/agents.d.ts +690 -0
- package/dist/schemas/agents.d.ts.map +1 -0
- package/dist/schemas/agents.js +314 -0
- package/dist/schemas/agents.js.map +1 -0
- package/dist/schemas/automations.d.ts +736 -0
- package/dist/schemas/automations.d.ts.map +1 -0
- package/dist/schemas/automations.js +218 -0
- package/dist/schemas/automations.js.map +1 -0
- package/dist/schemas/capabilities.d.ts +753 -0
- package/dist/schemas/capabilities.d.ts.map +1 -0
- package/dist/schemas/capabilities.js +269 -0
- package/dist/schemas/capabilities.js.map +1 -0
- package/dist/schemas/ci.d.ts +179 -0
- package/dist/schemas/ci.d.ts.map +1 -0
- package/dist/schemas/ci.js +99 -0
- package/dist/schemas/ci.js.map +1 -0
- package/dist/schemas/claude-gate.d.ts +13 -0
- package/dist/schemas/claude-gate.d.ts.map +1 -0
- package/dist/schemas/claude-gate.js +8 -0
- package/dist/schemas/claude-gate.js.map +1 -0
- package/dist/schemas/codebase-health.d.ts +56 -0
- package/dist/schemas/codebase-health.d.ts.map +1 -0
- package/dist/schemas/codebase-health.js +43 -0
- package/dist/schemas/codebase-health.js.map +1 -0
- package/dist/schemas/computers.d.ts +386 -0
- package/dist/schemas/computers.d.ts.map +1 -0
- package/dist/schemas/computers.js +107 -0
- package/dist/schemas/computers.js.map +1 -0
- package/dist/schemas/drafts.d.ts +84 -0
- package/dist/schemas/drafts.d.ts.map +1 -0
- package/dist/schemas/drafts.js +44 -0
- package/dist/schemas/drafts.js.map +1 -0
- package/dist/schemas/environment.d.ts +349 -0
- package/dist/schemas/environment.d.ts.map +1 -0
- package/dist/schemas/environment.js +111 -0
- package/dist/schemas/environment.js.map +1 -0
- package/dist/schemas/exit.d.ts +151 -0
- package/dist/schemas/exit.d.ts.map +1 -0
- package/dist/schemas/exit.js +115 -0
- package/dist/schemas/exit.js.map +1 -0
- package/dist/schemas/extension-updates.d.ts +1014 -0
- package/dist/schemas/extension-updates.d.ts.map +1 -0
- package/dist/schemas/extension-updates.js +197 -0
- package/dist/schemas/extension-updates.js.map +1 -0
- package/dist/schemas/fast-mode.d.ts +8 -0
- package/dist/schemas/fast-mode.d.ts.map +1 -0
- package/dist/schemas/fast-mode.js +3 -0
- package/dist/schemas/fast-mode.js.map +1 -0
- package/dist/schemas/git-history.d.ts +238 -0
- package/dist/schemas/git-history.d.ts.map +1 -0
- package/dist/schemas/git-history.js +152 -0
- package/dist/schemas/git-history.js.map +1 -0
- package/dist/schemas/git.d.ts +471 -0
- package/dist/schemas/git.d.ts.map +1 -0
- package/dist/schemas/git.js +204 -0
- package/dist/schemas/git.js.map +1 -0
- package/dist/schemas/history.d.ts +100 -0
- package/dist/schemas/history.d.ts.map +1 -0
- package/dist/schemas/history.js +54 -0
- package/dist/schemas/history.js.map +1 -0
- package/dist/schemas/hosts.d.ts +41 -0
- package/dist/schemas/hosts.d.ts.map +1 -0
- package/dist/schemas/hosts.js +18 -0
- package/dist/schemas/hosts.js.map +1 -0
- package/dist/schemas/intentic.d.ts +5 -0
- package/dist/schemas/intentic.d.ts.map +1 -0
- package/dist/schemas/intentic.js +3 -0
- package/dist/schemas/intentic.js.map +1 -0
- package/dist/schemas/internal.d.ts +8 -0
- package/dist/schemas/internal.d.ts.map +1 -0
- package/dist/schemas/internal.js +12 -0
- package/dist/schemas/internal.js.map +1 -0
- package/dist/schemas/inventory.d.ts +171 -0
- package/dist/schemas/inventory.d.ts.map +1 -0
- package/dist/schemas/inventory.js +51 -0
- package/dist/schemas/inventory.js.map +1 -0
- package/dist/schemas/logs.d.ts +67 -0
- package/dist/schemas/logs.d.ts.map +1 -0
- package/dist/schemas/logs.js +54 -0
- package/dist/schemas/logs.js.map +1 -0
- package/dist/schemas/loops.d.ts +415 -0
- package/dist/schemas/loops.d.ts.map +1 -0
- package/dist/schemas/loops.js +188 -0
- package/dist/schemas/loops.js.map +1 -0
- package/dist/schemas/maintenance.d.ts +557 -0
- package/dist/schemas/maintenance.d.ts.map +1 -0
- package/dist/schemas/maintenance.js +201 -0
- package/dist/schemas/maintenance.js.map +1 -0
- package/dist/schemas/marketplace.d.ts +64 -0
- package/dist/schemas/marketplace.d.ts.map +1 -0
- package/dist/schemas/marketplace.js +17 -0
- package/dist/schemas/marketplace.js.map +1 -0
- package/dist/schemas/panels.d.ts +61 -0
- package/dist/schemas/panels.d.ts.map +1 -0
- package/dist/schemas/panels.js +51 -0
- package/dist/schemas/panels.js.map +1 -0
- package/dist/schemas/personas.d.ts +122 -0
- package/dist/schemas/personas.d.ts.map +1 -0
- package/dist/schemas/personas.js +102 -0
- package/dist/schemas/personas.js.map +1 -0
- package/dist/schemas/plan-limits.d.ts +172 -0
- package/dist/schemas/plan-limits.d.ts.map +1 -0
- package/dist/schemas/plan-limits.js +126 -0
- package/dist/schemas/plan-limits.js.map +1 -0
- package/dist/schemas/ports.d.ts +71 -0
- package/dist/schemas/ports.d.ts.map +1 -0
- package/dist/schemas/ports.js +42 -0
- package/dist/schemas/ports.js.map +1 -0
- package/dist/schemas/provider-oauth.d.ts +128 -0
- package/dist/schemas/provider-oauth.d.ts.map +1 -0
- package/dist/schemas/provider-oauth.js +91 -0
- package/dist/schemas/provider-oauth.js.map +1 -0
- package/dist/schemas/provider-subscriptions.d.ts +9 -0
- package/dist/schemas/provider-subscriptions.d.ts.map +1 -0
- package/dist/schemas/provider-subscriptions.js +3 -0
- package/dist/schemas/provider-subscriptions.js.map +1 -0
- package/dist/schemas/public.d.ts +32 -0
- package/dist/schemas/public.d.ts.map +1 -0
- package/dist/schemas/public.js +29 -0
- package/dist/schemas/public.js.map +1 -0
- package/dist/schemas/push.d.ts +55 -0
- package/dist/schemas/push.d.ts.map +1 -0
- package/dist/schemas/push.js +60 -0
- package/dist/schemas/push.js.map +1 -0
- package/dist/schemas/secrets.d.ts +86 -0
- package/dist/schemas/secrets.d.ts.map +1 -0
- package/dist/schemas/secrets.js +51 -0
- package/dist/schemas/secrets.js.map +1 -0
- package/dist/schemas/sessions.d.ts +32 -0
- package/dist/schemas/sessions.d.ts.map +1 -0
- package/dist/schemas/sessions.js +11 -0
- package/dist/schemas/sessions.js.map +1 -0
- package/dist/schemas/settings.d.ts +548 -0
- package/dist/schemas/settings.d.ts.map +1 -0
- package/dist/schemas/settings.js +259 -0
- package/dist/schemas/settings.js.map +1 -0
- package/dist/schemas/share.d.ts +49 -0
- package/dist/schemas/share.d.ts.map +1 -0
- package/dist/schemas/share.js +26 -0
- package/dist/schemas/share.js.map +1 -0
- package/dist/schemas/shared.d.ts +22 -0
- package/dist/schemas/shared.d.ts.map +1 -0
- package/dist/schemas/shared.js +16 -0
- package/dist/schemas/shared.js.map +1 -0
- package/dist/schemas/system.d.ts +86 -0
- package/dist/schemas/system.d.ts.map +1 -0
- package/dist/schemas/system.js +64 -0
- package/dist/schemas/system.js.map +1 -0
- package/dist/schemas/terminal.d.ts +230 -0
- package/dist/schemas/terminal.d.ts.map +1 -0
- package/dist/schemas/terminal.js +133 -0
- package/dist/schemas/terminal.js.map +1 -0
- package/dist/schemas/usage.d.ts +113 -0
- package/dist/schemas/usage.d.ts.map +1 -0
- package/dist/schemas/usage.js +91 -0
- package/dist/schemas/usage.js.map +1 -0
- package/dist/schemas/vpn.d.ts +229 -0
- package/dist/schemas/vpn.d.ts.map +1 -0
- package/dist/schemas/vpn.js +115 -0
- package/dist/schemas/vpn.js.map +1 -0
- package/dist/schemas/webext.d.ts +98 -0
- package/dist/schemas/webext.d.ts.map +1 -0
- package/dist/schemas/webext.js +36 -0
- package/dist/schemas/webext.js.map +1 -0
- package/dist/schemas/workflows.d.ts +881 -0
- package/dist/schemas/workflows.d.ts.map +1 -0
- package/dist/schemas/workflows.js +164 -0
- package/dist/schemas/workflows.js.map +1 -0
- package/dist/schemas/workspace-repos.d.ts +143 -0
- package/dist/schemas/workspace-repos.d.ts.map +1 -0
- package/dist/schemas/workspace-repos.js +87 -0
- package/dist/schemas/workspace-repos.js.map +1 -0
- package/dist/schemas/workspace-search.d.ts +170 -0
- package/dist/schemas/workspace-search.d.ts.map +1 -0
- package/dist/schemas/workspace-search.js +85 -0
- package/dist/schemas/workspace-search.js.map +1 -0
- package/dist/schemas/workspace-setup.d.ts +48 -0
- package/dist/schemas/workspace-setup.d.ts.map +1 -0
- package/dist/schemas/workspace-setup.js +26 -0
- package/dist/schemas/workspace-setup.js.map +1 -0
- package/dist/schemas/workspace-tree.d.ts +120 -0
- package/dist/schemas/workspace-tree.d.ts.map +1 -0
- package/dist/schemas/workspace-tree.js +111 -0
- package/dist/schemas/workspace-tree.js.map +1 -0
- package/dist/webext-links.d.ts +13 -0
- package/dist/webext-links.d.ts.map +1 -0
- package/dist/webext-links.js +24 -0
- package/dist/webext-links.js.map +1 -0
- package/dist/webext-protocol.d.ts +8 -0
- package/dist/webext-protocol.d.ts.map +1 -0
- package/dist/webext-protocol.js +7 -0
- package/dist/webext-protocol.js.map +1 -0
- package/dist/workflow-faults.d.ts +1 -1
- package/dist/workflow-faults.d.ts.map +1 -1
- package/dist/workspace-state.d.ts +2 -2
- package/dist/workspace-state.d.ts.map +1 -1
- package/dist/workspace-state.js +2 -2
- package/dist/workspace-state.js.map +1 -1
- package/package.json +15 -4
- package/src/agent-catalog.test.ts +1 -1
- package/src/agent-catalog.ts +4 -11
- package/src/chores/chores.ts +1 -1
- package/src/chores/probes.ts +1 -1
- package/src/chores/stack.test.ts +19 -0
- package/src/chores/stack.ts +19 -3
- package/src/chores/verdict.test.ts +11 -1
- package/src/chores/verdict.ts +1 -1
- package/src/command-classes.test.ts +378 -0
- package/src/command-classes.ts +378 -0
- package/src/contracts/activity.contract.ts +1 -1
- package/src/contracts/agent.contract.ts +4 -13
- package/src/contracts/agents.contract.ts +6 -6
- package/src/contracts/automations.contract.ts +2 -2
- package/src/contracts/capabilities.contract.ts +3 -4
- package/src/contracts/chores.contract.ts +2 -1
- package/src/contracts/ci.contract.ts +2 -2
- package/src/contracts/claude.contract.ts +2 -2
- package/src/contracts/cursor.contract.ts +2 -2
- package/src/contracts/drafts.contract.ts +2 -1
- package/src/contracts/endpoints.contract.ts +2 -1
- package/src/contracts/exit.contract.ts +2 -1
- package/src/contracts/extensions.contract.ts +5 -5
- package/src/contracts/git.contract.ts +19 -18
- package/src/contracts/grok.contract.ts +2 -1
- package/src/contracts/history.contract.ts +2 -1
- package/src/contracts/host.contract.ts +4 -1
- package/src/contracts/intentic.contract.ts +2 -1
- package/src/contracts/inventory.contract.ts +1 -1
- package/src/contracts/logs.contract.ts +7 -1
- package/src/contracts/loops.contract.ts +2 -2
- package/src/contracts/panels.contract.ts +2 -1
- package/src/contracts/personas.contract.ts +3 -3
- package/src/contracts/ports.contract.ts +3 -2
- package/src/contracts/prepush.contract.ts +2 -1
- package/src/contracts/providers.contract.ts +2 -1
- package/src/contracts/public.contract.ts +3 -2
- package/src/contracts/push.contract.ts +2 -1
- package/src/contracts/runner.contract.ts +18 -2
- package/src/contracts/secrets.contract.ts +2 -1
- package/src/contracts/sessions.contract.ts +1 -1
- package/src/contracts/settings.contract.ts +3 -9
- package/src/contracts/share.contract.ts +3 -2
- package/src/contracts/skills.contract.ts +2 -1
- package/src/contracts/system.contract.ts +6 -9
- package/src/contracts/translator.contract.ts +4 -1
- package/src/contracts/usage.contract.ts +1 -1
- package/src/contracts/vpn.contract.ts +2 -8
- package/src/contracts/webext.contract.ts +37 -0
- package/src/contracts/workflows.contract.ts +2 -2
- package/src/contracts/workspace.contract.ts +10 -12
- package/src/conversation-ids.test.ts +1 -1
- package/src/definition-action.ts +8 -0
- package/src/definition.ts +74 -10
- package/src/events.ts +84 -22
- package/src/fast-tier.ts +1 -1
- package/src/history-state.ts +5 -0
- package/src/host-protocol.ts +1 -1
- package/src/hostnames.test.ts +2 -2
- package/src/index.ts +60 -1
- package/src/listener-protocol.ts +1 -1
- package/src/quick-model.ts +1 -1
- package/src/runner-protocol.ts +35 -5
- package/src/schemas/activity.ts +123 -0
- package/src/schemas/agent.ts +409 -0
- package/src/schemas/agents.ts +802 -0
- package/src/schemas/automations.ts +510 -0
- package/src/schemas/capabilities.ts +729 -0
- package/src/schemas/ci.ts +235 -0
- package/src/schemas/claude-gate.ts +13 -0
- package/src/schemas/codebase-health.ts +64 -0
- package/src/schemas/computers.ts +287 -0
- package/src/schemas/drafts.ts +108 -0
- package/src/schemas/environment.ts +276 -0
- package/src/schemas/exit.ts +222 -0
- package/src/schemas/extension-updates.ts +322 -0
- package/src/schemas/fast-mode.ts +8 -0
- package/src/schemas/git-history.ts +265 -0
- package/src/schemas/git.ts +430 -0
- package/src/schemas/history.ts +112 -0
- package/src/schemas/hosts.ts +37 -0
- package/src/schemas/intentic.ts +2 -0
- package/src/schemas/internal.ts +17 -0
- package/src/schemas/inventory.ts +68 -0
- package/src/schemas/logs.ts +96 -0
- package/src/schemas/loops.ts +401 -0
- package/src/schemas/maintenance.ts +421 -0
- package/src/schemas/marketplace.ts +23 -0
- package/src/schemas/panels.ts +99 -0
- package/src/schemas/personas.ts +281 -0
- package/src/schemas/plan-limits.ts +255 -0
- package/src/schemas/ports.ts +84 -0
- package/src/schemas/provider-oauth.ts +191 -0
- package/src/schemas/provider-subscriptions.ts +11 -0
- package/src/schemas/public.ts +52 -0
- package/src/schemas/push.ts +112 -0
- package/src/schemas/secrets.ts +68 -0
- package/src/schemas/sessions.ts +16 -0
- package/src/schemas/settings.ts +932 -0
- package/src/schemas/share.ts +71 -0
- package/src/schemas/shared.ts +32 -0
- package/src/schemas/system.ts +156 -0
- package/src/schemas/terminal.ts +286 -0
- package/src/schemas/usage.ts +303 -0
- package/src/{schemas.test.ts → schemas/version-seam.test.ts} +4 -2
- package/src/schemas/vpn.ts +215 -0
- package/src/schemas/webext.ts +79 -0
- package/src/schemas/workflows.ts +413 -0
- package/src/schemas/workspace-repos.ts +123 -0
- package/src/schemas/workspace-search.ts +141 -0
- package/src/schemas/workspace-setup.ts +43 -0
- package/src/schemas/workspace-tree.ts +234 -0
- package/src/title.test.ts +1 -1
- package/src/webext-links.ts +80 -0
- package/src/webext-protocol.ts +27 -0
- package/src/workflow-faults.test.ts +1 -1
- package/src/workflow-faults.ts +1 -1
- package/src/workspace-state.test.ts +3 -3
- package/src/workspace-state.ts +8 -13
- package/dist/schemas.d.ts +0 -9909
- package/dist/schemas.d.ts.map +0 -1
- package/dist/schemas.js +0 -4288
- package/dist/schemas.js.map +0 -1
- package/src/schemas.ts +0 -10090
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
// automations: scheduled agent wake-ups (.intentic/config/automations.json)
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { AgentHarnessSchema, AgentOriginSchema, AgentProviderSchema } from "./agent.js";
|
|
4
|
+
import { AgentSummarySchema } from "./agents.js";
|
|
5
|
+
import { entryId } from "./internal.js";
|
|
6
|
+
// An automation wakes the agent autonomously: the daemon's scheduler fires each enabled automation on its
|
|
7
|
+
// trigger, runs the optional guard command (a shell command in the workspace; non-zero exit skips the wake),
|
|
8
|
+
// then runs one agent turn with the prompt. The manifest is user config; run history is daemon-recorded.
|
|
9
|
+
|
|
10
|
+
// `schedule` fires on its cron; `event` fires when an external system POSTs /automations/{id}/fire?token=…
|
|
11
|
+
// (a plain Hono route, webhook bodies are arbitrary). The token is the webhook's own auth (senders can't do
|
|
12
|
+
// Google ID tokens): optional on input, the daemon generates one on upsert, and always present in stored and
|
|
13
|
+
// listed automations, so the owner's UI can render the copyable URL.
|
|
14
|
+
// `listener` fires from a realtime source's connection to the provider (an extension's gateway process holds
|
|
15
|
+
// it, e.g. Discord), no cron, no token, never reachable via /fire. channelId narrows to one channel; absent ⇒
|
|
16
|
+
// every channel the bot can read. eventType narrows to one kind of event (a Discord message, a live voice
|
|
17
|
+
// utterance batch, or a finished voice transcript); absent ⇒ all event kinds the source emits. mentioned
|
|
18
|
+
// narrows message events to those that @mention one of the workspace's bots or reply to a bot's message;
|
|
19
|
+
// absent ⇒ all messages. `provider` and `eventType` are open strings, a realtime source is now extension-
|
|
20
|
+
// declared (contributes.listener), so the daemon validates a listener trigger at upsert against `webchat` ∪ the
|
|
21
|
+
// installed extensions' declared providers/events rather than a hardcoded enum here.
|
|
22
|
+
// `webchat` is the exception: it has no gateway. An embeddable widget POSTs a visitor's message to
|
|
23
|
+
// /webchat/<id>/message and the agent's reply streams back over SSE. Its address is the public automation id, so
|
|
24
|
+
// allowedOrigins (the widget's embed sites) + a per-conversation rate limit are its abuse boundary, no secret
|
|
25
|
+
// token can live in a browser.
|
|
26
|
+
// `ci` is the other gateway-less source: the daemon's own pipeline receiver (ci/events.ts) dispatches it from a
|
|
27
|
+
// provider webhook, or from the REST poller on a sandbox whose hooks could not be registered. Its channelId is
|
|
28
|
+
// the workspace repo, and `branch` is its SECOND narrowing axis, a fleet pushes a branch per agent, so a
|
|
29
|
+
// pipeline trigger that can only say "this repo" says "every agent's every failure".
|
|
30
|
+
// `workspace` fires from the sandbox's OWN codebase instead of the outside world, see WorkspaceEventKindSchema.
|
|
31
|
+
|
|
32
|
+
// What the daemon emits as the fleet works, and what a `workspace` trigger names. These are the events a code
|
|
33
|
+
// CHORE runs on (continuous review, post-land checks): the daemon is both producer and consumer, so unlike
|
|
34
|
+
// `event` there is no token and no route, nothing outside the sandbox can reach them.
|
|
35
|
+
//
|
|
36
|
+
// The two OVERLAP on the common path: a clean turn auto-lands, firing both. A chore should name exactly one.
|
|
37
|
+
// `turn.settled` fires once per isolated turn whatever its outcome, so it also covers the errored and
|
|
38
|
+
// conflicted turns most worth a second pair of eyes, and it fires while the user is still looking at the diff,
|
|
39
|
+
// before they decide to land. `agent.landed` fires only when work actually reached the main tree, including an
|
|
40
|
+
// explicit Land from the review panel long after the turn ended.
|
|
41
|
+
//
|
|
42
|
+
// The `deps.*` pair fires from the dependency verifier (workspace/verify-deps.ts) rather than a turn: after a
|
|
43
|
+
// land drifts dependencies, the daemon installs them and runs the tree's own checks, and these are that chain's
|
|
44
|
+
// EDGES, `deps.broken` when the checks go red after a landed change, `deps.fixed` when a later land turns them
|
|
45
|
+
// green again. Edges, not states, on the ci-events precedent (pipeline_broken): a tree that is red and stays
|
|
46
|
+
// red emits nothing, so a fix chore is woken by the breakage, never by the standing colour.
|
|
47
|
+
export const WorkspaceEventKindSchema = z.enum(["turn.settled", "agent.landed", "deps.broken", "deps.fixed"]);
|
|
48
|
+
export type WorkspaceEventKind = z.infer<typeof WorkspaceEventKindSchema>;
|
|
49
|
+
// The payload a workspace-triggered wake carries: one JSON object, in $AUTOMATION_PAYLOAD for the guard and
|
|
50
|
+
// appended to the prompt for the turn.
|
|
51
|
+
//
|
|
52
|
+
// `repos` names the change to look at as an OPEN span, `git -C <dir> diff <from>`, with no upper bound. Each
|
|
53
|
+
// `from` is where that repo stood before the turn (its last landed tip, or the base it branched from); the
|
|
54
|
+
// other end is deliberately the working tree rather than a sha, because a turn that ERRORED left its work
|
|
55
|
+
// uncommitted in the worktree and a commit-to-commit span would report it as nothing at all. `dir` is that
|
|
56
|
+
// repo's dir inside the agent's own checkout, so a chore reads the agent's work without touching /work.
|
|
57
|
+
//
|
|
58
|
+
// No diffstat rides along on purpose: the registry's counts are refreshed at land, so an errored or conflicted
|
|
59
|
+
// turn would carry stale numbers, and a guard that wants a size threshold gets the true one from
|
|
60
|
+
// `git -C <dir> diff --numstat <from>` for the price of one spawn.
|
|
61
|
+
export const WorkspaceEventSchema = z.object({
|
|
62
|
+
event: WorkspaceEventKindSchema,
|
|
63
|
+
agentId: z.string(),
|
|
64
|
+
title: z.string().optional(),
|
|
65
|
+
branch: z.string(),
|
|
66
|
+
// `ready` is a clean turn whose delta was HELD on the branch (auto-land off), for a chore, the moment
|
|
67
|
+
// before the user's deliberate Land, which is exactly when a pre-land review wants to run.
|
|
68
|
+
outcome: z.enum(["landed", "conflict", "ready", "idle", "error"]),
|
|
69
|
+
repos: z.array(z.object({ repo: z.string(), from: z.string(), dir: z.string() })),
|
|
70
|
+
/* The `deps.*` events' own facts, absent on every turn-borne event. What a fix chore needs to start
|
|
71
|
+
* without rediscovering it: which project broke, the exact command that judged it, how it exited, and the
|
|
72
|
+
* tail of its output, bounded, because the payload rides a prompt and a guard's environment, and the full
|
|
73
|
+
* log is one attach away in the project's `--verify` terminal panel. `attempt` counts consecutive red
|
|
74
|
+
* verifies since the last green, so a guard can cap retries in one visible line of shell. */
|
|
75
|
+
deps: z
|
|
76
|
+
.object({
|
|
77
|
+
project: z.string(),
|
|
78
|
+
command: z.string(),
|
|
79
|
+
exitCode: z.number(),
|
|
80
|
+
attempt: z.number(),
|
|
81
|
+
logTail: z.string(),
|
|
82
|
+
})
|
|
83
|
+
.optional(),
|
|
84
|
+
});
|
|
85
|
+
export type WorkspaceEvent = z.infer<typeof WorkspaceEventSchema>;
|
|
86
|
+
export const TriggerSchema = z.discriminatedUnion("kind", [
|
|
87
|
+
z.object({
|
|
88
|
+
kind: z.literal("schedule").describe("On a clock."),
|
|
89
|
+
cron: z.string().min(1).describe("When, in cron notation."),
|
|
90
|
+
}),
|
|
91
|
+
z.object({
|
|
92
|
+
kind: z.literal("event").describe("When something calls its webhook."),
|
|
93
|
+
token: z
|
|
94
|
+
.string()
|
|
95
|
+
.min(1)
|
|
96
|
+
.optional()
|
|
97
|
+
.describe("The credential a caller presents. It is the only one in the exchange, because an outside sender has no identity here."),
|
|
98
|
+
}),
|
|
99
|
+
z.object({
|
|
100
|
+
kind: z.literal("listener").describe("When a message arrives from somewhere outside."),
|
|
101
|
+
provider: z.string().min(1).describe("Which service to listen to."),
|
|
102
|
+
channelId: z.string().min(1).optional().describe("Narrow it to one channel or thread."),
|
|
103
|
+
eventType: z.string().min(1).optional().describe("Narrow it to one kind of event."),
|
|
104
|
+
mentioned: z.boolean().optional().describe("Only when the agent is actually addressed, rather than on everything said in earshot."),
|
|
105
|
+
// ci only: the git ref the pipeline ran on. Absent ⇒ every branch of the matched repos.
|
|
106
|
+
branch: z
|
|
107
|
+
.string()
|
|
108
|
+
.min(1)
|
|
109
|
+
.optional()
|
|
110
|
+
.describe("Narrow it to one branch, for the sources that have branches. Absent means every branch of the repositories it matches."),
|
|
111
|
+
// webchat only: the website origins allowed to POST to the widget endpoint. Absent/empty ⇒ none admitted.
|
|
112
|
+
allowedOrigins: z.array(z.string()).optional().describe("Which websites may reach the chat widget. Absent or empty admits nobody."),
|
|
113
|
+
}),
|
|
114
|
+
// `repo` narrows to events whose span touches one workspace repo ("root" or a repo id); absent ⇒ any.
|
|
115
|
+
z.object({
|
|
116
|
+
kind: z.literal("workspace").describe("When something happens to the files or the repositories."),
|
|
117
|
+
event: WorkspaceEventKindSchema.describe("Which happening."),
|
|
118
|
+
repo: z.string().min(1).optional().describe("Narrow it to one repository. Absent means any of them."),
|
|
119
|
+
}),
|
|
120
|
+
]);
|
|
121
|
+
export type Trigger = z.infer<typeof TriggerSchema>;
|
|
122
|
+
/* The Front Desk widget's settings, everything about the embeddable chat that isn't the automation's prompt.
|
|
123
|
+
* Present only on `webchat` listener automations; the trigger keeps `allowedOrigins` because that one is the
|
|
124
|
+
* admission gate the message route reads, not a rendering choice.
|
|
125
|
+
*
|
|
126
|
+
* Split deliberately into what the WIDGET may read (title/greeting/accent/position/access/googleClientId/
|
|
127
|
+
* turnstileSiteKey, all public by construction, they ship to a stranger's browser) and what only the daemon
|
|
128
|
+
* may read (turnstileSecret). GET /webchat/<id>/config serves the first group by naming it, never by omitting
|
|
129
|
+
* the second: a field added here is invisible to the widget until it is listed there. */
|
|
130
|
+
export const WebchatConfigSchema = z.object({
|
|
131
|
+
// `public` admits anyone; `google` refuses a message that carries no verifiable Google ID token. Absent ⇒
|
|
132
|
+
// public, a Front Desk with no access setting is the anonymous support box it looks like.
|
|
133
|
+
access: z
|
|
134
|
+
.enum(["public", "google"])
|
|
135
|
+
.optional()
|
|
136
|
+
.describe("Who may write to it. Absent means anyone, which is the anonymous support box it looks like."),
|
|
137
|
+
// Ask an anonymous visitor for a display name before the first message. Cosmetic: the name is typed, so it
|
|
138
|
+
// reaches the model as untrusted `displayName`, never as identity.
|
|
139
|
+
requireName: z
|
|
140
|
+
.boolean()
|
|
141
|
+
.optional()
|
|
142
|
+
.describe(
|
|
143
|
+
"Ask a visitor for a name first. Cosmetic: the name is typed, so it reaches the model as something a stranger said, never as identity.",
|
|
144
|
+
),
|
|
145
|
+
/* The bot ceiling. `turnstile` is Cloudflare's (invisible, needs the site's own keys); `pow` is a
|
|
146
|
+
* hashcash-style challenge the daemon issues and the widget solves in a worker, so a site with no
|
|
147
|
+
* Cloudflare account still has something. Absent ⇒ off: the origin allowlist and the rate limit are then
|
|
148
|
+
* the whole boundary, which is the right default for an internal or invite-only page. */
|
|
149
|
+
antiBot: z
|
|
150
|
+
.enum(["turnstile", "pow"])
|
|
151
|
+
.optional()
|
|
152
|
+
.describe(
|
|
153
|
+
"How to keep bots out: a third-party check that needs the site's own keys, or a puzzle the sandbox sets and the widget solves, so a site with no such account still has something. Absent leaves the site allowlist and the rate limit as the whole boundary.",
|
|
154
|
+
),
|
|
155
|
+
turnstileSiteKey: z.string().optional().describe("The public half of those keys, which ships to the visitor's browser."),
|
|
156
|
+
turnstileSecret: z.string().optional().describe("The private half, which the sandbox keeps and the widget never sees."),
|
|
157
|
+
// The site's OWN Google OAuth web client id. It cannot be intentic's: Google Identity Services only issues
|
|
158
|
+
// a token to an authorized JavaScript origin, and intentic's client can't list every customer domain.
|
|
159
|
+
googleClientId: z
|
|
160
|
+
.string()
|
|
161
|
+
.optional()
|
|
162
|
+
.describe(
|
|
163
|
+
"The site's own sign-in client id. It cannot be ours: a sign-in is only issued to an approved origin, and no single client can list every customer's domain.",
|
|
164
|
+
),
|
|
165
|
+
/* Widget chrome. `position` picks the launcher corner.
|
|
166
|
+
*
|
|
167
|
+
* `accent` is a HEX colour, not any CSS colour, because the widget derives values from its channels rather
|
|
168
|
+
* than just painting it: a glyph step for the scheme, a 14% wash for the send button, a bubble edge, a focus
|
|
169
|
+
* ring, and the label that goes on top (see webchat-widget's styles.ts). A colour we cannot read is a widget
|
|
170
|
+
* with half its accent silently missing, so the unreadable case is rejected here instead. */
|
|
171
|
+
title: z.string().max(80).optional(),
|
|
172
|
+
greeting: z.string().max(500).optional(),
|
|
173
|
+
accent: z
|
|
174
|
+
.string()
|
|
175
|
+
.regex(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/, "accent must be a hex colour, e.g. #e47100")
|
|
176
|
+
.optional(),
|
|
177
|
+
position: z.enum(["top-right", "top-left", "bottom-right", "bottom-left"]).optional(),
|
|
178
|
+
/* Two ceilings on top of the route's fixed per-minute window, because a public endpoint's real exposure is
|
|
179
|
+
* cost, not request rate: `dailyMessageMax` caps the whole automation per UTC day, `conversationMessageMax`
|
|
180
|
+
* caps one visitor thread for its lifetime.
|
|
181
|
+
*
|
|
182
|
+
* `dailyMessageMax` absent ⇒ WEBCHAT_DAILY_MAX_DEFAULT, not uncapped. Every message here is an agent turn
|
|
183
|
+
* billed to the owner, and the per-minute window bounds the RATE without bounding the DAY, twenty a minute,
|
|
184
|
+
* sustained, is tens of thousands of turns before anyone notices. A Front Desk nobody configured should not be
|
|
185
|
+
* able to spend that, so the safe number is the one you get for free and the owner raises it deliberately.
|
|
186
|
+
* `conversationMessageMax` stays optional-means-uncapped: it is per visitor thread, which the daily ceiling
|
|
187
|
+
* already bounds in aggregate. */
|
|
188
|
+
dailyMessageMax: z.number().int().positive().optional(),
|
|
189
|
+
conversationMessageMax: z.number().int().positive().optional(),
|
|
190
|
+
// (WEBCHAT_DAILY_MAX_DEFAULT, below the schema, is the number `dailyMessageMax` falls back to.)
|
|
191
|
+
// How long a visitor thread keeps resuming the same conversation before the next message starts a fresh
|
|
192
|
+
// one. Absent ⇒ WEBCHAT_SESSION_TTL_MS (the daemon's default).
|
|
193
|
+
sessionTtlMinutes: z.number().int().positive().optional(),
|
|
194
|
+
});
|
|
195
|
+
export type WebchatConfig = z.infer<typeof WebchatConfigSchema>;
|
|
196
|
+
/* The daily agent-turn ceiling a Front Desk gets when its owner sets none. Lives here rather than beside the
|
|
197
|
+
* route that enforces it because both ends need the number: the daemon to apply it, and the automation editor
|
|
198
|
+
* to show the owner what they are already protected by (an invisible limit is one people hit and file as a bug).
|
|
199
|
+
*
|
|
200
|
+
* 200 is chosen to be irrelevant to real support traffic and decisive against a script. A Front Desk answering
|
|
201
|
+
* two hundred questions in one UTC day is a busy one; a scripted flood reaches that in ten seconds and then
|
|
202
|
+
* stops costing anything. */
|
|
203
|
+
export const WEBCHAT_DAILY_MAX_DEFAULT = 200;
|
|
204
|
+
/* ---- the widget wire: three shapes GET /webchat/<id>/config, GET …/challenge and POST …/message speak ----
|
|
205
|
+
*
|
|
206
|
+
* They live here, beside the stored config they derive from, because the Front Desk widget is a SECOND client of
|
|
207
|
+
* this daemon, a bundle running on a stranger's page, and the reason this package exists is that both ends of
|
|
208
|
+
* a wire read one definition. The widget imports these as types only (`import type`), so zod never reaches a
|
|
209
|
+
* visitor's browser. */
|
|
210
|
+
|
|
211
|
+
// What the widget is told about itself. Fully RESOLVED, every default is applied daemon-side, so the widget
|
|
212
|
+
// carries no fallback logic and one place decides what an unset field means. Everything here is public by
|
|
213
|
+
// construction: it ships to any browser that can reach the endpoint from an allowed origin.
|
|
214
|
+
export const WebchatPublicConfigSchema = z.object({
|
|
215
|
+
automationId: z.string(),
|
|
216
|
+
title: z.string(),
|
|
217
|
+
greeting: z.string(),
|
|
218
|
+
accent: z.string(),
|
|
219
|
+
position: z.enum(["top-right", "top-left", "bottom-right", "bottom-left"]),
|
|
220
|
+
access: z.enum(["public", "google"]),
|
|
221
|
+
requireName: z.boolean(),
|
|
222
|
+
// "off" is spelled out rather than left absent: the widget branches on this, and a missing field that means
|
|
223
|
+
// "no challenge" is the kind of default that turns one serialization bug into an open door.
|
|
224
|
+
antiBot: z.enum(["turnstile", "pow", "off"]),
|
|
225
|
+
turnstileSiteKey: z.string().optional(),
|
|
226
|
+
googleClientId: z.string().optional(),
|
|
227
|
+
});
|
|
228
|
+
export type WebchatPublicConfig = z.infer<typeof WebchatPublicConfigSchema>;
|
|
229
|
+
// A proof-of-work challenge: find a nonce whose SHA-256 of `${salt}:${nonce}` starts with `difficulty` zero
|
|
230
|
+
// bits. Issued per visitor conversation, spent on its first message.
|
|
231
|
+
export const WebchatChallengeSchema = z.object({ salt: z.string(), difficulty: z.number().int().positive() });
|
|
232
|
+
export type WebchatChallenge = z.infer<typeof WebchatChallengeSchema>;
|
|
233
|
+
// One visitor message. `conversationId` is the widget's own localStorage id, it threads the visitor's messages
|
|
234
|
+
// into ONE sandbox conversation, so it is the thread key, not a secret (anyone can mint one; the origin
|
|
235
|
+
// allowlist, the challenge and the rate limit are the gate).
|
|
236
|
+
export const WebchatMessageSchema = z.object({
|
|
237
|
+
conversationId: z.string().min(1).max(200),
|
|
238
|
+
content: z.string().min(1),
|
|
239
|
+
// What the visitor TYPED as their name. Never identity, it reaches the model tagged as unverified, and a
|
|
240
|
+
// signed-in visitor's verified name comes from the ID token instead.
|
|
241
|
+
displayName: z.string().max(200).optional(),
|
|
242
|
+
// A Google ID token from the site's own client id, verified daemon-side against Google's JWKS.
|
|
243
|
+
idToken: z.string().optional(),
|
|
244
|
+
// The anti-bot answer, whichever kind the config asked for. Checked once per conversation, not per message.
|
|
245
|
+
turnstileToken: z.string().optional(),
|
|
246
|
+
powNonce: z.string().optional(),
|
|
247
|
+
// The widget's own transcript, sent ONLY on the first message of a thread, after that the sandbox
|
|
248
|
+
// conversation resumes and carries its own context.
|
|
249
|
+
history: z
|
|
250
|
+
.array(z.object({ author: z.string().optional(), content: z.string() }))
|
|
251
|
+
.max(50)
|
|
252
|
+
.optional(),
|
|
253
|
+
});
|
|
254
|
+
export type WebchatMessage = z.infer<typeof WebchatMessageSchema>;
|
|
255
|
+
export const AutomationSchema = z.object({
|
|
256
|
+
id: entryId.describe("The automation's id."),
|
|
257
|
+
trigger: TriggerSchema.describe("What sets it off: a schedule, an event in the workspace, a message arriving from outside, or a webhook."),
|
|
258
|
+
// Shell command run in the workspace root before waking; exit 0 ⇒ wake, non-zero ⇒ the run is "skipped".
|
|
259
|
+
guard: z
|
|
260
|
+
.string()
|
|
261
|
+
.min(1)
|
|
262
|
+
.optional()
|
|
263
|
+
.describe(
|
|
264
|
+
"A command run before the wake that decides whether there is anything to do. Skipped by the guard is often the most useful thing an automation can report.",
|
|
265
|
+
),
|
|
266
|
+
prompt: z.string().min(1).describe("What the woken agent is told."),
|
|
267
|
+
// The Front Desk widget's settings, `webchat` listener automations only, ignored on every other trigger.
|
|
268
|
+
webchat: WebchatConfigSchema.optional().describe("Settings for the public chat widget, for an automation that answers visitors."),
|
|
269
|
+
/* NARROW THIS ONE JOB FURTHER than the persona it runs as, raw tool names, and the escape hatch under the
|
|
270
|
+
* shelves rather than the way anyone is expected to answer this question.
|
|
271
|
+
*
|
|
272
|
+
* The persona (`actsAs` below) is where a session's toolbox is decided now, because the answer is worth
|
|
273
|
+
* reusing: the same bounds apply to the chat, the workflow and the Front Desk that name the same card. This
|
|
274
|
+
* stays for the job that needs LESS than its persona allows, and only less, which is a rule the composer
|
|
275
|
+
* enforces rather than a convention: an edit here can never hand back a shelf the persona switched off. */
|
|
276
|
+
allowedTools: z
|
|
277
|
+
.array(z.string().min(1))
|
|
278
|
+
.optional()
|
|
279
|
+
.describe(
|
|
280
|
+
"Narrow the woken turn to these tools. For one driven by an outside message this list is the real boundary, because prompt wording is only advice and an empty toolbox is not.",
|
|
281
|
+
),
|
|
282
|
+
// Which provider adapter serves the wake; absent ⇒ claude. Same dispatch as a chat turn (AgentTurnSchema.agent).
|
|
283
|
+
agent: AgentProviderSchema.optional().describe("Which provider serves the wake."),
|
|
284
|
+
/* Which connected account of that provider serves the wake; absent ⇒ the provider's first account, exactly
|
|
285
|
+
* as for a chat turn (AgentTurnSchema.account).
|
|
286
|
+
*
|
|
287
|
+
* An automation needs this more than a chat does, and for a reason a chat never meets: nobody is watching.
|
|
288
|
+
* A sandbox holds several accounts side by side, and when the first one is out of headroom, or belongs to
|
|
289
|
+
* an organization that has disabled the plan, every fire of every automation errors against it until a
|
|
290
|
+
* human happens to read the row. Pinning the wake to an account that can actually run is the difference
|
|
291
|
+
* between "my nightly sweep is quiet" and a Front Desk that turns visitors away all day. */
|
|
292
|
+
account: z.string().optional().describe("Which account pays for it."),
|
|
293
|
+
/* WHICH FACE THE WAKE SHOWS THE OUTSIDE WORLD (AgentTurnSchema.actsAs, read its note for why this is not
|
|
294
|
+
* spelled `account`, which is the field directly above and means who PAYS).
|
|
295
|
+
*
|
|
296
|
+
* Absent ⇒ the wake reaches NO logged-in account at all. That is the one place this whole layer stops being
|
|
297
|
+
* a convenience and becomes a boundary, and it is deliberately the strictest default in the schema: an
|
|
298
|
+
* automation fires with nobody at the composer, on a prompt that, for a Front Desk, a stranger helped write.
|
|
299
|
+
* `allowedTools` above already carries this exact reasoning for tools; an unrepeatable public post deserves
|
|
300
|
+
* it at least as much. An automation that genuinely means "post as us" says so, once, in a field a reviewer
|
|
301
|
+
* can see. */
|
|
302
|
+
actsAs: entryId.optional().describe("Which persona it speaks as. An unwatched turn naming none reaches no signed-in account at all."),
|
|
303
|
+
// Which harness (agentic loop) runs the wake; absent ⇒ native. Same semantics as AgentTurnSchema.harness.
|
|
304
|
+
harness: AgentHarnessSchema.optional().describe("Which agentic loop runs it."),
|
|
305
|
+
// Which model the wake runs on (see agent-catalog.ts modelsFor); absent ⇒ the provider's default.
|
|
306
|
+
model: z.string().optional().describe("Which model runs it."),
|
|
307
|
+
// When true, a fire doesn't wake the agent, it's held in the approvals queue until the owner approves.
|
|
308
|
+
requireApproval: z.boolean().optional().describe("Hold every fire for a person instead of running it. Only a person can release one of those."),
|
|
309
|
+
/* The middle ground between firing instantly and requiring a click: the fire is held in the same approvals
|
|
310
|
+
* queue, visibly, and the daemon runs it ITSELF once the hold has elapsed AND no agent turn is live, the
|
|
311
|
+
* owner's window to cancel or start it early, with silence as consent. What a fix chore wants: time to see
|
|
312
|
+
* "checks broke, a fix is about to start" without a standing decision to make. `requireApproval` wins when
|
|
313
|
+
* both are set, an explicit "ask me" must never quietly become "unless I'm slow". */
|
|
314
|
+
holdForSeconds: z.number().optional().describe("Hold each fire this long before running it anyway, which is a delay rather than a decision."),
|
|
315
|
+
// A code CHORE: maintenance of THIS codebase rather than a reaction to the outside world. Purely a
|
|
316
|
+
// classification, the daemon fires a chore exactly like any other automation, but it cannot be derived
|
|
317
|
+
// from the trigger, which is why it is stored: a nightly `pnpm audit` sweep and a nightly Stripe poll are
|
|
318
|
+
// both `schedule`, and belong on different shelves. Absent ⇒ an ordinary automation.
|
|
319
|
+
chore: z
|
|
320
|
+
.boolean()
|
|
321
|
+
.optional()
|
|
322
|
+
.describe("This automation is a maintenance job, which is what files it under chores rather than among ordinary automations."),
|
|
323
|
+
enabled: z.boolean().describe("Whether it fires at all."),
|
|
324
|
+
});
|
|
325
|
+
export type Automation = z.infer<typeof AutomationSchema>;
|
|
326
|
+
// A wake held for owner approval (.intentic/records/approvals/<id>.json, one file per held wake). It snapshots the
|
|
327
|
+
// trigger payload so an approved run replays exactly what fired, even across a daemon restart. The id is minted
|
|
328
|
+
// by the daemon (an entryId-safe filename).
|
|
329
|
+
export const AutomationApprovalSchema = z.object({
|
|
330
|
+
id: entryId.describe("This waiting item's own id, which approving and rejecting take."),
|
|
331
|
+
automationId: z.string().describe("Which automation it came from."),
|
|
332
|
+
// The event/listener payload the wake would have carried; absent for schedule triggers.
|
|
333
|
+
payload: z
|
|
334
|
+
.string()
|
|
335
|
+
.optional()
|
|
336
|
+
.describe(
|
|
337
|
+
"What set it off, kept whole so an approved wake carries the same thing it would have had. Absent for one on a schedule, which carries nothing.",
|
|
338
|
+
),
|
|
339
|
+
// The provenance + title the held wake would have opened its conversation with, snapshotted alongside the
|
|
340
|
+
// payload so an approved external wake surfaces on the fleet exactly as an auto one would have.
|
|
341
|
+
origin: AgentOriginSchema.optional().describe(
|
|
342
|
+
"Where the message came from, kept alongside the payload so an approved wake appears on the board exactly as an automatic one would have.",
|
|
343
|
+
),
|
|
344
|
+
title: z.string().optional().describe("What the conversation would be called."),
|
|
345
|
+
/* The CONTINUING THREAD this wake belonged to, when it had one, the conversation the dispatcher had
|
|
346
|
+
* already opened for it and the provider session that conversation last ran on.
|
|
347
|
+
*
|
|
348
|
+
* Snapshotted for the same reason the payload is, and it is the half that was missing: without it an
|
|
349
|
+
* approved wake fell through to minting a fresh conversation, so a Front Desk visitor's chat became one card
|
|
350
|
+
* per approved message instead of the single thread the dispatcher had opened for them, a second worktree
|
|
351
|
+
* each time, and an agent that met the visitor again on every turn. Absent for a schedule or a webhook,
|
|
352
|
+
* which own no thread. */
|
|
353
|
+
conversationId: z
|
|
354
|
+
.string()
|
|
355
|
+
.optional()
|
|
356
|
+
.describe(
|
|
357
|
+
"The thread this belongs to, when it has one, so approving continues that conversation rather than opening a new one. Without it, one visitor's chat becomes a card per approved message and an agent that meets them again every turn.",
|
|
358
|
+
),
|
|
359
|
+
sessionId: z.string().optional().describe("The provider session that thread last ran on."),
|
|
360
|
+
createdAt: z.number().describe("When it started waiting, in milliseconds."),
|
|
361
|
+
/* Epoch ms after which the daemon may run this wake itself (a `holdForSeconds` hold), the countdown the
|
|
362
|
+
* row renders, and the deadline the scheduler's tick checks against. Absent on a `requireApproval` hold,
|
|
363
|
+
* which only the owner may release. */
|
|
364
|
+
autoRunAt: z
|
|
365
|
+
.number()
|
|
366
|
+
.optional()
|
|
367
|
+
.describe(
|
|
368
|
+
"When it goes ahead on its own, in milliseconds, for a hold that is only a delay. Absent for one that genuinely waits on a person.",
|
|
369
|
+
),
|
|
370
|
+
});
|
|
371
|
+
export type AutomationApproval = z.infer<typeof AutomationApprovalSchema>;
|
|
372
|
+
// `rev` is the registry revision this roster was read at, a counter the daemon bumps on every registry change.
|
|
373
|
+
// It is what makes the browser's optimistic writes safe: the fleet is published as full snapshots (last frame
|
|
374
|
+
// wins), so without an ordering stamp a roster READ before a mutation but delivered after it silently puts the
|
|
375
|
+
// mutated agents back. The browser drops any roster older than the newest it has applied, and holds its own
|
|
376
|
+
// pending change until a roster at or past the revision that applied it arrives. See useAgents.ts.
|
|
377
|
+
// `held` is the approvals queue projected onto the board, the wakes waiting at the door, so "needs you" sits
|
|
378
|
+
// beside "running" instead of in a page nobody opens. Defaulted so an older daemon's roster still parses.
|
|
379
|
+
export const AgentsListSchema = z.object({
|
|
380
|
+
agents: z.array(AgentSummarySchema).describe("The conversations."),
|
|
381
|
+
rev: z
|
|
382
|
+
.number()
|
|
383
|
+
.describe(
|
|
384
|
+
"Which version of the fleet this is. The fleet is published as whole snapshots, so without a version a list read before a change but delivered after it would silently undo that change. Drop any list older than the newest you have already applied.",
|
|
385
|
+
),
|
|
386
|
+
held: z
|
|
387
|
+
.array(AutomationApprovalSchema)
|
|
388
|
+
.default([])
|
|
389
|
+
.describe(
|
|
390
|
+
"Automations waiting at the door for a yes, put alongside the running conversations so needs-you sits beside working rather than on a page nobody opens.",
|
|
391
|
+
),
|
|
392
|
+
});
|
|
393
|
+
export type AgentsList = z.infer<typeof AgentsListSchema>;
|
|
394
|
+
export const AutomationApprovalsListSchema = z.object({ approvals: z.array(AutomationApprovalSchema).describe("Everything waiting for a yes.") });
|
|
395
|
+
export const AutomationApprovalIdParamSchema = z.object({ id: z.string().describe("Which waiting item.") });
|
|
396
|
+
export const AutomationRunSchema = z.object({
|
|
397
|
+
at: z.number(),
|
|
398
|
+
// skipped = the guard said no; error = the guard passed but the agent turn surfaced an error; interrupted =
|
|
399
|
+
// the daemon died mid-wake, so the run reached no outcome of its own (see agent/turn-journal.ts). Without
|
|
400
|
+
// that last one an interrupted fire records NOTHING and simply vanishes from the row's history, which reads
|
|
401
|
+
// as "it never fired", the one reading a 3 a.m. automation must not be given.
|
|
402
|
+
outcome: z.enum(["completed", "skipped", "error", "interrupted"]),
|
|
403
|
+
detail: z.string().optional(),
|
|
404
|
+
// The stable conversation opened by the wake, so the row can open the provider-neutral agent transcript.
|
|
405
|
+
// Absent only for a run skipped before a conversation was needed.
|
|
406
|
+
conversationId: z.string().optional(),
|
|
407
|
+
});
|
|
408
|
+
export type AutomationRun = z.infer<typeof AutomationRunSchema>;
|
|
409
|
+
// The list row: the stored automation + its recent runs + the next scheduled fire (absent when disabled).
|
|
410
|
+
export const AutomationSummarySchema = AutomationSchema.extend({
|
|
411
|
+
runs: z.array(AutomationRunSchema),
|
|
412
|
+
nextRun: z.number().optional(),
|
|
413
|
+
});
|
|
414
|
+
export type AutomationSummary = z.infer<typeof AutomationSummarySchema>;
|
|
415
|
+
export const AutomationsListSchema = z.object({ automations: z.array(AutomationSummarySchema) });
|
|
416
|
+
export const AutomationIdParamSchema = z.object({ id: z.string() });
|
|
417
|
+
export const AutomationEnabledInputSchema = z.object({ id: z.string(), enabled: z.boolean() });
|
|
418
|
+
/* ---- the automation catalogue: everything that can wake an agent here, and what to start from ----
|
|
419
|
+
*
|
|
420
|
+
* ONE ANSWER TO ONE QUESTION, and that is the whole reason it exists. The composer used to carry a hand-written
|
|
421
|
+
* list of every source and every template. CI, Komodo, Sentry, Stripe, email, the website widget, the chore
|
|
422
|
+
* book, while the daemon's upsert carried a SECOND hand-written list of the providers it would accept. Two
|
|
423
|
+
* lists, edited in different packages, disagreeing was a matter of time; and every area that gained something
|
|
424
|
+
* worth waking on had to edit the automations surface to say so, which is the dependency pointing backwards.
|
|
425
|
+
*
|
|
426
|
+
* Now the daemon merges what IT emits with what every installed extension declares, and serves the result. The
|
|
427
|
+
* composer draws whatever comes back and knows the name of nothing; `upsert` validates against the same merge.
|
|
428
|
+
* An area gains a trigger by declaring it, and the surface it appears on does not change.
|
|
429
|
+
*
|
|
430
|
+
* WHERE A SOURCE IS DECLARED IS WHERE ITS EVENTS COME FROM, `webchat` and `ci` are the daemon's own (it holds
|
|
431
|
+
* the widget endpoint and the pipeline webhook receiver), every other one belongs to the extension whose
|
|
432
|
+
* gateway or backend dispatches it.
|
|
433
|
+
*
|
|
434
|
+
* A TEMPLATE SITS BESIDE THE SOURCE IT FIRES ON, because the source's starter and the template's prompt
|
|
435
|
+
* describe the same payload, and one payload described in two packages is two descriptions to keep in step. A
|
|
436
|
+
* template on the generic `event` webhook has no source to sit beside, so it goes with the pack carrying the
|
|
437
|
+
* capability card it names, which is the same pack the user connected to make it work at all. */
|
|
438
|
+
|
|
439
|
+
// A source's per-source narrowing field, as the generic editor draws it. Absent ⇒ the editor offers no such
|
|
440
|
+
// filter rather than inventing one the provider has no meaning for.
|
|
441
|
+
const TriggerFieldSchema = z.object({ label: z.string().min(1), placeholder: z.string().min(1), hint: z.string().min(1).optional() });
|
|
442
|
+
export const TriggerSourceSchema = z.object({
|
|
443
|
+
// The slug a listener trigger fires on (Trigger.provider).
|
|
444
|
+
provider: z.string().min(1),
|
|
445
|
+
label: z.string().min(1),
|
|
446
|
+
// Simple-icons slug, or an app glyph, the same logo/icon split a capability card and an extension mark draw.
|
|
447
|
+
logo: z.string().min(1).optional(),
|
|
448
|
+
icon: z.string().min(1).optional(),
|
|
449
|
+
events: z.array(z.object({ value: z.string().min(1), label: z.string().min(1) })),
|
|
450
|
+
channel: TriggerFieldSchema,
|
|
451
|
+
// A SECOND narrowing axis, for sources whose events carry one, `ci` narrows by git ref as well as by repo.
|
|
452
|
+
branchField: TriggerFieldSchema.optional(),
|
|
453
|
+
// Only sources whose `message` events distinguish addressed messages set this; absent ⇒ no mention-only filter.
|
|
454
|
+
mentionLabel: z.string().min(1).optional(),
|
|
455
|
+
// The provider owns the payload vocabulary, so it owns the first prompt that explains that payload.
|
|
456
|
+
starterPrompt: z.string().min(1).optional(),
|
|
457
|
+
/* Capability providers that make this source WORK, any one of them connected is enough (a CI trigger rides
|
|
458
|
+
* github or gitlab). Empty ⇒ nothing to connect, the source is usable as it stands. Availability is computed
|
|
459
|
+
* in the browser rather than served, because the browser's capability facts are pushed live and a served
|
|
460
|
+
* boolean would be stale between polls. */
|
|
461
|
+
requires: z.array(z.string().min(1)).default([]),
|
|
462
|
+
/* Whether the extension declaring this is switched ON. Disabled ones are still listed, and that is the
|
|
463
|
+
* point: a stored automation must stay readable and editable while the pack that supplied its provider is
|
|
464
|
+
* off, showing the real label instead of degrading to a bare slug. */
|
|
465
|
+
enabled: z.boolean(),
|
|
466
|
+
});
|
|
467
|
+
export type TriggerSource = z.infer<typeof TriggerSourceSchema>;
|
|
468
|
+
/* HOW A TEMPLATE IS OFFERED. Absent ⇒ it lives in the create dialog's gallery, where you go once you know what
|
|
469
|
+
* you want. The two named forms are for what a user would never think to go looking for:
|
|
470
|
+
* create , a shelf card on the page that makes the automation in one click, switched off, ready to read.
|
|
471
|
+
* The chores are all of these: upkeep nobody opens an automations page hunting for.
|
|
472
|
+
* configure, a shelf card that opens the dialog PREFILLED, for a template that cannot work unconfigured (a
|
|
473
|
+
* Front Desk with no allowed sites admits nobody, and a row that silently does nothing is worse
|
|
474
|
+
* than a form). */
|
|
475
|
+
export const TemplateOfferSchema = z.enum(["create", "configure"]);
|
|
476
|
+
export const AutomationTemplateSchema = z.object({
|
|
477
|
+
// Prefills the automation name, so it is also what "does one of these already exist" is asked by.
|
|
478
|
+
id: z.string().min(1),
|
|
479
|
+
title: z.string().min(1),
|
|
480
|
+
logo: z.string().min(1).optional(),
|
|
481
|
+
icon: z.string().min(1).optional(),
|
|
482
|
+
// Same rule as a source's: any one connected is enough, empty ⇒ always offered.
|
|
483
|
+
requires: z.array(z.string().min(1)).default([]),
|
|
484
|
+
trigger: TriggerSchema,
|
|
485
|
+
// Prefills the guard command (a shell one-liner; non-zero exit skips the wake).
|
|
486
|
+
guard: z.string().min(1).optional(),
|
|
487
|
+
// Prefills the countdown hold: each fire waits this long, visibly and cancellably, before starting itself.
|
|
488
|
+
holdForSeconds: z.number().int().positive().optional(),
|
|
489
|
+
prompt: z.string().min(1),
|
|
490
|
+
// The card's disclosure under the title, "instant", "checks every 5 min", "skips changes under 20 lines".
|
|
491
|
+
note: z.string().min(1).optional(),
|
|
492
|
+
// Post-save instructions: where to paste the webhook URL this automation just minted.
|
|
493
|
+
setup: z.string().min(1).optional(),
|
|
494
|
+
// What the shelf card says under the title. Only offered templates need one; a gallery entry has its
|
|
495
|
+
// trigger beside it for context.
|
|
496
|
+
description: z.string().min(1).optional(),
|
|
497
|
+
offer: TemplateOfferSchema.optional(),
|
|
498
|
+
/* WHETHER THE AUTOMATION THIS MAKES WATCHES THIS CODEBASE, the flag the created record stores, which is
|
|
499
|
+
* what puts its row on the chores shelf rather than among the integrations.
|
|
500
|
+
*
|
|
501
|
+
* Carried rather than inferred from the trigger, because a nightly dependency sweep and a nightly Stripe
|
|
502
|
+
* poll are both `schedule` and only one of them is about your code. */
|
|
503
|
+
chore: z.boolean().optional(),
|
|
504
|
+
});
|
|
505
|
+
export type AutomationTemplate = z.infer<typeof AutomationTemplateSchema>;
|
|
506
|
+
export const AutomationCatalogSchema = z.object({
|
|
507
|
+
sources: z.array(TriggerSourceSchema),
|
|
508
|
+
templates: z.array(AutomationTemplateSchema),
|
|
509
|
+
});
|
|
510
|
+
export type AutomationCatalog = z.infer<typeof AutomationCatalogSchema>;
|