auricui-skill 0.0.0-stage → 0.1.2
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/LICENSE +21 -0
- package/README.md +29 -2
- package/bin/install.mjs +66 -0
- package/package.json +29 -4
- package/skill/SKILL.md +64 -0
- package/skill/agents/openai.yaml +4 -0
- package/skill/assets/examples/ApprovalCard.tsx +8 -0
- package/skill/assets/examples/BasicApp.tsx +38 -0
- package/skill/assets/examples/BriefingCard.tsx +8 -0
- package/skill/assets/examples/ChatControls.tsx +49 -0
- package/skill/assets/examples/ChatPanel.tsx +73 -0
- package/skill/assets/examples/Checkbox.tsx +13 -0
- package/skill/assets/examples/Combobox.tsx +14 -0
- package/skill/assets/examples/Drawer.tsx +10 -0
- package/skill/assets/examples/MemoryCard.tsx +9 -0
- package/skill/assets/examples/MessageList.tsx +8 -0
- package/skill/assets/examples/Theme.tsx +14 -0
- package/skill/assets/examples/ToolCall.tsx +8 -0
- package/skill/assets/examples/Tree.tsx +15 -0
- package/skill/assets/examples/examples.css +11 -0
- package/skill/assets/library/auricui-0.1.0-preview.1.tgz +0 -0
- package/skill/assets/library/auricui-0.1.0-preview.3.tgz +0 -0
- package/skill/assets/library/auricui-0.1.0-preview.4.tgz +0 -0
- package/skill/assets/upstream/LICENSE +21 -0
- package/skill/assets/upstream/apps/desktop/chat/src/App.tsx +1099 -0
- package/skill/assets/upstream/apps/desktop/chat/src/app-bridge.ts +154 -0
- package/skill/assets/upstream/apps/desktop/chat/src/chat.css +1812 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/AddSkill.tsx +223 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/AgentActivityRow.tsx +716 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/AgentIcons.tsx +46 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/AttachmentCard.tsx +34 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/AttachmentPreview.tsx +331 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/BalanceNotice.tsx +22 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/BrandLogo.tsx +35 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/ComposerCard.tsx +182 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/ConversationSessionBar.tsx +292 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/CopyDiagnostics.tsx +24 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/Divider.tsx +47 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/FileChangesList.tsx +119 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/Markdown.tsx +198 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/ModelPopover.tsx +280 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/NoticeCard.tsx +87 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/Popover.tsx +195 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/PreviewFrame.tsx +129 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/ProjectConversation.tsx +852 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/ProjectStarters.tsx +118 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/Tooltip.tsx +191 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/TurnLog.tsx +583 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/TurnQuestionCard.tsx +133 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/dock-pane-bar.ts +14 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/project-version.ts +37 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/prompt-editor/MentionMenuPlugin.tsx +372 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/prompt-editor/PromptEditor.tsx +476 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/prompt-editor/PromptPill.tsx +399 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/prompt-editor/PromptReferenceNode.tsx +164 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/prompt-editor/index.ts +31 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/prompt-editor/mention-menu.ts +206 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/prompt-editor/prompt-text.ts +171 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/useStickToBottom.ts +320 -0
- package/skill/assets/upstream/apps/desktop/chat/src/components/useTicker.ts +55 -0
- package/skill/assets/upstream/apps/desktop/chat/src/i18n/index.ts +42 -0
- package/skill/assets/upstream/apps/desktop/chat/src/i18n/locales/en-US.ts +408 -0
- package/skill/assets/upstream/apps/desktop/chat/src/i18n/locales/es.ts +407 -0
- package/skill/assets/upstream/apps/desktop/chat/src/i18n/locales/ja.ts +407 -0
- package/skill/assets/upstream/apps/desktop/chat/src/i18n/locales/ko.ts +403 -0
- package/skill/assets/upstream/apps/desktop/chat/src/i18n/locales/words.ts +6 -0
- package/skill/assets/upstream/apps/desktop/chat/src/i18n/locales/zh-CN.ts +407 -0
- package/skill/assets/upstream/apps/desktop/chat/src/i18n/lookup.ts +12 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/agent-activity-runs.ts +154 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/agent-menu-rows.ts +41 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/agent-refs.ts +105 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/agent-transcript.ts +440 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/asset-lists.ts +75 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/attachment-place.ts +17 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/balance.ts +16 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/chat-layer.ts +10 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/chat-menu.ts +18 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/chat-store.ts +101 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/composer-attachments.ts +189 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/desktop-attachments.ts +178 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/desktop-bridge.ts +291 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/developer.ts +39 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/esc-stop.ts +23 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/file-changes.ts +32 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/live-activity.ts +20 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/local-agent-run.ts +1174 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/local-sessions.ts +25 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/model-calls.ts +87 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/pretty-json.ts +12 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/preview-top.ts +15 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/project-resources.ts +66 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/project-sessions.ts +66 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/project-versions.ts +116 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/ref-pictures.ts +119 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/relative-time.ts +46 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/skill-pages.ts +29 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/step-file.ts +23 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/structural-share.ts +52 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/studio-film.ts +44 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/studio-transfer.ts +40 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/unprompted.ts +27 -0
- package/skill/assets/upstream/apps/desktop/chat/src/lib/upload-limits.ts +53 -0
- package/skill/assets/upstream/apps/desktop/chat/src/mount.tsx +19 -0
- package/skill/assets/upstream/apps/desktop/chat/src/state/local-agent-store.ts +296 -0
- package/skill/assets/upstream/apps/desktop/chat/src/studio-refs.ts +307 -0
- package/skill/assets/upstream/apps/desktop/package.json +51 -0
- package/skill/assets/upstream/apps/desktop/shell/bridge.ts +415 -0
- package/skill/assets/upstream/apps/desktop/shell/index.html +27 -0
- package/skill/assets/upstream/apps/desktop/shell/main.tsx +17 -0
- package/skill/assets/upstream/apps/desktop/shell/shell.css +17 -0
- package/skill/assets/upstream/apps/desktop/shell/vite.config.ts +65 -0
- package/skill/assets/upstream/apps/desktop/src/agent-definitions.mjs +31 -0
- package/skill/assets/upstream/packages/openfilm/LICENSE +21 -0
- package/skill/assets/upstream/packages/openfilm/package.json +88 -0
- package/skill/assets/upstream/packages/openfilm/src/film-doc.d.mts +125 -0
- package/skill/assets/upstream/packages/openfilm/src/film-doc.mjs +986 -0
- package/skill/assets/upstream/packages/openfilm/src/overrides.mjs +73 -0
- package/skill/assets/upstream/packages/openfilm/src/timeline.mjs +1280 -0
- package/skill/assets/upstream/packages/openfilm/studio/server/bridge.js +209 -0
- package/skill/assets/upstream/packages/openfilm/studio/server/film-subtitle.mjs +785 -0
- package/skill/assets/upstream/packages/openfilm/studio/server/ops.mjs +403 -0
- package/skill/assets/upstream/packages/openfilm/studio/server/stage.js +1649 -0
- package/skill/assets/upstream/packages/openfilm/studio/server/track-layout.mjs +43 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/App.tsx +156 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/api.ts +328 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/AudioMeters.tsx +188 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/BlockThumbs.tsx +84 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/BlockWaveform.tsx +201 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/BrandLoadingScreen.tsx +56 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/BrandLogo.tsx +25 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/Card.tsx +89 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ColorPicker.tsx +204 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ConfirmDialog.tsx +96 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ContextMenu.tsx +422 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/DesktopDialog.tsx +271 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ExamplesGallery.tsx +372 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/FilmFullscreenBar.tsx +147 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/FilmInspector.tsx +2310 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/FilmStageSelect.tsx +3296 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/FocusNav.tsx +28 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/FontFamilyPicker.tsx +293 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/FramePicker.tsx +69 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/InspectorPanel.tsx +25 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/Launcher.tsx +38 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/LayersPanel.tsx +277 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/LiveTime.tsx +101 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/MediaPool.tsx +1413 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/MediaPreview.tsx +188 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/MenuSelect.tsx +161 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/MgOutline.tsx +24 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/OperationHistory.tsx +184 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/PaneDivider.tsx +292 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/PasteAttrsDialog.tsx +69 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/PlaybackMenu.tsx +110 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/Popover.tsx +159 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ProjectCover.tsx +60 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ProjectHistoryControls.tsx +748 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ProjectLayoutMenu.tsx +82 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ProjectMenu.tsx +111 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ProjectSources.tsx +587 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ProjectView.tsx +3222 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ProjectsLibrary.tsx +567 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ProjectsView.tsx +1593 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/PropertiesSection.tsx +418 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ResourceInspector.tsx +100 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/SelectionToolbar.tsx +157 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/SkillsLibrary.tsx +504 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/SourcePreview.tsx +464 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/SpendAsks.tsx +88 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/StageMaskOverlay.tsx +299 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/StageTransformFrame.tsx +246 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/SubtitleInspector.module.css +46 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/SubtitleInspector.tsx +884 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/SubtitleOverlay.tsx +148 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/SubtitleRow.tsx +419 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/TabStrip.tsx +188 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/Timeline.tsx +4911 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/TimelineMarkers.tsx +329 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/Toast.tsx +55 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/Tooltip.tsx +193 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/UpdateButton.tsx +104 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ViewerBar.tsx +98 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/WhatsNew.tsx +147 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/dock-pane-bar.ts +16 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/export/ExportCenter.tsx +1502 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/export/ExportTray.tsx +284 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/film-stage-hit.ts +18 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/inspector-fields.tsx +863 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/inspector-look.tsx +1357 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/player-controls/controls-bar.tsx +397 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/player-controls/transport.tsx +294 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/replace-drop.ts +20 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/AgentsSection.tsx +613 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/CustomServices.tsx +104 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/DiagnosticsGroup.tsx +202 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/ModelsSection.tsx +179 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/ProviderMark.tsx +24 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/ProvidersSection.tsx +177 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/SettingsModal.tsx +511 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/SettingsSelect.tsx +84 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/ShortcutsSection.tsx +291 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/StorageGroup.tsx +119 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/theme.ts +47 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/ui.tsx +139 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/use-settings.ts +10 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/stage-menu.tsx +283 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/timeline-head-extras.tsx +91 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/typing-target.ts +45 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/use-editor-tools.tsx +408 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/use-page-changes.ts +48 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/use-project-history.ts +113 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/useBlockDrag.ts +639 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/editor/Preview.tsx +426 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/editor/player.ts +558 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/editor/preview-frames.ts +36 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/editor/steps.ts +36 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/editor/undo.ts +156 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/editor/use-film.ts +212 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/editor/use-preview-renders.ts +89 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/globals.css +559 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/i18n/en.ts +1901 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/i18n/es.ts +1900 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/i18n/index.ts +130 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/i18n/ja.ts +1900 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/i18n/ko.ts +1896 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/i18n/words.ts +6 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/i18n/zh-CN.ts +1901 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/agent-row.ts +21 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/asset-timeline.ts +469 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/audio-levels.ts +60 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/batch-map.ts +28 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/browser.ts +10 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/canvas-fit.ts +116 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/chat-marks.ts +114 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/clip-attrs.ts +102 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/clip-fade.ts +70 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/clip-look.ts +520 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/clip-mask.ts +536 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/clip-replace.ts +60 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/component-props.ts +128 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/context-length.ts +12 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/desktop-build.ts +44 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/diagnostics.ts +68 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/double-press.ts +22 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/dropped-overrides.ts +139 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/export-jobs.ts +191 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/export-spec.ts +261 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/field-input.ts +155 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/film-clip-edits.ts +82 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/film-frame.ts +134 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/film-overrides.ts +107 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/film-shape.ts +172 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/film.ts +80 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/font-menu.ts +236 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/font-styles.ts +129 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/freeze-frame.ts +49 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/host.ts +438 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/inspect-scrub.ts +26 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/keymap-store.ts +74 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/keymap.ts +529 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/layers-tree.ts +133 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/look.ts +83 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/loudness.ts +58 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/markers.ts +152 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/media-bar.ts +58 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/media-folders.ts +45 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/media-place.ts +102 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/media-queue.ts +107 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/media-selection.ts +64 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/menu-position.ts +77 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/mg-transform.ts +111 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/mixed.ts +3 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/page-changes.ts +45 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/picture-files.ts +19 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/preview-prefs.ts +46 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/preview-renders.ts +71 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/project-delete.ts +20 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/project-folders.ts +144 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/project-history.ts +188 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/project-sources.ts +283 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/projects-page.ts +40 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/provider-marks.ts +35 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/providers.ts +163 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/resource-drag.ts +131 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/retry-image.ts +17 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/saved-insert.ts +40 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/saved.ts +125 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/selection-toolbar.ts +158 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/shortcut-hint.ts +21 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/similar-layers.ts +46 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/solo.ts +19 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/stage-clip.ts +60 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/stage-crop.ts +232 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/stage-gesture.ts +277 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/stage-layers.ts +71 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/stage-mask.ts +176 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/stage-measure.ts +53 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/stage-types.ts +155 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/studio-refs.ts +248 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/studio-version.ts +41 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/subtitle-cues.ts +238 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/subtitles.ts +263 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/tab-menu.ts +6 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/template-controls.ts +131 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/theme-changes.ts +31 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/thumb-cache.ts +63 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/thumb-cell.ts +8 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/thumb-frame.ts +76 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/thumb-pick.ts +42 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/timecode.ts +161 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/timeline-clipboard.ts +279 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/timeline-drag.ts +589 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/timeline-edit.ts +1138 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/timeline-keys.ts +63 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/timeline-layout.ts +1038 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/timeline-nav.ts +160 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/timeline-prefs.ts +73 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/timeline-split.ts +40 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/timeline-view.ts +105 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/title.ts +39 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/track-heights.ts +55 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/track-lock.ts +27 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/transitions.ts +459 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/type-metrics.ts +83 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/use-film-subtitles.ts +111 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/use-fonts.ts +181 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/use-loaded-thumbs.ts +91 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/use-subtitle-edits.ts +134 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/use-subtitle-font.ts +51 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/use-subtitle-style.ts +68 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/waveform-columns.ts +48 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/web-update.ts +41 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/whats-new.ts +401 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/workspace-resources.ts +373 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/src/main.tsx +10 -0
- package/skill/assets/upstream/packages/openfilm/studio/ui/vite.config.ts +12 -0
- package/skill/assets/upstream/packages/shared/package.json +45 -0
- package/skill/assets/upstream/packages/shared/src/agent-activity.ts +263 -0
- package/skill/assets/upstream/packages/shared/src/contract.ts +285 -0
- package/skill/assets/upstream/packages/shared/src/index.ts +17 -0
- package/skill/assets/upstream/packages/shared/src/markdown-blocks.ts +252 -0
- package/skill/assets/upstream/packages/shared/src/modality.ts +4 -0
- package/skill/assets/upstream/packages/shared/src/prompt-reference.ts +113 -0
- package/skill/assets/upstream/packages/shared/src/title.ts +76 -0
- package/skill/assets/upstream/packages/shared/src/turn.ts +68 -0
- package/skill/assets/upstream/packages/shared/src/video.ts +26 -0
- package/skill/references/agent-components.md +33 -0
- package/skill/references/api-index.json +2693 -0
- package/skill/references/chat-components.md +65 -0
- package/skill/references/components.md +23 -0
- package/skill/references/core-components.md +44 -0
- package/skill/references/dependencies.md +22 -0
- package/skill/references/esm-package.md +48 -0
- package/skill/references/integration.md +43 -0
- package/skill/references/library-manifest.json +12 -0
- package/skill/references/source-manifest.json +325 -0
- package/skill/references/studio-components.md +24 -0
- package/skill/references/theme-motion.md +49 -0
- package/skill/references/troubleshooting.md +27 -0
- package/skill/references/verification.md +13 -0
- package/skill/scripts/check_dependencies.py +109 -0
- package/skill/scripts/inspect_api.py +60 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The official marks of the coding agents.
|
|
3
|
+
*
|
|
4
|
+
* Paths come unchanged from simple-icons (the brands' own published SVGs; the data is CC0). Those not in
|
|
5
|
+
* simple-icons come from the vendor: Devin's favicon.svg, unchanged; CodeBuddy, Qwen, Kimi and DeepSeek's monochrome marks
|
|
6
|
+
* from Lobe Icons (https://github.com/lobehub/lobe-icons, MIT), unchanged. They are other people's trademarks, so
|
|
7
|
+
* none is redrawn.
|
|
8
|
+
*
|
|
9
|
+
* Each is a single path, a plain shape, so all use `currentColor`: they brighten and dim with the text of their
|
|
10
|
+
* row, with no clashing brand colors on a dark background. They identify which agents are supported; they are not
|
|
11
|
+
* used as our own marks.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export type AgentIconId = 'claude' | 'codex' | 'cursor' | 'copilot' | 'opencode' | 'codebuddy' | 'qwen' | 'kimi' | 'minimax' | 'deepseek' | 'devin';
|
|
15
|
+
|
|
16
|
+
/** Codex is an OpenAI product and uses the OpenAI mark. */
|
|
17
|
+
const PATHS: Record<AgentIconId, string> = {
|
|
18
|
+
claude: 'm4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z',
|
|
19
|
+
codex: 'M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z',
|
|
20
|
+
cursor: 'M11.503.131 1.891 5.678a.84.84 0 0 0-.42.726v11.188c0 .3.162.575.42.724l9.609 5.55a1 1 0 0 0 .998 0l9.61-5.55a.84.84 0 0 0 .42-.724V6.404a.84.84 0 0 0-.42-.726L12.497.131a1.01 1.01 0 0 0-.996 0M2.657 6.338h18.55c.263 0 .43.287.297.515L12.23 22.918c-.062.107-.229.064-.229-.06V12.335a.59.59 0 0 0-.295-.51l-9.11-5.257c-.109-.063-.064-.23.061-.23',
|
|
21
|
+
copilot: 'M23.922 16.997C23.061 18.492 18.063 22.02 12 22.02 5.937 22.02.939 18.492.078 16.997A.641.641 0 0 1 0 16.741v-2.869a.883.883 0 0 1 .053-.22c.372-.935 1.347-2.292 2.605-2.656.167-.429.414-1.055.644-1.517a10.098 10.098 0 0 1-.052-1.086c0-1.331.282-2.499 1.132-3.368.397-.406.89-.717 1.474-.952C7.255 2.937 9.248 1.98 11.978 1.98c2.731 0 4.767.957 6.166 2.093.584.235 1.077.546 1.474.952.85.869 1.132 2.037 1.132 3.368 0 .368-.014.733-.052 1.086.23.462.477 1.088.644 1.517 1.258.364 2.233 1.721 2.605 2.656a.841.841 0 0 1 .053.22v2.869a.641.641 0 0 1-.078.256Zm-11.75-5.992h-.344a4.359 4.359 0 0 1-.355.508c-.77.947-1.918 1.492-3.508 1.492-1.725 0-2.989-.359-3.782-1.259a2.137 2.137 0 0 1-.085-.104L4 11.746v6.585c1.435.779 4.514 2.179 8 2.179 3.486 0 6.565-1.4 8-2.179v-6.585l-.098-.104s-.033.045-.085.104c-.793.9-2.057 1.259-3.782 1.259-1.59 0-2.738-.545-3.508-1.492a4.359 4.359 0 0 1-.355-.508Zm2.328 3.25c.549 0 1 .451 1 1v2c0 .549-.451 1-1 1-.549 0-1-.451-1-1v-2c0-.549.451-1 1-1Zm-5 0c.549 0 1 .451 1 1v2c0 .549-.451 1-1 1-.549 0-1-.451-1-1v-2c0-.549.451-1 1-1Zm3.313-6.185c.136 1.057.403 1.913.878 2.497.442.544 1.134.938 2.344.938 1.573 0 2.292-.337 2.657-.751.384-.435.558-1.15.558-2.361 0-1.14-.243-1.847-.705-2.319-.477-.488-1.319-.862-2.824-1.025-1.487-.161-2.192.138-2.533.529-.269.307-.437.808-.438 1.578v.021c0 .265.021.562.063.893Zm-1.626 0c.042-.331.063-.628.063-.894v-.02c-.001-.77-.169-1.271-.438-1.578-.341-.391-1.046-.69-2.533-.529-1.505.163-2.347.537-2.824 1.025-.462.472-.705 1.179-.705 2.319 0 1.211.175 1.926.558 2.361.365.414 1.084.751 2.657.751 1.21 0 1.902-.394 2.344-.938.475-.584.742-1.44.878-2.497Z',
|
|
22
|
+
opencode: 'M22 24H2V0h20zM17 4.8H7v14.4h10z',
|
|
23
|
+
codebuddy: 'M18.777 1.647c.28-.02.536.114.972.51 1.018.926 2.437 2.828 3.318 4.452l.34.631.482.24.11.06v3.638a5.206 5.206 0 00-5.32-1.23c-.491.166-1.021.471-2.08 1.082l-6.09 3.516c-1.057.61-1.586.916-1.975 1.259a5.208 5.208 0 00-1.493 5.572c.165.49.471 1.02 1.082 2.08l.315.543h-3.26c-.685 0-1.34-.135-1.939-.377-.169-.956-.009-1.789.469-2.335.158-.18.164-.189.13-.493a11.846 11.846 0 01-.057-1.711l.02-.444-.667-1.18C2.1 15.622 1.445 14.078 1.192 12.9c-.133-.647-.125-.934.04-1.146.1-.128.427-.261.822-.334.994-.175 3.162-.017 5.575.41l.25.043.551-.487c.915-.81 1.522-1.264 2.641-1.962 1.167-.73 2.484-1.331 3.967-1.807l.476-.152.261-.688c.937-2.471 1.896-4.293 2.58-4.9.235-.21.25-.22.422-.23zM12.139 18.2a1.203 1.203 0 011.642.44l1.296 2.243a1.204 1.204 0 01-2.083 1.203l-1.296-2.243a1.203 1.203 0 01.44-1.644zM18.629 14.452a1.203 1.203 0 011.642.44l1.295 2.244a1.203 1.203 0 11-2.083 1.203l-1.295-2.243a1.203 1.203 0 01.44-1.644z',
|
|
24
|
+
qwen: 'M12.604 1.34c.393.69.784 1.382 1.174 2.075a.18.18 0 00.157.091h5.552c.174 0 .322.11.446.327l1.454 2.57c.19.337.24.478.024.837-.26.43-.513.864-.76 1.3l-.367.658c-.106.196-.223.28-.04.512l2.652 4.637c.172.301.111.494-.043.77-.437.785-.882 1.564-1.335 2.34-.159.272-.352.375-.68.37-.777-.016-1.552-.01-2.327.016a.099.099 0 00-.081.05 575.097 575.097 0 01-2.705 4.74c-.169.293-.38.363-.725.364-.997.003-2.002.004-3.017.002a.537.537 0 01-.465-.271l-1.335-2.323a.09.09 0 00-.083-.049H4.982c-.285.03-.553-.001-.805-.092l-1.603-2.77a.543.543 0 01-.002-.54l1.207-2.12a.198.198 0 000-.197 550.951 550.951 0 01-1.875-3.272l-.79-1.395c-.16-.31-.173-.496.095-.965.465-.813.927-1.625 1.387-2.436.132-.234.304-.334.584-.335a338.3 338.3 0 012.589-.001.124.124 0 00.107-.063l2.806-4.895a.488.488 0 01.422-.246c.524-.001 1.053 0 1.583-.006L11.704 1c.341-.003.724.032.9.34zm-3.432.403a.06.06 0 00-.052.03L6.254 6.788a.157.157 0 01-.135.078H3.253c-.056 0-.07.025-.041.074l5.81 10.156c.025.042.013.062-.034.063l-2.795.015a.218.218 0 00-.2.116l-1.32 2.31c-.044.078-.021.118.068.118l5.716.008c.046 0 .08.02.104.061l1.403 2.454c.046.081.092.082.139 0l5.006-8.76.783-1.382a.055.055 0 01.096 0l1.424 2.53a.122.122 0 00.107.062l2.763-.02a.04.04 0 00.035-.02.041.041 0 000-.04l-2.9-5.086a.108.108 0 010-.113l.293-.507 1.12-1.977c.024-.041.012-.062-.035-.062H9.2c-.059 0-.073-.026-.043-.077l1.434-2.505a.107.107 0 000-.114L9.225 1.774a.06.06 0 00-.053-.031zm6.29 8.02c.046 0 .058.02.034.06l-.832 1.465-2.613 4.585a.056.056 0 01-.05.029.058.058 0 01-.05-.029L8.498 9.841c-.02-.034-.01-.052.028-.054l.216-.012 6.722-.012z',
|
|
25
|
+
kimi: 'M21.846 0a1.923 1.923 0 110 3.846H20.15a.226.226 0 01-.227-.226V1.923C19.923.861 20.784 0 21.846 0zM11.065 11.199l7.257-7.2c.137-.136.06-.41-.116-.41H14.3a.164.164 0 00-.117.051l-7.82 7.756c-.122.12-.302.013-.302-.179V3.82c0-.127-.083-.23-.185-.23H3.186c-.103 0-.186.103-.186.23V19.77c0 .128.083.23.186.23h2.69c.103 0 .186-.102.186-.23v-3.25c0-.069.025-.135.069-.178l2.424-2.406a.158.158 0 01.205-.023l6.484 4.772a7.677 7.677 0 003.453 1.283c.108.012.2-.095.2-.23v-3.06c0-.117-.07-.212-.164-.227a5.028 5.028 0 01-2.027-.807l-5.613-4.064c-.117-.078-.132-.279-.028-.381z',
|
|
26
|
+
minimax: 'M11.43 3.92a.86.86 0 1 0-1.718 0v14.236a1.999 1.999 0 0 1-3.997 0V9.022a.86.86 0 1 0-1.718 0v3.87a1.999 1.999 0 0 1-3.997 0V11.49a.57.57 0 0 1 1.139 0v1.404a.86.86 0 0 0 1.719 0V9.022a1.999 1.999 0 0 1 3.997 0v9.134a.86.86 0 0 0 1.719 0V3.92a1.998 1.998 0 1 1 3.996 0v11.788a.57.57 0 1 1-1.139 0zm10.572 3.105a2 2 0 0 0-1.999 1.997v7.63a.86.86 0 0 1-1.718 0V3.923a1.999 1.999 0 0 0-3.997 0v16.16a.86.86 0 0 1-1.719 0V18.08a.57.57 0 1 0-1.138 0v2a1.998 1.998 0 0 0 3.996 0V3.92a.86.86 0 0 1 1.719 0v12.73a1.999 1.999 0 0 0 3.996 0V9.023a.86.86 0 1 1 1.72 0v6.686a.57.57 0 0 0 1.138 0V9.022a2 2 0 0 0-1.998-1.997',
|
|
27
|
+
deepseek: 'M23.748 4.482c-.254-.124-.364.113-.512.234-.051.039-.094.09-.137.136-.372.397-.806.657-1.373.626-.829-.046-1.537.214-2.163.848-.133-.782-.575-1.248-1.247-1.548-.352-.156-.708-.311-.955-.65-.172-.241-.219-.51-.305-.774-.055-.16-.11-.323-.293-.35-.2-.031-.278.136-.356.276-.313.572-.434 1.202-.422 1.84.027 1.436.633 2.58 1.838 3.393.137.093.172.187.129.323-.082.28-.18.552-.266.833-.055.179-.137.217-.329.14a5.526 5.526 0 01-1.736-1.18c-.857-.828-1.631-1.742-2.597-2.458a11.365 11.365 0 00-.689-.471c-.985-.957.13-1.743.388-1.836.27-.098.093-.432-.779-.428-.872.004-1.67.295-2.687.684a3.055 3.055 0 01-.465.137 9.597 9.597 0 00-2.883-.102c-1.885.21-3.39 1.102-4.497 2.623C.082 8.606-.231 10.684.152 12.85c.403 2.284 1.569 4.175 3.36 5.653 1.858 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.133-.284 4.994-1.86.47.234.962.327 1.78.397.63.059 1.236-.03 1.705-.128.735-.156.684-.837.419-.961-2.155-1.004-1.682-.595-2.113-.926 1.096-1.296 2.746-2.642 3.392-7.003.05-.347.007-.565 0-.845-.004-.17.035-.237.23-.256a4.173 4.173 0 001.545-.475c1.396-.763 1.96-2.015 2.093-3.517.02-.23-.004-.467-.247-.588zM11.581 18c-2.089-1.642-3.102-2.183-3.52-2.16-.392.024-.321.471-.235.763.09.288.207.486.371.739.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.167-1.361-.802-2.5-1.86-3.301-3.307-.774-1.393-1.224-2.887-1.298-4.482-.02-.386.093-.522.477-.592a4.696 4.696 0 011.529-.039c2.132.312 3.946 1.265 5.468 2.774.868.86 1.525 1.887 2.202 2.891.72 1.066 1.494 2.082 2.48 2.914.348.292.625.514.891.677-.802.09-2.14.11-3.054-.614zm1-6.44a.306.306 0 01.415-.287.302.302 0 01.2.288.306.306 0 01-.31.307.303.303 0 01-.304-.308zm3.11 1.596c-.2.081-.399.151-.59.16a1.245 1.245 0 01-.798-.254c-.274-.23-.47-.358-.552-.758a1.73 1.73 0 01.016-.588c.07-.327-.008-.537-.239-.727-.187-.156-.426-.199-.688-.199a.559.559 0 01-.254-.078c-.11-.054-.2-.19-.114-.358.028-.054.16-.186.192-.21.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.391.451.462.576.685.914.176.265.336.537.445.848.067.195-.019.354-.25.452z',
|
|
28
|
+
devin: 'M70 159.333V91.3471C70 88.3592 71.594 85.5983 74.1816 84.1044L133.043 50.1205C135.631 48.6265 138.819 48.6265 141.407 50.1205L200.269 84.1044C202.856 85.5983 204.45 88.3592 204.45 91.3471V126.068C204.708 137.606 210.806 148.734 221.531 154.926C232.256 161.117 244.942 160.834 255.063 155.289L285.132 137.929C287.719 136.435 290.907 136.435 293.495 137.929L352.357 171.913C354.944 173.406 356.538 176.167 356.538 179.155V247.123C356.538 250.111 354.944 252.872 352.357 254.366L293.495 288.35C290.907 289.844 287.719 289.844 285.132 288.35L255.306 271.13C245.146 265.456 232.344 265.117 221.534 271.358C210.809 277.55 204.711 288.678 204.453 300.215V334.926C204.453 337.914 202.859 340.675 200.271 342.169L141.41 376.153C138.822 377.647 135.634 377.647 133.046 376.153L74.1845 342.169C71.5969 340.675 70.0028 337.914 70.0028 334.926V266.959C70.0029 263.971 71.5969 261.21 74.1845 259.716L133.046 225.732C135.634 224.238 138.822 224.238 141.41 225.732L171.547 243.132C181.656 248.638 194.306 248.906 205.005 242.729C215.815 236.488 221.922 225.231 222.088 213.595C221.83 202.057 215.732 189.737 205.008 183.545C194.283 177.353 181.597 177.636 171.476 183.181L141.269 200.72C138.67 202.229 135.461 202.228 132.864 200.716L74.1576 166.562C71.5835 165.065 70 162.311 70 159.333Z',
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/** Marks not on a 24 grid (Devin's comes from its 425-unit favicon, cropped of its margin). */
|
|
32
|
+
const VIEWBOX: Partial<Record<AgentIconId, string>> = { devin: '48 48 330 330' };
|
|
33
|
+
|
|
34
|
+
/** The Lobe Icons marks fill even-odd (so their cut-outs stay empty). */
|
|
35
|
+
const EVEN_ODD = new Set<AgentIconId>(['codebuddy', 'qwen', 'kimi', 'deepseek']);
|
|
36
|
+
|
|
37
|
+
/** Whether this agent has its own mark (those without, such as OpenFilm's own agent, use the OpenFilm mark). */
|
|
38
|
+
export const hasAgentIcon = (id: string): id is AgentIconId => Object.hasOwn(PATHS, id);
|
|
39
|
+
|
|
40
|
+
export function AgentIcon({ id, size = 18 }: { id: AgentIconId; size?: number }) {
|
|
41
|
+
return (
|
|
42
|
+
<svg width={size} height={size} viewBox={VIEWBOX[id] ?? '0 0 24 24'} fill="currentColor" fillRule={EVEN_ODD.has(id) ? 'evenodd' : undefined} aria-hidden>
|
|
43
|
+
<path d={PATHS[id]} />
|
|
44
|
+
</svg>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a message brought, as it shows in the composer and, the same, in the sent message: a picture or a video's
|
|
3
|
+
* frame as a 40px square, anything else as a card as tall: its type's icon on a small tile, its name, and under it
|
|
4
|
+
* what says most about it (a folder's place, a file's size).
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { Play } from 'lucide-react';
|
|
8
|
+
|
|
9
|
+
/** A picture's square; the caller adds its border color and what a click does. */
|
|
10
|
+
export const ATTACHMENT_THUMB = 'relative h-10 w-10 shrink-0 overflow-hidden rounded-[8px] border bg-[var(--fill-tsp)]';
|
|
11
|
+
|
|
12
|
+
/** A card's shape, left-aligned even as a button; the caller adds its border color and what a click does. */
|
|
13
|
+
export const ATTACHMENT_CARD = 'relative flex h-10 min-w-0 max-w-[180px] items-center gap-2 overflow-hidden rounded-[8px] border bg-[var(--fill-tsp)] pl-1.5 pr-2.5 text-left';
|
|
14
|
+
|
|
15
|
+
export function AttachmentCardBody({ icon, name, detail }: { icon: React.ReactNode; name: string; detail?: string | null }) {
|
|
16
|
+
return (
|
|
17
|
+
<>
|
|
18
|
+
<span className="flex h-7 w-7 shrink-0 items-center justify-center rounded-[6px] bg-[var(--bg-active)] text-[var(--text-muted)]">{icon}</span>
|
|
19
|
+
<span className="flex min-w-0 flex-col">
|
|
20
|
+
<span className="truncate text-[11.5px] leading-tight text-[var(--text)]">{name}</span>
|
|
21
|
+
{detail ? <span className="truncate text-[10.5px] leading-tight text-[var(--text-muted)]">{detail}</span> : null}
|
|
22
|
+
</span>
|
|
23
|
+
</>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Over a video's frame: it is not a picture. */
|
|
28
|
+
export function PlayMark() {
|
|
29
|
+
return (
|
|
30
|
+
<span aria-hidden className="pointer-events-none absolute inset-0 m-auto flex h-4 w-4 items-center justify-center rounded-full bg-black/55">
|
|
31
|
+
<Play size={8} className="translate-x-[0.5px] fill-white text-white" />
|
|
32
|
+
</span>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Opens an attachment to look at it, for both the composer's pending attachments and
|
|
5
|
+
* those in sent messages. A tile only shows that something is there; this shows which one.
|
|
6
|
+
*
|
|
7
|
+
* Uses the shared PreviewFrame shell. Unknown types say they cannot be previewed rather
|
|
8
|
+
* than show a broken preview.
|
|
9
|
+
*/
|
|
10
|
+
import React from 'react';
|
|
11
|
+
import { Download } from 'lucide-react';
|
|
12
|
+
import { PREVIEW_BTN, PreviewFrame, previewMediaFit } from './PreviewFrame';
|
|
13
|
+
import { Tooltip } from './Tooltip';
|
|
14
|
+
import { attachmentIcon, attachmentKind } from '@/lib/project-resources';
|
|
15
|
+
import { useT } from '@/i18n';
|
|
16
|
+
import { prettyJsonSource } from '@/lib/pretty-json';
|
|
17
|
+
|
|
18
|
+
export interface AttachmentPreviewItem {
|
|
19
|
+
name: string;
|
|
20
|
+
/**
|
|
21
|
+
* How it is sent to the model, not what it is; that comes from the name (see attachmentKind).
|
|
22
|
+
*
|
|
23
|
+
* Images go into the message, everything else only as a path. The preview does not
|
|
24
|
+
* use this to choose a player: an mp4 is a document here.
|
|
25
|
+
*/
|
|
26
|
+
kind: 'image' | 'document';
|
|
27
|
+
/** A data URL, or any address the browser can open. */
|
|
28
|
+
url: string;
|
|
29
|
+
mediaType?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Only a thumbnail, not the original.
|
|
32
|
+
*
|
|
33
|
+
* The case for sent messages: the original went to the agent's workspace, and only a
|
|
34
|
+
* copy at most 320px square is kept. It is shown at its own size with a note, not
|
|
35
|
+
* stretched, so it is not mistaken for the original's quality.
|
|
36
|
+
*/
|
|
37
|
+
thumbOnly?: boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* An attachment's type icon, the same in the composer, in sent messages and in the
|
|
42
|
+
* assets list (see attachmentIcon in project-resources).
|
|
43
|
+
*/
|
|
44
|
+
export function AttachmentTypeIcon({
|
|
45
|
+
file,
|
|
46
|
+
size,
|
|
47
|
+
className,
|
|
48
|
+
}: {
|
|
49
|
+
file: { name: string; mediaType?: string };
|
|
50
|
+
size: number;
|
|
51
|
+
className?: string;
|
|
52
|
+
}) {
|
|
53
|
+
const Icon = attachmentIcon(file);
|
|
54
|
+
return <Icon size={size} className={className} />;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Extensions shown as plain text. */
|
|
58
|
+
const TEXT_EXTENSIONS = new Set([
|
|
59
|
+
'txt', 'md', 'markdown', 'json', 'csv', 'tsv', 'srt', 'vtt', 'log',
|
|
60
|
+
'xml', 'yml', 'yaml', 'js', 'ts', 'tsx', 'jsx', 'css', 'html',
|
|
61
|
+
]);
|
|
62
|
+
|
|
63
|
+
function extensionOf(name: string): string {
|
|
64
|
+
const dot = name.lastIndexOf('.');
|
|
65
|
+
return dot > 0 ? name.slice(dot + 1).toLowerCase() : '';
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
type Body = 'image' | 'video' | 'audio' | 'pdf' | 'text' | 'none';
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Which player opens the attachment.
|
|
72
|
+
*
|
|
73
|
+
* The kind comes from the name (as in the assets list), then the extension for pdf and
|
|
74
|
+
* plain text. A thumbnail is always an image: the kept copy is a webp even when the
|
|
75
|
+
* original is an `.mp4`, and a `<video>` playing an image shows black.
|
|
76
|
+
*/
|
|
77
|
+
function bodyOf(item: AttachmentPreviewItem): Body {
|
|
78
|
+
if (item.thumbOnly) return 'image';
|
|
79
|
+
const kind = attachmentKind(item);
|
|
80
|
+
if (kind === 'image') return 'image';
|
|
81
|
+
if (kind === 'video') return 'video';
|
|
82
|
+
if (kind === 'audio') return 'audio';
|
|
83
|
+
const ext = extensionOf(item.name);
|
|
84
|
+
if (ext === 'pdf') return 'pdf';
|
|
85
|
+
if (TEXT_EXTENSIONS.has(ext)) return 'text';
|
|
86
|
+
return 'none';
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* A PDF needs a blob URL.
|
|
91
|
+
*
|
|
92
|
+
* Chrome does not load data: documents in an iframe (nor in top-level navigation): a
|
|
93
|
+
* data URL in `src` shows blank without an error. The same bytes as a blob: URL work.
|
|
94
|
+
*/
|
|
95
|
+
function useBlobUrl(dataUrl: string, enabled: boolean): string | null {
|
|
96
|
+
const [url, setUrl] = React.useState<string | null>(null);
|
|
97
|
+
React.useEffect(() => {
|
|
98
|
+
if (!enabled || !dataUrl.startsWith('data:')) {
|
|
99
|
+
setUrl(enabled ? dataUrl : null);
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
let objectUrl: string | null = null;
|
|
103
|
+
fetch(dataUrl)
|
|
104
|
+
.then((response) => response.blob())
|
|
105
|
+
.then((blob) => {
|
|
106
|
+
objectUrl = URL.createObjectURL(blob);
|
|
107
|
+
setUrl(objectUrl);
|
|
108
|
+
})
|
|
109
|
+
.catch(() => setUrl(null));
|
|
110
|
+
return () => {
|
|
111
|
+
if (objectUrl) URL.revokeObjectURL(objectUrl);
|
|
112
|
+
};
|
|
113
|
+
}, [dataUrl, enabled]);
|
|
114
|
+
return url;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function AttachmentPreview({
|
|
118
|
+
item,
|
|
119
|
+
onClose,
|
|
120
|
+
}: {
|
|
121
|
+
item: AttachmentPreviewItem;
|
|
122
|
+
onClose: () => void;
|
|
123
|
+
}) {
|
|
124
|
+
const t = useT();
|
|
125
|
+
const body = bodyOf(item);
|
|
126
|
+
if (body === 'image' && !item.thumbOnly) return <OriginalImagePreview key={item.url} item={item} onClose={onClose} />;
|
|
127
|
+
const Icon = attachmentIcon(item);
|
|
128
|
+
/* The two kinds with their own shape. Audio and documents get a fixed reading area. */
|
|
129
|
+
const onStage = body === 'image' || body === 'video';
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<PreviewFrame
|
|
133
|
+
name={item.name}
|
|
134
|
+
onClose={onClose}
|
|
135
|
+
icon={<Icon size={15} className="shrink-0 text-white/45" />}
|
|
136
|
+
/* Images and video fit their own shape, so the black backdrop hugs the picture; a light
|
|
137
|
+
surround makes a frame look darker. Text gets a fixed reading area on the paper
|
|
138
|
+
color, laid out from the top left, not centered. */
|
|
139
|
+
fit={onStage}
|
|
140
|
+
bodyClassName={onStage ? 'bg-black' : 'bg-[var(--surface-2)]'}
|
|
141
|
+
actions={
|
|
142
|
+
/* No download for a thumbnail: a 320px copy under the original's name would be
|
|
143
|
+
mistaken for the original. */
|
|
144
|
+
item.thumbOnly ? null : (
|
|
145
|
+
<Tooltip label={t('assets.download')} side="bottom">
|
|
146
|
+
<a
|
|
147
|
+
href={item.url}
|
|
148
|
+
download={item.name}
|
|
149
|
+
aria-label={t('assets.download')}
|
|
150
|
+
className={`${PREVIEW_BTN} w-8 px-0`}
|
|
151
|
+
>
|
|
152
|
+
<Download size={14} />
|
|
153
|
+
</a>
|
|
154
|
+
</Tooltip>
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
>
|
|
158
|
+
<div
|
|
159
|
+
className={`min-h-0 flex-1 overflow-auto ${
|
|
160
|
+
body === 'text' || body === 'pdf' ? 'block' : 'flex items-center justify-center'
|
|
161
|
+
}`}
|
|
162
|
+
>
|
|
163
|
+
<PreviewBody item={item} body={body} />
|
|
164
|
+
</div>
|
|
165
|
+
{item.thumbOnly && (
|
|
166
|
+
<p className="shrink-0 border-t border-[var(--border)] px-4 py-2 text-[11.5px] text-[var(--text-faint)]">
|
|
167
|
+
{t('composer.thumbOnly')}
|
|
168
|
+
</p>
|
|
169
|
+
)}
|
|
170
|
+
</PreviewFrame>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Uses the original file URL in both modes; 1:1 never stretches a thumbnail. */
|
|
175
|
+
function OriginalImagePreview({ item, onClose }: { item: AttachmentPreviewItem; onClose: () => void }) {
|
|
176
|
+
const t = useT();
|
|
177
|
+
const [actualSize, setActualSize] = React.useState(false);
|
|
178
|
+
const [size, setSize] = React.useState<{ w: number; h: number } | null>(null);
|
|
179
|
+
return (
|
|
180
|
+
<PreviewFrame name={item.name} onClose={onClose} bodyClassName="bg-black"
|
|
181
|
+
actions={<>
|
|
182
|
+
{size ? <span className="mr-2 hidden text-[11px] tabular-nums text-white/45 sm:block">{size.w} × {size.h}</span> : null}
|
|
183
|
+
<div className="flex rounded-lg bg-white/5 p-0.5">
|
|
184
|
+
<button type="button" aria-pressed={!actualSize} onClick={() => setActualSize(false)}
|
|
185
|
+
className={`${PREVIEW_BTN} ${!actualSize ? 'bg-white/10 text-white' : ''}`}>{t('assets.imageFit')}</button>
|
|
186
|
+
<button type="button" aria-label={t('assets.imageActualSize')} aria-pressed={actualSize} onClick={() => setActualSize(true)}
|
|
187
|
+
className={`${PREVIEW_BTN} ${actualSize ? 'bg-white/10 text-white' : ''}`}>100%</button>
|
|
188
|
+
</div>
|
|
189
|
+
<Tooltip label={t('assets.download')} side="bottom">
|
|
190
|
+
<a href={item.url} download={item.name} aria-label={t('assets.download')} className={`${PREVIEW_BTN} w-8 px-0`}><Download size={14} /></a>
|
|
191
|
+
</Tooltip>
|
|
192
|
+
</>}>
|
|
193
|
+
<div className="flex h-full min-h-0 w-full overflow-auto overscroll-contain">
|
|
194
|
+
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
195
|
+
<img src={item.url} alt={item.name} className="m-auto block shrink-0 object-contain"
|
|
196
|
+
onLoad={event => setSize({ w: event.currentTarget.naturalWidth, h: event.currentTarget.naturalHeight })}
|
|
197
|
+
style={actualSize && size
|
|
198
|
+
? { width: size.w, height: size.h, maxWidth: 'none', maxHeight: 'none' }
|
|
199
|
+
: { maxWidth: '100%', maxHeight: '100%', width: 'auto', height: 'auto' }} />
|
|
200
|
+
</div>
|
|
201
|
+
</PreviewFrame>
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function PreviewBody({ item, body }: { item: AttachmentPreviewItem; body: Body }) {
|
|
206
|
+
const t = useT();
|
|
207
|
+
const pdfUrl = useBlobUrl(item.url, body === 'pdf');
|
|
208
|
+
|
|
209
|
+
if (body === 'image') {
|
|
210
|
+
return (
|
|
211
|
+
// eslint-disable-next-line @next/next/no-img-element
|
|
212
|
+
<img
|
|
213
|
+
src={item.url}
|
|
214
|
+
alt={item.name}
|
|
215
|
+
/* Only maximums, no size: the box is the picture at its own ratio, and a thumbnail
|
|
216
|
+
is never scaled up into a blur. */
|
|
217
|
+
style={previewMediaFit()}
|
|
218
|
+
className={item.thumbOnly ? 'p-6' : undefined}
|
|
219
|
+
/>
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
if (body === 'video') return <VideoPreview item={item} />;
|
|
223
|
+
if (body === 'audio') return <AudioPreview item={item} />;
|
|
224
|
+
if (body === 'pdf') {
|
|
225
|
+
if (!pdfUrl) return <div className="h-full" />;
|
|
226
|
+
return <iframe src={pdfUrl} title={item.name} className="h-full w-full" />;
|
|
227
|
+
}
|
|
228
|
+
if (body === 'text') return <TextPreview dataUrl={item.url} name={item.name} />;
|
|
229
|
+
|
|
230
|
+
/* No preview, but still the type's icon, so a .zip and an .xlsx look different. */
|
|
231
|
+
return (
|
|
232
|
+
<div className="flex flex-col items-center gap-3 p-10 text-center">
|
|
233
|
+
<div className="flex h-16 w-16 items-center justify-center rounded-2xl bg-[var(--surface)]">
|
|
234
|
+
<AttachmentTypeIcon file={item} size={30} className="text-[var(--text-faint)]" />
|
|
235
|
+
</div>
|
|
236
|
+
<p className="text-[12.5px] text-[var(--text-muted)]">{t('assets.noPreview')}</p>
|
|
237
|
+
</div>
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* A video.
|
|
243
|
+
*
|
|
244
|
+
* The size is measured, not passed in: an attachment is only a URL, so its orientation
|
|
245
|
+
* is known once the metadata arrives.
|
|
246
|
+
*
|
|
247
|
+
* Until then it reserves 16:9. Before metadata a `<video>` reports 300×150, and the box
|
|
248
|
+
* fits it, so it would flash small and then jump. Most videos are 16:9; a vertical one
|
|
249
|
+
* reflows once, while still black.
|
|
250
|
+
*/
|
|
251
|
+
function VideoPreview({ item }: { item: AttachmentPreviewItem }) {
|
|
252
|
+
const t = useT();
|
|
253
|
+
const [size, setSize] = React.useState<{ w: number; h: number } | null>(null);
|
|
254
|
+
const [failed, setFailed] = React.useState(false);
|
|
255
|
+
|
|
256
|
+
if (failed) {
|
|
257
|
+
return <p className="p-10 text-[12.5px] text-white/60">{t('assets.previewFailed')}</p>;
|
|
258
|
+
}
|
|
259
|
+
return (
|
|
260
|
+
<video
|
|
261
|
+
src={item.url}
|
|
262
|
+
controls
|
|
263
|
+
playsInline
|
|
264
|
+
preload="metadata"
|
|
265
|
+
style={previewMediaFit(size?.w ?? 16, size?.h ?? 9)}
|
|
266
|
+
onLoadedMetadata={(event) => {
|
|
267
|
+
const el = event.currentTarget;
|
|
268
|
+
if (el.videoWidth > 0 && el.videoHeight > 0) {
|
|
269
|
+
setSize({ w: el.videoWidth, h: el.videoHeight });
|
|
270
|
+
}
|
|
271
|
+
}}
|
|
272
|
+
onError={() => setFailed(true)}
|
|
273
|
+
/>
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Audio: no picture, so an icon and a player on the paper color.
|
|
279
|
+
*/
|
|
280
|
+
function AudioPreview({ item }: { item: AttachmentPreviewItem }) {
|
|
281
|
+
const t = useT();
|
|
282
|
+
const Icon = attachmentIcon(item);
|
|
283
|
+
const [failed, setFailed] = React.useState(false);
|
|
284
|
+
|
|
285
|
+
return (
|
|
286
|
+
<div className="flex w-full flex-col items-center gap-5 p-10">
|
|
287
|
+
<div className="flex h-16 w-16 items-center justify-center rounded-2xl bg-[var(--surface)]">
|
|
288
|
+
<Icon size={30} className="text-[var(--text-faint)]" />
|
|
289
|
+
</div>
|
|
290
|
+
{failed ? (
|
|
291
|
+
<p className="text-[12.5px] text-[var(--text-muted)]">{t('assets.previewFailed')}</p>
|
|
292
|
+
) : (
|
|
293
|
+
<audio src={item.url} controls preload="metadata" className="w-full max-w-[480px]" onError={() => setFailed(true)} />
|
|
294
|
+
)}
|
|
295
|
+
</div>
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function TextPreview({ dataUrl, name }: { dataUrl: string; name: string }) {
|
|
300
|
+
const t = useT();
|
|
301
|
+
const [text, setText] = React.useState<string | null>(null);
|
|
302
|
+
const [failed, setFailed] = React.useState(false);
|
|
303
|
+
|
|
304
|
+
React.useEffect(() => {
|
|
305
|
+
let alive = true;
|
|
306
|
+
setText(null);
|
|
307
|
+
setFailed(false);
|
|
308
|
+
// fetch decodes data URLs too: base64 and UTF-8 handled by the browser; atob would break non-ASCII text.
|
|
309
|
+
fetch(dataUrl)
|
|
310
|
+
.then((response) => response.text())
|
|
311
|
+
.then((body) => {
|
|
312
|
+
if (alive) setText(prettyJsonSource(name, body));
|
|
313
|
+
})
|
|
314
|
+
.catch(() => {
|
|
315
|
+
if (alive) setFailed(true);
|
|
316
|
+
});
|
|
317
|
+
return () => {
|
|
318
|
+
alive = false;
|
|
319
|
+
};
|
|
320
|
+
}, [dataUrl, name]);
|
|
321
|
+
|
|
322
|
+
if (failed) {
|
|
323
|
+
return <p className="p-10 text-[12.5px] text-[var(--text-muted)]">{t('assets.previewFailed')}</p>;
|
|
324
|
+
}
|
|
325
|
+
if (text === null) return <div className="h-[200px]" />;
|
|
326
|
+
return (
|
|
327
|
+
<pre className="w-full whitespace-pre-wrap break-words p-5 font-mono text-[12px] leading-relaxed text-[var(--text)]">
|
|
328
|
+
{text}
|
|
329
|
+
</pre>
|
|
330
|
+
);
|
|
331
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A turn the app's own agent could not finish because the service its model runs on has no balance left (lib/balance):
|
|
3
|
+
* the same words for every service, and "Manage", its own page to top it up, when the app knows it.
|
|
4
|
+
*/
|
|
5
|
+
import { useT } from '@/i18n';
|
|
6
|
+
import type { Balance } from '@/lib/balance';
|
|
7
|
+
|
|
8
|
+
export function BalanceNotice({ balance }: { balance: Balance }) {
|
|
9
|
+
const t = useT();
|
|
10
|
+
return (
|
|
11
|
+
<p role="status" className="text-xs text-[var(--warn)]">
|
|
12
|
+
<b className="font-medium">{t('balance.title').replaceAll('{provider}', balance.provider)}</b>{' '}
|
|
13
|
+
{t('balance.body').replaceAll('{provider}', balance.provider)}
|
|
14
|
+
{balance.url ? (
|
|
15
|
+
<>
|
|
16
|
+
{' '}
|
|
17
|
+
<a href={balance.url} target="_blank" rel="noreferrer" className="underline underline-offset-2 hover:text-[var(--text)]">{t('balance.manage')}</a>
|
|
18
|
+
</>
|
|
19
|
+
) : null}
|
|
20
|
+
</p>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
/*
|
|
6
|
+
* The mark: a playhead over two clips, together an F, in the surrounding text color (currentColor).
|
|
7
|
+
* The clips are cut away around the playhead (a real gap, showing what is behind), so its shape holds in one color.
|
|
8
|
+
*/
|
|
9
|
+
const VIEWBOX = '8 6 84 92';
|
|
10
|
+
const PLAYHEAD = 'M17 12H37Q40 12 40 15V27Q40 29 38.5 30.5L31 37V88Q31 92 27 92Q23 92 23 88V37L15.5 30.5Q14 29 14 27V15Q14 12 17 12Z';
|
|
11
|
+
|
|
12
|
+
export function BrandLogo({ size = 18, className }: { size?: number; className?: string }) {
|
|
13
|
+
const gap = `openfilm-gap-${React.useId().replace(/:/g, '')}`;
|
|
14
|
+
return (
|
|
15
|
+
<svg
|
|
16
|
+
width={size}
|
|
17
|
+
height={size}
|
|
18
|
+
viewBox={VIEWBOX}
|
|
19
|
+
fill="currentColor"
|
|
20
|
+
className={`block shrink-0 ${className ?? ''}`.trim()}
|
|
21
|
+
role="img"
|
|
22
|
+
aria-label="OpenFilm"
|
|
23
|
+
>
|
|
24
|
+
<mask id={gap} maskUnits="userSpaceOnUse" x="0" y="0" width="100" height="100">
|
|
25
|
+
<rect width="100" height="100" fill="#fff" />
|
|
26
|
+
<path d={PLAYHEAD} stroke="#000" strokeWidth="7" strokeLinejoin="round" />
|
|
27
|
+
</mask>
|
|
28
|
+
<g mask={`url(#${gap})`}>
|
|
29
|
+
<rect x="22" y="12" width="64" height="20" rx="5" />
|
|
30
|
+
<rect x="25" y="44" width="47" height="19" rx="5" />
|
|
31
|
+
</g>
|
|
32
|
+
<path d={PLAYHEAD} />
|
|
33
|
+
</svg>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The cards above the composer and in the conversation that ask the person to decide: one shell, one set of
|
|
5
|
+
* buttons.
|
|
6
|
+
*
|
|
7
|
+
* Background and border follow the composer (they sit together), radius 12, the same shadow as the model menu.
|
|
8
|
+
* Buttons have one height (28) and three weights: primary (filled), secondary (outlined), quiet (text only).
|
|
9
|
+
* Choice rows are shared by question and permission cards: one choice per row, a number key cap on the left,
|
|
10
|
+
* pressing the number picks it, as in Claude Code's menus.
|
|
11
|
+
*/
|
|
12
|
+
import React from 'react';
|
|
13
|
+
import { ChevronDown, X } from 'lucide-react';
|
|
14
|
+
import { useT } from '@/i18n';
|
|
15
|
+
import { inChat } from '@/lib/chat-layer';
|
|
16
|
+
|
|
17
|
+
/** The shell of floating layers (menus, dropdowns): the cards' shadow, on the surface color. */
|
|
18
|
+
export const POPOVER_CHROME: React.CSSProperties = {
|
|
19
|
+
background: 'var(--bg-surface)',
|
|
20
|
+
border: '1px solid var(--border-strong)',
|
|
21
|
+
borderRadius: 12,
|
|
22
|
+
boxShadow: '0 16px 40px -8px rgba(0,0,0,0.4), 0 4px 12px rgba(0,0,0,0.18)',
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export function ComposerCard({
|
|
26
|
+
icon,
|
|
27
|
+
title,
|
|
28
|
+
body,
|
|
29
|
+
onClose,
|
|
30
|
+
collapse,
|
|
31
|
+
children,
|
|
32
|
+
role,
|
|
33
|
+
className = '',
|
|
34
|
+
}: {
|
|
35
|
+
icon?: React.ReactNode;
|
|
36
|
+
title: React.ReactNode;
|
|
37
|
+
body?: React.ReactNode;
|
|
38
|
+
onClose?: () => void;
|
|
39
|
+
/**
|
|
40
|
+
* Collapsible: a collapse button left of the close button. Collapsed, only the title row remains (the matter still
|
|
41
|
+
* waits, just out of the way); the title or the button expands it. `label` is the button's current screen-reader text.
|
|
42
|
+
*/
|
|
43
|
+
collapse?: { collapsed: boolean; onToggle: () => void; label: string };
|
|
44
|
+
children?: React.ReactNode;
|
|
45
|
+
role?: React.AriaRole;
|
|
46
|
+
className?: string;
|
|
47
|
+
}) {
|
|
48
|
+
const t = useT();
|
|
49
|
+
const collapsed = collapse?.collapsed ?? false;
|
|
50
|
+
const buttons = (onClose ? 1 : 0) + (collapse ? 1 : 0);
|
|
51
|
+
return (
|
|
52
|
+
<div
|
|
53
|
+
{...(role ? { role } : {})}
|
|
54
|
+
className={`relative rounded-[12px] border border-[var(--composer-border)] bg-[var(--composer-bg)] px-3.5 shadow-[0_8px_24px_-12px_rgba(0,0,0,0.35)] ${collapsed ? 'py-2' : 'pb-3 pt-3'} ${className}`}
|
|
55
|
+
>
|
|
56
|
+
<div className={`absolute right-2 flex items-center gap-0.5 ${collapsed ? 'top-1.5' : 'top-2'}`}>
|
|
57
|
+
{collapse ? (
|
|
58
|
+
<button
|
|
59
|
+
type="button"
|
|
60
|
+
onClick={collapse.onToggle}
|
|
61
|
+
aria-label={collapse.label}
|
|
62
|
+
aria-expanded={!collapsed}
|
|
63
|
+
className="flex h-6 w-6 items-center justify-center rounded-md text-[var(--text-faint)] transition hover:bg-[var(--bg-hover)] hover:text-[var(--text)]"
|
|
64
|
+
>
|
|
65
|
+
<ChevronDown size={14} strokeWidth={1.75} className={`transition-transform duration-150 ${collapsed ? 'rotate-180' : ''}`} />
|
|
66
|
+
</button>
|
|
67
|
+
) : null}
|
|
68
|
+
{onClose ? (
|
|
69
|
+
<button
|
|
70
|
+
type="button"
|
|
71
|
+
onClick={onClose}
|
|
72
|
+
aria-label={t('project.close')}
|
|
73
|
+
className="flex h-6 w-6 items-center justify-center rounded-md text-[var(--text-faint)] transition hover:bg-[var(--bg-hover)] hover:text-[var(--text)]"
|
|
74
|
+
>
|
|
75
|
+
<X size={14} strokeWidth={1.75} />
|
|
76
|
+
</button>
|
|
77
|
+
) : null}
|
|
78
|
+
</div>
|
|
79
|
+
<div className={`flex items-start gap-2 ${buttons === 2 ? 'pr-14' : buttons === 1 ? 'pr-7' : ''}`}>
|
|
80
|
+
{icon ? <span className="mt-[2px] shrink-0 text-[var(--text-muted)]">{icon}</span> : null}
|
|
81
|
+
<div className="min-w-0 flex-1">
|
|
82
|
+
{collapse && collapsed ? (
|
|
83
|
+
<button type="button" onClick={collapse.onToggle} className="block w-full min-w-0 truncate text-left text-[13px] font-medium leading-snug text-[var(--text)]">
|
|
84
|
+
{title}
|
|
85
|
+
</button>
|
|
86
|
+
) : (
|
|
87
|
+
<h3 className="text-[13px] font-medium leading-snug text-[var(--text)]">{title}</h3>
|
|
88
|
+
)}
|
|
89
|
+
{body && !collapsed ? <div className="mt-1 text-[12.5px] leading-relaxed text-[var(--text-muted)]">{body}</div> : null}
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
{collapsed ? null : children}
|
|
93
|
+
</div>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function CardActions({ children, className = '' }: { children: React.ReactNode; className?: string }) {
|
|
98
|
+
return <div className={`mt-3 flex items-center justify-end gap-2 ${className}`}>{children}</div>;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
type Weight = 'primary' | 'secondary' | 'quiet' | 'danger';
|
|
102
|
+
|
|
103
|
+
const WEIGHT: Record<Weight, string> = {
|
|
104
|
+
primary: 'bg-[var(--text)] text-[var(--panel)] hover:opacity-90',
|
|
105
|
+
secondary: 'text-[var(--text)] ring-1 ring-inset ring-[var(--border-strong)] hover:bg-[var(--bg-hover)]',
|
|
106
|
+
quiet: 'text-[var(--text-muted)] hover:text-[var(--text)]',
|
|
107
|
+
danger: 'bg-[var(--err)] text-white hover:brightness-110',
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
export const CardButton = React.forwardRef<
|
|
111
|
+
HTMLButtonElement,
|
|
112
|
+
React.ButtonHTMLAttributes<HTMLButtonElement> & { weight?: Weight }
|
|
113
|
+
>(function CardButton({ weight = 'secondary', className = '', type = 'button', ...props }, ref) {
|
|
114
|
+
return (
|
|
115
|
+
<button
|
|
116
|
+
{...props}
|
|
117
|
+
ref={ref}
|
|
118
|
+
type={type}
|
|
119
|
+
className={`inline-flex h-7 shrink-0 items-center justify-center gap-1.5 rounded-lg px-3 text-[12px] font-medium outline-none transition focus-visible:ring-2 focus-visible:ring-[var(--text)]/30 disabled:pointer-events-none disabled:opacity-50 ${WEIGHT[weight]} ${className}`}
|
|
120
|
+
/>
|
|
121
|
+
);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* One choice per row: a key cap (1, 2, 3…), the name, a line of description below; a tick on the selected row.
|
|
126
|
+
* Without `onPick` the row can't be clicked (an answered question stays visible but can't be changed).
|
|
127
|
+
*/
|
|
128
|
+
export function ChoiceRow({
|
|
129
|
+
index,
|
|
130
|
+
label,
|
|
131
|
+
description,
|
|
132
|
+
selected = false,
|
|
133
|
+
onPick,
|
|
134
|
+
}: {
|
|
135
|
+
index?: number;
|
|
136
|
+
label: React.ReactNode;
|
|
137
|
+
description?: React.ReactNode;
|
|
138
|
+
selected?: boolean;
|
|
139
|
+
onPick?: () => void;
|
|
140
|
+
}) {
|
|
141
|
+
const body = (
|
|
142
|
+
<>
|
|
143
|
+
{index != null ? (
|
|
144
|
+
<span className="mt-[1px] flex h-[18px] min-w-[18px] shrink-0 items-center justify-center rounded-[5px] border border-[var(--border)] px-1 text-[10.5px] tabular-nums text-[var(--text-faint)]">
|
|
145
|
+
{index}
|
|
146
|
+
</span>
|
|
147
|
+
) : null}
|
|
148
|
+
<span className="flex min-w-0 flex-1 flex-col">
|
|
149
|
+
<span className="text-[13px] leading-snug text-[var(--text)]">{label}</span>
|
|
150
|
+
{description ? <span className="mt-0.5 text-[11.5px] leading-snug text-[var(--text-faint)]">{description}</span> : null}
|
|
151
|
+
</span>
|
|
152
|
+
{selected ? <span aria-hidden className="mt-[1px] shrink-0 text-[12px] text-[var(--text)]">✓</span> : null}
|
|
153
|
+
</>
|
|
154
|
+
);
|
|
155
|
+
const shell = 'flex w-full items-start gap-2.5 rounded-lg px-2 py-1.5 text-left';
|
|
156
|
+
if (!onPick) return <div className={`${shell} ${selected ? 'bg-[var(--bg-hover)]' : 'opacity-70'}`}>{body}</div>;
|
|
157
|
+
return (
|
|
158
|
+
<button type="button" onClick={onPick} className={`${shell} outline-none transition hover:bg-[var(--bg-hover)] focus-visible:bg-[var(--bg-hover)]`}>
|
|
159
|
+
{body}
|
|
160
|
+
</button>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** While a card is open and focus is not in a text field, 1–9 picks that choice. */
|
|
165
|
+
export function useNumberKeys(count: number, onPick: ((index: number) => void) | null): void {
|
|
166
|
+
React.useEffect(() => {
|
|
167
|
+
if (!onPick || count <= 0) return undefined;
|
|
168
|
+
const onKey = (event: KeyboardEvent) => {
|
|
169
|
+
if (event.metaKey || event.ctrlKey || event.altKey) return;
|
|
170
|
+
const target = event.target as HTMLElement | null;
|
|
171
|
+
/* a number typed in Studio (a field there, a shortcut) is not an answer to the agent's question */
|
|
172
|
+
if (!inChat(target) && target !== document.body) return;
|
|
173
|
+
if (target?.closest('input, textarea, [contenteditable="true"]')) return;
|
|
174
|
+
const n = Number(event.key);
|
|
175
|
+
if (!Number.isInteger(n) || n < 1 || n > count) return;
|
|
176
|
+
event.preventDefault();
|
|
177
|
+
onPick(n - 1);
|
|
178
|
+
};
|
|
179
|
+
window.addEventListener('keydown', onKey);
|
|
180
|
+
return () => window.removeEventListener('keydown', onKey);
|
|
181
|
+
}, [count, onPick]);
|
|
182
|
+
}
|