@oh-my-pi/pi-coding-agent 8.0.20 → 8.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +125 -0
- package/docs/session.md +111 -46
- package/examples/custom-tools/hello/index.ts +1 -1
- package/examples/custom-tools/todo/index.ts +3 -4
- package/examples/extensions/api-demo.ts +0 -1
- package/examples/extensions/chalk-logger.ts +2 -3
- package/examples/extensions/hello.ts +0 -1
- package/examples/extensions/pirate.ts +0 -1
- package/examples/extensions/plan-mode.ts +15 -16
- package/examples/extensions/todo.ts +3 -4
- package/examples/extensions/tools.ts +1 -2
- package/examples/extensions/with-deps/index.ts +0 -1
- package/examples/hooks/auto-commit-on-exit.ts +1 -2
- package/examples/hooks/confirm-destructive.ts +0 -1
- package/examples/hooks/custom-compaction.ts +1 -2
- package/examples/hooks/dirty-repo-guard.ts +0 -1
- package/examples/hooks/file-trigger.ts +3 -4
- package/examples/hooks/git-checkpoint.ts +0 -1
- package/examples/hooks/handoff.ts +3 -4
- package/examples/hooks/permission-gate.ts +1 -2
- package/examples/hooks/protected-paths.ts +1 -2
- package/examples/hooks/qna.ts +2 -3
- package/examples/hooks/snake.ts +4 -5
- package/examples/hooks/status-line.ts +0 -1
- package/examples/sdk/01-minimal.ts +2 -3
- package/examples/sdk/02-custom-model.ts +2 -3
- package/examples/sdk/03-custom-prompt.ts +3 -4
- package/examples/sdk/04-skills.ts +2 -3
- package/examples/sdk/06-extensions.ts +1 -2
- package/examples/sdk/06-hooks.ts +6 -7
- package/examples/sdk/07-context-files.ts +0 -1
- package/examples/sdk/08-prompt-templates.ts +0 -1
- package/examples/sdk/08-slash-commands.ts +0 -1
- package/examples/sdk/09-api-keys-and-oauth.ts +0 -1
- package/examples/sdk/10-settings.ts +0 -1
- package/examples/sdk/11-sessions.ts +0 -1
- package/package.json +54 -23
- package/scripts/format-prompts.ts +0 -1
- package/src/capability/context-file.ts +3 -4
- package/src/capability/extension-module.ts +3 -4
- package/src/capability/extension.ts +3 -4
- package/src/capability/fs.ts +20 -21
- package/src/capability/hook.ts +3 -4
- package/src/capability/index.ts +15 -16
- package/src/capability/instruction.ts +3 -4
- package/src/capability/mcp.ts +3 -4
- package/src/capability/prompt.ts +3 -4
- package/src/capability/rule.ts +3 -4
- package/src/capability/settings.ts +2 -3
- package/src/capability/skill.ts +3 -4
- package/src/capability/slash-command.ts +3 -4
- package/src/capability/ssh.ts +3 -4
- package/src/capability/system-prompt.ts +3 -4
- package/src/capability/tool.ts +3 -4
- package/src/cli/args.ts +5 -6
- package/src/cli/config-cli.ts +6 -7
- package/src/cli/file-processor.ts +19 -17
- package/src/cli/jupyter-cli.ts +105 -0
- package/src/cli/list-models.ts +10 -11
- package/src/cli/plugin-cli.ts +20 -25
- package/src/cli/session-picker.ts +2 -3
- package/src/cli/setup-cli.ts +2 -3
- package/src/cli/stats-cli.ts +2 -3
- package/src/cli/update-cli.ts +25 -22
- package/src/commit/agentic/agent.ts +307 -0
- package/src/commit/agentic/fallback.ts +96 -0
- package/src/commit/agentic/index.ts +351 -0
- package/src/commit/agentic/prompts/analyze-file.md +22 -0
- package/src/commit/agentic/prompts/session-user.md +26 -0
- package/src/commit/agentic/prompts/split-confirm.md +1 -0
- package/src/commit/agentic/prompts/system.md +40 -0
- package/src/commit/agentic/state.ts +69 -0
- package/src/commit/agentic/tools/analyze-file.ts +131 -0
- package/src/commit/agentic/tools/git-file-diff.ts +194 -0
- package/src/commit/agentic/tools/git-hunk.ts +50 -0
- package/src/commit/agentic/tools/git-overview.ts +84 -0
- package/src/commit/agentic/tools/index.ts +56 -0
- package/src/commit/agentic/tools/propose-changelog.ts +128 -0
- package/src/commit/agentic/tools/propose-commit.ts +154 -0
- package/src/commit/agentic/tools/recent-commits.ts +81 -0
- package/src/commit/agentic/tools/split-commit.ts +280 -0
- package/src/commit/agentic/topo-sort.ts +44 -0
- package/src/commit/agentic/trivial.ts +51 -0
- package/src/commit/agentic/validation.ts +200 -0
- package/src/commit/analysis/conventional.ts +165 -0
- package/src/commit/analysis/index.ts +4 -0
- package/src/commit/analysis/scope.ts +242 -0
- package/src/commit/analysis/summary.ts +112 -0
- package/src/commit/analysis/validation.ts +66 -0
- package/src/commit/changelog/detect.ts +36 -0
- package/src/commit/changelog/generate.ts +110 -0
- package/src/commit/changelog/index.ts +233 -0
- package/src/commit/changelog/parse.ts +44 -0
- package/src/commit/cli.ts +93 -0
- package/src/commit/git/diff.ts +148 -0
- package/src/commit/git/errors.ts +11 -0
- package/src/commit/git/index.ts +212 -0
- package/src/commit/git/operations.ts +53 -0
- package/src/commit/index.ts +5 -0
- package/src/commit/map-reduce/index.ts +63 -0
- package/src/commit/map-reduce/map-phase.ts +178 -0
- package/src/commit/map-reduce/reduce-phase.ts +145 -0
- package/src/commit/map-reduce/utils.ts +9 -0
- package/src/commit/message.ts +11 -0
- package/src/commit/model-selection.ts +80 -0
- package/src/commit/pipeline.ts +240 -0
- package/src/commit/prompts/analysis-system.md +155 -0
- package/src/commit/prompts/analysis-user.md +41 -0
- package/src/commit/prompts/changelog-system.md +56 -0
- package/src/commit/prompts/changelog-user.md +19 -0
- package/src/commit/prompts/file-observer-system.md +26 -0
- package/src/commit/prompts/file-observer-user.md +9 -0
- package/src/commit/prompts/reduce-system.md +60 -0
- package/src/commit/prompts/reduce-user.md +17 -0
- package/src/commit/prompts/summary-retry.md +4 -0
- package/src/commit/prompts/summary-system.md +52 -0
- package/src/commit/prompts/summary-user.md +13 -0
- package/src/commit/prompts/types-description.md +2 -0
- package/src/commit/types.ts +109 -0
- package/src/commit/utils/exclusions.ts +42 -0
- package/src/config/file-lock.ts +121 -0
- package/src/config/keybindings.ts +6 -8
- package/src/config/model-registry.ts +65 -38
- package/src/config/model-resolver.ts +18 -19
- package/src/config/prompt-templates.ts +11 -11
- package/src/config/settings-manager.ts +141 -50
- package/src/config.ts +64 -66
- package/src/cursor.ts +11 -9
- package/src/discovery/agents-md.ts +11 -12
- package/src/discovery/builtin.ts +68 -73
- package/src/discovery/claude.ts +41 -42
- package/src/discovery/cline.ts +11 -12
- package/src/discovery/codex.ts +52 -53
- package/src/discovery/cursor.ts +9 -10
- package/src/discovery/gemini.ts +17 -22
- package/src/discovery/github.ts +13 -14
- package/src/discovery/helpers.ts +35 -34
- package/src/discovery/index.ts +22 -24
- package/src/discovery/mcp-json.ts +8 -9
- package/src/discovery/ssh.ts +8 -9
- package/src/discovery/vscode.ts +4 -5
- package/src/discovery/windsurf.ts +6 -7
- package/src/exa/company.ts +1 -2
- package/src/exa/index.ts +2 -3
- package/src/exa/linkedin.ts +1 -2
- package/src/exa/mcp-client.ts +14 -16
- package/src/exa/render.ts +10 -11
- package/src/exa/researcher.ts +1 -2
- package/src/exa/search.ts +1 -2
- package/src/exa/types.ts +0 -1
- package/src/exa/websets.ts +1 -2
- package/src/exec/bash-executor.ts +3 -4
- package/src/exec/exec.ts +0 -1
- package/src/export/custom-share.ts +5 -6
- package/src/export/html/index.ts +24 -21
- package/src/export/ttsr.ts +2 -3
- package/src/extensibility/custom-commands/bundled/review/index.ts +7 -8
- package/src/extensibility/custom-commands/loader.ts +18 -15
- package/src/extensibility/custom-commands/types.ts +2 -3
- package/src/extensibility/custom-tools/loader.ts +11 -12
- package/src/extensibility/custom-tools/types.ts +7 -8
- package/src/extensibility/custom-tools/wrapper.ts +2 -3
- package/src/extensibility/extensions/loader.ts +76 -54
- package/src/extensibility/extensions/runner.ts +11 -12
- package/src/extensibility/extensions/types.ts +20 -27
- package/src/extensibility/extensions/wrapper.ts +3 -4
- package/src/extensibility/hooks/index.ts +1 -1
- package/src/extensibility/hooks/loader.ts +9 -10
- package/src/extensibility/hooks/runner.ts +7 -8
- package/src/extensibility/hooks/tool-wrapper.ts +0 -1
- package/src/extensibility/hooks/types.ts +11 -18
- package/src/extensibility/plugins/doctor.ts +3 -3
- package/src/extensibility/plugins/installer.ts +27 -27
- package/src/extensibility/plugins/loader.ts +59 -56
- package/src/extensibility/plugins/manager.ts +211 -171
- package/src/extensibility/plugins/parser.ts +1 -1
- package/src/extensibility/plugins/paths.ts +8 -8
- package/src/extensibility/skills.ts +63 -60
- package/src/extensibility/slash-commands.ts +10 -10
- package/src/index.ts +54 -54
- package/src/internal-urls/agent-protocol.ts +21 -11
- package/src/internal-urls/artifact-protocol.ts +17 -13
- package/src/internal-urls/router.ts +1 -2
- package/src/internal-urls/rule-protocol.ts +3 -4
- package/src/internal-urls/skill-protocol.ts +3 -4
- package/src/ipy/executor.ts +109 -9
- package/src/ipy/gateway-coordinator.ts +79 -90
- package/src/ipy/kernel.ts +32 -30
- package/src/ipy/modules.ts +13 -13
- package/src/lsp/client.ts +21 -10
- package/src/lsp/clients/biome-client.ts +1 -2
- package/src/lsp/clients/index.ts +3 -3
- package/src/lsp/clients/lsp-linter-client.ts +4 -5
- package/src/lsp/config.ts +15 -15
- package/src/lsp/edits.ts +4 -5
- package/src/lsp/index.ts +43 -44
- package/src/lsp/lspmux.ts +8 -8
- package/src/lsp/render.ts +99 -61
- package/src/lsp/utils.ts +3 -3
- package/src/main.ts +71 -37
- package/src/mcp/client.ts +2 -3
- package/src/mcp/config.ts +5 -6
- package/src/mcp/json-rpc.ts +0 -1
- package/src/mcp/loader.ts +6 -7
- package/src/mcp/manager.ts +17 -18
- package/src/mcp/tool-bridge.ts +4 -9
- package/src/mcp/tool-cache.ts +2 -3
- package/src/mcp/transports/http.ts +2 -4
- package/src/mcp/transports/stdio.ts +1 -2
- package/src/migrations.ts +63 -52
- package/src/modes/components/armin.ts +4 -5
- package/src/modes/components/assistant-message.ts +33 -5
- package/src/modes/components/bash-execution.ts +7 -8
- package/src/modes/components/bordered-loader.ts +3 -3
- package/src/modes/components/branch-summary-message.ts +3 -3
- package/src/modes/components/compaction-summary-message.ts +3 -3
- package/src/modes/components/countdown-timer.ts +0 -1
- package/src/modes/components/custom-message.ts +5 -5
- package/src/modes/components/diff.ts +1 -1
- package/src/modes/components/dynamic-border.ts +2 -2
- package/src/modes/components/extensions/extension-dashboard.ts +6 -7
- package/src/modes/components/extensions/extension-list.ts +2 -3
- package/src/modes/components/extensions/inspector-panel.ts +3 -4
- package/src/modes/components/extensions/state-manager.ts +25 -26
- package/src/modes/components/extensions/types.ts +1 -2
- package/src/modes/components/footer.ts +47 -43
- package/src/modes/components/history-search.ts +2 -2
- package/src/modes/components/hook-editor.ts +3 -4
- package/src/modes/components/hook-input.ts +2 -3
- package/src/modes/components/hook-message.ts +5 -5
- package/src/modes/components/hook-selector.ts +2 -3
- package/src/modes/components/keybinding-hints.ts +2 -3
- package/src/modes/components/login-dialog.ts +2 -2
- package/src/modes/components/model-selector.ts +12 -12
- package/src/modes/components/oauth-selector.ts +2 -2
- package/src/modes/components/plugin-settings.ts +20 -20
- package/src/modes/components/python-execution.ts +7 -8
- package/src/modes/components/queue-mode-selector.ts +3 -3
- package/src/modes/components/read-tool-group.ts +2 -2
- package/src/modes/components/session-selector.ts +4 -4
- package/src/modes/components/settings-defs.ts +77 -69
- package/src/modes/components/settings-selector.ts +16 -16
- package/src/modes/components/show-images-selector.ts +2 -2
- package/src/modes/components/status-line/segments.ts +4 -4
- package/src/modes/components/status-line/separators.ts +1 -1
- package/src/modes/components/status-line/types.ts +2 -2
- package/src/modes/components/status-line-segment-editor.ts +7 -8
- package/src/modes/components/status-line.ts +12 -12
- package/src/modes/components/theme-selector.ts +8 -7
- package/src/modes/components/thinking-selector.ts +4 -4
- package/src/modes/components/todo-display.ts +2 -2
- package/src/modes/components/todo-reminder.ts +4 -4
- package/src/modes/components/tool-execution.ts +16 -19
- package/src/modes/components/tree-selector.ts +12 -12
- package/src/modes/components/ttsr-notification.ts +5 -5
- package/src/modes/components/user-message-selector.ts +1 -1
- package/src/modes/components/user-message.ts +1 -1
- package/src/modes/components/visual-truncate.ts +0 -1
- package/src/modes/components/welcome.ts +4 -4
- package/src/modes/controllers/command-controller.ts +46 -47
- package/src/modes/controllers/event-controller.ts +16 -20
- package/src/modes/controllers/extension-ui-controller.ts +40 -46
- package/src/modes/controllers/input-controller.ts +17 -18
- package/src/modes/controllers/selector-controller.ts +103 -91
- package/src/modes/index.ts +3 -3
- package/src/modes/interactive-mode.ts +31 -31
- package/src/modes/print-mode.ts +12 -13
- package/src/modes/rpc/rpc-client.ts +7 -8
- package/src/modes/rpc/rpc-mode.ts +24 -28
- package/src/modes/rpc/rpc-types.ts +3 -4
- package/src/modes/theme/mermaid-cache.ts +89 -0
- package/src/modes/theme/theme.ts +130 -53
- package/src/modes/types.ts +10 -10
- package/src/modes/utils/ui-helpers.ts +17 -17
- package/src/patch/applicator.ts +18 -19
- package/src/patch/diff.ts +1 -2
- package/src/patch/fuzzy.ts +1 -2
- package/src/patch/index.ts +11 -18
- package/src/patch/normalize.ts +4 -4
- package/src/patch/normative.ts +1 -2
- package/src/patch/parser.ts +8 -9
- package/src/patch/shared.ts +43 -16
- package/src/prompts/tools/task.md +2 -0
- package/src/sdk.ts +100 -65
- package/src/session/agent-session.ts +84 -85
- package/src/session/agent-storage.ts +43 -39
- package/src/session/artifacts.ts +32 -10
- package/src/session/auth-storage.ts +50 -39
- package/src/session/compaction/branch-summarization.ts +7 -10
- package/src/session/compaction/compaction.ts +8 -19
- package/src/session/compaction/utils.ts +6 -9
- package/src/session/history-storage.ts +10 -10
- package/src/session/messages.ts +4 -5
- package/src/session/session-manager.ts +76 -65
- package/src/session/session-storage.ts +57 -69
- package/src/session/storage-migration.ts +14 -56
- package/src/session/streaming-output.ts +2 -2
- package/src/ssh/connection-manager.ts +43 -50
- package/src/ssh/ssh-executor.ts +2 -2
- package/src/ssh/sshfs-mount.ts +11 -18
- package/src/system-prompt.ts +28 -35
- package/src/task/agents.ts +45 -30
- package/src/task/commands.ts +6 -7
- package/src/task/discovery.ts +39 -76
- package/src/task/executor.ts +14 -15
- package/src/task/index.ts +40 -34
- package/src/task/output-manager.ts +93 -0
- package/src/task/parallel.ts +0 -1
- package/src/task/render.ts +24 -30
- package/src/task/subprocess-tool-registry.ts +1 -2
- package/src/task/worker-protocol.ts +3 -3
- package/src/task/worker.ts +33 -39
- package/src/task/worktree.ts +19 -19
- package/src/tools/ask.ts +41 -20
- package/src/tools/bash-interceptor.ts +1 -5
- package/src/tools/bash.ts +91 -97
- package/src/tools/calculator.ts +49 -47
- package/src/tools/complete.ts +4 -5
- package/src/tools/context.ts +2 -2
- package/src/tools/fetch.ts +84 -124
- package/src/tools/find.ts +94 -98
- package/src/tools/gemini-image.ts +14 -14
- package/src/tools/grep.ts +100 -116
- package/src/tools/index.ts +80 -55
- package/src/tools/list-limit.ts +1 -1
- package/src/tools/ls.ts +44 -70
- package/src/tools/notebook.ts +51 -67
- package/src/tools/output-meta.ts +3 -4
- package/src/tools/output-utils.ts +2 -2
- package/src/tools/path-utils.ts +5 -5
- package/src/tools/python.ts +104 -217
- package/src/tools/read.ts +92 -33
- package/src/tools/render-utils.ts +8 -23
- package/src/tools/renderers.ts +6 -7
- package/src/tools/review.ts +8 -11
- package/src/tools/ssh.ts +69 -49
- package/src/tools/todo-write.ts +37 -25
- package/src/tools/tool-errors.ts +3 -3
- package/src/tools/tool-result.ts +3 -8
- package/src/tools/write.ts +99 -75
- package/src/tui/code-cell.ts +109 -0
- package/src/tui/file-list.ts +47 -0
- package/src/tui/index.ts +11 -0
- package/src/tui/output-block.ts +72 -0
- package/src/tui/status-line.ts +39 -0
- package/src/tui/tree-list.ts +55 -0
- package/src/tui/types.ts +16 -0
- package/src/tui/utils.ts +48 -0
- package/src/utils/changelog.ts +9 -10
- package/src/utils/clipboard.ts +11 -11
- package/src/utils/file-mentions.ts +4 -10
- package/src/utils/frontmatter.ts +6 -3
- package/src/utils/fuzzy.ts +2 -2
- package/src/utils/image-convert.ts +1 -1
- package/src/utils/image-resize.ts +1 -1
- package/src/utils/mime.ts +2 -2
- package/src/utils/shell-snapshot.ts +11 -13
- package/src/utils/shell.ts +4 -5
- package/src/utils/title-generator.ts +8 -9
- package/src/utils/tools-manager.ts +23 -23
- package/src/vendor/photon/index.js +1099 -1059
- package/src/vendor/photon/photon_rs_bg.wasm +0 -0
- package/src/web/scrapers/artifacthub.ts +1 -1
- package/src/web/scrapers/arxiv.ts +2 -2
- package/src/web/scrapers/bluesky.ts +2 -2
- package/src/web/scrapers/cheatsh.ts +1 -1
- package/src/web/scrapers/chocolatey.ts +2 -2
- package/src/web/scrapers/choosealicense.ts +5 -5
- package/src/web/scrapers/cisa-kev.ts +1 -1
- package/src/web/scrapers/crossref.ts +2 -2
- package/src/web/scrapers/devto.ts +3 -3
- package/src/web/scrapers/discogs.ts +3 -4
- package/src/web/scrapers/discourse.ts +1 -1
- package/src/web/scrapers/dockerhub.ts +1 -1
- package/src/web/scrapers/fdroid.ts +2 -2
- package/src/web/scrapers/firefox-addons.ts +3 -3
- package/src/web/scrapers/flathub.ts +1 -1
- package/src/web/scrapers/github.ts +3 -3
- package/src/web/scrapers/gitlab.ts +4 -4
- package/src/web/scrapers/hackernews.ts +2 -2
- package/src/web/scrapers/huggingface.ts +1 -1
- package/src/web/scrapers/iacr.ts +2 -2
- package/src/web/scrapers/index.ts +0 -1
- package/src/web/scrapers/jetbrains-marketplace.ts +1 -1
- package/src/web/scrapers/lemmy.ts +2 -2
- package/src/web/scrapers/maven.ts +2 -2
- package/src/web/scrapers/mdn.ts +2 -4
- package/src/web/scrapers/metacpan.ts +2 -2
- package/src/web/scrapers/musicbrainz.ts +1 -2
- package/src/web/scrapers/npm.ts +1 -1
- package/src/web/scrapers/nuget.ts +2 -2
- package/src/web/scrapers/nvd.ts +3 -3
- package/src/web/scrapers/ollama.ts +7 -9
- package/src/web/scrapers/opencorporates.ts +2 -2
- package/src/web/scrapers/openlibrary.ts +6 -6
- package/src/web/scrapers/orcid.ts +0 -1
- package/src/web/scrapers/osv.ts +2 -2
- package/src/web/scrapers/packagist.ts +1 -1
- package/src/web/scrapers/pubmed.ts +1 -2
- package/src/web/scrapers/rawg.ts +2 -2
- package/src/web/scrapers/readthedocs.ts +1 -2
- package/src/web/scrapers/repology.ts +2 -2
- package/src/web/scrapers/rfc.ts +1 -1
- package/src/web/scrapers/searchcode.ts +2 -2
- package/src/web/scrapers/semantic-scholar.ts +1 -1
- package/src/web/scrapers/snapcraft.ts +2 -2
- package/src/web/scrapers/sourcegraph.ts +1 -1
- package/src/web/scrapers/spdx.ts +3 -3
- package/src/web/scrapers/spotify.ts +0 -1
- package/src/web/scrapers/twitter.ts +1 -1
- package/src/web/scrapers/types.ts +1 -2
- package/src/web/scrapers/utils.ts +5 -5
- package/src/web/scrapers/wikidata.ts +3 -3
- package/src/web/scrapers/youtube.ts +9 -14
- package/src/web/search/auth.ts +5 -10
- package/src/web/search/index.ts +11 -21
- package/src/web/search/providers/anthropic.ts +3 -9
- package/src/web/search/providers/exa.ts +6 -10
- package/src/web/search/providers/perplexity.ts +5 -5
- package/src/web/search/render.ts +129 -175
- package/tsconfig.json +0 -42
package/src/ipy/kernel.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { createServer } from "node:net";
|
|
2
|
-
import
|
|
3
|
-
import { getShellConfig, killProcessTree } from "@oh-my-pi/pi-coding-agent/utils/shell";
|
|
4
|
-
import { getOrCreateSnapshot } from "@oh-my-pi/pi-coding-agent/utils/shell-snapshot";
|
|
5
|
-
import { htmlToBasicMarkdown } from "@oh-my-pi/pi-coding-agent/web/scrapers/types";
|
|
2
|
+
import * as path from "node:path";
|
|
6
3
|
import { logger } from "@oh-my-pi/pi-utils";
|
|
7
4
|
import { $, type Subprocess } from "bun";
|
|
8
5
|
import { nanoid } from "nanoid";
|
|
6
|
+
import { getShellConfig, killProcessTree } from "../utils/shell";
|
|
7
|
+
import { getOrCreateSnapshot } from "../utils/shell-snapshot";
|
|
8
|
+
import { time } from "../utils/timings";
|
|
9
|
+
import { htmlToBasicMarkdown } from "../web/scrapers/types";
|
|
9
10
|
import { acquireSharedGateway, releaseSharedGateway } from "./gateway-coordinator";
|
|
10
11
|
import { loadPythonModules } from "./modules";
|
|
11
12
|
import { PYTHON_PRELUDE } from "./prelude";
|
|
@@ -131,13 +132,13 @@ const BASE_ENV_ALLOWLIST = CASE_INSENSITIVE_ENV
|
|
|
131
132
|
? new Set([...DEFAULT_ENV_ALLOWLIST, ...WINDOWS_ENV_ALLOWLIST])
|
|
132
133
|
: DEFAULT_ENV_ALLOWLIST;
|
|
133
134
|
const NORMALIZED_ALLOWLIST = new Set(
|
|
134
|
-
Array.from(BASE_ENV_ALLOWLIST,
|
|
135
|
+
Array.from(BASE_ENV_ALLOWLIST, key => (CASE_INSENSITIVE_ENV ? key.toUpperCase() : key)),
|
|
135
136
|
);
|
|
136
137
|
const NORMALIZED_DENYLIST = new Set(
|
|
137
|
-
Array.from(DEFAULT_ENV_DENYLIST,
|
|
138
|
+
Array.from(DEFAULT_ENV_DENYLIST, key => (CASE_INSENSITIVE_ENV ? key.toUpperCase() : key)),
|
|
138
139
|
);
|
|
139
140
|
const NORMALIZED_ALLOW_PREFIXES = CASE_INSENSITIVE_ENV
|
|
140
|
-
? DEFAULT_ENV_ALLOW_PREFIXES.map(
|
|
141
|
+
? DEFAULT_ENV_ALLOW_PREFIXES.map(prefix => prefix.toUpperCase())
|
|
141
142
|
: DEFAULT_ENV_ALLOW_PREFIXES;
|
|
142
143
|
|
|
143
144
|
function normalizeEnvKey(key: string): string {
|
|
@@ -146,7 +147,7 @@ function normalizeEnvKey(key: string): string {
|
|
|
146
147
|
|
|
147
148
|
function resolvePathKey(env: Record<string, string | undefined>): string {
|
|
148
149
|
if (!CASE_INSENSITIVE_ENV) return "PATH";
|
|
149
|
-
const match = Object.keys(env).find(
|
|
150
|
+
const match = Object.keys(env).find(candidate => candidate.toLowerCase() === "path");
|
|
150
151
|
return match ?? "PATH";
|
|
151
152
|
}
|
|
152
153
|
|
|
@@ -230,7 +231,7 @@ function filterEnv(env: Record<string, string | undefined>): Record<string, stri
|
|
|
230
231
|
filtered[destKey] = value;
|
|
231
232
|
continue;
|
|
232
233
|
}
|
|
233
|
-
if (NORMALIZED_ALLOW_PREFIXES.some(
|
|
234
|
+
if (NORMALIZED_ALLOW_PREFIXES.some(prefix => normalizedKey.startsWith(prefix))) {
|
|
234
235
|
filtered[key] = value;
|
|
235
236
|
}
|
|
236
237
|
}
|
|
@@ -239,7 +240,7 @@ function filterEnv(env: Record<string, string | undefined>): Record<string, stri
|
|
|
239
240
|
|
|
240
241
|
async function resolveVenvPath(cwd: string): Promise<string | null> {
|
|
241
242
|
if (process.env.VIRTUAL_ENV) return process.env.VIRTUAL_ENV;
|
|
242
|
-
const candidates = [join(cwd, ".venv"), join(cwd, "venv")];
|
|
243
|
+
const candidates = [path.join(cwd, ".venv"), path.join(cwd, "venv")];
|
|
243
244
|
for (const candidate of candidates) {
|
|
244
245
|
if (await Bun.file(candidate).exists()) {
|
|
245
246
|
return candidate;
|
|
@@ -253,12 +254,12 @@ async function resolvePythonRuntime(cwd: string, baseEnv: Record<string, string
|
|
|
253
254
|
const venvPath = env.VIRTUAL_ENV ?? (await resolveVenvPath(cwd));
|
|
254
255
|
if (venvPath) {
|
|
255
256
|
env.VIRTUAL_ENV = venvPath;
|
|
256
|
-
const binDir = process.platform === "win32" ? join(venvPath, "Scripts") : join(venvPath, "bin");
|
|
257
|
-
const pythonCandidate = join(binDir, process.platform === "win32" ? "python.exe" : "python");
|
|
257
|
+
const binDir = process.platform === "win32" ? path.join(venvPath, "Scripts") : path.join(venvPath, "bin");
|
|
258
|
+
const pythonCandidate = path.join(binDir, process.platform === "win32" ? "python.exe" : "python");
|
|
258
259
|
if (await Bun.file(pythonCandidate).exists()) {
|
|
259
260
|
const pathKey = resolvePathKey(env);
|
|
260
261
|
const currentPath = env[pathKey];
|
|
261
|
-
env[pathKey] = currentPath ? `${binDir}${delimiter}${currentPath}` : binDir;
|
|
262
|
+
env[pathKey] = currentPath ? `${binDir}${path.delimiter}${currentPath}` : binDir;
|
|
262
263
|
return { pythonPath: pythonCandidate, env };
|
|
263
264
|
}
|
|
264
265
|
}
|
|
@@ -309,13 +310,11 @@ async function checkExternalGatewayAvailability(config: ExternalGatewayConfig):
|
|
|
309
310
|
}
|
|
310
311
|
|
|
311
312
|
const controller = new AbortController();
|
|
312
|
-
const timeout = setTimeout(() => controller.abort(), 5000);
|
|
313
313
|
|
|
314
314
|
const response = await fetch(`${config.url}/api/kernelspecs`, {
|
|
315
315
|
headers,
|
|
316
|
-
signal: controller.signal,
|
|
316
|
+
signal: AbortSignal.any([controller.signal, AbortSignal.timeout(5000)]),
|
|
317
317
|
});
|
|
318
|
-
clearTimeout(timeout);
|
|
319
318
|
|
|
320
319
|
if (response.ok) {
|
|
321
320
|
return { ok: true };
|
|
@@ -505,6 +504,7 @@ export class PythonKernel {
|
|
|
505
504
|
|
|
506
505
|
static async start(options: KernelStartOptions): Promise<PythonKernel> {
|
|
507
506
|
const availability = await checkPythonKernelAvailability(options.cwd);
|
|
507
|
+
time("PythonKernel.start:availabilityCheck");
|
|
508
508
|
if (!availability.ok) {
|
|
509
509
|
throw new Error(availability.reason ?? "Python kernel unavailable");
|
|
510
510
|
}
|
|
@@ -518,8 +518,11 @@ export class PythonKernel {
|
|
|
518
518
|
if (options.useSharedGateway !== false) {
|
|
519
519
|
try {
|
|
520
520
|
const sharedResult = await acquireSharedGateway(options.cwd);
|
|
521
|
+
time("PythonKernel.start:acquireSharedGateway");
|
|
521
522
|
if (sharedResult) {
|
|
522
|
-
|
|
523
|
+
const kernel = await PythonKernel.startWithSharedGateway(sharedResult.url, options.cwd, options.env);
|
|
524
|
+
time("PythonKernel.start:startWithSharedGateway");
|
|
525
|
+
return kernel;
|
|
523
526
|
}
|
|
524
527
|
} catch (err) {
|
|
525
528
|
logger.warn("Failed to acquire shared gateway, falling back to local", {
|
|
@@ -582,6 +585,7 @@ export class PythonKernel {
|
|
|
582
585
|
headers: { "Content-Type": "application/json" },
|
|
583
586
|
body: JSON.stringify({ name: "python3" }),
|
|
584
587
|
});
|
|
588
|
+
time("startWithSharedGateway:createKernel");
|
|
585
589
|
|
|
586
590
|
if (!createResponse.ok) {
|
|
587
591
|
await releaseSharedGateway();
|
|
@@ -595,13 +599,17 @@ export class PythonKernel {
|
|
|
595
599
|
|
|
596
600
|
try {
|
|
597
601
|
await kernel.connectWebSocket();
|
|
602
|
+
time("startWithSharedGateway:connectWS");
|
|
598
603
|
await kernel.initializeKernelEnvironment(cwd, env);
|
|
604
|
+
time("startWithSharedGateway:initEnv");
|
|
599
605
|
kernel.startHeartbeat();
|
|
600
606
|
const preludeResult = await kernel.execute(PYTHON_PRELUDE, { silent: true, storeHistory: false });
|
|
607
|
+
time("startWithSharedGateway:prelude");
|
|
601
608
|
if (preludeResult.cancelled || preludeResult.status === "error") {
|
|
602
609
|
throw new Error("Failed to initialize Python kernel prelude");
|
|
603
610
|
}
|
|
604
611
|
await loadPythonModules(kernel, { cwd });
|
|
612
|
+
time("startWithSharedGateway:loadModules");
|
|
605
613
|
return kernel;
|
|
606
614
|
} catch (err: unknown) {
|
|
607
615
|
await kernel.shutdown();
|
|
@@ -627,7 +635,7 @@ export class PythonKernel {
|
|
|
627
635
|
OMP_SHELL_SNAPSHOT: snapshotPath ?? undefined,
|
|
628
636
|
};
|
|
629
637
|
|
|
630
|
-
const pythonPathParts = [options.cwd, kernelEnv.PYTHONPATH].filter(Boolean).join(delimiter);
|
|
638
|
+
const pythonPathParts = [options.cwd, kernelEnv.PYTHONPATH].filter(Boolean).join(path.delimiter);
|
|
631
639
|
if (pythonPathParts) {
|
|
632
640
|
kernelEnv.PYTHONPATH = pythonPathParts;
|
|
633
641
|
}
|
|
@@ -754,7 +762,7 @@ export class PythonKernel {
|
|
|
754
762
|
resolve();
|
|
755
763
|
};
|
|
756
764
|
|
|
757
|
-
ws.onerror =
|
|
765
|
+
ws.onerror = event => {
|
|
758
766
|
const error = new Error(`WebSocket error: ${event}`);
|
|
759
767
|
if (!settled) {
|
|
760
768
|
settled = true;
|
|
@@ -779,7 +787,7 @@ export class PythonKernel {
|
|
|
779
787
|
this.abortPendingExecutions("WebSocket closed");
|
|
780
788
|
};
|
|
781
789
|
|
|
782
|
-
ws.onmessage =
|
|
790
|
+
ws.onmessage = event => {
|
|
783
791
|
let msg: JupyterMessage | null = null;
|
|
784
792
|
if (event.data instanceof ArrayBuffer) {
|
|
785
793
|
msg = deserializeWebSocketMessage(event.data);
|
|
@@ -950,7 +958,7 @@ export class PythonKernel {
|
|
|
950
958
|
return promise;
|
|
951
959
|
}
|
|
952
960
|
|
|
953
|
-
this.#messageHandlers.set(msgId, async
|
|
961
|
+
this.#messageHandlers.set(msgId, async response => {
|
|
954
962
|
switch (response.header.msg_type) {
|
|
955
963
|
case "execute_reply": {
|
|
956
964
|
replyReceived = true;
|
|
@@ -1045,7 +1053,7 @@ export class PythonKernel {
|
|
|
1045
1053
|
const result = await this.execute(PRELUDE_INTROSPECTION_SNIPPET, {
|
|
1046
1054
|
silent: false,
|
|
1047
1055
|
storeHistory: false,
|
|
1048
|
-
onChunk:
|
|
1056
|
+
onChunk: text => {
|
|
1049
1057
|
output += text;
|
|
1050
1058
|
},
|
|
1051
1059
|
});
|
|
@@ -1064,14 +1072,11 @@ export class PythonKernel {
|
|
|
1064
1072
|
|
|
1065
1073
|
async interrupt(): Promise<void> {
|
|
1066
1074
|
try {
|
|
1067
|
-
const controller = new AbortController();
|
|
1068
|
-
const timeout = setTimeout(() => controller.abort(), 2000);
|
|
1069
1075
|
await fetch(`${this.gatewayUrl}/api/kernels/${this.kernelId}/interrupt`, {
|
|
1070
1076
|
method: "POST",
|
|
1071
1077
|
headers: this.#authHeaders(),
|
|
1072
|
-
signal:
|
|
1078
|
+
signal: AbortSignal.timeout(2000),
|
|
1073
1079
|
});
|
|
1074
|
-
clearTimeout(timeout);
|
|
1075
1080
|
} catch (err: unknown) {
|
|
1076
1081
|
logger.warn("Failed to interrupt kernel via API", { error: err instanceof Error ? err.message : String(err) });
|
|
1077
1082
|
}
|
|
@@ -1138,13 +1143,10 @@ export class PythonKernel {
|
|
|
1138
1143
|
async ping(timeoutMs: number = HEARTBEAT_TIMEOUT_MS): Promise<boolean> {
|
|
1139
1144
|
if (!this.isAlive()) return false;
|
|
1140
1145
|
try {
|
|
1141
|
-
const controller = new AbortController();
|
|
1142
|
-
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
1143
1146
|
const response = await fetch(`${this.gatewayUrl}/api/kernels/${this.kernelId}`, {
|
|
1144
|
-
signal:
|
|
1147
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
1145
1148
|
headers: this.#authHeaders(),
|
|
1146
1149
|
});
|
|
1147
|
-
clearTimeout(timeout);
|
|
1148
1150
|
if (response.ok) {
|
|
1149
1151
|
this.#heartbeatFailures = 0;
|
|
1150
1152
|
return true;
|
package/src/ipy/modules.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import * as os from "node:os";
|
|
3
|
+
import * as path from "node:path";
|
|
4
4
|
|
|
5
5
|
export type PythonModuleSource = "user" | "project";
|
|
6
6
|
|
|
@@ -38,12 +38,12 @@ interface ModuleCandidate {
|
|
|
38
38
|
|
|
39
39
|
async function listModuleCandidates(dir: string, source: PythonModuleSource): Promise<ModuleCandidate[]> {
|
|
40
40
|
try {
|
|
41
|
-
const entries = await readdir(dir, { withFileTypes: true });
|
|
41
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
42
42
|
return entries
|
|
43
|
-
.filter(
|
|
44
|
-
.map(
|
|
43
|
+
.filter(entry => entry.isFile() && entry.name.endsWith(".py"))
|
|
44
|
+
.map(entry => ({
|
|
45
45
|
name: entry.name,
|
|
46
|
-
path: resolve(dir, entry.name),
|
|
46
|
+
path: path.resolve(dir, entry.name),
|
|
47
47
|
source,
|
|
48
48
|
}));
|
|
49
49
|
} catch {
|
|
@@ -66,13 +66,13 @@ async function readModuleContent(candidate: ModuleCandidate): Promise<PythonModu
|
|
|
66
66
|
*/
|
|
67
67
|
export async function discoverPythonModules(options: DiscoverPythonModulesOptions = {}): Promise<PythonModuleEntry[]> {
|
|
68
68
|
const cwd = options.cwd ?? process.cwd();
|
|
69
|
-
const homeDir = options.homeDir ?? homedir();
|
|
69
|
+
const homeDir = options.homeDir ?? os.homedir();
|
|
70
70
|
|
|
71
|
-
const userDirs = [join(homeDir, ".omp", "agent", "modules"), join(homeDir, ".pi", "agent", "modules")];
|
|
72
|
-
const projectDirs = [resolve(cwd, ".omp", "modules"), resolve(cwd, ".pi", "modules")];
|
|
71
|
+
const userDirs = [path.join(homeDir, ".omp", "agent", "modules"), path.join(homeDir, ".pi", "agent", "modules")];
|
|
72
|
+
const projectDirs = [path.resolve(cwd, ".omp", "modules"), path.resolve(cwd, ".pi", "modules")];
|
|
73
73
|
|
|
74
|
-
const userCandidates = (await Promise.all(userDirs.map(
|
|
75
|
-
const projectCandidates = (await Promise.all(projectDirs.map(
|
|
74
|
+
const userCandidates = (await Promise.all(userDirs.map(dir => listModuleCandidates(dir, "user")))).flat();
|
|
75
|
+
const projectCandidates = (await Promise.all(projectDirs.map(dir => listModuleCandidates(dir, "project")))).flat();
|
|
76
76
|
|
|
77
77
|
const byName = new Map<string, ModuleCandidate>();
|
|
78
78
|
for (const candidate of userCandidates) {
|
|
@@ -88,7 +88,7 @@ export async function discoverPythonModules(options: DiscoverPythonModulesOption
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
const sorted = Array.from(byName.values()).sort((a, b) => a.name.localeCompare(b.name));
|
|
91
|
-
return Promise.all(sorted.map(
|
|
91
|
+
return Promise.all(sorted.map(candidate => readModuleContent(candidate)));
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
/**
|
package/src/lsp/client.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { ToolAbortError, throwIfAborted } from "
|
|
3
|
-
import { logger } from "@oh-my-pi/pi-utils";
|
|
1
|
+
import { isEnoent, logger } from "@oh-my-pi/pi-utils";
|
|
2
|
+
import { ToolAbortError, throwIfAborted } from "../tools/tool-errors";
|
|
4
3
|
import { applyWorkspaceEdit } from "./edits";
|
|
5
4
|
import { getLspmuxCommand, isLspmuxSupported } from "./lspmux";
|
|
6
5
|
import type {
|
|
@@ -298,7 +297,7 @@ async function handleConfigurationRequest(client: LspClient, message: LspJsonRpc
|
|
|
298
297
|
if (typeof message.id !== "number") return;
|
|
299
298
|
const params = message.params as { items?: Array<{ section?: string }> };
|
|
300
299
|
const items = params?.items ?? [];
|
|
301
|
-
const result = items.map(
|
|
300
|
+
const result = items.map(item => {
|
|
302
301
|
const section = item.section ?? "";
|
|
303
302
|
return client.config.settings?.[section] ?? {};
|
|
304
303
|
});
|
|
@@ -512,7 +511,13 @@ export async function ensureFileOpen(client: LspClient, filePath: string): Promi
|
|
|
512
511
|
return;
|
|
513
512
|
}
|
|
514
513
|
|
|
515
|
-
|
|
514
|
+
let content: string;
|
|
515
|
+
try {
|
|
516
|
+
content = await Bun.file(filePath).text();
|
|
517
|
+
} catch (err) {
|
|
518
|
+
if (isEnoent(err)) return;
|
|
519
|
+
throw err;
|
|
520
|
+
}
|
|
516
521
|
const languageId = detectLanguageId(filePath);
|
|
517
522
|
|
|
518
523
|
await sendNotification(client, "textDocument/didOpen", {
|
|
@@ -634,7 +639,13 @@ export async function refreshFile(client: LspClient, filePath: string): Promise<
|
|
|
634
639
|
return;
|
|
635
640
|
}
|
|
636
641
|
|
|
637
|
-
|
|
642
|
+
let content: string;
|
|
643
|
+
try {
|
|
644
|
+
content = await Bun.file(filePath).text();
|
|
645
|
+
} catch (err) {
|
|
646
|
+
if (isEnoent(err)) return;
|
|
647
|
+
throw err;
|
|
648
|
+
}
|
|
638
649
|
const version = ++info.version;
|
|
639
650
|
|
|
640
651
|
await sendNotification(client, "textDocument/didChange", {
|
|
@@ -748,12 +759,12 @@ export async function sendRequest(
|
|
|
748
759
|
|
|
749
760
|
// Register pending request with timeout wrapper
|
|
750
761
|
client.pendingRequests.set(id, {
|
|
751
|
-
resolve:
|
|
762
|
+
resolve: result => {
|
|
752
763
|
if (timeout) clearTimeout(timeout);
|
|
753
764
|
cleanup();
|
|
754
765
|
resolve(result);
|
|
755
766
|
},
|
|
756
|
-
reject:
|
|
767
|
+
reject: err => {
|
|
757
768
|
if (timeout) clearTimeout(timeout);
|
|
758
769
|
cleanup();
|
|
759
770
|
reject(err);
|
|
@@ -762,7 +773,7 @@ export async function sendRequest(
|
|
|
762
773
|
});
|
|
763
774
|
|
|
764
775
|
// Write request
|
|
765
|
-
writeMessage(client.process.stdin as import("bun").FileSink, request).catch(
|
|
776
|
+
writeMessage(client.process.stdin as import("bun").FileSink, request).catch(err => {
|
|
766
777
|
if (timeout) clearTimeout(timeout);
|
|
767
778
|
client.pendingRequests.delete(id);
|
|
768
779
|
cleanup();
|
|
@@ -816,7 +827,7 @@ export interface LspServerStatus {
|
|
|
816
827
|
* Get status of all active LSP clients.
|
|
817
828
|
*/
|
|
818
829
|
export function getActiveClients(): LspServerStatus[] {
|
|
819
|
-
return Array.from(clients.values()).map(
|
|
830
|
+
return Array.from(clients.values()).map(client => ({
|
|
820
831
|
name: client.config.command,
|
|
821
832
|
status: "ready" as const,
|
|
822
833
|
fileTypes: client.config.fileTypes,
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
* Biome CLI-based linter client.
|
|
3
3
|
* Uses Biome's CLI with JSON output instead of LSP (which has stale diagnostics issues).
|
|
4
4
|
*/
|
|
5
|
-
|
|
6
5
|
import path from "node:path";
|
|
7
|
-
import type { Diagnostic, DiagnosticSeverity, LinterClient, ServerConfig } from "
|
|
6
|
+
import type { Diagnostic, DiagnosticSeverity, LinterClient, ServerConfig } from "../../lsp/types";
|
|
8
7
|
|
|
9
8
|
// =============================================================================
|
|
10
9
|
// Biome JSON Output Types
|
package/src/lsp/clients/index.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type { LinterClient, ServerConfig } from "../../lsp/types";
|
|
2
|
+
import { LspLinterClient } from "./lsp-linter-client";
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* Linter client implementations.
|
|
3
6
|
*
|
|
@@ -8,9 +11,6 @@
|
|
|
8
11
|
export { BiomeClient } from "./biome-client";
|
|
9
12
|
export { LspLinterClient } from "./lsp-linter-client";
|
|
10
13
|
|
|
11
|
-
import type { LinterClient, ServerConfig } from "@oh-my-pi/pi-coding-agent/lsp/types";
|
|
12
|
-
import { LspLinterClient } from "./lsp-linter-client";
|
|
13
|
-
|
|
14
14
|
// Cache of linter clients by server name + cwd
|
|
15
15
|
const clientCache = new Map<string, LinterClient>();
|
|
16
16
|
|
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
* LSP-based linter client.
|
|
3
3
|
* Uses the Language Server Protocol for formatting and diagnostics.
|
|
4
4
|
*/
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import { fileToUri } from "@oh-my-pi/pi-coding-agent/lsp/utils";
|
|
5
|
+
import { getOrCreateClient, notifySaved, sendRequest, syncContent } from "../../lsp/client";
|
|
6
|
+
import { applyTextEditsToString } from "../../lsp/edits";
|
|
7
|
+
import type { Diagnostic, LinterClient, LspClient, ServerConfig, TextEdit } from "../../lsp/types";
|
|
8
|
+
import { fileToUri } from "../../lsp/utils";
|
|
10
9
|
|
|
11
10
|
/** Default formatting options for LSP */
|
|
12
11
|
const DEFAULT_FORMAT_OPTIONS = {
|
package/src/lsp/config.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import { getConfigDirPaths } from "@oh-my-pi/pi-coding-agent/config";
|
|
1
|
+
import * as os from "node:os";
|
|
2
|
+
import * as path from "node:path";
|
|
4
3
|
import { logger } from "@oh-my-pi/pi-utils";
|
|
5
4
|
import { YAML } from "bun";
|
|
6
5
|
import { globSync } from "glob";
|
|
6
|
+
import { getConfigDirPaths } from "../config";
|
|
7
7
|
import { BiomeClient } from "./clients/biome-client";
|
|
8
8
|
import DEFAULTS from "./defaults.json" with { type: "json" };
|
|
9
9
|
import type { ServerConfig } from "./types";
|
|
@@ -30,7 +30,7 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
function parseConfigContent(content: string, filePath: string): unknown {
|
|
33
|
-
const extension = extname(filePath).toLowerCase();
|
|
33
|
+
const extension = path.extname(filePath).toLowerCase();
|
|
34
34
|
if (extension === ".yaml" || extension === ".yml") {
|
|
35
35
|
return YAML.parse(content) as unknown;
|
|
36
36
|
}
|
|
@@ -141,7 +141,7 @@ function applyRuntimeDefaults(servers: Record<string, ServerConfig>): Record<str
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
if (updated.omnisharp?.args) {
|
|
144
|
-
const args = updated.omnisharp.args.map(
|
|
144
|
+
const args = updated.omnisharp.args.map(arg => (arg === PID_TOKEN ? String(process.pid) : arg));
|
|
145
145
|
updated.omnisharp = { ...updated.omnisharp, args };
|
|
146
146
|
}
|
|
147
147
|
|
|
@@ -160,7 +160,7 @@ export async function hasRootMarkers(cwd: string, markers: string[]): Promise<bo
|
|
|
160
160
|
// Handle glob-like patterns (e.g., "*.cabal")
|
|
161
161
|
if (marker.includes("*")) {
|
|
162
162
|
try {
|
|
163
|
-
const matches = globSync(join(cwd, marker));
|
|
163
|
+
const matches = globSync(path.join(cwd, marker));
|
|
164
164
|
if (matches.length > 0) {
|
|
165
165
|
return true;
|
|
166
166
|
}
|
|
@@ -169,7 +169,7 @@ export async function hasRootMarkers(cwd: string, markers: string[]): Promise<bo
|
|
|
169
169
|
}
|
|
170
170
|
continue;
|
|
171
171
|
}
|
|
172
|
-
const filePath = join(cwd, marker);
|
|
172
|
+
const filePath = path.join(cwd, marker);
|
|
173
173
|
if (await Bun.file(filePath).exists()) {
|
|
174
174
|
return true;
|
|
175
175
|
}
|
|
@@ -211,7 +211,7 @@ export async function resolveCommand(command: string, cwd: string): Promise<stri
|
|
|
211
211
|
// Check local bin directories based on project markers
|
|
212
212
|
for (const { markers, binDir } of LOCAL_BIN_PATHS) {
|
|
213
213
|
if (await hasRootMarkers(cwd, markers)) {
|
|
214
|
-
const localPath = join(cwd, binDir, command);
|
|
214
|
+
const localPath = path.join(cwd, binDir, command);
|
|
215
215
|
if (await Bun.file(localPath).exists()) {
|
|
216
216
|
return localPath;
|
|
217
217
|
}
|
|
@@ -232,14 +232,14 @@ function getConfigPaths(cwd: string): string[] {
|
|
|
232
232
|
|
|
233
233
|
// Project root files (highest priority)
|
|
234
234
|
for (const filename of filenames) {
|
|
235
|
-
paths.push(join(cwd, filename));
|
|
235
|
+
paths.push(path.join(cwd, filename));
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
// Project config directories (.omp/, .pi/, .claude/)
|
|
239
239
|
const projectDirs = getConfigDirPaths("", { user: false, project: true, cwd });
|
|
240
240
|
for (const dir of projectDirs) {
|
|
241
241
|
for (const filename of filenames) {
|
|
242
|
-
paths.push(join(dir, filename));
|
|
242
|
+
paths.push(path.join(dir, filename));
|
|
243
243
|
}
|
|
244
244
|
}
|
|
245
245
|
|
|
@@ -247,13 +247,13 @@ function getConfigPaths(cwd: string): string[] {
|
|
|
247
247
|
const userDirs = getConfigDirPaths("", { user: true, project: false });
|
|
248
248
|
for (const dir of userDirs) {
|
|
249
249
|
for (const filename of filenames) {
|
|
250
|
-
paths.push(join(dir, filename));
|
|
250
|
+
paths.push(path.join(dir, filename));
|
|
251
251
|
}
|
|
252
252
|
}
|
|
253
253
|
|
|
254
254
|
// User home root files (lowest priority fallback)
|
|
255
255
|
for (const filename of filenames) {
|
|
256
|
-
paths.push(join(homedir(), filename));
|
|
256
|
+
paths.push(path.join(os.homedir(), filename));
|
|
257
257
|
}
|
|
258
258
|
|
|
259
259
|
return paths;
|
|
@@ -352,12 +352,12 @@ export async function loadConfig(cwd: string): Promise<LspConfig> {
|
|
|
352
352
|
* Returns servers sorted with primary (non-linter) servers first.
|
|
353
353
|
*/
|
|
354
354
|
export function getServersForFile(config: LspConfig, filePath: string): Array<[string, ServerConfig]> {
|
|
355
|
-
const ext = extname(filePath).toLowerCase();
|
|
356
|
-
const fileName = basename(filePath).toLowerCase();
|
|
355
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
356
|
+
const fileName = path.basename(filePath).toLowerCase();
|
|
357
357
|
const matches: Array<[string, ServerConfig]> = [];
|
|
358
358
|
|
|
359
359
|
for (const [name, serverConfig] of Object.entries(config.servers)) {
|
|
360
|
-
const supportsFile = serverConfig.fileTypes.some(
|
|
360
|
+
const supportsFile = serverConfig.fileTypes.some(fileType => {
|
|
361
361
|
const normalized = fileType.toLowerCase();
|
|
362
362
|
return normalized === ext || normalized === fileName;
|
|
363
363
|
});
|
package/src/lsp/edits.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import type { CreateFile, DeleteFile, RenameFile, TextDocumentEdit, TextEdit, WorkspaceEdit } from "./types";
|
|
4
4
|
import { uriToFile } from "./utils";
|
|
@@ -86,20 +86,19 @@ export async function applyWorkspaceEdit(edit: WorkspaceEdit, cwd: string): Prom
|
|
|
86
86
|
if (change.kind === "create") {
|
|
87
87
|
const createOp = change as CreateFile;
|
|
88
88
|
const filePath = uriToFile(createOp.uri);
|
|
89
|
-
await mkdir(path.dirname(filePath), { recursive: true });
|
|
90
89
|
await Bun.write(filePath, "");
|
|
91
90
|
applied.push(`Created ${path.relative(cwd, filePath)}`);
|
|
92
91
|
} else if (change.kind === "rename") {
|
|
93
92
|
const renameOp = change as RenameFile;
|
|
94
93
|
const oldPath = uriToFile(renameOp.oldUri);
|
|
95
94
|
const newPath = uriToFile(renameOp.newUri);
|
|
96
|
-
await mkdir(path.dirname(newPath), { recursive: true });
|
|
97
|
-
await rename(oldPath, newPath);
|
|
95
|
+
await fs.mkdir(path.dirname(newPath), { recursive: true });
|
|
96
|
+
await fs.rename(oldPath, newPath);
|
|
98
97
|
applied.push(`Renamed ${path.relative(cwd, oldPath)} → ${path.relative(cwd, newPath)}`);
|
|
99
98
|
} else if (change.kind === "delete") {
|
|
100
99
|
const deleteOp = change as DeleteFile;
|
|
101
100
|
const filePath = uriToFile(deleteOp.uri);
|
|
102
|
-
await rm(filePath, { recursive: true });
|
|
101
|
+
await fs.rm(filePath, { recursive: true });
|
|
103
102
|
applied.push(`Deleted ${path.relative(cwd, filePath)}`);
|
|
104
103
|
}
|
|
105
104
|
}
|