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,37 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import type { ServerCapabilities } from "vscode-languageserver-protocol";
|
|
4
|
+
import { matchesAnyGlob } from "./_shared/glob";
|
|
5
|
+
import { normalizeRelativePath } from "./_shared/paths";
|
|
6
|
+
import type { LspServerConfig } from "./_shared/types";
|
|
7
|
+
|
|
8
|
+
export async function readTextFile(file: string): Promise<string> {
|
|
9
|
+
return fs.readFile(file, "utf8");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function fileSizeAllowed(file: string, limit: number): Promise<boolean> {
|
|
13
|
+
const stat = await fs.stat(file);
|
|
14
|
+
return stat.size <= limit;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function languageIdForFile(server: LspServerConfig, file: string): string {
|
|
18
|
+
const extension = path.extname(file);
|
|
19
|
+
return server.languageIdByExtension?.[extension] ?? (extension.replace(/^\./, "") || "plaintext");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function couldMatchBeforeRoot(file: string, cwd: string, include?: string[], exclude?: string[]): boolean {
|
|
23
|
+
const candidates = [...new Set([normalizeRelativePath(path.relative(cwd, file)), path.basename(file)])];
|
|
24
|
+
const included = !include || include.length === 0 || candidates.some((candidate) => matchesAnyGlob(include, candidate));
|
|
25
|
+
if (!included) return false;
|
|
26
|
+
return !candidates.some((candidate) => matchesAnyGlob(exclude, candidate));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function supportsSave(capabilities: ServerCapabilities | undefined): boolean {
|
|
30
|
+
const sync = capabilities?.textDocumentSync;
|
|
31
|
+
if (!sync || typeof sync === "number") return false;
|
|
32
|
+
return !!sync.save;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function clientKey(serverId: string, root: string): string {
|
|
36
|
+
return `${serverId}\u0000${root}`;
|
|
37
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
import { DEFAULT_DIAGNOSTICS_WAIT_MS, DEFAULT_MAX_FILE_SIZE_BYTES, LSP_MANAGER_GLOBAL_KEY } from "./constants";
|
|
4
|
+
import { DiagnosticsStore } from "./diagnostics-store";
|
|
5
|
+
import { LspClient } from "./client";
|
|
6
|
+
import { loadLspConfig } from "./_shared/config";
|
|
7
|
+
import { isPathIncluded } from "./_shared/glob";
|
|
8
|
+
import { filePathToUri, findProjectRoot, normalizeRelativePath, resolveCommand, toAbsolutePath } from "./_shared/paths";
|
|
9
|
+
import { formatLspDiagnostics, formatWarnings, joinSections } from "./_shared/output";
|
|
10
|
+
import type { LspServerConfig, StoredDiagnostics } from "./_shared/types";
|
|
11
|
+
import { clientKey, couldMatchBeforeRoot, fileSizeAllowed, languageIdForFile, readTextFile } from "./lsp-utils";
|
|
12
|
+
import type { MatchedServer } from "./types";
|
|
13
|
+
|
|
14
|
+
function isFreshDiagnosticsEntry(entry: StoredDiagnostics | undefined, since: number, version: number | undefined): entry is StoredDiagnostics {
|
|
15
|
+
return !!entry
|
|
16
|
+
&& entry.updatedAt >= since
|
|
17
|
+
&& (entry.version === undefined || version === undefined || entry.version >= version);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class LspManager {
|
|
21
|
+
private readonly diagnostics = new DiagnosticsStore();
|
|
22
|
+
private readonly clients = new Map<string, LspClient>();
|
|
23
|
+
private readonly backoff = new Map<string, { retryAt: number; attempts: number; reason: string }>();
|
|
24
|
+
private readonly handleProcessExit = () => {
|
|
25
|
+
this.shutdownAllSync();
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
constructor() {
|
|
29
|
+
process.once("exit", this.handleProcessExit);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async matchingServers(ctx: ExtensionContext, file: string): Promise<{ matches: MatchedServer[]; warnings: string[]; workspace: string }> {
|
|
33
|
+
const loaded = await loadLspConfig(ctx);
|
|
34
|
+
const warnings = [...loaded.warnings];
|
|
35
|
+
const projectLayer = loaded.layers.find((layer) => layer.scope === "project");
|
|
36
|
+
const workspace = projectLayer ? path.dirname(projectLayer.dir) : ctx.cwd;
|
|
37
|
+
const matches: MatchedServer[] = [];
|
|
38
|
+
|
|
39
|
+
for (const server of loaded.items) {
|
|
40
|
+
if (server.enabled === false) continue;
|
|
41
|
+
if (!couldMatchBeforeRoot(file, ctx.cwd, server.include, server.exclude)) continue;
|
|
42
|
+
|
|
43
|
+
const root = findProjectRoot(file, server.rootMarkers, ctx.cwd);
|
|
44
|
+
if (!root) {
|
|
45
|
+
warnings.push(`${server.id}: root markers not found (${(server.rootMarkers ?? []).join(", ") || "none"})`);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
const relFile = normalizeRelativePath(path.relative(root, file));
|
|
49
|
+
if (relFile.startsWith("..") || path.isAbsolute(relFile)) continue;
|
|
50
|
+
if (!isPathIncluded(relFile, server.include, server.exclude)) continue;
|
|
51
|
+
matches.push({ server, root, relFile });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return { matches, warnings, workspace };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private async getClient(server: LspServerConfig, root: string, file: string, workspace: string, signal?: AbortSignal): Promise<LspClient> {
|
|
58
|
+
const key = clientKey(server.id, root);
|
|
59
|
+
const backoff = this.backoff.get(key);
|
|
60
|
+
if (backoff && Date.now() < backoff.retryAt) {
|
|
61
|
+
throw new Error(`${server.id}: unavailable (${backoff.reason}); retry after ${new Date(backoff.retryAt).toISOString()}`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
let client = this.clients.get(key);
|
|
65
|
+
if (!client || client.isUnavailable) {
|
|
66
|
+
const command = resolveCommand(server.id, server, { workspace, root, file });
|
|
67
|
+
client = new LspClient(server, root, command, this.diagnostics);
|
|
68
|
+
this.clients.set(key, client);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
await client.ensureStarted(signal);
|
|
73
|
+
this.backoff.delete(key);
|
|
74
|
+
return client;
|
|
75
|
+
} catch (error) {
|
|
76
|
+
const previous = this.backoff.get(key);
|
|
77
|
+
const attempts = (previous?.attempts ?? 0) + 1;
|
|
78
|
+
const delayMs = Math.min(60_000, 1_000 * 2 ** Math.min(attempts, 6));
|
|
79
|
+
this.backoff.set(key, { attempts, retryAt: Date.now() + delayMs, reason: (error as Error).message });
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async updateDiagnosticsForFile(ctx: ExtensionContext, file: string): Promise<string> {
|
|
85
|
+
const { matches, warnings, workspace } = await this.matchingServers(ctx, file);
|
|
86
|
+
if (matches.length === 0) return formatWarnings("LSP diagnostics", warnings);
|
|
87
|
+
|
|
88
|
+
const lines: string[] = [];
|
|
89
|
+
for (const match of matches) {
|
|
90
|
+
try {
|
|
91
|
+
const maxFileSizeBytes = match.server.maxFileSizeBytes ?? DEFAULT_MAX_FILE_SIZE_BYTES;
|
|
92
|
+
if (!(await fileSizeAllowed(file, maxFileSizeBytes))) {
|
|
93
|
+
lines.push(`⚠️ ${match.server.id}: skipped ${match.relFile}; file exceeds maxFileSizeBytes (${maxFileSizeBytes})`);
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Clear stale diagnostics before refreshing this file. The synchronous
|
|
98
|
+
// wait below must observe a fresh publishDiagnostics notification, not an
|
|
99
|
+
// old error from a previous document version. Empty diagnostics published
|
|
100
|
+
// by the server are stored, but this local clear is not.
|
|
101
|
+
this.diagnostics.clear(match.server.id, match.root, filePathToUri(file));
|
|
102
|
+
|
|
103
|
+
const text = await readTextFile(file);
|
|
104
|
+
const client = await this.getClient(match.server, match.root, file, workspace, ctx.signal);
|
|
105
|
+
const languageId = languageIdForFile(match.server, file);
|
|
106
|
+
const startedAt = Date.now();
|
|
107
|
+
const doc = await client.openOrChange(file, languageId, text, ctx.signal);
|
|
108
|
+
await client.didSave(file);
|
|
109
|
+
const diagnosticsWaitMs = match.server.diagnosticsWaitMs ?? DEFAULT_DIAGNOSTICS_WAIT_MS;
|
|
110
|
+
|
|
111
|
+
// typescript-language-server sometimes does not emit a fresh
|
|
112
|
+
// textDocument/publishDiagnostics notification after didChange/didSave,
|
|
113
|
+
// even though tsserver can answer diagnostics synchronously. Prefer the
|
|
114
|
+
// explicit tsserver request when the server exposes it, so post-edit
|
|
115
|
+
// diagnostics don't degrade into a misleading publishDiagnostics timeout.
|
|
116
|
+
let tsserverFallbackError: string | undefined;
|
|
117
|
+
try {
|
|
118
|
+
const tsserverDiagnostics = await client.tsserverDiagnostics(file, text, diagnosticsWaitMs);
|
|
119
|
+
if (tsserverDiagnostics !== undefined) {
|
|
120
|
+
this.diagnostics.set(match.server.id, match.root, filePathToUri(file), tsserverDiagnostics, doc.version);
|
|
121
|
+
lines.push(formatLspDiagnostics(match.server.id, file, tsserverDiagnostics, match.root));
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
} catch (error) {
|
|
125
|
+
tsserverFallbackError = (error as Error).message;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const entry = await this.diagnostics.waitForFile(
|
|
129
|
+
match.server.id,
|
|
130
|
+
match.root,
|
|
131
|
+
file,
|
|
132
|
+
startedAt,
|
|
133
|
+
doc.version,
|
|
134
|
+
diagnosticsWaitMs,
|
|
135
|
+
ctx.signal,
|
|
136
|
+
);
|
|
137
|
+
if (!isFreshDiagnosticsEntry(entry, startedAt, doc.version)) {
|
|
138
|
+
const fallbackSuffix = tsserverFallbackError ? `; tsserver fallback failed: ${tsserverFallbackError}` : "";
|
|
139
|
+
lines.push(`⚠️ ${match.server.id}: timed out after ${diagnosticsWaitMs}ms waiting for fresh diagnostics for ${match.relFile}${fallbackSuffix}`);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
lines.push(formatLspDiagnostics(match.server.id, file, entry.diagnostics, match.root));
|
|
143
|
+
} catch (error) {
|
|
144
|
+
lines.push(`⚠️ ${match.server.id}: ${(error as Error).message}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return [formatWarnings("LSP diagnostics", warnings), joinSections("LSP diagnostics", lines)].filter(Boolean).join("\n\n");
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async ensureDocumentForTool(ctx: ExtensionContext, inputPath: string): Promise<{ file: string; match: MatchedServer; client: LspClient; workspace: string } | undefined> {
|
|
152
|
+
const file = toAbsolutePath(inputPath, ctx.cwd);
|
|
153
|
+
const { matches, workspace } = await this.matchingServers(ctx, file);
|
|
154
|
+
const match = matches[0];
|
|
155
|
+
if (!match) return undefined;
|
|
156
|
+
const text = await readTextFile(file);
|
|
157
|
+
const client = await this.getClient(match.server, match.root, file, workspace, ctx.signal);
|
|
158
|
+
await client.openOrChange(file, languageIdForFile(match.server, file), text, ctx.signal);
|
|
159
|
+
return { file, match, client, workspace };
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
diagnosticsForPath(ctx: ExtensionContext, inputPath: string): string {
|
|
163
|
+
const file = toAbsolutePath(inputPath, ctx.cwd);
|
|
164
|
+
const entries = this.diagnostics.getAllForFile(file);
|
|
165
|
+
if (entries.length === 0) return `LSP diagnostics:\n\n✅ no diagnostics recorded for ${file}`;
|
|
166
|
+
return joinSections(
|
|
167
|
+
"LSP diagnostics",
|
|
168
|
+
entries.map((entry) => formatLspDiagnostics(entry.serverId, entry.file, entry.diagnostics, entry.root)),
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
async shutdownAll(): Promise<void> {
|
|
173
|
+
const clients = [...this.clients.values()];
|
|
174
|
+
this.clients.clear();
|
|
175
|
+
await Promise.allSettled(clients.map((client) => client.shutdown()));
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
shutdownAllSync(): void {
|
|
179
|
+
const clients = [...this.clients.values()];
|
|
180
|
+
this.clients.clear();
|
|
181
|
+
process.off("exit", this.handleProcessExit);
|
|
182
|
+
for (const client of clients) client.shutdownSync();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export function getGlobalLspManager(): LspManager {
|
|
187
|
+
const globalState = globalThis as typeof globalThis & { [LSP_MANAGER_GLOBAL_KEY]?: LspManager };
|
|
188
|
+
globalState[LSP_MANAGER_GLOBAL_KEY] ??= new LspManager();
|
|
189
|
+
return globalState[LSP_MANAGER_GLOBAL_KEY];
|
|
190
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
function patchTextFromInput(input: unknown): string | undefined {
|
|
2
|
+
if (typeof input === "string") return input;
|
|
3
|
+
if (typeof input !== "object" || input === null) return undefined;
|
|
4
|
+
|
|
5
|
+
const record = input as Record<string, unknown>;
|
|
6
|
+
for (const key of ["input", "patch", "text", "content"]) {
|
|
7
|
+
if (typeof record[key] === "string") return record[key];
|
|
8
|
+
}
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function changedFilesFromDetails(details: unknown): string[] {
|
|
13
|
+
if (typeof details !== "object" || details === null) return [];
|
|
14
|
+
const changedFiles = (details as Record<string, unknown>).changedFiles;
|
|
15
|
+
if (!Array.isArray(changedFiles)) return [];
|
|
16
|
+
return changedFiles.filter((file): file is string => typeof file === "string" && file.trim().length > 0);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function addPaths(paths: Set<string>, inputPaths: string[]): void {
|
|
20
|
+
for (const inputPath of inputPaths) {
|
|
21
|
+
addPath(paths, inputPath);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function addPath(paths: Set<string>, inputPath: string): void {
|
|
26
|
+
const trimmed = inputPath.trim();
|
|
27
|
+
if (trimmed) paths.add(trimmed);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function uniqueNonEmptyPaths(inputPaths: string[]): string[] {
|
|
31
|
+
const paths = new Set<string>();
|
|
32
|
+
addPaths(paths, inputPaths);
|
|
33
|
+
return [...paths];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function getEventPaths(input: unknown, details?: unknown): string[] {
|
|
37
|
+
const record = typeof input === "object" && input !== null ? input as Record<string, unknown> : undefined;
|
|
38
|
+
const exactChangedFiles = changedFilesFromDetails(details);
|
|
39
|
+
if (exactChangedFiles.length > 0) return uniqueNonEmptyPaths(exactChangedFiles);
|
|
40
|
+
|
|
41
|
+
const paths = new Set<string>();
|
|
42
|
+
|
|
43
|
+
if (typeof record?.path === "string") addPath(paths, record.path);
|
|
44
|
+
if (typeof record?.file_path === "string") addPath(paths, record.file_path);
|
|
45
|
+
if (Array.isArray(record?.paths)) addPaths(paths, record.paths.filter((file): file is string => typeof file === "string"));
|
|
46
|
+
|
|
47
|
+
// apply_patch receives the whole patch in a tool-specific field rather than
|
|
48
|
+
// a top-level path. Extract every affected file so multi-file patches refresh
|
|
49
|
+
// diagnostics for all changed files.
|
|
50
|
+
const patchText = patchTextFromInput(input);
|
|
51
|
+
if (patchText) {
|
|
52
|
+
const headerPattern = /^\*\*\* (?:Add|Update|Delete) File: (.+)$/gm;
|
|
53
|
+
for (const match of patchText.matchAll(headerPattern)) {
|
|
54
|
+
const patchPath = match[1]?.trim();
|
|
55
|
+
if (patchPath) addPath(paths, patchPath);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const movePattern = /^\*\*\* Move to: (.+)$/gm;
|
|
59
|
+
for (const match of patchText.matchAll(movePattern)) {
|
|
60
|
+
const patchPath = match[1]?.trim();
|
|
61
|
+
if (patchPath) addPath(paths, patchPath);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return [...paths];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function isMutationToolResult(event: { toolName?: string; input: unknown; details?: unknown }): boolean {
|
|
69
|
+
const toolName = typeof event.toolName === "string" ? event.toolName : "";
|
|
70
|
+
const baseName = (toolName.split(".").pop() ?? toolName).toLowerCase();
|
|
71
|
+
if (["write", "edit", "apply_patch"].includes(baseName)) return true;
|
|
72
|
+
if (baseName === "ast_apply") return changedFilesFromDetails(event.details).length > 0;
|
|
73
|
+
|
|
74
|
+
// Some tool providers may wrap/rename apply_patch but still expose the patch
|
|
75
|
+
// body in the input. Treat patch-shaped input as a file mutation.
|
|
76
|
+
const patchText = patchTextFromInput(event.input);
|
|
77
|
+
return typeof patchText === "string" && /^\*\*\* Begin Patch\b/m.test(patchText);
|
|
78
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// TUI rendering removed — extensions should not render custom TUI components.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { Diagnostic } from "vscode-languageserver-protocol";
|
|
2
|
+
|
|
3
|
+
interface TsserverLocation {
|
|
4
|
+
line?: number;
|
|
5
|
+
offset?: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface TsserverDiagnostic {
|
|
9
|
+
start?: number | TsserverLocation;
|
|
10
|
+
end?: TsserverLocation;
|
|
11
|
+
length?: number;
|
|
12
|
+
text?: unknown;
|
|
13
|
+
message?: unknown;
|
|
14
|
+
code?: string | number;
|
|
15
|
+
category?: string | number;
|
|
16
|
+
source?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface TsserverResponse {
|
|
20
|
+
success?: boolean;
|
|
21
|
+
message?: string;
|
|
22
|
+
body?: unknown;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
26
|
+
return typeof value === "object" && value !== null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function tsserverMessageText(value: unknown): string {
|
|
30
|
+
if (typeof value === "string") return value;
|
|
31
|
+
if (!isRecord(value)) return value === undefined ? "TypeScript diagnostic" : String(value);
|
|
32
|
+
|
|
33
|
+
const messageText = tsserverMessageText(value.messageText);
|
|
34
|
+
const next = Array.isArray(value.next) ? value.next.map(tsserverMessageText).filter((item) => item.trim().length > 0) : [];
|
|
35
|
+
return [messageText, ...next.map((item) => ` ${item}`)].filter((item) => item.trim().length > 0).join("\n");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function isTsserverDiagnostic(value: unknown): value is TsserverDiagnostic {
|
|
39
|
+
return isRecord(value) && ("text" in value || "message" in value || "code" in value);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function tsserverDiagnosticsFromResponse(value: unknown): TsserverDiagnostic[] {
|
|
43
|
+
const response = isRecord(value) ? value as TsserverResponse : undefined;
|
|
44
|
+
if (response?.success === false) throw new Error(response.message ?? "tsserver request failed");
|
|
45
|
+
|
|
46
|
+
const body = response && "body" in response ? response.body : value;
|
|
47
|
+
if (!Array.isArray(body)) return [];
|
|
48
|
+
return body.filter(isTsserverDiagnostic);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function tsserverCategoryToSeverity(category: string | number | undefined): NonNullable<Diagnostic["severity"]> {
|
|
52
|
+
if (category === "error" || category === 1) return 1;
|
|
53
|
+
if (category === "warning" || category === 0) return 2;
|
|
54
|
+
if (category === "message" || category === 3) return 3;
|
|
55
|
+
if (category === "suggestion" || category === 2) return 4;
|
|
56
|
+
return 1;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function positionAtOffset(text: string, offset: number): { line: number; character: number } {
|
|
60
|
+
const safeOffset = Math.max(0, Math.min(text.length, offset));
|
|
61
|
+
let line = 0;
|
|
62
|
+
let lineStart = 0;
|
|
63
|
+
for (let i = 0; i < safeOffset; i += 1) {
|
|
64
|
+
if (text.charCodeAt(i) === 10) {
|
|
65
|
+
line += 1;
|
|
66
|
+
lineStart = i + 1;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return { line, character: safeOffset - lineStart };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function tsserverLocationToPosition(location: TsserverLocation | undefined): { line: number; character: number } | undefined {
|
|
73
|
+
if (typeof location?.line !== "number" || typeof location.offset !== "number") return undefined;
|
|
74
|
+
return {
|
|
75
|
+
line: Math.max(0, location.line - 1),
|
|
76
|
+
character: Math.max(0, location.offset - 1),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function tsserverDiagnosticRange(diagnostic: TsserverDiagnostic, text: string): Diagnostic["range"] {
|
|
81
|
+
if (isRecord(diagnostic.start)) {
|
|
82
|
+
const start = tsserverLocationToPosition(diagnostic.start);
|
|
83
|
+
if (start) return { start, end: tsserverLocationToPosition(diagnostic.end) ?? start };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (typeof diagnostic.start === "number") {
|
|
87
|
+
const startOffset = Math.max(0, diagnostic.start - 1);
|
|
88
|
+
const length = typeof diagnostic.length === "number" ? Math.max(0, diagnostic.length) : 0;
|
|
89
|
+
return {
|
|
90
|
+
start: positionAtOffset(text, startOffset),
|
|
91
|
+
end: positionAtOffset(text, startOffset + length),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const start = { line: 0, character: 0 };
|
|
96
|
+
return { start, end: start };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function tsserverDiagnosticToLsp(diagnostic: TsserverDiagnostic, text: string): Diagnostic {
|
|
100
|
+
return {
|
|
101
|
+
range: tsserverDiagnosticRange(diagnostic, text),
|
|
102
|
+
severity: tsserverCategoryToSeverity(diagnostic.category),
|
|
103
|
+
source: diagnostic.source ?? "typescript",
|
|
104
|
+
message: tsserverMessageText(diagnostic.text ?? diagnostic.message),
|
|
105
|
+
code: diagnostic.code,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { LspServerConfig } from "./_shared/types";
|
|
2
|
+
|
|
3
|
+
export interface MatchedServer {
|
|
4
|
+
server: LspServerConfig;
|
|
5
|
+
root: string;
|
|
6
|
+
relFile: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface OpenDocument {
|
|
10
|
+
file: string;
|
|
11
|
+
uri: string;
|
|
12
|
+
languageId: string;
|
|
13
|
+
version: number;
|
|
14
|
+
text: string;
|
|
15
|
+
}
|