@herbertgao/pi-extensions 2026.8.5 → 2026.8.7
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/README.md +5 -5
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +19 -7
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +30 -9
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +272 -22
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +74 -5
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +94 -77
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/markdown-enhance.ts +48 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/message-display.ts +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/hover.ts +14 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +55 -17
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/layout.ts +41 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-renderer.ts +75 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/types.ts +7 -3
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +64 -1
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +16 -0
- package/node_modules/@herbertgao/pi-subagents/README.md +30 -22
- package/node_modules/@herbertgao/pi-subagents/examples/agent-tool-description.md +5 -5
- package/node_modules/@herbertgao/pi-subagents/package.json +7 -7
- package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +7 -1
- package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +48 -19
- package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +22 -15
- package/node_modules/@herbertgao/pi-subagents/src/custom-agents.ts +26 -2
- package/node_modules/@herbertgao/pi-subagents/src/index.ts +219 -40
- package/node_modules/@herbertgao/pi-subagents/src/invocation-config.ts +101 -3
- package/node_modules/@herbertgao/pi-subagents/src/nested-tools.ts +18 -4
- package/node_modules/@herbertgao/pi-subagents/src/settings.ts +99 -0
- package/node_modules/@herbertgao/pi-subagents/src/types.ts +22 -3
- package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +51 -3
- package/node_modules/@herbertgao/pi-subagents/src/ui/conversation-viewer.ts +20 -2
- package/node_modules/@herbertgao/pi-subagents/src/ui/fleet-list.ts +34 -10
- package/node_modules/@herbertgao/pi-subagents/src/usage.ts +129 -1
- package/node_modules/@herbertgao/pi-subagents/src/worktree.ts +29 -5
- package/node_modules/@juicesharp/rpiv-ask-user-question/README.md +3 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/ask-user-question.ts +46 -10
- package/node_modules/@juicesharp/rpiv-ask-user-question/config.ts +25 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/configuration.md +13 -4
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/hosts.md +8 -1
- package/node_modules/@juicesharp/rpiv-ask-user-question/docs/localization.md +3 -1
- package/node_modules/@juicesharp/rpiv-ask-user-question/locales/en.json +2 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/locales/zh.json +2 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +3 -2
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/build-questionnaire.ts +10 -0
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/key-router.ts +3 -1
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/questionnaire-session.ts +30 -7
- package/node_modules/@juicesharp/rpiv-ask-user-question/state/state.ts +14 -6
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/dialog-builder.ts +30 -4
- package/node_modules/@juicesharp/rpiv-ask-user-question/view/tab-content-strategy.ts +26 -5
- package/node_modules/@narumitw/pi-btw/README.md +119 -103
- package/node_modules/@narumitw/pi-btw/dist/index.ts +2898 -0
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +7 -0
- package/node_modules/@narumitw/pi-btw/package.json +13 -9
- package/node_modules/@narumitw/pi-btw/src/btw.ts +40 -42
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +55 -10
- package/node_modules/@narumitw/pi-btw/src/main-tree-picker.ts +390 -0
- package/node_modules/@narumitw/pi-btw/src/menu.ts +78 -15
- package/node_modules/@narumitw/pi-btw/src/settings.ts +22 -2
- package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +136 -45
- package/node_modules/pi-lens/CHANGELOG.md +1004 -0
- package/node_modules/pi-lens/README.md +11 -3
- package/node_modules/pi-lens/config/ruff/core.toml +42 -0
- package/node_modules/pi-lens/dist/clients/actionable-warnings.js +130 -27
- package/node_modules/pi-lens/dist/clients/advisory-provenance.js +427 -0
- package/node_modules/pi-lens/dist/clients/agent-nudge.js +79 -16
- package/node_modules/pi-lens/dist/clients/ast-grep-client.js +9 -3
- package/node_modules/pi-lens/dist/clients/atomic-write.js +9 -3
- package/node_modules/pi-lens/dist/clients/bash-file-access.js +285 -8
- package/node_modules/pi-lens/dist/clients/biome-client.js +176 -37
- package/node_modules/pi-lens/dist/clients/blocker-freshness.js +428 -0
- package/node_modules/pi-lens/dist/clients/blocker-past-eof.js +119 -0
- package/node_modules/pi-lens/dist/clients/bootstrap.js +12 -1
- package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +12 -3
- package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +192 -0
- package/node_modules/pi-lens/dist/clients/bus-events-logger.js +62 -6
- package/node_modules/pi-lens/dist/clients/bus-publish.js +11 -3
- package/node_modules/pi-lens/dist/clients/cascade-budget.js +196 -0
- package/node_modules/pi-lens/dist/clients/cascade-format.js +76 -2
- package/node_modules/pi-lens/dist/clients/cascade-types.js +9 -1
- package/node_modules/pi-lens/dist/clients/child-unref.js +54 -6
- package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +76 -24
- package/node_modules/pi-lens/dist/clients/console-guard-install.js +16 -4
- package/node_modules/pi-lens/dist/clients/dead-code-client.js +249 -52
- package/node_modules/pi-lens/dist/clients/deadline-utils.js +8 -1
- package/node_modules/pi-lens/dist/clients/debug-handles.js +5 -0
- package/node_modules/pi-lens/dist/clients/degradation-ledger.js +62 -13
- package/node_modules/pi-lens/dist/clients/dependency-checker.js +43 -9
- package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +153 -37
- package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +298 -0
- package/node_modules/pi-lens/dist/clients/diagnostics-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +165 -11
- package/node_modules/pi-lens/dist/clients/dispatch/integration.js +325 -72
- package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +7 -4
- package/node_modules/pi-lens/dist/clients/dispatch/plan.js +5 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +234 -18
- package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +187 -19
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +6 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +11 -9
- package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +398 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +11 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +12 -7
- package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +18 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +895 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +4 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +16 -3
- package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +81 -41
- package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +16 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +23 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +331 -55
- package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +38 -5
- package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +97 -19
- package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +14 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +20 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +22 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +10 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +18 -6
- package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +73 -12
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +488 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +84 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +260 -27
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +943 -93
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +86 -11
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +72 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +106 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +9 -0
- package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +18 -1
- package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +4 -2
- package/node_modules/pi-lens/dist/clients/disposition-publish.js +10 -3
- package/node_modules/pi-lens/dist/clients/eval-timestamp.js +17 -0
- package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +28 -5
- package/node_modules/pi-lens/dist/clients/extension-log.js +317 -3
- package/node_modules/pi-lens/dist/clients/file-kinds.js +8 -2
- package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +294 -0
- package/node_modules/pi-lens/dist/clients/finding-identity.js +88 -0
- package/node_modules/pi-lens/dist/clients/fix-worklog.js +5 -1
- package/node_modules/pi-lens/dist/clients/format-events-publish.js +39 -8
- package/node_modules/pi-lens/dist/clients/formatters-lazy.js +3 -2
- package/node_modules/pi-lens/dist/clients/formatters.js +500 -115
- package/node_modules/pi-lens/dist/clients/generation-guard.js +216 -0
- package/node_modules/pi-lens/dist/clients/git-guard.js +49 -21
- package/node_modules/pi-lens/dist/clients/gitleaks-client.js +181 -8
- package/node_modules/pi-lens/dist/clients/go-client.js +21 -39
- package/node_modules/pi-lens/dist/clients/govulncheck-client.js +219 -10
- package/node_modules/pi-lens/dist/clients/grammar-source.js +333 -10
- package/node_modules/pi-lens/dist/clients/host-ports.js +9 -1
- package/node_modules/pi-lens/dist/clients/installer/index.js +1119 -101
- package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh-session.js +58 -0
- package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +715 -0
- package/node_modules/pi-lens/dist/clients/instance-reaper.js +643 -97
- package/node_modules/pi-lens/dist/clients/instance-registry.js +87 -17
- package/node_modules/pi-lens/dist/clients/jscpd-client.js +86 -15
- package/node_modules/pi-lens/dist/clients/knip-client.js +361 -24
- package/node_modules/pi-lens/dist/clients/language-policy.js +8 -2
- package/node_modules/pi-lens/dist/clients/language-profile.js +2 -0
- package/node_modules/pi-lens/dist/clients/latency-logger.js +487 -9
- package/node_modules/pi-lens/dist/clients/lazy-import.js +21 -0
- package/node_modules/pi-lens/dist/clients/ledger-bounds.js +21 -0
- package/node_modules/pi-lens/dist/clients/lens-events.js +56 -25
- package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +16 -0
- package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +45 -2
- package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +30 -4
- package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +160 -20
- package/node_modules/pi-lens/dist/clients/lsp/client.js +1666 -148
- package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +111 -0
- package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +389 -0
- package/node_modules/pi-lens/dist/clients/lsp/index.js +2496 -171
- package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +215 -0
- package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +146 -14
- package/node_modules/pi-lens/dist/clients/lsp/language.js +48 -4
- package/node_modules/pi-lens/dist/clients/lsp/server.js +517 -69
- package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +22 -0
- package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +43 -0
- package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +172 -0
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/classification.js +21 -5
- package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +61 -3
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +422 -28
- package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-session.js +30 -0
- package/node_modules/pi-lens/dist/clients/lsp/workspace-sweep-hold.js +175 -0
- package/node_modules/pi-lens/dist/clients/lsp-lazy.js +3 -2
- package/node_modules/pi-lens/dist/clients/mcp/analyze.js +4 -0
- package/node_modules/pi-lens/dist/clients/mcp/session.js +39 -18
- package/node_modules/pi-lens/dist/clients/model-provider.js +53 -0
- package/node_modules/pi-lens/dist/clients/module-report.js +8 -0
- package/node_modules/pi-lens/dist/clients/opengrep-client.js +15 -1
- package/node_modules/pi-lens/dist/clients/package-manager.js +170 -14
- package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +27 -0
- package/node_modules/pi-lens/dist/clients/path-utils.js +160 -0
- package/node_modules/pi-lens/dist/clients/pipeline.js +178 -30
- package/node_modules/pi-lens/dist/clients/post-autofix-notice.js +37 -0
- package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +17 -3
- package/node_modules/pi-lens/dist/clients/project-diagnostics/extractors.js +89 -22
- package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +85 -15
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +15 -3
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +23 -2
- package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +50 -2
- package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +5 -0
- package/node_modules/pi-lens/dist/clients/project-lens-config.js +3 -0
- package/node_modules/pi-lens/dist/clients/project-snapshot.js +299 -0
- package/node_modules/pi-lens/dist/clients/quiet-window-config.js +47 -0
- package/node_modules/pi-lens/dist/clients/quiet-window.js +11 -25
- package/node_modules/pi-lens/dist/clients/read-guard-logger.js +1 -1
- package/node_modules/pi-lens/dist/clients/read-guard.js +184 -10
- package/node_modules/pi-lens/dist/clients/resource-sampler.js +49 -17
- package/node_modules/pi-lens/dist/clients/reverse-deps.js +50 -11
- package/node_modules/pi-lens/dist/clients/review-graph/query.js +76 -4
- package/node_modules/pi-lens/dist/clients/run-duration.js +55 -0
- package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +248 -13
- package/node_modules/pi-lens/dist/clients/runtime-context.js +112 -12
- package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +472 -61
- package/node_modules/pi-lens/dist/clients/runtime-session.js +359 -13
- package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +217 -22
- package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +269 -22
- package/node_modules/pi-lens/dist/clients/runtime-turn.js +948 -87
- package/node_modules/pi-lens/dist/clients/rust-client.js +21 -37
- package/node_modules/pi-lens/dist/clients/safe-spawn.js +220 -7
- package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +161 -0
- package/node_modules/pi-lens/dist/clients/search-read-registration.js +34 -6
- package/node_modules/pi-lens/dist/clients/security-scan-client.js +224 -8
- package/node_modules/pi-lens/dist/clients/sg-runner.js +249 -37
- package/node_modules/pi-lens/dist/clients/single-flight.js +158 -0
- package/node_modules/pi-lens/dist/clients/smells-rollup.js +18 -11
- package/node_modules/pi-lens/dist/clients/stale-marker.js +17 -0
- package/node_modules/pi-lens/dist/clients/startup-timing.js +26 -2
- package/node_modules/pi-lens/dist/clients/test-runner-client.js +574 -32
- package/node_modules/pi-lens/dist/clients/tool-event.js +56 -5
- package/node_modules/pi-lens/dist/clients/tool-policy.js +127 -20
- package/node_modules/pi-lens/dist/clients/tool-set-policy.js +76 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +75 -1
- package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +769 -64
- package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +11 -0
- package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +90 -0
- package/node_modules/pi-lens/dist/clients/trivy-client.js +19 -1
- package/node_modules/pi-lens/dist/clients/warm-attach.js +17 -0
- package/node_modules/pi-lens/dist/clients/widget-state.js +336 -36
- package/node_modules/pi-lens/dist/clients/word-index.js +305 -33
- package/node_modules/pi-lens/dist/clients/zizmor-config.js +214 -14
- package/node_modules/pi-lens/dist/index.js +64677 -49484
- package/node_modules/pi-lens/dist/mcp/server.js +8 -2
- package/node_modules/pi-lens/dist/tools/activate-tools.js +17 -5
- package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +9 -4
- package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +5 -2
- package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +469 -56
- package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +190 -46
- package/node_modules/pi-lens/dist/tools/lsp-navigation.js +46 -7
- package/node_modules/pi-lens/dist/tools/symbol-search.js +1 -1
- package/node_modules/pi-lens/docs/agent-guide.md +44 -14
- package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +518 -501
- package/node_modules/pi-lens/docs/dispositions.md +21 -0
- package/node_modules/pi-lens/docs/features.md +33 -6
- package/node_modules/pi-lens/docs/globalconfig.md +14 -0
- package/node_modules/pi-lens/docs/language-coverage.md +71 -5
- package/node_modules/pi-lens/docs/mcp.md +2 -2
- package/node_modules/pi-lens/docs/servercapabilities.md +4 -1
- package/node_modules/pi-lens/docs/settings.md +25 -1
- package/node_modules/pi-lens/docs/usage.md +24 -5
- package/node_modules/pi-lens/docs/word-index.md +35 -0
- package/node_modules/pi-lens/package.json +10 -6
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/no-reflect-get-js-snapshot.yml +23 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/no-reflect-get-snapshot.yml +23 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/__snapshots__/ts-void-zero-snapshot.yml +23 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-object-param-test.yml +16 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-chained-type-assertions-test.yml +22 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-compile-call-test.yml +29 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-conditional-empty-object-spread-js-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-conditional-empty-object-spread-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-dupe-class-members-test.yml +33 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-inner-html-js-test.yml +7 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-inner-html-test.yml +7 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-known-value-widening-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-non-null-assertion-test.yml +216 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-js-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-js-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-return-value-in-generator-test.yml +12 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-runtime-typeof-test.yml +33 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-server-bind-wildcard-test.yml +9 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-shape-in-symbol-names-test.yml +13 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-sql-in-code-js-test.yml +5 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-sql-in-code-test.yml +5 -1
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-laundering-test.yml +11 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-parameters-test.yml +12 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-returns-test.yml +16 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unsafe-dictionary-any-test.yml +10 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unsafe-dictionary-unknown-test.yml +8 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/redundant-unsafe-function-test.yml +35 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/require-safety-comment-for-as-unknown-as-test.yml +177 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/ts-void-zero-test.yml +1 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-await-expression-member-js.yml +13 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-await-expression-member.yml +13 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-host-path-in-win32-branch.yml +2 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-object-param.yml +60 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-chained-type-assertions.yml +66 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-compile-call.yml +63 -5
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-conditional-empty-object-spread-js.yml +21 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-conditional-empty-object-spread.yml +29 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-dupe-class-members.yml +52 -8
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-inner-html-js.yml +27 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-inner-html.yml +27 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-known-value-widening.yml +71 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-non-null-assertion.yml +316 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-raw-json-store-write.yml +7 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply-js.yml +29 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply.yml +30 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get-js.yml +41 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get.yml +42 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-return-value-in-generator.yml +22 -5
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-runtime-typeof.yml +121 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-server-bind-wildcard.yml +23 -7
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-shape-in-symbol-names.yml +68 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-sql-in-code-js.yml +41 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-sql-in-code.yml +41 -2
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-laundering.yml +32 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-parameters.yml +67 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-returns.yml +106 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unsafe-dictionary-any.yml +50 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unsafe-dictionary-unknown.yml +56 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-win32-isabsolute-for-qualification.yml +2 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/redundant-unsafe-function.yml +32 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/require-safety-comment-for-as-unknown-as.yml +184 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/rules/ts-void-zero.yml +5 -0
- package/node_modules/pi-lens/rules/ast-grep-rules/self-scan-baseline.json +5 -0
- package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +132 -1
- package/node_modules/pi-lens/scripts/download-grammars.js +25 -0
- package/node_modules/pi-lens/scripts/grammars.lock.json +9 -0
- package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +12 -11
- package/node_modules/pi-lens/skills/pi-lens-lsp-navigation/SKILL.md +22 -22
- package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/SKILL.md +87 -116
- package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/reference.md +170 -0
- package/node_modules/pi-lens/skills/pi-lens-write-tree-sitter-rule/SKILL.md +3 -1
- package/node_modules/pi-lens/vendor/grammars/tree-sitter-cue.wasm +0 -0
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +49 -0
- package/node_modules/pi-mcp-adapter/README.md +51 -6
- package/node_modules/pi-mcp-adapter/agent-dir.ts +12 -4
- package/node_modules/pi-mcp-adapter/cli.js +188 -5
- package/node_modules/pi-mcp-adapter/commands.ts +128 -22
- package/node_modules/pi-mcp-adapter/config.ts +28 -10
- package/node_modules/pi-mcp-adapter/direct-tools.ts +23 -19
- package/node_modules/pi-mcp-adapter/index.ts +219 -32
- package/node_modules/pi-mcp-adapter/init.ts +36 -4
- package/node_modules/pi-mcp-adapter/lifecycle.ts +315 -24
- package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +39 -6
- package/node_modules/pi-mcp-adapter/mcp-bearer-store.ts +387 -0
- package/node_modules/pi-mcp-adapter/mcp-callback-server.ts +27 -3
- package/node_modules/pi-mcp-adapter/mcp-code.ts +4 -0
- package/node_modules/pi-mcp-adapter/mcp-panel.ts +42 -13
- package/node_modules/pi-mcp-adapter/mcp-setup-panel.ts +2 -1
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +46 -25
- package/node_modules/pi-mcp-adapter/package-mcp-loader.ts +168 -0
- package/node_modules/pi-mcp-adapter/package.json +4 -1
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +5 -4
- package/node_modules/pi-mcp-adapter/request-headers-command.ts +330 -0
- package/node_modules/pi-mcp-adapter/search-ranking.ts +92 -22
- package/node_modules/pi-mcp-adapter/server-manager.ts +145 -2
- package/node_modules/pi-mcp-adapter/session-recovery.ts +7 -0
- package/node_modules/pi-mcp-adapter/tool-approval.ts +15 -2
- package/node_modules/pi-mcp-adapter/tool-metadata.ts +38 -18
- package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +44 -4
- package/node_modules/pi-mcp-adapter/types.ts +95 -10
- package/node_modules/pi-mcp-adapter/ui-server.ts +18 -16
- package/node_modules/pi-mcp-adapter/utils.ts +70 -0
- package/node_modules/pi-web-access/CHANGELOG.md +37 -0
- package/node_modules/pi-web-access/README.md +38 -14
- package/node_modules/pi-web-access/anysearch.ts +4 -2
- package/node_modules/pi-web-access/auth-fetch.ts +148 -0
- package/node_modules/pi-web-access/brave.ts +16 -4
- package/node_modules/pi-web-access/chrome-cookies.ts +110 -23
- package/node_modules/pi-web-access/curator-page.ts +8 -3
- package/node_modules/pi-web-access/curator-server.ts +5 -1
- package/node_modules/pi-web-access/exa.ts +18 -7
- package/node_modules/pi-web-access/extract.ts +134 -37
- package/node_modules/pi-web-access/fetch-params.ts +17 -3
- package/node_modules/pi-web-access/firecrawl.ts +172 -12
- package/node_modules/pi-web-access/gemini-search.ts +33 -7
- package/node_modules/pi-web-access/index.ts +160 -104
- package/node_modules/pi-web-access/package.json +2 -2
- package/node_modules/pi-web-access/page-query.ts +4 -2
- package/node_modules/pi-web-access/parallel-mcp.ts +249 -0
- package/node_modules/pi-web-access/parallel.ts +2 -2
- package/node_modules/pi-web-access/query-rewrite.ts +51 -0
- package/node_modules/pi-web-access/serper.ts +211 -0
- package/node_modules/pi-web-access/summary-model-scope.ts +12 -4
- package/node_modules/pi-web-access/summary-review.ts +51 -23
- package/node_modules/pi-web-access/tavily.ts +16 -4
- package/node_modules/pi-web-access/utils.ts +87 -0
- package/node_modules/pi-web-access/valyu.ts +199 -0
- package/node_modules/pi-web-access/youtube-extract.ts +2 -2
- package/package.json +13 -13
|
@@ -7,6 +7,7 @@ import type { Component, TUI } from "@earendil-works/pi-tui";
|
|
|
7
7
|
import type { MenuContext, RunMenuResult } from "@narumitw/pi-tui-kit";
|
|
8
8
|
import {
|
|
9
9
|
type BtwSettings,
|
|
10
|
+
type BtwSettingsPatch,
|
|
10
11
|
btwSettingsPath,
|
|
11
12
|
effectiveRememberThinkingLevelChanges,
|
|
12
13
|
readBtwSettings,
|
|
@@ -35,15 +36,20 @@ export interface ShowBtwCommandMenuOptions {
|
|
|
35
36
|
settingsPath?: string;
|
|
36
37
|
readSettings?: typeof readBtwSettings;
|
|
37
38
|
updateSettings?: (
|
|
38
|
-
patch:
|
|
39
|
+
patch: BtwSettingsPatch,
|
|
39
40
|
options: UpdateBtwSettingsOptions,
|
|
40
41
|
) => Promise<BtwSettings>;
|
|
41
42
|
}
|
|
42
43
|
|
|
43
|
-
export type BtwCommandMenuResult =
|
|
44
|
+
export type BtwCommandMenuResult =
|
|
45
|
+
| "start"
|
|
46
|
+
| "tree"
|
|
47
|
+
| "closed"
|
|
48
|
+
| { kind: "resume"; threadId: string };
|
|
44
49
|
|
|
45
50
|
type BtwMenuScreen = "main" | "resume" | "settings" | "invalid";
|
|
46
|
-
type BtwMenuAction = "start" | "resume" | "set-thinking" | "set-remember";
|
|
51
|
+
type BtwMenuAction = "start" | "start-tree" | "resume" | "set-thinking" | "set-remember";
|
|
52
|
+
const SAME_AS_MAIN_THREAD = "Same as main thread";
|
|
47
53
|
type BtwCustomOptions = Parameters<ExtensionCommandContext["ui"]["custom"]>[1];
|
|
48
54
|
|
|
49
55
|
type BtwCustomFactory<T> = (
|
|
@@ -70,6 +76,7 @@ export async function showBtwCommandMenu(
|
|
|
70
76
|
const displaySettingsPath = sanitizeSingleLine(settingsPath);
|
|
71
77
|
const resumeThreads = options.resumeThreads ?? [];
|
|
72
78
|
let startSelected = false;
|
|
79
|
+
let treeSelected = false;
|
|
73
80
|
let resumedThreadId: string | undefined;
|
|
74
81
|
|
|
75
82
|
const loadState = async (): Promise<BtwMenuState> => {
|
|
@@ -79,8 +86,22 @@ export async function showBtwCommandMenu(
|
|
|
79
86
|
}
|
|
80
87
|
return { kind: "valid", settings: loaded.kind === "loaded" ? loaded.settings : {} };
|
|
81
88
|
};
|
|
82
|
-
const
|
|
83
|
-
|
|
89
|
+
const currentMainThinkingLevel = clampToAvailableThinkingLevel(
|
|
90
|
+
options.currentThinkingLevel,
|
|
91
|
+
levels,
|
|
92
|
+
);
|
|
93
|
+
const displayThinkingLevel = (settings: BtwSettings): string =>
|
|
94
|
+
settings.thinkingLevel === undefined
|
|
95
|
+
? SAME_AS_MAIN_THREAD
|
|
96
|
+
: clampToAvailableThinkingLevel(settings.thinkingLevel, levels);
|
|
97
|
+
const displayThinkingSummary = (settings: BtwSettings): string =>
|
|
98
|
+
settings.thinkingLevel === undefined
|
|
99
|
+
? `${SAME_AS_MAIN_THREAD} (currently ${currentMainThinkingLevel})`
|
|
100
|
+
: displayThinkingLevel(settings);
|
|
101
|
+
const displayRememberSummary = (settings: BtwSettings): string => {
|
|
102
|
+
const value = effectiveRememberThinkingLevelChanges(settings) ? "On" : "Off";
|
|
103
|
+
return settings.thinkingLevel === undefined ? `${value} (fixed levels only)` : value;
|
|
104
|
+
};
|
|
84
105
|
|
|
85
106
|
const menu = defineMenu<BtwMenuState, BtwMenuScreen, BtwMenuAction, MenuContext>({
|
|
86
107
|
start: "main",
|
|
@@ -89,7 +110,7 @@ export async function showBtwCommandMenu(
|
|
|
89
110
|
kind: "actions",
|
|
90
111
|
title: "Pi BTW",
|
|
91
112
|
lines: [
|
|
92
|
-
`Thinking: ${
|
|
113
|
+
`Thinking: ${displayThinkingSummary(state.settings)} · Remember changes: ${displayRememberSummary(state.settings)}`,
|
|
93
114
|
],
|
|
94
115
|
items: [
|
|
95
116
|
{
|
|
@@ -98,6 +119,12 @@ export async function showBtwCommandMenu(
|
|
|
98
119
|
description: "Open an empty side thread",
|
|
99
120
|
action: "start",
|
|
100
121
|
},
|
|
122
|
+
{
|
|
123
|
+
id: "start-tree",
|
|
124
|
+
label: "Start from main thread tree…",
|
|
125
|
+
description: "Choose context without switching the main branch",
|
|
126
|
+
action: "start-tree",
|
|
127
|
+
},
|
|
101
128
|
...(resumeThreads.length > 0
|
|
102
129
|
? [
|
|
103
130
|
{
|
|
@@ -111,7 +138,7 @@ export async function showBtwCommandMenu(
|
|
|
111
138
|
{
|
|
112
139
|
id: "settings",
|
|
113
140
|
label: "Settings",
|
|
114
|
-
description: "Choose pi-btw thinking and
|
|
141
|
+
description: "Choose pi-btw thinking level and fixed-level shortcut memory",
|
|
115
142
|
to: state.kind === "invalid" ? "invalid" : "settings",
|
|
116
143
|
},
|
|
117
144
|
],
|
|
@@ -138,15 +165,15 @@ export async function showBtwCommandMenu(
|
|
|
138
165
|
{
|
|
139
166
|
id: "thinkingLevel",
|
|
140
167
|
label: "Thinking level",
|
|
141
|
-
description:
|
|
168
|
+
description: `Set the starting level for future pi-btw side threads. Currently ${currentMainThinkingLevel}.`,
|
|
142
169
|
currentValue: displayThinkingLevel(state.settings),
|
|
143
|
-
values: levels,
|
|
170
|
+
values: [SAME_AS_MAIN_THREAD, ...levels],
|
|
144
171
|
action: "set-thinking",
|
|
145
172
|
},
|
|
146
173
|
{
|
|
147
174
|
id: "rememberThinkingLevelChanges",
|
|
148
175
|
label: "Remember thinking level changes",
|
|
149
|
-
description: "Save
|
|
176
|
+
description: "Save shortcut changes for fixed thinking levels to pi-btw.json.",
|
|
150
177
|
currentValue: effectiveRememberThinkingLevelChanges(state.settings) ? "On" : "Off",
|
|
151
178
|
values: ["On", "Off"],
|
|
152
179
|
action: "set-remember",
|
|
@@ -168,6 +195,10 @@ export async function showBtwCommandMenu(
|
|
|
168
195
|
startSelected = true;
|
|
169
196
|
return { kind: "close" };
|
|
170
197
|
},
|
|
198
|
+
"start-tree": async () => {
|
|
199
|
+
treeSelected = true;
|
|
200
|
+
return { kind: "close" };
|
|
201
|
+
},
|
|
171
202
|
resume: async ({ itemId }: { itemId: string }) => {
|
|
172
203
|
if (!resumeThreads.some((thread) => thread.id === itemId)) {
|
|
173
204
|
return { kind: "rejected" } as const;
|
|
@@ -176,12 +207,16 @@ export async function showBtwCommandMenu(
|
|
|
176
207
|
return { kind: "close" } as const;
|
|
177
208
|
},
|
|
178
209
|
"set-thinking": async ({ value, signal }) => {
|
|
179
|
-
if (!value
|
|
210
|
+
if (!value) return { kind: "rejected" };
|
|
211
|
+
const patch =
|
|
212
|
+
value === SAME_AS_MAIN_THREAD
|
|
213
|
+
? ({ thinkingLevel: undefined } satisfies BtwSettingsPatch)
|
|
214
|
+
: levels.includes(value as BtwThinkingLevel)
|
|
215
|
+
? ({ thinkingLevel: value as BtwThinkingLevel } satisfies BtwSettingsPatch)
|
|
216
|
+
: undefined;
|
|
217
|
+
if (!patch) return { kind: "rejected" };
|
|
180
218
|
try {
|
|
181
|
-
await updateSettings(
|
|
182
|
-
{ thinkingLevel: value as BtwThinkingLevel },
|
|
183
|
-
{ settingsPath, signal },
|
|
184
|
-
);
|
|
219
|
+
await updateSettings(patch, { settingsPath, signal });
|
|
185
220
|
if (signal.aborted) return { kind: "rejected" };
|
|
186
221
|
notifySafely(ctx, `Pi BTW thinking level: ${value}.`, "info");
|
|
187
222
|
return { kind: "stay" };
|
|
@@ -213,9 +248,37 @@ export async function showBtwCommandMenu(
|
|
|
213
248
|
);
|
|
214
249
|
if (result.kind !== "closed" || result.reason !== "close") return "closed";
|
|
215
250
|
if (resumedThreadId) return { kind: "resume", threadId: resumedThreadId };
|
|
251
|
+
if (treeSelected) return "tree";
|
|
216
252
|
return startSelected ? "start" : "closed";
|
|
217
253
|
}
|
|
218
254
|
|
|
255
|
+
export async function showBtwCustomPreservingEditor<T>(
|
|
256
|
+
ctx: ExtensionCommandContext,
|
|
257
|
+
factory: BtwCustomFactory<T>,
|
|
258
|
+
): Promise<T | undefined> {
|
|
259
|
+
let liveEditorText = ctx.ui.getEditorText();
|
|
260
|
+
let completed = false;
|
|
261
|
+
const result = await ctx.ui.custom<T>((tui, theme, keybindings, done) =>
|
|
262
|
+
factory(tui, theme, keybindings, (value) => {
|
|
263
|
+
try {
|
|
264
|
+
liveEditorText = ctx.ui.getEditorText();
|
|
265
|
+
} catch {
|
|
266
|
+
// Keep completion finite if session replacement invalidates the editor context.
|
|
267
|
+
}
|
|
268
|
+
completed = true;
|
|
269
|
+
done(value);
|
|
270
|
+
}),
|
|
271
|
+
);
|
|
272
|
+
if (completed) {
|
|
273
|
+
try {
|
|
274
|
+
if (ctx.ui.getEditorText() !== liveEditorText) ctx.ui.setEditorText(liveEditorText);
|
|
275
|
+
} catch {
|
|
276
|
+
// A replaced context owns a different editor and must not receive stale restoration.
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return result;
|
|
280
|
+
}
|
|
281
|
+
|
|
219
282
|
export async function runBtwMenuPreservingEditor(
|
|
220
283
|
ctx: ExtensionCommandContext,
|
|
221
284
|
run: (menuContext: MenuContext) => Promise<RunMenuResult>,
|
|
@@ -20,6 +20,11 @@ export type BtwSettingsLoadResult =
|
|
|
20
20
|
| { kind: "invalid"; reason: string }
|
|
21
21
|
| { kind: "loaded"; settings: BtwSettings };
|
|
22
22
|
|
|
23
|
+
export interface BtwSettingsPatch {
|
|
24
|
+
thinkingLevel?: BtwThinkingLevel;
|
|
25
|
+
rememberThinkingLevelChanges?: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
23
28
|
export interface UpdateBtwSettingsOptions {
|
|
24
29
|
settingsPath?: string;
|
|
25
30
|
signal?: AbortSignal;
|
|
@@ -77,14 +82,14 @@ export async function readBtwSettings(
|
|
|
77
82
|
}
|
|
78
83
|
|
|
79
84
|
export function updateBtwSettings(
|
|
80
|
-
patch:
|
|
85
|
+
patch: BtwSettingsPatch,
|
|
81
86
|
options: UpdateBtwSettingsOptions = {},
|
|
82
87
|
): Promise<BtwSettings> {
|
|
83
88
|
const settingsPath = options.settingsPath ?? btwSettingsPath();
|
|
84
89
|
return enqueueMutation(settingsPath, async () => {
|
|
85
90
|
options.signal?.throwIfAborted();
|
|
86
91
|
const current = await readSettingsDocumentForUpdate(settingsPath);
|
|
87
|
-
const updated
|
|
92
|
+
const updated = applyBtwSettingsPatch(current, patch);
|
|
88
93
|
const settings = normalizeBtwSettings(updated);
|
|
89
94
|
if (!settings) throw invalidSettingsError(settingsPath, "invalid settings shape");
|
|
90
95
|
await publishSettings(settingsPath, updated, options.signal, options.beforeRename);
|
|
@@ -216,6 +221,21 @@ async function publishSettings(
|
|
|
216
221
|
}
|
|
217
222
|
}
|
|
218
223
|
|
|
224
|
+
function applyBtwSettingsPatch(
|
|
225
|
+
current: SettingsDocument,
|
|
226
|
+
patch: BtwSettingsPatch,
|
|
227
|
+
): SettingsDocument {
|
|
228
|
+
const updated: SettingsDocument = { ...current };
|
|
229
|
+
if (Object.hasOwn(patch, "thinkingLevel")) {
|
|
230
|
+
if (patch.thinkingLevel === undefined) delete updated.thinkingLevel;
|
|
231
|
+
else updated.thinkingLevel = patch.thinkingLevel;
|
|
232
|
+
}
|
|
233
|
+
if (Object.hasOwn(patch, "rememberThinkingLevelChanges")) {
|
|
234
|
+
updated.rememberThinkingLevelChanges = patch.rememberThinkingLevelChanges;
|
|
235
|
+
}
|
|
236
|
+
return updated;
|
|
237
|
+
}
|
|
238
|
+
|
|
219
239
|
function isSettingsDocument(value: unknown): value is SettingsDocument {
|
|
220
240
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
221
241
|
}
|
|
@@ -16,10 +16,13 @@ import {
|
|
|
16
16
|
Loader,
|
|
17
17
|
Markdown,
|
|
18
18
|
matchesKey,
|
|
19
|
+
ScrollView,
|
|
19
20
|
type TUI,
|
|
20
21
|
truncateToWidth,
|
|
22
|
+
VStack,
|
|
21
23
|
visibleWidth,
|
|
22
24
|
} from "@earendil-works/pi-tui";
|
|
25
|
+
import type { BtwFullscreenLayoutComponent } from "./fullscreen-ui.js";
|
|
23
26
|
import type { BtwThinkingLevel, SideThreadTurn } from "./side-thread.js";
|
|
24
27
|
import { sanitizeSingleLine } from "./text.js";
|
|
25
28
|
|
|
@@ -29,6 +32,21 @@ const OSC133_MARKERS = ["\u001b]133;A\u0007", "\u001b]133;B\u0007", "\u001b]133;
|
|
|
29
32
|
// Pi renders a spacer above the custom component and a two-line built-in footer below it.
|
|
30
33
|
const RESERVED_APP_LINES = 3;
|
|
31
34
|
|
|
35
|
+
// A temporary fit after manual scrolling must not silently resume following new output.
|
|
36
|
+
class PreservingScrollView extends ScrollView {
|
|
37
|
+
override updateLayout(
|
|
38
|
+
contentHeight: number,
|
|
39
|
+
viewportHeight: number,
|
|
40
|
+
requestRender: () => void,
|
|
41
|
+
): void {
|
|
42
|
+
const preserveManualPosition = !this.isFollowingEnd;
|
|
43
|
+
super.updateLayout(contentHeight, viewportHeight, requestRender);
|
|
44
|
+
if (preserveManualPosition && this.isFollowingEnd) {
|
|
45
|
+
this.scrollTo(this.scrollTop, { disableFollow: true });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
32
50
|
export type TranscriptPagerAction =
|
|
33
51
|
| { kind: "submit"; question: string }
|
|
34
52
|
| { kind: "bringToMain"; questionDraft: string }
|
|
@@ -49,14 +67,13 @@ export interface BtwAnsweringViewOptions {
|
|
|
49
67
|
};
|
|
50
68
|
}
|
|
51
69
|
|
|
52
|
-
export class BtwTranscriptPager implements
|
|
70
|
+
export class BtwTranscriptPager implements BtwFullscreenLayoutComponent, Focusable {
|
|
53
71
|
private readonly transcriptComponents: Component[];
|
|
54
72
|
private readonly editor: Editor;
|
|
55
73
|
private readonly canBringToMain: boolean;
|
|
56
|
-
private
|
|
74
|
+
private readonly scrollView: ScrollView;
|
|
75
|
+
private readonly layoutRoot: VStack;
|
|
57
76
|
private lastContentLineCount = 0;
|
|
58
|
-
private lastViewportHeight = 1;
|
|
59
|
-
private followBottom: boolean;
|
|
60
77
|
private warning: string | undefined;
|
|
61
78
|
private finished = false;
|
|
62
79
|
private isFocused = false;
|
|
@@ -75,7 +92,6 @@ export class BtwTranscriptPager implements Component, Focusable {
|
|
|
75
92
|
) {
|
|
76
93
|
this.transcriptComponents = buildTranscriptComponents(turns, this.theme);
|
|
77
94
|
this.canBringToMain = turns.some((turn) => turn.kind === "answered");
|
|
78
|
-
this.followBottom = options.startAtBottom ?? false;
|
|
79
95
|
this.thinkingLevel = options.thinking?.level;
|
|
80
96
|
const editorTheme: EditorTheme = {
|
|
81
97
|
borderColor: (text) => this.theme.fg("accent", text),
|
|
@@ -101,6 +117,17 @@ export class BtwTranscriptPager implements Component, Focusable {
|
|
|
101
117
|
this.finished = true;
|
|
102
118
|
this.onAction({ kind: "submit", question });
|
|
103
119
|
};
|
|
120
|
+
const transcript = this.createTranscriptComponent();
|
|
121
|
+
this.scrollView = new PreservingScrollView(transcript, {
|
|
122
|
+
follow: options.startAtBottom ? "end" : "none",
|
|
123
|
+
primary: true,
|
|
124
|
+
});
|
|
125
|
+
this.layoutRoot = new VStack([
|
|
126
|
+
{ component: this.createHeaderComponent(), basis: 1, shrink: 0, minSize: 1 },
|
|
127
|
+
{ component: this.scrollView, basis: 0, grow: 1, minSize: 0 },
|
|
128
|
+
{ component: this.createFooterComponent(), basis: 1, shrink: 0, minSize: 1 },
|
|
129
|
+
{ component: this.editor, basis: "auto", shrink: 1, minSize: 0 },
|
|
130
|
+
]);
|
|
104
131
|
}
|
|
105
132
|
|
|
106
133
|
get focused(): boolean {
|
|
@@ -112,6 +139,10 @@ export class BtwTranscriptPager implements Component, Focusable {
|
|
|
112
139
|
this.editor.focused = value;
|
|
113
140
|
}
|
|
114
141
|
|
|
142
|
+
getFullscreenLayout(): Component {
|
|
143
|
+
return this.layoutRoot;
|
|
144
|
+
}
|
|
145
|
+
|
|
115
146
|
render(width: number): string[] {
|
|
116
147
|
const safeWidth = Math.max(1, width);
|
|
117
148
|
const editorLines = this.editor.render(safeWidth);
|
|
@@ -122,13 +153,13 @@ export class BtwTranscriptPager implements Component, Focusable {
|
|
|
122
153
|
);
|
|
123
154
|
const contentLines = renderTranscriptLines(this.transcriptComponents, safeWidth);
|
|
124
155
|
this.lastContentLineCount = contentLines.length;
|
|
125
|
-
this.
|
|
126
|
-
|
|
127
|
-
|
|
156
|
+
this.scrollView.updateLayout(contentLines.length, viewportHeight, () =>
|
|
157
|
+
this.tui.requestRender(),
|
|
158
|
+
);
|
|
128
159
|
|
|
129
160
|
return fitComposerLayout(
|
|
130
161
|
renderSideThreadHeader(safeWidth, this.theme, this.thinkingLevel),
|
|
131
|
-
contentLines.slice(this.
|
|
162
|
+
contentLines.slice(this.scrollView.scrollTop, this.scrollView.scrollTop + viewportHeight),
|
|
132
163
|
this.renderFooter(safeWidth),
|
|
133
164
|
editorLines,
|
|
134
165
|
availableRows,
|
|
@@ -164,15 +195,12 @@ export class BtwTranscriptPager implements Component, Focusable {
|
|
|
164
195
|
return;
|
|
165
196
|
}
|
|
166
197
|
if (matchesKey(data, Key.pageUp)) {
|
|
167
|
-
|
|
168
|
-
this.scrollBy(-this.lastViewportHeight);
|
|
169
|
-
if (this.scrollOffset < previousOffset) this.followBottom = false;
|
|
198
|
+
this.scrollView.scrollBy(-Math.max(1, this.scrollView.viewportHeight));
|
|
170
199
|
this.tui.requestRender();
|
|
171
200
|
return;
|
|
172
201
|
}
|
|
173
202
|
if (matchesKey(data, Key.pageDown)) {
|
|
174
|
-
this.scrollBy(this.
|
|
175
|
-
this.followBottom = this.scrollOffset >= this.getMaxScrollOffset();
|
|
203
|
+
this.scrollView.scrollBy(Math.max(1, this.scrollView.viewportHeight));
|
|
176
204
|
this.tui.requestRender();
|
|
177
205
|
return;
|
|
178
206
|
}
|
|
@@ -181,8 +209,7 @@ export class BtwTranscriptPager implements Component, Focusable {
|
|
|
181
209
|
}
|
|
182
210
|
|
|
183
211
|
invalidate(): void {
|
|
184
|
-
|
|
185
|
-
this.editor.invalidate();
|
|
212
|
+
this.layoutRoot.invalidate();
|
|
186
213
|
}
|
|
187
214
|
|
|
188
215
|
dispose(): void {
|
|
@@ -218,7 +245,7 @@ export class BtwTranscriptPager implements Component, Focusable {
|
|
|
218
245
|
? compactBase
|
|
219
246
|
: fallbackBase;
|
|
220
247
|
if (scrollable) {
|
|
221
|
-
const history = ` • ${this.
|
|
248
|
+
const history = ` • ${this.scrollView.scrollTop > 0 ? "↑ older" : "↓ newer"} • PgUp/PgDn history`;
|
|
222
249
|
const compactHistory = " • PgUp/PgDn";
|
|
223
250
|
const compactScrollable = this.canBringToMain
|
|
224
251
|
? "Enter • Ctrl+R • Ctrl+C • PgUp/PgDn"
|
|
@@ -238,29 +265,46 @@ export class BtwTranscriptPager implements Component, Focusable {
|
|
|
238
265
|
return truncateToWidth(this.theme.fg("muted", hints), width);
|
|
239
266
|
}
|
|
240
267
|
|
|
241
|
-
private
|
|
242
|
-
|
|
243
|
-
|
|
268
|
+
private createHeaderComponent(): Component {
|
|
269
|
+
return {
|
|
270
|
+
render: (width) => [renderSideThreadHeader(width, this.theme, this.thinkingLevel)],
|
|
271
|
+
invalidate() {},
|
|
272
|
+
};
|
|
244
273
|
}
|
|
245
274
|
|
|
246
|
-
private
|
|
247
|
-
|
|
275
|
+
private createTranscriptComponent(): Component {
|
|
276
|
+
return {
|
|
277
|
+
render: (width) => {
|
|
278
|
+
const lines = renderTranscriptLines(this.transcriptComponents, width);
|
|
279
|
+
this.lastContentLineCount = lines.length;
|
|
280
|
+
return lines;
|
|
281
|
+
},
|
|
282
|
+
invalidate: () => {
|
|
283
|
+
for (const component of this.transcriptComponents) component.invalidate();
|
|
284
|
+
},
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
private createFooterComponent(): Component {
|
|
289
|
+
return {
|
|
290
|
+
render: (width) => [this.renderFooter(width)],
|
|
291
|
+
invalidate() {},
|
|
292
|
+
};
|
|
248
293
|
}
|
|
249
294
|
|
|
250
295
|
private getMaxScrollOffset(): number {
|
|
251
|
-
return Math.max(0, this.lastContentLineCount - this.
|
|
296
|
+
return Math.max(0, this.lastContentLineCount - this.scrollView.viewportHeight);
|
|
252
297
|
}
|
|
253
298
|
}
|
|
254
299
|
|
|
255
|
-
export class BtwAnsweringView implements
|
|
300
|
+
export class BtwAnsweringView implements BtwFullscreenLayoutComponent, Focusable {
|
|
256
301
|
private readonly transcriptComponents: Component[];
|
|
257
302
|
private readonly loader: Loader;
|
|
258
303
|
private readonly editor: Editor | undefined;
|
|
259
304
|
private readonly controller = new AbortController();
|
|
260
|
-
private
|
|
305
|
+
private readonly scrollView: ScrollView;
|
|
306
|
+
private readonly layoutRoot: VStack;
|
|
261
307
|
private lastContentLineCount = 0;
|
|
262
|
-
private lastViewportHeight = 1;
|
|
263
|
-
private followBottom = true;
|
|
264
308
|
private warning: string | undefined;
|
|
265
309
|
private finished = false;
|
|
266
310
|
private isFocused = false;
|
|
@@ -308,6 +352,23 @@ export class BtwAnsweringView implements Component, Focusable {
|
|
|
308
352
|
this.warning = undefined;
|
|
309
353
|
};
|
|
310
354
|
}
|
|
355
|
+
const transcript = this.createTranscriptComponent();
|
|
356
|
+
this.scrollView = new PreservingScrollView(transcript, { follow: "end", primary: true });
|
|
357
|
+
this.layoutRoot = new VStack([
|
|
358
|
+
{ component: this.createHeaderComponent(), basis: 1, shrink: 0, minSize: 1 },
|
|
359
|
+
{ component: this.scrollView, basis: 0, grow: 1, minSize: 0 },
|
|
360
|
+
{
|
|
361
|
+
component: this.createSteeringComponent(),
|
|
362
|
+
basis: "auto",
|
|
363
|
+
shrink: 1,
|
|
364
|
+
minSize: 0,
|
|
365
|
+
maxSize: MAX_STEERING_DISPLAY_LINES,
|
|
366
|
+
},
|
|
367
|
+
{ component: this.createFooterComponent(), basis: 1, shrink: 0, minSize: 1 },
|
|
368
|
+
...(this.editor
|
|
369
|
+
? [{ component: this.editor, basis: "auto" as const, shrink: 1, minSize: 0 }]
|
|
370
|
+
: []),
|
|
371
|
+
]);
|
|
311
372
|
}
|
|
312
373
|
|
|
313
374
|
get focused(): boolean {
|
|
@@ -323,6 +384,10 @@ export class BtwAnsweringView implements Component, Focusable {
|
|
|
323
384
|
return this.controller.signal;
|
|
324
385
|
}
|
|
325
386
|
|
|
387
|
+
getFullscreenLayout(): Component {
|
|
388
|
+
return this.layoutRoot;
|
|
389
|
+
}
|
|
390
|
+
|
|
326
391
|
render(width: number): string[] {
|
|
327
392
|
const safeWidth = Math.max(1, width);
|
|
328
393
|
const availableRows = Math.max(1, this.tui.terminal.rows - RESERVED_APP_LINES);
|
|
@@ -343,13 +408,13 @@ export class BtwAnsweringView implements Component, Focusable {
|
|
|
343
408
|
);
|
|
344
409
|
const contentLines = renderTranscriptLines(this.transcriptComponents, safeWidth);
|
|
345
410
|
this.lastContentLineCount = contentLines.length;
|
|
346
|
-
this.
|
|
347
|
-
|
|
348
|
-
|
|
411
|
+
this.scrollView.updateLayout(contentLines.length, viewportHeight, () =>
|
|
412
|
+
this.tui.requestRender(),
|
|
413
|
+
);
|
|
349
414
|
|
|
350
415
|
return fitComposerLayout(
|
|
351
416
|
renderSideThreadHeader(safeWidth, this.theme, this.thinkingLevel),
|
|
352
|
-
contentLines.slice(this.
|
|
417
|
+
contentLines.slice(this.scrollView.scrollTop, this.scrollView.scrollTop + viewportHeight),
|
|
353
418
|
this.renderFooter(safeWidth),
|
|
354
419
|
editorLines,
|
|
355
420
|
availableRows,
|
|
@@ -383,15 +448,12 @@ export class BtwAnsweringView implements Component, Focusable {
|
|
|
383
448
|
return;
|
|
384
449
|
}
|
|
385
450
|
if (matchesKey(data, Key.pageUp)) {
|
|
386
|
-
|
|
387
|
-
this.scrollBy(-this.lastViewportHeight);
|
|
388
|
-
if (this.scrollOffset < previousOffset) this.followBottom = false;
|
|
451
|
+
this.scrollView.scrollBy(-Math.max(1, this.scrollView.viewportHeight));
|
|
389
452
|
this.tui.requestRender();
|
|
390
453
|
return;
|
|
391
454
|
}
|
|
392
455
|
if (matchesKey(data, Key.pageDown)) {
|
|
393
|
-
this.scrollBy(this.
|
|
394
|
-
this.followBottom = this.scrollOffset >= this.getMaxScrollOffset();
|
|
456
|
+
this.scrollView.scrollBy(Math.max(1, this.scrollView.viewportHeight));
|
|
395
457
|
this.tui.requestRender();
|
|
396
458
|
return;
|
|
397
459
|
}
|
|
@@ -400,9 +462,7 @@ export class BtwAnsweringView implements Component, Focusable {
|
|
|
400
462
|
}
|
|
401
463
|
|
|
402
464
|
invalidate(): void {
|
|
403
|
-
|
|
404
|
-
this.loader.invalidate();
|
|
405
|
-
this.editor?.invalidate();
|
|
465
|
+
this.layoutRoot.invalidate();
|
|
406
466
|
}
|
|
407
467
|
|
|
408
468
|
finish(): void {
|
|
@@ -442,17 +502,48 @@ export class BtwAnsweringView implements Component, Focusable {
|
|
|
442
502
|
return truncateToWidth(`${loaderLine} • ${this.theme.fg("muted", selectedHints)}`, width);
|
|
443
503
|
}
|
|
444
504
|
|
|
445
|
-
private
|
|
446
|
-
|
|
447
|
-
|
|
505
|
+
private createHeaderComponent(): Component {
|
|
506
|
+
return {
|
|
507
|
+
render: (width) => [renderSideThreadHeader(width, this.theme, this.thinkingLevel)],
|
|
508
|
+
invalidate() {},
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
private createTranscriptComponent(): Component {
|
|
513
|
+
return {
|
|
514
|
+
render: (width) => {
|
|
515
|
+
const lines = renderTranscriptLines(this.transcriptComponents, width);
|
|
516
|
+
this.lastContentLineCount = lines.length;
|
|
517
|
+
return lines;
|
|
518
|
+
},
|
|
519
|
+
invalidate: () => {
|
|
520
|
+
for (const component of this.transcriptComponents) component.invalidate();
|
|
521
|
+
},
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
private createSteeringComponent(): Component {
|
|
526
|
+
return {
|
|
527
|
+
render: (width) =>
|
|
528
|
+
renderSteeringLines(
|
|
529
|
+
this.options.steering?.questions ?? [],
|
|
530
|
+
width,
|
|
531
|
+
this.theme,
|
|
532
|
+
MAX_STEERING_DISPLAY_LINES,
|
|
533
|
+
),
|
|
534
|
+
invalidate() {},
|
|
535
|
+
};
|
|
448
536
|
}
|
|
449
537
|
|
|
450
|
-
private
|
|
451
|
-
|
|
538
|
+
private createFooterComponent(): Component {
|
|
539
|
+
return {
|
|
540
|
+
render: (width) => [this.renderFooter(width)],
|
|
541
|
+
invalidate: () => this.loader.invalidate(),
|
|
542
|
+
};
|
|
452
543
|
}
|
|
453
544
|
|
|
454
545
|
private getMaxScrollOffset(): number {
|
|
455
|
-
return Math.max(0, this.lastContentLineCount - this.
|
|
546
|
+
return Math.max(0, this.lastContentLineCount - this.scrollView.viewportHeight);
|
|
456
547
|
}
|
|
457
548
|
}
|
|
458
549
|
|