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,82 @@
|
|
|
1
|
+
import type { Filer } from "./approval-policy.js";
|
|
2
|
+
export { validateTaskText } from "./task-text.js";
|
|
3
|
+
import type { Store } from "./store.js";
|
|
4
|
+
import { type UnattendedPermissionMode } from "./scope.js";
|
|
5
|
+
import type { QualityMode } from "./quality.js";
|
|
6
|
+
export type ProposalRefusal = {
|
|
7
|
+
ok: false;
|
|
8
|
+
/** Stable, machine-readable — joins the envelope like every reason. */
|
|
9
|
+
reason: "bad-title" | "bad-goal" | "bad-id" | "bad-name" | "bad-terms" | "bad-repo" | "outside-ceiling" | "bad-provenance" | "bad-acceptance" | "acceptance-required" | "backlog-full" | "duplicate";
|
|
10
|
+
message: string;
|
|
11
|
+
};
|
|
12
|
+
export type TaskProposalInput = {
|
|
13
|
+
id?: string;
|
|
14
|
+
title: string;
|
|
15
|
+
repo?: string;
|
|
16
|
+
goal?: string;
|
|
17
|
+
outOfScope?: string | null;
|
|
18
|
+
touches?: string[];
|
|
19
|
+
/** v39: the signed acceptance rubric — unparsed, checked by
|
|
20
|
+
* `store.createConsoleTask` the same way every other filing text is
|
|
21
|
+
* checked here: identically for every caller of this one door. */
|
|
22
|
+
acceptance?: unknown;
|
|
23
|
+
/** Which door filed this: 'cli', 'console', 'intake', 'template:<name>'. */
|
|
24
|
+
filedVia: string;
|
|
25
|
+
/** v102: who filed it — the person, or the person a coordinator acts for (separation of duties reads it). */
|
|
26
|
+
filedBy?: Filer;
|
|
27
|
+
/** The scope text's author when it is an LLM's (ruling 2; §10 for a
|
|
28
|
+
* scout's follow-up): mode coverage never seals it. */
|
|
29
|
+
proposedVia?: "mate" | "coordinator" | "scout";
|
|
30
|
+
/** What comes back (v34): 'report' files a scout task. Set once, at filing. */
|
|
31
|
+
deliverable?: "branch" | "report";
|
|
32
|
+
/** Planning policy at the filing door. `required` is an explicit
|
|
33
|
+
* operator choice, `skip` is an explicit direct-to-scope choice, and
|
|
34
|
+
* `auto` (the default) plans implementation work whose breadth suggests
|
|
35
|
+
* repository discovery will materially improve the approved scope. */
|
|
36
|
+
planning?: "auto" | "required" | "skip";
|
|
37
|
+
/** Concrete per-task unattended permission choice. When absent, the
|
|
38
|
+
* installation default is resolved as the scope is filed. */
|
|
39
|
+
permissionMode?: UnattendedPermissionMode;
|
|
40
|
+
/** Concrete per-task evidence depth. Absent inherits the installation
|
|
41
|
+
* default when the scope is filed. */
|
|
42
|
+
qualityMode?: QualityMode;
|
|
43
|
+
/**
|
|
44
|
+
* The caller's ceiling as canonical repo paths. undefined = the caller
|
|
45
|
+
* genuinely has none (the CLI on the operator's own machine). A surface
|
|
46
|
+
* that HAS a ceiling must pass it — an empty list refuses every repo,
|
|
47
|
+
* which is the fail-closed reading of an empty ceiling (finding 4).
|
|
48
|
+
*/
|
|
49
|
+
admittedRepos?: readonly string[];
|
|
50
|
+
};
|
|
51
|
+
/** One deterministic planning policy for console, chat, MCP, and sync
|
|
52
|
+
* filings. A planner needs a repository to inspect; report/scout work is
|
|
53
|
+
* already the discovery phase and never recursively plans itself. */
|
|
54
|
+
export declare function shouldPlanTask(input: TaskProposalInput): boolean;
|
|
55
|
+
export type RoutineProposalInput = {
|
|
56
|
+
name: string;
|
|
57
|
+
/** v102: who is making it (its instances are filed as theirs). */
|
|
58
|
+
createdBy?: string | null;
|
|
59
|
+
repo: string;
|
|
60
|
+
goal: string;
|
|
61
|
+
outOfScope: string | null;
|
|
62
|
+
touches: string[];
|
|
63
|
+
/** v39: the signed rubric every instance's scope copies forward. */
|
|
64
|
+
acceptance: unknown;
|
|
65
|
+
requirements: string[];
|
|
66
|
+
schedule: string;
|
|
67
|
+
costCeilingUsd: number | null;
|
|
68
|
+
/** Per-instance dollar cap in micro-USD (v16); optional, digest-bound. */
|
|
69
|
+
budgetPerRunMicrousd?: number | null;
|
|
70
|
+
filedVia: string;
|
|
71
|
+
admittedRepos?: readonly string[];
|
|
72
|
+
};
|
|
73
|
+
export declare function fileTaskProposal(store: Store, input: TaskProposalInput, now: Date): {
|
|
74
|
+
ok: true;
|
|
75
|
+
id: string;
|
|
76
|
+
planning: boolean;
|
|
77
|
+
} | ProposalRefusal;
|
|
78
|
+
export declare function fileRoutineProposal(store: Store, input: RoutineProposalInput, now: Date): {
|
|
79
|
+
ok: true;
|
|
80
|
+
id: number;
|
|
81
|
+
digest: string;
|
|
82
|
+
} | ProposalRefusal;
|
package/dist/proposal.js
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { validateTaskText } from "./task-text.js";
|
|
2
|
+
export { validateTaskText } from "./task-text.js";
|
|
3
|
+
/**
|
|
4
|
+
* The one door work enters through (Codex adoption review, finding 7).
|
|
5
|
+
*
|
|
6
|
+
* Before this module, each filing surface — CLI, console, intake — validated
|
|
7
|
+
* what it happened to think of: createConsoleTask checked title and goal but
|
|
8
|
+
* not disguised text, the routine command checked terms but nothing checked a
|
|
9
|
+
* repo against the caller's ceiling, and nothing stamped who filed what. The
|
|
10
|
+
* review's ruling: one canonical service that every filer calls, with an
|
|
11
|
+
* exact field allowlist, so a careless caller CANNOT spread a template or
|
|
12
|
+
* model object into scope rows and smuggle approval metadata.
|
|
13
|
+
*
|
|
14
|
+
* The contract, in order:
|
|
15
|
+
* - every text field is validated here, identically for every caller:
|
|
16
|
+
* length bounds, control characters, and DISGUISED text (invisibles,
|
|
17
|
+
* bidi overrides) on the fields an approver reads;
|
|
18
|
+
* - the repo is canonicalized, and when the caller has a ceiling the
|
|
19
|
+
* canonical repo must be inside it — an absent ceiling is the CLI's
|
|
20
|
+
* honest "no ceiling", never a wildcard for surfaces that have one;
|
|
21
|
+
* - approval fields are hardcoded null by the store methods this calls;
|
|
22
|
+
* nothing a caller passes can reach them (exact allowlist, no spread);
|
|
23
|
+
* - the digest is computed HERE, never accepted from the caller;
|
|
24
|
+
* - provenance (filedVia) is stamped in the same transaction and is
|
|
25
|
+
* immutable — there is no API to change it, anywhere.
|
|
26
|
+
*
|
|
27
|
+
* Filing carries NO authority. Everything this module creates is unapproved
|
|
28
|
+
* and stays inert until the operator's own ceremony says otherwise.
|
|
29
|
+
*/
|
|
30
|
+
import { resolveRoutineAuthority } from "./agentconfig.js";
|
|
31
|
+
import { resolve } from "node:path";
|
|
32
|
+
import { hasForbiddenControls, hasDisguisedText } from "./decision.js";
|
|
33
|
+
import { canonicalProject } from "./project.js";
|
|
34
|
+
import { ROUTINE_NAME, routineDigestOf, validateRoutineTerms, } from "./routine.js";
|
|
35
|
+
import { parseAcceptanceCriteria } from "./scope.js";
|
|
36
|
+
/** Provenance tokens are part of the audit surface: lowercase, bounded,
|
|
37
|
+
* nothing that could render as anything but itself. */
|
|
38
|
+
const FILED_VIA = /^[a-z][a-z0-9:-]{0,63}$/;
|
|
39
|
+
const SUBSTANTIAL_WORK = /\b(?:architecture|end[- ]to[- ]end|migrat(?:e|ion)|moderni[sz]e|redesign|refactor|rework|workflow|navigation|accessibility|responsive|performance|security|unif(?:y|ied)|multi[- ](?:step|project|service))\b/i;
|
|
40
|
+
/** One deterministic planning policy for console, chat, MCP, and sync
|
|
41
|
+
* filings. A planner needs a repository to inspect; report/scout work is
|
|
42
|
+
* already the discovery phase and never recursively plans itself. */
|
|
43
|
+
export function shouldPlanTask(input) {
|
|
44
|
+
if (input.deliverable === "report" || input.planning === "skip")
|
|
45
|
+
return false;
|
|
46
|
+
// Remote coordinators only propose work. Keep their submissions quarantined
|
|
47
|
+
// until an operator has restated the scope; automatic planning must not turn
|
|
48
|
+
// an untrusted MCP filing into executable workflow state.
|
|
49
|
+
if (input.proposedVia === "coordinator" || input.filedVia?.startsWith("mcp:"))
|
|
50
|
+
return false;
|
|
51
|
+
if (input.repo === undefined || input.repo.trim() === "")
|
|
52
|
+
return false;
|
|
53
|
+
if (input.planning === "required")
|
|
54
|
+
return true;
|
|
55
|
+
const goal = input.goal ?? "";
|
|
56
|
+
const descriptionSize = input.title.length + goal.length + (input.outOfScope?.length ?? 0);
|
|
57
|
+
return ((input.touches?.length ?? 0) >= 2 ||
|
|
58
|
+
descriptionSize >= 280 ||
|
|
59
|
+
SUBSTANTIAL_WORK.test(`${input.title}\n${goal}`));
|
|
60
|
+
}
|
|
61
|
+
function refuse(reason, message) {
|
|
62
|
+
return { ok: false, reason, message };
|
|
63
|
+
}
|
|
64
|
+
/** The fields an approver reads must BE what they appear to be: no control
|
|
65
|
+
* characters anywhere, no invisible or direction-override text either. */
|
|
66
|
+
function dishonest(text) {
|
|
67
|
+
return hasForbiddenControls(text) || hasDisguisedText(text);
|
|
68
|
+
}
|
|
69
|
+
/** Byte caps beside the character caps (Codex v3 review, change 8): a
|
|
70
|
+
* 2000-character goal of astral-plane text is 8000 bytes — model-authored
|
|
71
|
+
* fields must bound STORAGE, not just what a screen shows. */
|
|
72
|
+
const BYTE_CAPS = { title: 800, name: 200, text: 8_000, path: 800, requirement: 400 };
|
|
73
|
+
function overBytes(text, cap) {
|
|
74
|
+
return Buffer.byteLength(text, "utf8") > cap;
|
|
75
|
+
}
|
|
76
|
+
function checkRepo(given, admitted) {
|
|
77
|
+
if (given === undefined || given === "") {
|
|
78
|
+
// A ceiling names the ONLY repos this surface may file into. Filing
|
|
79
|
+
// repo-less under a ceiling would bypass it wholesale (MCP spec v2,
|
|
80
|
+
// Codex round 2 finding 2) — a bounded surface must say where.
|
|
81
|
+
if (admitted !== undefined) {
|
|
82
|
+
return refuse("outside-ceiling", "this surface must name a repository — it is limited to specific ones");
|
|
83
|
+
}
|
|
84
|
+
return { ok: true, repo: undefined };
|
|
85
|
+
}
|
|
86
|
+
// Best-effort canonicalization, the codebase's one convention: a real
|
|
87
|
+
// directory resolves through symlinks; a path that does not exist yet
|
|
88
|
+
// still normalizes, because filing must not depend on this machine
|
|
89
|
+
// seeing every repo the plane knows about.
|
|
90
|
+
const canonical = canonicalProject(given) ?? resolve(given);
|
|
91
|
+
if (admitted !== undefined && !admitted.includes(canonical)) {
|
|
92
|
+
return refuse("outside-ceiling", "that repository is outside what this surface was configured to show");
|
|
93
|
+
}
|
|
94
|
+
return { ok: true, repo: canonical };
|
|
95
|
+
}
|
|
96
|
+
export function fileTaskProposal(store, input, now) {
|
|
97
|
+
if (!FILED_VIA.test(input.filedVia)) {
|
|
98
|
+
return refuse("bad-provenance", "filedVia is an audit token: lowercase letters, digits, dashes, colons");
|
|
99
|
+
}
|
|
100
|
+
const badText = validateTaskText(input);
|
|
101
|
+
if (badText !== null)
|
|
102
|
+
return badText;
|
|
103
|
+
const outOfScope = input.outOfScope ?? null;
|
|
104
|
+
const touches = input.touches ?? [];
|
|
105
|
+
const repo = checkRepo(input.repo, input.admittedRepos);
|
|
106
|
+
if (!repo.ok)
|
|
107
|
+
return repo;
|
|
108
|
+
// Exact allowlist — built field by field, never spread from the input.
|
|
109
|
+
const made = store.createConsoleTask({
|
|
110
|
+
...(input.id === undefined ? {} : { id: input.id }),
|
|
111
|
+
title: input.title,
|
|
112
|
+
...(repo.repo === undefined ? {} : { repo: repo.repo }),
|
|
113
|
+
...(input.goal === undefined ? {} : { goal: input.goal }),
|
|
114
|
+
...(input.permissionMode === undefined ? {} : { permissionMode: input.permissionMode }),
|
|
115
|
+
...(input.qualityMode === undefined ? {} : { qualityMode: input.qualityMode }),
|
|
116
|
+
outOfScope,
|
|
117
|
+
touches,
|
|
118
|
+
acceptance: input.acceptance,
|
|
119
|
+
filedVia: input.filedVia,
|
|
120
|
+
...(input.filedBy === undefined ? {} : { filedBy: input.filedBy }),
|
|
121
|
+
proposedVia: input.proposedVia ?? null,
|
|
122
|
+
...(input.deliverable === undefined ? {} : { deliverable: input.deliverable }),
|
|
123
|
+
}, now);
|
|
124
|
+
if (!made.ok) {
|
|
125
|
+
return refuse(made.reason, made.reason === "backlog-full"
|
|
126
|
+
? "the backlog is full — finish or cancel something first"
|
|
127
|
+
: made.reason === "duplicate"
|
|
128
|
+
? "a task with that id already exists"
|
|
129
|
+
: made.reason === "acceptance-required"
|
|
130
|
+
? "a goal needs at least one signed acceptance criterion before it can be filed"
|
|
131
|
+
: `the store refused the filing: ${made.reason}`);
|
|
132
|
+
}
|
|
133
|
+
let planning = false;
|
|
134
|
+
if (shouldPlanTask({ ...input, ...(repo.repo === undefined ? {} : { repo: repo.repo }) })) {
|
|
135
|
+
const ref = store.lookupRef(made.id);
|
|
136
|
+
if (ref !== null)
|
|
137
|
+
planning = store.requestPlan(ref.id, now).ok;
|
|
138
|
+
}
|
|
139
|
+
return { ok: true, id: made.id, planning };
|
|
140
|
+
}
|
|
141
|
+
export function fileRoutineProposal(store, input, now) {
|
|
142
|
+
if (!FILED_VIA.test(input.filedVia)) {
|
|
143
|
+
return refuse("bad-provenance", "filedVia is an audit token: lowercase letters, digits, dashes, colons");
|
|
144
|
+
}
|
|
145
|
+
const repo = checkRepo(input.repo, input.admittedRepos);
|
|
146
|
+
if (!repo.ok)
|
|
147
|
+
return repo;
|
|
148
|
+
if (repo.repo === undefined)
|
|
149
|
+
return refuse("bad-repo", "a routine needs the repository it runs in");
|
|
150
|
+
const acceptanceParse = parseAcceptanceCriteria(input.acceptance);
|
|
151
|
+
const terms = {
|
|
152
|
+
repo: repo.repo,
|
|
153
|
+
goal: input.goal,
|
|
154
|
+
outOfScope: input.outOfScope,
|
|
155
|
+
touches: input.touches,
|
|
156
|
+
acceptance: acceptanceParse.criteria,
|
|
157
|
+
requirements: input.requirements,
|
|
158
|
+
schedule: input.schedule,
|
|
159
|
+
// v1 routines run one instance at a time, period — hardcoded, not accepted.
|
|
160
|
+
singleFlight: true,
|
|
161
|
+
costCeilingUsd: input.costCeilingUsd,
|
|
162
|
+
...(input.budgetPerRunMicrousd == null ? {} : { budgetPerRunMicrousd: input.budgetPerRunMicrousd }),
|
|
163
|
+
};
|
|
164
|
+
// EVERY problem at once — an operator fixing a form deserves the whole
|
|
165
|
+
// list, not one complaint per submission.
|
|
166
|
+
const problems = validateRoutineTerms(terms);
|
|
167
|
+
if (acceptanceParse.problems.length > 0) {
|
|
168
|
+
problems.push({ field: "acceptance", problem: acceptanceParse.problems.map(p => p.message).join("; ") });
|
|
169
|
+
}
|
|
170
|
+
if (!ROUTINE_NAME.test(input.name)) {
|
|
171
|
+
problems.unshift({ field: "name", problem: "lowercase letters, digits, and dashes — it becomes each instance's id" });
|
|
172
|
+
}
|
|
173
|
+
if (dishonest(input.goal) ||
|
|
174
|
+
overBytes(input.goal, BYTE_CAPS.text) ||
|
|
175
|
+
(input.outOfScope !== null && (dishonest(input.outOfScope) || overBytes(input.outOfScope, BYTE_CAPS.text)))) {
|
|
176
|
+
problems.push({ field: "goal", problem: "no control or disguised text, bounded bytes" });
|
|
177
|
+
}
|
|
178
|
+
// The v3 review, change 8: touches and requirements are approver-read
|
|
179
|
+
// text too — the door holds them to the same honesty everywhere.
|
|
180
|
+
if (input.touches.some(one => dishonest(one) || overBytes(one, BYTE_CAPS.path))) {
|
|
181
|
+
problems.push({ field: "touches", problem: "no control or disguised text, bounded bytes" });
|
|
182
|
+
}
|
|
183
|
+
if (input.requirements.some(one => dishonest(one) || overBytes(one, BYTE_CAPS.requirement))) {
|
|
184
|
+
problems.push({ field: "requirements", problem: "no control or disguised text, bounded bytes" });
|
|
185
|
+
}
|
|
186
|
+
if (problems.length > 0) {
|
|
187
|
+
const named = problems.map(one => `${one.field}: ${one.problem}`).join("; ");
|
|
188
|
+
return refuse(problems.some(one => one.field === "name") ? "bad-name" : "bad-terms", named);
|
|
189
|
+
}
|
|
190
|
+
// v24 filing invariant, routine flavor — since v48 the whole four-role
|
|
191
|
+
// ROUTE: resolve which agents plan, build, repair, and review a firing
|
|
192
|
+
// once, here, from the configuration of this moment, and bind route and
|
|
193
|
+
// profile into the digest a person will sign. Unresolved saves too
|
|
194
|
+
// (finding 19) — approval then refuses until the routine is restated.
|
|
195
|
+
const authority = resolveRoutineAuthority(store, repo.repo, terms.acceptance, now);
|
|
196
|
+
const routineProfile = authority.ok ? authority.profile : null;
|
|
197
|
+
const routineRoute = authority.ok ? authority.route : null;
|
|
198
|
+
const created = store.createRoutine({
|
|
199
|
+
name: input.name,
|
|
200
|
+
...terms,
|
|
201
|
+
digest: routineDigestOf(terms, routineProfile, routineRoute),
|
|
202
|
+
filedVia: input.filedVia,
|
|
203
|
+
createdBy: input.createdBy ?? null,
|
|
204
|
+
...(routineProfile === null ? {} : { profile: routineProfile }),
|
|
205
|
+
...(routineRoute === null ? {} : { route: routineRoute }),
|
|
206
|
+
}, now);
|
|
207
|
+
if (!created.ok)
|
|
208
|
+
return refuse("duplicate", `a routine named ${input.name} already exists`);
|
|
209
|
+
return { ok: true, id: created.id, digest: routineDigestOf(terms, routineProfile, routineRoute) };
|
|
210
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { run, type ExecResult } from "./exec.js";
|
|
2
|
+
import { type ProviderId } from "./provider.js";
|
|
3
|
+
import { type AuthMode, type KeyVerdict } from "./keys.js";
|
|
4
|
+
export type ProviderConnection = {
|
|
5
|
+
state: "connected" | "signed-out" | "not-installed" | "unverified" | "key-present" | "key-works" | "key-refused" | "missing-key";
|
|
6
|
+
/** A saved key that was just tested: what the provider said. */
|
|
7
|
+
verdict?: KeyVerdict;
|
|
8
|
+
mode: AuthMode;
|
|
9
|
+
email?: string;
|
|
10
|
+
plan?: string;
|
|
11
|
+
method?: string;
|
|
12
|
+
checkedAt: string;
|
|
13
|
+
};
|
|
14
|
+
export type ConnectionChecker = (provider: ProviderId, fresh?: boolean) => Promise<ProviderConnection>;
|
|
15
|
+
export declare function signInFacts(provider: ProviderId, result: ExecResult, now?: Date): ProviderConnection;
|
|
16
|
+
export declare function createConnectionChecker(options?: {
|
|
17
|
+
probe?: typeof run;
|
|
18
|
+
home?: string;
|
|
19
|
+
clock?: () => Date;
|
|
20
|
+
env?: NodeJS.ProcessEnv;
|
|
21
|
+
verify?: (provider: ProviderId, key: string) => Promise<KeyVerdict>;
|
|
22
|
+
}): ConnectionChecker;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/** Non-spending account checks. Only normalized facts leave this module. */
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { run } from "./exec.js";
|
|
4
|
+
import { ALL_CREDENTIAL_ENV, inspectionOf } from "./provider.js";
|
|
5
|
+
import { keyStatus, PROVIDER_KEY_ENV, readAuthMode, readProviderKey, verifyProviderKey } from "./keys.js";
|
|
6
|
+
export function signInFacts(provider, result, now = new Date()) {
|
|
7
|
+
const base = { mode: "subscription", checkedAt: now.toISOString() };
|
|
8
|
+
if (result.notFound)
|
|
9
|
+
return { ...base, state: "not-installed" };
|
|
10
|
+
if (result.timedOut)
|
|
11
|
+
return { ...base, state: "unverified" };
|
|
12
|
+
if (provider === "claude") {
|
|
13
|
+
try {
|
|
14
|
+
const value = JSON.parse(result.stdout);
|
|
15
|
+
if (value?.loggedIn === false && (result.code === 0 || result.code === 1))
|
|
16
|
+
return { ...base, state: "signed-out" };
|
|
17
|
+
if (value?.loggedIn !== true || result.code !== 0)
|
|
18
|
+
return { ...base, state: "unverified" };
|
|
19
|
+
const email = typeof value.email === "string" && value.email.length <= 254 && /^[\x21-\x7e]+$/.test(value.email) && /^[^\s@<>\x00-\x1f\x7f]+@[^\s@<>\x00-\x1f\x7f]+\.[^\s@<>\x00-\x1f\x7f]+$/.test(value.email) ? value.email : undefined;
|
|
20
|
+
const plans = { max: "Max", pro: "Pro", team: "Team", enterprise: "Enterprise" };
|
|
21
|
+
const methods = { "claude.ai": "Claude account", api_key: "API key", bedrock: "Amazon Bedrock", vertex: "Google Vertex AI" };
|
|
22
|
+
const plan = typeof value.subscriptionType === "string" && Object.hasOwn(plans, value.subscriptionType) ? plans[value.subscriptionType] : undefined;
|
|
23
|
+
const method = typeof value.authMethod === "string" && Object.hasOwn(methods, value.authMethod) ? methods[value.authMethod] : undefined;
|
|
24
|
+
return { ...base, state: value.authMethod === "claude.ai" ? "connected" : "unverified", ...(email ? { email } : {}), ...(plan ? { plan } : {}), ...(method ? { method } : {}) };
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return { ...base, state: "unverified" };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (provider === "codex") {
|
|
31
|
+
const text = `${result.stdout}\n${result.stderr}`;
|
|
32
|
+
if (result.code === 0 && /^Logged in using ChatGPT\s*$/m.test(text))
|
|
33
|
+
return { ...base, state: "connected", method: "ChatGPT account" };
|
|
34
|
+
if (result.code === 0 && /^Logged in using an? API key\b/m.test(text))
|
|
35
|
+
return { ...base, state: "unverified", method: "API key; subscription sign-in is not verified" };
|
|
36
|
+
if (result.code === 1 && /^Not logged in\s*$/m.test(text))
|
|
37
|
+
return { ...base, state: "signed-out" };
|
|
38
|
+
}
|
|
39
|
+
return { ...base, state: "unverified" };
|
|
40
|
+
}
|
|
41
|
+
export function createConnectionChecker(options = {}) {
|
|
42
|
+
const probe = options.probe ?? run;
|
|
43
|
+
const verify = options.verify ?? ((provider, key) => verifyProviderKey(provider, key));
|
|
44
|
+
const home = options.home ?? homedir();
|
|
45
|
+
const clock = options.clock ?? (() => new Date());
|
|
46
|
+
const cache = new Map();
|
|
47
|
+
const pending = new Map();
|
|
48
|
+
return async (provider, fresh = false) => {
|
|
49
|
+
const mode = readAuthMode(provider, home);
|
|
50
|
+
const keyFacts = keyStatus(provider, home);
|
|
51
|
+
const ambient = !!(options.env ?? process.env)[PROVIDER_KEY_ENV[provider]];
|
|
52
|
+
const key = JSON.stringify([provider, mode, keyFacts.set, keyFacts.updatedAt, ambient]);
|
|
53
|
+
const now = clock();
|
|
54
|
+
const existing = cache.get(provider);
|
|
55
|
+
if (!fresh && existing?.key === key && existing.until > now.getTime())
|
|
56
|
+
return existing.value;
|
|
57
|
+
const inFlight = pending.get(key);
|
|
58
|
+
if (inFlight)
|
|
59
|
+
return inFlight;
|
|
60
|
+
const check = (async () => {
|
|
61
|
+
if (mode === "api-key") {
|
|
62
|
+
// A saved key is tested only when asked (Check again, or just after it is saved): one small request to the provider, never a model.
|
|
63
|
+
const stored = fresh && keyFacts.set ? readProviderKey(provider, home) : null;
|
|
64
|
+
if (stored === null)
|
|
65
|
+
return { state: keyFacts.set || ambient ? "key-present" : "missing-key", mode, checkedAt: now.toISOString() };
|
|
66
|
+
const verdict = await verify(provider, stored);
|
|
67
|
+
return { state: verdict.ok ? "key-works" : verdict.reason === "rejected" ? "key-refused" : "key-present", mode, checkedAt: clock().toISOString(), verdict };
|
|
68
|
+
}
|
|
69
|
+
const facts = inspectionOf(provider);
|
|
70
|
+
const identityProbe = provider === "claude" ? ["auth", "status", "--json"] : facts.identityProbe;
|
|
71
|
+
if (identityProbe === null)
|
|
72
|
+
return { state: "unverified", mode, checkedAt: now.toISOString() };
|
|
73
|
+
try {
|
|
74
|
+
// Same subscription credential stripping as provider invocations.
|
|
75
|
+
// No model prompt, repository scripts, or stored API keys are used.
|
|
76
|
+
const result = await probe(facts.binary, [...identityProbe], { cwd: home, timeoutMs: 5000, maxBuffer: 32 * 1024, omitEnv: ALL_CREDENTIAL_ENV });
|
|
77
|
+
return signInFacts(provider, result, clock());
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return { state: "unverified", mode, checkedAt: clock().toISOString() };
|
|
81
|
+
}
|
|
82
|
+
})();
|
|
83
|
+
pending.set(key, check);
|
|
84
|
+
try {
|
|
85
|
+
const value = await check;
|
|
86
|
+
// Only cache against the same credential mode that began this check.
|
|
87
|
+
// A slow subscription probe must not overwrite a newer API-key result.
|
|
88
|
+
const currentKeyFacts = keyStatus(provider, home);
|
|
89
|
+
const currentKey = JSON.stringify([provider, readAuthMode(provider, home), currentKeyFacts.set, currentKeyFacts.updatedAt, !!(options.env ?? process.env)[PROVIDER_KEY_ENV[provider]]]);
|
|
90
|
+
if (currentKey === key)
|
|
91
|
+
cache.set(provider, { key, until: value.verdict !== undefined ? Number.POSITIVE_INFINITY : clock().getTime() + 30_000, value });
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
pending.delete(key);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subscription limits (v105): how much of each plan's usage windows is used,
|
|
3
|
+
* as the provider itself says. A subscription costs nothing per run, so these
|
|
4
|
+
* windows (not dollars) are what bind it. Claude says on every turn (a
|
|
5
|
+
* `rate_limit_event` in its stream: the 5-hour and weekly windows); Codex
|
|
6
|
+
* answers when asked (its app server's `account/rateLimits/read`, which spends
|
|
7
|
+
* nothing). The latest reading of each window is kept; the Tasks page shows
|
|
8
|
+
* them beside the monthly budgets.
|
|
9
|
+
*/
|
|
10
|
+
import type { Billing } from "./spend.js";
|
|
11
|
+
export type LimitWindow = {
|
|
12
|
+
window: string;
|
|
13
|
+
usedPercent: number;
|
|
14
|
+
windowMinutes: number | null;
|
|
15
|
+
resetsAt: string | null;
|
|
16
|
+
reached: boolean;
|
|
17
|
+
};
|
|
18
|
+
/** A provider's reading: its windows (all of them, or `partial` when it named only one), and how it was seen billing. */
|
|
19
|
+
export type LimitReading = {
|
|
20
|
+
provider: "claude" | "codex";
|
|
21
|
+
plan: string | null;
|
|
22
|
+
windows: LimitWindow[];
|
|
23
|
+
partial?: boolean;
|
|
24
|
+
billing?: Billing;
|
|
25
|
+
};
|
|
26
|
+
export declare const record: (value: unknown) => Record<string, unknown> | null;
|
|
27
|
+
/** A Claude stream event's limits, or null when it isn't a `rate_limit_event` or says nothing usable. */
|
|
28
|
+
export declare function claudeLimitsOf(event: unknown): LimitReading | null;
|
|
29
|
+
/** Codex's `account/rateLimits/read` answer as a reading, or null. */
|
|
30
|
+
export declare function codexLimitsOf(result: unknown): LimitReading | null;
|
|
31
|
+
export declare function pushLimitSink(next: (reading: LimitReading) => void): () => void;
|
|
32
|
+
/** A reading from a stream; never throws into the run that carried it. */
|
|
33
|
+
export declare function noteLimits(reading: LimitReading | null): void;
|
|
34
|
+
/** A window in words: "5-hour", "Weekly", "Weekly (Opus)". */
|
|
35
|
+
export declare function windowLabel(window: string, minutes: number | null): string;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
const WINDOW_NAME = /^[a-z][a-z0-9_]{0,39}$/;
|
|
2
|
+
const CLAUDE_MINUTES = { five_hour: 300, seven_day: 10_080, seven_day_opus: 10_080, seven_day_sonnet: 10_080 };
|
|
3
|
+
const finite = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
4
|
+
const percent = (value) => Math.max(0, Math.min(100, Math.round(value * 10) / 10));
|
|
5
|
+
/** An epoch (seconds) as an ISO time, or null when it isn't a plausible one. */
|
|
6
|
+
const epoch = (value) => {
|
|
7
|
+
const seconds = finite(value);
|
|
8
|
+
return seconds === null || seconds < 1_000_000_000 || seconds > 10_000_000_000 ? null : new Date(seconds * 1000).toISOString();
|
|
9
|
+
};
|
|
10
|
+
export const record = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
11
|
+
/** A Claude stream event's limits, or null when it isn't a `rate_limit_event` or says nothing usable. */
|
|
12
|
+
export function claudeLimitsOf(event) {
|
|
13
|
+
const body = record(event);
|
|
14
|
+
if (body === null || body["type"] !== "rate_limit_event")
|
|
15
|
+
return null;
|
|
16
|
+
const info = record(body["rate_limit_info"]);
|
|
17
|
+
if (info === null)
|
|
18
|
+
return null;
|
|
19
|
+
const rejected = info["status"] === "rejected";
|
|
20
|
+
const current = typeof info["rateLimitType"] === "string" ? info["rateLimitType"] : null;
|
|
21
|
+
const windows = [];
|
|
22
|
+
const unified = record(info["unifiedWindows"]);
|
|
23
|
+
for (const [name, raw] of Object.entries(unified ?? {}).slice(0, 8)) {
|
|
24
|
+
const one = record(raw);
|
|
25
|
+
const used = finite(one?.["utilization"]);
|
|
26
|
+
if (!WINDOW_NAME.test(name) || one === null || used === null)
|
|
27
|
+
continue;
|
|
28
|
+
windows.push({ window: name, usedPercent: percent(used * 100), windowMinutes: Object.hasOwn(CLAUDE_MINUTES, name) ? CLAUDE_MINUTES[name] : null, resetsAt: epoch(one["resetsAt"]), reached: rejected && name === current });
|
|
29
|
+
}
|
|
30
|
+
if (windows.length === 0 && current !== null && WINDOW_NAME.test(current)) {
|
|
31
|
+
// An older CLI names only the window it's in; its use is known only when it's spent.
|
|
32
|
+
const used = finite(info["utilization"]);
|
|
33
|
+
if (used !== null || rejected)
|
|
34
|
+
windows.push({ window: current, usedPercent: rejected ? 100 : percent(used * 100), windowMinutes: Object.hasOwn(CLAUDE_MINUTES, current) ? CLAUDE_MINUTES[current] : null, resetsAt: epoch(info["resetsAt"]), reached: rejected });
|
|
35
|
+
// Only this window is known: the others keep their last reading.
|
|
36
|
+
return windows.length === 0 ? null : { provider: "claude", plan: null, windows, partial: true, billing: "subscription" };
|
|
37
|
+
}
|
|
38
|
+
// A plan's windows are a plan's: this turn ran on the sign-in.
|
|
39
|
+
return windows.length === 0 ? null : { provider: "claude", plan: null, windows, billing: "subscription" };
|
|
40
|
+
}
|
|
41
|
+
/** Codex's `account/rateLimits/read` answer as a reading, or null. */
|
|
42
|
+
export function codexLimitsOf(result) {
|
|
43
|
+
const limits = record(record(result)?.["rateLimits"]);
|
|
44
|
+
if (limits === null)
|
|
45
|
+
return null;
|
|
46
|
+
// Codex names why it stopped ("rate_limit_reached", "…usage_limit_reached"), not which window: the fullest one.
|
|
47
|
+
const reachedType = typeof limits["rateLimitReachedType"] === "string" ? limits["rateLimitReachedType"] : null;
|
|
48
|
+
const windows = [];
|
|
49
|
+
for (const slot of ["primary", "secondary"]) {
|
|
50
|
+
const one = record(limits[slot]);
|
|
51
|
+
const used = finite(one?.["usedPercent"]);
|
|
52
|
+
if (one === null || used === null)
|
|
53
|
+
continue;
|
|
54
|
+
const minutes = finite(one["windowDurationMins"]);
|
|
55
|
+
const name = minutes === 300 ? "five_hour" : minutes === 10_080 ? "seven_day" : minutes !== null && minutes > 0 ? `window_${Math.round(minutes)}m` : slot;
|
|
56
|
+
windows.push({ window: name, usedPercent: percent(used), windowMinutes: minutes === null ? null : Math.round(minutes), resetsAt: epoch(one["resetsAt"]), reached: used >= 100 });
|
|
57
|
+
}
|
|
58
|
+
if (reachedType !== null && windows.length > 0)
|
|
59
|
+
windows.reduce((fullest, one) => one.usedPercent > fullest.usedPercent ? one : fullest).reached = true;
|
|
60
|
+
const plan = typeof limits["planType"] === "string" && /^[a-z0-9_-]{1,40}$/i.test(limits["planType"]) ? limits["planType"] : null;
|
|
61
|
+
return windows.length === 0 ? null : { provider: "codex", plan, windows };
|
|
62
|
+
}
|
|
63
|
+
/** Where readings go: the store, in any process that runs Claude. The latest one set wins; one that's done removes
|
|
64
|
+
* only itself, so a command that ends inside a longer one leaves the longer one's in place. Unset, readings drop. */
|
|
65
|
+
const sinks = [];
|
|
66
|
+
export function pushLimitSink(next) {
|
|
67
|
+
sinks.push(next);
|
|
68
|
+
return () => { const at = sinks.lastIndexOf(next); if (at !== -1)
|
|
69
|
+
sinks.splice(at, 1); };
|
|
70
|
+
}
|
|
71
|
+
/** A reading from a stream; never throws into the run that carried it. */
|
|
72
|
+
export function noteLimits(reading) {
|
|
73
|
+
const sink = sinks[sinks.length - 1];
|
|
74
|
+
if (reading === null || sink === undefined)
|
|
75
|
+
return;
|
|
76
|
+
try {
|
|
77
|
+
sink(reading);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// A reading that can't be kept must not touch the turn.
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** A window in words: "5-hour", "Weekly", "Weekly (Opus)". */
|
|
84
|
+
export function windowLabel(window, minutes) {
|
|
85
|
+
if (window === "five_hour")
|
|
86
|
+
return "5-hour";
|
|
87
|
+
if (window === "seven_day")
|
|
88
|
+
return "Weekly";
|
|
89
|
+
const model = /^seven_day_([a-z]+)$/.exec(window);
|
|
90
|
+
if (model !== null)
|
|
91
|
+
return `Weekly (${model[1].charAt(0).toUpperCase()}${model[1].slice(1)})`;
|
|
92
|
+
if (minutes !== null)
|
|
93
|
+
return minutes % 1440 === 0 ? `${minutes / 1440}-day` : minutes % 60 === 0 ? `${minutes / 60}-hour` : `${minutes}-minute`;
|
|
94
|
+
return window.replace(/_/g, " ");
|
|
95
|
+
}
|