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
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turning snapshots into something worth reading.
|
|
3
|
+
*
|
|
4
|
+
* Pure string building. The clock is a parameter rather than a call, so the
|
|
5
|
+
* output is deterministic under test and the same report can be re-rendered
|
|
6
|
+
* later against the time it was taken.
|
|
7
|
+
*/
|
|
8
|
+
import type { RepoSnapshot } from "./discover.js";
|
|
9
|
+
import type { TrackingState } from "./git.js";
|
|
10
|
+
import { type BackendKind, type Detection } from "./graph.js";
|
|
11
|
+
import { type Pull } from "./pulls.js";
|
|
12
|
+
import type { RemoteState } from "./remote.js";
|
|
13
|
+
export type ReportOptions = {
|
|
14
|
+
now: Date;
|
|
15
|
+
/** Where the scan looked, used only to make the empty result actionable. */
|
|
16
|
+
roots?: readonly string[];
|
|
17
|
+
maxBranches?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Pull requests and issues per repository path. Undefined means they were
|
|
20
|
+
* never read — which the report says out loud rather than showing zeroes,
|
|
21
|
+
* because "none" and "did not look" are different answers.
|
|
22
|
+
*/
|
|
23
|
+
remote?: RemoteMap;
|
|
24
|
+
};
|
|
25
|
+
export type RemoteMap = ReadonlyMap<string, RemoteState>;
|
|
26
|
+
export declare const DEFAULT_MAX_BRANCHES = 6;
|
|
27
|
+
export declare function formatAge(iso: string, now: Date): string;
|
|
28
|
+
export declare function formatTrack(track: TrackingState): string;
|
|
29
|
+
export declare function renderReport(snapshots: readonly RepoSnapshot[], options: ReportOptions): string;
|
|
30
|
+
/** One repository's open pull requests, as read. */
|
|
31
|
+
export type PullGroup = {
|
|
32
|
+
repo: string;
|
|
33
|
+
pulls: readonly Pull[];
|
|
34
|
+
problems: readonly string[];
|
|
35
|
+
};
|
|
36
|
+
export type PullsOptions = {
|
|
37
|
+
now: Date;
|
|
38
|
+
staleDays?: number;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* How long since anything happened. Phrased as idleness rather than age
|
|
42
|
+
* because a pull request opened in May and discussed yesterday is not old in
|
|
43
|
+
* any sense the operator cares about.
|
|
44
|
+
*/
|
|
45
|
+
export declare function formatIdle(iso: string, now: Date): string;
|
|
46
|
+
/**
|
|
47
|
+
* Grouped by whose move it is, because that is the only question being asked.
|
|
48
|
+
* Drafts and running builds are counted but not listed — nobody is blocked on
|
|
49
|
+
* them, and a report that lists everything is the attention problem it was
|
|
50
|
+
* written to solve.
|
|
51
|
+
*/
|
|
52
|
+
export declare function renderPulls(groups: readonly PullGroup[], options: PullsOptions): string;
|
|
53
|
+
/**
|
|
54
|
+
* What work graph is already here.
|
|
55
|
+
*
|
|
56
|
+
* The recommended backend is marked with a pointer and nothing else is, because
|
|
57
|
+
* the one thing this report must not read as is a menu of things already
|
|
58
|
+
* switched on. Every line ends by saying what is *not* authorized, since
|
|
59
|
+
* detection is not authorization and a report that omitted that would be
|
|
60
|
+
* inviting exactly the wrong conclusion.
|
|
61
|
+
*/
|
|
62
|
+
export declare function renderGraph(detections: readonly Detection[], options?: {
|
|
63
|
+
enrolled?: BackendKind;
|
|
64
|
+
}): string;
|
package/dist/render.js
ADDED
|
@@ -0,0 +1,587 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turning snapshots into something worth reading.
|
|
3
|
+
*
|
|
4
|
+
* Pure string building. The clock is a parameter rather than a call, so the
|
|
5
|
+
* output is deterministic under test and the same report can be re-rendered
|
|
6
|
+
* later against the time it was taken.
|
|
7
|
+
*/
|
|
8
|
+
import { chooseBackend, setupOptions, LABELS as GRAPH_LABELS, } from "./graph.js";
|
|
9
|
+
import { classify, describe as describePull, idleDays, DEFAULT_STALE_DAYS, } from "./pulls.js";
|
|
10
|
+
export const DEFAULT_MAX_BRANCHES = 6;
|
|
11
|
+
const MINUTE = 60_000;
|
|
12
|
+
const HOUR = 60 * MINUTE;
|
|
13
|
+
const DAY = 24 * HOUR;
|
|
14
|
+
const MONTH = 30 * DAY;
|
|
15
|
+
const YEAR = 365 * DAY;
|
|
16
|
+
const INDENT = " ";
|
|
17
|
+
const GUTTER = 2;
|
|
18
|
+
/**
|
|
19
|
+
* Columns size themselves to the content, within bounds. Fixed widths either
|
|
20
|
+
* waste half the terminal on short names or let one long branch name shove
|
|
21
|
+
* every other column out of alignment — and truncating is not an option when
|
|
22
|
+
* the name is the thing you are about to type.
|
|
23
|
+
*/
|
|
24
|
+
const MIN_NAME_WIDTH = 20;
|
|
25
|
+
const MAX_NAME_WIDTH = 44;
|
|
26
|
+
const MIN_STATE_WIDTH = 12;
|
|
27
|
+
const MAX_STATE_WIDTH = 20;
|
|
28
|
+
export function formatAge(iso, now) {
|
|
29
|
+
const then = Date.parse(iso);
|
|
30
|
+
if (Number.isNaN(then))
|
|
31
|
+
return "unknown";
|
|
32
|
+
// Clocks disagree across machines; a branch from the future is just recent.
|
|
33
|
+
const elapsed = Math.max(0, now.getTime() - then);
|
|
34
|
+
if (elapsed < MINUTE)
|
|
35
|
+
return "just now";
|
|
36
|
+
if (elapsed < HOUR)
|
|
37
|
+
return `${Math.floor(elapsed / MINUTE)}m ago`;
|
|
38
|
+
if (elapsed < DAY)
|
|
39
|
+
return `${Math.floor(elapsed / HOUR)}h ago`;
|
|
40
|
+
if (elapsed < MONTH)
|
|
41
|
+
return `${Math.floor(elapsed / DAY)}d ago`;
|
|
42
|
+
if (elapsed < YEAR)
|
|
43
|
+
return `${Math.floor(elapsed / MONTH)}mo ago`;
|
|
44
|
+
return `${Math.floor(elapsed / YEAR)}y ago`;
|
|
45
|
+
}
|
|
46
|
+
export function formatTrack(track) {
|
|
47
|
+
if (track.gone)
|
|
48
|
+
return "upstream gone";
|
|
49
|
+
const parts = [];
|
|
50
|
+
if (track.ahead > 0)
|
|
51
|
+
parts.push(`ahead ${track.ahead}`);
|
|
52
|
+
if (track.behind > 0)
|
|
53
|
+
parts.push(`behind ${track.behind}`);
|
|
54
|
+
return parts.join(", ");
|
|
55
|
+
}
|
|
56
|
+
/** A branch is in flight when it has diverged from its upstream or lost it. */
|
|
57
|
+
function isInFlight(branch) {
|
|
58
|
+
return branch.track.ahead > 0 || branch.track.behind > 0 || branch.track.gone;
|
|
59
|
+
}
|
|
60
|
+
export function renderReport(snapshots, options) {
|
|
61
|
+
const { now, roots = [], maxBranches = DEFAULT_MAX_BRANCHES, remote } = options;
|
|
62
|
+
if (snapshots.length === 0)
|
|
63
|
+
return renderEmpty(roots);
|
|
64
|
+
const sections = [...snapshots]
|
|
65
|
+
.sort(byRecency)
|
|
66
|
+
.map(snapshot => composeSection(snapshot, now, maxBranches, remote))
|
|
67
|
+
.filter(rows => rows.length > 0);
|
|
68
|
+
const totals = countInFlight(snapshots, remote);
|
|
69
|
+
const withheld = renderWithheld(snapshots, remote);
|
|
70
|
+
// "Nothing in flight" is a claim about what was looked at. If the budget ran
|
|
71
|
+
// out before some repositories were asked, saying it flatly would be the
|
|
72
|
+
// silence this tool exists to break — so the withheld line goes here too,
|
|
73
|
+
// and it is the whole point of this branch rather than a footnote.
|
|
74
|
+
if (sections.length === 0) {
|
|
75
|
+
return [...renderNothingInFlight(snapshots.length, remote, withheld.length > 0), ...withheld]
|
|
76
|
+
.join("\n")
|
|
77
|
+
.trimEnd();
|
|
78
|
+
}
|
|
79
|
+
const rows = sections.flat();
|
|
80
|
+
const nameWidth = widthOf(rows, row => row.indent.length + row.name.length, MIN_NAME_WIDTH, MAX_NAME_WIDTH);
|
|
81
|
+
const stateWidth = widthOf(rows, row => row.state.length, MIN_STATE_WIDTH, MAX_STATE_WIDTH);
|
|
82
|
+
const unmeasured = snapshots.filter(snapshot => !snapshot.hasTracking).length;
|
|
83
|
+
const body = sections.map(section => section.map(row => renderRow(row, nameWidth, stateWidth)).join("\n"));
|
|
84
|
+
return [renderHeader(totals, snapshots.length, unmeasured), "", ...body, ...withheld]
|
|
85
|
+
.join("\n")
|
|
86
|
+
.trimEnd();
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* One repository's block, from both halves.
|
|
90
|
+
*
|
|
91
|
+
* The local rows already end in a blank separator, so remote rows are spliced
|
|
92
|
+
* in ahead of it rather than appended after — otherwise a repository's pull
|
|
93
|
+
* requests would appear under the gap, reading as though they belonged to the
|
|
94
|
+
* repository below.
|
|
95
|
+
*/
|
|
96
|
+
function composeSection(snapshot, now, maxBranches, remote) {
|
|
97
|
+
const local = collectRows(snapshot, now, maxBranches);
|
|
98
|
+
const fromRemote = collectRemoteRows(snapshot, remote, now);
|
|
99
|
+
if (fromRemote.length === 0)
|
|
100
|
+
return local;
|
|
101
|
+
if (local.length === 0) {
|
|
102
|
+
// Nothing local to say, but a pull request waiting is still news, and the
|
|
103
|
+
// repository needs a heading of its own to be attributed to.
|
|
104
|
+
return [
|
|
105
|
+
{ indent: "", name: snapshot.name, state: snapshot.head ?? "detached", tail: "" },
|
|
106
|
+
...fromRemote,
|
|
107
|
+
{ indent: "", name: "", state: "", tail: "" },
|
|
108
|
+
];
|
|
109
|
+
}
|
|
110
|
+
return [...local.slice(0, -1), ...fromRemote, local[local.length - 1]];
|
|
111
|
+
}
|
|
112
|
+
function countInFlight(snapshots, remote) {
|
|
113
|
+
const branches = snapshots.reduce((total, snapshot) => total + (snapshot.hasTracking ? snapshot.branches.filter(isInFlight).length : 0), 0);
|
|
114
|
+
let pulls = 0;
|
|
115
|
+
let issues = 0;
|
|
116
|
+
for (const snapshot of snapshots) {
|
|
117
|
+
const state = remote?.get(snapshot.path);
|
|
118
|
+
if (state === undefined)
|
|
119
|
+
continue;
|
|
120
|
+
pulls += state.pulls.length;
|
|
121
|
+
issues += state.issues.length;
|
|
122
|
+
}
|
|
123
|
+
return { branches, pulls, issues, remoteRead: remote !== undefined };
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Pull requests waiting on somebody, and a count of open issues.
|
|
127
|
+
*
|
|
128
|
+
* Pull requests get a row each because a pull request that nobody has looked at
|
|
129
|
+
* is the single most actionable thing this report can surface — the case that
|
|
130
|
+
* motivated the tool was two of them sitting green and ignored for two months.
|
|
131
|
+
* Issues get a count: a hundred open issues is context, not a to-do list, and
|
|
132
|
+
* printing all of them would bury everything above.
|
|
133
|
+
*/
|
|
134
|
+
function collectRemoteRows(snapshot, remote, now) {
|
|
135
|
+
const state = remote?.get(snapshot.path);
|
|
136
|
+
if (state === undefined || state.skipped)
|
|
137
|
+
return [];
|
|
138
|
+
const rows = [];
|
|
139
|
+
const waiting = state.pulls.filter(pull => {
|
|
140
|
+
const attention = classify(pull);
|
|
141
|
+
return attention === "human" || attention === "agent";
|
|
142
|
+
});
|
|
143
|
+
for (const pull of waiting) {
|
|
144
|
+
rows.push({
|
|
145
|
+
indent: INDENT,
|
|
146
|
+
name: `#${pull.number} ${pull.branch}`,
|
|
147
|
+
state: describePull(pull),
|
|
148
|
+
tail: formatIdle(pull.updatedAt, now),
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
if (state.issues.length > 0) {
|
|
152
|
+
rows.push({
|
|
153
|
+
indent: INDENT,
|
|
154
|
+
name: `${plural(state.issues.length, "issue", "issues")} open`,
|
|
155
|
+
state: "",
|
|
156
|
+
tail: "",
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
for (const problem of state.problems) {
|
|
160
|
+
rows.push({ indent: INDENT, name: `! ${problem}`, state: "", tail: "" });
|
|
161
|
+
}
|
|
162
|
+
return rows;
|
|
163
|
+
}
|
|
164
|
+
/** What the budget did not reach, named rather than silently missing. */
|
|
165
|
+
function renderWithheld(snapshots, remote) {
|
|
166
|
+
if (remote === undefined)
|
|
167
|
+
return [];
|
|
168
|
+
const skipped = snapshots.filter(snapshot => remote.get(snapshot.path)?.skipped === true);
|
|
169
|
+
if (skipped.length === 0)
|
|
170
|
+
return [];
|
|
171
|
+
// Named, not counted. "3 repositories were not checked" leaves an operator
|
|
172
|
+
// to work out which three, and the whole reason this line exists is that a
|
|
173
|
+
// repository nobody looked at must not be mistaken for one with nothing in
|
|
174
|
+
// it. Long lists are truncated, because at that point the budget is the
|
|
175
|
+
// story rather than the names.
|
|
176
|
+
const shown = skipped.slice(0, MAX_SKIPPED_NAMED).map(snapshot => snapshot.name);
|
|
177
|
+
const rest = skipped.length - shown.length;
|
|
178
|
+
const names = rest > 0 ? `${shown.join(", ")} and ${rest} more` : shown.join(", ");
|
|
179
|
+
return [
|
|
180
|
+
"",
|
|
181
|
+
`Not checked for pull requests or issues: ${names}.`,
|
|
182
|
+
"The network budget ran out. `toolroll pulls` reads them without one.",
|
|
183
|
+
];
|
|
184
|
+
}
|
|
185
|
+
function renderRow(row, nameWidth, stateWidth) {
|
|
186
|
+
const name = pad(`${row.indent}${row.name}`, nameWidth);
|
|
187
|
+
return `${name}${pad(row.state, stateWidth)}${row.tail}`.trimEnd();
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Only rows that carry a later column get a vote on how wide the earlier ones
|
|
191
|
+
* are. A free-text problem line has nothing to its right, so letting it size
|
|
192
|
+
* the table would push every real column off to the horizon.
|
|
193
|
+
*/
|
|
194
|
+
function widthOf(rows, measure, min, max) {
|
|
195
|
+
const widest = rows
|
|
196
|
+
.filter(row => row.state !== "" || row.tail !== "")
|
|
197
|
+
.reduce((longest, row) => Math.max(longest, measure(row)), 0);
|
|
198
|
+
return Math.min(max, Math.max(min, widest + GUTTER));
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* The one line the milestone is actually about: every branch, pull request and
|
|
202
|
+
* issue in flight, counted together.
|
|
203
|
+
*
|
|
204
|
+
* Zeroes are dropped rather than printed. "3 branches, 0 pull requests, 0
|
|
205
|
+
* issues" reads as a system reporting on itself; "3 branches" reads as an
|
|
206
|
+
* answer. But a zero that was never *looked* for is different from one that
|
|
207
|
+
* was, which is why the remote counts only appear when the remote read
|
|
208
|
+
* actually happened.
|
|
209
|
+
*/
|
|
210
|
+
function renderHeader(totals, repoCount, unmeasured) {
|
|
211
|
+
const parts = [plural(totals.branches, "branch", "branches")];
|
|
212
|
+
if (totals.remoteRead && totals.pulls > 0) {
|
|
213
|
+
parts.push(plural(totals.pulls, "pull request", "pull requests"));
|
|
214
|
+
}
|
|
215
|
+
if (totals.remoteRead && totals.issues > 0) {
|
|
216
|
+
parts.push(plural(totals.issues, "issue", "issues"));
|
|
217
|
+
}
|
|
218
|
+
const repos = plural(repoCount, "repository", "repositories");
|
|
219
|
+
const headline = `${joinWords(parts)} in flight across ${repos}`;
|
|
220
|
+
// A count that quietly excludes repositories it could not measure is a lie
|
|
221
|
+
// of omission. The remedy is named once here rather than on every repo — and
|
|
222
|
+
// it is printed, never run, because it writes to someone else's .git.
|
|
223
|
+
if (unmeasured === 0)
|
|
224
|
+
return headline;
|
|
225
|
+
const which = unmeasured === 1 ? "1 repository is" : `${unmeasured} repositories are`;
|
|
226
|
+
return [
|
|
227
|
+
headline,
|
|
228
|
+
`${which} listed by recency: ahead/behind was too slow to compute.`,
|
|
229
|
+
"`git commit-graph write --reachable` in it makes this permanent —",
|
|
230
|
+
"it writes to .git, so run it yourself.",
|
|
231
|
+
].join("\n");
|
|
232
|
+
}
|
|
233
|
+
/** Repositories were found and read; none of them had anything outstanding. */
|
|
234
|
+
function renderNothingInFlight(repoCount, remote, anyWithheld) {
|
|
235
|
+
return [
|
|
236
|
+
anyWithheld
|
|
237
|
+
? `Nothing in flight across the ${plural(repoCount, "repository", "repositories")} that were checked.`
|
|
238
|
+
: `Nothing in flight across ${plural(repoCount, "repository", "repositories")}.`,
|
|
239
|
+
remote === undefined
|
|
240
|
+
? "Every branch is level with its upstream."
|
|
241
|
+
: "Every branch is level with its upstream, and nothing is waiting on a person.",
|
|
242
|
+
"",
|
|
243
|
+
"Uncommitted work is not counted here — add --dirty to read working trees.",
|
|
244
|
+
// Said in addition to, not instead of: an operator who ran --local has two
|
|
245
|
+
// things missing from this answer, and hearing about one of them would
|
|
246
|
+
// leave them believing the other was checked.
|
|
247
|
+
...(remote === undefined
|
|
248
|
+
? ["Pull requests and issues were not read — drop --local to include them."]
|
|
249
|
+
: []),
|
|
250
|
+
];
|
|
251
|
+
}
|
|
252
|
+
/** "a, b and c" — the report is prose at this point, not a field list. */
|
|
253
|
+
function joinWords(parts) {
|
|
254
|
+
if (parts.length <= 1)
|
|
255
|
+
return parts[0] ?? "";
|
|
256
|
+
return `${parts.slice(0, -1).join(", ")} and ${parts[parts.length - 1]}`;
|
|
257
|
+
}
|
|
258
|
+
function renderEmpty(roots) {
|
|
259
|
+
const where = roots.length > 0 ? ` under ${roots.join(", ")}` : "";
|
|
260
|
+
return [
|
|
261
|
+
`No git repositories found${where}.`,
|
|
262
|
+
"",
|
|
263
|
+
"Point it somewhere else with `toolroll <path>`, or go deeper with",
|
|
264
|
+
"`toolroll --depth 8`. Nothing has been written or configured.",
|
|
265
|
+
].join("\n");
|
|
266
|
+
}
|
|
267
|
+
/** Past this, the budget is the story rather than which repositories missed out. */
|
|
268
|
+
const MAX_SKIPPED_NAMED = 6;
|
|
269
|
+
/** Long enough to catch work you have put down, short enough to exclude archaeology. */
|
|
270
|
+
const RECENT_WINDOW = 30 * DAY;
|
|
271
|
+
/**
|
|
272
|
+
* Which branches to show. With tracking, the ones that have diverged. Without
|
|
273
|
+
* it, recency is the only signal left — filtering on ahead/behind that was
|
|
274
|
+
* never computed would discard every branch and leave the repository
|
|
275
|
+
* represented by a complaint, and listing all of them buries the report under
|
|
276
|
+
* whichever repo happens to have the most abandoned branches.
|
|
277
|
+
*/
|
|
278
|
+
function selectBranches(snapshot, now) {
|
|
279
|
+
const byRecent = [...snapshot.branches].sort(byCommittedAtDesc);
|
|
280
|
+
if (snapshot.hasTracking)
|
|
281
|
+
return { shown: byRecent.filter(isInFlight), note: null };
|
|
282
|
+
const recent = byRecent.filter(branch => isWithinWindow(branch.committedAt, now));
|
|
283
|
+
if (recent.length > 0)
|
|
284
|
+
return { shown: recent, note: null };
|
|
285
|
+
const count = plural(snapshot.branches.length, "branch", "branches");
|
|
286
|
+
return { shown: [], note: `${count}, none touched in 30 days` };
|
|
287
|
+
}
|
|
288
|
+
function isWithinWindow(iso, now) {
|
|
289
|
+
const then = Date.parse(iso);
|
|
290
|
+
return !Number.isNaN(then) && now.getTime() - then < RECENT_WINDOW;
|
|
291
|
+
}
|
|
292
|
+
function collectRows(snapshot, now, maxBranches) {
|
|
293
|
+
const { shown: selected, note } = selectBranches(snapshot, now);
|
|
294
|
+
// A quiet, clean repo with nothing outstanding is not worth a line.
|
|
295
|
+
if (selected.length === 0 &&
|
|
296
|
+
note === null &&
|
|
297
|
+
!snapshot.dirtyFiles &&
|
|
298
|
+
snapshot.problems.length === 0) {
|
|
299
|
+
return [];
|
|
300
|
+
}
|
|
301
|
+
const shown = selected.slice(0, maxBranches);
|
|
302
|
+
const withheld = selected.length - shown.length;
|
|
303
|
+
const rows = [
|
|
304
|
+
{
|
|
305
|
+
indent: "",
|
|
306
|
+
name: snapshot.name,
|
|
307
|
+
state: snapshot.head ?? "detached",
|
|
308
|
+
tail: renderDirty(snapshot.dirtyFiles),
|
|
309
|
+
},
|
|
310
|
+
...shown.map(branch => ({
|
|
311
|
+
indent: INDENT,
|
|
312
|
+
name: branch.name,
|
|
313
|
+
state: formatTrack(branch.track),
|
|
314
|
+
tail: formatAge(branch.committedAt, now),
|
|
315
|
+
})),
|
|
316
|
+
];
|
|
317
|
+
if (note !== null)
|
|
318
|
+
rows.push({ indent: INDENT, name: note, state: "", tail: "" });
|
|
319
|
+
if (withheld > 0) {
|
|
320
|
+
rows.push({ indent: INDENT, name: `… and ${withheld} more`, state: "", tail: "" });
|
|
321
|
+
}
|
|
322
|
+
for (const problem of snapshot.problems) {
|
|
323
|
+
rows.push({ indent: INDENT, name: `! ${problem}`, state: "", tail: "" });
|
|
324
|
+
}
|
|
325
|
+
rows.push({ indent: "", name: "", state: "", tail: "" });
|
|
326
|
+
return rows;
|
|
327
|
+
}
|
|
328
|
+
/** null means the working tree was not read, which is silence rather than "clean". */
|
|
329
|
+
function renderDirty(count) {
|
|
330
|
+
return count === null || count === 0 ? "" : `${count} uncommitted`;
|
|
331
|
+
}
|
|
332
|
+
/** Most recently touched repository first — recency is what "in flight" means. */
|
|
333
|
+
function byRecency(a, b) {
|
|
334
|
+
const difference = latestCommit(b) - latestCommit(a);
|
|
335
|
+
return difference !== 0 ? difference : a.name.localeCompare(b.name);
|
|
336
|
+
}
|
|
337
|
+
function latestCommit(snapshot) {
|
|
338
|
+
return snapshot.branches.reduce((latest, branch) => {
|
|
339
|
+
const at = Date.parse(branch.committedAt);
|
|
340
|
+
return Number.isNaN(at) ? latest : Math.max(latest, at);
|
|
341
|
+
}, 0);
|
|
342
|
+
}
|
|
343
|
+
function byCommittedAtDesc(a, b) {
|
|
344
|
+
return (Date.parse(b.committedAt) || 0) - (Date.parse(a.committedAt) || 0);
|
|
345
|
+
}
|
|
346
|
+
function pad(text, width) {
|
|
347
|
+
return text.length >= width ? `${text} ` : text.padEnd(width);
|
|
348
|
+
}
|
|
349
|
+
function plural(count, one, many) {
|
|
350
|
+
return `${count} ${count === 1 ? one : many}`;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* How long since anything happened. Phrased as idleness rather than age
|
|
354
|
+
* because a pull request opened in May and discussed yesterday is not old in
|
|
355
|
+
* any sense the operator cares about.
|
|
356
|
+
*/
|
|
357
|
+
export function formatIdle(iso, now) {
|
|
358
|
+
const age = formatAge(iso, now);
|
|
359
|
+
if (age === "unknown")
|
|
360
|
+
return "";
|
|
361
|
+
if (age === "just now")
|
|
362
|
+
return "just now";
|
|
363
|
+
return `${age.replace(" ago", "")} idle`;
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Grouped by whose move it is, because that is the only question being asked.
|
|
367
|
+
* Drafts and running builds are counted but not listed — nobody is blocked on
|
|
368
|
+
* them, and a report that lists everything is the attention problem it was
|
|
369
|
+
* written to solve.
|
|
370
|
+
*/
|
|
371
|
+
export function renderPulls(groups, options) {
|
|
372
|
+
const { now, staleDays = DEFAULT_STALE_DAYS } = options;
|
|
373
|
+
const entries = groups.flatMap(group => group.pulls.map(pull => ({ repo: group.repo, pull, attention: classify(pull) })));
|
|
374
|
+
const problems = groups.flatMap(group => group.problems.map(problem => `${group.repo}: ${problem}`));
|
|
375
|
+
const blocking = ["human", "agent"];
|
|
376
|
+
const sections = blocking
|
|
377
|
+
.map(attention => renderAttention(attention, entries, now))
|
|
378
|
+
.filter((section) => section !== null);
|
|
379
|
+
if (sections.length === 0) {
|
|
380
|
+
return [renderNothingWaiting(entries, problems), ...renderProblems(problems)]
|
|
381
|
+
.join("\n")
|
|
382
|
+
.trimEnd();
|
|
383
|
+
}
|
|
384
|
+
const waiting = entries.filter(entry => blocking.includes(entry.attention));
|
|
385
|
+
const stalled = waiting.filter(entry => (idleDays(entry.pull, now) ?? 0) >= staleDays);
|
|
386
|
+
return [
|
|
387
|
+
renderPullsHeader(waiting.length, stalled.length, staleDays),
|
|
388
|
+
"",
|
|
389
|
+
...sections,
|
|
390
|
+
...renderProblems(problems),
|
|
391
|
+
...renderQuiet(entries),
|
|
392
|
+
]
|
|
393
|
+
.join("\n")
|
|
394
|
+
.trimEnd();
|
|
395
|
+
}
|
|
396
|
+
const ATTENTION_HEADINGS = {
|
|
397
|
+
human: "Waiting on you",
|
|
398
|
+
agent: "Waiting on an agent",
|
|
399
|
+
machine: "Waiting on CI",
|
|
400
|
+
none: "In progress",
|
|
401
|
+
};
|
|
402
|
+
/**
|
|
403
|
+
* Longest-idle first. The one that has been ignored the longest is the one
|
|
404
|
+
* most likely to have been forgotten rather than deferred.
|
|
405
|
+
*/
|
|
406
|
+
function renderAttention(attention, entries, now) {
|
|
407
|
+
const mine = entries
|
|
408
|
+
.filter(entry => entry.attention === attention)
|
|
409
|
+
.sort((a, b) => (idleDays(b.pull, now) ?? 0) - (idleDays(a.pull, now) ?? 0));
|
|
410
|
+
if (mine.length === 0)
|
|
411
|
+
return null;
|
|
412
|
+
const rows = mine.map(entry => ({
|
|
413
|
+
indent: INDENT,
|
|
414
|
+
name: `${entry.repo} #${entry.pull.number}`,
|
|
415
|
+
state: describePull(entry.pull),
|
|
416
|
+
tail: formatIdle(entry.pull.updatedAt, now),
|
|
417
|
+
}));
|
|
418
|
+
const nameWidth = widthOf(rows, row => row.indent.length + row.name.length, MIN_NAME_WIDTH, MAX_NAME_WIDTH);
|
|
419
|
+
const stateWidth = widthOf(rows, row => row.state.length, MIN_STATE_WIDTH, MAX_STATE_WIDTH);
|
|
420
|
+
return [
|
|
421
|
+
ATTENTION_HEADINGS[attention],
|
|
422
|
+
...rows.map(row => renderRow(row, nameWidth, stateWidth)),
|
|
423
|
+
"",
|
|
424
|
+
].join("\n");
|
|
425
|
+
}
|
|
426
|
+
function renderPullsHeader(waiting, stalled, staleDays) {
|
|
427
|
+
const headline = `${plural(waiting, "pull request", "pull requests")} waiting.`;
|
|
428
|
+
if (stalled === 0)
|
|
429
|
+
return headline;
|
|
430
|
+
const which = stalled === 1 ? "1 has" : `${stalled} have`;
|
|
431
|
+
return `${headline} ${which} been waiting more than ${plural(staleDays, "day", "days")}.`;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Nothing waiting is only good news if we managed to look. A repository whose
|
|
435
|
+
* pull requests could not be read has told us nothing, and saying "nothing is
|
|
436
|
+
* waiting" about it would be the silence this tool exists to break.
|
|
437
|
+
*/
|
|
438
|
+
function renderNothingWaiting(entries, problems) {
|
|
439
|
+
if (problems.length > 0 && entries.length === 0)
|
|
440
|
+
return "No pull requests were read.";
|
|
441
|
+
const quiet = renderQuiet(entries);
|
|
442
|
+
return ["Nothing is waiting on you.", ...quiet].join("\n");
|
|
443
|
+
}
|
|
444
|
+
/** Drafts and running builds: counted, so their absence above is not a mystery. */
|
|
445
|
+
function renderQuiet(entries) {
|
|
446
|
+
const drafts = entries.filter(entry => entry.attention === "none").length;
|
|
447
|
+
const running = entries.filter(entry => entry.attention === "machine").length;
|
|
448
|
+
const parts = [
|
|
449
|
+
drafts > 0 ? `${plural(drafts, "draft", "drafts")} in progress` : null,
|
|
450
|
+
running > 0 ? `${running} waiting on CI` : null,
|
|
451
|
+
].filter((part) => part !== null);
|
|
452
|
+
return parts.length === 0 ? [] : ["", `${parts.join(", ")}.`];
|
|
453
|
+
}
|
|
454
|
+
function renderProblems(problems) {
|
|
455
|
+
return problems.length === 0 ? [] : ["", ...problems.map(problem => `! ${problem}`)];
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* What work graph is already here.
|
|
459
|
+
*
|
|
460
|
+
* The recommended backend is marked with a pointer and nothing else is, because
|
|
461
|
+
* the one thing this report must not read as is a menu of things already
|
|
462
|
+
* switched on. Every line ends by saying what is *not* authorized, since
|
|
463
|
+
* detection is not authorization and a report that omitted that would be
|
|
464
|
+
* inviting exactly the wrong conclusion.
|
|
465
|
+
*/
|
|
466
|
+
export function renderGraph(detections, options = {}) {
|
|
467
|
+
if (detections.length === 0) {
|
|
468
|
+
return [
|
|
469
|
+
"No work graph found in your repositories.",
|
|
470
|
+
"",
|
|
471
|
+
"Toolroll looked for `.beads/`, `backlog.md`, and open GitHub Issues.",
|
|
472
|
+
"Nothing was installed or created — a tracker is yours to set up.",
|
|
473
|
+
].join("\n");
|
|
474
|
+
}
|
|
475
|
+
const choice = chooseBackend(detections, options.enrolled === undefined ? {} : { enrolled: options.enrolled });
|
|
476
|
+
const chosen = choice.action === "recommend" ? choice.kind : null;
|
|
477
|
+
const rows = detections.map(detection => ({
|
|
478
|
+
marker: detection.kind === chosen ? "▸ " : " ",
|
|
479
|
+
label: detection.label,
|
|
480
|
+
facts: describeDetection(detection),
|
|
481
|
+
}));
|
|
482
|
+
const labelWidth = Math.max(...rows.map(row => row.label.length));
|
|
483
|
+
const problems = detections.flatMap(detection => detection.problems);
|
|
484
|
+
return [
|
|
485
|
+
"Work graph — detected in your repos",
|
|
486
|
+
"",
|
|
487
|
+
...rows.map(row => `${row.marker}${row.label.padEnd(labelWidth)} ${row.facts}`),
|
|
488
|
+
"",
|
|
489
|
+
...describeChoice(choice),
|
|
490
|
+
...(choice.action === "built-in" ? renderSetup() : []),
|
|
491
|
+
...renderProblems(problems),
|
|
492
|
+
]
|
|
493
|
+
.join("\n")
|
|
494
|
+
.trimEnd();
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* The way forward when nothing is set up.
|
|
498
|
+
*
|
|
499
|
+
* Without this the empty case is a dead end — "no tracker found, and the
|
|
500
|
+
* fallback does not exist yet" — which tells an operator nothing they can act
|
|
501
|
+
* on. §4 requires the opposite: print the upstream command *and* what it will
|
|
502
|
+
* do, and let them run it.
|
|
503
|
+
*
|
|
504
|
+
* The side effects are not a footnote. `bd init` rewrites AGENTS.md and
|
|
505
|
+
* installs agent integrations, and somebody who ran it because a tool
|
|
506
|
+
* suggested it and only found that out afterwards would be right to be angry.
|
|
507
|
+
*/
|
|
508
|
+
function renderSetup() {
|
|
509
|
+
const lines = ["", "Setting one up — commands to run yourself, in your own shell:"];
|
|
510
|
+
for (const option of setupOptions()) {
|
|
511
|
+
lines.push("");
|
|
512
|
+
lines.push(` ${option.label}${option.note === null ? "" : ` — ${option.note}`}`);
|
|
513
|
+
if (option.install !== null)
|
|
514
|
+
lines.push(` ${option.install}`);
|
|
515
|
+
if (option.init !== null)
|
|
516
|
+
lines.push(` ${option.init}`);
|
|
517
|
+
if (option.sideEffects !== null)
|
|
518
|
+
lines.push(` → ${option.sideEffects}`);
|
|
519
|
+
}
|
|
520
|
+
lines.push("");
|
|
521
|
+
lines.push("Toolroll runs none of these. Re-run `toolroll graph` afterwards.");
|
|
522
|
+
return lines;
|
|
523
|
+
}
|
|
524
|
+
/** The middle column: where it is, how much is in it, and whether it could run. */
|
|
525
|
+
function describeDetection(detection) {
|
|
526
|
+
const parts = [];
|
|
527
|
+
if (detection.repos.length > 0) {
|
|
528
|
+
parts.push(`${plural(detection.repos.length, "repo", "repos")}`);
|
|
529
|
+
}
|
|
530
|
+
// A row with no number at all reads as zero. Absence of a count is its own
|
|
531
|
+
// fact and has to be said out loud.
|
|
532
|
+
parts.push(detection.count === null
|
|
533
|
+
? "count unknown"
|
|
534
|
+
: `${detection.count.value} ${detection.count.of}`);
|
|
535
|
+
parts.push(describeDeps(detection.deps));
|
|
536
|
+
parts.push(describeRuntime(detection));
|
|
537
|
+
return parts.join(" · ");
|
|
538
|
+
}
|
|
539
|
+
function describeDeps(deps) {
|
|
540
|
+
if (deps === "native")
|
|
541
|
+
return "native deps";
|
|
542
|
+
if (deps === "none")
|
|
543
|
+
return "no deps";
|
|
544
|
+
return "deps unverified";
|
|
545
|
+
}
|
|
546
|
+
function describeRuntime(detection) {
|
|
547
|
+
const { runtime } = detection;
|
|
548
|
+
if (runtime.state === "missing")
|
|
549
|
+
return `${runtime.binary} not installed`;
|
|
550
|
+
if (runtime.state === "outdated")
|
|
551
|
+
return `${runtime.version} too old, needs ${runtime.needs}`;
|
|
552
|
+
if (runtime.state === "unreadable")
|
|
553
|
+
return "runtime would not answer";
|
|
554
|
+
return runtime.version === null ? "runtime ok" : `runtime ok (${runtime.version})`;
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* The closing line always says nothing is enrolled, including when a backend
|
|
558
|
+
* is recommended. A recommendation that read as an activation would be the one
|
|
559
|
+
* misunderstanding this whole module is written to prevent.
|
|
560
|
+
*/
|
|
561
|
+
function describeChoice(choice) {
|
|
562
|
+
const lines = [];
|
|
563
|
+
if (choice.action === "recommend" && choice.why === "already enrolled") {
|
|
564
|
+
// An enrolled backend is not a suggestion, and must not read like one.
|
|
565
|
+
lines.push(`Enrolled: ${GRAPH_LABELS[choice.kind]}. Write access has been granted.`);
|
|
566
|
+
lines.push("`toolroll grants` shows exactly what, and `revoke` takes it back.");
|
|
567
|
+
return lines;
|
|
568
|
+
}
|
|
569
|
+
if (choice.action === "recommend") {
|
|
570
|
+
lines.push(`Suggested: ${GRAPH_LABELS[choice.kind]} — ${choice.why}.`);
|
|
571
|
+
if (!choice.dispatchable) {
|
|
572
|
+
// Deliberately not "it can be read, but…": when the runtime is missing
|
|
573
|
+
// it cannot be read either, and the sentence would contradict the row
|
|
574
|
+
// directly above it.
|
|
575
|
+
lines.push("Nothing here could be scheduled from it as it stands.");
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
else if (choice.action === "ambiguous") {
|
|
579
|
+
const names = choice.kinds.map(kind => GRAPH_LABELS[kind]).join(" and ");
|
|
580
|
+
lines.push(`${names} are both populated — ${choice.why}.`);
|
|
581
|
+
}
|
|
582
|
+
else {
|
|
583
|
+
lines.push(choice.why.charAt(0).toUpperCase() + choice.why.slice(1) + ".");
|
|
584
|
+
}
|
|
585
|
+
lines.push("Nothing is enrolled, and detection grants nothing.");
|
|
586
|
+
return lines;
|
|
587
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Store } from "./store.js";
|
|
2
|
+
/** The report a scout delivered, for get_task: title, summary, follow-ups —
|
|
3
|
+
* verified before it is read; the document itself stays on the task page. */
|
|
4
|
+
export declare function reportSummaryFor(store: Store, evidenceRoot: string | undefined, taskRef: number): {
|
|
5
|
+
title: string;
|
|
6
|
+
summary: string;
|
|
7
|
+
followUps: {
|
|
8
|
+
title: string;
|
|
9
|
+
goal: string;
|
|
10
|
+
}[];
|
|
11
|
+
} | {
|
|
12
|
+
problem: string;
|
|
13
|
+
} | null;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { readVerifiedReport } from "./evidence.js";
|
|
2
|
+
/** The report a scout delivered, for get_task: title, summary, follow-ups —
|
|
3
|
+
* verified before it is read; the document itself stays on the task page. */
|
|
4
|
+
export function reportSummaryFor(store, evidenceRoot, taskRef) {
|
|
5
|
+
if (store.latestReportArtifact(taskRef) === null)
|
|
6
|
+
return null;
|
|
7
|
+
if (evidenceRoot === undefined)
|
|
8
|
+
return { problem: "a report exists, but this surface cannot read evidence" };
|
|
9
|
+
const view = readVerifiedReport(store, evidenceRoot, taskRef);
|
|
10
|
+
if (view === null)
|
|
11
|
+
return null;
|
|
12
|
+
if (!view.ok)
|
|
13
|
+
return { problem: view.problem };
|
|
14
|
+
return { title: view.report.title, summary: view.report.summary, followUps: view.report.followUps };
|
|
15
|
+
}
|