agentgui 1.0.67 → 1.0.69

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 (55) hide show
  1. package/.prd +92 -0
  2. package/.prd-browser +607 -0
  3. package/CLAUDE.md +1559 -125
  4. package/browser-test-harness.js +371 -0
  5. package/browser-test.js +409 -0
  6. package/execute-tests.js +164 -0
  7. package/lib/claude-runner.js +41 -12
  8. package/lib/database-service.ts +252 -0
  9. package/lib/sync-service.ts +275 -0
  10. package/lib/types.ts +168 -0
  11. package/package.json +1 -1
  12. package/readme.md +586 -0
  13. package/run-e2e-test.sh +88 -0
  14. package/server.js +274 -8
  15. package/static/index.html +487 -180
  16. package/static/js/client.js +558 -0
  17. package/static/js/event-filter.js +311 -0
  18. package/static/js/event-processor.js +454 -0
  19. package/static/js/streaming-renderer.js +813 -0
  20. package/static/js/syntax-highlighter.js +271 -0
  21. package/static/js/ui-components.js +433 -0
  22. package/static/js/websocket-manager.js +482 -0
  23. package/static/templates/INDEX.html +465 -0
  24. package/static/templates/README.md +190 -0
  25. package/static/templates/agent-capabilities.html +56 -0
  26. package/static/templates/agent-metadata-panel.html +44 -0
  27. package/static/templates/agent-status-badge.html +30 -0
  28. package/static/templates/code-annotation-panel.html +155 -0
  29. package/static/templates/code-suggestion-panel.html +184 -0
  30. package/static/templates/command-header.html +77 -0
  31. package/static/templates/command-output-scrollable.html +118 -0
  32. package/static/templates/elapsed-time.html +54 -0
  33. package/static/templates/error-alert.html +106 -0
  34. package/static/templates/error-history-timeline.html +160 -0
  35. package/static/templates/error-recovery-options.html +109 -0
  36. package/static/templates/error-stack-trace.html +95 -0
  37. package/static/templates/error-summary.html +80 -0
  38. package/static/templates/event-counter.html +48 -0
  39. package/static/templates/execution-actions.html +97 -0
  40. package/static/templates/execution-progress-bar.html +80 -0
  41. package/static/templates/execution-stepper.html +120 -0
  42. package/static/templates/file-breadcrumb.html +118 -0
  43. package/static/templates/file-diff-viewer.html +121 -0
  44. package/static/templates/file-metadata.html +133 -0
  45. package/static/templates/file-read-panel.html +66 -0
  46. package/static/templates/file-write-panel.html +120 -0
  47. package/static/templates/git-branch-remote.html +107 -0
  48. package/static/templates/git-diff-list.html +101 -0
  49. package/static/templates/git-log-visualization.html +153 -0
  50. package/static/templates/git-status-panel.html +115 -0
  51. package/static/templates/quality-metrics-display.html +170 -0
  52. package/static/templates/terminal-output-panel.html +87 -0
  53. package/static/templates/test-results-display.html +144 -0
  54. package/test-browser.js +457 -0
  55. package/test-runner.js +182 -0
@@ -0,0 +1,97 @@
1
+ <!-- Execution Control Buttons -->
2
+ <div class="execution-actions flex gap-2" role="group" aria-label="Execution controls">
3
+ <!-- Cancel Button -->
4
+ <button class="btn btn-secondary"
5
+ data-action="cancel"
6
+ aria-label="Cancel execution"
7
+ title="Stop the current execution">
8
+ <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
9
+ <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"/>
10
+ </svg>
11
+ <span>Cancel</span>
12
+ </button>
13
+
14
+ <!-- Pause Button -->
15
+ <button class="btn btn-secondary"
16
+ data-action="pause"
17
+ aria-label="Pause execution"
18
+ title="Pause the current execution">
19
+ <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
20
+ <path d="M5 3a2 2 0 012 2v10a2 2 0 01-2 2H3a2 2 0 01-2-2V5a2 2 0 012-2h2zm10 0a2 2 0 012 2v10a2 2 0 01-2 2h-2a2 2 0 01-2-2V5a2 2 0 012-2h2z"/>
21
+ </svg>
22
+ <span>Pause</span>
23
+ </button>
24
+
25
+ <!-- Resume Button (hidden by default) -->
26
+ <button class="btn btn-secondary hidden"
27
+ data-action="resume"
28
+ aria-label="Resume execution"
29
+ title="Resume the paused execution">
30
+ <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
31
+ <path d="M6.3 2.841A1.5 1.5 0 004 4.11V15.89a1.5 1.5 0 002.3 1.269l9.344-5.89a1.5 1.5 0 000-2.538L6.3 2.84z"/>
32
+ </svg>
33
+ <span>Resume</span>
34
+ </button>
35
+
36
+ <!-- Export Button -->
37
+ <button class="btn btn-tertiary"
38
+ data-action="export"
39
+ aria-label="Export execution results"
40
+ title="Download results as JSON">
41
+ <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
42
+ <path d="M3 17a1 1 0 011-1h12a1 1 0 011 1v2a1 1 0 01-1 1H4a1 1 0 01-1-1v-2zm4-6a1 1 0 011-1h2V4a1 1 0 112 0v6h2a1 1 0 110 2h-6a1 1 0 01-1-1z"/>
43
+ </svg>
44
+ <span>Export</span>
45
+ </button>
46
+ </div>
47
+
48
+ <style scoped>
49
+ .execution-actions {
50
+ display: flex;
51
+ gap: 8px;
52
+ flex-wrap: wrap;
53
+ }
54
+
55
+ .btn {
56
+ display: inline-flex;
57
+ align-items: center;
58
+ gap: 6px;
59
+ padding: 8px 12px;
60
+ border-radius: 4px;
61
+ font-size: 13px;
62
+ font-weight: 500;
63
+ cursor: pointer;
64
+ border: none;
65
+ transition: all 0.2s ease;
66
+ }
67
+
68
+ .btn:disabled {
69
+ opacity: 0.5;
70
+ cursor: not-allowed;
71
+ }
72
+
73
+ .btn-secondary {
74
+ background-color: var(--color-bg-secondary);
75
+ color: var(--color-text-primary);
76
+ border: 1px solid var(--color-border);
77
+ }
78
+
79
+ .btn-secondary:hover:not(:disabled) {
80
+ background-color: var(--color-bg-hover);
81
+ border-color: var(--color-primary);
82
+ }
83
+
84
+ .btn-tertiary {
85
+ background-color: transparent;
86
+ color: var(--color-primary);
87
+ border: 1px solid var(--color-primary);
88
+ }
89
+
90
+ .btn-tertiary:hover:not(:disabled) {
91
+ background-color: var(--color-primary-hover);
92
+ }
93
+
94
+ .hidden {
95
+ display: none;
96
+ }
97
+ </style>
@@ -0,0 +1,80 @@
1
+ <!-- Execution Progress Visualization -->
2
+ <div class="execution-progress card" role="region" aria-label="Execution progress">
3
+ <div class="card-header flex items-center justify-between mb-4">
4
+ <div>
5
+ <h3 class="font-semibold">Execution Progress</h3>
6
+ <p class="text-sm text-secondary">{{ executionStatus }}</p>
7
+ </div>
8
+ <span class="badge" role="status" aria-live="polite">{{ percentage }}%</span>
9
+ </div>
10
+
11
+ <!-- Progress Bar -->
12
+ <div class="progress-container mb-4" role="progressbar" aria-valuenow="{{ percentage }}" aria-valuemin="0" aria-valuemax="100" aria-label="Progress: {{ percentage }}%">
13
+ <div class="progress-bar" style="width: {{ percentage }}%">
14
+ <span class="progress-text" aria-hidden="true">{{ percentage }}%</span>
15
+ </div>
16
+ </div>
17
+
18
+ <!-- Progress Details Grid -->
19
+ <div class="grid grid-cols-3 gap-3 text-sm">
20
+ <div class="border-r pr-3">
21
+ <span class="text-secondary">Events</span>
22
+ <p class="font-semibold text-lg">{{ eventCount }}</p>
23
+ </div>
24
+ <div class="border-r pr-3">
25
+ <span class="text-secondary">Elapsed</span>
26
+ <p class="font-mono text-lg">{{ elapsedTime }}</p>
27
+ </div>
28
+ <div>
29
+ <span class="text-secondary">Remaining</span>
30
+ <p class="font-mono text-lg">{{ estimatedRemaining }}</p>
31
+ </div>
32
+ </div>
33
+
34
+ <!-- Status Timeline -->
35
+ <div class="mt-4 pt-4 border-t">
36
+ <div class="flex justify-between text-xs">
37
+ <span class="flex items-center gap-1">
38
+ <span class="w-2 h-2 rounded-full bg-primary" aria-hidden="true"></span>
39
+ Queued
40
+ </span>
41
+ <span class="flex items-center gap-1">
42
+ <span class="w-2 h-2 rounded-full bg-primary" aria-hidden="true"></span>
43
+ Running
44
+ </span>
45
+ <span class="flex items-center gap-1">
46
+ <span class="w-2 h-2 rounded-full bg-primary" aria-hidden="true"></span>
47
+ Processing
48
+ </span>
49
+ <span class="flex items-center gap-1">
50
+ <span class="w-2 h-2 rounded-full bg-secondary" aria-hidden="true"></span>
51
+ Complete
52
+ </span>
53
+ </div>
54
+ </div>
55
+ </div>
56
+
57
+ <style scoped>
58
+ .progress-container {
59
+ position: relative;
60
+ height: 24px;
61
+ background-color: var(--color-bg-secondary);
62
+ border-radius: 4px;
63
+ overflow: hidden;
64
+ }
65
+
66
+ .progress-bar {
67
+ height: 100%;
68
+ background-color: var(--color-primary);
69
+ transition: width 0.3s ease;
70
+ display: flex;
71
+ align-items: center;
72
+ justify-content: center;
73
+ }
74
+
75
+ .progress-text {
76
+ font-size: 11px;
77
+ font-weight: 600;
78
+ color: white;
79
+ }
80
+ </style>
@@ -0,0 +1,120 @@
1
+ <!-- Execution Phase Stepper -->
2
+ <div class="execution-stepper" role="region" aria-label="Execution phases">
3
+ <div class="flex justify-between items-center">
4
+ <!-- Phase 1: Queued -->
5
+ <div class="stepper-item" data-phase="queued" data-completed="true" aria-label="Phase: Queued (completed)">
6
+ <div class="stepper-circle">
7
+ <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
8
+ <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"/>
9
+ </svg>
10
+ </div>
11
+ <span class="stepper-label">Queued</span>
12
+ </div>
13
+
14
+ <div class="stepper-connector"></div>
15
+
16
+ <!-- Phase 2: Running -->
17
+ <div class="stepper-item" data-phase="running" data-completed="true" aria-label="Phase: Running (completed)">
18
+ <div class="stepper-circle">
19
+ <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
20
+ <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"/>
21
+ </svg>
22
+ </div>
23
+ <span class="stepper-label">Running</span>
24
+ </div>
25
+
26
+ <div class="stepper-connector"></div>
27
+
28
+ <!-- Phase 3: Processing -->
29
+ <div class="stepper-item" data-phase="processing" data-active="true" aria-label="Phase: Processing (active)">
30
+ <div class="stepper-circle loading">
31
+ <div class="spinner"></div>
32
+ </div>
33
+ <span class="stepper-label">Processing</span>
34
+ </div>
35
+
36
+ <div class="stepper-connector"></div>
37
+
38
+ <!-- Phase 4: Complete -->
39
+ <div class="stepper-item" data-phase="complete" aria-label="Phase: Complete (pending)">
40
+ <div class="stepper-circle">4</div>
41
+ <span class="stepper-label">Complete</span>
42
+ </div>
43
+ </div>
44
+ </div>
45
+
46
+ <style scoped>
47
+ .execution-stepper {
48
+ padding: 20px;
49
+ background: var(--color-bg-primary);
50
+ }
51
+
52
+ .stepper-item {
53
+ display: flex;
54
+ flex-direction: column;
55
+ align-items: center;
56
+ flex: 1;
57
+ }
58
+
59
+ .stepper-circle {
60
+ width: 40px;
61
+ height: 40px;
62
+ border-radius: 50%;
63
+ display: flex;
64
+ align-items: center;
65
+ justify-content: center;
66
+ background-color: var(--color-bg-secondary);
67
+ color: var(--color-text-secondary);
68
+ font-weight: 600;
69
+ margin-bottom: 8px;
70
+ border: 2px solid var(--color-border);
71
+ }
72
+
73
+ .stepper-item[data-completed="true"] .stepper-circle {
74
+ background-color: var(--color-success);
75
+ color: white;
76
+ border-color: var(--color-success);
77
+ }
78
+
79
+ .stepper-item[data-active="true"] .stepper-circle {
80
+ background-color: var(--color-primary);
81
+ color: white;
82
+ border-color: var(--color-primary);
83
+ }
84
+
85
+ .stepper-circle.loading {
86
+ position: relative;
87
+ }
88
+
89
+ .spinner {
90
+ width: 20px;
91
+ height: 20px;
92
+ border: 2px solid transparent;
93
+ border-top-color: white;
94
+ border-right-color: white;
95
+ border-radius: 50%;
96
+ animation: spin 0.8s linear infinite;
97
+ }
98
+
99
+ @keyframes spin {
100
+ to { transform: rotate(360deg); }
101
+ }
102
+
103
+ .stepper-label {
104
+ font-size: 12px;
105
+ font-weight: 500;
106
+ text-align: center;
107
+ }
108
+
109
+ .stepper-connector {
110
+ flex: 1;
111
+ height: 2px;
112
+ background-color: var(--color-border);
113
+ margin: 0 10px;
114
+ margin-top: 20px;
115
+ }
116
+
117
+ .stepper-item[data-completed="true"] ~ .stepper-connector {
118
+ background-color: var(--color-success);
119
+ }
120
+ </style>
@@ -0,0 +1,118 @@
1
+ <!-- File Path Breadcrumb Navigation -->
2
+ <nav class="file-breadcrumb" role="navigation" aria-label="File path">
3
+ <ol class="breadcrumb-list" role="list">
4
+ <!-- Home -->
5
+ <li role="listitem">
6
+ <a href="/" class="breadcrumb-link" title="Home directory">
7
+ <svg class="w-3 h-3" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
8
+ <path d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z"/>
9
+ </svg>
10
+ <span class="sr-only">Home</span>
11
+ </a>
12
+ </li>
13
+
14
+ <!-- Path segments -->
15
+ <li role="listitem" class="breadcrumb-separator">/</li>
16
+
17
+ {{ for segment in pathSegments }}
18
+ <li role="listitem">
19
+ <a href="{{ segmentPath }}" class="breadcrumb-link" title="{{ segmentPath }}">
20
+ {{ segment }}
21
+ </a>
22
+ </li>
23
+ <li role="listitem" class="breadcrumb-separator">/</li>
24
+ {{ end }}
25
+
26
+ <!-- Current file -->
27
+ <li role="listitem" aria-current="page" class="breadcrumb-current">
28
+ <span class="breadcrumb-link" title="{{ currentFile }}">{{ currentFile }}</span>
29
+ </li>
30
+ </ol>
31
+
32
+ <!-- Copy path button -->
33
+ <button class="copy-path-btn" data-action="copy-path" aria-label="Copy file path" title="Copy full path to clipboard">
34
+ <svg class="w-3 h-3" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
35
+ <path d="M7 3a1 1 0 000 2h6a1 1 0 000-2H7zM4 7a1 1 0 011-1h10a1 1 0 011 1v10a2 2 0 01-2 2H6a2 2 0 01-2-2V7z"/>
36
+ </svg>
37
+ </button>
38
+ </nav>
39
+
40
+ <style scoped>
41
+ .file-breadcrumb {
42
+ display: flex;
43
+ align-items: center;
44
+ gap: 8px;
45
+ padding: 8px 0;
46
+ font-size: 13px;
47
+ overflow-x: auto;
48
+ }
49
+
50
+ .breadcrumb-list {
51
+ display: flex;
52
+ align-items: center;
53
+ gap: 4px;
54
+ list-style: none;
55
+ margin: 0;
56
+ padding: 0;
57
+ flex: 1;
58
+ min-width: 0;
59
+ }
60
+
61
+ .breadcrumb-link {
62
+ color: var(--color-primary);
63
+ text-decoration: none;
64
+ padding: 2px 4px;
65
+ border-radius: 2px;
66
+ transition: background-color 0.2s;
67
+ display: flex;
68
+ align-items: center;
69
+ gap: 2px;
70
+ white-space: nowrap;
71
+ }
72
+
73
+ .breadcrumb-link:hover {
74
+ background-color: var(--color-bg-hover);
75
+ }
76
+
77
+ .breadcrumb-current .breadcrumb-link {
78
+ color: var(--color-text-primary);
79
+ cursor: default;
80
+ }
81
+
82
+ .breadcrumb-current .breadcrumb-link:hover {
83
+ background-color: transparent;
84
+ }
85
+
86
+ .breadcrumb-separator {
87
+ color: var(--color-text-secondary);
88
+ margin: 0 -2px;
89
+ }
90
+
91
+ .copy-path-btn {
92
+ background: none;
93
+ border: 1px solid var(--color-border);
94
+ color: var(--color-text-secondary);
95
+ cursor: pointer;
96
+ padding: 4px 6px;
97
+ border-radius: 3px;
98
+ flex-shrink: 0;
99
+ transition: all 0.2s;
100
+ }
101
+
102
+ .copy-path-btn:hover {
103
+ border-color: var(--color-primary);
104
+ color: var(--color-primary);
105
+ }
106
+
107
+ .sr-only {
108
+ position: absolute;
109
+ width: 1px;
110
+ height: 1px;
111
+ padding: 0;
112
+ margin: -1px;
113
+ overflow: hidden;
114
+ clip: rect(0, 0, 0, 0);
115
+ white-space: nowrap;
116
+ border-width: 0;
117
+ }
118
+ </style>
@@ -0,0 +1,121 @@
1
+ <!-- File Diff Visualization Panel -->
2
+ <div class="file-diff-viewer card" role="region" aria-label="Code diff viewer">
3
+ <div class="card-header flex items-center justify-between mb-3 pb-3 border-b">
4
+ <h4 class="font-semibold">Changes in {{ fileName }}</h4>
5
+ <div class="flex gap-2">
6
+ <button class="btn-icon" data-view="unified" title="Unified diff view" aria-label="Show unified diff">
7
+ <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
8
+ <path d="M7 3a1 1 0 000 2h6a1 1 0 000-2H7zM4 7a1 1 0 011-1h10a1 1 0 011 1v6a2 2 0 01-2 2H6a2 2 0 01-2-2V7z"/>
9
+ </svg>
10
+ </button>
11
+ <button class="btn-icon" data-view="split" title="Side-by-side view" aria-label="Show side-by-side diff">
12
+ <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
13
+ <path d="M2 3a1 1 0 011-1h6a1 1 0 011 1v8a1 1 0 01-1 1H3a1 1 0 01-1-1V3zm10-1a1 1 0 011 1v8a1 1 0 01-1 1h-6a1 1 0 01-1-1v2a1 1 0 01-2 0V3a1 1 0 011-1h6z"/>
14
+ </svg>
15
+ </button>
16
+ </div>
17
+ </div>
18
+
19
+ <!-- Diff Statistics -->
20
+ <div class="diff-stats text-sm mb-3 pb-3 border-b flex gap-4">
21
+ <span class="text-green-600" aria-label="Lines added">
22
+ <span class="font-mono">+{{ linesAdded }}</span> added
23
+ </span>
24
+ <span class="text-red-600" aria-label="Lines removed">
25
+ <span class="font-mono">-{{ linesRemoved }}</span> removed
26
+ </span>
27
+ <span class="text-blue-600" aria-label="Total changes">
28
+ <span class="font-mono">{{ totalChanges }}</span> total
29
+ </span>
30
+ </div>
31
+
32
+ <!-- Unified Diff View -->
33
+ <pre class="diff-content" data-view="unified"><code>{{ unifiedDiff }}</code></pre>
34
+
35
+ <!-- Split Diff View (hidden) -->
36
+ <div class="split-view hidden" data-view="split" role="region" aria-label="Side-by-side diff view">
37
+ <div class="flex gap-2">
38
+ <div class="flex-1">
39
+ <div class="bg-red-50 border-b p-2 text-xs font-semibold">Original</div>
40
+ <pre class="diff-side left"><code>{{ diffLeft }}</code></pre>
41
+ </div>
42
+ <div class="flex-1">
43
+ <div class="bg-green-50 border-b p-2 text-xs font-semibold">Modified</div>
44
+ <pre class="diff-side right"><code>{{ diffRight }}</code></pre>
45
+ </div>
46
+ </div>
47
+ </div>
48
+
49
+ <!-- Diff Legend -->
50
+ <div class="diff-legend text-xs mt-3 pt-3 border-t space-y-1">
51
+ <div class="flex items-center gap-2">
52
+ <span class="w-2 h-2 rounded-full bg-green-500"></span>
53
+ <span>Added or modified</span>
54
+ </div>
55
+ <div class="flex items-center gap-2">
56
+ <span class="w-2 h-2 rounded-full bg-red-500"></span>
57
+ <span>Removed or replaced</span>
58
+ </div>
59
+ </div>
60
+ </div>
61
+
62
+ <style scoped>
63
+ .file-diff-viewer {
64
+ padding: 16px;
65
+ max-height: 600px;
66
+ overflow: auto;
67
+ }
68
+
69
+ .btn-icon {
70
+ background: none;
71
+ border: none;
72
+ color: var(--color-text-secondary);
73
+ cursor: pointer;
74
+ padding: 4px;
75
+ border-radius: 4px;
76
+ transition: all 0.2s;
77
+ }
78
+
79
+ .btn-icon:hover {
80
+ background-color: var(--color-bg-hover);
81
+ color: var(--color-primary);
82
+ }
83
+
84
+ .diff-stats {
85
+ display: flex;
86
+ gap: 16px;
87
+ }
88
+
89
+ .diff-content,
90
+ .diff-side {
91
+ background-color: var(--color-bg-code);
92
+ border: 1px solid var(--color-border);
93
+ border-radius: 4px;
94
+ padding: 12px;
95
+ font-size: 11px;
96
+ line-height: 1.6;
97
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
98
+ overflow-x: auto;
99
+ }
100
+
101
+ .split-view {
102
+ display: flex;
103
+ gap: 8px;
104
+ margin-top: 12px;
105
+ }
106
+
107
+ .diff-side {
108
+ flex: 1;
109
+ background-color: transparent;
110
+ border: none;
111
+ padding: 0;
112
+ }
113
+
114
+ .diff-legend {
115
+ padding-top: 12px;
116
+ }
117
+
118
+ .hidden {
119
+ display: none;
120
+ }
121
+ </style>
@@ -0,0 +1,133 @@
1
+ <!-- File Metadata Display -->
2
+ <div class="file-metadata" role="region" aria-label="File metadata">
3
+ <div class="metadata-grid">
4
+ <!-- Permissions -->
5
+ <div class="metadata-item">
6
+ <span class="metadata-label">Permissions</span>
7
+ <code class="metadata-value font-mono">{{ permissions }}</code>
8
+ </div>
9
+
10
+ <!-- Size -->
11
+ <div class="metadata-item">
12
+ <span class="metadata-label">Size</span>
13
+ <span class="metadata-value">{{ fileSize }} bytes</span>
14
+ </div>
15
+
16
+ <!-- Modified Date -->
17
+ <div class="metadata-item">
18
+ <span class="metadata-label">Modified</span>
19
+ <span class="metadata-value" title="{{ modifiedISO }}">{{ modifiedHuman }}</span>
20
+ </div>
21
+
22
+ <!-- Created Date -->
23
+ <div class="metadata-item">
24
+ <span class="metadata-label">Created</span>
25
+ <span class="metadata-value" title="{{ createdISO }}">{{ createdHuman }}</span>
26
+ </div>
27
+
28
+ <!-- Encoding -->
29
+ <div class="metadata-item">
30
+ <span class="metadata-label">Encoding</span>
31
+ <span class="metadata-value">{{ encoding }}</span>
32
+ </div>
33
+
34
+ <!-- Language -->
35
+ <div class="metadata-item">
36
+ <span class="metadata-label">Language</span>
37
+ <span class="metadata-value">{{ language }}</span>
38
+ </div>
39
+
40
+ <!-- Lines of Code -->
41
+ <div class="metadata-item">
42
+ <span class="metadata-label">Lines</span>
43
+ <span class="metadata-value">{{ lineCount }}</span>
44
+ </div>
45
+
46
+ <!-- Owner -->
47
+ <div class="metadata-item">
48
+ <span class="metadata-label">Owner</span>
49
+ <span class="metadata-value">{{ owner }}:{{ group }}</span>
50
+ </div>
51
+ </div>
52
+
53
+ <!-- Actions -->
54
+ <div class="metadata-actions mt-3 pt-3 border-t space-y-2">
55
+ <button class="metadata-action-btn" data-action="reveal-path" aria-label="Reveal in file explorer">
56
+ <svg class="w-3 h-3" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
57
+ <path d="M2 6a2 2 0 012-2h12a2 2 0 012 2v8a2 2 0 01-2 2H4a2 2 0 01-2-2V6zm4 2a1 1 0 100 2 1 1 0 000-2z"/>
58
+ </svg>
59
+ Show in Explorer
60
+ </button>
61
+ <button class="metadata-action-btn" data-action="copy-path" aria-label="Copy file path">
62
+ <svg class="w-3 h-3" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
63
+ <path d="M7 3a1 1 0 000 2h6a1 1 0 000-2H7zM4 7a1 1 0 011-1h10a1 1 0 011 1v10a2 2 0 01-2 2H6a2 2 0 01-2-2V7z"/>
64
+ </svg>
65
+ Copy Path
66
+ </button>
67
+ </div>
68
+ </div>
69
+
70
+ <style scoped>
71
+ .file-metadata {
72
+ padding: 12px;
73
+ background: var(--color-bg-secondary);
74
+ border-radius: 4px;
75
+ }
76
+
77
+ .metadata-grid {
78
+ display: grid;
79
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
80
+ gap: 12px;
81
+ }
82
+
83
+ .metadata-item {
84
+ display: flex;
85
+ flex-direction: column;
86
+ gap: 4px;
87
+ }
88
+
89
+ .metadata-label {
90
+ font-size: 11px;
91
+ font-weight: 600;
92
+ text-transform: uppercase;
93
+ color: var(--color-text-secondary);
94
+ letter-spacing: 0.5px;
95
+ }
96
+
97
+ .metadata-value {
98
+ font-size: 13px;
99
+ color: var(--color-text-primary);
100
+ word-break: break-word;
101
+ }
102
+
103
+ .font-mono {
104
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
105
+ }
106
+
107
+ .metadata-actions {
108
+ display: flex;
109
+ flex-direction: column;
110
+ gap: 8px;
111
+ }
112
+
113
+ .metadata-action-btn {
114
+ display: inline-flex;
115
+ align-items: center;
116
+ gap: 6px;
117
+ padding: 6px 10px;
118
+ background-color: var(--color-bg-primary);
119
+ border: 1px solid var(--color-border);
120
+ border-radius: 3px;
121
+ font-size: 12px;
122
+ cursor: pointer;
123
+ transition: all 0.2s;
124
+ width: 100%;
125
+ justify-content: flex-start;
126
+ }
127
+
128
+ .metadata-action-btn:hover {
129
+ background-color: var(--color-bg-hover);
130
+ border-color: var(--color-primary);
131
+ color: var(--color-primary);
132
+ }
133
+ </style>