@calliopelabs/cli 2.2.0 → 2.5.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 (244) hide show
  1. package/README.md +17 -0
  2. package/dist/agents/agent-config-loader.js +1 -1
  3. package/dist/agents/agent-config-presets.js +13 -13
  4. package/dist/agents/agent-config-presets.js.map +1 -1
  5. package/dist/agents/agent-config-types.d.ts +1 -1
  6. package/dist/agents/agent-config-types.d.ts.map +1 -1
  7. package/dist/agents/council-types.d.ts +2 -0
  8. package/dist/agents/council-types.d.ts.map +1 -1
  9. package/dist/agents/council-types.js.map +1 -1
  10. package/dist/agents/council.d.ts +5 -0
  11. package/dist/agents/council.d.ts.map +1 -1
  12. package/dist/agents/council.js +150 -14
  13. package/dist/agents/council.js.map +1 -1
  14. package/dist/agents/dynamic-tools.d.ts.map +1 -1
  15. package/dist/agents/dynamic-tools.js +39 -10
  16. package/dist/agents/dynamic-tools.js.map +1 -1
  17. package/dist/agents/orchestrator.d.ts +7 -0
  18. package/dist/agents/orchestrator.d.ts.map +1 -1
  19. package/dist/agents/orchestrator.js +48 -7
  20. package/dist/agents/orchestrator.js.map +1 -1
  21. package/dist/agents/sdk-backend.js +1 -1
  22. package/dist/agents/sdk-backend.js.map +1 -1
  23. package/dist/agents/swarm-types.d.ts +1 -0
  24. package/dist/agents/swarm-types.d.ts.map +1 -1
  25. package/dist/agents/swarm.d.ts +5 -0
  26. package/dist/agents/swarm.d.ts.map +1 -1
  27. package/dist/agents/swarm.js +85 -17
  28. package/dist/agents/swarm.js.map +1 -1
  29. package/dist/agents/types.d.ts +1 -0
  30. package/dist/agents/types.d.ts.map +1 -1
  31. package/dist/agents/types.js.map +1 -1
  32. package/dist/api-server.d.ts +9 -0
  33. package/dist/api-server.d.ts.map +1 -1
  34. package/dist/api-server.js +75 -4
  35. package/dist/api-server.js.map +1 -1
  36. package/dist/auto-checkpoint.d.ts.map +1 -1
  37. package/dist/auto-checkpoint.js +50 -17
  38. package/dist/auto-checkpoint.js.map +1 -1
  39. package/dist/auto-compressor.d.ts +14 -0
  40. package/dist/auto-compressor.d.ts.map +1 -1
  41. package/dist/auto-compressor.js +67 -10
  42. package/dist/auto-compressor.js.map +1 -1
  43. package/dist/background-jobs.d.ts.map +1 -1
  44. package/dist/background-jobs.js +8 -3
  45. package/dist/background-jobs.js.map +1 -1
  46. package/dist/bin.d.ts +8 -0
  47. package/dist/bin.d.ts.map +1 -1
  48. package/dist/bin.js +63 -4
  49. package/dist/bin.js.map +1 -1
  50. package/dist/branching.d.ts.map +1 -1
  51. package/dist/branching.js +14 -1
  52. package/dist/branching.js.map +1 -1
  53. package/dist/checkpoint.d.ts.map +1 -1
  54. package/dist/checkpoint.js +13 -1
  55. package/dist/checkpoint.js.map +1 -1
  56. package/dist/cli/agent.d.ts.map +1 -1
  57. package/dist/cli/agent.js +130 -62
  58. package/dist/cli/agent.js.map +1 -1
  59. package/dist/cli/commands.d.ts.map +1 -1
  60. package/dist/cli/commands.js +218 -11
  61. package/dist/cli/commands.js.map +1 -1
  62. package/dist/cli/index.d.ts.map +1 -1
  63. package/dist/cli/index.js +55 -6
  64. package/dist/cli/index.js.map +1 -1
  65. package/dist/cli/types.d.ts +3 -0
  66. package/dist/cli/types.d.ts.map +1 -1
  67. package/dist/cli/types.js +2 -1
  68. package/dist/cli/types.js.map +1 -1
  69. package/dist/config.d.ts +1 -0
  70. package/dist/config.d.ts.map +1 -1
  71. package/dist/config.js +15 -3
  72. package/dist/config.js.map +1 -1
  73. package/dist/diff.d.ts.map +1 -1
  74. package/dist/diff.js +42 -4
  75. package/dist/diff.js.map +1 -1
  76. package/dist/env-expansion.d.ts +15 -0
  77. package/dist/env-expansion.d.ts.map +1 -0
  78. package/dist/env-expansion.js +43 -0
  79. package/dist/env-expansion.js.map +1 -0
  80. package/dist/errors.d.ts.map +1 -1
  81. package/dist/errors.js +30 -3
  82. package/dist/errors.js.map +1 -1
  83. package/dist/headless.d.ts.map +1 -1
  84. package/dist/headless.js +59 -4
  85. package/dist/headless.js.map +1 -1
  86. package/dist/hooks.d.ts +8 -2
  87. package/dist/hooks.d.ts.map +1 -1
  88. package/dist/hooks.js +97 -11
  89. package/dist/hooks.js.map +1 -1
  90. package/dist/idle-eviction.d.ts.map +1 -1
  91. package/dist/idle-eviction.js +8 -1
  92. package/dist/idle-eviction.js.map +1 -1
  93. package/dist/iteration-ledger.d.ts +111 -2
  94. package/dist/iteration-ledger.d.ts.map +1 -1
  95. package/dist/iteration-ledger.js +327 -19
  96. package/dist/iteration-ledger.js.map +1 -1
  97. package/dist/iteration-limit.d.ts +5 -0
  98. package/dist/iteration-limit.d.ts.map +1 -0
  99. package/dist/iteration-limit.js +17 -0
  100. package/dist/iteration-limit.js.map +1 -0
  101. package/dist/markdown.d.ts.map +1 -1
  102. package/dist/markdown.js +32 -10
  103. package/dist/markdown.js.map +1 -1
  104. package/dist/mcp.d.ts +35 -5
  105. package/dist/mcp.d.ts.map +1 -1
  106. package/dist/mcp.js +191 -12
  107. package/dist/mcp.js.map +1 -1
  108. package/dist/memory.d.ts.map +1 -1
  109. package/dist/memory.js +4 -9
  110. package/dist/memory.js.map +1 -1
  111. package/dist/model-detection.d.ts +14 -1
  112. package/dist/model-detection.d.ts.map +1 -1
  113. package/dist/model-detection.js +307 -114
  114. package/dist/model-detection.js.map +1 -1
  115. package/dist/model-router.js +7 -7
  116. package/dist/model-router.js.map +1 -1
  117. package/dist/parallel-tools.d.ts +9 -1
  118. package/dist/parallel-tools.d.ts.map +1 -1
  119. package/dist/parallel-tools.js +6 -5
  120. package/dist/parallel-tools.js.map +1 -1
  121. package/dist/plugins.d.ts +37 -0
  122. package/dist/plugins.d.ts.map +1 -1
  123. package/dist/plugins.js +87 -0
  124. package/dist/plugins.js.map +1 -1
  125. package/dist/prevent-sleep.d.ts +10 -0
  126. package/dist/prevent-sleep.d.ts.map +1 -0
  127. package/dist/prevent-sleep.js +85 -0
  128. package/dist/prevent-sleep.js.map +1 -0
  129. package/dist/providers/anthropic.d.ts.map +1 -1
  130. package/dist/providers/anthropic.js +36 -2
  131. package/dist/providers/anthropic.js.map +1 -1
  132. package/dist/providers/bedrock.d.ts.map +1 -1
  133. package/dist/providers/bedrock.js +81 -17
  134. package/dist/providers/bedrock.js.map +1 -1
  135. package/dist/providers/compat.d.ts.map +1 -1
  136. package/dist/providers/compat.js +21 -6
  137. package/dist/providers/compat.js.map +1 -1
  138. package/dist/providers/index.d.ts.map +1 -1
  139. package/dist/providers/index.js +2 -0
  140. package/dist/providers/index.js.map +1 -1
  141. package/dist/providers/openai-compat-shims.d.ts +31 -0
  142. package/dist/providers/openai-compat-shims.d.ts.map +1 -0
  143. package/dist/providers/openai-compat-shims.js +179 -0
  144. package/dist/providers/openai-compat-shims.js.map +1 -0
  145. package/dist/providers/openai.d.ts.map +1 -1
  146. package/dist/providers/types.d.ts.map +1 -1
  147. package/dist/providers/types.js +19 -10
  148. package/dist/providers/types.js.map +1 -1
  149. package/dist/risk.d.ts.map +1 -1
  150. package/dist/risk.js +15 -5
  151. package/dist/risk.js.map +1 -1
  152. package/dist/sandbox-native.d.ts +1 -0
  153. package/dist/sandbox-native.d.ts.map +1 -1
  154. package/dist/sandbox-native.js +37 -5
  155. package/dist/sandbox-native.js.map +1 -1
  156. package/dist/scope.d.ts +10 -0
  157. package/dist/scope.d.ts.map +1 -1
  158. package/dist/scope.js +75 -15
  159. package/dist/scope.js.map +1 -1
  160. package/dist/scuttlebot/client.d.ts +83 -0
  161. package/dist/scuttlebot/client.d.ts.map +1 -0
  162. package/dist/scuttlebot/client.js +350 -0
  163. package/dist/scuttlebot/client.js.map +1 -0
  164. package/dist/scuttlebot/config.d.ts +28 -0
  165. package/dist/scuttlebot/config.d.ts.map +1 -0
  166. package/dist/scuttlebot/config.js +91 -0
  167. package/dist/scuttlebot/config.js.map +1 -0
  168. package/dist/scuttlebot/http-client.d.ts +63 -0
  169. package/dist/scuttlebot/http-client.d.ts.map +1 -0
  170. package/dist/scuttlebot/http-client.js +124 -0
  171. package/dist/scuttlebot/http-client.js.map +1 -0
  172. package/dist/scuttlebot/index.d.ts +13 -0
  173. package/dist/scuttlebot/index.d.ts.map +1 -0
  174. package/dist/scuttlebot/index.js +10 -0
  175. package/dist/scuttlebot/index.js.map +1 -0
  176. package/dist/scuttlebot/irc-client.d.ts +124 -0
  177. package/dist/scuttlebot/irc-client.d.ts.map +1 -0
  178. package/dist/scuttlebot/irc-client.js +599 -0
  179. package/dist/scuttlebot/irc-client.js.map +1 -0
  180. package/dist/skills.d.ts +19 -0
  181. package/dist/skills.d.ts.map +1 -1
  182. package/dist/skills.js +98 -10
  183. package/dist/skills.js.map +1 -1
  184. package/dist/smart-router.js +4 -4
  185. package/dist/smart-router.js.map +1 -1
  186. package/dist/storage.d.ts +18 -3
  187. package/dist/storage.d.ts.map +1 -1
  188. package/dist/storage.js +182 -14
  189. package/dist/storage.js.map +1 -1
  190. package/dist/tools.d.ts.map +1 -1
  191. package/dist/tools.js +233 -39
  192. package/dist/tools.js.map +1 -1
  193. package/dist/trust.d.ts +16 -3
  194. package/dist/trust.d.ts.map +1 -1
  195. package/dist/trust.js +23 -4
  196. package/dist/trust.js.map +1 -1
  197. package/dist/types.d.ts.map +1 -1
  198. package/dist/types.js +18 -12
  199. package/dist/types.js.map +1 -1
  200. package/dist/ui/agent.d.ts +1 -1
  201. package/dist/ui/agent.d.ts.map +1 -1
  202. package/dist/ui/agent.js +175 -121
  203. package/dist/ui/agent.js.map +1 -1
  204. package/dist/ui/chat-input.d.ts +3 -1
  205. package/dist/ui/chat-input.d.ts.map +1 -1
  206. package/dist/ui/chat-input.js +82 -17
  207. package/dist/ui/chat-input.js.map +1 -1
  208. package/dist/ui/commands.d.ts +4 -0
  209. package/dist/ui/commands.d.ts.map +1 -1
  210. package/dist/ui/commands.js +562 -39
  211. package/dist/ui/commands.js.map +1 -1
  212. package/dist/ui/completions.d.ts.map +1 -1
  213. package/dist/ui/completions.js +2 -0
  214. package/dist/ui/completions.js.map +1 -1
  215. package/dist/ui/index.d.ts.map +1 -1
  216. package/dist/ui/index.js +288 -60
  217. package/dist/ui/index.js.map +1 -1
  218. package/dist/ui/input-utils.d.ts +20 -0
  219. package/dist/ui/input-utils.d.ts.map +1 -0
  220. package/dist/ui/input-utils.js +35 -0
  221. package/dist/ui/input-utils.js.map +1 -0
  222. package/dist/ui/messages.d.ts +6 -2
  223. package/dist/ui/messages.d.ts.map +1 -1
  224. package/dist/ui/messages.js +42 -11
  225. package/dist/ui/messages.js.map +1 -1
  226. package/dist/ui/modals.d.ts +21 -1
  227. package/dist/ui/modals.d.ts.map +1 -1
  228. package/dist/ui/modals.js +67 -5
  229. package/dist/ui/modals.js.map +1 -1
  230. package/dist/ui/status-bar.d.ts +4 -1
  231. package/dist/ui/status-bar.d.ts.map +1 -1
  232. package/dist/ui/status-bar.js +12 -1
  233. package/dist/ui/status-bar.js.map +1 -1
  234. package/dist/ui/types.d.ts +3 -0
  235. package/dist/ui/types.d.ts.map +1 -1
  236. package/package.json +4 -7
  237. package/dist/completion.d.ts +0 -75
  238. package/dist/completion.d.ts.map +0 -1
  239. package/dist/completion.js +0 -234
  240. package/dist/completion.js.map +0 -1
  241. package/dist/keyboard.d.ts +0 -57
  242. package/dist/keyboard.d.ts.map +0 -1
  243. package/dist/keyboard.js +0 -265
  244. package/dist/keyboard.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"completions.d.ts","sourceRoot":"","sources":["../../src/ui/completions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAMxC,eAAO,MAAM,cAAc,UA0F1B,CAAC;AAGF,eAAO,MAAM,aAAa,UAA8D,CAAC;AAMzF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAwDzE;AAMD,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,IAAI,CAAC;IAClB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,wBAAwB,GAAG,MAAM,EAAE,CA2DlF"}
1
+ {"version":3,"file":"completions.d.ts","sourceRoot":"","sources":["../../src/ui/completions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAMxC,eAAO,MAAM,cAAc,UA4F1B,CAAC;AAGF,eAAO,MAAM,aAAa,UAA8D,CAAC;AAMzF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAwDzE;AAMD,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,IAAI,CAAC;IAClB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,wBAAwB,GAAG,MAAM,EAAE,CA2DlF"}
@@ -20,6 +20,7 @@ export const SLASH_COMMANDS = [
20
20
  '/plans',
21
21
  '/session',
22
22
  '/sessions',
23
+ '/log',
23
24
  '/history',
24
25
  '/context',
25
26
  '/summarize',
@@ -60,6 +61,7 @@ export const SLASH_COMMANDS = [
60
61
  '/upgrade',
61
62
  '/loop',
62
63
  '/cancel-loop',
64
+ '/breakloop',
63
65
  '/exit',
64
66
  '/keys',
65
67
  '/?',
@@ -1 +1 @@
1
- {"version":3,"file":"completions.js","sourceRoot":"","sources":["../../src/ui/completions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"completions.js","sourceRoot":"","sources":["../../src/ui/completions.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAmqCH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CA+DjD;AAED,wBAAsB,WAAW,CAAC,OAAO,GAAE;IAAE,eAAe,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBrH"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AA45CH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CA+DjD;AAED,wBAAsB,WAAW,CAAC,OAAO,GAAE;IAAE,eAAe,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBrH"}
package/dist/ui/index.js CHANGED
@@ -29,10 +29,11 @@ import * as recording from '../terminal-recording.js';
29
29
  import * as sessionTimeout from '../session-timeout.js';
30
30
  import * as idleEviction from '../idle-eviction.js';
31
31
  import { isTmux, getTmuxInfo } from '../tmux.js';
32
+ import { scuttlebotClient } from '../scuttlebot/index.js';
32
33
  import { ErrorBoundary } from './error-boundary.js';
33
34
  import { ThinkingDisplay, ProcessingIndicator, StreamingIndicator, StateTransition } from './components.js';
34
35
  import { MessageHistory } from './messages.js';
35
- import { ModelSelector, SessionSelector, UpgradePrompt, ComplexityWarning, SessionResumePrompt, KeybindingsModal, } from './modals.js';
36
+ import { ModelSelector, SessionSelector, UpgradePrompt, ComplexityWarning, SessionResumePrompt, KeybindingsModal, ProviderSelector, ApiKeySetup, } from './modals.js';
36
37
  import { ThemePicker } from './theme-picker.js';
37
38
  import { PackPicker } from './pack-picker.js';
38
39
  import { applyThemePack, getCurrentPack, getCompanionMode, getThemePack } from '../hud/theme-packs/api.js';
@@ -40,10 +41,28 @@ import { ChatInput } from './chat-input.js';
40
41
  import { StatusBar } from './status-bar.js';
41
42
  import { handleCommand } from './commands.js';
42
43
  import { runAgentImpl, runLoopImpl, validateAndRepairMessagesImpl } from './agent.js';
44
+ import { resolveIterationLimit } from '../iteration-limit.js';
43
45
  // Wire emoji config at module load (breaks circular dep: companions → config)
44
46
  setEmojiConfig(config);
45
47
  // Module-level state for agterm mode
46
48
  let moduleAgtermEnabled = false;
49
+ let pendingRestartArgs = null;
50
+ function requestSelfRestart(args = process.argv.slice(1)) {
51
+ pendingRestartArgs = [...args];
52
+ }
53
+ async function spawnPendingRestart() {
54
+ if (!pendingRestartArgs) {
55
+ return;
56
+ }
57
+ const restartArgs = pendingRestartArgs;
58
+ pendingRestartArgs = null;
59
+ const { spawn } = await import('child_process');
60
+ const child = spawn(process.argv[0], restartArgs, {
61
+ stdio: 'inherit',
62
+ detached: true,
63
+ });
64
+ child.unref();
65
+ }
47
66
  // Debug logging for flow control issues
48
67
  let debugEnabled = process.env.CALLIOPE_DEBUG === '1';
49
68
  const debugLog = (label, ...args) => {
@@ -69,7 +88,18 @@ function TerminalChat() {
69
88
  return () => { process.stdout.off('resize', onResize); };
70
89
  }, [stdout]);
71
90
  // Core state
72
- const [input, setInput] = useState('');
91
+ // Input value is held primarily in a ref so that keystrokes don't force
92
+ // a full parent re-render (which cascades through modals, layouts, status bar
93
+ // and causes visible paint lag on every character). We only bump `inputVersion`
94
+ // when we need the parent to re-render with a programmatic value change
95
+ // (history nav, clear on submit) — keystrokes never trigger a parent render.
96
+ const inputRef = useRef('');
97
+ const [inputVersion, setInputVersion] = useState(0);
98
+ const setInputValue = useCallback((value) => {
99
+ inputRef.current = value;
100
+ setInputVersion(v => v + 1);
101
+ }, []);
102
+ const input = inputRef.current;
73
103
  const [suggestions, setSuggestions] = useState([]);
74
104
  const [messages, setMessages] = useState([]);
75
105
  const [isProcessing, setIsProcessing] = useState(false);
@@ -106,15 +136,17 @@ function TerminalChat() {
106
136
  }
107
137
  });
108
138
  const recentCommands = React.useMemo(() => inputHistory.filter(cmd => cmd.startsWith('/')).slice(-10), [inputHistory]);
109
- // Clear suggestions when input changes significantly
139
+ // Handle changes coming from the ChatInput. During typing, we update the
140
+ // ref only — ChatInput paints itself synchronously from its own ref, so we
141
+ // don't need to re-render the parent. We still want to clear stale slash
142
+ // suggestions and reset history navigation, but those setters bail out
143
+ // via functional updates when the value is already current.
110
144
  const handleInputChange = useCallback((newValue) => {
111
- setInput(newValue);
112
- // Clear suggestions if user clears input or submits
145
+ inputRef.current = newValue;
113
146
  if (!newValue || !newValue.startsWith('/')) {
114
- setSuggestions([]);
147
+ setSuggestions(prev => prev.length > 0 ? [] : prev);
115
148
  }
116
- // Reset history navigation when user types
117
- setHistoryIndex(-1);
149
+ setHistoryIndex(prev => prev === -1 ? prev : -1);
118
150
  }, []);
119
151
  // Navigate input history
120
152
  const navigateHistory = useCallback((direction) => {
@@ -123,13 +155,13 @@ function TerminalChat() {
123
155
  if (direction === 'up') {
124
156
  if (historyIndex === -1) {
125
157
  // Save current input before navigating
126
- setSavedInput(input);
158
+ setSavedInput(inputRef.current);
127
159
  setHistoryIndex(inputHistory.length - 1);
128
- setInput(inputHistory[inputHistory.length - 1]);
160
+ setInputValue(inputHistory[inputHistory.length - 1]);
129
161
  }
130
162
  else if (historyIndex > 0) {
131
163
  setHistoryIndex(historyIndex - 1);
132
- setInput(inputHistory[historyIndex - 1]);
164
+ setInputValue(inputHistory[historyIndex - 1]);
133
165
  }
134
166
  }
135
167
  else {
@@ -137,15 +169,15 @@ function TerminalChat() {
137
169
  return;
138
170
  if (historyIndex < inputHistory.length - 1) {
139
171
  setHistoryIndex(historyIndex + 1);
140
- setInput(inputHistory[historyIndex + 1]);
172
+ setInputValue(inputHistory[historyIndex + 1]);
141
173
  }
142
174
  else {
143
175
  // Return to saved input
144
176
  setHistoryIndex(-1);
145
- setInput(savedInput);
177
+ setInputValue(savedInput);
146
178
  }
147
179
  }
148
- }, [inputHistory, historyIndex, input, savedInput]);
180
+ }, [inputHistory, historyIndex, savedInput, setInputValue]);
149
181
  // Add to history when submitting
150
182
  const addToHistory = useCallback((value) => {
151
183
  if (value.trim() && (inputHistory.length === 0 || inputHistory[inputHistory.length - 1] !== value)) {
@@ -170,6 +202,8 @@ function TerminalChat() {
170
202
  }));
171
203
  // Modal state
172
204
  const [modalMode, setModalMode] = useState('none');
205
+ const [providerEntries, setProviderEntries] = useState([]);
206
+ const [pendingSetupProvider, setPendingSetupProvider] = useState(null);
173
207
  const [pendingComplexPrompt, setPendingComplexPrompt] = useState(null);
174
208
  const [previousSession, setPreviousSession] = useState(null);
175
209
  const [pendingToolCall, setPendingToolCall] = useState(null);
@@ -193,6 +227,14 @@ function TerminalChat() {
193
227
  useEffect(() => {
194
228
  queuedMessagesRef.current = queuedMessages;
195
229
  }, [queuedMessages]);
230
+ // Refs for scuttlebot polling — avoids stale closures across re-renders
231
+ const isProcessingRef = useRef(false);
232
+ const handleSubmitRef = useRef(async () => { });
233
+ const openProviderPickerRef = useRef(null);
234
+ // Keep isProcessingRef in sync
235
+ useEffect(() => {
236
+ isProcessingRef.current = isProcessing;
237
+ }, [isProcessing]);
196
238
  // Undo/Redo history - stores snapshots of conversation state
197
239
  const undoStack = useRef([]);
198
240
  const redoStack = useRef([]);
@@ -291,30 +333,26 @@ function TerminalChat() {
291
333
  // Agent loop state
292
334
  const [loopActive, setLoopActive] = useState(false);
293
335
  const [loopPrompt, setLoopPrompt] = useState('');
294
- const [loopMaxIterations, setLoopMaxIterations] = useState(100);
336
+ const [loopMaxIterations, setLoopMaxIterations] = useState(() => resolveIterationLimit(config.get('maxIterations')));
295
337
  const [loopCompletionPromise, setLoopCompletionPromise] = useState();
296
338
  const [loopIteration, setLoopIteration] = useState(0);
297
339
  const loopCancelledRef = useRef(false);
298
340
  // Initialize session and load memory on mount
299
341
  useEffect(() => {
300
342
  const cwd = process.cwd();
301
- // Check for existing session with messages
302
- const existingSessions = storage.listSessions(5);
303
- const recentSession = existingSessions.find(s => s.projectPath === cwd &&
304
- s.messageCount > 0 &&
305
- Date.now() - new Date(s.lastAccessedAt).getTime() < 24 * 60 * 60 * 1000 // Within 24 hours
306
- );
307
- if (recentSession && !sessionRef.current) {
308
- // Offer to resume
309
- setPreviousSession({
310
- projectName: recentSession.projectName,
311
- lastAccessedAt: recentSession.lastAccessedAt,
312
- messageCount: recentSession.messageCount,
313
- });
314
- setModalMode('session-resume');
315
- }
343
+ // Always start fresh session - skip resume dialog
344
+ // Note: Previous session data is still available via storage APIs if needed
316
345
  const session = storage.getOrCreateSession(cwd);
317
346
  sessionRef.current = session;
347
+ ledgerRef.current.setRetentionLimit(config.get('sessionLogLimit') ?? 0);
348
+ ledgerRef.current.setOnChange(() => {
349
+ const activeSessionId = sessionRef.current?.id;
350
+ if (activeSessionId) {
351
+ storage.saveIterationLedger(ledgerRef.current, activeSessionId);
352
+ }
353
+ });
354
+ ledgerRef.current.loadSnapshot(storage.loadIterationLedger(session.id));
355
+ storage.saveIterationLedger(ledgerRef.current, session.id);
318
356
  // Load memory context into system prompt
319
357
  if (!memoryLoaded) {
320
358
  const cwdMem = process.cwd();
@@ -345,6 +383,28 @@ function TerminalChat() {
345
383
  model: model || DEFAULT_MODELS[selectProvider(provider)],
346
384
  cwd: cwdMem,
347
385
  });
386
+ // Initialize scuttlebot integration
387
+ scuttlebotClient.initialize(session.id, cwdMem).then((enabled) => {
388
+ if (enabled) {
389
+ const status = scuttlebotClient.getStatus();
390
+ debugLog('scuttlebot', `enabled, nick=${status.nick}, irc=${status.config?.ircAddr}`);
391
+ // Show nick in system messages so operators know how to address calliope
392
+ addMessage('system', `IRC connected — address me as: ${status.nick}`);
393
+ scuttlebotClient.postOnline().catch(() => { });
394
+ scuttlebotClient.postMessage(`connected — address me as: ${status.nick}`).catch(() => { });
395
+ // Route incoming IRC instructions into the agent loop
396
+ scuttlebotClient.startPolling((instruction) => {
397
+ if (isProcessingRef.current) {
398
+ setQueuedMessages(prev => [...prev, instruction]);
399
+ }
400
+ else {
401
+ void handleSubmitRef.current(instruction);
402
+ }
403
+ });
404
+ }
405
+ }).catch((err) => {
406
+ debugLog('scuttlebot', 'initialization failed:', err instanceof Error ? err.message : err);
407
+ });
348
408
  // Configure session timeout (opt-in via config)
349
409
  const timeoutMs = config.get('sessionTimeoutMs');
350
410
  if (timeoutMs) {
@@ -396,11 +456,15 @@ function TerminalChat() {
396
456
  const actualModel = model || DEFAULT_MODELS[actualProvider];
397
457
  const isModalActive = modalMode !== 'none';
398
458
  // Add message helper
399
- const addMessage = useCallback((type, content) => {
459
+ const addMessage = useCallback((type, content, isError) => {
400
460
  setMessages(prev => [...prev, {
401
461
  id: `${Date.now()}-${Math.random().toString(36).slice(2)}`,
402
462
  type,
403
- content
463
+ content,
464
+ // isError is plumbed through to the renderer (messages.tsx) so the tool
465
+ // status icon is driven by the authoritative executeTool flag rather than
466
+ // string-matching the output. Omitted (undefined) for non-tool messages.
467
+ ...(isError !== undefined ? { isError } : {}),
404
468
  }]);
405
469
  // Persist user and assistant messages to storage for session history
406
470
  if (type === 'user' || type === 'assistant') {
@@ -501,6 +565,7 @@ function TerminalChat() {
501
565
  circuitBreaker: circuitBreakerRef.current || undefined,
502
566
  smartRouteActive,
503
567
  smartRoutingConfig: smartRoutingConfigRef.current,
568
+ ledger: ledgerRef.current,
504
569
  setProvider,
505
570
  setModel,
506
571
  setPersona,
@@ -526,7 +591,7 @@ function TerminalChat() {
526
591
  setThinkingState,
527
592
  setStreamingResponse,
528
593
  setQueuedMessages,
529
- setInput,
594
+ setInput: setInputValue,
530
595
  setBookmarks,
531
596
  setTemplates,
532
597
  setContextTokens,
@@ -544,6 +609,17 @@ function TerminalChat() {
544
609
  runAgent,
545
610
  runLoop,
546
611
  exit,
612
+ startScuttlebotPolling: () => {
613
+ scuttlebotClient.startPolling((instruction) => {
614
+ if (isProcessingRef.current) {
615
+ setQueuedMessages(prev => [...prev, instruction]);
616
+ }
617
+ else {
618
+ void handleSubmitRef.current(instruction);
619
+ }
620
+ });
621
+ },
622
+ openProviderPicker: () => openProviderPickerRef.current?.(),
547
623
  }), [actualProvider, actualModel, provider, model, persona, mode, confirmMode, autoRoute, smartRouteActive,
548
624
  layout, density, collapseSettings, messages, stats, loopActive, isProcessing,
549
625
  thinkingState, streamingResponse, queuedMessages, bookmarks, templates, modalMode,
@@ -564,7 +640,7 @@ function TerminalChat() {
564
640
  recording.recordEvent('input', trimmed);
565
641
  // Add to history for up/down arrow navigation
566
642
  addToHistory(trimmed);
567
- setInput('');
643
+ setInputValue('');
568
644
  if (trimmed.startsWith('/')) {
569
645
  await handleCommandWrapped(trimmed);
570
646
  return;
@@ -576,8 +652,9 @@ function TerminalChat() {
576
652
  addMessage('system', `$ ${shellCmd}`);
577
653
  try {
578
654
  const { execSync } = await import('child_process');
655
+ const activeCwd = sessionRef.current?.projectPath ?? process.cwd();
579
656
  const output = execSync(shellCmd, {
580
- cwd: process.cwd(),
657
+ cwd: activeCwd,
581
658
  encoding: 'utf-8',
582
659
  timeout: 30000,
583
660
  stdio: ['pipe', 'pipe', 'pipe'],
@@ -604,7 +681,8 @@ function TerminalChat() {
604
681
  // Save state for undo before modifying conversation
605
682
  saveUndoState();
606
683
  // Parse file references from input
607
- const { text: cleanText, files } = parseFileReferences(trimmed, process.cwd());
684
+ const activeCwd = sessionRef.current?.projectPath ?? process.cwd();
685
+ const { text: cleanText, files } = parseFileReferences(trimmed, activeCwd);
608
686
  // Show user message (with file info if any)
609
687
  if (files.length > 0) {
610
688
  const fileInfo = formatFileInfo(files);
@@ -613,6 +691,10 @@ function TerminalChat() {
613
691
  else {
614
692
  addMessage('user', trimmed);
615
693
  }
694
+ // Mirror user input to IRC so observers see what prompted each agent run
695
+ if (scuttlebotClient.isEnabled()) {
696
+ scuttlebotClient.postMessage(cleanText || trimmed).catch(() => { });
697
+ }
616
698
  setIsProcessing(true);
617
699
  try {
618
700
  // Build message content (with file/image support)
@@ -636,7 +718,11 @@ function TerminalChat() {
636
718
  setThinkingState(null);
637
719
  setStreamingResponse('');
638
720
  }
639
- }, [isProcessing, handleCommandWrapped, runAgent, addMessage, provider, model, saveUndoState, addToHistory, mode]);
721
+ }, [isProcessing, handleCommandWrapped, runAgent, addMessage, provider, model, saveUndoState, addToHistory, mode, setInputValue]);
722
+ // Keep handleSubmitRef current so scuttlebot polling never captures a stale closure
723
+ useEffect(() => {
724
+ handleSubmitRef.current = handleSubmit;
725
+ }, [handleSubmit]);
640
726
  // Modal handlers
641
727
  const handleModelSelect = useCallback((selectedModel) => {
642
728
  setModel(selectedModel);
@@ -657,13 +743,9 @@ function TerminalChat() {
657
743
  const success = await performUpgrade();
658
744
  if (success) {
659
745
  addMessage('system', 'Upgrade complete! Restarting...');
660
- const { spawn } = await import('child_process');
661
- const child = spawn(process.argv[0], process.argv.slice(1), {
662
- stdio: 'inherit',
663
- detached: true,
664
- });
665
- child.unref();
666
- process.exit(0);
746
+ requestSelfRestart(process.argv.slice(1));
747
+ exit();
748
+ return;
667
749
  }
668
750
  else {
669
751
  addMessage('error', 'Upgrade failed. Try: npm install -g @calliopelabs/cli@latest');
@@ -692,7 +774,7 @@ function TerminalChat() {
692
774
  setStreamingResponse('');
693
775
  setLoopActive(false);
694
776
  setEditingQueueIndex(null);
695
- addMessage('system', '⏹ Operation cancelled. Use /exit to quit.');
777
+ addMessage('system', '⏹ Operation cancelled. Press Ctrl+C again to quit.');
696
778
  }
697
779
  else if (modalMode !== 'none') {
698
780
  // Close any open modal
@@ -700,10 +782,113 @@ function TerminalChat() {
700
782
  setPendingComplexPrompt(null);
701
783
  }
702
784
  else {
703
- // Not processing - show hint instead of exiting
704
- addMessage('system', '💡 Use /exit to quit, or Ctrl+C.');
785
+ // Not processing - show hint. Second Ctrl+C within 2s will actually exit.
786
+ addMessage('system', '💡 Press Ctrl+C again to quit, or /exit.');
705
787
  }
706
788
  }, [isProcessing, modalMode, addMessage]);
789
+ const handleExit = useCallback(() => {
790
+ exit();
791
+ }, [exit]);
792
+ // Build the list of providers with their configuration status for the picker.
793
+ // Ordering: Ollama first (recommended onboarding), then others by rough popularity.
794
+ const buildProviderEntries = useCallback(() => {
795
+ const hasBedrock = !!(config.getApiKey('bedrock') || config.getBaseUrl('bedrock')
796
+ || process.env.AWS_ACCESS_KEY_ID || process.env.AWS_PROFILE);
797
+ const entries = [
798
+ { id: 'ollama', label: 'Ollama', configured: !!config.getBaseUrl('ollama'), configHint: 'OLLAMA_BASE_URL', recommended: true, note: 'local, free' },
799
+ { id: 'anthropic', label: 'Anthropic', configured: !!config.getApiKey('anthropic'), configHint: 'ANTHROPIC_API_KEY' },
800
+ { id: 'openai', label: 'OpenAI', configured: !!config.getApiKey('openai'), configHint: 'OPENAI_API_KEY' },
801
+ { id: 'google', label: 'Google', configured: !!config.getApiKey('google'), configHint: 'GOOGLE_API_KEY' },
802
+ { id: 'mistral', label: 'Mistral', configured: !!config.getApiKey('mistral'), configHint: 'MISTRAL_API_KEY' },
803
+ { id: 'openrouter', label: 'OpenRouter', configured: !!config.getApiKey('openrouter'), configHint: 'OPENROUTER_API_KEY' },
804
+ { id: 'together', label: 'Together', configured: !!config.getApiKey('together'), configHint: 'TOGETHER_API_KEY' },
805
+ { id: 'groq', label: 'Groq', configured: !!config.getApiKey('groq'), configHint: 'GROQ_API_KEY' },
806
+ { id: 'fireworks', label: 'Fireworks', configured: !!config.getApiKey('fireworks'), configHint: 'FIREWORKS_API_KEY' },
807
+ { id: 'ai21', label: 'AI21', configured: !!config.getApiKey('ai21'), configHint: 'AI21_API_KEY' },
808
+ { id: 'huggingface', label: 'HuggingFace', configured: !!config.getApiKey('huggingface'), configHint: 'HUGGINGFACE_API_KEY' },
809
+ { id: 'bedrock', label: 'AWS Bedrock', configured: hasBedrock, configHint: 'AWS_PROFILE or AWS_ACCESS_KEY_ID', note: 'AWS credentials' },
810
+ { id: 'litellm', label: 'LiteLLM', configured: !!config.getBaseUrl('litellm'), configHint: 'LITELLM_BASE_URL' },
811
+ ];
812
+ return entries;
813
+ }, []);
814
+ const openProviderPicker = useCallback(() => {
815
+ setProviderEntries(buildProviderEntries());
816
+ setModalMode('provider');
817
+ }, [buildProviderEntries]);
818
+ const handleProviderSelect = useCallback((entry) => {
819
+ if (entry.configured) {
820
+ setProvider(entry.id);
821
+ addMessage('system', `Provider: ${entry.label}${entry.id === 'ollama' ? ' (local)' : ''}`);
822
+ setModalMode('none');
823
+ setProviderEntries([]);
824
+ return;
825
+ }
826
+ // Not configured — open inline setup.
827
+ setPendingSetupProvider(entry);
828
+ setModalMode('api-key-setup');
829
+ }, [addMessage, setProvider]);
830
+ const handleApiKeySubmit = useCallback((value) => {
831
+ const entry = pendingSetupProvider;
832
+ if (!entry) {
833
+ setModalMode('none');
834
+ return;
835
+ }
836
+ try {
837
+ // Map provider → config key. Bedrock/Ollama/LiteLLM are special (base URL or AWS).
838
+ if (entry.id === 'ollama') {
839
+ config.set('ollamaBaseUrl', value);
840
+ }
841
+ else if (entry.id === 'litellm') {
842
+ config.set('litellmBaseUrl', value);
843
+ }
844
+ else if (entry.id === 'bedrock') {
845
+ // Simplest path: user enters AWS_PROFILE name. Write to env for this session;
846
+ // persistence is user's responsibility (profile lives in ~/.aws).
847
+ process.env.AWS_PROFILE = value;
848
+ // Clear any stale env-var credentials (e.g. from a prior `aws sso login`
849
+ // export that's since expired) so the profile actually wins.
850
+ delete process.env.AWS_ACCESS_KEY_ID;
851
+ delete process.env.AWS_SECRET_ACCESS_KEY;
852
+ delete process.env.AWS_SESSION_TOKEN;
853
+ addMessage('system', `AWS_PROFILE=${value} set for this session. Add to shell rc to persist.`);
854
+ }
855
+ else {
856
+ const keyMap = {
857
+ anthropic: 'anthropicApiKey',
858
+ openai: 'openaiApiKey',
859
+ google: 'googleApiKey',
860
+ mistral: 'mistralApiKey',
861
+ openrouter: 'openrouterApiKey',
862
+ together: 'togetherApiKey',
863
+ groq: 'groqApiKey',
864
+ fireworks: 'fireworksApiKey',
865
+ ai21: 'ai21ApiKey',
866
+ huggingface: 'huggingfaceApiKey',
867
+ };
868
+ const configKey = keyMap[entry.id];
869
+ if (!configKey)
870
+ throw new Error(`No config mapping for ${entry.id}`);
871
+ // Cast through any — the mapping above guarantees a valid ApiKey field.
872
+ config.set(configKey, value);
873
+ }
874
+ setProvider(entry.id);
875
+ addMessage('system', `✓ Configured ${entry.label}. Provider switched.`);
876
+ }
877
+ catch (e) {
878
+ addMessage('error', `Failed to configure ${entry.label}: ${e instanceof Error ? e.message : String(e)}`);
879
+ }
880
+ setPendingSetupProvider(null);
881
+ setModalMode('none');
882
+ }, [pendingSetupProvider, addMessage, setProvider]);
883
+ const handleApiKeyCancel = useCallback(() => {
884
+ setPendingSetupProvider(null);
885
+ setModalMode('none');
886
+ }, []);
887
+ // Forward-declared ref so buildCommandContext (defined earlier) can open the
888
+ // provider picker without a TDZ on the openProviderPicker callback.
889
+ useEffect(() => {
890
+ openProviderPickerRef.current = openProviderPicker;
891
+ }, [openProviderPicker]);
707
892
  // Handle direct send (Shift+Enter) - interrupts current operation and sends immediately
708
893
  const handleDirectSend = useCallback((msg) => {
709
894
  // Stop current processing
@@ -743,20 +928,45 @@ function TerminalChat() {
743
928
  addMessage('error', `Failed to delete session: ${session.projectName}`);
744
929
  }
745
930
  }, onCancel: handleModalCancel })), modalMode === 'upgrade' && latestVersion && (_jsx(UpgradePrompt, { currentVersion: getVersion(), latestVersion: latestVersion, onConfirm: handleUpgradeConfirm, onCancel: handleModalCancel })), modalMode === 'session-resume' && previousSession && (_jsx(SessionResumePrompt, { session: previousSession, onResume: () => {
746
- // Load chat history into context
747
- const history = storage.getChatHistory(20);
748
- if (history.length > 0) {
749
- for (const msg of history) {
750
- if (msg.role === 'user' || msg.role === 'assistant') {
751
- llmMessages.current.push({
752
- role: msg.role,
753
- content: msg.content,
754
- });
755
- }
931
+ const savedMessages = storage.loadMessageHistory();
932
+ if (savedMessages && savedMessages.length > 0) {
933
+ llmMessages.current.length = 0;
934
+ for (const msg of savedMessages) {
935
+ llmMessages.current.push(msg);
936
+ }
937
+ addMessage('system', `✓ Resumed session with ${savedMessages.length} saved messages loaded`);
938
+ const activeSessionId = sessionRef.current?.id;
939
+ if (activeSessionId) {
940
+ ledgerRef.current.loadSnapshot(storage.loadIterationLedger(activeSessionId));
941
+ storage.saveIterationLedger(ledgerRef.current, activeSessionId);
756
942
  }
757
- addMessage('system', `✓ Resumed session with ${history.length} messages loaded`);
758
943
  setContextTokens(estimateContextTokens());
759
944
  }
945
+ else {
946
+ const history = storage.getChatHistory(20);
947
+ if (history.length > 0) {
948
+ llmMessages.current.length = 0;
949
+ const activeCwd = sessionRef.current?.projectPath ?? process.cwd();
950
+ const basePrompt = getSystemPrompt(persona);
951
+ const memoryContext = memory.buildMemoryContext(activeCwd);
952
+ llmMessages.current.push({
953
+ role: 'system',
954
+ content: memoryContext.trim()
955
+ ? `${basePrompt}\n\n--- Project Context ---\n${memoryContext}`
956
+ : basePrompt,
957
+ });
958
+ for (const msg of history) {
959
+ if (msg.role === 'user' || msg.role === 'assistant') {
960
+ llmMessages.current.push({
961
+ role: msg.role,
962
+ content: msg.content,
963
+ });
964
+ }
965
+ }
966
+ addMessage('system', `✓ Resumed session with ${history.length} chat messages loaded`);
967
+ setContextTokens(estimateContextTokens());
968
+ }
969
+ }
760
970
  setModalMode('none');
761
971
  setPreviousSession(null);
762
972
  }, onNew: () => {
@@ -792,7 +1002,16 @@ function TerminalChat() {
792
1002
  setModalMode('none');
793
1003
  setPendingComplexPrompt(null);
794
1004
  addMessage('system', 'Operation cancelled.');
795
- } })), modalMode === 'keys' && (_jsx(KeybindingsModal, { onClose: () => setModalMode('none') })), modalMode === 'theme-picker' && (_jsx(ThemePicker, { currentLayout: layout, currentSkin: getCurrentSkin().name, currentPalette: getCurrentPalette().name, currentCompanion: getCurrentCompanion().name, onApply: (selection) => {
1005
+ } })), modalMode === 'keys' && (_jsx(KeybindingsModal, { onClose: () => setModalMode('none') })), modalMode === 'provider' && providerEntries.length > 0 && (_jsx(ProviderSelector, { providers: providerEntries, onSelect: handleProviderSelect, onCancel: () => {
1006
+ setModalMode('none');
1007
+ setProviderEntries([]);
1008
+ } })), modalMode === 'api-key-setup' && pendingSetupProvider && (_jsx(ApiKeySetup, { provider: pendingSetupProvider.id, configHint: pendingSetupProvider.configHint, onSubmit: handleApiKeySubmit, onCancel: handleApiKeyCancel, extraInstructions: pendingSetupProvider.id === 'ollama'
1009
+ ? 'e.g. http://localhost:11434 (start with: ollama serve)'
1010
+ : pendingSetupProvider.id === 'bedrock'
1011
+ ? 'Enter your AWS profile name. Ensure it exists in ~/.aws/credentials or ~/.aws/config.'
1012
+ : pendingSetupProvider.id === 'litellm'
1013
+ ? 'e.g. http://localhost:4000'
1014
+ : undefined })), modalMode === 'theme-picker' && (_jsx(ThemePicker, { currentLayout: layout, currentSkin: getCurrentSkin().name, currentPalette: getCurrentPalette().name, currentCompanion: getCurrentCompanion().name, onApply: (selection) => {
796
1015
  // Apply all selections
797
1016
  setLayout(selection.layout);
798
1017
  config.set('layout', selection.layout);
@@ -836,7 +1055,7 @@ function TerminalChat() {
836
1055
  ` Skin: ${pack.skin.name}, Palette: ${pack.palette.name}, Companion: ${companion.name}\n` +
837
1056
  ` "${companion.greeting}"`);
838
1057
  }
839
- }, onCancel: () => setModalMode('none') })), _jsx(ChatInput, { value: input, onChange: handleInputChange, onSubmit: handleSubmit, onEscape: handleEscape, onCycleMode: cycleMode, disabled: isModalActive, isProcessing: isProcessing, queuedCount: queuedMessages.length, queuedMessages: queuedMessages, editingQueueIndex: editingQueueIndex, onQueueMessage: (msg) => {
1058
+ }, onCancel: () => setModalMode('none') })), _jsx(ChatInput, { value: input, valueVersion: inputVersion, onChange: handleInputChange, onSubmit: handleSubmit, onEscape: handleEscape, onExit: handleExit, onCycleMode: cycleMode, disabled: isModalActive, isProcessing: isProcessing, queuedCount: queuedMessages.length, queuedMessages: queuedMessages, editingQueueIndex: editingQueueIndex, onQueueMessage: (msg) => {
840
1059
  setQueuedMessages(prev => [...prev, msg]);
841
1060
  addMessage('system', `📨 Queued: "${msg.substring(0, 50)}${msg.length > 50 ? '...' : ''}"`);
842
1061
  }, onEditQueuedMessage: handleEditQueuedMessage, onSetEditingQueueIndex: setEditingQueueIndex, onDirectSend: handleDirectSend, cwd: process.cwd(), suggestions: suggestions, onSuggestionsChange: setSuggestions, onNavigateHistory: navigateHistory,
@@ -921,8 +1140,17 @@ export async function startInkCLI(options = {}) {
921
1140
  });
922
1141
  await waitUntilExit();
923
1142
  // Session cleanup
1143
+ if (scuttlebotClient.isEnabled()) {
1144
+ await scuttlebotClient.postOffline().catch(() => {
1145
+ // Silent fail
1146
+ });
1147
+ await scuttlebotClient.disconnect().catch(() => {
1148
+ // Silent fail
1149
+ });
1150
+ }
924
1151
  recording.stopRecording();
925
1152
  sessionTimeout.clearTimers();
926
1153
  idleEviction.stopMonitor();
1154
+ await spawnPendingRestart();
927
1155
  }
928
1156
  //# sourceMappingURL=index.js.map