@selesai/code 0.6.3 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -1
- package/README.md +5 -3
- package/dist/bun/cli.d.ts +0 -1
- package/dist/bun/cli.js +0 -1
- package/dist/bun/register-bedrock.d.ts +0 -1
- package/dist/bun/register-bedrock.js +0 -1
- package/dist/bun/restore-sandbox-env.d.ts +0 -1
- package/dist/bun/restore-sandbox-env.js +0 -1
- package/dist/cli/args.d.ts +0 -1
- package/dist/cli/args.js +0 -1
- package/dist/cli/config-selector.d.ts +0 -1
- package/dist/cli/config-selector.js +0 -1
- package/dist/cli/credential-print.d.ts +0 -1
- package/dist/cli/credential-print.js +0 -1
- package/dist/cli/file-processor.d.ts +0 -1
- package/dist/cli/file-processor.js +0 -1
- package/dist/cli/initial-message.d.ts +0 -1
- package/dist/cli/initial-message.js +0 -1
- package/dist/cli/list-models.d.ts +0 -1
- package/dist/cli/list-models.js +0 -1
- package/dist/cli/project-trust.d.ts +0 -1
- package/dist/cli/project-trust.js +0 -1
- package/dist/cli/session-picker.d.ts +0 -1
- package/dist/cli/session-picker.js +0 -1
- package/dist/cli/startup-ui.d.ts +0 -1
- package/dist/cli/startup-ui.js +0 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +0 -1
- package/dist/config.d.ts +0 -1
- package/dist/config.js +0 -1
- package/dist/core/agent-session-auto-handoff.test.d.ts +0 -1
- package/dist/core/agent-session-auto-handoff.test.js +0 -1
- package/dist/core/agent-session-runtime.d.ts +0 -1
- package/dist/core/agent-session-runtime.js +0 -1
- package/dist/core/agent-session-services.d.ts +0 -1
- package/dist/core/agent-session-services.js +0 -1
- package/dist/core/agent-session-skill-block.test.d.ts +0 -1
- package/dist/core/agent-session-skill-block.test.js +0 -1
- package/dist/core/agent-session.d.ts +0 -1
- package/dist/core/agent-session.js +0 -1
- package/dist/core/agents.d.ts +0 -1
- package/dist/core/agents.js +0 -1
- package/dist/core/auth-guidance.d.ts +0 -1
- package/dist/core/auth-guidance.js +0 -1
- package/dist/core/auth-storage.d.ts +0 -1
- package/dist/core/auth-storage.js +0 -1
- package/dist/core/bash-executor.d.ts +0 -1
- package/dist/core/bash-executor.js +0 -1
- package/dist/core/built-in-extensions.d.ts +0 -1
- package/dist/core/built-in-extensions.js +0 -1
- package/dist/core/cache-stats.d.ts +0 -1
- package/dist/core/cache-stats.js +0 -1
- package/dist/core/compaction/branch-summarization.d.ts +0 -1
- package/dist/core/compaction/branch-summarization.js +0 -1
- package/dist/core/compaction/compaction.d.ts +0 -1
- package/dist/core/compaction/compaction.js +0 -1
- package/dist/core/compaction/index.d.ts +0 -1
- package/dist/core/compaction/index.js +0 -1
- package/dist/core/compaction/utils.d.ts +0 -1
- package/dist/core/compaction/utils.js +0 -1
- package/dist/core/defaults.d.ts +0 -1
- package/dist/core/defaults.js +0 -1
- package/dist/core/diagnostics.d.ts +0 -1
- package/dist/core/diagnostics.js +0 -1
- package/dist/core/event-bus.d.ts +0 -1
- package/dist/core/event-bus.js +0 -1
- package/dist/core/exec.d.ts +0 -1
- package/dist/core/exec.js +0 -1
- package/dist/core/experimental.d.ts +0 -1
- package/dist/core/experimental.js +0 -1
- package/dist/core/export-html/ansi-to-html.d.ts +0 -1
- package/dist/core/export-html/ansi-to-html.js +0 -1
- package/dist/core/export-html/index.d.ts +0 -1
- package/dist/core/export-html/index.js +0 -1
- package/dist/core/export-html/tool-renderer.d.ts +0 -1
- package/dist/core/export-html/tool-renderer.js +0 -1
- package/dist/core/extensions/index.d.ts +0 -1
- package/dist/core/extensions/index.js +0 -1
- package/dist/core/extensions/loader.d.ts +0 -1
- package/dist/core/extensions/loader.js +0 -1
- package/dist/core/extensions/runner.d.ts +0 -1
- package/dist/core/extensions/runner.js +0 -1
- package/dist/core/extensions/types.d.ts +0 -1
- package/dist/core/extensions/types.js +0 -1
- package/dist/core/extensions/wrapper.d.ts +0 -1
- package/dist/core/extensions/wrapper.js +0 -1
- package/dist/core/footer-data-provider.d.ts +0 -1
- package/dist/core/footer-data-provider.js +0 -1
- package/dist/core/git-command.d.ts +0 -1
- package/dist/core/git-command.js +0 -1
- package/dist/core/http-dispatcher.d.ts +0 -1
- package/dist/core/http-dispatcher.js +0 -1
- package/dist/core/index.d.ts +0 -1
- package/dist/core/index.js +0 -1
- package/dist/core/keybindings.d.ts +0 -1
- package/dist/core/keybindings.js +0 -1
- package/dist/core/llama/client.d.ts +0 -1
- package/dist/core/llama/client.js +0 -1
- package/dist/core/llama/huggingface.d.ts +0 -1
- package/dist/core/llama/huggingface.js +0 -1
- package/dist/core/llama/index.d.ts +0 -1
- package/dist/core/llama/index.js +0 -1
- package/dist/core/llama/provider.d.ts +0 -1
- package/dist/core/llama/provider.js +0 -1
- package/dist/core/llama/ui.d.ts +0 -1
- package/dist/core/llama/ui.js +0 -1
- package/dist/core/messages.d.ts +0 -1
- package/dist/core/messages.js +0 -1
- package/dist/core/model-config.d.ts +0 -1
- package/dist/core/model-config.js +0 -1
- package/dist/core/model-registry.d.ts +0 -1
- package/dist/core/model-registry.js +0 -1
- package/dist/core/model-resolver.d.ts +0 -1
- package/dist/core/model-resolver.js +0 -1
- package/dist/core/model-runtime.d.ts +0 -1
- package/dist/core/model-runtime.js +0 -1
- package/dist/core/models-store.d.ts +0 -1
- package/dist/core/models-store.js +0 -1
- package/dist/core/output-guard.d.ts +0 -1
- package/dist/core/output-guard.js +0 -1
- package/dist/core/package-manager.d.ts +0 -1
- package/dist/core/package-manager.js +0 -1
- package/dist/core/package-manager.test.d.ts +0 -1
- package/dist/core/package-manager.test.js +0 -1
- package/dist/core/project-trust.d.ts +0 -1
- package/dist/core/project-trust.js +0 -1
- package/dist/core/prompt-templates.d.ts +0 -1
- package/dist/core/prompt-templates.js +0 -1
- package/dist/core/provider-attribution.d.ts +0 -1
- package/dist/core/provider-attribution.js +0 -1
- package/dist/core/provider-composer.d.ts +0 -1
- package/dist/core/provider-composer.js +0 -1
- package/dist/core/radius.d.ts +0 -1
- package/dist/core/radius.js +0 -1
- package/dist/core/remote-catalog-provider.d.ts +0 -1
- package/dist/core/remote-catalog-provider.js +0 -1
- package/dist/core/resolve-config-value.d.ts +0 -1
- package/dist/core/resolve-config-value.js +0 -1
- package/dist/core/resource-loader.d.ts +0 -1
- package/dist/core/resource-loader.js +0 -1
- package/dist/core/runtime-credentials.d.ts +0 -1
- package/dist/core/runtime-credentials.js +0 -1
- package/dist/core/sdk.d.ts +0 -1
- package/dist/core/sdk.js +0 -1
- package/dist/core/session-cwd.d.ts +0 -1
- package/dist/core/session-cwd.js +0 -1
- package/dist/core/session-manager.d.ts +0 -1
- package/dist/core/session-manager.js +0 -1
- package/dist/core/settings-manager-auto-handoff.test.d.ts +0 -1
- package/dist/core/settings-manager-auto-handoff.test.js +0 -1
- package/dist/core/settings-manager.d.ts +0 -4
- package/dist/core/settings-manager.js +0 -12
- package/dist/core/skills.d.ts +0 -1
- package/dist/core/skills.js +0 -1
- package/dist/core/slash-commands.d.ts +0 -1
- package/dist/core/slash-commands.js +0 -1
- package/dist/core/source-info.d.ts +0 -1
- package/dist/core/source-info.js +0 -1
- package/dist/core/system-prompt.d.ts +0 -1
- package/dist/core/system-prompt.js +0 -1
- package/dist/core/system-prompt.test.d.ts +0 -1
- package/dist/core/system-prompt.test.js +0 -1
- package/dist/core/telemetry.d.ts +0 -1
- package/dist/core/telemetry.js +0 -1
- package/dist/core/timings.d.ts +0 -1
- package/dist/core/timings.js +0 -1
- package/dist/core/tools/bash.d.ts +0 -1
- package/dist/core/tools/bash.js +0 -1
- package/dist/core/tools/edit-diff.d.ts +0 -1
- package/dist/core/tools/edit-diff.js +0 -1
- package/dist/core/tools/edit.d.ts +0 -1
- package/dist/core/tools/edit.js +0 -1
- package/dist/core/tools/file-mutation-queue.d.ts +0 -1
- package/dist/core/tools/file-mutation-queue.js +0 -1
- package/dist/core/tools/find.d.ts +0 -1
- package/dist/core/tools/find.js +0 -1
- package/dist/core/tools/grep.d.ts +0 -1
- package/dist/core/tools/grep.js +0 -1
- package/dist/core/tools/index.d.ts +0 -1
- package/dist/core/tools/index.js +0 -1
- package/dist/core/tools/ls.d.ts +0 -1
- package/dist/core/tools/ls.js +0 -1
- package/dist/core/tools/output-accumulator.d.ts +0 -1
- package/dist/core/tools/output-accumulator.js +0 -1
- package/dist/core/tools/path-utils.d.ts +0 -1
- package/dist/core/tools/path-utils.js +0 -1
- package/dist/core/tools/read.d.ts +0 -1
- package/dist/core/tools/read.js +0 -1
- package/dist/core/tools/render-utils.d.ts +0 -1
- package/dist/core/tools/render-utils.js +0 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts +0 -1
- package/dist/core/tools/tool-definition-wrapper.js +0 -1
- package/dist/core/tools/truncate.d.ts +0 -1
- package/dist/core/tools/truncate.js +0 -1
- package/dist/core/tools/write.d.ts +0 -1
- package/dist/core/tools/write.js +0 -1
- package/dist/core/trust-manager.d.ts +0 -1
- package/dist/core/trust-manager.js +0 -1
- package/dist/core/usage-totals.d.ts +0 -1
- package/dist/core/usage-totals.js +0 -1
- package/dist/defaults/models.json +8 -0
- package/dist/defaults/settings.json +6 -7
- package/dist/extensions/agent-browser.test.ts +195 -0
- package/dist/extensions/agent-browser.ts +158 -0
- package/dist/extensions/inline-skills.test.ts +27 -13
- package/dist/extensions/inline-skills.ts +18 -11
- package/dist/extensions/package.json +2 -1
- package/dist/extensions/pi-powerline-footer/.github/workflows/test.yml +27 -0
- package/dist/extensions/pi-powerline-footer/CHANGELOG.md +153 -0
- package/dist/extensions/pi-powerline-footer/CONTRIBUTING.md +16 -0
- package/dist/extensions/pi-powerline-footer/README.md +192 -44
- package/dist/extensions/pi-powerline-footer/bash-mode/completion.ts +19 -4
- package/dist/extensions/pi-powerline-footer/bash-mode/editor.ts +80 -25
- package/dist/extensions/pi-powerline-footer/bash-mode/history.ts +81 -29
- package/dist/extensions/pi-powerline-footer/bash-mode/types.ts +1 -1
- package/dist/extensions/pi-powerline-footer/cd-command.ts +190 -0
- package/dist/extensions/pi-powerline-footer/colors.ts +2 -1
- package/dist/extensions/pi-powerline-footer/context-usage.ts +121 -6
- package/dist/extensions/pi-powerline-footer/currency-rates.ts +142 -0
- package/dist/extensions/pi-powerline-footer/editor-composition.ts +32 -0
- package/dist/extensions/pi-powerline-footer/git-status.ts +108 -6
- package/dist/extensions/pi-powerline-footer/icons.ts +11 -2
- package/dist/extensions/pi-powerline-footer/index.ts +1056 -324
- package/dist/extensions/pi-powerline-footer/lifecycle.ts +10 -0
- package/dist/extensions/pi-powerline-footer/package.json +10 -6
- package/dist/extensions/pi-powerline-footer/paths.ts +22 -0
- package/dist/extensions/pi-powerline-footer/powerline-config.ts +297 -15
- package/dist/extensions/pi-powerline-footer/presets.ts +6 -25
- package/dist/extensions/pi-powerline-footer/queue/store.ts +361 -0
- package/dist/extensions/pi-powerline-footer/queue/types.ts +54 -0
- package/dist/extensions/pi-powerline-footer/render-scheduler.ts +12 -7
- package/dist/extensions/pi-powerline-footer/segments.ts +114 -107
- package/dist/extensions/pi-powerline-footer/session-usage.ts +1 -1
- package/dist/extensions/pi-powerline-footer/shortcuts.ts +17 -3
- package/dist/extensions/pi-powerline-footer/tests/bash-mode.test.ts +189 -17
- package/dist/extensions/pi-powerline-footer/tests/cd-command.test.ts +144 -0
- package/dist/extensions/pi-powerline-footer/tests/context-usage.test.ts +120 -2
- package/dist/extensions/pi-powerline-footer/tests/custom-items.test.ts +245 -22
- package/dist/extensions/pi-powerline-footer/tests/editor-composition.test.ts +48 -0
- package/dist/extensions/pi-powerline-footer/tests/editor-responsiveness.test.ts +34 -0
- package/dist/extensions/pi-powerline-footer/tests/fixed-editor-border.test.ts +39 -0
- package/dist/extensions/pi-powerline-footer/tests/git-status.test.ts +92 -0
- package/dist/extensions/pi-powerline-footer/tests/guide.test.ts +4 -1
- package/dist/extensions/pi-powerline-footer/tests/jump-shortcuts.test.ts +33 -197
- package/dist/extensions/pi-powerline-footer/tests/mode-aware-trigger.test.ts +79 -0
- package/dist/extensions/pi-powerline-footer/tests/paths.test.ts +63 -0
- package/dist/extensions/pi-powerline-footer/tests/queue-store.test.ts +195 -0
- package/dist/extensions/pi-powerline-footer/tests/quit-cursor.test.ts +14 -0
- package/dist/extensions/pi-powerline-footer/tests/remaining-regressions.test.ts +167 -0
- package/dist/extensions/pi-powerline-footer/tests/stash-shortcut.test.ts +23 -18
- package/dist/extensions/pi-powerline-footer/tests/thinking-segment.test.ts +16 -1
- package/dist/extensions/pi-powerline-footer/tests/token-stats.test.ts +249 -0
- package/dist/extensions/pi-powerline-footer/tests/usage-display.test.ts +237 -0
- package/dist/extensions/pi-powerline-footer/tests/welcome.test.ts +199 -0
- package/dist/extensions/pi-powerline-footer/tests/working-vibes.test.ts +191 -100
- package/dist/extensions/pi-powerline-footer/theme.ts +32 -18
- package/dist/extensions/pi-powerline-footer/token-stats.ts +304 -0
- package/dist/extensions/pi-powerline-footer/tsconfig.json +13 -0
- package/dist/extensions/pi-powerline-footer/types.ts +74 -29
- package/dist/extensions/pi-powerline-footer/welcome-dismiss.ts +34 -0
- package/dist/extensions/pi-powerline-footer/welcome.ts +65 -10
- package/dist/extensions/pi-powerline-footer/working-vibes.ts +44 -11
- package/dist/extensions/pi-subagents/CHANGELOG.md +89 -12
- package/dist/extensions/pi-subagents/README.md +339 -604
- package/dist/extensions/pi-subagents/package-lock.json +190 -2079
- package/dist/extensions/pi-subagents/package.json +13 -5
- package/dist/extensions/pi-subagents/prompts/parallel-context-build.md +1 -1
- package/dist/extensions/pi-subagents/prompts/parallel-handoff-plan.md +1 -1
- package/dist/extensions/pi-subagents/prompts/review-loop.md +1 -1
- package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +10 -10
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +32 -43
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +106 -105
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +3 -3
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +28 -35
- package/dist/extensions/pi-subagents/src/agents/agent-management.ts +167 -124
- package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +19 -0
- package/dist/extensions/pi-subagents/src/agents/agents.ts +163 -75
- package/dist/extensions/pi-subagents/src/agents/chain-serializer.ts +10 -7
- package/dist/extensions/pi-subagents/src/agents/frontmatter.ts +5 -3
- package/dist/extensions/pi-subagents/src/agents/identity.ts +1 -1
- package/dist/extensions/pi-subagents/src/agents/proactive-skills.ts +14 -11
- package/dist/extensions/pi-subagents/src/agents/skills.ts +23 -6
- package/dist/extensions/pi-subagents/src/agents/task-aware-routing.ts +8 -1
- package/dist/extensions/pi-subagents/src/api/control-channel.ts +4 -0
- package/dist/extensions/pi-subagents/src/api/delegation.ts +26 -194
- package/dist/extensions/pi-subagents/src/api/external-runs.ts +129 -0
- package/dist/extensions/pi-subagents/src/api/intercom-bridge.ts +3 -0
- package/dist/extensions/pi-subagents/src/api/pi-args.ts +5 -0
- package/dist/extensions/pi-subagents/src/api/preflight.ts +4 -4
- package/dist/extensions/pi-subagents/src/api/shared-types.ts +19 -0
- package/dist/extensions/pi-subagents/src/extension/config.ts +10 -0
- package/dist/extensions/pi-subagents/src/extension/control-notices.ts +5 -39
- package/dist/extensions/pi-subagents/src/extension/doctor.ts +10 -9
- package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +7 -4
- package/dist/extensions/pi-subagents/src/extension/index.ts +243 -77
- package/dist/extensions/pi-subagents/src/extension/rpc.ts +18 -6
- package/dist/extensions/pi-subagents/src/extension/schemas.ts +50 -39
- package/dist/extensions/pi-subagents/src/extension/tool-description.ts +36 -103
- package/dist/extensions/pi-subagents/src/inspectors/herdr/actions.ts +229 -0
- package/dist/extensions/pi-subagents/src/inspectors/herdr/client.ts +130 -0
- package/dist/extensions/pi-subagents/src/inspectors/herdr/inspector-runner.ts +141 -0
- package/dist/extensions/pi-subagents/src/inspectors/herdr/project-panes.ts +154 -0
- package/dist/extensions/pi-subagents/src/integrations/herdr-status.ts +330 -0
- package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +3 -2
- package/dist/extensions/pi-subagents/src/intercom/result-intercom.ts +5 -1
- package/dist/extensions/pi-subagents/src/missions/actions.ts +372 -0
- package/dist/extensions/pi-subagents/src/missions/lifecycle.ts +314 -0
- package/dist/extensions/pi-subagents/src/missions/store.ts +442 -0
- package/dist/extensions/pi-subagents/src/missions/types.ts +135 -0
- package/dist/extensions/pi-subagents/src/policy/authority.ts +46 -0
- package/dist/extensions/pi-subagents/src/profiles/profiles.ts +32 -6
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +103 -72
- package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +10 -2
- package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +6 -6
- package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +29 -1
- package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +3 -3
- package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +3 -2
- package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +9 -7
- package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +3 -4
- package/dist/extensions/pi-subagents/src/runs/background/notify.ts +3 -28
- package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +5 -5
- package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +18 -68
- package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +3 -3
- package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +35 -8
- package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +602 -375
- package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +3 -3
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +612 -464
- package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +50 -9
- package/dist/extensions/pi-subagents/src/runs/background/wait-subscriptions.ts +253 -0
- package/dist/extensions/pi-subagents/src/runs/background/wait-tool.ts +12 -4
- package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +3 -3
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-clarify.ts +8 -4
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +74 -102
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +21 -22
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +1050 -396
- package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +44 -18
- package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +0 -1
- package/dist/extensions/pi-subagents/src/runs/shared/child-protocol.ts +302 -22
- package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/shared/external-cli-runner.ts +130 -0
- package/dist/extensions/pi-subagents/src/runs/shared/long-running-guard.ts +42 -1
- package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +59 -5
- package/dist/extensions/pi-subagents/src/runs/shared/nested-render.ts +9 -4
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +86 -2
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +11 -2
- package/dist/extensions/pi-subagents/src/runs/shared/permissions.ts +95 -0
- package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +11 -1
- package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +15 -6
- package/dist/extensions/pi-subagents/src/runs/shared/run-history.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +9 -63
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +37 -6
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-startup-retry.ts +5 -2
- package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +2 -23
- package/dist/extensions/pi-subagents/src/runs/shared/turn-budget.ts +6 -6
- package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +124 -13
- package/dist/extensions/pi-subagents/src/shared/accessible-dir.ts +29 -7
- package/dist/extensions/pi-subagents/src/shared/artifacts.ts +18 -1
- package/dist/extensions/pi-subagents/src/shared/fork-context.ts +3 -2
- package/dist/extensions/pi-subagents/src/shared/launch-contract.ts +1 -0
- package/dist/extensions/pi-subagents/src/shared/settings.ts +10 -0
- package/dist/extensions/pi-subagents/src/shared/types.ts +158 -55
- package/dist/extensions/pi-subagents/src/shared/utils.ts +16 -66
- package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +33 -199
- package/dist/extensions/pi-subagents/src/slash/delegation-request.ts +43 -126
- package/dist/extensions/pi-subagents/src/slash/inline-subagents.ts +136 -0
- package/dist/extensions/pi-subagents/src/slash/prompt-template-bridge.ts +158 -205
- package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +22 -58
- package/dist/extensions/pi-subagents/src/slash/slash-bridge.ts +14 -0
- package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +44 -642
- package/dist/extensions/pi-subagents/src/slash/subagents-admin.ts +18 -14
- package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +156 -21
- package/dist/extensions/pi-subagents/src/tui/fleet-transcript.ts +110 -5
- package/dist/extensions/pi-subagents/src/tui/fleet.ts +60 -24
- package/dist/extensions/pi-subagents/src/tui/render.ts +296 -140
- package/dist/extensions/pi-subagents/src/types/pi-runtime-compat.d.ts +14 -0
- package/dist/extensions/pi-subagents/src/watchdog/change-signature.ts +1 -1
- package/dist/extensions/pi-subagents/src/watchdog/lsp-diagnostics.ts +13 -7
- package/dist/extensions/pi-subagents/src/watchdog/model-selection.ts +2 -2
- package/dist/extensions/pi-subagents/src/watchdog/permission-arbiter.ts +145 -0
- package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +1 -1
- package/dist/extensions/pi-subagents/src/watchdog/register-main.ts +1 -1
- package/dist/extensions/pi-subagents/src/watchdog/review.ts +4 -1
- package/dist/extensions/pi-subagents/src/watchdog/runtime.ts +3 -2
- package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +140 -0
- package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +415 -0
- package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +41 -144
- package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +16 -16
- package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +415 -298
- package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +149 -82
- package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +40 -40
- package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +15 -15
- package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +193 -133
- package/dist/extensions/pi-subagents/test/integration/detect-error.test.ts +1 -49
- package/dist/extensions/pi-subagents/test/integration/external-cli-runner.test.ts +62 -0
- package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +56 -58
- package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +81 -68
- package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +20 -25
- package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +425 -317
- package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +73 -73
- package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +123 -98
- package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +653 -240
- package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +20 -1661
- package/dist/extensions/pi-subagents/test/integration/slash-live-state.test.ts +9 -9
- package/dist/extensions/pi-subagents/test/integration/template-resolution.test.ts +3 -3
- package/dist/extensions/pi-subagents/test/integration/top-level-async.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +8 -5
- package/dist/extensions/pi-subagents/test/support/mock-pi.ts +6 -6
- package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +4 -20
- package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +25 -4
- package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +280 -295
- package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +47 -207
- package/dist/extensions/pi-subagents/test/unit/agent-memory.test.ts +26 -26
- package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +89 -89
- package/dist/extensions/pi-subagents/test/unit/agent-selection.test.ts +9 -9
- package/dist/extensions/pi-subagents/test/unit/artifacts.test.ts +10 -0
- package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +33 -9
- package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +24 -2
- package/dist/extensions/pi-subagents/test/unit/async-permission-session.test.ts +11 -9
- package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +40 -40
- package/dist/extensions/pi-subagents/test/unit/authority-policy.test.ts +22 -0
- package/dist/extensions/pi-subagents/test/unit/background-work.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +5 -39
- package/dist/extensions/pi-subagents/test/unit/chain-append.test.ts +19 -19
- package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +9 -9
- package/dist/extensions/pi-subagents/test/unit/chain-serializer.test.ts +20 -20
- package/dist/extensions/pi-subagents/test/unit/child-protocol.test.ts +99 -0
- package/dist/extensions/pi-subagents/test/unit/child-transcript.test.ts +9 -9
- package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +41 -0
- package/dist/extensions/pi-subagents/test/unit/completion-dedupe.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +35 -5
- package/dist/extensions/pi-subagents/test/unit/config-dir-runtime.test.ts +7 -0
- package/dist/extensions/pi-subagents/test/unit/control-notices.test.ts +16 -82
- package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +162 -620
- package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +25 -25
- package/dist/extensions/pi-subagents/test/unit/ensure-accessible-dir.test.ts +125 -0
- package/dist/extensions/pi-subagents/test/unit/external-cli-runner.test.ts +94 -0
- package/dist/extensions/pi-subagents/test/unit/external-runs.test.ts +66 -0
- package/dist/extensions/pi-subagents/test/unit/extra-agent-dirs.test.ts +3 -3
- package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +242 -52
- package/dist/extensions/pi-subagents/test/unit/fleet-transcript.test.ts +127 -0
- package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +197 -36
- package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +4 -4
- package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +245 -0
- package/dist/extensions/pi-subagents/test/unit/herdr-status-bridge.test.ts +494 -0
- package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +261 -31
- package/dist/extensions/pi-subagents/test/unit/inline-subagents.test.ts +127 -0
- package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +6 -6
- package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +217 -0
- package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +182 -0
- package/dist/extensions/pi-subagents/test/unit/mock-pi.test.ts +22 -0
- package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +10 -10
- package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +20 -12
- package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +47 -5
- package/dist/extensions/pi-subagents/test/unit/notify.test.ts +49 -55
- package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +20 -3
- package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +37 -7
- package/dist/extensions/pi-subagents/test/unit/parallel-utils.test.ts +10 -10
- package/dist/extensions/pi-subagents/test/unit/path-handling.test.ts +3 -3
- package/dist/extensions/pi-subagents/test/unit/permissions.test.ts +46 -0
- package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +31 -10
- package/dist/extensions/pi-subagents/test/unit/pi-spawn.test.ts +40 -16
- package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +42 -44
- package/dist/extensions/pi-subagents/test/unit/proactive-skills.test.ts +13 -13
- package/dist/extensions/pi-subagents/test/unit/process-terminal.test.ts +4 -4
- package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +75 -9
- package/dist/extensions/pi-subagents/test/unit/prompt-template-bridge.test.ts +20 -84
- package/dist/extensions/pi-subagents/test/unit/prompt-workflows.test.ts +15 -16
- package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +28 -28
- package/dist/extensions/pi-subagents/test/unit/result-intercom.test.ts +19 -12
- package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +37 -21
- package/dist/extensions/pi-subagents/test/unit/run-id-resolver.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +50 -50
- package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +396 -433
- package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +76 -153
- package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +411 -0
- package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +1 -91
- package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +139 -0
- package/dist/extensions/pi-subagents/test/unit/slash-bridge.test.ts +29 -0
- package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +13 -13
- package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/steering.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +35 -35
- package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +53 -18
- package/dist/extensions/pi-subagents/test/unit/subagent-startup-retry.test.ts +13 -1
- package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +44 -11
- package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +2 -26
- package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +24 -148
- package/dist/extensions/pi-subagents/test/unit/turn-budget.test.ts +11 -9
- package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +351 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-child-status.test.ts +13 -13
- package/dist/extensions/pi-subagents/test/unit/watchdog-lsp-diagnostics.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/watchdog-permission-arbiter.test.ts +79 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-runtime.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/watchdog-settings.test.ts +8 -8
- package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +45 -9
- package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +197 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-graph.test.ts +8 -8
- package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +142 -12
- package/dist/extensions/pi-subagents/tsconfig.json +15 -0
- package/dist/extensions/ponytail/index.js +1 -31
- package/dist/extensions/ponytail/test/extension.test.js +5 -22
- package/dist/extensions/rtk.test.ts +141 -0
- package/dist/extensions/rtk.ts +78 -36
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/main.d.ts +0 -1
- package/dist/main.js +0 -1
- package/dist/migrations.d.ts +0 -1
- package/dist/migrations.js +0 -1
- package/dist/modes/index.d.ts +0 -1
- package/dist/modes/index.js +0 -1
- package/dist/modes/interactive/components/armin.d.ts +0 -1
- package/dist/modes/interactive/components/armin.js +0 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +0 -1
- package/dist/modes/interactive/components/assistant-message.js +0 -1
- package/dist/modes/interactive/components/bash-execution.d.ts +0 -1
- package/dist/modes/interactive/components/bash-execution.js +0 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts +0 -1
- package/dist/modes/interactive/components/bordered-loader.js +0 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts +0 -1
- package/dist/modes/interactive/components/branch-summary-message.js +0 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +0 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +0 -1
- package/dist/modes/interactive/components/config-selector.d.ts +0 -1
- package/dist/modes/interactive/components/config-selector.js +0 -1
- package/dist/modes/interactive/components/countdown-timer.d.ts +0 -1
- package/dist/modes/interactive/components/countdown-timer.js +0 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +0 -1
- package/dist/modes/interactive/components/custom-editor.js +0 -1
- package/dist/modes/interactive/components/custom-entry.d.ts +0 -1
- package/dist/modes/interactive/components/custom-entry.js +0 -1
- package/dist/modes/interactive/components/custom-message.d.ts +0 -1
- package/dist/modes/interactive/components/custom-message.js +0 -1
- package/dist/modes/interactive/components/daxnuts.d.ts +0 -1
- package/dist/modes/interactive/components/daxnuts.js +0 -1
- package/dist/modes/interactive/components/diff.d.ts +0 -1
- package/dist/modes/interactive/components/diff.js +0 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts +0 -1
- package/dist/modes/interactive/components/dynamic-border.js +0 -1
- package/dist/modes/interactive/components/earendil-announcement.d.ts +0 -1
- package/dist/modes/interactive/components/earendil-announcement.js +0 -1
- package/dist/modes/interactive/components/extension-editor.d.ts +0 -1
- package/dist/modes/interactive/components/extension-editor.js +0 -1
- package/dist/modes/interactive/components/extension-input.d.ts +0 -1
- package/dist/modes/interactive/components/extension-input.js +0 -1
- package/dist/modes/interactive/components/extension-selector.d.ts +0 -1
- package/dist/modes/interactive/components/extension-selector.js +0 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts +0 -1
- package/dist/modes/interactive/components/first-time-setup.js +0 -1
- package/dist/modes/interactive/components/footer.d.ts +0 -1
- package/dist/modes/interactive/components/footer.js +0 -1
- package/dist/modes/interactive/components/index.d.ts +0 -1
- package/dist/modes/interactive/components/index.js +0 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts +0 -1
- package/dist/modes/interactive/components/keybinding-hints.js +0 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +0 -1
- package/dist/modes/interactive/components/login-dialog.js +0 -1
- package/dist/modes/interactive/components/model-selector.d.ts +0 -1
- package/dist/modes/interactive/components/model-selector.js +0 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts +0 -1
- package/dist/modes/interactive/components/oauth-selector.js +0 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +0 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +0 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts +0 -1
- package/dist/modes/interactive/components/session-selector-search.js +0 -1
- package/dist/modes/interactive/components/session-selector.d.ts +0 -1
- package/dist/modes/interactive/components/session-selector.js +0 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +0 -3
- package/dist/modes/interactive/components/settings-selector.js +1 -14
- package/dist/modes/interactive/components/show-images-selector.d.ts +0 -1
- package/dist/modes/interactive/components/show-images-selector.js +0 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts +0 -1
- package/dist/modes/interactive/components/skill-invocation-message.js +0 -1
- package/dist/modes/interactive/components/status-indicator.d.ts +0 -1
- package/dist/modes/interactive/components/status-indicator.js +0 -1
- package/dist/modes/interactive/components/theme-selector.d.ts +0 -1
- package/dist/modes/interactive/components/theme-selector.js +0 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts +0 -1
- package/dist/modes/interactive/components/thinking-selector.js +0 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +0 -1
- package/dist/modes/interactive/components/tool-execution.js +0 -1
- package/dist/modes/interactive/components/tree-selector.d.ts +0 -1
- package/dist/modes/interactive/components/tree-selector.js +0 -1
- package/dist/modes/interactive/components/trust-selector.d.ts +0 -1
- package/dist/modes/interactive/components/trust-selector.js +0 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts +0 -1
- package/dist/modes/interactive/components/user-message-selector.js +0 -1
- package/dist/modes/interactive/components/user-message.d.ts +0 -1
- package/dist/modes/interactive/components/user-message.js +0 -1
- package/dist/modes/interactive/components/visual-truncate.d.ts +0 -1
- package/dist/modes/interactive/components/visual-truncate.js +0 -1
- package/dist/modes/interactive/external-editor.d.ts +0 -1
- package/dist/modes/interactive/external-editor.js +0 -1
- package/dist/modes/interactive/interactive-mode.d.ts +0 -2
- package/dist/modes/interactive/interactive-mode.js +1 -22
- package/dist/modes/interactive/model-search.d.ts +0 -1
- package/dist/modes/interactive/model-search.js +0 -1
- package/dist/modes/interactive/theme/theme-controller.d.ts +0 -1
- package/dist/modes/interactive/theme/theme-controller.js +0 -1
- package/dist/modes/interactive/theme/theme.d.ts +0 -1
- package/dist/modes/interactive/theme/theme.js +0 -1
- package/dist/modes/print-mode.d.ts +0 -1
- package/dist/modes/print-mode.js +0 -1
- package/dist/modes/rpc/jsonl.d.ts +0 -1
- package/dist/modes/rpc/jsonl.js +0 -1
- package/dist/modes/rpc/rpc-client.d.ts +1 -2
- package/dist/modes/rpc/rpc-client.js +1 -2
- package/dist/modes/rpc/rpc-mode.d.ts +0 -1
- package/dist/modes/rpc/rpc-mode.js +0 -9
- package/dist/modes/rpc/rpc-types.d.ts +0 -1
- package/dist/modes/rpc/rpc-types.js +0 -1
- package/dist/package-manager-cli.d.ts +0 -1
- package/dist/package-manager-cli.js +0 -1
- package/dist/rpc-entry.d.ts +0 -1
- package/dist/rpc-entry.js +0 -1
- package/dist/utils/ansi.d.ts +0 -1
- package/dist/utils/ansi.js +0 -1
- package/dist/utils/changelog.d.ts +0 -1
- package/dist/utils/changelog.js +0 -1
- package/dist/utils/child-process.d.ts +0 -1
- package/dist/utils/child-process.js +0 -1
- package/dist/utils/clipboard-image.d.ts +0 -1
- package/dist/utils/clipboard-image.js +0 -1
- package/dist/utils/clipboard-native.d.ts +0 -1
- package/dist/utils/clipboard-native.js +0 -1
- package/dist/utils/clipboard.d.ts +0 -1
- package/dist/utils/clipboard.js +0 -1
- package/dist/utils/deprecation.d.ts +0 -1
- package/dist/utils/deprecation.js +0 -1
- package/dist/utils/exif-orientation.d.ts +0 -1
- package/dist/utils/exif-orientation.js +0 -1
- package/dist/utils/frontmatter.d.ts +0 -1
- package/dist/utils/frontmatter.js +0 -1
- package/dist/utils/fs-watch.d.ts +0 -1
- package/dist/utils/fs-watch.js +0 -1
- package/dist/utils/git.d.ts +0 -1
- package/dist/utils/git.js +0 -1
- package/dist/utils/html.d.ts +0 -1
- package/dist/utils/html.js +0 -1
- package/dist/utils/image-convert.d.ts +0 -1
- package/dist/utils/image-convert.js +0 -1
- package/dist/utils/image-process.d.ts +0 -1
- package/dist/utils/image-process.js +0 -1
- package/dist/utils/image-resize-core.d.ts +0 -1
- package/dist/utils/image-resize-core.js +0 -1
- package/dist/utils/image-resize-worker.d.ts +0 -1
- package/dist/utils/image-resize-worker.js +0 -1
- package/dist/utils/image-resize.d.ts +0 -1
- package/dist/utils/image-resize.js +0 -1
- package/dist/utils/json.d.ts +0 -1
- package/dist/utils/json.js +0 -1
- package/dist/utils/mime.d.ts +0 -1
- package/dist/utils/mime.js +0 -1
- package/dist/utils/open-browser.d.ts +0 -1
- package/dist/utils/open-browser.js +0 -1
- package/dist/utils/paths.d.ts +0 -1
- package/dist/utils/paths.js +0 -1
- package/dist/utils/photon.d.ts +0 -1
- package/dist/utils/photon.js +0 -1
- package/dist/utils/pi-user-agent.d.ts +0 -1
- package/dist/utils/pi-user-agent.js +0 -1
- package/dist/utils/shell.d.ts +0 -1
- package/dist/utils/shell.js +0 -1
- package/dist/utils/sleep.d.ts +0 -1
- package/dist/utils/sleep.js +0 -1
- package/dist/utils/syntax-highlight.d.ts +0 -1
- package/dist/utils/syntax-highlight.js +0 -1
- package/dist/utils/thinking-tags.d.ts +0 -1
- package/dist/utils/thinking-tags.js +0 -1
- package/dist/utils/tools-manager.d.ts +3 -3
- package/dist/utils/tools-manager.js +125 -42
- package/dist/utils/version-check.d.ts +0 -1
- package/dist/utils/version-check.js +0 -1
- package/dist/utils/windows-self-update.d.ts +0 -1
- package/dist/utils/windows-self-update.js +0 -1
- package/docs/rpc.md +1 -2
- package/docs/settings.md +0 -1
- package/docs/skills.md +10 -18
- package/package.json +3 -2
- package/dist/bun/cli.d.ts.map +0 -1
- package/dist/bun/cli.js.map +0 -1
- package/dist/bun/register-bedrock.d.ts.map +0 -1
- package/dist/bun/register-bedrock.js.map +0 -1
- package/dist/bun/restore-sandbox-env.d.ts.map +0 -1
- package/dist/bun/restore-sandbox-env.js.map +0 -1
- package/dist/cli/args.d.ts.map +0 -1
- package/dist/cli/args.js.map +0 -1
- package/dist/cli/config-selector.d.ts.map +0 -1
- package/dist/cli/config-selector.js.map +0 -1
- package/dist/cli/credential-print.d.ts.map +0 -1
- package/dist/cli/credential-print.js.map +0 -1
- package/dist/cli/file-processor.d.ts.map +0 -1
- package/dist/cli/file-processor.js.map +0 -1
- package/dist/cli/initial-message.d.ts.map +0 -1
- package/dist/cli/initial-message.js.map +0 -1
- package/dist/cli/list-models.d.ts.map +0 -1
- package/dist/cli/list-models.js.map +0 -1
- package/dist/cli/project-trust.d.ts.map +0 -1
- package/dist/cli/project-trust.js.map +0 -1
- package/dist/cli/session-picker.d.ts.map +0 -1
- package/dist/cli/session-picker.js.map +0 -1
- package/dist/cli/startup-ui.d.ts.map +0 -1
- package/dist/cli/startup-ui.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/core/agent-session-auto-handoff.test.d.ts.map +0 -1
- package/dist/core/agent-session-auto-handoff.test.js.map +0 -1
- package/dist/core/agent-session-runtime.d.ts.map +0 -1
- package/dist/core/agent-session-runtime.js.map +0 -1
- package/dist/core/agent-session-services.d.ts.map +0 -1
- package/dist/core/agent-session-services.js.map +0 -1
- package/dist/core/agent-session-skill-block.test.d.ts.map +0 -1
- package/dist/core/agent-session-skill-block.test.js.map +0 -1
- package/dist/core/agent-session.d.ts.map +0 -1
- package/dist/core/agent-session.js.map +0 -1
- package/dist/core/agents.d.ts.map +0 -1
- package/dist/core/agents.js.map +0 -1
- package/dist/core/auth-guidance.d.ts.map +0 -1
- package/dist/core/auth-guidance.js.map +0 -1
- package/dist/core/auth-storage.d.ts.map +0 -1
- package/dist/core/auth-storage.js.map +0 -1
- package/dist/core/bash-executor.d.ts.map +0 -1
- package/dist/core/bash-executor.js.map +0 -1
- package/dist/core/built-in-extensions.d.ts.map +0 -1
- package/dist/core/built-in-extensions.js.map +0 -1
- package/dist/core/cache-stats.d.ts.map +0 -1
- package/dist/core/cache-stats.js.map +0 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +0 -1
- package/dist/core/compaction/branch-summarization.js.map +0 -1
- package/dist/core/compaction/compaction.d.ts.map +0 -1
- package/dist/core/compaction/compaction.js.map +0 -1
- package/dist/core/compaction/index.d.ts.map +0 -1
- package/dist/core/compaction/index.js.map +0 -1
- package/dist/core/compaction/utils.d.ts.map +0 -1
- package/dist/core/compaction/utils.js.map +0 -1
- package/dist/core/defaults.d.ts.map +0 -1
- package/dist/core/defaults.js.map +0 -1
- package/dist/core/diagnostics.d.ts.map +0 -1
- package/dist/core/diagnostics.js.map +0 -1
- package/dist/core/event-bus.d.ts.map +0 -1
- package/dist/core/event-bus.js.map +0 -1
- package/dist/core/exec.d.ts.map +0 -1
- package/dist/core/exec.js.map +0 -1
- package/dist/core/experimental.d.ts.map +0 -1
- package/dist/core/experimental.js.map +0 -1
- package/dist/core/export-html/ansi-to-html.d.ts.map +0 -1
- package/dist/core/export-html/ansi-to-html.js.map +0 -1
- package/dist/core/export-html/index.d.ts.map +0 -1
- package/dist/core/export-html/index.js.map +0 -1
- package/dist/core/export-html/tool-renderer.d.ts.map +0 -1
- package/dist/core/export-html/tool-renderer.js.map +0 -1
- package/dist/core/extensions/index.d.ts.map +0 -1
- package/dist/core/extensions/index.js.map +0 -1
- package/dist/core/extensions/loader.d.ts.map +0 -1
- package/dist/core/extensions/loader.js.map +0 -1
- package/dist/core/extensions/runner.d.ts.map +0 -1
- package/dist/core/extensions/runner.js.map +0 -1
- package/dist/core/extensions/types.d.ts.map +0 -1
- package/dist/core/extensions/types.js.map +0 -1
- package/dist/core/extensions/wrapper.d.ts.map +0 -1
- package/dist/core/extensions/wrapper.js.map +0 -1
- package/dist/core/footer-data-provider.d.ts.map +0 -1
- package/dist/core/footer-data-provider.js.map +0 -1
- package/dist/core/git-command.d.ts.map +0 -1
- package/dist/core/git-command.js.map +0 -1
- package/dist/core/http-dispatcher.d.ts.map +0 -1
- package/dist/core/http-dispatcher.js.map +0 -1
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js.map +0 -1
- package/dist/core/keybindings.d.ts.map +0 -1
- package/dist/core/keybindings.js.map +0 -1
- package/dist/core/llama/client.d.ts.map +0 -1
- package/dist/core/llama/client.js.map +0 -1
- package/dist/core/llama/huggingface.d.ts.map +0 -1
- package/dist/core/llama/huggingface.js.map +0 -1
- package/dist/core/llama/index.d.ts.map +0 -1
- package/dist/core/llama/index.js.map +0 -1
- package/dist/core/llama/provider.d.ts.map +0 -1
- package/dist/core/llama/provider.js.map +0 -1
- package/dist/core/llama/ui.d.ts.map +0 -1
- package/dist/core/llama/ui.js.map +0 -1
- package/dist/core/messages.d.ts.map +0 -1
- package/dist/core/messages.js.map +0 -1
- package/dist/core/model-config.d.ts.map +0 -1
- package/dist/core/model-config.js.map +0 -1
- package/dist/core/model-registry.d.ts.map +0 -1
- package/dist/core/model-registry.js.map +0 -1
- package/dist/core/model-resolver.d.ts.map +0 -1
- package/dist/core/model-resolver.js.map +0 -1
- package/dist/core/model-runtime.d.ts.map +0 -1
- package/dist/core/model-runtime.js.map +0 -1
- package/dist/core/models-store.d.ts.map +0 -1
- package/dist/core/models-store.js.map +0 -1
- package/dist/core/output-guard.d.ts.map +0 -1
- package/dist/core/output-guard.js.map +0 -1
- package/dist/core/package-manager.d.ts.map +0 -1
- package/dist/core/package-manager.js.map +0 -1
- package/dist/core/package-manager.test.d.ts.map +0 -1
- package/dist/core/package-manager.test.js.map +0 -1
- package/dist/core/project-trust.d.ts.map +0 -1
- package/dist/core/project-trust.js.map +0 -1
- package/dist/core/prompt-templates.d.ts.map +0 -1
- package/dist/core/prompt-templates.js.map +0 -1
- package/dist/core/provider-attribution.d.ts.map +0 -1
- package/dist/core/provider-attribution.js.map +0 -1
- package/dist/core/provider-composer.d.ts.map +0 -1
- package/dist/core/provider-composer.js.map +0 -1
- package/dist/core/radius.d.ts.map +0 -1
- package/dist/core/radius.js.map +0 -1
- package/dist/core/remote-catalog-provider.d.ts.map +0 -1
- package/dist/core/remote-catalog-provider.js.map +0 -1
- package/dist/core/resolve-config-value.d.ts.map +0 -1
- package/dist/core/resolve-config-value.js.map +0 -1
- package/dist/core/resource-loader.d.ts.map +0 -1
- package/dist/core/resource-loader.js.map +0 -1
- package/dist/core/runtime-credentials.d.ts.map +0 -1
- package/dist/core/runtime-credentials.js.map +0 -1
- package/dist/core/sdk.d.ts.map +0 -1
- package/dist/core/sdk.js.map +0 -1
- package/dist/core/session-cwd.d.ts.map +0 -1
- package/dist/core/session-cwd.js.map +0 -1
- package/dist/core/session-manager.d.ts.map +0 -1
- package/dist/core/session-manager.js.map +0 -1
- package/dist/core/settings-manager-auto-handoff.test.d.ts.map +0 -1
- package/dist/core/settings-manager-auto-handoff.test.js.map +0 -1
- package/dist/core/settings-manager.d.ts.map +0 -1
- package/dist/core/settings-manager.js.map +0 -1
- package/dist/core/skills.d.ts.map +0 -1
- package/dist/core/skills.js.map +0 -1
- package/dist/core/slash-commands.d.ts.map +0 -1
- package/dist/core/slash-commands.js.map +0 -1
- package/dist/core/source-info.d.ts.map +0 -1
- package/dist/core/source-info.js.map +0 -1
- package/dist/core/system-prompt.d.ts.map +0 -1
- package/dist/core/system-prompt.js.map +0 -1
- package/dist/core/system-prompt.test.d.ts.map +0 -1
- package/dist/core/system-prompt.test.js.map +0 -1
- package/dist/core/telemetry.d.ts.map +0 -1
- package/dist/core/telemetry.js.map +0 -1
- package/dist/core/timings.d.ts.map +0 -1
- package/dist/core/timings.js.map +0 -1
- package/dist/core/tools/bash.d.ts.map +0 -1
- package/dist/core/tools/bash.js.map +0 -1
- package/dist/core/tools/edit-diff.d.ts.map +0 -1
- package/dist/core/tools/edit-diff.js.map +0 -1
- package/dist/core/tools/edit.d.ts.map +0 -1
- package/dist/core/tools/edit.js.map +0 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +0 -1
- package/dist/core/tools/file-mutation-queue.js.map +0 -1
- package/dist/core/tools/find.d.ts.map +0 -1
- package/dist/core/tools/find.js.map +0 -1
- package/dist/core/tools/grep.d.ts.map +0 -1
- package/dist/core/tools/grep.js.map +0 -1
- package/dist/core/tools/index.d.ts.map +0 -1
- package/dist/core/tools/index.js.map +0 -1
- package/dist/core/tools/ls.d.ts.map +0 -1
- package/dist/core/tools/ls.js.map +0 -1
- package/dist/core/tools/output-accumulator.d.ts.map +0 -1
- package/dist/core/tools/output-accumulator.js.map +0 -1
- package/dist/core/tools/path-utils.d.ts.map +0 -1
- package/dist/core/tools/path-utils.js.map +0 -1
- package/dist/core/tools/read.d.ts.map +0 -1
- package/dist/core/tools/read.js.map +0 -1
- package/dist/core/tools/render-utils.d.ts.map +0 -1
- package/dist/core/tools/render-utils.js.map +0 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +0 -1
- package/dist/core/tools/tool-definition-wrapper.js.map +0 -1
- package/dist/core/tools/truncate.d.ts.map +0 -1
- package/dist/core/tools/truncate.js.map +0 -1
- package/dist/core/tools/write.d.ts.map +0 -1
- package/dist/core/tools/write.js.map +0 -1
- package/dist/core/trust-manager.d.ts.map +0 -1
- package/dist/core/trust-manager.js.map +0 -1
- package/dist/core/usage-totals.d.ts.map +0 -1
- package/dist/core/usage-totals.js.map +0 -1
- package/dist/extensions/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
- package/dist/extensions/pi-subagents/test/unit/slash-chain-groups.test.ts +0 -464
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/main.d.ts.map +0 -1
- package/dist/main.js.map +0 -1
- package/dist/migrations.d.ts.map +0 -1
- package/dist/migrations.js.map +0 -1
- package/dist/modes/index.d.ts.map +0 -1
- package/dist/modes/index.js.map +0 -1
- package/dist/modes/interactive/components/armin.d.ts.map +0 -1
- package/dist/modes/interactive/components/armin.js.map +0 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +0 -1
- package/dist/modes/interactive/components/assistant-message.js.map +0 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +0 -1
- package/dist/modes/interactive/components/bash-execution.js.map +0 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +0 -1
- package/dist/modes/interactive/components/bordered-loader.js.map +0 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +0 -1
- package/dist/modes/interactive/components/branch-summary-message.js.map +0 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +0 -1
- package/dist/modes/interactive/components/compaction-summary-message.js.map +0 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +0 -1
- package/dist/modes/interactive/components/config-selector.js.map +0 -1
- package/dist/modes/interactive/components/countdown-timer.d.ts.map +0 -1
- package/dist/modes/interactive/components/countdown-timer.js.map +0 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +0 -1
- package/dist/modes/interactive/components/custom-editor.js.map +0 -1
- package/dist/modes/interactive/components/custom-entry.d.ts.map +0 -1
- package/dist/modes/interactive/components/custom-entry.js.map +0 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +0 -1
- package/dist/modes/interactive/components/custom-message.js.map +0 -1
- package/dist/modes/interactive/components/daxnuts.d.ts.map +0 -1
- package/dist/modes/interactive/components/daxnuts.js.map +0 -1
- package/dist/modes/interactive/components/diff.d.ts.map +0 -1
- package/dist/modes/interactive/components/diff.js.map +0 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +0 -1
- package/dist/modes/interactive/components/dynamic-border.js.map +0 -1
- package/dist/modes/interactive/components/earendil-announcement.d.ts.map +0 -1
- package/dist/modes/interactive/components/earendil-announcement.js.map +0 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +0 -1
- package/dist/modes/interactive/components/extension-editor.js.map +0 -1
- package/dist/modes/interactive/components/extension-input.d.ts.map +0 -1
- package/dist/modes/interactive/components/extension-input.js.map +0 -1
- package/dist/modes/interactive/components/extension-selector.d.ts.map +0 -1
- package/dist/modes/interactive/components/extension-selector.js.map +0 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +0 -1
- package/dist/modes/interactive/components/first-time-setup.js.map +0 -1
- package/dist/modes/interactive/components/footer.d.ts.map +0 -1
- package/dist/modes/interactive/components/footer.js.map +0 -1
- package/dist/modes/interactive/components/index.d.ts.map +0 -1
- package/dist/modes/interactive/components/index.js.map +0 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +0 -1
- package/dist/modes/interactive/components/keybinding-hints.js.map +0 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +0 -1
- package/dist/modes/interactive/components/login-dialog.js.map +0 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +0 -1
- package/dist/modes/interactive/components/model-selector.js.map +0 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +0 -1
- package/dist/modes/interactive/components/oauth-selector.js.map +0 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +0 -1
- package/dist/modes/interactive/components/scoped-models-selector.js.map +0 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +0 -1
- package/dist/modes/interactive/components/session-selector-search.js.map +0 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +0 -1
- package/dist/modes/interactive/components/session-selector.js.map +0 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +0 -1
- package/dist/modes/interactive/components/settings-selector.js.map +0 -1
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +0 -1
- package/dist/modes/interactive/components/show-images-selector.js.map +0 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +0 -1
- package/dist/modes/interactive/components/skill-invocation-message.js.map +0 -1
- package/dist/modes/interactive/components/status-indicator.d.ts.map +0 -1
- package/dist/modes/interactive/components/status-indicator.js.map +0 -1
- package/dist/modes/interactive/components/theme-selector.d.ts.map +0 -1
- package/dist/modes/interactive/components/theme-selector.js.map +0 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +0 -1
- package/dist/modes/interactive/components/thinking-selector.js.map +0 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +0 -1
- package/dist/modes/interactive/components/tool-execution.js.map +0 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +0 -1
- package/dist/modes/interactive/components/tree-selector.js.map +0 -1
- package/dist/modes/interactive/components/trust-selector.d.ts.map +0 -1
- package/dist/modes/interactive/components/trust-selector.js.map +0 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +0 -1
- package/dist/modes/interactive/components/user-message-selector.js.map +0 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +0 -1
- package/dist/modes/interactive/components/user-message.js.map +0 -1
- package/dist/modes/interactive/components/visual-truncate.d.ts.map +0 -1
- package/dist/modes/interactive/components/visual-truncate.js.map +0 -1
- package/dist/modes/interactive/external-editor.d.ts.map +0 -1
- package/dist/modes/interactive/external-editor.js.map +0 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +0 -1
- package/dist/modes/interactive/interactive-mode.js.map +0 -1
- package/dist/modes/interactive/model-search.d.ts.map +0 -1
- package/dist/modes/interactive/model-search.js.map +0 -1
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +0 -1
- package/dist/modes/interactive/theme/theme-controller.js.map +0 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +0 -1
- package/dist/modes/interactive/theme/theme.js.map +0 -1
- package/dist/modes/print-mode.d.ts.map +0 -1
- package/dist/modes/print-mode.js.map +0 -1
- package/dist/modes/rpc/jsonl.d.ts.map +0 -1
- package/dist/modes/rpc/jsonl.js.map +0 -1
- package/dist/modes/rpc/rpc-client.d.ts.map +0 -1
- package/dist/modes/rpc/rpc-client.js.map +0 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +0 -1
- package/dist/modes/rpc/rpc-mode.js.map +0 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +0 -1
- package/dist/modes/rpc/rpc-types.js.map +0 -1
- package/dist/package-manager-cli.d.ts.map +0 -1
- package/dist/package-manager-cli.js.map +0 -1
- package/dist/rpc-entry.d.ts.map +0 -1
- package/dist/rpc-entry.js.map +0 -1
- package/dist/utils/ansi.d.ts.map +0 -1
- package/dist/utils/ansi.js.map +0 -1
- package/dist/utils/changelog.d.ts.map +0 -1
- package/dist/utils/changelog.js.map +0 -1
- package/dist/utils/child-process.d.ts.map +0 -1
- package/dist/utils/child-process.js.map +0 -1
- package/dist/utils/clipboard-image.d.ts.map +0 -1
- package/dist/utils/clipboard-image.js.map +0 -1
- package/dist/utils/clipboard-native.d.ts.map +0 -1
- package/dist/utils/clipboard-native.js.map +0 -1
- package/dist/utils/clipboard.d.ts.map +0 -1
- package/dist/utils/clipboard.js.map +0 -1
- package/dist/utils/deprecation.d.ts.map +0 -1
- package/dist/utils/deprecation.js.map +0 -1
- package/dist/utils/exif-orientation.d.ts.map +0 -1
- package/dist/utils/exif-orientation.js.map +0 -1
- package/dist/utils/frontmatter.d.ts.map +0 -1
- package/dist/utils/frontmatter.js.map +0 -1
- package/dist/utils/fs-watch.d.ts.map +0 -1
- package/dist/utils/fs-watch.js.map +0 -1
- package/dist/utils/git.d.ts.map +0 -1
- package/dist/utils/git.js.map +0 -1
- package/dist/utils/html.d.ts.map +0 -1
- package/dist/utils/html.js.map +0 -1
- package/dist/utils/image-convert.d.ts.map +0 -1
- package/dist/utils/image-convert.js.map +0 -1
- package/dist/utils/image-process.d.ts.map +0 -1
- package/dist/utils/image-process.js.map +0 -1
- package/dist/utils/image-resize-core.d.ts.map +0 -1
- package/dist/utils/image-resize-core.js.map +0 -1
- package/dist/utils/image-resize-worker.d.ts.map +0 -1
- package/dist/utils/image-resize-worker.js.map +0 -1
- package/dist/utils/image-resize.d.ts.map +0 -1
- package/dist/utils/image-resize.js.map +0 -1
- package/dist/utils/json.d.ts.map +0 -1
- package/dist/utils/json.js.map +0 -1
- package/dist/utils/mime.d.ts.map +0 -1
- package/dist/utils/mime.js.map +0 -1
- package/dist/utils/open-browser.d.ts.map +0 -1
- package/dist/utils/open-browser.js.map +0 -1
- package/dist/utils/paths.d.ts.map +0 -1
- package/dist/utils/paths.js.map +0 -1
- package/dist/utils/photon.d.ts.map +0 -1
- package/dist/utils/photon.js.map +0 -1
- package/dist/utils/pi-user-agent.d.ts.map +0 -1
- package/dist/utils/pi-user-agent.js.map +0 -1
- package/dist/utils/shell.d.ts.map +0 -1
- package/dist/utils/shell.js.map +0 -1
- package/dist/utils/sleep.d.ts.map +0 -1
- package/dist/utils/sleep.js.map +0 -1
- package/dist/utils/syntax-highlight.d.ts.map +0 -1
- package/dist/utils/syntax-highlight.js.map +0 -1
- package/dist/utils/thinking-tags.d.ts.map +0 -1
- package/dist/utils/thinking-tags.js.map +0 -1
- package/dist/utils/tools-manager.d.ts.map +0 -1
- package/dist/utils/tools-manager.js.map +0 -1
- package/dist/utils/version-check.d.ts.map +0 -1
- package/dist/utils/version-check.js.map +0 -1
- package/dist/utils/windows-self-update.d.ts.map +0 -1
- package/dist/utils/windows-self-update.js.map +0 -1
|
@@ -9,11 +9,11 @@ import {
|
|
|
9
9
|
type Theme,
|
|
10
10
|
} from "@selesai/code";
|
|
11
11
|
import type { AssistantMessage } from "@earendil-works/pi-ai";
|
|
12
|
-
import { isKeyRelease,
|
|
12
|
+
import { isKeyRelease, type AutocompleteProvider, type SelectItem, SelectList, truncateToWidth, TUI_KEYBINDINGS, visibleWidth } from "@earendil-works/pi-tui";
|
|
13
13
|
import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync } from "node:fs";
|
|
14
14
|
import { join, dirname } from "node:path";
|
|
15
15
|
|
|
16
|
-
import type { ColorScheme, SegmentContext, StatusLinePreset, StatusLineSegmentId } from "./types.ts";
|
|
16
|
+
import type { ColorScheme, SegmentContext, StatusLinePreset, StatusLineSegmentId, StatusLineSeparatorStyle } from "./types.ts";
|
|
17
17
|
import type { PowerlineConfig } from "./powerline-config.ts";
|
|
18
18
|
import { BashTranscriptStore } from "./bash-mode/transcript.ts";
|
|
19
19
|
import {
|
|
@@ -28,21 +28,26 @@ import { ManagedShellSession } from "./bash-mode/shell-session.ts";
|
|
|
28
28
|
import { matchHistoryEntries, readGlobalShellHistory, readProjectHistory, appendProjectHistory } from "./bash-mode/history.ts";
|
|
29
29
|
import type { BashModeSettings } from "./bash-mode/types.ts";
|
|
30
30
|
import { getPreset, PRESETS } from "./presets.ts";
|
|
31
|
-
import {
|
|
31
|
+
import { getAgentPath } from "./paths.ts";
|
|
32
|
+
import { collectHiddenExtensionStatusKeys, getNotificationExtensionStatuses, mergeSegmentOptions, mergeSegmentsWithCustomItems, nextPowerlineSettingWithOptions, nextPowerlineSettingWithPreset, parsePowerlineConfig } from "./powerline-config.ts";
|
|
32
33
|
import { getSeparator } from "./separators.ts";
|
|
33
34
|
import { renderSegment } from "./segments.ts";
|
|
34
|
-
import { getGitStatus, invalidateGitStatus, invalidateGitBranch } from "./git-status.ts";
|
|
35
|
+
import { getGitStatus, invalidateGitStatus, invalidateGitBranch, subscribeGitUpdates } from "./git-status.ts";
|
|
36
|
+
import { SessionBranchCache, SessionTokenStatsCache } from "./token-stats.ts";
|
|
35
37
|
import { ansi, getFgAnsiCode } from "./colors.ts";
|
|
36
38
|
import { WelcomeComponent, WelcomeHeader, discoverLoadedCounts, getRecentSessions } from "./welcome.ts";
|
|
37
39
|
import { getGuidePreferences, getNewGuideFeatures, markGuideVersionSeen, resolveGuideDisplayMode, saveGuidePreferences, type GuideFeature } from "./guide.ts";
|
|
38
40
|
import { createRenderScheduler } from "./render-scheduler.ts";
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
41
|
+
import { createWelcomeDismissScheduler } from "./welcome-dismiss.ts";
|
|
42
|
+
import { getEditorAutocompleteProvider, passAutocompleteProviderThroughPreviousEditor } from "./editor-composition.ts";
|
|
43
|
+
import { CoreContextUsageCache, estimateInitialContextTokens, estimateUnknownContextUsage, resolveDisplayContextUsage, type CoreContextUsage } from "./context-usage.ts";
|
|
44
|
+
import { isStaleExtensionContextError, shouldShowStartupWelcome } from "./lifecycle.ts";
|
|
42
45
|
import { getDefaultColors } from "./theme.ts";
|
|
46
|
+
import { registerCdCommand } from "./cd-command.ts";
|
|
43
47
|
import {
|
|
44
48
|
isSupportedSuperShortcut,
|
|
45
49
|
matchesConfiguredShortcut,
|
|
50
|
+
matchesStashShortcutInput,
|
|
46
51
|
shortcutConflictKey,
|
|
47
52
|
shortcutUsesSuper,
|
|
48
53
|
} from "./shortcuts.ts";
|
|
@@ -61,9 +66,14 @@ import {
|
|
|
61
66
|
hasVibeFile,
|
|
62
67
|
getVibeFileCount,
|
|
63
68
|
generateVibesBatch,
|
|
69
|
+
parseVibeGenerateArgs,
|
|
64
70
|
} from "./working-vibes.ts";
|
|
65
71
|
import { setupTpsTracker } from "./tps.ts";
|
|
66
|
-
import { readAsyncSubagentUsage
|
|
72
|
+
import { readAsyncSubagentUsage } from "./session-usage.ts";
|
|
73
|
+
import { renderFixedEditorCluster } from "./fixed-editor/cluster.ts";
|
|
74
|
+
import { emergencyTerminalModeReset, TerminalSplitCompositor } from "./fixed-editor/terminal-split.ts";
|
|
75
|
+
import { PowerlineQueueStore, currentQueueContext, formatIdeaIssuePrompt, formatQueueDeliveryText, parseCompactQueuedPrompt, parseSigilIdeaCapture, parseTargetPrefix, targetForIdea } from "./queue/store.ts";
|
|
76
|
+
import type { PowerlineQueueItem, QueueContext, QueueIntent, QueueTarget } from "./queue/types.ts";
|
|
67
77
|
|
|
68
78
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
69
79
|
// Configuration
|
|
@@ -75,24 +85,39 @@ let config: PowerlineConfig = {
|
|
|
75
85
|
mouseScroll: true,
|
|
76
86
|
fixedEditor: true,
|
|
77
87
|
fixedEditorPromptGlyph: "",
|
|
88
|
+
disabledSegments: [],
|
|
89
|
+
invalidDisabledSegments: [],
|
|
90
|
+
layout: null,
|
|
91
|
+
invalidLayoutSegments: [],
|
|
92
|
+
separator: null,
|
|
93
|
+
segmentOptions: {},
|
|
94
|
+
placement: "above",
|
|
95
|
+
invalidPlacement: null,
|
|
96
|
+
welcome: true,
|
|
97
|
+
stashSharpSShortcut: false,
|
|
98
|
+
queue: { captureSigil: "#" },
|
|
78
99
|
};
|
|
79
100
|
|
|
80
101
|
const CUSTOM_COMPACTION_STATUS_KEY = "compact-policy";
|
|
81
102
|
let customCompactionEnabled = false;
|
|
82
103
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
104
|
+
type ShortcutBinding = string | null;
|
|
105
|
+
|
|
106
|
+
export interface PowerlineShortcuts {
|
|
107
|
+
stashHistory: ShortcutBinding;
|
|
108
|
+
copyEditor: ShortcutBinding;
|
|
109
|
+
cutEditor: ShortcutBinding;
|
|
110
|
+
ideaCapture: ShortcutBinding;
|
|
111
|
+
queueOpen: ShortcutBinding;
|
|
112
|
+
jumpPreviousUserMessage: ShortcutBinding;
|
|
113
|
+
jumpNextUserMessage: ShortcutBinding;
|
|
114
|
+
jumpPreviousLlmMessage: ShortcutBinding;
|
|
115
|
+
jumpNextLlmMessage: ShortcutBinding;
|
|
116
|
+
jumpChatBottom: ShortcutBinding;
|
|
117
|
+
scrollChatUp: ShortcutBinding;
|
|
118
|
+
scrollChatDown: ShortcutBinding;
|
|
119
|
+
editorStart: ShortcutBinding;
|
|
120
|
+
editorEnd: ShortcutBinding;
|
|
96
121
|
}
|
|
97
122
|
|
|
98
123
|
type PowerlineShortcutKey = keyof PowerlineShortcuts;
|
|
@@ -112,9 +137,10 @@ type PowerlineShortcutAction =
|
|
|
112
137
|
| { kind: "stashHistory" }
|
|
113
138
|
| { kind: "copyEditor" }
|
|
114
139
|
| { kind: "cutEditor" }
|
|
140
|
+
| { kind: "ideaCapture" }
|
|
141
|
+
| { kind: "queueOpen" }
|
|
115
142
|
| { kind: "bashMode" }
|
|
116
143
|
| { kind: "chat"; action: ChatJumpShortcutAction };
|
|
117
|
-
|
|
118
144
|
const STASH_HISTORY_LIMIT = 12;
|
|
119
145
|
const PROJECT_PROMPT_HISTORY_LIMIT = 50;
|
|
120
146
|
const STASH_PREVIEW_WIDTH = 72;
|
|
@@ -122,6 +148,8 @@ const DEFAULT_SHORTCUTS: PowerlineShortcuts = {
|
|
|
122
148
|
stashHistory: "ctrl+alt+h",
|
|
123
149
|
copyEditor: "ctrl+alt+c",
|
|
124
150
|
cutEditor: "ctrl+alt+x",
|
|
151
|
+
ideaCapture: null,
|
|
152
|
+
queueOpen: "ctrl+alt+q",
|
|
125
153
|
jumpPreviousUserMessage: "ctrl+shift+u",
|
|
126
154
|
jumpNextUserMessage: "ctrl+shift+i",
|
|
127
155
|
jumpPreviousLlmMessage: "ctrl+alt+,",
|
|
@@ -132,11 +160,12 @@ const DEFAULT_SHORTCUTS: PowerlineShortcuts = {
|
|
|
132
160
|
editorStart: "super+shift+up",
|
|
133
161
|
editorEnd: "super+shift+down",
|
|
134
162
|
};
|
|
135
|
-
const DEFAULT_BASH_MODE_SETTINGS
|
|
163
|
+
const DEFAULT_BASH_MODE_SETTINGS = {
|
|
136
164
|
toggleShortcut: "ctrl+shift+b",
|
|
137
165
|
transcriptMaxLines: 2000,
|
|
138
166
|
transcriptMaxBytes: 512 * 1024,
|
|
139
|
-
};
|
|
167
|
+
} as const satisfies BashModeSettings;
|
|
168
|
+
const SHORTCUT_KEYS: PowerlineShortcutKey[] = ["stashHistory", "copyEditor", "cutEditor", "ideaCapture", "queueOpen", "jumpPreviousUserMessage", "jumpNextUserMessage", "jumpPreviousLlmMessage", "jumpNextLlmMessage", "jumpChatBottom", "scrollChatUp", "scrollChatDown", "editorStart", "editorEnd"];
|
|
140
169
|
const CHAT_JUMP_SHORTCUTS: Array<{
|
|
141
170
|
shortcutKey: ChatJumpShortcutKey;
|
|
142
171
|
description: string;
|
|
@@ -168,20 +197,6 @@ const CHAT_JUMP_SHORTCUTS: Array<{
|
|
|
168
197
|
action: { kind: "bottom" },
|
|
169
198
|
},
|
|
170
199
|
];
|
|
171
|
-
const SHORTCUT_KEYS: PowerlineShortcutKey[] = [
|
|
172
|
-
"stashHistory",
|
|
173
|
-
"copyEditor",
|
|
174
|
-
"cutEditor",
|
|
175
|
-
"jumpPreviousUserMessage",
|
|
176
|
-
"jumpNextUserMessage",
|
|
177
|
-
"jumpPreviousLlmMessage",
|
|
178
|
-
"jumpNextLlmMessage",
|
|
179
|
-
"jumpChatBottom",
|
|
180
|
-
"scrollChatUp",
|
|
181
|
-
"scrollChatDown",
|
|
182
|
-
"editorStart",
|
|
183
|
-
"editorEnd",
|
|
184
|
-
];
|
|
185
200
|
const APP_RESERVED_SHORTCUTS = [
|
|
186
201
|
"escape",
|
|
187
202
|
"ctrl+c",
|
|
@@ -212,7 +227,7 @@ const APP_RESERVED_SHORTCUTS = [
|
|
|
212
227
|
] as const;
|
|
213
228
|
const EXTRA_RESERVED_SHORTCUTS = ["alt+s"] as const;
|
|
214
229
|
const SHORTCUT_MODIFIER_ORDER = ["ctrl", "alt", "super", "shift"] as const;
|
|
215
|
-
const SHORTCUT_MODIFIERS = new Set(SHORTCUT_MODIFIER_ORDER);
|
|
230
|
+
const SHORTCUT_MODIFIERS = new Set<string>(SHORTCUT_MODIFIER_ORDER);
|
|
216
231
|
const SHORTCUT_NAMED_KEYS = new Set([
|
|
217
232
|
"escape", "esc", "enter", "return", "tab", "space", "backspace", "delete", "insert", "clear",
|
|
218
233
|
"home", "end", "pageup", "pagedown", "up", "down", "left", "right",
|
|
@@ -230,6 +245,10 @@ const EDITOR_STATUS_DEFER_MS = 150;
|
|
|
230
245
|
const PROMPT_HISTORY_TRACKED = Symbol.for("powerlinePromptHistoryTracked");
|
|
231
246
|
const PROMPT_HISTORY_STATE_KEY = Symbol.for("powerlinePromptHistoryState");
|
|
232
247
|
|
|
248
|
+
interface PromptHistoryEditor {
|
|
249
|
+
addToHistory?: (text: string) => void;
|
|
250
|
+
}
|
|
251
|
+
|
|
233
252
|
type PromptHistoryState = { savedPromptHistory: string[] };
|
|
234
253
|
type SessionAssistantUsage = AssistantMessage["usage"];
|
|
235
254
|
|
|
@@ -279,8 +298,9 @@ function getPromptHistoryState(): PromptHistoryState {
|
|
|
279
298
|
return state;
|
|
280
299
|
}
|
|
281
300
|
|
|
282
|
-
function readPromptHistory(editor:
|
|
283
|
-
|
|
301
|
+
function readPromptHistory(editor: PromptHistoryEditor | null | undefined): string[] {
|
|
302
|
+
if (!editor) return [];
|
|
303
|
+
const history = Reflect.get(editor, "history");
|
|
284
304
|
if (!Array.isArray(history)) return [];
|
|
285
305
|
|
|
286
306
|
const normalized: string[] = [];
|
|
@@ -296,14 +316,14 @@ function readPromptHistory(editor: any): string[] {
|
|
|
296
316
|
return normalized;
|
|
297
317
|
}
|
|
298
318
|
|
|
299
|
-
function snapshotPromptHistory(editor:
|
|
319
|
+
function snapshotPromptHistory(editor: PromptHistoryEditor | null | undefined): void {
|
|
300
320
|
const history = readPromptHistory(editor);
|
|
301
321
|
if (history.length > 0) {
|
|
302
322
|
getPromptHistoryState().savedPromptHistory = [...history];
|
|
303
323
|
}
|
|
304
324
|
}
|
|
305
325
|
|
|
306
|
-
function restorePromptHistory(editor:
|
|
326
|
+
function restorePromptHistory(editor: PromptHistoryEditor | null | undefined): void {
|
|
307
327
|
const { savedPromptHistory } = getPromptHistoryState();
|
|
308
328
|
if (!savedPromptHistory.length || typeof editor?.addToHistory !== "function") return;
|
|
309
329
|
|
|
@@ -312,9 +332,9 @@ function restorePromptHistory(editor: any): void {
|
|
|
312
332
|
}
|
|
313
333
|
}
|
|
314
334
|
|
|
315
|
-
function trackPromptHistory(editor:
|
|
335
|
+
function trackPromptHistory(editor: PromptHistoryEditor | null | undefined): void {
|
|
316
336
|
if (!editor || typeof editor.addToHistory !== "function") return;
|
|
317
|
-
if (editor
|
|
337
|
+
if (Reflect.get(editor, PROMPT_HISTORY_TRACKED)) {
|
|
318
338
|
snapshotPromptHistory(editor);
|
|
319
339
|
return;
|
|
320
340
|
}
|
|
@@ -324,7 +344,7 @@ function trackPromptHistory(editor: any): void {
|
|
|
324
344
|
originalAddToHistory(text);
|
|
325
345
|
snapshotPromptHistory(editor);
|
|
326
346
|
};
|
|
327
|
-
editor
|
|
347
|
+
Reflect.set(editor, PROMPT_HISTORY_TRACKED, true);
|
|
328
348
|
snapshotPromptHistory(editor);
|
|
329
349
|
}
|
|
330
350
|
|
|
@@ -624,7 +644,7 @@ function writePowerlinePresetSetting(preset: StatusLinePreset, cwd: string = pro
|
|
|
624
644
|
|
|
625
645
|
function writePowerlineOptionSetting(
|
|
626
646
|
cwd: string,
|
|
627
|
-
updates: Partial<Pick<PowerlineConfig, "
|
|
647
|
+
updates: Partial<Pick<PowerlineConfig, "welcome" | "stashSharpSShortcut" | "placement">>,
|
|
628
648
|
currentPreset: StatusLinePreset,
|
|
629
649
|
): boolean {
|
|
630
650
|
return writePowerlineSetting(cwd, (existingPowerlineSetting) => (
|
|
@@ -652,7 +672,9 @@ function hasNonWhitespaceText(text: string): boolean {
|
|
|
652
672
|
}
|
|
653
673
|
|
|
654
674
|
function getCurrentEditorText(ctx: any, editor: any): string {
|
|
655
|
-
|
|
675
|
+
const editorText = editor?.getExpandedText?.();
|
|
676
|
+
if (typeof editorText === "string" && editorText.length > 0) return editorText;
|
|
677
|
+
return ctx.ui.getEditorText?.() ?? editorText ?? "";
|
|
656
678
|
}
|
|
657
679
|
|
|
658
680
|
function buildStashPreview(text: string, maxWidth: number): string {
|
|
@@ -677,7 +699,7 @@ function normalizeShortcut(value: string): string {
|
|
|
677
699
|
const parts = value.trim().toLowerCase().split("+");
|
|
678
700
|
if (parts.length <= 1) return parts[0] ?? "";
|
|
679
701
|
|
|
680
|
-
const modifierRank = new Map(SHORTCUT_MODIFIER_ORDER.map((modifier, index) => [modifier, index]));
|
|
702
|
+
const modifierRank = new Map<string, number>(SHORTCUT_MODIFIER_ORDER.map((modifier, index) => [modifier, index]));
|
|
681
703
|
const modifiers = parts.slice(0, -1).sort((a, b) => (modifierRank.get(a) ?? 99) - (modifierRank.get(b) ?? 99));
|
|
682
704
|
return [...modifiers, parts[parts.length - 1]].join("+");
|
|
683
705
|
}
|
|
@@ -756,15 +778,21 @@ function shortcutUsageKey(shortcut: string): string {
|
|
|
756
778
|
return shortcutConflictKey(normalizeShortcut(shortcut));
|
|
757
779
|
}
|
|
758
780
|
|
|
781
|
+
function parseShortcutSetting(value: unknown): ShortcutBinding | undefined {
|
|
782
|
+
if (value === null || value === undefined) return null;
|
|
783
|
+
if (typeof value === "string" && value.trim() === "") return null;
|
|
784
|
+
return parseShortcutOverride(value) ?? undefined;
|
|
785
|
+
}
|
|
786
|
+
|
|
759
787
|
function findShortcutReplacement(key: PowerlineShortcutKey, used: Set<string>): string | null {
|
|
760
788
|
const preferred = DEFAULT_SHORTCUTS[key];
|
|
761
|
-
if (!used.has(shortcutUsageKey(preferred))) {
|
|
789
|
+
if (preferred && !used.has(shortcutUsageKey(preferred))) {
|
|
762
790
|
return preferred;
|
|
763
791
|
}
|
|
764
792
|
|
|
765
793
|
for (const shortcutKey of SHORTCUT_KEYS) {
|
|
766
794
|
const candidate = DEFAULT_SHORTCUTS[shortcutKey];
|
|
767
|
-
if (!used.has(shortcutUsageKey(candidate))) {
|
|
795
|
+
if (candidate && !used.has(shortcutUsageKey(candidate))) {
|
|
768
796
|
return candidate;
|
|
769
797
|
}
|
|
770
798
|
}
|
|
@@ -772,23 +800,45 @@ function findShortcutReplacement(key: PowerlineShortcutKey, used: Set<string>):
|
|
|
772
800
|
return null;
|
|
773
801
|
}
|
|
774
802
|
|
|
775
|
-
function
|
|
803
|
+
function bashToggleShortcutReservation(settings: Record<string, unknown>): ShortcutBinding {
|
|
804
|
+
const raw = isRecord(settings.bashMode) ? settings.bashMode : {};
|
|
805
|
+
if (!Object.prototype.hasOwnProperty.call(raw, "toggleShortcut")) {
|
|
806
|
+
return DEFAULT_BASH_MODE_SETTINGS.toggleShortcut;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
const parsed = parseShortcutSetting(raw.toggleShortcut);
|
|
810
|
+
return parsed === undefined ? DEFAULT_BASH_MODE_SETTINGS.toggleShortcut : parsed;
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
export function resolveShortcutConfig(settings: Record<string, unknown>): PowerlineShortcuts {
|
|
776
814
|
const resolved: PowerlineShortcuts = { ...DEFAULT_SHORTCUTS };
|
|
777
815
|
const shortcutSettings = settings.powerlineShortcuts;
|
|
778
816
|
|
|
779
817
|
if (isRecord(shortcutSettings)) {
|
|
780
818
|
for (const key of SHORTCUT_KEYS) {
|
|
781
|
-
|
|
782
|
-
|
|
819
|
+
if (!Object.prototype.hasOwnProperty.call(shortcutSettings, key)) {
|
|
820
|
+
continue;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
const override = parseShortcutSetting(shortcutSettings[key]);
|
|
824
|
+
if (override !== undefined) {
|
|
783
825
|
resolved[key] = override;
|
|
784
826
|
}
|
|
785
827
|
}
|
|
786
828
|
}
|
|
787
829
|
|
|
788
830
|
const used = new Set(Array.from(reservedShortcuts(), shortcutUsageKey));
|
|
831
|
+
const reservedBashToggle = bashToggleShortcutReservation(settings);
|
|
832
|
+
if (reservedBashToggle) {
|
|
833
|
+
used.add(shortcutUsageKey(reservedBashToggle));
|
|
834
|
+
}
|
|
789
835
|
|
|
790
836
|
for (const key of SHORTCUT_KEYS) {
|
|
791
837
|
const configured = resolved[key];
|
|
838
|
+
if (configured === null) {
|
|
839
|
+
continue;
|
|
840
|
+
}
|
|
841
|
+
|
|
792
842
|
const configuredUsageKey = shortcutUsageKey(configured);
|
|
793
843
|
|
|
794
844
|
if (!used.has(configuredUsageKey)) {
|
|
@@ -813,17 +863,33 @@ function resolveShortcutConfig(settings: Record<string, unknown>): PowerlineShor
|
|
|
813
863
|
return resolved;
|
|
814
864
|
}
|
|
815
865
|
|
|
816
|
-
function parseBashModeSettings(settings: Record<string, unknown
|
|
866
|
+
export function parseBashModeSettings(settings: Record<string, unknown>, powerlineShortcuts?: PowerlineShortcuts): BashModeSettings {
|
|
817
867
|
const raw = isRecord(settings.bashMode) ? settings.bashMode : {};
|
|
868
|
+
const used = new Set(Array.from(reservedShortcuts(), shortcutUsageKey));
|
|
869
|
+
if (powerlineShortcuts) {
|
|
870
|
+
for (const shortcut of Object.values(powerlineShortcuts)) {
|
|
871
|
+
if (shortcut) {
|
|
872
|
+
used.add(shortcutUsageKey(shortcut));
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
}
|
|
818
876
|
|
|
819
|
-
const configuredToggleShortcut =
|
|
820
|
-
|
|
821
|
-
|
|
877
|
+
const configuredToggleShortcut = Object.prototype.hasOwnProperty.call(raw, "toggleShortcut")
|
|
878
|
+
? parseShortcutSetting(raw.toggleShortcut)
|
|
879
|
+
: undefined;
|
|
880
|
+
const fallbackToggleShortcut = used.has(shortcutUsageKey(DEFAULT_BASH_MODE_SETTINGS.toggleShortcut))
|
|
881
|
+
? null
|
|
822
882
|
: DEFAULT_BASH_MODE_SETTINGS.toggleShortcut;
|
|
883
|
+
const toggleShortcut = configuredToggleShortcut === null
|
|
884
|
+
? null
|
|
885
|
+
: configuredToggleShortcut
|
|
886
|
+
&& !used.has(shortcutUsageKey(configuredToggleShortcut))
|
|
887
|
+
? configuredToggleShortcut
|
|
888
|
+
: fallbackToggleShortcut;
|
|
823
889
|
|
|
824
890
|
if (configuredToggleShortcut && toggleShortcut !== configuredToggleShortcut) {
|
|
825
891
|
console.debug(
|
|
826
|
-
`[powerline-footer] Bash mode shortcut conflict: "${configuredToggleShortcut}" replaced with "${toggleShortcut}"`,
|
|
892
|
+
`[powerline-footer] Bash mode shortcut conflict: "${configuredToggleShortcut}" replaced with "${toggleShortcut ?? "disabled"}"`,
|
|
827
893
|
);
|
|
828
894
|
}
|
|
829
895
|
const transcriptMaxLines = typeof raw.transcriptMaxLines === "number" && Number.isFinite(raw.transcriptMaxLines)
|
|
@@ -859,10 +925,10 @@ function renderSegmentWithWidth(
|
|
|
859
925
|
/** Build content string from pre-rendered parts */
|
|
860
926
|
function buildContentFromParts(
|
|
861
927
|
parts: string[],
|
|
862
|
-
|
|
928
|
+
separatorStyle: StatusLineSeparatorStyle,
|
|
863
929
|
): string {
|
|
864
930
|
if (parts.length === 0) return "";
|
|
865
|
-
const separatorDef = getSeparator(
|
|
931
|
+
const separatorDef = getSeparator(separatorStyle);
|
|
866
932
|
const sepAnsi = getFgAnsiCode("sep");
|
|
867
933
|
const sep = separatorDef.left;
|
|
868
934
|
return " " + parts.join(`${sepAnsi}${sep}${ansi.reset}`) + ansi.reset + " ";
|
|
@@ -878,37 +944,70 @@ function computeResponsiveLayout(
|
|
|
878
944
|
presetDef: ReturnType<typeof getPreset>,
|
|
879
945
|
availableWidth: number
|
|
880
946
|
): { topContent: string; secondaryContent: string } {
|
|
881
|
-
const
|
|
882
|
-
const
|
|
947
|
+
const separatorStyle = config.separator ?? presetDef.separator;
|
|
948
|
+
const separatorDef = getSeparator(separatorStyle);
|
|
949
|
+
const sepWidth = visibleWidth(separatorDef.left) + 2; // separator + spaces around it
|
|
950
|
+
|
|
951
|
+
// Get all segments: primary first, then secondary
|
|
952
|
+
const mergedSegments = mergeSegmentsWithCustomItems(presetDef, config.customItems, {
|
|
953
|
+
layout: config.layout,
|
|
954
|
+
disabledSegments: config.disabledSegments,
|
|
955
|
+
});
|
|
956
|
+
const primaryIds = [...mergedSegments.leftSegments, ...mergedSegments.rightSegments];
|
|
957
|
+
const secondaryIds = mergedSegments.secondarySegments;
|
|
958
|
+
const allSegmentIds = [...primaryIds, ...secondaryIds];
|
|
883
959
|
|
|
884
|
-
|
|
885
|
-
const
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
960
|
+
// Render all segments and get their widths
|
|
961
|
+
const renderedSegments: { content: string; width: number }[] = [];
|
|
962
|
+
for (const segId of allSegmentIds) {
|
|
963
|
+
const { content, width, visible } = renderSegmentWithWidth(segId, ctx);
|
|
964
|
+
if (visible) {
|
|
965
|
+
renderedSegments.push({ content, width });
|
|
890
966
|
}
|
|
891
|
-
|
|
892
|
-
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
if (renderedSegments.length === 0) {
|
|
970
|
+
return { topContent: "", secondaryContent: "" };
|
|
971
|
+
}
|
|
893
972
|
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
const
|
|
973
|
+
// Calculate how many segments fit in top bar
|
|
974
|
+
// Account for: leading space (1) + trailing space (1) = 2 chars overhead
|
|
975
|
+
const baseOverhead = 2;
|
|
976
|
+
let currentWidth = baseOverhead;
|
|
977
|
+
let topSegments: string[] = [];
|
|
978
|
+
let overflowSegments: { content: string; width: number }[] = [];
|
|
979
|
+
let overflow = false;
|
|
980
|
+
|
|
981
|
+
for (const seg of renderedSegments) {
|
|
982
|
+
const neededWidth = seg.width + (topSegments.length > 0 ? sepWidth : 0);
|
|
983
|
+
|
|
984
|
+
if (!overflow && currentWidth + neededWidth <= availableWidth) {
|
|
985
|
+
topSegments.push(seg.content);
|
|
986
|
+
currentWidth += neededWidth;
|
|
987
|
+
} else {
|
|
988
|
+
overflow = true;
|
|
989
|
+
overflowSegments.push(seg);
|
|
990
|
+
}
|
|
991
|
+
}
|
|
897
992
|
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
let
|
|
993
|
+
// Fit overflow segments into secondary row (same width constraint)
|
|
994
|
+
// Stop at first non-fitting segment to preserve ordering
|
|
995
|
+
let secondaryWidth = baseOverhead;
|
|
996
|
+
let secondarySegments: string[] = [];
|
|
901
997
|
|
|
902
|
-
|
|
903
|
-
const
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
998
|
+
for (const seg of overflowSegments) {
|
|
999
|
+
const neededWidth = seg.width + (secondarySegments.length > 0 ? sepWidth : 0);
|
|
1000
|
+
if (secondaryWidth + neededWidth <= availableWidth) {
|
|
1001
|
+
secondarySegments.push(seg.content);
|
|
1002
|
+
secondaryWidth += neededWidth;
|
|
1003
|
+
} else {
|
|
1004
|
+
break;
|
|
1005
|
+
}
|
|
907
1006
|
}
|
|
908
1007
|
|
|
909
1008
|
return {
|
|
910
|
-
topContent,
|
|
911
|
-
secondaryContent: buildContentFromParts(
|
|
1009
|
+
topContent: buildContentFromParts(topSegments, separatorStyle),
|
|
1010
|
+
secondaryContent: buildContentFromParts(secondarySegments, separatorStyle),
|
|
912
1011
|
};
|
|
913
1012
|
}
|
|
914
1013
|
|
|
@@ -916,11 +1015,33 @@ function computeResponsiveLayout(
|
|
|
916
1015
|
// Extension
|
|
917
1016
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
918
1017
|
|
|
1018
|
+
function warnInvalidSegmentSettings(ctx: any): void {
|
|
1019
|
+
if (config.invalidDisabledSegments.length > 0) {
|
|
1020
|
+
const invalid = config.invalidDisabledSegments.map((id) => JSON.stringify(id)).join(", ");
|
|
1021
|
+
const message = `Ignoring unknown powerline disabled segment${config.invalidDisabledSegments.length === 1 ? "" : "s"}: ${invalid}`;
|
|
1022
|
+
console.warn(`[powerline-footer] ${message}`);
|
|
1023
|
+
if (ctx.hasUI) ctx.ui.notify(message, "warning");
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
if (config.invalidLayoutSegments.length > 0) {
|
|
1027
|
+
const invalid = config.invalidLayoutSegments.map((id) => JSON.stringify(id)).join(", ");
|
|
1028
|
+
const message = `Ignoring unknown powerline layout segment${config.invalidLayoutSegments.length === 1 ? "" : "s"}: ${invalid}`;
|
|
1029
|
+
console.warn(`[powerline-footer] ${message}`);
|
|
1030
|
+
if (ctx.hasUI) ctx.ui.notify(message, "warning");
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
if (config.invalidPlacement !== null) {
|
|
1034
|
+
const message = `Ignoring invalid powerline placement: ${JSON.stringify(config.invalidPlacement)}`;
|
|
1035
|
+
console.warn(`[powerline-footer] ${message}`);
|
|
1036
|
+
if (ctx.hasUI) ctx.ui.notify(message, "warning");
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
|
|
919
1040
|
export default function powerlineFooter(pi: ExtensionAPI) {
|
|
920
1041
|
const startupSettings = readSettings();
|
|
921
1042
|
config = parsePowerlineConfig(startupSettings.powerline, PRESET_NAMES);
|
|
922
1043
|
let resolvedShortcuts = resolveShortcutConfig(startupSettings);
|
|
923
|
-
let bashModeSettings = parseBashModeSettings(startupSettings);
|
|
1044
|
+
let bashModeSettings = parseBashModeSettings(startupSettings, resolvedShortcuts);
|
|
924
1045
|
|
|
925
1046
|
let enabled = true;
|
|
926
1047
|
let sessionStartTime = Date.now();
|
|
@@ -931,14 +1052,10 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
931
1052
|
let currentThinkingLevel: string | null = null;
|
|
932
1053
|
let liveAssistantUsage: SessionAssistantUsage | null = null;
|
|
933
1054
|
const completedAsyncSubagentUsage = new Map<string, { input: number; output: number; cacheRead: number; cacheWrite: number; cost: number }>();
|
|
1055
|
+
let approximateContextUsage: CoreContextUsage | null = null;
|
|
934
1056
|
let isStreaming = false;
|
|
935
1057
|
let tuiRef: any = null;
|
|
936
1058
|
let restoreFooterStatusRepaintHook: (() => void) | null = null;
|
|
937
|
-
let fixedEditorCompositor: TerminalSplitCompositor | null = null;
|
|
938
|
-
let fixedStatusContainer: any = null;
|
|
939
|
-
let fixedEditorContainer: any = null;
|
|
940
|
-
let fixedWidgetContainerAbove: any = null;
|
|
941
|
-
let fixedWidgetContainerBelow: any = null;
|
|
942
1059
|
let stashShortcutInputUnsubscribe: (() => void) | null = null;
|
|
943
1060
|
let dismissWelcomeOverlay: (() => void) | null = null;
|
|
944
1061
|
let guideOverlayBlocking = false;
|
|
@@ -953,6 +1070,15 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
953
1070
|
let bashTranscript = new BashTranscriptStore(bashModeSettings);
|
|
954
1071
|
let bashCompletionEngine = new BashCompletionEngine();
|
|
955
1072
|
let shellSession: ManagedShellSession | null = null;
|
|
1073
|
+
let fixedEditorCompositor: TerminalSplitCompositor | null = null;
|
|
1074
|
+
let fixedStatusContainer: any = null;
|
|
1075
|
+
let fixedEditorContainer: any = null;
|
|
1076
|
+
let fixedWidgetContainerAbove: any = null;
|
|
1077
|
+
let fixedWidgetContainerBelow: any = null;
|
|
1078
|
+
const queueStore = new PowerlineQueueStore();
|
|
1079
|
+
let powerlineCompacting = false;
|
|
1080
|
+
let deliverAfterRetrySettles = false;
|
|
1081
|
+
let queueDeliveryTimer: ReturnType<typeof setTimeout> | null = null;
|
|
956
1082
|
|
|
957
1083
|
// Cache for the top and secondary powerline widgets.
|
|
958
1084
|
let lastLayoutWidth = 0;
|
|
@@ -963,6 +1089,13 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
963
1089
|
let lastEditorInputAt = 0;
|
|
964
1090
|
let lastLayoutSessionName: string | undefined;
|
|
965
1091
|
|
|
1092
|
+
// Cache for token counting: avoid re-scanning the full session event list
|
|
1093
|
+
// on every render (250ms-1s cadence). Revalidates the trailing event's
|
|
1094
|
+
// stats signature so in-place streaming updates are not served stale.
|
|
1095
|
+
const sessionBranchCache = new SessionBranchCache();
|
|
1096
|
+
const tokenStatsCache = new SessionTokenStatsCache();
|
|
1097
|
+
const coreContextUsageCache = new CoreContextUsageCache();
|
|
1098
|
+
|
|
966
1099
|
const getShellPath = () => process.env.SHELL || "/bin/sh";
|
|
967
1100
|
const getShellCwd = () => shellSession?.state.cwd ?? currentCtx?.cwd ?? process.cwd();
|
|
968
1101
|
|
|
@@ -976,10 +1109,19 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
976
1109
|
tuiRef?.requestRender();
|
|
977
1110
|
}, STATUS_RENDER_DEBOUNCE_MS);
|
|
978
1111
|
|
|
1112
|
+
const welcomeDismissScheduler = createWelcomeDismissScheduler({
|
|
1113
|
+
dismiss: (ctx: unknown) => dismissWelcome(ctx),
|
|
1114
|
+
getGeneration: () => sessionGeneration,
|
|
1115
|
+
isEnabled: () => enabled,
|
|
1116
|
+
});
|
|
1117
|
+
|
|
979
1118
|
const resetLayoutCache = () => {
|
|
980
1119
|
lastLayoutResult = null;
|
|
981
1120
|
lastLayoutSessionName = undefined;
|
|
982
1121
|
layoutDirty = true;
|
|
1122
|
+
sessionBranchCache.reset();
|
|
1123
|
+
tokenStatsCache.reset();
|
|
1124
|
+
coreContextUsageCache.reset();
|
|
983
1125
|
};
|
|
984
1126
|
|
|
985
1127
|
const requestStatusRender = (delayMs?: number) => {
|
|
@@ -1120,7 +1262,7 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
1120
1262
|
items: SelectItem[],
|
|
1121
1263
|
maxVisible: number,
|
|
1122
1264
|
): Promise<SelectItem | null> {
|
|
1123
|
-
return ctx.ui.custom
|
|
1265
|
+
return ctx.ui.custom(
|
|
1124
1266
|
(tui: any, theme: Theme, _keybindings: any, done: (result: SelectItem | null) => void) => {
|
|
1125
1267
|
const selectList = new SelectList(items, maxVisible, overlaySelectListTheme(theme));
|
|
1126
1268
|
const border = (text: string) => theme.fg("dim", text);
|
|
@@ -1167,6 +1309,291 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
1167
1309
|
);
|
|
1168
1310
|
}
|
|
1169
1311
|
|
|
1312
|
+
function getQueueSessionId(ctx: any): string | undefined {
|
|
1313
|
+
const sessionId = ctx.sessionManager?.getSessionId?.();
|
|
1314
|
+
return typeof sessionId === "string" && sessionId.trim() ? sessionId : undefined;
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
function getQueueContext(ctx: any): QueueContext {
|
|
1318
|
+
return currentQueueContext(ctx.cwd ?? process.cwd(), getQueueSessionId(ctx));
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
function requestQueueRender(): void {
|
|
1322
|
+
requestImmediateStatusRender({ deferDuringTyping: false });
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
function queueItemLabel(item: PowerlineQueueItem): string {
|
|
1326
|
+
const status = item.status === "queued" ? item.intent : `${item.intent}/${item.status}`;
|
|
1327
|
+
return `${item.id} ${status} ${buildStashPreview(item.text, 56)}`;
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
function queueItemDescription(item: PowerlineQueueItem): string {
|
|
1331
|
+
if (item.target.kind === "global") return "global";
|
|
1332
|
+
if (item.target.kind === "current-session") return "current session";
|
|
1333
|
+
return item.target.alias ? `@${item.target.alias}` : item.target.cwd;
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
function captureQueueItem(ctx: any, text: string, intent: QueueIntent, target: QueueTarget): PowerlineQueueItem {
|
|
1337
|
+
const item = queueStore.add({
|
|
1338
|
+
text,
|
|
1339
|
+
intent,
|
|
1340
|
+
target,
|
|
1341
|
+
source: getQueueContext(ctx),
|
|
1342
|
+
});
|
|
1343
|
+
requestQueueRender();
|
|
1344
|
+
return item;
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
function captureIdeaFromParsedInput(ctx: any, parsed: { target: string | null; text: string }): PowerlineQueueItem | null {
|
|
1348
|
+
const trimmed = parsed.text.trim();
|
|
1349
|
+
if (!trimmed) {
|
|
1350
|
+
ctx.ui.notify("Nothing to capture", "info");
|
|
1351
|
+
return null;
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
const target = targetForIdea(parsed.target, queueStore, ctx.cwd ?? process.cwd());
|
|
1355
|
+
const item = captureQueueItem(ctx, trimmed, "idea", target);
|
|
1356
|
+
ctx.ui.notify(`Idea saved (${item.id}) — /ideas to review`, "info");
|
|
1357
|
+
return item;
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
function captureIdeaFromText(ctx: any, text: string): PowerlineQueueItem | null {
|
|
1361
|
+
return captureIdeaFromParsedInput(ctx, parseTargetPrefix(text));
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
function captureCurrentProjectIdea(ctx: any, text: string): PowerlineQueueItem | null {
|
|
1365
|
+
const trimmed = text.trim();
|
|
1366
|
+
if (!trimmed) {
|
|
1367
|
+
ctx.ui.notify("Nothing to capture", "info");
|
|
1368
|
+
return null;
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
const item = captureQueueItem(ctx, trimmed, "idea", { kind: "project", cwd: ctx.cwd ?? process.cwd() });
|
|
1372
|
+
ctx.ui.notify(`Idea saved (${item.id}) — /ideas to review`, "info");
|
|
1373
|
+
return item;
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
function isSigilIdeaDraft(text: string): boolean {
|
|
1377
|
+
const sigil = config.queue.captureSigil;
|
|
1378
|
+
if (sigil === false) return false;
|
|
1379
|
+
const normalizedSigil = sigil.trim();
|
|
1380
|
+
if (!normalizedSigil) return false;
|
|
1381
|
+
const trimmed = text.trimStart();
|
|
1382
|
+
return trimmed.startsWith(normalizedSigil) && /^\s/.test(trimmed.slice(normalizedSigil.length));
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
function captureSigilGlyph(): string {
|
|
1386
|
+
const sigil = config.queue.captureSigil === false ? "#" : config.queue.captureSigil;
|
|
1387
|
+
return Array.from(sigil)[0] ?? "#";
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
function capturePostCompactPrompt(ctx: any, text: string): PowerlineQueueItem | null {
|
|
1391
|
+
const trimmed = text.trim();
|
|
1392
|
+
if (!trimmed) return null;
|
|
1393
|
+
|
|
1394
|
+
const item = captureQueueItem(ctx, trimmed, "post-compact", { kind: "current-session" });
|
|
1395
|
+
ctx.ui.notify(`Queued for after compaction (${item.id})`, "info");
|
|
1396
|
+
return item;
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
function deliveryModeForItem(ctx: any, item: PowerlineQueueItem): "steer" | "followUp" | undefined {
|
|
1400
|
+
const idle = typeof ctx.isIdle === "function" ? ctx.isIdle() : true;
|
|
1401
|
+
if (idle) return undefined;
|
|
1402
|
+
return item.intent === "steer" ? "steer" : "followUp";
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
function deliverQueueItem(ctx: any, item: PowerlineQueueItem): boolean {
|
|
1406
|
+
if (powerlineCompacting) {
|
|
1407
|
+
queueStore.update(item.id, { status: "queued" });
|
|
1408
|
+
requestQueueRender();
|
|
1409
|
+
return false;
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
queueStore.update(item.id, { status: "delivering", error: undefined });
|
|
1413
|
+
requestQueueRender();
|
|
1414
|
+
|
|
1415
|
+
let sent = false;
|
|
1416
|
+
try {
|
|
1417
|
+
const deliverAs = deliveryModeForItem(ctx, item);
|
|
1418
|
+
const deliveryText = formatQueueDeliveryText(item);
|
|
1419
|
+
if (deliverAs) {
|
|
1420
|
+
pi.sendUserMessage(deliveryText, { deliverAs });
|
|
1421
|
+
} else {
|
|
1422
|
+
pi.sendUserMessage(deliveryText);
|
|
1423
|
+
}
|
|
1424
|
+
sent = true;
|
|
1425
|
+
queueStore.update(item.id, { status: "sent", error: undefined });
|
|
1426
|
+
try {
|
|
1427
|
+
ctx.ui.notify(`Sent queued item ${item.id}`, "info");
|
|
1428
|
+
} catch (error) {
|
|
1429
|
+
if (!isStaleExtensionContextError(error)) throw error;
|
|
1430
|
+
currentCtx = null;
|
|
1431
|
+
}
|
|
1432
|
+
requestQueueRender();
|
|
1433
|
+
return true;
|
|
1434
|
+
} catch (error) {
|
|
1435
|
+
if (isStaleExtensionContextError(error)) {
|
|
1436
|
+
if (!sent) queueStore.update(item.id, { status: "queued", error: undefined });
|
|
1437
|
+
currentCtx = null;
|
|
1438
|
+
throw error;
|
|
1439
|
+
}
|
|
1440
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1441
|
+
queueStore.update(item.id, { status: "failed", error: message });
|
|
1442
|
+
ctx.ui.notify(`Failed to send ${item.id}: ${message}`, "error");
|
|
1443
|
+
requestQueueRender();
|
|
1444
|
+
return false;
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
function schedulePostCompactionDelivery(ctx: any): void {
|
|
1449
|
+
if (queueDeliveryTimer) clearTimeout(queueDeliveryTimer);
|
|
1450
|
+
const queueContext = getQueueContext(ctx);
|
|
1451
|
+
const scheduledGeneration = sessionGeneration;
|
|
1452
|
+
queueDeliveryTimer = setTimeout(() => {
|
|
1453
|
+
queueDeliveryTimer = null;
|
|
1454
|
+
if (scheduledGeneration !== sessionGeneration) return;
|
|
1455
|
+
try {
|
|
1456
|
+
const item = queueStore.queuedDeliveryItems(queueContext, "post-compact")[0];
|
|
1457
|
+
if (item) deliverQueueItem(ctx, item);
|
|
1458
|
+
} catch (error) {
|
|
1459
|
+
if (!isStaleExtensionContextError(error)) throw error;
|
|
1460
|
+
currentCtx = null;
|
|
1461
|
+
}
|
|
1462
|
+
}, 50);
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
function blockPostCompactionQueue(ctx: any, errorMessage: string): void {
|
|
1466
|
+
const items = queueStore.queuedDeliveryItems(getQueueContext(ctx), "post-compact");
|
|
1467
|
+
for (const item of items) {
|
|
1468
|
+
queueStore.update(item.id, { status: "blocked", error: errorMessage });
|
|
1469
|
+
}
|
|
1470
|
+
if (items.length > 0) {
|
|
1471
|
+
ctx.ui.notify(`Kept ${items.length} post-compaction item${items.length === 1 ? "" : "s"} blocked`, "warning");
|
|
1472
|
+
requestQueueRender();
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1476
|
+
function finishFailedCompaction(ctx: any, errorMessage: string): void {
|
|
1477
|
+
powerlineCompacting = false;
|
|
1478
|
+
deliverAfterRetrySettles = false;
|
|
1479
|
+
blockPostCompactionQueue(ctx, errorMessage);
|
|
1480
|
+
requestQueueRender();
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
async function chooseQueueAction(ctx: any, item: PowerlineQueueItem): Promise<void> {
|
|
1484
|
+
const actions: SelectItem[] = [
|
|
1485
|
+
{ value: "send", label: "Send to current session", description: "Deliver as prompt/follow-up" },
|
|
1486
|
+
{ value: "edit", label: "Edit in prompt", description: "Move text into the editor" },
|
|
1487
|
+
{ value: "retry", label: "Retry", description: "Mark queued and deliver" },
|
|
1488
|
+
{ value: "clear", label: "Clear", description: "Mark item done" },
|
|
1489
|
+
{ value: "cancel", label: "Cancel" },
|
|
1490
|
+
];
|
|
1491
|
+
const selected = await showSelectOverlay(ctx, `Queue item ${item.id}`, buildStashPreview(item.text, 72), actions, actions.length);
|
|
1492
|
+
if (!selected || selected.value === "cancel") return;
|
|
1493
|
+
|
|
1494
|
+
if (selected.value === "send") {
|
|
1495
|
+
deliverQueueItem(ctx, item);
|
|
1496
|
+
return;
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
if (selected.value === "retry") {
|
|
1500
|
+
const updated = queueStore.update(item.id, { status: "queued", error: undefined });
|
|
1501
|
+
if (updated) deliverQueueItem(ctx, updated);
|
|
1502
|
+
return;
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
if (selected.value === "edit") {
|
|
1506
|
+
ctx.ui.setEditorText(item.text);
|
|
1507
|
+
queueStore.clear(item.id);
|
|
1508
|
+
requestQueueRender();
|
|
1509
|
+
return;
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
if (selected.value === "clear") {
|
|
1513
|
+
queueStore.clear(item.id);
|
|
1514
|
+
ctx.ui.notify(`Cleared ${item.id}`, "info");
|
|
1515
|
+
requestQueueRender();
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
async function openQueuePicker(ctx: any, mode: "ideas" | "queue"): Promise<void> {
|
|
1520
|
+
const active = queueStore.activeItems(getQueueContext(ctx)).filter((item) => (
|
|
1521
|
+
mode === "ideas" ? item.intent === "idea" : item.intent !== "idea"
|
|
1522
|
+
));
|
|
1523
|
+
if (active.length === 0) {
|
|
1524
|
+
ctx.ui.notify(mode === "ideas" ? "No ideas captured" : "No queued items", "info");
|
|
1525
|
+
return;
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
const items: SelectItem[] = active.map((item) => ({
|
|
1529
|
+
value: item.id,
|
|
1530
|
+
label: queueItemLabel(item),
|
|
1531
|
+
description: queueItemDescription(item),
|
|
1532
|
+
}));
|
|
1533
|
+
const selected = await showSelectOverlay(
|
|
1534
|
+
ctx,
|
|
1535
|
+
mode === "ideas" ? "Powerline ideas" : "Powerline queue",
|
|
1536
|
+
"↑↓ navigate • enter manage • esc cancel",
|
|
1537
|
+
items,
|
|
1538
|
+
Math.min(active.length, 12),
|
|
1539
|
+
);
|
|
1540
|
+
if (!selected) return;
|
|
1541
|
+
|
|
1542
|
+
const item = active.find((candidate) => candidate.id === selected.value);
|
|
1543
|
+
if (item) await chooseQueueAction(ctx, item);
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
function resolveCommandTarget(ctx: any, spec: string): QueueTarget {
|
|
1547
|
+
const normalized = spec.trim().replace(/^@/, "");
|
|
1548
|
+
return targetForIdea(normalized || null, queueStore, ctx.cwd ?? process.cwd());
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
function sendOrRetryQueueItem(ctx: any, idPrefix: string): void {
|
|
1552
|
+
const item = queueStore.get(idPrefix);
|
|
1553
|
+
if (!item) {
|
|
1554
|
+
ctx.ui.notify(`No unique queue item matches ${idPrefix}`, "warning");
|
|
1555
|
+
return;
|
|
1556
|
+
}
|
|
1557
|
+
const updated = queueStore.update(item.id, { status: "queued", error: undefined });
|
|
1558
|
+
if (updated) deliverQueueItem(ctx, updated);
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
function findNextIdea(ctx: any): PowerlineQueueItem | null {
|
|
1562
|
+
return queueStore.activeItems(getQueueContext(ctx)).find((candidate) => candidate.intent === "idea") ?? null;
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
function sendIdeaIssueHandoff(ctx: any, item: PowerlineQueueItem): void {
|
|
1566
|
+
queueStore.update(item.id, { status: "delivering", error: undefined });
|
|
1567
|
+
requestQueueRender();
|
|
1568
|
+
|
|
1569
|
+
try {
|
|
1570
|
+
const deliverAs = deliveryModeForItem(ctx, item);
|
|
1571
|
+
const issuePrompt = formatIdeaIssuePrompt(item);
|
|
1572
|
+
if (deliverAs) {
|
|
1573
|
+
pi.sendUserMessage(issuePrompt, { deliverAs });
|
|
1574
|
+
} else {
|
|
1575
|
+
pi.sendUserMessage(issuePrompt);
|
|
1576
|
+
}
|
|
1577
|
+
queueStore.update(item.id, { status: "sent", error: undefined });
|
|
1578
|
+
ctx.ui.notify(`Sent idea ${item.id} for issue triage`, "info");
|
|
1579
|
+
requestQueueRender();
|
|
1580
|
+
} catch (error) {
|
|
1581
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1582
|
+
queueStore.update(item.id, { status: "failed", error: message });
|
|
1583
|
+
ctx.ui.notify(`Failed to send ${item.id}: ${message}`, "error");
|
|
1584
|
+
requestQueueRender();
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1588
|
+
function sendIdeaIssueHandoffById(ctx: any, id: string | undefined): void {
|
|
1589
|
+
const item = id ? queueStore.get(id) : findNextIdea(ctx);
|
|
1590
|
+
if (!item || item.intent !== "idea") {
|
|
1591
|
+
ctx.ui.notify(id ? `No unique idea matches ${id}` : "No ideas captured", id ? "warning" : "info");
|
|
1592
|
+
return;
|
|
1593
|
+
}
|
|
1594
|
+
sendIdeaIssueHandoff(ctx, item);
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1170
1597
|
// Track session start
|
|
1171
1598
|
setupTpsTracker(pi);
|
|
1172
1599
|
|
|
@@ -1181,6 +1608,9 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
1181
1608
|
isStreaming = false;
|
|
1182
1609
|
liveAssistantUsage = null;
|
|
1183
1610
|
completedAsyncSubagentUsage.clear();
|
|
1611
|
+
approximateContextUsage = event.reason === "reload" ? estimateUnknownContextUsage(ctx) : null;
|
|
1612
|
+
powerlineCompacting = false;
|
|
1613
|
+
deliverAfterRetrySettles = false;
|
|
1184
1614
|
stashedEditorText = null;
|
|
1185
1615
|
|
|
1186
1616
|
const settings = readSettings(ctx.cwd);
|
|
@@ -1191,22 +1621,25 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
1191
1621
|
guideMode: guidePreferences.mode,
|
|
1192
1622
|
});
|
|
1193
1623
|
const newGuideFeatures = getNewGuideFeatures(guidePreferences.lastSeenVersion, VERSION);
|
|
1194
|
-
bashModeSettings = parseBashModeSettings(settings);
|
|
1195
1624
|
resolvedShortcuts = resolveShortcutConfig(settings);
|
|
1625
|
+
bashModeSettings = parseBashModeSettings(settings, resolvedShortcuts);
|
|
1196
1626
|
showLastPrompt = settings.showLastPrompt !== false;
|
|
1197
1627
|
config = parsePowerlineConfig(settings.powerline, PRESET_NAMES);
|
|
1628
|
+
warnInvalidSegmentSettings(ctx);
|
|
1198
1629
|
stashedPromptHistory = readPersistedStashHistory();
|
|
1199
1630
|
bashModeActive = false;
|
|
1200
1631
|
bashTranscript = new BashTranscriptStore(bashModeSettings);
|
|
1201
1632
|
bashCompletionEngine = new BashCompletionEngine();
|
|
1202
1633
|
|
|
1203
|
-
getThinkingLevelFn =
|
|
1204
|
-
|
|
1205
|
-
: null;
|
|
1206
|
-
currentThinkingLevel = getThinkingLevelFn?.() ?? null;
|
|
1634
|
+
getThinkingLevelFn = () => ctx.thinkingLevel ?? "off";
|
|
1635
|
+
currentThinkingLevel = getThinkingLevelFn();
|
|
1207
1636
|
|
|
1208
1637
|
if (ctx.hasUI) {
|
|
1209
1638
|
ctx.ui.setStatus("stash", undefined);
|
|
1639
|
+
const pendingIdeas = queueStore.activeItems(getQueueContext(ctx)).filter((item) => item.intent === "idea").length;
|
|
1640
|
+
if (pendingIdeas > 0) {
|
|
1641
|
+
ctx.ui.notify(`${pendingIdeas} idea${pendingIdeas === 1 ? "" : "s"} waiting — /ideas`, "info");
|
|
1642
|
+
}
|
|
1210
1643
|
}
|
|
1211
1644
|
|
|
1212
1645
|
// Initialize vibe manager (needs modelRegistry from ctx)
|
|
@@ -1218,6 +1651,12 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
1218
1651
|
setupWelcomeOverlay(ctx, newGuideFeatures);
|
|
1219
1652
|
} else if (guideDisplayMode === "compact") {
|
|
1220
1653
|
setupWelcomeHeader(ctx, newGuideFeatures);
|
|
1654
|
+
} else if (shouldShowStartupWelcome(event.reason, config.welcome)) {
|
|
1655
|
+
if (settings.quietStartup === true) {
|
|
1656
|
+
setupWelcomeHeader(ctx, newGuideFeatures);
|
|
1657
|
+
} else {
|
|
1658
|
+
setupWelcomeOverlay(ctx, newGuideFeatures);
|
|
1659
|
+
}
|
|
1221
1660
|
} else {
|
|
1222
1661
|
dismissWelcome(ctx);
|
|
1223
1662
|
}
|
|
@@ -1225,7 +1664,7 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
1225
1664
|
|
|
1226
1665
|
});
|
|
1227
1666
|
|
|
1228
|
-
pi.on("session_shutdown", async () => {
|
|
1667
|
+
pi.on("session_shutdown", async (_event, ctx) => {
|
|
1229
1668
|
sessionGeneration++;
|
|
1230
1669
|
completedAsyncSubagentUsage.clear();
|
|
1231
1670
|
dismissWelcomeOverlay?.();
|
|
@@ -1236,11 +1675,16 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
1236
1675
|
statusRenderScheduler.cancel();
|
|
1237
1676
|
restoreFooterStatusRepaintHook?.();
|
|
1238
1677
|
restoreFooterStatusRepaintHook = null;
|
|
1239
|
-
teardownFixedEditorCompositor({ resetExtendedKeyboardModes: true });
|
|
1240
1678
|
stashShortcutInputUnsubscribe?.();
|
|
1241
1679
|
stashShortcutInputUnsubscribe = null;
|
|
1242
1680
|
shellSession?.dispose();
|
|
1243
1681
|
shellSession = null;
|
|
1682
|
+
if (queueDeliveryTimer) {
|
|
1683
|
+
clearTimeout(queueDeliveryTimer);
|
|
1684
|
+
queueDeliveryTimer = null;
|
|
1685
|
+
}
|
|
1686
|
+
powerlineCompacting = false;
|
|
1687
|
+
deliverAfterRetrySettles = false;
|
|
1244
1688
|
bashModeActive = false;
|
|
1245
1689
|
currentCtx = null;
|
|
1246
1690
|
footerDataRef = null;
|
|
@@ -1280,16 +1724,16 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
1280
1724
|
}
|
|
1281
1725
|
if (event.toolName === "write" || event.toolName === "edit") {
|
|
1282
1726
|
invalidateGitStatus();
|
|
1727
|
+
requestStatusRender();
|
|
1283
1728
|
}
|
|
1284
1729
|
// Check for bash commands that might change git branch
|
|
1285
1730
|
if (event.toolName === "bash" && event.input?.command) {
|
|
1286
1731
|
const cmd = String(event.input.command);
|
|
1287
1732
|
if (mightChangeGitBranch(cmd)) {
|
|
1288
|
-
//
|
|
1733
|
+
// The command has completed, so start refreshing immediately.
|
|
1289
1734
|
invalidateGitStatus();
|
|
1290
1735
|
invalidateGitBranch();
|
|
1291
|
-
|
|
1292
|
-
setTimeout(() => requestStatusRender(), 100);
|
|
1736
|
+
requestStatusRender();
|
|
1293
1737
|
}
|
|
1294
1738
|
}
|
|
1295
1739
|
});
|
|
@@ -1311,6 +1755,7 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
1311
1755
|
|
|
1312
1756
|
pi.on("model_select", async (_event, ctx) => {
|
|
1313
1757
|
currentCtx = ctx;
|
|
1758
|
+
coreContextUsageCache.reset();
|
|
1314
1759
|
requestStatusRender();
|
|
1315
1760
|
});
|
|
1316
1761
|
|
|
@@ -1358,6 +1803,7 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
1358
1803
|
|
|
1359
1804
|
pi.on("message_end", async (event, ctx) => {
|
|
1360
1805
|
currentCtx = ctx;
|
|
1806
|
+
coreContextUsageCache.reset();
|
|
1361
1807
|
if (isSessionAssistantMessage(event.message)) {
|
|
1362
1808
|
if (event.message.stopReason === "error" || event.message.stopReason === "aborted") {
|
|
1363
1809
|
liveAssistantUsage = null;
|
|
@@ -1370,10 +1816,48 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
1370
1816
|
|
|
1371
1817
|
pi.on("turn_end", async (_event, ctx) => {
|
|
1372
1818
|
currentCtx = ctx;
|
|
1819
|
+
coreContextUsageCache.reset();
|
|
1373
1820
|
requestImmediateStatusRender({ deferDuringTyping: false });
|
|
1374
1821
|
});
|
|
1375
1822
|
|
|
1376
|
-
|
|
1823
|
+
pi.on("session_before_compact", async (_event, ctx) => {
|
|
1824
|
+
powerlineCompacting = true;
|
|
1825
|
+
currentCtx = ctx;
|
|
1826
|
+
isStreaming = false;
|
|
1827
|
+
liveAssistantUsage = null;
|
|
1828
|
+
approximateContextUsage = null;
|
|
1829
|
+
coreContextUsageCache.reset();
|
|
1830
|
+
requestQueueRender();
|
|
1831
|
+
});
|
|
1832
|
+
|
|
1833
|
+
pi.on("session_compact", async (event, ctx) => {
|
|
1834
|
+
powerlineCompacting = false;
|
|
1835
|
+
currentCtx = ctx;
|
|
1836
|
+
isStreaming = false;
|
|
1837
|
+
liveAssistantUsage = null;
|
|
1838
|
+
approximateContextUsage = estimateUnknownContextUsage(ctx);
|
|
1839
|
+
coreContextUsageCache.reset();
|
|
1840
|
+
if (event.willRetry) {
|
|
1841
|
+
deliverAfterRetrySettles = true;
|
|
1842
|
+
} else {
|
|
1843
|
+
deliverAfterRetrySettles = false;
|
|
1844
|
+
schedulePostCompactionDelivery(ctx);
|
|
1845
|
+
}
|
|
1846
|
+
requestQueueRender();
|
|
1847
|
+
});
|
|
1848
|
+
|
|
1849
|
+
pi.on("agent_settled", async (_event, ctx) => {
|
|
1850
|
+
if (powerlineCompacting) {
|
|
1851
|
+
finishFailedCompaction(ctx, "Compaction did not complete");
|
|
1852
|
+
return;
|
|
1853
|
+
}
|
|
1854
|
+
if (deliverAfterRetrySettles) {
|
|
1855
|
+
deliverAfterRetrySettles = false;
|
|
1856
|
+
schedulePostCompactionDelivery(ctx);
|
|
1857
|
+
}
|
|
1858
|
+
});
|
|
1859
|
+
|
|
1860
|
+
// Also dismiss on tool calls (agent is working) + refresh vibe if rate limit allows
|
|
1377
1861
|
pi.on("tool_call", async (event, ctx) => {
|
|
1378
1862
|
if (ctx.hasUI) {
|
|
1379
1863
|
// Extract recent agent context from session for richer vibe generation
|
|
@@ -1424,6 +1908,11 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
1424
1908
|
}
|
|
1425
1909
|
}
|
|
1426
1910
|
|
|
1911
|
+
function scheduleDismissWelcome(ctx: any) {
|
|
1912
|
+
if (!dismissWelcomeOverlay && welcomeOverlayShouldDismiss && !welcomeHeaderActive) return;
|
|
1913
|
+
welcomeDismissScheduler.schedule(ctx);
|
|
1914
|
+
}
|
|
1915
|
+
|
|
1427
1916
|
function closeWelcome(ctx: any): void {
|
|
1428
1917
|
dismissWelcomeOverlay?.();
|
|
1429
1918
|
dismissWelcomeOverlay = null;
|
|
@@ -1559,20 +2048,25 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
1559
2048
|
}
|
|
1560
2049
|
}
|
|
1561
2050
|
|
|
1562
|
-
function
|
|
1563
|
-
|
|
2051
|
+
async function handleSelectedStashHistoryEntry(ctx: any, selected: string): Promise<void> {
|
|
2052
|
+
const action = await ctx.ui.select("Stashed prompt", ["Insert", "Promote to idea", "Cancel"]);
|
|
2053
|
+
|
|
2054
|
+
if (action === "Insert") {
|
|
2055
|
+
await insertSelectedPromptHistoryEntry(ctx, selected);
|
|
2056
|
+
return;
|
|
2057
|
+
}
|
|
1564
2058
|
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
2059
|
+
if (action === "Promote to idea") {
|
|
2060
|
+
try {
|
|
2061
|
+
captureIdeaFromText(ctx, selected);
|
|
2062
|
+
} catch (error) {
|
|
2063
|
+
ctx.ui.notify(error instanceof Error ? error.message : String(error), "error");
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
1572
2066
|
}
|
|
1573
2067
|
|
|
1574
|
-
function
|
|
1575
|
-
return
|
|
2068
|
+
function isStashShortcutInput(data: string): boolean {
|
|
2069
|
+
return matchesStashShortcutInput(data, { includePrintableSharpS: config.stashSharpSShortcut });
|
|
1576
2070
|
}
|
|
1577
2071
|
|
|
1578
2072
|
function isPromptHistoryShortcutInput(data: string): boolean {
|
|
@@ -1596,6 +2090,12 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
1596
2090
|
if (matchesConfiguredShortcut(data, resolvedShortcuts.cutEditor)) {
|
|
1597
2091
|
return { kind: "cutEditor" };
|
|
1598
2092
|
}
|
|
2093
|
+
if (matchesConfiguredShortcut(data, resolvedShortcuts.ideaCapture)) {
|
|
2094
|
+
return { kind: "ideaCapture" };
|
|
2095
|
+
}
|
|
2096
|
+
if (matchesConfiguredShortcut(data, resolvedShortcuts.queueOpen)) {
|
|
2097
|
+
return { kind: "queueOpen" };
|
|
2098
|
+
}
|
|
1599
2099
|
if (matchesConfiguredShortcut(data, bashModeSettings.toggleShortcut)) {
|
|
1600
2100
|
return { kind: "bashMode" };
|
|
1601
2101
|
}
|
|
@@ -1604,6 +2104,10 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
1604
2104
|
return chatJumpAction ? { kind: "chat", action: chatJumpAction } : null;
|
|
1605
2105
|
}
|
|
1606
2106
|
|
|
2107
|
+
function getChatJumpShortcutAction(data: string): ChatJumpShortcutAction | null {
|
|
2108
|
+
return CHAT_JUMP_SHORTCUTS.find(({ shortcutKey }) => matchesConfiguredShortcut(data, resolvedShortcuts[shortcutKey]))?.action ?? null;
|
|
2109
|
+
}
|
|
2110
|
+
|
|
1607
2111
|
function runPowerlineShortcut(ctx: any, action: PowerlineShortcutAction): void {
|
|
1608
2112
|
if (action.kind === "stashHistory") {
|
|
1609
2113
|
void openStashHistory(ctx);
|
|
@@ -1622,6 +2126,22 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
1622
2126
|
return;
|
|
1623
2127
|
}
|
|
1624
2128
|
|
|
2129
|
+
if (action.kind === "ideaCapture") {
|
|
2130
|
+
const text = getEditorTextForClipboard(ctx);
|
|
2131
|
+
if (!text) return;
|
|
2132
|
+
|
|
2133
|
+
const item = captureCurrentProjectIdea(ctx, text);
|
|
2134
|
+
if (item) {
|
|
2135
|
+
ctx.ui.setEditorText("");
|
|
2136
|
+
}
|
|
2137
|
+
return;
|
|
2138
|
+
}
|
|
2139
|
+
|
|
2140
|
+
if (action.kind === "queueOpen") {
|
|
2141
|
+
void openQueuePicker(ctx, "queue");
|
|
2142
|
+
return;
|
|
2143
|
+
}
|
|
2144
|
+
|
|
1625
2145
|
if (action.kind === "bashMode") {
|
|
1626
2146
|
void setBashModeActive(!bashModeActive, ctx);
|
|
1627
2147
|
return;
|
|
@@ -1684,27 +2204,241 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
1684
2204
|
: await selectStashedPromptFromHistory(ctx);
|
|
1685
2205
|
if (!selected) return;
|
|
1686
2206
|
|
|
2207
|
+
if (source === "stash") {
|
|
2208
|
+
await handleSelectedStashHistoryEntry(ctx, selected);
|
|
2209
|
+
return;
|
|
2210
|
+
}
|
|
2211
|
+
|
|
1687
2212
|
await insertSelectedPromptHistoryEntry(ctx, selected);
|
|
1688
2213
|
}
|
|
1689
2214
|
|
|
1690
2215
|
pi.on("agent_end", async (_event, ctx) => {
|
|
1691
2216
|
isStreaming = false;
|
|
1692
2217
|
liveAssistantUsage = null;
|
|
2218
|
+
coreContextUsageCache.reset();
|
|
2219
|
+
|
|
2220
|
+
let hasUI = false;
|
|
2221
|
+
try {
|
|
2222
|
+
hasUI = Boolean(ctx.hasUI);
|
|
2223
|
+
} catch (error) {
|
|
2224
|
+
if (!isStaleExtensionContextError(error)) throw error;
|
|
2225
|
+
currentCtx = null;
|
|
2226
|
+
return;
|
|
2227
|
+
}
|
|
2228
|
+
|
|
1693
2229
|
currentCtx = ctx;
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
if (
|
|
1698
|
-
ctx.ui.
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
2230
|
+
try {
|
|
2231
|
+
if (hasUI) {
|
|
2232
|
+
onVibeAgentEnd(ctx.ui.setWorkingMessage); // working-vibes internal state + reset message
|
|
2233
|
+
if (stashedEditorText !== null) {
|
|
2234
|
+
if (ctx.ui.getEditorText().trim() === "") {
|
|
2235
|
+
ctx.ui.setEditorText(stashedEditorText);
|
|
2236
|
+
stashedEditorText = null;
|
|
2237
|
+
ctx.ui.setStatus("stash", undefined);
|
|
2238
|
+
ctx.ui.notify("Stash restored", "info");
|
|
2239
|
+
} else {
|
|
2240
|
+
ctx.ui.notify("Stash preserved — clear editor then Alt+S to restore", "info");
|
|
2241
|
+
}
|
|
1704
2242
|
}
|
|
1705
2243
|
}
|
|
2244
|
+
} catch (error) {
|
|
2245
|
+
if (!isStaleExtensionContextError(error)) throw error;
|
|
2246
|
+
currentCtx = null;
|
|
2247
|
+
return;
|
|
1706
2248
|
}
|
|
2249
|
+
|
|
1707
2250
|
requestStatusRender();
|
|
2251
|
+
if (!powerlineCompacting && !deliverAfterRetrySettles) {
|
|
2252
|
+
schedulePostCompactionDelivery(ctx);
|
|
2253
|
+
}
|
|
2254
|
+
});
|
|
2255
|
+
|
|
2256
|
+
registerCdCommand(pi, () => currentCtx?.cwd ?? process.cwd());
|
|
2257
|
+
|
|
2258
|
+
pi.registerCommand("idea", {
|
|
2259
|
+
description: "Capture an idea without interrupting the current agent. Usage: /idea [@alias|@global|@current] <text> | /idea issue [id]",
|
|
2260
|
+
handler: async (args, ctx) => {
|
|
2261
|
+
currentCtx = ctx;
|
|
2262
|
+
const trimmedArgs = args.trim();
|
|
2263
|
+
const [action, id] = trimmedArgs.split(/\s+/).filter(Boolean);
|
|
2264
|
+
if (action === "issue") {
|
|
2265
|
+
sendIdeaIssueHandoffById(ctx, id);
|
|
2266
|
+
return;
|
|
2267
|
+
}
|
|
2268
|
+
|
|
2269
|
+
const raw = trimmedArgs || getCurrentEditorText(ctx, currentEditor).trim();
|
|
2270
|
+
if (!raw) {
|
|
2271
|
+
ctx.ui.notify("Usage: /idea [@alias|@global|@current] <text> | /idea issue [id]", "info");
|
|
2272
|
+
return;
|
|
2273
|
+
}
|
|
2274
|
+
|
|
2275
|
+
try {
|
|
2276
|
+
const item = captureIdeaFromText(ctx, raw);
|
|
2277
|
+
if (item && !trimmedArgs) {
|
|
2278
|
+
ctx.ui.setEditorText("");
|
|
2279
|
+
}
|
|
2280
|
+
} catch (error) {
|
|
2281
|
+
ctx.ui.notify(error instanceof Error ? error.message : String(error), "error");
|
|
2282
|
+
}
|
|
2283
|
+
},
|
|
2284
|
+
});
|
|
2285
|
+
|
|
2286
|
+
pi.registerCommand("ideas", {
|
|
2287
|
+
description: "Review or send captured ideas. Usage: /ideas next | /ideas issue [id] | /ideas [send|retry|clear|edit] <id>",
|
|
2288
|
+
handler: async (args, ctx) => {
|
|
2289
|
+
currentCtx = ctx;
|
|
2290
|
+
const parts = args.trim().split(/\s+/).filter(Boolean);
|
|
2291
|
+
const action = parts[0];
|
|
2292
|
+
const id = parts[1];
|
|
2293
|
+
|
|
2294
|
+
if (!action) {
|
|
2295
|
+
await openQueuePicker(ctx, "ideas");
|
|
2296
|
+
return;
|
|
2297
|
+
}
|
|
2298
|
+
|
|
2299
|
+
if (action === "next") {
|
|
2300
|
+
const item = findNextIdea(ctx);
|
|
2301
|
+
if (!item) {
|
|
2302
|
+
ctx.ui.notify("No ideas captured", "info");
|
|
2303
|
+
return;
|
|
2304
|
+
}
|
|
2305
|
+
const updated = queueStore.update(item.id, { status: "queued", target: { kind: "current-session" }, error: undefined });
|
|
2306
|
+
if (updated) deliverQueueItem(ctx, updated);
|
|
2307
|
+
return;
|
|
2308
|
+
}
|
|
2309
|
+
|
|
2310
|
+
if (action === "issue") {
|
|
2311
|
+
sendIdeaIssueHandoffById(ctx, id);
|
|
2312
|
+
return;
|
|
2313
|
+
}
|
|
2314
|
+
|
|
2315
|
+
if (!id) {
|
|
2316
|
+
ctx.ui.notify("Usage: /ideas next | /ideas issue [id] | /ideas [send|retry|clear|edit] <id>", "info");
|
|
2317
|
+
return;
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2320
|
+
const item = queueStore.get(id);
|
|
2321
|
+
if (!item || item.intent !== "idea") {
|
|
2322
|
+
ctx.ui.notify(`No unique idea matches ${id}`, "warning");
|
|
2323
|
+
return;
|
|
2324
|
+
}
|
|
2325
|
+
|
|
2326
|
+
if (action === "send" || action === "retry") {
|
|
2327
|
+
const updated = queueStore.update(item.id, { status: "queued", target: { kind: "current-session" }, error: undefined });
|
|
2328
|
+
if (updated) deliverQueueItem(ctx, updated);
|
|
2329
|
+
return;
|
|
2330
|
+
}
|
|
2331
|
+
|
|
2332
|
+
if (action === "edit") {
|
|
2333
|
+
ctx.ui.setEditorText(item.text);
|
|
2334
|
+
queueStore.clear(item.id);
|
|
2335
|
+
requestQueueRender();
|
|
2336
|
+
return;
|
|
2337
|
+
}
|
|
2338
|
+
|
|
2339
|
+
if (action === "clear") {
|
|
2340
|
+
queueStore.clear(item.id);
|
|
2341
|
+
ctx.ui.notify(`Cleared idea ${item.id}`, "info");
|
|
2342
|
+
requestQueueRender();
|
|
2343
|
+
return;
|
|
2344
|
+
}
|
|
2345
|
+
|
|
2346
|
+
ctx.ui.notify("Usage: /ideas next | /ideas issue [id] | /ideas [send|retry|clear|edit] <id>", "info");
|
|
2347
|
+
},
|
|
2348
|
+
});
|
|
2349
|
+
|
|
2350
|
+
pi.registerCommand("queue", {
|
|
2351
|
+
description: "Manage Powerline queued prompts and project aliases",
|
|
2352
|
+
handler: async (args, ctx) => {
|
|
2353
|
+
currentCtx = ctx;
|
|
2354
|
+
const parts = args.trim().split(/\s+/).filter(Boolean);
|
|
2355
|
+
const action = parts[0];
|
|
2356
|
+
|
|
2357
|
+
if (!action) {
|
|
2358
|
+
await openQueuePicker(ctx, "queue");
|
|
2359
|
+
return;
|
|
2360
|
+
}
|
|
2361
|
+
|
|
2362
|
+
if (action === "alias") {
|
|
2363
|
+
const alias = parts[1];
|
|
2364
|
+
const aliasPath = parts.slice(2).join(" ") || ctx.cwd || process.cwd();
|
|
2365
|
+
if (!alias) {
|
|
2366
|
+
ctx.ui.notify("Usage: /queue alias <name> [path]", "info");
|
|
2367
|
+
return;
|
|
2368
|
+
}
|
|
2369
|
+
try {
|
|
2370
|
+
queueStore.setAlias(alias, aliasPath);
|
|
2371
|
+
ctx.ui.notify(`Alias @${alias} → ${aliasPath}`, "info");
|
|
2372
|
+
} catch (error) {
|
|
2373
|
+
ctx.ui.notify(error instanceof Error ? error.message : String(error), "error");
|
|
2374
|
+
}
|
|
2375
|
+
return;
|
|
2376
|
+
}
|
|
2377
|
+
|
|
2378
|
+
if (action === "send" || action === "retry") {
|
|
2379
|
+
const id = parts[1];
|
|
2380
|
+
if (!id) {
|
|
2381
|
+
const item = queueStore.queuedDeliveryItems(getQueueContext(ctx))[0];
|
|
2382
|
+
if (!item) {
|
|
2383
|
+
ctx.ui.notify("No queued item to send", "info");
|
|
2384
|
+
return;
|
|
2385
|
+
}
|
|
2386
|
+
sendOrRetryQueueItem(ctx, item.id);
|
|
2387
|
+
return;
|
|
2388
|
+
}
|
|
2389
|
+
sendOrRetryQueueItem(ctx, id);
|
|
2390
|
+
return;
|
|
2391
|
+
}
|
|
2392
|
+
|
|
2393
|
+
if (action === "clear") {
|
|
2394
|
+
const id = parts[1];
|
|
2395
|
+
if (id === "all") {
|
|
2396
|
+
const active = queueStore.activeItems(getQueueContext(ctx)).filter((item) => item.intent !== "idea");
|
|
2397
|
+
for (const item of active) queueStore.clear(item.id);
|
|
2398
|
+
ctx.ui.notify(`Cleared ${active.length} queued item${active.length === 1 ? "" : "s"}`, "info");
|
|
2399
|
+
requestQueueRender();
|
|
2400
|
+
return;
|
|
2401
|
+
}
|
|
2402
|
+
if (!id) {
|
|
2403
|
+
ctx.ui.notify("Usage: /queue clear <id|all>", "info");
|
|
2404
|
+
return;
|
|
2405
|
+
}
|
|
2406
|
+
const item = queueStore.get(id);
|
|
2407
|
+
if (!item || item.intent === "idea") {
|
|
2408
|
+
ctx.ui.notify(`No unique queued item matches ${id}`, "warning");
|
|
2409
|
+
return;
|
|
2410
|
+
}
|
|
2411
|
+
queueStore.clear(item.id);
|
|
2412
|
+
ctx.ui.notify(`Cleared ${item.id}`, "info");
|
|
2413
|
+
requestQueueRender();
|
|
2414
|
+
return;
|
|
2415
|
+
}
|
|
2416
|
+
|
|
2417
|
+
if (action === "target") {
|
|
2418
|
+
const id = parts[1];
|
|
2419
|
+
const spec = parts[2];
|
|
2420
|
+
if (!id || !spec) {
|
|
2421
|
+
ctx.ui.notify("Usage: /queue target <id> @alias|global|current", "info");
|
|
2422
|
+
return;
|
|
2423
|
+
}
|
|
2424
|
+
const item = queueStore.get(id);
|
|
2425
|
+
if (!item) {
|
|
2426
|
+
ctx.ui.notify(`No unique queue item matches ${id}`, "warning");
|
|
2427
|
+
return;
|
|
2428
|
+
}
|
|
2429
|
+
try {
|
|
2430
|
+
const target = resolveCommandTarget(ctx, spec);
|
|
2431
|
+
queueStore.update(item.id, { target });
|
|
2432
|
+
ctx.ui.notify(`Retargeted ${item.id}`, "info");
|
|
2433
|
+
requestQueueRender();
|
|
2434
|
+
} catch (error) {
|
|
2435
|
+
ctx.ui.notify(error instanceof Error ? error.message : String(error), "error");
|
|
2436
|
+
}
|
|
2437
|
+
return;
|
|
2438
|
+
}
|
|
2439
|
+
|
|
2440
|
+
ctx.ui.notify("Usage: /queue [send|retry|clear|target|alias]", "info");
|
|
2441
|
+
},
|
|
1708
2442
|
});
|
|
1709
2443
|
|
|
1710
2444
|
pi.registerCommand("guide", {
|
|
@@ -1778,7 +2512,6 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
1778
2512
|
ctx.ui.setStatus("stash", undefined);
|
|
1779
2513
|
restoreFooterStatusRepaintHook?.();
|
|
1780
2514
|
restoreFooterStatusRepaintHook = null;
|
|
1781
|
-
teardownFixedEditorCompositor();
|
|
1782
2515
|
stashShortcutInputUnsubscribe?.();
|
|
1783
2516
|
stashShortcutInputUnsubscribe = null;
|
|
1784
2517
|
// Clear all custom UI components
|
|
@@ -1789,6 +2522,7 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
1789
2522
|
ctx.ui.setWidget("powerline-secondary", undefined);
|
|
1790
2523
|
ctx.ui.setWidget("powerline-bash-transcript", undefined);
|
|
1791
2524
|
ctx.ui.setWidget("powerline-status", undefined);
|
|
2525
|
+
ctx.ui.setWidget("powerline-queue-preview", undefined);
|
|
1792
2526
|
ctx.ui.setWidget("powerline-last-prompt", undefined);
|
|
1793
2527
|
footerDataRef = null;
|
|
1794
2528
|
tuiRef = null;
|
|
@@ -1801,34 +2535,19 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
1801
2535
|
}
|
|
1802
2536
|
|
|
1803
2537
|
const normalizedArgs = args.trim().toLowerCase();
|
|
1804
|
-
const
|
|
1805
|
-
if (
|
|
1806
|
-
const
|
|
1807
|
-
config.
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
2538
|
+
const placementMatch = /^placement(?:\s+(above|below|toggle))?$/.exec(normalizedArgs);
|
|
2539
|
+
if (placementMatch) {
|
|
2540
|
+
const requestedPlacement = placementMatch[1];
|
|
2541
|
+
config.placement = requestedPlacement === "above" || requestedPlacement === "below"
|
|
2542
|
+
? requestedPlacement
|
|
2543
|
+
: config.placement === "above" ? "below" : "above";
|
|
2544
|
+
config.invalidPlacement = null;
|
|
2545
|
+
if (enabled && ctx.hasUI) setupCustomEditor(ctx);
|
|
2546
|
+
|
|
2547
|
+
if (writePowerlineOptionSetting(ctx.cwd, { placement: config.placement }, config.preset)) {
|
|
2548
|
+
ctx.ui.notify(`Powerline placement set to: ${config.placement}`, "info");
|
|
1814
2549
|
} else {
|
|
1815
|
-
ctx.ui.notify(`Powerline
|
|
1816
|
-
}
|
|
1817
|
-
return;
|
|
1818
|
-
}
|
|
1819
|
-
|
|
1820
|
-
const fixedEditorMatch = /^fixed-editor(?:\s+(on|off|toggle))?$/.exec(normalizedArgs);
|
|
1821
|
-
if (fixedEditorMatch) {
|
|
1822
|
-
const mode = fixedEditorMatch[1] ?? "toggle";
|
|
1823
|
-
config.fixedEditor = mode === "toggle" ? !config.fixedEditor : mode === "on";
|
|
1824
|
-
if (enabled && ctx.hasUI) {
|
|
1825
|
-
setupCustomEditor(ctx);
|
|
1826
|
-
}
|
|
1827
|
-
|
|
1828
|
-
if (writePowerlineOptionSetting(ctx.cwd, { fixedEditor: config.fixedEditor }, config.preset)) {
|
|
1829
|
-
ctx.ui.notify(`Powerline fixed editor ${config.fixedEditor ? "enabled" : "disabled"}`, "info");
|
|
1830
|
-
} else {
|
|
1831
|
-
ctx.ui.notify(`Powerline fixed editor ${config.fixedEditor ? "enabled" : "disabled"} (not persisted; check settings.json)`, "warning");
|
|
2550
|
+
ctx.ui.notify(`Powerline placement set to: ${config.placement} (not persisted; check settings.json)`, "warning");
|
|
1832
2551
|
}
|
|
1833
2552
|
return;
|
|
1834
2553
|
}
|
|
@@ -1910,65 +2629,6 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
1910
2629
|
},
|
|
1911
2630
|
});
|
|
1912
2631
|
|
|
1913
|
-
pi.registerShortcut(bashModeSettings.toggleShortcut, {
|
|
1914
|
-
description: "Toggle bash mode",
|
|
1915
|
-
handler: async (ctx) => {
|
|
1916
|
-
if (!enabled || !ctx.hasUI) return;
|
|
1917
|
-
await setBashModeActive(!bashModeActive, ctx);
|
|
1918
|
-
},
|
|
1919
|
-
});
|
|
1920
|
-
|
|
1921
|
-
pi.registerShortcut("alt+s", {
|
|
1922
|
-
description: "Stash/restore editor text",
|
|
1923
|
-
handler: async (ctx) => {
|
|
1924
|
-
if (!enabled || !ctx.hasUI) return;
|
|
1925
|
-
stashOrRestoreEditorText(ctx);
|
|
1926
|
-
},
|
|
1927
|
-
});
|
|
1928
|
-
|
|
1929
|
-
pi.registerShortcut(resolvedShortcuts.stashHistory, {
|
|
1930
|
-
description: "Open prompt history picker",
|
|
1931
|
-
handler: async (ctx) => {
|
|
1932
|
-
if (!enabled || !ctx.hasUI) return;
|
|
1933
|
-
await openStashHistory(ctx);
|
|
1934
|
-
},
|
|
1935
|
-
});
|
|
1936
|
-
|
|
1937
|
-
pi.registerShortcut(resolvedShortcuts.copyEditor, {
|
|
1938
|
-
description: "Copy full editor text",
|
|
1939
|
-
handler: async (ctx) => {
|
|
1940
|
-
if (!enabled || !ctx.hasUI) return;
|
|
1941
|
-
|
|
1942
|
-
const text = getEditorTextForClipboard(ctx);
|
|
1943
|
-
if (!text) return;
|
|
1944
|
-
|
|
1945
|
-
copyTextToClipboard(ctx, text, "Copied editor text");
|
|
1946
|
-
},
|
|
1947
|
-
});
|
|
1948
|
-
|
|
1949
|
-
pi.registerShortcut(resolvedShortcuts.cutEditor, {
|
|
1950
|
-
description: "Cut full editor text",
|
|
1951
|
-
handler: async (ctx) => {
|
|
1952
|
-
if (!enabled || !ctx.hasUI) return;
|
|
1953
|
-
|
|
1954
|
-
const text = getEditorTextForClipboard(ctx);
|
|
1955
|
-
if (!text) return;
|
|
1956
|
-
|
|
1957
|
-
copyTextToClipboard(ctx, text);
|
|
1958
|
-
ctx.ui.setEditorText("");
|
|
1959
|
-
ctx.ui.notify("Cut editor text", "info");
|
|
1960
|
-
},
|
|
1961
|
-
});
|
|
1962
|
-
|
|
1963
|
-
for (const { shortcutKey, description, action } of CHAT_JUMP_SHORTCUTS) {
|
|
1964
|
-
pi.registerShortcut(resolvedShortcuts[shortcutKey], {
|
|
1965
|
-
description,
|
|
1966
|
-
handler: async (ctx) => {
|
|
1967
|
-
if (!enabled || !ctx.hasUI) return;
|
|
1968
|
-
runPowerlineShortcut(ctx, { kind: "chat", action });
|
|
1969
|
-
},
|
|
1970
|
-
});
|
|
1971
|
-
}
|
|
1972
2632
|
|
|
1973
2633
|
// Command to set working message theme
|
|
1974
2634
|
pi.registerCommand("vibe", {
|
|
@@ -2040,17 +2700,13 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2040
2700
|
|
|
2041
2701
|
// /vibe generate <theme> [count] - generate vibes and save to file
|
|
2042
2702
|
if (subcommand === "generate") {
|
|
2043
|
-
const
|
|
2044
|
-
|
|
2045
|
-
const count = Number.isFinite(parsedCount)
|
|
2046
|
-
? Math.min(Math.max(Math.floor(parsedCount), 1), 500)
|
|
2047
|
-
: 100;
|
|
2048
|
-
|
|
2049
|
-
if (!theme) {
|
|
2703
|
+
const parsed = parseVibeGenerateArgs(parts.slice(1));
|
|
2704
|
+
if (!parsed) {
|
|
2050
2705
|
ctx.ui.notify("Usage: /vibe generate <theme> [count]", "error");
|
|
2051
2706
|
return;
|
|
2052
2707
|
}
|
|
2053
2708
|
|
|
2709
|
+
const { theme, count } = parsed;
|
|
2054
2710
|
ctx.ui.notify(`Generating ${count} vibes for "${theme}"...`, "info");
|
|
2055
2711
|
|
|
2056
2712
|
const result = await generateVibesBatch(theme, count);
|
|
@@ -2108,53 +2764,14 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2108
2764
|
const presetDef = getPreset(config.preset);
|
|
2109
2765
|
const colors: ColorScheme = presetDef.colors ?? getDefaultColors();
|
|
2110
2766
|
|
|
2111
|
-
// Build usage stats and get thinking level from session
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
continue;
|
|
2120
|
-
}
|
|
2121
|
-
|
|
2122
|
-
// Check for thinking level change entries
|
|
2123
|
-
if (e.type === "thinking_level_change" && typeof e.thinkingLevel === "string") {
|
|
2124
|
-
thinkingLevelFromSession = e.thinkingLevel;
|
|
2125
|
-
}
|
|
2126
|
-
|
|
2127
|
-
if (e.type !== "message") {
|
|
2128
|
-
continue;
|
|
2129
|
-
}
|
|
2130
|
-
|
|
2131
|
-
const subagentUsage = readSubagentToolResultUsage(e.message);
|
|
2132
|
-
if (subagentUsage) {
|
|
2133
|
-
input += subagentUsage.input;
|
|
2134
|
-
output += subagentUsage.output;
|
|
2135
|
-
cacheRead += subagentUsage.cacheRead;
|
|
2136
|
-
cacheWrite += subagentUsage.cacheWrite;
|
|
2137
|
-
cost += subagentUsage.cost;
|
|
2138
|
-
continue;
|
|
2139
|
-
}
|
|
2140
|
-
|
|
2141
|
-
if (!isSessionAssistantMessage(e.message)) {
|
|
2142
|
-
continue;
|
|
2143
|
-
}
|
|
2144
|
-
|
|
2145
|
-
const m = e.message;
|
|
2146
|
-
if (m.stopReason === "error" || m.stopReason === "aborted") {
|
|
2147
|
-
continue;
|
|
2148
|
-
}
|
|
2149
|
-
input += m.usage.input;
|
|
2150
|
-
output += m.usage.output;
|
|
2151
|
-
cacheRead += m.usage.cacheRead;
|
|
2152
|
-
cacheWrite += m.usage.cacheWrite;
|
|
2153
|
-
cost += m.usage.cost.total;
|
|
2154
|
-
if (getUsageTokenTotal(m.usage) > 0) {
|
|
2155
|
-
lastAssistant = m;
|
|
2156
|
-
}
|
|
2157
|
-
}
|
|
2767
|
+
// Build usage stats and get thinking level from session (cached; the full
|
|
2768
|
+
// event list is only re-scanned when events are appended or the trailing
|
|
2769
|
+
// event's stats-relevant fields change, e.g. in-place streaming updates)
|
|
2770
|
+
const sessionEvents = sessionBranchCache.get(ctx.sessionManager);
|
|
2771
|
+
const tokenStats = tokenStatsCache.get(sessionEvents);
|
|
2772
|
+
let { input, output, cacheRead, cacheWrite, cost, subagentCost } = tokenStats;
|
|
2773
|
+
const lastAssistant = tokenStats.lastAssistant;
|
|
2774
|
+
const thinkingLevelFromSession = tokenStats.thinkingLevelFromSession;
|
|
2158
2775
|
|
|
2159
2776
|
for (const subagentUsage of completedAsyncSubagentUsage.values()) {
|
|
2160
2777
|
input += subagentUsage.input;
|
|
@@ -2166,14 +2783,25 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2166
2783
|
|
|
2167
2784
|
// Calculate context percentage.
|
|
2168
2785
|
const latestUsage = isStreaming ? liveAssistantUsage ?? lastAssistant?.usage : lastAssistant?.usage;
|
|
2169
|
-
const coreContextUsage = isStreaming && liveAssistantUsage ? null :
|
|
2170
|
-
const
|
|
2171
|
-
const
|
|
2172
|
-
|
|
2786
|
+
const coreContextUsage = isStreaming && liveAssistantUsage ? null : coreContextUsageCache.get(ctx);
|
|
2787
|
+
const fallbackContextTokens = latestUsage ? getUsageTokenTotal(latestUsage) : 0;
|
|
2788
|
+
const {
|
|
2789
|
+
contextTokens,
|
|
2790
|
+
contextWindow,
|
|
2791
|
+
contextPercent,
|
|
2792
|
+
} = resolveDisplayContextUsage({
|
|
2793
|
+
coreContextUsage,
|
|
2794
|
+
unknownCoreFallback: approximateContextUsage,
|
|
2795
|
+
fallbackContextTokens,
|
|
2796
|
+
fallbackContextWindow: ctx.model?.contextWindow ?? 0,
|
|
2797
|
+
});
|
|
2798
|
+
const contextApproximate = coreContextUsage?.contextTokens === null && approximateContextUsage !== null;
|
|
2799
|
+
|
|
2800
|
+
const segmentOptions = mergeSegmentOptions(presetDef.segmentOptions, config.segmentOptions);
|
|
2173
2801
|
|
|
2174
2802
|
// Get git status (cached)
|
|
2175
2803
|
const gitBranch = footerDataRef?.getGitBranch() ?? null;
|
|
2176
|
-
const gitStatus = getGitStatus(gitBranch);
|
|
2804
|
+
const gitStatus = getGitStatus(gitBranch, segmentOptions.git?.polling);
|
|
2177
2805
|
const extensionStatuses = footerDataRef?.getExtensionStatuses() ?? new Map();
|
|
2178
2806
|
const customItemsById = new Map(config.customItems.map((item) => [item.id, item]));
|
|
2179
2807
|
const hiddenExtensionStatusKeys = collectHiddenExtensionStatusKeys(config.customItems);
|
|
@@ -2184,6 +2812,7 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2184
2812
|
: false;
|
|
2185
2813
|
|
|
2186
2814
|
const thinkingLevel = currentThinkingLevel ?? thinkingLevelFromSession ?? getThinkingLevelFn?.() ?? "off";
|
|
2815
|
+
const queueSummary = queueStore.summarize(getQueueContext(ctx), powerlineCompacting);
|
|
2187
2816
|
|
|
2188
2817
|
return {
|
|
2189
2818
|
model: ctx.model,
|
|
@@ -2191,12 +2820,15 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2191
2820
|
sessionId: ctx.sessionManager?.getSessionId?.(),
|
|
2192
2821
|
sessionName: getCurrentSessionName(ctx),
|
|
2193
2822
|
cwd: ctx.cwd,
|
|
2194
|
-
usageStats: { input, output, cacheRead, cacheWrite, cost },
|
|
2823
|
+
usageStats: { input, output, cacheRead, cacheWrite, cost, subagentCost },
|
|
2824
|
+
contextTokens,
|
|
2195
2825
|
contextPercent,
|
|
2196
2826
|
contextWindow,
|
|
2827
|
+
contextApproximate,
|
|
2197
2828
|
autoCompactEnabled: ctx.settingsManager?.getCompactionSettings?.()?.enabled ?? true,
|
|
2198
2829
|
customCompactionEnabled: customCompactionEnabled || extensionStatuses.has(CUSTOM_COMPACTION_STATUS_KEY),
|
|
2199
2830
|
usingSubscription,
|
|
2831
|
+
queueSummary,
|
|
2200
2832
|
sessionStartTime,
|
|
2201
2833
|
shellModeActive: bashModeActive,
|
|
2202
2834
|
shellRunning: shellSession?.state.running ?? false,
|
|
@@ -2206,7 +2838,7 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2206
2838
|
extensionStatuses,
|
|
2207
2839
|
hiddenExtensionStatusKeys,
|
|
2208
2840
|
customItemsById,
|
|
2209
|
-
options:
|
|
2841
|
+
options: segmentOptions,
|
|
2210
2842
|
theme,
|
|
2211
2843
|
colors,
|
|
2212
2844
|
};
|
|
@@ -2235,7 +2867,19 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2235
2867
|
}
|
|
2236
2868
|
|
|
2237
2869
|
const presetDef = getPreset(config.preset);
|
|
2238
|
-
|
|
2870
|
+
let segmentCtx: SegmentContext;
|
|
2871
|
+
try {
|
|
2872
|
+
segmentCtx = buildSegmentContext(currentCtx, theme);
|
|
2873
|
+
} catch (error) {
|
|
2874
|
+
if (!isStaleExtensionContextError(error)) throw error;
|
|
2875
|
+
currentCtx = null;
|
|
2876
|
+
lastLayoutWidth = width;
|
|
2877
|
+
lastLayoutResult = { topContent: "", secondaryContent: "" };
|
|
2878
|
+
lastLayoutTimestamp = now;
|
|
2879
|
+
layoutDirty = false;
|
|
2880
|
+
forceNextLayoutRecompute = false;
|
|
2881
|
+
return lastLayoutResult;
|
|
2882
|
+
}
|
|
2239
2883
|
|
|
2240
2884
|
lastLayoutWidth = width;
|
|
2241
2885
|
lastLayoutResult = computeResponsiveLayout(segmentCtx, presetDef, width);
|
|
@@ -2265,7 +2909,7 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2265
2909
|
return notifications;
|
|
2266
2910
|
}
|
|
2267
2911
|
|
|
2268
|
-
function
|
|
2912
|
+
function renderPowerlinePrimaryLines(width: number, theme: Theme): string[] {
|
|
2269
2913
|
if (!currentCtx) return [];
|
|
2270
2914
|
|
|
2271
2915
|
const layout = getResponsiveLayout(width, theme);
|
|
@@ -2279,6 +2923,23 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2279
2923
|
return layout.secondaryContent ? [layout.secondaryContent] : [];
|
|
2280
2924
|
}
|
|
2281
2925
|
|
|
2926
|
+
function renderPowerlineQueuePreviewLines(width: number, theme: Theme): string[] {
|
|
2927
|
+
if (!currentCtx) return [];
|
|
2928
|
+
const summary = queueStore.summarize(getQueueContext(currentCtx), powerlineCompacting);
|
|
2929
|
+
if (!summary.leadingText) return [];
|
|
2930
|
+
|
|
2931
|
+
const prefix = summary.leadingStatus === "blocked" || summary.leadingStatus === "failed"
|
|
2932
|
+
? "blocked: "
|
|
2933
|
+
: summary.leadingStatus === "delivering"
|
|
2934
|
+
? "sending: "
|
|
2935
|
+
: summary.leadingIntent === "idea"
|
|
2936
|
+
? "idea: "
|
|
2937
|
+
: "queued: ";
|
|
2938
|
+
const text = `${prefix}${summary.leadingText.replace(/\s+/g, " ").trim()}`;
|
|
2939
|
+
const color = summary.leadingStatus === "blocked" || summary.leadingStatus === "failed" ? "warning" : "dim";
|
|
2940
|
+
return [` ${theme.fg(color, truncateToWidth(text, Math.max(1, width - 1), "…"))}`];
|
|
2941
|
+
}
|
|
2942
|
+
|
|
2282
2943
|
function renderBashTranscriptLines(width: number, theme: Theme): string[] {
|
|
2283
2944
|
if (!bashModeActive) return [];
|
|
2284
2945
|
|
|
@@ -2383,8 +3044,8 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2383
3044
|
terminal: tui.terminal,
|
|
2384
3045
|
mouseScroll: config.mouseScroll,
|
|
2385
3046
|
keyboardScrollShortcuts: {
|
|
2386
|
-
up: resolvedShortcuts.scrollChatUp,
|
|
2387
|
-
down: resolvedShortcuts.scrollChatDown,
|
|
3047
|
+
up: resolvedShortcuts.scrollChatUp ?? "super+up",
|
|
3048
|
+
down: resolvedShortcuts.scrollChatDown ?? "super+down",
|
|
2388
3049
|
},
|
|
2389
3050
|
shouldCaptureKeyboardScroll: () => Reflect.get(tui, "focusedComponent") === currentEditor,
|
|
2390
3051
|
onCopySelection: (text) => copyTextToClipboard(ctx, text),
|
|
@@ -2400,7 +3061,7 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2400
3061
|
width,
|
|
2401
3062
|
terminalRows,
|
|
2402
3063
|
statusLines: [...aboveWidgetLines, ...renderPowerlineStatusLines(width), ...statusContainerLines],
|
|
2403
|
-
topLines:
|
|
3064
|
+
topLines: renderPowerlinePrimaryLines(width, theme),
|
|
2404
3065
|
editorLines: fixedEditorContainer ? compositor.renderHidden(fixedEditorContainer, width) : [],
|
|
2405
3066
|
secondaryLines: [...renderPowerlineSecondaryLines(width, theme), ...belowWidgetLines],
|
|
2406
3067
|
transcriptLines: renderBashTranscriptLines(width, theme),
|
|
@@ -2530,9 +3191,9 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2530
3191
|
resetLayoutCache();
|
|
2531
3192
|
},
|
|
2532
3193
|
render(width: number): string[] {
|
|
2533
|
-
return
|
|
3194
|
+
return renderPowerlinePrimaryLines(width, theme);
|
|
2534
3195
|
},
|
|
2535
|
-
}), { placement: "aboveEditor" });
|
|
3196
|
+
}), { placement: config.placement === "below" ? "belowEditor" : "aboveEditor" });
|
|
2536
3197
|
|
|
2537
3198
|
ctx.ui.setWidget("powerline-secondary", (_tui: any, theme: Theme) => ({
|
|
2538
3199
|
dispose() {},
|
|
@@ -2552,6 +3213,14 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2552
3213
|
},
|
|
2553
3214
|
}), { placement: "belowEditor" });
|
|
2554
3215
|
|
|
3216
|
+
ctx.ui.setWidget("powerline-queue-preview", (_tui: any, theme: Theme) => ({
|
|
3217
|
+
dispose() {},
|
|
3218
|
+
invalidate() {},
|
|
3219
|
+
render(width: number): string[] {
|
|
3220
|
+
return renderPowerlineQueuePreviewLines(width, theme);
|
|
3221
|
+
},
|
|
3222
|
+
}), { placement: "belowEditor" });
|
|
3223
|
+
|
|
2555
3224
|
ctx.ui.setWidget("powerline-last-prompt", () => ({
|
|
2556
3225
|
dispose() {},
|
|
2557
3226
|
invalidate() {},
|
|
@@ -2590,16 +3259,18 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2590
3259
|
})
|
|
2591
3260
|
: null;
|
|
2592
3261
|
|
|
2593
|
-
teardownFixedEditorCompositor();
|
|
2594
3262
|
ctx.ui.setWidget("powerline-top", undefined);
|
|
2595
3263
|
ctx.ui.setWidget("powerline-secondary", undefined);
|
|
2596
3264
|
ctx.ui.setWidget("powerline-bash-transcript", undefined);
|
|
2597
3265
|
ctx.ui.setWidget("powerline-status", undefined);
|
|
3266
|
+
ctx.ui.setWidget("powerline-queue-preview", undefined);
|
|
2598
3267
|
ctx.ui.setWidget("powerline-last-prompt", undefined);
|
|
2599
3268
|
|
|
2600
3269
|
let autocompleteFixed = false;
|
|
3270
|
+
const previousEditorFactory = typeof ctx.ui.getEditorComponent === "function" ? ctx.ui.getEditorComponent() : undefined;
|
|
2601
3271
|
|
|
2602
3272
|
const editorFactory = (tui: any, editorTheme: any, keybindings: any) => {
|
|
3273
|
+
const previousEditor = previousEditorFactory?.(tui, editorTheme, keybindings);
|
|
2603
3274
|
const editor = new BashModeEditor(tui, editorTheme, keybindings, {
|
|
2604
3275
|
keybindings,
|
|
2605
3276
|
isBashModeActive: () => bashModeActive,
|
|
@@ -2608,7 +3279,6 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2608
3279
|
void setBashModeActive(false, ctx);
|
|
2609
3280
|
},
|
|
2610
3281
|
onSubmitCommand: (command) => void runShellCommand(command, ctx),
|
|
2611
|
-
onEditorSubmit: () => followSubmittedEditorToBottom(),
|
|
2612
3282
|
editorBoundaryShortcuts: {
|
|
2613
3283
|
start: resolvedShortcuts.editorStart,
|
|
2614
3284
|
end: resolvedShortcuts.editorEnd,
|
|
@@ -2635,18 +3305,20 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2635
3305
|
},
|
|
2636
3306
|
});
|
|
2637
3307
|
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
return undefined;
|
|
2645
|
-
}
|
|
2646
|
-
if (typeof Reflect.get(candidate, "applyCompletion") !== "function") {
|
|
2647
|
-
return undefined;
|
|
3308
|
+
let installingPowerlineAutocompleteProvider = false;
|
|
3309
|
+
const originalSetAutocompleteProvider = editor.setAutocompleteProvider.bind(editor);
|
|
3310
|
+
editor.setAutocompleteProvider = (provider: AutocompleteProvider) => {
|
|
3311
|
+
if (installingPowerlineAutocompleteProvider) {
|
|
3312
|
+
originalSetAutocompleteProvider(provider);
|
|
3313
|
+
return;
|
|
2648
3314
|
}
|
|
2649
|
-
|
|
3315
|
+
|
|
3316
|
+
originalSetAutocompleteProvider(passAutocompleteProviderThroughPreviousEditor(provider, previousEditor));
|
|
3317
|
+
attachAutocompleteProvider();
|
|
3318
|
+
};
|
|
3319
|
+
|
|
3320
|
+
const getInstalledAutocompleteProvider = (): AutocompleteProvider | undefined => {
|
|
3321
|
+
return getEditorAutocompleteProvider(editor) ?? getEditorAutocompleteProvider(previousEditor);
|
|
2650
3322
|
};
|
|
2651
3323
|
|
|
2652
3324
|
const attachAutocompleteProvider = (): boolean => {
|
|
@@ -2656,26 +3328,17 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2656
3328
|
|
|
2657
3329
|
const bashProvider = new BashAutocompleteProvider();
|
|
2658
3330
|
const oneOffBashProvider = new OneOffBashAutocompleteProvider();
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
3331
|
+
installingPowerlineAutocompleteProvider = true;
|
|
3332
|
+
try {
|
|
3333
|
+
editor.installAutocompleteProvider(
|
|
3334
|
+
new ModeAwareAutocompleteProvider(defaultProvider, bashProvider, oneOffBashProvider, () => bashModeActive),
|
|
3335
|
+
);
|
|
3336
|
+
} finally {
|
|
3337
|
+
installingPowerlineAutocompleteProvider = false;
|
|
3338
|
+
}
|
|
2662
3339
|
return true;
|
|
2663
3340
|
};
|
|
2664
3341
|
|
|
2665
|
-
let inheritedOnSubmit: unknown;
|
|
2666
|
-
Object.defineProperty(editor, "onSubmit", {
|
|
2667
|
-
configurable: true,
|
|
2668
|
-
get: () => inheritedOnSubmit,
|
|
2669
|
-
set(handler: unknown) {
|
|
2670
|
-
inheritedOnSubmit = typeof handler === "function"
|
|
2671
|
-
? (text: string) => {
|
|
2672
|
-
followSubmittedEditorToBottom();
|
|
2673
|
-
handler(text);
|
|
2674
|
-
}
|
|
2675
|
-
: handler;
|
|
2676
|
-
},
|
|
2677
|
-
});
|
|
2678
|
-
|
|
2679
3342
|
currentEditor = editor;
|
|
2680
3343
|
trackPromptHistory(editor);
|
|
2681
3344
|
restorePromptHistory(editor);
|
|
@@ -2685,6 +3348,62 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2685
3348
|
editor.handleInput = (data: string) => {
|
|
2686
3349
|
lastEditorInputAt = Date.now();
|
|
2687
3350
|
|
|
3351
|
+
const isSubmit = keybindings.matches(data, "tui.input.submit") && !keybindings.matches(data, "tui.input.newLine");
|
|
3352
|
+
const isFollowUpSubmit = keybindings.matches(data, "app.message.followUp");
|
|
3353
|
+
if (!bashModeActive && (isSubmit || isFollowUpSubmit)) {
|
|
3354
|
+
const sigilCapture = parseSigilIdeaCapture(editor.getExpandedText(), config.queue.captureSigil);
|
|
3355
|
+
if (sigilCapture) {
|
|
3356
|
+
try {
|
|
3357
|
+
const item = captureIdeaFromParsedInput(ctx, sigilCapture);
|
|
3358
|
+
if (item) {
|
|
3359
|
+
editor.addToHistory?.(editor.getExpandedText().trim());
|
|
3360
|
+
editor.setText("");
|
|
3361
|
+
}
|
|
3362
|
+
} catch (error) {
|
|
3363
|
+
ctx.ui.notify(error instanceof Error ? error.message : String(error), "error");
|
|
3364
|
+
}
|
|
3365
|
+
scheduleDismissWelcome(ctx);
|
|
3366
|
+
return;
|
|
3367
|
+
}
|
|
3368
|
+
}
|
|
3369
|
+
|
|
3370
|
+
if (!powerlineCompacting && !bashModeActive && isSubmit && typeof ctx.compact === "function") {
|
|
3371
|
+
const editorText = editor.getExpandedText().trim();
|
|
3372
|
+
const compactQueuedPrompt = parseCompactQueuedPrompt(editorText);
|
|
3373
|
+
if (editorText === "/compact" || compactQueuedPrompt) {
|
|
3374
|
+
editor.addToHistory?.(editorText);
|
|
3375
|
+
editor.setText("");
|
|
3376
|
+
if (compactQueuedPrompt) {
|
|
3377
|
+
capturePostCompactPrompt(ctx, compactQueuedPrompt);
|
|
3378
|
+
}
|
|
3379
|
+
powerlineCompacting = true;
|
|
3380
|
+
deliverAfterRetrySettles = false;
|
|
3381
|
+
requestQueueRender();
|
|
3382
|
+
ctx.compact({
|
|
3383
|
+
onError: (error: Error) => {
|
|
3384
|
+
finishFailedCompaction(ctx, error.message);
|
|
3385
|
+
ctx.ui.notify(error.message, "error");
|
|
3386
|
+
},
|
|
3387
|
+
});
|
|
3388
|
+
scheduleDismissWelcome(ctx);
|
|
3389
|
+
return;
|
|
3390
|
+
}
|
|
3391
|
+
}
|
|
3392
|
+
|
|
3393
|
+
if (powerlineCompacting && !bashModeActive && (isSubmit || isFollowUpSubmit)) {
|
|
3394
|
+
const text = editor.getExpandedText().trim();
|
|
3395
|
+
if (!text) return;
|
|
3396
|
+
if (text.startsWith("/")) {
|
|
3397
|
+
originalHandleInput(data);
|
|
3398
|
+
return;
|
|
3399
|
+
}
|
|
3400
|
+
editor.addToHistory?.(text);
|
|
3401
|
+
editor.setText("");
|
|
3402
|
+
capturePostCompactPrompt(ctx, text);
|
|
3403
|
+
scheduleDismissWelcome(ctx);
|
|
3404
|
+
return;
|
|
3405
|
+
}
|
|
3406
|
+
|
|
2688
3407
|
if (isStashShortcutInput(data)) {
|
|
2689
3408
|
stashOrRestoreEditorText(ctx);
|
|
2690
3409
|
return;
|
|
@@ -2700,15 +3419,13 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2700
3419
|
autocompleteFixed = true;
|
|
2701
3420
|
snapshotPromptHistory(editor);
|
|
2702
3421
|
ctx.ui.setEditorComponent(editorFactory);
|
|
2703
|
-
if (config.fixedEditor) {
|
|
2704
|
-
installFixedEditorCompositor(ctx, tui);
|
|
2705
|
-
}
|
|
2706
3422
|
currentEditor?.handleInput(data);
|
|
2707
3423
|
return;
|
|
2708
3424
|
}
|
|
2709
3425
|
|
|
2710
3426
|
attachAutocompleteProvider();
|
|
2711
3427
|
const followUpText = keybindings.matches(data, "app.message.followUp") ? getCurrentEditorText(ctx, editor) : "";
|
|
3428
|
+
scheduleDismissWelcome(ctx);
|
|
2712
3429
|
originalHandleInput(data);
|
|
2713
3430
|
if (hasNonWhitespaceText(followUpText) && !hasNonWhitespaceText(getCurrentEditorText(ctx, editor))) {
|
|
2714
3431
|
followSubmittedEditorToBottom();
|
|
@@ -2721,9 +3438,14 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2721
3438
|
return originalRender(width);
|
|
2722
3439
|
}
|
|
2723
3440
|
|
|
2724
|
-
const bc = (s: string) =>
|
|
2725
|
-
|
|
2726
|
-
|
|
3441
|
+
const bc = (s: string) =>
|
|
3442
|
+
typeof editor.borderColor === "function"
|
|
3443
|
+
? editor.borderColor(s)
|
|
3444
|
+
: `${getFgAnsiCode("sep")}${s}${ansi.reset}`;
|
|
3445
|
+
const captureDraft = !bashModeActive && isSigilIdeaDraft(editor.getExpandedText());
|
|
3446
|
+
const promptGlyph = bashModeActive ? "$" : captureDraft ? captureSigilGlyph() : config.fixedEditorPromptGlyph;
|
|
3447
|
+
const promptColor = captureDraft ? getFgAnsiCode("queue") : ansi.getFgAnsi(200, 200, 200);
|
|
3448
|
+
const prompt = promptGlyph ? `${promptColor}${promptGlyph}${ansi.reset}` : "";
|
|
2727
3449
|
const promptPrefix = prompt ? ` ${prompt} ` : " ";
|
|
2728
3450
|
const contPrefix = " ";
|
|
2729
3451
|
const contentWidth = Math.max(1, width - 1);
|
|
@@ -2771,10 +3493,12 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2771
3493
|
tuiRef = tui;
|
|
2772
3494
|
installFooterStatusRepaintHook(footerData);
|
|
2773
3495
|
const unsub = footerData.onBranchChange(() => requestStatusRender());
|
|
3496
|
+
const unsubGitUpdates = subscribeGitUpdates(() => requestStatusRender());
|
|
2774
3497
|
|
|
2775
3498
|
return {
|
|
2776
3499
|
dispose() {
|
|
2777
3500
|
unsub();
|
|
3501
|
+
unsubGitUpdates();
|
|
2778
3502
|
restoreFooterStatusRepaintHook?.();
|
|
2779
3503
|
restoreFooterStatusRepaintHook = null;
|
|
2780
3504
|
},
|
|
@@ -2782,18 +3506,12 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2782
3506
|
requestStatusRender();
|
|
2783
3507
|
},
|
|
2784
3508
|
render(): string[] {
|
|
2785
|
-
return [];
|
|
3509
|
+
return [""];
|
|
2786
3510
|
},
|
|
2787
3511
|
};
|
|
2788
3512
|
});
|
|
2789
3513
|
|
|
2790
|
-
|
|
2791
|
-
if (tuiRef) {
|
|
2792
|
-
installFixedEditorCompositor(ctx, tuiRef);
|
|
2793
|
-
}
|
|
2794
|
-
} else {
|
|
2795
|
-
installPowerlineWidgets(ctx);
|
|
2796
|
-
}
|
|
3514
|
+
installPowerlineWidgets(ctx);
|
|
2797
3515
|
}
|
|
2798
3516
|
|
|
2799
3517
|
function setupWelcomeHeader(ctx: any, newFeatures: GuideFeature[] = []) {
|
|
@@ -2801,8 +3519,9 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2801
3519
|
const providerName = ctx.model?.provider || "Unknown";
|
|
2802
3520
|
const loadedCounts = discoverLoadedCounts();
|
|
2803
3521
|
const recentSessions = getRecentSessions(3);
|
|
3522
|
+
const initialContextTokens = estimateInitialContextTokens(ctx);
|
|
2804
3523
|
|
|
2805
|
-
const header = new WelcomeHeader(modelName, providerName, recentSessions, loadedCounts, "compact", newFeatures);
|
|
3524
|
+
const header = new WelcomeHeader(modelName, providerName, recentSessions, loadedCounts, "compact", newFeatures, initialContextTokens);
|
|
2806
3525
|
welcomeHeaderActive = true;
|
|
2807
3526
|
markGuideVersionSeen(VERSION, getSettingsPath());
|
|
2808
3527
|
|
|
@@ -2833,6 +3552,18 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2833
3552
|
return;
|
|
2834
3553
|
}
|
|
2835
3554
|
|
|
3555
|
+
const sessionEvents = ctx.sessionManager?.getBranch?.() ?? [];
|
|
3556
|
+
const hasActivity = sessionEvents.some((entry: unknown) => {
|
|
3557
|
+
if (!isRecord(entry)) return false;
|
|
3558
|
+
if (entry.type === "tool_call" || entry.type === "tool_result") return true;
|
|
3559
|
+
return entry.type === "message" && isRecord(entry.message) && entry.message.role === "assistant";
|
|
3560
|
+
});
|
|
3561
|
+
if (hasActivity) {
|
|
3562
|
+
return;
|
|
3563
|
+
}
|
|
3564
|
+
|
|
3565
|
+
const initialContextTokens = estimateInitialContextTokens(ctx);
|
|
3566
|
+
|
|
2836
3567
|
ctx.ui.custom(
|
|
2837
3568
|
(_tui: any, _theme: any, _keybindings: any, done: (result: void) => void) => {
|
|
2838
3569
|
const welcome = new WelcomeComponent(
|
|
@@ -2842,6 +3573,7 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2842
3573
|
loadedCounts,
|
|
2843
3574
|
"full",
|
|
2844
3575
|
newFeatures,
|
|
3576
|
+
initialContextTokens,
|
|
2845
3577
|
);
|
|
2846
3578
|
markGuideVersionSeen(VERSION, getSettingsPath());
|
|
2847
3579
|
guideOverlayBlocking = true;
|
|
@@ -2880,7 +3612,7 @@ export default function powerlineFooter(pi: ExtensionAPI) {
|
|
|
2880
3612
|
horizontalAlign: "center",
|
|
2881
3613
|
}),
|
|
2882
3614
|
},
|
|
2883
|
-
).catch((error) => {
|
|
3615
|
+
).catch((error: unknown) => {
|
|
2884
3616
|
console.debug("[powerline-footer] Welcome overlay failed:", error);
|
|
2885
3617
|
});
|
|
2886
3618
|
}, 100);
|