@fitchmultz/pi-subagents 0.44.7 → 0.46.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/CHANGELOG.md +264 -7
- package/LICENSE +1 -0
- package/README.md +58 -1483
- package/agents/context-builder.md +19 -1
- package/agents/debugger.md +10 -3
- package/agents/delegate.md +1 -0
- package/agents/fixer.md +4 -1
- package/agents/oracle.md +13 -2
- package/agents/planner.md +14 -3
- package/agents/researcher.md +11 -2
- package/agents/reviewer-claude.md +11 -2
- package/agents/reviewer-gpt.md +12 -2
- package/agents/reviewer-ponytail.md +11 -1
- package/agents/reviewer-security.md +13 -2
- package/agents/reviewer.md +12 -3
- package/agents/scout.md +12 -1
- package/agents/ui-designer.md +10 -3
- package/agents/watcher.md +1 -0
- package/agents/worker.md +8 -2
- package/agents/writer.md +6 -3
- package/dist/agents/agent-defaults.js +9 -0
- package/dist/agents/agent-definition.js +196 -0
- package/dist/agents/agent-management.js +64 -905
- package/dist/agents/agent-scope.js +4 -2
- package/dist/agents/agent-selection.js +10 -5
- package/dist/agents/agent-serializer.js +55 -67
- package/dist/agents/agents.js +75 -716
- package/dist/agents/builtin-overrides.js +218 -0
- package/dist/agents/chain-serializer.js +3 -367
- package/dist/agents/config-values.js +52 -0
- package/dist/agents/discovery-paths.js +91 -0
- package/dist/agents/frontmatter.js +15 -5
- package/dist/agents/identity.js +25 -8
- package/dist/agents/json-chain.js +254 -0
- package/dist/agents/management-config.js +332 -0
- package/dist/agents/management-format.js +231 -0
- package/dist/agents/management-persistence.js +287 -0
- package/dist/agents/management-targets.js +136 -0
- package/dist/agents/management-warnings.js +81 -0
- package/dist/agents/markdown-chain.js +210 -0
- package/dist/agents/package-agents.js +154 -0
- package/dist/agents/skill-files.js +157 -0
- package/dist/agents/skill-search-paths.js +246 -0
- package/dist/agents/skill-types.js +1 -0
- package/dist/agents/skills.js +54 -499
- package/dist/extension/acceptance-schema.js +55 -0
- package/dist/extension/build-info.js +1 -1
- package/dist/extension/chain-schema.js +196 -0
- package/dist/extension/child-runtime.js +237 -0
- package/dist/extension/compact-tools.js +122 -51
- package/dist/extension/config-schema.js +29 -0
- package/dist/extension/config.js +27 -11
- package/dist/extension/control-notice-schema.js +37 -0
- package/dist/extension/control-notices.js +13 -6
- package/dist/extension/delegation-bridges.js +43 -0
- package/dist/extension/doctor.js +48 -25
- package/dist/extension/everyday-schemas.js +207 -0
- package/dist/extension/fanout-child.js +18 -319
- package/dist/extension/index.js +8 -563
- package/dist/extension/message-renderers.js +225 -0
- package/dist/extension/nested-control-inbox.js +154 -0
- package/dist/extension/parent-runtime.js +339 -0
- package/dist/extension/primary-tool.js +69 -0
- package/dist/extension/result-snapshot.js +22 -0
- package/dist/extension/runtime-reload.js +62 -0
- package/dist/extension/runtime-storage.js +43 -0
- package/dist/extension/schema-overrides.js +75 -0
- package/dist/extension/schemas.js +265 -336
- package/dist/extension/tool-input.js +27 -12
- package/dist/extension/tool-result.js +19 -4
- package/dist/history/answer-texts.js +57 -0
- package/dist/history/canonical-result.js +76 -43
- package/dist/history/canonical-selection.js +40 -0
- package/dist/history/database-generation.js +82 -0
- package/dist/history/database.js +57 -33
- package/dist/history/entry-ingestion.js +61 -0
- package/dist/history/index.js +242 -97
- package/dist/history/ingest.js +168 -331
- package/dist/history/output-digests.js +40 -0
- package/dist/history/preview.js +210 -0
- package/dist/history/prune.js +33 -0
- package/dist/history/queries.js +60 -349
- package/dist/history/query-scope.js +190 -0
- package/dist/history/rows.js +77 -0
- package/dist/history/run-projection.js +137 -0
- package/dist/history/run-queries.js +153 -0
- package/dist/history/schema.js +31 -0
- package/dist/history/search-queries.js +163 -0
- package/dist/history/selected-record.js +108 -0
- package/dist/history/source-file.js +45 -0
- package/dist/history/source-watches.js +141 -0
- package/dist/history/store.js +164 -153
- package/dist/history/text-chunks.js +169 -0
- package/dist/history/text.js +35 -0
- package/dist/history/transcript-queries.js +177 -0
- package/dist/history/types.js +5 -1
- package/dist/history/values.js +36 -0
- package/dist/history/wire-inputs.js +122 -0
- package/dist/history/wire-models.js +38 -0
- package/dist/history/worker-runtime.js +441 -0
- package/dist/history/worker.js +66 -462
- package/dist/intercom/intercom-bridge.js +48 -20
- package/dist/intercom/live-intercom.js +80 -23
- package/dist/intercom/nested-result-tree.js +163 -0
- package/dist/intercom/result-delivery.js +40 -0
- package/dist/intercom/result-intercom.js +178 -261
- package/dist/pi-intercom/agent-dir.js +7 -3
- package/dist/pi-intercom/async.js +27 -0
- package/dist/pi-intercom/bridge-ask.js +57 -0
- package/dist/pi-intercom/bridge-config.js +89 -0
- package/dist/pi-intercom/bridge-http.js +86 -0
- package/dist/pi-intercom/bridge-launch-policy.js +88 -0
- package/dist/pi-intercom/bridge-launch.js +217 -0
- package/dist/pi-intercom/bridge-protocol.js +106 -0
- package/dist/pi-intercom/bridge-routes.js +72 -0
- package/dist/pi-intercom/bridge-rpc-process.js +264 -0
- package/dist/pi-intercom/bridge-session.js +420 -0
- package/dist/pi-intercom/bridge.js +221 -606
- package/dist/pi-intercom/broker/broker.js +236 -244
- package/dist/pi-intercom/broker/client.js +189 -304
- package/dist/pi-intercom/broker/connection.js +165 -0
- package/dist/pi-intercom/broker/framing.js +5 -3
- package/dist/pi-intercom/broker/paths.js +4 -1
- package/dist/pi-intercom/broker/pid.js +53 -25
- package/dist/pi-intercom/broker/snapshot-reader.js +78 -0
- package/dist/pi-intercom/broker/snapshots.js +188 -0
- package/dist/pi-intercom/broker/spawn.js +36 -25
- package/dist/pi-intercom/config.js +85 -71
- package/dist/pi-intercom/connection.js +297 -0
- package/dist/pi-intercom/identity.js +58 -0
- package/dist/pi-intercom/inbound-delivery.js +356 -0
- package/dist/pi-intercom/inbound-journal.js +303 -0
- package/dist/pi-intercom/inbound-record.js +113 -0
- package/dist/pi-intercom/inbound.js +179 -0
- package/dist/pi-intercom/index.js +79 -2933
- package/dist/pi-intercom/inspection.js +62 -0
- package/dist/pi-intercom/interview.js +236 -0
- package/dist/pi-intercom/lifecycle.js +168 -0
- package/dist/pi-intercom/message-format.js +69 -0
- package/dist/pi-intercom/outbound.js +304 -0
- package/dist/pi-intercom/peer-awareness.js +66 -0
- package/dist/pi-intercom/reply-tracker.js +62 -43
- package/dist/pi-intercom/reply-wait.js +201 -0
- package/dist/pi-intercom/runtime-types.js +3 -0
- package/dist/pi-intercom/session-events.js +180 -0
- package/dist/pi-intercom/session-targets.js +42 -34
- package/dist/pi-intercom/subagent-events.js +238 -0
- package/dist/pi-intercom/subagent-live-events.js +129 -86
- package/dist/pi-intercom/supervisor.js +282 -0
- package/dist/pi-intercom/tool-arguments.js +74 -0
- package/dist/pi-intercom/tool-registration.js +95 -0
- package/dist/pi-intercom/tool-results.js +38 -0
- package/dist/pi-intercom/tool-schemas.js +82 -0
- package/dist/pi-intercom/tools.js +51 -0
- package/dist/pi-intercom/topic-actions.js +177 -0
- package/dist/pi-intercom/topics.js +177 -92
- package/dist/pi-intercom/transport.js +1 -0
- package/dist/pi-intercom/types.js +151 -114
- package/dist/pi-intercom/ui/compose-paste.js +93 -0
- package/dist/pi-intercom/ui/compose.js +121 -143
- package/dist/pi-intercom/ui/inline-message.js +59 -59
- package/dist/pi-intercom/ui/message-renderers.js +147 -0
- package/dist/pi-intercom/ui/overlay.js +181 -0
- package/dist/pi-intercom/ui/session-format.js +124 -0
- package/dist/pi-intercom/ui/session-list.js +76 -43
- package/dist/pi-intercom/ui/tool-renderers.js +110 -0
- package/dist/pi-intercom/ui/topic-view.js +88 -0
- package/dist/pi-intercom/validation.js +59 -0
- package/dist/runs/background/async-chain-plan.js +265 -0
- package/dist/runs/background/async-control.js +134 -58
- package/dist/runs/background/async-execution.js +136 -633
- package/dist/runs/background/async-job-admission.js +40 -0
- package/dist/runs/background/async-job-projection.js +169 -0
- package/dist/runs/background/async-job-tracker.js +297 -327
- package/dist/runs/background/async-launch.js +216 -0
- package/dist/runs/background/async-plan.js +116 -0
- package/dist/runs/background/async-result-file.js +47 -23
- package/dist/runs/background/async-resume.js +195 -253
- package/dist/runs/background/async-run-discovery.js +213 -0
- package/dist/runs/background/async-run-location.js +135 -0
- package/dist/runs/background/async-run-record.js +1 -0
- package/dist/runs/background/async-run-repair.js +223 -0
- package/dist/runs/background/async-run-summary.js +1 -0
- package/dist/runs/background/async-single-plan.js +105 -0
- package/dist/runs/background/async-status-projection.js +155 -0
- package/dist/runs/background/async-status-render.js +117 -0
- package/dist/runs/background/async-status-validation.js +181 -0
- package/dist/runs/background/async-status.js +3 -442
- package/dist/runs/background/async-value.js +21 -0
- package/dist/runs/background/completion-dedupe.js +36 -12
- package/dist/runs/background/completion-delivery.js +211 -205
- package/dist/runs/background/completion-receipts.js +237 -0
- package/dist/runs/background/legacy-status-acceptance.js +34 -0
- package/dist/runs/background/notify.js +96 -48
- package/dist/runs/background/parallel-groups.js +36 -19
- package/dist/runs/background/result-payload.js +178 -0
- package/dist/runs/background/result-watcher.js +348 -339
- package/dist/runs/background/run-id-resolver.js +53 -33
- package/dist/runs/background/run-schemas.js +189 -0
- package/dist/runs/background/run-status-contracts.js +14 -0
- package/dist/runs/background/run-status-render.js +270 -0
- package/dist/runs/background/run-status.js +231 -339
- package/dist/runs/background/runner-attempt-output.js +155 -0
- package/dist/runs/background/runner-attempt.js +263 -0
- package/dist/runs/background/runner-child-executor.js +166 -0
- package/dist/runs/background/runner-child-observer.js +192 -0
- package/dist/runs/background/runner-completion-summary.js +71 -0
- package/dist/runs/background/runner-completion.js +211 -0
- package/dist/runs/background/runner-config.js +1 -0
- package/dist/runs/background/runner-contract.js +1 -0
- package/dist/runs/background/runner-dynamic.js +121 -0
- package/dist/runs/background/runner-finalization.js +149 -0
- package/dist/runs/background/runner-graph.js +68 -0
- package/dist/runs/background/runner-initial-status.js +60 -0
- package/dist/runs/background/runner-lifecycle.js +142 -0
- package/dist/runs/background/runner-monitor.js +309 -0
- package/dist/runs/background/runner-parallel.js +204 -0
- package/dist/runs/background/runner-prepare-step.js +86 -0
- package/dist/runs/background/runner-reporting.js +153 -0
- package/dist/runs/background/runner-status.js +148 -0
- package/dist/runs/background/runner-step-output.js +92 -0
- package/dist/runs/background/runner-step-record.js +45 -0
- package/dist/runs/background/runner-step.js +112 -0
- package/dist/runs/background/runner-streaming.js +173 -0
- package/dist/runs/background/runner-workflow.js +213 -0
- package/dist/runs/background/stale-run-reconciler.js +155 -292
- package/dist/runs/background/subagent-runner-launcher.js +33 -13
- package/dist/runs/background/subagent-runner.js +51 -1842
- package/dist/runs/background/top-level-async.js +2 -1
- package/dist/runs/foreground/chain-clarify.js +293 -1017
- package/dist/runs/foreground/clarification-draft.js +87 -0
- package/dist/runs/foreground/clarify-contracts.js +1 -0
- package/dist/runs/foreground/clarify-invocation.js +129 -38
- package/dist/runs/foreground/clarify-text-editor.js +210 -0
- package/dist/runs/foreground/clarify-view.js +167 -0
- package/dist/runs/foreground/execution-input.js +226 -353
- package/dist/runs/foreground/execution-routing.js +33 -0
- package/dist/runs/foreground/execution-timeout.js +81 -0
- package/dist/runs/foreground/foreground-control.js +222 -763
- package/dist/runs/foreground/foreground-memory.js +99 -0
- package/dist/runs/foreground/invocation-context.js +55 -0
- package/dist/runs/foreground/invocation-execution.js +331 -0
- package/dist/runs/foreground/invocation-expansion.js +48 -0
- package/dist/runs/foreground/management-actions.js +295 -0
- package/dist/runs/foreground/nested-control.js +179 -0
- package/dist/runs/foreground/question-continuation.js +78 -0
- package/dist/runs/foreground/question-control.js +155 -50
- package/dist/runs/foreground/resume-target.js +221 -0
- package/dist/runs/foreground/revival-launch-policy.js +58 -0
- package/dist/runs/foreground/run-async-path.js +190 -178
- package/dist/runs/foreground/run-interrupt.js +164 -0
- package/dist/runs/foreground/run-nudge.js +278 -0
- package/dist/runs/foreground/saved-revival.js +251 -0
- package/dist/runs/foreground/subagent-executor.js +135 -424
- package/dist/runs/foreground/subagent-params.js +67 -30
- package/dist/runs/foreground/wait-observation.js +104 -0
- package/dist/runs/foreground/wait-registration.js +17 -0
- package/dist/runs/foreground/wait-run.js +283 -123
- package/dist/runs/shared/acceptance-contract.js +193 -99
- package/dist/runs/shared/acceptance-defaults.js +1 -0
- package/dist/runs/shared/acceptance-evaluation.js +201 -181
- package/dist/runs/shared/acceptance-finalization.js +256 -180
- package/dist/runs/shared/acceptance-outcome.js +53 -0
- package/dist/runs/shared/acceptance-reports.js +137 -72
- package/dist/runs/shared/acceptance-submission.js +167 -0
- package/dist/runs/shared/acceptance-verification.js +100 -0
- package/dist/runs/shared/chain-outputs.js +80 -52
- package/dist/runs/shared/child-attempt-types.js +1 -0
- package/dist/runs/shared/child-attempt.js +314 -667
- package/dist/runs/shared/child-boundaries.js +173 -0
- package/dist/runs/shared/child-context-filter.js +44 -0
- package/dist/runs/shared/child-event-observer.js +390 -0
- package/dist/runs/shared/child-execution-cwd.js +73 -43
- package/dist/runs/shared/child-execution-outcome.js +72 -0
- package/dist/runs/shared/child-invocation.js +54 -0
- package/dist/runs/shared/child-message-validation.js +215 -0
- package/dist/runs/shared/child-native-accounting.js +106 -0
- package/dist/runs/shared/child-native-observation.js +69 -0
- package/dist/runs/shared/child-observation-spool.js +164 -0
- package/dist/runs/shared/child-observations.js +157 -76
- package/dist/runs/shared/child-presence.js +3 -0
- package/dist/runs/shared/child-route-env.js +119 -0
- package/dist/runs/shared/child-stream-observer.js +221 -0
- package/dist/runs/shared/child-stream-projection.js +137 -0
- package/dist/runs/shared/child-structured-tool.js +27 -0
- package/dist/runs/shared/claude-code.js +121 -158
- package/dist/runs/shared/claude-model.js +42 -0
- package/dist/runs/shared/claude-session.js +83 -0
- package/dist/runs/shared/claude-types.js +1 -0
- package/dist/runs/shared/completion-guard.js +18 -18
- package/dist/runs/shared/control-event-policy.js +8 -0
- package/dist/runs/shared/control-notification-owner.js +13 -0
- package/dist/runs/shared/dynamic-fanout.js +188 -173
- package/dist/runs/shared/dynamic-item.js +102 -0
- package/dist/runs/shared/history-index.js +62 -36
- package/dist/runs/shared/legacy-async-recovery.js +114 -0
- package/dist/runs/shared/legacy-output-recovery.js +148 -0
- package/dist/runs/shared/mcp-config-schema.js +36 -0
- package/dist/runs/shared/mcp-direct-tool-allowlist.js +147 -116
- package/dist/runs/shared/model-fallback.js +97 -38
- package/dist/runs/shared/mutating-tool-guard.js +128 -88
- package/dist/runs/shared/native-finalization-types.js +1 -0
- package/dist/runs/shared/native-finalization.js +155 -76
- package/dist/runs/shared/native-usage.js +238 -98
- package/dist/runs/shared/nested-control-records.js +128 -0
- package/dist/runs/shared/nested-events.js +8 -700
- package/dist/runs/shared/nested-path.js +32 -28
- package/dist/runs/shared/nested-projection.js +155 -0
- package/dist/runs/shared/nested-protocol.js +18 -0
- package/dist/runs/shared/nested-registry.js +191 -0
- package/dist/runs/shared/nested-render.js +106 -58
- package/dist/runs/shared/nested-route.js +220 -0
- package/dist/runs/shared/nested-validation.js +216 -0
- package/dist/runs/shared/owned-child-evidence.js +125 -0
- package/dist/runs/shared/owned-run-list.js +146 -0
- package/dist/runs/shared/owned-run-observation.js +267 -0
- package/dist/runs/shared/owned-run-progress.js +109 -0
- package/dist/runs/shared/owned-run-read-state.js +1 -0
- package/dist/runs/shared/owned-run-results.js +202 -0
- package/dist/runs/shared/owned-run-status.js +180 -0
- package/dist/runs/shared/owned-run-view.js +51 -0
- package/dist/runs/shared/owned-workflow-details.js +17 -0
- package/dist/runs/shared/owner-output.js +43 -0
- package/dist/runs/shared/parallel-utils.js +36 -28
- package/dist/runs/shared/parent-receipts.js +90 -32
- package/dist/runs/shared/parent-usage.js +169 -57
- package/dist/runs/shared/pi-args.js +108 -201
- package/dist/runs/shared/pi-launch-input.js +1 -0
- package/dist/runs/shared/pi-session-launch.js +86 -0
- package/dist/runs/shared/pi-spawn.js +35 -21
- package/dist/runs/shared/run-history-queries.js +126 -35
- package/dist/runs/shared/run-history.js +101 -35
- package/dist/runs/shared/run-metadata-paths.js +14 -0
- package/dist/runs/shared/run-metadata.js +158 -0
- package/dist/runs/shared/run-persistence.js +131 -0
- package/dist/runs/shared/run-records.js +9 -679
- package/dist/runs/shared/run-restoration.js +338 -0
- package/dist/runs/shared/run-state-owner.js +26 -0
- package/dist/runs/shared/session-cwd-preload.js +27 -18
- package/dist/runs/shared/single-output.js +148 -70
- package/dist/runs/shared/stable-value.js +15 -0
- package/dist/runs/shared/streaming-text.js +23 -12
- package/dist/runs/shared/structured-output.js +25 -13
- package/dist/runs/shared/subagent-control.js +167 -100
- package/dist/runs/shared/subagent-prompt-runtime.js +27 -130
- package/dist/runs/shared/subagent-tool-loop-guard.js +81 -52
- package/dist/runs/shared/supervisor-question-state.js +145 -0
- package/dist/runs/shared/supervisor-questions.js +185 -254
- package/dist/runs/shared/workflow-graph.js +259 -167
- package/dist/runs/shared/workflow-policy.js +120 -48
- package/dist/runs/shared/worktree-contract.js +1 -0
- package/dist/runs/shared/worktree-hook.js +138 -0
- package/dist/runs/shared/worktree-location.js +47 -0
- package/dist/runs/shared/worktree-preservation.js +8 -0
- package/dist/runs/shared/worktree-process.js +107 -0
- package/dist/runs/shared/worktree.js +183 -322
- package/dist/shared/agent-context-policy.js +34 -44
- package/dist/shared/agent-dir.js +14 -0
- package/dist/shared/artifacts.js +30 -12
- package/dist/shared/atomic-json.js +4 -1
- package/dist/shared/chain-files.js +72 -0
- package/dist/shared/concurrency.js +18 -0
- package/dist/shared/content-preview.js +115 -0
- package/dist/shared/cooperative.js +5 -2
- package/dist/shared/execution-cwd.js +13 -5
- package/dist/shared/file-coalescer.js +2 -1
- package/dist/shared/fork-context.js +10 -12
- package/dist/shared/formatters.js +45 -19
- package/dist/shared/journal-frames.js +164 -0
- package/dist/shared/journal-projections.js +121 -0
- package/dist/shared/journal-reader.js +6 -407
- package/dist/shared/json-projection.js +191 -0
- package/dist/shared/lazy-tools.js +19 -8
- package/dist/shared/message-output.js +116 -0
- package/dist/shared/model-info.js +31 -14
- package/dist/shared/native-import.js +20 -0
- package/dist/shared/native-journal.js +140 -0
- package/dist/shared/native-session-loader.js +17 -0
- package/dist/shared/native-session.js +2 -13
- package/dist/shared/native-tui.js +7 -2
- package/dist/shared/native-typebox.js +15 -3
- package/dist/shared/output-page.js +63 -0
- package/dist/shared/post-exit-stdio-guard.js +128 -88
- package/dist/shared/prompt-sections.js +2 -0
- package/dist/shared/session-entries.js +70 -35
- package/dist/shared/session-identity.js +5 -3
- package/dist/shared/settings.js +62 -192
- package/dist/shared/status-format.js +97 -37
- package/dist/shared/task-file-policy.js +24 -0
- package/dist/shared/temp-root.js +44 -15
- package/dist/shared/types/acceptance.js +1 -0
- package/dist/shared/types/async.js +1 -0
- package/dist/shared/types/config.js +1 -0
- package/dist/shared/types/details.js +1 -0
- package/dist/shared/types/history.js +1 -0
- package/dist/shared/types/inputs.js +1 -0
- package/dist/shared/types/intercom.js +1 -0
- package/dist/shared/types/launch.js +1 -0
- package/dist/shared/types/messages.js +1 -0
- package/dist/shared/types/nested.js +1 -0
- package/dist/shared/types/owned-runs.js +1 -0
- package/dist/shared/types/progress.js +1 -0
- package/dist/shared/types/questions.js +1 -0
- package/dist/shared/types/results.js +1 -0
- package/dist/shared/types/state.js +1 -0
- package/dist/shared/types/usage.js +1 -0
- package/dist/shared/types/workflow.js +1 -0
- package/dist/shared/types.js +75 -30
- package/dist/shared/unknown.js +52 -0
- package/dist/shared/utils.js +54 -260
- package/dist/slash/command-discovery.js +82 -0
- package/dist/slash/command-input.js +190 -0
- package/dist/slash/prompt-template-bridge.js +94 -270
- package/dist/slash/prompt-template-contract.js +77 -0
- package/dist/slash/prompt-template-results.js +125 -0
- package/dist/slash/request-protocol.js +68 -0
- package/dist/slash/result-delivery.js +237 -0
- package/dist/slash/saved-chain.js +78 -0
- package/dist/slash/slash-bridge.js +123 -89
- package/dist/slash/slash-commands.js +101 -572
- package/dist/slash/slash-live-state.js +68 -47
- package/dist/tui/action-hints.js +50 -22
- package/dist/tui/activity-lines.js +32 -0
- package/dist/tui/agent-browser.js +290 -0
- package/dist/tui/agent-controls.js +289 -0
- package/dist/tui/agent-conversation.js +444 -0
- package/dist/tui/agent-dock.js +171 -0
- package/dist/tui/agent-history.js +50 -183
- package/dist/tui/agent-model.js +62 -0
- package/dist/tui/agent-picker.js +262 -0
- package/dist/tui/agent-view.js +232 -1564
- package/dist/tui/compact-results.js +193 -0
- package/dist/tui/conversation-details.js +190 -0
- package/dist/tui/conversation-frame.js +135 -0
- package/dist/tui/conversation-history.js +201 -0
- package/dist/tui/conversation-menu.js +78 -0
- package/dist/tui/conversation-notices.js +79 -0
- package/dist/tui/conversation-selection.js +58 -0
- package/dist/tui/conversation-viewport.js +129 -0
- package/dist/tui/direction-message.js +27 -0
- package/dist/tui/display.js +282 -0
- package/dist/tui/editor-viewport.js +18 -0
- package/dist/tui/expanded-content.js +87 -0
- package/dist/tui/expanded-multi.js +170 -0
- package/dist/tui/expanded-single.js +65 -0
- package/dist/tui/history-cards.js +216 -0
- package/dist/tui/history-display.js +238 -0
- package/dist/tui/history-json.js +16 -0
- package/dist/tui/history-metadata.js +152 -0
- package/dist/tui/history-record.js +251 -0
- package/dist/tui/history-text.js +34 -0
- package/dist/tui/indexed-history.js +116 -0
- package/dist/tui/nested-widget.js +120 -0
- package/dist/tui/picker-page.js +59 -0
- package/dist/tui/render.js +58 -1501
- package/dist/tui/result-facts.js +64 -0
- package/dist/tui/task-observation.js +59 -0
- package/dist/tui/task-store.js +366 -0
- package/dist/tui/text-values.js +16 -0
- package/dist/tui/view-connections.js +47 -0
- package/dist/tui/view-model.js +94 -0
- package/dist/tui/view-persistence.js +51 -0
- package/dist/tui/view-ports.js +1 -0
- package/dist/tui/view-session.js +37 -0
- package/dist/tui/widget-details.js +144 -0
- package/dist/tui/widget-status.js +245 -0
- package/dist/tui/widget.js +145 -0
- package/dist/tui/workflow-labels.js +223 -0
- package/dist/tui/workflow-outcomes.js +124 -0
- package/docs/code-quality.md +38 -0
- package/docs/development.md +99 -0
- package/docs/intercom-bridge.md +77 -22
- package/docs/intercom.md +132 -106
- package/docs/performance.md +19 -17
- package/docs/reference.md +1472 -0
- package/generated/RunValidators.d.ts +28 -0
- package/generated/RunValidators.js +2 -0
- package/package.json +27 -6
- package/prompts/parallel-cleanup.md +3 -0
- package/prompts/parallel-context-build.md +3 -0
- package/prompts/parallel-handoff-plan.md +6 -0
- package/prompts/parallel-research.md +4 -0
- package/prompts/parallel-review.md +2 -0
- package/prompts/review-loop.md +2 -0
- package/scripts/build.mjs +129 -85
- package/scripts/check-compat.mjs +48 -11
- package/scripts/compat-host.mjs +35 -7
- package/scripts/generate-run-schemas.mjs +210 -0
- package/scripts/intercom-bridge-credentials.mjs +158 -29
- package/scripts/intercom-remote.mjs +213 -52
- package/scripts/local-install-smoke.mjs +47 -37
- package/scripts/native-package-smoke.mjs +135 -25
- package/scripts/package-smoke.mjs +360 -140
- package/scripts/prepare.mjs +54 -34
- package/scripts/real-pi-processes.mjs +261 -0
- package/scripts/real-pi-smoke.mjs +432 -351
- package/scripts/run-tests.mjs +29 -15
- package/skills/pi-intercom/SKILL.md +11 -11
- package/skills/pi-intercom/references/peer-sessions.md +7 -2
- package/skills/pi-subagents/SKILL.md +1 -1
- package/skills/pi-subagents/references/full-orchestration-guide.md +254 -112
- package/src/agents/agent-defaults.ts +13 -0
- package/src/agents/agent-definition.ts +253 -0
- package/src/agents/agent-management.ts +111 -808
- package/src/agents/agent-scope.ts +7 -3
- package/src/agents/agent-selection.ts +26 -16
- package/src/agents/agent-serializer.ts +84 -93
- package/src/agents/agents.ts +199 -906
- package/src/agents/builtin-overrides.ts +297 -0
- package/src/agents/chain-serializer.ts +3 -329
- package/src/agents/config-values.ts +57 -0
- package/src/agents/discovery-paths.ts +134 -0
- package/src/agents/frontmatter.ts +35 -17
- package/src/agents/identity.ts +49 -18
- package/src/agents/json-chain.ts +305 -0
- package/src/agents/management-config.ts +342 -0
- package/src/agents/management-format.ts +243 -0
- package/src/agents/management-persistence.ts +408 -0
- package/src/agents/management-targets.ts +260 -0
- package/src/agents/management-warnings.ts +115 -0
- package/src/agents/markdown-chain.ts +237 -0
- package/src/agents/package-agents.ts +231 -0
- package/src/agents/skill-files.ts +182 -0
- package/src/agents/skill-search-paths.ts +289 -0
- package/src/agents/skill-types.ts +31 -0
- package/src/agents/skills.ts +152 -610
- package/src/extension/acceptance-schema.ts +88 -0
- package/src/extension/chain-schema.ts +276 -0
- package/src/extension/child-runtime.ts +302 -0
- package/src/extension/compact-tools.ts +259 -102
- package/src/extension/config-schema.ts +59 -0
- package/src/extension/config.ts +39 -17
- package/src/extension/control-notice-schema.ts +55 -0
- package/src/extension/control-notices.ts +57 -33
- package/src/extension/delegation-bridges.ts +59 -0
- package/src/extension/doctor.ts +171 -135
- package/src/extension/everyday-schemas.ts +252 -0
- package/src/extension/fanout-child.ts +29 -308
- package/src/extension/index.ts +17 -642
- package/src/extension/message-renderers.ts +334 -0
- package/src/extension/nested-control-inbox.ts +196 -0
- package/src/extension/parent-runtime.ts +405 -0
- package/src/extension/primary-tool.ts +130 -0
- package/src/extension/result-snapshot.ts +35 -0
- package/src/extension/runtime-reload.ts +72 -0
- package/src/extension/runtime-storage.ts +49 -0
- package/src/extension/schema-overrides.ts +114 -0
- package/src/extension/schemas.ts +451 -418
- package/src/extension/tool-input.ts +40 -13
- package/src/extension/tool-result.ts +45 -14
- package/src/history/answer-texts.ts +74 -0
- package/src/history/canonical-result.ts +127 -51
- package/src/history/canonical-selection.ts +54 -0
- package/src/history/database-generation.ts +86 -0
- package/src/history/database.ts +86 -48
- package/src/history/entry-ingestion.ts +129 -0
- package/src/history/index.ts +426 -148
- package/src/history/ingest.ts +372 -342
- package/src/history/output-digests.ts +41 -0
- package/src/history/preview.ts +235 -0
- package/src/history/prune.ts +48 -0
- package/src/history/queries.ts +122 -256
- package/src/history/query-scope.ts +278 -0
- package/src/history/rows.ts +118 -0
- package/src/history/run-projection.ts +164 -0
- package/src/history/run-queries.ts +199 -0
- package/src/history/schema.ts +34 -0
- package/src/history/search-queries.ts +216 -0
- package/src/history/selected-record.ts +140 -0
- package/src/history/source-file.ts +51 -0
- package/src/history/source-watches.ts +156 -0
- package/src/history/store.ts +310 -197
- package/src/history/text-chunks.ts +181 -0
- package/src/history/text.ts +43 -0
- package/src/history/transcript-queries.ts +251 -0
- package/src/history/types.ts +27 -164
- package/src/history/values.ts +36 -0
- package/src/history/wire-inputs.ts +141 -0
- package/src/history/wire-models.ts +51 -0
- package/src/history/worker-runtime.ts +502 -0
- package/src/history/worker.ts +94 -336
- package/src/intercom/intercom-bridge.ts +136 -69
- package/src/intercom/live-intercom.ts +197 -92
- package/src/intercom/nested-result-tree.ts +213 -0
- package/src/intercom/result-delivery.ts +56 -0
- package/src/intercom/result-intercom.ts +364 -382
- package/src/pi-intercom/agent-dir.ts +9 -3
- package/src/pi-intercom/async.ts +33 -0
- package/src/pi-intercom/bridge-ask.ts +64 -0
- package/src/pi-intercom/bridge-config.ts +120 -0
- package/src/pi-intercom/bridge-http.ts +97 -0
- package/src/pi-intercom/bridge-launch-policy.ts +109 -0
- package/src/pi-intercom/bridge-launch.ts +317 -0
- package/src/pi-intercom/bridge-protocol.ts +123 -0
- package/src/pi-intercom/bridge-routes.ts +105 -0
- package/src/pi-intercom/bridge-rpc-process.ts +293 -0
- package/src/pi-intercom/bridge-session.ts +510 -0
- package/src/pi-intercom/bridge.ts +305 -549
- package/src/pi-intercom/broker/broker.ts +326 -263
- package/src/pi-intercom/broker/client.ts +273 -354
- package/src/pi-intercom/broker/connection.ts +192 -0
- package/src/pi-intercom/broker/framing.ts +11 -6
- package/src/pi-intercom/broker/paths.ts +28 -25
- package/src/pi-intercom/broker/pid.ts +68 -24
- package/src/pi-intercom/broker/snapshot-reader.ts +91 -0
- package/src/pi-intercom/broker/snapshots.ts +241 -0
- package/src/pi-intercom/broker/spawn.ts +58 -34
- package/src/pi-intercom/config.ts +113 -108
- package/src/pi-intercom/connection.ts +346 -0
- package/src/pi-intercom/identity.ts +71 -0
- package/src/pi-intercom/inbound-delivery.ts +450 -0
- package/src/pi-intercom/inbound-journal.ts +350 -0
- package/src/pi-intercom/inbound-record.ts +141 -0
- package/src/pi-intercom/inbound.ts +237 -0
- package/src/pi-intercom/index.ts +86 -2923
- package/src/pi-intercom/inspection.ts +82 -0
- package/src/pi-intercom/interview.ts +295 -0
- package/src/pi-intercom/lifecycle.ts +183 -0
- package/src/pi-intercom/message-format.ts +77 -0
- package/src/pi-intercom/outbound.ts +418 -0
- package/src/pi-intercom/peer-awareness.ts +84 -0
- package/src/pi-intercom/reply-tracker.ts +121 -59
- package/src/pi-intercom/reply-wait.ts +247 -0
- package/src/pi-intercom/runtime-types.ts +97 -0
- package/src/pi-intercom/session-events.ts +247 -0
- package/src/pi-intercom/session-targets.ts +124 -72
- package/src/pi-intercom/subagent-events.ts +299 -0
- package/src/pi-intercom/subagent-live-events.ts +212 -109
- package/src/pi-intercom/supervisor.ts +362 -0
- package/src/pi-intercom/tool-arguments.ts +120 -0
- package/src/pi-intercom/tool-registration.ts +121 -0
- package/src/pi-intercom/tool-results.ts +54 -0
- package/src/pi-intercom/tool-schemas.ts +134 -0
- package/src/pi-intercom/tools.ts +80 -0
- package/src/pi-intercom/topic-actions.ts +243 -0
- package/src/pi-intercom/topics.ts +267 -121
- package/src/pi-intercom/transport.ts +14 -0
- package/src/pi-intercom/types.ts +288 -190
- package/src/pi-intercom/ui/compose-paste.ts +109 -0
- package/src/pi-intercom/ui/compose.ts +173 -157
- package/src/pi-intercom/ui/inline-message.ts +80 -62
- package/src/pi-intercom/ui/message-renderers.ts +182 -0
- package/src/pi-intercom/ui/overlay.ts +238 -0
- package/src/pi-intercom/ui/session-format.ts +146 -0
- package/src/pi-intercom/ui/session-list.ts +145 -62
- package/src/pi-intercom/ui/tool-renderers.ts +148 -0
- package/src/pi-intercom/ui/topic-view.ts +107 -0
- package/src/pi-intercom/validation.ts +69 -0
- package/src/runs/background/async-chain-plan.ts +451 -0
- package/src/runs/background/async-control.ts +201 -71
- package/src/runs/background/async-execution.ts +206 -829
- package/src/runs/background/async-job-admission.ts +54 -0
- package/src/runs/background/async-job-projection.ts +225 -0
- package/src/runs/background/async-job-tracker.ts +416 -360
- package/src/runs/background/async-launch.ts +319 -0
- package/src/runs/background/async-plan.ts +285 -0
- package/src/runs/background/async-result-file.ts +79 -37
- package/src/runs/background/async-resume.ts +338 -285
- package/src/runs/background/async-run-discovery.ts +270 -0
- package/src/runs/background/async-run-location.ts +194 -0
- package/src/runs/background/async-run-record.ts +14 -0
- package/src/runs/background/async-run-repair.ts +307 -0
- package/src/runs/background/async-run-summary.ts +71 -0
- package/src/runs/background/async-single-plan.ts +168 -0
- package/src/runs/background/async-status-projection.ts +188 -0
- package/src/runs/background/async-status-render.ts +164 -0
- package/src/runs/background/async-status-validation.ts +238 -0
- package/src/runs/background/async-status.ts +9 -481
- package/src/runs/background/async-value.ts +29 -0
- package/src/runs/background/completion-dedupe.ts +103 -54
- package/src/runs/background/completion-delivery.ts +313 -187
- package/src/runs/background/completion-receipts.ts +309 -0
- package/src/runs/background/legacy-status-acceptance.ts +38 -0
- package/src/runs/background/notify.ts +167 -106
- package/src/runs/background/parallel-groups.ts +95 -46
- package/src/runs/background/result-payload.ts +268 -0
- package/src/runs/background/result-watcher.ts +484 -387
- package/src/runs/background/run-id-resolver.ts +126 -57
- package/src/runs/background/run-schemas.ts +240 -0
- package/src/runs/background/run-status-contracts.ts +46 -0
- package/src/runs/background/run-status-render.ts +364 -0
- package/src/runs/background/run-status.ts +338 -356
- package/src/runs/background/runner-attempt-output.ts +281 -0
- package/src/runs/background/runner-attempt.ts +354 -0
- package/src/runs/background/runner-child-executor.ts +232 -0
- package/src/runs/background/runner-child-observer.ts +270 -0
- package/src/runs/background/runner-completion-summary.ts +106 -0
- package/src/runs/background/runner-completion.ts +274 -0
- package/src/runs/background/runner-config.ts +52 -0
- package/src/runs/background/runner-contract.ts +51 -0
- package/src/runs/background/runner-dynamic.ts +185 -0
- package/src/runs/background/runner-finalization.ts +203 -0
- package/src/runs/background/runner-graph.ts +91 -0
- package/src/runs/background/runner-initial-status.ts +72 -0
- package/src/runs/background/runner-lifecycle.ts +159 -0
- package/src/runs/background/runner-monitor.ts +399 -0
- package/src/runs/background/runner-parallel.ts +280 -0
- package/src/runs/background/runner-prepare-step.ts +128 -0
- package/src/runs/background/runner-reporting.ts +192 -0
- package/src/runs/background/runner-status.ts +220 -0
- package/src/runs/background/runner-step-output.ts +158 -0
- package/src/runs/background/runner-step-record.ts +76 -0
- package/src/runs/background/runner-step.ts +150 -0
- package/src/runs/background/runner-streaming.ts +220 -0
- package/src/runs/background/runner-workflow.ts +284 -0
- package/src/runs/background/stale-run-reconciler.ts +279 -336
- package/src/runs/background/subagent-runner-launcher.ts +67 -35
- package/src/runs/background/subagent-runner.ts +80 -2048
- package/src/runs/background/top-level-async.ts +9 -7
- package/src/runs/foreground/chain-clarify.ts +499 -1334
- package/src/runs/foreground/clarification-draft.ts +92 -0
- package/src/runs/foreground/clarify-contracts.ts +33 -0
- package/src/runs/foreground/clarify-invocation.ts +192 -65
- package/src/runs/foreground/clarify-text-editor.ts +229 -0
- package/src/runs/foreground/clarify-view.ts +222 -0
- package/src/runs/foreground/execution-input.ts +358 -424
- package/src/runs/foreground/execution-routing.ts +41 -0
- package/src/runs/foreground/execution-timeout.ts +92 -0
- package/src/runs/foreground/foreground-control.ts +333 -812
- package/src/runs/foreground/foreground-memory.ts +132 -0
- package/src/runs/foreground/invocation-context.ts +88 -0
- package/src/runs/foreground/invocation-execution.ts +465 -0
- package/src/runs/foreground/invocation-expansion.ts +58 -0
- package/src/runs/foreground/management-actions.ts +360 -0
- package/src/runs/foreground/nested-control.ts +248 -0
- package/src/runs/foreground/question-continuation.ts +112 -0
- package/src/runs/foreground/question-control.ts +297 -70
- package/src/runs/foreground/resume-target.ts +330 -0
- package/src/runs/foreground/revival-launch-policy.ts +112 -0
- package/src/runs/foreground/run-async-path.ts +307 -223
- package/src/runs/foreground/run-interrupt.ts +202 -0
- package/src/runs/foreground/run-nudge.ts +355 -0
- package/src/runs/foreground/saved-revival.ts +356 -0
- package/src/runs/foreground/subagent-executor.ts +195 -493
- package/src/runs/foreground/subagent-params.ts +314 -242
- package/src/runs/foreground/wait-observation.ts +160 -0
- package/src/runs/foreground/wait-registration.ts +18 -0
- package/src/runs/foreground/wait-run.ts +361 -119
- package/src/runs/shared/acceptance-contract.ts +410 -209
- package/src/runs/shared/acceptance-defaults.ts +1 -0
- package/src/runs/shared/acceptance-evaluation.ts +314 -240
- package/src/runs/shared/acceptance-finalization.ts +447 -305
- package/src/runs/shared/acceptance-outcome.ts +69 -0
- package/src/runs/shared/acceptance-reports.ts +220 -126
- package/src/runs/shared/acceptance-submission.ts +251 -0
- package/src/runs/shared/acceptance-verification.ts +118 -0
- package/src/runs/shared/acceptance.ts +25 -25
- package/src/runs/shared/chain-outputs.ts +190 -98
- package/src/runs/shared/child-attempt-types.ts +118 -0
- package/src/runs/shared/child-attempt.ts +372 -608
- package/src/runs/shared/child-boundaries.ts +217 -0
- package/src/runs/shared/child-context-filter.ts +53 -0
- package/src/runs/shared/child-event-observer.ts +496 -0
- package/src/runs/shared/child-execution-cwd.ts +139 -68
- package/src/runs/shared/child-execution-outcome.ts +103 -0
- package/src/runs/shared/child-invocation.ts +74 -0
- package/src/runs/shared/child-message-validation.ts +233 -0
- package/src/runs/shared/child-native-accounting.ts +154 -0
- package/src/runs/shared/child-native-observation.ts +79 -0
- package/src/runs/shared/child-observation-spool.ts +188 -0
- package/src/runs/shared/child-observations.ts +219 -89
- package/src/runs/shared/child-presence.ts +6 -0
- package/src/runs/shared/child-route-env.ts +142 -0
- package/src/runs/shared/child-stream-observer.ts +302 -0
- package/src/runs/shared/child-stream-projection.ts +160 -0
- package/src/runs/shared/child-structured-tool.ts +38 -0
- package/src/runs/shared/claude-code.ts +201 -228
- package/src/runs/shared/claude-model.ts +67 -0
- package/src/runs/shared/claude-session.ts +124 -0
- package/src/runs/shared/claude-types.ts +31 -0
- package/src/runs/shared/completion-guard.ts +35 -26
- package/src/runs/shared/control-event-policy.ts +15 -0
- package/src/runs/shared/control-notification-owner.ts +20 -0
- package/src/runs/shared/dynamic-fanout.ts +402 -238
- package/src/runs/shared/dynamic-item.ts +114 -0
- package/src/runs/shared/history-index.ts +112 -51
- package/src/runs/shared/legacy-async-recovery.ts +153 -0
- package/src/runs/shared/legacy-output-recovery.ts +214 -0
- package/src/runs/shared/mcp-config-schema.ts +46 -0
- package/src/runs/shared/mcp-direct-tool-allowlist.ts +396 -307
- package/src/runs/shared/model-fallback.ts +302 -180
- package/src/runs/shared/mutating-tool-guard.ts +259 -158
- package/src/runs/shared/native-finalization-types.ts +29 -0
- package/src/runs/shared/native-finalization.ts +233 -109
- package/src/runs/shared/native-usage.ts +379 -96
- package/src/runs/shared/nested-control-records.ts +178 -0
- package/src/runs/shared/nested-events.ts +45 -752
- package/src/runs/shared/nested-path.ts +47 -34
- package/src/runs/shared/nested-projection.ts +230 -0
- package/src/runs/shared/nested-protocol.ts +67 -0
- package/src/runs/shared/nested-registry.ts +273 -0
- package/src/runs/shared/nested-render.ts +198 -100
- package/src/runs/shared/nested-route.ts +292 -0
- package/src/runs/shared/nested-validation.ts +291 -0
- package/src/runs/shared/owned-child-evidence.ts +184 -0
- package/src/runs/shared/owned-run-list.ts +187 -0
- package/src/runs/shared/owned-run-observation.ts +368 -0
- package/src/runs/shared/owned-run-progress.ts +172 -0
- package/src/runs/shared/owned-run-read-state.ts +7 -0
- package/src/runs/shared/owned-run-results.ts +289 -0
- package/src/runs/shared/owned-run-status.ts +239 -0
- package/src/runs/shared/owned-run-view.ts +65 -0
- package/src/runs/shared/owned-workflow-details.ts +24 -0
- package/src/runs/shared/owner-output.ts +73 -0
- package/src/runs/shared/parallel-utils.ts +93 -129
- package/src/runs/shared/parent-receipts.ts +177 -50
- package/src/runs/shared/parent-usage.ts +314 -91
- package/src/runs/shared/pi-args.ts +241 -311
- package/src/runs/shared/pi-launch-input.ts +48 -0
- package/src/runs/shared/pi-session-launch.ts +94 -0
- package/src/runs/shared/pi-spawn.ts +57 -33
- package/src/runs/shared/run-history-queries.ts +189 -38
- package/src/runs/shared/run-history.ts +197 -76
- package/src/runs/shared/run-id-ambiguity.ts +7 -3
- package/src/runs/shared/run-metadata-paths.ts +17 -0
- package/src/runs/shared/run-metadata.ts +240 -0
- package/src/runs/shared/run-persistence.ts +181 -0
- package/src/runs/shared/run-records.ts +19 -607
- package/src/runs/shared/run-restoration.ts +455 -0
- package/src/runs/shared/run-state-owner.ts +31 -0
- package/src/runs/shared/session-cwd-preload.ts +39 -19
- package/src/runs/shared/single-output.ts +358 -205
- package/src/runs/shared/stable-value.ts +15 -0
- package/src/runs/shared/streaming-text.ts +39 -12
- package/src/runs/shared/structured-output.ts +76 -46
- package/src/runs/shared/subagent-control.ts +330 -197
- package/src/runs/shared/subagent-prompt-runtime.ts +92 -174
- package/src/runs/shared/subagent-tool-loop-guard.ts +118 -68
- package/src/runs/shared/supervisor-question-state.ts +221 -0
- package/src/runs/shared/supervisor-questions.ts +396 -401
- package/src/runs/shared/workflow-graph.ts +400 -198
- package/src/runs/shared/workflow-policy.ts +245 -110
- package/src/runs/shared/worktree-contract.ts +29 -0
- package/src/runs/shared/worktree-hook.ts +181 -0
- package/src/runs/shared/worktree-location.ts +61 -0
- package/src/runs/shared/worktree-preservation.ts +10 -0
- package/src/runs/shared/worktree-process.ts +132 -0
- package/src/runs/shared/worktree.ts +459 -587
- package/src/shared/agent-context-policy.ts +176 -145
- package/src/shared/agent-dir.ts +15 -0
- package/src/shared/artifacts.ts +99 -68
- package/src/shared/atomic-json.ts +14 -11
- package/src/shared/chain-files.ts +72 -0
- package/src/shared/concurrency.ts +27 -0
- package/src/shared/content-preview.ts +117 -0
- package/src/shared/cooperative.ts +17 -13
- package/src/shared/execution-cwd.ts +34 -9
- package/src/shared/file-coalescer.ts +24 -22
- package/src/shared/fork-context.ts +52 -48
- package/src/shared/formatters.ts +88 -47
- package/src/shared/journal-frames.ts +197 -0
- package/src/shared/journal-projections.ts +133 -0
- package/src/shared/journal-reader.ts +18 -333
- package/src/shared/json-projection.ts +224 -0
- package/src/shared/lazy-tools.ts +76 -27
- package/src/shared/message-output.ts +146 -0
- package/src/shared/model-info.ts +94 -58
- package/src/shared/native-import.ts +25 -0
- package/src/shared/native-journal.ts +172 -0
- package/src/shared/native-session-loader.ts +13 -0
- package/src/shared/native-session.ts +3 -5
- package/src/shared/native-tui.ts +13 -3
- package/src/shared/native-typebox.ts +18 -3
- package/src/shared/output-page.ts +76 -0
- package/src/shared/post-exit-stdio-guard.ts +232 -172
- package/src/shared/prompt-sections.ts +13 -7
- package/src/shared/session-entries.ts +103 -44
- package/src/shared/session-identity.ts +17 -10
- package/src/shared/settings.ts +182 -367
- package/src/shared/status-format.ts +207 -98
- package/src/shared/stream-json.d.ts +10 -0
- package/src/shared/task-file-policy.ts +35 -0
- package/src/shared/temp-root.ts +122 -71
- package/src/shared/types/acceptance.ts +149 -0
- package/src/shared/types/async.ts +247 -0
- package/src/shared/types/config.ts +139 -0
- package/src/shared/types/details.ts +104 -0
- package/src/shared/types/history.ts +217 -0
- package/src/shared/types/inputs.ts +4 -0
- package/src/shared/types/intercom.ts +57 -0
- package/src/shared/types/launch.ts +39 -0
- package/src/shared/types/messages.ts +104 -0
- package/src/shared/types/nested.ts +153 -0
- package/src/shared/types/owned-runs.ts +148 -0
- package/src/shared/types/progress.ts +106 -0
- package/src/shared/types/questions.ts +103 -0
- package/src/shared/types/results.ts +119 -0
- package/src/shared/types/state.ts +56 -0
- package/src/shared/types/usage.ts +36 -0
- package/src/shared/types/workflow.ts +187 -0
- package/src/shared/types.ts +222 -1161
- package/src/shared/ui-mode.ts +1 -1
- package/src/shared/unknown.ts +59 -0
- package/src/shared/utils.ts +111 -305
- package/src/slash/command-discovery.ts +109 -0
- package/src/slash/command-input.ts +232 -0
- package/src/slash/prompt-template-bridge.ts +153 -400
- package/src/slash/prompt-template-contract.ts +152 -0
- package/src/slash/prompt-template-results.ts +189 -0
- package/src/slash/request-protocol.ts +87 -0
- package/src/slash/result-delivery.ts +312 -0
- package/src/slash/saved-chain.ts +115 -0
- package/src/slash/slash-bridge.ts +202 -156
- package/src/slash/slash-commands.ts +176 -598
- package/src/slash/slash-live-state.ts +287 -229
- package/src/tui/action-hints.ts +147 -61
- package/src/tui/activity-lines.ts +40 -0
- package/src/tui/agent-browser.ts +354 -0
- package/src/tui/agent-controls.ts +355 -0
- package/src/tui/agent-conversation.ts +514 -0
- package/src/tui/agent-dock.ts +250 -0
- package/src/tui/agent-history.ts +78 -203
- package/src/tui/agent-model.ts +78 -0
- package/src/tui/agent-picker.ts +325 -0
- package/src/tui/agent-view.ts +391 -1333
- package/src/tui/compact-results.ts +342 -0
- package/src/tui/conversation-details.ts +206 -0
- package/src/tui/conversation-frame.ts +184 -0
- package/src/tui/conversation-history.ts +246 -0
- package/src/tui/conversation-menu.ts +119 -0
- package/src/tui/conversation-notices.ts +116 -0
- package/src/tui/conversation-selection.ts +66 -0
- package/src/tui/conversation-viewport.ts +169 -0
- package/src/tui/direction-message.ts +35 -0
- package/src/tui/display.ts +409 -0
- package/src/tui/editor-viewport.ts +19 -0
- package/src/tui/expanded-content.ts +134 -0
- package/src/tui/expanded-multi.ts +264 -0
- package/src/tui/expanded-single.ts +92 -0
- package/src/tui/history-cards.ts +316 -0
- package/src/tui/history-display.ts +334 -0
- package/src/tui/history-json.ts +17 -0
- package/src/tui/history-metadata.ts +177 -0
- package/src/tui/history-record.ts +321 -0
- package/src/tui/history-text.ts +34 -0
- package/src/tui/indexed-history.ts +149 -0
- package/src/tui/nested-widget.ts +192 -0
- package/src/tui/picker-page.ts +80 -0
- package/src/tui/render.ts +100 -1546
- package/src/tui/result-facts.ts +99 -0
- package/src/tui/task-observation.ts +96 -0
- package/src/tui/task-store.ts +432 -0
- package/src/tui/text-values.ts +20 -0
- package/src/tui/view-connections.ts +64 -0
- package/src/tui/view-model.ts +181 -0
- package/src/tui/view-persistence.ts +57 -0
- package/src/tui/view-ports.ts +55 -0
- package/src/tui/view-session.ts +42 -0
- package/src/tui/widget-details.ts +220 -0
- package/src/tui/widget-status.ts +331 -0
- package/src/tui/widget.ts +208 -0
- package/src/tui/workflow-labels.ts +340 -0
- package/src/tui/workflow-outcomes.ts +150 -0
- package/tsconfig.build.json +11 -10
- package/tsconfig.json +30 -17
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import {
|
|
2
|
+
HistoryIndexError,
|
|
3
|
+
type HistoryRunOptions,
|
|
4
|
+
type HistoryRunPage,
|
|
5
|
+
type HistoryRunRow,
|
|
6
|
+
} from "./types.ts";
|
|
7
|
+
import { integer, pageLimit, hasText } from "./text.ts";
|
|
8
|
+
import { number, text, type Row, type IndexInput } from "./rows.ts";
|
|
9
|
+
import { parseRunRow } from "./wire-models.ts";
|
|
10
|
+
import type { QueryScope, Cursor } from "./query-scope.ts";
|
|
11
|
+
|
|
12
|
+
interface RunFilter {
|
|
13
|
+
readonly clauses: readonly string[];
|
|
14
|
+
readonly params: readonly IndexInput[];
|
|
15
|
+
readonly childWhere: string;
|
|
16
|
+
readonly childParams: readonly IndexInput[];
|
|
17
|
+
}
|
|
18
|
+
function validate(options: HistoryRunOptions): void {
|
|
19
|
+
if (
|
|
20
|
+
options.state !== undefined &&
|
|
21
|
+
!["live", "completed", "paused", "blocked", "failed", "unknown"].includes(options.state)
|
|
22
|
+
) {
|
|
23
|
+
throw new HistoryIndexError("INVALID", "Unsupported run state.");
|
|
24
|
+
}
|
|
25
|
+
validateFilters(options);
|
|
26
|
+
}
|
|
27
|
+
function validateFilters(options: HistoryRunOptions): void {
|
|
28
|
+
if (
|
|
29
|
+
(options.text?.length ?? 0) > 256 ||
|
|
30
|
+
(options.agent?.length ?? 0) > 256 ||
|
|
31
|
+
(options.latestTasksOnly !== undefined && typeof options.latestTasksOnly !== "boolean")
|
|
32
|
+
) {
|
|
33
|
+
throw new HistoryIndexError("INVALID", "Invalid run filter.");
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function queryKey(scope: Readonly<QueryScope>, options: HistoryRunOptions, sort: string): string {
|
|
37
|
+
return scope.key([
|
|
38
|
+
"runs",
|
|
39
|
+
sort,
|
|
40
|
+
options.agent ?? null,
|
|
41
|
+
options.state ?? null,
|
|
42
|
+
options.text?.toLowerCase() ?? null,
|
|
43
|
+
options.latestTasksOnly ?? false,
|
|
44
|
+
]);
|
|
45
|
+
}
|
|
46
|
+
function filters(options: HistoryRunOptions): RunFilter {
|
|
47
|
+
const clauses: string[] = [];
|
|
48
|
+
const params: IndexInput[] = [];
|
|
49
|
+
const childClauses: string[] = [];
|
|
50
|
+
const childParams: IndexInput[] = [];
|
|
51
|
+
if (hasText(options.agent)) {
|
|
52
|
+
childClauses.push("c.agent=?");
|
|
53
|
+
childParams.push(options.agent);
|
|
54
|
+
}
|
|
55
|
+
if (hasText(options.text)) {
|
|
56
|
+
childClauses.push("instr(c.filter_text,?)>0");
|
|
57
|
+
childParams.push(options.text.toLowerCase());
|
|
58
|
+
}
|
|
59
|
+
if (options.latestTasksOnly === true) {
|
|
60
|
+
childClauses.push(
|
|
61
|
+
"NOT EXISTS(SELECT 1 FROM runs successor WHERE successor.predecessor_id=c.run_id AND successor.predecessor_index=c.child_index)",
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
const childWhere = childClauses.length > 0 ? ` AND ${childClauses.join(" AND ")}` : "";
|
|
65
|
+
if (childWhere.length > 0) {
|
|
66
|
+
clauses.push(`EXISTS(SELECT 1 FROM children c WHERE c.run_id=r.id${childWhere})`);
|
|
67
|
+
params.push(...childParams);
|
|
68
|
+
}
|
|
69
|
+
if (hasText(options.state)) {
|
|
70
|
+
clauses.push("r.state=?");
|
|
71
|
+
params.push(options.state);
|
|
72
|
+
}
|
|
73
|
+
return { clauses, params, childWhere, childParams };
|
|
74
|
+
}
|
|
75
|
+
function columns(sort: HistoryRunOptions["sort"]): readonly string[] {
|
|
76
|
+
if (sort === "attention") {
|
|
77
|
+
return ["attention", "negative_updated", "id"];
|
|
78
|
+
}
|
|
79
|
+
return [sort === "newest" ? "negative_updated" : "updated", "id"];
|
|
80
|
+
}
|
|
81
|
+
function runSort(value: HistoryRunOptions["sort"]): NonNullable<HistoryRunOptions["sort"]> {
|
|
82
|
+
const sort = value ?? "attention";
|
|
83
|
+
if (!["attention", "newest", "oldest"].includes(sort)) {
|
|
84
|
+
throw new HistoryIndexError("INVALID", "Unsupported run sort.");
|
|
85
|
+
}
|
|
86
|
+
return sort;
|
|
87
|
+
}
|
|
88
|
+
function seek(filter: RunFilter, cursor: Cursor | undefined, order: readonly string[]): RunFilter {
|
|
89
|
+
if (!cursor) {
|
|
90
|
+
return filter;
|
|
91
|
+
}
|
|
92
|
+
if (cursor.keys.length !== order.length) {
|
|
93
|
+
throw new HistoryIndexError("INVALID_CURSOR", "Invalid run seek tuple.");
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
...filter,
|
|
97
|
+
clauses: [
|
|
98
|
+
...filter.clauses,
|
|
99
|
+
`(${order.map((column) => `r.${column}`).join(",")}) > (${order.map(() => "?").join(",")})`,
|
|
100
|
+
],
|
|
101
|
+
params: [...filter.params, ...cursor.keys],
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
export class RunQueries {
|
|
105
|
+
private readonly scope: Readonly<QueryScope>;
|
|
106
|
+
constructor(scope: Readonly<QueryScope>) {
|
|
107
|
+
this.scope = scope;
|
|
108
|
+
}
|
|
109
|
+
private view(row: Row, filter: RunFilter): HistoryRunRow {
|
|
110
|
+
const value: unknown = JSON.parse(text(row, "view"));
|
|
111
|
+
const view = parseRunRow(value);
|
|
112
|
+
const matchedChildIndexes =
|
|
113
|
+
filter.childWhere.length > 0
|
|
114
|
+
? this.scope.store
|
|
115
|
+
.all(
|
|
116
|
+
`SELECT child_index FROM children c WHERE c.run_id=?${filter.childWhere} ORDER BY child_index`,
|
|
117
|
+
view.runId,
|
|
118
|
+
...filter.childParams,
|
|
119
|
+
)
|
|
120
|
+
.map((child) => number(child, "child_index"))
|
|
121
|
+
: view.matchedChildIndexes;
|
|
122
|
+
return {
|
|
123
|
+
...view,
|
|
124
|
+
...(matchedChildIndexes === undefined ? {} : { matchedChildIndexes }),
|
|
125
|
+
children: view.children.map((child) => {
|
|
126
|
+
const { source } = this.scope.child(view.runId, child.index);
|
|
127
|
+
if (!source) {
|
|
128
|
+
return child;
|
|
129
|
+
}
|
|
130
|
+
const boundary =
|
|
131
|
+
child.state === "live"
|
|
132
|
+
? {}
|
|
133
|
+
: {
|
|
134
|
+
terminalEntryId: child.result?.terminalEntryId,
|
|
135
|
+
endedAt:
|
|
136
|
+
(child.result?.terminalEntryId?.length ?? 0) > 0 ? undefined : view.updatedAt,
|
|
137
|
+
leaf: child.result?.terminalLeafId,
|
|
138
|
+
};
|
|
139
|
+
return Object.assign({}, child, {
|
|
140
|
+
nativeConfiguration: this.scope.configuration(source, boundary, false),
|
|
141
|
+
});
|
|
142
|
+
}),
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
private nextPage(
|
|
146
|
+
query: string,
|
|
147
|
+
order: readonly string[],
|
|
148
|
+
page: readonly Row[],
|
|
149
|
+
position: number,
|
|
150
|
+
): Pick<HistoryRunPage, "nextOffset" | "nextCursor"> {
|
|
151
|
+
const last = page.at(-1);
|
|
152
|
+
return last
|
|
153
|
+
? {
|
|
154
|
+
nextOffset: position + page.length,
|
|
155
|
+
nextCursor: this.scope.cursor(
|
|
156
|
+
query,
|
|
157
|
+
order.map((column) => (column === "id" ? text(last, column) : number(last, column))),
|
|
158
|
+
position + page.length,
|
|
159
|
+
),
|
|
160
|
+
}
|
|
161
|
+
: {};
|
|
162
|
+
}
|
|
163
|
+
list(options: HistoryRunOptions): HistoryRunPage {
|
|
164
|
+
validate(options);
|
|
165
|
+
const limit = pageLimit(options.limit, 20);
|
|
166
|
+
const offset = integer(options.offset, 0);
|
|
167
|
+
const sort = runSort(options.sort);
|
|
168
|
+
const query = queryKey(this.scope, options, sort);
|
|
169
|
+
const cursor = this.scope.parseCursor(options.cursor, query);
|
|
170
|
+
if (cursor && options.offset !== undefined) {
|
|
171
|
+
throw new HistoryIndexError("INVALID", "Use cursor or offset, not both.");
|
|
172
|
+
}
|
|
173
|
+
const filter = filters(options);
|
|
174
|
+
const total = number(
|
|
175
|
+
this.scope.store.require(
|
|
176
|
+
`SELECT COUNT(*) AS total FROM runs r ${filter.clauses.length > 0 ? `WHERE ${filter.clauses.join(" AND ")}` : ""}`,
|
|
177
|
+
...filter.params,
|
|
178
|
+
),
|
|
179
|
+
"total",
|
|
180
|
+
);
|
|
181
|
+
const order = columns(sort);
|
|
182
|
+
const selected = seek(filter, cursor, order);
|
|
183
|
+
const rows = this.scope.store.all(
|
|
184
|
+
`SELECT * FROM runs r ${selected.clauses.length > 0 ? `WHERE ${selected.clauses.join(" AND ")}` : ""} ORDER BY ${order.map((column) => `r.${column}`).join(",")} LIMIT ? OFFSET ?`,
|
|
185
|
+
...selected.params,
|
|
186
|
+
limit + 1,
|
|
187
|
+
cursor ? 0 : offset,
|
|
188
|
+
);
|
|
189
|
+
const page = rows.slice(0, limit);
|
|
190
|
+
const position = cursor?.offset ?? offset;
|
|
191
|
+
return {
|
|
192
|
+
rows: page.map((row) => this.view(row, filter)),
|
|
193
|
+
total,
|
|
194
|
+
offset: position,
|
|
195
|
+
...this.scope.info(),
|
|
196
|
+
...this.nextPage(query, order, rows.length > limit ? page : [], position),
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import type { DatabaseSync } from "node:sqlite";
|
|
3
|
+
|
|
4
|
+
export const HISTORY_SCHEMA_VERSION = 5;
|
|
5
|
+
|
|
6
|
+
/** One schema version owns the row, FTS and cursor publication contracts together. */
|
|
7
|
+
export function createHistorySchema(db: DatabaseSync): void {
|
|
8
|
+
db.exec(`
|
|
9
|
+
CREATE TABLE meta(key TEXT PRIMARY KEY,value TEXT NOT NULL);
|
|
10
|
+
INSERT INTO meta VALUES ('generation','${randomUUID()}'),('version','0'),('indexedAt','0');
|
|
11
|
+
CREATE TABLE runs(id TEXT PRIMARY KEY,attention INTEGER NOT NULL,updated INTEGER NOT NULL,negative_updated INTEGER NOT NULL,state TEXT NOT NULL,filter_text TEXT NOT NULL,view TEXT NOT NULL,predecessor_id TEXT,predecessor_index INTEGER);
|
|
12
|
+
CREATE INDEX runs_predecessor ON runs(predecessor_id,predecessor_index);
|
|
13
|
+
CREATE INDEX runs_attention ON runs(attention,negative_updated,id);
|
|
14
|
+
CREATE INDEX runs_newest ON runs(negative_updated,id);
|
|
15
|
+
CREATE INDEX runs_oldest ON runs(updated,id);
|
|
16
|
+
CREATE INDEX runs_state ON runs(state,attention,negative_updated,id);
|
|
17
|
+
CREATE TABLE sources(id TEXT PRIMARY KEY,path TEXT NOT NULL UNIQUE,generation INTEGER NOT NULL DEFAULT 1,identity TEXT,stamp TEXT,session_id TEXT,header_digest TEXT,cursor INTEGER NOT NULL DEFAULT 0,prefix_digest TEXT,state TEXT NOT NULL DEFAULT 'pending',error TEXT,malformed INTEGER NOT NULL DEFAULT 0,complexity INTEGER NOT NULL DEFAULT 0,checked_at INTEGER,format_version INTEGER);
|
|
18
|
+
CREATE TABLE children(run_id TEXT NOT NULL REFERENCES runs(id) ON DELETE CASCADE,child_index INTEGER NOT NULL,agent TEXT NOT NULL,source_id TEXT REFERENCES sources(id),filter_text TEXT NOT NULL,output_digest TEXT,terminal_entry_id TEXT,ended_at INTEGER,PRIMARY KEY(run_id,child_index));
|
|
19
|
+
CREATE INDEX children_source ON children(source_id);
|
|
20
|
+
CREATE INDEX children_agent ON children(agent,run_id);
|
|
21
|
+
CREATE TABLE entries(rowid INTEGER PRIMARY KEY,source_id TEXT NOT NULL REFERENCES sources(id),generation INTEGER NOT NULL,id TEXT NOT NULL,native_id TEXT,parent_id TEXT,start INTEGER NOT NULL,end INTEGER NOT NULL,digest TEXT NOT NULL,timestamp INTEGER,type TEXT NOT NULL,preview TEXT NOT NULL,published INTEGER NOT NULL DEFAULT 0,role TEXT,assistant_text INTEGER NOT NULL DEFAULT 0,visible_id TEXT,human_id TEXT,configuration_model TEXT,configuration_thinking TEXT,UNIQUE(source_id,generation,id),UNIQUE(source_id,generation,start));
|
|
22
|
+
CREATE INDEX entries_page ON entries(source_id,generation,published,start);
|
|
23
|
+
CREATE INDEX entries_time ON entries(source_id,generation,published,timestamp,start);
|
|
24
|
+
CREATE INDEX entries_human ON entries(source_id,generation,human_id,start);
|
|
25
|
+
CREATE TABLE answers(entry_rowid INTEGER NOT NULL REFERENCES entries(rowid) ON DELETE CASCADE,digest TEXT NOT NULL,item_id TEXT NOT NULL,PRIMARY KEY(entry_rowid,digest));
|
|
26
|
+
CREATE INDEX answers_digest ON answers(digest,entry_rowid);
|
|
27
|
+
CREATE TABLE tools(entry_rowid INTEGER NOT NULL REFERENCES entries(rowid) ON DELETE CASCADE,source_id TEXT NOT NULL,generation INTEGER NOT NULL,call_id TEXT NOT NULL,kind TEXT NOT NULL);
|
|
28
|
+
CREATE INDEX tools_lookup ON tools(source_id,generation,call_id,kind);
|
|
29
|
+
CREATE TABLE documents(id INTEGER PRIMARY KEY,entry_rowid INTEGER NOT NULL REFERENCES entries(rowid) ON DELETE CASCADE,field TEXT NOT NULL,text_start INTEGER NOT NULL,text_end INTEGER NOT NULL,preview TEXT NOT NULL);
|
|
30
|
+
CREATE INDEX documents_entry ON documents(entry_rowid);
|
|
31
|
+
CREATE VIRTUAL TABLE corpus USING fts5(text,content='',contentless_delete=1,tokenize='unicode61');
|
|
32
|
+
PRAGMA user_version=${HISTORY_SCHEMA_VERSION};
|
|
33
|
+
`);
|
|
34
|
+
}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import {
|
|
2
|
+
HistoryIndexError,
|
|
3
|
+
type HistorySearchInput,
|
|
4
|
+
type HistorySearchPage,
|
|
5
|
+
type HistorySearchMatch,
|
|
6
|
+
} from "./types.ts";
|
|
7
|
+
import { integer, pageLimit, hasText } from "./text.ts";
|
|
8
|
+
import { number, nullableNumber, nullableText, text, type Row, type IndexInput } from "./rows.ts";
|
|
9
|
+
import type { QueryScope, Cursor } from "./query-scope.ts";
|
|
10
|
+
|
|
11
|
+
function searchGrammar(query: string): readonly string[] {
|
|
12
|
+
if (typeof query !== "string" || query.trim().length === 0 || query.length > 1024) {
|
|
13
|
+
throw new HistoryIndexError(
|
|
14
|
+
"INVALID_QUERY",
|
|
15
|
+
"Search requires 1–12 tokens or one quoted phrase.",
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
const value = query.trim();
|
|
19
|
+
const phrase = value.startsWith('"') && value.endsWith('"');
|
|
20
|
+
const words = (phrase ? value.slice(1, -1) : value).trim().split(/\s+/u);
|
|
21
|
+
if (
|
|
22
|
+
words.length === 0 ||
|
|
23
|
+
words.length > 12 ||
|
|
24
|
+
words.some(
|
|
25
|
+
(word) =>
|
|
26
|
+
!/^[\p{L}\p{N}\p{M}]{1,64}$/u.test(word) ||
|
|
27
|
+
(!phrase && ["AND", "OR", "NOT", "NEAR"].includes(word)),
|
|
28
|
+
)
|
|
29
|
+
) {
|
|
30
|
+
throw new HistoryIndexError(
|
|
31
|
+
"INVALID_QUERY",
|
|
32
|
+
"Only lexical tokens or one quoted phrase are supported; operators, punctuation, and prefixes are not allowed.",
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
return phrase ? [`"${words.join(" ")}"`] : [...new Set(words.map((word) => `"${word}"`))];
|
|
36
|
+
}
|
|
37
|
+
function match(row: Row): HistorySearchMatch {
|
|
38
|
+
return {
|
|
39
|
+
id: number(row, "document_id"),
|
|
40
|
+
runId: text(row, "run_id"),
|
|
41
|
+
index: number(row, "child_index"),
|
|
42
|
+
agent: text(row, "agent"),
|
|
43
|
+
entryId: text(row, "id"),
|
|
44
|
+
nativeId: nullableText(row, "native_id"),
|
|
45
|
+
sessionId: nullableText(row, "session_id"),
|
|
46
|
+
sessionFile: text(row, "path"),
|
|
47
|
+
timestamp: nullableNumber(row, "timestamp"),
|
|
48
|
+
ref: {
|
|
49
|
+
sourceId: text(row, "source_id"),
|
|
50
|
+
generation: number(row, "generation"),
|
|
51
|
+
start: number(row, "start"),
|
|
52
|
+
end: number(row, "end"),
|
|
53
|
+
digest: text(row, "digest"),
|
|
54
|
+
},
|
|
55
|
+
preview: text(row, "document_preview"),
|
|
56
|
+
field: text(row, "field"),
|
|
57
|
+
textStart: number(row, "text_start"),
|
|
58
|
+
textEnd: number(row, "text_end"),
|
|
59
|
+
score: number(row, "score"),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
interface SearchPlan {
|
|
63
|
+
readonly clauses: readonly string[];
|
|
64
|
+
readonly params: readonly IndexInput[];
|
|
65
|
+
readonly eligible: string;
|
|
66
|
+
readonly eligibleParams: readonly IndexInput[];
|
|
67
|
+
}
|
|
68
|
+
function plan(
|
|
69
|
+
input: HistorySearchInput,
|
|
70
|
+
expression: readonly string[],
|
|
71
|
+
cursor: Cursor | undefined,
|
|
72
|
+
score: string,
|
|
73
|
+
): SearchPlan {
|
|
74
|
+
const clauses = [
|
|
75
|
+
"e.published=1",
|
|
76
|
+
"e.generation=s.generation",
|
|
77
|
+
"(c.terminal_entry_id IS NULL OR e.start<=terminal.start)",
|
|
78
|
+
"(c.ended_at IS NULL OR e.timestamp<=c.ended_at)",
|
|
79
|
+
];
|
|
80
|
+
const params: IndexInput[] = [...expression];
|
|
81
|
+
if (hasText(input.runId)) {
|
|
82
|
+
clauses.push("c.run_id=?");
|
|
83
|
+
params.push(input.runId);
|
|
84
|
+
}
|
|
85
|
+
if (input.index !== undefined) {
|
|
86
|
+
clauses.push("c.child_index=?");
|
|
87
|
+
params.push(input.index);
|
|
88
|
+
}
|
|
89
|
+
if (hasText(input.agent)) {
|
|
90
|
+
if (input.agent.length > 256) {
|
|
91
|
+
throw new HistoryIndexError("INVALID", "Agent filter is too long.");
|
|
92
|
+
}
|
|
93
|
+
clauses.push("c.agent=?");
|
|
94
|
+
params.push(input.agent);
|
|
95
|
+
}
|
|
96
|
+
// Scope physical records once before aggregation; bm25 still uses the whole corpus.
|
|
97
|
+
const eligible =
|
|
98
|
+
hasText(input.runId) || hasText(input.agent)
|
|
99
|
+
? `eligible AS MATERIALIZED (SELECT e.rowid FROM entries e JOIN sources s ON s.id=e.source_id WHERE e.published=1 AND e.generation=s.generation AND e.source_id IN (SELECT c.source_id FROM children c WHERE ${clauses.slice(4).join(" AND ")})),`
|
|
100
|
+
: "";
|
|
101
|
+
const eligibleParams = eligible.length > 0 ? params.slice(expression.length) : [];
|
|
102
|
+
if (cursor) {
|
|
103
|
+
if (cursor.keys.length !== 4) {
|
|
104
|
+
throw new HistoryIndexError("INVALID_CURSOR", "Invalid search seek tuple.");
|
|
105
|
+
}
|
|
106
|
+
clauses.push(`(${score},d.id,c.run_id,c.child_index)>(?,?,?,?)`);
|
|
107
|
+
params.push(...cursor.keys);
|
|
108
|
+
}
|
|
109
|
+
return { clauses, params, eligible, eligibleParams };
|
|
110
|
+
}
|
|
111
|
+
function queryKey(
|
|
112
|
+
scope: Readonly<QueryScope>,
|
|
113
|
+
input: HistorySearchInput,
|
|
114
|
+
expression: readonly string[],
|
|
115
|
+
sort: string,
|
|
116
|
+
): string {
|
|
117
|
+
return scope.key([
|
|
118
|
+
"search",
|
|
119
|
+
expression,
|
|
120
|
+
sort,
|
|
121
|
+
input.runId ?? null,
|
|
122
|
+
input.index ?? null,
|
|
123
|
+
input.agent ?? null,
|
|
124
|
+
]);
|
|
125
|
+
}
|
|
126
|
+
export class SearchQueries {
|
|
127
|
+
private readonly scope: Readonly<QueryScope>;
|
|
128
|
+
constructor(scope: Readonly<QueryScope>) {
|
|
129
|
+
this.scope = scope;
|
|
130
|
+
}
|
|
131
|
+
private validateScope(input: HistorySearchInput): void {
|
|
132
|
+
if (input.index !== undefined && !hasText(input.runId)) {
|
|
133
|
+
throw new HistoryIndexError("INVALID", "A child search requires runId.");
|
|
134
|
+
}
|
|
135
|
+
if (!hasText(input.runId)) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (!this.scope.store.get("SELECT id FROM runs WHERE id=?", input.runId)) {
|
|
139
|
+
throw new HistoryIndexError("OWNERSHIP", "Run is not admitted by the current owner.");
|
|
140
|
+
}
|
|
141
|
+
if (input.index !== undefined) {
|
|
142
|
+
this.scope.child(input.runId, integer(input.index, 0));
|
|
143
|
+
}
|
|
144
|
+
this.checkAttemptBoundaries(input);
|
|
145
|
+
}
|
|
146
|
+
private checkAttemptBoundaries(input: Pick<HistorySearchInput, "runId" | "index">): void {
|
|
147
|
+
for (const child of this.scope.store.all(
|
|
148
|
+
`SELECT source_id,terminal_entry_id,ended_at FROM children WHERE run_id=?${input.index !== undefined ? " AND child_index=?" : ""}`,
|
|
149
|
+
input.runId ?? "",
|
|
150
|
+
...(input.index !== undefined ? [input.index] : []),
|
|
151
|
+
)) {
|
|
152
|
+
const sourceId = nullableText(child, "source_id");
|
|
153
|
+
const source = sourceId === null ? undefined : this.scope.store.source(sourceId);
|
|
154
|
+
if (source) {
|
|
155
|
+
this.scope.boundary(source, {
|
|
156
|
+
terminalEntryId: nullableText(child, "terminal_entry_id") ?? undefined,
|
|
157
|
+
endedAt: nullableNumber(child, "ended_at") ?? undefined,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
private rows(
|
|
163
|
+
expression: readonly string[],
|
|
164
|
+
filter: SearchPlan,
|
|
165
|
+
score: string,
|
|
166
|
+
limit: number,
|
|
167
|
+
): readonly Row[] {
|
|
168
|
+
// Match every token across a record's visible windows; a quoted phrase cannot span fields.
|
|
169
|
+
// Ranking/filters precede LIMIT. The parent owns the hard deadline for a costly FTS scan.
|
|
170
|
+
return this.scope.store.all(
|
|
171
|
+
`WITH ${filter.eligible} hits AS MATERIALIZED (
|
|
172
|
+
${expression.map((_term, index) => `SELECT d.id,d.entry_rowid,bm25(corpus) AS score,${index} AS term FROM corpus JOIN documents d ON d.id=corpus.rowid WHERE corpus MATCH ?${filter.eligible.length > 0 ? " AND d.entry_rowid IN (SELECT rowid FROM eligible)" : ""}`).join(" UNION ALL ")}
|
|
173
|
+
), terms AS (SELECT entry_rowid,term,MIN(score) AS score FROM hits GROUP BY entry_rowid,term),
|
|
174
|
+
matched AS (SELECT entry_rowid,SUM(score) AS score FROM terms GROUP BY entry_rowid HAVING COUNT(*)=${expression.length}),
|
|
175
|
+
excerpts AS (SELECT id,entry_rowid,ROW_NUMBER() OVER (PARTITION BY entry_rowid ORDER BY score,id) AS choice FROM hits)
|
|
176
|
+
SELECT d.*,${score} AS score,e.*,d.id AS document_id,s.path,s.session_id,c.run_id,c.child_index,c.agent,d.preview AS document_preview FROM matched JOIN excerpts ON excerpts.entry_rowid=matched.entry_rowid AND excerpts.choice=1 JOIN documents d ON d.id=excerpts.id JOIN entries e ON e.rowid=matched.entry_rowid JOIN sources s ON s.id=e.source_id JOIN children c ON c.source_id=s.id LEFT JOIN entries terminal ON terminal.source_id=s.id AND terminal.generation=s.generation AND terminal.id=c.terminal_entry_id AND terminal.published=1 WHERE ${filter.clauses.join(" AND ")} ORDER BY score,d.id,c.run_id,c.child_index LIMIT ?`,
|
|
177
|
+
...filter.eligibleParams,
|
|
178
|
+
...filter.params,
|
|
179
|
+
limit + 1,
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
search(input: HistorySearchInput): HistorySearchPage {
|
|
183
|
+
const expression = searchGrammar(input.query);
|
|
184
|
+
const limit = pageLimit(input.limit, 20);
|
|
185
|
+
const sort = input.sort ?? "relevance";
|
|
186
|
+
if (!["relevance", "newest"].includes(sort)) {
|
|
187
|
+
throw new HistoryIndexError("INVALID", "Unsupported search sort.");
|
|
188
|
+
}
|
|
189
|
+
this.validateScope(input);
|
|
190
|
+
const query = queryKey(this.scope, input, expression, sort);
|
|
191
|
+
const cursor = this.scope.parseCursor(input.cursor, query);
|
|
192
|
+
const score = sort === "relevance" ? "matched.score" : "-COALESCE(e.timestamp,0)";
|
|
193
|
+
const filter = plan(input, expression, cursor, score);
|
|
194
|
+
const rows = this.rows(expression, filter, score, limit);
|
|
195
|
+
const page = rows.slice(0, limit);
|
|
196
|
+
const last = page.at(-1);
|
|
197
|
+
return {
|
|
198
|
+
...this.scope.info(),
|
|
199
|
+
matches: page.map(match),
|
|
200
|
+
...(rows.length > limit && last
|
|
201
|
+
? {
|
|
202
|
+
nextCursor: this.scope.cursor(
|
|
203
|
+
query,
|
|
204
|
+
[
|
|
205
|
+
number(last, "score"),
|
|
206
|
+
number(last, "document_id"),
|
|
207
|
+
text(last, "run_id"),
|
|
208
|
+
number(last, "child_index"),
|
|
209
|
+
],
|
|
210
|
+
(cursor?.offset ?? 0) + page.length,
|
|
211
|
+
),
|
|
212
|
+
}
|
|
213
|
+
: {}),
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { JsonProjection } from "../shared/journal-reader.ts";
|
|
4
|
+
import { HistoryIndexError } from "./types.ts";
|
|
5
|
+
import type { EntryRow, SourceRow } from "./rows.ts";
|
|
6
|
+
import { identity } from "./source-file.ts";
|
|
7
|
+
import { previewLimits, previewProjection } from "./preview.ts";
|
|
8
|
+
import { parseObject } from "./values.ts";
|
|
9
|
+
import { isRecord, hasErrorCode } from "../shared/unknown.ts";
|
|
10
|
+
|
|
11
|
+
function validateHeader(fd: number, source: SourceRow): void {
|
|
12
|
+
const hash = createHash("sha256");
|
|
13
|
+
const bytes = Buffer.allocUnsafe(64 * 1024);
|
|
14
|
+
let position = 0;
|
|
15
|
+
let complete = false;
|
|
16
|
+
while (!complete && position < 1024 * 1024) {
|
|
17
|
+
const count = fs.readSync(fd, bytes, 0, bytes.length, position);
|
|
18
|
+
if (count === 0) {
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
const newline = bytes.subarray(0, count).indexOf(10);
|
|
22
|
+
const length = newline < 0 ? count : newline + 1;
|
|
23
|
+
hash.update(bytes.subarray(0, length));
|
|
24
|
+
position += length;
|
|
25
|
+
complete = newline >= 0;
|
|
26
|
+
}
|
|
27
|
+
if (!complete || hash.digest("hex") !== source.header_digest) {
|
|
28
|
+
throw new HistoryIndexError(
|
|
29
|
+
"SOURCE_CHANGED",
|
|
30
|
+
"Selected native header changed or exceeds its validation budget.",
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function readBody(
|
|
35
|
+
fd: number,
|
|
36
|
+
row: EntryRow,
|
|
37
|
+
full: boolean,
|
|
38
|
+
): { readonly finish: () => Readonly<Record<string, unknown>>; readonly digest: string } {
|
|
39
|
+
const digest = createHash("sha256");
|
|
40
|
+
const parser = new JsonProjection(previewProjection, undefined, undefined, previewLimits);
|
|
41
|
+
const bytes = Buffer.allocUnsafe(64 * 1024);
|
|
42
|
+
const body: Buffer[] = [];
|
|
43
|
+
const decoder = new TextDecoder("utf8", { fatal: true });
|
|
44
|
+
for (let position = row.start; position < row.end;) {
|
|
45
|
+
const count = fs.readSync(fd, bytes, 0, Math.min(bytes.length, row.end - position), position);
|
|
46
|
+
if (count === 0) {
|
|
47
|
+
throw new HistoryIndexError(
|
|
48
|
+
"SOURCE_CHANGED",
|
|
49
|
+
"Selected record was truncated during validation.",
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
const chunk = bytes.subarray(0, count);
|
|
53
|
+
digest.update(chunk);
|
|
54
|
+
if (full) {
|
|
55
|
+
body.push(Buffer.from(chunk));
|
|
56
|
+
} else {
|
|
57
|
+
parser.write(decoder.decode(chunk, { stream: true }));
|
|
58
|
+
}
|
|
59
|
+
position += count;
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
digest: digest.digest("hex"),
|
|
63
|
+
finish: () => {
|
|
64
|
+
if (full) {
|
|
65
|
+
return parseObject(new TextDecoder("utf8", { fatal: true }).decode(Buffer.concat(body)));
|
|
66
|
+
}
|
|
67
|
+
parser.write(decoder.decode());
|
|
68
|
+
const projected = parser.finish();
|
|
69
|
+
if (!isRecord(projected)) {
|
|
70
|
+
throw new HistoryIndexError("SOURCE_CHANGED", "Selected record is not an object.");
|
|
71
|
+
}
|
|
72
|
+
return projected;
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function validateSnapshot(
|
|
77
|
+
fd: number,
|
|
78
|
+
source: SourceRow,
|
|
79
|
+
row: EntryRow,
|
|
80
|
+
snapshot: { readonly before: fs.BigIntStats; readonly digest: string },
|
|
81
|
+
): void {
|
|
82
|
+
const { before, digest } = snapshot;
|
|
83
|
+
const current = fs.statSync(source.path, { bigint: true });
|
|
84
|
+
const after = fs.fstatSync(fd, { bigint: true });
|
|
85
|
+
if (
|
|
86
|
+
identity(current) !== identity(before) ||
|
|
87
|
+
current.size < BigInt(row.end) ||
|
|
88
|
+
(after.ctimeNs !== before.ctimeNs && after.size <= before.size) ||
|
|
89
|
+
digest !== row.digest
|
|
90
|
+
) {
|
|
91
|
+
throw new HistoryIndexError(
|
|
92
|
+
"SOURCE_CHANGED",
|
|
93
|
+
"Selected record changed; refresh history before reading details.",
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/** Revalidate physical identity, native header and exact selected bytes before exposing detail. */
|
|
98
|
+
export function validateRecord(
|
|
99
|
+
source: SourceRow,
|
|
100
|
+
row: EntryRow,
|
|
101
|
+
full: boolean,
|
|
102
|
+
): Readonly<Record<string, unknown>> {
|
|
103
|
+
let fd: number | undefined;
|
|
104
|
+
try {
|
|
105
|
+
fd = fs.openSync(source.path, "r");
|
|
106
|
+
const stat = fs.fstatSync(fd, { bigint: true });
|
|
107
|
+
if (identity(stat) !== source.identity || Number(stat.size) < row.end) {
|
|
108
|
+
throw new HistoryIndexError(
|
|
109
|
+
"SOURCE_CHANGED",
|
|
110
|
+
"Selected conversation was replaced or truncated.",
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
validateHeader(fd, source);
|
|
114
|
+
if (full && row.end - row.start > 16 * 1024 * 1024) {
|
|
115
|
+
throw new HistoryIndexError(
|
|
116
|
+
"RECORD_TOO_LARGE",
|
|
117
|
+
"Selected full record exceeds the 16 MiB detail budget; use its validated preview.",
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
const body = readBody(fd, row, full);
|
|
121
|
+
validateSnapshot(fd, source, row, { before: stat, digest: body.digest });
|
|
122
|
+
// Physical validation wins over full JSON/UTF-8 decode errors if the file changed during reading.
|
|
123
|
+
return body.finish();
|
|
124
|
+
} catch (error) {
|
|
125
|
+
if (hasErrorCode(error, "ENOENT")) {
|
|
126
|
+
throw new HistoryIndexError("SOURCE_CHANGED", "Selected conversation is missing.");
|
|
127
|
+
}
|
|
128
|
+
if (error instanceof RangeError) {
|
|
129
|
+
throw new HistoryIndexError(
|
|
130
|
+
"RECORD_COMPLEXITY",
|
|
131
|
+
"Selected preview exceeds bounded history structure budgets.",
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
throw error;
|
|
135
|
+
} finally {
|
|
136
|
+
if (fd !== undefined) {
|
|
137
|
+
fs.closeSync(fd);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import type { HistoryStore, SourceRow } from "./store.ts";
|
|
3
|
+
import { HistoryIndexError } from "./types.ts";
|
|
4
|
+
|
|
5
|
+
export function identity(stat: fs.BigIntStats): string {
|
|
6
|
+
return `${stat.dev}:${stat.ino}`;
|
|
7
|
+
}
|
|
8
|
+
export function stamp(stat: fs.BigIntStats): string {
|
|
9
|
+
return `${identity(stat)}:${stat.size}:${stat.mtimeNs}:${stat.ctimeNs}`;
|
|
10
|
+
}
|
|
11
|
+
export function requireSource(store: Readonly<HistoryStore>, id: string): SourceRow {
|
|
12
|
+
const source = store.source(id);
|
|
13
|
+
if (!source) {
|
|
14
|
+
throw new HistoryIndexError("SOURCE_CHANGED", "Source was removed before ingestion.");
|
|
15
|
+
}
|
|
16
|
+
return source;
|
|
17
|
+
}
|
|
18
|
+
/** Acquires the writer lock before reading any cursor or clearing shared staging. */
|
|
19
|
+
export function openSource(
|
|
20
|
+
store: Readonly<HistoryStore>,
|
|
21
|
+
id: string,
|
|
22
|
+
): { readonly fd: number; readonly initial: fs.BigIntStats; readonly source: SourceRow } {
|
|
23
|
+
store.beginIngest();
|
|
24
|
+
let fd: number | undefined;
|
|
25
|
+
try {
|
|
26
|
+
let source = requireSource(store, id);
|
|
27
|
+
store.count("sourceChecks");
|
|
28
|
+
store.count("sourceOpens");
|
|
29
|
+
fd = fs.openSync(source.path, "r");
|
|
30
|
+
const initial = fs.fstatSync(fd, { bigint: true });
|
|
31
|
+
if (!initial.isFile() || initial.size > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
32
|
+
throw new Error("Journal is not a supported regular file.");
|
|
33
|
+
}
|
|
34
|
+
if (
|
|
35
|
+
source.identity !== null &&
|
|
36
|
+
(source.identity !== identity(initial) || Number(initial.size) < source.cursor)
|
|
37
|
+
) {
|
|
38
|
+
store.resetSource(id);
|
|
39
|
+
source = requireSource(store, id);
|
|
40
|
+
}
|
|
41
|
+
store.clearUnpublished(id);
|
|
42
|
+
store.run("DELETE FROM pending_text");
|
|
43
|
+
return { fd, initial, source };
|
|
44
|
+
} catch (error) {
|
|
45
|
+
if (fd !== undefined) {
|
|
46
|
+
fs.closeSync(fd);
|
|
47
|
+
}
|
|
48
|
+
store.endIngest();
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
}
|