@oh-my-pi/pi-coding-agent 8.1.0 → 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 +21 -1
- 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 +51 -23
- package/scripts/format-prompts.ts +0 -1
- package/src/capability/context-file.ts +2 -3
- package/src/capability/extension-module.ts +2 -3
- package/src/capability/extension.ts +2 -3
- package/src/capability/fs.ts +20 -21
- package/src/capability/hook.ts +2 -3
- package/src/capability/index.ts +15 -16
- package/src/capability/instruction.ts +2 -3
- package/src/capability/mcp.ts +2 -3
- package/src/capability/prompt.ts +2 -3
- package/src/capability/rule.ts +2 -3
- package/src/capability/settings.ts +1 -2
- package/src/capability/skill.ts +2 -3
- package/src/capability/slash-command.ts +2 -3
- package/src/capability/ssh.ts +2 -3
- package/src/capability/system-prompt.ts +2 -3
- package/src/capability/tool.ts +2 -3
- 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 -21
- 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 +21 -23
- package/src/commit/agentic/fallback.ts +9 -9
- package/src/commit/agentic/index.ts +30 -38
- package/src/commit/agentic/state.ts +1 -6
- package/src/commit/agentic/tools/analyze-file.ts +15 -15
- package/src/commit/agentic/tools/git-file-diff.ts +3 -3
- package/src/commit/agentic/tools/git-hunk.ts +7 -7
- package/src/commit/agentic/tools/git-overview.ts +5 -5
- package/src/commit/agentic/tools/index.ts +14 -14
- package/src/commit/agentic/tools/propose-changelog.ts +6 -6
- package/src/commit/agentic/tools/propose-commit.ts +8 -8
- package/src/commit/agentic/tools/recent-commits.ts +2 -2
- package/src/commit/agentic/tools/split-commit.ts +19 -23
- package/src/commit/agentic/topo-sort.ts +1 -1
- package/src/commit/agentic/trivial.ts +3 -3
- package/src/commit/agentic/validation.ts +12 -12
- package/src/commit/analysis/conventional.ts +7 -11
- package/src/commit/analysis/index.ts +4 -4
- package/src/commit/analysis/scope.ts +4 -4
- package/src/commit/analysis/summary.ts +7 -9
- package/src/commit/analysis/validation.ts +1 -1
- package/src/commit/changelog/detect.ts +6 -6
- package/src/commit/changelog/generate.ts +7 -9
- package/src/commit/changelog/index.ts +13 -13
- package/src/commit/changelog/parse.ts +2 -2
- package/src/commit/cli.ts +1 -1
- package/src/commit/git/diff.ts +3 -3
- package/src/commit/git/index.ts +19 -24
- package/src/commit/index.ts +1 -1
- package/src/commit/map-reduce/index.ts +9 -9
- package/src/commit/map-reduce/map-phase.ts +19 -34
- package/src/commit/map-reduce/reduce-phase.ts +9 -11
- package/src/commit/message.ts +2 -2
- package/src/commit/model-selection.ts +3 -7
- package/src/commit/pipeline.ts +20 -22
- package/src/commit/utils/exclusions.ts +3 -3
- package/src/config/file-lock.ts +17 -7
- package/src/config/keybindings.ts +6 -8
- package/src/config/model-registry.ts +55 -37
- package/src/config/model-resolver.ts +18 -19
- package/src/config/prompt-templates.ts +11 -11
- package/src/config/settings-manager.ts +50 -34
- package/src/config.ts +60 -62
- 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 +16 -18
- 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 +17 -14
- package/src/extensibility/custom-commands/types.ts +1 -2
- package/src/extensibility/custom-tools/loader.ts +10 -11
- package/src/extensibility/custom-tools/types.ts +6 -7
- package/src/extensibility/custom-tools/wrapper.ts +2 -3
- package/src/extensibility/extensions/loader.ts +75 -53
- package/src/extensibility/extensions/runner.ts +11 -12
- package/src/extensibility/extensions/types.ts +19 -26
- package/src/extensibility/extensions/wrapper.ts +3 -4
- package/src/extensibility/hooks/index.ts +1 -1
- package/src/extensibility/hooks/loader.ts +8 -9
- package/src/extensibility/hooks/runner.ts +7 -8
- package/src/extensibility/hooks/tool-wrapper.ts +0 -1
- package/src/extensibility/hooks/types.ts +10 -17
- 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 +46 -46
- 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 +14 -10
- 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 +10 -16
- package/src/lsp/utils.ts +3 -3
- package/src/main.ts +55 -34
- 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 +3 -4
- 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 +60 -49
- package/src/modes/components/armin.ts +4 -5
- package/src/modes/components/assistant-message.ts +6 -6
- 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 +11 -16
- package/src/modes/components/tree-selector.ts +11 -11
- 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 +27 -29
- 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 -25
- package/src/modes/rpc/rpc-types.ts +3 -4
- package/src/modes/theme/mermaid-cache.ts +2 -2
- package/src/modes/theme/theme.ts +128 -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 +10 -11
- 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 +12 -13
- package/src/sdk.ts +60 -63
- package/src/session/agent-session.ts +83 -84
- package/src/session/agent-storage.ts +11 -11
- package/src/session/artifacts.ts +8 -9
- package/src/session/auth-storage.ts +25 -29
- 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 +2 -3
- 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 +27 -34
- 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 +33 -36
- package/src/task/output-manager.ts +3 -4
- package/src/task/parallel.ts +0 -1
- package/src/task/render.ts +19 -20
- package/src/task/subprocess-tool-registry.ts +1 -2
- package/src/task/worker-protocol.ts +3 -3
- package/src/task/worker.ts +32 -38
- package/src/task/worktree.ts +19 -19
- package/src/tools/ask.ts +8 -9
- package/src/tools/bash-interceptor.ts +1 -5
- package/src/tools/bash.ts +19 -18
- package/src/tools/calculator.ts +12 -12
- package/src/tools/complete.ts +3 -4
- package/src/tools/context.ts +2 -2
- package/src/tools/fetch.ts +23 -26
- package/src/tools/find.ts +15 -16
- package/src/tools/gemini-image.ts +14 -14
- package/src/tools/grep.ts +27 -27
- package/src/tools/index.ts +78 -56
- package/src/tools/list-limit.ts +1 -1
- package/src/tools/ls.ts +7 -7
- package/src/tools/notebook.ts +5 -5
- package/src/tools/output-meta.ts +3 -4
- package/src/tools/output-utils.ts +1 -1
- package/src/tools/path-utils.ts +5 -5
- package/src/tools/python.ts +36 -37
- package/src/tools/read.ts +23 -23
- package/src/tools/render-utils.ts +8 -9
- package/src/tools/renderers.ts +6 -7
- package/src/tools/review.ts +8 -11
- package/src/tools/ssh.ts +31 -30
- package/src/tools/todo-write.ts +13 -13
- package/src/tools/tool-errors.ts +3 -3
- package/src/tools/tool-result.ts +3 -8
- package/src/tools/write.ts +11 -16
- package/src/tui/code-cell.ts +3 -9
- package/src/tui/file-list.ts +3 -4
- package/src/tui/output-block.ts +1 -2
- package/src/tui/status-line.ts +2 -3
- package/src/tui/tree-list.ts +2 -3
- package/src/tui/types.ts +1 -2
- package/src/tui/utils.ts +2 -3
- 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 +4 -9
- 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 +16 -18
- package/scripts/generate-wasm-b64.ts +0 -24
- package/src/commit/map-reduce/.map-phase.ts.kate-swp +0 -0
- package/src/task/.executor.ts.kate-swp +0 -0
- package/src/vendor/photon/photon_rs_bg.wasm.b64.js +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import { getAgentDir } from "
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { isEnoent } from "@oh-my-pi/pi-utils";
|
|
4
|
+
import { getAgentDir } from "../../config";
|
|
5
5
|
import type { InstalledPlugin } from "./types";
|
|
6
6
|
|
|
7
|
-
const PLUGINS_DIR = join(getAgentDir(), "plugins");
|
|
7
|
+
const PLUGINS_DIR = path.join(getAgentDir(), "plugins");
|
|
8
8
|
|
|
9
9
|
// Valid npm package name pattern (scoped and unscoped)
|
|
10
10
|
const VALID_PACKAGE_NAME = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*(@[a-z0-9-._^~>=<]+)?$/i;
|
|
@@ -26,8 +26,8 @@ function validatePackageName(name: string): void {
|
|
|
26
26
|
* Ensure the plugins directory exists
|
|
27
27
|
*/
|
|
28
28
|
async function ensurePluginsDir(): Promise<void> {
|
|
29
|
-
await mkdir(PLUGINS_DIR, { recursive: true });
|
|
30
|
-
await mkdir(join(PLUGINS_DIR, "node_modules"), { recursive: true });
|
|
29
|
+
await fs.mkdir(PLUGINS_DIR, { recursive: true });
|
|
30
|
+
await fs.mkdir(path.join(PLUGINS_DIR, "node_modules"), { recursive: true });
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
export async function installPlugin(packageName: string): Promise<InstalledPlugin> {
|
|
@@ -38,7 +38,7 @@ export async function installPlugin(packageName: string): Promise<InstalledPlugi
|
|
|
38
38
|
await ensurePluginsDir();
|
|
39
39
|
|
|
40
40
|
// Initialize package.json if it doesn't exist
|
|
41
|
-
const pkgJsonPath = join(PLUGINS_DIR, "package.json");
|
|
41
|
+
const pkgJsonPath = path.join(PLUGINS_DIR, "package.json");
|
|
42
42
|
const pkgJson = Bun.file(pkgJsonPath);
|
|
43
43
|
if (!(await pkgJson.exists())) {
|
|
44
44
|
await pkgJson.write(JSON.stringify({ name: "omp-plugins", private: true, dependencies: {} }, null, 2));
|
|
@@ -62,7 +62,7 @@ export async function installPlugin(packageName: string): Promise<InstalledPlugi
|
|
|
62
62
|
const actualName = packageName.replace(/@[^/]+$/, "").replace(/^(@[^/]+\/[^@]+).*$/, "$1");
|
|
63
63
|
|
|
64
64
|
// Read the installed package's package.json
|
|
65
|
-
const pkgPath = join(PLUGINS_DIR, "node_modules", actualName, "package.json");
|
|
65
|
+
const pkgPath = path.join(PLUGINS_DIR, "node_modules", actualName, "package.json");
|
|
66
66
|
const pkgFile = Bun.file(pkgPath);
|
|
67
67
|
if (!(await pkgFile.exists())) {
|
|
68
68
|
throw new Error(`Package installed but package.json not found at ${pkgPath}`);
|
|
@@ -73,7 +73,7 @@ export async function installPlugin(packageName: string): Promise<InstalledPlugi
|
|
|
73
73
|
return {
|
|
74
74
|
name: pkg.name,
|
|
75
75
|
version: pkg.version,
|
|
76
|
-
path: join(PLUGINS_DIR, "node_modules", actualName),
|
|
76
|
+
path: path.join(PLUGINS_DIR, "node_modules", actualName),
|
|
77
77
|
manifest: pkg.omp || pkg.pi || { version: pkg.version },
|
|
78
78
|
enabledFeatures: null,
|
|
79
79
|
enabled: true,
|
|
@@ -100,7 +100,7 @@ export async function uninstallPlugin(name: string): Promise<void> {
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
export async function listPlugins(): Promise<InstalledPlugin[]> {
|
|
103
|
-
const pkgJsonPath = Bun.file(join(PLUGINS_DIR, "package.json"));
|
|
103
|
+
const pkgJsonPath = Bun.file(path.join(PLUGINS_DIR, "package.json"));
|
|
104
104
|
if (!(await pkgJsonPath.exists())) {
|
|
105
105
|
return [];
|
|
106
106
|
}
|
|
@@ -110,14 +110,14 @@ export async function listPlugins(): Promise<InstalledPlugin[]> {
|
|
|
110
110
|
|
|
111
111
|
const plugins: InstalledPlugin[] = [];
|
|
112
112
|
for (const [name, _version] of Object.entries(deps)) {
|
|
113
|
-
const
|
|
114
|
-
const fpkg = Bun.file(join(
|
|
113
|
+
const pluginPath = path.join(PLUGINS_DIR, "node_modules", name);
|
|
114
|
+
const fpkg = Bun.file(path.join(pluginPath, "package.json"));
|
|
115
115
|
if (await fpkg.exists()) {
|
|
116
116
|
const pkg = await fpkg.json();
|
|
117
117
|
plugins.push({
|
|
118
118
|
name,
|
|
119
119
|
version: pkg.version,
|
|
120
|
-
path,
|
|
120
|
+
path: pluginPath,
|
|
121
121
|
manifest: pkg.omp || pkg.pi || { version: pkg.version },
|
|
122
122
|
enabledFeatures: null,
|
|
123
123
|
enabled: true,
|
|
@@ -130,17 +130,17 @@ export async function listPlugins(): Promise<InstalledPlugin[]> {
|
|
|
130
130
|
|
|
131
131
|
export async function linkPlugin(localPath: string): Promise<void> {
|
|
132
132
|
const cwd = process.cwd();
|
|
133
|
-
const absolutePath = resolve(cwd, localPath);
|
|
133
|
+
const absolutePath = path.resolve(cwd, localPath);
|
|
134
134
|
|
|
135
135
|
// Validate that resolved path is within cwd to prevent path traversal
|
|
136
|
-
const normalizedCwd = resolve(cwd);
|
|
137
|
-
const normalizedPath = resolve(absolutePath);
|
|
136
|
+
const normalizedCwd = path.resolve(cwd);
|
|
137
|
+
const normalizedPath = path.resolve(absolutePath);
|
|
138
138
|
if (!normalizedPath.startsWith(`${normalizedCwd}/`) && normalizedPath !== normalizedCwd) {
|
|
139
139
|
throw new Error(`Invalid path: ${localPath} resolves outside working directory`);
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
// Validate package.json exists
|
|
143
|
-
const pkgFile = Bun.file(join(absolutePath, "package.json"));
|
|
143
|
+
const pkgFile = Bun.file(path.join(absolutePath, "package.json"));
|
|
144
144
|
if (!(await pkgFile.exists())) {
|
|
145
145
|
throw new Error(`package.json not found at ${absolutePath}`);
|
|
146
146
|
}
|
|
@@ -167,24 +167,24 @@ export async function linkPlugin(localPath: string): Promise<void> {
|
|
|
167
167
|
await ensurePluginsDir();
|
|
168
168
|
|
|
169
169
|
// Create symlink in plugins/node_modules
|
|
170
|
-
const linkPath = join(PLUGINS_DIR, "node_modules", pkg.name);
|
|
170
|
+
const linkPath = path.join(PLUGINS_DIR, "node_modules", pkg.name);
|
|
171
171
|
|
|
172
172
|
// For scoped packages, ensure the scope directory exists
|
|
173
173
|
if (pkg.name.startsWith("@")) {
|
|
174
|
-
const scopeDir = join(PLUGINS_DIR, "node_modules", pkg.name.split("/")[0]);
|
|
175
|
-
await mkdir(scopeDir, { recursive: true });
|
|
174
|
+
const scopeDir = path.join(PLUGINS_DIR, "node_modules", pkg.name.split("/")[0]);
|
|
175
|
+
await fs.mkdir(scopeDir, { recursive: true });
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
// Remove existing if present
|
|
179
179
|
try {
|
|
180
|
-
const
|
|
181
|
-
if (
|
|
182
|
-
|
|
180
|
+
const stats = await fs.lstat(linkPath);
|
|
181
|
+
if (stats.isSymbolicLink() || stats.isDirectory()) {
|
|
182
|
+
await fs.unlink(linkPath);
|
|
183
183
|
}
|
|
184
|
-
} catch {
|
|
185
|
-
|
|
184
|
+
} catch (err) {
|
|
185
|
+
if (!isEnoent(err)) throw err;
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
// Create symlink using fs instead of shell command
|
|
189
|
-
|
|
189
|
+
await fs.symlink(absolutePath, linkPath);
|
|
190
190
|
}
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* Reads enabled plugins from the runtime config and loads their tools/hooks
|
|
5
5
|
* based on manifest entries and enabled features.
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
7
|
+
import * as fs from "node:fs";
|
|
8
|
+
import * as path from "node:path";
|
|
9
|
+
import { isEnoent } from "@oh-my-pi/pi-utils";
|
|
10
10
|
import {
|
|
11
11
|
getAllProjectPluginOverridePaths,
|
|
12
12
|
getPluginsLockfile,
|
|
@@ -22,29 +22,26 @@ import type { InstalledPlugin, PluginManifest, PluginRuntimeConfig, ProjectPlugi
|
|
|
22
22
|
/**
|
|
23
23
|
* Load plugin runtime config from lock file.
|
|
24
24
|
*/
|
|
25
|
-
function loadRuntimeConfig(): PluginRuntimeConfig {
|
|
25
|
+
async function loadRuntimeConfig(): Promise<PluginRuntimeConfig> {
|
|
26
26
|
const lockPath = getPluginsLockfile();
|
|
27
|
-
if (!existsSync(lockPath)) {
|
|
28
|
-
return { plugins: {}, settings: {} };
|
|
29
|
-
}
|
|
30
27
|
try {
|
|
31
|
-
return
|
|
32
|
-
} catch {
|
|
33
|
-
return { plugins: {}, settings: {} };
|
|
28
|
+
return await Bun.file(lockPath).json();
|
|
29
|
+
} catch (err) {
|
|
30
|
+
if (isEnoent(err)) return { plugins: {}, settings: {} };
|
|
31
|
+
throw err;
|
|
34
32
|
}
|
|
35
33
|
}
|
|
36
34
|
|
|
37
35
|
/**
|
|
38
36
|
* Load project-local plugin overrides (checks .omp and .pi directories).
|
|
39
37
|
*/
|
|
40
|
-
function loadProjectOverrides(cwd: string): ProjectPluginOverrides {
|
|
38
|
+
async function loadProjectOverrides(cwd: string): Promise<ProjectPluginOverrides> {
|
|
41
39
|
for (const overridesPath of getAllProjectPluginOverridePaths(cwd)) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
40
|
+
try {
|
|
41
|
+
return await Bun.file(overridesPath).json();
|
|
42
|
+
} catch (err) {
|
|
43
|
+
if (isEnoent(err)) continue;
|
|
44
|
+
// JSON parse error - continue to next path
|
|
48
45
|
}
|
|
49
46
|
}
|
|
50
47
|
return {};
|
|
@@ -58,30 +55,36 @@ function loadProjectOverrides(cwd: string): ProjectPluginOverrides {
|
|
|
58
55
|
* Get list of enabled plugins with their resolved configurations.
|
|
59
56
|
* Respects both global runtime config and project overrides.
|
|
60
57
|
*/
|
|
61
|
-
export function getEnabledPlugins(cwd: string): InstalledPlugin[] {
|
|
58
|
+
export async function getEnabledPlugins(cwd: string): Promise<InstalledPlugin[]> {
|
|
62
59
|
const pkgJsonPath = getPluginsPackageJson();
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
let pkg: { dependencies?: Record<string, string> };
|
|
61
|
+
try {
|
|
62
|
+
pkg = await Bun.file(pkgJsonPath).json();
|
|
63
|
+
} catch (err) {
|
|
64
|
+
if (isEnoent(err)) return [];
|
|
65
|
+
throw err;
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
const nodeModulesPath = getPluginsNodeModules();
|
|
68
|
-
if (!existsSync(nodeModulesPath)) {
|
|
69
|
+
if (!fs.existsSync(nodeModulesPath)) {
|
|
69
70
|
return [];
|
|
70
71
|
}
|
|
71
72
|
|
|
72
|
-
const pkg = JSON.parse(readFileSync(pkgJsonPath, "utf-8"));
|
|
73
73
|
const deps = pkg.dependencies || {};
|
|
74
|
-
const runtimeConfig = loadRuntimeConfig();
|
|
75
|
-
const projectOverrides = loadProjectOverrides(cwd);
|
|
74
|
+
const runtimeConfig = await loadRuntimeConfig();
|
|
75
|
+
const projectOverrides = await loadProjectOverrides(cwd);
|
|
76
76
|
const plugins: InstalledPlugin[] = [];
|
|
77
77
|
|
|
78
78
|
for (const [name] of Object.entries(deps)) {
|
|
79
|
-
const pluginPkgPath = join(nodeModulesPath, name, "package.json");
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
const pluginPkgPath = path.join(nodeModulesPath, name, "package.json");
|
|
80
|
+
let pluginPkg: { version: string; omp?: PluginManifest; pi?: PluginManifest };
|
|
81
|
+
try {
|
|
82
|
+
pluginPkg = await Bun.file(pluginPkgPath).json();
|
|
83
|
+
} catch (err) {
|
|
84
|
+
if (isEnoent(err)) continue;
|
|
85
|
+
throw err;
|
|
82
86
|
}
|
|
83
87
|
|
|
84
|
-
const pluginPkg = JSON.parse(readFileSync(pluginPkgPath, "utf-8"));
|
|
85
88
|
const manifest: PluginManifest | undefined = pluginPkg.omp || pluginPkg.pi;
|
|
86
89
|
|
|
87
90
|
if (!manifest) {
|
|
@@ -109,7 +112,7 @@ export function getEnabledPlugins(cwd: string): InstalledPlugin[] {
|
|
|
109
112
|
plugins.push({
|
|
110
113
|
name,
|
|
111
114
|
version: pluginPkg.version,
|
|
112
|
-
path: join(nodeModulesPath, name),
|
|
115
|
+
path: path.join(nodeModulesPath, name),
|
|
113
116
|
manifest,
|
|
114
117
|
enabledFeatures,
|
|
115
118
|
enabled: true,
|
|
@@ -133,8 +136,8 @@ export function resolvePluginToolPaths(plugin: InstalledPlugin): string[] {
|
|
|
133
136
|
|
|
134
137
|
// Base tools entry (always included if exists)
|
|
135
138
|
if (manifest.tools) {
|
|
136
|
-
const toolPath = join(plugin.path, manifest.tools);
|
|
137
|
-
if (existsSync(toolPath)) {
|
|
139
|
+
const toolPath = path.join(plugin.path, manifest.tools);
|
|
140
|
+
if (fs.existsSync(toolPath)) {
|
|
138
141
|
paths.push(toolPath);
|
|
139
142
|
}
|
|
140
143
|
}
|
|
@@ -148,8 +151,8 @@ export function resolvePluginToolPaths(plugin: InstalledPlugin): string[] {
|
|
|
148
151
|
|
|
149
152
|
if (feat.tools) {
|
|
150
153
|
for (const toolEntry of feat.tools) {
|
|
151
|
-
const toolPath = join(plugin.path, toolEntry);
|
|
152
|
-
if (existsSync(toolPath)) {
|
|
154
|
+
const toolPath = path.join(plugin.path, toolEntry);
|
|
155
|
+
if (fs.existsSync(toolPath)) {
|
|
153
156
|
paths.push(toolPath);
|
|
154
157
|
}
|
|
155
158
|
}
|
|
@@ -162,8 +165,8 @@ export function resolvePluginToolPaths(plugin: InstalledPlugin): string[] {
|
|
|
162
165
|
|
|
163
166
|
if (feat.tools) {
|
|
164
167
|
for (const toolEntry of feat.tools) {
|
|
165
|
-
const toolPath = join(plugin.path, toolEntry);
|
|
166
|
-
if (existsSync(toolPath)) {
|
|
168
|
+
const toolPath = path.join(plugin.path, toolEntry);
|
|
169
|
+
if (fs.existsSync(toolPath)) {
|
|
167
170
|
paths.push(toolPath);
|
|
168
171
|
}
|
|
169
172
|
}
|
|
@@ -184,8 +187,8 @@ export function resolvePluginHookPaths(plugin: InstalledPlugin): string[] {
|
|
|
184
187
|
|
|
185
188
|
// Base hooks entry (always included if exists)
|
|
186
189
|
if (manifest.hooks) {
|
|
187
|
-
const hookPath = join(plugin.path, manifest.hooks);
|
|
188
|
-
if (existsSync(hookPath)) {
|
|
190
|
+
const hookPath = path.join(plugin.path, manifest.hooks);
|
|
191
|
+
if (fs.existsSync(hookPath)) {
|
|
189
192
|
paths.push(hookPath);
|
|
190
193
|
}
|
|
191
194
|
}
|
|
@@ -199,8 +202,8 @@ export function resolvePluginHookPaths(plugin: InstalledPlugin): string[] {
|
|
|
199
202
|
|
|
200
203
|
if (feat.hooks) {
|
|
201
204
|
for (const hookEntry of feat.hooks) {
|
|
202
|
-
const hookPath = join(plugin.path, hookEntry);
|
|
203
|
-
if (existsSync(hookPath)) {
|
|
205
|
+
const hookPath = path.join(plugin.path, hookEntry);
|
|
206
|
+
if (fs.existsSync(hookPath)) {
|
|
204
207
|
paths.push(hookPath);
|
|
205
208
|
}
|
|
206
209
|
}
|
|
@@ -213,8 +216,8 @@ export function resolvePluginHookPaths(plugin: InstalledPlugin): string[] {
|
|
|
213
216
|
|
|
214
217
|
if (feat.hooks) {
|
|
215
218
|
for (const hookEntry of feat.hooks) {
|
|
216
|
-
const hookPath = join(plugin.path, hookEntry);
|
|
217
|
-
if (existsSync(hookPath)) {
|
|
219
|
+
const hookPath = path.join(plugin.path, hookEntry);
|
|
220
|
+
if (fs.existsSync(hookPath)) {
|
|
218
221
|
paths.push(hookPath);
|
|
219
222
|
}
|
|
220
223
|
}
|
|
@@ -236,8 +239,8 @@ export function resolvePluginCommandPaths(plugin: InstalledPlugin): string[] {
|
|
|
236
239
|
// Base commands (always included if exists)
|
|
237
240
|
if (manifest.commands) {
|
|
238
241
|
for (const cmdEntry of manifest.commands) {
|
|
239
|
-
const cmdPath = join(plugin.path, cmdEntry);
|
|
240
|
-
if (existsSync(cmdPath)) {
|
|
242
|
+
const cmdPath = path.join(plugin.path, cmdEntry);
|
|
243
|
+
if (fs.existsSync(cmdPath)) {
|
|
241
244
|
paths.push(cmdPath);
|
|
242
245
|
}
|
|
243
246
|
}
|
|
@@ -252,8 +255,8 @@ export function resolvePluginCommandPaths(plugin: InstalledPlugin): string[] {
|
|
|
252
255
|
|
|
253
256
|
if (feat.commands) {
|
|
254
257
|
for (const cmdEntry of feat.commands) {
|
|
255
|
-
const cmdPath = join(plugin.path, cmdEntry);
|
|
256
|
-
if (existsSync(cmdPath)) {
|
|
258
|
+
const cmdPath = path.join(plugin.path, cmdEntry);
|
|
259
|
+
if (fs.existsSync(cmdPath)) {
|
|
257
260
|
paths.push(cmdPath);
|
|
258
261
|
}
|
|
259
262
|
}
|
|
@@ -266,8 +269,8 @@ export function resolvePluginCommandPaths(plugin: InstalledPlugin): string[] {
|
|
|
266
269
|
|
|
267
270
|
if (feat.commands) {
|
|
268
271
|
for (const cmdEntry of feat.commands) {
|
|
269
|
-
const cmdPath = join(plugin.path, cmdEntry);
|
|
270
|
-
if (existsSync(cmdPath)) {
|
|
272
|
+
const cmdPath = path.join(plugin.path, cmdEntry);
|
|
273
|
+
if (fs.existsSync(cmdPath)) {
|
|
271
274
|
paths.push(cmdPath);
|
|
272
275
|
}
|
|
273
276
|
}
|
|
@@ -285,8 +288,8 @@ export function resolvePluginCommandPaths(plugin: InstalledPlugin): string[] {
|
|
|
285
288
|
/**
|
|
286
289
|
* Get all tool paths from all enabled plugins.
|
|
287
290
|
*/
|
|
288
|
-
export function getAllPluginToolPaths(cwd: string): string[] {
|
|
289
|
-
const plugins = getEnabledPlugins(cwd);
|
|
291
|
+
export async function getAllPluginToolPaths(cwd: string): Promise<string[]> {
|
|
292
|
+
const plugins = await getEnabledPlugins(cwd);
|
|
290
293
|
const paths: string[] = [];
|
|
291
294
|
|
|
292
295
|
for (const plugin of plugins) {
|
|
@@ -299,8 +302,8 @@ export function getAllPluginToolPaths(cwd: string): string[] {
|
|
|
299
302
|
/**
|
|
300
303
|
* Get all hook paths from all enabled plugins.
|
|
301
304
|
*/
|
|
302
|
-
export function getAllPluginHookPaths(cwd: string): string[] {
|
|
303
|
-
const plugins = getEnabledPlugins(cwd);
|
|
305
|
+
export async function getAllPluginHookPaths(cwd: string): Promise<string[]> {
|
|
306
|
+
const plugins = await getEnabledPlugins(cwd);
|
|
304
307
|
const paths: string[] = [];
|
|
305
308
|
|
|
306
309
|
for (const plugin of plugins) {
|
|
@@ -313,8 +316,8 @@ export function getAllPluginHookPaths(cwd: string): string[] {
|
|
|
313
316
|
/**
|
|
314
317
|
* Get all command paths from all enabled plugins.
|
|
315
318
|
*/
|
|
316
|
-
export function getAllPluginCommandPaths(cwd: string): string[] {
|
|
317
|
-
const plugins = getEnabledPlugins(cwd);
|
|
319
|
+
export async function getAllPluginCommandPaths(cwd: string): Promise<string[]> {
|
|
320
|
+
const plugins = await getEnabledPlugins(cwd);
|
|
318
321
|
const paths: string[] = [];
|
|
319
322
|
|
|
320
323
|
for (const plugin of plugins) {
|
|
@@ -328,9 +331,9 @@ export function getAllPluginCommandPaths(cwd: string): string[] {
|
|
|
328
331
|
* Get plugin settings for use in tool/hook contexts.
|
|
329
332
|
* Merges global settings with project overrides.
|
|
330
333
|
*/
|
|
331
|
-
export function getPluginSettings(pluginName: string, cwd: string): Record<string, unknown
|
|
332
|
-
const runtimeConfig = loadRuntimeConfig();
|
|
333
|
-
const projectOverrides = loadProjectOverrides(cwd);
|
|
334
|
+
export async function getPluginSettings(pluginName: string, cwd: string): Promise<Record<string, unknown>> {
|
|
335
|
+
const runtimeConfig = await loadRuntimeConfig();
|
|
336
|
+
const projectOverrides = await loadProjectOverrides(cwd);
|
|
334
337
|
|
|
335
338
|
const global = runtimeConfig.settings[pluginName] || {};
|
|
336
339
|
const project = projectOverrides.settings?.[pluginName] || {};
|