@itsaplan/runner 0.7.0 → 0.8.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/README.md +19 -17
- package/dist/cli.js +66 -4
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -8,7 +8,8 @@ This package runs such agents on your own machine — one, or several at once.
|
|
|
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
10
|
- Has presets for Claude Code, Codex, opencode, Antigravity CLI, GitHub Copilot CLI,
|
|
11
|
-
Pi,
|
|
11
|
+
Pi, Oh My Pi (`omp`), and Mastra Code. Each preset sets the unattended flags and the
|
|
12
|
+
session resume.
|
|
12
13
|
- Runs your own `command` instead, if you prefer. The command takes the task on stdin.
|
|
13
14
|
- Answers the agent's chat. Sends the text and the tool calls while the CLI prints them.
|
|
14
15
|
- Sends the messages and the tool calls of a queued run to the issue while the run works.
|
|
@@ -23,9 +24,9 @@ of kind External. The key appears one time only, at creation.
|
|
|
23
24
|
**2. Enable MCP** for the project, in Settings, MCP Server. MCP is off by default. The
|
|
24
25
|
agent reads the issue and writes its result through it.
|
|
25
26
|
|
|
26
|
-
**3. Give the coding agent the address of that server.** Claude Code, Oh My Pi,
|
|
27
|
-
(through `pi-mcp-adapter`) read `.mcp.json` from the folder they run in. For
|
|
28
|
-
CLIs, see
|
|
27
|
+
**3. Give the coding agent the address of that server.** Claude Code, Oh My Pi, Mastra
|
|
28
|
+
Code, and Pi (through `pi-mcp-adapter`) read `.mcp.json` from the folder they run in. For
|
|
29
|
+
the other CLIs, see
|
|
29
30
|
[Coding agent setup](https://github.com/croffasia/itsaplan/blob/main/docs/runner.md).
|
|
30
31
|
|
|
31
32
|
```json
|
|
@@ -67,15 +68,16 @@ or mention it in a comment. The task then starts in your terminal.
|
|
|
67
68
|
`agent` names a CLI that the runner knows. The runner then builds the command itself: the
|
|
68
69
|
flags for an unattended run, and the session resume. Every preset keeps a chat session.
|
|
69
70
|
|
|
70
|
-
| Agent | Runs
|
|
71
|
-
| ------------- |
|
|
72
|
-
| `claude` | Claude Code
|
|
73
|
-
| `codex` | Codex CLI
|
|
74
|
-
| `opencode` | opencode
|
|
75
|
-
| `antigravity` | Antigravity CLI
|
|
76
|
-
| `copilot` | GitHub Copilot CLI
|
|
77
|
-
| `pi` | Pi
|
|
78
|
-
| `omp` | Oh My Pi
|
|
71
|
+
| Agent | Runs |
|
|
72
|
+
| ------------- | ---------------------------------------------------------------------------- |
|
|
73
|
+
| `claude` | [Claude Code](https://code.claude.com/docs/en/overview) |
|
|
74
|
+
| `codex` | [Codex CLI](https://github.com/openai/codex) |
|
|
75
|
+
| `opencode` | [opencode](https://opencode.ai) |
|
|
76
|
+
| `antigravity` | [Antigravity CLI](https://antigravity.google/docs/getting-started?tab=cli) |
|
|
77
|
+
| `copilot` | [GitHub Copilot CLI](https://github.com/github/copilot-cli) |
|
|
78
|
+
| `pi` | [Pi](https://pi.dev) |
|
|
79
|
+
| `omp` | [Oh My Pi](https://omp.sh) |
|
|
80
|
+
| `mastracode` | [Mastra Code](https://code.mastra.ai) |
|
|
79
81
|
|
|
80
82
|
Each preset needs the CLI's own MCP config.
|
|
81
83
|
[Coding agent setup](https://github.com/croffasia/itsaplan/blob/main/docs/runner.md) holds
|
|
@@ -273,8 +275,8 @@ npx -y @itsaplan/runner --agent claude
|
|
|
273
275
|
|
|
274
276
|
The server writes the task text. The text states what occurred, what to do, and to post
|
|
275
277
|
the result as a comment on the issue. Your own `command` receives the text on **stdin**. A
|
|
276
|
-
preset gives it to its CLI in the way that CLI accepts it: on stdin for `claude`, `codex
|
|
277
|
-
and `
|
|
278
|
+
preset gives it to its CLI in the way that CLI accepts it: on stdin for `claude`, `codex`,
|
|
279
|
+
`pi` and `mastracode`, as an argument for `antigravity`, `copilot`, `opencode` and `omp`.
|
|
278
280
|
|
|
279
281
|
The agent reads all other data through the MCP server at `$ITSAPLAN_URL/mcp`. The agent
|
|
280
282
|
sends `$ITSAPLAN_API_KEY` as a bearer token, and acts as its own user with its role.
|
|
@@ -323,8 +325,8 @@ error.
|
|
|
323
325
|
|
|
324
326
|
- `text` — all of stdout is the answer.
|
|
325
327
|
- `claude-stream-json`, `codex-jsonl`, `opencode-json`, `antigravity-stream-json`,
|
|
326
|
-
`copilot-json`, `pi-json` — the event stream of that CLI. `pi` and
|
|
327
|
-
`pi-json`. The runner reads the text and the tool calls from it.
|
|
328
|
+
`copilot-json`, `pi-json`, `mastracode-jsonl` — the event stream of that CLI. `pi` and
|
|
329
|
+
`omp` both use `pi-json`. The runner reads the text and the tool calls from it.
|
|
328
330
|
|
|
329
331
|
A preset sets `outputFormat` for you. Set it yourself only with your own `command`. If the
|
|
330
332
|
output does not agree with the format, the runner uses the output as plain text.
|
package/dist/cli.js
CHANGED
|
@@ -177,6 +177,19 @@ var PRESETS = {
|
|
|
177
177
|
...sessionId ? ["--resume", sessionId] : []
|
|
178
178
|
],
|
|
179
179
|
tail: ["--"]
|
|
180
|
+
},
|
|
181
|
+
mastracode: {
|
|
182
|
+
bin: "mastracode",
|
|
183
|
+
outputFormat: "mastracode-jsonl",
|
|
184
|
+
promptVia: "stdin",
|
|
185
|
+
head: (sessionId) => [
|
|
186
|
+
"--output",
|
|
187
|
+
"jsonl",
|
|
188
|
+
"--permission-mode",
|
|
189
|
+
"auto",
|
|
190
|
+
...sessionId ? ["--thread", sessionId] : []
|
|
191
|
+
],
|
|
192
|
+
tail: ["--prompt", "-"]
|
|
180
193
|
}
|
|
181
194
|
};
|
|
182
195
|
var PRESET_NAMES = Object.keys(PRESETS);
|
|
@@ -208,7 +221,8 @@ var OUTPUT_FORMATS = [
|
|
|
208
221
|
"opencode-json",
|
|
209
222
|
"antigravity-stream-json",
|
|
210
223
|
"copilot-json",
|
|
211
|
-
"pi-json"
|
|
224
|
+
"pi-json",
|
|
225
|
+
"mastracode-jsonl"
|
|
212
226
|
];
|
|
213
227
|
function presetOf(config) {
|
|
214
228
|
if (config.command || !config.agent)
|
|
@@ -529,6 +543,7 @@ function startListener(port, agents, log) {
|
|
|
529
543
|
var FLUSH_CHARS = 1500;
|
|
530
544
|
var DELTA_LIMIT = 12000;
|
|
531
545
|
var TOOL_TEXT_LIMIT = 32000;
|
|
546
|
+
var TERMINAL_CODES = /\x1b\[[0-?]*[ -/]*[@-~]/g;
|
|
532
547
|
|
|
533
548
|
class AnswerStream {
|
|
534
549
|
format;
|
|
@@ -544,6 +559,7 @@ class AnswerStream {
|
|
|
544
559
|
openTextPart = "";
|
|
545
560
|
openToolCalls = new Set;
|
|
546
561
|
closedToolCalls = new Set;
|
|
562
|
+
mastraMessageId;
|
|
547
563
|
sawPartialText = false;
|
|
548
564
|
sawAnyText = false;
|
|
549
565
|
segment = "";
|
|
@@ -654,7 +670,9 @@ class AnswerStream {
|
|
|
654
670
|
try {
|
|
655
671
|
parsed = JSON.parse(trimmed);
|
|
656
672
|
} catch {
|
|
657
|
-
|
|
673
|
+
const plain = trimmed.replace(TERMINAL_CODES, "").trim();
|
|
674
|
+
if (plain)
|
|
675
|
+
this.appendText(`${plain}
|
|
658
676
|
`);
|
|
659
677
|
return;
|
|
660
678
|
}
|
|
@@ -680,6 +698,39 @@ class AnswerStream {
|
|
|
680
698
|
case "pi-json":
|
|
681
699
|
this.readPiLine(parsed);
|
|
682
700
|
break;
|
|
701
|
+
case "mastracode-jsonl":
|
|
702
|
+
this.readMastraLine(parsed);
|
|
703
|
+
break;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
readMastraLine(message) {
|
|
707
|
+
switch (message.type) {
|
|
708
|
+
case "thread_created":
|
|
709
|
+
if (message.thread?.id)
|
|
710
|
+
this.sessionId ??= message.thread.id;
|
|
711
|
+
return;
|
|
712
|
+
case "message_start":
|
|
713
|
+
if (message.message?.role === "assistant")
|
|
714
|
+
this.mastraMessageId = message.message.id;
|
|
715
|
+
return;
|
|
716
|
+
case "message_update":
|
|
717
|
+
if (message.id === this.mastraMessageId && message.event?.type === "text-delta") {
|
|
718
|
+
this.appendText(message.event.delta ?? "");
|
|
719
|
+
}
|
|
720
|
+
return;
|
|
721
|
+
case "tool_start":
|
|
722
|
+
if (message.toolCallId) {
|
|
723
|
+
this.pushToolCall(message.toolCallId, message.toolName ?? "tool", JSON.stringify(message.args ?? {}));
|
|
724
|
+
}
|
|
725
|
+
return;
|
|
726
|
+
case "tool_end":
|
|
727
|
+
if (message.toolCallId)
|
|
728
|
+
this.pushToolResult(message.toolCallId, toolResultText(message.result));
|
|
729
|
+
return;
|
|
730
|
+
case "result":
|
|
731
|
+
if (!this.sawAnyText)
|
|
732
|
+
this.appendText(message.text || message.error?.message || "");
|
|
733
|
+
return;
|
|
683
734
|
}
|
|
684
735
|
}
|
|
685
736
|
readPiLine(message) {
|
|
@@ -704,7 +755,7 @@ class AnswerStream {
|
|
|
704
755
|
if (!message.toolCallId || this.closedToolCalls.has(message.toolCallId))
|
|
705
756
|
return;
|
|
706
757
|
this.closedToolCalls.add(message.toolCallId);
|
|
707
|
-
this.pushToolResult(message.toolCallId,
|
|
758
|
+
this.pushToolResult(message.toolCallId, toolResultText(message.result));
|
|
708
759
|
return;
|
|
709
760
|
}
|
|
710
761
|
case "message_end":
|
|
@@ -970,8 +1021,19 @@ class UsageReader {
|
|
|
970
1021
|
case "pi-json":
|
|
971
1022
|
this.readPi(parsed);
|
|
972
1023
|
return;
|
|
1024
|
+
case "mastracode-jsonl":
|
|
1025
|
+
this.readMastra(parsed);
|
|
1026
|
+
return;
|
|
973
1027
|
}
|
|
974
1028
|
}
|
|
1029
|
+
readMastra(message) {
|
|
1030
|
+
if (message.type !== "usage_update" || !message.usage)
|
|
1031
|
+
return;
|
|
1032
|
+
this.last = {
|
|
1033
|
+
inputTokens: message.usage.promptTokens ?? 0,
|
|
1034
|
+
outputTokens: message.usage.completionTokens ?? 0
|
|
1035
|
+
};
|
|
1036
|
+
}
|
|
975
1037
|
readClaude(message) {
|
|
976
1038
|
const event = message.type === "stream_event" ? message.event : undefined;
|
|
977
1039
|
if (!event)
|
|
@@ -1042,7 +1104,7 @@ function textOfResult(content) {
|
|
|
1042
1104
|
}
|
|
1043
1105
|
return "";
|
|
1044
1106
|
}
|
|
1045
|
-
function
|
|
1107
|
+
function toolResultText(result) {
|
|
1046
1108
|
if (result && typeof result === "object" && !Array.isArray(result) && "content" in result) {
|
|
1047
1109
|
return textOfResult(result.content);
|
|
1048
1110
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itsaplan/runner",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
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",
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
"antigravity",
|
|
21
21
|
"opencode",
|
|
22
22
|
"pi",
|
|
23
|
-
"omp"
|
|
23
|
+
"omp",
|
|
24
|
+
"mastracode"
|
|
24
25
|
],
|
|
25
26
|
"homepage": "https://github.com/croffasia/itsaplan/tree/main/packages/runner#readme",
|
|
26
27
|
"repository": {
|