@bastani/atomic 0.9.4-alpha.4 → 0.9.4-alpha.6

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 (180) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/dist/builtin/cursor/CHANGELOG.md +12 -0
  3. package/dist/builtin/cursor/package.json +3 -3
  4. package/dist/builtin/intercom/CHANGELOG.md +12 -0
  5. package/dist/builtin/intercom/package.json +2 -2
  6. package/dist/builtin/mcp/CHANGELOG.md +12 -0
  7. package/dist/builtin/mcp/package.json +3 -3
  8. package/dist/builtin/subagents/CHANGELOG.md +12 -0
  9. package/dist/builtin/subagents/package.json +4 -4
  10. package/dist/builtin/web-access/CHANGELOG.md +12 -0
  11. package/dist/builtin/web-access/package.json +2 -2
  12. package/dist/builtin/workflows/CHANGELOG.md +12 -0
  13. package/dist/builtin/workflows/package.json +2 -2
  14. package/dist/cli/file-processor.d.ts.map +1 -1
  15. package/dist/cli/file-processor.js +13 -25
  16. package/dist/cli/file-processor.js.map +1 -1
  17. package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
  18. package/dist/core/agent-session-auto-compaction.js +8 -1
  19. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  20. package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
  21. package/dist/core/agent-session-extension-bindings.js +1 -1
  22. package/dist/core/agent-session-extension-bindings.js.map +1 -1
  23. package/dist/core/agent-session-methods.d.ts +3 -0
  24. package/dist/core/agent-session-methods.d.ts.map +1 -1
  25. package/dist/core/agent-session-methods.js.map +1 -1
  26. package/dist/core/agent-session-prompt.d.ts +2 -0
  27. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  28. package/dist/core/agent-session-prompt.js +15 -2
  29. package/dist/core/agent-session-prompt.js.map +1 -1
  30. package/dist/core/agent-session-state.d.ts.map +1 -1
  31. package/dist/core/agent-session-state.js +2 -2
  32. package/dist/core/agent-session-state.js.map +1 -1
  33. package/dist/core/agent-session-tool-hooks.d.ts +7 -1
  34. package/dist/core/agent-session-tool-hooks.d.ts.map +1 -1
  35. package/dist/core/agent-session-tool-hooks.js +26 -4
  36. package/dist/core/agent-session-tool-hooks.js.map +1 -1
  37. package/dist/core/agent-session-tree.d.ts.map +1 -1
  38. package/dist/core/agent-session-tree.js +3 -1
  39. package/dist/core/agent-session-tree.js.map +1 -1
  40. package/dist/core/agent-session-types.d.ts +4 -0
  41. package/dist/core/agent-session-types.d.ts.map +1 -1
  42. package/dist/core/agent-session-types.js.map +1 -1
  43. package/dist/core/agent-session.d.ts +1 -0
  44. package/dist/core/agent-session.d.ts.map +1 -1
  45. package/dist/core/agent-session.js +1 -0
  46. package/dist/core/agent-session.js.map +1 -1
  47. package/dist/core/copilot-model-catalog.d.ts +18 -5
  48. package/dist/core/copilot-model-catalog.d.ts.map +1 -1
  49. package/dist/core/copilot-model-catalog.js +64 -5
  50. package/dist/core/copilot-model-catalog.js.map +1 -1
  51. package/dist/core/extensions/api-types.d.ts +2 -1
  52. package/dist/core/extensions/api-types.d.ts.map +1 -1
  53. package/dist/core/extensions/api-types.js.map +1 -1
  54. package/dist/core/extensions/index.d.ts +1 -1
  55. package/dist/core/extensions/index.d.ts.map +1 -1
  56. package/dist/core/extensions/index.js.map +1 -1
  57. package/dist/core/extensions/loader-core.d.ts.map +1 -1
  58. package/dist/core/extensions/loader-core.js +3 -3
  59. package/dist/core/extensions/loader-core.js.map +1 -1
  60. package/dist/core/extensions/session-events.d.ts +7 -1
  61. package/dist/core/extensions/session-events.d.ts.map +1 -1
  62. package/dist/core/extensions/session-events.js.map +1 -1
  63. package/dist/core/http-dispatcher.d.ts.map +1 -1
  64. package/dist/core/http-dispatcher.js +28 -1
  65. package/dist/core/http-dispatcher.js.map +1 -1
  66. package/dist/core/model-registry-builtins.d.ts.map +1 -1
  67. package/dist/core/model-registry-builtins.js +10 -2
  68. package/dist/core/model-registry-builtins.js.map +1 -1
  69. package/dist/core/model-registry.d.ts.map +1 -1
  70. package/dist/core/model-registry.js +4 -3
  71. package/dist/core/model-registry.js.map +1 -1
  72. package/dist/core/model-resolver-defaults.d.ts.map +1 -1
  73. package/dist/core/model-resolver-defaults.js +1 -1
  74. package/dist/core/model-resolver-defaults.js.map +1 -1
  75. package/dist/core/resource-loader-reload.d.ts.map +1 -1
  76. package/dist/core/resource-loader-reload.js +2 -1
  77. package/dist/core/resource-loader-reload.js.map +1 -1
  78. package/dist/core/session-manager-core.d.ts +2 -12
  79. package/dist/core/session-manager-core.d.ts.map +1 -1
  80. package/dist/core/session-manager-core.js +8 -16
  81. package/dist/core/session-manager-core.js.map +1 -1
  82. package/dist/core/settings-manager-resource-accessors.d.ts +1 -0
  83. package/dist/core/settings-manager-resource-accessors.d.ts.map +1 -1
  84. package/dist/core/settings-manager-resource-accessors.js +11 -0
  85. package/dist/core/settings-manager-resource-accessors.js.map +1 -1
  86. package/dist/core/settings-manager-ui-accessors.d.ts +2 -0
  87. package/dist/core/settings-manager-ui-accessors.d.ts.map +1 -1
  88. package/dist/core/settings-manager-ui-accessors.js +9 -0
  89. package/dist/core/settings-manager-ui-accessors.js.map +1 -1
  90. package/dist/core/settings-types.d.ts +2 -0
  91. package/dist/core/settings-types.d.ts.map +1 -1
  92. package/dist/core/settings-types.js.map +1 -1
  93. package/dist/core/timings.d.ts +7 -5
  94. package/dist/core/timings.d.ts.map +1 -1
  95. package/dist/core/timings.js +42 -24
  96. package/dist/core/timings.js.map +1 -1
  97. package/dist/core/tools/read.d.ts.map +1 -1
  98. package/dist/core/tools/read.js +12 -23
  99. package/dist/core/tools/read.js.map +1 -1
  100. package/dist/index-extensions.d.ts +1 -1
  101. package/dist/index-extensions.d.ts.map +1 -1
  102. package/dist/index-extensions.js.map +1 -1
  103. package/dist/index.d.ts +1 -1
  104. package/dist/index.d.ts.map +1 -1
  105. package/dist/index.js.map +1 -1
  106. package/dist/main-session.d.ts.map +1 -1
  107. package/dist/main-session.js +14 -5
  108. package/dist/main-session.js.map +1 -1
  109. package/dist/modes/interactive/components/assistant-message.d.ts +3 -1
  110. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  111. package/dist/modes/interactive/components/assistant-message.js +22 -15
  112. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  113. package/dist/modes/interactive/components/chat-message-renderer.d.ts +1 -0
  114. package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
  115. package/dist/modes/interactive/components/chat-message-renderer.js +5 -5
  116. package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
  117. package/dist/modes/interactive/components/chat-session-host-events.d.ts.map +1 -1
  118. package/dist/modes/interactive/components/chat-session-host-events.js +8 -0
  119. package/dist/modes/interactive/components/chat-session-host-events.js.map +1 -1
  120. package/dist/modes/interactive/components/chat-session-host-rendering.d.ts.map +1 -1
  121. package/dist/modes/interactive/components/chat-session-host-rendering.js +1 -0
  122. package/dist/modes/interactive/components/chat-session-host-rendering.js.map +1 -1
  123. package/dist/modes/interactive/components/user-message.d.ts +6 -2
  124. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  125. package/dist/modes/interactive/components/user-message.js +16 -5
  126. package/dist/modes/interactive/components/user-message.js.map +1 -1
  127. package/dist/modes/interactive/interactive-agent-events.d.ts.map +1 -1
  128. package/dist/modes/interactive/interactive-agent-events.js +6 -1
  129. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  130. package/dist/modes/interactive/interactive-editor-actions.d.ts.map +1 -1
  131. package/dist/modes/interactive/interactive-editor-actions.js +1 -0
  132. package/dist/modes/interactive/interactive-editor-actions.js.map +1 -1
  133. package/dist/modes/interactive/interactive-extension-context.d.ts.map +1 -1
  134. package/dist/modes/interactive/interactive-extension-context.js +1 -0
  135. package/dist/modes/interactive/interactive-extension-context.js.map +1 -1
  136. package/dist/modes/interactive/interactive-mode-base.d.ts +1 -0
  137. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  138. package/dist/modes/interactive/interactive-mode-base.js +2 -0
  139. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  140. package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
  141. package/dist/modes/interactive/interactive-model-routing.js +1 -4
  142. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  143. package/dist/modes/interactive/interactive-render-chat.d.ts.map +1 -1
  144. package/dist/modes/interactive/interactive-render-chat.js +4 -3
  145. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  146. package/dist/modes/interactive/interactive-session-runtime.d.ts.map +1 -1
  147. package/dist/modes/interactive/interactive-session-runtime.js +1 -0
  148. package/dist/modes/interactive/interactive-session-runtime.js.map +1 -1
  149. package/dist/modes/rpc/rpc-client.d.ts +28 -51
  150. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  151. package/dist/modes/rpc/rpc-client.js +27 -51
  152. package/dist/modes/rpc/rpc-client.js.map +1 -1
  153. package/dist/modes/rpc/rpc-command-handler.d.ts.map +1 -1
  154. package/dist/modes/rpc/rpc-command-handler.js +19 -0
  155. package/dist/modes/rpc/rpc-command-handler.js.map +1 -1
  156. package/dist/modes/rpc/rpc-types.d.ts +26 -0
  157. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  158. package/dist/modes/rpc/rpc-types.js.map +1 -1
  159. package/dist/rpc-entry.d.ts +3 -0
  160. package/dist/rpc-entry.d.ts.map +1 -0
  161. package/dist/rpc-entry.js +12 -0
  162. package/dist/rpc-entry.js.map +1 -0
  163. package/dist/utils/image-convert.d.ts +1 -0
  164. package/dist/utils/image-convert.d.ts.map +1 -1
  165. package/dist/utils/image-convert.js +21 -15
  166. package/dist/utils/image-convert.js.map +1 -1
  167. package/dist/utils/image-process.d.ts +18 -0
  168. package/dist/utils/image-process.d.ts.map +1 -0
  169. package/dist/utils/image-process.js +83 -0
  170. package/dist/utils/image-process.js.map +1 -0
  171. package/dist/utils/mime.d.ts.map +1 -1
  172. package/dist/utils/mime.js +41 -0
  173. package/dist/utils/mime.js.map +1 -1
  174. package/docs/compaction.md +2 -0
  175. package/docs/extensions.md +11 -0
  176. package/docs/providers.md +1 -0
  177. package/docs/rpc.md +58 -0
  178. package/docs/settings.md +2 -0
  179. package/npm-shrinkwrap.json +134 -136
  180. package/package.json +11 -6
@@ -1 +1 @@
1
- {"version":3,"file":"interactive-session-runtime.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-session-runtime.ts"],"names":[],"mappings":"","sourcesContent":["import { InteractiveModeBase } from \"./interactive-mode-base.ts\";\nimport { type AgentSession, setRegisteredThemes, stopThemeWatcher } from \"./interactive-mode-deps.ts\";\n\nInteractiveModeBase.prototype.bindCurrentSessionExtensions = async function(this: InteractiveModeBase): Promise<void> {\n const uiContext = this.createExtensionUIContext();\n await this.session.bindExtensions({\n uiContext,\n mode: \"tui\",\n commandContextActions: {\n waitForIdle: () => this.session.agent.waitForIdle(),\n newSession: async (options) => {\n if (this.loadingAnimation) {\n this.loadingAnimation.stop();\n this.loadingAnimation = undefined;\n }\n this.statusContainer.clear();\n try {\n const result = await this.runtimeHost.newSession(options);\n if (!result.cancelled) {\n this.renderCurrentSessionState();\n this.ui.requestRender();\n }\n return result;\n } catch (error: unknown) {\n return this.handleFatalRuntimeError(\n \"Failed to create session\",\n error,\n );\n }\n },\n fork: async (entryId, options) => {\n try {\n const result = await this.runtimeHost.fork(entryId, options);\n if (!result.cancelled) {\n this.renderCurrentSessionState();\n this.editor.setText(result.selectedText ?? \"\");\n this.showStatus(\"Forked to new session\");\n }\n return { cancelled: result.cancelled };\n } catch (error: unknown) {\n return this.handleFatalRuntimeError(\n \"Failed to fork session\",\n error,\n );\n }\n },\n navigateTree: async (targetId, options) => {\n const result = await this.session.navigateTree(targetId, {\n summarize: options?.summarize,\n customInstructions: options?.customInstructions,\n replaceInstructions: options?.replaceInstructions,\n label: options?.label,\n });\n if (result.cancelled) {\n return { cancelled: true };\n }\n\n this.chatContainer.clear();\n this.renderInitialMessages();\n if (result.editorText && !this.editor.getText().trim()) {\n this.editor.setText(result.editorText);\n }\n this.showStatus(\"Navigated to selected point\");\n void this.flushCompactionQueue({ willRetry: false });\n return { cancelled: false };\n },\n switchSession: async (sessionPath, options) => {\n return this.handleResumeSession(sessionPath, options);\n },\n reload: async () => {\n await this.handleReloadCommand();\n },\n },\n shutdownHandler: () => {\n this.shutdownRequested = true;\n if (!this.session.isStreaming) {\n void this.shutdown();\n }\n },\n onError: (error) => {\n this.showExtensionError(error.extensionPath, error.error, error.stack);\n },\n });\n\n setRegisteredThemes(this.session.resourceLoader.getThemes().themes);\n this.setupAutocompleteProvider();\n\n const extensionRunner = this.session.extensionRunner;\n this.setupExtensionShortcuts(extensionRunner);\n this.showLoadedResources({ force: false, showDiagnosticsWhenQuiet: true });\n this.showStartupNoticesIfNeeded();\n };\n\nInteractiveModeBase.prototype.applyRuntimeSettings = function(this: InteractiveModeBase): void {\n this.footer.setSession(this.session);\n this.usageMeter.setSession(this.session);\n this.usageMeter.setAutoCompactEnabled(this.session.autoCompactionEnabled);\n this.footerDataProvider.setCwd(this.sessionManager.getCwd());\n this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();\n this.ui.setShowHardwareCursor(this.settingsManager.getShowHardwareCursor());\n this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink());\n const editorPaddingX = this.settingsManager.getEditorPaddingX();\n const autocompleteMaxVisible =\n this.settingsManager.getAutocompleteMaxVisible();\n this.defaultEditor.setPaddingX(editorPaddingX);\n this.defaultEditor.setAutocompleteMaxVisible(autocompleteMaxVisible);\n if (this.editor !== this.defaultEditor) {\n this.editor.setPaddingX?.(editorPaddingX);\n this.editor.setAutocompleteMaxVisible?.(autocompleteMaxVisible);\n }\n };\n\nInteractiveModeBase.prototype.rebindCurrentSession = async function(this: InteractiveModeBase): Promise<void> {\n this.unsubscribe?.();\n this.unsubscribe = undefined;\n this.applyRuntimeSettings();\n await this.bindCurrentSessionExtensions();\n this.subscribeToAgent();\n await this.updateAvailableProviderCount();\n this.updateEditorBorderColor();\n this.updateTerminalTitle();\n };\n\nInteractiveModeBase.prototype.handleFatalRuntimeError = async function(this: InteractiveModeBase, prefix: string, error: unknown): Promise<never> {\n const message = error instanceof Error ? error.message : String(error);\n this.showError(`${prefix}: ${message}`);\n stopThemeWatcher();\n this.stop();\n process.exit(1);\n };\n\nInteractiveModeBase.prototype.renderCurrentSessionState = function(this: InteractiveModeBase): void {\n this.chatContainer.clear();\n this.pendingMessagesContainer.clear();\n this.compactionQueuedMessages = [];\n this.streamingComponent = undefined;\n this.streamingMessage = undefined;\n this.pendingTools.clear();\n this.renderInitialMessages();\n };\n\nInteractiveModeBase.prototype.getRegisteredToolDefinition = function(this: InteractiveModeBase, toolName: string): ReturnType<AgentSession[\"getToolDefinition\"]> {\n return this.session.getToolDefinition(toolName);\n };\n"]}
1
+ {"version":3,"file":"interactive-session-runtime.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-session-runtime.ts"],"names":[],"mappings":"","sourcesContent":["import { InteractiveModeBase } from \"./interactive-mode-base.ts\";\nimport { type AgentSession, setRegisteredThemes, stopThemeWatcher } from \"./interactive-mode-deps.ts\";\n\nInteractiveModeBase.prototype.bindCurrentSessionExtensions = async function(this: InteractiveModeBase): Promise<void> {\n const uiContext = this.createExtensionUIContext();\n await this.session.bindExtensions({\n uiContext,\n mode: \"tui\",\n commandContextActions: {\n waitForIdle: () => this.session.agent.waitForIdle(),\n newSession: async (options) => {\n if (this.loadingAnimation) {\n this.loadingAnimation.stop();\n this.loadingAnimation = undefined;\n }\n this.statusContainer.clear();\n try {\n const result = await this.runtimeHost.newSession(options);\n if (!result.cancelled) {\n this.renderCurrentSessionState();\n this.ui.requestRender();\n }\n return result;\n } catch (error: unknown) {\n return this.handleFatalRuntimeError(\n \"Failed to create session\",\n error,\n );\n }\n },\n fork: async (entryId, options) => {\n try {\n const result = await this.runtimeHost.fork(entryId, options);\n if (!result.cancelled) {\n this.renderCurrentSessionState();\n this.editor.setText(result.selectedText ?? \"\");\n this.showStatus(\"Forked to new session\");\n }\n return { cancelled: result.cancelled };\n } catch (error: unknown) {\n return this.handleFatalRuntimeError(\n \"Failed to fork session\",\n error,\n );\n }\n },\n navigateTree: async (targetId, options) => {\n const result = await this.session.navigateTree(targetId, {\n summarize: options?.summarize,\n customInstructions: options?.customInstructions,\n replaceInstructions: options?.replaceInstructions,\n label: options?.label,\n });\n if (result.cancelled) {\n return { cancelled: true };\n }\n\n this.chatContainer.clear();\n this.renderInitialMessages();\n if (result.editorText && !this.editor.getText().trim()) {\n this.editor.setText(result.editorText);\n }\n this.showStatus(\"Navigated to selected point\");\n void this.flushCompactionQueue({ willRetry: false });\n return { cancelled: false };\n },\n switchSession: async (sessionPath, options) => {\n return this.handleResumeSession(sessionPath, options);\n },\n reload: async () => {\n await this.handleReloadCommand();\n },\n },\n shutdownHandler: () => {\n this.shutdownRequested = true;\n if (!this.session.isStreaming) {\n void this.shutdown();\n }\n },\n onError: (error) => {\n this.showExtensionError(error.extensionPath, error.error, error.stack);\n },\n });\n\n setRegisteredThemes(this.session.resourceLoader.getThemes().themes);\n this.setupAutocompleteProvider();\n\n const extensionRunner = this.session.extensionRunner;\n this.setupExtensionShortcuts(extensionRunner);\n this.showLoadedResources({ force: false, showDiagnosticsWhenQuiet: true });\n this.showStartupNoticesIfNeeded();\n };\n\nInteractiveModeBase.prototype.applyRuntimeSettings = function(this: InteractiveModeBase): void {\n this.footer.setSession(this.session);\n this.usageMeter.setSession(this.session);\n this.usageMeter.setAutoCompactEnabled(this.session.autoCompactionEnabled);\n this.footerDataProvider.setCwd(this.sessionManager.getCwd());\n this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();\n this.outputPad = this.settingsManager.getOutputPad();\n this.ui.setShowHardwareCursor(this.settingsManager.getShowHardwareCursor());\n this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink());\n const editorPaddingX = this.settingsManager.getEditorPaddingX();\n const autocompleteMaxVisible =\n this.settingsManager.getAutocompleteMaxVisible();\n this.defaultEditor.setPaddingX(editorPaddingX);\n this.defaultEditor.setAutocompleteMaxVisible(autocompleteMaxVisible);\n if (this.editor !== this.defaultEditor) {\n this.editor.setPaddingX?.(editorPaddingX);\n this.editor.setAutocompleteMaxVisible?.(autocompleteMaxVisible);\n }\n };\n\nInteractiveModeBase.prototype.rebindCurrentSession = async function(this: InteractiveModeBase): Promise<void> {\n this.unsubscribe?.();\n this.unsubscribe = undefined;\n this.applyRuntimeSettings();\n await this.bindCurrentSessionExtensions();\n this.subscribeToAgent();\n await this.updateAvailableProviderCount();\n this.updateEditorBorderColor();\n this.updateTerminalTitle();\n };\n\nInteractiveModeBase.prototype.handleFatalRuntimeError = async function(this: InteractiveModeBase, prefix: string, error: unknown): Promise<never> {\n const message = error instanceof Error ? error.message : String(error);\n this.showError(`${prefix}: ${message}`);\n stopThemeWatcher();\n this.stop();\n process.exit(1);\n };\n\nInteractiveModeBase.prototype.renderCurrentSessionState = function(this: InteractiveModeBase): void {\n this.chatContainer.clear();\n this.pendingMessagesContainer.clear();\n this.compactionQueuedMessages = [];\n this.streamingComponent = undefined;\n this.streamingMessage = undefined;\n this.pendingTools.clear();\n this.renderInitialMessages();\n };\n\nInteractiveModeBase.prototype.getRegisteredToolDefinition = function(this: InteractiveModeBase, toolName: string): ReturnType<AgentSession[\"getToolDefinition\"]> {\n return this.session.getToolDefinition(toolName);\n };\n"]}
@@ -88,6 +88,7 @@ InteractiveModeBase.prototype.applyRuntimeSettings = function () {
88
88
  this.usageMeter.setAutoCompactEnabled(this.session.autoCompactionEnabled);
89
89
  this.footerDataProvider.setCwd(this.sessionManager.getCwd());
90
90
  this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();
91
+ this.outputPad = this.settingsManager.getOutputPad();
91
92
  this.ui.setShowHardwareCursor(this.settingsManager.getShowHardwareCursor());
92
93
  this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink());
93
94
  const editorPaddingX = this.settingsManager.getEditorPaddingX();
@@ -1 +1 @@
1
- {"version":3,"file":"interactive-session-runtime.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-session-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { InteractiveModeBase } from \"./interactive-mode-base.ts\";\nimport { type AgentSession, setRegisteredThemes, stopThemeWatcher } from \"./interactive-mode-deps.ts\";\n\nInteractiveModeBase.prototype.bindCurrentSessionExtensions = async function(this: InteractiveModeBase): Promise<void> {\n const uiContext = this.createExtensionUIContext();\n await this.session.bindExtensions({\n uiContext,\n mode: \"tui\",\n commandContextActions: {\n waitForIdle: () => this.session.agent.waitForIdle(),\n newSession: async (options) => {\n if (this.loadingAnimation) {\n this.loadingAnimation.stop();\n this.loadingAnimation = undefined;\n }\n this.statusContainer.clear();\n try {\n const result = await this.runtimeHost.newSession(options);\n if (!result.cancelled) {\n this.renderCurrentSessionState();\n this.ui.requestRender();\n }\n return result;\n } catch (error: unknown) {\n return this.handleFatalRuntimeError(\n \"Failed to create session\",\n error,\n );\n }\n },\n fork: async (entryId, options) => {\n try {\n const result = await this.runtimeHost.fork(entryId, options);\n if (!result.cancelled) {\n this.renderCurrentSessionState();\n this.editor.setText(result.selectedText ?? \"\");\n this.showStatus(\"Forked to new session\");\n }\n return { cancelled: result.cancelled };\n } catch (error: unknown) {\n return this.handleFatalRuntimeError(\n \"Failed to fork session\",\n error,\n );\n }\n },\n navigateTree: async (targetId, options) => {\n const result = await this.session.navigateTree(targetId, {\n summarize: options?.summarize,\n customInstructions: options?.customInstructions,\n replaceInstructions: options?.replaceInstructions,\n label: options?.label,\n });\n if (result.cancelled) {\n return { cancelled: true };\n }\n\n this.chatContainer.clear();\n this.renderInitialMessages();\n if (result.editorText && !this.editor.getText().trim()) {\n this.editor.setText(result.editorText);\n }\n this.showStatus(\"Navigated to selected point\");\n void this.flushCompactionQueue({ willRetry: false });\n return { cancelled: false };\n },\n switchSession: async (sessionPath, options) => {\n return this.handleResumeSession(sessionPath, options);\n },\n reload: async () => {\n await this.handleReloadCommand();\n },\n },\n shutdownHandler: () => {\n this.shutdownRequested = true;\n if (!this.session.isStreaming) {\n void this.shutdown();\n }\n },\n onError: (error) => {\n this.showExtensionError(error.extensionPath, error.error, error.stack);\n },\n });\n\n setRegisteredThemes(this.session.resourceLoader.getThemes().themes);\n this.setupAutocompleteProvider();\n\n const extensionRunner = this.session.extensionRunner;\n this.setupExtensionShortcuts(extensionRunner);\n this.showLoadedResources({ force: false, showDiagnosticsWhenQuiet: true });\n this.showStartupNoticesIfNeeded();\n };\n\nInteractiveModeBase.prototype.applyRuntimeSettings = function(this: InteractiveModeBase): void {\n this.footer.setSession(this.session);\n this.usageMeter.setSession(this.session);\n this.usageMeter.setAutoCompactEnabled(this.session.autoCompactionEnabled);\n this.footerDataProvider.setCwd(this.sessionManager.getCwd());\n this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();\n this.ui.setShowHardwareCursor(this.settingsManager.getShowHardwareCursor());\n this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink());\n const editorPaddingX = this.settingsManager.getEditorPaddingX();\n const autocompleteMaxVisible =\n this.settingsManager.getAutocompleteMaxVisible();\n this.defaultEditor.setPaddingX(editorPaddingX);\n this.defaultEditor.setAutocompleteMaxVisible(autocompleteMaxVisible);\n if (this.editor !== this.defaultEditor) {\n this.editor.setPaddingX?.(editorPaddingX);\n this.editor.setAutocompleteMaxVisible?.(autocompleteMaxVisible);\n }\n };\n\nInteractiveModeBase.prototype.rebindCurrentSession = async function(this: InteractiveModeBase): Promise<void> {\n this.unsubscribe?.();\n this.unsubscribe = undefined;\n this.applyRuntimeSettings();\n await this.bindCurrentSessionExtensions();\n this.subscribeToAgent();\n await this.updateAvailableProviderCount();\n this.updateEditorBorderColor();\n this.updateTerminalTitle();\n };\n\nInteractiveModeBase.prototype.handleFatalRuntimeError = async function(this: InteractiveModeBase, prefix: string, error: unknown): Promise<never> {\n const message = error instanceof Error ? error.message : String(error);\n this.showError(`${prefix}: ${message}`);\n stopThemeWatcher();\n this.stop();\n process.exit(1);\n };\n\nInteractiveModeBase.prototype.renderCurrentSessionState = function(this: InteractiveModeBase): void {\n this.chatContainer.clear();\n this.pendingMessagesContainer.clear();\n this.compactionQueuedMessages = [];\n this.streamingComponent = undefined;\n this.streamingMessage = undefined;\n this.pendingTools.clear();\n this.renderInitialMessages();\n };\n\nInteractiveModeBase.prototype.getRegisteredToolDefinition = function(this: InteractiveModeBase, toolName: string): ReturnType<AgentSession[\"getToolDefinition\"]> {\n return this.session.getToolDefinition(toolName);\n };\n"]}
1
+ {"version":3,"file":"interactive-session-runtime.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-session-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { InteractiveModeBase } from \"./interactive-mode-base.ts\";\nimport { type AgentSession, setRegisteredThemes, stopThemeWatcher } from \"./interactive-mode-deps.ts\";\n\nInteractiveModeBase.prototype.bindCurrentSessionExtensions = async function(this: InteractiveModeBase): Promise<void> {\n const uiContext = this.createExtensionUIContext();\n await this.session.bindExtensions({\n uiContext,\n mode: \"tui\",\n commandContextActions: {\n waitForIdle: () => this.session.agent.waitForIdle(),\n newSession: async (options) => {\n if (this.loadingAnimation) {\n this.loadingAnimation.stop();\n this.loadingAnimation = undefined;\n }\n this.statusContainer.clear();\n try {\n const result = await this.runtimeHost.newSession(options);\n if (!result.cancelled) {\n this.renderCurrentSessionState();\n this.ui.requestRender();\n }\n return result;\n } catch (error: unknown) {\n return this.handleFatalRuntimeError(\n \"Failed to create session\",\n error,\n );\n }\n },\n fork: async (entryId, options) => {\n try {\n const result = await this.runtimeHost.fork(entryId, options);\n if (!result.cancelled) {\n this.renderCurrentSessionState();\n this.editor.setText(result.selectedText ?? \"\");\n this.showStatus(\"Forked to new session\");\n }\n return { cancelled: result.cancelled };\n } catch (error: unknown) {\n return this.handleFatalRuntimeError(\n \"Failed to fork session\",\n error,\n );\n }\n },\n navigateTree: async (targetId, options) => {\n const result = await this.session.navigateTree(targetId, {\n summarize: options?.summarize,\n customInstructions: options?.customInstructions,\n replaceInstructions: options?.replaceInstructions,\n label: options?.label,\n });\n if (result.cancelled) {\n return { cancelled: true };\n }\n\n this.chatContainer.clear();\n this.renderInitialMessages();\n if (result.editorText && !this.editor.getText().trim()) {\n this.editor.setText(result.editorText);\n }\n this.showStatus(\"Navigated to selected point\");\n void this.flushCompactionQueue({ willRetry: false });\n return { cancelled: false };\n },\n switchSession: async (sessionPath, options) => {\n return this.handleResumeSession(sessionPath, options);\n },\n reload: async () => {\n await this.handleReloadCommand();\n },\n },\n shutdownHandler: () => {\n this.shutdownRequested = true;\n if (!this.session.isStreaming) {\n void this.shutdown();\n }\n },\n onError: (error) => {\n this.showExtensionError(error.extensionPath, error.error, error.stack);\n },\n });\n\n setRegisteredThemes(this.session.resourceLoader.getThemes().themes);\n this.setupAutocompleteProvider();\n\n const extensionRunner = this.session.extensionRunner;\n this.setupExtensionShortcuts(extensionRunner);\n this.showLoadedResources({ force: false, showDiagnosticsWhenQuiet: true });\n this.showStartupNoticesIfNeeded();\n };\n\nInteractiveModeBase.prototype.applyRuntimeSettings = function(this: InteractiveModeBase): void {\n this.footer.setSession(this.session);\n this.usageMeter.setSession(this.session);\n this.usageMeter.setAutoCompactEnabled(this.session.autoCompactionEnabled);\n this.footerDataProvider.setCwd(this.sessionManager.getCwd());\n this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();\n this.outputPad = this.settingsManager.getOutputPad();\n this.ui.setShowHardwareCursor(this.settingsManager.getShowHardwareCursor());\n this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink());\n const editorPaddingX = this.settingsManager.getEditorPaddingX();\n const autocompleteMaxVisible =\n this.settingsManager.getAutocompleteMaxVisible();\n this.defaultEditor.setPaddingX(editorPaddingX);\n this.defaultEditor.setAutocompleteMaxVisible(autocompleteMaxVisible);\n if (this.editor !== this.defaultEditor) {\n this.editor.setPaddingX?.(editorPaddingX);\n this.editor.setAutocompleteMaxVisible?.(autocompleteMaxVisible);\n }\n };\n\nInteractiveModeBase.prototype.rebindCurrentSession = async function(this: InteractiveModeBase): Promise<void> {\n this.unsubscribe?.();\n this.unsubscribe = undefined;\n this.applyRuntimeSettings();\n await this.bindCurrentSessionExtensions();\n this.subscribeToAgent();\n await this.updateAvailableProviderCount();\n this.updateEditorBorderColor();\n this.updateTerminalTitle();\n };\n\nInteractiveModeBase.prototype.handleFatalRuntimeError = async function(this: InteractiveModeBase, prefix: string, error: unknown): Promise<never> {\n const message = error instanceof Error ? error.message : String(error);\n this.showError(`${prefix}: ${message}`);\n stopThemeWatcher();\n this.stop();\n process.exit(1);\n };\n\nInteractiveModeBase.prototype.renderCurrentSessionState = function(this: InteractiveModeBase): void {\n this.chatContainer.clear();\n this.pendingMessagesContainer.clear();\n this.compactionQueuedMessages = [];\n this.streamingComponent = undefined;\n this.streamingMessage = undefined;\n this.pendingTools.clear();\n this.renderInitialMessages();\n };\n\nInteractiveModeBase.prototype.getRegisteredToolDefinition = function(this: InteractiveModeBase, toolName: string): ReturnType<AgentSession[\"getToolDefinition\"]> {\n return this.session.getToolDefinition(toolName);\n };\n"]}
@@ -8,6 +8,7 @@ import type { ImageContent } from "@earendil-works/pi-ai/compat";
8
8
  import type { SessionStats } from "../../core/agent-session.ts";
9
9
  import type { BashResult } from "../../core/bash-executor.ts";
10
10
  import type { ContextCompactionResult } from "../../core/compaction/index.ts";
11
+ import type { SessionEntry, SessionTreeNode } from "../../core/session-manager.ts";
11
12
  import type { RpcContextWindowInfo, RpcEvent, RpcSessionState, RpcSlashCommand } from "./rpc-types.ts";
12
13
  export type { RpcContextWindowInfo, RpcEvent } from "./rpc-types.ts";
13
14
  export interface RpcClientOptions {
@@ -43,21 +44,13 @@ export declare class RpcClient {
43
44
  private exitError;
44
45
  private options;
45
46
  constructor(options?: RpcClientOptions);
46
- /**
47
- * Start the RPC agent process.
48
- */
47
+ /** Start the RPC agent process. */
49
48
  start(): Promise<void>;
50
- /**
51
- * Stop the RPC agent process.
52
- */
49
+ /** Stop the RPC agent process. */
53
50
  stop(): Promise<void>;
54
- /**
55
- * Subscribe to agent events.
56
- */
51
+ /** Subscribe to agent events. */
57
52
  onEvent(listener: RpcEventListener): () => void;
58
- /**
59
- * Get collected stderr output (useful for debugging).
60
- */
53
+ /** Get collected stderr output (useful for debugging). */
61
54
  getStderr(): string;
62
55
  /**
63
56
  * Send a prompt to the agent.
@@ -65,17 +58,11 @@ export declare class RpcClient {
65
58
  * Use waitForIdle() to wait for completion.
66
59
  */
67
60
  prompt(message: string, images?: ImageContent[]): Promise<void>;
68
- /**
69
- * Queue a steering message to interrupt the agent mid-run.
70
- */
61
+ /** Queue a steering message to interrupt the agent mid-run. */
71
62
  steer(message: string, images?: ImageContent[]): Promise<void>;
72
- /**
73
- * Queue a follow-up message to be processed after the agent finishes.
74
- */
63
+ /** Queue a follow-up message to be processed after the agent finishes. */
75
64
  followUp(message: string, images?: ImageContent[]): Promise<void>;
76
- /**
77
- * Abort current operation.
78
- */
65
+ /** Abort current operation. */
79
66
  abort(): Promise<void>;
80
67
  /**
81
68
  * Start a new session, optionally with parent tracking.
@@ -85,20 +72,14 @@ export declare class RpcClient {
85
72
  newSession(parentSession?: string): Promise<{
86
73
  cancelled: boolean;
87
74
  }>;
88
- /**
89
- * Get current session state.
90
- */
75
+ /** Get current session state. */
91
76
  getState(): Promise<RpcSessionState>;
92
- /**
93
- * Set model by provider and ID.
94
- */
77
+ /** Set model by provider and ID. */
95
78
  setModel(provider: string, modelId: string): Promise<{
96
79
  provider: string;
97
80
  id: string;
98
81
  }>;
99
- /**
100
- * Cycle to next model.
101
- */
82
+ /** Cycle to next model. */
102
83
  cycleModel(): Promise<{
103
84
  model: {
104
85
  provider: string;
@@ -107,17 +88,11 @@ export declare class RpcClient {
107
88
  thinkingLevel: ThinkingLevel;
108
89
  isScoped: boolean;
109
90
  } | null>;
110
- /**
111
- * Get list of available models.
112
- */
91
+ /** Get list of available models. */
113
92
  getAvailableModels(): Promise<ModelInfo[]>;
114
- /**
115
- * Set thinking level.
116
- */
93
+ /** Set thinking level. */
117
94
  setThinkingLevel(level: ThinkingLevel): Promise<void>;
118
- /**
119
- * Cycle thinking level.
120
- */
95
+ /** Cycle thinking level. */
121
96
  cycleThinkingLevel(): Promise<{
122
97
  level: ThinkingLevel;
123
98
  } | null>;
@@ -126,21 +101,13 @@ export declare class RpcClient {
126
101
  * This is a runtime selection and does not persist context-window defaults.
127
102
  */
128
103
  setContextWindow(contextWindow: number | string): Promise<void>;
129
- /**
130
- * Get selectable context-window token budgets for the current model.
131
- */
104
+ /** Get selectable context-window token budgets for the current model. */
132
105
  getAvailableContextWindows(): Promise<RpcContextWindowInfo>;
133
- /**
134
- * Set steering mode.
135
- */
106
+ /** Set steering mode. */
136
107
  setSteeringMode(mode: "all" | "one-at-a-time"): Promise<void>;
137
- /**
138
- * Set follow-up mode.
139
- */
108
+ /** Set follow-up mode. */
140
109
  setFollowUpMode(mode: "all" | "one-at-a-time"): Promise<void>;
141
- /**
142
- * Compact session context with deletion-only verbatim context compaction.
143
- */
110
+ /** Compact session context with deletion-only verbatim context compaction. */
144
111
  compact(): Promise<ContextCompactionResult>;
145
112
  /** @deprecated Use compact() instead. */
146
113
  contextCompact(): Promise<ContextCompactionResult>;
@@ -167,6 +134,16 @@ export declare class RpcClient {
167
134
  entryId: string;
168
135
  text: string;
169
136
  }>>;
137
+ /** Session entries in append order, optionally only those after the `since` entry id. */
138
+ getEntries(since?: string): Promise<{
139
+ entries: SessionEntry[];
140
+ leafId: string | null;
141
+ }>;
142
+ /** The session entry tree. */
143
+ getTree(): Promise<{
144
+ tree: SessionTreeNode[];
145
+ leafId: string | null;
146
+ }>;
170
147
  getLastAssistantText(): Promise<string | null>;
171
148
  setSessionName(name: string): Promise<void>;
172
149
  getMessages(): Promise<AgentMessage[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"rpc-client.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-client.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * RPC Client for programmatic access to the coding agent.\n *\n * Spawns the agent in RPC mode and provides a typed API for all operations.\n */\n\nimport { type ChildProcess, spawn } from \"node:child_process\";\nimport type { AgentMessage, ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { ImageContent } from \"@earendil-works/pi-ai/compat\";\nimport type { SessionStats } from \"../../core/agent-session.ts\";\nimport type { BashResult } from \"../../core/bash-executor.ts\";\nimport type { ContextCompactionResult } from \"../../core/compaction/index.ts\";\nimport { attachJsonlLineReader, serializeJsonLine } from \"./jsonl.ts\";\nimport type {\n\tRpcCommand,\n\tRpcContextWindowInfo,\n\tRpcEvent,\n\tRpcResponse,\n\tRpcSessionState,\n\tRpcSlashCommand,\n} from \"./rpc-types.ts\";\nexport type { RpcContextWindowInfo, RpcEvent } from \"./rpc-types.ts\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Distributive Omit that works with union types */\ntype DistributiveOmit<T, K extends keyof T> = T extends unknown ? Omit<T, K> : never;\n\n/** RpcCommand without the id field (for internal send) */\ntype RpcCommandBody = DistributiveOmit<RpcCommand, \"id\">;\n\nexport interface RpcClientOptions {\n\t/** Path to the CLI entry point (default: searches for dist/cli.js) */\n\tcliPath?: string;\n\t/** Working directory for the agent */\n\tcwd?: string;\n\t/** Environment variables */\n\tenv?: Record<string, string>;\n\t/** Provider to use */\n\tprovider?: string;\n\t/** Model ID to use */\n\tmodel?: string;\n\t/** Startup context-window selection, as raw tokens or compact form like \"400k\"/\"1m\" */\n\tcontextWindow?: number | string;\n\t/** Additional CLI arguments */\n\targs?: string[];\n}\n\nexport interface ModelInfo {\n\tprovider: string;\n\tid: string;\n\tcontextWindow: number;\n\treasoning: boolean;\n}\n\nexport type RpcEventListener = (event: RpcEvent) => void;\n\n// ============================================================================\n// RPC Client\n// ============================================================================\n\nexport class RpcClient {\n\tprivate process: ChildProcess | null = null;\n\tprivate stopReadingStdout: (() => void) | null = null;\n\tprivate eventListeners: RpcEventListener[] = [];\n\tprivate pendingRequests: Map<string, { resolve: (response: RpcResponse) => void; reject: (error: Error) => void }> =\n\t\tnew Map();\n\tprivate requestId = 0;\n\tprivate stderr = \"\";\n\tprivate exitError: Error | null = null;\n\n\tdeclare private options: RpcClientOptions;\n\n\tconstructor(options: RpcClientOptions = {}) {\n\t\tthis.options = options;\n\t}\n\n\t/**\n\t * Start the RPC agent process.\n\t */\n\tasync start(): Promise<void> {\n\t\tif (this.process) {\n\t\t\tthrow new Error(\"Client already started\");\n\t\t}\n\n\t\tconst cliPath = this.options.cliPath ?? \"dist/cli.js\";\n\t\tconst args = [\"--mode\", \"rpc\"];\n\n\t\tif (this.options.provider) {\n\t\t\targs.push(\"--provider\", this.options.provider);\n\t\t}\n\t\tif (this.options.model) {\n\t\t\targs.push(\"--model\", this.options.model);\n\t\t}\n\t\tif (this.options.contextWindow !== undefined) {\n\t\t\targs.push(\"--context-window\", String(this.options.contextWindow));\n\t\t}\n\t\tif (this.options.args) {\n\t\t\targs.push(...this.options.args);\n\t\t}\n\n\t\tthis.exitError = null;\n\t\tconst childProcess = spawn(\"node\", [cliPath, ...args], {\n\t\t\tcwd: this.options.cwd,\n\t\t\tenv: { ...process.env, ...this.options.env },\n\t\t\tstdio: [\"pipe\", \"pipe\", \"pipe\"],\n\t\t});\n\t\tthis.process = childProcess;\n\n\t\tchildProcess.once(\"exit\", (code, signal) => {\n\t\t\tconst error = this.createProcessExitError(code, signal);\n\t\t\tthis.exitError = error;\n\t\t\tthis.rejectPendingRequests(error);\n\t\t});\n\t\tchildProcess.once(\"error\", (error) => {\n\t\t\tthis.exitError = error;\n\t\t\tthis.rejectPendingRequests(error);\n\t\t});\n\t\tchildProcess.stdin?.on(\"error\", (error) => {\n\t\t\tthis.exitError = error;\n\t\t\tthis.rejectPendingRequests(error);\n\t\t});\n\n\t\t// Collect stderr for debugging\n\t\tchildProcess.stderr?.on(\"data\", (data) => {\n\t\t\tthis.stderr += data.toString();\n\t\t\tprocess.stderr.write(data);\n\t\t});\n\n\t\t// Set up strict JSONL reader for stdout.\n\t\tthis.stopReadingStdout = attachJsonlLineReader(childProcess.stdout!, (line) => {\n\t\t\tthis.handleLine(line);\n\t\t});\n\n\t\t// Wait a moment for process to initialize\n\t\tawait new Promise((resolve) => setTimeout(resolve, 100));\n\n\t\tif (this.process.exitCode !== null) {\n\t\t\tthrow new Error(`Agent process exited immediately with code ${this.process.exitCode}. Stderr: ${this.stderr}`);\n\t\t}\n\t}\n\n\t/**\n\t * Stop the RPC agent process.\n\t */\n\tasync stop(): Promise<void> {\n\t\tif (!this.process) return;\n\n\t\tthis.stopReadingStdout?.();\n\t\tthis.stopReadingStdout = null;\n\t\tthis.process.kill(\"SIGTERM\");\n\n\t\t// Wait for process to exit\n\t\tawait new Promise<void>((resolve) => {\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tthis.process?.kill(\"SIGKILL\");\n\t\t\t\tresolve();\n\t\t\t}, 1000);\n\n\t\t\tthis.process?.on(\"exit\", () => {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\n\t\tthis.process = null;\n\t\tthis.pendingRequests.clear();\n\t}\n\n\t/**\n\t * Subscribe to agent events.\n\t */\n\tonEvent(listener: RpcEventListener): () => void {\n\t\tthis.eventListeners.push(listener);\n\t\treturn () => {\n\t\t\tconst index = this.eventListeners.indexOf(listener);\n\t\t\tif (index !== -1) {\n\t\t\t\tthis.eventListeners.splice(index, 1);\n\t\t\t}\n\t\t};\n\t}\n\n\t/**\n\t * Get collected stderr output (useful for debugging).\n\t */\n\tgetStderr(): string {\n\t\treturn this.stderr;\n\t}\n\n\t// =========================================================================\n\t// Command Methods\n\t// =========================================================================\n\n\t/**\n\t * Send a prompt to the agent.\n\t * Returns immediately after sending; use onEvent() to receive streaming events.\n\t * Use waitForIdle() to wait for completion.\n\t */\n\tasync prompt(message: string, images?: ImageContent[]): Promise<void> {\n\t\tawait this.send({ type: \"prompt\", message, images });\n\t}\n\n\t/**\n\t * Queue a steering message to interrupt the agent mid-run.\n\t */\n\tasync steer(message: string, images?: ImageContent[]): Promise<void> {\n\t\tawait this.send({ type: \"steer\", message, images });\n\t}\n\n\t/**\n\t * Queue a follow-up message to be processed after the agent finishes.\n\t */\n\tasync followUp(message: string, images?: ImageContent[]): Promise<void> {\n\t\tawait this.send({ type: \"follow_up\", message, images });\n\t}\n\n\t/**\n\t * Abort current operation.\n\t */\n\tasync abort(): Promise<void> {\n\t\tawait this.send({ type: \"abort\" });\n\t}\n\n\t/**\n\t * Start a new session, optionally with parent tracking.\n\t * @param parentSession - Optional parent session path for lineage tracking\n\t * @returns Object with `cancelled: true` if an extension cancelled the new session\n\t */\n\tasync newSession(parentSession?: string): Promise<{ cancelled: boolean }> {\n\t\tconst response = await this.send({ type: \"new_session\", parentSession });\n\t\treturn this.getData(response);\n\t}\n\n\t/**\n\t * Get current session state.\n\t */\n\tasync getState(): Promise<RpcSessionState> {\n\t\tconst response = await this.send({ type: \"get_state\" });\n\t\treturn this.getData(response);\n\t}\n\n\t/**\n\t * Set model by provider and ID.\n\t */\n\tasync setModel(provider: string, modelId: string): Promise<{ provider: string; id: string }> {\n\t\tconst response = await this.send({ type: \"set_model\", provider, modelId });\n\t\treturn this.getData(response);\n\t}\n\n\t/**\n\t * Cycle to next model.\n\t */\n\tasync cycleModel(): Promise<{\n\t\tmodel: { provider: string; id: string };\n\t\tthinkingLevel: ThinkingLevel;\n\t\tisScoped: boolean;\n\t} | null> {\n\t\tconst response = await this.send({ type: \"cycle_model\" });\n\t\treturn this.getData(response);\n\t}\n\n\t/**\n\t * Get list of available models.\n\t */\n\tasync getAvailableModels(): Promise<ModelInfo[]> {\n\t\tconst response = await this.send({ type: \"get_available_models\" });\n\t\treturn this.getData<{ models: ModelInfo[] }>(response).models;\n\t}\n\n\t/**\n\t * Set thinking level.\n\t */\n\tasync setThinkingLevel(level: ThinkingLevel): Promise<void> {\n\t\tawait this.send({ type: \"set_thinking_level\", level });\n\t}\n\n\t/**\n\t * Cycle thinking level.\n\t */\n\tasync cycleThinkingLevel(): Promise<{ level: ThinkingLevel } | null> {\n\t\tconst response = await this.send({ type: \"cycle_thinking_level\" });\n\t\treturn this.getData(response);\n\t}\n\n\t/**\n\t * Set the active context-window token budget for the current model.\n\t * This is a runtime selection and does not persist context-window defaults.\n\t */\n\tasync setContextWindow(contextWindow: number | string): Promise<void> {\n\t\tconst response = await this.send({ type: \"set_context_window\", contextWindow });\n\t\tthis.assertSuccess(response);\n\t}\n\n\t/**\n\t * Get selectable context-window token budgets for the current model.\n\t */\n\tasync getAvailableContextWindows(): Promise<RpcContextWindowInfo> {\n\t\tconst response = await this.send({ type: \"get_available_context_windows\" });\n\t\treturn this.getData(response);\n\t}\n\n\t/**\n\t * Set steering mode.\n\t */\n\tasync setSteeringMode(mode: \"all\" | \"one-at-a-time\"): Promise<void> {\n\t\tawait this.send({ type: \"set_steering_mode\", mode });\n\t}\n\n\t/**\n\t * Set follow-up mode.\n\t */\n\tasync setFollowUpMode(mode: \"all\" | \"one-at-a-time\"): Promise<void> {\n\t\tawait this.send({ type: \"set_follow_up_mode\", mode });\n\t}\n\n\t/**\n\t * Compact session context with deletion-only verbatim context compaction.\n\t */\n\tasync compact(): Promise<ContextCompactionResult> {\n\t\tconst response = await this.send({ type: \"compact\" });\n\t\treturn this.getData(response);\n\t}\n\n\t/** @deprecated Use compact() instead. */\n\tasync contextCompact(): Promise<ContextCompactionResult> {\n\t\tconst response = await this.send({ type: \"context_compact\" });\n\t\treturn this.getData(response);\n\t}\n\tasync setAutoCompaction(enabled: boolean): Promise<void> {\n\t\tawait this.send({ type: \"set_auto_compaction\", enabled });\n\t}\n\tasync setAutoRetry(enabled: boolean): Promise<void> {\n\t\tawait this.send({ type: \"set_auto_retry\", enabled });\n\t}\n\tasync abortRetry(): Promise<void> {\n\t\tawait this.send({ type: \"abort_retry\" });\n\t}\n\tasync bash(command: string): Promise<BashResult> {\n\t\tconst response = await this.send({ type: \"bash\", command });\n\t\treturn this.getData(response);\n\t}\n\tasync abortBash(): Promise<void> {\n\t\tawait this.send({ type: \"abort_bash\" });\n\t}\n\tasync getSessionStats(): Promise<SessionStats> {\n\t\tconst response = await this.send({ type: \"get_session_stats\" });\n\t\treturn this.getData(response);\n\t}\n\tasync exportHtml(outputPath?: string): Promise<{ path: string }> {\n\t\tconst response = await this.send({ type: \"export_html\", outputPath });\n\t\treturn this.getData(response);\n\t}\n\tasync switchSession(sessionPath: string): Promise<{ cancelled: boolean }> {\n\t\tconst response = await this.send({ type: \"switch_session\", sessionPath });\n\t\treturn this.getData(response);\n\t}\n\tasync fork(entryId: string): Promise<{ text: string; cancelled: boolean }> {\n\t\tconst response = await this.send({ type: \"fork\", entryId });\n\t\treturn this.getData(response);\n\t}\n\tasync clone(): Promise<{ cancelled: boolean }> {\n\t\tconst response = await this.send({ type: \"clone\" });\n\t\treturn this.getData(response);\n\t}\n\tasync getForkMessages(): Promise<Array<{ entryId: string; text: string }>> {\n\t\tconst response = await this.send({ type: \"get_fork_messages\" });\n\t\treturn this.getData<{ messages: Array<{ entryId: string; text: string }> }>(response).messages;\n\t}\n\tasync getLastAssistantText(): Promise<string | null> {\n\t\tconst response = await this.send({ type: \"get_last_assistant_text\" });\n\t\treturn this.getData<{ text: string | null }>(response).text;\n\t}\n\tasync setSessionName(name: string): Promise<void> {\n\t\tawait this.send({ type: \"set_session_name\", name });\n\t}\n\tasync getMessages(): Promise<AgentMessage[]> {\n\t\tconst response = await this.send({ type: \"get_messages\" });\n\t\treturn this.getData<{ messages: AgentMessage[] }>(response).messages;\n\t}\n\tasync getCommands(): Promise<RpcSlashCommand[]> {\n\t\tconst response = await this.send({ type: \"get_commands\" });\n\t\treturn this.getData<{ commands: RpcSlashCommand[] }>(response).commands;\n\t}\n\twaitForIdle(timeout = 60000): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tunsubscribe();\n\t\t\t\treject(new Error(`Timeout waiting for agent to become idle. Stderr: ${this.stderr}`));\n\t\t\t}, timeout);\n\t\t\tconst unsubscribe = this.onEvent((event) => {\n\t\t\t\tif (event.type === \"agent_end\") {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\tunsubscribe();\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\tcollectEvents(timeout = 60000): Promise<RpcEvent[]> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst events: RpcEvent[] = [];\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tunsubscribe();\n\t\t\t\treject(new Error(`Timeout collecting events. Stderr: ${this.stderr}`));\n\t\t\t}, timeout);\n\t\t\tconst unsubscribe = this.onEvent((event) => {\n\t\t\t\tevents.push(event);\n\t\t\t\tif (event.type === \"agent_end\") {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\tunsubscribe();\n\t\t\t\t\tresolve(events);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\tasync promptAndWait(message: string, images?: ImageContent[], timeout = 60000): Promise<RpcEvent[]> {\n\t\tconst eventsPromise = this.collectEvents(timeout);\n\t\tawait this.prompt(message, images);\n\t\treturn eventsPromise;\n\t}\n\tprivate handleLine(line: string): void {\n\t\ttry {\n\t\t\tconst data = JSON.parse(line);\n\t\t\tif (data.type === \"response\" && data.id && this.pendingRequests.has(data.id)) {\n\t\t\t\tconst pending = this.pendingRequests.get(data.id)!;\n\t\t\t\tthis.pendingRequests.delete(data.id);\n\t\t\t\tpending.resolve(data as RpcResponse);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (const listener of this.eventListeners) {\n\t\t\t\tlistener(data as RpcEvent);\n\t\t\t}\n\t\t} catch {\n\t\t}\n\t}\n\tprivate createProcessExitError(code: number | null, signal: NodeJS.Signals | null): Error {\n\t\treturn new Error(`Agent process exited (code=${code} signal=${signal}). Stderr: ${this.stderr}`);\n\t}\n\tprivate rejectPendingRequests(error: Error): void {\n\t\tfor (const { reject } of this.pendingRequests.values()) {\n\t\t\treject(error);\n\t\t}\n\t\tthis.pendingRequests.clear();\n\t}\n\tprivate async send(command: RpcCommandBody): Promise<RpcResponse> {\n\t\tconst childProcess = this.process;\n\t\tconst stdin = childProcess?.stdin;\n\t\tif (!childProcess || !stdin) {\n\t\t\tthrow new Error(\"Client not started\");\n\t\t}\n\t\tif (this.exitError) {\n\t\t\tthrow this.exitError;\n\t\t}\n\t\tif (childProcess.exitCode !== null) {\n\t\t\tconst error = this.createProcessExitError(childProcess.exitCode, childProcess.signalCode);\n\t\t\tthis.exitError = error;\n\t\t\tthrow error;\n\t\t}\n\t\tif (stdin.destroyed || !stdin.writable) {\n\t\t\tthrow new Error(\"Agent process stdin is not writable\");\n\t\t}\n\t\tconst id = `req_${++this.requestId}`;\n\t\tconst fullCommand = { ...command, id } as RpcCommand;\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tthis.pendingRequests.delete(id);\n\t\t\t\treject(new Error(`Timeout waiting for response to ${command.type}. Stderr: ${this.stderr}`));\n\t\t\t}, 30000);\n\t\t\tthis.pendingRequests.set(id, {\n\t\t\t\tresolve: (response) => {\n\t\t\t\t\tclearTimeout(timeout);\n\t\t\t\t\tresolve(response);\n\t\t\t\t},\n\t\t\t\treject: (error) => {\n\t\t\t\t\tclearTimeout(timeout);\n\t\t\t\t\treject(error);\n\t\t\t\t},\n\t\t\t});\n\t\t\ttry {\n\t\t\t\tstdin.write(serializeJsonLine(fullCommand));\n\t\t\t} catch (error) {\n\t\t\t\tthis.pendingRequests.delete(id);\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\treject(error instanceof Error ? error : new Error(String(error)));\n\t\t\t}\n\t\t});\n\t}\n\tprivate assertSuccess(response: RpcResponse): void {\n\t\tif (!response.success) {\n\t\t\tthrow new Error(response.error);\n\t\t}\n\t}\n\tprivate getData<T>(response: RpcResponse): T {\n\t\tthis.assertSuccess(response);\n\t\tconst successResponse = response as Extract<RpcResponse, { success: true; data: unknown }>;\n\t\treturn successResponse.data as T;\n\t}\n}\n"]}
1
+ {"version":3,"file":"rpc-client.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-client.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * RPC Client for programmatic access to the coding agent.\n *\n * Spawns the agent in RPC mode and provides a typed API for all operations.\n */\n\nimport { type ChildProcess, spawn } from \"node:child_process\";\nimport type { AgentMessage, ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { ImageContent } from \"@earendil-works/pi-ai/compat\";\nimport type { SessionStats } from \"../../core/agent-session.ts\";\nimport type { BashResult } from \"../../core/bash-executor.ts\";\nimport type { ContextCompactionResult } from \"../../core/compaction/index.ts\";\nimport type { SessionEntry, SessionTreeNode } from \"../../core/session-manager.ts\";\nimport { attachJsonlLineReader, serializeJsonLine } from \"./jsonl.ts\";\nimport type {\n\tRpcCommand,\n\tRpcContextWindowInfo,\n\tRpcEvent,\n\tRpcResponse,\n\tRpcSessionState,\n\tRpcSlashCommand,\n} from \"./rpc-types.ts\";\nexport type { RpcContextWindowInfo, RpcEvent } from \"./rpc-types.ts\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Distributive Omit that works with union types */\ntype DistributiveOmit<T, K extends keyof T> = T extends unknown ? Omit<T, K> : never;\n\n/** RpcCommand without the id field (for internal send) */\ntype RpcCommandBody = DistributiveOmit<RpcCommand, \"id\">;\n\nexport interface RpcClientOptions {\n\t/** Path to the CLI entry point (default: searches for dist/cli.js) */\n\tcliPath?: string;\n\t/** Working directory for the agent */\n\tcwd?: string;\n\t/** Environment variables */\n\tenv?: Record<string, string>;\n\t/** Provider to use */\n\tprovider?: string;\n\t/** Model ID to use */\n\tmodel?: string;\n\t/** Startup context-window selection, as raw tokens or compact form like \"400k\"/\"1m\" */\n\tcontextWindow?: number | string;\n\t/** Additional CLI arguments */\n\targs?: string[];\n}\n\nexport interface ModelInfo {\n\tprovider: string;\n\tid: string;\n\tcontextWindow: number;\n\treasoning: boolean;\n}\n\nexport type RpcEventListener = (event: RpcEvent) => void;\n\n// ============================================================================\n// RPC Client\n// ============================================================================\n\nexport class RpcClient {\n\tprivate process: ChildProcess | null = null;\n\tprivate stopReadingStdout: (() => void) | null = null;\n\tprivate eventListeners: RpcEventListener[] = [];\n\tprivate pendingRequests: Map<string, { resolve: (response: RpcResponse) => void; reject: (error: Error) => void }> =\n\t\tnew Map();\n\tprivate requestId = 0;\n\tprivate stderr = \"\";\n\tprivate exitError: Error | null = null;\n\n\tdeclare private options: RpcClientOptions;\n\n\tconstructor(options: RpcClientOptions = {}) {\n\t\tthis.options = options;\n\t}\n\n\t/** Start the RPC agent process. */\n\tasync start(): Promise<void> {\n\t\tif (this.process) {\n\t\t\tthrow new Error(\"Client already started\");\n\t\t}\n\n\t\tconst cliPath = this.options.cliPath ?? \"dist/cli.js\";\n\t\tconst args = [\"--mode\", \"rpc\"];\n\n\t\tif (this.options.provider) {\n\t\t\targs.push(\"--provider\", this.options.provider);\n\t\t}\n\t\tif (this.options.model) {\n\t\t\targs.push(\"--model\", this.options.model);\n\t\t}\n\t\tif (this.options.contextWindow !== undefined) {\n\t\t\targs.push(\"--context-window\", String(this.options.contextWindow));\n\t\t}\n\t\tif (this.options.args) {\n\t\t\targs.push(...this.options.args);\n\t\t}\n\n\t\tthis.exitError = null;\n\t\tconst childProcess = spawn(\"node\", [cliPath, ...args], {\n\t\t\tcwd: this.options.cwd,\n\t\t\tenv: { ...process.env, ...this.options.env },\n\t\t\tstdio: [\"pipe\", \"pipe\", \"pipe\"],\n\t\t});\n\t\tthis.process = childProcess;\n\n\t\tchildProcess.once(\"exit\", (code, signal) => {\n\t\t\tconst error = this.createProcessExitError(code, signal);\n\t\t\tthis.exitError = error;\n\t\t\tthis.rejectPendingRequests(error);\n\t\t});\n\t\tchildProcess.once(\"error\", (error) => {\n\t\t\tthis.exitError = error;\n\t\t\tthis.rejectPendingRequests(error);\n\t\t});\n\t\tchildProcess.stdin?.on(\"error\", (error) => {\n\t\t\tthis.exitError = error;\n\t\t\tthis.rejectPendingRequests(error);\n\t\t});\n\n\t\t// Collect stderr for debugging\n\t\tchildProcess.stderr?.on(\"data\", (data) => {\n\t\t\tthis.stderr += data.toString();\n\t\t\tprocess.stderr.write(data);\n\t\t});\n\n\t\t// Set up strict JSONL reader for stdout.\n\t\tthis.stopReadingStdout = attachJsonlLineReader(childProcess.stdout!, (line) => {\n\t\t\tthis.handleLine(line);\n\t\t});\n\n\t\t// Wait a moment for process to initialize\n\t\tawait new Promise((resolve) => setTimeout(resolve, 100));\n\n\t\tif (this.process.exitCode !== null) {\n\t\t\tthrow new Error(`Agent process exited immediately with code ${this.process.exitCode}. Stderr: ${this.stderr}`);\n\t\t}\n\t}\n\n\t/** Stop the RPC agent process. */\n\tasync stop(): Promise<void> {\n\t\tif (!this.process) return;\n\n\t\tthis.stopReadingStdout?.();\n\t\tthis.stopReadingStdout = null;\n\t\tthis.process.kill(\"SIGTERM\");\n\n\t\t// Wait for process to exit\n\t\tawait new Promise<void>((resolve) => {\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tthis.process?.kill(\"SIGKILL\");\n\t\t\t\tresolve();\n\t\t\t}, 1000);\n\n\t\t\tthis.process?.on(\"exit\", () => {\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\n\t\tthis.process = null;\n\t\tthis.pendingRequests.clear();\n\t}\n\n\t/** Subscribe to agent events. */\n\tonEvent(listener: RpcEventListener): () => void {\n\t\tthis.eventListeners.push(listener);\n\t\treturn () => {\n\t\t\tconst index = this.eventListeners.indexOf(listener);\n\t\t\tif (index !== -1) {\n\t\t\t\tthis.eventListeners.splice(index, 1);\n\t\t\t}\n\t\t};\n\t}\n\n\t/** Get collected stderr output (useful for debugging). */\n\tgetStderr(): string {\n\t\treturn this.stderr;\n\t}\n\n\t// =========================================================================\n\t// Command Methods\n\t// =========================================================================\n\n\t/**\n\t * Send a prompt to the agent.\n\t * Returns immediately after sending; use onEvent() to receive streaming events.\n\t * Use waitForIdle() to wait for completion.\n\t */\n\tasync prompt(message: string, images?: ImageContent[]): Promise<void> {\n\t\tawait this.send({ type: \"prompt\", message, images });\n\t}\n\n\t/** Queue a steering message to interrupt the agent mid-run. */\n\tasync steer(message: string, images?: ImageContent[]): Promise<void> {\n\t\tawait this.send({ type: \"steer\", message, images });\n\t}\n\n\t/** Queue a follow-up message to be processed after the agent finishes. */\n\tasync followUp(message: string, images?: ImageContent[]): Promise<void> {\n\t\tawait this.send({ type: \"follow_up\", message, images });\n\t}\n\n\t/** Abort current operation. */\n\tasync abort(): Promise<void> {\n\t\tawait this.send({ type: \"abort\" });\n\t}\n\n\t/**\n\t * Start a new session, optionally with parent tracking.\n\t * @param parentSession - Optional parent session path for lineage tracking\n\t * @returns Object with `cancelled: true` if an extension cancelled the new session\n\t */\n\tasync newSession(parentSession?: string): Promise<{ cancelled: boolean }> {\n\t\tconst response = await this.send({ type: \"new_session\", parentSession });\n\t\treturn this.getData(response);\n\t}\n\n\t/** Get current session state. */\n\tasync getState(): Promise<RpcSessionState> {\n\t\tconst response = await this.send({ type: \"get_state\" });\n\t\treturn this.getData(response);\n\t}\n\n\t/** Set model by provider and ID. */\n\tasync setModel(provider: string, modelId: string): Promise<{ provider: string; id: string }> {\n\t\tconst response = await this.send({ type: \"set_model\", provider, modelId });\n\t\treturn this.getData(response);\n\t}\n\n\t/** Cycle to next model. */\n\tasync cycleModel(): Promise<{\n\t\tmodel: { provider: string; id: string };\n\t\tthinkingLevel: ThinkingLevel;\n\t\tisScoped: boolean;\n\t} | null> {\n\t\tconst response = await this.send({ type: \"cycle_model\" });\n\t\treturn this.getData(response);\n\t}\n\n\t/** Get list of available models. */\n\tasync getAvailableModels(): Promise<ModelInfo[]> {\n\t\tconst response = await this.send({ type: \"get_available_models\" });\n\t\treturn this.getData<{ models: ModelInfo[] }>(response).models;\n\t}\n\n\t/** Set thinking level. */\n\tasync setThinkingLevel(level: ThinkingLevel): Promise<void> {\n\t\tawait this.send({ type: \"set_thinking_level\", level });\n\t}\n\n\t/** Cycle thinking level. */\n\tasync cycleThinkingLevel(): Promise<{ level: ThinkingLevel } | null> {\n\t\tconst response = await this.send({ type: \"cycle_thinking_level\" });\n\t\treturn this.getData(response);\n\t}\n\n\t/**\n\t * Set the active context-window token budget for the current model.\n\t * This is a runtime selection and does not persist context-window defaults.\n\t */\n\tasync setContextWindow(contextWindow: number | string): Promise<void> {\n\t\tconst response = await this.send({ type: \"set_context_window\", contextWindow });\n\t\tthis.assertSuccess(response);\n\t}\n\n\t/** Get selectable context-window token budgets for the current model. */\n\tasync getAvailableContextWindows(): Promise<RpcContextWindowInfo> {\n\t\tconst response = await this.send({ type: \"get_available_context_windows\" });\n\t\treturn this.getData(response);\n\t}\n\n\t/** Set steering mode. */\n\tasync setSteeringMode(mode: \"all\" | \"one-at-a-time\"): Promise<void> {\n\t\tawait this.send({ type: \"set_steering_mode\", mode });\n\t}\n\n\t/** Set follow-up mode. */\n\tasync setFollowUpMode(mode: \"all\" | \"one-at-a-time\"): Promise<void> {\n\t\tawait this.send({ type: \"set_follow_up_mode\", mode });\n\t}\n\n\t/** Compact session context with deletion-only verbatim context compaction. */\n\tasync compact(): Promise<ContextCompactionResult> {\n\t\tconst response = await this.send({ type: \"compact\" });\n\t\treturn this.getData(response);\n\t}\n\n\t/** @deprecated Use compact() instead. */\n\tasync contextCompact(): Promise<ContextCompactionResult> {\n\t\tconst response = await this.send({ type: \"context_compact\" });\n\t\treturn this.getData(response);\n\t}\n\tasync setAutoCompaction(enabled: boolean): Promise<void> {\n\t\tawait this.send({ type: \"set_auto_compaction\", enabled });\n\t}\n\tasync setAutoRetry(enabled: boolean): Promise<void> {\n\t\tawait this.send({ type: \"set_auto_retry\", enabled });\n\t}\n\tasync abortRetry(): Promise<void> {\n\t\tawait this.send({ type: \"abort_retry\" });\n\t}\n\tasync bash(command: string): Promise<BashResult> {\n\t\tconst response = await this.send({ type: \"bash\", command });\n\t\treturn this.getData(response);\n\t}\n\tasync abortBash(): Promise<void> {\n\t\tawait this.send({ type: \"abort_bash\" });\n\t}\n\tasync getSessionStats(): Promise<SessionStats> {\n\t\tconst response = await this.send({ type: \"get_session_stats\" });\n\t\treturn this.getData(response);\n\t}\n\tasync exportHtml(outputPath?: string): Promise<{ path: string }> {\n\t\tconst response = await this.send({ type: \"export_html\", outputPath });\n\t\treturn this.getData(response);\n\t}\n\tasync switchSession(sessionPath: string): Promise<{ cancelled: boolean }> {\n\t\tconst response = await this.send({ type: \"switch_session\", sessionPath });\n\t\treturn this.getData(response);\n\t}\n\tasync fork(entryId: string): Promise<{ text: string; cancelled: boolean }> {\n\t\tconst response = await this.send({ type: \"fork\", entryId });\n\t\treturn this.getData(response);\n\t}\n\tasync clone(): Promise<{ cancelled: boolean }> {\n\t\tconst response = await this.send({ type: \"clone\" });\n\t\treturn this.getData(response);\n\t}\n\tasync getForkMessages(): Promise<Array<{ entryId: string; text: string }>> {\n\t\tconst response = await this.send({ type: \"get_fork_messages\" });\n\t\treturn this.getData<{ messages: Array<{ entryId: string; text: string }> }>(response).messages;\n\t}\n\n\t/** Session entries in append order, optionally only those after the `since` entry id. */\n\tasync getEntries(since?: string): Promise<{ entries: SessionEntry[]; leafId: string | null }> {\n\t\tconst response = await this.send({ type: \"get_entries\", since });\n\t\treturn this.getData<{ entries: SessionEntry[]; leafId: string | null }>(response);\n\t}\n\n\t/** The session entry tree. */\n\tasync getTree(): Promise<{ tree: SessionTreeNode[]; leafId: string | null }> {\n\t\tconst response = await this.send({ type: \"get_tree\" });\n\t\treturn this.getData<{ tree: SessionTreeNode[]; leafId: string | null }>(response);\n\t}\n\tasync getLastAssistantText(): Promise<string | null> {\n\t\tconst response = await this.send({ type: \"get_last_assistant_text\" });\n\t\treturn this.getData<{ text: string | null }>(response).text;\n\t}\n\tasync setSessionName(name: string): Promise<void> {\n\t\tawait this.send({ type: \"set_session_name\", name });\n\t}\n\tasync getMessages(): Promise<AgentMessage[]> {\n\t\tconst response = await this.send({ type: \"get_messages\" });\n\t\treturn this.getData<{ messages: AgentMessage[] }>(response).messages;\n\t}\n\tasync getCommands(): Promise<RpcSlashCommand[]> {\n\t\tconst response = await this.send({ type: \"get_commands\" });\n\t\treturn this.getData<{ commands: RpcSlashCommand[] }>(response).commands;\n\t}\n\twaitForIdle(timeout = 60000): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tunsubscribe();\n\t\t\t\treject(new Error(`Timeout waiting for agent to become idle. Stderr: ${this.stderr}`));\n\t\t\t}, timeout);\n\t\t\tconst unsubscribe = this.onEvent((event) => {\n\t\t\t\tif (event.type === \"agent_end\") {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\tunsubscribe();\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\tcollectEvents(timeout = 60000): Promise<RpcEvent[]> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst events: RpcEvent[] = [];\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tunsubscribe();\n\t\t\t\treject(new Error(`Timeout collecting events. Stderr: ${this.stderr}`));\n\t\t\t}, timeout);\n\t\t\tconst unsubscribe = this.onEvent((event) => {\n\t\t\t\tevents.push(event);\n\t\t\t\tif (event.type === \"agent_end\") {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\tunsubscribe();\n\t\t\t\t\tresolve(events);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\tasync promptAndWait(message: string, images?: ImageContent[], timeout = 60000): Promise<RpcEvent[]> {\n\t\tconst eventsPromise = this.collectEvents(timeout);\n\t\tawait this.prompt(message, images);\n\t\treturn eventsPromise;\n\t}\n\tprivate handleLine(line: string): void {\n\t\ttry {\n\t\t\tconst data = JSON.parse(line);\n\t\t\tif (data.type === \"response\" && data.id && this.pendingRequests.has(data.id)) {\n\t\t\t\tconst pending = this.pendingRequests.get(data.id)!;\n\t\t\t\tthis.pendingRequests.delete(data.id);\n\t\t\t\tpending.resolve(data as RpcResponse);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (const listener of this.eventListeners) {\n\t\t\t\tlistener(data as RpcEvent);\n\t\t\t}\n\t\t} catch {\n\t\t}\n\t}\n\tprivate createProcessExitError(code: number | null, signal: NodeJS.Signals | null): Error {\n\t\treturn new Error(`Agent process exited (code=${code} signal=${signal}). Stderr: ${this.stderr}`);\n\t}\n\tprivate rejectPendingRequests(error: Error): void {\n\t\tfor (const { reject } of this.pendingRequests.values()) {\n\t\t\treject(error);\n\t\t}\n\t\tthis.pendingRequests.clear();\n\t}\n\tprivate async send(command: RpcCommandBody): Promise<RpcResponse> {\n\t\tconst childProcess = this.process;\n\t\tconst stdin = childProcess?.stdin;\n\t\tif (!childProcess || !stdin) {\n\t\t\tthrow new Error(\"Client not started\");\n\t\t}\n\t\tif (this.exitError) {\n\t\t\tthrow this.exitError;\n\t\t}\n\t\tif (childProcess.exitCode !== null) {\n\t\t\tconst error = this.createProcessExitError(childProcess.exitCode, childProcess.signalCode);\n\t\t\tthis.exitError = error;\n\t\t\tthrow error;\n\t\t}\n\t\tif (stdin.destroyed || !stdin.writable) {\n\t\t\tthrow new Error(\"Agent process stdin is not writable\");\n\t\t}\n\t\tconst id = `req_${++this.requestId}`;\n\t\tconst fullCommand = { ...command, id } as RpcCommand;\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tthis.pendingRequests.delete(id);\n\t\t\t\treject(new Error(`Timeout waiting for response to ${command.type}. Stderr: ${this.stderr}`));\n\t\t\t}, 30000);\n\t\t\tthis.pendingRequests.set(id, {\n\t\t\t\tresolve: (response) => {\n\t\t\t\t\tclearTimeout(timeout);\n\t\t\t\t\tresolve(response);\n\t\t\t\t},\n\t\t\t\treject: (error) => {\n\t\t\t\t\tclearTimeout(timeout);\n\t\t\t\t\treject(error);\n\t\t\t\t},\n\t\t\t});\n\t\t\ttry {\n\t\t\t\tstdin.write(serializeJsonLine(fullCommand));\n\t\t\t} catch (error) {\n\t\t\t\tthis.pendingRequests.delete(id);\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\treject(error instanceof Error ? error : new Error(String(error)));\n\t\t\t}\n\t\t});\n\t}\n\tprivate assertSuccess(response: RpcResponse): void {\n\t\tif (!response.success) {\n\t\t\tthrow new Error(response.error);\n\t\t}\n\t}\n\tprivate getData<T>(response: RpcResponse): T {\n\t\tthis.assertSuccess(response);\n\t\tconst successResponse = response as Extract<RpcResponse, { success: true; data: unknown }>;\n\t\treturn successResponse.data as T;\n\t}\n}\n"]}
@@ -19,9 +19,7 @@ export class RpcClient {
19
19
  this.exitError = null;
20
20
  this.options = options;
21
21
  }
22
- /**
23
- * Start the RPC agent process.
24
- */
22
+ /** Start the RPC agent process. */
25
23
  async start() {
26
24
  if (this.process) {
27
25
  throw new Error("Client already started");
@@ -75,9 +73,7 @@ export class RpcClient {
75
73
  throw new Error(`Agent process exited immediately with code ${this.process.exitCode}. Stderr: ${this.stderr}`);
76
74
  }
77
75
  }
78
- /**
79
- * Stop the RPC agent process.
80
- */
76
+ /** Stop the RPC agent process. */
81
77
  async stop() {
82
78
  if (!this.process)
83
79
  return;
@@ -98,9 +94,7 @@ export class RpcClient {
98
94
  this.process = null;
99
95
  this.pendingRequests.clear();
100
96
  }
101
- /**
102
- * Subscribe to agent events.
103
- */
97
+ /** Subscribe to agent events. */
104
98
  onEvent(listener) {
105
99
  this.eventListeners.push(listener);
106
100
  return () => {
@@ -110,9 +104,7 @@ export class RpcClient {
110
104
  }
111
105
  };
112
106
  }
113
- /**
114
- * Get collected stderr output (useful for debugging).
115
- */
107
+ /** Get collected stderr output (useful for debugging). */
116
108
  getStderr() {
117
109
  return this.stderr;
118
110
  }
@@ -127,21 +119,15 @@ export class RpcClient {
127
119
  async prompt(message, images) {
128
120
  await this.send({ type: "prompt", message, images });
129
121
  }
130
- /**
131
- * Queue a steering message to interrupt the agent mid-run.
132
- */
122
+ /** Queue a steering message to interrupt the agent mid-run. */
133
123
  async steer(message, images) {
134
124
  await this.send({ type: "steer", message, images });
135
125
  }
136
- /**
137
- * Queue a follow-up message to be processed after the agent finishes.
138
- */
126
+ /** Queue a follow-up message to be processed after the agent finishes. */
139
127
  async followUp(message, images) {
140
128
  await this.send({ type: "follow_up", message, images });
141
129
  }
142
- /**
143
- * Abort current operation.
144
- */
130
+ /** Abort current operation. */
145
131
  async abort() {
146
132
  await this.send({ type: "abort" });
147
133
  }
@@ -154,43 +140,31 @@ export class RpcClient {
154
140
  const response = await this.send({ type: "new_session", parentSession });
155
141
  return this.getData(response);
156
142
  }
157
- /**
158
- * Get current session state.
159
- */
143
+ /** Get current session state. */
160
144
  async getState() {
161
145
  const response = await this.send({ type: "get_state" });
162
146
  return this.getData(response);
163
147
  }
164
- /**
165
- * Set model by provider and ID.
166
- */
148
+ /** Set model by provider and ID. */
167
149
  async setModel(provider, modelId) {
168
150
  const response = await this.send({ type: "set_model", provider, modelId });
169
151
  return this.getData(response);
170
152
  }
171
- /**
172
- * Cycle to next model.
173
- */
153
+ /** Cycle to next model. */
174
154
  async cycleModel() {
175
155
  const response = await this.send({ type: "cycle_model" });
176
156
  return this.getData(response);
177
157
  }
178
- /**
179
- * Get list of available models.
180
- */
158
+ /** Get list of available models. */
181
159
  async getAvailableModels() {
182
160
  const response = await this.send({ type: "get_available_models" });
183
161
  return this.getData(response).models;
184
162
  }
185
- /**
186
- * Set thinking level.
187
- */
163
+ /** Set thinking level. */
188
164
  async setThinkingLevel(level) {
189
165
  await this.send({ type: "set_thinking_level", level });
190
166
  }
191
- /**
192
- * Cycle thinking level.
193
- */
167
+ /** Cycle thinking level. */
194
168
  async cycleThinkingLevel() {
195
169
  const response = await this.send({ type: "cycle_thinking_level" });
196
170
  return this.getData(response);
@@ -203,28 +177,20 @@ export class RpcClient {
203
177
  const response = await this.send({ type: "set_context_window", contextWindow });
204
178
  this.assertSuccess(response);
205
179
  }
206
- /**
207
- * Get selectable context-window token budgets for the current model.
208
- */
180
+ /** Get selectable context-window token budgets for the current model. */
209
181
  async getAvailableContextWindows() {
210
182
  const response = await this.send({ type: "get_available_context_windows" });
211
183
  return this.getData(response);
212
184
  }
213
- /**
214
- * Set steering mode.
215
- */
185
+ /** Set steering mode. */
216
186
  async setSteeringMode(mode) {
217
187
  await this.send({ type: "set_steering_mode", mode });
218
188
  }
219
- /**
220
- * Set follow-up mode.
221
- */
189
+ /** Set follow-up mode. */
222
190
  async setFollowUpMode(mode) {
223
191
  await this.send({ type: "set_follow_up_mode", mode });
224
192
  }
225
- /**
226
- * Compact session context with deletion-only verbatim context compaction.
227
- */
193
+ /** Compact session context with deletion-only verbatim context compaction. */
228
194
  async compact() {
229
195
  const response = await this.send({ type: "compact" });
230
196
  return this.getData(response);
@@ -274,6 +240,16 @@ export class RpcClient {
274
240
  const response = await this.send({ type: "get_fork_messages" });
275
241
  return this.getData(response).messages;
276
242
  }
243
+ /** Session entries in append order, optionally only those after the `since` entry id. */
244
+ async getEntries(since) {
245
+ const response = await this.send({ type: "get_entries", since });
246
+ return this.getData(response);
247
+ }
248
+ /** The session entry tree. */
249
+ async getTree() {
250
+ const response = await this.send({ type: "get_tree" });
251
+ return this.getData(response);
252
+ }
277
253
  async getLastAssistantText() {
278
254
  const response = await this.send({ type: "get_last_assistant_text" });
279
255
  return this.getData(response).text;