agentgui 1.0.552 → 1.0.554

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.
@@ -95,6 +95,10 @@ class AgentRunner {
95
95
  try { config.onPid(proc.pid); } catch (e) {}
96
96
  }
97
97
 
98
+ if (config.onProcess) {
99
+ try { config.onProcess(proc); } catch (e) {}
100
+ }
101
+
98
102
  let jsonBuffer = '';
99
103
  const outputs = [];
100
104
  let timedOut = false;
@@ -274,6 +278,10 @@ class AgentRunner {
274
278
  try { config.onPid(proc.pid); } catch (e) {}
275
279
  }
276
280
 
281
+ if (config.onProcess) {
282
+ try { config.onProcess(proc); } catch (e) {}
283
+ }
284
+
277
285
  const outputs = [];
278
286
  let timedOut = false;
279
287
  let sessionId = null;
@@ -5,7 +5,7 @@ function notFound(msg = 'Not found') { fail(404, msg); }
5
5
 
6
6
  export function register(router, deps) {
7
7
  const { queries, activeExecutions, messageQueues, rateLimitState,
8
- broadcastSync, processMessageWithStreaming } = deps;
8
+ broadcastSync, processMessageWithStreaming, activeProcessesByConvId } = deps;
9
9
 
10
10
  router.handle('conv.ls', () => {
11
11
  const conversations = queries.getConversationsList();
@@ -114,6 +114,28 @@ export function register(router, deps) {
114
114
  return { ok: true, injected: true, conversationId: p.id, messageId: message.id };
115
115
  });
116
116
 
117
+ router.handle('conv.steer', (p) => {
118
+ const conv = queries.getConversation(p.id);
119
+ if (!conv) notFound('Conversation not found');
120
+ if (!p.content) fail(400, 'Missing content');
121
+ const entry = activeExecutions.get(p.id);
122
+ if (!entry) fail(409, 'No active execution to steer');
123
+ const proc = activeProcessesByConvId.get(p.id);
124
+ if (!proc || !proc.stdin) fail(409, 'Process not available for steering');
125
+
126
+ const message = queries.createMessage(p.id, 'user', p.content);
127
+ queries.createEvent('message.created', { role: 'user', messageId: message.id }, p.id);
128
+ broadcastSync({ type: 'message_created', conversationId: p.id, message, timestamp: Date.now() });
129
+
130
+ try {
131
+ // Write directly to stdin for steering
132
+ proc.stdin.write(p.content + '\n');
133
+ return { ok: true, steered: true, conversationId: p.id, messageId: message.id };
134
+ } catch (err) {
135
+ fail(500, `Failed to steer: ${err.message}`);
136
+ }
137
+ });
138
+
117
139
  router.handle('msg.ls', (p) => {
118
140
  return queries.getPaginatedMessages(p.id, Math.min(p.limit || 50, 100), Math.max(p.offset || 0, 0));
119
141
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentgui",
3
- "version": "1.0.552",
3
+ "version": "1.0.554",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "server.js",
package/server.js CHANGED
@@ -292,6 +292,7 @@ const activeScripts = new Map();
292
292
  const messageQueues = new Map();
293
293
  const rateLimitState = new Map();
294
294
  const activeProcessesByRunId = new Map();
295
+ const activeProcessesByConvId = new Map(); // Store process handles by conversationId for steering
295
296
  const acpQueries = queries;
296
297
  const STUCK_AGENT_THRESHOLD_MS = 600000;
297
298
  const NO_PID_GRACE_PERIOD_MS = 60000;
@@ -3806,18 +3807,24 @@ async function processMessageWithStreaming(conversationId, messageId, sessionId,
3806
3807
  onPid: (pid) => {
3807
3808
  const entry = activeExecutions.get(conversationId);
3808
3809
  if (entry) entry.pid = pid;
3810
+ },
3811
+ onProcess: (proc) => {
3812
+ // Store process handle for steering
3813
+ activeProcessesByConvId.set(conversationId, proc);
3809
3814
  }
3810
3815
  };
3811
3816
 
3812
3817
  const { outputs, sessionId: claudeSessionId } = await runClaudeWithStreaming(content, cwd, agentId || 'claude-code', config);
3813
-
3818
+
3814
3819
  // Check if rate limit was already handled in stream detection
3815
3820
  if (rateLimitState.get(conversationId)?.isStreamDetected) {
3816
3821
  debugLog(`[rate-limit] Rate limit already handled in stream for conv ${conversationId}, skipping success handler`);
3822
+ activeProcessesByConvId.delete(conversationId);
3817
3823
  return;
3818
3824
  }
3819
-
3825
+
3820
3826
  activeExecutions.delete(conversationId);
3827
+ activeProcessesByConvId.delete(conversationId);
3821
3828
  batcher.drain();
3822
3829
  debugLog(`[stream] Claude returned ${outputs.length} outputs, sessionId=${claudeSessionId}`);
3823
3830
 
@@ -4134,7 +4141,7 @@ const wsRouter = new WsRouter();
4134
4141
 
4135
4142
  registerConvHandlers(wsRouter, {
4136
4143
  queries, activeExecutions, messageQueues, rateLimitState,
4137
- broadcastSync, processMessageWithStreaming
4144
+ broadcastSync, processMessageWithStreaming, activeProcessesByConvId
4138
4145
  });
4139
4146
 
4140
4147
  registerSessionHandlers(wsRouter, {
package/static/index.html CHANGED
@@ -948,6 +948,26 @@
948
948
  .inject-btn:disabled { opacity: 0.4; cursor: not-allowed; }
949
949
  .inject-btn.visible { display: flex; }
950
950
 
951
+ .steer-btn {
952
+ display: none;
953
+ align-items: center;
954
+ justify-content: center;
955
+ width: 40px;
956
+ height: 40px;
957
+ background-color: #06b6d4;
958
+ color: white;
959
+ border: none;
960
+ border-radius: 0.5rem;
961
+ cursor: pointer;
962
+ flex-shrink: 0;
963
+ transition: background-color 0.15s;
964
+ margin-right: 0.25rem;
965
+ }
966
+
967
+ .steer-btn:hover:not(:disabled) { background-color: #0891b2; }
968
+ .steer-btn:disabled { opacity: 0.4; cursor: not-allowed; }
969
+ .steer-btn.visible { display: flex; }
970
+
951
971
  /* ===== OVERLAY for mobile sidebar ===== */
952
972
  .sidebar-overlay {
953
973
  display: none;
@@ -1478,7 +1498,7 @@
1478
1498
  overflow: hidden;
1479
1499
  }
1480
1500
 
1481
- html.dark .block-thinking { background: #1e1033; }
1501
+ html.dark .block-thinking { }
1482
1502
 
1483
1503
  .block-thinking summary {
1484
1504
  padding: 0.375rem 0.75rem;
@@ -1495,7 +1515,7 @@
1495
1515
  }
1496
1516
 
1497
1517
  html.dark .block-thinking summary { color: #c4b5fd; }
1498
- .block-thinking summary:hover { background: rgba(139,92,246,0.08); }
1518
+ .block-thinking summary:hover { }
1499
1519
 
1500
1520
  .block-thinking .thinking-content {
1501
1521
  padding: 0.375rem 0.75rem;
@@ -1515,7 +1535,7 @@
1515
1535
  overflow: hidden;
1516
1536
  }
1517
1537
 
1518
- html.dark .block-tool-use { background: #0c1a24; }
1538
+ html.dark .block-tool-use { }
1519
1539
 
1520
1540
  .block-tool-use .tool-header {
1521
1541
  padding: 0.375rem 0.75rem;
@@ -1525,7 +1545,7 @@
1525
1545
  background: #cffafe;
1526
1546
  }
1527
1547
 
1528
- html.dark .block-tool-use .tool-header { background: #0e2a3a; }
1548
+ html.dark .block-tool-use .tool-header { }
1529
1549
 
1530
1550
  .block-tool-use .tool-header .tool-icon {
1531
1551
  display: flex;
@@ -1545,13 +1565,12 @@
1545
1565
 
1546
1566
  .block-tool-use .tool-header .tool-name code {
1547
1567
  font-family: 'Monaco','Menlo','Ubuntu Mono', monospace;
1548
- background: #a5f3fc;
1549
1568
  padding: 0.125rem 0.5rem;
1550
1569
  border-radius: 0.25rem;
1551
1570
  font-size: 0.8rem;
1552
1571
  }
1553
1572
 
1554
- html.dark .block-tool-use .tool-header .tool-name code { background: #164e63; }
1573
+ html.dark .block-tool-use .tool-header .tool-name code { }
1555
1574
 
1556
1575
  .block-tool-use .tool-params {
1557
1576
  padding: 0.5rem 0.75rem;
@@ -1884,15 +1903,13 @@
1884
1903
  .folded-tool-info > .folded-tool-body { border-top-color: #c7d2fe; }
1885
1904
  html.dark .folded-tool-info > .folded-tool-body { border-top-color: #3730a3; }
1886
1905
 
1887
- /* --- Per-block-type unique colored backgrounds --- */
1888
- .block-type-text { background: #f8fafc; }
1889
- html.dark .block-type-text { background: #1e293b; }
1906
+ /* --- Per-block-type unique colored backgrounds (removed) --- */
1890
1907
 
1891
1908
  /* --- Per-tool-name header colors (tool-color-*) --- */
1892
- .tool-color-read.folded-tool > .folded-tool-bar { background: #dbeafe; }
1893
- html.dark .tool-color-read.folded-tool > .folded-tool-bar { background: #1e3a5f; }
1894
- .tool-color-read.folded-tool > .folded-tool-bar:hover { background: #bfdbfe; }
1895
- html.dark .tool-color-read.folded-tool > .folded-tool-bar:hover { background: #1e40af; }
1909
+ .tool-color-read.folded-tool > .folded-tool-bar { }
1910
+ html.dark .tool-color-read.folded-tool > .folded-tool-bar { }
1911
+ .tool-color-read.folded-tool > .folded-tool-bar:hover { }
1912
+ html.dark .tool-color-read.folded-tool > .folded-tool-bar:hover { }
1896
1913
  .tool-color-read.folded-tool > .folded-tool-bar::before { color: #2563eb; }
1897
1914
  html.dark .tool-color-read.folded-tool > .folded-tool-bar::before { color: #60a5fa; }
1898
1915
  .tool-color-read .folded-tool-icon { color: #2563eb; }
@@ -1901,15 +1918,13 @@
1901
1918
  html.dark .tool-color-read .folded-tool-name { color: #93bbfd; }
1902
1919
  .tool-color-read .folded-tool-desc { color: #1d4ed8; }
1903
1920
  html.dark .tool-color-read .folded-tool-desc { color: #60a5fa; }
1904
- .tool-color-read { background: #eff6ff; }
1905
- html.dark .tool-color-read { background: #0c1929; }
1906
1921
  .tool-color-read > .folded-tool-body { border-top-color: #bfdbfe; }
1907
1922
  html.dark .tool-color-read > .folded-tool-body { border-top-color: #1e3a5f; }
1908
1923
 
1909
- .tool-color-write.folded-tool > .folded-tool-bar { background: #fef3c7; }
1910
- html.dark .tool-color-write.folded-tool > .folded-tool-bar { background: #422006; }
1911
- .tool-color-write.folded-tool > .folded-tool-bar:hover { background: #fde68a; }
1912
- html.dark .tool-color-write.folded-tool > .folded-tool-bar:hover { background: #78350f; }
1924
+ .tool-color-write.folded-tool > .folded-tool-bar { }
1925
+ html.dark .tool-color-write.folded-tool > .folded-tool-bar { }
1926
+ .tool-color-write.folded-tool > .folded-tool-bar:hover { }
1927
+ html.dark .tool-color-write.folded-tool > .folded-tool-bar:hover { }
1913
1928
  .tool-color-write.folded-tool > .folded-tool-bar::before { color: #d97706; }
1914
1929
  html.dark .tool-color-write.folded-tool > .folded-tool-bar::before { color: #fbbf24; }
1915
1930
  .tool-color-write .folded-tool-icon { color: #d97706; }
@@ -1918,15 +1933,13 @@
1918
1933
  html.dark .tool-color-write .folded-tool-name { color: #fcd34d; }
1919
1934
  .tool-color-write .folded-tool-desc { color: #b45309; }
1920
1935
  html.dark .tool-color-write .folded-tool-desc { color: #fbbf24; }
1921
- .tool-color-write { background: #fffbeb; }
1922
- html.dark .tool-color-write { background: #1c1507; }
1923
1936
  .tool-color-write > .folded-tool-body { border-top-color: #fde68a; }
1924
1937
  html.dark .tool-color-write > .folded-tool-body { border-top-color: #422006; }
1925
1938
 
1926
- .tool-color-edit.folded-tool > .folded-tool-bar { background: #ede9fe; }
1927
- html.dark .tool-color-edit.folded-tool > .folded-tool-bar { background: #2e1065; }
1928
- .tool-color-edit.folded-tool > .folded-tool-bar:hover { background: #ddd6fe; }
1929
- html.dark .tool-color-edit.folded-tool > .folded-tool-bar:hover { background: #4c1d95; }
1939
+ .tool-color-edit.folded-tool > .folded-tool-bar { }
1940
+ html.dark .tool-color-edit.folded-tool > .folded-tool-bar { }
1941
+ .tool-color-edit.folded-tool > .folded-tool-bar:hover { }
1942
+ html.dark .tool-color-edit.folded-tool > .folded-tool-bar:hover { }
1930
1943
  .tool-color-edit.folded-tool > .folded-tool-bar::before { color: #7c3aed; }
1931
1944
  html.dark .tool-color-edit.folded-tool > .folded-tool-bar::before { color: #a78bfa; }
1932
1945
  .tool-color-edit .folded-tool-icon { color: #7c3aed; }
@@ -1935,15 +1948,13 @@
1935
1948
  html.dark .tool-color-edit .folded-tool-name { color: #c4b5fd; }
1936
1949
  .tool-color-edit .folded-tool-desc { color: #6d28d9; }
1937
1950
  html.dark .tool-color-edit .folded-tool-desc { color: #a78bfa; }
1938
- .tool-color-edit { background: #f5f3ff; }
1939
- html.dark .tool-color-edit { background: #1a0a2e; }
1940
1951
  .tool-color-edit > .folded-tool-body { border-top-color: #ddd6fe; }
1941
1952
  html.dark .tool-color-edit > .folded-tool-body { border-top-color: #2e1065; }
1942
1953
 
1943
- .tool-color-bash.folded-tool > .folded-tool-bar { background: #cbd5e1; }
1944
- html.dark .tool-color-bash.folded-tool > .folded-tool-bar { background: #475569; }
1945
- .tool-color-bash.folded-tool > .folded-tool-bar:hover { background: #cbd5e1; }
1946
- html.dark .tool-color-bash.folded-tool > .folded-tool-bar:hover { background: #334155; }
1954
+ .tool-color-bash.folded-tool > .folded-tool-bar { }
1955
+ html.dark .tool-color-bash.folded-tool > .folded-tool-bar { }
1956
+ .tool-color-bash.folded-tool > .folded-tool-bar:hover { }
1957
+ html.dark .tool-color-bash.folded-tool > .folded-tool-bar:hover { }
1947
1958
  .tool-color-bash.folded-tool > .folded-tool-bar::before { color: #475569; }
1948
1959
  html.dark .tool-color-bash.folded-tool > .folded-tool-bar::before { color: #94a3b8; }
1949
1960
  .tool-color-bash .folded-tool-icon { color: #475569; }
@@ -1952,15 +1963,13 @@
1952
1963
  html.dark .tool-color-bash .folded-tool-name { color: #cbd5e1; }
1953
1964
  .tool-color-bash .folded-tool-desc { color: #475569; }
1954
1965
  html.dark .tool-color-bash .folded-tool-desc { color: #94a3b8; }
1955
- .tool-color-bash { background: #f8fafc; }
1956
- html.dark .tool-color-bash { background: #0f172a; }
1957
1966
  .tool-color-bash > .folded-tool-body { border-top-color: #cbd5e1; }
1958
1967
  html.dark .tool-color-bash > .folded-tool-body { border-top-color: #334155; }
1959
1968
 
1960
- .tool-color-glob.folded-tool > .folded-tool-bar { background: #d1fae5; }
1961
- html.dark .tool-color-glob.folded-tool > .folded-tool-bar { background: #064e3b; }
1962
- .tool-color-glob.folded-tool > .folded-tool-bar:hover { background: #a7f3d0; }
1963
- html.dark .tool-color-glob.folded-tool > .folded-tool-bar:hover { background: #065f46; }
1969
+ .tool-color-glob.folded-tool > .folded-tool-bar { }
1970
+ html.dark .tool-color-glob.folded-tool > .folded-tool-bar { }
1971
+ .tool-color-glob.folded-tool > .folded-tool-bar:hover { }
1972
+ html.dark .tool-color-glob.folded-tool > .folded-tool-bar:hover { }
1964
1973
  .tool-color-glob.folded-tool > .folded-tool-bar::before { color: #059669; }
1965
1974
  html.dark .tool-color-glob.folded-tool > .folded-tool-bar::before { color: #34d399; }
1966
1975
  .tool-color-glob .folded-tool-icon { color: #059669; }
@@ -1969,15 +1978,13 @@
1969
1978
  html.dark .tool-color-glob .folded-tool-name { color: #6ee7b7; }
1970
1979
  .tool-color-glob .folded-tool-desc { color: #047857; }
1971
1980
  html.dark .tool-color-glob .folded-tool-desc { color: #34d399; }
1972
- .tool-color-glob { background: #ecfdf5; }
1973
- html.dark .tool-color-glob { background: #022c22; }
1974
1981
  .tool-color-glob > .folded-tool-body { border-top-color: #a7f3d0; }
1975
1982
  html.dark .tool-color-glob > .folded-tool-body { border-top-color: #064e3b; }
1976
1983
 
1977
- .tool-color-grep.folded-tool > .folded-tool-bar { background: #ffe4e6; }
1978
- html.dark .tool-color-grep.folded-tool > .folded-tool-bar { background: #4c0519; }
1979
- .tool-color-grep.folded-tool > .folded-tool-bar:hover { background: #fecdd3; }
1980
- html.dark .tool-color-grep.folded-tool > .folded-tool-bar:hover { background: #881337; }
1984
+ .tool-color-grep.folded-tool > .folded-tool-bar { }
1985
+ html.dark .tool-color-grep.folded-tool > .folded-tool-bar { }
1986
+ .tool-color-grep.folded-tool > .folded-tool-bar:hover { }
1987
+ html.dark .tool-color-grep.folded-tool > .folded-tool-bar:hover { }
1981
1988
  .tool-color-grep.folded-tool > .folded-tool-bar::before { color: #e11d48; }
1982
1989
  html.dark .tool-color-grep.folded-tool > .folded-tool-bar::before { color: #fb7185; }
1983
1990
  .tool-color-grep .folded-tool-icon { color: #e11d48; }
@@ -1986,15 +1993,13 @@
1986
1993
  html.dark .tool-color-grep .folded-tool-name { color: #fda4af; }
1987
1994
  .tool-color-grep .folded-tool-desc { color: #be123c; }
1988
1995
  html.dark .tool-color-grep .folded-tool-desc { color: #fb7185; }
1989
- .tool-color-grep { background: #fff1f2; }
1990
- html.dark .tool-color-grep { background: #2a0a10; }
1991
1996
  .tool-color-grep > .folded-tool-body { border-top-color: #fecdd3; }
1992
1997
  html.dark .tool-color-grep > .folded-tool-body { border-top-color: #4c0519; }
1993
1998
 
1994
- .tool-color-web.folded-tool > .folded-tool-bar { background: #e0f2fe; }
1995
- html.dark .tool-color-web.folded-tool > .folded-tool-bar { background: #0c4a6e; }
1996
- .tool-color-web.folded-tool > .folded-tool-bar:hover { background: #bae6fd; }
1997
- html.dark .tool-color-web.folded-tool > .folded-tool-bar:hover { background: #075985; }
1999
+ .tool-color-web.folded-tool > .folded-tool-bar { }
2000
+ html.dark .tool-color-web.folded-tool > .folded-tool-bar { }
2001
+ .tool-color-web.folded-tool > .folded-tool-bar:hover { }
2002
+ html.dark .tool-color-web.folded-tool > .folded-tool-bar:hover { }
1998
2003
  .tool-color-web.folded-tool > .folded-tool-bar::before { color: #0284c7; }
1999
2004
  html.dark .tool-color-web.folded-tool > .folded-tool-bar::before { color: #38bdf8; }
2000
2005
  .tool-color-web .folded-tool-icon { color: #0284c7; }
@@ -2003,15 +2008,13 @@
2003
2008
  html.dark .tool-color-web .folded-tool-name { color: #7dd3fc; }
2004
2009
  .tool-color-web .folded-tool-desc { color: #0369a1; }
2005
2010
  html.dark .tool-color-web .folded-tool-desc { color: #38bdf8; }
2006
- .tool-color-web { background: #f0f9ff; }
2007
- html.dark .tool-color-web { background: #0a1929; }
2008
2011
  .tool-color-web > .folded-tool-body { border-top-color: #bae6fd; }
2009
2012
  html.dark .tool-color-web > .folded-tool-body { border-top-color: #0c4a6e; }
2010
2013
 
2011
- .tool-color-todo.folded-tool > .folded-tool-bar { background: #ffedd5; }
2012
- html.dark .tool-color-todo.folded-tool > .folded-tool-bar { background: #431407; }
2013
- .tool-color-todo.folded-tool > .folded-tool-bar:hover { background: #fed7aa; }
2014
- html.dark .tool-color-todo.folded-tool > .folded-tool-bar:hover { background: #7c2d12; }
2014
+ .tool-color-todo.folded-tool > .folded-tool-bar { }
2015
+ html.dark .tool-color-todo.folded-tool > .folded-tool-bar { }
2016
+ .tool-color-todo.folded-tool > .folded-tool-bar:hover { }
2017
+ html.dark .tool-color-todo.folded-tool > .folded-tool-bar:hover { }
2015
2018
  .tool-color-todo.folded-tool > .folded-tool-bar::before { color: #ea580c; }
2016
2019
  html.dark .tool-color-todo.folded-tool > .folded-tool-bar::before { color: #fb923c; }
2017
2020
  .tool-color-todo .folded-tool-icon { color: #ea580c; }
@@ -2020,15 +2023,13 @@
2020
2023
  html.dark .tool-color-todo .folded-tool-name { color: #fdba74; }
2021
2024
  .tool-color-todo .folded-tool-desc { color: #c2410c; }
2022
2025
  html.dark .tool-color-todo .folded-tool-desc { color: #fb923c; }
2023
- .tool-color-todo { background: #fff7ed; }
2024
- html.dark .tool-color-todo { background: #1c0f02; }
2025
2026
  .tool-color-todo > .folded-tool-body { border-top-color: #fed7aa; }
2026
2027
  html.dark .tool-color-todo > .folded-tool-body { border-top-color: #431407; }
2027
2028
 
2028
- .tool-color-task.folded-tool > .folded-tool-bar { background: #bfdbfe; }
2029
- html.dark .tool-color-task.folded-tool > .folded-tool-bar { background: #2563eb; }
2030
- .tool-color-task.folded-tool > .folded-tool-bar:hover { background: #c7d2fe; }
2031
- html.dark .tool-color-task.folded-tool > .folded-tool-bar:hover { background: #312e81; }
2029
+ .tool-color-task.folded-tool > .folded-tool-bar { }
2030
+ html.dark .tool-color-task.folded-tool > .folded-tool-bar { }
2031
+ .tool-color-task.folded-tool > .folded-tool-bar:hover { }
2032
+ html.dark .tool-color-task.folded-tool > .folded-tool-bar:hover { }
2032
2033
  .tool-color-task.folded-tool > .folded-tool-bar::before { color: #4f46e5; }
2033
2034
  html.dark .tool-color-task.folded-tool > .folded-tool-bar::before { color: #818cf8; }
2034
2035
  .tool-color-task .folded-tool-icon { color: #4f46e5; }
@@ -2037,15 +2038,13 @@
2037
2038
  html.dark .tool-color-task .folded-tool-name { color: #a5b4fc; }
2038
2039
  .tool-color-task .folded-tool-desc { color: #4338ca; }
2039
2040
  html.dark .tool-color-task .folded-tool-desc { color: #818cf8; }
2040
- .tool-color-task { background: #eef2ff; }
2041
- html.dark .tool-color-task { background: #0f0d29; }
2042
2041
  .tool-color-task > .folded-tool-body { border-top-color: #c7d2fe; }
2043
2042
  html.dark .tool-color-task > .folded-tool-body { border-top-color: #1e1b4b; }
2044
2043
 
2045
- .tool-color-default.folded-tool > .folded-tool-bar { background: #cffafe; }
2046
- html.dark .tool-color-default.folded-tool > .folded-tool-bar { background: #0e2a3a; }
2047
- .tool-color-default.folded-tool > .folded-tool-bar:hover { background: #a5f3fc; }
2048
- html.dark .tool-color-default.folded-tool > .folded-tool-bar:hover { background: #164e63; }
2044
+ .tool-color-default.folded-tool > .folded-tool-bar { }
2045
+ html.dark .tool-color-default.folded-tool > .folded-tool-bar { }
2046
+ .tool-color-default.folded-tool > .folded-tool-bar:hover { }
2047
+ html.dark .tool-color-default.folded-tool > .folded-tool-bar:hover { }
2049
2048
  .tool-color-default.folded-tool > .folded-tool-bar::before { color: #0891b2; }
2050
2049
  html.dark .tool-color-default.folded-tool > .folded-tool-bar::before { color: #22d3ee; }
2051
2050
  .tool-color-default .folded-tool-icon { color: #0891b2; }
@@ -2054,16 +2053,14 @@
2054
2053
  html.dark .tool-color-default .folded-tool-name { color: #67e8f9; }
2055
2054
  .tool-color-default .folded-tool-desc { color: #0e7490; }
2056
2055
  html.dark .tool-color-default .folded-tool-desc { color: #22d3ee; }
2057
- .tool-color-default { background: #ecfeff; }
2058
- html.dark .tool-color-default { background: #0c1a24; }
2059
2056
  .tool-color-default > .folded-tool-body { border-top-color: #a5f3fc; }
2060
2057
  html.dark .tool-color-default > .folded-tool-body { border-top-color: #164e63; }
2061
2058
 
2062
2059
  /* Execute - Purple */
2063
- .tool-color-execute.folded-tool > .folded-tool-bar { background: #e9d5ff; }
2064
- html.dark .tool-color-execute.folded-tool > .folded-tool-bar { background: #7c3aed; }
2065
- .tool-color-execute.folded-tool > .folded-tool-bar:hover { background: #e9d5ff; }
2066
- html.dark .tool-color-execute.folded-tool > .folded-tool-bar:hover { background: #4c1d95; }
2060
+ .tool-color-execute.folded-tool > .folded-tool-bar { }
2061
+ html.dark .tool-color-execute.folded-tool > .folded-tool-bar { }
2062
+ .tool-color-execute.folded-tool > .folded-tool-bar:hover { }
2063
+ html.dark .tool-color-execute.folded-tool > .folded-tool-bar:hover { }
2067
2064
  .tool-color-execute.folded-tool > .folded-tool-bar::before { color: #a855f7; }
2068
2065
  html.dark .tool-color-execute.folded-tool > .folded-tool-bar::before { color: #d8b4fe; }
2069
2066
  .tool-color-execute .folded-tool-icon { color: #a855f7; }
@@ -2072,16 +2069,14 @@
2072
2069
  html.dark .tool-color-execute .folded-tool-name { color: #e879f9; }
2073
2070
  .tool-color-execute .folded-tool-desc { color: #7e22ce; }
2074
2071
  html.dark .tool-color-execute .folded-tool-desc { color: #d8b4fe; }
2075
- .tool-color-execute { background: #faf5ff; }
2076
- html.dark .tool-color-execute { background: #1a0d2e; }
2077
2072
  .tool-color-execute > .folded-tool-body { border-top-color: #e9d5ff; }
2078
2073
  html.dark .tool-color-execute > .folded-tool-body { border-top-color: #4c1d95; }
2079
2074
 
2080
2075
  /* Sleep - Orange */
2081
- .tool-color-sleep.folded-tool > .folded-tool-bar { background: #fed7aa; }
2082
- html.dark .tool-color-sleep.folded-tool > .folded-tool-bar { background: #ea580c; }
2083
- .tool-color-sleep.folded-tool > .folded-tool-bar:hover { background: #fdba74; }
2084
- html.dark .tool-color-sleep.folded-tool > .folded-tool-bar:hover { background: #7c2d12; }
2076
+ .tool-color-sleep.folded-tool > .folded-tool-bar { }
2077
+ html.dark .tool-color-sleep.folded-tool > .folded-tool-bar { }
2078
+ .tool-color-sleep.folded-tool > .folded-tool-bar:hover { }
2079
+ html.dark .tool-color-sleep.folded-tool > .folded-tool-bar:hover { }
2085
2080
  .tool-color-sleep.folded-tool > .folded-tool-bar::before { color: #f97316; }
2086
2081
  html.dark .tool-color-sleep.folded-tool > .folded-tool-bar::before { color: #fb923c; }
2087
2082
  .tool-color-sleep .folded-tool-icon { color: #f97316; }
@@ -2090,16 +2085,14 @@
2090
2085
  html.dark .tool-color-sleep .folded-tool-name { color: #fed7aa; }
2091
2086
  .tool-color-sleep .folded-tool-desc { color: #b45309; }
2092
2087
  html.dark .tool-color-sleep .folded-tool-desc { color: #fb923c; }
2093
- .tool-color-sleep { background: #fff7ed; }
2094
- html.dark .tool-color-sleep { background: #1f1409; }
2095
2088
  .tool-color-sleep > .folded-tool-body { border-top-color: #fdba74; }
2096
2089
  html.dark .tool-color-sleep > .folded-tool-body { border-top-color: #7c2d12; }
2097
2090
 
2098
2091
  /* Search - Green */
2099
- .tool-color-search.folded-tool > .folded-tool-bar { background: #a7f3d0; }
2100
- html.dark .tool-color-search.folded-tool > .folded-tool-bar { background: #059669; }
2101
- .tool-color-search.folded-tool > .folded-tool-bar:hover { background: #bbf7d0; }
2102
- html.dark .tool-color-search.folded-tool > .folded-tool-bar:hover { background: #16a34a; }
2092
+ .tool-color-search.folded-tool > .folded-tool-bar { }
2093
+ html.dark .tool-color-search.folded-tool > .folded-tool-bar { }
2094
+ .tool-color-search.folded-tool > .folded-tool-bar:hover { }
2095
+ html.dark .tool-color-search.folded-tool > .folded-tool-bar:hover { }
2103
2096
  .tool-color-search.folded-tool > .folded-tool-bar::before { color: #16a34a; }
2104
2097
  html.dark .tool-color-search.folded-tool > .folded-tool-bar::before { color: #86efac; }
2105
2098
  .tool-color-search .folded-tool-icon { color: #16a34a; }
@@ -2108,16 +2101,14 @@
2108
2101
  html.dark .tool-color-search .folded-tool-name { color: #bbf7d0; }
2109
2102
  .tool-color-search .folded-tool-desc { color: #166534; }
2110
2103
  html.dark .tool-color-search .folded-tool-desc { color: #86efac; }
2111
- .tool-color-search { background: #f0fdf4; }
2112
- html.dark .tool-color-search { background: #0a1c0e; }
2113
2104
  .tool-color-search > .folded-tool-body { border-top-color: #bbf7d0; }
2114
2105
  html.dark .tool-color-search > .folded-tool-body { border-top-color: #16a34a; }
2115
2106
 
2116
2107
  /* Skill - Yellow/Amber */
2117
- .tool-color-skill.folded-tool > .folded-tool-bar { background: #d9f99d; }
2118
- html.dark .tool-color-skill.folded-tool > .folded-tool-bar { background: #65a30d; }
2119
- .tool-color-skill.folded-tool > .folded-tool-bar:hover { background: #fde68a; }
2120
- html.dark .tool-color-skill.folded-tool > .folded-tool-bar:hover { background: #78350f; }
2108
+ .tool-color-skill.folded-tool > .folded-tool-bar { }
2109
+ html.dark .tool-color-skill.folded-tool > .folded-tool-bar { }
2110
+ .tool-color-skill.folded-tool > .folded-tool-bar:hover { }
2111
+ html.dark .tool-color-skill.folded-tool > .folded-tool-bar:hover { }
2121
2112
  .tool-color-skill.folded-tool > .folded-tool-bar::before { color: #d97706; }
2122
2113
  html.dark .tool-color-skill.folded-tool > .folded-tool-bar::before { color: #fbbf24; }
2123
2114
  .tool-color-skill .folded-tool-icon { color: #d97706; }
@@ -2126,45 +2117,35 @@
2126
2117
  html.dark .tool-color-skill .folded-tool-name { color: #fcd34d; }
2127
2118
  .tool-color-skill .folded-tool-desc { color: #b45309; }
2128
2119
  html.dark .tool-color-skill .folded-tool-desc { color: #fbbf24; }
2129
- .tool-color-skill { background: #fffbeb; }
2130
- html.dark .tool-color-skill { background: #1c1507; }
2131
2120
  .tool-color-skill > .folded-tool-body { border-top-color: #fde68a; }
2132
2121
  html.dark .tool-color-skill > .folded-tool-body { border-top-color: #78350f; }
2133
2122
 
2134
- .block-type-tool_result { background: #f3f4f6; }
2135
- html.dark .block-type-tool_result { background: #1f2937; }
2136
- .block-type-tool_result .tool-result-status { background: #e5e7eb; }
2137
- html.dark .block-type-tool_result .tool-result-status { background: #374151; }
2123
+ .block-type-tool_result .tool-result-status { }
2124
+ html.dark .block-type-tool_result .tool-result-status { }
2138
2125
  .block-type-tool_result .folded-tool-icon { color: #16a34a; }
2139
2126
  html.dark .block-type-tool_result .folded-tool-icon { color: #4ade80; }
2140
2127
  .block-type-tool_result .folded-tool-name { color: #374151; }
2141
2128
  html.dark .block-type-tool_result .folded-tool-name { color: #d1d5db; }
2142
2129
  .block-type-tool_result > .folded-tool-body { border-top-color: #d1d5db; }
2143
2130
  html.dark .block-type-tool_result > .folded-tool-body { border-top-color: #4b5563; }
2144
- .block-type-tool_result.tool-result-error { background: #f3f4f6; }
2145
- html.dark .block-type-tool_result.tool-result-error { background: #1f2937; }
2146
- .block-type-tool_result.tool-result-error .tool-result-status { background: #e5e7eb; }
2147
- html.dark .block-type-tool_result.tool-result-error .tool-result-status { background: #374151; }
2131
+ .block-type-tool_result.tool-result-error { }
2132
+ html.dark .block-type-tool_result.tool-result-error { }
2133
+ .block-type-tool_result.tool-result-error .tool-result-status { }
2134
+ html.dark .block-type-tool_result.tool-result-error .tool-result-status { }
2148
2135
  .block-type-tool_result.tool-result-error .folded-tool-icon { color: #dc2626; }
2149
2136
  html.dark .block-type-tool_result.tool-result-error .folded-tool-icon { color: #f87171; }
2150
2137
  .block-type-tool_result.tool-result-error .folded-tool-name { color: #374151; }
2151
2138
  html.dark .block-type-tool_result.tool-result-error .folded-tool-name { color: #d1d5db; }
2152
2139
 
2153
- .block-type-code { background: #1e293b; }
2154
- html.dark .block-type-code { background: #0f172a; }
2155
2140
 
2156
- .block-type-thinking { background: #f5f3ff; }
2157
- html.dark .block-type-thinking { background: #1e1033; }
2158
2141
 
2159
- .block-type-bash { background: #fffbeb; }
2160
- html.dark .block-type-bash { background: #1c1507; }
2161
2142
 
2162
- .block-type-system { background: #eef2ff; }
2163
- html.dark .block-type-system { background: #15103a; }
2164
- .block-type-system.folded-tool > .folded-tool-bar { background: #e0e7ff; }
2165
- html.dark .block-type-system.folded-tool > .folded-tool-bar { background: #1e1b4b; }
2166
- .block-type-system.folded-tool > .folded-tool-bar:hover { background: #c7d2fe; }
2167
- html.dark .block-type-system.folded-tool > .folded-tool-bar:hover { background: #312e81; }
2143
+ .block-type-system { }
2144
+ html.dark .block-type-system { }
2145
+ .block-type-system.folded-tool > .folded-tool-bar { }
2146
+ html.dark .block-type-system.folded-tool > .folded-tool-bar { }
2147
+ .block-type-system.folded-tool > .folded-tool-bar:hover { }
2148
+ html.dark .block-type-system.folded-tool > .folded-tool-bar:hover { }
2168
2149
  .block-type-system.folded-tool > .folded-tool-bar::before { color: #6366f1; }
2169
2150
  html.dark .block-type-system.folded-tool > .folded-tool-bar::before { color: #a5b4fc; }
2170
2151
  .block-type-system .folded-tool-icon { color: #6366f1; }
@@ -2176,12 +2157,12 @@
2176
2157
  .block-type-system > .folded-tool-body { border-top-color: #c7d2fe; }
2177
2158
  html.dark .block-type-system > .folded-tool-body { border-top-color: #3730a3; }
2178
2159
 
2179
- .block-type-result { background: #f0fdf4; }
2180
- html.dark .block-type-result { background: #0a1f0f; }
2181
- .block-type-result.folded-tool > .folded-tool-bar { background: #dcfce7; }
2182
- html.dark .block-type-result.folded-tool > .folded-tool-bar { background: #0f2b1a; }
2183
- .block-type-result.folded-tool > .folded-tool-bar:hover { background: #bbf7d0; }
2184
- html.dark .block-type-result.folded-tool > .folded-tool-bar:hover { background: #14532d; }
2160
+ .block-type-result { }
2161
+ html.dark .block-type-result { }
2162
+ .block-type-result.folded-tool > .folded-tool-bar { }
2163
+ html.dark .block-type-result.folded-tool > .folded-tool-bar { }
2164
+ .block-type-result.folded-tool > .folded-tool-bar:hover { }
2165
+ html.dark .block-type-result.folded-tool > .folded-tool-bar:hover { }
2185
2166
  .block-type-result.folded-tool > .folded-tool-bar::before { color: #16a34a; }
2186
2167
  html.dark .block-type-result.folded-tool > .folded-tool-bar::before { color: #4ade80; }
2187
2168
  .block-type-result .folded-tool-icon { color: #16a34a; }
@@ -2193,12 +2174,12 @@
2193
2174
  .block-type-result > .folded-tool-body { border-top-color: #bbf7d0; }
2194
2175
  html.dark .block-type-result > .folded-tool-body { border-top-color: #166534; }
2195
2176
 
2196
- .block-type-error { background: #fef2f2; }
2197
- html.dark .block-type-error { background: #1c0f0f; }
2198
- .block-type-error.folded-tool > .folded-tool-bar { background: #fee2e2; }
2199
- html.dark .block-type-error.folded-tool > .folded-tool-bar { background: #2c1010; }
2200
- .block-type-error.folded-tool > .folded-tool-bar:hover { background: #fecaca; }
2201
- html.dark .block-type-error.folded-tool > .folded-tool-bar:hover { background: #451a1a; }
2177
+ .block-type-error { }
2178
+ html.dark .block-type-error { }
2179
+ .block-type-error.folded-tool > .folded-tool-bar { }
2180
+ html.dark .block-type-error.folded-tool > .folded-tool-bar { }
2181
+ .block-type-error.folded-tool > .folded-tool-bar:hover { }
2182
+ html.dark .block-type-error.folded-tool > .folded-tool-bar:hover { }
2202
2183
  .block-type-error.folded-tool > .folded-tool-bar::before { color: #ef4444; }
2203
2184
  html.dark .block-type-error.folded-tool > .folded-tool-bar::before { color: #f87171; }
2204
2185
  .block-type-error .folded-tool-icon { color: #ef4444; }
@@ -2210,23 +2191,11 @@
2210
2191
  .block-type-error > .folded-tool-body { border-top-color: #fecaca; }
2211
2192
  html.dark .block-type-error > .folded-tool-body { border-top-color: #7f1d1d; }
2212
2193
 
2213
- .block-type-image { background: #fdf2f8; }
2214
- html.dark .block-type-image { background: #1f0a1a; }
2215
2194
 
2216
- .block-type-plan { background: #eff6ff; }
2217
- html.dark .block-type-plan { background: #0c1929; }
2218
2195
 
2219
- .block-type-usage { background: #f9fafb; }
2220
- html.dark .block-type-usage { background: #1f2937; }
2221
2196
 
2222
- .block-type-premature { background: #fffbeb; }
2223
- html.dark .block-type-premature { background: #1c1507; }
2224
2197
 
2225
- .block-type-tool_status { background: #f0f9ff; }
2226
- html.dark .block-type-tool_status { background: #0c1929; }
2227
2198
 
2228
- .block-type-generic { background: #f9fafb; }
2229
- html.dark .block-type-generic { background: #1f2937; }
2230
2199
 
2231
2200
  /* --- Code block header (non-collapsible) --- */
2232
2201
  .code-block-header {
@@ -3216,6 +3185,11 @@
3216
3185
  <path d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"/>
3217
3186
  </svg>
3218
3187
  </button>
3188
+ <button class="steer-btn" id="steerBtn" title="Steer running agent with message" aria-label="Steer agent">
3189
+ <svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18">
3190
+ <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z"/>
3191
+ </svg>
3192
+ </button>
3219
3193
  <button class="stop-btn" id="stopBtn" title="Stop running agent (emergency)" aria-label="Stop agent">
3220
3194
  <svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18">
3221
3195
  <path d="M6 6h12v12H6z"/>
@@ -458,6 +458,7 @@ class AgentGUIClient {
458
458
 
459
459
  this.ui.stopButton = document.getElementById('stopBtn');
460
460
  this.ui.injectButton = document.getElementById('injectBtn');
461
+ this.ui.steerButton = document.getElementById('steerBtn');
461
462
 
462
463
  if (this.ui.stopButton) {
463
464
  this.ui.stopButton.addEventListener('click', async () => {
@@ -485,6 +486,28 @@ class AgentGUIClient {
485
486
  });
486
487
  }
487
488
 
489
+ if (this.ui.steerButton) {
490
+ this.ui.steerButton.addEventListener('click', async () => {
491
+ if (!this.state.currentConversation) return;
492
+ const message = this.ui.messageInput?.value || '';
493
+ if (!message.trim()) {
494
+ this.showError('Please enter a message to steer');
495
+ return;
496
+ }
497
+ try {
498
+ const data = await window.wsClient.rpc('conv.steer', { id: this.state.currentConversation.id, content: message });
499
+ console.log('Steer response:', data);
500
+ if (this.ui.messageInput) {
501
+ this.ui.messageInput.value = '';
502
+ this.ui.messageInput.style.height = 'auto';
503
+ }
504
+ } catch (err) {
505
+ console.error('Failed to steer:', err);
506
+ this.showError('Failed to steer: ' + err.message);
507
+ }
508
+ });
509
+ }
510
+
488
511
  if (this.ui.messageInput) {
489
512
  this.ui.messageInput.addEventListener('keydown', (e) => {
490
513
  if (e.key === 'Enter' && e.ctrlKey) {
@@ -708,9 +731,10 @@ class AgentGUIClient {
708
731
  return;
709
732
  }
710
733
 
711
- // Show stop and inject buttons when streaming starts for current conversation
734
+ // Show stop, steer, and inject buttons when streaming starts for current conversation
712
735
  if (this.ui.stopButton) this.ui.stopButton.classList.add('visible');
713
736
  if (this.ui.injectButton) this.ui.injectButton.classList.add('visible');
737
+ if (this.ui.steerButton) this.ui.steerButton.classList.add('visible');
714
738
  if (this.ui.sendButton) this.ui.sendButton.style.display = 'none';
715
739
 
716
740
  this.state.streamingConversations.set(data.conversationId, true);
@@ -937,9 +961,10 @@ class AgentGUIClient {
937
961
  console.error('Streaming error:', data);
938
962
  this._clearThinkingCountdown();
939
963
 
940
- // Hide stop and inject buttons on error
964
+ // Hide stop, steer, and inject buttons on error
941
965
  if (this.ui.stopButton) this.ui.stopButton.classList.remove('visible');
942
966
  if (this.ui.injectButton) this.ui.injectButton.classList.remove('visible');
967
+ if (this.ui.steerButton) this.ui.steerButton.classList.remove('visible');
943
968
  if (this.ui.sendButton) this.ui.sendButton.style.display = '';
944
969
 
945
970
  const conversationId = data.conversationId || this.state.currentSession?.conversationId;
@@ -988,9 +1013,10 @@ class AgentGUIClient {
988
1013
  console.log('Streaming completed:', data);
989
1014
  this._clearThinkingCountdown();
990
1015
 
991
- // Hide stop and inject buttons when streaming completes
1016
+ // Hide stop, steer, and inject buttons when streaming completes
992
1017
  if (this.ui.stopButton) this.ui.stopButton.classList.remove('visible');
993
1018
  if (this.ui.injectButton) this.ui.injectButton.classList.remove('visible');
1019
+ if (this.ui.steerButton) this.ui.steerButton.classList.remove('visible');
994
1020
  if (this.ui.sendButton) this.ui.sendButton.style.display = '';
995
1021
 
996
1022
  const conversationId = data.conversationId || this.state.currentSession?.conversationId;
@@ -2437,6 +2463,7 @@ class AgentGUIClient {
2437
2463
 
2438
2464
  if (this.ui.stopButton) this.ui.stopButton.classList.remove('visible');
2439
2465
  if (this.ui.injectButton) this.ui.injectButton.classList.remove('visible');
2466
+ if (this.ui.steerButton) this.ui.steerButton.classList.remove('visible');
2440
2467
  if (this.ui.sendButton) this.ui.sendButton.style.display = '';
2441
2468
 
2442
2469
  var prevId = this.state.currentConversation?.id;