pi-ui-extend 0.1.1
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 +307 -0
- package/bin/pix.mjs +219 -0
- package/dist/app/app.d.ts +96 -0
- package/dist/app/app.js +871 -0
- package/dist/app/blink-controller.d.ts +23 -0
- package/dist/app/blink-controller.js +82 -0
- package/dist/app/cli.d.ts +8 -0
- package/dist/app/cli.js +83 -0
- package/dist/app/clipboard.d.ts +1 -0
- package/dist/app/clipboard.js +24 -0
- package/dist/app/command-controller.d.ts +18 -0
- package/dist/app/command-controller.js +58 -0
- package/dist/app/command-host.d.ts +44 -0
- package/dist/app/command-host.js +1 -0
- package/dist/app/command-model-actions.d.ts +12 -0
- package/dist/app/command-model-actions.js +176 -0
- package/dist/app/command-navigation-actions.d.ts +19 -0
- package/dist/app/command-navigation-actions.js +267 -0
- package/dist/app/command-registry.d.ts +32 -0
- package/dist/app/command-registry.js +225 -0
- package/dist/app/command-runtime.d.ts +5 -0
- package/dist/app/command-runtime.js +32 -0
- package/dist/app/command-session-actions.d.ts +20 -0
- package/dist/app/command-session-actions.js +295 -0
- package/dist/app/constants.d.ts +52 -0
- package/dist/app/constants.js +103 -0
- package/dist/app/conversation-entry-renderer.d.ts +21 -0
- package/dist/app/conversation-entry-renderer.js +81 -0
- package/dist/app/conversation-shell-renderer.d.ts +5 -0
- package/dist/app/conversation-shell-renderer.js +43 -0
- package/dist/app/conversation-tool-renderer.d.ts +16 -0
- package/dist/app/conversation-tool-renderer.js +216 -0
- package/dist/app/conversation-viewport.d.ts +55 -0
- package/dist/app/conversation-viewport.js +252 -0
- package/dist/app/dcp-stats.d.ts +2 -0
- package/dist/app/dcp-stats.js +116 -0
- package/dist/app/editor-layout-renderer.d.ts +31 -0
- package/dist/app/editor-layout-renderer.js +211 -0
- package/dist/app/editor-panels.d.ts +4 -0
- package/dist/app/editor-panels.js +130 -0
- package/dist/app/extension-actions-controller.d.ts +22 -0
- package/dist/app/extension-actions-controller.js +60 -0
- package/dist/app/extension-event-bus.d.ts +3 -0
- package/dist/app/extension-event-bus.js +23 -0
- package/dist/app/extension-ui-controller.d.ts +57 -0
- package/dist/app/extension-ui-controller.js +532 -0
- package/dist/app/file-link-opener.d.ts +2 -0
- package/dist/app/file-link-opener.js +66 -0
- package/dist/app/file-links.d.ts +10 -0
- package/dist/app/file-links.js +117 -0
- package/dist/app/guards.d.ts +3 -0
- package/dist/app/guards.js +9 -0
- package/dist/app/icons.d.ts +37 -0
- package/dist/app/icons.js +97 -0
- package/dist/app/id.d.ts +1 -0
- package/dist/app/id.js +4 -0
- package/dist/app/image-click-targets.d.ts +5 -0
- package/dist/app/image-click-targets.js +32 -0
- package/dist/app/image-opener.d.ts +2 -0
- package/dist/app/image-opener.js +64 -0
- package/dist/app/input-action-controller.d.ts +47 -0
- package/dist/app/input-action-controller.js +209 -0
- package/dist/app/input-controller.d.ts +60 -0
- package/dist/app/input-controller.js +425 -0
- package/dist/app/input-paste-handler.d.ts +27 -0
- package/dist/app/input-paste-handler.js +146 -0
- package/dist/app/menu-items-controller.d.ts +32 -0
- package/dist/app/menu-items-controller.js +182 -0
- package/dist/app/message-content.d.ts +8 -0
- package/dist/app/message-content.js +115 -0
- package/dist/app/model-ref.d.ts +13 -0
- package/dist/app/model-ref.js +50 -0
- package/dist/app/model-usage-controller.d.ts +35 -0
- package/dist/app/model-usage-controller.js +99 -0
- package/dist/app/model-usage-status.d.ts +125 -0
- package/dist/app/model-usage-status.js +749 -0
- package/dist/app/mouse-controller.d.ts +182 -0
- package/dist/app/mouse-controller.js +968 -0
- package/dist/app/native-modifiers.d.ts +3 -0
- package/dist/app/native-modifiers.js +60 -0
- package/dist/app/nerd-font-controller.d.ts +11 -0
- package/dist/app/nerd-font-controller.js +90 -0
- package/dist/app/popup-action-controller.d.ts +44 -0
- package/dist/app/popup-action-controller.js +278 -0
- package/dist/app/popup-menu-controller.d.ts +183 -0
- package/dist/app/popup-menu-controller.js +1070 -0
- package/dist/app/prompt-enhancer-controller.d.ts +40 -0
- package/dist/app/prompt-enhancer-controller.js +215 -0
- package/dist/app/queued-message-controller.d.ts +62 -0
- package/dist/app/queued-message-controller.js +377 -0
- package/dist/app/render-controller.d.ts +41 -0
- package/dist/app/render-controller.js +378 -0
- package/dist/app/render-text.d.ts +19 -0
- package/dist/app/render-text.js +67 -0
- package/dist/app/request-history.d.ts +23 -0
- package/dist/app/request-history.js +131 -0
- package/dist/app/runtime.d.ts +39 -0
- package/dist/app/runtime.js +195 -0
- package/dist/app/screen-selection.d.ts +6 -0
- package/dist/app/screen-selection.js +9 -0
- package/dist/app/screen-styler.d.ts +34 -0
- package/dist/app/screen-styler.js +168 -0
- package/dist/app/scroll-controller.d.ts +51 -0
- package/dist/app/scroll-controller.js +207 -0
- package/dist/app/session-event-controller.d.ts +69 -0
- package/dist/app/session-event-controller.js +338 -0
- package/dist/app/session-history.d.ts +23 -0
- package/dist/app/session-history.js +164 -0
- package/dist/app/session-lifecycle-controller.d.ts +55 -0
- package/dist/app/session-lifecycle-controller.js +116 -0
- package/dist/app/session-search.d.ts +24 -0
- package/dist/app/session-search.js +215 -0
- package/dist/app/shell-command.d.ts +27 -0
- package/dist/app/shell-command.js +176 -0
- package/dist/app/shell-controller.d.ts +28 -0
- package/dist/app/shell-controller.js +124 -0
- package/dist/app/slash-commands.d.ts +6 -0
- package/dist/app/slash-commands.js +75 -0
- package/dist/app/startup-checks.d.ts +8 -0
- package/dist/app/startup-checks.js +59 -0
- package/dist/app/startup-info.d.ts +3 -0
- package/dist/app/startup-info.js +176 -0
- package/dist/app/status-controller.d.ts +35 -0
- package/dist/app/status-controller.js +105 -0
- package/dist/app/status-line-renderer.d.ts +68 -0
- package/dist/app/status-line-renderer.js +453 -0
- package/dist/app/subagents-files.d.ts +10 -0
- package/dist/app/subagents-files.js +193 -0
- package/dist/app/subagents-model.d.ts +23 -0
- package/dist/app/subagents-model.js +224 -0
- package/dist/app/subagents-widget-controller.d.ts +43 -0
- package/dist/app/subagents-widget-controller.js +311 -0
- package/dist/app/tab-line-renderer.d.ts +26 -0
- package/dist/app/tab-line-renderer.js +222 -0
- package/dist/app/tabs-controller.d.ts +100 -0
- package/dist/app/tabs-controller.js +885 -0
- package/dist/app/terminal-controller.d.ts +40 -0
- package/dist/app/terminal-controller.js +135 -0
- package/dist/app/terminal-edit-shortcuts.d.ts +23 -0
- package/dist/app/terminal-edit-shortcuts.js +138 -0
- package/dist/app/terminal-output-buffer.d.ts +20 -0
- package/dist/app/terminal-output-buffer.js +52 -0
- package/dist/app/toast-controller.d.ts +13 -0
- package/dist/app/toast-controller.js +40 -0
- package/dist/app/toast-renderer.d.ts +9 -0
- package/dist/app/toast-renderer.js +79 -0
- package/dist/app/todo-model.d.ts +22 -0
- package/dist/app/todo-model.js +179 -0
- package/dist/app/todo-widget-controller.d.ts +21 -0
- package/dist/app/todo-widget-controller.js +59 -0
- package/dist/app/tool-block-renderer.d.ts +26 -0
- package/dist/app/tool-block-renderer.js +439 -0
- package/dist/app/types.d.ts +550 -0
- package/dist/app/types.js +1 -0
- package/dist/app/update.d.ts +36 -0
- package/dist/app/update.js +315 -0
- package/dist/app/voice-controller.d.ts +52 -0
- package/dist/app/voice-controller.js +600 -0
- package/dist/app/workspace-actions-controller.d.ts +40 -0
- package/dist/app/workspace-actions-controller.js +215 -0
- package/dist/app/workspace-undo.d.ts +44 -0
- package/dist/app/workspace-undo.js +215 -0
- package/dist/config.d.ts +62 -0
- package/dist/config.js +527 -0
- package/dist/context-progress-bar.d.ts +17 -0
- package/dist/context-progress-bar.js +48 -0
- package/dist/default-pix-config.d.ts +1 -0
- package/dist/default-pix-config.js +375 -0
- package/dist/fuzzy.d.ts +23 -0
- package/dist/fuzzy.js +165 -0
- package/dist/input-editor-files.d.ts +15 -0
- package/dist/input-editor-files.js +62 -0
- package/dist/input-editor.d.ts +186 -0
- package/dist/input-editor.js +835 -0
- package/dist/main.d.ts +1 -0
- package/dist/main.js +12 -0
- package/dist/markdown-format.d.ts +22 -0
- package/dist/markdown-format.js +542 -0
- package/dist/sdk.d.ts +3 -0
- package/dist/sdk.js +1 -0
- package/dist/syntax-highlight.d.ts +22 -0
- package/dist/syntax-highlight.js +528 -0
- package/dist/terminal-width.d.ts +6 -0
- package/dist/terminal-width.js +245 -0
- package/dist/theme.d.ts +56 -0
- package/dist/theme.js +118 -0
- package/dist/tool-renderers/apply-patch.d.ts +2 -0
- package/dist/tool-renderers/apply-patch.js +36 -0
- package/dist/tool-renderers/ast.d.ts +2 -0
- package/dist/tool-renderers/ast.js +5 -0
- package/dist/tool-renderers/compress.d.ts +2 -0
- package/dist/tool-renderers/compress.js +126 -0
- package/dist/tool-renderers/index.d.ts +3 -0
- package/dist/tool-renderers/index.js +44 -0
- package/dist/tool-renderers/question.d.ts +2 -0
- package/dist/tool-renderers/question.js +88 -0
- package/dist/tool-renderers/read.d.ts +2 -0
- package/dist/tool-renderers/read.js +36 -0
- package/dist/tool-renderers/repo.d.ts +2 -0
- package/dist/tool-renderers/repo.js +13 -0
- package/dist/tool-renderers/shell.d.ts +3 -0
- package/dist/tool-renderers/shell.js +27 -0
- package/dist/tool-renderers/skill.d.ts +2 -0
- package/dist/tool-renderers/skill.js +132 -0
- package/dist/tool-renderers/subagents.d.ts +2 -0
- package/dist/tool-renderers/subagents.js +51 -0
- package/dist/tool-renderers/todo.d.ts +2 -0
- package/dist/tool-renderers/todo.js +9 -0
- package/dist/tool-renderers/types.d.ts +42 -0
- package/dist/tool-renderers/types.js +1 -0
- package/dist/tool-renderers/utils.d.ts +31 -0
- package/dist/tool-renderers/utils.js +230 -0
- package/dist/tool-renderers/web.d.ts +3 -0
- package/dist/tool-renderers/web.js +9 -0
- package/dist/tool-renderers/write.d.ts +2 -0
- package/dist/tool-renderers/write.js +42 -0
- package/dist/ui.d.ts +56 -0
- package/dist/ui.js +94 -0
- package/docs/release.md +81 -0
- package/extensions/question/contract.ts +100 -0
- package/extensions/question/index.ts +34 -0
- package/extensions/question/render.ts +28 -0
- package/extensions/question/result.ts +86 -0
- package/extensions/question/tool-description.ts +11 -0
- package/extensions/question/tui.ts +629 -0
- package/extensions/question/types.ts +123 -0
- package/extensions/session-title/config.ts +169 -0
- package/extensions/session-title/index.ts +459 -0
- package/extensions/terminal-bell/index.ts +315 -0
- package/external/pi-tools-suite/README.md +242 -0
- package/external/pi-tools-suite/index.ts +1 -0
- package/external/pi-tools-suite/licenses/ollama-pi-web-search.MIT +21 -0
- package/external/pi-tools-suite/licenses/opencode-mystatus-MIT.txt +21 -0
- package/external/pi-tools-suite/package.json +53 -0
- package/external/pi-tools-suite/src/antigravity-auth/auth-store.ts +194 -0
- package/external/pi-tools-suite/src/antigravity-auth/commands.ts +80 -0
- package/external/pi-tools-suite/src/antigravity-auth/constants.ts +26 -0
- package/external/pi-tools-suite/src/antigravity-auth/headers.ts +20 -0
- package/external/pi-tools-suite/src/antigravity-auth/index.ts +104 -0
- package/external/pi-tools-suite/src/antigravity-auth/models.ts +86 -0
- package/external/pi-tools-suite/src/antigravity-auth/oauth.ts +305 -0
- package/external/pi-tools-suite/src/antigravity-auth/payload.ts +423 -0
- package/external/pi-tools-suite/src/antigravity-auth/status.ts +78 -0
- package/external/pi-tools-suite/src/antigravity-auth/stream.ts +302 -0
- package/external/pi-tools-suite/src/antigravity-auth/types.ts +113 -0
- package/external/pi-tools-suite/src/ast-grep/index.ts +6 -0
- package/external/pi-tools-suite/src/ast-grep/render.ts +70 -0
- package/external/pi-tools-suite/src/ast-grep/schema.ts +109 -0
- package/external/pi-tools-suite/src/ast-grep/tool.ts +345 -0
- package/external/pi-tools-suite/src/ast-grep/types.ts +55 -0
- package/external/pi-tools-suite/src/ast-grep/utils.ts +65 -0
- package/external/pi-tools-suite/src/async-subagents/async-subagents.sample.jsonc +222 -0
- package/external/pi-tools-suite/src/async-subagents/commands.ts +518 -0
- package/external/pi-tools-suite/src/async-subagents/constants.ts +11 -0
- package/external/pi-tools-suite/src/async-subagents/core/agent-strategy.ts +74 -0
- package/external/pi-tools-suite/src/async-subagents/core/attachment-bridge.ts +133 -0
- package/external/pi-tools-suite/src/async-subagents/core/cleanup.ts +66 -0
- package/external/pi-tools-suite/src/async-subagents/core/concurrency.ts +90 -0
- package/external/pi-tools-suite/src/async-subagents/core/config.ts +819 -0
- package/external/pi-tools-suite/src/async-subagents/core/log-limits.ts +166 -0
- package/external/pi-tools-suite/src/async-subagents/core/model-fallback.ts +133 -0
- package/external/pi-tools-suite/src/async-subagents/core/paths.ts +47 -0
- package/external/pi-tools-suite/src/async-subagents/core/pi-invocation.ts +35 -0
- package/external/pi-tools-suite/src/async-subagents/core/presets.ts +67 -0
- package/external/pi-tools-suite/src/async-subagents/core/process.ts +15 -0
- package/external/pi-tools-suite/src/async-subagents/core/prompt.ts +66 -0
- package/external/pi-tools-suite/src/async-subagents/core/registry.ts +224 -0
- package/external/pi-tools-suite/src/async-subagents/core/retry.ts +191 -0
- package/external/pi-tools-suite/src/async-subagents/core/routing.ts +259 -0
- package/external/pi-tools-suite/src/async-subagents/core/sessions.ts +138 -0
- package/external/pi-tools-suite/src/async-subagents/core/spawn.ts +688 -0
- package/external/pi-tools-suite/src/async-subagents/core/state.ts +281 -0
- package/external/pi-tools-suite/src/async-subagents/core/stop.ts +131 -0
- package/external/pi-tools-suite/src/async-subagents/core/structured-result.ts +237 -0
- package/external/pi-tools-suite/src/async-subagents/core/tool-guard.ts +34 -0
- package/external/pi-tools-suite/src/async-subagents/core/types.ts +150 -0
- package/external/pi-tools-suite/src/async-subagents/core/ultrawork-auto.ts +184 -0
- package/external/pi-tools-suite/src/async-subagents/core/utils.ts +11 -0
- package/external/pi-tools-suite/src/async-subagents/format.ts +41 -0
- package/external/pi-tools-suite/src/async-subagents/index.ts +422 -0
- package/external/pi-tools-suite/src/async-subagents/lib.ts +88 -0
- package/external/pi-tools-suite/src/async-subagents/live.ts +10 -0
- package/external/pi-tools-suite/src/async-subagents/polling.ts +83 -0
- package/external/pi-tools-suite/src/async-subagents/render.ts +230 -0
- package/external/pi-tools-suite/src/async-subagents/subagent-overlay.ts +77 -0
- package/external/pi-tools-suite/src/async-subagents/tasks.ts +120 -0
- package/external/pi-tools-suite/src/async-subagents/tools/cleanup.ts +99 -0
- package/external/pi-tools-suite/src/async-subagents/tools/result.ts +179 -0
- package/external/pi-tools-suite/src/async-subagents/tools/spawn.ts +372 -0
- package/external/pi-tools-suite/src/async-subagents/tools/status.ts +60 -0
- package/external/pi-tools-suite/src/async-subagents/tools/stop.ts +79 -0
- package/external/pi-tools-suite/src/async-subagents/tools/subagents.ts +152 -0
- package/external/pi-tools-suite/src/async-subagents/tools/wait.ts +67 -0
- package/external/pi-tools-suite/src/async-subagents/types.ts +45 -0
- package/external/pi-tools-suite/src/async-subagents/ui.ts +5 -0
- package/external/pi-tools-suite/src/compress/commands.ts +440 -0
- package/external/pi-tools-suite/src/compress/compress-tool.ts +368 -0
- package/external/pi-tools-suite/src/compress/compression-blocks.ts +524 -0
- package/external/pi-tools-suite/src/compress/config.ts +310 -0
- package/external/pi-tools-suite/src/compress/dcp-tui-filter.ts +498 -0
- package/external/pi-tools-suite/src/compress/index.ts +397 -0
- package/external/pi-tools-suite/src/compress/prompts.ts +269 -0
- package/external/pi-tools-suite/src/compress/pruner-candidates.ts +176 -0
- package/external/pi-tools-suite/src/compress/pruner-compression-blocks.ts +260 -0
- package/external/pi-tools-suite/src/compress/pruner-message-ids.ts +147 -0
- package/external/pi-tools-suite/src/compress/pruner-metadata.ts +268 -0
- package/external/pi-tools-suite/src/compress/pruner-nudge.ts +315 -0
- package/external/pi-tools-suite/src/compress/pruner-tools.ts +263 -0
- package/external/pi-tools-suite/src/compress/pruner-types.ts +25 -0
- package/external/pi-tools-suite/src/compress/pruner.ts +92 -0
- package/external/pi-tools-suite/src/compress/state.ts +486 -0
- package/external/pi-tools-suite/src/compress/ui.ts +308 -0
- package/external/pi-tools-suite/src/config.ts +176 -0
- package/external/pi-tools-suite/src/context-usage.ts +31 -0
- package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +355 -0
- package/external/pi-tools-suite/src/index.ts +46 -0
- package/external/pi-tools-suite/src/lib/lsp.ts +62 -0
- package/external/pi-tools-suite/src/lib/project.ts +42 -0
- package/external/pi-tools-suite/src/lib/tool-args.ts +137 -0
- package/external/pi-tools-suite/src/lsp/_shared/config.ts +156 -0
- package/external/pi-tools-suite/src/lsp/_shared/glob.ts +60 -0
- package/external/pi-tools-suite/src/lsp/_shared/output.ts +102 -0
- package/external/pi-tools-suite/src/lsp/_shared/paths.ts +138 -0
- package/external/pi-tools-suite/src/lsp/_shared/runner.ts +64 -0
- package/external/pi-tools-suite/src/lsp/_shared/template.ts +23 -0
- package/external/pi-tools-suite/src/lsp/_shared/trust.ts +116 -0
- package/external/pi-tools-suite/src/lsp/_shared/types.ts +98 -0
- package/external/pi-tools-suite/src/lsp/async.ts +29 -0
- package/external/pi-tools-suite/src/lsp/child-process.ts +81 -0
- package/external/pi-tools-suite/src/lsp/client.ts +340 -0
- package/external/pi-tools-suite/src/lsp/constants.ts +9 -0
- package/external/pi-tools-suite/src/lsp/diagnostics-store.ts +64 -0
- package/external/pi-tools-suite/src/lsp/documents.ts +24 -0
- package/external/pi-tools-suite/src/lsp/index.ts +31 -0
- package/external/pi-tools-suite/src/lsp/lsp-utils.ts +37 -0
- package/external/pi-tools-suite/src/lsp/manager.ts +190 -0
- package/external/pi-tools-suite/src/lsp/mutation-events.ts +78 -0
- package/external/pi-tools-suite/src/lsp/renderer.ts +1 -0
- package/external/pi-tools-suite/src/lsp/tool-result.ts +6 -0
- package/external/pi-tools-suite/src/lsp/tsserver.ts +107 -0
- package/external/pi-tools-suite/src/lsp/types.ts +15 -0
- package/external/pi-tools-suite/src/model-tools/apply-patch.ts +590 -0
- package/external/pi-tools-suite/src/model-tools/index.ts +430 -0
- package/external/pi-tools-suite/src/model-tools/path-utils.ts +6 -0
- package/external/pi-tools-suite/src/model-tools/tool-args.ts +11 -0
- package/external/pi-tools-suite/src/prompt-commands/index.ts +349 -0
- package/external/pi-tools-suite/src/repo-discovery/index.ts +384 -0
- package/external/pi-tools-suite/src/repo-discovery/project.ts +7 -0
- package/external/pi-tools-suite/src/startup-section.ts +13 -0
- package/external/pi-tools-suite/src/terminal-bell/index.ts +309 -0
- package/external/pi-tools-suite/src/todo/index.ts +201 -0
- package/external/pi-tools-suite/src/todo/state/auto-clear.ts +13 -0
- package/external/pi-tools-suite/src/todo/state/invariants.ts +21 -0
- package/external/pi-tools-suite/src/todo/state/persistence.ts +94 -0
- package/external/pi-tools-suite/src/todo/state/replay.ts +38 -0
- package/external/pi-tools-suite/src/todo/state/selectors.ts +49 -0
- package/external/pi-tools-suite/src/todo/state/state-reducer.ts +362 -0
- package/external/pi-tools-suite/src/todo/state/state.ts +18 -0
- package/external/pi-tools-suite/src/todo/state/store.ts +52 -0
- package/external/pi-tools-suite/src/todo/state/task-graph.ts +57 -0
- package/external/pi-tools-suite/src/todo/todo.ts +487 -0
- package/external/pi-tools-suite/src/todo/tool/response-envelope.ts +143 -0
- package/external/pi-tools-suite/src/todo/tool/types.ts +188 -0
- package/external/pi-tools-suite/src/todo/view/format.ts +18 -0
- package/external/pi-tools-suite/src/todo/view/labels.ts +13 -0
- package/external/pi-tools-suite/src/tool-descriptions.ts +369 -0
- package/external/pi-tools-suite/src/usage/index.ts +152 -0
- package/external/pi-tools-suite/src/usage/lib/copilot.ts +535 -0
- package/external/pi-tools-suite/src/usage/lib/google.ts +478 -0
- package/external/pi-tools-suite/src/usage/lib/openai.ts +268 -0
- package/external/pi-tools-suite/src/usage/lib/types.ts +114 -0
- package/external/pi-tools-suite/src/usage/lib/utils.ts +134 -0
- package/external/pi-tools-suite/src/usage/lib/zhipu.ts +228 -0
- package/external/pi-tools-suite/src/web-search/index.ts +397 -0
- package/package.json +89 -0
- package/skills/context7/SKILL.md +69 -0
- package/skills/context7/scripts/context7.sh +73 -0
- package/skills/handoff/SKILL.md +15 -0
- package/skills/pdf/LICENSE.txt +30 -0
- package/skills/pdf/SKILL.md +314 -0
- package/skills/pdf/forms.md +294 -0
- package/skills/pdf/reference.md +612 -0
- package/skills/pdf/scripts/check_bounding_boxes.py +65 -0
- package/skills/pdf/scripts/check_fillable_fields.py +11 -0
- package/skills/pdf/scripts/convert_pdf_to_images.py +33 -0
- package/skills/pdf/scripts/create_validation_image.py +37 -0
- package/skills/pdf/scripts/extract_form_field_info.py +122 -0
- package/skills/pdf/scripts/extract_form_structure.py +115 -0
- package/skills/pdf/scripts/fill_fillable_fields.py +98 -0
- package/skills/pdf/scripts/fill_pdf_form_with_annotations.py +107 -0
- package/skills/playwright-cli/SKILL.md +388 -0
- package/skills/playwright-cli/references/element-attributes.md +23 -0
- package/skills/playwright-cli/references/playwright-tests.md +39 -0
- package/skills/playwright-cli/references/request-mocking.md +87 -0
- package/skills/playwright-cli/references/running-code.md +241 -0
- package/skills/playwright-cli/references/session-management.md +225 -0
- package/skills/playwright-cli/references/spec-driven-testing.md +305 -0
- package/skills/playwright-cli/references/storage-state.md +275 -0
- package/skills/playwright-cli/references/test-generation.md +134 -0
- package/skills/playwright-cli/references/tracing.md +139 -0
- package/skills/playwright-cli/references/video-recording.md +143 -0
- package/skills/simplify/SKILL.md +51 -0
- package/skills/skill-creator/LICENSE.txt +202 -0
- package/skills/skill-creator/SKILL.md +485 -0
- package/skills/skill-creator/agents/analyzer.md +274 -0
- package/skills/skill-creator/agents/comparator.md +202 -0
- package/skills/skill-creator/agents/grader.md +223 -0
- package/skills/skill-creator/assets/eval_review.html +146 -0
- package/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/skills/skill-creator/references/schemas.md +430 -0
- package/skills/skill-creator/scripts/__init__.py +0 -0
- package/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/skills/skill-creator/scripts/generate_report.py +326 -0
- package/skills/skill-creator/scripts/improve_description.py +247 -0
- package/skills/skill-creator/scripts/package_skill.py +136 -0
- package/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/skills/skill-creator/scripts/run_eval.py +310 -0
- package/skills/skill-creator/scripts/run_loop.py +328 -0
- package/skills/skill-creator/scripts/utils.py +47 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
export function bangShellCommandFromInput(text) {
|
|
3
|
+
const trimmed = text.trimStart();
|
|
4
|
+
if (!trimmed.startsWith("!"))
|
|
5
|
+
return undefined;
|
|
6
|
+
const interactive = trimmed.startsWith("!!");
|
|
7
|
+
return { command: trimmed.slice(interactive ? 2 : 1).trim(), interactive };
|
|
8
|
+
}
|
|
9
|
+
export function shellCommandFromBangInput(text) {
|
|
10
|
+
return bangShellCommandFromInput(text)?.command;
|
|
11
|
+
}
|
|
12
|
+
export function runChatShellCommand(command, cwd, handlers = {}) {
|
|
13
|
+
let child;
|
|
14
|
+
try {
|
|
15
|
+
child = spawn(command, {
|
|
16
|
+
cwd,
|
|
17
|
+
env: process.env,
|
|
18
|
+
shell: shellOption(),
|
|
19
|
+
stdio: "pipe",
|
|
20
|
+
...(process.platform === "win32" ? {} : { detached: true }),
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
return failedChatShellCommand(error, handlers);
|
|
25
|
+
}
|
|
26
|
+
let settled = false;
|
|
27
|
+
let resolveDone = () => { };
|
|
28
|
+
const done = new Promise((resolve) => {
|
|
29
|
+
resolveDone = resolve;
|
|
30
|
+
});
|
|
31
|
+
const settle = (result) => {
|
|
32
|
+
if (settled)
|
|
33
|
+
return;
|
|
34
|
+
settled = true;
|
|
35
|
+
handlers.onSettled?.(result);
|
|
36
|
+
resolveDone(result);
|
|
37
|
+
};
|
|
38
|
+
child.stdout.setEncoding("utf8");
|
|
39
|
+
child.stderr.setEncoding("utf8");
|
|
40
|
+
child.stdout.on("data", (chunk) => handlers.onOutput?.(chunk, "stdout"));
|
|
41
|
+
child.stderr.on("data", (chunk) => handlers.onOutput?.(chunk, "stderr"));
|
|
42
|
+
child.once("error", (error) => {
|
|
43
|
+
settle({ exitCode: null, signal: null, error: error instanceof Error ? error.message : String(error) });
|
|
44
|
+
});
|
|
45
|
+
child.once("close", (exitCode, signal) => {
|
|
46
|
+
settle({ exitCode, signal });
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
...(child.pid === undefined ? {} : { pid: child.pid }),
|
|
50
|
+
done,
|
|
51
|
+
writeInput: (input) => {
|
|
52
|
+
if (child.stdin.destroyed || !child.stdin.writable)
|
|
53
|
+
return false;
|
|
54
|
+
try {
|
|
55
|
+
child.stdin.write(input);
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
interrupt: () => signalChildProcess(child, "SIGINT"),
|
|
63
|
+
kill: (signal = "SIGTERM") => signalChildProcess(child, signal),
|
|
64
|
+
endInput: () => {
|
|
65
|
+
try {
|
|
66
|
+
if (!child.stdin.destroyed && child.stdin.writable)
|
|
67
|
+
child.stdin.end();
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// Closing stdin is best-effort during shell teardown.
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export async function runInteractiveShellCommand(command, cwd) {
|
|
76
|
+
const ignoreSigint = () => { };
|
|
77
|
+
process.on("SIGINT", ignoreSigint);
|
|
78
|
+
process.stdout.write(`\n$ ${command}\n\n`);
|
|
79
|
+
try {
|
|
80
|
+
const result = await spawnShellCommand(command, cwd);
|
|
81
|
+
process.stdout.write(`\n[pix] ${formatInteractiveShellResult(result)}\n`);
|
|
82
|
+
await waitForReturnToPix();
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
process.off("SIGINT", ignoreSigint);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
export function formatShellCommandEntry(command, result, prefix = "!") {
|
|
90
|
+
if (result.error)
|
|
91
|
+
return `Shell command failed to start: ${prefix}${command}\n${result.error}`;
|
|
92
|
+
return `Shell command finished (${formatInteractiveShellResult(result)}): ${prefix}${command}`;
|
|
93
|
+
}
|
|
94
|
+
async function spawnShellCommand(command, cwd) {
|
|
95
|
+
try {
|
|
96
|
+
const child = spawn(command, {
|
|
97
|
+
cwd,
|
|
98
|
+
env: process.env,
|
|
99
|
+
shell: shellOption(),
|
|
100
|
+
stdio: "inherit",
|
|
101
|
+
});
|
|
102
|
+
return await new Promise((resolve) => {
|
|
103
|
+
let settled = false;
|
|
104
|
+
const settle = (result) => {
|
|
105
|
+
if (settled)
|
|
106
|
+
return;
|
|
107
|
+
settled = true;
|
|
108
|
+
resolve(result);
|
|
109
|
+
};
|
|
110
|
+
child.once("error", (error) => {
|
|
111
|
+
settle({ exitCode: null, signal: null, error: error instanceof Error ? error.message : String(error) });
|
|
112
|
+
});
|
|
113
|
+
child.once("close", (exitCode, signal) => {
|
|
114
|
+
settle({ exitCode, signal });
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
return { exitCode: null, signal: null, error: error instanceof Error ? error.message : String(error) };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function failedChatShellCommand(error, handlers) {
|
|
123
|
+
const result = { exitCode: null, signal: null, error: error instanceof Error ? error.message : String(error) };
|
|
124
|
+
const done = Promise.resolve(result);
|
|
125
|
+
queueMicrotask(() => handlers.onSettled?.(result));
|
|
126
|
+
return {
|
|
127
|
+
done,
|
|
128
|
+
writeInput: () => false,
|
|
129
|
+
interrupt: () => false,
|
|
130
|
+
kill: () => false,
|
|
131
|
+
endInput: () => { },
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function signalChildProcess(child, signal) {
|
|
135
|
+
if (child.killed)
|
|
136
|
+
return false;
|
|
137
|
+
try {
|
|
138
|
+
if (process.platform !== "win32" && child.pid !== undefined) {
|
|
139
|
+
process.kill(-child.pid, signal);
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
return child.kill(signal);
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
try {
|
|
146
|
+
return child.kill(signal);
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
function shellOption() {
|
|
154
|
+
return process.platform === "win32" ? true : process.env.SHELL || true;
|
|
155
|
+
}
|
|
156
|
+
function formatInteractiveShellResult(result) {
|
|
157
|
+
if (result.error)
|
|
158
|
+
return `failed to start: ${result.error}`;
|
|
159
|
+
if (result.signal)
|
|
160
|
+
return `terminated by ${result.signal}`;
|
|
161
|
+
return `exit ${result.exitCode ?? 0}`;
|
|
162
|
+
}
|
|
163
|
+
async function waitForReturnToPix() {
|
|
164
|
+
if (!process.stdin.isTTY || !process.stdin.readable)
|
|
165
|
+
return;
|
|
166
|
+
process.stdout.write("[pix] Press Enter to return to pix…");
|
|
167
|
+
await new Promise((resolve) => {
|
|
168
|
+
const cleanup = () => {
|
|
169
|
+
process.stdin.off("data", onData);
|
|
170
|
+
resolve();
|
|
171
|
+
};
|
|
172
|
+
const onData = () => cleanup();
|
|
173
|
+
process.stdin.once("data", onData);
|
|
174
|
+
process.stdin.resume();
|
|
175
|
+
});
|
|
176
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type InteractiveShellCommandResult } from "./shell-command.js";
|
|
2
|
+
import type { Entry, SessionActivity } from "./types.js";
|
|
3
|
+
export type AppShellControllerHost = {
|
|
4
|
+
readonly cwd: string;
|
|
5
|
+
isRunning(): boolean;
|
|
6
|
+
addEntry(entry: Entry): void;
|
|
7
|
+
touchEntry(entry: Entry): void;
|
|
8
|
+
setStatus(status: string): void;
|
|
9
|
+
setSessionActivity(activity: SessionActivity): void;
|
|
10
|
+
restoreSessionStatus(): void;
|
|
11
|
+
render(): void;
|
|
12
|
+
};
|
|
13
|
+
export declare class AppShellController {
|
|
14
|
+
private readonly host;
|
|
15
|
+
private activeRun;
|
|
16
|
+
private renderTimer;
|
|
17
|
+
constructor(host: AppShellControllerHost);
|
|
18
|
+
isRunning(): boolean;
|
|
19
|
+
run(command: string): Promise<InteractiveShellCommandResult>;
|
|
20
|
+
sendInput(text: string): boolean;
|
|
21
|
+
interrupt(): boolean;
|
|
22
|
+
dispose(): void;
|
|
23
|
+
private appendOutput;
|
|
24
|
+
private appendInputEcho;
|
|
25
|
+
private finishEntry;
|
|
26
|
+
private touchAndScheduleRender;
|
|
27
|
+
private flushRender;
|
|
28
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { createId } from "./id.js";
|
|
2
|
+
import { runChatShellCommand } from "./shell-command.js";
|
|
3
|
+
const SHELL_RENDER_THROTTLE_MS = 33;
|
|
4
|
+
export class AppShellController {
|
|
5
|
+
host;
|
|
6
|
+
activeRun;
|
|
7
|
+
renderTimer;
|
|
8
|
+
constructor(host) {
|
|
9
|
+
this.host = host;
|
|
10
|
+
}
|
|
11
|
+
isRunning() {
|
|
12
|
+
return this.activeRun !== undefined;
|
|
13
|
+
}
|
|
14
|
+
async run(command) {
|
|
15
|
+
if (this.activeRun)
|
|
16
|
+
throw new Error("A shell command is already running");
|
|
17
|
+
const entry = {
|
|
18
|
+
id: createId("shell"),
|
|
19
|
+
kind: "shell",
|
|
20
|
+
command,
|
|
21
|
+
output: "",
|
|
22
|
+
expanded: true,
|
|
23
|
+
status: "running",
|
|
24
|
+
};
|
|
25
|
+
this.host.addEntry(entry);
|
|
26
|
+
this.host.setStatus(`shell: ${command}`);
|
|
27
|
+
this.host.setSessionActivity("running");
|
|
28
|
+
this.host.render();
|
|
29
|
+
const runningCommand = runChatShellCommand(command, this.host.cwd, {
|
|
30
|
+
onOutput: (chunk) => this.appendOutput(entry, chunk),
|
|
31
|
+
onSettled: (result) => this.finishEntry(entry, result),
|
|
32
|
+
});
|
|
33
|
+
this.activeRun = { entry, command: runningCommand };
|
|
34
|
+
try {
|
|
35
|
+
return await runningCommand.done;
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
if (this.activeRun?.entry === entry)
|
|
39
|
+
this.activeRun = undefined;
|
|
40
|
+
this.flushRender();
|
|
41
|
+
this.host.restoreSessionStatus();
|
|
42
|
+
if (this.host.isRunning())
|
|
43
|
+
this.host.render();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
sendInput(text) {
|
|
47
|
+
const activeRun = this.activeRun;
|
|
48
|
+
if (!activeRun)
|
|
49
|
+
return false;
|
|
50
|
+
const input = text.endsWith("\n") ? text : `${text}\n`;
|
|
51
|
+
this.appendInputEcho(activeRun.entry, input);
|
|
52
|
+
return activeRun.command.writeInput(input);
|
|
53
|
+
}
|
|
54
|
+
interrupt() {
|
|
55
|
+
const activeRun = this.activeRun;
|
|
56
|
+
if (!activeRun)
|
|
57
|
+
return false;
|
|
58
|
+
this.appendOutput(activeRun.entry, "\n^C\n");
|
|
59
|
+
return activeRun.command.interrupt();
|
|
60
|
+
}
|
|
61
|
+
dispose() {
|
|
62
|
+
if (this.renderTimer)
|
|
63
|
+
clearTimeout(this.renderTimer);
|
|
64
|
+
this.renderTimer = undefined;
|
|
65
|
+
const activeRun = this.activeRun;
|
|
66
|
+
this.activeRun = undefined;
|
|
67
|
+
activeRun?.command.kill("SIGTERM");
|
|
68
|
+
}
|
|
69
|
+
appendOutput(entry, chunk) {
|
|
70
|
+
entry.output = appendTerminalChunk(entry.output, chunk);
|
|
71
|
+
this.touchAndScheduleRender(entry);
|
|
72
|
+
}
|
|
73
|
+
appendInputEcho(entry, input) {
|
|
74
|
+
entry.output = appendTerminalChunk(entry.output, formatInputEcho(input));
|
|
75
|
+
this.touchAndScheduleRender(entry);
|
|
76
|
+
}
|
|
77
|
+
finishEntry(entry, result) {
|
|
78
|
+
entry.status = "done";
|
|
79
|
+
entry.exitCode = result.exitCode;
|
|
80
|
+
entry.signal = result.signal;
|
|
81
|
+
if (result.error)
|
|
82
|
+
entry.error = result.error;
|
|
83
|
+
this.touchAndScheduleRender(entry);
|
|
84
|
+
}
|
|
85
|
+
touchAndScheduleRender(entry) {
|
|
86
|
+
this.host.touchEntry(entry);
|
|
87
|
+
if (!this.host.isRunning() || this.renderTimer)
|
|
88
|
+
return;
|
|
89
|
+
this.renderTimer = setTimeout(() => {
|
|
90
|
+
this.renderTimer = undefined;
|
|
91
|
+
if (this.host.isRunning())
|
|
92
|
+
this.host.render();
|
|
93
|
+
}, SHELL_RENDER_THROTTLE_MS);
|
|
94
|
+
this.renderTimer.unref?.();
|
|
95
|
+
}
|
|
96
|
+
flushRender() {
|
|
97
|
+
if (!this.renderTimer)
|
|
98
|
+
return;
|
|
99
|
+
clearTimeout(this.renderTimer);
|
|
100
|
+
this.renderTimer = undefined;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function appendTerminalChunk(current, chunk) {
|
|
104
|
+
let next = current;
|
|
105
|
+
for (let index = 0; index < chunk.length;) {
|
|
106
|
+
const codePoint = chunk.codePointAt(index) ?? 0;
|
|
107
|
+
const char = String.fromCodePoint(codePoint);
|
|
108
|
+
index += codePoint > 0xffff ? 2 : 1;
|
|
109
|
+
if (char === "\r") {
|
|
110
|
+
const lineStart = next.lastIndexOf("\n") + 1;
|
|
111
|
+
next = next.slice(0, lineStart);
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
next += char;
|
|
115
|
+
}
|
|
116
|
+
return next;
|
|
117
|
+
}
|
|
118
|
+
function formatInputEcho(input) {
|
|
119
|
+
const text = input.endsWith("\n") ? input.slice(0, -1) : input;
|
|
120
|
+
const lines = text.split("\n");
|
|
121
|
+
if (lines.length === 1 && lines[0] === "")
|
|
122
|
+
return "\x1b[90m› Enter\x1b[0m\n";
|
|
123
|
+
return `${lines.map((line, index) => `\x1b[90m${index === 0 ? "› " : " "}${line}\x1b[0m`).join("\n")}\n`;
|
|
124
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AgentSessionRuntime } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { type FuzzyMatch } from "../fuzzy.js";
|
|
3
|
+
import type { ParsedSlashInput, SlashCommand } from "./types.js";
|
|
4
|
+
export declare function parseSlashInput(text: string): ParsedSlashInput | undefined;
|
|
5
|
+
export declare function getResourceSlashCommands(runtime: AgentSessionRuntime | undefined, builtInCommands: readonly SlashCommand[]): SlashCommand[];
|
|
6
|
+
export declare function getSlashCommandMatches(commands: readonly SlashCommand[], query: string, limit?: number): FuzzyMatch<SlashCommand>[];
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { fuzzySearch } from "../fuzzy.js";
|
|
2
|
+
export function parseSlashInput(text) {
|
|
3
|
+
if (!text.startsWith("/"))
|
|
4
|
+
return undefined;
|
|
5
|
+
const body = text.slice(1);
|
|
6
|
+
const match = /^(\S*)(?:\s+(.*))?$/.exec(body);
|
|
7
|
+
const commandArguments = match?.[2];
|
|
8
|
+
return {
|
|
9
|
+
commandName: match?.[1] ?? body,
|
|
10
|
+
hasArguments: commandArguments !== undefined,
|
|
11
|
+
arguments: commandArguments ?? "",
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export function getResourceSlashCommands(runtime, builtInCommands) {
|
|
15
|
+
if (!runtime)
|
|
16
|
+
return [];
|
|
17
|
+
const commands = [];
|
|
18
|
+
const seen = new Set(builtInCommands.map((command) => command.name));
|
|
19
|
+
const addResourceCommand = (command) => {
|
|
20
|
+
if (!command.name || seen.has(command.name))
|
|
21
|
+
return;
|
|
22
|
+
seen.add(command.name);
|
|
23
|
+
commands.push({
|
|
24
|
+
...command,
|
|
25
|
+
kind: "resource",
|
|
26
|
+
allowArguments: true,
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
for (const command of runtime.session.extensionRunner.getRegisteredCommands()) {
|
|
30
|
+
addResourceCommand({
|
|
31
|
+
name: command.invocationName,
|
|
32
|
+
description: formatResourceDescription(command.description, "extension", command.sourceInfo),
|
|
33
|
+
source: "extension",
|
|
34
|
+
sourceInfo: command.sourceInfo,
|
|
35
|
+
keywords: [command.name, "extension"],
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
for (const template of runtime.session.promptTemplates) {
|
|
39
|
+
addResourceCommand({
|
|
40
|
+
name: template.name,
|
|
41
|
+
description: formatResourceDescription(template.description, "prompt", template.sourceInfo),
|
|
42
|
+
source: "prompt",
|
|
43
|
+
sourceInfo: template.sourceInfo,
|
|
44
|
+
keywords: ["prompt", "template", template.argumentHint ?? ""].filter(Boolean),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
if (runtime.services.settingsManager.getEnableSkillCommands()) {
|
|
48
|
+
for (const skill of runtime.session.resourceLoader.getSkills().skills) {
|
|
49
|
+
addResourceCommand({
|
|
50
|
+
name: `skill:${skill.name}`,
|
|
51
|
+
description: formatResourceDescription(skill.description, "skill", skill.sourceInfo),
|
|
52
|
+
source: "skill",
|
|
53
|
+
sourceInfo: skill.sourceInfo,
|
|
54
|
+
keywords: ["skill", skill.name],
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return commands;
|
|
59
|
+
}
|
|
60
|
+
export function getSlashCommandMatches(commands, query, limit) {
|
|
61
|
+
const items = commands.map((command) => ({
|
|
62
|
+
value: command,
|
|
63
|
+
label: command.name,
|
|
64
|
+
}));
|
|
65
|
+
return fuzzySearch(items, query, limit === undefined ? {} : { limit });
|
|
66
|
+
}
|
|
67
|
+
function formatResourceDescription(description, source, sourceInfo) {
|
|
68
|
+
const tag = resourceSourceTag(source, sourceInfo);
|
|
69
|
+
return description ? `[${tag}] ${description}` : `[${tag}]`;
|
|
70
|
+
}
|
|
71
|
+
function resourceSourceTag(source, sourceInfo) {
|
|
72
|
+
if (!sourceInfo)
|
|
73
|
+
return source;
|
|
74
|
+
return `${source}:${sourceInfo.scope}`;
|
|
75
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AgentSessionRuntime, LoadExtensionsResult } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
export type StartupAvailabilityIssue = {
|
|
3
|
+
kind: "warning" | "error";
|
|
4
|
+
message: string;
|
|
5
|
+
};
|
|
6
|
+
export declare function collectStartupAvailabilityIssues(runtime: AgentSessionRuntime): Promise<StartupAvailabilityIssue[]>;
|
|
7
|
+
export declare function checkPiCliAvailability(pathValue?: string): Promise<StartupAvailabilityIssue[]>;
|
|
8
|
+
export declare function checkPiToolsSuiteExtensionAvailability(extensionsResult: LoadExtensionsResult): StartupAvailabilityIssue[];
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { access } from "node:fs/promises";
|
|
2
|
+
import { delimiter, join } from "node:path";
|
|
3
|
+
import { constants as fsConstants } from "node:fs";
|
|
4
|
+
const PI_CLI_COMMAND = "pi";
|
|
5
|
+
const PI_TOOLS_SUITE_EXTENSION_ID = "pi-tools-suite";
|
|
6
|
+
export async function collectStartupAvailabilityIssues(runtime) {
|
|
7
|
+
return [
|
|
8
|
+
...(await checkPiCliAvailability()),
|
|
9
|
+
...checkPiToolsSuiteExtensionAvailability(runtime.services.resourceLoader.getExtensions()),
|
|
10
|
+
];
|
|
11
|
+
}
|
|
12
|
+
export async function checkPiCliAvailability(pathValue = process.env.PATH ?? "") {
|
|
13
|
+
if (await executableExistsOnPath(PI_CLI_COMMAND, pathValue))
|
|
14
|
+
return [];
|
|
15
|
+
return [{
|
|
16
|
+
kind: "error",
|
|
17
|
+
message: "pi CLI is not available on PATH. Install pi or add it to PATH before starting pix.",
|
|
18
|
+
}];
|
|
19
|
+
}
|
|
20
|
+
export function checkPiToolsSuiteExtensionAvailability(extensionsResult) {
|
|
21
|
+
if (extensionsResult.extensions.some(isPiToolsSuiteExtension))
|
|
22
|
+
return [];
|
|
23
|
+
const matchingErrors = extensionsResult.errors.filter((error) => pathLooksLikePiToolsSuite(error.path));
|
|
24
|
+
if (matchingErrors.length > 0) {
|
|
25
|
+
return matchingErrors.map((error) => ({
|
|
26
|
+
kind: "error",
|
|
27
|
+
message: `Pix bundled pi-tools-suite failed to load: ${error.error}. Check write access to ~/.pi/agent/extensions and the bundled external/pi-tools-suite payload.`,
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
return [{
|
|
31
|
+
kind: "error",
|
|
32
|
+
message: "Pix bundled pi-tools-suite is not loaded from ~/.pi/agent/extensions/pi-tools-suite. Check write access to ~/.pi/agent/extensions and the bundled external/pi-tools-suite payload.",
|
|
33
|
+
}];
|
|
34
|
+
}
|
|
35
|
+
async function executableExistsOnPath(command, pathValue) {
|
|
36
|
+
const dirs = pathValue.split(delimiter).filter((part) => part.length > 0);
|
|
37
|
+
for (const dir of dirs) {
|
|
38
|
+
try {
|
|
39
|
+
await access(join(dir, command), fsConstants.X_OK);
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// Keep scanning PATH entries.
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
function isPiToolsSuiteExtension(extension) {
|
|
49
|
+
return [
|
|
50
|
+
extension.path,
|
|
51
|
+
extension.resolvedPath,
|
|
52
|
+
extension.sourceInfo.path,
|
|
53
|
+
extension.sourceInfo.source,
|
|
54
|
+
extension.sourceInfo.baseDir,
|
|
55
|
+
].some((value) => value !== undefined && pathLooksLikePiToolsSuite(value));
|
|
56
|
+
}
|
|
57
|
+
function pathLooksLikePiToolsSuite(value) {
|
|
58
|
+
return value.toLowerCase().includes(PI_TOOLS_SUITE_EXTENSION_ID);
|
|
59
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { basename, isAbsolute, relative, sep } from "node:path";
|
|
3
|
+
import { VERSION } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
export function createStartupInfoMessage(runtime) {
|
|
5
|
+
const sections = startupSections(runtime);
|
|
6
|
+
return [
|
|
7
|
+
formatModelLine(runtime),
|
|
8
|
+
`pix · pi-sdk v${VERSION}`,
|
|
9
|
+
"escape interrupt · ctrl+c/ctrl+d clear/exit · / commands",
|
|
10
|
+
"",
|
|
11
|
+
...sections.flatMap(formatSection),
|
|
12
|
+
].join("\n").trimEnd();
|
|
13
|
+
}
|
|
14
|
+
export function isEmptyStartupSession(runtime) {
|
|
15
|
+
return Array.isArray(runtime.session.messages) && runtime.session.messages.length === 0;
|
|
16
|
+
}
|
|
17
|
+
function startupSections(runtime) {
|
|
18
|
+
const loader = runtime.session.resourceLoader;
|
|
19
|
+
const context = loader.getAgentsFiles();
|
|
20
|
+
const skills = loader.getSkills();
|
|
21
|
+
const prompts = loader.getPrompts();
|
|
22
|
+
const extensions = loader.getExtensions();
|
|
23
|
+
const themes = loader.getThemes();
|
|
24
|
+
const diagnostics = [
|
|
25
|
+
...diagnosticLines("skills", skills.diagnostics),
|
|
26
|
+
...diagnosticLines("prompts", prompts.diagnostics),
|
|
27
|
+
...diagnosticLines("themes", themes.diagnostics),
|
|
28
|
+
...extensions.errors.map((error) => `extensions: ${formatPath(error.path, runtime.cwd)} — ${error.error}`),
|
|
29
|
+
];
|
|
30
|
+
return [
|
|
31
|
+
section("Context", context.agentsFiles.map((file) => formatPath(file.path, runtime.cwd))),
|
|
32
|
+
section("Skills", skills.skills.map((skill) => skill.name)),
|
|
33
|
+
section("Prompts", unique(runtime.session.promptTemplates.map((prompt) => prompt.name), prompts.prompts.map((prompt) => prompt.name))),
|
|
34
|
+
section("Extensions", extensionLabels(extensions.extensions, runtime.cwd)),
|
|
35
|
+
section("Themes", themes.themes.map((theme) => theme.name ?? sourcePathLabel(theme.sourcePath, theme.sourceInfo, runtime.cwd))),
|
|
36
|
+
section("Diagnostics", diagnostics),
|
|
37
|
+
].filter((item) => item !== undefined);
|
|
38
|
+
}
|
|
39
|
+
function section(title, items) {
|
|
40
|
+
const filtered = items.map((item) => item.trim()).filter(Boolean);
|
|
41
|
+
return filtered.length > 0 ? { title, items: filtered } : undefined;
|
|
42
|
+
}
|
|
43
|
+
function formatSection(sectionValue) {
|
|
44
|
+
return [`[${sectionValue.title}]`, ` ${sectionValue.items.join(", ")}`, ""];
|
|
45
|
+
}
|
|
46
|
+
function formatModelLine(runtime) {
|
|
47
|
+
const scopedModels = runtime.session.scopedModels;
|
|
48
|
+
if (scopedModels.length > 0) {
|
|
49
|
+
return `Model scope: ${scopedModels.map((item) => modelLabel(item.model.id, item.thinkingLevel)).join(", ")}`;
|
|
50
|
+
}
|
|
51
|
+
const model = runtime.session.model;
|
|
52
|
+
return model ? `Model: ${model.provider}/${modelLabel(model.id, runtime.session.thinkingLevel)}` : "Model: unavailable";
|
|
53
|
+
}
|
|
54
|
+
function modelLabel(modelId, thinkingLevel) {
|
|
55
|
+
return thinkingLevel === undefined || thinkingLevel === "off" ? modelId : `${modelId}:${thinkingLevel}`;
|
|
56
|
+
}
|
|
57
|
+
function diagnosticLines(kind, diagnostics) {
|
|
58
|
+
return diagnostics.map((diag) => `${kind}: [${diag.type}] ${diag.message}${diag.path ? ` (${diag.path})` : ""}`);
|
|
59
|
+
}
|
|
60
|
+
function sourcePathLabel(pathValue, sourceInfo, cwd) {
|
|
61
|
+
if (pathValue)
|
|
62
|
+
return formatPath(pathValue, cwd);
|
|
63
|
+
return sourceInfo ? formatPath(sourceInfo.path, cwd) : "unknown";
|
|
64
|
+
}
|
|
65
|
+
function extensionLabels(extensions, cwd) {
|
|
66
|
+
const localExtensions = extensions
|
|
67
|
+
.map((extension) => ({
|
|
68
|
+
...extension,
|
|
69
|
+
segments: compactDisplayPathSegments(extension.path, cwd),
|
|
70
|
+
}))
|
|
71
|
+
.filter((extension) => !isPackageSource(extension.sourceInfo));
|
|
72
|
+
return extensions.map((extension) => {
|
|
73
|
+
if (isPackageSource(extension.sourceInfo)) {
|
|
74
|
+
return packageExtensionLabel(extension.path, extension.sourceInfo, cwd);
|
|
75
|
+
}
|
|
76
|
+
const localIndex = localExtensions.findIndex((candidate) => candidate.path === extension.path);
|
|
77
|
+
if (localIndex === -1)
|
|
78
|
+
return compactPathLabel(extension.path, cwd);
|
|
79
|
+
return compactNonPackageExtensionLabel(extension.path, localIndex, localExtensions, cwd);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function isPackageSource(sourceInfo) {
|
|
83
|
+
const source = sourceInfo?.source ?? "";
|
|
84
|
+
return source.startsWith("npm:") || source.startsWith("git:");
|
|
85
|
+
}
|
|
86
|
+
function packageExtensionLabel(pathValue, sourceInfo, cwd) {
|
|
87
|
+
const sourceLabel = packageSourceLabel(sourceInfo);
|
|
88
|
+
if (!sourceLabel)
|
|
89
|
+
return compactPathLabel(pathValue, cwd);
|
|
90
|
+
const shortPath = shortPathForSource(pathValue, sourceInfo, cwd).replace(/\\/g, "/");
|
|
91
|
+
const packagePath = shortPath.startsWith("extensions/") ? shortPath.slice("extensions/".length) : shortPath;
|
|
92
|
+
const trimmedPath = packagePath.replace(/\/(index\.[cm]?[jt]s)$/u, "");
|
|
93
|
+
if (!trimmedPath || trimmedPath === "." || /^index\.[cm]?[jt]s$/u.test(trimmedPath))
|
|
94
|
+
return sourceLabel;
|
|
95
|
+
return `${sourceLabel}:${trimmedPath}`;
|
|
96
|
+
}
|
|
97
|
+
function packageSourceLabel(sourceInfo) {
|
|
98
|
+
const source = sourceInfo?.source ?? "";
|
|
99
|
+
if (source.startsWith("npm:"))
|
|
100
|
+
return source.slice("npm:".length) || source;
|
|
101
|
+
if (source.startsWith("git:")) {
|
|
102
|
+
const normalized = source.slice("git:".length).replace(/\.git$/u, "");
|
|
103
|
+
const match = normalized.match(/([^/:]+\/[^/]+)$/u);
|
|
104
|
+
return match?.[1] ?? normalized ?? source;
|
|
105
|
+
}
|
|
106
|
+
return "";
|
|
107
|
+
}
|
|
108
|
+
function compactNonPackageExtensionLabel(pathValue, index, allPaths, cwd) {
|
|
109
|
+
const segments = allPaths[index]?.segments;
|
|
110
|
+
if (!segments || segments.length === 0)
|
|
111
|
+
return compactPathLabel(pathValue, cwd);
|
|
112
|
+
for (let segmentCount = 1; segmentCount <= segments.length; segmentCount += 1) {
|
|
113
|
+
const candidate = segments.slice(-segmentCount).join("/");
|
|
114
|
+
const unique = allPaths.every((item, itemIndex) => {
|
|
115
|
+
if (itemIndex === index)
|
|
116
|
+
return true;
|
|
117
|
+
return item.segments.slice(-segmentCount).join("/") !== candidate;
|
|
118
|
+
});
|
|
119
|
+
if (unique)
|
|
120
|
+
return candidate;
|
|
121
|
+
}
|
|
122
|
+
return segments.join("/");
|
|
123
|
+
}
|
|
124
|
+
function compactDisplayPathSegments(pathValue, cwd) {
|
|
125
|
+
const segments = displayPath(pathValue, cwd)
|
|
126
|
+
.replace(/\\/g, "/")
|
|
127
|
+
.split("/")
|
|
128
|
+
.filter((segment) => segment.length > 0 && segment !== "~");
|
|
129
|
+
const lastSegment = segments.at(-1);
|
|
130
|
+
if (segments.length > 1 && (lastSegment === "index.ts" || lastSegment === "index.js")) {
|
|
131
|
+
segments.pop();
|
|
132
|
+
}
|
|
133
|
+
return segments;
|
|
134
|
+
}
|
|
135
|
+
function compactPathLabel(pathValue, cwd) {
|
|
136
|
+
const segments = compactDisplayPathSegments(pathValue, cwd);
|
|
137
|
+
return segments.at(-1) ?? formatPath(pathValue, cwd);
|
|
138
|
+
}
|
|
139
|
+
function shortPathForSource(pathValue, sourceInfo, cwd) {
|
|
140
|
+
const baseDir = sourceInfo?.baseDir;
|
|
141
|
+
if (baseDir && isPackageSource(sourceInfo)) {
|
|
142
|
+
const rel = relative(baseDir, pathValue);
|
|
143
|
+
if (rel && rel !== "." && !rel.startsWith("..") && !isAbsolute(rel))
|
|
144
|
+
return rel;
|
|
145
|
+
}
|
|
146
|
+
return displayPath(pathValue, cwd);
|
|
147
|
+
}
|
|
148
|
+
function displayPath(pathValue, cwd) {
|
|
149
|
+
if (!isAbsolute(pathValue))
|
|
150
|
+
return pathValue;
|
|
151
|
+
const rel = relative(cwd, pathValue);
|
|
152
|
+
if (rel && rel !== "." && !rel.startsWith("..") && !rel.startsWith(`..${sep}`) && !isAbsolute(rel)) {
|
|
153
|
+
return rel;
|
|
154
|
+
}
|
|
155
|
+
const home = homedir();
|
|
156
|
+
return pathValue.startsWith(home) ? `~${pathValue.slice(home.length)}` : pathValue;
|
|
157
|
+
}
|
|
158
|
+
function formatPath(pathValue, cwd) {
|
|
159
|
+
if (!isAbsolute(pathValue))
|
|
160
|
+
return pathValue;
|
|
161
|
+
const rel = relative(cwd, pathValue);
|
|
162
|
+
return rel && !rel.startsWith("..") && !isAbsolute(rel) ? rel : basename(pathValue);
|
|
163
|
+
}
|
|
164
|
+
function unique(...groups) {
|
|
165
|
+
const seen = new Set();
|
|
166
|
+
const values = [];
|
|
167
|
+
for (const group of groups) {
|
|
168
|
+
for (const item of group) {
|
|
169
|
+
if (seen.has(item))
|
|
170
|
+
continue;
|
|
171
|
+
seen.add(item);
|
|
172
|
+
values.push(item);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return values;
|
|
176
|
+
}
|