@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
package/src/cli/list-models.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* List available models with optional fuzzy search
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
4
|
import type { Api, Model } from "@oh-my-pi/pi-ai";
|
|
6
|
-
import type { ModelRegistry } from "
|
|
7
|
-
import { fuzzyFilter } from "
|
|
5
|
+
import type { ModelRegistry } from "../config/model-registry";
|
|
6
|
+
import { fuzzyFilter } from "../utils/fuzzy";
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* Format a number as human-readable (e.g., 200000 -> "200K", 1000000 -> "1M")
|
|
@@ -35,7 +34,7 @@ export async function listModels(modelRegistry: ModelRegistry, searchPattern?: s
|
|
|
35
34
|
// Apply fuzzy filter if search pattern provided
|
|
36
35
|
let filteredModels: Model<Api>[] = models;
|
|
37
36
|
if (searchPattern) {
|
|
38
|
-
filteredModels = fuzzyFilter(models, searchPattern,
|
|
37
|
+
filteredModels = fuzzyFilter(models, searchPattern, m => `${m.provider} ${m.id}`);
|
|
39
38
|
}
|
|
40
39
|
|
|
41
40
|
if (filteredModels.length === 0) {
|
|
@@ -51,7 +50,7 @@ export async function listModels(modelRegistry: ModelRegistry, searchPattern?: s
|
|
|
51
50
|
});
|
|
52
51
|
|
|
53
52
|
// Calculate column widths
|
|
54
|
-
const rows = filteredModels.map(
|
|
53
|
+
const rows = filteredModels.map(m => ({
|
|
55
54
|
provider: m.provider,
|
|
56
55
|
model: m.id,
|
|
57
56
|
context: formatTokenCount(m.contextWindow),
|
|
@@ -70,12 +69,12 @@ export async function listModels(modelRegistry: ModelRegistry, searchPattern?: s
|
|
|
70
69
|
};
|
|
71
70
|
|
|
72
71
|
const widths = {
|
|
73
|
-
provider: Math.max(headers.provider.length, ...rows.map(
|
|
74
|
-
model: Math.max(headers.model.length, ...rows.map(
|
|
75
|
-
context: Math.max(headers.context.length, ...rows.map(
|
|
76
|
-
maxOut: Math.max(headers.maxOut.length, ...rows.map(
|
|
77
|
-
thinking: Math.max(headers.thinking.length, ...rows.map(
|
|
78
|
-
images: Math.max(headers.images.length, ...rows.map(
|
|
72
|
+
provider: Math.max(headers.provider.length, ...rows.map(r => r.provider.length)),
|
|
73
|
+
model: Math.max(headers.model.length, ...rows.map(r => r.model.length)),
|
|
74
|
+
context: Math.max(headers.context.length, ...rows.map(r => r.context.length)),
|
|
75
|
+
maxOut: Math.max(headers.maxOut.length, ...rows.map(r => r.maxOut.length)),
|
|
76
|
+
thinking: Math.max(headers.thinking.length, ...rows.map(r => r.thinking.length)),
|
|
77
|
+
images: Math.max(headers.images.length, ...rows.map(r => r.images.length)),
|
|
79
78
|
};
|
|
80
79
|
|
|
81
80
|
// Print header
|
package/src/cli/plugin-cli.ts
CHANGED
|
@@ -3,11 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Handles `omp plugin <command>` subcommands for plugin lifecycle management.
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
import { APP_NAME } from "@oh-my-pi/pi-coding-agent/config";
|
|
8
|
-
import { PluginManager, parseSettingValue, validateSetting } from "@oh-my-pi/pi-coding-agent/extensibility/plugins";
|
|
9
|
-
import { theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
|
|
10
6
|
import chalk from "chalk";
|
|
7
|
+
import { APP_NAME } from "../config";
|
|
8
|
+
import { PluginManager, parseSettingValue, validateSetting } from "../extensibility/plugins";
|
|
9
|
+
import { theme } from "../modes/theme/theme";
|
|
11
10
|
|
|
12
11
|
// =============================================================================
|
|
13
12
|
// Types
|
|
@@ -247,7 +246,7 @@ async function handleList(manager: PluginManager, flags: { json?: boolean }): Pr
|
|
|
247
246
|
if (availableFeatures.length > 0) {
|
|
248
247
|
const enabledSet = new Set(plugin.enabledFeatures ?? []);
|
|
249
248
|
const featureDisplay = availableFeatures
|
|
250
|
-
.map(
|
|
249
|
+
.map(f => (enabledSet.has(f) ? chalk.green(f) : chalk.dim(f)))
|
|
251
250
|
.join(", ");
|
|
252
251
|
console.log(chalk.dim(` Available: [${featureDisplay}]`));
|
|
253
252
|
}
|
|
@@ -298,10 +297,10 @@ async function handleDoctor(manager: PluginManager, flags: { json?: boolean; fix
|
|
|
298
297
|
}
|
|
299
298
|
}
|
|
300
299
|
|
|
301
|
-
const errors = checks.filter(
|
|
302
|
-
const warnings = checks.filter(
|
|
303
|
-
const ok = checks.filter(
|
|
304
|
-
const fixed = checks.filter(
|
|
300
|
+
const errors = checks.filter(c => c.status === "error" && !c.fixed).length;
|
|
301
|
+
const warnings = checks.filter(c => c.status === "warning" && !c.fixed).length;
|
|
302
|
+
const ok = checks.filter(c => c.status === "ok").length;
|
|
303
|
+
const fixed = checks.filter(c => c.fixed).length;
|
|
305
304
|
|
|
306
305
|
console.log("");
|
|
307
306
|
console.log(`Summary: ${ok} ok, ${warnings} warnings, ${errors} errors${fixed > 0 ? `, ${fixed} fixed` : ""}`);
|
|
@@ -328,7 +327,7 @@ async function handleFeatures(
|
|
|
328
327
|
|
|
329
328
|
const pluginName = args[0];
|
|
330
329
|
const plugins = await manager.list();
|
|
331
|
-
const plugin = plugins.find(
|
|
330
|
+
const plugin = plugins.find(p => p.name === pluginName);
|
|
332
331
|
|
|
333
332
|
if (!plugin) {
|
|
334
333
|
console.error(chalk.red(`Plugin "${pluginName}" not found`));
|
|
@@ -337,21 +336,21 @@ async function handleFeatures(
|
|
|
337
336
|
|
|
338
337
|
// Handle modifications
|
|
339
338
|
if (flags.enable || flags.disable || flags.set) {
|
|
340
|
-
let currentFeatures = new Set(manager.getEnabledFeatures(pluginName) ?? []);
|
|
339
|
+
let currentFeatures = new Set((await manager.getEnabledFeatures(pluginName)) ?? []);
|
|
341
340
|
|
|
342
341
|
if (flags.set) {
|
|
343
342
|
// --set replaces all features
|
|
344
343
|
currentFeatures = new Set(
|
|
345
344
|
flags.set
|
|
346
345
|
.split(",")
|
|
347
|
-
.map(
|
|
346
|
+
.map(f => f.trim())
|
|
348
347
|
.filter(Boolean),
|
|
349
348
|
);
|
|
350
349
|
} else {
|
|
351
350
|
if (flags.enable) {
|
|
352
351
|
for (const f of flags.enable
|
|
353
352
|
.split(",")
|
|
354
|
-
.map(
|
|
353
|
+
.map(f => f.trim())
|
|
355
354
|
.filter(Boolean)) {
|
|
356
355
|
currentFeatures.add(f);
|
|
357
356
|
}
|
|
@@ -359,7 +358,7 @@ async function handleFeatures(
|
|
|
359
358
|
if (flags.disable) {
|
|
360
359
|
for (const f of flags.disable
|
|
361
360
|
.split(",")
|
|
362
|
-
.map(
|
|
361
|
+
.map(f => f.trim())
|
|
363
362
|
.filter(Boolean)) {
|
|
364
363
|
currentFeatures.delete(f);
|
|
365
364
|
}
|
|
@@ -371,7 +370,7 @@ async function handleFeatures(
|
|
|
371
370
|
}
|
|
372
371
|
|
|
373
372
|
// Display current state
|
|
374
|
-
const updatedFeatures = manager.getEnabledFeatures(pluginName);
|
|
373
|
+
const updatedFeatures = await manager.getEnabledFeatures(pluginName);
|
|
375
374
|
|
|
376
375
|
if (flags.json) {
|
|
377
376
|
console.log(
|
|
@@ -433,7 +432,7 @@ async function handleConfig(
|
|
|
433
432
|
}
|
|
434
433
|
|
|
435
434
|
const plugins = await manager.list();
|
|
436
|
-
const plugin = plugins.find(
|
|
435
|
+
const plugin = plugins.find(p => p.name === pluginName);
|
|
437
436
|
|
|
438
437
|
if (!plugin) {
|
|
439
438
|
console.error(chalk.red(`Plugin "${pluginName}" not found`));
|
|
@@ -442,7 +441,7 @@ async function handleConfig(
|
|
|
442
441
|
|
|
443
442
|
switch (subcommand) {
|
|
444
443
|
case "list": {
|
|
445
|
-
const settings = manager.getPluginSettings(pluginName);
|
|
444
|
+
const settings = await manager.getPluginSettings(pluginName);
|
|
446
445
|
const schema = plugin.manifest.settings || {};
|
|
447
446
|
|
|
448
447
|
if (flags.json) {
|
|
@@ -477,7 +476,7 @@ async function handleConfig(
|
|
|
477
476
|
process.exit(1);
|
|
478
477
|
}
|
|
479
478
|
|
|
480
|
-
const settings = manager.getPluginSettings(pluginName);
|
|
479
|
+
const settings = await manager.getPluginSettings(pluginName);
|
|
481
480
|
const schema = plugin.manifest.settings?.[key];
|
|
482
481
|
const value = settings[key] ?? schema?.default;
|
|
483
482
|
|
|
@@ -512,7 +511,7 @@ async function handleConfig(
|
|
|
512
511
|
}
|
|
513
512
|
}
|
|
514
513
|
|
|
515
|
-
manager.setPluginSetting(pluginName, key, value);
|
|
514
|
+
await manager.setPluginSetting(pluginName, key, value);
|
|
516
515
|
console.log(chalk.green(`${theme.status.success} Set ${key}`));
|
|
517
516
|
break;
|
|
518
517
|
}
|
|
@@ -523,7 +522,7 @@ async function handleConfig(
|
|
|
523
522
|
process.exit(1);
|
|
524
523
|
}
|
|
525
524
|
|
|
526
|
-
manager.deletePluginSetting(pluginName, key);
|
|
525
|
+
await manager.deletePluginSetting(pluginName, key);
|
|
527
526
|
console.log(chalk.green(`${theme.status.success} Deleted ${key}`));
|
|
528
527
|
break;
|
|
529
528
|
}
|
|
@@ -540,7 +539,7 @@ async function handleConfigValidate(manager: PluginManager, flags: { json?: bool
|
|
|
540
539
|
const results: Array<{ plugin: string; key: string; error: string }> = [];
|
|
541
540
|
|
|
542
541
|
for (const plugin of plugins) {
|
|
543
|
-
const settings = manager.getPluginSettings(plugin.name);
|
|
542
|
+
const settings = await manager.getPluginSettings(plugin.name);
|
|
544
543
|
const schema = plugin.manifest.settings || {};
|
|
545
544
|
|
|
546
545
|
for (const [key, s] of Object.entries(schema)) {
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* TUI session selector for --resume flag
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
|
-
import { SessionSelectorComponent } from "@oh-my-pi/pi-coding-agent/modes/components/session-selector";
|
|
6
|
-
import type { SessionInfo } from "@oh-my-pi/pi-coding-agent/session/session-manager";
|
|
7
4
|
import { ProcessTerminal, TUI } from "@oh-my-pi/pi-tui";
|
|
5
|
+
import { SessionSelectorComponent } from "../modes/components/session-selector";
|
|
6
|
+
import type { SessionInfo } from "../session/session-manager";
|
|
8
7
|
|
|
9
8
|
/** Show TUI session selector and return selected session path or null if cancelled */
|
|
10
9
|
export async function selectSession(sessions: SessionInfo[]): Promise<string | null> {
|
package/src/cli/setup-cli.ts
CHANGED
|
@@ -3,11 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Handles `omp setup <component>` to install dependencies for optional features.
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
import { APP_NAME } from "@oh-my-pi/pi-coding-agent/config";
|
|
8
|
-
import { theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
|
|
9
6
|
import { $ } from "bun";
|
|
10
7
|
import chalk from "chalk";
|
|
8
|
+
import { APP_NAME } from "../config";
|
|
9
|
+
import { theme } from "../modes/theme/theme";
|
|
11
10
|
|
|
12
11
|
export type SetupComponent = "python";
|
|
13
12
|
|
package/src/cli/stats-cli.ts
CHANGED
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Handles `omp stats` subcommand for viewing AI usage statistics.
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
import { APP_NAME } from "@oh-my-pi/pi-coding-agent/config";
|
|
8
6
|
import chalk from "chalk";
|
|
7
|
+
import { APP_NAME } from "../config";
|
|
9
8
|
|
|
10
9
|
// =============================================================================
|
|
11
10
|
// Types
|
|
@@ -106,7 +105,7 @@ export async function runStatsCommand(cmd: StatsCommandArgs): Promise<void> {
|
|
|
106
105
|
}
|
|
107
106
|
|
|
108
107
|
// Start the dashboard server
|
|
109
|
-
const { port } = startServer(cmd.port);
|
|
108
|
+
const { port } = await startServer(cmd.port);
|
|
110
109
|
console.log(chalk.green(`Dashboard available at: http://localhost:${port}`));
|
|
111
110
|
console.log("Press Ctrl+C to stop\n");
|
|
112
111
|
|
package/src/cli/update-cli.ts
CHANGED
|
@@ -4,15 +4,15 @@
|
|
|
4
4
|
* Handles `omp update` to check for and install updates.
|
|
5
5
|
* Uses bun if available, otherwise downloads binary from GitHub releases.
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
7
|
import { execSync, spawnSync } from "node:child_process";
|
|
9
|
-
import
|
|
10
|
-
import
|
|
8
|
+
import * as fs from "node:fs";
|
|
9
|
+
import * as path from "node:path";
|
|
11
10
|
import { Readable } from "node:stream";
|
|
12
11
|
import { pipeline } from "node:stream/promises";
|
|
13
|
-
import {
|
|
14
|
-
import { theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
|
|
12
|
+
import { isEnoent } from "@oh-my-pi/pi-utils";
|
|
15
13
|
import chalk from "chalk";
|
|
14
|
+
import { APP_NAME, VERSION } from "../config";
|
|
15
|
+
import { theme } from "../modes/theme/theme";
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Detect if we're running as a Bun compiled binary.
|
|
@@ -73,7 +73,7 @@ async function getLatestRelease(): Promise<ReleaseInfo> {
|
|
|
73
73
|
return {
|
|
74
74
|
tag: data.tag_name,
|
|
75
75
|
version: data.tag_name.replace(/^v/, ""),
|
|
76
|
-
assets: data.assets.map(
|
|
76
|
+
assets: data.assets.map(a => ({ name: a.name, url: a.browser_download_url })),
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
79
|
|
|
@@ -154,14 +154,14 @@ async function updateViaBun(): Promise<void> {
|
|
|
154
154
|
*/
|
|
155
155
|
async function updateViaBinary(release: ReleaseInfo): Promise<void> {
|
|
156
156
|
const binaryName = getBinaryName();
|
|
157
|
-
const asset = release.assets.find(
|
|
157
|
+
const asset = release.assets.find(a => a.name === binaryName);
|
|
158
158
|
|
|
159
159
|
if (!asset) {
|
|
160
160
|
throw new Error(`No binary found for ${binaryName}`);
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
const execPath = process.execPath;
|
|
164
|
-
const _execDir = dirname(execPath);
|
|
164
|
+
const _execDir = path.dirname(execPath);
|
|
165
165
|
const tempPath = `${execPath}.new`;
|
|
166
166
|
const backupPath = `${execPath}.bak`;
|
|
167
167
|
|
|
@@ -173,7 +173,7 @@ async function updateViaBinary(release: ReleaseInfo): Promise<void> {
|
|
|
173
173
|
throw new Error(`Download failed: ${response.statusText}`);
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
-
const fileStream = createWriteStream(tempPath, { mode: 0o755 });
|
|
176
|
+
const fileStream = fs.createWriteStream(tempPath, { mode: 0o755 });
|
|
177
177
|
const nodeStream = Readable.fromWeb(response.body as import("stream/web").ReadableStream);
|
|
178
178
|
await pipeline(nodeStream, fileStream);
|
|
179
179
|
|
|
@@ -181,27 +181,30 @@ async function updateViaBinary(release: ReleaseInfo): Promise<void> {
|
|
|
181
181
|
console.log(chalk.dim("Installing update..."));
|
|
182
182
|
|
|
183
183
|
try {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
184
|
+
try {
|
|
185
|
+
await fs.promises.unlink(backupPath);
|
|
186
|
+
} catch (err) {
|
|
187
|
+
if (!isEnoent(err)) throw err;
|
|
187
188
|
}
|
|
188
|
-
|
|
189
|
+
await fs.promises.rename(execPath, backupPath);
|
|
189
190
|
|
|
190
|
-
|
|
191
|
-
renameSync(tempPath, execPath);
|
|
191
|
+
await fs.promises.rename(tempPath, execPath);
|
|
192
192
|
|
|
193
|
-
|
|
194
|
-
unlinkSync(backupPath);
|
|
193
|
+
await fs.promises.unlink(backupPath);
|
|
195
194
|
|
|
196
195
|
console.log(chalk.green(`\n${theme.status.success} Updated to ${release.version}`));
|
|
197
196
|
console.log(chalk.dim(`Restart ${APP_NAME} to use the new version`));
|
|
198
197
|
} catch (err) {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
198
|
+
const [backupExists, execExists, tempExists] = await Promise.all([
|
|
199
|
+
Bun.file(backupPath).exists(),
|
|
200
|
+
Bun.file(execPath).exists(),
|
|
201
|
+
Bun.file(tempPath).exists(),
|
|
202
|
+
]);
|
|
203
|
+
if (backupExists && !execExists) {
|
|
204
|
+
await fs.promises.rename(backupPath, execPath);
|
|
202
205
|
}
|
|
203
|
-
if (
|
|
204
|
-
|
|
206
|
+
if (tempExists) {
|
|
207
|
+
await fs.promises.unlink(tempPath);
|
|
205
208
|
}
|
|
206
209
|
throw err;
|
|
207
210
|
}
|
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
import type { Api, Model } from "@oh-my-pi/pi-ai";
|
|
2
|
-
import agentUserPrompt from "@oh-my-pi/pi-coding-agent/commit/agentic/prompts/session-user.md" with { type: "text" };
|
|
3
|
-
import agentSystemPrompt from "@oh-my-pi/pi-coding-agent/commit/agentic/prompts/system.md" with { type: "text" };
|
|
4
|
-
import type { CommitAgentState } from "@oh-my-pi/pi-coding-agent/commit/agentic/state";
|
|
5
|
-
import { createCommitTools } from "@oh-my-pi/pi-coding-agent/commit/agentic/tools";
|
|
6
|
-
import type { ControlledGit } from "@oh-my-pi/pi-coding-agent/commit/git";
|
|
7
|
-
import typesDescriptionPrompt from "@oh-my-pi/pi-coding-agent/commit/prompts/types-description.md" with {
|
|
8
|
-
type: "text",
|
|
9
|
-
};
|
|
10
|
-
import type { ModelRegistry } from "@oh-my-pi/pi-coding-agent/config/model-registry";
|
|
11
|
-
import { renderPromptTemplate } from "@oh-my-pi/pi-coding-agent/config/prompt-templates";
|
|
12
|
-
import type { SettingsManager } from "@oh-my-pi/pi-coding-agent/config/settings-manager";
|
|
13
|
-
import { getMarkdownTheme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
|
|
14
|
-
import { createAgentSession } from "@oh-my-pi/pi-coding-agent/sdk";
|
|
15
|
-
import type { AgentSessionEvent } from "@oh-my-pi/pi-coding-agent/session/agent-session";
|
|
16
|
-
import type { AuthStorage } from "@oh-my-pi/pi-coding-agent/session/auth-storage";
|
|
17
2
|
import { Markdown } from "@oh-my-pi/pi-tui";
|
|
18
3
|
import chalk from "chalk";
|
|
4
|
+
import type { ControlledGit } from "../../commit/git";
|
|
5
|
+
import typesDescriptionPrompt from "../../commit/prompts/types-description.md" with { type: "text" };
|
|
6
|
+
import type { ModelRegistry } from "../../config/model-registry";
|
|
7
|
+
import { renderPromptTemplate } from "../../config/prompt-templates";
|
|
8
|
+
import type { SettingsManager } from "../../config/settings-manager";
|
|
9
|
+
import { getMarkdownTheme } from "../../modes/theme/theme";
|
|
10
|
+
import { createAgentSession } from "../../sdk";
|
|
11
|
+
import type { AgentSessionEvent } from "../../session/agent-session";
|
|
12
|
+
import type { AuthStorage } from "../../session/auth-storage";
|
|
13
|
+
import agentUserPrompt from "./prompts/session-user.md" with { type: "text" };
|
|
14
|
+
import agentSystemPrompt from "./prompts/system.md" with { type: "text" };
|
|
15
|
+
import type { CommitAgentState } from "./state";
|
|
16
|
+
import { createCommitTools } from "./tools";
|
|
19
17
|
|
|
20
18
|
export interface CommitAgentInput {
|
|
21
19
|
cwd: string;
|
|
@@ -176,8 +174,8 @@ function writeStdout(message: string): void {
|
|
|
176
174
|
|
|
177
175
|
function extractMessagePreview(content: Array<{ type: string; text?: string }>): string | null {
|
|
178
176
|
const textBlocks = content
|
|
179
|
-
.filter(
|
|
180
|
-
.map(
|
|
177
|
+
.filter(block => block.type === "text" && typeof block.text === "string")
|
|
178
|
+
.map(block => block.text?.trim())
|
|
181
179
|
.filter((value): value is string => Boolean(value));
|
|
182
180
|
if (textBlocks.length === 0) return null;
|
|
183
181
|
const combined = textBlocks.join(" ").replace(/\s+/g, " ").trim();
|
|
@@ -186,9 +184,9 @@ function extractMessagePreview(content: Array<{ type: string; text?: string }>):
|
|
|
186
184
|
|
|
187
185
|
function extractMessageText(content: Array<{ type: string; text?: string }>): string | null {
|
|
188
186
|
const textBlocks = content
|
|
189
|
-
.filter(
|
|
190
|
-
.map(
|
|
191
|
-
.filter(
|
|
187
|
+
.filter(block => block.type === "text" && typeof block.text === "string")
|
|
188
|
+
.map(block => block.text ?? "")
|
|
189
|
+
.filter(value => value.trim().length > 0);
|
|
192
190
|
if (textBlocks.length === 0) return null;
|
|
193
191
|
return textBlocks.join("\n").trim();
|
|
194
192
|
}
|
|
@@ -196,7 +194,7 @@ function extractMessageText(content: Array<{ type: string; text?: string }>): st
|
|
|
196
194
|
function writeAssistantMessage(message: string): void {
|
|
197
195
|
const lines = renderMarkdownLines(message);
|
|
198
196
|
if (lines.length === 0) return;
|
|
199
|
-
let firstContentIndex = lines.findIndex(
|
|
197
|
+
let firstContentIndex = lines.findIndex(line => line.trim().length > 0);
|
|
200
198
|
if (firstContentIndex === -1) {
|
|
201
199
|
firstContentIndex = 0;
|
|
202
200
|
}
|
|
@@ -215,7 +213,7 @@ function renderMarkdownLines(message: string): string[] {
|
|
|
215
213
|
function formatToolLabel(toolName: string): string {
|
|
216
214
|
const displayName = toolName
|
|
217
215
|
.split(/[_-]/)
|
|
218
|
-
.map(
|
|
216
|
+
.map(segment => segment.charAt(0).toUpperCase() + segment.slice(1))
|
|
219
217
|
.join("");
|
|
220
218
|
return displayName;
|
|
221
219
|
}
|
|
@@ -227,7 +225,7 @@ function formatToolArgs(args?: Record<string, unknown>): string[] {
|
|
|
227
225
|
if (value === null || value === undefined) return;
|
|
228
226
|
if (Array.isArray(value)) {
|
|
229
227
|
if (value.length === 0) return;
|
|
230
|
-
const rendered = value.map(
|
|
228
|
+
const rendered = value.map(item => renderPrimitive(item)).filter(Boolean);
|
|
231
229
|
if (rendered.length > 0) {
|
|
232
230
|
lines.push(`${keyPath}: ${rendered.join(", ")}`);
|
|
233
231
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import type { CommitType, ConventionalAnalysis, NumstatEntry } from "../../commit/types";
|
|
3
|
+
import type { CommitProposal } from "./state";
|
|
4
4
|
|
|
5
5
|
const TEST_PATTERNS = ["/test/", "/tests/", "/__tests__/", "_test.", ".test.", ".spec.", "_spec."];
|
|
6
6
|
const DOC_EXTENSIONS = new Set([".md", ".txt", ".rst", ".adoc"]);
|
|
@@ -20,7 +20,7 @@ function inferTypeFromFiles(numstat: NumstatEntry[]): CommitType {
|
|
|
20
20
|
const lowerPath = entry.path.toLowerCase();
|
|
21
21
|
const ext = getExtension(entry.path);
|
|
22
22
|
|
|
23
|
-
if (TEST_PATTERNS.some(
|
|
23
|
+
if (TEST_PATTERNS.some(pattern => lowerPath.includes(pattern))) {
|
|
24
24
|
hasTests = true;
|
|
25
25
|
} else if (DOC_EXTENSIONS.has(ext)) {
|
|
26
26
|
hasDocs = true;
|
|
@@ -40,16 +40,16 @@ function inferTypeFromFiles(numstat: NumstatEntry[]): CommitType {
|
|
|
40
40
|
return "refactor";
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
function getExtension(
|
|
44
|
-
const name = basename(
|
|
43
|
+
function getExtension(filePath: string): string {
|
|
44
|
+
const name = path.basename(filePath);
|
|
45
45
|
const dotIndex = name.lastIndexOf(".");
|
|
46
46
|
return dotIndex >= 0 ? name.slice(dotIndex).toLowerCase() : "";
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
export function generateFallbackAnalysis(numstat: NumstatEntry[]): ConventionalAnalysis {
|
|
50
50
|
const type = inferTypeFromFiles(numstat);
|
|
51
|
-
const details = numstat.slice(0, 3).map(
|
|
52
|
-
text: `Updated ${basename(e.path)}`,
|
|
51
|
+
const details = numstat.slice(0, 3).map(e => ({
|
|
52
|
+
text: `Updated ${path.basename(e.path)}`,
|
|
53
53
|
userVisible: false,
|
|
54
54
|
}));
|
|
55
55
|
|
|
@@ -76,7 +76,7 @@ export function generateFallbackSummary(type: CommitType, numstat: NumstatEntry[
|
|
|
76
76
|
revert: "reverted changes in",
|
|
77
77
|
};
|
|
78
78
|
const verb = verbMap[type] ?? "updated";
|
|
79
|
-
const file = basename(numstat[0]?.path ?? "files");
|
|
79
|
+
const file = path.basename(numstat[0]?.path ?? "files");
|
|
80
80
|
|
|
81
81
|
if (numstat.length === 1) {
|
|
82
82
|
return `${verb} ${file}`;
|
|
@@ -1,28 +1,21 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as path from "node:path";
|
|
2
2
|
import { createInterface } from "node:readline/promises";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
};
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} from "
|
|
14
|
-
import {
|
|
15
|
-
import
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import { ControlledGit } from "@oh-my-pi/pi-coding-agent/commit/git";
|
|
20
|
-
import { formatCommitMessage } from "@oh-my-pi/pi-coding-agent/commit/message";
|
|
21
|
-
import { resolvePrimaryModel, resolveSmolModel } from "@oh-my-pi/pi-coding-agent/commit/model-selection";
|
|
22
|
-
import type { CommitCommandArgs, ConventionalAnalysis } from "@oh-my-pi/pi-coding-agent/commit/types";
|
|
23
|
-
import { renderPromptTemplate } from "@oh-my-pi/pi-coding-agent/config/prompt-templates";
|
|
24
|
-
import { SettingsManager } from "@oh-my-pi/pi-coding-agent/config/settings-manager";
|
|
25
|
-
import { discoverAuthStorage, discoverContextFiles, discoverModels } from "@oh-my-pi/pi-coding-agent/sdk";
|
|
3
|
+
import { applyChangelogProposals } from "../../commit/changelog";
|
|
4
|
+
import { detectChangelogBoundaries } from "../../commit/changelog/detect";
|
|
5
|
+
import { parseUnreleasedSection } from "../../commit/changelog/parse";
|
|
6
|
+
import { ControlledGit } from "../../commit/git";
|
|
7
|
+
import { formatCommitMessage } from "../../commit/message";
|
|
8
|
+
import { resolvePrimaryModel, resolveSmolModel } from "../../commit/model-selection";
|
|
9
|
+
import type { CommitCommandArgs, ConventionalAnalysis } from "../../commit/types";
|
|
10
|
+
import { renderPromptTemplate } from "../../config/prompt-templates";
|
|
11
|
+
import { SettingsManager } from "../../config/settings-manager";
|
|
12
|
+
import { discoverAuthStorage, discoverContextFiles, discoverModels } from "../../sdk";
|
|
13
|
+
import { type ExistingChangelogEntries, runCommitAgentSession } from "./agent";
|
|
14
|
+
import { generateFallbackProposal } from "./fallback";
|
|
15
|
+
import splitConfirmPrompt from "./prompts/split-confirm.md" with { type: "text" };
|
|
16
|
+
import type { CommitAgentState, CommitProposal, HunkSelector, SplitCommitPlan } from "./state";
|
|
17
|
+
import { computeDependencyOrder } from "./topo-sort";
|
|
18
|
+
import { detectTrivialChange } from "./trivial";
|
|
26
19
|
|
|
27
20
|
interface CommitExecutionContext {
|
|
28
21
|
git: ControlledGit;
|
|
@@ -34,9 +27,9 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
34
27
|
const cwd = process.cwd();
|
|
35
28
|
const git = new ControlledGit(cwd);
|
|
36
29
|
const [settingsManager, authStorage] = await Promise.all([SettingsManager.create(cwd), discoverAuthStorage()]);
|
|
37
|
-
const modelRegistryPromise = discoverModels(authStorage);
|
|
38
30
|
|
|
39
31
|
writeStdout("● Resolving model...");
|
|
32
|
+
const modelRegistry = discoverModels(authStorage);
|
|
40
33
|
const stagedFilesPromise = (async () => {
|
|
41
34
|
let stagedFiles = await git.getStagedFiles();
|
|
42
35
|
if (stagedFiles.length === 0) {
|
|
@@ -47,7 +40,6 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
47
40
|
return stagedFiles;
|
|
48
41
|
})();
|
|
49
42
|
|
|
50
|
-
const modelRegistry = await modelRegistryPromise;
|
|
51
43
|
const primaryModelPromise = resolvePrimaryModel(args.model, settingsManager, modelRegistry);
|
|
52
44
|
const [primaryModelResult, stagedFiles] = await Promise.all([primaryModelPromise, stagedFilesPromise]);
|
|
53
45
|
const { model: primaryModel, apiKey: primaryApiKey } = primaryModelResult;
|
|
@@ -69,7 +61,7 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
69
61
|
git.getNumstat(true),
|
|
70
62
|
git.getDiff(true),
|
|
71
63
|
]);
|
|
72
|
-
const changelogTargets = changelogBoundaries.map(
|
|
64
|
+
const changelogTargets = changelogBoundaries.map(boundary => boundary.changelogPath);
|
|
73
65
|
if (!args.noChangelog) {
|
|
74
66
|
if (changelogTargets.length > 0) {
|
|
75
67
|
for (const path of changelogTargets) {
|
|
@@ -81,7 +73,7 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
81
73
|
}
|
|
82
74
|
|
|
83
75
|
writeStdout("● Discovering context files...");
|
|
84
|
-
const agentsMdFiles = contextFiles.filter(
|
|
76
|
+
const agentsMdFiles = contextFiles.filter(file => file.path.endsWith("AGENTS.md"));
|
|
85
77
|
if (agentsMdFiles.length > 0) {
|
|
86
78
|
for (const file of agentsMdFiles) {
|
|
87
79
|
writeStdout(` └─ ${file.path}`);
|
|
@@ -168,14 +160,14 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
168
160
|
cwd,
|
|
169
161
|
proposals: commitState.changelogProposal.entries,
|
|
170
162
|
dryRun: args.dryRun,
|
|
171
|
-
onProgress:
|
|
163
|
+
onProgress: message => {
|
|
172
164
|
writeStdout(` ├─ ${message}`);
|
|
173
165
|
},
|
|
174
166
|
});
|
|
175
|
-
updatedChangelogFiles = updated.map(
|
|
167
|
+
updatedChangelogFiles = updated.map(filePath => path.relative(cwd, filePath));
|
|
176
168
|
if (updated.length > 0) {
|
|
177
|
-
for (const
|
|
178
|
-
writeStdout(` └─ ${
|
|
169
|
+
for (const filePath of updated) {
|
|
170
|
+
writeStdout(` └─ ${filePath}`);
|
|
179
171
|
}
|
|
180
172
|
} else {
|
|
181
173
|
writeStdout(" └─ (no changes)");
|
|
@@ -229,8 +221,8 @@ async function runSplitCommit(
|
|
|
229
221
|
appendFilesToLastCommit(plan, ctx.additionalFiles);
|
|
230
222
|
}
|
|
231
223
|
const stagedFiles = await ctx.git.getStagedFiles();
|
|
232
|
-
const plannedFiles = new Set(plan.commits.flatMap(
|
|
233
|
-
const missingFiles = stagedFiles.filter(
|
|
224
|
+
const plannedFiles = new Set(plan.commits.flatMap(commit => commit.changes.map(change => change.path)));
|
|
225
|
+
const missingFiles = stagedFiles.filter(file => !plannedFiles.has(file));
|
|
234
226
|
if (missingFiles.length > 0) {
|
|
235
227
|
writeStderr(`Split commit plan missing staged files: ${missingFiles.join(", ")}`);
|
|
236
228
|
return;
|
|
@@ -248,7 +240,7 @@ async function runSplitCommit(
|
|
|
248
240
|
const message = formatCommitMessage(analysis, commit.summary);
|
|
249
241
|
writeStdout(`Commit ${index + 1}:\n${message}\n`);
|
|
250
242
|
const changeSummary = commit.changes
|
|
251
|
-
.map(
|
|
243
|
+
.map(change => formatFileChangeSummary(change.path, change.hunks))
|
|
252
244
|
.join(", ");
|
|
253
245
|
writeStdout(`Changes: ${changeSummary}\n`);
|
|
254
246
|
}
|
|
@@ -288,7 +280,7 @@ async function runSplitCommit(
|
|
|
288
280
|
|
|
289
281
|
function appendFilesToLastCommit(plan: SplitCommitPlan, files: string[]): void {
|
|
290
282
|
if (plan.commits.length === 0) return;
|
|
291
|
-
const planned = new Set(plan.commits.flatMap(
|
|
283
|
+
const planned = new Set(plan.commits.flatMap(commit => commit.changes.map(change => change.path)));
|
|
292
284
|
const targetCommit = plan.commits[plan.commits.length - 1];
|
|
293
285
|
for (const file of files) {
|
|
294
286
|
if (planned.has(file)) continue;
|
|
@@ -312,7 +304,7 @@ async function confirmSplitCommitPlan(plan: SplitCommitPlan): Promise<boolean> {
|
|
|
312
304
|
}
|
|
313
305
|
|
|
314
306
|
function formatWarnings(warnings: string[]): string {
|
|
315
|
-
return `Warnings:\n${warnings.map(
|
|
307
|
+
return `Warnings:\n${warnings.map(warning => `- ${warning}`).join("\n")}`;
|
|
316
308
|
}
|
|
317
309
|
|
|
318
310
|
function writeStdout(message: string): void {
|
|
@@ -335,7 +327,7 @@ function formatFileChangeSummary(path: string, hunks: HunkSelector): string {
|
|
|
335
327
|
|
|
336
328
|
async function loadExistingChangelogEntries(paths: string[]): Promise<ExistingChangelogEntries[]> {
|
|
337
329
|
const entries = await Promise.all(
|
|
338
|
-
paths.map(async
|
|
330
|
+
paths.map(async path => {
|
|
339
331
|
const file = Bun.file(path);
|
|
340
332
|
if (!(await file.exists())) {
|
|
341
333
|
return null;
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
CommitType,
|
|
3
|
-
ConventionalAnalysis,
|
|
4
|
-
ConventionalDetail,
|
|
5
|
-
NumstatEntry,
|
|
6
|
-
} from "@oh-my-pi/pi-coding-agent/commit/types";
|
|
1
|
+
import type { CommitType, ConventionalAnalysis, ConventionalDetail, NumstatEntry } from "../../commit/types";
|
|
7
2
|
|
|
8
3
|
export interface GitOverviewSnapshot {
|
|
9
4
|
files: string[];
|