pi-app-server 0.1.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 (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +195 -0
  3. package/dist/command-classification.d.ts +59 -0
  4. package/dist/command-classification.d.ts.map +1 -0
  5. package/dist/command-classification.js +78 -0
  6. package/dist/command-classification.js.map +7 -0
  7. package/dist/command-execution-engine.d.ts +118 -0
  8. package/dist/command-execution-engine.d.ts.map +1 -0
  9. package/dist/command-execution-engine.js +259 -0
  10. package/dist/command-execution-engine.js.map +7 -0
  11. package/dist/command-replay-store.d.ts +241 -0
  12. package/dist/command-replay-store.d.ts.map +1 -0
  13. package/dist/command-replay-store.js +306 -0
  14. package/dist/command-replay-store.js.map +7 -0
  15. package/dist/command-router.d.ts +25 -0
  16. package/dist/command-router.d.ts.map +1 -0
  17. package/dist/command-router.js +353 -0
  18. package/dist/command-router.js.map +7 -0
  19. package/dist/extension-ui.d.ts +139 -0
  20. package/dist/extension-ui.d.ts.map +1 -0
  21. package/dist/extension-ui.js +189 -0
  22. package/dist/extension-ui.js.map +7 -0
  23. package/dist/resource-governor.d.ts +254 -0
  24. package/dist/resource-governor.d.ts.map +1 -0
  25. package/dist/resource-governor.js +603 -0
  26. package/dist/resource-governor.js.map +7 -0
  27. package/dist/server-command-handlers.d.ts +120 -0
  28. package/dist/server-command-handlers.d.ts.map +1 -0
  29. package/dist/server-command-handlers.js +234 -0
  30. package/dist/server-command-handlers.js.map +7 -0
  31. package/dist/server-ui-context.d.ts +22 -0
  32. package/dist/server-ui-context.d.ts.map +1 -0
  33. package/dist/server-ui-context.js +221 -0
  34. package/dist/server-ui-context.js.map +7 -0
  35. package/dist/server.d.ts +82 -0
  36. package/dist/server.d.ts.map +1 -0
  37. package/dist/server.js +561 -0
  38. package/dist/server.js.map +7 -0
  39. package/dist/session-lock-manager.d.ts +100 -0
  40. package/dist/session-lock-manager.d.ts.map +1 -0
  41. package/dist/session-lock-manager.js +199 -0
  42. package/dist/session-lock-manager.js.map +7 -0
  43. package/dist/session-manager.d.ts +196 -0
  44. package/dist/session-manager.d.ts.map +1 -0
  45. package/dist/session-manager.js +1010 -0
  46. package/dist/session-manager.js.map +7 -0
  47. package/dist/session-store.d.ts +190 -0
  48. package/dist/session-store.d.ts.map +1 -0
  49. package/dist/session-store.js +446 -0
  50. package/dist/session-store.js.map +7 -0
  51. package/dist/session-version-store.d.ts +83 -0
  52. package/dist/session-version-store.d.ts.map +1 -0
  53. package/dist/session-version-store.js +117 -0
  54. package/dist/session-version-store.js.map +7 -0
  55. package/dist/type-guards.d.ts +59 -0
  56. package/dist/type-guards.d.ts.map +1 -0
  57. package/dist/type-guards.js +40 -0
  58. package/dist/type-guards.js.map +7 -0
  59. package/dist/types.d.ts +621 -0
  60. package/dist/types.d.ts.map +1 -0
  61. package/dist/types.js +23 -0
  62. package/dist/types.js.map +7 -0
  63. package/dist/validation.d.ts +22 -0
  64. package/dist/validation.d.ts.map +1 -0
  65. package/dist/validation.js +323 -0
  66. package/dist/validation.js.map +7 -0
  67. package/package.json +135 -0
@@ -0,0 +1,353 @@
1
+ import path from "path";
2
+ import { SessionManager } from "@mariozechner/pi-coding-agent";
3
+ const handlePrompt = async (session, command) => {
4
+ await session.prompt(command.message, {
5
+ images: command.images,
6
+ streamingBehavior: command.streamingBehavior
7
+ });
8
+ return { id: command.id, type: "response", command: "prompt", success: true };
9
+ };
10
+ const handleSteer = async (session, command) => {
11
+ await session.steer(command.message, command.images);
12
+ return { id: command.id, type: "response", command: "steer", success: true };
13
+ };
14
+ const handleFollowUp = async (session, command) => {
15
+ await session.followUp(command.message, command.images);
16
+ return { id: command.id, type: "response", command: "follow_up", success: true };
17
+ };
18
+ const handleAbort = async (session, command) => {
19
+ await session.abort();
20
+ return { id: command.id, type: "response", command: "abort", success: true };
21
+ };
22
+ const handleGetState = (_session, command, getSessionInfo) => {
23
+ const info = getSessionInfo(command.sessionId);
24
+ if (!info) {
25
+ return {
26
+ id: command.id,
27
+ type: "response",
28
+ command: "get_state",
29
+ success: false,
30
+ error: `Session ${command.sessionId} not found`
31
+ };
32
+ }
33
+ return { id: command.id, type: "response", command: "get_state", success: true, data: info };
34
+ };
35
+ const handleGetMessages = (session, command) => {
36
+ return {
37
+ id: command.id,
38
+ type: "response",
39
+ command: "get_messages",
40
+ success: true,
41
+ data: { messages: session.messages }
42
+ };
43
+ };
44
+ const handleSetModel = async (session, command) => {
45
+ const model = session.modelRegistry.find(command.provider, command.modelId);
46
+ if (!model) {
47
+ return {
48
+ id: command.id,
49
+ type: "response",
50
+ command: "set_model",
51
+ success: false,
52
+ error: `Model not found: ${command.provider}/${command.modelId}`
53
+ };
54
+ }
55
+ await session.setModel(model);
56
+ return {
57
+ id: command.id,
58
+ type: "response",
59
+ command: "set_model",
60
+ success: true,
61
+ data: { model: session.model }
62
+ };
63
+ };
64
+ const handleCycleModel = async (session, command) => {
65
+ const result = await session.cycleModel(command.direction);
66
+ return {
67
+ id: command.id,
68
+ type: "response",
69
+ command: "cycle_model",
70
+ success: true,
71
+ data: result ? { model: result.model, thinkingLevel: result.thinkingLevel, isScoped: result.isScoped } : null
72
+ };
73
+ };
74
+ const handleSetThinkingLevel = (session, command) => {
75
+ session.setThinkingLevel(command.level);
76
+ return { id: command.id, type: "response", command: "set_thinking_level", success: true };
77
+ };
78
+ const handleCycleThinkingLevel = (session, command) => {
79
+ const level = session.cycleThinkingLevel();
80
+ return {
81
+ id: command.id,
82
+ type: "response",
83
+ command: "cycle_thinking_level",
84
+ success: true,
85
+ data: level ? { level } : null
86
+ };
87
+ };
88
+ const handleCompact = async (session, command) => {
89
+ const result = await session.compact(command.customInstructions);
90
+ return { id: command.id, type: "response", command: "compact", success: true, data: result };
91
+ };
92
+ const handleAbortCompaction = (session, command) => {
93
+ session.abortCompaction();
94
+ return { id: command.id, type: "response", command: "abort_compaction", success: true };
95
+ };
96
+ const handleSetAutoCompaction = (session, command) => {
97
+ session.setAutoCompactionEnabled(command.enabled);
98
+ return { id: command.id, type: "response", command: "set_auto_compaction", success: true };
99
+ };
100
+ const handleSetAutoRetry = (session, command) => {
101
+ session.setAutoRetryEnabled(command.enabled);
102
+ return { id: command.id, type: "response", command: "set_auto_retry", success: true };
103
+ };
104
+ const handleAbortRetry = (session, command) => {
105
+ session.abortRetry();
106
+ return { id: command.id, type: "response", command: "abort_retry", success: true };
107
+ };
108
+ const handleBash = async (session, command) => {
109
+ const result = await session.executeBash(command.command, void 0, {
110
+ excludeFromContext: command.excludeFromContext
111
+ });
112
+ return {
113
+ id: command.id,
114
+ type: "response",
115
+ command: "bash",
116
+ success: true,
117
+ data: { exitCode: result.exitCode ?? 0, output: result.output, cancelled: result.cancelled }
118
+ };
119
+ };
120
+ const handleAbortBash = (session, command) => {
121
+ session.abortBash();
122
+ return { id: command.id, type: "response", command: "abort_bash", success: true };
123
+ };
124
+ const handleGetSessionStats = (session, command) => {
125
+ const stats = session.getSessionStats();
126
+ return {
127
+ id: command.id,
128
+ type: "response",
129
+ command: "get_session_stats",
130
+ success: true,
131
+ data: stats
132
+ };
133
+ };
134
+ const handleSetSessionName = (session, command) => {
135
+ session.setSessionName(command.name);
136
+ return { id: command.id, type: "response", command: "set_session_name", success: true };
137
+ };
138
+ const handleExportHtml = async (session, command) => {
139
+ const path2 = await session.exportToHtml(command.outputPath);
140
+ return {
141
+ id: command.id,
142
+ type: "response",
143
+ command: "export_html",
144
+ success: true,
145
+ data: { path: path2 }
146
+ };
147
+ };
148
+ const handleNewSession = async (session, command) => {
149
+ const cancelled = !await session.newSession({ parentSession: command.parentSession });
150
+ return {
151
+ id: command.id,
152
+ type: "response",
153
+ command: "new_session",
154
+ success: true,
155
+ data: { cancelled }
156
+ };
157
+ };
158
+ const handleSwitchSessionFile = async (session, command) => {
159
+ const cancelled = !await session.switchSession(command.sessionPath);
160
+ return {
161
+ id: command.id,
162
+ type: "response",
163
+ command: "switch_session_file",
164
+ success: true,
165
+ data: { cancelled }
166
+ };
167
+ };
168
+ const handleFork = async (session, command) => {
169
+ const result = await session.fork(command.entryId);
170
+ return {
171
+ id: command.id,
172
+ type: "response",
173
+ command: "fork",
174
+ success: true,
175
+ data: { text: result.selectedText, cancelled: result.cancelled }
176
+ };
177
+ };
178
+ const handleGetForkMessages = (session, command) => {
179
+ const messages = session.getUserMessagesForForking();
180
+ return {
181
+ id: command.id,
182
+ type: "response",
183
+ command: "get_fork_messages",
184
+ success: true,
185
+ data: { messages }
186
+ };
187
+ };
188
+ const handleGetLastAssistantText = (session, command) => {
189
+ const text = session.getLastAssistantText();
190
+ return {
191
+ id: command.id,
192
+ type: "response",
193
+ command: "get_last_assistant_text",
194
+ success: true,
195
+ data: { text: text ?? null }
196
+ };
197
+ };
198
+ const handleGetContextUsage = (session, command) => {
199
+ const usage = session.getContextUsage();
200
+ return {
201
+ id: command.id,
202
+ type: "response",
203
+ command: "get_context_usage",
204
+ success: true,
205
+ data: usage ? { tokens: usage.tokens, contextWindow: usage.contextWindow, percent: usage.percent } : null
206
+ };
207
+ };
208
+ const handleGetAvailableModels = (session, command) => {
209
+ const models = session.modelRegistry.getAvailable();
210
+ return {
211
+ id: command.id,
212
+ type: "response",
213
+ command: "get_available_models",
214
+ success: true,
215
+ data: { models }
216
+ };
217
+ };
218
+ const handleGetCommands = (session, command) => {
219
+ const extensions = session.resourceLoader.getExtensions();
220
+ const commands = [];
221
+ for (const ext of extensions.extensions) {
222
+ for (const [name, cmd] of ext.commands) {
223
+ commands.push({
224
+ name,
225
+ description: cmd.description,
226
+ source: "extension",
227
+ path: ext.path
228
+ });
229
+ }
230
+ }
231
+ const skillsResult = session.resourceLoader.getSkills();
232
+ for (const skill of skillsResult.skills) {
233
+ commands.push({
234
+ name: skill.name,
235
+ description: skill.description,
236
+ source: "skill",
237
+ path: skill.filePath
238
+ });
239
+ }
240
+ const promptsResult = session.resourceLoader.getPrompts();
241
+ for (const prompt of promptsResult.prompts) {
242
+ commands.push({
243
+ name: prompt.name,
244
+ description: prompt.description,
245
+ source: "prompt",
246
+ path: prompt.filePath
247
+ });
248
+ }
249
+ return {
250
+ id: command.id,
251
+ type: "response",
252
+ command: "get_commands",
253
+ success: true,
254
+ data: { commands }
255
+ };
256
+ };
257
+ const handleGetSkills = (session, command) => {
258
+ const skillsResult = session.resourceLoader.getSkills();
259
+ const skills = skillsResult.skills.map((skill) => ({
260
+ name: skill.name,
261
+ description: skill.description,
262
+ filePath: skill.filePath,
263
+ source: skill.source
264
+ }));
265
+ return {
266
+ id: command.id,
267
+ type: "response",
268
+ command: "get_skills",
269
+ success: true,
270
+ data: { skills }
271
+ };
272
+ };
273
+ const handleGetTools = (session, command) => {
274
+ const tools = session.getAllTools().map((tool) => ({
275
+ name: tool.name,
276
+ description: tool.description
277
+ }));
278
+ return {
279
+ id: command.id,
280
+ type: "response",
281
+ command: "get_tools",
282
+ success: true,
283
+ data: { tools }
284
+ };
285
+ };
286
+ const handleListSessionFiles = async (session, command) => {
287
+ const cwd = session.sessionManager.getCwd();
288
+ const files = await SessionManager.list(cwd);
289
+ const formattedFiles = files.map((file) => ({
290
+ path: file.path,
291
+ name: path.basename(file.path),
292
+ // Cross-platform basename extraction
293
+ modifiedAt: file.modified.toISOString()
294
+ }));
295
+ return {
296
+ id: command.id,
297
+ type: "response",
298
+ command: "list_session_files",
299
+ success: true,
300
+ data: { files: formattedFiles }
301
+ };
302
+ };
303
+ const sessionCommandHandlers = {
304
+ // Discovery commands
305
+ get_available_models: handleGetAvailableModels,
306
+ get_commands: handleGetCommands,
307
+ get_skills: handleGetSkills,
308
+ get_tools: handleGetTools,
309
+ list_session_files: handleListSessionFiles,
310
+ // Session commands
311
+ prompt: handlePrompt,
312
+ steer: handleSteer,
313
+ follow_up: handleFollowUp,
314
+ abort: handleAbort,
315
+ get_state: handleGetState,
316
+ get_messages: handleGetMessages,
317
+ set_model: handleSetModel,
318
+ cycle_model: handleCycleModel,
319
+ set_thinking_level: handleSetThinkingLevel,
320
+ cycle_thinking_level: handleCycleThinkingLevel,
321
+ compact: handleCompact,
322
+ abort_compaction: handleAbortCompaction,
323
+ set_auto_compaction: handleSetAutoCompaction,
324
+ set_auto_retry: handleSetAutoRetry,
325
+ abort_retry: handleAbortRetry,
326
+ bash: handleBash,
327
+ abort_bash: handleAbortBash,
328
+ get_session_stats: handleGetSessionStats,
329
+ set_session_name: handleSetSessionName,
330
+ export_html: handleExportHtml,
331
+ new_session: handleNewSession,
332
+ switch_session_file: handleSwitchSessionFile,
333
+ fork: handleFork,
334
+ get_fork_messages: handleGetForkMessages,
335
+ get_last_assistant_text: handleGetLastAssistantText,
336
+ get_context_usage: handleGetContextUsage
337
+ };
338
+ function routeSessionCommand(session, command, getSessionInfo) {
339
+ const handler = sessionCommandHandlers[command.type];
340
+ if (!handler) {
341
+ return void 0;
342
+ }
343
+ return handler(session, command, getSessionInfo);
344
+ }
345
+ function getSupportedSessionCommands() {
346
+ return Object.keys(sessionCommandHandlers);
347
+ }
348
+ export {
349
+ getSupportedSessionCommands,
350
+ routeSessionCommand,
351
+ sessionCommandHandlers
352
+ };
353
+ //# sourceMappingURL=command-router.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/command-router.ts"],
4
+ "sourcesContent": ["/**\n * Command Router - extensible command dispatch via handler map.\n *\n * Each handler is a self-contained function that takes a session and command,\n * executes against the session, and returns a response.\n *\n * This replaces the giant switch statement, enabling:\n * - Easy addition of new commands\n * - Isolated testing of handlers\n * - Clear separation of concerns\n */\n\nimport path from \"path\";\nimport { type AgentSession, SessionManager } from \"@mariozechner/pi-coding-agent\";\nimport type { RpcResponse, SessionInfo } from \"./types.js\";\n\n// =============================================================================\n// HANDLER TYPE\n// =============================================================================\n\nexport type CommandHandler = (\n session: AgentSession,\n command: any,\n getSessionInfo: (sessionId: string) => SessionInfo | undefined\n) => Promise<RpcResponse> | RpcResponse;\n\n// =============================================================================\n// HANDLER IMPLEMENTATIONS\n// =============================================================================\n\nconst handlePrompt: CommandHandler = async (session, command) => {\n await session.prompt(command.message, {\n images: command.images,\n streamingBehavior: command.streamingBehavior,\n });\n return { id: command.id, type: \"response\", command: \"prompt\", success: true };\n};\n\nconst handleSteer: CommandHandler = async (session, command) => {\n await session.steer(command.message, command.images);\n return { id: command.id, type: \"response\", command: \"steer\", success: true };\n};\n\nconst handleFollowUp: CommandHandler = async (session, command) => {\n await session.followUp(command.message, command.images);\n return { id: command.id, type: \"response\", command: \"follow_up\", success: true };\n};\n\nconst handleAbort: CommandHandler = async (session, command) => {\n await session.abort();\n return { id: command.id, type: \"response\", command: \"abort\", success: true };\n};\n\nconst handleGetState: CommandHandler = (_session, command, getSessionInfo) => {\n const info = getSessionInfo(command.sessionId);\n if (!info) {\n return {\n id: command.id,\n type: \"response\",\n command: \"get_state\",\n success: false,\n error: `Session ${command.sessionId} not found`,\n };\n }\n return { id: command.id, type: \"response\", command: \"get_state\", success: true, data: info };\n};\n\nconst handleGetMessages: CommandHandler = (session, command) => {\n return {\n id: command.id,\n type: \"response\",\n command: \"get_messages\",\n success: true,\n data: { messages: session.messages },\n };\n};\n\nconst handleSetModel: CommandHandler = async (session, command) => {\n // Use public API: modelRegistry.find() instead of internal getModel()\n const model = session.modelRegistry.find(command.provider, command.modelId);\n if (!model) {\n return {\n id: command.id,\n type: \"response\",\n command: \"set_model\",\n success: false,\n error: `Model not found: ${command.provider}/${command.modelId}`,\n };\n }\n await session.setModel(model);\n return {\n id: command.id,\n type: \"response\",\n command: \"set_model\",\n success: true,\n data: { model: session.model! },\n };\n};\n\nconst handleCycleModel: CommandHandler = async (session, command) => {\n const result = await session.cycleModel(command.direction);\n return {\n id: command.id,\n type: \"response\",\n command: \"cycle_model\",\n success: true,\n data: result\n ? { model: result.model, thinkingLevel: result.thinkingLevel, isScoped: result.isScoped }\n : null,\n };\n};\n\nconst handleSetThinkingLevel: CommandHandler = (session, command) => {\n session.setThinkingLevel(command.level);\n return { id: command.id, type: \"response\", command: \"set_thinking_level\", success: true };\n};\n\nconst handleCycleThinkingLevel: CommandHandler = (session, command) => {\n const level = session.cycleThinkingLevel();\n return {\n id: command.id,\n type: \"response\",\n command: \"cycle_thinking_level\",\n success: true,\n data: level ? { level } : null,\n };\n};\n\nconst handleCompact: CommandHandler = async (session, command) => {\n const result = await session.compact(command.customInstructions);\n return { id: command.id, type: \"response\", command: \"compact\", success: true, data: result };\n};\n\nconst handleAbortCompaction: CommandHandler = (session, command) => {\n session.abortCompaction();\n return { id: command.id, type: \"response\", command: \"abort_compaction\", success: true };\n};\n\nconst handleSetAutoCompaction: CommandHandler = (session, command) => {\n session.setAutoCompactionEnabled(command.enabled);\n return { id: command.id, type: \"response\", command: \"set_auto_compaction\", success: true };\n};\n\nconst handleSetAutoRetry: CommandHandler = (session, command) => {\n session.setAutoRetryEnabled(command.enabled);\n return { id: command.id, type: \"response\", command: \"set_auto_retry\", success: true };\n};\n\nconst handleAbortRetry: CommandHandler = (session, command) => {\n session.abortRetry();\n return { id: command.id, type: \"response\", command: \"abort_retry\", success: true };\n};\n\nconst handleBash: CommandHandler = async (session, command) => {\n const result = await session.executeBash(command.command, undefined, {\n excludeFromContext: command.excludeFromContext,\n });\n return {\n id: command.id,\n type: \"response\",\n command: \"bash\",\n success: true,\n data: { exitCode: result.exitCode ?? 0, output: result.output, cancelled: result.cancelled },\n };\n};\n\nconst handleAbortBash: CommandHandler = (session, command) => {\n session.abortBash();\n return { id: command.id, type: \"response\", command: \"abort_bash\", success: true };\n};\n\nconst handleGetSessionStats: CommandHandler = (session, command) => {\n const stats = session.getSessionStats();\n return {\n id: command.id,\n type: \"response\",\n command: \"get_session_stats\",\n success: true,\n data: stats,\n };\n};\n\nconst handleSetSessionName: CommandHandler = (session, command) => {\n session.setSessionName(command.name);\n return { id: command.id, type: \"response\", command: \"set_session_name\", success: true };\n};\n\nconst handleExportHtml: CommandHandler = async (session, command) => {\n const path = await session.exportToHtml(command.outputPath);\n return {\n id: command.id,\n type: \"response\",\n command: \"export_html\",\n success: true,\n data: { path },\n };\n};\n\nconst handleNewSession: CommandHandler = async (session, command) => {\n const cancelled = !(await session.newSession({ parentSession: command.parentSession }));\n return {\n id: command.id,\n type: \"response\",\n command: \"new_session\",\n success: true,\n data: { cancelled },\n };\n};\n\nconst handleSwitchSessionFile: CommandHandler = async (session, command) => {\n const cancelled = !(await session.switchSession(command.sessionPath));\n return {\n id: command.id,\n type: \"response\",\n command: \"switch_session_file\",\n success: true,\n data: { cancelled },\n };\n};\n\nconst handleFork: CommandHandler = async (session, command) => {\n const result = await session.fork(command.entryId);\n return {\n id: command.id,\n type: \"response\",\n command: \"fork\",\n success: true,\n data: { text: result.selectedText, cancelled: result.cancelled },\n };\n};\n\nconst handleGetForkMessages: CommandHandler = (session, command) => {\n const messages = session.getUserMessagesForForking();\n return {\n id: command.id,\n type: \"response\",\n command: \"get_fork_messages\",\n success: true,\n data: { messages },\n };\n};\n\nconst handleGetLastAssistantText: CommandHandler = (session, command) => {\n const text = session.getLastAssistantText();\n return {\n id: command.id,\n type: \"response\",\n command: \"get_last_assistant_text\",\n success: true,\n data: { text: text ?? null },\n };\n};\n\nconst handleGetContextUsage: CommandHandler = (session, command) => {\n const usage = session.getContextUsage();\n return {\n id: command.id,\n type: \"response\",\n command: \"get_context_usage\",\n success: true,\n data: usage\n ? { tokens: usage.tokens, contextWindow: usage.contextWindow, percent: usage.percent }\n : null,\n };\n};\n\n// =============================================================================\n// DISCOVERY HANDLERS\n// =============================================================================\n\nconst handleGetAvailableModels: CommandHandler = (session, command) => {\n const models = session.modelRegistry.getAvailable();\n return {\n id: command.id,\n type: \"response\",\n command: \"get_available_models\",\n success: true,\n data: { models },\n };\n};\n\nconst handleGetCommands: CommandHandler = (session, command) => {\n // Get commands from resourceLoader's extensions\n const extensions = session.resourceLoader.getExtensions();\n const commands: Array<{\n name: string;\n description?: string;\n source: string;\n location?: string;\n path?: string;\n }> = [];\n\n for (const ext of extensions.extensions) {\n for (const [name, cmd] of ext.commands) {\n commands.push({\n name,\n description: cmd.description,\n source: \"extension\",\n path: ext.path,\n });\n }\n }\n\n // Add skills as commands\n const skillsResult = session.resourceLoader.getSkills();\n for (const skill of skillsResult.skills) {\n commands.push({\n name: skill.name,\n description: skill.description,\n source: \"skill\",\n path: skill.filePath,\n });\n }\n\n // Add prompts as commands\n const promptsResult = session.resourceLoader.getPrompts();\n for (const prompt of promptsResult.prompts) {\n commands.push({\n name: prompt.name,\n description: prompt.description,\n source: \"prompt\",\n path: prompt.filePath,\n });\n }\n\n return {\n id: command.id,\n type: \"response\",\n command: \"get_commands\",\n success: true,\n data: { commands },\n };\n};\n\nconst handleGetSkills: CommandHandler = (session, command) => {\n const skillsResult = session.resourceLoader.getSkills();\n const skills = skillsResult.skills.map((skill) => ({\n name: skill.name,\n description: skill.description,\n filePath: skill.filePath,\n source: skill.source,\n }));\n\n return {\n id: command.id,\n type: \"response\",\n command: \"get_skills\",\n success: true,\n data: { skills },\n };\n};\n\nconst handleGetTools: CommandHandler = (session, command) => {\n const tools = session.getAllTools().map((tool) => ({\n name: tool.name,\n description: tool.description,\n }));\n\n return {\n id: command.id,\n type: \"response\",\n command: \"get_tools\",\n success: true,\n data: { tools },\n };\n};\n\nconst handleListSessionFiles: CommandHandler = async (session, command) => {\n // Get session files from the session manager (static async method)\n const cwd = session.sessionManager.getCwd();\n const files = await SessionManager.list(cwd);\n\n const formattedFiles = files.map((file) => ({\n path: file.path,\n name: path.basename(file.path), // Cross-platform basename extraction\n modifiedAt: file.modified.toISOString(),\n }));\n\n return {\n id: command.id,\n type: \"response\",\n command: \"list_session_files\",\n success: true,\n data: { files: formattedFiles },\n };\n};\n\n// =============================================================================\n// HANDLER MAP\n// =============================================================================\n\nexport const sessionCommandHandlers: Record<string, CommandHandler> = {\n // Discovery commands\n get_available_models: handleGetAvailableModels,\n get_commands: handleGetCommands,\n get_skills: handleGetSkills,\n get_tools: handleGetTools,\n list_session_files: handleListSessionFiles,\n // Session commands\n prompt: handlePrompt,\n steer: handleSteer,\n follow_up: handleFollowUp,\n abort: handleAbort,\n get_state: handleGetState,\n get_messages: handleGetMessages,\n set_model: handleSetModel,\n cycle_model: handleCycleModel,\n set_thinking_level: handleSetThinkingLevel,\n cycle_thinking_level: handleCycleThinkingLevel,\n compact: handleCompact,\n abort_compaction: handleAbortCompaction,\n set_auto_compaction: handleSetAutoCompaction,\n set_auto_retry: handleSetAutoRetry,\n abort_retry: handleAbortRetry,\n bash: handleBash,\n abort_bash: handleAbortBash,\n get_session_stats: handleGetSessionStats,\n set_session_name: handleSetSessionName,\n export_html: handleExportHtml,\n new_session: handleNewSession,\n switch_session_file: handleSwitchSessionFile,\n fork: handleFork,\n get_fork_messages: handleGetForkMessages,\n get_last_assistant_text: handleGetLastAssistantText,\n get_context_usage: handleGetContextUsage,\n};\n\n// =============================================================================\n// ROUTING FUNCTION\n// =============================================================================\n\n/**\n * Route a session command to the appropriate handler.\n * Returns a response or undefined if no handler exists (unknown command).\n */\nexport function routeSessionCommand(\n session: AgentSession,\n command: any,\n getSessionInfo: (sessionId: string) => SessionInfo | undefined\n): Promise<RpcResponse> | RpcResponse | undefined {\n const handler = sessionCommandHandlers[command.type];\n if (!handler) {\n return undefined;\n }\n return handler(session, command, getSessionInfo);\n}\n\n/**\n * Get list of supported session command types.\n */\nexport function getSupportedSessionCommands(): string[] {\n return Object.keys(sessionCommandHandlers);\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["path"]
7
+ }
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Extension UI - tracks pending UI requests from extensions and routes responses.
3
+ *
4
+ * NOTE: Extension UI requests are NOT AgentSessionEvents. They come through
5
+ * the ExtensionUIContext interface which must be provided when binding extensions.
6
+ *
7
+ * This module provides:
8
+ * - Types for extension UI commands/responses
9
+ * - ExtensionUIManager for tracking pending requests (used when we provide our own UIContext)
10
+ *
11
+ * Phase 3 will wire this up by providing a custom ExtensionUIContext to bindExtensions().
12
+ */
13
+ export interface PendingUIRequest {
14
+ sessionId: string;
15
+ requestId: string;
16
+ method: ExtensionUIMethod;
17
+ resolve: (response: ExtensionUIResponseValue) => void;
18
+ reject: (error: Error) => void;
19
+ timeout: NodeJS.Timeout;
20
+ createdAt: Date;
21
+ /** Guard flag to prevent double-resolve on race between timeout and cancel */
22
+ settled: boolean;
23
+ }
24
+ export type ExtensionUIMethod = "select" | "confirm" | "input" | "editor" | "interview" | "notify" | "setStatus" | "setWidget" | "setTitle";
25
+ export type ExtensionUIResponseValue = {
26
+ method: "select";
27
+ value: string;
28
+ } | {
29
+ method: "confirm";
30
+ confirmed: boolean;
31
+ } | {
32
+ method: "input";
33
+ value: string;
34
+ } | {
35
+ method: "editor";
36
+ value: string;
37
+ } | {
38
+ method: "interview";
39
+ responses: Record<string, any>;
40
+ } | {
41
+ method: "cancelled";
42
+ };
43
+ export declare function isSelectResponse(r: ExtensionUIResponseValue): r is {
44
+ method: "select";
45
+ value: string;
46
+ };
47
+ export declare function isConfirmResponse(r: ExtensionUIResponseValue): r is {
48
+ method: "confirm";
49
+ confirmed: boolean;
50
+ };
51
+ export declare function isInputResponse(r: ExtensionUIResponseValue): r is {
52
+ method: "input";
53
+ value: string;
54
+ };
55
+ export declare function isEditorResponse(r: ExtensionUIResponseValue): r is {
56
+ method: "editor";
57
+ value: string;
58
+ };
59
+ export interface ExtensionUIResponseCommand {
60
+ id?: string;
61
+ sessionId: string;
62
+ type: "extension_ui_response";
63
+ requestId: string;
64
+ response: ExtensionUIResponseValue;
65
+ }
66
+ /**
67
+ * Statistics about the extension UI manager.
68
+ */
69
+ export interface ExtensionUIManagerStats {
70
+ /** Current number of pending requests. */
71
+ pendingCount: number;
72
+ /** Maximum pending requests allowed. */
73
+ maxPendingRequests: number;
74
+ /** Total requests rejected due to limit. */
75
+ rejectedCount: number;
76
+ }
77
+ export declare class ExtensionUIManager {
78
+ private pendingRequests;
79
+ private defaultTimeoutMs;
80
+ private maxPendingRequests;
81
+ private rejectedCount;
82
+ private broadcast;
83
+ constructor(broadcast: (sessionId: string, event: any) => void, defaultTimeoutMs?: number, maxPendingRequests?: number);
84
+ /**
85
+ * Check if a new pending request would exceed the limit.
86
+ * Use this to check before calling createPendingRequest if you need to
87
+ * distinguish limit reached from other failure modes.
88
+ */
89
+ wouldExceedLimit(): boolean;
90
+ /**
91
+ * Handle a UI request from an extension.
92
+ * This is called by our ExtensionUIContext implementation.
93
+ * Returns the requestId and a promise that resolves when client responds.
94
+ *
95
+ * Returns null if the pending request limit has been reached.
96
+ */
97
+ createPendingRequest(sessionId: string, method: ExtensionUIMethod, requestData: Record<string, any>): {
98
+ requestId: string;
99
+ promise: Promise<ExtensionUIResponseValue>;
100
+ } | null;
101
+ /**
102
+ * Broadcast a UI request to clients.
103
+ */
104
+ broadcastUIRequest(sessionId: string, requestId: string, method: ExtensionUIMethod, data: Record<string, any>): void;
105
+ /**
106
+ * Handle a response from a client to a pending UI request.
107
+ * Returns true if the response was handled, false if no pending request found.
108
+ */
109
+ handleUIResponse(command: ExtensionUIResponseCommand): {
110
+ success: boolean;
111
+ error?: string;
112
+ };
113
+ /**
114
+ * Get all pending requests for a session (for debugging/cleanup).
115
+ */
116
+ getPendingRequests(sessionId: string): PendingUIRequest[];
117
+ /**
118
+ * Cancel all pending requests for a session (e.g., when session is deleted).
119
+ */
120
+ cancelSessionRequests(sessionId: string): void;
121
+ /**
122
+ * Cancel a specific pending request (e.g., on abort signal).
123
+ */
124
+ cancelRequest(requestId: string): void;
125
+ /**
126
+ * Get count of pending requests (for monitoring).
127
+ */
128
+ getPendingCount(): number;
129
+ /**
130
+ * Get full statistics about the manager (for monitoring).
131
+ */
132
+ getStats(): ExtensionUIManagerStats;
133
+ /**
134
+ * Reset rejected count (for testing).
135
+ */
136
+ resetStats(): void;
137
+ private generateRequestId;
138
+ }
139
+ //# sourceMappingURL=extension-ui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-ui.d.ts","sourceRoot":"","sources":["../src/extension-ui.ts"],"names":[],"mappings":"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"}