larkup 0.1.39 → 0.1.40

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 (238) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +3 -3
  3. package/.next/diagnostics/route-bundle-stats.json +22 -21
  4. package/.next/fallback-build-manifest.json +3 -3
  5. package/.next/required-server-files.js +1 -1
  6. package/.next/required-server-files.json +1 -1
  7. package/.next/server/app/_global-error.html +1 -1
  8. package/.next/server/app/_global-error.rsc +1 -1
  9. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  10. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  15. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  16. package/.next/server/app/_not-found.html +1 -1
  17. package/.next/server/app/_not-found.rsc +18 -18
  18. package/.next/server/app/_not-found.segments/_full.segment.rsc +18 -18
  19. package/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  20. package/.next/server/app/_not-found.segments/_index.segment.rsc +12 -12
  21. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  22. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  23. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  24. package/.next/server/app/analytics/page.js.nft.json +1 -1
  25. package/.next/server/app/analytics/page_client-reference-manifest.js +1 -1
  26. package/.next/server/app/analytics.html +1 -1
  27. package/.next/server/app/analytics.rsc +19 -19
  28. package/.next/server/app/analytics.segments/_full.segment.rsc +19 -19
  29. package/.next/server/app/analytics.segments/_head.segment.rsc +4 -4
  30. package/.next/server/app/analytics.segments/_index.segment.rsc +12 -12
  31. package/.next/server/app/analytics.segments/_tree.segment.rsc +2 -2
  32. package/.next/server/app/analytics.segments/analytics/__PAGE__.segment.rsc +3 -3
  33. package/.next/server/app/analytics.segments/analytics.segment.rsc +3 -3
  34. package/.next/server/app/chat/page.js.nft.json +1 -1
  35. package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
  36. package/.next/server/app/chat.html +1 -1
  37. package/.next/server/app/chat.rsc +19 -19
  38. package/.next/server/app/chat.segments/_full.segment.rsc +19 -19
  39. package/.next/server/app/chat.segments/_head.segment.rsc +4 -4
  40. package/.next/server/app/chat.segments/_index.segment.rsc +12 -12
  41. package/.next/server/app/chat.segments/_tree.segment.rsc +2 -2
  42. package/.next/server/app/chat.segments/chat/__PAGE__.segment.rsc +3 -3
  43. package/.next/server/app/chat.segments/chat.segment.rsc +3 -3
  44. package/.next/server/app/data/page.js.nft.json +1 -1
  45. package/.next/server/app/data/page_client-reference-manifest.js +1 -1
  46. package/.next/server/app/data.html +1 -1
  47. package/.next/server/app/data.rsc +25 -26
  48. package/.next/server/app/data.segments/_full.segment.rsc +25 -26
  49. package/.next/server/app/data.segments/_head.segment.rsc +4 -4
  50. package/.next/server/app/data.segments/_index.segment.rsc +12 -12
  51. package/.next/server/app/data.segments/_tree.segment.rsc +2 -2
  52. package/.next/server/app/data.segments/data/__PAGE__.segment.rsc +3 -3
  53. package/.next/server/app/data.segments/data.segment.rsc +3 -3
  54. package/.next/server/app/index.html +1 -1
  55. package/.next/server/app/index.rsc +17 -17
  56. package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  57. package/.next/server/app/index.segments/_full.segment.rsc +17 -17
  58. package/.next/server/app/index.segments/_head.segment.rsc +4 -4
  59. package/.next/server/app/index.segments/_index.segment.rsc +12 -12
  60. package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  61. package/.next/server/app/page.js.nft.json +1 -1
  62. package/.next/server/app/page_client-reference-manifest.js +1 -1
  63. package/.next/server/app/settings/page.js.nft.json +1 -1
  64. package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  65. package/.next/server/app/settings.html +1 -1
  66. package/.next/server/app/settings.rsc +19 -19
  67. package/.next/server/app/settings.segments/_full.segment.rsc +19 -19
  68. package/.next/server/app/settings.segments/_head.segment.rsc +4 -4
  69. package/.next/server/app/settings.segments/_index.segment.rsc +12 -12
  70. package/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  71. package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +4 -4
  72. package/.next/server/app/settings.segments/settings.segment.rsc +3 -3
  73. package/.next/server/chunks/0598_next_dist_esm_build_templates_app-route_0kbcuk-.js +6 -6
  74. package/.next/server/chunks/0598_next_dist_esm_build_templates_app-route_0sbf4ny.js +2 -2
  75. package/.next/server/chunks/ssr/{[root-of-the-server]__0m21fli._.js → [root-of-the-server]__0pgotbk._.js} +2 -2
  76. package/.next/server/chunks/ssr/[root-of-the-server]__1k1mxo2._.js +3 -0
  77. package/.next/server/chunks/ssr/_169pdlf._.js +4 -4
  78. package/.next/server/chunks/ssr/_18jagqc._.js +2 -2
  79. package/.next/server/chunks/ssr/_1hetwwu._.js +2 -2
  80. package/.next/{standalone/apps/web/.next/server/chunks/ssr/_0s8403d._.js → server/chunks/ssr/_1p6lb7s._.js} +2 -2
  81. package/.next/server/chunks/ssr/_1yqlx1m._.js +1 -1
  82. package/.next/server/chunks/ssr/apps_web_components_analytics_analytics-dashboard_tsx_1056-z3._.js +1 -1
  83. package/.next/server/middleware-build-manifest.js +3 -3
  84. package/.next/server/pages/404.html +1 -1
  85. package/.next/server/pages/500.html +1 -1
  86. package/.next/standalone/apps/web/.next/BUILD_ID +1 -1
  87. package/.next/standalone/apps/web/.next/build-manifest.json +3 -3
  88. package/.next/standalone/apps/web/.next/required-server-files.json +1 -1
  89. package/.next/standalone/apps/web/.next/server/app/_global-error.html +1 -1
  90. package/.next/standalone/apps/web/.next/server/app/_global-error.rsc +1 -1
  91. package/.next/standalone/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  92. package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  93. package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  94. package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  95. package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  96. package/.next/standalone/apps/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  97. package/.next/standalone/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  98. package/.next/standalone/apps/web/.next/server/app/_not-found.html +1 -1
  99. package/.next/standalone/apps/web/.next/server/app/_not-found.rsc +18 -18
  100. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_full.segment.rsc +18 -18
  101. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  102. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_index.segment.rsc +12 -12
  103. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  104. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  105. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  106. package/.next/standalone/apps/web/.next/server/app/analytics/page.js.nft.json +1 -1
  107. package/.next/standalone/apps/web/.next/server/app/analytics/page_client-reference-manifest.js +1 -1
  108. package/.next/standalone/apps/web/.next/server/app/analytics.html +1 -1
  109. package/.next/standalone/apps/web/.next/server/app/analytics.rsc +19 -19
  110. package/.next/standalone/apps/web/.next/server/app/analytics.segments/_full.segment.rsc +19 -19
  111. package/.next/standalone/apps/web/.next/server/app/analytics.segments/_head.segment.rsc +4 -4
  112. package/.next/standalone/apps/web/.next/server/app/analytics.segments/_index.segment.rsc +12 -12
  113. package/.next/standalone/apps/web/.next/server/app/analytics.segments/_tree.segment.rsc +2 -2
  114. package/.next/standalone/apps/web/.next/server/app/analytics.segments/analytics/__PAGE__.segment.rsc +3 -3
  115. package/.next/standalone/apps/web/.next/server/app/analytics.segments/analytics.segment.rsc +3 -3
  116. package/.next/standalone/apps/web/.next/server/app/chat/page.js.nft.json +1 -1
  117. package/.next/standalone/apps/web/.next/server/app/chat/page_client-reference-manifest.js +1 -1
  118. package/.next/standalone/apps/web/.next/server/app/chat.html +1 -1
  119. package/.next/standalone/apps/web/.next/server/app/chat.rsc +19 -19
  120. package/.next/standalone/apps/web/.next/server/app/chat.segments/_full.segment.rsc +19 -19
  121. package/.next/standalone/apps/web/.next/server/app/chat.segments/_head.segment.rsc +4 -4
  122. package/.next/standalone/apps/web/.next/server/app/chat.segments/_index.segment.rsc +12 -12
  123. package/.next/standalone/apps/web/.next/server/app/chat.segments/_tree.segment.rsc +2 -2
  124. package/.next/standalone/apps/web/.next/server/app/chat.segments/chat/__PAGE__.segment.rsc +3 -3
  125. package/.next/standalone/apps/web/.next/server/app/chat.segments/chat.segment.rsc +3 -3
  126. package/.next/standalone/apps/web/.next/server/app/data/page.js.nft.json +1 -1
  127. package/.next/standalone/apps/web/.next/server/app/data/page_client-reference-manifest.js +1 -1
  128. package/.next/standalone/apps/web/.next/server/app/data.html +1 -1
  129. package/.next/standalone/apps/web/.next/server/app/data.rsc +25 -26
  130. package/.next/standalone/apps/web/.next/server/app/data.segments/_full.segment.rsc +25 -26
  131. package/.next/standalone/apps/web/.next/server/app/data.segments/_head.segment.rsc +4 -4
  132. package/.next/standalone/apps/web/.next/server/app/data.segments/_index.segment.rsc +12 -12
  133. package/.next/standalone/apps/web/.next/server/app/data.segments/_tree.segment.rsc +2 -2
  134. package/.next/standalone/apps/web/.next/server/app/data.segments/data/__PAGE__.segment.rsc +3 -3
  135. package/.next/standalone/apps/web/.next/server/app/data.segments/data.segment.rsc +3 -3
  136. package/.next/standalone/apps/web/.next/server/app/index.html +1 -1
  137. package/.next/standalone/apps/web/.next/server/app/index.rsc +17 -17
  138. package/.next/standalone/apps/web/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  139. package/.next/standalone/apps/web/.next/server/app/index.segments/_full.segment.rsc +17 -17
  140. package/.next/standalone/apps/web/.next/server/app/index.segments/_head.segment.rsc +4 -4
  141. package/.next/standalone/apps/web/.next/server/app/index.segments/_index.segment.rsc +12 -12
  142. package/.next/standalone/apps/web/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  143. package/.next/standalone/apps/web/.next/server/app/page.js.nft.json +1 -1
  144. package/.next/standalone/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
  145. package/.next/standalone/apps/web/.next/server/app/settings/page.js.nft.json +1 -1
  146. package/.next/standalone/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  147. package/.next/standalone/apps/web/.next/server/app/settings.html +1 -1
  148. package/.next/standalone/apps/web/.next/server/app/settings.rsc +19 -19
  149. package/.next/standalone/apps/web/.next/server/app/settings.segments/_full.segment.rsc +19 -19
  150. package/.next/standalone/apps/web/.next/server/app/settings.segments/_head.segment.rsc +4 -4
  151. package/.next/standalone/apps/web/.next/server/app/settings.segments/_index.segment.rsc +12 -12
  152. package/.next/standalone/apps/web/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  153. package/.next/standalone/apps/web/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +4 -4
  154. package/.next/standalone/apps/web/.next/server/app/settings.segments/settings.segment.rsc +3 -3
  155. package/.next/standalone/apps/web/.next/server/chunks/0598_next_dist_esm_build_templates_app-route_0kbcuk-.js +6 -6
  156. package/.next/standalone/apps/web/.next/server/chunks/0598_next_dist_esm_build_templates_app-route_0sbf4ny.js +2 -2
  157. package/.next/standalone/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__0m21fli._.js → [root-of-the-server]__0pgotbk._.js} +2 -2
  158. package/.next/standalone/apps/web/.next/server/chunks/ssr/[root-of-the-server]__1k1mxo2._.js +3 -0
  159. package/.next/standalone/apps/web/.next/server/chunks/ssr/_169pdlf._.js +4 -4
  160. package/.next/standalone/apps/web/.next/server/chunks/ssr/_18jagqc._.js +2 -2
  161. package/.next/standalone/apps/web/.next/server/chunks/ssr/_1hetwwu._.js +2 -2
  162. package/.next/{server/chunks/ssr/_0s8403d._.js → standalone/apps/web/.next/server/chunks/ssr/_1p6lb7s._.js} +2 -2
  163. package/.next/standalone/apps/web/.next/server/chunks/ssr/_1yqlx1m._.js +1 -1
  164. package/.next/standalone/apps/web/.next/server/chunks/ssr/apps_web_components_analytics_analytics-dashboard_tsx_1056-z3._.js +1 -1
  165. package/.next/standalone/apps/web/.next/server/middleware-build-manifest.js +3 -3
  166. package/.next/standalone/apps/web/.next/server/pages/404.html +1 -1
  167. package/.next/standalone/apps/web/.next/server/pages/500.html +1 -1
  168. package/.next/standalone/apps/web/.next/static/chunks/0f_k7h1yraes3.js +1 -0
  169. package/.next/{static/chunks/1ov69q-i9ybqi.js → standalone/apps/web/.next/static/chunks/1b9srvyupwcjz.js} +1 -1
  170. package/.next/standalone/apps/web/.next/static/chunks/1j_-mc43_9-b3.js +121 -0
  171. package/.next/standalone/apps/web/.next/static/chunks/23efo4rpc31kr.js +1 -0
  172. package/.next/standalone/apps/web/.next/static/chunks/2_qbhu4zxkm7j.js +11 -0
  173. package/.next/standalone/apps/web/.next/static/chunks/{2ljwki2xxnblc.js → 2h-80z3n8mi3d.js} +7 -7
  174. package/.next/standalone/apps/web/.next/static/chunks/37j20in7beze4.js +1 -0
  175. package/.next/standalone/apps/web/.next/static/chunks/{1cxabi5yzqz57.js → 38f3p67a1uufx.js} +1 -1
  176. package/.next/standalone/apps/web/.next/static/chunks/3fe06cefiv690.css +1 -0
  177. package/.next/standalone/apps/web/CHANGELOG.md +12 -0
  178. package/.next/standalone/apps/web/app/api/chat/route.ts +25 -11
  179. package/.next/standalone/apps/web/app/api/media/process/route.ts +34 -1
  180. package/.next/standalone/apps/web/app/settings/page.tsx +16 -5
  181. package/.next/standalone/apps/web/bin/larkup.js +12 -1
  182. package/.next/standalone/apps/web/components/chat/message-item.tsx +68 -3
  183. package/.next/standalone/apps/web/components/data/data-workspace.tsx +53 -120
  184. package/.next/standalone/apps/web/components/data/firecrawl-notice.tsx +1 -11
  185. package/.next/standalone/apps/web/components/data/media-panel.tsx +187 -25
  186. package/.next/standalone/apps/web/components/data/scrape-panel.tsx +1 -1
  187. package/.next/standalone/apps/web/components/data/upload-panel.tsx +0 -1
  188. package/.next/standalone/apps/web/components/index/index-workspace.tsx +48 -25
  189. package/.next/standalone/apps/web/components/settings/marketplace-section.tsx +1 -1
  190. package/.next/standalone/apps/web/components/settings/settings-layout.tsx +1 -2
  191. package/.next/standalone/apps/web/package.json +1 -1
  192. package/.next/standalone/apps/web/server.js +1 -1
  193. package/.next/standalone/packages/tools/doc-editor/CHANGELOG.md +7 -0
  194. package/.next/standalone/packages/tools/doc-editor/dist/editor.js +1 -15
  195. package/.next/standalone/packages/tools/doc-editor/package.json +1 -1
  196. package/.next/standalone/packages/tools/doc-editor/src/editor.ts +1 -15
  197. package/.next/static/chunks/0f_k7h1yraes3.js +1 -0
  198. package/.next/{standalone/apps/web/.next/static/chunks/1ov69q-i9ybqi.js → static/chunks/1b9srvyupwcjz.js} +1 -1
  199. package/.next/static/chunks/1j_-mc43_9-b3.js +121 -0
  200. package/.next/static/chunks/23efo4rpc31kr.js +1 -0
  201. package/.next/static/chunks/2_qbhu4zxkm7j.js +11 -0
  202. package/.next/static/chunks/{2ljwki2xxnblc.js → 2h-80z3n8mi3d.js} +7 -7
  203. package/.next/static/chunks/37j20in7beze4.js +1 -0
  204. package/.next/static/chunks/{1cxabi5yzqz57.js → 38f3p67a1uufx.js} +1 -1
  205. package/.next/static/chunks/3fe06cefiv690.css +1 -0
  206. package/CHANGELOG.md +12 -0
  207. package/app/api/chat/route.ts +25 -11
  208. package/app/api/media/process/route.ts +34 -1
  209. package/app/settings/page.tsx +16 -5
  210. package/bin/larkup.js +12 -1
  211. package/components/chat/message-item.tsx +68 -3
  212. package/components/data/data-workspace.tsx +53 -120
  213. package/components/data/firecrawl-notice.tsx +1 -11
  214. package/components/data/media-panel.tsx +187 -25
  215. package/components/data/scrape-panel.tsx +1 -1
  216. package/components/data/upload-panel.tsx +0 -1
  217. package/components/index/index-workspace.tsx +48 -25
  218. package/components/settings/marketplace-section.tsx +1 -1
  219. package/components/settings/settings-layout.tsx +1 -2
  220. package/package.json +6 -6
  221. package/.next/server/chunks/ssr/[root-of-the-server]__0t8ud_u._.js +0 -3
  222. package/.next/standalone/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0t8ud_u._.js +0 -3
  223. package/.next/standalone/apps/web/.next/static/chunks/03ju_837pa9ul.js +0 -11
  224. package/.next/standalone/apps/web/.next/static/chunks/0ge3nirnmx_np.js +0 -1
  225. package/.next/standalone/apps/web/.next/static/chunks/19krxv-ou9c8c.js +0 -121
  226. package/.next/standalone/apps/web/.next/static/chunks/1_nk3imchwn8a.css +0 -1
  227. package/.next/standalone/apps/web/.next/static/chunks/25rt2v27sz0io.js +0 -1
  228. package/.next/static/chunks/03ju_837pa9ul.js +0 -11
  229. package/.next/static/chunks/0ge3nirnmx_np.js +0 -1
  230. package/.next/static/chunks/19krxv-ou9c8c.js +0 -121
  231. package/.next/static/chunks/1_nk3imchwn8a.css +0 -1
  232. package/.next/static/chunks/25rt2v27sz0io.js +0 -1
  233. /package/.next/standalone/apps/web/.next/static/{iCALZzxFfElF4z3wYZwsC → 7yuxi3XYqMr4kxUl6T-qk}/_buildManifest.js +0 -0
  234. /package/.next/standalone/apps/web/.next/static/{iCALZzxFfElF4z3wYZwsC → 7yuxi3XYqMr4kxUl6T-qk}/_clientMiddlewareManifest.js +0 -0
  235. /package/.next/standalone/apps/web/.next/static/{iCALZzxFfElF4z3wYZwsC → 7yuxi3XYqMr4kxUl6T-qk}/_ssgManifest.js +0 -0
  236. /package/.next/static/{iCALZzxFfElF4z3wYZwsC → 7yuxi3XYqMr4kxUl6T-qk}/_buildManifest.js +0 -0
  237. /package/.next/static/{iCALZzxFfElF4z3wYZwsC → 7yuxi3XYqMr4kxUl6T-qk}/_clientMiddlewareManifest.js +0 -0
  238. /package/.next/static/{iCALZzxFfElF4z3wYZwsC → 7yuxi3XYqMr4kxUl6T-qk}/_ssgManifest.js +0 -0
@@ -19,6 +19,8 @@ import {
19
19
  Store,
20
20
  Link2,
21
21
  Sparkles,
22
+ Pause,
23
+ Play,
22
24
  } from 'lucide-react';
23
25
  import { Button } from '@/components/ui/button';
24
26
  import { cn } from '@/lib/utils';
@@ -35,6 +37,16 @@ import {
35
37
  DialogTitle,
36
38
  DialogTrigger,
37
39
  } from '@/components/ui/dialog';
40
+ import {
41
+ AlertDialog,
42
+ AlertDialogAction,
43
+ AlertDialogCancel,
44
+ AlertDialogContent,
45
+ AlertDialogDescription,
46
+ AlertDialogFooter,
47
+ AlertDialogHeader,
48
+ AlertDialogTitle,
49
+ } from '@/components/ui/alert-dialog';
38
50
 
39
51
  /* ------------------------------------------------------------------ */
40
52
  /* Types */
@@ -64,6 +76,7 @@ interface MediaAsset {
64
76
  processingStatus: 'pending' | 'processing' | 'completed' | 'failed';
65
77
  processingError?: string;
66
78
  processingMessage?: string;
79
+ processingPaused?: boolean;
67
80
  processingProgress?: number;
68
81
  processingSteps?: MediaProcessingStep[];
69
82
  processingRevision?: number;
@@ -571,6 +584,8 @@ function MediaContent({
571
584
  const [remoteEstimates, setRemoteEstimates] = useState<RemoteEstimate[] | null>(null);
572
585
  const [checkingUrls, setCheckingUrls] = useState(false);
573
586
  const [importingUrls, setImportingUrls] = useState(false);
587
+ const [playlistAlertOpen, setPlaylistAlertOpen] = useState(false);
588
+ const [assetToRemove, setAssetToRemove] = useState<MediaAsset | null>(null);
574
589
  const [importMode, setImportMode] = useState<'upload' | 'url'>('upload');
575
590
  const mediaApiUrl = serverId
576
591
  ? `/api/media?serverId=${encodeURIComponent(serverId)}`
@@ -687,10 +702,24 @@ function MediaContent({
687
702
  }
688
703
  }
689
704
 
690
- async function importRemoteUrls() {
691
- const urls = parsedUrls();
705
+ async function importRemoteUrls(ignorePlaylist = false) {
706
+ let urls = parsedUrls();
692
707
  if (urls.length === 0 || !remoteEstimates) return;
693
708
  if (!ensureAudioConfiguration()) return;
709
+
710
+ if (ignorePlaylist) {
711
+ urls = urls.map((url) => {
712
+ try {
713
+ const u = new URL(url);
714
+ if (u.hostname.includes('youtube.com')) {
715
+ u.searchParams.delete('list');
716
+ return u.toString();
717
+ }
718
+ } catch {}
719
+ return url;
720
+ });
721
+ }
722
+
694
723
  setImportingUrls(true);
695
724
  try {
696
725
  const res = await fetch(mediaApiUrl, {
@@ -701,8 +730,17 @@ function MediaContent({
701
730
  const data = await res.json();
702
731
  if (!res.ok) throw new Error(data.error ?? 'Media import failed');
703
732
  const ids = (data.assets as MediaAsset[]).map((asset) => asset.id);
733
+ toast.success(`${mediaType === 'video' ? 'Video' : 'Audio'} import started`, {
734
+ description: `Expected time: ${
735
+ remoteDuration
736
+ ? `about ${remoteEstimate.processingMinutes} minute${
737
+ remoteEstimate.processingMinutes === 1 ? '' : 's'
738
+ }`
739
+ : 'a few minutes'
740
+ }. You can safely leave — we will keep indexing it in the background.`,
741
+ duration: 8_000,
742
+ });
704
743
  await processAssets(ids);
705
- toast.success(`${mediaType === 'video' ? 'Video' : 'Audio'} indexing started`);
706
744
  setUrlsText('');
707
745
  setRemoteEstimates(null);
708
746
  setProgress(null);
@@ -757,7 +795,15 @@ function MediaContent({
757
795
  }
758
796
  const mediaLabel =
759
797
  mediaType === 'video' ? 'Video' : mediaType === 'audio' ? 'Audio' : 'Image';
760
- toast.success(`${mediaLabel} indexing started`);
798
+ toast.success(`${mediaLabel} indexing started`, {
799
+ description:
800
+ mediaType === 'image'
801
+ ? 'You can safely leave while we make it searchable.'
802
+ : `Expected time: about ${stagedEstimate.processingMinutes} minute${
803
+ stagedEstimate.processingMinutes === 1 ? '' : 's'
804
+ }. You can safely leave while we index it.`,
805
+ duration: 8_000,
806
+ });
761
807
  setProgress(null);
762
808
 
763
809
  staged.forEach((f) => {
@@ -791,6 +837,26 @@ function MediaContent({
791
837
  }
792
838
  }
793
839
 
840
+ async function togglePause(asset: MediaAsset) {
841
+ try {
842
+ const res = await fetch('/api/media/process', {
843
+ method: 'POST',
844
+ headers: { 'Content-Type': 'application/json' },
845
+ body: JSON.stringify({
846
+ action: asset.processingPaused ? 'resume' : 'pause',
847
+ assetId: asset.id,
848
+ serverId,
849
+ }),
850
+ });
851
+ const body = await res.json();
852
+ if (!res.ok) throw new Error(body.error || 'Could not update media indexing.');
853
+ toast.success(asset.processingPaused ? 'Media indexing resumed.' : 'Media indexing paused.');
854
+ await onMutate();
855
+ } catch (error) {
856
+ showErrorToast(error);
857
+ }
858
+ }
859
+
794
860
  async function handleRetry(assetId: string) {
795
861
  setProgress({ message: 'Retrying media processing...', current: 0, total: 1 });
796
862
  try {
@@ -831,7 +897,11 @@ function MediaContent({
831
897
  )}
832
898
 
833
899
  {activeAssets.length > 0 ? (
834
- <ActiveIndexingList assets={activeAssets} onCancel={handleDelete} />
900
+ <ActiveIndexingList
901
+ assets={activeAssets}
902
+ onPause={togglePause}
903
+ onRemove={setAssetToRemove}
904
+ />
835
905
  ) : null}
836
906
 
837
907
  {mediaType !== 'image' && (
@@ -902,7 +972,18 @@ function MediaContent({
902
972
  size="sm"
903
973
  className="h-9 text-xs"
904
974
  disabled={!remoteEstimates || importingUrls}
905
- onClick={importRemoteUrls}
975
+ onClick={() => {
976
+ const totalEntries =
977
+ remoteEstimates?.reduce(
978
+ (sum: number, item: any) => sum + (item.entryCount ?? 1),
979
+ 0,
980
+ ) ?? 0;
981
+ if (totalEntries > 1) {
982
+ setPlaylistAlertOpen(true);
983
+ } else {
984
+ importRemoteUrls();
985
+ }
986
+ }}
906
987
  >
907
988
  {importingUrls ? (
908
989
  <Loader2 className="mr-1.5 size-3 animate-spin" />
@@ -912,6 +993,38 @@ function MediaContent({
912
993
  Import
913
994
  </Button>
914
995
  </div>
996
+
997
+ <AlertDialog open={playlistAlertOpen} onOpenChange={setPlaylistAlertOpen}>
998
+ <AlertDialogContent>
999
+ <AlertDialogHeader>
1000
+ <AlertDialogTitle>Playlist Detected</AlertDialogTitle>
1001
+ <AlertDialogDescription>
1002
+ You entered a URL that points to a playlist. Do you want to download and index the
1003
+ entire playlist, or just the single video?
1004
+ </AlertDialogDescription>
1005
+ </AlertDialogHeader>
1006
+ <AlertDialogFooter>
1007
+ <AlertDialogCancel>Cancel</AlertDialogCancel>
1008
+ <Button
1009
+ variant="outline"
1010
+ onClick={() => {
1011
+ setPlaylistAlertOpen(false);
1012
+ importRemoteUrls(true);
1013
+ }}
1014
+ >
1015
+ Single Video
1016
+ </Button>
1017
+ <AlertDialogAction
1018
+ onClick={() => {
1019
+ setPlaylistAlertOpen(false);
1020
+ importRemoteUrls(false);
1021
+ }}
1022
+ >
1023
+ Entire Playlist
1024
+ </AlertDialogAction>
1025
+ </AlertDialogFooter>
1026
+ </AlertDialogContent>
1027
+ </AlertDialog>
915
1028
  <p className="mt-2 pl-1 text-[11px] leading-relaxed text-muted-foreground">
916
1029
  Direct {mediaType} links
917
1030
  {mediaType === 'video' ? ', YouTube videos, or playlists' : ''}. Add up to 10 URLs
@@ -951,17 +1064,7 @@ function MediaContent({
951
1064
  />
952
1065
  </div>
953
1066
 
954
- {isPlaylist ? (
955
- <div className="flex items-start gap-2 rounded-lg border border-amber-200 bg-amber-50/60 dark:border-amber-800/50 dark:bg-amber-950/30 px-3 py-2.5">
956
- <AlertCircle className="size-3.5 shrink-0 mt-0.5 text-amber-600 dark:text-amber-400" />
957
- <p className="text-[11px] text-amber-800 dark:text-amber-300 leading-relaxed">
958
- <span className="font-medium">Playlist detected</span> — this will
959
- download and index{' '}
960
- <span className="font-semibold">{totalEntries} items</span> (max 10). Each
961
- item is transcribed and analyzed separately.
962
- </p>
963
- </div>
964
- ) : null}
1067
+ {/* Playlist warning moved to AlertDialog */}
965
1068
 
966
1069
  {(mediaType === 'audio'
967
1070
  ? remoteEstimates.slice(0, 1)
@@ -1238,12 +1341,20 @@ function MediaContent({
1238
1341
  </DialogHeader>
1239
1342
  <div className="flex-1 overflow-y-auto px-6 py-4">
1240
1343
  {mediaType === 'image' ? (
1241
- <ImageGallery assets={assets} onDelete={handleDelete} serverId={serverId} />
1344
+ <ImageGallery
1345
+ assets={assets}
1346
+ onDelete={(id) =>
1347
+ setAssetToRemove(assets.find((asset) => asset.id === id) ?? null)
1348
+ }
1349
+ serverId={serverId}
1350
+ />
1242
1351
  ) : (
1243
1352
  <FileList
1244
1353
  assets={assets}
1245
1354
  mediaType={mediaType}
1246
- onDelete={handleDelete}
1355
+ onDelete={(id) =>
1356
+ setAssetToRemove(assets.find((asset) => asset.id === id) ?? null)
1357
+ }
1247
1358
  onProcess={handleRetry}
1248
1359
  />
1249
1360
  )}
@@ -1258,6 +1369,34 @@ function MediaContent({
1258
1369
  </div>
1259
1370
  ) : null}
1260
1371
 
1372
+ <AlertDialog
1373
+ open={Boolean(assetToRemove)}
1374
+ onOpenChange={(open) => !open && setAssetToRemove(null)}
1375
+ >
1376
+ <AlertDialogContent>
1377
+ <AlertDialogHeader>
1378
+ <AlertDialogTitle>Remove this {assetToRemove?.type ?? 'media'} file?</AlertDialogTitle>
1379
+ <AlertDialogDescription>
1380
+ {assetToRemove && isActiveJob(assetToRemove)
1381
+ ? 'This will stop its indexing job and permanently remove any progress already made.'
1382
+ : 'This permanently removes the file and its searchable data from your knowledge base.'}
1383
+ </AlertDialogDescription>
1384
+ </AlertDialogHeader>
1385
+ <AlertDialogFooter>
1386
+ <AlertDialogCancel>Keep file</AlertDialogCancel>
1387
+ <AlertDialogAction
1388
+ className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
1389
+ onClick={() => {
1390
+ if (assetToRemove) void handleDelete(assetToRemove.id);
1391
+ setAssetToRemove(null);
1392
+ }}
1393
+ >
1394
+ Remove file
1395
+ </AlertDialogAction>
1396
+ </AlertDialogFooter>
1397
+ </AlertDialogContent>
1398
+ </AlertDialog>
1399
+
1261
1400
  {/* Storage warning */}
1262
1401
  {/* {storageUsedBytes > 1024 * 1024 * 1024 && (
1263
1402
  <div className="flex items-start gap-2.5 rounded-lg border border-amber-200 bg-amber-50 px-3.5 py-3">
@@ -1310,7 +1449,6 @@ function ImageGallery({
1310
1449
  className="size-full object-cover transition-transform duration-300 group-hover:scale-105"
1311
1450
  loading="lazy"
1312
1451
  onError={(e) => {
1313
- // Fallback to original if no thumbnail
1314
1452
  (e.target as HTMLImageElement).src = mediaAssetUrl(asset.id, serverId);
1315
1453
  }}
1316
1454
  />
@@ -1599,10 +1737,12 @@ function StatusBadge({ asset }: { asset: MediaAsset }) {
1599
1737
 
1600
1738
  function ActiveIndexingList({
1601
1739
  assets,
1602
- onCancel,
1740
+ onPause,
1741
+ onRemove,
1603
1742
  }: {
1604
1743
  assets: MediaAsset[];
1605
- onCancel: (id: string) => void;
1744
+ onPause: (asset: MediaAsset) => void;
1745
+ onRemove: (asset: MediaAsset) => void;
1606
1746
  }) {
1607
1747
  return (
1608
1748
  <section
@@ -1637,10 +1777,30 @@ function ActiveIndexingList({
1637
1777
  <span className="shrink-0 text-[10px] font-medium tabular-nums text-emerald-600 dark:text-emerald-400">
1638
1778
  {Math.round(progress)}%
1639
1779
  </span>
1780
+ {asset.type !== 'image' ? (
1781
+ <button
1782
+ type="button"
1783
+ title={asset.processingPaused ? 'Resume Indexing' : 'Pause Indexing'}
1784
+ aria-label={
1785
+ asset.processingPaused
1786
+ ? `Resume ${asset.fileName}`
1787
+ : `Pause ${asset.fileName}`
1788
+ }
1789
+ onClick={() => onPause(asset)}
1790
+ className="rounded-full p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
1791
+ >
1792
+ {asset.processingPaused ? (
1793
+ <Play className="size-3" />
1794
+ ) : (
1795
+ <Pause className="size-3" />
1796
+ )}
1797
+ </button>
1798
+ ) : null}
1640
1799
  <button
1641
1800
  type="button"
1642
- title="Cancel Indexing"
1643
- onClick={() => onCancel(asset.id)}
1801
+ title="Remove file"
1802
+ aria-label={`Remove ${asset.fileName}`}
1803
+ onClick={() => onRemove(asset)}
1644
1804
  className="p-1 -mr-1 rounded-full text-muted-foreground hover:bg-red-100 hover:text-red-600 dark:hover:bg-red-900/30 transition-colors"
1645
1805
  >
1646
1806
  <X className="size-3" />
@@ -1657,7 +1817,9 @@ function ActiveIndexingList({
1657
1817
  <div className="flex items-center gap-1.5">
1658
1818
  <ElapsedTime startTime={asset.createdAt} />
1659
1819
  <p className="truncate text-[10px] text-muted-foreground animate-pulse">
1660
- {asset.processingMessage || 'Preparing media indexing...'}
1820
+ {asset.processingPaused
1821
+ ? 'Paused — resume when you are ready.'
1822
+ : asset.processingMessage || 'Preparing media indexing...'}
1661
1823
  </p>
1662
1824
  </div>
1663
1825
  {/* {asset.processingSteps?.length ? (
@@ -397,7 +397,7 @@ export function ScrapePanel({
397
397
  queries.map((q) => searchGeneric(q, activeProvider, 1, queries.length > 1, false)),
398
398
  );
399
399
  } catch (err) {
400
- toast.info(`${activeProvider} search failed. Falling back to local crawler...`);
400
+ toast.info(`using local crawler...`);
401
401
  await Promise.all(queries.map((q) => searchFirecrawl(q, queries.length > 1)));
402
402
  }
403
403
  }
@@ -181,7 +181,6 @@ export function UploadPanel({ onAdded }: { onAdded: () => void }) {
181
181
  indexAsTabular: true,
182
182
  });
183
183
  } else {
184
- // fallback to plain
185
184
  next.push({
186
185
  id,
187
186
  name: file.name,
@@ -64,7 +64,8 @@ const ACTIVE: IndexRun['status'][] = ['chunking', 'embedding', 'upserting'];
64
64
  export function IndexWorkspace({
65
65
  onDone,
66
66
  onClose,
67
- }: { onDone?: () => void; onClose?: () => void } = {}) {
67
+ automatic = false,
68
+ }: { onDone?: () => void; onClose?: () => void; automatic?: boolean } = {}) {
68
69
  const [starting, setStarting] = useState(false);
69
70
  const [isIndexing, setIsIndexing] = useState(false);
70
71
 
@@ -94,7 +95,21 @@ export function IndexWorkspace({
94
95
  setIsIndexing(true);
95
96
  } else if (isIndexing && status === 'completed') {
96
97
  setIsIndexing(false);
97
- toast.success('Indexing completed successfully!');
98
+ toast.success('Indexing complete — your data is ready to use.');
99
+ try {
100
+ const context = new (window.AudioContext || (window as any).webkitAudioContext)();
101
+ const oscillator = context.createOscillator();
102
+ const gain = context.createGain();
103
+ oscillator.connect(gain);
104
+ gain.connect(context.destination);
105
+ oscillator.frequency.setValueAtTime(880, context.currentTime);
106
+ gain.gain.setValueAtTime(0.04, context.currentTime);
107
+ gain.gain.exponentialRampToValueAtTime(0.001, context.currentTime + 0.12);
108
+ oscillator.start();
109
+ oscillator.stop(context.currentTime + 0.12);
110
+ } catch {
111
+ // Browsers may block notification sounds until a user gesture.
112
+ }
98
113
  onClose?.();
99
114
  }
100
115
  }, [data?.run?.status, isIndexing, onClose]);
@@ -215,29 +230,37 @@ export function IndexWorkspace({
215
230
  </Alert>
216
231
  )} */}
217
232
 
218
- <div className="flex w-full items-center justify-between pt-4 mt-2">
219
- <Button onClick={() => onClose?.()} size="lg" variant="outline">
220
- Cancel
221
- </Button>
222
- <Button
223
- onClick={() => build(run?.status === 'completed')}
224
- disabled={
225
- !ready || running || starting || (run?.status === 'completed' && unindexedCount === 0)
226
- }
227
- size="lg"
228
- >
229
- {running || starting ? (
230
- <Loader2 className="size-4 animate-spin mr-2" />
231
- ) : (
232
- <Play className="size-4 mr-2" />
233
- )}
234
- {running
235
- ? 'Indexing…'
236
- : run?.status === 'completed'
237
- ? `Index new documents (${unindexedCount})`
238
- : `Start indexing (${unindexedCount})`}
239
- </Button>
240
- </div>
233
+ {automatic ? (
234
+ <div className="flex justify-end pt-2">
235
+ <Button onClick={() => onClose?.()} variant="outline">
236
+ Continue working
237
+ </Button>
238
+ </div>
239
+ ) : (
240
+ <div className="flex w-full items-center justify-between pt-4 mt-2">
241
+ <Button onClick={() => onClose?.()} size="lg" variant="outline">
242
+ Cancel
243
+ </Button>
244
+ <Button
245
+ onClick={() => build(run?.status === 'completed')}
246
+ disabled={
247
+ !ready || running || starting || (run?.status === 'completed' && unindexedCount === 0)
248
+ }
249
+ size="lg"
250
+ >
251
+ {running || starting ? (
252
+ <Loader2 className="size-4 animate-spin mr-2" />
253
+ ) : (
254
+ <Play className="size-4 mr-2" />
255
+ )}
256
+ {running
257
+ ? 'Indexing…'
258
+ : run?.status === 'completed'
259
+ ? `Index new documents (${unindexedCount})`
260
+ : `Start indexing (${unindexedCount})`}
261
+ </Button>
262
+ </div>
263
+ )}
241
264
  </div>
242
265
  );
243
266
  }
@@ -99,7 +99,7 @@ export function MarketplaceSection() {
99
99
  async (toolId: string) => {
100
100
  setInstalling(toolId);
101
101
  const toastId = toast.loading('Downloading and installing tool…', {
102
- description: 'This may take a moment on first install.',
102
+ description: 'This may take a minute on first install.',
103
103
  });
104
104
  try {
105
105
  const res = await fetch(`/api/marketplace/${toolId}`, {
@@ -10,7 +10,6 @@ import {
10
10
  Database,
11
11
  Plug,
12
12
  Store,
13
- Share2,
14
13
  type LucideIcon,
15
14
  Grid2X2Plus,
16
15
  } from 'lucide-react';
@@ -82,7 +81,7 @@ export function SettingsLayout({ activeSection, onSectionChange, children }: Set
82
81
 
83
82
  return (
84
83
  <div className="flex h-full w-full flex-1 min-h-0 bg-transparent">
85
- <nav className="hidden md:flex w-[240px] shrink-0 flex-col overflow-y-auto h-full bg-transparent border-r border-border/40">
84
+ <nav className="hidden md:flex w-60 shrink-0 flex-col overflow-y-auto h-full bg-transparent border-r border-border/40">
86
85
  <div className="flex flex-col gap-6 py-6 px-4">
87
86
  {SECTION_GROUPS.map((group) => (
88
87
  <div key={group.label}>
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "larkup",
3
- "version": "0.1.39",
3
+ "version": "0.1.40",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "larkup": "./bin/larkup.js"
@@ -15,7 +15,7 @@ const currentPort = parseInt(process.env.PORT, 10) || 3000
15
15
  const hostname = process.env.HOSTNAME || '0.0.0.0'
16
16
 
17
17
  let keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10)
18
- const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"0.1.39"},"webpack":null,"typescript":{"ignoreBuildErrors":true},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.mjs","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true,"customCacheHandler":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{"serverFunctions":true,"browserToTerminal":"warn"},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/Users/abdelrahmanabounida/Desktop/my-ai-startup/larkup/larkup","cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"appNewScrollHandler":false,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"partialFallbacks":false,"dynamicOnHover":false,"varyParams":false,"prefetchInlining":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":9,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"useTypeScriptCli":false,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"gestureTransition":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":"warn","lockDistDir":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.mjs","transpilePackages":["@larkup/core","@larkup/vector-stores","@larkup/scraper","@larkup/marketplace"],"serverExternalPackages":["@lancedb/lancedb","chromadb","dockerode","@larkup/sandbox"],"turbopack":{"root":"/Users/abdelrahmanabounida/Desktop/my-ai-startup/larkup/larkup"},"distDirRoot":".next","_originalRewrites":{"beforeFiles":[],"afterFiles":[{"source":"/uploads/:path*","destination":"/api/uploads/:path*"}],"fallback":[]}}
18
+ const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"0.1.40"},"webpack":null,"typescript":{"ignoreBuildErrors":true},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.mjs","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true,"customCacheHandler":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{"serverFunctions":true,"browserToTerminal":"warn"},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/Users/abdelrahmanabounida/Desktop/my-ai-startup/larkup/larkup","cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"appNewScrollHandler":false,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"partialFallbacks":false,"dynamicOnHover":false,"varyParams":false,"prefetchInlining":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":9,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"useTypeScriptCli":false,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"gestureTransition":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":"warn","lockDistDir":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.mjs","transpilePackages":["@larkup/core","@larkup/vector-stores","@larkup/scraper","@larkup/marketplace"],"serverExternalPackages":["@lancedb/lancedb","chromadb","dockerode","@larkup/sandbox"],"turbopack":{"root":"/Users/abdelrahmanabounida/Desktop/my-ai-startup/larkup/larkup"},"distDirRoot":".next","_originalRewrites":{"beforeFiles":[],"afterFiles":[{"source":"/uploads/:path*","destination":"/api/uploads/:path*"}],"fallback":[]}}
19
19
 
20
20
  process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
21
21
 
@@ -1,5 +1,12 @@
1
1
  # @larkup/tool-doc-editor
2
2
 
3
+ ## 0.2.6
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [2a0a7e2]
8
+ - @larkup/core@0.2.5
9
+
3
10
  ## 0.2.5
4
11
 
5
12
  ### Patch Changes
@@ -99,19 +99,13 @@ export async function applyFieldEdits(sessionId, edits) {
99
99
  try {
100
100
  let resultBuffer;
101
101
  let updatedFields = [];
102
- // Map field IDs to actual field names for native PDF filling and sandbox scripts.
103
- // The LLM sends field IDs like "pdf_field_0"; we resolve them to the actual PDF field names.
104
- // If the ID doesn't match any field, try matching by name directly (case-insensitive).
105
102
  const resolvedEdits = edits.map((edit) => {
106
- // Primary: look up by ID
107
103
  let field = session.parsed.fields.find((f) => f.id === edit.fieldId);
108
104
  if (!field) {
109
- // Fallback: match by name (case-insensitive, trimmed)
110
105
  const needle = edit.fieldId.trim().toLowerCase();
111
106
  field = session.parsed.fields.find((f) => f.name.trim().toLowerCase() === needle);
112
107
  }
113
108
  if (!field) {
114
- // Fallback: match by partial name containment
115
109
  const needle = edit.fieldId.trim().toLowerCase();
116
110
  field = session.parsed.fields.find((f) => f.name.trim().toLowerCase().includes(needle) ||
117
111
  needle.includes(f.name.trim().toLowerCase()));
@@ -464,26 +458,18 @@ export async function applySignature(sessionId, data) {
464
458
  let resolvedY = null;
465
459
  if (data.detectedContext) {
466
460
  try {
467
- // Use sandbox PyPDF to find text coordinates on this page
468
461
  const coords = await findTextPositionOnPage(buffer, pageIndex, data.detectedContext);
469
462
  if (coords) {
470
- // Place signature right below the detected text line
471
463
  resolvedX = coords.x;
472
- // coords.y is the bottom of the text in PDF coordinate system
473
- // Place signature just below (subtract a small offset for spacing)
474
464
  resolvedY = coords.y - 10;
475
465
  }
476
466
  }
477
- catch {
478
- // Fallback to UI-provided coordinates
479
- }
467
+ catch { }
480
468
  }
481
- // Fall back to user-specified percentages
482
469
  if (resolvedX === null || resolvedY === null) {
483
470
  const xPct = data.x ?? 50;
484
471
  const yPct = data.y ?? 50;
485
472
  resolvedX = (xPct / 100) * width;
486
- // Invert Y: UI treats y=0 as top, PDF treats y=0 as bottom
487
473
  resolvedY = height - (yPct / 100) * height;
488
474
  }
489
475
  const x = resolvedX;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@larkup/tool-doc-editor",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },