@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,6 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import { CONFIG_DIR_NAME, getConfigDirPaths } from "
|
|
1
|
+
import * as os from "node:os";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { CONFIG_DIR_NAME, getConfigDirPaths } from "../../config";
|
|
4
4
|
|
|
5
5
|
// =============================================================================
|
|
6
6
|
// Plugin Directory Paths
|
|
@@ -8,27 +8,27 @@ import { CONFIG_DIR_NAME, getConfigDirPaths } from "@oh-my-pi/pi-coding-agent/co
|
|
|
8
8
|
|
|
9
9
|
/** Root plugin directory: ~/.omp/plugins (not under agent/) */
|
|
10
10
|
export function getPluginsDir(): string {
|
|
11
|
-
return join(homedir(), CONFIG_DIR_NAME, "plugins");
|
|
11
|
+
return path.join(os.homedir(), CONFIG_DIR_NAME, "plugins");
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
/** Where npm installs packages: ~/.omp/plugins/node_modules */
|
|
15
15
|
export function getPluginsNodeModules(): string {
|
|
16
|
-
return join(getPluginsDir(), "node_modules");
|
|
16
|
+
return path.join(getPluginsDir(), "node_modules");
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/** Plugin manifest: ~/.omp/plugins/package.json */
|
|
20
20
|
export function getPluginsPackageJson(): string {
|
|
21
|
-
return join(getPluginsDir(), "package.json");
|
|
21
|
+
return path.join(getPluginsDir(), "package.json");
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
/** Plugin lock file: ~/.omp/plugins/omp-plugins.lock.json */
|
|
25
25
|
export function getPluginsLockfile(): string {
|
|
26
|
-
return join(getPluginsDir(), "omp-plugins.lock.json");
|
|
26
|
+
return path.join(getPluginsDir(), "omp-plugins.lock.json");
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/** Project-local plugin overrides: .omp/plugin-overrides.json (primary) */
|
|
30
30
|
export function getProjectPluginOverrides(cwd: string): string {
|
|
31
|
-
return join(cwd, CONFIG_DIR_NAME, "plugin-overrides.json");
|
|
31
|
+
return path.join(cwd, CONFIG_DIR_NAME, "plugin-overrides.json");
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
/** All possible project plugin override paths (primary + legacy) */
|
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import { basename, join } from "node:path";
|
|
4
|
-
import { skillCapability } from "@oh-my-pi/pi-coding-agent/capability/skill";
|
|
5
|
-
import type { SourceMeta } from "@oh-my-pi/pi-coding-agent/capability/types";
|
|
6
|
-
import type { SkillsSettings } from "@oh-my-pi/pi-coding-agent/config/settings-manager";
|
|
7
|
-
import type {
|
|
8
|
-
Skill as CapabilitySkill,
|
|
9
|
-
SkillFrontmatter as ImportedSkillFrontmatter,
|
|
10
|
-
} from "@oh-my-pi/pi-coding-agent/discovery";
|
|
11
|
-
import { loadCapability } from "@oh-my-pi/pi-coding-agent/discovery";
|
|
12
|
-
import { parseFrontmatter } from "@oh-my-pi/pi-coding-agent/utils/frontmatter";
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import * as path from "node:path";
|
|
13
3
|
import { logger } from "@oh-my-pi/pi-utils";
|
|
4
|
+
import { skillCapability } from "../capability/skill";
|
|
5
|
+
import type { SourceMeta } from "../capability/types";
|
|
6
|
+
import type { SkillsSettings } from "../config/settings-manager";
|
|
7
|
+
import type { Skill as CapabilitySkill, SkillFrontmatter as ImportedSkillFrontmatter } from "../discovery";
|
|
8
|
+
import { loadCapability } from "../discovery";
|
|
9
|
+
import { parseFrontmatter } from "../utils/frontmatter";
|
|
14
10
|
|
|
15
11
|
// Re-export SkillFrontmatter for backward compatibility
|
|
16
12
|
export type { ImportedSkillFrontmatter as SkillFrontmatter };
|
|
@@ -45,17 +41,16 @@ export interface LoadSkillsFromDirOptions {
|
|
|
45
41
|
/**
|
|
46
42
|
* Load skills from a directory recursively.
|
|
47
43
|
* Skills are directories containing a SKILL.md file with frontmatter including a description.
|
|
48
|
-
* @deprecated Use loadSync("skills") from discovery API instead
|
|
49
44
|
*/
|
|
50
|
-
export function loadSkillsFromDir(options: LoadSkillsFromDirOptions): LoadSkillsResult {
|
|
45
|
+
export async function loadSkillsFromDir(options: LoadSkillsFromDirOptions): Promise<LoadSkillsResult> {
|
|
51
46
|
const skills: Skill[] = [];
|
|
52
47
|
const warnings: SkillWarning[] = [];
|
|
53
48
|
const seenPaths = new Set<string>();
|
|
54
49
|
|
|
55
|
-
function addSkill(skillFile: string, skillDir: string, dirName: string) {
|
|
50
|
+
async function addSkill(skillFile: string, skillDir: string, dirName: string): Promise<void> {
|
|
56
51
|
if (seenPaths.has(skillFile)) return;
|
|
57
52
|
try {
|
|
58
|
-
const content =
|
|
53
|
+
const content = await fs.readFile(skillFile, "utf-8");
|
|
59
54
|
const { frontmatter } = parseFrontmatter(content, { source: skillFile });
|
|
60
55
|
const name = (frontmatter.name as string) || dirName;
|
|
61
56
|
const description = frontmatter.description as string;
|
|
@@ -75,26 +70,30 @@ export function loadSkillsFromDir(options: LoadSkillsFromDirOptions): LoadSkills
|
|
|
75
70
|
}
|
|
76
71
|
}
|
|
77
72
|
|
|
78
|
-
function scanDir(dir: string) {
|
|
73
|
+
async function scanDir(dir: string): Promise<void> {
|
|
79
74
|
try {
|
|
80
|
-
|
|
75
|
+
// First check if this directory itself is a skill
|
|
76
|
+
const selfSkillFile = path.join(dir, "SKILL.md");
|
|
77
|
+
try {
|
|
78
|
+
const s = await fs.stat(selfSkillFile);
|
|
79
|
+
if (s.isFile()) {
|
|
80
|
+
await addSkill(selfSkillFile, dir, path.basename(dir));
|
|
81
|
+
// This directory is a skill, don't recurse
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
} catch {
|
|
85
|
+
// No SKILL.md in this directory
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Recurse into subdirectories
|
|
89
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
90
|
+
|
|
81
91
|
for (const entry of entries) {
|
|
82
92
|
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
|
83
93
|
|
|
84
|
-
const fullPath = join(dir, entry.name);
|
|
94
|
+
const fullPath = path.join(dir, entry.name);
|
|
85
95
|
if (entry.isDirectory()) {
|
|
86
|
-
|
|
87
|
-
try {
|
|
88
|
-
const stat = statSync(skillFile);
|
|
89
|
-
if (stat.isFile()) {
|
|
90
|
-
addSkill(skillFile, fullPath, entry.name);
|
|
91
|
-
}
|
|
92
|
-
} catch {
|
|
93
|
-
// No SKILL.md in this directory
|
|
94
|
-
}
|
|
95
|
-
scanDir(fullPath);
|
|
96
|
-
} else if (entry.isFile() && entry.name === "SKILL.md") {
|
|
97
|
-
addSkill(fullPath, dir, basename(dir));
|
|
96
|
+
await scanDir(fullPath);
|
|
98
97
|
}
|
|
99
98
|
}
|
|
100
99
|
} catch (err) {
|
|
@@ -102,7 +101,7 @@ export function loadSkillsFromDir(options: LoadSkillsFromDirOptions): LoadSkills
|
|
|
102
101
|
}
|
|
103
102
|
}
|
|
104
103
|
|
|
105
|
-
scanDir(options.dir);
|
|
104
|
+
await scanDir(options.dir);
|
|
106
105
|
|
|
107
106
|
return { skills, warnings };
|
|
108
107
|
}
|
|
@@ -111,15 +110,15 @@ export function loadSkillsFromDir(options: LoadSkillsFromDirOptions): LoadSkills
|
|
|
111
110
|
* Scan a directory for SKILL.md files recursively.
|
|
112
111
|
* Used internally by loadSkills for custom directories.
|
|
113
112
|
*/
|
|
114
|
-
function scanDirectoryForSkills(dir: string): LoadSkillsResult {
|
|
113
|
+
async function scanDirectoryForSkills(dir: string): Promise<LoadSkillsResult> {
|
|
115
114
|
const skills: Skill[] = [];
|
|
116
115
|
const warnings: SkillWarning[] = [];
|
|
117
116
|
const seenPaths = new Set<string>();
|
|
118
117
|
|
|
119
|
-
function addSkill(skillFile: string, skillDir: string, dirName: string) {
|
|
118
|
+
async function addSkill(skillFile: string, skillDir: string, dirName: string): Promise<void> {
|
|
120
119
|
if (seenPaths.has(skillFile)) return;
|
|
121
120
|
try {
|
|
122
|
-
const content =
|
|
121
|
+
const content = await fs.readFile(skillFile, "utf-8");
|
|
123
122
|
const { frontmatter } = parseFrontmatter(content, { source: skillFile });
|
|
124
123
|
const name = (frontmatter.name as string) || dirName;
|
|
125
124
|
const description = frontmatter.description as string;
|
|
@@ -139,26 +138,30 @@ function scanDirectoryForSkills(dir: string): LoadSkillsResult {
|
|
|
139
138
|
}
|
|
140
139
|
}
|
|
141
140
|
|
|
142
|
-
function scanDir(currentDir: string) {
|
|
141
|
+
async function scanDir(currentDir: string): Promise<void> {
|
|
143
142
|
try {
|
|
144
|
-
|
|
143
|
+
// First check if this directory itself is a skill
|
|
144
|
+
const selfSkillFile = path.join(currentDir, "SKILL.md");
|
|
145
|
+
try {
|
|
146
|
+
const s = await fs.stat(selfSkillFile);
|
|
147
|
+
if (s.isFile()) {
|
|
148
|
+
await addSkill(selfSkillFile, currentDir, path.basename(currentDir));
|
|
149
|
+
// This directory is a skill, don't recurse
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
} catch {
|
|
153
|
+
// No SKILL.md in this directory
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Recurse into subdirectories
|
|
157
|
+
const entries = await fs.readdir(currentDir, { withFileTypes: true });
|
|
158
|
+
|
|
145
159
|
for (const entry of entries) {
|
|
146
160
|
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
|
147
161
|
|
|
148
|
-
const fullPath = join(currentDir, entry.name);
|
|
162
|
+
const fullPath = path.join(currentDir, entry.name);
|
|
149
163
|
if (entry.isDirectory()) {
|
|
150
|
-
|
|
151
|
-
try {
|
|
152
|
-
const stat = statSync(skillFile);
|
|
153
|
-
if (stat.isFile()) {
|
|
154
|
-
addSkill(skillFile, fullPath, entry.name);
|
|
155
|
-
}
|
|
156
|
-
} catch {
|
|
157
|
-
// No SKILL.md in this directory
|
|
158
|
-
}
|
|
159
|
-
scanDir(fullPath);
|
|
160
|
-
} else if (entry.isFile() && entry.name === "SKILL.md") {
|
|
161
|
-
addSkill(fullPath, currentDir, basename(currentDir));
|
|
164
|
+
await scanDir(fullPath);
|
|
162
165
|
}
|
|
163
166
|
}
|
|
164
167
|
} catch (err) {
|
|
@@ -166,7 +169,7 @@ function scanDirectoryForSkills(dir: string): LoadSkillsResult {
|
|
|
166
169
|
}
|
|
167
170
|
}
|
|
168
171
|
|
|
169
|
-
scanDir(dir);
|
|
172
|
+
await scanDir(dir);
|
|
170
173
|
|
|
171
174
|
return { skills, warnings };
|
|
172
175
|
}
|
|
@@ -221,17 +224,17 @@ export async function loadSkills(options: LoadSkillsOptions = {}): Promise<LoadS
|
|
|
221
224
|
// Check if skill name matches any of the include patterns
|
|
222
225
|
function matchesIncludePatterns(name: string): boolean {
|
|
223
226
|
if (includeSkills.length === 0) return true;
|
|
224
|
-
return includeSkills.some(
|
|
227
|
+
return includeSkills.some(pattern => new Bun.Glob(pattern).match(name));
|
|
225
228
|
}
|
|
226
229
|
|
|
227
230
|
// Check if skill name matches any of the ignore patterns
|
|
228
231
|
function matchesIgnorePatterns(name: string): boolean {
|
|
229
232
|
if (ignoredSkills.length === 0) return false;
|
|
230
|
-
return ignoredSkills.some(
|
|
233
|
+
return ignoredSkills.some(pattern => new Bun.Glob(pattern).match(name));
|
|
231
234
|
}
|
|
232
235
|
|
|
233
236
|
// Filter skills by source and patterns first
|
|
234
|
-
const filteredSkills = result.items.filter(
|
|
237
|
+
const filteredSkills = result.items.filter(capSkill => {
|
|
235
238
|
if (!isSourceEnabled(capSkill._source)) return false;
|
|
236
239
|
if (matchesIgnorePatterns(capSkill.name)) return false;
|
|
237
240
|
if (!matchesIncludePatterns(capSkill.name)) return false;
|
|
@@ -240,9 +243,9 @@ export async function loadSkills(options: LoadSkillsOptions = {}): Promise<LoadS
|
|
|
240
243
|
|
|
241
244
|
// Batch resolve all real paths in parallel
|
|
242
245
|
const realPaths = await Promise.all(
|
|
243
|
-
filteredSkills.map(async
|
|
246
|
+
filteredSkills.map(async capSkill => {
|
|
244
247
|
try {
|
|
245
|
-
return await realpath(capSkill.path);
|
|
248
|
+
return await fs.realpath(capSkill.path);
|
|
246
249
|
} catch {
|
|
247
250
|
return capSkill.path;
|
|
248
251
|
}
|
|
@@ -282,8 +285,8 @@ export async function loadSkills(options: LoadSkillsOptions = {}): Promise<LoadS
|
|
|
282
285
|
|
|
283
286
|
// Process custom directories - scan directly without using full provider system
|
|
284
287
|
const allCustomSkills: Array<{ skill: Skill; path: string }> = [];
|
|
285
|
-
|
|
286
|
-
|
|
288
|
+
const customScanResults = await Promise.all(customDirectories.map(dir => scanDirectoryForSkills(dir)));
|
|
289
|
+
for (const customSkills of customScanResults) {
|
|
287
290
|
for (const s of customSkills.skills) {
|
|
288
291
|
if (matchesIgnorePatterns(s.name)) continue;
|
|
289
292
|
if (!matchesIncludePatterns(s.name)) continue;
|
|
@@ -306,7 +309,7 @@ export async function loadSkills(options: LoadSkillsOptions = {}): Promise<LoadS
|
|
|
306
309
|
const customRealPaths = await Promise.all(
|
|
307
310
|
allCustomSkills.map(async ({ path }) => {
|
|
308
311
|
try {
|
|
309
|
-
return await realpath(path);
|
|
312
|
+
return await fs.realpath(path);
|
|
310
313
|
} catch {
|
|
311
314
|
return path;
|
|
312
315
|
}
|
|
@@ -332,6 +335,6 @@ export async function loadSkills(options: LoadSkillsOptions = {}): Promise<LoadS
|
|
|
332
335
|
|
|
333
336
|
return {
|
|
334
337
|
skills: Array.from(skillMap.values()),
|
|
335
|
-
warnings: [...result.warnings.map(
|
|
338
|
+
warnings: [...result.warnings.map(w => ({ skillPath: "", message: w })), ...collisionWarnings],
|
|
336
339
|
};
|
|
337
340
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { slashCommandCapability } from "
|
|
2
|
-
import { renderPromptTemplate } from "
|
|
3
|
-
import type { SlashCommand } from "
|
|
4
|
-
import { loadCapability } from "
|
|
5
|
-
import { EMBEDDED_COMMAND_TEMPLATES } from "
|
|
6
|
-
import { parseFrontmatter } from "
|
|
1
|
+
import { slashCommandCapability } from "../capability/slash-command";
|
|
2
|
+
import { renderPromptTemplate } from "../config/prompt-templates";
|
|
3
|
+
import type { SlashCommand } from "../discovery";
|
|
4
|
+
import { loadCapability } from "../discovery";
|
|
5
|
+
import { EMBEDDED_COMMAND_TEMPLATES } from "../task/commands";
|
|
6
|
+
import { parseFrontmatter } from "../utils/frontmatter";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Represents a custom slash command loaded from a file
|
|
@@ -29,7 +29,7 @@ function parseCommandTemplate(
|
|
|
29
29
|
// Get description from frontmatter or first non-empty line
|
|
30
30
|
let description = frontmatterDesc;
|
|
31
31
|
if (!description) {
|
|
32
|
-
const firstLine = body.split("\n").find(
|
|
32
|
+
const firstLine = body.split("\n").find(line => line.trim());
|
|
33
33
|
if (firstLine) {
|
|
34
34
|
description = firstLine.slice(0, 60);
|
|
35
35
|
if (firstLine.length > 60) description += "...";
|
|
@@ -114,7 +114,7 @@ export interface LoadSlashCommandsOptions {
|
|
|
114
114
|
export async function loadSlashCommands(options: LoadSlashCommandsOptions = {}): Promise<FileSlashCommand[]> {
|
|
115
115
|
const result = await loadCapability<SlashCommand>(slashCommandCapability.id, { cwd: options.cwd });
|
|
116
116
|
|
|
117
|
-
const fileCommands: FileSlashCommand[] = result.items.map(
|
|
117
|
+
const fileCommands: FileSlashCommand[] = result.items.map(cmd => {
|
|
118
118
|
const { description, body } = parseCommandTemplate(cmd.content, {
|
|
119
119
|
source: cmd.path ?? `slash-command:${cmd.name}`,
|
|
120
120
|
level: cmd.level === "native" ? "fatal" : "warn",
|
|
@@ -133,7 +133,7 @@ export async function loadSlashCommands(options: LoadSlashCommandsOptions = {}):
|
|
|
133
133
|
};
|
|
134
134
|
});
|
|
135
135
|
|
|
136
|
-
const seenNames = new Set(fileCommands.map(
|
|
136
|
+
const seenNames = new Set(fileCommands.map(cmd => cmd.name));
|
|
137
137
|
for (const cmd of EMBEDDED_SLASH_COMMANDS) {
|
|
138
138
|
const name = cmd.name.replace(/\.md$/, "");
|
|
139
139
|
if (seenNames.has(name)) continue;
|
|
@@ -165,7 +165,7 @@ export function expandSlashCommand(text: string, fileCommands: FileSlashCommand[
|
|
|
165
165
|
const commandName = spaceIndex === -1 ? text.slice(1) : text.slice(1, spaceIndex);
|
|
166
166
|
const argsString = spaceIndex === -1 ? "" : text.slice(spaceIndex + 1);
|
|
167
167
|
|
|
168
|
-
const fileCommand = fileCommands.find(
|
|
168
|
+
const fileCommand = fileCommands.find(cmd => cmd.name === commandName);
|
|
169
169
|
if (fileCommand) {
|
|
170
170
|
const args = parseCommandArgs(argsString);
|
|
171
171
|
const argsText = args.join(" ");
|
package/src/index.ts
CHANGED
|
@@ -3,52 +3,6 @@
|
|
|
3
3
|
// TypeBox helper for string enums (convenience for custom tools)
|
|
4
4
|
// Re-export from pi-ai which uses the correct enum-based schema format
|
|
5
5
|
export { StringEnum } from "@oh-my-pi/pi-ai";
|
|
6
|
-
export type { FileDiagnosticsResult } from "@oh-my-pi/pi-coding-agent/lsp";
|
|
7
|
-
// UI components for extensions
|
|
8
|
-
export {
|
|
9
|
-
ArminComponent,
|
|
10
|
-
AssistantMessageComponent,
|
|
11
|
-
BashExecutionComponent,
|
|
12
|
-
BorderedLoader,
|
|
13
|
-
BranchSummaryMessageComponent,
|
|
14
|
-
CompactionSummaryMessageComponent,
|
|
15
|
-
CustomEditor,
|
|
16
|
-
CustomMessageComponent,
|
|
17
|
-
DynamicBorder,
|
|
18
|
-
FooterComponent,
|
|
19
|
-
HookEditorComponent as ExtensionEditorComponent,
|
|
20
|
-
HookInputComponent as ExtensionInputComponent,
|
|
21
|
-
HookSelectorComponent as ExtensionSelectorComponent,
|
|
22
|
-
LoginDialogComponent,
|
|
23
|
-
ModelSelectorComponent,
|
|
24
|
-
OAuthSelectorComponent,
|
|
25
|
-
type RenderDiffOptions,
|
|
26
|
-
renderDiff,
|
|
27
|
-
SessionSelectorComponent,
|
|
28
|
-
type SettingsCallbacks,
|
|
29
|
-
SettingsSelectorComponent,
|
|
30
|
-
ShowImagesSelectorComponent,
|
|
31
|
-
ThemeSelectorComponent,
|
|
32
|
-
ThinkingSelectorComponent,
|
|
33
|
-
ToolExecutionComponent,
|
|
34
|
-
type ToolExecutionOptions,
|
|
35
|
-
TreeSelectorComponent,
|
|
36
|
-
truncateToVisualLines,
|
|
37
|
-
UserMessageComponent,
|
|
38
|
-
UserMessageSelectorComponent,
|
|
39
|
-
type VisualTruncateResult,
|
|
40
|
-
} from "@oh-my-pi/pi-coding-agent/modes/components";
|
|
41
|
-
// Theme utilities for custom tools
|
|
42
|
-
export {
|
|
43
|
-
getLanguageFromPath,
|
|
44
|
-
getMarkdownTheme,
|
|
45
|
-
getSelectListTheme,
|
|
46
|
-
getSettingsListTheme,
|
|
47
|
-
highlightCode,
|
|
48
|
-
initTheme,
|
|
49
|
-
Theme,
|
|
50
|
-
type ThemeColor,
|
|
51
|
-
} from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
|
|
52
6
|
// Re-export TUI components for custom tool rendering
|
|
53
7
|
export { Container, Markdown, Spacer, Text } from "@oh-my-pi/pi-tui";
|
|
54
8
|
// Logging
|
|
@@ -150,6 +104,7 @@ export {
|
|
|
150
104
|
} from "./extensibility/skills";
|
|
151
105
|
// Slash commands
|
|
152
106
|
export { type FileSlashCommand, loadSlashCommands as discoverSlashCommands } from "./extensibility/slash-commands";
|
|
107
|
+
export type { FileDiagnosticsResult } from "./lsp";
|
|
153
108
|
// Main entry point
|
|
154
109
|
export { main } from "./main";
|
|
155
110
|
// Run modes for programmatic SDK usage
|
|
@@ -163,6 +118,51 @@ export {
|
|
|
163
118
|
runPrintMode,
|
|
164
119
|
runRpcMode,
|
|
165
120
|
} from "./modes";
|
|
121
|
+
// UI components for extensions
|
|
122
|
+
export {
|
|
123
|
+
ArminComponent,
|
|
124
|
+
AssistantMessageComponent,
|
|
125
|
+
BashExecutionComponent,
|
|
126
|
+
BorderedLoader,
|
|
127
|
+
BranchSummaryMessageComponent,
|
|
128
|
+
CompactionSummaryMessageComponent,
|
|
129
|
+
CustomEditor,
|
|
130
|
+
CustomMessageComponent,
|
|
131
|
+
DynamicBorder,
|
|
132
|
+
FooterComponent,
|
|
133
|
+
HookEditorComponent as ExtensionEditorComponent,
|
|
134
|
+
HookInputComponent as ExtensionInputComponent,
|
|
135
|
+
HookSelectorComponent as ExtensionSelectorComponent,
|
|
136
|
+
LoginDialogComponent,
|
|
137
|
+
ModelSelectorComponent,
|
|
138
|
+
OAuthSelectorComponent,
|
|
139
|
+
type RenderDiffOptions,
|
|
140
|
+
renderDiff,
|
|
141
|
+
SessionSelectorComponent,
|
|
142
|
+
type SettingsCallbacks,
|
|
143
|
+
SettingsSelectorComponent,
|
|
144
|
+
ShowImagesSelectorComponent,
|
|
145
|
+
ThemeSelectorComponent,
|
|
146
|
+
ThinkingSelectorComponent,
|
|
147
|
+
ToolExecutionComponent,
|
|
148
|
+
type ToolExecutionOptions,
|
|
149
|
+
TreeSelectorComponent,
|
|
150
|
+
truncateToVisualLines,
|
|
151
|
+
UserMessageComponent,
|
|
152
|
+
UserMessageSelectorComponent,
|
|
153
|
+
type VisualTruncateResult,
|
|
154
|
+
} from "./modes/components";
|
|
155
|
+
// Theme utilities for custom tools
|
|
156
|
+
export {
|
|
157
|
+
getLanguageFromPath,
|
|
158
|
+
getMarkdownTheme,
|
|
159
|
+
getSelectListTheme,
|
|
160
|
+
getSettingsListTheme,
|
|
161
|
+
highlightCode,
|
|
162
|
+
initTheme,
|
|
163
|
+
Theme,
|
|
164
|
+
type ThemeColor,
|
|
165
|
+
} from "./modes/theme/theme";
|
|
166
166
|
// SDK for programmatic usage
|
|
167
167
|
export {
|
|
168
168
|
// Factory
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
* - agent://<id>/<path> - JSON extraction via path form
|
|
9
9
|
* - agent://<id>?q=<query> - JSON extraction via query form
|
|
10
10
|
*/
|
|
11
|
-
|
|
12
|
-
import * as fs from "node:fs";
|
|
11
|
+
import * as fs from "node:fs/promises";
|
|
13
12
|
import * as path from "node:path";
|
|
13
|
+
import { isEnoent } from "@oh-my-pi/pi-utils";
|
|
14
14
|
import { applyQuery, pathToQuery } from "./json-query";
|
|
15
15
|
import type { InternalResource, InternalUrl, ProtocolHandler } from "./types";
|
|
16
16
|
|
|
@@ -25,10 +25,10 @@ export interface AgentProtocolOptions {
|
|
|
25
25
|
/**
|
|
26
26
|
* List available output IDs in artifacts directory.
|
|
27
27
|
*/
|
|
28
|
-
function listAvailableOutputs(artifactsDir: string): string[] {
|
|
28
|
+
async function listAvailableOutputs(artifactsDir: string): Promise<string[]> {
|
|
29
29
|
try {
|
|
30
|
-
const files = fs.
|
|
31
|
-
return files.filter(
|
|
30
|
+
const files = await fs.readdir(artifactsDir);
|
|
31
|
+
return files.filter(f => f.endsWith(".md")).map(f => f.replace(".md", ""));
|
|
32
32
|
} catch {
|
|
33
33
|
return [];
|
|
34
34
|
}
|
|
@@ -51,8 +51,13 @@ export class AgentProtocolHandler implements ProtocolHandler {
|
|
|
51
51
|
throw new Error("No session - agent outputs unavailable");
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
try {
|
|
55
|
+
await fs.stat(artifactsDir);
|
|
56
|
+
} catch (err) {
|
|
57
|
+
if (isEnoent(err)) {
|
|
58
|
+
throw new Error("No artifacts directory found");
|
|
59
|
+
}
|
|
60
|
+
throw err;
|
|
56
61
|
}
|
|
57
62
|
|
|
58
63
|
// Extract output ID from host
|
|
@@ -73,10 +78,15 @@ export class AgentProtocolHandler implements ProtocolHandler {
|
|
|
73
78
|
|
|
74
79
|
// Load the output file
|
|
75
80
|
const outputPath = path.join(artifactsDir, `${outputId}.md`);
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
81
|
+
try {
|
|
82
|
+
await fs.stat(outputPath);
|
|
83
|
+
} catch (err) {
|
|
84
|
+
if (isEnoent(err)) {
|
|
85
|
+
const available = await listAvailableOutputs(artifactsDir);
|
|
86
|
+
const availableStr = available.length > 0 ? available.join(", ") : "none";
|
|
87
|
+
throw new Error(`Not found: ${outputId}\nAvailable: ${availableStr}`);
|
|
88
|
+
}
|
|
89
|
+
throw err;
|
|
80
90
|
}
|
|
81
91
|
|
|
82
92
|
const rawContent = await Bun.file(outputPath).text();
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Pagination is handled by the read tool via offset/limit parameters.
|
|
11
11
|
*/
|
|
12
|
-
|
|
13
|
-
import * as fs from "node:fs";
|
|
12
|
+
import * as fs from "node:fs/promises";
|
|
14
13
|
import * as path from "node:path";
|
|
14
|
+
import { isEnoent } from "@oh-my-pi/pi-utils";
|
|
15
15
|
import type { InternalResource, InternalUrl, ProtocolHandler } from "./types";
|
|
16
16
|
|
|
17
17
|
export interface ArtifactProtocolOptions {
|
|
@@ -24,12 +24,12 @@ export interface ArtifactProtocolOptions {
|
|
|
24
24
|
/**
|
|
25
25
|
* List available artifact IDs in the directory.
|
|
26
26
|
*/
|
|
27
|
-
function listAvailableArtifacts(artifactsDir: string): string[] {
|
|
27
|
+
async function listAvailableArtifacts(artifactsDir: string): Promise<string[]> {
|
|
28
28
|
try {
|
|
29
|
-
const files = fs.
|
|
29
|
+
const files = await fs.readdir(artifactsDir);
|
|
30
30
|
return files
|
|
31
|
-
.filter(
|
|
32
|
-
.map(
|
|
31
|
+
.filter(f => /^\d+\./.test(f))
|
|
32
|
+
.map(f => f.split(".")[0])
|
|
33
33
|
.sort((a, b) => Number(a) - Number(b));
|
|
34
34
|
} catch {
|
|
35
35
|
return [];
|
|
@@ -64,17 +64,21 @@ export class ArtifactProtocolHandler implements ProtocolHandler {
|
|
|
64
64
|
throw new Error(`artifact:// ID must be numeric, got: ${id}`);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
// Check directory exists
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
// Check directory exists and find file matching ID prefix
|
|
68
|
+
let files: string[];
|
|
69
|
+
try {
|
|
70
|
+
files = await fs.readdir(artifactsDir);
|
|
71
|
+
} catch (err) {
|
|
72
|
+
if (isEnoent(err)) {
|
|
73
|
+
throw new Error("No artifacts directory found");
|
|
74
|
+
}
|
|
75
|
+
throw err;
|
|
70
76
|
}
|
|
71
77
|
|
|
72
|
-
|
|
73
|
-
const files = fs.readdirSync(artifactsDir);
|
|
74
|
-
const match = files.find((f) => f.startsWith(`${id}.`));
|
|
78
|
+
const match = files.find(f => f.startsWith(`${id}.`));
|
|
75
79
|
|
|
76
80
|
if (!match) {
|
|
77
|
-
const available = listAvailableArtifacts(artifactsDir);
|
|
81
|
+
const available = await listAvailableArtifacts(artifactsDir);
|
|
78
82
|
const availableStr = available.length > 0 ? available.join(", ") : "none";
|
|
79
83
|
throw new Error(`Artifact ${id} not found. Available: ${availableStr}`);
|
|
80
84
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Internal URL router for resolving agent:// and skill:// URLs.
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
4
|
import type { InternalResource, InternalUrl, ProtocolHandler } from "./types";
|
|
6
5
|
|
|
7
6
|
/**
|
|
@@ -59,7 +58,7 @@ export class InternalUrlRouter {
|
|
|
59
58
|
|
|
60
59
|
if (!handler) {
|
|
61
60
|
const available = Array.from(this.handlers.keys())
|
|
62
|
-
.map(
|
|
61
|
+
.map(s => `${s}://`)
|
|
63
62
|
.join(", ");
|
|
64
63
|
throw new Error(`Unknown protocol: ${scheme}://\nSupported: ${available || "none"}`);
|
|
65
64
|
}
|
|
@@ -6,8 +6,7 @@
|
|
|
6
6
|
* URL forms:
|
|
7
7
|
* - rule://<name> - Reads rule content
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
|
-
import type { Rule } from "@oh-my-pi/pi-coding-agent/capability/rule";
|
|
9
|
+
import type { Rule } from "../capability/rule";
|
|
11
10
|
import type { InternalResource, InternalUrl, ProtocolHandler } from "./types";
|
|
12
11
|
|
|
13
12
|
export interface RuleProtocolOptions {
|
|
@@ -37,9 +36,9 @@ export class RuleProtocolHandler implements ProtocolHandler {
|
|
|
37
36
|
}
|
|
38
37
|
|
|
39
38
|
// Find the rule
|
|
40
|
-
const rule = rules.find(
|
|
39
|
+
const rule = rules.find(r => r.name === ruleName);
|
|
41
40
|
if (!rule) {
|
|
42
|
-
const available = rules.map(
|
|
41
|
+
const available = rules.map(r => r.name);
|
|
43
42
|
const availableStr = available.length > 0 ? available.join(", ") : "none";
|
|
44
43
|
throw new Error(`Unknown rule: ${ruleName}\nAvailable: ${availableStr}`);
|
|
45
44
|
}
|
|
@@ -7,9 +7,8 @@
|
|
|
7
7
|
* - skill://<name> - Reads SKILL.md
|
|
8
8
|
* - skill://<name>/<path> - Reads relative path within skill's baseDir
|
|
9
9
|
*/
|
|
10
|
-
|
|
11
10
|
import * as path from "node:path";
|
|
12
|
-
import type { Skill } from "
|
|
11
|
+
import type { Skill } from "../extensibility/skills";
|
|
13
12
|
import type { InternalResource, InternalUrl, ProtocolHandler } from "./types";
|
|
14
13
|
|
|
15
14
|
export interface SkillProtocolOptions {
|
|
@@ -62,9 +61,9 @@ export class SkillProtocolHandler implements ProtocolHandler {
|
|
|
62
61
|
}
|
|
63
62
|
|
|
64
63
|
// Find the skill
|
|
65
|
-
const skill = skills.find(
|
|
64
|
+
const skill = skills.find(s => s.name === skillName);
|
|
66
65
|
if (!skill) {
|
|
67
|
-
const available = skills.map(
|
|
66
|
+
const available = skills.map(s => s.name);
|
|
68
67
|
const availableStr = available.length > 0 ? available.join(", ") : "none";
|
|
69
68
|
throw new Error(`Unknown skill: ${skillName}\nAvailable: ${availableStr}`);
|
|
70
69
|
}
|