gh-here 3.0.3 → 3.2.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 (47) hide show
  1. package/.env +0 -0
  2. package/lib/constants.js +21 -16
  3. package/lib/content-search.js +212 -0
  4. package/lib/error-handler.js +39 -28
  5. package/lib/file-utils.js +438 -287
  6. package/lib/git.js +11 -55
  7. package/lib/gitignore.js +70 -41
  8. package/lib/renderers.js +17 -33
  9. package/lib/server.js +73 -196
  10. package/lib/symbol-parser.js +600 -0
  11. package/package.json +1 -1
  12. package/public/app.js +135 -68
  13. package/public/css/components/buttons.css +423 -0
  14. package/public/css/components/forms.css +171 -0
  15. package/public/css/components/modals.css +286 -0
  16. package/public/css/components/notifications.css +36 -0
  17. package/public/css/file-table.css +318 -0
  18. package/public/css/file-tree.css +269 -0
  19. package/public/css/file-viewer.css +1259 -0
  20. package/public/css/layout.css +372 -0
  21. package/public/css/main.css +35 -0
  22. package/public/css/reset.css +64 -0
  23. package/public/css/search.css +694 -0
  24. package/public/css/symbol-outline.css +279 -0
  25. package/public/css/variables.css +135 -0
  26. package/public/js/constants.js +50 -34
  27. package/public/js/content-search-handler.js +551 -0
  28. package/public/js/file-viewer.js +437 -0
  29. package/public/js/focus-mode.js +280 -0
  30. package/public/js/inline-search.js +659 -0
  31. package/public/js/modal-manager.js +14 -28
  32. package/public/js/symbol-outline.js +454 -0
  33. package/public/js/utils.js +152 -94
  34. package/.claude/settings.local.json +0 -30
  35. package/SAMPLE.md +0 -287
  36. package/lib/validation.js +0 -77
  37. package/public/app.js.backup +0 -1902
  38. package/public/highlight.css +0 -121
  39. package/public/js/draft-manager.js +0 -36
  40. package/public/js/editor-manager.js +0 -159
  41. package/public/styles.css +0 -2727
  42. package/test.js +0 -138
  43. package/tests/draftManager.test.js +0 -241
  44. package/tests/fileTypeDetection.test.js +0 -111
  45. package/tests/httpService.test.js +0 -268
  46. package/tests/languageDetection.test.js +0 -145
  47. package/tests/pathUtils.test.js +0 -136
@@ -0,0 +1,279 @@
1
+ /**
2
+ * Symbol Outline Panel Styles
3
+ * Code navigation panel showing functions, classes, methods
4
+ */
5
+
6
+ /* ========================================
7
+ Symbol Outline Button
8
+ ======================================== */
9
+
10
+ .symbol-outline-btn {
11
+ position: relative;
12
+ }
13
+
14
+ .symbol-outline-btn.active {
15
+ background: var(--hover-bg);
16
+ color: var(--link-color);
17
+ }
18
+
19
+ /* ========================================
20
+ Symbol Outline Panel
21
+ ======================================== */
22
+
23
+ .symbol-outline-panel {
24
+ background: var(--bg-card);
25
+ border: 1px solid var(--border-subtle);
26
+ border-radius: var(--radius-lg);
27
+ box-shadow: var(--shadow-xl);
28
+ display: none;
29
+ flex-direction: column;
30
+ max-height: 400px;
31
+ overflow: hidden;
32
+ position: fixed;
33
+ width: 300px;
34
+ z-index: 99999;
35
+ }
36
+
37
+ .symbol-outline-panel.open {
38
+ display: flex;
39
+ }
40
+
41
+ /* ========================================
42
+ Panel Header
43
+ ======================================== */
44
+
45
+ .symbol-outline-header {
46
+ align-items: center;
47
+ background: var(--bg-secondary);
48
+ border-bottom: 1px solid var(--border-subtle);
49
+ display: flex;
50
+ justify-content: space-between;
51
+ padding: 12px 16px;
52
+ }
53
+
54
+ .symbol-outline-title {
55
+ color: var(--text-primary);
56
+ font-size: 13px;
57
+ font-weight: 600;
58
+ }
59
+
60
+ .symbol-outline-count {
61
+ color: var(--text-muted);
62
+ font-size: 12px;
63
+ }
64
+
65
+ /* ========================================
66
+ Panel Search
67
+ ======================================== */
68
+
69
+ .symbol-outline-search {
70
+ border-bottom: 1px solid var(--border-subtle);
71
+ padding: 8px 12px;
72
+ }
73
+
74
+ .symbol-search-input {
75
+ background: var(--bg-primary);
76
+ border: 1px solid var(--border-subtle);
77
+ border-radius: var(--radius-md);
78
+ color: var(--text-primary);
79
+ font-size: 13px;
80
+ outline: none;
81
+ padding: 8px 12px;
82
+ transition: border-color var(--transition-base);
83
+ width: 100%;
84
+ }
85
+
86
+ .symbol-search-input:focus {
87
+ border-color: var(--link-color);
88
+ }
89
+
90
+ .symbol-search-input::placeholder {
91
+ color: var(--text-muted);
92
+ }
93
+
94
+ /* ========================================
95
+ Panel Content
96
+ ======================================== */
97
+
98
+ .symbol-outline-content {
99
+ flex: 1;
100
+ overflow-y: auto;
101
+ padding: 8px 0;
102
+ }
103
+
104
+ .symbol-outline-loading,
105
+ .symbol-outline-empty,
106
+ .symbol-outline-error {
107
+ color: var(--text-muted);
108
+ font-size: 13px;
109
+ padding: 24px 16px;
110
+ text-align: center;
111
+ }
112
+
113
+ .symbol-outline-error {
114
+ color: var(--text-danger, #f87171);
115
+ }
116
+
117
+ /* ========================================
118
+ Symbol Groups
119
+ ======================================== */
120
+
121
+ .symbol-group {
122
+ margin-bottom: 4px;
123
+ }
124
+
125
+ .symbol-group-header {
126
+ align-items: center;
127
+ color: var(--text-muted);
128
+ display: flex;
129
+ font-size: 11px;
130
+ font-weight: 600;
131
+ justify-content: space-between;
132
+ letter-spacing: 0.5px;
133
+ padding: 6px 16px;
134
+ text-transform: uppercase;
135
+ }
136
+
137
+ .symbol-group-count {
138
+ color: var(--text-muted);
139
+ font-weight: 400;
140
+ opacity: 0.7;
141
+ }
142
+
143
+ .symbol-group-items {
144
+ display: flex;
145
+ flex-direction: column;
146
+ }
147
+
148
+ /* ========================================
149
+ Symbol Items
150
+ ======================================== */
151
+
152
+ .symbol-item {
153
+ align-items: center;
154
+ cursor: pointer;
155
+ display: flex;
156
+ gap: 8px;
157
+ padding: 6px 16px;
158
+ transition: background var(--transition-fast);
159
+ }
160
+
161
+ .symbol-item:hover {
162
+ background: rgba(96, 165, 250, 0.08);
163
+ border-left: 2px solid var(--link-color);
164
+ padding-left: 14px;
165
+ }
166
+
167
+ .symbol-item.selected {
168
+ background: rgba(96, 165, 250, 0.15);
169
+ border-left: 2px solid var(--link-color);
170
+ padding-left: 14px;
171
+ }
172
+
173
+ /* ========================================
174
+ Symbol Icon
175
+ ======================================== */
176
+
177
+ .symbol-icon {
178
+ align-items: center;
179
+ border-radius: 3px;
180
+ display: flex;
181
+ flex-shrink: 0;
182
+ font-family: ui-monospace, monospace;
183
+ font-size: 10px;
184
+ font-weight: 700;
185
+ height: 18px;
186
+ justify-content: center;
187
+ width: 18px;
188
+ }
189
+
190
+ /* Function/Method icons */
191
+ .symbol-icon-function,
192
+ .symbol-icon-method {
193
+ background: rgba(139, 92, 246, 0.2);
194
+ color: #a78bfa;
195
+ }
196
+
197
+ /* Class icons */
198
+ .symbol-icon-class {
199
+ background: rgba(251, 191, 36, 0.2);
200
+ color: #fbbf24;
201
+ }
202
+
203
+ /* Interface/Type icons */
204
+ .symbol-icon-interface,
205
+ .symbol-icon-type {
206
+ background: rgba(34, 211, 238, 0.2);
207
+ color: #22d3ee;
208
+ }
209
+
210
+ /* Constant/Variable icons */
211
+ .symbol-icon-constant,
212
+ .symbol-icon-variable {
213
+ background: rgba(74, 222, 128, 0.2);
214
+ color: #4ade80;
215
+ }
216
+
217
+ /* CSS-specific icons */
218
+ .symbol-icon-selector,
219
+ .symbol-icon-mixin,
220
+ .symbol-icon-keyframes,
221
+ .symbol-icon-media {
222
+ background: rgba(251, 113, 133, 0.2);
223
+ color: #fb7185;
224
+ }
225
+
226
+ /* ========================================
227
+ Symbol Name & Line
228
+ ======================================== */
229
+
230
+ .symbol-name {
231
+ color: var(--text-primary);
232
+ flex: 1;
233
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
234
+ font-size: 13px;
235
+ overflow: hidden;
236
+ text-overflow: ellipsis;
237
+ white-space: nowrap;
238
+ }
239
+
240
+ .symbol-line {
241
+ color: var(--text-muted);
242
+ font-family: ui-monospace, monospace;
243
+ font-size: 11px;
244
+ }
245
+
246
+ /* ========================================
247
+ Light Theme Adjustments
248
+ ======================================== */
249
+
250
+ [data-theme="light"] .symbol-icon-function,
251
+ [data-theme="light"] .symbol-icon-method {
252
+ background: rgba(139, 92, 246, 0.15);
253
+ color: #7c3aed;
254
+ }
255
+
256
+ [data-theme="light"] .symbol-icon-class {
257
+ background: rgba(217, 119, 6, 0.15);
258
+ color: #b45309;
259
+ }
260
+
261
+ [data-theme="light"] .symbol-icon-interface,
262
+ [data-theme="light"] .symbol-icon-type {
263
+ background: rgba(6, 182, 212, 0.15);
264
+ color: #0891b2;
265
+ }
266
+
267
+ [data-theme="light"] .symbol-icon-constant,
268
+ [data-theme="light"] .symbol-icon-variable {
269
+ background: rgba(22, 163, 74, 0.15);
270
+ color: #16a34a;
271
+ }
272
+
273
+ [data-theme="light"] .symbol-icon-selector,
274
+ [data-theme="light"] .symbol-icon-mixin,
275
+ [data-theme="light"] .symbol-icon-keyframes,
276
+ [data-theme="light"] .symbol-icon-media {
277
+ background: rgba(225, 29, 72, 0.15);
278
+ color: #be123c;
279
+ }
@@ -0,0 +1,135 @@
1
+ /**
2
+ * CSS Custom Properties (Variables)
3
+ * Theme colors, shadows, transitions, spacing, and border radius
4
+ */
5
+
6
+ :root {
7
+ /* Background colors - Dark theme */
8
+ --bg-card: #161b22;
9
+ --bg-elevated: #1f252d;
10
+ --bg-primary: #0a0e14;
11
+ --bg-secondary: #13171d;
12
+ --bg-tertiary: #1a1f26;
13
+
14
+ /* Border colors */
15
+ --border-primary: #2d333b;
16
+ --border-secondary: #21262d;
17
+ --border-subtle: #1c2128;
18
+
19
+ /* Text colors */
20
+ --text-accent: #f8fafc;
21
+ --text-primary: #eef2f6;
22
+ --text-secondary: #9ca3af;
23
+ --text-tertiary: #6b7280;
24
+
25
+ /* Link colors */
26
+ --link-color: #60a5fa;
27
+ --link-hover: #93c5fd;
28
+
29
+ /* Hover backgrounds */
30
+ --hover-bg: #1e242b;
31
+ --hover-bg-strong: #252b33;
32
+
33
+ /* Accent colors for status */
34
+ --accent-error: #ef4444;
35
+ --accent-info: #3b82f6;
36
+ --accent-success: #10b981;
37
+ --accent-warning: #f59e0b;
38
+
39
+ /* Shadows - Enhanced depth system */
40
+ --shadow-2xl: 0 24px 64px rgba(0, 0, 0, 0.3);
41
+ --shadow-glow: 0 0 20px rgba(96, 165, 250, 0.15);
42
+ --shadow-inner: inset 0 1px 2px rgba(0, 0, 0, 0.1);
43
+ --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.2);
44
+ --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.15);
45
+ --shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.1);
46
+ --shadow-xl: 0 16px 48px rgba(0, 0, 0, 0.25);
47
+ --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.05);
48
+
49
+ /* Transitions - Refined timing */
50
+ --transition-base: 200ms cubic-bezier(0.4, 0, 0.2, 1);
51
+ --transition-bounce: 400ms cubic-bezier(0.68, -0.55, 0.265, 1.55);
52
+ --transition-fast: 120ms cubic-bezier(0.4, 0, 0.2, 1);
53
+ --transition-slow: 350ms cubic-bezier(0.4, 0, 0.2, 1);
54
+
55
+ /* Border radius */
56
+ --radius-2xl: 20px;
57
+ --radius-full: 9999px;
58
+ --radius-lg: 12px;
59
+ --radius-md: 8px;
60
+ --radius-sm: 6px;
61
+ --radius-xl: 16px;
62
+ --radius-xs: 3px;
63
+
64
+ /* Spacing scale */
65
+ --space-2xl: 48px;
66
+ --space-3xl: 64px;
67
+ --space-lg: 24px;
68
+ --space-md: 16px;
69
+ --space-sm: 8px;
70
+ --space-xl: 32px;
71
+ --space-xs: 4px;
72
+
73
+ /* Syntax highlighting colors - Dark theme */
74
+ --hljs-builtin: #ffa657;
75
+ --hljs-comment: #8b949e;
76
+ --hljs-function: #d2a8ff;
77
+ --hljs-keyword: #ff7b72;
78
+ --hljs-number: #79c0ff;
79
+ --hljs-string: #a5d6ff;
80
+ --hljs-tag: #7ee787;
81
+ }
82
+
83
+ /* Light Theme */
84
+ [data-theme="light"] {
85
+ /* Background colors */
86
+ --bg-card: #ffffff;
87
+ --bg-elevated: #ffffff;
88
+ --bg-primary: #ffffff;
89
+ --bg-secondary: #f8fafc;
90
+ --bg-tertiary: #f1f5f9;
91
+
92
+ /* Border colors */
93
+ --border-primary: #e2e8f0;
94
+ --border-secondary: #cbd5e1;
95
+ --border-subtle: #e2e8f0;
96
+
97
+ /* Text colors */
98
+ --text-accent: #020617;
99
+ --text-primary: #0f172a;
100
+ --text-secondary: #64748b;
101
+ --text-tertiary: #94a3b8;
102
+
103
+ /* Link colors */
104
+ --link-color: #2563eb;
105
+ --link-hover: #1d4ed8;
106
+
107
+ /* Hover backgrounds */
108
+ --hover-bg: #f1f5f9;
109
+ --hover-bg-strong: #e2e8f0;
110
+
111
+ /* Accent colors */
112
+ --accent-error: #dc2626;
113
+ --accent-info: #2563eb;
114
+ --accent-success: #059669;
115
+ --accent-warning: #d97706;
116
+
117
+ /* Shadows - Softer for light theme */
118
+ --shadow-2xl: 0 24px 64px rgba(0, 0, 0, 0.15);
119
+ --shadow-glow: 0 0 20px rgba(37, 99, 235, 0.1);
120
+ --shadow-inner: inset 0 1px 2px rgba(0, 0, 0, 0.03);
121
+ --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.1);
122
+ --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);
123
+ --shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.05);
124
+ --shadow-xl: 0 16px 48px rgba(0, 0, 0, 0.12);
125
+ --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.03);
126
+
127
+ /* Syntax highlighting colors - Light theme */
128
+ --hljs-builtin: #e36209;
129
+ --hljs-comment: #6f42c1;
130
+ --hljs-function: #6f42c1;
131
+ --hljs-keyword: #d73a49;
132
+ --hljs-number: #005cc5;
133
+ --hljs-string: #032f62;
134
+ --hljs-tag: #22863a;
135
+ }
@@ -1,60 +1,76 @@
1
1
  /**
2
2
  * Application constants and configuration
3
+ * @module constants
3
4
  */
4
5
 
6
+ // ============================================================================
7
+ // Configuration
8
+ // ============================================================================
9
+
5
10
  export const CONFIG = {
6
- MONACO_CDN: 'https://unpkg.com/monaco-editor@0.45.0/min/vs',
7
- MONACO_VERSION: '0.45.0',
8
- EDITOR_HEIGHT: 600,
9
11
  DEFAULT_PORT: 5555,
12
+ MONACO_CDN: 'https://unpkg.com/monaco-editor@0.45.0/min/vs',
10
13
  NOTIFICATION_DURATION: 4000
11
14
  };
12
15
 
16
+ // ============================================================================
17
+ // Enums
18
+ // ============================================================================
19
+
13
20
  export const THEME = {
14
21
  DARK: 'dark',
15
22
  LIGHT: 'light'
16
23
  };
17
24
 
25
+ // ============================================================================
26
+ // Storage Keys
27
+ // ============================================================================
28
+
18
29
  export const STORAGE_KEYS = {
19
- THEME: 'gh-here-theme',
20
- DRAFT_PREFIX: 'gh-here-draft-'
30
+ THEME: 'gh-here-theme'
21
31
  };
22
32
 
33
+ // ============================================================================
34
+ // Keyboard Shortcuts (alpha-sorted)
35
+ // ============================================================================
36
+
37
+ export const KEYBOARD_SHORTCUTS = {
38
+ ESCAPE: 'Escape',
39
+ GO_UP: 'h',
40
+ HELP: '?',
41
+ NAV_DOWN: 'j',
42
+ NAV_UP: 'k',
43
+ OPEN: 'o',
44
+ REFRESH: 'r',
45
+ SEARCH: ['/', 's'],
46
+ SHOW_DIFF: 'd',
47
+ THEME_TOGGLE: 't',
48
+ TOGGLE_GITIGNORE: 'i'
49
+ };
50
+
51
+ // ============================================================================
52
+ // Monaco Editor Options (for FileViewer read-only mode)
53
+ // ============================================================================
54
+
23
55
  export const EDITOR_OPTIONS = {
24
- minimap: { enabled: false },
25
- lineNumbers: 'on',
26
- wordWrap: 'off',
27
- scrollBeyondLastLine: false,
28
- fontSize: 12,
29
- lineHeight: 20,
30
- fontFamily: "ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace",
31
- padding: { top: 16, bottom: 16 },
32
- renderLineHighlight: 'line',
33
- selectOnLineNumbers: true,
34
56
  automaticLayout: true,
57
+ bracketPairColorization: { enabled: true },
35
58
  folding: true,
36
59
  foldingHighlight: true,
37
60
  foldingStrategy: 'auto',
38
- showFoldingControls: 'mouseover',
39
- bracketPairColorization: { enabled: true },
61
+ fontFamily: "ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace",
62
+ fontSize: 12,
40
63
  guides: {
41
64
  bracketPairs: true,
42
65
  indentation: true
43
- }
44
- };
45
-
46
- export const KEYBOARD_SHORTCUTS = {
47
- SEARCH: ['/', 's'],
48
- THEME_TOGGLE: 't',
49
- HELP: '?',
50
- ESCAPE: 'Escape',
51
- GO_UP: 'h',
52
- REFRESH: 'r',
53
- CREATE_FILE: 'c',
54
- EDIT_FILE: 'e',
55
- SHOW_DIFF: 'd',
56
- TOGGLE_GITIGNORE: 'i',
57
- NAV_DOWN: 'j',
58
- NAV_UP: 'k',
59
- OPEN: 'o'
66
+ },
67
+ lineHeight: 20,
68
+ lineNumbers: 'on',
69
+ minimap: { enabled: false },
70
+ padding: { top: 16, bottom: 16 },
71
+ renderLineHighlight: 'line',
72
+ scrollBeyondLastLine: false,
73
+ selectOnLineNumbers: true,
74
+ showFoldingControls: 'mouseover',
75
+ wordWrap: 'off'
60
76
  };