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,108 @@
|
|
|
1
|
+
import type { ToolCaller } from "./flow-actions.js";
|
|
2
|
+
import { type ProjectTool, type ToolSpec } from "./project-tools.js";
|
|
3
|
+
import type { Store, TeammateCallRow, TeammateGrantRow, TeammateRow, ToolActionInfo, ToolRule } from "./store.js";
|
|
4
|
+
/** Lists what a tool offers; injectable so tests never start a server. */
|
|
5
|
+
export type ToolLister = (spec: ToolSpec, values: Record<string, string>) => Promise<{
|
|
6
|
+
ok: true;
|
|
7
|
+
actions: ToolActionInfo[];
|
|
8
|
+
} | {
|
|
9
|
+
ok: false;
|
|
10
|
+
problem: string;
|
|
11
|
+
}>;
|
|
12
|
+
export type ToolIo = {
|
|
13
|
+
callTool?: ToolCaller;
|
|
14
|
+
listTools?: ToolLister;
|
|
15
|
+
toolHome?: string;
|
|
16
|
+
};
|
|
17
|
+
/** Actions whose names say they only read start as "do it"; everything else asks first until its manager says otherwise. */
|
|
18
|
+
export declare const READ_VERB: RegExp;
|
|
19
|
+
export declare const defaultRule: (action: Pick<ToolActionInfo, "name" | "readOnly">) => ToolRule;
|
|
20
|
+
type Done = {
|
|
21
|
+
ok: true;
|
|
22
|
+
said: string;
|
|
23
|
+
} | {
|
|
24
|
+
ok: false;
|
|
25
|
+
said: string;
|
|
26
|
+
};
|
|
27
|
+
/** How a turn names an action: "shop.refund_order". */
|
|
28
|
+
export declare const callName: (tool: string, action: string) => string;
|
|
29
|
+
/** A fresh listing merged into a grant: rules already set are kept, new actions get the default, and gone ones drop out. */
|
|
30
|
+
export declare function withActions(rules: Record<string, ToolRule>, actions: readonly ToolActionInfo[]): {
|
|
31
|
+
actions: ToolActionInfo[];
|
|
32
|
+
rules: Record<string, ToolRule>;
|
|
33
|
+
};
|
|
34
|
+
/** The rule that applies to one call with this input, and why, in words. */
|
|
35
|
+
export declare function ruleFor(grant: Pick<TeammateGrantRow, "actions" | "rules">, action: string, input: Record<string, unknown>): {
|
|
36
|
+
use: ToolRule["use"];
|
|
37
|
+
why: string;
|
|
38
|
+
};
|
|
39
|
+
/** A rule in words, for the teammate's turn and its page. */
|
|
40
|
+
export declare function ruleWords(rule: ToolRule): string;
|
|
41
|
+
/** Number fields an action's input declares: what a limit can be set on. */
|
|
42
|
+
export declare function numberFields(action: Pick<ToolActionInfo, "input">): string[];
|
|
43
|
+
/** What's wrong with an input, by what the action declares: its required fields and their simple types. */
|
|
44
|
+
export declare function inputProblem(action: Pick<ToolActionInfo, "input">, input: Record<string, unknown>): string | null;
|
|
45
|
+
/** A call in a few words: "shop → refund_order · order 1044 · amount 400". */
|
|
46
|
+
export declare function callWords(tool: string, action: string, input: Record<string, unknown>, cap?: number): string;
|
|
47
|
+
/** An action as a turn is offered it. */
|
|
48
|
+
export type OfferedTool = {
|
|
49
|
+
name: string;
|
|
50
|
+
about: string;
|
|
51
|
+
input: string;
|
|
52
|
+
rule: string;
|
|
53
|
+
};
|
|
54
|
+
/** What a teammate may use now: its grants' actions on tools the project still has, "never" left out. */
|
|
55
|
+
export declare function offeredTools(store: Store, mate: TeammateRow): OfferedTool[];
|
|
56
|
+
/** Before a turn: re-list tools whose listing is old (or never happened), so the turn sees what they offer today. A tool that can't be reached keeps its last listing. */
|
|
57
|
+
export declare function refreshGrants(store: Store, mate: TeammateRow, now: Date, io: ToolIo): Promise<void>;
|
|
58
|
+
/** Let a teammate use one of the project's tools. Its actions start at their defaults: reading is free, everything else asks first. */
|
|
59
|
+
export declare function grantTool(store: Store, mate: TeammateRow, tool: string, by: string, now: Date, io?: ToolIo): Promise<Done>;
|
|
60
|
+
/** A grant from what the tool offers (or, not reachable now, the names its last test found). */
|
|
61
|
+
export declare function grantListed(store: Store, mate: TeammateRow, tool: ProjectTool, actions: ToolActionInfo[] | null, by: string, now: Date): Done;
|
|
62
|
+
export declare function revokeTool(store: Store, mate: TeammateRow, tool: string, by: string, now?: Date): Done;
|
|
63
|
+
/** Check one rule: an action the tool offers, a known use, and a limit on one of its number fields. */
|
|
64
|
+
export declare function checkRule(grant: Pick<TeammateGrantRow, "tool" | "actions">, action: string, rule: {
|
|
65
|
+
use: unknown;
|
|
66
|
+
limit?: {
|
|
67
|
+
field: unknown;
|
|
68
|
+
over: unknown;
|
|
69
|
+
} | null;
|
|
70
|
+
undo?: unknown;
|
|
71
|
+
}): {
|
|
72
|
+
ok: true;
|
|
73
|
+
rule: ToolRule;
|
|
74
|
+
} | {
|
|
75
|
+
ok: false;
|
|
76
|
+
said: string;
|
|
77
|
+
};
|
|
78
|
+
/** Set the rules for some of a granted tool's actions; the others keep theirs. */
|
|
79
|
+
export declare function setToolRules(store: Store, mate: TeammateRow, tool: string, changes: Record<string, {
|
|
80
|
+
use: unknown;
|
|
81
|
+
limit?: {
|
|
82
|
+
field: unknown;
|
|
83
|
+
over: unknown;
|
|
84
|
+
} | null;
|
|
85
|
+
undo?: unknown;
|
|
86
|
+
}>, by: string, now: Date): Done;
|
|
87
|
+
/**
|
|
88
|
+
* Make one call now: a free one, or one a person approved (exactly as they
|
|
89
|
+
* saw it). What the tool said is kept on the receipt, secrets scrubbed; a
|
|
90
|
+
* tool that says it failed is an answer the teammate reads, not trouble.
|
|
91
|
+
*/
|
|
92
|
+
export declare function makeCall(store: Store, call: TeammateCallRow, repo: string, io: ToolIo, now: Date, options?: {
|
|
93
|
+
byPerson?: boolean;
|
|
94
|
+
}): Promise<TeammateCallRow>;
|
|
95
|
+
/** A receipt in words: what happened to the call. */
|
|
96
|
+
export declare function callOutcome(call: TeammateCallRow): string;
|
|
97
|
+
/** A receipt as a person reads it on the card: what happened, and who decided. */
|
|
98
|
+
export declare function receiptWords(store: Store, call: TeammateCallRow): string;
|
|
99
|
+
/** The Tools section's form, read into rule changes: every action the grant knows. */
|
|
100
|
+
export declare function rulesFromForm(grant: Pick<TeammateGrantRow, "actions">, field: (key: string) => string | null): Record<string, {
|
|
101
|
+
use: unknown;
|
|
102
|
+
limit?: {
|
|
103
|
+
field: unknown;
|
|
104
|
+
over: unknown;
|
|
105
|
+
};
|
|
106
|
+
undo?: unknown;
|
|
107
|
+
}>;
|
|
108
|
+
export {};
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The tools a teammate may use (v94), and its rule for each of their actions.
|
|
3
|
+
*
|
|
4
|
+
* A teammate never calls a tool itself. On its turn it may ask for one call
|
|
5
|
+
* ("use_tool": which action, with what input, and why), and Toolroll
|
|
6
|
+
* checks the rule its manager set for that action:
|
|
7
|
+
*
|
|
8
|
+
* - do it: the call is made and its answer goes back to the teammate, whose
|
|
9
|
+
* turn goes on;
|
|
10
|
+
* - ask first: the exact call goes to the zone's person, in their chat app
|
|
11
|
+
* and on the card. Approve makes exactly that call; Deny doesn't; words
|
|
12
|
+
* tell the teammate what to do instead;
|
|
13
|
+
* - never: the action isn't offered at all.
|
|
14
|
+
*
|
|
15
|
+
* "Do it" can ask first above a number in the input ("refunds up to $50"),
|
|
16
|
+
* so a limit holds in code, not only in the soul file's words. Every call,
|
|
17
|
+
* made or not, is a receipt on the card and on the teammate's page.
|
|
18
|
+
*/
|
|
19
|
+
import { redactSecretLines, scanForSecrets } from "./evidence.js";
|
|
20
|
+
import { scrubSecrets } from "./flow-secrets.js";
|
|
21
|
+
import { toolRefusal } from "./policy.js";
|
|
22
|
+
import { callProjectTool, listProjectToolActions, projectToolsOf, readToolSecrets } from "./project-tools.js";
|
|
23
|
+
import { ALL_CREDENTIAL_ENV } from "./provider.js";
|
|
24
|
+
/** Actions whose names say they only read start as "do it"; everything else asks first until its manager says otherwise. */
|
|
25
|
+
export const READ_VERB = /^(get|list|search|find|read|fetch|lookup|look_up|query|show|describe|count|check|view|retrieve)([_.-]|$)/i;
|
|
26
|
+
export const defaultRule = (action) => ({ use: action.readOnly || READ_VERB.test(action.name) ? "free" : "ask" });
|
|
27
|
+
/** How long a tool's listing is trusted before a turn lists it again. */
|
|
28
|
+
const LISTING_MS = 6 * 60 * 60_000;
|
|
29
|
+
const RESULT_CHARS = 6000;
|
|
30
|
+
/** How a turn names an action: "shop.refund_order". */
|
|
31
|
+
export const callName = (tool, action) => `${tool}.${action}`;
|
|
32
|
+
/** A fresh listing merged into a grant: rules already set are kept, new actions get the default, and gone ones drop out. */
|
|
33
|
+
export function withActions(rules, actions) {
|
|
34
|
+
return { actions: [...actions], rules: Object.fromEntries(actions.map(one => [one.name, rules[one.name] ?? defaultRule(one)])) };
|
|
35
|
+
}
|
|
36
|
+
const numberOf = (value) => typeof value === "number" && Number.isFinite(value) ? value
|
|
37
|
+
: typeof value === "string" && /^\s*-?\$?\d+(\.\d+)?\s*$/.test(value) ? Number(value.replace(/[$\s]/g, "")) : null;
|
|
38
|
+
/** The rule that applies to one call with this input, and why, in words. */
|
|
39
|
+
export function ruleFor(grant, action, input) {
|
|
40
|
+
const info = grant.actions.find(one => one.name === action);
|
|
41
|
+
const rule = grant.rules[action] ?? (info === undefined ? { use: "never" } : defaultRule(info));
|
|
42
|
+
if (info === undefined || rule.use === "never")
|
|
43
|
+
return { use: "never", why: `The rules never allow ${action}.` };
|
|
44
|
+
if (rule.use === "ask")
|
|
45
|
+
return { use: "ask", why: `${action} needs a person's approval each time.` };
|
|
46
|
+
if (rule.limit !== undefined) {
|
|
47
|
+
const value = numberOf(input[rule.limit.field]);
|
|
48
|
+
if (value === null)
|
|
49
|
+
return { use: "ask", why: `${action} is free only up to ${rule.limit.field} ${rule.limit.over}, and this call gives no ${rule.limit.field}.` };
|
|
50
|
+
if (value > rule.limit.over)
|
|
51
|
+
return { use: "ask", why: `${rule.limit.field} ${value} is over the limit of ${rule.limit.over}.` };
|
|
52
|
+
}
|
|
53
|
+
return { use: "free", why: "" };
|
|
54
|
+
}
|
|
55
|
+
/** A rule in words, for the teammate's turn and its page. */
|
|
56
|
+
export function ruleWords(rule) {
|
|
57
|
+
if (rule.use === "never")
|
|
58
|
+
return "never";
|
|
59
|
+
if (rule.use === "ask")
|
|
60
|
+
return "a person approves each call first";
|
|
61
|
+
return rule.limit === undefined ? "use freely" : `use freely up to ${rule.limit.field} ${rule.limit.over}; above that, a person approves first`;
|
|
62
|
+
}
|
|
63
|
+
/** Number fields an action's input declares: what a limit can be set on. */
|
|
64
|
+
export function numberFields(action) {
|
|
65
|
+
const properties = (action.input?.["properties"] ?? {});
|
|
66
|
+
return Object.entries(properties).filter(([, one]) => one !== null && typeof one === "object" && (one.type === "number" || one.type === "integer")).map(([name]) => name).slice(0, 20);
|
|
67
|
+
}
|
|
68
|
+
/** What's wrong with an input, by what the action declares: its required fields and their simple types. */
|
|
69
|
+
export function inputProblem(action, input) {
|
|
70
|
+
const schema = action.input;
|
|
71
|
+
if (schema === null)
|
|
72
|
+
return null;
|
|
73
|
+
const properties = (schema["properties"] ?? {});
|
|
74
|
+
const required = Array.isArray(schema["required"]) ? schema["required"].filter((one) => typeof one === "string") : [];
|
|
75
|
+
const missing = required.filter(one => input[one] === undefined || input[one] === null || input[one] === "");
|
|
76
|
+
if (missing.length > 0)
|
|
77
|
+
return `It needs ${missing.join(", ")}.`;
|
|
78
|
+
for (const [name, value] of Object.entries(input)) {
|
|
79
|
+
const type = properties[name]?.type;
|
|
80
|
+
const fits = type === undefined || typeof type !== "string" ? true
|
|
81
|
+
: type === "string" ? typeof value === "string" : type === "number" ? numberOf(value) !== null : type === "integer" ? Number.isInteger(numberOf(value))
|
|
82
|
+
: type === "boolean" ? typeof value === "boolean" : type === "array" ? Array.isArray(value) : type === "object" ? value !== null && typeof value === "object" && !Array.isArray(value) : true;
|
|
83
|
+
if (!fits)
|
|
84
|
+
return `${name} should be ${type === "integer" ? "a whole number" : `a ${type}`}.`;
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
/** A call in a few words: "shop → refund_order · order 1044 · amount 400". */
|
|
89
|
+
export function callWords(tool, action, input, cap = 300) {
|
|
90
|
+
const parts = Object.entries(input).map(([key, value]) => `${key} ${typeof value === "string" ? value.replace(/\s+/g, " ") : JSON.stringify(value)}`);
|
|
91
|
+
const line = `${tool} → ${action}${parts.length === 0 ? "" : ` · ${parts.join(" · ")}`}`;
|
|
92
|
+
return line.length <= cap ? line : `${line.slice(0, cap - 1)}…`;
|
|
93
|
+
}
|
|
94
|
+
/** What a teammate may use now: its grants' actions on tools the project still has, "never" left out. */
|
|
95
|
+
export function offeredTools(store, mate) {
|
|
96
|
+
const present = new Set(projectToolsOf(store, mate.repo).map(one => one.name));
|
|
97
|
+
// Sprint 8: a tool the organisation policy doesn't allow isn't offered.
|
|
98
|
+
const policy = store.orgPolicy();
|
|
99
|
+
return store.teammateGrants(mate.id).filter(grant => present.has(grant.tool) && toolRefusal(policy, grant.tool) === null).flatMap(grant => grant.actions.flatMap(action => {
|
|
100
|
+
const rule = grant.rules[action.name] ?? defaultRule(action);
|
|
101
|
+
if (rule.use === "never")
|
|
102
|
+
return [];
|
|
103
|
+
const input = action.input === null ? "any" : JSON.stringify({ properties: action.input["properties"] ?? {}, required: action.input["required"] ?? [] });
|
|
104
|
+
return [{ name: callName(grant.tool, action.name), about: action.about, input: input.length > 1500 ? `${input.slice(0, 1499)}…` : input, rule: ruleWords(rule) }];
|
|
105
|
+
})).slice(0, 40);
|
|
106
|
+
}
|
|
107
|
+
/** Before a turn: re-list tools whose listing is old (or never happened), so the turn sees what they offer today. A tool that can't be reached keeps its last listing. */
|
|
108
|
+
export async function refreshGrants(store, mate, now, io) {
|
|
109
|
+
const tools = projectToolsOf(store, mate.repo);
|
|
110
|
+
for (const grant of store.teammateGrants(mate.id)) {
|
|
111
|
+
if (grant.listedAt !== null && now.getTime() - Date.parse(grant.listedAt) < LISTING_MS)
|
|
112
|
+
continue;
|
|
113
|
+
const tool = tools.find(one => one.name === grant.tool);
|
|
114
|
+
if (tool === undefined)
|
|
115
|
+
continue;
|
|
116
|
+
const listed = await listed_(tool, mate.repo, io);
|
|
117
|
+
if (!listed.ok)
|
|
118
|
+
continue;
|
|
119
|
+
store.saveTeammateGrant({ teammate: mate.id, tool: grant.tool, ...withActions(grant.rules, listed.actions), listedAt: now.toISOString() }, grant.updatedBy, now);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
const listed_ = (tool, repo, io) => (io.listTools ?? ((spec, values) => listProjectToolActions(spec, values, { timeoutMs: 60_000, omitEnv: ALL_CREDENTIAL_ENV })))(tool.spec, readToolSecrets(repo, tool.name, io.toolHome));
|
|
123
|
+
/** Names only, from the tool's last test: what a grant starts with when it can't be listed right now. */
|
|
124
|
+
const namesOnly = (tool) => (tool.lastTest?.tools ?? []).map(name => ({ name, about: "", input: null, readOnly: false }));
|
|
125
|
+
/** Let a teammate use one of the project's tools. Its actions start at their defaults: reading is free, everything else asks first. */
|
|
126
|
+
export async function grantTool(store, mate, tool, by, now, io = {}) {
|
|
127
|
+
const found = projectToolsOf(store, mate.repo).find(one => one.name === tool);
|
|
128
|
+
if (found === undefined)
|
|
129
|
+
return { ok: false, said: `This project has no tool called ${tool}. Add it on the Tools page first.` };
|
|
130
|
+
if (store.teammateGrant(mate.id, tool) !== null)
|
|
131
|
+
return { ok: true, said: `It can already use ${tool}.` };
|
|
132
|
+
const listed = await listed_(found, mate.repo, io);
|
|
133
|
+
return grantListed(store, mate, found, listed.ok ? listed.actions : null, by, now);
|
|
134
|
+
}
|
|
135
|
+
/** A grant from what the tool offers (or, not reachable now, the names its last test found). */
|
|
136
|
+
export function grantListed(store, mate, tool, actions, by, now) {
|
|
137
|
+
const offered = actions ?? namesOnly(tool);
|
|
138
|
+
if (offered.length === 0)
|
|
139
|
+
return { ok: false, said: `${tool.name} didn't say what it can do. Test it on the Tools page, then try again.` };
|
|
140
|
+
store.saveTeammateGrant({ teammate: mate.id, tool: tool.name, ...withActions({}, offered), listedAt: actions === null ? null : now.toISOString() }, by, now);
|
|
141
|
+
const free = offered.filter(one => defaultRule(one).use === "free").length;
|
|
142
|
+
return { ok: true, said: `It can use ${tool.name} now: ${free} of its ${offered.length} action${offered.length === 1 ? "" : "s"} freely (the ones that only read), and the rest after a person approves each call. Change that under Tools.` };
|
|
143
|
+
}
|
|
144
|
+
export function revokeTool(store, mate, tool, by, now = new Date()) {
|
|
145
|
+
for (const call of store.teammateCallsOf(mate.id, 200).filter(one => one.tool === tool && one.state === "asked")) {
|
|
146
|
+
store.moveTeammateCall(call.id, ["asked"], { state: "refused", result: `It can't use ${tool} any more.` }, new Date());
|
|
147
|
+
const question = store.teammateQuestionForCall(call.id);
|
|
148
|
+
if (question !== null)
|
|
149
|
+
store.dropTeammateQuestion(question.id, new Date());
|
|
150
|
+
}
|
|
151
|
+
return store.dropTeammateGrant(mate.id, tool, by, now) ? { ok: true, said: `It can't use ${tool} any more.` } : { ok: true, said: `It wasn't using ${tool}.` };
|
|
152
|
+
}
|
|
153
|
+
/** Check one rule: an action the tool offers, a known use, and a limit on one of its number fields. */
|
|
154
|
+
export function checkRule(grant, action, rule) {
|
|
155
|
+
const info = grant.actions.find(one => one.name === action);
|
|
156
|
+
if (info === undefined)
|
|
157
|
+
return { ok: false, said: `${grant.tool} has no action called ${action}. Its actions: ${grant.actions.map(one => one.name).join(", ")}.` };
|
|
158
|
+
if (rule.use !== "free" && rule.use !== "ask" && rule.use !== "never")
|
|
159
|
+
return { ok: false, said: "Choose do it, ask first or never." };
|
|
160
|
+
// v97: the action that undoes this one, when a person presses Undo on its receipt.
|
|
161
|
+
const undo = typeof rule.undo === "string" && rule.undo !== "" ? rule.undo : null;
|
|
162
|
+
if (undo !== null && (undo === action || !grant.actions.some(one => one.name === undo)))
|
|
163
|
+
return { ok: false, said: `${grant.tool} has no other action called ${undo} to undo ${action} with.` };
|
|
164
|
+
const withUndo = (made) => ({ ok: true, rule: undo === null ? made : { ...made, undo } });
|
|
165
|
+
if (rule.use !== "free" || rule.limit === undefined || rule.limit === null)
|
|
166
|
+
return withUndo({ use: rule.use });
|
|
167
|
+
const field = String(rule.limit.field ?? "");
|
|
168
|
+
const over = numberOf(rule.limit.over);
|
|
169
|
+
if (field === "")
|
|
170
|
+
return { ok: false, said: `Choose which number of ${action} the limit is on.` };
|
|
171
|
+
if (info.input !== null && !numberFields(info).includes(field))
|
|
172
|
+
return { ok: false, said: `${action} has no number called ${field}.` };
|
|
173
|
+
if (over === null || over < 0 || over > 1e12)
|
|
174
|
+
return { ok: false, said: "A limit is a number, 0 or more." };
|
|
175
|
+
return withUndo({ use: "free", limit: { field, over } });
|
|
176
|
+
}
|
|
177
|
+
/** Set the rules for some of a granted tool's actions; the others keep theirs. */
|
|
178
|
+
export function setToolRules(store, mate, tool, changes, by, now) {
|
|
179
|
+
const grant = store.teammateGrant(mate.id, tool);
|
|
180
|
+
if (grant === null)
|
|
181
|
+
return { ok: false, said: `It doesn't use ${tool}. Let it use ${tool} first.` };
|
|
182
|
+
const rules = { ...grant.rules };
|
|
183
|
+
for (const [action, change] of Object.entries(changes)) {
|
|
184
|
+
const checked = checkRule(grant, action, change);
|
|
185
|
+
if (!checked.ok)
|
|
186
|
+
return { ok: false, said: checked.said };
|
|
187
|
+
rules[action] = checked.rule;
|
|
188
|
+
}
|
|
189
|
+
store.saveTeammateGrant({ teammate: mate.id, tool, actions: grant.actions, rules }, by, now);
|
|
190
|
+
return { ok: true, said: "Saved. Its next turn uses these rules." };
|
|
191
|
+
}
|
|
192
|
+
const blank = (text) => redactSecretLines(text, scanForSecrets(text));
|
|
193
|
+
/**
|
|
194
|
+
* Make one call now: a free one, or one a person approved (exactly as they
|
|
195
|
+
* saw it). What the tool said is kept on the receipt, secrets scrubbed; a
|
|
196
|
+
* tool that says it failed is an answer the teammate reads, not trouble.
|
|
197
|
+
*/
|
|
198
|
+
export async function makeCall(store, call, repo, io, now, options = {}) {
|
|
199
|
+
// Its rules are read again at the moment of the call: a tool taken away, or an action set to never, since it was approved stops it.
|
|
200
|
+
// (A person's own undo (v97) needs the tool still granted, not the teammate's rule for that action.)
|
|
201
|
+
const grant = store.teammateGrant(call.teammate, call.tool);
|
|
202
|
+
if (grant === null || (options.byPerson !== true && ruleFor(grant, call.action, call.input).use === "never")) {
|
|
203
|
+
store.moveTeammateCall(call.id, ["approved", "running"], { state: "refused", result: "Its rules changed before the call was made." }, now);
|
|
204
|
+
return store.teammateCall(call.id);
|
|
205
|
+
}
|
|
206
|
+
// Sprint 8: nor does a call to a tool the organisation policy doesn't allow (a person's undo included).
|
|
207
|
+
const disallowed = toolRefusal(store.orgPolicy(), call.tool);
|
|
208
|
+
if (disallowed !== null) {
|
|
209
|
+
store.moveTeammateCall(call.id, ["approved", "running"], { state: "refused", result: disallowed }, now);
|
|
210
|
+
return store.teammateCall(call.id);
|
|
211
|
+
}
|
|
212
|
+
if (call.state !== "running" && !store.moveTeammateCall(call.id, ["approved"], { state: "running" }, now))
|
|
213
|
+
return store.teammateCall(call.id);
|
|
214
|
+
const tool = projectToolsOf(store, repo).find(one => one.name === call.tool);
|
|
215
|
+
if (tool === undefined) {
|
|
216
|
+
store.moveTeammateCall(call.id, ["running"], { state: "failed", result: `There's no tool called ${call.tool} in this project any more.` }, now);
|
|
217
|
+
return store.teammateCall(call.id);
|
|
218
|
+
}
|
|
219
|
+
const values = readToolSecrets(repo, tool.name, io.toolHome);
|
|
220
|
+
let answer;
|
|
221
|
+
try {
|
|
222
|
+
answer = await (io.callTool ?? ((spec, secrets, name, given) => callProjectTool(spec, secrets, name, given, { timeoutMs: 120_000, omitEnv: ALL_CREDENTIAL_ENV })))(tool.spec, values, call.action, call.input);
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
answer = { ok: false, problem: error instanceof Error ? error.message : "It couldn't be reached." };
|
|
226
|
+
}
|
|
227
|
+
const text = answer.ok ? blank(scrubSecrets(answer.text, values)).trim() : answer.problem;
|
|
228
|
+
const kept = text.length <= RESULT_CHARS ? text : `${text.slice(0, RESULT_CHARS - 1)}…`;
|
|
229
|
+
store.moveTeammateCall(call.id, ["running"], { state: answer.ok && !answer.isError ? "done" : "failed", result: kept || (answer.ok ? "(no answer)" : "It couldn't be reached.") }, now);
|
|
230
|
+
return store.teammateCall(call.id);
|
|
231
|
+
}
|
|
232
|
+
/** A receipt in words: what happened to the call. */
|
|
233
|
+
export function callOutcome(call) {
|
|
234
|
+
switch (call.state) {
|
|
235
|
+
case "asked": return "waiting for approval";
|
|
236
|
+
case "approved": return `${call.decidedBy} approved it; making it`;
|
|
237
|
+
case "running": return "making it";
|
|
238
|
+
case "done": return call.decidedBy === null ? "done" : `${call.decidedBy} approved it; done`;
|
|
239
|
+
case "failed": return call.decidedBy === null ? "failed" : `${call.decidedBy} approved it; it failed`;
|
|
240
|
+
case "denied": return `${call.decidedBy ?? "A person"} denied it`;
|
|
241
|
+
default: return "not made";
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
/** A receipt as a person reads it on the card: what happened, and who decided. */
|
|
245
|
+
export function receiptWords(store, call) {
|
|
246
|
+
switch (call.state) {
|
|
247
|
+
case "asked": {
|
|
248
|
+
const question = store.teammateQuestionForCall(call.id);
|
|
249
|
+
return `Waiting for ${question?.askedOf ?? "a person"} to approve`;
|
|
250
|
+
}
|
|
251
|
+
case "approved":
|
|
252
|
+
case "running": return call.decidedBy === null ? "Making it now" : `${call.decidedBy} approved · making it now`;
|
|
253
|
+
case "done": return call.undoneBy !== null ? `Done · undone by ${call.undoneBy}` : call.undoOf !== null ? `Undid ${store.teammateCall(call.undoOf)?.action ?? "a call"} · done` : call.decidedBy === null ? "Done" : `${call.decidedBy} approved · done`;
|
|
254
|
+
case "failed": return call.decidedBy === null ? "Failed" : `${call.decidedBy} approved · failed`;
|
|
255
|
+
case "denied": {
|
|
256
|
+
const said = store.teammateQuestionForCall(call.id)?.answer;
|
|
257
|
+
return `${call.decidedBy ?? "A person"} said no${said ? `: ${said}` : ""}`;
|
|
258
|
+
}
|
|
259
|
+
default: return `Not made: ${call.result ?? "outside its rules"}`;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/** The Tools section's form, read into rule changes: every action the grant knows. */
|
|
263
|
+
export function rulesFromForm(grant, field) {
|
|
264
|
+
return Object.fromEntries(grant.actions.flatMap(action => {
|
|
265
|
+
const use = field(`use.${action.name}`);
|
|
266
|
+
if (use === null)
|
|
267
|
+
return [];
|
|
268
|
+
const undo = field(`undo.${action.name}`) ?? "";
|
|
269
|
+
return [[action.name, { ...(use === "limit" ? { use: "free", limit: { field: field(`field.${action.name}`) ?? "", over: field(`over.${action.name}`) ?? "" } } : { use }), undo }]];
|
|
270
|
+
}));
|
|
271
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { Store, TeammateCallRow, TeammateRow } from "./store.js";
|
|
2
|
+
import { type ToolIo } from "./teammate-tools.js";
|
|
3
|
+
type Done = {
|
|
4
|
+
ok: true;
|
|
5
|
+
said: string;
|
|
6
|
+
} | {
|
|
7
|
+
ok: false;
|
|
8
|
+
said: string;
|
|
9
|
+
};
|
|
10
|
+
export type Week = {
|
|
11
|
+
since: string;
|
|
12
|
+
turns: number;
|
|
13
|
+
failedTurns: number;
|
|
14
|
+
costUsd: number | null;
|
|
15
|
+
minutes: number;
|
|
16
|
+
decided: number;
|
|
17
|
+
handled: number;
|
|
18
|
+
handed: number;
|
|
19
|
+
asked: number;
|
|
20
|
+
calls: {
|
|
21
|
+
made: number;
|
|
22
|
+
approved: number;
|
|
23
|
+
denied: number;
|
|
24
|
+
refused: number;
|
|
25
|
+
undone: number;
|
|
26
|
+
};
|
|
27
|
+
overrides: {
|
|
28
|
+
said: string;
|
|
29
|
+
at: string;
|
|
30
|
+
href: string | null;
|
|
31
|
+
}[];
|
|
32
|
+
undoable: {
|
|
33
|
+
call: number;
|
|
34
|
+
words: string;
|
|
35
|
+
undo: string;
|
|
36
|
+
at: string;
|
|
37
|
+
href: string | null;
|
|
38
|
+
}[];
|
|
39
|
+
};
|
|
40
|
+
/** The undo action a call's rule names, when there is one and the call can still be undone. */
|
|
41
|
+
export declare function undoFor(store: Store, call: TeammateCallRow): string | null;
|
|
42
|
+
/** The last seven days (or since a time) for one teammate. */
|
|
43
|
+
export declare function weekOf(store: Store, mate: TeammateRow, now: Date, since?: string): Week;
|
|
44
|
+
/** The week in words its manager reads at a glance. */
|
|
45
|
+
export declare function weekWords(mate: TeammateRow, week: Week): string;
|
|
46
|
+
/** Each Monday from 9:00 (this computer's time), the week's report to each active teammate's manager, once; or now, for one. */
|
|
47
|
+
export declare function sendTeammateWeeklies(store: Store, repo: string, now: Date, only?: number | null): number;
|
|
48
|
+
/**
|
|
49
|
+
* A person asks to undo one of its tool calls with the action its manager
|
|
50
|
+
* named: the undo call is recorded at once (the same input, as them), and
|
|
51
|
+
* made by finishUndo — right away on the page, or by the worker's next pass
|
|
52
|
+
* when it was asked for in chat. Both calls keep their receipts.
|
|
53
|
+
*/
|
|
54
|
+
export declare function requestUndo(store: Store, mate: TeammateRow, id: number, by: string, now: Date): {
|
|
55
|
+
ok: true;
|
|
56
|
+
call: number;
|
|
57
|
+
said: string;
|
|
58
|
+
} | {
|
|
59
|
+
ok: false;
|
|
60
|
+
said: string;
|
|
61
|
+
};
|
|
62
|
+
/** Make a requested undo call; if the tool says it failed, the original call stands (and can be undone again). */
|
|
63
|
+
export declare function finishUndo(store: Store, id: number, io: ToolIo, now: Date): Promise<Done>;
|
|
64
|
+
/** The worker's pass: undo calls asked for in chat, made now. */
|
|
65
|
+
export declare function runRequestedUndos(store: Store, io: ToolIo, now: Date): Promise<number>;
|
|
66
|
+
/** Undo, on the page: asked for and made at once. */
|
|
67
|
+
export declare function undoCall(store: Store, mate: TeammateRow, id: number, by: string, io: ToolIo, now: Date): Promise<Done>;
|
|
68
|
+
export {};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A teammate's week (v97): what it did, what it cost, what its people
|
|
3
|
+
* overrode, and its receipts — on its page, and each Monday morning to its
|
|
4
|
+
* manager in their chat app.
|
|
5
|
+
*
|
|
6
|
+
* Cost is what the Claude CLI reports for each turn (at API prices; a Claude
|
|
7
|
+
* plan covers subscription turns). Overrides are the calls its people turned
|
|
8
|
+
* down and the cards someone moved by hand right after it moved them.
|
|
9
|
+
*
|
|
10
|
+
* Undo, where the tool can: a manager names, per action, another action of
|
|
11
|
+
* the same tool that undoes it (remove_label for add_label, say). Undo makes
|
|
12
|
+
* that call with the same input, as the person who pressed it, and both calls
|
|
13
|
+
* keep their receipts.
|
|
14
|
+
*/
|
|
15
|
+
import { flowCardHref } from "./flow-engine.js";
|
|
16
|
+
import { labelOf, nameOf } from "./teammate-admin.js";
|
|
17
|
+
import { callWords, makeCall } from "./teammate-tools.js";
|
|
18
|
+
const WEEK_MS = 7 * 86_400_000;
|
|
19
|
+
const money = (usd) => usd < 0.01 ? "under 1¢" : usd < 10 ? `$${usd.toFixed(2)}` : `$${Math.round(usd)}`;
|
|
20
|
+
/** The undo action a call's rule names, when there is one and the call can still be undone. */
|
|
21
|
+
export function undoFor(store, call) {
|
|
22
|
+
if (call.state !== "done" || call.undoneBy !== null || call.undoOf !== null)
|
|
23
|
+
return null;
|
|
24
|
+
const grant = store.teammateGrant(call.teammate, call.tool);
|
|
25
|
+
const undo = grant?.rules[call.action]?.undo;
|
|
26
|
+
return undo !== undefined && grant.actions.some(one => one.name === undo) ? undo : null;
|
|
27
|
+
}
|
|
28
|
+
/** The last seven days (or since a time) for one teammate. */
|
|
29
|
+
export function weekOf(store, mate, now, since = new Date(now.getTime() - WEEK_MS).toISOString()) {
|
|
30
|
+
const turns = store.teammateTurns(mate.id, since);
|
|
31
|
+
const costs = turns.map(one => one.costUsd).filter((one) => one !== null);
|
|
32
|
+
const events = store.teammateEvents(mate.id, 5000, since);
|
|
33
|
+
const count = (kind) => events.filter(one => one.kind === kind).length;
|
|
34
|
+
const calls = store.teammateCallsOf(mate.id, 5000, since).filter(one => one.undoOf === null);
|
|
35
|
+
const hrefOf = (card) => { const found = card === null ? null : store.getFlowCard(card); return found === null ? null : flowCardHref(found.flow, found.id); };
|
|
36
|
+
const name = nameOf(mate);
|
|
37
|
+
const denied = calls.filter(one => one.state === "denied").map(one => {
|
|
38
|
+
const words = store.teammateQuestionForCall(one.id)?.answer;
|
|
39
|
+
return { said: `${one.decidedBy ?? "Someone"} turned down ${callWords(one.tool, one.action, one.input, 160)}${words ? `: “${words.slice(0, 160)}”` : ""}`, at: one.decidedAt ?? one.createdAt, href: hrefOf(one.card) };
|
|
40
|
+
});
|
|
41
|
+
const moved = store.flowMovesOverridden(`${name} (AI)`, since).map(one => ({ said: `${one.by} moved “${one.title.slice(0, 80)}” after ${name} did`, at: one.at, href: flowCardHref(one.flow, one.card) }));
|
|
42
|
+
return {
|
|
43
|
+
since, turns: turns.length, failedTurns: turns.filter(one => !one.ok).length, costUsd: costs.length === 0 ? null : Math.round(costs.reduce((sum, one) => sum + one, 0) * 1e6) / 1e6,
|
|
44
|
+
minutes: Math.round(turns.reduce((sum, one) => sum + one.ms, 0) / 60_000),
|
|
45
|
+
decided: count("decided"), handled: count("handled"), handed: count("handed"), asked: count("asked"),
|
|
46
|
+
calls: { made: calls.filter(one => one.state === "done" || one.state === "failed").length, approved: calls.filter(one => one.decidedBy !== null && one.state !== "denied" && one.state !== "refused").length,
|
|
47
|
+
denied: calls.filter(one => one.state === "denied").length, refused: calls.filter(one => one.state === "refused").length, undone: calls.filter(one => one.undoneBy !== null).length },
|
|
48
|
+
overrides: [...denied, ...moved].sort((a, b) => b.at.localeCompare(a.at)).slice(0, 20),
|
|
49
|
+
undoable: calls.flatMap(one => { const undo = undoFor(store, one); return undo === null ? [] : [{ call: one.id, words: callWords(one.tool, one.action, one.input, 200), undo, at: one.createdAt, href: hrefOf(one.card) }]; }).reverse().slice(0, 20),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/** The week in words its manager reads at a glance. */
|
|
53
|
+
export function weekWords(mate, week) {
|
|
54
|
+
const name = nameOf(mate);
|
|
55
|
+
const quiet = week.turns === 0 && week.decided + week.handled + week.handed + week.asked + week.calls.made === 0;
|
|
56
|
+
if (quiet)
|
|
57
|
+
return `${name} had nothing to do this week.`;
|
|
58
|
+
const lines = [
|
|
59
|
+
`${name} decided ${week.decided}, handled ${week.handled}, handed ${week.handed} to people and asked ${week.asked} question${week.asked === 1 ? "" : "s"}.`,
|
|
60
|
+
`Tool calls: ${week.calls.made} made${week.calls.approved > 0 ? ` (${week.calls.approved} after a person approved)` : ""}${week.calls.denied > 0 ? `, ${week.calls.denied} turned down` : ""}${week.calls.refused > 0 ? `, ${week.calls.refused} outside its rules` : ""}${week.calls.undone > 0 ? `, ${week.calls.undone} undone` : ""}.`,
|
|
61
|
+
`${week.turns} turn${week.turns === 1 ? "" : "s"}${week.failedTurns > 0 ? ` (${week.failedTurns} failed)` : ""}, about ${week.minutes} minute${week.minutes === 1 ? "" : "s"} of thinking${week.costUsd === null ? "" : `, ${money(week.costUsd)} at API prices`}.`,
|
|
62
|
+
...(week.overrides.length === 0 ? ["Nobody overrode it."] : [`You overrode it ${week.overrides.length} time${week.overrides.length === 1 ? "" : "s"}:`, ...week.overrides.slice(0, 5).map(one => `• ${one.said}`)]),
|
|
63
|
+
];
|
|
64
|
+
return lines.join("\n");
|
|
65
|
+
}
|
|
66
|
+
/** Each Monday from 9:00 (this computer's time), the week's report to each active teammate's manager, once; or now, for one. */
|
|
67
|
+
export function sendTeammateWeeklies(store, repo, now, only = null) {
|
|
68
|
+
const monday = new Date(now);
|
|
69
|
+
monday.setHours(9, 0, 0, 0);
|
|
70
|
+
monday.setDate(monday.getDate() - ((monday.getDay() + 6) % 7));
|
|
71
|
+
let sent = 0;
|
|
72
|
+
for (const mate of store.teammates([repo])) {
|
|
73
|
+
// One a week, from Monday 9:00; a teammate that joined since then has its first next Monday.
|
|
74
|
+
if (only !== null ? mate.id !== only : mate.state !== "active" || now < monday || (mate.weeklyAt ?? mate.createdAt) >= monday.toISOString())
|
|
75
|
+
continue;
|
|
76
|
+
store.updateTeammate(mate.id, { weeklyAt: now.toISOString() }, "weekly", now);
|
|
77
|
+
const week = weekOf(store, mate, now);
|
|
78
|
+
if (week.turns === 0 && only === null)
|
|
79
|
+
continue;
|
|
80
|
+
store.enqueueNotification({ dedupeKey: `teammate-weekly:${mate.id}:${now.toISOString().slice(0, only === null ? 10 : 19)}`, kind: "teammate-weekly", recipient: mate.manager,
|
|
81
|
+
subject: `${labelOf(mate)}: the week`, body: weekWords(mate, week), link: `/teammates/${mate.id}#week`, source: { project: repo } }, now);
|
|
82
|
+
sent++;
|
|
83
|
+
}
|
|
84
|
+
return sent;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* A person asks to undo one of its tool calls with the action its manager
|
|
88
|
+
* named: the undo call is recorded at once (the same input, as them), and
|
|
89
|
+
* made by finishUndo — right away on the page, or by the worker's next pass
|
|
90
|
+
* when it was asked for in chat. Both calls keep their receipts.
|
|
91
|
+
*/
|
|
92
|
+
export function requestUndo(store, mate, id, by, now) {
|
|
93
|
+
const call = store.teammateCall(id);
|
|
94
|
+
if (call === null || call.teammate !== mate.id)
|
|
95
|
+
return { ok: false, said: "No such call." };
|
|
96
|
+
const undo = undoFor(store, call);
|
|
97
|
+
if (undo === null)
|
|
98
|
+
return { ok: false, said: call.undoneBy !== null ? `${call.undoneBy} already undid it.` : "That call can't be undone here." };
|
|
99
|
+
return store.transact(() => {
|
|
100
|
+
if (!store.markTeammateCallUndone(call.id, by, now))
|
|
101
|
+
return { ok: false, said: "Someone undid it just now." };
|
|
102
|
+
const made = store.addTeammateCall({ teammate: mate.id, card: call.card, entry: call.entry, tool: call.tool, action: undo, input: call.input, rule: "free",
|
|
103
|
+
why: `${by} undid ${call.action} (call ${call.id}).`, state: "approved", undoOf: call.id, decidedBy: by }, now);
|
|
104
|
+
return { ok: true, call: made, said: `Undoing it with ${undo}.` };
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/** Make a requested undo call; if the tool says it failed, the original call stands (and can be undone again). */
|
|
108
|
+
export async function finishUndo(store, id, io, now) {
|
|
109
|
+
const pending = store.teammateCall(id);
|
|
110
|
+
const mate = pending === null ? null : store.getTeammate(pending.teammate);
|
|
111
|
+
if (pending === null || mate === null || pending.undoOf === null || pending.state !== "approved")
|
|
112
|
+
return { ok: false, said: "That undo was already made." };
|
|
113
|
+
const made = await makeCall(store, pending, mate.repo, io, now, { byPerson: true });
|
|
114
|
+
if (made.state === "done")
|
|
115
|
+
return { ok: true, said: `Undone: ${callWords(made.tool, made.action, made.input, 120)}. ${made.result ?? ""}`.trim() };
|
|
116
|
+
store.clearTeammateCallUndone(pending.undoOf, now);
|
|
117
|
+
return { ok: false, said: `The undo call failed: ${made.result ?? "no answer"}. The original call stands.` };
|
|
118
|
+
}
|
|
119
|
+
/** The worker's pass: undo calls asked for in chat, made now. */
|
|
120
|
+
export async function runRequestedUndos(store, io, now) {
|
|
121
|
+
let made = 0;
|
|
122
|
+
for (const call of store.pendingTeammateUndos()) {
|
|
123
|
+
await finishUndo(store, call.id, io, now);
|
|
124
|
+
made++;
|
|
125
|
+
}
|
|
126
|
+
return made;
|
|
127
|
+
}
|
|
128
|
+
/** Undo, on the page: asked for and made at once. */
|
|
129
|
+
export async function undoCall(store, mate, id, by, io, now) {
|
|
130
|
+
const asked = requestUndo(store, mate, id, by, now);
|
|
131
|
+
return asked.ok ? finishUndo(store, asked.call, io, now) : asked;
|
|
132
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A teammate's turn on a card (v92), run by the flow step pass.
|
|
3
|
+
*
|
|
4
|
+
* The turn reads the zone, the card (as data) and what its people told it,
|
|
5
|
+
* and answers with one decision (teammates.ts). This carries the decision
|
|
6
|
+
* out within the zone's own choices, and writes it down — what it did and
|
|
7
|
+
* why — in the card's history and the teammate's log:
|
|
8
|
+
*
|
|
9
|
+
* - "Person decides" zone: approve (the draft as written, or as it rewrote
|
|
10
|
+
* it), send back with a note, or hand it to the zone's person, whose
|
|
11
|
+
* decision then arrives in their chat app as always.
|
|
12
|
+
* - "Teammate handles it" zone: pick one of the zone's answers (its text is
|
|
13
|
+
* kept for the next zones), ask its person a question and wait for the
|
|
14
|
+
* answer, or say it can't and take the failure path.
|
|
15
|
+
*
|
|
16
|
+
* Either way (v94), before it decides it may use the project tools its
|
|
17
|
+
* manager let it use: each call is checked against its rule for that action
|
|
18
|
+
* (teammate-tools.ts), made at once or put to its person first, and kept as
|
|
19
|
+
* a receipt; the turn goes on with what the tool answered.
|
|
20
|
+
*/
|
|
21
|
+
import type { FlowCardRow, FlowRow, Store, TeammateRow } from "./store.js";
|
|
22
|
+
import type { FlowDefinition, FlowStage } from "./flows.js";
|
|
23
|
+
import { type TurnRunner } from "./teammates.js";
|
|
24
|
+
import { type ToolIo } from "./teammate-tools.js";
|
|
25
|
+
/** A question waits for its answer this long before the step is due again on its own: never, in practice. */
|
|
26
|
+
export declare const ASKED = "9999-12-31T00:00:00.000Z";
|
|
27
|
+
/** v94: tool calls one visit of a card may make, and turns one step run may take, before it must decide with what it has. */
|
|
28
|
+
export declare const CALLS_PER_VISIT = 12;
|
|
29
|
+
/** The two answers an ask-first call offers; words instead tell the teammate what to do. */
|
|
30
|
+
export declare const APPROVE = "approve", DENY = "deny";
|
|
31
|
+
export type TeammateOutcome = {
|
|
32
|
+
state: "passed" | "failed" | "retry" | "waiting";
|
|
33
|
+
said: string;
|
|
34
|
+
log?: string;
|
|
35
|
+
decisionJson?: string;
|
|
36
|
+
nextAt?: string;
|
|
37
|
+
};
|
|
38
|
+
/** The Claude model a teammate's turns run on: its own, or the lead chat's Claude model, or Claude's default. */
|
|
39
|
+
export declare function teammateModel(store: Store, mate: TeammateRow): string;
|
|
40
|
+
/** Whether a teammate can take a turn now: active, readable, and under its daily limit. */
|
|
41
|
+
export declare function teammateReady(store: Store, mate: TeammateRow | null, now: Date): {
|
|
42
|
+
ok: true;
|
|
43
|
+
} | {
|
|
44
|
+
ok: false;
|
|
45
|
+
why: string;
|
|
46
|
+
};
|
|
47
|
+
/** The answers a "Teammate handles it" zone offers, each with the zone it leads to. */
|
|
48
|
+
export declare function handleAnswers(stage: FlowStage): {
|
|
49
|
+
answer: string;
|
|
50
|
+
to: string | null;
|
|
51
|
+
}[];
|
|
52
|
+
/**
|
|
53
|
+
* Run one teammate turn on a card and carry out what it decided. With tools
|
|
54
|
+
* (v94) a turn is a short loop: each tool call it asks for is made (or put to
|
|
55
|
+
* its person, and the turn waits), and it decides again with the answer —
|
|
56
|
+
* until it decides, or it has used its tools as much as a visit allows.
|
|
57
|
+
*/
|
|
58
|
+
export declare function teammateTurn(store: Store, flow: FlowRow, definition: FlowDefinition, stage: FlowStage, card: FlowCardRow, mate: TeammateRow, now: Date, io: {
|
|
59
|
+
turn?: TurnRunner;
|
|
60
|
+
evidenceRoot?: string;
|
|
61
|
+
} & ToolIo): Promise<TeammateOutcome>;
|
|
62
|
+
/** A person answers a teammate's question: once, by the person it was asked of; the card's turn is due again. */
|
|
63
|
+
export declare function answerTeammateQuestion(store: Store, id: number, answer: {
|
|
64
|
+
choice: string | null;
|
|
65
|
+
text: string | null;
|
|
66
|
+
by: string;
|
|
67
|
+
via: string;
|
|
68
|
+
}, now: Date): {
|
|
69
|
+
ok: true;
|
|
70
|
+
said: string;
|
|
71
|
+
} | {
|
|
72
|
+
ok: false;
|
|
73
|
+
said: string;
|
|
74
|
+
};
|
|
75
|
+
/** A card's link, for messages about it. */
|
|
76
|
+
export declare const teammateCardHref: (flow: number, card: number) => string;
|