@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.
- package/README.md +10 -6
- package/dist/cli.js +89 -2
- 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
|
|
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
|
|
24
|
-
from the folder
|
|
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 `
|
|
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
|
-
|
|
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.
|
|
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": {
|