@agent-native/creative-context 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/README.md +51 -9
  2. package/agent-native.package.json +4 -0
  3. package/dist/actions/index.d.ts.map +1 -1
  4. package/dist/actions/index.js +8 -0
  5. package/dist/actions/index.js.map +1 -1
  6. package/dist/actions/list-context-memberships.d.ts +11 -0
  7. package/dist/actions/list-context-memberships.d.ts.map +1 -0
  8. package/dist/actions/list-context-memberships.js +47 -0
  9. package/dist/actions/list-context-memberships.js.map +1 -0
  10. package/dist/actions/list-creative-contexts.d.ts +12 -0
  11. package/dist/actions/list-creative-contexts.d.ts.map +1 -0
  12. package/dist/actions/list-creative-contexts.js +28 -0
  13. package/dist/actions/list-creative-contexts.js.map +1 -0
  14. package/dist/actions/manage-context-membership.d.ts +64 -0
  15. package/dist/actions/manage-context-membership.d.ts.map +1 -0
  16. package/dist/actions/manage-context-membership.js +70 -0
  17. package/dist/actions/manage-context-membership.js.map +1 -0
  18. package/dist/actions/manage-context-pack.d.ts +3 -0
  19. package/dist/actions/manage-context-pack.js +6 -0
  20. package/dist/actions/manage-context-pack.js.map +1 -1
  21. package/dist/actions/manage-context-source.js +4 -11
  22. package/dist/actions/manage-context-source.js.map +1 -1
  23. package/dist/actions/manage-creative-context.d.ts +28 -0
  24. package/dist/actions/manage-creative-context.d.ts.map +1 -0
  25. package/dist/actions/manage-creative-context.js +65 -0
  26. package/dist/actions/manage-creative-context.js.map +1 -0
  27. package/dist/actions/process-context-purge.d.ts +16 -1
  28. package/dist/actions/process-context-purge.js +2 -1
  29. package/dist/actions/process-context-purge.js.map +1 -1
  30. package/dist/actions/search-creative-context.d.ts +1 -0
  31. package/dist/actions/search-creative-context.js +2 -1
  32. package/dist/actions/search-creative-context.js.map +1 -1
  33. package/dist/client/CreativeContextChip.d.ts +7 -2
  34. package/dist/client/CreativeContextChip.d.ts.map +1 -1
  35. package/dist/client/CreativeContextChip.js +42 -7
  36. package/dist/client/CreativeContextChip.js.map +1 -1
  37. package/dist/client/CreativeContextPanel.d.ts.map +1 -1
  38. package/dist/client/CreativeContextPanel.js +406 -89
  39. package/dist/client/CreativeContextPanel.js.map +1 -1
  40. package/dist/client/CreativeContextShareTab.d.ts +56 -0
  41. package/dist/client/CreativeContextShareTab.d.ts.map +1 -0
  42. package/dist/client/CreativeContextShareTab.js +213 -0
  43. package/dist/client/CreativeContextShareTab.js.map +1 -0
  44. package/dist/client/actions.d.ts +210 -0
  45. package/dist/client/actions.d.ts.map +1 -1
  46. package/dist/client/actions.js +318 -0
  47. package/dist/client/actions.js.map +1 -1
  48. package/dist/client/application-state.d.ts +2 -0
  49. package/dist/client/application-state.d.ts.map +1 -1
  50. package/dist/client/application-state.js +25 -2
  51. package/dist/client/application-state.js.map +1 -1
  52. package/dist/client/index.d.ts +4 -3
  53. package/dist/client/index.d.ts.map +1 -1
  54. package/dist/client/index.js +4 -3
  55. package/dist/client/index.js.map +1 -1
  56. package/dist/client/messages.d.ts +1 -1
  57. package/dist/client/messages.d.ts.map +1 -1
  58. package/dist/client/messages.js +77 -0
  59. package/dist/client/messages.js.map +1 -1
  60. package/dist/connectors/types.d.ts +2 -2
  61. package/dist/connectors/types.d.ts.map +1 -1
  62. package/dist/schema/index.d.ts +1592 -0
  63. package/dist/schema/index.d.ts.map +1 -1
  64. package/dist/schema/index.js +95 -0
  65. package/dist/schema/index.js.map +1 -1
  66. package/dist/schema/migrations.d.ts.map +1 -1
  67. package/dist/schema/migrations.js +80 -0
  68. package/dist/schema/migrations.js.map +1 -1
  69. package/dist/server/generation-artifact-access.js +2 -0
  70. package/dist/server/generation-artifact-access.js.map +1 -1
  71. package/dist/server/generation-context.d.ts +12 -4
  72. package/dist/server/generation-context.d.ts.map +1 -1
  73. package/dist/server/generation-context.js +129 -7
  74. package/dist/server/generation-context.js.map +1 -1
  75. package/dist/server/index.d.ts +4 -0
  76. package/dist/server/index.d.ts.map +1 -1
  77. package/dist/server/index.js +16 -0
  78. package/dist/server/index.js.map +1 -1
  79. package/dist/server/isolated-a2a.d.ts +3 -0
  80. package/dist/server/isolated-a2a.d.ts.map +1 -1
  81. package/dist/server/isolated-a2a.js +3 -1
  82. package/dist/server/isolated-a2a.js.map +1 -1
  83. package/dist/server/media.d.ts +1 -1
  84. package/dist/server/media.d.ts.map +1 -1
  85. package/dist/server/media.js +24 -9
  86. package/dist/server/media.js.map +1 -1
  87. package/dist/server/native-resource-capture.d.ts +78 -0
  88. package/dist/server/native-resource-capture.d.ts.map +1 -0
  89. package/dist/server/native-resource-capture.js +94 -0
  90. package/dist/server/native-resource-capture.js.map +1 -0
  91. package/dist/server/public-serialization.js +1 -1
  92. package/dist/server/public-serialization.js.map +1 -1
  93. package/dist/server/retrieval.d.ts +1 -0
  94. package/dist/server/retrieval.d.ts.map +1 -1
  95. package/dist/server/retrieval.js +2 -0
  96. package/dist/server/retrieval.js.map +1 -1
  97. package/dist/server/safe-native-preview.d.ts +15 -0
  98. package/dist/server/safe-native-preview.d.ts.map +1 -0
  99. package/dist/server/safe-native-preview.js +149 -0
  100. package/dist/server/safe-native-preview.js.map +1 -0
  101. package/dist/store/brand.d.ts.map +1 -1
  102. package/dist/store/brand.js +2 -16
  103. package/dist/store/brand.js.map +1 -1
  104. package/dist/store/content.d.ts +1 -0
  105. package/dist/store/content.d.ts.map +1 -1
  106. package/dist/store/content.js +84 -20
  107. package/dist/store/content.js.map +1 -1
  108. package/dist/store/contexts.d.ts +216 -0
  109. package/dist/store/contexts.d.ts.map +1 -0
  110. package/dist/store/contexts.js +1341 -0
  111. package/dist/store/contexts.js.map +1 -0
  112. package/dist/store/index.d.ts +1 -0
  113. package/dist/store/index.d.ts.map +1 -1
  114. package/dist/store/index.js +1 -0
  115. package/dist/store/index.js.map +1 -1
  116. package/dist/store/packs.d.ts +3 -0
  117. package/dist/store/packs.d.ts.map +1 -1
  118. package/dist/store/packs.js +126 -9
  119. package/dist/store/packs.js.map +1 -1
  120. package/dist/store/purge.d.ts.map +1 -1
  121. package/dist/store/purge.js +103 -6
  122. package/dist/store/purge.js.map +1 -1
  123. package/dist/store/sources.d.ts.map +1 -1
  124. package/dist/store/sources.js +2 -15
  125. package/dist/store/sources.js.map +1 -1
  126. package/dist/store/suggestions.d.ts.map +1 -1
  127. package/dist/store/suggestions.js +3 -1
  128. package/dist/store/suggestions.js.map +1 -1
  129. package/dist/types.d.ts +77 -0
  130. package/dist/types.d.ts.map +1 -1
  131. package/dist/types.js +9 -1
  132. package/dist/types.js.map +1 -1
  133. package/docs/skills/creative-context/SKILL.md +13 -5
  134. package/package.json +2 -2
  135. package/src/actions/index.ts +8 -0
  136. package/src/actions/job-public-serialization.spec.ts +21 -0
  137. package/src/actions/list-context-memberships.ts +56 -0
  138. package/src/actions/list-creative-contexts.spec.ts +38 -0
  139. package/src/actions/list-creative-contexts.ts +32 -0
  140. package/src/actions/manage-context-membership.ts +80 -0
  141. package/src/actions/manage-context-pack.ts +6 -0
  142. package/src/actions/manage-context-source.ts +8 -11
  143. package/src/actions/manage-creative-context.ts +73 -0
  144. package/src/actions/process-context-purge.ts +4 -1
  145. package/src/actions/search-creative-context.ts +2 -1
  146. package/src/client/CreativeContextChip.spec.ts +59 -0
  147. package/src/client/CreativeContextChip.tsx +95 -14
  148. package/src/client/CreativeContextPanel.tsx +1947 -885
  149. package/src/client/CreativeContextShareTab.spec.ts +70 -0
  150. package/src/client/CreativeContextShareTab.tsx +657 -0
  151. package/src/client/actions.spec.ts +177 -0
  152. package/src/client/actions.ts +566 -0
  153. package/src/client/application-state.spec.ts +5 -0
  154. package/src/client/application-state.ts +30 -2
  155. package/src/client/index.ts +33 -0
  156. package/src/client/messages.ts +95 -0
  157. package/src/connectors/types.ts +6 -8
  158. package/src/eval/library-flow.acceptance.spec.tsx +1 -0
  159. package/src/schema/index.ts +116 -0
  160. package/src/schema/migrations.ts +80 -0
  161. package/src/server/generation-artifact-access.ts +1 -0
  162. package/src/server/generation-context-a2a.spec.ts +133 -0
  163. package/src/server/generation-context.ts +153 -7
  164. package/src/server/index.spec.ts +15 -0
  165. package/src/server/index.ts +16 -0
  166. package/src/server/isolated-a2a.ts +4 -1
  167. package/src/server/media.spec.ts +30 -2
  168. package/src/server/media.ts +31 -12
  169. package/src/server/native-resource-capture.spec.ts +121 -0
  170. package/src/server/native-resource-capture.ts +198 -0
  171. package/src/server/public-serialization.spec.ts +1 -0
  172. package/src/server/public-serialization.ts +1 -1
  173. package/src/server/retrieval.ts +3 -0
  174. package/src/server/safe-native-preview.spec.ts +29 -0
  175. package/src/server/safe-native-preview.ts +200 -0
  176. package/src/store/access.integration.spec.ts +1116 -0
  177. package/src/store/brand.ts +2 -21
  178. package/src/store/content.ts +217 -17
  179. package/src/store/contexts.ts +1826 -0
  180. package/src/store/index.ts +1 -0
  181. package/src/store/packs.ts +279 -24
  182. package/src/store/purge.ts +139 -6
  183. package/src/store/sources.ts +2 -18
  184. package/src/store/suggestions.ts +3 -1
  185. package/src/types.ts +95 -0
@@ -1,8 +1,8 @@
1
- import { getDbExec } from "@agent-native/core/db";
2
1
  import {
3
2
  resourcePut,
4
3
  sharedResourceOwner,
5
4
  } from "@agent-native/core/resources/store";
5
+ import { currentRequestUserIsOrgAdmin } from "@agent-native/core/server";
6
6
  import {
7
7
  accessFilter,
8
8
  assertAccess,
@@ -202,22 +202,6 @@ async function projectPublishedBrandContext(
202
202
  );
203
203
  }
204
204
 
205
- async function currentActorIsOrgAdmin(
206
- orgId: string,
207
- ownerEmail: string,
208
- ): Promise<boolean> {
209
- try {
210
- const result = await getDbExec().execute({
211
- sql: "SELECT role FROM org_members WHERE org_id = ? AND LOWER(email) = ? LIMIT 1",
212
- args: [orgId, ownerEmail.toLowerCase()],
213
- });
214
- const role = String(result.rows[0]?.role ?? "").toLowerCase();
215
- return role === "owner" || role === "admin";
216
- } catch {
217
- return false;
218
- }
219
- }
220
-
221
205
  export async function previewBrandProfilePromotion(profileId: string) {
222
206
  const access = await assertAccess(
223
207
  "creative-context-brand",
@@ -225,10 +209,7 @@ export async function previewBrandProfilePromotion(profileId: string) {
225
209
  "admin",
226
210
  );
227
211
  const actor = requireActor();
228
- if (
229
- !actor.orgId ||
230
- !(await currentActorIsOrgAdmin(actor.orgId, actor.ownerEmail))
231
- ) {
212
+ if (!actor.orgId || !(await currentRequestUserIsOrgAdmin(actor.orgId))) {
232
213
  throw new Error(
233
214
  "Brand profile promotion requires an active organization owner or admin.",
234
215
  );
@@ -1,4 +1,3 @@
1
- import { getDbExec } from "@agent-native/core/db";
2
1
  import {
3
2
  buildSearchSnippet,
4
3
  escapeLikeTerm,
@@ -6,6 +5,7 @@ import {
6
5
  scoreSearchText,
7
6
  type SearchMatchMode,
8
7
  } from "@agent-native/core/search-utils";
8
+ import { currentRequestUserIsOrgAdmin } from "@agent-native/core/server";
9
9
  import { accessFilter, assertAccess } from "@agent-native/core/sharing";
10
10
  import {
11
11
  and,
@@ -16,6 +16,7 @@ import {
16
16
  gt,
17
17
  gte,
18
18
  inArray,
19
+ isNotNull,
19
20
  lte,
20
21
  ne,
21
22
  or,
@@ -934,6 +935,7 @@ export interface AccessibleLexicalCandidatesInput {
934
935
  query: string;
935
936
  sourceIds?: string[];
936
937
  packId?: string;
938
+ contextId?: string;
937
939
  kinds?: string[];
938
940
  tags?: string[];
939
941
  colors?: string[];
@@ -971,6 +973,68 @@ async function accessiblePackVersionIds(packId: string): Promise<string[]> {
971
973
  return members.map((member: any) => member.itemVersionId);
972
974
  }
973
975
 
976
+ async function accessibleContextVersionIds(
977
+ contextId: string,
978
+ ): Promise<string[]> {
979
+ await assertAccess("creative-context", contextId, "viewer", undefined, {
980
+ skipResourceBody: true,
981
+ });
982
+ const { getDb, schema } = getCreativeContext();
983
+ const rows = await getDb()
984
+ .select({
985
+ itemVersionId: schema.creativeContextMemberships.publishedItemVersionId,
986
+ })
987
+ .from(schema.creativeContextMemberships)
988
+ .where(
989
+ and(
990
+ eq(schema.creativeContextMemberships.contextId, contextId),
991
+ eq(schema.creativeContextMemberships.status, "active"),
992
+ ),
993
+ );
994
+ return rows.flatMap((row: any) =>
995
+ typeof row.itemVersionId === "string" ? [row.itemVersionId] : [],
996
+ );
997
+ }
998
+
999
+ async function accessibleContextMembershipMetadata(
1000
+ contextId: string,
1001
+ ): Promise<
1002
+ Map<
1003
+ string,
1004
+ { rank: "canonical" | "exemplar" | "normal"; purpose: string | null }
1005
+ >
1006
+ > {
1007
+ await assertAccess("creative-context", contextId, "viewer", undefined, {
1008
+ skipResourceBody: true,
1009
+ });
1010
+ const { getDb, schema } = getCreativeContext();
1011
+ const rows = await getDb()
1012
+ .select({
1013
+ itemVersionId: schema.creativeContextMemberships.publishedItemVersionId,
1014
+ rank: schema.creativeContextMemberships.rank,
1015
+ purpose: schema.creativeContextMemberships.purpose,
1016
+ })
1017
+ .from(schema.creativeContextMemberships)
1018
+ .where(
1019
+ and(
1020
+ eq(schema.creativeContextMemberships.contextId, contextId),
1021
+ eq(schema.creativeContextMemberships.status, "active"),
1022
+ ),
1023
+ );
1024
+ return new Map(
1025
+ (rows as any[]).flatMap((row) =>
1026
+ typeof row.itemVersionId === "string"
1027
+ ? [
1028
+ [
1029
+ row.itemVersionId,
1030
+ { rank: row.rank, purpose: row.purpose ?? null },
1031
+ ] as const,
1032
+ ]
1033
+ : [],
1034
+ ),
1035
+ );
1036
+ }
1037
+
974
1038
  export interface AccessibleSearchDocument extends ContextSearchResult {
975
1039
  body: string;
976
1040
  summary: string | null;
@@ -997,11 +1061,33 @@ export async function listAccessibleSearchDocuments(
997
1061
  const packVersionIds: string[] | null = input.packId
998
1062
  ? await accessiblePackVersionIds(input.packId)
999
1063
  : null;
1000
- if (packVersionIds && !packVersionIds.length) return [];
1001
- const filters: any[] = [
1064
+ const contextVersionIds: string[] | null = input.contextId
1065
+ ? await accessibleContextVersionIds(input.contextId)
1066
+ : null;
1067
+ const contextMemberships = input.contextId
1068
+ ? await accessibleContextMembershipMetadata(input.contextId)
1069
+ : null;
1070
+ if (
1071
+ (packVersionIds && !packVersionIds.length) ||
1072
+ (contextVersionIds && !contextVersionIds.length)
1073
+ )
1074
+ return [];
1075
+ const sourceAccess = and(
1002
1076
  accessFilter(schema.contextSources, schema.contextSourceShares),
1003
1077
  ne(schema.contextSources.upstreamAccess, "restricted"),
1004
1078
  ne(schema.contextSources.status, "archived"),
1079
+ );
1080
+ const filters: any[] = [
1081
+ ...(input.contextId
1082
+ ? [inArray(schema.contextChunks.itemVersionId, contextVersionIds!)]
1083
+ : input.packId
1084
+ ? [
1085
+ or(
1086
+ sourceAccess,
1087
+ isNotNull(schema.creativeContextPublishedSnapshots.id),
1088
+ ),
1089
+ ]
1090
+ : [sourceAccess]),
1005
1091
  ...(packVersionIds
1006
1092
  ? [inArray(schema.contextChunks.itemVersionId, packVersionIds)]
1007
1093
  : [
@@ -1072,6 +1158,23 @@ export async function listAccessibleSearchDocuments(
1072
1158
  schema.contextItemVersions,
1073
1159
  eq(schema.contextItemVersions.id, schema.contextChunks.itemVersionId),
1074
1160
  )
1161
+ .leftJoin(
1162
+ schema.creativeContextPublishedSnapshots,
1163
+ and(
1164
+ eq(
1165
+ schema.creativeContextPublishedSnapshots.itemId,
1166
+ schema.contextItems.id,
1167
+ ),
1168
+ eq(
1169
+ schema.creativeContextPublishedSnapshots.itemVersionId,
1170
+ schema.contextChunks.itemVersionId,
1171
+ ),
1172
+ eq(
1173
+ schema.creativeContextPublishedSnapshots.sourceId,
1174
+ schema.contextItems.sourceId,
1175
+ ),
1176
+ ),
1177
+ )
1075
1178
  .where(
1076
1179
  and(
1077
1180
  ...filters,
@@ -1111,7 +1214,8 @@ export async function listAccessibleSearchDocuments(
1111
1214
  tags: row.tags,
1112
1215
  colors: row.colors,
1113
1216
  updatedAt: row.updatedAt,
1114
- curationRank: row.curationRank,
1217
+ curationRank:
1218
+ contextMemberships?.get(row.itemVersionId)?.rank ?? row.curationRank,
1115
1219
  starred: Boolean(row.starred),
1116
1220
  indexState: row.indexState,
1117
1221
  inventoryOnly: row.parseStatus === "pending",
@@ -1183,7 +1287,17 @@ export async function listAccessibleLexicalCandidates(
1183
1287
  const packVersionIds: string[] | null = input.packId
1184
1288
  ? await accessiblePackVersionIds(input.packId)
1185
1289
  : null;
1186
- if (packVersionIds && !packVersionIds.length) return { results: [] };
1290
+ const contextVersionIds: string[] | null = input.contextId
1291
+ ? await accessibleContextVersionIds(input.contextId)
1292
+ : null;
1293
+ const contextMemberships = input.contextId
1294
+ ? await accessibleContextMembershipMetadata(input.contextId)
1295
+ : null;
1296
+ if (
1297
+ (packVersionIds && !packVersionIds.length) ||
1298
+ (contextVersionIds && !contextVersionIds.length)
1299
+ )
1300
+ return { results: [] };
1187
1301
  const matchMode = input.matchMode ?? "allTerms";
1188
1302
  const terms = normalizeSearchTerms(input.query);
1189
1303
  if (!terms.length && matchMode !== "regex") return { results: [] };
@@ -1200,10 +1314,22 @@ export async function listAccessibleLexicalCandidates(
1200
1314
  sql`lower(${schema.contextChunks.text}) like ${pattern} escape '\\'`,
1201
1315
  );
1202
1316
  });
1203
- const filters: any[] = [
1317
+ const sourceAccess = and(
1204
1318
  accessFilter(schema.contextSources, schema.contextSourceShares),
1205
1319
  ne(schema.contextSources.upstreamAccess, "restricted"),
1206
1320
  ne(schema.contextSources.status, "archived"),
1321
+ );
1322
+ const filters: any[] = [
1323
+ ...(input.contextId
1324
+ ? [inArray(schema.contextChunks.itemVersionId, contextVersionIds!)]
1325
+ : input.packId
1326
+ ? [
1327
+ or(
1328
+ sourceAccess,
1329
+ isNotNull(schema.creativeContextPublishedSnapshots.id),
1330
+ ),
1331
+ ]
1332
+ : [sourceAccess]),
1207
1333
  ...(packVersionIds
1208
1334
  ? [inArray(schema.contextChunks.itemVersionId, packVersionIds)]
1209
1335
  : [
@@ -1281,6 +1407,23 @@ export async function listAccessibleLexicalCandidates(
1281
1407
  schema.contextItemVersions,
1282
1408
  eq(schema.contextItemVersions.id, schema.contextChunks.itemVersionId),
1283
1409
  )
1410
+ .leftJoin(
1411
+ schema.creativeContextPublishedSnapshots,
1412
+ and(
1413
+ eq(
1414
+ schema.creativeContextPublishedSnapshots.itemId,
1415
+ schema.contextItems.id,
1416
+ ),
1417
+ eq(
1418
+ schema.creativeContextPublishedSnapshots.itemVersionId,
1419
+ schema.contextChunks.itemVersionId,
1420
+ ),
1421
+ eq(
1422
+ schema.creativeContextPublishedSnapshots.sourceId,
1423
+ schema.contextItems.sourceId,
1424
+ ),
1425
+ ),
1426
+ )
1284
1427
  .where(
1285
1428
  and(
1286
1429
  ...filters,
@@ -1324,9 +1467,11 @@ export async function listAccessibleLexicalCandidates(
1324
1467
  ) +
1325
1468
  (row.starred
1326
1469
  ? 2
1327
- : row.curationRank === "canonical"
1470
+ : (contextMemberships?.get(row.itemVersionId)?.rank ??
1471
+ row.curationRank) === "canonical"
1328
1472
  ? 1.5
1329
- : row.curationRank === "exemplar"
1473
+ : (contextMemberships?.get(row.itemVersionId)?.rank ??
1474
+ row.curationRank) === "exemplar"
1330
1475
  ? 1
1331
1476
  : 0),
1332
1477
  canonicalUrl: row.canonicalUrl ?? null,
@@ -1354,6 +1499,8 @@ export async function getCreativeContextItem(
1354
1499
  itemVersionId?: string,
1355
1500
  ): Promise<ContextDetail | null> {
1356
1501
  const { getDb, schema } = getCreativeContext();
1502
+ const requestedVersionId =
1503
+ itemVersionId ?? schema.contextItems.currentVersionId;
1357
1504
  const itemRows = await getDb()
1358
1505
  .select({ item: schema.contextItems })
1359
1506
  .from(schema.contextItems)
@@ -1361,12 +1508,70 @@ export async function getCreativeContextItem(
1361
1508
  schema.contextSources,
1362
1509
  eq(schema.contextSources.id, schema.contextItems.sourceId),
1363
1510
  )
1511
+ .leftJoin(
1512
+ schema.creativeContextMemberships,
1513
+ and(
1514
+ eq(
1515
+ schema.creativeContextMemberships.publishedItemId,
1516
+ schema.contextItems.id,
1517
+ ),
1518
+ eq(
1519
+ schema.creativeContextMemberships.publishedItemVersionId,
1520
+ requestedVersionId,
1521
+ ),
1522
+ eq(schema.creativeContextMemberships.status, "active"),
1523
+ ),
1524
+ )
1525
+ .leftJoin(
1526
+ schema.creativeContexts,
1527
+ eq(
1528
+ schema.creativeContexts.id,
1529
+ schema.creativeContextMemberships.contextId,
1530
+ ),
1531
+ )
1532
+ .leftJoin(
1533
+ schema.contextPackMembers,
1534
+ and(
1535
+ eq(schema.contextPackMembers.itemId, schema.contextItems.id),
1536
+ eq(schema.contextPackMembers.itemVersionId, requestedVersionId),
1537
+ ),
1538
+ )
1539
+ .leftJoin(
1540
+ schema.contextPacks,
1541
+ eq(schema.contextPacks.id, schema.contextPackMembers.packId),
1542
+ )
1543
+ .leftJoin(
1544
+ schema.creativeContextPublishedSnapshots,
1545
+ and(
1546
+ eq(
1547
+ schema.creativeContextPublishedSnapshots.itemId,
1548
+ schema.contextItems.id,
1549
+ ),
1550
+ eq(
1551
+ schema.creativeContextPublishedSnapshots.itemVersionId,
1552
+ requestedVersionId,
1553
+ ),
1554
+ eq(
1555
+ schema.creativeContextPublishedSnapshots.sourceId,
1556
+ schema.contextItems.sourceId,
1557
+ ),
1558
+ ),
1559
+ )
1364
1560
  .where(
1365
1561
  and(
1366
1562
  eq(schema.contextItems.id, itemId),
1367
- accessFilter(schema.contextSources, schema.contextSourceShares),
1368
- ne(schema.contextSources.upstreamAccess, "restricted"),
1369
- ne(schema.contextSources.status, "archived"),
1563
+ or(
1564
+ and(
1565
+ accessFilter(schema.contextSources, schema.contextSourceShares),
1566
+ ne(schema.contextSources.upstreamAccess, "restricted"),
1567
+ ne(schema.contextSources.status, "archived"),
1568
+ ),
1569
+ and(
1570
+ isNotNull(schema.creativeContextPublishedSnapshots.id),
1571
+ accessFilter(schema.contextPacks, schema.contextPackShares),
1572
+ ),
1573
+ accessFilter(schema.creativeContexts, schema.creativeContextShares),
1574
+ ),
1370
1575
  eq(schema.contextItems.curationStatus, "included"),
1371
1576
  ne(schema.contextItems.curationRank, "ignored"),
1372
1577
  eq(schema.contextItems.status, "active"),
@@ -1651,12 +1856,7 @@ export async function createEmbeddingSet(input: {
1651
1856
  const { getDb, schema } = getCreativeContext();
1652
1857
  const actor = requireActor();
1653
1858
  if (actor.orgId) {
1654
- const membership = await getDbExec().execute({
1655
- sql: "SELECT role FROM org_members WHERE org_id = ? AND LOWER(email) = ? LIMIT 1",
1656
- args: [actor.orgId, actor.ownerEmail.toLowerCase()],
1657
- });
1658
- const role = String(membership.rows[0]?.role ?? "").toLowerCase();
1659
- if (role !== "owner" && role !== "admin") {
1859
+ if (!(await currentRequestUserIsOrgAdmin(actor.orgId))) {
1660
1860
  throw new Error(
1661
1861
  "Only organization owners or admins can activate an organization embedding family.",
1662
1862
  );