tevra-design-kit 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/LICENSE +21 -0
  2. package/PROVENANCE.md +18 -0
  3. package/README.md +251 -2
  4. package/SKILL.md +20 -0
  5. package/THIRD_PARTY_NOTICES.md +23 -0
  6. package/adapters/claude-code/CLAUDE.md +14 -0
  7. package/adapters/codex/AGENTS.md +5 -0
  8. package/adapters/cursor/README.md +5 -0
  9. package/adapters/gemini-cli/README.md +5 -0
  10. package/adapters/github-copilot/README.md +5 -0
  11. package/adapters/kiro/README.md +5 -0
  12. package/adapters/opencode/README.md +5 -0
  13. package/adapters/windsurf/README.md +5 -0
  14. package/dist/packages/cli/src/arguments.d.ts +9 -0
  15. package/dist/packages/cli/src/arguments.js +58 -0
  16. package/dist/packages/cli/src/arguments.js.map +1 -0
  17. package/dist/packages/cli/src/index.d.ts +2 -0
  18. package/dist/packages/cli/src/index.js +132 -0
  19. package/dist/packages/cli/src/index.js.map +1 -0
  20. package/dist/packages/cli/src/project-commands.d.ts +4 -0
  21. package/dist/packages/cli/src/project-commands.js +137 -0
  22. package/dist/packages/cli/src/project-commands.js.map +1 -0
  23. package/dist/packages/cli/src/run-command.d.ts +2 -0
  24. package/dist/packages/cli/src/run-command.js +35 -0
  25. package/dist/packages/cli/src/run-command.js.map +1 -0
  26. package/dist/packages/cli/src/visual-commands.d.ts +5 -0
  27. package/dist/packages/cli/src/visual-commands.js +73 -0
  28. package/dist/packages/cli/src/visual-commands.js.map +1 -0
  29. package/dist/packages/cli/src/workflow-commands.d.ts +2 -0
  30. package/dist/packages/cli/src/workflow-commands.js +73 -0
  31. package/dist/packages/cli/src/workflow-commands.js.map +1 -0
  32. package/dist/packages/contracts/src/index.d.ts +181 -0
  33. package/dist/packages/contracts/src/index.js +3 -0
  34. package/dist/packages/contracts/src/index.js.map +1 -0
  35. package/dist/packages/core/src/analyze.d.ts +6 -0
  36. package/dist/packages/core/src/analyze.js +46 -0
  37. package/dist/packages/core/src/analyze.js.map +1 -0
  38. package/dist/packages/core/src/config.d.ts +4 -0
  39. package/dist/packages/core/src/config.js +39 -0
  40. package/dist/packages/core/src/config.js.map +1 -0
  41. package/dist/packages/core/src/install.d.ts +13 -0
  42. package/dist/packages/core/src/install.js +69 -0
  43. package/dist/packages/core/src/install.js.map +1 -0
  44. package/dist/packages/core/src/router.d.ts +12 -0
  45. package/dist/packages/core/src/router.js +90 -0
  46. package/dist/packages/core/src/router.js.map +1 -0
  47. package/dist/packages/core/src/search.d.ts +12 -0
  48. package/dist/packages/core/src/search.js +31 -0
  49. package/dist/packages/core/src/search.js.map +1 -0
  50. package/dist/packages/core/src/skills.d.ts +7 -0
  51. package/dist/packages/core/src/skills.js +36 -0
  52. package/dist/packages/core/src/skills.js.map +1 -0
  53. package/dist/packages/core/src/workflow.d.ts +3 -0
  54. package/dist/packages/core/src/workflow.js +73 -0
  55. package/dist/packages/core/src/workflow.js.map +1 -0
  56. package/dist/packages/design-context/src/index.d.ts +5 -0
  57. package/dist/packages/design-context/src/index.js +41 -0
  58. package/dist/packages/design-context/src/index.js.map +1 -0
  59. package/dist/packages/design-context/src/migrate.d.ts +2 -0
  60. package/dist/packages/design-context/src/migrate.js +27 -0
  61. package/dist/packages/design-context/src/migrate.js.map +1 -0
  62. package/dist/packages/design-context/src/tokens.d.ts +8 -0
  63. package/dist/packages/design-context/src/tokens.js +65 -0
  64. package/dist/packages/design-context/src/tokens.js.map +1 -0
  65. package/dist/packages/design-context/src/validation.d.ts +1 -0
  66. package/dist/packages/design-context/src/validation.js +22 -0
  67. package/dist/packages/design-context/src/validation.js.map +1 -0
  68. package/dist/packages/design-memory/src/index.d.ts +16 -0
  69. package/dist/packages/design-memory/src/index.js +47 -0
  70. package/dist/packages/design-memory/src/index.js.map +1 -0
  71. package/dist/packages/filesystem/src/index.d.ts +8 -0
  72. package/dist/packages/filesystem/src/index.js +83 -0
  73. package/dist/packages/filesystem/src/index.js.map +1 -0
  74. package/dist/packages/filesystem/src/resources.d.ts +1 -0
  75. package/dist/packages/filesystem/src/resources.js +13 -0
  76. package/dist/packages/filesystem/src/resources.js.map +1 -0
  77. package/dist/packages/performance-qa/src/index.d.ts +24 -0
  78. package/dist/packages/performance-qa/src/index.js +77 -0
  79. package/dist/packages/performance-qa/src/index.js.map +1 -0
  80. package/dist/packages/quality-engine/src/html.d.ts +2 -0
  81. package/dist/packages/quality-engine/src/html.js +15 -0
  82. package/dist/packages/quality-engine/src/html.js.map +1 -0
  83. package/dist/packages/quality-engine/src/index.d.ts +3 -0
  84. package/dist/packages/quality-engine/src/index.js +45 -0
  85. package/dist/packages/quality-engine/src/index.js.map +1 -0
  86. package/dist/packages/registry/src/index.d.ts +49 -0
  87. package/dist/packages/registry/src/index.js +132 -0
  88. package/dist/packages/registry/src/index.js.map +1 -0
  89. package/dist/packages/visual-testing/src/capture.d.ts +12 -0
  90. package/dist/packages/visual-testing/src/capture.js +174 -0
  91. package/dist/packages/visual-testing/src/capture.js.map +1 -0
  92. package/dist/packages/visual-testing/src/checks.d.ts +3 -0
  93. package/dist/packages/visual-testing/src/checks.js +17 -0
  94. package/dist/packages/visual-testing/src/checks.js.map +1 -0
  95. package/dist/packages/visual-testing/src/compare.d.ts +12 -0
  96. package/dist/packages/visual-testing/src/compare.js +85 -0
  97. package/dist/packages/visual-testing/src/compare.js.map +1 -0
  98. package/dist/packages/visual-testing/src/types.d.ts +49 -0
  99. package/dist/packages/visual-testing/src/types.js +2 -0
  100. package/dist/packages/visual-testing/src/types.js.map +1 -0
  101. package/dist/packages/workflow-engine/src/index.d.ts +11 -0
  102. package/dist/packages/workflow-engine/src/index.js +51 -0
  103. package/dist/packages/workflow-engine/src/index.js.map +1 -0
  104. package/docs/agents.md +36 -0
  105. package/docs/architecture.md +86 -0
  106. package/docs/configuration.md +109 -0
  107. package/docs/contributing.md +75 -0
  108. package/docs/security.md +42 -0
  109. package/docs/usage.md +142 -0
  110. package/package.json +85 -4
  111. package/references/accessibility/manual-checklist.md +3 -0
  112. package/references/color-systems/semantic-color.md +3 -0
  113. package/references/design-principles/decision-making.md +3 -0
  114. package/references/frameworks/nextjs.md +3 -0
  115. package/references/frameworks/react-native-expo.md +3 -0
  116. package/references/frameworks/react.md +3 -0
  117. package/references/frameworks/sveltekit.md +3 -0
  118. package/references/frameworks/vue.md +3 -0
  119. package/references/typography/scales.md +3 -0
  120. package/references/ux-patterns/README.md +7 -0
  121. package/references/ux-patterns/UPSTREAM-LICENSE.txt +21 -0
  122. package/references/ux-patterns/catalog.json +221 -0
  123. package/registry/capability-ownership.json +191 -0
  124. package/registry/skills.json +764 -0
  125. package/registry/sources.json +159 -0
  126. package/rubrics/quality-rubric.md +24 -0
  127. package/schemas/capability-ownership.schema.json +69 -0
  128. package/schemas/capture-manifest.schema.json +209 -0
  129. package/schemas/checks.schema.json +83 -0
  130. package/schemas/comparison.schema.json +154 -0
  131. package/schemas/config.schema.json +297 -0
  132. package/schemas/design-context.schema.json +651 -0
  133. package/schemas/design-context.v2.schema.json +395 -0
  134. package/schemas/handoff.schema.json +135 -0
  135. package/schemas/legacy/design-context.master-v1.schema.json +167 -0
  136. package/schemas/legacy/design-context.v1.schema.json +36 -0
  137. package/schemas/memory.schema.json +69 -0
  138. package/schemas/plan.schema.json +139 -0
  139. package/schemas/quality-report.schema.json +151 -0
  140. package/schemas/skill-registry.schema.json +222 -0
  141. package/schemas/sources.schema.json +129 -0
  142. package/skills/accessibility-qa/LICENSE +21 -0
  143. package/skills/accessibility-qa/SKILL.md +56 -0
  144. package/skills/accessibility-qa/references/guide.md +3 -0
  145. package/skills/browser-testing/LICENSE +21 -0
  146. package/skills/browser-testing/SKILL.md +35 -0
  147. package/skills/browser-testing/references/guide.md +11 -0
  148. package/skills/design-direction/LICENSE +21 -0
  149. package/skills/design-direction/SKILL.md +56 -0
  150. package/skills/design-direction/references/guide.md +3 -0
  151. package/skills/design-research/LICENSE +21 -0
  152. package/skills/design-research/SKILL.md +56 -0
  153. package/skills/design-research/references/guide.md +3 -0
  154. package/skills/design-system/LICENSE +21 -0
  155. package/skills/design-system/SKILL.md +56 -0
  156. package/skills/design-system/references/guide.md +3 -0
  157. package/skills/frontend-review/LICENSE +21 -0
  158. package/skills/frontend-review/SKILL.md +35 -0
  159. package/skills/frontend-review/references/guide.md +11 -0
  160. package/skills/interaction-motion/LICENSE +21 -0
  161. package/skills/interaction-motion/SKILL.md +56 -0
  162. package/skills/interaction-motion/references/guide.md +3 -0
  163. package/skills/performance-qa/LICENSE +21 -0
  164. package/skills/performance-qa/SKILL.md +35 -0
  165. package/skills/performance-qa/references/guide.md +9 -0
  166. package/skills/responsive-design/LICENSE +21 -0
  167. package/skills/responsive-design/SKILL.md +56 -0
  168. package/skills/responsive-design/references/guide.md +3 -0
  169. package/skills/ui-builder/LICENSE +21 -0
  170. package/skills/ui-builder/SKILL.md +58 -0
  171. package/skills/ui-builder/references/guide.md +3 -0
  172. package/skills/ui-builder/references/nextjs.md +3 -0
  173. package/skills/ui-builder/references/react-native-expo.md +3 -0
  174. package/skills/ui-builder/references/react.md +3 -0
  175. package/skills/ui-builder/references/sveltekit.md +3 -0
  176. package/skills/ui-builder/references/vue.md +3 -0
  177. package/skills/ui-redesign/LICENSE +21 -0
  178. package/skills/ui-redesign/SKILL.md +56 -0
  179. package/skills/ui-redesign/references/guide.md +3 -0
  180. package/skills/visual-review/LICENSE +21 -0
  181. package/skills/visual-review/SKILL.md +56 -0
  182. package/skills/visual-review/references/guide.md +7 -0
  183. package/templates/direction-decision.md +45 -0
  184. package/templates/research-brief.md +56 -0
  185. package/templates/visual-review.md +46 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../../../packages/design-context/src/migrate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { DesignContext } from '../../contracts/src/index.js';
2
+ export declare function contrastRatio(first: string, second: string): number;
3
+ export declare function createFoundation(brand?: string): DesignContext['tokens'];
4
+ export declare function exportTokens(tokens: DesignContext['tokens']): {
5
+ css: string;
6
+ tailwind: string;
7
+ portable: string;
8
+ };
@@ -0,0 +1,65 @@
1
+ export function contrastRatio(first, second) {
2
+ function luminance(hex) {
3
+ if (!/^#[\da-f]{6}$/iu.test(hex))
4
+ throw new Error('Contrast input must be a six-digit hex color');
5
+ const channels = [1, 3, 5].map(offset => { const channel = Number.parseInt(hex.slice(offset, offset + 2), 16) / 255; return channel <= 0.04045 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4; });
6
+ return (channels[0] ?? 0) * 0.2126 + (channels[1] ?? 0) * 0.7152 + (channels[2] ?? 0) * 0.0722;
7
+ }
8
+ const left = luminance(first);
9
+ const right = luminance(second);
10
+ return (Math.max(left, right) + 0.05) / (Math.min(left, right) + 0.05);
11
+ }
12
+ export function createFoundation(brand = '#175a44') {
13
+ if (!/^#[\da-f]{6}$/iu.test(brand))
14
+ throw new Error('Brand color must be a six-digit hex color');
15
+ return {
16
+ primitive: { 'color.brand': brand, 'color.ink': '#17231e', 'color.paper': '#fbfcf9', 'color.white': '#ffffff', 'space.1': '0.25rem', 'space.2': '0.5rem', 'space.3': '0.75rem', 'space.4': '1rem', 'space.6': '1.5rem', 'space.8': '2rem', 'radius.control': '0.5rem', 'type.body': '1rem', 'type.title': 'clamp(1.75rem, 3vw, 2.75rem)', 'motion.feedback': '160ms', 'motion.enter': '240ms', 'motion.ease': 'cubic-bezier(0.2, 0, 0, 1)', 'shadow.panel': '0 2px 12px rgb(0 0 0 / 0.08)' },
17
+ semantic: { 'color.accent': '{primitive.color.brand}', 'color.on-accent': contrastRatio(brand, '#ffffff') >= 4.5 ? '#ffffff' : '#000000', 'color.text': '{primitive.color.ink}', 'color.canvas': '{primitive.color.paper}', 'color.surface': '{primitive.color.white}', 'color.focus': '#145bb5', 'color.danger': '#b42318', 'type.body': '{primitive.type.body}', 'type.heading': '{primitive.type.title}' },
18
+ component: { 'button.radius': '{primitive.radius.control}', 'button.padding': '{primitive.space.3}', 'button.primary.background': '{semantic.color.accent}', 'button.primary.text': '{semantic.color.on-accent}', 'button.disabled.opacity': '0.6', 'panel.shadow': '{primitive.shadow.panel}' },
19
+ themes: { light: { 'color.text': '#17231e', 'color.canvas': '#fbfcf9', 'color.surface': '#ffffff', 'color.accent': brand, 'color.on-accent': contrastRatio(brand, '#ffffff') >= 4.5 ? '#ffffff' : '#000000' }, dark: { 'color.text': '#e8f0eb', 'color.canvas': '#111a16', 'color.surface': '#1b2922', 'color.accent': '#88d4af', 'color.on-accent': '#111a16', 'color.focus': '#9fc6ff', 'color.danger': '#ffb4ab' } },
20
+ responsive: { 'breakpoint.tablet': '48rem', 'breakpoint.desktop': '80rem', 'content.max': '76rem', 'type.title': 'clamp(1.75rem, 3vw, 2.75rem)' }
21
+ };
22
+ }
23
+ export function exportTokens(tokens) {
24
+ const flat = {};
25
+ for (const layer of ['primitive', 'semantic', 'component', 'responsive'])
26
+ for (const [key, value] of Object.entries(tokens[layer]))
27
+ flat[`${layer}.${key}`] = value;
28
+ const cssName = (name) => `--tevra-${name.replace(/\./gu, '-')}`;
29
+ if (new Set(Object.keys(flat).map(cssName)).size !== Object.keys(flat).length)
30
+ throw new Error('Token names collide after CSS variable normalization');
31
+ const active = new Set();
32
+ function value(name) {
33
+ if (active.has(name))
34
+ throw new Error(`Cyclic token reference: ${name}`);
35
+ const raw = flat[name];
36
+ if (raw === undefined)
37
+ throw new Error(`Missing token reference: ${name}`);
38
+ const reference = /^\{([a-zA-Z0-9_.-]+)\}$/u.exec(raw);
39
+ if (reference?.[1]) {
40
+ active.add(name);
41
+ value(reference[1]);
42
+ active.delete(name);
43
+ return `var(${cssName(reference[1])})`;
44
+ }
45
+ if (/[;{}<>@]/u.test(raw))
46
+ throw new Error(`Unsafe CSS token value: ${name}`);
47
+ return raw;
48
+ }
49
+ const declarations = Object.keys(flat).map(name => ` ${cssName(name)}: ${value(name)};`).join('\n');
50
+ let css = `:root {\n${declarations}\n}\n`;
51
+ for (const [theme, entries] of Object.entries(tokens.themes)) {
52
+ if (!/^[a-z][a-z0-9-]*$/u.test(theme))
53
+ throw new Error(`Unsafe theme name: ${theme}`);
54
+ const declarations = Object.entries(entries).map(([name, raw]) => {
55
+ flat[`theme.${name}`] = raw;
56
+ return ` ${cssName(`semantic.${name}`)}: ${value(`theme.${name}`)};`;
57
+ }).join('\n');
58
+ css += `[data-theme="${theme}"] {\n${declarations}\n}\n`;
59
+ if (theme === 'dark')
60
+ css += `@media (prefers-color-scheme: dark) {\n :root:not([data-theme="light"]) {\n${declarations}\n }\n}\n`;
61
+ }
62
+ const theme = Object.keys(tokens.semantic).filter(name => /^(color|type)\./u.test(name)).map(name => ` --${name.replace(/^type\./u, 'text.').replace(/\./gu, '-')}: var(${cssName(`semantic.${name}`)});`).join('\n');
63
+ return { css, tailwind: `@import "tailwindcss";\n@import "./tokens.css";\n@theme inline {\n${theme}\n}\n`, portable: `${JSON.stringify({ version: 1, layers: tokens }, null, 2)}\n` };
64
+ }
65
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../../../packages/design-context/src/tokens.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function validate<T>(schema: string, value: unknown): T;
@@ -0,0 +1,22 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { Ajv2020 } from 'ajv/dist/2020.js';
4
+ import { kitRoot } from '../../filesystem/src/resources.js';
5
+ const ajv = new Ajv2020({ allErrors: true, strict: true });
6
+ ajv.addFormat('uri-reference', { type: 'string', validate: (value) => !/\s/u.test(value) });
7
+ ajv.addFormat('date-time', { type: 'string', validate: (value) => /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/u.test(value) && Number.isFinite(Date.parse(value)) });
8
+ const validators = new Map();
9
+ export function validate(schema, value) {
10
+ let checker = validators.get(schema);
11
+ if (!checker) {
12
+ const definition = JSON.parse(readFileSync(resolve(kitRoot(), 'schemas', schema), 'utf8'));
13
+ if (!definition || typeof definition !== 'object')
14
+ throw new Error(`Invalid bundled schema ${schema}`);
15
+ checker = ajv.compile(definition);
16
+ validators.set(schema, checker);
17
+ }
18
+ if (!checker(value))
19
+ throw new Error(`${schema}: ${ajv.errorsText(checker.errors, { separator: '; ' })}`);
20
+ return value;
21
+ }
22
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../../packages/design-context/src/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,OAAO,EAAE,OAAO,EAAE,MAAM,mCAAmC,CAAC;AAE5D,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AAC3D,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AACpG,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,uEAAuE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;AACvM,MAAM,UAAU,GAAG,IAAI,GAAG,EAA4B,CAAC;AAEvD,MAAM,UAAU,QAAQ,CAAI,MAAc,EAAE,KAAc;IACxD,IAAI,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,UAAU,GAAY,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACpG,IAAI,CAAC,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,MAAM,EAAE,CAAC,CAAC;QACvG,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAClC,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,KAAK,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IAC1G,OAAO,KAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,16 @@
1
+ export interface MemoryEntry {
2
+ id: string;
3
+ kind: 'direction' | 'tokens' | 'convention' | 'rejected' | 'redesign' | 'constraint' | 'regression';
4
+ text: string;
5
+ approved: boolean;
6
+ owner: string;
7
+ updatedAt: string;
8
+ }
9
+ export interface Memory {
10
+ version: 1;
11
+ revision: number;
12
+ entries: MemoryEntry[];
13
+ }
14
+ export declare function inspectMemory(root: string): Promise<Memory>;
15
+ export declare function updateMemory(root: string, entry: unknown, expectedRevision: number): Promise<Memory>;
16
+ export declare function resetMemory(root: string, confirmed: boolean): Promise<Memory>;
@@ -0,0 +1,47 @@
1
+ import { isMissing, readJSON, redact, safePath, withLock, writeJSON } from '../../filesystem/src/index.js';
2
+ import { stat } from 'node:fs/promises';
3
+ import { validate } from '../../design-context/src/validation.js';
4
+ import { isDeepStrictEqual } from 'node:util';
5
+ const path = '.tevra/memory.json';
6
+ export async function inspectMemory(root) {
7
+ try {
8
+ await stat(await safePath(root, path));
9
+ }
10
+ catch (error) {
11
+ if (isMissing(error))
12
+ return { version: 1, revision: 0, entries: [] };
13
+ throw error;
14
+ }
15
+ return validate('memory.schema.json', await readJSON(root, path));
16
+ }
17
+ export async function updateMemory(root, entry, expectedRevision) {
18
+ const serialized = JSON.stringify(entry);
19
+ if (typeof serialized !== 'string' || redact(serialized) !== serialized)
20
+ throw new Error('Possible secret in memory; remove sensitive values before persistence');
21
+ return withLock(root, '.tevra/memory.lock', async () => {
22
+ const memory = await inspectMemory(root);
23
+ if (expectedRevision !== memory.revision)
24
+ throw new Error('Stale memory revision');
25
+ const candidate = validate('memory.schema.json', { ...memory, entries: [entry] }).entries[0];
26
+ if (!candidate)
27
+ throw new Error('Memory entry missing');
28
+ const previous = memory.entries.find(value => value.id === candidate.id);
29
+ if (previous?.approved && !isDeepStrictEqual(previous, candidate))
30
+ throw new Error('Approved memory is immutable; append a new decision');
31
+ memory.entries = [...memory.entries.filter(value => value.id !== candidate.id), candidate];
32
+ memory.revision++;
33
+ await writeJSON(root, path, memory);
34
+ return memory;
35
+ });
36
+ }
37
+ export async function resetMemory(root, confirmed) {
38
+ if (!confirmed)
39
+ throw new Error('Memory reset requires --yes');
40
+ return withLock(root, '.tevra/memory.lock', async () => {
41
+ const current = await inspectMemory(root);
42
+ const reset = { version: 1, revision: current.revision + 1, entries: [] };
43
+ await writeJSON(root, path, reset);
44
+ return reset;
45
+ });
46
+ }
47
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/design-memory/src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export declare function projectRoot(path: string): Promise<string>;
2
+ export declare function safePath(root: string, name: string): Promise<string>;
3
+ export declare function isMissing(error: unknown): boolean;
4
+ export declare function readJSON(root: string, name: string): Promise<unknown>;
5
+ export declare function writeAtomic(root: string, name: string, content: string | Uint8Array): Promise<void>;
6
+ export declare function writeJSON(root: string, name: string, value: unknown): Promise<void>;
7
+ export declare function withLock<T>(root: string, name: string, action: () => Promise<T>): Promise<T>;
8
+ export declare function redact(text: string): string;
@@ -0,0 +1,83 @@
1
+ import { lstat, mkdir, open, readFile, realpath, rename, unlink } from 'node:fs/promises';
2
+ import { dirname, isAbsolute, relative, resolve, sep } from 'node:path';
3
+ import { randomUUID } from 'node:crypto';
4
+ export async function projectRoot(path) { return realpath(resolve(path)); }
5
+ export async function safePath(root, name) {
6
+ if (!name || isAbsolute(name) || name.split(/[\\/]/u).includes('..') || name.includes('\0'))
7
+ throw new Error(`Unsafe project path: ${name}`);
8
+ const destination = resolve(root, name);
9
+ const local = relative(root, destination);
10
+ if (!local || local.startsWith(`..${sep}`) || isAbsolute(local))
11
+ throw new Error(`Path escapes project: ${name}`);
12
+ let current = root;
13
+ for (const segment of local.split(sep)) {
14
+ current = resolve(current, segment);
15
+ try {
16
+ if ((await lstat(current)).isSymbolicLink())
17
+ throw new Error(`Symlink path refused: ${name}`);
18
+ }
19
+ catch (error) {
20
+ if (!isMissing(error))
21
+ throw error;
22
+ }
23
+ }
24
+ return destination;
25
+ }
26
+ export function isMissing(error) { return error instanceof Error && 'code' in error && error.code === 'ENOENT'; }
27
+ export async function readJSON(root, name) {
28
+ const path = await safePath(root, name);
29
+ try {
30
+ return JSON.parse(await readFile(path, 'utf8'));
31
+ }
32
+ catch (error) {
33
+ throw new Error(`Cannot read JSON ${name}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
34
+ }
35
+ }
36
+ export async function writeAtomic(root, name, content) {
37
+ const destination = await safePath(root, name);
38
+ await mkdir(dirname(destination), { recursive: true });
39
+ await safePath(root, name);
40
+ const tempName = `${name}.${randomUUID()}.tmp`;
41
+ const temporary = await safePath(root, tempName);
42
+ try {
43
+ await open(temporary, 'wx', 0o600).then(async (file) => { try {
44
+ await file.writeFile(content);
45
+ await file.sync();
46
+ }
47
+ finally {
48
+ await file.close();
49
+ } });
50
+ await rename(temporary, destination);
51
+ }
52
+ finally {
53
+ try {
54
+ await unlink(temporary);
55
+ }
56
+ catch (error) {
57
+ if (!isMissing(error))
58
+ throw error;
59
+ }
60
+ }
61
+ }
62
+ export async function writeJSON(root, name, value) { await writeAtomic(root, name, `${JSON.stringify(value, null, 2)}\n`); }
63
+ export async function withLock(root, name, action) {
64
+ const path = await safePath(root, name);
65
+ await mkdir(dirname(path), { recursive: true });
66
+ const lock = await open(path, 'wx', 0o600).catch(error => { throw new Error(`Write lock unavailable (${name}); check concurrent work or inspect a stale lock`, { cause: error }); });
67
+ try {
68
+ await lock.writeFile(JSON.stringify({ pid: process.pid, createdAt: new Date().toISOString() }));
69
+ return await action();
70
+ }
71
+ finally {
72
+ await lock.close();
73
+ await unlink(path);
74
+ }
75
+ }
76
+ export function redact(text) {
77
+ return text.replace(/(https?:\/\/)[^\s/@]+:[^\s/@]+@/gu, '$1[REDACTED]@')
78
+ .replace(/([?&][^=\s]+)=([^&\s#]*)/gu, '$1=[REDACTED]')
79
+ .replace(/\b(?:sk-[a-zA-Z0-9_-]{10,}|gh[pousr]_[a-zA-Z0-9_]{10,})\b/gu, '[REDACTED]')
80
+ .replace(/\b(?:AKIA[0-9A-Z]{16}|eyJ[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\b/gu, '[REDACTED]')
81
+ .replace(/((?:authorization|password|api[_-]?key|access[_-]?token|secret|cookie|session[_-]?id)\s*[=:]\s*)(?:Bearer\s+)?[^\s,;]+/giu, '$1[REDACTED]');
82
+ }
83
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/filesystem/src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function kitRoot(): string;
@@ -0,0 +1,13 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { dirname, resolve } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ export function kitRoot() {
5
+ let current = dirname(fileURLToPath(import.meta.url));
6
+ while (dirname(current) !== current) {
7
+ if (existsSync(resolve(current, 'skills')) && existsSync(resolve(current, 'schemas/design-context.schema.json')))
8
+ return current;
9
+ current = dirname(current);
10
+ }
11
+ throw new Error('Kit resources missing; install the complete Tevra package');
12
+ }
13
+ //# sourceMappingURL=resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.js","sourceRoot":"","sources":["../../../../packages/filesystem/src/resources.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,UAAU,OAAO;IACrB,IAAI,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACtD,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,OAAO,EAAE,CAAC;QACpC,IAAI,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,oCAAoC,CAAC,CAAC;YAAE,OAAO,OAAO,CAAC;QACjI,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;AAC/E,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { Check, Config } from '../../contracts/src/index.js';
2
+ export interface PerformanceBudgets {
3
+ lcpMs: number;
4
+ cls: number;
5
+ tbtMs: number;
6
+ }
7
+ export interface PerformanceMetrics {
8
+ lcpMs: number;
9
+ cls: number;
10
+ tbtMs: number;
11
+ }
12
+ export declare const defaultBudgets: PerformanceBudgets;
13
+ export declare function extractMetrics(input: unknown): PerformanceMetrics;
14
+ export declare function performanceChecks(metrics: PerformanceMetrics, budgets: PerformanceBudgets, evidence: string): Check[];
15
+ export declare function auditPerformance(root: string, config: Config, revision: number, options: {
16
+ allowNetwork: boolean;
17
+ allowCustomBrowser?: boolean;
18
+ budgets?: PerformanceBudgets;
19
+ }): Promise<{
20
+ metrics: PerformanceMetrics;
21
+ checks: Check[];
22
+ report: string;
23
+ html: string;
24
+ }>;
@@ -0,0 +1,77 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { dirname, resolve } from 'node:path';
5
+ import { access, mkdir, readFile } from 'node:fs/promises';
6
+ import { randomUUID } from 'node:crypto';
7
+ import { chromium } from 'playwright';
8
+ import { redact, safePath, withLock, writeAtomic, writeJSON } from '../../filesystem/src/index.js';
9
+ export const defaultBudgets = { lcpMs: 2500, cls: 0.1, tbtMs: 200 };
10
+ function record(value) { return typeof value === 'object' && value !== null && !Array.isArray(value); }
11
+ export function extractMetrics(input) {
12
+ if (!record(input) || !record(input.audits))
13
+ throw new Error('Invalid Lighthouse report: missing audits');
14
+ if (input.runtimeError)
15
+ throw new Error('Lighthouse reported a runtime error; metrics are unverified');
16
+ const audits = input.audits;
17
+ function metric(name) {
18
+ const audit = audits[name];
19
+ if (!record(audit) || audit.errorMessage || typeof audit.numericValue !== 'number' || !Number.isFinite(audit.numericValue) || audit.numericValue < 0)
20
+ throw new Error(`Missing or invalid Lighthouse metric: ${name}`);
21
+ return audit.numericValue;
22
+ }
23
+ return { lcpMs: metric('largest-contentful-paint'), cls: metric('cumulative-layout-shift'), tbtMs: metric('total-blocking-time') };
24
+ }
25
+ export function performanceChecks(metrics, budgets, evidence) {
26
+ return ['lcpMs', 'cls', 'tbtMs'].map(name => {
27
+ const budget = budgets[name];
28
+ const value = metrics[name];
29
+ if (!Number.isFinite(budget) || budget < 0 || !Number.isFinite(value) || value < 0)
30
+ throw new Error(`Invalid performance metric or budget: ${name}`);
31
+ return { id: `performance-${name}`, category: 'performance', kind: 'deterministic', status: value <= budget ? 'passed' : 'failed', severity: 'major', evidence: [evidence], issue: `${name}: ${value}; laboratory budget: ${budget}`, component: 'audited navigation', correction: 'Inspect the saved Lighthouse diagnostics; repeat under equivalent conditions.' };
32
+ });
33
+ }
34
+ export async function auditPerformance(root, config, revision, options) {
35
+ if (!options.allowNetwork)
36
+ throw new Error('Lighthouse loads the target and its resources; review the application and pass --allow-network explicitly');
37
+ if (config.browser.executablePath && !options.allowCustomBrowser)
38
+ throw new Error('Custom browser requires --allow-custom-browser');
39
+ const budgets = options.budgets ?? defaultBudgets;
40
+ for (const value of Object.values(budgets))
41
+ if (!Number.isFinite(value) || value < 0)
42
+ throw new Error('Invalid performance budgets');
43
+ const target = new URL(config.baseURL);
44
+ if (!config.permittedOrigins.includes(target.origin) || target.username || target.password || !['http:', 'https:'].includes(target.protocol))
45
+ throw new Error('Performance URL must use an explicitly permitted origin without credentials');
46
+ const executable = config.browser.executablePath ?? (config.browser.channel === 'chrome' && process.platform === 'darwin' ? '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome' : chromium.executablePath());
47
+ await access(executable);
48
+ return withLock(root, '.tevra/performance.lock', async () => {
49
+ const id = randomUUID();
50
+ const directory = `.tevra/artifacts/performance/${id}`;
51
+ await mkdir(await safePath(root, directory), { recursive: true });
52
+ const output = await safePath(root, `${directory}/lighthouse`);
53
+ const report = `${directory}/lighthouse.report.json`;
54
+ const html = `${directory}/lighthouse.report.html`;
55
+ await writeJSON(root, '.tevra/artifacts/performance/attempt.json', { status: 'running', id, contextRevision: revision });
56
+ try {
57
+ const cli = resolve(dirname(fileURLToPath(import.meta.resolve('lighthouse'))), '../cli/index.js');
58
+ await promisify(execFile)(process.execPath, [cli, target.href, '--only-categories=performance', '--output=json', '--output=html', `--output-path=${output}`, '--chrome-flags=--headless', '--quiet', '--enable-error-reporting=false'], {
59
+ cwd: root, env: { ...process.env, CHROME_PATH: executable }, timeout: 120000, maxBuffer: 1024 * 1024, windowsHide: true
60
+ });
61
+ const raw = JSON.parse(await readFile(await safePath(root, report), 'utf8'));
62
+ const metrics = extractMetrics(raw);
63
+ await writeAtomic(root, report, redact(JSON.stringify(raw, null, 2)));
64
+ await writeAtomic(root, html, redact(await readFile(await safePath(root, html), 'utf8')));
65
+ const checks = performanceChecks(metrics, budgets, report);
66
+ const result = { metrics, checks, report, html };
67
+ await writeJSON(root, `${directory}/summary.json`, { ...result, contextRevision: revision, budgets, measurement: 'laboratory', caveat: 'Navigation TBT is not real-user INP. A single run does not establish a field regression.' });
68
+ await writeJSON(root, '.tevra/artifacts/performance/attempt.json', { status: 'passed', id, contextRevision: revision, summary: `${directory}/summary.json` });
69
+ return result;
70
+ }
71
+ catch (error) {
72
+ await writeJSON(root, '.tevra/artifacts/performance/attempt.json', { status: 'failed', id, contextRevision: revision, error: redact(error instanceof Error ? error.message : String(error)) });
73
+ throw error;
74
+ }
75
+ });
76
+ }
77
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/performance-qa/src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { QualityReport } from '../../contracts/src/index.js';
2
+ export declare function htmlReport(report: QualityReport): string;
@@ -0,0 +1,15 @@
1
+ import { redact } from '../../filesystem/src/index.js';
2
+ function escape(value) {
3
+ return redact(value).replace(/&/gu, '&amp;').replace(/</gu, '&lt;').replace(/>/gu, '&gt;').replace(/"/gu, '&quot;').replace(/'/gu, '&#39;');
4
+ }
5
+ function artifact(path) {
6
+ if (/^[a-z][a-z0-9+.-]*:|^[\\/]|[?#\u0000-\u001f]/iu.test(path) || path.split(/[\\/]/u).some(part => part === '..' || part === '.' || !part))
7
+ return escape(path);
8
+ const href = `../../${path.split('/').map(encodeURIComponent).join('/')}`;
9
+ return `<a href="${escape(href)}">${escape(path)}</a>${/\.png$/iu.test(path) ? `<br><img src="${escape(href)}" alt="Screenshot evidence" loading="lazy">` : ''}`;
10
+ }
11
+ export function htmlReport(report) {
12
+ const rows = report.checks.map(check => `<tr><th scope="row">${escape(check.id)}</th><td>${escape(check.kind)}</td><td>${escape(check.status)}</td><td>${escape(check.severity)}</td><td>${escape(check.component)}</td><td>${escape(check.issue)}</td><td>${check.evidence.map(artifact).join('<br>')}</td><td>${escape(check.correction)}</td></tr>`).join('');
13
+ return `<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src 'self'; style-src 'unsafe-inline'; base-uri 'none'"><title>Tevra quality report</title><style>body{font:16px/1.5 system-ui;margin:2rem;color:#18251f;background:#fff}table{border-collapse:collapse;width:100%}th,td{padding:.5rem;border:1px solid #bbb;text-align:left;vertical-align:top}img{max-width:24rem;max-height:20rem}section{overflow:auto}a{color:#165b42}</style><body><main><h1>Tevra quality report</h1><p>Status: <strong>${escape(report.status)}</strong>. Context revision: ${report.contextRevision}.</p><p>Score: ${report.score === null ? 'unscored / incomplete evidence' : `${report.score}/100 (evidence-labeled judgment)`}</p><p>Blockers: ${escape(report.blockers.join(', ') || 'none')}</p><p>Missing evidence: ${escape(report.missing.join(', ') || 'none')}</p><section aria-label="Quality findings"><table><thead><tr>${['Check', 'Evidence kind', 'Status', 'Severity', 'Component', 'Issue', 'Evidence', 'Correction'].map(title => `<th scope="col">${title}</th>`).join('')}</tr></thead><tbody>${rows}</tbody></table></section><h2>Verification limits</h2><ul>${report.limits.map(limit => `<li>${escape(limit)}</li>`).join('')}</ul></main></body></html>`;
14
+ }
15
+ //# sourceMappingURL=html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../../../packages/quality-engine/src/html.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAEvD,SAAS,MAAM,CAAC,KAAa;IAC3B,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AAC9I,CAAC;AACD,SAAS,QAAQ,CAAC,IAAY;IAC5B,IAAI,gDAAgD,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;IAClK,MAAM,IAAI,GAAG,SAAS,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IAC1E,OAAO,YAAY,MAAM,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,IAAI,CAAC,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,iBAAiB,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AACnK,CAAC;AACD,MAAM,UAAU,UAAU,CAAC,MAAqB;IAC9C,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,uBAAuB,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,YAAY,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjW,OAAO,snBAAsnB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,gCAAgC,MAAM,CAAC,eAAe,kBAAkB,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,kCAAkC,oBAAoB,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,4BAA4B,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,gEAAgE,CAAC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,mBAAmB,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,uBAAuB,IAAI,6DAA6D,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,4BAA4B,CAAC;AAC31C,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Config, QualityReport } from '../../contracts/src/index.js';
2
+ export declare function evaluateQuality(input: unknown, config: Config, contextRevision: number): QualityReport;
3
+ export declare function markdownReport(report: QualityReport): string;
@@ -0,0 +1,45 @@
1
+ import { categories } from '../../contracts/src/index.js';
2
+ import { validate } from '../../design-context/src/validation.js';
3
+ import { redact } from '../../filesystem/src/index.js';
4
+ export function evaluateQuality(input, config, contextRevision) {
5
+ const checks = validate('checks.schema.json', input);
6
+ if (new Set(checks.map(check => check.id)).size !== checks.length)
7
+ throw new Error('Quality check IDs must be unique');
8
+ for (const check of checks)
9
+ if (check.status !== 'unverified' && !check.evidence.length)
10
+ throw new Error(`Executed check requires evidence: ${check.id}`);
11
+ for (const check of checks)
12
+ if (check.score !== undefined && check.score < 3 && (!check.issue.trim() || !check.correction.trim()))
13
+ throw new Error(`Low score requires a finding and correction: ${check.id}`);
14
+ const blockers = checks.filter(check => check.status === 'failed' && (check.severity === 'critical' || config.requiredChecks.includes(check.id))).map(check => check.id);
15
+ const missing = config.requiredChecks.filter(id => !checks.some(check => check.id === id && check.status === 'passed'));
16
+ let weighted = 0;
17
+ let complete = true;
18
+ for (const category of categories) {
19
+ const weight = config.weights[category] ?? 0;
20
+ if (weight === 0)
21
+ continue;
22
+ const scored = checks.filter(check => check.category === category && check.score !== undefined && check.status !== 'unverified');
23
+ if (!scored.length) {
24
+ complete = false;
25
+ if (config.thresholds.minScore > 0)
26
+ missing.push(`score:${category}`);
27
+ continue;
28
+ }
29
+ weighted += Math.min(...scored.map(check => check.score ?? 0)) / 4 * weight;
30
+ }
31
+ const score = complete ? Math.round(weighted * 100) / 100 : null;
32
+ if (score !== null && score < config.thresholds.minScore)
33
+ blockers.push('weighted-score');
34
+ return validate('quality-report.schema.json', {
35
+ version: 1, createdAt: new Date().toISOString(), status: blockers.length || missing.length ? 'FAIL' : 'PASS', score,
36
+ blockers: [...new Set(blockers)], missing: [...new Set(missing)], checks,
37
+ limits: ['AI/human scores are subjective judgments, not objective measurements.', 'Pixel differences measure visual change, not usability.', 'Automated accessibility checks do not establish full WCAG compliance.', 'Unexecuted manual, screen-reader, native and performance checks remain unverified.'], contextRevision
38
+ });
39
+ }
40
+ function cell(value) { return redact(value).replace(/([\\|\[\]()`])/gu, '\\$1').replace(/</gu, '&lt;').replace(/>/gu, '&gt;').replace(/[\r\n]/gu, ' '); }
41
+ export function markdownReport(report) {
42
+ const rows = report.checks.map(check => `| ${cell(check.id)} | ${check.kind} | ${check.status} | ${check.severity} | ${cell(check.component)} | ${cell(check.issue)} | ${cell(check.evidence.join(', '))} | ${cell(check.correction)} |`);
43
+ return redact(`# Tevra quality report\n\nStatus: **${report.status}** · Context revision: ${report.contextRevision}\n\nWeighted score: ${report.score === null ? 'unscored / incomplete evidence' : `${report.score}/100 (evidence-labeled judgment)`}\n\nBlockers: ${report.blockers.join(', ') || 'none'}\n\nMissing required evidence: ${report.missing.join(', ') || 'none'}\n\n| Check | Evidence kind | Status | Severity | Component | Issue | Evidence | Correction |\n| --- | --- | --- | --- | --- | --- | --- | --- |\n${rows.join('\n')}\n\n## Verification limits\n\n${report.limits.map(limit => `- ${limit}`).join('\n')}\n`);
44
+ }
45
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/quality-engine/src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ export interface RegistrySkill {
2
+ id: string;
3
+ name: string;
4
+ description: string;
5
+ version: string;
6
+ capabilities: string[];
7
+ activation: {
8
+ intents: string[];
9
+ };
10
+ inputs: string[];
11
+ outputs: string[];
12
+ dependencies: string[];
13
+ conflicts: string[];
14
+ frameworks: string[];
15
+ platforms: string[];
16
+ agents: string[];
17
+ source: {
18
+ type: string;
19
+ references: string[];
20
+ };
21
+ license: string;
22
+ priority: number;
23
+ estimatedCost: {
24
+ minutes: number;
25
+ contextTokens: number;
26
+ };
27
+ requiredTools: string[];
28
+ validation: string[];
29
+ entrypoint: string;
30
+ }
31
+ export interface Registry {
32
+ version: 1;
33
+ skills: RegistrySkill[];
34
+ }
35
+ export interface Selection {
36
+ skills: RegistrySkill[];
37
+ owners: Record<string, string>;
38
+ duplicates: Record<string, string[]>;
39
+ }
40
+ export declare function validateRegistry(input: unknown): Registry;
41
+ export declare function loadRegistry(extensionFiles?: string[]): Promise<Registry>;
42
+ export declare function selectCapabilities(registryInput: unknown, capabilities: string[], options?: {
43
+ framework?: string;
44
+ platform?: string;
45
+ agent?: string;
46
+ overrides?: Record<string, string>;
47
+ }): Selection;
48
+ export declare function registryGraph(registry: Registry): string;
49
+ export declare function validateBundledProvenance(registry: Registry): Promise<void>;