@happyvertical/smrt-content 0.40.65 → 0.40.67

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workbench.js","names":[],"sources":["../src/route-loaders.ts","../src/svelte/routes/shared.ts","../src/route-module.ts","../src/workbench.ts"],"sourcesContent":["import type {\n ContentData,\n ContentTransparencyData,\n} from './mock-smrt-client.js';\nimport type {\n LoadPublishedArticleRouteInput,\n PublishedContentArticleRouteData,\n} from './svelte/routes/shared.js';\n\nexport type ContentRouteLoadError = Error & {\n name: 'ContentRouteLoadError';\n status: number;\n code?: string;\n};\n\nfunction createContentRouteLoadError(\n status: number,\n message: string,\n code?: string,\n): ContentRouteLoadError {\n const error = new Error(message) as ContentRouteLoadError;\n error.name = 'ContentRouteLoadError';\n error.status = status;\n error.code = code;\n return error;\n}\n\nexport function isContentRouteLoadError(\n value: unknown,\n): value is ContentRouteLoadError {\n return (\n value instanceof Error &&\n value.name === 'ContentRouteLoadError' &&\n typeof (value as ContentRouteLoadError).status === 'number'\n );\n}\n\nfunction getItemData<T>(payload: unknown): T {\n if (!payload || typeof payload !== 'object') {\n return payload as T;\n }\n\n const wrappedPayload = payload as { data?: unknown; result?: unknown };\n if ('result' in wrappedPayload) {\n return wrappedPayload.result as T;\n }\n\n if ('data' in wrappedPayload) {\n return wrappedPayload.data as T;\n }\n\n return payload as T;\n}\n\nexport async function loadPublishedArticleRouteData({\n fetch,\n slug,\n apiBasePath = '/api/v1',\n}: LoadPublishedArticleRouteInput): Promise<PublishedContentArticleRouteData> {\n const searchParams = new URLSearchParams({\n slug,\n status: 'published',\n });\n\n const contentResponse = await fetch(\n `${apiBasePath}/contents/by-slug?${searchParams.toString()}`,\n );\n\n if (!contentResponse.ok) {\n throw createContentRouteLoadError(\n contentResponse.status,\n 'Failed to load article',\n 'content_fetch_failed',\n );\n }\n\n const contentPayload = await contentResponse.json();\n const content = getItemData<ContentData | null>(contentPayload);\n\n if (!content?.id) {\n throw createContentRouteLoadError(\n 404,\n 'Article not found',\n 'content_not_found',\n );\n }\n\n const transparencyResponse = await fetch(\n `${apiBasePath}/contents/${content.id}/transparency`,\n );\n\n if (!transparencyResponse.ok) {\n throw createContentRouteLoadError(\n transparencyResponse.status,\n 'Failed to load transparency',\n 'transparency_fetch_failed',\n );\n }\n\n const transparencyPayload = await transparencyResponse.json();\n const transparency = getItemData<ContentTransparencyData | null>(\n transparencyPayload,\n );\n\n return {\n content,\n transparency,\n };\n}\n","import type {\n SmrtRouteLoadKind,\n SmrtRouteNavigationItem,\n SmrtRouteNavigationMeta,\n} from '@happyvertical/smrt-types';\nimport type {\n ContentData,\n ContentTransparencyData,\n} from '../../mock-smrt-client.js';\n\nexport const CONTENT_ROUTE_IDS = {\n workspace: 'content.workspace',\n facts: 'content.facts',\n governance: 'content.governance',\n contributions: 'content.contributions',\n article: 'content.article',\n} as const;\n\nexport type ContentRouteKey = keyof typeof CONTENT_ROUTE_IDS;\nexport type ContentRouteId = (typeof CONTENT_ROUTE_IDS)[ContentRouteKey];\n\ninterface ContentRouteMeta {\n id: ContentRouteId;\n title: string;\n description: string;\n defaultPath: string;\n loadKind?: SmrtRouteLoadKind;\n nav?: SmrtRouteNavigationMeta;\n}\n\nexport interface ContentRouteNavigationItem extends SmrtRouteNavigationItem {\n routeId: ContentRouteId;\n}\n\nexport interface PublishedContentArticleRouteData {\n content: ContentData;\n transparency: ContentTransparencyData | null;\n}\n\nexport interface LoadPublishedArticleRouteInput {\n fetch: typeof globalThis.fetch;\n slug: string;\n apiBasePath?: string;\n}\n\nexport const CONTENT_ROUTE_META = {\n workspace: {\n id: CONTENT_ROUTE_IDS.workspace,\n title: 'Contents',\n description:\n 'Author, review, and publish content records against the content module workflows.',\n defaultPath: '/workspace',\n nav: {\n label: 'Workspace',\n description: 'Authoring and publishing workspace',\n icon: 'file-text',\n order: 10,\n group: 'content',\n },\n },\n governance: {\n id: CONTENT_ROUTE_IDS.governance,\n title: 'Governance Admin',\n description:\n 'Manage review policies, profiles, and publication assignments for governed content.',\n defaultPath: '/governance',\n nav: {\n label: 'Governance',\n description: 'Policy, profile, and assignment management',\n icon: 'shield-check',\n order: 20,\n group: 'content',\n },\n },\n facts: {\n id: CONTENT_ROUTE_IDS.facts,\n title: 'Fact Catalog',\n description:\n 'Browse extracted facts, search by text or domain, and confirm what content workflows can cite.',\n defaultPath: '/facts',\n nav: {\n label: 'Facts',\n description: 'Browse indexed facts and confidence',\n icon: 'sparkles',\n order: 15,\n group: 'content',\n },\n },\n contributions: {\n id: CONTENT_ROUTE_IDS.contributions,\n title: 'Contribution Intake and Review',\n description:\n 'Review contributor submissions, moderation state, and promotion flows into content.',\n defaultPath: '/contributions',\n nav: {\n label: 'Contributions',\n description: 'Contributor intake, moderation, and promotion',\n icon: 'inbox',\n order: 30,\n group: 'content',\n },\n },\n article: {\n id: CONTENT_ROUTE_IDS.article,\n title: 'Published article',\n description:\n 'Render a published content record with its public transparency information.',\n defaultPath: '/articles/[slug]',\n loadKind: 'page',\n },\n} as const satisfies Record<ContentRouteKey, ContentRouteMeta>;\n\ntype ContentNavigableRouteKey = Exclude<ContentRouteKey, 'article'>;\n\nconst CONTENT_NAV_ROUTE_KEYS = [\n 'workspace',\n 'facts',\n 'governance',\n 'contributions',\n] as const satisfies readonly ContentNavigableRouteKey[];\n\nexport function getContentRouteDefaultPath(routeId: ContentRouteId): string {\n const route = Object.values(CONTENT_ROUTE_META).find(\n (entry) => entry.id === routeId,\n );\n if (!route) {\n throw new Error(`Unknown content route id: ${routeId}`);\n }\n\n return route.defaultPath;\n}\n\nexport function buildPublishedArticlePath(\n slug: string,\n basePath = CONTENT_ROUTE_META.article.defaultPath,\n): string {\n const normalizedBase = basePath.replace(/\\/\\[[^/]+\\]$/, '');\n return `${normalizedBase}/${slug}`;\n}\n\nexport function createContentRouteNavigation(\n pathOverrides: Partial<Record<ContentRouteId, string>> = {},\n): ContentRouteNavigationItem[] {\n return CONTENT_NAV_ROUTE_KEYS.map((routeKey) => {\n const route = CONTENT_ROUTE_META[routeKey];\n\n return {\n routeId: route.id,\n href: pathOverrides[route.id] || route.defaultPath,\n label: route.nav.label,\n description: route.nav.description,\n icon: route.nav.icon,\n order: route.nav.order,\n group: route.nav.group,\n };\n }).sort((left, right) => (left.order || 0) - (right.order || 0));\n}\n\nexport const CONTENT_DEFAULT_ROUTE_NAVIGATION = createContentRouteNavigation();\n\nexport function getContentRouteHref(\n navigation: ContentRouteNavigationItem[],\n routeId: ContentRouteId,\n): string {\n return (\n navigation.find((item) => item.routeId === routeId)?.href ||\n getContentRouteDefaultPath(routeId)\n );\n}\n","/**\n * Internal content route module\n *\n * Keeps the package's own page shells and loader helpers aligned without\n * publishing a public `./routes` package contract.\n *\n * @example Package-local SvelteKit wrapper\n * ```ts\n * // src/routes/articles/[slug]/+page.ts\n * import { error } from '@sveltejs/kit';\n * import { CONTENT_ROUTE_MODULE, isContentRouteLoadError } from '../route-module.js';\n *\n * export async function load(event) {\n * try {\n * return await CONTENT_ROUTE_MODULE.routes.article.load?.({\n * fetch: event.fetch,\n * slug: event.params.slug,\n * apiBasePath: '/api/v1',\n * });\n * } catch (cause) {\n * if (isContentRouteLoadError(cause)) {\n * throw error(cause.status, cause.message);\n * }\n * throw cause;\n * }\n * }\n * ```\n */\n\nimport type {\n SmrtRouteDefinition,\n SmrtRouteModule,\n} from '@happyvertical/smrt-types';\nimport {\n type ContentRouteLoadError,\n isContentRouteLoadError,\n loadPublishedArticleRouteData,\n} from './route-loaders.js';\nimport {\n ContentContributionsRoute,\n ContentFactsRoute,\n ContentGovernanceRoute,\n ContentWorkspaceRoute,\n PublishedArticleRoute,\n} from './svelte/routes/index.js';\nimport {\n CONTENT_DEFAULT_ROUTE_NAVIGATION,\n CONTENT_ROUTE_IDS,\n CONTENT_ROUTE_META,\n type ContentRouteId,\n type ContentRouteNavigationItem,\n createContentRouteNavigation,\n type LoadPublishedArticleRouteInput,\n type PublishedContentArticleRouteData,\n} from './svelte/routes/shared.js';\n\nexport type {\n ContentRouteId,\n ContentRouteLoadError,\n ContentRouteNavigationItem,\n LoadPublishedArticleRouteInput,\n PublishedContentArticleRouteData,\n};\nexport {\n CONTENT_DEFAULT_ROUTE_NAVIGATION,\n CONTENT_ROUTE_IDS,\n CONTENT_ROUTE_META,\n ContentContributionsRoute,\n ContentFactsRoute,\n ContentGovernanceRoute,\n ContentWorkspaceRoute,\n createContentRouteNavigation,\n isContentRouteLoadError,\n loadPublishedArticleRouteData,\n PublishedArticleRoute,\n};\n\nexport interface ContentRouteDefinitions {\n workspace: SmrtRouteDefinition;\n facts: SmrtRouteDefinition;\n governance: SmrtRouteDefinition;\n contributions: SmrtRouteDefinition;\n article: SmrtRouteDefinition<\n PublishedContentArticleRouteData,\n LoadPublishedArticleRouteInput\n >;\n}\n\nexport type ContentRouteModule = Omit<SmrtRouteModule, 'routes'> & {\n routes: ContentRouteDefinitions;\n};\n\nexport const CONTENT_ROUTE_MODULE: ContentRouteModule = {\n packageName: '@happyvertical/smrt-content',\n displayName: 'Content',\n description:\n 'Package-owned route surfaces for authoring, facts, governance, contributions, and published article rendering.',\n routes: {\n workspace: {\n ...CONTENT_ROUTE_META.workspace,\n component: ContentWorkspaceRoute,\n tags: ['content', 'authoring', 'admin'],\n },\n facts: {\n ...CONTENT_ROUTE_META.facts,\n component: ContentFactsRoute,\n tags: ['content', 'facts', 'admin'],\n },\n governance: {\n ...CONTENT_ROUTE_META.governance,\n component: ContentGovernanceRoute,\n tags: ['content', 'governance', 'admin'],\n },\n contributions: {\n ...CONTENT_ROUTE_META.contributions,\n component: ContentContributionsRoute,\n tags: ['content', 'contributions', 'admin'],\n },\n article: {\n ...CONTENT_ROUTE_META.article,\n component: PublishedArticleRoute,\n load: loadPublishedArticleRouteData,\n tags: ['content', 'article', 'public'],\n },\n },\n};\n\nexport default CONTENT_ROUTE_MODULE;\n","import type {\n ApiResponse,\n ContentContributionData,\n ContentContributionTypeConfigStateData,\n ContentContributionTypeData,\n ContentContributorData,\n ContentData,\n ContentGovernanceAssignmentData,\n ContentGovernanceDefinitionsData,\n ContentGovernanceProfileData,\n ContentReviewPolicyData,\n FactData,\n ResolvedContentGovernanceData,\n} from './mock-smrt-client.js';\nimport {\n CONTENT_ROUTE_IDS,\n CONTENT_ROUTE_MODULE,\n createContentRouteNavigation,\n} from './route-module.js';\nimport playground from './svelte/playground.js';\n\nconst sampleContents: ContentData[] = [\n {\n id: 'content-workbench-brief',\n slug: 'workbench-editorial-brief',\n title: 'Workbench Editorial Brief',\n description:\n 'A draft content record used to exercise the shared route shell.',\n body: '## Editorial Brief\\n\\nThis fixture is served by the workbench route module so the authoring route can render inline.',\n bodyFormat: 'markdown',\n author: 'Content Systems',\n type: 'article',\n status: 'draft',\n state: 'active',\n source: 'manual',\n factIds: ['fact-workbench-route'],\n createdAt: '2026-03-20T12:00:00.000Z',\n updatedAt: '2026-03-20T12:00:00.000Z',\n },\n {\n id: 'content-workbench-published',\n slug: 'shared-route-workbench',\n title: 'Shared Route Workbench',\n description:\n 'Published sample content with a slug so the workspace can show the public route affordance.',\n body: 'Shared routes render inside one Workbench app instead of redirecting to package-local dev servers.',\n bodyFormat: 'markdown',\n author: 'Content Ops',\n type: 'article',\n status: 'published',\n state: 'active',\n source: 'manual',\n publish_date: '2026-03-21T09:00:00.000Z',\n factIds: ['fact-workbench-route', 'fact-governance-visible'],\n createdAt: '2026-03-19T15:00:00.000Z',\n updatedAt: '2026-03-21T09:00:00.000Z',\n },\n];\n\nconst sampleFacts: FactData[] = [\n {\n id: 'fact-workbench-route',\n textRaw: 'Workbench route demos render inside the shared workbench host.',\n textRefined:\n 'Workbench route demos render inside the shared workbench host.',\n status: 'active',\n domain: 'developer-tools',\n confidence: 0.94,\n sourceCount: 3,\n metadata: {\n package: '@happyvertical/smrt-content',\n source: 'workbench',\n },\n createdAt: '2026-03-20T12:00:00.000Z',\n updatedAt: '2026-03-20T12:00:00.000Z',\n },\n {\n id: 'fact-governance-visible',\n textRaw: 'Governance policies should be visible before publishing.',\n textRefined: 'Governance policies should be visible before publishing.',\n status: 'active',\n domain: 'content-governance',\n confidence: 0.88,\n sourceCount: 2,\n metadata: {\n policy: 'facts',\n },\n createdAt: '2026-03-18T16:00:00.000Z',\n updatedAt: '2026-03-19T10:00:00.000Z',\n },\n];\n\nconst sampleGovernanceDefinitions: ContentGovernanceDefinitionsData = {\n effective: {\n policies: [\n {\n id: 'policy-facts',\n key: 'facts',\n label: 'Facts review',\n kind: 'facts',\n instructions: 'Compare claims against linked facts before publication.',\n enabled: true,\n },\n {\n id: 'policy-style',\n key: 'style',\n label: 'Style review',\n kind: 'custom',\n instructions: 'Apply editorial style and clarity guidelines.',\n enabled: true,\n },\n ],\n profiles: [\n {\n id: 'profile-publication',\n key: 'publication',\n label: 'Publication',\n description: 'Required before governed content can be published.',\n enabled: true,\n requirements: [\n {\n policyKey: 'facts',\n label: 'Facts review',\n blocking: true,\n acceptedStatuses: ['passed'],\n },\n {\n policyKey: 'style',\n label: 'Style review',\n blocking: false,\n acceptedStatuses: ['passed', 'warning'],\n },\n ],\n },\n ],\n assignments: [\n {\n id: 'assignment-article',\n key: 'article',\n label: 'Articles',\n contentType: 'article',\n contentVariant: null,\n enabled: true,\n factLinkingEnabled: true,\n transparencyEnabled: true,\n publicationProfileKey: 'publication',\n correctionProfileKey: null,\n enforcePublishReadiness: true,\n defaultFactRelationship: 'supports',\n },\n ],\n },\n persisted: {\n policies: [\n {\n id: 'policy-style',\n key: 'style',\n label: 'Style review',\n kind: 'custom',\n instructions: 'Apply editorial style and clarity guidelines.',\n enabled: true,\n },\n ],\n profiles: [\n {\n id: 'profile-publication',\n key: 'publication',\n label: 'Publication',\n description: 'Required before governed content can be published.',\n enabled: true,\n requirements: [\n {\n policyKey: 'facts',\n label: 'Facts review',\n blocking: true,\n acceptedStatuses: ['passed'],\n },\n {\n policyKey: 'style',\n label: 'Style review',\n blocking: false,\n acceptedStatuses: ['passed', 'warning'],\n },\n ],\n },\n ],\n assignments: [\n {\n id: 'assignment-article',\n key: 'article',\n label: 'Articles',\n contentType: 'article',\n contentVariant: null,\n enabled: true,\n factLinkingEnabled: true,\n transparencyEnabled: true,\n publicationProfileKey: 'publication',\n correctionProfileKey: null,\n enforcePublishReadiness: true,\n defaultFactRelationship: 'supports',\n },\n ],\n },\n};\n\nconst sampleContributionTypes: ContentContributionTypeData[] = [\n {\n id: 'type-article',\n key: 'article',\n label: 'Article pitch',\n enabled: true,\n allowedChannels: ['web', 'email'],\n allowText: true,\n allowFiles: true,\n allowEmptyText: false,\n intakeRules: {\n requireTitle: true,\n },\n },\n {\n id: 'type-field-report',\n key: 'field-report',\n label: 'Field report',\n enabled: true,\n allowedChannels: ['web'],\n allowText: true,\n allowFiles: false,\n allowEmptyText: false,\n },\n];\n\nconst sampleContributors: ContentContributorData[] = [\n {\n id: 'contributor-taylor',\n email: 'taylor@example.com',\n name: 'Taylor Rowan',\n trustLevel: 'trusted',\n },\n {\n id: 'contributor-jordan',\n email: 'jordan@example.com',\n name: 'Jordan Lee',\n trustLevel: 'new',\n },\n];\n\nconst sampleContributions: ContentContributionData[] = [\n {\n id: 'contribution-spring-guide',\n contributorId: 'contributor-taylor',\n contributionTypeKey: 'article',\n status: 'needs_changes',\n intakeDecision: 'needs_changes',\n channel: 'web',\n title: 'Spring buyer guide',\n description: 'Draft guide with sourcing notes for editorial review.',\n body: 'The spring buyer guide draft includes product comparisons and sourcing notes.',\n contributorEmail: 'taylor@example.com',\n contributorName: 'Taylor Rowan',\n revisionCount: 2,\n editorNotes: 'Please tighten the sourcing notes in the opening section.',\n updatedAt: '2026-03-20T15:18:00.000Z',\n },\n {\n id: 'contribution-field-report',\n contributorId: 'contributor-jordan',\n contributionTypeKey: 'field-report',\n status: 'submitted',\n intakeDecision: 'submitted',\n channel: 'web',\n title: 'Field report: Pacific logistics',\n description: 'Field notes from the Pacific corridor.',\n body: 'Updated shipping windows, route constraints, and operator interviews.',\n contributorEmail: 'jordan@example.com',\n contributorName: 'Jordan Lee',\n revisionCount: 1,\n updatedAt: '2026-03-18T10:40:00.000Z',\n },\n];\n\nfunction cloneValue<T>(value: T): T {\n if (value === undefined) {\n return value;\n }\n\n return JSON.parse(JSON.stringify(value)) as T;\n}\n\nfunction buildResponse<T>(data: T): ApiResponse<T> {\n return {\n data: cloneValue(data),\n success: true,\n };\n}\n\nfunction upsertByIdOrKey<T extends { id?: string; key?: string }>(\n items: T[],\n value: Partial<T>,\n prefix: string,\n): T[] {\n const id = value.id || `${prefix}-${value.key || items.length + 1}`;\n const nextValue = {\n ...value,\n id,\n } as T;\n const index = items.findIndex(\n (item) => item.id === id || Boolean(value.key && item.key === value.key),\n );\n\n if (index === -1) {\n return [...items, nextValue];\n }\n\n const nextItems = [...items];\n nextItems[index] = {\n ...nextItems[index],\n ...nextValue,\n };\n return nextItems;\n}\n\nfunction createContentWorkbenchClient() {\n let contents = cloneValue(sampleContents);\n let facts = cloneValue(sampleFacts);\n let policies = cloneValue(sampleGovernanceDefinitions.effective.policies);\n let profiles = cloneValue(sampleGovernanceDefinitions.effective.profiles);\n let assignments = cloneValue(\n sampleGovernanceDefinitions.effective.assignments,\n );\n let contributionTypes = cloneValue(sampleContributionTypes);\n let contributors = cloneValue(sampleContributors);\n let contributions = cloneValue(sampleContributions);\n\n const getDefinitions = (): ContentGovernanceDefinitionsData => ({\n effective: {\n policies: cloneValue(policies),\n profiles: cloneValue(profiles),\n assignments: cloneValue(assignments),\n },\n persisted: {\n policies: cloneValue(policies),\n profiles: cloneValue(profiles),\n assignments: cloneValue(assignments),\n },\n });\n\n const resolveGovernance = (\n type?: string,\n variant?: string | null,\n ): ResolvedContentGovernanceData => {\n const assignment =\n assignments.find(\n (item) =>\n item.contentType === type &&\n (item.contentVariant || null) === (variant || null),\n ) ||\n assignments.find((item) => item.contentType === type) ||\n assignments[0] ||\n null;\n\n return {\n isGoverned: Boolean(assignment),\n factLinkingEnabled: assignment?.factLinkingEnabled ?? true,\n transparencyEnabled: assignment?.transparencyEnabled ?? true,\n publicationProfileKey: assignment?.publicationProfileKey || null,\n correctionProfileKey: assignment?.correctionProfileKey || null,\n enforcePublishReadiness:\n assignment?.enforcePublishReadiness ?? Boolean(assignment),\n defaultFactRelationship:\n assignment?.defaultFactRelationship || 'supports',\n reviewPolicies: cloneValue(policies),\n availableProfiles: cloneValue(profiles),\n assignment: cloneValue(assignment),\n };\n };\n\n const updateContributionStatus = (\n id: string,\n status: string,\n extra: Partial<ContentContributionData> = {},\n ) => {\n contributions = contributions.map((item) =>\n item.id === id\n ? {\n ...item,\n status,\n intakeDecision: status,\n updatedAt: new Date().toISOString(),\n ...extra,\n }\n : item,\n );\n return contributions.find((item) => item.id === id) || null;\n };\n\n const getContributionTypes = (): ContentContributionTypeConfigStateData => ({\n effective: cloneValue(contributionTypes),\n persisted: cloneValue(contributionTypes),\n });\n\n return {\n contents: {\n list: async () => buildResponse(contents),\n get: async (id: string) =>\n buildResponse(contents.find((item) => item.id === id) || contents[0]),\n create: async (content: Partial<ContentData>) => {\n const nextContent: ContentData = {\n type: 'article',\n status: 'draft',\n state: 'active',\n source: 'manual',\n ...content,\n id: content.id || `content-workbench-${contents.length + 1}`,\n updatedAt: new Date().toISOString(),\n };\n contents = [nextContent, ...contents];\n return buildResponse(nextContent);\n },\n update: async (id: string, updates: Partial<ContentData>) => {\n contents = contents.map((item) =>\n item.id === id\n ? {\n ...item,\n ...updates,\n id,\n updatedAt: new Date().toISOString(),\n }\n : item,\n );\n return buildResponse(\n contents.find((item) => item.id === id) || contents[0],\n );\n },\n delete: async (id: string) => {\n contents = contents.filter((item) => item.id !== id);\n return buildResponse(undefined);\n },\n browseFacts: async (\n query = '',\n _options: Record<string, unknown> = {},\n ) => {\n const normalizedQuery = query.trim().toLowerCase();\n facts = cloneValue(sampleFacts);\n return buildResponse(\n normalizedQuery\n ? facts.filter((fact) =>\n [\n fact.textRaw,\n fact.textRefined,\n fact.domain,\n JSON.stringify(fact.metadata || {}),\n ]\n .join(' ')\n .toLowerCase()\n .includes(normalizedQuery),\n )\n : facts,\n );\n },\n getGovernanceDefinitions: async () => buildResponse(getDefinitions()),\n resolveGovernance: async (options: {\n type?: string;\n variant?: string | null;\n }) => buildResponse(resolveGovernance(options.type, options.variant)),\n },\n contentGovernancePolicies: {\n create: async (policy: Partial<ContentReviewPolicyData>) => {\n policies = upsertByIdOrKey(policies, policy, 'policy');\n return buildResponse(policies[policies.length - 1]);\n },\n update: async (id: string, policy: Partial<ContentReviewPolicyData>) => {\n policies = upsertByIdOrKey(policies, { ...policy, id }, 'policy');\n return buildResponse(\n policies.find((item) => item.id === id) || policies[0],\n );\n },\n delete: async (id: string) => {\n policies = policies.filter((item) => item.id !== id);\n return buildResponse(undefined);\n },\n },\n contentGovernanceProfiles: {\n create: async (profile: Partial<ContentGovernanceProfileData>) => {\n profiles = upsertByIdOrKey(profiles, profile, 'profile');\n return buildResponse(profiles[profiles.length - 1]);\n },\n update: async (\n id: string,\n profile: Partial<ContentGovernanceProfileData>,\n ) => {\n profiles = upsertByIdOrKey(profiles, { ...profile, id }, 'profile');\n return buildResponse(\n profiles.find((item) => item.id === id) || profiles[0],\n );\n },\n delete: async (id: string) => {\n profiles = profiles.filter((item) => item.id !== id);\n return buildResponse(undefined);\n },\n },\n contentGovernanceAssignments: {\n create: async (assignment: Partial<ContentGovernanceAssignmentData>) => {\n assignments = upsertByIdOrKey(assignments, assignment, 'assignment');\n return buildResponse(assignments[assignments.length - 1]);\n },\n update: async (\n id: string,\n assignment: Partial<ContentGovernanceAssignmentData>,\n ) => {\n assignments = upsertByIdOrKey(\n assignments,\n { ...assignment, id },\n 'assignment',\n );\n return buildResponse(\n assignments.find((item) => item.id === id) || assignments[0],\n );\n },\n delete: async (id: string) => {\n assignments = assignments.filter((item) => item.id !== id);\n return buildResponse(undefined);\n },\n },\n contentContributions: {\n getContributionTypes: async () => buildResponse(getContributionTypes()),\n listInbox: async () => buildResponse(contributions),\n listForContributor: async (options: {\n contributorId?: string;\n contributorEmail?: string;\n }) =>\n buildResponse(\n contributions.filter((item) =>\n options.contributorId\n ? item.contributorId === options.contributorId\n : item.contributorEmail === options.contributorEmail,\n ),\n ),\n submitWebContribution: async (\n payload: Partial<ContentContributionData> & {\n typeKey?: string;\n attachments?: unknown[];\n },\n ) => {\n const contributor = contributors.find(\n (item) => item.email === payload.contributorEmail,\n );\n const nextContribution: ContentContributionData = {\n id: `contribution-workbench-${contributions.length + 1}`,\n contributorId: contributor?.id,\n contributionTypeKey: payload.typeKey || payload.contributionTypeKey,\n status: 'submitted',\n intakeDecision: 'submitted',\n channel: 'web',\n title: payload.title,\n description: payload.description,\n body: payload.body,\n contributorEmail: payload.contributorEmail,\n contributorName: payload.contributorName,\n revisionCount: 1,\n updatedAt: new Date().toISOString(),\n };\n contributions = [nextContribution, ...contributions];\n return buildResponse({\n contribution: nextContribution,\n });\n },\n ingestEmailContribution: async (\n payload: Partial<ContentContributionData>,\n ) =>\n buildResponse({\n contribution: {\n ...payload,\n id: `contribution-email-${contributions.length + 1}`,\n status: 'submitted',\n },\n }),\n appendRevision: async (id: string) =>\n buildResponse(\n updateContributionStatus(id, 'submitted', {\n revisionCount:\n (contributions.find((item) => item.id === id)?.revisionCount ||\n 0) + 1,\n }),\n ),\n requestChanges: async (id: string) =>\n buildResponse(updateContributionStatus(id, 'needs_changes')),\n approve: async (id: string) =>\n buildResponse(\n updateContributionStatus(id, 'approved', {\n approvedAt: new Date().toISOString(),\n }),\n ),\n reject: async (id: string) =>\n buildResponse(\n updateContributionStatus(id, 'rejected', {\n rejectedAt: new Date().toISOString(),\n }),\n ),\n withdraw: async (id: string) =>\n buildResponse(\n updateContributionStatus(id, 'withdrawn', {\n withdrawnAt: new Date().toISOString(),\n }),\n ),\n promote: async (id: string) =>\n buildResponse(\n updateContributionStatus(id, 'promoted', {\n promotedAt: new Date().toISOString(),\n }),\n ),\n },\n contentContributionTypes: {\n create: async (type: Partial<ContentContributionTypeData>) => {\n contributionTypes = upsertByIdOrKey(\n contributionTypes,\n type,\n 'contribution-type',\n );\n return buildResponse(contributionTypes[contributionTypes.length - 1]);\n },\n update: async (\n id: string,\n type: Partial<ContentContributionTypeData>,\n ) => {\n contributionTypes = upsertByIdOrKey(\n contributionTypes,\n { ...type, id },\n 'contribution-type',\n );\n return buildResponse(\n contributionTypes.find((item) => item.id === id) ||\n contributionTypes[0],\n );\n },\n delete: async (id: string) => {\n contributionTypes = contributionTypes.filter((item) => item.id !== id);\n return buildResponse(undefined);\n },\n },\n contentContributors: {\n list: async () => buildResponse(contributors),\n create: async (contributor: Partial<ContentContributorData>) => {\n const nextContributor: ContentContributorData = {\n ...contributor,\n id: contributor.id || `contributor-${contributors.length + 1}`,\n };\n contributors = [nextContributor, ...contributors];\n return buildResponse(nextContributor);\n },\n update: async (\n id: string,\n contributor: Partial<ContentContributorData>,\n ) => {\n contributors = contributors.map((item) =>\n item.id === id ? { ...item, ...contributor, id } : item,\n );\n return buildResponse(\n contributors.find((item) => item.id === id) || contributors[0],\n );\n },\n delete: async (id: string) => {\n contributors = contributors.filter((item) => item.id !== id);\n return buildResponse(undefined);\n },\n },\n };\n}\n\nconst contentWorkbenchClient = createContentWorkbenchClient();\nconst contentWorkbenchNavigation = createContentRouteNavigation({\n [CONTENT_ROUTE_IDS.workspace]: '#content-workspace',\n [CONTENT_ROUTE_IDS.facts]: '#content-facts',\n [CONTENT_ROUTE_IDS.governance]: '#content-governance',\n [CONTENT_ROUTE_IDS.contributions]: '#content-contributions',\n});\nconst contentRouteProps = {\n embedded: true,\n client: contentWorkbenchClient,\n navigation: contentWorkbenchNavigation,\n};\n\nconst articleRouteData = {\n content: {\n id: 'workbench-article',\n slug: 'workbench-reference-article',\n title: 'Workbench Reference Article',\n description:\n 'Inline route sample rendered inside the shared SMRT workbench.',\n author: 'Content Systems',\n body: '## Reference Article\\n\\nThis article route is rendered without redirecting to a package-local dev server.',\n bodyFormat: 'markdown',\n publish_date: '2026-03-20T12:00:00.000Z',\n status: 'published',\n },\n transparency: null,\n};\n\nconst routeModule = {\n ...CONTENT_ROUTE_MODULE,\n routes: {\n workspace: {\n ...CONTENT_ROUTE_MODULE.routes.workspace,\n props: contentRouteProps,\n },\n facts: {\n ...CONTENT_ROUTE_MODULE.routes.facts,\n props: contentRouteProps,\n },\n governance: {\n ...CONTENT_ROUTE_MODULE.routes.governance,\n props: contentRouteProps,\n },\n contributions: {\n ...CONTENT_ROUTE_MODULE.routes.contributions,\n props: contentRouteProps,\n },\n article: {\n ...CONTENT_ROUTE_MODULE.routes.article,\n props: {\n data: articleRouteData,\n backHref: '#content-workspace',\n },\n },\n },\n};\n\nexport default {\n packageName: '@happyvertical/smrt-content',\n displayName: 'Content',\n description:\n 'Workbench surfaces for content authoring, governance, facts, contributions, articles, and package previews.',\n routeModules: [routeModule],\n recommendedCommands: [\n {\n id: 'content:test',\n label: 'Test',\n command: 'pnpm --filter @happyvertical/smrt-content test',\n },\n {\n id: 'content:typecheck',\n label: 'Typecheck',\n command: 'pnpm --filter @happyvertical/smrt-content typecheck',\n },\n ],\n examples: [\n {\n id: 'content:playground',\n title: 'Content playground module',\n path: 'src/svelte/playground.ts',\n source: 'playground',\n },\n ],\n};\n\nexport { playground };\n"],"mappings":";;;;;;;AAeA,SAAS,4BACP,QACA,SACA,MACuB;CACvB,MAAM,QAAQ,IAAI,MAAM,OAAO;CAC/B,MAAM,OAAO;CACb,MAAM,SAAS;CACf,MAAM,OAAO;CACb,OAAO;AACT;AAYA,SAAS,YAAe,SAAqB;CAC3C,IAAI,CAAC,WAAW,OAAO,YAAY,UACjC,OAAO;CAGT,MAAM,iBAAiB;CACvB,IAAI,YAAY,gBACd,OAAO,eAAe;CAGxB,IAAI,UAAU,gBACZ,OAAO,eAAe;CAGxB,OAAO;AACT;AAEA,eAAsB,8BAA8B,EAClD,OACA,MACA,cAAc,aAC8D;CAM5E,MAAM,kBAAkB,MAAM,MAC5B,GAAG,YAAW,oBAAqB,IANZ,gBAAgB;EACvC;EACA,QAAQ;CACV,CAGqC,CAAA,CAAa,SAAS,GAC3D;CAEA,IAAI,CAAC,gBAAgB,IACnB,MAAM,4BACJ,gBAAgB,QAChB,0BACA,sBACF;CAIF,MAAM,UAAU,YAAgC,MADnB,gBAAgB,KAAK,CACY;CAE9D,IAAI,CAAC,SAAS,IACZ,MAAM,4BACJ,KACA,qBACA,mBACF;CAGF,MAAM,uBAAuB,MAAM,MACjC,GAAG,YAAW,YAAa,QAAQ,GAAE,cACvC;CAEA,IAAI,CAAC,qBAAqB,IACxB,MAAM,4BACJ,qBAAqB,QACrB,+BACA,2BACF;CAQF,OAAO;EACL;EACA,cANmB,YACnB,MAFgC,qBAAqB,KAAK,CAO1D;CACF;AACF;;;AClGO,IAAM,oBAAoB;CAC/B,WAAW;CACX,OAAO;CACP,YAAY;CACZ,eAAe;CACf,SAAS;AACX;AA6BO,IAAM,qBAAqB;CAChC,WAAW;EACT,IAAI,kBAAkB;EACtB,OAAO;EACP,aACE;EACF,aAAa;EACb,KAAK;GACH,OAAO;GACP,aAAa;GACb,MAAM;GACN,OAAO;GACP,OAAO;EACT;CACF;CACA,YAAY;EACV,IAAI,kBAAkB;EACtB,OAAO;EACP,aACE;EACF,aAAa;EACb,KAAK;GACH,OAAO;GACP,aAAa;GACb,MAAM;GACN,OAAO;GACP,OAAO;EACT;CACF;CACA,OAAO;EACL,IAAI,kBAAkB;EACtB,OAAO;EACP,aACE;EACF,aAAa;EACb,KAAK;GACH,OAAO;GACP,aAAa;GACb,MAAM;GACN,OAAO;GACP,OAAO;EACT;CACF;CACA,eAAe;EACb,IAAI,kBAAkB;EACtB,OAAO;EACP,aACE;EACF,aAAa;EACb,KAAK;GACH,OAAO;GACP,aAAa;GACb,MAAM;GACN,OAAO;GACP,OAAO;EACT;CACF;CACA,SAAS;EACP,IAAI,kBAAkB;EACtB,OAAO;EACP,aACE;EACF,aAAa;EACb,UAAU;CACZ;AACF;AAIA,IAAM,yBAAyB;CAC7B;CACA;CACA;CACA;AACF;AAqBO,SAAS,6BACd,gBAAyD,CAAC,GAC5B;CAC9B,OAAO,uBAAuB,KAAK,aAAa;EAC9C,MAAM,QAAQ,mBAAmB;EAEjC,OAAO;GACL,SAAS,MAAM;GACf,MAAM,cAAc,MAAM,OAAO,MAAM;GACvC,OAAO,MAAM,IAAI;GACjB,aAAa,MAAM,IAAI;GACvB,MAAM,MAAM,IAAI;GAChB,OAAO,MAAM,IAAI;GACjB,OAAO,MAAM,IAAI;EACnB;CACF,CAAC,CAAA,CAAE,MAAM,MAAM,WAAW,KAAK,SAAS,MAAM,MAAM,SAAS,EAAE;AACjE;AAEgD,6BAA6B;;;AClEtE,IAAM,uBAA2C;CACtD,aAAa;CACb,aAAa;CACb,aACE;CACF,QAAQ;EACN,WAAW;GACT,GAAG,mBAAmB;GACtB,WAAW;GACX,MAAM;IAAC;IAAW;IAAa;GAAO;EACxC;EACA,OAAO;GACL,GAAG,mBAAmB;GACtB,WAAW;GACX,MAAM;IAAC;IAAW;IAAS;GAAO;EACpC;EACA,YAAY;GACV,GAAG,mBAAmB;GACtB,WAAW;GACX,MAAM;IAAC;IAAW;IAAc;GAAO;EACzC;EACA,eAAe;GACb,GAAG,mBAAmB;GACtB,WAAW;GACX,MAAM;IAAC;IAAW;IAAiB;GAAO;EAC5C;EACA,SAAS;GACP,GAAG,mBAAmB;GACtB,WAAW;GACX,MAAM;GACN,MAAM;IAAC;IAAW;IAAW;GAAQ;EACvC;CACF;AACF;;;ACxGA,IAAM,iBAAgC,CACpC;CACE,IAAI;CACJ,MAAM;CACN,OAAO;CACP,aACE;CACF,MAAM;CACN,YAAY;CACZ,QAAQ;CACR,MAAM;CACN,QAAQ;CACR,OAAO;CACP,QAAQ;CACR,SAAS,CAAC,sBAAsB;CAChC,WAAW;CACX,WAAW;AACb,GACA;CACE,IAAI;CACJ,MAAM;CACN,OAAO;CACP,aACE;CACF,MAAM;CACN,YAAY;CACZ,QAAQ;CACR,MAAM;CACN,QAAQ;CACR,OAAO;CACP,QAAQ;CACR,cAAc;CACd,SAAS,CAAC,wBAAwB,yBAAyB;CAC3D,WAAW;CACX,WAAW;AACb,CACF;AAEA,IAAM,cAA0B,CAC9B;CACE,IAAI;CACJ,SAAS;CACT,aACE;CACF,QAAQ;CACR,QAAQ;CACR,YAAY;CACZ,aAAa;CACb,UAAU;EACR,SAAS;EACT,QAAQ;CACV;CACA,WAAW;CACX,WAAW;AACb,GACA;CACE,IAAI;CACJ,SAAS;CACT,aAAa;CACb,QAAQ;CACR,QAAQ;CACR,YAAY;CACZ,aAAa;CACb,UAAU,EACR,QAAQ,QACV;CACA,WAAW;CACX,WAAW;AACb,CACF;AAEA,IAAM,8BAAgE;CACpE,WAAW;EACT,UAAU,CACR;GACE,IAAI;GACJ,KAAK;GACL,OAAO;GACP,MAAM;GACN,cAAc;GACd,SAAS;EACX,GACA;GACE,IAAI;GACJ,KAAK;GACL,OAAO;GACP,MAAM;GACN,cAAc;GACd,SAAS;EACX,CACF;EACA,UAAU,CACR;GACE,IAAI;GACJ,KAAK;GACL,OAAO;GACP,aAAa;GACb,SAAS;GACT,cAAc,CACZ;IACE,WAAW;IACX,OAAO;IACP,UAAU;IACV,kBAAkB,CAAC,QAAQ;GAC7B,GACA;IACE,WAAW;IACX,OAAO;IACP,UAAU;IACV,kBAAkB,CAAC,UAAU,SAAS;GACxC,CACF;EACF,CACF;EACA,aAAa,CACX;GACE,IAAI;GACJ,KAAK;GACL,OAAO;GACP,aAAa;GACb,gBAAgB;GAChB,SAAS;GACT,oBAAoB;GACpB,qBAAqB;GACrB,uBAAuB;GACvB,sBAAsB;GACtB,yBAAyB;GACzB,yBAAyB;EAC3B,CACF;CACF;CACA,WAAW;EACT,UAAU,CACR;GACE,IAAI;GACJ,KAAK;GACL,OAAO;GACP,MAAM;GACN,cAAc;GACd,SAAS;EACX,CACF;EACA,UAAU,CACR;GACE,IAAI;GACJ,KAAK;GACL,OAAO;GACP,aAAa;GACb,SAAS;GACT,cAAc,CACZ;IACE,WAAW;IACX,OAAO;IACP,UAAU;IACV,kBAAkB,CAAC,QAAQ;GAC7B,GACA;IACE,WAAW;IACX,OAAO;IACP,UAAU;IACV,kBAAkB,CAAC,UAAU,SAAS;GACxC,CACF;EACF,CACF;EACA,aAAa,CACX;GACE,IAAI;GACJ,KAAK;GACL,OAAO;GACP,aAAa;GACb,gBAAgB;GAChB,SAAS;GACT,oBAAoB;GACpB,qBAAqB;GACrB,uBAAuB;GACvB,sBAAsB;GACtB,yBAAyB;GACzB,yBAAyB;EAC3B,CACF;CACF;AACF;AAEA,IAAM,0BAAyD,CAC7D;CACE,IAAI;CACJ,KAAK;CACL,OAAO;CACP,SAAS;CACT,iBAAiB,CAAC,OAAO,OAAO;CAChC,WAAW;CACX,YAAY;CACZ,gBAAgB;CAChB,aAAa,EACX,cAAc,KAChB;AACF,GACA;CACE,IAAI;CACJ,KAAK;CACL,OAAO;CACP,SAAS;CACT,iBAAiB,CAAC,KAAK;CACvB,WAAW;CACX,YAAY;CACZ,gBAAgB;AAClB,CACF;AAEA,IAAM,qBAA+C,CACnD;CACE,IAAI;CACJ,OAAO;CACP,MAAM;CACN,YAAY;AACd,GACA;CACE,IAAI;CACJ,OAAO;CACP,MAAM;CACN,YAAY;AACd,CACF;AAEA,IAAM,sBAAiD,CACrD;CACE,IAAI;CACJ,eAAe;CACf,qBAAqB;CACrB,QAAQ;CACR,gBAAgB;CAChB,SAAS;CACT,OAAO;CACP,aAAa;CACb,MAAM;CACN,kBAAkB;CAClB,iBAAiB;CACjB,eAAe;CACf,aAAa;CACb,WAAW;AACb,GACA;CACE,IAAI;CACJ,eAAe;CACf,qBAAqB;CACrB,QAAQ;CACR,gBAAgB;CAChB,SAAS;CACT,OAAO;CACP,aAAa;CACb,MAAM;CACN,kBAAkB;CAClB,iBAAiB;CACjB,eAAe;CACf,WAAW;AACb,CACF;AAEA,SAAS,WAAc,OAAa;CAClC,IAAI,UAAU,KAAA,GACZ,OAAO;CAGT,OAAO,KAAK,MAAM,KAAK,UAAU,KAAK,CAAC;AACzC;AAEA,SAAS,cAAiB,MAAyB;CACjD,OAAO;EACL,MAAM,WAAW,IAAI;EACrB,SAAS;CACX;AACF;AAEA,SAAS,gBACP,OACA,OACA,QACK;CACL,MAAM,KAAK,MAAM,MAAM,GAAG,OAAM,GAAI,MAAM,OAAO,MAAM,SAAS;CAChE,MAAM,YAAY;EAChB,GAAG;EACH;CACF;CACA,MAAM,QAAQ,MAAM,WACjB,SAAS,KAAK,OAAO,MAAM,QAAQ,MAAM,OAAO,KAAK,QAAQ,MAAM,GAAG,CACzE;CAEA,IAAI,UAAU,IACZ,OAAO,CAAC,GAAG,OAAO,SAAS;CAG7B,MAAM,YAAY,CAAC,GAAG,KAAK;CAC3B,UAAU,SAAS;EACjB,GAAG,UAAU;EACb,GAAG;CACL;CACA,OAAO;AACT;AAEA,SAAS,+BAA+B;CACtC,IAAI,WAAW,WAAW,cAAc;CACxC,IAAI,QAAQ,WAAW,WAAW;CAClC,IAAI,WAAW,WAAW,4BAA4B,UAAU,QAAQ;CACxE,IAAI,WAAW,WAAW,4BAA4B,UAAU,QAAQ;CACxE,IAAI,cAAc,WAChB,4BAA4B,UAAU,WACxC;CACA,IAAI,oBAAoB,WAAW,uBAAuB;CAC1D,IAAI,eAAe,WAAW,kBAAkB;CAChD,IAAI,gBAAgB,WAAW,mBAAmB;CAElD,MAAM,wBAA0D;EAC9D,WAAW;GACT,UAAU,WAAW,QAAQ;GAC7B,UAAU,WAAW,QAAQ;GAC7B,aAAa,WAAW,WAAW;EACrC;EACA,WAAW;GACT,UAAU,WAAW,QAAQ;GAC7B,UAAU,WAAW,QAAQ;GAC7B,aAAa,WAAW,WAAW;EACrC;CACF;CAEA,MAAM,qBACJ,MACA,YACkC;EAClC,MAAM,aACJ,YAAY,MACT,SACC,KAAK,gBAAgB,SACpB,KAAK,kBAAkB,WAAW,WAAW,KAClD,KACA,YAAY,MAAM,SAAS,KAAK,gBAAgB,IAAI,KACpD,YAAY,MACZ;EAEF,OAAO;GACL,YAAY,QAAQ,UAAU;GAC9B,oBAAoB,YAAY,sBAAsB;GACtD,qBAAqB,YAAY,uBAAuB;GACxD,uBAAuB,YAAY,yBAAyB;GAC5D,sBAAsB,YAAY,wBAAwB;GAC1D,yBACE,YAAY,2BAA2B,QAAQ,UAAU;GAC3D,yBACE,YAAY,2BAA2B;GACzC,gBAAgB,WAAW,QAAQ;GACnC,mBAAmB,WAAW,QAAQ;GACtC,YAAY,WAAW,UAAU;EACnC;CACF;CAEA,MAAM,4BACJ,IACA,QACA,QAA0C,CAAC,MACxC;EACH,gBAAgB,cAAc,KAAK,SACjC,KAAK,OAAO,KACR;GACE,GAAG;GACH;GACA,gBAAgB;GAChB,4BAAW,IAAI,KAAK,EAAA,CAAE,YAAY;GAClC,GAAG;EACL,IACA,IACN;EACA,OAAO,cAAc,MAAM,SAAS,KAAK,OAAO,EAAE,KAAK;CACzD;CAEA,MAAM,8BAAsE;EAC1E,WAAW,WAAW,iBAAiB;EACvC,WAAW,WAAW,iBAAiB;CACzC;CAEA,OAAO;EACL,UAAU;GACR,MAAM,YAAY,cAAc,QAAQ;GACxC,KAAK,OAAO,OACV,cAAc,SAAS,MAAM,SAAS,KAAK,OAAO,EAAE,KAAK,SAAS,EAAE;GACtE,QAAQ,OAAO,YAAkC;IAC/C,MAAM,cAA2B;KAC/B,MAAM;KACN,QAAQ;KACR,OAAO;KACP,QAAQ;KACR,GAAG;KACH,IAAI,QAAQ,MAAM,qBAAqB,SAAS,SAAS;KACzD,4BAAW,IAAI,KAAK,EAAA,CAAE,YAAY;IACpC;IACA,WAAW,CAAC,aAAa,GAAG,QAAQ;IACpC,OAAO,cAAc,WAAW;GAClC;GACA,QAAQ,OAAO,IAAY,YAAkC;IAC3D,WAAW,SAAS,KAAK,SACvB,KAAK,OAAO,KACR;KACE,GAAG;KACH,GAAG;KACH;KACA,4BAAW,IAAI,KAAK,EAAA,CAAE,YAAY;IACpC,IACA,IACN;IACA,OAAO,cACL,SAAS,MAAM,SAAS,KAAK,OAAO,EAAE,KAAK,SAAS,EACtD;GACF;GACA,QAAQ,OAAO,OAAe;IAC5B,WAAW,SAAS,QAAQ,SAAS,KAAK,OAAO,EAAE;IACnD,OAAO,cAAc,KAAA,CAAS;GAChC;GACA,aAAa,OACX,QAAQ,IACR,WAAoC,CAAC,MAClC;IACH,MAAM,kBAAkB,MAAM,KAAK,CAAA,CAAE,YAAY;IACjD,QAAQ,WAAW,WAAW;IAC9B,OAAO,cACL,kBACI,MAAM,QAAQ,SACZ;KACE,KAAK;KACL,KAAK;KACL,KAAK;KACL,KAAK,UAAU,KAAK,YAAY,CAAC,CAAC;IACpC,CAAA,CACG,KAAK,GAAG,CAAA,CACR,YAAY,CAAA,CACZ,SAAS,eAAe,CAC7B,IACA,KACN;GACF;GACA,0BAA0B,YAAY,cAAc,eAAe,CAAC;GACpE,mBAAmB,OAAO,YAGpB,cAAc,kBAAkB,QAAQ,MAAM,QAAQ,OAAO,CAAC;EACtE;EACA,2BAA2B;GACzB,QAAQ,OAAO,WAA6C;IAC1D,WAAW,gBAAgB,UAAU,QAAQ,QAAQ;IACrD,OAAO,cAAc,SAAS,SAAS,SAAS,EAAE;GACpD;GACA,QAAQ,OAAO,IAAY,WAA6C;IACtE,WAAW,gBAAgB,UAAU;KAAE,GAAG;KAAQ;IAAG,GAAG,QAAQ;IAChE,OAAO,cACL,SAAS,MAAM,SAAS,KAAK,OAAO,EAAE,KAAK,SAAS,EACtD;GACF;GACA,QAAQ,OAAO,OAAe;IAC5B,WAAW,SAAS,QAAQ,SAAS,KAAK,OAAO,EAAE;IACnD,OAAO,cAAc,KAAA,CAAS;GAChC;EACF;EACA,2BAA2B;GACzB,QAAQ,OAAO,YAAmD;IAChE,WAAW,gBAAgB,UAAU,SAAS,SAAS;IACvD,OAAO,cAAc,SAAS,SAAS,SAAS,EAAE;GACpD;GACA,QAAQ,OACN,IACA,YACG;IACH,WAAW,gBAAgB,UAAU;KAAE,GAAG;KAAS;IAAG,GAAG,SAAS;IAClE,OAAO,cACL,SAAS,MAAM,SAAS,KAAK,OAAO,EAAE,KAAK,SAAS,EACtD;GACF;GACA,QAAQ,OAAO,OAAe;IAC5B,WAAW,SAAS,QAAQ,SAAS,KAAK,OAAO,EAAE;IACnD,OAAO,cAAc,KAAA,CAAS;GAChC;EACF;EACA,8BAA8B;GAC5B,QAAQ,OAAO,eAAyD;IACtE,cAAc,gBAAgB,aAAa,YAAY,YAAY;IACnE,OAAO,cAAc,YAAY,YAAY,SAAS,EAAE;GAC1D;GACA,QAAQ,OACN,IACA,eACG;IACH,cAAc,gBACZ,aACA;KAAE,GAAG;KAAY;IAAG,GACpB,YACF;IACA,OAAO,cACL,YAAY,MAAM,SAAS,KAAK,OAAO,EAAE,KAAK,YAAY,EAC5D;GACF;GACA,QAAQ,OAAO,OAAe;IAC5B,cAAc,YAAY,QAAQ,SAAS,KAAK,OAAO,EAAE;IACzD,OAAO,cAAc,KAAA,CAAS;GAChC;EACF;EACA,sBAAsB;GACpB,sBAAsB,YAAY,cAAc,qBAAqB,CAAC;GACtE,WAAW,YAAY,cAAc,aAAa;GAClD,oBAAoB,OAAO,YAIzB,cACE,cAAc,QAAQ,SACpB,QAAQ,gBACJ,KAAK,kBAAkB,QAAQ,gBAC/B,KAAK,qBAAqB,QAAQ,gBACxC,CACF;GACF,uBAAuB,OACrB,YAIG;IACH,MAAM,cAAc,aAAa,MAC9B,SAAS,KAAK,UAAU,QAAQ,gBACnC;IACA,MAAM,mBAA4C;KAChD,IAAI,0BAA0B,cAAc,SAAS;KACrD,eAAe,aAAa;KAC5B,qBAAqB,QAAQ,WAAW,QAAQ;KAChD,QAAQ;KACR,gBAAgB;KAChB,SAAS;KACT,OAAO,QAAQ;KACf,aAAa,QAAQ;KACrB,MAAM,QAAQ;KACd,kBAAkB,QAAQ;KAC1B,iBAAiB,QAAQ;KACzB,eAAe;KACf,4BAAW,IAAI,KAAK,EAAA,CAAE,YAAY;IACpC;IACA,gBAAgB,CAAC,kBAAkB,GAAG,aAAa;IACnD,OAAO,cAAc,EACnB,cAAc,iBAChB,CAAC;GACH;GACA,yBAAyB,OACvB,YAEA,cAAc,EACZ,cAAc;IACZ,GAAG;IACH,IAAI,sBAAsB,cAAc,SAAS;IACjD,QAAQ;GACV,EACF,CAAC;GACH,gBAAgB,OAAO,OACrB,cACE,yBAAyB,IAAI,aAAa,EACxC,gBACG,cAAc,MAAM,SAAS,KAAK,OAAO,EAAE,CAAA,EAAG,iBAC7C,KAAK,EACX,CAAC,CACH;GACF,gBAAgB,OAAO,OACrB,cAAc,yBAAyB,IAAI,eAAe,CAAC;GAC7D,SAAS,OAAO,OACd,cACE,yBAAyB,IAAI,YAAY,EACvC,6BAAY,IAAI,KAAK,EAAA,CAAE,YAAY,EACrC,CAAC,CACH;GACF,QAAQ,OAAO,OACb,cACE,yBAAyB,IAAI,YAAY,EACvC,6BAAY,IAAI,KAAK,EAAA,CAAE,YAAY,EACrC,CAAC,CACH;GACF,UAAU,OAAO,OACf,cACE,yBAAyB,IAAI,aAAa,EACxC,8BAAa,IAAI,KAAK,EAAA,CAAE,YAAY,EACtC,CAAC,CACH;GACF,SAAS,OAAO,OACd,cACE,yBAAyB,IAAI,YAAY,EACvC,6BAAY,IAAI,KAAK,EAAA,CAAE,YAAY,EACrC,CAAC,CACH;EACJ;EACA,0BAA0B;GACxB,QAAQ,OAAO,SAA+C;IAC5D,oBAAoB,gBAClB,mBACA,MACA,mBACF;IACA,OAAO,cAAc,kBAAkB,kBAAkB,SAAS,EAAE;GACtE;GACA,QAAQ,OACN,IACA,SACG;IACH,oBAAoB,gBAClB,mBACA;KAAE,GAAG;KAAM;IAAG,GACd,mBACF;IACA,OAAO,cACL,kBAAkB,MAAM,SAAS,KAAK,OAAO,EAAE,KAC7C,kBAAkB,EACtB;GACF;GACA,QAAQ,OAAO,OAAe;IAC5B,oBAAoB,kBAAkB,QAAQ,SAAS,KAAK,OAAO,EAAE;IACrE,OAAO,cAAc,KAAA,CAAS;GAChC;EACF;EACA,qBAAqB;GACnB,MAAM,YAAY,cAAc,YAAY;GAC5C,QAAQ,OAAO,gBAAiD;IAC9D,MAAM,kBAA0C;KAC9C,GAAG;KACH,IAAI,YAAY,MAAM,eAAe,aAAa,SAAS;IAC7D;IACA,eAAe,CAAC,iBAAiB,GAAG,YAAY;IAChD,OAAO,cAAc,eAAe;GACtC;GACA,QAAQ,OACN,IACA,gBACG;IACH,eAAe,aAAa,KAAK,SAC/B,KAAK,OAAO,KAAK;KAAE,GAAG;KAAM,GAAG;KAAa;IAAG,IAAI,IACrD;IACA,OAAO,cACL,aAAa,MAAM,SAAS,KAAK,OAAO,EAAE,KAAK,aAAa,EAC9D;GACF;GACA,QAAQ,OAAO,OAAe;IAC5B,eAAe,aAAa,QAAQ,SAAS,KAAK,OAAO,EAAE;IAC3D,OAAO,cAAc,KAAA,CAAS;GAChC;EACF;CACF;AACF;AASA,IAAM,oBAAoB;CACxB,UAAU;CACV,QAT6B,6BASrB;CACR,YATiC,6BAA6B;GAC7D,kBAAkB,YAAY;GAC9B,kBAAkB,QAAQ;GAC1B,kBAAkB,aAAa;GAC/B,kBAAkB,gBAAgB;CACrC,CAIc;AACd;AAEA,IAAM,mBAAmB;CACvB,SAAS;EACP,IAAI;EACJ,MAAM;EACN,OAAO;EACP,aACE;EACF,QAAQ;EACR,MAAM;EACN,YAAY;EACZ,cAAc;EACd,QAAQ;CACV;CACA,cAAc;AAChB;AA+BA,IAAA,oBAAe;CACb,aAAa;CACb,aAAa;CACb,aACE;CACF,cAAc,CAAC;EAjCf,GAAG;EACH,QAAQ;GACN,WAAW;IACT,GAAG,qBAAqB,OAAO;IAC/B,OAAO;GACT;GACA,OAAO;IACL,GAAG,qBAAqB,OAAO;IAC/B,OAAO;GACT;GACA,YAAY;IACV,GAAG,qBAAqB,OAAO;IAC/B,OAAO;GACT;GACA,eAAe;IACb,GAAG,qBAAqB,OAAO;IAC/B,OAAO;GACT;GACA,SAAS;IACP,GAAG,qBAAqB,OAAO;IAC/B,OAAO;KACL,MAAM;KACN,UAAU;IACZ;GACF;EACF;CAQe,CAAW;CAC1B,qBAAqB,CACnB;EACE,IAAI;EACJ,OAAO;EACP,SAAS;CACX,GACA;EACE,IAAI;EACJ,OAAO;EACP,SAAS;CACX,CACF;CACA,UAAU,CACR;EACE,IAAI;EACJ,OAAO;EACP,MAAM;EACN,QAAQ;CACV,CACF;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-content",
3
- "version": "0.40.65",
3
+ "version": "0.40.67",
4
4
  "description": "Content processing module for SMRT framework - handles documents, web content, and media",
5
5
  "type": "module",
6
6
  "smrtRawPrimitives": "strict",
@@ -34,33 +34,37 @@
34
34
  "./playground": {
35
35
  "types": "./dist/playground.d.ts",
36
36
  "import": "./dist/playground.js"
37
+ },
38
+ "./workbench": {
39
+ "types": "./dist/workbench.d.ts",
40
+ "import": "./dist/workbench.js"
37
41
  }
38
42
  },
39
43
  "dependencies": {
40
- "@happyvertical/ai": "^0.86.1",
41
- "@happyvertical/documents": "^0.86.1",
42
- "@happyvertical/files": "^0.86.1",
43
- "@happyvertical/geo": "^0.86.1",
44
- "@happyvertical/images": "^0.86.1",
45
- "@happyvertical/logger": "^0.86.1",
44
+ "@happyvertical/ai": "^0.86.3",
45
+ "@happyvertical/documents": "^0.86.3",
46
+ "@happyvertical/files": "^0.86.3",
47
+ "@happyvertical/geo": "^0.86.3",
48
+ "@happyvertical/images": "^0.86.3",
49
+ "@happyvertical/logger": "^0.86.3",
46
50
  "@happyvertical/ocr": "^0.61.4",
47
51
  "@happyvertical/pdf": "^0.65.9",
48
52
  "@happyvertical/spider": "^1.1.13",
49
- "@happyvertical/sql": "^0.86.1",
50
- "@happyvertical/utils": "^0.86.1",
53
+ "@happyvertical/sql": "^0.86.3",
54
+ "@happyvertical/utils": "^0.86.3",
51
55
  "fast-xml-parser": "^5.10.1",
52
56
  "yaml": "^2.9.0",
53
- "@happyvertical/smrt-assets": "0.40.65",
54
- "@happyvertical/smrt-chat": "0.40.65",
55
- "@happyvertical/smrt-core": "0.40.65",
56
- "@happyvertical/smrt-facts": "0.40.65",
57
- "@happyvertical/smrt-images": "0.40.65",
58
- "@happyvertical/smrt-messages": "0.40.65",
59
- "@happyvertical/smrt-prompts": "0.40.65",
60
- "@happyvertical/smrt-profiles": "0.40.65",
61
- "@happyvertical/smrt-tenancy": "0.40.65",
62
- "@happyvertical/smrt-types": "0.40.65",
63
- "@happyvertical/smrt-ui": "0.40.65"
57
+ "@happyvertical/smrt-assets": "0.40.67",
58
+ "@happyvertical/smrt-chat": "0.40.67",
59
+ "@happyvertical/smrt-core": "0.40.67",
60
+ "@happyvertical/smrt-facts": "0.40.67",
61
+ "@happyvertical/smrt-images": "0.40.67",
62
+ "@happyvertical/smrt-messages": "0.40.67",
63
+ "@happyvertical/smrt-prompts": "0.40.67",
64
+ "@happyvertical/smrt-profiles": "0.40.67",
65
+ "@happyvertical/smrt-tenancy": "0.40.67",
66
+ "@happyvertical/smrt-types": "0.40.67",
67
+ "@happyvertical/smrt-ui": "0.40.67"
64
68
  },
65
69
  "peerDependencies": {
66
70
  "svelte": "^5.56.4"
@@ -81,8 +85,8 @@
81
85
  "typescript": "5.9.3",
82
86
  "vite": "8.1.4",
83
87
  "vitest": "4.1.10",
84
- "@happyvertical/smrt-playground": "0.40.65",
85
- "@happyvertical/smrt-vitest": "0.40.65"
88
+ "@happyvertical/smrt-playground": "0.40.67",
89
+ "@happyvertical/smrt-vitest": "0.40.67"
86
90
  },
87
91
  "keywords": [
88
92
  "ai",
@@ -1 +0,0 @@
1
- {"version":3,"file":"playground.js","names":[],"sources":["../src/svelte/playground.ts"],"sourcesContent":["import type {\n ApiResponse,\n ContentGovernanceAssignmentData,\n ContentGovernanceDefinitionsData,\n ContentGovernanceProfileData,\n ContentReviewPolicyData,\n} from '../mock-smrt-client';\nimport { CONTENT_MODULE_META } from '../ui.js';\nimport type { ContentGovernanceManagerClient } from './governance-manager-client';\n\nconst DEFAULT_CONTENT_PLAYGROUND_API_BASE_URL = '/api/v1';\n\ntype ContentPlaygroundGlobal = typeof globalThis & {\n __SMRT_CONTENT_PLAYGROUND_API_BASE_URL__?: string;\n location?: {\n search: string;\n };\n};\n\nfunction resolveContentPlaygroundApiBaseUrl(): string {\n const configuredViaGlobal = (globalThis as ContentPlaygroundGlobal)\n .__SMRT_CONTENT_PLAYGROUND_API_BASE_URL__;\n if (configuredViaGlobal) {\n return configuredViaGlobal;\n }\n\n const browserLocation = (globalThis as ContentPlaygroundGlobal).location;\n if (browserLocation) {\n const configuredViaQuery = new URLSearchParams(browserLocation.search).get(\n 'smrtContentApiBaseUrl',\n );\n\n if (configuredViaQuery) {\n return configuredViaQuery;\n }\n }\n\n return DEFAULT_CONTENT_PLAYGROUND_API_BASE_URL;\n}\n\nconst sampleArticles = [\n {\n id: 'article-aurora-kitchen',\n slug: 'aurora-kitchen-notes',\n title: 'Aurora Kitchen Notes',\n description:\n 'A reference article card preview showing how editorial metadata lands in the package playground.',\n publish_date: '2026-03-14T12:00:00.000Z',\n author: 'Editorial Systems',\n tags: ['release', 'editorial', 'qa'],\n },\n {\n id: 'article-governance-habits',\n slug: 'governance-habits',\n title: 'Governance Habits That Scale',\n description:\n 'Teams can move fast when quality gates are visible, lightweight, and shared with contributors.',\n publish_date: '2026-03-19T09:30:00.000Z',\n author: 'Content Ops',\n tags: ['governance', 'quality', 'workflows'],\n },\n];\n\nconst sampleContributions = [\n {\n id: 'contribution-1',\n title: 'Spring buyer guide',\n contributionTypeKey: 'article',\n status: 'needs_changes',\n revisionCount: 2,\n editorNotes: 'Please tighten the sourcing notes in the opening section.',\n contributorName: 'Taylor Rowan',\n contributorEmail: 'taylor@example.com',\n intakeDecision: 'needs_changes',\n body: 'The spring buyer guide draft is attached, with sourcing notes for the opening section and the product comparison appendix.',\n updatedAt: '2026-03-20T15:18:00.000Z',\n },\n {\n id: 'contribution-2',\n title: 'Field report: Pacific logistics',\n contributionTypeKey: 'report',\n status: 'submitted',\n revisionCount: 1,\n contributorName: 'Jordan Lee',\n contributorEmail: 'jordan@example.com',\n intakeDecision: 'submitted',\n body: 'Field notes from the Pacific corridor include updated shipping windows, route constraints, and operator interviews.',\n updatedAt: '2026-03-18T10:40:00.000Z',\n },\n];\n\nconst sampleGovernanceDefinitions: ContentGovernanceDefinitionsData = {\n effective: {\n policies: [\n {\n id: 'policy-facts',\n key: 'facts',\n label: 'Facts review',\n kind: 'facts',\n instructions: 'Compare claims against linked facts before publication.',\n enabled: true,\n },\n {\n id: 'policy-style',\n key: 'style',\n label: 'Style review',\n kind: 'custom',\n instructions: 'Apply newsroom tone, structure, and clarity guidelines.',\n enabled: true,\n },\n ],\n profiles: [\n {\n id: 'profile-publication',\n key: 'publication',\n label: 'Publication',\n description: 'Required before governed content can be published.',\n enabled: true,\n requirements: [\n {\n policyKey: 'facts',\n label: 'Facts review',\n blocking: true,\n acceptedStatuses: ['passed'],\n },\n {\n policyKey: 'style',\n label: 'Style review',\n blocking: false,\n acceptedStatuses: ['passed', 'warning'],\n },\n ],\n },\n ],\n assignments: [\n {\n id: 'assignment-article',\n key: 'article',\n label: 'Articles',\n contentType: 'article',\n contentVariant: null,\n enabled: true,\n factLinkingEnabled: true,\n transparencyEnabled: true,\n publicationProfileKey: 'publication',\n correctionProfileKey: null,\n enforcePublishReadiness: true,\n defaultFactRelationship: 'supports',\n },\n ],\n },\n persisted: {\n policies: [\n {\n id: 'policy-style',\n key: 'style',\n label: 'Style review',\n kind: 'custom',\n instructions: 'Apply newsroom tone, structure, and clarity guidelines.',\n enabled: true,\n },\n ],\n profiles: [\n {\n id: 'profile-publication',\n key: 'publication',\n label: 'Publication',\n description: 'Required before governed content can be published.',\n enabled: true,\n requirements: [\n {\n policyKey: 'facts',\n label: 'Facts review',\n blocking: true,\n acceptedStatuses: ['passed'],\n },\n {\n policyKey: 'style',\n label: 'Style review',\n blocking: false,\n acceptedStatuses: ['passed', 'warning'],\n },\n ],\n },\n ],\n assignments: [\n {\n id: 'assignment-article',\n key: 'article',\n label: 'Articles',\n contentType: 'article',\n contentVariant: null,\n enabled: true,\n factLinkingEnabled: true,\n transparencyEnabled: true,\n publicationProfileKey: 'publication',\n correctionProfileKey: null,\n enforcePublishReadiness: true,\n defaultFactRelationship: 'supports',\n },\n ],\n },\n};\n\nconst sampleEditorContent = {\n id: 'content-playground-editor',\n slug: 'playground-editor-reference',\n title: 'Reference editorial draft',\n description:\n 'A working editor preview with copy, references, and assets already populated.',\n body: `# Editorial Draft\n\nThis preview is meant to feel like a real authoring surface.\n\n- tighten the lede\n- verify product claims\n- attach supporting references`,\n author: 'Editorial Systems',\n type: 'article',\n status: 'draft',\n state: 'active',\n source: 'manual',\n tags: ['editorial', 'playground'],\n referenceIds: ['fact-aurora', 'source-governance'],\n assetIds: [],\n assets: [],\n};\n\nconst noop = () => {};\n\nfunction cloneValue<T>(value: T): T {\n return JSON.parse(JSON.stringify(value)) as T;\n}\n\nfunction buildPlaygroundResponse<T>(data: T): ApiResponse<T> {\n return {\n data,\n success: true,\n };\n}\n\nfunction upsertByIdOrKey<\n T extends {\n id?: string;\n key?: string;\n },\n>(items: T[], value: Partial<T>, prefix: string): T[] {\n const id = value.id || `${prefix}-${value.key || items.length + 1}`;\n const nextValue = {\n ...value,\n id,\n } as T;\n\n const index = items.findIndex(\n (item) => item.id === id || (!!value.key && item.key === value.key),\n );\n\n if (index === -1) {\n return [...items, nextValue];\n }\n\n const nextItems = [...items];\n nextItems[index] = {\n ...nextItems[index],\n ...nextValue,\n };\n return nextItems;\n}\n\nfunction createGovernancePlaygroundClient(\n seed = sampleGovernanceDefinitions,\n): ContentGovernanceManagerClient {\n let policies = cloneValue(seed.effective.policies);\n let profiles = cloneValue(seed.effective.profiles);\n let assignments = cloneValue(seed.effective.assignments);\n\n const getDefinitions = (): ContentGovernanceDefinitionsData => ({\n effective: {\n policies: cloneValue(policies),\n profiles: cloneValue(profiles),\n assignments: cloneValue(assignments),\n },\n persisted: {\n policies: cloneValue(policies),\n profiles: cloneValue(profiles),\n assignments: cloneValue(assignments),\n },\n });\n\n return {\n contents: {\n getGovernanceDefinitions: async () =>\n buildPlaygroundResponse(getDefinitions()),\n },\n contentGovernancePolicies: {\n create: async (policy: Partial<ContentReviewPolicyData>) => {\n policies = upsertByIdOrKey(policies, policy, 'policy');\n return buildPlaygroundResponse(policies[policies.length - 1]);\n },\n update: async (id: string, policy: Partial<ContentReviewPolicyData>) => {\n policies = upsertByIdOrKey(policies, { ...policy, id }, 'policy');\n return buildPlaygroundResponse(\n policies.find((item) => item.id === id)!,\n );\n },\n delete: async (id: string) => {\n policies = policies.filter((item) => item.id !== id);\n return buildPlaygroundResponse(undefined);\n },\n },\n contentGovernanceProfiles: {\n create: async (profile: Partial<ContentGovernanceProfileData>) => {\n profiles = upsertByIdOrKey(profiles, profile, 'profile');\n return buildPlaygroundResponse(profiles[profiles.length - 1]);\n },\n update: async (\n id: string,\n profile: Partial<ContentGovernanceProfileData>,\n ) => {\n profiles = upsertByIdOrKey(profiles, { ...profile, id }, 'profile');\n return buildPlaygroundResponse(\n profiles.find((item) => item.id === id)!,\n );\n },\n delete: async (id: string) => {\n profiles = profiles.filter((item) => item.id !== id);\n return buildPlaygroundResponse(undefined);\n },\n },\n contentGovernanceAssignments: {\n create: async (assignment: Partial<ContentGovernanceAssignmentData>) => {\n assignments = upsertByIdOrKey(assignments, assignment, 'assignment');\n return buildPlaygroundResponse(assignments[assignments.length - 1]);\n },\n update: async (\n id: string,\n assignment: Partial<ContentGovernanceAssignmentData>,\n ) => {\n assignments = upsertByIdOrKey(\n assignments,\n { ...assignment, id },\n 'assignment',\n );\n return buildPlaygroundResponse(\n assignments.find((item) => item.id === id)!,\n );\n },\n delete: async (id: string) => {\n assignments = assignments.filter((item) => item.id !== id);\n return buildPlaygroundResponse(undefined);\n },\n },\n };\n}\n\nconst markdownExample = `# Content Playground\n\nThis preview module lives in \\`src/svelte/playground.ts\\`.\n\n- Package-owned previews stay close to the real components\n- The shared host simply discovers and renders them\n- Live entries can point at the package's generated API routes`;\n\n// Keep the published playground module importable from Node so `smrt\n// playground list` can inspect entry metadata without needing a Svelte loader.\nconst loadArticleCard = () => import('./components/ArticleCard.svelte');\nconst loadArticleList = () => import('./components/ArticleList.svelte');\nconst loadContentEditor = () => import('./components/ContentEditor.svelte');\nconst loadContentContributionInbox = () =>\n import('./components/ContentContributionInbox.svelte');\nconst loadContentContributionPortal = () =>\n import('./components/ContentContributionPortal.svelte');\nconst loadContentGovernanceManager = () =>\n import('./components/ContentGovernanceManager.svelte');\nconst loadMarkdown = () => import('./components/Markdown.svelte');\nconst governancePlaygroundClient = createGovernancePlaygroundClient();\n\nexport default {\n packageName: '@happyvertical/smrt-content',\n displayName: 'Content',\n description: CONTENT_MODULE_META.description,\n moduleMeta: CONTENT_MODULE_META,\n entries: [\n {\n id: 'article-card',\n slotId: 'article-card',\n title: 'Article Card',\n description: 'Editorial teaser card with tags and metadata.',\n loadComponent: loadArticleCard,\n order: 1,\n props: {\n article: sampleArticles[0],\n showTags: true,\n },\n modes: {\n mock: {\n label: 'Mock',\n },\n },\n },\n {\n id: 'article-list',\n slotId: 'article-list',\n title: 'Article List',\n description: 'Reference list/grid layout for published content.',\n loadComponent: loadArticleList,\n order: 2,\n props: {\n articles: sampleArticles,\n showTags: true,\n },\n modes: {\n mock: {\n label: 'Mock',\n },\n },\n },\n {\n id: 'markdown',\n slotId: 'markdown',\n title: 'Markdown Renderer',\n description: 'Safe markdown rendering with a small editorial snippet.',\n loadComponent: loadMarkdown,\n order: 3,\n props: {\n content: markdownExample,\n },\n modes: {\n mock: {\n label: 'Mock',\n },\n },\n },\n {\n id: 'content-editor',\n title: 'Content Editor',\n description: 'Authoring surface for body copy, references, and media.',\n loadComponent: loadContentEditor,\n order: 4,\n props: {\n apiBaseUrl: resolveContentPlaygroundApiBaseUrl(),\n content: sampleEditorContent,\n contentId: sampleEditorContent.id,\n agentChatEnabled: false,\n agentChatNotice:\n 'The shared playground keeps the editor preview local. Run the content package app when you want the live agent chat routes too.',\n onSave: noop,\n onCancel: noop,\n },\n modes: {\n mock: {\n label: 'Mock',\n },\n },\n },\n {\n id: 'contribution-portal',\n title: 'Contribution Portal',\n description: 'Contributor-facing inbox and submission status view.',\n loadComponent: loadContentContributionPortal,\n order: 5,\n props: {\n contributions: sampleContributions,\n },\n modes: {\n mock: {\n label: 'Mock',\n },\n },\n },\n {\n id: 'contribution-inbox',\n title: 'Contribution Inbox',\n description:\n 'Editorial review queue for approving, rejecting, or requesting changes.',\n loadComponent: loadContentContributionInbox,\n order: 6,\n props: {\n contributions: sampleContributions,\n },\n modes: {\n mock: {\n label: 'Mock',\n },\n },\n },\n {\n id: 'governance-manager',\n title: 'Governance Manager',\n description:\n 'Administrative view with in-memory mock data and optional live package routes.',\n loadComponent: loadContentGovernanceManager,\n order: 7,\n modes: {\n mock: {\n label: 'Mock',\n description:\n 'Uses an in-memory governance client so the shared playground works without a package-local dev server.',\n props: {\n client: governancePlaygroundClient,\n },\n },\n live: {\n label: 'Live',\n description:\n 'Requires the content package dev server and generated routes. Override the base URL with ?smrtContentApiBaseUrl=... or window.__SMRT_CONTENT_PLAYGROUND_API_BASE_URL__ when needed.',\n props: {\n apiBaseUrl: resolveContentPlaygroundApiBaseUrl(),\n },\n },\n },\n },\n ],\n};\n"],"mappings":"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"}