@symerian/symi 2.0.10 → 2.0.12

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 (32) hide show
  1. package/dist/{audio-preflight-B8ffbICW.js → audio-preflight-Cq4C-m27.js} +4 -4
  2. package/dist/{audio-preflight-DRQD_nt1.js → audio-preflight-DbUFnPX1.js} +4 -4
  3. package/dist/build-info.json +3 -3
  4. package/dist/bundled/boot-md/handler.js +6 -6
  5. package/dist/bundled/session-memory/handler.js +6 -6
  6. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  7. package/dist/{chrome-LmEyZdbC.js → chrome-BATLK3yK.js} +7 -7
  8. package/dist/{chrome-B_zrSLce.js → chrome-h6BnL8Lp.js} +7 -7
  9. package/dist/control-ui/css/style.css +199 -0
  10. package/dist/control-ui/index.html +19 -0
  11. package/dist/control-ui/js/app.js +34 -0
  12. package/dist/control-ui/js/render.js +217 -1
  13. package/dist/control-ui/vendor/highlight.min.js +2518 -0
  14. package/dist/control-ui/vendor/marked.min.js +69 -0
  15. package/dist/daemon-cli.js +6 -6
  16. package/dist/{deliver-CkjSfucB.js → deliver-CZF9f8aC.js} +1 -1
  17. package/dist/{deliver-B3UoBZdC.js → deliver-DD3gs9SF.js} +1 -1
  18. package/dist/extensionAPI.js +6 -6
  19. package/dist/{image-CSeAnozE.js → image-DOnOTocl.js} +1 -1
  20. package/dist/{image-RFofsrof.js → image-RLbZ3RUn.js} +1 -1
  21. package/dist/llm-slug-generator.js +6 -6
  22. package/dist/{pi-embedded-9wEA_0mu.js → pi-embedded-BvCoZBNg.js} +16 -16
  23. package/dist/{pi-embedded-BjzaB3CT.js → pi-embedded-ZzUH4ioO.js} +16 -16
  24. package/dist/{pi-embedded-helpers-BmYZe8o8.js → pi-embedded-helpers--yFTAWwW.js} +4 -4
  25. package/dist/{pi-embedded-helpers-kB5lBgXk.js → pi-embedded-helpers-x8rJur4F.js} +4 -4
  26. package/dist/{pw-ai-CAkn033M.js → pw-ai-CCt1nIO-.js} +1 -1
  27. package/dist/{pw-ai-s-d46DCX.js → pw-ai-C_C5as1t.js} +1 -1
  28. package/dist/{runner-DOvsNiYz.js → runner-DjHRFXSI.js} +1 -1
  29. package/dist/{runner-CJJY2r19.js → runner-uDZlTCm2.js} +1 -1
  30. package/dist/{web-BKQnrqo-.js → web-0bP0TLM2.js} +6 -6
  31. package/dist/{web-CAnxcgBD.js → web-G0LUda_q.js} +6 -6
  32. package/package.json +1 -1
@@ -12,10 +12,10 @@ import "./accounts-8zZqL37v.js";
12
12
  import "./image-ops-ByaQt43P.js";
13
13
  import "./pi-model-discovery-j5tVLINv.js";
14
14
  import "./message-channel-BQINJQIT.js";
15
- import "./pi-embedded-helpers-BmYZe8o8.js";
15
+ import "./pi-embedded-helpers--yFTAWwW.js";
16
16
  import "./config-BjGo9GnL.js";
17
17
  import "./manifest-registry-D-mTF1cj.js";
18
- import "./chrome-B_zrSLce.js";
18
+ import "./chrome-h6BnL8Lp.js";
19
19
  import "./skills-BNpGMnp-.js";
20
20
  import "./redact-1NGYV_8p.js";
21
21
  import "./errors-CPfngF0S.js";
@@ -25,10 +25,10 @@ import "./thinking-W85Rb32m.js";
25
25
  import "./accounts-DImOt9jX.js";
26
26
  import "./paths-DkMamAQ-.js";
27
27
  import "./tool-images-ChC2CXaN.js";
28
- import "./image-CSeAnozE.js";
28
+ import "./image-DOnOTocl.js";
29
29
  import "./gemini-auth-K6vg8B5c.js";
30
30
  import "./local-roots-CC8jiKDk.js";
31
- import { a as resolveMediaAttachmentLocalRoots, n as createMediaAttachmentCache, o as runCapability, r as normalizeMediaAttachments, t as buildProviderRegistry, u as isAudioAttachment } from "./runner-CJJY2r19.js";
31
+ import { a as resolveMediaAttachmentLocalRoots, n as createMediaAttachmentCache, o as runCapability, r as normalizeMediaAttachments, t as buildProviderRegistry, u as isAudioAttachment } from "./runner-uDZlTCm2.js";
32
32
 
33
33
  //#region src/media-understanding/audio-preflight.ts
34
34
  /**
@@ -14,10 +14,10 @@ import "./model-auth-CeL58m55.js";
14
14
  import "./github-copilot-token-C_qUP7p5.js";
15
15
  import "./pi-model-discovery-DaNAekda.js";
16
16
  import "./message-channel-Dz5lr5b0.js";
17
- import "./pi-embedded-helpers-kB5lBgXk.js";
17
+ import "./pi-embedded-helpers-x8rJur4F.js";
18
18
  import "./config-DM0K7qC1.js";
19
19
  import "./manifest-registry-D0IQ3WuX.js";
20
- import "./chrome-LmEyZdbC.js";
20
+ import "./chrome-BATLK3yK.js";
21
21
  import "./frontmatter-C_bv_0P8.js";
22
22
  import "./skills-BFekKL7i.js";
23
23
  import "./redact-jSxx6Ep2.js";
@@ -28,10 +28,10 @@ import "./thinking-CdlENGRW.js";
28
28
  import "./accounts-qtxJ-6em.js";
29
29
  import "./paths-DLyHUt31.js";
30
30
  import "./tool-images-DXB7tqWi.js";
31
- import "./image-RFofsrof.js";
31
+ import "./image-RLbZ3RUn.js";
32
32
  import "./gemini-auth-7AWT6JXV.js";
33
33
  import "./local-roots-DMwIh5cS.js";
34
- import { a as resolveMediaAttachmentLocalRoots, n as createMediaAttachmentCache, o as runCapability, r as normalizeMediaAttachments, t as buildProviderRegistry, u as isAudioAttachment } from "./runner-DOvsNiYz.js";
34
+ import { a as resolveMediaAttachmentLocalRoots, n as createMediaAttachmentCache, o as runCapability, r as normalizeMediaAttachments, t as buildProviderRegistry, u as isAudioAttachment } from "./runner-DjHRFXSI.js";
35
35
 
36
36
  //#region src/media-understanding/audio-preflight.ts
37
37
  /**
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.0.10",
3
- "commit": "4b89239a49089e430c47f05346a6e37b09618fb6",
4
- "builtAt": "2026-03-09T00:25:15.389Z"
2
+ "version": "2.0.12",
3
+ "commit": "836b23c66e3fc139ac5c7db44a43adea9ec35b22",
4
+ "builtAt": "2026-03-09T16:39:28.949Z"
5
5
  }
@@ -5,7 +5,7 @@ import { s as resolveAgentWorkspaceDir, t as listAgentIds } from "../../agent-sc
5
5
  import { r as defaultRuntime, t as createSubsystemLogger } from "../../subsystem-Bs9YvKLa.js";
6
6
  import "../../workspace-wAaHI8-5.js";
7
7
  import { n as SILENT_REPLY_TOKEN } from "../../tokens-H1H1LiSQ.js";
8
- import { a as createDefaultDeps, i as agentCommand } from "../../pi-embedded-BjzaB3CT.js";
8
+ import { a as createDefaultDeps, i as agentCommand } from "../../pi-embedded-ZzUH4ioO.js";
9
9
  import "../../plugins-DQYI3Fr-.js";
10
10
  import "../../accounts-tNElYrCH.js";
11
11
  import "../../boolean-B8-BqKGQ.js";
@@ -13,7 +13,7 @@ import "../../command-format-BaxDnULz.js";
13
13
  import "../../bindings-B7Ke6LJi.js";
14
14
  import "../../send-CHOArYFe.js";
15
15
  import "../../send-D3M6pMr5.js";
16
- import "../../deliver-B3UoBZdC.js";
16
+ import "../../deliver-DD3gs9SF.js";
17
17
  import "../../diagnostic-CI0kRQkt.js";
18
18
  import "../../diagnostic-session-state-Bxo4UHOL.js";
19
19
  import "../../accounts-CWktKM8a.js";
@@ -23,10 +23,10 @@ import "../../model-auth-CeL58m55.js";
23
23
  import "../../github-copilot-token-C_qUP7p5.js";
24
24
  import "../../pi-model-discovery-DaNAekda.js";
25
25
  import "../../message-channel-Dz5lr5b0.js";
26
- import { H as loadSessionStore, K as updateSessionStore, xt as resolveMainSessionKey, yt as resolveAgentMainSessionKey } from "../../pi-embedded-helpers-kB5lBgXk.js";
26
+ import { H as loadSessionStore, K as updateSessionStore, xt as resolveMainSessionKey, yt as resolveAgentMainSessionKey } from "../../pi-embedded-helpers-x8rJur4F.js";
27
27
  import "../../config-DM0K7qC1.js";
28
28
  import "../../manifest-registry-D0IQ3WuX.js";
29
- import "../../chrome-LmEyZdbC.js";
29
+ import "../../chrome-BATLK3yK.js";
30
30
  import "../../frontmatter-C_bv_0P8.js";
31
31
  import "../../skills-BFekKL7i.js";
32
32
  import "../../redact-jSxx6Ep2.js";
@@ -37,7 +37,7 @@ import "../../thinking-CdlENGRW.js";
37
37
  import "../../accounts-qtxJ-6em.js";
38
38
  import { s as resolveStorePath } from "../../paths-DLyHUt31.js";
39
39
  import "../../tool-images-DXB7tqWi.js";
40
- import "../../image-RFofsrof.js";
40
+ import "../../image-RLbZ3RUn.js";
41
41
  import "../../reply-prefix-XlyuyChD.js";
42
42
  import "../../manager-B5EXdBQV.js";
43
43
  import "../../gemini-auth-7AWT6JXV.js";
@@ -51,7 +51,7 @@ import "../../ir-DccrnjsE.js";
51
51
  import "../../render-CDCvpfhh.js";
52
52
  import "../../commands-registry-C3C4Rv3O.js";
53
53
  import "../../skill-commands-B64uavY9.js";
54
- import "../../runner-DOvsNiYz.js";
54
+ import "../../runner-DjHRFXSI.js";
55
55
  import "../../fetch-Bso4i15F.js";
56
56
  import "../../channel-activity-CsM_hJ_s.js";
57
57
  import "../../tables-DuZspiBu.js";
@@ -5,7 +5,7 @@ import { s as resolveAgentWorkspaceDir } from "../../agent-scope-BxoUQqgM.js";
5
5
  import { t as createSubsystemLogger } from "../../subsystem-Bs9YvKLa.js";
6
6
  import "../../workspace-wAaHI8-5.js";
7
7
  import "../../tokens-H1H1LiSQ.js";
8
- import "../../pi-embedded-BjzaB3CT.js";
8
+ import "../../pi-embedded-ZzUH4ioO.js";
9
9
  import "../../plugins-DQYI3Fr-.js";
10
10
  import "../../accounts-tNElYrCH.js";
11
11
  import "../../boolean-B8-BqKGQ.js";
@@ -13,7 +13,7 @@ import "../../command-format-BaxDnULz.js";
13
13
  import "../../bindings-B7Ke6LJi.js";
14
14
  import "../../send-CHOArYFe.js";
15
15
  import "../../send-D3M6pMr5.js";
16
- import "../../deliver-B3UoBZdC.js";
16
+ import "../../deliver-DD3gs9SF.js";
17
17
  import "../../diagnostic-CI0kRQkt.js";
18
18
  import "../../diagnostic-session-state-Bxo4UHOL.js";
19
19
  import "../../accounts-CWktKM8a.js";
@@ -23,10 +23,10 @@ import "../../model-auth-CeL58m55.js";
23
23
  import "../../github-copilot-token-C_qUP7p5.js";
24
24
  import "../../pi-model-discovery-DaNAekda.js";
25
25
  import "../../message-channel-Dz5lr5b0.js";
26
- import { ct as hasInterSessionUserProvenance } from "../../pi-embedded-helpers-kB5lBgXk.js";
26
+ import { ct as hasInterSessionUserProvenance } from "../../pi-embedded-helpers-x8rJur4F.js";
27
27
  import "../../config-DM0K7qC1.js";
28
28
  import "../../manifest-registry-D0IQ3WuX.js";
29
- import "../../chrome-LmEyZdbC.js";
29
+ import "../../chrome-BATLK3yK.js";
30
30
  import "../../frontmatter-C_bv_0P8.js";
31
31
  import "../../skills-BFekKL7i.js";
32
32
  import "../../redact-jSxx6Ep2.js";
@@ -37,7 +37,7 @@ import "../../thinking-CdlENGRW.js";
37
37
  import "../../accounts-qtxJ-6em.js";
38
38
  import "../../paths-DLyHUt31.js";
39
39
  import "../../tool-images-DXB7tqWi.js";
40
- import "../../image-RFofsrof.js";
40
+ import "../../image-RLbZ3RUn.js";
41
41
  import "../../reply-prefix-XlyuyChD.js";
42
42
  import "../../manager-B5EXdBQV.js";
43
43
  import "../../gemini-auth-7AWT6JXV.js";
@@ -51,7 +51,7 @@ import "../../ir-DccrnjsE.js";
51
51
  import "../../render-CDCvpfhh.js";
52
52
  import "../../commands-registry-C3C4Rv3O.js";
53
53
  import "../../skill-commands-B64uavY9.js";
54
- import "../../runner-DOvsNiYz.js";
54
+ import "../../runner-DjHRFXSI.js";
55
55
  import "../../fetch-Bso4i15F.js";
56
56
  import "../../channel-activity-CsM_hJ_s.js";
57
57
  import "../../tables-DuZspiBu.js";
@@ -1 +1 @@
1
- 47a931667acd62f8951ea76d786d695990d0e3e45d9224285237d7b5eda0f7eb
1
+ 2fb661e40a01af0991c00286ee43d4cbc9c8f6b1cc4459500dd5826143402576
@@ -10,7 +10,7 @@ import fs$1 from "node:fs";
10
10
  import { execFileSync, spawn } from "node:child_process";
11
11
  import net from "node:net";
12
12
  import { createServer } from "node:http";
13
- import WebSocket, { WebSocketServer } from "ws";
13
+ import WebSocket$1, { WebSocketServer } from "ws";
14
14
  import { Buffer as Buffer$1 } from "node:buffer";
15
15
 
16
16
  //#region src/browser/constants.ts
@@ -178,7 +178,7 @@ async function ensureChromeExtensionRelayServer(opts) {
178
178
  let nextExtensionId = 1;
179
179
  const sendToExtension = async (payload) => {
180
180
  const ws = extensionWs;
181
- if (!ws || ws.readyState !== WebSocket.OPEN) throw new Error("Chrome extension not connected");
181
+ if (!ws || ws.readyState !== WebSocket$1.OPEN) throw new Error("Chrome extension not connected");
182
182
  ws.send(JSON.stringify(payload));
183
183
  return await new Promise((resolve, reject) => {
184
184
  const timer = setTimeout(() => {
@@ -195,12 +195,12 @@ async function ensureChromeExtensionRelayServer(opts) {
195
195
  const broadcastToCdpClients = (evt) => {
196
196
  const msg = JSON.stringify(evt);
197
197
  for (const ws of cdpClients) {
198
- if (ws.readyState !== WebSocket.OPEN) continue;
198
+ if (ws.readyState !== WebSocket$1.OPEN) continue;
199
199
  ws.send(msg);
200
200
  }
201
201
  };
202
202
  const sendResponseToCdp = (ws, res) => {
203
- if (ws.readyState !== WebSocket.OPEN) return;
203
+ if (ws.readyState !== WebSocket$1.OPEN) return;
204
204
  ws.send(JSON.stringify(res));
205
205
  };
206
206
  const ensureTargetEventsForClient = (ws, mode) => {
@@ -425,7 +425,7 @@ async function ensureChromeExtensionRelayServer(opts) {
425
425
  wssExtension.on("connection", (ws) => {
426
426
  extensionWs = ws;
427
427
  const ping = setInterval(() => {
428
- if (ws.readyState !== WebSocket.OPEN) return;
428
+ if (ws.readyState !== WebSocket$1.OPEN) return;
429
429
  ws.send(JSON.stringify({ method: "ping" }));
430
430
  }, 5e3);
431
431
  ws.on("message", (data) => {
@@ -743,7 +743,7 @@ async function fetchOk(url, timeoutMs = 1500, init) {
743
743
  }
744
744
  async function withCdpSocket(wsUrl, fn, opts) {
745
745
  const headers = getHeadersWithAuth(wsUrl, opts?.headers ?? {});
746
- const ws = new WebSocket(wsUrl, {
746
+ const ws = new WebSocket$1(wsUrl, {
747
747
  handshakeTimeout: typeof opts?.handshakeTimeoutMs === "number" && Number.isFinite(opts.handshakeTimeoutMs) ? Math.max(1, Math.floor(opts.handshakeTimeoutMs)) : 5e3,
748
748
  ...Object.keys(headers).length ? { headers } : {}
749
749
  });
@@ -1637,7 +1637,7 @@ async function getChromeWebSocketUrl(cdpUrl, timeoutMs = 500) {
1637
1637
  async function canOpenWebSocket(wsUrl, timeoutMs = 800) {
1638
1638
  return await new Promise((resolve) => {
1639
1639
  const headers = getHeadersWithAuth(wsUrl);
1640
- const ws = new WebSocket(wsUrl, {
1640
+ const ws = new WebSocket$1(wsUrl, {
1641
1641
  handshakeTimeout: timeoutMs,
1642
1642
  ...Object.keys(headers).length ? { headers } : {}
1643
1643
  });
@@ -10,7 +10,7 @@ import fs$1 from "node:fs/promises";
10
10
  import { execFileSync, spawn } from "node:child_process";
11
11
  import net from "node:net";
12
12
  import { createServer } from "node:http";
13
- import WebSocket, { WebSocketServer } from "ws";
13
+ import WebSocket$1, { WebSocketServer } from "ws";
14
14
  import { Buffer as Buffer$1 } from "node:buffer";
15
15
 
16
16
  //#region src/browser/constants.ts
@@ -178,7 +178,7 @@ async function ensureChromeExtensionRelayServer(opts) {
178
178
  let nextExtensionId = 1;
179
179
  const sendToExtension = async (payload) => {
180
180
  const ws = extensionWs;
181
- if (!ws || ws.readyState !== WebSocket.OPEN) throw new Error("Chrome extension not connected");
181
+ if (!ws || ws.readyState !== WebSocket$1.OPEN) throw new Error("Chrome extension not connected");
182
182
  ws.send(JSON.stringify(payload));
183
183
  return await new Promise((resolve, reject) => {
184
184
  const timer = setTimeout(() => {
@@ -195,12 +195,12 @@ async function ensureChromeExtensionRelayServer(opts) {
195
195
  const broadcastToCdpClients = (evt) => {
196
196
  const msg = JSON.stringify(evt);
197
197
  for (const ws of cdpClients) {
198
- if (ws.readyState !== WebSocket.OPEN) continue;
198
+ if (ws.readyState !== WebSocket$1.OPEN) continue;
199
199
  ws.send(msg);
200
200
  }
201
201
  };
202
202
  const sendResponseToCdp = (ws, res) => {
203
- if (ws.readyState !== WebSocket.OPEN) return;
203
+ if (ws.readyState !== WebSocket$1.OPEN) return;
204
204
  ws.send(JSON.stringify(res));
205
205
  };
206
206
  const ensureTargetEventsForClient = (ws, mode) => {
@@ -425,7 +425,7 @@ async function ensureChromeExtensionRelayServer(opts) {
425
425
  wssExtension.on("connection", (ws) => {
426
426
  extensionWs = ws;
427
427
  const ping = setInterval(() => {
428
- if (ws.readyState !== WebSocket.OPEN) return;
428
+ if (ws.readyState !== WebSocket$1.OPEN) return;
429
429
  ws.send(JSON.stringify({ method: "ping" }));
430
430
  }, 5e3);
431
431
  ws.on("message", (data) => {
@@ -743,7 +743,7 @@ async function fetchOk(url, timeoutMs = 1500, init) {
743
743
  }
744
744
  async function withCdpSocket(wsUrl, fn, opts) {
745
745
  const headers = getHeadersWithAuth(wsUrl, opts?.headers ?? {});
746
- const ws = new WebSocket(wsUrl, {
746
+ const ws = new WebSocket$1(wsUrl, {
747
747
  handshakeTimeout: typeof opts?.handshakeTimeoutMs === "number" && Number.isFinite(opts.handshakeTimeoutMs) ? Math.max(1, Math.floor(opts.handshakeTimeoutMs)) : 5e3,
748
748
  ...Object.keys(headers).length ? { headers } : {}
749
749
  });
@@ -1637,7 +1637,7 @@ async function getChromeWebSocketUrl(cdpUrl, timeoutMs = 500) {
1637
1637
  async function canOpenWebSocket(wsUrl, timeoutMs = 800) {
1638
1638
  return await new Promise((resolve) => {
1639
1639
  const headers = getHeadersWithAuth(wsUrl);
1640
- const ws = new WebSocket(wsUrl, {
1640
+ const ws = new WebSocket$1(wsUrl, {
1641
1641
  handshakeTimeout: timeoutMs,
1642
1642
  ...Object.keys(headers).length ? { headers } : {}
1643
1643
  });
@@ -3513,3 +3513,202 @@ html, body {
3513
3513
  background: rgba(52, 211, 153, 0.25);
3514
3514
  border-color: rgba(52, 211, 153, 0.5);
3515
3515
  }
3516
+
3517
+ /* ── Reasoning Panel ───────────────────────────────────────────────── */
3518
+ .reasoning-panel {
3519
+ display: flex;
3520
+ flex-direction: column;
3521
+ min-height: 120px;
3522
+ max-height: 420px;
3523
+ flex-shrink: 0;
3524
+ }
3525
+
3526
+ .reasoning-live-dot {
3527
+ display: inline-block;
3528
+ width: 6px;
3529
+ height: 6px;
3530
+ border-radius: 50%;
3531
+ background: var(--accent-cyan);
3532
+ margin-left: 6px;
3533
+ vertical-align: middle;
3534
+ opacity: 0;
3535
+ transition: opacity 0.3s ease;
3536
+ }
3537
+ .reasoning-live-dot.active {
3538
+ opacity: 1;
3539
+ animation: pulse 1.2s ease-in-out infinite;
3540
+ }
3541
+
3542
+ .reasoning-feed {
3543
+ flex: 1;
3544
+ overflow-y: auto;
3545
+ scrollbar-width: thin;
3546
+ scrollbar-color: rgba(0, 212, 255, 0.2) transparent;
3547
+ display: flex;
3548
+ flex-direction: column;
3549
+ gap: 6px;
3550
+ padding-right: 2px;
3551
+ }
3552
+ .reasoning-feed::-webkit-scrollbar { width: 3px; }
3553
+ .reasoning-feed::-webkit-scrollbar-track { background: transparent; }
3554
+ .reasoning-feed::-webkit-scrollbar-thumb { background: rgba(0, 212, 255, 0.2); border-radius: 2px; }
3555
+
3556
+ /* Empty state */
3557
+ .reasoning-empty {
3558
+ display: flex;
3559
+ flex-direction: column;
3560
+ align-items: center;
3561
+ justify-content: center;
3562
+ gap: 8px;
3563
+ padding: 20px 0 12px;
3564
+ color: var(--text-dim);
3565
+ }
3566
+ .reasoning-empty-icon {
3567
+ width: 28px;
3568
+ height: 28px;
3569
+ opacity: 0.4;
3570
+ }
3571
+ .reasoning-empty-icon svg {
3572
+ width: 100%;
3573
+ height: 100%;
3574
+ }
3575
+ .reasoning-empty-text {
3576
+ font-size: 11px;
3577
+ font-family: var(--font-mono);
3578
+ opacity: 0.5;
3579
+ text-align: center;
3580
+ }
3581
+
3582
+ /* Run separator */
3583
+ .reasoning-run-sep {
3584
+ display: flex;
3585
+ align-items: center;
3586
+ gap: 8px;
3587
+ margin: 4px 0 2px;
3588
+ }
3589
+ .reasoning-run-sep::before,
3590
+ .reasoning-run-sep::after {
3591
+ content: '';
3592
+ flex: 1;
3593
+ height: 1px;
3594
+ background: rgba(255, 255, 255, 0.06);
3595
+ }
3596
+ .reasoning-run-sep-label {
3597
+ font-size: 9px;
3598
+ font-family: var(--font-mono);
3599
+ font-weight: 600;
3600
+ letter-spacing: 0.1em;
3601
+ color: var(--text-dim);
3602
+ white-space: nowrap;
3603
+ }
3604
+
3605
+ /* Individual reasoning entry */
3606
+ .reasoning-entry {
3607
+ display: flex;
3608
+ flex-direction: column;
3609
+ gap: 4px;
3610
+ padding: 6px 8px;
3611
+ background: rgba(255, 255, 255, 0.02);
3612
+ border: 1px solid rgba(255, 255, 255, 0.05);
3613
+ border-radius: 8px;
3614
+ transition: border-color 0.2s;
3615
+ }
3616
+ .reasoning-entry:hover {
3617
+ border-color: rgba(255, 255, 255, 0.09);
3618
+ }
3619
+
3620
+ /* Entry header row: badge + label */
3621
+ .reasoning-entry-header {
3622
+ display: flex;
3623
+ align-items: center;
3624
+ gap: 6px;
3625
+ }
3626
+ .reasoning-entry-badge {
3627
+ font-size: 9px;
3628
+ font-family: var(--font-mono);
3629
+ font-weight: 700;
3630
+ letter-spacing: 0.1em;
3631
+ padding: 1px 5px;
3632
+ border-radius: 4px;
3633
+ flex-shrink: 0;
3634
+ }
3635
+ /* Thinking badge — cyan tint */
3636
+ .reasoning-entry-badge.badge-think {
3637
+ background: rgba(0, 212, 255, 0.1);
3638
+ color: var(--accent-cyan);
3639
+ border: 1px solid rgba(0, 212, 255, 0.18);
3640
+ }
3641
+ /* Tool call badge — purple tint */
3642
+ .reasoning-entry-badge.badge-tool {
3643
+ background: rgba(139, 92, 246, 0.12);
3644
+ color: var(--accent-purple);
3645
+ border: 1px solid rgba(139, 92, 246, 0.2);
3646
+ }
3647
+ /* Tool result badge — green tint */
3648
+ .reasoning-entry-badge.badge-result {
3649
+ background: rgba(52, 211, 153, 0.1);
3650
+ color: var(--accent-green);
3651
+ border: 1px solid rgba(52, 211, 153, 0.18);
3652
+ }
3653
+
3654
+ .reasoning-entry-name {
3655
+ font-size: 11px;
3656
+ font-family: var(--font-mono);
3657
+ color: var(--text-muted);
3658
+ white-space: nowrap;
3659
+ overflow: hidden;
3660
+ text-overflow: ellipsis;
3661
+ flex: 1;
3662
+ }
3663
+
3664
+ /* Thinking body */
3665
+ .reasoning-think-body {
3666
+ font-size: 10px;
3667
+ font-family: var(--font-mono);
3668
+ color: var(--text-muted);
3669
+ line-height: 1.55;
3670
+ white-space: pre-wrap;
3671
+ word-break: break-word;
3672
+ max-height: 120px;
3673
+ overflow-y: auto;
3674
+ padding: 4px 2px 0;
3675
+ opacity: 0.75;
3676
+ scrollbar-width: thin;
3677
+ scrollbar-color: rgba(0, 212, 255, 0.15) transparent;
3678
+ }
3679
+ .reasoning-think-body::-webkit-scrollbar { width: 2px; }
3680
+ .reasoning-think-body::-webkit-scrollbar-thumb { background: rgba(0, 212, 255, 0.15); border-radius: 2px; }
3681
+
3682
+ /* Tool detail — compact JSON preview, collapsible */
3683
+ .reasoning-tool-preview {
3684
+ font-size: 10px;
3685
+ font-family: var(--font-mono);
3686
+ color: var(--text-muted);
3687
+ opacity: 0.65;
3688
+ white-space: nowrap;
3689
+ overflow: hidden;
3690
+ text-overflow: ellipsis;
3691
+ padding: 2px 0 0;
3692
+ }
3693
+ .reasoning-tool-detail {
3694
+ display: none;
3695
+ font-size: 10px;
3696
+ font-family: var(--font-mono);
3697
+ color: var(--text-muted);
3698
+ white-space: pre-wrap;
3699
+ word-break: break-all;
3700
+ padding: 4px 2px 0;
3701
+ opacity: 0.65;
3702
+ max-height: 100px;
3703
+ overflow-y: auto;
3704
+ }
3705
+ .reasoning-entry.expanded .reasoning-tool-detail { display: block; }
3706
+ .reasoning-entry.expanded .reasoning-tool-preview { display: none; }
3707
+
3708
+ /* Result row */
3709
+ .reasoning-result-meta {
3710
+ font-size: 10px;
3711
+ font-family: var(--font-mono);
3712
+ color: var(--text-dim);
3713
+ padding: 2px 0 0;
3714
+ }
@@ -138,6 +138,25 @@
138
138
  </button>
139
139
  </div>
140
140
 
141
+ <!-- Reasoning Panel -->
142
+ <div class="glass-panel reasoning-panel" id="reasoning-panel">
143
+ <div class="panel-label">
144
+ REASONING
145
+ <span class="reasoning-live-dot" id="reasoning-live-dot"></span>
146
+ </div>
147
+ <div class="reasoning-feed" id="reasoning-feed">
148
+ <div class="reasoning-empty" id="reasoning-empty">
149
+ <div class="reasoning-empty-icon">
150
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
151
+ <circle cx="12" cy="12" r="3"/>
152
+ <path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/>
153
+ </svg>
154
+ </div>
155
+ <div class="reasoning-empty-text">No reasoning yet</div>
156
+ </div>
157
+ </div>
158
+ </div>
159
+
141
160
  </aside>
142
161
 
143
162
  <!-- Metrics — Right column -->
@@ -195,6 +195,9 @@ function handleRunFailure(reason) {
195
195
  // Stop timers immediately
196
196
  stopElapsedTimer();
197
197
  clearWatchdog();
198
+ if (typeof window.closeLiveThinking === "function") {
199
+ window.closeLiveThinking();
200
+ }
198
201
 
199
202
  // Clean up any in-flight UI elements
200
203
  if (thinkingEl) {
@@ -243,6 +246,10 @@ function handleRunFailure(reason) {
243
246
 
244
247
  // ── Render history (on first connect) ─────────────────────────────
245
248
  function renderHistory(messages) {
249
+ // Clear reasoning panel in sync with the feed — prevents double-entries on reconnect
250
+ if (typeof window.clearReasoningPanel === "function") {
251
+ window.clearReasoningPanel();
252
+ }
246
253
  responseArea.innerHTML = "";
247
254
  for (const m of messages) {
248
255
  if (!m || !m.role) {
@@ -301,9 +308,18 @@ function handleGatewayEvent(event) {
301
308
  if (text) {
302
309
  updateStream(text);
303
310
  }
311
+ // Stream thinking deltas live to the Reasoning Panel
312
+ const thinkingText =
313
+ typeof window.extractThinkingText === "function" ? window.extractThinkingText(p.message) : "";
314
+ if (thinkingText && typeof window.updateLiveThinking === "function") {
315
+ window.updateLiveThinking(thinkingText);
316
+ }
304
317
  } else if (p.state === "final") {
305
318
  stopElapsedTimer();
306
319
  clearWatchdog();
320
+ if (typeof window.closeLiveThinking === "function") {
321
+ window.closeLiveThinking();
322
+ }
307
323
  closeStreamBubble();
308
324
  setAgentStatus("done");
309
325
  isStreaming = false;
@@ -316,6 +332,9 @@ function handleGatewayEvent(event) {
316
332
  // Clean abort (user-initiated or model decided to stop) — not an error
317
333
  stopElapsedTimer();
318
334
  clearWatchdog();
335
+ if (typeof window.closeLiveThinking === "function") {
336
+ window.closeLiveThinking();
337
+ }
319
338
  if (streamBubble) {
320
339
  closeStreamBubble();
321
340
  }
@@ -371,6 +390,13 @@ function setAgentStatus(key) {
371
390
  asoSub.textContent = s.sub;
372
391
  }
373
392
 
393
+ // Pulse the reasoning live-dot while agent is actively thinking/streaming
394
+ const reasoningDot = document.getElementById("reasoning-live-dot");
395
+ if (reasoningDot) {
396
+ const active = key === "thinking" || key === "streaming" || key === "waiting";
397
+ reasoningDot.classList.toggle("active", active);
398
+ }
399
+
374
400
  // ── Elapsed timer management ──────────────────────────────────
375
401
  if (key === "thinking") {
376
402
  // Start elapsed timer and watchdog when processing begins
@@ -476,6 +502,11 @@ async function sendText(text) {
476
502
  addUserMessage(text);
477
503
  await sleep(200);
478
504
 
505
+ // Mark the start of this run in the Reasoning Panel
506
+ if (typeof window.injectReasoningRunSeparator === "function") {
507
+ window.injectReasoningRunSeparator();
508
+ }
509
+
479
510
  setAgentStatus("waiting");
480
511
  thinkingEl = createThinkingBubble();
481
512
  setAgentStatus("thinking");
@@ -532,6 +563,9 @@ async function handleNewSession() {
532
563
 
533
564
  responseArea.innerHTML = "";
534
565
  responseArea.style.opacity = "1";
566
+ if (typeof window.clearReasoningPanel === "function") {
567
+ window.clearReasoningPanel();
568
+ }
535
569
 
536
570
  // Show empty-state indicator
537
571
  const cleared = document.createElement("div");