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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { useEffect, Suspense } from 'react';
|
|
3
|
+
import { useEffect, useState, Suspense } from 'react';
|
|
4
4
|
import { useSearchParams, useRouter, usePathname } from 'next/navigation';
|
|
5
5
|
import { SettingsLayout, type SettingsSection } from '@/components/settings/settings-layout';
|
|
6
6
|
import { GeneralSection } from '@/components/settings/general-section';
|
|
@@ -27,9 +27,14 @@ function SettingsContent() {
|
|
|
27
27
|
return 'general';
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
|
|
30
|
+
// Keep an immediate local selection as well as the URL. A slow Installed
|
|
31
|
+
// Tools request must never make the rest of the settings navigation feel
|
|
32
|
+
// frozen while Next finishes a route transition.
|
|
33
|
+
const [activeSection, setActiveSection] = useState<SettingsSection>(resolveSection);
|
|
34
|
+
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
setActiveSection(resolveSection());
|
|
37
|
+
}, [searchParams]);
|
|
33
38
|
|
|
34
39
|
useEffect(() => {
|
|
35
40
|
// Normalize legacy `?ai-models` param to `?section=models`
|
|
@@ -42,7 +47,13 @@ function SettingsContent() {
|
|
|
42
47
|
}, [searchParams, pathname, router]);
|
|
43
48
|
|
|
44
49
|
const handleSectionChange = (newSection: SettingsSection) => {
|
|
45
|
-
|
|
50
|
+
setActiveSection(newSection);
|
|
51
|
+
const nextUrl = `${pathname}?section=${newSection}`;
|
|
52
|
+
window.history.replaceState(null, '', nextUrl);
|
|
53
|
+
// Keep Next's route state in sync in the background. The local state above
|
|
54
|
+
// is intentionally updated first so this remains responsive if a section
|
|
55
|
+
// has a slow request in flight.
|
|
56
|
+
router.replace(nextUrl, { scroll: false });
|
|
46
57
|
};
|
|
47
58
|
|
|
48
59
|
return (
|
|
@@ -35,8 +35,19 @@ if (command === '--version' || command === '-v') {
|
|
|
35
35
|
child.once('exit', (code) => process.exit(code ?? 0));
|
|
36
36
|
|
|
37
37
|
void openWhenReady(url);
|
|
38
|
+
} else if (command === 'update') {
|
|
39
|
+
console.log('\x1b[38;2;223;156;32mUpdating Larkup…\x1b[0m');
|
|
40
|
+
const child = spawn('npm', ['install', '-g', 'larkup@latest'], { stdio: 'inherit' });
|
|
41
|
+
child.once('error', (error) => {
|
|
42
|
+
console.error('Failed to update Larkup:', error.message);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
});
|
|
45
|
+
child.once('exit', (code) => {
|
|
46
|
+
if (code === 0) console.log('Larkup is up to date. Restart it to use the new version.');
|
|
47
|
+
process.exit(code ?? 0);
|
|
48
|
+
});
|
|
38
49
|
} else {
|
|
39
|
-
console.error('Usage: larkup dev');
|
|
50
|
+
console.error('Usage: larkup <dev|start|update>');
|
|
40
51
|
process.exit(1);
|
|
41
52
|
}
|
|
42
53
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { useEffect, useMemo, useRef } from 'react';
|
|
3
|
+
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
4
4
|
import type { UIMessage } from 'ai';
|
|
5
5
|
import { KnowledgeBaseResult } from '@/components/chat/tools/knowledge-base-result';
|
|
6
6
|
import { ChatChart, type ChartConfig } from '@/components/chat/tools/chat-chart';
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
type CorpusDataConfig,
|
|
16
16
|
} from '@/components/chat/tools/corpus-data-result';
|
|
17
17
|
import { ChatSignatureRequest } from '@/components/chat/tools/chat-signature-request';
|
|
18
|
-
import { Sparkles, FileEdit, CheckCircle2, Globe } from 'lucide-react';
|
|
18
|
+
import { Sparkles, FileEdit, CheckCircle2, Globe, ChevronDown } from 'lucide-react';
|
|
19
19
|
import { ChatMediaPreview, parseMediaRefs } from '@/components/chat/tools/chat-media-preview';
|
|
20
20
|
import { useDocEditor } from '@/components/chat/canvas/doc-editor-provider';
|
|
21
21
|
|
|
@@ -455,6 +455,64 @@ function renderToolPart(
|
|
|
455
455
|
return null;
|
|
456
456
|
}
|
|
457
457
|
|
|
458
|
+
function WebSearchSummary({ parts }: { parts: any[] }) {
|
|
459
|
+
const [open, setOpen] = useState(false);
|
|
460
|
+
const searches = parts.map((part) => {
|
|
461
|
+
const info = getToolInfo(part);
|
|
462
|
+
const results = Array.isArray(info.output?.results) ? info.output.results : [];
|
|
463
|
+
return { query: info.input?.query as string | undefined, results, running: info.isExecuting };
|
|
464
|
+
});
|
|
465
|
+
const resultCount = searches.reduce((count, search) => count + search.results.length, 0);
|
|
466
|
+
const running = searches.some((search) => search.running);
|
|
467
|
+
|
|
468
|
+
return (
|
|
469
|
+
<div className="mb-2 w-full">
|
|
470
|
+
<button
|
|
471
|
+
type="button"
|
|
472
|
+
onClick={() => (resultCount > 0 || searches.length > 1) && setOpen((value) => !value)}
|
|
473
|
+
className="inline-flex items-center gap-2 rounded-md border border-border/50 bg-muted/30 px-2 py-1.5 text-xs text-muted-foreground transition-colors hover:bg-muted/50"
|
|
474
|
+
>
|
|
475
|
+
<Globe className="size-3.5 shrink-0" />
|
|
476
|
+
<span>{running ? 'Searching the web…' : 'Searched the web'}</span>
|
|
477
|
+
{!running && resultCount > 0 ? (
|
|
478
|
+
<span className="rounded-full bg-secondary px-1.5 py-0.5 text-[10px] font-medium text-foreground">
|
|
479
|
+
{resultCount} result{resultCount === 1 ? '' : 's'}
|
|
480
|
+
</span>
|
|
481
|
+
) : null}
|
|
482
|
+
{!running && (resultCount > 0 || searches.length > 1) ? (
|
|
483
|
+
<ChevronDown className={`size-3 transition-transform ${open ? 'rotate-180' : ''}`} />
|
|
484
|
+
) : null}
|
|
485
|
+
</button>
|
|
486
|
+
|
|
487
|
+
{open ? (
|
|
488
|
+
<div className="mt-2 max-w-xl overflow-hidden rounded-lg border border-border/60 bg-background text-xs">
|
|
489
|
+
{searches
|
|
490
|
+
.flatMap((search) => search.results)
|
|
491
|
+
.slice(0, 5)
|
|
492
|
+
.map((result: any, index) => (
|
|
493
|
+
<a
|
|
494
|
+
key={`${result.url ?? result.title ?? index}-${index}`}
|
|
495
|
+
href={result.url}
|
|
496
|
+
target="_blank"
|
|
497
|
+
rel="noreferrer"
|
|
498
|
+
className="block border-b border-border/50 px-3 py-2.5 last:border-0 hover:bg-muted/40"
|
|
499
|
+
>
|
|
500
|
+
<span className="block truncate font-medium text-foreground">
|
|
501
|
+
{result.title || result.url}
|
|
502
|
+
</span>
|
|
503
|
+
{result.snippet ? (
|
|
504
|
+
<span className="mt-0.5 block line-clamp-2 text-muted-foreground">
|
|
505
|
+
{result.snippet}
|
|
506
|
+
</span>
|
|
507
|
+
) : null}
|
|
508
|
+
</a>
|
|
509
|
+
))}
|
|
510
|
+
</div>
|
|
511
|
+
) : null}
|
|
512
|
+
</div>
|
|
513
|
+
);
|
|
514
|
+
}
|
|
515
|
+
|
|
458
516
|
/* ------------------------------------------------------------------ */
|
|
459
517
|
/* Main message component */
|
|
460
518
|
/* ------------------------------------------------------------------ */
|
|
@@ -777,8 +835,12 @@ export function MessageItem({
|
|
|
777
835
|
|
|
778
836
|
const vizParts = toolParts.filter(isVizPart);
|
|
779
837
|
const mediaToolParts = toolParts.filter((p: any) => getToolInfo(p).toolName === 'presentMedia');
|
|
838
|
+
const webSearchParts = toolParts.filter((p: any) => getToolInfo(p).toolName === 'webSearch');
|
|
780
839
|
const nonVizToolParts = toolParts.filter(
|
|
781
|
-
(p: any) =>
|
|
840
|
+
(p: any) =>
|
|
841
|
+
!isVizPart(p) &&
|
|
842
|
+
getToolInfo(p).toolName !== 'presentMedia' &&
|
|
843
|
+
getToolInfo(p).toolName !== 'webSearch',
|
|
782
844
|
);
|
|
783
845
|
|
|
784
846
|
// Build tabs if we have multiple visualizations
|
|
@@ -808,6 +870,9 @@ export function MessageItem({
|
|
|
808
870
|
{/* Knowledge base results */}
|
|
809
871
|
{kbParts.length > 0 && <KnowledgeBaseResult parts={kbParts} isShimmering={isShimmering} />}
|
|
810
872
|
|
|
873
|
+
{/* All search attempts are intentionally one compact disclosure. */}
|
|
874
|
+
{webSearchParts.length > 0 && <WebSearchSummary parts={webSearchParts} />}
|
|
875
|
+
|
|
811
876
|
{/* Non-visualization tool outputs (data tables, sandbox results) */}
|
|
812
877
|
{nonVizToolParts
|
|
813
878
|
.filter((p: any) => getToolInfo(p).isCompleted)
|
|
@@ -1,23 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { useState, useEffect, useRef, useCallback } from 'react';
|
|
4
|
-
import { useSearchParams,
|
|
4
|
+
import { useSearchParams, usePathname } from 'next/navigation';
|
|
5
5
|
import useSWR, { useSWRConfig } from 'swr';
|
|
6
6
|
import { toast } from 'sonner';
|
|
7
7
|
import { motion } from 'framer-motion';
|
|
8
8
|
import { cn } from '@/lib/utils';
|
|
9
9
|
import type { CrawlJob, SourceDocument, IndexRun } from '@larkup/core/types';
|
|
10
|
-
import {
|
|
11
|
-
Globe,
|
|
12
|
-
FileUp,
|
|
13
|
-
Type,
|
|
14
|
-
Image,
|
|
15
|
-
Plug,
|
|
16
|
-
Briefcase,
|
|
17
|
-
ChevronDown,
|
|
18
|
-
Zap,
|
|
19
|
-
RotateCcw,
|
|
20
|
-
} from 'lucide-react';
|
|
10
|
+
import { Globe, FileUp, Type, Image, Plug, Briefcase, ChevronDown } from 'lucide-react';
|
|
21
11
|
import { ScrapePanel } from '@/components/data/scrape-panel';
|
|
22
12
|
import { PastePanel } from '@/components/data/paste-panel';
|
|
23
13
|
import { UploadPanel } from '@/components/data/upload-panel';
|
|
@@ -33,20 +23,7 @@ import {
|
|
|
33
23
|
DialogHeader,
|
|
34
24
|
DialogTitle,
|
|
35
25
|
DialogDescription,
|
|
36
|
-
DialogTrigger,
|
|
37
26
|
} from '@/components/ui/dialog';
|
|
38
|
-
import {
|
|
39
|
-
AlertDialog,
|
|
40
|
-
AlertDialogAction,
|
|
41
|
-
AlertDialogCancel,
|
|
42
|
-
AlertDialogContent,
|
|
43
|
-
AlertDialogDescription,
|
|
44
|
-
AlertDialogFooter,
|
|
45
|
-
AlertDialogHeader,
|
|
46
|
-
AlertDialogTitle,
|
|
47
|
-
AlertDialogTrigger,
|
|
48
|
-
} from '@/components/ui/alert-dialog';
|
|
49
|
-
import { Button } from '@/components/ui/button';
|
|
50
27
|
|
|
51
28
|
const fetcher = (url: string) => fetch(url).then((r) => r.json());
|
|
52
29
|
|
|
@@ -102,7 +79,6 @@ type SubTabId = (typeof SUB_TABS)[number]['id'];
|
|
|
102
79
|
|
|
103
80
|
export function DataWorkspace() {
|
|
104
81
|
const searchParams = useSearchParams();
|
|
105
|
-
const router = useRouter();
|
|
106
82
|
const pathname = usePathname();
|
|
107
83
|
|
|
108
84
|
const getInitialTab = (): TopTabId => {
|
|
@@ -165,30 +141,6 @@ export function DataWorkspace() {
|
|
|
165
141
|
});
|
|
166
142
|
const { mutate: mutateDocuments } = docsQuery;
|
|
167
143
|
const documents = docsQuery.data?.documents ?? [];
|
|
168
|
-
const stats = docsQuery.data?.stats;
|
|
169
|
-
const docCount = stats?.docCount ?? 0;
|
|
170
|
-
|
|
171
|
-
useEffect(() => {
|
|
172
|
-
const prevJobs = prevJobsRef.current;
|
|
173
|
-
if (prevJobs.length > 0 && jobs.length > 0) {
|
|
174
|
-
const justCompleted = jobs.filter(
|
|
175
|
-
(j) =>
|
|
176
|
-
j.status === 'completed' &&
|
|
177
|
-
prevJobs.some(
|
|
178
|
-
(pj) => pj.id === j.id && (pj.status === 'running' || pj.status === 'queued'),
|
|
179
|
-
),
|
|
180
|
-
);
|
|
181
|
-
|
|
182
|
-
if (justCompleted.length > 0) {
|
|
183
|
-
toast.success('Scraping completed.');
|
|
184
|
-
// Refresh the corpus immediately so new documents appear.
|
|
185
|
-
mutateDocuments();
|
|
186
|
-
// Documents may still be flushing — re-fetch after a short delay.
|
|
187
|
-
setTimeout(() => mutateDocuments(), 2500);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
prevJobsRef.current = jobs;
|
|
191
|
-
}, [jobs, mutateDocuments]);
|
|
192
144
|
|
|
193
145
|
const indexQuery = useSWR<{
|
|
194
146
|
unindexedCount: number;
|
|
@@ -197,9 +149,7 @@ export function DataWorkspace() {
|
|
|
197
149
|
}>('/api/index', fetcher, {
|
|
198
150
|
refreshInterval: (d) => (d?.running ? 2000 : 0),
|
|
199
151
|
});
|
|
200
|
-
const unindexedCount = indexQuery.data?.unindexedCount ?? 0;
|
|
201
152
|
const indexRunning = indexQuery.data?.running ?? false;
|
|
202
|
-
const hasCompletedIndex = indexQuery.data?.run?.status === 'completed';
|
|
203
153
|
const { mutate: mutateIndex } = indexQuery;
|
|
204
154
|
|
|
205
155
|
const prevIndexRunning = useRef(indexRunning);
|
|
@@ -219,9 +169,54 @@ export function DataWorkspace() {
|
|
|
219
169
|
mutateGlobal('/api/index');
|
|
220
170
|
};
|
|
221
171
|
|
|
172
|
+
const startAutomaticIndex = useCallback(async () => {
|
|
173
|
+
try {
|
|
174
|
+
const res = await fetch('/api/index', {
|
|
175
|
+
method: 'POST',
|
|
176
|
+
headers: { 'Content-Type': 'application/json' },
|
|
177
|
+
body: JSON.stringify({ incremental: indexQuery.data?.run?.status === 'completed' }),
|
|
178
|
+
});
|
|
179
|
+
const body = await res.json();
|
|
180
|
+
if (res.status === 409) return;
|
|
181
|
+
if (!res.ok) {
|
|
182
|
+
toast.error(body.error || 'Your data was added, but indexing could not start.');
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
toast.success('Making your data searchable', {
|
|
186
|
+
description: 'This continues in the background. You can safely leave this page.',
|
|
187
|
+
duration: 7_000,
|
|
188
|
+
});
|
|
189
|
+
setIndexDialogOpen(true);
|
|
190
|
+
void indexQuery.mutate();
|
|
191
|
+
} catch {
|
|
192
|
+
toast.error('Your data was added, but indexing could not start.');
|
|
193
|
+
}
|
|
194
|
+
}, [indexQuery]);
|
|
195
|
+
|
|
196
|
+
useEffect(() => {
|
|
197
|
+
const prevJobs = prevJobsRef.current;
|
|
198
|
+
if (prevJobs.length > 0 && jobs.length > 0) {
|
|
199
|
+
const justCompleted = jobs.filter(
|
|
200
|
+
(j) =>
|
|
201
|
+
j.status === 'completed' &&
|
|
202
|
+
prevJobs.some(
|
|
203
|
+
(pj) => pj.id === j.id && (pj.status === 'running' || pj.status === 'queued'),
|
|
204
|
+
),
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
if (justCompleted.length > 0) {
|
|
208
|
+
toast.success('Scraping completed. Making the new pages searchable…');
|
|
209
|
+
void mutateDocuments();
|
|
210
|
+
setTimeout(() => void mutateDocuments(), 2500);
|
|
211
|
+
void startAutomaticIndex();
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
prevJobsRef.current = jobs;
|
|
215
|
+
}, [jobs, mutateDocuments, startAutomaticIndex]);
|
|
216
|
+
|
|
222
217
|
const handleDataAdded = () => {
|
|
223
218
|
refreshAll();
|
|
224
|
-
|
|
219
|
+
void startAutomaticIndex();
|
|
225
220
|
};
|
|
226
221
|
|
|
227
222
|
const handleScrapeStarted = useCallback(
|
|
@@ -330,79 +325,17 @@ export function DataWorkspace() {
|
|
|
330
325
|
</button>
|
|
331
326
|
)}
|
|
332
327
|
|
|
333
|
-
{
|
|
334
|
-
<AlertDialog>
|
|
335
|
-
<AlertDialogTrigger
|
|
336
|
-
render={
|
|
337
|
-
<Button variant="outline" className="h-10 bg-white px-4 text-sm gap-1.5">
|
|
338
|
-
<RotateCcw className="size-3.5" />
|
|
339
|
-
Re-Index
|
|
340
|
-
</Button>
|
|
341
|
-
}
|
|
342
|
-
/>
|
|
343
|
-
<AlertDialogContent>
|
|
344
|
-
<AlertDialogHeader>
|
|
345
|
-
<AlertDialogTitle>Are you sure you want to re-index data?</AlertDialogTitle>
|
|
346
|
-
<AlertDialogDescription>
|
|
347
|
-
This will rebuild the entire index from scratch. All documents will be
|
|
348
|
-
re-processed.
|
|
349
|
-
</AlertDialogDescription>
|
|
350
|
-
</AlertDialogHeader>
|
|
351
|
-
<AlertDialogFooter>
|
|
352
|
-
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
|
353
|
-
<AlertDialogAction
|
|
354
|
-
onClick={() => {
|
|
355
|
-
fetch('/api/index', {
|
|
356
|
-
method: 'POST',
|
|
357
|
-
body: JSON.stringify({ incremental: false }),
|
|
358
|
-
headers: { 'Content-Type': 'application/json' },
|
|
359
|
-
}).then(() => {
|
|
360
|
-
toast.success('Indexing started.');
|
|
361
|
-
setIndexDialogOpen(true);
|
|
362
|
-
indexQuery.mutate();
|
|
363
|
-
});
|
|
364
|
-
}}
|
|
365
|
-
>
|
|
366
|
-
Continue
|
|
367
|
-
</AlertDialogAction>
|
|
368
|
-
</AlertDialogFooter>
|
|
369
|
-
</AlertDialogContent>
|
|
370
|
-
</AlertDialog>
|
|
371
|
-
)}
|
|
372
|
-
|
|
328
|
+
{/* Indexing begins automatically after data is added. */}
|
|
373
329
|
<Dialog open={indexDialogOpen} onOpenChange={setIndexDialogOpen}>
|
|
374
|
-
<
|
|
375
|
-
render={
|
|
376
|
-
<Button
|
|
377
|
-
variant={indexRunning ? 'success' : 'default'}
|
|
378
|
-
disabled={(docCount === 0 || unindexedCount === 0) && !indexRunning}
|
|
379
|
-
className="h-10 rounded-md px-4 gap-1.5 text-sm"
|
|
380
|
-
>
|
|
381
|
-
{indexRunning ? (
|
|
382
|
-
<>
|
|
383
|
-
<span className="relative flex size-2">
|
|
384
|
-
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-white opacity-75" />
|
|
385
|
-
<span className="relative inline-flex size-2 rounded-full bg-white" />
|
|
386
|
-
</span>
|
|
387
|
-
Indexing…
|
|
388
|
-
</>
|
|
389
|
-
) : (
|
|
390
|
-
<>
|
|
391
|
-
<Zap className="size-3.5" />
|
|
392
|
-
{unindexedCount > 0 ? `Start Indexing (${unindexedCount})` : 'Start Indexing'}
|
|
393
|
-
</>
|
|
394
|
-
)}
|
|
395
|
-
</Button>
|
|
396
|
-
}
|
|
397
|
-
/>
|
|
398
|
-
<DialogContent className="max-w-2xl max-h-[85vh] overflow-y-auto ">
|
|
330
|
+
<DialogContent className="max-w-lg overflow-y-auto">
|
|
399
331
|
<DialogHeader>
|
|
400
|
-
<DialogTitle>
|
|
332
|
+
<DialogTitle>Making your data searchable</DialogTitle>
|
|
401
333
|
<DialogDescription>
|
|
402
|
-
|
|
334
|
+
This runs safely in the background. You can close this and come back anytime.
|
|
403
335
|
</DialogDescription>
|
|
404
336
|
</DialogHeader>
|
|
405
337
|
<IndexWorkspace
|
|
338
|
+
automatic
|
|
406
339
|
onDone={() => {
|
|
407
340
|
indexQuery.mutate();
|
|
408
341
|
setResetKey((k) => k + 1);
|
|
@@ -29,16 +29,6 @@ interface LocalResponse {
|
|
|
29
29
|
|
|
30
30
|
const fetcher = (url: string) => fetch(url).then((r) => r.json());
|
|
31
31
|
|
|
32
|
-
/**
|
|
33
|
-
* Web-crawler launcher notice.
|
|
34
|
-
*
|
|
35
|
-
* Adapts to the runtime environment:
|
|
36
|
-
* - **Web / Desktop**: starts Larkup's built-in crawler (no Docker required).
|
|
37
|
-
* - **Docker**: detects a sibling crawler service on the Docker network.
|
|
38
|
-
*
|
|
39
|
-
* The API key (cloud) option is managed in Settings — this component only
|
|
40
|
-
* handles the local/Docker launcher.
|
|
41
|
-
*/
|
|
42
32
|
export function FirecrawlNotice({
|
|
43
33
|
cloudConfigured = false,
|
|
44
34
|
onChange,
|
|
@@ -76,7 +66,7 @@ export function FirecrawlNotice({
|
|
|
76
66
|
description:
|
|
77
67
|
runtimeEnv === 'docker'
|
|
78
68
|
? 'Checking if the crawler service is available on the network.'
|
|
79
|
-
: 'Starting Larkup’s built-in crawler.
|
|
69
|
+
: 'Starting Larkup’s built-in crawler. ',
|
|
80
70
|
},
|
|
81
71
|
);
|
|
82
72
|
}
|