sparkecoder 0.1.68 → 0.1.69

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 (108) hide show
  1. package/dist/agent/index.d.ts +3 -3
  2. package/dist/agent/index.js +38 -6
  3. package/dist/agent/index.js.map +1 -1
  4. package/dist/cli.js +107 -16
  5. package/dist/cli.js.map +1 -1
  6. package/dist/db/index.d.ts +2 -2
  7. package/dist/{index-Dm6wGcYv.d.ts → index-DqaHLgSC.d.ts} +19 -19
  8. package/dist/index.d.ts +5 -5
  9. package/dist/index.js +107 -16
  10. package/dist/index.js.map +1 -1
  11. package/dist/{schema-XcP0dedO.d.ts → schema-Bq4tID-f.d.ts} +3 -3
  12. package/dist/{search-CCffrVJE.d.ts → search-BRnGaIl-.d.ts} +7 -7
  13. package/dist/server/index.js +107 -16
  14. package/dist/server/index.js.map +1 -1
  15. package/dist/tools/index.d.ts +2 -2
  16. package/package.json +1 -1
  17. package/web/.next/BUILD_ID +1 -1
  18. package/web/.next/standalone/web/.next/BUILD_ID +1 -1
  19. package/web/.next/standalone/web/.next/build-manifest.json +2 -2
  20. package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
  21. package/web/.next/standalone/web/.next/server/app/(main)/page_client-reference-manifest.js +1 -1
  22. package/web/.next/standalone/web/.next/server/app/(main)/session/[id]/page_client-reference-manifest.js +1 -1
  23. package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
  24. package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
  25. package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  26. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  27. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  28. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  29. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  30. package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
  31. package/web/.next/standalone/web/.next/server/app/_not-found.rsc +1 -1
  32. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  33. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  34. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  35. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  36. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  37. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  38. package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
  39. package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +1 -1
  40. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +1 -1
  41. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
  42. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +1 -1
  43. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +1 -1
  44. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +1 -1
  45. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
  46. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +1 -1
  47. package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
  48. package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +1 -1
  49. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +1 -1
  50. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
  51. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +1 -1
  52. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +1 -1
  53. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
  54. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
  55. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +1 -1
  56. package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
  57. package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +1 -1
  58. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +1 -1
  59. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
  60. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +1 -1
  61. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +1 -1
  62. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +1 -1
  63. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
  64. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +1 -1
  65. package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
  66. package/web/.next/standalone/web/.next/server/app/docs.rsc +1 -1
  67. package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +1 -1
  68. package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
  69. package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +1 -1
  70. package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
  71. package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +1 -1
  72. package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +1 -1
  73. package/web/.next/standalone/web/.next/server/app/embed/[id]/page_client-reference-manifest.js +1 -1
  74. package/web/.next/standalone/web/.next/server/app/index.html +1 -1
  75. package/web/.next/standalone/web/.next/server/app/index.rsc +3 -3
  76. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +2 -2
  77. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +2 -2
  78. package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +3 -3
  79. package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
  80. package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +1 -1
  81. package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  82. package/web/.next/standalone/web/.next/server/chunks/ssr/[root-of-the-server]__c71f29f9._.js +3 -3
  83. package/web/.next/standalone/web/.next/server/chunks/ssr/web_2b3a5919._.js +1 -1
  84. package/web/.next/standalone/web/.next/server/chunks/ssr/web_38156da8._.js +1 -1
  85. package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
  86. package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
  87. package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
  88. package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
  89. package/web/.next/{static/chunks/4e673433173ad456.js → standalone/web/.next/static/chunks/2cafc7cb79454d33.js} +3 -3
  90. package/web/.next/standalone/web/.next/static/chunks/{515f0c0bd6087843.js → b6ec74cad9ffd3ee.js} +3 -3
  91. package/web/.next/standalone/web/.next/static/chunks/{31208ade542a0fcb.js → fc39a194539da104.js} +3 -3
  92. package/web/.next/standalone/web/.next/static/{chunks/4e673433173ad456.js → static/chunks/2cafc7cb79454d33.js} +3 -3
  93. package/web/.next/standalone/web/.next/static/static/chunks/{515f0c0bd6087843.js → b6ec74cad9ffd3ee.js} +3 -3
  94. package/web/.next/{static/chunks/31208ade542a0fcb.js → standalone/web/.next/static/static/chunks/fc39a194539da104.js} +3 -3
  95. package/web/.next/standalone/web/src/components/chat-interface.tsx +14 -0
  96. package/web/.next/standalone/web/src/lib/api.ts +89 -16
  97. package/web/.next/{standalone/web/.next/static/static/chunks/4e673433173ad456.js → static/chunks/2cafc7cb79454d33.js} +3 -3
  98. package/web/.next/static/chunks/{515f0c0bd6087843.js → b6ec74cad9ffd3ee.js} +3 -3
  99. package/web/.next/{standalone/web/.next/static/static/chunks/31208ade542a0fcb.js → static/chunks/fc39a194539da104.js} +3 -3
  100. /package/web/.next/standalone/web/.next/static/{6Dlxqhgk8Mki7q7L-gDbl → XB638PEDChQhwk6wSMrSh}/_buildManifest.js +0 -0
  101. /package/web/.next/standalone/web/.next/static/{6Dlxqhgk8Mki7q7L-gDbl → XB638PEDChQhwk6wSMrSh}/_clientMiddlewareManifest.json +0 -0
  102. /package/web/.next/standalone/web/.next/static/{6Dlxqhgk8Mki7q7L-gDbl → XB638PEDChQhwk6wSMrSh}/_ssgManifest.js +0 -0
  103. /package/web/.next/standalone/web/.next/static/static/{6Dlxqhgk8Mki7q7L-gDbl → XB638PEDChQhwk6wSMrSh}/_buildManifest.js +0 -0
  104. /package/web/.next/standalone/web/.next/static/static/{6Dlxqhgk8Mki7q7L-gDbl → XB638PEDChQhwk6wSMrSh}/_clientMiddlewareManifest.json +0 -0
  105. /package/web/.next/standalone/web/.next/static/static/{6Dlxqhgk8Mki7q7L-gDbl → XB638PEDChQhwk6wSMrSh}/_ssgManifest.js +0 -0
  106. /package/web/.next/static/{6Dlxqhgk8Mki7q7L-gDbl → XB638PEDChQhwk6wSMrSh}/_buildManifest.js +0 -0
  107. /package/web/.next/static/{6Dlxqhgk8Mki7q7L-gDbl → XB638PEDChQhwk6wSMrSh}/_clientMiddlewareManifest.json +0 -0
  108. /package/web/.next/static/{6Dlxqhgk8Mki7q7L-gDbl → XB638PEDChQhwk6wSMrSh}/_ssgManifest.js +0 -0
@@ -1,5 +1,5 @@
1
- import { C as Checkpoint, F as FileBackup, M as ModelMessage, a as Message, S as Session, L as LoadedSkill, T as TodoItem, b as ToolExecution, A as ActiveStream, I as IndexStatusRecord, c as IndexedChunk, d as SubagentExecution, e as SubagentStep, f as Terminal } from '../schema-XcP0dedO.js';
2
- export { N as NewActiveStream, g as NewCheckpoint, h as NewFileBackup, i as NewIndexStatusRecord, j as NewIndexedChunk, k as NewMessage, l as NewSession, m as NewSubagentExecution, n as NewTerminal, o as NewTodoItem, p as NewToolExecution, q as SessionConfig, r as TaskConfig, U as UserContentPart, s as UserFilePart, t as UserImagePart, u as UserModelMessage, v as UserTextPart } from '../schema-XcP0dedO.js';
1
+ import { C as Checkpoint, F as FileBackup, M as ModelMessage, a as Message, S as Session, L as LoadedSkill, T as TodoItem, b as ToolExecution, A as ActiveStream, I as IndexStatusRecord, c as IndexedChunk, d as SubagentExecution, e as SubagentStep, f as Terminal } from '../schema-Bq4tID-f.js';
2
+ export { N as NewActiveStream, g as NewCheckpoint, h as NewFileBackup, i as NewIndexStatusRecord, j as NewIndexedChunk, k as NewMessage, l as NewSession, m as NewSubagentExecution, n as NewTerminal, o as NewTodoItem, p as NewToolExecution, q as SessionConfig, r as TaskConfig, U as UserContentPart, s as UserFilePart, t as UserImagePart, u as UserModelMessage, v as UserTextPart } from '../schema-Bq4tID-f.js';
3
3
  import 'drizzle-orm/sqlite-core';
4
4
 
5
5
  /**
@@ -1,7 +1,7 @@
1
1
  import { ModelMessage, streamText } from 'ai';
2
- import { S as Session, b as ToolExecution, r as TaskConfig } from './schema-XcP0dedO.js';
2
+ import { S as Session, b as ToolExecution, r as TaskConfig } from './schema-Bq4tID-f.js';
3
3
  import { z } from 'zod';
4
- import { B as BashToolProgress, W as WriteFileProgress, S as SearchToolProgress } from './search-CCffrVJE.js';
4
+ import { B as BashToolProgress, W as WriteFileProgress, S as SearchToolProgress } from './search-BRnGaIl-.js';
5
5
 
6
6
  declare const ToolApprovalConfigSchema: z.ZodObject<{
7
7
  bash: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
@@ -37,21 +37,21 @@ declare const SessionConfigSchema: z.ZodObject<{
37
37
  error: z.ZodOptional<z.ZodString>;
38
38
  iterations: z.ZodOptional<z.ZodNumber>;
39
39
  }, "strip", z.ZodTypeAny, {
40
- status: "completed" | "failed" | "running";
41
- outputSchema: Record<string, unknown>;
40
+ status: "completed" | "running" | "failed";
42
41
  enabled: boolean;
42
+ outputSchema: Record<string, unknown>;
43
43
  error?: string | undefined;
44
- maxIterations?: number | undefined;
45
44
  webhookUrl?: string | undefined;
45
+ maxIterations?: number | undefined;
46
46
  result?: unknown;
47
47
  iterations?: number | undefined;
48
48
  }, {
49
- status: "completed" | "failed" | "running";
50
- outputSchema: Record<string, unknown>;
49
+ status: "completed" | "running" | "failed";
51
50
  enabled: boolean;
51
+ outputSchema: Record<string, unknown>;
52
52
  error?: string | undefined;
53
- maxIterations?: number | undefined;
54
53
  webhookUrl?: string | undefined;
54
+ maxIterations?: number | undefined;
55
55
  result?: unknown;
56
56
  iterations?: number | undefined;
57
57
  }>>;
@@ -59,32 +59,32 @@ declare const SessionConfigSchema: z.ZodObject<{
59
59
  maxContextChars: number;
60
60
  toolApprovals?: Record<string, boolean> | undefined;
61
61
  approvalWebhook?: string | undefined;
62
+ skillsDirectory?: string | undefined;
62
63
  task?: {
63
- status: "completed" | "failed" | "running";
64
- outputSchema: Record<string, unknown>;
64
+ status: "completed" | "running" | "failed";
65
65
  enabled: boolean;
66
+ outputSchema: Record<string, unknown>;
66
67
  error?: string | undefined;
67
- maxIterations?: number | undefined;
68
68
  webhookUrl?: string | undefined;
69
+ maxIterations?: number | undefined;
69
70
  result?: unknown;
70
71
  iterations?: number | undefined;
71
72
  } | undefined;
72
- skillsDirectory?: string | undefined;
73
73
  }, {
74
74
  toolApprovals?: Record<string, boolean> | undefined;
75
75
  approvalWebhook?: string | undefined;
76
+ skillsDirectory?: string | undefined;
77
+ maxContextChars?: number | undefined;
76
78
  task?: {
77
- status: "completed" | "failed" | "running";
78
- outputSchema: Record<string, unknown>;
79
+ status: "completed" | "running" | "failed";
79
80
  enabled: boolean;
81
+ outputSchema: Record<string, unknown>;
80
82
  error?: string | undefined;
81
- maxIterations?: number | undefined;
82
83
  webhookUrl?: string | undefined;
84
+ maxIterations?: number | undefined;
83
85
  result?: unknown;
84
86
  iterations?: number | undefined;
85
87
  } | undefined;
86
- skillsDirectory?: string | undefined;
87
- maxContextChars?: number | undefined;
88
88
  }>;
89
89
  declare const SparkcoderConfigSchema: z.ZodObject<{
90
90
  defaultModel: z.ZodDefault<z.ZodString>;
@@ -179,7 +179,6 @@ declare const SparkcoderConfigSchema: z.ZodObject<{
179
179
  exclude?: string[] | undefined;
180
180
  }>>;
181
181
  }, "strip", z.ZodTypeAny, {
182
- defaultModel: string;
183
182
  toolApprovals: {
184
183
  bash: boolean;
185
184
  write_file: boolean;
@@ -187,6 +186,7 @@ declare const SparkcoderConfigSchema: z.ZodObject<{
187
186
  load_skill: boolean;
188
187
  todo: boolean;
189
188
  };
189
+ defaultModel: string;
190
190
  skills: {
191
191
  directory: string;
192
192
  additionalDirectories: string[];
@@ -217,7 +217,6 @@ declare const SparkcoderConfigSchema: z.ZodObject<{
217
217
  namespace?: string | undefined;
218
218
  } | undefined;
219
219
  }, {
220
- defaultModel?: string | undefined;
221
220
  workingDirectory?: string | undefined;
222
221
  toolApprovals?: {
223
222
  bash?: boolean | undefined;
@@ -227,6 +226,7 @@ declare const SparkcoderConfigSchema: z.ZodObject<{
227
226
  todo?: boolean | undefined;
228
227
  } | undefined;
229
228
  approvalWebhook?: string | undefined;
229
+ defaultModel?: string | undefined;
230
230
  skills?: {
231
231
  directory?: string | undefined;
232
232
  additionalDirectories?: string[] | undefined;
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- import { R as ResolvedConfig } from './index-Dm6wGcYv.js';
2
- export { A as Agent, a as AgentOptions, b as AgentRunOptions, c as AgentStreamResult, S as SparkcoderConfig, T as ToolApprovalConfig } from './index-Dm6wGcYv.js';
1
+ import { R as ResolvedConfig } from './index-DqaHLgSC.js';
2
+ export { A as Agent, a as AgentOptions, b as AgentRunOptions, c as AgentStreamResult, S as SparkcoderConfig, T as ToolApprovalConfig } from './index-DqaHLgSC.js';
3
3
  export { ServerOptions, createApp, startServer, stopServer } from './server/index.js';
4
4
  export { checkpointQueries, closeDatabase, fileBackupQueries, getDb, initDatabase, messageQueries, sessionQueries, skillQueries, todoQueries, toolExecutionQueries } from './db/index.js';
5
- import { F as FileBackup, C as Checkpoint } from './schema-XcP0dedO.js';
6
- export { a as Message, M as ModelMessage, S as Session, q as SessionConfig, f as Terminal, T as TodoItem, b as ToolExecution } from './schema-XcP0dedO.js';
5
+ import { F as FileBackup, C as Checkpoint } from './schema-Bq4tID-f.js';
6
+ export { a as Message, M as ModelMessage, S as Session, q as SessionConfig, f as Terminal, T as TodoItem, b as ToolExecution } from './schema-Bq4tID-f.js';
7
7
  export { createLoadSkillTool, createReadFileTool, createTodoTool, createTools } from './tools/index.js';
8
- export { c as createBashTool, a as createWriteFileTool } from './search-CCffrVJE.js';
8
+ export { c as createBashTool, a as createWriteFileTool } from './search-BRnGaIl-.js';
9
9
  import 'ai';
10
10
  import 'zod';
11
11
  import 'hono/types';
package/dist/index.js CHANGED
@@ -1785,10 +1785,15 @@ import WebSocket from "ws";
1785
1785
  import { EventEmitter } from "events";
1786
1786
  function getOrCreateProxy(sessionId, port) {
1787
1787
  const existing = activeProxies.get(sessionId);
1788
- if (existing) return existing;
1788
+ if (existing) {
1789
+ console.log(`[BROWSER-WS] Reusing existing proxy for session ${sessionId} (connected=${existing.connected})`);
1790
+ return existing;
1791
+ }
1792
+ console.log(`[BROWSER-WS] Creating new proxy for session ${sessionId} on port ${port} (active proxies: ${activeProxies.size})`);
1789
1793
  const proxy = new BrowserStreamProxy(port);
1790
1794
  activeProxies.set(sessionId, proxy);
1791
1795
  proxy.on("close", () => {
1796
+ console.log(`[BROWSER-WS] Proxy closed for session ${sessionId}, removing from registry`);
1792
1797
  activeProxies.delete(sessionId);
1793
1798
  });
1794
1799
  proxy.connect();
@@ -1800,8 +1805,11 @@ function getProxy(sessionId) {
1800
1805
  function destroyProxy(sessionId) {
1801
1806
  const proxy = activeProxies.get(sessionId);
1802
1807
  if (proxy) {
1808
+ console.log(`[BROWSER-WS] destroyProxy() called for session ${sessionId}`);
1803
1809
  proxy.destroy();
1804
1810
  activeProxies.delete(sessionId);
1811
+ } else {
1812
+ console.log(`[BROWSER-WS] destroyProxy() called but no proxy exists for session ${sessionId}`);
1805
1813
  }
1806
1814
  }
1807
1815
  var RECONNECT_DELAY_MS, MAX_RECONNECT_ATTEMPTS, FRAME_THROTTLE_MS, BrowserStreamProxy, activeProxies;
@@ -1832,18 +1840,22 @@ var init_stream_proxy = __esm({
1832
1840
  }
1833
1841
  connect() {
1834
1842
  if (this.destroyed) return;
1843
+ console.log(`[BROWSER-WS] connect() called for port ${this.port}`);
1835
1844
  this.doConnect();
1836
1845
  }
1837
1846
  doConnect() {
1838
1847
  if (this.destroyed) return;
1839
1848
  const url = `ws://localhost:${this.port}`;
1849
+ console.log(`[BROWSER-WS] Attempting WebSocket connection to ${url} (attempt ${this.reconnectAttempts + 1}/${MAX_RECONNECT_ATTEMPTS})`);
1840
1850
  try {
1841
1851
  this.ws = new WebSocket(url);
1842
- } catch {
1852
+ } catch (err) {
1853
+ console.warn(`[BROWSER-WS] WebSocket constructor threw for ${url}:`, err);
1843
1854
  this.scheduleReconnect();
1844
1855
  return;
1845
1856
  }
1846
1857
  this.ws.on("open", () => {
1858
+ console.log(`[BROWSER-WS] Connected to ${url} (after ${this.reconnectAttempts} retries)`);
1847
1859
  this.reconnectAttempts = 0;
1848
1860
  this._connected = true;
1849
1861
  this.emit("status", {
@@ -1855,12 +1867,14 @@ var init_stream_proxy = __esm({
1855
1867
  try {
1856
1868
  const msg = JSON.parse(typeof raw === "string" ? raw : raw.toString("utf8"));
1857
1869
  this.handleMessage(msg);
1858
- } catch {
1870
+ } catch (err) {
1871
+ console.warn(`[BROWSER-WS] Malformed message from ${url}:`, err);
1859
1872
  }
1860
1873
  });
1861
- this.ws.on("close", () => {
1874
+ this.ws.on("close", (code, reason) => {
1862
1875
  const wasConnected = this._connected;
1863
1876
  this._connected = false;
1877
+ console.log(`[BROWSER-WS] Connection closed: code=${code} reason="${reason?.toString() || ""}" wasConnected=${wasConnected} destroyed=${this.destroyed}`);
1864
1878
  if (wasConnected) {
1865
1879
  this.emit("status", { connected: false, screencasting: false });
1866
1880
  }
@@ -1868,14 +1882,26 @@ var init_stream_proxy = __esm({
1868
1882
  this.scheduleReconnect();
1869
1883
  }
1870
1884
  });
1871
- this.ws.on("error", () => {
1885
+ this.ws.on("error", (err) => {
1886
+ console.warn(`[BROWSER-WS] WebSocket error on port ${this.port}:`, err.message);
1872
1887
  });
1873
1888
  }
1889
+ frameCount = 0;
1890
+ throttledCount = 0;
1891
+ lastFrameLogTime = 0;
1874
1892
  handleMessage(msg) {
1875
1893
  if (msg.type === "frame") {
1876
1894
  const now = Date.now();
1877
- if (now - this.lastFrameTime < FRAME_THROTTLE_MS) return;
1895
+ if (now - this.lastFrameTime < FRAME_THROTTLE_MS) {
1896
+ this.throttledCount++;
1897
+ return;
1898
+ }
1878
1899
  this.lastFrameTime = now;
1900
+ this.frameCount++;
1901
+ if (now - this.lastFrameLogTime > 5e3) {
1902
+ console.log(`[BROWSER-WS] Frame stats: emitted=${this.frameCount} throttled=${this.throttledCount} listeners=${this.listenerCount("frame")} dataSize=${msg.data?.length ?? 0}`);
1903
+ this.lastFrameLogTime = now;
1904
+ }
1879
1905
  const frame = {
1880
1906
  data: msg.data,
1881
1907
  metadata: msg.metadata ?? {
@@ -1891,21 +1917,26 @@ var init_stream_proxy = __esm({
1891
1917
  this._latestFrame = frame;
1892
1918
  this.emit("frame", frame);
1893
1919
  } else if (msg.type === "status") {
1920
+ console.log(`[BROWSER-WS] Status message received:`, JSON.stringify(msg));
1894
1921
  this.emit("status", {
1895
1922
  connected: msg.connected ?? true,
1896
1923
  screencasting: msg.screencasting ?? true,
1897
1924
  viewportWidth: msg.viewportWidth,
1898
1925
  viewportHeight: msg.viewportHeight
1899
1926
  });
1927
+ } else {
1928
+ console.log(`[BROWSER-WS] Unknown message type: ${msg.type}`);
1900
1929
  }
1901
1930
  }
1902
1931
  scheduleReconnect() {
1903
1932
  if (this.destroyed || this.reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
1933
+ console.log(`[BROWSER-WS] Giving up reconnection: destroyed=${this.destroyed} attempts=${this.reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS}`);
1904
1934
  this.emit("close");
1905
1935
  return;
1906
1936
  }
1907
1937
  this.reconnectAttempts++;
1908
1938
  const delay = this.reconnectAttempts <= 5 ? RECONNECT_DELAY_MS : RECONNECT_DELAY_MS * (this.reconnectAttempts - 4);
1939
+ console.log(`[BROWSER-WS] Scheduling reconnect in ${delay}ms (attempt ${this.reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS})`);
1909
1940
  this.reconnectTimer = setTimeout(() => this.doConnect(), delay);
1910
1941
  }
1911
1942
  /**
@@ -1917,6 +1948,7 @@ var init_stream_proxy = __esm({
1917
1948
  }
1918
1949
  }
1919
1950
  destroy() {
1951
+ console.log(`[BROWSER-WS] Destroying proxy for port ${this.port} (emitted ${this.frameCount} frames, throttled ${this.throttledCount})`);
1920
1952
  this.destroyed = true;
1921
1953
  if (this.reconnectTimer) {
1922
1954
  clearTimeout(this.reconnectTimer);
@@ -8078,11 +8110,19 @@ var cleanupInterval = setInterval(() => {
8078
8110
  }
8079
8111
  }, 6e4);
8080
8112
  cleanupInterval.unref();
8113
+ var publishCount = 0;
8114
+ var lastPublishLog = 0;
8081
8115
  var publisher = {
8082
8116
  connect: async () => {
8083
8117
  },
8084
8118
  publish: async (channel, message) => {
8085
8119
  const subscribers = channels.get(channel);
8120
+ publishCount++;
8121
+ const now = Date.now();
8122
+ if (now - lastPublishLog > 1e4) {
8123
+ console.log(`[ResumableStream] Publish stats: total=${publishCount}, channels=${channels.size}, store=${store.size}`);
8124
+ lastPublishLog = now;
8125
+ }
8086
8126
  if (subscribers) {
8087
8127
  for (const callback of subscribers) {
8088
8128
  setImmediate(() => callback(message));
@@ -8121,9 +8161,12 @@ var subscriber = {
8121
8161
  channels.set(channel, /* @__PURE__ */ new Set());
8122
8162
  }
8123
8163
  channels.get(channel).add(callback);
8164
+ console.log(`[ResumableStream] Subscribe to channel "${channel}" (total subscribers: ${channels.get(channel).size})`);
8124
8165
  },
8125
8166
  unsubscribe: async (channel) => {
8167
+ const count = channels.get(channel)?.size ?? 0;
8126
8168
  channels.delete(channel);
8169
+ console.log(`[ResumableStream] Unsubscribe from channel "${channel}" (removed ${count} subscribers)`);
8127
8170
  }
8128
8171
  };
8129
8172
  var streamContext = createResumableStreamContext({
@@ -8309,19 +8352,28 @@ function createAgentStreamProducer(sessionId, prompt, streamId, attachments) {
8309
8352
  const toolCallStarts = /* @__PURE__ */ new Set();
8310
8353
  const abortController = new AbortController();
8311
8354
  streamAbortControllers.set(streamId, abortController);
8355
+ let sseEventCount = 0;
8356
+ let sseBrowserFrameCount = 0;
8357
+ let sseWriteErrors = 0;
8312
8358
  const writeSSE = async (data) => {
8313
8359
  if (writerClosed) return;
8314
8360
  try {
8361
+ sseEventCount++;
8315
8362
  await writer.write(`data: ${data}
8316
8363
 
8317
8364
  `);
8318
8365
  } catch (err) {
8366
+ sseWriteErrors++;
8367
+ if (sseWriteErrors === 1) {
8368
+ console.log(`[SSE:${streamId}] Writer closed (client disconnected). Total events sent: ${sseEventCount}, browser frames: ${sseBrowserFrameCount}`);
8369
+ }
8319
8370
  writerClosed = true;
8320
8371
  }
8321
8372
  };
8322
8373
  const safeClose = async () => {
8323
8374
  if (writerClosed) return;
8324
8375
  try {
8376
+ console.log(`[SSE:${streamId}] Stream closing. Total events: ${sseEventCount}, browser frames: ${sseBrowserFrameCount}, write errors: ${sseWriteErrors}`);
8325
8377
  writerClosed = true;
8326
8378
  await writer.close();
8327
8379
  } catch {
@@ -8444,35 +8496,47 @@ ${prompt}` });
8444
8496
  const browserPort = progress.data?.browserStreamPort;
8445
8497
  const browserClosed = progress.data?.browserClosed;
8446
8498
  if (progress.toolName === "bash" && browserClosed) {
8447
- console.log(`[BROWSER-STREAM] agent-browser close detected, destroying proxy`);
8499
+ console.log(`[BROWSER-STREAM:${streamId}] agent-browser close detected, destroying proxy for session ${sessionId}`);
8448
8500
  destroyProxy(sessionId);
8449
8501
  } else if (progress.toolName === "bash" && browserPort) {
8450
- console.log(`[BROWSER-STREAM] agent-browser command detected, ensuring proxy on port ${browserPort}`);
8502
+ console.log(`[BROWSER-STREAM:${streamId}] agent-browser command detected, ensuring proxy on port ${browserPort} for session ${sessionId}`);
8451
8503
  const proxy = getOrCreateProxy(sessionId, browserPort);
8504
+ console.log(`[BROWSER-STREAM:${streamId}] Proxy state: connected=${proxy.connected}, frameListeners=${proxy.listenerCount("frame")}, statusListeners=${proxy.listenerCount("status")}`);
8452
8505
  if (!sessionRecorders.has(sessionId)) {
8453
8506
  const recorder = new FrameRecorder(sessionId);
8454
8507
  recorder.start();
8455
8508
  sessionRecorders.set(sessionId, recorder);
8456
8509
  }
8457
8510
  if (proxy.listenerCount("frame") === 0) {
8511
+ console.log(`[BROWSER-STREAM:${streamId}] Attaching frame+status listeners to proxy`);
8458
8512
  proxy.on("frame", (frame) => {
8513
+ sseBrowserFrameCount++;
8514
+ if (sseBrowserFrameCount === 1) {
8515
+ console.log(`[BROWSER-STREAM:${streamId}] First browser frame received! dataSize=${frame.data?.length ?? 0} writerClosed=${writerClosed}`);
8516
+ } else if (sseBrowserFrameCount % 50 === 0) {
8517
+ console.log(`[BROWSER-STREAM:${streamId}] Browser frame #${sseBrowserFrameCount} (writerClosed=${writerClosed})`);
8518
+ }
8459
8519
  const rec = sessionRecorders.get(sessionId);
8460
8520
  rec?.addFrame(frame);
8461
8521
  writeSSE(JSON.stringify({
8462
8522
  type: "browser-frame",
8463
8523
  data: frame.data,
8464
8524
  metadata: frame.metadata
8465
- })).catch(() => {
8525
+ })).catch((err) => {
8526
+ console.warn(`[BROWSER-STREAM:${streamId}] Failed to send browser-frame via SSE:`, err);
8466
8527
  });
8467
8528
  });
8468
8529
  proxy.on("status", (s) => {
8469
- console.log(`[BROWSER-STREAM] Status:`, s);
8530
+ console.log(`[BROWSER-STREAM:${streamId}] Browser status event: connected=${s.connected} screencasting=${s.screencasting} viewport=${s.viewportWidth}x${s.viewportHeight}`);
8470
8531
  writeSSE(JSON.stringify({
8471
8532
  type: "browser-status",
8472
8533
  ...s
8473
- })).catch(() => {
8534
+ })).catch((err) => {
8535
+ console.warn(`[BROWSER-STREAM:${streamId}] Failed to send browser-status via SSE:`, err);
8474
8536
  });
8475
8537
  });
8538
+ } else {
8539
+ console.log(`[BROWSER-STREAM:${streamId}] Frame listeners already attached (count=${proxy.listenerCount("frame")}), skipping`);
8476
8540
  }
8477
8541
  }
8478
8542
  },
@@ -8662,14 +8726,17 @@ ${prompt}` });
8662
8726
  }
8663
8727
  await messageQueries.create(id, { role: "user", content: userMessageContent });
8664
8728
  const streamId = `stream_${id}_${nanoid6(10)}`;
8729
+ console.log(`[STREAM] Creating stream ${streamId} for session ${id}`);
8665
8730
  await activeStreamQueries.create(id, streamId);
8666
8731
  const stream = await streamContext.resumableStream(
8667
8732
  streamId,
8668
8733
  createAgentStreamProducer(id, prompt, streamId, streamAttachments)
8669
8734
  );
8670
8735
  if (!stream) {
8736
+ console.error(`[STREAM] Failed to create resumable stream ${streamId}`);
8671
8737
  return c.json({ error: "Failed to create stream" }, 500);
8672
8738
  }
8739
+ console.log(`[STREAM] Stream ${streamId} created successfully`);
8673
8740
  const encodedStream = stream.pipeThrough(new TextEncoderStream());
8674
8741
  return new Response(encodedStream, {
8675
8742
  headers: {
@@ -8698,17 +8765,20 @@ agents.get("/:id/watch", async (c) => {
8698
8765
  }
8699
8766
  streamId = activeStream.streamId;
8700
8767
  }
8768
+ console.log(`[STREAM] Watch request for session ${sessionId}, streamId=${streamId}, resumeAt=${resumeAt || "none"}`);
8701
8769
  const stream = await streamContext.resumeExistingStream(
8702
8770
  streamId,
8703
8771
  resumeAt ? parseInt(resumeAt, 10) : void 0
8704
8772
  );
8705
8773
  if (!stream) {
8774
+ console.log(`[STREAM] Watch failed \u2014 stream ${streamId} is no longer active`);
8706
8775
  return c.json({
8707
8776
  error: "Stream is no longer active",
8708
8777
  streamId,
8709
8778
  hint: "The stream may have finished. Check /agents/:id/approvals or start a new run."
8710
8779
  }, 422);
8711
8780
  }
8781
+ console.log(`[STREAM] Client watching stream ${streamId}`);
8712
8782
  const encodedStream = stream.pipeThrough(new TextEncoderStream());
8713
8783
  return new Response(encodedStream, {
8714
8784
  headers: {
@@ -8870,19 +8940,28 @@ agents.post(
8870
8940
  const toolCallStarts = /* @__PURE__ */ new Set();
8871
8941
  const abortController = new AbortController();
8872
8942
  streamAbortControllers.set(streamId, abortController);
8943
+ let sseEventCount = 0;
8944
+ let sseBrowserFrameCount = 0;
8945
+ let sseWriteErrors = 0;
8873
8946
  const writeSSE = async (data) => {
8874
8947
  if (writerClosed) return;
8875
8948
  try {
8949
+ sseEventCount++;
8876
8950
  await writer.write(`data: ${data}
8877
8951
 
8878
8952
  `);
8879
8953
  } catch (err) {
8954
+ sseWriteErrors++;
8955
+ if (sseWriteErrors === 1) {
8956
+ console.log(`[SSE:${streamId}] Writer closed (client disconnected). Total events sent: ${sseEventCount}, browser frames: ${sseBrowserFrameCount}`);
8957
+ }
8880
8958
  writerClosed = true;
8881
8959
  }
8882
8960
  };
8883
8961
  const safeClose = async () => {
8884
8962
  if (writerClosed) return;
8885
8963
  try {
8964
+ console.log(`[SSE:${streamId}] Stream closing. Total events: ${sseEventCount}, browser frames: ${sseBrowserFrameCount}, write errors: ${sseWriteErrors}`);
8886
8965
  writerClosed = true;
8887
8966
  await writer.close();
8888
8967
  } catch {
@@ -8942,35 +9021,47 @@ agents.post(
8942
9021
  const browserPort = progress.data?.browserStreamPort;
8943
9022
  const browserClosed = progress.data?.browserClosed;
8944
9023
  if (progress.toolName === "bash" && browserClosed) {
8945
- console.log(`[BROWSER-STREAM] agent-browser close detected`);
9024
+ console.log(`[BROWSER-STREAM:${streamId}] agent-browser close detected, destroying proxy for session ${session.id}`);
8946
9025
  destroyProxy(session.id);
8947
9026
  } else if (progress.toolName === "bash" && browserPort) {
8948
- console.log(`[BROWSER-STREAM] agent-browser command detected, port ${browserPort}`);
9027
+ console.log(`[BROWSER-STREAM:${streamId}] agent-browser command detected, port ${browserPort} for session ${session.id}`);
8949
9028
  const proxy = getOrCreateProxy(session.id, browserPort);
9029
+ console.log(`[BROWSER-STREAM:${streamId}] Proxy state: connected=${proxy.connected}, frameListeners=${proxy.listenerCount("frame")}, statusListeners=${proxy.listenerCount("status")}`);
8950
9030
  if (!sessionRecorders.has(session.id)) {
8951
9031
  const recorder = new FrameRecorder(session.id);
8952
9032
  recorder.start();
8953
9033
  sessionRecorders.set(session.id, recorder);
8954
9034
  }
8955
9035
  if (proxy.listenerCount("frame") === 0) {
9036
+ console.log(`[BROWSER-STREAM:${streamId}] Attaching frame+status listeners to proxy`);
8956
9037
  proxy.on("frame", (frame) => {
9038
+ sseBrowserFrameCount++;
9039
+ if (sseBrowserFrameCount === 1) {
9040
+ console.log(`[BROWSER-STREAM:${streamId}] First browser frame received! dataSize=${frame.data?.length ?? 0} writerClosed=${writerClosed}`);
9041
+ } else if (sseBrowserFrameCount % 50 === 0) {
9042
+ console.log(`[BROWSER-STREAM:${streamId}] Browser frame #${sseBrowserFrameCount} (writerClosed=${writerClosed})`);
9043
+ }
8957
9044
  const rec = sessionRecorders.get(session.id);
8958
9045
  rec?.addFrame(frame);
8959
9046
  writeSSE(JSON.stringify({
8960
9047
  type: "browser-frame",
8961
9048
  data: frame.data,
8962
9049
  metadata: frame.metadata
8963
- })).catch(() => {
9050
+ })).catch((err) => {
9051
+ console.warn(`[BROWSER-STREAM:${streamId}] Failed to send browser-frame via SSE:`, err);
8964
9052
  });
8965
9053
  });
8966
9054
  proxy.on("status", (s) => {
8967
- console.log(`[BROWSER-STREAM] Status:`, s);
9055
+ console.log(`[BROWSER-STREAM:${streamId}] Browser status event: connected=${s.connected} screencasting=${s.screencasting} viewport=${s.viewportWidth}x${s.viewportHeight}`);
8968
9056
  writeSSE(JSON.stringify({
8969
9057
  type: "browser-status",
8970
9058
  ...s
8971
- })).catch(() => {
9059
+ })).catch((err) => {
9060
+ console.warn(`[BROWSER-STREAM:${streamId}] Failed to send browser-status via SSE:`, err);
8972
9061
  });
8973
9062
  });
9063
+ } else {
9064
+ console.log(`[BROWSER-STREAM:${streamId}] Frame listeners already attached (count=${proxy.listenerCount("frame")}), skipping`);
8974
9065
  }
8975
9066
  }
8976
9067
  },