@oh-my-pi/pi-coding-agent 3.13.1337 → 3.15.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 +88 -0
- package/docs/theme.md +38 -5
- package/examples/sdk/11-sessions.ts +2 -2
- package/package.json +7 -4
- package/src/cli/file-processor.ts +51 -2
- package/src/cli/plugin-cli.ts +25 -19
- package/src/cli/update-cli.ts +4 -3
- package/src/core/agent-session.ts +31 -4
- package/src/core/compaction/branch-summarization.ts +4 -32
- package/src/core/compaction/compaction.ts +6 -84
- package/src/core/compaction/utils.ts +2 -3
- package/src/core/custom-tools/types.ts +2 -0
- package/src/core/export-html/index.ts +1 -1
- package/src/core/hooks/index.ts +1 -1
- package/src/core/hooks/tool-wrapper.ts +0 -1
- package/src/core/hooks/types.ts +2 -2
- package/src/core/plugins/doctor.ts +9 -1
- package/src/core/sdk.ts +2 -1
- package/src/core/session-manager.ts +552 -41
- package/src/core/settings-manager.ts +174 -0
- package/src/core/system-prompt.ts +9 -14
- package/src/core/title-generator.ts +2 -8
- package/src/core/tools/ask.ts +19 -37
- package/src/core/tools/bash.ts +2 -37
- package/src/core/tools/edit.ts +2 -9
- package/src/core/tools/exa/render.ts +52 -48
- package/src/core/tools/find.ts +10 -8
- package/src/core/tools/grep.ts +45 -17
- package/src/core/tools/ls.ts +22 -2
- package/src/core/tools/lsp/clients/biome-client.ts +207 -0
- package/src/core/tools/lsp/clients/index.ts +49 -0
- package/src/core/tools/lsp/clients/lsp-linter-client.ts +98 -0
- package/src/core/tools/lsp/config.ts +3 -0
- package/src/core/tools/lsp/index.ts +107 -55
- package/src/core/tools/lsp/render.ts +192 -79
- package/src/core/tools/lsp/types.ts +27 -0
- package/src/core/tools/lsp/utils.ts +62 -22
- package/src/core/tools/notebook.ts +9 -1
- package/src/core/tools/output.ts +37 -14
- package/src/core/tools/read.ts +349 -34
- package/src/core/tools/renderers.ts +290 -89
- package/src/core/tools/review.ts +12 -5
- package/src/core/tools/task/agents.ts +5 -5
- package/src/core/tools/task/commands.ts +3 -3
- package/src/core/tools/task/executor.ts +33 -1
- package/src/core/tools/task/index.ts +93 -6
- package/src/core/tools/task/render.ts +147 -66
- package/src/core/tools/task/types.ts +14 -9
- package/src/core/tools/web-fetch.ts +242 -103
- package/src/core/tools/web-search/index.ts +64 -20
- package/src/core/tools/web-search/providers/exa.ts +68 -172
- package/src/core/tools/web-search/render.ts +264 -74
- package/src/core/tools/write.ts +2 -8
- package/src/main.ts +10 -6
- package/src/modes/cleanup.ts +23 -0
- package/src/modes/index.ts +9 -4
- package/src/modes/interactive/components/bash-execution.ts +6 -3
- package/src/modes/interactive/components/branch-summary-message.ts +1 -1
- package/src/modes/interactive/components/compaction-summary-message.ts +1 -1
- package/src/modes/interactive/components/dynamic-border.ts +1 -1
- package/src/modes/interactive/components/extensions/extension-dashboard.ts +4 -5
- package/src/modes/interactive/components/extensions/extension-list.ts +18 -16
- package/src/modes/interactive/components/extensions/inspector-panel.ts +8 -8
- package/src/modes/interactive/components/hook-message.ts +2 -2
- package/src/modes/interactive/components/hook-selector.ts +1 -1
- package/src/modes/interactive/components/model-selector.ts +22 -9
- package/src/modes/interactive/components/oauth-selector.ts +20 -4
- package/src/modes/interactive/components/plugin-settings.ts +4 -2
- package/src/modes/interactive/components/session-selector.ts +9 -6
- package/src/modes/interactive/components/settings-defs.ts +285 -1
- package/src/modes/interactive/components/settings-selector.ts +176 -3
- package/src/modes/interactive/components/status-line/index.ts +4 -0
- package/src/modes/interactive/components/status-line/presets.ts +94 -0
- package/src/modes/interactive/components/status-line/segments.ts +350 -0
- package/src/modes/interactive/components/status-line/separators.ts +55 -0
- package/src/modes/interactive/components/status-line/types.ts +81 -0
- package/src/modes/interactive/components/status-line-segment-editor.ts +357 -0
- package/src/modes/interactive/components/status-line.ts +169 -233
- package/src/modes/interactive/components/tool-execution.ts +446 -211
- package/src/modes/interactive/components/tree-selector.ts +17 -6
- package/src/modes/interactive/components/ttsr-notification.ts +4 -4
- package/src/modes/interactive/components/welcome.ts +27 -19
- package/src/modes/interactive/interactive-mode.ts +98 -13
- package/src/modes/interactive/theme/dark.json +3 -2
- package/src/modes/interactive/theme/defaults/dark-arctic.json +111 -0
- package/src/modes/interactive/theme/defaults/dark-catppuccin.json +106 -0
- package/src/modes/interactive/theme/defaults/dark-cyberpunk.json +109 -0
- package/src/modes/interactive/theme/defaults/dark-dracula.json +105 -0
- package/src/modes/interactive/theme/defaults/dark-forest.json +103 -0
- package/src/modes/interactive/theme/defaults/dark-github.json +112 -0
- package/src/modes/interactive/theme/defaults/dark-gruvbox.json +119 -0
- package/src/modes/interactive/theme/defaults/dark-monochrome.json +101 -0
- package/src/modes/interactive/theme/defaults/dark-monokai.json +105 -0
- package/src/modes/interactive/theme/defaults/dark-nord.json +104 -0
- package/src/modes/interactive/theme/defaults/dark-ocean.json +108 -0
- package/src/modes/interactive/theme/defaults/dark-one.json +107 -0
- package/src/modes/interactive/theme/defaults/dark-retro.json +99 -0
- package/src/modes/interactive/theme/defaults/dark-rose-pine.json +95 -0
- package/src/modes/interactive/theme/defaults/dark-solarized.json +96 -0
- package/src/modes/interactive/theme/defaults/dark-sunset.json +106 -0
- package/src/modes/interactive/theme/defaults/dark-synthwave.json +102 -0
- package/src/modes/interactive/theme/defaults/dark-tokyo-night.json +108 -0
- package/src/modes/interactive/theme/defaults/index.ts +67 -0
- package/src/modes/interactive/theme/defaults/light-arctic.json +106 -0
- package/src/modes/interactive/theme/defaults/light-catppuccin.json +105 -0
- package/src/modes/interactive/theme/defaults/light-cyberpunk.json +103 -0
- package/src/modes/interactive/theme/defaults/light-forest.json +107 -0
- package/src/modes/interactive/theme/defaults/light-github.json +114 -0
- package/src/modes/interactive/theme/defaults/light-gruvbox.json +115 -0
- package/src/modes/interactive/theme/defaults/light-monochrome.json +100 -0
- package/src/modes/interactive/theme/defaults/light-ocean.json +106 -0
- package/src/modes/interactive/theme/defaults/light-one.json +105 -0
- package/src/modes/interactive/theme/defaults/light-retro.json +105 -0
- package/src/modes/interactive/theme/defaults/light-solarized.json +101 -0
- package/src/modes/interactive/theme/defaults/light-sunset.json +106 -0
- package/src/modes/interactive/theme/defaults/light-synthwave.json +105 -0
- package/src/modes/interactive/theme/defaults/light-tokyo-night.json +118 -0
- package/src/modes/interactive/theme/light.json +3 -2
- package/src/modes/interactive/theme/theme-schema.json +120 -4
- package/src/modes/interactive/theme/theme.ts +1228 -14
- package/src/prompts/branch-summary-preamble.md +3 -0
- package/src/prompts/branch-summary.md +28 -0
- package/src/prompts/compaction-summary.md +34 -0
- package/src/prompts/compaction-turn-prefix.md +16 -0
- package/src/prompts/compaction-update-summary.md +41 -0
- package/src/prompts/init.md +30 -0
- package/src/{core/tools/task/bundled-agents → prompts}/reviewer.md +6 -0
- package/src/prompts/summarization-system.md +3 -0
- package/src/prompts/system-prompt.md +27 -0
- package/src/{core/tools/task/bundled-agents → prompts}/task.md +2 -0
- package/src/prompts/title-system.md +8 -0
- package/src/prompts/tools/ask.md +24 -0
- package/src/prompts/tools/bash.md +23 -0
- package/src/prompts/tools/edit.md +9 -0
- package/src/prompts/tools/find.md +6 -0
- package/src/prompts/tools/grep.md +12 -0
- package/src/prompts/tools/lsp.md +14 -0
- package/src/prompts/tools/output.md +23 -0
- package/src/prompts/tools/read.md +25 -0
- package/src/prompts/tools/web-fetch.md +8 -0
- package/src/prompts/tools/web-search.md +10 -0
- package/src/prompts/tools/write.md +10 -0
- package/src/commands/init.md +0 -20
- /package/src/{core/tools/task/bundled-commands → prompts}/architect-plan.md +0 -0
- /package/src/{core/tools/task/bundled-agents → prompts}/browser.md +0 -0
- /package/src/{core/tools/task/bundled-agents → prompts}/explore.md +0 -0
- /package/src/{core/tools/task/bundled-commands → prompts}/implement-with-critic.md +0 -0
- /package/src/{core/tools/task/bundled-commands → prompts}/implement.md +0 -0
- /package/src/{core/tools/task/bundled-agents → prompts}/plan.md +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,94 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [3.15.0] - 2026-01-05
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added spinner type variants (status and activity) with distinct animation frames per symbol preset
|
|
10
|
+
- Added animated spinner for task tool progress display during subagent execution
|
|
11
|
+
- Added language/file type icons for read tool output with support for 35+ file types
|
|
12
|
+
- Added async cleanup registry for graceful session flush on SIGINT, SIGTERM, and SIGHUP signals
|
|
13
|
+
- Added subagent token usage aggregation to session statistics and task tool results
|
|
14
|
+
- Added streaming NDJSON writer for session persistence with proper backpressure handling
|
|
15
|
+
- Added `flush()` method to SessionManager for explicit control over pending write completion
|
|
16
|
+
- Added `/exit` slash command to exit the application from interactive mode
|
|
17
|
+
- Added fuzzy path matching suggestions when read tool encounters file-not-found errors, showing closest matches using Levenshtein distance
|
|
18
|
+
- Added `status.shadowed` symbol for theme customization to properly indicate shadowed extension state
|
|
19
|
+
- Added Biome CLI-based linter client as alternative to LSP for more reliable diagnostics
|
|
20
|
+
- Added LinterClient interface for pluggable formatter/linter implementations
|
|
21
|
+
- Added status line segment editor for arranging and toggling status line components
|
|
22
|
+
- Added status line presets (default, minimal, compact, developer, balanced) for quick configuration
|
|
23
|
+
- Added status line separator styles (powerline, powerline-thin, arrow, slash, pipe, space)
|
|
24
|
+
- Added configurable status line segments including time, hostname, and subagent count
|
|
25
|
+
- Added symbol customization via theme overrides for icons, separators, and glyphs
|
|
26
|
+
- Added 30+ built-in color themes including Catppuccin, Dracula, Nord, Gruvbox, Tokyo Night, and more
|
|
27
|
+
- Added configurable status line with customizable segments, presets, and separators
|
|
28
|
+
- Added status line segment editor for arranging and toggling status line components
|
|
29
|
+
- Added symbol preset setting to switch between Unicode, Nerd Font, and ASCII glyphs
|
|
30
|
+
- Added file size limit (20MB) for image files to prevent memory issues during serialization
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
|
|
34
|
+
- Changed `isError` property in tool result events to be optional instead of required
|
|
35
|
+
- Changed `SessionManager.open()` and `SessionManager.continueRecent()` to async methods for proper initialization
|
|
36
|
+
- Changed session file writes to use atomic rename pattern with fsync for crash-safe persistence
|
|
37
|
+
- Changed read tool display to show file type icons and metadata inline with path
|
|
38
|
+
- Changed `AgentSession.dispose()` to async method that flushes pending writes before cleanup
|
|
39
|
+
- Changed read tool result display to hide content by default with expand hint, showing only metadata until expanded
|
|
40
|
+
- Changed diagnostics display to group messages by file with tree structure and severity icons
|
|
41
|
+
- Changed diff stats formatting to use colored +/- indicators with slash separators
|
|
42
|
+
- Changed session persistence to use streaming writes instead of synchronous file appends for better performance
|
|
43
|
+
- Changed read tool to automatically redirect to ls when given a directory path instead of a file
|
|
44
|
+
- Changed tool description prompts to be more concise with clearer usage guidelines and structured formatting
|
|
45
|
+
- Moved tool description prompts from inline strings to external markdown files in `src/prompts/tools/` directory for better maintainability
|
|
46
|
+
- Changed Exa web search provider from MCP protocol to direct REST API for simpler integration
|
|
47
|
+
- Changed web search result rendering to handle malformed response data with fallback text display
|
|
48
|
+
- Changed compaction prompts to preserve tool outputs, command results, and repository state in context summaries
|
|
49
|
+
- Changed init prompt to include runtime/tooling preferences section and improved formatting guidelines
|
|
50
|
+
- Changed reviewer prompt to require evidence-backed findings anchored to diff hunks with stricter suggestion block formatting
|
|
51
|
+
- Changed system prompt to include explicit core behavior guidelines for task completion and progress updates
|
|
52
|
+
- Changed task prompt to emphasize end-to-end task completion and tool verification
|
|
53
|
+
- Moved all prompt templates from inline strings to external markdown files in `src/prompts/` directory for better maintainability
|
|
54
|
+
- Changed tool result renderers to use structured tree layouts with consistent expand hints and truncation indicators
|
|
55
|
+
- Changed grep, find, and ls tools to show scope path and detailed truncation reasons in output
|
|
56
|
+
- Changed web search and web fetch result rendering to display structured metadata sections with bounded content previews
|
|
57
|
+
- Changed task/subagent progress rendering to use badge-style status labels and structured output sections
|
|
58
|
+
- Changed notebook tool to display cell content preview with line counts
|
|
59
|
+
- Changed ask tool result to show checkbox-style selection indicators
|
|
60
|
+
- Changed output tool to include provenance metadata and content previews for retrieved outputs
|
|
61
|
+
- Changed collapsed tool views to show consistent "Ctrl+O to expand" hints with remaining item counts
|
|
62
|
+
- Changed Biome integration to use CLI instead of LSP to avoid stale diagnostics issues
|
|
63
|
+
- Changed hardcoded UI symbols throughout codebase to use theme-configurable glyphs
|
|
64
|
+
- Changed tree drawing characters to use theme-defined box-drawing symbols
|
|
65
|
+
- Changed status line rendering to support left/right segment positioning with separators
|
|
66
|
+
- Changed hardcoded UI symbols to use theme-configurable glyphs throughout the interface
|
|
67
|
+
- Changed tree drawing characters to use theme-defined box-drawing symbols
|
|
68
|
+
- Changed CLI image attachments to resize if larger than 2048px (fit within 1920x1080) and convert >2MB images to JPEG
|
|
69
|
+
|
|
70
|
+
### Removed
|
|
71
|
+
|
|
72
|
+
- Removed custom renderers for ls, find, and grep tools in favor of generic tool display
|
|
73
|
+
|
|
74
|
+
### Fixed
|
|
75
|
+
|
|
76
|
+
- Fixed spinner animation crash when spinner frames array is empty by adding length check
|
|
77
|
+
- Fixed session persistence to properly await all queued writes before closing or switching sessions
|
|
78
|
+
- Fixed session persistence to truncate oversized content blocks before writing to prevent memory exhaustion
|
|
79
|
+
- Fixed extension list and inspector panel to use correct symbols for disabled and shadowed states instead of reusing unrelated status icons
|
|
80
|
+
- Fixed token counting for subagent progress to handle different usage object formats (camelCase and snake_case)
|
|
81
|
+
- Fixed image file handling by adding 20MB size limit to prevent memory issues during serialization
|
|
82
|
+
- Fixed session persistence to truncate oversized entries before writing JSONL to prevent out-of-memory errors
|
|
83
|
+
|
|
84
|
+
## [3.14.0] - 2026-01-04
|
|
85
|
+
### Added
|
|
86
|
+
|
|
87
|
+
- Added `getUsageStatistics()` method to SessionManager for tracking cumulative token usage and costs across session messages
|
|
88
|
+
|
|
89
|
+
### Changed
|
|
90
|
+
|
|
91
|
+
- Changed status line to display usage statistics more efficiently by using centralized session statistics instead of recalculating from entries
|
|
92
|
+
|
|
5
93
|
## [3.13.1337] - 2026-01-04
|
|
6
94
|
|
|
7
95
|
## [3.9.1337] - 2026-01-04
|
package/docs/theme.md
CHANGED
|
@@ -132,7 +132,7 @@ Themes are defined in JSON files with the following structure:
|
|
|
132
132
|
|
|
133
133
|
```json
|
|
134
134
|
{
|
|
135
|
-
"$schema": "https://raw.githubusercontent.com/
|
|
135
|
+
"$schema": "https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/theme-schema.json",
|
|
136
136
|
"name": "my-theme",
|
|
137
137
|
"vars": {
|
|
138
138
|
"blue": "#0066cc",
|
|
@@ -149,6 +149,39 @@ Themes are defined in JSON files with the following structure:
|
|
|
149
149
|
}
|
|
150
150
|
```
|
|
151
151
|
|
|
152
|
+
## Symbols
|
|
153
|
+
|
|
154
|
+
Themes can also customize specific UI symbols (icons, separators, bullets, etc.). Use `symbols.preset` to set a theme default (overridden by user settings), and `symbols.overrides` to override individual keys.
|
|
155
|
+
|
|
156
|
+
Example:
|
|
157
|
+
|
|
158
|
+
```json
|
|
159
|
+
{
|
|
160
|
+
"symbols": {
|
|
161
|
+
"preset": "ascii",
|
|
162
|
+
"overrides": {
|
|
163
|
+
"icon.model": "[M]",
|
|
164
|
+
"sep.powerlineLeft": ">",
|
|
165
|
+
"sep.powerlineRight": "<"
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Symbol keys by category:
|
|
172
|
+
|
|
173
|
+
- Status: `status.success`, `status.error`, `status.warning`, `status.info`, `status.pending`, `status.disabled`, `status.enabled`, `status.running`, `status.shadowed`, `status.aborted`
|
|
174
|
+
- Navigation: `nav.cursor`, `nav.selected`, `nav.expand`, `nav.collapse`, `nav.back`
|
|
175
|
+
- Tree: `tree.branch`, `tree.last`, `tree.vertical`, `tree.horizontal`, `tree.hook`
|
|
176
|
+
- Boxes (rounded): `boxRound.topLeft`, `boxRound.topRight`, `boxRound.bottomLeft`, `boxRound.bottomRight`, `boxRound.horizontal`, `boxRound.vertical`
|
|
177
|
+
- Boxes (sharp): `boxSharp.topLeft`, `boxSharp.topRight`, `boxSharp.bottomLeft`, `boxSharp.bottomRight`, `boxSharp.horizontal`, `boxSharp.vertical`, `boxSharp.cross`, `boxSharp.teeDown`, `boxSharp.teeUp`, `boxSharp.teeRight`, `boxSharp.teeLeft`
|
|
178
|
+
- Separators: `sep.powerline`, `sep.powerlineThin`, `sep.powerlineLeft`, `sep.powerlineRight`, `sep.powerlineThinLeft`, `sep.powerlineThinRight`, `sep.dot`, `sep.slash`, `sep.pipe`
|
|
179
|
+
- Icons: `icon.model`, `icon.folder`, `icon.file`, `icon.git`, `icon.branch`, `icon.tokens`, `icon.context`, `icon.cost`, `icon.time`, `icon.pi`, `icon.agents`, `icon.cache`, `icon.input`, `icon.output`, `icon.host`, `icon.session`, `icon.package`, `icon.warning`, `icon.rewind`, `icon.auto`, `icon.extensionSkill`, `icon.extensionTool`, `icon.extensionSlashCommand`, `icon.extensionMcp`, `icon.extensionRule`, `icon.extensionHook`, `icon.extensionPrompt`, `icon.extensionContextFile`, `icon.extensionInstruction`
|
|
180
|
+
- Thinking: `thinking.minimal`, `thinking.low`, `thinking.medium`, `thinking.high`, `thinking.xhigh`
|
|
181
|
+
- Checkboxes: `checkbox.checked`, `checkbox.unchecked`
|
|
182
|
+
- Formatting: `format.ellipsis`, `format.bullet`, `format.dash`
|
|
183
|
+
- Markdown: `md.quoteBorder`, `md.hrChar`, `md.bullet`
|
|
184
|
+
|
|
152
185
|
### Color Values
|
|
153
186
|
|
|
154
187
|
Four formats are supported:
|
|
@@ -253,7 +286,7 @@ Custom themes are loaded from `~/.omp/agent/themes/*.json`.
|
|
|
253
286
|
|
|
254
287
|
```json
|
|
255
288
|
{
|
|
256
|
-
"$schema": "https://raw.githubusercontent.com/
|
|
289
|
+
"$schema": "https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/theme-schema.json",
|
|
257
290
|
"name": "my-theme",
|
|
258
291
|
"vars": {
|
|
259
292
|
"primary": "#00aaff",
|
|
@@ -448,14 +481,14 @@ Error loading theme 'my-theme':
|
|
|
448
481
|
For editor support, the JSON schema is available at:
|
|
449
482
|
|
|
450
483
|
```
|
|
451
|
-
https://raw.githubusercontent.com/
|
|
484
|
+
https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/theme-schema.json
|
|
452
485
|
```
|
|
453
486
|
|
|
454
487
|
Add to your theme file for auto-completion and validation:
|
|
455
488
|
|
|
456
489
|
```json
|
|
457
490
|
{
|
|
458
|
-
"$schema": "https://raw.githubusercontent.com/
|
|
491
|
+
"$schema": "https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/theme-schema.json",
|
|
459
492
|
...
|
|
460
493
|
}
|
|
461
494
|
```
|
|
@@ -552,7 +585,7 @@ function getMarkdownTheme(): MarkdownTheme {
|
|
|
552
585
|
}
|
|
553
586
|
|
|
554
587
|
// Create markdown with theme
|
|
555
|
-
const md = new Markdown(text, 1, 1, { bgColor: theme.bg("userMessageBg") }
|
|
588
|
+
const md = new Markdown(text, 1, 1, getMarkdownTheme(), { bgColor: theme.bg("userMessageBg") });
|
|
556
589
|
```
|
|
557
590
|
|
|
558
591
|
This approach:
|
|
@@ -20,7 +20,7 @@ console.log("New session file:", newSession.sessionFile);
|
|
|
20
20
|
|
|
21
21
|
// Continue most recent session (or create new if none)
|
|
22
22
|
const { session: continued, modelFallbackMessage } = await createAgentSession({
|
|
23
|
-
sessionManager: SessionManager.continueRecent(process.cwd()),
|
|
23
|
+
sessionManager: await SessionManager.continueRecent(process.cwd()),
|
|
24
24
|
});
|
|
25
25
|
if (modelFallbackMessage) console.log("Note:", modelFallbackMessage);
|
|
26
26
|
console.log("Continued session:", continued.sessionFile);
|
|
@@ -34,7 +34,7 @@ for (const info of sessions.slice(0, 3)) {
|
|
|
34
34
|
|
|
35
35
|
if (sessions.length > 0) {
|
|
36
36
|
const { session: opened } = await createAgentSession({
|
|
37
|
-
sessionManager: SessionManager.open(sessions[0].path),
|
|
37
|
+
sessionManager: await SessionManager.open(sessions[0].path),
|
|
38
38
|
});
|
|
39
39
|
console.log(`\nOpened: ${opened.sessionId}`);
|
|
40
40
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.15.0",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"ompConfig": {
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
"prepublishOnly": "bun run generate-template && bun run clean && bun run build"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@oh-my-pi/pi-agent-core": "3.
|
|
43
|
-
"@oh-my-pi/pi-ai": "3.
|
|
44
|
-
"@oh-my-pi/pi-tui": "3.
|
|
42
|
+
"@oh-my-pi/pi-agent-core": "3.15.0",
|
|
43
|
+
"@oh-my-pi/pi-ai": "3.15.0",
|
|
44
|
+
"@oh-my-pi/pi-tui": "3.15.0",
|
|
45
45
|
"@sinclair/typebox": "^0.34.46",
|
|
46
46
|
"ajv": "^8.17.1",
|
|
47
47
|
"chalk": "^5.5.0",
|
|
@@ -53,15 +53,18 @@
|
|
|
53
53
|
"marked": "^15.0.12",
|
|
54
54
|
"minimatch": "^10.1.1",
|
|
55
55
|
"nanoid": "^5.1.6",
|
|
56
|
+
"ndjson": "^2.0.0",
|
|
56
57
|
"node-html-parser": "^6.1.13",
|
|
57
58
|
"smol-toml": "^1.6.0",
|
|
58
59
|
"strip-ansi": "^7.1.2",
|
|
60
|
+
"sharp": "^0.34.2",
|
|
59
61
|
"winston": "^3.17.0",
|
|
60
62
|
"winston-daily-rotate-file": "^5.0.0",
|
|
61
63
|
"yaml": "^2.8.2"
|
|
62
64
|
},
|
|
63
65
|
"devDependencies": {
|
|
64
66
|
"@types/diff": "^7.0.2",
|
|
67
|
+
"@types/ndjson": "^2.0.4",
|
|
65
68
|
"@types/node": "^24.3.0",
|
|
66
69
|
"vitest": "^3.2.4"
|
|
67
70
|
},
|
|
@@ -6,6 +6,7 @@ import { access, readFile, stat } from "node:fs/promises";
|
|
|
6
6
|
import { resolve } from "node:path";
|
|
7
7
|
import type { ImageContent } from "@oh-my-pi/pi-ai";
|
|
8
8
|
import chalk from "chalk";
|
|
9
|
+
import sharp from "sharp";
|
|
9
10
|
import { resolveReadPath } from "../core/tools/path-utils";
|
|
10
11
|
import { detectSupportedImageMimeTypeFromFile } from "../utils/mime";
|
|
11
12
|
|
|
@@ -14,6 +15,53 @@ export interface ProcessedFiles {
|
|
|
14
15
|
images: ImageContent[];
|
|
15
16
|
}
|
|
16
17
|
|
|
18
|
+
const RESIZE_TRIGGER_MAX_DIMENSION = 2048;
|
|
19
|
+
const MAX_RESIZE_WIDTH = 1920;
|
|
20
|
+
const MAX_RESIZE_HEIGHT = 1080;
|
|
21
|
+
const JPEG_CONVERT_THRESHOLD_BYTES = 2 * 1024 * 1024;
|
|
22
|
+
const JPEG_QUALITY = 85;
|
|
23
|
+
|
|
24
|
+
async function processImageAttachment(buffer: Buffer, mimeType: string): Promise<{ buffer: Buffer; mimeType: string }> {
|
|
25
|
+
const metadata = await sharp(buffer, { failOnError: false }).metadata();
|
|
26
|
+
const width = metadata.width ?? 0;
|
|
27
|
+
const height = metadata.height ?? 0;
|
|
28
|
+
const maxDim = Math.max(width, height);
|
|
29
|
+
const shouldResize = width > 0 && height > 0 && maxDim > RESIZE_TRIGGER_MAX_DIMENSION;
|
|
30
|
+
const shouldConvertToJpeg = buffer.length > JPEG_CONVERT_THRESHOLD_BYTES;
|
|
31
|
+
|
|
32
|
+
if (!shouldResize && !shouldConvertToJpeg) {
|
|
33
|
+
return { buffer, mimeType };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let pipeline = sharp(buffer, { failOnError: false });
|
|
37
|
+
if (shouldResize) {
|
|
38
|
+
pipeline = pipeline.resize({
|
|
39
|
+
width: MAX_RESIZE_WIDTH,
|
|
40
|
+
height: MAX_RESIZE_HEIGHT,
|
|
41
|
+
fit: "inside",
|
|
42
|
+
withoutEnlargement: true,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (shouldConvertToJpeg) {
|
|
47
|
+
pipeline = pipeline.jpeg({ quality: JPEG_QUALITY });
|
|
48
|
+
return { buffer: await pipeline.toBuffer(), mimeType: "image/jpeg" };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (mimeType === "image/png") {
|
|
52
|
+
pipeline = pipeline.png();
|
|
53
|
+
} else if (mimeType === "image/webp") {
|
|
54
|
+
pipeline = pipeline.webp();
|
|
55
|
+
} else if (mimeType === "image/gif") {
|
|
56
|
+
pipeline = pipeline.gif();
|
|
57
|
+
} else {
|
|
58
|
+
pipeline = pipeline.jpeg({ quality: JPEG_QUALITY });
|
|
59
|
+
return { buffer: await pipeline.toBuffer(), mimeType: "image/jpeg" };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return { buffer: await pipeline.toBuffer(), mimeType };
|
|
63
|
+
}
|
|
64
|
+
|
|
17
65
|
/** Process @file arguments into text content and image attachments */
|
|
18
66
|
export async function processFileArguments(fileArgs: string[]): Promise<ProcessedFiles> {
|
|
19
67
|
let text = "";
|
|
@@ -43,11 +91,12 @@ export async function processFileArguments(fileArgs: string[]): Promise<Processe
|
|
|
43
91
|
if (mimeType) {
|
|
44
92
|
// Handle image file
|
|
45
93
|
const content = await readFile(absolutePath);
|
|
46
|
-
const
|
|
94
|
+
const processed = await processImageAttachment(content, mimeType);
|
|
95
|
+
const base64Content = processed.buffer.toString("base64");
|
|
47
96
|
|
|
48
97
|
const attachment: ImageContent = {
|
|
49
98
|
type: "image",
|
|
50
|
-
mimeType,
|
|
99
|
+
mimeType: processed.mimeType,
|
|
51
100
|
data: base64Content,
|
|
52
101
|
};
|
|
53
102
|
|
package/src/cli/plugin-cli.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import chalk from "chalk";
|
|
8
8
|
import { APP_NAME } from "../config";
|
|
9
9
|
import { PluginManager, parseSettingValue, validateSetting } from "../core/plugins/index";
|
|
10
|
+
import { theme } from "../modes/interactive/theme/theme";
|
|
10
11
|
|
|
11
12
|
// =============================================================================
|
|
12
13
|
// Types
|
|
@@ -173,7 +174,7 @@ async function handleInstall(
|
|
|
173
174
|
if (flags.dryRun) {
|
|
174
175
|
console.log(chalk.dim(`[dry-run] Would install ${spec}`));
|
|
175
176
|
} else {
|
|
176
|
-
console.log(chalk.green(
|
|
177
|
+
console.log(chalk.green(`${theme.status.success} Installed ${result.name}@${result.version}`));
|
|
177
178
|
if (result.enabledFeatures && result.enabledFeatures.length > 0) {
|
|
178
179
|
console.log(chalk.dim(` Features: ${result.enabledFeatures.join(", ")}`));
|
|
179
180
|
}
|
|
@@ -183,7 +184,7 @@ async function handleInstall(
|
|
|
183
184
|
}
|
|
184
185
|
}
|
|
185
186
|
} catch (err) {
|
|
186
|
-
console.error(chalk.red(
|
|
187
|
+
console.error(chalk.red(`${theme.status.error} Failed to install ${spec}: ${err}`));
|
|
187
188
|
process.exit(1);
|
|
188
189
|
}
|
|
189
190
|
}
|
|
@@ -202,10 +203,10 @@ async function handleUninstall(manager: PluginManager, packages: string[], flags
|
|
|
202
203
|
if (flags.json) {
|
|
203
204
|
console.log(JSON.stringify({ uninstalled: name }));
|
|
204
205
|
} else {
|
|
205
|
-
console.log(chalk.green(
|
|
206
|
+
console.log(chalk.green(`${theme.status.success} Uninstalled ${name}`));
|
|
206
207
|
}
|
|
207
208
|
} catch (err) {
|
|
208
|
-
console.error(chalk.red(
|
|
209
|
+
console.error(chalk.red(`${theme.status.error} Failed to uninstall ${name}: ${err}`));
|
|
209
210
|
process.exit(1);
|
|
210
211
|
}
|
|
211
212
|
}
|
|
@@ -226,8 +227,9 @@ async function handleList(manager: PluginManager, flags: { json?: boolean }): Pr
|
|
|
226
227
|
}
|
|
227
228
|
|
|
228
229
|
console.log(chalk.bold("Installed Plugins:\n"));
|
|
230
|
+
|
|
229
231
|
for (const plugin of plugins) {
|
|
230
|
-
const status = plugin.enabled ? chalk.green(
|
|
232
|
+
const status = plugin.enabled ? chalk.green(theme.status.enabled) : chalk.dim(theme.status.disabled);
|
|
231
233
|
const nameVersion = `${plugin.name}@${plugin.version}`;
|
|
232
234
|
console.log(`${status} ${nameVersion}`);
|
|
233
235
|
|
|
@@ -265,10 +267,10 @@ async function handleLink(manager: PluginManager, paths: string[], flags: { json
|
|
|
265
267
|
if (flags.json) {
|
|
266
268
|
console.log(JSON.stringify(result, null, 2));
|
|
267
269
|
} else {
|
|
268
|
-
console.log(chalk.green(
|
|
270
|
+
console.log(chalk.green(`${theme.status.success} Linked ${result.name} from ${paths[0]}`));
|
|
269
271
|
}
|
|
270
272
|
} catch (err) {
|
|
271
|
-
console.error(chalk.red(
|
|
273
|
+
console.error(chalk.red(`${theme.status.error} Failed to link: ${err}`));
|
|
272
274
|
process.exit(1);
|
|
273
275
|
}
|
|
274
276
|
}
|
|
@@ -285,10 +287,14 @@ async function handleDoctor(manager: PluginManager, flags: { json?: boolean; fix
|
|
|
285
287
|
|
|
286
288
|
for (const check of checks) {
|
|
287
289
|
const icon =
|
|
288
|
-
check.status === "ok"
|
|
290
|
+
check.status === "ok"
|
|
291
|
+
? chalk.green(theme.status.success)
|
|
292
|
+
: check.status === "warning"
|
|
293
|
+
? chalk.yellow(theme.status.warning)
|
|
294
|
+
: chalk.red(theme.status.error);
|
|
289
295
|
console.log(`${icon} ${check.name}: ${check.message}`);
|
|
290
296
|
if (check.fixed) {
|
|
291
|
-
console.log(chalk.dim(`
|
|
297
|
+
console.log(chalk.dim(` ${theme.nav.cursor} Fixed`));
|
|
292
298
|
}
|
|
293
299
|
}
|
|
294
300
|
|
|
@@ -361,7 +367,7 @@ async function handleFeatures(
|
|
|
361
367
|
}
|
|
362
368
|
|
|
363
369
|
await manager.setEnabledFeatures(pluginName, [...currentFeatures]);
|
|
364
|
-
console.log(chalk.green(
|
|
370
|
+
console.log(chalk.green(`${theme.status.success} Updated features for ${pluginName}`));
|
|
365
371
|
}
|
|
366
372
|
|
|
367
373
|
// Display current state
|
|
@@ -392,7 +398,7 @@ async function handleFeatures(
|
|
|
392
398
|
const enabledSet = new Set(updatedFeatures ?? []);
|
|
393
399
|
for (const [name, feat] of Object.entries(plugin.manifest.features)) {
|
|
394
400
|
const enabled = enabledSet.has(name);
|
|
395
|
-
const icon = enabled ? chalk.green(
|
|
401
|
+
const icon = enabled ? chalk.green(theme.status.enabled) : chalk.dim(theme.status.disabled);
|
|
396
402
|
const defaultLabel = feat.default ? chalk.dim(" (default)") : "";
|
|
397
403
|
console.log(`${icon} ${name}${defaultLabel}`);
|
|
398
404
|
if (feat.description) {
|
|
@@ -507,7 +513,7 @@ async function handleConfig(
|
|
|
507
513
|
}
|
|
508
514
|
|
|
509
515
|
manager.setPluginSetting(pluginName, key, value);
|
|
510
|
-
console.log(chalk.green(
|
|
516
|
+
console.log(chalk.green(`${theme.status.success} Set ${key}`));
|
|
511
517
|
break;
|
|
512
518
|
}
|
|
513
519
|
|
|
@@ -518,7 +524,7 @@ async function handleConfig(
|
|
|
518
524
|
}
|
|
519
525
|
|
|
520
526
|
manager.deletePluginSetting(pluginName, key);
|
|
521
|
-
console.log(chalk.green(
|
|
527
|
+
console.log(chalk.green(`${theme.status.success} Deleted ${key}`));
|
|
522
528
|
break;
|
|
523
529
|
}
|
|
524
530
|
|
|
@@ -554,10 +560,10 @@ async function handleConfigValidate(manager: PluginManager, flags: { json?: bool
|
|
|
554
560
|
}
|
|
555
561
|
|
|
556
562
|
if (results.length === 0) {
|
|
557
|
-
console.log(chalk.green(
|
|
563
|
+
console.log(chalk.green(`${theme.status.success} All settings valid`));
|
|
558
564
|
} else {
|
|
559
565
|
for (const { plugin, key, error } of results) {
|
|
560
|
-
console.log(chalk.red(
|
|
566
|
+
console.log(chalk.red(`${theme.status.error} ${plugin}.${key}: ${error}`));
|
|
561
567
|
}
|
|
562
568
|
process.exit(1);
|
|
563
569
|
}
|
|
@@ -576,10 +582,10 @@ async function handleEnable(manager: PluginManager, plugins: string[], flags: {
|
|
|
576
582
|
if (flags.json) {
|
|
577
583
|
console.log(JSON.stringify({ enabled: name }));
|
|
578
584
|
} else {
|
|
579
|
-
console.log(chalk.green(
|
|
585
|
+
console.log(chalk.green(`${theme.status.success} Enabled ${name}`));
|
|
580
586
|
}
|
|
581
587
|
} catch (err) {
|
|
582
|
-
console.error(chalk.red(
|
|
588
|
+
console.error(chalk.red(`${theme.status.error} Failed to enable ${name}: ${err}`));
|
|
583
589
|
process.exit(1);
|
|
584
590
|
}
|
|
585
591
|
}
|
|
@@ -598,10 +604,10 @@ async function handleDisable(manager: PluginManager, plugins: string[], flags: {
|
|
|
598
604
|
if (flags.json) {
|
|
599
605
|
console.log(JSON.stringify({ disabled: name }));
|
|
600
606
|
} else {
|
|
601
|
-
console.log(chalk.green(
|
|
607
|
+
console.log(chalk.green(`${theme.status.success} Disabled ${name}`));
|
|
602
608
|
}
|
|
603
609
|
} catch (err) {
|
|
604
|
-
console.error(chalk.red(
|
|
610
|
+
console.error(chalk.red(`${theme.status.error} Failed to disable ${name}: ${err}`));
|
|
605
611
|
process.exit(1);
|
|
606
612
|
}
|
|
607
613
|
}
|
package/src/cli/update-cli.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { Readable } from "node:stream";
|
|
|
12
12
|
import { pipeline } from "node:stream/promises";
|
|
13
13
|
import chalk from "chalk";
|
|
14
14
|
import { APP_NAME, VERSION } from "../config";
|
|
15
|
+
import { theme } from "../modes/interactive/theme/theme";
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Detect if we're running as a Bun compiled binary.
|
|
@@ -142,7 +143,7 @@ async function updateViaBun(): Promise<void> {
|
|
|
142
143
|
|
|
143
144
|
try {
|
|
144
145
|
execSync(`bun update -g ${PACKAGE}`, { stdio: "inherit" });
|
|
145
|
-
console.log(chalk.green(
|
|
146
|
+
console.log(chalk.green(`\n${theme.status.success} Update complete`));
|
|
146
147
|
} catch {
|
|
147
148
|
throw new Error("bun update failed");
|
|
148
149
|
}
|
|
@@ -192,7 +193,7 @@ async function updateViaBinary(release: ReleaseInfo): Promise<void> {
|
|
|
192
193
|
// Clean up backup
|
|
193
194
|
unlinkSync(backupPath);
|
|
194
195
|
|
|
195
|
-
console.log(chalk.green(`\n
|
|
196
|
+
console.log(chalk.green(`\n${theme.status.success} Updated to ${release.version}`));
|
|
196
197
|
console.log(chalk.dim(`Restart ${APP_NAME} to use the new version`));
|
|
197
198
|
} catch (err) {
|
|
198
199
|
// Restore from backup if possible
|
|
@@ -224,7 +225,7 @@ export async function runUpdateCommand(opts: { force: boolean; check: boolean })
|
|
|
224
225
|
const comparison = compareVersions(release.version, VERSION);
|
|
225
226
|
|
|
226
227
|
if (comparison <= 0 && !opts.force) {
|
|
227
|
-
console.log(chalk.green(
|
|
228
|
+
console.log(chalk.green(`${theme.status.success} Already up to date`));
|
|
228
229
|
return;
|
|
229
230
|
}
|
|
230
231
|
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import type { Agent, AgentEvent, AgentMessage, AgentState, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
17
|
-
import type { AssistantMessage, ImageContent, Message, Model, TextContent } from "@oh-my-pi/pi-ai";
|
|
17
|
+
import type { AssistantMessage, ImageContent, Message, Model, TextContent, Usage } from "@oh-my-pi/pi-ai";
|
|
18
18
|
import { isContextOverflow, modelsAreEqual, supportsXhigh } from "@oh-my-pi/pi-ai";
|
|
19
19
|
import type { Rule } from "../capability/rule";
|
|
20
20
|
import { getAuthPath } from "../config";
|
|
@@ -479,10 +479,11 @@ export class AgentSession {
|
|
|
479
479
|
}
|
|
480
480
|
|
|
481
481
|
/**
|
|
482
|
-
* Remove all listeners and disconnect from agent.
|
|
482
|
+
* Remove all listeners, flush pending writes, and disconnect from agent.
|
|
483
483
|
* Call this when completely done with the session.
|
|
484
484
|
*/
|
|
485
|
-
dispose(): void {
|
|
485
|
+
async dispose(): Promise<void> {
|
|
486
|
+
await this.sessionManager.flush();
|
|
486
487
|
this._disconnectFromAgent();
|
|
487
488
|
this._eventListeners = [];
|
|
488
489
|
}
|
|
@@ -841,6 +842,7 @@ export class AgentSession {
|
|
|
841
842
|
this._disconnectFromAgent();
|
|
842
843
|
await this.abort();
|
|
843
844
|
this.agent.reset();
|
|
845
|
+
await this.sessionManager.flush();
|
|
844
846
|
this.sessionManager.newSession(options);
|
|
845
847
|
this._queuedMessages = [];
|
|
846
848
|
this._reconnectToAgent();
|
|
@@ -1636,8 +1638,11 @@ export class AgentSession {
|
|
|
1636
1638
|
await this.abort();
|
|
1637
1639
|
this._queuedMessages = [];
|
|
1638
1640
|
|
|
1641
|
+
// Flush pending writes before switching
|
|
1642
|
+
await this.sessionManager.flush();
|
|
1643
|
+
|
|
1639
1644
|
// Set new session
|
|
1640
|
-
this.sessionManager.setSessionFile(sessionPath);
|
|
1645
|
+
await this.sessionManager.setSessionFile(sessionPath);
|
|
1641
1646
|
|
|
1642
1647
|
// Reload messages
|
|
1643
1648
|
const sessionContext = this.sessionManager.buildSessionContext();
|
|
@@ -1714,6 +1719,9 @@ export class AgentSession {
|
|
|
1714
1719
|
skipConversationRestore = result?.skipConversationRestore ?? false;
|
|
1715
1720
|
}
|
|
1716
1721
|
|
|
1722
|
+
// Flush pending writes before branching
|
|
1723
|
+
await this.sessionManager.flush();
|
|
1724
|
+
|
|
1717
1725
|
if (!selectedEntry.parentId) {
|
|
1718
1726
|
this.sessionManager.newSession();
|
|
1719
1727
|
} else {
|
|
@@ -1955,6 +1963,14 @@ export class AgentSession {
|
|
|
1955
1963
|
let totalCacheWrite = 0;
|
|
1956
1964
|
let totalCost = 0;
|
|
1957
1965
|
|
|
1966
|
+
const getTaskToolUsage = (details: unknown): Usage | undefined => {
|
|
1967
|
+
if (!details || typeof details !== "object") return undefined;
|
|
1968
|
+
const record = details as Record<string, unknown>;
|
|
1969
|
+
const usage = record.usage;
|
|
1970
|
+
if (!usage || typeof usage !== "object") return undefined;
|
|
1971
|
+
return usage as Usage;
|
|
1972
|
+
};
|
|
1973
|
+
|
|
1958
1974
|
for (const message of state.messages) {
|
|
1959
1975
|
if (message.role === "assistant") {
|
|
1960
1976
|
const assistantMsg = message as AssistantMessage;
|
|
@@ -1965,6 +1981,17 @@ export class AgentSession {
|
|
|
1965
1981
|
totalCacheWrite += assistantMsg.usage.cacheWrite;
|
|
1966
1982
|
totalCost += assistantMsg.usage.cost.total;
|
|
1967
1983
|
}
|
|
1984
|
+
|
|
1985
|
+
if (message.role === "toolResult" && message.toolName === "task") {
|
|
1986
|
+
const usage = getTaskToolUsage(message.details);
|
|
1987
|
+
if (usage) {
|
|
1988
|
+
totalInput += usage.input;
|
|
1989
|
+
totalOutput += usage.output;
|
|
1990
|
+
totalCacheRead += usage.cacheRead;
|
|
1991
|
+
totalCacheWrite += usage.cacheWrite;
|
|
1992
|
+
totalCost += usage.cost.total;
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1968
1995
|
}
|
|
1969
1996
|
|
|
1970
1997
|
return {
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
|
|
9
9
|
import type { Model } from "@oh-my-pi/pi-ai";
|
|
10
10
|
import { completeSimple } from "@oh-my-pi/pi-ai";
|
|
11
|
+
import branchSummaryPrompt from "../../prompts/branch-summary.md" with { type: "text" };
|
|
12
|
+
import branchSummaryPreamble from "../../prompts/branch-summary-preamble.md" with { type: "text" };
|
|
11
13
|
import {
|
|
12
14
|
convertToLlm,
|
|
13
15
|
createBranchSummaryMessage,
|
|
@@ -235,39 +237,9 @@ export function prepareBranchEntries(entries: SessionEntry[], tokenBudget: numbe
|
|
|
235
237
|
// Summary Generation
|
|
236
238
|
// ============================================================================
|
|
237
239
|
|
|
238
|
-
const BRANCH_SUMMARY_PREAMBLE =
|
|
239
|
-
Summary of that exploration:
|
|
240
|
+
const BRANCH_SUMMARY_PREAMBLE = branchSummaryPreamble;
|
|
240
241
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
const BRANCH_SUMMARY_PROMPT = `Create a structured summary of this conversation branch for context when returning later.
|
|
244
|
-
|
|
245
|
-
Use this EXACT format:
|
|
246
|
-
|
|
247
|
-
## Goal
|
|
248
|
-
[What was the user trying to accomplish in this branch?]
|
|
249
|
-
|
|
250
|
-
## Constraints & Preferences
|
|
251
|
-
- [Any constraints, preferences, or requirements mentioned]
|
|
252
|
-
- [Or "(none)" if none were mentioned]
|
|
253
|
-
|
|
254
|
-
## Progress
|
|
255
|
-
### Done
|
|
256
|
-
- [x] [Completed tasks/changes]
|
|
257
|
-
|
|
258
|
-
### In Progress
|
|
259
|
-
- [ ] [Work that was started but not finished]
|
|
260
|
-
|
|
261
|
-
### Blocked
|
|
262
|
-
- [Issues preventing progress, if any]
|
|
263
|
-
|
|
264
|
-
## Key Decisions
|
|
265
|
-
- **[Decision]**: [Brief rationale]
|
|
266
|
-
|
|
267
|
-
## Next Steps
|
|
268
|
-
1. [What should happen next to continue this work]
|
|
269
|
-
|
|
270
|
-
Keep each section concise. Preserve exact file paths, function names, and error messages.`;
|
|
242
|
+
const BRANCH_SUMMARY_PROMPT = branchSummaryPrompt;
|
|
271
243
|
|
|
272
244
|
/**
|
|
273
245
|
* Generate a summary of abandoned branch entries.
|