claude-code-autoconfig 1.0.14 → 1.0.16

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.
@@ -1,1870 +1,1740 @@
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 Autoconfig — Walkthrough</title>
7
- <style>
8
- * {
9
- margin: 0;
10
- padding: 0;
11
- box-sizing: border-box;
12
- }
13
-
14
- :root {
15
- --bg-primary: #0D0D0D;
16
- --bg-secondary: #1A1A1A;
17
- --bg-elevated: #252525;
18
- --text-primary: #FFFFFF;
19
- --text-secondary: #8FBBCF;
20
- --text-dim: #6B7280;
21
- --accent-orange: #FF9933;
22
- --accent-blue: #5C9ECE;
23
- --accent-cyan: #22D3EE;
24
- --accent-green: #6ABF69;
25
- --accent-yellow: #E5C07B;
26
- }
27
-
28
- body {
29
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
30
- background: var(--bg-primary);
31
- color: var(--text-primary);
32
- min-height: 100vh;
33
- overflow: hidden;
34
- }
35
-
36
- .container {
37
- max-width: 900px;
38
- margin: 0 auto;
39
- padding: 40px 20px;
40
- min-height: 100vh;
41
- display: flex;
42
- flex-direction: column;
43
- }
44
-
45
- /* Progress bar */
46
- .progress-container {
47
- display: flex;
48
- justify-content: center;
49
- gap: 8px;
50
- margin-bottom: 40px;
51
- }
52
-
53
- .progress-dot {
54
- width: 12px;
55
- height: 12px;
56
- border-radius: 50%;
57
- background: #4a4a4a;
58
- cursor: pointer;
59
- transition: all 0.3s ease;
60
- }
61
-
62
- .progress-dot:hover {
63
- background: #6a6a6a;
64
- transform: scale(1.2);
65
- }
66
-
67
- .progress-dot.active {
68
- background: var(--accent-green);
69
- box-shadow: 0 0 15px rgba(106, 191, 105, 0.4);
70
- }
71
-
72
- /* Slides */
73
- .slides-container {
74
- flex: 1;
75
- position: relative;
76
- overflow: hidden;
77
- }
78
-
79
- .slide {
80
- position: absolute;
81
- top: 0;
82
- left: 0;
83
- width: 100%;
84
- opacity: 0;
85
- visibility: hidden;
86
- transform: translateX(100px);
87
- transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
88
- pointer-events: none;
89
- display: flex;
90
- flex-direction: column;
91
- }
92
-
93
- .slide.active {
94
- opacity: 1;
95
- visibility: visible;
96
- transform: translateX(0);
97
- pointer-events: auto;
98
- }
99
-
100
- .slide.exit {
101
- opacity: 0;
102
- transform: translateX(-100px);
103
- }
104
-
105
- .slide-number {
106
- font-size: 14px;
107
- color: var(--accent-orange);
108
- text-transform: uppercase;
109
- letter-spacing: 2px;
110
- margin-bottom: 12px;
111
- }
112
-
113
- .slide h1 {
114
- font-size: 2.5rem;
115
- font-weight: 700;
116
- margin-bottom: 20px;
117
- color: var(--text-primary);
118
- }
119
-
120
- .slide h2 {
121
- font-size: 1.3rem;
122
- font-weight: 400;
123
- color: var(--text-secondary);
124
- margin-bottom: 30px;
125
- line-height: 1.6;
126
- }
127
-
128
- .slide-content {
129
- flex: 1;
130
- overflow-y: auto;
131
- }
132
-
133
- /* Code blocks */
134
- .code-block {
135
- background: var(--bg-secondary);
136
- border: 1px solid var(--bg-elevated);
137
- border-radius: 8px;
138
- padding: 20px;
139
- margin: 20px 0;
140
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Roboto', 'Noto Sans', sans-serif;
141
- font-size: 14px;
142
- line-height: 1.6;
143
- overflow-x: auto;
144
- }
145
-
146
- .code-block .comment {
147
- color: var(--text-dim);
148
- }
149
-
150
- .code-block .keyword {
151
- color: var(--accent-orange);
152
- }
153
-
154
- .code-block .string {
155
- color: var(--accent-green);
156
- }
157
-
158
- .code-block .property {
159
- color: var(--accent-blue);
160
- }
161
-
162
- .code-block .folder {
163
- color: var(--accent-cyan);
164
- }
165
-
166
- .code-block .file {
167
- color: var(--accent-orange);
168
- }
169
-
170
- /* Info cards */
171
- .info-card {
172
- background: rgba(212, 165, 116, 0.1);
173
- border-left: 4px solid var(--accent-orange);
174
- border-radius: 0 8px 8px 0;
175
- padding: 16px 20px;
176
- margin: 20px 0;
177
- }
178
-
179
- .info-card.warning {
180
- background: rgba(229, 192, 123, 0.1);
181
- border-left-color: var(--accent-yellow);
182
- }
183
-
184
- .info-card h4 {
185
- font-size: 14px;
186
- text-transform: uppercase;
187
- letter-spacing: 1px;
188
- margin-bottom: 8px;
189
- color: var(--accent-orange);
190
- }
191
-
192
- .info-card.warning h4 {
193
- color: var(--accent-yellow);
194
- }
195
-
196
- /* Feature list */
197
- .feature-list {
198
- list-style: none;
199
- margin: 20px 0;
200
- }
201
-
202
- .feature-list li {
203
- padding: 14px 0;
204
- padding-left: 28px;
205
- position: relative;
206
- border-bottom: 1px solid var(--bg-elevated);
207
- display: flex;
208
- align-items: center;
209
- }
210
-
211
- .feature-list li:last-child {
212
- border-bottom: none;
213
- }
214
-
215
- .feature-list li::before {
216
- content: "●";
217
- position: absolute;
218
- left: 0;
219
- color: var(--text-primary);
220
- font-size: 14px;
221
- }
222
-
223
- .feature-list li.blue-bullet::before {
224
- color: var(--accent-blue);
225
- }
226
-
227
- .feature-list .file-name {
228
- color: var(--accent-orange);
229
- font-family: 'SF Mono', 'Fira Code', monospace;
230
- font-size: 14px;
231
- }
232
-
233
- /* Welcome content */
234
- .welcome-content {
235
- display: flex;
236
- flex-direction: column;
237
- align-items: center;
238
- justify-content: center;
239
- text-align: center;
240
- padding: 40px 20px;
241
- }
242
-
243
- .welcome-text {
244
- font-size: 24px;
245
- color: var(--text-primary);
246
- margin-bottom: 30px;
247
- }
248
-
249
- .welcome-action {
250
- background: var(--bg-secondary);
251
- border: 1px solid var(--bg-elevated);
252
- border-radius: 12px;
253
- padding: 24px 32px;
254
- max-width: 500px;
255
- }
256
-
257
- .welcome-action p {
258
- font-size: 16px;
259
- color: var(--text-secondary);
260
- line-height: 1.6;
261
- margin: 0;
262
- }
263
-
264
- .welcome-action code {
265
- background: var(--bg-elevated);
266
- padding: 4px 12px;
267
- border-radius: 6px;
268
- font-family: 'SF Mono', 'Fira Code', monospace;
269
- font-size: 15px;
270
- color: var(--accent-cyan);
271
- }
272
-
273
- /* TOC list */
274
- .tip-banner {
275
- display: flex;
276
- align-items: flex-start;
277
- gap: 12px;
278
- padding: 16px 20px;
279
- margin-bottom: 20px;
280
- background: rgba(255, 153, 51, 0.1);
281
- border: 1px solid rgba(255, 153, 51, 0.3);
282
- border-radius: 8px;
283
- }
284
-
285
- .tip-icon {
286
- font-size: 18px;
287
- flex-shrink: 0;
288
- }
289
-
290
- .tip-text {
291
- color: var(--text-secondary);
292
- font-size: 14px;
293
- line-height: 1.5;
294
- }
295
-
296
- .tip-text code {
297
- background: var(--bg-elevated);
298
- padding: 2px 8px;
299
- border-radius: 4px;
300
- font-family: 'SF Mono', 'Fira Code', monospace;
301
- font-size: 13px;
302
- color: var(--accent-cyan);
303
- }
304
-
305
- .toc-list {
306
- list-style: none;
307
- margin: 10px 0;
308
- padding: 0;
309
- }
310
-
311
- .toc-list li {
312
- display: flex;
313
- align-items: center;
314
- gap: 16px;
315
- padding: 16px 20px;
316
- margin: 8px 0;
317
- background: var(--bg-secondary);
318
- border-radius: 8px;
319
- cursor: pointer;
320
- transition: all 0.2s ease;
321
- }
322
-
323
- .toc-list li:hover {
324
- background: var(--bg-elevated);
325
- transform: translateX(8px);
326
- }
327
-
328
- .toc-number {
329
- color: var(--accent-orange);
330
- font-family: 'SF Mono', 'Fira Code', monospace;
331
- font-size: 14px;
332
- font-weight: 600;
333
- min-width: 28px;
334
- }
335
-
336
- .toc-title {
337
- color: var(--text-primary);
338
- font-weight: 600;
339
- font-size: 16px;
340
- min-width: 140px;
341
- }
342
-
343
- .toc-desc {
344
- color: var(--text-dim);
345
- font-size: 14px;
346
- }
347
-
348
- /* Tree view */
349
- .tree-view {
350
- background: var(--bg-secondary);
351
- border: 1px solid var(--bg-elevated);
352
- border-radius: 8px;
353
- padding: 20px;
354
- margin: 20px 0;
355
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Roboto', 'Noto Sans', sans-serif;
356
- font-size: 14px;
357
- line-height: 1.5;
358
- overflow-x: auto;
359
- white-space: pre;
360
- }
361
-
362
- .tree-view .folder {
363
- color: var(--accent-cyan);
364
- }
365
-
366
- .tree-view .file {
367
- color: var(--accent-orange);
368
- }
369
-
370
- .tree-view .comment {
371
- color: var(--text-dim);
372
- }
373
-
374
- /* Split-pane tree panel */
375
- .tree-panel {
376
- display: flex;
377
- gap: 0;
378
- background: var(--bg-secondary);
379
- border-radius: 8px;
380
- overflow: hidden;
381
- height: 340px;
382
- position: relative;
383
- }
384
-
385
- .tree-side {
386
- padding: 16px;
387
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Roboto', 'Noto Sans', sans-serif;
388
- font-size: 13px;
389
- line-height: 1.4;
390
- border-right: 1px solid var(--bg-elevated);
391
- overflow-y: auto;
392
- flex-shrink: 0;
393
- height: 100%;
394
- }
395
-
396
- .tree-item {
397
- padding: 4px 8px;
398
- margin: 1px 0;
399
- border-radius: 4px;
400
- cursor: pointer;
401
- transition: background 0.15s ease;
402
- white-space: nowrap;
403
- display: flex;
404
- align-items: center;
405
- gap: 4px;
406
- }
407
-
408
- .tree-item.hidden {
409
- display: none;
410
- }
411
-
412
- .tree-item:hover {
413
- background: rgba(255, 255, 255, 0.1);
414
- }
415
-
416
- .tree-item.active {
417
- background: rgba(45, 105, 175, 0.5);
418
- }
419
-
420
- .tree-item.active:hover {
421
- background: rgba(45, 105, 175, 0.5);
422
- }
423
-
424
- .tree-chevron {
425
- width: 18px;
426
- font-size: 18px;
427
- color: var(--text-primary);
428
- text-align: center;
429
- flex-shrink: 0;
430
- transition: transform 0.15s ease;
431
- user-select: none;
432
- transform: rotate(90deg);
433
- }
434
-
435
- .tree-item.collapsed .tree-chevron {
436
- transform: rotate(0deg);
437
- }
438
-
439
- .tree-spacer {
440
- width: 16px;
441
- flex-shrink: 0;
442
- }
443
-
444
- .tree-folder-icon,
445
- .tree-file-icon {
446
- font-size: 14px;
447
- flex-shrink: 0;
448
- }
449
-
450
- .tree-item .folder {
451
- color: var(--text-primary);
452
- }
453
-
454
- .tree-item .file {
455
- color: var(--text-secondary);
456
- }
457
-
458
- .tree-item.indent-1 { padding-left: 24px; }
459
- .tree-item.indent-2 { padding-left: 44px; }
460
- .tree-item.indent-3 { padding-left: 64px; }
461
- .tree-item.indent-4 { padding-left: 84px; }
462
-
463
- .tree-indent {
464
- color: var(--text-dim);
465
- }
466
-
467
- .info-side {
468
- flex: 1;
469
- min-width: 200px;
470
- overflow-y: auto;
471
- }
472
-
473
- .info-panel {
474
- padding: 20px;
475
- width: 100%;
476
- box-sizing: border-box;
477
- }
478
-
479
- .info-panel-title {
480
- font-size: 16px;
481
- font-weight: 600;
482
- color: var(--accent-orange);
483
- margin-bottom: 12px;
484
- }
485
-
486
- .info-panel-desc {
487
- font-size: 14px;
488
- color: var(--text-secondary);
489
- line-height: 1.6;
490
- letter-spacing: 0.02em;
491
- }
492
-
493
- .info-panel-trigger {
494
- margin-top: 16px;
495
- padding: 8px 12px;
496
- background: var(--bg-elevated);
497
- border-radius: 4px;
498
- font-family: 'SF Mono', 'Fira Code', monospace;
499
- font-size: 13px;
500
- color: var(--accent-cyan);
501
- }
502
-
503
- /* Navigation */
504
- .nav-container {
505
- display: flex;
506
- justify-content: space-between;
507
- align-items: center;
508
- margin-top: 40px;
509
- padding-top: 20px;
510
- }
511
-
512
- .nav-btn {
513
- display: flex;
514
- align-items: center;
515
- gap: 8px;
516
- padding: 14px 28px;
517
- border: none;
518
- border-radius: 8px;
519
- font-size: 16px;
520
- font-weight: 500;
521
- cursor: pointer;
522
- transition: all 0.3s ease;
523
- }
524
-
525
- .nav-btn.prev {
526
- background: var(--bg-elevated);
527
- color: var(--text-secondary);
528
- }
529
-
530
- .nav-btn.prev:hover:not(:disabled) {
531
- background: var(--bg-secondary);
532
- color: var(--text-primary);
533
- }
534
-
535
- .nav-btn.next {
536
- background: var(--accent-orange);
537
- color: var(--bg-primary);
538
- }
539
-
540
- .nav-btn.next:hover:not(:disabled) {
541
- transform: translateY(-2px);
542
- box-shadow: 0 10px 30px rgba(212, 165, 116, 0.3);
543
- }
544
-
545
- .nav-btn:disabled {
546
- opacity: 0.3;
547
- cursor: not-allowed;
548
- transform: none !important;
549
- }
550
-
551
- .nav-hint {
552
- color: var(--text-dim);
553
- font-size: 14px;
554
- }
555
-
556
- .nav-hint kbd {
557
- background: var(--bg-elevated);
558
- padding: 4px 8px;
559
- border-radius: 4px;
560
- font-family: inherit;
561
- margin: 0 2px;
562
- }
563
-
564
- /* Table */
565
- .table-container {
566
- overflow-x: auto;
567
- margin: 20px 0;
568
- }
569
-
570
- table {
571
- width: 100%;
572
- border-collapse: collapse;
573
- }
574
-
575
- th, td {
576
- padding: 12px 16px;
577
- text-align: left;
578
- border-bottom: 1px solid var(--bg-elevated);
579
- }
580
-
581
- th {
582
- color: var(--accent-blue);
583
- font-size: 12px;
584
- text-transform: uppercase;
585
- letter-spacing: 1px;
586
- }
587
-
588
- td {
589
- font-size: 14px;
590
- }
591
-
592
- td code {
593
- background: var(--bg-secondary);
594
- color: var(--accent-orange);
595
- padding: 2px 8px;
596
- border-radius: 4px;
597
- font-family: 'SF Mono', 'Fira Code', monospace;
598
- font-size: 13px;
599
- }
600
-
601
- /* Animations */
602
- @keyframes fadeInUp {
603
- from {
604
- opacity: 0;
605
- transform: translateY(20px);
606
- }
607
- to {
608
- opacity: 1;
609
- transform: translateY(0);
610
- }
611
- }
612
-
613
- .slide.active .slide-number { animation: fadeIn 0.4s ease both; }
614
- .slide.active h1 { animation: fadeIn 0.4s ease 0.1s both; }
615
- .slide.active h2 { animation: none; }
616
- .slide.active .slide-content > ul,
617
- .slide.active .slide-content > div { animation: fadeIn 0.5s ease 0.3s both; }
618
-
619
- @keyframes fadeIn {
620
- from { opacity: 0; }
621
- to { opacity: 1; }
622
- }
623
-
624
- /* Typewriter effect */
625
- .typewriter {
626
- border-right: 2px solid var(--bg-primary);
627
- animation: none !important;
628
- }
629
-
630
- .typewriter.typing {
631
- animation: blink-caret 0.75s step-end infinite !important;
632
- }
633
-
634
- .typewriter.done {
635
- border-right: none !important;
636
- animation: none !important;
637
- }
638
-
639
- @keyframes blink-caret {
640
- from, to { border-color: var(--bg-primary); }
641
- 50% { border-color: transparent; }
642
- }
643
-
644
- /* Scrollbar */
645
- ::-webkit-scrollbar {
646
- width: 8px;
647
- }
648
-
649
- ::-webkit-scrollbar-track {
650
- background: var(--bg-secondary);
651
- border-radius: 4px;
652
- }
653
-
654
- ::-webkit-scrollbar-thumb {
655
- background: var(--bg-elevated);
656
- border-radius: 4px;
657
- }
658
-
659
- ::-webkit-scrollbar-thumb:hover {
660
- background: var(--text-dim);
661
- }
662
-
663
- /* Logo */
664
- .logo {
665
- font-size: 24px;
666
- margin-bottom: 8px;
667
- }
668
-
669
- /* Final slide special */
670
- .final-links {
671
- display: flex;
672
- gap: 16px;
673
- margin-top: 30px;
674
- flex-wrap: wrap;
675
- }
676
-
677
- .final-link {
678
- display: inline-flex;
679
- align-items: center;
680
- gap: 8px;
681
- padding: 12px 24px;
682
- background: var(--bg-elevated);
683
- border-radius: 8px;
684
- color: var(--text-secondary);
685
- text-decoration: none;
686
- transition: all 0.3s ease;
687
- }
688
-
689
- .final-link:hover {
690
- background: var(--bg-secondary);
691
- color: var(--accent-orange);
692
- transform: translateY(-2px);
693
- }
694
-
695
- /* File Preview Modal */
696
- .modal-overlay {
697
- position: fixed;
698
- top: 0;
699
- left: 0;
700
- right: 0;
701
- bottom: 0;
702
- background: rgba(0, 0, 0, 0.85);
703
- display: none;
704
- justify-content: center;
705
- align-items: center;
706
- z-index: 1000;
707
- padding: 40px;
708
- opacity: 0;
709
- transition: opacity 0.2s ease;
710
- }
711
-
712
- .modal-overlay.visible {
713
- display: flex;
714
- opacity: 1;
715
- }
716
-
717
- .modal-content {
718
- background: var(--bg-secondary);
719
- border: 1px solid var(--bg-elevated);
720
- border-radius: 12px;
721
- max-width: 800px;
722
- width: 100%;
723
- max-height: 80vh;
724
- display: flex;
725
- flex-direction: column;
726
- transform: scale(0.95);
727
- transition: transform 0.2s ease;
728
- }
729
-
730
- .modal-overlay.visible .modal-content {
731
- transform: scale(1);
732
- }
733
-
734
- .modal-header {
735
- display: flex;
736
- justify-content: space-between;
737
- align-items: center;
738
- padding: 16px 20px;
739
- border-bottom: 1px solid var(--bg-elevated);
740
- }
741
-
742
- .modal-title {
743
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Roboto', 'Noto Sans', sans-serif;
744
- font-size: 14px;
745
- color: var(--accent-orange);
746
- }
747
-
748
- .modal-close {
749
- background: none;
750
- border: none;
751
- color: var(--text-dim);
752
- font-size: 24px;
753
- cursor: pointer;
754
- padding: 0;
755
- line-height: 1;
756
- transition: color 0.2s ease;
757
- }
758
-
759
- .modal-close:hover {
760
- color: var(--text-primary);
761
- }
762
-
763
- .modal-body {
764
- padding: 20px;
765
- overflow-y: auto;
766
- flex: 1;
767
- }
768
-
769
- .modal-body pre {
770
- margin: 0;
771
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Roboto', 'Noto Sans', sans-serif;
772
- font-size: 13px;
773
- line-height: 1.6;
774
- color: var(--text-secondary);
775
- white-space: pre-wrap;
776
- word-wrap: break-word;
777
- }
778
-
779
- .modal-body .comment { color: var(--text-dim); }
780
- .modal-body .keyword { color: var(--accent-orange); }
781
- .modal-body .string { color: var(--accent-green); }
782
- .modal-body .property { color: var(--accent-blue); }
783
-
784
- .modal-empty {
785
- color: var(--text-dim);
786
- font-style: italic;
787
- text-align: center;
788
- padding: 40px;
789
- }
790
-
791
- /* Migration link */
792
- .migration-link {
793
- margin: 10px 0 20px 0;
794
- }
795
-
796
- .migration-link a {
797
- color: var(--accent-orange);
798
- text-decoration: none;
799
- font-size: 14px;
800
- padding: 8px 16px;
801
- background: rgba(255, 153, 51, 0.1);
802
- border: 1px solid rgba(255, 153, 51, 0.3);
803
- border-radius: 6px;
804
- display: inline-block;
805
- transition: all 0.2s ease;
806
- }
807
-
808
- .migration-link a:hover {
809
- background: rgba(255, 153, 51, 0.2);
810
- transform: translateY(-1px);
811
- }
812
-
813
- </style>
814
- </head>
815
- <body>
816
- <!-- File Preview Modal -->
817
- <div class="modal-overlay" id="fileModal">
818
- <div class="modal-content">
819
- <div class="modal-header">
820
- <span class="modal-title" id="modalTitle">filename.md</span>
821
- <button class="modal-close" id="modalClose">&times;</button>
822
- </div>
823
- <div class="modal-body">
824
- <pre id="modalCode"></pre>
825
- </div>
826
- </div>
827
- </div>
828
-
829
- <div class="container">
830
- <div class="progress-container" id="progress"></div>
831
-
832
- <div class="slides-container">
833
- <!-- Slide 0: What Got Installed -->
834
- <div class="slide active" data-slide="0">
835
- <div class="slide-number">01 / Overview</div>
836
- <h1>✨ Autoconfig Complete</h1>
837
- <h2 class="typewriter" data-text="Here's what got installed. Hover over any file or folder to learn what it does."></h2>
838
- <div class="migration-link" id="migrationLink" style="display: none;">
839
- <a href="#" id="showMigration">📦 View migrated files</a>
840
- </div>
841
- <div class="migration-link" id="backToInstallLink" style="display: none;">
842
- <a href="#" id="backToInstall">Back to install view</a>
843
- </div>
844
- <div class="slide-content">
845
- <div class="tree-panel">
846
- <div class="tree-side">
847
- <div class="tree-item folder-row" data-info="root" data-folder="root">
848
- <span class="tree-chevron">›</span>
849
- <span class="tree-folder-icon">📁</span>
850
- <span class="folder">your-project</span>
851
- </div>
852
- <div class="tree-item indent-1 folder-row collapsed" data-info="claude-dir" data-folder="claude-dir" data-parent="root">
853
- <span class="tree-chevron">›</span>
854
- <span class="tree-folder-icon">📁</span>
855
- <span class="folder">.claude</span>
856
- </div>
857
- <div class="tree-item indent-2 folder-row hidden collapsed" data-info="commands" data-folder="commands" data-parent="claude-dir">
858
- <span class="tree-chevron">›</span>
859
- <span class="tree-folder-icon">📁</span>
860
- <span class="folder">commands</span>
861
- </div>
862
- <div class="tree-item indent-3 hidden" data-info="autoconfig" data-parent="commands">
863
- <span class="tree-spacer"></span>
864
- <span class="tree-file-icon">📄</span>
865
- <span class="file">autoconfig.md</span>
866
- </div>
867
- <div class="tree-item indent-3 hidden" data-info="commit-and-push" data-parent="commands">
868
- <span class="tree-spacer"></span>
869
- <span class="tree-file-icon">📄</span>
870
- <span class="file">commit-and-push.md</span>
871
- </div>
872
- <div class="tree-item indent-3 hidden" data-info="enable-retro" data-parent="commands">
873
- <span class="tree-spacer"></span>
874
- <span class="tree-file-icon">📄</span>
875
- <span class="file">enable-retro.md</span>
876
- </div>
877
- <div class="tree-item indent-3 hidden" data-info="guide-cmd" data-parent="commands">
878
- <span class="tree-spacer"></span>
879
- <span class="tree-file-icon">📄</span>
880
- <span class="file">show-guide.md</span>
881
- </div>
882
- <div class="tree-item indent-3 hidden" data-info="sync-claude-md" data-parent="commands">
883
- <span class="tree-spacer"></span>
884
- <span class="tree-file-icon">📄</span>
885
- <span class="file">sync-claude-md.md</span>
886
- </div>
887
- <div class="tree-item indent-3 hidden" data-info="test" data-parent="commands">
888
- <span class="tree-spacer"></span>
889
- <span class="tree-file-icon">📄</span>
890
- <span class="file">test.md</span>
891
- </div>
892
- <div class="tree-item indent-2 folder-row hidden collapsed" data-info="feedback" data-folder="feedback" data-parent="claude-dir">
893
- <span class="tree-chevron">›</span>
894
- <span class="tree-folder-icon">📁</span>
895
- <span class="folder">feedback</span>
896
- </div>
897
- <div class="tree-item indent-3 hidden" data-info="feedback-template" data-parent="feedback">
898
- <span class="tree-spacer"></span>
899
- <span class="tree-file-icon">📄</span>
900
- <span class="file">FEEDBACK.md</span>
901
- </div>
902
- <div class="tree-item indent-2 hidden" data-info="agents" data-parent="claude-dir">
903
- <span class="tree-spacer"></span>
904
- <span class="tree-folder-icon">📁</span>
905
- <span class="folder">agents</span>
906
- </div>
907
- <div class="tree-item indent-2 folder-row hidden collapsed" data-info="guide" data-folder="guide-folder" data-parent="claude-dir">
908
- <span class="tree-chevron">›</span>
909
- <span class="tree-folder-icon">📁</span>
910
- <span class="folder">guide</span>
911
- </div>
912
- <div class="tree-item indent-3 hidden" data-info="guide" data-parent="guide-folder">
913
- <span class="tree-spacer"></span>
914
- <span class="tree-file-icon">🌐</span>
915
- <span class="file">autoconfig.guide.html</span>
916
- </div>
917
- <div class="tree-item indent-2 hidden" data-info="rules" data-parent="claude-dir">
918
- <span class="tree-spacer"></span>
919
- <span class="tree-folder-icon">📁</span>
920
- <span class="folder">rules</span>
921
- </div>
922
- <div class="tree-item indent-2 hidden" data-info="mcp" data-parent="claude-dir">
923
- <span class="tree-spacer"></span>
924
- <span class="tree-file-icon">🔌</span>
925
- <span class="file">.mcp.json</span>
926
- </div>
927
- <div class="tree-item indent-2 hidden" data-info="settings" data-parent="claude-dir">
928
- <span class="tree-spacer"></span>
929
- <span class="tree-file-icon">⚙️</span>
930
- <span class="file">settings.json</span>
931
- </div>
932
- <div class="tree-item indent-1" data-info="claude-md" data-parent="root">
933
- <span class="tree-spacer"></span>
934
- <span class="tree-file-icon">📄</span>
935
- <span class="file">CLAUDE.md</span>
936
- </div>
937
- </div>
938
- <div class="info-side">
939
- <div class="info-panel" id="infoPanel">
940
- <div class="info-panel-title">Select a file</div>
941
- <div class="info-panel-desc">Hover over any item in the tree to see what it does.</div>
942
- </div>
943
- </div>
944
- </div>
945
-
946
- <!-- Migration Tree Panel (hidden by default) -->
947
- <div class="tree-panel" id="migrationTreePanel" style="display: none;">
948
- <div class="tree-side">
949
- <div class="tree-item folder-row" data-folder="migration-root">
950
- <span class="tree-chevron">›</span>
951
- <span class="tree-folder-icon">📁</span>
952
- <span class="folder">.claude/migration/</span>
953
- </div>
954
- <div class="tree-item indent-1 folder-row" data-folder="backup-folder">
955
- <span class="tree-chevron">›</span>
956
- <span class="tree-folder-icon">📦</span>
957
- <span class="folder" id="backupFolderName">backup/</span>
958
- </div>
959
- <div id="backedUpTreeItems"></div>
960
- </div>
961
- <div class="info-side">
962
- <div class="info-panel" id="migrationInfoPanel">
963
- <div class="info-panel-title">Migration Backup</div>
964
- <div class="info-panel-desc">Your previous configuration files were backed up here before the new autoconfig was installed.<br><br>You can restore any file by copying it back from this folder.</div>
965
- </div>
966
- </div>
967
- </div>
968
- </div>
969
- </div>
970
-
971
- <!-- Slide 1: Finale -->
972
- <div class="slide" data-slide="1">
973
- <div class="slide-number">02 / You're Ready</div>
974
- <h1>That's It</h1>
975
- <h2 class="typewriter" data-text="You've got the autoconfig. Now go build something."></h2>
976
- <div class="slide-content">
977
- <div class="final-links">
978
- <a href="https://github.com/design-and-deliver/claude-code-autoconfig" class="final-link" target="_blank">
979
- ⭐ Star on GitHub
980
- </a>
981
- <a href="https://docs.anthropic.com/en/docs/claude-code/overview" class="final-link" target="_blank">
982
- 📚 Claude Code Docs
983
- </a>
984
- </div>
985
- </div>
986
- </div>
987
- </div>
988
-
989
- <div class="nav-container">
990
- <button class="nav-btn prev" id="prevBtn">
991
- Back
992
- </button>
993
- <button class="nav-btn next" id="nextBtn">
994
- Next
995
- </button>
996
- </div>
997
- </div>
998
-
999
- <script>
1000
- const slides = document.querySelectorAll('.slide');
1001
- const progressContainer = document.getElementById('progress');
1002
- const prevBtn = document.getElementById('prevBtn');
1003
- const nextBtn = document.getElementById('nextBtn');
1004
- let currentSlide = 0;
1005
-
1006
- // Create progress dots
1007
- slides.forEach((_, i) => {
1008
- const dot = document.createElement('div');
1009
- dot.className = 'progress-dot' + (i === 0 ? ' active' : '');
1010
- dot.addEventListener('click', () => goToSlide(i));
1011
- progressContainer.appendChild(dot);
1012
- });
1013
-
1014
- function updateProgress() {
1015
- document.querySelectorAll('.progress-dot').forEach((dot, i) => {
1016
- dot.classList.remove('active');
1017
- if (i === currentSlide) dot.classList.add('active');
1018
- });
1019
- }
1020
-
1021
- function goToSlide(index) {
1022
- if (index < 0 || index >= slides.length) return;
1023
-
1024
- const direction = index > currentSlide ? 1 : -1;
1025
-
1026
- slides[currentSlide].classList.remove('active');
1027
- if (direction > 0) {
1028
- slides[currentSlide].classList.add('exit');
1029
- }
1030
-
1031
- currentSlide = index;
1032
-
1033
- slides.forEach(s => s.classList.remove('exit'));
1034
- slides[currentSlide].classList.add('active');
1035
-
1036
- updateProgress();
1037
- updateButtons();
1038
- checkTypewriter();
1039
-
1040
- // Select CLAUDE.md by default when entering slide 0 (tree view)
1041
- if (currentSlide === 0) {
1042
- setTimeout(() => selectTreeItemByKey('claude-md'), 100);
1043
- }
1044
- }
1045
-
1046
- function updateButtons() {
1047
- // Hide back button on first slide, show on others
1048
- prevBtn.style.visibility = currentSlide === 0 ? 'hidden' : 'visible';
1049
-
1050
- if (currentSlide === slides.length - 1) {
1051
- nextBtn.textContent = 'Done';
1052
- } else {
1053
- nextBtn.textContent = 'Next';
1054
- }
1055
- }
1056
-
1057
- prevBtn.addEventListener('click', () => {
1058
- if (currentSlide > 0) {
1059
- goToSlide(currentSlide - 1);
1060
- }
1061
- });
1062
-
1063
- nextBtn.addEventListener('click', () => {
1064
- if (currentSlide < slides.length - 1) {
1065
- goToSlide(currentSlide + 1);
1066
- } else {
1067
- window.close();
1068
- }
1069
- });
1070
-
1071
- // Select CLAUDE.md on initial page load
1072
- setTimeout(() => selectTreeItemByKey('claude-md'), 300);
1073
-
1074
- // Keyboard navigation for slides
1075
- document.addEventListener('keydown', (e) => {
1076
- // On slide 0, arrow keys control tree - use spacebar for next slide
1077
- if (currentSlide === 0) {
1078
- if (e.key === ' ') {
1079
- e.preventDefault();
1080
- if (currentSlide < slides.length - 1) {
1081
- goToSlide(currentSlide + 1);
1082
- }
1083
- }
1084
- return; // Let tree keyboard handler deal with arrows
1085
- }
1086
-
1087
- // Space bar for next slide (but not on slide 0 with tree)
1088
- if (e.key === ' ' && currentSlide !== 0) {
1089
- e.preventDefault();
1090
- if (currentSlide < slides.length - 1) {
1091
- goToSlide(currentSlide + 1);
1092
- }
1093
- }
1094
- });
1095
-
1096
- updateButtons();
1097
-
1098
- // Auto-focus for keyboard navigation
1099
- document.body.setAttribute('tabindex', '0');
1100
- document.body.focus();
1101
-
1102
- // Detect project name from file path
1103
- function getProjectName() {
1104
- try {
1105
- const path = window.location.pathname;
1106
- const parts = path.split('/').filter(p => p && !p.includes(':'));
1107
- const claudeIndex = parts.indexOf('.claude');
1108
- if (claudeIndex > 0) {
1109
- return parts[claudeIndex - 1];
1110
- }
1111
- if (parts.length >= 3) {
1112
- return parts[parts.length - 3];
1113
- }
1114
- } catch (e) {}
1115
- return 'your-project';
1116
- }
1117
-
1118
- const projectName = getProjectName();
1119
-
1120
- // Update tree root with actual project name
1121
- const rootItem = document.querySelector('[data-info="root"]');
1122
- if (rootItem) {
1123
- rootItem.querySelector('.folder').textContent = projectName + '/';
1124
- }
1125
-
1126
- // Calculate tree side width dynamically
1127
- function setTreeWidth() {
1128
- const treeSide = document.querySelector('.tree-side');
1129
- const treeItems = document.querySelectorAll('.tree-item');
1130
- if (!treeSide || !treeItems.length) return;
1131
-
1132
- const hiddenItems = [];
1133
- treeItems.forEach(item => {
1134
- if (item.classList.contains('hidden')) {
1135
- hiddenItems.push(item);
1136
- item.style.visibility = 'hidden';
1137
- item.style.position = 'absolute';
1138
- item.classList.remove('hidden');
1139
- }
1140
- });
1141
-
1142
- let maxWidth = 0;
1143
- treeItems.forEach(item => {
1144
- const width = item.scrollWidth;
1145
- if (width > maxWidth) maxWidth = width;
1146
- });
1147
-
1148
- hiddenItems.forEach(item => {
1149
- item.classList.add('hidden');
1150
- item.style.visibility = '';
1151
- item.style.position = '';
1152
- });
1153
-
1154
- treeSide.style.width = (maxWidth + 32) + 'px';
1155
- treeSide.style.padding = '16px 8px';
1156
- }
1157
-
1158
- if (document.fonts && document.fonts.ready) {
1159
- document.fonts.ready.then(setTreeWidth);
1160
- } else {
1161
- setTimeout(setTreeWidth, 100);
1162
- }
1163
-
1164
- // Typewriter effect
1165
- function typeWriter(element) {
1166
- const text = element.dataset.text;
1167
- if (!text) return;
1168
-
1169
- element.textContent = '';
1170
- element.classList.add('typing');
1171
- element.classList.remove('done');
1172
-
1173
- let i = 0;
1174
- const speed = 30;
1175
-
1176
- function type() {
1177
- if (i < text.length) {
1178
- element.textContent += text.charAt(i);
1179
- i++;
1180
- setTimeout(type, speed);
1181
- } else {
1182
- element.classList.remove('typing');
1183
- element.classList.add('done');
1184
- }
1185
- }
1186
-
1187
- setTimeout(type, 300);
1188
- }
1189
-
1190
- function checkTypewriter() {
1191
- const activeSlide = slides[currentSlide];
1192
- const typewriterEl = activeSlide.querySelector('.typewriter');
1193
- if (typewriterEl) {
1194
- typeWriter(typewriterEl);
1195
- }
1196
- }
1197
-
1198
- setTimeout(checkTypewriter, 100);
1199
-
1200
- // Tree panel info data - UPDATED
1201
- const treeInfo = {
1202
- 'root': {
1203
- title: projectName,
1204
- desc: 'The autoconfig adds CLAUDE.md at your project root and configuration files inside a .claude/ directory. Nothing else is touched.'
1205
- },
1206
- 'claude-md': {
1207
- title: 'CLAUDE.md',
1208
- desc: 'The entry point — Claude reads this at the start of every session. Contains project context populated by autoconfig to optimize how Claude processes requests.<br><br><span style="color: var(--accent-orange);">⚠️ Managed by Claude — do not edit manually.</span>',
1209
- trigger: 'Loaded automatically at session start'
1210
- },
1211
- 'claude-dir': {
1212
- title: '.claude/ Directory',
1213
- desc: 'Commands, rules, settings, and this guide. Keeps configuration organized as your project grows.'
1214
- },
1215
- 'settings': {
1216
- title: 'settings.json',
1217
- desc: 'Permissions, security, and hooks. Controls which commands Claude can run and which files it can access.',
1218
- trigger: 'Claude Code loads this automatically at the start of every session'
1219
- },
1220
- 'mcp': {
1221
- title: '.mcp.json',
1222
- desc: 'MCP (Model Context Protocol) server configuration. Add your MCP server configs here when you\'re ready.<br><br>See <a href="https://docs.anthropic.com/en/docs/claude-code/mcp" target="_blank" style="color: var(--accent-cyan);">MCP documentation</a> for setup instructions.'
1223
- },
1224
- 'commands': {
1225
- title: 'commands/',
1226
- desc: 'On-demand workflows you trigger with <code>/name</code>. Each .md file becomes a <a href="https://docs.anthropic.com/en/docs/claude-code/slash-commands" target="_blank" style="color: var(--accent-cyan);">slash command</a>.'
1227
- },
1228
- 'enable-retro': {
1229
- title: 'enable-retro.md',
1230
- desc: '(Experimental) Enables tech debt tracking. Creates <code>.claude/retro/</code> directory and configures Claude to log improvement opportunities as structured story files.',
1231
- trigger: '/enable-retro'
1232
- },
1233
- 'feedback': {
1234
- title: 'feedback/',
1235
- desc: 'Team-maintained corrections and guidance for Claude. Add notes here when Claude does something wrong — it learns for next time. This directory persists across <code>/autoconfig</code> runs.'
1236
- },
1237
- 'agents': {
1238
- title: 'agents/',
1239
- desc: 'Custom AI agents for specialized tasks. Each <code>.md</code> file defines an agent that Claude can spawn for complex, multi-step operations. Use <code>/enable-retro</code> to add a retro item agent.'
1240
- },
1241
- 'feedback-template': {
1242
- title: 'FEEDBACK.md',
1243
- desc: 'Starter template for team feedback. Add dated entries when Claude makes mistakes — include what went wrong and the correct approach. Claude reads this on every session.'
1244
- },
1245
- 'autoconfig': {
1246
- title: 'autoconfig.md',
1247
- desc: 'The command you just ran. Analyzes your project and populates CLAUDE.md with real context. Re-run anytime your stack changes.',
1248
- trigger: '/autoconfig'
1249
- },
1250
- 'sync-claude-md': {
1251
- title: 'sync-claude-md.md',
1252
- desc: 'Re-analyzes your project and updates CLAUDE.md to reflect current state. Run when your stack changes significantly.',
1253
- trigger: '/sync-claude-md'
1254
- },
1255
- 'guide-cmd': {
1256
- title: 'show-guide.md',
1257
- desc: 'Opens this interactive guide in your browser. Auto-syncs any changed files before opening.',
1258
- trigger: '/show-guide'
1259
- },
1260
- 'test': {
1261
- title: 'test.md',
1262
- desc: 'Runs your test suite. Auto-detects Jest, Vitest, Pytest, Go, RSpec, or falls back to npm test.',
1263
- trigger: '/test'
1264
- },
1265
- 'commit-and-push': {
1266
- title: 'commit-and-push.md',
1267
- desc: 'Stages all changes, generates a conventional commit message from the diff, commits, and pushes. One command, full workflow.',
1268
- trigger: '/commit-and-push'
1269
- },
1270
- 'rules': {
1271
- title: 'rules/',
1272
- desc: 'Path-scoped context that loads when Claude works on matching files. Optimized rules are based on your project\'s needs, patterns and practices.<br><br><div style="background: var(--bg-elevated); border: 1px solid var(--accent-cyan); border-radius: 8px; padding: 16px; margin-top: 8px;"><strong style="color: var(--accent-orange);">Want optimized rules for your project?</strong><br>Reach out: <a href="mailto:info@adac1001.com" style="color: var(--accent-cyan);">info@adac1001.com</a></div>'
1273
- },
1274
- 'guide': {
1275
- title: 'guide/autoconfig.guide.html',
1276
- desc: 'This interactive guide. Open it anytime to review what each file does.',
1277
- trigger: '/show-guide'
1278
- }
1279
- };
1280
-
1281
- // Tree panel hover handling
1282
- const infoPanel = document.getElementById('infoPanel');
1283
- const treeItems = document.querySelectorAll('.tree-item');
1284
-
1285
- let selectedInfoKey = 'claude-md'; // Default selection
1286
-
1287
- function showInfo(key) {
1288
- const info = treeInfo[key];
1289
- if (info) {
1290
- let html = `<div class="info-panel-title">${info.title}</div>`;
1291
- html += `<div class="info-panel-desc">${info.desc}</div>`;
1292
- if (info.trigger) {
1293
- html += `<div class="info-panel-trigger">${info.trigger}</div>`;
1294
- }
1295
- infoPanel.innerHTML = html;
1296
- }
1297
- }
1298
-
1299
- treeItems.forEach((item, idx) => {
1300
- // Hover updates info panel only (preview)
1301
- item.addEventListener('mouseenter', () => {
1302
- const key = item.dataset.info;
1303
- showInfo(key);
1304
- });
1305
-
1306
- // Mouseleave restores selected item's info
1307
- item.addEventListener('mouseleave', () => {
1308
- showInfo(selectedInfoKey);
1309
- });
1310
-
1311
- // Click sets active selection
1312
- item.addEventListener('click', (e) => {
1313
- // Don't select if clicking on a folder chevron (let toggle handle it)
1314
- if (e.target.classList.contains('tree-chevron')) return;
1315
-
1316
- treeItems.forEach(i => i.classList.remove('active'));
1317
- item.classList.add('active');
1318
-
1319
- // Update selected info key
1320
- selectedInfoKey = item.dataset.info;
1321
- showInfo(selectedInfoKey);
1322
-
1323
- // Sync selectedTreeIndex with visible items
1324
- const visibleItems = Array.from(document.querySelectorAll('.tree-item:not(.hidden)'));
1325
- selectedTreeIndex = visibleItems.indexOf(item);
1326
- });
1327
- });
1328
-
1329
- // Folder collapse/expand handling
1330
- function toggleFolder(folderId, collapsed) {
1331
- const children = document.querySelectorAll(`[data-parent="${folderId}"]`);
1332
- children.forEach(child => {
1333
- if (collapsed) {
1334
- child.classList.add('hidden');
1335
- } else {
1336
- child.classList.remove('hidden');
1337
- if (child.dataset.folder && !child.classList.contains('collapsed')) {
1338
- toggleFolder(child.dataset.folder, false);
1339
- }
1340
- }
1341
- if (collapsed && child.dataset.folder) {
1342
- toggleFolder(child.dataset.folder, true);
1343
- }
1344
- });
1345
- }
1346
-
1347
- document.querySelectorAll('.folder-row').forEach(folder => {
1348
- folder.addEventListener('click', (e) => {
1349
- const folderId = folder.dataset.folder;
1350
- const isCollapsed = folder.classList.toggle('collapsed');
1351
- toggleFolder(folderId, isCollapsed);
1352
- });
1353
- });
1354
-
1355
- // Tree keyboard navigation
1356
- let selectedTreeIndex = -1;
1357
-
1358
- function getVisibleTreeItems() {
1359
- return Array.from(document.querySelectorAll('.tree-item:not(.hidden)'));
1360
- }
1361
-
1362
- function selectTreeItemByKey(key) {
1363
- const item = document.querySelector(`.tree-item[data-info="${key}"]`);
1364
- if (!item) return;
1365
-
1366
- treeItems.forEach(i => i.classList.remove('active'));
1367
- item.classList.add('active');
1368
-
1369
- selectedInfoKey = key;
1370
- showInfo(selectedInfoKey);
1371
-
1372
- // Update selectedTreeIndex
1373
- const visibleItems = getVisibleTreeItems();
1374
- selectedTreeIndex = visibleItems.indexOf(item);
1375
- }
1376
-
1377
- function selectTreeItem(index) {
1378
- const items = getVisibleTreeItems();
1379
- if (index < 0 || index >= items.length) return;
1380
-
1381
- treeItems.forEach(i => i.classList.remove('active'));
1382
-
1383
- selectedTreeIndex = index;
1384
- const item = items[index];
1385
- item.classList.add('active');
1386
-
1387
- item.scrollIntoView({ block: 'nearest' });
1388
-
1389
- selectedInfoKey = item.dataset.info;
1390
- showInfo(selectedInfoKey);
1391
- }
1392
-
1393
- document.addEventListener('keydown', (e) => {
1394
- if (currentSlide !== 0) return;
1395
-
1396
- const items = getVisibleTreeItems();
1397
- if (items.length === 0) return;
1398
-
1399
- if (selectedTreeIndex === -1) {
1400
- selectTreeItem(0);
1401
- if (e.key === 'ArrowDown' || e.key === 'ArrowUp' || e.key === 'ArrowRight' || e.key === 'ArrowLeft') {
1402
- e.preventDefault();
1403
- }
1404
- return;
1405
- }
1406
-
1407
- if (e.key === 'ArrowDown') {
1408
- e.preventDefault();
1409
- if (selectedTreeIndex < items.length - 1) {
1410
- selectTreeItem(selectedTreeIndex + 1);
1411
- }
1412
- } else if (e.key === 'ArrowUp') {
1413
- e.preventDefault();
1414
- if (selectedTreeIndex > 0) {
1415
- selectTreeItem(selectedTreeIndex - 1);
1416
- }
1417
- } else if (e.key === 'ArrowRight') {
1418
- e.preventDefault();
1419
- const item = items[selectedTreeIndex];
1420
- if (item && item.classList.contains('folder-row')) {
1421
- if (item.classList.contains('collapsed')) {
1422
- item.classList.remove('collapsed');
1423
- toggleFolder(item.dataset.folder, false);
1424
- }
1425
- }
1426
- } else if (e.key === 'ArrowLeft') {
1427
- e.preventDefault();
1428
- const item = items[selectedTreeIndex];
1429
- if (item && item.classList.contains('folder-row')) {
1430
- if (!item.classList.contains('collapsed')) {
1431
- item.classList.add('collapsed');
1432
- toggleFolder(item.dataset.folder, true);
1433
- }
1434
- }
1435
- } else if (e.key === 'Enter') {
1436
- e.preventDefault();
1437
- const item = items[selectedTreeIndex];
1438
- if (item && item.classList.contains('folder-row')) {
1439
- const isCollapsed = item.classList.toggle('collapsed');
1440
- toggleFolder(item.dataset.folder, isCollapsed);
1441
- }
1442
- }
1443
- });
1444
-
1445
- // File Preview Modal
1446
- const fileContents = {
1447
- 'claude-md': {
1448
- filename: 'CLAUDE.md',
1449
- content: `# Project Name
1450
-
1451
- > Run \`/autoconfig\` to populate this based on your project.`
1452
- },
1453
- 'settings': {
1454
- filename: 'settings.json',
1455
- content: `{
1456
- "permissions": {
1457
- "allow": [
1458
- "Read(./**)",
1459
- "Edit(./**)",
1460
- "Write(./**)",
1461
- "Bash(npm run dev)",
1462
- "Bash(npm run build)",
1463
- "Bash(npm run test)",
1464
- "Bash(git status)",
1465
- "Bash(git diff:*)",
1466
- "Bash(git add:*)",
1467
- "Bash(git commit:*)",
1468
- "Bash(git push:*)"
1469
- ],
1470
- "deny": [
1471
- "Read(./.env)",
1472
- "Read(./.env.*)",
1473
- "Read(./secrets/**)"
1474
- ]
1475
- },
1476
- "hooks": {
1477
- "PostToolUse": [{
1478
- "matcher": "Edit|Write",
1479
- "hooks": [{
1480
- "type": "command",
1481
- "command": "// Auto-refresh guide when .claude/ changes"
1482
- }]
1483
- }]
1484
- }
1485
- }`
1486
- },
1487
- 'mcp': {
1488
- filename: '.mcp.json',
1489
- content: `{
1490
- "mcpServers": {}
1491
- }
1492
-
1493
- // Add your MCP server configs here when you're ready.
1494
- // See: https://docs.anthropic.com/en/docs/claude-code/mcp`
1495
- },
1496
- 'autoconfig': {
1497
- filename: 'autoconfig.md',
1498
- content: `# Autoconfig
1499
-
1500
- Analyze this project and configure Claude Code with real context.
1501
-
1502
- ## Step 1: Scan the Project
1503
-
1504
- Look for these indicators to understand the project:
1505
-
1506
- **Package/Config Files:**
1507
- - \`package.json\` Node.js, npm scripts, dependencies
1508
- - \`requirements.txt\` / \`pyproject.toml\` / \`setup.py\` → Python
1509
- - \`Cargo.toml\` Rust
1510
- - \`go.mod\` → Go
1511
- - \`Gemfile\` Ruby
1512
- - \`pom.xml\` / \`build.gradle\` → Java
1513
- - \`*.csproj\` / \`*.sln\` .NET
1514
- - \`composer.json\` → PHP
1515
-
1516
- **Framework Indicators:**
1517
- - \`next.config.*\` / \`app/\` directory Next.js
1518
- - \`vite.config.*\` → Vite
1519
- - \`angular.json\` → Angular
1520
- - \`svelte.config.*\` → Svelte
1521
- - \`remix.config.*\` → Remix
1522
- - \`nuxt.config.*\` → Nuxt
1523
- - \`django\` in imports → Django
1524
- - \`flask\` in imports → Flask
1525
- - \`fastapi\` in imports → FastAPI
1526
- - \`express\` in dependencies → Express
1527
- - \`rails\` / \`Gemfile\` with rails → Rails
1528
- - \`laravel\` → Laravel
1529
-
1530
- **Testing Frameworks:**
1531
- - \`jest.config.*\` / \`@jest\` in deps → Jest
1532
- - \`vitest.config.*\` → Vitest
1533
- - \`pytest.ini\` / \`conftest.py\` → Pytest
1534
- - \`*_test.go\` files → Go testing
1535
- - \`*_spec.rb\` files RSpec
1536
- - \`cypress/\` or \`playwright/\` → E2E testing
1537
-
1538
- **Infrastructure:**
1539
- - \`Dockerfile\` / \`docker-compose.*\` → Docker
1540
- - \`*.tf\` files → Terraform
1541
- - \`k8s/\` or \`kubernetes/\` → Kubernetes
1542
- - \`.github/workflows/\` → GitHub Actions
1543
- - \`serverless.yml\` → Serverless Framework
1544
-
1545
- ## Step 2: Populate CLAUDE.md
1546
-
1547
- Focus on what Claude Code actually needs to work effectively. Claude can explore the codebase itself — don't document what it can discover.
1548
-
1549
- **Always include:**
1550
- - **Project name + one-liner**: What is this thing?
1551
- - **Tech stack**: Runtime, framework, database, key services (so Claude uses correct patterns)
1552
- - **Commands**: How to run, test, build, deploy — Claude needs these to execute tasks
1553
- - **Non-obvious conventions**: Multi-schema databases, monorepo structure, unusual patterns Claude wouldn't infer
1554
-
1555
- **Include if relevant:**
1556
- - **Deployment flow**: If non-standard or involves multiple steps
1557
-
1558
- **Skip these — Claude can discover them:**
1559
- - Detailed project structure trees (Claude can run \`ls\` or \`tree\`)
1560
- - Exhaustive route/endpoint lists (Claude can grep)
1561
- - File-by-file descriptions (Claude can read files)
1562
- - Database model lists (Claude can read schema files)
1563
-
1564
- **Keep it tight.** A 30-line CLAUDE.md that hits the essentials beats a 200-line doc Claude has to parse every session.
1565
-
1566
- ## Step 3: Create Rules Directory
1567
-
1568
- Create an empty \`.claude/rules/\` directory. Do not create any subdirectories or rule files.
1569
-
1570
- Rules are path-scoped context files that load automatically when Claude works on matching files. Effective rules require deep understanding of your codebase patterns, team conventions, and quality goals — they should be crafted intentionally, not auto-generated.
1571
-
1572
- ## Step 4: Configure Settings
1573
-
1574
- Update \`.claude/settings.json\` using the official schema.
1575
-
1576
- ### Deny Patterns (files Claude shouldn't read/write)
1577
-
1578
- Use \`Read()\` for blocking reads, \`Edit()\` for blocking writes:
1579
-
1580
- **Always deny (security):**
1581
- \`\`\`
1582
- Read(./.env)
1583
- Read(./.env.*)
1584
- Read(./secrets/**)
1585
- Edit(./.env)
1586
- Edit(./.env.*)
1587
- \`\`\`
1588
-
1589
- **Often deny (generated/vendor):**
1590
- \`\`\`
1591
- Edit(./node_modules/**)
1592
- Edit(./dist/**)
1593
- Edit(./.git/**)
1594
- \`\`\`
1595
-
1596
- ### Allow Patterns (auto-approve without prompting)
1597
-
1598
- Use \`Bash()\` patterns with prefix matching:
1599
-
1600
- \`\`\`
1601
- Bash(npm run test:*)
1602
- Bash(npm run lint:*)
1603
- Bash(npm run build)
1604
- \`\`\`
1605
-
1606
- ### Environment Variables
1607
-
1608
- Set session-level env vars:
1609
-
1610
- \`\`\`json
1611
- {
1612
- "env": {
1613
- "NODE_ENV": "development"
1614
- }
1615
- }
1616
- \`\`\`
1617
-
1618
- **Keep it minimal** — only include patterns that actually exist in this project.
1619
-
1620
- ## Guidelines
1621
-
1622
- - Replace ALL placeholder content with real values from THIS project
1623
- - Delete sections that don't apply no empty stubs
1624
- - Optimize for Claude's efficiency, not human documentation
1625
- - When uncertain, leave it out — Claude can ask or explore
1626
-
1627
- ## After Completion
1628
-
1629
- Once autoconfig is complete, prompt the user:
1630
-
1631
- **Run \`/guide\` for an interactive walkthrough of your new Claude Code project setup.**`
1632
- },
1633
- 'commit-and-push': {
1634
- filename: 'commit-and-push.md',
1635
- content: `# Commit and Push
1636
-
1637
- Stage all changes, create a commit with a good message, and push to the current branch.
1638
-
1639
- ## Steps
1640
-
1641
- 1. Stage all changes (\`git add -A\`)
1642
- 2. Generate a conventional commit message based on the diff
1643
- 3. Commit the changes
1644
- 4. Push to the current branch
1645
-
1646
- ## Commit Message Format
1647
-
1648
- Use conventional commits: \`type(scope): description\`
1649
-
1650
- Types: feat, fix, docs, style, refactor, test, chore
1651
-
1652
- Keep the subject line under 50 chars. Add body if the change needs explanation.`
1653
- },
1654
- 'guide-cmd': {
1655
- filename: 'show-guide.md',
1656
- content: `# Show Guide
1657
-
1658
- Open the interactive guide for Claude Code Autoconfig.
1659
-
1660
- ## Step 1: Check for Changes
1661
-
1662
- Compare modification times of files in \`.claude/\` against the guide HTML.
1663
-
1664
- If any files are newer: "Syncing guide with latest changes..." → proceed to delta sync.
1665
-
1666
- ## Step 2: Delta Sync
1667
-
1668
- For each changed file, update only that entry in the guide's fileContents.
1669
-
1670
- ## Step 3: Open Guide
1671
-
1672
- Open in default browser (macOS: open, Linux: xdg-open, Windows: start).`
1673
- },
1674
- 'test': {
1675
- filename: 'test.md',
1676
- content: `# Run Tests
1677
-
1678
- Run tests for this project.
1679
-
1680
- **Scope:** $ARGUMENTS
1681
-
1682
- If no scope provided, run the full test suite. Otherwise run tests matching the scope (file, directory, or pattern).
1683
-
1684
- Detect the test command from project config (package.json scripts, pytest, go test, etc.) and execute it.`
1685
- },
1686
- 'rules': {
1687
- filename: 'rules/',
1688
- content: null,
1689
- empty: true,
1690
- emptyMessage: 'This directory is empty.\n\nAdd .md files here to define rules for specific paths in your codebase.'
1691
- },
1692
- 'guide': {
1693
- filename: 'autoconfig.guide.html',
1694
- content: null,
1695
- empty: true,
1696
- emptyMessage: "You're looking at it! 👀"
1697
- },
1698
- 'enable-retro': {
1699
- filename: 'enable-retro.md',
1700
- content: `# Enable Retro
1701
-
1702
- (Experimental) Enable tech debt tracking.
1703
-
1704
- ## What This Does
1705
-
1706
- 1. Creates \`.claude/retro/\` directory
1707
- 2. Creates \`.claude/agents/create-retro-item.md\` agent
1708
- 3. Adds Retro instructions to CLAUDE.md
1709
-
1710
- ## After Enabling
1711
-
1712
- Claude will log tech debt and improvement opportunities as structured story files:
1713
- - Problem description
1714
- - Acceptance criteria
1715
- - Suggested approach
1716
- - Priority & effort sizing
1717
- - Files involved
1718
-
1719
- Work through items: "Fix retro #001"`
1720
- },
1721
- 'feedback-template': {
1722
- filename: 'FEEDBACK.md',
1723
- content: `# Team Feedback
1724
-
1725
- Add corrections and guidance here when Claude does something wrong.
1726
- Claude reads this directory and learns for next time.
1727
-
1728
- ## YYYY-MM-DD: Brief title
1729
-
1730
- Describe what Claude did wrong and what to do instead.
1731
- Keep entries brief and actionable.
1732
-
1733
- Example:
1734
-
1735
- ## 2026-01-06: Don't use deprecated API
1736
- Claude used \`oldFunction()\` instead of \`newFunction()\`.
1737
- Always use the v2 API for user endpoints.
1738
-
1739
- ## 2026-01-07: Test database naming
1740
- Use \`test_\` prefix for test databases, not \`dev_\`.`
1741
- }
1742
- };
1743
-
1744
- const modal = document.getElementById('fileModal');
1745
- const modalTitle = document.getElementById('modalTitle');
1746
- const modalCode = document.getElementById('modalCode');
1747
- const modalClose = document.getElementById('modalClose');
1748
-
1749
- function openModal(key) {
1750
- const file = fileContents[key];
1751
- if (!file) return;
1752
-
1753
- modalTitle.textContent = file.filename;
1754
-
1755
- if (file.empty) {
1756
- modalCode.innerHTML = `<span class="modal-empty">${file.emptyMessage}</span>`;
1757
- } else {
1758
- modalCode.textContent = file.content;
1759
- }
1760
-
1761
- modal.classList.add('visible');
1762
- }
1763
-
1764
- function closeModal() {
1765
- modal.classList.remove('visible');
1766
- }
1767
-
1768
- modalClose.addEventListener('click', closeModal);
1769
- modal.addEventListener('click', (e) => {
1770
- if (e.target === modal) closeModal();
1771
- });
1772
- document.addEventListener('keydown', (e) => {
1773
- if (e.key === 'Escape' && modal.classList.contains('visible')) {
1774
- closeModal();
1775
- }
1776
- // Enter key opens preview for selected item
1777
- if (e.key === 'Enter' && !modal.classList.contains('visible')) {
1778
- const selected = document.querySelector('.tree-item.active');
1779
- if (selected) {
1780
- const key = selected.dataset.info;
1781
- if (fileContents[key]) {
1782
- openModal(key);
1783
- }
1784
- }
1785
- }
1786
- });
1787
-
1788
- // Double-click to open file preview
1789
- treeItems.forEach(item => {
1790
- item.addEventListener('dblclick', (e) => {
1791
- const key = item.dataset.info;
1792
- // Don't open modal for folders (except rules which is empty) or root
1793
- if (key === 'root' || key === 'claude-dir' || key === 'commands') return;
1794
- if (fileContents[key]) {
1795
- openModal(key);
1796
- }
1797
- });
1798
- });
1799
-
1800
- // Migration detection and toggle view
1801
- const migrationLink = document.getElementById('migrationLink');
1802
- const backToInstallLink = document.getElementById('backToInstallLink');
1803
- const showMigrationBtn = document.getElementById('showMigration');
1804
- const backToInstallBtn = document.getElementById('backToInstall');
1805
- const mainTreePanel = document.querySelector('.slide[data-slide="0"] .tree-panel:not(#migrationTreePanel)');
1806
- const migrationTreePanel = document.getElementById('migrationTreePanel');
1807
- const backupFolderName = document.getElementById('backupFolderName');
1808
- const backedUpTreeItems = document.getElementById('backedUpTreeItems');
1809
-
1810
- let migrationData = null;
1811
-
1812
- // Check for migration
1813
- async function checkMigration() {
1814
- try {
1815
- const guidePath = window.location.pathname;
1816
- const claudeDir = guidePath.substring(0, guidePath.lastIndexOf('/guide/'));
1817
- const migrationPath = claudeDir + '/migration/latest.json';
1818
-
1819
- const response = await fetch(migrationPath);
1820
- if (response.ok) {
1821
- migrationData = await response.json();
1822
- migrationLink.style.display = 'block';
1823
-
1824
- // Set backup folder name
1825
- backupFolderName.textContent = migrationData.timestamp + '/';
1826
-
1827
- // Build tree items for backed up files
1828
- const itemsHtml = migrationData.backedUpFiles.map(f => `
1829
- <div class="tree-item indent-2">
1830
- <span class="tree-spacer"></span>
1831
- <span class="tree-file-icon">📄</span>
1832
- <span class="file">${f}</span>
1833
- </div>
1834
- `).join('');
1835
- backedUpTreeItems.innerHTML = itemsHtml;
1836
- }
1837
- } catch (e) {
1838
- // No migration - that's fine
1839
- }
1840
- }
1841
-
1842
- function showMigrationView() {
1843
- mainTreePanel.style.display = 'none';
1844
- migrationTreePanel.style.display = 'flex';
1845
- migrationLink.style.display = 'none';
1846
- backToInstallLink.style.display = 'block';
1847
- }
1848
-
1849
- function showInstallView() {
1850
- migrationTreePanel.style.display = 'none';
1851
- mainTreePanel.style.display = 'flex';
1852
- backToInstallLink.style.display = 'none';
1853
- migrationLink.style.display = 'block';
1854
- }
1855
-
1856
- showMigrationBtn?.addEventListener('click', (e) => {
1857
- e.preventDefault();
1858
- showMigrationView();
1859
- });
1860
-
1861
- backToInstallBtn?.addEventListener('click', (e) => {
1862
- e.preventDefault();
1863
- showInstallView();
1864
- });
1865
-
1866
- // Check for migration on load
1867
- checkMigration();
1868
- </script>
1869
- </body>
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 Autoconfig — Walkthrough</title>
7
+ <style>
8
+ * {
9
+ margin: 0;
10
+ padding: 0;
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ :root {
15
+ --bg-primary: #0D0D0D;
16
+ --bg-secondary: #1A1A1A;
17
+ --bg-elevated: #252525;
18
+ --text-primary: #FFFFFF;
19
+ --text-secondary: #8FBBCF;
20
+ --text-dim: #6B7280;
21
+ --accent-orange: #FF9933;
22
+ --accent-blue: #5C9ECE;
23
+ --accent-cyan: #22D3EE;
24
+ --accent-green: #6ABF69;
25
+ --accent-yellow: #E5C07B;
26
+ }
27
+
28
+ body {
29
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
30
+ background: var(--bg-primary);
31
+ color: var(--text-primary);
32
+ min-height: 100vh;
33
+ overflow: hidden;
34
+ }
35
+
36
+ .container {
37
+ max-width: 900px;
38
+ margin: 0 auto;
39
+ padding: 40px 20px;
40
+ min-height: 100vh;
41
+ display: flex;
42
+ flex-direction: column;
43
+ }
44
+
45
+ /* Progress bar */
46
+ .progress-container {
47
+ display: flex;
48
+ justify-content: center;
49
+ gap: 8px;
50
+ margin-bottom: 40px;
51
+ }
52
+
53
+ .progress-dot {
54
+ width: 12px;
55
+ height: 12px;
56
+ border-radius: 50%;
57
+ background: #4a4a4a;
58
+ cursor: pointer;
59
+ transition: all 0.3s ease;
60
+ }
61
+
62
+ .progress-dot:hover {
63
+ background: #6a6a6a;
64
+ transform: scale(1.2);
65
+ }
66
+
67
+ .progress-dot.active {
68
+ background: var(--accent-green);
69
+ box-shadow: 0 0 15px rgba(106, 191, 105, 0.4);
70
+ }
71
+
72
+ /* Slides */
73
+ .slides-container {
74
+ flex: 1;
75
+ position: relative;
76
+ overflow: hidden;
77
+ }
78
+
79
+ .slide {
80
+ position: absolute;
81
+ top: 0;
82
+ left: 0;
83
+ width: 100%;
84
+ opacity: 0;
85
+ visibility: hidden;
86
+ transform: translateX(100px);
87
+ transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
88
+ pointer-events: none;
89
+ display: flex;
90
+ flex-direction: column;
91
+ }
92
+
93
+ .slide.active {
94
+ opacity: 1;
95
+ visibility: visible;
96
+ transform: translateX(0);
97
+ pointer-events: auto;
98
+ }
99
+
100
+ .slide.exit {
101
+ opacity: 0;
102
+ transform: translateX(-100px);
103
+ }
104
+
105
+ .slide-number {
106
+ font-size: 14px;
107
+ color: var(--accent-orange);
108
+ text-transform: uppercase;
109
+ letter-spacing: 2px;
110
+ margin-bottom: 12px;
111
+ }
112
+
113
+ .slide h1 {
114
+ font-size: 2.5rem;
115
+ font-weight: 700;
116
+ margin-bottom: 20px;
117
+ color: var(--text-primary);
118
+ }
119
+
120
+ .slide h2 {
121
+ font-size: 1.3rem;
122
+ font-weight: 400;
123
+ color: var(--text-secondary);
124
+ margin-bottom: 30px;
125
+ line-height: 1.6;
126
+ }
127
+
128
+ .slide-content {
129
+ flex: 1;
130
+ overflow-y: auto;
131
+ }
132
+
133
+ /* Code blocks */
134
+ .code-block {
135
+ background: var(--bg-secondary);
136
+ border: 1px solid var(--bg-elevated);
137
+ border-radius: 8px;
138
+ padding: 20px;
139
+ margin: 20px 0;
140
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Roboto', 'Noto Sans', sans-serif;
141
+ font-size: 14px;
142
+ line-height: 1.6;
143
+ overflow-x: auto;
144
+ }
145
+
146
+ .code-block .comment {
147
+ color: var(--text-dim);
148
+ }
149
+
150
+ .code-block .keyword {
151
+ color: var(--accent-orange);
152
+ }
153
+
154
+ .code-block .string {
155
+ color: var(--accent-green);
156
+ }
157
+
158
+ .code-block .property {
159
+ color: var(--accent-blue);
160
+ }
161
+
162
+ .code-block .folder {
163
+ color: var(--accent-cyan);
164
+ }
165
+
166
+ .code-block .file {
167
+ color: var(--accent-orange);
168
+ }
169
+
170
+ /* Info cards */
171
+ .info-card {
172
+ background: rgba(212, 165, 116, 0.1);
173
+ border-left: 4px solid var(--accent-orange);
174
+ border-radius: 0 8px 8px 0;
175
+ padding: 16px 20px;
176
+ margin: 20px 0;
177
+ }
178
+
179
+ .info-card.warning {
180
+ background: rgba(229, 192, 123, 0.1);
181
+ border-left-color: var(--accent-yellow);
182
+ }
183
+
184
+ .info-card h4 {
185
+ font-size: 14px;
186
+ text-transform: uppercase;
187
+ letter-spacing: 1px;
188
+ margin-bottom: 8px;
189
+ color: var(--accent-orange);
190
+ }
191
+
192
+ .info-card.warning h4 {
193
+ color: var(--accent-yellow);
194
+ }
195
+
196
+ /* Feature list */
197
+ .feature-list {
198
+ list-style: none;
199
+ margin: 20px 0;
200
+ }
201
+
202
+ .feature-list li {
203
+ padding: 14px 0;
204
+ padding-left: 28px;
205
+ position: relative;
206
+ border-bottom: 1px solid var(--bg-elevated);
207
+ display: flex;
208
+ align-items: center;
209
+ }
210
+
211
+ .feature-list li:last-child {
212
+ border-bottom: none;
213
+ }
214
+
215
+ .feature-list li::before {
216
+ content: "●";
217
+ position: absolute;
218
+ left: 0;
219
+ color: var(--text-primary);
220
+ font-size: 14px;
221
+ }
222
+
223
+ .feature-list li.blue-bullet::before {
224
+ color: var(--accent-blue);
225
+ }
226
+
227
+ .feature-list .file-name {
228
+ color: var(--accent-orange);
229
+ font-family: 'SF Mono', 'Fira Code', monospace;
230
+ font-size: 14px;
231
+ }
232
+
233
+ /* Welcome content */
234
+ .welcome-content {
235
+ display: flex;
236
+ flex-direction: column;
237
+ align-items: center;
238
+ justify-content: center;
239
+ text-align: center;
240
+ padding: 40px 20px;
241
+ }
242
+
243
+ .welcome-text {
244
+ font-size: 24px;
245
+ color: var(--text-primary);
246
+ margin-bottom: 30px;
247
+ }
248
+
249
+ .welcome-action {
250
+ background: var(--bg-secondary);
251
+ border: 1px solid var(--bg-elevated);
252
+ border-radius: 12px;
253
+ padding: 24px 32px;
254
+ max-width: 500px;
255
+ }
256
+
257
+ .welcome-action p {
258
+ font-size: 16px;
259
+ color: var(--text-secondary);
260
+ line-height: 1.6;
261
+ margin: 0;
262
+ }
263
+
264
+ .welcome-action code {
265
+ background: var(--bg-elevated);
266
+ padding: 4px 12px;
267
+ border-radius: 6px;
268
+ font-family: 'SF Mono', 'Fira Code', monospace;
269
+ font-size: 15px;
270
+ color: var(--accent-cyan);
271
+ }
272
+
273
+ /* TOC list */
274
+ .tip-banner {
275
+ display: flex;
276
+ align-items: flex-start;
277
+ gap: 12px;
278
+ padding: 16px 20px;
279
+ margin-bottom: 20px;
280
+ background: rgba(255, 153, 51, 0.1);
281
+ border: 1px solid rgba(255, 153, 51, 0.3);
282
+ border-radius: 8px;
283
+ }
284
+
285
+ .tip-icon {
286
+ font-size: 18px;
287
+ flex-shrink: 0;
288
+ }
289
+
290
+ .tip-text {
291
+ color: var(--text-secondary);
292
+ font-size: 14px;
293
+ line-height: 1.5;
294
+ }
295
+
296
+ .tip-text code {
297
+ background: var(--bg-elevated);
298
+ padding: 2px 8px;
299
+ border-radius: 4px;
300
+ font-family: 'SF Mono', 'Fira Code', monospace;
301
+ font-size: 13px;
302
+ color: var(--accent-cyan);
303
+ }
304
+
305
+ .toc-list {
306
+ list-style: none;
307
+ margin: 10px 0;
308
+ padding: 0;
309
+ }
310
+
311
+ .toc-list li {
312
+ display: flex;
313
+ align-items: center;
314
+ gap: 16px;
315
+ padding: 16px 20px;
316
+ margin: 8px 0;
317
+ background: var(--bg-secondary);
318
+ border-radius: 8px;
319
+ cursor: pointer;
320
+ transition: all 0.2s ease;
321
+ }
322
+
323
+ .toc-list li:hover {
324
+ background: var(--bg-elevated);
325
+ transform: translateX(8px);
326
+ }
327
+
328
+ .toc-number {
329
+ color: var(--accent-orange);
330
+ font-family: 'SF Mono', 'Fira Code', monospace;
331
+ font-size: 14px;
332
+ font-weight: 600;
333
+ min-width: 28px;
334
+ }
335
+
336
+ .toc-title {
337
+ color: var(--text-primary);
338
+ font-weight: 600;
339
+ font-size: 16px;
340
+ min-width: 140px;
341
+ }
342
+
343
+ .toc-desc {
344
+ color: var(--text-dim);
345
+ font-size: 14px;
346
+ }
347
+
348
+ /* Tree view */
349
+ .tree-view {
350
+ background: var(--bg-secondary);
351
+ border: 1px solid var(--bg-elevated);
352
+ border-radius: 8px;
353
+ padding: 20px;
354
+ margin: 20px 0;
355
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Roboto', 'Noto Sans', sans-serif;
356
+ font-size: 14px;
357
+ line-height: 1.5;
358
+ overflow-x: auto;
359
+ white-space: pre;
360
+ }
361
+
362
+ .tree-view .folder {
363
+ color: var(--accent-cyan);
364
+ }
365
+
366
+ .tree-view .file {
367
+ color: var(--accent-orange);
368
+ }
369
+
370
+ .tree-view .comment {
371
+ color: var(--text-dim);
372
+ }
373
+
374
+ /* Split-pane tree panel */
375
+ .tree-panel {
376
+ display: flex;
377
+ gap: 0;
378
+ background: var(--bg-secondary);
379
+ border-radius: 8px;
380
+ overflow: hidden;
381
+ height: 340px;
382
+ position: relative;
383
+ }
384
+
385
+ .tree-side {
386
+ padding: 16px;
387
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Roboto', 'Noto Sans', sans-serif;
388
+ font-size: 13px;
389
+ line-height: 1.4;
390
+ border-right: 1px solid var(--bg-elevated);
391
+ overflow-y: auto;
392
+ flex-shrink: 0;
393
+ height: 100%;
394
+ }
395
+
396
+ .tree-item {
397
+ padding: 4px 8px;
398
+ margin: 1px 0;
399
+ border-radius: 4px;
400
+ cursor: pointer;
401
+ transition: background 0.15s ease;
402
+ white-space: nowrap;
403
+ display: flex;
404
+ align-items: center;
405
+ gap: 4px;
406
+ }
407
+
408
+ .tree-item.hidden {
409
+ display: none;
410
+ }
411
+
412
+ .tree-item:hover {
413
+ background: rgba(255, 255, 255, 0.1);
414
+ }
415
+
416
+ .tree-item.active {
417
+ background: rgba(45, 105, 175, 0.5);
418
+ }
419
+
420
+ .tree-item.active:hover {
421
+ background: rgba(45, 105, 175, 0.5);
422
+ }
423
+
424
+ .tree-chevron {
425
+ width: 18px;
426
+ font-size: 18px;
427
+ color: var(--text-primary);
428
+ text-align: center;
429
+ flex-shrink: 0;
430
+ transition: transform 0.15s ease;
431
+ user-select: none;
432
+ transform: rotate(90deg);
433
+ }
434
+
435
+ .tree-item.collapsed .tree-chevron {
436
+ transform: rotate(0deg);
437
+ }
438
+
439
+ .tree-spacer {
440
+ width: 16px;
441
+ flex-shrink: 0;
442
+ }
443
+
444
+ .tree-folder-icon,
445
+ .tree-file-icon {
446
+ font-size: 14px;
447
+ flex-shrink: 0;
448
+ }
449
+
450
+ .tree-item .folder {
451
+ color: var(--text-primary);
452
+ }
453
+
454
+ .tree-item .file {
455
+ color: var(--text-secondary);
456
+ }
457
+
458
+ .tree-item.indent-1 { padding-left: 24px; }
459
+ .tree-item.indent-2 { padding-left: 44px; }
460
+ .tree-item.indent-3 { padding-left: 64px; }
461
+ .tree-item.indent-4 { padding-left: 84px; }
462
+
463
+ .tree-indent {
464
+ color: var(--text-dim);
465
+ }
466
+
467
+ .info-side {
468
+ flex: 1;
469
+ min-width: 200px;
470
+ overflow-y: auto;
471
+ }
472
+
473
+ .info-panel {
474
+ padding: 20px;
475
+ width: 100%;
476
+ box-sizing: border-box;
477
+ }
478
+
479
+ .info-panel-title {
480
+ font-size: 16px;
481
+ font-weight: 600;
482
+ color: var(--accent-orange);
483
+ margin-bottom: 12px;
484
+ }
485
+
486
+ .info-panel-desc {
487
+ font-size: 14px;
488
+ color: var(--text-secondary);
489
+ line-height: 1.6;
490
+ letter-spacing: 0.02em;
491
+ }
492
+
493
+ .info-panel-trigger {
494
+ margin-top: 16px;
495
+ padding: 8px 12px;
496
+ background: var(--bg-elevated);
497
+ border-radius: 4px;
498
+ font-family: 'SF Mono', 'Fira Code', monospace;
499
+ font-size: 13px;
500
+ color: var(--accent-cyan);
501
+ }
502
+
503
+ /* Navigation */
504
+ .nav-container {
505
+ display: flex;
506
+ justify-content: space-between;
507
+ align-items: center;
508
+ margin-top: 40px;
509
+ padding-top: 20px;
510
+ }
511
+
512
+ .nav-btn {
513
+ display: flex;
514
+ align-items: center;
515
+ gap: 8px;
516
+ padding: 14px 28px;
517
+ border: none;
518
+ border-radius: 8px;
519
+ font-size: 16px;
520
+ font-weight: 500;
521
+ cursor: pointer;
522
+ transition: all 0.3s ease;
523
+ }
524
+
525
+ .nav-btn.prev {
526
+ background: var(--bg-elevated);
527
+ color: var(--text-secondary);
528
+ }
529
+
530
+ .nav-btn.prev:hover:not(:disabled) {
531
+ background: var(--bg-secondary);
532
+ color: var(--text-primary);
533
+ }
534
+
535
+ .nav-btn.next {
536
+ background: var(--accent-orange);
537
+ color: var(--bg-primary);
538
+ }
539
+
540
+ .nav-btn.next:hover:not(:disabled) {
541
+ transform: translateY(-2px);
542
+ box-shadow: 0 10px 30px rgba(212, 165, 116, 0.3);
543
+ }
544
+
545
+ .nav-btn:disabled {
546
+ opacity: 0.3;
547
+ cursor: not-allowed;
548
+ transform: none !important;
549
+ }
550
+
551
+ .nav-hint {
552
+ color: var(--text-dim);
553
+ font-size: 14px;
554
+ }
555
+
556
+ .nav-hint kbd {
557
+ background: var(--bg-elevated);
558
+ padding: 4px 8px;
559
+ border-radius: 4px;
560
+ font-family: inherit;
561
+ margin: 0 2px;
562
+ }
563
+
564
+ /* Table */
565
+ .table-container {
566
+ overflow-x: auto;
567
+ margin: 20px 0;
568
+ }
569
+
570
+ table {
571
+ width: 100%;
572
+ border-collapse: collapse;
573
+ }
574
+
575
+ th, td {
576
+ padding: 12px 16px;
577
+ text-align: left;
578
+ border-bottom: 1px solid var(--bg-elevated);
579
+ }
580
+
581
+ th {
582
+ color: var(--accent-blue);
583
+ font-size: 12px;
584
+ text-transform: uppercase;
585
+ letter-spacing: 1px;
586
+ }
587
+
588
+ td {
589
+ font-size: 14px;
590
+ }
591
+
592
+ td code {
593
+ background: var(--bg-secondary);
594
+ color: var(--accent-orange);
595
+ padding: 2px 8px;
596
+ border-radius: 4px;
597
+ font-family: 'SF Mono', 'Fira Code', monospace;
598
+ font-size: 13px;
599
+ }
600
+
601
+ /* Animations */
602
+ @keyframes fadeInUp {
603
+ from {
604
+ opacity: 0;
605
+ transform: translateY(20px);
606
+ }
607
+ to {
608
+ opacity: 1;
609
+ transform: translateY(0);
610
+ }
611
+ }
612
+
613
+ .slide.active .slide-number { animation: fadeIn 0.4s ease both; }
614
+ .slide.active h1 { animation: fadeIn 0.4s ease 0.1s both; }
615
+ .slide.active h2 { animation: none; }
616
+ .slide.active .slide-content > ul,
617
+ .slide.active .slide-content > div { animation: fadeIn 0.5s ease 0.3s both; }
618
+
619
+ @keyframes fadeIn {
620
+ from { opacity: 0; }
621
+ to { opacity: 1; }
622
+ }
623
+
624
+ /* Typewriter effect */
625
+ .typewriter {
626
+ border-right: 2px solid var(--bg-primary);
627
+ animation: none !important;
628
+ }
629
+
630
+ .typewriter.typing {
631
+ animation: blink-caret 0.75s step-end infinite !important;
632
+ }
633
+
634
+ .typewriter.done {
635
+ border-right: none !important;
636
+ animation: none !important;
637
+ }
638
+
639
+ @keyframes blink-caret {
640
+ from, to { border-color: var(--bg-primary); }
641
+ 50% { border-color: transparent; }
642
+ }
643
+
644
+ /* Scrollbar */
645
+ ::-webkit-scrollbar {
646
+ width: 8px;
647
+ }
648
+
649
+ ::-webkit-scrollbar-track {
650
+ background: var(--bg-secondary);
651
+ border-radius: 4px;
652
+ }
653
+
654
+ ::-webkit-scrollbar-thumb {
655
+ background: var(--bg-elevated);
656
+ border-radius: 4px;
657
+ }
658
+
659
+ ::-webkit-scrollbar-thumb:hover {
660
+ background: var(--text-dim);
661
+ }
662
+
663
+ /* Logo */
664
+ .logo {
665
+ font-size: 24px;
666
+ margin-bottom: 8px;
667
+ }
668
+
669
+ /* Final slide special */
670
+ .final-links {
671
+ display: flex;
672
+ gap: 16px;
673
+ margin-top: 30px;
674
+ flex-wrap: wrap;
675
+ }
676
+
677
+ .final-link {
678
+ display: inline-flex;
679
+ align-items: center;
680
+ gap: 8px;
681
+ padding: 12px 24px;
682
+ background: var(--bg-elevated);
683
+ border-radius: 8px;
684
+ color: var(--text-secondary);
685
+ text-decoration: none;
686
+ transition: all 0.3s ease;
687
+ }
688
+
689
+ .final-link:hover {
690
+ background: var(--bg-secondary);
691
+ color: var(--accent-orange);
692
+ transform: translateY(-2px);
693
+ }
694
+
695
+ /* File Preview Modal */
696
+ .modal-overlay {
697
+ position: fixed;
698
+ top: 0;
699
+ left: 0;
700
+ right: 0;
701
+ bottom: 0;
702
+ background: rgba(0, 0, 0, 0.85);
703
+ display: none;
704
+ justify-content: center;
705
+ align-items: center;
706
+ z-index: 1000;
707
+ padding: 40px;
708
+ opacity: 0;
709
+ transition: opacity 0.2s ease;
710
+ }
711
+
712
+ .modal-overlay.visible {
713
+ display: flex;
714
+ opacity: 1;
715
+ }
716
+
717
+ .modal-content {
718
+ background: var(--bg-secondary);
719
+ border: 1px solid var(--bg-elevated);
720
+ border-radius: 12px;
721
+ max-width: 800px;
722
+ width: 100%;
723
+ max-height: 80vh;
724
+ display: flex;
725
+ flex-direction: column;
726
+ transform: scale(0.95);
727
+ transition: transform 0.2s ease;
728
+ }
729
+
730
+ .modal-overlay.visible .modal-content {
731
+ transform: scale(1);
732
+ }
733
+
734
+ .modal-header {
735
+ display: flex;
736
+ justify-content: space-between;
737
+ align-items: center;
738
+ padding: 16px 20px;
739
+ border-bottom: 1px solid var(--bg-elevated);
740
+ }
741
+
742
+ .modal-title {
743
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Roboto', 'Noto Sans', sans-serif;
744
+ font-size: 14px;
745
+ color: var(--accent-orange);
746
+ }
747
+
748
+ .modal-close {
749
+ background: none;
750
+ border: none;
751
+ color: var(--text-dim);
752
+ font-size: 24px;
753
+ cursor: pointer;
754
+ padding: 0;
755
+ line-height: 1;
756
+ transition: color 0.2s ease;
757
+ }
758
+
759
+ .modal-close:hover {
760
+ color: var(--text-primary);
761
+ }
762
+
763
+ .modal-body {
764
+ padding: 20px;
765
+ overflow-y: auto;
766
+ flex: 1;
767
+ }
768
+
769
+ .modal-body pre {
770
+ margin: 0;
771
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Roboto', 'Noto Sans', sans-serif;
772
+ font-size: 13px;
773
+ line-height: 1.6;
774
+ color: var(--text-secondary);
775
+ white-space: pre-wrap;
776
+ word-wrap: break-word;
777
+ }
778
+
779
+ .modal-body .comment { color: var(--text-dim); }
780
+ .modal-body .keyword { color: var(--accent-orange); }
781
+ .modal-body .string { color: var(--accent-green); }
782
+ .modal-body .property { color: var(--accent-blue); }
783
+
784
+ .modal-empty {
785
+ color: var(--text-dim);
786
+ font-style: italic;
787
+ text-align: center;
788
+ padding: 40px;
789
+ }
790
+ </style>
791
+ </head>
792
+ <body>
793
+ <!-- File Preview Modal -->
794
+ <div class="modal-overlay" id="fileModal">
795
+ <div class="modal-content">
796
+ <div class="modal-header">
797
+ <span class="modal-title" id="modalTitle">filename.md</span>
798
+ <button class="modal-close" id="modalClose">&times;</button>
799
+ </div>
800
+ <div class="modal-body">
801
+ <pre id="modalCode"></pre>
802
+ </div>
803
+ </div>
804
+ </div>
805
+
806
+ <div class="container">
807
+ <div class="progress-container" id="progress"></div>
808
+
809
+ <div class="slides-container">
810
+ <!-- Slide 0: What Got Installed -->
811
+ <div class="slide active" data-slide="0">
812
+ <div class="slide-number">01 / Overview</div>
813
+ <h1>✨ Autoconfig Complete</h1>
814
+ <h2 class="typewriter" data-text="Here's what got installed. Hover over any file or folder to learn what it does."></h2>
815
+ <div class="slide-content">
816
+ <div class="tree-panel">
817
+ <div class="tree-side">
818
+ <div class="tree-item folder-row" data-info="root" data-folder="root">
819
+ <span class="tree-chevron">›</span>
820
+ <span class="tree-folder-icon">📁</span>
821
+ <span class="folder">your-project</span>
822
+ </div>
823
+ <div class="tree-item indent-1 folder-row collapsed" data-info="claude-dir" data-folder="claude-dir" data-parent="root">
824
+ <span class="tree-chevron">›</span>
825
+ <span class="tree-folder-icon">📁</span>
826
+ <span class="folder">.claude</span>
827
+ </div>
828
+ <div class="tree-item indent-2 folder-row hidden collapsed" data-info="commands" data-folder="commands" data-parent="claude-dir">
829
+ <span class="tree-chevron">›</span>
830
+ <span class="tree-folder-icon">📁</span>
831
+ <span class="folder">commands</span>
832
+ </div>
833
+ <div class="tree-item indent-3 hidden" data-info="autoconfig" data-parent="commands">
834
+ <span class="tree-spacer"></span>
835
+ <span class="tree-file-icon">📄</span>
836
+ <span class="file">autoconfig.md</span>
837
+ </div>
838
+ <div class="tree-item indent-3 hidden" data-info="commit-and-push" data-parent="commands">
839
+ <span class="tree-spacer"></span>
840
+ <span class="tree-file-icon">📄</span>
841
+ <span class="file">commit-and-push.md</span>
842
+ </div>
843
+ <div class="tree-item indent-3 hidden" data-info="enable-retro" data-parent="commands">
844
+ <span class="tree-spacer"></span>
845
+ <span class="tree-file-icon">📄</span>
846
+ <span class="file">enable-retro.md</span>
847
+ </div>
848
+ <div class="tree-item indent-3 hidden" data-info="guide-cmd" data-parent="commands">
849
+ <span class="tree-spacer"></span>
850
+ <span class="tree-file-icon">📄</span>
851
+ <span class="file">show-guide.md</span>
852
+ </div>
853
+ <div class="tree-item indent-3 hidden" data-info="sync-claude-md" data-parent="commands">
854
+ <span class="tree-spacer"></span>
855
+ <span class="tree-file-icon">📄</span>
856
+ <span class="file">sync-claude-md.md</span>
857
+ </div>
858
+ <div class="tree-item indent-3 hidden" data-info="test" data-parent="commands">
859
+ <span class="tree-spacer"></span>
860
+ <span class="tree-file-icon">📄</span>
861
+ <span class="file">test.md</span>
862
+ </div>
863
+ <div class="tree-item indent-2 folder-row hidden collapsed" data-info="feedback" data-folder="feedback" data-parent="claude-dir">
864
+ <span class="tree-chevron">›</span>
865
+ <span class="tree-folder-icon">📁</span>
866
+ <span class="folder">feedback</span>
867
+ </div>
868
+ <div class="tree-item indent-3 hidden" data-info="feedback-template" data-parent="feedback">
869
+ <span class="tree-spacer"></span>
870
+ <span class="tree-file-icon">📄</span>
871
+ <span class="file">FEEDBACK.md</span>
872
+ </div>
873
+ <div class="tree-item indent-2 folder-row hidden collapsed" data-info="guide" data-folder="guide-folder" data-parent="claude-dir">
874
+ <span class="tree-chevron">›</span>
875
+ <span class="tree-folder-icon">📁</span>
876
+ <span class="folder">guide</span>
877
+ </div>
878
+ <div class="tree-item indent-3 hidden" data-info="guide" data-parent="guide-folder">
879
+ <span class="tree-spacer"></span>
880
+ <span class="tree-file-icon">🌐</span>
881
+ <span class="file">autoconfig.guide.html</span>
882
+ </div>
883
+ <div class="tree-item indent-2 hidden" data-info="rules" data-parent="claude-dir">
884
+ <span class="tree-spacer"></span>
885
+ <span class="tree-folder-icon">📁</span>
886
+ <span class="folder">rules</span>
887
+ </div>
888
+ <div class="tree-item indent-2 hidden" data-info="mcp" data-parent="claude-dir">
889
+ <span class="tree-spacer"></span>
890
+ <span class="tree-file-icon">🔌</span>
891
+ <span class="file">.mcp.json</span>
892
+ </div>
893
+ <div class="tree-item indent-2 hidden" data-info="settings" data-parent="claude-dir">
894
+ <span class="tree-spacer"></span>
895
+ <span class="tree-file-icon">⚙️</span>
896
+ <span class="file">settings.json</span>
897
+ </div>
898
+ <div class="tree-item indent-1" data-info="claude-md" data-parent="root">
899
+ <span class="tree-spacer"></span>
900
+ <span class="tree-file-icon">📄</span>
901
+ <span class="file">CLAUDE.md</span>
902
+ </div>
903
+ </div>
904
+ <div class="info-side">
905
+ <div class="info-panel" id="infoPanel">
906
+ <div class="info-panel-title">Select a file</div>
907
+ <div class="info-panel-desc">Hover over any item in the tree to see what it does.</div>
908
+ </div>
909
+ </div>
910
+ </div>
911
+ </div>
912
+ </div>
913
+
914
+ <!-- Slide 1: Finale -->
915
+ <div class="slide" data-slide="1">
916
+ <div class="slide-number">02 / You're Ready</div>
917
+ <h1>That's It</h1>
918
+ <h2 class="typewriter" data-text="You've got the autoconfig. Now go build something."></h2>
919
+ <div class="slide-content">
920
+ <div class="final-links">
921
+ <a href="https://github.com/design-and-deliver/claude-code-autoconfig" class="final-link" target="_blank">
922
+ Star on GitHub
923
+ </a>
924
+ <a href="https://docs.anthropic.com/en/docs/claude-code/overview" class="final-link" target="_blank">
925
+ 📚 Claude Code Docs
926
+ </a>
927
+ </div>
928
+ </div>
929
+ </div>
930
+ </div>
931
+
932
+ <div class="nav-container">
933
+ <button class="nav-btn prev" id="prevBtn">
934
+ Back
935
+ </button>
936
+ <button class="nav-btn next" id="nextBtn">
937
+ Next
938
+ </button>
939
+ </div>
940
+ </div>
941
+
942
+ <script>
943
+ const slides = document.querySelectorAll('.slide');
944
+ const progressContainer = document.getElementById('progress');
945
+ const prevBtn = document.getElementById('prevBtn');
946
+ const nextBtn = document.getElementById('nextBtn');
947
+ let currentSlide = 0;
948
+
949
+ // Create progress dots
950
+ slides.forEach((_, i) => {
951
+ const dot = document.createElement('div');
952
+ dot.className = 'progress-dot' + (i === 0 ? ' active' : '');
953
+ dot.addEventListener('click', () => goToSlide(i));
954
+ progressContainer.appendChild(dot);
955
+ });
956
+
957
+ function updateProgress() {
958
+ document.querySelectorAll('.progress-dot').forEach((dot, i) => {
959
+ dot.classList.remove('active');
960
+ if (i === currentSlide) dot.classList.add('active');
961
+ });
962
+ }
963
+
964
+ function goToSlide(index) {
965
+ if (index < 0 || index >= slides.length) return;
966
+
967
+ const direction = index > currentSlide ? 1 : -1;
968
+
969
+ slides[currentSlide].classList.remove('active');
970
+ if (direction > 0) {
971
+ slides[currentSlide].classList.add('exit');
972
+ }
973
+
974
+ currentSlide = index;
975
+
976
+ slides.forEach(s => s.classList.remove('exit'));
977
+ slides[currentSlide].classList.add('active');
978
+
979
+ updateProgress();
980
+ updateButtons();
981
+ checkTypewriter();
982
+
983
+ // Select CLAUDE.md by default when entering slide 0 (tree view)
984
+ if (currentSlide === 0) {
985
+ setTimeout(() => selectTreeItemByKey('claude-md'), 100);
986
+ }
987
+ }
988
+
989
+ function updateButtons() {
990
+ // Hide back button on first slide, show on others
991
+ prevBtn.style.visibility = currentSlide === 0 ? 'hidden' : 'visible';
992
+
993
+ if (currentSlide === slides.length - 1) {
994
+ nextBtn.textContent = 'Done';
995
+ } else {
996
+ nextBtn.textContent = 'Next';
997
+ }
998
+ }
999
+
1000
+ prevBtn.addEventListener('click', () => {
1001
+ if (currentSlide > 0) {
1002
+ goToSlide(currentSlide - 1);
1003
+ }
1004
+ });
1005
+
1006
+ nextBtn.addEventListener('click', () => {
1007
+ if (currentSlide < slides.length - 1) {
1008
+ goToSlide(currentSlide + 1);
1009
+ } else {
1010
+ window.close();
1011
+ }
1012
+ });
1013
+
1014
+ // Select CLAUDE.md on initial page load
1015
+ setTimeout(() => selectTreeItemByKey('claude-md'), 300);
1016
+
1017
+ // Keyboard navigation for slides
1018
+ document.addEventListener('keydown', (e) => {
1019
+ // On slide 0, arrow keys control tree - use spacebar for next slide
1020
+ if (currentSlide === 0) {
1021
+ if (e.key === ' ') {
1022
+ e.preventDefault();
1023
+ if (currentSlide < slides.length - 1) {
1024
+ goToSlide(currentSlide + 1);
1025
+ }
1026
+ }
1027
+ return; // Let tree keyboard handler deal with arrows
1028
+ }
1029
+
1030
+ // Space bar for next slide (but not on slide 0 with tree)
1031
+ if (e.key === ' ' && currentSlide !== 0) {
1032
+ e.preventDefault();
1033
+ if (currentSlide < slides.length - 1) {
1034
+ goToSlide(currentSlide + 1);
1035
+ }
1036
+ }
1037
+ });
1038
+
1039
+ updateButtons();
1040
+
1041
+ // Auto-focus for keyboard navigation
1042
+ document.body.setAttribute('tabindex', '0');
1043
+ document.body.focus();
1044
+
1045
+ // Detect project name from file path
1046
+ function getProjectName() {
1047
+ try {
1048
+ const path = window.location.pathname;
1049
+ const parts = path.split('/').filter(p => p && !p.includes(':'));
1050
+ const claudeIndex = parts.indexOf('.claude');
1051
+ if (claudeIndex > 0) {
1052
+ return parts[claudeIndex - 1];
1053
+ }
1054
+ if (parts.length >= 3) {
1055
+ return parts[parts.length - 3];
1056
+ }
1057
+ } catch (e) {}
1058
+ return 'your-project';
1059
+ }
1060
+
1061
+ const projectName = getProjectName();
1062
+
1063
+ // Update tree root with actual project name
1064
+ const rootItem = document.querySelector('[data-info="root"]');
1065
+ if (rootItem) {
1066
+ rootItem.querySelector('.folder').textContent = projectName + '/';
1067
+ }
1068
+
1069
+ // Calculate tree side width dynamically
1070
+ function setTreeWidth() {
1071
+ const treeSide = document.querySelector('.tree-side');
1072
+ const treeItems = document.querySelectorAll('.tree-item');
1073
+ if (!treeSide || !treeItems.length) return;
1074
+
1075
+ const hiddenItems = [];
1076
+ treeItems.forEach(item => {
1077
+ if (item.classList.contains('hidden')) {
1078
+ hiddenItems.push(item);
1079
+ item.style.visibility = 'hidden';
1080
+ item.style.position = 'absolute';
1081
+ item.classList.remove('hidden');
1082
+ }
1083
+ });
1084
+
1085
+ let maxWidth = 0;
1086
+ treeItems.forEach(item => {
1087
+ const width = item.scrollWidth;
1088
+ if (width > maxWidth) maxWidth = width;
1089
+ });
1090
+
1091
+ hiddenItems.forEach(item => {
1092
+ item.classList.add('hidden');
1093
+ item.style.visibility = '';
1094
+ item.style.position = '';
1095
+ });
1096
+
1097
+ treeSide.style.width = (maxWidth + 32) + 'px';
1098
+ treeSide.style.padding = '16px 8px';
1099
+ }
1100
+
1101
+ if (document.fonts && document.fonts.ready) {
1102
+ document.fonts.ready.then(setTreeWidth);
1103
+ } else {
1104
+ setTimeout(setTreeWidth, 100);
1105
+ }
1106
+
1107
+ // Typewriter effect
1108
+ function typeWriter(element) {
1109
+ const text = element.dataset.text;
1110
+ if (!text) return;
1111
+
1112
+ element.textContent = '';
1113
+ element.classList.add('typing');
1114
+ element.classList.remove('done');
1115
+
1116
+ let i = 0;
1117
+ const speed = 30;
1118
+
1119
+ function type() {
1120
+ if (i < text.length) {
1121
+ element.textContent += text.charAt(i);
1122
+ i++;
1123
+ setTimeout(type, speed);
1124
+ } else {
1125
+ element.classList.remove('typing');
1126
+ element.classList.add('done');
1127
+ }
1128
+ }
1129
+
1130
+ setTimeout(type, 300);
1131
+ }
1132
+
1133
+ function checkTypewriter() {
1134
+ const activeSlide = slides[currentSlide];
1135
+ const typewriterEl = activeSlide.querySelector('.typewriter');
1136
+ if (typewriterEl) {
1137
+ typeWriter(typewriterEl);
1138
+ }
1139
+ }
1140
+
1141
+ setTimeout(checkTypewriter, 100);
1142
+
1143
+ // Tree panel info data - UPDATED
1144
+ const treeInfo = {
1145
+ 'root': {
1146
+ title: projectName,
1147
+ desc: 'The autoconfig adds CLAUDE.md at your project root and configuration files inside a .claude/ directory. Nothing else is touched.'
1148
+ },
1149
+ 'claude-md': {
1150
+ title: 'CLAUDE.md',
1151
+ desc: 'The entry point — Claude reads this at the start of every session. Contains project context populated by autoconfig to optimize how Claude processes requests.<br><br><span style="color: var(--accent-orange);">⚠️ Managed by Claude — do not edit manually.</span>',
1152
+ trigger: 'Loaded automatically at session start'
1153
+ },
1154
+ 'claude-dir': {
1155
+ title: '.claude/ Directory',
1156
+ desc: 'Commands, rules, settings, and this guide. Keeps configuration organized as your project grows.'
1157
+ },
1158
+ 'settings': {
1159
+ title: 'settings.json',
1160
+ desc: 'Permissions, security, and hooks. Controls which commands Claude can run and which files it can access.',
1161
+ trigger: 'Claude Code loads this automatically at the start of every session'
1162
+ },
1163
+ 'mcp': {
1164
+ title: '.mcp.json',
1165
+ desc: 'MCP (Model Context Protocol) server configuration. Add your MCP server configs here when you\'re ready.<br><br>See <a href="https://docs.anthropic.com/en/docs/claude-code/mcp" target="_blank" style="color: var(--accent-cyan);">MCP documentation</a> for setup instructions.'
1166
+ },
1167
+ 'commands': {
1168
+ title: 'commands/',
1169
+ desc: 'On-demand workflows you trigger with <code>/name</code>. Each .md file becomes a <a href="https://docs.anthropic.com/en/docs/claude-code/slash-commands" target="_blank" style="color: var(--accent-cyan);">slash command</a>.'
1170
+ },
1171
+ 'enable-retro': {
1172
+ title: 'enable-retro.md',
1173
+ desc: '(Experimental) Enables tech debt tracking. Creates <code>.claude/retro/</code> directory and configures Claude to log improvement opportunities as structured story files.',
1174
+ trigger: '/enable-retro'
1175
+ },
1176
+ 'feedback': {
1177
+ title: 'feedback/',
1178
+ desc: 'Team-maintained corrections and guidance for Claude. Add notes here when Claude does something wrong — it learns for next time. This directory persists across <code>/autoconfig</code> runs.'
1179
+ },
1180
+ 'feedback-template': {
1181
+ title: 'FEEDBACK.md',
1182
+ desc: 'Starter template for team feedback. Add dated entries when Claude makes mistakes — include what went wrong and the correct approach. Claude reads this on every session.'
1183
+ },
1184
+ 'autoconfig': {
1185
+ title: 'autoconfig.md',
1186
+ desc: 'The command you just ran. Analyzes your project and populates CLAUDE.md with real context. Re-run anytime your stack changes.',
1187
+ trigger: '/autoconfig'
1188
+ },
1189
+ 'sync-claude-md': {
1190
+ title: 'sync-claude-md.md',
1191
+ desc: 'Re-analyzes your project and updates CLAUDE.md to reflect current state. Run when your stack changes significantly.',
1192
+ trigger: '/sync-claude-md'
1193
+ },
1194
+ 'guide-cmd': {
1195
+ title: 'show-guide.md',
1196
+ desc: 'Opens this interactive guide in your browser. Auto-syncs any changed files before opening.',
1197
+ trigger: '/show-guide'
1198
+ },
1199
+ 'test': {
1200
+ title: 'test.md',
1201
+ desc: 'Runs your test suite. Auto-detects Jest, Vitest, Pytest, Go, RSpec, or falls back to npm test.',
1202
+ trigger: '/test'
1203
+ },
1204
+ 'commit-and-push': {
1205
+ title: 'commit-and-push.md',
1206
+ desc: 'Stages all changes, generates a conventional commit message from the diff, commits, and pushes. One command, full workflow.',
1207
+ trigger: '/commit-and-push'
1208
+ },
1209
+ 'rules': {
1210
+ title: 'rules/',
1211
+ desc: 'Path-scoped context that loads when Claude works on matching files. Optimized rules are based on your project\'s needs, patterns and practices.<br><br><div style="background: var(--bg-elevated); border: 1px solid var(--accent-cyan); border-radius: 8px; padding: 16px; margin-top: 8px;"><strong style="color: var(--accent-orange);">Want optimized rules for your project?</strong><br>Reach out: <a href="mailto:info@adac1001.com" style="color: var(--accent-cyan);">info@adac1001.com</a></div>'
1212
+ },
1213
+ 'guide': {
1214
+ title: 'guide/autoconfig.guide.html',
1215
+ desc: 'This interactive guide. Open it anytime to review what each file does.',
1216
+ trigger: '/show-guide'
1217
+ }
1218
+ };
1219
+
1220
+ // Tree panel hover handling
1221
+ const infoPanel = document.getElementById('infoPanel');
1222
+ const treeItems = document.querySelectorAll('.tree-item');
1223
+
1224
+ let selectedInfoKey = 'claude-md'; // Default selection
1225
+
1226
+ function showInfo(key) {
1227
+ const info = treeInfo[key];
1228
+ if (info) {
1229
+ let html = `<div class="info-panel-title">${info.title}</div>`;
1230
+ html += `<div class="info-panel-desc">${info.desc}</div>`;
1231
+ if (info.trigger) {
1232
+ html += `<div class="info-panel-trigger">${info.trigger}</div>`;
1233
+ }
1234
+ infoPanel.innerHTML = html;
1235
+ }
1236
+ }
1237
+
1238
+ treeItems.forEach((item, idx) => {
1239
+ // Hover updates info panel only (preview)
1240
+ item.addEventListener('mouseenter', () => {
1241
+ const key = item.dataset.info;
1242
+ showInfo(key);
1243
+ });
1244
+
1245
+ // Mouseleave restores selected item's info
1246
+ item.addEventListener('mouseleave', () => {
1247
+ showInfo(selectedInfoKey);
1248
+ });
1249
+
1250
+ // Click sets active selection
1251
+ item.addEventListener('click', (e) => {
1252
+ // Don't select if clicking on a folder chevron (let toggle handle it)
1253
+ if (e.target.classList.contains('tree-chevron')) return;
1254
+
1255
+ treeItems.forEach(i => i.classList.remove('active'));
1256
+ item.classList.add('active');
1257
+
1258
+ // Update selected info key
1259
+ selectedInfoKey = item.dataset.info;
1260
+ showInfo(selectedInfoKey);
1261
+
1262
+ // Sync selectedTreeIndex with visible items
1263
+ const visibleItems = Array.from(document.querySelectorAll('.tree-item:not(.hidden)'));
1264
+ selectedTreeIndex = visibleItems.indexOf(item);
1265
+ });
1266
+ });
1267
+
1268
+ // Folder collapse/expand handling
1269
+ function toggleFolder(folderId, collapsed) {
1270
+ const children = document.querySelectorAll(`[data-parent="${folderId}"]`);
1271
+ children.forEach(child => {
1272
+ if (collapsed) {
1273
+ child.classList.add('hidden');
1274
+ } else {
1275
+ child.classList.remove('hidden');
1276
+ if (child.dataset.folder && !child.classList.contains('collapsed')) {
1277
+ toggleFolder(child.dataset.folder, false);
1278
+ }
1279
+ }
1280
+ if (collapsed && child.dataset.folder) {
1281
+ toggleFolder(child.dataset.folder, true);
1282
+ }
1283
+ });
1284
+ }
1285
+
1286
+ document.querySelectorAll('.folder-row').forEach(folder => {
1287
+ folder.addEventListener('click', (e) => {
1288
+ const folderId = folder.dataset.folder;
1289
+ const isCollapsed = folder.classList.toggle('collapsed');
1290
+ toggleFolder(folderId, isCollapsed);
1291
+ });
1292
+ });
1293
+
1294
+ // Tree keyboard navigation
1295
+ let selectedTreeIndex = -1;
1296
+
1297
+ function getVisibleTreeItems() {
1298
+ return Array.from(document.querySelectorAll('.tree-item:not(.hidden)'));
1299
+ }
1300
+
1301
+ function selectTreeItemByKey(key) {
1302
+ const item = document.querySelector(`.tree-item[data-info="${key}"]`);
1303
+ if (!item) return;
1304
+
1305
+ treeItems.forEach(i => i.classList.remove('active'));
1306
+ item.classList.add('active');
1307
+
1308
+ selectedInfoKey = key;
1309
+ showInfo(selectedInfoKey);
1310
+
1311
+ // Update selectedTreeIndex
1312
+ const visibleItems = getVisibleTreeItems();
1313
+ selectedTreeIndex = visibleItems.indexOf(item);
1314
+ }
1315
+
1316
+ function selectTreeItem(index) {
1317
+ const items = getVisibleTreeItems();
1318
+ if (index < 0 || index >= items.length) return;
1319
+
1320
+ treeItems.forEach(i => i.classList.remove('active'));
1321
+
1322
+ selectedTreeIndex = index;
1323
+ const item = items[index];
1324
+ item.classList.add('active');
1325
+
1326
+ item.scrollIntoView({ block: 'nearest' });
1327
+
1328
+ selectedInfoKey = item.dataset.info;
1329
+ showInfo(selectedInfoKey);
1330
+ }
1331
+
1332
+ document.addEventListener('keydown', (e) => {
1333
+ if (currentSlide !== 0) return;
1334
+
1335
+ const items = getVisibleTreeItems();
1336
+ if (items.length === 0) return;
1337
+
1338
+ if (selectedTreeIndex === -1) {
1339
+ selectTreeItem(0);
1340
+ if (e.key === 'ArrowDown' || e.key === 'ArrowUp' || e.key === 'ArrowRight' || e.key === 'ArrowLeft') {
1341
+ e.preventDefault();
1342
+ }
1343
+ return;
1344
+ }
1345
+
1346
+ if (e.key === 'ArrowDown') {
1347
+ e.preventDefault();
1348
+ if (selectedTreeIndex < items.length - 1) {
1349
+ selectTreeItem(selectedTreeIndex + 1);
1350
+ }
1351
+ } else if (e.key === 'ArrowUp') {
1352
+ e.preventDefault();
1353
+ if (selectedTreeIndex > 0) {
1354
+ selectTreeItem(selectedTreeIndex - 1);
1355
+ }
1356
+ } else if (e.key === 'ArrowRight') {
1357
+ e.preventDefault();
1358
+ const item = items[selectedTreeIndex];
1359
+ if (item && item.classList.contains('folder-row')) {
1360
+ if (item.classList.contains('collapsed')) {
1361
+ item.classList.remove('collapsed');
1362
+ toggleFolder(item.dataset.folder, false);
1363
+ }
1364
+ }
1365
+ } else if (e.key === 'ArrowLeft') {
1366
+ e.preventDefault();
1367
+ const item = items[selectedTreeIndex];
1368
+ if (item && item.classList.contains('folder-row')) {
1369
+ if (!item.classList.contains('collapsed')) {
1370
+ item.classList.add('collapsed');
1371
+ toggleFolder(item.dataset.folder, true);
1372
+ }
1373
+ }
1374
+ } else if (e.key === 'Enter') {
1375
+ e.preventDefault();
1376
+ const item = items[selectedTreeIndex];
1377
+ if (item && item.classList.contains('folder-row')) {
1378
+ const isCollapsed = item.classList.toggle('collapsed');
1379
+ toggleFolder(item.dataset.folder, isCollapsed);
1380
+ }
1381
+ }
1382
+ });
1383
+
1384
+ // File Preview Modal
1385
+ const fileContents = {
1386
+ 'claude-md': {
1387
+ filename: 'CLAUDE.md',
1388
+ content: `# Project Name
1389
+
1390
+ > Run \`/autoconfig\` to populate this based on your project.`
1391
+ },
1392
+ 'settings': {
1393
+ filename: 'settings.json',
1394
+ content: `{
1395
+ "permissions": {
1396
+ "allow": [
1397
+ "Read(./**)",
1398
+ "Edit(./**)",
1399
+ "Write(./**)",
1400
+ "Bash(npm run dev)",
1401
+ "Bash(npm run build)",
1402
+ "Bash(npm run test)",
1403
+ "Bash(git status)",
1404
+ "Bash(git diff:*)",
1405
+ "Bash(git add:*)",
1406
+ "Bash(git commit:*)",
1407
+ "Bash(git push:*)"
1408
+ ],
1409
+ "deny": [
1410
+ "Read(./.env)",
1411
+ "Read(./.env.*)",
1412
+ "Read(./secrets/**)"
1413
+ ]
1414
+ },
1415
+ "hooks": {
1416
+ "PostToolUse": [{
1417
+ "matcher": "Edit|Write",
1418
+ "hooks": [{
1419
+ "type": "command",
1420
+ "command": "// Auto-refresh guide when .claude/ changes"
1421
+ }]
1422
+ }]
1423
+ }
1424
+ }`
1425
+ },
1426
+ 'mcp': {
1427
+ filename: '.mcp.json',
1428
+ content: `{
1429
+ "mcpServers": {}
1430
+ }
1431
+
1432
+ // Add your MCP server configs here when you're ready.
1433
+ // See: https://docs.anthropic.com/en/docs/claude-code/mcp`
1434
+ },
1435
+ 'autoconfig': {
1436
+ filename: 'autoconfig.md',
1437
+ content: `# Autoconfig
1438
+
1439
+ Analyze this project and configure Claude Code with real context.
1440
+
1441
+ ## Step 1: Scan the Project
1442
+
1443
+ Look for these indicators to understand the project:
1444
+
1445
+ **Package/Config Files:**
1446
+ - \`package.json\` Node.js, npm scripts, dependencies
1447
+ - \`requirements.txt\` / \`pyproject.toml\` / \`setup.py\` → Python
1448
+ - \`Cargo.toml\` → Rust
1449
+ - \`go.mod\` Go
1450
+ - \`Gemfile\` → Ruby
1451
+ - \`pom.xml\` / \`build.gradle\` Java
1452
+ - \`*.csproj\` / \`*.sln\` → .NET
1453
+ - \`composer.json\` → PHP
1454
+
1455
+ **Framework Indicators:**
1456
+ - \`next.config.*\` / \`app/\` directory → Next.js
1457
+ - \`vite.config.*\` → Vite
1458
+ - \`angular.json\` → Angular
1459
+ - \`svelte.config.*\` → Svelte
1460
+ - \`remix.config.*\` → Remix
1461
+ - \`nuxt.config.*\` → Nuxt
1462
+ - \`django\` in imports → Django
1463
+ - \`flask\` in imports → Flask
1464
+ - \`fastapi\` in imports → FastAPI
1465
+ - \`express\` in dependencies → Express
1466
+ - \`rails\` / \`Gemfile\` with rails → Rails
1467
+ - \`laravel\` → Laravel
1468
+
1469
+ **Testing Frameworks:**
1470
+ - \`jest.config.*\` / \`@jest\` in deps → Jest
1471
+ - \`vitest.config.*\` → Vitest
1472
+ - \`pytest.ini\` / \`conftest.py\` → Pytest
1473
+ - \`*_test.go\` files → Go testing
1474
+ - \`*_spec.rb\` files → RSpec
1475
+ - \`cypress/\` or \`playwright/\` → E2E testing
1476
+
1477
+ **Infrastructure:**
1478
+ - \`Dockerfile\` / \`docker-compose.*\` → Docker
1479
+ - \`*.tf\` files → Terraform
1480
+ - \`k8s/\` or \`kubernetes/\` → Kubernetes
1481
+ - \`.github/workflows/\` GitHub Actions
1482
+ - \`serverless.yml\` → Serverless Framework
1483
+
1484
+ ## Step 2: Populate CLAUDE.md
1485
+
1486
+ Focus on what Claude Code actually needs to work effectively. Claude can explore the codebase itself — don't document what it can discover.
1487
+
1488
+ **Always include:**
1489
+ - **Project name + one-liner**: What is this thing?
1490
+ - **Tech stack**: Runtime, framework, database, key services (so Claude uses correct patterns)
1491
+ - **Commands**: How to run, test, build, deploy — Claude needs these to execute tasks
1492
+ - **Non-obvious conventions**: Multi-schema databases, monorepo structure, unusual patterns Claude wouldn't infer
1493
+
1494
+ **Include if relevant:**
1495
+ - **Deployment flow**: If non-standard or involves multiple steps
1496
+
1497
+ **Skip these — Claude can discover them:**
1498
+ - Detailed project structure trees (Claude can run \`ls\` or \`tree\`)
1499
+ - Exhaustive route/endpoint lists (Claude can grep)
1500
+ - File-by-file descriptions (Claude can read files)
1501
+ - Database model lists (Claude can read schema files)
1502
+
1503
+ **Keep it tight.** A 30-line CLAUDE.md that hits the essentials beats a 200-line doc Claude has to parse every session.
1504
+
1505
+ ## Step 3: Create Rules Directory
1506
+
1507
+ Create an empty \`.claude/rules/\` directory. Do not create any subdirectories or rule files.
1508
+
1509
+ Rules are path-scoped context files that load automatically when Claude works on matching files. Effective rules require deep understanding of your codebase patterns, team conventions, and quality goals — they should be crafted intentionally, not auto-generated.
1510
+
1511
+ ## Step 4: Configure Settings
1512
+
1513
+ Update \`.claude/settings.json\` using the official schema.
1514
+
1515
+ ### Deny Patterns (files Claude shouldn't read/write)
1516
+
1517
+ Use \`Read()\` for blocking reads, \`Edit()\` for blocking writes:
1518
+
1519
+ **Always deny (security):**
1520
+ \`\`\`
1521
+ Read(./.env)
1522
+ Read(./.env.*)
1523
+ Read(./secrets/**)
1524
+ Edit(./.env)
1525
+ Edit(./.env.*)
1526
+ \`\`\`
1527
+
1528
+ **Often deny (generated/vendor):**
1529
+ \`\`\`
1530
+ Edit(./node_modules/**)
1531
+ Edit(./dist/**)
1532
+ Edit(./.git/**)
1533
+ \`\`\`
1534
+
1535
+ ### Allow Patterns (auto-approve without prompting)
1536
+
1537
+ Use \`Bash()\` patterns with prefix matching:
1538
+
1539
+ \`\`\`
1540
+ Bash(npm run test:*)
1541
+ Bash(npm run lint:*)
1542
+ Bash(npm run build)
1543
+ \`\`\`
1544
+
1545
+ ### Environment Variables
1546
+
1547
+ Set session-level env vars:
1548
+
1549
+ \`\`\`json
1550
+ {
1551
+ "env": {
1552
+ "NODE_ENV": "development"
1553
+ }
1554
+ }
1555
+ \`\`\`
1556
+
1557
+ **Keep it minimal** — only include patterns that actually exist in this project.
1558
+
1559
+ ## Guidelines
1560
+
1561
+ - Replace ALL placeholder content with real values from THIS project
1562
+ - Delete sections that don't apply no empty stubs
1563
+ - Optimize for Claude's efficiency, not human documentation
1564
+ - When uncertain, leave it out Claude can ask or explore
1565
+
1566
+ ## After Completion
1567
+
1568
+ Once autoconfig is complete, prompt the user:
1569
+
1570
+ **Run \`/guide\` for an interactive walkthrough of your new Claude Code project setup.**`
1571
+ },
1572
+ 'commit-and-push': {
1573
+ filename: 'commit-and-push.md',
1574
+ content: `# Commit and Push
1575
+
1576
+ Stage all changes, create a commit with a good message, and push to the current branch.
1577
+
1578
+ ## Steps
1579
+
1580
+ 1. Stage all changes (\`git add -A\`)
1581
+ 2. Generate a conventional commit message based on the diff
1582
+ 3. Commit the changes
1583
+ 4. Push to the current branch
1584
+
1585
+ ## Commit Message Format
1586
+
1587
+ Use conventional commits: \`type(scope): description\`
1588
+
1589
+ Types: feat, fix, docs, style, refactor, test, chore
1590
+
1591
+ Keep the subject line under 50 chars. Add body if the change needs explanation.`
1592
+ },
1593
+ 'guide-cmd': {
1594
+ filename: 'show-guide.md',
1595
+ content: `# Show Guide
1596
+
1597
+ Open the interactive guide for Claude Code Autoconfig.
1598
+
1599
+ ## Step 1: Check for Changes
1600
+
1601
+ Compare modification times of files in \`.claude/\` against the guide HTML.
1602
+
1603
+ If any files are newer: "Syncing guide with latest changes..." → proceed to delta sync.
1604
+
1605
+ ## Step 2: Delta Sync
1606
+
1607
+ For each changed file, update only that entry in the guide's fileContents.
1608
+
1609
+ ## Step 3: Open Guide
1610
+
1611
+ Open in default browser (macOS: open, Linux: xdg-open, Windows: start).`
1612
+ },
1613
+ 'test': {
1614
+ filename: 'test.md',
1615
+ content: `# Run Tests
1616
+
1617
+ Run tests for this project.
1618
+
1619
+ **Scope:** $ARGUMENTS
1620
+
1621
+ If no scope provided, run the full test suite. Otherwise run tests matching the scope (file, directory, or pattern).
1622
+
1623
+ Detect the test command from project config (package.json scripts, pytest, go test, etc.) and execute it.`
1624
+ },
1625
+ 'rules': {
1626
+ filename: 'rules/',
1627
+ content: null,
1628
+ empty: true,
1629
+ emptyMessage: 'This directory is empty.\n\nAdd .md files here to define rules for specific paths in your codebase.'
1630
+ },
1631
+ 'guide': {
1632
+ filename: 'autoconfig.guide.html',
1633
+ content: null,
1634
+ empty: true,
1635
+ emptyMessage: "You're looking at it! 👀"
1636
+ },
1637
+ 'enable-retro': {
1638
+ filename: 'enable-retro.md',
1639
+ content: `# Enable Retro
1640
+
1641
+ (Experimental) Enable tech debt tracking.
1642
+
1643
+ ## What This Does
1644
+
1645
+ 1. Creates \`.claude/retro/\` directory
1646
+ 2. Creates \`.claude/agents/create-retro-item.md\` agent
1647
+ 3. Adds Retro instructions to CLAUDE.md
1648
+
1649
+ ## After Enabling
1650
+
1651
+ Claude will log tech debt and improvement opportunities as structured story files:
1652
+ - Problem description
1653
+ - Acceptance criteria
1654
+ - Suggested approach
1655
+ - Priority & effort sizing
1656
+ - Files involved
1657
+
1658
+ Work through items: "Fix retro #001"`
1659
+ },
1660
+ 'feedback-template': {
1661
+ filename: 'FEEDBACK.md',
1662
+ content: `# Team Feedback
1663
+
1664
+ Add corrections and guidance here when Claude does something wrong.
1665
+ Claude reads this directory and learns for next time.
1666
+
1667
+ ## YYYY-MM-DD: Brief title
1668
+
1669
+ Describe what Claude did wrong and what to do instead.
1670
+ Keep entries brief and actionable.
1671
+
1672
+ Example:
1673
+
1674
+ ## 2026-01-06: Don't use deprecated API
1675
+ Claude used \`oldFunction()\` instead of \`newFunction()\`.
1676
+ Always use the v2 API for user endpoints.
1677
+
1678
+ ## 2026-01-07: Test database naming
1679
+ Use \`test_\` prefix for test databases, not \`dev_\`.`
1680
+ }
1681
+ };
1682
+
1683
+ const modal = document.getElementById('fileModal');
1684
+ const modalTitle = document.getElementById('modalTitle');
1685
+ const modalCode = document.getElementById('modalCode');
1686
+ const modalClose = document.getElementById('modalClose');
1687
+
1688
+ function openModal(key) {
1689
+ const file = fileContents[key];
1690
+ if (!file) return;
1691
+
1692
+ modalTitle.textContent = file.filename;
1693
+
1694
+ if (file.empty) {
1695
+ modalCode.innerHTML = `<span class="modal-empty">${file.emptyMessage}</span>`;
1696
+ } else {
1697
+ modalCode.textContent = file.content;
1698
+ }
1699
+
1700
+ modal.classList.add('visible');
1701
+ }
1702
+
1703
+ function closeModal() {
1704
+ modal.classList.remove('visible');
1705
+ }
1706
+
1707
+ modalClose.addEventListener('click', closeModal);
1708
+ modal.addEventListener('click', (e) => {
1709
+ if (e.target === modal) closeModal();
1710
+ });
1711
+ document.addEventListener('keydown', (e) => {
1712
+ if (e.key === 'Escape' && modal.classList.contains('visible')) {
1713
+ closeModal();
1714
+ }
1715
+ // Enter key opens preview for selected item
1716
+ if (e.key === 'Enter' && !modal.classList.contains('visible')) {
1717
+ const selected = document.querySelector('.tree-item.active');
1718
+ if (selected) {
1719
+ const key = selected.dataset.info;
1720
+ if (fileContents[key]) {
1721
+ openModal(key);
1722
+ }
1723
+ }
1724
+ }
1725
+ });
1726
+
1727
+ // Double-click to open file preview
1728
+ treeItems.forEach(item => {
1729
+ item.addEventListener('dblclick', (e) => {
1730
+ const key = item.dataset.info;
1731
+ // Don't open modal for folders (except rules which is empty) or root
1732
+ if (key === 'root' || key === 'claude-dir' || key === 'commands') return;
1733
+ if (fileContents[key]) {
1734
+ openModal(key);
1735
+ }
1736
+ });
1737
+ });
1738
+ </script>
1739
+ </body>
1870
1740
  </html>