sparkecoder 0.1.44 → 0.1.46

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 (184) hide show
  1. package/README.md +1 -1
  2. package/dist/agent/index.d.ts +2 -2
  3. package/dist/agent/index.js +153 -4
  4. package/dist/agent/index.js.map +1 -1
  5. package/dist/cli.js +209 -22
  6. package/dist/cli.js.map +1 -1
  7. package/dist/db/index.js +11 -3
  8. package/dist/db/index.js.map +1 -1
  9. package/dist/{index-D2eLXP9V.d.ts → index-DJ5qNs1Z.d.ts} +9 -5
  10. package/dist/index.d.ts +3 -3
  11. package/dist/index.js +210 -21
  12. package/dist/index.js.map +1 -1
  13. package/dist/{search-D3Wtf7TJ.d.ts → search-BOYIUmDp.d.ts} +1 -1
  14. package/dist/server/index.js +208 -21
  15. package/dist/server/index.js.map +1 -1
  16. package/dist/tools/index.d.ts +2 -2
  17. package/dist/tools/index.js +11 -3
  18. package/dist/tools/index.js.map +1 -1
  19. package/package.json +1 -1
  20. package/web/.next/BUILD_ID +1 -1
  21. package/web/.next/standalone/web/.next/BUILD_ID +1 -1
  22. package/web/.next/standalone/web/.next/build-manifest.json +2 -2
  23. package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
  24. package/web/.next/standalone/web/.next/server/app/(main)/page.js.nft.json +1 -1
  25. package/web/.next/standalone/web/.next/server/app/(main)/page_client-reference-manifest.js +1 -1
  26. package/web/.next/standalone/web/.next/server/app/(main)/session/[id]/page.js.nft.json +1 -1
  27. package/web/.next/standalone/web/.next/server/app/(main)/session/[id]/page_client-reference-manifest.js +1 -1
  28. package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
  29. package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
  30. package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  31. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  32. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  33. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  34. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  35. package/web/.next/standalone/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  36. package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
  37. package/web/.next/standalone/web/.next/server/app/_not-found.rsc +3 -3
  38. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  39. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  40. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  41. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  42. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  43. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  44. package/web/.next/standalone/web/.next/server/app/docs/installation/page_client-reference-manifest.js +1 -1
  45. package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
  46. package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +4 -4
  47. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +4 -4
  48. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
  49. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +3 -3
  50. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +2 -2
  51. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +2 -2
  52. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
  53. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +2 -2
  54. package/web/.next/standalone/web/.next/server/app/docs/page_client-reference-manifest.js +1 -1
  55. package/web/.next/standalone/web/.next/server/app/docs/skills/page_client-reference-manifest.js +1 -1
  56. package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
  57. package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +4 -4
  58. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +4 -4
  59. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
  60. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +3 -3
  61. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +2 -2
  62. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
  63. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
  64. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +2 -2
  65. package/web/.next/standalone/web/.next/server/app/docs/tools/page_client-reference-manifest.js +1 -1
  66. package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
  67. package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +4 -4
  68. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +4 -4
  69. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
  70. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +3 -3
  71. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +2 -2
  72. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +2 -2
  73. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
  74. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +2 -2
  75. package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
  76. package/web/.next/standalone/web/.next/server/app/docs.rsc +4 -4
  77. package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +4 -4
  78. package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
  79. package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +3 -3
  80. package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +2 -2
  81. package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +2 -2
  82. package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +2 -2
  83. package/web/.next/standalone/web/.next/server/app/embed/[id]/page.js.nft.json +1 -1
  84. package/web/.next/standalone/web/.next/server/app/embed/[id]/page_client-reference-manifest.js +1 -1
  85. package/web/.next/standalone/web/.next/server/app/index.html +1 -1
  86. package/web/.next/standalone/web/.next/server/app/index.rsc +5 -5
  87. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +2 -2
  88. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +2 -2
  89. package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +5 -5
  90. package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
  91. package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +3 -3
  92. package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  93. package/web/.next/standalone/web/.next/server/chunks/[root-of-the-server]__36edac7c._.js +1 -1
  94. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_85c176b8._.js → 2374f_13da7b2a._.js} +1 -1
  95. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_3eca1553._.js → 2374f_1de2f628._.js} +1 -1
  96. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_8b8baaa3._.js → 2374f_2bfcd3a2._.js} +1 -1
  97. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_0146c9df._.js → 2374f_40c1da73._.js} +1 -1
  98. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_b30bed04._.js → 2374f_41d07cce._.js} +1 -1
  99. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_4d1accac._.js → 2374f_6d8e5e94._.js} +1 -1
  100. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_c99180da._.js → 2374f_88aa1671._.js} +1 -1
  101. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_147b1db0._.js → 2374f_9f2fae06._.js} +1 -1
  102. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_98432ce4._.js → 2374f_ac79ddf4._.js} +1 -1
  103. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_36dd81aa._.js → 2374f_c8f8a326._.js} +1 -1
  104. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_bcffd98c._.js → 2374f_dd21a4e9._.js} +1 -1
  105. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_dde5cdd9._.js → 2374f_e5142825._.js} +1 -1
  106. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_4b3676c4._.js → 2374f_ec658806._.js} +1 -1
  107. package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_f5998fca._.js → 2374f_f3c65774._.js} +1 -1
  108. package/web/.next/standalone/web/.next/server/chunks/ssr/[root-of-the-server]__43405ad6._.js +3 -0
  109. package/web/.next/standalone/web/.next/server/chunks/ssr/{[root-of-the-server]__adf39cf8._.js → [root-of-the-server]__a87e1c27._.js} +6 -4
  110. package/web/.next/standalone/web/.next/server/chunks/ssr/[root-of-the-server]__be5e2967._.js +1 -1
  111. package/web/.next/standalone/web/.next/server/chunks/ssr/[root-of-the-server]__de76483d._.js +1 -1
  112. package/web/.next/standalone/web/.next/server/chunks/ssr/{web_76f53fe7._.js → web_273500a6._.js} +2 -2
  113. package/web/.next/standalone/web/.next/server/chunks/ssr/{web_76ccf09f._.js → web_2b3a5919._.js} +2 -2
  114. package/web/.next/standalone/web/.next/server/chunks/ssr/{web_633d8a33._.js → web_329773d1._.js} +2 -2
  115. package/web/.next/standalone/web/.next/server/chunks/ssr/{web_248fc1f2._.js → web_38156da8._.js} +2 -2
  116. package/web/.next/standalone/web/.next/server/chunks/ssr/web_8305f089._.js +7 -0
  117. package/web/.next/standalone/web/.next/server/chunks/ssr/web_src_app_(main)_page_tsx_5ac4794b._.js +1 -1
  118. package/web/.next/standalone/web/.next/server/chunks/ssr/web_src_components_sessions-sidebar_tsx_92510070._.js +1 -1
  119. package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
  120. package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
  121. package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
  122. package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
  123. package/web/.next/standalone/web/.next/static/{static/chunks/194b3ed8e8d9c0e9.js → chunks/294ebe8457006bce.js} +3 -3
  124. package/web/.next/standalone/web/.next/static/chunks/{23aa98f6e3d7e0e4.js → 7e48d04fbd6dd7a6.js} +5 -3
  125. package/web/.next/standalone/web/.next/static/{static/chunks/1e9fdac31c7fd474.js → chunks/81685e5e8be4eac9.js} +3 -3
  126. package/web/.next/{static/chunks/3425251cd978da61.js → standalone/web/.next/static/chunks/8d3efc76109d2efc.js} +1 -1
  127. package/web/.next/standalone/web/.next/static/chunks/96ec96279ada0efe.js +1 -0
  128. package/web/.next/standalone/web/.next/static/chunks/b31b0765abe0c427.js +1 -0
  129. package/web/.next/standalone/web/.next/static/{static/chunks/c06faa5848e3b0b3.js → chunks/b7d722dab2a7ecc0.js} +1 -1
  130. package/web/.next/standalone/web/.next/static/chunks/cc6d43f798bbe415.js +5 -0
  131. package/web/.next/standalone/web/.next/static/chunks/de300ff10b63be85.css +1 -0
  132. package/web/.next/standalone/web/.next/static/chunks/de71e63276f488bb.js +7 -0
  133. package/web/.next/standalone/web/.next/static/{chunks/194b3ed8e8d9c0e9.js → static/chunks/294ebe8457006bce.js} +3 -3
  134. package/web/.next/standalone/web/.next/static/static/chunks/{23aa98f6e3d7e0e4.js → 7e48d04fbd6dd7a6.js} +5 -3
  135. package/web/.next/{static/chunks/1e9fdac31c7fd474.js → standalone/web/.next/static/static/chunks/81685e5e8be4eac9.js} +3 -3
  136. package/web/.next/standalone/web/.next/static/{chunks/3425251cd978da61.js → static/chunks/8d3efc76109d2efc.js} +1 -1
  137. package/web/.next/standalone/web/.next/static/static/chunks/96ec96279ada0efe.js +1 -0
  138. package/web/.next/standalone/web/.next/static/static/chunks/b31b0765abe0c427.js +1 -0
  139. package/web/.next/{static/chunks/c06faa5848e3b0b3.js → standalone/web/.next/static/static/chunks/b7d722dab2a7ecc0.js} +1 -1
  140. package/web/.next/standalone/web/.next/static/static/chunks/cc6d43f798bbe415.js +5 -0
  141. package/web/.next/standalone/web/.next/static/static/chunks/de300ff10b63be85.css +1 -0
  142. package/web/.next/standalone/web/.next/static/static/chunks/de71e63276f488bb.js +7 -0
  143. package/web/.next/standalone/web/src/app/(main)/page.tsx +2 -2
  144. package/web/.next/standalone/web/src/app/api/config/route.ts +3 -2
  145. package/web/.next/standalone/web/src/components/chat-interface.tsx +324 -37
  146. package/web/.next/standalone/web/src/components/sessions-sidebar.tsx +1 -1
  147. package/web/.next/standalone/web/src/lib/api.ts +3 -0
  148. package/web/.next/standalone/web/src/lib/config.ts +2 -1
  149. package/web/.next/static/chunks/{194b3ed8e8d9c0e9.js → 294ebe8457006bce.js} +3 -3
  150. package/web/.next/static/chunks/{23aa98f6e3d7e0e4.js → 7e48d04fbd6dd7a6.js} +5 -3
  151. package/web/.next/{standalone/web/.next/static/chunks/1e9fdac31c7fd474.js → static/chunks/81685e5e8be4eac9.js} +3 -3
  152. package/web/.next/{standalone/web/.next/static/static/chunks/3425251cd978da61.js → static/chunks/8d3efc76109d2efc.js} +1 -1
  153. package/web/.next/static/chunks/96ec96279ada0efe.js +1 -0
  154. package/web/.next/static/chunks/b31b0765abe0c427.js +1 -0
  155. package/web/.next/{standalone/web/.next/static/chunks/c06faa5848e3b0b3.js → static/chunks/b7d722dab2a7ecc0.js} +1 -1
  156. package/web/.next/static/chunks/cc6d43f798bbe415.js +5 -0
  157. package/web/.next/static/chunks/de300ff10b63be85.css +1 -0
  158. package/web/.next/static/chunks/de71e63276f488bb.js +7 -0
  159. package/web/.next/standalone/web/.next/server/chunks/ssr/[root-of-the-server]__9d3fe3b4._.js +0 -3
  160. package/web/.next/standalone/web/.next/server/chunks/ssr/web_631133e0._.js +0 -7
  161. package/web/.next/standalone/web/.next/static/chunks/2110d26bc24ed542.js +0 -1
  162. package/web/.next/standalone/web/.next/static/chunks/4fe97b7866eacdcf.js +0 -7
  163. package/web/.next/standalone/web/.next/static/chunks/7c000de1a1357775.css +0 -1
  164. package/web/.next/standalone/web/.next/static/chunks/a895d50f76a48e6e.js +0 -1
  165. package/web/.next/standalone/web/.next/static/chunks/dccaa0e6b27241a5.js +0 -5
  166. package/web/.next/standalone/web/.next/static/static/chunks/2110d26bc24ed542.js +0 -1
  167. package/web/.next/standalone/web/.next/static/static/chunks/4fe97b7866eacdcf.js +0 -7
  168. package/web/.next/standalone/web/.next/static/static/chunks/7c000de1a1357775.css +0 -1
  169. package/web/.next/standalone/web/.next/static/static/chunks/a895d50f76a48e6e.js +0 -1
  170. package/web/.next/standalone/web/.next/static/static/chunks/dccaa0e6b27241a5.js +0 -5
  171. package/web/.next/static/chunks/2110d26bc24ed542.js +0 -1
  172. package/web/.next/static/chunks/4fe97b7866eacdcf.js +0 -7
  173. package/web/.next/static/chunks/7c000de1a1357775.css +0 -1
  174. package/web/.next/static/chunks/a895d50f76a48e6e.js +0 -1
  175. package/web/.next/static/chunks/dccaa0e6b27241a5.js +0 -5
  176. /package/web/.next/standalone/web/.next/static/{mUwpFRyqjpPrLQ3DS2i5G → _0-MmiObGsO5iLpf0Qgmw}/_buildManifest.js +0 -0
  177. /package/web/.next/standalone/web/.next/static/{mUwpFRyqjpPrLQ3DS2i5G → _0-MmiObGsO5iLpf0Qgmw}/_clientMiddlewareManifest.json +0 -0
  178. /package/web/.next/standalone/web/.next/static/{mUwpFRyqjpPrLQ3DS2i5G → _0-MmiObGsO5iLpf0Qgmw}/_ssgManifest.js +0 -0
  179. /package/web/.next/standalone/web/.next/static/static/{mUwpFRyqjpPrLQ3DS2i5G → _0-MmiObGsO5iLpf0Qgmw}/_buildManifest.js +0 -0
  180. /package/web/.next/standalone/web/.next/static/static/{mUwpFRyqjpPrLQ3DS2i5G → _0-MmiObGsO5iLpf0Qgmw}/_clientMiddlewareManifest.json +0 -0
  181. /package/web/.next/standalone/web/.next/static/static/{mUwpFRyqjpPrLQ3DS2i5G → _0-MmiObGsO5iLpf0Qgmw}/_ssgManifest.js +0 -0
  182. /package/web/.next/static/{mUwpFRyqjpPrLQ3DS2i5G → _0-MmiObGsO5iLpf0Qgmw}/_buildManifest.js +0 -0
  183. /package/web/.next/static/{mUwpFRyqjpPrLQ3DS2i5G → _0-MmiObGsO5iLpf0Qgmw}/_clientMiddlewareManifest.json +0 -0
  184. /package/web/.next/static/{mUwpFRyqjpPrLQ3DS2i5G → _0-MmiObGsO5iLpf0Qgmw}/_ssgManifest.js +0 -0
package/dist/cli.js CHANGED
@@ -85,7 +85,7 @@ var init_types = __esm({
85
85
  }).optional();
86
86
  SparkcoderConfigSchema = z.object({
87
87
  // Default model to use (Vercel AI Gateway format)
88
- defaultModel: z.string().default("anthropic/claude-opus-4-5"),
88
+ defaultModel: z.string().default("anthropic/claude-opus-4-6"),
89
89
  // Working directory for file operations
90
90
  workingDirectory: z.string().optional(),
91
91
  // Tool approval settings
@@ -487,12 +487,16 @@ function closeRemoteDatabase() {
487
487
  authKey = null;
488
488
  }
489
489
  var DATE_FIELDS = ["createdAt", "updatedAt", "startedAt", "completedAt", "stoppedAt", "finishedAt", "loadedAt", "indexedAt", "lastFullIndex", "lastIncrementalIndex"];
490
+ var MODEL_MESSAGE_FIELDS = ["modelMessage", "modelMessages"];
490
491
  function parseDates(obj) {
491
492
  if (obj === null || obj === void 0) return obj;
492
493
  if (Array.isArray(obj)) return obj.map(parseDates);
493
- if (typeof obj !== "object") return obj;
494
+ if (typeof obj !== "object" || obj instanceof Date) return obj;
494
495
  const result = { ...obj };
495
496
  for (const key of Object.keys(result)) {
497
+ if (MODEL_MESSAGE_FIELDS.includes(key)) {
498
+ continue;
499
+ }
496
500
  if (DATE_FIELDS.includes(key) && typeof result[key] === "string") {
497
501
  result[key] = new Date(result[key]);
498
502
  } else if (typeof result[key] === "object") {
@@ -525,7 +529,11 @@ async function api(path, options = {}) {
525
529
  if (!text || text === "null") {
526
530
  return null;
527
531
  }
528
- return parseDates(JSON.parse(text));
532
+ const parsed = JSON.parse(text);
533
+ if (options.skipParseDates) {
534
+ return parsed;
535
+ }
536
+ return parseDates(parsed);
529
537
  }
530
538
  var remoteSessionQueries = {
531
539
  create(data) {
@@ -565,7 +573,7 @@ var remoteMessageQueries = {
565
573
  return api(`/messages/session/${sessionId}`);
566
574
  },
567
575
  getModelMessages(sessionId) {
568
- return api(`/messages/session/${sessionId}/model-messages`);
576
+ return api(`/messages/session/${sessionId}/model-messages`, { skipParseDates: true });
569
577
  },
570
578
  async getRecentBySession(sessionId, limit = 50) {
571
579
  const messages = await api(`/messages/session/${sessionId}`);
@@ -1105,7 +1113,7 @@ function requiresApproval(toolName, sessionConfig) {
1105
1113
  }
1106
1114
  function createDefaultConfig() {
1107
1115
  return {
1108
- defaultModel: "anthropic/claude-opus-4-5",
1116
+ defaultModel: "anthropic/claude-opus-4-6",
1109
1117
  // workingDirectory is intentionally not set - defaults to where CLI is run
1110
1118
  toolApprovals: {
1111
1119
  bash: true,
@@ -5277,6 +5285,142 @@ ${conversationHistory}
5277
5285
  Summary:`;
5278
5286
  }
5279
5287
 
5288
+ // src/utils/sanitize-messages.ts
5289
+ import { modelMessageSchema } from "ai";
5290
+ function convertDatesToStrings(value) {
5291
+ if (value === null || value === void 0) return value;
5292
+ if (value instanceof Date) return value.toISOString();
5293
+ if (Array.isArray(value)) return value.map(convertDatesToStrings);
5294
+ if (typeof value === "object") {
5295
+ const result = {};
5296
+ for (const [k, v] of Object.entries(value)) {
5297
+ result[k] = convertDatesToStrings(v);
5298
+ }
5299
+ return result;
5300
+ }
5301
+ return value;
5302
+ }
5303
+ function sanitizeMessage(msg) {
5304
+ if (msg === null || msg === void 0 || typeof msg !== "object") return msg;
5305
+ const message = msg;
5306
+ if (!message.role || typeof message.role !== "string") return msg;
5307
+ return convertDatesToStrings(message);
5308
+ }
5309
+ function mergeUserContent(a, b) {
5310
+ const aIsString = typeof a === "string";
5311
+ const bIsString = typeof b === "string";
5312
+ if (aIsString && bIsString) {
5313
+ return `${a}
5314
+
5315
+ ${b}`;
5316
+ }
5317
+ const aParts = aIsString ? [{ type: "text", text: a }] : Array.isArray(a) ? a : [];
5318
+ const bParts = bIsString ? [{ type: "text", text: b }] : Array.isArray(b) ? b : [];
5319
+ return [...aParts, ...bParts];
5320
+ }
5321
+ function mergeConsecutiveSameRole(messages) {
5322
+ if (messages.length <= 1) return messages;
5323
+ const merged = [];
5324
+ for (const msg of messages) {
5325
+ const prev = merged[merged.length - 1];
5326
+ if (!prev || prev.role !== msg.role) {
5327
+ merged.push(msg);
5328
+ continue;
5329
+ }
5330
+ const role = msg.role;
5331
+ if (role === "user") {
5332
+ const mergedContent = mergeUserContent(prev.content, msg.content);
5333
+ merged[merged.length - 1] = { role: "user", content: mergedContent };
5334
+ console.warn("[sanitize-messages] Merged consecutive user messages");
5335
+ } else if (role === "assistant") {
5336
+ const prevParts = typeof prev.content === "string" ? [{ type: "text", text: prev.content }] : Array.isArray(prev.content) ? prev.content : [];
5337
+ const curParts = typeof msg.content === "string" ? [{ type: "text", text: msg.content }] : Array.isArray(msg.content) ? msg.content : [];
5338
+ merged[merged.length - 1] = { role: "assistant", content: [...prevParts, ...curParts] };
5339
+ console.warn("[sanitize-messages] Merged consecutive assistant messages");
5340
+ } else if (role === "tool") {
5341
+ const prevContent = Array.isArray(prev.content) ? prev.content : [];
5342
+ const curContent = Array.isArray(msg.content) ? msg.content : [];
5343
+ merged[merged.length - 1] = { role: "tool", content: [...prevContent, ...curContent] };
5344
+ console.warn("[sanitize-messages] Merged consecutive tool messages");
5345
+ } else {
5346
+ merged.push(msg);
5347
+ }
5348
+ }
5349
+ return merged;
5350
+ }
5351
+ function sanitizeModelMessages(messages) {
5352
+ let allValid = true;
5353
+ for (const msg of messages) {
5354
+ try {
5355
+ modelMessageSchema.parse(msg);
5356
+ } catch {
5357
+ allValid = false;
5358
+ break;
5359
+ }
5360
+ }
5361
+ let result;
5362
+ if (allValid) {
5363
+ result = messages;
5364
+ } else {
5365
+ console.warn("[sanitize-messages] Detected invalid messages, attempting self-repair...");
5366
+ const sanitized = [];
5367
+ let repairCount = 0;
5368
+ for (let i = 0; i < messages.length; i++) {
5369
+ const msg = messages[i];
5370
+ try {
5371
+ modelMessageSchema.parse(msg);
5372
+ sanitized.push(msg);
5373
+ continue;
5374
+ } catch {
5375
+ }
5376
+ const fixed = sanitizeMessage(msg);
5377
+ try {
5378
+ modelMessageSchema.parse(fixed);
5379
+ sanitized.push(fixed);
5380
+ repairCount++;
5381
+ console.warn(`[sanitize-messages] Repaired message ${i} (role=${msg.role}) - converted Date objects to strings`);
5382
+ continue;
5383
+ } catch {
5384
+ }
5385
+ if (msg.role === "tool" && Array.isArray(msg.content)) {
5386
+ const fixedContent = msg.content.map((part) => {
5387
+ if (part.type === "tool-result" && part.output !== void 0) {
5388
+ const output = convertDatesToStrings(part.output);
5389
+ if (output && typeof output === "object" && !output.type) {
5390
+ return { ...part, output: { type: "json", value: output } };
5391
+ }
5392
+ const knownTypes = ["text", "json", "execution-denied", "error-text", "error-json", "content"];
5393
+ if (output && typeof output === "object" && !knownTypes.includes(output.type)) {
5394
+ return { ...part, output: { type: "json", value: output } };
5395
+ }
5396
+ return { ...part, output };
5397
+ }
5398
+ return convertDatesToStrings(part);
5399
+ });
5400
+ const wrappedMsg = { ...msg, content: fixedContent };
5401
+ try {
5402
+ modelMessageSchema.parse(wrappedMsg);
5403
+ sanitized.push(wrappedMsg);
5404
+ repairCount++;
5405
+ console.warn(`[sanitize-messages] Repaired message ${i} (role=tool) - wrapped raw output in json type`);
5406
+ continue;
5407
+ } catch {
5408
+ }
5409
+ }
5410
+ console.error(
5411
+ `[sanitize-messages] Could not repair message ${i} (role=${msg.role}). Message will be included as-is. Content keys: ${JSON.stringify(Object.keys(msg))}`
5412
+ );
5413
+ sanitized.push(msg);
5414
+ }
5415
+ if (repairCount > 0) {
5416
+ console.warn(`[sanitize-messages] Self-repair complete: fixed ${repairCount}/${messages.length} messages`);
5417
+ }
5418
+ result = sanitized;
5419
+ }
5420
+ result = mergeConsecutiveSameRole(result);
5421
+ return result;
5422
+ }
5423
+
5280
5424
  // src/agent/context.ts
5281
5425
  var ContextManager = class {
5282
5426
  sessionId;
@@ -5293,9 +5437,14 @@ var ContextManager = class {
5293
5437
  /**
5294
5438
  * Get messages for the current context
5295
5439
  * Returns ModelMessage[] that can be passed directly to streamText/generateText
5440
+ *
5441
+ * Includes self-repair: if messages from the database have been corrupted
5442
+ * (e.g., Date objects in tool outputs from parseDates), they are automatically
5443
+ * sanitized to conform to the AI SDK's ModelMessage schema.
5296
5444
  */
5297
5445
  async getMessages() {
5298
5446
  let modelMessages = await messageQueries.getModelMessages(this.sessionId);
5447
+ modelMessages = sanitizeModelMessages(modelMessages);
5299
5448
  const contextSize = calculateContextSize(modelMessages);
5300
5449
  if (this.autoSummarize && contextSize > this.maxContextChars) {
5301
5450
  modelMessages = await this.summarizeContext(modelMessages);
@@ -5722,10 +5871,27 @@ ${prompt}` });
5722
5871
  }
5723
5872
  };
5724
5873
 
5874
+ // src/server/devtools-store.ts
5875
+ var devtoolsContextStore = /* @__PURE__ */ new Map();
5876
+ function setDevtoolsContext(sessionId, context) {
5877
+ devtoolsContextStore.set(sessionId, context);
5878
+ }
5879
+ function getDevtoolsContext(sessionId) {
5880
+ cleanupStaleContexts();
5881
+ return devtoolsContextStore.get(sessionId) || null;
5882
+ }
5883
+ function cleanupStaleContexts() {
5884
+ const now = Date.now();
5885
+ for (const [sessionId, ctx] of devtoolsContextStore) {
5886
+ if (now - ctx.lastHeartbeat.getTime() > 30 * 1e3) {
5887
+ devtoolsContextStore.delete(sessionId);
5888
+ }
5889
+ }
5890
+ }
5891
+
5725
5892
  // src/server/routes/sessions.ts
5726
5893
  var sessions = new Hono();
5727
5894
  var pendingInputStore = /* @__PURE__ */ new Map();
5728
- var devtoolsContextStore = /* @__PURE__ */ new Map();
5729
5895
  function cleanupPendingInputs() {
5730
5896
  const now = Date.now();
5731
5897
  for (const [sessionId, entry] of pendingInputStore) {
@@ -5734,14 +5900,6 @@ function cleanupPendingInputs() {
5734
5900
  }
5735
5901
  }
5736
5902
  }
5737
- function cleanupDevtoolsContexts() {
5738
- const now = Date.now();
5739
- for (const [sessionId, ctx] of devtoolsContextStore) {
5740
- if (now - ctx.lastHeartbeat.getTime() > 30 * 1e3) {
5741
- devtoolsContextStore.delete(sessionId);
5742
- }
5743
- }
5744
- }
5745
5903
  var createSessionSchema = z12.object({
5746
5904
  name: z12.string().optional(),
5747
5905
  workingDirectory: z12.string().optional(),
@@ -6000,7 +6158,10 @@ sessions.get("/:id/pending-input", async (c) => {
6000
6158
  var devtoolsContextSchema = z12.object({
6001
6159
  url: z12.string(),
6002
6160
  path: z12.string(),
6003
- pageName: z12.string().optional()
6161
+ pageName: z12.string().optional(),
6162
+ screenWidth: z12.number().optional(),
6163
+ screenHeight: z12.number().optional(),
6164
+ devicePixelRatio: z12.number().optional()
6004
6165
  });
6005
6166
  sessions.post(
6006
6167
  "/:id/devtools-context",
@@ -6008,20 +6169,21 @@ sessions.post(
6008
6169
  async (c) => {
6009
6170
  const id = c.req.param("id");
6010
6171
  const body = c.req.valid("json");
6011
- devtoolsContextStore.set(id, {
6172
+ setDevtoolsContext(id, {
6012
6173
  url: body.url,
6013
6174
  path: body.path,
6014
6175
  pageName: body.pageName || body.path,
6176
+ screenWidth: body.screenWidth,
6177
+ screenHeight: body.screenHeight,
6178
+ devicePixelRatio: body.devicePixelRatio,
6015
6179
  lastHeartbeat: /* @__PURE__ */ new Date()
6016
6180
  });
6017
- cleanupDevtoolsContexts();
6018
6181
  return c.json({ success: true, sessionId: id });
6019
6182
  }
6020
6183
  );
6021
6184
  sessions.get("/:id/devtools-context", async (c) => {
6022
6185
  const id = c.req.param("id");
6023
- cleanupDevtoolsContexts();
6024
- const ctx = devtoolsContextStore.get(id);
6186
+ const ctx = getDevtoolsContext(id);
6025
6187
  if (!ctx) {
6026
6188
  return c.json({ connected: false, context: null });
6027
6189
  }
@@ -6031,6 +6193,9 @@ sessions.get("/:id/devtools-context", async (c) => {
6031
6193
  url: ctx.url,
6032
6194
  path: ctx.path,
6033
6195
  pageName: ctx.pageName,
6196
+ screenWidth: ctx.screenWidth,
6197
+ screenHeight: ctx.screenHeight,
6198
+ devicePixelRatio: ctx.devicePixelRatio,
6034
6199
  lastHeartbeat: ctx.lastHeartbeat.toISOString()
6035
6200
  }
6036
6201
  });
@@ -6611,6 +6776,25 @@ async function emitSyntheticToolStreaming(writeSSE, toolCallStarts, toolCallId,
6611
6776
  await new Promise((resolve11) => setTimeout(resolve11, 0));
6612
6777
  }
6613
6778
  }
6779
+ function buildDevtoolsContextXml(sessionId) {
6780
+ const ctx = getDevtoolsContext(sessionId);
6781
+ if (!ctx) return "";
6782
+ const parts = [];
6783
+ parts.push(`<devtools-context>`);
6784
+ parts.push(` <page url="${ctx.url}" path="${ctx.path}" name="${ctx.pageName}" />`);
6785
+ if (ctx.screenWidth && ctx.screenHeight) {
6786
+ parts.push(` <viewport width="${ctx.screenWidth}" height="${ctx.screenHeight}"${ctx.devicePixelRatio ? ` dpr="${ctx.devicePixelRatio}"` : ""} />`);
6787
+ }
6788
+ parts.push(`</devtools-context>`);
6789
+ return parts.join("\n");
6790
+ }
6791
+ function enrichPromptWithDevtoolsContext(sessionId, prompt) {
6792
+ const xml = buildDevtoolsContextXml(sessionId);
6793
+ if (!xml) return prompt;
6794
+ return `${xml}
6795
+
6796
+ ${prompt}`;
6797
+ }
6614
6798
  var agents = new Hono2();
6615
6799
  var attachmentSchema = z13.object({
6616
6800
  type: z13.enum(["image", "file"]),
@@ -6946,7 +7130,8 @@ agents.post(
6946
7130
  zValidator2("json", runPromptSchema),
6947
7131
  async (c) => {
6948
7132
  const id = c.req.param("id");
6949
- const { prompt, attachments } = c.req.valid("json");
7133
+ const { prompt: rawPrompt, attachments } = c.req.valid("json");
7134
+ const prompt = enrichPromptWithDevtoolsContext(id, rawPrompt);
6950
7135
  const session = await sessionQueries.getById(id);
6951
7136
  if (!session) {
6952
7137
  return c.json({ error: "Session not found" }, 404);
@@ -7091,7 +7276,8 @@ agents.post(
7091
7276
  zValidator2("json", runPromptSchema),
7092
7277
  async (c) => {
7093
7278
  const id = c.req.param("id");
7094
- const { prompt } = c.req.valid("json");
7279
+ const { prompt: rawPrompt } = c.req.valid("json");
7280
+ const prompt = enrichPromptWithDevtoolsContext(id, rawPrompt);
7095
7281
  const session = await sessionQueries.getById(id);
7096
7282
  if (!session) {
7097
7283
  return c.json({ error: "Session not found" }, 404);
@@ -7206,6 +7392,7 @@ agents.post(
7206
7392
  sessionConfig: body.toolApprovals ? { toolApprovals: body.toolApprovals } : void 0
7207
7393
  });
7208
7394
  const session = agent.getSession();
7395
+ const enrichedPrompt = enrichPromptWithDevtoolsContext(session.id, body.prompt);
7209
7396
  const streamId = `stream_${session.id}_${nanoid5(10)}`;
7210
7397
  await createCheckpoint(session.id, session.workingDirectory, 0);
7211
7398
  await activeStreamQueries.create(session.id, streamId);
@@ -7255,7 +7442,7 @@ agents.post(
7255
7442
  let textId = `text_${Date.now()}`;
7256
7443
  let textStarted = false;
7257
7444
  const result = await agent.stream({
7258
- prompt: body.prompt,
7445
+ prompt: enrichedPrompt,
7259
7446
  abortSignal: abortController.signal,
7260
7447
  // Use our managed abort controller, NOT client signal
7261
7448
  onToolProgress: async (progress) => {