@multiplayer-app/sandbox 0.0.31 → 0.0.32

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 (186) hide show
  1. package/dist/agents/html-generator.agent.d.ts +3 -1
  2. package/dist/agents/html-generator.agent.d.ts.map +1 -1
  3. package/dist/agents/html-generator.agent.js +90 -4
  4. package/dist/agents/html-generator.agent.js.map +1 -1
  5. package/dist/agents/markdown-generator.agent.d.ts.map +1 -1
  6. package/dist/agents/markdown-generator.agent.js +5 -10
  7. package/dist/agents/markdown-generator.agent.js.map +1 -1
  8. package/dist/agents/shared/app-vm.tools.d.ts +4 -0
  9. package/dist/agents/shared/app-vm.tools.d.ts.map +1 -0
  10. package/dist/agents/shared/app-vm.tools.js +105 -0
  11. package/dist/agents/shared/app-vm.tools.js.map +1 -0
  12. package/dist/agents/shared/build-plan.tools.d.ts +5 -0
  13. package/dist/agents/shared/build-plan.tools.d.ts.map +1 -0
  14. package/dist/agents/shared/build-plan.tools.js +176 -0
  15. package/dist/agents/shared/build-plan.tools.js.map +1 -0
  16. package/dist/agents/shared/session-quality-report.tool.d.ts +7 -0
  17. package/dist/agents/shared/session-quality-report.tool.d.ts.map +1 -0
  18. package/dist/agents/shared/session-quality-report.tool.js +97 -0
  19. package/dist/agents/shared/session-quality-report.tool.js.map +1 -0
  20. package/dist/agents/shared/session-vm-bridge.d.ts +49 -0
  21. package/dist/agents/shared/session-vm-bridge.d.ts.map +1 -0
  22. package/dist/agents/shared/session-vm-bridge.js +9 -0
  23. package/dist/agents/shared/session-vm-bridge.js.map +1 -0
  24. package/dist/agents/skills/a11y.skill.d.ts +3 -0
  25. package/dist/agents/skills/a11y.skill.d.ts.map +1 -0
  26. package/dist/agents/skills/a11y.skill.js +23 -0
  27. package/dist/agents/skills/a11y.skill.js.map +1 -0
  28. package/dist/agents/skills/account-skill-loader.d.ts +13 -0
  29. package/dist/agents/skills/account-skill-loader.d.ts.map +1 -0
  30. package/dist/agents/skills/account-skill-loader.js +42 -0
  31. package/dist/agents/skills/account-skill-loader.js.map +1 -0
  32. package/dist/agents/skills/app-scaffold.skill.d.ts +3 -0
  33. package/dist/agents/skills/app-scaffold.skill.d.ts.map +1 -0
  34. package/dist/agents/skills/app-scaffold.skill.js +30 -0
  35. package/dist/agents/skills/app-scaffold.skill.js.map +1 -0
  36. package/dist/agents/skills/copywriting.skill.d.ts +3 -0
  37. package/dist/agents/skills/copywriting.skill.d.ts.map +1 -0
  38. package/dist/agents/skills/copywriting.skill.js +35 -0
  39. package/dist/agents/skills/copywriting.skill.js.map +1 -0
  40. package/dist/agents/skills/custom-skill-repository.d.ts +40 -0
  41. package/dist/agents/skills/custom-skill-repository.d.ts.map +1 -0
  42. package/dist/agents/skills/custom-skill-repository.js +3 -0
  43. package/dist/agents/skills/custom-skill-repository.js.map +1 -0
  44. package/dist/agents/skills/data-viz.skill.d.ts +3 -0
  45. package/dist/agents/skills/data-viz.skill.d.ts.map +1 -0
  46. package/dist/agents/skills/data-viz.skill.js +42 -0
  47. package/dist/agents/skills/data-viz.skill.js.map +1 -0
  48. package/dist/agents/skills/designer.skill.d.ts +3 -0
  49. package/dist/agents/skills/designer.skill.d.ts.map +1 -0
  50. package/dist/agents/skills/designer.skill.js +139 -0
  51. package/dist/agents/skills/designer.skill.js.map +1 -0
  52. package/dist/agents/skills/forms.skill.d.ts +3 -0
  53. package/dist/agents/skills/forms.skill.d.ts.map +1 -0
  54. package/dist/agents/skills/forms.skill.js +37 -0
  55. package/dist/agents/skills/forms.skill.js.map +1 -0
  56. package/dist/agents/skills/index.d.ts +6 -0
  57. package/dist/agents/skills/index.d.ts.map +1 -0
  58. package/dist/agents/skills/index.js +18 -0
  59. package/dist/agents/skills/index.js.map +1 -0
  60. package/dist/agents/skills/interactions.skill.d.ts +3 -0
  61. package/dist/agents/skills/interactions.skill.d.ts.map +1 -0
  62. package/dist/agents/skills/interactions.skill.js +31 -0
  63. package/dist/agents/skills/interactions.skill.js.map +1 -0
  64. package/dist/agents/skills/registry.d.ts +23 -0
  65. package/dist/agents/skills/registry.d.ts.map +1 -0
  66. package/dist/agents/skills/registry.js +75 -0
  67. package/dist/agents/skills/registry.js.map +1 -0
  68. package/dist/agents/skills/skill-injection.d.ts +52 -0
  69. package/dist/agents/skills/skill-injection.d.ts.map +1 -0
  70. package/dist/agents/skills/skill-injection.js +210 -0
  71. package/dist/agents/skills/skill-injection.js.map +1 -0
  72. package/dist/agents/skills/types.d.ts +12 -0
  73. package/dist/agents/skills/types.d.ts.map +1 -0
  74. package/dist/agents/skills/types.js +3 -0
  75. package/dist/agents/skills/types.js.map +1 -0
  76. package/dist/builder-api-config.d.ts +7 -0
  77. package/dist/builder-api-config.d.ts.map +1 -1
  78. package/dist/builder-api-config.js.map +1 -1
  79. package/dist/context.d.ts +7 -0
  80. package/dist/context.d.ts.map +1 -1
  81. package/dist/context.js +19 -0
  82. package/dist/context.js.map +1 -1
  83. package/dist/create-builder-api.d.ts +2 -3
  84. package/dist/create-builder-api.d.ts.map +1 -1
  85. package/dist/create-builder-api.js +18 -0
  86. package/dist/create-builder-api.js.map +1 -1
  87. package/dist/index.d.ts +2 -1
  88. package/dist/index.d.ts.map +1 -1
  89. package/dist/index.js +2 -1
  90. package/dist/index.js.map +1 -1
  91. package/dist/lib/library/list-library-items.d.ts +2 -2
  92. package/dist/lib/library/list-library-items.d.ts.map +1 -1
  93. package/dist/lib/library/list-library-items.js +49 -7
  94. package/dist/lib/library/list-library-items.js.map +1 -1
  95. package/dist/lib/object-storage/index.d.ts +3 -0
  96. package/dist/lib/object-storage/index.d.ts.map +1 -0
  97. package/dist/lib/object-storage/index.js +19 -0
  98. package/dist/lib/object-storage/index.js.map +1 -0
  99. package/dist/lib/object-storage/keys.d.ts +10 -0
  100. package/dist/lib/object-storage/keys.d.ts.map +1 -0
  101. package/dist/lib/object-storage/keys.js +51 -0
  102. package/dist/lib/object-storage/keys.js.map +1 -0
  103. package/dist/lib/object-storage/s3-object-store.d.ts +14 -0
  104. package/dist/lib/object-storage/s3-object-store.d.ts.map +1 -0
  105. package/dist/lib/object-storage/s3-object-store.js +64 -0
  106. package/dist/lib/object-storage/s3-object-store.js.map +1 -0
  107. package/dist/lib/session-pages/artifact-quality-audit.d.ts +16 -0
  108. package/dist/lib/session-pages/artifact-quality-audit.d.ts.map +1 -0
  109. package/dist/lib/session-pages/artifact-quality-audit.js +293 -0
  110. package/dist/lib/session-pages/artifact-quality-audit.js.map +1 -0
  111. package/dist/lib/session-pages/artifact-storage.d.ts +3 -0
  112. package/dist/lib/session-pages/artifact-storage.d.ts.map +1 -1
  113. package/dist/lib/session-pages/artifact-storage.js +94 -85
  114. package/dist/lib/session-pages/artifact-storage.js.map +1 -1
  115. package/dist/lib/session-pages/audit-session-html.d.ts +23 -0
  116. package/dist/lib/session-pages/audit-session-html.d.ts.map +1 -0
  117. package/dist/lib/session-pages/audit-session-html.js +82 -0
  118. package/dist/lib/session-pages/audit-session-html.js.map +1 -0
  119. package/dist/lib/session-pages/contrast-check.d.ts +25 -0
  120. package/dist/lib/session-pages/contrast-check.d.ts.map +1 -0
  121. package/dist/lib/session-pages/contrast-check.js +290 -0
  122. package/dist/lib/session-pages/contrast-check.js.map +1 -0
  123. package/dist/lib/session-pages/deferred-quality-rules.d.ts +7 -0
  124. package/dist/lib/session-pages/deferred-quality-rules.d.ts.map +1 -0
  125. package/dist/lib/session-pages/deferred-quality-rules.js +25 -0
  126. package/dist/lib/session-pages/deferred-quality-rules.js.map +1 -0
  127. package/dist/lib/session-pages/delete-session-artifact.d.ts.map +1 -1
  128. package/dist/lib/session-pages/delete-session-artifact.js +12 -41
  129. package/dist/lib/session-pages/delete-session-artifact.js.map +1 -1
  130. package/dist/lib/session-pages/delete-session-artifacts.d.ts +0 -6
  131. package/dist/lib/session-pages/delete-session-artifacts.d.ts.map +1 -1
  132. package/dist/lib/session-pages/delete-session-artifacts.js +51 -15
  133. package/dist/lib/session-pages/delete-session-artifacts.js.map +1 -1
  134. package/dist/lib/session-pages/list-session-artifacts.d.ts.map +1 -1
  135. package/dist/lib/session-pages/list-session-artifacts.js +48 -48
  136. package/dist/lib/session-pages/list-session-artifacts.js.map +1 -1
  137. package/dist/lib/session-pages/read-session-artifacts.d.ts.map +1 -1
  138. package/dist/lib/session-pages/read-session-artifacts.js +4 -26
  139. package/dist/lib/session-pages/read-session-artifacts.js.map +1 -1
  140. package/dist/lib/session-pages/resolve-session-account-id.d.ts +3 -0
  141. package/dist/lib/session-pages/resolve-session-account-id.d.ts.map +1 -0
  142. package/dist/lib/session-pages/resolve-session-account-id.js +31 -0
  143. package/dist/lib/session-pages/resolve-session-account-id.js.map +1 -0
  144. package/dist/lib/session-pages/write-session-artifacts.d.ts +0 -2
  145. package/dist/lib/session-pages/write-session-artifacts.d.ts.map +1 -1
  146. package/dist/lib/session-pages/write-session-artifacts.js +8 -0
  147. package/dist/lib/session-pages/write-session-artifacts.js.map +1 -1
  148. package/dist/lib/session-plans/build-plan.d.ts +64 -0
  149. package/dist/lib/session-plans/build-plan.d.ts.map +1 -0
  150. package/dist/lib/session-plans/build-plan.js +134 -0
  151. package/dist/lib/session-plans/build-plan.js.map +1 -0
  152. package/dist/lib/yjs-pending/flush-lock.d.ts +6 -0
  153. package/dist/lib/yjs-pending/flush-lock.d.ts.map +1 -0
  154. package/dist/lib/yjs-pending/flush-lock.js +43 -0
  155. package/dist/lib/yjs-pending/flush-lock.js.map +1 -0
  156. package/dist/lib/yjs-pending/flush-worker.d.ts +5 -0
  157. package/dist/lib/yjs-pending/flush-worker.d.ts.map +1 -0
  158. package/dist/lib/yjs-pending/flush-worker.js +75 -0
  159. package/dist/lib/yjs-pending/flush-worker.js.map +1 -0
  160. package/dist/lib/yjs-pending/yjs-pending-updates-repository.d.ts +22 -0
  161. package/dist/lib/yjs-pending/yjs-pending-updates-repository.d.ts.map +1 -0
  162. package/dist/lib/yjs-pending/yjs-pending-updates-repository.js +3 -0
  163. package/dist/lib/yjs-pending/yjs-pending-updates-repository.js.map +1 -0
  164. package/dist/lib/yjs-pending/yjs-persistence.d.ts +23 -0
  165. package/dist/lib/yjs-pending/yjs-persistence.d.ts.map +1 -0
  166. package/dist/lib/yjs-pending/yjs-persistence.js +222 -0
  167. package/dist/lib/yjs-pending/yjs-persistence.js.map +1 -0
  168. package/dist/realtime/reset-session-artifact-y-docs.d.ts.map +1 -1
  169. package/dist/realtime/reset-session-artifact-y-docs.js +1 -6
  170. package/dist/realtime/reset-session-artifact-y-docs.js.map +1 -1
  171. package/dist/realtime/session-artifact-y-socket-io.d.ts +0 -5
  172. package/dist/realtime/session-artifact-y-socket-io.d.ts.map +1 -1
  173. package/dist/realtime/session-artifact-y-socket-io.js +5 -69
  174. package/dist/realtime/session-artifact-y-socket-io.js.map +1 -1
  175. package/dist/realtime/session-artifact-yjs-store.d.ts +3 -35
  176. package/dist/realtime/session-artifact-yjs-store.d.ts.map +1 -1
  177. package/dist/realtime/session-artifact-yjs-store.js +75 -235
  178. package/dist/realtime/session-artifact-yjs-store.js.map +1 -1
  179. package/dist/routes/sessions.d.ts.map +1 -1
  180. package/dist/routes/sessions.js +26 -6
  181. package/dist/routes/sessions.js.map +1 -1
  182. package/dist/routes/skills.d.ts +2 -0
  183. package/dist/routes/skills.d.ts.map +1 -0
  184. package/dist/routes/skills.js +140 -0
  185. package/dist/routes/skills.js.map +1 -0
  186. package/package.json +2 -2
@@ -0,0 +1,293 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.auditHtmlArtifact = auditHtmlArtifact;
4
+ const contrast_check_1 = require("./contrast-check");
5
+ function extractStyles(html) {
6
+ var _a, _b;
7
+ const closed = [...html.matchAll(/<style[^>]*>([\s\S]*?)<\/style>/gi)].map((m) => m[1]);
8
+ if (closed.length > 0)
9
+ return closed.join('\n');
10
+ // Unclosed <style> swallows the rest of the document — still treat that
11
+ // trailing text as the stylesheet so the other rules stay meaningful.
12
+ return (_b = (_a = html.match(/<style[^>]*>([\s\S]*)$/i)) === null || _a === void 0 ? void 0 : _a[1]) !== null && _b !== void 0 ? _b : '';
13
+ }
14
+ function extractScripts(html) {
15
+ return [...html.matchAll(/<script[^>]*>([\s\S]*?)<\/script>/gi)].map((m) => m[1]).join('\n');
16
+ }
17
+ /** Legacy Pico-era classes usable without a page-level definition (kept for
18
+ * auditing older documents that still link Pico). */
19
+ const FRAMEWORK_CLASSES = new Set([
20
+ 'container',
21
+ 'container-fluid',
22
+ 'grid',
23
+ 'secondary',
24
+ 'contrast',
25
+ 'outline',
26
+ ]);
27
+ /** Pages on the Tailwind shell style themselves via utility classes, so the
28
+ * undefined-class and thin-CSS heuristics do not apply. */
29
+ function usesTailwind(html) {
30
+ return /cdn\.tailwindcss\.com|tailwindcss/i.test(html);
31
+ }
32
+ /**
33
+ * Static quality audit for generated HTML pages. Deterministic counterpart to
34
+ * the generation skill guides: flags the failure modes they warn about so
35
+ * subagents can fix them before publishing.
36
+ */
37
+ function auditHtmlArtifact(html) {
38
+ var _a, _b, _c, _d, _e, _f;
39
+ const findings = [];
40
+ const styles = extractStyles(html);
41
+ const scripts = extractScripts(html);
42
+ const openStyleTags = ((_a = html.match(/<style[^>]*>/gi)) !== null && _a !== void 0 ? _a : []).length;
43
+ const closeStyleTags = ((_b = html.match(/<\/style>/gi)) !== null && _b !== void 0 ? _b : []).length;
44
+ const hasUnclosedStyle = openStyleTags > closeStyleTags;
45
+ if (hasUnclosedStyle) {
46
+ findings.push({
47
+ rule: 'unclosed-style',
48
+ severity: 'error',
49
+ message: '<style> tag is never closed — everything after it is swallowed as CSS. Add the missing </style> first; other style checks are skipped until it is fixed.',
50
+ });
51
+ }
52
+ const openScriptTags = ((_c = html.match(/<script[^>]*>/gi)) !== null && _c !== void 0 ? _c : []).length;
53
+ const closeScriptTags = ((_d = html.match(/<\/script>/gi)) !== null && _d !== void 0 ? _d : []).length;
54
+ if (openScriptTags > closeScriptTags) {
55
+ findings.push({
56
+ rule: 'unclosed-script',
57
+ severity: 'error',
58
+ message: '<script> tag is never closed — everything after it is swallowed as JavaScript. Add the missing </script>.',
59
+ });
60
+ }
61
+ // Legacy Pico-based pages: Pico is (nearly) classless — it styles bare
62
+ // elements and ships no utility classes, so any class the markup references
63
+ // does nothing unless the page's own <style> defines it. Tailwind pages are
64
+ // exempt (utilities ARE the styling). Also skipped while a <style> tag is
65
+ // unclosed — that breakage makes class detection unreliable.
66
+ const tailwind = usesTailwind(html);
67
+ if (!hasUnclosedStyle && !tailwind) {
68
+ const referencedClasses = new Set();
69
+ for (const match of html.matchAll(/class=["']([^"']+)["']/gi)) {
70
+ for (const token of match[1].split(/\s+/)) {
71
+ if (token)
72
+ referencedClasses.add(token);
73
+ }
74
+ }
75
+ const undefinedClasses = [...referencedClasses].filter((token) => !FRAMEWORK_CLASSES.has(token) && !styles.includes(`.${token}`) && !scripts.includes(token));
76
+ if (undefinedClasses.length > 0) {
77
+ findings.push({
78
+ rule: 'undefined-classes',
79
+ severity: 'error',
80
+ message: `These classes have no CSS — the base stylesheet (Pico) has no utility classes, so a class does nothing until your <style> defines it. Add a rule for each of: ${undefinedClasses
81
+ .slice(0, 12)
82
+ .join(', ')}${undefinedClasses.length > 12 ? ` +${undefinedClasses.length - 12} more` : ''} — or delete the class attribute.`,
83
+ });
84
+ }
85
+ }
86
+ // Advisory: native form submits are legitimate scriptless buttons, so this
87
+ // cannot be a hard invariant — but a page full of dead toggles usually is.
88
+ // Checks INLINE script content: src-only tags (e.g. the Tailwind CDN loader)
89
+ // don't count as page behavior.
90
+ if (/<button[\s>]/i.test(html) && scripts.trim().length === 0) {
91
+ findings.push({
92
+ rule: 'static-controls',
93
+ severity: 'warning',
94
+ message: '<button> elements present but the page has no <script> — interactive controls (toggles, filters, tabs) must actually work.',
95
+ });
96
+ }
97
+ // Advisory only: fragment titles are auto-derived from the first <h1> at
98
+ // wrap time, so this now fires only for pages with neither.
99
+ const titleMatch = html.match(/<title[^>]*>([^<]*)<\/title>/i);
100
+ if (titleMatch && /^(page|document|untitled)?$/i.test(titleMatch[1].trim())) {
101
+ findings.push({
102
+ rule: 'generic-title',
103
+ severity: 'warning',
104
+ message: 'Document title is missing or generic — pass a meaningful `title` (or add an <h1>, which the server uses to derive one).',
105
+ });
106
+ }
107
+ const markupOnly = html
108
+ .replace(/<style[\s\S]*?<\/style>/gi, '')
109
+ .replace(/<script[\s\S]*?<\/script>/gi, '');
110
+ // Class-strategy dark mode: dark: variants do nothing unless the page opts
111
+ // in with a .dark ancestor. Half-implemented dark mode (dark text variants
112
+ // on light backgrounds) was a severe real-world contrast failure.
113
+ if (tailwind && /class=["'][^"']*\bdark:/.test(html) && !/class=["'][^"']*\bdark\b(?!:)/.test(html)) {
114
+ findings.push({
115
+ rule: 'inert-dark-variants',
116
+ severity: 'warning',
117
+ message: 'dark: utility variants found but the page never enables the dark class — they have no effect. Style your color scheme explicitly (per the design brief) and remove the dark: variants.',
118
+ });
119
+ }
120
+ // CSS variables referenced but never defined render as transparent/initial —
121
+ // invisible buttons, black text on dark heroes. Always an authoring error.
122
+ const referencedVars = new Set([...html.matchAll(/var\((--[a-zA-Z0-9_-]+)/g)].map((match) => match[1]));
123
+ const undefinedVars = [...referencedVars].filter((name) => !new RegExp(`${name}\\s*:`).test(html));
124
+ if (undefinedVars.length > 0) {
125
+ findings.push({
126
+ rule: 'undefined-css-variable',
127
+ severity: 'error',
128
+ message: `CSS variables referenced but never defined: ${undefinedVars.join(', ')} — elements using them render transparent or inherit the wrong color. Define them in a :root block in your <style> (e.g. :root { ${undefinedVars[0]}: #0ea5e9 }).`,
129
+ });
130
+ }
131
+ // WCAG contrast: static analysis over Tailwind color utilities. This is a
132
+ // heuristic: it cannot reliably resolve every CSS cascade, overlay,
133
+ // pseudo-element, or runtime class. Findings are therefore always advisory.
134
+ // Treating an inferred contrast pair as a transactional publish error caused
135
+ // valid dark/gradient pages to regenerate the complete document repeatedly.
136
+ // Accessibility still matters, but it belongs in the targeted consistency
137
+ // pass (or a browser-backed check), not in the atomic file-write gate.
138
+ if (!hasUnclosedStyle && tailwind) {
139
+ try {
140
+ for (const issue of (0, contrast_check_1.checkContrast)(html).slice(0, 5)) {
141
+ findings.push({
142
+ rule: issue.severity === 'error' ? 'unreadable-contrast' : 'low-contrast',
143
+ severity: 'warning',
144
+ message: `WCAG contrast ${issue.ratio}:1 — "${issue.textToken}" on "${issue.bgToken}" (e.g. "${issue.snippet}"). ${issue.severity === 'error' ? 'This text is effectively invisible.' : 'Below the 4.5:1 AA minimum.'} Static analysis only; verify the rendered state and pick a text color readable on that background.`,
145
+ });
146
+ }
147
+ }
148
+ catch (_g) {
149
+ // Contrast analysis is best-effort — never break the audit on it.
150
+ }
151
+ }
152
+ // Distinctive web fonts are required — the shell no longer injects Inter.
153
+ // Google Fonts link OR an explicit font-family in <style> satisfies this.
154
+ if (!/fonts\.googleapis\.com/i.test(html) &&
155
+ !/font-family\s*:/i.test(styles) &&
156
+ !/<link[^>]+fonts\.(?:googleapis|gstatic)\.com/i.test(html)) {
157
+ findings.push({
158
+ rule: 'missing-web-font',
159
+ severity: 'error',
160
+ message: 'No web font loaded — add the design-brief Google Font pairing (<link href="https://fonts.googleapis.com/css2?family=…"> plus font-family on body). Never rely on system/Inter defaults.',
161
+ });
162
+ }
163
+ const emojiMatches = ((_e = markupOnly.match(/\p{Extended_Pictographic}/gu)) !== null && _e !== void 0 ? _e : []).filter((char) => !'©®™°†‡§¶'.includes(char));
164
+ if (emojiMatches.length > 0) {
165
+ findings.push({
166
+ rule: 'emoji-icons',
167
+ severity: 'error',
168
+ message: `${emojiMatches.length} emoji character(s) in the markup (${[...new Set(emojiMatches)]
169
+ .slice(0, 6)
170
+ .join(' ')}) — emoji are not icons; use inline SVG icons (Lucide/Heroicons, stroke="currentColor") unless the user explicitly asked for emoji content.`,
171
+ });
172
+ }
173
+ const markupLength = markupOnly.length;
174
+ if (!tailwind && markupLength > 1500 && styles.length < 1200) {
175
+ findings.push({
176
+ rule: 'thin-styling',
177
+ severity: 'warning',
178
+ message: `Only ${styles.length} chars of CSS for ${markupLength} chars of markup — this reads as an unstyled page. Build the full design system: layout container, cards, spacing scale, hover/focus states.`,
179
+ });
180
+ }
181
+ // Web-font hosts are the one sanctioned external dependency (the designer
182
+ // guide mandates a Google Fonts pairing) — everything else remote is a 404
183
+ // waiting to happen.
184
+ const externalStyleUrl = /url\(\s*["']?https?:\/\/(?!fonts\.googleapis\.com|fonts\.gstatic\.com)/i;
185
+ if (/<img[^>]+src=["']https?:/i.test(html) || externalStyleUrl.test(styles)) {
186
+ findings.push({
187
+ rule: 'external-image',
188
+ severity: 'error',
189
+ message: 'External image/asset URLs can 404 — replace with inline SVG, CSS gradients, or data: URIs (Google Fonts imports are allowed).',
190
+ });
191
+ }
192
+ if (/lorem\s+ipsum/i.test(html)) {
193
+ findings.push({
194
+ rule: 'placeholder-copy',
195
+ severity: 'error',
196
+ message: 'Lorem ipsum found — write realistic, domain-appropriate content instead.',
197
+ });
198
+ }
199
+ if (/\b(?:Item|Feature|Card|Product)\s+[0-9]\b/.test(html)) {
200
+ findings.push({
201
+ rule: 'generic-sample-data',
202
+ severity: 'error',
203
+ message: 'Generic sample data ("Item 1"…) found — use realistic, internally consistent examples.',
204
+ });
205
+ }
206
+ // Generic marketing filler — ships as "AI template" even when layout is fine.
207
+ if (/\bwelcome\s+to\s+(?:our|the)\b/i.test(markupOnly)) {
208
+ findings.push({
209
+ rule: 'template-copy',
210
+ severity: 'error',
211
+ message: 'Template copy ("Welcome to our/the…") found — lead with the product outcome instead.',
212
+ });
213
+ }
214
+ if (/\b(?:revolutionary|seamless|cutting-edge|unleash(?:ing)?|empower(?:ing)?)\b/i.test(markupOnly)) {
215
+ findings.push({
216
+ rule: 'template-copy',
217
+ severity: 'error',
218
+ message: 'Banned template adjectives found (revolutionary/seamless/cutting-edge/unleash/empower) — use concrete, domain-specific language.',
219
+ });
220
+ }
221
+ // Inter is the default AI-page tell — designer skill and design brief forbid it.
222
+ if (/family=Inter\b|font-family:\s*['"]?Inter\b/i.test(html)) {
223
+ findings.push({
224
+ rule: 'generic-font',
225
+ severity: 'error',
226
+ message: 'Inter font detected — replace with the design-brief pairing (Manrope/Sora/Fraunces/Outfit/…).',
227
+ });
228
+ }
229
+ // Indigo/violet gradient walls are the strongest "AI SaaS template" signal.
230
+ if (/(?:from|via|to)-(?:indigo|violet|purple)-\d{2,3}|(?:bg|text|border)-(?:indigo|violet)-[56]00/i.test(markupOnly)) {
231
+ findings.push({
232
+ rule: 'ai-palette-cliche',
233
+ severity: 'warning',
234
+ message: 'Indigo/violet palette utilities detected — unless the design brief explicitly chose indigo, switch to the brief accent hex for a topic-fit look.',
235
+ });
236
+ }
237
+ if (/\son(?:click|change|input|submit|mouseover|keydown|load)\s*=/i.test(html)) {
238
+ findings.push({
239
+ rule: 'inline-handler',
240
+ severity: 'warning',
241
+ message: 'Inline event handler attributes found — wire behavior with addEventListener instead.',
242
+ });
243
+ }
244
+ if (/(?:animation|transition)\s*:/i.test(styles) && !/prefers-reduced-motion/i.test(html)) {
245
+ findings.push({
246
+ rule: 'missing-reduced-motion',
247
+ severity: 'warning',
248
+ message: 'Animations/transitions without a prefers-reduced-motion guard.',
249
+ });
250
+ }
251
+ if (/(?:background(?:-color)?|(?<![a-z-])color)\s*:\s*(?:#(?:fff(?:fff)?|000(?:000)?)\b|white\b|black\b)/i.test(styles)) {
252
+ findings.push({
253
+ rule: 'hard-coded-scheme-color',
254
+ severity: 'warning',
255
+ message: 'Hard-coded black/white colors break light/dark schemes — use your design-token CSS variables (with color-mix) or dark-mode variants instead.',
256
+ });
257
+ }
258
+ const h1Count = ((_f = html.match(/<h1[\s>]/gi)) !== null && _f !== void 0 ? _f : []).length;
259
+ if (h1Count === 0) {
260
+ findings.push({
261
+ rule: 'missing-h1',
262
+ severity: 'error',
263
+ message: 'Page has no <h1> — add one clear page headline.',
264
+ });
265
+ }
266
+ else if (h1Count > 1) {
267
+ findings.push({
268
+ rule: 'multiple-h1',
269
+ severity: 'warning',
270
+ message: `Page has ${h1Count} <h1> elements — keep one and demote the rest.`,
271
+ });
272
+ }
273
+ if (/href=["']#["']/.test(html)) {
274
+ findings.push({
275
+ rule: 'dead-link',
276
+ severity: 'warning',
277
+ message: 'href="#" links found — prefer real section ids, index.html, or <button> for actions.',
278
+ });
279
+ }
280
+ const hasVisibleInputs = /<(?:input(?![^>]*type=["']hidden)|select|textarea)[\s>]/i.test(html);
281
+ if (hasVisibleInputs && !/<label[\s>]/i.test(html) && !/aria-label(?:ledby)?=/i.test(html)) {
282
+ findings.push({
283
+ rule: 'unlabeled-inputs',
284
+ severity: 'error',
285
+ message: 'Form controls without any <label> or aria-label — every control needs an accessible name.',
286
+ });
287
+ }
288
+ return {
289
+ clean: findings.length === 0,
290
+ findings,
291
+ };
292
+ }
293
+ //# sourceMappingURL=artifact-quality-audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-quality-audit.js","sourceRoot":"","sources":["../../../src/lib/session-pages/artifact-quality-audit.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { sessionArtifactsPrefix, isSessionArtifactUserFacingKey, relativeSessionArtifactPath } from '../object-storage/keys';
1
2
  export declare function writeArtifactLatestState(sessionId: string, artifactPath: string, state: Uint8Array): Promise<void>;
2
3
  export declare function readArtifactLatestState(sessionId: string, artifactPath: string): Promise<Uint8Array | null>;
3
4
  export declare function writeArtifactContentSnapshot(sessionId: string, artifactPath: string, content: string): Promise<void>;
@@ -5,4 +6,6 @@ export declare function readArtifactContentSnapshot(sessionId: string, artifactP
5
6
  export declare function writeArtifactNamedSnapshot(sessionId: string, artifactPath: string, content: string, at?: Date): Promise<string>;
6
7
  export declare function listArtifactSnapshotPaths(sessionId: string, artifactPath: string): Promise<string[]>;
7
8
  export declare function deleteArtifactStorageFiles(sessionId: string, artifactPath: string): Promise<void>;
9
+ export declare function sessionArtifactExistsOnStorage(sessionId: string, artifactPath: string): Promise<boolean>;
10
+ export { isSessionArtifactUserFacingKey, relativeSessionArtifactPath, sessionArtifactsPrefix };
8
11
  //# sourceMappingURL=artifact-storage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"artifact-storage.d.ts","sourceRoot":"","sources":["../../../src/lib/session-pages/artifact-storage.ts"],"names":[],"mappings":"AASA,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,UAAU,GAChB,OAAO,CAAC,IAAI,CAAC,CAKf;AAED,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAW5B;AAED,wBAAsB,4BAA4B,CAChD,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAIf;AAED,wBAAsB,2BAA2B,CAC/C,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAUxB;AAED,wBAAsB,0BAA0B,CAC9C,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,EAAE,GAAE,IAAiB,GACpB,OAAO,CAAC,MAAM,CAAC,CAMjB;AAgCD,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,EAAE,CAAC,CAYnB;AAED,wBAAsB,0BAA0B,CAC9C,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAqBf"}
1
+ {"version":3,"file":"artifact-storage.d.ts","sourceRoot":"","sources":["../../../src/lib/session-pages/artifact-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,sBAAsB,EACtB,8BAA8B,EAC9B,2BAA2B,EAC5B,MAAM,wBAAwB,CAAA;AAS/B,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,UAAU,GAChB,OAAO,CAAC,IAAI,CAAC,CAGf;AAED,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAG5B;AAED,wBAAsB,4BAA4B,CAChD,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAGf;AAED,wBAAsB,2BAA2B,CAC/C,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGxB;AAED,wBAAsB,0BAA0B,CAC9C,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,EAAE,GAAE,IAAiB,GACpB,OAAO,CAAC,MAAM,CAAC,CAKjB;AAED,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,EAAE,CAAC,CAQnB;AAED,wBAAsB,0BAA0B,CAC9C,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CA6Bf;AAED,wBAAsB,8BAA8B,CAClD,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,OAAO,CAAC,CAUlB;AAED,OAAO,EAAE,8BAA8B,EAAE,2BAA2B,EAAE,sBAAsB,EAAE,CAAA"}
@@ -1,8 +1,39 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
5
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.sessionArtifactsPrefix = exports.relativeSessionArtifactPath = exports.isSessionArtifactUserFacingKey = void 0;
6
37
  exports.writeArtifactLatestState = writeArtifactLatestState;
7
38
  exports.readArtifactLatestState = readArtifactLatestState;
8
39
  exports.writeArtifactContentSnapshot = writeArtifactContentSnapshot;
@@ -10,104 +41,82 @@ exports.readArtifactContentSnapshot = readArtifactContentSnapshot;
10
41
  exports.writeArtifactNamedSnapshot = writeArtifactNamedSnapshot;
11
42
  exports.listArtifactSnapshotPaths = listArtifactSnapshotPaths;
12
43
  exports.deleteArtifactStorageFiles = deleteArtifactStorageFiles;
13
- const promises_1 = __importDefault(require("node:fs/promises"));
14
- const node_path_1 = __importDefault(require("node:path"));
44
+ exports.sessionArtifactExistsOnStorage = sessionArtifactExistsOnStorage;
45
+ const keys_1 = require("../object-storage/keys");
46
+ Object.defineProperty(exports, "sessionArtifactsPrefix", { enumerable: true, get: function () { return keys_1.sessionArtifactsPrefix; } });
47
+ Object.defineProperty(exports, "isSessionArtifactUserFacingKey", { enumerable: true, get: function () { return keys_1.isSessionArtifactUserFacingKey; } });
48
+ Object.defineProperty(exports, "relativeSessionArtifactPath", { enumerable: true, get: function () { return keys_1.relativeSessionArtifactPath; } });
49
+ const s3 = __importStar(require("../object-storage/s3-object-store"));
50
+ const context_1 = require("../../context");
51
+ const session_artifact_document_id_1 = require("../../realtime/session-artifact-document-id");
52
+ const flush_lock_1 = require("../yjs-pending/flush-lock");
15
53
  const artifact_storage_paths_1 = require("./artifact-storage-paths");
16
54
  const paths_1 = require("./paths");
55
+ const resolve_session_account_id_1 = require("./resolve-session-account-id");
17
56
  async function writeArtifactLatestState(sessionId, artifactPath, state) {
18
- const relativeStatePath = (0, artifact_storage_paths_1.artifactLatestStatePath)(artifactPath);
19
- const absolutePath = (0, paths_1.resolveArtifactPath)(sessionId, relativeStatePath);
20
- await promises_1.default.mkdir(node_path_1.default.dirname(absolutePath), { recursive: true });
21
- await promises_1.default.writeFile(absolutePath, Buffer.from(state));
57
+ const accountId = await (0, resolve_session_account_id_1.resolveSessionAccountId)(sessionId);
58
+ await s3.putBytes((0, keys_1.sessionArtifactLatestStateKey)(accountId, sessionId, artifactPath), state);
22
59
  }
23
60
  async function readArtifactLatestState(sessionId, artifactPath) {
24
- try {
25
- const absolutePath = (0, paths_1.resolveArtifactPath)(sessionId, (0, artifact_storage_paths_1.artifactLatestStatePath)(artifactPath));
26
- const data = await promises_1.default.readFile(absolutePath);
27
- return new Uint8Array(data);
28
- }
29
- catch (error) {
30
- if (error.code === 'ENOENT') {
31
- return null;
32
- }
33
- throw error;
34
- }
61
+ const accountId = await (0, resolve_session_account_id_1.resolveSessionAccountId)(sessionId);
62
+ return s3.getBytes((0, keys_1.sessionArtifactLatestStateKey)(accountId, sessionId, artifactPath));
35
63
  }
36
64
  async function writeArtifactContentSnapshot(sessionId, artifactPath, content) {
37
- const absolutePath = (0, paths_1.resolveArtifactPath)(sessionId, artifactPath);
38
- await promises_1.default.mkdir(node_path_1.default.dirname(absolutePath), { recursive: true });
39
- await promises_1.default.writeFile(absolutePath, content, 'utf8');
65
+ const accountId = await (0, resolve_session_account_id_1.resolveSessionAccountId)(sessionId);
66
+ await s3.putString((0, keys_1.sessionArtifactContentKey)(accountId, sessionId, artifactPath), content);
40
67
  }
41
68
  async function readArtifactContentSnapshot(sessionId, artifactPath) {
42
- try {
43
- const absolutePath = (0, paths_1.resolveArtifactPath)(sessionId, artifactPath);
44
- return await promises_1.default.readFile(absolutePath, 'utf8');
45
- }
46
- catch (error) {
47
- if (error.code === 'ENOENT') {
48
- return null;
49
- }
50
- throw error;
51
- }
69
+ const accountId = await (0, resolve_session_account_id_1.resolveSessionAccountId)(sessionId);
70
+ return s3.getString((0, keys_1.sessionArtifactContentKey)(accountId, sessionId, artifactPath));
52
71
  }
53
72
  async function writeArtifactNamedSnapshot(sessionId, artifactPath, content, at = new Date()) {
54
- const relativePath = (0, artifact_storage_paths_1.artifactSnapshotPath)(artifactPath, at);
55
- const absolutePath = (0, paths_1.resolveArtifactPath)(sessionId, relativePath);
56
- await promises_1.default.mkdir(node_path_1.default.dirname(absolutePath), { recursive: true });
57
- await promises_1.default.writeFile(absolutePath, content, 'utf8');
58
- return relativePath;
59
- }
60
- async function walkFiles(dir, root, onFile) {
61
- let entries;
62
- try {
63
- entries = await promises_1.default.readdir(dir, { withFileTypes: true });
64
- }
65
- catch (error) {
66
- if (error.code === 'ENOENT') {
67
- return;
68
- }
69
- throw error;
70
- }
71
- for (const entry of entries) {
72
- const absolute = node_path_1.default.join(dir, entry.name);
73
- if (entry.isDirectory()) {
74
- await walkFiles(absolute, root, onFile);
75
- continue;
76
- }
77
- if (!entry.isFile()) {
78
- continue;
79
- }
80
- const relative = node_path_1.default.relative(root, absolute).split(node_path_1.default.sep).join('/');
81
- await onFile(relative);
82
- }
73
+ const accountId = await (0, resolve_session_account_id_1.resolveSessionAccountId)(sessionId);
74
+ const key = (0, keys_1.sessionArtifactNamedSnapshotKey)(accountId, sessionId, artifactPath, at);
75
+ await s3.putString(key, content);
76
+ return key;
83
77
  }
84
78
  async function listArtifactSnapshotPaths(sessionId, artifactPath) {
85
- const root = (0, paths_1.getSessionDir)(sessionId);
79
+ const accountId = await (0, resolve_session_account_id_1.resolveSessionAccountId)(sessionId);
80
+ const prefix = (0, keys_1.sessionArtifactsPrefix)(accountId, sessionId);
86
81
  const normalized = (0, paths_1.normalizeArtifactPath)(artifactPath);
87
- const snapshots = [];
88
- await walkFiles(root, root, (relativePath) => {
89
- if ((0, artifact_storage_paths_1.isSnapshotForArtifact)(relativePath, normalized)) {
90
- snapshots.push(relativePath);
91
- }
92
- });
93
- return snapshots.sort((a, b) => a.localeCompare(b));
82
+ return (await s3.listKeysByPrefix(prefix))
83
+ .map((o) => (0, keys_1.relativeSessionArtifactPath)(prefix, o.key))
84
+ .filter((relative) => (0, artifact_storage_paths_1.isSnapshotForArtifact)(relative, normalized))
85
+ .sort();
94
86
  }
95
87
  async function deleteArtifactStorageFiles(sessionId, artifactPath) {
88
+ const accountId = await (0, resolve_session_account_id_1.resolveSessionAccountId)(sessionId);
89
+ const normalized = (0, paths_1.normalizeArtifactPath)(artifactPath);
90
+ const documentId = (0, session_artifact_document_id_1.buildSessionArtifactDocumentId)(sessionId, normalized);
91
+ const prefix = (0, keys_1.sessionArtifactsPrefix)(accountId, sessionId);
92
+ const objects = await s3.listKeysByPrefix(prefix);
93
+ const run = async () => {
94
+ await (0, context_1.getYjsPendingUpdatesRepository)().deleteByDocumentId(documentId);
95
+ await Promise.all(objects
96
+ .filter((o) => {
97
+ const relative = (0, keys_1.relativeSessionArtifactPath)(prefix, o.key);
98
+ return (relative === normalized ||
99
+ relative === `${normalized}.latest.state` ||
100
+ (0, artifact_storage_paths_1.isSnapshotForArtifact)(relative, normalized));
101
+ })
102
+ .map((o) => s3.deleteObject(o.key)));
103
+ };
104
+ const redis = (0, context_1.getSharedRedisClient)();
105
+ if (redis) {
106
+ await (0, flush_lock_1.withFlushLock)(redis, documentId, run);
107
+ return;
108
+ }
109
+ await run();
110
+ }
111
+ async function sessionArtifactExistsOnStorage(sessionId, artifactPath) {
112
+ const accountId = await (0, resolve_session_account_id_1.resolveSessionAccountId)(sessionId);
96
113
  const normalized = (0, paths_1.normalizeArtifactPath)(artifactPath);
97
- const targets = [
98
- (0, paths_1.resolveArtifactPath)(sessionId, normalized),
99
- (0, paths_1.resolveArtifactPath)(sessionId, (0, artifact_storage_paths_1.artifactLatestStatePath)(normalized)),
100
- ...(await listArtifactSnapshotPaths(sessionId, normalized)).map((snapshotPath) => (0, paths_1.resolveArtifactPath)(sessionId, snapshotPath)),
101
- ];
102
- await Promise.all(targets.map(async (absolutePath) => {
103
- try {
104
- await promises_1.default.unlink(absolutePath);
105
- }
106
- catch (error) {
107
- if (error.code !== 'ENOENT') {
108
- throw error;
109
- }
110
- }
111
- }));
114
+ const documentId = (0, session_artifact_document_id_1.buildSessionArtifactDocumentId)(sessionId, normalized);
115
+ const [content, latest, pendingCount] = await Promise.all([
116
+ s3.objectExists((0, keys_1.sessionArtifactContentKey)(accountId, sessionId, normalized)),
117
+ s3.objectExists((0, keys_1.sessionArtifactLatestStateKey)(accountId, sessionId, normalized)),
118
+ (0, context_1.getYjsPendingUpdatesRepository)().countByDocumentId(documentId),
119
+ ]);
120
+ return content || latest || pendingCount > 0;
112
121
  }
113
122
  //# sourceMappingURL=artifact-storage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"artifact-storage.js","sourceRoot":"","sources":["../../../src/lib/session-pages/artifact-storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"artifact-storage.js","sourceRoot":"","sources":["../../../src/lib/session-pages/artifact-storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { type QualityFinding } from './artifact-quality-audit';
2
+ export interface SessionQualityIssue {
3
+ path: string;
4
+ findings: QualityFinding[];
5
+ }
6
+ export interface SessionQualityReport {
7
+ issues: SessionQualityIssue[];
8
+ /** Actionable findings only (excludes deferred heuristics like contrast). */
9
+ actionableIssues: SessionQualityIssue[];
10
+ /** Flat lines suitable for plan.openAdvisories / tool output (actionable only). */
11
+ advisoryLines: string[];
12
+ errorCount: number;
13
+ warningCount: number;
14
+ deferredWarningCount: number;
15
+ }
16
+ /**
17
+ * Re-audit every HTML artifact in the session. Used by the consistency pass
18
+ * to prove polish work actually cleared quality findings.
19
+ */
20
+ export declare function auditSessionHtmlArtifacts(sessionId: string): Promise<SessionQualityReport>;
21
+ /** Compact path → finding lines for openAdvisories storage (actionable only). */
22
+ export declare function sessionQualityToAdvisoryLines(report: SessionQualityReport): string[];
23
+ //# sourceMappingURL=audit-session-html.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-session-html.d.ts","sourceRoot":"","sources":["../../../src/lib/session-pages/audit-session-html.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAKjF,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,cAAc,EAAE,CAAA;CAC3B;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,mBAAmB,EAAE,CAAA;IAC7B,6EAA6E;IAC7E,gBAAgB,EAAE,mBAAmB,EAAE,CAAA;IACvC,mFAAmF;IACnF,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,oBAAoB,EAAE,MAAM,CAAA;CAC7B;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAuEhG;AAED,iFAAiF;AACjF,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,EAAE,CAIpF"}