@mariozechner/pi-coding-agent 0.15.0 → 0.17.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 (49) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +418 -1106
  3. package/dist/core/agent-session.d.ts +5 -0
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +65 -18
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/compaction.d.ts +30 -5
  8. package/dist/core/compaction.d.ts.map +1 -1
  9. package/dist/core/compaction.js +194 -61
  10. package/dist/core/compaction.js.map +1 -1
  11. package/dist/core/session-manager.d.ts +10 -3
  12. package/dist/core/session-manager.d.ts.map +1 -1
  13. package/dist/core/session-manager.js +78 -28
  14. package/dist/core/session-manager.js.map +1 -1
  15. package/dist/core/tools/truncate.d.ts +6 -2
  16. package/dist/core/tools/truncate.d.ts.map +1 -1
  17. package/dist/core/tools/truncate.js +11 -1
  18. package/dist/core/tools/truncate.js.map +1 -1
  19. package/dist/modes/index.d.ts +3 -1
  20. package/dist/modes/index.d.ts.map +1 -1
  21. package/dist/modes/index.js +2 -2
  22. package/dist/modes/index.js.map +1 -1
  23. package/dist/modes/interactive/components/bash-execution.d.ts +1 -0
  24. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  25. package/dist/modes/interactive/components/bash-execution.js +17 -6
  26. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  27. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  28. package/dist/modes/interactive/components/tool-execution.js +12 -7
  29. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  30. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  31. package/dist/modes/interactive/interactive-mode.js +18 -4
  32. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  33. package/dist/modes/rpc/rpc-client.d.ts +182 -0
  34. package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
  35. package/dist/modes/rpc/rpc-client.js +362 -0
  36. package/dist/modes/rpc/rpc-client.js.map +1 -0
  37. package/dist/modes/rpc/rpc-mode.d.ts +19 -0
  38. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
  39. package/dist/modes/rpc/rpc-mode.js +205 -0
  40. package/dist/modes/rpc/rpc-mode.js.map +1 -0
  41. package/dist/modes/rpc/rpc-types.d.ts +255 -0
  42. package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
  43. package/dist/modes/rpc/rpc-types.js +8 -0
  44. package/dist/modes/rpc/rpc-types.js.map +1 -0
  45. package/package.json +4 -4
  46. package/dist/modes/rpc-mode.d.ts +0 -21
  47. package/dist/modes/rpc-mode.d.ts.map +0 -1
  48. package/dist/modes/rpc-mode.js +0 -77
  49. package/dist/modes/rpc-mode.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-mode.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-mode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAIhE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAE/E;;;GAGG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,CAqOtE","sourcesContent":["/**\n * RPC mode: Headless operation with JSON stdin/stdout protocol.\n *\n * Used for embedding the agent in other applications.\n * Receives commands as JSON on stdin, outputs events and responses as JSON on stdout.\n *\n * Protocol:\n * - Commands: JSON objects with `type` field, optional `id` for correlation\n * - Responses: JSON objects with `type: \"response\"`, `command`, `success`, and optional `data`/`error`\n * - Events: AgentSessionEvent objects streamed as they occur\n */\n\nimport * as readline from \"readline\";\nimport type { AgentSession } from \"../../core/agent-session.js\";\nimport type { RpcCommand, RpcResponse, RpcSessionState } from \"./rpc-types.js\";\n\n// Re-export types for consumers\nexport type { RpcCommand, RpcResponse, RpcSessionState } from \"./rpc-types.js\";\n\n/**\n * Run in RPC mode.\n * Listens for JSON commands on stdin, outputs events and responses on stdout.\n */\nexport async function runRpcMode(session: AgentSession): Promise<never> {\n\tconst output = (obj: RpcResponse | object) => {\n\t\tconsole.log(JSON.stringify(obj));\n\t};\n\n\tconst success = <T extends RpcCommand[\"type\"]>(\n\t\tid: string | undefined,\n\t\tcommand: T,\n\t\tdata?: object | null,\n\t): RpcResponse => {\n\t\tif (data === undefined) {\n\t\t\treturn { id, type: \"response\", command, success: true } as RpcResponse;\n\t\t}\n\t\treturn { id, type: \"response\", command, success: true, data } as RpcResponse;\n\t};\n\n\tconst error = (id: string | undefined, command: string, message: string): RpcResponse => {\n\t\treturn { id, type: \"response\", command, success: false, error: message };\n\t};\n\n\t// Output all agent events as JSON\n\tsession.subscribe((event) => {\n\t\toutput(event);\n\t});\n\n\t// Handle a single command\n\tconst handleCommand = async (command: RpcCommand): Promise<RpcResponse> => {\n\t\tconst id = command.id;\n\n\t\tswitch (command.type) {\n\t\t\t// =================================================================\n\t\t\t// Prompting\n\t\t\t// =================================================================\n\n\t\t\tcase \"prompt\": {\n\t\t\t\t// Don't await - events will stream\n\t\t\t\tsession\n\t\t\t\t\t.prompt(command.message, {\n\t\t\t\t\t\tattachments: command.attachments,\n\t\t\t\t\t\texpandSlashCommands: false,\n\t\t\t\t\t})\n\t\t\t\t\t.catch((e) => output(error(id, \"prompt\", e.message)));\n\t\t\t\treturn success(id, \"prompt\");\n\t\t\t}\n\n\t\t\tcase \"queue_message\": {\n\t\t\t\tawait session.queueMessage(command.message);\n\t\t\t\treturn success(id, \"queue_message\");\n\t\t\t}\n\n\t\t\tcase \"abort\": {\n\t\t\t\tawait session.abort();\n\t\t\t\treturn success(id, \"abort\");\n\t\t\t}\n\n\t\t\tcase \"reset\": {\n\t\t\t\tawait session.reset();\n\t\t\t\treturn success(id, \"reset\");\n\t\t\t}\n\n\t\t\t// =================================================================\n\t\t\t// State\n\t\t\t// =================================================================\n\n\t\t\tcase \"get_state\": {\n\t\t\t\tconst state: RpcSessionState = {\n\t\t\t\t\tmodel: session.model,\n\t\t\t\t\tthinkingLevel: session.thinkingLevel,\n\t\t\t\t\tisStreaming: session.isStreaming,\n\t\t\t\t\tisCompacting: session.isCompacting,\n\t\t\t\t\tqueueMode: session.queueMode,\n\t\t\t\t\tsessionFile: session.sessionFile,\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tautoCompactionEnabled: session.autoCompactionEnabled,\n\t\t\t\t\tmessageCount: session.messages.length,\n\t\t\t\t\tqueuedMessageCount: session.queuedMessageCount,\n\t\t\t\t};\n\t\t\t\treturn success(id, \"get_state\", state);\n\t\t\t}\n\n\t\t\t// =================================================================\n\t\t\t// Model\n\t\t\t// =================================================================\n\n\t\t\tcase \"set_model\": {\n\t\t\t\tconst models = await session.getAvailableModels();\n\t\t\t\tconst model = models.find((m) => m.provider === command.provider && m.id === command.modelId);\n\t\t\t\tif (!model) {\n\t\t\t\t\treturn error(id, \"set_model\", `Model not found: ${command.provider}/${command.modelId}`);\n\t\t\t\t}\n\t\t\t\tawait session.setModel(model);\n\t\t\t\treturn success(id, \"set_model\", model);\n\t\t\t}\n\n\t\t\tcase \"cycle_model\": {\n\t\t\t\tconst result = await session.cycleModel();\n\t\t\t\tif (!result) {\n\t\t\t\t\treturn success(id, \"cycle_model\", null);\n\t\t\t\t}\n\t\t\t\treturn success(id, \"cycle_model\", result);\n\t\t\t}\n\n\t\t\tcase \"get_available_models\": {\n\t\t\t\tconst models = await session.getAvailableModels();\n\t\t\t\treturn success(id, \"get_available_models\", { models });\n\t\t\t}\n\n\t\t\t// =================================================================\n\t\t\t// Thinking\n\t\t\t// =================================================================\n\n\t\t\tcase \"set_thinking_level\": {\n\t\t\t\tsession.setThinkingLevel(command.level);\n\t\t\t\treturn success(id, \"set_thinking_level\");\n\t\t\t}\n\n\t\t\tcase \"cycle_thinking_level\": {\n\t\t\t\tconst level = session.cycleThinkingLevel();\n\t\t\t\tif (!level) {\n\t\t\t\t\treturn success(id, \"cycle_thinking_level\", null);\n\t\t\t\t}\n\t\t\t\treturn success(id, \"cycle_thinking_level\", { level });\n\t\t\t}\n\n\t\t\t// =================================================================\n\t\t\t// Queue Mode\n\t\t\t// =================================================================\n\n\t\t\tcase \"set_queue_mode\": {\n\t\t\t\tsession.setQueueMode(command.mode);\n\t\t\t\treturn success(id, \"set_queue_mode\");\n\t\t\t}\n\n\t\t\t// =================================================================\n\t\t\t// Compaction\n\t\t\t// =================================================================\n\n\t\t\tcase \"compact\": {\n\t\t\t\tconst result = await session.compact(command.customInstructions);\n\t\t\t\treturn success(id, \"compact\", result);\n\t\t\t}\n\n\t\t\tcase \"set_auto_compaction\": {\n\t\t\t\tsession.setAutoCompactionEnabled(command.enabled);\n\t\t\t\treturn success(id, \"set_auto_compaction\");\n\t\t\t}\n\n\t\t\t// =================================================================\n\t\t\t// Bash\n\t\t\t// =================================================================\n\n\t\t\tcase \"bash\": {\n\t\t\t\tconst result = await session.executeBash(command.command);\n\t\t\t\treturn success(id, \"bash\", result);\n\t\t\t}\n\n\t\t\tcase \"abort_bash\": {\n\t\t\t\tsession.abortBash();\n\t\t\t\treturn success(id, \"abort_bash\");\n\t\t\t}\n\n\t\t\t// =================================================================\n\t\t\t// Session\n\t\t\t// =================================================================\n\n\t\t\tcase \"get_session_stats\": {\n\t\t\t\tconst stats = session.getSessionStats();\n\t\t\t\treturn success(id, \"get_session_stats\", stats);\n\t\t\t}\n\n\t\t\tcase \"export_html\": {\n\t\t\t\tconst path = session.exportToHtml(command.outputPath);\n\t\t\t\treturn success(id, \"export_html\", { path });\n\t\t\t}\n\n\t\t\tcase \"switch_session\": {\n\t\t\t\tawait session.switchSession(command.sessionPath);\n\t\t\t\treturn success(id, \"switch_session\");\n\t\t\t}\n\n\t\t\tcase \"branch\": {\n\t\t\t\tconst text = session.branch(command.entryIndex);\n\t\t\t\treturn success(id, \"branch\", { text });\n\t\t\t}\n\n\t\t\tcase \"get_branch_messages\": {\n\t\t\t\tconst messages = session.getUserMessagesForBranching();\n\t\t\t\treturn success(id, \"get_branch_messages\", { messages });\n\t\t\t}\n\n\t\t\tcase \"get_last_assistant_text\": {\n\t\t\t\tconst text = session.getLastAssistantText();\n\t\t\t\treturn success(id, \"get_last_assistant_text\", { text });\n\t\t\t}\n\n\t\t\t// =================================================================\n\t\t\t// Messages\n\t\t\t// =================================================================\n\n\t\t\tcase \"get_messages\": {\n\t\t\t\treturn success(id, \"get_messages\", { messages: session.messages });\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tconst unknownCommand = command as { type: string };\n\t\t\t\treturn error(undefined, unknownCommand.type, `Unknown command: ${unknownCommand.type}`);\n\t\t\t}\n\t\t}\n\t};\n\n\t// Listen for JSON input\n\tconst rl = readline.createInterface({\n\t\tinput: process.stdin,\n\t\toutput: process.stdout,\n\t\tterminal: false,\n\t});\n\n\trl.on(\"line\", async (line: string) => {\n\t\ttry {\n\t\t\tconst command = JSON.parse(line) as RpcCommand;\n\t\t\tconst response = await handleCommand(command);\n\t\t\toutput(response);\n\t\t} catch (e: any) {\n\t\t\toutput(error(undefined, \"parse\", `Failed to parse command: ${e.message}`));\n\t\t}\n\t});\n\n\t// Keep process alive forever\n\treturn new Promise(() => {});\n}\n"]}
@@ -0,0 +1,205 @@
1
+ /**
2
+ * RPC mode: Headless operation with JSON stdin/stdout protocol.
3
+ *
4
+ * Used for embedding the agent in other applications.
5
+ * Receives commands as JSON on stdin, outputs events and responses as JSON on stdout.
6
+ *
7
+ * Protocol:
8
+ * - Commands: JSON objects with `type` field, optional `id` for correlation
9
+ * - Responses: JSON objects with `type: "response"`, `command`, `success`, and optional `data`/`error`
10
+ * - Events: AgentSessionEvent objects streamed as they occur
11
+ */
12
+ import * as readline from "readline";
13
+ /**
14
+ * Run in RPC mode.
15
+ * Listens for JSON commands on stdin, outputs events and responses on stdout.
16
+ */
17
+ export async function runRpcMode(session) {
18
+ const output = (obj) => {
19
+ console.log(JSON.stringify(obj));
20
+ };
21
+ const success = (id, command, data) => {
22
+ if (data === undefined) {
23
+ return { id, type: "response", command, success: true };
24
+ }
25
+ return { id, type: "response", command, success: true, data };
26
+ };
27
+ const error = (id, command, message) => {
28
+ return { id, type: "response", command, success: false, error: message };
29
+ };
30
+ // Output all agent events as JSON
31
+ session.subscribe((event) => {
32
+ output(event);
33
+ });
34
+ // Handle a single command
35
+ const handleCommand = async (command) => {
36
+ const id = command.id;
37
+ switch (command.type) {
38
+ // =================================================================
39
+ // Prompting
40
+ // =================================================================
41
+ case "prompt": {
42
+ // Don't await - events will stream
43
+ session
44
+ .prompt(command.message, {
45
+ attachments: command.attachments,
46
+ expandSlashCommands: false,
47
+ })
48
+ .catch((e) => output(error(id, "prompt", e.message)));
49
+ return success(id, "prompt");
50
+ }
51
+ case "queue_message": {
52
+ await session.queueMessage(command.message);
53
+ return success(id, "queue_message");
54
+ }
55
+ case "abort": {
56
+ await session.abort();
57
+ return success(id, "abort");
58
+ }
59
+ case "reset": {
60
+ await session.reset();
61
+ return success(id, "reset");
62
+ }
63
+ // =================================================================
64
+ // State
65
+ // =================================================================
66
+ case "get_state": {
67
+ const state = {
68
+ model: session.model,
69
+ thinkingLevel: session.thinkingLevel,
70
+ isStreaming: session.isStreaming,
71
+ isCompacting: session.isCompacting,
72
+ queueMode: session.queueMode,
73
+ sessionFile: session.sessionFile,
74
+ sessionId: session.sessionId,
75
+ autoCompactionEnabled: session.autoCompactionEnabled,
76
+ messageCount: session.messages.length,
77
+ queuedMessageCount: session.queuedMessageCount,
78
+ };
79
+ return success(id, "get_state", state);
80
+ }
81
+ // =================================================================
82
+ // Model
83
+ // =================================================================
84
+ case "set_model": {
85
+ const models = await session.getAvailableModels();
86
+ const model = models.find((m) => m.provider === command.provider && m.id === command.modelId);
87
+ if (!model) {
88
+ return error(id, "set_model", `Model not found: ${command.provider}/${command.modelId}`);
89
+ }
90
+ await session.setModel(model);
91
+ return success(id, "set_model", model);
92
+ }
93
+ case "cycle_model": {
94
+ const result = await session.cycleModel();
95
+ if (!result) {
96
+ return success(id, "cycle_model", null);
97
+ }
98
+ return success(id, "cycle_model", result);
99
+ }
100
+ case "get_available_models": {
101
+ const models = await session.getAvailableModels();
102
+ return success(id, "get_available_models", { models });
103
+ }
104
+ // =================================================================
105
+ // Thinking
106
+ // =================================================================
107
+ case "set_thinking_level": {
108
+ session.setThinkingLevel(command.level);
109
+ return success(id, "set_thinking_level");
110
+ }
111
+ case "cycle_thinking_level": {
112
+ const level = session.cycleThinkingLevel();
113
+ if (!level) {
114
+ return success(id, "cycle_thinking_level", null);
115
+ }
116
+ return success(id, "cycle_thinking_level", { level });
117
+ }
118
+ // =================================================================
119
+ // Queue Mode
120
+ // =================================================================
121
+ case "set_queue_mode": {
122
+ session.setQueueMode(command.mode);
123
+ return success(id, "set_queue_mode");
124
+ }
125
+ // =================================================================
126
+ // Compaction
127
+ // =================================================================
128
+ case "compact": {
129
+ const result = await session.compact(command.customInstructions);
130
+ return success(id, "compact", result);
131
+ }
132
+ case "set_auto_compaction": {
133
+ session.setAutoCompactionEnabled(command.enabled);
134
+ return success(id, "set_auto_compaction");
135
+ }
136
+ // =================================================================
137
+ // Bash
138
+ // =================================================================
139
+ case "bash": {
140
+ const result = await session.executeBash(command.command);
141
+ return success(id, "bash", result);
142
+ }
143
+ case "abort_bash": {
144
+ session.abortBash();
145
+ return success(id, "abort_bash");
146
+ }
147
+ // =================================================================
148
+ // Session
149
+ // =================================================================
150
+ case "get_session_stats": {
151
+ const stats = session.getSessionStats();
152
+ return success(id, "get_session_stats", stats);
153
+ }
154
+ case "export_html": {
155
+ const path = session.exportToHtml(command.outputPath);
156
+ return success(id, "export_html", { path });
157
+ }
158
+ case "switch_session": {
159
+ await session.switchSession(command.sessionPath);
160
+ return success(id, "switch_session");
161
+ }
162
+ case "branch": {
163
+ const text = session.branch(command.entryIndex);
164
+ return success(id, "branch", { text });
165
+ }
166
+ case "get_branch_messages": {
167
+ const messages = session.getUserMessagesForBranching();
168
+ return success(id, "get_branch_messages", { messages });
169
+ }
170
+ case "get_last_assistant_text": {
171
+ const text = session.getLastAssistantText();
172
+ return success(id, "get_last_assistant_text", { text });
173
+ }
174
+ // =================================================================
175
+ // Messages
176
+ // =================================================================
177
+ case "get_messages": {
178
+ return success(id, "get_messages", { messages: session.messages });
179
+ }
180
+ default: {
181
+ const unknownCommand = command;
182
+ return error(undefined, unknownCommand.type, `Unknown command: ${unknownCommand.type}`);
183
+ }
184
+ }
185
+ };
186
+ // Listen for JSON input
187
+ const rl = readline.createInterface({
188
+ input: process.stdin,
189
+ output: process.stdout,
190
+ terminal: false,
191
+ });
192
+ rl.on("line", async (line) => {
193
+ try {
194
+ const command = JSON.parse(line);
195
+ const response = await handleCommand(command);
196
+ output(response);
197
+ }
198
+ catch (e) {
199
+ output(error(undefined, "parse", `Failed to parse command: ${e.message}`));
200
+ }
201
+ });
202
+ // Keep process alive forever
203
+ return new Promise(() => { });
204
+ }
205
+ //# sourceMappingURL=rpc-mode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-mode.js","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-mode.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * RPC mode: Headless operation with JSON stdin/stdout protocol.\n *\n * Used for embedding the agent in other applications.\n * Receives commands as JSON on stdin, outputs events and responses as JSON on stdout.\n *\n * Protocol:\n * - Commands: JSON objects with `type` field, optional `id` for correlation\n * - Responses: JSON objects with `type: \"response\"`, `command`, `success`, and optional `data`/`error`\n * - Events: AgentSessionEvent objects streamed as they occur\n */\n\nimport * as readline from \"readline\";\nimport type { AgentSession } from \"../../core/agent-session.js\";\nimport type { RpcCommand, RpcResponse, RpcSessionState } from \"./rpc-types.js\";\n\n// Re-export types for consumers\nexport type { RpcCommand, RpcResponse, RpcSessionState } from \"./rpc-types.js\";\n\n/**\n * Run in RPC mode.\n * Listens for JSON commands on stdin, outputs events and responses on stdout.\n */\nexport async function runRpcMode(session: AgentSession): Promise<never> {\n\tconst output = (obj: RpcResponse | object) => {\n\t\tconsole.log(JSON.stringify(obj));\n\t};\n\n\tconst success = <T extends RpcCommand[\"type\"]>(\n\t\tid: string | undefined,\n\t\tcommand: T,\n\t\tdata?: object | null,\n\t): RpcResponse => {\n\t\tif (data === undefined) {\n\t\t\treturn { id, type: \"response\", command, success: true } as RpcResponse;\n\t\t}\n\t\treturn { id, type: \"response\", command, success: true, data } as RpcResponse;\n\t};\n\n\tconst error = (id: string | undefined, command: string, message: string): RpcResponse => {\n\t\treturn { id, type: \"response\", command, success: false, error: message };\n\t};\n\n\t// Output all agent events as JSON\n\tsession.subscribe((event) => {\n\t\toutput(event);\n\t});\n\n\t// Handle a single command\n\tconst handleCommand = async (command: RpcCommand): Promise<RpcResponse> => {\n\t\tconst id = command.id;\n\n\t\tswitch (command.type) {\n\t\t\t// =================================================================\n\t\t\t// Prompting\n\t\t\t// =================================================================\n\n\t\t\tcase \"prompt\": {\n\t\t\t\t// Don't await - events will stream\n\t\t\t\tsession\n\t\t\t\t\t.prompt(command.message, {\n\t\t\t\t\t\tattachments: command.attachments,\n\t\t\t\t\t\texpandSlashCommands: false,\n\t\t\t\t\t})\n\t\t\t\t\t.catch((e) => output(error(id, \"prompt\", e.message)));\n\t\t\t\treturn success(id, \"prompt\");\n\t\t\t}\n\n\t\t\tcase \"queue_message\": {\n\t\t\t\tawait session.queueMessage(command.message);\n\t\t\t\treturn success(id, \"queue_message\");\n\t\t\t}\n\n\t\t\tcase \"abort\": {\n\t\t\t\tawait session.abort();\n\t\t\t\treturn success(id, \"abort\");\n\t\t\t}\n\n\t\t\tcase \"reset\": {\n\t\t\t\tawait session.reset();\n\t\t\t\treturn success(id, \"reset\");\n\t\t\t}\n\n\t\t\t// =================================================================\n\t\t\t// State\n\t\t\t// =================================================================\n\n\t\t\tcase \"get_state\": {\n\t\t\t\tconst state: RpcSessionState = {\n\t\t\t\t\tmodel: session.model,\n\t\t\t\t\tthinkingLevel: session.thinkingLevel,\n\t\t\t\t\tisStreaming: session.isStreaming,\n\t\t\t\t\tisCompacting: session.isCompacting,\n\t\t\t\t\tqueueMode: session.queueMode,\n\t\t\t\t\tsessionFile: session.sessionFile,\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tautoCompactionEnabled: session.autoCompactionEnabled,\n\t\t\t\t\tmessageCount: session.messages.length,\n\t\t\t\t\tqueuedMessageCount: session.queuedMessageCount,\n\t\t\t\t};\n\t\t\t\treturn success(id, \"get_state\", state);\n\t\t\t}\n\n\t\t\t// =================================================================\n\t\t\t// Model\n\t\t\t// =================================================================\n\n\t\t\tcase \"set_model\": {\n\t\t\t\tconst models = await session.getAvailableModels();\n\t\t\t\tconst model = models.find((m) => m.provider === command.provider && m.id === command.modelId);\n\t\t\t\tif (!model) {\n\t\t\t\t\treturn error(id, \"set_model\", `Model not found: ${command.provider}/${command.modelId}`);\n\t\t\t\t}\n\t\t\t\tawait session.setModel(model);\n\t\t\t\treturn success(id, \"set_model\", model);\n\t\t\t}\n\n\t\t\tcase \"cycle_model\": {\n\t\t\t\tconst result = await session.cycleModel();\n\t\t\t\tif (!result) {\n\t\t\t\t\treturn success(id, \"cycle_model\", null);\n\t\t\t\t}\n\t\t\t\treturn success(id, \"cycle_model\", result);\n\t\t\t}\n\n\t\t\tcase \"get_available_models\": {\n\t\t\t\tconst models = await session.getAvailableModels();\n\t\t\t\treturn success(id, \"get_available_models\", { models });\n\t\t\t}\n\n\t\t\t// =================================================================\n\t\t\t// Thinking\n\t\t\t// =================================================================\n\n\t\t\tcase \"set_thinking_level\": {\n\t\t\t\tsession.setThinkingLevel(command.level);\n\t\t\t\treturn success(id, \"set_thinking_level\");\n\t\t\t}\n\n\t\t\tcase \"cycle_thinking_level\": {\n\t\t\t\tconst level = session.cycleThinkingLevel();\n\t\t\t\tif (!level) {\n\t\t\t\t\treturn success(id, \"cycle_thinking_level\", null);\n\t\t\t\t}\n\t\t\t\treturn success(id, \"cycle_thinking_level\", { level });\n\t\t\t}\n\n\t\t\t// =================================================================\n\t\t\t// Queue Mode\n\t\t\t// =================================================================\n\n\t\t\tcase \"set_queue_mode\": {\n\t\t\t\tsession.setQueueMode(command.mode);\n\t\t\t\treturn success(id, \"set_queue_mode\");\n\t\t\t}\n\n\t\t\t// =================================================================\n\t\t\t// Compaction\n\t\t\t// =================================================================\n\n\t\t\tcase \"compact\": {\n\t\t\t\tconst result = await session.compact(command.customInstructions);\n\t\t\t\treturn success(id, \"compact\", result);\n\t\t\t}\n\n\t\t\tcase \"set_auto_compaction\": {\n\t\t\t\tsession.setAutoCompactionEnabled(command.enabled);\n\t\t\t\treturn success(id, \"set_auto_compaction\");\n\t\t\t}\n\n\t\t\t// =================================================================\n\t\t\t// Bash\n\t\t\t// =================================================================\n\n\t\t\tcase \"bash\": {\n\t\t\t\tconst result = await session.executeBash(command.command);\n\t\t\t\treturn success(id, \"bash\", result);\n\t\t\t}\n\n\t\t\tcase \"abort_bash\": {\n\t\t\t\tsession.abortBash();\n\t\t\t\treturn success(id, \"abort_bash\");\n\t\t\t}\n\n\t\t\t// =================================================================\n\t\t\t// Session\n\t\t\t// =================================================================\n\n\t\t\tcase \"get_session_stats\": {\n\t\t\t\tconst stats = session.getSessionStats();\n\t\t\t\treturn success(id, \"get_session_stats\", stats);\n\t\t\t}\n\n\t\t\tcase \"export_html\": {\n\t\t\t\tconst path = session.exportToHtml(command.outputPath);\n\t\t\t\treturn success(id, \"export_html\", { path });\n\t\t\t}\n\n\t\t\tcase \"switch_session\": {\n\t\t\t\tawait session.switchSession(command.sessionPath);\n\t\t\t\treturn success(id, \"switch_session\");\n\t\t\t}\n\n\t\t\tcase \"branch\": {\n\t\t\t\tconst text = session.branch(command.entryIndex);\n\t\t\t\treturn success(id, \"branch\", { text });\n\t\t\t}\n\n\t\t\tcase \"get_branch_messages\": {\n\t\t\t\tconst messages = session.getUserMessagesForBranching();\n\t\t\t\treturn success(id, \"get_branch_messages\", { messages });\n\t\t\t}\n\n\t\t\tcase \"get_last_assistant_text\": {\n\t\t\t\tconst text = session.getLastAssistantText();\n\t\t\t\treturn success(id, \"get_last_assistant_text\", { text });\n\t\t\t}\n\n\t\t\t// =================================================================\n\t\t\t// Messages\n\t\t\t// =================================================================\n\n\t\t\tcase \"get_messages\": {\n\t\t\t\treturn success(id, \"get_messages\", { messages: session.messages });\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tconst unknownCommand = command as { type: string };\n\t\t\t\treturn error(undefined, unknownCommand.type, `Unknown command: ${unknownCommand.type}`);\n\t\t\t}\n\t\t}\n\t};\n\n\t// Listen for JSON input\n\tconst rl = readline.createInterface({\n\t\tinput: process.stdin,\n\t\toutput: process.stdout,\n\t\tterminal: false,\n\t});\n\n\trl.on(\"line\", async (line: string) => {\n\t\ttry {\n\t\t\tconst command = JSON.parse(line) as RpcCommand;\n\t\t\tconst response = await handleCommand(command);\n\t\t\toutput(response);\n\t\t} catch (e: any) {\n\t\t\toutput(error(undefined, \"parse\", `Failed to parse command: ${e.message}`));\n\t\t}\n\t});\n\n\t// Keep process alive forever\n\treturn new Promise(() => {});\n}\n"]}
@@ -0,0 +1,255 @@
1
+ /**
2
+ * RPC protocol types for headless operation.
3
+ *
4
+ * Commands are sent as JSON lines on stdin.
5
+ * Responses and events are emitted as JSON lines on stdout.
6
+ */
7
+ import type { AppMessage, Attachment, ThinkingLevel } from "@mariozechner/pi-agent-core";
8
+ import type { Model } from "@mariozechner/pi-ai";
9
+ import type { CompactionResult, SessionStats } from "../../core/agent-session.js";
10
+ import type { BashResult } from "../../core/bash-executor.js";
11
+ export type RpcCommand = {
12
+ id?: string;
13
+ type: "prompt";
14
+ message: string;
15
+ attachments?: Attachment[];
16
+ } | {
17
+ id?: string;
18
+ type: "queue_message";
19
+ message: string;
20
+ } | {
21
+ id?: string;
22
+ type: "abort";
23
+ } | {
24
+ id?: string;
25
+ type: "reset";
26
+ } | {
27
+ id?: string;
28
+ type: "get_state";
29
+ } | {
30
+ id?: string;
31
+ type: "set_model";
32
+ provider: string;
33
+ modelId: string;
34
+ } | {
35
+ id?: string;
36
+ type: "cycle_model";
37
+ } | {
38
+ id?: string;
39
+ type: "get_available_models";
40
+ } | {
41
+ id?: string;
42
+ type: "set_thinking_level";
43
+ level: ThinkingLevel;
44
+ } | {
45
+ id?: string;
46
+ type: "cycle_thinking_level";
47
+ } | {
48
+ id?: string;
49
+ type: "set_queue_mode";
50
+ mode: "all" | "one-at-a-time";
51
+ } | {
52
+ id?: string;
53
+ type: "compact";
54
+ customInstructions?: string;
55
+ } | {
56
+ id?: string;
57
+ type: "set_auto_compaction";
58
+ enabled: boolean;
59
+ } | {
60
+ id?: string;
61
+ type: "bash";
62
+ command: string;
63
+ } | {
64
+ id?: string;
65
+ type: "abort_bash";
66
+ } | {
67
+ id?: string;
68
+ type: "get_session_stats";
69
+ } | {
70
+ id?: string;
71
+ type: "export_html";
72
+ outputPath?: string;
73
+ } | {
74
+ id?: string;
75
+ type: "switch_session";
76
+ sessionPath: string;
77
+ } | {
78
+ id?: string;
79
+ type: "branch";
80
+ entryIndex: number;
81
+ } | {
82
+ id?: string;
83
+ type: "get_branch_messages";
84
+ } | {
85
+ id?: string;
86
+ type: "get_last_assistant_text";
87
+ } | {
88
+ id?: string;
89
+ type: "get_messages";
90
+ };
91
+ export interface RpcSessionState {
92
+ model: Model<any> | null;
93
+ thinkingLevel: ThinkingLevel;
94
+ isStreaming: boolean;
95
+ isCompacting: boolean;
96
+ queueMode: "all" | "one-at-a-time";
97
+ sessionFile: string;
98
+ sessionId: string;
99
+ autoCompactionEnabled: boolean;
100
+ messageCount: number;
101
+ queuedMessageCount: number;
102
+ }
103
+ export type RpcResponse = {
104
+ id?: string;
105
+ type: "response";
106
+ command: "prompt";
107
+ success: true;
108
+ } | {
109
+ id?: string;
110
+ type: "response";
111
+ command: "queue_message";
112
+ success: true;
113
+ } | {
114
+ id?: string;
115
+ type: "response";
116
+ command: "abort";
117
+ success: true;
118
+ } | {
119
+ id?: string;
120
+ type: "response";
121
+ command: "reset";
122
+ success: true;
123
+ } | {
124
+ id?: string;
125
+ type: "response";
126
+ command: "get_state";
127
+ success: true;
128
+ data: RpcSessionState;
129
+ } | {
130
+ id?: string;
131
+ type: "response";
132
+ command: "set_model";
133
+ success: true;
134
+ data: Model<any>;
135
+ } | {
136
+ id?: string;
137
+ type: "response";
138
+ command: "cycle_model";
139
+ success: true;
140
+ data: {
141
+ model: Model<any>;
142
+ thinkingLevel: ThinkingLevel;
143
+ isScoped: boolean;
144
+ } | null;
145
+ } | {
146
+ id?: string;
147
+ type: "response";
148
+ command: "get_available_models";
149
+ success: true;
150
+ data: {
151
+ models: Model<any>[];
152
+ };
153
+ } | {
154
+ id?: string;
155
+ type: "response";
156
+ command: "set_thinking_level";
157
+ success: true;
158
+ } | {
159
+ id?: string;
160
+ type: "response";
161
+ command: "cycle_thinking_level";
162
+ success: true;
163
+ data: {
164
+ level: ThinkingLevel;
165
+ } | null;
166
+ } | {
167
+ id?: string;
168
+ type: "response";
169
+ command: "set_queue_mode";
170
+ success: true;
171
+ } | {
172
+ id?: string;
173
+ type: "response";
174
+ command: "compact";
175
+ success: true;
176
+ data: CompactionResult;
177
+ } | {
178
+ id?: string;
179
+ type: "response";
180
+ command: "set_auto_compaction";
181
+ success: true;
182
+ } | {
183
+ id?: string;
184
+ type: "response";
185
+ command: "bash";
186
+ success: true;
187
+ data: BashResult;
188
+ } | {
189
+ id?: string;
190
+ type: "response";
191
+ command: "abort_bash";
192
+ success: true;
193
+ } | {
194
+ id?: string;
195
+ type: "response";
196
+ command: "get_session_stats";
197
+ success: true;
198
+ data: SessionStats;
199
+ } | {
200
+ id?: string;
201
+ type: "response";
202
+ command: "export_html";
203
+ success: true;
204
+ data: {
205
+ path: string;
206
+ };
207
+ } | {
208
+ id?: string;
209
+ type: "response";
210
+ command: "switch_session";
211
+ success: true;
212
+ } | {
213
+ id?: string;
214
+ type: "response";
215
+ command: "branch";
216
+ success: true;
217
+ data: {
218
+ text: string;
219
+ };
220
+ } | {
221
+ id?: string;
222
+ type: "response";
223
+ command: "get_branch_messages";
224
+ success: true;
225
+ data: {
226
+ messages: Array<{
227
+ entryIndex: number;
228
+ text: string;
229
+ }>;
230
+ };
231
+ } | {
232
+ id?: string;
233
+ type: "response";
234
+ command: "get_last_assistant_text";
235
+ success: true;
236
+ data: {
237
+ text: string | null;
238
+ };
239
+ } | {
240
+ id?: string;
241
+ type: "response";
242
+ command: "get_messages";
243
+ success: true;
244
+ data: {
245
+ messages: AppMessage[];
246
+ };
247
+ } | {
248
+ id?: string;
249
+ type: "response";
250
+ command: string;
251
+ success: false;
252
+ error: string;
253
+ };
254
+ export type RpcCommandType = RpcCommand["type"];
255
+ //# sourceMappingURL=rpc-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-types.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACzF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAClF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAM9D,MAAM,MAAM,UAAU,GAEnB;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,UAAU,EAAE,CAAA;CAAE,GAC5E;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACvD;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC9B;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAG9B;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GAGlC;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACrE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,aAAa,CAAA;CAAE,GACpC;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,sBAAsB,CAAA;CAAE,GAG7C;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,oBAAoB,CAAC;IAAC,KAAK,EAAE,aAAa,CAAA;CAAE,GACjE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,sBAAsB,CAAA;CAAE,GAG7C;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,KAAK,GAAG,eAAe,CAAA;CAAE,GAGtE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7D;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,qBAAqB,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAG9D;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC9C;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,YAAY,CAAA;CAAE,GAGnC;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,mBAAmB,CAAA;CAAE,GAC1C;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,aAAa,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GACzD;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAC5D;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,qBAAqB,CAAA;CAAE,GAC5C;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,yBAAyB,CAAA;CAAE,GAGhD;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,cAAc,CAAA;CAAE,CAAC;AAMzC,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,aAAa,CAAC;IAC7B,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,KAAK,GAAG,eAAe,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;CAC3B;AAOD,MAAM,MAAM,WAAW,GAEpB;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GACnE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GAC1E;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GAClE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GAGlE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,eAAe,CAAA;CAAE,GAG7F;IACA,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,WAAW,CAAC;IACrB,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;CAChB,GACD;IACA,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE;QAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAAC,aAAa,EAAE,aAAa,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;CACnF,GACD;IACA,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,sBAAsB,CAAC;IAChC,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE;QAAE,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAA;KAAE,CAAC;CAC9B,GAGD;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,oBAAoB,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GAC/E;IACA,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,sBAAsB,CAAC;IAChC,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE;QAAE,KAAK,EAAE,aAAa,CAAA;KAAE,GAAG,IAAI,CAAC;CACrC,GAGD;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GAG3E;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC5F;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,qBAAqB,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GAGhF;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GACnF;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GAGvE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,mBAAmB,CAAC;IAAC,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,YAAY,CAAA;CAAE,GAClG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAChG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GAC3E;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAC3F;IACA,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,qBAAqB,CAAC;IAC/B,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE;QAAE,QAAQ,EAAE,KAAK,CAAC;YAAE,UAAU,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;CAC/D,GACD;IACA,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,yBAAyB,CAAC;IACnC,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;CAC7B,GAGD;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,UAAU,EAAE,CAAA;KAAE,CAAA;CAAE,GAG3G;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAMrF,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC","sourcesContent":["/**\n * RPC protocol types for headless operation.\n *\n * Commands are sent as JSON lines on stdin.\n * Responses and events are emitted as JSON lines on stdout.\n */\n\nimport type { AppMessage, Attachment, ThinkingLevel } from \"@mariozechner/pi-agent-core\";\nimport type { Model } from \"@mariozechner/pi-ai\";\nimport type { CompactionResult, SessionStats } from \"../../core/agent-session.js\";\nimport type { BashResult } from \"../../core/bash-executor.js\";\n\n// ============================================================================\n// RPC Commands (stdin)\n// ============================================================================\n\nexport type RpcCommand =\n\t// Prompting\n\t| { id?: string; type: \"prompt\"; message: string; attachments?: Attachment[] }\n\t| { id?: string; type: \"queue_message\"; message: string }\n\t| { id?: string; type: \"abort\" }\n\t| { id?: string; type: \"reset\" }\n\n\t// State\n\t| { id?: string; type: \"get_state\" }\n\n\t// Model\n\t| { id?: string; type: \"set_model\"; provider: string; modelId: string }\n\t| { id?: string; type: \"cycle_model\" }\n\t| { id?: string; type: \"get_available_models\" }\n\n\t// Thinking\n\t| { id?: string; type: \"set_thinking_level\"; level: ThinkingLevel }\n\t| { id?: string; type: \"cycle_thinking_level\" }\n\n\t// Queue mode\n\t| { id?: string; type: \"set_queue_mode\"; mode: \"all\" | \"one-at-a-time\" }\n\n\t// Compaction\n\t| { id?: string; type: \"compact\"; customInstructions?: string }\n\t| { id?: string; type: \"set_auto_compaction\"; enabled: boolean }\n\n\t// Bash\n\t| { id?: string; type: \"bash\"; command: string }\n\t| { id?: string; type: \"abort_bash\" }\n\n\t// Session\n\t| { id?: string; type: \"get_session_stats\" }\n\t| { id?: string; type: \"export_html\"; outputPath?: string }\n\t| { id?: string; type: \"switch_session\"; sessionPath: string }\n\t| { id?: string; type: \"branch\"; entryIndex: number }\n\t| { id?: string; type: \"get_branch_messages\" }\n\t| { id?: string; type: \"get_last_assistant_text\" }\n\n\t// Messages\n\t| { id?: string; type: \"get_messages\" };\n\n// ============================================================================\n// RPC State\n// ============================================================================\n\nexport interface RpcSessionState {\n\tmodel: Model<any> | null;\n\tthinkingLevel: ThinkingLevel;\n\tisStreaming: boolean;\n\tisCompacting: boolean;\n\tqueueMode: \"all\" | \"one-at-a-time\";\n\tsessionFile: string;\n\tsessionId: string;\n\tautoCompactionEnabled: boolean;\n\tmessageCount: number;\n\tqueuedMessageCount: number;\n}\n\n// ============================================================================\n// RPC Responses (stdout)\n// ============================================================================\n\n// Success responses with data\nexport type RpcResponse =\n\t// Prompting (async - events follow)\n\t| { id?: string; type: \"response\"; command: \"prompt\"; success: true }\n\t| { id?: string; type: \"response\"; command: \"queue_message\"; success: true }\n\t| { id?: string; type: \"response\"; command: \"abort\"; success: true }\n\t| { id?: string; type: \"response\"; command: \"reset\"; success: true }\n\n\t// State\n\t| { id?: string; type: \"response\"; command: \"get_state\"; success: true; data: RpcSessionState }\n\n\t// Model\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"response\";\n\t\t\tcommand: \"set_model\";\n\t\t\tsuccess: true;\n\t\t\tdata: Model<any>;\n\t }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"response\";\n\t\t\tcommand: \"cycle_model\";\n\t\t\tsuccess: true;\n\t\t\tdata: { model: Model<any>; thinkingLevel: ThinkingLevel; isScoped: boolean } | null;\n\t }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"response\";\n\t\t\tcommand: \"get_available_models\";\n\t\t\tsuccess: true;\n\t\t\tdata: { models: Model<any>[] };\n\t }\n\n\t// Thinking\n\t| { id?: string; type: \"response\"; command: \"set_thinking_level\"; success: true }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"response\";\n\t\t\tcommand: \"cycle_thinking_level\";\n\t\t\tsuccess: true;\n\t\t\tdata: { level: ThinkingLevel } | null;\n\t }\n\n\t// Queue mode\n\t| { id?: string; type: \"response\"; command: \"set_queue_mode\"; success: true }\n\n\t// Compaction\n\t| { id?: string; type: \"response\"; command: \"compact\"; success: true; data: CompactionResult }\n\t| { id?: string; type: \"response\"; command: \"set_auto_compaction\"; success: true }\n\n\t// Bash\n\t| { id?: string; type: \"response\"; command: \"bash\"; success: true; data: BashResult }\n\t| { id?: string; type: \"response\"; command: \"abort_bash\"; success: true }\n\n\t// Session\n\t| { id?: string; type: \"response\"; command: \"get_session_stats\"; success: true; data: SessionStats }\n\t| { id?: string; type: \"response\"; command: \"export_html\"; success: true; data: { path: string } }\n\t| { id?: string; type: \"response\"; command: \"switch_session\"; success: true }\n\t| { id?: string; type: \"response\"; command: \"branch\"; success: true; data: { text: string } }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"response\";\n\t\t\tcommand: \"get_branch_messages\";\n\t\t\tsuccess: true;\n\t\t\tdata: { messages: Array<{ entryIndex: number; text: string }> };\n\t }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"response\";\n\t\t\tcommand: \"get_last_assistant_text\";\n\t\t\tsuccess: true;\n\t\t\tdata: { text: string | null };\n\t }\n\n\t// Messages\n\t| { id?: string; type: \"response\"; command: \"get_messages\"; success: true; data: { messages: AppMessage[] } }\n\n\t// Error response (any command can fail)\n\t| { id?: string; type: \"response\"; command: string; success: false; error: string };\n\n// ============================================================================\n// Helper type for extracting command types\n// ============================================================================\n\nexport type RpcCommandType = RpcCommand[\"type\"];\n"]}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * RPC protocol types for headless operation.
3
+ *
4
+ * Commands are sent as JSON lines on stdin.
5
+ * Responses and events are emitted as JSON lines on stdout.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=rpc-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-types.js","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG","sourcesContent":["/**\n * RPC protocol types for headless operation.\n *\n * Commands are sent as JSON lines on stdin.\n * Responses and events are emitted as JSON lines on stdout.\n */\n\nimport type { AppMessage, Attachment, ThinkingLevel } from \"@mariozechner/pi-agent-core\";\nimport type { Model } from \"@mariozechner/pi-ai\";\nimport type { CompactionResult, SessionStats } from \"../../core/agent-session.js\";\nimport type { BashResult } from \"../../core/bash-executor.js\";\n\n// ============================================================================\n// RPC Commands (stdin)\n// ============================================================================\n\nexport type RpcCommand =\n\t// Prompting\n\t| { id?: string; type: \"prompt\"; message: string; attachments?: Attachment[] }\n\t| { id?: string; type: \"queue_message\"; message: string }\n\t| { id?: string; type: \"abort\" }\n\t| { id?: string; type: \"reset\" }\n\n\t// State\n\t| { id?: string; type: \"get_state\" }\n\n\t// Model\n\t| { id?: string; type: \"set_model\"; provider: string; modelId: string }\n\t| { id?: string; type: \"cycle_model\" }\n\t| { id?: string; type: \"get_available_models\" }\n\n\t// Thinking\n\t| { id?: string; type: \"set_thinking_level\"; level: ThinkingLevel }\n\t| { id?: string; type: \"cycle_thinking_level\" }\n\n\t// Queue mode\n\t| { id?: string; type: \"set_queue_mode\"; mode: \"all\" | \"one-at-a-time\" }\n\n\t// Compaction\n\t| { id?: string; type: \"compact\"; customInstructions?: string }\n\t| { id?: string; type: \"set_auto_compaction\"; enabled: boolean }\n\n\t// Bash\n\t| { id?: string; type: \"bash\"; command: string }\n\t| { id?: string; type: \"abort_bash\" }\n\n\t// Session\n\t| { id?: string; type: \"get_session_stats\" }\n\t| { id?: string; type: \"export_html\"; outputPath?: string }\n\t| { id?: string; type: \"switch_session\"; sessionPath: string }\n\t| { id?: string; type: \"branch\"; entryIndex: number }\n\t| { id?: string; type: \"get_branch_messages\" }\n\t| { id?: string; type: \"get_last_assistant_text\" }\n\n\t// Messages\n\t| { id?: string; type: \"get_messages\" };\n\n// ============================================================================\n// RPC State\n// ============================================================================\n\nexport interface RpcSessionState {\n\tmodel: Model<any> | null;\n\tthinkingLevel: ThinkingLevel;\n\tisStreaming: boolean;\n\tisCompacting: boolean;\n\tqueueMode: \"all\" | \"one-at-a-time\";\n\tsessionFile: string;\n\tsessionId: string;\n\tautoCompactionEnabled: boolean;\n\tmessageCount: number;\n\tqueuedMessageCount: number;\n}\n\n// ============================================================================\n// RPC Responses (stdout)\n// ============================================================================\n\n// Success responses with data\nexport type RpcResponse =\n\t// Prompting (async - events follow)\n\t| { id?: string; type: \"response\"; command: \"prompt\"; success: true }\n\t| { id?: string; type: \"response\"; command: \"queue_message\"; success: true }\n\t| { id?: string; type: \"response\"; command: \"abort\"; success: true }\n\t| { id?: string; type: \"response\"; command: \"reset\"; success: true }\n\n\t// State\n\t| { id?: string; type: \"response\"; command: \"get_state\"; success: true; data: RpcSessionState }\n\n\t// Model\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"response\";\n\t\t\tcommand: \"set_model\";\n\t\t\tsuccess: true;\n\t\t\tdata: Model<any>;\n\t }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"response\";\n\t\t\tcommand: \"cycle_model\";\n\t\t\tsuccess: true;\n\t\t\tdata: { model: Model<any>; thinkingLevel: ThinkingLevel; isScoped: boolean } | null;\n\t }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"response\";\n\t\t\tcommand: \"get_available_models\";\n\t\t\tsuccess: true;\n\t\t\tdata: { models: Model<any>[] };\n\t }\n\n\t// Thinking\n\t| { id?: string; type: \"response\"; command: \"set_thinking_level\"; success: true }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"response\";\n\t\t\tcommand: \"cycle_thinking_level\";\n\t\t\tsuccess: true;\n\t\t\tdata: { level: ThinkingLevel } | null;\n\t }\n\n\t// Queue mode\n\t| { id?: string; type: \"response\"; command: \"set_queue_mode\"; success: true }\n\n\t// Compaction\n\t| { id?: string; type: \"response\"; command: \"compact\"; success: true; data: CompactionResult }\n\t| { id?: string; type: \"response\"; command: \"set_auto_compaction\"; success: true }\n\n\t// Bash\n\t| { id?: string; type: \"response\"; command: \"bash\"; success: true; data: BashResult }\n\t| { id?: string; type: \"response\"; command: \"abort_bash\"; success: true }\n\n\t// Session\n\t| { id?: string; type: \"response\"; command: \"get_session_stats\"; success: true; data: SessionStats }\n\t| { id?: string; type: \"response\"; command: \"export_html\"; success: true; data: { path: string } }\n\t| { id?: string; type: \"response\"; command: \"switch_session\"; success: true }\n\t| { id?: string; type: \"response\"; command: \"branch\"; success: true; data: { text: string } }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"response\";\n\t\t\tcommand: \"get_branch_messages\";\n\t\t\tsuccess: true;\n\t\t\tdata: { messages: Array<{ entryIndex: number; text: string }> };\n\t }\n\t| {\n\t\t\tid?: string;\n\t\t\ttype: \"response\";\n\t\t\tcommand: \"get_last_assistant_text\";\n\t\t\tsuccess: true;\n\t\t\tdata: { text: string | null };\n\t }\n\n\t// Messages\n\t| { id?: string; type: \"response\"; command: \"get_messages\"; success: true; data: { messages: AppMessage[] } }\n\n\t// Error response (any command can fail)\n\t| { id?: string; type: \"response\"; command: string; success: false; error: string };\n\n// ============================================================================\n// Helper type for extracting command types\n// ============================================================================\n\nexport type RpcCommandType = RpcCommand[\"type\"];\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mariozechner/pi-coding-agent",
3
- "version": "0.15.0",
3
+ "version": "0.17.0",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "piConfig": {
@@ -28,9 +28,9 @@
28
28
  "prepublishOnly": "npm run clean && npm run build"
29
29
  },
30
30
  "dependencies": {
31
- "@mariozechner/pi-agent-core": "^0.15.0",
32
- "@mariozechner/pi-ai": "^0.15.0",
33
- "@mariozechner/pi-tui": "^0.15.0",
31
+ "@mariozechner/pi-agent-core": "^0.17.0",
32
+ "@mariozechner/pi-ai": "^0.17.0",
33
+ "@mariozechner/pi-tui": "^0.17.0",
34
34
  "chalk": "^5.5.0",
35
35
  "diff": "^8.0.2",
36
36
  "glob": "^11.0.3"
@@ -1,21 +0,0 @@
1
- /**
2
- * RPC mode: Headless operation with JSON stdin/stdout protocol.
3
- *
4
- * Used for embedding the agent in other applications.
5
- * Receives commands as JSON on stdin, outputs events as JSON on stdout.
6
- */
7
- import type { AgentSession } from "../core/agent-session.js";
8
- /**
9
- * Run in RPC mode.
10
- * Listens for JSON commands on stdin, outputs events on stdout.
11
- *
12
- * Commands:
13
- * - { type: "prompt", message: string, attachments?: Attachment[] }
14
- * - { type: "abort" }
15
- * - { type: "compact", customInstructions?: string }
16
- * - { type: "bash", command: string }
17
- *
18
- * Events are output as JSON lines (same format as session manager).
19
- */
20
- export declare function runRpcMode(session: AgentSession): Promise<never>;
21
- //# sourceMappingURL=rpc-mode.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rpc-mode.d.ts","sourceRoot":"","sources":["../../src/modes/rpc-mode.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D;;;;;;;;;;;GAWG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,CA6DtE","sourcesContent":["/**\n * RPC mode: Headless operation with JSON stdin/stdout protocol.\n *\n * Used for embedding the agent in other applications.\n * Receives commands as JSON on stdin, outputs events as JSON on stdout.\n */\n\nimport * as readline from \"readline\";\nimport type { AgentSession } from \"../core/agent-session.js\";\n\n/**\n * Run in RPC mode.\n * Listens for JSON commands on stdin, outputs events on stdout.\n *\n * Commands:\n * - { type: \"prompt\", message: string, attachments?: Attachment[] }\n * - { type: \"abort\" }\n * - { type: \"compact\", customInstructions?: string }\n * - { type: \"bash\", command: string }\n *\n * Events are output as JSON lines (same format as session manager).\n */\nexport async function runRpcMode(session: AgentSession): Promise<never> {\n\t// Output all agent events as JSON\n\tsession.subscribe((event) => {\n\t\tconsole.log(JSON.stringify(event));\n\t});\n\n\t// Listen for JSON input\n\tconst rl = readline.createInterface({\n\t\tinput: process.stdin,\n\t\toutput: process.stdout,\n\t\tterminal: false,\n\t});\n\n\trl.on(\"line\", async (line: string) => {\n\t\ttry {\n\t\t\tconst input = JSON.parse(line);\n\n\t\t\tswitch (input.type) {\n\t\t\t\tcase \"prompt\":\n\t\t\t\t\tif (input.message) {\n\t\t\t\t\t\tawait session.prompt(input.message, {\n\t\t\t\t\t\t\tattachments: input.attachments,\n\t\t\t\t\t\t\texpandSlashCommands: false, // RPC mode doesn't expand slash commands\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"abort\":\n\t\t\t\t\tawait session.abort();\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"compact\":\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await session.compact(input.customInstructions);\n\t\t\t\t\t\tconsole.log(JSON.stringify({ type: \"compaction\", ...result }));\n\t\t\t\t\t} catch (error: any) {\n\t\t\t\t\t\tconsole.log(JSON.stringify({ type: \"error\", error: `Compaction failed: ${error.message}` }));\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase \"bash\":\n\t\t\t\t\tif (input.command) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst result = await session.executeBash(input.command);\n\t\t\t\t\t\t\tconsole.log(JSON.stringify({ type: \"bash_end\", ...result }));\n\t\t\t\t\t\t} catch (error: any) {\n\t\t\t\t\t\t\tconsole.log(JSON.stringify({ type: \"error\", error: `Bash failed: ${error.message}` }));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tconsole.log(JSON.stringify({ type: \"error\", error: `Unknown command: ${input.type}` }));\n\t\t\t}\n\t\t} catch (error: any) {\n\t\t\tconsole.log(JSON.stringify({ type: \"error\", error: error.message }));\n\t\t}\n\t});\n\n\t// Keep process alive forever\n\treturn new Promise(() => {});\n}\n"]}