sparkecoder 0.1.64 → 0.1.66

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 (151) hide show
  1. package/dist/agent/index.d.ts +3 -3
  2. package/dist/agent/index.js +815 -30
  3. package/dist/agent/index.js.map +1 -1
  4. package/dist/cli.js +1042 -165
  5. package/dist/cli.js.map +1 -1
  6. package/dist/db/index.d.ts +2 -2
  7. package/dist/db/index.js.map +1 -1
  8. package/dist/{index-Dn-eCGLe.d.ts → index-Db23cukG.d.ts} +35 -25
  9. package/dist/index.d.ts +5 -5
  10. package/dist/index.js +1058 -146
  11. package/dist/index.js.map +1 -1
  12. package/dist/{schema-XcP0dedO.d.ts → schema-C7Mm4Ykn.d.ts} +3 -3
  13. package/dist/{search-DINnDTgj.d.ts → search-CVVfuBPZ.d.ts} +6 -4
  14. package/dist/server/index.js +1058 -146
  15. package/dist/server/index.js.map +1 -1
  16. package/dist/skills/default/qa.md +317 -0
  17. package/dist/tools/index.d.ts +31 -4
  18. package/dist/tools/index.js +433 -7
  19. package/dist/tools/index.js.map +1 -1
  20. package/package.json +3 -1
  21. package/src/skills/default/qa.md +317 -0
  22. package/web/.next/BUILD_ID +1 -1
  23. package/web/.next/standalone/web/.next/BUILD_ID +1 -1
  24. package/web/.next/standalone/web/.next/build-manifest.json +2 -2
  25. package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
  26. package/web/.next/standalone/web/.next/server/app/(main)/page.js.nft.json +1 -1
  27. package/web/.next/standalone/web/.next/server/app/(main)/page_client-reference-manifest.js +1 -1
  28. package/web/.next/standalone/web/.next/server/app/(main)/session/[id]/page.js.nft.json +1 -1
  29. package/web/.next/standalone/web/.next/server/app/(main)/session/[id]/page_client-reference-manifest.js +1 -1
  30. package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
  31. package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
  32. package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  33. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  34. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  35. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  36. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  37. package/web/.next/standalone/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  38. package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
  39. package/web/.next/standalone/web/.next/server/app/_not-found.rsc +2 -2
  40. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  41. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  42. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  43. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  44. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  45. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  46. package/web/.next/standalone/web/.next/server/app/api/config/route.js.nft.json +1 -1
  47. package/web/.next/standalone/web/.next/server/app/api/health/route.js.nft.json +1 -1
  48. package/web/.next/standalone/web/.next/server/app/docs/installation/page_client-reference-manifest.js +1 -1
  49. package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
  50. package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +2 -2
  51. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +2 -2
  52. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
  53. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +2 -2
  54. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +2 -2
  55. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +1 -1
  56. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
  57. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +1 -1
  58. package/web/.next/standalone/web/.next/server/app/docs/page_client-reference-manifest.js +1 -1
  59. package/web/.next/standalone/web/.next/server/app/docs/skills/page_client-reference-manifest.js +1 -1
  60. package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
  61. package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +2 -2
  62. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +2 -2
  63. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
  64. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +2 -2
  65. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +2 -2
  66. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
  67. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
  68. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +1 -1
  69. package/web/.next/standalone/web/.next/server/app/docs/tools/page_client-reference-manifest.js +1 -1
  70. package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
  71. package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +2 -2
  72. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +2 -2
  73. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
  74. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +2 -2
  75. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +2 -2
  76. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +1 -1
  77. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
  78. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +1 -1
  79. package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
  80. package/web/.next/standalone/web/.next/server/app/docs.rsc +2 -2
  81. package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +2 -2
  82. package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
  83. package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +2 -2
  84. package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +2 -2
  85. package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +1 -1
  86. package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +1 -1
  87. package/web/.next/standalone/web/.next/server/app/embed/[id]/page.js.nft.json +1 -1
  88. package/web/.next/standalone/web/.next/server/app/embed/[id]/page_client-reference-manifest.js +1 -1
  89. package/web/.next/standalone/web/.next/server/app/index.html +1 -1
  90. package/web/.next/standalone/web/.next/server/app/index.rsc +4 -4
  91. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +2 -2
  92. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +2 -2
  93. package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +4 -4
  94. package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
  95. package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +2 -2
  96. package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  97. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_5c78460e._.js → 2374f_02a118f9._.js} +1 -1
  98. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_bfc8ef7d._.js → 2374f_0ed477f8._.js} +1 -1
  99. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_04a544c8._.js → 2374f_12bad06e._.js} +1 -1
  100. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_e366206f._.js → 2374f_2526ca80._.js} +1 -1
  101. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_45534372._.js → 2374f_3b51a934._.js} +1 -1
  102. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_d5f5b9ba._.js → 2374f_3e519469._.js} +1 -1
  103. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_5e9eb6da._.js → 2374f_5ebfcf1a._.js} +1 -1
  104. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_db790cfe._.js → 2374f_a0f483d1._.js} +1 -1
  105. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_c61a33b3._.js → 2374f_acf3dfe4._.js} +1 -1
  106. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_ab5b97d8._.js → 2374f_ad08e83a._.js} +1 -1
  107. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_68abddfe._.js → 2374f_c1d54c16._.js} +1 -1
  108. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_de60e6ea._.js → 2374f_db3e363b._.js} +1 -1
  109. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_72fb9db7._.js → 2374f_f0d7e130._.js} +1 -1
  110. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_5d0b3394._.js → 2374f_fc992d90._.js} +1 -1
  111. package/web/.next/standalone/web/.next/server/chunks/ssr/{[root-of-the-server]__aa788b85._.js → [root-of-the-server]__06818a54._.js} +2 -2
  112. package/web/.next/standalone/web/.next/server/chunks/ssr/{[root-of-the-server]__d04c460d._.js → [root-of-the-server]__c71f29f9._.js} +4 -4
  113. package/web/.next/standalone/web/.next/server/chunks/ssr/web_2b3a5919._.js +1 -1
  114. package/web/.next/standalone/web/.next/server/chunks/ssr/web_38156da8._.js +1 -1
  115. package/web/.next/standalone/web/.next/server/chunks/ssr/web_5cca707f._.js +7 -0
  116. package/web/.next/standalone/web/.next/server/chunks/ssr/web_935e81f5._.js +7 -0
  117. package/web/.next/standalone/web/.next/server/chunks/ssr/{web_6fb589ac._.js → web_cc5f7515._.js} +2 -2
  118. package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
  119. package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
  120. package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
  121. package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
  122. package/web/.next/standalone/web/.next/static/chunks/{eea48be65cdb3f4b.js → 31208ade542a0fcb.js} +3 -3
  123. package/web/.next/{static/chunks/054deec0c7b19894.js → standalone/web/.next/static/chunks/4e673433173ad456.js} +3 -3
  124. package/web/.next/standalone/web/.next/static/chunks/{7fb141141caa4fac.js → 515f0c0bd6087843.js} +5 -5
  125. package/web/.next/standalone/web/.next/static/chunks/fd39dd62879495e1.css +1 -0
  126. package/web/.next/{static/chunks/eea48be65cdb3f4b.js → standalone/web/.next/static/static/chunks/31208ade542a0fcb.js} +3 -3
  127. package/web/.next/standalone/web/.next/static/static/chunks/{054deec0c7b19894.js → 4e673433173ad456.js} +3 -3
  128. package/web/.next/standalone/web/.next/static/static/chunks/{7fb141141caa4fac.js → 515f0c0bd6087843.js} +5 -5
  129. package/web/.next/standalone/web/.next/static/static/chunks/fd39dd62879495e1.css +1 -0
  130. package/web/.next/standalone/web/src/components/ai-elements/browser-recording.tsx +100 -0
  131. package/web/.next/standalone/web/src/components/browser-preview.tsx +196 -0
  132. package/web/.next/standalone/web/src/components/chat-interface.tsx +188 -4
  133. package/web/.next/standalone/web/src/lib/api.ts +119 -0
  134. package/web/.next/{standalone/web/.next/static/static/chunks/eea48be65cdb3f4b.js → static/chunks/31208ade542a0fcb.js} +3 -3
  135. package/web/.next/{standalone/web/.next/static/chunks/054deec0c7b19894.js → static/chunks/4e673433173ad456.js} +3 -3
  136. package/web/.next/static/chunks/{7fb141141caa4fac.js → 515f0c0bd6087843.js} +5 -5
  137. package/web/.next/static/chunks/fd39dd62879495e1.css +1 -0
  138. package/web/.next/standalone/web/.next/server/chunks/ssr/web_08bbd8c8._.js +0 -7
  139. package/web/.next/standalone/web/.next/server/chunks/ssr/web_c729ad51._.js +0 -7
  140. package/web/.next/standalone/web/.next/static/chunks/1f42a42914068041.css +0 -1
  141. package/web/.next/standalone/web/.next/static/static/chunks/1f42a42914068041.css +0 -1
  142. package/web/.next/static/chunks/1f42a42914068041.css +0 -1
  143. /package/web/.next/standalone/web/.next/static/{9M2ys377uFtNH8BEy1_vL → UMGGmtMDTCI6fL-AIFkiM}/_buildManifest.js +0 -0
  144. /package/web/.next/standalone/web/.next/static/{9M2ys377uFtNH8BEy1_vL → UMGGmtMDTCI6fL-AIFkiM}/_clientMiddlewareManifest.json +0 -0
  145. /package/web/.next/standalone/web/.next/static/{9M2ys377uFtNH8BEy1_vL → UMGGmtMDTCI6fL-AIFkiM}/_ssgManifest.js +0 -0
  146. /package/web/.next/standalone/web/.next/static/static/{9M2ys377uFtNH8BEy1_vL → UMGGmtMDTCI6fL-AIFkiM}/_buildManifest.js +0 -0
  147. /package/web/.next/standalone/web/.next/static/static/{9M2ys377uFtNH8BEy1_vL → UMGGmtMDTCI6fL-AIFkiM}/_clientMiddlewareManifest.json +0 -0
  148. /package/web/.next/standalone/web/.next/static/static/{9M2ys377uFtNH8BEy1_vL → UMGGmtMDTCI6fL-AIFkiM}/_ssgManifest.js +0 -0
  149. /package/web/.next/static/{9M2ys377uFtNH8BEy1_vL → UMGGmtMDTCI6fL-AIFkiM}/_buildManifest.js +0 -0
  150. /package/web/.next/static/{9M2ys377uFtNH8BEy1_vL → UMGGmtMDTCI6fL-AIFkiM}/_clientMiddlewareManifest.json +0 -0
  151. /package/web/.next/static/{9M2ys377uFtNH8BEy1_vL → UMGGmtMDTCI6fL-AIFkiM}/_ssgManifest.js +0 -0
@@ -177,6 +177,36 @@ var init_config = __esm({
177
177
  });
178
178
 
179
179
  // src/db/remote.ts
180
+ var remote_exports = {};
181
+ __export(remote_exports, {
182
+ closeRemoteDatabase: () => closeRemoteDatabase,
183
+ initRemoteDatabase: () => initRemoteDatabase,
184
+ isRemoteConfigured: () => isRemoteConfigured,
185
+ remoteActiveStreamQueries: () => remoteActiveStreamQueries,
186
+ remoteCheckpointQueries: () => remoteCheckpointQueries,
187
+ remoteFileBackupQueries: () => remoteFileBackupQueries,
188
+ remoteIndexStatusQueries: () => remoteIndexStatusQueries,
189
+ remoteIndexedChunkQueries: () => remoteIndexedChunkQueries,
190
+ remoteMessageQueries: () => remoteMessageQueries,
191
+ remoteSessionQueries: () => remoteSessionQueries,
192
+ remoteSkillQueries: () => remoteSkillQueries,
193
+ remoteSubagentQueries: () => remoteSubagentQueries,
194
+ remoteTerminalQueries: () => remoteTerminalQueries,
195
+ remoteTodoQueries: () => remoteTodoQueries,
196
+ remoteToolExecutionQueries: () => remoteToolExecutionQueries,
197
+ storageQueries: () => storageQueries
198
+ });
199
+ function initRemoteDatabase(serverUrl, key) {
200
+ remoteServerUrl = serverUrl.replace(/\/$/, "");
201
+ authKey = key;
202
+ }
203
+ function closeRemoteDatabase() {
204
+ remoteServerUrl = null;
205
+ authKey = null;
206
+ }
207
+ function isRemoteConfigured() {
208
+ return !!remoteServerUrl && !!authKey;
209
+ }
180
210
  function parseDates(obj) {
181
211
  if (obj === null || obj === void 0) return obj;
182
212
  if (Array.isArray(obj)) return obj.map(parseDates);
@@ -224,7 +254,29 @@ async function api(path, options = {}) {
224
254
  }
225
255
  return parseDates(parsed);
226
256
  }
227
- var remoteServerUrl, authKey, DATE_FIELDS, MODEL_MESSAGE_FIELDS, remoteTodoQueries, remoteSkillQueries, remoteFileBackupQueries, remoteSubagentQueries, remoteIndexStatusQueries;
257
+ async function storageApi(path, options = {}) {
258
+ if (!remoteServerUrl || !authKey) {
259
+ throw new Error("Remote database not initialized");
260
+ }
261
+ const url = `${remoteServerUrl}/storage${path}`;
262
+ const init = {
263
+ method: options.method || "GET",
264
+ headers: {
265
+ "Content-Type": "application/json",
266
+ "Authorization": `Bearer ${authKey}`
267
+ }
268
+ };
269
+ if (options.body) {
270
+ init.body = JSON.stringify(options.body);
271
+ }
272
+ const response = await fetch(url, init);
273
+ if (!response.ok) {
274
+ const errorText = await response.text().catch(() => "Unknown error");
275
+ throw new Error(`Storage API error ${response.status}: ${errorText}`);
276
+ }
277
+ return response.json();
278
+ }
279
+ var remoteServerUrl, authKey, DATE_FIELDS, MODEL_MESSAGE_FIELDS, remoteSessionQueries, remoteMessageQueries, remoteToolExecutionQueries, remoteTodoQueries, remoteSkillQueries, remoteTerminalQueries, remoteActiveStreamQueries, remoteCheckpointQueries, remoteFileBackupQueries, remoteSubagentQueries, remoteIndexedChunkQueries, remoteIndexStatusQueries, storageQueries;
228
280
  var init_remote = __esm({
229
281
  "src/db/remote.ts"() {
230
282
  "use strict";
@@ -232,6 +284,103 @@ var init_remote = __esm({
232
284
  authKey = null;
233
285
  DATE_FIELDS = ["createdAt", "updatedAt", "startedAt", "completedAt", "stoppedAt", "finishedAt", "loadedAt", "indexedAt", "lastFullIndex", "lastIncrementalIndex"];
234
286
  MODEL_MESSAGE_FIELDS = ["modelMessage", "modelMessages"];
287
+ remoteSessionQueries = {
288
+ create(data) {
289
+ return api("/sessions", { method: "POST", body: data });
290
+ },
291
+ getById(id) {
292
+ return api(`/sessions/${id}`).catch(() => void 0);
293
+ },
294
+ list(limit = 50, offset = 0) {
295
+ return api(`/sessions?limit=${limit}&offset=${offset}`);
296
+ },
297
+ updateStatus(id, status) {
298
+ return api(`/sessions/${id}`, { method: "PATCH", body: { status } });
299
+ },
300
+ updateModel(id, model) {
301
+ return api(`/sessions/${id}`, { method: "PATCH", body: { model } });
302
+ },
303
+ update(id, updates) {
304
+ return api(`/sessions/${id}`, { method: "PATCH", body: updates });
305
+ },
306
+ delete(id) {
307
+ return api(`/sessions/${id}`, { method: "DELETE" }).then((r) => r?.success ?? false);
308
+ }
309
+ };
310
+ remoteMessageQueries = {
311
+ async getNextSequence(sessionId) {
312
+ const result = await api(`/messages/session/${sessionId}/next-sequence`);
313
+ return result.nextSequence;
314
+ },
315
+ create(sessionId, modelMessage) {
316
+ return api("/messages", { method: "POST", body: { sessionId, modelMessage } });
317
+ },
318
+ addMany(sessionId, modelMessages) {
319
+ return api("/messages/batch", { method: "POST", body: { sessionId, modelMessages } });
320
+ },
321
+ getBySession(sessionId) {
322
+ return api(`/messages/session/${sessionId}`);
323
+ },
324
+ getModelMessages(sessionId) {
325
+ return api(`/messages/session/${sessionId}/model-messages`, { skipParseDates: true });
326
+ },
327
+ async getRecentBySession(sessionId, limit = 50) {
328
+ const messages = await api(`/messages/session/${sessionId}`);
329
+ return messages.slice(-limit);
330
+ },
331
+ async countBySession(sessionId) {
332
+ const result = await api(`/messages/session/${sessionId}/count`);
333
+ return result.count;
334
+ },
335
+ async deleteBySession(sessionId) {
336
+ const result = await api(`/messages/session/${sessionId}`, { method: "DELETE" });
337
+ return result.deleted;
338
+ },
339
+ async deleteFromSequence(sessionId, fromSequence) {
340
+ const result = await api(
341
+ `/messages/session/${sessionId}/from-sequence/${fromSequence}`,
342
+ { method: "DELETE" }
343
+ );
344
+ return result.deleted;
345
+ }
346
+ };
347
+ remoteToolExecutionQueries = {
348
+ create(data) {
349
+ return api("/tool-executions", { method: "POST", body: data });
350
+ },
351
+ getById(id) {
352
+ return api(`/tool-executions/${id}`).catch(() => void 0);
353
+ },
354
+ getByToolCallId(toolCallId) {
355
+ return api(`/tool-executions/by-tool-call-id/${toolCallId}`).catch(() => void 0);
356
+ },
357
+ getPendingApprovals(sessionId) {
358
+ return api(`/tool-executions/session/${sessionId}/pending`);
359
+ },
360
+ approve(id) {
361
+ return api(`/tool-executions/${id}`, { method: "PATCH", body: { status: "approved" } });
362
+ },
363
+ reject(id) {
364
+ return api(`/tool-executions/${id}`, { method: "PATCH", body: { status: "rejected" } });
365
+ },
366
+ complete(id, output, error) {
367
+ return api(`/tool-executions/${id}`, {
368
+ method: "PATCH",
369
+ body: { status: error ? "error" : "completed", output, error }
370
+ });
371
+ },
372
+ getBySession(sessionId) {
373
+ return api(`/tool-executions/session/${sessionId}`);
374
+ },
375
+ async deleteAfterTime(sessionId, afterTime) {
376
+ const timestamp = afterTime instanceof Date ? afterTime.getTime() : new Date(afterTime).getTime();
377
+ const result = await api(
378
+ `/tool-executions/session/${sessionId}/after/${timestamp}`,
379
+ { method: "DELETE" }
380
+ );
381
+ return result.deleted;
382
+ }
383
+ };
235
384
  remoteTodoQueries = {
236
385
  create(data) {
237
386
  return api("/todos", { method: "POST", body: data });
@@ -266,6 +415,83 @@ var init_remote = __esm({
266
415
  return result.isLoaded;
267
416
  }
268
417
  };
418
+ remoteTerminalQueries = {
419
+ create(data) {
420
+ return api("/terminals", { method: "POST", body: data });
421
+ },
422
+ getById(id) {
423
+ return api(`/terminals/${id}`).catch(() => void 0);
424
+ },
425
+ getBySession(sessionId) {
426
+ return api(`/terminals/session/${sessionId}`);
427
+ },
428
+ getRunning(sessionId) {
429
+ return api(`/terminals/session/${sessionId}/running`);
430
+ },
431
+ updateStatus(id, status, exitCode, error) {
432
+ return api(`/terminals/${id}`, { method: "PATCH", body: { status, exitCode, error } });
433
+ },
434
+ updatePid(id, pid) {
435
+ return api(`/terminals/${id}`, { method: "PATCH", body: { pid } });
436
+ },
437
+ async delete(id) {
438
+ const result = await api(`/terminals/${id}`, { method: "DELETE" });
439
+ return result?.success ?? false;
440
+ },
441
+ async deleteBySession(sessionId) {
442
+ const result = await api(`/terminals/session/${sessionId}`, { method: "DELETE" });
443
+ return result.deleted;
444
+ }
445
+ };
446
+ remoteActiveStreamQueries = {
447
+ create(sessionId, streamId) {
448
+ return api("/streams", { method: "POST", body: { sessionId, streamId } });
449
+ },
450
+ getBySessionId(sessionId) {
451
+ return api(`/streams/session/${sessionId}`).then((r) => r ?? void 0);
452
+ },
453
+ getByStreamId(streamId) {
454
+ return api(`/streams/by-stream-id/${streamId}`).catch(() => void 0);
455
+ },
456
+ finish(streamId) {
457
+ return api(`/streams/by-stream-id/${streamId}`, { method: "PATCH", body: { status: "finished" } });
458
+ },
459
+ markError(streamId) {
460
+ return api(`/streams/by-stream-id/${streamId}`, { method: "PATCH", body: { status: "error" } });
461
+ },
462
+ async deleteBySession(sessionId) {
463
+ const result = await api(`/streams/session/${sessionId}`, { method: "DELETE" });
464
+ return result.deleted;
465
+ }
466
+ };
467
+ remoteCheckpointQueries = {
468
+ create(data) {
469
+ return api("/checkpoints", { method: "POST", body: data });
470
+ },
471
+ getById(id) {
472
+ return api(`/checkpoints/${id}`).catch(() => void 0);
473
+ },
474
+ getBySession(sessionId) {
475
+ return api(`/checkpoints/session/${sessionId}`);
476
+ },
477
+ getByMessageSequence(sessionId, messageSequence) {
478
+ return api(`/checkpoints/session/${sessionId}/by-sequence/${messageSequence}`).then((r) => r ?? void 0);
479
+ },
480
+ getLatest(sessionId) {
481
+ return api(`/checkpoints/session/${sessionId}/latest`).then((r) => r ?? void 0);
482
+ },
483
+ async deleteAfterSequence(sessionId, messageSequence) {
484
+ const result = await api(
485
+ `/checkpoints/session/${sessionId}/after-sequence/${messageSequence}`,
486
+ { method: "DELETE" }
487
+ );
488
+ return result.deleted;
489
+ },
490
+ async deleteBySession(sessionId) {
491
+ const result = await api(`/checkpoints/session/${sessionId}`, { method: "DELETE" });
492
+ return result.deleted;
493
+ }
494
+ };
269
495
  remoteFileBackupQueries = {
270
496
  create(data) {
271
497
  return api("/file-backups", { method: "POST", body: data });
@@ -320,6 +546,41 @@ var init_remote = __esm({
320
546
  return result.deleted;
321
547
  }
322
548
  };
549
+ remoteIndexedChunkQueries = {
550
+ upsert(_db, data) {
551
+ return api("/indexed-chunks", { method: "POST", body: data });
552
+ },
553
+ batchUpsert(_db, chunks) {
554
+ return api("/indexed-chunks/batch", {
555
+ method: "POST",
556
+ body: { chunks }
557
+ });
558
+ },
559
+ getById(_db, id) {
560
+ return api(`/indexed-chunks/${id}`).catch(() => void 0);
561
+ },
562
+ getByNamespace(_db, namespace) {
563
+ return api(`/indexed-chunks/namespace/${namespace}`);
564
+ },
565
+ getByFilePath(_db, namespace, filePath) {
566
+ return api(`/indexed-chunks/namespace/${namespace}/file/${encodeURIComponent(filePath)}`);
567
+ },
568
+ async deleteByNamespace(_db, namespace) {
569
+ const result = await api(`/indexed-chunks/namespace/${namespace}`, { method: "DELETE" });
570
+ return result.deleted;
571
+ },
572
+ async deleteByFilePath(_db, namespace, filePath) {
573
+ const result = await api(
574
+ `/indexed-chunks/namespace/${namespace}/file/${encodeURIComponent(filePath)}`,
575
+ { method: "DELETE" }
576
+ );
577
+ return result.deleted;
578
+ },
579
+ async countByNamespace(_db, namespace) {
580
+ const result = await api(`/indexed-chunks/namespace/${namespace}/count`);
581
+ return result.count;
582
+ }
583
+ };
323
584
  remoteIndexStatusQueries = {
324
585
  upsert(_db, data) {
325
586
  return api("/index-status", {
@@ -342,6 +603,27 @@ var init_remote = __esm({
342
603
  return api("/index-status");
343
604
  }
344
605
  };
606
+ storageQueries = {
607
+ async getUploadUrl(sessionId, fileName, contentType, category) {
608
+ return storageApi("/upload-url", {
609
+ method: "POST",
610
+ body: { sessionId, fileName, contentType, category }
611
+ });
612
+ },
613
+ async getSessionFiles(sessionId) {
614
+ const result = await storageApi(`/files/${sessionId}`);
615
+ return result.files;
616
+ },
617
+ async getDownloadUrl(fileId) {
618
+ return storageApi(`/download/${fileId}`);
619
+ },
620
+ async deleteFile(fileId) {
621
+ await storageApi(`/files/${fileId}`, { method: "DELETE" });
622
+ },
623
+ async updateFile(fileId, data) {
624
+ await storageApi(`/files/${fileId}`, { method: "PATCH", body: data });
625
+ }
626
+ };
345
627
  }
346
628
  });
347
629
 
@@ -1076,6 +1358,29 @@ function isBlockedCommand(command) {
1076
1358
  (blocked) => normalizedCommand.includes(blocked.toLowerCase())
1077
1359
  );
1078
1360
  }
1361
+ var BROWSER_STREAM_BASE_PORT = 9223;
1362
+ var sessionBrowserPorts = /* @__PURE__ */ new Map();
1363
+ var nextPortOffset = 0;
1364
+ function getBrowserStreamPort(sessionId) {
1365
+ let port = sessionBrowserPorts.get(sessionId);
1366
+ if (!port) {
1367
+ port = BROWSER_STREAM_BASE_PORT + nextPortOffset++;
1368
+ sessionBrowserPorts.set(sessionId, port);
1369
+ }
1370
+ return port;
1371
+ }
1372
+ function hasAgentBrowserCommand(command) {
1373
+ return /\bagent-browser\b/.test(command);
1374
+ }
1375
+ function isAgentBrowserCloseCommand(command) {
1376
+ return /\bagent-browser\s+(close|close\s+--all)\b/.test(command);
1377
+ }
1378
+ function injectBrowserStreamPort(command, port) {
1379
+ return command.replace(
1380
+ /\bagent-browser\b/g,
1381
+ `AGENT_BROWSER_STREAM_PORT=${port} agent-browser`
1382
+ );
1383
+ }
1079
1384
  var bashInputSchema = z2.object({
1080
1385
  command: z2.string().optional().describe("The command to execute. Required for running new commands."),
1081
1386
  background: z2.boolean().default(false).describe("Run the command in background mode (for dev servers, watchers). Returns immediately with terminal ID."),
@@ -1241,6 +1546,16 @@ Terminal output is stored in the global SparkECoder data directory. Use the \`ta
1241
1546
  exitCode: 1
1242
1547
  };
1243
1548
  }
1549
+ let actualCommand = command;
1550
+ const hasAgentBrowser = hasAgentBrowserCommand(command);
1551
+ const browserClose = isAgentBrowserCloseCommand(command);
1552
+ let browserPort;
1553
+ if (hasAgentBrowser) {
1554
+ browserPort = getBrowserStreamPort(options.sessionId);
1555
+ if (!browserClose) {
1556
+ actualCommand = injectBrowserStreamPort(command, browserPort);
1557
+ }
1558
+ }
1244
1559
  const canUseTmux = await shouldUseTmux();
1245
1560
  if (background) {
1246
1561
  if (!canUseTmux) {
@@ -1250,8 +1565,8 @@ Terminal output is stored in the global SparkECoder data directory. Use the \`ta
1250
1565
  };
1251
1566
  }
1252
1567
  const terminalId = generateTerminalId();
1253
- options.onProgress?.({ terminalId, status: "started", command });
1254
- const result = await runBackground(command, options.workingDirectory, {
1568
+ options.onProgress?.({ terminalId, status: "started", command, browserStreamPort: browserPort });
1569
+ const result = await runBackground(actualCommand, options.workingDirectory, {
1255
1570
  sessionId: options.sessionId,
1256
1571
  terminalId
1257
1572
  });
@@ -1264,16 +1579,22 @@ Terminal output is stored in the global SparkECoder data directory. Use the \`ta
1264
1579
  }
1265
1580
  if (canUseTmux) {
1266
1581
  const terminalId = generateTerminalId();
1267
- options.onProgress?.({ terminalId, status: "started", command });
1582
+ options.onProgress?.({ terminalId, status: "started", command, browserStreamPort: browserPort });
1268
1583
  try {
1269
- const result = await runSync(command, options.workingDirectory, {
1584
+ const result = await runSync(actualCommand, options.workingDirectory, {
1270
1585
  sessionId: options.sessionId,
1271
1586
  timeout: COMMAND_TIMEOUT,
1272
1587
  terminalId
1273
1588
  });
1274
1589
  const truncatedOutput = truncateOutput(result.output, MAX_OUTPUT_CHARS2);
1275
1590
  options.onOutput?.(truncatedOutput);
1276
- options.onProgress?.({ terminalId, status: "completed", command });
1591
+ options.onProgress?.({
1592
+ terminalId,
1593
+ status: "completed",
1594
+ command,
1595
+ browserStreamPort: browserPort,
1596
+ browserClosed: browserClose || void 0
1597
+ });
1277
1598
  return {
1278
1599
  success: result.exitCode === 0,
1279
1600
  id: result.id,
@@ -1291,7 +1612,7 @@ Terminal output is stored in the global SparkECoder data directory. Use the \`ta
1291
1612
  };
1292
1613
  }
1293
1614
  } else {
1294
- const result = await execFallback(command, options.workingDirectory, options.onOutput);
1615
+ const result = await execFallback(actualCommand, options.workingDirectory, options.onOutput);
1295
1616
  return {
1296
1617
  success: result.success,
1297
1618
  output: result.output,
@@ -4302,8 +4623,106 @@ function createTaskFailedTool(options) {
4302
4623
  });
4303
4624
  }
4304
4625
 
4626
+ // src/tools/upload-file.ts
4627
+ import { tool as tool12 } from "ai";
4628
+ import { z as z13 } from "zod";
4629
+ import { readFile as readFile9, stat as stat4 } from "fs/promises";
4630
+ import { join as join5, basename as basename4, extname as extname7 } from "path";
4631
+ var MIME_TYPES = {
4632
+ ".txt": "text/plain",
4633
+ ".md": "text/markdown",
4634
+ ".html": "text/html",
4635
+ ".css": "text/css",
4636
+ ".js": "application/javascript",
4637
+ ".ts": "application/typescript",
4638
+ ".json": "application/json",
4639
+ ".csv": "text/csv",
4640
+ ".xml": "application/xml",
4641
+ ".pdf": "application/pdf",
4642
+ ".png": "image/png",
4643
+ ".jpg": "image/jpeg",
4644
+ ".jpeg": "image/jpeg",
4645
+ ".gif": "image/gif",
4646
+ ".webp": "image/webp",
4647
+ ".svg": "image/svg+xml",
4648
+ ".mp4": "video/mp4",
4649
+ ".webm": "video/webm",
4650
+ ".mp3": "audio/mpeg",
4651
+ ".wav": "audio/wav",
4652
+ ".zip": "application/zip",
4653
+ ".tar": "application/x-tar",
4654
+ ".gz": "application/gzip"
4655
+ };
4656
+ function createUploadFileTool(options) {
4657
+ return tool12({
4658
+ description: `Upload a file to cloud storage and get back a shareable download URL. Use this when the user needs a hosted link to a file (e.g. a generated report, image, export, or any artifact they want to download or share). The file must already exist on disk.`,
4659
+ inputSchema: z13.object({
4660
+ path: z13.string().describe("Path to the file to upload (relative to working directory or absolute)"),
4661
+ name: z13.string().optional().describe("Display name for the file (defaults to the filename)")
4662
+ }),
4663
+ execute: async (input) => {
4664
+ try {
4665
+ const { isRemoteConfigured: isRemoteConfigured2, storageQueries: storageQueries2 } = await Promise.resolve().then(() => (init_remote(), remote_exports));
4666
+ if (!isRemoteConfigured2()) {
4667
+ return {
4668
+ success: false,
4669
+ error: "File upload is not available \u2014 remote server with GCS is not configured."
4670
+ };
4671
+ }
4672
+ const fullPath = input.path.startsWith("/") ? input.path : join5(options.workingDirectory, input.path);
4673
+ try {
4674
+ await stat4(fullPath);
4675
+ } catch {
4676
+ return {
4677
+ success: false,
4678
+ error: `File not found: ${input.path}`
4679
+ };
4680
+ }
4681
+ const fileName = input.name || basename4(fullPath);
4682
+ const ext = extname7(fullPath).toLowerCase();
4683
+ const contentType = MIME_TYPES[ext] || "application/octet-stream";
4684
+ const uploadInfo = await storageQueries2.getUploadUrl(
4685
+ options.sessionId,
4686
+ fileName,
4687
+ contentType,
4688
+ "general"
4689
+ );
4690
+ const fileData = await readFile9(fullPath);
4691
+ const putRes = await fetch(uploadInfo.uploadUrl, {
4692
+ method: "PUT",
4693
+ headers: { "Content-Type": contentType },
4694
+ body: fileData
4695
+ });
4696
+ if (!putRes.ok) {
4697
+ return {
4698
+ success: false,
4699
+ error: `Upload failed: ${putRes.status} ${putRes.statusText}`
4700
+ };
4701
+ }
4702
+ await storageQueries2.updateFile(uploadInfo.fileId, { sizeBytes: fileData.length });
4703
+ const downloadInfo = await storageQueries2.getDownloadUrl(uploadInfo.fileId);
4704
+ return {
4705
+ success: true,
4706
+ fileId: uploadInfo.fileId,
4707
+ fileName,
4708
+ sizeBytes: fileData.length,
4709
+ contentType,
4710
+ downloadUrl: downloadInfo.downloadUrl,
4711
+ expiresAt: downloadInfo.expiresAt
4712
+ };
4713
+ } catch (err) {
4714
+ return {
4715
+ success: false,
4716
+ error: `Upload failed: ${err.message}`
4717
+ };
4718
+ }
4719
+ }
4720
+ });
4721
+ }
4722
+
4305
4723
  // src/tools/index.ts
4306
4724
  init_semantic();
4725
+ init_remote();
4307
4726
  init_semantic_search();
4308
4727
  async function createTools(options) {
4309
4728
  const tools = {
@@ -4341,6 +4760,12 @@ async function createTools(options) {
4341
4760
  workingDirectory: options.workingDirectory
4342
4761
  })
4343
4762
  };
4763
+ if (isRemoteConfigured()) {
4764
+ tools.upload_file = createUploadFileTool({
4765
+ workingDirectory: options.workingDirectory,
4766
+ sessionId: options.sessionId
4767
+ });
4768
+ }
4344
4769
  if (options.enableSemanticSearch !== false) {
4345
4770
  try {
4346
4771
  if (isVectorGatewayConfigured()) {
@@ -4372,6 +4797,7 @@ export {
4372
4797
  createTaskFailedTool,
4373
4798
  createTodoTool,
4374
4799
  createTools,
4800
+ createUploadFileTool,
4375
4801
  createWriteFileTool
4376
4802
  };
4377
4803
  //# sourceMappingURL=index.js.map