claude-code-autoconfig 1.0.15 → 1.0.17

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,1749 @@
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 hidden" data-info="agents" data-parent="claude-dir">
829
+ <span class="tree-spacer"></span>
830
+ <span class="tree-folder-icon">📁</span>
831
+ <span class="folder">agents</span>
832
+ </div>
833
+ <div class="tree-item indent-2 folder-row hidden collapsed" data-info="commands" data-folder="commands" data-parent="claude-dir">
834
+ <span class="tree-chevron">›</span>
835
+ <span class="tree-folder-icon">📁</span>
836
+ <span class="folder">commands</span>
837
+ </div>
838
+ <div class="tree-item indent-3 hidden" data-info="autoconfig" data-parent="commands">
839
+ <span class="tree-spacer"></span>
840
+ <span class="tree-file-icon">📄</span>
841
+ <span class="file">autoconfig.md</span>
842
+ </div>
843
+ <div class="tree-item indent-3 hidden" data-info="commit-and-push" data-parent="commands">
844
+ <span class="tree-spacer"></span>
845
+ <span class="tree-file-icon">📄</span>
846
+ <span class="file">commit-and-push.md</span>
847
+ </div>
848
+ <div class="tree-item indent-3 hidden" data-info="enable-retro" data-parent="commands">
849
+ <span class="tree-spacer"></span>
850
+ <span class="tree-file-icon">📄</span>
851
+ <span class="file">enable-retro.md</span>
852
+ </div>
853
+ <div class="tree-item indent-3 hidden" data-info="guide-cmd" data-parent="commands">
854
+ <span class="tree-spacer"></span>
855
+ <span class="tree-file-icon">📄</span>
856
+ <span class="file">show-guide.md</span>
857
+ </div>
858
+ <div class="tree-item indent-3 hidden" data-info="sync-claude-md" data-parent="commands">
859
+ <span class="tree-spacer"></span>
860
+ <span class="tree-file-icon">📄</span>
861
+ <span class="file">sync-claude-md.md</span>
862
+ </div>
863
+ <div class="tree-item indent-3 hidden" data-info="test" data-parent="commands">
864
+ <span class="tree-spacer"></span>
865
+ <span class="tree-file-icon">📄</span>
866
+ <span class="file">test.md</span>
867
+ </div>
868
+ <div class="tree-item indent-2 folder-row hidden collapsed" data-info="feedback" data-folder="feedback" data-parent="claude-dir">
869
+ <span class="tree-chevron">›</span>
870
+ <span class="tree-folder-icon">📁</span>
871
+ <span class="folder">feedback</span>
872
+ </div>
873
+ <div class="tree-item indent-3 hidden" data-info="feedback-template" data-parent="feedback">
874
+ <span class="tree-spacer"></span>
875
+ <span class="tree-file-icon">📄</span>
876
+ <span class="file">FEEDBACK.md</span>
877
+ </div>
878
+ <div class="tree-item indent-2 folder-row hidden collapsed" data-info="guide" data-folder="guide-folder" data-parent="claude-dir">
879
+ <span class="tree-chevron">›</span>
880
+ <span class="tree-folder-icon">📁</span>
881
+ <span class="folder">guide</span>
882
+ </div>
883
+ <div class="tree-item indent-3 hidden" data-info="guide" data-parent="guide-folder">
884
+ <span class="tree-spacer"></span>
885
+ <span class="tree-file-icon">🌐</span>
886
+ <span class="file">autoconfig.guide.html</span>
887
+ </div>
888
+ <div class="tree-item indent-2 hidden" data-info="rules" data-parent="claude-dir">
889
+ <span class="tree-spacer"></span>
890
+ <span class="tree-folder-icon">📁</span>
891
+ <span class="folder">rules</span>
892
+ </div>
893
+ <div class="tree-item indent-2 hidden" data-info="mcp" data-parent="claude-dir">
894
+ <span class="tree-spacer"></span>
895
+ <span class="tree-file-icon">🔌</span>
896
+ <span class="file">.mcp.json</span>
897
+ </div>
898
+ <div class="tree-item indent-2 hidden" data-info="settings" data-parent="claude-dir">
899
+ <span class="tree-spacer"></span>
900
+ <span class="tree-file-icon">⚙️</span>
901
+ <span class="file">settings.json</span>
902
+ </div>
903
+ <div class="tree-item indent-1" data-info="claude-md" data-parent="root">
904
+ <span class="tree-spacer"></span>
905
+ <span class="tree-file-icon">📄</span>
906
+ <span class="file">CLAUDE.md</span>
907
+ </div>
908
+ </div>
909
+ <div class="info-side">
910
+ <div class="info-panel" id="infoPanel">
911
+ <div class="info-panel-title">Select a file</div>
912
+ <div class="info-panel-desc">Hover over any item in the tree to see what it does.</div>
913
+ </div>
914
+ </div>
915
+ </div>
916
+ </div>
917
+ </div>
918
+
919
+ <!-- Slide 1: Finale -->
920
+ <div class="slide" data-slide="1">
921
+ <div class="slide-number">02 / You're Ready</div>
922
+ <h1>That's It</h1>
923
+ <h2 class="typewriter" data-text="You've got the autoconfig. Now go build something."></h2>
924
+ <div class="slide-content">
925
+ <div class="final-links">
926
+ <a href="https://github.com/design-and-deliver/claude-code-autoconfig" class="final-link" target="_blank">
927
+ Star on GitHub
928
+ </a>
929
+ <a href="https://docs.anthropic.com/en/docs/claude-code/overview" class="final-link" target="_blank">
930
+ 📚 Claude Code Docs
931
+ </a>
932
+ </div>
933
+ </div>
934
+ </div>
935
+ </div>
936
+
937
+ <div class="nav-container">
938
+ <button class="nav-btn prev" id="prevBtn">
939
+ Back
940
+ </button>
941
+ <button class="nav-btn next" id="nextBtn">
942
+ Next
943
+ </button>
944
+ </div>
945
+ </div>
946
+
947
+ <script>
948
+ const slides = document.querySelectorAll('.slide');
949
+ const progressContainer = document.getElementById('progress');
950
+ const prevBtn = document.getElementById('prevBtn');
951
+ const nextBtn = document.getElementById('nextBtn');
952
+ let currentSlide = 0;
953
+
954
+ // Create progress dots
955
+ slides.forEach((_, i) => {
956
+ const dot = document.createElement('div');
957
+ dot.className = 'progress-dot' + (i === 0 ? ' active' : '');
958
+ dot.addEventListener('click', () => goToSlide(i));
959
+ progressContainer.appendChild(dot);
960
+ });
961
+
962
+ function updateProgress() {
963
+ document.querySelectorAll('.progress-dot').forEach((dot, i) => {
964
+ dot.classList.remove('active');
965
+ if (i === currentSlide) dot.classList.add('active');
966
+ });
967
+ }
968
+
969
+ function goToSlide(index) {
970
+ if (index < 0 || index >= slides.length) return;
971
+
972
+ const direction = index > currentSlide ? 1 : -1;
973
+
974
+ slides[currentSlide].classList.remove('active');
975
+ if (direction > 0) {
976
+ slides[currentSlide].classList.add('exit');
977
+ }
978
+
979
+ currentSlide = index;
980
+
981
+ slides.forEach(s => s.classList.remove('exit'));
982
+ slides[currentSlide].classList.add('active');
983
+
984
+ updateProgress();
985
+ updateButtons();
986
+ checkTypewriter();
987
+
988
+ // Select CLAUDE.md by default when entering slide 0 (tree view)
989
+ if (currentSlide === 0) {
990
+ setTimeout(() => selectTreeItemByKey('claude-md'), 100);
991
+ }
992
+ }
993
+
994
+ function updateButtons() {
995
+ // Hide back button on first slide, show on others
996
+ prevBtn.style.visibility = currentSlide === 0 ? 'hidden' : 'visible';
997
+
998
+ if (currentSlide === slides.length - 1) {
999
+ nextBtn.textContent = 'Done';
1000
+ } else {
1001
+ nextBtn.textContent = 'Next';
1002
+ }
1003
+ }
1004
+
1005
+ prevBtn.addEventListener('click', () => {
1006
+ if (currentSlide > 0) {
1007
+ goToSlide(currentSlide - 1);
1008
+ }
1009
+ });
1010
+
1011
+ nextBtn.addEventListener('click', () => {
1012
+ if (currentSlide < slides.length - 1) {
1013
+ goToSlide(currentSlide + 1);
1014
+ } else {
1015
+ window.close();
1016
+ }
1017
+ });
1018
+
1019
+ // Select CLAUDE.md on initial page load
1020
+ setTimeout(() => selectTreeItemByKey('claude-md'), 300);
1021
+
1022
+ // Keyboard navigation for slides
1023
+ document.addEventListener('keydown', (e) => {
1024
+ // On slide 0, arrow keys control tree - use spacebar for next slide
1025
+ if (currentSlide === 0) {
1026
+ if (e.key === ' ') {
1027
+ e.preventDefault();
1028
+ if (currentSlide < slides.length - 1) {
1029
+ goToSlide(currentSlide + 1);
1030
+ }
1031
+ }
1032
+ return; // Let tree keyboard handler deal with arrows
1033
+ }
1034
+
1035
+ // Space bar for next slide (but not on slide 0 with tree)
1036
+ if (e.key === ' ' && currentSlide !== 0) {
1037
+ e.preventDefault();
1038
+ if (currentSlide < slides.length - 1) {
1039
+ goToSlide(currentSlide + 1);
1040
+ }
1041
+ }
1042
+ });
1043
+
1044
+ updateButtons();
1045
+
1046
+ // Auto-focus for keyboard navigation
1047
+ document.body.setAttribute('tabindex', '0');
1048
+ document.body.focus();
1049
+
1050
+ // Detect project name from file path
1051
+ function getProjectName() {
1052
+ try {
1053
+ const path = window.location.pathname;
1054
+ const parts = path.split('/').filter(p => p && !p.includes(':'));
1055
+ const claudeIndex = parts.indexOf('.claude');
1056
+ if (claudeIndex > 0) {
1057
+ return parts[claudeIndex - 1];
1058
+ }
1059
+ if (parts.length >= 3) {
1060
+ return parts[parts.length - 3];
1061
+ }
1062
+ } catch (e) {}
1063
+ return 'your-project';
1064
+ }
1065
+
1066
+ const projectName = getProjectName();
1067
+
1068
+ // Update tree root with actual project name
1069
+ const rootItem = document.querySelector('[data-info="root"]');
1070
+ if (rootItem) {
1071
+ rootItem.querySelector('.folder').textContent = projectName + '/';
1072
+ }
1073
+
1074
+ // Calculate tree side width dynamically
1075
+ function setTreeWidth() {
1076
+ const treeSide = document.querySelector('.tree-side');
1077
+ const treeItems = document.querySelectorAll('.tree-item');
1078
+ if (!treeSide || !treeItems.length) return;
1079
+
1080
+ const hiddenItems = [];
1081
+ treeItems.forEach(item => {
1082
+ if (item.classList.contains('hidden')) {
1083
+ hiddenItems.push(item);
1084
+ item.style.visibility = 'hidden';
1085
+ item.style.position = 'absolute';
1086
+ item.classList.remove('hidden');
1087
+ }
1088
+ });
1089
+
1090
+ let maxWidth = 0;
1091
+ treeItems.forEach(item => {
1092
+ const width = item.scrollWidth;
1093
+ if (width > maxWidth) maxWidth = width;
1094
+ });
1095
+
1096
+ hiddenItems.forEach(item => {
1097
+ item.classList.add('hidden');
1098
+ item.style.visibility = '';
1099
+ item.style.position = '';
1100
+ });
1101
+
1102
+ treeSide.style.width = (maxWidth + 32) + 'px';
1103
+ treeSide.style.padding = '16px 8px';
1104
+ }
1105
+
1106
+ if (document.fonts && document.fonts.ready) {
1107
+ document.fonts.ready.then(setTreeWidth);
1108
+ } else {
1109
+ setTimeout(setTreeWidth, 100);
1110
+ }
1111
+
1112
+ // Typewriter effect
1113
+ function typeWriter(element) {
1114
+ const text = element.dataset.text;
1115
+ if (!text) return;
1116
+
1117
+ element.textContent = '';
1118
+ element.classList.add('typing');
1119
+ element.classList.remove('done');
1120
+
1121
+ let i = 0;
1122
+ const speed = 30;
1123
+
1124
+ function type() {
1125
+ if (i < text.length) {
1126
+ element.textContent += text.charAt(i);
1127
+ i++;
1128
+ setTimeout(type, speed);
1129
+ } else {
1130
+ element.classList.remove('typing');
1131
+ element.classList.add('done');
1132
+ }
1133
+ }
1134
+
1135
+ setTimeout(type, 300);
1136
+ }
1137
+
1138
+ function checkTypewriter() {
1139
+ const activeSlide = slides[currentSlide];
1140
+ const typewriterEl = activeSlide.querySelector('.typewriter');
1141
+ if (typewriterEl) {
1142
+ typeWriter(typewriterEl);
1143
+ }
1144
+ }
1145
+
1146
+ setTimeout(checkTypewriter, 100);
1147
+
1148
+ // Tree panel info data - UPDATED
1149
+ const treeInfo = {
1150
+ 'root': {
1151
+ title: projectName,
1152
+ desc: 'The autoconfig adds CLAUDE.md at your project root and configuration files inside a .claude/ directory. Nothing else is touched.'
1153
+ },
1154
+ 'claude-md': {
1155
+ title: 'CLAUDE.md',
1156
+ 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>',
1157
+ trigger: 'Loaded automatically at session start'
1158
+ },
1159
+ 'claude-dir': {
1160
+ title: '.claude/ Directory',
1161
+ desc: 'Commands, rules, settings, and this guide. Keeps configuration organized as your project grows.'
1162
+ },
1163
+ 'settings': {
1164
+ title: 'settings.json',
1165
+ desc: 'Permissions, security, and hooks. Controls which commands Claude can run and which files it can access.',
1166
+ trigger: 'Claude Code loads this automatically at the start of every session'
1167
+ },
1168
+ 'mcp': {
1169
+ title: '.mcp.json',
1170
+ 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.'
1171
+ },
1172
+ 'agents': {
1173
+ title: 'agents/',
1174
+ desc: 'Custom agent definitions for specialized tasks. Agents are autonomous workers that can be spawned to handle complex operations independently.'
1175
+ },
1176
+ 'commands': {
1177
+ title: 'commands/',
1178
+ 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>.'
1179
+ },
1180
+ 'enable-retro': {
1181
+ title: 'enable-retro.md',
1182
+ desc: '(Experimental) Enables tech debt tracking. Creates <code>.claude/retro/</code> directory and configures Claude to log improvement opportunities as structured story files.',
1183
+ trigger: '/enable-retro'
1184
+ },
1185
+ 'feedback': {
1186
+ title: 'feedback/',
1187
+ 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.'
1188
+ },
1189
+ 'feedback-template': {
1190
+ title: 'FEEDBACK.md',
1191
+ 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.'
1192
+ },
1193
+ 'autoconfig': {
1194
+ title: 'autoconfig.md',
1195
+ desc: 'The command you just ran. Analyzes your project and populates CLAUDE.md with real context. Re-run anytime your stack changes.',
1196
+ trigger: '/autoconfig'
1197
+ },
1198
+ 'sync-claude-md': {
1199
+ title: 'sync-claude-md.md',
1200
+ desc: 'Re-analyzes your project and updates CLAUDE.md to reflect current state. Run when your stack changes significantly.',
1201
+ trigger: '/sync-claude-md'
1202
+ },
1203
+ 'guide-cmd': {
1204
+ title: 'show-guide.md',
1205
+ desc: 'Opens this interactive guide in your browser. Auto-syncs any changed files before opening.',
1206
+ trigger: '/show-guide'
1207
+ },
1208
+ 'test': {
1209
+ title: 'test.md',
1210
+ desc: 'Runs your test suite. Auto-detects Jest, Vitest, Pytest, Go, RSpec, or falls back to npm test.',
1211
+ trigger: '/test'
1212
+ },
1213
+ 'commit-and-push': {
1214
+ title: 'commit-and-push.md',
1215
+ desc: 'Stages all changes, generates a conventional commit message from the diff, commits, and pushes. One command, full workflow.',
1216
+ trigger: '/commit-and-push'
1217
+ },
1218
+ 'rules': {
1219
+ title: 'rules/',
1220
+ 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>'
1221
+ },
1222
+ 'guide': {
1223
+ title: 'guide/autoconfig.guide.html',
1224
+ desc: 'This interactive guide. Open it anytime to review what each file does.',
1225
+ trigger: '/show-guide'
1226
+ }
1227
+ };
1228
+
1229
+ // Tree panel hover handling
1230
+ const infoPanel = document.getElementById('infoPanel');
1231
+ const treeItems = document.querySelectorAll('.tree-item');
1232
+
1233
+ let selectedInfoKey = 'claude-md'; // Default selection
1234
+
1235
+ function showInfo(key) {
1236
+ const info = treeInfo[key];
1237
+ if (info) {
1238
+ let html = `<div class="info-panel-title">${info.title}</div>`;
1239
+ html += `<div class="info-panel-desc">${info.desc}</div>`;
1240
+ if (info.trigger) {
1241
+ html += `<div class="info-panel-trigger">${info.trigger}</div>`;
1242
+ }
1243
+ infoPanel.innerHTML = html;
1244
+ }
1245
+ }
1246
+
1247
+ treeItems.forEach((item, idx) => {
1248
+ // Hover updates info panel only (preview)
1249
+ item.addEventListener('mouseenter', () => {
1250
+ const key = item.dataset.info;
1251
+ showInfo(key);
1252
+ });
1253
+
1254
+ // Mouseleave restores selected item's info
1255
+ item.addEventListener('mouseleave', () => {
1256
+ showInfo(selectedInfoKey);
1257
+ });
1258
+
1259
+ // Click sets active selection
1260
+ item.addEventListener('click', (e) => {
1261
+ // Don't select if clicking on a folder chevron (let toggle handle it)
1262
+ if (e.target.classList.contains('tree-chevron')) return;
1263
+
1264
+ treeItems.forEach(i => i.classList.remove('active'));
1265
+ item.classList.add('active');
1266
+
1267
+ // Update selected info key
1268
+ selectedInfoKey = item.dataset.info;
1269
+ showInfo(selectedInfoKey);
1270
+
1271
+ // Sync selectedTreeIndex with visible items
1272
+ const visibleItems = Array.from(document.querySelectorAll('.tree-item:not(.hidden)'));
1273
+ selectedTreeIndex = visibleItems.indexOf(item);
1274
+ });
1275
+ });
1276
+
1277
+ // Folder collapse/expand handling
1278
+ function toggleFolder(folderId, collapsed) {
1279
+ const children = document.querySelectorAll(`[data-parent="${folderId}"]`);
1280
+ children.forEach(child => {
1281
+ if (collapsed) {
1282
+ child.classList.add('hidden');
1283
+ } else {
1284
+ child.classList.remove('hidden');
1285
+ if (child.dataset.folder && !child.classList.contains('collapsed')) {
1286
+ toggleFolder(child.dataset.folder, false);
1287
+ }
1288
+ }
1289
+ if (collapsed && child.dataset.folder) {
1290
+ toggleFolder(child.dataset.folder, true);
1291
+ }
1292
+ });
1293
+ }
1294
+
1295
+ document.querySelectorAll('.folder-row').forEach(folder => {
1296
+ folder.addEventListener('click', (e) => {
1297
+ const folderId = folder.dataset.folder;
1298
+ const isCollapsed = folder.classList.toggle('collapsed');
1299
+ toggleFolder(folderId, isCollapsed);
1300
+ });
1301
+ });
1302
+
1303
+ // Tree keyboard navigation
1304
+ let selectedTreeIndex = -1;
1305
+
1306
+ function getVisibleTreeItems() {
1307
+ return Array.from(document.querySelectorAll('.tree-item:not(.hidden)'));
1308
+ }
1309
+
1310
+ function selectTreeItemByKey(key) {
1311
+ const item = document.querySelector(`.tree-item[data-info="${key}"]`);
1312
+ if (!item) return;
1313
+
1314
+ treeItems.forEach(i => i.classList.remove('active'));
1315
+ item.classList.add('active');
1316
+
1317
+ selectedInfoKey = key;
1318
+ showInfo(selectedInfoKey);
1319
+
1320
+ // Update selectedTreeIndex
1321
+ const visibleItems = getVisibleTreeItems();
1322
+ selectedTreeIndex = visibleItems.indexOf(item);
1323
+ }
1324
+
1325
+ function selectTreeItem(index) {
1326
+ const items = getVisibleTreeItems();
1327
+ if (index < 0 || index >= items.length) return;
1328
+
1329
+ treeItems.forEach(i => i.classList.remove('active'));
1330
+
1331
+ selectedTreeIndex = index;
1332
+ const item = items[index];
1333
+ item.classList.add('active');
1334
+
1335
+ item.scrollIntoView({ block: 'nearest' });
1336
+
1337
+ selectedInfoKey = item.dataset.info;
1338
+ showInfo(selectedInfoKey);
1339
+ }
1340
+
1341
+ document.addEventListener('keydown', (e) => {
1342
+ if (currentSlide !== 0) return;
1343
+
1344
+ const items = getVisibleTreeItems();
1345
+ if (items.length === 0) return;
1346
+
1347
+ if (selectedTreeIndex === -1) {
1348
+ selectTreeItem(0);
1349
+ if (e.key === 'ArrowDown' || e.key === 'ArrowUp' || e.key === 'ArrowRight' || e.key === 'ArrowLeft') {
1350
+ e.preventDefault();
1351
+ }
1352
+ return;
1353
+ }
1354
+
1355
+ if (e.key === 'ArrowDown') {
1356
+ e.preventDefault();
1357
+ if (selectedTreeIndex < items.length - 1) {
1358
+ selectTreeItem(selectedTreeIndex + 1);
1359
+ }
1360
+ } else if (e.key === 'ArrowUp') {
1361
+ e.preventDefault();
1362
+ if (selectedTreeIndex > 0) {
1363
+ selectTreeItem(selectedTreeIndex - 1);
1364
+ }
1365
+ } else if (e.key === 'ArrowRight') {
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.remove('collapsed');
1371
+ toggleFolder(item.dataset.folder, false);
1372
+ }
1373
+ }
1374
+ } else if (e.key === 'ArrowLeft') {
1375
+ e.preventDefault();
1376
+ const item = items[selectedTreeIndex];
1377
+ if (item && item.classList.contains('folder-row')) {
1378
+ if (!item.classList.contains('collapsed')) {
1379
+ item.classList.add('collapsed');
1380
+ toggleFolder(item.dataset.folder, true);
1381
+ }
1382
+ }
1383
+ } else if (e.key === 'Enter') {
1384
+ e.preventDefault();
1385
+ const item = items[selectedTreeIndex];
1386
+ if (item && item.classList.contains('folder-row')) {
1387
+ const isCollapsed = item.classList.toggle('collapsed');
1388
+ toggleFolder(item.dataset.folder, isCollapsed);
1389
+ }
1390
+ }
1391
+ });
1392
+
1393
+ // File Preview Modal
1394
+ const fileContents = {
1395
+ 'claude-md': {
1396
+ filename: 'CLAUDE.md',
1397
+ content: `# Project Name
1398
+
1399
+ > Run \`/autoconfig\` to populate this based on your project.`
1400
+ },
1401
+ 'settings': {
1402
+ filename: 'settings.json',
1403
+ content: `{
1404
+ "permissions": {
1405
+ "allow": [
1406
+ "Read(./**)",
1407
+ "Edit(./**)",
1408
+ "Write(./**)",
1409
+ "Bash(npm run dev)",
1410
+ "Bash(npm run build)",
1411
+ "Bash(npm run test)",
1412
+ "Bash(git status)",
1413
+ "Bash(git diff:*)",
1414
+ "Bash(git add:*)",
1415
+ "Bash(git commit:*)",
1416
+ "Bash(git push:*)"
1417
+ ],
1418
+ "deny": [
1419
+ "Read(./.env)",
1420
+ "Read(./.env.*)",
1421
+ "Read(./secrets/**)"
1422
+ ]
1423
+ },
1424
+ "hooks": {
1425
+ "PostToolUse": [{
1426
+ "matcher": "Edit|Write",
1427
+ "hooks": [{
1428
+ "type": "command",
1429
+ "command": "// Auto-refresh guide when .claude/ changes"
1430
+ }]
1431
+ }]
1432
+ }
1433
+ }`
1434
+ },
1435
+ 'mcp': {
1436
+ filename: '.mcp.json',
1437
+ content: `{
1438
+ "mcpServers": {}
1439
+ }
1440
+
1441
+ // Add your MCP server configs here when you're ready.
1442
+ // See: https://docs.anthropic.com/en/docs/claude-code/mcp`
1443
+ },
1444
+ 'autoconfig': {
1445
+ filename: 'autoconfig.md',
1446
+ content: `# Autoconfig
1447
+
1448
+ Analyze this project and configure Claude Code with real context.
1449
+
1450
+ ## Step 1: Scan the Project
1451
+
1452
+ Look for these indicators to understand the project:
1453
+
1454
+ **Package/Config Files:**
1455
+ - \`package.json\` → Node.js, npm scripts, dependencies
1456
+ - \`requirements.txt\` / \`pyproject.toml\` / \`setup.py\` → Python
1457
+ - \`Cargo.toml\` → Rust
1458
+ - \`go.mod\` → Go
1459
+ - \`Gemfile\` → Ruby
1460
+ - \`pom.xml\` / \`build.gradle\` → Java
1461
+ - \`*.csproj\` / \`*.sln\` → .NET
1462
+ - \`composer.json\` → PHP
1463
+
1464
+ **Framework Indicators:**
1465
+ - \`next.config.*\` / \`app/\` directory → Next.js
1466
+ - \`vite.config.*\` → Vite
1467
+ - \`angular.json\` → Angular
1468
+ - \`svelte.config.*\` → Svelte
1469
+ - \`remix.config.*\` → Remix
1470
+ - \`nuxt.config.*\` → Nuxt
1471
+ - \`django\` in imports → Django
1472
+ - \`flask\` in imports → Flask
1473
+ - \`fastapi\` in imports → FastAPI
1474
+ - \`express\` in dependencies → Express
1475
+ - \`rails\` / \`Gemfile\` with rails → Rails
1476
+ - \`laravel\` → Laravel
1477
+
1478
+ **Testing Frameworks:**
1479
+ - \`jest.config.*\` / \`@jest\` in deps → Jest
1480
+ - \`vitest.config.*\` → Vitest
1481
+ - \`pytest.ini\` / \`conftest.py\` → Pytest
1482
+ - \`*_test.go\` files → Go testing
1483
+ - \`*_spec.rb\` files → RSpec
1484
+ - \`cypress/\` or \`playwright/\` → E2E testing
1485
+
1486
+ **Infrastructure:**
1487
+ - \`Dockerfile\` / \`docker-compose.*\` → Docker
1488
+ - \`*.tf\` files → Terraform
1489
+ - \`k8s/\` or \`kubernetes/\` → Kubernetes
1490
+ - \`.github/workflows/\` → GitHub Actions
1491
+ - \`serverless.yml\` → Serverless Framework
1492
+
1493
+ ## Step 2: Populate CLAUDE.md
1494
+
1495
+ Focus on what Claude Code actually needs to work effectively. Claude can explore the codebase itself — don't document what it can discover.
1496
+
1497
+ **Always include:**
1498
+ - **Project name + one-liner**: What is this thing?
1499
+ - **Tech stack**: Runtime, framework, database, key services (so Claude uses correct patterns)
1500
+ - **Commands**: How to run, test, build, deploy — Claude needs these to execute tasks
1501
+ - **Non-obvious conventions**: Multi-schema databases, monorepo structure, unusual patterns Claude wouldn't infer
1502
+
1503
+ **Include if relevant:**
1504
+ - **Deployment flow**: If non-standard or involves multiple steps
1505
+
1506
+ **Skip these — Claude can discover them:**
1507
+ - Detailed project structure trees (Claude can run \`ls\` or \`tree\`)
1508
+ - Exhaustive route/endpoint lists (Claude can grep)
1509
+ - File-by-file descriptions (Claude can read files)
1510
+ - Database model lists (Claude can read schema files)
1511
+
1512
+ **Keep it tight.** A 30-line CLAUDE.md that hits the essentials beats a 200-line doc Claude has to parse every session.
1513
+
1514
+ ## Step 3: Create Rules Directory
1515
+
1516
+ Create an empty \`.claude/rules/\` directory. Do not create any subdirectories or rule files.
1517
+
1518
+ 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.
1519
+
1520
+ ## Step 4: Configure Settings
1521
+
1522
+ Update \`.claude/settings.json\` using the official schema.
1523
+
1524
+ ### Deny Patterns (files Claude shouldn't read/write)
1525
+
1526
+ Use \`Read()\` for blocking reads, \`Edit()\` for blocking writes:
1527
+
1528
+ **Always deny (security):**
1529
+ \`\`\`
1530
+ Read(./.env)
1531
+ Read(./.env.*)
1532
+ Read(./secrets/**)
1533
+ Edit(./.env)
1534
+ Edit(./.env.*)
1535
+ \`\`\`
1536
+
1537
+ **Often deny (generated/vendor):**
1538
+ \`\`\`
1539
+ Edit(./node_modules/**)
1540
+ Edit(./dist/**)
1541
+ Edit(./.git/**)
1542
+ \`\`\`
1543
+
1544
+ ### Allow Patterns (auto-approve without prompting)
1545
+
1546
+ Use \`Bash()\` patterns with prefix matching:
1547
+
1548
+ \`\`\`
1549
+ Bash(npm run test:*)
1550
+ Bash(npm run lint:*)
1551
+ Bash(npm run build)
1552
+ \`\`\`
1553
+
1554
+ ### Environment Variables
1555
+
1556
+ Set session-level env vars:
1557
+
1558
+ \`\`\`json
1559
+ {
1560
+ "env": {
1561
+ "NODE_ENV": "development"
1562
+ }
1563
+ }
1564
+ \`\`\`
1565
+
1566
+ **Keep it minimal** only include patterns that actually exist in this project.
1567
+
1568
+ ## Guidelines
1569
+
1570
+ - Replace ALL placeholder content with real values from THIS project
1571
+ - Delete sections that don't apply — no empty stubs
1572
+ - Optimize for Claude's efficiency, not human documentation
1573
+ - When uncertain, leave it out — Claude can ask or explore
1574
+
1575
+ ## After Completion
1576
+
1577
+ Once autoconfig is complete, prompt the user:
1578
+
1579
+ **Run \`/guide\` for an interactive walkthrough of your new Claude Code project setup.**`
1580
+ },
1581
+ 'commit-and-push': {
1582
+ filename: 'commit-and-push.md',
1583
+ content: `# Commit and Push
1584
+
1585
+ Stage all changes, create a commit with a good message, and push to the current branch.
1586
+
1587
+ ## Steps
1588
+
1589
+ 1. Stage all changes (\`git add -A\`)
1590
+ 2. Generate a conventional commit message based on the diff
1591
+ 3. Commit the changes
1592
+ 4. Push to the current branch
1593
+
1594
+ ## Commit Message Format
1595
+
1596
+ Use conventional commits: \`type(scope): description\`
1597
+
1598
+ Types: feat, fix, docs, style, refactor, test, chore
1599
+
1600
+ Keep the subject line under 50 chars. Add body if the change needs explanation.`
1601
+ },
1602
+ 'guide-cmd': {
1603
+ filename: 'show-guide.md',
1604
+ content: `# Show Guide
1605
+
1606
+ Open the interactive guide for Claude Code Autoconfig.
1607
+
1608
+ ## Step 1: Check for Changes
1609
+
1610
+ Compare modification times of files in \`.claude/\` against the guide HTML.
1611
+
1612
+ If any files are newer: "Syncing guide with latest changes..." → proceed to delta sync.
1613
+
1614
+ ## Step 2: Delta Sync
1615
+
1616
+ For each changed file, update only that entry in the guide's fileContents.
1617
+
1618
+ ## Step 3: Open Guide
1619
+
1620
+ Open in default browser (macOS: open, Linux: xdg-open, Windows: start).`
1621
+ },
1622
+ 'test': {
1623
+ filename: 'test.md',
1624
+ content: `# Run Tests
1625
+
1626
+ Run tests for this project.
1627
+
1628
+ **Scope:** $ARGUMENTS
1629
+
1630
+ If no scope provided, run the full test suite. Otherwise run tests matching the scope (file, directory, or pattern).
1631
+
1632
+ Detect the test command from project config (package.json scripts, pytest, go test, etc.) and execute it.`
1633
+ },
1634
+ 'rules': {
1635
+ filename: 'rules/',
1636
+ content: null,
1637
+ empty: true,
1638
+ emptyMessage: 'This directory is empty.\n\nAdd .md files here to define rules for specific paths in your codebase.'
1639
+ },
1640
+ 'guide': {
1641
+ filename: 'autoconfig.guide.html',
1642
+ content: null,
1643
+ empty: true,
1644
+ emptyMessage: "You're looking at it! 👀"
1645
+ },
1646
+ 'enable-retro': {
1647
+ filename: 'enable-retro.md',
1648
+ content: `# Enable Retro
1649
+
1650
+ (Experimental) Enable tech debt tracking.
1651
+
1652
+ ## What This Does
1653
+
1654
+ 1. Creates \`.claude/retro/\` directory
1655
+ 2. Creates \`.claude/agents/create-retro-item.md\` agent
1656
+ 3. Adds Retro instructions to CLAUDE.md
1657
+
1658
+ ## After Enabling
1659
+
1660
+ Claude will log tech debt and improvement opportunities as structured story files:
1661
+ - Problem description
1662
+ - Acceptance criteria
1663
+ - Suggested approach
1664
+ - Priority & effort sizing
1665
+ - Files involved
1666
+
1667
+ Work through items: "Fix retro #001"`
1668
+ },
1669
+ 'feedback-template': {
1670
+ filename: 'FEEDBACK.md',
1671
+ content: `# Team Feedback
1672
+
1673
+ Add corrections and guidance here when Claude does something wrong.
1674
+ Claude reads this directory and learns for next time.
1675
+
1676
+ ## YYYY-MM-DD: Brief title
1677
+
1678
+ Describe what Claude did wrong and what to do instead.
1679
+ Keep entries brief and actionable.
1680
+
1681
+ Example:
1682
+
1683
+ ## 2026-01-06: Don't use deprecated API
1684
+ Claude used \`oldFunction()\` instead of \`newFunction()\`.
1685
+ Always use the v2 API for user endpoints.
1686
+
1687
+ ## 2026-01-07: Test database naming
1688
+ Use \`test_\` prefix for test databases, not \`dev_\`.`
1689
+ }
1690
+ };
1691
+
1692
+ const modal = document.getElementById('fileModal');
1693
+ const modalTitle = document.getElementById('modalTitle');
1694
+ const modalCode = document.getElementById('modalCode');
1695
+ const modalClose = document.getElementById('modalClose');
1696
+
1697
+ function openModal(key) {
1698
+ const file = fileContents[key];
1699
+ if (!file) return;
1700
+
1701
+ modalTitle.textContent = file.filename;
1702
+
1703
+ if (file.empty) {
1704
+ modalCode.innerHTML = `<span class="modal-empty">${file.emptyMessage}</span>`;
1705
+ } else {
1706
+ modalCode.textContent = file.content;
1707
+ }
1708
+
1709
+ modal.classList.add('visible');
1710
+ }
1711
+
1712
+ function closeModal() {
1713
+ modal.classList.remove('visible');
1714
+ }
1715
+
1716
+ modalClose.addEventListener('click', closeModal);
1717
+ modal.addEventListener('click', (e) => {
1718
+ if (e.target === modal) closeModal();
1719
+ });
1720
+ document.addEventListener('keydown', (e) => {
1721
+ if (e.key === 'Escape' && modal.classList.contains('visible')) {
1722
+ closeModal();
1723
+ }
1724
+ // Enter key opens preview for selected item
1725
+ if (e.key === 'Enter' && !modal.classList.contains('visible')) {
1726
+ const selected = document.querySelector('.tree-item.active');
1727
+ if (selected) {
1728
+ const key = selected.dataset.info;
1729
+ if (fileContents[key]) {
1730
+ openModal(key);
1731
+ }
1732
+ }
1733
+ }
1734
+ });
1735
+
1736
+ // Double-click to open file preview
1737
+ treeItems.forEach(item => {
1738
+ item.addEventListener('dblclick', (e) => {
1739
+ const key = item.dataset.info;
1740
+ // Don't open modal for folders (except rules which is empty) or root
1741
+ if (key === 'root' || key === 'claude-dir' || key === 'commands') return;
1742
+ if (fileContents[key]) {
1743
+ openModal(key);
1744
+ }
1745
+ });
1746
+ });
1747
+ </script>
1748
+ </body>
1870
1749
  </html>