claude-code-runner 0.1.0 → 0.1.2

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.
@@ -0,0 +1,660 @@
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>Claude Code Runner - Terminal</title>
7
+ <link rel="stylesheet" href="https://unpkg.com/xterm@5.3.0/css/xterm.css" />
8
+ <style>
9
+ * {
10
+ margin: 0;
11
+ padding: 0;
12
+ box-sizing: border-box;
13
+ }
14
+
15
+ body {
16
+ font-family:
17
+ -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu,
18
+ Cantarell, sans-serif;
19
+ background-color: #1e1e1e;
20
+ color: #d4d4d4;
21
+ height: 100vh;
22
+ display: flex;
23
+ flex-direction: column;
24
+ }
25
+
26
+ .header {
27
+ background-color: #2d2d2d;
28
+ padding: 1rem;
29
+ border-bottom: 1px solid #3e3e3e;
30
+ display: flex;
31
+ align-items: center;
32
+ justify-content: space-between;
33
+ }
34
+
35
+ .header h1 {
36
+ font-size: 1.25rem;
37
+ font-weight: 500;
38
+ color: #ffffff;
39
+ display: flex;
40
+ align-items: center;
41
+ gap: 0.5rem;
42
+ }
43
+
44
+ .status {
45
+ display: flex;
46
+ align-items: center;
47
+ gap: 0.5rem;
48
+ font-size: 0.875rem;
49
+ }
50
+
51
+ .status-indicator {
52
+ width: 8px;
53
+ height: 8px;
54
+ border-radius: 50%;
55
+ background-color: #4c4c4c;
56
+ }
57
+
58
+ .status-indicator.connected {
59
+ background-color: #4caf50;
60
+ }
61
+
62
+ .status-indicator.connecting {
63
+ background-color: #ff9800;
64
+ animation: pulse 1.5s infinite;
65
+ }
66
+
67
+ .status-indicator.error {
68
+ background-color: #f44336;
69
+ }
70
+
71
+ @keyframes pulse {
72
+ 0% {
73
+ opacity: 1;
74
+ }
75
+ 50% {
76
+ opacity: 0.5;
77
+ }
78
+ 100% {
79
+ opacity: 1;
80
+ }
81
+ }
82
+
83
+ .terminal-container {
84
+ flex: 1;
85
+ padding: 1rem;
86
+ overflow: hidden;
87
+ }
88
+
89
+ #terminal {
90
+ height: 100%;
91
+ background-color: #1e1e1e;
92
+ }
93
+
94
+ .controls {
95
+ background-color: #2d2d2d;
96
+ padding: 0.75rem 1rem;
97
+ border-top: 1px solid #3e3e3e;
98
+ display: flex;
99
+ gap: 0.5rem;
100
+ font-size: 0.875rem;
101
+ }
102
+
103
+ .controls button {
104
+ background-color: #3c3c3c;
105
+ color: #cccccc;
106
+ border: 1px solid #4c4c4c;
107
+ padding: 0.5rem 1rem;
108
+ border-radius: 4px;
109
+ cursor: pointer;
110
+ font-size: 0.875rem;
111
+ transition: all 0.2s;
112
+ }
113
+
114
+ .controls button:hover {
115
+ background-color: #4c4c4c;
116
+ border-color: #5c5c5c;
117
+ }
118
+
119
+ .controls button:active {
120
+ background-color: #3c3c3c;
121
+ }
122
+
123
+ .controls label {
124
+ color: #cccccc;
125
+ font-size: 0.875rem;
126
+ cursor: pointer;
127
+ user-select: none;
128
+ }
129
+
130
+ .controls input[type="checkbox"] {
131
+ cursor: pointer;
132
+ }
133
+
134
+ .info {
135
+ background-color: #364152;
136
+ border: 1px solid #4c5c74;
137
+ border-radius: 4px;
138
+ padding: 1rem;
139
+ margin: 1rem;
140
+ font-size: 0.875rem;
141
+ line-height: 1.5;
142
+ }
143
+
144
+ .info code {
145
+ background-color: #2d3748;
146
+ padding: 0.125rem 0.25rem;
147
+ border-radius: 3px;
148
+ font-family: "Consolas", "Monaco", "Courier New", monospace;
149
+ }
150
+
151
+ .error-message {
152
+ background-color: #4a1e1e;
153
+ border: 1px solid #6a2e2e;
154
+ color: #ffcccc;
155
+ border-radius: 4px;
156
+ padding: 1rem;
157
+ margin: 1rem;
158
+ font-size: 0.875rem;
159
+ }
160
+
161
+ .loading {
162
+ position: absolute;
163
+ top: 50%;
164
+ left: 50%;
165
+ transform: translate(-50%, -50%);
166
+ text-align: center;
167
+ }
168
+
169
+ .loading-spinner {
170
+ border: 3px solid #3c3c3c;
171
+ border-top: 3px solid #ffffff;
172
+ border-radius: 50%;
173
+ width: 40px;
174
+ height: 40px;
175
+ animation: spin 1s linear infinite;
176
+ margin: 0 auto 1rem;
177
+ }
178
+
179
+ @keyframes spin {
180
+ 0% {
181
+ transform: rotate(0deg);
182
+ }
183
+ 100% {
184
+ transform: rotate(360deg);
185
+ }
186
+ }
187
+
188
+ /* Input needed state */
189
+ body.input-needed .header {
190
+ background-color: #4a3526;
191
+ border-bottom-color: #ff8c42;
192
+ transition: all 0.3s ease;
193
+ }
194
+
195
+ /* Tab system */
196
+ .tabs {
197
+ background-color: #2d2d2d;
198
+ border-bottom: 1px solid #3e3e3e;
199
+ display: flex;
200
+ align-items: center;
201
+ padding: 0 1rem;
202
+ }
203
+
204
+ .tab {
205
+ background-color: transparent;
206
+ border: none;
207
+ color: #cccccc;
208
+ padding: 0.75rem 1.5rem;
209
+ cursor: pointer;
210
+ font-size: 0.875rem;
211
+ font-weight: 500;
212
+ border-bottom: 2px solid transparent;
213
+ transition: all 0.2s;
214
+ position: relative;
215
+ }
216
+
217
+ .tab:hover {
218
+ color: #ffffff;
219
+ background-color: #3c3c3c;
220
+ }
221
+
222
+ .tab.active {
223
+ color: #ffffff;
224
+ border-bottom-color: #4caf50;
225
+ background-color: #1e1e1e;
226
+ }
227
+
228
+ .tab .file-count-badge {
229
+ display: inline-block;
230
+ margin-left: 8px;
231
+ padding: 2px 6px;
232
+ font-size: 11px;
233
+ font-weight: 600;
234
+ line-height: 1;
235
+ color: #fff;
236
+ background-color: #1f6feb;
237
+ border-radius: 10px;
238
+ min-width: 20px;
239
+ text-align: center;
240
+ }
241
+
242
+ .tab-content {
243
+ flex: 1;
244
+ display: none;
245
+ flex-direction: column;
246
+ overflow: hidden;
247
+ }
248
+
249
+ .tab-content.active {
250
+ display: flex;
251
+ }
252
+
253
+ .changes-view {
254
+ flex: 1;
255
+ display: flex;
256
+ flex-direction: column;
257
+ overflow: hidden;
258
+ }
259
+
260
+ .changes-header {
261
+ background-color: #2d2d2d;
262
+ padding: 1rem;
263
+ border-bottom: 1px solid #3e3e3e;
264
+ }
265
+
266
+ .changes-summary {
267
+ background: #2d2d2d;
268
+ padding: 15px;
269
+ border-radius: 6px;
270
+ margin-bottom: 20px;
271
+ border-left: 4px solid #4caf50;
272
+ color: #e6edf3;
273
+ }
274
+
275
+ .diff-stats {
276
+ margin-top: 8px;
277
+ font-size: 0.875rem;
278
+ color: #7d8590;
279
+ font-family: "SF Mono", Consolas, "Liberation Mono", Menlo, monospace;
280
+ }
281
+
282
+ .changes-content {
283
+ flex: 1;
284
+ display: flex;
285
+ flex-direction: column;
286
+ overflow: hidden;
287
+ padding: 1rem;
288
+ }
289
+
290
+ .diff-viewer {
291
+ background: #0d1117;
292
+ border: 1px solid #30363d;
293
+ border-radius: 6px;
294
+ padding: 15px;
295
+ margin-bottom: 20px;
296
+ font-family: "SF Mono", Consolas, "Liberation Mono", Menlo, monospace;
297
+ font-size: 13px;
298
+ line-height: 1.45;
299
+ overflow-x: auto;
300
+ flex: 1;
301
+ overflow-y: auto;
302
+ }
303
+
304
+ .diff-line {
305
+ padding: 2px 0;
306
+ white-space: pre;
307
+ }
308
+
309
+ .diff-line.added {
310
+ background: rgba(46, 160, 67, 0.15);
311
+ color: #3fb950;
312
+ }
313
+
314
+ .diff-line.removed {
315
+ background: rgba(248, 81, 73, 0.15);
316
+ color: #f85149;
317
+ }
318
+
319
+ .diff-line.context {
320
+ color: #e6edf3;
321
+ }
322
+
323
+ .diff-line.header {
324
+ color: #7d8590;
325
+ font-weight: bold;
326
+ }
327
+
328
+ .git-actions {
329
+ background: #2d2d2d;
330
+ padding: 20px;
331
+ border-radius: 6px;
332
+ margin-bottom: 15px;
333
+ }
334
+
335
+ .git-actions h3 {
336
+ margin: 0 0 15px 0;
337
+ color: #fff;
338
+ }
339
+
340
+ #commit-message {
341
+ width: 100%;
342
+ background: #0d1117;
343
+ border: 1px solid #30363d;
344
+ border-radius: 6px;
345
+ padding: 12px;
346
+ color: #e6edf3;
347
+ font-family: "SF Mono", Consolas, "Liberation Mono", Menlo, monospace;
348
+ font-size: 14px;
349
+ resize: vertical;
350
+ margin-bottom: 15px;
351
+ }
352
+
353
+ .branch-input {
354
+ margin-bottom: 15px;
355
+ }
356
+
357
+ .branch-input label {
358
+ display: block;
359
+ margin-bottom: 5px;
360
+ color: #e6edf3;
361
+ }
362
+
363
+ #branch-name {
364
+ width: 200px;
365
+ background: #0d1117;
366
+ border: 1px solid #30363d;
367
+ border-radius: 6px;
368
+ padding: 8px 12px;
369
+ color: #e6edf3;
370
+ font-family: "SF Mono", Consolas, "Liberation Mono", Menlo, monospace;
371
+ }
372
+
373
+ .btn {
374
+ background: #238636;
375
+ color: white;
376
+ border: none;
377
+ padding: 8px 16px;
378
+ border-radius: 6px;
379
+ cursor: pointer;
380
+ font-size: 14px;
381
+ font-weight: 500;
382
+ margin-right: 10px;
383
+ }
384
+
385
+ .btn:hover {
386
+ background: #2ea043;
387
+ }
388
+
389
+ .btn:disabled {
390
+ background: #484f58;
391
+ cursor: not-allowed;
392
+ }
393
+
394
+ .btn-primary {
395
+ background: #1f6feb;
396
+ }
397
+
398
+ .btn-primary:hover {
399
+ background: #388bfd;
400
+ }
401
+
402
+ .btn-success {
403
+ background: #238636;
404
+ }
405
+
406
+ .btn-success:hover {
407
+ background: #2ea043;
408
+ }
409
+
410
+ .empty-state {
411
+ text-align: center;
412
+ padding: 4rem 2rem;
413
+ color: #7d8590;
414
+ }
415
+
416
+ .empty-state h3 {
417
+ margin-bottom: 1rem;
418
+ font-size: 1.1rem;
419
+ }
420
+
421
+ /* Git info styles */
422
+ .git-info {
423
+ color: #7d8590;
424
+ font-size: 0.875rem;
425
+ }
426
+
427
+ .pr-badge {
428
+ display: inline-block;
429
+ padding: 2px 6px;
430
+ font-size: 12px;
431
+ font-weight: 500;
432
+ line-height: 1;
433
+ border-radius: 3px;
434
+ text-decoration: none;
435
+ margin-left: 4px;
436
+ }
437
+
438
+ .pr-badge.open {
439
+ background-color: #2ea043;
440
+ color: white;
441
+ }
442
+
443
+ .pr-badge.draft {
444
+ background-color: #6e7681;
445
+ color: white;
446
+ }
447
+
448
+ .pr-badge.closed {
449
+ background-color: #8250df;
450
+ color: white;
451
+ }
452
+
453
+ .pr-badge.merged {
454
+ background-color: #8250df;
455
+ color: white;
456
+ }
457
+
458
+ .pr-badge:hover {
459
+ opacity: 0.8;
460
+ }
461
+
462
+ /* Language selector styles */
463
+ .language-selector-wrapper {
464
+ display: flex;
465
+ align-items: center;
466
+ gap: 0.5rem;
467
+ margin-right: 1rem;
468
+ padding-right: 1rem;
469
+ border-right: 1px solid #3e3e3e;
470
+ }
471
+
472
+ .language-selector-wrapper svg {
473
+ color: #7d8590;
474
+ }
475
+
476
+ #language-selector {
477
+ background-color: #3c3c3c;
478
+ color: #cccccc;
479
+ border: 1px solid #4c4c4c;
480
+ padding: 0.25rem 0.5rem;
481
+ border-radius: 4px;
482
+ font-size: 0.75rem;
483
+ cursor: pointer;
484
+ outline: none;
485
+ }
486
+
487
+ #language-selector:hover {
488
+ background-color: #4c4c4c;
489
+ border-color: #5c5c5c;
490
+ }
491
+
492
+ #language-selector:focus {
493
+ border-color: #4caf50;
494
+ }
495
+ </style>
496
+ </head>
497
+ <body>
498
+ <!-- Hidden audio element for fallback sound -->
499
+ <audio id="notification-sound" style="display: none">
500
+ <source
501
+ src="data:audio/wav;base64,UklGRnoGAABXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YQoGAACBhYqFbF1fdJivrJBhNjVgodDbq2EcBj+a2/LDciUFLIHO8tiJNwgZaLvt559NEAxQp+PwtmMcBjiR1/LMeSwFJHfH8N2QQAoUXrTp66hVFApGn+DyvmwhBCx+zPLZhjEGHWm98OScTgwOUrHx1ZdVDwpGn+DyvmwhBCx+zPLZhjEGHWm98OScTgwOUrHx1ZdVDwpGn+DyvmwhBCx+zPLZhjEGHWm98OScTgwOUrHx1ZdVDwpGn+DyvmwhBCx+zPLZhjEGHWm98OScTgwOUrHx1ZdVDwpGn+DyvmwhBCx+zPLZhjEGHWm98OScTgwOUrHx1ZdVDwpGn+DyvmwhBCx+zPLZhjEGHWm98OScTgwOUrHx1ZdVDwpGn+DyvmwhBCx+zPLZhjEGHWm98OScTgwOUrHx1ZdVDwpGn+DyvmwhBCx+zPLZhjEGHWm98OScTgwOUrHx1ZdVDwpGn+DyvmwhBCx+zPLZhjEGHWm98OScTgwOUrHx1ZdVDwpGn+DyvmwhBCx+zPLZhjEGHWm98OScTgwOUrHx1ZdVDwpGn+DyvmwhBCx+zPLZhjEGHWm98OScTgwOUrHx1ZdVDwpGn+DyvmwhBCx+zPLZhjEGHWm98OScTgwOUrHx1ZdVDwpGn+DyvmwhBCx+zPLZhjEGHWm98OScTgwOUrHx1ZdVDwr2hYmbe9FmXQY1Waj48noCAiaMr+xuQQEfcd/04FkGEly1+O18CgEiirLyalQDG3DY9ONfCBJZtPfvfgwCIYiw8m1aDBtu1fTiYwsVXLT47nkJAiKHrvJvXg0abtX04mMLFVy0+O55CQIih67yb14NGm7V9OJjCxVctPjueQkCIoeu8m9eDRpu1fTiYwsVXLT47nkJAiKHrvJvXg0abtX04mMLFVy0+O55CQIih67yb14NGm7V9OJjCxVctPjueQkCIoeu8m9eDRpu1fTiYwsVXLT47nkJAiKHrvJvXg0abtX04mMLFVy0+O55CQIih67yb14NGm7V9OJjCxVctPjueQkCIoeu8m9eDRpu1fTiYwsVXLT47nkJAiKHrvJvXg0abtX04mMLFVy0+O55CQIih67yb14NGm7V9OJjCxVctPjueQkCIoeu8m9eDRpu1fTiYwsVXLT47nkJAiKHrvJvXg0abtX04mMLFVy0+O55CQIih67yb14NGm7V9OJjCxVctPjueQkCIoeu8m9eDRpu1fTiYwsVXLT47nkJAiKHrvJvXg0abtX04mMLFVy0+O55CQIih67yb14NGgA="
502
+ preload="auto"
503
+ />
504
+ </audio>
505
+ <div class="header">
506
+ <h1>
507
+ <svg
508
+ width="20"
509
+ height="20"
510
+ viewBox="0 0 24 24"
511
+ fill="none"
512
+ stroke="currentColor"
513
+ stroke-width="2"
514
+ >
515
+ <rect x="2" y="3" width="20" height="14" rx="2" ry="2"></rect>
516
+ <line x1="8" y1="21" x2="16" y2="21"></line>
517
+ <line x1="12" y1="17" x2="12" y2="21"></line>
518
+ </svg>
519
+ Claude Code Runner
520
+ </h1>
521
+ <div class="status">
522
+ <!-- Language Selector -->
523
+ <div class="language-selector-wrapper">
524
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
525
+ <circle cx="12" cy="12" r="10"></circle>
526
+ <line x1="2" y1="12" x2="22" y2="12"></line>
527
+ <path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path>
528
+ </svg>
529
+ <select id="language-selector" onchange="I18n.setLocale(this.value)">
530
+ <option value="en">English</option>
531
+ <option value="zh-CN">简体中文</option>
532
+ </select>
533
+ </div>
534
+ <span
535
+ class="git-info"
536
+ id="git-info"
537
+ style="margin-right: 1rem; display: none"
538
+ >
539
+ <svg
540
+ width="14"
541
+ height="14"
542
+ viewBox="0 0 16 16"
543
+ fill="currentColor"
544
+ style="vertical-align: text-bottom; margin-right: 4px"
545
+ >
546
+ <path
547
+ d="M11.75 2.5a.75.75 0 100 1.5.75.75 0 000-1.5zm-2.25.75a2.25 2.25 0 113 2.122V6A2.5 2.5 0 0110 8.5H6a1 1 0 00-1 1v1.128a2.251 2.251 0 11-1.5 0V5.372a2.25 2.25 0 111.5 0v1.836A2.492 2.492 0 016 7h4a1 1 0 001-1v-.628A2.25 2.25 0 019.5 3.25zM4.25 12a.75.75 0 100 1.5.75.75 0 000-1.5zM3.5 3.25a.75.75 0 111.5 0 .75.75 0 01-1.5 0z"
548
+ />
549
+ </svg>
550
+ <span id="branch-name">loading...</span>
551
+ <span id="pr-info" style="margin-left: 0.5rem"></span>
552
+ </span>
553
+ <span class="status-indicator" id="status-indicator"></span>
554
+ <span id="status-text">Connecting...</span>
555
+ </div>
556
+ </div>
557
+
558
+ <!-- Tab Bar -->
559
+ <div class="tabs">
560
+ <button
561
+ class="tab active"
562
+ id="terminal-tab"
563
+ onclick="switchTab('terminal')"
564
+ >
565
+ <svg
566
+ width="16"
567
+ height="16"
568
+ viewBox="0 0 24 24"
569
+ fill="none"
570
+ stroke="currentColor"
571
+ stroke-width="2"
572
+ style="margin-right: 6px"
573
+ >
574
+ <polyline points="4,17 10,11 4,5"></polyline>
575
+ <line x1="12" y1="19" x2="20" y2="19"></line>
576
+ </svg>
577
+ <span data-i18n="tabs.terminal">Terminal</span>
578
+ </button>
579
+ <button class="tab" id="changes-tab" onclick="switchTab('changes')">
580
+ <svg
581
+ width="16"
582
+ height="16"
583
+ viewBox="0 0 24 24"
584
+ fill="none"
585
+ stroke="currentColor"
586
+ stroke-width="2"
587
+ style="margin-right: 6px"
588
+ >
589
+ <path
590
+ d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"
591
+ ></path>
592
+ <polyline points="14,2 14,8 20,8"></polyline>
593
+ <line x1="16" y1="13" x2="8" y2="13"></line>
594
+ <line x1="16" y1="17" x2="8" y2="17"></line>
595
+ <polyline points="10,9 9,9 8,9"></polyline>
596
+ </svg>
597
+ <span data-i18n="tabs.changes">Changes</span>
598
+ </button>
599
+ </div>
600
+
601
+ <!-- Terminal Tab Content -->
602
+ <div class="tab-content active" id="terminal-content">
603
+ <div class="terminal-container">
604
+ <div id="terminal"></div>
605
+ <div class="loading" id="loading">
606
+ <div class="loading-spinner"></div>
607
+ <div data-i18n="terminal.connectingToContainer">Connecting to container...</div>
608
+ </div>
609
+ </div>
610
+
611
+ <div class="controls">
612
+ <button onclick="clearTerminal()" data-i18n="terminal.clear">Clear</button>
613
+ <button onclick="reconnect()" data-i18n="terminal.reconnect">Reconnect</button>
614
+ <button onclick="copySelection()" data-i18n="terminal.copySelection">Copy Selection</button>
615
+ <label
616
+ style="
617
+ margin-left: 1rem;
618
+ display: flex;
619
+ align-items: center;
620
+ gap: 0.5rem;
621
+ "
622
+ >
623
+ <input type="checkbox" id="soundEnabled" checked />
624
+ <span data-i18n="terminal.soundNotifications">Sound notifications</span>
625
+ </label>
626
+ <span style="margin-left: auto; color: #888" data-i18n="terminal.shortcuts">
627
+ Ctrl+C: Interrupt | Ctrl+D: Exit | Ctrl+L: Clear
628
+ </span>
629
+ </div>
630
+ </div>
631
+
632
+ <!-- Changes Tab Content -->
633
+ <div class="tab-content" id="changes-content">
634
+ <div class="changes-view">
635
+ <div class="changes-content" id="changes-container">
636
+ <div class="empty-state" id="no-changes">
637
+ <h3 data-i18n="changes.noChangesTitle">No changes detected</h3>
638
+ <p data-i18n="changes.noChangesDescription">
639
+ Claude hasn't made any changes yet. Changes will appear here
640
+ automatically when Claude modifies files.
641
+ </p>
642
+ </div>
643
+ </div>
644
+ </div>
645
+ </div>
646
+
647
+ <script src="https://unpkg.com/xterm@5.3.0/lib/xterm.js"></script>
648
+ <script src="https://unpkg.com/xterm-addon-fit@0.8.0/lib/xterm-addon-fit.js"></script>
649
+ <script src="https://unpkg.com/xterm-addon-web-links@0.9.0/lib/xterm-addon-web-links.js"></script>
650
+ <script src="/socket.io/socket.io.js"></script>
651
+ <script src="/i18n.js"></script>
652
+ <script src="/app.js"></script>
653
+ <script>
654
+ // Initialize i18n before app starts
655
+ I18n.init().then(() => {
656
+ console.log('i18n initialized with locale:', I18n.getLocale());
657
+ });
658
+ </script>
659
+ </body>
660
+ </html>