@happyvertical/smrt-content 0.30.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 (291) hide show
  1. package/AGENTS.md +194 -0
  2. package/CLAUDE.md +1 -0
  3. package/LICENSE +7 -0
  4. package/README.md +634 -0
  5. package/dist/__smrt-register__.d.ts +2 -0
  6. package/dist/__smrt-register__.d.ts.map +1 -0
  7. package/dist/asset-associable.d.ts +115 -0
  8. package/dist/asset-associable.d.ts.map +1 -0
  9. package/dist/body-format.d.ts +29 -0
  10. package/dist/body-format.d.ts.map +1 -0
  11. package/dist/body-format.js +604 -0
  12. package/dist/body-format.js.map +1 -0
  13. package/dist/content-asset.d.ts +17 -0
  14. package/dist/content-asset.d.ts.map +1 -0
  15. package/dist/content-assets.d.ts +10 -0
  16. package/dist/content-assets.d.ts.map +1 -0
  17. package/dist/content-chat-handlers.d.ts +115 -0
  18. package/dist/content-chat-handlers.d.ts.map +1 -0
  19. package/dist/content-chat-prompts.d.ts +3 -0
  20. package/dist/content-chat-prompts.d.ts.map +1 -0
  21. package/dist/content-chat-session.d.ts +26 -0
  22. package/dist/content-chat-session.d.ts.map +1 -0
  23. package/dist/content-contribution-attachment.d.ts +42 -0
  24. package/dist/content-contribution-attachment.d.ts.map +1 -0
  25. package/dist/content-contribution-attachments.d.ts +8 -0
  26. package/dist/content-contribution-attachments.d.ts.map +1 -0
  27. package/dist/content-contribution-config.d.ts +84 -0
  28. package/dist/content-contribution-config.d.ts.map +1 -0
  29. package/dist/content-contribution-revision.d.ts +38 -0
  30. package/dist/content-contribution-revision.d.ts.map +1 -0
  31. package/dist/content-contribution-revisions.d.ts +8 -0
  32. package/dist/content-contribution-revisions.d.ts.map +1 -0
  33. package/dist/content-contribution-type.d.ts +51 -0
  34. package/dist/content-contribution-type.d.ts.map +1 -0
  35. package/dist/content-contribution-types.d.ts +7 -0
  36. package/dist/content-contribution-types.d.ts.map +1 -0
  37. package/dist/content-contribution.d.ts +161 -0
  38. package/dist/content-contribution.d.ts.map +1 -0
  39. package/dist/content-contributions.d.ts +53 -0
  40. package/dist/content-contributions.d.ts.map +1 -0
  41. package/dist/content-contributor.d.ts +30 -0
  42. package/dist/content-contributor.d.ts.map +1 -0
  43. package/dist/content-contributors.d.ts +13 -0
  44. package/dist/content-contributors.d.ts.map +1 -0
  45. package/dist/content-correction.d.ts +39 -0
  46. package/dist/content-correction.d.ts.map +1 -0
  47. package/dist/content-corrections.d.ts +9 -0
  48. package/dist/content-corrections.d.ts.map +1 -0
  49. package/dist/content-editor-assistant.d.ts +68 -0
  50. package/dist/content-editor-assistant.d.ts.map +1 -0
  51. package/dist/content-editor-assistant.js +97 -0
  52. package/dist/content-editor-assistant.js.map +1 -0
  53. package/dist/content-feed-parser.d.ts +19 -0
  54. package/dist/content-feed-parser.d.ts.map +1 -0
  55. package/dist/content-feed-source.d.ts +52 -0
  56. package/dist/content-feed-source.d.ts.map +1 -0
  57. package/dist/content-feed-sources.d.ts +11 -0
  58. package/dist/content-feed-sources.d.ts.map +1 -0
  59. package/dist/content-feed-sync.d.ts +23 -0
  60. package/dist/content-feed-sync.d.ts.map +1 -0
  61. package/dist/content-governance-assignment.d.ts +42 -0
  62. package/dist/content-governance-assignment.d.ts.map +1 -0
  63. package/dist/content-governance-assignments.d.ts +11 -0
  64. package/dist/content-governance-assignments.d.ts.map +1 -0
  65. package/dist/content-governance-policies.d.ts +7 -0
  66. package/dist/content-governance-policies.d.ts.map +1 -0
  67. package/dist/content-governance-policy.d.ts +29 -0
  68. package/dist/content-governance-policy.d.ts.map +1 -0
  69. package/dist/content-governance-profile.d.ts +31 -0
  70. package/dist/content-governance-profile.d.ts.map +1 -0
  71. package/dist/content-governance-profiles.d.ts +7 -0
  72. package/dist/content-governance-profiles.d.ts.map +1 -0
  73. package/dist/content-governance.d.ts +188 -0
  74. package/dist/content-governance.d.ts.map +1 -0
  75. package/dist/content-prompts.d.ts +10 -0
  76. package/dist/content-prompts.d.ts.map +1 -0
  77. package/dist/content-reference.d.ts +17 -0
  78. package/dist/content-reference.d.ts.map +1 -0
  79. package/dist/content-references.d.ts +55 -0
  80. package/dist/content-references.d.ts.map +1 -0
  81. package/dist/content-review.d.ts +34 -0
  82. package/dist/content-review.d.ts.map +1 -0
  83. package/dist/content-reviews.d.ts +21 -0
  84. package/dist/content-reviews.d.ts.map +1 -0
  85. package/dist/content-transparency.d.ts +72 -0
  86. package/dist/content-transparency.d.ts.map +1 -0
  87. package/dist/content-types.d.ts +51 -0
  88. package/dist/content-types.d.ts.map +1 -0
  89. package/dist/content-version.d.ts +38 -0
  90. package/dist/content-version.d.ts.map +1 -0
  91. package/dist/content-versions.d.ts +16 -0
  92. package/dist/content-versions.d.ts.map +1 -0
  93. package/dist/content.d.ts +736 -0
  94. package/dist/content.d.ts.map +1 -0
  95. package/dist/contents.d.ts +292 -0
  96. package/dist/contents.d.ts.map +1 -0
  97. package/dist/database-utils.d.ts +3 -0
  98. package/dist/database-utils.d.ts.map +1 -0
  99. package/dist/index.d.ts +78 -0
  100. package/dist/index.d.ts.map +1 -0
  101. package/dist/index.js +11602 -0
  102. package/dist/index.js.map +1 -0
  103. package/dist/manifest.json +12308 -0
  104. package/dist/mock-smrt-client.d.ts +493 -0
  105. package/dist/mock-smrt-client.d.ts.map +1 -0
  106. package/dist/mock-smrt-client.js +390 -0
  107. package/dist/mock-smrt-client.js.map +1 -0
  108. package/dist/playground.d.ts +2 -0
  109. package/dist/playground.d.ts.map +1 -0
  110. package/dist/playground.js +454 -0
  111. package/dist/playground.js.map +1 -0
  112. package/dist/publish-readiness.d.ts +30 -0
  113. package/dist/publish-readiness.d.ts.map +1 -0
  114. package/dist/publish-readiness.js +74 -0
  115. package/dist/publish-readiness.js.map +1 -0
  116. package/dist/safe-remote-url.d.ts +52 -0
  117. package/dist/safe-remote-url.d.ts.map +1 -0
  118. package/dist/serialization.d.ts +78 -0
  119. package/dist/serialization.d.ts.map +1 -0
  120. package/dist/smrt-knowledge.json +6130 -0
  121. package/dist/svelte/api.d.ts +3 -0
  122. package/dist/svelte/api.d.ts.map +1 -0
  123. package/dist/svelte/api.js +10 -0
  124. package/dist/svelte/components/ArticleCard.svelte +159 -0
  125. package/dist/svelte/components/ArticleCard.svelte.d.ts +17 -0
  126. package/dist/svelte/components/ArticleCard.svelte.d.ts.map +1 -0
  127. package/dist/svelte/components/ArticleList.svelte +75 -0
  128. package/dist/svelte/components/ArticleList.svelte.d.ts +21 -0
  129. package/dist/svelte/components/ArticleList.svelte.d.ts.map +1 -0
  130. package/dist/svelte/components/ContentAgentChat.svelte +652 -0
  131. package/dist/svelte/components/ContentAgentChat.svelte.d.ts +17 -0
  132. package/dist/svelte/components/ContentAgentChat.svelte.d.ts.map +1 -0
  133. package/dist/svelte/components/ContentBodyEditor.svelte +1446 -0
  134. package/dist/svelte/components/ContentBodyEditor.svelte.d.ts +25 -0
  135. package/dist/svelte/components/ContentBodyEditor.svelte.d.ts.map +1 -0
  136. package/dist/svelte/components/ContentBodyRenderer.svelte +152 -0
  137. package/dist/svelte/components/ContentBodyRenderer.svelte.d.ts +10 -0
  138. package/dist/svelte/components/ContentBodyRenderer.svelte.d.ts.map +1 -0
  139. package/dist/svelte/components/ContentClaimAuditTool.svelte +441 -0
  140. package/dist/svelte/components/ContentClaimAuditTool.svelte.d.ts +12 -0
  141. package/dist/svelte/components/ContentClaimAuditTool.svelte.d.ts.map +1 -0
  142. package/dist/svelte/components/ContentContributionForm.svelte +226 -0
  143. package/dist/svelte/components/ContentContributionForm.svelte.d.ts +23 -0
  144. package/dist/svelte/components/ContentContributionForm.svelte.d.ts.map +1 -0
  145. package/dist/svelte/components/ContentContributionInbox.svelte +322 -0
  146. package/dist/svelte/components/ContentContributionInbox.svelte.d.ts +22 -0
  147. package/dist/svelte/components/ContentContributionInbox.svelte.d.ts.map +1 -0
  148. package/dist/svelte/components/ContentContributionPortal.svelte +182 -0
  149. package/dist/svelte/components/ContentContributionPortal.svelte.d.ts +12 -0
  150. package/dist/svelte/components/ContentContributionPortal.svelte.d.ts.map +1 -0
  151. package/dist/svelte/components/ContentContributionTypeManager.svelte +281 -0
  152. package/dist/svelte/components/ContentContributionTypeManager.svelte.d.ts +10 -0
  153. package/dist/svelte/components/ContentContributionTypeManager.svelte.d.ts.map +1 -0
  154. package/dist/svelte/components/ContentContributorManager.svelte +140 -0
  155. package/dist/svelte/components/ContentContributorManager.svelte.d.ts +10 -0
  156. package/dist/svelte/components/ContentContributorManager.svelte.d.ts.map +1 -0
  157. package/dist/svelte/components/ContentCorrectionsTool.svelte +361 -0
  158. package/dist/svelte/components/ContentCorrectionsTool.svelte.d.ts +11 -0
  159. package/dist/svelte/components/ContentCorrectionsTool.svelte.d.ts.map +1 -0
  160. package/dist/svelte/components/ContentEditor.svelte +2166 -0
  161. package/dist/svelte/components/ContentEditor.svelte.d.ts +26 -0
  162. package/dist/svelte/components/ContentEditor.svelte.d.ts.map +1 -0
  163. package/dist/svelte/components/ContentGovernanceAssignmentEditor.svelte +199 -0
  164. package/dist/svelte/components/ContentGovernanceAssignmentEditor.svelte.d.ts +11 -0
  165. package/dist/svelte/components/ContentGovernanceAssignmentEditor.svelte.d.ts.map +1 -0
  166. package/dist/svelte/components/ContentGovernanceManager.svelte +340 -0
  167. package/dist/svelte/components/ContentGovernanceManager.svelte.d.ts +11 -0
  168. package/dist/svelte/components/ContentGovernanceManager.svelte.d.ts.map +1 -0
  169. package/dist/svelte/components/ContentGovernancePanel.svelte +2244 -0
  170. package/dist/svelte/components/ContentGovernancePanel.svelte.d.ts +26 -0
  171. package/dist/svelte/components/ContentGovernancePanel.svelte.d.ts.map +1 -0
  172. package/dist/svelte/components/ContentGovernancePolicyEditor.svelte +110 -0
  173. package/dist/svelte/components/ContentGovernancePolicyEditor.svelte.d.ts +10 -0
  174. package/dist/svelte/components/ContentGovernancePolicyEditor.svelte.d.ts.map +1 -0
  175. package/dist/svelte/components/ContentGovernanceProfileEditor.svelte +185 -0
  176. package/dist/svelte/components/ContentGovernanceProfileEditor.svelte.d.ts +11 -0
  177. package/dist/svelte/components/ContentGovernanceProfileEditor.svelte.d.ts.map +1 -0
  178. package/dist/svelte/components/ContentGovernanceTool.svelte +56 -0
  179. package/dist/svelte/components/ContentGovernanceTool.svelte.d.ts +13 -0
  180. package/dist/svelte/components/ContentGovernanceTool.svelte.d.ts.map +1 -0
  181. package/dist/svelte/components/ContentImageBrowser.svelte +243 -0
  182. package/dist/svelte/components/ContentImageBrowser.svelte.d.ts +18 -0
  183. package/dist/svelte/components/ContentImageBrowser.svelte.d.ts.map +1 -0
  184. package/dist/svelte/components/ContentImageChooser.svelte +134 -0
  185. package/dist/svelte/components/ContentImageChooser.svelte.d.ts +11 -0
  186. package/dist/svelte/components/ContentImageChooser.svelte.d.ts.map +1 -0
  187. package/dist/svelte/components/ContentList.svelte +906 -0
  188. package/dist/svelte/components/ContentList.svelte.d.ts +16 -0
  189. package/dist/svelte/components/ContentList.svelte.d.ts.map +1 -0
  190. package/dist/svelte/components/ContentMetadataFields.svelte +107 -0
  191. package/dist/svelte/components/ContentMetadataFields.svelte.d.ts +8 -0
  192. package/dist/svelte/components/ContentMetadataFields.svelte.d.ts.map +1 -0
  193. package/dist/svelte/components/ContentReferencesPanel.svelte +221 -0
  194. package/dist/svelte/components/ContentReferencesPanel.svelte.d.ts +20 -0
  195. package/dist/svelte/components/ContentReferencesPanel.svelte.d.ts.map +1 -0
  196. package/dist/svelte/components/ContentReviewStatusTray.svelte +151 -0
  197. package/dist/svelte/components/ContentReviewStatusTray.svelte.d.ts +20 -0
  198. package/dist/svelte/components/ContentReviewStatusTray.svelte.d.ts.map +1 -0
  199. package/dist/svelte/components/ContentStatusFields.svelte +85 -0
  200. package/dist/svelte/components/ContentStatusFields.svelte.d.ts +8 -0
  201. package/dist/svelte/components/ContentStatusFields.svelte.d.ts.map +1 -0
  202. package/dist/svelte/components/ContentTitleField.svelte +54 -0
  203. package/dist/svelte/components/ContentTitleField.svelte.d.ts +10 -0
  204. package/dist/svelte/components/ContentTitleField.svelte.d.ts.map +1 -0
  205. package/dist/svelte/components/ContentTransparencyReport.svelte +322 -0
  206. package/dist/svelte/components/ContentTransparencyReport.svelte.d.ts +10 -0
  207. package/dist/svelte/components/ContentTransparencyReport.svelte.d.ts.map +1 -0
  208. package/dist/svelte/components/ContentTransparencyTool.svelte +314 -0
  209. package/dist/svelte/components/ContentTransparencyTool.svelte.d.ts +10 -0
  210. package/dist/svelte/components/ContentTransparencyTool.svelte.d.ts.map +1 -0
  211. package/dist/svelte/components/ContentVersionsTool.svelte +291 -0
  212. package/dist/svelte/components/ContentVersionsTool.svelte.d.ts +10 -0
  213. package/dist/svelte/components/ContentVersionsTool.svelte.d.ts.map +1 -0
  214. package/dist/svelte/components/GovernedContentEditor.svelte +409 -0
  215. package/dist/svelte/components/GovernedContentEditor.svelte.d.ts +35 -0
  216. package/dist/svelte/components/GovernedContentEditor.svelte.d.ts.map +1 -0
  217. package/dist/svelte/components/ImageThumbnail.cache.d.ts +14 -0
  218. package/dist/svelte/components/ImageThumbnail.cache.d.ts.map +1 -0
  219. package/dist/svelte/components/ImageThumbnail.cache.js +36 -0
  220. package/dist/svelte/components/ImageThumbnail.svelte +159 -0
  221. package/dist/svelte/components/ImageThumbnail.svelte.d.ts +8 -0
  222. package/dist/svelte/components/ImageThumbnail.svelte.d.ts.map +1 -0
  223. package/dist/svelte/components/Markdown.svelte +125 -0
  224. package/dist/svelte/components/Markdown.svelte.d.ts +11 -0
  225. package/dist/svelte/components/Markdown.svelte.d.ts.map +1 -0
  226. package/dist/svelte/content-editor-form.d.ts +63 -0
  227. package/dist/svelte/content-editor-form.d.ts.map +1 -0
  228. package/dist/svelte/content-editor-form.js +94 -0
  229. package/dist/svelte/content-editor-media.d.ts +12 -0
  230. package/dist/svelte/content-editor-media.d.ts.map +1 -0
  231. package/dist/svelte/content-editor-media.js +84 -0
  232. package/dist/svelte/content-editor-state.svelte.d.ts +35 -0
  233. package/dist/svelte/content-editor-state.svelte.d.ts.map +1 -0
  234. package/dist/svelte/content-editor-state.svelte.js +141 -0
  235. package/dist/svelte/governance-manager-client.d.ts +22 -0
  236. package/dist/svelte/governance-manager-client.d.ts.map +1 -0
  237. package/dist/svelte/governance-manager-client.js +1 -0
  238. package/dist/svelte/i18n.contribution.d.ts +57 -0
  239. package/dist/svelte/i18n.contribution.d.ts.map +1 -0
  240. package/dist/svelte/i18n.contribution.js +64 -0
  241. package/dist/svelte/i18n.editor.d.ts +71 -0
  242. package/dist/svelte/i18n.editor.d.ts.map +1 -0
  243. package/dist/svelte/i18n.editor.js +87 -0
  244. package/dist/svelte/i18n.governance.d.ts +66 -0
  245. package/dist/svelte/i18n.governance.d.ts.map +1 -0
  246. package/dist/svelte/i18n.governance.js +66 -0
  247. package/dist/svelte/i18n.routes.d.ts +66 -0
  248. package/dist/svelte/i18n.routes.d.ts.map +1 -0
  249. package/dist/svelte/i18n.routes.js +75 -0
  250. package/dist/svelte/i18n.tools.d.ts +81 -0
  251. package/dist/svelte/i18n.tools.d.ts.map +1 -0
  252. package/dist/svelte/i18n.tools.js +90 -0
  253. package/dist/svelte/index.d.ts +101 -0
  254. package/dist/svelte/index.d.ts.map +1 -0
  255. package/dist/svelte/index.js +63 -0
  256. package/dist/svelte/playground.d.ts +281 -0
  257. package/dist/svelte/playground.d.ts.map +1 -0
  258. package/dist/svelte/playground.js +438 -0
  259. package/dist/svelte/routes/ContentContributionsRoute.svelte +809 -0
  260. package/dist/svelte/routes/ContentContributionsRoute.svelte.d.ts +10 -0
  261. package/dist/svelte/routes/ContentContributionsRoute.svelte.d.ts.map +1 -0
  262. package/dist/svelte/routes/ContentFactsRoute.svelte +612 -0
  263. package/dist/svelte/routes/ContentFactsRoute.svelte.d.ts +11 -0
  264. package/dist/svelte/routes/ContentFactsRoute.svelte.d.ts.map +1 -0
  265. package/dist/svelte/routes/ContentGovernanceRoute.svelte +218 -0
  266. package/dist/svelte/routes/ContentGovernanceRoute.svelte.d.ts +10 -0
  267. package/dist/svelte/routes/ContentGovernanceRoute.svelte.d.ts.map +1 -0
  268. package/dist/svelte/routes/ContentWorkspaceRoute.svelte +431 -0
  269. package/dist/svelte/routes/ContentWorkspaceRoute.svelte.d.ts +12 -0
  270. package/dist/svelte/routes/ContentWorkspaceRoute.svelte.d.ts.map +1 -0
  271. package/dist/svelte/routes/PublishedArticleRoute.svelte +194 -0
  272. package/dist/svelte/routes/PublishedArticleRoute.svelte.d.ts +10 -0
  273. package/dist/svelte/routes/PublishedArticleRoute.svelte.d.ts.map +1 -0
  274. package/dist/svelte/routes/index.d.ts +8 -0
  275. package/dist/svelte/routes/index.d.ts.map +1 -0
  276. package/dist/svelte/routes/index.js +6 -0
  277. package/dist/svelte/routes/shared.d.ts +90 -0
  278. package/dist/svelte/routes/shared.d.ts.map +1 -0
  279. package/dist/svelte/routes/shared.js +104 -0
  280. package/dist/svelte/types.d.ts +69 -0
  281. package/dist/svelte/types.d.ts.map +1 -0
  282. package/dist/svelte/types.js +6 -0
  283. package/dist/thumbnail-generator.d.ts +174 -0
  284. package/dist/thumbnail-generator.d.ts.map +1 -0
  285. package/dist/ui.d.ts +10 -0
  286. package/dist/ui.d.ts.map +1 -0
  287. package/dist/ui.js +42 -0
  288. package/dist/ui.js.map +1 -0
  289. package/dist/utils.d.ts +18 -0
  290. package/dist/utils.d.ts.map +1 -0
  291. package/package.json +119 -0
package/AGENTS.md ADDED
@@ -0,0 +1,194 @@
1
+ # @happyvertical/smrt-content
2
+
3
+ STI content management with governance workflows, contribution intake, AI reviews, fact-checking, corrections, versioning, transparency reports, and thumbnail generation.
4
+
5
+ ## Models
6
+
7
+ - **Content** (STI base): `type`, `variant` (generator:domain:specific format), `status` (published/draft/review/archived/deleted), `state`, `category` (hierarchical path with `/` separator), `metadata` JSON, `tags` array, `thumbnailAssetId`
8
+ - **Article**, **ContentDocument**, **Mirror**: STI subclasses — all share `contents` table via `_meta_type`
9
+ - **ContentReview**: AI review result tied to a governance policy. Fields: `contentId`, `policyKey`, `kind`, `status` (accepted/flagged/rejected), `findings`, `fingerprint`, `metadata`
10
+ - **ContentCorrection**: Post-publication change record. Fields: `contentId`, `type` (correction/retraction/update/clarification), `summary`, `note`, `status`, `metadata`
11
+ - **ContentVersion**: Content snapshot. Fields: `contentId`, `kind` (publication/manual), `versionNumber`, `summary`, `metadata` (includes `transparency` for publication versions)
12
+ - **ContentReference**: Junction model for content-to-content links (`content_references` table). Nullable `targetVersion` pins a citation to a specific `ContentVersion.version` for drift detection.
13
+ - **ContentGovernancePolicy**: Persisted review policy (key, label, kind, instructions)
14
+ - **ContentGovernanceProfile**: Persisted review profile (key, label, requirements array)
15
+ - **ContentGovernanceAssignment**: Governs content type/variant → profile mapping, feature flags
16
+ - **ContentContribution**: Held inbound submission with status lifecycle (submitted → approved/rejected/withdrawn → promoted)
17
+ - **ContentContributor**: Contributor profile resolved by email, with trust level (standard/trusted/blocked)
18
+ - **ContentContributionType**: Configures intake channels, rules, and promotion mapping
19
+ - **ContentContributionRevision**: Revision history for held submissions
20
+ - **ContentContributionAttachment**: Held file metadata; becomes an `Asset` on promotion
21
+
22
+ ## Contents Collection
23
+
24
+ | Method | Purpose |
25
+ |--------|---------|
26
+ | `mirror({ url })` | Downloads URL content, extracts text, creates `type: 'mirror'`. Idempotent. |
27
+ | `syncContentDir({ contentDir })` | Batch exports articles as markdown with YAML frontmatter |
28
+ | `generateMissingThumbnails(options)` | Bulk thumbnail generation for content missing `thumbnailAssetId` |
29
+ | `findWithGlobals(tenantId)` | Returns tenant-specific + global (tenantId=null) content |
30
+ | `getOrUpsert({ slug, context })` | Upsert by slug+context combination |
31
+ | `browseFacts()` | Browse fact catalog linked to content |
32
+ | `getGovernanceDefinitionsAction()` | Get all governance policy/profile/assignment definitions |
33
+ | `resolveGovernanceAction({ type, variant })` | Resolve effective governance for a content type |
34
+
35
+ ## Content Instance Methods
36
+
37
+ | Method | Purpose |
38
+ |--------|---------|
39
+ | `resolveGovernance()` | Resolve effective governance config for this content |
40
+ | `runReviewAction(options)` | Run AI review against a policy; returns `ContentReview` |
41
+ | `listReviews()` | List all reviews for this content |
42
+ | `listReviewProfilesAction()` | Get readiness for all profiles |
43
+ | `evaluateReviewProfile(key)` | Evaluate one profile's requirements |
44
+ | `issueCorrectionAction(options)` | Issue a post-publication correction |
45
+ | `listCorrections()` | List corrections for this content |
46
+ | `listVersions()` | List version history |
47
+ | `mutateVersionAction(options)` | Create a version snapshot |
48
+ | `getPublishedTransparencyAction()` | Get frozen transparency from latest publication version |
49
+ | `previewTransparencyAction()` | Preview live transparency state |
50
+ | `addFact(factId, relationship)` | Link a fact (supports/contradicts/referenced_in) |
51
+ | `getFacts(options)` | Get linked facts |
52
+ | `getFactLinks()` | Get fact-content link records |
53
+ | `getFactsState()` / `syncFactsState(options)` | API-level facts get/sync |
54
+ | `addAsset(asset, relationship, sortOrder)` | Add asset association |
55
+ | `setThumbnail(image)` | Convenience: adds asset + updates `thumbnailAssetId` |
56
+ | `addReference(content, options?)` | Link to another content; `options.targetVersion` pins citation-time `ContentVersion.version` |
57
+ | `getReferences()` | Get content references |
58
+ | `getReferenceDrift()` | Per-edge `{ citedVersion, currentVersion, isDrifted }` for drift detection |
59
+
60
+ ## Governance Workflow
61
+
62
+ 1. `configureContentGovernance({ policies, profiles, assignments })` — static config
63
+ 2. Or persist `ContentGovernancePolicy/Profile/Assignment` objects — DB overrides static
64
+ 3. Effective config: DB layer merges over static defaults
65
+ 4. `content.resolveGovernance()` → `ResolvedContentGovernance` with `isGoverned`, `reviewPolicies`, profile keys, feature flags
66
+ 5. `content.runReviewAction()` creates a `ContentReview` with fingerprint for staleness detection
67
+ 6. `content.evaluateReviewProfile(key)` checks all requirements
68
+ 7. `content.save()` auto-validates publish readiness when `enforcePublishReadiness` is true
69
+ 8. Publication auto-creates a `ContentVersion` with frozen transparency data
70
+
71
+ ## Thumbnail Generation
72
+
73
+ Three strategies via ThumbnailGenerator:
74
+ - **headline-card**: title on branded background (via `@happyvertical/images`)
75
+ - **static-map**: requires `metadata.latitude`/`longitude` (via `@happyvertical/geo`)
76
+ - **ai-generate**: AI image generation (dynamic import of `@happyvertical/ai`)
77
+
78
+ ## Svelte Components
79
+
80
+ ### Content Management
81
+ `ContentList`, `ContentEditor`, `GovernedContentEditor`, `ContentAgentChat`, `ContentTitleField`, `ContentStatusFields`, `ContentMetadataFields`, `ContentReferencesPanel`, `ContentImageBrowser`, `ContentReviewStatusTray`, `ArticleCard`, `ArticleList`, `ImageThumbnail`, `Markdown`
82
+
83
+ ### Governance
84
+ `ContentGovernanceManager`, `ContentGovernancePanel`, `ContentGovernancePolicyEditor`, `ContentGovernanceProfileEditor`, `ContentGovernanceAssignmentEditor`, `ContentTransparencyReport`
85
+
86
+ ### Contributions
87
+ `ContentContributionForm`, `ContentContributionInbox`, `ContentContributionPortal`, `ContentContributionTypeManager`, `ContentContributorManager`
88
+
89
+ ## Dev Server
90
+
91
+ `npm run dev` starts SvelteKit at `localhost:5173` with 4 pages:
92
+
93
+ - `/` — Content catalog (CRUD, search, filters, card/list views)
94
+ - `/governance` — Policy/profile/assignment management
95
+ - `/contributions` — Inbox, submit form, contributor/type management
96
+ - `/api-explorer` — Browse 69 endpoints with try-it-live for GET
97
+
98
+ On startup, `hooks.server.ts` bootstraps schemas for all 13 local classes,
99
+ loads cross-package manifests, and seeds 3 sample content items.
100
+
101
+ ## Chat Integration
102
+
103
+ Content `GET/POST /api/v1/contents/{id}/chat` endpoint creates
104
+ chat sessions via `@happyvertical/smrt-chat`. Gracefully handles
105
+ missing chat tables (returns `session: null` with notice).
106
+ `ContentAgentChat` Svelte component provides the UI.
107
+
108
+ For global assistant shells, `ContentEditor` and `GovernedContentEditor`
109
+ support `onAssistantContextChange`. The callback receives a serializable
110
+ `ContentEditorAssistantContext` plus local editor actions, and still fires when
111
+ `hideChat={true}`. `ContentAgentChat` can be mounted outside the editor with an
112
+ `assistantContext` prop. Server-side consumers can reuse the exported
113
+ `getOrCreateContentEditorChatSession`, `createContentEditorChatThread`,
114
+ `listContentEditorChatThreadMessages`, and
115
+ `sendContentEditorChatThreadMessage` helpers for app-specific tenancy/auth/AI
116
+ route wiring.
117
+
118
+ These handlers go exclusively through the tenant-bound `ChatService` facade
119
+ (S5 #1392) — `getAgentSession`/`findActiveAgentSessions`/`getThread`/
120
+ `listRoomThreads`/`getThreadMessages` for reads and `startThread`/`sendMessage`/
121
+ `sendAgentReply` (internal agent-runtime subpath) for writes. They never reach
122
+ into the now-`#private` chat collections, so cross-tenant chat state can no
123
+ longer be selected by raw id before authorization.
124
+
125
+ The content-editor session is created with a content-scoped `sessionKey`
126
+ (`contentChatSessionKey(contentId)` → `content:<id>`, S5 #1392). Without it,
127
+ `createAgentSession` reuses ANY active `content_editor` session for the same
128
+ profile/tenant, so a request about a new content id would reuse — and the
129
+ handler would rewrite — a session created for a different content and return the
130
+ other content's room/threads. Keying on the content id makes each content get a
131
+ distinct session/room.
132
+
133
+ ## Relationship Models
134
+
135
+ - **ContentReference**: SMRT junction model backing `content_references` for content-to-content links
136
+ - **ContentAsset**: dedicated SMRT junction model backing `content_assets` for content-owned asset links
137
+
138
+ ```typescript
139
+ await content.addAsset(image, 'thumbnail', 0); // relationship, sortOrder
140
+ await content.getAssets('attachment');
141
+ await content.setThumbnail(image); // convenience: adds asset + updates thumbnailAssetId
142
+ await content.addReference(otherContent); // unpinned
143
+ await content.addReference(otherContent, { targetVersion: 2 }); // pinned to v2
144
+ await content.getReferences();
145
+ await content.getReferenceDrift(); // → [{ targetId, citedVersion, currentVersion, isDrifted }, ...]
146
+ ```
147
+
148
+ ## API Contracts
149
+
150
+ `Content` implements `AssetAssociable` and `MetadataAccessor` (issue #1162). Consumers can type their parameters as `Content` (or the interfaces directly) and rely on the methods existing without `typeof === 'function'` defensive checks:
151
+
152
+ ```typescript
153
+ import type { AssetAssociable, MetadataAccessor } from '@happyvertical/smrt-content';
154
+
155
+ async function attachThumbnail(doc: AssetAssociable, asset: Asset) {
156
+ await doc.addAsset(asset, 'thumbnail', 0); // contract guaranteed
157
+ }
158
+
159
+ function bumpRevision(doc: MetadataAccessor) {
160
+ const meta = doc.getMetadata();
161
+ doc.updateMetadata({ revision: (meta.revision ?? 0) + 1 });
162
+ }
163
+ ```
164
+
165
+ ## Category Navigation
166
+
167
+ `getCategorySegments()`, `getParentCategory()`, `getRootCategory()`, `getAncestorPaths()`, `isInCategory(path, includeChildren?)`
168
+
169
+ ## Prompt Registry
170
+
171
+ Content prompts are registered with `@happyvertical/smrt-prompts` so tenants can override template/profile/model/params at runtime:
172
+
173
+ ```typescript
174
+ import {
175
+ smrtContentReviewPrompt, // key: 'smrtContent.review'
176
+ smrtContentApplyCorrectionPrompt, // key: 'smrtContent.applyCorrection'
177
+ smrtContentThumbnailAIGeneratePrompt, // key: 'smrtContent.thumbnail.aiGenerate'
178
+ } from '@happyvertical/smrt-content';
179
+ ```
180
+
181
+ `smrtContent.thumbnail.aiGenerate` powers the AI image-generation prompt used by `ThumbnailGenerator` (strategy `'ai-generate'`). Variables substituted into the template: `style`, `title`, `styleHint`, `descriptionClause`. Internal foreign-key fields (`id`, `tenantId`) and the freeform `metadata` blob are intentionally excluded — `metadata` may carry tenant-private configuration or coordinates unrelated to the visual prompt.
182
+
183
+ ## Gotchas
184
+
185
+ - **STI discriminator**: qualified names like `@happyvertical/smrt-content:Article`
186
+ - **Optional tenancy**: `@TenantScoped({ mode: 'optional' })` — null tenantId = global content
187
+ - **Metadata is primary extension pattern**: use JSON `metadata` field, not additional class fields
188
+ - **Static map coordinates**: uses unary `+` for strict parsing (rejects "45invalid" unlike parseFloat)
189
+ - **Review fingerprints**: reviews track content state at review time; stale reviews are detected by fingerprint mismatch
190
+ - **Publish readiness enforcement**: `save()` throws `ValidationError` if blocking requirements aren't met when setting status to `'published'`
191
+ - **Transparency snapshots**: published transparency is frozen into `ContentVersion.metadata.transparency` — use published for public display, preview for editors
192
+ - **Reference pinning**: `ContentReference` is keyed on `(source_id, target_id)`; `targetVersion` is an attribute of the edge, not part of identity. Re-calling `addReference(target, { targetVersion })` updates the pin in place. Unpinned references (`targetVersion: null`) report `isDrifted: false` regardless of how stale the target is — pin them only when you want drift to be detectable.
193
+ - **Chat tables**: chat endpoint requires `@happyvertical/smrt-chat` tables; dev server handles missing tables gracefully
194
+ - **Dev server bootstraps all classes**: `hooks.server.ts` generates schemas for all 13 local `@smrt()` classes plus cross-package manifests
package/CLAUDE.md ADDED
@@ -0,0 +1 @@
1
+ @AGENTS.md
package/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright <2025> <Happy Vertical Corporation>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.