@oh-my-pi/pi-coding-agent 8.4.5 → 8.6.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.
Files changed (42) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +2 -2
  3. package/docs/rpc.md +32 -15
  4. package/docs/session.md +3 -5
  5. package/docs/tui.md +3 -3
  6. package/package.json +6 -8
  7. package/src/cli/args.ts +4 -0
  8. package/src/export/html/template.css +9 -0
  9. package/src/export/html/template.generated.ts +1 -1
  10. package/src/export/html/template.js +6 -4
  11. package/src/main.ts +3 -1
  12. package/src/mcp/json-rpc.ts +2 -5
  13. package/src/mcp/transports/http.ts +24 -11
  14. package/src/mcp/transports/stdio.ts +17 -12
  15. package/src/migrations.ts +15 -6
  16. package/src/modes/components/model-selector.ts +24 -5
  17. package/src/modes/controllers/event-controller.ts +0 -6
  18. package/src/modes/controllers/input-controller.ts +1 -1
  19. package/src/modes/interactive-mode.ts +1 -20
  20. package/src/modes/rpc/rpc-client.ts +51 -10
  21. package/src/modes/rpc/rpc-mode.ts +25 -19
  22. package/src/modes/types.ts +0 -1
  23. package/src/prompts/agents/plan.md +1 -1
  24. package/src/prompts/system/custom-system-prompt.md +14 -0
  25. package/src/prompts/system/system-prompt.md +12 -0
  26. package/src/prompts/tools/task.md +1 -0
  27. package/src/prompts/tools/todo-write.md +3 -4
  28. package/src/sdk.ts +6 -1
  29. package/src/session/session-manager.ts +84 -80
  30. package/src/system-prompt.ts +26 -1
  31. package/src/task/executor.ts +502 -469
  32. package/src/task/index.ts +58 -11
  33. package/src/task/template.ts +3 -1
  34. package/src/task/types.ts +6 -1
  35. package/src/tools/gemini-image.ts +22 -23
  36. package/src/tools/grep.ts +58 -26
  37. package/src/tools/index.ts +3 -8
  38. package/src/tools/todo-write.ts +7 -7
  39. package/src/prompts/tools/enter-plan-mode.md +0 -98
  40. package/src/task/worker-protocol.ts +0 -130
  41. package/src/task/worker.ts +0 -912
  42. package/src/tools/enter-plan-mode.ts +0 -81
package/CHANGELOG.md CHANGED
@@ -2,6 +2,33 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [8.6.0] - 2026-01-27
6
+
7
+ ### Added
8
+ - Added `plan` model role for specifying the model used by the plan agent
9
+ - Added `--plan` CLI flag and `OMP_PLAN_MODEL` environment variable for ephemeral plan model override
10
+ - Added plan model selection in model selector UI with PLAN badge
11
+
12
+ ### Changed
13
+ - Task tool subagents now execute in-process instead of using worker threads
14
+
15
+ ### Fixed
16
+ - Queued skill commands as follow-ups when the agent is already streaming to avoid load failures
17
+ - Deduplicated repeated review findings in subagent progress rendering
18
+ - Restored MCP proxy tool timeout handling to prevent subagent hangs
19
+
20
+ ## [8.5.0] - 2026-01-27
21
+
22
+ ### Added
23
+ - Added subagent support for preloading skill contents into the system prompt instead of listing available skills
24
+ - Added session init entries to capture system prompt, task, tools, and output schema for subagent session logs
25
+
26
+ ### Fixed
27
+ - Reduced Task tool progress update overhead to keep the UI responsive during high-volume streaming output
28
+ - Fixed subagent session logs dropping pre-assistant entries (user/task metadata) before the first assistant response
29
+
30
+ ### Removed
31
+ - Removed enter-plan-mode tool
5
32
  ## [8.4.5] - 2026-01-26
6
33
 
7
34
  ### 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": "anthropic/claude-sonnet-4-20250514", "slow": "...", "smol": "..."}`) | - |
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
- for line in proc.stdout:
1051
- yield json.loads(line)
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 (Node.js)
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 { spawn } = require("child_process");
1074
- const readline = require("readline");
1075
-
1076
- const agent = spawn("omp", ["--mode", "rpc", "--no-session"]);
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
- if (event.type === "message_update") {
1082
- const { assistantMessageEvent } = event;
1083
- if (assistantMessageEvent.type === "text_delta") {
1084
- process.stdout.write(assistantMessageEvent.delta);
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
- import * as fs from "node:fs";
230
+ const text = await Bun.file("session.jsonl").text();
231
+ const entries = Bun.JSONL.parse(text);
231
232
 
232
- const lines = fs.readFileSync("session.jsonl", "utf8").trim().split("\n");
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 (ignores ANSI codes)
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.4.5",
3
+ "version": "8.6.0",
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.4.5",
87
- "@oh-my-pi/pi-agent-core": "8.4.5",
88
- "@oh-my-pi/pi-ai": "8.4.5",
89
- "@oh-my-pi/pi-tui": "8.4.5",
90
- "@oh-my-pi/pi-utils": "8.4.5",
86
+ "@oh-my-pi/omp-stats": "8.6.0",
87
+ "@oh-my-pi/pi-agent-core": "8.6.0",
88
+ "@oh-my-pi/pi-ai": "8.6.0",
89
+ "@oh-my-pi/pi-tui": "8.6.0",
90
+ "@oh-my-pi/pi-utils": "8.6.0",
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
@@ -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 {