claude-code-autoconfig 1.0.186 → 1.0.188

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,2149 +1,2149 @@
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: 1100px;
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: 480px;
382
- position: relative;
383
- }
384
-
385
- .tree-side {
386
- display: flex;
387
- flex-direction: column;
388
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Roboto', 'Noto Sans', sans-serif;
389
- font-size: 13px;
390
- line-height: 1.4;
391
- border-right: 1px solid var(--bg-elevated);
392
- flex-shrink: 0;
393
- height: 100%;
394
- }
395
-
396
- .tree-content {
397
- padding: 16px 16px 20px 16px;
398
- overflow: auto;
399
- flex: 1;
400
- min-height: 0;
401
- }
402
-
403
- .tree-footer-hint {
404
- padding: 6px 16px;
405
- font-size: 12px;
406
- color: var(--text-secondary);
407
- opacity: 0.5;
408
- border-top: 1px solid var(--bg-elevated);
409
- flex-shrink: 0;
410
- }
411
-
412
- .tree-item {
413
- padding: 4px 8px;
414
- margin: 1px 0;
415
- border-radius: 4px;
416
- cursor: pointer;
417
- transition: background 0.15s ease;
418
- white-space: nowrap;
419
- display: flex;
420
- align-items: center;
421
- gap: 4px;
422
- }
423
-
424
- .tree-item.hidden {
425
- display: none;
426
- }
427
-
428
- .tree-item:hover {
429
- background: rgba(255, 255, 255, 0.1);
430
- }
431
-
432
- .tree-item.active {
433
- background: rgba(45, 105, 175, 0.5);
434
- }
435
-
436
- .tree-item.active:hover {
437
- background: rgba(45, 105, 175, 0.5);
438
- }
439
-
440
- .tree-chevron {
441
- width: 18px;
442
- font-size: 18px;
443
- color: var(--text-primary);
444
- text-align: center;
445
- flex-shrink: 0;
446
- transition: transform 0.15s ease;
447
- user-select: none;
448
- transform: rotate(90deg);
449
- }
450
-
451
- .tree-item.collapsed .tree-chevron {
452
- transform: rotate(0deg);
453
- }
454
-
455
- .tree-spacer {
456
- width: 18px;
457
- flex-shrink: 0;
458
- }
459
-
460
- .tree-folder-icon,
461
- .tree-file-icon {
462
- font-size: 14px;
463
- flex-shrink: 0;
464
- }
465
-
466
- .tree-item .folder {
467
- color: var(--text-primary);
468
- }
469
-
470
- .tree-item .file {
471
- color: var(--text-secondary);
472
- }
473
-
474
- .tree-item.indent-1 { padding-left: 24px; }
475
- .tree-item.indent-2 { padding-left: 44px; }
476
- .tree-item.indent-3 { padding-left: 64px; }
477
- .tree-item.indent-4 { padding-left: 84px; }
478
-
479
- .tree-indent {
480
- color: var(--text-dim);
481
- }
482
-
483
- .info-side {
484
- flex: 1;
485
- min-width: 0;
486
- height: 100%;
487
- overflow-y: auto;
488
- overflow-x: hidden;
489
- word-wrap: break-word;
490
- }
491
-
492
- .info-panel {
493
- padding: 20px 20px 20px 0;
494
- width: 100%;
495
- box-sizing: border-box;
496
- }
497
-
498
- .info-panel-title {
499
- font-size: 16px;
500
- font-weight: 600;
501
- color: var(--accent-orange);
502
- margin-bottom: 12px;
503
- }
504
-
505
- .info-panel-desc {
506
- font-size: 14px;
507
- color: var(--text-secondary);
508
- line-height: 1.6;
509
- letter-spacing: 0.02em;
510
- }
511
-
512
- .info-panel-trigger {
513
- margin-top: 16px;
514
- padding: 8px 12px;
515
- background: var(--bg-elevated);
516
- border-radius: 4px;
517
- font-family: 'SF Mono', 'Fira Code', monospace;
518
- font-size: 13px;
519
- color: var(--accent-cyan);
520
- }
521
-
522
- .info-panel-hint {
523
- margin-top: 20px;
524
- font-size: 12px;
525
- color: var(--text-secondary);
526
- opacity: 0.5;
527
- }
528
-
529
- /* Navigation */
530
- .nav-container {
531
- display: flex;
532
- justify-content: space-between;
533
- align-items: center;
534
- margin-top: 40px;
535
- padding-top: 20px;
536
- }
537
-
538
- .nav-btn {
539
- display: flex;
540
- align-items: center;
541
- gap: 8px;
542
- padding: 14px 28px;
543
- border: none;
544
- border-radius: 8px;
545
- font-size: 16px;
546
- font-weight: 500;
547
- cursor: pointer;
548
- transition: all 0.3s ease;
549
- }
550
-
551
- .nav-btn.prev {
552
- background: var(--bg-elevated);
553
- color: var(--text-secondary);
554
- }
555
-
556
- .nav-btn.prev:hover:not(:disabled) {
557
- background: var(--bg-secondary);
558
- color: var(--text-primary);
559
- }
560
-
561
- .nav-btn.next {
562
- background: var(--accent-orange);
563
- color: var(--bg-primary);
564
- }
565
-
566
- .nav-btn.next:hover:not(:disabled) {
567
- transform: translateY(-2px);
568
- box-shadow: 0 10px 30px rgba(212, 165, 116, 0.3);
569
- }
570
-
571
- .nav-btn:disabled {
572
- opacity: 0.3;
573
- cursor: not-allowed;
574
- transform: none !important;
575
- }
576
-
577
- .nav-hint {
578
- color: var(--text-dim);
579
- font-size: 14px;
580
- }
581
-
582
- .nav-hint kbd {
583
- background: var(--bg-elevated);
584
- padding: 4px 8px;
585
- border-radius: 4px;
586
- font-family: inherit;
587
- margin: 0 2px;
588
- }
589
-
590
- /* Table */
591
- .table-container {
592
- overflow-x: auto;
593
- margin: 20px 0;
594
- }
595
-
596
- table {
597
- width: 100%;
598
- border-collapse: collapse;
599
- }
600
-
601
- th, td {
602
- padding: 12px 16px 12px 0;
603
- text-align: left;
604
- vertical-align: top;
605
- border-bottom: 1px solid var(--bg-elevated);
606
- }
607
-
608
- th {
609
- color: var(--accent-blue);
610
- font-size: 12px;
611
- text-transform: uppercase;
612
- letter-spacing: 1px;
613
- }
614
-
615
- td {
616
- font-size: 14px;
617
- }
618
-
619
- td code {
620
- background: var(--bg-secondary);
621
- color: var(--accent-orange);
622
- padding: 2px 4px;
623
- border-radius: 4px;
624
- font-family: 'SF Mono', 'Fira Code', monospace;
625
- font-size: 13px;
626
- }
627
-
628
- /* Animations */
629
- @keyframes fadeInUp {
630
- from {
631
- opacity: 0;
632
- transform: translateY(20px);
633
- }
634
- to {
635
- opacity: 1;
636
- transform: translateY(0);
637
- }
638
- }
639
-
640
- .slide.active .slide-number { animation: fadeIn 0.4s ease both; }
641
- .slide.active h1 { animation: fadeIn 0.4s ease 0.1s both; }
642
- .slide.active h2 { animation: none; }
643
- .slide.active .slide-content > ul,
644
- .slide.active .slide-content > div { animation: fadeIn 0.5s ease 0.3s both; }
645
-
646
- @keyframes fadeIn {
647
- from { opacity: 0; }
648
- to { opacity: 1; }
649
- }
650
-
651
- /* Typewriter effect */
652
- .typewriter {
653
- border-right: 2px solid var(--bg-primary);
654
- animation: none !important;
655
- }
656
-
657
- .typewriter.typing {
658
- animation: blink-caret 0.75s step-end infinite !important;
659
- }
660
-
661
- .typewriter.done {
662
- border-right: none !important;
663
- animation: none !important;
664
- }
665
-
666
- @keyframes blink-caret {
667
- from, to { border-color: var(--bg-primary); }
668
- 50% { border-color: transparent; }
669
- }
670
-
671
- /* Scrollbar */
672
- ::-webkit-scrollbar {
673
- width: 8px;
674
- }
675
-
676
- ::-webkit-scrollbar-track {
677
- background: var(--bg-secondary);
678
- border-radius: 4px;
679
- }
680
-
681
- ::-webkit-scrollbar-thumb {
682
- background: var(--bg-elevated);
683
- border-radius: 4px;
684
- }
685
-
686
- ::-webkit-scrollbar-thumb:hover {
687
- background: var(--text-dim);
688
- }
689
-
690
- /* Logo */
691
- .logo {
692
- font-size: 24px;
693
- margin-bottom: 8px;
694
- }
695
-
696
- /* Final slide special */
697
- .final-links {
698
- display: flex;
699
- gap: 16px;
700
- margin-top: 30px;
701
- flex-wrap: wrap;
702
- }
703
-
704
- .final-link {
705
- display: inline-flex;
706
- align-items: center;
707
- gap: 8px;
708
- padding: 12px 24px;
709
- background: var(--bg-elevated);
710
- border-radius: 8px;
711
- color: var(--text-secondary);
712
- text-decoration: none;
713
- transition: all 0.3s ease;
714
- }
715
-
716
- .final-link:hover {
717
- background: var(--bg-secondary);
718
- color: var(--accent-orange);
719
- transform: translateY(-2px);
720
- }
721
-
722
- /* File Preview Modal */
723
- .modal-overlay {
724
- position: fixed;
725
- top: 0;
726
- left: 0;
727
- right: 0;
728
- bottom: 0;
729
- background: rgba(0, 0, 0, 0.85);
730
- display: none;
731
- justify-content: center;
732
- align-items: center;
733
- z-index: 1000;
734
- padding: 40px;
735
- opacity: 0;
736
- transition: opacity 0.2s ease;
737
- }
738
-
739
- .modal-overlay.visible {
740
- display: flex;
741
- opacity: 1;
742
- }
743
-
744
- .modal-content {
745
- background: var(--bg-secondary);
746
- border: 1px solid var(--bg-elevated);
747
- border-radius: 12px;
748
- max-width: 1000px;
749
- width: 100%;
750
- max-height: 80vh;
751
- display: flex;
752
- flex-direction: column;
753
- transform: scale(0.95);
754
- transition: transform 0.2s ease;
755
- }
756
-
757
- .modal-overlay.visible .modal-content {
758
- transform: scale(1);
759
- }
760
-
761
- .modal-header {
762
- display: flex;
763
- justify-content: space-between;
764
- align-items: center;
765
- padding: 16px 20px;
766
- border-bottom: 1px solid var(--bg-elevated);
767
- }
768
-
769
- .modal-title {
770
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Roboto', 'Noto Sans', sans-serif;
771
- font-size: 14px;
772
- color: var(--accent-orange);
773
- }
774
-
775
- .modal-close {
776
- background: none;
777
- border: none;
778
- color: var(--text-dim);
779
- font-size: 24px;
780
- cursor: pointer;
781
- padding: 0;
782
- line-height: 1;
783
- transition: color 0.2s ease;
784
- }
785
-
786
- .modal-close:hover {
787
- color: var(--text-primary);
788
- }
789
-
790
- .modal-body {
791
- padding: 20px;
792
- overflow-y: auto;
793
- flex: 1;
794
- }
795
-
796
- .modal-body pre {
797
- margin: 0;
798
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Roboto', 'Noto Sans', sans-serif;
799
- font-size: 13px;
800
- line-height: 1.6;
801
- color: var(--text-secondary);
802
- white-space: pre-wrap;
803
- word-wrap: break-word;
804
- }
805
-
806
- .modal-body .comment { color: var(--text-dim); }
807
- .modal-body .keyword { color: var(--accent-orange); }
808
- .modal-body .string { color: var(--accent-green); }
809
- .modal-body .property { color: var(--accent-blue); }
810
-
811
- .modal-empty {
812
- color: var(--text-dim);
813
- font-style: italic;
814
- text-align: center;
815
- padding: 40px;
816
- }
817
- </style>
818
- </head>
819
- <body>
820
- <!-- File Preview Modal -->
821
- <div class="modal-overlay" id="fileModal">
822
- <div class="modal-content">
823
- <div class="modal-header">
824
- <span class="modal-title" id="modalTitle">filename.md</span>
825
- <button class="modal-close" id="modalClose">&times;</button>
826
- </div>
827
- <div class="modal-body">
828
- <pre id="modalCode"></pre>
829
- </div>
830
- </div>
831
- </div>
832
-
833
- <div class="container">
834
- <div class="progress-container" id="progress"></div>
835
-
836
- <div class="slides-container">
837
- <!-- Slide 0: What Got Installed -->
838
- <div class="slide active" data-slide="0">
839
- <div class="slide-number">01 / Overview</div>
840
- <h1>✨ Autoconfig Complete</h1>
841
- <h2 class="typewriter" data-text="Here's what got installed. Hover over any file or folder to learn what it does."></h2>
842
- <div class="slide-content">
843
- <div class="tree-panel">
844
- <div class="tree-side">
845
- <div class="tree-content">
846
- <div class="tree-item" data-info="memory-md">
847
- <span class="tree-spacer"></span>
848
- <span class="tree-file-icon">📄</span>
849
- <span class="file">MEMORY.md</span>
850
- </div>
851
- <div class="tree-item folder-row" data-info="root" data-folder="root">
852
- <span class="tree-chevron">›</span>
853
- <span class="tree-folder-icon">📁</span>
854
- <span class="folder">your-project</span>
855
- </div>
856
- <div class="tree-item indent-1 folder-row collapsed" data-info="claude-dir" data-folder="claude-dir" data-parent="root">
857
- <span class="tree-chevron">›</span>
858
- <span class="tree-folder-icon">📁</span>
859
- <span class="folder">.claude</span>
860
- </div>
861
- <div class="tree-item indent-2 folder-row hidden collapsed" data-info="commands" data-folder="commands" data-parent="claude-dir">
862
- <span class="tree-chevron">›</span>
863
- <span class="tree-folder-icon">📁</span>
864
- <span class="folder">commands</span>
865
- </div>
866
- <div class="tree-item indent-3 hidden" data-info="autoconfig-update" data-parent="commands">
867
- <span class="tree-spacer"></span>
868
- <span class="tree-file-icon">📄</span>
869
- <span class="file">autoconfig-update.md</span>
870
- </div>
871
- <div class="tree-item indent-3 hidden" data-info="autoconfig" data-parent="commands">
872
- <span class="tree-spacer"></span>
873
- <span class="tree-file-icon">📄</span>
874
- <span class="file">autoconfig.md</span>
875
- </div>
876
- <div class="tree-item indent-3 hidden" data-info="commit-and-push" data-parent="commands">
877
- <span class="tree-spacer"></span>
878
- <span class="tree-file-icon">📄</span>
879
- <span class="file">commit-and-push.md</span>
880
- </div>
881
- <div class="tree-item indent-3 hidden" data-info="extract-rules" data-parent="commands">
882
- <span class="tree-spacer"></span>
883
- <span class="tree-file-icon">📄</span>
884
- <span class="file">extract-rules.md</span>
885
- </div>
886
- <div class="tree-item indent-3 hidden" data-info="gls" data-parent="commands">
887
- <span class="tree-spacer"></span>
888
- <span class="tree-file-icon">📄</span>
889
- <span class="file">gls.md</span>
890
- </div>
891
- <div class="tree-item indent-3 hidden" data-info="publish" data-parent="commands">
892
- <span class="tree-spacer"></span>
893
- <span class="tree-file-icon">📄</span>
894
- <span class="file">publish.md</span>
895
- </div>
896
- <div class="tree-item indent-3 hidden" data-info="recover-context" data-parent="commands">
897
- <span class="tree-spacer"></span>
898
- <span class="tree-file-icon">📄</span>
899
- <span class="file">recover-context.md</span>
900
- </div>
901
- <div class="tree-item indent-3 hidden" data-info="show-docs" data-parent="commands">
902
- <span class="tree-spacer"></span>
903
- <span class="tree-file-icon">📄</span>
904
- <span class="file">show-docs.md</span>
905
- </div>
906
- <div class="tree-item indent-3 hidden" data-info="test" data-parent="commands">
907
- <span class="tree-spacer"></span>
908
- <span class="tree-file-icon">📄</span>
909
- <span class="file">test.md</span>
910
- </div>
911
- <div class="tree-item indent-3 hidden" data-info="validate-cca-install" data-parent="commands">
912
- <span class="tree-spacer"></span>
913
- <span class="tree-file-icon">📄</span>
914
- <span class="file">validate-cca-install.md</span>
915
- </div>
916
- <div class="tree-item indent-2 folder-row hidden collapsed" data-info="agents" data-folder="agents" data-parent="claude-dir">
917
- <span class="tree-chevron">›</span>
918
- <span class="tree-folder-icon">📁</span>
919
- <span class="folder">agents</span>
920
- </div>
921
- <div class="tree-item indent-3 hidden" data-info="README-agent" data-parent="agents">
922
- <span class="tree-spacer"></span>
923
- <span class="tree-file-icon">📄</span>
924
- <span class="file">README.md</span>
925
- </div>
926
- <div class="tree-item indent-2 folder-row hidden collapsed" data-info="feedback" data-folder="feedback" data-parent="claude-dir">
927
- <span class="tree-chevron">›</span>
928
- <span class="tree-folder-icon">📁</span>
929
- <span class="folder">feedback</span>
930
- </div>
931
- <div class="tree-item indent-3 hidden" data-info="feedback-feedback" data-parent="feedback">
932
- <span class="tree-spacer"></span>
933
- <span class="tree-file-icon">📄</span>
934
- <span class="file">FEEDBACK.md</span>
935
- </div>
936
- <div class="tree-item indent-2 folder-row hidden collapsed" data-info="hooks" data-folder="hooks" data-parent="claude-dir">
937
- <span class="tree-chevron">›</span>
938
- <span class="tree-folder-icon">📁</span>
939
- <span class="folder">hooks</span>
940
- </div>
941
- <div class="tree-item indent-3 hidden" data-info="feedback-rule-check-hook" data-parent="hooks">
942
- <span class="tree-spacer"></span>
943
- <span class="tree-file-icon">📄</span>
944
- <span class="file">feedback-rule-check.js</span>
945
- </div>
946
- <div class="tree-item indent-3 hidden" data-info="format-hook" data-parent="hooks">
947
- <span class="tree-spacer"></span>
948
- <span class="tree-file-icon">📄</span>
949
- <span class="file">format.js</span>
950
- </div>
951
- <div class="tree-item indent-3 hidden" data-info="migrate-feedback-hook" data-parent="hooks">
952
- <span class="tree-spacer"></span>
953
- <span class="tree-file-icon">📄</span>
954
- <span class="file">migrate-feedback.js</span>
955
- </div>
956
- <div class="tree-item indent-2 folder-row hidden collapsed" data-info="docs" data-folder="docs-folder" data-parent="claude-dir">
957
- <span class="tree-chevron">›</span>
958
- <span class="tree-folder-icon">📁</span>
959
- <span class="folder">docs</span>
960
- </div>
961
- <div class="tree-item indent-3 hidden" data-info="docs" data-parent="docs-folder">
962
- <span class="tree-spacer"></span>
963
- <span class="tree-file-icon">🌐</span>
964
- <span class="file">autoconfig.docs.html</span>
965
- </div>
966
- <div class="tree-item indent-2 hidden" data-info="rules" data-parent="claude-dir">
967
- <span class="tree-spacer"></span>
968
- <span class="tree-folder-icon">📁</span>
969
- <span class="folder">rules</span>
970
- </div>
971
- <div class="tree-item indent-2 hidden" data-info="mcp" data-parent="claude-dir">
972
- <span class="tree-spacer"></span>
973
- <span class="tree-file-icon">🔌</span>
974
- <span class="file">.mcp.json</span>
975
- </div>
976
- <div class="tree-item indent-2 hidden" data-info="settings" data-parent="claude-dir">
977
- <span class="tree-spacer"></span>
978
- <span class="tree-file-icon">⚙️</span>
979
- <span class="file">settings.json</span>
980
- </div>
981
- </div>
982
- </div>
983
- <div class="info-side">
984
- <div class="info-panel" id="infoPanel">
985
- <div class="info-panel-title">Select a file</div>
986
- <div class="info-panel-desc">Hover over any item in the tree to see what it does.</div>
987
- </div>
988
- </div>
989
- </div>
990
- </div>
991
- </div>
992
-
993
- <!-- Slide 1: Finale -->
994
- <div class="slide" data-slide="1">
995
- <div class="slide-number">02 / You're Ready</div>
996
- <h1>That's It</h1>
997
- <h2 class="typewriter" data-text="You've got the autoconfig. Now go build something."></h2>
998
- <div class="slide-content">
999
- <div class="final-links">
1000
- <a href="https://github.com/design-and-deliver/claude-code-autoconfig" class="final-link" target="_blank">
1001
- ⭐ Star on GitHub
1002
- </a>
1003
- <a href="https://docs.anthropic.com/en/docs/claude-code/overview" class="final-link" target="_blank">
1004
- 📚 Claude Code Docs
1005
- </a>
1006
- </div>
1007
- </div>
1008
- </div>
1009
- </div>
1010
-
1011
- <div class="nav-container">
1012
- <button class="nav-btn prev" id="prevBtn">
1013
- Back
1014
- </button>
1015
- <button class="nav-btn next" id="nextBtn">
1016
- Next
1017
- </button>
1018
- </div>
1019
- </div>
1020
-
1021
- <script>
1022
- const slides = document.querySelectorAll('.slide');
1023
- const progressContainer = document.getElementById('progress');
1024
- const prevBtn = document.getElementById('prevBtn');
1025
- const nextBtn = document.getElementById('nextBtn');
1026
- let currentSlide = 0;
1027
-
1028
- // Create progress dots
1029
- slides.forEach((_, i) => {
1030
- const dot = document.createElement('div');
1031
- dot.className = 'progress-dot' + (i === 0 ? ' active' : '');
1032
- dot.addEventListener('click', () => goToSlide(i));
1033
- progressContainer.appendChild(dot);
1034
- });
1035
-
1036
- function updateProgress() {
1037
- document.querySelectorAll('.progress-dot').forEach((dot, i) => {
1038
- dot.classList.remove('active');
1039
- if (i === currentSlide) dot.classList.add('active');
1040
- });
1041
- }
1042
-
1043
- function goToSlide(index) {
1044
- if (index < 0 || index >= slides.length) return;
1045
-
1046
- const direction = index > currentSlide ? 1 : -1;
1047
-
1048
- slides[currentSlide].classList.remove('active');
1049
- if (direction > 0) {
1050
- slides[currentSlide].classList.add('exit');
1051
- }
1052
-
1053
- currentSlide = index;
1054
-
1055
- slides.forEach(s => s.classList.remove('exit'));
1056
- slides[currentSlide].classList.add('active');
1057
-
1058
- updateProgress();
1059
- updateButtons();
1060
- checkTypewriter();
1061
-
1062
- // Select CLAUDE.md by default when entering slide 0 (tree view)
1063
- if (currentSlide === 0) {
1064
- setTimeout(() => selectTreeItemByKey('memory-md'), 100);
1065
- }
1066
- }
1067
-
1068
- function updateButtons() {
1069
- // Hide back button on first slide, show on others
1070
- prevBtn.style.visibility = currentSlide === 0 ? 'hidden' : 'visible';
1071
-
1072
- if (currentSlide === slides.length - 1) {
1073
- nextBtn.textContent = 'Done';
1074
- } else {
1075
- nextBtn.textContent = 'Next';
1076
- }
1077
- }
1078
-
1079
- prevBtn.addEventListener('click', () => {
1080
- if (currentSlide > 0) {
1081
- goToSlide(currentSlide - 1);
1082
- }
1083
- });
1084
-
1085
- nextBtn.addEventListener('click', () => {
1086
- if (currentSlide < slides.length - 1) {
1087
- goToSlide(currentSlide + 1);
1088
- } else {
1089
- window.close();
1090
- }
1091
- });
1092
-
1093
- // Select CLAUDE.md on initial page load
1094
- setTimeout(() => selectTreeItemByKey('memory-md'), 300);
1095
-
1096
- // Keyboard navigation for slides
1097
- document.addEventListener('keydown', (e) => {
1098
- // On slide 0, arrow keys control tree - use spacebar for next slide
1099
- if (currentSlide === 0) {
1100
- if (e.key === ' ') {
1101
- e.preventDefault();
1102
- if (currentSlide < slides.length - 1) {
1103
- goToSlide(currentSlide + 1);
1104
- }
1105
- }
1106
- return; // Let tree keyboard handler deal with arrows
1107
- }
1108
-
1109
- // Space bar for next slide (but not on slide 0 with tree)
1110
- if (e.key === ' ' && currentSlide !== 0) {
1111
- e.preventDefault();
1112
- if (currentSlide < slides.length - 1) {
1113
- goToSlide(currentSlide + 1);
1114
- }
1115
- }
1116
- });
1117
-
1118
- updateButtons();
1119
-
1120
- // Auto-focus for keyboard navigation
1121
- document.body.setAttribute('tabindex', '0');
1122
- document.body.focus();
1123
-
1124
- // Detect project name from file path
1125
- function getProjectName() {
1126
- try {
1127
- const path = window.location.pathname;
1128
- const parts = path.split('/').filter(p => p && !p.includes(':'));
1129
- const claudeIndex = parts.indexOf('.claude');
1130
- if (claudeIndex > 0) {
1131
- return parts[claudeIndex - 1];
1132
- }
1133
- if (parts.length >= 3) {
1134
- return parts[parts.length - 3];
1135
- }
1136
- } catch (e) {}
1137
- return 'your-project';
1138
- }
1139
-
1140
- const projectName = getProjectName();
1141
-
1142
- // Update tree root with actual project name
1143
- const rootItem = document.querySelector('[data-info="root"]');
1144
- if (rootItem) {
1145
- rootItem.querySelector('.folder').textContent = projectName + '/';
1146
- }
1147
-
1148
- // Build full MEMORY.md path from project location
1149
- function getMemoryPath() {
1150
- try {
1151
- const path = window.location.pathname;
1152
- // Extract drive + full path up to .claude, then convert to Claude's encoding
1153
- const claudeIdx = path.indexOf('.claude');
1154
- if (claudeIdx > 0) {
1155
- const projectPath = path.substring(0, claudeIdx - 1);
1156
- // Claude encodes the path: C:\CODE\proj → C--CODE-proj
1157
- const parts = projectPath.split('/').filter(p => p);
1158
- const encoded = parts.join('-').replace(/:/g, '');
1159
- return '~/.claude/projects/' + encoded + '/memory/MEMORY.md';
1160
- }
1161
- } catch (e) {}
1162
- return '~/.claude/projects/' + projectName + '/memory/MEMORY.md';
1163
- }
1164
- const memoryPath = getMemoryPath();
1165
-
1166
- // Calculate tree side width dynamically
1167
- function setTreeWidth() {
1168
- const treeSide = document.querySelector('.tree-side');
1169
- const treeItems = document.querySelectorAll('.tree-item');
1170
- if (!treeSide || !treeItems.length) return;
1171
-
1172
- const hiddenItems = [];
1173
- treeItems.forEach(item => {
1174
- if (item.classList.contains('hidden')) {
1175
- hiddenItems.push(item);
1176
- item.style.visibility = 'hidden';
1177
- item.style.position = 'absolute';
1178
- item.classList.remove('hidden');
1179
- }
1180
- });
1181
-
1182
- let maxWidth = 0;
1183
- treeItems.forEach(item => {
1184
- const width = item.scrollWidth;
1185
- if (width > maxWidth) maxWidth = width;
1186
- });
1187
-
1188
- hiddenItems.forEach(item => {
1189
- item.classList.add('hidden');
1190
- item.style.visibility = '';
1191
- item.style.position = '';
1192
- });
1193
-
1194
- treeSide.style.width = Math.round((maxWidth + 32) * 1.25) + 'px';
1195
- treeSide.style.paddingLeft = '8px';
1196
- treeSide.style.paddingRight = '8px';
1197
- }
1198
-
1199
- if (document.fonts && document.fonts.ready) {
1200
- document.fonts.ready.then(setTreeWidth);
1201
- } else {
1202
- setTimeout(setTreeWidth, 100);
1203
- }
1204
-
1205
- // Typewriter effect
1206
- function typeWriter(element) {
1207
- const text = element.dataset.text;
1208
- if (!text) return;
1209
-
1210
- element.textContent = '';
1211
- element.classList.add('typing');
1212
- element.classList.remove('done');
1213
-
1214
- let i = 0;
1215
- const speed = 30;
1216
-
1217
- function type() {
1218
- if (i < text.length) {
1219
- element.textContent += text.charAt(i);
1220
- i++;
1221
- setTimeout(type, speed);
1222
- } else {
1223
- element.classList.remove('typing');
1224
- element.classList.add('done');
1225
- }
1226
- }
1227
-
1228
- setTimeout(type, 300);
1229
- }
1230
-
1231
- function checkTypewriter() {
1232
- const activeSlide = slides[currentSlide];
1233
- const typewriterEl = activeSlide.querySelector('.typewriter');
1234
- if (typewriterEl) {
1235
- typeWriter(typewriterEl);
1236
- }
1237
- }
1238
-
1239
- setTimeout(checkTypewriter, 100);
1240
-
1241
- // Tree panel info data - UPDATED
1242
- const treeInfo = {
1243
- 'memory-md': {
1244
- title: 'MEMORY.md',
1245
- desc: 'Native Claude Code file — loaded into the system prompt at the start of every session. Autoconfig appends debugging methodology instructions here so Claude always follows evidence-based troubleshooting.<br><br><span style="color: var(--accent-orange);">Location: ' + memoryPath + '</span>',
1246
- trigger: 'Loaded into system prompt automatically'
1247
- },
1248
- 'root': {
1249
- title: projectName,
1250
- desc: 'The autoconfig adds CLAUDE.md at your project root and configuration files inside a .claude/ directory. Nothing else is touched.'
1251
- },
1252
- 'claude-md': {
1253
- title: 'CLAUDE.md',
1254
- 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>',
1255
- trigger: 'Loaded automatically at session start'
1256
- },
1257
- 'claude-dir': {
1258
- title: '.claude/ Directory',
1259
- desc: 'Commands, rules, settings, and these docs. Keeps configuration organized as your project grows.'
1260
- },
1261
- 'rules': {
1262
- title: 'rules/',
1263
- desc: 'Path-scoped context that loads when Claude works on matching files.'
1264
- },
1265
- 'commands': {
1266
- title: 'commands/',
1267
- 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>.'
1268
- },
1269
- 'agents': {
1270
- title: 'agents/',
1271
- desc: 'Reusable agent definitions that Claude can invoke for specialized tasks.'
1272
- },
1273
- 'hooks': {
1274
- title: 'hooks/',
1275
- desc: 'Executable hook scripts that trigger on Claude Code events like PostToolUse.'
1276
- },
1277
- 'feedback': {
1278
- title: 'feedback/',
1279
- 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.'
1280
- },
1281
- 'autoconfig-update': {
1282
- title: 'autoconfig-update.md',
1283
- desc: 'Manages and installs updates to Claude Code configuration.<div style="margin-top: 12px;"><strong>Parameters</strong><div style="margin-top: 4px; opacity: 0.6;">None</div></div><div style="margin-top: 12px;"><strong>Responses</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Status</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>updates-available</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Displays list of pending updates with install/review options.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>up-to-date</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">All updates are already installed.</td></tr></table></div><div style="margin-top: 12px;"><strong>Side Effects</strong><div style="margin-top: 4px; font-size: 0.9em;">Pulls latest update files from npm, executes update instructions, tracks applied updates</div></div><div style="margin-top: 12px;"><strong>Examples</strong><div style="margin-top: 6px; background: var(--bg-elevated); border-radius: 6px; padding: 8px 12px; font-family: monospace; font-size: 0.85em;"><div><code>/autoconfig-update</code> <span style="opacity: 0.6;">— Check for and install configuration updates</span></div></div></div>',
1284
- trigger: '/autoconfig-update'
1285
- },
1286
- 'autoconfig': {
1287
- title: 'autoconfig.md',
1288
- desc: 'Configures Claude Code scaffolding for your project. Sets up settings, permissions, hooks, commands, and docs.<div style="margin-top: 12px;"><strong>Parameters</strong><div style="margin-top: 4px; opacity: 0.6;">None</div></div><div style="margin-top: 12px;"><strong>Responses</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Status</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>success</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Scaffolding configured, CLAUDE.md initialized, docs opened in browser.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>no-project</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">No project detected — asks user to confirm directory.</td></tr></table></div><div style="margin-top: 12px;"><strong>Side Effects</strong><div style="margin-top: 4px; font-size: 0.9em;">Initializes CLAUDE.md, settings.json, hooks, commands, and MEMORY.md</div></div><div style="margin-top: 12px;"><strong>Examples</strong><div style="margin-top: 6px; background: var(--bg-elevated); border-radius: 6px; padding: 8px 12px; font-family: monospace; font-size: 0.85em;"><div><code>/autoconfig</code> <span style="opacity: 0.6;">— Analyze project and configure Claude</span></div></div></div>',
1289
- trigger: '/autoconfig'
1290
- },
1291
- 'commit-and-push': {
1292
- title: 'commit-and-push.md',
1293
- desc: 'Runs tests, then stages all changes, generates a conventional commit message, commits, and pushes.<div style="margin-top: 12px;"><strong>Parameters</strong><div style="margin-top: 4px; opacity: 0.6;">None</div></div><div style="margin-top: 12px;"><strong>Responses</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Status</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>success</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Changes committed and pushed to current branch.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>test-failure</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Tests failed — no commit made.</td></tr></table></div><div style="margin-top: 12px;"><strong>Side Effects</strong><div style="margin-top: 4px; font-size: 0.9em;">Runs test suite, stages all changes, creates git commit, pushes to remote</div></div><div style="margin-top: 12px;"><strong>Examples</strong><div style="margin-top: 6px; background: var(--bg-elevated); border-radius: 6px; padding: 8px 12px; font-family: monospace; font-size: 0.85em;"><div><code>/commit-and-push</code> <span style="opacity: 0.6;">— Run tests, commit, and push</span></div></div></div>',
1294
- trigger: '/commit-and-push'
1295
- },
1296
- 'extract-rules': {
1297
- title: 'extract-rules.md',
1298
- desc: 'Scan Claude artifacts and extract structured rules into .claude/rules/<div style="margin-top: 12px;"><strong>Parameters</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Name</th><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Type</th><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Required</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>select</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>string</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">optional</td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Write only specific rules by number: "1,3,5". Default: all.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>keep-sources</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>boolean</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">optional</td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Write rules but skip source cleanup (Step 8)</td></tr></table></div><div style="margin-top: 12px;"><strong>Responses</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Status</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>success</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Rules extracted, written, and sources cleaned up.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>no-rules</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">No extractable rules found in scanned sources.</td></tr></table></div><div style="margin-top: 12px;"><strong>Side Effects</strong><div style="margin-top: 4px; font-size: 0.9em;">Creates .claude/rules/ files and removes extracted content from source files</div></div><div style="margin-top: 12px;"><strong>Examples</strong><div style="margin-top: 6px; background: var(--bg-elevated); border-radius: 6px; padding: 8px 12px; font-family: monospace; font-size: 0.85em;"><div><code>/extract-rules</code> <span style="opacity: 0.6;">— Scan, propose, prompt for approval, write, and clean up</span></div><div><code>/extract-rules --keep-sources</code> <span style="opacity: 0.6;">— Write rules without modifying source files</span></div><div><code>/extract-rules --select 1,3</code> <span style="opacity: 0.6;">— Write only rules #1 and #3</span></div></div></div>',
1299
- trigger: '/extract-rules'
1300
- },
1301
- 'gls': {
1302
- title: 'gls.md',
1303
- desc: 'Get the latest screenshot(s) and display them.<div style="margin-top: 12px;"><strong>Parameters</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Name</th><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Type</th><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Required</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>count</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>integer</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">optional</td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Number of screenshots to display. Use /gls-N syntax. Default: 1. Min: 1.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>path</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>string</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">optional</td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Screenshot directory path. Saved for future use. Auto-detected if omitted.</td></tr></table></div><div style="margin-top: 12px;"><strong>Responses</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Status</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>success</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Displays requested screenshot(s) from newest to oldest.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>no-screenshots</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Directory exists but contains no image files.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>no-directory</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Unable to detect screenshot directory — prompts for path.</td></tr></table></div><div style="margin-top: 12px;"><strong>Side Effects</strong><div style="margin-top: 4px; font-size: 0.9em;">Saves detected screenshot path to .claude/cca.config.json on first run</div></div><div style="margin-top: 12px;"><strong>Examples</strong><div style="margin-top: 6px; background: var(--bg-elevated); border-radius: 6px; padding: 8px 12px; font-family: monospace; font-size: 0.85em;"><div><code>/gls</code> <span style="opacity: 0.6;">— Display the most recent screenshot</span></div><div><code>/gls-3</code> <span style="opacity: 0.6;">— Display the 3 most recent screenshots</span></div><div><code>/gls /path/to/dir</code> <span style="opacity: 0.6;">— Use a specific screenshot directory</span></div></div></div>',
1304
- trigger: '/gls'
1305
- },
1306
- 'publish': {
1307
- title: 'publish.md',
1308
- desc: 'Runs tests, bumps version, commits, and publishes to npm.<div style="margin-top: 12px;"><strong>Parameters</strong><div style="margin-top: 4px; opacity: 0.6;">None</div></div>',
1309
- trigger: '/publish'
1310
- },
1311
- 'recover-context': {
1312
- title: 'recover-context.md',
1313
- desc: 'Recovers conversation context from the session transcript after compaction.<div style="margin-top: 12px;"><strong>Parameters</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Name</th><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Type</th><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Required</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>minutes</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>integer</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">required</td><td style="padding: 4px 8px 4px 0; vertical-align: top;">How far back to recover, in minutes. Leading dash optional. Min: 1.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>--show</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>flag</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">optional</td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Opens the extracted transcript in your default editor.</td></tr></table></div><div style="margin-top: 12px;"><strong>Responses</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Status</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>success</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">~{tokens} tokens recovered ({N} messages across {sessions} session(s), last {minutes} min).</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>no-transcript</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">No transcript files found.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>no-messages</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">No messages found in the requested time range.</td></tr></table></div><div style="margin-top: 12px;"><strong>Side Effects</strong><div style="margin-top: 4px; font-size: 0.9em;">Reads .jsonl transcripts from ~/.claude/projects/, writes temp file</div></div><div style="margin-top: 12px;"><strong>Examples</strong><div style="margin-top: 6px; background: var(--bg-elevated); border-radius: 6px; padding: 8px 12px; font-family: monospace; font-size: 0.85em;"><div><code>/recover-context -60</code> <span style="opacity: 0.6;">— Last 60 minutes of conversation</span></div><div><code>/recover-context 120</code> <span style="opacity: 0.6;">— Last 2 hours (dash optional)</span></div><div><code>/recover-context -60 --show</code> <span style="opacity: 0.6;">— Last 60 min + open transcript file</span></div></div></div>',
1314
- trigger: '/recover-context'
1315
- },
1316
- 'show-docs': {
1317
- title: 'show-docs.md',
1318
- desc: 'Opens the interactive docs in your browser.<div style="margin-top: 12px;"><strong>Parameters</strong><div style="margin-top: 4px; opacity: 0.6;">None</div></div><div style="margin-top: 12px;"><strong>Responses</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Status</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>success</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Docs synced and opened in default browser.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>no-docs</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Docs file not found — run /autoconfig first.</td></tr></table></div><div style="margin-top: 12px;"><strong>Side Effects</strong><div style="margin-top: 4px; font-size: 0.9em;">Runs sync-docs.js to refresh content, opens browser</div></div><div style="margin-top: 12px;"><strong>Examples</strong><div style="margin-top: 6px; background: var(--bg-elevated); border-radius: 6px; padding: 8px 12px; font-family: monospace; font-size: 0.85em;"><div><code>/show-docs</code> <span style="opacity: 0.6;">— Open interactive documentation</span></div></div></div>',
1319
- trigger: '/show-docs'
1320
- },
1321
- 'test': {
1322
- title: 'test.md',
1323
- desc: 'Runs your test suite. Auto-detects Jest, Vitest, Pytest, Go, RSpec, or falls back to npm test.<div style="margin-top: 12px;"><strong>Parameters</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Name</th><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Type</th><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Required</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>scope</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>string</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">optional</td><td style="padding: 4px 8px 4px 0; vertical-align: top;">File, directory, or pattern to limit test run. Runs full suite if omitted.</td></tr></table></div><div style="margin-top: 12px;"><strong>Responses</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Status</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>success</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Test suite passes.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>failure</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Test suite fails with non-zero exit code.</td></tr></table></div><div style="margin-top: 12px;"><strong>Side Effects</strong><div style="margin-top: 4px; font-size: 0.9em;">Executes detected test runner command</div></div><div style="margin-top: 12px;"><strong>Examples</strong><div style="margin-top: 6px; background: var(--bg-elevated); border-radius: 6px; padding: 8px 12px; font-family: monospace; font-size: 0.85em;"><div><code>/test</code> <span style="opacity: 0.6;">— Run full test suite</span></div><div><code>/test src/auth</code> <span style="opacity: 0.6;">— Run tests in src/auth directory</span></div><div><code>/test --coverage</code> <span style="opacity: 0.6;">— Run tests with coverage report</span></div></div></div>',
1324
- trigger: '/test'
1325
- },
1326
- 'validate-cca-install': {
1327
- title: 'validate-cca-install.md',
1328
- desc: 'Validates your claude-code-autoconfig installation against the latest published version.<div style="margin-top: 12px;"><strong>Parameters</strong><div style="margin-top: 4px; opacity: 0.6;">None</div></div><div style="margin-top: 12px;"><strong>Responses</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Status</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>valid</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Install validated — all checks passed.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>issues</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Validation found {N} issue(s) with fix suggestions.</td></tr></table></div><div style="margin-top: 12px;"><strong>Side Effects</strong><div style="margin-top: 4px; font-size: 0.9em;">Read-only. Downloads latest package to temp dir for comparison, then cleans up.</div></div><div style="margin-top: 12px;"><strong>Examples</strong><div style="margin-top: 6px; background: var(--bg-elevated); border-radius: 6px; padding: 8px 12px; font-family: monospace; font-size: 0.85em;"><div><code>/validate-cca-install</code> <span style="opacity: 0.6;">— Run full installation validation</span></div></div></div>',
1329
- trigger: '/validate-cca-install'
1330
- },
1331
- 'README-agent': {
1332
- title: 'README.md',
1333
- desc: 'Placeholder — drop your project\'s custom subagent definitions in this directory.',
1334
- trigger: 'Background agent'
1335
- },
1336
- 'feedback-rule-check-hook': {
1337
- title: 'feedback-rule-check.js',
1338
- desc: 'After FEEDBACK.md is edited, notifies Claude to evaluate',
1339
- trigger: 'PostToolUse on Write|Edit'
1340
- },
1341
- 'format-hook': {
1342
- title: 'format.js',
1343
- desc: 'format.js in hooks/',
1344
- trigger: 'PostToolUse hook'
1345
- },
1346
- 'migrate-feedback-hook': {
1347
- title: 'migrate-feedback.js',
1348
- desc: 'On session start, migrates custom FEEDBACK.md content to',
1349
- trigger: 'SessionStart'
1350
- },
1351
- 'feedback-feedback': {
1352
- title: 'FEEDBACK.md',
1353
- desc: 'Human-authored corrections and guidance for Claude. Reserved for team feedback only — Claude must not write here. This directory persists across /autoconfig runs.'
1354
- },
1355
- 'docs': {
1356
- title: 'docs/autoconfig.docs.html',
1357
- desc: 'This interactive docs. Open it anytime to review what each file does.',
1358
- trigger: '/show-docs'
1359
- },
1360
- 'rules': {
1361
- title: 'rules/',
1362
- 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>'
1363
- },
1364
- 'mcp': {
1365
- title: '.mcp.json',
1366
- desc: 'MCP (Model Context Protocol) server configuration. Add your MCP servers here.'
1367
- },
1368
- 'settings': {
1369
- title: 'settings.json',
1370
- desc: 'Permissions and security settings. Controls what Claude can auto-approve (allow) and what is always blocked (deny).'
1371
- }
1372
- };
1373
-
1374
- // Tree panel hover handling
1375
- const infoPanel = document.getElementById('infoPanel');
1376
- const treeItems = document.querySelectorAll('.tree-item');
1377
-
1378
- let selectedInfoKey = 'memory-md'; // Default selection
1379
-
1380
- function showInfo(key) {
1381
- const info = treeInfo[key];
1382
- if (info) {
1383
- let html = `<div class="info-panel-title">${info.title}</div>`;
1384
- html += `<div class="info-panel-desc">${info.desc}</div>`;
1385
- if (info.trigger) {
1386
- html += `<div class="info-panel-trigger">${info.trigger}</div>`;
1387
- }
1388
- infoPanel.innerHTML = html;
1389
- }
1390
- }
1391
-
1392
- treeItems.forEach((item, idx) => {
1393
- // Hover updates info panel only (preview)
1394
- item.addEventListener('mouseenter', () => {
1395
- const key = item.dataset.info;
1396
- showInfo(key);
1397
- });
1398
-
1399
- // Mouseleave restores selected item's info
1400
- item.addEventListener('mouseleave', () => {
1401
- showInfo(selectedInfoKey);
1402
- });
1403
-
1404
- // Click sets active selection
1405
- item.addEventListener('click', (e) => {
1406
- // Don't select if clicking on a folder chevron (let toggle handle it)
1407
- if (e.target.classList.contains('tree-chevron')) return;
1408
-
1409
- treeItems.forEach(i => i.classList.remove('active'));
1410
- item.classList.add('active');
1411
-
1412
- // Update selected info key
1413
- selectedInfoKey = item.dataset.info;
1414
- showInfo(selectedInfoKey);
1415
-
1416
- // Sync selectedTreeIndex with visible items
1417
- const visibleItems = Array.from(document.querySelectorAll('.tree-item:not(.hidden)'));
1418
- selectedTreeIndex = visibleItems.indexOf(item);
1419
- });
1420
- });
1421
-
1422
- // Folder collapse/expand handling
1423
- function toggleFolder(folderId, collapsed) {
1424
- const children = document.querySelectorAll(`[data-parent="${folderId}"]`);
1425
- children.forEach(child => {
1426
- if (collapsed) {
1427
- child.classList.add('hidden');
1428
- } else {
1429
- child.classList.remove('hidden');
1430
- if (child.dataset.folder && !child.classList.contains('collapsed')) {
1431
- toggleFolder(child.dataset.folder, false);
1432
- }
1433
- }
1434
- if (collapsed && child.dataset.folder) {
1435
- toggleFolder(child.dataset.folder, true);
1436
- }
1437
- });
1438
- }
1439
-
1440
- document.querySelectorAll('.folder-row').forEach(folder => {
1441
- folder.addEventListener('click', (e) => {
1442
- const folderId = folder.dataset.folder;
1443
- const isCollapsed = folder.classList.toggle('collapsed');
1444
- toggleFolder(folderId, isCollapsed);
1445
- });
1446
- });
1447
-
1448
- // Tree keyboard navigation
1449
- let selectedTreeIndex = -1;
1450
-
1451
- function getVisibleTreeItems() {
1452
- return Array.from(document.querySelectorAll('.tree-item:not(.hidden)'));
1453
- }
1454
-
1455
- function selectTreeItemByKey(key) {
1456
- const item = document.querySelector(`.tree-item[data-info="${key}"]`);
1457
- if (!item) return;
1458
-
1459
- treeItems.forEach(i => i.classList.remove('active'));
1460
- item.classList.add('active');
1461
-
1462
- selectedInfoKey = key;
1463
- showInfo(selectedInfoKey);
1464
-
1465
- // Update selectedTreeIndex
1466
- const visibleItems = getVisibleTreeItems();
1467
- selectedTreeIndex = visibleItems.indexOf(item);
1468
- }
1469
-
1470
- function selectTreeItem(index) {
1471
- const items = getVisibleTreeItems();
1472
- if (index < 0 || index >= items.length) return;
1473
-
1474
- treeItems.forEach(i => i.classList.remove('active'));
1475
-
1476
- selectedTreeIndex = index;
1477
- const item = items[index];
1478
- item.classList.add('active');
1479
-
1480
- item.scrollIntoView({ block: 'nearest' });
1481
-
1482
- selectedInfoKey = item.dataset.info;
1483
- showInfo(selectedInfoKey);
1484
- }
1485
-
1486
- document.addEventListener('keydown', (e) => {
1487
- if (currentSlide !== 0) return;
1488
-
1489
- const items = getVisibleTreeItems();
1490
- if (items.length === 0) return;
1491
-
1492
- if (selectedTreeIndex === -1) {
1493
- selectTreeItem(0);
1494
- if (e.key === 'ArrowDown' || e.key === 'ArrowUp' || e.key === 'ArrowRight' || e.key === 'ArrowLeft') {
1495
- e.preventDefault();
1496
- }
1497
- return;
1498
- }
1499
-
1500
- if (e.key === 'ArrowDown') {
1501
- e.preventDefault();
1502
- if (selectedTreeIndex < items.length - 1) {
1503
- selectTreeItem(selectedTreeIndex + 1);
1504
- }
1505
- } else if (e.key === 'ArrowUp') {
1506
- e.preventDefault();
1507
- if (selectedTreeIndex > 0) {
1508
- selectTreeItem(selectedTreeIndex - 1);
1509
- }
1510
- } else if (e.key === 'ArrowRight') {
1511
- e.preventDefault();
1512
- const item = items[selectedTreeIndex];
1513
- if (item && item.classList.contains('folder-row')) {
1514
- if (item.classList.contains('collapsed')) {
1515
- item.classList.remove('collapsed');
1516
- toggleFolder(item.dataset.folder, false);
1517
- }
1518
- }
1519
- } else if (e.key === 'ArrowLeft') {
1520
- e.preventDefault();
1521
- const item = items[selectedTreeIndex];
1522
- if (item && item.classList.contains('folder-row')) {
1523
- if (!item.classList.contains('collapsed')) {
1524
- item.classList.add('collapsed');
1525
- toggleFolder(item.dataset.folder, true);
1526
- }
1527
- }
1528
- } else if (e.key === 'Enter') {
1529
- e.preventDefault();
1530
- const item = items[selectedTreeIndex];
1531
- if (item && item.classList.contains('folder-row')) {
1532
- const isCollapsed = item.classList.toggle('collapsed');
1533
- toggleFolder(item.dataset.folder, isCollapsed);
1534
- }
1535
- }
1536
- });
1537
-
1538
- // File Preview Modal
1539
- const fileContents = {
1540
- 'memory-md': {
1541
- filename: 'MEMORY.md',
1542
- content: `# Native Claude Code File — Debugging instructions appended by autoconfig
1543
-
1544
- Location: ` + memoryPath + `
1545
-
1546
- ---
1547
-
1548
- ## Debugging — Evidence Before Solutions
1549
- NEVER guess the root cause and jump to coding a fix. Always:
1550
- 1. Add logging / check actual data first
1551
- 2. Confirm root cause with evidence
1552
- 3. Only then propose and implement a fix
1553
- If you can't determine the cause from code alone, add diagnostic logging and verify with runtime data.
1554
- CRITICAL: A plausible-looking cause from code reading is NOT confirmed evidence. Even if a mismatch looks obvious across multiple files, verify with runtime data before implementing. The more "obvious" the cause looks, the more important it is to verify — that's when the temptation to skip evidence gathering is strongest.`
1555
- },
1556
- 'claude-md': {
1557
- filename: 'CLAUDE.md',
1558
- content: `# Project Name
1559
-
1560
- > Run \`/autoconfig\` to populate this based on your project.`
1561
- },
1562
- 'autoconfig-update': {
1563
- filename: 'autoconfig-update.md',
1564
- content: `<!-- @applied
1565
- -->
1566
-
1567
- # Autoconfig Update
1568
-
1569
- Check for and install pending updates to your Claude Code configuration.
1570
-
1571
- **Style guideline**: Work silently through Steps 1-3. Do not narrate internal steps, implementation details, or progress messages (e.g., "Let me check...", "The @applied block is empty..."). The first output the user sees should be the formatted summary in Step 4 (or the "up to date" message).
1572
-
1573
- ## Step 1: Pull Latest Updates
1574
-
1575
- Run this command via Bash to pull new update files from the latest package:
1576
-
1577
- \`\`\`bash
1578
- npx claude-code-autoconfig@latest --pull-updates
1579
- \`\`\`
1580
-
1581
- This copies any new update \`.md\` files into \`.claude/updates/\` and refreshes this command file (preserving the \`@applied\` block above).
1582
-
1583
- After the command completes, check \`.claude/updates/\` directory. If it doesn't exist or is empty, output:
1584
-
1585
- \`\`\`
1586
- No new updates available. You're up to date.
1587
- \`\`\`
1588
-
1589
- Then stop — do not continue to further steps.
1590
-
1591
- ## Step 2: Parse Update Files
1592
-
1593
- Read all \`.md\` files in \`.claude/updates/\` matching the pattern \`NNN-*.md\` (e.g., \`001-debug-methodology.md\`).`
1594
- },
1595
- 'autoconfig': {
1596
- filename: 'autoconfig.md',
1597
- content: `# Autoconfig
1598
-
1599
- Configure Claude Code scaffolding for this project — settings, permissions, hooks, commands, and docs.
1600
-
1601
- CLAUDE.md is intentionally kept minimal. Claude can read your config files directly — pre-populating project descriptions wastes tokens and dilutes important rules. Instead, CLAUDE.md grows organically through Discoveries as you work.
1602
-
1603
- **Setup Note**: During autoconfig, prefer Glob/Read/Write tools over Bash commands. This ensures smooth setup without permission prompts. Only use Bash for the bootstrap step and opening the guide at the end.
1604
-
1605
- ## Step 0a: Bootstrap files from latest package
1606
-
1607
- **MANDATORY: You MUST run this Bash command before doing anything else.** Do not skip it. Do not assume it will fail. It is designed to work inside Claude Code sessions:
1608
-
1609
- \`\`\`bash
1610
- npx claude-code-autoconfig@latest --bootstrap
1611
- \`\`\`
1612
-
1613
- This downloads the latest package and copies slash commands, hooks, agents, docs, and settings into \`.claude/\`. The \`--bootstrap\` flag makes it safe to run inside Claude Code — it copies files and exits silently with code 0. If it fails (e.g., no network), continue anyway — the existing files will still work.
1614
-
1615
- ## Step 0b: Migrate FEEDBACK.md to Discoveries (one-time)
1616
-
1617
- Read \`.claude/feedback/FEEDBACK.md\`. If it contains custom content beyond the default template header (sections after the first \`---\`), and \`CLAUDE.md\` does NOT already have a \`## Discoveries\` section:
1618
-
1619
- 1. Read all custom content from FEEDBACK.md (everything after the first \`---\` separator)
1620
- 2. Append a \`## Discoveries\` section to the bottom of CLAUDE.md with that content
1621
- 3. Reset FEEDBACK.md to the clean template:
1622
- \`\`\`
1623
- <!-- @description Human-authored corrections and guidance for Claude. Reserved for team feedback only — Claude must not write here. This directory persists across /autoconfig runs. -->
1624
-
1625
- # Team Feedback`
1626
- },
1627
- 'commit-and-push': {
1628
- filename: 'commit-and-push.md',
1629
- content: `# Commit and Push
1630
-
1631
- Run tests, stage all changes, create a commit with a good message, and push to the current branch.
1632
-
1633
- ## Steps
1634
-
1635
- 1. Run the project's test suite (e.g., \`npm test\`)
1636
- 2. **If tests fail, stop here.** Do not commit or push failing code.
1637
- 3. Stage all changes (\`git add -A\`)
1638
- 4. Generate a conventional commit message based on the diff
1639
- 5. Commit the changes
1640
- 6. Push to the current branch
1641
-
1642
- ## Commit Message Format
1643
-
1644
- Use conventional commits: \`type(scope): description\`
1645
-
1646
- Types: feat, fix, docs, style, refactor, test, chore
1647
-
1648
- Keep the subject line under 50 chars. Add body if the change needs explanation.`
1649
- },
1650
- 'extract-rules': {
1651
- filename: 'extract-rules.md',
1652
- content: `# Extract Rules
1653
-
1654
- Scan all Claude configuration artifacts and propose structured rules for \`.claude/rules/\`.
1655
-
1656
- ## Step 0: Git safety check
1657
-
1658
- Before doing anything else, check for uncommitted changes:
1659
-
1660
- \`\`\`bash
1661
- git status --porcelain
1662
- \`\`\`
1663
-
1664
- If there are uncommitted changes, show this warning and wait for confirmation:
1665
-
1666
- > **Warning:** This command will modify files (extract rules from sources and optionally clean up originals). You have uncommitted changes.
1667
- >
1668
- > Commit your work before proceeding, or type "continue" to proceed anyway.
1669
-
1670
- If the working tree is clean, proceed silently.
1671
-
1672
- ## Step 1: Discover sources
1673
-
1674
- Scan these locations for \`.md\` files containing potential rules. **Skip any that don't exist** — not all projects have all of these:
1675
-
1676
- 1. \`CLAUDE.md\` (project root)
1677
- 2. \`CLAUDE.local.md\` (project root, if present)
1678
- 3. All \`.md\` files in \`.claude/\` recursively (feedback, commands, etc.) — **excluding** \`.claude/rules/\` and \`.claude/commands/extract-rules.md\`
1679
- 4. Any nested \`CLAUDE.md\` files in subdirectories (e.g., \`src/CLAUDE.md\`)
1680
- 5. Auto memory files — memory often contains misplaced imperatives that should be promoted to rules. To find the memory directory, list \`~/.claude/projects/\` and fuzzy-match against the current project path. The directory name encodes the path with dashes replacing separators, but encoding varies by platform and may not be consistent for paths with spaces, special characters, or deep nesting. **Discovery strategy**: list all directories under \`~/.claude/projects/\`, then find the one whose name best matches the current working directory (check if the directory name contains key path segments like the project folder name). Read \`MEMORY.md\` in that directory, then each \`.md\` file it links to. If no match is found or the memory directory can't be read, skip this source silently.`
1681
- },
1682
- 'gls': {
1683
- filename: 'gls.md',
1684
- content: `Get the latest screenshot(s) and display them.
1685
-
1686
- Usage:
1687
- - \`/gls\` - Get and display the most recent screenshot
1688
- - \`/gls-2\` - Get and display the 2 most recent screenshots
1689
- - \`/gls-3\` - Get and display the 3 most recent screenshots
1690
- - \`/gls-N\` - Get and display the N most recent screenshots
1691
- - \`/gls /path/to/dir\` - Use a specific directory and save it
1692
-
1693
- ## Step 1: Check for saved path
1694
-
1695
- Read \`.claude/cca.config.json\` in the project root. If it exists and contains a \`gls.screenshotDir\` value, use that path and skip to Step 3.
1696
-
1697
- If the file doesn't exist or the key is missing, continue to Step 2.
1698
-
1699
- ## Step 2: Detect screenshot directory
1700
-
1701
- If the user provides a path as an argument (e.g., \`/gls /path/to/dir\`), use that path and skip to Step 2b.
1702
-
1703
- Otherwise, detect the OS and find the screenshot directory. Run this **single Bash command** which finds all candidate directories and reports the newest screenshot in each:
1704
-
1705
- \`\`\`bash
1706
- OS=$(uname -s); echo "OS=$OS"; for d in \\
1707
- "$HOME/OneDrive/Pictures/Screenshots"* \\
1708
- "$HOME/Pictures/Screenshots" \\
1709
- "$HOME/Desktop" \\
1710
- "$HOME/Pictures" \\
1711
- "$HOME/Videos/Captures"; do \\
1712
- [ -d "$d" ] || continue; \\
1713
- newest=$(ls -t "$d/" 2>/dev/null | grep -iE '\\.(png|jpg|jpeg|bmp|webp|gif)$' | head -1); \\`
1714
- },
1715
- 'publish': {
1716
- filename: 'publish.md',
1717
- content: `# Publish
1718
-
1719
- Run tests, bump the patch version, commit, push, and publish to npm.
1720
-
1721
- ## Steps
1722
-
1723
- 1. **Sync README.md** — Compare the current README against the actual state of the project (file tree, slash commands, features, settings). If anything is out of date or missing, update the README before proceeding. Check:
1724
- - File tree matches actual \`.claude/\` directory contents
1725
- - Slash commands table matches actual \`.claude/commands/\` files
1726
- - Feature sections reflect current capabilities (update system, MEMORY.md, hooks, etc.)
1727
- - No references to nonexistent commands or files
1728
- 2. Run the project's test suite (\`npm test\`)
1729
- 3. **If tests fail, stop here.** Do not publish broken code.
1730
- 4. Check for uncommitted changes. If there are any:
1731
- a. Stage all changes (\`git add -A\`)
1732
- b. Generate a conventional commit message based on the diff
1733
- c. Commit the changes
1734
- 5. Bump the version: \`npm version patch\`
1735
- 6. Push the commit and tag: \`git push && git push --tags\`
1736
- 7. Publish to npm: \`npm publish\`
1737
- 8. Output the new version number on success
1738
-
1739
- ## Important
1740
-
1741
- - Always run tests before publishing — never skip this step
1742
- - If any step fails, stop immediately and report the error
1743
- - Do not use \`--force\` on publish unless the user explicitly asks`
1744
- },
1745
- 'recover-context': {
1746
- filename: 'recover-context.md',
1747
- content: `Recover recent conversation context from the raw session transcript on disk.
1748
-
1749
- Usage:
1750
- - \`/recover-context -60\` — last 60 minutes of conversation
1751
- - \`/recover-context -60 --show\` — same, but also opens the transcript in your editor
1752
-
1753
- The number means "go back N minutes from now." The leading dash is optional. The minutes argument is **required**.
1754
-
1755
- ## Step 1: Parse the arguments
1756
-
1757
- The arguments are: $ARGUMENTS
1758
-
1759
- - If empty or missing, ask the user: "How many minutes back? (e.g., -60)"
1760
- - Strip the leading \`-\` from the number and treat it as the number of minutes to look back
1761
- - Check if \`--show\` flag is present
1762
-
1763
- ## Step 2: List candidate transcript files
1764
-
1765
- List all \`.jsonl\` transcript files sorted by most recently modified:
1766
-
1767
- \`\`\`bash
1768
- ls -t ~/.claude/projects/*/*.jsonl 2>/dev/null | head -20
1769
- \`\`\`
1770
-
1771
- If no transcripts are found, tell the user and stop. Store the list as \`$TRANSCRIPT_FILES\` (one path per line).
1772
-
1773
- ## Step 3: Identify which files to parse (lazy probing)
1774
-
1775
- For each file in \`$TRANSCRIPT_FILES\` (starting from most recent), probe its time range by reading only the **first and last timestamp** — do NOT parse the full file yet. Run this script, substituting \`$MINUTES\` and \`$TRANSCRIPT_FILES\`:`
1776
- },
1777
- 'show-docs': {
1778
- filename: 'show-docs.md',
1779
- content: `# Show Docs
1780
-
1781
- Open the interactive documentation for Claude Code Autoconfig.
1782
-
1783
- ## Step 1: Sync Docs
1784
-
1785
- Run the sync script to ensure the docs reflect the current state of \`.claude/\`:
1786
-
1787
- \`\`\`bash
1788
- node .claude/scripts/sync-docs.js
1789
- \`\`\`
1790
-
1791
- This scans all files in \`.claude/\` (commands, hooks, agents, feedback, updates, settings) and updates the docs HTML file tree, info cards, and content previews automatically. It's fast and idempotent.
1792
-
1793
- If the script fails (e.g., file not found), skip to Step 2 — the docs will still open with whatever content they have.
1794
-
1795
- ## Step 2: Open Docs
1796
-
1797
- Open the docs in the default browser. Use the command matching the current OS:
1798
-
1799
- - **macOS:** \`open .claude/docs/autoconfig.docs.html\`
1800
- - **Linux:** \`xdg-open .claude/docs/autoconfig.docs.html\`
1801
- - **Windows:** \`powershell -NoProfile -Command "Start-Process '.claude/docs/autoconfig.docs.html'"\`
1802
-
1803
- **Important:** If the command exits with a non-zero exit code or produces an error, tell the user the file failed to open and suggest they open it manually. Do NOT report success unless the command completed without error.`
1804
- },
1805
- 'test': {
1806
- filename: 'test.md',
1807
- content: `# Run Tests
1808
-
1809
- Run tests for this project.
1810
-
1811
- **Scope:** $ARGUMENTS
1812
-
1813
- If no scope provided, run the full test suite. Otherwise run tests matching the scope (file, directory, or pattern).
1814
-
1815
- Detect the test command from project config (package.json scripts, pytest, go test, etc.) and execute it.`
1816
- },
1817
- 'validate-cca-install': {
1818
- filename: 'validate-cca-install.md',
1819
- content: `Validate the current claude-code-autoconfig installation. Reports what's correct, what's outdated, and what's missing. **Does not modify anything.**
1820
-
1821
- Usage:
1822
- - \`/validate-cca-install\` — run a full validation check
1823
-
1824
- ## Step 1: Fetch the latest package metadata
1825
-
1826
- Query the npm registry for the latest published version and its file manifest:
1827
-
1828
- \`\`\`bash
1829
- python3 -c "
1830
- import json, urllib.request
1831
- url = 'https://registry.npmjs.org/claude-code-autoconfig/latest'
1832
- data = json.loads(urllib.request.urlopen(url, timeout=10).read())
1833
- print(json.dumps({'version': data.get('version', 'unknown')}))
1834
- "
1835
- \`\`\`
1836
-
1837
- Store the latest version as \`$LATEST_VERSION\`.
1838
-
1839
- ## Step 2: Download and extract the latest package to a temp directory
1840
-
1841
- \`\`\`bash
1842
- TMPDIR=$(mktemp -d)
1843
- npm pack claude-code-autoconfig@latest --pack-destination "$TMPDIR" 2>/dev/null
1844
- tar -xzf "$TMPDIR"/*.tgz -C "$TMPDIR"
1845
- echo "$TMPDIR/package"
1846
- \`\`\`
1847
-
1848
- Store the extracted path as \`$PKG_DIR\`. This gives us the ground truth for what files and versions should be installed.`
1849
- },
1850
- 'README-agent': {
1851
- filename: 'README.md',
1852
- content: `# Agents
1853
-
1854
- This directory is where you define **subagents** — focused assistants Claude can delegate to during a task (e.g., a code reviewer, a test writer, a security auditor).
1855
-
1856
- claude-code-autoconfig ships this folder empty so you can populate it with agents tuned to your project. Each agent is a single Markdown file with frontmatter describing its purpose, tools, and system prompt.
1857
-
1858
- See Anthropic's subagents docs for the file format:
1859
- https://docs.anthropic.com/en/docs/claude-code/sub-agents`
1860
- },
1861
- 'feedback-rule-check-hook': {
1862
- filename: 'feedback-rule-check.js',
1863
- content: `#!/usr/bin/env node
1864
-
1865
- /**
1866
- * @name Feedback Rule Migration Check
1867
- * @description After FEEDBACK.md is edited, notifies Claude to evaluate
1868
- * whether any entries would be more reliably delivered as
1869
- * .claude/rules/ files with glob patterns.
1870
- * @trigger PostToolUse on Write|Edit
1871
- */
1872
-
1873
- // Read hook input from stdin
1874
- let input = '';
1875
- process.stdin.setEncoding('utf8');
1876
- process.stdin.on('data', chunk => input += chunk);
1877
- process.stdin.on('end', () => {
1878
- try {
1879
- const data = JSON.parse(input);
1880
- const filePath = data?.tool_input?.file_path || '';
1881
-
1882
- // Only fire for FEEDBACK.md edits
1883
- if (!filePath.endsWith('FEEDBACK.md')) {
1884
- process.exit(0);
1885
- }
1886
-
1887
- console.log([
1888
- 'FEEDBACK.md was just modified.',
1889
- 'Review the changes and evaluate whether any entries are tied to specific file types,',
1890
- 'frameworks, or patterns that could be scoped with a glob (e.g., *.py, *.tsx, src/api/**).',
1891
- '',
1892
- 'If any entries qualify, ask the user:',`
1893
- },
1894
- 'format-hook': {
1895
- filename: 'format.js',
1896
- content: `#!/usr/bin/env node
1897
-
1898
- /**
1899
- * @name Format Hook
1900
- * @description Runs project formatter after Write/Edit operations
1901
- * @trigger PostToolUse on Write|Edit
1902
- */
1903
-
1904
- const { execSync } = require('child_process');
1905
- const path = require('path');
1906
-
1907
- // Read hook input from stdin
1908
- let input = '';
1909
- process.stdin.setEncoding('utf8');
1910
- process.stdin.on('data', chunk => input += chunk);
1911
- process.stdin.on('end', () => {
1912
- try {
1913
- const data = JSON.parse(input);
1914
- handleHook(data);
1915
- } catch (err) {
1916
- // Silent exit if no valid input
1917
- process.exit(0);
1918
- }
1919
- });
1920
-
1921
- function handleHook(data) {
1922
- const filePath = data?.tool_input?.file_path || '';
1923
-
1924
- // Skip non-source files
1925
- if (!filePath.match(/\\.(js|jsx|ts|tsx|json|css|scss|md|html)$/)) {`
1926
- },
1927
- 'migrate-feedback-hook': {
1928
- filename: 'migrate-feedback.js',
1929
- content: `#!/usr/bin/env node
1930
-
1931
- /**
1932
- * @name Feedback to Discoveries Migration
1933
- * @description On session start, migrates custom FEEDBACK.md content to
1934
- * CLAUDE.md Discoveries section. One-time, idempotent.
1935
- * @trigger SessionStart
1936
- */
1937
-
1938
- const fs = require('fs');
1939
- const path = require('path');
1940
-
1941
- const cwd = process.cwd();
1942
- const claudeMdPath = path.join(cwd, 'CLAUDE.md');
1943
- const feedbackPath = path.join(cwd, '.claude', 'feedback', 'FEEDBACK.md');
1944
-
1945
- // Read hook input from stdin (required by hook protocol)
1946
- let input = '';
1947
- process.stdin.setEncoding('utf8');
1948
- process.stdin.on('data', chunk => input += chunk);
1949
- process.stdin.on('end', () => {
1950
- try {
1951
- migrate();
1952
- } catch (err) {
1953
- // Silent exit on any error
1954
- }
1955
- process.exit(0);
1956
- });
1957
-
1958
- function migrate() {`
1959
- },
1960
- 'feedback-feedback': {
1961
- filename: 'FEEDBACK.md',
1962
- content: `# Team Feedback
1963
-
1964
- **This file is for human-authored corrections and guidance only.**
1965
- Claude reads this file but must never write to it. When Claude discovers project context, gotchas, or learnings, it should append to the \`## Discoveries\` section in CLAUDE.md instead.
1966
-
1967
- ---`
1968
- },
1969
- 'rules': {
1970
- filename: 'rules/',
1971
- content: null,
1972
- empty: true,
1973
- emptyMessage: 'Add .md files here to define rules for specific paths in your codebase.'
1974
- },
1975
- 'hooks': {
1976
- filename: 'hooks/',
1977
- content: null,
1978
- empty: true,
1979
- emptyMessage: 'Contains executable hook scripts that trigger on Claude Code events.'
1980
- },
1981
- 'docs': {
1982
- filename: 'autoconfig.docs.html',
1983
- content: null,
1984
- empty: true,
1985
- emptyMessage: "You\'re looking at it! 👀"
1986
- },
1987
- 'rules': {
1988
- filename: 'rules/',
1989
- content: null,
1990
- empty: true,
1991
- emptyMessage: 'This directory is empty.\nAdd .md files here to define rules for specific paths in your codebase.'
1992
- },
1993
- 'settings': {
1994
- filename: 'settings.json',
1995
- content: `{
1996
- "env": {
1997
- "CLAUDE_CODE_DISABLE_AUTO_MEMORY": "0"
1998
- },
1999
- "hooks": {
2000
- "SessionStart": [
2001
- {
2002
- "matcher": "",
2003
- "hooks": [
2004
- {
2005
- "type": "command",
2006
- "command": "node .claude/hooks/migrate-feedback.js"
2007
- }
2008
- ]
2009
- }
2010
- ],
2011
- "PostToolUse": [
2012
- {
2013
- "matcher": "Edit|Write",
2014
- "hooks": [
2015
- {
2016
- "type": "command",
2017
- "command": "node .claude/hooks/feedback-rule-check.js"
2018
- }
2019
- ]
2020
- }
2021
- ]
2022
- },
2023
- "permissions": {
2024
- "allow": [
2025
- "Read(./**)",
2026
- "Edit(./**)",
2027
- "Write(./**)",
2028
- "Glob",
2029
- "Grep",
2030
- "WebSearch",
2031
- "WebFetch",
2032
- "Bash(npm test)",
2033
- "Bash(npm test *)",
2034
- "Bash(npm run dev)",
2035
- "Bash(npm run build)",
2036
- "Bash(npm run lint)",
2037
- "Bash(npm run lint:fix)",
2038
- "Bash(npm run typecheck)",
2039
- "Bash(npm run test)",
2040
- "Bash(npm run test:*)",
2041
- "Bash(npm run validate)",
2042
- "Bash(git status)",
2043
- "Bash(git status *)",
2044
- "Bash(git diff *)",
2045
- "Bash(git add *)",
2046
- "Bash(git commit *)",
2047
- "Bash(git push *)",
2048
- "Bash(git pull)",
2049
- "Bash(git pull *)",
2050
- "Bash(git checkout *)",
2051
- "Bash(git branch *)",
2052
- "Bash(node .claude/*)",
2053
- "Bash(python3 *)",
2054
- "Bash(npx claude-code-autoconfig*)",
2055
- "Bash(npm pack *)",
2056
- "Bash(tar *)",
2057
- "Bash(mktemp *)",
2058
- "Bash(find ./*)",
2059
- "Bash(ls *)",
2060
- "Bash(dir *)",
2061
- "Bash(mkdir *)",
2062
- "Bash(mkdir -p *)",
2063
- "Bash(start *)",
2064
- "Bash(start .claude *)",
2065
- "Bash(open *)",
2066
- "Bash(open .claude *)",
2067
- "Bash(xdg-open *)",
2068
- "Bash(xdg-open .claude *)"
2069
- ],
2070
- "deny": [
2071
- "Read(./.env)",
2072
- "Read(./.env.*)",
2073
- "Read(./secrets/**)",
2074
- "Read(./**/credentials.*)",
2075
- "Read(./**/*.pem)",
2076
- "Read(./**/*.key)",
2077
- "Bash(rm -rf *)",
2078
- "Bash(curl *)",
2079
- "Bash(wget *)"
2080
- ]
2081
- }
2082
- }`
2083
- },
2084
- 'mcp': {
2085
- filename: '.mcp.json',
2086
- content: `{
2087
- "mcpServers": {}
2088
- }`
2089
- }
2090
- };
2091
-
2092
- const modal = document.getElementById('fileModal');
2093
- const modalTitle = document.getElementById('modalTitle');
2094
- const modalCode = document.getElementById('modalCode');
2095
- const modalClose = document.getElementById('modalClose');
2096
-
2097
- function openModal(key) {
2098
- const file = fileContents[key];
2099
- if (!file) return;
2100
-
2101
- modalTitle.textContent = file.filename;
2102
-
2103
- if (file.empty) {
2104
- modalCode.innerHTML = `<span class="modal-empty">${file.emptyMessage}</span>`;
2105
- } else {
2106
- modalCode.textContent = file.content;
2107
- }
2108
-
2109
- modal.classList.add('visible');
2110
- }
2111
-
2112
- function closeModal() {
2113
- modal.classList.remove('visible');
2114
- }
2115
-
2116
- modalClose.addEventListener('click', closeModal);
2117
- modal.addEventListener('click', (e) => {
2118
- if (e.target === modal) closeModal();
2119
- });
2120
- document.addEventListener('keydown', (e) => {
2121
- if (e.key === 'Escape' && modal.classList.contains('visible')) {
2122
- closeModal();
2123
- }
2124
- // Enter key opens preview for selected item
2125
- if (e.key === 'Enter' && !modal.classList.contains('visible')) {
2126
- const selected = document.querySelector('.tree-item.active');
2127
- if (selected) {
2128
- const key = selected.dataset.info;
2129
- if (fileContents[key]) {
2130
- openModal(key);
2131
- }
2132
- }
2133
- }
2134
- });
2135
-
2136
- // Double-click to open file preview
2137
- treeItems.forEach(item => {
2138
- item.addEventListener('dblclick', (e) => {
2139
- const key = item.dataset.info;
2140
- // Don't open modal for folders (except rules which is empty) or root
2141
- if (key === 'root' || key === 'claude-dir' || key === 'commands') return;
2142
- if (fileContents[key]) {
2143
- openModal(key);
2144
- }
2145
- });
2146
- });
2147
- </script>
2148
- </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: 1100px;
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: 480px;
382
+ position: relative;
383
+ }
384
+
385
+ .tree-side {
386
+ display: flex;
387
+ flex-direction: column;
388
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Roboto', 'Noto Sans', sans-serif;
389
+ font-size: 13px;
390
+ line-height: 1.4;
391
+ border-right: 1px solid var(--bg-elevated);
392
+ flex-shrink: 0;
393
+ height: 100%;
394
+ }
395
+
396
+ .tree-content {
397
+ padding: 16px 16px 20px 16px;
398
+ overflow: auto;
399
+ flex: 1;
400
+ min-height: 0;
401
+ }
402
+
403
+ .tree-footer-hint {
404
+ padding: 6px 16px;
405
+ font-size: 12px;
406
+ color: var(--text-secondary);
407
+ opacity: 0.5;
408
+ border-top: 1px solid var(--bg-elevated);
409
+ flex-shrink: 0;
410
+ }
411
+
412
+ .tree-item {
413
+ padding: 4px 8px;
414
+ margin: 1px 0;
415
+ border-radius: 4px;
416
+ cursor: pointer;
417
+ transition: background 0.15s ease;
418
+ white-space: nowrap;
419
+ display: flex;
420
+ align-items: center;
421
+ gap: 4px;
422
+ }
423
+
424
+ .tree-item.hidden {
425
+ display: none;
426
+ }
427
+
428
+ .tree-item:hover {
429
+ background: rgba(255, 255, 255, 0.1);
430
+ }
431
+
432
+ .tree-item.active {
433
+ background: rgba(45, 105, 175, 0.5);
434
+ }
435
+
436
+ .tree-item.active:hover {
437
+ background: rgba(45, 105, 175, 0.5);
438
+ }
439
+
440
+ .tree-chevron {
441
+ width: 18px;
442
+ font-size: 18px;
443
+ color: var(--text-primary);
444
+ text-align: center;
445
+ flex-shrink: 0;
446
+ transition: transform 0.15s ease;
447
+ user-select: none;
448
+ transform: rotate(90deg);
449
+ }
450
+
451
+ .tree-item.collapsed .tree-chevron {
452
+ transform: rotate(0deg);
453
+ }
454
+
455
+ .tree-spacer {
456
+ width: 18px;
457
+ flex-shrink: 0;
458
+ }
459
+
460
+ .tree-folder-icon,
461
+ .tree-file-icon {
462
+ font-size: 14px;
463
+ flex-shrink: 0;
464
+ }
465
+
466
+ .tree-item .folder {
467
+ color: var(--text-primary);
468
+ }
469
+
470
+ .tree-item .file {
471
+ color: var(--text-secondary);
472
+ }
473
+
474
+ .tree-item.indent-1 { padding-left: 24px; }
475
+ .tree-item.indent-2 { padding-left: 44px; }
476
+ .tree-item.indent-3 { padding-left: 64px; }
477
+ .tree-item.indent-4 { padding-left: 84px; }
478
+
479
+ .tree-indent {
480
+ color: var(--text-dim);
481
+ }
482
+
483
+ .info-side {
484
+ flex: 1;
485
+ min-width: 0;
486
+ height: 100%;
487
+ overflow-y: auto;
488
+ overflow-x: hidden;
489
+ word-wrap: break-word;
490
+ }
491
+
492
+ .info-panel {
493
+ padding: 20px 20px 20px 0;
494
+ width: 100%;
495
+ box-sizing: border-box;
496
+ }
497
+
498
+ .info-panel-title {
499
+ font-size: 16px;
500
+ font-weight: 600;
501
+ color: var(--accent-orange);
502
+ margin-bottom: 12px;
503
+ }
504
+
505
+ .info-panel-desc {
506
+ font-size: 14px;
507
+ color: var(--text-secondary);
508
+ line-height: 1.6;
509
+ letter-spacing: 0.02em;
510
+ }
511
+
512
+ .info-panel-trigger {
513
+ margin-top: 16px;
514
+ padding: 8px 12px;
515
+ background: var(--bg-elevated);
516
+ border-radius: 4px;
517
+ font-family: 'SF Mono', 'Fira Code', monospace;
518
+ font-size: 13px;
519
+ color: var(--accent-cyan);
520
+ }
521
+
522
+ .info-panel-hint {
523
+ margin-top: 20px;
524
+ font-size: 12px;
525
+ color: var(--text-secondary);
526
+ opacity: 0.5;
527
+ }
528
+
529
+ /* Navigation */
530
+ .nav-container {
531
+ display: flex;
532
+ justify-content: space-between;
533
+ align-items: center;
534
+ margin-top: 40px;
535
+ padding-top: 20px;
536
+ }
537
+
538
+ .nav-btn {
539
+ display: flex;
540
+ align-items: center;
541
+ gap: 8px;
542
+ padding: 14px 28px;
543
+ border: none;
544
+ border-radius: 8px;
545
+ font-size: 16px;
546
+ font-weight: 500;
547
+ cursor: pointer;
548
+ transition: all 0.3s ease;
549
+ }
550
+
551
+ .nav-btn.prev {
552
+ background: var(--bg-elevated);
553
+ color: var(--text-secondary);
554
+ }
555
+
556
+ .nav-btn.prev:hover:not(:disabled) {
557
+ background: var(--bg-secondary);
558
+ color: var(--text-primary);
559
+ }
560
+
561
+ .nav-btn.next {
562
+ background: var(--accent-orange);
563
+ color: var(--bg-primary);
564
+ }
565
+
566
+ .nav-btn.next:hover:not(:disabled) {
567
+ transform: translateY(-2px);
568
+ box-shadow: 0 10px 30px rgba(212, 165, 116, 0.3);
569
+ }
570
+
571
+ .nav-btn:disabled {
572
+ opacity: 0.3;
573
+ cursor: not-allowed;
574
+ transform: none !important;
575
+ }
576
+
577
+ .nav-hint {
578
+ color: var(--text-dim);
579
+ font-size: 14px;
580
+ }
581
+
582
+ .nav-hint kbd {
583
+ background: var(--bg-elevated);
584
+ padding: 4px 8px;
585
+ border-radius: 4px;
586
+ font-family: inherit;
587
+ margin: 0 2px;
588
+ }
589
+
590
+ /* Table */
591
+ .table-container {
592
+ overflow-x: auto;
593
+ margin: 20px 0;
594
+ }
595
+
596
+ table {
597
+ width: 100%;
598
+ border-collapse: collapse;
599
+ }
600
+
601
+ th, td {
602
+ padding: 12px 16px 12px 0;
603
+ text-align: left;
604
+ vertical-align: top;
605
+ border-bottom: 1px solid var(--bg-elevated);
606
+ }
607
+
608
+ th {
609
+ color: var(--accent-blue);
610
+ font-size: 12px;
611
+ text-transform: uppercase;
612
+ letter-spacing: 1px;
613
+ }
614
+
615
+ td {
616
+ font-size: 14px;
617
+ }
618
+
619
+ td code {
620
+ background: var(--bg-secondary);
621
+ color: var(--accent-orange);
622
+ padding: 2px 4px;
623
+ border-radius: 4px;
624
+ font-family: 'SF Mono', 'Fira Code', monospace;
625
+ font-size: 13px;
626
+ }
627
+
628
+ /* Animations */
629
+ @keyframes fadeInUp {
630
+ from {
631
+ opacity: 0;
632
+ transform: translateY(20px);
633
+ }
634
+ to {
635
+ opacity: 1;
636
+ transform: translateY(0);
637
+ }
638
+ }
639
+
640
+ .slide.active .slide-number { animation: fadeIn 0.4s ease both; }
641
+ .slide.active h1 { animation: fadeIn 0.4s ease 0.1s both; }
642
+ .slide.active h2 { animation: none; }
643
+ .slide.active .slide-content > ul,
644
+ .slide.active .slide-content > div { animation: fadeIn 0.5s ease 0.3s both; }
645
+
646
+ @keyframes fadeIn {
647
+ from { opacity: 0; }
648
+ to { opacity: 1; }
649
+ }
650
+
651
+ /* Typewriter effect */
652
+ .typewriter {
653
+ border-right: 2px solid var(--bg-primary);
654
+ animation: none !important;
655
+ }
656
+
657
+ .typewriter.typing {
658
+ animation: blink-caret 0.75s step-end infinite !important;
659
+ }
660
+
661
+ .typewriter.done {
662
+ border-right: none !important;
663
+ animation: none !important;
664
+ }
665
+
666
+ @keyframes blink-caret {
667
+ from, to { border-color: var(--bg-primary); }
668
+ 50% { border-color: transparent; }
669
+ }
670
+
671
+ /* Scrollbar */
672
+ ::-webkit-scrollbar {
673
+ width: 8px;
674
+ }
675
+
676
+ ::-webkit-scrollbar-track {
677
+ background: var(--bg-secondary);
678
+ border-radius: 4px;
679
+ }
680
+
681
+ ::-webkit-scrollbar-thumb {
682
+ background: var(--bg-elevated);
683
+ border-radius: 4px;
684
+ }
685
+
686
+ ::-webkit-scrollbar-thumb:hover {
687
+ background: var(--text-dim);
688
+ }
689
+
690
+ /* Logo */
691
+ .logo {
692
+ font-size: 24px;
693
+ margin-bottom: 8px;
694
+ }
695
+
696
+ /* Final slide special */
697
+ .final-links {
698
+ display: flex;
699
+ gap: 16px;
700
+ margin-top: 30px;
701
+ flex-wrap: wrap;
702
+ }
703
+
704
+ .final-link {
705
+ display: inline-flex;
706
+ align-items: center;
707
+ gap: 8px;
708
+ padding: 12px 24px;
709
+ background: var(--bg-elevated);
710
+ border-radius: 8px;
711
+ color: var(--text-secondary);
712
+ text-decoration: none;
713
+ transition: all 0.3s ease;
714
+ }
715
+
716
+ .final-link:hover {
717
+ background: var(--bg-secondary);
718
+ color: var(--accent-orange);
719
+ transform: translateY(-2px);
720
+ }
721
+
722
+ /* File Preview Modal */
723
+ .modal-overlay {
724
+ position: fixed;
725
+ top: 0;
726
+ left: 0;
727
+ right: 0;
728
+ bottom: 0;
729
+ background: rgba(0, 0, 0, 0.85);
730
+ display: none;
731
+ justify-content: center;
732
+ align-items: center;
733
+ z-index: 1000;
734
+ padding: 40px;
735
+ opacity: 0;
736
+ transition: opacity 0.2s ease;
737
+ }
738
+
739
+ .modal-overlay.visible {
740
+ display: flex;
741
+ opacity: 1;
742
+ }
743
+
744
+ .modal-content {
745
+ background: var(--bg-secondary);
746
+ border: 1px solid var(--bg-elevated);
747
+ border-radius: 12px;
748
+ max-width: 1000px;
749
+ width: 100%;
750
+ max-height: 80vh;
751
+ display: flex;
752
+ flex-direction: column;
753
+ transform: scale(0.95);
754
+ transition: transform 0.2s ease;
755
+ }
756
+
757
+ .modal-overlay.visible .modal-content {
758
+ transform: scale(1);
759
+ }
760
+
761
+ .modal-header {
762
+ display: flex;
763
+ justify-content: space-between;
764
+ align-items: center;
765
+ padding: 16px 20px;
766
+ border-bottom: 1px solid var(--bg-elevated);
767
+ }
768
+
769
+ .modal-title {
770
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Roboto', 'Noto Sans', sans-serif;
771
+ font-size: 14px;
772
+ color: var(--accent-orange);
773
+ }
774
+
775
+ .modal-close {
776
+ background: none;
777
+ border: none;
778
+ color: var(--text-dim);
779
+ font-size: 24px;
780
+ cursor: pointer;
781
+ padding: 0;
782
+ line-height: 1;
783
+ transition: color 0.2s ease;
784
+ }
785
+
786
+ .modal-close:hover {
787
+ color: var(--text-primary);
788
+ }
789
+
790
+ .modal-body {
791
+ padding: 20px;
792
+ overflow-y: auto;
793
+ flex: 1;
794
+ }
795
+
796
+ .modal-body pre {
797
+ margin: 0;
798
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Roboto', 'Noto Sans', sans-serif;
799
+ font-size: 13px;
800
+ line-height: 1.6;
801
+ color: var(--text-secondary);
802
+ white-space: pre-wrap;
803
+ word-wrap: break-word;
804
+ }
805
+
806
+ .modal-body .comment { color: var(--text-dim); }
807
+ .modal-body .keyword { color: var(--accent-orange); }
808
+ .modal-body .string { color: var(--accent-green); }
809
+ .modal-body .property { color: var(--accent-blue); }
810
+
811
+ .modal-empty {
812
+ color: var(--text-dim);
813
+ font-style: italic;
814
+ text-align: center;
815
+ padding: 40px;
816
+ }
817
+ </style>
818
+ </head>
819
+ <body>
820
+ <!-- File Preview Modal -->
821
+ <div class="modal-overlay" id="fileModal">
822
+ <div class="modal-content">
823
+ <div class="modal-header">
824
+ <span class="modal-title" id="modalTitle">filename.md</span>
825
+ <button class="modal-close" id="modalClose">&times;</button>
826
+ </div>
827
+ <div class="modal-body">
828
+ <pre id="modalCode"></pre>
829
+ </div>
830
+ </div>
831
+ </div>
832
+
833
+ <div class="container">
834
+ <div class="progress-container" id="progress"></div>
835
+
836
+ <div class="slides-container">
837
+ <!-- Slide 0: What Got Installed -->
838
+ <div class="slide active" data-slide="0">
839
+ <div class="slide-number">01 / Overview</div>
840
+ <h1>✨ Autoconfig Complete</h1>
841
+ <h2 class="typewriter" data-text="Here's what got installed. Hover over any file or folder to learn what it does."></h2>
842
+ <div class="slide-content">
843
+ <div class="tree-panel">
844
+ <div class="tree-side">
845
+ <div class="tree-content">
846
+ <div class="tree-item" data-info="memory-md">
847
+ <span class="tree-spacer"></span>
848
+ <span class="tree-file-icon">📄</span>
849
+ <span class="file">MEMORY.md</span>
850
+ </div>
851
+ <div class="tree-item folder-row" data-info="root" data-folder="root">
852
+ <span class="tree-chevron">›</span>
853
+ <span class="tree-folder-icon">📁</span>
854
+ <span class="folder">your-project</span>
855
+ </div>
856
+ <div class="tree-item indent-1 folder-row collapsed" data-info="claude-dir" data-folder="claude-dir" data-parent="root">
857
+ <span class="tree-chevron">›</span>
858
+ <span class="tree-folder-icon">📁</span>
859
+ <span class="folder">.claude</span>
860
+ </div>
861
+ <div class="tree-item indent-2 folder-row hidden collapsed" data-info="commands" data-folder="commands" data-parent="claude-dir">
862
+ <span class="tree-chevron">›</span>
863
+ <span class="tree-folder-icon">📁</span>
864
+ <span class="folder">commands</span>
865
+ </div>
866
+ <div class="tree-item indent-3 hidden" data-info="autoconfig-update" data-parent="commands">
867
+ <span class="tree-spacer"></span>
868
+ <span class="tree-file-icon">📄</span>
869
+ <span class="file">autoconfig-update.md</span>
870
+ </div>
871
+ <div class="tree-item indent-3 hidden" data-info="autoconfig" data-parent="commands">
872
+ <span class="tree-spacer"></span>
873
+ <span class="tree-file-icon">📄</span>
874
+ <span class="file">autoconfig.md</span>
875
+ </div>
876
+ <div class="tree-item indent-3 hidden" data-info="commit-and-push" data-parent="commands">
877
+ <span class="tree-spacer"></span>
878
+ <span class="tree-file-icon">📄</span>
879
+ <span class="file">commit-and-push.md</span>
880
+ </div>
881
+ <div class="tree-item indent-3 hidden" data-info="extract-rules" data-parent="commands">
882
+ <span class="tree-spacer"></span>
883
+ <span class="tree-file-icon">📄</span>
884
+ <span class="file">extract-rules.md</span>
885
+ </div>
886
+ <div class="tree-item indent-3 hidden" data-info="gls" data-parent="commands">
887
+ <span class="tree-spacer"></span>
888
+ <span class="tree-file-icon">📄</span>
889
+ <span class="file">gls.md</span>
890
+ </div>
891
+ <div class="tree-item indent-3 hidden" data-info="publish" data-parent="commands">
892
+ <span class="tree-spacer"></span>
893
+ <span class="tree-file-icon">📄</span>
894
+ <span class="file">publish.md</span>
895
+ </div>
896
+ <div class="tree-item indent-3 hidden" data-info="recover-context" data-parent="commands">
897
+ <span class="tree-spacer"></span>
898
+ <span class="tree-file-icon">📄</span>
899
+ <span class="file">recover-context.md</span>
900
+ </div>
901
+ <div class="tree-item indent-3 hidden" data-info="show-docs" data-parent="commands">
902
+ <span class="tree-spacer"></span>
903
+ <span class="tree-file-icon">📄</span>
904
+ <span class="file">show-docs.md</span>
905
+ </div>
906
+ <div class="tree-item indent-3 hidden" data-info="test" data-parent="commands">
907
+ <span class="tree-spacer"></span>
908
+ <span class="tree-file-icon">📄</span>
909
+ <span class="file">test.md</span>
910
+ </div>
911
+ <div class="tree-item indent-3 hidden" data-info="validate-cca-install" data-parent="commands">
912
+ <span class="tree-spacer"></span>
913
+ <span class="tree-file-icon">📄</span>
914
+ <span class="file">validate-cca-install.md</span>
915
+ </div>
916
+ <div class="tree-item indent-2 folder-row hidden collapsed" data-info="agents" data-folder="agents" data-parent="claude-dir">
917
+ <span class="tree-chevron">›</span>
918
+ <span class="tree-folder-icon">📁</span>
919
+ <span class="folder">agents</span>
920
+ </div>
921
+ <div class="tree-item indent-3 hidden" data-info="README-agent" data-parent="agents">
922
+ <span class="tree-spacer"></span>
923
+ <span class="tree-file-icon">📄</span>
924
+ <span class="file">README.md</span>
925
+ </div>
926
+ <div class="tree-item indent-2 folder-row hidden collapsed" data-info="feedback" data-folder="feedback" data-parent="claude-dir">
927
+ <span class="tree-chevron">›</span>
928
+ <span class="tree-folder-icon">📁</span>
929
+ <span class="folder">feedback</span>
930
+ </div>
931
+ <div class="tree-item indent-3 hidden" data-info="feedback-feedback" data-parent="feedback">
932
+ <span class="tree-spacer"></span>
933
+ <span class="tree-file-icon">📄</span>
934
+ <span class="file">FEEDBACK.md</span>
935
+ </div>
936
+ <div class="tree-item indent-2 folder-row hidden collapsed" data-info="hooks" data-folder="hooks" data-parent="claude-dir">
937
+ <span class="tree-chevron">›</span>
938
+ <span class="tree-folder-icon">📁</span>
939
+ <span class="folder">hooks</span>
940
+ </div>
941
+ <div class="tree-item indent-3 hidden" data-info="feedback-rule-check-hook" data-parent="hooks">
942
+ <span class="tree-spacer"></span>
943
+ <span class="tree-file-icon">📄</span>
944
+ <span class="file">feedback-rule-check.js</span>
945
+ </div>
946
+ <div class="tree-item indent-3 hidden" data-info="format-hook" data-parent="hooks">
947
+ <span class="tree-spacer"></span>
948
+ <span class="tree-file-icon">📄</span>
949
+ <span class="file">format.js</span>
950
+ </div>
951
+ <div class="tree-item indent-3 hidden" data-info="migrate-feedback-hook" data-parent="hooks">
952
+ <span class="tree-spacer"></span>
953
+ <span class="tree-file-icon">📄</span>
954
+ <span class="file">migrate-feedback.js</span>
955
+ </div>
956
+ <div class="tree-item indent-2 folder-row hidden collapsed" data-info="docs" data-folder="docs-folder" data-parent="claude-dir">
957
+ <span class="tree-chevron">›</span>
958
+ <span class="tree-folder-icon">📁</span>
959
+ <span class="folder">docs</span>
960
+ </div>
961
+ <div class="tree-item indent-3 hidden" data-info="docs" data-parent="docs-folder">
962
+ <span class="tree-spacer"></span>
963
+ <span class="tree-file-icon">🌐</span>
964
+ <span class="file">autoconfig.docs.html</span>
965
+ </div>
966
+ <div class="tree-item indent-2 hidden" data-info="rules" data-parent="claude-dir">
967
+ <span class="tree-spacer"></span>
968
+ <span class="tree-folder-icon">📁</span>
969
+ <span class="folder">rules</span>
970
+ </div>
971
+ <div class="tree-item indent-2 hidden" data-info="mcp" data-parent="claude-dir">
972
+ <span class="tree-spacer"></span>
973
+ <span class="tree-file-icon">🔌</span>
974
+ <span class="file">.mcp.json</span>
975
+ </div>
976
+ <div class="tree-item indent-2 hidden" data-info="settings" data-parent="claude-dir">
977
+ <span class="tree-spacer"></span>
978
+ <span class="tree-file-icon">⚙️</span>
979
+ <span class="file">settings.json</span>
980
+ </div>
981
+ </div>
982
+ </div>
983
+ <div class="info-side">
984
+ <div class="info-panel" id="infoPanel">
985
+ <div class="info-panel-title">Select a file</div>
986
+ <div class="info-panel-desc">Hover over any item in the tree to see what it does.</div>
987
+ </div>
988
+ </div>
989
+ </div>
990
+ </div>
991
+ </div>
992
+
993
+ <!-- Slide 1: Finale -->
994
+ <div class="slide" data-slide="1">
995
+ <div class="slide-number">02 / You're Ready</div>
996
+ <h1>That's It</h1>
997
+ <h2 class="typewriter" data-text="You've got the autoconfig. Now go build something."></h2>
998
+ <div class="slide-content">
999
+ <div class="final-links">
1000
+ <a href="https://github.com/design-and-deliver/claude-code-autoconfig" class="final-link" target="_blank">
1001
+ ⭐ Star on GitHub
1002
+ </a>
1003
+ <a href="https://docs.anthropic.com/en/docs/claude-code/overview" class="final-link" target="_blank">
1004
+ 📚 Claude Code Docs
1005
+ </a>
1006
+ </div>
1007
+ </div>
1008
+ </div>
1009
+ </div>
1010
+
1011
+ <div class="nav-container">
1012
+ <button class="nav-btn prev" id="prevBtn">
1013
+ Back
1014
+ </button>
1015
+ <button class="nav-btn next" id="nextBtn">
1016
+ Next
1017
+ </button>
1018
+ </div>
1019
+ </div>
1020
+
1021
+ <script>
1022
+ const slides = document.querySelectorAll('.slide');
1023
+ const progressContainer = document.getElementById('progress');
1024
+ const prevBtn = document.getElementById('prevBtn');
1025
+ const nextBtn = document.getElementById('nextBtn');
1026
+ let currentSlide = 0;
1027
+
1028
+ // Create progress dots
1029
+ slides.forEach((_, i) => {
1030
+ const dot = document.createElement('div');
1031
+ dot.className = 'progress-dot' + (i === 0 ? ' active' : '');
1032
+ dot.addEventListener('click', () => goToSlide(i));
1033
+ progressContainer.appendChild(dot);
1034
+ });
1035
+
1036
+ function updateProgress() {
1037
+ document.querySelectorAll('.progress-dot').forEach((dot, i) => {
1038
+ dot.classList.remove('active');
1039
+ if (i === currentSlide) dot.classList.add('active');
1040
+ });
1041
+ }
1042
+
1043
+ function goToSlide(index) {
1044
+ if (index < 0 || index >= slides.length) return;
1045
+
1046
+ const direction = index > currentSlide ? 1 : -1;
1047
+
1048
+ slides[currentSlide].classList.remove('active');
1049
+ if (direction > 0) {
1050
+ slides[currentSlide].classList.add('exit');
1051
+ }
1052
+
1053
+ currentSlide = index;
1054
+
1055
+ slides.forEach(s => s.classList.remove('exit'));
1056
+ slides[currentSlide].classList.add('active');
1057
+
1058
+ updateProgress();
1059
+ updateButtons();
1060
+ checkTypewriter();
1061
+
1062
+ // Select CLAUDE.md by default when entering slide 0 (tree view)
1063
+ if (currentSlide === 0) {
1064
+ setTimeout(() => selectTreeItemByKey('memory-md'), 100);
1065
+ }
1066
+ }
1067
+
1068
+ function updateButtons() {
1069
+ // Hide back button on first slide, show on others
1070
+ prevBtn.style.visibility = currentSlide === 0 ? 'hidden' : 'visible';
1071
+
1072
+ if (currentSlide === slides.length - 1) {
1073
+ nextBtn.textContent = 'Done';
1074
+ } else {
1075
+ nextBtn.textContent = 'Next';
1076
+ }
1077
+ }
1078
+
1079
+ prevBtn.addEventListener('click', () => {
1080
+ if (currentSlide > 0) {
1081
+ goToSlide(currentSlide - 1);
1082
+ }
1083
+ });
1084
+
1085
+ nextBtn.addEventListener('click', () => {
1086
+ if (currentSlide < slides.length - 1) {
1087
+ goToSlide(currentSlide + 1);
1088
+ } else {
1089
+ window.close();
1090
+ }
1091
+ });
1092
+
1093
+ // Select CLAUDE.md on initial page load
1094
+ setTimeout(() => selectTreeItemByKey('memory-md'), 300);
1095
+
1096
+ // Keyboard navigation for slides
1097
+ document.addEventListener('keydown', (e) => {
1098
+ // On slide 0, arrow keys control tree - use spacebar for next slide
1099
+ if (currentSlide === 0) {
1100
+ if (e.key === ' ') {
1101
+ e.preventDefault();
1102
+ if (currentSlide < slides.length - 1) {
1103
+ goToSlide(currentSlide + 1);
1104
+ }
1105
+ }
1106
+ return; // Let tree keyboard handler deal with arrows
1107
+ }
1108
+
1109
+ // Space bar for next slide (but not on slide 0 with tree)
1110
+ if (e.key === ' ' && currentSlide !== 0) {
1111
+ e.preventDefault();
1112
+ if (currentSlide < slides.length - 1) {
1113
+ goToSlide(currentSlide + 1);
1114
+ }
1115
+ }
1116
+ });
1117
+
1118
+ updateButtons();
1119
+
1120
+ // Auto-focus for keyboard navigation
1121
+ document.body.setAttribute('tabindex', '0');
1122
+ document.body.focus();
1123
+
1124
+ // Detect project name from file path
1125
+ function getProjectName() {
1126
+ try {
1127
+ const path = window.location.pathname;
1128
+ const parts = path.split('/').filter(p => p && !p.includes(':'));
1129
+ const claudeIndex = parts.indexOf('.claude');
1130
+ if (claudeIndex > 0) {
1131
+ return parts[claudeIndex - 1];
1132
+ }
1133
+ if (parts.length >= 3) {
1134
+ return parts[parts.length - 3];
1135
+ }
1136
+ } catch (e) {}
1137
+ return 'your-project';
1138
+ }
1139
+
1140
+ const projectName = getProjectName();
1141
+
1142
+ // Update tree root with actual project name
1143
+ const rootItem = document.querySelector('[data-info="root"]');
1144
+ if (rootItem) {
1145
+ rootItem.querySelector('.folder').textContent = projectName + '/';
1146
+ }
1147
+
1148
+ // Build full MEMORY.md path from project location
1149
+ function getMemoryPath() {
1150
+ try {
1151
+ const path = window.location.pathname;
1152
+ // Extract drive + full path up to .claude, then convert to Claude's encoding
1153
+ const claudeIdx = path.indexOf('.claude');
1154
+ if (claudeIdx > 0) {
1155
+ const projectPath = path.substring(0, claudeIdx - 1);
1156
+ // Claude encodes the path: C:\CODE\proj → C--CODE-proj
1157
+ const parts = projectPath.split('/').filter(p => p);
1158
+ const encoded = parts.join('-').replace(/:/g, '');
1159
+ return '~/.claude/projects/' + encoded + '/memory/MEMORY.md';
1160
+ }
1161
+ } catch (e) {}
1162
+ return '~/.claude/projects/' + projectName + '/memory/MEMORY.md';
1163
+ }
1164
+ const memoryPath = getMemoryPath();
1165
+
1166
+ // Calculate tree side width dynamically
1167
+ function setTreeWidth() {
1168
+ const treeSide = document.querySelector('.tree-side');
1169
+ const treeItems = document.querySelectorAll('.tree-item');
1170
+ if (!treeSide || !treeItems.length) return;
1171
+
1172
+ const hiddenItems = [];
1173
+ treeItems.forEach(item => {
1174
+ if (item.classList.contains('hidden')) {
1175
+ hiddenItems.push(item);
1176
+ item.style.visibility = 'hidden';
1177
+ item.style.position = 'absolute';
1178
+ item.classList.remove('hidden');
1179
+ }
1180
+ });
1181
+
1182
+ let maxWidth = 0;
1183
+ treeItems.forEach(item => {
1184
+ const width = item.scrollWidth;
1185
+ if (width > maxWidth) maxWidth = width;
1186
+ });
1187
+
1188
+ hiddenItems.forEach(item => {
1189
+ item.classList.add('hidden');
1190
+ item.style.visibility = '';
1191
+ item.style.position = '';
1192
+ });
1193
+
1194
+ treeSide.style.width = Math.round((maxWidth + 32) * 1.25) + 'px';
1195
+ treeSide.style.paddingLeft = '8px';
1196
+ treeSide.style.paddingRight = '8px';
1197
+ }
1198
+
1199
+ if (document.fonts && document.fonts.ready) {
1200
+ document.fonts.ready.then(setTreeWidth);
1201
+ } else {
1202
+ setTimeout(setTreeWidth, 100);
1203
+ }
1204
+
1205
+ // Typewriter effect
1206
+ function typeWriter(element) {
1207
+ const text = element.dataset.text;
1208
+ if (!text) return;
1209
+
1210
+ element.textContent = '';
1211
+ element.classList.add('typing');
1212
+ element.classList.remove('done');
1213
+
1214
+ let i = 0;
1215
+ const speed = 30;
1216
+
1217
+ function type() {
1218
+ if (i < text.length) {
1219
+ element.textContent += text.charAt(i);
1220
+ i++;
1221
+ setTimeout(type, speed);
1222
+ } else {
1223
+ element.classList.remove('typing');
1224
+ element.classList.add('done');
1225
+ }
1226
+ }
1227
+
1228
+ setTimeout(type, 300);
1229
+ }
1230
+
1231
+ function checkTypewriter() {
1232
+ const activeSlide = slides[currentSlide];
1233
+ const typewriterEl = activeSlide.querySelector('.typewriter');
1234
+ if (typewriterEl) {
1235
+ typeWriter(typewriterEl);
1236
+ }
1237
+ }
1238
+
1239
+ setTimeout(checkTypewriter, 100);
1240
+
1241
+ // Tree panel info data - UPDATED
1242
+ const treeInfo = {
1243
+ 'memory-md': {
1244
+ title: 'MEMORY.md',
1245
+ desc: 'Native Claude Code file — loaded into the system prompt at the start of every session. Autoconfig appends debugging methodology instructions here so Claude always follows evidence-based troubleshooting.<br><br><span style="color: var(--accent-orange);">Location: ' + memoryPath + '</span>',
1246
+ trigger: 'Loaded into system prompt automatically'
1247
+ },
1248
+ 'root': {
1249
+ title: projectName,
1250
+ desc: 'The autoconfig adds CLAUDE.md at your project root and configuration files inside a .claude/ directory. Nothing else is touched.'
1251
+ },
1252
+ 'claude-md': {
1253
+ title: 'CLAUDE.md',
1254
+ 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>',
1255
+ trigger: 'Loaded automatically at session start'
1256
+ },
1257
+ 'claude-dir': {
1258
+ title: '.claude/ Directory',
1259
+ desc: 'Commands, rules, settings, and these docs. Keeps configuration organized as your project grows.'
1260
+ },
1261
+ 'rules': {
1262
+ title: 'rules/',
1263
+ desc: 'Path-scoped context that loads when Claude works on matching files.'
1264
+ },
1265
+ 'commands': {
1266
+ title: 'commands/',
1267
+ 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>.'
1268
+ },
1269
+ 'agents': {
1270
+ title: 'agents/',
1271
+ desc: 'Reusable agent definitions that Claude can invoke for specialized tasks.'
1272
+ },
1273
+ 'hooks': {
1274
+ title: 'hooks/',
1275
+ desc: 'Executable hook scripts that trigger on Claude Code events like PostToolUse.'
1276
+ },
1277
+ 'feedback': {
1278
+ title: 'feedback/',
1279
+ 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.'
1280
+ },
1281
+ 'autoconfig-update': {
1282
+ title: 'autoconfig-update.md',
1283
+ desc: 'Manages and installs updates to Claude Code configuration.<div style="margin-top: 12px;"><strong>Parameters</strong><div style="margin-top: 4px; opacity: 0.6;">None</div></div><div style="margin-top: 12px;"><strong>Responses</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Status</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>updates-available</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Displays list of pending updates with install/review options.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>up-to-date</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">All updates are already installed.</td></tr></table></div><div style="margin-top: 12px;"><strong>Side Effects</strong><div style="margin-top: 4px; font-size: 0.9em;">Pulls latest update files from npm, executes update instructions, tracks applied updates</div></div><div style="margin-top: 12px;"><strong>Examples</strong><div style="margin-top: 6px; background: var(--bg-elevated); border-radius: 6px; padding: 8px 12px; font-family: monospace; font-size: 0.85em;"><div><code>/autoconfig-update</code> <span style="opacity: 0.6;">— Check for and install configuration updates</span></div></div></div>',
1284
+ trigger: '/autoconfig-update'
1285
+ },
1286
+ 'autoconfig': {
1287
+ title: 'autoconfig.md',
1288
+ desc: 'Configures Claude Code scaffolding for your project. Sets up settings, permissions, hooks, commands, and docs.<div style="margin-top: 12px;"><strong>Parameters</strong><div style="margin-top: 4px; opacity: 0.6;">None</div></div><div style="margin-top: 12px;"><strong>Responses</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Status</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>success</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Scaffolding configured, CLAUDE.md initialized, docs opened in browser.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>no-project</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">No project detected — asks user to confirm directory.</td></tr></table></div><div style="margin-top: 12px;"><strong>Side Effects</strong><div style="margin-top: 4px; font-size: 0.9em;">Initializes CLAUDE.md, settings.json, hooks, commands, and MEMORY.md</div></div><div style="margin-top: 12px;"><strong>Examples</strong><div style="margin-top: 6px; background: var(--bg-elevated); border-radius: 6px; padding: 8px 12px; font-family: monospace; font-size: 0.85em;"><div><code>/autoconfig</code> <span style="opacity: 0.6;">— Analyze project and configure Claude</span></div></div></div>',
1289
+ trigger: '/autoconfig'
1290
+ },
1291
+ 'commit-and-push': {
1292
+ title: 'commit-and-push.md',
1293
+ desc: 'Runs tests, then stages all changes, generates a conventional commit message, commits, and pushes.<div style="margin-top: 12px;"><strong>Parameters</strong><div style="margin-top: 4px; opacity: 0.6;">None</div></div><div style="margin-top: 12px;"><strong>Responses</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Status</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>success</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Changes committed and pushed to current branch.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>test-failure</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Tests failed — no commit made.</td></tr></table></div><div style="margin-top: 12px;"><strong>Side Effects</strong><div style="margin-top: 4px; font-size: 0.9em;">Runs test suite, stages all changes, creates git commit, pushes to remote</div></div><div style="margin-top: 12px;"><strong>Examples</strong><div style="margin-top: 6px; background: var(--bg-elevated); border-radius: 6px; padding: 8px 12px; font-family: monospace; font-size: 0.85em;"><div><code>/commit-and-push</code> <span style="opacity: 0.6;">— Run tests, commit, and push</span></div></div></div>',
1294
+ trigger: '/commit-and-push'
1295
+ },
1296
+ 'extract-rules': {
1297
+ title: 'extract-rules.md',
1298
+ desc: 'Scan Claude artifacts and extract structured rules into .claude/rules/<div style="margin-top: 12px;"><strong>Parameters</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Name</th><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Type</th><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Required</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>select</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>string</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">optional</td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Write only specific rules by number: "1,3,5". Default: all.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>keep-sources</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>boolean</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">optional</td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Write rules but skip source cleanup (Step 8)</td></tr></table></div><div style="margin-top: 12px;"><strong>Responses</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Status</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>success</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Rules extracted, written, and sources cleaned up.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>no-rules</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">No extractable rules found in scanned sources.</td></tr></table></div><div style="margin-top: 12px;"><strong>Side Effects</strong><div style="margin-top: 4px; font-size: 0.9em;">Creates .claude/rules/ files and removes extracted content from source files</div></div><div style="margin-top: 12px;"><strong>Examples</strong><div style="margin-top: 6px; background: var(--bg-elevated); border-radius: 6px; padding: 8px 12px; font-family: monospace; font-size: 0.85em;"><div><code>/extract-rules</code> <span style="opacity: 0.6;">— Scan, propose, prompt for approval, write, and clean up</span></div><div><code>/extract-rules --keep-sources</code> <span style="opacity: 0.6;">— Write rules without modifying source files</span></div><div><code>/extract-rules --select 1,3</code> <span style="opacity: 0.6;">— Write only rules #1 and #3</span></div></div></div>',
1299
+ trigger: '/extract-rules'
1300
+ },
1301
+ 'gls': {
1302
+ title: 'gls.md',
1303
+ desc: 'Get the latest screenshot(s) and display them.<div style="margin-top: 12px;"><strong>Parameters</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Name</th><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Type</th><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Required</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>count</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>integer</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">optional</td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Number of screenshots to display. Use /gls-N syntax. Default: 1. Min: 1.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>path</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>string</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">optional</td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Screenshot directory path. Saved for future use. Auto-detected if omitted.</td></tr></table></div><div style="margin-top: 12px;"><strong>Responses</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Status</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>success</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Displays requested screenshot(s) from newest to oldest.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>no-screenshots</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Directory exists but contains no image files.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>no-directory</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Unable to detect screenshot directory — prompts for path.</td></tr></table></div><div style="margin-top: 12px;"><strong>Side Effects</strong><div style="margin-top: 4px; font-size: 0.9em;">Saves detected screenshot path to .claude/cca.config.json on first run</div></div><div style="margin-top: 12px;"><strong>Examples</strong><div style="margin-top: 6px; background: var(--bg-elevated); border-radius: 6px; padding: 8px 12px; font-family: monospace; font-size: 0.85em;"><div><code>/gls</code> <span style="opacity: 0.6;">— Display the most recent screenshot</span></div><div><code>/gls-3</code> <span style="opacity: 0.6;">— Display the 3 most recent screenshots</span></div><div><code>/gls /path/to/dir</code> <span style="opacity: 0.6;">— Use a specific screenshot directory</span></div></div></div>',
1304
+ trigger: '/gls'
1305
+ },
1306
+ 'publish': {
1307
+ title: 'publish.md',
1308
+ desc: 'Runs tests, bumps version, commits, and publishes to npm.<div style="margin-top: 12px;"><strong>Parameters</strong><div style="margin-top: 4px; opacity: 0.6;">None</div></div>',
1309
+ trigger: '/publish'
1310
+ },
1311
+ 'recover-context': {
1312
+ title: 'recover-context.md',
1313
+ desc: 'Recovers conversation context from the session transcript after compaction.<div style="margin-top: 12px;"><strong>Parameters</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Name</th><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Type</th><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Required</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>minutes</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>integer</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">required</td><td style="padding: 4px 8px 4px 0; vertical-align: top;">How far back to recover, in minutes. Leading dash optional. Min: 1.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>--show</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>flag</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">optional</td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Opens the extracted transcript in your default editor.</td></tr></table></div><div style="margin-top: 12px;"><strong>Responses</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Status</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>success</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">~{tokens} tokens recovered ({N} messages across {sessions} session(s), last {minutes} min).</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>no-transcript</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">No transcript files found.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>no-messages</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">No messages found in the requested time range.</td></tr></table></div><div style="margin-top: 12px;"><strong>Side Effects</strong><div style="margin-top: 4px; font-size: 0.9em;">Reads .jsonl transcripts from ~/.claude/projects/, writes temp file</div></div><div style="margin-top: 12px;"><strong>Examples</strong><div style="margin-top: 6px; background: var(--bg-elevated); border-radius: 6px; padding: 8px 12px; font-family: monospace; font-size: 0.85em;"><div><code>/recover-context -60</code> <span style="opacity: 0.6;">— Last 60 minutes of conversation</span></div><div><code>/recover-context 120</code> <span style="opacity: 0.6;">— Last 2 hours (dash optional)</span></div><div><code>/recover-context -60 --show</code> <span style="opacity: 0.6;">— Last 60 min + open transcript file</span></div></div></div>',
1314
+ trigger: '/recover-context'
1315
+ },
1316
+ 'show-docs': {
1317
+ title: 'show-docs.md',
1318
+ desc: 'Opens the interactive docs in your browser.<div style="margin-top: 12px;"><strong>Parameters</strong><div style="margin-top: 4px; opacity: 0.6;">None</div></div><div style="margin-top: 12px;"><strong>Responses</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Status</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>success</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Docs synced and opened in default browser.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>no-docs</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Docs file not found — run /autoconfig first.</td></tr></table></div><div style="margin-top: 12px;"><strong>Side Effects</strong><div style="margin-top: 4px; font-size: 0.9em;">Runs sync-docs.js to refresh content, opens browser</div></div><div style="margin-top: 12px;"><strong>Examples</strong><div style="margin-top: 6px; background: var(--bg-elevated); border-radius: 6px; padding: 8px 12px; font-family: monospace; font-size: 0.85em;"><div><code>/show-docs</code> <span style="opacity: 0.6;">— Open interactive documentation</span></div></div></div>',
1319
+ trigger: '/show-docs'
1320
+ },
1321
+ 'test': {
1322
+ title: 'test.md',
1323
+ desc: 'Runs your test suite. Auto-detects Jest, Vitest, Pytest, Go, RSpec, or falls back to npm test.<div style="margin-top: 12px;"><strong>Parameters</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Name</th><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Type</th><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Required</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>scope</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>string</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">optional</td><td style="padding: 4px 8px 4px 0; vertical-align: top;">File, directory, or pattern to limit test run. Runs full suite if omitted.</td></tr></table></div><div style="margin-top: 12px;"><strong>Responses</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Status</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>success</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Test suite passes.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>failure</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Test suite fails with non-zero exit code.</td></tr></table></div><div style="margin-top: 12px;"><strong>Side Effects</strong><div style="margin-top: 4px; font-size: 0.9em;">Executes detected test runner command</div></div><div style="margin-top: 12px;"><strong>Examples</strong><div style="margin-top: 6px; background: var(--bg-elevated); border-radius: 6px; padding: 8px 12px; font-family: monospace; font-size: 0.85em;"><div><code>/test</code> <span style="opacity: 0.6;">— Run full test suite</span></div><div><code>/test src/auth</code> <span style="opacity: 0.6;">— Run tests in src/auth directory</span></div><div><code>/test --coverage</code> <span style="opacity: 0.6;">— Run tests with coverage report</span></div></div></div>',
1324
+ trigger: '/test'
1325
+ },
1326
+ 'validate-cca-install': {
1327
+ title: 'validate-cca-install.md',
1328
+ desc: 'Validates your claude-code-autoconfig installation against the latest published version.<div style="margin-top: 12px;"><strong>Parameters</strong><div style="margin-top: 4px; opacity: 0.6;">None</div></div><div style="margin-top: 12px;"><strong>Responses</strong><table style="margin-top: 6px; border-collapse: collapse; font-size: 0.9em; text-align: left;"><tr style="text-align: left; border-bottom: 1px solid var(--border);"><th style="padding: 4px 8px 4px 0; white-space: nowrap;">Status</th><th style="padding: 4px 8px 4px 0;">Description</th></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>valid</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Install validated — all checks passed.</td></tr><tr style="border-bottom: 1px solid var(--border);"><td style="padding: 4px 8px 4px 0; vertical-align: top; white-space: nowrap;"><code>issues</code></td><td style="padding: 4px 8px 4px 0; vertical-align: top;">Validation found {N} issue(s) with fix suggestions.</td></tr></table></div><div style="margin-top: 12px;"><strong>Side Effects</strong><div style="margin-top: 4px; font-size: 0.9em;">Read-only. Downloads latest package to temp dir for comparison, then cleans up.</div></div><div style="margin-top: 12px;"><strong>Examples</strong><div style="margin-top: 6px; background: var(--bg-elevated); border-radius: 6px; padding: 8px 12px; font-family: monospace; font-size: 0.85em;"><div><code>/validate-cca-install</code> <span style="opacity: 0.6;">— Run full installation validation</span></div></div></div>',
1329
+ trigger: '/validate-cca-install'
1330
+ },
1331
+ 'README-agent': {
1332
+ title: 'README.md',
1333
+ desc: 'Placeholder — drop your project\'s custom subagent definitions in this directory.',
1334
+ trigger: 'Background agent'
1335
+ },
1336
+ 'feedback-rule-check-hook': {
1337
+ title: 'feedback-rule-check.js',
1338
+ desc: 'After FEEDBACK.md is edited, notifies Claude to evaluate',
1339
+ trigger: 'PostToolUse on Write|Edit'
1340
+ },
1341
+ 'format-hook': {
1342
+ title: 'format.js',
1343
+ desc: 'format.js in hooks/',
1344
+ trigger: 'PostToolUse hook'
1345
+ },
1346
+ 'migrate-feedback-hook': {
1347
+ title: 'migrate-feedback.js',
1348
+ desc: 'On session start, migrates custom FEEDBACK.md content to',
1349
+ trigger: 'SessionStart'
1350
+ },
1351
+ 'feedback-feedback': {
1352
+ title: 'FEEDBACK.md',
1353
+ desc: 'Human-authored corrections and guidance for Claude. Reserved for team feedback only — Claude must not write here. This directory persists across /autoconfig runs.'
1354
+ },
1355
+ 'docs': {
1356
+ title: 'docs/autoconfig.docs.html',
1357
+ desc: 'This interactive docs. Open it anytime to review what each file does.',
1358
+ trigger: '/show-docs'
1359
+ },
1360
+ 'rules': {
1361
+ title: 'rules/',
1362
+ 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>'
1363
+ },
1364
+ 'mcp': {
1365
+ title: '.mcp.json',
1366
+ desc: 'MCP (Model Context Protocol) server configuration. Add your MCP servers here.'
1367
+ },
1368
+ 'settings': {
1369
+ title: 'settings.json',
1370
+ desc: 'Permissions and security settings. Controls what Claude can auto-approve (allow) and what is always blocked (deny).'
1371
+ }
1372
+ };
1373
+
1374
+ // Tree panel hover handling
1375
+ const infoPanel = document.getElementById('infoPanel');
1376
+ const treeItems = document.querySelectorAll('.tree-item');
1377
+
1378
+ let selectedInfoKey = 'memory-md'; // Default selection
1379
+
1380
+ function showInfo(key) {
1381
+ const info = treeInfo[key];
1382
+ if (info) {
1383
+ let html = `<div class="info-panel-title">${info.title}</div>`;
1384
+ html += `<div class="info-panel-desc">${info.desc}</div>`;
1385
+ if (info.trigger) {
1386
+ html += `<div class="info-panel-trigger">${info.trigger}</div>`;
1387
+ }
1388
+ infoPanel.innerHTML = html;
1389
+ }
1390
+ }
1391
+
1392
+ treeItems.forEach((item, idx) => {
1393
+ // Hover updates info panel only (preview)
1394
+ item.addEventListener('mouseenter', () => {
1395
+ const key = item.dataset.info;
1396
+ showInfo(key);
1397
+ });
1398
+
1399
+ // Mouseleave restores selected item's info
1400
+ item.addEventListener('mouseleave', () => {
1401
+ showInfo(selectedInfoKey);
1402
+ });
1403
+
1404
+ // Click sets active selection
1405
+ item.addEventListener('click', (e) => {
1406
+ // Don't select if clicking on a folder chevron (let toggle handle it)
1407
+ if (e.target.classList.contains('tree-chevron')) return;
1408
+
1409
+ treeItems.forEach(i => i.classList.remove('active'));
1410
+ item.classList.add('active');
1411
+
1412
+ // Update selected info key
1413
+ selectedInfoKey = item.dataset.info;
1414
+ showInfo(selectedInfoKey);
1415
+
1416
+ // Sync selectedTreeIndex with visible items
1417
+ const visibleItems = Array.from(document.querySelectorAll('.tree-item:not(.hidden)'));
1418
+ selectedTreeIndex = visibleItems.indexOf(item);
1419
+ });
1420
+ });
1421
+
1422
+ // Folder collapse/expand handling
1423
+ function toggleFolder(folderId, collapsed) {
1424
+ const children = document.querySelectorAll(`[data-parent="${folderId}"]`);
1425
+ children.forEach(child => {
1426
+ if (collapsed) {
1427
+ child.classList.add('hidden');
1428
+ } else {
1429
+ child.classList.remove('hidden');
1430
+ if (child.dataset.folder && !child.classList.contains('collapsed')) {
1431
+ toggleFolder(child.dataset.folder, false);
1432
+ }
1433
+ }
1434
+ if (collapsed && child.dataset.folder) {
1435
+ toggleFolder(child.dataset.folder, true);
1436
+ }
1437
+ });
1438
+ }
1439
+
1440
+ document.querySelectorAll('.folder-row').forEach(folder => {
1441
+ folder.addEventListener('click', (e) => {
1442
+ const folderId = folder.dataset.folder;
1443
+ const isCollapsed = folder.classList.toggle('collapsed');
1444
+ toggleFolder(folderId, isCollapsed);
1445
+ });
1446
+ });
1447
+
1448
+ // Tree keyboard navigation
1449
+ let selectedTreeIndex = -1;
1450
+
1451
+ function getVisibleTreeItems() {
1452
+ return Array.from(document.querySelectorAll('.tree-item:not(.hidden)'));
1453
+ }
1454
+
1455
+ function selectTreeItemByKey(key) {
1456
+ const item = document.querySelector(`.tree-item[data-info="${key}"]`);
1457
+ if (!item) return;
1458
+
1459
+ treeItems.forEach(i => i.classList.remove('active'));
1460
+ item.classList.add('active');
1461
+
1462
+ selectedInfoKey = key;
1463
+ showInfo(selectedInfoKey);
1464
+
1465
+ // Update selectedTreeIndex
1466
+ const visibleItems = getVisibleTreeItems();
1467
+ selectedTreeIndex = visibleItems.indexOf(item);
1468
+ }
1469
+
1470
+ function selectTreeItem(index) {
1471
+ const items = getVisibleTreeItems();
1472
+ if (index < 0 || index >= items.length) return;
1473
+
1474
+ treeItems.forEach(i => i.classList.remove('active'));
1475
+
1476
+ selectedTreeIndex = index;
1477
+ const item = items[index];
1478
+ item.classList.add('active');
1479
+
1480
+ item.scrollIntoView({ block: 'nearest' });
1481
+
1482
+ selectedInfoKey = item.dataset.info;
1483
+ showInfo(selectedInfoKey);
1484
+ }
1485
+
1486
+ document.addEventListener('keydown', (e) => {
1487
+ if (currentSlide !== 0) return;
1488
+
1489
+ const items = getVisibleTreeItems();
1490
+ if (items.length === 0) return;
1491
+
1492
+ if (selectedTreeIndex === -1) {
1493
+ selectTreeItem(0);
1494
+ if (e.key === 'ArrowDown' || e.key === 'ArrowUp' || e.key === 'ArrowRight' || e.key === 'ArrowLeft') {
1495
+ e.preventDefault();
1496
+ }
1497
+ return;
1498
+ }
1499
+
1500
+ if (e.key === 'ArrowDown') {
1501
+ e.preventDefault();
1502
+ if (selectedTreeIndex < items.length - 1) {
1503
+ selectTreeItem(selectedTreeIndex + 1);
1504
+ }
1505
+ } else if (e.key === 'ArrowUp') {
1506
+ e.preventDefault();
1507
+ if (selectedTreeIndex > 0) {
1508
+ selectTreeItem(selectedTreeIndex - 1);
1509
+ }
1510
+ } else if (e.key === 'ArrowRight') {
1511
+ e.preventDefault();
1512
+ const item = items[selectedTreeIndex];
1513
+ if (item && item.classList.contains('folder-row')) {
1514
+ if (item.classList.contains('collapsed')) {
1515
+ item.classList.remove('collapsed');
1516
+ toggleFolder(item.dataset.folder, false);
1517
+ }
1518
+ }
1519
+ } else if (e.key === 'ArrowLeft') {
1520
+ e.preventDefault();
1521
+ const item = items[selectedTreeIndex];
1522
+ if (item && item.classList.contains('folder-row')) {
1523
+ if (!item.classList.contains('collapsed')) {
1524
+ item.classList.add('collapsed');
1525
+ toggleFolder(item.dataset.folder, true);
1526
+ }
1527
+ }
1528
+ } else if (e.key === 'Enter') {
1529
+ e.preventDefault();
1530
+ const item = items[selectedTreeIndex];
1531
+ if (item && item.classList.contains('folder-row')) {
1532
+ const isCollapsed = item.classList.toggle('collapsed');
1533
+ toggleFolder(item.dataset.folder, isCollapsed);
1534
+ }
1535
+ }
1536
+ });
1537
+
1538
+ // File Preview Modal
1539
+ const fileContents = {
1540
+ 'memory-md': {
1541
+ filename: 'MEMORY.md',
1542
+ content: `# Native Claude Code File — Debugging instructions appended by autoconfig
1543
+
1544
+ Location: ` + memoryPath + `
1545
+
1546
+ ---
1547
+
1548
+ ## Debugging — Evidence Before Solutions
1549
+ NEVER guess the root cause and jump to coding a fix. Always:
1550
+ 1. Add logging / check actual data first
1551
+ 2. Confirm root cause with evidence
1552
+ 3. Only then propose and implement a fix
1553
+ If you can't determine the cause from code alone, add diagnostic logging and verify with runtime data.
1554
+ CRITICAL: A plausible-looking cause from code reading is NOT confirmed evidence. Even if a mismatch looks obvious across multiple files, verify with runtime data before implementing. The more "obvious" the cause looks, the more important it is to verify — that's when the temptation to skip evidence gathering is strongest.`
1555
+ },
1556
+ 'claude-md': {
1557
+ filename: 'CLAUDE.md',
1558
+ content: `# Project Name
1559
+
1560
+ > Run \`/autoconfig\` to populate this based on your project.`
1561
+ },
1562
+ 'autoconfig-update': {
1563
+ filename: 'autoconfig-update.md',
1564
+ content: `<!-- @applied
1565
+ -->
1566
+
1567
+ # Autoconfig Update
1568
+
1569
+ Check for and install pending updates to your Claude Code configuration.
1570
+
1571
+ **Style guideline**: Work silently through Steps 1-3. Do not narrate internal steps, implementation details, or progress messages (e.g., "Let me check...", "The @applied block is empty..."). The first output the user sees should be the formatted summary in Step 4 (or the "up to date" message).
1572
+
1573
+ ## Step 1: Pull Latest Updates
1574
+
1575
+ Run this command via Bash to pull new update files from the latest package:
1576
+
1577
+ \`\`\`bash
1578
+ npx claude-code-autoconfig@latest --pull-updates
1579
+ \`\`\`
1580
+
1581
+ This copies any new update \`.md\` files into \`.claude/updates/\` and refreshes this command file (preserving the \`@applied\` block above).
1582
+
1583
+ After the command completes, check \`.claude/updates/\` directory. If it doesn't exist or is empty, output:
1584
+
1585
+ \`\`\`
1586
+ No new updates available. You're up to date.
1587
+ \`\`\`
1588
+
1589
+ Then stop — do not continue to further steps.
1590
+
1591
+ ## Step 2: Parse Update Files
1592
+
1593
+ Read all \`.md\` files in \`.claude/updates/\` matching the pattern \`NNN-*.md\` (e.g., \`001-debug-methodology.md\`).`
1594
+ },
1595
+ 'autoconfig': {
1596
+ filename: 'autoconfig.md',
1597
+ content: `# Autoconfig
1598
+
1599
+ Configure Claude Code scaffolding for this project — settings, permissions, hooks, commands, and docs.
1600
+
1601
+ CLAUDE.md is intentionally kept minimal. Claude can read your config files directly — pre-populating project descriptions wastes tokens and dilutes important rules. Instead, CLAUDE.md grows organically through Discoveries as you work.
1602
+
1603
+ **Setup Note**: During autoconfig, prefer Glob/Read/Write tools over Bash commands. This ensures smooth setup without permission prompts. Only use Bash for the bootstrap step and opening the guide at the end.
1604
+
1605
+ ## Step 0a: Bootstrap files from latest package
1606
+
1607
+ **MANDATORY: You MUST run this Bash command before doing anything else.** Do not skip it. Do not assume it will fail. It is designed to work inside Claude Code sessions:
1608
+
1609
+ \`\`\`bash
1610
+ npx claude-code-autoconfig@latest --bootstrap
1611
+ \`\`\`
1612
+
1613
+ This downloads the latest package and copies slash commands, hooks, agents, docs, and settings into \`.claude/\`. The \`--bootstrap\` flag makes it safe to run inside Claude Code — it copies files and exits silently with code 0. If it fails (e.g., no network), continue anyway — the existing files will still work.
1614
+
1615
+ ## Step 0b: Migrate FEEDBACK.md to Discoveries (one-time)
1616
+
1617
+ Read \`.claude/feedback/FEEDBACK.md\`. If it contains custom content beyond the default template header (sections after the first \`---\`), and \`CLAUDE.md\` does NOT already have a \`## Discoveries\` section:
1618
+
1619
+ 1. Read all custom content from FEEDBACK.md (everything after the first \`---\` separator)
1620
+ 2. Append a \`## Discoveries\` section to the bottom of CLAUDE.md with that content
1621
+ 3. Reset FEEDBACK.md to the clean template:
1622
+ \`\`\`
1623
+ <!-- @description Human-authored corrections and guidance for Claude. Reserved for team feedback only — Claude must not write here. This directory persists across /autoconfig runs. -->
1624
+
1625
+ # Team Feedback`
1626
+ },
1627
+ 'commit-and-push': {
1628
+ filename: 'commit-and-push.md',
1629
+ content: `# Commit and Push
1630
+
1631
+ Run tests, stage all changes, create a commit with a good message, and push to the current branch.
1632
+
1633
+ ## Steps
1634
+
1635
+ 1. Run the project's test suite (e.g., \`npm test\`)
1636
+ 2. **If tests fail, stop here.** Do not commit or push failing code.
1637
+ 3. Stage all changes (\`git add -A\`)
1638
+ 4. Generate a conventional commit message based on the diff
1639
+ 5. Commit the changes
1640
+ 6. Push to the current branch
1641
+
1642
+ ## Commit Message Format
1643
+
1644
+ Use conventional commits: \`type(scope): description\`
1645
+
1646
+ Types: feat, fix, docs, style, refactor, test, chore
1647
+
1648
+ Keep the subject line under 50 chars. Add body if the change needs explanation.`
1649
+ },
1650
+ 'extract-rules': {
1651
+ filename: 'extract-rules.md',
1652
+ content: `# Extract Rules
1653
+
1654
+ Scan all Claude configuration artifacts and propose structured rules for \`.claude/rules/\`.
1655
+
1656
+ ## Step 0: Git safety check
1657
+
1658
+ Before doing anything else, check for uncommitted changes:
1659
+
1660
+ \`\`\`bash
1661
+ git status --porcelain
1662
+ \`\`\`
1663
+
1664
+ If there are uncommitted changes, show this warning and wait for confirmation:
1665
+
1666
+ > **Warning:** This command will modify files (extract rules from sources and optionally clean up originals). You have uncommitted changes.
1667
+ >
1668
+ > Commit your work before proceeding, or type "continue" to proceed anyway.
1669
+
1670
+ If the working tree is clean, proceed silently.
1671
+
1672
+ ## Step 1: Discover sources
1673
+
1674
+ Scan these locations for \`.md\` files containing potential rules. **Skip any that don't exist** — not all projects have all of these:
1675
+
1676
+ 1. \`CLAUDE.md\` (project root)
1677
+ 2. \`CLAUDE.local.md\` (project root, if present)
1678
+ 3. All \`.md\` files in \`.claude/\` recursively (feedback, commands, etc.) — **excluding** \`.claude/rules/\` and \`.claude/commands/extract-rules.md\`
1679
+ 4. Any nested \`CLAUDE.md\` files in subdirectories (e.g., \`src/CLAUDE.md\`)
1680
+ 5. Auto memory files — memory often contains misplaced imperatives that should be promoted to rules. To find the memory directory, list \`~/.claude/projects/\` and fuzzy-match against the current project path. The directory name encodes the path with dashes replacing separators, but encoding varies by platform and may not be consistent for paths with spaces, special characters, or deep nesting. **Discovery strategy**: list all directories under \`~/.claude/projects/\`, then find the one whose name best matches the current working directory (check if the directory name contains key path segments like the project folder name). Read \`MEMORY.md\` in that directory, then each \`.md\` file it links to. If no match is found or the memory directory can't be read, skip this source silently.`
1681
+ },
1682
+ 'gls': {
1683
+ filename: 'gls.md',
1684
+ content: `Get the latest screenshot(s) and display them.
1685
+
1686
+ Usage:
1687
+ - \`/gls\` - Get and display the most recent screenshot
1688
+ - \`/gls-2\` - Get and display the 2 most recent screenshots
1689
+ - \`/gls-3\` - Get and display the 3 most recent screenshots
1690
+ - \`/gls-N\` - Get and display the N most recent screenshots
1691
+ - \`/gls /path/to/dir\` - Use a specific directory and save it
1692
+
1693
+ ## Step 1: Check for saved path
1694
+
1695
+ Read \`.claude/cca.config.json\` in the project root. If it exists and contains a \`gls.screenshotDir\` value, use that path and skip to Step 3.
1696
+
1697
+ If the file doesn't exist or the key is missing, continue to Step 2.
1698
+
1699
+ ## Step 2: Detect screenshot directory
1700
+
1701
+ If the user provides a path as an argument (e.g., \`/gls /path/to/dir\`), use that path and skip to Step 2b.
1702
+
1703
+ Otherwise, detect the OS and find the screenshot directory. Run this **single Bash command** which finds all candidate directories and reports the newest screenshot in each:
1704
+
1705
+ \`\`\`bash
1706
+ OS=$(uname -s); echo "OS=$OS"; for d in \\
1707
+ "$HOME/OneDrive/Pictures/Screenshots"* \\
1708
+ "$HOME/Pictures/Screenshots" \\
1709
+ "$HOME/Desktop" \\
1710
+ "$HOME/Pictures" \\
1711
+ "$HOME/Videos/Captures"; do \\
1712
+ [ -d "$d" ] || continue; \\
1713
+ newest=$(ls -t "$d/" 2>/dev/null | grep -iE '\\.(png|jpg|jpeg|bmp|webp|gif)$' | head -1); \\`
1714
+ },
1715
+ 'publish': {
1716
+ filename: 'publish.md',
1717
+ content: `# Publish
1718
+
1719
+ Run tests, bump the patch version, commit, push, and publish to npm.
1720
+
1721
+ ## Steps
1722
+
1723
+ 1. **Sync README.md** — Compare the current README against the actual state of the project (file tree, slash commands, features, settings). If anything is out of date or missing, update the README before proceeding. Check:
1724
+ - File tree matches actual \`.claude/\` directory contents
1725
+ - Slash commands table matches actual \`.claude/commands/\` files
1726
+ - Feature sections reflect current capabilities (update system, MEMORY.md, hooks, etc.)
1727
+ - No references to nonexistent commands or files
1728
+ 2. Run the project's test suite (\`npm test\`)
1729
+ 3. **If tests fail, stop here.** Do not publish broken code.
1730
+ 4. Check for uncommitted changes. If there are any:
1731
+ a. Stage all changes (\`git add -A\`)
1732
+ b. Generate a conventional commit message based on the diff
1733
+ c. Commit the changes
1734
+ 5. Bump the version: \`npm version patch\`
1735
+ 6. Push the commit and tag: \`git push && git push --tags\`
1736
+ 7. Publish to npm: \`npm publish\`
1737
+ 8. Output the new version number on success
1738
+
1739
+ ## Important
1740
+
1741
+ - Always run tests before publishing — never skip this step
1742
+ - If any step fails, stop immediately and report the error
1743
+ - Do not use \`--force\` on publish unless the user explicitly asks`
1744
+ },
1745
+ 'recover-context': {
1746
+ filename: 'recover-context.md',
1747
+ content: `Recover recent conversation context from the raw session transcript on disk.
1748
+
1749
+ Usage:
1750
+ - \`/recover-context -60\` — last 60 minutes of conversation
1751
+ - \`/recover-context -60 --show\` — same, but also opens the transcript in your editor
1752
+
1753
+ The number means "go back N minutes from now." The leading dash is optional. The minutes argument is **required**.
1754
+
1755
+ ## Step 1: Parse the arguments
1756
+
1757
+ The arguments are: $ARGUMENTS
1758
+
1759
+ - If empty or missing, ask the user: "How many minutes back? (e.g., -60)"
1760
+ - Strip the leading \`-\` from the number and treat it as the number of minutes to look back
1761
+ - Check if \`--show\` flag is present
1762
+
1763
+ ## Step 2: List candidate transcript files
1764
+
1765
+ List all \`.jsonl\` transcript files sorted by most recently modified:
1766
+
1767
+ \`\`\`bash
1768
+ ls -t ~/.claude/projects/*/*.jsonl 2>/dev/null | head -20
1769
+ \`\`\`
1770
+
1771
+ If no transcripts are found, tell the user and stop. Store the list as \`$TRANSCRIPT_FILES\` (one path per line).
1772
+
1773
+ ## Step 3: Identify which files to parse (lazy probing)
1774
+
1775
+ For each file in \`$TRANSCRIPT_FILES\` (starting from most recent), probe its time range by reading only the **first and last timestamp** — do NOT parse the full file yet. Run this script, substituting \`$MINUTES\` and \`$TRANSCRIPT_FILES\`:`
1776
+ },
1777
+ 'show-docs': {
1778
+ filename: 'show-docs.md',
1779
+ content: `# Show Docs
1780
+
1781
+ Open the interactive documentation for Claude Code Autoconfig.
1782
+
1783
+ ## Step 1: Sync Docs
1784
+
1785
+ Run the sync script to ensure the docs reflect the current state of \`.claude/\`:
1786
+
1787
+ \`\`\`bash
1788
+ node .claude/scripts/sync-docs.js
1789
+ \`\`\`
1790
+
1791
+ This scans all files in \`.claude/\` (commands, hooks, agents, feedback, updates, settings) and updates the docs HTML file tree, info cards, and content previews automatically. It's fast and idempotent.
1792
+
1793
+ If the script fails (e.g., file not found), skip to Step 2 — the docs will still open with whatever content they have.
1794
+
1795
+ ## Step 2: Open Docs
1796
+
1797
+ Open the docs in the default browser. Use the command matching the current OS:
1798
+
1799
+ - **macOS:** \`open .claude/docs/autoconfig.docs.html\`
1800
+ - **Linux:** \`xdg-open .claude/docs/autoconfig.docs.html\`
1801
+ - **Windows:** \`powershell -NoProfile -Command "Start-Process '.claude/docs/autoconfig.docs.html'"\`
1802
+
1803
+ **Important:** If the command exits with a non-zero exit code or produces an error, tell the user the file failed to open and suggest they open it manually. Do NOT report success unless the command completed without error.`
1804
+ },
1805
+ 'test': {
1806
+ filename: 'test.md',
1807
+ content: `# Run Tests
1808
+
1809
+ Run tests for this project.
1810
+
1811
+ **Scope:** $ARGUMENTS
1812
+
1813
+ If no scope provided, run the full test suite. Otherwise run tests matching the scope (file, directory, or pattern).
1814
+
1815
+ Detect the test command from project config (package.json scripts, pytest, go test, etc.) and execute it.`
1816
+ },
1817
+ 'validate-cca-install': {
1818
+ filename: 'validate-cca-install.md',
1819
+ content: `Validate the current claude-code-autoconfig installation. Reports what's correct, what's outdated, and what's missing. **Does not modify anything.**
1820
+
1821
+ Usage:
1822
+ - \`/validate-cca-install\` — run a full validation check
1823
+
1824
+ ## Step 1: Fetch the latest package metadata
1825
+
1826
+ Query the npm registry for the latest published version and its file manifest:
1827
+
1828
+ \`\`\`bash
1829
+ python3 -c "
1830
+ import json, urllib.request
1831
+ url = 'https://registry.npmjs.org/claude-code-autoconfig/latest'
1832
+ data = json.loads(urllib.request.urlopen(url, timeout=10).read())
1833
+ print(json.dumps({'version': data.get('version', 'unknown')}))
1834
+ "
1835
+ \`\`\`
1836
+
1837
+ Store the latest version as \`$LATEST_VERSION\`.
1838
+
1839
+ ## Step 2: Download and extract the latest package to a temp directory
1840
+
1841
+ \`\`\`bash
1842
+ TMPDIR=$(mktemp -d)
1843
+ npm pack claude-code-autoconfig@latest --pack-destination "$TMPDIR" 2>/dev/null
1844
+ tar -xzf "$TMPDIR"/*.tgz -C "$TMPDIR"
1845
+ echo "$TMPDIR/package"
1846
+ \`\`\`
1847
+
1848
+ Store the extracted path as \`$PKG_DIR\`. This gives us the ground truth for what files and versions should be installed.`
1849
+ },
1850
+ 'README-agent': {
1851
+ filename: 'README.md',
1852
+ content: `# Agents
1853
+
1854
+ This directory is where you define **subagents** — focused assistants Claude can delegate to during a task (e.g., a code reviewer, a test writer, a security auditor).
1855
+
1856
+ claude-code-autoconfig ships this folder empty so you can populate it with agents tuned to your project. Each agent is a single Markdown file with frontmatter describing its purpose, tools, and system prompt.
1857
+
1858
+ See Anthropic's subagents docs for the file format:
1859
+ https://docs.anthropic.com/en/docs/claude-code/sub-agents`
1860
+ },
1861
+ 'feedback-rule-check-hook': {
1862
+ filename: 'feedback-rule-check.js',
1863
+ content: `#!/usr/bin/env node
1864
+
1865
+ /**
1866
+ * @name Feedback Rule Migration Check
1867
+ * @description After FEEDBACK.md is edited, notifies Claude to evaluate
1868
+ * whether any entries would be more reliably delivered as
1869
+ * .claude/rules/ files with glob patterns.
1870
+ * @trigger PostToolUse on Write|Edit
1871
+ */
1872
+
1873
+ // Read hook input from stdin
1874
+ let input = '';
1875
+ process.stdin.setEncoding('utf8');
1876
+ process.stdin.on('data', chunk => input += chunk);
1877
+ process.stdin.on('end', () => {
1878
+ try {
1879
+ const data = JSON.parse(input);
1880
+ const filePath = data?.tool_input?.file_path || '';
1881
+
1882
+ // Only fire for FEEDBACK.md edits
1883
+ if (!filePath.endsWith('FEEDBACK.md')) {
1884
+ process.exit(0);
1885
+ }
1886
+
1887
+ console.log([
1888
+ 'FEEDBACK.md was just modified.',
1889
+ 'Review the changes and evaluate whether any entries are tied to specific file types,',
1890
+ 'frameworks, or patterns that could be scoped with a glob (e.g., *.py, *.tsx, src/api/**).',
1891
+ '',
1892
+ 'If any entries qualify, ask the user:',`
1893
+ },
1894
+ 'format-hook': {
1895
+ filename: 'format.js',
1896
+ content: `#!/usr/bin/env node
1897
+
1898
+ /**
1899
+ * @name Format Hook
1900
+ * @description Runs project formatter after Write/Edit operations
1901
+ * @trigger PostToolUse on Write|Edit
1902
+ */
1903
+
1904
+ const { execSync } = require('child_process');
1905
+ const path = require('path');
1906
+
1907
+ // Read hook input from stdin
1908
+ let input = '';
1909
+ process.stdin.setEncoding('utf8');
1910
+ process.stdin.on('data', chunk => input += chunk);
1911
+ process.stdin.on('end', () => {
1912
+ try {
1913
+ const data = JSON.parse(input);
1914
+ handleHook(data);
1915
+ } catch (err) {
1916
+ // Silent exit if no valid input
1917
+ process.exit(0);
1918
+ }
1919
+ });
1920
+
1921
+ function handleHook(data) {
1922
+ const filePath = data?.tool_input?.file_path || '';
1923
+
1924
+ // Skip non-source files
1925
+ if (!filePath.match(/\\.(js|jsx|ts|tsx|json|css|scss|md|html)$/)) {`
1926
+ },
1927
+ 'migrate-feedback-hook': {
1928
+ filename: 'migrate-feedback.js',
1929
+ content: `#!/usr/bin/env node
1930
+
1931
+ /**
1932
+ * @name Feedback to Discoveries Migration
1933
+ * @description On session start, migrates custom FEEDBACK.md content to
1934
+ * CLAUDE.md Discoveries section. One-time, idempotent.
1935
+ * @trigger SessionStart
1936
+ */
1937
+
1938
+ const fs = require('fs');
1939
+ const path = require('path');
1940
+
1941
+ const cwd = process.cwd();
1942
+ const claudeMdPath = path.join(cwd, 'CLAUDE.md');
1943
+ const feedbackPath = path.join(cwd, '.claude', 'feedback', 'FEEDBACK.md');
1944
+
1945
+ // Read hook input from stdin (required by hook protocol)
1946
+ let input = '';
1947
+ process.stdin.setEncoding('utf8');
1948
+ process.stdin.on('data', chunk => input += chunk);
1949
+ process.stdin.on('end', () => {
1950
+ try {
1951
+ migrate();
1952
+ } catch (err) {
1953
+ // Silent exit on any error
1954
+ }
1955
+ process.exit(0);
1956
+ });
1957
+
1958
+ function migrate() {`
1959
+ },
1960
+ 'feedback-feedback': {
1961
+ filename: 'FEEDBACK.md',
1962
+ content: `# Team Feedback
1963
+
1964
+ **This file is for human-authored corrections and guidance only.**
1965
+ Claude reads this file but must never write to it. When Claude discovers project context, gotchas, or learnings, it should append to the \`## Discoveries\` section in CLAUDE.md instead.
1966
+
1967
+ ---`
1968
+ },
1969
+ 'rules': {
1970
+ filename: 'rules/',
1971
+ content: null,
1972
+ empty: true,
1973
+ emptyMessage: 'Add .md files here to define rules for specific paths in your codebase.'
1974
+ },
1975
+ 'hooks': {
1976
+ filename: 'hooks/',
1977
+ content: null,
1978
+ empty: true,
1979
+ emptyMessage: 'Contains executable hook scripts that trigger on Claude Code events.'
1980
+ },
1981
+ 'docs': {
1982
+ filename: 'autoconfig.docs.html',
1983
+ content: null,
1984
+ empty: true,
1985
+ emptyMessage: "You\'re looking at it! 👀"
1986
+ },
1987
+ 'rules': {
1988
+ filename: 'rules/',
1989
+ content: null,
1990
+ empty: true,
1991
+ emptyMessage: 'This directory is empty.\nAdd .md files here to define rules for specific paths in your codebase.'
1992
+ },
1993
+ 'settings': {
1994
+ filename: 'settings.json',
1995
+ content: `{
1996
+ "env": {
1997
+ "CLAUDE_CODE_DISABLE_AUTO_MEMORY": "0"
1998
+ },
1999
+ "hooks": {
2000
+ "SessionStart": [
2001
+ {
2002
+ "matcher": "",
2003
+ "hooks": [
2004
+ {
2005
+ "type": "command",
2006
+ "command": "node .claude/hooks/migrate-feedback.js"
2007
+ }
2008
+ ]
2009
+ }
2010
+ ],
2011
+ "PostToolUse": [
2012
+ {
2013
+ "matcher": "Edit|Write",
2014
+ "hooks": [
2015
+ {
2016
+ "type": "command",
2017
+ "command": "node .claude/hooks/feedback-rule-check.js"
2018
+ }
2019
+ ]
2020
+ }
2021
+ ]
2022
+ },
2023
+ "permissions": {
2024
+ "allow": [
2025
+ "Read(./**)",
2026
+ "Edit(./**)",
2027
+ "Write(./**)",
2028
+ "Glob",
2029
+ "Grep",
2030
+ "WebSearch",
2031
+ "WebFetch",
2032
+ "Bash(npm test)",
2033
+ "Bash(npm test *)",
2034
+ "Bash(npm run dev)",
2035
+ "Bash(npm run build)",
2036
+ "Bash(npm run lint)",
2037
+ "Bash(npm run lint:fix)",
2038
+ "Bash(npm run typecheck)",
2039
+ "Bash(npm run test)",
2040
+ "Bash(npm run test:*)",
2041
+ "Bash(npm run validate)",
2042
+ "Bash(git status)",
2043
+ "Bash(git status *)",
2044
+ "Bash(git diff *)",
2045
+ "Bash(git add *)",
2046
+ "Bash(git commit *)",
2047
+ "Bash(git push *)",
2048
+ "Bash(git pull)",
2049
+ "Bash(git pull *)",
2050
+ "Bash(git checkout *)",
2051
+ "Bash(git branch *)",
2052
+ "Bash(node .claude/*)",
2053
+ "Bash(python3 *)",
2054
+ "Bash(npx claude-code-autoconfig*)",
2055
+ "Bash(npm pack *)",
2056
+ "Bash(tar *)",
2057
+ "Bash(mktemp *)",
2058
+ "Bash(find ./*)",
2059
+ "Bash(ls *)",
2060
+ "Bash(dir *)",
2061
+ "Bash(mkdir *)",
2062
+ "Bash(mkdir -p *)",
2063
+ "Bash(start *)",
2064
+ "Bash(start .claude *)",
2065
+ "Bash(open *)",
2066
+ "Bash(open .claude *)",
2067
+ "Bash(xdg-open *)",
2068
+ "Bash(xdg-open .claude *)"
2069
+ ],
2070
+ "deny": [
2071
+ "Read(./.env)",
2072
+ "Read(./.env.*)",
2073
+ "Read(./secrets/**)",
2074
+ "Read(./**/credentials.*)",
2075
+ "Read(./**/*.pem)",
2076
+ "Read(./**/*.key)",
2077
+ "Bash(rm -rf *)",
2078
+ "Bash(curl *)",
2079
+ "Bash(wget *)"
2080
+ ]
2081
+ }
2082
+ }`
2083
+ },
2084
+ 'mcp': {
2085
+ filename: '.mcp.json',
2086
+ content: `{
2087
+ "mcpServers": {}
2088
+ }`
2089
+ }
2090
+ };
2091
+
2092
+ const modal = document.getElementById('fileModal');
2093
+ const modalTitle = document.getElementById('modalTitle');
2094
+ const modalCode = document.getElementById('modalCode');
2095
+ const modalClose = document.getElementById('modalClose');
2096
+
2097
+ function openModal(key) {
2098
+ const file = fileContents[key];
2099
+ if (!file) return;
2100
+
2101
+ modalTitle.textContent = file.filename;
2102
+
2103
+ if (file.empty) {
2104
+ modalCode.innerHTML = `<span class="modal-empty">${file.emptyMessage}</span>`;
2105
+ } else {
2106
+ modalCode.textContent = file.content;
2107
+ }
2108
+
2109
+ modal.classList.add('visible');
2110
+ }
2111
+
2112
+ function closeModal() {
2113
+ modal.classList.remove('visible');
2114
+ }
2115
+
2116
+ modalClose.addEventListener('click', closeModal);
2117
+ modal.addEventListener('click', (e) => {
2118
+ if (e.target === modal) closeModal();
2119
+ });
2120
+ document.addEventListener('keydown', (e) => {
2121
+ if (e.key === 'Escape' && modal.classList.contains('visible')) {
2122
+ closeModal();
2123
+ }
2124
+ // Enter key opens preview for selected item
2125
+ if (e.key === 'Enter' && !modal.classList.contains('visible')) {
2126
+ const selected = document.querySelector('.tree-item.active');
2127
+ if (selected) {
2128
+ const key = selected.dataset.info;
2129
+ if (fileContents[key]) {
2130
+ openModal(key);
2131
+ }
2132
+ }
2133
+ }
2134
+ });
2135
+
2136
+ // Double-click to open file preview
2137
+ treeItems.forEach(item => {
2138
+ item.addEventListener('dblclick', (e) => {
2139
+ const key = item.dataset.info;
2140
+ // Don't open modal for folders (except rules which is empty) or root
2141
+ if (key === 'root' || key === 'claude-dir' || key === 'commands') return;
2142
+ if (fileContents[key]) {
2143
+ openModal(key);
2144
+ }
2145
+ });
2146
+ });
2147
+ </script>
2148
+ </body>
2149
2149
  </html>