@oh-my-pi/pi-coding-agent 8.0.16 → 8.1.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 +105 -0
- package/package.json +14 -11
- package/scripts/generate-wasm-b64.ts +24 -0
- package/src/capability/context-file.ts +1 -1
- package/src/capability/extension-module.ts +1 -1
- package/src/capability/extension.ts +1 -1
- package/src/capability/hook.ts +1 -1
- package/src/capability/instruction.ts +1 -1
- package/src/capability/mcp.ts +1 -1
- package/src/capability/prompt.ts +1 -1
- package/src/capability/rule.ts +1 -1
- package/src/capability/settings.ts +1 -1
- package/src/capability/skill.ts +1 -1
- package/src/capability/slash-command.ts +1 -1
- package/src/capability/ssh.ts +1 -1
- package/src/capability/system-prompt.ts +1 -1
- package/src/capability/tool.ts +1 -1
- package/src/cli/args.ts +1 -1
- package/src/cli/plugin-cli.ts +1 -5
- package/src/commit/agentic/agent.ts +309 -0
- package/src/commit/agentic/fallback.ts +96 -0
- package/src/commit/agentic/index.ts +359 -0
- package/src/commit/agentic/prompts/analyze-file.md +22 -0
- package/src/commit/agentic/prompts/session-user.md +26 -0
- package/src/commit/agentic/prompts/split-confirm.md +1 -0
- package/src/commit/agentic/prompts/system.md +40 -0
- package/src/commit/agentic/state.ts +74 -0
- package/src/commit/agentic/tools/analyze-file.ts +131 -0
- package/src/commit/agentic/tools/git-file-diff.ts +194 -0
- package/src/commit/agentic/tools/git-hunk.ts +50 -0
- package/src/commit/agentic/tools/git-overview.ts +84 -0
- package/src/commit/agentic/tools/index.ts +56 -0
- package/src/commit/agentic/tools/propose-changelog.ts +128 -0
- package/src/commit/agentic/tools/propose-commit.ts +154 -0
- package/src/commit/agentic/tools/recent-commits.ts +81 -0
- package/src/commit/agentic/tools/split-commit.ts +284 -0
- package/src/commit/agentic/topo-sort.ts +44 -0
- package/src/commit/agentic/trivial.ts +51 -0
- package/src/commit/agentic/validation.ts +200 -0
- package/src/commit/analysis/conventional.ts +169 -0
- package/src/commit/analysis/index.ts +4 -0
- package/src/commit/analysis/scope.ts +242 -0
- package/src/commit/analysis/summary.ts +114 -0
- package/src/commit/analysis/validation.ts +66 -0
- package/src/commit/changelog/detect.ts +36 -0
- package/src/commit/changelog/generate.ts +112 -0
- package/src/commit/changelog/index.ts +233 -0
- package/src/commit/changelog/parse.ts +44 -0
- package/src/commit/cli.ts +93 -0
- package/src/commit/git/diff.ts +148 -0
- package/src/commit/git/errors.ts +11 -0
- package/src/commit/git/index.ts +217 -0
- package/src/commit/git/operations.ts +53 -0
- package/src/commit/index.ts +5 -0
- package/src/commit/map-reduce/.map-phase.ts.kate-swp +0 -0
- package/src/commit/map-reduce/index.ts +63 -0
- package/src/commit/map-reduce/map-phase.ts +193 -0
- package/src/commit/map-reduce/reduce-phase.ts +147 -0
- package/src/commit/map-reduce/utils.ts +9 -0
- package/src/commit/message.ts +11 -0
- package/src/commit/model-selection.ts +84 -0
- package/src/commit/pipeline.ts +242 -0
- package/src/commit/prompts/analysis-system.md +155 -0
- package/src/commit/prompts/analysis-user.md +41 -0
- package/src/commit/prompts/changelog-system.md +56 -0
- package/src/commit/prompts/changelog-user.md +19 -0
- package/src/commit/prompts/file-observer-system.md +26 -0
- package/src/commit/prompts/file-observer-user.md +9 -0
- package/src/commit/prompts/reduce-system.md +60 -0
- package/src/commit/prompts/reduce-user.md +17 -0
- package/src/commit/prompts/summary-retry.md +4 -0
- package/src/commit/prompts/summary-system.md +52 -0
- package/src/commit/prompts/summary-user.md +13 -0
- package/src/commit/prompts/types-description.md +2 -0
- package/src/commit/types.ts +109 -0
- package/src/commit/utils/exclusions.ts +42 -0
- package/src/config/file-lock.ts +111 -0
- package/src/config/model-registry.ts +16 -7
- package/src/config/settings-manager.ts +115 -40
- package/src/config.ts +5 -5
- package/src/discovery/agents-md.ts +1 -1
- package/src/discovery/builtin.ts +1 -1
- package/src/discovery/claude.ts +1 -1
- package/src/discovery/cline.ts +1 -1
- package/src/discovery/codex.ts +1 -1
- package/src/discovery/cursor.ts +1 -1
- package/src/discovery/gemini.ts +1 -1
- package/src/discovery/github.ts +1 -1
- package/src/discovery/index.ts +11 -11
- package/src/discovery/mcp-json.ts +1 -1
- package/src/discovery/ssh.ts +1 -1
- package/src/discovery/vscode.ts +1 -1
- package/src/discovery/windsurf.ts +1 -1
- package/src/extensibility/custom-commands/loader.ts +1 -1
- package/src/extensibility/custom-commands/types.ts +1 -1
- package/src/extensibility/custom-tools/loader.ts +1 -1
- package/src/extensibility/custom-tools/types.ts +1 -1
- package/src/extensibility/extensions/loader.ts +1 -1
- package/src/extensibility/extensions/types.ts +1 -1
- package/src/extensibility/hooks/loader.ts +1 -1
- package/src/extensibility/hooks/types.ts +3 -3
- package/src/index.ts +10 -10
- package/src/ipy/executor.ts +97 -1
- package/src/lsp/index.ts +1 -1
- package/src/lsp/render.ts +90 -46
- package/src/main.ts +16 -3
- package/src/mcp/loader.ts +3 -3
- package/src/migrations.ts +3 -3
- package/src/modes/components/assistant-message.ts +29 -1
- package/src/modes/components/tool-execution.ts +5 -3
- package/src/modes/components/tree-selector.ts +1 -1
- package/src/modes/controllers/extension-ui-controller.ts +1 -1
- package/src/modes/controllers/selector-controller.ts +1 -1
- package/src/modes/interactive-mode.ts +5 -3
- package/src/modes/rpc/rpc-client.ts +1 -1
- package/src/modes/rpc/rpc-mode.ts +1 -4
- package/src/modes/rpc/rpc-types.ts +1 -1
- package/src/modes/theme/mermaid-cache.ts +89 -0
- package/src/modes/theme/theme.ts +2 -0
- package/src/modes/types.ts +2 -2
- package/src/patch/index.ts +3 -9
- package/src/patch/shared.ts +33 -5
- package/src/prompts/tools/task.md +2 -0
- package/src/sdk.ts +60 -22
- package/src/session/agent-session.ts +3 -3
- package/src/session/agent-storage.ts +32 -28
- package/src/session/artifacts.ts +24 -1
- package/src/session/auth-storage.ts +25 -10
- package/src/session/storage-migration.ts +12 -53
- package/src/system-prompt.ts +2 -2
- package/src/task/.executor.ts.kate-swp +0 -0
- package/src/task/executor.ts +1 -1
- package/src/task/index.ts +10 -1
- package/src/task/output-manager.ts +94 -0
- package/src/task/render.ts +7 -12
- package/src/task/worker.ts +1 -1
- package/src/tools/ask.ts +35 -13
- package/src/tools/bash.ts +80 -87
- package/src/tools/calculator.ts +42 -40
- package/src/tools/complete.ts +1 -1
- package/src/tools/fetch.ts +67 -104
- package/src/tools/find.ts +83 -86
- package/src/tools/grep.ts +80 -96
- package/src/tools/index.ts +10 -7
- package/src/tools/ls.ts +39 -65
- package/src/tools/notebook.ts +48 -64
- package/src/tools/output-utils.ts +1 -1
- package/src/tools/python.ts +71 -183
- package/src/tools/read.ts +74 -15
- package/src/tools/render-utils.ts +1 -15
- package/src/tools/ssh.ts +43 -24
- package/src/tools/todo-write.ts +27 -15
- package/src/tools/write.ts +93 -64
- package/src/tui/code-cell.ts +115 -0
- package/src/tui/file-list.ts +48 -0
- package/src/tui/index.ts +11 -0
- package/src/tui/output-block.ts +73 -0
- package/src/tui/status-line.ts +40 -0
- package/src/tui/tree-list.ts +56 -0
- package/src/tui/types.ts +17 -0
- package/src/tui/utils.ts +49 -0
- package/src/vendor/photon/photon_rs_bg.wasm.b64.js +1 -0
- package/src/web/search/auth.ts +1 -1
- package/src/web/search/index.ts +1 -1
- package/src/web/search/render.ts +119 -163
- package/tsconfig.json +0 -42
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,111 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
### Added
|
|
6
|
+
- Added `omp commit` command to generate conventional commits with changelog updates
|
|
7
|
+
- Added agentic commit mode with commit-specific tools and `--legacy` fallback
|
|
8
|
+
- Added configurable settings for map-reduce analysis including concurrency, timeout, file thresholds, and token limits
|
|
9
|
+
- Added support for excluding YAML lock files (`.lock.yml`, `.lock.yaml`, `-lock.yml`, `-lock.yaml`) from commit analysis
|
|
10
|
+
- Added new TUI component library with reusable rendering utilities including code cells, file lists, tree lists, status lines, and output blocks
|
|
11
|
+
- Added renderCodeCell component for displaying code with optional output sections, supporting syntax highlighting and status indicators
|
|
12
|
+
- Added renderFileList component for rendering file/directory listings with language icons and metadata
|
|
13
|
+
- Added renderTreeList component for hierarchical tree-based item rendering with expand/collapse support
|
|
14
|
+
- Added renderStatusLine component for standardized tool status headers with icons, descriptions, and metadata
|
|
15
|
+
- Added renderOutputBlock component for bordered output containers with structured sections
|
|
16
|
+
- Added renderOutputBlock to Bash tool for improved output formatting with status indicators
|
|
17
|
+
- Added `--legacy` flag to `omp commit` for using the deterministic pipeline instead of agentic mode
|
|
18
|
+
- Added split commit support to automatically create multiple atomic commits for unrelated changes
|
|
19
|
+
- Added git hunk inspection tools for fine-grained diff analysis in commit generation
|
|
20
|
+
- Added commit message validation with filler word and meta phrase detection
|
|
21
|
+
- Added automatic unicode normalization in commit summaries
|
|
22
|
+
- Added real-time progress output to agentic commit mode showing thinking status, tool calls, and completion summary
|
|
23
|
+
- Added hunk-level staging support in split commits allowing partial file changes per commit
|
|
24
|
+
- Added dependency ordering for split commits ensuring commits are applied in correct sequence
|
|
25
|
+
- Added circular dependency detection with validation errors for split commit plans
|
|
26
|
+
- Added parallel file analysis with cross-file context awareness via `analyze_files` tool
|
|
27
|
+
- Added AGENTS.md context file discovery for commit generation
|
|
28
|
+
- Added progress indicators during changelog generation and model resolution
|
|
29
|
+
- Added propose_changelog tool for agent-provided changelog entries in agentic commit workflow
|
|
30
|
+
- Added fallback commit generation when agentic mode fails, using file pattern analysis and heuristic-based type inference
|
|
31
|
+
- Added trivial change detection to automatically classify whitespace-only and import-reorganization commits
|
|
32
|
+
- Added support for pre-computed file observations in commit agent to skip redundant analyze_files calls
|
|
33
|
+
- Added diff content caching with smart file prioritization to optimize token usage in large changesets
|
|
34
|
+
- Added lock file filtering (17 patterns including Cargo.lock, package-lock.json, bun.lock) from commit analysis
|
|
35
|
+
- Added changelog deletion support to remove outdated entries via the changelog proposal interface
|
|
36
|
+
- Added support for pre-computed changelog entries in commit agent to display existing unreleased sections for potential deletion
|
|
37
|
+
- Added `ExistingChangelogEntries` interface to track changelog sections by path for changelog proposal context
|
|
38
|
+
- Added conditional `analyze_files` skipping in commit agent when pre-analyzed observations are provided
|
|
39
|
+
- Added guidance to commit agent prompts instructing subagents to write files directly instead of returning changes for manual application
|
|
40
|
+
- Added mermaid diagram rendering with terminal graphics support (Kitty/iTerm2) for markdown output
|
|
41
|
+
- Added renderMermaidToPng utility for converting mermaid code blocks to terminal-displayable PNG images via mmdc CLI
|
|
42
|
+
- Added mermaid block extraction with content-addressed hashing for deduplication and cache lookup
|
|
43
|
+
- Added background mermaid pre-rendering in assistant messages for responsive diagram display
|
|
44
|
+
- Added two-level mermaid caching with pending deduplication to prevent redundant renders
|
|
45
|
+
- Added Python kernel session pooling with MAX_KERNEL_SESSIONS limit and automatic eviction of oldest sessions
|
|
46
|
+
- Added automatic idle kernel session cleanup timer (5-minute timeout, 30-second interval)
|
|
47
|
+
- Added WASM binary generation script for photon module distribution
|
|
48
|
+
|
|
49
|
+
### Changed
|
|
50
|
+
- Changed changelog diff truncation limit to be configurable via settings
|
|
51
|
+
- Changed tool result rendering to use new TUI component library across multiple tools (bash, calculator, fetch, find, grep, ls, notebook, python, read, ssh, write, lsp, web search) for consistent output formatting
|
|
52
|
+
- Changed Bash tool output rendering to use renderOutputBlock with proper section handling and width-aware truncation
|
|
53
|
+
- Changed Python tool output rendering to use renderCodeCell component for code cell display with status indicators
|
|
54
|
+
- Changed Read tool output rendering to use renderCodeCell with syntax highlighting and warnings display
|
|
55
|
+
- Changed Write tool output rendering to use renderCodeCell for code display with streaming preview support
|
|
56
|
+
- Changed Fetch tool output rendering to use renderOutputBlock with metadata and content preview sections
|
|
57
|
+
- Changed LSP tool output rendering to use renderStatusLine and renderOutputBlock for structured output display
|
|
58
|
+
- Changed Web Search result rendering to use renderOutputBlock with answer, sources, related questions, and metadata sections
|
|
59
|
+
- Changed Find, Grep, and Ls tools to use renderFileList and renderTreeList for consistent file/item listing
|
|
60
|
+
- Changed Calculator tool result rendering to use renderTreeList for result item display
|
|
61
|
+
- Changed Notebook and TodoWrite tools to use new TUI rendering components for consistent output format
|
|
62
|
+
- Refactored render-utils to move tree-related utilities to TUI module (getTreeBranch, getTreeContinuePrefix)
|
|
63
|
+
- Changed import organization in sdk.ts for consistency
|
|
64
|
+
- Changed tool result rendering to merge call and result displays, showing tool arguments (command, pattern, query, path) in result headers for Bash, Calculator, Fetch, Find, Grep, Ls, LSP, Notebook, Read, SSH, TodoWrite, Web Search, and Write tools
|
|
65
|
+
- Changed Read tool title to display line range when offset or limit arguments are provided
|
|
66
|
+
- Changed worker instantiation to use direct URL import instead of pre-bundled worker files
|
|
67
|
+
- Changed `omp commit` to use agentic mode by default with tool-based git inspection
|
|
68
|
+
- Changed agentic commit progress output to show real-time thinking previews and structured tool argument details
|
|
69
|
+
- Changed agentic commit progress output to display full multi-line assistant messages and render tool arguments with tree-style formatting for improved readability
|
|
70
|
+
- Changed agentic commit progress output to render assistant messages as formatted Markdown with proper word wrapping
|
|
71
|
+
- Changed output block border color to reflect state (error, success, warning) for improved visual feedback
|
|
72
|
+
- Changed LSP hover rendering to display documentation text before code blocks in both collapsed and expanded views
|
|
73
|
+
- Changed Write tool to show streaming preview of content being written with syntax highlighting
|
|
74
|
+
- Changed Read tool to display resolved path information when reading from URLs or symlinks
|
|
75
|
+
- Changed Calculator tool result display to show both expression and output (e.g., `2+2 = 4`) instead of just the result
|
|
76
|
+
- Changed Python tool output to group status information under a labeled section for clearer organization
|
|
77
|
+
- Changed SSH tool output to apply consistent styling to non-ANSI output lines
|
|
78
|
+
- Changed Todo Write tool to respect expanded/collapsed state and use standard preview limits
|
|
79
|
+
- Changed Web Search related questions to respect expanded/collapsed state instead of always showing all items
|
|
80
|
+
- Changed empty and error state rendering across multiple tools (Find, Grep, Ls, Notebook, Calculator, Ask) to include consistent status headers
|
|
81
|
+
- Changed split commit to support hunk selectors (all, indices, or line ranges) instead of whole-file staging
|
|
82
|
+
- Changed `analyze_file` tool to `analyze_files` for batch parallel analysis of multiple files
|
|
83
|
+
- Switched agentic commit from auto-generated changelogs to agent-proposed entries with validation and retry logic
|
|
84
|
+
- Commit agent now resolves a separate smaller model for commit generation instead of reusing the primary model
|
|
85
|
+
- Normalized code formatting and indentation across tool renderers and UI components
|
|
86
|
+
- Changed git-file-diff tool to prioritize files by type and respect token budget limits with intelligent truncation
|
|
87
|
+
- Changed git-overview tool to filter and report excluded lock files separately from staged files
|
|
88
|
+
- Changed analyze-file tool to include file type inference and enriched related files with line counts
|
|
89
|
+
- Changed propose-changelog tool to support optional deletion entries for removing existing changelog items
|
|
90
|
+
- Changed commit agent to accept pre-computed file observations and format them into session prompts
|
|
91
|
+
- Changed changelog skip condition in `applyChangelogProposals` to also check for empty deletions object
|
|
92
|
+
- Changed `createCommitTools()` to build tools array incrementally with conditional `analyze_files` inclusion based on `enableAnalyzeFiles` flag
|
|
93
|
+
- Changed system prompt guidance to clarify that pre-computed observations prevent redundant `analyze_files` calls
|
|
94
|
+
- Removed map-reduce preprocessing phase from commit agent for faster iteration
|
|
95
|
+
- Changed commit agent to process full diff text directly instead of pre-computed file observations
|
|
96
|
+
- Changed commit agent initialization to load settingsManager, authStorage, modelRegistry, and stagedFiles in parallel
|
|
97
|
+
- Changed commit agent prompt to remove pre-computed observations guidance and encourage direct analyze_files usage
|
|
98
|
+
- Changed AuthStorage from constructor-based instantiation to async factory method (AuthStorage.create())
|
|
99
|
+
- Changed Python kernel resource management with gateway shutdown on session disposal
|
|
100
|
+
- Updated TypeScript configuration for better publish-time configuration handling with tsconfig.publish.json
|
|
101
|
+
|
|
102
|
+
### Fixed
|
|
103
|
+
- Fixed database busy errors during concurrent access by adding retry logic with exponential backoff when opening storage
|
|
104
|
+
- Find tool now rejects searches from root directory and enforces a 5-second timeout on fd operations
|
|
105
|
+
- Commit command now exits cleanly with exit code 0 on success
|
|
106
|
+
- Handle undefined code parameter in code cell renderer
|
|
107
|
+
- Fixed indentation formatting in split-commit tool function signature
|
|
108
|
+
- Fixed changelog application to process proposals containing only deletion entries without additions
|
|
109
|
+
- Fixed indentation formatting in Python tool output renderer
|
|
5
110
|
## [8.0.0] - 2026-01-23
|
|
6
111
|
### Added
|
|
7
112
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
3
|
-
"version": "8.0
|
|
3
|
+
"version": "8.1.0",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"ompConfig": {
|
|
@@ -22,15 +22,17 @@
|
|
|
22
22
|
"import": "./src/extensibility/hooks/index.ts"
|
|
23
23
|
},
|
|
24
24
|
"./prompts/*": "./src/prompts/*",
|
|
25
|
-
"./*":
|
|
25
|
+
"./*": {
|
|
26
|
+
"types": "./src/*",
|
|
27
|
+
"import": "./src/*"
|
|
28
|
+
}
|
|
26
29
|
},
|
|
27
30
|
"files": [
|
|
28
31
|
"src",
|
|
29
32
|
"scripts",
|
|
30
33
|
"docs",
|
|
31
34
|
"examples",
|
|
32
|
-
"CHANGELOG.md"
|
|
33
|
-
"tsconfig.json"
|
|
35
|
+
"CHANGELOG.md"
|
|
34
36
|
],
|
|
35
37
|
"scripts": {
|
|
36
38
|
"check": "tsgo -p tsconfig.check.json",
|
|
@@ -38,17 +40,18 @@
|
|
|
38
40
|
"clean": "rm -rf dist",
|
|
39
41
|
"build": "tsgo -p tsconfig.build.json && chmod +x dist/cli.js",
|
|
40
42
|
"build:binary": "bun run generate-wasm-b64 && bun build --compile ./src/cli.ts --outfile dist/omp",
|
|
43
|
+
"generate-wasm-b64": "bun scripts/generate-wasm-b64.ts",
|
|
41
44
|
"generate-template": "bun scripts/generate-template.ts",
|
|
42
|
-
"postinstall": "bun run generate-template || true",
|
|
45
|
+
"postinstall": "(bun run generate-wasm-b64 && bun run generate-template) || true",
|
|
43
46
|
"test": "bun test",
|
|
44
|
-
"prepublishOnly": "
|
|
47
|
+
"prepublishOnly": "cp tsconfig.publish.json tsconfig.json && bun run generate-template"
|
|
45
48
|
},
|
|
46
49
|
"dependencies": {
|
|
47
|
-
"@oh-my-pi/omp-stats": "
|
|
48
|
-
"@oh-my-pi/pi-agent-core": "
|
|
49
|
-
"@oh-my-pi/pi-ai": "
|
|
50
|
-
"@oh-my-pi/pi-tui": "
|
|
51
|
-
"@oh-my-pi/pi-utils": "
|
|
50
|
+
"@oh-my-pi/omp-stats": "workspace:*",
|
|
51
|
+
"@oh-my-pi/pi-agent-core": "workspace:*",
|
|
52
|
+
"@oh-my-pi/pi-ai": "workspace:*",
|
|
53
|
+
"@oh-my-pi/pi-tui": "workspace:*",
|
|
54
|
+
"@oh-my-pi/pi-utils": "workspace:*",
|
|
52
55
|
"@openai/agents": "^0.3.7",
|
|
53
56
|
"@sinclair/typebox": "^0.34.46",
|
|
54
57
|
"ajv": "^8.17.1",
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Generates a base64-encoded JavaScript module from the photon WASM file.
|
|
4
|
+
* This allows bundling the WASM binary inline for single-file distribution.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
|
|
9
|
+
const VENDOR_DIR = join(import.meta.dir, "../src/vendor/photon");
|
|
10
|
+
const WASM_PATH = join(VENDOR_DIR, "photon_rs_bg.wasm");
|
|
11
|
+
const OUTPUT_PATH = join(VENDOR_DIR, "photon_rs_bg.wasm.b64.js");
|
|
12
|
+
|
|
13
|
+
const wasmFile = Bun.file(WASM_PATH);
|
|
14
|
+
if (!(await wasmFile.exists())) {
|
|
15
|
+
console.error(`WASM file not found: ${WASM_PATH}`);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const wasmBytes = await wasmFile.arrayBuffer();
|
|
20
|
+
const base64 = Buffer.from(wasmBytes).toString("base64");
|
|
21
|
+
const content = `export default "${base64}";\n`;
|
|
22
|
+
|
|
23
|
+
await Bun.write(OUTPUT_PATH, content);
|
|
24
|
+
console.log(`Generated ${OUTPUT_PATH} (${Math.round(base64.length / 1024)}KB)`);
|
package/src/capability/hook.ts
CHANGED
package/src/capability/mcp.ts
CHANGED
package/src/capability/prompt.ts
CHANGED
package/src/capability/rule.ts
CHANGED
package/src/capability/skill.ts
CHANGED
package/src/capability/ssh.ts
CHANGED
package/src/capability/tool.ts
CHANGED
package/src/cli/args.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
6
6
|
import { APP_NAME, CONFIG_DIR_NAME, ENV_AGENT_DIR } from "@oh-my-pi/pi-coding-agent/config";
|
|
7
|
-
import { BUILTIN_TOOLS } from "@oh-my-pi/pi-coding-agent/tools
|
|
7
|
+
import { BUILTIN_TOOLS } from "@oh-my-pi/pi-coding-agent/tools";
|
|
8
8
|
import chalk from "chalk";
|
|
9
9
|
|
|
10
10
|
export type Mode = "text" | "json" | "rpc";
|
package/src/cli/plugin-cli.ts
CHANGED
|
@@ -5,11 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { APP_NAME } from "@oh-my-pi/pi-coding-agent/config";
|
|
8
|
-
import {
|
|
9
|
-
PluginManager,
|
|
10
|
-
parseSettingValue,
|
|
11
|
-
validateSetting,
|
|
12
|
-
} from "@oh-my-pi/pi-coding-agent/extensibility/plugins/index";
|
|
8
|
+
import { PluginManager, parseSettingValue, validateSetting } from "@oh-my-pi/pi-coding-agent/extensibility/plugins";
|
|
13
9
|
import { theme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
|
|
14
10
|
import chalk from "chalk";
|
|
15
11
|
|
|
@@ -0,0 +1,309 @@
|
|
|
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
|
+
import { Markdown } from "@oh-my-pi/pi-tui";
|
|
18
|
+
import chalk from "chalk";
|
|
19
|
+
|
|
20
|
+
export interface CommitAgentInput {
|
|
21
|
+
cwd: string;
|
|
22
|
+
git: ControlledGit;
|
|
23
|
+
model: Model<Api>;
|
|
24
|
+
settingsManager: SettingsManager;
|
|
25
|
+
modelRegistry: ModelRegistry;
|
|
26
|
+
authStorage: AuthStorage;
|
|
27
|
+
userContext?: string;
|
|
28
|
+
contextFiles?: Array<{ path: string; content: string }>;
|
|
29
|
+
changelogTargets: string[];
|
|
30
|
+
requireChangelog: boolean;
|
|
31
|
+
diffText?: string;
|
|
32
|
+
existingChangelogEntries?: ExistingChangelogEntries[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface ExistingChangelogEntries {
|
|
36
|
+
path: string;
|
|
37
|
+
sections: Array<{ name: string; items: string[] }>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export async function runCommitAgentSession(input: CommitAgentInput): Promise<CommitAgentState> {
|
|
41
|
+
const typesDescription = renderPromptTemplate(typesDescriptionPrompt);
|
|
42
|
+
const systemPrompt = renderPromptTemplate(agentSystemPrompt, {
|
|
43
|
+
types_description: typesDescription,
|
|
44
|
+
});
|
|
45
|
+
const state: CommitAgentState = { diffText: input.diffText };
|
|
46
|
+
const spawns = "quick_task";
|
|
47
|
+
const tools = createCommitTools({
|
|
48
|
+
cwd: input.cwd,
|
|
49
|
+
git: input.git,
|
|
50
|
+
authStorage: input.authStorage,
|
|
51
|
+
modelRegistry: input.modelRegistry,
|
|
52
|
+
settingsManager: input.settingsManager,
|
|
53
|
+
spawns,
|
|
54
|
+
state,
|
|
55
|
+
changelogTargets: input.changelogTargets,
|
|
56
|
+
enableAnalyzeFiles: true,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const { session } = await createAgentSession({
|
|
60
|
+
cwd: input.cwd,
|
|
61
|
+
authStorage: input.authStorage,
|
|
62
|
+
modelRegistry: input.modelRegistry,
|
|
63
|
+
settingsManager: input.settingsManager,
|
|
64
|
+
model: input.model,
|
|
65
|
+
systemPrompt,
|
|
66
|
+
customTools: tools,
|
|
67
|
+
enableLsp: false,
|
|
68
|
+
enableMCP: false,
|
|
69
|
+
hasUI: false,
|
|
70
|
+
spawns,
|
|
71
|
+
toolNames: ["__none__"],
|
|
72
|
+
contextFiles: input.contextFiles,
|
|
73
|
+
disableExtensionDiscovery: true,
|
|
74
|
+
skills: [],
|
|
75
|
+
promptTemplates: [],
|
|
76
|
+
slashCommands: [],
|
|
77
|
+
});
|
|
78
|
+
let toolCalls = 0;
|
|
79
|
+
let messageCount = 0;
|
|
80
|
+
let isThinking = false;
|
|
81
|
+
let thinkingLineActive = false;
|
|
82
|
+
const toolArgsById = new Map<string, { name: string; args?: Record<string, unknown> }>();
|
|
83
|
+
const writeThinkingLine = (text: string) => {
|
|
84
|
+
const line = chalk.dim(`… ${text}`);
|
|
85
|
+
process.stdout.write(`\r\x1b[2K${line}`);
|
|
86
|
+
thinkingLineActive = true;
|
|
87
|
+
};
|
|
88
|
+
const clearThinkingLine = () => {
|
|
89
|
+
if (!thinkingLineActive) return;
|
|
90
|
+
process.stdout.write("\r\x1b[2K");
|
|
91
|
+
thinkingLineActive = false;
|
|
92
|
+
};
|
|
93
|
+
const unsubscribe = session.subscribe((event: AgentSessionEvent) => {
|
|
94
|
+
switch (event.type) {
|
|
95
|
+
case "message_start":
|
|
96
|
+
if (event.message.role === "assistant") {
|
|
97
|
+
isThinking = true;
|
|
98
|
+
thinkingLineActive = false;
|
|
99
|
+
}
|
|
100
|
+
break;
|
|
101
|
+
case "message_update": {
|
|
102
|
+
if (event.message?.role !== "assistant") break;
|
|
103
|
+
const preview = extractMessagePreview(event.message?.content ?? []);
|
|
104
|
+
if (!preview) break;
|
|
105
|
+
writeThinkingLine(preview);
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
case "tool_execution_start":
|
|
109
|
+
toolCalls += 1;
|
|
110
|
+
toolArgsById.set(event.toolCallId, { name: event.toolName, args: event.args });
|
|
111
|
+
break;
|
|
112
|
+
case "message_end": {
|
|
113
|
+
const role = event.message?.role;
|
|
114
|
+
if (role === "assistant") {
|
|
115
|
+
messageCount += 1;
|
|
116
|
+
isThinking = false;
|
|
117
|
+
clearThinkingLine();
|
|
118
|
+
const messageText = extractMessageText(event.message?.content ?? []);
|
|
119
|
+
if (messageText) {
|
|
120
|
+
writeAssistantMessage(messageText);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
case "tool_execution_end": {
|
|
126
|
+
const stored = toolArgsById.get(event.toolCallId) ?? { name: event.toolName };
|
|
127
|
+
toolArgsById.delete(event.toolCallId);
|
|
128
|
+
clearThinkingLine();
|
|
129
|
+
const toolLabel = formatToolLabel(stored.name);
|
|
130
|
+
const symbol = event.isError ? "" : "";
|
|
131
|
+
writeStdout(`${symbol} ${toolLabel}`);
|
|
132
|
+
const argsLines = formatToolArgs(stored.args);
|
|
133
|
+
if (argsLines.length > 0) {
|
|
134
|
+
writeStdout(formatToolArgsBlock(argsLines));
|
|
135
|
+
}
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
case "agent_end":
|
|
139
|
+
if (isThinking) {
|
|
140
|
+
isThinking = false;
|
|
141
|
+
}
|
|
142
|
+
writeStdout(`● agent finished (${messageCount} messages, ${toolCalls} tools)`);
|
|
143
|
+
break;
|
|
144
|
+
default:
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
try {
|
|
150
|
+
const prompt = renderPromptTemplate(agentUserPrompt, {
|
|
151
|
+
user_context: input.userContext,
|
|
152
|
+
changelog_targets: input.changelogTargets.length > 0 ? input.changelogTargets.join("\n") : undefined,
|
|
153
|
+
existing_changelog_entries: input.existingChangelogEntries,
|
|
154
|
+
});
|
|
155
|
+
const MAX_RETRIES = 3;
|
|
156
|
+
let retryCount = 0;
|
|
157
|
+
const needsChangelog = input.requireChangelog && input.changelogTargets.length > 0;
|
|
158
|
+
|
|
159
|
+
await session.prompt(prompt, { expandPromptTemplates: false });
|
|
160
|
+
while (retryCount < MAX_RETRIES && !isProposalComplete(state, needsChangelog)) {
|
|
161
|
+
retryCount += 1;
|
|
162
|
+
const reminder = buildReminderMessage(state, needsChangelog, retryCount, MAX_RETRIES);
|
|
163
|
+
await session.prompt(reminder, { expandPromptTemplates: false });
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return state;
|
|
167
|
+
} finally {
|
|
168
|
+
unsubscribe();
|
|
169
|
+
await session.dispose();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function writeStdout(message: string): void {
|
|
174
|
+
process.stdout.write(`${message}\n`);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function extractMessagePreview(content: Array<{ type: string; text?: string }>): string | null {
|
|
178
|
+
const textBlocks = content
|
|
179
|
+
.filter((block) => block.type === "text" && typeof block.text === "string")
|
|
180
|
+
.map((block) => block.text?.trim())
|
|
181
|
+
.filter((value): value is string => Boolean(value));
|
|
182
|
+
if (textBlocks.length === 0) return null;
|
|
183
|
+
const combined = textBlocks.join(" ").replace(/\s+/g, " ").trim();
|
|
184
|
+
return truncateToolArg(combined);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function extractMessageText(content: Array<{ type: string; text?: string }>): string | null {
|
|
188
|
+
const textBlocks = content
|
|
189
|
+
.filter((block) => block.type === "text" && typeof block.text === "string")
|
|
190
|
+
.map((block) => block.text ?? "")
|
|
191
|
+
.filter((value) => value.trim().length > 0);
|
|
192
|
+
if (textBlocks.length === 0) return null;
|
|
193
|
+
return textBlocks.join("\n").trim();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function writeAssistantMessage(message: string): void {
|
|
197
|
+
const lines = renderMarkdownLines(message);
|
|
198
|
+
if (lines.length === 0) return;
|
|
199
|
+
let firstContentIndex = lines.findIndex((line) => line.trim().length > 0);
|
|
200
|
+
if (firstContentIndex === -1) {
|
|
201
|
+
firstContentIndex = 0;
|
|
202
|
+
}
|
|
203
|
+
for (const [index, line] of lines.entries()) {
|
|
204
|
+
const prefix = index === firstContentIndex ? "● " : " ";
|
|
205
|
+
writeStdout(`${prefix}${line}`.trimEnd());
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function renderMarkdownLines(message: string): string[] {
|
|
210
|
+
const width = Math.max(40, process.stdout.columns ?? 100);
|
|
211
|
+
const markdown = new Markdown(message, 0, 0, getMarkdownTheme());
|
|
212
|
+
return markdown.render(width);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function formatToolLabel(toolName: string): string {
|
|
216
|
+
const displayName = toolName
|
|
217
|
+
.split(/[_-]/)
|
|
218
|
+
.map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
|
|
219
|
+
.join("");
|
|
220
|
+
return displayName;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function formatToolArgs(args?: Record<string, unknown>): string[] {
|
|
224
|
+
if (!args || Object.keys(args).length === 0) return [];
|
|
225
|
+
const lines: string[] = [];
|
|
226
|
+
const visit = (value: unknown, keyPath: string) => {
|
|
227
|
+
if (value === null || value === undefined) return;
|
|
228
|
+
if (Array.isArray(value)) {
|
|
229
|
+
if (value.length === 0) return;
|
|
230
|
+
const rendered = value.map((item) => renderPrimitive(item)).filter(Boolean);
|
|
231
|
+
if (rendered.length > 0) {
|
|
232
|
+
lines.push(`${keyPath}: ${rendered.join(", ")}`);
|
|
233
|
+
}
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
if (typeof value === "object") {
|
|
237
|
+
const entries = Object.entries(value as Record<string, unknown>);
|
|
238
|
+
if (entries.length === 0) return;
|
|
239
|
+
for (const [childKey, childValue] of entries) {
|
|
240
|
+
visit(childValue, `${keyPath}.${childKey}`);
|
|
241
|
+
}
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
const rendered = renderPrimitive(value);
|
|
245
|
+
if (rendered) {
|
|
246
|
+
lines.push(`${keyPath}: ${rendered}`);
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
for (const [key, value] of Object.entries(args)) {
|
|
250
|
+
visit(value, key);
|
|
251
|
+
}
|
|
252
|
+
return lines;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function renderPrimitive(value: unknown): string | null {
|
|
256
|
+
if (value === null || value === undefined) return null;
|
|
257
|
+
if (typeof value === "string") {
|
|
258
|
+
const trimmed = value.trim();
|
|
259
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
260
|
+
}
|
|
261
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
262
|
+
return String(value);
|
|
263
|
+
}
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function formatToolArgsBlock(lines: string[]): string {
|
|
268
|
+
return lines
|
|
269
|
+
.map((line, index) => {
|
|
270
|
+
if (index === 0) return ` ⎿ ${line}`;
|
|
271
|
+
const branch = index === lines.length - 1 ? "└" : "├";
|
|
272
|
+
return ` ${branch} ${line}`;
|
|
273
|
+
})
|
|
274
|
+
.join("\n");
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function isProposalComplete(state: CommitAgentState, requireChangelog: boolean): boolean {
|
|
278
|
+
const hasCommit = Boolean(state.proposal ?? state.splitProposal);
|
|
279
|
+
const hasChangelog = !requireChangelog || Boolean(state.changelogProposal);
|
|
280
|
+
return hasCommit && hasChangelog;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function buildReminderMessage(
|
|
284
|
+
state: CommitAgentState,
|
|
285
|
+
requireChangelog: boolean,
|
|
286
|
+
retryCount: number,
|
|
287
|
+
maxRetries: number,
|
|
288
|
+
): string {
|
|
289
|
+
const missing: string[] = [];
|
|
290
|
+
if (!state.proposal && !state.splitProposal) {
|
|
291
|
+
missing.push("commit proposal (propose_commit or split_commit)");
|
|
292
|
+
}
|
|
293
|
+
if (requireChangelog && !state.changelogProposal) {
|
|
294
|
+
missing.push("changelog entries (propose_changelog)");
|
|
295
|
+
}
|
|
296
|
+
return `<system-reminder>
|
|
297
|
+
CRITICAL: You must call the required tools before finishing.
|
|
298
|
+
|
|
299
|
+
Missing: ${missing.join(", ") || "none"}.
|
|
300
|
+
Reminder ${retryCount} of ${maxRetries}.
|
|
301
|
+
|
|
302
|
+
Call the missing tool(s) now.
|
|
303
|
+
</system-reminder>`;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function truncateToolArg(value: string): string {
|
|
307
|
+
if (value.length <= 40) return value;
|
|
308
|
+
return `${value.slice(0, 37)}...`;
|
|
309
|
+
}
|