hjworktree-cli 2.0.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 (68) hide show
  1. package/.context-snapshots/context-snapshot-20260106-110353.md +66 -0
  2. package/.context-snapshots/context-snapshot-20260106-110441.md +66 -0
  3. package/.context-snapshots/context-snapshot-20260106-220000.md +99 -0
  4. package/AGENTS.md +29 -0
  5. package/CLAUDE.md +88 -0
  6. package/bin/cli.js +85 -0
  7. package/dist/server/index.d.ts +6 -0
  8. package/dist/server/index.d.ts.map +1 -0
  9. package/dist/server/index.js +64 -0
  10. package/dist/server/index.js.map +1 -0
  11. package/dist/server/routes/api.d.ts +3 -0
  12. package/dist/server/routes/api.d.ts.map +1 -0
  13. package/dist/server/routes/api.js +101 -0
  14. package/dist/server/routes/api.js.map +1 -0
  15. package/dist/server/services/gitService.d.ts +13 -0
  16. package/dist/server/services/gitService.d.ts.map +1 -0
  17. package/dist/server/services/gitService.js +84 -0
  18. package/dist/server/services/gitService.js.map +1 -0
  19. package/dist/server/services/worktreeService.d.ts +17 -0
  20. package/dist/server/services/worktreeService.d.ts.map +1 -0
  21. package/dist/server/services/worktreeService.js +161 -0
  22. package/dist/server/services/worktreeService.js.map +1 -0
  23. package/dist/server/socketHandlers.d.ts +4 -0
  24. package/dist/server/socketHandlers.d.ts.map +1 -0
  25. package/dist/server/socketHandlers.js +118 -0
  26. package/dist/server/socketHandlers.js.map +1 -0
  27. package/dist/shared/constants.d.ts +10 -0
  28. package/dist/shared/constants.d.ts.map +1 -0
  29. package/dist/shared/constants.js +31 -0
  30. package/dist/shared/constants.js.map +1 -0
  31. package/dist/shared/types/index.d.ts +67 -0
  32. package/dist/shared/types/index.d.ts.map +1 -0
  33. package/dist/shared/types/index.js +3 -0
  34. package/dist/shared/types/index.js.map +1 -0
  35. package/dist/web/assets/index-C61yAbey.css +32 -0
  36. package/dist/web/assets/index-WEdVUKxb.js +53 -0
  37. package/dist/web/assets/index-WEdVUKxb.js.map +1 -0
  38. package/dist/web/index.html +16 -0
  39. package/package.json +63 -0
  40. package/server/index.ts +75 -0
  41. package/server/routes/api.ts +108 -0
  42. package/server/services/gitService.ts +91 -0
  43. package/server/services/worktreeService.ts +181 -0
  44. package/server/socketHandlers.ts +157 -0
  45. package/shared/constants.ts +35 -0
  46. package/shared/types/index.ts +92 -0
  47. package/tsconfig.json +20 -0
  48. package/web/index.html +15 -0
  49. package/web/src/App.tsx +65 -0
  50. package/web/src/components/Layout/Header.tsx +29 -0
  51. package/web/src/components/Layout/LeftNavBar.tsx +67 -0
  52. package/web/src/components/Layout/MainLayout.tsx +23 -0
  53. package/web/src/components/Layout/StepContainer.tsx +71 -0
  54. package/web/src/components/Setup/AgentSelector.tsx +27 -0
  55. package/web/src/components/Setup/BranchSelector.tsx +28 -0
  56. package/web/src/components/Setup/SetupPanel.tsx +32 -0
  57. package/web/src/components/Setup/WorktreeCountSelector.tsx +30 -0
  58. package/web/src/components/Steps/AgentStep.tsx +20 -0
  59. package/web/src/components/Steps/BranchStep.tsx +20 -0
  60. package/web/src/components/Steps/WorktreeStep.tsx +41 -0
  61. package/web/src/components/Terminal/TerminalPanel.tsx +113 -0
  62. package/web/src/components/Terminal/XTerminal.tsx +203 -0
  63. package/web/src/hooks/useSocket.ts +80 -0
  64. package/web/src/main.tsx +10 -0
  65. package/web/src/stores/useAppStore.ts +348 -0
  66. package/web/src/styles/global.css +695 -0
  67. package/web/tsconfig.json +23 -0
  68. package/web/vite.config.ts +32 -0
@@ -0,0 +1,695 @@
1
+ * {
2
+ margin: 0;
3
+ padding: 0;
4
+ box-sizing: border-box;
5
+ }
6
+
7
+ :root {
8
+ --bg-primary: #0d1117;
9
+ --bg-secondary: #161b22;
10
+ --bg-tertiary: #21262d;
11
+ --border-color: #30363d;
12
+ --text-primary: #c9d1d9;
13
+ --text-secondary: #8b949e;
14
+ --text-muted: #6e7681;
15
+ --accent-blue: #58a6ff;
16
+ --accent-green: #3fb950;
17
+ --accent-yellow: #d29922;
18
+ --accent-red: #f85149;
19
+ --accent-purple: #a371f7;
20
+ }
21
+
22
+ html, body, #root {
23
+ height: 100%;
24
+ width: 100%;
25
+ }
26
+
27
+ body {
28
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
29
+ background-color: var(--bg-primary);
30
+ color: var(--text-primary);
31
+ line-height: 1.5;
32
+ }
33
+
34
+ .app {
35
+ display: flex;
36
+ flex-direction: column;
37
+ height: 100vh;
38
+ overflow: hidden;
39
+ }
40
+
41
+ /* Header */
42
+ .header {
43
+ display: flex;
44
+ align-items: center;
45
+ justify-content: space-between;
46
+ padding: 12px 24px;
47
+ background-color: var(--bg-secondary);
48
+ border-bottom: 1px solid var(--border-color);
49
+ }
50
+
51
+ .header h1 {
52
+ font-size: 18px;
53
+ font-weight: 600;
54
+ color: var(--text-primary);
55
+ }
56
+
57
+ .header .project-info {
58
+ display: flex;
59
+ align-items: center;
60
+ gap: 12px;
61
+ color: var(--text-secondary);
62
+ font-size: 13px;
63
+ }
64
+
65
+ .header .project-info .branch {
66
+ display: flex;
67
+ align-items: center;
68
+ gap: 4px;
69
+ color: var(--accent-green);
70
+ }
71
+
72
+ /* Main content */
73
+ .main-content {
74
+ flex: 1;
75
+ display: flex;
76
+ flex-direction: column;
77
+ overflow: hidden;
78
+ }
79
+
80
+ /* Setup Panel */
81
+ .setup-panel {
82
+ flex: 1;
83
+ display: flex;
84
+ flex-direction: column;
85
+ align-items: center;
86
+ justify-content: center;
87
+ padding: 40px;
88
+ gap: 32px;
89
+ }
90
+
91
+ .setup-panel h2 {
92
+ font-size: 24px;
93
+ font-weight: 600;
94
+ margin-bottom: 8px;
95
+ }
96
+
97
+ .setup-panel p {
98
+ color: var(--text-secondary);
99
+ font-size: 14px;
100
+ }
101
+
102
+ .setup-section {
103
+ width: 100%;
104
+ max-width: 500px;
105
+ background: var(--bg-secondary);
106
+ border: 1px solid var(--border-color);
107
+ border-radius: 8px;
108
+ padding: 20px;
109
+ }
110
+
111
+ .setup-section label {
112
+ display: block;
113
+ font-size: 14px;
114
+ font-weight: 500;
115
+ margin-bottom: 8px;
116
+ color: var(--text-primary);
117
+ }
118
+
119
+ .setup-section select,
120
+ .setup-section input {
121
+ width: 100%;
122
+ padding: 10px 12px;
123
+ border: 1px solid var(--border-color);
124
+ border-radius: 6px;
125
+ background-color: var(--bg-tertiary);
126
+ color: var(--text-primary);
127
+ font-size: 14px;
128
+ font-family: inherit;
129
+ }
130
+
131
+ .setup-section select:focus,
132
+ .setup-section input:focus {
133
+ outline: none;
134
+ border-color: var(--accent-blue);
135
+ }
136
+
137
+ .setup-section .counter {
138
+ display: flex;
139
+ align-items: center;
140
+ gap: 16px;
141
+ }
142
+
143
+ .setup-section .counter button {
144
+ width: 40px;
145
+ height: 40px;
146
+ border: 1px solid var(--border-color);
147
+ border-radius: 6px;
148
+ background-color: var(--bg-tertiary);
149
+ color: var(--text-primary);
150
+ font-size: 20px;
151
+ cursor: pointer;
152
+ transition: all 0.2s;
153
+ }
154
+
155
+ .setup-section .counter button:hover {
156
+ background-color: var(--bg-primary);
157
+ border-color: var(--accent-blue);
158
+ }
159
+
160
+ .setup-section .counter button:disabled {
161
+ opacity: 0.5;
162
+ cursor: not-allowed;
163
+ }
164
+
165
+ .setup-section .counter span {
166
+ font-size: 24px;
167
+ font-weight: 600;
168
+ min-width: 60px;
169
+ text-align: center;
170
+ }
171
+
172
+ /* Agent cards */
173
+ .agent-cards {
174
+ display: grid;
175
+ grid-template-columns: repeat(3, 1fr);
176
+ gap: 12px;
177
+ }
178
+
179
+ .agent-card {
180
+ padding: 16px;
181
+ border: 2px solid var(--border-color);
182
+ border-radius: 8px;
183
+ background-color: var(--bg-tertiary);
184
+ cursor: pointer;
185
+ transition: all 0.2s;
186
+ }
187
+
188
+ .agent-card:hover {
189
+ border-color: var(--accent-blue);
190
+ }
191
+
192
+ .agent-card.selected {
193
+ border-color: var(--accent-blue);
194
+ background-color: rgba(88, 166, 255, 0.1);
195
+ }
196
+
197
+ .agent-card h4 {
198
+ font-size: 14px;
199
+ font-weight: 600;
200
+ margin-bottom: 4px;
201
+ }
202
+
203
+ .agent-card p {
204
+ font-size: 12px;
205
+ color: var(--text-muted);
206
+ }
207
+
208
+ /* Execute button */
209
+ .execute-button {
210
+ padding: 14px 48px;
211
+ background-color: var(--accent-green);
212
+ color: var(--bg-primary);
213
+ border: none;
214
+ border-radius: 8px;
215
+ font-size: 16px;
216
+ font-weight: 600;
217
+ cursor: pointer;
218
+ transition: all 0.2s;
219
+ }
220
+
221
+ .execute-button:hover {
222
+ filter: brightness(1.1);
223
+ }
224
+
225
+ .execute-button:disabled {
226
+ background-color: var(--bg-tertiary);
227
+ color: var(--text-muted);
228
+ cursor: not-allowed;
229
+ }
230
+
231
+ /* Terminal Panel */
232
+ .terminal-panel {
233
+ display: flex;
234
+ flex-direction: column;
235
+ height: 100%;
236
+ overflow: hidden;
237
+ }
238
+
239
+ .terminal-tabs {
240
+ display: flex;
241
+ align-items: center;
242
+ gap: 4px;
243
+ padding: 8px 16px;
244
+ background-color: var(--bg-secondary);
245
+ border-bottom: 1px solid var(--border-color);
246
+ overflow-x: auto;
247
+ }
248
+
249
+ .terminal-tab {
250
+ display: flex;
251
+ align-items: center;
252
+ gap: 8px;
253
+ padding: 8px 16px;
254
+ background-color: transparent;
255
+ border: 1px solid transparent;
256
+ border-radius: 6px;
257
+ color: var(--text-secondary);
258
+ font-size: 13px;
259
+ cursor: pointer;
260
+ transition: all 0.2s;
261
+ white-space: nowrap;
262
+ }
263
+
264
+ .terminal-tab:hover {
265
+ background-color: var(--bg-tertiary);
266
+ }
267
+
268
+ .terminal-tab.active {
269
+ background-color: var(--bg-tertiary);
270
+ border-color: var(--border-color);
271
+ color: var(--text-primary);
272
+ }
273
+
274
+ .terminal-tab .status {
275
+ width: 8px;
276
+ height: 8px;
277
+ border-radius: 50%;
278
+ }
279
+
280
+ .terminal-tab .status.running {
281
+ background-color: var(--accent-green);
282
+ }
283
+
284
+ .terminal-tab .status.initializing {
285
+ background-color: var(--accent-yellow);
286
+ }
287
+
288
+ .terminal-tab .status.stopped {
289
+ background-color: var(--text-muted);
290
+ }
291
+
292
+ .terminal-tab .status.error {
293
+ background-color: var(--accent-red);
294
+ }
295
+
296
+ .terminal-tab .close-btn {
297
+ padding: 2px 4px;
298
+ background: transparent;
299
+ border: none;
300
+ color: var(--text-muted);
301
+ cursor: pointer;
302
+ border-radius: 4px;
303
+ line-height: 1;
304
+ }
305
+
306
+ .terminal-tab .close-btn:hover {
307
+ background-color: var(--bg-primary);
308
+ color: var(--accent-red);
309
+ }
310
+
311
+ .terminal-actions {
312
+ display: flex;
313
+ align-items: center;
314
+ gap: 8px;
315
+ margin-left: auto;
316
+ padding-left: 16px;
317
+ }
318
+
319
+ .terminal-actions button {
320
+ padding: 6px 12px;
321
+ background-color: transparent;
322
+ border: 1px solid var(--border-color);
323
+ border-radius: 6px;
324
+ color: var(--text-secondary);
325
+ font-size: 12px;
326
+ cursor: pointer;
327
+ transition: all 0.2s;
328
+ }
329
+
330
+ .terminal-actions button:hover {
331
+ background-color: var(--bg-tertiary);
332
+ color: var(--text-primary);
333
+ }
334
+
335
+ .terminal-actions button.danger:hover {
336
+ border-color: var(--accent-red);
337
+ color: var(--accent-red);
338
+ }
339
+
340
+ .terminal-container {
341
+ flex: 1;
342
+ position: relative;
343
+ overflow: hidden;
344
+ }
345
+
346
+ .terminal-wrapper {
347
+ position: absolute;
348
+ top: 0;
349
+ left: 0;
350
+ right: 0;
351
+ bottom: 0;
352
+ padding: 8px;
353
+ }
354
+
355
+ .terminal-wrapper.hidden {
356
+ visibility: hidden;
357
+ }
358
+
359
+ .terminal {
360
+ height: 100%;
361
+ width: 100%;
362
+ }
363
+
364
+ /* Loading overlay */
365
+ .loading-overlay {
366
+ position: fixed;
367
+ top: 0;
368
+ left: 0;
369
+ right: 0;
370
+ bottom: 0;
371
+ background-color: rgba(13, 17, 23, 0.9);
372
+ display: flex;
373
+ flex-direction: column;
374
+ align-items: center;
375
+ justify-content: center;
376
+ gap: 16px;
377
+ z-index: 1000;
378
+ }
379
+
380
+ .loading-spinner {
381
+ width: 48px;
382
+ height: 48px;
383
+ border: 3px solid var(--border-color);
384
+ border-top-color: var(--accent-blue);
385
+ border-radius: 50%;
386
+ animation: spin 1s linear infinite;
387
+ }
388
+
389
+ @keyframes spin {
390
+ to {
391
+ transform: rotate(360deg);
392
+ }
393
+ }
394
+
395
+ .loading-overlay p {
396
+ color: var(--text-secondary);
397
+ font-size: 14px;
398
+ }
399
+
400
+ /* Connection status */
401
+ .connection-status {
402
+ position: fixed;
403
+ bottom: 16px;
404
+ right: 16px;
405
+ display: flex;
406
+ align-items: center;
407
+ gap: 8px;
408
+ padding: 8px 12px;
409
+ background-color: var(--bg-secondary);
410
+ border: 1px solid var(--border-color);
411
+ border-radius: 6px;
412
+ font-size: 12px;
413
+ color: var(--text-secondary);
414
+ }
415
+
416
+ .connection-status .dot {
417
+ width: 8px;
418
+ height: 8px;
419
+ border-radius: 50%;
420
+ }
421
+
422
+ .connection-status .dot.connected {
423
+ background-color: var(--accent-green);
424
+ }
425
+
426
+ .connection-status .dot.disconnected {
427
+ background-color: var(--accent-red);
428
+ }
429
+
430
+ /* Error message */
431
+ .error-banner {
432
+ padding: 12px 16px;
433
+ background-color: rgba(248, 81, 73, 0.1);
434
+ border: 1px solid var(--accent-red);
435
+ border-radius: 6px;
436
+ color: var(--accent-red);
437
+ font-size: 14px;
438
+ text-align: center;
439
+ }
440
+
441
+ /* ========================================
442
+ LNB (Left Navigation Bar) Styles
443
+ ======================================== */
444
+
445
+ /* Main layout with LNB */
446
+ .main-layout {
447
+ display: flex;
448
+ flex: 1;
449
+ overflow: hidden;
450
+ }
451
+
452
+ .main-content-area {
453
+ flex: 1;
454
+ display: flex;
455
+ flex-direction: column;
456
+ overflow: hidden;
457
+ }
458
+
459
+ .main-content-area.with-lnb {
460
+ margin-left: 0;
461
+ }
462
+
463
+ .main-content-area.full-width {
464
+ width: 100%;
465
+ }
466
+
467
+ /* Left Navigation Bar */
468
+ .left-nav-bar {
469
+ width: 260px;
470
+ background-color: var(--bg-secondary);
471
+ border-right: 1px solid var(--border-color);
472
+ display: flex;
473
+ flex-direction: column;
474
+ flex-shrink: 0;
475
+ }
476
+
477
+ .lnb-header {
478
+ padding: 20px;
479
+ border-bottom: 1px solid var(--border-color);
480
+ font-size: 14px;
481
+ font-weight: 600;
482
+ color: var(--text-secondary);
483
+ text-transform: uppercase;
484
+ letter-spacing: 0.5px;
485
+ }
486
+
487
+ .lnb-steps {
488
+ padding: 16px;
489
+ display: flex;
490
+ flex-direction: column;
491
+ gap: 8px;
492
+ }
493
+
494
+ /* Step Item */
495
+ .lnb-step {
496
+ display: flex;
497
+ align-items: center;
498
+ gap: 12px;
499
+ padding: 14px 16px;
500
+ background: transparent;
501
+ border: 1px solid transparent;
502
+ border-radius: 8px;
503
+ text-align: left;
504
+ cursor: pointer;
505
+ transition: all 0.2s ease;
506
+ width: 100%;
507
+ font-family: inherit;
508
+ }
509
+
510
+ .lnb-step:hover:not(:disabled) {
511
+ background-color: var(--bg-tertiary);
512
+ }
513
+
514
+ .lnb-step:disabled {
515
+ cursor: not-allowed;
516
+ opacity: 0.5;
517
+ }
518
+
519
+ /* Step Number Circle */
520
+ .step-number {
521
+ width: 28px;
522
+ height: 28px;
523
+ border-radius: 50%;
524
+ display: flex;
525
+ align-items: center;
526
+ justify-content: center;
527
+ font-size: 13px;
528
+ font-weight: 600;
529
+ flex-shrink: 0;
530
+ transition: all 0.2s ease;
531
+ }
532
+
533
+ /* Step States */
534
+ .lnb-step.pending .step-number {
535
+ background-color: var(--bg-tertiary);
536
+ color: var(--text-muted);
537
+ border: 2px solid var(--border-color);
538
+ }
539
+
540
+ .lnb-step.pending .step-label {
541
+ color: var(--text-muted);
542
+ }
543
+
544
+ .lnb-step.current {
545
+ background-color: rgba(88, 166, 255, 0.1);
546
+ border-color: var(--accent-blue);
547
+ }
548
+
549
+ .lnb-step.current .step-number {
550
+ background-color: var(--accent-blue);
551
+ color: var(--bg-primary);
552
+ }
553
+
554
+ .lnb-step.current .step-label {
555
+ color: var(--text-primary);
556
+ font-weight: 500;
557
+ }
558
+
559
+ .lnb-step.completed .step-number {
560
+ background-color: var(--accent-green);
561
+ color: var(--bg-primary);
562
+ }
563
+
564
+ .lnb-step.completed .step-label {
565
+ color: var(--text-primary);
566
+ }
567
+
568
+ .step-label {
569
+ font-size: 14px;
570
+ flex: 1;
571
+ }
572
+
573
+ /* ========================================
574
+ Step Container Styles
575
+ ======================================== */
576
+
577
+ .step-container {
578
+ flex: 1;
579
+ display: flex;
580
+ flex-direction: column;
581
+ padding: 40px;
582
+ max-width: 600px;
583
+ margin: 0 auto;
584
+ width: 100%;
585
+ }
586
+
587
+ .step-header {
588
+ text-align: center;
589
+ margin-bottom: 32px;
590
+ }
591
+
592
+ .step-header h2 {
593
+ font-size: 24px;
594
+ font-weight: 600;
595
+ margin-bottom: 8px;
596
+ color: var(--text-primary);
597
+ }
598
+
599
+ .step-header p {
600
+ color: var(--text-secondary);
601
+ font-size: 14px;
602
+ }
603
+
604
+ .step-content {
605
+ flex: 1;
606
+ display: flex;
607
+ flex-direction: column;
608
+ gap: 24px;
609
+ }
610
+
611
+ .step-navigation {
612
+ display: flex;
613
+ justify-content: space-between;
614
+ padding-top: 32px;
615
+ margin-top: auto;
616
+ border-top: 1px solid var(--border-color);
617
+ }
618
+
619
+ /* Navigation Buttons */
620
+ .nav-button {
621
+ padding: 12px 32px;
622
+ border-radius: 8px;
623
+ font-size: 14px;
624
+ font-weight: 500;
625
+ cursor: pointer;
626
+ transition: all 0.2s ease;
627
+ font-family: inherit;
628
+ }
629
+
630
+ .nav-button.prev {
631
+ background: transparent;
632
+ border: 1px solid var(--border-color);
633
+ color: var(--text-secondary);
634
+ }
635
+
636
+ .nav-button.prev:hover:not(:disabled) {
637
+ background-color: var(--bg-tertiary);
638
+ color: var(--text-primary);
639
+ }
640
+
641
+ .nav-button.prev:disabled {
642
+ opacity: 0.3;
643
+ cursor: not-allowed;
644
+ }
645
+
646
+ .nav-button.next {
647
+ background-color: var(--accent-blue);
648
+ border: none;
649
+ color: white;
650
+ }
651
+
652
+ .nav-button.next:hover:not(:disabled) {
653
+ filter: brightness(1.1);
654
+ }
655
+
656
+ .nav-button.next:disabled {
657
+ background-color: var(--bg-tertiary);
658
+ color: var(--text-muted);
659
+ cursor: not-allowed;
660
+ }
661
+
662
+ /* Execution Summary in WorktreeStep */
663
+ .execution-summary {
664
+ background-color: var(--bg-secondary);
665
+ border: 1px solid var(--border-color);
666
+ border-radius: 8px;
667
+ padding: 20px;
668
+ }
669
+
670
+ .execution-summary h4 {
671
+ font-size: 14px;
672
+ font-weight: 600;
673
+ margin-bottom: 16px;
674
+ color: var(--text-primary);
675
+ padding-bottom: 12px;
676
+ border-bottom: 1px solid var(--border-color);
677
+ }
678
+
679
+ .summary-item {
680
+ display: flex;
681
+ justify-content: space-between;
682
+ align-items: center;
683
+ padding: 8px 0;
684
+ }
685
+
686
+ .summary-label {
687
+ font-size: 13px;
688
+ color: var(--text-secondary);
689
+ }
690
+
691
+ .summary-value {
692
+ font-size: 13px;
693
+ font-weight: 500;
694
+ color: var(--text-primary);
695
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
5
+ "module": "ESNext",
6
+ "moduleResolution": "bundler",
7
+ "jsx": "react-jsx",
8
+ "strict": true,
9
+ "skipLibCheck": true,
10
+ "esModuleInterop": true,
11
+ "allowSyntheticDefaultImports": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "resolveJsonModule": true,
14
+ "isolatedModules": true,
15
+ "noEmit": true,
16
+ "baseUrl": ".",
17
+ "paths": {
18
+ "@/*": ["src/*"]
19
+ }
20
+ },
21
+ "include": ["src/**/*", "../shared/**/*"],
22
+ "exclude": ["node_modules"]
23
+ }