@triedotdev/mcp 1.0.123 → 1.0.124

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 (32) hide show
  1. package/dist/{chunk-QIS2VDJL.js → chunk-7J4ZOOAD.js} +50 -13
  2. package/dist/{chunk-QIS2VDJL.js.map → chunk-7J4ZOOAD.js.map} +1 -1
  3. package/dist/{chunk-F4ZIAHTZ.js → chunk-A4EDTN6R.js} +2 -2
  4. package/dist/{chunk-B46FDUKR.js → chunk-D2CGMX7K.js} +4 -4
  5. package/dist/{chunk-CKT2A33R.js → chunk-W2DEBKZ2.js} +2 -2
  6. package/dist/{chunk-WRGSH5RT.js → chunk-WMI44VIC.js} +2 -2
  7. package/dist/{chunk-WRGSH5RT.js.map → chunk-WMI44VIC.js.map} +1 -1
  8. package/dist/cli/main.js +2 -2
  9. package/dist/cli/yolo-daemon.js +5 -5
  10. package/dist/{client-PMKE26IV.js → client-EWP4SIG3.js} +2 -2
  11. package/dist/{goal-validator-XYA364W3.js → goal-validator-CKFKJ46J.js} +2 -2
  12. package/dist/{guardian-agent-PTC6G37Q.js → guardian-agent-5QVLDPKB.js} +5 -5
  13. package/dist/{hypothesis-WWDONGPU.js → hypothesis-HFYZNIMZ.js} +2 -2
  14. package/dist/index.js +147 -27
  15. package/dist/index.js.map +1 -1
  16. package/dist/ui/chat.html +821 -0
  17. package/dist/ui/goals.html +724 -0
  18. package/dist/ui/hypotheses.html +768 -0
  19. package/dist/ui/ledger.html +711 -0
  20. package/dist/ui/nudges.html +752 -0
  21. package/package.json +1 -1
  22. package/dist/ui/memory-viewer.html +0 -773
  23. package/dist/ui/pr-review.html +0 -742
  24. package/dist/ui/scan-dashboard.html +0 -741
  25. package/dist/ui/visual-qa.html +0 -762
  26. /package/dist/{chunk-F4ZIAHTZ.js.map → chunk-A4EDTN6R.js.map} +0 -0
  27. /package/dist/{chunk-B46FDUKR.js.map → chunk-D2CGMX7K.js.map} +0 -0
  28. /package/dist/{chunk-CKT2A33R.js.map → chunk-W2DEBKZ2.js.map} +0 -0
  29. /package/dist/{client-PMKE26IV.js.map → client-EWP4SIG3.js.map} +0 -0
  30. /package/dist/{goal-validator-XYA364W3.js.map → goal-validator-CKFKJ46J.js.map} +0 -0
  31. /package/dist/{guardian-agent-PTC6G37Q.js.map → guardian-agent-5QVLDPKB.js.map} +0 -0
  32. /package/dist/{hypothesis-WWDONGPU.js.map → hypothesis-HFYZNIMZ.js.map} +0 -0
@@ -0,0 +1,724 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Goals & Progress - Trie</title>
7
+ <style>
8
+ /* MCP Apps Shared Styles for Trie */
9
+ :root {
10
+ --trie-bg: #0d1117;
11
+ --trie-surface: #161b22;
12
+ --trie-border: #30363d;
13
+ --trie-text: #e6edf3;
14
+ --trie-text-muted: #8b949e;
15
+ --trie-primary: #58a6ff;
16
+ --trie-success: #3fb950;
17
+ --trie-warning: #d29922;
18
+ --trie-error: #f85149;
19
+ --trie-critical: #ff7b72;
20
+ --trie-info: #58a6ff;
21
+ --radius: 6px;
22
+ --font-mono: 'SF Mono', 'Menlo', 'Monaco', 'Consolas', monospace;
23
+ --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;
24
+ }
25
+
26
+ * {
27
+ box-sizing: border-box;
28
+ margin: 0;
29
+ padding: 0;
30
+ }
31
+
32
+ body {
33
+ font-family: var(--font-sans);
34
+ font-size: 14px;
35
+ line-height: 1.5;
36
+ color: var(--trie-text);
37
+ background: var(--trie-bg);
38
+ padding: 16px;
39
+ }
40
+
41
+ /* Typography */
42
+ h1, h2, h3, h4 {
43
+ font-weight: 600;
44
+ margin-bottom: 8px;
45
+ }
46
+
47
+ h1 { font-size: 24px; }
48
+ h2 { font-size: 20px; }
49
+ h3 { font-size: 16px; }
50
+ h4 { font-size: 14px; }
51
+
52
+ .text-muted { color: var(--trie-text-muted); }
53
+ .text-error { color: var(--trie-error); }
54
+ .text-warning { color: var(--trie-warning); }
55
+ .text-success { color: var(--trie-success); }
56
+ .text-info { color: var(--trie-info); }
57
+
58
+ /* Layout */
59
+ .container {
60
+ max-width: 1200px;
61
+ margin: 0 auto;
62
+ }
63
+
64
+ .flex { display: flex; }
65
+ .flex-col { flex-direction: column; }
66
+ .flex-wrap { flex-wrap: wrap; }
67
+ .items-center { align-items: center; }
68
+ .justify-between { justify-content: space-between; }
69
+ .gap-2 { gap: 8px; }
70
+ .gap-4 { gap: 16px; }
71
+
72
+ /* Cards */
73
+ .card {
74
+ background: var(--trie-surface);
75
+ border: 1px solid var(--trie-border);
76
+ border-radius: var(--radius);
77
+ padding: 16px;
78
+ }
79
+
80
+ .card-header {
81
+ display: flex;
82
+ align-items: center;
83
+ justify-content: space-between;
84
+ margin-bottom: 12px;
85
+ padding-bottom: 12px;
86
+ border-bottom: 1px solid var(--trie-border);
87
+ }
88
+
89
+ /* Buttons */
90
+ .btn {
91
+ display: inline-flex;
92
+ align-items: center;
93
+ gap: 6px;
94
+ padding: 6px 12px;
95
+ font-size: 14px;
96
+ font-weight: 500;
97
+ border-radius: var(--radius);
98
+ border: 1px solid var(--trie-border);
99
+ background: var(--trie-surface);
100
+ color: var(--trie-text);
101
+ cursor: pointer;
102
+ transition: all 0.15s ease;
103
+ }
104
+
105
+ .btn:hover {
106
+ background: var(--trie-border);
107
+ }
108
+
109
+ .btn-primary {
110
+ background: var(--trie-primary);
111
+ border-color: var(--trie-primary);
112
+ color: #fff;
113
+ }
114
+
115
+ .btn-primary:hover {
116
+ opacity: 0.9;
117
+ }
118
+
119
+ .btn-success {
120
+ background: var(--trie-success);
121
+ border-color: var(--trie-success);
122
+ color: #fff;
123
+ }
124
+
125
+ .btn-danger {
126
+ background: var(--trie-error);
127
+ border-color: var(--trie-error);
128
+ color: #fff;
129
+ }
130
+
131
+ .btn-sm {
132
+ padding: 4px 8px;
133
+ font-size: 12px;
134
+ }
135
+
136
+ .btn-icon {
137
+ padding: 6px;
138
+ min-width: 32px;
139
+ justify-content: center;
140
+ }
141
+
142
+ /* Inputs */
143
+ .input {
144
+ padding: 8px 12px;
145
+ font-size: 14px;
146
+ border: 1px solid var(--trie-border);
147
+ border-radius: var(--radius);
148
+ background: var(--trie-bg);
149
+ color: var(--trie-text);
150
+ width: 100%;
151
+ }
152
+
153
+ .input:focus {
154
+ outline: none;
155
+ border-color: var(--trie-primary);
156
+ }
157
+
158
+ .select {
159
+ padding: 8px 12px;
160
+ font-size: 14px;
161
+ border: 1px solid var(--trie-border);
162
+ border-radius: var(--radius);
163
+ background: var(--trie-surface);
164
+ color: var(--trie-text);
165
+ cursor: pointer;
166
+ }
167
+
168
+ /* Badges */
169
+ .badge {
170
+ display: inline-flex;
171
+ align-items: center;
172
+ padding: 2px 8px;
173
+ font-size: 12px;
174
+ font-weight: 500;
175
+ border-radius: 12px;
176
+ background: var(--trie-border);
177
+ color: var(--trie-text);
178
+ }
179
+
180
+ .badge-critical {
181
+ background: rgba(255, 123, 114, 0.2);
182
+ color: var(--trie-critical);
183
+ }
184
+
185
+ .badge-high {
186
+ background: rgba(248, 81, 73, 0.2);
187
+ color: var(--trie-error);
188
+ }
189
+
190
+ .badge-medium {
191
+ background: rgba(210, 153, 34, 0.2);
192
+ color: var(--trie-warning);
193
+ }
194
+
195
+ .badge-low {
196
+ background: rgba(63, 185, 80, 0.2);
197
+ color: var(--trie-success);
198
+ }
199
+
200
+ .badge-info {
201
+ background: rgba(88, 166, 255, 0.2);
202
+ color: var(--trie-info);
203
+ }
204
+
205
+ /* Tables */
206
+ .table {
207
+ width: 100%;
208
+ border-collapse: collapse;
209
+ }
210
+
211
+ .table th,
212
+ .table td {
213
+ padding: 12px;
214
+ text-align: left;
215
+ border-bottom: 1px solid var(--trie-border);
216
+ }
217
+
218
+ .table th {
219
+ font-weight: 600;
220
+ color: var(--trie-text-muted);
221
+ font-size: 12px;
222
+ text-transform: uppercase;
223
+ }
224
+
225
+ .table tr:hover {
226
+ background: rgba(255, 255, 255, 0.02);
227
+ }
228
+
229
+ /* Lists */
230
+ .list {
231
+ list-style: none;
232
+ }
233
+
234
+ .list-item {
235
+ padding: 12px;
236
+ border-bottom: 1px solid var(--trie-border);
237
+ cursor: pointer;
238
+ transition: background 0.15s ease;
239
+ }
240
+
241
+ .list-item:hover {
242
+ background: rgba(255, 255, 255, 0.02);
243
+ }
244
+
245
+ .list-item:last-child {
246
+ border-bottom: none;
247
+ }
248
+
249
+ /* Issue Item */
250
+ .issue-item {
251
+ display: flex;
252
+ gap: 12px;
253
+ padding: 12px;
254
+ border: 1px solid var(--trie-border);
255
+ border-radius: var(--radius);
256
+ margin-bottom: 8px;
257
+ cursor: pointer;
258
+ transition: all 0.15s ease;
259
+ }
260
+
261
+ .issue-item:hover {
262
+ border-color: var(--trie-primary);
263
+ background: rgba(88, 166, 255, 0.05);
264
+ }
265
+
266
+ .issue-item.expanded {
267
+ border-color: var(--trie-primary);
268
+ }
269
+
270
+ .issue-severity {
271
+ width: 4px;
272
+ border-radius: 2px;
273
+ flex-shrink: 0;
274
+ }
275
+
276
+ .issue-severity.critical { background: var(--trie-critical); }
277
+ .issue-severity.high { background: var(--trie-error); }
278
+ .issue-severity.medium { background: var(--trie-warning); }
279
+ .issue-severity.low { background: var(--trie-success); }
280
+ .issue-severity.info { background: var(--trie-info); }
281
+
282
+ .issue-content {
283
+ flex: 1;
284
+ min-width: 0;
285
+ }
286
+
287
+ .issue-title {
288
+ font-weight: 500;
289
+ margin-bottom: 4px;
290
+ }
291
+
292
+ .issue-meta {
293
+ font-size: 12px;
294
+ color: var(--trie-text-muted);
295
+ }
296
+
297
+ .issue-details {
298
+ margin-top: 12px;
299
+ padding-top: 12px;
300
+ border-top: 1px solid var(--trie-border);
301
+ }
302
+
303
+ .issue-actions {
304
+ display: flex;
305
+ gap: 8px;
306
+ margin-top: 12px;
307
+ }
308
+
309
+ /* Code blocks */
310
+ .code-block {
311
+ font-family: var(--font-mono);
312
+ font-size: 12px;
313
+ background: var(--trie-bg);
314
+ border: 1px solid var(--trie-border);
315
+ border-radius: var(--radius);
316
+ padding: 12px;
317
+ overflow-x: auto;
318
+ white-space: pre;
319
+ }
320
+
321
+ .code-inline {
322
+ font-family: var(--font-mono);
323
+ font-size: 12px;
324
+ background: rgba(110, 118, 129, 0.2);
325
+ padding: 2px 6px;
326
+ border-radius: 4px;
327
+ }
328
+
329
+ /* File path */
330
+ .file-path {
331
+ font-family: var(--font-mono);
332
+ font-size: 12px;
333
+ color: var(--trie-primary);
334
+ }
335
+
336
+ /* Tabs */
337
+ .tabs {
338
+ display: flex;
339
+ border-bottom: 1px solid var(--trie-border);
340
+ margin-bottom: 16px;
341
+ }
342
+
343
+ .tab {
344
+ padding: 8px 16px;
345
+ font-size: 14px;
346
+ color: var(--trie-text-muted);
347
+ cursor: pointer;
348
+ border-bottom: 2px solid transparent;
349
+ margin-bottom: -1px;
350
+ transition: all 0.15s ease;
351
+ }
352
+
353
+ .tab:hover {
354
+ color: var(--trie-text);
355
+ }
356
+
357
+ .tab.active {
358
+ color: var(--trie-primary);
359
+ border-bottom-color: var(--trie-primary);
360
+ }
361
+
362
+ /* Stats */
363
+ .stats {
364
+ display: grid;
365
+ grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
366
+ gap: 16px;
367
+ margin-bottom: 24px;
368
+ }
369
+
370
+ .stat {
371
+ text-align: center;
372
+ padding: 16px;
373
+ background: var(--trie-surface);
374
+ border: 1px solid var(--trie-border);
375
+ border-radius: var(--radius);
376
+ }
377
+
378
+ .stat-value {
379
+ font-size: 32px;
380
+ font-weight: 700;
381
+ line-height: 1;
382
+ }
383
+
384
+ .stat-label {
385
+ font-size: 12px;
386
+ color: var(--trie-text-muted);
387
+ margin-top: 4px;
388
+ }
389
+
390
+ /* Filters */
391
+ .filters {
392
+ display: flex;
393
+ flex-wrap: wrap;
394
+ gap: 12px;
395
+ margin-bottom: 16px;
396
+ padding: 12px;
397
+ background: var(--trie-surface);
398
+ border: 1px solid var(--trie-border);
399
+ border-radius: var(--radius);
400
+ }
401
+
402
+ .filter-group {
403
+ display: flex;
404
+ align-items: center;
405
+ gap: 8px;
406
+ }
407
+
408
+ .filter-label {
409
+ font-size: 12px;
410
+ color: var(--trie-text-muted);
411
+ }
412
+
413
+ /* Screenshot Grid */
414
+ .screenshot-grid {
415
+ display: grid;
416
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
417
+ gap: 16px;
418
+ }
419
+
420
+ .screenshot-card {
421
+ border: 1px solid var(--trie-border);
422
+ border-radius: var(--radius);
423
+ overflow: hidden;
424
+ }
425
+
426
+ .screenshot-card img {
427
+ width: 100%;
428
+ height: auto;
429
+ display: block;
430
+ }
431
+
432
+ .screenshot-card-footer {
433
+ padding: 12px;
434
+ background: var(--trie-surface);
435
+ }
436
+
437
+ /* Diff view */
438
+ .diff-container {
439
+ font-family: var(--font-mono);
440
+ font-size: 12px;
441
+ border: 1px solid var(--trie-border);
442
+ border-radius: var(--radius);
443
+ overflow: hidden;
444
+ }
445
+
446
+ .diff-header {
447
+ padding: 8px 12px;
448
+ background: var(--trie-surface);
449
+ border-bottom: 1px solid var(--trie-border);
450
+ }
451
+
452
+ .diff-line {
453
+ display: flex;
454
+ padding: 0 12px;
455
+ min-height: 24px;
456
+ line-height: 24px;
457
+ }
458
+
459
+ .diff-line-number {
460
+ width: 50px;
461
+ color: var(--trie-text-muted);
462
+ user-select: none;
463
+ text-align: right;
464
+ padding-right: 12px;
465
+ flex-shrink: 0;
466
+ }
467
+
468
+ .diff-line-content {
469
+ flex: 1;
470
+ white-space: pre;
471
+ }
472
+
473
+ .diff-line.added {
474
+ background: rgba(63, 185, 80, 0.15);
475
+ }
476
+
477
+ .diff-line.removed {
478
+ background: rgba(248, 81, 73, 0.15);
479
+ }
480
+
481
+ .diff-line.added .diff-line-content::before {
482
+ content: '+';
483
+ color: var(--trie-success);
484
+ margin-right: 8px;
485
+ }
486
+
487
+ .diff-line.removed .diff-line-content::before {
488
+ content: '-';
489
+ color: var(--trie-error);
490
+ margin-right: 8px;
491
+ }
492
+
493
+ /* File tree */
494
+ .file-tree {
495
+ font-family: var(--font-mono);
496
+ font-size: 12px;
497
+ }
498
+
499
+ .file-tree-item {
500
+ display: flex;
501
+ align-items: center;
502
+ gap: 8px;
503
+ padding: 6px 12px;
504
+ cursor: pointer;
505
+ border-radius: var(--radius);
506
+ }
507
+
508
+ .file-tree-item:hover {
509
+ background: rgba(255, 255, 255, 0.05);
510
+ }
511
+
512
+ .file-tree-item.selected {
513
+ background: rgba(88, 166, 255, 0.1);
514
+ color: var(--trie-primary);
515
+ }
516
+
517
+ .file-tree-icon {
518
+ width: 16px;
519
+ height: 16px;
520
+ opacity: 0.7;
521
+ }
522
+
523
+ /* Loading */
524
+ .loading {
525
+ display: flex;
526
+ align-items: center;
527
+ justify-content: center;
528
+ padding: 48px;
529
+ color: var(--trie-text-muted);
530
+ }
531
+
532
+ .spinner {
533
+ width: 24px;
534
+ height: 24px;
535
+ border: 2px solid var(--trie-border);
536
+ border-top-color: var(--trie-primary);
537
+ border-radius: 50%;
538
+ animation: spin 0.8s linear infinite;
539
+ }
540
+
541
+ @keyframes spin {
542
+ to { transform: rotate(360deg); }
543
+ }
544
+
545
+ /* Empty state */
546
+ .empty-state {
547
+ text-align: center;
548
+ padding: 48px;
549
+ color: var(--trie-text-muted);
550
+ }
551
+
552
+ .empty-state-icon {
553
+ font-size: 48px;
554
+ margin-bottom: 16px;
555
+ opacity: 0.5;
556
+ }
557
+
558
+ /* Scrollbar */
559
+ ::-webkit-scrollbar {
560
+ width: 8px;
561
+ height: 8px;
562
+ }
563
+
564
+ ::-webkit-scrollbar-track {
565
+ background: transparent;
566
+ }
567
+
568
+ ::-webkit-scrollbar-thumb {
569
+ background: var(--trie-border);
570
+ border-radius: 4px;
571
+ }
572
+
573
+ ::-webkit-scrollbar-thumb:hover {
574
+ background: var(--trie-text-muted);
575
+ }
576
+
577
+ /* Utilities */
578
+ .hidden { display: none !important; }
579
+ .mt-2 { margin-top: 8px; }
580
+ .mt-4 { margin-top: 16px; }
581
+ .mb-2 { margin-bottom: 8px; }
582
+ .mb-4 { margin-bottom: 16px; }
583
+ .p-2 { padding: 8px; }
584
+ .p-4 { padding: 16px; }
585
+ .truncate {
586
+ overflow: hidden;
587
+ text-overflow: ellipsis;
588
+ white-space: nowrap;
589
+ }
590
+
591
+ /* Tree View Styles */
592
+ .tree-section {
593
+ margin-bottom: 12px;
594
+ }
595
+
596
+ .tree-section-header {
597
+ user-select: none;
598
+ transition: background 0.15s ease;
599
+ }
600
+
601
+ .tree-section-header:hover {
602
+ background: rgba(255, 255, 255, 0.05) !important;
603
+ }
604
+
605
+ .tree-item {
606
+ transition: background 0.15s ease;
607
+ margin-bottom: 2px;
608
+ }
609
+
610
+ .tree-item:hover {
611
+ background: rgba(255, 255, 255, 0.05) !important;
612
+ }
613
+
614
+ /* Memory Tree specific */
615
+ .memory-tree {
616
+ font-family: var(--font-mono);
617
+ font-size: 12px;
618
+ line-height: 1.6;
619
+ }
620
+
621
+ .memory-tree-indent {
622
+ display: inline-block;
623
+ width: 24px;
624
+ }
625
+
626
+ .memory-tree-bar {
627
+ display: inline-flex;
628
+ align-items: center;
629
+ height: 16px;
630
+ margin-left: 8px;
631
+ }
632
+
633
+ .memory-tree-bar-filled {
634
+ height: 8px;
635
+ background: var(--trie-primary);
636
+ border-radius: 4px;
637
+ transition: width 0.3s ease;
638
+ }
639
+
640
+ .memory-tree-bar-empty {
641
+ height: 8px;
642
+ background: var(--trie-border);
643
+ border-radius: 4px;
644
+ flex: 1;
645
+ }
646
+
647
+ </style>
648
+ </head>
649
+ <body>
650
+ <div id="app" class="container"></div>
651
+ <script type="module">
652
+ var g=Object.defineProperty;var m=(n,e,t)=>e in n?g(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var l=(n,e,t)=>m(n,typeof e!="symbol"?e+"":e,t);function v(n,e,t){let a=document.createElement(n);if(e)for(let[s,i]of Object.entries(e))s==="className"?a.className=String(i):typeof i=="boolean"?i&&a.setAttribute(s,""):a.setAttribute(s,String(i));if(t)for(let s of t)typeof s=="string"?a.appendChild(document.createTextNode(s)):a.appendChild(s);return a}var r=v;function h(n){return r("div",{className:"loading"},[r("div",{className:"spinner"}),n?r("span",{className:"ml-2"},[n]):document.createTextNode("")])}function p(n,e="Loading..."){n.innerHTML="",n.appendChild(h(e))}function c(n,e){n.innerHTML="",n.appendChild(r("div",{className:"error-state"},[r("div",{className:"error-icon"},["\u26A0\uFE0F"]),r("p",{className:"error-message"},[e])]))}function u(n){document.addEventListener("DOMContentLoaded",()=>{let e=document.getElementById("app");if(!e){console.error("App container not found");return}try{new n(e)}catch(t){c(e,`Failed to initialize app: ${t}`)}})}var d=class{constructor(e){l(this,"container");l(this,"goals",[]);l(this,"selectedGoal",null);this.container=e,this.init()}async init(){await this.loadData(),this.render(),this.setupEventListeners()}async loadData(){try{p(this.container,"Loading goals..."),this.goals=[{id:"goal-1",description:"Eliminate all emoji usage from codebase",type:"reduction",status:"active",currentValue:2,target:0,startValue:15,category:"quality",autoGenerated:!1,createdAt:new Date(Date.now()-864e5*3).toISOString(),updatedAt:new Date().toISOString()},{id:"goal-2",description:"Increase test coverage to 85%",type:"increase",status:"active",currentValue:72,target:85,startValue:65,category:"coverage",autoGenerated:!0,createdAt:new Date(Date.now()-864e5).toISOString(),updatedAt:new Date().toISOString()},{id:"goal-3",description:"Remove all TODO comments",type:"reduction",status:"achieved",currentValue:0,target:0,startValue:8,category:"quality",autoGenerated:!1,createdAt:new Date(Date.now()-864e5*7).toISOString(),updatedAt:new Date(Date.now()-864e5*2).toISOString(),achievedAt:new Date(Date.now()-864e5*2).toISOString()}]}catch(e){c(this.container,`Failed to load goals: ${e}`)}}render(){let e=this.goals.filter(i=>i.status==="active"),t=this.goals.filter(i=>i.status==="achieved"),a=this.goals.filter(i=>i.status==="rejected"),s=`
653
+ <div class="app-header">
654
+ <h1>Goals & Progress</h1>
655
+ <p>Track your code quality and improvement goals</p>
656
+ </div>
657
+
658
+ <div class="stats-bar">
659
+ <div class="stat">
660
+ <span class="stat-number">${e.length}</span>
661
+ <span class="stat-label">Active Goals</span>
662
+ </div>
663
+ <div class="stat">
664
+ <span class="stat-number">${t.length}</span>
665
+ <span class="stat-label">Achieved</span>
666
+ </div>
667
+ <div class="stat">
668
+ <span class="stat-number">${Math.round(this.calculateOverallProgress())}%</span>
669
+ <span class="stat-label">Overall Progress</span>
670
+ </div>
671
+ </div>
672
+
673
+ ${this.renderGoalsList("Active Goals",e,"active")}
674
+ ${t.length>0?this.renderGoalsList("Achieved Goals",t,"achieved"):""}
675
+ ${a.length>0?this.renderGoalsList("Other Goals",a,"other"):""}
676
+ `;this.container.innerHTML=s}renderGoalsList(e,t,a){return t.length===0?"":`
677
+ <div class="section">
678
+ <h2 class="section-title">${e}</h2>
679
+ <div class="goals-list">
680
+ ${t.map(s=>this.renderGoalCard(s,a)).join("")}
681
+ </div>
682
+ </div>
683
+ `}renderGoalCard(e,t){let a=this.calculateGoalProgress(e),s=this.createProgressBar(a);return`
684
+ <div class="goal-card ${t==="achieved"?"goal-achieved":t==="active"?"goal-active":"goal-other"}" data-goal-id="${e.id}">
685
+ <div class="goal-header">
686
+ <span class="goal-title">${e.description}</span>
687
+ <div class="goal-meta">
688
+ ${e.category?`<span class="goal-category">${e.category}</span>`:""}
689
+ ${e.autoGenerated?'<span class="goal-auto">auto</span>':""}
690
+ </div>
691
+ </div>
692
+
693
+ <div class="goal-progress">
694
+ <div class="progress-bar-container">
695
+ ${s}
696
+ <span class="progress-text">${a}%</span>
697
+ </div>
698
+ <div class="progress-details">
699
+ Current: ${e.currentValue} | Target: ${e.target}
700
+ ${e.startValue!==void 0?` | Start: ${e.startValue}`:""}
701
+ </div>
702
+ </div>
703
+
704
+ <div class="goal-footer">
705
+ <span class="goal-date">
706
+ ${t==="achieved"&&e.achievedAt?`Achieved ${this.formatTimeAgo(e.achievedAt)}`:`Updated ${this.formatTimeAgo(e.updatedAt)}`}
707
+ </span>
708
+ ${t==="active"?`
709
+ <div class="goal-actions">
710
+ <button class="btn btn-sm" onclick="checkGoal('${e.id}')">Check Now</button>
711
+ <button class="btn btn-sm btn-success" onclick="completeGoal('${e.id}')">Complete</button>
712
+ </div>
713
+ `:""}
714
+ </div>
715
+ </div>
716
+ `}calculateGoalProgress(e){if(e.target<=0)return 0;let t=e.startValue??e.currentValue;if(t>e.target){let a=t-e.target,s=t-e.currentValue;return Math.min(100,Math.max(0,Math.round(s/a*100)))}return Math.min(100,Math.max(0,Math.round(e.currentValue/e.target*100)))}calculateOverallProgress(){let e=this.goals.filter(a=>a.status==="active");return e.length===0?100:e.reduce((a,s)=>a+this.calculateGoalProgress(s),0)/e.length}createProgressBar(e){let a=10-Math.round(e/10);return`
717
+ <div class="progress-bar">
718
+ <div class="progress-fill" style="width: ${e}%"></div>
719
+ </div>
720
+ `}formatTimeAgo(e){let t=Date.now(),a=new Date(e).getTime(),s=t-a,i=Math.floor(s/(1e3*60));if(i<60)return`${i}m ago`;let o=Math.floor(i/60);return o<24?`${o}h ago`:`${Math.floor(o/24)}d ago`}setupEventListeners(){this.container.addEventListener("click",e=>{let a=e.target.closest(".goal-card");if(a){let s=a.getAttribute("data-goal-id"),i=this.goals.find(o=>o.id===s);i&&(this.selectedGoal=i)}}),window.checkGoal=e=>{console.log("Checking goal:",e)},window.completeGoal=e=>{console.log("Completing goal:",e)}}};u(d);
721
+
722
+ </script>
723
+ </body>
724
+ </html>