@agent-native/creative-context 0.1.0

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 (618) hide show
  1. package/README.md +108 -0
  2. package/agent-native.package.json +104 -0
  3. package/dist/actions/confirm-canonical-logo.d.ts +6 -0
  4. package/dist/actions/confirm-canonical-logo.d.ts.map +1 -0
  5. package/dist/actions/confirm-canonical-logo.js +19 -0
  6. package/dist/actions/confirm-canonical-logo.js.map +1 -0
  7. package/dist/actions/continue-context-import.d.ts +7 -0
  8. package/dist/actions/continue-context-import.d.ts.map +1 -0
  9. package/dist/actions/continue-context-import.js +10 -0
  10. package/dist/actions/continue-context-import.js.map +1 -0
  11. package/dist/actions/creative-context-a2a.d.ts +10 -0
  12. package/dist/actions/creative-context-a2a.d.ts.map +1 -0
  13. package/dist/actions/creative-context-a2a.js +66 -0
  14. package/dist/actions/creative-context-a2a.js.map +1 -0
  15. package/dist/actions/get-brand-profile.d.ts +33 -0
  16. package/dist/actions/get-brand-profile.d.ts.map +1 -0
  17. package/dist/actions/get-brand-profile.js +13 -0
  18. package/dist/actions/get-brand-profile.js.map +1 -0
  19. package/dist/actions/get-context-import-status.d.ts +22 -0
  20. package/dist/actions/get-context-import-status.d.ts.map +1 -0
  21. package/dist/actions/get-context-import-status.js +12 -0
  22. package/dist/actions/get-context-import-status.js.map +1 -0
  23. package/dist/actions/get-context-item.d.ts +2 -0
  24. package/dist/actions/get-context-item.d.ts.map +1 -0
  25. package/dist/actions/get-context-item.js +2 -0
  26. package/dist/actions/get-context-item.js.map +1 -0
  27. package/dist/actions/get-context-pack.d.ts +7 -0
  28. package/dist/actions/get-context-pack.d.ts.map +1 -0
  29. package/dist/actions/get-context-pack.js +12 -0
  30. package/dist/actions/get-context-pack.js.map +1 -0
  31. package/dist/actions/get-creative-context.d.ts +119 -0
  32. package/dist/actions/get-creative-context.d.ts.map +1 -0
  33. package/dist/actions/get-creative-context.js +112 -0
  34. package/dist/actions/get-creative-context.js.map +1 -0
  35. package/dist/actions/index.d.ts +3 -0
  36. package/dist/actions/index.d.ts.map +1 -0
  37. package/dist/actions/index.js +63 -0
  38. package/dist/actions/index.js.map +1 -0
  39. package/dist/actions/infer-brand-dna.d.ts +52 -0
  40. package/dist/actions/infer-brand-dna.d.ts.map +1 -0
  41. package/dist/actions/infer-brand-dna.js +13 -0
  42. package/dist/actions/infer-brand-dna.js.map +1 -0
  43. package/dist/actions/list-canonical-logo-candidates.d.ts +9 -0
  44. package/dist/actions/list-canonical-logo-candidates.d.ts.map +1 -0
  45. package/dist/actions/list-canonical-logo-candidates.js +82 -0
  46. package/dist/actions/list-canonical-logo-candidates.js.map +1 -0
  47. package/dist/actions/list-context-connections.d.ts +22 -0
  48. package/dist/actions/list-context-connections.d.ts.map +1 -0
  49. package/dist/actions/list-context-connections.js +43 -0
  50. package/dist/actions/list-context-connections.js.map +1 -0
  51. package/dist/actions/list-context-packs.d.ts +10 -0
  52. package/dist/actions/list-context-packs.d.ts.map +1 -0
  53. package/dist/actions/list-context-packs.js +16 -0
  54. package/dist/actions/list-context-packs.js.map +1 -0
  55. package/dist/actions/list-context-sources.d.ts +12 -0
  56. package/dist/actions/list-context-sources.d.ts.map +1 -0
  57. package/dist/actions/list-context-sources.js +20 -0
  58. package/dist/actions/list-context-sources.js.map +1 -0
  59. package/dist/actions/list-context-suggestions.d.ts +13 -0
  60. package/dist/actions/list-context-suggestions.d.ts.map +1 -0
  61. package/dist/actions/list-context-suggestions.js +28 -0
  62. package/dist/actions/list-context-suggestions.js.map +1 -0
  63. package/dist/actions/manage-brand-profile.d.ts +28 -0
  64. package/dist/actions/manage-brand-profile.d.ts.map +1 -0
  65. package/dist/actions/manage-brand-profile.js +47 -0
  66. package/dist/actions/manage-brand-profile.js.map +1 -0
  67. package/dist/actions/manage-context-pack.d.ts +33 -0
  68. package/dist/actions/manage-context-pack.d.ts.map +1 -0
  69. package/dist/actions/manage-context-pack.js +65 -0
  70. package/dist/actions/manage-context-pack.js.map +1 -0
  71. package/dist/actions/manage-context-source.d.ts +51 -0
  72. package/dist/actions/manage-context-source.d.ts.map +1 -0
  73. package/dist/actions/manage-context-source.js +137 -0
  74. package/dist/actions/manage-context-source.js.map +1 -0
  75. package/dist/actions/manage-layout-template.d.ts +13 -0
  76. package/dist/actions/manage-layout-template.d.ts.map +1 -0
  77. package/dist/actions/manage-layout-template.js +43 -0
  78. package/dist/actions/manage-layout-template.js.map +1 -0
  79. package/dist/actions/preview-context-import.d.ts +23 -0
  80. package/dist/actions/preview-context-import.d.ts.map +1 -0
  81. package/dist/actions/preview-context-import.js +57 -0
  82. package/dist/actions/preview-context-import.js.map +1 -0
  83. package/dist/actions/process-context-purge.d.ts +22 -0
  84. package/dist/actions/process-context-purge.d.ts.map +1 -0
  85. package/dist/actions/process-context-purge.js +19 -0
  86. package/dist/actions/process-context-purge.js.map +1 -0
  87. package/dist/actions/propose-brand-dna.d.ts +15 -0
  88. package/dist/actions/propose-brand-dna.d.ts.map +1 -0
  89. package/dist/actions/propose-brand-dna.js +19 -0
  90. package/dist/actions/propose-brand-dna.js.map +1 -0
  91. package/dist/actions/propose-canonical-logo.d.ts +9 -0
  92. package/dist/actions/propose-canonical-logo.d.ts.map +1 -0
  93. package/dist/actions/propose-canonical-logo.js +16 -0
  94. package/dist/actions/propose-canonical-logo.js.map +1 -0
  95. package/dist/actions/publish-brand-dna.d.ts +13 -0
  96. package/dist/actions/publish-brand-dna.d.ts.map +1 -0
  97. package/dist/actions/publish-brand-dna.js +23 -0
  98. package/dist/actions/publish-brand-dna.js.map +1 -0
  99. package/dist/actions/recommend-context-roots.d.ts +14 -0
  100. package/dist/actions/recommend-context-roots.d.ts.map +1 -0
  101. package/dist/actions/recommend-context-roots.js +22 -0
  102. package/dist/actions/recommend-context-roots.js.map +1 -0
  103. package/dist/actions/record-context-feedback.d.ts +10 -0
  104. package/dist/actions/record-context-feedback.d.ts.map +1 -0
  105. package/dist/actions/record-context-feedback.js +14 -0
  106. package/dist/actions/record-context-feedback.js.map +1 -0
  107. package/dist/actions/review-context-items.d.ts +35 -0
  108. package/dist/actions/review-context-items.d.ts.map +1 -0
  109. package/dist/actions/review-context-items.js +65 -0
  110. package/dist/actions/review-context-items.js.map +1 -0
  111. package/dist/actions/run-embedding-bakeoff.d.ts +15 -0
  112. package/dist/actions/run-embedding-bakeoff.d.ts.map +1 -0
  113. package/dist/actions/run-embedding-bakeoff.js +72 -0
  114. package/dist/actions/run-embedding-bakeoff.js.map +1 -0
  115. package/dist/actions/search-creative-context.d.ts +75 -0
  116. package/dist/actions/search-creative-context.d.ts.map +1 -0
  117. package/dist/actions/search-creative-context.js +41 -0
  118. package/dist/actions/search-creative-context.js.map +1 -0
  119. package/dist/actions/set-brand-dna.d.ts +15 -0
  120. package/dist/actions/set-brand-dna.d.ts.map +1 -0
  121. package/dist/actions/set-brand-dna.js +19 -0
  122. package/dist/actions/set-brand-dna.js.map +1 -0
  123. package/dist/actions/start-context-enrichment.d.ts +10 -0
  124. package/dist/actions/start-context-enrichment.d.ts.map +1 -0
  125. package/dist/actions/start-context-enrichment.js +46 -0
  126. package/dist/actions/start-context-enrichment.js.map +1 -0
  127. package/dist/actions/start-context-import.d.ts +9 -0
  128. package/dist/actions/start-context-import.d.ts.map +1 -0
  129. package/dist/actions/start-context-import.js +36 -0
  130. package/dist/actions/start-context-import.js.map +1 -0
  131. package/dist/client/CreativeContextChip.d.ts +13 -0
  132. package/dist/client/CreativeContextChip.d.ts.map +1 -0
  133. package/dist/client/CreativeContextChip.js +45 -0
  134. package/dist/client/CreativeContextChip.js.map +1 -0
  135. package/dist/client/CreativeContextPanel.d.ts +131 -0
  136. package/dist/client/CreativeContextPanel.d.ts.map +1 -0
  137. package/dist/client/CreativeContextPanel.js +778 -0
  138. package/dist/client/CreativeContextPanel.js.map +1 -0
  139. package/dist/client/CreativeContextSettingsLink.d.ts +4 -0
  140. package/dist/client/CreativeContextSettingsLink.d.ts.map +1 -0
  141. package/dist/client/CreativeContextSettingsLink.js +8 -0
  142. package/dist/client/CreativeContextSettingsLink.js.map +1 -0
  143. package/dist/client/actions.d.ts +256 -0
  144. package/dist/client/actions.d.ts.map +1 -0
  145. package/dist/client/actions.js +89 -0
  146. package/dist/client/actions.js.map +1 -0
  147. package/dist/client/agent-tab.d.ts +9 -0
  148. package/dist/client/agent-tab.d.ts.map +1 -0
  149. package/dist/client/agent-tab.js +32 -0
  150. package/dist/client/agent-tab.js.map +1 -0
  151. package/dist/client/application-state.d.ts +22 -0
  152. package/dist/client/application-state.d.ts.map +1 -0
  153. package/dist/client/application-state.js +88 -0
  154. package/dist/client/application-state.js.map +1 -0
  155. package/dist/client/index.d.ts +8 -0
  156. package/dist/client/index.d.ts.map +1 -0
  157. package/dist/client/index.js +8 -0
  158. package/dist/client/index.js.map +1 -0
  159. package/dist/client/messages.d.ts +5 -0
  160. package/dist/client/messages.d.ts.map +1 -0
  161. package/dist/client/messages.js +1059 -0
  162. package/dist/client/messages.js.map +1 -0
  163. package/dist/connectors/context.d.ts +9 -0
  164. package/dist/connectors/context.d.ts.map +1 -0
  165. package/dist/connectors/context.js +59 -0
  166. package/dist/connectors/context.js.map +1 -0
  167. package/dist/connectors/document-parser.d.ts +2 -0
  168. package/dist/connectors/document-parser.d.ts.map +1 -0
  169. package/dist/connectors/document-parser.js +2 -0
  170. package/dist/connectors/document-parser.js.map +1 -0
  171. package/dist/connectors/figma-native.d.ts +18 -0
  172. package/dist/connectors/figma-native.d.ts.map +1 -0
  173. package/dist/connectors/figma-native.js +883 -0
  174. package/dist/connectors/figma-native.js.map +1 -0
  175. package/dist/connectors/figma.d.ts +10 -0
  176. package/dist/connectors/figma.d.ts.map +1 -0
  177. package/dist/connectors/figma.js +166 -0
  178. package/dist/connectors/figma.js.map +1 -0
  179. package/dist/connectors/google-slides-native.d.ts +58 -0
  180. package/dist/connectors/google-slides-native.d.ts.map +1 -0
  181. package/dist/connectors/google-slides-native.js +1118 -0
  182. package/dist/connectors/google-slides-native.js.map +1 -0
  183. package/dist/connectors/google-slides.d.ts +15 -0
  184. package/dist/connectors/google-slides.d.ts.map +1 -0
  185. package/dist/connectors/google-slides.js +896 -0
  186. package/dist/connectors/google-slides.js.map +1 -0
  187. package/dist/connectors/index.d.ts +20 -0
  188. package/dist/connectors/index.d.ts.map +1 -0
  189. package/dist/connectors/index.js +44 -0
  190. package/dist/connectors/index.js.map +1 -0
  191. package/dist/connectors/manual.d.ts +9 -0
  192. package/dist/connectors/manual.d.ts.map +1 -0
  193. package/dist/connectors/manual.js +91 -0
  194. package/dist/connectors/manual.js.map +1 -0
  195. package/dist/connectors/normalize.d.ts +35 -0
  196. package/dist/connectors/normalize.d.ts.map +1 -0
  197. package/dist/connectors/normalize.js +216 -0
  198. package/dist/connectors/normalize.js.map +1 -0
  199. package/dist/connectors/notion.d.ts +10 -0
  200. package/dist/connectors/notion.d.ts.map +1 -0
  201. package/dist/connectors/notion.js +393 -0
  202. package/dist/connectors/notion.js.map +1 -0
  203. package/dist/connectors/private-artifacts.d.ts +39 -0
  204. package/dist/connectors/private-artifacts.d.ts.map +1 -0
  205. package/dist/connectors/private-artifacts.js +175 -0
  206. package/dist/connectors/private-artifacts.js.map +1 -0
  207. package/dist/connectors/provider-response.d.ts +20 -0
  208. package/dist/connectors/provider-response.d.ts.map +1 -0
  209. package/dist/connectors/provider-response.js +98 -0
  210. package/dist/connectors/provider-response.js.map +1 -0
  211. package/dist/connectors/recommendations.d.ts +25 -0
  212. package/dist/connectors/recommendations.d.ts.map +1 -0
  213. package/dist/connectors/recommendations.js +172 -0
  214. package/dist/connectors/recommendations.js.map +1 -0
  215. package/dist/connectors/registry.d.ts +10 -0
  216. package/dist/connectors/registry.d.ts.map +1 -0
  217. package/dist/connectors/registry.js +34 -0
  218. package/dist/connectors/registry.js.map +1 -0
  219. package/dist/connectors/rendered-page.d.ts +101 -0
  220. package/dist/connectors/rendered-page.d.ts.map +1 -0
  221. package/dist/connectors/rendered-page.js +504 -0
  222. package/dist/connectors/rendered-page.js.map +1 -0
  223. package/dist/connectors/smart-defaults.d.ts +9 -0
  224. package/dist/connectors/smart-defaults.d.ts.map +1 -0
  225. package/dist/connectors/smart-defaults.js +72 -0
  226. package/dist/connectors/smart-defaults.js.map +1 -0
  227. package/dist/connectors/types.d.ts +79 -0
  228. package/dist/connectors/types.d.ts.map +1 -0
  229. package/dist/connectors/types.js +2 -0
  230. package/dist/connectors/types.js.map +1 -0
  231. package/dist/connectors/upload.d.ts +9 -0
  232. package/dist/connectors/upload.d.ts.map +1 -0
  233. package/dist/connectors/upload.js +440 -0
  234. package/dist/connectors/upload.js.map +1 -0
  235. package/dist/connectors/website.d.ts +20 -0
  236. package/dist/connectors/website.d.ts.map +1 -0
  237. package/dist/connectors/website.js +616 -0
  238. package/dist/connectors/website.js.map +1 -0
  239. package/dist/embeddings/index.d.ts +3 -0
  240. package/dist/embeddings/index.d.ts.map +1 -0
  241. package/dist/embeddings/index.js +3 -0
  242. package/dist/embeddings/index.js.map +1 -0
  243. package/dist/embeddings/providers.d.ts +7 -0
  244. package/dist/embeddings/providers.d.ts.map +1 -0
  245. package/dist/embeddings/providers.js +176 -0
  246. package/dist/embeddings/providers.js.map +1 -0
  247. package/dist/embeddings/types.d.ts +19 -0
  248. package/dist/embeddings/types.d.ts.map +1 -0
  249. package/dist/embeddings/types.js +2 -0
  250. package/dist/embeddings/types.js.map +1 -0
  251. package/dist/eval/acceptance-fixtures.d.ts +3 -0
  252. package/dist/eval/acceptance-fixtures.d.ts.map +1 -0
  253. package/dist/eval/acceptance-fixtures.js +84 -0
  254. package/dist/eval/acceptance-fixtures.js.map +1 -0
  255. package/dist/eval/acceptance.d.ts +114 -0
  256. package/dist/eval/acceptance.d.ts.map +1 -0
  257. package/dist/eval/acceptance.js +260 -0
  258. package/dist/eval/acceptance.js.map +1 -0
  259. package/dist/eval/fixtures.d.ts +16 -0
  260. package/dist/eval/fixtures.d.ts.map +1 -0
  261. package/dist/eval/fixtures.js +119 -0
  262. package/dist/eval/fixtures.js.map +1 -0
  263. package/dist/eval/index.d.ts +63 -0
  264. package/dist/eval/index.d.ts.map +1 -0
  265. package/dist/eval/index.js +174 -0
  266. package/dist/eval/index.js.map +1 -0
  267. package/dist/index.d.ts +5 -0
  268. package/dist/index.d.ts.map +1 -0
  269. package/dist/index.js +5 -0
  270. package/dist/index.js.map +1 -0
  271. package/dist/jobs/background-worker.d.ts +31 -0
  272. package/dist/jobs/background-worker.d.ts.map +1 -0
  273. package/dist/jobs/background-worker.js +315 -0
  274. package/dist/jobs/background-worker.js.map +1 -0
  275. package/dist/jobs/import-runner.d.ts +3 -0
  276. package/dist/jobs/import-runner.d.ts.map +1 -0
  277. package/dist/jobs/import-runner.js +613 -0
  278. package/dist/jobs/import-runner.js.map +1 -0
  279. package/dist/jobs/index.d.ts +9 -0
  280. package/dist/jobs/index.d.ts.map +1 -0
  281. package/dist/jobs/index.js +8 -0
  282. package/dist/jobs/index.js.map +1 -0
  283. package/dist/jobs/progress.d.ts +3 -0
  284. package/dist/jobs/progress.d.ts.map +1 -0
  285. package/dist/jobs/progress.js +30 -0
  286. package/dist/jobs/progress.js.map +1 -0
  287. package/dist/jobs/rebuild.d.ts +13 -0
  288. package/dist/jobs/rebuild.d.ts.map +1 -0
  289. package/dist/jobs/rebuild.js +178 -0
  290. package/dist/jobs/rebuild.js.map +1 -0
  291. package/dist/jobs/server-worker.d.ts +16 -0
  292. package/dist/jobs/server-worker.d.ts.map +1 -0
  293. package/dist/jobs/server-worker.js +252 -0
  294. package/dist/jobs/server-worker.js.map +1 -0
  295. package/dist/jobs/store-adapter.d.ts +3 -0
  296. package/dist/jobs/store-adapter.d.ts.map +1 -0
  297. package/dist/jobs/store-adapter.js +37 -0
  298. package/dist/jobs/store-adapter.js.map +1 -0
  299. package/dist/jobs/types.d.ts +138 -0
  300. package/dist/jobs/types.d.ts.map +1 -0
  301. package/dist/jobs/types.js +2 -0
  302. package/dist/jobs/types.js.map +1 -0
  303. package/dist/jobs/worker.d.ts +27 -0
  304. package/dist/jobs/worker.d.ts.map +1 -0
  305. package/dist/jobs/worker.js +90 -0
  306. package/dist/jobs/worker.js.map +1 -0
  307. package/dist/media-url.d.ts +7 -0
  308. package/dist/media-url.d.ts.map +1 -0
  309. package/dist/media-url.js +15 -0
  310. package/dist/media-url.js.map +1 -0
  311. package/dist/native-artifact-reassembly.d.ts +25 -0
  312. package/dist/native-artifact-reassembly.d.ts.map +1 -0
  313. package/dist/native-artifact-reassembly.js +262 -0
  314. package/dist/native-artifact-reassembly.js.map +1 -0
  315. package/dist/native-artifact.d.ts +88 -0
  316. package/dist/native-artifact.d.ts.map +1 -0
  317. package/dist/native-artifact.js +86 -0
  318. package/dist/native-artifact.js.map +1 -0
  319. package/dist/schema/index.d.ts +5519 -0
  320. package/dist/schema/index.d.ts.map +1 -0
  321. package/dist/schema/index.js +374 -0
  322. package/dist/schema/index.js.map +1 -0
  323. package/dist/schema/migrations.d.ts +10 -0
  324. package/dist/schema/migrations.d.ts.map +1 -0
  325. package/dist/schema/migrations.js +253 -0
  326. package/dist/schema/migrations.js.map +1 -0
  327. package/dist/search/fusion.d.ts +15 -0
  328. package/dist/search/fusion.d.ts.map +1 -0
  329. package/dist/search/fusion.js +25 -0
  330. package/dist/search/fusion.js.map +1 -0
  331. package/dist/search/mode.d.ts +4 -0
  332. package/dist/search/mode.d.ts.map +1 -0
  333. package/dist/search/mode.js +13 -0
  334. package/dist/search/mode.js.map +1 -0
  335. package/dist/search/postgres-fts.d.ts +22 -0
  336. package/dist/search/postgres-fts.d.ts.map +1 -0
  337. package/dist/search/postgres-fts.js +83 -0
  338. package/dist/search/postgres-fts.js.map +1 -0
  339. package/dist/server/brand-context.d.ts +15 -0
  340. package/dist/server/brand-context.d.ts.map +1 -0
  341. package/dist/server/brand-context.js +149 -0
  342. package/dist/server/brand-context.js.map +1 -0
  343. package/dist/server/context.d.ts +77 -0
  344. package/dist/server/context.d.ts.map +1 -0
  345. package/dist/server/context.js +63 -0
  346. package/dist/server/context.js.map +1 -0
  347. package/dist/server/enrichment.d.ts +23 -0
  348. package/dist/server/enrichment.d.ts.map +1 -0
  349. package/dist/server/enrichment.js +136 -0
  350. package/dist/server/enrichment.js.map +1 -0
  351. package/dist/server/generation-artifact-access.d.ts +21 -0
  352. package/dist/server/generation-artifact-access.d.ts.map +1 -0
  353. package/dist/server/generation-artifact-access.js +111 -0
  354. package/dist/server/generation-artifact-access.js.map +1 -0
  355. package/dist/server/generation-context.d.ts +204 -0
  356. package/dist/server/generation-context.d.ts.map +1 -0
  357. package/dist/server/generation-context.js +310 -0
  358. package/dist/server/generation-context.js.map +1 -0
  359. package/dist/server/index.d.ts +22 -0
  360. package/dist/server/index.d.ts.map +1 -0
  361. package/dist/server/index.js +96 -0
  362. package/dist/server/index.js.map +1 -0
  363. package/dist/server/isolated-a2a.d.ts +172 -0
  364. package/dist/server/isolated-a2a.d.ts.map +1 -0
  365. package/dist/server/isolated-a2a.js +310 -0
  366. package/dist/server/isolated-a2a.js.map +1 -0
  367. package/dist/server/media.d.ts +15 -0
  368. package/dist/server/media.d.ts.map +1 -0
  369. package/dist/server/media.js +93 -0
  370. package/dist/server/media.js.map +1 -0
  371. package/dist/server/prompt-provider.d.ts +5 -0
  372. package/dist/server/prompt-provider.d.ts.map +1 -0
  373. package/dist/server/prompt-provider.js +59 -0
  374. package/dist/server/prompt-provider.js.map +1 -0
  375. package/dist/server/public-serialization.d.ts +160 -0
  376. package/dist/server/public-serialization.d.ts.map +1 -0
  377. package/dist/server/public-serialization.js +108 -0
  378. package/dist/server/public-serialization.js.map +1 -0
  379. package/dist/server/resource-paths.d.ts +3 -0
  380. package/dist/server/resource-paths.d.ts.map +1 -0
  381. package/dist/server/resource-paths.js +5 -0
  382. package/dist/server/resource-paths.js.map +1 -0
  383. package/dist/server/retrieval.d.ts +78 -0
  384. package/dist/server/retrieval.d.ts.map +1 -0
  385. package/dist/server/retrieval.js +443 -0
  386. package/dist/server/retrieval.js.map +1 -0
  387. package/dist/server/untrusted-reference.d.ts +8 -0
  388. package/dist/server/untrusted-reference.d.ts.map +1 -0
  389. package/dist/server/untrusted-reference.js +19 -0
  390. package/dist/server/untrusted-reference.js.map +1 -0
  391. package/dist/store/brand.d.ts +47 -0
  392. package/dist/store/brand.d.ts.map +1 -0
  393. package/dist/store/brand.js +360 -0
  394. package/dist/store/brand.js.map +1 -0
  395. package/dist/store/content.d.ts +120 -0
  396. package/dist/store/content.d.ts.map +1 -0
  397. package/dist/store/content.js +1437 -0
  398. package/dist/store/content.js.map +1 -0
  399. package/dist/store/generation.d.ts +28 -0
  400. package/dist/store/generation.d.ts.map +1 -0
  401. package/dist/store/generation.js +140 -0
  402. package/dist/store/generation.js.map +1 -0
  403. package/dist/store/helpers.d.ts +12 -0
  404. package/dist/store/helpers.d.ts.map +1 -0
  405. package/dist/store/helpers.js +41 -0
  406. package/dist/store/helpers.js.map +1 -0
  407. package/dist/store/index.d.ts +10 -0
  408. package/dist/store/index.d.ts.map +1 -0
  409. package/dist/store/index.js +10 -0
  410. package/dist/store/index.js.map +1 -0
  411. package/dist/store/inference.d.ts +57 -0
  412. package/dist/store/inference.d.ts.map +1 -0
  413. package/dist/store/inference.js +279 -0
  414. package/dist/store/inference.js.map +1 -0
  415. package/dist/store/jobs.d.ts +80 -0
  416. package/dist/store/jobs.d.ts.map +1 -0
  417. package/dist/store/jobs.js +428 -0
  418. package/dist/store/jobs.js.map +1 -0
  419. package/dist/store/packs.d.ts +33 -0
  420. package/dist/store/packs.d.ts.map +1 -0
  421. package/dist/store/packs.js +321 -0
  422. package/dist/store/packs.js.map +1 -0
  423. package/dist/store/purge.d.ts +16 -0
  424. package/dist/store/purge.d.ts.map +1 -0
  425. package/dist/store/purge.js +256 -0
  426. package/dist/store/purge.js.map +1 -0
  427. package/dist/store/sources.d.ts +76 -0
  428. package/dist/store/sources.d.ts.map +1 -0
  429. package/dist/store/sources.js +538 -0
  430. package/dist/store/sources.js.map +1 -0
  431. package/dist/store/suggestions.d.ts +28 -0
  432. package/dist/store/suggestions.d.ts.map +1 -0
  433. package/dist/store/suggestions.js +250 -0
  434. package/dist/store/suggestions.js.map +1 -0
  435. package/dist/types.d.ts +493 -0
  436. package/dist/types.d.ts.map +1 -0
  437. package/dist/types.js +2 -0
  438. package/dist/types.js.map +1 -0
  439. package/dist/vector/index.d.ts +2 -0
  440. package/dist/vector/index.d.ts.map +1 -0
  441. package/dist/vector/index.js +2 -0
  442. package/dist/vector/index.js.map +1 -0
  443. package/dist/vector/pgvector.d.ts +28 -0
  444. package/dist/vector/pgvector.d.ts.map +1 -0
  445. package/dist/vector/pgvector.js +117 -0
  446. package/dist/vector/pgvector.js.map +1 -0
  447. package/docs/evaluation.md +92 -0
  448. package/docs/llms-full.txt +168 -0
  449. package/docs/llms.txt +76 -0
  450. package/docs/skills/creative-context/SKILL.md +74 -0
  451. package/package.json +91 -0
  452. package/src/actions/agent-input-schemas.spec.ts +46 -0
  453. package/src/actions/confirm-canonical-logo.ts +20 -0
  454. package/src/actions/continue-context-import.ts +12 -0
  455. package/src/actions/creative-context-a2a.spec.ts +64 -0
  456. package/src/actions/creative-context-a2a.ts +88 -0
  457. package/src/actions/get-brand-profile.ts +16 -0
  458. package/src/actions/get-context-import-status.ts +13 -0
  459. package/src/actions/get-context-item.ts +1 -0
  460. package/src/actions/get-context-pack.ts +14 -0
  461. package/src/actions/get-creative-context.spec.ts +315 -0
  462. package/src/actions/get-creative-context.ts +148 -0
  463. package/src/actions/index.ts +65 -0
  464. package/src/actions/infer-brand-dna.ts +15 -0
  465. package/src/actions/list-canonical-logo-candidates.ts +121 -0
  466. package/src/actions/list-context-connections.spec.ts +23 -0
  467. package/src/actions/list-context-connections.ts +51 -0
  468. package/src/actions/list-context-packs.ts +17 -0
  469. package/src/actions/list-context-sources.ts +21 -0
  470. package/src/actions/list-context-suggestions.ts +30 -0
  471. package/src/actions/manage-brand-profile.ts +58 -0
  472. package/src/actions/manage-context-pack.ts +75 -0
  473. package/src/actions/manage-context-source.ts +154 -0
  474. package/src/actions/manage-layout-template.ts +51 -0
  475. package/src/actions/preview-context-import.spec.ts +64 -0
  476. package/src/actions/preview-context-import.ts +61 -0
  477. package/src/actions/process-context-purge.ts +25 -0
  478. package/src/actions/propose-brand-dna.ts +22 -0
  479. package/src/actions/propose-canonical-logo.ts +19 -0
  480. package/src/actions/publish-brand-dna.ts +25 -0
  481. package/src/actions/recommend-context-roots.ts +24 -0
  482. package/src/actions/record-context-feedback.ts +16 -0
  483. package/src/actions/review-context-items.ts +69 -0
  484. package/src/actions/run-embedding-bakeoff.ts +90 -0
  485. package/src/actions/search-creative-context.ts +47 -0
  486. package/src/actions/set-brand-dna.ts +22 -0
  487. package/src/actions/start-context-enrichment.ts +50 -0
  488. package/src/actions/start-context-import.ts +37 -0
  489. package/src/client/CreativeContextChip.tsx +162 -0
  490. package/src/client/CreativeContextPanel.tsx +2442 -0
  491. package/src/client/CreativeContextSettingsLink.tsx +30 -0
  492. package/src/client/actions.ts +438 -0
  493. package/src/client/agent-tab.tsx +58 -0
  494. package/src/client/application-state.spec.ts +41 -0
  495. package/src/client/application-state.ts +130 -0
  496. package/src/client/index.ts +62 -0
  497. package/src/client/messages.ts +1240 -0
  498. package/src/client/source-config.spec.ts +152 -0
  499. package/src/connectors/connectors.spec.ts +778 -0
  500. package/src/connectors/context.ts +83 -0
  501. package/src/connectors/document-parser.ts +5 -0
  502. package/src/connectors/figma-native.ts +1192 -0
  503. package/src/connectors/figma-native.visual.spec.ts +221 -0
  504. package/src/connectors/figma.spec.ts +812 -0
  505. package/src/connectors/figma.ts +257 -0
  506. package/src/connectors/fixtures/google-slides-native.json +353 -0
  507. package/src/connectors/google-slides-native.spec.ts +804 -0
  508. package/src/connectors/google-slides-native.ts +1656 -0
  509. package/src/connectors/google-slides-native.visual.spec.ts +119 -0
  510. package/src/connectors/google-slides.ts +1172 -0
  511. package/src/connectors/index.ts +103 -0
  512. package/src/connectors/manual.ts +132 -0
  513. package/src/connectors/normalize.ts +277 -0
  514. package/src/connectors/notion.ts +529 -0
  515. package/src/connectors/private-artifacts.spec.ts +95 -0
  516. package/src/connectors/private-artifacts.ts +248 -0
  517. package/src/connectors/provider-response.ts +144 -0
  518. package/src/connectors/recommendations.ts +237 -0
  519. package/src/connectors/registry.ts +48 -0
  520. package/src/connectors/rendered-page.ts +705 -0
  521. package/src/connectors/smart-defaults.spec.ts +135 -0
  522. package/src/connectors/smart-defaults.ts +87 -0
  523. package/src/connectors/types.ts +115 -0
  524. package/src/connectors/upload.spec.ts +175 -0
  525. package/src/connectors/upload.ts +548 -0
  526. package/src/connectors/website.spec.ts +509 -0
  527. package/src/connectors/website.ts +777 -0
  528. package/src/embeddings/index.ts +2 -0
  529. package/src/embeddings/providers.spec.ts +73 -0
  530. package/src/embeddings/providers.ts +228 -0
  531. package/src/embeddings/types.ts +24 -0
  532. package/src/eval/acceptance-fixtures.ts +97 -0
  533. package/src/eval/acceptance.spec.ts +92 -0
  534. package/src/eval/acceptance.ts +371 -0
  535. package/src/eval/connectors-golden.spec.ts +421 -0
  536. package/src/eval/eval.spec.ts +166 -0
  537. package/src/eval/fixtures/README.md +17 -0
  538. package/src/eval/fixtures/figma-brand-system-v1.json +140 -0
  539. package/src/eval/fixtures/figma-brand-system-v2.json +127 -0
  540. package/src/eval/fixtures/launch-hero.png +0 -0
  541. package/src/eval/fixtures/launch-system-v1.pptx +0 -0
  542. package/src/eval/fixtures/launch-system-v2.pptx +0 -0
  543. package/src/eval/fixtures/notion-brand-root.json +218 -0
  544. package/src/eval/fixtures/pricing-hero.png +0 -0
  545. package/src/eval/fixtures/rendered-brand-page.html +76 -0
  546. package/src/eval/fixtures.spec.ts +43 -0
  547. package/src/eval/fixtures.ts +136 -0
  548. package/src/eval/index.ts +291 -0
  549. package/src/eval/library-flow.acceptance.spec.tsx +141 -0
  550. package/src/index.ts +4 -0
  551. package/src/jobs/background-worker.ts +423 -0
  552. package/src/jobs/import-runner.spec.ts +582 -0
  553. package/src/jobs/import-runner.ts +792 -0
  554. package/src/jobs/index.ts +40 -0
  555. package/src/jobs/progress.ts +37 -0
  556. package/src/jobs/rebuild.ts +245 -0
  557. package/src/jobs/server-worker.spec.ts +159 -0
  558. package/src/jobs/server-worker.ts +344 -0
  559. package/src/jobs/store-adapter.ts +52 -0
  560. package/src/jobs/types.ts +147 -0
  561. package/src/jobs/worker.ts +152 -0
  562. package/src/manifest.spec.ts +26 -0
  563. package/src/media-url.ts +17 -0
  564. package/src/native-artifact-reassembly.spec.ts +386 -0
  565. package/src/native-artifact-reassembly.ts +406 -0
  566. package/src/native-artifact.ts +102 -0
  567. package/src/schema/index.ts +411 -0
  568. package/src/schema/migrations.spec.ts +41 -0
  569. package/src/schema/migrations.ts +258 -0
  570. package/src/search/fusion.spec.ts +21 -0
  571. package/src/search/fusion.ts +39 -0
  572. package/src/search/mode.spec.ts +28 -0
  573. package/src/search/mode.ts +21 -0
  574. package/src/search/postgres-fts.spec.ts +71 -0
  575. package/src/search/postgres-fts.ts +112 -0
  576. package/src/server/brand-context.spec.ts +43 -0
  577. package/src/server/brand-context.ts +160 -0
  578. package/src/server/context.ts +162 -0
  579. package/src/server/enrichment.ts +163 -0
  580. package/src/server/generation-artifact-access.ts +216 -0
  581. package/src/server/generation-context-a2a.spec.ts +131 -0
  582. package/src/server/generation-context-off.spec.ts +213 -0
  583. package/src/server/generation-context.spec.ts +124 -0
  584. package/src/server/generation-context.ts +493 -0
  585. package/src/server/index.ts +135 -0
  586. package/src/server/isolated-a2a.spec.ts +164 -0
  587. package/src/server/isolated-a2a.ts +413 -0
  588. package/src/server/media.spec.ts +92 -0
  589. package/src/server/media.ts +117 -0
  590. package/src/server/prompt-provider.spec.ts +78 -0
  591. package/src/server/prompt-provider.ts +73 -0
  592. package/src/server/public-serialization.spec.ts +149 -0
  593. package/src/server/public-serialization.ts +130 -0
  594. package/src/server/resource-paths.spec.ts +9 -0
  595. package/src/server/resource-paths.ts +5 -0
  596. package/src/server/retrieval-vector.spec.ts +180 -0
  597. package/src/server/retrieval.ts +587 -0
  598. package/src/server/untrusted-reference.spec.ts +22 -0
  599. package/src/server/untrusted-reference.ts +24 -0
  600. package/src/store/access.integration.spec.ts +1922 -0
  601. package/src/store/brand.ts +477 -0
  602. package/src/store/content.ts +1900 -0
  603. package/src/store/generation.ts +226 -0
  604. package/src/store/helpers.ts +53 -0
  605. package/src/store/index.ts +9 -0
  606. package/src/store/inference.spec.ts +84 -0
  607. package/src/store/inference.ts +339 -0
  608. package/src/store/invariants.spec.ts +119 -0
  609. package/src/store/jobs.ts +672 -0
  610. package/src/store/packs.ts +466 -0
  611. package/src/store/purge.ts +321 -0
  612. package/src/store/sources.spec.ts +102 -0
  613. package/src/store/sources.ts +708 -0
  614. package/src/store/suggestions.ts +333 -0
  615. package/src/types.ts +571 -0
  616. package/src/vector/index.ts +1 -0
  617. package/src/vector/pgvector.spec.ts +98 -0
  618. package/src/vector/pgvector.ts +164 -0
@@ -0,0 +1,778 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useFormatters, useUploadResource, useT, } from "@agent-native/core/client";
3
+ import { useOrg } from "@agent-native/core/client/org";
4
+ import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, Badge, Button, Checkbox, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Skeleton, Textarea, } from "@agent-native/toolkit/ui";
5
+ import { IconAlertTriangle, IconArrowUpRight, IconBooks, IconCheck, IconDots, IconFileImport, IconFileText, IconLayout, IconPalette, IconPhoto, IconPin, IconRefresh, IconSearch, IconSlideshow, IconSparkles, IconUpload, IconWorld, } from "@tabler/icons-react";
6
+ import { useEffect, useMemo, useRef, useState, } from "react";
7
+ import { creativeContextMediaUrl } from "../media-url.js";
8
+ import { useCreativeContextBrandProfile, useCanonicalLogoCandidates, useCreativeContextConnections, useCreativeContextRootRecommendations, useCreativeContextImportStatus, useCreativeContextPack, useCreativeContextPacks, useCreativeContextSearch, useCreativeContextSuggestions, useCreativeContextSources, useManageCreativeContextSource, useManageLayoutTemplate, usePreviewCreativeContextImport, usePublishCreativeContextBrandDna, useConfirmCanonicalLogo, useProposeCanonicalLogo, useRefreshCreativeContextSource, useReviewCreativeContextItems, useStartCreativeContextImport, } from "./actions.js";
9
+ import { useCreativeContextState, } from "./application-state.js";
10
+ import { CreativeContextChip } from "./CreativeContextChip.js";
11
+ const CONNECTORS = [
12
+ {
13
+ kind: "google-slides",
14
+ label: "Google Slides",
15
+ referencePlaceholder: "Folder or shared-drive URL / ID",
16
+ referenceRequired: false,
17
+ icon: IconSlideshow,
18
+ },
19
+ {
20
+ kind: "figma",
21
+ label: "Figma",
22
+ referencePlaceholder: "Team, project, or file URLs — one per line",
23
+ referenceRequired: false,
24
+ icon: IconPalette,
25
+ },
26
+ {
27
+ kind: "notion",
28
+ label: "Notion",
29
+ referencePlaceholder: "Page or teamspace root URLs / IDs — one per line",
30
+ referenceRequired: false,
31
+ icon: IconFileText,
32
+ },
33
+ {
34
+ kind: "website",
35
+ label: "Website",
36
+ referencePlaceholder: "https://example.com\nhttps://example.com/about",
37
+ referenceRequired: true,
38
+ icon: IconWorld,
39
+ },
40
+ {
41
+ kind: "upload",
42
+ label: "Uploaded files",
43
+ referencePlaceholder: "One hosted file URL per line",
44
+ referenceRequired: true,
45
+ icon: IconUpload,
46
+ },
47
+ ];
48
+ function isVisibleInScope(visibility, scope) {
49
+ return scope === "org" ? visibility !== "private" : visibility === "private";
50
+ }
51
+ function splitReferences(value) {
52
+ return value
53
+ .split(/\r?\n|,/)
54
+ .map((entry) => entry.trim())
55
+ .filter(Boolean);
56
+ }
57
+ function connectionProviderForConnector(kind) {
58
+ if (kind === "google-slides")
59
+ return "google_drive";
60
+ if (kind === "figma" || kind === "notion")
61
+ return kind;
62
+ return null;
63
+ }
64
+ function recommendationProviderForConnector(kind) {
65
+ if (kind === "google-slides" || kind === "figma" || kind === "notion") {
66
+ return kind;
67
+ }
68
+ return null;
69
+ }
70
+ export function parseFigmaRecommendationBoundary(reference) {
71
+ for (const value of splitReferences(reference)) {
72
+ const teamId = value.match(/\/team\/([^/?#]+)/)?.[1] ??
73
+ (value.startsWith("team:") ? value.slice("team:".length) : undefined);
74
+ if (teamId)
75
+ return { figmaTeamId: teamId };
76
+ const projectId = value.match(/\/project\/([^/?#]+)/)?.[1] ??
77
+ (value.startsWith("project:")
78
+ ? value.slice("project:".length)
79
+ : undefined);
80
+ if (projectId)
81
+ return { figmaProjectId: projectId };
82
+ }
83
+ return {};
84
+ }
85
+ export function selectRenderableLayoutThumbnails(thumbnails) {
86
+ return thumbnails.filter((thumbnail) => thumbnail.hasThumbnail).slice(0, 3);
87
+ }
88
+ export function buildCreativeContextSourceConfig(kind, reference, uploadedFiles, recommendations = []) {
89
+ const references = splitReferences(reference);
90
+ if (kind === "google-slides") {
91
+ if (!references.length && recommendations.length) {
92
+ return {
93
+ presentationIds: recommendations.map((item) => item.externalId),
94
+ };
95
+ }
96
+ const container = references[0];
97
+ const folderMatch = container?.match(/\/folders\/([^/?#]+)/);
98
+ if (container?.startsWith("shared-drive:")) {
99
+ return { sharedDriveId: container.slice("shared-drive:".length) };
100
+ }
101
+ if (container && /^https?:\/\//.test(container)) {
102
+ return { folderUrl: container };
103
+ }
104
+ return container ? { folderId: folderMatch?.[1] ?? container } : {};
105
+ }
106
+ if (kind === "figma") {
107
+ const fileUrls = [];
108
+ const projectUrls = [];
109
+ const teamUrls = [];
110
+ for (const url of references) {
111
+ if (/\/team\//.test(url))
112
+ teamUrls.push(url);
113
+ else if (/\/project\//.test(url))
114
+ projectUrls.push(url);
115
+ else
116
+ fileUrls.push(url);
117
+ }
118
+ return {
119
+ fileUrls,
120
+ projectUrls,
121
+ teamUrls,
122
+ ...(recommendations.length
123
+ ? { fileKeys: recommendations.map((item) => item.externalId) }
124
+ : {}),
125
+ };
126
+ }
127
+ if (kind === "notion") {
128
+ const rootPageIds = [];
129
+ const rootPageUrls = [];
130
+ const teamspaceRootPageIds = [];
131
+ const teamspaceRootPageUrls = [];
132
+ for (const root of references) {
133
+ const isTeamspace = root.startsWith("teamspace:");
134
+ const value = isTeamspace ? root.slice("teamspace:".length) : root;
135
+ if (/^https?:\/\//.test(value)) {
136
+ (isTeamspace ? teamspaceRootPageUrls : rootPageUrls).push(value);
137
+ }
138
+ else {
139
+ (isTeamspace ? teamspaceRootPageIds : rootPageIds).push(value);
140
+ }
141
+ }
142
+ return {
143
+ rootPageIds: [
144
+ ...rootPageIds,
145
+ ...recommendations.map((item) => item.externalId),
146
+ ],
147
+ rootPageUrls,
148
+ teamspaceRootPageIds,
149
+ teamspaceRootPageUrls,
150
+ };
151
+ }
152
+ if (kind === "website")
153
+ return { urls: references };
154
+ return { items: uploadedFiles };
155
+ }
156
+ function ContextModeButton({ mode, activeMode, label, description, disabled, onSelect, }) {
157
+ const selected = mode === activeMode;
158
+ return (_jsxs("button", { type: "button", role: "radio", "aria-checked": selected, disabled: disabled, onClick: () => onSelect(mode), className: `min-w-0 flex-1 cursor-pointer rounded-md border px-3 py-2 text-start transition-colors disabled:cursor-not-allowed disabled:opacity-60 ${selected
159
+ ? "border-foreground/25 bg-accent/70 text-foreground"
160
+ : "border-border bg-background text-muted-foreground hover:bg-accent/40 hover:text-foreground"}`, children: [_jsx("span", { className: "block text-sm font-medium", children: label }), _jsx("span", { className: "mt-0.5 block text-xs leading-relaxed", children: description })] }));
161
+ }
162
+ function ScopeControl({ scope, onChange, }) {
163
+ const t = useT();
164
+ return (_jsx("div", { className: "inline-flex rounded-md border border-border bg-muted/30 p-0.5", children: ["user", "org"].map((value) => (_jsx("button", { type: "button", "aria-pressed": scope === value, onClick: () => onChange(value), className: `rounded px-2.5 py-1 text-xs font-medium transition-colors ${scope === value
165
+ ? "bg-background text-foreground shadow-sm"
166
+ : "text-muted-foreground hover:text-foreground"}`, children: t(value === "user"
167
+ ? "creativeContext.personal"
168
+ : "creativeContext.organization") }, value))) }));
169
+ }
170
+ function SourceRow({ source, refreshing, canReview, onRefresh, onReview, onCurate, canPromote, onPromote, onPause, onRestore, onDelete, }) {
171
+ const t = useT();
172
+ const { formatDate, formatNumber } = useFormatters();
173
+ return (_jsxs("div", { className: "flex items-start gap-3 border-t border-border/60 py-3 first:border-t-0", children: [_jsx("div", { className: "mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-md bg-muted text-muted-foreground", children: _jsx(IconBooks, { className: "size-4" }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("span", { className: "truncate text-sm font-medium text-foreground", children: source.name }), _jsx(Badge, { variant: "secondary", className: "font-normal", children: source.kind }), source.status === "error" ? (_jsx(Badge, { variant: "destructive", className: "font-normal", children: t("creativeContext.sourceError") })) : source.status !== "active" ? (_jsx(Badge, { variant: "outline", className: "font-normal", children: source.status })) : null] }), _jsxs("div", { className: "mt-1 flex flex-wrap gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [_jsx("span", { children: t("creativeContext.itemsLabel", {
174
+ count: formatNumber(source.itemCount),
175
+ }) }), source.lastSyncedAt ? (_jsx("span", { children: formatDate(source.lastSyncedAt, {
176
+ month: "short",
177
+ day: "numeric",
178
+ year: "numeric",
179
+ }) })) : null] }), source.restrictedItemCount > 0 ? (_jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-2 text-xs text-amber-700 dark:text-amber-300", children: [_jsx("span", { children: t("creativeContext.restrictedItems", {
180
+ count: formatNumber(source.restrictedItemCount),
181
+ }) }), canReview ? (_jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "h-6 px-2 text-xs", onClick: () => onReview(source), children: t("creativeContext.reviewRestricted") })) : null] })) : null, source.lastError ? (_jsx("p", { className: "mt-1 line-clamp-2 text-xs text-destructive", children: source.lastError })) : null] }), source.status !== "archived" ? (_jsxs(Button, { type: "button", variant: "ghost", size: "sm", disabled: refreshing, onClick: () => onRefresh(source.id), children: [_jsx(IconRefresh, { className: refreshing ? "animate-spin" : undefined }), refreshing
182
+ ? t("creativeContext.refreshing")
183
+ : t("creativeContext.refresh")] })) : null, _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": t("creativeContext.manage"), children: _jsx(IconDots, {}) }) }), _jsxs(DropdownMenuContent, { align: "end", children: [_jsx(DropdownMenuItem, { onSelect: () => onCurate(source), children: t("creativeContext.curateItems") }), source.status === "paused" || source.status === "error" ? (_jsx(DropdownMenuItem, { onSelect: () => onRestore(source), children: t("creativeContext.restore") })) : (_jsx(DropdownMenuItem, { onSelect: () => onPause(source), children: t("creativeContext.pause") })), canPromote ? (_jsx(DropdownMenuItem, { onSelect: () => onPromote(source), children: t("creativeContext.promoteToOrganization") })) : null, _jsx(DropdownMenuSeparator, {}), _jsx(DropdownMenuItem, { className: "text-destructive focus:text-destructive", onSelect: () => onDelete(source), children: t("creativeContext.delete") })] })] })] }));
184
+ }
185
+ function PackRow({ pack, pinned, disabled, onPin, onDetails, }) {
186
+ const t = useT();
187
+ const { formatNumber } = useFormatters();
188
+ return (_jsxs("div", { className: "flex items-center gap-3 border-t border-border/60 py-3 first:border-t-0", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "truncate text-sm font-medium", children: pack.name }), pinned ? (_jsxs(Badge, { variant: "secondary", className: "font-normal", children: [_jsx(IconPin, { className: "me-1 size-3" }), t("creativeContext.pinned")] })) : null] }), pack.description ? (_jsx("p", { className: "mt-0.5 line-clamp-2 text-xs text-muted-foreground", children: pack.description })) : null, _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: t("creativeContext.itemsLabel", {
189
+ count: formatNumber(pack.memberCount),
190
+ }) })] }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => onDetails(pack.id), children: t("creativeContext.packDetails") }), _jsxs(Button, { type: "button", variant: pinned ? "secondary" : "ghost", size: "sm", disabled: disabled, onClick: () => onPin(pinned ? null : pack.id), children: [_jsx(IconPin, {}), pinned ? t("creativeContext.unpin") : t("creativeContext.pin")] })] }));
191
+ }
192
+ function AccessScopedThumbnail({ itemId, itemVersionId, className, }) {
193
+ const [failed, setFailed] = useState(false);
194
+ if (failed) {
195
+ return (_jsx("div", { className: `flex items-center justify-center bg-muted text-muted-foreground ${className}`, children: _jsx(IconFileText, { className: "size-5" }) }));
196
+ }
197
+ return (_jsx("img", { src: creativeContextMediaUrl({ itemId, itemVersionId }), alt: "", className: className, onError: () => setFailed(true) }));
198
+ }
199
+ function ItemCuration({ source, items, busy, onReview, onClose, }) {
200
+ const t = useT();
201
+ return (_jsxs("div", { className: "mt-4 rounded-md border border-border p-4", children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-sm font-semibold", children: t("creativeContext.curateItems") }), _jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: source.name })] }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: onClose, children: t("creativeContext.cancel") })] }), _jsx("div", { className: "mt-3 grid gap-3 sm:grid-cols-2", children: items.map((item) => (_jsxs("article", { className: "overflow-hidden rounded-md border border-border/70", children: [item.thumbnailBlobRef ? (_jsx(AccessScopedThumbnail, { itemId: item.id, itemVersionId: item.currentVersionId, className: "aspect-video w-full object-cover" }, item.currentVersionId)) : (_jsx("div", { className: "flex aspect-video w-full items-center justify-center bg-muted text-muted-foreground", children: _jsx(IconFileText, { className: "size-5" }) })), _jsxs("div", { className: "p-3", children: [_jsxs("div", { className: "flex items-start justify-between gap-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "truncate text-sm font-medium", children: item.title }), _jsx("p", { className: "text-xs text-muted-foreground", children: item.kind })] }), _jsxs("div", { className: "flex flex-wrap justify-end gap-1", children: [item.curationRank === "exemplar" ? (_jsx(Badge, { variant: "secondary", children: t("creativeContext.exemplar") })) : null, item.status === "deprecated" ? (_jsx(Badge, { variant: "outline", children: t("creativeContext.deprecated") })) : null, item.upstreamAccess === "unknown" ? (_jsx(Badge, { variant: "outline", children: t("creativeContext.unknownAccess") })) : null] })] }), _jsxs("div", { className: "mt-3 flex flex-wrap gap-1.5", children: [_jsx(Button, { type: "button", variant: item.starred ? "secondary" : "outline", size: "sm", disabled: busy, onClick: () => onReview(item.starred ? "unstar" : "star", item.id), children: t(item.starred
202
+ ? "creativeContext.unstar"
203
+ : "creativeContext.star") }), _jsx(Button, { type: "button", variant: item.curationRank === "exemplar" ? "secondary" : "outline", size: "sm", disabled: busy, onClick: () => onReview(item.curationRank === "exemplar" ? "normal" : "exemplar", item.id), children: t("creativeContext.exemplar") }), _jsx(Button, { type: "button", variant: item.curationRank === "ignored" ? "secondary" : "outline", size: "sm", disabled: busy, onClick: () => onReview(item.curationRank === "ignored" ? "normal" : "ignore", item.id), children: t("creativeContext.ignore") }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", disabled: busy, onClick: () => onReview(item.status === "deprecated" ? "restore" : "deprecate", item.id), children: t(item.status === "deprecated"
204
+ ? "creativeContext.restore"
205
+ : "creativeContext.deprecate") })] }), item.curationStatus === "review" ? (_jsxs("div", { className: "mt-2 flex gap-1.5 border-t border-border/60 pt-2", children: [_jsx(Button, { type: "button", variant: "outline", size: "sm", disabled: busy, onClick: () => onReview("exclude", item.id), children: t("creativeContext.exclude") }), _jsx(Button, { type: "button", size: "sm", disabled: busy, onClick: () => onReview("approve", item.id), children: t("creativeContext.approve") })] })) : null] })] }, item.id))) })] }));
206
+ }
207
+ export function CreativeContextPanel({ scope = "user", canManageOrg = false, scopeControl, connectionsHref = "/agent#connections", }) {
208
+ const t = useT();
209
+ const { formatNumber } = useFormatters();
210
+ const { data: org } = useOrg();
211
+ const [libraryScope, setLibraryScope] = useState(scope);
212
+ const sourcesQuery = useCreativeContextSources({ limit: 100 });
213
+ const packsQuery = useCreativeContextPacks();
214
+ const brandProfileQuery = useCreativeContextBrandProfile();
215
+ const suggestionsQuery = useCreativeContextSuggestions();
216
+ const logoCandidatesQuery = useCanonicalLogoCandidates(brandProfileQuery.data?.profile?.id, suggestionsQuery.data?.capabilities.canonicalLogo === true);
217
+ const refreshSource = useRefreshCreativeContextSource();
218
+ const manageSource = useManageCreativeContextSource();
219
+ const uploadResource = useUploadResource();
220
+ const startImport = useStartCreativeContextImport();
221
+ const searchContext = useCreativeContextSearch();
222
+ const reviewItems = useReviewCreativeContextItems();
223
+ const publishBrandDna = usePublishCreativeContextBrandDna();
224
+ const proposeCanonicalLogo = useProposeCanonicalLogo();
225
+ const confirmCanonicalLogo = useConfirmCanonicalLogo();
226
+ const manageLayoutTemplate = useManageLayoutTemplate();
227
+ const contextState = useCreativeContextState();
228
+ const [query, setQuery] = useState("");
229
+ const [savingState, setSavingState] = useState(false);
230
+ const [stateError, setStateError] = useState(null);
231
+ const [refreshMessage, setRefreshMessage] = useState(null);
232
+ const [searchError, setSearchError] = useState(null);
233
+ const [connectorKind, setConnectorKind] = useState(null);
234
+ const connectionProvider = connectionProviderForConnector(connectorKind);
235
+ const connectionsQuery = useCreativeContextConnections(connectionProvider);
236
+ const [selectedConnectionId, setSelectedConnectionId] = useState("");
237
+ const [sourceName, setSourceName] = useState("");
238
+ const [sourceReference, setSourceReference] = useState("");
239
+ const recommendationProvider = recommendationProviderForConnector(connectorKind);
240
+ const recommendationsQuery = useCreativeContextRootRecommendations(recommendationProvider, selectedConnectionId || null, connectorKind === "figma"
241
+ ? parseFigmaRecommendationBoundary(sourceReference)
242
+ : {});
243
+ const [selectedRecommendationIds, setSelectedRecommendationIds] = useState(() => new Set());
244
+ const [uploadedFiles, setUploadedFiles] = useState([]);
245
+ const fileInputRef = useRef(null);
246
+ const folderInputRef = useRef(null);
247
+ const [setupError, setSetupError] = useState(null);
248
+ const [previewSourceId, setPreviewSourceId] = useState(null);
249
+ const [previewSourceName, setPreviewSourceName] = useState("");
250
+ const [selectedPreviewItemIds, setSelectedPreviewItemIds] = useState(() => new Set());
251
+ const initializedPreviewSelectionRef = useRef(null);
252
+ const [importJobId, setImportJobId] = useState(null);
253
+ const [importTargetScope, setImportTargetScope] = useState("user");
254
+ const [completedJobId, setCompletedJobId] = useState(null);
255
+ const [promotionPreview, setPromotionPreview] = useState(null);
256
+ const [promotionSourceId, setPromotionSourceId] = useState(null);
257
+ const [promotionMessage, setPromotionMessage] = useState(null);
258
+ const [lifecycleMessage, setLifecycleMessage] = useState(null);
259
+ const [deleteSource, setDeleteSource] = useState(null);
260
+ const [hiddenSourceIds, setHiddenSourceIds] = useState(() => new Set());
261
+ const [publishedMessage, setPublishedMessage] = useState(null);
262
+ const [reviewSource, setReviewSource] = useState(null);
263
+ const [reviewedItems, setReviewedItems] = useState([]);
264
+ const [reviewError, setReviewError] = useState(null);
265
+ const [selectedPackId, setSelectedPackId] = useState(null);
266
+ const [suggestionError, setSuggestionError] = useState(null);
267
+ const previewQuery = usePreviewCreativeContextImport(previewSourceId);
268
+ const importStatusQuery = useCreativeContextImportStatus(importJobId);
269
+ const packQuery = useCreativeContextPack(selectedPackId);
270
+ useEffect(() => setLibraryScope(scope), [scope]);
271
+ useEffect(() => {
272
+ if (!connectionProvider) {
273
+ setSelectedConnectionId("");
274
+ return;
275
+ }
276
+ setSelectedConnectionId(connectionsQuery.data?.autoSelectedConnectionId ?? "");
277
+ }, [connectionProvider, connectionsQuery.data?.autoSelectedConnectionId]);
278
+ useEffect(() => {
279
+ setSelectedRecommendationIds(new Set((recommendationsQuery.data?.recommendations ?? []).map((recommendation) => recommendation.externalId)));
280
+ }, [recommendationsQuery.data?.recommendations]);
281
+ const sources = useMemo(() => (sourcesQuery.data?.sources ?? []).filter((source) => source.status !== "archived" &&
282
+ !hiddenSourceIds.has(source.id) &&
283
+ isVisibleInScope(source.visibility, libraryScope)), [hiddenSourceIds, libraryScope, sourcesQuery.data?.sources]);
284
+ const packs = useMemo(() => (packsQuery.data?.packs ?? []).filter((pack) => !pack.archivedAt && isVisibleInScope(pack.visibility, libraryScope)), [libraryScope, packsQuery.data?.packs]);
285
+ const activePack = packs.find((pack) => pack.id === contextState.state.currentPackId);
286
+ const selectedConnector = CONNECTORS.find((connector) => connector.kind === connectorKind);
287
+ const importJob = importStatusQuery.data?.job;
288
+ const importResult = importJob?.result;
289
+ const brandProposal = importResult?.inference?.brandDnaProposal;
290
+ const brandLayoutThumbnails = selectRenderableLayoutThumbnails(brandProposal?.layoutThumbnails ?? []);
291
+ const brandVoicePreview = brandProposal?.voiceDescriptors?.join(" · ") ?? brandProposal?.voiceLine;
292
+ const canManageScope = libraryScope === "user" || canManageOrg;
293
+ const proposalCapabilities = suggestionsQuery.data?.capabilities;
294
+ const logoCandidates = proposalCapabilities?.canonicalLogo
295
+ ? (logoCandidatesQuery.data?.candidates ?? [])
296
+ : [];
297
+ const proposedLayouts = (suggestionsQuery.data?.suggestions ?? []).filter((suggestion) => suggestion.kind === "layout-template" &&
298
+ (suggestion.status === "proposed" || suggestion.status === "promoted"));
299
+ useEffect(() => {
300
+ if (!previewSourceId || !previewQuery.data)
301
+ return;
302
+ const defaults = previewQuery.data.smartDefaultExternalIds ?? [];
303
+ const initializationKey = `${previewSourceId}:${defaults.join("\u0000")}`;
304
+ if (initializedPreviewSelectionRef.current === initializationKey)
305
+ return;
306
+ const discoveredIds = new Set(previewQuery.data.items.map((item) => item.externalId));
307
+ setSelectedPreviewItemIds(new Set(defaults.filter((externalId) => discoveredIds.has(externalId))));
308
+ initializedPreviewSelectionRef.current = initializationKey;
309
+ }, [previewQuery.data, previewSourceId]);
310
+ useEffect(() => {
311
+ if (importJob?.status !== "completed" || completedJobId === importJob.id)
312
+ return;
313
+ setCompletedJobId(importJob.id);
314
+ void sourcesQuery.refetch();
315
+ void packsQuery.refetch();
316
+ void brandProfileQuery.refetch();
317
+ if (importTargetScope === "org" && previewSourceId) {
318
+ setPromotionSourceId(previewSourceId);
319
+ void manageSource
320
+ .mutateAsync({
321
+ operation: "preview-promotion",
322
+ sourceId: previewSourceId,
323
+ })
324
+ .then((result) => setPromotionPreview(result.promotionPreview ?? null))
325
+ .catch(() => setPromotionMessage(t("creativeContext.saveFailed")));
326
+ }
327
+ }, [
328
+ brandProfileQuery,
329
+ completedJobId,
330
+ importJob,
331
+ importTargetScope,
332
+ manageSource,
333
+ packsQuery,
334
+ previewSourceId,
335
+ sourcesQuery,
336
+ t,
337
+ ]);
338
+ async function changeMode(mode) {
339
+ if (mode === contextState.state.contextMode)
340
+ return;
341
+ setSavingState(true);
342
+ setStateError(null);
343
+ try {
344
+ await contextState.setState(mode === "off"
345
+ ? { contextMode: "off", currentPackId: null, pinnedPackId: null }
346
+ : { ...contextState.state, contextMode: "auto" });
347
+ }
348
+ catch {
349
+ setStateError(t("creativeContext.stateSaveFailed"));
350
+ }
351
+ finally {
352
+ setSavingState(false);
353
+ }
354
+ }
355
+ async function changePinnedPack(packId) {
356
+ setSavingState(true);
357
+ setStateError(null);
358
+ try {
359
+ await contextState.setState({
360
+ ...contextState.state,
361
+ contextMode: "auto",
362
+ pinnedPackId: packId,
363
+ });
364
+ }
365
+ catch {
366
+ setStateError(t("creativeContext.stateSaveFailed"));
367
+ }
368
+ finally {
369
+ setSavingState(false);
370
+ }
371
+ }
372
+ function refresh(sourceId) {
373
+ setRefreshMessage(null);
374
+ refreshSource.mutate({ sourceId, mode: "incremental" }, {
375
+ onSuccess: () => setRefreshMessage(t("creativeContext.refreshed")),
376
+ onError: () => setRefreshMessage(t("creativeContext.refreshFailed")),
377
+ });
378
+ }
379
+ async function uploadFiles(files) {
380
+ if (!files.length)
381
+ return;
382
+ setSetupError(null);
383
+ try {
384
+ const uploaded = await Promise.all(files.map(async (file) => {
385
+ const relativePath = file
386
+ .webkitRelativePath || file.name;
387
+ const safePath = relativePath
388
+ .replace(/\.\./g, "")
389
+ .replace(/[^a-zA-Z0-9._/-]/g, "-");
390
+ const formData = new FormData();
391
+ formData.append("file", file, file.name);
392
+ formData.append("path", `/creative-context/${Date.now()}-${safePath}`);
393
+ const resource = (await uploadResource.mutateAsync(formData));
394
+ const url = resource.url ?? resource.content;
395
+ if (!url)
396
+ throw new Error("Upload returned no file handle");
397
+ return {
398
+ id: resource.id,
399
+ title: file.name,
400
+ fileName: file.name,
401
+ mimeType: file.type || "application/octet-stream",
402
+ url,
403
+ };
404
+ }));
405
+ setUploadedFiles((current) => [...current, ...uploaded]);
406
+ }
407
+ catch {
408
+ setSetupError(t("creativeContext.saveFailed"));
409
+ }
410
+ }
411
+ function chooseFiles(event) {
412
+ void uploadFiles(Array.from(event.target.files ?? []));
413
+ event.target.value = "";
414
+ }
415
+ function dropFiles(event) {
416
+ event.preventDefault();
417
+ void uploadFiles(Array.from(event.dataTransfer.files));
418
+ }
419
+ async function previewImport(event) {
420
+ event.preventDefault();
421
+ if (!selectedConnector || !sourceName.trim())
422
+ return;
423
+ setSetupError(null);
424
+ setImportJobId(null);
425
+ setCompletedJobId(null);
426
+ setPublishedMessage(null);
427
+ try {
428
+ const confirmedRecommendations = (recommendationsQuery.data?.recommendations ?? []).filter((recommendation) => selectedRecommendationIds.has(recommendation.externalId));
429
+ const result = await manageSource.mutateAsync({
430
+ operation: "create",
431
+ name: sourceName.trim(),
432
+ kind: selectedConnector.kind,
433
+ connectionId: selectedConnectionId || undefined,
434
+ externalRef: selectedConnector.kind === "upload"
435
+ ? `${uploadedFiles.length} files`
436
+ : sourceReference.trim() ||
437
+ (confirmedRecommendations.length
438
+ ? `${selectedConnector.kind}:${confirmedRecommendations
439
+ .map((recommendation) => recommendation.externalId)
440
+ .join(",")}`
441
+ : undefined),
442
+ config: buildCreativeContextSourceConfig(selectedConnector.kind, sourceReference, uploadedFiles, confirmedRecommendations),
443
+ });
444
+ if (!result.source)
445
+ throw new Error("Source creation returned no source");
446
+ setImportTargetScope(libraryScope);
447
+ setPreviewSourceName(result.source.name);
448
+ setPreviewSourceId(result.source.id);
449
+ setSelectedPreviewItemIds(new Set());
450
+ initializedPreviewSelectionRef.current = null;
451
+ setPromotionSourceId(null);
452
+ setPromotionPreview(null);
453
+ setPromotionMessage(null);
454
+ setConnectorKind(null);
455
+ setSourceName("");
456
+ setSourceReference("");
457
+ setUploadedFiles([]);
458
+ await sourcesQuery.refetch();
459
+ }
460
+ catch {
461
+ setSetupError(t("creativeContext.saveFailed"));
462
+ }
463
+ }
464
+ async function confirmPromotion() {
465
+ if (!promotionSourceId || !promotionPreview)
466
+ return;
467
+ setPromotionMessage(null);
468
+ try {
469
+ await manageSource.mutateAsync({
470
+ operation: "promote",
471
+ sourceId: promotionSourceId,
472
+ confirmation: {
473
+ containerRef: promotionPreview.containerRef,
474
+ boundaryHash: promotionPreview.boundaryHash,
475
+ itemCount: promotionPreview.itemCount,
476
+ },
477
+ });
478
+ setPromotionMessage(t("creativeContext.promotionComplete"));
479
+ setPromotionPreview(null);
480
+ setPromotionSourceId(null);
481
+ await sourcesQuery.refetch();
482
+ }
483
+ catch {
484
+ setPromotionMessage(t("creativeContext.saveFailed"));
485
+ }
486
+ }
487
+ async function pauseSource(source) {
488
+ setLifecycleMessage(null);
489
+ try {
490
+ await manageSource.mutateAsync({
491
+ operation: "update",
492
+ sourceId: source.id,
493
+ patch: { status: "paused" },
494
+ });
495
+ setLifecycleMessage(t("creativeContext.sourcePaused"));
496
+ await sourcesQuery.refetch();
497
+ }
498
+ catch {
499
+ setLifecycleMessage(t("creativeContext.saveFailed"));
500
+ }
501
+ }
502
+ async function restoreSource(source) {
503
+ setLifecycleMessage(null);
504
+ try {
505
+ await manageSource.mutateAsync({
506
+ operation: "restore",
507
+ sourceId: source.id,
508
+ });
509
+ setLifecycleMessage(t("creativeContext.sourceRestored"));
510
+ await sourcesQuery.refetch();
511
+ }
512
+ catch {
513
+ setLifecycleMessage(t("creativeContext.saveFailed"));
514
+ }
515
+ }
516
+ async function previewSourcePromotion(source) {
517
+ setPromotionMessage(null);
518
+ setPromotionPreview(null);
519
+ setPromotionSourceId(source.id);
520
+ try {
521
+ const result = await manageSource.mutateAsync({
522
+ operation: "preview-promotion",
523
+ sourceId: source.id,
524
+ });
525
+ setPromotionPreview(result.promotionPreview ?? null);
526
+ }
527
+ catch {
528
+ setPromotionSourceId(null);
529
+ setPromotionMessage(t("creativeContext.saveFailed"));
530
+ }
531
+ }
532
+ async function confirmDeleteSource() {
533
+ if (!deleteSource)
534
+ return;
535
+ const sourceId = deleteSource.id;
536
+ setLifecycleMessage(null);
537
+ setDeleteSource(null);
538
+ setHiddenSourceIds((current) => new Set(current).add(sourceId));
539
+ try {
540
+ await manageSource.mutateAsync({ operation: "delete", sourceId });
541
+ setLifecycleMessage(t("creativeContext.deletionQueued"));
542
+ void sourcesQuery.refetch();
543
+ }
544
+ catch {
545
+ setHiddenSourceIds((current) => {
546
+ const next = new Set(current);
547
+ next.delete(sourceId);
548
+ return next;
549
+ });
550
+ setLifecycleMessage(t("creativeContext.saveFailed"));
551
+ }
552
+ }
553
+ async function beginImport() {
554
+ if (!previewSourceId || !selectedPreviewItemIds.size)
555
+ return;
556
+ setSetupError(null);
557
+ try {
558
+ const result = await startImport.mutateAsync({
559
+ sourceId: previewSourceId,
560
+ mode: "incremental",
561
+ itemExternalIds: (previewQuery.data?.items ?? [])
562
+ .map((item) => item.externalId)
563
+ .filter((externalId) => selectedPreviewItemIds.has(externalId)),
564
+ });
565
+ setImportJobId(result.job.id);
566
+ }
567
+ catch {
568
+ setSetupError(t("creativeContext.importFailed"));
569
+ }
570
+ }
571
+ async function publishProposal() {
572
+ const importResult = importJob?.result;
573
+ const proposal = importResult?.inference?.brandDnaProposal;
574
+ if (!proposal)
575
+ return;
576
+ setPublishedMessage(null);
577
+ try {
578
+ const result = await publishBrandDna.mutateAsync({
579
+ profileId: proposal.profileId,
580
+ proposalVersionId: proposal.dnaVersionId,
581
+ confirmation: {
582
+ proposalVersionId: proposal.dnaVersionId,
583
+ contentHash: proposal.contentHash,
584
+ },
585
+ });
586
+ setPublishedMessage(`${t("creativeContext.brandContextPublished")} · ${result.profile.name} · v${result.dna.versionNumber}`);
587
+ await brandProfileQuery.refetch();
588
+ }
589
+ catch {
590
+ setPublishedMessage(t("creativeContext.saveFailed"));
591
+ }
592
+ }
593
+ async function openItemCuration(source, queue = "all") {
594
+ setReviewSource(source);
595
+ setReviewError(null);
596
+ try {
597
+ const result = await reviewItems.mutateAsync({
598
+ sourceId: source.id,
599
+ operation: "list",
600
+ queue,
601
+ limit: 100,
602
+ });
603
+ setReviewedItems(result.items);
604
+ }
605
+ catch {
606
+ setReviewedItems([]);
607
+ setReviewError(t("creativeContext.unavailable"));
608
+ }
609
+ }
610
+ async function reviewContextItem(operation, itemId) {
611
+ if (!reviewSource)
612
+ return;
613
+ setReviewError(null);
614
+ try {
615
+ await reviewItems.mutateAsync({
616
+ sourceId: reviewSource.id,
617
+ operation,
618
+ itemIds: [itemId],
619
+ });
620
+ const result = await reviewItems.mutateAsync({
621
+ sourceId: reviewSource.id,
622
+ operation: "list",
623
+ queue: "all",
624
+ limit: 100,
625
+ });
626
+ setReviewedItems(result.items);
627
+ await sourcesQuery.refetch();
628
+ }
629
+ catch {
630
+ setReviewError(t("creativeContext.saveFailed"));
631
+ }
632
+ }
633
+ async function chooseCanonicalLogo(candidate) {
634
+ setSuggestionError(null);
635
+ try {
636
+ const suggestion = await proposeCanonicalLogo.mutateAsync({
637
+ profileId: brandProfileQuery.data?.profile?.id,
638
+ itemId: candidate.itemId,
639
+ itemVersionId: candidate.itemVersionId,
640
+ reason: "Selected from the ranked Library review card",
641
+ payload: { mediaId: candidate.mediaId },
642
+ });
643
+ await confirmCanonicalLogo.mutateAsync({
644
+ suggestionId: suggestion.id,
645
+ decision: "confirm",
646
+ });
647
+ await suggestionsQuery.refetch();
648
+ }
649
+ catch {
650
+ setSuggestionError(t("creativeContext.saveFailed"));
651
+ }
652
+ }
653
+ async function decideLayoutSuggestion(suggestionId, operation) {
654
+ setSuggestionError(null);
655
+ try {
656
+ await manageLayoutTemplate.mutateAsync({ suggestionId, operation });
657
+ await suggestionsQuery.refetch();
658
+ }
659
+ catch {
660
+ setSuggestionError(t("creativeContext.saveFailed"));
661
+ }
662
+ }
663
+ async function search(event) {
664
+ event.preventDefault();
665
+ const searchText = query.trim();
666
+ if (!searchText || !sources.length)
667
+ return;
668
+ setSearchError(null);
669
+ try {
670
+ const result = await searchContext.mutateAsync({
671
+ query: searchText,
672
+ sourceIds: sources.map((source) => source.id),
673
+ packId: contextState.state.pinnedPackId ?? undefined,
674
+ limit: 20,
675
+ snapshot: true,
676
+ });
677
+ if (result.contextPackId && contextState.state.contextMode === "auto") {
678
+ await contextState.setState({
679
+ ...contextState.state,
680
+ currentPackId: result.contextPackId,
681
+ });
682
+ }
683
+ }
684
+ catch {
685
+ setSearchError(t("creativeContext.unavailable"));
686
+ }
687
+ }
688
+ const loading = sourcesQuery.isLoading || packsQuery.isLoading || contextState.isLoading;
689
+ const unavailable = sourcesQuery.error || packsQuery.error;
690
+ return (_jsxs("div", { className: "mx-auto flex w-full max-w-5xl flex-col gap-7 p-6 lg:p-10", children: [_jsxs("header", { className: "flex flex-wrap items-start justify-between gap-4 border-b border-border/70 pb-5", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-2xl font-semibold tracking-tight", children: t("creativeContext.title") }), _jsx("p", { className: "mt-1 max-w-2xl text-sm text-muted-foreground", children: t("creativeContext.description") })] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [scopeControl ??
691
+ (org?.orgId ? (_jsx(ScopeControl, { scope: libraryScope, onChange: setLibraryScope })) : null), _jsx(CreativeContextChip, { state: contextState.state, packs: packs })] })] }), loading ? (_jsxs("div", { className: "space-y-3", "aria-label": t("creativeContext.loading"), children: [_jsx(Skeleton, { className: "h-24 w-full" }), _jsx(Skeleton, { className: "h-40 w-full" }), _jsx(Skeleton, { className: "h-32 w-full" })] })) : unavailable ? (_jsxs("div", { className: "flex items-center gap-3 rounded-md border border-dashed border-border p-6 text-sm text-muted-foreground", children: [_jsx(IconAlertTriangle, { className: "size-5" }), t("creativeContext.unavailable")] })) : (_jsxs(_Fragment, { children: [_jsxs("section", { className: "space-y-3", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-sm font-semibold", children: t("creativeContext.modeLabel") }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: activePack
692
+ ? `${t("creativeContext.activePack")}: ${activePack.name}`
693
+ : t("creativeContext.noActivePack") })] }), _jsxs("div", { className: "flex flex-col gap-2 sm:flex-row", role: "radiogroup", children: [_jsx(ContextModeButton, { mode: "auto", activeMode: contextState.state.contextMode, label: t("creativeContext.automatic"), description: t("creativeContext.automaticDescription"), disabled: savingState, onSelect: (mode) => void changeMode(mode) }), _jsx(ContextModeButton, { mode: "off", activeMode: contextState.state.contextMode, label: t("creativeContext.off"), description: t("creativeContext.offDescription"), disabled: savingState, onSelect: (mode) => void changeMode(mode) })] }), stateError ? (_jsx("p", { className: "text-xs text-destructive", children: stateError })) : null] }), brandProfileQuery.data?.profile && brandProfileQuery.data.dna ? (_jsx("section", { className: "border-t border-border/70 pt-6", children: _jsxs("div", { className: "rounded-md border border-border p-4", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-sm font-semibold", children: t("creativeContext.publishedBrandContext") }), _jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: brandProfileQuery.data.profile.name })] }), _jsxs(Badge, { variant: "secondary", children: ["v", brandProfileQuery.data.dna.versionNumber] })] }), _jsx("p", { className: "mt-3 text-sm text-muted-foreground", children: brandProfileQuery.data.dna.payload.summary })] }) })) : null, logoCandidates.length || proposedLayouts.length ? (_jsxs("section", { className: "border-t border-border/70 pt-6", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(IconSparkles, { className: "size-5 text-muted-foreground" }), _jsx("h2", { className: "text-lg font-semibold", children: t("creativeContext.suggestions") })] }), logoCandidates.length ? (_jsxs("div", { className: "mt-4", children: [_jsxs("h3", { className: "flex items-center gap-2 text-sm font-semibold", children: [_jsx(IconPhoto, { className: "size-4 text-muted-foreground" }), t("creativeContext.logo")] }), _jsx("div", { className: "mt-2 grid gap-3 sm:grid-cols-2 lg:grid-cols-3", children: logoCandidates.map((candidate) => (_jsxs("article", { className: "overflow-hidden rounded-md border border-border", children: [_jsx("div", { className: "flex h-28 items-center justify-center bg-muted/40 p-3", children: _jsx("img", { src: candidate.thumbnailUrl, alt: candidate.title, className: "max-h-full max-w-full object-contain" }) }), _jsxs("div", { className: "flex items-center justify-between gap-2 p-3", children: [_jsx("p", { className: "min-w-0 truncate text-sm font-medium", children: candidate.title }), _jsxs(Button, { type: "button", size: "sm", variant: "outline", disabled: proposeCanonicalLogo.isPending ||
694
+ confirmCanonicalLogo.isPending, onClick: () => void chooseCanonicalLogo(candidate), children: [_jsx(IconCheck, {}), t("creativeContext.approve")] })] })] }, candidate.mediaId))) })] })) : null, proposedLayouts.length &&
695
+ proposalCapabilities?.layoutTemplate ? (_jsxs("div", { className: "mt-5", children: [_jsxs("h3", { className: "flex items-center gap-2 text-sm font-semibold", children: [_jsx(IconLayout, { className: "size-4 text-muted-foreground" }), t("creativeContext.layouts")] }), _jsx("div", { className: "mt-2 divide-y divide-border/70 rounded-md border border-border", children: proposedLayouts.map((suggestion) => (_jsxs("article", { className: "flex flex-wrap items-center justify-between gap-3 p-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "truncate text-sm font-medium", children: suggestion.reason ?? suggestion.itemId }), _jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: suggestion.status })] }), _jsx("div", { className: "flex items-center gap-2", children: suggestion.status === "proposed" ? (_jsxs(_Fragment, { children: [_jsxs(Button, { type: "button", size: "sm", disabled: manageLayoutTemplate.isPending, onClick: () => void decideLayoutSuggestion(suggestion.id, "promote"), children: [_jsx(IconCheck, {}), t("creativeContext.approve")] }), _jsx(Button, { type: "button", size: "sm", variant: "outline", disabled: manageLayoutTemplate.isPending, onClick: () => void decideLayoutSuggestion(suggestion.id, "reject"), children: t("creativeContext.exclude") })] })) : (_jsx(Button, { type: "button", size: "sm", variant: "outline", disabled: manageLayoutTemplate.isPending, onClick: () => void decideLayoutSuggestion(suggestion.id, "demote"), children: t("creativeContext.deprecate") })) })] }, suggestion.id))) })] })) : null, suggestionError ? (_jsx("p", { className: "mt-3 text-sm text-destructive", children: suggestionError })) : null] })) : null, _jsxs("section", { className: "border-t border-border/70 pt-6", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-lg font-semibold", children: t("creativeContext.addSource") }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: t("creativeContext.sourcesDescription") })] }), _jsx("div", { className: "mt-4 grid gap-2 sm:grid-cols-2 lg:grid-cols-5", children: CONNECTORS.map((connector) => {
696
+ const Icon = connector.icon;
697
+ return (_jsxs("button", { type: "button", disabled: !canManageScope, onClick: () => {
698
+ setConnectorKind(connector.kind);
699
+ setSourceName(connector.label);
700
+ setSourceReference("");
701
+ setUploadedFiles([]);
702
+ setSelectedConnectionId("");
703
+ setSelectedRecommendationIds(new Set());
704
+ setSetupError(null);
705
+ }, className: "flex min-h-24 flex-col items-start justify-between rounded-md border border-border p-3 text-start transition-colors hover:bg-accent/50 disabled:cursor-not-allowed disabled:opacity-50", children: [_jsx(Icon, { className: "size-5 text-muted-foreground" }), _jsx("span", { className: "text-sm font-medium", children: connector.label })] }, connector.kind));
706
+ }) }), selectedConnector ? (_jsxs("form", { className: "mt-4 rounded-md border border-border p-4", onSubmit: (event) => void previewImport(event), children: [connectionProvider ? (_jsx("div", { className: "mb-3", children: connectionsQuery.isLoading ? (_jsx(Skeleton, { className: "h-9 w-full" })) : connectionsQuery.data?.needsSetup ? (_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 rounded-md border border-dashed border-border p-3 text-sm text-muted-foreground", children: [_jsx("span", { children: t("creativeContext.setupConnection") }), _jsx(Button, { asChild: true, type: "button", variant: "outline", size: "sm", children: _jsxs("a", { href: connectionsQuery.data.connectPath ||
707
+ connectionsQuery.data.connectionsPath ||
708
+ connectionsHref, children: [t("creativeContext.connectProvider"), _jsx(IconArrowUpRight, {})] }) })] })) : connectionsQuery.data?.needsPicker ? (_jsxs("label", { className: "block space-y-1.5 text-xs font-medium", children: [_jsx("span", { children: t("creativeContext.chooseConnection") }), _jsxs(Select, { value: selectedConnectionId, onValueChange: setSelectedConnectionId, children: [_jsx(SelectTrigger, { children: _jsx(SelectValue, { placeholder: t("creativeContext.chooseConnection") }) }), _jsx(SelectContent, { children: connectionsQuery.data.connections.map((connection) => (_jsx(SelectItem, { value: connection.connectionId, children: connection.label }, connection.connectionId))) })] })] })) : null })) : null, recommendationProvider && selectedConnectionId ? (_jsx("div", { className: "mb-3 rounded-md border border-border p-3", children: recommendationsQuery.isLoading ? (_jsx(Skeleton, { className: "h-16 w-full" })) : recommendationsQuery.data?.recommendations.length ? (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center justify-between gap-3 text-xs text-muted-foreground", children: [_jsx("span", { children: t("creativeContext.discoveredItems", {
709
+ count: formatNumber(recommendationsQuery.data.recommendations
710
+ .length),
711
+ }) }), _jsx("span", { children: t("creativeContext.selectedItems", {
712
+ count: formatNumber(selectedRecommendationIds.size),
713
+ }) })] }), _jsx("div", { className: "max-h-52 divide-y divide-border/60 overflow-y-auto", children: recommendationsQuery.data.recommendations.map((recommendation) => (_jsxs("label", { className: "flex cursor-pointer items-start gap-3 py-2", children: [_jsx(Checkbox, { className: "mt-0.5", checked: selectedRecommendationIds.has(recommendation.externalId), onCheckedChange: (checked) => setSelectedRecommendationIds((current) => {
714
+ const next = new Set(current);
715
+ if (checked) {
716
+ next.add(recommendation.externalId);
717
+ }
718
+ else {
719
+ next.delete(recommendation.externalId);
720
+ }
721
+ return next;
722
+ }) }), _jsxs("span", { className: "min-w-0", children: [_jsx("span", { className: "block truncate text-sm", children: recommendation.title }), _jsx("span", { className: "block text-xs text-muted-foreground", children: recommendation.containerRef ??
723
+ recommendation.kind })] })] }, recommendation.externalId))) })] })) : (_jsx("p", { className: "text-xs text-muted-foreground", children: recommendationsQuery.data?.unavailableReason ??
724
+ t("creativeContext.unavailable") })) })) : null, _jsxs("div", { className: "grid gap-3 sm:grid-cols-2", children: [_jsxs("label", { className: "space-y-1.5 text-xs font-medium", children: [_jsx("span", { children: t("creativeContext.sourceName") }), _jsx(Input, { value: sourceName, onChange: (event) => setSourceName(event.target.value), required: true })] }), selectedConnector.kind === "upload" ? (_jsxs("div", { className: "space-y-1.5 text-xs font-medium", children: [_jsx("span", { children: t("creativeContext.sourceReference") }), _jsx("input", { ref: fileInputRef, type: "file", multiple: true, accept: ".pptx,.docx,.pdf,.png,.jpg,.jpeg,.webp,.gif,.svg,application/pdf,application/vnd.openxmlformats-officedocument.presentationml.presentation,application/vnd.openxmlformats-officedocument.wordprocessingml.document,image/png,image/jpeg,image/webp,image/gif,image/svg+xml", className: "hidden", onChange: chooseFiles }), _jsx("input", { ref: folderInputRef, type: "file", multiple: true, className: "hidden", onChange: chooseFiles, ...{ webkitdirectory: "", directory: "" } }), _jsxs("div", { onDragOver: (event) => event.preventDefault(), onDrop: dropFiles, className: "rounded-md border border-dashed border-border p-4", children: [_jsx("p", { className: "text-xs text-muted-foreground", children: t("creativeContext.dropFiles") }), _jsxs("div", { className: "mt-3 flex flex-wrap gap-2", children: [_jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => fileInputRef.current?.click(), children: t("creativeContext.chooseFiles") }), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => folderInputRef.current?.click(), children: t("creativeContext.chooseFolder") })] }), uploadedFiles.length ? (_jsx("ul", { className: "mt-3 space-y-1 text-xs text-muted-foreground", children: uploadedFiles.map((file) => (_jsx("li", { className: "truncate", children: file.fileName }, file.id))) })) : null] })] })) : (_jsxs("label", { className: "space-y-1.5 text-xs font-medium", children: [_jsx("span", { children: t("creativeContext.sourceReference") }), selectedConnector.kind === "website" ||
725
+ selectedConnector.kind === "figma" ||
726
+ selectedConnector.kind === "notion" ? (_jsx(Textarea, { value: sourceReference, onChange: (event) => setSourceReference(event.target.value), placeholder: selectedConnector.referencePlaceholder, required: selectedConnector.referenceRequired, rows: 3 })) : (_jsx(Input, { value: sourceReference, onChange: (event) => setSourceReference(event.target.value), placeholder: selectedConnector.referencePlaceholder, required: selectedConnector.referenceRequired }))] }))] }), _jsxs("div", { className: "mt-3 flex justify-end gap-2", children: [_jsx(Button, { type: "button", variant: "ghost", onClick: () => setConnectorKind(null), children: t("creativeContext.cancel") }), _jsxs(Button, { type: "submit", disabled: manageSource.isPending ||
727
+ uploadResource.isPending ||
728
+ (selectedConnector.kind === "upload" &&
729
+ !uploadedFiles.length) ||
730
+ (Boolean(connectionProvider) && !selectedConnectionId) ||
731
+ (selectedConnector.referenceRequired &&
732
+ !sourceReference.trim()) ||
733
+ (Boolean(recommendationProvider) &&
734
+ !sourceReference.trim() &&
735
+ !selectedRecommendationIds.size), children: [_jsx(IconFileImport, {}), t("creativeContext.preview")] })] })] })) : null, previewSourceId ? (_jsxs("div", { className: "mt-4 rounded-md border border-border p-4", children: [_jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-sm font-semibold", children: previewSourceName }), previewQuery.isLoading ? (_jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: t("creativeContext.loading") })) : (_jsxs("div", { className: "mt-1 flex flex-wrap gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [_jsx("span", { children: t("creativeContext.discoveredItems", {
736
+ count: formatNumber(previewQuery.data?.total ??
737
+ previewQuery.data?.items.length ??
738
+ 0),
739
+ }) }), _jsx("span", { children: t("creativeContext.selectedItems", {
740
+ count: formatNumber(selectedPreviewItemIds.size),
741
+ }) })] }))] }), _jsxs(Button, { type: "button", disabled: previewQuery.isLoading ||
742
+ !previewQuery.data?.items.length ||
743
+ !selectedPreviewItemIds.size ||
744
+ startImport.isPending ||
745
+ importJob?.status === "queued" ||
746
+ importJob?.status === "running", onClick: () => void beginImport(), children: [_jsx(IconFileImport, {}), startImport.isPending
747
+ ? t("creativeContext.importing")
748
+ : t("creativeContext.startImport")] })] }), previewQuery.data?.items.length ? (_jsxs("div", { className: "mt-3", children: [_jsxs("div", { className: "flex items-center gap-2 border-y border-border/60 py-2", children: [_jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setSelectedPreviewItemIds(new Set(previewQuery.data?.items.map((item) => item.externalId) ?? [])), children: t("creativeContext.selectAll") }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setSelectedPreviewItemIds(new Set()), children: t("creativeContext.clearSelection") })] }), _jsx("div", { className: "max-h-80 divide-y divide-border/60 overflow-y-auto", children: previewQuery.data.items.map((item) => (_jsxs("label", { className: "flex cursor-pointer items-start gap-3 py-2", children: [_jsx(Checkbox, { className: "mt-0.5", checked: selectedPreviewItemIds.has(item.externalId), onCheckedChange: (checked) => setSelectedPreviewItemIds((current) => {
749
+ const next = new Set(current);
750
+ if (checked)
751
+ next.add(item.externalId);
752
+ else
753
+ next.delete(item.externalId);
754
+ return next;
755
+ }) }), _jsxs("span", { className: "min-w-0", children: [_jsx("span", { className: "block truncate text-sm", children: item.title }), _jsx("span", { className: "block text-xs text-muted-foreground", children: item.kind })] })] }, item.externalId))) })] })) : null] })) : null, importJob ? (_jsxs("div", { className: "mt-4 rounded-md border border-border p-4", children: [_jsxs("div", { className: "flex items-center gap-2", children: [importJob.status === "completed" ? (_jsx(IconCheck, { className: "size-5 text-emerald-600" })) : importJob.status === "failed" ? (_jsx(IconAlertTriangle, { className: "size-5 text-destructive" })) : (_jsx(IconRefresh, { className: "size-5 animate-spin text-muted-foreground" })), _jsx("h3", { className: "text-sm font-semibold", children: importJob.status === "completed"
756
+ ? t("creativeContext.importComplete")
757
+ : importJob.status === "failed"
758
+ ? t("creativeContext.importFailed")
759
+ : t("creativeContext.importing") })] }), importJob.status === "completed" && brandProposal ? (_jsx("div", { className: "mt-4 rounded-md bg-muted/50 p-4", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx(IconSparkles, { className: "mt-0.5 size-5 text-muted-foreground" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("h4", { className: "text-sm font-semibold", children: t("creativeContext.brandDnaTitle") }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: brandProposal.summary }), brandProposal.colors.length ? (_jsxs("div", { className: "mt-4", children: [_jsx("p", { className: "text-xs font-medium", children: t("creativeContext.colors") }), _jsx("div", { className: "mt-2 flex flex-wrap gap-2", children: brandProposal.colors.map((color) => (_jsxs("div", { className: "flex items-center gap-1.5 rounded border border-border bg-background px-2 py-1 text-xs", children: [_jsx("span", { className: "size-4 rounded-sm border border-black/10", style: { backgroundColor: color } }), color] }, color))) })] })) : null, brandProposal.fonts.length ? (_jsxs("div", { className: "mt-4", children: [_jsx("p", { className: "text-xs font-medium", children: t("creativeContext.fonts") }), _jsx("div", { className: "mt-2 flex flex-wrap gap-2", children: brandProposal.fonts.map((font) => (_jsx(Badge, { variant: "outline", children: font }, font))) })] })) : null, brandLayoutThumbnails.length ? (_jsxs("div", { className: "mt-4", children: [_jsx("p", { className: "text-xs font-medium", children: t("creativeContext.layouts") }), _jsx("div", { className: "mt-2 grid grid-cols-3 gap-2", children: brandLayoutThumbnails.map((thumbnail) => (_jsx(AccessScopedThumbnail, { itemId: thumbnail.itemId, itemVersionId: thumbnail.itemVersionId, className: "aspect-video w-full rounded border border-border object-cover" }, thumbnail.itemVersionId))) })] })) : null, brandVoicePreview ? (_jsxs("div", { className: "mt-4", children: [_jsx("p", { className: "text-xs font-medium", children: t("creativeContext.voice") }), _jsx("blockquote", { className: "mt-1 border-s-2 border-border ps-3 text-sm text-muted-foreground", children: brandVoicePreview })] })) : null, _jsxs("div", { className: "mt-4 flex flex-wrap gap-2", children: [_jsxs(Button, { type: "button", disabled: publishBrandDna.isPending, onClick: () => void publishProposal(), children: [_jsx(IconSparkles, {}), publishBrandDna.isPending
760
+ ? t("creativeContext.applyingBrandContext")
761
+ : t("creativeContext.applyBrandContext")] }), _jsx(Button, { asChild: true, type: "button", variant: "outline", children: _jsxs("a", { href: "/agent", children: [t("creativeContext.generateWithContext"), _jsx(IconArrowUpRight, {})] }) })] }), publishedMessage ? (_jsx("p", { className: "mt-2 text-xs text-muted-foreground", children: publishedMessage })) : null] })] }) })) : importJob.error ? (_jsx("p", { className: "mt-2 text-sm text-destructive", children: importJob.error })) : (_jsxs("p", { className: "mt-2 text-xs text-muted-foreground", children: [formatNumber(importJob.progressCurrent), " /", " ", formatNumber(importJob.progressTotal ?? 0)] }))] })) : null, promotionPreview ? (_jsxs("div", { className: "mt-4 rounded-md border border-border p-4", children: [_jsx("h3", { className: "text-sm font-semibold", children: t("creativeContext.promoteToOrganization") }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: t("creativeContext.promotionDescription") }), _jsxs("dl", { className: "mt-3 grid gap-2 text-xs sm:grid-cols-3", children: [_jsxs("div", { children: [_jsx("dt", { className: "text-muted-foreground", children: t("creativeContext.sourceReference") }), _jsx("dd", { className: "mt-0.5 truncate font-medium", children: promotionPreview.containerRef })] }), _jsxs("div", { children: [_jsx("dt", { className: "text-muted-foreground", children: t("creativeContext.itemsLabel", { count: "" }) }), _jsx("dd", { className: "mt-0.5 font-medium", children: formatNumber(promotionPreview.itemCount) })] }), _jsxs("div", { children: [_jsx("dt", { className: "text-muted-foreground", children: t("creativeContext.restrictedItems", { count: "" }) }), _jsx("dd", { className: "mt-0.5 font-medium", children: formatNumber(promotionPreview.restrictedItemCount) })] })] }), _jsx(Button, { type: "button", className: "mt-4", disabled: manageSource.isPending, onClick: () => void confirmPromotion(), children: t("creativeContext.promoteToOrganization") })] })) : null, promotionMessage ? (_jsx("p", { className: "mt-2 text-xs text-muted-foreground", children: promotionMessage })) : null, setupError ? (_jsx("p", { className: "mt-2 text-sm text-destructive", children: setupError })) : null] }), _jsxs("section", { className: "border-t border-border/70 pt-6", children: [_jsx("h2", { className: "text-lg font-semibold", children: t("creativeContext.sourcesTitle") }), sources.length ? (_jsx("div", { className: "mt-3", children: sources.map((source) => (_jsx(SourceRow, { source: source, refreshing: refreshSource.isPending &&
762
+ refreshSource.variables?.sourceId === source.id, canReview: canManageScope, canPromote: libraryScope === "user" &&
763
+ Boolean(org?.orgId) &&
764
+ canManageOrg &&
765
+ source.visibility === "private", onRefresh: refresh, onReview: (selected) => void openItemCuration(selected, "restricted"), onCurate: (selected) => void openItemCuration(selected), onPromote: (selected) => void previewSourcePromotion(selected), onPause: (selected) => void pauseSource(selected), onRestore: (selected) => void restoreSource(selected), onDelete: setDeleteSource }, source.id))) })) : (_jsxs("div", { className: "mt-4 rounded-md border border-dashed border-border p-6 text-center", children: [_jsx(IconBooks, { className: "mx-auto size-7 text-muted-foreground" }), _jsx("h3", { className: "mt-3 text-sm font-semibold", children: t("creativeContext.noSourcesTitle") }), _jsx("p", { className: "mx-auto mt-1 max-w-md text-sm text-muted-foreground", children: t("creativeContext.noSourcesDescription") }), _jsx(Button, { asChild: true, variant: "outline", size: "sm", className: "mt-4", children: _jsxs("a", { href: connectionsHref, children: [t("creativeContext.connectSources"), _jsx(IconArrowUpRight, {})] }) })] })), reviewSource ? (_jsx(ItemCuration, { source: reviewSource, items: reviewedItems, busy: reviewItems.isPending, onReview: (operation, itemId) => void reviewContextItem(operation, itemId), onClose: () => {
766
+ setReviewSource(null);
767
+ setReviewedItems([]);
768
+ } })) : null, reviewError ? (_jsx("p", { className: "mt-2 text-sm text-destructive", children: reviewError })) : null, refreshMessage ? (_jsx("p", { className: "mt-2 text-xs text-muted-foreground", children: refreshMessage })) : null, lifecycleMessage ? (_jsx("p", { className: "mt-2 text-xs text-muted-foreground", children: lifecycleMessage })) : null] }), _jsxs("section", { className: "border-t border-border/70 pt-6", children: [_jsx("h2", { className: "text-lg font-semibold", children: t("creativeContext.packsTitle") }), packs.length ? (_jsx("div", { className: "mt-3", children: packs.map((pack) => (_jsx(PackRow, { pack: pack, pinned: contextState.state.pinnedPackId === pack.id, disabled: savingState, onPin: (packId) => void changePinnedPack(packId), onDetails: setSelectedPackId }, pack.id))) })) : (_jsx("p", { className: "mt-3 rounded-md border border-dashed border-border p-5 text-sm text-muted-foreground", children: t("creativeContext.noPacks") })), selectedPackId ? (_jsxs("div", { className: "mt-4 rounded-md border border-border p-4", children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { children: [_jsx("h3", { className: "text-sm font-semibold", children: packQuery.data?.pack?.name ??
769
+ t("creativeContext.packDetails") }), packQuery.data?.pack?.derivedFromPackId ? (_jsxs("p", { className: "mt-1 text-xs text-muted-foreground", children: [t("creativeContext.influence"), ":", " ", packQuery.data.pack.derivedFromPackId] })) : null] }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setSelectedPackId(null), children: t("creativeContext.cancel") })] }), packQuery.data?.pack?.members.length ? (_jsx("div", { className: "mt-3 divide-y divide-border/60", children: packQuery.data.pack.members.map((member) => (_jsxs("div", { className: "py-2 text-xs", children: [_jsx("p", { className: "font-medium", children: member.itemId }), member.reason ? (_jsxs("p", { className: "mt-0.5 text-muted-foreground", children: [t("creativeContext.influence"), ": ", member.reason] })) : null] }, member.id))) })) : null] })) : null] }), _jsxs("section", { className: "border-t border-border/70 pt-6", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-lg font-semibold", children: t("creativeContext.searchTitle") }), _jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: t("creativeContext.searchDescription") })] }), _jsxs("form", { className: "mt-4 flex gap-2", onSubmit: (event) => void search(event), children: [_jsxs("div", { className: "relative min-w-0 flex-1", children: [_jsx(IconSearch, { className: "pointer-events-none absolute start-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" }), _jsx(Input, { type: "search", value: query, onChange: (event) => setQuery(event.target.value), placeholder: t("creativeContext.searchPlaceholder"), "aria-label": t("creativeContext.searchPlaceholder"), className: "ps-9" })] }), _jsxs(Button, { type: "submit", variant: "outline", disabled: !query.trim() || !sources.length || searchContext.isPending, children: [_jsx(IconSearch, {}), t("creativeContext.searchTitle")] })] }), searchError ? (_jsx("p", { className: "mt-4 text-sm text-destructive", children: searchError })) : !searchContext.data && !searchContext.isPending ? (_jsx("p", { className: "mt-4 text-sm text-muted-foreground", children: t("creativeContext.searchPrompt") })) : searchContext.isPending ? (_jsxs("div", { className: "mt-4 space-y-2", children: [_jsx(Skeleton, { className: "h-20 w-full" }), _jsx(Skeleton, { className: "h-20 w-full" })] })) : searchContext.data?.results.length ? (_jsxs("div", { className: "mt-4 space-y-2", children: [_jsx("p", { className: "text-xs text-muted-foreground", children: t("creativeContext.resultsLabel", {
770
+ count: formatNumber(searchContext.data.results.length),
771
+ }) }), searchContext.data.results.map((result) => (_jsxs("article", { className: "rounded-md border border-border/70 p-3", children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("h3", { className: "truncate text-sm font-medium", children: result.title }), _jsxs("p", { className: "mt-0.5 text-xs text-muted-foreground", children: [result.sourceName, " \u00B7 ", result.kind] })] }), result.canonicalUrl ? (_jsx(Button, { asChild: true, variant: "ghost", size: "icon", children: _jsx("a", { href: result.canonicalUrl, target: "_blank", rel: "noreferrer", "aria-label": result.title, children: _jsx(IconArrowUpRight, {}) }) })) : null] }), _jsx("p", { className: "mt-2 line-clamp-3 text-sm leading-relaxed text-muted-foreground", children: result.excerpt })] }, `${result.itemVersionId}:${result.chunkId ?? "item"}`)))] })) : (_jsx("p", { className: "mt-4 text-sm text-muted-foreground", children: t("creativeContext.noResults") }))] })] })), _jsx(AlertDialog, { open: Boolean(deleteSource), onOpenChange: (open) => {
772
+ if (!open)
773
+ setDeleteSource(null);
774
+ }, children: _jsxs(AlertDialogContent, { children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { children: t("creativeContext.deleteSourceTitle") }), _jsx(AlertDialogDescription, { children: t("creativeContext.deleteSourceDescription", {
775
+ name: deleteSource?.name ?? "",
776
+ }) })] }), _jsxs(AlertDialogFooter, { children: [_jsx(AlertDialogCancel, { children: t("creativeContext.cancel") }), _jsx(AlertDialogAction, { className: "bg-destructive text-destructive-foreground hover:bg-destructive/90", onClick: () => void confirmDeleteSource(), children: t("creativeContext.delete") })] })] }) })] }));
777
+ }
778
+ //# sourceMappingURL=CreativeContextPanel.js.map