toolroll 0.9.62 → 0.9.65
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/CHANGELOG.md +80 -0
- package/README.md +66 -8
- package/dist/acp-agents.d.ts +43 -0
- package/dist/acp-agents.js +62 -0
- package/dist/acp-attest.d.ts +44 -0
- package/dist/acp-attest.js +269 -0
- package/dist/acp-check.d.ts +28 -0
- package/dist/acp-check.js +410 -0
- package/dist/acp-client.d.ts +163 -0
- package/dist/acp-client.js +738 -0
- package/dist/acp-inspect.d.ts +23 -0
- package/dist/acp-inspect.js +109 -0
- package/dist/agent-board.d.ts +19 -6
- package/dist/agent-board.js +30 -9
- package/dist/agent-fence.d.ts +203 -10
- package/dist/agent-fence.js +623 -41
- package/dist/agent-pulse.js +9 -2
- package/dist/agent-state-words.d.ts +19 -0
- package/dist/agent-state-words.js +20 -0
- package/dist/agent-state.d.ts +65 -0
- package/dist/agent-state.js +229 -0
- package/dist/agentconfig.js +36 -13
- package/dist/agents-board.d.ts +34 -2
- package/dist/agents-board.js +110 -1
- package/dist/approval-rules-ui.js +2 -2
- package/dist/assignment-delivery.d.ts +14 -0
- package/dist/assignment-delivery.js +13 -0
- package/dist/assignment.js +13 -0
- package/dist/attest.js +7 -0
- package/dist/backup-ui.js +2 -2
- package/dist/browser/THIRD_PARTY_NOTICES.txt +48 -0
- package/dist/browser/terminal.css +37 -0
- package/dist/browser/terminal.js +117 -0
- package/dist/browser/workspace.css +2 -2
- package/dist/browser/workspace.js +42 -38
- package/dist/browser-shell.js +6 -3
- package/dist/browser-workspace.d.ts +263 -1
- package/dist/browser-workspace.js +60 -0
- package/dist/builder.d.ts +6 -1
- package/dist/builder.js +34 -13
- package/dist/chat-actions.d.ts +13 -1
- package/dist/chat-actions.js +199 -17
- package/dist/chat-ask.d.ts +4 -0
- package/dist/chat-ask.js +14 -0
- package/dist/chat-channel.js +20 -0
- package/dist/chat-continuity.js +5 -4
- package/dist/chat-decide.d.ts +0 -14
- package/dist/chat-decide.js +4 -1
- package/dist/chat-delivery.d.ts +9 -0
- package/dist/chat-delivery.js +45 -6
- package/dist/chat-messages.d.ts +8 -0
- package/dist/chat-messages.js +36 -4
- package/dist/check-levels-ui.js +2 -2
- package/dist/check-levels.js +3 -0
- package/dist/checkout-proof.d.ts +28 -0
- package/dist/checkout-proof.js +62 -0
- package/dist/claim.d.ts +12 -0
- package/dist/claim.js +20 -1
- package/dist/cli-help.d.ts +1 -1
- package/dist/cli-help.js +5 -1
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +24 -2
- package/dist/coding-ui.js +6 -4
- package/dist/console-instance.d.ts +124 -0
- package/dist/console-instance.js +337 -0
- package/dist/contracts/chat-actions.d.ts +16 -0
- package/dist/contracts/chat-actions.js +4 -0
- package/dist/contracts/chat-content.d.ts +19 -0
- package/dist/contracts/chat-content.js +6 -0
- package/dist/contracts/cli.d.ts +8 -0
- package/dist/contracts/cli.js +3 -1
- package/dist/contracts/console-api.d.ts +30 -4
- package/dist/contracts/console-api.js +13 -4
- package/dist/contracts/flow-card.d.ts +4 -0
- package/dist/contracts/flow-card.js +3 -0
- package/dist/contracts/flow.d.ts +46 -0
- package/dist/contracts/flow.js +11 -2
- package/dist/contracts/integration-metadata.d.ts +2 -1
- package/dist/contracts/integration-metadata.js +2 -1
- package/dist/contracts/lead-tools.d.ts +92 -0
- package/dist/contracts/lead-tools.js +13 -0
- package/dist/contracts/provider.d.ts +11 -1
- package/dist/contracts/provider.js +1 -1
- package/dist/contracts/route.d.ts +76 -1
- package/dist/contracts/route.js +1 -1
- package/dist/contracts/store-json.d.ts +2 -0
- package/dist/control-setup.d.ts +1 -1
- package/dist/control-ui.js +2 -2
- package/dist/converse.d.ts +16 -0
- package/dist/converse.js +32 -4
- package/dist/demo-chat.js +4 -4
- package/dist/demo.js +2 -2
- package/dist/desktop-update-gate.js +6 -0
- package/dist/discord-chat.js +4 -1
- package/dist/dispatch.js +7 -4
- package/dist/doctor.d.ts +53 -0
- package/dist/doctor.js +427 -0
- package/dist/egress-bridge.d.ts +17 -0
- package/dist/egress-bridge.js +111 -0
- package/dist/egress.d.ts +119 -0
- package/dist/egress.js +423 -0
- package/dist/evidence-pack.d.ts +1 -1
- package/dist/evidence-pack.js +2 -2
- package/dist/exec.d.ts +81 -0
- package/dist/exec.js +368 -9
- package/dist/export-ui.js +2 -2
- package/dist/flow-code.d.ts +2 -2
- package/dist/flow-code.js +4 -15
- package/dist/flow-engine.js +35 -11
- package/dist/flow-gallery-ui.js +2 -2
- package/dist/flow-gallery.js +27 -8
- package/dist/flow-share.js +16 -5
- package/dist/flow-triggers.d.ts +84 -11
- package/dist/flow-triggers.js +554 -87
- package/dist/flow-unattended-words.d.ts +28 -0
- package/dist/flow-unattended-words.js +50 -0
- package/dist/flow-unattended.d.ts +227 -0
- package/dist/flow-unattended.js +776 -0
- package/dist/flows-cli.d.ts +28 -1
- package/dist/flows-cli.js +63 -12
- package/dist/flows-ui.d.ts +2 -3
- package/dist/flows-ui.js +56 -5
- package/dist/flows.d.ts +4 -0
- package/dist/flows.js +9 -1
- package/dist/google-mail.d.ts +1 -0
- package/dist/google-mail.js +61 -18
- package/dist/html.d.ts +9 -0
- package/dist/html.js +11 -0
- package/dist/integrations-ui.d.ts +2 -1
- package/dist/integrations-ui.js +6 -3
- package/dist/integrations.d.ts +17 -3
- package/dist/integrations.js +38 -18
- package/dist/invoke.d.ts +17 -0
- package/dist/invoke.js +510 -182
- package/dist/keys.d.ts +18 -14
- package/dist/keys.js +5 -0
- package/dist/landed-cleanup.d.ts +3 -2
- package/dist/landed-cleanup.js +12 -5
- package/dist/lead-capabilities.js +3 -2
- package/dist/lead-contract.js +2 -0
- package/dist/lead-doors.d.ts +2 -0
- package/dist/lead-doors.js +7 -0
- package/dist/lead-follow.d.ts +2 -0
- package/dist/lead-follow.js +58 -2
- package/dist/lead-progress.js +1 -0
- package/dist/lead-queue-runtime.d.ts +46 -0
- package/dist/lead-queue-runtime.js +191 -0
- package/dist/lead-queue.d.ts +104 -0
- package/dist/lead-queue.js +187 -0
- package/dist/lead-sweep.d.ts +67 -0
- package/dist/lead-sweep.js +99 -0
- package/dist/lead-tools.d.ts +22 -0
- package/dist/lead-tools.js +163 -4
- package/dist/lead.d.ts +13 -5
- package/dist/lead.js +89 -29
- package/dist/limits-ui.d.ts +8 -1
- package/dist/limits-ui.js +26 -0
- package/dist/live-bus.d.ts +8 -0
- package/dist/live-bus.js +40 -4
- package/dist/live-detail.d.ts +27 -0
- package/dist/live-detail.js +57 -0
- package/dist/live-notes.d.ts +20 -0
- package/dist/live-notes.js +47 -0
- package/dist/live-records.d.ts +140 -0
- package/dist/live-records.js +935 -0
- package/dist/live-terminal.d.ts +258 -0
- package/dist/live-terminal.js +649 -0
- package/dist/live.d.ts +38 -27
- package/dist/live.js +142 -124
- package/dist/mcp-connect.d.ts +8 -7
- package/dist/mcp-connect.js +49 -51
- package/dist/mcp-oauth.d.ts +6 -3
- package/dist/mcp-oauth.js +8 -4
- package/dist/memory-pass.js +2 -2
- package/dist/mobile-viewport.d.ts +5 -1
- package/dist/mobile-viewport.js +18 -2
- package/dist/model-catalog.js +4 -0
- package/dist/monitoring-ui.js +2 -2
- package/dist/needs-you.d.ts +1 -1
- package/dist/needs-you.js +11 -4
- package/dist/oauth-run-token.d.ts +51 -0
- package/dist/oauth-run-token.js +127 -0
- package/dist/operate.d.ts +2 -0
- package/dist/operate.js +282 -18
- package/dist/passwordless.d.ts +23 -0
- package/dist/passwordless.js +26 -0
- package/dist/peek-cli.d.ts +12 -4
- package/dist/peek-cli.js +19 -11
- package/dist/phase-routing.js +10 -3
- package/dist/plan-auto.d.ts +11 -0
- package/dist/plan-auto.js +62 -11
- package/dist/planner-source.d.ts +3 -0
- package/dist/planner-source.js +14 -0
- package/dist/planner.d.ts +2 -1
- package/dist/planner.js +7 -1
- package/dist/policy-ui.js +2 -2
- package/dist/policy.d.ts +1 -20
- package/dist/policy.js +29 -2
- package/dist/process-recovery-eligibility.d.ts +1 -1
- package/dist/project-access.d.ts +3 -0
- package/dist/project-access.js +3 -0
- package/dist/project-delete-ui.d.ts +12 -0
- package/dist/project-delete-ui.js +41 -9
- package/dist/project-delete.d.ts +3 -1
- package/dist/project-delete.js +12 -6
- package/dist/project-file.d.ts +3 -0
- package/dist/project-file.js +16 -0
- package/dist/project-memory.d.ts +3 -1
- package/dist/project-memory.js +57 -25
- package/dist/project-tools.d.ts +103 -27
- package/dist/project-tools.js +399 -100
- package/dist/provider-auth.d.ts +4 -3
- package/dist/provider-auth.js +5 -4
- package/dist/provider-connection.d.ts +2 -1
- package/dist/provider-connection.js +5 -0
- package/dist/provider-home.d.ts +22 -0
- package/dist/provider-home.js +99 -0
- package/dist/provider.d.ts +42 -5
- package/dist/provider.js +97 -19
- package/dist/pull-request-ui.js +2 -2
- package/dist/push.js +1 -1
- package/dist/quick-start.d.ts +24 -0
- package/dist/quick-start.js +127 -0
- package/dist/release.d.ts +3 -0
- package/dist/release.js +14 -8
- package/dist/remote-main.d.ts +4 -0
- package/dist/remote-main.js +3 -3
- package/dist/request-budget-ui.js +2 -2
- package/dist/result-review.d.ts +1 -1
- package/dist/result-review.js +9 -3
- package/dist/retention-ui.js +2 -2
- package/dist/retention.js +10 -1
- package/dist/run-efficiency.d.ts +73 -0
- package/dist/run-efficiency.js +228 -0
- package/dist/runner.d.ts +5 -1
- package/dist/runner.js +22 -1
- package/dist/scope.d.ts +171 -6
- package/dist/scope.js +251 -31
- package/dist/scout-net.d.ts +4 -1
- package/dist/scout-net.js +37 -12
- package/dist/scout.d.ts +20 -6
- package/dist/scout.js +27 -3
- package/dist/serve.js +258 -43
- package/dist/server/chat.d.ts +1 -1
- package/dist/server/chat.js +122 -31
- package/dist/server/chrome.d.ts +6 -1
- package/dist/server/chrome.js +18 -7
- package/dist/server/console.css +52 -38
- package/dist/server/flows.js +65 -13
- package/dist/server/guards.d.ts +1 -0
- package/dist/server/guards.js +23 -9
- package/dist/server/http.d.ts +7 -0
- package/dist/server/http.js +3 -2
- package/dist/server/live.d.ts +34 -1
- package/dist/server/live.js +39 -17
- package/dist/server/pages-assets.js +5 -0
- package/dist/server/pages.js +90 -13
- package/dist/server/people-tokens.d.ts +3 -0
- package/dist/server/people-tokens.js +55 -17
- package/dist/server/remote-hooks.js +12 -6
- package/dist/server/remote.d.ts +2 -1
- package/dist/server/remote.js +14 -5
- package/dist/server/render-chat.d.ts +12 -3
- package/dist/server/render-chat.js +47 -16
- package/dist/server/render-pages.d.ts +4 -1
- package/dist/server/render-pages.js +5 -4
- package/dist/server/render-people.d.ts +3 -2
- package/dist/server/render-people.js +3 -2
- package/dist/server/render-results.d.ts +18 -2
- package/dist/server/render-results.js +37 -28
- package/dist/server/render-settings.js +6 -5
- package/dist/server/render-tasks.d.ts +35 -10
- package/dist/server/render-tasks.js +110 -27
- package/dist/server/request-context.d.ts +2 -0
- package/dist/server/request-context.js +2 -1
- package/dist/server/route-table.d.ts +3 -0
- package/dist/server/route-table.js +49 -5
- package/dist/server/runtime.d.ts +34 -3
- package/dist/server/session.d.ts +25 -1
- package/dist/server/session.js +18 -4
- package/dist/server/settings.js +132 -13
- package/dist/server/sweeps.d.ts +4 -0
- package/dist/server/sweeps.js +58 -0
- package/dist/server/task-views.d.ts +2 -1
- package/dist/server/task-views.js +96 -6
- package/dist/server/tasks.js +320 -74
- package/dist/server/terminals.d.ts +31 -0
- package/dist/server/terminals.js +365 -0
- package/dist/setup-guide.js +3 -2
- package/dist/slack-chat.js +4 -1
- package/dist/spend-ui.js +3 -3
- package/dist/spend.js +2 -1
- package/dist/steer-capabilities.d.ts +32 -0
- package/dist/steer-capabilities.js +60 -0
- package/dist/steer-controls.d.ts +14 -0
- package/dist/steer-controls.js +36 -0
- package/dist/steer-status.js +2 -2
- package/dist/storage-sweep-child.js +3 -1
- package/dist/storage-sweep-process.d.ts +12 -5
- package/dist/storage-sweep-process.js +23 -6
- package/dist/storage-ui.js +4 -4
- package/dist/store-baseline.d.ts +1 -1
- package/dist/store-baseline.js +1 -1
- package/dist/store.d.ts +466 -19
- package/dist/store.js +1185 -63
- package/dist/subagent-desk.js +1 -1
- package/dist/subagent-tools.d.ts +1 -1
- package/dist/summary.js +3 -0
- package/dist/surface.js +6 -4
- package/dist/task-source.d.ts +58 -0
- package/dist/task-source.js +93 -0
- package/dist/team-leads.js +1 -1
- package/dist/teams-chat.js +4 -1
- package/dist/teardown-git.d.ts +14 -0
- package/dist/teardown-git.js +119 -0
- package/dist/telegram-lead.d.ts +3 -0
- package/dist/telegram-lead.js +44 -7
- package/dist/telegram.d.ts +11 -2
- package/dist/telegram.js +51 -17
- package/dist/terminal-catalog.d.ts +11 -0
- package/dist/terminal-catalog.js +129 -0
- package/dist/text-limits.d.ts +2 -0
- package/dist/text-limits.js +2 -0
- package/dist/tool-broker.d.ts +39 -0
- package/dist/tool-broker.js +370 -0
- package/dist/tool-launcher.js +5 -4
- package/dist/tool-secret-store.d.ts +170 -0
- package/dist/tool-secret-store.js +834 -0
- package/dist/toolroll-update-ui.js +2 -2
- package/dist/toolroll-update.js +14 -3
- package/dist/tools-ui.d.ts +7 -1
- package/dist/tools-ui.js +19 -10
- package/dist/webhook-limits.d.ts +23 -0
- package/dist/webhook-limits.js +30 -0
- package/dist/webhook-readers.d.ts +56 -0
- package/dist/webhook-readers.js +138 -0
- package/dist/webhook-signing.d.ts +27 -0
- package/dist/webhook-signing.js +119 -0
- package/dist/work-index.d.ts +29 -0
- package/dist/work-index.js +21 -5
- package/dist/workspace-revision.js +3 -1
- package/dist/worktree.d.ts +10 -4
- package/dist/worktree.js +70 -29
- package/package.json +13 -2
- package/scripts/provider-canary.mjs +210 -31
|
@@ -16,7 +16,7 @@ import { type ContractResult } from "./contract.js";
|
|
|
16
16
|
export declare const ROUTE_PHASES: readonly ["plan", "build", "repair", "review"];
|
|
17
17
|
/** provider.ts's provider ids, restated (provider.ts sits above phase-routing.ts in the module graph) and pinned to
|
|
18
18
|
* them by the test suite. */
|
|
19
|
-
export declare const ROUTE_PROVIDERS: readonly ["claude", "codex", "openrouter", "gemini"];
|
|
19
|
+
export declare const ROUTE_PROVIDERS: readonly ["claude", "codex", "openrouter", "gemini", "opencode", "cursor", "cline", "qwen", "goose"];
|
|
20
20
|
/** provider.ts's MODEL_ID, restated for the same reason: an exact model id is argv-safe — no leading dash, no
|
|
21
21
|
* whitespace or control bytes. */
|
|
22
22
|
export declare const MODEL_ID_SHAPE: RegExp;
|
|
@@ -49,9 +49,14 @@ export declare const routeOverrideSchema: z.ZodObject<{
|
|
|
49
49
|
}>;
|
|
50
50
|
provider: z.ZodEnum<{
|
|
51
51
|
claude: "claude";
|
|
52
|
+
cline: "cline";
|
|
52
53
|
codex: "codex";
|
|
54
|
+
cursor: "cursor";
|
|
53
55
|
gemini: "gemini";
|
|
56
|
+
goose: "goose";
|
|
57
|
+
opencode: "opencode";
|
|
54
58
|
openrouter: "openrouter";
|
|
59
|
+
qwen: "qwen";
|
|
55
60
|
}>;
|
|
56
61
|
model: z.ZodString;
|
|
57
62
|
by: z.ZodString;
|
|
@@ -67,9 +72,14 @@ export declare const routeLegSchema: z.ZodObject<{
|
|
|
67
72
|
}>;
|
|
68
73
|
provider: z.ZodEnum<{
|
|
69
74
|
claude: "claude";
|
|
75
|
+
cline: "cline";
|
|
70
76
|
codex: "codex";
|
|
77
|
+
cursor: "cursor";
|
|
71
78
|
gemini: "gemini";
|
|
79
|
+
goose: "goose";
|
|
80
|
+
opencode: "opencode";
|
|
72
81
|
openrouter: "openrouter";
|
|
82
|
+
qwen: "qwen";
|
|
73
83
|
}>;
|
|
74
84
|
model: z.ZodString;
|
|
75
85
|
tier: z.ZodEnum<{
|
|
@@ -85,9 +95,14 @@ export declare const routeLegSchema: z.ZodObject<{
|
|
|
85
95
|
recommended: z.ZodObject<{
|
|
86
96
|
provider: z.ZodEnum<{
|
|
87
97
|
claude: "claude";
|
|
98
|
+
cline: "cline";
|
|
88
99
|
codex: "codex";
|
|
100
|
+
cursor: "cursor";
|
|
89
101
|
gemini: "gemini";
|
|
102
|
+
goose: "goose";
|
|
103
|
+
opencode: "opencode";
|
|
90
104
|
openrouter: "openrouter";
|
|
105
|
+
qwen: "qwen";
|
|
91
106
|
}>;
|
|
92
107
|
model: z.ZodString;
|
|
93
108
|
tier: z.ZodEnum<{
|
|
@@ -135,9 +150,14 @@ export declare const sealedRouteV1Schema: z.ZodObject<{
|
|
|
135
150
|
}>;
|
|
136
151
|
provider: z.ZodEnum<{
|
|
137
152
|
claude: "claude";
|
|
153
|
+
cline: "cline";
|
|
138
154
|
codex: "codex";
|
|
155
|
+
cursor: "cursor";
|
|
139
156
|
gemini: "gemini";
|
|
157
|
+
goose: "goose";
|
|
158
|
+
opencode: "opencode";
|
|
140
159
|
openrouter: "openrouter";
|
|
160
|
+
qwen: "qwen";
|
|
141
161
|
}>;
|
|
142
162
|
model: z.ZodString;
|
|
143
163
|
tier: z.ZodEnum<{
|
|
@@ -152,9 +172,14 @@ export declare const sealedRouteV1Schema: z.ZodObject<{
|
|
|
152
172
|
recommended: z.ZodObject<{
|
|
153
173
|
provider: z.ZodEnum<{
|
|
154
174
|
claude: "claude";
|
|
175
|
+
cline: "cline";
|
|
155
176
|
codex: "codex";
|
|
177
|
+
cursor: "cursor";
|
|
156
178
|
gemini: "gemini";
|
|
179
|
+
goose: "goose";
|
|
180
|
+
opencode: "opencode";
|
|
157
181
|
openrouter: "openrouter";
|
|
182
|
+
qwen: "qwen";
|
|
158
183
|
}>;
|
|
159
184
|
model: z.ZodString;
|
|
160
185
|
tier: z.ZodEnum<{
|
|
@@ -174,9 +199,14 @@ export declare const sealedRouteV1Schema: z.ZodObject<{
|
|
|
174
199
|
}>;
|
|
175
200
|
provider: z.ZodEnum<{
|
|
176
201
|
claude: "claude";
|
|
202
|
+
cline: "cline";
|
|
177
203
|
codex: "codex";
|
|
204
|
+
cursor: "cursor";
|
|
178
205
|
gemini: "gemini";
|
|
206
|
+
goose: "goose";
|
|
207
|
+
opencode: "opencode";
|
|
179
208
|
openrouter: "openrouter";
|
|
209
|
+
qwen: "qwen";
|
|
180
210
|
}>;
|
|
181
211
|
model: z.ZodString;
|
|
182
212
|
by: z.ZodString;
|
|
@@ -219,9 +249,14 @@ export declare const sealedRouteV2Schema: z.ZodObject<{
|
|
|
219
249
|
}>;
|
|
220
250
|
provider: z.ZodEnum<{
|
|
221
251
|
claude: "claude";
|
|
252
|
+
cline: "cline";
|
|
222
253
|
codex: "codex";
|
|
254
|
+
cursor: "cursor";
|
|
223
255
|
gemini: "gemini";
|
|
256
|
+
goose: "goose";
|
|
257
|
+
opencode: "opencode";
|
|
224
258
|
openrouter: "openrouter";
|
|
259
|
+
qwen: "qwen";
|
|
225
260
|
}>;
|
|
226
261
|
model: z.ZodString;
|
|
227
262
|
tier: z.ZodEnum<{
|
|
@@ -237,9 +272,14 @@ export declare const sealedRouteV2Schema: z.ZodObject<{
|
|
|
237
272
|
recommended: z.ZodObject<{
|
|
238
273
|
provider: z.ZodEnum<{
|
|
239
274
|
claude: "claude";
|
|
275
|
+
cline: "cline";
|
|
240
276
|
codex: "codex";
|
|
277
|
+
cursor: "cursor";
|
|
241
278
|
gemini: "gemini";
|
|
279
|
+
goose: "goose";
|
|
280
|
+
opencode: "opencode";
|
|
242
281
|
openrouter: "openrouter";
|
|
282
|
+
qwen: "qwen";
|
|
243
283
|
}>;
|
|
244
284
|
model: z.ZodString;
|
|
245
285
|
tier: z.ZodEnum<{
|
|
@@ -260,9 +300,14 @@ export declare const sealedRouteV2Schema: z.ZodObject<{
|
|
|
260
300
|
}>;
|
|
261
301
|
provider: z.ZodEnum<{
|
|
262
302
|
claude: "claude";
|
|
303
|
+
cline: "cline";
|
|
263
304
|
codex: "codex";
|
|
305
|
+
cursor: "cursor";
|
|
264
306
|
gemini: "gemini";
|
|
307
|
+
goose: "goose";
|
|
308
|
+
opencode: "opencode";
|
|
265
309
|
openrouter: "openrouter";
|
|
310
|
+
qwen: "qwen";
|
|
266
311
|
}>;
|
|
267
312
|
model: z.ZodString;
|
|
268
313
|
by: z.ZodString;
|
|
@@ -320,9 +365,14 @@ export declare const sealedRouteSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
320
365
|
}>;
|
|
321
366
|
provider: z.ZodEnum<{
|
|
322
367
|
claude: "claude";
|
|
368
|
+
cline: "cline";
|
|
323
369
|
codex: "codex";
|
|
370
|
+
cursor: "cursor";
|
|
324
371
|
gemini: "gemini";
|
|
372
|
+
goose: "goose";
|
|
373
|
+
opencode: "opencode";
|
|
325
374
|
openrouter: "openrouter";
|
|
375
|
+
qwen: "qwen";
|
|
326
376
|
}>;
|
|
327
377
|
model: z.ZodString;
|
|
328
378
|
tier: z.ZodEnum<{
|
|
@@ -337,9 +387,14 @@ export declare const sealedRouteSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
337
387
|
recommended: z.ZodObject<{
|
|
338
388
|
provider: z.ZodEnum<{
|
|
339
389
|
claude: "claude";
|
|
390
|
+
cline: "cline";
|
|
340
391
|
codex: "codex";
|
|
392
|
+
cursor: "cursor";
|
|
341
393
|
gemini: "gemini";
|
|
394
|
+
goose: "goose";
|
|
395
|
+
opencode: "opencode";
|
|
342
396
|
openrouter: "openrouter";
|
|
397
|
+
qwen: "qwen";
|
|
343
398
|
}>;
|
|
344
399
|
model: z.ZodString;
|
|
345
400
|
tier: z.ZodEnum<{
|
|
@@ -359,9 +414,14 @@ export declare const sealedRouteSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
359
414
|
}>;
|
|
360
415
|
provider: z.ZodEnum<{
|
|
361
416
|
claude: "claude";
|
|
417
|
+
cline: "cline";
|
|
362
418
|
codex: "codex";
|
|
419
|
+
cursor: "cursor";
|
|
363
420
|
gemini: "gemini";
|
|
421
|
+
goose: "goose";
|
|
422
|
+
opencode: "opencode";
|
|
364
423
|
openrouter: "openrouter";
|
|
424
|
+
qwen: "qwen";
|
|
365
425
|
}>;
|
|
366
426
|
model: z.ZodString;
|
|
367
427
|
by: z.ZodString;
|
|
@@ -403,9 +463,14 @@ export declare const sealedRouteSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
403
463
|
}>;
|
|
404
464
|
provider: z.ZodEnum<{
|
|
405
465
|
claude: "claude";
|
|
466
|
+
cline: "cline";
|
|
406
467
|
codex: "codex";
|
|
468
|
+
cursor: "cursor";
|
|
407
469
|
gemini: "gemini";
|
|
470
|
+
goose: "goose";
|
|
471
|
+
opencode: "opencode";
|
|
408
472
|
openrouter: "openrouter";
|
|
473
|
+
qwen: "qwen";
|
|
409
474
|
}>;
|
|
410
475
|
model: z.ZodString;
|
|
411
476
|
tier: z.ZodEnum<{
|
|
@@ -421,9 +486,14 @@ export declare const sealedRouteSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
421
486
|
recommended: z.ZodObject<{
|
|
422
487
|
provider: z.ZodEnum<{
|
|
423
488
|
claude: "claude";
|
|
489
|
+
cline: "cline";
|
|
424
490
|
codex: "codex";
|
|
491
|
+
cursor: "cursor";
|
|
425
492
|
gemini: "gemini";
|
|
493
|
+
goose: "goose";
|
|
494
|
+
opencode: "opencode";
|
|
426
495
|
openrouter: "openrouter";
|
|
496
|
+
qwen: "qwen";
|
|
427
497
|
}>;
|
|
428
498
|
model: z.ZodString;
|
|
429
499
|
tier: z.ZodEnum<{
|
|
@@ -444,9 +514,14 @@ export declare const sealedRouteSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
444
514
|
}>;
|
|
445
515
|
provider: z.ZodEnum<{
|
|
446
516
|
claude: "claude";
|
|
517
|
+
cline: "cline";
|
|
447
518
|
codex: "codex";
|
|
519
|
+
cursor: "cursor";
|
|
448
520
|
gemini: "gemini";
|
|
521
|
+
goose: "goose";
|
|
522
|
+
opencode: "opencode";
|
|
449
523
|
openrouter: "openrouter";
|
|
524
|
+
qwen: "qwen";
|
|
450
525
|
}>;
|
|
451
526
|
model: z.ZodString;
|
|
452
527
|
by: z.ZodString;
|
package/dist/contracts/route.js
CHANGED
|
@@ -17,7 +17,7 @@ import { limited, parseContract, versioned } from "./contract.js";
|
|
|
17
17
|
export const ROUTE_PHASES = ["plan", "build", "repair", "review"];
|
|
18
18
|
/** provider.ts's provider ids, restated (provider.ts sits above phase-routing.ts in the module graph) and pinned to
|
|
19
19
|
* them by the test suite. */
|
|
20
|
-
export const ROUTE_PROVIDERS = ["claude", "codex", "openrouter", "gemini"];
|
|
20
|
+
export const ROUTE_PROVIDERS = ["claude", "codex", "openrouter", "gemini", "opencode", "cursor", "cline", "qwen", "goose"];
|
|
21
21
|
/** provider.ts's MODEL_ID, restated for the same reason: an exact model id is argv-safe — no leading dash, no
|
|
22
22
|
* whitespace or control bytes. */
|
|
23
23
|
export const MODEL_ID_SHAPE = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$/;
|
|
@@ -208,6 +208,8 @@ declare const STORE_COLUMN_VALUES: {
|
|
|
208
208
|
subagent_state: "subagent_state";
|
|
209
209
|
subagent_tools: "subagent_tools";
|
|
210
210
|
subagent_undo: "subagent_undo";
|
|
211
|
+
sweep_cancel_rest: "sweep_cancel_rest";
|
|
212
|
+
sweep_file: "sweep_file";
|
|
211
213
|
task_cancel: "task_cancel";
|
|
212
214
|
task_resume: "task_resume";
|
|
213
215
|
tool_add: "tool_add";
|
package/dist/control-setup.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ export declare function previewSetup(store: Store, repo: string, inputs: SetupIn
|
|
|
19
19
|
fingerprint: string;
|
|
20
20
|
command: string;
|
|
21
21
|
seconds: number;
|
|
22
|
-
provider: "claude" | "codex" | "gemini" | "openrouter";
|
|
22
|
+
provider: "claude" | "cline" | "codex" | "cursor" | "gemini" | "goose" | "opencode" | "openrouter" | "qwen";
|
|
23
23
|
model: string;
|
|
24
24
|
};
|
|
25
25
|
export declare function approveSetup(store: Store, repo: string, inputs: SetupInputs, fingerprint: string, by: string, token: string, now: Date): {
|
package/dist/control-ui.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Shared setup views over the existing project configuration and approval doors. */
|
|
2
|
-
import { html, joinHtml, postForm } from "./html.js";
|
|
2
|
+
import { html, joinHtml, postForm, reauth } from "./html.js";
|
|
3
3
|
import { ASSISTANTS } from "./setup-guide.js";
|
|
4
4
|
import { openRouterPicker } from "./openrouter-models.js";
|
|
5
5
|
export function connectionWords(connection) {
|
|
@@ -24,5 +24,5 @@ export function controlSetupHtml(data) {
|
|
|
24
24
|
/** `fields` may still carry the session's csrf (a caller's habit): postForm writes the one CSRF field. */
|
|
25
25
|
export function setupPreviewHtml(inputs, fields) {
|
|
26
26
|
const { csrf: _csrf, ...rest } = fields;
|
|
27
|
-
return html `<h1>Approve project setup</h1><div class="card"><p>${fields.repo ?? ""}</p><p><strong>Builder:</strong> ${inputs.provider} · ${inputs.model}</p><p><strong>Preparation:</strong></p><pre class="recap">${inputs.command || "No preparation command"}</pre><p>Preparation timeout: ${inputs.seconds} seconds.</p><p>The builder default applies to new tasks. Preparation applies to subsequent runs, including already approved tasks. Existing signed task settings and verification rules remain in force.</p>${postForm("/control/setup-approve", html `<label>Your password<input type="password" name="token" autocomplete="current-password" required></label
|
|
27
|
+
return html `<h1>Approve project setup</h1><div class="card"><p>${fields.repo ?? ""}</p><p><strong>Builder:</strong> ${inputs.provider} · ${inputs.model}</p><p><strong>Preparation:</strong></p><pre class="recap">${inputs.command || "No preparation command"}</pre><p>Preparation timeout: ${inputs.seconds} seconds.</p><p>The builder default applies to new tasks. Preparation applies to subsequent runs, including already approved tasks. Existing signed task settings and verification rules remain in force.</p>${postForm("/control/setup-approve", html `${reauth(html `<label>Your password<input type="password" name="token" autocomplete="current-password" required></label>`)}<button>Approve project setup</button>`, { hidden: { ...rest, ...inputs } })}</div>`;
|
|
28
28
|
}
|
package/dist/converse.d.ts
CHANGED
|
@@ -180,13 +180,24 @@ export type LeadToolCall = {
|
|
|
180
180
|
args: Record<string, unknown>;
|
|
181
181
|
};
|
|
182
182
|
/** A provider answer with tool calls allowed: text, calls, usage. */
|
|
183
|
+
/** `tokensIn` is ALL input tokens of the request; of them, `cacheWriteTokens` were written to the provider's prompt cache
|
|
184
|
+
* and `cacheReadTokens` read from it (absent: the provider reported none — never assumed zero for a cached request). */
|
|
183
185
|
export type LeadProviderAnswer = {
|
|
184
186
|
text: string;
|
|
185
187
|
calls: LeadToolCall[];
|
|
186
188
|
tokensIn: number;
|
|
187
189
|
tokensOut: number;
|
|
188
190
|
reportedCostMicrousd: number | null;
|
|
191
|
+
cacheWriteTokens?: number;
|
|
192
|
+
cacheReadTokens?: number;
|
|
189
193
|
};
|
|
194
|
+
/** Anthropic prices a cache write at 1.25x and a cache read at 0.1x the input price (5-minute cache). */
|
|
195
|
+
export declare const CACHE_WRITE_RATIO = 1.25;
|
|
196
|
+
export declare const CACHE_READ_RATIO = 0.1;
|
|
197
|
+
/** The price a worst case reserves at while prompt caching is on: every input token as a cache write (the dearest). */
|
|
198
|
+
export declare function cacheWorstPrice(price: ModelPrice): ModelPrice;
|
|
199
|
+
/** A step's settlement with its cache categories: plain input, cache writes and cache reads each at their own rate. */
|
|
200
|
+
export declare function settleWithCache(price: ModelPrice, answer: Pick<LeadProviderAnswer, "tokensIn" | "tokensOut" | "cacheWriteTokens" | "cacheReadTokens">): number;
|
|
190
201
|
/** One message of the lead's own history, provider-neutral. */
|
|
191
202
|
export type LeadHistoryMessage = {
|
|
192
203
|
role: "operator";
|
|
@@ -224,6 +235,11 @@ export declare function composeLeadRequest(args: {
|
|
|
224
235
|
dataDocument: string;
|
|
225
236
|
history: readonly LeadHistoryMessage[];
|
|
226
237
|
tools: readonly LeadToolSchema[];
|
|
238
|
+
/** Anthropic prompt caching: breakpoints after the first `coreTools` tools (stable across replies), on the system
|
|
239
|
+
* block, and on the DATA message (stable across the steps of one reply). Absent: no cache annotations. */
|
|
240
|
+
cache?: {
|
|
241
|
+
coreTools: number;
|
|
242
|
+
};
|
|
227
243
|
}): {
|
|
228
244
|
url: string;
|
|
229
245
|
headers: Record<string, string>;
|
package/dist/converse.js
CHANGED
|
@@ -393,6 +393,20 @@ export function leadWorstCaseForPrice(price, baseBytes, caps = {}) {
|
|
|
393
393
|
export function embeddedBytes(text) {
|
|
394
394
|
return Buffer.byteLength(JSON.stringify(text), "utf8");
|
|
395
395
|
}
|
|
396
|
+
/** Anthropic prices a cache write at 1.25x and a cache read at 0.1x the input price (5-minute cache). */
|
|
397
|
+
export const CACHE_WRITE_RATIO = 1.25;
|
|
398
|
+
export const CACHE_READ_RATIO = 0.1;
|
|
399
|
+
/** The price a worst case reserves at while prompt caching is on: every input token as a cache write (the dearest). */
|
|
400
|
+
export function cacheWorstPrice(price) {
|
|
401
|
+
return { inMicrousd: Math.ceil(price.inMicrousd * CACHE_WRITE_RATIO), outMicrousd: price.outMicrousd };
|
|
402
|
+
}
|
|
403
|
+
/** A step's settlement with its cache categories: plain input, cache writes and cache reads each at their own rate. */
|
|
404
|
+
export function settleWithCache(price, answer) {
|
|
405
|
+
const write = answer.cacheWriteTokens ?? 0, read = answer.cacheReadTokens ?? 0;
|
|
406
|
+
const plain = answer.tokensIn - write - read;
|
|
407
|
+
return plain * price.inMicrousd + write * Math.ceil(price.inMicrousd * CACHE_WRITE_RATIO) + read * Math.ceil(price.inMicrousd * CACHE_READ_RATIO)
|
|
408
|
+
+ answer.tokensOut * price.outMicrousd;
|
|
409
|
+
}
|
|
396
410
|
/**
|
|
397
411
|
* The tool-capable wrapper parser (mate arc). Same caps and the same
|
|
398
412
|
* duplicate-key lexer as fleet chat's; tool calls are read, bounded (at
|
|
@@ -475,7 +489,18 @@ export function parseLeadProviderWrapper(provider, bytes) {
|
|
|
475
489
|
const usage = usageOf(body["usage"], "input_tokens", "output_tokens");
|
|
476
490
|
if (usage === null)
|
|
477
491
|
return { ok: false, problem: "no-usage" };
|
|
478
|
-
|
|
492
|
+
// Prompt cache categories: integers when present (anything else is malformed usage, never a guess). Anthropic's
|
|
493
|
+
// input_tokens counts only the uncached part; the request's whole input is the three added up.
|
|
494
|
+
const cache = (key) => {
|
|
495
|
+
const value = body["usage"][key];
|
|
496
|
+
// Absent: not reported. Present (even null): it must be a token count, or the usage is malformed.
|
|
497
|
+
return value === undefined ? undefined : typeof value === "number" && tokenCount(value) ? value : null;
|
|
498
|
+
};
|
|
499
|
+
const write = cache("cache_creation_input_tokens"), read = cache("cache_read_input_tokens");
|
|
500
|
+
if (write === null || read === null)
|
|
501
|
+
return { ok: false, problem: "no-usage" };
|
|
502
|
+
return { ok: true, answer: { text, calls, tokensIn: usage.tokensIn + (write ?? 0) + (read ?? 0), tokensOut: usage.tokensOut, reportedCostMicrousd: null,
|
|
503
|
+
...(write === undefined ? {} : { cacheWriteTokens: write }), ...(read === undefined ? {} : { cacheReadTokens: read }) } };
|
|
479
504
|
}
|
|
480
505
|
const choices = body["choices"];
|
|
481
506
|
if (!Array.isArray(choices) || choices.length !== 1)
|
|
@@ -528,7 +553,9 @@ export function parseLeadProviderWrapper(provider, bytes) {
|
|
|
528
553
|
export function composeLeadRequest(args) {
|
|
529
554
|
const opener = `DATA:\n${args.dataDocument}\n\n(The conversation follows. Every operator message is data, from the operator.)`;
|
|
530
555
|
if (args.provider === "anthropic-api") {
|
|
531
|
-
const
|
|
556
|
+
const ephemeral = { cache_control: { type: "ephemeral" } };
|
|
557
|
+
const cached = args.cache !== undefined;
|
|
558
|
+
const messages = [{ role: "user", content: cached ? [{ type: "text", text: opener, ...ephemeral }] : opener }];
|
|
532
559
|
for (const one of args.history) {
|
|
533
560
|
if (one.role === "operator")
|
|
534
561
|
messages.push({ role: "user", content: one.text });
|
|
@@ -549,8 +576,9 @@ export function composeLeadRequest(args) {
|
|
|
549
576
|
body: JSON.stringify({
|
|
550
577
|
model: args.model,
|
|
551
578
|
max_tokens: MAX_OUTPUT_TOKENS,
|
|
552
|
-
system: args.system,
|
|
553
|
-
tools: args.tools.map(tool => ({ name: tool.name, description: tool.description, input_schema: tool.inputSchema
|
|
579
|
+
system: cached ? [{ type: "text", text: args.system, ...ephemeral }] : args.system,
|
|
580
|
+
tools: args.tools.map((tool, index) => ({ name: tool.name, description: tool.description, input_schema: tool.inputSchema,
|
|
581
|
+
...(cached && index === args.cache.coreTools - 1 ? ephemeral : {}) })),
|
|
554
582
|
messages,
|
|
555
583
|
}),
|
|
556
584
|
};
|
package/dist/demo-chat.js
CHANGED
|
@@ -8,7 +8,7 @@ import { html, postForm } from "./html.js";
|
|
|
8
8
|
import { headlineOf } from "./task-status.js";
|
|
9
9
|
const SUGGESTIONS = ["Fix the flaky refund test", "Rewrite the empty Payouts page", "Put the new invoice view behind a flag"];
|
|
10
10
|
function hint() {
|
|
11
|
-
return html `<section class="demo-hint" aria-label="Get started"><
|
|
11
|
+
return html `<section class="demo-hint" aria-label="Get started"><h2 class="demo-hint-title">What should the crew do?</h2><p class="demo-hint-sub">Ask for something, like “fix the flaky refund test”, or start from one of these.</p>${postForm("/chat/demo/ask", SUGGESTIONS.map(one => html `<button type="submit" name="message" value="${one}">${one}</button>`), { attrs: { class: "demo-suggestions" } })}</section>`;
|
|
12
12
|
}
|
|
13
13
|
function planCard(exchange) {
|
|
14
14
|
const plan = exchange.plan;
|
|
@@ -55,7 +55,7 @@ export function demoThreadHtml(exchanges, resultOf) {
|
|
|
55
55
|
return html `${exchanges.map(exchange => {
|
|
56
56
|
const parts = [
|
|
57
57
|
html `<div class="demo-said demo-you"><p>${exchange.asked}</p></div>`,
|
|
58
|
-
html `<div class="demo-said demo-lead"><p class="demo-who">Lead</p><p>${exchange.reply}</p></div>`,
|
|
58
|
+
html `<div class="demo-said demo-lead"><p class="demo-who"><span class="demo-avatar" aria-hidden="true">L</span>Lead</p><p>${exchange.reply}</p></div>`,
|
|
59
59
|
planCard(exchange),
|
|
60
60
|
];
|
|
61
61
|
if (exchange.state === "working")
|
|
@@ -63,14 +63,14 @@ export function demoThreadHtml(exchanges, resultOf) {
|
|
|
63
63
|
if (exchange.state === "ready" || exchange.state === "complete" || exchange.state === "sent-back")
|
|
64
64
|
parts.push(resultCard(exchange, resultOf(exchange)));
|
|
65
65
|
if (exchange.state === "complete") {
|
|
66
|
-
parts.push(html `<div class="demo-said demo-lead"><p class="demo-who">Lead</p><p>Done. That's the whole loop: ask, approve, Ready, Complete. Ask for something else whenever you like.</p></div>`, html `<section class="card demo-handoff" data-demo-handoff aria-label="Your own project"><h2>Now try it on your own project</h2><p>In your repository's folder, run:</p><pre class="demo-command"><code>${START_COMMAND}</code></pre><p class="meta">It opens in your browser, already signed in.</p></section>`);
|
|
66
|
+
parts.push(html `<div class="demo-said demo-lead"><p class="demo-who"><span class="demo-avatar" aria-hidden="true">L</span>Lead</p><p>Done. That's the whole loop: ask, approve, Ready, Complete. Ask for something else whenever you like.</p></div>`, html `<section class="card demo-handoff" data-demo-handoff aria-label="Your own project"><h2>Now try it on your own project</h2><p>In your repository's folder, run:</p><pre class="demo-command"><code>${START_COMMAND}</code></pre><p class="meta">It opens in your browser, already signed in.</p></section>`);
|
|
67
67
|
}
|
|
68
68
|
return html `<article class="demo-turn" id="demo-${exchange.id}">${parts}</article>`;
|
|
69
69
|
})}`;
|
|
70
70
|
}
|
|
71
71
|
export function demoChatHtml(input) {
|
|
72
72
|
const working = input.exchanges.some(one => one.state === "working");
|
|
73
|
-
return html `<div class="demo-chat">${input.problem === null ? "" : html `<p class="problem" role="alert">${input.problem}</p>`}<div id="demo-thread" class="demo-thread" aria-live="polite" data-version="${input.version}" data-working="${working ? "1" : "0"}">${demoThreadHtml(input.exchanges, input.resultOf)}</div>${postForm("/chat/demo/ask", html `<label for="demo-message" class="so-sr-only">Message the lead</label><textarea id="demo-message" name="message" rows="
|
|
73
|
+
return html `<div class="demo-chat${input.exchanges.length === 0 ? " demo-chat--empty" : ""}">${input.problem === null ? "" : html `<p class="problem" role="alert">${input.problem}</p>`}<div id="demo-thread" class="demo-thread" aria-live="polite" data-version="${input.version}" data-working="${working ? "1" : "0"}">${demoThreadHtml(input.exchanges, input.resultOf)}</div>${postForm("/chat/demo/ask", html `<label for="demo-message" class="so-sr-only">Message the lead</label><div class="demo-composer-card"><textarea id="demo-message" name="message" rows="1" maxlength="500" placeholder="Ask the lead for a change" required aria-describedby="demo-composer-hint"></textarea><div class="demo-composer-bar"><span id="demo-composer-hint">Enter to send · Shift + Enter for a new line</span><button type="submit" class="demo-primary demo-send" aria-label="Send"><svg aria-hidden="true" viewBox="0 0 16 16" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M8 13V3M3.5 7.5 8 3l4.5 4.5"/></svg></button></div></div>`, { attrs: { class: "demo-composer" } })}</div>`;
|
|
74
74
|
}
|
|
75
75
|
/**
|
|
76
76
|
* Keeps a running build live: polls while one is working and swaps the
|
package/dist/demo.js
CHANGED
|
@@ -1044,14 +1044,14 @@ function seedDemoFlows(store, folder, now) {
|
|
|
1044
1044
|
["Parcel arrived crushed", "The box was crushed and two glasses inside are broken.", "Delivery problem", 0.91, "delivery", "Soon: the customer is waiting on it", true, 120],
|
|
1045
1045
|
["Where is my order and why was I billed?", "It hasn't arrived and there's a charge I don't recognise.", "Delivery problem", 0.58, "by-hand", "Soon: the customer is waiting on it", false, 45],
|
|
1046
1046
|
]) {
|
|
1047
|
-
const card = store.addFlowCard({ flow: desk, title, description, stage: "sort", by: "Support form" }, at(minutes));
|
|
1047
|
+
const card = store.addFlowCard({ flow: desk, title, description, stage: "sort", by: "Support form", byKind: "automation" }, at(minutes));
|
|
1048
1048
|
const confident = sure >= 0.8;
|
|
1049
1049
|
step(card, "sort", "sort", at(minutes - 1), confident ? `${answer}, ${Math.round(sure * 100)}% sure.` : `Not sure: ${Math.round(sure * 100)}% ${answer}.`, `${confident ? `${answer}, ${Math.round(sure * 100)}% sure.` : `Not sure: ${Math.round(sure * 100)}% ${answer}.`} How urgent is it? ${urgency.split(":")[0]}.`, { decisionJson: sorted(answer, sure, to, urgency, refund) });
|
|
1050
1050
|
move(card, to, at(minutes - 1));
|
|
1051
1051
|
}
|
|
1052
1052
|
const replies = store.createFlow({ repo, name: "Customer replies", definitionJson: template("email-replies"), by: "demo" }, at(200));
|
|
1053
1053
|
const drafted = (title, description, draft, minutes) => {
|
|
1054
|
-
const card = store.addFlowCard({ flow: replies, title, description, stage: "write", by: "Contact form" }, at(minutes));
|
|
1054
|
+
const card = store.addFlowCard({ flow: replies, title, description, stage: "write", by: "Contact form", byKind: "automation" }, at(minutes));
|
|
1055
1055
|
step(card, "write", "draft", at(minutes - 1), `Drafted ${draft.split(/\s+/).length} words.`, draft, { log: `Claude (sonnet) · 4.2 s\n\n${draft}` });
|
|
1056
1056
|
move(card, "check", at(minutes - 1));
|
|
1057
1057
|
return card;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { activeCodingUpdateWork, installCodingUpdateGate, removeCodingUpdateGate } from "./coding-update.js";
|
|
2
|
+
import { activeTerminalUpdateWork, installTerminalUpdateGate, removeTerminalUpdateGate } from "./terminal-catalog.js";
|
|
2
3
|
export const UPDATE_PAUSED = "Toolroll is updating. Current work can finish; new work will resume after the update. Open Update status in the desktop app.";
|
|
3
4
|
const prefix = "so_desktop_update_";
|
|
4
5
|
const rows = (db) => db.prepare("SELECT name, sql FROM sqlite_master WHERE type='trigger' AND name GLOB 'so_desktop_update_*' ORDER BY name").all();
|
|
@@ -36,6 +37,7 @@ export function installUpdateGate(db, id) {
|
|
|
36
37
|
throw error;
|
|
37
38
|
}
|
|
38
39
|
installCodingUpdateGate(db, id);
|
|
40
|
+
installTerminalUpdateGate(db, id);
|
|
39
41
|
}
|
|
40
42
|
export function removeUpdateGate(db, id) {
|
|
41
43
|
const wanted = [...statements(id), ...statements(id, true)];
|
|
@@ -45,6 +47,7 @@ export function removeUpdateGate(db, id) {
|
|
|
45
47
|
if (existing.some(row => !owns(wanted, row.sql)))
|
|
46
48
|
throw Error("This update does not own the admission pause. Nothing was cleared.");
|
|
47
49
|
removeCodingUpdateGate(db, id);
|
|
50
|
+
removeTerminalUpdateGate(db, id);
|
|
48
51
|
for (const row of existing)
|
|
49
52
|
db.exec(`DROP TRIGGER "${String(row.name)}"`);
|
|
50
53
|
db.exec("COMMIT");
|
|
@@ -67,6 +70,8 @@ export function activeUpdateWork(db) {
|
|
|
67
70
|
conversations: count("SELECT count(*) n FROM mate_turn WHERE state IN ('queued','running')") + count("SELECT count(*) n FROM chat_turn WHERE state IN ('queued','running')"),
|
|
68
71
|
stopping: count("SELECT count(*) n FROM run_stop WHERE settled_at IS NULL"),
|
|
69
72
|
...activeCodingUpdateWork(db),
|
|
73
|
+
// Live terminals in a console that is still running (terminal-catalog.ts).
|
|
74
|
+
...activeTerminalUpdateWork(db),
|
|
70
75
|
};
|
|
71
76
|
}
|
|
72
77
|
/** Last admission race closes in the same SQLite write transaction as the
|
|
@@ -77,6 +82,7 @@ export function freezeUpdateGate(db, id) {
|
|
|
77
82
|
if (!updateGateOwned(db, id))
|
|
78
83
|
throw Error("The update no longer owns admission.");
|
|
79
84
|
installCodingUpdateGate(db, id);
|
|
85
|
+
installTerminalUpdateGate(db, id);
|
|
80
86
|
const idle = Object.values(activeUpdateWork(db)).every(n => n === 0);
|
|
81
87
|
if (idle) {
|
|
82
88
|
for (const row of rows(db))
|
package/dist/discord-chat.js
CHANGED
|
@@ -8,7 +8,7 @@ import { roomCommand } from "./chat-rooms.js";
|
|
|
8
8
|
import { ChatState, ChatDeliveryError, chatHash, partContent, } from "./chat-delivery-state.js";
|
|
9
9
|
import { readChatPart } from "./contracts/chat-content.js";
|
|
10
10
|
import { readDiscordButtonToken, readDiscordComponentInteraction } from "./contracts/discord-callback.js";
|
|
11
|
-
import { processChatEvent, planChatNotifications, channelAccess, chatObject as object, planRoomMessages, } from "./chat-delivery.js";
|
|
11
|
+
import { processChatEvent, planChatNotifications, channelAccess, chatObject as object, planRoomMessages, heldForWatch, } from "./chat-delivery.js";
|
|
12
12
|
import { chatResultHref } from "./chat-controls.js";
|
|
13
13
|
import { LEAD_MESSAGE_MAX_CHARS } from "./lead.js";
|
|
14
14
|
import { discordPlain, renderReply } from "./reply-shape.js";
|
|
@@ -379,6 +379,9 @@ export async function deliverDiscordPart(options) {
|
|
|
379
379
|
fail_if_not_exists: false,
|
|
380
380
|
};
|
|
381
381
|
}
|
|
382
|
+
// The watch, at the last moment before the network (cockpit §3).
|
|
383
|
+
if (heldForWatch(state, store, row.id, event, binding.approver, content, now))
|
|
384
|
+
return true;
|
|
382
385
|
const answer = await options.api(target ? "PATCH" : "POST", `/channels/${destination}/messages${target ? `/${target}` : ""}`, args, file);
|
|
383
386
|
if (!discordId(answer.id) ||
|
|
384
387
|
answer.channel_id !== destination ||
|
package/dist/dispatch.js
CHANGED
|
@@ -15,6 +15,8 @@ import { REVIEW_TOKENS, resultStatusOf, reviewFactsOf } from "./workspace-ui.js"
|
|
|
15
15
|
import { replacedWords } from "./task-status.js";
|
|
16
16
|
import { failedAttemptSentence, latestFinishedAttempt } from "./needs-you.js";
|
|
17
17
|
import { buildReviewOf } from "./review-switch.js";
|
|
18
|
+
import { grantStandsSql } from "./flow-unattended.js";
|
|
19
|
+
import { accountReachesSql } from "./project-access.js";
|
|
18
20
|
import { BUILT_IN, parseCapabilityKey } from "./store.js";
|
|
19
21
|
export const DEFAULT_MAX_OPEN_DECISIONS = 5;
|
|
20
22
|
/**
|
|
@@ -75,13 +77,14 @@ export function scopeApprovedForDispatch(store, taskRef, now) {
|
|
|
75
77
|
.prepare(`SELECT 1 AS hit FROM task_scope
|
|
76
78
|
JOIN task_ref ON task_ref.id = ? AND task_scope.task_id = task_ref.external_id
|
|
77
79
|
WHERE task_scope.approved_digest = task_scope.digest AND task_scope.approved_at IS NOT NULL
|
|
78
|
-
AND (COALESCE(task_scope.approval_basis, 'password')
|
|
79
|
-
OR EXISTS (SELECT 1 FROM operating_mode om
|
|
80
|
+
AND (COALESCE(task_scope.approval_basis, 'password') NOT IN ('mode', 'grant')
|
|
81
|
+
OR (task_scope.approval_basis = 'mode' AND EXISTS (SELECT 1 FROM operating_mode om
|
|
80
82
|
JOIN approver signer ON signer.name = om.signed_by
|
|
81
83
|
WHERE om.repo = task_ref.repo AND om.revoked_at IS NULL
|
|
82
84
|
AND om.absolute_expiry > ? AND om.digest = task_scope.mode_digest
|
|
83
|
-
AND signer.revoked_at IS NULL AND signer.role = 'approver'))
|
|
84
|
-
|
|
85
|
+
AND signer.revoked_at IS NULL AND signer.role = 'approver' AND ${accountReachesSql("signer", "task_ref.repo")}))
|
|
86
|
+
OR (task_scope.approval_basis = 'grant' AND ${grantStandsSql("task_scope.mode_digest", "?", "task_ref.repo")}))`)
|
|
87
|
+
.get(taskRef, now.toISOString(), now.toISOString());
|
|
85
88
|
return row !== undefined;
|
|
86
89
|
}
|
|
87
90
|
/** The phase the ordinary dispatch loop would choose before it resolves an
|
package/dist/doctor.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type SupervisorRunner } from "./daemon.js";
|
|
2
|
+
/** Something that holds a credential a build could read, by name only, and what the owner does about it. */
|
|
3
|
+
export type DoctorFinding = {
|
|
4
|
+
where: string;
|
|
5
|
+
names: string[];
|
|
6
|
+
steps: string[];
|
|
7
|
+
};
|
|
8
|
+
/** Something the doctor could not read: never taken for clean. */
|
|
9
|
+
export type DoctorUnreadable = {
|
|
10
|
+
where: string;
|
|
11
|
+
problem: string;
|
|
12
|
+
steps: string[];
|
|
13
|
+
};
|
|
14
|
+
export type DoctorReport = {
|
|
15
|
+
ok: boolean;
|
|
16
|
+
checked: string[];
|
|
17
|
+
findings: DoctorFinding[];
|
|
18
|
+
unreadable: DoctorUnreadable[];
|
|
19
|
+
notes: string[];
|
|
20
|
+
};
|
|
21
|
+
export type DoctorDeps = {
|
|
22
|
+
platform?: NodeJS.Platform;
|
|
23
|
+
home?: string;
|
|
24
|
+
uid?: number;
|
|
25
|
+
/** Runs the read-only supervisor and process queries (launchctl, systemctl, ps). */
|
|
26
|
+
run?: SupervisorRunner;
|
|
27
|
+
/** Where Linux keeps its process files (a test's stand-in). */
|
|
28
|
+
procRoot?: string;
|
|
29
|
+
/** The doctor's own environment: the terminal a `toolroll up` would start from. */
|
|
30
|
+
env?: NodeJS.ProcessEnv;
|
|
31
|
+
};
|
|
32
|
+
/** The names among `pairs` that hold a credential: a provider key, a credential-looking name, or a key-shaped value.
|
|
33
|
+
* Values are only tested here and never leave. */
|
|
34
|
+
export declare function credentialNames(pairs: Iterable<readonly [string, string]>): string[];
|
|
35
|
+
/** A running process's environment names (never values) that hold a credential: macOS through `ps -E`, which reads
|
|
36
|
+
* KERN_PROCARGS2; Linux from /proc/<pid>/environ. */
|
|
37
|
+
export declare function processCredentialNames(pid: number, deps: {
|
|
38
|
+
platform: NodeJS.Platform;
|
|
39
|
+
run: SupervisorRunner;
|
|
40
|
+
procRoot?: string;
|
|
41
|
+
}): Promise<{
|
|
42
|
+
ok: true;
|
|
43
|
+
names: string[];
|
|
44
|
+
} | {
|
|
45
|
+
ok: false;
|
|
46
|
+
problem: string;
|
|
47
|
+
}>;
|
|
48
|
+
/** Audit what Toolroll's service holds. Reads only; the report names variables, never their values. */
|
|
49
|
+
export declare function auditServiceEnvironment(deps?: DoctorDeps): Promise<DoctorReport>;
|
|
50
|
+
/** The report as the owner reads it: one state, then each finding with its steps; detail after. */
|
|
51
|
+
export declare function doctorLines(report: DoctorReport): string[];
|
|
52
|
+
export declare const DOCTOR_HELP = "toolroll doctor [--json]\nChecks that Toolroll's service holds no API key, token or password a build could read: its service definitions, what `daemon install` writes, the environment its manager hands it, and its running process. Reads only: it names what it finds and the steps to fix it, and never changes a file or restarts anything.";
|
|
53
|
+
export declare function runDoctorCommand(argv: readonly string[], write: (line: string) => void, deps?: DoctorDeps): Promise<number>;
|