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.
- package/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +3 -3
- package/.next/diagnostics/route-bundle-stats.json +22 -21
- package/.next/fallback-build-manifest.json +3 -3
- package/.next/required-server-files.js +1 -1
- package/.next/required-server-files.json +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +18 -18
- package/.next/server/app/_not-found.segments/_full.segment.rsc +18 -18
- package/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
- package/.next/server/app/_not-found.segments/_index.segment.rsc +12 -12
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/analytics/page.js.nft.json +1 -1
- package/.next/server/app/analytics/page_client-reference-manifest.js +1 -1
- package/.next/server/app/analytics.html +1 -1
- package/.next/server/app/analytics.rsc +19 -19
- package/.next/server/app/analytics.segments/_full.segment.rsc +19 -19
- package/.next/server/app/analytics.segments/_head.segment.rsc +4 -4
- package/.next/server/app/analytics.segments/_index.segment.rsc +12 -12
- package/.next/server/app/analytics.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/analytics.segments/analytics/__PAGE__.segment.rsc +3 -3
- package/.next/server/app/analytics.segments/analytics.segment.rsc +3 -3
- package/.next/server/app/chat/page.js.nft.json +1 -1
- package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
- package/.next/server/app/chat.html +1 -1
- package/.next/server/app/chat.rsc +19 -19
- package/.next/server/app/chat.segments/_full.segment.rsc +19 -19
- package/.next/server/app/chat.segments/_head.segment.rsc +4 -4
- package/.next/server/app/chat.segments/_index.segment.rsc +12 -12
- package/.next/server/app/chat.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/chat.segments/chat/__PAGE__.segment.rsc +3 -3
- package/.next/server/app/chat.segments/chat.segment.rsc +3 -3
- package/.next/server/app/data/page.js.nft.json +1 -1
- package/.next/server/app/data/page_client-reference-manifest.js +1 -1
- package/.next/server/app/data.html +1 -1
- package/.next/server/app/data.rsc +25 -26
- package/.next/server/app/data.segments/_full.segment.rsc +25 -26
- package/.next/server/app/data.segments/_head.segment.rsc +4 -4
- package/.next/server/app/data.segments/_index.segment.rsc +12 -12
- package/.next/server/app/data.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/data.segments/data/__PAGE__.segment.rsc +3 -3
- package/.next/server/app/data.segments/data.segment.rsc +3 -3
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.rsc +17 -17
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/index.segments/_full.segment.rsc +17 -17
- package/.next/server/app/index.segments/_head.segment.rsc +4 -4
- package/.next/server/app/index.segments/_index.segment.rsc +12 -12
- package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings.html +1 -1
- package/.next/server/app/settings.rsc +19 -19
- package/.next/server/app/settings.segments/_full.segment.rsc +19 -19
- package/.next/server/app/settings.segments/_head.segment.rsc +4 -4
- package/.next/server/app/settings.segments/_index.segment.rsc +12 -12
- package/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/settings.segments/settings.segment.rsc +3 -3
- package/.next/server/chunks/0598_next_dist_esm_build_templates_app-route_0kbcuk-.js +6 -6
- package/.next/server/chunks/0598_next_dist_esm_build_templates_app-route_0sbf4ny.js +2 -2
- package/.next/server/chunks/ssr/{[root-of-the-server]__0m21fli._.js → [root-of-the-server]__0pgotbk._.js} +2 -2
- package/.next/server/chunks/ssr/[root-of-the-server]__1k1mxo2._.js +3 -0
- package/.next/server/chunks/ssr/_169pdlf._.js +4 -4
- package/.next/server/chunks/ssr/_18jagqc._.js +2 -2
- package/.next/server/chunks/ssr/_1hetwwu._.js +2 -2
- package/.next/{standalone/apps/web/.next/server/chunks/ssr/_0s8403d._.js → server/chunks/ssr/_1p6lb7s._.js} +2 -2
- package/.next/server/chunks/ssr/_1yqlx1m._.js +1 -1
- package/.next/server/chunks/ssr/apps_web_components_analytics_analytics-dashboard_tsx_1056-z3._.js +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/standalone/apps/web/.next/BUILD_ID +1 -1
- package/.next/standalone/apps/web/.next/build-manifest.json +3 -3
- package/.next/standalone/apps/web/.next/required-server-files.json +1 -1
- package/.next/standalone/apps/web/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/apps/web/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/apps/web/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/apps/web/.next/server/app/_not-found.rsc +18 -18
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_full.segment.rsc +18 -18
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_index.segment.rsc +12 -12
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/apps/web/.next/server/app/analytics/page.js.nft.json +1 -1
- package/.next/standalone/apps/web/.next/server/app/analytics/page_client-reference-manifest.js +1 -1
- package/.next/standalone/apps/web/.next/server/app/analytics.html +1 -1
- package/.next/standalone/apps/web/.next/server/app/analytics.rsc +19 -19
- package/.next/standalone/apps/web/.next/server/app/analytics.segments/_full.segment.rsc +19 -19
- package/.next/standalone/apps/web/.next/server/app/analytics.segments/_head.segment.rsc +4 -4
- package/.next/standalone/apps/web/.next/server/app/analytics.segments/_index.segment.rsc +12 -12
- package/.next/standalone/apps/web/.next/server/app/analytics.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/apps/web/.next/server/app/analytics.segments/analytics/__PAGE__.segment.rsc +3 -3
- package/.next/standalone/apps/web/.next/server/app/analytics.segments/analytics.segment.rsc +3 -3
- package/.next/standalone/apps/web/.next/server/app/chat/page.js.nft.json +1 -1
- package/.next/standalone/apps/web/.next/server/app/chat/page_client-reference-manifest.js +1 -1
- package/.next/standalone/apps/web/.next/server/app/chat.html +1 -1
- package/.next/standalone/apps/web/.next/server/app/chat.rsc +19 -19
- package/.next/standalone/apps/web/.next/server/app/chat.segments/_full.segment.rsc +19 -19
- package/.next/standalone/apps/web/.next/server/app/chat.segments/_head.segment.rsc +4 -4
- package/.next/standalone/apps/web/.next/server/app/chat.segments/_index.segment.rsc +12 -12
- package/.next/standalone/apps/web/.next/server/app/chat.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/apps/web/.next/server/app/chat.segments/chat/__PAGE__.segment.rsc +3 -3
- package/.next/standalone/apps/web/.next/server/app/chat.segments/chat.segment.rsc +3 -3
- package/.next/standalone/apps/web/.next/server/app/data/page.js.nft.json +1 -1
- package/.next/standalone/apps/web/.next/server/app/data/page_client-reference-manifest.js +1 -1
- package/.next/standalone/apps/web/.next/server/app/data.html +1 -1
- package/.next/standalone/apps/web/.next/server/app/data.rsc +25 -26
- package/.next/standalone/apps/web/.next/server/app/data.segments/_full.segment.rsc +25 -26
- package/.next/standalone/apps/web/.next/server/app/data.segments/_head.segment.rsc +4 -4
- package/.next/standalone/apps/web/.next/server/app/data.segments/_index.segment.rsc +12 -12
- package/.next/standalone/apps/web/.next/server/app/data.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/apps/web/.next/server/app/data.segments/data/__PAGE__.segment.rsc +3 -3
- package/.next/standalone/apps/web/.next/server/app/data.segments/data.segment.rsc +3 -3
- package/.next/standalone/apps/web/.next/server/app/index.html +1 -1
- package/.next/standalone/apps/web/.next/server/app/index.rsc +17 -17
- package/.next/standalone/apps/web/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/apps/web/.next/server/app/index.segments/_full.segment.rsc +17 -17
- package/.next/standalone/apps/web/.next/server/app/index.segments/_head.segment.rsc +4 -4
- package/.next/standalone/apps/web/.next/server/app/index.segments/_index.segment.rsc +12 -12
- package/.next/standalone/apps/web/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/apps/web/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/apps/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/standalone/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/apps/web/.next/server/app/settings.html +1 -1
- package/.next/standalone/apps/web/.next/server/app/settings.rsc +19 -19
- package/.next/standalone/apps/web/.next/server/app/settings.segments/_full.segment.rsc +19 -19
- package/.next/standalone/apps/web/.next/server/app/settings.segments/_head.segment.rsc +4 -4
- package/.next/standalone/apps/web/.next/server/app/settings.segments/_index.segment.rsc +12 -12
- package/.next/standalone/apps/web/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/apps/web/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +4 -4
- package/.next/standalone/apps/web/.next/server/app/settings.segments/settings.segment.rsc +3 -3
- package/.next/standalone/apps/web/.next/server/chunks/0598_next_dist_esm_build_templates_app-route_0kbcuk-.js +6 -6
- package/.next/standalone/apps/web/.next/server/chunks/0598_next_dist_esm_build_templates_app-route_0sbf4ny.js +2 -2
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__0m21fli._.js → [root-of-the-server]__0pgotbk._.js} +2 -2
- package/.next/standalone/apps/web/.next/server/chunks/ssr/[root-of-the-server]__1k1mxo2._.js +3 -0
- package/.next/standalone/apps/web/.next/server/chunks/ssr/_169pdlf._.js +4 -4
- package/.next/standalone/apps/web/.next/server/chunks/ssr/_18jagqc._.js +2 -2
- package/.next/standalone/apps/web/.next/server/chunks/ssr/_1hetwwu._.js +2 -2
- package/.next/{server/chunks/ssr/_0s8403d._.js → standalone/apps/web/.next/server/chunks/ssr/_1p6lb7s._.js} +2 -2
- package/.next/standalone/apps/web/.next/server/chunks/ssr/_1yqlx1m._.js +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/apps_web_components_analytics_analytics-dashboard_tsx_1056-z3._.js +1 -1
- package/.next/standalone/apps/web/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/apps/web/.next/server/pages/404.html +1 -1
- package/.next/standalone/apps/web/.next/server/pages/500.html +1 -1
- package/.next/standalone/apps/web/.next/static/chunks/0f_k7h1yraes3.js +1 -0
- package/.next/{static/chunks/1ov69q-i9ybqi.js → standalone/apps/web/.next/static/chunks/1b9srvyupwcjz.js} +1 -1
- package/.next/standalone/apps/web/.next/static/chunks/1j_-mc43_9-b3.js +121 -0
- package/.next/standalone/apps/web/.next/static/chunks/23efo4rpc31kr.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/2_qbhu4zxkm7j.js +11 -0
- package/.next/standalone/apps/web/.next/static/chunks/{2ljwki2xxnblc.js → 2h-80z3n8mi3d.js} +7 -7
- package/.next/standalone/apps/web/.next/static/chunks/37j20in7beze4.js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/{1cxabi5yzqz57.js → 38f3p67a1uufx.js} +1 -1
- package/.next/standalone/apps/web/.next/static/chunks/3fe06cefiv690.css +1 -0
- package/.next/standalone/apps/web/CHANGELOG.md +12 -0
- package/.next/standalone/apps/web/app/api/chat/route.ts +25 -11
- package/.next/standalone/apps/web/app/api/media/process/route.ts +34 -1
- package/.next/standalone/apps/web/app/settings/page.tsx +16 -5
- package/.next/standalone/apps/web/bin/larkup.js +12 -1
- package/.next/standalone/apps/web/components/chat/message-item.tsx +68 -3
- package/.next/standalone/apps/web/components/data/data-workspace.tsx +53 -120
- package/.next/standalone/apps/web/components/data/firecrawl-notice.tsx +1 -11
- package/.next/standalone/apps/web/components/data/media-panel.tsx +187 -25
- package/.next/standalone/apps/web/components/data/scrape-panel.tsx +1 -1
- package/.next/standalone/apps/web/components/data/upload-panel.tsx +0 -1
- package/.next/standalone/apps/web/components/index/index-workspace.tsx +48 -25
- package/.next/standalone/apps/web/components/settings/marketplace-section.tsx +1 -1
- package/.next/standalone/apps/web/components/settings/settings-layout.tsx +1 -2
- package/.next/standalone/apps/web/package.json +1 -1
- package/.next/standalone/apps/web/server.js +1 -1
- package/.next/standalone/packages/tools/doc-editor/CHANGELOG.md +7 -0
- package/.next/standalone/packages/tools/doc-editor/dist/editor.js +1 -15
- package/.next/standalone/packages/tools/doc-editor/package.json +1 -1
- package/.next/standalone/packages/tools/doc-editor/src/editor.ts +1 -15
- package/.next/static/chunks/0f_k7h1yraes3.js +1 -0
- package/.next/{standalone/apps/web/.next/static/chunks/1ov69q-i9ybqi.js → static/chunks/1b9srvyupwcjz.js} +1 -1
- package/.next/static/chunks/1j_-mc43_9-b3.js +121 -0
- package/.next/static/chunks/23efo4rpc31kr.js +1 -0
- package/.next/static/chunks/2_qbhu4zxkm7j.js +11 -0
- package/.next/static/chunks/{2ljwki2xxnblc.js → 2h-80z3n8mi3d.js} +7 -7
- package/.next/static/chunks/37j20in7beze4.js +1 -0
- package/.next/static/chunks/{1cxabi5yzqz57.js → 38f3p67a1uufx.js} +1 -1
- package/.next/static/chunks/3fe06cefiv690.css +1 -0
- package/CHANGELOG.md +12 -0
- package/app/api/chat/route.ts +25 -11
- package/app/api/media/process/route.ts +34 -1
- package/app/settings/page.tsx +16 -5
- package/bin/larkup.js +12 -1
- package/components/chat/message-item.tsx +68 -3
- package/components/data/data-workspace.tsx +53 -120
- package/components/data/firecrawl-notice.tsx +1 -11
- package/components/data/media-panel.tsx +187 -25
- package/components/data/scrape-panel.tsx +1 -1
- package/components/data/upload-panel.tsx +0 -1
- package/components/index/index-workspace.tsx +48 -25
- package/components/settings/marketplace-section.tsx +1 -1
- package/components/settings/settings-layout.tsx +1 -2
- package/package.json +6 -6
- package/.next/server/chunks/ssr/[root-of-the-server]__0t8ud_u._.js +0 -3
- package/.next/standalone/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0t8ud_u._.js +0 -3
- package/.next/standalone/apps/web/.next/static/chunks/03ju_837pa9ul.js +0 -11
- package/.next/standalone/apps/web/.next/static/chunks/0ge3nirnmx_np.js +0 -1
- package/.next/standalone/apps/web/.next/static/chunks/19krxv-ou9c8c.js +0 -121
- package/.next/standalone/apps/web/.next/static/chunks/1_nk3imchwn8a.css +0 -1
- package/.next/standalone/apps/web/.next/static/chunks/25rt2v27sz0io.js +0 -1
- package/.next/static/chunks/03ju_837pa9ul.js +0 -11
- package/.next/static/chunks/0ge3nirnmx_np.js +0 -1
- package/.next/static/chunks/19krxv-ou9c8c.js +0 -121
- package/.next/static/chunks/1_nk3imchwn8a.css +0 -1
- package/.next/static/chunks/25rt2v27sz0io.js +0 -1
- /package/.next/standalone/apps/web/.next/static/{iCALZzxFfElF4z3wYZwsC → 7yuxi3XYqMr4kxUl6T-qk}/_buildManifest.js +0 -0
- /package/.next/standalone/apps/web/.next/static/{iCALZzxFfElF4z3wYZwsC → 7yuxi3XYqMr4kxUl6T-qk}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/apps/web/.next/static/{iCALZzxFfElF4z3wYZwsC → 7yuxi3XYqMr4kxUl6T-qk}/_ssgManifest.js +0 -0
- /package/.next/static/{iCALZzxFfElF4z3wYZwsC → 7yuxi3XYqMr4kxUl6T-qk}/_buildManifest.js +0 -0
- /package/.next/static/{iCALZzxFfElF4z3wYZwsC → 7yuxi3XYqMr4kxUl6T-qk}/_clientMiddlewareManifest.js +0 -0
- /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
|
-
|
|
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
|
|
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={
|
|
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
|
-
{
|
|
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
|
|
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={
|
|
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
|
-
|
|
1740
|
+
onPause,
|
|
1741
|
+
onRemove,
|
|
1603
1742
|
}: {
|
|
1604
1743
|
assets: MediaAsset[];
|
|
1605
|
-
|
|
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="
|
|
1643
|
-
|
|
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.
|
|
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(
|
|
400
|
+
toast.info(`using local crawler...`);
|
|
401
401
|
await Promise.all(queries.map((q) => searchFirecrawl(q, queries.length > 1)));
|
|
402
402
|
}
|
|
403
403
|
}
|
|
@@ -64,7 +64,8 @@ const ACTIVE: IndexRun['status'][] = ['chunking', 'embedding', 'upserting'];
|
|
|
64
64
|
export function IndexWorkspace({
|
|
65
65
|
onDone,
|
|
66
66
|
onClose,
|
|
67
|
-
|
|
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
|
|
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
|
-
|
|
219
|
-
<
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
:
|
|
239
|
-
|
|
240
|
-
|
|
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
|
|
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-
|
|
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}>
|
|
@@ -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.
|
|
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
|
|
|
@@ -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;
|