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.
Files changed (362) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +29 -2
  3. package/bin/install.mjs +66 -0
  4. package/package.json +29 -4
  5. package/skill/SKILL.md +64 -0
  6. package/skill/agents/openai.yaml +4 -0
  7. package/skill/assets/examples/ApprovalCard.tsx +8 -0
  8. package/skill/assets/examples/BasicApp.tsx +38 -0
  9. package/skill/assets/examples/BriefingCard.tsx +8 -0
  10. package/skill/assets/examples/ChatControls.tsx +49 -0
  11. package/skill/assets/examples/ChatPanel.tsx +73 -0
  12. package/skill/assets/examples/Checkbox.tsx +13 -0
  13. package/skill/assets/examples/Combobox.tsx +14 -0
  14. package/skill/assets/examples/Drawer.tsx +10 -0
  15. package/skill/assets/examples/MemoryCard.tsx +9 -0
  16. package/skill/assets/examples/MessageList.tsx +8 -0
  17. package/skill/assets/examples/Theme.tsx +14 -0
  18. package/skill/assets/examples/ToolCall.tsx +8 -0
  19. package/skill/assets/examples/Tree.tsx +15 -0
  20. package/skill/assets/examples/examples.css +11 -0
  21. package/skill/assets/library/auricui-0.1.0-preview.1.tgz +0 -0
  22. package/skill/assets/library/auricui-0.1.0-preview.3.tgz +0 -0
  23. package/skill/assets/library/auricui-0.1.0-preview.4.tgz +0 -0
  24. package/skill/assets/upstream/LICENSE +21 -0
  25. package/skill/assets/upstream/apps/desktop/chat/src/App.tsx +1099 -0
  26. package/skill/assets/upstream/apps/desktop/chat/src/app-bridge.ts +154 -0
  27. package/skill/assets/upstream/apps/desktop/chat/src/chat.css +1812 -0
  28. package/skill/assets/upstream/apps/desktop/chat/src/components/AddSkill.tsx +223 -0
  29. package/skill/assets/upstream/apps/desktop/chat/src/components/AgentActivityRow.tsx +716 -0
  30. package/skill/assets/upstream/apps/desktop/chat/src/components/AgentIcons.tsx +46 -0
  31. package/skill/assets/upstream/apps/desktop/chat/src/components/AttachmentCard.tsx +34 -0
  32. package/skill/assets/upstream/apps/desktop/chat/src/components/AttachmentPreview.tsx +331 -0
  33. package/skill/assets/upstream/apps/desktop/chat/src/components/BalanceNotice.tsx +22 -0
  34. package/skill/assets/upstream/apps/desktop/chat/src/components/BrandLogo.tsx +35 -0
  35. package/skill/assets/upstream/apps/desktop/chat/src/components/ComposerCard.tsx +182 -0
  36. package/skill/assets/upstream/apps/desktop/chat/src/components/ConversationSessionBar.tsx +292 -0
  37. package/skill/assets/upstream/apps/desktop/chat/src/components/CopyDiagnostics.tsx +24 -0
  38. package/skill/assets/upstream/apps/desktop/chat/src/components/Divider.tsx +47 -0
  39. package/skill/assets/upstream/apps/desktop/chat/src/components/FileChangesList.tsx +119 -0
  40. package/skill/assets/upstream/apps/desktop/chat/src/components/Markdown.tsx +198 -0
  41. package/skill/assets/upstream/apps/desktop/chat/src/components/ModelPopover.tsx +280 -0
  42. package/skill/assets/upstream/apps/desktop/chat/src/components/NoticeCard.tsx +87 -0
  43. package/skill/assets/upstream/apps/desktop/chat/src/components/Popover.tsx +195 -0
  44. package/skill/assets/upstream/apps/desktop/chat/src/components/PreviewFrame.tsx +129 -0
  45. package/skill/assets/upstream/apps/desktop/chat/src/components/ProjectConversation.tsx +852 -0
  46. package/skill/assets/upstream/apps/desktop/chat/src/components/ProjectStarters.tsx +118 -0
  47. package/skill/assets/upstream/apps/desktop/chat/src/components/Tooltip.tsx +191 -0
  48. package/skill/assets/upstream/apps/desktop/chat/src/components/TurnLog.tsx +583 -0
  49. package/skill/assets/upstream/apps/desktop/chat/src/components/TurnQuestionCard.tsx +133 -0
  50. package/skill/assets/upstream/apps/desktop/chat/src/components/dock-pane-bar.ts +14 -0
  51. package/skill/assets/upstream/apps/desktop/chat/src/components/project-version.ts +37 -0
  52. package/skill/assets/upstream/apps/desktop/chat/src/components/prompt-editor/MentionMenuPlugin.tsx +372 -0
  53. package/skill/assets/upstream/apps/desktop/chat/src/components/prompt-editor/PromptEditor.tsx +476 -0
  54. package/skill/assets/upstream/apps/desktop/chat/src/components/prompt-editor/PromptPill.tsx +399 -0
  55. package/skill/assets/upstream/apps/desktop/chat/src/components/prompt-editor/PromptReferenceNode.tsx +164 -0
  56. package/skill/assets/upstream/apps/desktop/chat/src/components/prompt-editor/index.ts +31 -0
  57. package/skill/assets/upstream/apps/desktop/chat/src/components/prompt-editor/mention-menu.ts +206 -0
  58. package/skill/assets/upstream/apps/desktop/chat/src/components/prompt-editor/prompt-text.ts +171 -0
  59. package/skill/assets/upstream/apps/desktop/chat/src/components/useStickToBottom.ts +320 -0
  60. package/skill/assets/upstream/apps/desktop/chat/src/components/useTicker.ts +55 -0
  61. package/skill/assets/upstream/apps/desktop/chat/src/i18n/index.ts +42 -0
  62. package/skill/assets/upstream/apps/desktop/chat/src/i18n/locales/en-US.ts +408 -0
  63. package/skill/assets/upstream/apps/desktop/chat/src/i18n/locales/es.ts +407 -0
  64. package/skill/assets/upstream/apps/desktop/chat/src/i18n/locales/ja.ts +407 -0
  65. package/skill/assets/upstream/apps/desktop/chat/src/i18n/locales/ko.ts +403 -0
  66. package/skill/assets/upstream/apps/desktop/chat/src/i18n/locales/words.ts +6 -0
  67. package/skill/assets/upstream/apps/desktop/chat/src/i18n/locales/zh-CN.ts +407 -0
  68. package/skill/assets/upstream/apps/desktop/chat/src/i18n/lookup.ts +12 -0
  69. package/skill/assets/upstream/apps/desktop/chat/src/lib/agent-activity-runs.ts +154 -0
  70. package/skill/assets/upstream/apps/desktop/chat/src/lib/agent-menu-rows.ts +41 -0
  71. package/skill/assets/upstream/apps/desktop/chat/src/lib/agent-refs.ts +105 -0
  72. package/skill/assets/upstream/apps/desktop/chat/src/lib/agent-transcript.ts +440 -0
  73. package/skill/assets/upstream/apps/desktop/chat/src/lib/asset-lists.ts +75 -0
  74. package/skill/assets/upstream/apps/desktop/chat/src/lib/attachment-place.ts +17 -0
  75. package/skill/assets/upstream/apps/desktop/chat/src/lib/balance.ts +16 -0
  76. package/skill/assets/upstream/apps/desktop/chat/src/lib/chat-layer.ts +10 -0
  77. package/skill/assets/upstream/apps/desktop/chat/src/lib/chat-menu.ts +18 -0
  78. package/skill/assets/upstream/apps/desktop/chat/src/lib/chat-store.ts +101 -0
  79. package/skill/assets/upstream/apps/desktop/chat/src/lib/composer-attachments.ts +189 -0
  80. package/skill/assets/upstream/apps/desktop/chat/src/lib/desktop-attachments.ts +178 -0
  81. package/skill/assets/upstream/apps/desktop/chat/src/lib/desktop-bridge.ts +291 -0
  82. package/skill/assets/upstream/apps/desktop/chat/src/lib/developer.ts +39 -0
  83. package/skill/assets/upstream/apps/desktop/chat/src/lib/esc-stop.ts +23 -0
  84. package/skill/assets/upstream/apps/desktop/chat/src/lib/file-changes.ts +32 -0
  85. package/skill/assets/upstream/apps/desktop/chat/src/lib/live-activity.ts +20 -0
  86. package/skill/assets/upstream/apps/desktop/chat/src/lib/local-agent-run.ts +1174 -0
  87. package/skill/assets/upstream/apps/desktop/chat/src/lib/local-sessions.ts +25 -0
  88. package/skill/assets/upstream/apps/desktop/chat/src/lib/model-calls.ts +87 -0
  89. package/skill/assets/upstream/apps/desktop/chat/src/lib/pretty-json.ts +12 -0
  90. package/skill/assets/upstream/apps/desktop/chat/src/lib/preview-top.ts +15 -0
  91. package/skill/assets/upstream/apps/desktop/chat/src/lib/project-resources.ts +66 -0
  92. package/skill/assets/upstream/apps/desktop/chat/src/lib/project-sessions.ts +66 -0
  93. package/skill/assets/upstream/apps/desktop/chat/src/lib/project-versions.ts +116 -0
  94. package/skill/assets/upstream/apps/desktop/chat/src/lib/ref-pictures.ts +119 -0
  95. package/skill/assets/upstream/apps/desktop/chat/src/lib/relative-time.ts +46 -0
  96. package/skill/assets/upstream/apps/desktop/chat/src/lib/skill-pages.ts +29 -0
  97. package/skill/assets/upstream/apps/desktop/chat/src/lib/step-file.ts +23 -0
  98. package/skill/assets/upstream/apps/desktop/chat/src/lib/structural-share.ts +52 -0
  99. package/skill/assets/upstream/apps/desktop/chat/src/lib/studio-film.ts +44 -0
  100. package/skill/assets/upstream/apps/desktop/chat/src/lib/studio-transfer.ts +40 -0
  101. package/skill/assets/upstream/apps/desktop/chat/src/lib/unprompted.ts +27 -0
  102. package/skill/assets/upstream/apps/desktop/chat/src/lib/upload-limits.ts +53 -0
  103. package/skill/assets/upstream/apps/desktop/chat/src/mount.tsx +19 -0
  104. package/skill/assets/upstream/apps/desktop/chat/src/state/local-agent-store.ts +296 -0
  105. package/skill/assets/upstream/apps/desktop/chat/src/studio-refs.ts +307 -0
  106. package/skill/assets/upstream/apps/desktop/package.json +51 -0
  107. package/skill/assets/upstream/apps/desktop/shell/bridge.ts +415 -0
  108. package/skill/assets/upstream/apps/desktop/shell/index.html +27 -0
  109. package/skill/assets/upstream/apps/desktop/shell/main.tsx +17 -0
  110. package/skill/assets/upstream/apps/desktop/shell/shell.css +17 -0
  111. package/skill/assets/upstream/apps/desktop/shell/vite.config.ts +65 -0
  112. package/skill/assets/upstream/apps/desktop/src/agent-definitions.mjs +31 -0
  113. package/skill/assets/upstream/packages/openfilm/LICENSE +21 -0
  114. package/skill/assets/upstream/packages/openfilm/package.json +88 -0
  115. package/skill/assets/upstream/packages/openfilm/src/film-doc.d.mts +125 -0
  116. package/skill/assets/upstream/packages/openfilm/src/film-doc.mjs +986 -0
  117. package/skill/assets/upstream/packages/openfilm/src/overrides.mjs +73 -0
  118. package/skill/assets/upstream/packages/openfilm/src/timeline.mjs +1280 -0
  119. package/skill/assets/upstream/packages/openfilm/studio/server/bridge.js +209 -0
  120. package/skill/assets/upstream/packages/openfilm/studio/server/film-subtitle.mjs +785 -0
  121. package/skill/assets/upstream/packages/openfilm/studio/server/ops.mjs +403 -0
  122. package/skill/assets/upstream/packages/openfilm/studio/server/stage.js +1649 -0
  123. package/skill/assets/upstream/packages/openfilm/studio/server/track-layout.mjs +43 -0
  124. package/skill/assets/upstream/packages/openfilm/studio/ui/src/App.tsx +156 -0
  125. package/skill/assets/upstream/packages/openfilm/studio/ui/src/api.ts +328 -0
  126. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/AudioMeters.tsx +188 -0
  127. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/BlockThumbs.tsx +84 -0
  128. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/BlockWaveform.tsx +201 -0
  129. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/BrandLoadingScreen.tsx +56 -0
  130. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/BrandLogo.tsx +25 -0
  131. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/Card.tsx +89 -0
  132. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ColorPicker.tsx +204 -0
  133. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ConfirmDialog.tsx +96 -0
  134. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ContextMenu.tsx +422 -0
  135. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/DesktopDialog.tsx +271 -0
  136. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ExamplesGallery.tsx +372 -0
  137. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/FilmFullscreenBar.tsx +147 -0
  138. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/FilmInspector.tsx +2310 -0
  139. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/FilmStageSelect.tsx +3296 -0
  140. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/FocusNav.tsx +28 -0
  141. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/FontFamilyPicker.tsx +293 -0
  142. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/FramePicker.tsx +69 -0
  143. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/InspectorPanel.tsx +25 -0
  144. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/Launcher.tsx +38 -0
  145. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/LayersPanel.tsx +277 -0
  146. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/LiveTime.tsx +101 -0
  147. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/MediaPool.tsx +1413 -0
  148. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/MediaPreview.tsx +188 -0
  149. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/MenuSelect.tsx +161 -0
  150. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/MgOutline.tsx +24 -0
  151. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/OperationHistory.tsx +184 -0
  152. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/PaneDivider.tsx +292 -0
  153. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/PasteAttrsDialog.tsx +69 -0
  154. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/PlaybackMenu.tsx +110 -0
  155. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/Popover.tsx +159 -0
  156. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ProjectCover.tsx +60 -0
  157. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ProjectHistoryControls.tsx +748 -0
  158. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ProjectLayoutMenu.tsx +82 -0
  159. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ProjectMenu.tsx +111 -0
  160. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ProjectSources.tsx +587 -0
  161. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ProjectView.tsx +3222 -0
  162. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ProjectsLibrary.tsx +567 -0
  163. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ProjectsView.tsx +1593 -0
  164. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/PropertiesSection.tsx +418 -0
  165. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ResourceInspector.tsx +100 -0
  166. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/SelectionToolbar.tsx +157 -0
  167. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/SkillsLibrary.tsx +504 -0
  168. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/SourcePreview.tsx +464 -0
  169. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/SpendAsks.tsx +88 -0
  170. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/StageMaskOverlay.tsx +299 -0
  171. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/StageTransformFrame.tsx +246 -0
  172. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/SubtitleInspector.module.css +46 -0
  173. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/SubtitleInspector.tsx +884 -0
  174. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/SubtitleOverlay.tsx +148 -0
  175. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/SubtitleRow.tsx +419 -0
  176. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/TabStrip.tsx +188 -0
  177. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/Timeline.tsx +4911 -0
  178. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/TimelineMarkers.tsx +329 -0
  179. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/Toast.tsx +55 -0
  180. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/Tooltip.tsx +193 -0
  181. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/UpdateButton.tsx +104 -0
  182. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/ViewerBar.tsx +98 -0
  183. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/WhatsNew.tsx +147 -0
  184. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/dock-pane-bar.ts +16 -0
  185. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/export/ExportCenter.tsx +1502 -0
  186. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/export/ExportTray.tsx +284 -0
  187. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/film-stage-hit.ts +18 -0
  188. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/inspector-fields.tsx +863 -0
  189. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/inspector-look.tsx +1357 -0
  190. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/player-controls/controls-bar.tsx +397 -0
  191. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/player-controls/transport.tsx +294 -0
  192. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/replace-drop.ts +20 -0
  193. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/AgentsSection.tsx +613 -0
  194. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/CustomServices.tsx +104 -0
  195. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/DiagnosticsGroup.tsx +202 -0
  196. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/ModelsSection.tsx +179 -0
  197. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/ProviderMark.tsx +24 -0
  198. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/ProvidersSection.tsx +177 -0
  199. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/SettingsModal.tsx +511 -0
  200. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/SettingsSelect.tsx +84 -0
  201. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/ShortcutsSection.tsx +291 -0
  202. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/StorageGroup.tsx +119 -0
  203. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/theme.ts +47 -0
  204. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/ui.tsx +139 -0
  205. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/settings/use-settings.ts +10 -0
  206. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/stage-menu.tsx +283 -0
  207. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/timeline-head-extras.tsx +91 -0
  208. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/typing-target.ts +45 -0
  209. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/use-editor-tools.tsx +408 -0
  210. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/use-page-changes.ts +48 -0
  211. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/use-project-history.ts +113 -0
  212. package/skill/assets/upstream/packages/openfilm/studio/ui/src/components/useBlockDrag.ts +639 -0
  213. package/skill/assets/upstream/packages/openfilm/studio/ui/src/editor/Preview.tsx +426 -0
  214. package/skill/assets/upstream/packages/openfilm/studio/ui/src/editor/player.ts +558 -0
  215. package/skill/assets/upstream/packages/openfilm/studio/ui/src/editor/preview-frames.ts +36 -0
  216. package/skill/assets/upstream/packages/openfilm/studio/ui/src/editor/steps.ts +36 -0
  217. package/skill/assets/upstream/packages/openfilm/studio/ui/src/editor/undo.ts +156 -0
  218. package/skill/assets/upstream/packages/openfilm/studio/ui/src/editor/use-film.ts +212 -0
  219. package/skill/assets/upstream/packages/openfilm/studio/ui/src/editor/use-preview-renders.ts +89 -0
  220. package/skill/assets/upstream/packages/openfilm/studio/ui/src/globals.css +559 -0
  221. package/skill/assets/upstream/packages/openfilm/studio/ui/src/i18n/en.ts +1901 -0
  222. package/skill/assets/upstream/packages/openfilm/studio/ui/src/i18n/es.ts +1900 -0
  223. package/skill/assets/upstream/packages/openfilm/studio/ui/src/i18n/index.ts +130 -0
  224. package/skill/assets/upstream/packages/openfilm/studio/ui/src/i18n/ja.ts +1900 -0
  225. package/skill/assets/upstream/packages/openfilm/studio/ui/src/i18n/ko.ts +1896 -0
  226. package/skill/assets/upstream/packages/openfilm/studio/ui/src/i18n/words.ts +6 -0
  227. package/skill/assets/upstream/packages/openfilm/studio/ui/src/i18n/zh-CN.ts +1901 -0
  228. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/agent-row.ts +21 -0
  229. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/asset-timeline.ts +469 -0
  230. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/audio-levels.ts +60 -0
  231. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/batch-map.ts +28 -0
  232. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/browser.ts +10 -0
  233. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/canvas-fit.ts +116 -0
  234. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/chat-marks.ts +114 -0
  235. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/clip-attrs.ts +102 -0
  236. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/clip-fade.ts +70 -0
  237. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/clip-look.ts +520 -0
  238. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/clip-mask.ts +536 -0
  239. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/clip-replace.ts +60 -0
  240. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/component-props.ts +128 -0
  241. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/context-length.ts +12 -0
  242. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/desktop-build.ts +44 -0
  243. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/diagnostics.ts +68 -0
  244. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/double-press.ts +22 -0
  245. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/dropped-overrides.ts +139 -0
  246. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/export-jobs.ts +191 -0
  247. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/export-spec.ts +261 -0
  248. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/field-input.ts +155 -0
  249. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/film-clip-edits.ts +82 -0
  250. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/film-frame.ts +134 -0
  251. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/film-overrides.ts +107 -0
  252. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/film-shape.ts +172 -0
  253. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/film.ts +80 -0
  254. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/font-menu.ts +236 -0
  255. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/font-styles.ts +129 -0
  256. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/freeze-frame.ts +49 -0
  257. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/host.ts +438 -0
  258. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/inspect-scrub.ts +26 -0
  259. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/keymap-store.ts +74 -0
  260. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/keymap.ts +529 -0
  261. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/layers-tree.ts +133 -0
  262. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/look.ts +83 -0
  263. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/loudness.ts +58 -0
  264. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/markers.ts +152 -0
  265. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/media-bar.ts +58 -0
  266. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/media-folders.ts +45 -0
  267. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/media-place.ts +102 -0
  268. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/media-queue.ts +107 -0
  269. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/media-selection.ts +64 -0
  270. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/menu-position.ts +77 -0
  271. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/mg-transform.ts +111 -0
  272. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/mixed.ts +3 -0
  273. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/page-changes.ts +45 -0
  274. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/picture-files.ts +19 -0
  275. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/preview-prefs.ts +46 -0
  276. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/preview-renders.ts +71 -0
  277. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/project-delete.ts +20 -0
  278. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/project-folders.ts +144 -0
  279. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/project-history.ts +188 -0
  280. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/project-sources.ts +283 -0
  281. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/projects-page.ts +40 -0
  282. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/provider-marks.ts +35 -0
  283. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/providers.ts +163 -0
  284. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/resource-drag.ts +131 -0
  285. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/retry-image.ts +17 -0
  286. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/saved-insert.ts +40 -0
  287. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/saved.ts +125 -0
  288. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/selection-toolbar.ts +158 -0
  289. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/shortcut-hint.ts +21 -0
  290. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/similar-layers.ts +46 -0
  291. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/solo.ts +19 -0
  292. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/stage-clip.ts +60 -0
  293. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/stage-crop.ts +232 -0
  294. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/stage-gesture.ts +277 -0
  295. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/stage-layers.ts +71 -0
  296. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/stage-mask.ts +176 -0
  297. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/stage-measure.ts +53 -0
  298. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/stage-types.ts +155 -0
  299. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/studio-refs.ts +248 -0
  300. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/studio-version.ts +41 -0
  301. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/subtitle-cues.ts +238 -0
  302. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/subtitles.ts +263 -0
  303. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/tab-menu.ts +6 -0
  304. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/template-controls.ts +131 -0
  305. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/theme-changes.ts +31 -0
  306. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/thumb-cache.ts +63 -0
  307. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/thumb-cell.ts +8 -0
  308. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/thumb-frame.ts +76 -0
  309. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/thumb-pick.ts +42 -0
  310. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/timecode.ts +161 -0
  311. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/timeline-clipboard.ts +279 -0
  312. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/timeline-drag.ts +589 -0
  313. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/timeline-edit.ts +1138 -0
  314. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/timeline-keys.ts +63 -0
  315. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/timeline-layout.ts +1038 -0
  316. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/timeline-nav.ts +160 -0
  317. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/timeline-prefs.ts +73 -0
  318. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/timeline-split.ts +40 -0
  319. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/timeline-view.ts +105 -0
  320. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/title.ts +39 -0
  321. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/track-heights.ts +55 -0
  322. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/track-lock.ts +27 -0
  323. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/transitions.ts +459 -0
  324. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/type-metrics.ts +83 -0
  325. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/use-film-subtitles.ts +111 -0
  326. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/use-fonts.ts +181 -0
  327. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/use-loaded-thumbs.ts +91 -0
  328. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/use-subtitle-edits.ts +134 -0
  329. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/use-subtitle-font.ts +51 -0
  330. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/use-subtitle-style.ts +68 -0
  331. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/waveform-columns.ts +48 -0
  332. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/web-update.ts +41 -0
  333. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/whats-new.ts +401 -0
  334. package/skill/assets/upstream/packages/openfilm/studio/ui/src/lib/workspace-resources.ts +373 -0
  335. package/skill/assets/upstream/packages/openfilm/studio/ui/src/main.tsx +10 -0
  336. package/skill/assets/upstream/packages/openfilm/studio/ui/vite.config.ts +12 -0
  337. package/skill/assets/upstream/packages/shared/package.json +45 -0
  338. package/skill/assets/upstream/packages/shared/src/agent-activity.ts +263 -0
  339. package/skill/assets/upstream/packages/shared/src/contract.ts +285 -0
  340. package/skill/assets/upstream/packages/shared/src/index.ts +17 -0
  341. package/skill/assets/upstream/packages/shared/src/markdown-blocks.ts +252 -0
  342. package/skill/assets/upstream/packages/shared/src/modality.ts +4 -0
  343. package/skill/assets/upstream/packages/shared/src/prompt-reference.ts +113 -0
  344. package/skill/assets/upstream/packages/shared/src/title.ts +76 -0
  345. package/skill/assets/upstream/packages/shared/src/turn.ts +68 -0
  346. package/skill/assets/upstream/packages/shared/src/video.ts +26 -0
  347. package/skill/references/agent-components.md +33 -0
  348. package/skill/references/api-index.json +2693 -0
  349. package/skill/references/chat-components.md +65 -0
  350. package/skill/references/components.md +23 -0
  351. package/skill/references/core-components.md +44 -0
  352. package/skill/references/dependencies.md +22 -0
  353. package/skill/references/esm-package.md +48 -0
  354. package/skill/references/integration.md +43 -0
  355. package/skill/references/library-manifest.json +12 -0
  356. package/skill/references/source-manifest.json +325 -0
  357. package/skill/references/studio-components.md +24 -0
  358. package/skill/references/theme-motion.md +49 -0
  359. package/skill/references/troubleshooting.md +27 -0
  360. package/skill/references/verification.md +13 -0
  361. package/skill/scripts/check_dependencies.py +109 -0
  362. package/skill/scripts/inspect_api.py +60 -0
@@ -0,0 +1,399 @@
1
+ 'use client';
2
+
3
+ /**
4
+ * How a pill looks; drawing only, not where it comes from.
5
+ *
6
+ * Shared by the pill in the editor (a Lexical decorator node, clickable and removable)
7
+ * and the pill in a sent message (read-only), so the sentence looks the same after send.
8
+ *
9
+ * It must not touch Lexical: `useLexicalComposerContext` throws outside a composer, so
10
+ * the caller passes things like the remove button through `trailing`.
11
+ */
12
+
13
+ import React from 'react';
14
+ import {
15
+ Blocks, Brackets, Captions, Clapperboard, Clock3, Crop, Film, Mic, MousePointer2, Music, Paperclip,
16
+ Quote, Rows3, Shapes, SquareDashed, Video, Waves,
17
+ } from 'lucide-react';
18
+ import {
19
+ splitPromptReferenceText,
20
+ type PromptDisplay,
21
+ type PromptReference as StoredPromptReference,
22
+ } from '@openfilm/shared';
23
+ import { Tooltip } from '@/components/Tooltip';
24
+ import type { PromptReferenceKind } from './prompt-text';
25
+
26
+ /* The `@` menu uses this table too, so a menu row and the pill it becomes share an icon. */
27
+ export const PILL_ICON: Record<PromptReferenceKind, React.ComponentType<{ size?: number; className?: string }>> = {
28
+ element: MousePointer2,
29
+ region: Crop,
30
+ time: Clock3,
31
+ /* A range: the in and out brackets, as marked on the timeline ruler. */
32
+ range: Brackets,
33
+ /* A whole track: rows, matching the timeline. */
34
+ track: Rows3,
35
+ /* A subtitle line: quotes, since the label is the spoken words themselves. */
36
+ subtitle: Quote,
37
+ showcase: Film,
38
+ /* Files get one icon regardless of video, image or audio: the file name says which,
39
+ and a paperclip reads more clearly than three similar file icons. */
40
+ file: Paperclip,
41
+ /* A canvas card: an empty frame. Text and image cards share it; the name says which. */
42
+ card: SquareDashed,
43
+ /* A skill: blocks, a piece of craft inserted into the sentence. Other pills point at
44
+ things in the film; this one points at a way of working. */
45
+ skill: Blocks,
46
+ /* An example film (another film, not this one): a clapperboard. */
47
+ example: Clapperboard,
48
+ /* Timeline clips: the icon follows the clip's kind on the timeline, so the pill
49
+ matches the clip the user just picked. */
50
+ clipMg: Shapes,
51
+ clipVideo: Video,
52
+ clipVoice: Mic,
53
+ clipSfx: Waves,
54
+ clipMusic: Music,
55
+ clipCaption: Captions,
56
+ };
57
+
58
+ /**
59
+ * Unknown kinds fall back to a paperclip.
60
+ *
61
+ * A stored `kind` is a string, not this table's enum (see `promptReferenceSchema` in
62
+ * @openfilm/shared): kinds come and go, but old messages keep theirs. A missing icon is
63
+ * better than a message that fails to render.
64
+ */
65
+ function iconFor(kind: string): React.ComponentType<{ size?: number; className?: string }> {
66
+ return PILL_ICON[kind as PromptReferenceKind] ?? Paperclip;
67
+ }
68
+
69
+ /**
70
+ * Each kind's color, drawn on the icon's small square.
71
+ *
72
+ * Clips use the timeline's colors (`--tl-*`), so a pill matches its clip. Things in the
73
+ * picture (an element, a region) use the selection blue they light up in. Times use
74
+ * amber, apart from the playhead's colors. Things outside the film (files, canvas cards,
75
+ * skills) have no color.
76
+ */
77
+ const PILL_TONE: Partial<Record<PromptReferenceKind, string>> = {
78
+ element: '#0d99ff',
79
+ region: '#0d99ff',
80
+ time: '#d48a1f',
81
+ range: '#d48a1f',
82
+ subtitle: 'var(--tl-caption)',
83
+ clipMg: 'var(--tl-scene)',
84
+ clipVideo: 'var(--tl-video)',
85
+ clipVoice: 'var(--tl-voice)',
86
+ clipSfx: 'var(--tl-sfx)',
87
+ clipMusic: 'var(--tl-music)',
88
+ clipCaption: 'var(--tl-caption)',
89
+ };
90
+
91
+ /**
92
+ * Kinds that lead somewhere in the film when clicked (seek there, point it out in the
93
+ * picture). Files and showcases point outside the film; the canvas moves to its own cards.
94
+ */
95
+ const REVEALABLE_PILL_KINDS = new Set<string>([
96
+ 'element', 'region', 'time', 'range', 'track', 'subtitle', 'card',
97
+ 'clipMg', 'clipVideo', 'clipVoice', 'clipSfx', 'clipMusic', 'clipCaption',
98
+ ]);
99
+
100
+ /**
101
+ * Whether clicking leads somewhere: the kind points into the film, or the host recorded
102
+ * what it points at (`target`), such as a file dragged in from Studio's assets.
103
+ */
104
+ export function canRevealPill(reference: StoredPromptReference): boolean {
105
+ /* a skill opens on its page in the Community */
106
+ return Boolean(reference.target) || REVEALABLE_PILL_KINDS.has(reference.kind) || reference.kind === 'skill';
107
+ }
108
+
109
+ /** A pill's hover card: what it is, and label/value rows (already translated by the host). */
110
+ export interface PromptPillCard {
111
+ title: string;
112
+ rows: Array<[string, string]>;
113
+ /** paragraphs under the title: what a skill or an example is, as its page says */
114
+ text?: string[];
115
+ }
116
+
117
+ type PillImage = NonNullable<StoredPromptReference['image']>;
118
+
119
+ /* Each picture is loaded once, since many pills can show the same frame. */
120
+ const pictureState = new Map<string, 'ok' | 'failed' | Promise<void>>();
121
+
122
+ /** Whether the picture loads. If not (the film changed, the project closed), the pill shows its icon instead. */
123
+ function usePictureLoads(src: string | undefined): boolean {
124
+ const [, bump] = React.useReducer((n: number) => n + 1, 0);
125
+ const state = src ? pictureState.get(src) : undefined;
126
+ React.useEffect(() => {
127
+ if (!src) return;
128
+ let current = pictureState.get(src);
129
+ if (!current) {
130
+ current = new Promise<void>((resolve) => {
131
+ const img = new Image();
132
+ img.onload = () => { pictureState.set(src, 'ok'); resolve(); };
133
+ img.onerror = () => { pictureState.set(src, 'failed'); resolve(); };
134
+ img.src = src;
135
+ });
136
+ pictureState.set(src, current);
137
+ }
138
+ if (current instanceof Promise) {
139
+ let live = true;
140
+ void current.then(() => { if (live) bump(); });
141
+ return () => { live = false; };
142
+ }
143
+ return undefined;
144
+ }, [src]);
145
+ return Boolean(src) && state !== 'failed';
146
+ }
147
+
148
+ /** The thumbnail's aspect ratio: that of the crop (or the whole frame), clamped so the pill keeps its shape. */
149
+ function pictureAspect(image: PillImage): number {
150
+ const shape = image.crop ?? image.stage;
151
+ const aspect = shape && shape.h > 0 ? shape.w / shape.h : 16 / 9;
152
+ return Math.min(Math.max(aspect, 1), 16 / 9);
153
+ }
154
+
155
+ /**
156
+ * A background showing only the `crop`: grown to the thumbnail's shape (no stretching),
157
+ * then turned into background size and position. Percentages are relative to the
158
+ * thumbnail, so they hold at any font size.
159
+ */
160
+ function pictureStyle(image: PillImage, aspect: number): React.CSSProperties {
161
+ const backgroundImage = `url(${JSON.stringify(image.src)})`;
162
+ const { crop, stage } = image;
163
+ if (!crop || !stage || crop.w <= 0 || crop.h <= 0) return { backgroundImage, backgroundSize: 'cover', backgroundPosition: 'center' };
164
+ let { x, y, w, h } = crop;
165
+ if (w / h < aspect) { const grown = h * aspect; x -= (grown - w) / 2; w = grown; } else { const grown = w / aspect; y -= (grown - h) / 2; h = grown; }
166
+ w = Math.min(w, stage.w);
167
+ h = Math.min(h, stage.h);
168
+ x = Math.min(Math.max(x, 0), stage.w - w);
169
+ y = Math.min(Math.max(y, 0), stage.h - h);
170
+ return {
171
+ backgroundImage,
172
+ backgroundSize: `${(stage.w / w) * 100}% ${(stage.h / h) * 100}%`,
173
+ backgroundPosition: `${stage.w > w ? (x / (stage.w - w)) * 100 : 0}% ${stage.h > h ? (y / (stage.h - h)) * 100 : 0}%`,
174
+ };
175
+ }
176
+
177
+ /** The card's picture: the whole frame, with the crop outlined in blue and the rest dimmed. */
178
+ function PillCardPicture({ image }: { image: PillImage }) {
179
+ const { crop, stage } = image;
180
+ const box = crop && stage && stage.w > 0 && stage.h > 0 ? {
181
+ left: `${(crop.x / stage.w) * 100}%`,
182
+ top: `${(crop.y / stage.h) * 100}%`,
183
+ width: `${(crop.w / stage.w) * 100}%`,
184
+ height: `${(crop.h / stage.h) * 100}%`,
185
+ } : null;
186
+ return (
187
+ <div className="relative overflow-hidden rounded-[5px] bg-black/40">
188
+ <img src={image.src} alt="" className="block h-auto w-full" draggable={false} />
189
+ {box ? (
190
+ <div
191
+ aria-hidden
192
+ className="absolute rounded-[2px] border-[1.5px] border-[#0d99ff] shadow-[0_0_0_9999px_rgba(0,0,0,0.35)]"
193
+ style={box}
194
+ />
195
+ ) : null}
196
+ </div>
197
+ );
198
+ }
199
+
200
+ function PillCardBody({ card, image, hint }: { card?: PromptPillCard | null; image?: PillImage | null; hint?: string }) {
201
+ return (
202
+ <div className={`flex flex-col gap-1.5 whitespace-normal py-0.5 text-left ${card?.text?.length ? 'w-[300px]' : 'w-[240px]'}`}>
203
+ {image ? <PillCardPicture image={image} /> : null}
204
+ {card ? (
205
+ <>
206
+ <div className="text-[11.5px] font-semibold">{card.title}</div>
207
+ {card.text?.map((line, index) => <p key={index} className="text-[11.5px] font-normal leading-[17px] opacity-80">{line}</p>)}
208
+ {card.rows.length ? (
209
+ <dl className="grid grid-cols-[auto_minmax(0,1fr)] gap-x-2 gap-y-0.5 text-[11px] font-normal leading-snug">
210
+ {card.rows.map(([label, value], index) => (
211
+ <React.Fragment key={index}>
212
+ <dt className="opacity-60">{label}</dt>
213
+ <dd className="break-words font-mono tabular-nums">{value}</dd>
214
+ </React.Fragment>
215
+ ))}
216
+ </dl>
217
+ ) : null}
218
+ </>
219
+ ) : null}
220
+ {hint ? <div className="text-[10.5px] font-normal opacity-60">{hint}</div> : null}
221
+ </div>
222
+ );
223
+ }
224
+
225
+ /**
226
+ * Links a pill and what it points at, both ways: hovering a pill lights the thing up
227
+ * elsewhere (`hover`, null on leave); pointing at a thing elsewhere lights its pills
228
+ * (`lit`, with `subscribe` notifying changes). A context, because pills in the editor,
229
+ * sent messages, agent replies and the changes list are all PromptPill.
230
+ */
231
+ export interface PromptPillHover {
232
+ hover: (reference: StoredPromptReference | null) => void;
233
+ lit: (reference: StoredPromptReference) => boolean;
234
+ subscribe: (listener: () => void) => () => void;
235
+ }
236
+ export const PromptPillHoverContext = React.createContext<PromptPillHover | null>(null);
237
+ const noSubscribe = () => () => {};
238
+
239
+ export function PromptPill({
240
+ reference,
241
+ onClick,
242
+ onMouseDown,
243
+ title,
244
+ trailing,
245
+ card,
246
+ hint,
247
+ }: {
248
+ reference: StoredPromptReference;
249
+ /** Only when clicking leads somewhere; without it the pill is read-only. */
250
+ onClick?: (event: React.MouseEvent) => void;
251
+ /** A press on it: in the editor, where the caret goes. */
252
+ onMouseDown?: (event: React.MouseEvent) => void;
253
+ title?: string;
254
+ /** The trailing slot: the remove button in the editor, nothing in history. */
255
+ trailing?: React.ReactNode;
256
+ /** The hover card's facts; with neither these nor a picture there is no card, only the native title. */
257
+ card?: PromptPillCard | null;
258
+ /** The small line under the card (what clicking does), since the card replaces the native title. */
259
+ hint?: string;
260
+ }) {
261
+ const Icon = iconFor(reference.kind);
262
+ const tone = PILL_TONE[reference.kind as PromptReferenceKind];
263
+ const image = reference.image;
264
+ const pictured = usePictureLoads(image?.src) && image ? image : null;
265
+ const aspect = pictured ? pictureAspect(pictured) : 1;
266
+ const hoverCard = pictured || card;
267
+ const hoverCtx = React.useContext(PromptPillHoverContext);
268
+ const lit = React.useSyncExternalStore(hoverCtx?.subscribe ?? noSubscribe, () => hoverCtx?.lit(reference) ?? false);
269
+ /* If the pill goes away while hovered (removed, sent), turn off what it lit elsewhere */
270
+ const hovering = React.useRef(false);
271
+ React.useEffect(() => () => { if (hovering.current) hoverCtx?.hover(null); }, [hoverCtx]);
272
+
273
+ const pill = (
274
+ <span
275
+ contentEditable={false}
276
+ onClick={onClick}
277
+ onMouseDown={onMouseDown}
278
+ onMouseEnter={hoverCtx ? () => { hovering.current = true; hoverCtx.hover(reference); } : undefined}
279
+ onMouseLeave={hoverCtx ? () => { hovering.current = false; hoverCtx.hover(null); } : undefined}
280
+ /* No native title with a card: the system one would appear on top of it a second later */
281
+ title={hoverCard ? undefined : title ?? reference.label}
282
+ /* A fixed height below the line height, so a pill does not make the line taller.
283
+ `vertical-align: middle` centers the box on baseline + half the x-height, so the
284
+ part below the baseline must fit in the line box too. 1.45em (the pill's own font
285
+ size) is 18.7px at 14px/22px, with room on both sides. */
286
+ className={`mx-[1px] inline-flex h-[1.45em] max-w-[240px] select-none items-center gap-[5px] rounded-[6px] pl-[3px] align-middle text-[0.9em] font-medium leading-none text-[var(--text)] ring-1 ring-inset transition-[background-color,box-shadow] ${
287
+ trailing ? 'pr-[3px]' : 'pr-1.5'
288
+ } ${onClick ? 'cursor-pointer' : ''}`}
289
+ style={{
290
+ background: tone
291
+ ? `color-mix(in srgb, ${tone} ${onClick ? 11 : 9}%, var(--surface))`
292
+ : 'var(--surface-2)',
293
+ ['--tw-ring-color' as string]: tone ? `color-mix(in srgb, ${tone} 26%, transparent)` : 'var(--border)',
294
+ /* Lit from elsewhere: a solid border (over the faint ring) and a deeper fill */
295
+ ...(lit ? {
296
+ background: tone ? `color-mix(in srgb, ${tone} 24%, var(--surface))` : 'var(--bg-hover)',
297
+ boxShadow: `inset 0 0 0 1.5px ${tone ?? 'var(--text-muted)'}`,
298
+ } : {}),
299
+ }}
300
+ data-pill-kind={reference.kind}
301
+ data-pill-lit={lit ? '' : undefined}
302
+ >
303
+ {pictured ? (
304
+ /* A picture replaces the icon: it shows what part of the frame is meant */
305
+ <span
306
+ aria-hidden
307
+ className="h-[1.05em] shrink-0 rounded-[3px] bg-no-repeat ring-1 ring-inset ring-black/10"
308
+ style={{ width: `${(1.05 * aspect).toFixed(3)}em`, ...pictureStyle(pictured, aspect) }}
309
+ />
310
+ ) : (
311
+ <span
312
+ className="flex h-[1.05em] w-[1.05em] shrink-0 items-center justify-center rounded-[4px]"
313
+ style={tone
314
+ ? { background: tone, color: '#fff' }
315
+ : { background: 'var(--fill-tsp)', color: 'var(--text-muted)' }}
316
+ >
317
+ <Icon size={10} className="shrink-0" />
318
+ </span>
319
+ )}
320
+ <span className="truncate">{reference.label}</span>
321
+ {reference.detail ? (
322
+ <span className="shrink-0 font-normal tabular-nums text-[var(--text-faint)]">{reference.detail}</span>
323
+ ) : null}
324
+ {trailing}
325
+ </span>
326
+ );
327
+ if (!hoverCard) return pill;
328
+ return (
329
+ <Tooltip label={reference.label} content={<PillCardBody card={card} image={pictured} {...(onClick && hint ? { hint } : {})} />}>
330
+ {pill}
331
+ </Tooltip>
332
+ );
333
+ }
334
+
335
+ /**
336
+ * A sent message: text as text, references as pills.
337
+ *
338
+ * Unknown markers are dropped, not shown raw: raw, a marker reads like
339
+ * `file:assets/upload/x.mp4` in the middle of the sentence. Same as
340
+ * `collectPromptReferences` treats unknown references.
341
+ */
342
+ /**
343
+ * Where sent pills lead when clicked. A context rather than props: the conversation is a
344
+ * memoized list (see ProjectConversation), not worth rebuilding every turn for a callback.
345
+ */
346
+ export const PromptPillRevealContext = React.createContext<{
347
+ onReveal: (reference: StoredPromptReference) => void;
348
+ revealLabel?: string;
349
+ /** What the hover card says (the host knows what the pill points at; this layer does not). */
350
+ describe?: (reference: StoredPromptReference) => PromptPillCard | null;
351
+ } | null>(null);
352
+
353
+ export function PromptWithPills({
354
+ display,
355
+ onReveal,
356
+ revealLabel,
357
+ }: {
358
+ display: PromptDisplay;
359
+ /** Clicking a pill in history: seek to its moment and point it out in the picture, as in the editor. */
360
+ onReveal?: (reference: StoredPromptReference) => void;
361
+ revealLabel?: string;
362
+ }) {
363
+ const byId = React.useMemo(
364
+ () => new Map(display.references.map((item) => [item.id, item])),
365
+ [display.references],
366
+ );
367
+ const ctx = React.useContext(PromptPillRevealContext);
368
+ const onRevealRef = onReveal ?? ctx?.onReveal;
369
+ const label = revealLabel ?? ctx?.revealLabel;
370
+
371
+ return (
372
+ <>
373
+ {splitPromptReferenceText(display.text).map((segment, index) => {
374
+ if (segment.kind === 'text') {
375
+ return <React.Fragment key={index}>{segment.value}</React.Fragment>;
376
+ }
377
+ const reference = byId.get(segment.id);
378
+ if (!reference) return null;
379
+ const reveal = onRevealRef && canRevealPill(reference) ? onRevealRef : undefined;
380
+ return (
381
+ <PromptPill
382
+ key={index}
383
+ reference={reference}
384
+ card={ctx?.describe?.(reference) ?? null}
385
+ {...(reveal && label ? { hint: label } : {})}
386
+ {...(reveal ? {
387
+ onClick: (event: React.MouseEvent) => {
388
+ event.preventDefault();
389
+ event.stopPropagation();
390
+ reveal(reference);
391
+ },
392
+ } : {})}
393
+ {...(reveal && label ? { title: `${reference.label} · ${label}` } : {})}
394
+ />
395
+ );
396
+ })}
397
+ </>
398
+ );
399
+ }
@@ -0,0 +1,164 @@
1
+ 'use client';
2
+
3
+ import React from 'react';
4
+ import { X } from 'lucide-react';
5
+ import {
6
+ $getNodeByKey,
7
+ DecoratorNode,
8
+ type LexicalNode,
9
+ type NodeKey,
10
+ type SerializedLexicalNode,
11
+ type Spread,
12
+ } from 'lexical';
13
+ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
14
+ import { canRevealPill, PromptPill, type PromptPillCard } from './PromptPill';
15
+ import { promptReferenceToken, type PromptReference } from './prompt-text';
16
+
17
+ type SerializedPromptReferenceNode = Spread<
18
+ { reference: PromptReference },
19
+ SerializedLexicalNode
20
+ >;
21
+
22
+ /**
23
+ * A reference node: the caret cannot enter it, an arrow key steps over it, and one
24
+ * Backspace deletes it whole. It is one indivisible thing in the document, not a few
25
+ * characters.
26
+ */
27
+ export class PromptReferenceNode extends DecoratorNode<React.JSX.Element> {
28
+ __reference: PromptReference;
29
+
30
+ static getType(): string {
31
+ return 'prompt-reference';
32
+ }
33
+
34
+ static clone(node: PromptReferenceNode): PromptReferenceNode {
35
+ return new PromptReferenceNode(node.__reference, node.__key);
36
+ }
37
+
38
+ static importJSON(json: SerializedPromptReferenceNode): PromptReferenceNode {
39
+ return $createPromptReferenceNode(json.reference);
40
+ }
41
+
42
+ constructor(reference: PromptReference, key?: NodeKey) {
43
+ super(key);
44
+ this.__reference = reference;
45
+ }
46
+
47
+ exportJSON(): SerializedPromptReferenceNode {
48
+ return { ...super.exportJSON(), reference: this.__reference };
49
+ }
50
+
51
+ createDOM(): HTMLElement {
52
+ const dom = document.createElement('span');
53
+ dom.style.display = 'inline-flex';
54
+ dom.style.verticalAlign = 'middle';
55
+ /* Room on each side, outside this box: a click there is in the text (the caret goes
56
+ beside the pill), where a click on the box itself puts the caret at the start. */
57
+ dom.style.margin = '0 2px';
58
+ return dom;
59
+ }
60
+
61
+ updateDOM(): false {
62
+ return false;
63
+ }
64
+
65
+ isInline(): true {
66
+ return true;
67
+ }
68
+
69
+ /* Not selectable by the arrow keys: selected, a pill shows nothing and swallows what is
70
+ typed next. The caret goes past it instead, to the text on its other side. */
71
+ isKeyboardSelectable(): false {
72
+ return false;
73
+ }
74
+
75
+ /* As plain text it is a marker, so the document's getTextContent() is the string the
76
+ host stores and restores from, with no separate text-and-positions bookkeeping. */
77
+ getTextContent(): string {
78
+ return promptReferenceToken(this.__reference.id);
79
+ }
80
+
81
+ getReference(): PromptReference {
82
+ return this.__reference;
83
+ }
84
+
85
+ decorate(): React.JSX.Element {
86
+ return <PromptReferencePill nodeKey={this.getKey()} reference={this.__reference} />;
87
+ }
88
+ }
89
+
90
+ export function $createPromptReferenceNode(reference: PromptReference): PromptReferenceNode {
91
+ return new PromptReferenceNode(reference);
92
+ }
93
+
94
+ export function $isPromptReferenceNode(
95
+ node: LexicalNode | null | undefined,
96
+ ): node is PromptReferenceNode {
97
+ return node instanceof PromptReferenceNode;
98
+ }
99
+
100
+ interface PromptReferencePillHandlers {
101
+ /** Clicking the reference: for example, seek to its moment and light up the marked area. */
102
+ onReveal?: (reference: PromptReference) => void;
103
+ revealLabel?: string;
104
+ removeLabel: string;
105
+ /** What the hover card says. */
106
+ describe?: (reference: PromptReference) => PromptPillCard | null;
107
+ }
108
+
109
+ /* Pills render into the contentEditable through a portal, and context crosses portals,
110
+ so callbacks come through context rather than node data (which must serialize). */
111
+ export const PromptReferenceContext =
112
+ React.createContext<PromptReferencePillHandlers | null>(null);
113
+
114
+ function PromptReferencePill({
115
+ nodeKey,
116
+ reference,
117
+ }: {
118
+ nodeKey: NodeKey;
119
+ reference: PromptReference;
120
+ }) {
121
+ const [editor] = useLexicalComposerContext();
122
+ const handlers = React.useContext(PromptReferenceContext);
123
+ /* Not every reference leads somewhere in the film: a file is on disk, with no moment or
124
+ picture. Such pills drop the pointer cursor and hint, so they do not look clickable. */
125
+ const reveal = canRevealPill(reference) ? handlers?.onReveal : undefined;
126
+
127
+ return (
128
+ <PromptPill
129
+ reference={reference}
130
+ card={handlers?.describe?.(reference) ?? null}
131
+ /* A click on the pill goes where it points; the caret stays where it was. Left to the
132
+ browser, a press on something not editable puts the caret at the start of the text. */
133
+ onMouseDown={(event: React.MouseEvent) => {
134
+ if (event.button === 0) event.preventDefault();
135
+ }}
136
+ {...(reveal && handlers?.revealLabel ? { hint: handlers.revealLabel } : {})}
137
+ {...(reveal ? {
138
+ onClick: (event: React.MouseEvent) => {
139
+ event.preventDefault();
140
+ reveal(reference);
141
+ },
142
+ } : {})}
143
+ {...(reveal && handlers?.revealLabel ? { title: `${reference.label} · ${handlers.revealLabel}` } : {})}
144
+ trailing={(
145
+ <button
146
+ type="button"
147
+ aria-label={handlers?.removeLabel}
148
+ /* Keep focus in the editor on mouse down, so typing continues after removing. */
149
+ onMouseDown={(event) => event.preventDefault()}
150
+ onClick={(event) => {
151
+ event.preventDefault();
152
+ event.stopPropagation();
153
+ editor.update(() => {
154
+ $getNodeByKey(nodeKey)?.remove();
155
+ });
156
+ }}
157
+ className="flex h-[1.05em] w-[1.05em] shrink-0 items-center justify-center rounded-[4px] text-[var(--text-faint)] transition hover:bg-[var(--bg-hover)] hover:text-[var(--text)]"
158
+ >
159
+ <X size={10} />
160
+ </button>
161
+ )}
162
+ />
163
+ );
164
+ }
@@ -0,0 +1,31 @@
1
+ export {
2
+ PromptEditor,
3
+ type PromptEditorHandle,
4
+ type PromptEditorProps,
5
+ type PromptEditorState,
6
+ } from './PromptEditor';
7
+ export { PILL_ICON, PromptPill, PromptPillHoverContext, PromptPillRevealContext, PromptWithPills, type PromptPillCard, type PromptPillHover } from './PromptPill';
8
+ export { type MentionMenuConfig } from './MentionMenuPlugin';
9
+ export {
10
+ buildMentionMenu,
11
+ matchMentionTrigger,
12
+ MENTION_MENU_LIMIT,
13
+ type MentionEntry,
14
+ type MentionItem,
15
+ type MentionProvider,
16
+ } from './mention-menu';
17
+ export {
18
+ activatedSkillIds,
19
+ collectPromptReferences,
20
+ fileReferenceId,
21
+ fileReferencePath,
22
+ promptReferenceToken,
23
+ resolvePromptReferences,
24
+ skillReferenceId,
25
+ skillReferencePackage,
26
+ splitPromptReferenceText,
27
+ stripPromptReferenceTokens,
28
+ type PromptReference,
29
+ type PromptReferenceKind,
30
+ type PromptTextSegment,
31
+ } from './prompt-text';