@decibelsystems/tools 2.0.2 → 2.1.1

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 (96) hide show
  1. package/README.md +115 -233
  2. package/dist/config/queueableActions.d.ts +11 -0
  3. package/dist/config/queueableActions.d.ts.map +1 -0
  4. package/dist/config/queueableActions.js +22 -0
  5. package/dist/config/queueableActions.js.map +1 -0
  6. package/dist/daemon.d.ts +29 -0
  7. package/dist/daemon.d.ts.map +1 -1
  8. package/dist/daemon.js +64 -0
  9. package/dist/daemon.js.map +1 -1
  10. package/dist/daemonConfig.d.ts +7 -0
  11. package/dist/daemonConfig.d.ts.map +1 -1
  12. package/dist/daemonConfig.js +9 -0
  13. package/dist/daemonConfig.js.map +1 -1
  14. package/dist/facades/definitions.d.ts.map +1 -1
  15. package/dist/facades/definitions.js +130 -33
  16. package/dist/facades/definitions.js.map +1 -1
  17. package/dist/httpQueueDetection.d.ts +16 -0
  18. package/dist/httpQueueDetection.d.ts.map +1 -0
  19. package/dist/httpQueueDetection.js +36 -0
  20. package/dist/httpQueueDetection.js.map +1 -0
  21. package/dist/httpServer.d.ts +4 -0
  22. package/dist/httpServer.d.ts.map +1 -1
  23. package/dist/httpServer.js +224 -97
  24. package/dist/httpServer.js.map +1 -1
  25. package/dist/kernel.d.ts +2 -0
  26. package/dist/kernel.d.ts.map +1 -1
  27. package/dist/kernel.js +1 -0
  28. package/dist/kernel.js.map +1 -1
  29. package/dist/server.js +30 -1
  30. package/dist/server.js.map +1 -1
  31. package/dist/tools/agentic/agentQueue.d.ts +50 -0
  32. package/dist/tools/agentic/agentQueue.d.ts.map +1 -0
  33. package/dist/tools/agentic/agentQueue.js +226 -0
  34. package/dist/tools/agentic/agentQueue.js.map +1 -0
  35. package/dist/tools/agentic/index.d.ts +2 -0
  36. package/dist/tools/agentic/index.d.ts.map +1 -1
  37. package/dist/tools/agentic/index.js +84 -0
  38. package/dist/tools/agentic/index.js.map +1 -1
  39. package/dist/tools/coordinator/coordinator.d.ts +14 -0
  40. package/dist/tools/coordinator/coordinator.d.ts.map +1 -1
  41. package/dist/tools/coordinator/coordinator.js +101 -0
  42. package/dist/tools/coordinator/coordinator.js.map +1 -1
  43. package/dist/tools/coordinator/index.d.ts +2 -0
  44. package/dist/tools/coordinator/index.d.ts.map +1 -1
  45. package/dist/tools/coordinator/index.js +2 -0
  46. package/dist/tools/coordinator/index.js.map +1 -1
  47. package/dist/tools/decibel/index.d.ts +3 -0
  48. package/dist/tools/decibel/index.d.ts.map +1 -0
  49. package/dist/tools/decibel/index.js +150 -0
  50. package/dist/tools/decibel/index.js.map +1 -0
  51. package/dist/tools/decibel.d.ts +13 -0
  52. package/dist/tools/decibel.d.ts.map +1 -0
  53. package/dist/tools/decibel.js +156 -0
  54. package/dist/tools/decibel.js.map +1 -0
  55. package/dist/tools/deck.d.ts +4 -4
  56. package/dist/tools/deck.d.ts.map +1 -1
  57. package/dist/tools/deck.js +1546 -78
  58. package/dist/tools/deck.js.map +1 -1
  59. package/dist/tools/designer/index.d.ts +6 -0
  60. package/dist/tools/designer/index.d.ts.map +1 -1
  61. package/dist/tools/designer/index.js +344 -1
  62. package/dist/tools/designer/index.js.map +1 -1
  63. package/dist/tools/designer.d.ts +143 -0
  64. package/dist/tools/designer.d.ts.map +1 -1
  65. package/dist/tools/designer.js +457 -0
  66. package/dist/tools/designer.js.map +1 -1
  67. package/dist/tools/guardian/index.d.ts +1 -0
  68. package/dist/tools/guardian/index.d.ts.map +1 -1
  69. package/dist/tools/guardian/index.js +40 -1
  70. package/dist/tools/guardian/index.js.map +1 -1
  71. package/dist/tools/guardian.d.ts +30 -0
  72. package/dist/tools/guardian.d.ts.map +1 -1
  73. package/dist/tools/guardian.js +96 -0
  74. package/dist/tools/guardian.js.map +1 -1
  75. package/dist/tools/index.d.ts.map +1 -1
  76. package/dist/tools/index.js +7 -1
  77. package/dist/tools/index.js.map +1 -1
  78. package/dist/tools/mother.d.ts +11 -0
  79. package/dist/tools/mother.d.ts.map +1 -0
  80. package/dist/tools/mother.js +503 -0
  81. package/dist/tools/mother.js.map +1 -0
  82. package/dist/tools/swarm.d.ts +11 -0
  83. package/dist/tools/swarm.d.ts.map +1 -0
  84. package/dist/tools/swarm.js +701 -0
  85. package/dist/tools/swarm.js.map +1 -0
  86. package/dist/tools/terminal.d.ts +17 -0
  87. package/dist/tools/terminal.d.ts.map +1 -0
  88. package/dist/tools/terminal.js +968 -0
  89. package/dist/tools/terminal.js.map +1 -0
  90. package/dist/transports/http.d.ts.map +1 -1
  91. package/dist/transports/http.js +2 -0
  92. package/dist/transports/http.js.map +1 -1
  93. package/dist/transports/types.d.ts +4 -0
  94. package/dist/transports/types.d.ts.map +1 -1
  95. package/package.json +1 -1
  96. package/templates/docs.html +1084 -0
@@ -117,6 +117,149 @@ export interface CheckParityOutput {
117
117
  source: string;
118
118
  }
119
119
  export declare function checkParity(input: CheckParityInput): Promise<CheckParityOutput | DesignerError>;
120
+ export interface TokensLookupInput {
121
+ projectId?: string;
122
+ category?: string;
123
+ }
124
+ export interface TokensLookupOutput {
125
+ tokens: DesignToken[];
126
+ total: number;
127
+ categories: string[];
128
+ source: string | null;
129
+ synced_at: string | null;
130
+ path: string;
131
+ }
132
+ export declare function tokensLookup(input: TokensLookupInput): Promise<TokensLookupOutput | DesignerError>;
133
+ export interface DriftDetectionInput {
134
+ projectId?: string;
135
+ }
136
+ export interface DriftEntry {
137
+ token_name: string;
138
+ expected: string;
139
+ actual: string;
140
+ file: string;
141
+ format: 'css' | 'tailwind' | 'swift' | 'json';
142
+ }
143
+ export interface DriftDetectionOutput {
144
+ drifted: DriftEntry[];
145
+ scanned_files: number;
146
+ total_tokens_checked: number;
147
+ drift_detected: boolean;
148
+ timestamp: string;
149
+ }
150
+ export declare function driftDetection(input: DriftDetectionInput): Promise<DriftDetectionOutput | DesignerError>;
151
+ export interface FigmaParityInput {
152
+ projectId?: string;
153
+ component: string;
154
+ figma_node_id?: string;
155
+ }
156
+ export interface FigmaParityOutput {
157
+ component: string;
158
+ status: 'pending_figma_integration' | 'compared';
159
+ figma_node_id: string | null;
160
+ message: string;
161
+ timestamp: string;
162
+ }
163
+ export declare function figmaParity(input: FigmaParityInput): Promise<FigmaParityOutput | DesignerError>;
120
164
  export declare function listPrinciples(input: ListPrinciplesInput): Promise<ListPrinciplesOutput | DesignerError>;
165
+ export type EvalType = 'token-drift' | 'component-parity' | 'motion-review' | 'design-compliance' | 'visual-review' | 'accessibility';
166
+ export type EvalScope = 'component' | 'page' | 'project';
167
+ export type FindingSeverity = 'critical' | 'warning' | 'info';
168
+ export interface EvalFinding {
169
+ severity: FindingSeverity;
170
+ category: string;
171
+ message: string;
172
+ location?: string;
173
+ expected?: string;
174
+ actual?: string;
175
+ suggestion?: string;
176
+ }
177
+ export interface LogEvalInput {
178
+ projectId?: string;
179
+ evalType: EvalType;
180
+ scope: EvalScope;
181
+ target: string;
182
+ score: number;
183
+ summary: string;
184
+ findings: EvalFinding[];
185
+ platform?: string;
186
+ branch?: string;
187
+ commit?: string;
188
+ evaluator?: string;
189
+ requestedBy?: string;
190
+ tags?: string[];
191
+ }
192
+ export interface LogEvalOutput {
193
+ id: string;
194
+ grade: string;
195
+ score: number;
196
+ findingCounts: {
197
+ critical: number;
198
+ warning: number;
199
+ info: number;
200
+ };
201
+ previousEvalId: string | null;
202
+ path: string;
203
+ timestamp: string;
204
+ }
205
+ export declare function logEval(input: LogEvalInput): Promise<LogEvalOutput | DesignerError>;
206
+ export interface ListEvalsInput {
207
+ projectId?: string;
208
+ evalType?: EvalType;
209
+ scope?: EvalScope;
210
+ target?: string;
211
+ minScore?: number;
212
+ maxScore?: number;
213
+ tags?: string[];
214
+ limit?: number;
215
+ }
216
+ export interface EvalSummary {
217
+ id: string;
218
+ eval_type: EvalType;
219
+ scope: EvalScope;
220
+ target: string;
221
+ score: number;
222
+ grade: string;
223
+ summary: string;
224
+ finding_counts: {
225
+ critical: number;
226
+ warning: number;
227
+ info: number;
228
+ };
229
+ tags: string[];
230
+ timestamp: string;
231
+ }
232
+ export interface ListEvalsOutput {
233
+ evals: EvalSummary[];
234
+ total: number;
235
+ path: string;
236
+ }
237
+ export declare function listEvals(input: ListEvalsInput): Promise<ListEvalsOutput | DesignerError>;
238
+ export interface EvalHistoryInput {
239
+ projectId?: string;
240
+ evalType: EvalType;
241
+ target?: string;
242
+ }
243
+ export interface EvalHistoryPoint {
244
+ id: string;
245
+ score: number;
246
+ grade: string;
247
+ finding_counts: {
248
+ critical: number;
249
+ warning: number;
250
+ info: number;
251
+ };
252
+ timestamp: string;
253
+ summary: string;
254
+ }
255
+ export interface EvalHistoryOutput {
256
+ eval_type: EvalType;
257
+ target: string;
258
+ history: EvalHistoryPoint[];
259
+ trend: 'improving' | 'declining' | 'stable' | 'insufficient_data';
260
+ delta: number | null;
261
+ path: string;
262
+ }
263
+ export declare function evalHistory(input: EvalHistoryInput): Promise<EvalHistoryOutput | DesignerError>;
121
264
  export {};
122
265
  //# sourceMappingURL=designer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"designer.d.ts","sourceRoot":"","sources":["../../src/tools/designer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"designer.d.ts","sourceRoot":"","sources":["../../src/tools/designer.ts"],"names":[],"mappings":"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"}
@@ -470,6 +470,242 @@ export async function checkParity(input) {
470
470
  source: `figma:${input.fileKey}`,
471
471
  };
472
472
  }
473
+ export async function tokensLookup(input) {
474
+ let resolved;
475
+ try {
476
+ resolved = resolveProjectPaths(input.projectId);
477
+ }
478
+ catch {
479
+ return makeProjectError('look up tokens');
480
+ }
481
+ const tokensFile = path.join(resolved.subPath('designer', 'tokens'), 'tokens.yaml');
482
+ let tokens;
483
+ let source = null;
484
+ let synced_at = null;
485
+ try {
486
+ const content = await fs.readFile(tokensFile, 'utf-8');
487
+ const data = YAML.parse(content);
488
+ tokens = data?.tokens || [];
489
+ source = data?.source || null;
490
+ synced_at = data?.synced_at || null;
491
+ }
492
+ catch {
493
+ return {
494
+ error: 'NO_TOKENS',
495
+ message: 'No tokens.yaml found. Sync tokens from Figma first or create a tokens file manually.',
496
+ hint: 'Use designer sync_tokens with a Figma fileKey, or place a tokens.yaml in .decibel/designer/tokens/',
497
+ };
498
+ }
499
+ // Derive categories from token types + collections
500
+ const categorySet = new Set();
501
+ for (const t of tokens) {
502
+ if (t.type)
503
+ categorySet.add(t.type);
504
+ if (t.collection)
505
+ categorySet.add(t.collection.toLowerCase());
506
+ }
507
+ // Filter by category if specified
508
+ if (input.category) {
509
+ const cat = input.category.toLowerCase();
510
+ tokens = tokens.filter(t => t.type === cat ||
511
+ (t.collection && t.collection.toLowerCase() === cat));
512
+ }
513
+ log(`Designer: Tokens lookup — ${tokens.length} tokens${input.category ? ` (category: ${input.category})` : ''}`);
514
+ return {
515
+ tokens,
516
+ total: tokens.length,
517
+ categories: Array.from(categorySet).sort(),
518
+ source,
519
+ synced_at,
520
+ path: tokensFile,
521
+ };
522
+ }
523
+ // Format-aware value normalizer: convert various color/value formats to comparable form
524
+ function normalizeColorValue(value) {
525
+ if (typeof value === 'string')
526
+ return value.toLowerCase().replace(/\s/g, '');
527
+ // Figma RGBA object → hex
528
+ if (typeof value === 'object' && value !== null && 'r' in value) {
529
+ const v = value;
530
+ const toHex = (n) => Math.round(n * 255).toString(16).padStart(2, '0');
531
+ return `#${toHex(v.r)}${toHex(v.g)}${toHex(v.b)}`.toLowerCase();
532
+ }
533
+ if (typeof value === 'number')
534
+ return String(value);
535
+ return null;
536
+ }
537
+ // Parsers for different source file formats
538
+ const FORMAT_PARSERS = {
539
+ css: {
540
+ glob: '**/*.css',
541
+ extract(content) {
542
+ const map = new Map();
543
+ const re = /--([a-zA-Z0-9_-]+)\s*:\s*([^;]+)/g;
544
+ let m;
545
+ while ((m = re.exec(content)) !== null) {
546
+ map.set(m[1].toLowerCase(), m[2].trim().toLowerCase());
547
+ }
548
+ return map;
549
+ },
550
+ },
551
+ tailwind: {
552
+ glob: '**/tailwind.config.{js,ts,cjs,mjs}',
553
+ extract(content) {
554
+ const map = new Map();
555
+ // Match hex/rgb values in tailwind config
556
+ const re = /['"]([a-zA-Z0-9_-]+)['"]\s*:\s*['"](#[0-9a-fA-F]{3,8}|rgb[a]?\([^)]+\))['"]/g;
557
+ let m;
558
+ while ((m = re.exec(content)) !== null) {
559
+ map.set(m[1].toLowerCase(), m[2].toLowerCase());
560
+ }
561
+ return map;
562
+ },
563
+ },
564
+ swift: {
565
+ glob: '**/*.swift',
566
+ extract(content) {
567
+ const map = new Map();
568
+ // Match Color(hex: 0xRRGGBB) or Color(hex: "RRGGBB")
569
+ const re = /(?:let|var|static)\s+(\w+)\s*.*?Color\(\s*hex\s*:\s*(?:0x|"|')([0-9a-fA-F]{6,8})/g;
570
+ let m;
571
+ while ((m = re.exec(content)) !== null) {
572
+ map.set(m[1].toLowerCase(), `#${m[2].toLowerCase()}`);
573
+ }
574
+ return map;
575
+ },
576
+ },
577
+ json: {
578
+ glob: '**/tokens.json',
579
+ extract(content) {
580
+ const map = new Map();
581
+ try {
582
+ const data = JSON.parse(content);
583
+ // Flatten nested token objects
584
+ function walk(obj, prefix) {
585
+ for (const [k, v] of Object.entries(obj)) {
586
+ const key = prefix ? `${prefix}/${k}` : k;
587
+ if (typeof v === 'object' && v !== null && 'value' in v) {
588
+ map.set(key.toLowerCase(), String(v.value).toLowerCase());
589
+ }
590
+ else if (typeof v === 'object' && v !== null) {
591
+ walk(v, key);
592
+ }
593
+ }
594
+ }
595
+ walk(data, '');
596
+ }
597
+ catch { /* not valid JSON, skip */ }
598
+ return map;
599
+ },
600
+ },
601
+ };
602
+ export async function driftDetection(input) {
603
+ let resolved;
604
+ try {
605
+ resolved = resolveProjectPaths(input.projectId);
606
+ }
607
+ catch {
608
+ return makeProjectError('detect drift');
609
+ }
610
+ const now = new Date();
611
+ // Load token registry
612
+ const tokensFile = path.join(resolved.subPath('designer', 'tokens'), 'tokens.yaml');
613
+ let registryTokens;
614
+ try {
615
+ const content = await fs.readFile(tokensFile, 'utf-8');
616
+ const data = YAML.parse(content);
617
+ registryTokens = data?.tokens || [];
618
+ }
619
+ catch {
620
+ return {
621
+ error: 'NO_TOKENS',
622
+ message: 'No tokens.yaml found. Sync or create tokens first.',
623
+ hint: 'Use designer sync_tokens or manually place tokens.yaml in .decibel/designer/tokens/',
624
+ };
625
+ }
626
+ // Build a lookup from token name → normalized expected value
627
+ const expectedMap = new Map();
628
+ for (const t of registryTokens) {
629
+ const norm = normalizeColorValue(t.value);
630
+ if (norm) {
631
+ // Use the last segment of slash-separated names for matching
632
+ const shortName = t.name.split('/').pop().toLowerCase();
633
+ expectedMap.set(shortName, norm);
634
+ expectedMap.set(t.name.toLowerCase(), norm);
635
+ }
636
+ }
637
+ const drifted = [];
638
+ let scannedFiles = 0;
639
+ // Scan source files using each format parser
640
+ for (const [format, parser] of Object.entries(FORMAT_PARSERS)) {
641
+ // Use the project root to find source files
642
+ const projectRoot = resolved.projectPath.replace(/\/.decibel$/, '');
643
+ let files;
644
+ try {
645
+ const { glob } = await import('glob');
646
+ files = await glob(parser.glob, {
647
+ cwd: projectRoot,
648
+ absolute: true,
649
+ ignore: ['**/node_modules/**', '**/dist/**', '**/.decibel/**'],
650
+ });
651
+ }
652
+ catch {
653
+ continue; // glob not available or no matches
654
+ }
655
+ for (const file of files) {
656
+ scannedFiles++;
657
+ const content = await fs.readFile(file, 'utf-8');
658
+ const sourceValues = parser.extract(content);
659
+ for (const [name, actual] of sourceValues) {
660
+ const expected = expectedMap.get(name);
661
+ if (expected && expected !== actual.replace(/\s/g, '')) {
662
+ drifted.push({
663
+ token_name: name,
664
+ expected,
665
+ actual,
666
+ file: path.relative(projectRoot, file),
667
+ format: format,
668
+ });
669
+ }
670
+ }
671
+ }
672
+ }
673
+ log(`Designer: Drift detection — ${drifted.length} drifted tokens across ${scannedFiles} files`);
674
+ return {
675
+ drifted,
676
+ scanned_files: scannedFiles,
677
+ total_tokens_checked: expectedMap.size,
678
+ drift_detected: drifted.length > 0,
679
+ timestamp: now.toISOString(),
680
+ };
681
+ }
682
+ export async function figmaParity(input) {
683
+ let resolved;
684
+ try {
685
+ resolved = resolveProjectPaths(input.projectId);
686
+ }
687
+ catch {
688
+ return makeProjectError('check Figma parity');
689
+ }
690
+ // Input validation
691
+ if (!input.component || input.component.trim().length === 0) {
692
+ return {
693
+ error: 'INVALID_INPUT',
694
+ message: 'component parameter is required and must be non-empty.',
695
+ hint: 'Provide the component name or file path (e.g., "Button", "src/components/Button.tsx").',
696
+ };
697
+ }
698
+ const now = new Date();
699
+ // Phase 1: skeleton — real Figma MCP integration is pending
700
+ log(`Designer: Figma parity check requested for component "${input.component}" (Phase 2 integration pending)`);
701
+ return {
702
+ component: input.component,
703
+ status: 'pending_figma_integration',
704
+ figma_node_id: input.figma_node_id || null,
705
+ message: `Figma parity diff for "${input.component}" is registered. Real comparison requires Phase 2 Figma MCP integration. Node ID ${input.figma_node_id ? `"${input.figma_node_id}" saved for` : 'not provided — will need it for'} automated comparison.`,
706
+ timestamp: now.toISOString(),
707
+ };
708
+ }
473
709
  // ============================================================================
474
710
  // List Design Principles
475
711
  // ============================================================================
@@ -492,4 +728,225 @@ export async function listPrinciples(input) {
492
728
  path: principlesDir,
493
729
  };
494
730
  }
731
+ function deriveGrade(score) {
732
+ if (score >= 90)
733
+ return 'A';
734
+ if (score >= 80)
735
+ return 'B';
736
+ if (score >= 70)
737
+ return 'C';
738
+ if (score >= 60)
739
+ return 'D';
740
+ return 'F';
741
+ }
742
+ export async function logEval(input) {
743
+ let resolved;
744
+ try {
745
+ resolved = resolveProjectPaths(input.projectId);
746
+ }
747
+ catch {
748
+ return makeProjectError('log eval');
749
+ }
750
+ // Validate score range
751
+ if (input.score < 0 || input.score > 100) {
752
+ return {
753
+ error: 'INVALID_INPUT',
754
+ message: 'score must be between 0 and 100.',
755
+ };
756
+ }
757
+ const now = new Date();
758
+ const timestamp = now.toISOString();
759
+ const fileTimestamp = formatTimestampForFilename(now);
760
+ const grade = deriveGrade(input.score);
761
+ const id = `EVAL-${fileTimestamp}-${slugify(input.target)}`;
762
+ const evalsDir = resolved.subPath('designer', 'evals');
763
+ ensureDir(evalsDir);
764
+ // Auto-link to most recent eval with same evalType + target
765
+ let previousEvalId = null;
766
+ try {
767
+ const existingFiles = await fs.readdir(evalsDir);
768
+ const candidates = [];
769
+ for (const f of existingFiles) {
770
+ if (!f.endsWith('.yaml') && !f.endsWith('.yml'))
771
+ continue;
772
+ try {
773
+ const content = await fs.readFile(path.join(evalsDir, f), 'utf-8');
774
+ const data = YAML.parse(content);
775
+ if (data?.eval_type === input.evalType && data?.target === input.target && data?.id) {
776
+ candidates.push({ id: data.id, timestamp: data.timestamp });
777
+ }
778
+ }
779
+ catch { /* skip malformed */ }
780
+ }
781
+ if (candidates.length > 0) {
782
+ candidates.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
783
+ previousEvalId = candidates[0].id;
784
+ }
785
+ }
786
+ catch { /* no evals dir yet */ }
787
+ const findingCounts = {
788
+ critical: input.findings.filter(f => f.severity === 'critical').length,
789
+ warning: input.findings.filter(f => f.severity === 'warning').length,
790
+ info: input.findings.filter(f => f.severity === 'info').length,
791
+ };
792
+ const evalData = {
793
+ id,
794
+ project: resolved.id,
795
+ eval_type: input.evalType,
796
+ scope: input.scope,
797
+ target: input.target,
798
+ score: input.score,
799
+ grade,
800
+ summary: input.summary,
801
+ findings: input.findings,
802
+ finding_counts: findingCounts,
803
+ previous_eval_id: previousEvalId,
804
+ platform: input.platform || null,
805
+ branch: input.branch || null,
806
+ commit: input.commit || null,
807
+ evaluator: input.evaluator || 'decibel-designer',
808
+ requested_by: input.requestedBy || null,
809
+ tags: input.tags || [],
810
+ timestamp,
811
+ };
812
+ const filePath = path.join(evalsDir, `${id}.yaml`);
813
+ validateWritePath(filePath, resolved);
814
+ await fs.writeFile(filePath, YAML.stringify(evalData), 'utf-8');
815
+ log(`Designer: Logged eval ${id} — ${input.evalType} ${input.scope} "${input.target}" → ${grade} (${input.score}/100, ${input.findings.length} findings)`);
816
+ await emitCreateProvenance(`designer:eval:${id}`, YAML.stringify(evalData), `Design eval: ${input.evalType} on "${input.target}" — ${grade} (${input.score}/100)`, input.projectId);
817
+ return {
818
+ id,
819
+ grade,
820
+ score: input.score,
821
+ findingCounts,
822
+ previousEvalId,
823
+ path: filePath,
824
+ timestamp,
825
+ };
826
+ }
827
+ export async function listEvals(input) {
828
+ let resolved;
829
+ try {
830
+ resolved = resolveProjectPaths(input.projectId);
831
+ }
832
+ catch {
833
+ return makeProjectError('list evals');
834
+ }
835
+ const evalsDir = resolved.subPath('designer', 'evals');
836
+ let files;
837
+ try {
838
+ files = await fs.readdir(evalsDir);
839
+ }
840
+ catch {
841
+ return { evals: [], total: 0, path: evalsDir };
842
+ }
843
+ const evals = [];
844
+ for (const file of files) {
845
+ if (!file.endsWith('.yaml') && !file.endsWith('.yml'))
846
+ continue;
847
+ try {
848
+ const content = await fs.readFile(path.join(evalsDir, file), 'utf-8');
849
+ const data = YAML.parse(content);
850
+ if (!data?.id)
851
+ continue;
852
+ evals.push({
853
+ id: data.id,
854
+ eval_type: data.eval_type,
855
+ scope: data.scope,
856
+ target: data.target,
857
+ score: data.score,
858
+ grade: data.grade,
859
+ summary: data.summary,
860
+ finding_counts: data.finding_counts || { critical: 0, warning: 0, info: 0 },
861
+ tags: data.tags || [],
862
+ timestamp: data.timestamp,
863
+ });
864
+ }
865
+ catch {
866
+ // Skip malformed files
867
+ }
868
+ }
869
+ // Apply filters
870
+ let filtered = evals;
871
+ if (input.evalType) {
872
+ filtered = filtered.filter(e => e.eval_type === input.evalType);
873
+ }
874
+ if (input.scope) {
875
+ filtered = filtered.filter(e => e.scope === input.scope);
876
+ }
877
+ if (input.target) {
878
+ const t = input.target.toLowerCase();
879
+ filtered = filtered.filter(e => e.target.toLowerCase().includes(t));
880
+ }
881
+ if (input.minScore !== undefined) {
882
+ filtered = filtered.filter(e => e.score >= input.minScore);
883
+ }
884
+ if (input.maxScore !== undefined) {
885
+ filtered = filtered.filter(e => e.score <= input.maxScore);
886
+ }
887
+ if (input.tags && input.tags.length > 0) {
888
+ filtered = filtered.filter(e => input.tags.some(tag => e.tags.includes(tag)));
889
+ }
890
+ // Sort by timestamp descending (most recent first)
891
+ filtered.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
892
+ if (input.limit) {
893
+ filtered = filtered.slice(0, input.limit);
894
+ }
895
+ return {
896
+ evals: filtered,
897
+ total: filtered.length,
898
+ path: evalsDir,
899
+ };
900
+ }
901
+ export async function evalHistory(input) {
902
+ let resolved;
903
+ try {
904
+ resolved = resolveProjectPaths(input.projectId);
905
+ }
906
+ catch {
907
+ return makeProjectError('get eval history');
908
+ }
909
+ const target = input.target || 'full-project';
910
+ // Reuse listEvals to get all matching evals
911
+ const result = await listEvals({
912
+ projectId: input.projectId,
913
+ evalType: input.evalType,
914
+ target,
915
+ });
916
+ if ('error' in result)
917
+ return result;
918
+ // Sort chronologically (oldest first) for trend analysis
919
+ const sorted = [...result.evals].sort((a, b) => a.timestamp.localeCompare(b.timestamp));
920
+ const history = sorted.map(e => ({
921
+ id: e.id,
922
+ score: e.score,
923
+ grade: e.grade,
924
+ finding_counts: e.finding_counts,
925
+ timestamp: e.timestamp,
926
+ summary: e.summary,
927
+ }));
928
+ // Compute trend
929
+ let trend = 'insufficient_data';
930
+ let delta = null;
931
+ if (history.length >= 2) {
932
+ const first = history[0].score;
933
+ const last = history[history.length - 1].score;
934
+ delta = last - first;
935
+ if (delta > 5)
936
+ trend = 'improving';
937
+ else if (delta < -5)
938
+ trend = 'declining';
939
+ else
940
+ trend = 'stable';
941
+ }
942
+ log(`Designer: Eval history for ${input.evalType} "${target}" — ${history.length} data points, trend: ${trend}`);
943
+ return {
944
+ eval_type: input.evalType,
945
+ target,
946
+ history,
947
+ trend,
948
+ delta,
949
+ path: resolved.subPath('designer', 'evals'),
950
+ };
951
+ }
495
952
  //# sourceMappingURL=designer.js.map