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/mailbox.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading mail for Inbox triggers (v89).
|
|
3
|
+
*
|
|
4
|
+
* The mailbox is the same account emails are sent from (Settings → Email):
|
|
5
|
+
* a mail server's IMAP address with the same sign-in, or a connected Google
|
|
6
|
+
* account (IMAP with XOAUTH2). It is only ever read — opened read-only, and
|
|
7
|
+
* nothing is marked, moved or deleted — and only mail that arrives after a
|
|
8
|
+
* trigger is added becomes cards: the first check notes where the mailbox
|
|
9
|
+
* stands, and each later one reads what came after (by IMAP UID, restarting
|
|
10
|
+
* from "now" if the server renumbers the folder).
|
|
11
|
+
*
|
|
12
|
+
* Each message becomes plain words: the sender, the subject, and the body
|
|
13
|
+
* without the quoted history of earlier messages. Automatic replies (out of
|
|
14
|
+
* office, bounces) are left out, so a flow that answers mail can't end up
|
|
15
|
+
* answering machines. The card keeps the message's ID so a Send email step
|
|
16
|
+
* replying to the sender stays in the same thread.
|
|
17
|
+
*/
|
|
18
|
+
import { ImapFlow } from "imapflow";
|
|
19
|
+
import { simpleParser } from "mailparser";
|
|
20
|
+
import { googleAccessToken, googleConnected } from "./google-mail.js";
|
|
21
|
+
import { readEmailSettings } from "./email-settings.js";
|
|
22
|
+
const BODY_CHARS = 4000;
|
|
23
|
+
const SOURCE_BYTES = 2 * 1024 * 1024;
|
|
24
|
+
export function mailCursorOf(text) {
|
|
25
|
+
const match = text === null ? null : /^([0-9]{1,20}):([0-9]{1,12})$/.exec(text);
|
|
26
|
+
return match === null ? null : { validity: match[1], uid: Number(match[2]) };
|
|
27
|
+
}
|
|
28
|
+
export const mailCursorText = (at) => `${at.validity}:${at.uid}`;
|
|
29
|
+
// ------------------------------------------------------------- the account
|
|
30
|
+
/** Whether Inbox triggers can read mail: a connected Google account, or a mail server with its IMAP address. */
|
|
31
|
+
export function mailboxReady(dir) {
|
|
32
|
+
return googleConnected(dir) !== null || (readEmailSettings(dir)?.imap ?? null) !== null;
|
|
33
|
+
}
|
|
34
|
+
/** The mailbox to read, signed in: Google when connected, else the mail server's IMAP. */
|
|
35
|
+
export async function mailboxAccess(dir, fetcher) {
|
|
36
|
+
if (googleConnected(dir) !== null) {
|
|
37
|
+
const token = await googleAccessToken(dir, fetcher);
|
|
38
|
+
if (!token.ok)
|
|
39
|
+
return token;
|
|
40
|
+
return { ok: true, access: { host: "imap.gmail.com", port: 993, secure: true, user: token.address, accessToken: token.token }, address: token.address };
|
|
41
|
+
}
|
|
42
|
+
const server = readEmailSettings(dir);
|
|
43
|
+
if (server?.imap == null)
|
|
44
|
+
return { ok: false, said: "Reading mail isn't set up yet. Add the IMAP address in Settings → Email.", permanent: false };
|
|
45
|
+
return { ok: true, access: { host: server.imap.host, port: server.imap.port, secure: server.imap.secure, user: server.user || server.from, password: server.password }, address: server.from };
|
|
46
|
+
}
|
|
47
|
+
// ------------------------------------------------------------ the words
|
|
48
|
+
/** The new part of a message: no quoted earlier messages, no signature, tidy lines. */
|
|
49
|
+
export function freshText(text) {
|
|
50
|
+
const lines = text.replace(/\r\n?/g, "\n").replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/g, "").split("\n");
|
|
51
|
+
const kept = [];
|
|
52
|
+
for (const [index, line] of lines.entries()) {
|
|
53
|
+
const trimmed = line.trim();
|
|
54
|
+
// Where the history starts: "On <date>, <name> wrote:", an Outlook header block, or a forwarded-message marker.
|
|
55
|
+
if (/^On .{4,200} wrote:$/.test(trimmed) || /^-{2,}\s*(Original Message|Forwarded message)\s*-{2,}$/i.test(trimmed))
|
|
56
|
+
break;
|
|
57
|
+
if (/^From: .+$/.test(trimmed) && (lines[index + 1] ?? "").trim().match(/^(Sent|Date): /) !== null)
|
|
58
|
+
break;
|
|
59
|
+
// A signature: the "-- " line and everything after it.
|
|
60
|
+
if (line === "-- ")
|
|
61
|
+
break;
|
|
62
|
+
if (trimmed.startsWith(">"))
|
|
63
|
+
continue;
|
|
64
|
+
kept.push(line.trimEnd());
|
|
65
|
+
}
|
|
66
|
+
const joined = kept.join("\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
67
|
+
return joined.length > BODY_CHARS ? `${joined.slice(0, BODY_CHARS).trimEnd()}…` : joined;
|
|
68
|
+
}
|
|
69
|
+
const header = (headers, name) => {
|
|
70
|
+
const value = headers.get(name);
|
|
71
|
+
return typeof value === "string" ? value : value !== undefined && value !== null && typeof value === "object" && "value" in value ? String(value.value) : "";
|
|
72
|
+
};
|
|
73
|
+
/** One raw message as plain words, and whether a machine sent it. */
|
|
74
|
+
export async function readMail(uid, source) {
|
|
75
|
+
const parsed = await simpleParser(source, { skipImageLinks: true, skipTextToHtml: true, skipTextLinks: true });
|
|
76
|
+
const sender = parsed.from?.value[0];
|
|
77
|
+
const from = (sender?.address ?? "").toLowerCase();
|
|
78
|
+
const headers = parsed.headers;
|
|
79
|
+
const auto = header(headers, "auto-submitted").toLowerCase();
|
|
80
|
+
const precedence = header(headers, "precedence").toLowerCase();
|
|
81
|
+
const automatic = (auto !== "" && auto !== "no") || headers.has("x-autoreply") || headers.has("x-autorespond") || precedence === "auto_reply"
|
|
82
|
+
|| /^(mailer-daemon|postmaster)@/.test(from) || /multipart\/report/i.test(header(headers, "content-type"));
|
|
83
|
+
const references = (Array.isArray(parsed.references) ? parsed.references : typeof parsed.references === "string" ? parsed.references.split(/\s+/) : []).filter(one => /^<[^<>\s]{3,250}>$/.test(one)).slice(-20);
|
|
84
|
+
const replyTo = typeof parsed.inReplyTo === "string" ? /<[^<>\s]{3,250}>/.exec(parsed.inReplyTo)?.[0] ?? null : null;
|
|
85
|
+
return {
|
|
86
|
+
uid, messageId: typeof parsed.messageId === "string" && /^<[^<>\s]{3,250}>$/.test(parsed.messageId) ? parsed.messageId : null, inReplyTo: replyTo, references, from,
|
|
87
|
+
fromName: sender?.name && sender.name !== sender.address ? sender.name.slice(0, 120) : null,
|
|
88
|
+
subject: (parsed.subject ?? "").replace(/\s+/g, " ").trim().slice(0, 200), text: freshText(parsed.text ?? ""), automatic,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
// ------------------------------------------------------------ the reader
|
|
92
|
+
function problemOf(error) {
|
|
93
|
+
const code = String(error?.code ?? ""), text = String(error?.responseText ?? error?.message ?? "");
|
|
94
|
+
if (error?.authenticationFailed === true || /AUTHENTICATIONFAILED|Invalid credentials|LOGIN failed|authentication failed/i.test(text))
|
|
95
|
+
return { said: "The mail server didn't accept the sign-in. Check the username and password in Settings → Email (Gmail needs an app password).", permanent: false };
|
|
96
|
+
if (/NONEXISTENT|doesn't exist|Unknown Mailbox|no such mailbox/i.test(text))
|
|
97
|
+
return { said: "That folder doesn't exist in the mailbox.", permanent: false };
|
|
98
|
+
if (code === "ENOTFOUND" || code === "EAI_AGAIN")
|
|
99
|
+
return { said: "Couldn't find the mail server. Check its IMAP address in Settings → Email.", permanent: false };
|
|
100
|
+
if (code === "ECONNREFUSED" || code === "ETIMEDOUT" || code === "ECONNRESET" || /timeout/i.test(text))
|
|
101
|
+
return { said: "Couldn't reach the mail server just now.", permanent: false };
|
|
102
|
+
return { said: `The mail server said: ${text.split("\n")[0]?.slice(0, 160) || "something went wrong"}.`, permanent: false };
|
|
103
|
+
}
|
|
104
|
+
/** The production reader: one read-only IMAP visit. */
|
|
105
|
+
export const readThroughImap = async (access, folder, after, limit) => {
|
|
106
|
+
const client = new ImapFlow({
|
|
107
|
+
host: access.host, port: access.port, secure: access.secure, logger: false, disableAutoIdle: true,
|
|
108
|
+
auth: access.accessToken !== undefined ? { user: access.user, accessToken: access.accessToken } : { user: access.user, pass: access.password ?? "" },
|
|
109
|
+
connectionTimeout: 15_000, greetingTimeout: 15_000, socketTimeout: 60_000,
|
|
110
|
+
// A password never travels unencrypted: without TLS from the start, STARTTLS is required.
|
|
111
|
+
...(access.secure ? {} : { doSTARTTLS: true }),
|
|
112
|
+
});
|
|
113
|
+
client.on("error", () => { });
|
|
114
|
+
try {
|
|
115
|
+
await client.connect();
|
|
116
|
+
const lock = await client.getMailboxLock(folder, { readOnly: true });
|
|
117
|
+
try {
|
|
118
|
+
const box = client.mailbox;
|
|
119
|
+
if (box === false)
|
|
120
|
+
return { ok: false, said: "That folder couldn't be opened.", permanent: false };
|
|
121
|
+
const validity = String(box.uidValidity), last = Math.max(0, Number(box.uidNext) - 1);
|
|
122
|
+
// The first look, or a renumbered folder: note where it stands, and start from there.
|
|
123
|
+
if (after === null || after.validity !== validity)
|
|
124
|
+
return { ok: true, at: { validity, uid: last }, mails: [], renumbered: after !== null, more: false };
|
|
125
|
+
if (last <= after.uid)
|
|
126
|
+
return { ok: true, at: after, mails: [], renumbered: false, more: false };
|
|
127
|
+
const found = await client.search({ uid: `${after.uid + 1}:*` }, { uid: true });
|
|
128
|
+
const waiting = (Array.isArray(found) ? found : []).filter(uid => uid > after.uid).sort((a, b) => a - b);
|
|
129
|
+
const uids = waiting.slice(0, limit);
|
|
130
|
+
const mails = [];
|
|
131
|
+
if (uids.length > 0) {
|
|
132
|
+
for await (const message of client.fetch(uids.join(","), { uid: true, source: { start: 0, maxLength: SOURCE_BYTES } }, { uid: true })) {
|
|
133
|
+
if (message.source !== undefined)
|
|
134
|
+
mails.push(await readMail(message.uid, message.source));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
mails.sort((a, b) => a.uid - b.uid);
|
|
138
|
+
return { ok: true, at: { validity, uid: uids.at(-1) ?? after.uid }, mails, renumbered: false, more: waiting.length > uids.length };
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
lock.release();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
return { ok: false, ...problemOf(error) };
|
|
146
|
+
}
|
|
147
|
+
finally {
|
|
148
|
+
await client.logout().catch(() => client.close());
|
|
149
|
+
}
|
|
150
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Serialized background maintenance. It schedules no agent work: callers
|
|
2
|
+
* retain dispatch, ownership and recovery policy. Slow passes never overlap. */
|
|
3
|
+
export declare function startMaintenance(args: {
|
|
4
|
+
intervalMs: number;
|
|
5
|
+
run: () => Promise<void>;
|
|
6
|
+
shouldStop: () => boolean;
|
|
7
|
+
onError: (error: unknown) => void;
|
|
8
|
+
}): {
|
|
9
|
+
runNow: () => Promise<void>;
|
|
10
|
+
stop: () => Promise<void>;
|
|
11
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** Serialized background maintenance. It schedules no agent work: callers
|
|
2
|
+
* retain dispatch, ownership and recovery policy. Slow passes never overlap. */
|
|
3
|
+
export function startMaintenance(args) {
|
|
4
|
+
if (!Number.isSafeInteger(args.intervalMs) || args.intervalMs < 1 || args.intervalMs > 2_147_483_647) {
|
|
5
|
+
throw new Error("maintenance interval must be an integer from 1 to 2147483647 milliseconds");
|
|
6
|
+
}
|
|
7
|
+
let stopped = false;
|
|
8
|
+
let pending = null;
|
|
9
|
+
const runNow = () => {
|
|
10
|
+
if (stopped || args.shouldStop())
|
|
11
|
+
return Promise.resolve();
|
|
12
|
+
if (pending !== null)
|
|
13
|
+
return pending;
|
|
14
|
+
pending = Promise.resolve().then(async () => {
|
|
15
|
+
if (!stopped && !args.shouldStop())
|
|
16
|
+
await args.run();
|
|
17
|
+
}).catch(error => {
|
|
18
|
+
try {
|
|
19
|
+
args.onError(error);
|
|
20
|
+
}
|
|
21
|
+
catch { /* Reporting cannot create an unhandled timer rejection. */ }
|
|
22
|
+
}).finally(() => { pending = null; });
|
|
23
|
+
return pending;
|
|
24
|
+
};
|
|
25
|
+
const timer = setInterval(() => { void runNow(); }, args.intervalMs);
|
|
26
|
+
timer.unref?.();
|
|
27
|
+
return {
|
|
28
|
+
runNow,
|
|
29
|
+
stop: async () => {
|
|
30
|
+
stopped = true;
|
|
31
|
+
clearInterval(timer);
|
|
32
|
+
await pending;
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { MateProposal, Store } from "./store.js";
|
|
2
|
+
import type { SubscriptionMateRunner } from "./subscription-chat.js";
|
|
3
|
+
export type MateCliSeams = {
|
|
4
|
+
fetcher?: typeof fetch;
|
|
5
|
+
env?: Record<string, string | undefined>;
|
|
6
|
+
/** Lines the REPL reads instead of stdin (tests). */
|
|
7
|
+
lines?: AsyncIterable<string> | Iterable<string>;
|
|
8
|
+
clock?: () => Date;
|
|
9
|
+
/** Subscription harness seam; tests never consume a real membership turn. */
|
|
10
|
+
subscriptionRunner?: SubscriptionMateRunner;
|
|
11
|
+
};
|
|
12
|
+
export type MateCliInput = {
|
|
13
|
+
store: Store;
|
|
14
|
+
databaseFile: string;
|
|
15
|
+
write: (line: string) => void;
|
|
16
|
+
json: boolean;
|
|
17
|
+
credentials: {
|
|
18
|
+
name: string;
|
|
19
|
+
token: string;
|
|
20
|
+
};
|
|
21
|
+
/** The ceiling: explicit `--repo` paths, or the enrolled projects when none are named. */
|
|
22
|
+
repos: readonly string[];
|
|
23
|
+
say: string | undefined;
|
|
24
|
+
end: boolean;
|
|
25
|
+
follow?: boolean;
|
|
26
|
+
ceilingUsd: number | undefined;
|
|
27
|
+
seams?: MateCliSeams;
|
|
28
|
+
/** Where evidence lives — a scout's report reads from here. */
|
|
29
|
+
evidenceRoot?: string;
|
|
30
|
+
};
|
|
31
|
+
export type MateCliResult = {
|
|
32
|
+
code: number;
|
|
33
|
+
reason?: string;
|
|
34
|
+
message?: string;
|
|
35
|
+
};
|
|
36
|
+
export declare const MATE_CLI_EXIT: {
|
|
37
|
+
readonly ok: 0;
|
|
38
|
+
readonly failed: 1;
|
|
39
|
+
readonly usage: 2;
|
|
40
|
+
readonly refused: 3;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* What a terminal must show before an answer is confirmed (v3 review,
|
|
44
|
+
* finding 4): the question, every option with its consequence, which one
|
|
45
|
+
* the builder recommends, which one is proposed — the card's content.
|
|
46
|
+
*/
|
|
47
|
+
export declare function answerContextLines(store: Store, payload: Record<string, unknown>): string[];
|
|
48
|
+
/** One line per proposal, numbered in thread order, for the operator to name. */
|
|
49
|
+
export declare function proposalLines(proposals: readonly MateProposal[], repos: readonly string[], ordinal?: (proposal: MateProposal) => number): string[];
|
|
50
|
+
/** The lines for one proposal, its answer context included when it is an answer. */
|
|
51
|
+
export declare function proposalBlock(store: Store, proposal: MateProposal, repos: readonly string[], number: number): string[];
|
|
52
|
+
export declare function runMateCli(input: MateCliInput): Promise<MateCliResult>;
|
package/dist/mate-cli.js
ADDED
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import { configureLeadFollow, leadFollowStatus } from './lead-follow.js';
|
|
2
|
+
/**
|
|
3
|
+
* `toolroll chat` (mate arc §6): the same thread the console shows,
|
|
4
|
+
* driven from a terminal. The password is typed once — it mints the mate
|
|
5
|
+
* session, the one ceremony a conversation gets — and every later turn
|
|
6
|
+
* debits that session without asking again. Confirming a card runs the
|
|
7
|
+
* same doors the console runs; password-class acts (approving a scope,
|
|
8
|
+
* cancelling) print where to do them instead of doing them here.
|
|
9
|
+
*/
|
|
10
|
+
import { createHash } from "node:crypto";
|
|
11
|
+
import { readFileSync } from "node:fs";
|
|
12
|
+
import { dirname, join } from "node:path";
|
|
13
|
+
import { CHAT_KEY_ENV, credentialKeyOf, isDirectChatProvider, priceForConfig, subscriptionCredentialKey } from "./converse.js";
|
|
14
|
+
import { verifyApproverByPassword } from "./principal.js";
|
|
15
|
+
import { runMateTurn } from "./mate.js";
|
|
16
|
+
import { confirmMateProposal, dismissMateProposal } from "./mate-doors.js";
|
|
17
|
+
import { projectName } from "./project.js";
|
|
18
|
+
import { CHAT_CONTROLS, chatControlHref, isChatControl } from "./chat-controls.js";
|
|
19
|
+
import { CHAT_TASK_ACTIONS, isChatTaskAction } from "./chat-task-actions.js";
|
|
20
|
+
export const MATE_CLI_EXIT = { ok: 0, failed: 1, usage: 2, refused: 3 };
|
|
21
|
+
function money(microusd) {
|
|
22
|
+
return `$${(microusd / 1_000_000).toFixed(2)}`;
|
|
23
|
+
}
|
|
24
|
+
function keyFor(config, databaseFile, env) {
|
|
25
|
+
const fromEnv = env[CHAT_KEY_ENV[config.provider]];
|
|
26
|
+
if (fromEnv !== undefined && fromEnv !== "")
|
|
27
|
+
return fromEnv;
|
|
28
|
+
try {
|
|
29
|
+
const read = readFileSync(join(dirname(databaseFile), `chat-key-${config.provider}`), "utf8").trim();
|
|
30
|
+
return read === "" ? null : read;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* What a terminal must show before an answer is confirmed (v3 review,
|
|
38
|
+
* finding 4): the question, every option with its consequence, which one
|
|
39
|
+
* the builder recommends, which one is proposed — the card's content.
|
|
40
|
+
*/
|
|
41
|
+
export function answerContextLines(store, payload) {
|
|
42
|
+
const id = typeof payload["decision"] === "number" ? payload["decision"] : null;
|
|
43
|
+
const decision = id === null ? null : store.getDecision(id);
|
|
44
|
+
if (decision === null)
|
|
45
|
+
return [" (the decision is gone)"];
|
|
46
|
+
const pick = typeof payload["option"] === "string" ? payload["option"] : "";
|
|
47
|
+
return [
|
|
48
|
+
` ${decision.question}${decision.state !== "open" ? ` [${decision.state}]` : ""}`,
|
|
49
|
+
...decision.options.map(one => ` ${one.id === pick ? "→" : " "} ${one.label}${one.reversible ? "" : " (irreversible)"}${one.id === decision.recommendation ? " — the builder recommends this" : ""}: ${one.consequence}`),
|
|
50
|
+
];
|
|
51
|
+
}
|
|
52
|
+
/** One line per proposal, numbered in thread order, for the operator to name. */
|
|
53
|
+
export function proposalLines(proposals, repos, ordinal = (_p) => 0) {
|
|
54
|
+
return proposals.map((one, index) => {
|
|
55
|
+
const number = ordinal(one) || index + 1;
|
|
56
|
+
const payload = one.payload;
|
|
57
|
+
const t = (key) => (typeof payload[key] === "string" ? payload[key] : "");
|
|
58
|
+
const repoLabel = (() => {
|
|
59
|
+
const id = t("repoId");
|
|
60
|
+
const path = /^r[0-9]+$/.test(id) ? repos[Number(id.slice(1)) - 1] : undefined;
|
|
61
|
+
return path === undefined ? id : `${id} ${projectName(path)}`;
|
|
62
|
+
})();
|
|
63
|
+
const what = one.kind === "task_action"
|
|
64
|
+
? `${isChatTaskAction(payload["operation"]) ? CHAT_TASK_ACTIONS[payload["operation"]].label : "Unavailable"}: ${t("taskTitle") || t("task")}${t("dependencyTitle") ? ` · ${t("dependencyTitle")}` : ""}`
|
|
65
|
+
: one.kind === "review"
|
|
66
|
+
? `${t("operation") === "revise" ? "request a revision" : "save feedback"} for ${t("taskTitle") || t("task")}: ${t("note")}${Array.isArray(payload["notes"]) && payload["notes"].length > 0 ? ` (saved notes: ${payload["notes"].join(", ")})` : ""}`
|
|
67
|
+
: one.kind === "control"
|
|
68
|
+
? (isChatControl(payload["control"]) ? `${CHAT_CONTROLS[payload["control"]].label}: ${chatControlHref(payload["control"], t("task"), payload["run"], payload["project"])} (open in the console)` : "control unavailable")
|
|
69
|
+
: one.kind === "steer" ? `guide ${t("task")}'s next attempt: ${t("note")}`
|
|
70
|
+
: one.kind === "agents" ? `change agents for ${t("task")}: ${t("role")} ${t("provider")} ${t("model")} ${t("risk")}`
|
|
71
|
+
: one.kind === "repair" ? `${t("operation")} dependency ${t("blocker")} for ${t("task")}`
|
|
72
|
+
:
|
|
73
|
+
one.kind === "task"
|
|
74
|
+
? `file "${t("title")}" in ${repoLabel}${payload["report"] === true ? " (a scout task — it delivers a report, never a branch)" : ""}`
|
|
75
|
+
: one.kind === "next"
|
|
76
|
+
? `move ${t("task")} to the front (was ${String(payload["position"] ?? "?")} of ${String(payload["of"] ?? "?")})`
|
|
77
|
+
: one.kind === "reserve"
|
|
78
|
+
? `${payload["worker"] === null ? `release ${t("task")} to the shared queue` : `reserve ${t("task")} for ${t("worker")}`}`
|
|
79
|
+
: one.kind === "hold"
|
|
80
|
+
? `hold ${t("task")}: ${t("reason")}`
|
|
81
|
+
: one.kind === "unhold"
|
|
82
|
+
? `release ${t("task")} from its hold`
|
|
83
|
+
: one.kind === "answer"
|
|
84
|
+
? `answer decision #${String(payload["decision"])} on ${t("task")} with "${t("optionLabel")}"${payload["reversible"] === false ? " (irreversible — confirm N yes)" : ""}: ${t("rationale")}`
|
|
85
|
+
: one.kind === "scope"
|
|
86
|
+
? `rewrite the scope of ${t("task")} (then approve it: toolroll task approve ${t("task")})`
|
|
87
|
+
: `cancel ${t("task")}: ${t("reason")} (arm it yourself: toolroll task cancel ${t("task")})`;
|
|
88
|
+
const state = one.state === "pending" ? "" : ` [${one.state}${one.outcome !== null && typeof one.outcome.said === "string" ? `: ${one.outcome.said}` : ""}]`;
|
|
89
|
+
return ` ${number}. ${what}${state}`;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/** The lines for one proposal, its answer context included when it is an answer. */
|
|
93
|
+
export function proposalBlock(store, proposal, repos, number) {
|
|
94
|
+
const [line] = proposalLines([proposal], repos, () => number);
|
|
95
|
+
if (proposal.kind === "review") {
|
|
96
|
+
const snapshot = proposal.payload["snapshot"];
|
|
97
|
+
const selected = Array.isArray(proposal.payload["notes"]) ? proposal.payload["notes"] : [];
|
|
98
|
+
const notes = snapshot?.notes.filter(one => selected.includes(one.id)) ?? [];
|
|
99
|
+
return [line, ...notes.map(one => ` ${one.path === null ? "" : `${one.path}${one.line === null ? "" : `:${one.line}`}: `}${one.note}`),
|
|
100
|
+
proposal.payload["operation"] === "revise" ? " Creates a revision of the same task; approval is separate." : " Saves feedback; no work starts."];
|
|
101
|
+
}
|
|
102
|
+
return proposal.kind === "answer" ? [line, ...answerContextLines(store, proposal.payload)] : [line];
|
|
103
|
+
}
|
|
104
|
+
async function* linesOf(seams) {
|
|
105
|
+
if (seams?.lines !== undefined) {
|
|
106
|
+
for await (const line of seams.lines)
|
|
107
|
+
yield line;
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const { createInterface } = await import("node:readline");
|
|
111
|
+
const reader = createInterface({ input: process.stdin, terminal: false });
|
|
112
|
+
try {
|
|
113
|
+
for await (const line of reader)
|
|
114
|
+
yield line;
|
|
115
|
+
}
|
|
116
|
+
finally {
|
|
117
|
+
reader.close();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
export async function runMateCli(input) {
|
|
121
|
+
const { store, write, json } = input;
|
|
122
|
+
const seams = input.seams ?? {};
|
|
123
|
+
const clock = seams.clock ?? (() => new Date());
|
|
124
|
+
const env = seams.env ?? process.env;
|
|
125
|
+
const say = (line) => {
|
|
126
|
+
if (!json)
|
|
127
|
+
write(line);
|
|
128
|
+
};
|
|
129
|
+
const emit = (envelope) => {
|
|
130
|
+
if (json)
|
|
131
|
+
write(JSON.stringify({ command: "chat", ...envelope }));
|
|
132
|
+
};
|
|
133
|
+
const refuse = (reason, message, code = MATE_CLI_EXIT.refused) => {
|
|
134
|
+
if (json)
|
|
135
|
+
write(JSON.stringify({ ok: false, command: "chat", reason, message }));
|
|
136
|
+
else
|
|
137
|
+
write(message);
|
|
138
|
+
return { code, reason, message };
|
|
139
|
+
};
|
|
140
|
+
if (store.isDemo())
|
|
141
|
+
return refuse("demo", "this is a demo database — chat cannot contact an external model");
|
|
142
|
+
const config = store.getChatConfig();
|
|
143
|
+
if (config === null)
|
|
144
|
+
return refuse("unconfigured", "chat is not configured — choose a membership or direct API provider with toolroll config set chat");
|
|
145
|
+
const directProvider = isDirectChatProvider(config.provider) ? config.provider : null;
|
|
146
|
+
const subscriptionProvider = directProvider === null ? config.provider : null;
|
|
147
|
+
const direct = directProvider !== null;
|
|
148
|
+
if (direct && priceForConfig(config) === null)
|
|
149
|
+
return refuse("unpriced", `no pinned price for ${config.model} — re-save the chat configuration`);
|
|
150
|
+
const key = direct ? keyFor(config, input.databaseFile, env) : null;
|
|
151
|
+
if (direct && key === null)
|
|
152
|
+
return refuse("no-key", `no ${directProvider} key — export ${CHAT_KEY_ENV[directProvider]}, or paste one on the console's chat page`);
|
|
153
|
+
const repos = [...input.repos];
|
|
154
|
+
if (repos.length === 0)
|
|
155
|
+
return refuse("empty-ceiling", "the mate needs projects to see — name them with --repo, or enroll some in the console", MATE_CLI_EXIT.usage);
|
|
156
|
+
const verified = verifyApproverByPassword(store, input.credentials.name, input.credentials.token, repos);
|
|
157
|
+
if (!verified.ok)
|
|
158
|
+
return refuse("unauthenticated", "that is not an approver, or the password does not match");
|
|
159
|
+
const who = verified.who;
|
|
160
|
+
let now = clock();
|
|
161
|
+
if (input.end) {
|
|
162
|
+
const turns = store.failLiveMateTurnsFor(who.name, "ended", now);
|
|
163
|
+
const sessions = store.endMateSessionsFor(who.name, who.name, now);
|
|
164
|
+
const threads = store.closeMateThreadsFor(who.name, now);
|
|
165
|
+
emit({ ok: true, ended: { sessions, threads, turns } });
|
|
166
|
+
say(sessions === 0 ? "no mate session was live; the thread is gone" : "the session is over and the thread is forgotten");
|
|
167
|
+
return { code: MATE_CLI_EXIT.ok };
|
|
168
|
+
}
|
|
169
|
+
store.sweepStaleMateTurns(now);
|
|
170
|
+
let session = store.activeMateSession(who.name);
|
|
171
|
+
const credentialKey = direct ? credentialKeyOf(directProvider, key) : subscriptionCredentialKey(subscriptionProvider);
|
|
172
|
+
if (session !== null && session.credentialKey !== credentialKey) {
|
|
173
|
+
// A session minted under another provider key cannot be spent by this
|
|
174
|
+
// one (slice-2 review, finding 9): say so, never loop on `not-yours`.
|
|
175
|
+
return refuse("key-mismatch", "the live mate session was minted under a different provider key — use that key, or end the session with --end and mint a new one");
|
|
176
|
+
}
|
|
177
|
+
if (session !== null && session.ceilingDigest !== who.ceilingDigest) {
|
|
178
|
+
store.endMateSession(session.id, who.name, now);
|
|
179
|
+
store.closeMateThreadsFor(who.name, now);
|
|
180
|
+
say("the projects named differ from the live session's — that session ended; minting a new one");
|
|
181
|
+
session = null;
|
|
182
|
+
}
|
|
183
|
+
if (session === null) {
|
|
184
|
+
const ceilingUsd = direct ? (input.ceilingUsd ?? 5) : 0;
|
|
185
|
+
if (direct && (!Number.isFinite(ceilingUsd) || ceilingUsd <= 0 || ceilingUsd > 1_000))
|
|
186
|
+
return refuse("usage", "--ceiling-usd is a dollar amount between 0 and 1000", MATE_CLI_EXIT.usage);
|
|
187
|
+
const ceilingMicrousd = Math.round(ceilingUsd * 1_000_000);
|
|
188
|
+
const termsDigest = createHash("sha256").update(`${ceilingMicrousd}\n${who.ceilingDigest}`).digest("hex");
|
|
189
|
+
const id = store.mintMateSession({ approver: who.name, approverGeneration: who.generation, credentialKey, ceilingMicrousd, ceilingDigest: who.ceilingDigest, termsDigest }, now);
|
|
190
|
+
session = store.getMateSession(id);
|
|
191
|
+
if (session === null)
|
|
192
|
+
return refuse("failed", "the session could not be minted", MATE_CLI_EXIT.failed);
|
|
193
|
+
if (!direct && input.ceilingUsd !== undefined)
|
|
194
|
+
say("the supplied --ceiling-usd value is ignored for membership usage");
|
|
195
|
+
say(`mate conversation started: ${direct ? `up to ${money(ceilingMicrousd)}` : "subscription usage (no dollar ceiling)"} over ${repos.map((one, index) => `r${index + 1} ${projectName(one)}`).join(", ")} — live until you end it`);
|
|
196
|
+
if (direct)
|
|
197
|
+
say(`(the weekly chat ceiling, ${money(config.weeklyCeilingMicrousd)}, still binds above it)`);
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
say(`mate conversation live: ${direct ? `${money(session.spentMicrousd)} of ${money(session.ceilingMicrousd)} spent` : "subscription usage (no dollar ceiling)"} — live until you end it`);
|
|
201
|
+
}
|
|
202
|
+
const thread = store.openMateThread(who.name, who.ceilingDigest, now).thread;
|
|
203
|
+
if (input.follow !== undefined) {
|
|
204
|
+
if (!configureLeadFollow(store, who, session, thread, input.follow, now))
|
|
205
|
+
return refuse("standing", "Conversation access changed.");
|
|
206
|
+
say(leadFollowStatus(store, who.name).detail);
|
|
207
|
+
emit({ ok: true, follow: leadFollowStatus(store, who.name) });
|
|
208
|
+
}
|
|
209
|
+
const pendingProposals = () => store.listMateProposals(thread.id, ["pending"]);
|
|
210
|
+
// Ordinals are assigned once per proposal and never reused within this
|
|
211
|
+
// run (slice-2 review, finding 4): `confirm 2` means the card printed as
|
|
212
|
+
// 2, whatever the console did to its neighbours meanwhile.
|
|
213
|
+
const ordinals = new Map();
|
|
214
|
+
const ordinalOf = (proposal) => {
|
|
215
|
+
const known = ordinals.get(proposal.id);
|
|
216
|
+
if (known !== undefined)
|
|
217
|
+
return known;
|
|
218
|
+
const next = ordinals.size + 1;
|
|
219
|
+
ordinals.set(proposal.id, next);
|
|
220
|
+
return next;
|
|
221
|
+
};
|
|
222
|
+
const byOrdinal = (ordinal) => {
|
|
223
|
+
for (const [id, n] of ordinals)
|
|
224
|
+
if (n === ordinal)
|
|
225
|
+
return store.getMateProposal(id);
|
|
226
|
+
return null;
|
|
227
|
+
};
|
|
228
|
+
const printProposals = () => {
|
|
229
|
+
const rows = pendingProposals();
|
|
230
|
+
if (rows.length === 0)
|
|
231
|
+
return;
|
|
232
|
+
say("proposals — `confirm N`, `dismiss N`, `open N`:");
|
|
233
|
+
for (const row of rows)
|
|
234
|
+
ordinalOf(row);
|
|
235
|
+
for (const row of rows)
|
|
236
|
+
for (const line of proposalBlock(store, row, repos, ordinalOf(row)))
|
|
237
|
+
say(line);
|
|
238
|
+
};
|
|
239
|
+
const turn = async (message) => {
|
|
240
|
+
const live = store.activeMateSession(who.name);
|
|
241
|
+
if (live === null) {
|
|
242
|
+
const outcome = { ok: false, refused: "session-ended", message: "this mate session has ended — run chat again to mint one" };
|
|
243
|
+
return outcome;
|
|
244
|
+
}
|
|
245
|
+
return runMateTurn({ store, who, session: live, thread, config, key, message, ...(seams.fetcher === undefined ? {} : { fetcher: seams.fetcher }), ...(seams.subscriptionRunner === undefined ? {} : { subscriptionRunner: seams.subscriptionRunner }), ...(input.evidenceRoot === undefined ? {} : { evidenceRoot: input.evidenceRoot }), clock });
|
|
246
|
+
};
|
|
247
|
+
const report = (outcome) => {
|
|
248
|
+
if (outcome.ok && outcome.replayed) {
|
|
249
|
+
emit(outcome);
|
|
250
|
+
say(`Message already received as turn #${outcome.turn}.`);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
if (outcome.ok) {
|
|
254
|
+
emit({ ok: true, turn: outcome.turn, reply: outcome.reply, activity: outcome.activity, steps: outcome.steps, settledMicrousd: outcome.settledMicrousd, proposals: pendingProposals().map(one => ({ id: one.id, ordinal: ordinalOf(one), kind: one.kind, payload: one.payload })) });
|
|
255
|
+
say(` ${outcome.activity}`);
|
|
256
|
+
say(outcome.reply);
|
|
257
|
+
printProposals();
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
emit({ ok: false, ...("refused" in outcome ? { reason: outcome.refused } : { turn: outcome.turn, reason: outcome.failed, unknownSpend: outcome.unknownSpend }), message: outcome.message });
|
|
261
|
+
say(outcome.message);
|
|
262
|
+
};
|
|
263
|
+
if (input.say !== undefined) {
|
|
264
|
+
const outcome = await turn(input.say);
|
|
265
|
+
report(outcome);
|
|
266
|
+
return { code: outcome.ok ? MATE_CLI_EXIT.ok : MATE_CLI_EXIT.refused };
|
|
267
|
+
}
|
|
268
|
+
// The REPL. Text is a turn; a few words are acts on the cards.
|
|
269
|
+
say("say something, or: proposals · confirm N · dismiss N · open N · end · quit");
|
|
270
|
+
const openTask = (proposal) => {
|
|
271
|
+
if (proposal.kind === "control" && isChatControl(proposal.payload["control"])) {
|
|
272
|
+
say(`Open in the console: ${chatControlHref(proposal.payload["control"], String(proposal.payload["task"] ?? ""), proposal.payload["run"], proposal.payload["project"])}`);
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
const taskId = typeof proposal.payload["task"] === "string" ? proposal.payload["task"] : null;
|
|
276
|
+
if (taskId === null) {
|
|
277
|
+
say("that proposal names no task yet");
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
const task = store.getTask(taskId);
|
|
281
|
+
const scope = store.getScope(taskId);
|
|
282
|
+
say(task === null ? `no task ${taskId}` : `${taskId} · ${task.title} · ${task.state}${scope === null ? "" : `\n goal: ${scope.goal}${scope.outOfScope === null ? "" : `\n not: ${scope.outOfScope}`}${scope.touches.length === 0 ? "" : `\n touches: ${scope.touches.join(", ")}`}`}`);
|
|
283
|
+
};
|
|
284
|
+
for await (const raw of linesOf(seams)) {
|
|
285
|
+
const line = raw.trim();
|
|
286
|
+
if (line === "")
|
|
287
|
+
continue;
|
|
288
|
+
now = clock();
|
|
289
|
+
const act = /^(confirm|dismiss|open)\s+([0-9]{1,3})(\s+yes)?$/i.exec(line);
|
|
290
|
+
if (act !== null) {
|
|
291
|
+
for (const row of pendingProposals())
|
|
292
|
+
ordinalOf(row);
|
|
293
|
+
const proposal = byOrdinal(Number(act[2]));
|
|
294
|
+
if (proposal === null) {
|
|
295
|
+
say(`no proposal ${act[2]}`);
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
if (proposal.state !== "pending" && act[1].toLowerCase() !== "open") {
|
|
299
|
+
say(`proposal ${act[2]} is ${proposal.state}${proposal.outcome !== null && typeof proposal.outcome.said === "string" ? `: ${proposal.outcome.said}` : ""}`);
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
const verb = act[1].toLowerCase();
|
|
303
|
+
if (verb === "open") {
|
|
304
|
+
openTask(proposal);
|
|
305
|
+
}
|
|
306
|
+
else if (verb === "dismiss") {
|
|
307
|
+
const done = dismissMateProposal(store, who, proposal.id, now);
|
|
308
|
+
emit({ ok: done, act: "dismiss", proposal: proposal.id });
|
|
309
|
+
say(done ? `dismissed ${act[2]}` : "that proposal was already acted on");
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
const outcome = confirmMateProposal(store, who, proposal.id, now, { confirm: act[3] !== undefined, via: "cli", ...(input.evidenceRoot === undefined ? {} : { evidenceRoot: input.evidenceRoot }) });
|
|
313
|
+
emit({ ok: outcome.ok, act: "confirm", proposal: proposal.id, ...(outcome.ok ? { said: outcome.said, taskId: outcome.taskId } : { reason: outcome.reason, said: outcome.said }) });
|
|
314
|
+
say(outcome.ok ? outcome.said : outcome.reason === "needs-confirm" ? `${outcome.said}: confirm ${act[2]} yes` : `refused: ${outcome.said}`);
|
|
315
|
+
if (outcome.ok && outcome.kind === "scope" && outcome.taskId !== null)
|
|
316
|
+
say(`approve it with your password: toolroll task approve ${outcome.taskId}`);
|
|
317
|
+
}
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
const word = line.toLowerCase();
|
|
321
|
+
if (word === "proposals") {
|
|
322
|
+
if (pendingProposals().length === 0)
|
|
323
|
+
say("no proposals are pending");
|
|
324
|
+
else
|
|
325
|
+
printProposals();
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
if (word === "quit" || word === "exit")
|
|
329
|
+
break;
|
|
330
|
+
if (word === "end") {
|
|
331
|
+
store.failLiveMateTurnsFor(who.name, "ended", now);
|
|
332
|
+
store.endMateSessionsFor(who.name, who.name, now);
|
|
333
|
+
store.closeMateThreadsFor(who.name, now);
|
|
334
|
+
say("the session is over and the thread is forgotten");
|
|
335
|
+
emit({ ok: true, ended: true });
|
|
336
|
+
return { code: MATE_CLI_EXIT.ok };
|
|
337
|
+
}
|
|
338
|
+
if (word === "help" || word === "?") {
|
|
339
|
+
say("say something, or: proposals · confirm N · dismiss N · open N · end · quit");
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
report(await turn(line));
|
|
343
|
+
}
|
|
344
|
+
return { code: MATE_CLI_EXIT.ok };
|
|
345
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The contract the mate reads (mate arc §4): plain words, versioned. It
|
|
3
|
+
* tells the model what the plane is, that every act is a proposal the
|
|
4
|
+
* operator confirms, the honesty and copy rules, when to ask instead of
|
|
5
|
+
* propose, and the shape of a good recap. Paths, consequences, and
|
|
6
|
+
* recommendations never reach the model — the tools already hide them —
|
|
7
|
+
* so the contract need not forbid repeating what it cannot see.
|
|
8
|
+
*/
|
|
9
|
+
export declare const MATE_CONTRACT_VERSION = 43;
|
|
10
|
+
export declare const MATE_CONTRACT: string;
|