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,454 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase-agent resolution: which provider and model a phase runs on, layer
|
|
3
|
+
* by layer, with the layers written down (Codex provider review, Q8).
|
|
4
|
+
*
|
|
5
|
+
* pinned task agent — stamped by a fire transaction; NOTHING overrides it
|
|
6
|
+
* explicit flags — this pass's operator, per field
|
|
7
|
+
* project override — phase_config row scoped to the canonical repo
|
|
8
|
+
* installation — phase_config row scoped 'installation'
|
|
9
|
+
* review inheritance — when review is unset, the planner's complete pair
|
|
10
|
+
* default — claude, harness default model
|
|
11
|
+
*
|
|
12
|
+
* Config rows are COMPLETE pairs (provider required, model optional), so a
|
|
13
|
+
* partial override cannot marry a codex model to an inherited claude
|
|
14
|
+
* provider. Flags are per-field with one stated rule: `--model` alone
|
|
15
|
+
* rides whatever provider resolves; `--provider` alone runs that
|
|
16
|
+
* provider's default model — a lower layer's model never crosses onto a
|
|
17
|
+
* flag-chosen provider it was not written for.
|
|
18
|
+
*
|
|
19
|
+
* The resolved pair is validated before anything is claimed or spent, and
|
|
20
|
+
* the caller snapshots it into the run row.
|
|
21
|
+
*/
|
|
22
|
+
import { isProviderId, validateSpec } from "./provider.js";
|
|
23
|
+
import { contestantProfileOf } from "./store.js";
|
|
24
|
+
import { CLAUDE_LIMITS, CODEX_SHAPED_LIMITS, GEMINI_LIMITS, chainFromJson, canonicalChainJson } from "./scope.js";
|
|
25
|
+
import { SUBSCRIPTION_CAPABLE } from "./keys.js";
|
|
26
|
+
import { exactModelId, legOf, PHASES, recommendRoute, routeFromJson, routeProblems, sameSpec } from "./phase-routing.js";
|
|
27
|
+
export const INSTALLATION_SCOPE = "installation";
|
|
28
|
+
/**
|
|
29
|
+
* Fail-closed (not a fallback to claude — a refusal): gemini's own
|
|
30
|
+
* `.gemini/` config loads hooks and MCP servers unconditionally
|
|
31
|
+
* (provider.ts's geminiArgv), a leak claude and codex both now close for
|
|
32
|
+
* review with a dedicated isolation argv. Until gemini earns the same, it
|
|
33
|
+
* is not eligible to run the reviewer phase at all — however it got
|
|
34
|
+
* resolved: pinned, flagged, or configured.
|
|
35
|
+
*/
|
|
36
|
+
function reviewEligible(phase, spec) {
|
|
37
|
+
return phase === "review" && spec.provider === "gemini"
|
|
38
|
+
? "gemini has no isolation posture for the review phase yet (its own config can load hooks and MCP servers) — pin review to claude or codex"
|
|
39
|
+
: null;
|
|
40
|
+
}
|
|
41
|
+
export function resolvePhaseAgent(store, phase, repo, flags,
|
|
42
|
+
/** The task being dispatched, when one is — its pin is authoritative. */
|
|
43
|
+
ref) {
|
|
44
|
+
// The pin: a firing resolved under approved terms must not be re-routed
|
|
45
|
+
// by anything later, flags included (Codex provider review, critical 1).
|
|
46
|
+
if (ref !== undefined && ref.agentProvider !== null) {
|
|
47
|
+
if (!isProviderId(ref.agentProvider)) {
|
|
48
|
+
return { ok: false, problem: `the task is pinned to unknown provider \`${ref.agentProvider}\`` };
|
|
49
|
+
}
|
|
50
|
+
const spec = { provider: ref.agentProvider, model: ref.agentModel };
|
|
51
|
+
const ineligible = reviewEligible(phase, spec);
|
|
52
|
+
if (ineligible !== null)
|
|
53
|
+
return { ok: false, problem: ineligible };
|
|
54
|
+
const valid = validateSpec(spec);
|
|
55
|
+
return valid.ok ? { ok: true, spec, source: "pinned" } : { ok: false, problem: valid.problem };
|
|
56
|
+
}
|
|
57
|
+
if (flags.provider !== undefined) {
|
|
58
|
+
if (!isProviderId(flags.provider)) {
|
|
59
|
+
return { ok: false, problem: `unknown provider \`${flags.provider}\`` };
|
|
60
|
+
}
|
|
61
|
+
const spec = { provider: flags.provider, model: flags.model ?? null };
|
|
62
|
+
const ineligible = reviewEligible(phase, spec);
|
|
63
|
+
if (ineligible !== null)
|
|
64
|
+
return { ok: false, problem: ineligible };
|
|
65
|
+
const valid = validateSpec(spec);
|
|
66
|
+
return valid.ok ? { ok: true, spec, source: "flag" } : { ok: false, problem: valid.problem };
|
|
67
|
+
}
|
|
68
|
+
const directProject = repo === null ? null : store.phaseConfig(repo, phase);
|
|
69
|
+
const directInstallation = store.phaseConfig(INSTALLATION_SCOPE, phase);
|
|
70
|
+
// Planning and review benefit from the same high-judgment model, while
|
|
71
|
+
// execution can use a different provider. An explicit review row always
|
|
72
|
+
// wins; only an unset review inherits the planner's complete pair.
|
|
73
|
+
const inheritedProject = phase === "review" && directProject === null && directInstallation === null && repo !== null
|
|
74
|
+
? store.phaseConfig(repo, "plan")
|
|
75
|
+
: null;
|
|
76
|
+
const inheritedInstallation = phase === "review" && directProject === null && directInstallation === null
|
|
77
|
+
? store.phaseConfig(INSTALLATION_SCOPE, "plan")
|
|
78
|
+
: null;
|
|
79
|
+
const project = directProject ?? inheritedProject;
|
|
80
|
+
const installation = directInstallation ?? inheritedInstallation;
|
|
81
|
+
const row = project ?? installation;
|
|
82
|
+
const source = project !== null ? "project" : installation !== null ? "installation" : "default";
|
|
83
|
+
// A misconfigured row REFUSES instead of silently rerouting to claude
|
|
84
|
+
// (foundations finding 3c): the operator wrote a provider; running a
|
|
85
|
+
// different one is not a fallback, it is a substitution.
|
|
86
|
+
if (row !== null && !isProviderId(row.provider)) {
|
|
87
|
+
return { ok: false, problem: `the ${source} configuration names unknown provider \`${row.provider}\` — fix it with \`config set\`` };
|
|
88
|
+
}
|
|
89
|
+
const provider = row !== null && isProviderId(row.provider) ? row.provider : "claude";
|
|
90
|
+
// --model alone rides the resolved provider; otherwise the pair comes
|
|
91
|
+
// whole from the row that named the provider.
|
|
92
|
+
const model = flags.model ?? (row !== null ? row.model : null);
|
|
93
|
+
const spec = { provider, model };
|
|
94
|
+
const ineligible = reviewEligible(phase, spec);
|
|
95
|
+
if (ineligible !== null)
|
|
96
|
+
return { ok: false, problem: ineligible };
|
|
97
|
+
const valid = validateSpec(spec);
|
|
98
|
+
return valid.ok ? { ok: true, spec, source: flags.model !== undefined ? "flag" : source } : { ok: false, problem: valid.problem };
|
|
99
|
+
}
|
|
100
|
+
export function resolveScopeProfile(store, repo, ref, flags) {
|
|
101
|
+
const build = resolvePhaseAgent(store, "build", repo, flags, ref);
|
|
102
|
+
if (!build.ok)
|
|
103
|
+
return { ok: false, reason: "unknown-provider", problem: build.problem };
|
|
104
|
+
const { provider, model } = build.spec;
|
|
105
|
+
if (model === null || model === "") {
|
|
106
|
+
return {
|
|
107
|
+
ok: false,
|
|
108
|
+
reason: "no-model",
|
|
109
|
+
problem: "approvals bind exact routing — name --model on the scope, or set a default once with `config set build --provider " +
|
|
110
|
+
provider +
|
|
111
|
+
" --model <model>`",
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
let repairModel = "inherit";
|
|
115
|
+
let repairFrom = "inherit";
|
|
116
|
+
if (flags.repairModel !== undefined && flags.repairModel !== "") {
|
|
117
|
+
repairModel = flags.repairModel;
|
|
118
|
+
repairFrom = "flag";
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
const repairRow = (repo === null ? null : store.phaseConfig(repo, "repair")) ?? store.phaseConfig(INSTALLATION_SCOPE, "repair");
|
|
122
|
+
if (repairRow !== null) {
|
|
123
|
+
if (repairRow.provider !== provider) {
|
|
124
|
+
return {
|
|
125
|
+
ok: false,
|
|
126
|
+
reason: "repair-provider-mismatch",
|
|
127
|
+
problem: `the repair configuration names provider \`${repairRow.provider}\` but the build runs \`${provider}\` — cross-provider repair does not exist; fix the repair row or name --repair-model`,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
if (repairRow.model !== null && repairRow.model !== "") {
|
|
131
|
+
repairModel = repairRow.model;
|
|
132
|
+
repairFrom = "config";
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const permissionMode = flags.permissionMode ?? store.permissionDefault().mode;
|
|
137
|
+
const profile = provider === "claude"
|
|
138
|
+
? {
|
|
139
|
+
provider,
|
|
140
|
+
model,
|
|
141
|
+
// Auto mode is designed for headless work: routine repository
|
|
142
|
+
// commands and edits proceed, while risky acts still stop at the
|
|
143
|
+
// provider's permission classifier. Full access is an explicit
|
|
144
|
+
// installation or task choice and is sealed into this profile.
|
|
145
|
+
permissionArgv: permissionMode,
|
|
146
|
+
maxTurns: CLAUDE_LIMITS.maxTurns,
|
|
147
|
+
repairMaxTurns: CLAUDE_LIMITS.repairMaxTurns,
|
|
148
|
+
timeoutSeconds: CLAUDE_LIMITS.timeoutSeconds,
|
|
149
|
+
timeoutKind: "idle",
|
|
150
|
+
repairTimeoutSeconds: CLAUDE_LIMITS.repairTimeoutSeconds,
|
|
151
|
+
repairModel,
|
|
152
|
+
}
|
|
153
|
+
: provider === "gemini"
|
|
154
|
+
? {
|
|
155
|
+
provider,
|
|
156
|
+
model,
|
|
157
|
+
// The cross-provider choice resolves to Gemini's own real argv:
|
|
158
|
+
// auto_edit for Auto, yolo for Full access.
|
|
159
|
+
approvalArgv: permissionMode === "bypassPermissions" ? "yolo" : "auto_edit",
|
|
160
|
+
maxTurns: "unsupported",
|
|
161
|
+
repairMaxTurns: "unsupported",
|
|
162
|
+
timeoutSeconds: GEMINI_LIMITS.timeoutSeconds,
|
|
163
|
+
timeoutKind: "idle",
|
|
164
|
+
repairTimeoutSeconds: GEMINI_LIMITS.repairTimeoutSeconds,
|
|
165
|
+
repairModel,
|
|
166
|
+
}
|
|
167
|
+
: {
|
|
168
|
+
provider,
|
|
169
|
+
model,
|
|
170
|
+
sandboxMode: permissionMode === "bypassPermissions" ? "danger-full-access" : "workspace-write",
|
|
171
|
+
maxTurns: "unsupported",
|
|
172
|
+
repairMaxTurns: "unsupported",
|
|
173
|
+
timeoutSeconds: CODEX_SHAPED_LIMITS.timeoutSeconds,
|
|
174
|
+
timeoutKind: "idle",
|
|
175
|
+
repairTimeoutSeconds: CODEX_SHAPED_LIMITS.repairTimeoutSeconds,
|
|
176
|
+
repairModel,
|
|
177
|
+
};
|
|
178
|
+
return { ok: true, profile, provenance: { resolvedFrom: build.source, repairFrom } };
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Resolve the full EXECUTION CHAIN a scope files under (v30): the base
|
|
182
|
+
* (entry 0) is the ordinary single-profile resolution wearing the base
|
|
183
|
+
* provider's auth mode; the fallbacks are the scope's configured entries,
|
|
184
|
+
* each resolved to a WHOLE ExecutionProfile (repair per entry). With no
|
|
185
|
+
* fallbacks configured, the result is `kind: "profile"` — a single-profile
|
|
186
|
+
* approval, byte-identical to today (NOT an explicit chain). With
|
|
187
|
+
* fallbacks, it is `kind: "chain"` and the approval binds the whole thing.
|
|
188
|
+
* The base auth mode is passed in (the caller reads it from the managed
|
|
189
|
+
* key store) so resolution stays pure and testable.
|
|
190
|
+
*/
|
|
191
|
+
export function resolveScopeChain(store, repo, ref, flags, baseAuthMode) {
|
|
192
|
+
const base = resolveScopeProfile(store, repo, ref, flags);
|
|
193
|
+
if (!base.ok)
|
|
194
|
+
return { ok: false, reason: "base-unresolved", problem: base.problem };
|
|
195
|
+
const unreadable = repo === null ? null : store.fallbackConfigProblem(repo);
|
|
196
|
+
if (unreadable !== null)
|
|
197
|
+
return { ok: false, reason: "bad-fallback", problem: unreadable };
|
|
198
|
+
const fallbacks = repo === null ? [] : store.fallbackConfig(repo);
|
|
199
|
+
if (fallbacks.length === 0) {
|
|
200
|
+
// No fallbacks: a legacy single-profile approval, unchanged.
|
|
201
|
+
return { ok: true, chain: [{ profile: base.profile, authMode: baseAuthMode }], kind: "profile" };
|
|
202
|
+
}
|
|
203
|
+
const entries = [{ profile: base.profile, authMode: baseAuthMode }];
|
|
204
|
+
for (const one of fallbacks) {
|
|
205
|
+
if (!isProviderId(one.provider) || one.model === undefined || one.model === "") {
|
|
206
|
+
return { ok: false, reason: "bad-fallback", problem: `a fallback entry names an unknown provider or empty model (${one.provider}:${one.model})` };
|
|
207
|
+
}
|
|
208
|
+
if (one.authMode !== "subscription" && one.authMode !== "api-key") {
|
|
209
|
+
return { ok: false, reason: "bad-fallback", problem: `a fallback entry has an unknown auth mode` };
|
|
210
|
+
}
|
|
211
|
+
// An entry can only pin an auth mode its provider can actually take:
|
|
212
|
+
// "subscription" on a provider with no login (openrouter) would seal an
|
|
213
|
+
// entry that can never authenticate (E3d, gateway pin).
|
|
214
|
+
if (one.authMode === "subscription" && !SUBSCRIPTION_CAPABLE[one.provider]) {
|
|
215
|
+
return { ok: false, reason: "bad-fallback", problem: `${one.provider} has no subscription login — this entry must use an API key` };
|
|
216
|
+
}
|
|
217
|
+
// The model rides provider argv (F+G review, finding 1): the SAME
|
|
218
|
+
// argv-safety validation every other sealed model passes — never a
|
|
219
|
+
// leading dash, control bytes, or whitespace into a harness's argv.
|
|
220
|
+
const argvSafe = validateSpec({ provider: one.provider, model: one.model });
|
|
221
|
+
if (!argvSafe.ok) {
|
|
222
|
+
return { ok: false, reason: "bad-fallback", problem: argvSafe.problem };
|
|
223
|
+
}
|
|
224
|
+
entries.push({ profile: contestantProfileOf(one.provider, one.model, one.repairModel ?? "inherit", flags.permissionMode ?? store.permissionDefault().mode), authMode: one.authMode });
|
|
225
|
+
}
|
|
226
|
+
// Re-prove the whole chain through the strict rehydrator: it rejects
|
|
227
|
+
// exact-duplicate entries and any malformed shape, so what the approval
|
|
228
|
+
// seals is exactly what dispatch will re-derive.
|
|
229
|
+
const proven = chainFromJson(canonicalChainJson(entries));
|
|
230
|
+
if (proven === null) {
|
|
231
|
+
return { ok: false, reason: "duplicate", problem: "the fallback chain has a duplicate entry (same profile and auth mode) or is malformed" };
|
|
232
|
+
}
|
|
233
|
+
return { ok: true, chain: proven, kind: "chain" };
|
|
234
|
+
}
|
|
235
|
+
const PHASE_NOUN = { plan: "planner", build: "builder", repair: "repair", review: "reviewer" };
|
|
236
|
+
export function resolveRouteCandidates(store, repo, pins = {}) {
|
|
237
|
+
const strongOf = (phase) => {
|
|
238
|
+
const strongProject = repo === null ? null : store.phaseTierConfig(repo, phase, "strong");
|
|
239
|
+
const strongInstallation = store.phaseTierConfig(INSTALLATION_SCOPE, phase, "strong");
|
|
240
|
+
const inheritedProject = phase === "review" && strongProject === null && strongInstallation === null && repo !== null ? store.phaseTierConfig(repo, "plan", "strong") : null;
|
|
241
|
+
const inheritedInstallation = phase === "review" && strongProject === null && strongInstallation === null ? store.phaseTierConfig(INSTALLATION_SCOPE, "plan", "strong") : null;
|
|
242
|
+
const row = strongProject ?? inheritedProject ?? strongInstallation ?? inheritedInstallation;
|
|
243
|
+
const source = strongProject !== null ? "project (strong)" : inheritedProject !== null ? "project (strong, inherited from plan)" : strongInstallation !== null ? "installation (strong)" : inheritedInstallation !== null ? "installation (strong, inherited from plan)" : null;
|
|
244
|
+
if (row === null || source === null)
|
|
245
|
+
return { ok: true, strong: null };
|
|
246
|
+
if (!isProviderId(row.provider) || row.model === null || row.model === "") {
|
|
247
|
+
return { ok: false, problem: `the ${source} ${PHASE_NOUN[phase]} names ${row.provider}${row.model === null || row.model === "" ? " with no model" : ` · ${row.model}`} — a strong agent is an exact pair: \`config set ${phase} --tier strong --provider … --model …\`, or \`--clear\` it` };
|
|
248
|
+
}
|
|
249
|
+
const valid = validateSpec({ provider: row.provider, model: row.model });
|
|
250
|
+
if (!valid.ok)
|
|
251
|
+
return { ok: false, problem: `the ${source} ${PHASE_NOUN[phase]}: ${valid.problem}` };
|
|
252
|
+
return { ok: true, strong: { provider: row.provider, model: row.model, source } };
|
|
253
|
+
};
|
|
254
|
+
const exact = (phase) => {
|
|
255
|
+
const routine = resolvePhaseAgent(store, phase, repo, {});
|
|
256
|
+
if (!routine.ok)
|
|
257
|
+
return { ok: false, problem: routine.problem };
|
|
258
|
+
if (routine.spec.model === null || routine.spec.model === "") {
|
|
259
|
+
// A PINNED exact pair (a routine firing's approved profile, a plan
|
|
260
|
+
// request's pin) is the phase's agent whatever the configuration
|
|
261
|
+
// says — it stands in as the candidate when nothing exact is
|
|
262
|
+
// configured, so a firing never depends on today's config.
|
|
263
|
+
const pin = phase === "plan" ? pins.plan ?? null : phase === "build" ? pins.build ?? null : null;
|
|
264
|
+
if (pin !== null)
|
|
265
|
+
return { ok: true, routine: { provider: pin.provider, model: pin.model, source: "the pinned agent" } };
|
|
266
|
+
return {
|
|
267
|
+
ok: false,
|
|
268
|
+
problem: `approvals bind exact routing — the ${PHASE_NOUN[phase]} (${routine.spec.provider}) has no exact model: set one once with \`config set ${phase} --provider ${routine.spec.provider} --model <model>\``,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
return { ok: true, routine: { provider: routine.spec.provider, model: routine.spec.model, source: routine.source === "default" ? "the built-in default" : routine.source } };
|
|
272
|
+
};
|
|
273
|
+
const out = {};
|
|
274
|
+
for (const phase of ["plan", "build", "review"]) {
|
|
275
|
+
const routine = exact(phase);
|
|
276
|
+
const strong = strongOf(phase);
|
|
277
|
+
// Retain the historical four-leg encoding, but retired reviewer settings
|
|
278
|
+
// cannot prevent a new task from planning or building. This leg never runs.
|
|
279
|
+
if (phase === "review" && (!routine.ok || !strong.ok)) {
|
|
280
|
+
out.review = out.plan;
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
if (!routine.ok)
|
|
284
|
+
return { ok: false, phase, problem: routine.problem };
|
|
285
|
+
if (!strong.ok)
|
|
286
|
+
return { ok: false, phase, problem: strong.problem };
|
|
287
|
+
out[phase] = { routine: routine.routine, strong: strong.strong };
|
|
288
|
+
}
|
|
289
|
+
// Repair: the configured row is optional (inherit is the law when none
|
|
290
|
+
// exists), but a row that EXISTS must be exact — a provider the policy
|
|
291
|
+
// can hold against the build's, and a model id.
|
|
292
|
+
const repairProject = repo === null ? null : store.phaseConfig(repo, "repair");
|
|
293
|
+
const repairRow = repairProject ?? store.phaseConfig(INSTALLATION_SCOPE, "repair");
|
|
294
|
+
const repairSource = repairProject !== null ? "project" : "installation";
|
|
295
|
+
let repairRoutine = null;
|
|
296
|
+
if (repairRow !== null) {
|
|
297
|
+
if (!isProviderId(repairRow.provider) || repairRow.model === null || repairRow.model === "") {
|
|
298
|
+
return { ok: false, phase: "repair", problem: `the ${repairSource} repair configuration names ${repairRow.provider}${repairRow.model === null || repairRow.model === "" ? " with no model" : ` · ${repairRow.model}`} — approvals bind exact routing: \`config set repair --provider … --model …\` names an exact pair, or clear it so repairs inherit the build agent` };
|
|
299
|
+
}
|
|
300
|
+
const valid = validateSpec({ provider: repairRow.provider, model: repairRow.model });
|
|
301
|
+
if (!valid.ok)
|
|
302
|
+
return { ok: false, phase: "repair", problem: `the ${repairSource} repair configuration: ${valid.problem}` };
|
|
303
|
+
repairRoutine = { provider: repairRow.provider, model: repairRow.model, source: repairSource };
|
|
304
|
+
}
|
|
305
|
+
const repairStrong = strongOf("repair");
|
|
306
|
+
if (!repairStrong.ok)
|
|
307
|
+
return { ok: false, phase: "repair", problem: repairStrong.problem };
|
|
308
|
+
out.repair = { routine: repairRoutine, strong: repairStrong.strong };
|
|
309
|
+
return { ok: true, candidates: out };
|
|
310
|
+
}
|
|
311
|
+
/** A task's pinned pair as an EXACT spec, or the words for why it cannot
|
|
312
|
+
* route: a pin with no model id binds nothing exact. */
|
|
313
|
+
export function exactPinOf(provider, model, phase) {
|
|
314
|
+
if (provider === null)
|
|
315
|
+
return { ok: true, pin: null };
|
|
316
|
+
if (!isProviderId(provider))
|
|
317
|
+
return { ok: false, problem: `the task's ${phase} pin names unknown provider \`${provider}\`` };
|
|
318
|
+
if (model === null || model === "") {
|
|
319
|
+
return { ok: false, problem: phase === "plan" ? `the plan pin names ${provider} with no exact model — \`task plan <id> --provider ${provider} --model <model>\` names one` : `the task's build pin names ${provider} with no exact model — approvals bind exact routing` };
|
|
320
|
+
}
|
|
321
|
+
// An exact pin is an exact ID: a stored model that is not argv-safe (a
|
|
322
|
+
// leading dash, whitespace, a control byte) files the scope unresolved
|
|
323
|
+
// in words rather than riding into a route or a spawn.
|
|
324
|
+
if (!exactModelId(model)) {
|
|
325
|
+
return { ok: false, problem: `the task's ${phase} pin names ${provider} with a model that is not an exact id — re-pin it with an exact model id` };
|
|
326
|
+
}
|
|
327
|
+
return { ok: true, pin: { provider, model } };
|
|
328
|
+
}
|
|
329
|
+
export function routeOfTask(store, taskId, ref, now) {
|
|
330
|
+
const sealed = store.sealedRouteOf(taskId);
|
|
331
|
+
if (sealed.ok)
|
|
332
|
+
return { kind: "route", route: sealed.route, source: "approved" };
|
|
333
|
+
const scope = store.getScope(taskId);
|
|
334
|
+
if (scope !== null) {
|
|
335
|
+
if (scope.routeEra == null) {
|
|
336
|
+
const profile = scope.approvedProfile ?? scope.profile ?? null;
|
|
337
|
+
return profile === null ? null : { kind: "legacy", profile, approved: sealed.reason !== "unapproved" && scope.approvedAt !== null && scope.approvedDigest === scope.digest };
|
|
338
|
+
}
|
|
339
|
+
if (sealed.reason === "unreadable")
|
|
340
|
+
return { kind: "unreadable", problem: sealed.detail };
|
|
341
|
+
const proposed = routeFromJson(scope.proposedRouteJson ?? null);
|
|
342
|
+
if (proposed !== null)
|
|
343
|
+
return { kind: "route", route: proposed, source: "proposed" };
|
|
344
|
+
return { kind: "unreadable", problem: scope.unresolvedReason ?? "the filed route cannot be read — re-file the scope" };
|
|
345
|
+
}
|
|
346
|
+
const repo = ref?.repo ?? null;
|
|
347
|
+
const overrides = ref === null || ref.routeOverrides === undefined ? [] : ref.routeOverrides;
|
|
348
|
+
if (overrides === null)
|
|
349
|
+
return { kind: "unreadable", problem: "the task's recorded route overrides cannot be read — clear or re-record them with `task route`" };
|
|
350
|
+
const planPin = exactPinOf(ref?.planProvider ?? null, ref?.planModel ?? null, "plan");
|
|
351
|
+
if (!planPin.ok)
|
|
352
|
+
return { kind: "unreadable", problem: planPin.problem };
|
|
353
|
+
const buildPin = exactPinOf(ref?.agentProvider ?? null, ref?.agentModel ?? null, "build");
|
|
354
|
+
if (!buildPin.ok)
|
|
355
|
+
return { kind: "unreadable", problem: buildPin.problem };
|
|
356
|
+
const candidates = resolveRouteCandidates(store, repo, { plan: planPin.pin, build: buildPin.pin });
|
|
357
|
+
if (!candidates.ok)
|
|
358
|
+
return { kind: "unreadable", problem: candidates.problem };
|
|
359
|
+
const route = recommendRoute({
|
|
360
|
+
risk: ref?.riskLevel ?? "routine",
|
|
361
|
+
qualityMode: ref?.qualityMode ?? store.qualityDefault().mode,
|
|
362
|
+
evidence: [],
|
|
363
|
+
publication: store.publicationAuthorityOf(repo, now),
|
|
364
|
+
candidates: candidates.candidates,
|
|
365
|
+
overrides,
|
|
366
|
+
pins: { plan: planPin.pin, build: buildPin.pin },
|
|
367
|
+
});
|
|
368
|
+
return { kind: "route", route, source: "live" };
|
|
369
|
+
}
|
|
370
|
+
export function resolveRoutineAuthority(store, repo, acceptance, now) {
|
|
371
|
+
const candidates = resolveRouteCandidates(store, repo);
|
|
372
|
+
if (!candidates.ok)
|
|
373
|
+
return { ok: false, problem: candidates.problem };
|
|
374
|
+
const route = recommendRoute({
|
|
375
|
+
risk: "routine",
|
|
376
|
+
qualityMode: store.qualityDefault().mode,
|
|
377
|
+
evidence: [...new Set(acceptance.flatMap(one => one.evidence))],
|
|
378
|
+
publication: store.publicationAuthorityOf(repo, now),
|
|
379
|
+
candidates: candidates.candidates,
|
|
380
|
+
overrides: [],
|
|
381
|
+
});
|
|
382
|
+
const problems = routeProblems(route);
|
|
383
|
+
if (problems.length > 0)
|
|
384
|
+
return { ok: false, problem: problems.join("; ") };
|
|
385
|
+
const build = legOf(route, "build");
|
|
386
|
+
const repair = legOf(route, "repair");
|
|
387
|
+
// The repair model rides as a flag only when the leg says more than
|
|
388
|
+
// "the build's own model" — an inheriting repair stays the stable
|
|
389
|
+
// literal "inherit" (= the exact build model), as saveScope files it.
|
|
390
|
+
const inheriting = candidates.candidates.repair.routine === null && repair.chosen === "recommended" && repair.tier === "routine" && repair.model === build.model;
|
|
391
|
+
const resolved = resolveScopeProfile(store, repo, undefined, { provider: build.provider, model: build.model, ...(inheriting ? {} : { repairModel: repair.model }) });
|
|
392
|
+
if (!resolved.ok)
|
|
393
|
+
return { ok: false, problem: resolved.problem };
|
|
394
|
+
const repairModel = resolved.profile.repairModel === "inherit" ? resolved.profile.model : resolved.profile.repairModel;
|
|
395
|
+
if (!sameSpec(resolved.profile, build) || repairModel !== repair.model) {
|
|
396
|
+
return { ok: false, problem: `the agent profile (${resolved.profile.provider} · ${resolved.profile.model}, repair ${repairModel}) does not match the route (${build.provider} · ${build.model}, repair ${repair.model})` };
|
|
397
|
+
}
|
|
398
|
+
return { ok: true, route, profile: resolved.profile };
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* THE ROLE'S CONFIGURED CHOICES (v48), simple and role-specific: for each
|
|
402
|
+
* role, exactly the exact pairs the active configuration names FOR THAT
|
|
403
|
+
* ROLE — its everyday agent and its strong agent — and nothing borrowed
|
|
404
|
+
* from another role. Repair runs only the build leg's provider (repairs
|
|
405
|
+
* resume the builder's session): its choices are the configured repair
|
|
406
|
+
* rows on that provider plus the build role's own configured agents on
|
|
407
|
+
* it, so an operator can keep repairs on the builder without naming a
|
|
408
|
+
* repair row. Gemini never reviews. Nothing is typed free-hand and
|
|
409
|
+
* nothing unconfigured is selectable: an approval binds an exact agent
|
|
410
|
+
* the operator named once, in configuration.
|
|
411
|
+
*
|
|
412
|
+
* The role's CURRENT leg rides along marked `current`; when the
|
|
413
|
+
* configuration no longer names it (a stale override, a routine's pin)
|
|
414
|
+
* it is display-only — `selectable: false` — so a surface can say what
|
|
415
|
+
* runs today without offering to re-pick it. Empty when the
|
|
416
|
+
* configuration cannot make exact candidates at all; the surface then
|
|
417
|
+
* says so instead of guessing.
|
|
418
|
+
*/
|
|
419
|
+
export function agentChoicesFor(store, repo, route) {
|
|
420
|
+
const empty = { plan: [], build: [], repair: [], review: [] };
|
|
421
|
+
const candidates = resolveRouteCandidates(store, repo);
|
|
422
|
+
if (!candidates.ok)
|
|
423
|
+
return empty;
|
|
424
|
+
const buildProvider = route === null ? candidates.candidates.build.routine.provider : legOf(route, "build").provider;
|
|
425
|
+
const configuredFor = (phase) => {
|
|
426
|
+
const tiers = candidates.candidates[phase];
|
|
427
|
+
const own = phase === "repair"
|
|
428
|
+
? [tiers.routine, tiers.strong, candidates.candidates.build.routine, candidates.candidates.build.strong]
|
|
429
|
+
: [tiers.routine, tiers.strong];
|
|
430
|
+
const out = [];
|
|
431
|
+
for (const one of own) {
|
|
432
|
+
if (one === null || out.some(seen => sameSpec(seen, one)))
|
|
433
|
+
continue;
|
|
434
|
+
if (phase === "review" && one.provider === "gemini")
|
|
435
|
+
continue;
|
|
436
|
+
if (phase === "repair" && one.provider !== buildProvider)
|
|
437
|
+
continue;
|
|
438
|
+
if (!validateSpec({ provider: one.provider, model: one.model }).ok)
|
|
439
|
+
continue;
|
|
440
|
+
out.push(one);
|
|
441
|
+
}
|
|
442
|
+
return out;
|
|
443
|
+
};
|
|
444
|
+
const out = { plan: [], build: [], repair: [], review: [] };
|
|
445
|
+
for (const phase of PHASES.filter(one => one !== "review")) {
|
|
446
|
+
const current = route === null ? null : legOf(route, phase);
|
|
447
|
+
const offered = configuredFor(phase).map(one => ({ provider: one.provider, model: one.model, source: one.source, current: current !== null && sameSpec(current, one), selectable: true }));
|
|
448
|
+
if (current !== null && !offered.some(one => sameSpec(one, current))) {
|
|
449
|
+
offered.push({ provider: current.provider, model: current.model, source: "this task's current agent — not in today's configuration", current: true, selectable: false });
|
|
450
|
+
}
|
|
451
|
+
out[phase] = offered;
|
|
452
|
+
}
|
|
453
|
+
return out;
|
|
454
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type TokenAccess = "read" | "act";
|
|
2
|
+
export declare const TOKEN_DAYS: readonly [30, 90, 365];
|
|
3
|
+
export declare function mintApiToken(): {
|
|
4
|
+
id: string;
|
|
5
|
+
secret: string;
|
|
6
|
+
token: string;
|
|
7
|
+
hash: string;
|
|
8
|
+
};
|
|
9
|
+
export declare const hashSecret: (secret: string) => string;
|
|
10
|
+
/** The id and secret of something shaped like a token, or null. */
|
|
11
|
+
export declare function parseApiToken(presented: string): {
|
|
12
|
+
id: string;
|
|
13
|
+
secret: string;
|
|
14
|
+
} | null;
|
|
15
|
+
/** Whether the secret is the one whose hash was kept, in constant time. */
|
|
16
|
+
export declare function secretMatches(secret: string, keptHash: string): boolean;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API tokens (v101): what scripts and CI use instead of a password on each
|
|
3
|
+
* request. A token belongs to one person, reads or acts (never more than the
|
|
4
|
+
* person may), always expires (a year at most), is shown once, and only its
|
|
5
|
+
* hash is kept. `Authorization: Bearer so_<id>_<secret>`.
|
|
6
|
+
*
|
|
7
|
+
* A token never passes a step-up: approvals and other password ceremonies
|
|
8
|
+
* stay a person's act in the console.
|
|
9
|
+
*/
|
|
10
|
+
import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
|
|
11
|
+
export const TOKEN_DAYS = [30, 90, 365];
|
|
12
|
+
const SHAPE = /^so_([a-f0-9]{12})_([A-Za-z0-9_-]{43})$/;
|
|
13
|
+
export function mintApiToken() {
|
|
14
|
+
const id = randomBytes(6).toString("hex"), secret = randomBytes(32).toString("base64url");
|
|
15
|
+
return { id, secret, token: `so_${id}_${secret}`, hash: hashSecret(secret) };
|
|
16
|
+
}
|
|
17
|
+
export const hashSecret = (secret) => createHash("sha256").update(secret, "utf8").digest("hex");
|
|
18
|
+
/** The id and secret of something shaped like a token, or null. */
|
|
19
|
+
export function parseApiToken(presented) {
|
|
20
|
+
const match = SHAPE.exec(presented);
|
|
21
|
+
return match === null ? null : { id: match[1], secret: match[2] };
|
|
22
|
+
}
|
|
23
|
+
/** Whether the secret is the one whose hash was kept, in constant time. */
|
|
24
|
+
export function secretMatches(secret, keptHash) {
|
|
25
|
+
const a = Buffer.from(hashSecret(secret), "hex"), b = Buffer.from(keptHash, "hex");
|
|
26
|
+
return a.length === b.length && timingSafeEqual(a, b);
|
|
27
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Separation of duties (v102): a project's approval rules. Two can be on at
|
|
3
|
+
* once, and neither changes a thing until a project turns it on.
|
|
4
|
+
*
|
|
5
|
+
* - The person who filed a task can't approve it ("not the requester").
|
|
6
|
+
* - Protected work (the whole project, or tasks that touch protected paths)
|
|
7
|
+
* needs two different people to approve the same exact scope, and an AI
|
|
8
|
+
* teammate or an operating mode can never decide it.
|
|
9
|
+
*
|
|
10
|
+
* The store enforces these at the one place every approval is sealed
|
|
11
|
+
* (`Store.sealScopeApproval`); this module holds the pure parts.
|
|
12
|
+
*/
|
|
13
|
+
/** Who filed a task, as far as anyone can tell: a person (browser, chat, a
|
|
14
|
+
* revision), a coordinator acting for the person who made it, an AI
|
|
15
|
+
* teammate, or automation that names no person (a routine, the CLI, a flow
|
|
16
|
+
* with no owner). The requester rule binds only a named person. */
|
|
17
|
+
export type FilerKind = "person" | "coordinator" | "teammate" | "automation";
|
|
18
|
+
export type Filer = {
|
|
19
|
+
name: string | null;
|
|
20
|
+
kind: FilerKind;
|
|
21
|
+
};
|
|
22
|
+
/** A filer from a name as the ledger writes it: an AI teammate's ends " (AI)"; a coordinator's starts "coordinator:"; none is automation. */
|
|
23
|
+
export declare function filerFor(name: string | null | undefined): Filer;
|
|
24
|
+
export type ApprovalRules = {
|
|
25
|
+
notRequester: boolean;
|
|
26
|
+
protectProject: boolean;
|
|
27
|
+
protectedPaths: string[];
|
|
28
|
+
};
|
|
29
|
+
export declare const NO_RULES: ApprovalRules;
|
|
30
|
+
/** Who is sealing: a person at a ceremony, an operating mode, an AI teammate, or automation. */
|
|
31
|
+
export type ApproverKind = "person" | "mode" | "ai" | "automation";
|
|
32
|
+
export type ApprovalGate = {
|
|
33
|
+
verdict: "seal";
|
|
34
|
+
protectedWork: boolean;
|
|
35
|
+
} | {
|
|
36
|
+
verdict: "vote";
|
|
37
|
+
have: number;
|
|
38
|
+
need: 2;
|
|
39
|
+
already: boolean;
|
|
40
|
+
} | {
|
|
41
|
+
verdict: "refuse";
|
|
42
|
+
reason: "requester" | "person-required";
|
|
43
|
+
};
|
|
44
|
+
/** Whether a task that says it touches `touch` may touch something under
|
|
45
|
+
* `protectedGlob`, or a changed file is protected. A plain path covers
|
|
46
|
+
* itself and everything under it; a pattern with no slash matches at any
|
|
47
|
+
* depth (as in .gitignore); two patterns that could reach the same files
|
|
48
|
+
* count as overlapping; a path that climbs out of the checkout is
|
|
49
|
+
* protected. Every doubt errs toward protecting. */
|
|
50
|
+
export declare function touchesProtected(touch: string, protectedGlob: string): boolean;
|
|
51
|
+
/** The changed files (from a build's diff) that the rules protect. */
|
|
52
|
+
export declare function protectedChanges(rules: ApprovalRules, changed: readonly string[]): string[];
|
|
53
|
+
/** Whether a task's declared paths reach protected work. A task that
|
|
54
|
+
* declares no paths can't show it stays clear, so it counts as protected. */
|
|
55
|
+
export declare function isProtectedWork(rules: ApprovalRules, touches: string[]): boolean;
|
|
56
|
+
/** Protected paths as a person types them: one per line or comma separated, trimmed, deduplicated, at most 50. */
|
|
57
|
+
export declare function parseProtectedPaths(raw: string): {
|
|
58
|
+
ok: true;
|
|
59
|
+
paths: string[];
|
|
60
|
+
} | {
|
|
61
|
+
ok: false;
|
|
62
|
+
problem: string;
|
|
63
|
+
};
|
|
64
|
+
/** The rules in a line, for the ledger's before → after. */
|
|
65
|
+
export declare function rulesWords(rules: ApprovalRules): string;
|
|
66
|
+
/** What a person reads when the rules stop an approval. */
|
|
67
|
+
export declare function gateWords(gate: Exclude<ApprovalGate, {
|
|
68
|
+
verdict: "seal";
|
|
69
|
+
}>): string;
|