@agent-native/core 0.80.11 → 0.81.1
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/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +53 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/cli/design-connect.ts +419 -19
- package/corpus/core/src/client/AgentPanel.tsx +33 -1
- package/corpus/core/src/client/ConnectBuilderCard.tsx +1 -0
- package/corpus/core/src/client/chat/index.ts +1 -0
- package/corpus/core/src/client/chat/run-recovery.tsx +9 -7
- package/corpus/core/src/client/chat-view-transition.ts +33 -2
- package/corpus/core/src/client/composer/PromptComposer.tsx +21 -2
- package/corpus/core/src/client/index.ts +1 -0
- package/corpus/core/src/client/org/OrgSwitcher.tsx +26 -4
- package/corpus/core/src/client/sharing/ShareButton.tsx +3 -3
- package/corpus/core/src/client/use-agent-chat-home-handoff.ts +31 -3
- package/corpus/core/src/db/client.ts +29 -2
- package/corpus/core/src/provider-api/index.ts +29 -0
- package/corpus/core/src/server/core-routes-plugin.ts +58 -20
- package/corpus/core/src/styles/agent-native.css +54 -0
- package/corpus/core/src/usage/store.ts +2 -2
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +118 -10
- package/corpus/templates/analytics/app/components/layout/layout-route-policy.ts +7 -0
- package/corpus/templates/analytics/app/global.css +8 -0
- package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +7 -1
- package/corpus/templates/analytics/app/lib/chat-handoff.ts +34 -0
- package/corpus/templates/analytics/app/pages/Ask.tsx +9 -18
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +2 -2
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +109 -21
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +4 -6
- package/corpus/templates/analytics/changelog/2026-06-30-ask-opens-a-fresh-chat-unless-you-were-just-chatting-and-das.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-30-dashboard-email-reports-are-more-reliable-and-use-cleaner.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-30-dashboard-toolbar-controls-use-a-quieter-share-button-and-ve.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-30-session-replay-rows-show-whole-minute-durations-in-the-playl.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-30-session-replays-now-render-captured-styling-and-keep-the-eve.md +6 -0
- package/corpus/templates/analytics/server/jobs/dashboard-report.ts +16 -3
- package/corpus/templates/analytics/server/lib/dashboard-report.ts +31 -14
- package/corpus/templates/assets/actions/open-asset-picker.ts +9 -0
- package/corpus/templates/assets/app/global.css +15 -0
- package/corpus/templates/assets/app/hooks/use-navigation-state.ts +4 -0
- package/corpus/templates/assets/app/routes/library.tsx +90 -16
- package/corpus/templates/assets/changelog/2026-06-30-the-assets-picker-now-supports-a-vertical-embedded-layout-fo.md +6 -0
- package/corpus/templates/clips/actions/finalize-recording.ts +1 -12
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +10 -5
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +6 -8
- package/corpus/templates/clips/changelog/2026-06-30-extension-save-recovery-avoids-false-upload-failures.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-30-longer-chrome-extension-recordings-now-keep-saving-reliably-.md +6 -0
- package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
- package/corpus/templates/clips/chrome-extension/src/background.ts +19 -10
- package/corpus/templates/clips/chrome-extension/src/content-script.ts +38 -12
- package/corpus/templates/clips/chrome-extension/src/finalize-recovery.ts +224 -0
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +119 -16
- package/corpus/templates/clips/chrome-extension/src/overlay.ts +16 -0
- package/corpus/templates/clips/server/lib/recording-upload-state.ts +48 -0
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +9 -1
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +63 -13
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/status.get.ts +74 -0
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +32 -0
- package/corpus/templates/design/AGENTS.md +27 -0
- package/corpus/templates/design/CODE_NATIVE_DESIGN_STUDIO_IMPLEMENTATION_PLAN.md +1 -1
- package/corpus/templates/design/DESIGN-STUDIO-PLAN.md +5 -5
- package/corpus/templates/design/actions/apply-component-prop-edit.ts +63 -20
- package/corpus/templates/design/actions/apply-motion-edit.ts +67 -69
- package/corpus/templates/design/actions/apply-shader-fill.ts +148 -56
- package/corpus/templates/design/actions/capture-design-state.ts +27 -4
- package/corpus/templates/design/actions/connect-localhost.ts +59 -22
- package/corpus/templates/design/actions/export-zip.ts +23 -8
- package/corpus/templates/design/actions/generate-design.ts +53 -1
- package/corpus/templates/design/actions/get-component-details.ts +5 -19
- package/corpus/templates/design/actions/get-motion-timeline.ts +135 -10
- package/corpus/templates/design/actions/grant-localhost-write-consent.ts +116 -0
- package/corpus/templates/design/actions/import-design-tokens.ts +521 -0
- package/corpus/templates/design/actions/index-design-tokens.ts +10 -1
- package/corpus/templates/design/actions/insert-design-native-asset.ts +268 -0
- package/corpus/templates/design/actions/insert-figma-library-asset.ts +233 -0
- package/corpus/templates/design/actions/list-design-extensions.ts +32 -10
- package/corpus/templates/design/actions/list-design-native-assets.ts +105 -0
- package/corpus/templates/design/actions/list-figma-library-assets.ts +292 -0
- package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +238 -0
- package/corpus/templates/design/actions/navigate.ts +18 -3
- package/corpus/templates/design/actions/provider-api-catalog.ts +2 -2
- package/corpus/templates/design/actions/provider-api-docs.ts +1 -1
- package/corpus/templates/design/actions/provider-api-request.ts +3 -3
- package/corpus/templates/design/actions/revoke-localhost-write-consent.ts +48 -0
- package/corpus/templates/design/actions/run-design-audit.ts +53 -4
- package/corpus/templates/design/actions/run-design-extension-action.ts +1 -1
- package/corpus/templates/design/actions/view-screen.ts +1 -1
- package/corpus/templates/design/actions/write-local-file.ts +213 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +230 -3308
- package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +30 -20
- package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +776 -287
- package/corpus/templates/design/app/components/design/EditPanel.tsx +212 -208
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +14 -2
- package/corpus/templates/design/app/components/design/LocalhostWriteConsentDialog.tsx +161 -0
- package/corpus/templates/design/app/components/design/MotionDock.tsx +235 -266
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +490 -55
- package/corpus/templates/design/app/components/design/ReviewPanel.tsx +43 -62
- package/corpus/templates/design/app/components/design/StatesPanel.tsx +34 -61
- package/corpus/templates/design/app/components/design/TokensPanel.tsx +251 -0
- package/corpus/templates/design/app/components/design/bridge/codegen.ts +125 -0
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +4037 -0
- package/corpus/templates/design/app/components/design/bridge/embedded-wheel.bridge.ts +62 -0
- package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +272 -0
- package/corpus/templates/design/app/components/design/bridge/nav.bridge.ts +116 -0
- package/corpus/templates/design/app/components/design/bridge/sample.bridge.ts +24 -0
- package/corpus/templates/design/app/components/design/bridge/shader-fill-preview.bridge.ts +78 -0
- package/corpus/templates/design/app/components/design/bridge/tsconfig.json +17 -0
- package/corpus/templates/design/app/components/design/bridge/tweak.bridge.ts +28 -0
- package/corpus/templates/design/app/components/design/bridge/zoom.bridge.ts +43 -0
- package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +45 -16
- package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +88 -9
- package/corpus/templates/design/app/components/editor/PromptDialog.tsx +94 -9
- package/corpus/templates/design/app/components/layout/Layout.tsx +19 -3
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +1 -1
- package/corpus/templates/design/app/global.css +7 -0
- package/corpus/templates/design/app/hooks/use-navigation-state.ts +23 -0
- package/corpus/templates/design/app/i18n/zh-TW.ts +21 -0
- package/corpus/templates/design/app/i18n-data.ts +358 -0
- package/corpus/templates/design/app/lib/pending-generation.ts +1 -0
- package/corpus/templates/design/app/pages/DesignEditor.tsx +2402 -499
- package/corpus/templates/design/app/pages/Index.tsx +5 -1
- package/corpus/templates/design/changelog/2026-06-30-applying-the-one-click-fix-for-a-small-tap-target-accessibil.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-canvas-creation-screen-dragging-undo-redo-and-image-fill-edi.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-component-prop-edits-and-shader-fills-now-preserve-rapid-sam.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-can-browse-figma-library-components-and-insert-them-i.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-now-has-a-figma-style-left-rail-for-file-agent-assets.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-now-has-native-components-embedded-media-and-figma-im.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-preview-now-includes-a-publish-app-waitlist-option-fr.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-s-left-rail-now-matches-the-sidebar-chrome-and-uses-t.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-s-tools-create-menu-now-stays-compact-instead-of-rend.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-starter-prompts-now-begin-generating-immediately-and-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-tools-now-use-a-quieter-figma-style-list-layout.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-drawing-rectangles-on-the-all-screens-canvas-no-longer-flash.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-fixed-code-native-design-studio-edits-so-component-props-mot.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-fixed-visual-editing-hover-overlays-and-spacing-handles-so-s.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-motion-edits-now-save-automatically-without-a-separate-css-a.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-motion-timelines-now-reopen-as-editable-tracks-after-writing.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-new-design-prompts-with-uploaded-screenshots-work-reliably-o.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-screen-previews-in-all-screens-view-now-keep-rounded-outline.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-selection-outlines-now-sit-flush-on-rectangles-drawn-directl.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-share-options-use-a-tighter-design-editor-popover-with-compa.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-the-collapsed-motion-panel-now-stays-tucked-under-the-left-s.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-the-design-inspector-now-shows-states-and-review-in-a-tighte.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-the-sidebar-keeps-the-organization-picker-space-stable-while.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-tokens-can-now-be-imported-from-pasted-notes-code-files-fold.md +6 -0
- package/corpus/templates/design/e2e/helpers.ts +168 -65
- package/corpus/templates/design/package.json +3 -1
- package/corpus/templates/design/server/db/schema.ts +23 -0
- package/corpus/templates/design/server/handlers/uploads.ts +22 -1
- package/corpus/templates/design/server/lib/provider-api.ts +7 -4
- package/corpus/templates/design/server/lib/verify-write-grant.ts +108 -0
- package/corpus/templates/design/server/plugins/db.ts +39 -0
- package/corpus/templates/design/server/register-secrets.ts +38 -0
- package/corpus/templates/design/shared/board-file.ts +228 -0
- package/corpus/templates/design/shared/board-objects.ts +288 -0
- package/corpus/templates/design/shared/code-layer.ts +52 -0
- package/corpus/templates/design/shared/motion-compiler.ts +58 -7
- package/corpus/templates/design/shared/motion-timeline.ts +2 -2
- package/corpus/templates/design/tsconfig.json +2 -1
- package/corpus/templates/slides/AGENTS.md +9 -0
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +4 -0
- package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +4 -24
- package/corpus/templates/slides/app/lib/export-pdf-client.ts +29 -20
- package/corpus/templates/slides/app/lib/export-pptx-client.ts +365 -0
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +12 -9
- package/corpus/templates/slides/app/vite-env.d.ts +18 -0
- package/corpus/templates/slides/changelog/2026-06-30-powerpoint-downloads-now-preserve-the-rendered-slide-layout-.md +6 -0
- package/corpus/templates/slides/changelog/2026-06-30-unavailable-decks-open-in-a-cleaner-full-height-centered-sta.md +6 -0
- package/corpus/templates/slides/package.json +1 -0
- package/corpus/templates/slides/vite.config.ts +1 -0
- package/dist/cli/design-connect.d.ts +25 -0
- package/dist/cli/design-connect.d.ts.map +1 -1
- package/dist/cli/design-connect.js +357 -18
- package/dist/cli/design-connect.js.map +1 -1
- package/dist/client/AgentPanel.d.ts +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +18 -3
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
- package/dist/client/ConnectBuilderCard.js +1 -0
- package/dist/client/ConnectBuilderCard.js.map +1 -1
- package/dist/client/chat/index.d.ts +1 -1
- package/dist/client/chat/index.d.ts.map +1 -1
- package/dist/client/chat/index.js +1 -1
- package/dist/client/chat/index.js.map +1 -1
- package/dist/client/chat/run-recovery.d.ts.map +1 -1
- package/dist/client/chat/run-recovery.js +5 -5
- package/dist/client/chat/run-recovery.js.map +1 -1
- package/dist/client/chat-view-transition.d.ts +6 -0
- package/dist/client/chat-view-transition.d.ts.map +1 -1
- package/dist/client/chat-view-transition.js +23 -2
- package/dist/client/chat-view-transition.js.map +1 -1
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +3 -2
- package/dist/client/composer/PromptComposer.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +11 -4
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/sharing/ShareButton.js +3 -3
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/client/use-agent-chat-home-handoff.d.ts +8 -2
- package/dist/client/use-agent-chat-home-handoff.d.ts.map +1 -1
- package/dist/client/use-agent-chat-home-handoff.js +20 -6
- package/dist/client/use-agent-chat-home-handoff.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/db/client.d.ts +1 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +28 -2
- package/dist/db/client.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +8 -8
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/index.d.ts +5 -4
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +28 -0
- package/dist/provider-api/index.js.map +1 -1
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/core-routes-plugin.d.ts +25 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +43 -18
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/styles/agent-native.css +54 -0
- package/dist/usage/store.js +2 -2
- package/dist/usage/store.js.map +1 -1
- package/package.json +1 -1
|
@@ -57,6 +57,7 @@ export type LayersPanelNodeType =
|
|
|
57
57
|
| "image"
|
|
58
58
|
| "code"
|
|
59
59
|
| "element"
|
|
60
|
+
| "board-element"
|
|
60
61
|
| "unknown";
|
|
61
62
|
|
|
62
63
|
export interface LayersPanelNode {
|
|
@@ -151,6 +152,7 @@ export interface LayersPanelProps {
|
|
|
151
152
|
expandedIds: readonly string[];
|
|
152
153
|
searchQuery: string;
|
|
153
154
|
className?: string;
|
|
155
|
+
footer?: ReactNode;
|
|
154
156
|
labels?: Partial<LayersPanelLabels>;
|
|
155
157
|
onSearchQueryChange: (query: string) => void;
|
|
156
158
|
onScreenSelect?: (id: string) => void;
|
|
@@ -168,6 +170,9 @@ export interface LayersPanelProps {
|
|
|
168
170
|
onLeaveLayer?: (id: string) => void;
|
|
169
171
|
onMoveLayer?: (intent: LayersPanelMoveIntent) => void;
|
|
170
172
|
canMoveLayer?: (intent: LayersPanelMoveIntent) => boolean;
|
|
173
|
+
// Board elements — top-level layer nodes projected from the board file.
|
|
174
|
+
// When absent the panel is unchanged.
|
|
175
|
+
boardElements?: LayersPanelNode[];
|
|
171
176
|
}
|
|
172
177
|
|
|
173
178
|
export interface FlatLayerRow {
|
|
@@ -283,14 +288,16 @@ function buildRootNodes({
|
|
|
283
288
|
layers,
|
|
284
289
|
codeLayers,
|
|
285
290
|
elementLayers,
|
|
291
|
+
boardElements,
|
|
286
292
|
labels,
|
|
287
293
|
}: Pick<
|
|
288
294
|
LayersPanelProps,
|
|
289
|
-
"files" | "layers" | "codeLayers" | "elementLayers"
|
|
295
|
+
"files" | "layers" | "codeLayers" | "elementLayers" | "boardElements"
|
|
290
296
|
> & {
|
|
291
297
|
labels: LayersPanelLabels;
|
|
292
298
|
}) {
|
|
293
299
|
const roots: LayersPanelNode[] = [
|
|
300
|
+
...(boardElements ?? []),
|
|
294
301
|
...(files?.map(asFileNode) ?? []),
|
|
295
302
|
...(layers ?? []),
|
|
296
303
|
];
|
|
@@ -491,6 +498,7 @@ export function LayersPanel({
|
|
|
491
498
|
expandedIds,
|
|
492
499
|
searchQuery,
|
|
493
500
|
className,
|
|
501
|
+
footer,
|
|
494
502
|
labels: labelsProp,
|
|
495
503
|
onSearchQueryChange,
|
|
496
504
|
onScreenSelect,
|
|
@@ -505,6 +513,7 @@ export function LayersPanel({
|
|
|
505
513
|
onLeaveLayer,
|
|
506
514
|
onMoveLayer,
|
|
507
515
|
canMoveLayer,
|
|
516
|
+
boardElements,
|
|
508
517
|
}: LayersPanelProps) {
|
|
509
518
|
const t = useT();
|
|
510
519
|
const labels = useMemo(() => mergeLabels(labelsProp, t), [labelsProp, t]);
|
|
@@ -529,9 +538,10 @@ export function LayersPanel({
|
|
|
529
538
|
layers,
|
|
530
539
|
codeLayers,
|
|
531
540
|
elementLayers,
|
|
541
|
+
boardElements,
|
|
532
542
|
labels,
|
|
533
543
|
}),
|
|
534
|
-
[codeLayers, elementLayers, files, labels, layers],
|
|
544
|
+
[boardElements, codeLayers, elementLayers, files, labels, layers],
|
|
535
545
|
);
|
|
536
546
|
|
|
537
547
|
const visibleRows = useMemo(() => {
|
|
@@ -916,6 +926,7 @@ export function LayersPanel({
|
|
|
916
926
|
</div>
|
|
917
927
|
)}
|
|
918
928
|
</div>
|
|
929
|
+
{footer ? <div className="shrink-0">{footer}</div> : null}
|
|
919
930
|
</aside>
|
|
920
931
|
);
|
|
921
932
|
}
|
|
@@ -1557,6 +1568,7 @@ function LayerGlyph({
|
|
|
1557
1568
|
case "component":
|
|
1558
1569
|
case "instance":
|
|
1559
1570
|
return <ComponentLayerGlyph className={cn(common, componentColor)} />;
|
|
1571
|
+
case "board-element":
|
|
1560
1572
|
case "shape":
|
|
1561
1573
|
case "rectangle":
|
|
1562
1574
|
return <RectangleLayerGlyph className={common} />;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { callAction } from "@agent-native/core/client";
|
|
2
|
+
import { IconDeviceFloppy, IconFolderOpen } from "@tabler/icons-react";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
|
|
5
|
+
import { Button } from "@/components/ui/button";
|
|
6
|
+
import {
|
|
7
|
+
Dialog,
|
|
8
|
+
DialogContent,
|
|
9
|
+
DialogDescription,
|
|
10
|
+
DialogFooter,
|
|
11
|
+
DialogHeader,
|
|
12
|
+
DialogTitle,
|
|
13
|
+
} from "@/components/ui/dialog";
|
|
14
|
+
import { Spinner } from "@/components/ui/spinner";
|
|
15
|
+
|
|
16
|
+
export interface LocalhostWriteConsentPayload {
|
|
17
|
+
/** The path being granted write access. */
|
|
18
|
+
rootPath: string;
|
|
19
|
+
/** File(s) about to be written (for display only). */
|
|
20
|
+
files: string[];
|
|
21
|
+
/** Pending callback to invoke after user grants consent. */
|
|
22
|
+
onGranted: (grant: {
|
|
23
|
+
grantId: string;
|
|
24
|
+
bridgeToken: string;
|
|
25
|
+
rootPath: string;
|
|
26
|
+
grantedUntil: string;
|
|
27
|
+
}) => void;
|
|
28
|
+
/** Called when the user cancels. */
|
|
29
|
+
onCancel: () => void;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface LocalhostWriteConsentDialogProps {
|
|
33
|
+
open: boolean;
|
|
34
|
+
onOpenChange: (open: boolean) => void;
|
|
35
|
+
designId: string;
|
|
36
|
+
connectionId: string;
|
|
37
|
+
payload: LocalhostWriteConsentPayload | null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Modal dialog requesting explicit user consent before the agent writes local
|
|
42
|
+
* files. Shows the rootPath that will be granted write access and the specific
|
|
43
|
+
* file(s) about to be modified. The grant expires after 8 hours and is scoped
|
|
44
|
+
* to that folder only.
|
|
45
|
+
*/
|
|
46
|
+
export function LocalhostWriteConsentDialog({
|
|
47
|
+
open,
|
|
48
|
+
onOpenChange,
|
|
49
|
+
designId,
|
|
50
|
+
connectionId,
|
|
51
|
+
payload,
|
|
52
|
+
}: LocalhostWriteConsentDialogProps) {
|
|
53
|
+
const [granting, setGranting] = useState(false);
|
|
54
|
+
|
|
55
|
+
async function handleAllowWrites() {
|
|
56
|
+
if (!payload || !designId || !connectionId) return;
|
|
57
|
+
setGranting(true);
|
|
58
|
+
try {
|
|
59
|
+
const result = await callAction<{
|
|
60
|
+
grantId: string;
|
|
61
|
+
bridgeToken: string;
|
|
62
|
+
rootPath: string;
|
|
63
|
+
grantedUntil: string;
|
|
64
|
+
}>("grant-localhost-write-consent", {
|
|
65
|
+
designId,
|
|
66
|
+
connectionId,
|
|
67
|
+
});
|
|
68
|
+
onOpenChange(false);
|
|
69
|
+
payload.onGranted(result);
|
|
70
|
+
} catch {
|
|
71
|
+
// Silently close; the caller's onCancel path already guards the write.
|
|
72
|
+
onOpenChange(false);
|
|
73
|
+
payload.onCancel();
|
|
74
|
+
} finally {
|
|
75
|
+
setGranting(false);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function handleCancel() {
|
|
80
|
+
payload?.onCancel();
|
|
81
|
+
onOpenChange(false);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (!payload) return null;
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<Dialog
|
|
88
|
+
open={open}
|
|
89
|
+
onOpenChange={(next) => {
|
|
90
|
+
if (!next) handleCancel();
|
|
91
|
+
else onOpenChange(next);
|
|
92
|
+
}}
|
|
93
|
+
>
|
|
94
|
+
<DialogContent className="max-w-md">
|
|
95
|
+
<DialogHeader>
|
|
96
|
+
<DialogTitle className="flex items-center gap-2">
|
|
97
|
+
<IconDeviceFloppy className="size-4" />
|
|
98
|
+
{"Allow file writes" /* i18n-ignore */}
|
|
99
|
+
</DialogTitle>
|
|
100
|
+
<DialogDescription>
|
|
101
|
+
{
|
|
102
|
+
"The agent wants to write source files on your machine. This access is scoped to the folder below and expires automatically after 8 hours." /* i18n-ignore */
|
|
103
|
+
}
|
|
104
|
+
</DialogDescription>
|
|
105
|
+
</DialogHeader>
|
|
106
|
+
|
|
107
|
+
<div className="space-y-3 py-1 text-sm">
|
|
108
|
+
<div className="rounded-lg border bg-muted/50 px-3 py-2">
|
|
109
|
+
<div className="flex items-center gap-2 text-xs font-medium text-muted-foreground mb-1">
|
|
110
|
+
<IconFolderOpen className="size-3.5 shrink-0" />
|
|
111
|
+
{"Root folder" /* i18n-ignore */}
|
|
112
|
+
</div>
|
|
113
|
+
<code className="break-all text-xs text-foreground">
|
|
114
|
+
{payload.rootPath}
|
|
115
|
+
</code>
|
|
116
|
+
</div>
|
|
117
|
+
|
|
118
|
+
{payload.files.length > 0 && (
|
|
119
|
+
<div className="space-y-1">
|
|
120
|
+
<p className="text-xs font-medium text-muted-foreground">
|
|
121
|
+
{"Files to be written:" /* i18n-ignore */}
|
|
122
|
+
</p>
|
|
123
|
+
<ul className="space-y-0.5 pl-1">
|
|
124
|
+
{payload.files.map((file) => (
|
|
125
|
+
<li key={file} className="flex items-center gap-1.5 text-xs">
|
|
126
|
+
<span className="size-1 rounded-full bg-muted-foreground/50 shrink-0" />
|
|
127
|
+
<code className="break-all">{file}</code>
|
|
128
|
+
</li>
|
|
129
|
+
))}
|
|
130
|
+
</ul>
|
|
131
|
+
</div>
|
|
132
|
+
)}
|
|
133
|
+
|
|
134
|
+
<p className="text-xs text-muted-foreground">
|
|
135
|
+
{
|
|
136
|
+
"Only .html and .css files can be written. Paths outside the root folder are always blocked." /* i18n-ignore */
|
|
137
|
+
}
|
|
138
|
+
</p>
|
|
139
|
+
</div>
|
|
140
|
+
|
|
141
|
+
<DialogFooter className="gap-2">
|
|
142
|
+
<Button variant="outline" onClick={handleCancel} disabled={granting}>
|
|
143
|
+
{"Cancel" /* i18n-ignore */}
|
|
144
|
+
</Button>
|
|
145
|
+
<Button onClick={() => void handleAllowWrites()} disabled={granting}>
|
|
146
|
+
{
|
|
147
|
+
granting ? (
|
|
148
|
+
<>
|
|
149
|
+
<Spinner className="mr-2 size-3.5" />
|
|
150
|
+
{"Granting…" /* i18n-ignore */}
|
|
151
|
+
</>
|
|
152
|
+
) : (
|
|
153
|
+
"Allow writes"
|
|
154
|
+
) /* i18n-ignore */
|
|
155
|
+
}
|
|
156
|
+
</Button>
|
|
157
|
+
</DialogFooter>
|
|
158
|
+
</DialogContent>
|
|
159
|
+
</Dialog>
|
|
160
|
+
);
|
|
161
|
+
}
|