@pure-ds/core 0.6.9 → 0.6.11

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 (90) hide show
  1. package/custom-elements.json +865 -35
  2. package/dist/types/pds.d.ts +31 -0
  3. package/dist/types/public/assets/js/pds-manager.d.ts +100 -2
  4. package/dist/types/public/assets/js/pds-manager.d.ts.map +1 -1
  5. package/dist/types/public/assets/js/pds.d.ts.map +1 -1
  6. package/dist/types/public/assets/pds/components/pds-form.d.ts.map +1 -1
  7. package/dist/types/public/assets/pds/components/pds-live-converter.d.ts +8 -0
  8. package/dist/types/public/assets/pds/components/pds-live-converter.d.ts.map +1 -0
  9. package/dist/types/public/assets/pds/components/pds-live-edit.d.ts +1 -195
  10. package/dist/types/public/assets/pds/components/pds-live-edit.d.ts.map +1 -1
  11. package/dist/types/public/assets/pds/components/pds-live-importer.d.ts +2 -0
  12. package/dist/types/public/assets/pds/components/pds-live-importer.d.ts.map +1 -0
  13. package/dist/types/public/assets/pds/components/pds-live-template-canvas.d.ts +2 -0
  14. package/dist/types/public/assets/pds/components/pds-live-template-canvas.d.ts.map +1 -0
  15. package/dist/types/public/assets/pds/components/pds-omnibox.d.ts +0 -2
  16. package/dist/types/public/assets/pds/components/pds-omnibox.d.ts.map +1 -1
  17. package/dist/types/public/assets/pds/components/pds-scrollrow.d.ts +20 -0
  18. package/dist/types/public/assets/pds/components/pds-scrollrow.d.ts.map +1 -1
  19. package/dist/types/public/assets/pds/components/pds-toaster.d.ts +1 -1
  20. package/dist/types/public/assets/pds/components/pds-toaster.d.ts.map +1 -1
  21. package/dist/types/public/assets/pds/components/pds-treeview.d.ts +37 -0
  22. package/dist/types/public/assets/pds/components/pds-treeview.d.ts.map +1 -0
  23. package/dist/types/src/js/common/toast.d.ts +8 -0
  24. package/dist/types/src/js/common/toast.d.ts.map +1 -1
  25. package/dist/types/src/js/pds-core/pds-config.d.ts +1306 -13
  26. package/dist/types/src/js/pds-core/pds-config.d.ts.map +1 -1
  27. package/dist/types/src/js/pds-core/pds-enhancers-meta.d.ts.map +1 -1
  28. package/dist/types/src/js/pds-core/pds-enhancers.d.ts.map +1 -1
  29. package/dist/types/src/js/pds-core/pds-generator.d.ts.map +1 -1
  30. package/dist/types/src/js/pds-core/pds-live.d.ts +2 -1
  31. package/dist/types/src/js/pds-core/pds-live.d.ts.map +1 -1
  32. package/dist/types/src/js/pds-core/pds-ontology.d.ts.map +1 -1
  33. package/dist/types/src/js/pds-core/pds-start-helpers.d.ts +1 -4
  34. package/dist/types/src/js/pds-core/pds-start-helpers.d.ts.map +1 -1
  35. package/dist/types/src/js/pds-live-manager/conversion-service.d.ts +66 -0
  36. package/dist/types/src/js/pds-live-manager/conversion-service.d.ts.map +1 -0
  37. package/dist/types/src/js/pds-live-manager/import-contract.d.ts +15 -0
  38. package/dist/types/src/js/pds-live-manager/import-contract.d.ts.map +1 -0
  39. package/dist/types/src/js/pds-live-manager/import-history-service.d.ts +32 -0
  40. package/dist/types/src/js/pds-live-manager/import-history-service.d.ts.map +1 -0
  41. package/dist/types/src/js/pds-live-manager/import-service.d.ts +21 -0
  42. package/dist/types/src/js/pds-live-manager/import-service.d.ts.map +1 -0
  43. package/dist/types/src/js/pds-live-manager/template-service.d.ts +17 -0
  44. package/dist/types/src/js/pds-live-manager/template-service.d.ts.map +1 -0
  45. package/dist/types/src/js/pds-manager.d.ts +4 -0
  46. package/dist/types/src/js/pds.d.ts.map +1 -1
  47. package/package.json +7 -3
  48. package/packages/pds-cli/README.md +51 -0
  49. package/packages/pds-cli/bin/pds-import.js +176 -0
  50. package/packages/pds-cli/bin/pds-static.js +31 -1
  51. package/packages/pds-cli/bin/postinstall.mjs +17 -8
  52. package/public/assets/js/app.js +23 -147
  53. package/public/assets/js/pds-manager.js +481 -248
  54. package/public/assets/js/pds.js +16 -16
  55. package/public/assets/pds/components/pds-form.js +124 -27
  56. package/public/assets/pds/components/pds-live-converter.js +47 -0
  57. package/public/assets/pds/components/pds-live-edit.js +1626 -211
  58. package/public/assets/pds/components/pds-live-importer.js +772 -0
  59. package/public/assets/pds/components/pds-live-template-canvas.js +171 -0
  60. package/public/assets/pds/components/pds-omnibox.js +146 -20
  61. package/public/assets/pds/components/pds-scrollrow.js +56 -1
  62. package/public/assets/pds/components/pds-toaster.js +50 -5
  63. package/public/assets/pds/components/pds-treeview.js +972 -0
  64. package/public/assets/pds/custom-elements.json +865 -35
  65. package/public/assets/pds/pds-css-complete.json +7 -7
  66. package/public/assets/pds/pds.css-data.json +5 -35
  67. package/public/assets/pds/templates/commerce-scroll-explorer.html +115 -0
  68. package/public/assets/pds/templates/content-brand-showcase.html +110 -0
  69. package/public/assets/pds/templates/feedback-ops-dashboard.html +91 -0
  70. package/public/assets/pds/templates/release-readiness-radar.html +69 -0
  71. package/public/assets/pds/templates/support-command-center.html +92 -0
  72. package/public/assets/pds/templates/templates.json +53 -0
  73. package/public/assets/pds/templates/workspace-settings-lab.html +131 -0
  74. package/public/assets/pds/vscode-custom-data.json +54 -4
  75. package/readme.md +34 -0
  76. package/src/js/pds-core/pds-config.js +831 -40
  77. package/src/js/pds-core/pds-enhancers-meta.js +11 -0
  78. package/src/js/pds-core/pds-enhancers.js +259 -5
  79. package/src/js/pds-core/pds-generator.js +353 -52
  80. package/src/js/pds-core/pds-live.js +630 -15
  81. package/src/js/pds-core/pds-ontology.js +6 -0
  82. package/src/js/pds-core/pds-start-helpers.js +14 -6
  83. package/src/js/pds-live-manager/conversion-service.js +3136 -0
  84. package/src/js/pds-live-manager/import-contract.js +57 -0
  85. package/src/js/pds-live-manager/import-history-service.js +145 -0
  86. package/src/js/pds-live-manager/import-service.js +255 -0
  87. package/src/js/pds-live-manager/tailwind-conversion-rules.json +383 -0
  88. package/src/js/pds-live-manager/template-service.js +170 -0
  89. package/src/js/pds.d.ts +31 -0
  90. package/src/js/pds.js +71 -60
@@ -0,0 +1,57 @@
1
+ const DEFAULT_CONFIDENCE = 0.5;
2
+
3
+ function normalizeConfidence(value) {
4
+ const parsed = Number(value);
5
+ if (!Number.isFinite(parsed)) return DEFAULT_CONFIDENCE;
6
+ return Math.max(0, Math.min(1, parsed));
7
+ }
8
+
9
+ function normalizeIssues(issues) {
10
+ if (!Array.isArray(issues)) return [];
11
+ return issues
12
+ .map((issue) => {
13
+ if (!issue) return null;
14
+ const severity = String(issue.severity || "info").toLowerCase();
15
+ return {
16
+ severity,
17
+ message: String(issue.message || ""),
18
+ path: issue.path ? String(issue.path) : "",
19
+ };
20
+ })
21
+ .filter((issue) => issue && issue.message);
22
+ }
23
+
24
+ export function createImportResult(input = {}) {
25
+ const source = String(input.source || "unknown");
26
+ const type = String(input.type || "generic");
27
+ const confidence = normalizeConfidence(input.confidence);
28
+ const issues = normalizeIssues(input.issues);
29
+ const designPatch =
30
+ input.designPatch && typeof input.designPatch === "object"
31
+ ? input.designPatch
32
+ : {};
33
+ const template =
34
+ input.template && typeof input.template === "object" ? input.template : null;
35
+
36
+ return {
37
+ source,
38
+ type,
39
+ confidence,
40
+ issues,
41
+ designPatch,
42
+ template,
43
+ meta: input.meta && typeof input.meta === "object" ? input.meta : {},
44
+ };
45
+ }
46
+
47
+ export function isImportResult(value) {
48
+ return Boolean(
49
+ value &&
50
+ typeof value === "object" &&
51
+ "source" in value &&
52
+ "type" in value &&
53
+ "confidence" in value &&
54
+ "issues" in value &&
55
+ "designPatch" in value
56
+ );
57
+ }
@@ -0,0 +1,145 @@
1
+ const IMPORT_HISTORY_DB_NAME = "pds-live-import-history";
2
+ const IMPORT_HISTORY_DB_VERSION = 1;
3
+ const IMPORT_HISTORY_STORE = "imports";
4
+
5
+ let dbPromise = null;
6
+
7
+ function supportsIndexedDb() {
8
+ return typeof globalThis !== "undefined" && typeof globalThis.indexedDB !== "undefined";
9
+ }
10
+
11
+ function sanitizeText(value) {
12
+ return typeof value === "string" ? value : "";
13
+ }
14
+
15
+ function sanitizeArray(value) {
16
+ return Array.isArray(value) ? value : [];
17
+ }
18
+
19
+ function sanitizeObject(value) {
20
+ return value && typeof value === "object" ? value : {};
21
+ }
22
+
23
+ function openDb() {
24
+ if (!supportsIndexedDb()) return Promise.resolve(null);
25
+ if (dbPromise) return dbPromise;
26
+
27
+ dbPromise = new Promise((resolve, reject) => {
28
+ const request = globalThis.indexedDB.open(IMPORT_HISTORY_DB_NAME, IMPORT_HISTORY_DB_VERSION);
29
+
30
+ request.onupgradeneeded = () => {
31
+ const db = request.result;
32
+ if (!db.objectStoreNames.contains(IMPORT_HISTORY_STORE)) {
33
+ const store = db.createObjectStore(IMPORT_HISTORY_STORE, {
34
+ keyPath: "id",
35
+ autoIncrement: true,
36
+ });
37
+ store.createIndex("createdAt", "createdAt", { unique: false });
38
+ store.createIndex("sourceType", "sourceType", { unique: false });
39
+ store.createIndex("fileName", "fileName", { unique: false });
40
+ }
41
+ };
42
+
43
+ request.onsuccess = () => resolve(request.result);
44
+ request.onerror = () => reject(request.error || new Error("Failed to open import history database."));
45
+ });
46
+
47
+ return dbPromise;
48
+ }
49
+
50
+ function requestToPromise(request) {
51
+ return new Promise((resolve, reject) => {
52
+ request.onsuccess = () => resolve(request.result);
53
+ request.onerror = () => reject(request.error || new Error("IndexedDB operation failed."));
54
+ });
55
+ }
56
+
57
+ function normalizeHistoryEntry(input = {}) {
58
+ const now = Date.now();
59
+ const createdAt = Number.isFinite(Number(input.createdAt)) ? Number(input.createdAt) : now;
60
+ const createdAtIso = new Date(createdAt).toISOString();
61
+
62
+ const issues = sanitizeArray(input.issues).map((issue) => ({
63
+ severity: sanitizeText(issue?.severity || "info"),
64
+ message: sanitizeText(issue?.message || ""),
65
+ }));
66
+
67
+ const notes = sanitizeArray(input.notes).filter((note) => typeof note === "string");
68
+ const unknownTailwindTokens = sanitizeArray(input.unknownTailwindTokens).filter(
69
+ (token) => typeof token === "string"
70
+ );
71
+ const appliedRules = sanitizeArray(input.appliedRules).filter((rule) => typeof rule === "string");
72
+
73
+ return {
74
+ createdAt,
75
+ createdAtIso,
76
+ sourceType: sanitizeText(input.sourceType || "unknown"),
77
+ importMode: sanitizeText(input.importMode || "convert-only"),
78
+ source: sanitizeText(input.source || "unknown"),
79
+ type: sanitizeText(input.type || "unknown"),
80
+ fileName: sanitizeText(input.fileName || ""),
81
+ fileSize: Number.isFinite(Number(input.fileSize)) ? Number(input.fileSize) : 0,
82
+ mimeType: sanitizeText(input.mimeType || ""),
83
+ fileContents: sanitizeText(input.fileContents || ""),
84
+ convertedHtml: sanitizeText(input.convertedHtml || ""),
85
+ confidence: Number.isFinite(Number(input.confidence)) ? Number(input.confidence) : 0,
86
+ notes,
87
+ issues,
88
+ coverage: sanitizeObject(input.coverage),
89
+ unknownTailwindTokens,
90
+ appliedRules,
91
+ importStyleSheetInjected: Boolean(input.importStyleSheetInjected),
92
+ templateName: sanitizeText(input.templateName || ""),
93
+ designPatch: sanitizeObject(input.designPatch),
94
+ meta: sanitizeObject(input.meta),
95
+ resultSnapshot: sanitizeObject(input.resultSnapshot),
96
+ };
97
+ }
98
+
99
+ export async function saveLiveImportHistory(input = {}) {
100
+ const db = await openDb();
101
+ if (!db) return null;
102
+
103
+ const entry = normalizeHistoryEntry(input);
104
+ const tx = db.transaction(IMPORT_HISTORY_STORE, "readwrite");
105
+ const store = tx.objectStore(IMPORT_HISTORY_STORE);
106
+ const id = await requestToPromise(store.add(entry));
107
+
108
+ return { id, ...entry };
109
+ }
110
+
111
+ export async function listLiveImportHistory(options = {}) {
112
+ const db = await openDb();
113
+ if (!db) return [];
114
+
115
+ const limit = Number.isFinite(Number(options.limit)) ? Math.max(1, Number(options.limit)) : 30;
116
+ const tx = db.transaction(IMPORT_HISTORY_STORE, "readonly");
117
+ const store = tx.objectStore(IMPORT_HISTORY_STORE);
118
+ const items = (await requestToPromise(store.getAll())) || [];
119
+
120
+ return items
121
+ .sort((a, b) => Number(b?.createdAt || 0) - Number(a?.createdAt || 0))
122
+ .slice(0, limit);
123
+ }
124
+
125
+ export async function getLiveImportHistoryEntry(id) {
126
+ const db = await openDb();
127
+ if (!db) return null;
128
+
129
+ const parsedId = Number(id);
130
+ if (!Number.isFinite(parsedId)) return null;
131
+
132
+ const tx = db.transaction(IMPORT_HISTORY_STORE, "readonly");
133
+ const store = tx.objectStore(IMPORT_HISTORY_STORE);
134
+ const entry = await requestToPromise(store.get(parsedId));
135
+ return entry || null;
136
+ }
137
+
138
+ export async function clearLiveImportHistory() {
139
+ const db = await openDb();
140
+ if (!db) return;
141
+
142
+ const tx = db.transaction(IMPORT_HISTORY_STORE, "readwrite");
143
+ const store = tx.objectStore(IMPORT_HISTORY_STORE);
144
+ await requestToPromise(store.clear());
145
+ }
@@ -0,0 +1,255 @@
1
+ import { createImportResult } from "./import-contract.js";
2
+ import {
3
+ buildTemplateImportResult,
4
+ listLiveTemplates,
5
+ loadLiveTemplateCatalog,
6
+ } from "./template-service.js";
7
+ import {
8
+ convertTailwindHtmlToPds,
9
+ convertBrandGuidelinesToPatch,
10
+ inferPdsDesignFromHtml,
11
+ convertHtmlLikeInputToPdsTemplate,
12
+ } from "./conversion-service.js";
13
+ import { validateDesign } from "../pds-core/pds-generator.js";
14
+
15
+ const IMPORT_MODE_CONVERT_ONLY = "convert-only";
16
+ const IMPORT_MODE_ADOPT_AND_CONVERT = "adopt-design-and-convert";
17
+
18
+ function normalizeImportMode(value) {
19
+ const normalized = String(value || "").trim().toLowerCase();
20
+ if (normalized === IMPORT_MODE_ADOPT_AND_CONVERT) return IMPORT_MODE_ADOPT_AND_CONVERT;
21
+ return IMPORT_MODE_CONVERT_ONLY;
22
+ }
23
+
24
+ function combineIssues(...issueLists) {
25
+ const items = issueLists.flat().filter(Boolean);
26
+ if (!items.length) return [];
27
+ const seen = new Set();
28
+ return items.filter((issue) => {
29
+ const key = `${String(issue?.severity || "info")}::${String(issue?.path || "")}::${String(issue?.message || "")}`;
30
+ if (seen.has(key)) return false;
31
+ seen.add(key);
32
+ return true;
33
+ });
34
+ }
35
+
36
+ function combineConfidence(values = []) {
37
+ const list = values.map((value) => Number(value)).filter((value) => Number.isFinite(value));
38
+ if (!list.length) return 0;
39
+ return Math.max(0, Math.min(1, list.reduce((sum, value) => sum + value, 0) / list.length));
40
+ }
41
+
42
+ function mergeMeta(base = {}, extra = {}) {
43
+ return {
44
+ ...(base && typeof base === "object" ? base : {}),
45
+ ...(extra && typeof extra === "object" ? extra : {}),
46
+ };
47
+ }
48
+
49
+ function deepMerge(target = {}, source = {}) {
50
+ if (!source || typeof source !== "object") return target;
51
+ const out = Array.isArray(target) ? [...target] : { ...target };
52
+ Object.entries(source).forEach(([key, value]) => {
53
+ if (value && typeof value === "object" && !Array.isArray(value)) {
54
+ out[key] = deepMerge(
55
+ out[key] && typeof out[key] === "object" ? out[key] : {},
56
+ value
57
+ );
58
+ } else {
59
+ out[key] = value;
60
+ }
61
+ });
62
+ return out;
63
+ }
64
+
65
+ function cloneValue(value) {
66
+ if (typeof structuredClone === "function") {
67
+ try {
68
+ return structuredClone(value);
69
+ } catch (error) {}
70
+ }
71
+ return JSON.parse(JSON.stringify(value || {}));
72
+ }
73
+
74
+ function normalizeValidationIssue(issue = {}) {
75
+ const ratio = Number(issue?.ratio);
76
+ const min = Number(issue?.min);
77
+ const ratioLabel = Number.isFinite(ratio) ? ratio.toFixed(2) : "n/a";
78
+ const minLabel = Number.isFinite(min) ? min.toFixed(2) : "n/a";
79
+ return {
80
+ severity: "error",
81
+ path: String(issue?.path || "/colors"),
82
+ message: `${String(issue?.message || "Color contrast validation failed.")} (ratio=${ratioLabel}, required=${minLabel})`,
83
+ };
84
+ }
85
+
86
+ function validateAdoptedDesignPatch(baseDesign = {}, designPatch = {}, options = {}) {
87
+ const patchKeys = designPatch && typeof designPatch === "object" ? Object.keys(designPatch) : [];
88
+ if (!patchKeys.length) {
89
+ return { ok: true, blocked: false, issues: [], report: { ok: true, issues: [] } };
90
+ }
91
+
92
+ const minContrast = Number(options.minContrast);
93
+ const threshold = Number.isFinite(minContrast) ? minContrast : 4.5;
94
+ const mergedDesign = deepMerge(cloneValue(baseDesign || {}), cloneValue(designPatch || {}));
95
+ const report = validateDesign(mergedDesign, {
96
+ minContrast: threshold,
97
+ minMutedContrast: 3,
98
+ extendedChecks: true,
99
+ });
100
+ const issues = Array.isArray(report?.issues)
101
+ ? report.issues.map((issue) => normalizeValidationIssue(issue))
102
+ : [];
103
+
104
+ return {
105
+ ok: Boolean(report?.ok),
106
+ blocked: !report?.ok,
107
+ issues,
108
+ report: {
109
+ ok: Boolean(report?.ok),
110
+ minContrast: threshold,
111
+ issues: Array.isArray(report?.issues) ? report.issues : [],
112
+ },
113
+ };
114
+ }
115
+
116
+ export function getLiveImportSources() {
117
+ return [
118
+ { id: "template", name: "Templates" },
119
+ { id: "tailwind-html", name: "Tailwind HTML" },
120
+ { id: "brand-guidelines", name: "Brand Guidelines" },
121
+ { id: "figma-json", name: "Figma Tokens JSON (planned)" },
122
+ { id: "ux-pilot", name: "UX Pilot (planned)" },
123
+ { id: "google-stitch", name: "Google Stitch (planned)" },
124
+ ];
125
+ }
126
+
127
+ export async function runLiveImport(request = {}) {
128
+ const sourceType = String(request.sourceType || "");
129
+ const importMode = normalizeImportMode(request.importMode);
130
+ const input = String(request.input || "");
131
+ const config = request.config || null;
132
+
133
+ if (sourceType === "template") {
134
+ const result = buildTemplateImportResult(request.templateId, request);
135
+ result.meta = mergeMeta(result.meta, { importMode });
136
+ return result;
137
+ }
138
+
139
+ if (sourceType === "tailwind-html") {
140
+ const conversionResult = convertTailwindHtmlToPds({ html: input, config });
141
+ if (importMode === IMPORT_MODE_CONVERT_ONLY) {
142
+ conversionResult.meta = mergeMeta(conversionResult.meta, { importMode });
143
+ return conversionResult;
144
+ }
145
+
146
+ const inferred = inferPdsDesignFromHtml({ html: input, config, sourceType });
147
+ const validation = validateAdoptedDesignPatch(config || {}, inferred.designPatch || {});
148
+ const safeDesignPatch = validation.blocked ? {} : inferred.designPatch;
149
+ const validationIssues = validation.blocked
150
+ ? [
151
+ {
152
+ severity: "error",
153
+ path: "/colors",
154
+ message: "Import blocked: inferred design patch failed accessibility contrast validation.",
155
+ },
156
+ ...validation.issues,
157
+ ]
158
+ : [];
159
+
160
+ return createImportResult({
161
+ source: conversionResult.source || "tailwind",
162
+ type: sourceType,
163
+ confidence: combineConfidence([conversionResult.confidence, inferred.confidence]),
164
+ issues: combineIssues(conversionResult.issues, inferred.issues, validationIssues),
165
+ template: conversionResult.template,
166
+ designPatch: safeDesignPatch,
167
+ meta: mergeMeta(conversionResult.meta, {
168
+ importMode,
169
+ inference: inferred.meta,
170
+ validation: validation.report,
171
+ validationBlocked: validation.blocked,
172
+ }),
173
+ });
174
+ }
175
+
176
+ if (sourceType === "brand-guidelines") {
177
+ const templateResult = convertHtmlLikeInputToPdsTemplate({ input, sourceType, config });
178
+ if (importMode === IMPORT_MODE_CONVERT_ONLY) {
179
+ templateResult.meta = mergeMeta(templateResult.meta, { importMode });
180
+ return templateResult;
181
+ }
182
+
183
+ const heuristicPatch = convertBrandGuidelinesToPatch({ text: input });
184
+ const inferred = inferPdsDesignFromHtml({ html: input, config, sourceType });
185
+ const designPatch = {
186
+ ...(heuristicPatch.designPatch && typeof heuristicPatch.designPatch === "object"
187
+ ? heuristicPatch.designPatch
188
+ : {}),
189
+ ...(inferred.designPatch && typeof inferred.designPatch === "object" ? inferred.designPatch : {}),
190
+ };
191
+ const validation = validateAdoptedDesignPatch(config || {}, designPatch || {});
192
+ const safeDesignPatch = validation.blocked ? {} : designPatch;
193
+ const validationIssues = validation.blocked
194
+ ? [
195
+ {
196
+ severity: "error",
197
+ path: "/colors",
198
+ message: "Import blocked: inferred design patch failed accessibility contrast validation.",
199
+ },
200
+ ...validation.issues,
201
+ ]
202
+ : [];
203
+
204
+ return createImportResult({
205
+ source: "brand",
206
+ type: sourceType,
207
+ confidence: combineConfidence([
208
+ templateResult.confidence,
209
+ heuristicPatch.confidence,
210
+ inferred.confidence,
211
+ ]),
212
+ issues: combineIssues(
213
+ templateResult.issues,
214
+ heuristicPatch.issues,
215
+ inferred.issues,
216
+ validationIssues
217
+ ),
218
+ template: templateResult.template,
219
+ designPatch: safeDesignPatch,
220
+ meta: mergeMeta(templateResult.meta, {
221
+ importMode,
222
+ inference: inferred.meta,
223
+ brandHeuristics: heuristicPatch.meta,
224
+ validation: validation.report,
225
+ validationBlocked: validation.blocked,
226
+ }),
227
+ });
228
+ }
229
+
230
+ if (sourceType === "figma-json" || sourceType === "ux-pilot" || sourceType === "google-stitch") {
231
+ return createImportResult({
232
+ source: sourceType,
233
+ type: sourceType,
234
+ confidence: 0,
235
+ issues: [
236
+ {
237
+ severity: "info",
238
+ message: `${sourceType} adapter is not implemented yet in this phase.`,
239
+ },
240
+ ],
241
+ meta: { importMode },
242
+ });
243
+ }
244
+
245
+ return createImportResult({
246
+ source: sourceType || "unknown",
247
+ type: "unknown",
248
+ confidence: 0,
249
+ issues: [{ severity: "error", message: "Unsupported import source type." }],
250
+ meta: { importMode },
251
+ });
252
+ }
253
+
254
+ export { listLiveTemplates };
255
+ export { loadLiveTemplateCatalog };