muonroi-cli 1.8.3 → 1.8.5
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 -21
- package/README.md +133 -122
- package/dist/packages/agent-harness-core/src/driver.d.ts +27 -1
- package/dist/packages/agent-harness-core/src/driver.js +46 -0
- package/dist/packages/agent-harness-core/src/event-tee.d.ts +48 -0
- package/dist/packages/agent-harness-core/src/event-tee.js +77 -0
- package/dist/packages/agent-harness-core/src/mcp-server.d.ts +11 -0
- package/dist/packages/agent-harness-core/src/mcp-server.js +87 -15
- package/dist/packages/agent-harness-core/src/protocol.d.ts +66 -2
- package/dist/packages/agent-harness-core/src/protocol.js +15 -0
- package/dist/packages/agent-harness-core/src/visual-quality.d.ts +58 -0
- package/dist/packages/agent-harness-core/src/visual-quality.js +141 -0
- package/dist/packages/agent-harness-opentui/src/agent-mode.d.ts +6 -0
- package/dist/packages/agent-harness-opentui/src/agent-mode.js +14 -1
- package/dist/packages/agent-harness-opentui/src/input-bridge.d.ts +2 -10
- package/dist/packages/agent-harness-opentui/src/input-bridge.js +103 -16
- package/dist/packages/agent-harness-opentui/src/install.d.ts +8 -0
- package/dist/packages/agent-harness-opentui/src/install.js +10 -0
- package/dist/packages/agent-harness-opentui/src/semantic.js +12 -10
- package/dist/packages/agent-harness-opentui/src/visual-capture.d.ts +56 -0
- package/dist/packages/agent-harness-opentui/src/visual-capture.js +103 -0
- package/dist/src/agent-harness/mock-model.d.ts +28 -0
- package/dist/src/agent-harness/mock-model.js +63 -1
- package/dist/src/agent-harness/test-spawn.js +31 -0
- package/dist/src/cli/config/screen-providers.js +1 -1
- package/dist/src/cli/cost-forensics.d.ts +10 -0
- package/dist/src/cli/cost-forensics.js +30 -15
- package/dist/src/cli/keys-bundle.d.ts +1 -1
- package/dist/src/cli/keys-bundle.js +1 -1
- package/dist/src/cli/keys.d.ts +2 -2
- package/dist/src/cli/keys.js +19 -81
- package/dist/src/council/clarifier.d.ts +28 -2
- package/dist/src/council/clarifier.js +81 -15
- package/dist/src/council/context.js +49 -15
- package/dist/src/council/debate-checkpoint.d.ts +129 -0
- package/dist/src/council/debate-checkpoint.js +176 -0
- package/dist/src/council/debate-planner.js +51 -3
- package/dist/src/council/debate-summary.d.ts +25 -0
- package/dist/src/council/debate-summary.js +85 -0
- package/dist/src/council/debate.d.ts +169 -2
- package/dist/src/council/debate.js +1210 -134
- package/dist/src/council/index.d.ts +85 -1
- package/dist/src/council/index.js +634 -196
- package/dist/src/council/leader.d.ts +26 -0
- package/dist/src/council/leader.js +150 -9
- package/dist/src/council/llm.d.ts +32 -0
- package/dist/src/council/llm.js +231 -38
- package/dist/src/council/panel-select.d.ts +30 -0
- package/dist/src/council/panel-select.js +72 -0
- package/dist/src/council/planner.js +23 -0
- package/dist/src/council/preflight.d.ts +7 -0
- package/dist/src/council/preflight.js +14 -2
- package/dist/src/council/prompts.d.ts +30 -3
- package/dist/src/council/prompts.js +254 -84
- package/dist/src/council/stance-recall.d.ts +42 -0
- package/dist/src/council/stance-recall.js +57 -0
- package/dist/src/council/strip-think.d.ts +17 -0
- package/dist/src/council/strip-think.js +33 -0
- package/dist/src/council/types.d.ts +128 -0
- package/dist/src/ee/artifact-cache.d.ts +16 -0
- package/dist/src/ee/artifact-cache.js +32 -0
- package/dist/src/ee/auth.d.ts +1 -0
- package/dist/src/ee/auth.js +15 -2
- package/dist/src/ee/bridge.d.ts +10 -0
- package/dist/src/ee/bridge.js +58 -0
- package/dist/src/ee/client.js +81 -18
- package/dist/src/ee/export-transcripts.d.ts +1 -0
- package/dist/src/ee/export-transcripts.js +8 -10
- package/dist/src/ee/extract-session.js +29 -0
- package/dist/src/ee/extract-style.d.ts +58 -0
- package/dist/src/ee/extract-style.js +270 -0
- package/dist/src/ee/recall-ledger.d.ts +9 -0
- package/dist/src/ee/recall-ledger.js +3 -0
- package/dist/src/ee/scope.d.ts +1 -0
- package/dist/src/ee/scope.js +26 -1
- package/dist/src/ee/search.d.ts +7 -0
- package/dist/src/ee/search.js +24 -0
- package/dist/src/ee/transcript-emit.js +2 -0
- package/dist/src/ee/types.d.ts +22 -0
- package/dist/src/ee/who-am-i-brain.d.ts +35 -0
- package/dist/src/ee/who-am-i-brain.js +220 -0
- package/dist/src/ee/who-am-i.d.ts +10 -3
- package/dist/src/ee/who-am-i.js +12 -0
- package/dist/src/ee/workflow-event.d.ts +48 -0
- package/dist/src/ee/workflow-event.js +81 -0
- package/dist/src/flow/compaction/compress.d.ts +3 -3
- package/dist/src/flow/compaction/compress.js +45 -8
- package/dist/src/flow/compaction/extract.d.ts +4 -7
- package/dist/src/flow/compaction/extract.js +50 -10
- package/dist/src/flow/compaction/index.d.ts +13 -1
- package/dist/src/flow/compaction/index.js +70 -3
- package/dist/src/flow/compaction/input-guard.d.ts +24 -0
- package/dist/src/flow/compaction/input-guard.js +43 -0
- package/dist/src/flow/fold-planning.d.ts +36 -0
- package/dist/src/flow/fold-planning.js +83 -0
- package/dist/src/flow/hierarchy.d.ts +146 -0
- package/dist/src/flow/hierarchy.js +427 -0
- package/dist/src/flow/index.d.ts +1 -0
- package/dist/src/flow/index.js +2 -0
- package/dist/src/flow/run-artifacts.d.ts +102 -0
- package/dist/src/flow/run-artifacts.js +208 -0
- package/dist/src/generated/version.d.ts +1 -1
- package/dist/src/generated/version.js +1 -1
- package/dist/src/gsd/assessment-schema.d.ts +44 -0
- package/dist/src/gsd/assessment-schema.js +134 -0
- package/dist/src/gsd/capability-registry.d.ts +45 -0
- package/dist/src/gsd/capability-registry.js +337 -0
- package/dist/src/gsd/complexity-assessor.d.ts +39 -0
- package/dist/src/gsd/complexity-assessor.js +152 -0
- package/dist/src/gsd/config-bridge.d.ts +7 -0
- package/dist/src/gsd/config-bridge.js +114 -0
- package/dist/src/gsd/config-loader.d.ts +27 -0
- package/dist/src/gsd/config-loader.js +50 -0
- package/dist/src/gsd/council-context.d.ts +44 -0
- package/dist/src/gsd/council-context.js +114 -0
- package/dist/src/gsd/ee-closure.d.ts +28 -0
- package/dist/src/gsd/ee-closure.js +49 -0
- package/dist/src/gsd/flags.d.ts +55 -0
- package/dist/src/gsd/flags.js +83 -0
- package/dist/src/gsd/gsd-dispatch.d.ts +58 -0
- package/dist/src/gsd/gsd-dispatch.js +131 -0
- package/dist/src/gsd/gsd-runtime.d.ts +22 -0
- package/dist/src/gsd/gsd-runtime.js +37 -0
- package/dist/src/gsd/host-adapter.d.ts +11 -0
- package/dist/src/gsd/host-adapter.js +29 -0
- package/dist/src/gsd/index.d.ts +24 -1
- package/dist/src/gsd/index.js +27 -0
- package/dist/src/gsd/loop-host-contract.d.ts +21 -0
- package/dist/src/gsd/loop-host-contract.js +39 -0
- package/dist/src/gsd/loop-host.d.ts +69 -0
- package/dist/src/gsd/loop-host.js +245 -0
- package/dist/src/gsd/loop-resolver.d.ts +36 -0
- package/dist/src/gsd/loop-resolver.js +79 -0
- package/dist/src/gsd/model-tier.d.ts +13 -0
- package/dist/src/gsd/model-tier.js +45 -0
- package/dist/src/gsd/mutation-gate.d.ts +16 -0
- package/dist/src/gsd/mutation-gate.js +41 -0
- package/dist/src/gsd/native-roadmap.d.ts +89 -0
- package/dist/src/gsd/native-roadmap.js +343 -0
- package/dist/src/gsd/native-state.d.ts +47 -0
- package/dist/src/gsd/native-state.js +220 -0
- package/dist/src/gsd/paths.d.ts +23 -0
- package/dist/src/gsd/paths.js +66 -0
- package/dist/src/gsd/phase-dag.d.ts +12 -0
- package/dist/src/gsd/phase-dag.js +94 -0
- package/dist/src/gsd/phase-sync.d.ts +42 -0
- package/dist/src/gsd/phase-sync.js +321 -0
- package/dist/src/gsd/pil-gate-context.d.ts +13 -0
- package/dist/src/gsd/pil-gate-context.js +64 -0
- package/dist/src/gsd/pil-gate-critic.d.ts +19 -0
- package/dist/src/gsd/pil-gate-critic.js +74 -0
- package/dist/src/gsd/plan-council-prompts.d.ts +25 -0
- package/dist/src/gsd/plan-council-prompts.js +79 -0
- package/dist/src/gsd/plan-council.d.ts +44 -0
- package/dist/src/gsd/plan-council.js +251 -0
- package/dist/src/gsd/plan-gate-vocabulary.d.ts +40 -0
- package/dist/src/gsd/plan-gate-vocabulary.js +64 -0
- package/dist/src/gsd/product-workspace.d.ts +13 -0
- package/dist/src/gsd/product-workspace.js +124 -0
- package/dist/src/gsd/ship-bridge.d.ts +25 -0
- package/dist/src/gsd/ship-bridge.js +65 -0
- package/dist/src/gsd/state-document.d.ts +40 -0
- package/dist/src/gsd/state-document.js +163 -0
- package/dist/src/gsd/verdict-schema.d.ts +39 -0
- package/dist/src/gsd/verdict-schema.js +144 -0
- package/dist/src/gsd/verify-context.d.ts +22 -0
- package/dist/src/gsd/verify-context.js +27 -0
- package/dist/src/gsd/verify-council-prompts.d.ts +19 -0
- package/dist/src/gsd/verify-council-prompts.js +85 -0
- package/dist/src/gsd/verify-council.d.ts +25 -0
- package/dist/src/gsd/verify-council.js +119 -0
- package/dist/src/gsd/verify-gate-vocabulary.d.ts +25 -0
- package/dist/src/gsd/verify-gate-vocabulary.js +46 -0
- package/dist/src/gsd/workflow-engine.d.ts +60 -0
- package/dist/src/gsd/workflow-engine.js +207 -0
- package/dist/src/gsd/workflow-tools.d.ts +13 -0
- package/dist/src/gsd/workflow-tools.js +277 -0
- package/dist/src/hooks/index.js +1 -1
- package/dist/src/index.js +44 -11
- package/dist/src/maintain/pr-builder.js +23 -13
- package/dist/src/mcp/auto-setup.js +57 -32
- package/dist/src/mcp/client-pool.js +1 -1
- package/dist/src/mcp/ee-tools.js +1 -0
- package/dist/src/mcp/oauth-callback.js +2 -2
- package/dist/src/mcp/research-onboarding.js +8 -7
- package/dist/src/mcp/runtime.js +34 -2
- package/dist/src/mcp/setup-guide-text.d.ts +1 -1
- package/dist/src/mcp/setup-guide-text.js +77 -76
- package/dist/src/models/catalog-client.d.ts +87 -0
- package/dist/src/models/catalog-client.js +105 -38
- package/dist/src/models/catalog.json +528 -265
- package/dist/src/models/registry.d.ts +22 -7
- package/dist/src/models/registry.js +73 -10
- package/dist/src/ops/doctor.js +8 -8
- package/dist/src/orchestrator/auto-commit.js +1 -1
- package/dist/src/orchestrator/batch-turn-runner.js +2 -2
- package/dist/src/orchestrator/cache-prefix.d.ts +67 -0
- package/dist/src/orchestrator/cache-prefix.js +83 -0
- package/dist/src/orchestrator/compact-request.d.ts +32 -0
- package/dist/src/orchestrator/compact-request.js +41 -0
- package/dist/src/orchestrator/compaction.d.ts +10 -0
- package/dist/src/orchestrator/compaction.js +27 -7
- package/dist/src/orchestrator/council-manager.d.ts +12 -3
- package/dist/src/orchestrator/council-manager.js +65 -24
- package/dist/src/orchestrator/cross-turn-dedup.d.ts +6 -0
- package/dist/src/orchestrator/cross-turn-dedup.js +22 -1
- package/dist/src/orchestrator/error-utils.d.ts +29 -0
- package/dist/src/orchestrator/error-utils.js +132 -24
- package/dist/src/orchestrator/grounding-check.js +39 -1
- package/dist/src/orchestrator/message-processor.js +242 -33
- package/dist/src/orchestrator/orchestrator.d.ts +39 -3
- package/dist/src/orchestrator/orchestrator.js +651 -102
- package/dist/src/orchestrator/preprocessor.js +1 -1
- package/dist/src/orchestrator/proactive-compact-detector.d.ts +26 -0
- package/dist/src/orchestrator/proactive-compact-detector.js +36 -0
- package/dist/src/orchestrator/prompts.js +159 -159
- package/dist/src/orchestrator/reactive-delegation.d.ts +39 -0
- package/dist/src/orchestrator/reactive-delegation.js +59 -0
- package/dist/src/orchestrator/retry-classifier.d.ts +2 -1
- package/dist/src/orchestrator/retry-classifier.js +46 -2
- package/dist/src/orchestrator/safety-intercept.d.ts +45 -0
- package/dist/src/orchestrator/safety-intercept.js +55 -0
- package/dist/src/orchestrator/scope-reminder.js +1 -1
- package/dist/src/orchestrator/session-experience.d.ts +2 -1
- package/dist/src/orchestrator/session-experience.js +2 -1
- package/dist/src/orchestrator/should-run-gate.d.ts +5 -0
- package/dist/src/orchestrator/should-run-gate.js +18 -0
- package/dist/src/orchestrator/stall-watchdog.d.ts +24 -3
- package/dist/src/orchestrator/stall-watchdog.js +47 -13
- package/dist/src/orchestrator/stream-runner.js +62 -29
- package/dist/src/orchestrator/sub-agent-cap.d.ts +13 -1
- package/dist/src/orchestrator/sub-agent-cap.js +16 -1
- package/dist/src/orchestrator/sub-agent-model-tier.d.ts +13 -1
- package/dist/src/orchestrator/sub-agent-model-tier.js +16 -2
- package/dist/src/orchestrator/subagent-compactor.d.ts +53 -1
- package/dist/src/orchestrator/subagent-compactor.js +126 -15
- package/dist/src/orchestrator/tool-engine.d.ts +26 -0
- package/dist/src/orchestrator/tool-engine.js +669 -56
- package/dist/src/orchestrator/tool-limit-auto-recover.d.ts +22 -0
- package/dist/src/orchestrator/tool-limit-auto-recover.js +30 -0
- package/dist/src/orchestrator/turn-runner-deps.d.ts +19 -0
- package/dist/src/orchestrator/turn-watchdog.d.ts +37 -0
- package/dist/src/orchestrator/turn-watchdog.js +55 -0
- package/dist/src/pil/agent-operating-contract.d.ts +1 -1
- package/dist/src/pil/agent-operating-contract.js +1 -1
- package/dist/src/pil/cheap-model-playbook.d.ts +1 -1
- package/dist/src/pil/cheap-model-playbook.js +5 -1
- package/dist/src/pil/cheap-model-workbooks.d.ts +1 -1
- package/dist/src/pil/cheap-model-workbooks.js +1 -1
- package/dist/src/pil/discovery-types.d.ts +1 -0
- package/dist/src/pil/discovery.js +16 -11
- package/dist/src/pil/layer1-intent.d.ts +18 -6
- package/dist/src/pil/layer1-intent.js +66 -757
- package/dist/src/pil/layer15-context-scan.js +15 -1
- package/dist/src/pil/layer2_5-ponytail.js +8 -8
- package/dist/src/pil/layer3-ee-injection.js +23 -8
- package/dist/src/pil/layer4-gsd.js +69 -16
- package/dist/src/pil/layer5-context.js +7 -3
- package/dist/src/pil/layer6-output.d.ts +23 -0
- package/dist/src/pil/layer6-output.js +5 -1
- package/dist/src/pil/llm-classify.d.ts +33 -2
- package/dist/src/pil/llm-classify.js +123 -131
- package/dist/src/pil/native-capabilities-workbook.d.ts +1 -1
- package/dist/src/pil/native-capabilities-workbook.js +1 -0
- package/dist/src/pil/pipeline.js +34 -2
- package/dist/src/pil/response-tools.js +5 -3
- package/dist/src/pil/schema.d.ts +1 -0
- package/dist/src/pil/schema.js +2 -0
- package/dist/src/pil/types.d.ts +18 -0
- package/dist/src/playbook/directives.d.ts +4 -0
- package/dist/src/playbook/directives.js +17 -5
- package/dist/src/product-loop/backlog-builder.d.ts +14 -1
- package/dist/src/product-loop/backlog-builder.js +30 -6
- package/dist/src/product-loop/discovery-context-format.js +3 -1
- package/dist/src/product-loop/discovery-ecosystem.js +4 -1
- package/dist/src/product-loop/discovery-interview.js +32 -3
- package/dist/src/product-loop/discovery-schema.js +5 -1
- package/dist/src/product-loop/done-gate.js +3 -3
- package/dist/src/product-loop/ideal-trace.d.ts +7 -0
- package/dist/src/product-loop/ideal-trace.js +64 -0
- package/dist/src/product-loop/index.d.ts +13 -1
- package/dist/src/product-loop/index.js +333 -52
- package/dist/src/product-loop/loop-driver.d.ts +7 -0
- package/dist/src/product-loop/loop-driver.js +327 -116
- package/dist/src/product-loop/phase-plan.d.ts +5 -0
- package/dist/src/product-loop/phase-plan.js +39 -2
- package/dist/src/product-loop/phase-runner.js +9 -1
- package/dist/src/product-loop/progress-snapshot.js +4 -4
- package/dist/src/product-loop/sprint-runner.d.ts +111 -0
- package/dist/src/product-loop/sprint-runner.js +559 -16
- package/dist/src/product-loop/types.d.ts +36 -5
- package/dist/src/providers/adapter.d.ts +1 -1
- package/dist/src/providers/adapter.js +3 -4
- package/dist/src/providers/auth/browser-flow.d.ts +1 -1
- package/dist/src/providers/auth/browser-flow.js +1 -1
- package/dist/src/providers/auth/openai-oauth.js +1 -1
- package/dist/src/providers/auth/registry.js +0 -34
- package/dist/src/providers/auth/token-store.js +4 -1
- package/dist/src/providers/auth/types.d.ts +1 -1
- package/dist/src/providers/auth/types.js +1 -1
- package/dist/src/providers/capabilities.d.ts +24 -5
- package/dist/src/providers/capabilities.js +42 -24
- package/dist/src/providers/endpoints.d.ts +2 -2
- package/dist/src/providers/endpoints.js +11 -10
- package/dist/src/providers/keychain.d.ts +1 -1
- package/dist/src/providers/keychain.js +7 -9
- package/dist/src/providers/mcp-vision-bridge.js +82 -172
- package/dist/src/providers/openai-compatible.js +8 -1
- package/dist/src/providers/pricing.d.ts +2 -2
- package/dist/src/providers/pricing.js +3 -13
- package/dist/src/providers/runtime.d.ts +27 -2
- package/dist/src/providers/runtime.js +78 -15
- package/dist/src/providers/strategies/base.strategy.d.ts +16 -0
- package/dist/src/providers/strategies/base.strategy.js +24 -1
- package/dist/src/providers/strategies/{siliconflow.strategy.d.ts → opencode-go.strategy.d.ts} +3 -3
- package/dist/src/providers/strategies/opencode-go.strategy.js +83 -0
- package/dist/src/providers/strategies/registry.js +4 -4
- package/dist/src/providers/strategies/thinking-mode.d.ts +109 -0
- package/dist/src/providers/strategies/thinking-mode.js +280 -1
- package/dist/src/providers/strategies/zai.strategy.d.ts +14 -0
- package/dist/src/providers/strategies/zai.strategy.js +44 -0
- package/dist/src/providers/types.d.ts +5 -6
- package/dist/src/providers/types.js +2 -2
- package/dist/src/providers/vision-backend.d.ts +47 -0
- package/dist/src/providers/vision-backend.js +258 -0
- package/dist/src/providers/vision-proxy.d.ts +22 -9
- package/dist/src/providers/vision-proxy.js +63 -132
- package/dist/src/providers/wire-debug.js +95 -0
- package/dist/src/reporter/index.js +1 -1
- package/dist/src/router/decide.d.ts +13 -0
- package/dist/src/router/decide.js +138 -36
- package/dist/src/router/peak-hour.d.ts +38 -0
- package/dist/src/router/peak-hour.js +107 -0
- package/dist/src/router/step-router.js +3 -2
- package/dist/src/router/warm.js +4 -5
- package/dist/src/scaffold/bb-ecosystem-apply.js +47 -47
- package/dist/src/scaffold/bb-quality-gate.js +5 -5
- package/dist/src/scaffold/continuation-prompt.d.ts +11 -0
- package/dist/src/scaffold/continuation-prompt.js +86 -60
- package/dist/src/scaffold/init-new.js +453 -453
- package/dist/src/scaffold/point-to-existing.d.ts +21 -0
- package/dist/src/scaffold/point-to-existing.js +25 -0
- package/dist/src/self-qa/agentic-loop.js +22 -22
- package/dist/src/{ui/state → state}/active-run.d.ts +19 -0
- package/dist/src/{ui/state → state}/active-run.js +21 -0
- package/dist/src/{ui/status-bar/store.d.ts → state/status-bar-store.d.ts} +4 -1
- package/dist/src/{ui/status-bar/store.js → state/status-bar-store.js} +12 -9
- package/dist/src/state/turn-trace.d.ts +43 -0
- package/dist/src/state/turn-trace.js +32 -0
- package/dist/src/storage/db.js +2 -1
- package/dist/src/storage/index.d.ts +1 -1
- package/dist/src/storage/index.js +1 -1
- package/dist/src/storage/interaction-log.d.ts +1 -1
- package/dist/src/storage/interaction-log.js +5 -5
- package/dist/src/storage/migrations.js +196 -126
- package/dist/src/storage/session-experience-store.js +4 -4
- package/dist/src/storage/sessions.d.ts +28 -10
- package/dist/src/storage/sessions.js +112 -55
- package/dist/src/storage/transcript-view.js +1 -1
- package/dist/src/storage/transcript.d.ts +51 -0
- package/dist/src/storage/transcript.js +383 -112
- package/dist/src/storage/usage.js +14 -14
- package/dist/src/storage/workspaces.js +12 -12
- package/dist/src/tools/file.d.ts +15 -0
- package/dist/src/tools/file.js +32 -0
- package/dist/src/tools/native-tools.js +5 -0
- package/dist/src/tools/registry.d.ts +3 -0
- package/dist/src/tools/registry.js +460 -22
- package/dist/src/tools/research.d.ts +29 -0
- package/dist/src/tools/research.js +233 -0
- package/dist/src/types/index.d.ts +118 -3
- package/dist/src/ui/app.js +0 -0
- package/dist/src/ui/cards/product-status-card.js +1 -1
- package/dist/src/ui/components/bubble-body-guard.d.ts +27 -0
- package/dist/src/ui/components/bubble-body-guard.js +50 -0
- package/dist/src/ui/components/context-rail.d.ts +26 -0
- package/dist/src/ui/components/context-rail.js +33 -0
- package/dist/src/ui/components/council-conclusion-card.d.ts +73 -0
- package/dist/src/ui/components/council-conclusion-card.js +420 -0
- package/dist/src/ui/components/council-debate-pill.d.ts +36 -0
- package/dist/src/ui/components/council-debate-pill.js +34 -0
- package/dist/src/ui/components/council-info-card.js +2 -2
- package/dist/src/ui/components/council-leader-bubble.d.ts +10 -3
- package/dist/src/ui/components/council-leader-bubble.js +21 -11
- package/dist/src/ui/components/council-message-bubble.d.ts +15 -2
- package/dist/src/ui/components/council-message-bubble.js +16 -15
- package/dist/src/ui/components/council-phase-timeline.d.ts +9 -1
- package/dist/src/ui/components/council-phase-timeline.js +49 -15
- package/dist/src/ui/components/council-placeholder-bubble.d.ts +16 -9
- package/dist/src/ui/components/council-placeholder-bubble.js +32 -29
- package/dist/src/ui/components/council-question-card.js +12 -12
- package/dist/src/ui/components/council-rail-rounds.d.ts +26 -0
- package/dist/src/ui/components/council-rail-rounds.js +57 -0
- package/dist/src/ui/components/council-round-group.d.ts +38 -0
- package/dist/src/ui/components/council-round-group.js +88 -0
- package/dist/src/ui/components/council-status-list.d.ts +3 -1
- package/dist/src/ui/components/council-status-list.js +36 -24
- package/dist/src/ui/components/council-synthesis-banner.d.ts +7 -2
- package/dist/src/ui/components/council-synthesis-banner.js +20 -5
- package/dist/src/ui/components/halt-recovery-card.js +9 -5
- package/dist/src/ui/components/jump-to-latest-pill.d.ts +11 -0
- package/dist/src/ui/components/jump-to-latest-pill.js +14 -0
- package/dist/src/ui/components/prompt-box.js +18 -16
- package/dist/src/ui/components/session-tree-card.d.ts +14 -0
- package/dist/src/ui/components/session-tree-card.js +46 -0
- package/dist/src/ui/components/slash-inline-menu.d.ts +12 -0
- package/dist/src/ui/components/slash-inline-menu.js +26 -5
- package/dist/src/ui/components/task-list-panel.d.ts +14 -1
- package/dist/src/ui/components/task-list-panel.js +22 -2
- package/dist/src/ui/containers/modals-layer.d.ts +2 -1
- package/dist/src/ui/hooks/use-session-picker.d.ts +3 -3
- package/dist/src/ui/mcp-modal.js +2 -4
- package/dist/src/ui/modals/api-key-modal.js +1 -1
- package/dist/src/ui/modals/connect-modal.js +4 -3
- package/dist/src/ui/modals/session-picker-modal.d.ts +2 -2
- package/dist/src/ui/modals/session-picker-modal.js +3 -5
- package/dist/src/ui/picker-providers.d.ts +1 -1
- package/dist/src/ui/picker-providers.js +1 -1
- package/dist/src/ui/primitives/index.d.ts +1 -0
- package/dist/src/ui/primitives/index.js +2 -0
- package/dist/src/ui/primitives/semantic-primitives.d.ts +76 -0
- package/dist/src/ui/primitives/semantic-primitives.js +81 -0
- package/dist/src/ui/slash/compact.js +5 -7
- package/dist/src/ui/slash/cost.js +1 -1
- package/dist/src/ui/slash/council-inspect.js +4 -4
- package/dist/src/ui/slash/council.js +19 -1
- package/dist/src/ui/slash/debug.d.ts +3 -31
- package/dist/src/ui/slash/debug.js +9 -20
- package/dist/src/ui/slash/ideal.d.ts +6 -2
- package/dist/src/ui/slash/ideal.js +97 -7
- package/dist/src/ui/slash/menu-items.d.ts +7 -0
- package/dist/src/ui/slash/menu-items.js +12 -18
- package/dist/src/ui/slash/registry.d.ts +2 -0
- package/dist/src/ui/slash/registry.js +4 -0
- package/dist/src/ui/status-bar/cache-hit.d.ts +6 -0
- package/dist/src/ui/status-bar/cache-hit.js +9 -0
- package/dist/src/ui/status-bar/index.d.ts +1 -1
- package/dist/src/ui/status-bar/index.js +7 -3
- package/dist/src/ui/status-bar/usd-meter.d.ts +5 -4
- package/dist/src/ui/status-bar/usd-meter.js +6 -4
- package/dist/src/ui/theme.d.ts +1 -0
- package/dist/src/ui/theme.js +2 -0
- package/dist/src/ui/types.d.ts +7 -0
- package/dist/src/ui/use-app-logic.js +0 -0
- package/dist/src/ui/utils/format.d.ts +14 -0
- package/dist/src/ui/utils/format.js +23 -3
- package/dist/src/usage/downgrade.js +2 -2
- package/dist/src/usage/product-ledger.js +2 -2
- package/dist/src/utils/clipboard-image.js +23 -23
- package/dist/src/utils/install-manager.js +14 -11
- package/dist/src/utils/logger.js +2 -2
- package/dist/src/utils/permission-mode.js +5 -3
- package/dist/src/utils/redactor.js +1 -1
- package/dist/src/utils/settings.d.ts +153 -5
- package/dist/src/utils/settings.js +233 -29
- package/dist/src/utils/side-question.js +2 -2
- package/dist/src/utils/skills.js +3 -3
- package/dist/src/utils/visible-retry.d.ts +11 -0
- package/dist/src/utils/visible-retry.js +10 -1
- package/dist/src/verify/entrypoint.d.ts +1 -1
- package/dist/src/verify/entrypoint.js +1 -1
- package/dist/src/verify/recipes.d.ts +13 -0
- package/dist/src/verify/recipes.js +15 -0
- package/package.json +135 -132
- package/dist/src/providers/auth/gcloud.d.ts +0 -28
- package/dist/src/providers/auth/gcloud.js +0 -102
- package/dist/src/providers/auth/gemini-oauth.d.ts +0 -82
- package/dist/src/providers/auth/gemini-oauth.js +0 -472
- package/dist/src/providers/gemini.d.ts +0 -11
- package/dist/src/providers/gemini.js +0 -45
- package/dist/src/providers/siliconflow-sse-repair.d.ts +0 -58
- package/dist/src/providers/siliconflow-sse-repair.js +0 -177
- package/dist/src/providers/strategies/google.strategy.d.ts +0 -22
- package/dist/src/providers/strategies/google.strategy.js +0 -174
- package/dist/src/providers/strategies/siliconflow.strategy.js +0 -29
- package/dist/src/ui/containers/chat-feed.d.ts +0 -40
- package/dist/src/ui/containers/chat-feed.js +0 -66
|
@@ -43,11 +43,11 @@ function isInternalCouncilMarker(content) {
|
|
|
43
43
|
}
|
|
44
44
|
function loadMessageRows(sessionId) {
|
|
45
45
|
const rows = getDatabase()
|
|
46
|
-
.prepare(`
|
|
47
|
-
SELECT session_id, seq, role, message_json, created_at
|
|
48
|
-
FROM messages
|
|
49
|
-
WHERE session_id = ?
|
|
50
|
-
ORDER BY seq ASC
|
|
46
|
+
.prepare(`
|
|
47
|
+
SELECT session_id, seq, role, message_json, created_at
|
|
48
|
+
FROM messages
|
|
49
|
+
WHERE session_id = ?
|
|
50
|
+
ORDER BY seq ASC
|
|
51
51
|
`)
|
|
52
52
|
.all(sessionId);
|
|
53
53
|
for (const row of rows) {
|
|
@@ -67,12 +67,12 @@ function toPersistedCompaction(row) {
|
|
|
67
67
|
}
|
|
68
68
|
export function loadLatestCompaction(sessionId) {
|
|
69
69
|
const row = getDatabase()
|
|
70
|
-
.prepare(`
|
|
71
|
-
SELECT session_id, first_kept_seq, summary, tokens_before, created_at
|
|
72
|
-
FROM compactions
|
|
73
|
-
WHERE session_id = ?
|
|
74
|
-
ORDER BY id DESC
|
|
75
|
-
LIMIT 1
|
|
70
|
+
.prepare(`
|
|
71
|
+
SELECT session_id, first_kept_seq, summary, tokens_before, created_at
|
|
72
|
+
FROM compactions
|
|
73
|
+
WHERE session_id = ?
|
|
74
|
+
ORDER BY id DESC
|
|
75
|
+
LIMIT 1
|
|
76
76
|
`)
|
|
77
77
|
.get(sessionId);
|
|
78
78
|
return toPersistedCompaction(row);
|
|
@@ -99,6 +99,119 @@ export function loadTranscriptState(sessionId) {
|
|
|
99
99
|
export function loadTranscript(sessionId) {
|
|
100
100
|
return loadTranscriptState(sessionId).messages;
|
|
101
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Resume a session together with every session in its conversation tree.
|
|
104
|
+
*
|
|
105
|
+
* When a session has spawned child sessions (silent rotations, sub-agents,
|
|
106
|
+
* sub-sessions), resuming only the parent loses the work that happened in the
|
|
107
|
+
* children. This loader walks up to the root and then down through all
|
|
108
|
+
* descendants, applies each session's own compaction, merges the messages
|
|
109
|
+
* chronologically, and returns them as one flat transcript for the model.
|
|
110
|
+
*
|
|
111
|
+
* Sequence numbers from sessions other than the one being resumed are replaced
|
|
112
|
+
* with `null` so that usage attribution and compaction still belong to the
|
|
113
|
+
* resumed session.
|
|
114
|
+
*/
|
|
115
|
+
export function loadSessionChainTranscriptState(sessionId) {
|
|
116
|
+
const chain = getSessionChain(sessionId);
|
|
117
|
+
if (chain.length <= 1) {
|
|
118
|
+
return loadTranscriptState(sessionId);
|
|
119
|
+
}
|
|
120
|
+
const records = [];
|
|
121
|
+
for (const sid of chain) {
|
|
122
|
+
const rows = loadMessageRows(sid);
|
|
123
|
+
const messages = rows.map((row) => JSON.parse(row.message_json));
|
|
124
|
+
const seqs = rows.map((row) => row.seq);
|
|
125
|
+
const timestamps = rows.map((row) => new Date(row.created_at));
|
|
126
|
+
const effective = buildEffectiveTranscript(messages, seqs, timestamps, loadLatestCompaction(sid));
|
|
127
|
+
for (let i = 0; i < effective.messages.length; i++) {
|
|
128
|
+
records.push({
|
|
129
|
+
sessionId: sid,
|
|
130
|
+
message: effective.messages[i],
|
|
131
|
+
seq: effective.seqs[i],
|
|
132
|
+
timestamp: effective.timestamps[i],
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// getSessionChain already orders sessions by creation time. Preserve each
|
|
137
|
+
// session's internal effective-transcript order (especially compaction
|
|
138
|
+
// summaries, which must precede their kept tail) instead of re-sorting by
|
|
139
|
+
// individual message timestamps.
|
|
140
|
+
return {
|
|
141
|
+
messages: records.map((r) => r.message),
|
|
142
|
+
seqs: records.map((r) => (r.sessionId === sessionId ? r.seq : null)),
|
|
143
|
+
timestamps: records.map((r) => r.timestamp),
|
|
144
|
+
compaction: loadLatestCompaction(sessionId),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Enumerate the full session chain (root + all descendants) with per-session
|
|
149
|
+
* metadata, ordered root-first then by creation time. Read-only; safe to call
|
|
150
|
+
* on every render. Returns a single-node array for a session with no children.
|
|
151
|
+
*/
|
|
152
|
+
export function getSessionChainInfos(sessionId) {
|
|
153
|
+
const chain = getSessionChain(sessionId);
|
|
154
|
+
if (chain.length === 0)
|
|
155
|
+
return [];
|
|
156
|
+
const db = getDatabase();
|
|
157
|
+
const placeholders = chain.map(() => "?").join(",");
|
|
158
|
+
let rows = [];
|
|
159
|
+
try {
|
|
160
|
+
rows = db
|
|
161
|
+
.prepare(`
|
|
162
|
+
SELECT s.id, s.parent_session_id, s.kind, s.model, s.status, s.created_at,
|
|
163
|
+
(SELECT COUNT(*) FROM messages m WHERE m.session_id = s.id) AS msgs
|
|
164
|
+
FROM sessions s
|
|
165
|
+
WHERE s.id IN (${placeholders})
|
|
166
|
+
`)
|
|
167
|
+
.all(...chain);
|
|
168
|
+
}
|
|
169
|
+
catch (err) {
|
|
170
|
+
logger.error("storage", "getSessionChainInfos query failed", {
|
|
171
|
+
sessionId,
|
|
172
|
+
message: err?.message,
|
|
173
|
+
});
|
|
174
|
+
return [];
|
|
175
|
+
}
|
|
176
|
+
const byId = new Map(rows.map((r) => [r.id, r]));
|
|
177
|
+
const depthOf = (id) => {
|
|
178
|
+
let depth = 0;
|
|
179
|
+
let cur = id;
|
|
180
|
+
const seen = new Set();
|
|
181
|
+
while (cur && !seen.has(cur)) {
|
|
182
|
+
seen.add(cur);
|
|
183
|
+
const parent = byId.get(cur)?.parent_session_id ?? null;
|
|
184
|
+
// Only count parents that are inside this chain (the walk-up root has none).
|
|
185
|
+
if (parent && byId.has(parent)) {
|
|
186
|
+
depth++;
|
|
187
|
+
cur = parent;
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return depth;
|
|
194
|
+
};
|
|
195
|
+
const nodes = chain
|
|
196
|
+
.map((id) => byId.get(id))
|
|
197
|
+
.filter((r) => r !== undefined)
|
|
198
|
+
.map((r) => ({
|
|
199
|
+
id: r.id,
|
|
200
|
+
kind: r.kind ?? null,
|
|
201
|
+
model: r.model,
|
|
202
|
+
status: r.status,
|
|
203
|
+
messageCount: r.msgs,
|
|
204
|
+
parentId: r.parent_session_id,
|
|
205
|
+
depth: depthOf(r.id),
|
|
206
|
+
isCurrent: r.id === sessionId,
|
|
207
|
+
}));
|
|
208
|
+
// Render order: shallowest first (root → children → grandchildren) so the rail
|
|
209
|
+
// always shows the parent on top with descendants indented under it. Ties keep
|
|
210
|
+
// getSessionChain's created_at order. A stable index-carrying sort — chain
|
|
211
|
+
// created_at can tie at second granularity, so depth is the deterministic key.
|
|
212
|
+
const chainIndex = new Map(nodes.map((n, i) => [n.id, i]));
|
|
213
|
+
return nodes.sort((a, b) => a.depth - b.depth || chainIndex.get(a.id) - chainIndex.get(b.id));
|
|
214
|
+
}
|
|
102
215
|
export function getNextMessageSequence(sessionId) {
|
|
103
216
|
return getNextSequence(getDatabase(), sessionId);
|
|
104
217
|
}
|
|
@@ -113,43 +226,44 @@ export function appendMessages(sessionId, messages) {
|
|
|
113
226
|
// with `status='completed'` and the full message_json. Pre-A5 callers
|
|
114
227
|
// hit this path identically: there is no pending row so the IGNORE
|
|
115
228
|
// branch is unused and the INSERT wins.
|
|
116
|
-
const insertMessage = db.prepare(`
|
|
117
|
-
INSERT INTO messages (session_id, seq, role, message_json, created_at, status)
|
|
118
|
-
VALUES (?, ?, ?, ?, ?, 'completed')
|
|
119
|
-
ON CONFLICT(session_id, seq) DO UPDATE SET
|
|
120
|
-
role = excluded.role,
|
|
121
|
-
message_json = excluded.message_json,
|
|
122
|
-
status = 'completed'
|
|
229
|
+
const insertMessage = db.prepare(`
|
|
230
|
+
INSERT INTO messages (session_id, seq, role, message_json, created_at, status)
|
|
231
|
+
VALUES (?, ?, ?, ?, ?, 'completed')
|
|
232
|
+
ON CONFLICT(session_id, seq) DO UPDATE SET
|
|
233
|
+
role = excluded.role,
|
|
234
|
+
message_json = excluded.message_json,
|
|
235
|
+
status = 'completed'
|
|
123
236
|
`);
|
|
124
|
-
const insertToolCall = db.prepare(`
|
|
125
|
-
INSERT OR IGNORE INTO tool_calls (
|
|
126
|
-
session_id, message_seq, tool_call_id, tool_name, args_json, status, started_at, completed_at
|
|
127
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
237
|
+
const insertToolCall = db.prepare(`
|
|
238
|
+
INSERT OR IGNORE INTO tool_calls (
|
|
239
|
+
session_id, message_seq, tool_call_id, tool_name, args_json, status, started_at, completed_at
|
|
240
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
128
241
|
`);
|
|
129
|
-
const updateToolCall = db.prepare(`
|
|
130
|
-
UPDATE tool_calls
|
|
131
|
-
SET tool_name = ?, args_json = ?, status = ?, completed_at = ?
|
|
132
|
-
WHERE session_id = ? AND tool_call_id = ?
|
|
242
|
+
const updateToolCall = db.prepare(`
|
|
243
|
+
UPDATE tool_calls
|
|
244
|
+
SET tool_name = ?, args_json = ?, status = ?, completed_at = ?
|
|
245
|
+
WHERE session_id = ? AND tool_call_id = ?
|
|
133
246
|
`);
|
|
134
|
-
const selectToolCall = db.prepare(`
|
|
135
|
-
SELECT id, tool_call_id, tool_name, args_json
|
|
136
|
-
FROM tool_calls
|
|
137
|
-
WHERE session_id = ? AND tool_call_id = ?
|
|
247
|
+
const selectToolCall = db.prepare(`
|
|
248
|
+
SELECT id, tool_call_id, tool_name, args_json
|
|
249
|
+
FROM tool_calls
|
|
250
|
+
WHERE session_id = ? AND tool_call_id = ?
|
|
138
251
|
`);
|
|
139
|
-
const insertToolResult = db.prepare(`
|
|
140
|
-
INSERT INTO tool_results (tool_call_row_id, output_kind, output_json, success, created_at)
|
|
141
|
-
VALUES (?, ?, ?, ?, ?)
|
|
252
|
+
const insertToolResult = db.prepare(`
|
|
253
|
+
INSERT INTO tool_results (tool_call_row_id, output_kind, output_json, success, created_at)
|
|
254
|
+
VALUES (?, ?, ?, ?, ?)
|
|
142
255
|
`);
|
|
143
|
-
const updateSession = db.prepare(`
|
|
144
|
-
UPDATE sessions
|
|
145
|
-
SET updated_at = ?
|
|
146
|
-
WHERE id = ?
|
|
256
|
+
const updateSession = db.prepare(`
|
|
257
|
+
UPDATE sessions
|
|
258
|
+
SET updated_at = ?
|
|
259
|
+
WHERE id = ?
|
|
147
260
|
`);
|
|
148
261
|
messages.forEach((message, index) => {
|
|
149
262
|
const seq = nextSeq + index;
|
|
150
263
|
const createdAt = new Date().toISOString();
|
|
151
264
|
insertedSeqs.push(seq);
|
|
152
265
|
insertMessage.run(sessionId, seq, message.role, JSON.stringify(message), createdAt);
|
|
266
|
+
indexMessageInFts(db, sessionId, seq, message.role, JSON.stringify(message));
|
|
153
267
|
if (message.role === "assistant" && Array.isArray(message.content)) {
|
|
154
268
|
for (const part of message.content) {
|
|
155
269
|
if (part.type !== "tool-call")
|
|
@@ -205,16 +319,20 @@ export function persistToolCallWriteAhead(sessionId, messageSeq, toolCallId, too
|
|
|
205
319
|
const now = new Date().toISOString();
|
|
206
320
|
try {
|
|
207
321
|
getDatabase()
|
|
208
|
-
.prepare(`
|
|
209
|
-
INSERT OR IGNORE INTO tool_calls (
|
|
210
|
-
session_id, message_seq, tool_call_id, tool_name, args_json, status, started_at, completed_at
|
|
211
|
-
) VALUES (?, ?, ?, ?, ?, 'pending', ?, NULL)
|
|
322
|
+
.prepare(`
|
|
323
|
+
INSERT OR IGNORE INTO tool_calls (
|
|
324
|
+
session_id, message_seq, tool_call_id, tool_name, args_json, status, started_at, completed_at
|
|
325
|
+
) VALUES (?, ?, ?, ?, ?, 'pending', ?, NULL)
|
|
212
326
|
`)
|
|
213
327
|
.run(sessionId, messageSeq, toolCallId, toolName, argsJson, now);
|
|
214
328
|
}
|
|
215
|
-
catch {
|
|
216
|
-
|
|
217
|
-
|
|
329
|
+
catch (err) {
|
|
330
|
+
logger.error("storage", `[transcript] persistToolCallWriteAhead failed: ${err.message}`, {
|
|
331
|
+
sessionId,
|
|
332
|
+
messageSeq,
|
|
333
|
+
toolCallId,
|
|
334
|
+
toolName,
|
|
335
|
+
});
|
|
218
336
|
}
|
|
219
337
|
}
|
|
220
338
|
/**
|
|
@@ -253,16 +371,20 @@ export function persistToolCallWriteAhead(sessionId, messageSeq, toolCallId, too
|
|
|
253
371
|
export function persistMessageWriteAhead(sessionId, seq, role, messageJson) {
|
|
254
372
|
const now = new Date().toISOString();
|
|
255
373
|
try {
|
|
256
|
-
getDatabase()
|
|
257
|
-
|
|
258
|
-
INSERT OR IGNORE INTO messages (
|
|
259
|
-
session_id, seq, role, message_json, created_at, status
|
|
260
|
-
) VALUES (?, ?, ?, ?, ?, 'pending')
|
|
261
|
-
`)
|
|
262
|
-
|
|
374
|
+
const db = getDatabase();
|
|
375
|
+
db.prepare(`
|
|
376
|
+
INSERT OR IGNORE INTO messages (
|
|
377
|
+
session_id, seq, role, message_json, created_at, status
|
|
378
|
+
) VALUES (?, ?, ?, ?, ?, 'pending')
|
|
379
|
+
`).run(sessionId, seq, role, messageJson, now);
|
|
380
|
+
indexMessageInFts(db, sessionId, seq, role, messageJson);
|
|
263
381
|
}
|
|
264
|
-
catch {
|
|
265
|
-
|
|
382
|
+
catch (err) {
|
|
383
|
+
logger.error("storage", `[transcript] persistMessageWriteAhead failed: ${err.message}`, {
|
|
384
|
+
sessionId,
|
|
385
|
+
seq,
|
|
386
|
+
role,
|
|
387
|
+
});
|
|
266
388
|
}
|
|
267
389
|
}
|
|
268
390
|
/**
|
|
@@ -275,15 +397,15 @@ export function persistMessageWriteAhead(sessionId, seq, role, messageJson) {
|
|
|
275
397
|
export function markMessageCompleted(sessionId, seq) {
|
|
276
398
|
try {
|
|
277
399
|
getDatabase()
|
|
278
|
-
.prepare(`
|
|
279
|
-
UPDATE messages
|
|
280
|
-
SET status = 'completed'
|
|
281
|
-
WHERE session_id = ? AND seq = ? AND status = 'pending'
|
|
400
|
+
.prepare(`
|
|
401
|
+
UPDATE messages
|
|
402
|
+
SET status = 'completed'
|
|
403
|
+
WHERE session_id = ? AND seq = ? AND status = 'pending'
|
|
282
404
|
`)
|
|
283
405
|
.run(sessionId, seq);
|
|
284
406
|
}
|
|
285
|
-
catch {
|
|
286
|
-
|
|
407
|
+
catch (err) {
|
|
408
|
+
logger.error("storage", `[transcript] markMessageCompleted failed: ${err.message}`, { sessionId, seq });
|
|
287
409
|
}
|
|
288
410
|
}
|
|
289
411
|
/**
|
|
@@ -297,15 +419,15 @@ export function markMessageCompleted(sessionId, seq) {
|
|
|
297
419
|
export function markMessageErrored(sessionId, seq) {
|
|
298
420
|
try {
|
|
299
421
|
getDatabase()
|
|
300
|
-
.prepare(`
|
|
301
|
-
UPDATE messages
|
|
302
|
-
SET status = 'errored'
|
|
303
|
-
WHERE session_id = ? AND seq = ? AND status = 'pending'
|
|
422
|
+
.prepare(`
|
|
423
|
+
UPDATE messages
|
|
424
|
+
SET status = 'errored'
|
|
425
|
+
WHERE session_id = ? AND seq = ? AND status = 'pending'
|
|
304
426
|
`)
|
|
305
427
|
.run(sessionId, seq);
|
|
306
428
|
}
|
|
307
|
-
catch {
|
|
308
|
-
|
|
429
|
+
catch (err) {
|
|
430
|
+
logger.error("storage", `[transcript] markMessageErrored failed: ${err.message}`, { sessionId, seq });
|
|
309
431
|
}
|
|
310
432
|
}
|
|
311
433
|
/**
|
|
@@ -331,17 +453,17 @@ export function sweepStalePendingRows(staleAfterMs = 5 * 60 * 1000) {
|
|
|
331
453
|
try {
|
|
332
454
|
const db = getDatabase();
|
|
333
455
|
const toolCalls = db
|
|
334
|
-
.prepare(`
|
|
335
|
-
UPDATE tool_calls
|
|
336
|
-
SET status = 'aborted', completed_at = started_at
|
|
337
|
-
WHERE status = 'pending' AND started_at < ?
|
|
456
|
+
.prepare(`
|
|
457
|
+
UPDATE tool_calls
|
|
458
|
+
SET status = 'aborted', completed_at = started_at
|
|
459
|
+
WHERE status = 'pending' AND started_at < ?
|
|
338
460
|
`)
|
|
339
461
|
.run(cutoff);
|
|
340
462
|
const messages = db
|
|
341
|
-
.prepare(`
|
|
342
|
-
UPDATE messages
|
|
343
|
-
SET status = 'aborted'
|
|
344
|
-
WHERE status = 'pending' AND created_at < ?
|
|
463
|
+
.prepare(`
|
|
464
|
+
UPDATE messages
|
|
465
|
+
SET status = 'aborted'
|
|
466
|
+
WHERE status = 'pending' AND created_at < ?
|
|
345
467
|
`)
|
|
346
468
|
.run(cutoff);
|
|
347
469
|
return { toolCalls: toolCalls.changes, messages: messages.changes };
|
|
@@ -355,10 +477,10 @@ export function markToolCallErrored(sessionId, toolCallId, errorMessage) {
|
|
|
355
477
|
const now = new Date().toISOString();
|
|
356
478
|
try {
|
|
357
479
|
getDatabase()
|
|
358
|
-
.prepare(`
|
|
359
|
-
UPDATE tool_calls
|
|
360
|
-
SET status = 'errored', completed_at = ?, args_json = COALESCE(args_json, ?)
|
|
361
|
-
WHERE session_id = ? AND tool_call_id = ?
|
|
480
|
+
.prepare(`
|
|
481
|
+
UPDATE tool_calls
|
|
482
|
+
SET status = 'errored', completed_at = ?, args_json = COALESCE(args_json, ?)
|
|
483
|
+
WHERE session_id = ? AND tool_call_id = ?
|
|
362
484
|
`)
|
|
363
485
|
.run(now, JSON.stringify({ error: errorMessage.slice(0, 500) }), sessionId, toolCallId);
|
|
364
486
|
}
|
|
@@ -368,28 +490,28 @@ export function markToolCallErrored(sessionId, toolCallId, errorMessage) {
|
|
|
368
490
|
}
|
|
369
491
|
export function appendCompaction(sessionId, firstKeptSeq, summary, tokensBefore) {
|
|
370
492
|
withTransaction((db) => {
|
|
371
|
-
db.prepare(`
|
|
372
|
-
INSERT INTO compactions (session_id, first_kept_seq, summary, tokens_before, created_at)
|
|
373
|
-
VALUES (?, ?, ?, ?, ?)
|
|
493
|
+
db.prepare(`
|
|
494
|
+
INSERT INTO compactions (session_id, first_kept_seq, summary, tokens_before, created_at)
|
|
495
|
+
VALUES (?, ?, ?, ?, ?)
|
|
374
496
|
`).run(sessionId, firstKeptSeq, summary, tokensBefore, new Date().toISOString());
|
|
375
|
-
db.prepare(`
|
|
376
|
-
UPDATE sessions
|
|
377
|
-
SET updated_at = ?
|
|
378
|
-
WHERE id = ?
|
|
497
|
+
db.prepare(`
|
|
498
|
+
UPDATE sessions
|
|
499
|
+
SET updated_at = ?
|
|
500
|
+
WHERE id = ?
|
|
379
501
|
`).run(new Date().toISOString(), sessionId);
|
|
380
502
|
});
|
|
381
503
|
}
|
|
382
504
|
export function revertLatestCompaction(sessionId) {
|
|
383
505
|
withTransaction((db) => {
|
|
384
|
-
db.prepare(`
|
|
385
|
-
DELETE FROM compactions
|
|
386
|
-
WHERE session_id = ?
|
|
387
|
-
AND id = (SELECT MAX(id) FROM compactions WHERE session_id = ?)
|
|
506
|
+
db.prepare(`
|
|
507
|
+
DELETE FROM compactions
|
|
508
|
+
WHERE session_id = ?
|
|
509
|
+
AND id = (SELECT MAX(id) FROM compactions WHERE session_id = ?)
|
|
388
510
|
`).run(sessionId, sessionId);
|
|
389
|
-
db.prepare(`
|
|
390
|
-
UPDATE sessions
|
|
391
|
-
SET updated_at = ?
|
|
392
|
-
WHERE id = ?
|
|
511
|
+
db.prepare(`
|
|
512
|
+
UPDATE sessions
|
|
513
|
+
SET updated_at = ?
|
|
514
|
+
WHERE id = ?
|
|
393
515
|
`).run(new Date().toISOString(), sessionId);
|
|
394
516
|
});
|
|
395
517
|
}
|
|
@@ -439,10 +561,10 @@ export function getSessionChain(sessionId) {
|
|
|
439
561
|
.map(() => "?")
|
|
440
562
|
.join(",");
|
|
441
563
|
const sortedRows = db
|
|
442
|
-
.prepare(`
|
|
443
|
-
SELECT id FROM sessions
|
|
444
|
-
WHERE id IN (${placeholders})
|
|
445
|
-
ORDER BY created_at ASC
|
|
564
|
+
.prepare(`
|
|
565
|
+
SELECT id FROM sessions
|
|
566
|
+
WHERE id IN (${placeholders})
|
|
567
|
+
ORDER BY created_at ASC
|
|
446
568
|
`)
|
|
447
569
|
.all(...Array.from(allIds));
|
|
448
570
|
chain = sortedRows.map((r) => r.id);
|
|
@@ -624,10 +746,10 @@ export function buildChatEntries(sessionId) {
|
|
|
624
746
|
}
|
|
625
747
|
function getNextSequence(db, sessionId) {
|
|
626
748
|
const row = db
|
|
627
|
-
.prepare(`
|
|
628
|
-
SELECT COALESCE(MAX(seq), 0) AS max_seq
|
|
629
|
-
FROM messages
|
|
630
|
-
WHERE session_id = ?
|
|
749
|
+
.prepare(`
|
|
750
|
+
SELECT COALESCE(MAX(seq), 0) AS max_seq
|
|
751
|
+
FROM messages
|
|
752
|
+
WHERE session_id = ?
|
|
631
753
|
`)
|
|
632
754
|
.get(sessionId);
|
|
633
755
|
return (row?.max_seq ?? 0) + 1;
|
|
@@ -677,12 +799,12 @@ function renderAssistantContent(content, callMap) {
|
|
|
677
799
|
}
|
|
678
800
|
function loadStoredToolResults(sessionId) {
|
|
679
801
|
const rows = getDatabase()
|
|
680
|
-
.prepare(`
|
|
681
|
-
SELECT tc.tool_call_id, tr.output_json
|
|
682
|
-
FROM tool_results tr
|
|
683
|
-
JOIN tool_calls tc ON tc.id = tr.tool_call_row_id
|
|
684
|
-
WHERE tc.session_id = ?
|
|
685
|
-
ORDER BY tr.id ASC
|
|
802
|
+
.prepare(`
|
|
803
|
+
SELECT tc.tool_call_id, tr.output_json
|
|
804
|
+
FROM tool_results tr
|
|
805
|
+
JOIN tool_calls tc ON tc.id = tr.tool_call_row_id
|
|
806
|
+
WHERE tc.session_id = ?
|
|
807
|
+
ORDER BY tr.id ASC
|
|
686
808
|
`)
|
|
687
809
|
.all(sessionId);
|
|
688
810
|
return new Map(rows.map((row) => [row.tool_call_id, JSON.parse(row.output_json)]));
|
|
@@ -703,12 +825,12 @@ export function getLastTodoWriteArgs(sessionId) {
|
|
|
703
825
|
for (let i = chain.length - 1; i >= 0; i--) {
|
|
704
826
|
try {
|
|
705
827
|
const row = db
|
|
706
|
-
.prepare(`
|
|
707
|
-
SELECT args_json
|
|
708
|
-
FROM tool_calls
|
|
709
|
-
WHERE session_id = ? AND tool_name = 'todo_write'
|
|
710
|
-
ORDER BY id DESC
|
|
711
|
-
LIMIT 1
|
|
828
|
+
.prepare(`
|
|
829
|
+
SELECT args_json
|
|
830
|
+
FROM tool_calls
|
|
831
|
+
WHERE session_id = ? AND tool_name = 'todo_write'
|
|
832
|
+
ORDER BY id DESC
|
|
833
|
+
LIMIT 1
|
|
712
834
|
`)
|
|
713
835
|
.get(chain[i]);
|
|
714
836
|
if (row?.args_json) {
|
|
@@ -721,4 +843,153 @@ export function getLastTodoWriteArgs(sessionId) {
|
|
|
721
843
|
}
|
|
722
844
|
return null;
|
|
723
845
|
}
|
|
846
|
+
/**
|
|
847
|
+
* Persist the approved plan text for a session so that "tiếp tục"/"continue"
|
|
848
|
+
* turns (which are classified as chitchat/general by PIL Pass 0) can re-inject
|
|
849
|
+
* the APPROVED PLAN section into the system prompt instead of forgetting context.
|
|
850
|
+
*
|
|
851
|
+
* Stored as a synthetic tool_call row (tool_name='__approved_plan') so we reuse
|
|
852
|
+
* the existing schema and getLast* query pattern without a new table/migration.
|
|
853
|
+
* The planText is stored verbatim in args_json.
|
|
854
|
+
*/
|
|
855
|
+
export function persistApprovedPlan(sessionId, planText) {
|
|
856
|
+
if (!sessionId || !planText)
|
|
857
|
+
return;
|
|
858
|
+
const db = getDatabase();
|
|
859
|
+
const toolCallId = `approved-plan-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
860
|
+
const now = new Date().toISOString();
|
|
861
|
+
try {
|
|
862
|
+
db.prepare(`
|
|
863
|
+
INSERT OR REPLACE INTO tool_calls (session_id, message_seq, tool_call_id, tool_name, args_json, status, started_at, completed_at)
|
|
864
|
+
VALUES (?, 0, ?, '__approved_plan', ?, 'completed', ?, ?)
|
|
865
|
+
`).run(sessionId, toolCallId, planText, now, now);
|
|
866
|
+
}
|
|
867
|
+
catch {
|
|
868
|
+
/* best-effort persistence; never block the turn */
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
/** Load the most recent persisted approved plan for this session (or parent chain). */
|
|
872
|
+
export function getLastApprovedPlan(sessionId) {
|
|
873
|
+
const chain = getSessionChain(sessionId);
|
|
874
|
+
const db = getDatabase();
|
|
875
|
+
for (let i = chain.length - 1; i >= 0; i--) {
|
|
876
|
+
try {
|
|
877
|
+
// 1) Prefer our synthetic persisted row (written by setPlanContext + persistApprovedPlan).
|
|
878
|
+
const synthetic = db
|
|
879
|
+
.prepare(`
|
|
880
|
+
SELECT args_json
|
|
881
|
+
FROM tool_calls
|
|
882
|
+
WHERE session_id = ? AND tool_name = '__approved_plan'
|
|
883
|
+
ORDER BY id DESC
|
|
884
|
+
LIMIT 1
|
|
885
|
+
`)
|
|
886
|
+
.get(chain[i]);
|
|
887
|
+
if (synthetic?.args_json) {
|
|
888
|
+
return synthetic.args_json;
|
|
889
|
+
}
|
|
890
|
+
// 2) Fallback: scan real plan tool_calls (respond_plan / generate_plan) written by
|
|
891
|
+
// council, PIL response-tools, or generate_plan UI. Extract a human-readable slice.
|
|
892
|
+
const planRow = db
|
|
893
|
+
.prepare(`
|
|
894
|
+
SELECT args_json, tool_name
|
|
895
|
+
FROM tool_calls
|
|
896
|
+
WHERE session_id = ? AND tool_name IN ('respond_plan', 'generate_plan')
|
|
897
|
+
ORDER BY id DESC
|
|
898
|
+
LIMIT 1
|
|
899
|
+
`)
|
|
900
|
+
.get(chain[i]);
|
|
901
|
+
if (planRow?.args_json) {
|
|
902
|
+
try {
|
|
903
|
+
const parsed = JSON.parse(planRow.args_json);
|
|
904
|
+
// respond_plan shape typically has { steps, assumptions?, risks? } or { plan: {...} }
|
|
905
|
+
const candidate = parsed?.plan ?? parsed;
|
|
906
|
+
if (candidate && (Array.isArray(candidate.steps) || typeof candidate === "object")) {
|
|
907
|
+
return JSON.stringify(candidate, null, 2);
|
|
908
|
+
}
|
|
909
|
+
// generate_plan may carry raw text or { content, steps }
|
|
910
|
+
if (typeof parsed === "string")
|
|
911
|
+
return parsed;
|
|
912
|
+
if (parsed && typeof parsed === "object")
|
|
913
|
+
return JSON.stringify(parsed, null, 2);
|
|
914
|
+
}
|
|
915
|
+
catch {
|
|
916
|
+
// not JSON — return as-is (may be a raw string payload)
|
|
917
|
+
if (typeof planRow.args_json === "string" && planRow.args_json.trim().length > 0) {
|
|
918
|
+
return planRow.args_json;
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
catch {
|
|
924
|
+
// ignore and check parent
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
return null;
|
|
928
|
+
}
|
|
929
|
+
function indexMessageInFts(db, sessionId, seq, role, messageJsonStr) {
|
|
930
|
+
db.prepare(`DELETE FROM session_history_fts WHERE session_id = ? AND seq = ?`).run(sessionId, seq);
|
|
931
|
+
let message;
|
|
932
|
+
try {
|
|
933
|
+
message = JSON.parse(messageJsonStr);
|
|
934
|
+
}
|
|
935
|
+
catch (err) {
|
|
936
|
+
logger.error("storage", `[transcript] Failed to parse message JSON for FTS indexing: ${err.message}`, {
|
|
937
|
+
sessionId,
|
|
938
|
+
seq,
|
|
939
|
+
role,
|
|
940
|
+
});
|
|
941
|
+
return;
|
|
942
|
+
}
|
|
943
|
+
let content = "";
|
|
944
|
+
let toolName = "";
|
|
945
|
+
let toolArgs = "";
|
|
946
|
+
let toolOutput = "";
|
|
947
|
+
const msgContent = message.content;
|
|
948
|
+
if (typeof msgContent === "string") {
|
|
949
|
+
content = msgContent;
|
|
950
|
+
}
|
|
951
|
+
else if (Array.isArray(msgContent)) {
|
|
952
|
+
const textParts = [];
|
|
953
|
+
const toolNames = [];
|
|
954
|
+
const argParts = [];
|
|
955
|
+
const outputParts = [];
|
|
956
|
+
for (const part of msgContent) {
|
|
957
|
+
if (part && typeof part === "object") {
|
|
958
|
+
if (part.type === "text" && typeof part.text === "string") {
|
|
959
|
+
textParts.push(part.text);
|
|
960
|
+
}
|
|
961
|
+
else if (part.type === "tool-call" && typeof part.toolName === "string") {
|
|
962
|
+
toolNames.push(part.toolName);
|
|
963
|
+
if (part.input !== undefined) {
|
|
964
|
+
argParts.push(typeof part.input === "string" ? part.input : JSON.stringify(part.input));
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
else if (part.type === "tool-result" && typeof part.toolName === "string") {
|
|
968
|
+
toolNames.push(part.toolName);
|
|
969
|
+
if (part.output !== undefined) {
|
|
970
|
+
outputParts.push(typeof part.output === "string" ? part.output : JSON.stringify(part.output));
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
content = textParts.join("\n").trim();
|
|
976
|
+
toolName = toolNames.join(", ").trim();
|
|
977
|
+
toolArgs = argParts.join("\n").trim();
|
|
978
|
+
toolOutput = outputParts.join("\n").trim();
|
|
979
|
+
}
|
|
980
|
+
try {
|
|
981
|
+
db.prepare(`
|
|
982
|
+
INSERT INTO session_history_fts (session_id, seq, role, tool_name, content, tool_args, tool_output)
|
|
983
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
984
|
+
`).run(sessionId, seq, role, toolName || null, content || null, toolArgs || null, toolOutput || null);
|
|
985
|
+
}
|
|
986
|
+
catch (err) {
|
|
987
|
+
logger.error("storage", `[transcript] Failed to execute FTS indexing query: ${err.message}`, {
|
|
988
|
+
sessionId,
|
|
989
|
+
seq,
|
|
990
|
+
role,
|
|
991
|
+
});
|
|
992
|
+
throw err;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
724
995
|
//# sourceMappingURL=transcript.js.map
|
|
@@ -14,11 +14,11 @@ export function recordUsageEvent(sessionId, source, model, usage, messageSeq, pi
|
|
|
14
14
|
const cacheCreationTokens = usage.cacheCreationTokens ?? 0;
|
|
15
15
|
const costMicros = estimateCostMicros(model, inputTokens, outputTokens, cacheReadTokens);
|
|
16
16
|
getDatabase()
|
|
17
|
-
.prepare(`
|
|
18
|
-
INSERT INTO usage_events (
|
|
19
|
-
session_id, message_seq, source, model, input_tokens, output_tokens, total_tokens, cost_micros, created_at,
|
|
20
|
-
pil_active, enrichment_delta, cache_read_tokens, cache_creation_tokens, provider_options_shape
|
|
21
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
17
|
+
.prepare(`
|
|
18
|
+
INSERT INTO usage_events (
|
|
19
|
+
session_id, message_seq, source, model, input_tokens, output_tokens, total_tokens, cost_micros, created_at,
|
|
20
|
+
pil_active, enrichment_delta, cache_read_tokens, cache_creation_tokens, provider_options_shape
|
|
21
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
22
22
|
`)
|
|
23
23
|
.run(sessionId, messageSeq ?? null, source, model, inputTokens, outputTokens, totalTokens, costMicros, new Date().toISOString(), pilActive ? 1 : 0, enrichmentDelta, cacheReadTokens, cacheCreationTokens, providerOptionsShape);
|
|
24
24
|
}
|
|
@@ -26,10 +26,10 @@ export function getSessionTotalTokens(sessionId) {
|
|
|
26
26
|
const chain = getSessionChain(sessionId);
|
|
27
27
|
const placeholders = chain.map(() => "?").join(",");
|
|
28
28
|
const row = getDatabase()
|
|
29
|
-
.prepare(`
|
|
30
|
-
SELECT COALESCE(SUM(total_tokens), 0) AS total_tokens
|
|
31
|
-
FROM usage_events
|
|
32
|
-
WHERE session_id IN (${placeholders})
|
|
29
|
+
.prepare(`
|
|
30
|
+
SELECT COALESCE(SUM(total_tokens), 0) AS total_tokens
|
|
31
|
+
FROM usage_events
|
|
32
|
+
WHERE session_id IN (${placeholders})
|
|
33
33
|
`)
|
|
34
34
|
.get(...chain);
|
|
35
35
|
const total = row?.total_tokens ?? 0;
|
|
@@ -44,11 +44,11 @@ export function listSessionUsage(sessionId) {
|
|
|
44
44
|
const chain = getSessionChain(sessionId);
|
|
45
45
|
const placeholders = chain.map(() => "?").join(",");
|
|
46
46
|
const rows = getDatabase()
|
|
47
|
-
.prepare(`
|
|
48
|
-
SELECT id, session_id, message_seq, source, model, input_tokens, output_tokens, total_tokens, cost_micros, created_at, cache_read_tokens, cache_creation_tokens
|
|
49
|
-
FROM usage_events
|
|
50
|
-
WHERE session_id IN (${placeholders})
|
|
51
|
-
ORDER BY id ASC
|
|
47
|
+
.prepare(`
|
|
48
|
+
SELECT id, session_id, message_seq, source, model, input_tokens, output_tokens, total_tokens, cost_micros, created_at, cache_read_tokens, cache_creation_tokens
|
|
49
|
+
FROM usage_events
|
|
50
|
+
WHERE session_id IN (${placeholders})
|
|
51
|
+
ORDER BY id ASC
|
|
52
52
|
`)
|
|
53
53
|
.all(...chain);
|
|
54
54
|
logger.debug("storage", "Retrieved session usage events from chain", {
|