pi-ui-extend 1.0.42 → 1.0.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -12
- package/dist/app/app.d.ts +10 -0
- package/dist/app/app.js +132 -8
- package/dist/app/cli/install.js +2 -2
- package/dist/app/commands/command-controller.d.ts +4 -0
- package/dist/app/commands/command-controller.js +11 -0
- package/dist/app/commands/command-git-actions.d.ts +25 -0
- package/dist/app/commands/command-git-actions.js +381 -0
- package/dist/app/commands/command-host.d.ts +3 -0
- package/dist/app/commands/command-host.js +5 -2
- package/dist/app/commands/command-model-actions.d.ts +1 -0
- package/dist/app/commands/command-model-actions.js +51 -34
- package/dist/app/commands/command-navigation-actions.d.ts +1 -0
- package/dist/app/commands/command-navigation-actions.js +16 -3
- package/dist/app/commands/command-registry.d.ts +2 -0
- package/dist/app/commands/command-registry.js +14 -0
- package/dist/app/commands/reload-context-inventory.js +12 -1
- package/dist/app/input/autocomplete-controller.js +61 -34
- package/dist/app/input/input-action-controller.d.ts +2 -0
- package/dist/app/input/input-action-controller.js +8 -1
- package/dist/app/input/input-controller.d.ts +2 -1
- package/dist/app/input/input-controller.js +7 -2
- package/dist/app/input/prompt-enhancer-controller.js +53 -35
- package/dist/app/input/voice-controller.d.ts +41 -45
- package/dist/app/input/voice-controller.js +351 -419
- package/dist/app/model/model-usage-controller.js +17 -7
- package/dist/app/model/model-usage-status.d.ts +4 -1
- package/dist/app/model/model-usage-status.js +270 -46
- package/dist/app/popup/menu-items-controller.d.ts +13 -3
- package/dist/app/popup/menu-items-controller.js +37 -21
- package/dist/app/popup/popup-action-controller.d.ts +12 -2
- package/dist/app/popup/popup-action-controller.js +77 -24
- package/dist/app/popup/popup-menu-controller.d.ts +36 -14
- package/dist/app/popup/popup-menu-controller.js +239 -69
- package/dist/app/rendering/dcp-stats.d.ts +9 -4
- package/dist/app/rendering/dcp-stats.js +40 -425
- package/dist/app/rendering/popup-menu-renderer.d.ts +3 -5
- package/dist/app/rendering/popup-menu-renderer.js +42 -37
- package/dist/app/rendering/render-controller.js +23 -2
- package/dist/app/rendering/status-line-renderer.d.ts +5 -0
- package/dist/app/rendering/status-line-renderer.js +41 -5
- package/dist/app/rendering/tab-line-renderer.js +26 -20
- package/dist/app/runtime.d.ts +12 -1
- package/dist/app/runtime.js +120 -12
- package/dist/app/screen/mouse-controller.d.ts +2 -0
- package/dist/app/screen/mouse-controller.js +17 -7
- package/dist/app/screen/status-controller.d.ts +4 -0
- package/dist/app/screen/status-controller.js +5 -0
- package/dist/app/session/lazy-session-manager.js +34 -0
- package/dist/app/session/session-event-controller.d.ts +1 -0
- package/dist/app/session/session-event-controller.js +10 -1
- package/dist/app/session/session-history.d.ts +1 -0
- package/dist/app/session/session-history.js +12 -1
- package/dist/app/session/session-lifecycle-controller.d.ts +6 -1
- package/dist/app/session/session-lifecycle-controller.js +10 -1
- package/dist/app/session/tabs-controller.d.ts +25 -1
- package/dist/app/session/tabs-controller.js +442 -153
- package/dist/app/subagents/subagents-widget-controller.d.ts +1 -0
- package/dist/app/subagents/subagents-widget-controller.js +6 -0
- package/dist/app/types.d.ts +11 -1
- package/dist/app/workspace/workspace-actions-controller.js +10 -2
- package/dist/app/workspace/workspace-undo.d.ts +1 -0
- package/dist/app/workspace/workspace-undo.js +1 -0
- package/dist/bundled-extensions/question/index.js +9 -1
- package/dist/bundled-extensions/question/remote.d.ts +4 -0
- package/dist/bundled-extensions/question/remote.js +33 -0
- package/dist/bundled-extensions/telegram-connector/bot.d.ts +43 -0
- package/dist/bundled-extensions/telegram-connector/bot.js +166 -0
- package/dist/bundled-extensions/telegram-connector/config.d.ts +8 -0
- package/dist/bundled-extensions/telegram-connector/config.js +87 -0
- package/dist/bundled-extensions/telegram-connector/coordinator.d.ts +66 -0
- package/dist/bundled-extensions/telegram-connector/coordinator.js +413 -0
- package/dist/bundled-extensions/telegram-connector/index.d.ts +3 -0
- package/dist/bundled-extensions/telegram-connector/index.js +195 -0
- package/dist/bundled-extensions/terminal-bell/index.d.ts +0 -8
- package/dist/bundled-extensions/terminal-bell/index.js +0 -76
- package/dist/bundled-extensions/workspace-undo/index.d.ts +26 -0
- package/dist/bundled-extensions/workspace-undo/index.js +191 -0
- package/dist/config.d.ts +21 -2
- package/dist/config.js +159 -32
- package/dist/default-pix-config.js +20 -10
- package/dist/schemas/pi-tools-suite-schema.d.ts +8 -4
- package/dist/schemas/pi-tools-suite-schema.js +11 -5
- package/dist/schemas/pix-schema.d.ts +12 -2
- package/dist/schemas/pix-schema.js +37 -9
- package/dist/schemas/tasks-schema.js +1 -1
- package/docs/concurrency.md +3 -1
- package/docs/desktop-mvp.md +10 -5
- package/docs/desktop-task-manager.md +81 -28
- package/docs/release.md +30 -6
- package/external/pi-tools-suite/README.md +165 -39
- package/external/pi-tools-suite/docs/session-recovery.md +7 -0
- package/external/pi-tools-suite/docs/subagent-model-pools.md +12 -5
- package/external/pi-tools-suite/docs/ui-qa-subagent.md +440 -0
- package/external/pi-tools-suite/package.json +6 -1
- package/external/pi-tools-suite/src/antigravity-auth/auth-store.ts +2 -1
- package/external/pi-tools-suite/src/antigravity-auth/constants.ts +9 -3
- package/external/pi-tools-suite/src/antigravity-auth/headers.ts +41 -3
- package/external/pi-tools-suite/src/antigravity-auth/models.ts +94 -21
- package/external/pi-tools-suite/src/antigravity-auth/oauth.ts +5 -17
- package/external/pi-tools-suite/src/antigravity-auth/payload.ts +72 -7
- package/external/pi-tools-suite/src/antigravity-auth/stream.ts +13 -1
- package/external/pi-tools-suite/src/async-subagents/agents/implement.md +1 -1
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/backends/browser.mjs +346 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/backends/desktop.mjs +1038 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/backends/tui.mjs +759 -0
- package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/scripts/browser-qa-runner.mjs +32 -23
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/chrome-devtools/chrome-devtools-provider.mjs +895 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/linux/linux-atspi.py +494 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/macos/macos-accessibility.swift +1085 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/native-terminal/bridge-client.mjs +50 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/native-terminal/native-terminal-host.mjs +501 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/windows/windows-uia.ps1 +454 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser-auth.md +114 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser-chrome-devtools.md +91 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser-playwright.md +145 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser.md +82 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop-linux.md +26 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop-macos.md +29 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop-windows.md +23 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop.md +54 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/tui-native-terminal.md +59 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/tui-pty.md +37 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/tui.md +60 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/scripts/ui-qa-runner.mjs +535 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa.md +75 -0
- package/external/pi-tools-suite/src/async-subagents/commands.ts +1 -1
- package/external/pi-tools-suite/src/async-subagents/core/agent-strategy.ts +1 -1
- package/external/pi-tools-suite/src/async-subagents/core/agents-dir.ts +0 -2
- package/external/pi-tools-suite/src/async-subagents/core/browser-qa.ts +16 -2
- package/external/pi-tools-suite/src/async-subagents/core/config.ts +40 -17
- package/external/pi-tools-suite/src/async-subagents/core/model-selection.ts +2 -1
- package/external/pi-tools-suite/src/async-subagents/core/registry.ts +158 -33
- package/external/pi-tools-suite/src/async-subagents/core/routing.ts +7 -4
- package/external/pi-tools-suite/src/async-subagents/core/spawn.ts +34 -24
- package/external/pi-tools-suite/src/async-subagents/core/ultrawork-auto.ts +51 -45
- package/external/pi-tools-suite/src/async-subagents/lib.ts +9 -1
- package/external/pi-tools-suite/src/async-subagents/tools/spawn.ts +0 -1
- package/external/pi-tools-suite/src/async-subagents/tools/subagents.ts +2 -2
- package/external/pi-tools-suite/src/coding-discipline/index.ts +90 -59
- package/external/pi-tools-suite/src/config.ts +14 -0
- package/external/pi-tools-suite/src/context-gateway/accounting-log.ts +282 -0
- package/external/pi-tools-suite/src/context-gateway/config.ts +66 -1
- package/external/pi-tools-suite/src/context-gateway/efficiency.ts +414 -0
- package/external/pi-tools-suite/src/context-gateway/enforcement.ts +123 -3
- package/external/pi-tools-suite/src/context-gateway/index.ts +137 -4
- package/external/pi-tools-suite/src/context-gateway/storeless-capabilities.ts +5 -5
- package/external/pi-tools-suite/src/context-gateway/telemetry.ts +2 -2
- package/external/pi-tools-suite/src/context-gateway/types.ts +8 -1
- package/external/pi-tools-suite/src/dcp/auto-compress-budget.ts +39 -4
- package/external/pi-tools-suite/src/dcp/auto-compress.ts +41 -14
- package/external/pi-tools-suite/src/dcp/commands.ts +14 -156
- package/external/pi-tools-suite/src/dcp/compress-tool.ts +8 -2
- package/external/pi-tools-suite/src/dcp/compression-progress.ts +22 -0
- package/external/pi-tools-suite/src/dcp/config.ts +58 -4
- package/external/pi-tools-suite/src/dcp/conversation-index.ts +36 -9
- package/external/pi-tools-suite/src/dcp/diagnostics.ts +41 -0
- package/external/pi-tools-suite/src/dcp/fresh-tool-results.ts +38 -0
- package/external/pi-tools-suite/src/dcp/index.ts +338 -66
- package/external/pi-tools-suite/src/dcp/journal.ts +126 -4
- package/external/pi-tools-suite/src/dcp/progress-controller.ts +2 -1
- package/external/pi-tools-suite/src/dcp/pruner-candidates.ts +92 -2
- package/external/pi-tools-suite/src/dcp/pruner-nudge.ts +36 -33
- package/external/pi-tools-suite/src/dcp/pruner.ts +1 -0
- package/external/pi-tools-suite/src/dcp/routine-pressure.ts +86 -0
- package/external/pi-tools-suite/src/dcp/state.ts +9 -0
- package/external/pi-tools-suite/src/dcp/statistics.d.ts +8 -0
- package/external/pi-tools-suite/src/dcp/statistics.js +156 -0
- package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +68 -16
- package/external/pi-tools-suite/src/lib/project.ts +36 -1
- package/external/pi-tools-suite/src/model-tools/index.ts +10 -7
- package/external/pi-tools-suite/src/repo-discovery/index.ts +304 -4
- package/external/pi-tools-suite/src/resource-registry/index.ts +282 -21
- package/external/pi-tools-suite/src/session-recovery/index.ts +17 -0
- package/external/pi-tools-suite/src/todo/index.ts +21 -0
- package/external/pi-tools-suite/src/todo/todo.ts +19 -1
- package/external/pi-tools-suite/src/tool-descriptions.ts +44 -15
- package/package.json +9 -10
- package/schemas/pi-tools-suite.json +44 -12
- package/schemas/pix.json +109 -15
- package/schemas/tasks.json +1 -2
- package/skills/simplify/SKILL.md +33 -5
- package/external/pi-tools-suite/docs/browser-qa-subagent.md +0 -196
- package/external/pi-tools-suite/src/async-subagents/agents/browser-qa.md +0 -598
- package/skills/playwright-cli/SKILL.md +0 -420
- package/skills/playwright-cli/references/element-attributes.md +0 -23
- package/skills/playwright-cli/references/playwright-tests.md +0 -50
- package/skills/playwright-cli/references/request-mocking.md +0 -87
- package/skills/playwright-cli/references/running-code.md +0 -241
- package/skills/playwright-cli/references/session-management.md +0 -273
- package/skills/playwright-cli/references/spec-driven-testing.md +0 -311
- package/skills/playwright-cli/references/storage-state.md +0 -290
- package/skills/playwright-cli/references/test-generation.md +0 -142
- package/skills/playwright-cli/references/tracing.md +0 -154
- package/skills/playwright-cli/references/video-recording.md +0 -147
- package/skills/spec-wiki/SKILL.md +0 -55
- package/skills/spec-wiki/evals/evals.json +0 -132
- package/skills/spec-wiki/evals/files/bootstrap/architecture/rfc-007.md +0 -14
- package/skills/spec-wiki/evals/files/bootstrap/docs/how-to-pay.md +0 -4
- package/skills/spec-wiki/evals/files/bootstrap/docs/overview.md +0 -9
- package/skills/spec-wiki/evals/files/bootstrap/requirements/payment-behavior.md +0 -17
- package/skills/spec-wiki/evals/files/bootstrap/src/payments.ts +0 -12
- package/skills/spec-wiki/evals/files/bootstrap/tests/payments.test.ts +0 -11
- package/skills/spec-wiki/evals/files/focused/src/session.ts +0 -5
- package/skills/spec-wiki/evals/files/focused/tests/session.test.ts +0 -17
- package/skills/spec-wiki/evals/files/maintenance/low-signal/incoming/capture.txt +0 -2
- package/skills/spec-wiki/evals/files/maintenance/low-signal/src/capture.ts +0 -3
- package/skills/spec-wiki/evals/files/maintenance/move/docs/old-job-contract.md +0 -18
- package/skills/spec-wiki/evals/files/maintenance/move/src/job.ts +0 -5
- package/skills/spec-wiki/evals/files/maintenance/new-relation/docs/session-refresh.md +0 -24
- package/skills/spec-wiki/evals/files/maintenance/new-relation/incoming/refresh-worker.ts +0 -7
- package/skills/spec-wiki/evals/files/maintenance/new-relation/src/session.ts +0 -7
- package/skills/spec-wiki/evals/files/maintenance/no-impact/docs/auth-contract.md +0 -17
- package/skills/spec-wiki/evals/files/maintenance/no-impact/incoming/telemetry-format.ts +0 -3
- package/skills/spec-wiki/evals/files/maintenance/no-impact/src/auth.ts +0 -3
- package/skills/spec-wiki/evals/files/query/docs/how-to-run-jobs.md +0 -4
- package/skills/spec-wiki/evals/files/query/docs/spec-overview.md +0 -9
- package/skills/spec-wiki/evals/files/query/features/jobs/cancellation-contract.md +0 -15
- package/skills/spec-wiki/evals/files/query/features/jobs/retry-spec.md +0 -6
- package/skills/spec-wiki/evals/maintenance_regression.py +0 -311
- package/skills/spec-wiki/evals/retrieval-eval.md +0 -37
- package/skills/spec-wiki/evals/retrieval-evals.json +0 -37
- package/skills/spec-wiki/evals/trigger-evals.json +0 -94
- package/skills/spec-wiki/references/bootstrap.md +0 -100
- package/skills/spec-wiki/references/focused-spec.md +0 -117
- package/skills/spec-wiki/references/index-schema.md +0 -330
- package/skills/spec-wiki/references/maintenance.md +0 -134
- package/skills/spec-wiki/references/query.md +0 -74
- package/skills/spec-wiki/scripts/spec_wiki.py +0 -2076
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/examples/qa-auth.example.jsonc +0 -0
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/examples/qa-flow.example.jsonc +0 -0
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/vendor/fflate.LICENSE +0 -0
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/vendor/fflate.mjs +0 -0
package/README.md
CHANGED
|
@@ -34,7 +34,7 @@ Pi provides the agent runtime, models, tools, skills, extensions, and persistent
|
|
|
34
34
|
- **Keep projects organized.** Tabs are scoped to the working directory and survive restarts. Search, resume, fork, clone, jump through, import, export, share, or delete sessions without leaving the terminal.
|
|
35
35
|
- **Stay in flow.** Run quick commands with `!`, open a raw interactive terminal with `!!`, paste images, follow file links, dictate in English or Russian, and improve a prompt before sending it.
|
|
36
36
|
- **Know what the agent is doing.** The status area exposes model, thinking level, context, usage, workspace, todos, sub-agents, voice state, and prompt actions — with mouse targets where useful.
|
|
37
|
-
- **Bring a serious toolkit.** Pix ships with `pi-tools-suite`:
|
|
37
|
+
- **Bring a serious toolkit.** Pix ships with `pi-tools-suite`: 21 integrated modules for indexed repository discovery, AST edits, LSP diagnostics, parallel agents, durable todos, context compression, web access, provider accounts, and more.
|
|
38
38
|
- **Use the models you want.** Pix runs on Pi's provider ecosystem and supports model switching, scoped model lists, per-model thinking levels, usage views, autocomplete, and fallback-aware helper workflows.
|
|
39
39
|
|
|
40
40
|
Pix is not a separate agent protocol or an RPC wrapper around Pi. It runs on the Pi SDK, so the runtime, session format, extensions, skills, prompts, and tools remain part of the same ecosystem.
|
|
@@ -97,6 +97,8 @@ On startup, Pix tries to link the bundled suite into the active Pi agent directo
|
|
|
97
97
|
| Providers and quotas | `antigravity-auth`, `opencode-import`, `usage` | Antigravity OAuth/account failover, OpenCode credential import, and multi-provider usage views. |
|
|
98
98
|
| Reusable workflows | `prompt-commands`, `resource-registry`, `session-name` | Prompt-command CRUD, private Git-backed skill/agent install/update/push/remote-remove/local-uninstall with reload-on-change, project-scoped `.pi/tasks.jsonc` + `.pi/plans/` + `.pi/TODO.md` sync, a Desktop Registry sidebar for status/actions/configuration, and session naming. |
|
|
99
99
|
| Model compatibility | `coding-discipline`, `model-tools`, `codex-reasoning-fix` | Model-specific discipline and vision lookup, compatibility aliases, and a Codex reasoning payload workaround. |
|
|
100
|
+
| Agent session context | `session-recovery` | Bounded session overview/search/section tools so agents can recover prior context. |
|
|
101
|
+
| Payload hygiene | `context-gateway`, `truncation-metadata-normalizer`, `credential-firewall` | Observe-only result-chain gateway, opt-in truncation-metadata cleanup, and an opt-in secret firewall. |
|
|
100
102
|
|
|
101
103
|
Every module can be disabled. Optional integrations only activate when their requirements are available — for example, repository tools require an index, web tools require local Ollama web search, and LSP servers must be configured and trusted.
|
|
102
104
|
|
|
@@ -136,8 +138,8 @@ Recommended:
|
|
|
136
138
|
|
|
137
139
|
Optional:
|
|
138
140
|
|
|
139
|
-
-
|
|
140
|
-
- an audio recorder for dictation: SoX (`rec`/`sox`), `ffmpeg`, or `arecord` on Linux
|
|
141
|
+
- a Deepgram API key in `dictation.apiKey` inside `~/.config/pi/pix.jsonc` for voice input; `DEEPGRAM_API_KEY` remains supported as a fallback
|
|
142
|
+
- an audio recorder for terminal dictation: SoX (`rec`/`sox`), `ffmpeg`, or `arecord` on Linux
|
|
141
143
|
- `tmux` and `rsvg-convert` only if you want to regenerate README screenshots
|
|
142
144
|
- Ollama with web search enabled for the bundled `web_search` and `web_fetch` tools
|
|
143
145
|
- language servers for the LSP module (see [LSP setup](external/pi-tools-suite/README.md#lsp-setup) for install commands and ready-to-paste configs for popular servers, including Svelte, Vue, Go, clangd, Lua, and bash)
|
|
@@ -210,7 +212,7 @@ Pix uses Pi's model and authentication stores. Environment-based API keys and cr
|
|
|
210
212
|
| Model-backed helpers | No | Review `promptEnhancer`, `autocomplete`, and `sessionTitle` in `pix.jsonc` | Each configured helper model needs credentials for its own provider; it need not use the main session provider. |
|
|
211
213
|
| Ollama/Tavily web access | No | Use local Ollama without a cloud key, set `OLLAMA_API_KEY`/`TAVILY_API_KEY`, or run `/web-credentials` | Stored keys live in `~/.config/pi/pi-tools-suite-credentials.json` with mode `0600`. |
|
|
212
214
|
| Context7 documentation skill | No | Export `CONTEXT7_API_KEY` | The skill fails before making a network request when the variable is absent. |
|
|
213
|
-
| Telegram
|
|
215
|
+
| Telegram task connector | No | Configure `telegramConnector.botToken` + `telegramConnector.chatId`, or `PIX_TELEGRAM_BOT_TOKEN` + `PIX_TELEGRAM_CHAT_ID` | Completion/question notifications; reply to continue the exact live session, or use `/new <task>` for a fresh session. |
|
|
214
216
|
|
|
215
217
|
`pix install` reports whether these sources appear configured, but never displays, copies, or overwrites token values.
|
|
216
218
|
|
|
@@ -267,6 +269,12 @@ Pix can provide inline, model-backed autocomplete with configurable debounce, ti
|
|
|
267
269
|
- While it runs, submit editor text to its stdin; use `Ctrl-C` to interrupt.
|
|
268
270
|
- `!!command` opens a raw interactive terminal for REPLs, TUIs, debuggers, and development servers. Exit it to return to Pix.
|
|
269
271
|
|
|
272
|
+
### Git helpers
|
|
273
|
+
|
|
274
|
+
- `/code-review` reviews staged, unstaged, and untracked Git changes with the configured review model and prints the findings locally in the TUI.
|
|
275
|
+
- `/commit-message` generates a message from staged changes, shows the full message, and asks for confirmation before running `git commit`. If the staged diff changes before confirmation completes, Pix refuses the commit and asks you to regenerate the message.
|
|
276
|
+
- These helpers use the existing `desktop.git.reviewModelRef` / `reviewFallbackModels` and `desktop.git.commitMessageModelRef` / `commitMessageFallbackModels` settings for compatibility. `/commit-message` never stages changes or bypasses Git hooks.
|
|
277
|
+
|
|
270
278
|
### Images, clipboard, and files
|
|
271
279
|
|
|
272
280
|
- Paste an image from the clipboard with `Ctrl+V`/`Cmd+V` in supported terminals.
|
|
@@ -274,14 +282,25 @@ Pix can provide inline, model-backed autocomplete with configurable debounce, ti
|
|
|
274
282
|
- `/copy` copies the last assistant message.
|
|
275
283
|
- Pix integrates with the native clipboard on macOS and Windows and common Wayland/X11 helpers on Linux.
|
|
276
284
|
|
|
277
|
-
###
|
|
285
|
+
### Voice input
|
|
286
|
+
|
|
287
|
+
Put the Deepgram key in the user Pix config:
|
|
288
|
+
|
|
289
|
+
```jsonc
|
|
290
|
+
{
|
|
291
|
+
"dictation": {
|
|
292
|
+
"apiKey": "your-deepgram-api-key"
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
The file is `~/.config/pi/pix.jsonc`. Keep the key in this user config rather than a project `.pi/pix.jsonc`; project config is intentionally not allowed to override the secret. `DEEPGRAM_API_KEY` remains supported as a compatibility fallback when `dictation.apiKey` is not set.
|
|
278
298
|
|
|
279
|
-
|
|
299
|
+
Then press `Ctrl+G` or click the microphone in the terminal status area to start/stop dictation. Pix streams microphone audio to Deepgram Nova-3 and inserts finalized text into the editor so you can review it before sending. The default dictation languages are English and Russian and can be changed with the existing language control.
|
|
280
300
|
|
|
281
|
-
-
|
|
282
|
-
- Russian: `vosk-model-small-ru-0.22`
|
|
301
|
+
Pix Desktop exposes the same voice-input action directly in the message composer. The desktop client uses Nova-3 and respects `dictation.language` plus the selected language's `deepgramLanguage` value from the user Pix config. It requests a short-lived Deepgram token from the local Tauri backend; the permanent API key is read from the user Pix config (or the environment fallback) by Rust and is never exposed to the WebView. The Settings UI also exposes `Dictation · Api Key` as a sensitive field because it is generated from the Pix schema.
|
|
283
302
|
|
|
284
|
-
|
|
303
|
+
Voice audio is sent to Deepgram while recording. Pix no longer downloads or installs local speech-recognition models.
|
|
285
304
|
|
|
286
305
|
### Workspace undo
|
|
287
306
|
|
|
@@ -312,6 +331,7 @@ Type `/` for the live, searchable list. Extensions can add more commands than th
|
|
|
312
331
|
| Models | `/model`, `/default-model`, `/scoped-models`, `/thinking`, `/default-thinking`, `/autocomplete` |
|
|
313
332
|
| Project context | `/no-context-files`, `/compact` |
|
|
314
333
|
| Prompt workflow | `/enhance`, `/queue`, `/copy` |
|
|
334
|
+
| Git | `/code-review`, `/commit-message` |
|
|
315
335
|
| Sessions | `/new`, `/new_tab`, `/resume`, `/name`, `/session`, `/search`, `/history`, `/jump`, `/tree` |
|
|
316
336
|
| Branching and files | `/fork`, `/clone`, `/delete`, `/export`, `/import`, `/share` |
|
|
317
337
|
| Status | `/usage` |
|
|
@@ -361,6 +381,7 @@ Both support the published schema:
|
|
|
361
381
|
"$schema": "https://unpkg.com/pi-ui-extend/schemas/pix.json",
|
|
362
382
|
"defaultModel": {
|
|
363
383
|
"modelRef": "openai-codex/gpt-5.6-sol",
|
|
384
|
+
"fallbackModels": [],
|
|
364
385
|
"thinking": "medium"
|
|
365
386
|
},
|
|
366
387
|
"toolRenderer": {
|
|
@@ -371,9 +392,10 @@ Both support the published schema:
|
|
|
371
392
|
"apply_patch": { "defaultExpanded": true }
|
|
372
393
|
}
|
|
373
394
|
},
|
|
374
|
-
"promptEnhancer": { "modelRef": "openai-codex/gpt-5.6-luna" },
|
|
395
|
+
"promptEnhancer": { "modelRef": "openai-codex/gpt-5.6-luna", "fallbackModels": [] },
|
|
375
396
|
"autocomplete": {
|
|
376
397
|
"modelRef": "zai/glm-5-turbo",
|
|
398
|
+
"fallbackModels": [],
|
|
377
399
|
"debounceMs": 350,
|
|
378
400
|
"timeoutMs": 3000
|
|
379
401
|
},
|
|
@@ -387,6 +409,12 @@ Both support the published schema:
|
|
|
387
409
|
}
|
|
388
410
|
```
|
|
389
411
|
|
|
412
|
+
Singular model selectors resolve with an explicit ordered fallback array, even
|
|
413
|
+
when it is empty. Existing configs that omit the array remain compatible and
|
|
414
|
+
normalize to `[]`. Pix uses `fallbackModels` for object selectors; Desktop Git
|
|
415
|
+
uses `reviewFallbackModels` and `commitMessageFallbackModels` beside the
|
|
416
|
+
corresponding primary model refs.
|
|
417
|
+
|
|
390
418
|
Configurable areas include:
|
|
391
419
|
|
|
392
420
|
- default model and thinking level;
|
|
@@ -449,7 +477,7 @@ Install `wl-clipboard` on Wayland or `xclip`/`xsel` on X11, then run `pix instal
|
|
|
449
477
|
|
|
450
478
|
### Voice input is unavailable
|
|
451
479
|
|
|
452
|
-
Ensure the
|
|
480
|
+
Ensure `dictation.apiKey` is set in `~/.config/pi/pix.jsonc`, or set the compatibility fallback `DEEPGRAM_API_KEY` in the environment that launches Pix. Terminal voice input also needs an audio recorder: SoX (`rec`/`sox`), `ffmpeg`, or `arecord` on Linux. Pix Desktop additionally needs microphone permission from the operating system. Voice support can be omitted without affecting the rest of Pix.
|
|
453
481
|
|
|
454
482
|
### A provider login dialog is missing
|
|
455
483
|
|
|
@@ -508,7 +536,8 @@ npm run watch:all
|
|
|
508
536
|
`watch:all` rebuilds only the affected project parts. It keeps the last working
|
|
509
537
|
Desktop process alive while changes compile, then replaces it only after the
|
|
510
538
|
entire queued build succeeds. A failed build is reported without replacing the
|
|
511
|
-
running Desktop.
|
|
539
|
+
running Desktop. Desktop web changes rebuild the Vite bundle first and then
|
|
540
|
+
invalidate the native Tauri asset embedding before the replacement app starts.
|
|
512
541
|
|
|
513
542
|
Regenerate the README screenshots without accounts or live model traffic:
|
|
514
543
|
|
package/dist/app/app.d.ts
CHANGED
|
@@ -68,9 +68,18 @@ export declare class PiUiExtendApp {
|
|
|
68
68
|
private voicePartialText;
|
|
69
69
|
private resumeSessions;
|
|
70
70
|
private resumeLoading;
|
|
71
|
+
private draftModels;
|
|
72
|
+
private draftModelRef;
|
|
73
|
+
private draftThinkingLevel;
|
|
74
|
+
private draftModelOverrideRef;
|
|
71
75
|
constructor(options: AppOptions);
|
|
72
76
|
private createRuntime;
|
|
73
77
|
private loadStartupConfig;
|
|
78
|
+
private refreshDraftModelCatalog;
|
|
79
|
+
private resetDraftModelSelection;
|
|
80
|
+
private selectDraftModel;
|
|
81
|
+
private draftModelState;
|
|
82
|
+
private draftModelStatus;
|
|
74
83
|
private applyPixConfig;
|
|
75
84
|
private updateOutputFilters;
|
|
76
85
|
start(): Promise<void>;
|
|
@@ -78,6 +87,7 @@ export declare class PiUiExtendApp {
|
|
|
78
87
|
private bindCurrentSession;
|
|
79
88
|
private awaitCurrentSessionExtensions;
|
|
80
89
|
private activateRuntime;
|
|
90
|
+
private deactivateRuntimeForDraft;
|
|
81
91
|
private createExtensionEventBus;
|
|
82
92
|
private subagentTypesForRuntime;
|
|
83
93
|
private contextInventoryText;
|
package/dist/app/app.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { THEMES } from "../theme.js";
|
|
2
2
|
import { InputEditor } from "../input-editor.js";
|
|
3
|
-
import { compileOutputFilterPatterns, defaultPixConfig, loadPixConfig, resolveToolRule, } from "../config.js";
|
|
3
|
+
import { compileOutputFilterPatterns, defaultPixConfig, loadPixConfig, resolveDefaultModelRef, resolveToolRule, savePixThinkingLevelForModel, savePixVisibleModels, } from "../config.js";
|
|
4
4
|
import { AppCommandController } from "./commands/command-controller.js";
|
|
5
5
|
import { ConversationViewport } from "./rendering/conversation-viewport.js";
|
|
6
6
|
import { renderRegisteredExtensionEntry } from "./rendering/extension-entry-renderer.js";
|
|
@@ -23,7 +23,8 @@ import { AppAutocompleteController } from "./input/autocomplete-controller.js";
|
|
|
23
23
|
import { AppQueuedMessageController } from "./session/queued-message-controller.js";
|
|
24
24
|
import { AppRequestHistory } from "./session/request-history.js";
|
|
25
25
|
import { AppRenderController } from "./rendering/render-controller.js";
|
|
26
|
-
import { createPixRuntime } from "./runtime.js";
|
|
26
|
+
import { createPixDraftModelCatalog, createPixRuntime } from "./runtime.js";
|
|
27
|
+
import { parseModelRef } from "./model/model-ref.js";
|
|
27
28
|
import { ScreenStyler } from "./screen/screen-styler.js";
|
|
28
29
|
import { AppScrollController } from "./screen/scroll-controller.js";
|
|
29
30
|
import { searchResultScrollNeedles, searchResultTargetEntry } from "./session/session-search.js";
|
|
@@ -142,6 +143,10 @@ export class PiUiExtendApp {
|
|
|
142
143
|
voicePartialText;
|
|
143
144
|
resumeSessions = [];
|
|
144
145
|
resumeLoading = false;
|
|
146
|
+
draftModels = [];
|
|
147
|
+
draftModelRef;
|
|
148
|
+
draftThinkingLevel = "off";
|
|
149
|
+
draftModelOverrideRef;
|
|
145
150
|
constructor(options) {
|
|
146
151
|
this.options = options;
|
|
147
152
|
this.theme = THEMES[options.themeName];
|
|
@@ -170,6 +175,7 @@ export class PiUiExtendApp {
|
|
|
170
175
|
theme: this.theme,
|
|
171
176
|
blinkController: this.blinkController,
|
|
172
177
|
runtimeSession: () => this.runtime?.session,
|
|
178
|
+
draftModelStatus: () => this.draftModelStatus(),
|
|
173
179
|
render: () => this.scheduleRender(),
|
|
174
180
|
});
|
|
175
181
|
this.agentPauseController = new AgentPauseController({
|
|
@@ -186,7 +192,7 @@ export class PiUiExtendApp {
|
|
|
186
192
|
maxProjectSessions: () => this.pixConfig.maxProjectSessions,
|
|
187
193
|
blinkController: this.blinkController,
|
|
188
194
|
runtime: () => this.runtime,
|
|
189
|
-
createRuntimeForNewSession: () => this.createRuntime(
|
|
195
|
+
createRuntimeForNewSession: (modelRef) => this.createRuntime(
|
|
190
196
|
// Never reuse services across tabs. The SDK ties the extension
|
|
191
197
|
// runtime (resourceLoader.getExtensions().runtime) to the
|
|
192
198
|
// resourceLoader, and that runtime is shared by every session
|
|
@@ -197,12 +203,18 @@ export class PiUiExtendApp {
|
|
|
197
203
|
// then throw "ctx is stale after session replacement or reload".
|
|
198
204
|
// Fresh services per session = fresh extension runtime = no
|
|
199
205
|
// cross-session invalidation.
|
|
200
|
-
|
|
206
|
+
{
|
|
207
|
+
...newTabRuntimeOptions(this.options),
|
|
208
|
+
...(modelRef ? { modelRef } : {}),
|
|
209
|
+
}),
|
|
201
210
|
createRuntimeForSession: (sessionPath) => this.createRuntime({
|
|
202
211
|
...this.options,
|
|
203
212
|
noSession: false,
|
|
204
213
|
sessionPath,
|
|
205
214
|
}),
|
|
215
|
+
draftModelOverrideRef: () => this.draftModelOverrideRef,
|
|
216
|
+
resetDraftModelSelection: () => this.resetDraftModelSelection(),
|
|
217
|
+
deactivateRuntimeForDraft: () => this.deactivateRuntimeForDraft(),
|
|
206
218
|
awaitCurrentSessionExtensions: (runtime) => this.awaitCurrentSessionExtensions(runtime),
|
|
207
219
|
activateRuntime: (runtime, options) => this.activateRuntime(runtime, options),
|
|
208
220
|
disposeRuntime: (runtime) => this.terminalController.disposeRuntime(runtime),
|
|
@@ -224,6 +236,12 @@ export class PiUiExtendApp {
|
|
|
224
236
|
restoreAutoUserMessages: (messages) => this.queuedMessages.restoreAutoUserMessages(messages),
|
|
225
237
|
captureDeferredUserMessages: () => this.queuedMessages.captureDeferredUserMessages(),
|
|
226
238
|
restoreDeferredUserMessages: (messages) => this.queuedMessages.restoreDeferredUserMessages(messages),
|
|
239
|
+
openDraftSessionSelector: () => {
|
|
240
|
+
void this.commandController.runDraftSessionSelector();
|
|
241
|
+
},
|
|
242
|
+
closeDraftSessionSelector: () => {
|
|
243
|
+
this.popupMenus.closeDraftSessionSelectorForTabLifecycle();
|
|
244
|
+
},
|
|
227
245
|
contextInventoryText: (runtime, heading) => this.contextInventoryText(runtime, heading),
|
|
228
246
|
addEntry: (entry) => this.addEntry(entry),
|
|
229
247
|
showToast: (message, kind) => this.showToast(message, kind),
|
|
@@ -262,9 +280,12 @@ export class PiUiExtendApp {
|
|
|
262
280
|
}, this.pixConfig.dictation);
|
|
263
281
|
this.menuItems = new AppMenuItemsController({
|
|
264
282
|
runtime: () => this.runtime,
|
|
283
|
+
draftModelState: () => this.draftModelState(),
|
|
284
|
+
visibleModels: () => this.pixConfig.visibleModels,
|
|
265
285
|
getBuiltinSlashCommands: () => this.slashCommands,
|
|
266
286
|
getEntries: () => this.entries,
|
|
267
287
|
getResumeSessions: () => this.resumeSessions,
|
|
288
|
+
getOpenSessionPaths: () => this.tabsController.openSessionPaths(),
|
|
268
289
|
});
|
|
269
290
|
const popupMenuRenderer = new PopupMenuRenderer({
|
|
270
291
|
theme: this.theme,
|
|
@@ -279,6 +300,8 @@ export class PiUiExtendApp {
|
|
|
279
300
|
this.popupMenus = new AppPopupMenuController({
|
|
280
301
|
get entries() { return app.entries; },
|
|
281
302
|
get session() { return app.runtime?.session; },
|
|
303
|
+
currentThinkingLevel: () => this.runtime?.session.thinkingLevel ?? this.draftModelState()?.thinkingLevel,
|
|
304
|
+
rememberedThinkingLevel: (modelRef) => this.pixConfig.thinkingByModel?.[modelRef],
|
|
282
305
|
get resumeLoading() { return app.resumeLoading; },
|
|
283
306
|
get resumeSessionCount() { return app.resumeSessions.length; },
|
|
284
307
|
isRunning: () => this.running,
|
|
@@ -286,9 +309,9 @@ export class PiUiExtendApp {
|
|
|
286
309
|
setInput: (value) => this.setInput(value),
|
|
287
310
|
parseSlashInput: (text) => this.menuItems.parseSlashInput(text),
|
|
288
311
|
getSlashCommandMenuItems: (query) => this.menuItems.getSlashCommandMenuItems(query),
|
|
289
|
-
getModelMenuItems: (query) => this.menuItems.getModelMenuItems(query),
|
|
312
|
+
getModelMenuItems: (query, includeHidden) => this.menuItems.getModelMenuItems(query, includeHidden),
|
|
290
313
|
getThinkingMenuItems: (query) => this.menuItems.getThinkingMenuItems(query),
|
|
291
|
-
getResumeMenuItems: (query, limit) => this.menuItems.getResumeMenuItems(query, limit),
|
|
314
|
+
getResumeMenuItems: (query, limit, options) => this.menuItems.getResumeMenuItems(query, limit, options),
|
|
292
315
|
getUserMessageMenuItems: () => this.menuItems.getUserMessageMenuItems(),
|
|
293
316
|
getUserMessageJumpMenuItems: (query) => this.menuItems.getUserMessageJumpMenuItems(query),
|
|
294
317
|
getQueueMessageMenuItems: () => this.menuItems.getQueueMessageMenuItems(),
|
|
@@ -302,6 +325,7 @@ export class PiUiExtendApp {
|
|
|
302
325
|
theme: this.theme,
|
|
303
326
|
screenStyler: this.screenStyler,
|
|
304
327
|
get session() { return app.runtime?.session; },
|
|
328
|
+
draftModelStatus: () => this.draftModelStatus(),
|
|
305
329
|
modelColors: this.pixConfig.modelColors,
|
|
306
330
|
get sessionActivity() { return app.statusController.sessionActivity; },
|
|
307
331
|
get statusDotBright() { return app.statusController.statusDotBright; },
|
|
@@ -377,6 +401,7 @@ export class PiUiExtendApp {
|
|
|
377
401
|
});
|
|
378
402
|
this.subagentsWidgetController = new AppSubagentsWidgetController({
|
|
379
403
|
cwd: this.options.cwd,
|
|
404
|
+
hasActiveRuntime: () => this.runtime !== undefined,
|
|
380
405
|
sessionFile: () => this.runtime?.session.sessionFile,
|
|
381
406
|
isRunning: () => this.running,
|
|
382
407
|
render: () => this.scheduleRender(),
|
|
@@ -513,6 +538,7 @@ export class PiUiExtendApp {
|
|
|
513
538
|
this.commandController = new AppCommandController({
|
|
514
539
|
options: this.options,
|
|
515
540
|
runtime: () => this.runtime,
|
|
541
|
+
inputScopeKey: () => this.tabsController.activeInputTabId(),
|
|
516
542
|
subagentTypes: (runtime) => this.subagentTypesForRuntime(runtime),
|
|
517
543
|
requestHistory: () => this.requestHistory,
|
|
518
544
|
getInput: () => this.input,
|
|
@@ -558,6 +584,7 @@ export class PiUiExtendApp {
|
|
|
558
584
|
setDirectPopupMenuQuery: (query) => {
|
|
559
585
|
this.popupMenus.setDirectQuery(query);
|
|
560
586
|
},
|
|
587
|
+
setResumeMenuMode: (mode) => this.popupMenus.setResumeMenuMode(mode),
|
|
561
588
|
refreshUserMessageJumpMenuItems: () => this.menuItems.refreshUserMessageJumpMenuItems(),
|
|
562
589
|
getResumeLoading: () => this.resumeLoading,
|
|
563
590
|
getResumeSessions: () => this.resumeSessions,
|
|
@@ -576,6 +603,10 @@ export class PiUiExtendApp {
|
|
|
576
603
|
});
|
|
577
604
|
this.popupActions = new AppPopupActionController({
|
|
578
605
|
runtime: () => this.runtime,
|
|
606
|
+
inputScopeKey: () => this.tabsController.activeInputTabId(),
|
|
607
|
+
isDraftTabActive: () => this.tabsController.isDraftTabActive(),
|
|
608
|
+
materializeDraftSession: () => this.tabsController.materializeActiveDraftTab(),
|
|
609
|
+
selectDraftModel: (model, thinkingLevel) => this.selectDraftModel(model, thinkingLevel),
|
|
579
610
|
getBuiltinSlashCommands: () => this.slashCommands,
|
|
580
611
|
isRunning: () => this.running,
|
|
581
612
|
setInput: (value) => this.setInput(value),
|
|
@@ -583,9 +614,20 @@ export class PiUiExtendApp {
|
|
|
583
614
|
setStatus: (status) => this.setStatus(status),
|
|
584
615
|
setSessionStatus: (session) => this.setSessionStatus(session),
|
|
585
616
|
showToast: (message, kind) => this.showToast(message, kind),
|
|
617
|
+
visibleModels: () => this.pixConfig.visibleModels,
|
|
618
|
+
saveVisibleModels: (modelRefs) => {
|
|
619
|
+
const saved = savePixVisibleModels(modelRefs);
|
|
620
|
+
this.pixConfig.visibleModels = [...saved];
|
|
621
|
+
return saved;
|
|
622
|
+
},
|
|
623
|
+
saveThinkingLevelForModel: (modelRef, thinkingLevel) => {
|
|
624
|
+
const saved = savePixThinkingLevelForModel(modelRef, thinkingLevel);
|
|
625
|
+
this.pixConfig.thinkingByModel = { ...saved };
|
|
626
|
+
},
|
|
586
627
|
render: () => this.render(),
|
|
587
628
|
awaitCurrentSessionExtensions: (runtime) => this.awaitCurrentSessionExtensions(runtime),
|
|
588
629
|
afterSessionReplacement: (message) => this.afterSessionReplacement(message),
|
|
630
|
+
openSessionInActiveDraftTab: (sessionPath) => this.tabsController.openSessionInActiveDraftTab(sessionPath),
|
|
589
631
|
scrollToConversationEntry: (entryId) => this.scrollController.scrollToConversationEntry(entryId),
|
|
590
632
|
scrollToUserMessageJumpTarget: (target) => this.scrollToUserMessageJumpTarget(target),
|
|
591
633
|
}, this.popupMenus, this.commandController, this.menuItems, this.queuedMessages, this.workspaceActions);
|
|
@@ -697,6 +739,8 @@ export class PiUiExtendApp {
|
|
|
697
739
|
this.inputActions = new AppInputActionController({
|
|
698
740
|
runtime: () => this.runtime,
|
|
699
741
|
inputScopeKey: () => this.tabsController.activeInputTabId(),
|
|
742
|
+
isDraftTabActive: () => this.tabsController.isDraftTabActive(),
|
|
743
|
+
materializeDraftSession: () => this.tabsController.materializeActiveDraftTab(),
|
|
700
744
|
isRunning: () => this.running,
|
|
701
745
|
isSessionSwitching: () => this.tabsController.isSwitching(),
|
|
702
746
|
inputEditor: () => this.inputEditor,
|
|
@@ -736,6 +780,7 @@ export class PiUiExtendApp {
|
|
|
736
780
|
resetInputMenuDismissals: () => this.popupMenus.resetInputMenuDismissals(),
|
|
737
781
|
render: () => this.render(),
|
|
738
782
|
moveActivePopupMenuSelection: (delta) => this.popupMenus.moveActivePopupMenuSelection(delta),
|
|
783
|
+
moveActiveModelThinkingLevel: (delta) => this.popupMenus.moveActiveModelThinkingLevel(delta),
|
|
739
784
|
navigateRequestHistory: (delta) => this.requestHistory.navigate(delta),
|
|
740
785
|
scrollByLines: (delta) => this.scrollController.scrollByLines(delta),
|
|
741
786
|
scrollByPage: (delta) => this.scrollController.scrollByPage(delta),
|
|
@@ -744,8 +789,8 @@ export class PiUiExtendApp {
|
|
|
744
789
|
handleInterrupt: () => this.inputActions.handleInterrupt(),
|
|
745
790
|
handleEscape: () => this.inputActions.handleEscape(),
|
|
746
791
|
handleDirectPopupInput: (char) => this.popupMenus.handleDirectPopupInput(char),
|
|
792
|
+
toggleModelVisibilityMode: () => this.popupMenus.toggleModelVisibilityMode(),
|
|
747
793
|
autocompleteModel: () => this.popupMenus.autocompleteModel(),
|
|
748
|
-
autocompleteThinking: () => this.popupMenus.autocompleteThinking(),
|
|
749
794
|
acceptAutocompleteSuggestion: () => this.autocompleteController.acceptSuggestion(),
|
|
750
795
|
autocompleteSlashCommand: () => this.popupMenus.autocompleteSlashCommand(),
|
|
751
796
|
toggleVoiceRecording: () => {
|
|
@@ -780,7 +825,10 @@ export class PiUiExtendApp {
|
|
|
780
825
|
});
|
|
781
826
|
this.sessionLifecycle = new AppSessionLifecycleController({
|
|
782
827
|
options: this.options,
|
|
783
|
-
|
|
828
|
+
prepareStartupRuntime: () => this.tabsController.prepareStartupRuntime(),
|
|
829
|
+
createRuntime: (startup) => this.createRuntime(startup?.sessionPath
|
|
830
|
+
? { ...this.options, noSession: false, sessionPath: startup.sessionPath }
|
|
831
|
+
: this.options),
|
|
784
832
|
entries: this.entries,
|
|
785
833
|
runtime: () => this.runtime,
|
|
786
834
|
setRuntime: (runtime) => {
|
|
@@ -863,6 +911,59 @@ export class PiUiExtendApp {
|
|
|
863
911
|
async loadStartupConfig() {
|
|
864
912
|
await yieldToEventLoop();
|
|
865
913
|
this.applyPixConfig(loadPixConfig(this.options.cwd));
|
|
914
|
+
await this.refreshDraftModelCatalog();
|
|
915
|
+
}
|
|
916
|
+
async refreshDraftModelCatalog() {
|
|
917
|
+
try {
|
|
918
|
+
this.draftModels = await createPixDraftModelCatalog({ cwd: this.options.cwd });
|
|
919
|
+
}
|
|
920
|
+
catch {
|
|
921
|
+
this.draftModels = [];
|
|
922
|
+
}
|
|
923
|
+
this.resetDraftModelSelection();
|
|
924
|
+
}
|
|
925
|
+
resetDraftModelSelection() {
|
|
926
|
+
this.draftModelOverrideRef = undefined;
|
|
927
|
+
const configuredRef = this.options.modelRef ?? resolveDefaultModelRef(this.pixConfig);
|
|
928
|
+
if (configuredRef) {
|
|
929
|
+
try {
|
|
930
|
+
const parsed = parseModelRef(configuredRef);
|
|
931
|
+
this.draftModelRef = `${parsed.provider}/${parsed.modelId}`;
|
|
932
|
+
this.draftThinkingLevel = parsed.thinkingLevel ?? "off";
|
|
933
|
+
return;
|
|
934
|
+
}
|
|
935
|
+
catch {
|
|
936
|
+
// Runtime creation will surface an invalid configured model. Keep the
|
|
937
|
+
// draft picker usable so the user can select a valid model first.
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
const first = this.draftModels[0];
|
|
941
|
+
this.draftModelRef = first ? `${first.provider}/${first.id}` : undefined;
|
|
942
|
+
this.draftThinkingLevel = "off";
|
|
943
|
+
}
|
|
944
|
+
selectDraftModel(model, thinkingLevel) {
|
|
945
|
+
if (!this.tabsController.isDraftTabActive())
|
|
946
|
+
return;
|
|
947
|
+
const ref = `${model.provider}/${model.id}`;
|
|
948
|
+
this.draftModelRef = ref;
|
|
949
|
+
this.draftThinkingLevel = thinkingLevel;
|
|
950
|
+
this.draftModelOverrideRef = `${ref}:${thinkingLevel}`;
|
|
951
|
+
this.setStatus("new conversation");
|
|
952
|
+
}
|
|
953
|
+
draftModelState() {
|
|
954
|
+
if (!this.tabsController.isDraftTabActive())
|
|
955
|
+
return undefined;
|
|
956
|
+
return {
|
|
957
|
+
models: this.draftModels,
|
|
958
|
+
...(this.draftModelRef ? { modelRef: this.draftModelRef } : {}),
|
|
959
|
+
thinkingLevel: this.draftThinkingLevel,
|
|
960
|
+
};
|
|
961
|
+
}
|
|
962
|
+
draftModelStatus() {
|
|
963
|
+
const state = this.draftModelState();
|
|
964
|
+
if (!state?.modelRef)
|
|
965
|
+
return undefined;
|
|
966
|
+
return { modelLabel: state.modelRef, thinkingLabel: state.thinkingLevel };
|
|
866
967
|
}
|
|
867
968
|
applyPixConfig(config) {
|
|
868
969
|
replaceRecord(this.pixConfig.toolRenderer, config.toolRenderer);
|
|
@@ -876,6 +977,14 @@ export class PiUiExtendApp {
|
|
|
876
977
|
delete this.pixConfig.defaultModel;
|
|
877
978
|
else
|
|
878
979
|
this.pixConfig.defaultModel = { ...config.defaultModel };
|
|
980
|
+
if (config.visibleModels === undefined)
|
|
981
|
+
delete this.pixConfig.visibleModels;
|
|
982
|
+
else
|
|
983
|
+
this.pixConfig.visibleModels = [...config.visibleModels];
|
|
984
|
+
if (config.thinkingByModel === undefined)
|
|
985
|
+
delete this.pixConfig.thinkingByModel;
|
|
986
|
+
else
|
|
987
|
+
this.pixConfig.thinkingByModel = { ...config.thinkingByModel };
|
|
879
988
|
this.pixConfig.ignoreContextFiles = config.ignoreContextFiles;
|
|
880
989
|
this.pixConfig.maxProjectSessions = config.maxProjectSessions;
|
|
881
990
|
this.updateOutputFilters();
|
|
@@ -946,6 +1055,20 @@ export class PiUiExtendApp {
|
|
|
946
1055
|
});
|
|
947
1056
|
await this.bindCurrentSession(options);
|
|
948
1057
|
}
|
|
1058
|
+
deactivateRuntimeForDraft() {
|
|
1059
|
+
const runtime = this.runtime;
|
|
1060
|
+
if (!runtime)
|
|
1061
|
+
return;
|
|
1062
|
+
const scopeKey = this.activeExtensionUiScope();
|
|
1063
|
+
// Clear the visible runtime before any UI cleanup. cancelCustomUi() can
|
|
1064
|
+
// synchronously render; leaving the old runtime attached during that render
|
|
1065
|
+
// lets tab synchronization incorrectly reactivate the previous real tab.
|
|
1066
|
+
this.runtime = undefined;
|
|
1067
|
+
this.extensionUiController.cancelCustomUi(scopeKey);
|
|
1068
|
+
this.extensionUiController.clearWidgets(scopeKey, { cancelCustomUi: false });
|
|
1069
|
+
void this.voiceController.stopRecording();
|
|
1070
|
+
this.sessionLifecycle.unsubscribeSession();
|
|
1071
|
+
}
|
|
949
1072
|
createExtensionEventBus() {
|
|
950
1073
|
return createIsolatedExtensionEventBus((channel, data) => {
|
|
951
1074
|
if (channel === TERMINAL_BELL_ATTENTION_EVENT)
|
|
@@ -1276,6 +1399,7 @@ export class PiUiExtendApp {
|
|
|
1276
1399
|
if (contentVersion === this.lastInputEditorContentVersion)
|
|
1277
1400
|
return;
|
|
1278
1401
|
this.lastInputEditorContentVersion = contentVersion;
|
|
1402
|
+
this.tabsController.noteActiveDraftInputChanged();
|
|
1279
1403
|
this.scrollController.scrollToBottom();
|
|
1280
1404
|
}
|
|
1281
1405
|
conversationQuickScrollDirections() {
|
package/dist/app/cli/install.js
CHANGED
|
@@ -59,7 +59,7 @@ export function inspectPixOnboarding(homeDir = homedir(), env = process.env) {
|
|
|
59
59
|
opencodeAntigravityExists: pixInstallDeps.existsSync(join(opencodeConfigDir, "antigravity-accounts.json")),
|
|
60
60
|
webCredentialsConfigured: Boolean(env.OLLAMA_API_KEY?.trim() || env.TAVILY_API_KEY?.trim()) || jsonObjectHasEntries(webCredentialPath),
|
|
61
61
|
context7Configured: Boolean(env.CONTEXT7_API_KEY?.trim()),
|
|
62
|
-
telegramConfigured: Boolean(env.
|
|
62
|
+
telegramConfigured: Boolean(env.PIX_TELEGRAM_BOT_TOKEN?.trim() && env.PIX_TELEGRAM_CHAT_ID?.trim()),
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
65
|
export function ensurePixSetupFiles(homeDir = homedir()) {
|
|
@@ -106,7 +106,7 @@ export function formatPixInstallNextSteps(homeDir = homedir(), state = inspectPi
|
|
|
106
106
|
"Optional integrations:",
|
|
107
107
|
` ${state.webCredentialsConfigured ? "✓ Web credentials detected." : "○ Web search: use local Ollama without a key, or run /web-credentials for Ollama Cloud/Tavily."}`,
|
|
108
108
|
` ${state.context7Configured ? "✓ Context7 API key detected." : "○ Context7 docs skill: export CONTEXT7_API_KEY."}`,
|
|
109
|
-
` ${state.telegramConfigured ? "✓ Telegram
|
|
109
|
+
` ${state.telegramConfigured ? "✓ Telegram connector credentials detected in the environment." : "○ Telegram connector: set telegramConnector in tools config or PIX_TELEGRAM_BOT_TOKEN plus PIX_TELEGRAM_CHAT_ID."}`,
|
|
110
110
|
" ○ Model-backed helpers: review promptEnhancer, autocomplete, and sessionTitle model refs; each provider needs its own credentials.",
|
|
111
111
|
" ○ Voice: set dictation.language in Pix config. LSP: configure and trust servers under lsp.servers in tools config.",
|
|
112
112
|
"",
|
|
@@ -4,14 +4,18 @@ export declare class AppCommandController {
|
|
|
4
4
|
private readonly host;
|
|
5
5
|
readonly slashCommands: readonly SlashCommand[];
|
|
6
6
|
private readonly modelActions;
|
|
7
|
+
private readonly gitActions;
|
|
7
8
|
private readonly sessionActions;
|
|
8
9
|
private readonly navigationActions;
|
|
9
10
|
constructor(host: CommandControllerHost);
|
|
10
11
|
runResumeCommand(queryOrOptions?: string | {
|
|
11
12
|
preserveStatus?: boolean;
|
|
12
13
|
placement?: PopupMenuPlacement;
|
|
14
|
+
draft?: boolean;
|
|
13
15
|
}): Promise<void>;
|
|
16
|
+
runDraftSessionSelector(): Promise<void>;
|
|
14
17
|
runModelCommand(model: SessionModel): Promise<void>;
|
|
18
|
+
runModelThinkingCommand(model: SessionModel, level: ThinkingLevel): Promise<void>;
|
|
15
19
|
runThinkingCommand(level: ThinkingLevel): Promise<void>;
|
|
16
20
|
private registryActions;
|
|
17
21
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { GitCommandActions } from "./command-git-actions.js";
|
|
1
2
|
import { ModelCommandActions } from "./command-model-actions.js";
|
|
2
3
|
import { NavigationCommandActions } from "./command-navigation-actions.js";
|
|
3
4
|
import { createSlashCommands } from "./command-registry.js";
|
|
@@ -6,11 +7,13 @@ export class AppCommandController {
|
|
|
6
7
|
host;
|
|
7
8
|
slashCommands;
|
|
8
9
|
modelActions;
|
|
10
|
+
gitActions;
|
|
9
11
|
sessionActions;
|
|
10
12
|
navigationActions;
|
|
11
13
|
constructor(host) {
|
|
12
14
|
this.host = host;
|
|
13
15
|
this.modelActions = new ModelCommandActions(host);
|
|
16
|
+
this.gitActions = new GitCommandActions(host);
|
|
14
17
|
this.sessionActions = new SessionCommandActions(host);
|
|
15
18
|
this.navigationActions = new NavigationCommandActions(host);
|
|
16
19
|
this.slashCommands = createSlashCommands(this.registryActions(), host);
|
|
@@ -18,9 +21,15 @@ export class AppCommandController {
|
|
|
18
21
|
async runResumeCommand(queryOrOptions = "") {
|
|
19
22
|
await this.navigationActions.runResumeCommand(queryOrOptions);
|
|
20
23
|
}
|
|
24
|
+
async runDraftSessionSelector() {
|
|
25
|
+
await this.navigationActions.runResumeCommand({ preserveStatus: true, placement: "draft-surface", draft: true });
|
|
26
|
+
}
|
|
21
27
|
async runModelCommand(model) {
|
|
22
28
|
await this.modelActions.runModelCommand(model);
|
|
23
29
|
}
|
|
30
|
+
async runModelThinkingCommand(model, level) {
|
|
31
|
+
await this.modelActions.runModelThinkingCommand(model, level);
|
|
32
|
+
}
|
|
24
33
|
async runThinkingCommand(level) {
|
|
25
34
|
await this.modelActions.runThinkingCommand(level);
|
|
26
35
|
}
|
|
@@ -35,6 +44,8 @@ export class AppCommandController {
|
|
|
35
44
|
runThinkingSlashCommand: (argumentsText) => this.modelActions.runThinkingSlashCommand(argumentsText),
|
|
36
45
|
runDefaultThinkingSlashCommand: (argumentsText) => this.modelActions.runDefaultThinkingSlashCommand(argumentsText),
|
|
37
46
|
runEnhanceCommand: () => this.host.enhancePrompt(),
|
|
47
|
+
runCodeReviewCommand: () => this.gitActions.runCodeReviewCommand(),
|
|
48
|
+
runCommitMessageCommand: () => this.gitActions.runCommitMessageCommand(),
|
|
38
49
|
runExportCommand: (argumentsText) => this.sessionActions.runExportCommand(argumentsText),
|
|
39
50
|
runImportCommand: (argumentsText) => this.sessionActions.runImportCommand(argumentsText),
|
|
40
51
|
runShareCommand: () => this.sessionActions.runShareCommand(),
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { AgentSessionRuntime } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { type AsyncProcessResult, type RunProcessOptions } from "../process.js";
|
|
3
|
+
import { type CommandControllerHost } from "./command-host.js";
|
|
4
|
+
export type GitAssistantKind = "review" | "commit-message";
|
|
5
|
+
type GitProcessRunner = (command: string, args?: readonly string[], options?: RunProcessOptions) => Promise<AsyncProcessResult>;
|
|
6
|
+
type GitAssistantRunner = (runtime: AgentSessionRuntime, kind: GitAssistantKind, diff: string) => Promise<string>;
|
|
7
|
+
export type GitCommandActionsDeps = {
|
|
8
|
+
runProcess?: GitProcessRunner;
|
|
9
|
+
generateGitAssistantText?: GitAssistantRunner;
|
|
10
|
+
};
|
|
11
|
+
export declare class GitCommandActions {
|
|
12
|
+
private readonly host;
|
|
13
|
+
private readonly runProcess;
|
|
14
|
+
private readonly generateGitAssistantText;
|
|
15
|
+
constructor(host: CommandControllerHost, deps?: GitCommandActionsDeps);
|
|
16
|
+
runCodeReviewCommand(): Promise<void>;
|
|
17
|
+
runCommitMessageCommand(): Promise<void>;
|
|
18
|
+
private gitRoot;
|
|
19
|
+
private trackedDiff;
|
|
20
|
+
private reviewInput;
|
|
21
|
+
private untrackedFiles;
|
|
22
|
+
}
|
|
23
|
+
export declare function generateGitAssistantText(runtime: AgentSessionRuntime, kind: GitAssistantKind, diff: string): Promise<string>;
|
|
24
|
+
export declare function loadGitAssistantModelRefs(cwd: string, kind: GitAssistantKind, homeDir?: string): string[];
|
|
25
|
+
export {};
|