toolroll 0.5.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/LICENSE +21 -0
- package/README.md +1113 -0
- package/THIRD_PARTY_NOTICES.md +449 -0
- package/dist/accent-colors.d.ts +48 -0
- package/dist/accent-colors.js +122 -0
- package/dist/action-ledger.d.ts +26 -0
- package/dist/action-ledger.js +75 -0
- package/dist/agent-fence.d.ts +42 -0
- package/dist/agent-fence.js +183 -0
- package/dist/agentconfig.d.ts +216 -0
- package/dist/agentconfig.js +454 -0
- package/dist/api-tokens.d.ts +16 -0
- package/dist/api-tokens.js +27 -0
- package/dist/approval-policy.d.ts +69 -0
- package/dist/approval-policy.js +137 -0
- package/dist/approval-rules-ui.d.ts +25 -0
- package/dist/approval-rules-ui.js +39 -0
- package/dist/assignment-adapters.d.ts +180 -0
- package/dist/assignment-adapters.js +239 -0
- package/dist/assignment-brief.d.ts +71 -0
- package/dist/assignment-brief.js +129 -0
- package/dist/assignment-delivery.d.ts +56 -0
- package/dist/assignment-delivery.js +160 -0
- package/dist/assignment-presentation.d.ts +26 -0
- package/dist/assignment-presentation.js +80 -0
- package/dist/assignment-status.d.ts +62 -0
- package/dist/assignment-status.js +152 -0
- package/dist/assignment-ui.d.ts +71 -0
- package/dist/assignment-ui.js +103 -0
- package/dist/assignment.d.ts +222 -0
- package/dist/assignment.js +399 -0
- package/dist/attest.d.ts +56 -0
- package/dist/attest.js +153 -0
- package/dist/backend.d.ts +97 -0
- package/dist/backend.js +166 -0
- package/dist/backup-ui.d.ts +22 -0
- package/dist/backup-ui.js +59 -0
- package/dist/backup.d.ts +84 -0
- package/dist/backup.js +421 -0
- package/dist/beads.d.ts +34 -0
- package/dist/beads.js +135 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +22 -0
- package/dist/board.d.ts +150 -0
- package/dist/board.js +210 -0
- package/dist/boot-identity.d.ts +63 -0
- package/dist/boot-identity.js +99 -0
- package/dist/browser/THIRD_PARTY_NOTICES.txt +2295 -0
- package/dist/browser/workspace.css +4 -0
- package/dist/browser/workspace.js +225 -0
- package/dist/browser-crew.d.ts +11 -0
- package/dist/browser-crew.js +50 -0
- package/dist/browser-shell.d.ts +8 -0
- package/dist/browser-shell.js +60 -0
- package/dist/browser-workspace.d.ts +780 -0
- package/dist/browser-workspace.js +47 -0
- package/dist/budget-alerts.d.ts +19 -0
- package/dist/budget-alerts.js +46 -0
- package/dist/builder.d.ts +370 -0
- package/dist/builder.js +3262 -0
- package/dist/capscan.d.ts +35 -0
- package/dist/capscan.js +113 -0
- package/dist/chat-acceptance.d.ts +71 -0
- package/dist/chat-acceptance.js +120 -0
- package/dist/chat-actions.d.ts +265 -0
- package/dist/chat-actions.js +1273 -0
- package/dist/chat-channel.d.ts +109 -0
- package/dist/chat-channel.js +652 -0
- package/dist/chat-continuity.d.ts +32 -0
- package/dist/chat-continuity.js +317 -0
- package/dist/chat-controls.d.ts +113 -0
- package/dist/chat-controls.js +53 -0
- package/dist/chat-delivery-state.d.ts +159 -0
- package/dist/chat-delivery-state.js +309 -0
- package/dist/chat-delivery.d.ts +38 -0
- package/dist/chat-delivery.js +693 -0
- package/dist/chat-display.d.ts +1 -0
- package/dist/chat-display.js +18 -0
- package/dist/chat-evidence.d.ts +123 -0
- package/dist/chat-evidence.js +207 -0
- package/dist/chat-flow.d.ts +44 -0
- package/dist/chat-flow.js +215 -0
- package/dist/chat-inbox.d.ts +57 -0
- package/dist/chat-inbox.js +123 -0
- package/dist/chat-polish.d.ts +16 -0
- package/dist/chat-polish.js +135 -0
- package/dist/chat-review.d.ts +46 -0
- package/dist/chat-review.js +98 -0
- package/dist/chat-rooms.d.ts +123 -0
- package/dist/chat-rooms.js +216 -0
- package/dist/chat-task-actions.d.ts +44 -0
- package/dist/chat-task-actions.js +79 -0
- package/dist/check-progress.d.ts +51 -0
- package/dist/check-progress.js +290 -0
- package/dist/child-database.d.ts +12 -0
- package/dist/child-database.js +30 -0
- package/dist/claim.d.ts +688 -0
- package/dist/claim.js +1740 -0
- package/dist/cli.d.ts +137 -0
- package/dist/cli.js +1461 -0
- package/dist/codex-limits.d.ts +15 -0
- package/dist/codex-limits.js +145 -0
- package/dist/coding-context.d.ts +55 -0
- package/dist/coding-context.js +92 -0
- package/dist/coding-handoff.d.ts +57 -0
- package/dist/coding-handoff.js +277 -0
- package/dist/coding-provider.d.ts +72 -0
- package/dist/coding-provider.js +424 -0
- package/dist/coding-shipping-ui.d.ts +4 -0
- package/dist/coding-shipping-ui.js +12 -0
- package/dist/coding-types.d.ts +62 -0
- package/dist/coding-types.js +1 -0
- package/dist/coding-ui.d.ts +17 -0
- package/dist/coding-ui.js +364 -0
- package/dist/coding-update.d.ts +15 -0
- package/dist/coding-update.js +149 -0
- package/dist/coding-workspace.d.ts +124 -0
- package/dist/coding-workspace.js +768 -0
- package/dist/container-state.d.ts +5 -0
- package/dist/container-state.js +62 -0
- package/dist/containment.d.ts +197 -0
- package/dist/containment.js +559 -0
- package/dist/contest.d.ts +318 -0
- package/dist/contest.js +753 -0
- package/dist/control-setup.d.ts +35 -0
- package/dist/control-setup.js +40 -0
- package/dist/control-ui.d.ts +29 -0
- package/dist/control-ui.js +53 -0
- package/dist/controller-service.d.ts +1 -0
- package/dist/controller-service.js +19 -0
- package/dist/controller-supervisor.d.ts +30 -0
- package/dist/controller-supervisor.js +104 -0
- package/dist/converse.d.ts +304 -0
- package/dist/converse.js +849 -0
- package/dist/coordinator-proposals.d.ts +29 -0
- package/dist/coordinator-proposals.js +137 -0
- package/dist/coordinator.d.ts +186 -0
- package/dist/coordinator.js +447 -0
- package/dist/credentials-ui.d.ts +25 -0
- package/dist/credentials-ui.js +48 -0
- package/dist/daemon.d.ts +209 -0
- package/dist/daemon.js +604 -0
- package/dist/decision.d.ts +120 -0
- package/dist/decision.js +388 -0
- package/dist/demo.d.ts +55 -0
- package/dist/demo.js +992 -0
- package/dist/desktop-access.d.ts +28 -0
- package/dist/desktop-access.js +88 -0
- package/dist/desktop-bundle.d.ts +16 -0
- package/dist/desktop-bundle.js +74 -0
- package/dist/desktop-host.d.ts +54 -0
- package/dist/desktop-host.js +508 -0
- package/dist/desktop-update-gate.d.ts +12 -0
- package/dist/desktop-update-gate.js +91 -0
- package/dist/desktop-update-recovery.d.ts +14 -0
- package/dist/desktop-update-recovery.js +243 -0
- package/dist/desktop-update.d.ts +110 -0
- package/dist/desktop-update.js +740 -0
- package/dist/discord-api.d.ts +20 -0
- package/dist/discord-api.js +138 -0
- package/dist/discord-chat.d.ts +16 -0
- package/dist/discord-chat.js +381 -0
- package/dist/discord-settings.d.ts +7 -0
- package/dist/discord-settings.js +75 -0
- package/dist/discord.d.ts +10 -0
- package/dist/discord.js +169 -0
- package/dist/discover.d.ts +75 -0
- package/dist/discover.js +150 -0
- package/dist/dispatch.d.ts +100 -0
- package/dist/dispatch.js +311 -0
- package/dist/dispose.d.ts +161 -0
- package/dist/dispose.js +803 -0
- package/dist/email-settings.d.ts +34 -0
- package/dist/email-settings.js +50 -0
- package/dist/envelope.d.ts +47 -0
- package/dist/envelope.js +105 -0
- package/dist/evidence-pack.d.ts +185 -0
- package/dist/evidence-pack.js +258 -0
- package/dist/evidence.d.ts +345 -0
- package/dist/evidence.js +782 -0
- package/dist/exec.d.ts +285 -0
- package/dist/exec.js +1841 -0
- package/dist/exhaustion.d.ts +85 -0
- package/dist/exhaustion.js +141 -0
- package/dist/export-ui.d.ts +4 -0
- package/dist/export-ui.js +17 -0
- package/dist/export.d.ts +48 -0
- package/dist/export.js +305 -0
- package/dist/flow-actions.d.ts +77 -0
- package/dist/flow-actions.js +203 -0
- package/dist/flow-code.d.ts +50 -0
- package/dist/flow-code.js +159 -0
- package/dist/flow-draft.d.ts +38 -0
- package/dist/flow-draft.js +80 -0
- package/dist/flow-engine.d.ts +66 -0
- package/dist/flow-engine.js +416 -0
- package/dist/flow-insights.d.ts +95 -0
- package/dist/flow-insights.js +149 -0
- package/dist/flow-live.d.ts +24 -0
- package/dist/flow-live.js +150 -0
- package/dist/flow-people.d.ts +24 -0
- package/dist/flow-people.js +91 -0
- package/dist/flow-replies.d.ts +48 -0
- package/dist/flow-replies.js +113 -0
- package/dist/flow-scripts.d.ts +38 -0
- package/dist/flow-scripts.js +73 -0
- package/dist/flow-secrets.d.ts +13 -0
- package/dist/flow-secrets.js +45 -0
- package/dist/flow-sort.d.ts +82 -0
- package/dist/flow-sort.js +153 -0
- package/dist/flow-steps.d.ts +40 -0
- package/dist/flow-steps.js +408 -0
- package/dist/flow-triggers.d.ts +244 -0
- package/dist/flow-triggers.js +959 -0
- package/dist/flows-ui.d.ts +20 -0
- package/dist/flows-ui.js +175 -0
- package/dist/flows.d.ts +229 -0
- package/dist/flows.js +968 -0
- package/dist/fonts.d.ts +19 -0
- package/dist/fonts.js +19 -0
- package/dist/gaps.d.ts +35 -0
- package/dist/gaps.js +101 -0
- package/dist/gate-failure.d.ts +40 -0
- package/dist/gate-failure.js +66 -0
- package/dist/git.d.ts +54 -0
- package/dist/git.js +94 -0
- package/dist/google-mail.d.ts +58 -0
- package/dist/google-mail.js +151 -0
- package/dist/grant.d.ts +136 -0
- package/dist/grant.js +238 -0
- package/dist/graph.d.ts +164 -0
- package/dist/graph.js +383 -0
- package/dist/guides.d.ts +22 -0
- package/dist/guides.js +363 -0
- package/dist/held.d.ts +150 -0
- package/dist/held.js +799 -0
- package/dist/invoke.d.ts +112 -0
- package/dist/invoke.js +780 -0
- package/dist/issues.d.ts +41 -0
- package/dist/issues.js +131 -0
- package/dist/job-object-helper.ps1 +252 -0
- package/dist/jsonl-discriminants.d.ts +11 -0
- package/dist/jsonl-discriminants.js +93 -0
- package/dist/keys.d.ts +104 -0
- package/dist/keys.js +229 -0
- package/dist/kits-ui.d.ts +17 -0
- package/dist/kits-ui.js +46 -0
- package/dist/kits.d.ts +86 -0
- package/dist/kits.js +215 -0
- package/dist/knowledge-cli.d.ts +101 -0
- package/dist/knowledge-cli.js +92 -0
- package/dist/knowledge-ui.d.ts +24 -0
- package/dist/knowledge-ui.js +40 -0
- package/dist/lead-context.d.ts +8 -0
- package/dist/lead-context.js +56 -0
- package/dist/lead-follow.d.ts +22 -0
- package/dist/lead-follow.js +167 -0
- package/dist/lead-status.d.ts +75 -0
- package/dist/lead-status.js +285 -0
- package/dist/ledger-chain.d.ts +46 -0
- package/dist/ledger-chain.js +187 -0
- package/dist/ledger-csv.d.ts +4 -0
- package/dist/ledger-csv.js +11 -0
- package/dist/ledger-view.d.ts +24 -0
- package/dist/ledger-view.js +58 -0
- package/dist/limits-ui.d.ts +26 -0
- package/dist/limits-ui.js +67 -0
- package/dist/link.d.ts +72 -0
- package/dist/link.js +217 -0
- package/dist/live.d.ts +96 -0
- package/dist/live.js +366 -0
- package/dist/liveness.d.ts +30 -0
- package/dist/liveness.js +42 -0
- package/dist/log.d.ts +7 -0
- package/dist/log.js +25 -0
- package/dist/mailbox.d.ts +57 -0
- package/dist/mailbox.js +150 -0
- package/dist/maintenance.d.ts +11 -0
- package/dist/maintenance.js +35 -0
- package/dist/mate-cli.d.ts +52 -0
- package/dist/mate-cli.js +345 -0
- package/dist/mate-contract.d.ts +10 -0
- package/dist/mate-contract.js +30 -0
- package/dist/mate-doors.d.ts +69 -0
- package/dist/mate-doors.js +548 -0
- package/dist/mate-progress.d.ts +29 -0
- package/dist/mate-progress.js +121 -0
- package/dist/mate-tools.d.ts +94 -0
- package/dist/mate-tools.js +1878 -0
- package/dist/mate.d.ts +92 -0
- package/dist/mate.js +435 -0
- package/dist/mcp-connect.d.ts +103 -0
- package/dist/mcp-connect.js +252 -0
- package/dist/mcp.d.ts +27 -0
- package/dist/mcp.js +651 -0
- package/dist/memory-cli.d.ts +466 -0
- package/dist/memory-cli.js +111 -0
- package/dist/memory-pass.d.ts +160 -0
- package/dist/memory-pass.js +409 -0
- package/dist/metrics.d.ts +3 -0
- package/dist/metrics.js +56 -0
- package/dist/mobile-viewport.d.ts +3 -0
- package/dist/mobile-viewport.js +37 -0
- package/dist/model-catalog.d.ts +118 -0
- package/dist/model-catalog.js +376 -0
- package/dist/models-cli.d.ts +102 -0
- package/dist/models-cli.js +66 -0
- package/dist/models-ui.d.ts +34 -0
- package/dist/models-ui.js +68 -0
- package/dist/modes.d.ts +80 -0
- package/dist/modes.js +182 -0
- package/dist/monitoring-settings.d.ts +44 -0
- package/dist/monitoring-settings.js +173 -0
- package/dist/monitoring-ui.d.ts +20 -0
- package/dist/monitoring-ui.js +51 -0
- package/dist/monitoring.d.ts +34 -0
- package/dist/monitoring.js +221 -0
- package/dist/names.d.ts +67 -0
- package/dist/names.js +102 -0
- package/dist/observations.d.ts +40 -0
- package/dist/observations.js +211 -0
- package/dist/oidc.d.ts +71 -0
- package/dist/oidc.js +182 -0
- package/dist/onboard.d.ts +108 -0
- package/dist/onboard.js +325 -0
- package/dist/openrouter-models.d.ts +30 -0
- package/dist/openrouter-models.js +120 -0
- package/dist/operate.d.ts +118 -0
- package/dist/operate.js +11321 -0
- package/dist/peek-cli.d.ts +97 -0
- package/dist/peek-cli.js +215 -0
- package/dist/peek.d.ts +134 -0
- package/dist/peek.js +578 -0
- package/dist/phase-routing.d.ts +307 -0
- package/dist/phase-routing.js +658 -0
- package/dist/plan-auto.d.ts +14 -0
- package/dist/plan-auto.js +92 -0
- package/dist/plan.d.ts +186 -0
- package/dist/plan.js +401 -0
- package/dist/planner-source.d.ts +251 -0
- package/dist/planner-source.js +460 -0
- package/dist/planner.d.ts +75 -0
- package/dist/planner.js +992 -0
- package/dist/policy-ui.d.ts +20 -0
- package/dist/policy-ui.js +41 -0
- package/dist/policy.d.ts +111 -0
- package/dist/policy.js +231 -0
- package/dist/prepared-evidence.d.ts +16 -0
- package/dist/prepared-evidence.js +96 -0
- package/dist/pricing.d.ts +45 -0
- package/dist/pricing.js +77 -0
- package/dist/principal.d.ts +42 -0
- package/dist/principal.js +82 -0
- package/dist/probe.d.ts +46 -0
- package/dist/probe.js +79 -0
- package/dist/process-custody.d.ts +17 -0
- package/dist/process-custody.js +91 -0
- package/dist/process-liveness.d.ts +10 -0
- package/dist/process-liveness.js +81 -0
- package/dist/process-recovery-anchor.d.ts +75 -0
- package/dist/process-recovery-anchor.js +188 -0
- package/dist/process-recovery-coalition.d.ts +25 -0
- package/dist/process-recovery-coalition.js +105 -0
- package/dist/process-recovery-eligibility.d.ts +178 -0
- package/dist/process-recovery-eligibility.js +170 -0
- package/dist/process-recovery-native.d.ts +172 -0
- package/dist/process-recovery-native.js +592 -0
- package/dist/process-recovery-provenance.d.ts +163 -0
- package/dist/process-recovery-provenance.js +292 -0
- package/dist/process-recovery-services.d.ts +56 -0
- package/dist/process-recovery-services.js +191 -0
- package/dist/process-recovery-settlement.d.ts +32 -0
- package/dist/process-recovery-settlement.js +132 -0
- package/dist/process-recovery.d.ts +41 -0
- package/dist/process-recovery.js +91 -0
- package/dist/process-tree.d.ts +41 -0
- package/dist/process-tree.js +264 -0
- package/dist/project-access.d.ts +14 -0
- package/dist/project-access.js +34 -0
- package/dist/project-cli.d.ts +18 -0
- package/dist/project-cli.js +104 -0
- package/dist/project-delete-ui.d.ts +22 -0
- package/dist/project-delete-ui.js +48 -0
- package/dist/project-delete.d.ts +55 -0
- package/dist/project-delete.js +413 -0
- package/dist/project-knowledge.d.ts +111 -0
- package/dist/project-knowledge.js +241 -0
- package/dist/project-learning.d.ts +100 -0
- package/dist/project-learning.js +438 -0
- package/dist/project-memory.d.ts +81 -0
- package/dist/project-memory.js +264 -0
- package/dist/project-skills.d.ts +152 -0
- package/dist/project-skills.js +660 -0
- package/dist/project-tools.d.ts +219 -0
- package/dist/project-tools.js +796 -0
- package/dist/project.d.ts +61 -0
- package/dist/project.js +125 -0
- package/dist/prompt.d.ts +22 -0
- package/dist/prompt.js +72 -0
- package/dist/proof.d.ts +513 -0
- package/dist/proof.js +1140 -0
- package/dist/proposal.d.ts +82 -0
- package/dist/proposal.js +210 -0
- package/dist/provider-connection.d.ts +22 -0
- package/dist/provider-connection.js +98 -0
- package/dist/provider-limits.d.ts +35 -0
- package/dist/provider-limits.js +95 -0
- package/dist/provider.d.ts +279 -0
- package/dist/provider.js +935 -0
- package/dist/publish.d.ts +107 -0
- package/dist/publish.js +650 -0
- package/dist/pulls.d.ts +118 -0
- package/dist/pulls.js +240 -0
- package/dist/push.d.ts +95 -0
- package/dist/push.js +353 -0
- package/dist/quality.d.ts +8 -0
- package/dist/quality.js +6 -0
- package/dist/recipe-ui.d.ts +18 -0
- package/dist/recipe-ui.js +152 -0
- package/dist/recipes.d.ts +81 -0
- package/dist/recipes.js +332 -0
- package/dist/remote.d.ts +67 -0
- package/dist/remote.js +122 -0
- package/dist/render.d.ts +64 -0
- package/dist/render.js +587 -0
- package/dist/report-summary.d.ts +13 -0
- package/dist/report-summary.js +15 -0
- package/dist/repos.d.ts +65 -0
- package/dist/repos.js +277 -0
- package/dist/repository-context-ui.d.ts +2 -0
- package/dist/repository-context-ui.js +10 -0
- package/dist/repository-context.d.ts +67 -0
- package/dist/repository-context.js +376 -0
- package/dist/restart-certification.d.ts +134 -0
- package/dist/restart-certification.js +226 -0
- package/dist/result-actions.d.ts +28 -0
- package/dist/result-actions.js +270 -0
- package/dist/result-completion.d.ts +18 -0
- package/dist/result-completion.js +66 -0
- package/dist/result-review.d.ts +213 -0
- package/dist/result-review.js +430 -0
- package/dist/retention-ui.d.ts +12 -0
- package/dist/retention-ui.js +39 -0
- package/dist/retention.d.ts +72 -0
- package/dist/retention.js +288 -0
- package/dist/review-context.d.ts +243 -0
- package/dist/review-context.js +1043 -0
- package/dist/review-evidence.d.ts +33 -0
- package/dist/review-evidence.js +56 -0
- package/dist/reviewer.d.ts +97 -0
- package/dist/reviewer.js +202 -0
- package/dist/routine.d.ts +228 -0
- package/dist/routine.js +764 -0
- package/dist/runner.d.ts +266 -0
- package/dist/runner.js +399 -0
- package/dist/scan.d.ts +32 -0
- package/dist/scan.js +92 -0
- package/dist/scope.d.ts +695 -0
- package/dist/scope.js +1176 -0
- package/dist/scout-report.d.ts +42 -0
- package/dist/scout-report.js +108 -0
- package/dist/scout.d.ts +69 -0
- package/dist/scout.js +351 -0
- package/dist/serve.d.ts +313 -0
- package/dist/serve.js +21776 -0
- package/dist/session-brief.d.ts +8 -0
- package/dist/session-brief.js +24 -0
- package/dist/session-cli.d.ts +13 -0
- package/dist/session-cli.js +284 -0
- package/dist/session-contract.d.ts +183 -0
- package/dist/session-contract.js +122 -0
- package/dist/session-http.d.ts +19 -0
- package/dist/session-http.js +154 -0
- package/dist/session-server.d.ts +12 -0
- package/dist/session-server.js +37 -0
- package/dist/session-service.d.ts +22 -0
- package/dist/session-service.js +157 -0
- package/dist/setup-guide.d.ts +39 -0
- package/dist/setup-guide.js +93 -0
- package/dist/sign-in-guard.d.ts +45 -0
- package/dist/sign-in-guard.js +74 -0
- package/dist/skills-ui.d.ts +11 -0
- package/dist/skills-ui.js +58 -0
- package/dist/skills.d.ts +97 -0
- package/dist/skills.js +276 -0
- package/dist/slack-api.d.ts +55 -0
- package/dist/slack-api.js +229 -0
- package/dist/slack-chat.d.ts +28 -0
- package/dist/slack-chat.js +413 -0
- package/dist/slack-settings.d.ts +7 -0
- package/dist/slack-settings.js +75 -0
- package/dist/slack-state.d.ts +13 -0
- package/dist/slack-state.js +9 -0
- package/dist/slack.d.ts +13 -0
- package/dist/slack.js +167 -0
- package/dist/spend-ui.d.ts +28 -0
- package/dist/spend-ui.js +95 -0
- package/dist/spend.d.ts +142 -0
- package/dist/spend.js +313 -0
- package/dist/sqlite-runtime.d.ts +3 -0
- package/dist/sqlite-runtime.js +6 -0
- package/dist/sso-settings.d.ts +33 -0
- package/dist/sso-settings.js +103 -0
- package/dist/sso-ui.d.ts +22 -0
- package/dist/sso-ui.js +39 -0
- package/dist/storage.d.ts +15 -0
- package/dist/storage.js +84 -0
- package/dist/store.d.ts +7754 -0
- package/dist/store.js +23279 -0
- package/dist/structured-output.d.ts +58 -0
- package/dist/structured-output.js +103 -0
- package/dist/style-asset.d.ts +7 -0
- package/dist/style-asset.js +41 -0
- package/dist/subscription-chat.d.ts +46 -0
- package/dist/subscription-chat.js +275 -0
- package/dist/summary.d.ts +33 -0
- package/dist/summary.js +71 -0
- package/dist/supervisor.mjs +297 -0
- package/dist/surface.d.ts +63 -0
- package/dist/surface.js +352 -0
- package/dist/sync.d.ts +94 -0
- package/dist/sync.js +279 -0
- package/dist/task-composer.d.ts +13 -0
- package/dist/task-composer.js +52 -0
- package/dist/task-control.d.ts +165 -0
- package/dist/task-control.js +214 -0
- package/dist/task-outcome-cli.d.ts +10 -0
- package/dist/task-outcome-cli.js +92 -0
- package/dist/task-text.d.ts +30 -0
- package/dist/task-text.js +41 -0
- package/dist/team-cli.d.ts +15 -0
- package/dist/team-cli.js +618 -0
- package/dist/team-contract.d.ts +92 -0
- package/dist/team-contract.js +1 -0
- package/dist/team-http.d.ts +17 -0
- package/dist/team-http.js +144 -0
- package/dist/team-leads.d.ts +81 -0
- package/dist/team-leads.js +565 -0
- package/dist/team-runtime.d.ts +27 -0
- package/dist/team-runtime.js +264 -0
- package/dist/team-ui.d.ts +3 -0
- package/dist/team-ui.js +9 -0
- package/dist/team-updates.d.ts +8 -0
- package/dist/team-updates.js +57 -0
- package/dist/teammate-admin.d.ts +53 -0
- package/dist/teammate-admin.js +111 -0
- package/dist/teammate-desk.d.ts +60 -0
- package/dist/teammate-desk.js +154 -0
- package/dist/teammate-memory.d.ts +64 -0
- package/dist/teammate-memory.js +196 -0
- package/dist/teammate-question.d.ts +59 -0
- package/dist/teammate-question.js +175 -0
- package/dist/teammate-tools.d.ts +108 -0
- package/dist/teammate-tools.js +271 -0
- package/dist/teammate-week.d.ts +68 -0
- package/dist/teammate-week.js +132 -0
- package/dist/teammate-work.d.ts +76 -0
- package/dist/teammate-work.js +280 -0
- package/dist/teammates-ui.d.ts +20 -0
- package/dist/teammates-ui.js +166 -0
- package/dist/teammates.d.ts +180 -0
- package/dist/teammates.js +253 -0
- package/dist/teams-api.d.ts +33 -0
- package/dist/teams-api.js +204 -0
- package/dist/teams-chat.d.ts +26 -0
- package/dist/teams-chat.js +215 -0
- package/dist/teams-settings.d.ts +12 -0
- package/dist/teams-settings.js +57 -0
- package/dist/teams.d.ts +21 -0
- package/dist/teams.js +124 -0
- package/dist/telegram-flow.d.ts +49 -0
- package/dist/telegram-flow.js +110 -0
- package/dist/telegram-mate.d.ts +137 -0
- package/dist/telegram-mate.js +707 -0
- package/dist/telegram-progress.d.ts +14 -0
- package/dist/telegram-progress.js +129 -0
- package/dist/telegram-settings.d.ts +9 -0
- package/dist/telegram-settings.js +36 -0
- package/dist/telegram-status.d.ts +75 -0
- package/dist/telegram-status.js +265 -0
- package/dist/telegram-team.d.ts +85 -0
- package/dist/telegram-team.js +359 -0
- package/dist/telegram.d.ts +230 -0
- package/dist/telegram.js +1931 -0
- package/dist/templates.d.ts +65 -0
- package/dist/templates.js +118 -0
- package/dist/tool-launcher.d.ts +1 -0
- package/dist/tool-launcher.js +101 -0
- package/dist/tools-ui.d.ts +30 -0
- package/dist/tools-ui.js +40 -0
- package/dist/transitions-recipes.d.ts +1 -0
- package/dist/transitions-recipes.js +203 -0
- package/dist/tree-proof.d.ts +34 -0
- package/dist/tree-proof.js +58 -0
- package/dist/verification-evidence.d.ts +44 -0
- package/dist/verification-evidence.js +238 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +10 -0
- package/dist/webhooks.d.ts +91 -0
- package/dist/webhooks.js +283 -0
- package/dist/work-index.d.ts +68 -0
- package/dist/work-index.js +384 -0
- package/dist/work-summary.d.ts +57 -0
- package/dist/work-summary.js +116 -0
- package/dist/workspace-motion.d.ts +4 -0
- package/dist/workspace-motion.js +133 -0
- package/dist/workspace-revision.d.ts +19 -0
- package/dist/workspace-revision.js +92 -0
- package/dist/workspace-ui.d.ts +204 -0
- package/dist/workspace-ui.js +411 -0
- package/dist/worktree-notices.d.ts +13 -0
- package/dist/worktree-notices.js +17 -0
- package/dist/worktree.d.ts +249 -0
- package/dist/worktree.js +720 -0
- package/package.json +122 -0
- package/scripts/canary-assertions.mjs +42 -0
- package/scripts/crash-canary.mjs +253 -0
- package/scripts/fixtures/crash-process.mjs +74 -0
- package/scripts/fixtures/pilot-scenarios.mjs +85 -0
- package/scripts/fixtures/restart-service.mjs +27 -0
- package/scripts/launchd-certification.mjs +143 -0
- package/scripts/pilot.mjs +121 -0
- package/scripts/proof-preflight.mjs +140 -0
- package/scripts/provider-canary.mjs +379 -0
- package/scripts/recovery-canary.mjs +135 -0
- package/scripts/restart-certification.mjs +98 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared structured-output recovery primitives for planner and reviewer.
|
|
3
|
+
*
|
|
4
|
+
* The normalizer is deliberately syntax-only. It may remove transport
|
|
5
|
+
* wrappers that carry no meaning; it never extracts a likely-looking object
|
|
6
|
+
* from prose, fills a field, truncates a note, changes an id, or chooses a
|
|
7
|
+
* judgement. Semantic repair belongs to the same agent session and remains
|
|
8
|
+
* subject to the phase's strict parser.
|
|
9
|
+
*/
|
|
10
|
+
import type { Store } from "./store.js";
|
|
11
|
+
export declare const STRUCTURED_REPAIR_ATTEMPTS = 2;
|
|
12
|
+
export declare const STRUCTURED_REPAIR_MAX_TURNS = 4;
|
|
13
|
+
export declare const STRUCTURED_REPAIR_TIMEOUT_MS: number;
|
|
14
|
+
/** Native parsing counts UTF-16 code units. A shorter writing target keeps
|
|
15
|
+
* notes concise without imposing a second, stricter transport contract. */
|
|
16
|
+
export declare const REVIEW_OUTPUT_LIMITS: {
|
|
17
|
+
readonly comments: 40;
|
|
18
|
+
readonly criteria: 12;
|
|
19
|
+
readonly note: 500;
|
|
20
|
+
readonly path: 300;
|
|
21
|
+
};
|
|
22
|
+
export declare const REVIEW_NOTE_CODE_POINTS: number;
|
|
23
|
+
export declare const REVIEW_NOTE_GUIDANCE: string;
|
|
24
|
+
export type StructuredNormalization = {
|
|
25
|
+
text: string;
|
|
26
|
+
changed: boolean;
|
|
27
|
+
changes: readonly ("bom" | "whitespace" | "json-fence" | "json-string")[];
|
|
28
|
+
};
|
|
29
|
+
/** Strip only unambiguous, whole-payload wrappers. */
|
|
30
|
+
export declare function normalizeStructuredJson(raw: string): StructuredNormalization;
|
|
31
|
+
export type StructuredAttemptPhase = "planner" | "reviewer" | "builder-proof";
|
|
32
|
+
/**
|
|
33
|
+
* Keep the exact emitted payload unless it contains a high-confidence secret
|
|
34
|
+
* shape, in which case the same line-redaction discipline as terminal diffs
|
|
35
|
+
* keeps the audit record useful without creating a second credential copy.
|
|
36
|
+
*/
|
|
37
|
+
export declare function storeStructuredAttempt(store: Store, root: string, logicalRunId: number, args: {
|
|
38
|
+
phase: StructuredAttemptPhase;
|
|
39
|
+
attempt: number;
|
|
40
|
+
authoredRunId: number;
|
|
41
|
+
raw: string | Buffer;
|
|
42
|
+
/** Exact source size when `raw` is an intentionally bounded prefix. */
|
|
43
|
+
sourceBytesOriginal?: number;
|
|
44
|
+
/**
|
|
45
|
+
* The exact bytes passed the phase parser and every eligibility gate the
|
|
46
|
+
* caller had checked when it captured them. This is never the workflow's
|
|
47
|
+
* final acceptance: custody, evidence bindings, or the atomic finalizer
|
|
48
|
+
* may still refuse them. The run's terminal outcome is that authority.
|
|
49
|
+
*/
|
|
50
|
+
accepted: boolean;
|
|
51
|
+
normalized: boolean;
|
|
52
|
+
now: Date;
|
|
53
|
+
}): number;
|
|
54
|
+
/** JSON-quote parser errors so agent-authored ids/paths remain data. */
|
|
55
|
+
export declare function validationErrorsJson(problems: readonly {
|
|
56
|
+
reason: string;
|
|
57
|
+
message?: string;
|
|
58
|
+
}[]): string;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared structured-output recovery primitives for planner and reviewer.
|
|
3
|
+
*
|
|
4
|
+
* The normalizer is deliberately syntax-only. It may remove transport
|
|
5
|
+
* wrappers that carry no meaning; it never extracts a likely-looking object
|
|
6
|
+
* from prose, fills a field, truncates a note, changes an id, or chooses a
|
|
7
|
+
* judgement. Semantic repair belongs to the same agent session and remains
|
|
8
|
+
* subject to the phase's strict parser.
|
|
9
|
+
*/
|
|
10
|
+
import { redactSecretLines, scanForSecrets, storeEvidence } from "./evidence.js";
|
|
11
|
+
export const STRUCTURED_REPAIR_ATTEMPTS = 2;
|
|
12
|
+
export const STRUCTURED_REPAIR_MAX_TURNS = 4;
|
|
13
|
+
export const STRUCTURED_REPAIR_TIMEOUT_MS = 5 * 60_000;
|
|
14
|
+
/** Native parsing counts UTF-16 code units. A shorter writing target keeps
|
|
15
|
+
* notes concise without imposing a second, stricter transport contract. */
|
|
16
|
+
export const REVIEW_OUTPUT_LIMITS = { comments: 40, criteria: 12, note: 500, path: 300 };
|
|
17
|
+
export const REVIEW_NOTE_CODE_POINTS = Math.floor(REVIEW_OUTPUT_LIMITS.note / 2);
|
|
18
|
+
export const REVIEW_NOTE_GUIDANCE = `Keep each comment and criterion note to one concise finding and its evidence. Aim for ${REVIEW_NOTE_CODE_POINTS} characters or fewer; the hard limit is ${REVIEW_OUTPUT_LIMITS.note} UTF-16 units. Preserve the conclusion and any needed provenance; omit repeated rubric text.`;
|
|
19
|
+
/** Strip only unambiguous, whole-payload wrappers. */
|
|
20
|
+
export function normalizeStructuredJson(raw) {
|
|
21
|
+
let text = raw;
|
|
22
|
+
const changes = [];
|
|
23
|
+
if (text.startsWith("\uFEFF")) {
|
|
24
|
+
text = text.slice(1);
|
|
25
|
+
changes.push("bom");
|
|
26
|
+
}
|
|
27
|
+
const trimmed = text.trim();
|
|
28
|
+
const fenced = /^```(?:json)?[ \t]*\r?\n([\s\S]*?)\r?\n```$/i.exec(trimmed);
|
|
29
|
+
// A pair of complete fenced blocks also matches the outer anchors above
|
|
30
|
+
// (the first opener and final closer). Never collapse that ambiguous
|
|
31
|
+
// payload into one: the strict phase parser should reject it and ask the
|
|
32
|
+
// author to emit one response. A fence marker inside JSON source cannot
|
|
33
|
+
// occur on its own line without making that JSON invalid, so this is a
|
|
34
|
+
// conservative false-negative rather than a semantic rewrite.
|
|
35
|
+
if (fenced !== null && !(fenced[1] ?? "").includes("```")) {
|
|
36
|
+
text = fenced[1] ?? "";
|
|
37
|
+
changes.push("json-fence");
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
if (trimmed !== text)
|
|
41
|
+
changes.push("whitespace");
|
|
42
|
+
text = trimmed;
|
|
43
|
+
}
|
|
44
|
+
// Some harness/model pairs double-encode the complete JSON reply as one
|
|
45
|
+
// JSON string. Unwrap exactly one layer only when the decoded value is a
|
|
46
|
+
// string containing one object/array-shaped payload. No brace searching.
|
|
47
|
+
try {
|
|
48
|
+
const once = JSON.parse(text);
|
|
49
|
+
if (typeof once === "string") {
|
|
50
|
+
const candidate = once.trim();
|
|
51
|
+
// Shape alone is not enough: `"{not json}"` is content, not an
|
|
52
|
+
// unambiguous transport wrapper. Verify the decoded layer is itself a
|
|
53
|
+
// complete JSON object or array before removing the one string layer.
|
|
54
|
+
let decoded;
|
|
55
|
+
try {
|
|
56
|
+
decoded = JSON.parse(candidate);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
decoded = null;
|
|
60
|
+
}
|
|
61
|
+
if (decoded !== null && typeof decoded === "object") {
|
|
62
|
+
text = candidate;
|
|
63
|
+
changes.push("json-string");
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// The phase parser owns the useful error; normalization never guesses.
|
|
69
|
+
}
|
|
70
|
+
return { text, changed: changes.length > 0, changes };
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Keep the exact emitted payload unless it contains a high-confidence secret
|
|
74
|
+
* shape, in which case the same line-redaction discipline as terminal diffs
|
|
75
|
+
* keeps the audit record useful without creating a second credential copy.
|
|
76
|
+
*/
|
|
77
|
+
export function storeStructuredAttempt(store, root, logicalRunId, args) {
|
|
78
|
+
const rawBytes = Buffer.isBuffer(args.raw) ? args.raw : Buffer.from(args.raw, "utf8");
|
|
79
|
+
const rawText = rawBytes.toString("utf8");
|
|
80
|
+
const hits = scanForSecrets(rawText);
|
|
81
|
+
const content = hits.length === 0 ? rawBytes : Buffer.from(redactSecretLines(rawText, hits), "utf8");
|
|
82
|
+
// `accepted: false` can mean strict validation, provider status, session
|
|
83
|
+
// identity, or another provenance gate rejected the bytes. Keep the
|
|
84
|
+
// evidence wording honest without pretending every refusal was a parser
|
|
85
|
+
// error; the run's typed reason records which gate failed.
|
|
86
|
+
// Do not call a pre-finalization candidate simply "accepted": this
|
|
87
|
+
// artifact must remain truthful if a later custody/binding transaction
|
|
88
|
+
// refuses it. Parser acceptance and final workflow acceptance are separate
|
|
89
|
+
// facts; the latter lives on the terminal run.
|
|
90
|
+
const normalization = args.normalized ? ", syntax normalized" : "";
|
|
91
|
+
const state = args.accepted
|
|
92
|
+
? `parser accepted${normalization}; workflow pending`
|
|
93
|
+
: `not accepted${normalization}`;
|
|
94
|
+
return storeEvidence(store, root, logicalRunId, "structured-output", `${args.phase}-response-${args.attempt}.txt`, content, `${args.phase} response ${args.attempt} from run ${args.authoredRunId} (${state})`, args.now, {
|
|
95
|
+
redacted: hits.length > 0,
|
|
96
|
+
captureStatus: args.accepted ? "ok" : "failed",
|
|
97
|
+
sourceBytesOriginal: args.sourceBytesOriginal ?? rawBytes.length,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
/** JSON-quote parser errors so agent-authored ids/paths remain data. */
|
|
101
|
+
export function validationErrorsJson(problems) {
|
|
102
|
+
return JSON.stringify(problems.map(problem => ({ reason: problem.reason, ...(problem.message === undefined ? {} : { message: problem.message }) })), null, 2);
|
|
103
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
/** Only application-owned CSS belongs here. Never pass rendered HTML or
|
|
3
|
+
* session data: this asset is public, immutable and compressed. */
|
|
4
|
+
export declare function styleAsset(css: string): {
|
|
5
|
+
path: string;
|
|
6
|
+
serve(request: IncomingMessage, response: ServerResponse): void;
|
|
7
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { gzipSync } from "node:zlib";
|
|
3
|
+
/** Only application-owned CSS belongs here. Never pass rendered HTML or
|
|
4
|
+
* session data: this asset is public, immutable and compressed. */
|
|
5
|
+
export function styleAsset(css) {
|
|
6
|
+
const body = Buffer.from(css);
|
|
7
|
+
const digest = createHash("sha256").update(body).digest("hex");
|
|
8
|
+
const path = `/assets/workspace-${digest}.css`;
|
|
9
|
+
const zipped = gzipSync(body);
|
|
10
|
+
return {
|
|
11
|
+
path,
|
|
12
|
+
serve(request, response) {
|
|
13
|
+
const encodings = (request.headers["accept-encoding"] ?? "").split(",").map(value => {
|
|
14
|
+
const [name, ...params] = value.trim().toLowerCase().split(";");
|
|
15
|
+
const quality = params.find(p => p.trim().startsWith("q="));
|
|
16
|
+
return { name, q: quality === undefined ? 1 : Number(quality.trim().slice(2)) };
|
|
17
|
+
});
|
|
18
|
+
const gzip = encodings.find(e => e.name === "gzip") ?? encodings.find(e => e.name === "*");
|
|
19
|
+
const compressed = gzip !== undefined && gzip.q > 0 && gzip.q <= 1;
|
|
20
|
+
const bytes = compressed ? zipped : body;
|
|
21
|
+
const etag = `"${digest}${compressed ? "-gzip" : ""}"`;
|
|
22
|
+
const headers = {
|
|
23
|
+
"Content-Type": "text/css; charset=utf-8",
|
|
24
|
+
"Cache-Control": "public, max-age=31536000, immutable",
|
|
25
|
+
"Content-Security-Policy": "default-src 'none'",
|
|
26
|
+
"X-Content-Type-Options": "nosniff",
|
|
27
|
+
"Vary": "Accept-Encoding",
|
|
28
|
+
"ETag": etag,
|
|
29
|
+
...(compressed ? { "Content-Encoding": "gzip" } : {}),
|
|
30
|
+
};
|
|
31
|
+
const matches = (request.headers["if-none-match"] ?? "").split(",").some(value => value.trim().replace(/^W\//, "") === etag || value.trim() === "*");
|
|
32
|
+
if (matches) {
|
|
33
|
+
response.writeHead(304, headers);
|
|
34
|
+
response.end();
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
response.writeHead(200, { ...headers, "Content-Length": bytes.length });
|
|
38
|
+
response.end(request.method === "HEAD" ? undefined : bytes);
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type MateHistoryMessage, type MateProviderAnswer, type MateToolSchema } from "./converse.js";
|
|
2
|
+
import { run, type ExecResult } from "./exec.js";
|
|
3
|
+
import type { SubscriptionChatProviderId } from "./store.js";
|
|
4
|
+
export type SubscriptionMateRequest = {
|
|
5
|
+
provider: SubscriptionChatProviderId;
|
|
6
|
+
/** `default` lets the authenticated harness choose its current default. */
|
|
7
|
+
model: string;
|
|
8
|
+
system: string;
|
|
9
|
+
dataDocument: string;
|
|
10
|
+
history: readonly MateHistoryMessage[];
|
|
11
|
+
tools: readonly MateToolSchema[];
|
|
12
|
+
timeoutMs: number;
|
|
13
|
+
/** The reply as it is written, cumulative, when the harness can stream it
|
|
14
|
+
* (Claude). Display only: the finished answer is still parsed whole. */
|
|
15
|
+
onText?: (text: string) => void;
|
|
16
|
+
};
|
|
17
|
+
export type SubscriptionMateRunner = (request: SubscriptionMateRequest) => Promise<{
|
|
18
|
+
ok: true;
|
|
19
|
+
answer: MateProviderAnswer;
|
|
20
|
+
} | {
|
|
21
|
+
ok: false;
|
|
22
|
+
problem: string;
|
|
23
|
+
}>;
|
|
24
|
+
type CommandRunner = (file: string, args: readonly string[], options: Parameters<typeof run>[2]) => Promise<ExecResult>;
|
|
25
|
+
/** The model-visible request. Tool results are already redacted by mateView. */
|
|
26
|
+
export declare function composeSubscriptionMatePrompt(request: Omit<SubscriptionMateRequest, "provider" | "model" | "timeoutMs">): string;
|
|
27
|
+
/** Strictly turn the harness's structured output into the provider-neutral answer. */
|
|
28
|
+
export declare function parseSubscriptionMateAnswer(text: string, usage?: {
|
|
29
|
+
tokensIn?: unknown;
|
|
30
|
+
tokensOut?: unknown;
|
|
31
|
+
}): {
|
|
32
|
+
ok: true;
|
|
33
|
+
answer: MateProviderAnswer;
|
|
34
|
+
} | {
|
|
35
|
+
ok: false;
|
|
36
|
+
problem: string;
|
|
37
|
+
};
|
|
38
|
+
/** Production runner; injectable so tests never consume a subscription turn. */
|
|
39
|
+
export declare function performSubscriptionMateRequest(request: SubscriptionMateRequest, runner?: CommandRunner): Promise<{
|
|
40
|
+
ok: true;
|
|
41
|
+
answer: MateProviderAnswer;
|
|
42
|
+
} | {
|
|
43
|
+
ok: false;
|
|
44
|
+
problem: string;
|
|
45
|
+
}>;
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subscription-backed transport for the mate.
|
|
3
|
+
*
|
|
4
|
+
* The direct API transport owns dollar reservations and native function
|
|
5
|
+
* calls. A cached Codex or Claude login has neither an API key nor a
|
|
6
|
+
* truthful dollar meter, so this adapter runs the local harness in a clean
|
|
7
|
+
* temporary directory and asks for the same tool-call envelope as strict
|
|
8
|
+
* structured JSON. The harness receives no repository path, no project
|
|
9
|
+
* instructions, no MCP servers, and no executable tool surface. Tool calls
|
|
10
|
+
* are still interpreted and executed by mate.ts, where every act remains a
|
|
11
|
+
* proposal that needs a human confirmation card.
|
|
12
|
+
*/
|
|
13
|
+
import { Buffer } from "node:buffer";
|
|
14
|
+
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
15
|
+
import { tmpdir } from "node:os";
|
|
16
|
+
import { join } from "node:path";
|
|
17
|
+
import { MATE_MAX_CALLS_PER_STEP, MATE_STEP_TEXT_CAP_BYTES, MATE_TOOL_CALL_CAP_BYTES, MATE_TOOL_CALL_ID_CAP_BYTES, strictJsonParse, tokenCount, } from "./converse.js";
|
|
18
|
+
import { run } from "./exec.js";
|
|
19
|
+
import { claudeStreamReader } from "./mate-progress.js";
|
|
20
|
+
import { ALL_CREDENTIAL_ENV } from "./provider.js";
|
|
21
|
+
import { claudeLimitsOf, noteLimits } from "./provider-limits.js";
|
|
22
|
+
import { claudeBillingFrom } from "./spend.js";
|
|
23
|
+
const RESPONSE_CAP_BYTES = 65_536;
|
|
24
|
+
function outputSchema(tools) {
|
|
25
|
+
return {
|
|
26
|
+
type: "object",
|
|
27
|
+
properties: {
|
|
28
|
+
text: { type: "string", maxLength: MATE_STEP_TEXT_CAP_BYTES },
|
|
29
|
+
// With no tools offered there is nothing to name: an empty enum is not
|
|
30
|
+
// a valid schema, so the calls array is simply required to be empty.
|
|
31
|
+
calls: tools.length === 0 ? { type: "array", maxItems: 0 } : {
|
|
32
|
+
type: "array",
|
|
33
|
+
maxItems: MATE_MAX_CALLS_PER_STEP,
|
|
34
|
+
items: {
|
|
35
|
+
type: "object",
|
|
36
|
+
properties: {
|
|
37
|
+
id: { type: "string", minLength: 1, maxLength: MATE_TOOL_CALL_ID_CAP_BYTES },
|
|
38
|
+
name: { type: "string", enum: tools.map(tool => tool.name) },
|
|
39
|
+
argumentsJson: { type: "string", maxLength: MATE_TOOL_CALL_CAP_BYTES },
|
|
40
|
+
},
|
|
41
|
+
required: ["id", "name", "argumentsJson"],
|
|
42
|
+
additionalProperties: false,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
required: ["text", "calls"],
|
|
47
|
+
additionalProperties: false,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/** The model-visible request. Tool results are already redacted by mateView. */
|
|
51
|
+
export function composeSubscriptionMatePrompt(request) {
|
|
52
|
+
return [
|
|
53
|
+
request.system,
|
|
54
|
+
"SUBSCRIPTION HARNESS PROTOCOL:",
|
|
55
|
+
"Do not use any harness tools or inspect the computer. The only current state is DATA and TOOL RESULTS below.",
|
|
56
|
+
"Return the required JSON object. To request a host tool, append {id, name, argumentsJson} to calls; argumentsJson is the JSON serialization of that tool's argument object.",
|
|
57
|
+
"The host validates and runs those calls, then gives you another step. When finished, return a non-empty text and an empty calls array.",
|
|
58
|
+
`AVAILABLE HOST TOOLS:\n${JSON.stringify(request.tools)}`,
|
|
59
|
+
`DATA:\n${request.dataDocument}`,
|
|
60
|
+
`CONVERSATION:\n${JSON.stringify(request.history)}`,
|
|
61
|
+
].join("\n\n");
|
|
62
|
+
}
|
|
63
|
+
function exactKeys(value, keys) {
|
|
64
|
+
const actual = Object.keys(value).sort();
|
|
65
|
+
return actual.length === keys.length && [...keys].sort().every((key, index) => actual[index] === key);
|
|
66
|
+
}
|
|
67
|
+
/** Strictly turn the harness's structured output into the provider-neutral answer. */
|
|
68
|
+
export function parseSubscriptionMateAnswer(text, usage = {}) {
|
|
69
|
+
const parsed = strictJsonParse(Buffer.from(text, "utf8"), RESPONSE_CAP_BYTES, 8);
|
|
70
|
+
if (!parsed.ok || typeof parsed.value !== "object" || parsed.value === null || Array.isArray(parsed.value)) {
|
|
71
|
+
return { ok: false, problem: parsed.ok ? "not-an-object" : parsed.problem };
|
|
72
|
+
}
|
|
73
|
+
const body = parsed.value;
|
|
74
|
+
if (!exactKeys(body, ["text", "calls"]) || typeof body["text"] !== "string" || !Array.isArray(body["calls"])) {
|
|
75
|
+
return { ok: false, problem: "wrong-shape" };
|
|
76
|
+
}
|
|
77
|
+
if (Buffer.byteLength(body["text"], "utf8") > MATE_STEP_TEXT_CAP_BYTES || body["calls"].length > MATE_MAX_CALLS_PER_STEP) {
|
|
78
|
+
return { ok: false, problem: "over-cap" };
|
|
79
|
+
}
|
|
80
|
+
const calls = [];
|
|
81
|
+
for (const raw of body["calls"]) {
|
|
82
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw))
|
|
83
|
+
return { ok: false, problem: "bad-tool-call" };
|
|
84
|
+
const call = raw;
|
|
85
|
+
if (!exactKeys(call, ["id", "name", "argumentsJson"]))
|
|
86
|
+
return { ok: false, problem: "bad-tool-call" };
|
|
87
|
+
if (typeof call["id"] !== "string" || call["id"] === "" || Buffer.byteLength(call["id"], "utf8") > MATE_TOOL_CALL_ID_CAP_BYTES) {
|
|
88
|
+
return { ok: false, problem: "bad-tool-call" };
|
|
89
|
+
}
|
|
90
|
+
if (typeof call["name"] !== "string" || call["name"] === "" || call["name"].length > 64 || typeof call["argumentsJson"] !== "string") {
|
|
91
|
+
return { ok: false, problem: "bad-tool-call" };
|
|
92
|
+
}
|
|
93
|
+
const argumentsBytes = Buffer.from(call["argumentsJson"], "utf8");
|
|
94
|
+
if (argumentsBytes.byteLength > MATE_TOOL_CALL_CAP_BYTES)
|
|
95
|
+
return { ok: false, problem: "bad-tool-call" };
|
|
96
|
+
const args = strictJsonParse(argumentsBytes, MATE_TOOL_CALL_CAP_BYTES, 6);
|
|
97
|
+
if (!args.ok || typeof args.value !== "object" || args.value === null || Array.isArray(args.value))
|
|
98
|
+
return { ok: false, problem: "bad-tool-call" };
|
|
99
|
+
const normalized = { id: call["id"], name: call["name"], args: args.value };
|
|
100
|
+
if (Buffer.byteLength(JSON.stringify(normalized), "utf8") > MATE_TOOL_CALL_CAP_BYTES)
|
|
101
|
+
return { ok: false, problem: "bad-tool-call" };
|
|
102
|
+
calls.push(normalized);
|
|
103
|
+
}
|
|
104
|
+
const tokensIn = typeof usage.tokensIn === "number" && tokenCount(usage.tokensIn) ? usage.tokensIn : 0;
|
|
105
|
+
const tokensOut = typeof usage.tokensOut === "number" && tokenCount(usage.tokensOut) ? usage.tokensOut : 0;
|
|
106
|
+
return { ok: true, answer: { text: body["text"], calls, tokensIn, tokensOut, reportedCostMicrousd: null } };
|
|
107
|
+
}
|
|
108
|
+
function codexOutput(stdout) {
|
|
109
|
+
let text = null;
|
|
110
|
+
let tokensIn = 0;
|
|
111
|
+
let tokensOut = 0;
|
|
112
|
+
let completed = 0;
|
|
113
|
+
let invalid = false;
|
|
114
|
+
for (const line of stdout.split("\n")) {
|
|
115
|
+
if (line.trim() === "")
|
|
116
|
+
continue;
|
|
117
|
+
let event;
|
|
118
|
+
try {
|
|
119
|
+
event = JSON.parse(line);
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
invalid = true;
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (event === null || typeof event !== "object" || Array.isArray(event)) {
|
|
126
|
+
invalid = true;
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (event["type"] === "turn.failed")
|
|
130
|
+
invalid = true;
|
|
131
|
+
if (event["type"] === "item.completed") {
|
|
132
|
+
const item = event["item"];
|
|
133
|
+
if (item?.["type"] === "agent_message" && typeof item["text"] === "string") {
|
|
134
|
+
if (completed !== 0)
|
|
135
|
+
invalid = true;
|
|
136
|
+
text = item["text"];
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else if (event["type"] === "turn.completed") {
|
|
140
|
+
completed += 1;
|
|
141
|
+
const usage = event["usage"];
|
|
142
|
+
if (typeof usage?.["input_tokens"] === "number" && tokenCount(usage["input_tokens"]))
|
|
143
|
+
tokensIn = usage["input_tokens"];
|
|
144
|
+
if (typeof usage?.["output_tokens"] === "number" && tokenCount(usage["output_tokens"]))
|
|
145
|
+
tokensOut = usage["output_tokens"];
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// A partial answer is not authority to run host tools. Process exit zero
|
|
149
|
+
// alone is insufficient; the harness must finish this one turn successfully.
|
|
150
|
+
return { text: !invalid && completed === 1 ? text : null, tokensIn, tokensOut };
|
|
151
|
+
}
|
|
152
|
+
function claudeOutput(stdout) {
|
|
153
|
+
const parsed = strictJsonParse(Buffer.from(stdout, "utf8"), RESPONSE_CAP_BYTES, 12);
|
|
154
|
+
if (!parsed.ok || typeof parsed.value !== "object" || parsed.value === null || Array.isArray(parsed.value))
|
|
155
|
+
return { text: null, tokensIn: 0, tokensOut: 0 };
|
|
156
|
+
const body = parsed.value;
|
|
157
|
+
if (body["type"] !== "result" || body["subtype"] !== "success" || body["is_error"] !== false) {
|
|
158
|
+
return { text: null, tokensIn: 0, tokensOut: 0 };
|
|
159
|
+
}
|
|
160
|
+
const usage = body["usage"];
|
|
161
|
+
const tokensIn = typeof usage?.["input_tokens"] === "number" && tokenCount(usage["input_tokens"]) ? usage["input_tokens"] : 0;
|
|
162
|
+
const tokensOut = typeof usage?.["output_tokens"] === "number" && tokenCount(usage["output_tokens"]) ? usage["output_tokens"] : 0;
|
|
163
|
+
const structured = body["structured_output"];
|
|
164
|
+
if (typeof structured === "object" && structured !== null)
|
|
165
|
+
return { text: JSON.stringify(structured), tokensIn, tokensOut };
|
|
166
|
+
return { text: typeof body["result"] === "string" ? body["result"] : null, tokensIn, tokensOut };
|
|
167
|
+
}
|
|
168
|
+
/** The streamed run's closing `result` event: the same body the buffered
|
|
169
|
+
* `--output-format json` run prints. */
|
|
170
|
+
function lastResultLine(stdout) {
|
|
171
|
+
const lines = stdout.split("\n");
|
|
172
|
+
for (let index = lines.length - 1; index >= 0; index--) {
|
|
173
|
+
const line = lines[index].trim();
|
|
174
|
+
if (line === "")
|
|
175
|
+
continue;
|
|
176
|
+
try {
|
|
177
|
+
const event = JSON.parse(line);
|
|
178
|
+
if (typeof event === "object" && event !== null && event["type"] === "result")
|
|
179
|
+
return line;
|
|
180
|
+
}
|
|
181
|
+
catch { /* not an event line */ }
|
|
182
|
+
}
|
|
183
|
+
return "";
|
|
184
|
+
}
|
|
185
|
+
/** Production runner; injectable so tests never consume a subscription turn. */
|
|
186
|
+
export async function performSubscriptionMateRequest(request, runner = run) {
|
|
187
|
+
const dir = mkdtempSync(join(tmpdir(), "standing-orders-mate-"));
|
|
188
|
+
try {
|
|
189
|
+
const prompt = composeSubscriptionMatePrompt(request);
|
|
190
|
+
const streaming = request.provider !== "codex-subscription" && request.onText !== undefined;
|
|
191
|
+
const schema = outputSchema(request.tools);
|
|
192
|
+
let command;
|
|
193
|
+
let args;
|
|
194
|
+
if (request.provider === "codex-subscription") {
|
|
195
|
+
const schemaFile = join(dir, "response-schema.json");
|
|
196
|
+
writeFileSync(schemaFile, JSON.stringify(schema), { mode: 0o600 });
|
|
197
|
+
command = "codex";
|
|
198
|
+
args = [
|
|
199
|
+
"exec", "--json", "--ephemeral", "--ignore-user-config", "--ignore-rules", "--skip-git-repo-check",
|
|
200
|
+
"--sandbox", "read-only", "--output-schema", schemaFile,
|
|
201
|
+
"-c", 'approval_policy="never"', "-c", 'web_search="disabled"',
|
|
202
|
+
"-c", "features.shell_tool=false", "-c", "features.unified_exec=false",
|
|
203
|
+
"-c", "features.multi_agent=false", "-c", "features.skill_mcp_dependency_install=false",
|
|
204
|
+
"-c", "apps._default.enabled=false",
|
|
205
|
+
...(request.model === "default" ? [] : ["--model", request.model]),
|
|
206
|
+
"-",
|
|
207
|
+
];
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
command = "claude";
|
|
211
|
+
args = [
|
|
212
|
+
// Streaming (someone is watching): the same answer, delivered as
|
|
213
|
+
// events whose final `result` line is the whole structured reply.
|
|
214
|
+
"-p", ...(streaming ? ["--output-format", "stream-json", "--verbose", "--include-partial-messages"] : ["--output-format", "json"]), "--json-schema", JSON.stringify(schema),
|
|
215
|
+
"--safe-mode", "--no-session-persistence", "--tools", "", "--permission-mode", "dontAsk",
|
|
216
|
+
"--permission-prompts", "none", "--strict-mcp-config", "--mcp-config", '{"mcpServers":{}}',
|
|
217
|
+
...(request.model === "default" ? [] : ["--model", request.model]),
|
|
218
|
+
];
|
|
219
|
+
}
|
|
220
|
+
const result = await runner(command, args, {
|
|
221
|
+
cwd: dir,
|
|
222
|
+
stdin: prompt,
|
|
223
|
+
timeoutMs: request.timeoutMs,
|
|
224
|
+
// Events repeat the answer (deltas, the message, the result line).
|
|
225
|
+
maxBuffer: streaming ? RESPONSE_CAP_BYTES * 16 : RESPONSE_CAP_BYTES,
|
|
226
|
+
omitEnv: ALL_CREDENTIAL_ENV,
|
|
227
|
+
processGroup: true,
|
|
228
|
+
...(streaming ? { onStdout: claudeStreamReader(request.onText) } : {}),
|
|
229
|
+
});
|
|
230
|
+
if (result.timedOut)
|
|
231
|
+
return { ok: false, problem: "timeout" };
|
|
232
|
+
if (result.notFound)
|
|
233
|
+
return { ok: false, problem: "not-found" };
|
|
234
|
+
// v105: a streamed Claude turn says its plan's usage windows, and (once it answered) how this computer's Claude bills
|
|
235
|
+
// with no key from us: the chat ran with every key left out.
|
|
236
|
+
if (command === "claude" && streaming) {
|
|
237
|
+
const seen = { keySource: null, model: null, planWindows: false };
|
|
238
|
+
let answered = false;
|
|
239
|
+
for (const line of result.stdout.split("\n")) {
|
|
240
|
+
if (!line.includes('"rate_limit_event"') && !line.includes('"apiKeySource"') && !line.includes('"type":"result"'))
|
|
241
|
+
continue;
|
|
242
|
+
let event;
|
|
243
|
+
try {
|
|
244
|
+
event = JSON.parse(line);
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
const reading = claudeLimitsOf(event);
|
|
250
|
+
if (reading !== null) {
|
|
251
|
+
seen.planWindows = true;
|
|
252
|
+
noteLimits(reading);
|
|
253
|
+
}
|
|
254
|
+
else if (event["type"] === "system" && event["subtype"] === "init") {
|
|
255
|
+
seen.keySource = typeof event["apiKeySource"] === "string" ? event["apiKeySource"] : null;
|
|
256
|
+
seen.model = typeof event["model"] === "string" ? event["model"] : null;
|
|
257
|
+
}
|
|
258
|
+
else if (event["type"] === "result")
|
|
259
|
+
answered = true;
|
|
260
|
+
}
|
|
261
|
+
const billing = answered ? claudeBillingFrom(seen) : null;
|
|
262
|
+
if (billing !== null)
|
|
263
|
+
noteLimits({ provider: "claude", plan: null, windows: [], partial: true, billing });
|
|
264
|
+
}
|
|
265
|
+
if (result.code !== 0)
|
|
266
|
+
return { ok: false, problem: `status-${result.code}` };
|
|
267
|
+
const output = request.provider === "codex-subscription" ? codexOutput(result.stdout) : claudeOutput(streaming ? lastResultLine(result.stdout) : result.stdout);
|
|
268
|
+
if (output.text === null)
|
|
269
|
+
return { ok: false, problem: "malformed-reply" };
|
|
270
|
+
return parseSubscriptionMateAnswer(output.text, output);
|
|
271
|
+
}
|
|
272
|
+
finally {
|
|
273
|
+
rmSync(dir, { recursive: true, force: true });
|
|
274
|
+
}
|
|
275
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A window of runs, tallied — one arithmetic, shared by the CLI brief and
|
|
3
|
+
* the web console so the two can never disagree about what a stretch of
|
|
4
|
+
* unattended work cost.
|
|
5
|
+
*
|
|
6
|
+
* Economics are measured, never asserted: every provider spawn stamps its
|
|
7
|
+
* run before spending, so `invoked` is the complete population; `measured`
|
|
8
|
+
* is the subset whose envelopes actually reported cost, and the gap between
|
|
9
|
+
* them is named by callers instead of summed as zero.
|
|
10
|
+
*/
|
|
11
|
+
import type { Run } from "./store.js";
|
|
12
|
+
export type RunTally<T extends Run> = {
|
|
13
|
+
built: T[];
|
|
14
|
+
failed: T[];
|
|
15
|
+
refused: T[];
|
|
16
|
+
/** Runs that never finished — the process died with them. Also an answer. */
|
|
17
|
+
cutDown: T[];
|
|
18
|
+
invoked: T[];
|
|
19
|
+
measured: T[];
|
|
20
|
+
spend: number;
|
|
21
|
+
tokens: number;
|
|
22
|
+
};
|
|
23
|
+
export declare function tally<T extends Run>(runs: T[]): RunTally<T>;
|
|
24
|
+
/**
|
|
25
|
+
* Provider harnesses do not all mean the same thing when they report a
|
|
26
|
+
* dollar figure. Claude Code includes `total_cost_usd` in its result even
|
|
27
|
+
* when it authenticated with a paid membership. In that case the number is
|
|
28
|
+
* useful as an API-price equivalent for comparing work, but it is not API
|
|
29
|
+
* key spend and must never be presented as a separate charge.
|
|
30
|
+
*/
|
|
31
|
+
export declare function runCostWords(run: Pick<Run, "authMode" | "costUsd" | "tokensIn" | "tokensOut">, live?: boolean): string;
|
|
32
|
+
/** The spend line, one wording everywhere. */
|
|
33
|
+
export declare function spendLine(summary: RunTally<Run>): string;
|
package/dist/summary.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A window of runs, tallied — one arithmetic, shared by the CLI brief and
|
|
3
|
+
* the web console so the two can never disagree about what a stretch of
|
|
4
|
+
* unattended work cost.
|
|
5
|
+
*
|
|
6
|
+
* Economics are measured, never asserted: every provider spawn stamps its
|
|
7
|
+
* run before spending, so `invoked` is the complete population; `measured`
|
|
8
|
+
* is the subset whose envelopes actually reported cost, and the gap between
|
|
9
|
+
* them is named by callers instead of summed as zero.
|
|
10
|
+
*/
|
|
11
|
+
export function tally(runs) {
|
|
12
|
+
const invoked = runs.filter(one => one.providerStartedAt !== null);
|
|
13
|
+
const measured = invoked.filter(one => one.costUsd !== null);
|
|
14
|
+
return {
|
|
15
|
+
built: runs.filter(one => one.outcome === "built" || one.outcome === "no-change"),
|
|
16
|
+
failed: runs.filter(one => one.outcome === "failed"),
|
|
17
|
+
refused: runs.filter(one => one.outcome === "refused"),
|
|
18
|
+
cutDown: runs.filter(one => one.outcome === null),
|
|
19
|
+
invoked,
|
|
20
|
+
measured,
|
|
21
|
+
spend: measured.reduce((sum, one) => sum + (one.costUsd ?? 0), 0),
|
|
22
|
+
tokens: invoked
|
|
23
|
+
.filter(one => one.tokensOut !== null)
|
|
24
|
+
.reduce((sum, one) => sum + (one.tokensOut ?? 0) + (one.tokensIn ?? 0), 0),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Provider harnesses do not all mean the same thing when they report a
|
|
29
|
+
* dollar figure. Claude Code includes `total_cost_usd` in its result even
|
|
30
|
+
* when it authenticated with a paid membership. In that case the number is
|
|
31
|
+
* useful as an API-price equivalent for comparing work, but it is not API
|
|
32
|
+
* key spend and must never be presented as a separate charge.
|
|
33
|
+
*/
|
|
34
|
+
export function runCostWords(run, live = false) {
|
|
35
|
+
if (run.authMode === "subscription") {
|
|
36
|
+
return run.costUsd === null
|
|
37
|
+
? live
|
|
38
|
+
? "subscription usage in progress"
|
|
39
|
+
: "subscription · no API-key spend"
|
|
40
|
+
: `subscription · $${run.costUsd.toFixed(2)} API-price equivalent (not an API charge)`;
|
|
41
|
+
}
|
|
42
|
+
if (run.costUsd !== null) {
|
|
43
|
+
return run.authMode === "api-key" ? `$${run.costUsd.toFixed(2)} API-key usage` : `$${run.costUsd.toFixed(2)}`;
|
|
44
|
+
}
|
|
45
|
+
return run.tokensIn !== null || run.tokensOut !== null
|
|
46
|
+
? "dollar cost unmeasured — this provider reports tokens, not prices"
|
|
47
|
+
: live
|
|
48
|
+
? "usage in progress"
|
|
49
|
+
: "unmeasured";
|
|
50
|
+
}
|
|
51
|
+
/** The spend line, one wording everywhere. */
|
|
52
|
+
export function spendLine(summary) {
|
|
53
|
+
if (summary.invoked.length === 0)
|
|
54
|
+
return "nothing — no provider was invoked";
|
|
55
|
+
const subscription = summary.measured.filter(one => one.authMode === "subscription");
|
|
56
|
+
const metered = summary.measured.filter(one => one.authMode !== "subscription");
|
|
57
|
+
const subscriptionEquivalent = subscription.reduce((sum, one) => sum + (one.costUsd ?? 0), 0);
|
|
58
|
+
const meteredSpend = metered.reduce((sum, one) => sum + (one.costUsd ?? 0), 0);
|
|
59
|
+
if (subscription.length > 0) {
|
|
60
|
+
const money = [
|
|
61
|
+
...(metered.length > 0 ? [`$${meteredSpend.toFixed(4)} API-key usage`] : []),
|
|
62
|
+
`$${subscriptionEquivalent.toFixed(4)} API-price equivalent from ${subscription.length} subscription invocation(s) — not an API charge`,
|
|
63
|
+
].join(" · ");
|
|
64
|
+
const unmeasured = summary.invoked.length - summary.measured.length;
|
|
65
|
+
return `${money} · ${summary.tokens.toLocaleString()} tokens${unmeasured === 0 ? "" : ` · ${unmeasured} invocation(s) unmeasured`}`;
|
|
66
|
+
}
|
|
67
|
+
const dollars = `$${summary.spend.toFixed(4)}`;
|
|
68
|
+
return summary.measured.length === summary.invoked.length
|
|
69
|
+
? `${dollars} · ${summary.tokens.toLocaleString()} tokens, measured across all ${summary.invoked.length} invocation(s)`
|
|
70
|
+
: `${dollars} measured across ${summary.measured.length}/${summary.invoked.length} invocation(s) — ${summary.invoked.length - summary.measured.length} unmeasured`;
|
|
71
|
+
}
|