toolroll 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1113 -0
- package/THIRD_PARTY_NOTICES.md +449 -0
- package/dist/accent-colors.d.ts +48 -0
- package/dist/accent-colors.js +122 -0
- package/dist/action-ledger.d.ts +26 -0
- package/dist/action-ledger.js +75 -0
- package/dist/agent-fence.d.ts +42 -0
- package/dist/agent-fence.js +183 -0
- package/dist/agentconfig.d.ts +216 -0
- package/dist/agentconfig.js +454 -0
- package/dist/api-tokens.d.ts +16 -0
- package/dist/api-tokens.js +27 -0
- package/dist/approval-policy.d.ts +69 -0
- package/dist/approval-policy.js +137 -0
- package/dist/approval-rules-ui.d.ts +25 -0
- package/dist/approval-rules-ui.js +39 -0
- package/dist/assignment-adapters.d.ts +180 -0
- package/dist/assignment-adapters.js +239 -0
- package/dist/assignment-brief.d.ts +71 -0
- package/dist/assignment-brief.js +129 -0
- package/dist/assignment-delivery.d.ts +56 -0
- package/dist/assignment-delivery.js +160 -0
- package/dist/assignment-presentation.d.ts +26 -0
- package/dist/assignment-presentation.js +80 -0
- package/dist/assignment-status.d.ts +62 -0
- package/dist/assignment-status.js +152 -0
- package/dist/assignment-ui.d.ts +71 -0
- package/dist/assignment-ui.js +103 -0
- package/dist/assignment.d.ts +222 -0
- package/dist/assignment.js +399 -0
- package/dist/attest.d.ts +56 -0
- package/dist/attest.js +153 -0
- package/dist/backend.d.ts +97 -0
- package/dist/backend.js +166 -0
- package/dist/backup-ui.d.ts +22 -0
- package/dist/backup-ui.js +59 -0
- package/dist/backup.d.ts +84 -0
- package/dist/backup.js +421 -0
- package/dist/beads.d.ts +34 -0
- package/dist/beads.js +135 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +22 -0
- package/dist/board.d.ts +150 -0
- package/dist/board.js +210 -0
- package/dist/boot-identity.d.ts +63 -0
- package/dist/boot-identity.js +99 -0
- package/dist/browser/THIRD_PARTY_NOTICES.txt +2295 -0
- package/dist/browser/workspace.css +4 -0
- package/dist/browser/workspace.js +225 -0
- package/dist/browser-crew.d.ts +11 -0
- package/dist/browser-crew.js +50 -0
- package/dist/browser-shell.d.ts +8 -0
- package/dist/browser-shell.js +60 -0
- package/dist/browser-workspace.d.ts +780 -0
- package/dist/browser-workspace.js +47 -0
- package/dist/budget-alerts.d.ts +19 -0
- package/dist/budget-alerts.js +46 -0
- package/dist/builder.d.ts +370 -0
- package/dist/builder.js +3262 -0
- package/dist/capscan.d.ts +35 -0
- package/dist/capscan.js +113 -0
- package/dist/chat-acceptance.d.ts +71 -0
- package/dist/chat-acceptance.js +120 -0
- package/dist/chat-actions.d.ts +265 -0
- package/dist/chat-actions.js +1273 -0
- package/dist/chat-channel.d.ts +109 -0
- package/dist/chat-channel.js +652 -0
- package/dist/chat-continuity.d.ts +32 -0
- package/dist/chat-continuity.js +317 -0
- package/dist/chat-controls.d.ts +113 -0
- package/dist/chat-controls.js +53 -0
- package/dist/chat-delivery-state.d.ts +159 -0
- package/dist/chat-delivery-state.js +309 -0
- package/dist/chat-delivery.d.ts +38 -0
- package/dist/chat-delivery.js +693 -0
- package/dist/chat-display.d.ts +1 -0
- package/dist/chat-display.js +18 -0
- package/dist/chat-evidence.d.ts +123 -0
- package/dist/chat-evidence.js +207 -0
- package/dist/chat-flow.d.ts +44 -0
- package/dist/chat-flow.js +215 -0
- package/dist/chat-inbox.d.ts +57 -0
- package/dist/chat-inbox.js +123 -0
- package/dist/chat-polish.d.ts +16 -0
- package/dist/chat-polish.js +135 -0
- package/dist/chat-review.d.ts +46 -0
- package/dist/chat-review.js +98 -0
- package/dist/chat-rooms.d.ts +123 -0
- package/dist/chat-rooms.js +216 -0
- package/dist/chat-task-actions.d.ts +44 -0
- package/dist/chat-task-actions.js +79 -0
- package/dist/check-progress.d.ts +51 -0
- package/dist/check-progress.js +290 -0
- package/dist/child-database.d.ts +12 -0
- package/dist/child-database.js +30 -0
- package/dist/claim.d.ts +688 -0
- package/dist/claim.js +1740 -0
- package/dist/cli.d.ts +137 -0
- package/dist/cli.js +1461 -0
- package/dist/codex-limits.d.ts +15 -0
- package/dist/codex-limits.js +145 -0
- package/dist/coding-context.d.ts +55 -0
- package/dist/coding-context.js +92 -0
- package/dist/coding-handoff.d.ts +57 -0
- package/dist/coding-handoff.js +277 -0
- package/dist/coding-provider.d.ts +72 -0
- package/dist/coding-provider.js +424 -0
- package/dist/coding-shipping-ui.d.ts +4 -0
- package/dist/coding-shipping-ui.js +12 -0
- package/dist/coding-types.d.ts +62 -0
- package/dist/coding-types.js +1 -0
- package/dist/coding-ui.d.ts +17 -0
- package/dist/coding-ui.js +364 -0
- package/dist/coding-update.d.ts +15 -0
- package/dist/coding-update.js +149 -0
- package/dist/coding-workspace.d.ts +124 -0
- package/dist/coding-workspace.js +768 -0
- package/dist/container-state.d.ts +5 -0
- package/dist/container-state.js +62 -0
- package/dist/containment.d.ts +197 -0
- package/dist/containment.js +559 -0
- package/dist/contest.d.ts +318 -0
- package/dist/contest.js +753 -0
- package/dist/control-setup.d.ts +35 -0
- package/dist/control-setup.js +40 -0
- package/dist/control-ui.d.ts +29 -0
- package/dist/control-ui.js +53 -0
- package/dist/controller-service.d.ts +1 -0
- package/dist/controller-service.js +19 -0
- package/dist/controller-supervisor.d.ts +30 -0
- package/dist/controller-supervisor.js +104 -0
- package/dist/converse.d.ts +304 -0
- package/dist/converse.js +849 -0
- package/dist/coordinator-proposals.d.ts +29 -0
- package/dist/coordinator-proposals.js +137 -0
- package/dist/coordinator.d.ts +186 -0
- package/dist/coordinator.js +447 -0
- package/dist/credentials-ui.d.ts +25 -0
- package/dist/credentials-ui.js +48 -0
- package/dist/daemon.d.ts +209 -0
- package/dist/daemon.js +604 -0
- package/dist/decision.d.ts +120 -0
- package/dist/decision.js +388 -0
- package/dist/demo.d.ts +55 -0
- package/dist/demo.js +992 -0
- package/dist/desktop-access.d.ts +28 -0
- package/dist/desktop-access.js +88 -0
- package/dist/desktop-bundle.d.ts +16 -0
- package/dist/desktop-bundle.js +74 -0
- package/dist/desktop-host.d.ts +54 -0
- package/dist/desktop-host.js +508 -0
- package/dist/desktop-update-gate.d.ts +12 -0
- package/dist/desktop-update-gate.js +91 -0
- package/dist/desktop-update-recovery.d.ts +14 -0
- package/dist/desktop-update-recovery.js +243 -0
- package/dist/desktop-update.d.ts +110 -0
- package/dist/desktop-update.js +740 -0
- package/dist/discord-api.d.ts +20 -0
- package/dist/discord-api.js +138 -0
- package/dist/discord-chat.d.ts +16 -0
- package/dist/discord-chat.js +381 -0
- package/dist/discord-settings.d.ts +7 -0
- package/dist/discord-settings.js +75 -0
- package/dist/discord.d.ts +10 -0
- package/dist/discord.js +169 -0
- package/dist/discover.d.ts +75 -0
- package/dist/discover.js +150 -0
- package/dist/dispatch.d.ts +100 -0
- package/dist/dispatch.js +311 -0
- package/dist/dispose.d.ts +161 -0
- package/dist/dispose.js +803 -0
- package/dist/email-settings.d.ts +34 -0
- package/dist/email-settings.js +50 -0
- package/dist/envelope.d.ts +47 -0
- package/dist/envelope.js +105 -0
- package/dist/evidence-pack.d.ts +185 -0
- package/dist/evidence-pack.js +258 -0
- package/dist/evidence.d.ts +345 -0
- package/dist/evidence.js +782 -0
- package/dist/exec.d.ts +285 -0
- package/dist/exec.js +1841 -0
- package/dist/exhaustion.d.ts +85 -0
- package/dist/exhaustion.js +141 -0
- package/dist/export-ui.d.ts +4 -0
- package/dist/export-ui.js +17 -0
- package/dist/export.d.ts +48 -0
- package/dist/export.js +305 -0
- package/dist/flow-actions.d.ts +77 -0
- package/dist/flow-actions.js +203 -0
- package/dist/flow-code.d.ts +50 -0
- package/dist/flow-code.js +159 -0
- package/dist/flow-draft.d.ts +38 -0
- package/dist/flow-draft.js +80 -0
- package/dist/flow-engine.d.ts +66 -0
- package/dist/flow-engine.js +416 -0
- package/dist/flow-insights.d.ts +95 -0
- package/dist/flow-insights.js +149 -0
- package/dist/flow-live.d.ts +24 -0
- package/dist/flow-live.js +150 -0
- package/dist/flow-people.d.ts +24 -0
- package/dist/flow-people.js +91 -0
- package/dist/flow-replies.d.ts +48 -0
- package/dist/flow-replies.js +113 -0
- package/dist/flow-scripts.d.ts +38 -0
- package/dist/flow-scripts.js +73 -0
- package/dist/flow-secrets.d.ts +13 -0
- package/dist/flow-secrets.js +45 -0
- package/dist/flow-sort.d.ts +82 -0
- package/dist/flow-sort.js +153 -0
- package/dist/flow-steps.d.ts +40 -0
- package/dist/flow-steps.js +408 -0
- package/dist/flow-triggers.d.ts +244 -0
- package/dist/flow-triggers.js +959 -0
- package/dist/flows-ui.d.ts +20 -0
- package/dist/flows-ui.js +175 -0
- package/dist/flows.d.ts +229 -0
- package/dist/flows.js +968 -0
- package/dist/fonts.d.ts +19 -0
- package/dist/fonts.js +19 -0
- package/dist/gaps.d.ts +35 -0
- package/dist/gaps.js +101 -0
- package/dist/gate-failure.d.ts +40 -0
- package/dist/gate-failure.js +66 -0
- package/dist/git.d.ts +54 -0
- package/dist/git.js +94 -0
- package/dist/google-mail.d.ts +58 -0
- package/dist/google-mail.js +151 -0
- package/dist/grant.d.ts +136 -0
- package/dist/grant.js +238 -0
- package/dist/graph.d.ts +164 -0
- package/dist/graph.js +383 -0
- package/dist/guides.d.ts +22 -0
- package/dist/guides.js +363 -0
- package/dist/held.d.ts +150 -0
- package/dist/held.js +799 -0
- package/dist/invoke.d.ts +112 -0
- package/dist/invoke.js +780 -0
- package/dist/issues.d.ts +41 -0
- package/dist/issues.js +131 -0
- package/dist/job-object-helper.ps1 +252 -0
- package/dist/jsonl-discriminants.d.ts +11 -0
- package/dist/jsonl-discriminants.js +93 -0
- package/dist/keys.d.ts +104 -0
- package/dist/keys.js +229 -0
- package/dist/kits-ui.d.ts +17 -0
- package/dist/kits-ui.js +46 -0
- package/dist/kits.d.ts +86 -0
- package/dist/kits.js +215 -0
- package/dist/knowledge-cli.d.ts +101 -0
- package/dist/knowledge-cli.js +92 -0
- package/dist/knowledge-ui.d.ts +24 -0
- package/dist/knowledge-ui.js +40 -0
- package/dist/lead-context.d.ts +8 -0
- package/dist/lead-context.js +56 -0
- package/dist/lead-follow.d.ts +22 -0
- package/dist/lead-follow.js +167 -0
- package/dist/lead-status.d.ts +75 -0
- package/dist/lead-status.js +285 -0
- package/dist/ledger-chain.d.ts +46 -0
- package/dist/ledger-chain.js +187 -0
- package/dist/ledger-csv.d.ts +4 -0
- package/dist/ledger-csv.js +11 -0
- package/dist/ledger-view.d.ts +24 -0
- package/dist/ledger-view.js +58 -0
- package/dist/limits-ui.d.ts +26 -0
- package/dist/limits-ui.js +67 -0
- package/dist/link.d.ts +72 -0
- package/dist/link.js +217 -0
- package/dist/live.d.ts +96 -0
- package/dist/live.js +366 -0
- package/dist/liveness.d.ts +30 -0
- package/dist/liveness.js +42 -0
- package/dist/log.d.ts +7 -0
- package/dist/log.js +25 -0
- package/dist/mailbox.d.ts +57 -0
- package/dist/mailbox.js +150 -0
- package/dist/maintenance.d.ts +11 -0
- package/dist/maintenance.js +35 -0
- package/dist/mate-cli.d.ts +52 -0
- package/dist/mate-cli.js +345 -0
- package/dist/mate-contract.d.ts +10 -0
- package/dist/mate-contract.js +30 -0
- package/dist/mate-doors.d.ts +69 -0
- package/dist/mate-doors.js +548 -0
- package/dist/mate-progress.d.ts +29 -0
- package/dist/mate-progress.js +121 -0
- package/dist/mate-tools.d.ts +94 -0
- package/dist/mate-tools.js +1878 -0
- package/dist/mate.d.ts +92 -0
- package/dist/mate.js +435 -0
- package/dist/mcp-connect.d.ts +103 -0
- package/dist/mcp-connect.js +252 -0
- package/dist/mcp.d.ts +27 -0
- package/dist/mcp.js +651 -0
- package/dist/memory-cli.d.ts +466 -0
- package/dist/memory-cli.js +111 -0
- package/dist/memory-pass.d.ts +160 -0
- package/dist/memory-pass.js +409 -0
- package/dist/metrics.d.ts +3 -0
- package/dist/metrics.js +56 -0
- package/dist/mobile-viewport.d.ts +3 -0
- package/dist/mobile-viewport.js +37 -0
- package/dist/model-catalog.d.ts +118 -0
- package/dist/model-catalog.js +376 -0
- package/dist/models-cli.d.ts +102 -0
- package/dist/models-cli.js +66 -0
- package/dist/models-ui.d.ts +34 -0
- package/dist/models-ui.js +68 -0
- package/dist/modes.d.ts +80 -0
- package/dist/modes.js +182 -0
- package/dist/monitoring-settings.d.ts +44 -0
- package/dist/monitoring-settings.js +173 -0
- package/dist/monitoring-ui.d.ts +20 -0
- package/dist/monitoring-ui.js +51 -0
- package/dist/monitoring.d.ts +34 -0
- package/dist/monitoring.js +221 -0
- package/dist/names.d.ts +67 -0
- package/dist/names.js +102 -0
- package/dist/observations.d.ts +40 -0
- package/dist/observations.js +211 -0
- package/dist/oidc.d.ts +71 -0
- package/dist/oidc.js +182 -0
- package/dist/onboard.d.ts +108 -0
- package/dist/onboard.js +325 -0
- package/dist/openrouter-models.d.ts +30 -0
- package/dist/openrouter-models.js +120 -0
- package/dist/operate.d.ts +118 -0
- package/dist/operate.js +11321 -0
- package/dist/peek-cli.d.ts +97 -0
- package/dist/peek-cli.js +215 -0
- package/dist/peek.d.ts +134 -0
- package/dist/peek.js +578 -0
- package/dist/phase-routing.d.ts +307 -0
- package/dist/phase-routing.js +658 -0
- package/dist/plan-auto.d.ts +14 -0
- package/dist/plan-auto.js +92 -0
- package/dist/plan.d.ts +186 -0
- package/dist/plan.js +401 -0
- package/dist/planner-source.d.ts +251 -0
- package/dist/planner-source.js +460 -0
- package/dist/planner.d.ts +75 -0
- package/dist/planner.js +992 -0
- package/dist/policy-ui.d.ts +20 -0
- package/dist/policy-ui.js +41 -0
- package/dist/policy.d.ts +111 -0
- package/dist/policy.js +231 -0
- package/dist/prepared-evidence.d.ts +16 -0
- package/dist/prepared-evidence.js +96 -0
- package/dist/pricing.d.ts +45 -0
- package/dist/pricing.js +77 -0
- package/dist/principal.d.ts +42 -0
- package/dist/principal.js +82 -0
- package/dist/probe.d.ts +46 -0
- package/dist/probe.js +79 -0
- package/dist/process-custody.d.ts +17 -0
- package/dist/process-custody.js +91 -0
- package/dist/process-liveness.d.ts +10 -0
- package/dist/process-liveness.js +81 -0
- package/dist/process-recovery-anchor.d.ts +75 -0
- package/dist/process-recovery-anchor.js +188 -0
- package/dist/process-recovery-coalition.d.ts +25 -0
- package/dist/process-recovery-coalition.js +105 -0
- package/dist/process-recovery-eligibility.d.ts +178 -0
- package/dist/process-recovery-eligibility.js +170 -0
- package/dist/process-recovery-native.d.ts +172 -0
- package/dist/process-recovery-native.js +592 -0
- package/dist/process-recovery-provenance.d.ts +163 -0
- package/dist/process-recovery-provenance.js +292 -0
- package/dist/process-recovery-services.d.ts +56 -0
- package/dist/process-recovery-services.js +191 -0
- package/dist/process-recovery-settlement.d.ts +32 -0
- package/dist/process-recovery-settlement.js +132 -0
- package/dist/process-recovery.d.ts +41 -0
- package/dist/process-recovery.js +91 -0
- package/dist/process-tree.d.ts +41 -0
- package/dist/process-tree.js +264 -0
- package/dist/project-access.d.ts +14 -0
- package/dist/project-access.js +34 -0
- package/dist/project-cli.d.ts +18 -0
- package/dist/project-cli.js +104 -0
- package/dist/project-delete-ui.d.ts +22 -0
- package/dist/project-delete-ui.js +48 -0
- package/dist/project-delete.d.ts +55 -0
- package/dist/project-delete.js +413 -0
- package/dist/project-knowledge.d.ts +111 -0
- package/dist/project-knowledge.js +241 -0
- package/dist/project-learning.d.ts +100 -0
- package/dist/project-learning.js +438 -0
- package/dist/project-memory.d.ts +81 -0
- package/dist/project-memory.js +264 -0
- package/dist/project-skills.d.ts +152 -0
- package/dist/project-skills.js +660 -0
- package/dist/project-tools.d.ts +219 -0
- package/dist/project-tools.js +796 -0
- package/dist/project.d.ts +61 -0
- package/dist/project.js +125 -0
- package/dist/prompt.d.ts +22 -0
- package/dist/prompt.js +72 -0
- package/dist/proof.d.ts +513 -0
- package/dist/proof.js +1140 -0
- package/dist/proposal.d.ts +82 -0
- package/dist/proposal.js +210 -0
- package/dist/provider-connection.d.ts +22 -0
- package/dist/provider-connection.js +98 -0
- package/dist/provider-limits.d.ts +35 -0
- package/dist/provider-limits.js +95 -0
- package/dist/provider.d.ts +279 -0
- package/dist/provider.js +935 -0
- package/dist/publish.d.ts +107 -0
- package/dist/publish.js +650 -0
- package/dist/pulls.d.ts +118 -0
- package/dist/pulls.js +240 -0
- package/dist/push.d.ts +95 -0
- package/dist/push.js +353 -0
- package/dist/quality.d.ts +8 -0
- package/dist/quality.js +6 -0
- package/dist/recipe-ui.d.ts +18 -0
- package/dist/recipe-ui.js +152 -0
- package/dist/recipes.d.ts +81 -0
- package/dist/recipes.js +332 -0
- package/dist/remote.d.ts +67 -0
- package/dist/remote.js +122 -0
- package/dist/render.d.ts +64 -0
- package/dist/render.js +587 -0
- package/dist/report-summary.d.ts +13 -0
- package/dist/report-summary.js +15 -0
- package/dist/repos.d.ts +65 -0
- package/dist/repos.js +277 -0
- package/dist/repository-context-ui.d.ts +2 -0
- package/dist/repository-context-ui.js +10 -0
- package/dist/repository-context.d.ts +67 -0
- package/dist/repository-context.js +376 -0
- package/dist/restart-certification.d.ts +134 -0
- package/dist/restart-certification.js +226 -0
- package/dist/result-actions.d.ts +28 -0
- package/dist/result-actions.js +270 -0
- package/dist/result-completion.d.ts +18 -0
- package/dist/result-completion.js +66 -0
- package/dist/result-review.d.ts +213 -0
- package/dist/result-review.js +430 -0
- package/dist/retention-ui.d.ts +12 -0
- package/dist/retention-ui.js +39 -0
- package/dist/retention.d.ts +72 -0
- package/dist/retention.js +288 -0
- package/dist/review-context.d.ts +243 -0
- package/dist/review-context.js +1043 -0
- package/dist/review-evidence.d.ts +33 -0
- package/dist/review-evidence.js +56 -0
- package/dist/reviewer.d.ts +97 -0
- package/dist/reviewer.js +202 -0
- package/dist/routine.d.ts +228 -0
- package/dist/routine.js +764 -0
- package/dist/runner.d.ts +266 -0
- package/dist/runner.js +399 -0
- package/dist/scan.d.ts +32 -0
- package/dist/scan.js +92 -0
- package/dist/scope.d.ts +695 -0
- package/dist/scope.js +1176 -0
- package/dist/scout-report.d.ts +42 -0
- package/dist/scout-report.js +108 -0
- package/dist/scout.d.ts +69 -0
- package/dist/scout.js +351 -0
- package/dist/serve.d.ts +313 -0
- package/dist/serve.js +21776 -0
- package/dist/session-brief.d.ts +8 -0
- package/dist/session-brief.js +24 -0
- package/dist/session-cli.d.ts +13 -0
- package/dist/session-cli.js +284 -0
- package/dist/session-contract.d.ts +183 -0
- package/dist/session-contract.js +122 -0
- package/dist/session-http.d.ts +19 -0
- package/dist/session-http.js +154 -0
- package/dist/session-server.d.ts +12 -0
- package/dist/session-server.js +37 -0
- package/dist/session-service.d.ts +22 -0
- package/dist/session-service.js +157 -0
- package/dist/setup-guide.d.ts +39 -0
- package/dist/setup-guide.js +93 -0
- package/dist/sign-in-guard.d.ts +45 -0
- package/dist/sign-in-guard.js +74 -0
- package/dist/skills-ui.d.ts +11 -0
- package/dist/skills-ui.js +58 -0
- package/dist/skills.d.ts +97 -0
- package/dist/skills.js +276 -0
- package/dist/slack-api.d.ts +55 -0
- package/dist/slack-api.js +229 -0
- package/dist/slack-chat.d.ts +28 -0
- package/dist/slack-chat.js +413 -0
- package/dist/slack-settings.d.ts +7 -0
- package/dist/slack-settings.js +75 -0
- package/dist/slack-state.d.ts +13 -0
- package/dist/slack-state.js +9 -0
- package/dist/slack.d.ts +13 -0
- package/dist/slack.js +167 -0
- package/dist/spend-ui.d.ts +28 -0
- package/dist/spend-ui.js +95 -0
- package/dist/spend.d.ts +142 -0
- package/dist/spend.js +313 -0
- package/dist/sqlite-runtime.d.ts +3 -0
- package/dist/sqlite-runtime.js +6 -0
- package/dist/sso-settings.d.ts +33 -0
- package/dist/sso-settings.js +103 -0
- package/dist/sso-ui.d.ts +22 -0
- package/dist/sso-ui.js +39 -0
- package/dist/storage.d.ts +15 -0
- package/dist/storage.js +84 -0
- package/dist/store.d.ts +7754 -0
- package/dist/store.js +23279 -0
- package/dist/structured-output.d.ts +58 -0
- package/dist/structured-output.js +103 -0
- package/dist/style-asset.d.ts +7 -0
- package/dist/style-asset.js +41 -0
- package/dist/subscription-chat.d.ts +46 -0
- package/dist/subscription-chat.js +275 -0
- package/dist/summary.d.ts +33 -0
- package/dist/summary.js +71 -0
- package/dist/supervisor.mjs +297 -0
- package/dist/surface.d.ts +63 -0
- package/dist/surface.js +352 -0
- package/dist/sync.d.ts +94 -0
- package/dist/sync.js +279 -0
- package/dist/task-composer.d.ts +13 -0
- package/dist/task-composer.js +52 -0
- package/dist/task-control.d.ts +165 -0
- package/dist/task-control.js +214 -0
- package/dist/task-outcome-cli.d.ts +10 -0
- package/dist/task-outcome-cli.js +92 -0
- package/dist/task-text.d.ts +30 -0
- package/dist/task-text.js +41 -0
- package/dist/team-cli.d.ts +15 -0
- package/dist/team-cli.js +618 -0
- package/dist/team-contract.d.ts +92 -0
- package/dist/team-contract.js +1 -0
- package/dist/team-http.d.ts +17 -0
- package/dist/team-http.js +144 -0
- package/dist/team-leads.d.ts +81 -0
- package/dist/team-leads.js +565 -0
- package/dist/team-runtime.d.ts +27 -0
- package/dist/team-runtime.js +264 -0
- package/dist/team-ui.d.ts +3 -0
- package/dist/team-ui.js +9 -0
- package/dist/team-updates.d.ts +8 -0
- package/dist/team-updates.js +57 -0
- package/dist/teammate-admin.d.ts +53 -0
- package/dist/teammate-admin.js +111 -0
- package/dist/teammate-desk.d.ts +60 -0
- package/dist/teammate-desk.js +154 -0
- package/dist/teammate-memory.d.ts +64 -0
- package/dist/teammate-memory.js +196 -0
- package/dist/teammate-question.d.ts +59 -0
- package/dist/teammate-question.js +175 -0
- package/dist/teammate-tools.d.ts +108 -0
- package/dist/teammate-tools.js +271 -0
- package/dist/teammate-week.d.ts +68 -0
- package/dist/teammate-week.js +132 -0
- package/dist/teammate-work.d.ts +76 -0
- package/dist/teammate-work.js +280 -0
- package/dist/teammates-ui.d.ts +20 -0
- package/dist/teammates-ui.js +166 -0
- package/dist/teammates.d.ts +180 -0
- package/dist/teammates.js +253 -0
- package/dist/teams-api.d.ts +33 -0
- package/dist/teams-api.js +204 -0
- package/dist/teams-chat.d.ts +26 -0
- package/dist/teams-chat.js +215 -0
- package/dist/teams-settings.d.ts +12 -0
- package/dist/teams-settings.js +57 -0
- package/dist/teams.d.ts +21 -0
- package/dist/teams.js +124 -0
- package/dist/telegram-flow.d.ts +49 -0
- package/dist/telegram-flow.js +110 -0
- package/dist/telegram-mate.d.ts +137 -0
- package/dist/telegram-mate.js +707 -0
- package/dist/telegram-progress.d.ts +14 -0
- package/dist/telegram-progress.js +129 -0
- package/dist/telegram-settings.d.ts +9 -0
- package/dist/telegram-settings.js +36 -0
- package/dist/telegram-status.d.ts +75 -0
- package/dist/telegram-status.js +265 -0
- package/dist/telegram-team.d.ts +85 -0
- package/dist/telegram-team.js +359 -0
- package/dist/telegram.d.ts +230 -0
- package/dist/telegram.js +1931 -0
- package/dist/templates.d.ts +65 -0
- package/dist/templates.js +118 -0
- package/dist/tool-launcher.d.ts +1 -0
- package/dist/tool-launcher.js +101 -0
- package/dist/tools-ui.d.ts +30 -0
- package/dist/tools-ui.js +40 -0
- package/dist/transitions-recipes.d.ts +1 -0
- package/dist/transitions-recipes.js +203 -0
- package/dist/tree-proof.d.ts +34 -0
- package/dist/tree-proof.js +58 -0
- package/dist/verification-evidence.d.ts +44 -0
- package/dist/verification-evidence.js +238 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +10 -0
- package/dist/webhooks.d.ts +91 -0
- package/dist/webhooks.js +283 -0
- package/dist/work-index.d.ts +68 -0
- package/dist/work-index.js +384 -0
- package/dist/work-summary.d.ts +57 -0
- package/dist/work-summary.js +116 -0
- package/dist/workspace-motion.d.ts +4 -0
- package/dist/workspace-motion.js +133 -0
- package/dist/workspace-revision.d.ts +19 -0
- package/dist/workspace-revision.js +92 -0
- package/dist/workspace-ui.d.ts +204 -0
- package/dist/workspace-ui.js +411 -0
- package/dist/worktree-notices.d.ts +13 -0
- package/dist/worktree-notices.js +17 -0
- package/dist/worktree.d.ts +249 -0
- package/dist/worktree.js +720 -0
- package/package.json +122 -0
- package/scripts/canary-assertions.mjs +42 -0
- package/scripts/crash-canary.mjs +253 -0
- package/scripts/fixtures/crash-process.mjs +74 -0
- package/scripts/fixtures/pilot-scenarios.mjs +85 -0
- package/scripts/fixtures/restart-service.mjs +27 -0
- package/scripts/launchd-certification.mjs +143 -0
- package/scripts/pilot.mjs +121 -0
- package/scripts/proof-preflight.mjs +140 -0
- package/scripts/provider-canary.mjs +379 -0
- package/scripts/recovery-canary.mjs +135 -0
- package/scripts/restart-certification.mjs +98 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SessionBrief, SessionResult, SessionView } from './session-contract.js';
|
|
2
|
+
export type SavedSessionBrief = SessionBrief & {
|
|
3
|
+
sourceItemIds: string[];
|
|
4
|
+
partialHistory: boolean;
|
|
5
|
+
};
|
|
6
|
+
/** FirstMate-style bearings from saved facts, without another model call or
|
|
7
|
+
* supervisor. Agent text is explicitly a report, never verification evidence. */
|
|
8
|
+
export declare function savedSessionBrief(session: SessionView, items: NonNullable<SessionResult['items']>, nextAction: string, partialHistory: boolean): SavedSessionBrief;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const states = {
|
|
2
|
+
starting: 'Starting', ready: 'Ready to continue', working: 'Working', 'needs-input': 'Waiting for your answer',
|
|
3
|
+
stopping: 'Stopping the current turn', interrupted: 'Saved; reconnect to continue', failed: 'Stopped with an error',
|
|
4
|
+
uncertain: 'Delivery needs review', closed: 'Closed; saved work is preserved',
|
|
5
|
+
};
|
|
6
|
+
const excerpt = (text, limit) => {
|
|
7
|
+
const one = text.replace(/\s+/g, ' ').trim();
|
|
8
|
+
return one.length > limit ? `${one.slice(0, limit - 1)}…` : one;
|
|
9
|
+
};
|
|
10
|
+
/** FirstMate-style bearings from saved facts, without another model call or
|
|
11
|
+
* supervisor. Agent text is explicitly a report, never verification evidence. */
|
|
12
|
+
export function savedSessionBrief(session, items, nextAction, partialHistory) {
|
|
13
|
+
const request = [...items].reverse().find(one => one.type === 'userMessage');
|
|
14
|
+
const update = [...items].reverse().find(one => one.type === 'agentMessage');
|
|
15
|
+
const lines = [`${session.title} — ${states[session.status] ?? session.status}.`];
|
|
16
|
+
if (request)
|
|
17
|
+
lines.push(`Latest saved request: ${excerpt(request.text, 280)}`);
|
|
18
|
+
if (update)
|
|
19
|
+
lines.push(`Latest saved agent report: ${excerpt(update.text, 600)}`);
|
|
20
|
+
if (session.error)
|
|
21
|
+
lines.push(excerpt(session.error, 400));
|
|
22
|
+
return { summary: lines.join('\n'), nextAction, sourceRevision: session.revision,
|
|
23
|
+
sourceItemIds: [request?.id, update?.id].filter((id) => id !== undefined), partialHistory };
|
|
24
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type SessionDescriptor, type SessionOperation } from './session-contract.js';
|
|
2
|
+
export type SessionCliOptions = {
|
|
3
|
+
fetch?: typeof fetch;
|
|
4
|
+
env?: NodeJS.ProcessEnv;
|
|
5
|
+
readStdin?: () => Promise<string>;
|
|
6
|
+
stderr?: (line: string) => void;
|
|
7
|
+
};
|
|
8
|
+
export declare const SESSION_CLI_ACTIONS: readonly ["capabilities", ...SessionOperation[]];
|
|
9
|
+
export declare function sessionCliFlags(spec: SessionDescriptor): Record<string, 'value' | 'flag'>;
|
|
10
|
+
/** Credentials are never sent to a URL with embedded authority, an API path,
|
|
11
|
+
* query, fragment or an insecure remote host. Fetch cannot follow redirects. */
|
|
12
|
+
export declare function sessionServiceOrigin(raw: string): string;
|
|
13
|
+
export declare function runSessionCommand(argv: readonly string[], write: (line: string) => void, options?: SessionCliOptions): Promise<number>;
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { open } from 'node:fs/promises';
|
|
2
|
+
import { envelopeJson } from './envelope.js';
|
|
3
|
+
import { SESSION_DESCRIPTORS, SESSION_PROMPT_BYTES, SESSION_RESPONSE_BYTES, isSessionResponse, sessionCapabilities, sessionDescriptor, validateSessionRequest, } from './session-contract.js';
|
|
4
|
+
const commonFlags = { url: 'value', as: 'value', 'token-env': 'value', 'token-file': 'value', json: 'flag', help: 'flag' };
|
|
5
|
+
export const SESSION_CLI_ACTIONS = ['capabilities', ...SESSION_DESCRIPTORS.map(one => one.operation)];
|
|
6
|
+
export function sessionCliFlags(spec) {
|
|
7
|
+
return { ...commonFlags, ...Object.fromEntries(Object.keys(spec.flags).map(name => [name, 'value'])), ...(spec.operation === 'start' || spec.operation === 'send' ? { file: 'value', stdin: 'flag' } : {}) };
|
|
8
|
+
}
|
|
9
|
+
function help(spec) {
|
|
10
|
+
if (!spec)
|
|
11
|
+
return `toolroll session <operation>\n\n${SESSION_DESCRIPTORS.map(one => ` ${one.operation.padEnd(12)} ${one.synopsis}`).join('\n')}\n capabilities Show this client's schemas and authority requirements\n\nUse session <operation> --help for required flags. Session controls require operator credentials. Chat is the separate coordinator conversation.`;
|
|
12
|
+
const fields = spec.inputSchema.required.filter(one => !['version', 'sessionId', 'prompt'].includes(one));
|
|
13
|
+
const required = fields.map(field => Object.entries(spec.flags).find(([, value]) => value.field === field)?.[0]).filter(Boolean);
|
|
14
|
+
return `toolroll session ${spec.operation}${'sessionId' in spec.inputSchema.properties ? ' <session-id>' : ''}\n${spec.synopsis}.\n\nRequired: --url <service-origin> --as <operator>\n --token-env <variable-name> or --token-file <path>\n${required.map(name => ` --${name} <value>`).join('\n')}${'prompt' in spec.inputSchema.properties ? '\n --file <path> or --stdin (complete prompt, up to 64 KB)' : ''}\n${'expectedRevision' in spec.inputSchema.properties ? '\nUse the revision, nativeThreadId and turnId from session show. Use none for a null thread or turn.\n' : ''}\nOptions: ${Object.keys(sessionCliFlags(spec)).map(name => `--${name}`).join(' ')}\nCredentials are sent only to the named HTTPS service or loopback HTTP. Redirects and automatic mutation retries are disabled.`;
|
|
15
|
+
}
|
|
16
|
+
class UsageError extends Error {
|
|
17
|
+
}
|
|
18
|
+
async function readBoundedFile(path, limit, label) {
|
|
19
|
+
let file;
|
|
20
|
+
try {
|
|
21
|
+
file = await open(path, 'r');
|
|
22
|
+
const stat = await file.stat();
|
|
23
|
+
if (!stat.isFile() || stat.size > limit)
|
|
24
|
+
throw new Error();
|
|
25
|
+
const buffer = Buffer.alloc(limit + 1);
|
|
26
|
+
let offset = 0;
|
|
27
|
+
while (offset <= limit) {
|
|
28
|
+
const { bytesRead } = await file.read(buffer, offset, buffer.length - offset, null);
|
|
29
|
+
if (!bytesRead)
|
|
30
|
+
break;
|
|
31
|
+
offset += bytesRead;
|
|
32
|
+
}
|
|
33
|
+
if (offset > limit)
|
|
34
|
+
throw new Error();
|
|
35
|
+
return new TextDecoder('utf-8', { fatal: true }).decode(buffer.subarray(0, offset));
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
throw new UsageError(`${label} must be a readable UTF-8 regular file of at most ${limit} bytes.`);
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
await file?.close();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async function readStdin() {
|
|
45
|
+
if (process.stdin.isTTY)
|
|
46
|
+
throw new UsageError('Pipe the complete prompt into --stdin, or use --file.');
|
|
47
|
+
const chunks = [];
|
|
48
|
+
let bytes = 0;
|
|
49
|
+
for await (const chunk of process.stdin) {
|
|
50
|
+
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
51
|
+
bytes += buffer.length;
|
|
52
|
+
if (bytes > SESSION_PROMPT_BYTES)
|
|
53
|
+
throw new UsageError('The prompt exceeds 64 KB.');
|
|
54
|
+
chunks.push(buffer);
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
return new TextDecoder('utf-8', { fatal: true }).decode(Buffer.concat(chunks));
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
throw new UsageError('The prompt must be UTF-8 text.');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/** Credentials are never sent to a URL with embedded authority, an API path,
|
|
64
|
+
* query, fragment or an insecure remote host. Fetch cannot follow redirects. */
|
|
65
|
+
export function sessionServiceOrigin(raw) {
|
|
66
|
+
let url;
|
|
67
|
+
try {
|
|
68
|
+
url = new URL(raw);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
throw new UsageError('--url must be an HTTPS or loopback HTTP service origin.');
|
|
72
|
+
}
|
|
73
|
+
if (url.username || url.password || url.search || url.hash || url.pathname !== '/')
|
|
74
|
+
throw new UsageError('--url must contain only the service origin, with no credentials, path, query or fragment.');
|
|
75
|
+
if (url.protocol !== 'https:' && !(url.protocol === 'http:' && ['127.0.0.1', '[::1]', 'localhost'].includes(url.hostname)))
|
|
76
|
+
throw new UsageError('--url requires HTTPS except for loopback HTTP.');
|
|
77
|
+
return url.origin;
|
|
78
|
+
}
|
|
79
|
+
async function parseRequest(spec, flags, positionals, options) {
|
|
80
|
+
const value = (name) => typeof flags[name] === 'string' ? flags[name] : '';
|
|
81
|
+
const url = sessionServiceOrigin(value('url'));
|
|
82
|
+
const account = value('as');
|
|
83
|
+
if (!account || account.length > 200 || /[\s:\x00-\x1f\x7f]/.test(account))
|
|
84
|
+
throw new UsageError('--as must name the operator account.');
|
|
85
|
+
if (Boolean(flags['token-env']) === Boolean(flags['token-file']))
|
|
86
|
+
throw new UsageError('Choose exactly one credential source: --token-env <variable-name> or --token-file <path>.');
|
|
87
|
+
let token;
|
|
88
|
+
if (flags['token-env']) {
|
|
89
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(value('token-env')))
|
|
90
|
+
throw new UsageError('--token-env must name an environment variable.');
|
|
91
|
+
token = (options.env ?? process.env)[value('token-env')] ?? '';
|
|
92
|
+
}
|
|
93
|
+
else
|
|
94
|
+
token = (await readBoundedFile(value('token-file'), 8192, 'The token file')).trim();
|
|
95
|
+
if (!token || token.length > 8192 || /[\s\x00-\x1f\x7f]/.test(token))
|
|
96
|
+
throw new UsageError('The selected credential is empty or invalid. Set the named variable or token file.');
|
|
97
|
+
const request = { version: 1 };
|
|
98
|
+
if ('sessionId' in spec.inputSchema.properties) {
|
|
99
|
+
if (positionals.length !== 1)
|
|
100
|
+
throw new UsageError('Name exactly one session ID.');
|
|
101
|
+
request['sessionId'] = positionals[0];
|
|
102
|
+
}
|
|
103
|
+
else if (positionals.length)
|
|
104
|
+
throw new UsageError('This operation takes no positional arguments.');
|
|
105
|
+
for (const [name, field] of Object.entries(spec.flags)) {
|
|
106
|
+
if (flags[name] === undefined)
|
|
107
|
+
continue;
|
|
108
|
+
const raw = value(name);
|
|
109
|
+
if (field.kind === 'integer' && !/^\d+$/.test(raw))
|
|
110
|
+
throw new UsageError(`--${name} must be a whole number.`);
|
|
111
|
+
request[field.field] = field.kind === 'integer' ? Number(raw) : field.kind === 'nullable-id' && raw === 'none' ? null : raw;
|
|
112
|
+
}
|
|
113
|
+
if ('prompt' in spec.inputSchema.properties) {
|
|
114
|
+
if (Boolean(flags['file']) === Boolean(flags['stdin']))
|
|
115
|
+
throw new UsageError('Choose exactly one prompt source: --file <path> or --stdin.');
|
|
116
|
+
request['prompt'] = flags['file'] ? await readBoundedFile(value('file'), SESSION_PROMPT_BYTES, 'The prompt file') : await (options.readStdin ?? readStdin)();
|
|
117
|
+
}
|
|
118
|
+
const validated = validateSessionRequest(spec.operation, request);
|
|
119
|
+
if (!validated.ok)
|
|
120
|
+
throw new UsageError(validated.message);
|
|
121
|
+
return { spec, request: validated.request, url, account, token };
|
|
122
|
+
}
|
|
123
|
+
async function readResponse(response) {
|
|
124
|
+
if (!response.body)
|
|
125
|
+
throw new Error('Missing response body');
|
|
126
|
+
const reader = response.body.getReader();
|
|
127
|
+
const chunks = [];
|
|
128
|
+
let bytes = 0;
|
|
129
|
+
try {
|
|
130
|
+
while (true) {
|
|
131
|
+
const chunk = await reader.read();
|
|
132
|
+
if (chunk.done)
|
|
133
|
+
break;
|
|
134
|
+
bytes += chunk.value.byteLength;
|
|
135
|
+
if (bytes > SESSION_RESPONSE_BYTES) {
|
|
136
|
+
await reader.cancel();
|
|
137
|
+
throw new Error('Response limit');
|
|
138
|
+
}
|
|
139
|
+
chunks.push(chunk.value);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
reader.releaseLock();
|
|
144
|
+
}
|
|
145
|
+
return JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(Buffer.concat(chunks)));
|
|
146
|
+
}
|
|
147
|
+
function unconfirmed(spec, request) {
|
|
148
|
+
const sessionId = 'sessionId' in request ? request.sessionId : undefined;
|
|
149
|
+
return { version: 1, operation: spec.operation, ok: false, status: spec.mutation ? 'uncertain' : 'rejected',
|
|
150
|
+
delivery: spec.mutation ? 'unknown' : 'not-sent', retry: spec.mutation ? 'inspect-first' : 'safe-read',
|
|
151
|
+
reason: spec.mutation ? 'delivery-unknown' : 'service-unavailable',
|
|
152
|
+
message: spec.mutation ? 'The service response could not be confirmed. Inspect the saved session before continuing; the request was not retried.' : 'The service response could not be read. Check the service address and connection.',
|
|
153
|
+
nextActions: [{ operation: sessionId ? 'show' : 'list', label: sessionId ? 'Inspect session' : 'List sessions', ...(sessionId ? { sessionId } : {}) }] };
|
|
154
|
+
}
|
|
155
|
+
async function perform(parsed, options) {
|
|
156
|
+
const { spec, request, url, account, token } = parsed;
|
|
157
|
+
try {
|
|
158
|
+
const response = await (options.fetch ?? fetch)(`${url}/api/sessions/${spec.operation}`, {
|
|
159
|
+
method: 'POST', redirect: 'manual', credentials: 'omit', signal: AbortSignal.timeout(60_000),
|
|
160
|
+
headers: { authorization: `Bearer ${account}:${token}`, 'content-type': 'application/json', accept: 'application/json' }, body: JSON.stringify(request),
|
|
161
|
+
});
|
|
162
|
+
if (response.status >= 300 && response.status < 400) {
|
|
163
|
+
await response.body?.cancel();
|
|
164
|
+
return unconfirmed(spec, request);
|
|
165
|
+
}
|
|
166
|
+
// This marker belongs to the owner boundary. A bare gateway 503 or 404
|
|
167
|
+
// cannot prove that an upstream mutation was never accepted.
|
|
168
|
+
if ([401, 403, 404, 503].includes(response.status) && response.headers.get('x-standing-orders-session-delivery') === 'not-sent') {
|
|
169
|
+
await response.body?.cancel();
|
|
170
|
+
const reason = response.status === 401 ? 'unauthenticated' : response.status === 403 ? 'forbidden' : response.status === 404 ? 'session-unsupported' : 'session-unavailable';
|
|
171
|
+
return { version: 1, operation: spec.operation, ok: false, status: 'rejected', delivery: 'not-sent', retry: spec.mutation ? 'never' : 'safe-read', reason,
|
|
172
|
+
message: response.status === 401 || response.status === 403 ? 'The service refused these operator credentials. Check the account and its access.' : 'This service does not currently support the requested session operation. Check its installed build and readiness.', nextActions: [] };
|
|
173
|
+
}
|
|
174
|
+
const payload = await readResponse(response);
|
|
175
|
+
if (!isSessionResponse(payload, spec.operation) || (payload.ok && !response.ok))
|
|
176
|
+
return unconfirmed(spec, request);
|
|
177
|
+
if ('sessionId' in request && payload.result?.session && payload.result.session.id !== request.sessionId)
|
|
178
|
+
return unconfirmed(spec, request);
|
|
179
|
+
if (payload.ok && 'key' in request && payload.result?.receipt?.key !== request.key)
|
|
180
|
+
return unconfirmed(spec, request);
|
|
181
|
+
if (payload.ok && 'expectedThreadId' in request && request.expectedThreadId !== null && payload.result?.session?.nativeThreadId !== request.expectedThreadId)
|
|
182
|
+
return unconfirmed(spec, request);
|
|
183
|
+
return payload;
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
return unconfirmed(spec, request);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
const terminalText = (value) => value.replace(/[\x00-\x08\x0b-\x1f\x7f]/g, '');
|
|
190
|
+
function render(response) {
|
|
191
|
+
const result = response.result;
|
|
192
|
+
const lines = response.ok && response.operation === 'show' && result?.brief ? [] : [response.message];
|
|
193
|
+
for (const session of result?.sessions ?? [])
|
|
194
|
+
lines.push(`${session.id} ${session.status} ${session.title}`);
|
|
195
|
+
if (result?.session) {
|
|
196
|
+
const session = result.session;
|
|
197
|
+
lines.push(result?.brief?.summary ?? `${session.title} · ${session.status}`, `Session: ${session.id}`, `Revision: ${session.revision} · Thread: ${session.nativeThreadId ?? 'none'} · Turn: ${session.turnId ?? 'none'}`);
|
|
198
|
+
if (session.error && !result?.brief)
|
|
199
|
+
lines.push(session.error);
|
|
200
|
+
}
|
|
201
|
+
for (const item of result?.items ?? [])
|
|
202
|
+
lines.push(`\n${item.type}: ${item.text}`);
|
|
203
|
+
for (const request of result?.requests ?? [])
|
|
204
|
+
lines.push(`\n${request.title}\n${request.detail}`);
|
|
205
|
+
if (result?.changes)
|
|
206
|
+
lines.push(result.changes.status, result.changes.diff, ...(result.changes.truncated ? ['Changes were truncated. Open the workspace for the full diff.'] : []));
|
|
207
|
+
if (result?.truncated)
|
|
208
|
+
lines.push('The response is shortened. Open the workspace for complete activity.');
|
|
209
|
+
for (const action of response.nextActions)
|
|
210
|
+
lines.push(`${action.label}: ${action.operation === 'open-ui' ? 'open the coding workspace' : `toolroll session ${action.operation}${action.sessionId ? ` ${action.sessionId}` : ''}`}`);
|
|
211
|
+
return terminalText(lines.join('\n'));
|
|
212
|
+
}
|
|
213
|
+
export async function runSessionCommand(argv, write, options = {}) {
|
|
214
|
+
const json = argv.includes('--json');
|
|
215
|
+
const stderr = options.stderr ?? (line => process.stderr.write(`${line}\n`));
|
|
216
|
+
const operation = argv[0];
|
|
217
|
+
const command = operation ? `session ${operation}` : 'session';
|
|
218
|
+
const fail = (message) => {
|
|
219
|
+
const payload = { ok: false, command, reason: 'usage', status: 'rejected', delivery: 'not-sent', retry: 'never', message };
|
|
220
|
+
if (json)
|
|
221
|
+
write(envelopeJson(payload));
|
|
222
|
+
else
|
|
223
|
+
stderr(message);
|
|
224
|
+
return 2;
|
|
225
|
+
};
|
|
226
|
+
if (!operation || operation === '--help' || operation === '-h') {
|
|
227
|
+
if (json)
|
|
228
|
+
write(envelopeJson({ ok: true, command: 'session', ...sessionCapabilities() }));
|
|
229
|
+
else
|
|
230
|
+
write(help());
|
|
231
|
+
return 0;
|
|
232
|
+
}
|
|
233
|
+
if (operation === 'capabilities') {
|
|
234
|
+
if (argv.slice(1).some(arg => !['--json', '--help', '-h'].includes(arg)))
|
|
235
|
+
return fail('session capabilities accepts only --json or --help.');
|
|
236
|
+
write(json ? envelopeJson({ ok: true, command, ...sessionCapabilities() }) : help());
|
|
237
|
+
return 0;
|
|
238
|
+
}
|
|
239
|
+
const spec = sessionDescriptor(operation);
|
|
240
|
+
if (!spec)
|
|
241
|
+
return fail(`Unknown session operation. Use: ${SESSION_CLI_ACTIONS.join(', ')}.`);
|
|
242
|
+
const allowed = sessionCliFlags(spec);
|
|
243
|
+
const flags = {};
|
|
244
|
+
const positionals = [];
|
|
245
|
+
for (let index = 1; index < argv.length; index++) {
|
|
246
|
+
const argument = argv[index];
|
|
247
|
+
if (!argument.startsWith('-')) {
|
|
248
|
+
positionals.push(argument);
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
const name = argument === '-h' ? 'help' : argument.startsWith('--') ? argument.slice(2) : '';
|
|
252
|
+
if (!Object.hasOwn(allowed, name))
|
|
253
|
+
return fail(`Unknown option ${argument} for session ${operation}.`);
|
|
254
|
+
if (Object.hasOwn(flags, name))
|
|
255
|
+
return fail(`Option --${name} was repeated.`);
|
|
256
|
+
if (allowed[name] === 'flag')
|
|
257
|
+
flags[name] = true;
|
|
258
|
+
else {
|
|
259
|
+
const value = argv[++index];
|
|
260
|
+
if (!value || value.startsWith('-'))
|
|
261
|
+
return fail(`--${name} requires a value.`);
|
|
262
|
+
flags[name] = value;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
if (flags['help']) {
|
|
266
|
+
write(json ? envelopeJson({ ok: true, command, descriptor: spec, help: help(spec) }) : help(spec));
|
|
267
|
+
return 0;
|
|
268
|
+
}
|
|
269
|
+
let parsed;
|
|
270
|
+
try {
|
|
271
|
+
parsed = await parseRequest(spec, flags, positionals, options);
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
return fail(error instanceof UsageError ? error.message : 'The session request could not be prepared. Check the prompt and credential source.');
|
|
275
|
+
}
|
|
276
|
+
const response = await perform(parsed, options);
|
|
277
|
+
if (json)
|
|
278
|
+
write(envelopeJson({ ...response, command, ...('key' in parsed.request ? { key: parsed.request.key } : {}) }));
|
|
279
|
+
else if (response.ok)
|
|
280
|
+
write(render(response));
|
|
281
|
+
else
|
|
282
|
+
stderr(render(response));
|
|
283
|
+
return response.ok ? 0 : response.status === 'uncertain' || response.reason === 'service-unavailable' ? 1 : 3;
|
|
284
|
+
}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/** The session transport is a client of the running owner, never a catalog owner.
|
|
2
|
+
* These descriptors drive request validation, CLI parsing, help and discovery. */
|
|
3
|
+
export declare const SESSION_PROTOCOL_VERSION = 1;
|
|
4
|
+
export declare const SESSION_PROMPT_BYTES = 64000;
|
|
5
|
+
export declare const SESSION_REQUEST_BYTES = 128000;
|
|
6
|
+
export declare const SESSION_RESPONSE_BYTES = 4000000;
|
|
7
|
+
export type SessionOperation = 'list' | 'show' | 'changes' | 'start' | 'send' | 'stop' | 'resume' | 'recover';
|
|
8
|
+
export type SessionExpected = {
|
|
9
|
+
sessionId: string;
|
|
10
|
+
key: string;
|
|
11
|
+
expectedRevision: number;
|
|
12
|
+
expectedThreadId: string | null;
|
|
13
|
+
expectedTurnId: string | null;
|
|
14
|
+
};
|
|
15
|
+
export type SessionRequests = {
|
|
16
|
+
list: {
|
|
17
|
+
version: 1;
|
|
18
|
+
project?: string;
|
|
19
|
+
limit?: number;
|
|
20
|
+
};
|
|
21
|
+
show: {
|
|
22
|
+
version: 1;
|
|
23
|
+
sessionId: string;
|
|
24
|
+
view?: 'brief' | 'activity';
|
|
25
|
+
};
|
|
26
|
+
changes: {
|
|
27
|
+
version: 1;
|
|
28
|
+
sessionId: string;
|
|
29
|
+
};
|
|
30
|
+
start: {
|
|
31
|
+
version: 1;
|
|
32
|
+
project: string;
|
|
33
|
+
title: string;
|
|
34
|
+
prompt: string;
|
|
35
|
+
model?: string;
|
|
36
|
+
key: string;
|
|
37
|
+
};
|
|
38
|
+
send: {
|
|
39
|
+
version: 1;
|
|
40
|
+
prompt: string;
|
|
41
|
+
} & SessionExpected;
|
|
42
|
+
stop: {
|
|
43
|
+
version: 1;
|
|
44
|
+
} & SessionExpected;
|
|
45
|
+
resume: {
|
|
46
|
+
version: 1;
|
|
47
|
+
} & SessionExpected;
|
|
48
|
+
recover: {
|
|
49
|
+
version: 1;
|
|
50
|
+
} & SessionExpected;
|
|
51
|
+
};
|
|
52
|
+
export type SessionRequest = SessionRequests[SessionOperation];
|
|
53
|
+
export type SessionView = {
|
|
54
|
+
id: string;
|
|
55
|
+
repo: string;
|
|
56
|
+
title: string;
|
|
57
|
+
status: string;
|
|
58
|
+
nativeThreadId: string | null;
|
|
59
|
+
turnId: string | null;
|
|
60
|
+
revision: number;
|
|
61
|
+
branch?: string;
|
|
62
|
+
base?: string;
|
|
63
|
+
error?: string | null;
|
|
64
|
+
deliveryReviewRequired?: boolean;
|
|
65
|
+
updatedAt?: string;
|
|
66
|
+
};
|
|
67
|
+
export type SessionBrief = {
|
|
68
|
+
summary: string;
|
|
69
|
+
nextAction: string;
|
|
70
|
+
sourceRevision: number;
|
|
71
|
+
sourceItemIds?: string[];
|
|
72
|
+
partialHistory?: boolean;
|
|
73
|
+
};
|
|
74
|
+
export type SessionResult = {
|
|
75
|
+
session?: SessionView;
|
|
76
|
+
sessions?: SessionView[];
|
|
77
|
+
items?: {
|
|
78
|
+
id: string;
|
|
79
|
+
type: string;
|
|
80
|
+
text: string;
|
|
81
|
+
status: string | null;
|
|
82
|
+
clientId?: string;
|
|
83
|
+
}[];
|
|
84
|
+
requests?: {
|
|
85
|
+
id: string;
|
|
86
|
+
kind: string;
|
|
87
|
+
title: string;
|
|
88
|
+
detail: string;
|
|
89
|
+
}[];
|
|
90
|
+
changes?: {
|
|
91
|
+
head: string;
|
|
92
|
+
status: string;
|
|
93
|
+
diff: string;
|
|
94
|
+
truncated: boolean;
|
|
95
|
+
};
|
|
96
|
+
receipt?: {
|
|
97
|
+
key: string;
|
|
98
|
+
status: string;
|
|
99
|
+
};
|
|
100
|
+
brief?: SessionBrief;
|
|
101
|
+
truncated?: boolean;
|
|
102
|
+
};
|
|
103
|
+
export type SessionNextAction = {
|
|
104
|
+
operation: SessionOperation | 'open-ui';
|
|
105
|
+
label: string;
|
|
106
|
+
sessionId?: string;
|
|
107
|
+
};
|
|
108
|
+
export type SessionResponse = {
|
|
109
|
+
version: 1;
|
|
110
|
+
operation: SessionOperation;
|
|
111
|
+
ok: boolean;
|
|
112
|
+
status: 'succeeded' | 'pending' | 'rejected' | 'uncertain';
|
|
113
|
+
delivery: 'confirmed' | 'not-sent' | 'unknown';
|
|
114
|
+
retry: 'safe-read' | 'inspect-first' | 'never';
|
|
115
|
+
message: string;
|
|
116
|
+
nextActions: SessionNextAction[];
|
|
117
|
+
reason?: string;
|
|
118
|
+
result?: SessionResult;
|
|
119
|
+
};
|
|
120
|
+
type Field = {
|
|
121
|
+
type: 'string' | 'integer' | readonly ['string', 'null'];
|
|
122
|
+
minLength?: number;
|
|
123
|
+
maxLength?: number;
|
|
124
|
+
pattern?: string;
|
|
125
|
+
minimum?: number;
|
|
126
|
+
maximum?: number;
|
|
127
|
+
maxBytes?: number;
|
|
128
|
+
nonblank?: boolean;
|
|
129
|
+
const?: number;
|
|
130
|
+
};
|
|
131
|
+
export type SessionDescriptor = {
|
|
132
|
+
operation: SessionOperation;
|
|
133
|
+
synopsis: string;
|
|
134
|
+
mutation: boolean;
|
|
135
|
+
audience: 'operator';
|
|
136
|
+
agentMayInvoke: false;
|
|
137
|
+
retry: 'safe-read' | 'inspect-first';
|
|
138
|
+
inputSchema: {
|
|
139
|
+
type: 'object';
|
|
140
|
+
additionalProperties: false;
|
|
141
|
+
required: readonly string[];
|
|
142
|
+
properties: Record<string, Field>;
|
|
143
|
+
};
|
|
144
|
+
flags: Readonly<Record<string, {
|
|
145
|
+
field: string;
|
|
146
|
+
kind: 'string' | 'integer' | 'nullable-id';
|
|
147
|
+
}>>;
|
|
148
|
+
};
|
|
149
|
+
export declare const SESSION_DESCRIPTORS: readonly SessionDescriptor[];
|
|
150
|
+
export declare const SESSION_OPERATIONS: SessionOperation[];
|
|
151
|
+
export declare function sessionDescriptor(operation: string): SessionDescriptor | undefined;
|
|
152
|
+
export type SessionValidation = {
|
|
153
|
+
ok: true;
|
|
154
|
+
request: SessionRequest;
|
|
155
|
+
} | {
|
|
156
|
+
ok: false;
|
|
157
|
+
message: string;
|
|
158
|
+
};
|
|
159
|
+
export declare function validateSessionRequest(operation: string, value: unknown): SessionValidation;
|
|
160
|
+
/** Validate before claiming success. A broken response to a mutation is unknown
|
|
161
|
+
* delivery, not proof that the owner rejected it. Additional fields are allowed. */
|
|
162
|
+
export declare function isSessionResponse(value: unknown, operation: SessionOperation): value is SessionResponse;
|
|
163
|
+
export declare function sessionCapabilities(): {
|
|
164
|
+
version: number;
|
|
165
|
+
transport: string;
|
|
166
|
+
authentication: string;
|
|
167
|
+
authority: string;
|
|
168
|
+
operations: readonly SessionDescriptor[];
|
|
169
|
+
brief: {
|
|
170
|
+
supported: boolean;
|
|
171
|
+
operation: string;
|
|
172
|
+
defaultView: string;
|
|
173
|
+
source: string;
|
|
174
|
+
};
|
|
175
|
+
unsupported: string[];
|
|
176
|
+
limits: {
|
|
177
|
+
promptBytes: number;
|
|
178
|
+
requestBytes: number;
|
|
179
|
+
responseBytes: number;
|
|
180
|
+
};
|
|
181
|
+
retry: string;
|
|
182
|
+
};
|
|
183
|
+
export {};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/** The session transport is a client of the running owner, never a catalog owner.
|
|
2
|
+
* These descriptors drive request validation, CLI parsing, help and discovery. */
|
|
3
|
+
export const SESSION_PROTOCOL_VERSION = 1;
|
|
4
|
+
export const SESSION_PROMPT_BYTES = 64_000;
|
|
5
|
+
export const SESSION_REQUEST_BYTES = 128_000;
|
|
6
|
+
export const SESSION_RESPONSE_BYTES = 4_000_000;
|
|
7
|
+
const text = (maxLength) => ({ type: 'string', minLength: 1, maxLength, nonblank: true });
|
|
8
|
+
const identity = { ...text(200), pattern: '^[A-Za-z0-9_.:-]+$' };
|
|
9
|
+
const nullableIdentity = { ...identity, type: ['string', 'null'] };
|
|
10
|
+
const key = { type: 'string', pattern: '^[A-Za-z0-9_-]{16,100}$', minLength: 16, maxLength: 100 };
|
|
11
|
+
const prompt = { ...text(SESSION_PROMPT_BYTES), maxBytes: SESSION_PROMPT_BYTES };
|
|
12
|
+
const model = { ...text(128), pattern: '^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$' };
|
|
13
|
+
const expected = { sessionId: identity, key, expectedRevision: { type: 'integer', minimum: 0 }, expectedThreadId: nullableIdentity, expectedTurnId: nullableIdentity };
|
|
14
|
+
const expectedFlags = {
|
|
15
|
+
key: { field: 'key', kind: 'string' }, revision: { field: 'expectedRevision', kind: 'integer' },
|
|
16
|
+
thread: { field: 'expectedThreadId', kind: 'nullable-id' }, turn: { field: 'expectedTurnId', kind: 'nullable-id' },
|
|
17
|
+
};
|
|
18
|
+
function descriptor(operation, synopsis, mutation, fields, required, flags) {
|
|
19
|
+
return { operation, synopsis, mutation, audience: 'operator', agentMayInvoke: false, retry: mutation ? 'inspect-first' : 'safe-read',
|
|
20
|
+
inputSchema: { type: 'object', additionalProperties: false, required: ['version', ...required], properties: { version: { type: 'integer', const: 1 }, ...fields } }, flags };
|
|
21
|
+
}
|
|
22
|
+
export const SESSION_DESCRIPTORS = [
|
|
23
|
+
descriptor('list', 'List your native coding sessions', false, { project: text(4096), limit: { type: 'integer', minimum: 1, maximum: 100 } }, [], { project: { field: 'project', kind: 'string' }, limit: { field: 'limit', kind: 'integer' } }),
|
|
24
|
+
descriptor('show', 'Inspect the saved brief and exact identity; request activity when needed', false, { sessionId: identity, view: { type: 'string', pattern: '^(brief|activity)$' } }, ['sessionId'], { view: { field: 'view', kind: 'string' } }),
|
|
25
|
+
descriptor('changes', 'Read changes from the saved session checkout', false, { sessionId: identity }, ['sessionId'], {}),
|
|
26
|
+
descriptor('start', 'Start a native coding session in a project', true, { project: text(4096), title: text(160), prompt, model, key }, ['project', 'title', 'prompt', 'key'], { project: { field: 'project', kind: 'string' }, title: { field: 'title', kind: 'string' }, model: { field: 'model', kind: 'string' }, key: { field: 'key', kind: 'string' } }),
|
|
27
|
+
descriptor('send', 'Send a message to the exact saved session and turn', true, { ...expected, prompt }, [...Object.keys(expected), 'prompt'], expectedFlags),
|
|
28
|
+
descriptor('stop', 'Stop the exact running turn', true, expected, Object.keys(expected), expectedFlags),
|
|
29
|
+
descriptor('resume', 'Reconnect the saved conversation', true, expected, Object.keys(expected), expectedFlags),
|
|
30
|
+
descriptor('recover', 'Check process exit and reconcile saved delivery receipts', true, expected, Object.keys(expected), expectedFlags),
|
|
31
|
+
];
|
|
32
|
+
export const SESSION_OPERATIONS = SESSION_DESCRIPTORS.map(one => one.operation);
|
|
33
|
+
export function sessionDescriptor(operation) { return SESSION_DESCRIPTORS.find(one => one.operation === operation); }
|
|
34
|
+
const record = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
35
|
+
export function validateSessionRequest(operation, value) {
|
|
36
|
+
const spec = sessionDescriptor(operation);
|
|
37
|
+
const bad = (message) => ({ ok: false, message });
|
|
38
|
+
if (!spec)
|
|
39
|
+
return bad('Choose a supported session operation.');
|
|
40
|
+
if (!record(value))
|
|
41
|
+
return bad('The session request must be a JSON object.');
|
|
42
|
+
for (const field of Object.keys(value))
|
|
43
|
+
if (!Object.hasOwn(spec.inputSchema.properties, field))
|
|
44
|
+
return bad(`Unknown session field: ${field}.`);
|
|
45
|
+
for (const field of spec.inputSchema.required)
|
|
46
|
+
if (!Object.hasOwn(value, field))
|
|
47
|
+
return bad(`Missing session field: ${field}.`);
|
|
48
|
+
for (const [name, valueAtField] of Object.entries(value)) {
|
|
49
|
+
const field = spec.inputSchema.properties[name];
|
|
50
|
+
if (Array.isArray(field.type) && valueAtField === null)
|
|
51
|
+
continue;
|
|
52
|
+
if (field.type === 'integer') {
|
|
53
|
+
if (!Number.isSafeInteger(valueAtField) || typeof valueAtField !== 'number' || (field.minimum !== undefined && valueAtField < field.minimum) || (field.maximum !== undefined && valueAtField > field.maximum) || (field.const !== undefined && valueAtField !== field.const))
|
|
54
|
+
return bad(`Invalid ${name}.`);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
if (typeof valueAtField !== 'string' || (field.nonblank && !valueAtField.trim()) || (field.minLength !== undefined && valueAtField.length < field.minLength) || (field.maxLength !== undefined && valueAtField.length > field.maxLength) || (field.maxBytes !== undefined && Buffer.byteLength(valueAtField) > field.maxBytes) || (field.pattern !== undefined && !new RegExp(field.pattern).test(valueAtField)))
|
|
58
|
+
return bad(`Invalid ${name}.`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (Buffer.byteLength(JSON.stringify(value)) > SESSION_REQUEST_BYTES)
|
|
62
|
+
return bad('The session request is too large.');
|
|
63
|
+
return { ok: true, request: value };
|
|
64
|
+
}
|
|
65
|
+
/** Validate before claiming success. A broken response to a mutation is unknown
|
|
66
|
+
* delivery, not proof that the owner rejected it. Additional fields are allowed. */
|
|
67
|
+
export function isSessionResponse(value, operation) {
|
|
68
|
+
if (!record(value) || value['version'] !== 1 || value['operation'] !== operation || typeof value['ok'] !== 'boolean' || typeof value['message'] !== 'string' || !Array.isArray(value['nextActions']))
|
|
69
|
+
return false;
|
|
70
|
+
if (!['succeeded', 'pending', 'rejected', 'uncertain'].includes(String(value['status'])) || !['confirmed', 'not-sent', 'unknown'].includes(String(value['delivery'])) || !['safe-read', 'inspect-first', 'never'].includes(String(value['retry'])))
|
|
71
|
+
return false;
|
|
72
|
+
if ((value['ok'] === true) !== ['succeeded', 'pending'].includes(String(value['status'])))
|
|
73
|
+
return false;
|
|
74
|
+
if (value['status'] === 'uncertain' && (value['delivery'] !== 'unknown' || value['retry'] !== 'inspect-first'))
|
|
75
|
+
return false;
|
|
76
|
+
if (value['status'] === 'rejected' && value['delivery'] !== 'not-sent')
|
|
77
|
+
return false;
|
|
78
|
+
if (value['ok'] === true && value['delivery'] !== 'confirmed')
|
|
79
|
+
return false;
|
|
80
|
+
if (value['reason'] !== undefined && (typeof value['reason'] !== 'string' || !/^[a-z][a-z0-9-]*$/.test(value['reason'])))
|
|
81
|
+
return false;
|
|
82
|
+
for (const action of value['nextActions'])
|
|
83
|
+
if (!record(action) || typeof action['label'] !== 'string' || ![...SESSION_OPERATIONS, 'open-ui'].includes(String(action['operation'])) || (action['sessionId'] !== undefined && typeof action['sessionId'] !== 'string'))
|
|
84
|
+
return false;
|
|
85
|
+
if (value['result'] === undefined)
|
|
86
|
+
return value['ok'] === false;
|
|
87
|
+
const result = value['result'];
|
|
88
|
+
if (!record(result))
|
|
89
|
+
return false;
|
|
90
|
+
const session = (item) => record(item) && ['id', 'repo', 'title', 'status'].every(key => typeof item[key] === 'string') && (typeof item['nativeThreadId'] === 'string' || item['nativeThreadId'] === null) && (typeof item['turnId'] === 'string' || item['turnId'] === null) && Number.isSafeInteger(item['revision']) && Number(item['revision']) >= 0;
|
|
91
|
+
if (result['session'] !== undefined && !session(result['session']))
|
|
92
|
+
return false;
|
|
93
|
+
if (result['sessions'] !== undefined && (!Array.isArray(result['sessions']) || !result['sessions'].every(session)))
|
|
94
|
+
return false;
|
|
95
|
+
if (value['ok'] === true && (operation === 'list' ? !Array.isArray(result['sessions']) : !session(result['session'])))
|
|
96
|
+
return false;
|
|
97
|
+
if (result['changes'] !== undefined) {
|
|
98
|
+
const changes = result['changes'];
|
|
99
|
+
if (!record(changes) || !['head', 'status', 'diff'].every(key => typeof changes[key] === 'string') || typeof changes['truncated'] !== 'boolean')
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
if (value['ok'] === true && operation === 'changes' && result['changes'] === undefined)
|
|
103
|
+
return false;
|
|
104
|
+
if (result['items'] !== undefined && (!Array.isArray(result['items']) || !result['items'].every(item => record(item) && ['id', 'type', 'text'].every(key => typeof item[key] === 'string') && (item['status'] === null || typeof item['status'] === 'string'))))
|
|
105
|
+
return false;
|
|
106
|
+
if (result['requests'] !== undefined && (!Array.isArray(result['requests']) || !result['requests'].every(item => record(item) && ['id', 'kind', 'title', 'detail'].every(key => typeof item[key] === 'string'))))
|
|
107
|
+
return false;
|
|
108
|
+
if (result['receipt'] !== undefined && (!record(result['receipt']) || typeof result['receipt']['key'] !== 'string' || typeof result['receipt']['status'] !== 'string'))
|
|
109
|
+
return false;
|
|
110
|
+
if (result['truncated'] !== undefined && typeof result['truncated'] !== 'boolean')
|
|
111
|
+
return false;
|
|
112
|
+
if (result['brief'] !== undefined && (!record(result['brief']) || typeof result['brief']['summary'] !== 'string' || typeof result['brief']['nextAction'] !== 'string' || !Number.isSafeInteger(result['brief']['sourceRevision'])))
|
|
113
|
+
return false;
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
export function sessionCapabilities() {
|
|
117
|
+
return { version: SESSION_PROTOCOL_VERSION, transport: 'POST /api/sessions/<operation>', authentication: 'operator account: Authorization Bearer name:token',
|
|
118
|
+
authority: 'Operator credentials are required for session reads and controls. External coordinator credentials have no session access.',
|
|
119
|
+
operations: SESSION_DESCRIPTORS, brief: { supported: true, operation: 'show', defaultView: 'brief', source: 'Saved state and labeled agent reports, pinned to a revision; no additional model call.' },
|
|
120
|
+
unsupported: ['events', 'review', 'continue'], limits: { promptBytes: SESSION_PROMPT_BYTES, requestBytes: SESSION_REQUEST_BYTES, responseBytes: SESSION_RESPONSE_BYTES },
|
|
121
|
+
retry: 'Never automatically retry a mutation. Inspect saved state after a lost response; keep the original key.' };
|
|
122
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
import { type SessionOperation, type SessionRequests, type SessionResponse } from './session-contract.js';
|
|
3
|
+
export type SessionHttpActor = {
|
|
4
|
+
name: string;
|
|
5
|
+
generation: number;
|
|
6
|
+
};
|
|
7
|
+
export type SessionHttpExecute = <O extends SessionOperation>(actor: SessionHttpActor, operation: O, request: SessionRequests[O]) => Promise<SessionResponse>;
|
|
8
|
+
export type SessionHttpOptions = {
|
|
9
|
+
/** Verify the bearer against the current account and installation-wide
|
|
10
|
+
* operator role. Derive both fields here, never from the JSON request.
|
|
11
|
+
* Host, TLS and other server admission checks remain with the caller. */
|
|
12
|
+
authenticate: (request: IncomingMessage) => SessionHttpActor | null | Promise<SessionHttpActor | null>;
|
|
13
|
+
/** The existing live owner's operation. Null means no owner is ready.
|
|
14
|
+
* The service rechecks actor generation and project access at execution. */
|
|
15
|
+
execute: SessionHttpExecute | null;
|
|
16
|
+
};
|
|
17
|
+
/** Handle this API family before the browser's form parser or login redirects.
|
|
18
|
+
* This adapter dispatches at most once. It owns no catalog, database or provider. */
|
|
19
|
+
export declare function handleSessionHttp(request: IncomingMessage, response: ServerResponse, options: SessionHttpOptions): Promise<boolean>;
|