@oh-my-pi/pi-coding-agent 8.5.0 → 8.8.8
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 +23 -0
- package/README.md +2 -2
- package/docs/rpc.md +32 -15
- package/docs/session.md +3 -5
- package/docs/tui.md +3 -3
- package/package.json +6 -8
- package/src/cli/args.ts +4 -0
- package/src/commit/agentic/prompts/analyze-file.md +1 -1
- package/src/commit/agentic/tools/analyze-file.ts +1 -1
- package/src/config/prompt-templates.ts +3 -0
- package/src/config/settings-manager.ts +19 -1
- package/src/export/html/template.css +9 -0
- package/src/export/html/template.generated.ts +1 -1
- package/src/export/html/template.js +6 -4
- package/src/extensibility/extensions/index.ts +2 -0
- package/src/extensibility/extensions/runner.ts +13 -2
- package/src/extensibility/extensions/types.ts +17 -2
- package/src/extensibility/hooks/runner.ts +13 -2
- package/src/extensibility/hooks/types.ts +22 -3
- package/src/ipy/executor.ts +2 -3
- package/src/ipy/kernel.ts +0 -42
- package/src/main.ts +3 -1
- package/src/mcp/json-rpc.ts +2 -5
- package/src/mcp/transports/http.ts +24 -11
- package/src/mcp/transports/stdio.ts +17 -12
- package/src/migrations.ts +15 -6
- package/src/modes/components/compaction-summary-message.ts +3 -0
- package/src/modes/components/model-selector.ts +24 -5
- package/src/modes/components/user-message.ts +7 -3
- package/src/modes/controllers/command-controller.ts +35 -1
- package/src/modes/controllers/event-controller.ts +5 -2
- package/src/modes/controllers/input-controller.ts +6 -1
- package/src/modes/interactive-mode.ts +6 -0
- package/src/modes/rpc/rpc-client.ts +51 -10
- package/src/modes/rpc/rpc-mode.ts +25 -19
- package/src/modes/types.ts +1 -0
- package/src/modes/utils/ui-helpers.ts +2 -2
- package/src/prompts/agents/explore.md +1 -1
- package/src/prompts/agents/plan.md +1 -1
- package/src/prompts/agents/reviewer.md +5 -3
- package/src/prompts/compaction/branch-summary-context.md +5 -0
- package/src/prompts/compaction/compaction-short-summary.md +9 -0
- package/src/prompts/compaction/compaction-summary-context.md +5 -0
- package/src/prompts/compaction/compaction-summary.md +13 -7
- package/src/prompts/compaction/compaction-update-summary.md +6 -2
- package/src/prompts/review-request.md +1 -1
- package/src/prompts/system/subagent-system-prompt.md +24 -0
- package/src/prompts/system/system-prompt.md +1 -0
- package/src/prompts/tools/task-summary.md +35 -0
- package/src/prompts/tools/task.md +28 -30
- package/src/prompts/tools/todo-write.md +3 -4
- package/src/sdk.ts +5 -4
- package/src/session/agent-session.ts +168 -8
- package/src/session/compaction/branch-summarization.ts +1 -1
- package/src/session/compaction/compaction.ts +154 -0
- package/src/session/compaction/pruning.ts +91 -0
- package/src/session/messages.ts +32 -17
- package/src/session/session-manager.ts +134 -80
- package/src/task/executor.ts +559 -495
- package/src/task/index.ts +39 -18
- package/src/task/render.ts +101 -12
- package/src/task/types.ts +3 -3
- package/src/tools/gemini-image.ts +22 -23
- package/src/tools/grep.ts +58 -26
- package/src/tools/index.ts +12 -14
- package/src/tools/jtd-to-typescript.ts +198 -0
- package/src/tools/review.ts +3 -3
- package/src/tools/{complete.ts → submit-result.ts} +10 -10
- package/src/tools/todo-write.ts +7 -7
- package/src/task/worker-protocol.ts +0 -131
- package/src/task/worker.ts +0 -921
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [8.8.8] - 2026-01-28
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- Added `/fork` command to create a new session with the exact same state (entries and artifacts) as the current session
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- Renamed the `complete` tool to `submit_result` for subagent result submission
|
|
12
|
+
|
|
13
|
+
## [8.6.0] - 2026-01-27
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- Added `plan` model role for specifying the model used by the plan agent
|
|
17
|
+
- Added `--plan` CLI flag and `OMP_PLAN_MODEL` environment variable for ephemeral plan model override
|
|
18
|
+
- Added plan model selection in model selector UI with PLAN badge
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- Task tool subagents now execute in-process instead of using worker threads
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
- Queued skill commands as follow-ups when the agent is already streaming to avoid load failures
|
|
25
|
+
- Deduplicated repeated review findings in subagent progress rendering
|
|
26
|
+
- Restored MCP proxy tool timeout handling to prevent subagent hangs
|
|
27
|
+
|
|
5
28
|
## [8.5.0] - 2026-01-27
|
|
6
29
|
|
|
7
30
|
### Added
|
package/README.md
CHANGED
|
@@ -263,7 +263,7 @@ The agent reads, writes, and edits files, and executes commands via bash.
|
|
|
263
263
|
| Ctrl+D | Exit (when editor is empty) |
|
|
264
264
|
| Ctrl+Z | Suspend to background (use `fg` in shell to resume) |
|
|
265
265
|
| Shift+Tab | Cycle thinking level |
|
|
266
|
-
| Ctrl+P / Shift+Ctrl+P | Cycle role models (slow/default/smol)
|
|
266
|
+
| Ctrl+P / Shift+Ctrl+P | Cycle role models (slow/default/smol/plan) |
|
|
267
267
|
| Ctrl+L | Open model selector |
|
|
268
268
|
| Ctrl+O | Toggle tool output expansion |
|
|
269
269
|
| Ctrl+T | Toggle todo list expansion |
|
|
@@ -564,7 +564,7 @@ Global `~/.omp/agent/settings.json` stores persistent preferences:
|
|
|
564
564
|
| Setting | Description | Default |
|
|
565
565
|
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | --------------- |
|
|
566
566
|
| `theme` | Color theme name | auto-detected |
|
|
567
|
-
| `modelRoles` | Model assignments by role (e.g., `{"default": "
|
|
567
|
+
| `modelRoles` | Model assignments by role (e.g., `{"default": "...", "slow": "...", "smol": "...", "plan": "..."}`) | - |
|
|
568
568
|
| `defaultThinkingLevel` | Thinking level: `off`, `minimal`, `low`, `medium`, `high`, `xhigh` | - |
|
|
569
569
|
| `enabledModels` | Model patterns for cycling. Supports glob patterns (`github-copilot/*`, `*sonnet*`) and fuzzy matching. Same as `--models` CLI flag | - |
|
|
570
570
|
| `queueMode` | Message queue mode: `all` or `one-at-a-time` | `one-at-a-time` |
|
package/docs/rpc.md
CHANGED
|
@@ -23,6 +23,8 @@ Common options:
|
|
|
23
23
|
- **Responses**: JSON objects with `type: "response"` indicating command success/failure
|
|
24
24
|
- **Events**: Agent events streamed to stdout as JSON lines
|
|
25
25
|
|
|
26
|
+
If you're consuming output in Bun, prefer `Bun.JSONL.parse(text)` for buffered JSONL or `Bun.JSONL.parseChunk()` for streaming output instead of splitting and `JSON.parse`.
|
|
27
|
+
|
|
26
28
|
All commands support an optional `id` field for request/response correlation. If provided, the corresponding response will include the same `id`.
|
|
27
29
|
|
|
28
30
|
## Commands
|
|
@@ -1034,6 +1036,7 @@ Created by the `bash` RPC command (not by LLM tool calls):
|
|
|
1034
1036
|
```python
|
|
1035
1037
|
import subprocess
|
|
1036
1038
|
import json
|
|
1039
|
+
import jsonlines
|
|
1037
1040
|
|
|
1038
1041
|
proc = subprocess.Popen(
|
|
1039
1042
|
["omp", "--mode", "rpc", "--no-session"],
|
|
@@ -1047,8 +1050,9 @@ def send(cmd):
|
|
|
1047
1050
|
proc.stdin.flush()
|
|
1048
1051
|
|
|
1049
1052
|
def read_events():
|
|
1050
|
-
|
|
1051
|
-
|
|
1053
|
+
with jsonlines.Reader(proc.stdout) as reader:
|
|
1054
|
+
for event in reader:
|
|
1055
|
+
yield event
|
|
1052
1056
|
|
|
1053
1057
|
# Send prompt
|
|
1054
1058
|
send({"type": "prompt", "message": "Hello!"})
|
|
@@ -1065,26 +1069,39 @@ for event in read_events():
|
|
|
1065
1069
|
break
|
|
1066
1070
|
```
|
|
1067
1071
|
|
|
1068
|
-
## Example: Interactive Client (
|
|
1072
|
+
## Example: Interactive Client (Bun)
|
|
1069
1073
|
|
|
1070
1074
|
See [`test/rpc-example.ts`](../test/rpc-example.ts) for a complete interactive example, or [`src/modes/rpc/rpc-client.ts`](../src/modes/rpc/rpc-client.ts) for a typed client implementation.
|
|
1071
1075
|
|
|
1072
1076
|
```javascript
|
|
1073
|
-
const
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
readline.createInterface({ input: agent.stdout }).on("line", (line) => {
|
|
1079
|
-
const event = JSON.parse(line);
|
|
1077
|
+
const agent = Bun.spawn(["omp", "--mode", "rpc", "--no-session"], {
|
|
1078
|
+
stdin: "pipe",
|
|
1079
|
+
stdout: "pipe",
|
|
1080
|
+
});
|
|
1080
1081
|
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1082
|
+
const decoder = new TextDecoder();
|
|
1083
|
+
let buffer = "";
|
|
1084
|
+
|
|
1085
|
+
async function readEvents() {
|
|
1086
|
+
const reader = agent.stdout.getReader();
|
|
1087
|
+
while (true) {
|
|
1088
|
+
const { value, done } = await reader.read();
|
|
1089
|
+
if (done) break;
|
|
1090
|
+
buffer += decoder.decode(value, { stream: true });
|
|
1091
|
+
const result = Bun.JSONL.parseChunk(buffer);
|
|
1092
|
+
buffer = buffer.slice(result.read);
|
|
1093
|
+
for (const event of result.values) {
|
|
1094
|
+
if (event.type === "message_update") {
|
|
1095
|
+
const { assistantMessageEvent } = event;
|
|
1096
|
+
if (assistantMessageEvent.type === "text_delta") {
|
|
1097
|
+
process.stdout.write(assistantMessageEvent.delta);
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1085
1100
|
}
|
|
1086
1101
|
}
|
|
1087
|
-
}
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
readEvents();
|
|
1088
1105
|
|
|
1089
1106
|
// Send prompt
|
|
1090
1107
|
agent.stdin.write(JSON.stringify({ type: "prompt", message: "Hello" }) + "\n");
|
package/docs/session.md
CHANGED
|
@@ -227,12 +227,10 @@ Entries form a tree:
|
|
|
227
227
|
## Parsing Example
|
|
228
228
|
|
|
229
229
|
```typescript
|
|
230
|
-
|
|
230
|
+
const text = await Bun.file("session.jsonl").text();
|
|
231
|
+
const entries = Bun.JSONL.parse(text);
|
|
231
232
|
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
for (const line of lines) {
|
|
235
|
-
const entry = JSON.parse(line);
|
|
233
|
+
for (const entry of entries) {
|
|
236
234
|
|
|
237
235
|
switch (entry.type) {
|
|
238
236
|
case "session":
|
package/docs/tui.md
CHANGED
|
@@ -153,7 +153,7 @@ handleInput(data: string) {
|
|
|
153
153
|
|
|
154
154
|
## Line Width
|
|
155
155
|
|
|
156
|
-
**Critical:** Each line from `render()` must not exceed the `width` parameter.
|
|
156
|
+
**Critical:** Each line from `render()` must not exceed the `width` parameter. Width calculations and wrapping follow Bun’s built-ins (`Bun.stringWidth`, `Bun.wrapAnsi`).
|
|
157
157
|
|
|
158
158
|
```typescript
|
|
159
159
|
import { visibleWidth, truncateToWidth } from "@oh-my-pi/pi-tui";
|
|
@@ -166,9 +166,9 @@ render(width: number): string[] {
|
|
|
166
166
|
|
|
167
167
|
Utilities:
|
|
168
168
|
|
|
169
|
-
- `visibleWidth(str)` - Get display width (
|
|
169
|
+
- `visibleWidth(str)` - Get display width (ANSI-safe, Unicode-width aware)
|
|
170
170
|
- `truncateToWidth(str, width, ellipsis?)` - Truncate with optional ellipsis
|
|
171
|
-
- `wrapTextWithAnsi(str, width)` - Word wrap preserving ANSI codes
|
|
171
|
+
- `wrapTextWithAnsi(str, width)` - Word wrap preserving ANSI codes (Bun.wrapAnsi)
|
|
172
172
|
|
|
173
173
|
## Creating Custom Components
|
|
174
174
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.8.8",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"ompConfig": {
|
|
@@ -83,11 +83,11 @@
|
|
|
83
83
|
"test": "bun test"
|
|
84
84
|
},
|
|
85
85
|
"dependencies": {
|
|
86
|
-
"@oh-my-pi/omp-stats": "8.
|
|
87
|
-
"@oh-my-pi/pi-agent-core": "8.
|
|
88
|
-
"@oh-my-pi/pi-ai": "8.
|
|
89
|
-
"@oh-my-pi/pi-tui": "8.
|
|
90
|
-
"@oh-my-pi/pi-utils": "8.
|
|
86
|
+
"@oh-my-pi/omp-stats": "8.8.8",
|
|
87
|
+
"@oh-my-pi/pi-agent-core": "8.8.8",
|
|
88
|
+
"@oh-my-pi/pi-ai": "8.8.8",
|
|
89
|
+
"@oh-my-pi/pi-tui": "8.8.8",
|
|
90
|
+
"@oh-my-pi/pi-utils": "8.8.8",
|
|
91
91
|
"@openai/agents": "^0.4.3",
|
|
92
92
|
"@sinclair/typebox": "^0.34.46",
|
|
93
93
|
"ajv": "^8.17.1",
|
|
@@ -100,7 +100,6 @@
|
|
|
100
100
|
"highlight.js": "^11.11.1",
|
|
101
101
|
"marked": "^17.0.1",
|
|
102
102
|
"nanoid": "^5.1.6",
|
|
103
|
-
"ndjson": "^2.0.0",
|
|
104
103
|
"node-html-parser": "^7.0.2",
|
|
105
104
|
"smol-toml": "^1.6.0",
|
|
106
105
|
"strip-ansi": "^7.1.2",
|
|
@@ -109,7 +108,6 @@
|
|
|
109
108
|
"devDependencies": {
|
|
110
109
|
"@types/diff": "^8.0.0",
|
|
111
110
|
"@types/ms": "^2.1.0",
|
|
112
|
-
"@types/ndjson": "^2.0.4",
|
|
113
111
|
"@types/node": "^25.0.10",
|
|
114
112
|
"ms": "^2.1.3"
|
|
115
113
|
},
|
package/src/cli/args.ts
CHANGED
|
@@ -15,6 +15,7 @@ export interface Args {
|
|
|
15
15
|
model?: string;
|
|
16
16
|
smol?: string;
|
|
17
17
|
slow?: string;
|
|
18
|
+
plan?: string;
|
|
18
19
|
apiKey?: string;
|
|
19
20
|
systemPrompt?: string;
|
|
20
21
|
appendSystemPrompt?: string;
|
|
@@ -85,6 +86,8 @@ export function parseArgs(args: string[], extensionFlags?: Map<string, { type: "
|
|
|
85
86
|
result.smol = args[++i];
|
|
86
87
|
} else if (arg === "--slow" && i + 1 < args.length) {
|
|
87
88
|
result.slow = args[++i];
|
|
89
|
+
} else if (arg === "--plan" && i + 1 < args.length) {
|
|
90
|
+
result.plan = args[++i];
|
|
88
91
|
} else if (arg === "--api-key" && i + 1 < args.length) {
|
|
89
92
|
result.apiKey = args[++i];
|
|
90
93
|
} else if (arg === "--system-prompt" && i + 1 < args.length) {
|
|
@@ -193,6 +196,7 @@ ${chalk.bold("Options:")}
|
|
|
193
196
|
--model <pattern> Model to use (fuzzy match: "opus", "gpt-5.2", or "p-openai/gpt-5.2")
|
|
194
197
|
--smol <id> Smol/fast model for lightweight tasks (or OMP_SMOL_MODEL env)
|
|
195
198
|
--slow <id> Slow/reasoning model for thorough analysis (or OMP_SLOW_MODEL env)
|
|
199
|
+
--plan <id> Plan model for architectural planning (or OMP_PLAN_MODEL env)
|
|
196
200
|
--api-key <key> API key (defaults to env vars)
|
|
197
201
|
--system-prompt <text> System prompt (default: coding assistant prompt)
|
|
198
202
|
--append-system-prompt <text> Append text or file contents to the system prompt
|
|
@@ -82,7 +82,7 @@ export function createAnalyzeFileTool(options: {
|
|
|
82
82
|
const taskParams: TaskParams = {
|
|
83
83
|
agent: "quick_task",
|
|
84
84
|
context,
|
|
85
|
-
|
|
85
|
+
schema: analyzeFileOutputSchema,
|
|
86
86
|
tasks,
|
|
87
87
|
};
|
|
88
88
|
return taskTool.execute(toolCallId, taskParams, signal, onUpdate);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
|
+
import { jtdToTypeScript } from "@oh-my-pi/pi-coding-agent/tools/jtd-to-typescript";
|
|
2
3
|
import { logger } from "@oh-my-pi/pi-utils";
|
|
3
4
|
import Handlebars from "handlebars";
|
|
4
5
|
import { CONFIG_DIR_NAME, getPromptsDir } from "../config";
|
|
@@ -222,6 +223,8 @@ handlebars.registerHelper("includes", (collection: unknown, item: unknown): bool
|
|
|
222
223
|
*/
|
|
223
224
|
handlebars.registerHelper("not", (value: unknown): boolean => !value);
|
|
224
225
|
|
|
226
|
+
handlebars.registerHelper("jtdToTypeScript", (schema: unknown): string => jtdToTypeScript(schema));
|
|
227
|
+
|
|
225
228
|
export function renderPromptTemplate(template: string, context: TemplateContext = {}): string {
|
|
226
229
|
const compiled = handlebars.compile(template, { noEscape: true, strict: false });
|
|
227
230
|
const rendered = compiled(context ?? {});
|
|
@@ -13,6 +13,8 @@ export interface CompactionSettings {
|
|
|
13
13
|
enabled?: boolean; // default: true
|
|
14
14
|
reserveTokens?: number; // default: 16384
|
|
15
15
|
keepRecentTokens?: number; // default: 20000
|
|
16
|
+
autoContinue?: boolean; // default: true
|
|
17
|
+
remoteEndpoint?: string;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
export interface BranchSummarySettings {
|
|
@@ -838,11 +840,27 @@ export class SettingsManager {
|
|
|
838
840
|
return this.settings.compaction?.keepRecentTokens ?? 20000;
|
|
839
841
|
}
|
|
840
842
|
|
|
841
|
-
|
|
843
|
+
getCompactionAutoContinue(): boolean {
|
|
844
|
+
return this.settings.compaction?.autoContinue ?? true;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
getCompactionRemoteEndpoint(): string | undefined {
|
|
848
|
+
return this.settings.compaction?.remoteEndpoint;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
getCompactionSettings(): {
|
|
852
|
+
enabled: boolean;
|
|
853
|
+
reserveTokens: number;
|
|
854
|
+
keepRecentTokens: number;
|
|
855
|
+
autoContinue: boolean;
|
|
856
|
+
remoteEndpoint?: string;
|
|
857
|
+
} {
|
|
842
858
|
return {
|
|
843
859
|
enabled: this.getCompactionEnabled(),
|
|
844
860
|
reserveTokens: this.getCompactionReserveTokens(),
|
|
845
861
|
keepRecentTokens: this.getCompactionKeepRecentTokens(),
|
|
862
|
+
autoContinue: this.getCompactionAutoContinue(),
|
|
863
|
+
remoteEndpoint: this.getCompactionRemoteEndpoint(),
|
|
846
864
|
};
|
|
847
865
|
}
|
|
848
866
|
|
|
@@ -137,6 +137,15 @@
|
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
.tree-node.in-path {
|
|
140
|
+
background: color-mix(in srgb, var(--accent) 10%, transparent);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.tree-node:not(.in-path) {
|
|
144
|
+
opacity: 0.5;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.tree-node:not(.in-path):hover {
|
|
148
|
+
opacity: 1;
|
|
140
149
|
}
|
|
141
150
|
|
|
142
151
|
.tree-prefix {
|