@itsaplan/runner 0.5.0 → 0.5.2

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 (3) hide show
  1. package/README.md +10 -6
  2. package/dist/cli.js +89 -2
  3. package/package.json +4 -2
package/README.md CHANGED
@@ -7,8 +7,8 @@ This package runs such agents on your own machine — one, or several at once.
7
7
 
8
8
  - Polls your instance for the agent's queued runs. Runs each one with a coding agent CLI.
9
9
  Reports the result.
10
- - Has presets for Claude Code, Codex, opencode, Antigravity CLI and GitHub Copilot CLI.
11
- Each preset sets the unattended flags and the session resume.
10
+ - Has presets for Claude Code, Codex, opencode, Antigravity CLI, GitHub Copilot CLI,
11
+ Pi, and Oh My Pi (`omp`). Each preset sets the unattended flags and the session resume.
12
12
  - Runs your own `command` instead, if you prefer. The command takes the task on stdin.
13
13
  - Answers the agent's chat. Sends the text and the tool calls while the CLI prints them.
14
14
 
@@ -20,8 +20,9 @@ of kind External. The key appears one time only, at creation.
20
20
  **2. Enable MCP** for the project, in Settings, MCP Server. MCP is off by default. The
21
21
  agent reads the issue and writes its result through it.
22
22
 
23
- **3. Give the coding agent the address of that server.** Claude Code reads `.mcp.json`
24
- from the folder it runs in. For the other four CLIs, see
23
+ **3. Give the coding agent the address of that server.** Claude Code, Oh My Pi, and Pi
24
+ (through `pi-mcp-adapter`) read `.mcp.json` from the folder they run in. For the other
25
+ CLIs, see
25
26
  [Coding agent setup](https://github.com/croffasia/itsaplan/blob/main/docs/runner.md).
26
27
 
27
28
  ```json
@@ -70,6 +71,8 @@ flags for an unattended run, and the session resume. Every preset keeps a chat s
70
71
  | `opencode` | opencode |
71
72
  | `antigravity` | Antigravity CLI |
72
73
  | `copilot` | GitHub Copilot CLI |
74
+ | `pi` | Pi |
75
+ | `omp` | Oh My Pi |
73
76
 
74
77
  Each preset needs the CLI's own MCP config.
75
78
  [Coding agent setup](https://github.com/croffasia/itsaplan/blob/main/docs/runner.md) holds
@@ -188,7 +191,7 @@ npx -y @itsaplan/runner --agent claude
188
191
  The server writes the task text. The text states what occurred, what to do, and to post
189
192
  the result as a comment on the issue. Your own `command` receives the text on **stdin**. A
190
193
  preset gives it to its CLI in the way that CLI accepts it: on stdin for `claude` and
191
- `codex`, as an argument for `antigravity`, `copilot` and `opencode`.
194
+ `codex`, as an argument for `antigravity`, `copilot`, `opencode`, `pi` and `omp`.
192
195
 
193
196
  The agent reads all other data through the MCP server at `$ITSAPLAN_URL/mcp`. The agent
194
197
  sends `$ITSAPLAN_API_KEY` as a bearer token, and acts as its own user with its role.
@@ -235,7 +238,8 @@ calls with the answer. `outputFormat` tells the runner how to read the output:
235
238
 
236
239
  - `text` — all the output is the answer.
237
240
  - `claude-stream-json`, `codex-jsonl`, `opencode-json`, `antigravity-stream-json`,
238
- `copilot-json` — the event stream of that CLI.
241
+ `copilot-json`, `pi-json` — the event stream of that CLI. `pi` and `omp` both use
242
+ `pi-json`.
239
243
 
240
244
  A preset sets `outputFormat` for you. Set it yourself only with your own `command`. If the
241
245
  output does not agree with the format, the runner sends the output as plain text.
package/dist/cli.js CHANGED
@@ -149,6 +149,43 @@ class AnswerStream {
149
149
  case "copilot-json":
150
150
  this.readCopilotLine(parsed);
151
151
  break;
152
+ case "pi-json":
153
+ this.readPiLine(parsed);
154
+ break;
155
+ }
156
+ }
157
+ readPiLine(message) {
158
+ if (message.type === "session" && message.id)
159
+ this.sessionId ??= message.id;
160
+ switch (message.type) {
161
+ case "message_update": {
162
+ const event = message.assistantMessageEvent;
163
+ if (event?.type === "text_delta" && event.delta) {
164
+ this.sawPartialText = true;
165
+ this.appendText(event.delta);
166
+ }
167
+ return;
168
+ }
169
+ case "tool_execution_start":
170
+ if (message.toolCallId && !this.openToolCalls.has(message.toolCallId)) {
171
+ this.openToolCalls.add(message.toolCallId);
172
+ this.pushToolCall(message.toolCallId, message.toolName ?? "tool", JSON.stringify(message.args ?? {}));
173
+ }
174
+ return;
175
+ case "tool_execution_end": {
176
+ if (!message.toolCallId || this.closedToolCalls.has(message.toolCallId))
177
+ return;
178
+ this.closedToolCalls.add(message.toolCallId);
179
+ this.pushToolResult(message.toolCallId, piResultText(message.result));
180
+ return;
181
+ }
182
+ case "message_end":
183
+ if (message.message?.role === "assistant" && !this.sawAnyText && message.message.content) {
184
+ const body = textOfResult(message.message.content);
185
+ if (body)
186
+ this.appendText(body);
187
+ }
188
+ return;
152
189
  }
153
190
  }
154
191
  readCopilotLine(message) {
@@ -374,6 +411,9 @@ class UsageReader {
374
411
  case "antigravity-stream-json":
375
412
  this.readAntigravity(parsed);
376
413
  return;
414
+ case "pi-json":
415
+ this.readPi(parsed);
416
+ return;
377
417
  }
378
418
  }
379
419
  readClaude(message) {
@@ -422,9 +462,21 @@ class UsageReader {
422
462
  outputTokens: (usage.output_tokens ?? 0) + (usage.thinking_tokens ?? 0)
423
463
  };
424
464
  }
465
+ readPi(message) {
466
+ const usage = message.usage;
467
+ if (!usage)
468
+ return;
469
+ this.last = {
470
+ inputTokens: (usage.input ?? usage.input_tokens ?? 0) + (usage.cacheRead ?? 0),
471
+ outputTokens: usage.output ?? usage.output_tokens ?? 0
472
+ };
473
+ }
425
474
  }
426
475
  function tail(text, limit) {
427
- return text.length <= limit ? text : `…${text.slice(-limit)}`;
476
+ if (text.length <= limit)
477
+ return text;
478
+ const mark = "…";
479
+ return mark + text.slice(-(limit - mark.length));
428
480
  }
429
481
  function textOfResult(content) {
430
482
  if (typeof content === "string")
@@ -434,6 +486,13 @@ function textOfResult(content) {
434
486
  }
435
487
  return "";
436
488
  }
489
+ function piResultText(result) {
490
+ if (result && typeof result === "object" && !Array.isArray(result) && "content" in result) {
491
+ return textOfResult(result.content);
492
+ }
493
+ const text = textOfResult(result);
494
+ return text || (result == null ? "" : JSON.stringify(result));
495
+ }
437
496
 
438
497
  // src/execute.ts
439
498
  import { spawn } from "node:child_process";
@@ -510,6 +569,33 @@ var PRESETS = {
510
569
  ...sessionId ? ["--session-id", sessionId] : []
511
570
  ],
512
571
  tail: ["-p"]
572
+ },
573
+ pi: {
574
+ bin: "pi",
575
+ outputFormat: "pi-json",
576
+ promptVia: "arg",
577
+ systemPromptFlag: "--append-system-prompt",
578
+ head: (sessionId) => [
579
+ "-p",
580
+ "--mode",
581
+ "json",
582
+ ...sessionId ? ["--session-id", sessionId] : []
583
+ ],
584
+ tail: []
585
+ },
586
+ omp: {
587
+ bin: "omp",
588
+ outputFormat: "pi-json",
589
+ promptVia: "arg",
590
+ systemPromptFlag: "--append-system-prompt",
591
+ head: (sessionId) => [
592
+ "-p",
593
+ "--mode",
594
+ "json",
595
+ "--auto-approve",
596
+ ...sessionId ? ["--resume", sessionId] : []
597
+ ],
598
+ tail: []
513
599
  }
514
600
  };
515
601
  var PRESET_NAMES = Object.keys(PRESETS);
@@ -540,7 +626,8 @@ var OUTPUT_FORMATS = [
540
626
  "codex-jsonl",
541
627
  "opencode-json",
542
628
  "antigravity-stream-json",
543
- "copilot-json"
629
+ "copilot-json",
630
+ "pi-json"
544
631
  ];
545
632
  function presetOf(config) {
546
633
  if (config.command || !config.agent)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itsaplan/runner",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "Runs an Itsaplan external agent's queued tasks and answers its chat on your own machine",
5
5
  "keywords": [
6
6
  "itsaplan",
@@ -18,7 +18,9 @@
18
18
  "claude-code",
19
19
  "codex",
20
20
  "antigravity",
21
- "opencode"
21
+ "opencode",
22
+ "pi",
23
+ "omp"
22
24
  ],
23
25
  "homepage": "https://github.com/croffasia/itsaplan/tree/main/packages/runner#readme",
24
26
  "repository": {