@plebeiantech/lat.md 0.12.3-fork.1 → 0.12.3-fork.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +39 -3
  2. package/dist/src/cli/check-coverage.d.ts +2 -0
  3. package/dist/src/cli/check-coverage.js +71 -0
  4. package/dist/src/cli/check-mode.d.ts +16 -1
  5. package/dist/src/cli/check-mode.js +65 -4
  6. package/dist/src/cli/check.js +5 -1
  7. package/dist/src/cli/comment-guard.d.ts +14 -0
  8. package/dist/src/cli/comment-guard.js +10 -33
  9. package/dist/src/cli/comment-reminder.d.ts +65 -6
  10. package/dist/src/cli/comment-reminder.js +164 -28
  11. package/dist/src/cli/fork-instructions.d.ts +19 -0
  12. package/dist/src/cli/fork-instructions.js +183 -0
  13. package/dist/src/cli/fork-scaffold.d.ts +106 -0
  14. package/dist/src/cli/fork-scaffold.js +490 -0
  15. package/dist/src/cli/index.js +29 -4
  16. package/dist/src/cli/init.js +5 -0
  17. package/dist/src/cli/search.js +6 -4
  18. package/dist/src/cli/ui-build.d.ts +4 -0
  19. package/dist/src/cli/ui-build.js +13 -0
  20. package/dist/src/cli/ui.js +18 -2
  21. package/dist/src/code-refs.js +25 -4
  22. package/dist/src/fork/upstream-drift-cli.d.ts +1 -0
  23. package/dist/src/fork/upstream-drift-cli.js +2 -0
  24. package/dist/src/fork/upstream-drift.d.ts +26 -0
  25. package/dist/src/fork/upstream-drift.js +185 -0
  26. package/dist/src/fork/upstream-guard-cli.d.ts +1 -0
  27. package/dist/src/fork/upstream-guard-cli.js +2 -0
  28. package/dist/src/fork/upstream-guard.d.ts +72 -0
  29. package/dist/src/fork/upstream-guard.js +445 -0
  30. package/dist/src/graph-export.d.ts +2 -0
  31. package/dist/src/graph-export.js +31 -12
  32. package/dist/src/init-version.d.ts +1 -1
  33. package/dist/src/init-version.js +1 -1
  34. package/dist/src/knowledge/claude-memory.d.ts +1 -0
  35. package/dist/src/knowledge/claude-memory.js +33 -4
  36. package/dist/src/lattice.d.ts +2 -1
  37. package/dist/src/lattice.js +1 -0
  38. package/dist/src/search/index.js +23 -6
  39. package/dist/src/search/search.d.ts +1 -0
  40. package/dist/src/search/search.js +15 -9
  41. package/dist/src/untrusted.d.ts +0 -6
  42. package/dist/src/untrusted.js +7 -11
  43. package/dist/src/view/client/assets/index-C3iaZyYT.css +1 -0
  44. package/dist/src/view/client/assets/index-KWi67IMz.js +334 -0
  45. package/dist/src/view/client/assets/logo-CNF8zs47.svg +182 -0
  46. package/dist/src/view/client/index.html +2 -2
  47. package/dist/src/view/git-diff.js +17 -0
  48. package/dist/src/view/graph.d.ts +6 -0
  49. package/dist/src/view/graph.js +176 -0
  50. package/dist/src/view/markdown.d.ts +5 -1
  51. package/dist/src/view/markdown.js +112 -25
  52. package/dist/src/view/protocol.d.ts +43 -0
  53. package/dist/src/view/protocol.js +1 -1
  54. package/dist/src/view/references.d.ts +2 -0
  55. package/dist/src/view/references.js +30 -8
  56. package/dist/src/view/repository.d.ts +5 -2
  57. package/dist/src/view/repository.js +13 -12
  58. package/dist/src/view/search.js +1 -0
  59. package/dist/src/view/server.d.ts +3 -0
  60. package/dist/src/view/server.js +42 -9
  61. package/dist/src/view/source-target.d.ts +8 -0
  62. package/dist/src/view/source-target.js +22 -0
  63. package/dist/src/view/static-build.d.ts +16 -0
  64. package/dist/src/view/static-build.js +408 -0
  65. package/dist/src/view/static-protocol.d.ts +23 -0
  66. package/dist/src/view/static-protocol.js +10 -0
  67. package/dist/src/view/store.d.ts +9 -1
  68. package/dist/src/view/store.js +82 -15
  69. package/dist/src/view/table-of-contents.d.ts +9 -0
  70. package/dist/src/view/table-of-contents.js +103 -0
  71. package/package.json +12 -10
  72. package/templates/AGENTS.md +2 -13
  73. package/templates/fork/conventions.md +119 -0
  74. package/templates/skill/SKILL.md +3 -14
  75. package/dist/src/view/client/assets/index-B0n0u03y.css +0 -1
  76. package/dist/src/view/client/assets/index-xm2_px4q.js +0 -23
@@ -0,0 +1,182 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 73224 16688" fill="#ddd">
2
+ <defs>
3
+ <path id="g2588" d="M-20 -512V1576H1253V-512Z"/>
4
+ <path id="g2591" d="M934 -512V-251H1094V-512ZM298 -512V-251H457V-512ZM616 -147V114H775V-147ZM-20 -147V114H138V-147ZM934 219V480H1094V219ZM298 219V480H457V219ZM616 584V845H775V584ZM-20 584V845H138V584ZM934 950V1211H1094V950ZM298 950V1211H457V950ZM616 1315V1576H775V1315ZM-20 1315V1576H138V1315Z"/>
5
+ </defs>
6
+ <use href="#g2591" transform="translate(0,0) scale(1,-1) translate(0,-1901)"/>
7
+ <use href="#g2588" transform="translate(1356,0) scale(1,-1) translate(0,-1901)"/>
8
+ <use href="#g2588" transform="translate(2712,0) scale(1,-1) translate(0,-1901)"/>
9
+ <use href="#g2591" transform="translate(21696,0) scale(1,-1) translate(0,-1901)"/>
10
+ <use href="#g2588" transform="translate(23052,0) scale(1,-1) translate(0,-1901)"/>
11
+ <use href="#g2588" transform="translate(24408,0) scale(1,-1) translate(0,-1901)"/>
12
+ <use href="#g2591" transform="translate(69156,0) scale(1,-1) translate(0,-1901)"/>
13
+ <use href="#g2588" transform="translate(70512,0) scale(1,-1) translate(0,-1901)"/>
14
+ <use href="#g2588" transform="translate(71868,0) scale(1,-1) translate(0,-1901)"/>
15
+ <use href="#g2591" transform="translate(0,2384) scale(1,-1) translate(0,-1901)"/>
16
+ <use href="#g2588" transform="translate(1356,2384) scale(1,-1) translate(0,-1901)"/>
17
+ <use href="#g2588" transform="translate(2712,2384) scale(1,-1) translate(0,-1901)"/>
18
+ <use href="#g2591" transform="translate(21696,2384) scale(1,-1) translate(0,-1901)"/>
19
+ <use href="#g2588" transform="translate(23052,2384) scale(1,-1) translate(0,-1901)"/>
20
+ <use href="#g2588" transform="translate(24408,2384) scale(1,-1) translate(0,-1901)"/>
21
+ <use href="#g2591" transform="translate(69156,2384) scale(1,-1) translate(0,-1901)"/>
22
+ <use href="#g2588" transform="translate(70512,2384) scale(1,-1) translate(0,-1901)"/>
23
+ <use href="#g2588" transform="translate(71868,2384) scale(1,-1) translate(0,-1901)"/>
24
+ <use href="#g2591" transform="translate(0,4768) scale(1,-1) translate(0,-1901)"/>
25
+ <use href="#g2588" transform="translate(1356,4768) scale(1,-1) translate(0,-1901)"/>
26
+ <use href="#g2588" transform="translate(2712,4768) scale(1,-1) translate(0,-1901)"/>
27
+ <use href="#g2591" transform="translate(6780,4768) scale(1,-1) translate(0,-1901)"/>
28
+ <use href="#g2588" transform="translate(8136,4768) scale(1,-1) translate(0,-1901)"/>
29
+ <use href="#g2588" transform="translate(9492,4768) scale(1,-1) translate(0,-1901)"/>
30
+ <use href="#g2588" transform="translate(10848,4768) scale(1,-1) translate(0,-1901)"/>
31
+ <use href="#g2588" transform="translate(12204,4768) scale(1,-1) translate(0,-1901)"/>
32
+ <use href="#g2588" transform="translate(13560,4768) scale(1,-1) translate(0,-1901)"/>
33
+ <use href="#g2588" transform="translate(14916,4768) scale(1,-1) translate(0,-1901)"/>
34
+ <use href="#g2591" transform="translate(18984,4768) scale(1,-1) translate(0,-1901)"/>
35
+ <use href="#g2588" transform="translate(20340,4768) scale(1,-1) translate(0,-1901)"/>
36
+ <use href="#g2588" transform="translate(21696,4768) scale(1,-1) translate(0,-1901)"/>
37
+ <use href="#g2588" transform="translate(23052,4768) scale(1,-1) translate(0,-1901)"/>
38
+ <use href="#g2588" transform="translate(24408,4768) scale(1,-1) translate(0,-1901)"/>
39
+ <use href="#g2588" transform="translate(25764,4768) scale(1,-1) translate(0,-1901)"/>
40
+ <use href="#g2588" transform="translate(27120,4768) scale(1,-1) translate(0,-1901)"/>
41
+ <use href="#g2591" transform="translate(37968,4768) scale(1,-1) translate(0,-1901)"/>
42
+ <use href="#g2588" transform="translate(39324,4768) scale(1,-1) translate(0,-1901)"/>
43
+ <use href="#g2588" transform="translate(40680,4768) scale(1,-1) translate(0,-1901)"/>
44
+ <use href="#g2588" transform="translate(42036,4768) scale(1,-1) translate(0,-1901)"/>
45
+ <use href="#g2588" transform="translate(43392,4768) scale(1,-1) translate(0,-1901)"/>
46
+ <use href="#g2588" transform="translate(44748,4768) scale(1,-1) translate(0,-1901)"/>
47
+ <use href="#g2588" transform="translate(46104,4768) scale(1,-1) translate(0,-1901)"/>
48
+ <use href="#g2588" transform="translate(47460,4768) scale(1,-1) translate(0,-1901)"/>
49
+ <use href="#g2588" transform="translate(48816,4768) scale(1,-1) translate(0,-1901)"/>
50
+ <use href="#g2588" transform="translate(50172,4768) scale(1,-1) translate(0,-1901)"/>
51
+ <use href="#g2588" transform="translate(51528,4768) scale(1,-1) translate(0,-1901)"/>
52
+ <use href="#g2588" transform="translate(52884,4768) scale(1,-1) translate(0,-1901)"/>
53
+ <use href="#g2588" transform="translate(54240,4768) scale(1,-1) translate(0,-1901)"/>
54
+ <use href="#g2588" transform="translate(55596,4768) scale(1,-1) translate(0,-1901)"/>
55
+ <use href="#g2591" transform="translate(61020,4768) scale(1,-1) translate(0,-1901)"/>
56
+ <use href="#g2588" transform="translate(62376,4768) scale(1,-1) translate(0,-1901)"/>
57
+ <use href="#g2588" transform="translate(63732,4768) scale(1,-1) translate(0,-1901)"/>
58
+ <use href="#g2588" transform="translate(65088,4768) scale(1,-1) translate(0,-1901)"/>
59
+ <use href="#g2588" transform="translate(66444,4768) scale(1,-1) translate(0,-1901)"/>
60
+ <use href="#g2588" transform="translate(67800,4768) scale(1,-1) translate(0,-1901)"/>
61
+ <use href="#g2588" transform="translate(69156,4768) scale(1,-1) translate(0,-1901)"/>
62
+ <use href="#g2588" transform="translate(70512,4768) scale(1,-1) translate(0,-1901)"/>
63
+ <use href="#g2588" transform="translate(71868,4768) scale(1,-1) translate(0,-1901)"/>
64
+ <use href="#g2591" transform="translate(0,7152) scale(1,-1) translate(0,-1901)"/>
65
+ <use href="#g2588" transform="translate(1356,7152) scale(1,-1) translate(0,-1901)"/>
66
+ <use href="#g2588" transform="translate(2712,7152) scale(1,-1) translate(0,-1901)"/>
67
+ <use href="#g2591" transform="translate(13560,7152) scale(1,-1) translate(0,-1901)"/>
68
+ <use href="#g2588" transform="translate(14916,7152) scale(1,-1) translate(0,-1901)"/>
69
+ <use href="#g2588" transform="translate(16272,7152) scale(1,-1) translate(0,-1901)"/>
70
+ <use href="#g2591" transform="translate(21696,7152) scale(1,-1) translate(0,-1901)"/>
71
+ <use href="#g2588" transform="translate(23052,7152) scale(1,-1) translate(0,-1901)"/>
72
+ <use href="#g2588" transform="translate(24408,7152) scale(1,-1) translate(0,-1901)"/>
73
+ <use href="#g2591" transform="translate(37968,7152) scale(1,-1) translate(0,-1901)"/>
74
+ <use href="#g2588" transform="translate(39324,7152) scale(1,-1) translate(0,-1901)"/>
75
+ <use href="#g2588" transform="translate(40680,7152) scale(1,-1) translate(0,-1901)"/>
76
+ <use href="#g2591" transform="translate(46104,7152) scale(1,-1) translate(0,-1901)"/>
77
+ <use href="#g2588" transform="translate(47460,7152) scale(1,-1) translate(0,-1901)"/>
78
+ <use href="#g2588" transform="translate(48816,7152) scale(1,-1) translate(0,-1901)"/>
79
+ <use href="#g2591" transform="translate(54240,7152) scale(1,-1) translate(0,-1901)"/>
80
+ <use href="#g2588" transform="translate(55596,7152) scale(1,-1) translate(0,-1901)"/>
81
+ <use href="#g2588" transform="translate(56952,7152) scale(1,-1) translate(0,-1901)"/>
82
+ <use href="#g2591" transform="translate(59664,7152) scale(1,-1) translate(0,-1901)"/>
83
+ <use href="#g2588" transform="translate(61020,7152) scale(1,-1) translate(0,-1901)"/>
84
+ <use href="#g2588" transform="translate(62376,7152) scale(1,-1) translate(0,-1901)"/>
85
+ <use href="#g2591" transform="translate(69156,7152) scale(1,-1) translate(0,-1901)"/>
86
+ <use href="#g2588" transform="translate(70512,7152) scale(1,-1) translate(0,-1901)"/>
87
+ <use href="#g2588" transform="translate(71868,7152) scale(1,-1) translate(0,-1901)"/>
88
+ <use href="#g2591" transform="translate(0,9536) scale(1,-1) translate(0,-1901)"/>
89
+ <use href="#g2588" transform="translate(1356,9536) scale(1,-1) translate(0,-1901)"/>
90
+ <use href="#g2588" transform="translate(2712,9536) scale(1,-1) translate(0,-1901)"/>
91
+ <use href="#g2591" transform="translate(6780,9536) scale(1,-1) translate(0,-1901)"/>
92
+ <use href="#g2588" transform="translate(8136,9536) scale(1,-1) translate(0,-1901)"/>
93
+ <use href="#g2588" transform="translate(9492,9536) scale(1,-1) translate(0,-1901)"/>
94
+ <use href="#g2588" transform="translate(10848,9536) scale(1,-1) translate(0,-1901)"/>
95
+ <use href="#g2588" transform="translate(12204,9536) scale(1,-1) translate(0,-1901)"/>
96
+ <use href="#g2588" transform="translate(13560,9536) scale(1,-1) translate(0,-1901)"/>
97
+ <use href="#g2588" transform="translate(14916,9536) scale(1,-1) translate(0,-1901)"/>
98
+ <use href="#g2588" transform="translate(16272,9536) scale(1,-1) translate(0,-1901)"/>
99
+ <use href="#g2591" transform="translate(21696,9536) scale(1,-1) translate(0,-1901)"/>
100
+ <use href="#g2588" transform="translate(23052,9536) scale(1,-1) translate(0,-1901)"/>
101
+ <use href="#g2588" transform="translate(24408,9536) scale(1,-1) translate(0,-1901)"/>
102
+ <use href="#g2591" transform="translate(37968,9536) scale(1,-1) translate(0,-1901)"/>
103
+ <use href="#g2588" transform="translate(39324,9536) scale(1,-1) translate(0,-1901)"/>
104
+ <use href="#g2588" transform="translate(40680,9536) scale(1,-1) translate(0,-1901)"/>
105
+ <use href="#g2591" transform="translate(46104,9536) scale(1,-1) translate(0,-1901)"/>
106
+ <use href="#g2588" transform="translate(47460,9536) scale(1,-1) translate(0,-1901)"/>
107
+ <use href="#g2588" transform="translate(48816,9536) scale(1,-1) translate(0,-1901)"/>
108
+ <use href="#g2591" transform="translate(54240,9536) scale(1,-1) translate(0,-1901)"/>
109
+ <use href="#g2588" transform="translate(55596,9536) scale(1,-1) translate(0,-1901)"/>
110
+ <use href="#g2588" transform="translate(56952,9536) scale(1,-1) translate(0,-1901)"/>
111
+ <use href="#g2591" transform="translate(59664,9536) scale(1,-1) translate(0,-1901)"/>
112
+ <use href="#g2588" transform="translate(61020,9536) scale(1,-1) translate(0,-1901)"/>
113
+ <use href="#g2588" transform="translate(62376,9536) scale(1,-1) translate(0,-1901)"/>
114
+ <use href="#g2591" transform="translate(69156,9536) scale(1,-1) translate(0,-1901)"/>
115
+ <use href="#g2588" transform="translate(70512,9536) scale(1,-1) translate(0,-1901)"/>
116
+ <use href="#g2588" transform="translate(71868,9536) scale(1,-1) translate(0,-1901)"/>
117
+ <use href="#g2591" transform="translate(0,11920) scale(1,-1) translate(0,-1901)"/>
118
+ <use href="#g2588" transform="translate(1356,11920) scale(1,-1) translate(0,-1901)"/>
119
+ <use href="#g2588" transform="translate(2712,11920) scale(1,-1) translate(0,-1901)"/>
120
+ <use href="#g2591" transform="translate(5424,11920) scale(1,-1) translate(0,-1901)"/>
121
+ <use href="#g2588" transform="translate(6780,11920) scale(1,-1) translate(0,-1901)"/>
122
+ <use href="#g2588" transform="translate(8136,11920) scale(1,-1) translate(0,-1901)"/>
123
+ <use href="#g2591" transform="translate(13560,11920) scale(1,-1) translate(0,-1901)"/>
124
+ <use href="#g2588" transform="translate(14916,11920) scale(1,-1) translate(0,-1901)"/>
125
+ <use href="#g2588" transform="translate(16272,11920) scale(1,-1) translate(0,-1901)"/>
126
+ <use href="#g2591" transform="translate(21696,11920) scale(1,-1) translate(0,-1901)"/>
127
+ <use href="#g2588" transform="translate(23052,11920) scale(1,-1) translate(0,-1901)"/>
128
+ <use href="#g2588" transform="translate(24408,11920) scale(1,-1) translate(0,-1901)"/>
129
+ <use href="#g2591" transform="translate(37968,11920) scale(1,-1) translate(0,-1901)"/>
130
+ <use href="#g2588" transform="translate(39324,11920) scale(1,-1) translate(0,-1901)"/>
131
+ <use href="#g2588" transform="translate(40680,11920) scale(1,-1) translate(0,-1901)"/>
132
+ <use href="#g2591" transform="translate(46104,11920) scale(1,-1) translate(0,-1901)"/>
133
+ <use href="#g2588" transform="translate(47460,11920) scale(1,-1) translate(0,-1901)"/>
134
+ <use href="#g2588" transform="translate(48816,11920) scale(1,-1) translate(0,-1901)"/>
135
+ <use href="#g2591" transform="translate(54240,11920) scale(1,-1) translate(0,-1901)"/>
136
+ <use href="#g2588" transform="translate(55596,11920) scale(1,-1) translate(0,-1901)"/>
137
+ <use href="#g2588" transform="translate(56952,11920) scale(1,-1) translate(0,-1901)"/>
138
+ <use href="#g2591" transform="translate(59664,11920) scale(1,-1) translate(0,-1901)"/>
139
+ <use href="#g2588" transform="translate(61020,11920) scale(1,-1) translate(0,-1901)"/>
140
+ <use href="#g2588" transform="translate(62376,11920) scale(1,-1) translate(0,-1901)"/>
141
+ <use href="#g2591" transform="translate(67800,11920) scale(1,-1) translate(0,-1901)"/>
142
+ <use href="#g2588" transform="translate(69156,11920) scale(1,-1) translate(0,-1901)"/>
143
+ <use href="#g2588" transform="translate(70512,11920) scale(1,-1) translate(0,-1901)"/>
144
+ <use href="#g2588" transform="translate(71868,11920) scale(1,-1) translate(0,-1901)"/>
145
+ <use href="#g2591" transform="translate(0,14304) scale(1,-1) translate(0,-1901)"/>
146
+ <use href="#g2588" transform="translate(1356,14304) scale(1,-1) translate(0,-1901)"/>
147
+ <use href="#g2588" transform="translate(2712,14304) scale(1,-1) translate(0,-1901)"/>
148
+ <use href="#g2591" transform="translate(6780,14304) scale(1,-1) translate(0,-1901)"/>
149
+ <use href="#g2588" transform="translate(8136,14304) scale(1,-1) translate(0,-1901)"/>
150
+ <use href="#g2588" transform="translate(9492,14304) scale(1,-1) translate(0,-1901)"/>
151
+ <use href="#g2588" transform="translate(10848,14304) scale(1,-1) translate(0,-1901)"/>
152
+ <use href="#g2588" transform="translate(12204,14304) scale(1,-1) translate(0,-1901)"/>
153
+ <use href="#g2588" transform="translate(13560,14304) scale(1,-1) translate(0,-1901)"/>
154
+ <use href="#g2591" transform="translate(14916,14304) scale(1,-1) translate(0,-1901)"/>
155
+ <use href="#g2588" transform="translate(16272,14304) scale(1,-1) translate(0,-1901)"/>
156
+ <use href="#g2588" transform="translate(17628,14304) scale(1,-1) translate(0,-1901)"/>
157
+ <use href="#g2591" transform="translate(23052,14304) scale(1,-1) translate(0,-1901)"/>
158
+ <use href="#g2588" transform="translate(24408,14304) scale(1,-1) translate(0,-1901)"/>
159
+ <use href="#g2588" transform="translate(25764,14304) scale(1,-1) translate(0,-1901)"/>
160
+ <use href="#g2588" transform="translate(27120,14304) scale(1,-1) translate(0,-1901)"/>
161
+ <use href="#g2591" transform="translate(31188,14304) scale(1,-1) translate(0,-1901)"/>
162
+ <use href="#g2588" transform="translate(32544,14304) scale(1,-1) translate(0,-1901)"/>
163
+ <use href="#g2588" transform="translate(33900,14304) scale(1,-1) translate(0,-1901)"/>
164
+ <use href="#g2591" transform="translate(37968,14304) scale(1,-1) translate(0,-1901)"/>
165
+ <use href="#g2588" transform="translate(39324,14304) scale(1,-1) translate(0,-1901)"/>
166
+ <use href="#g2588" transform="translate(40680,14304) scale(1,-1) translate(0,-1901)"/>
167
+ <use href="#g2591" transform="translate(46104,14304) scale(1,-1) translate(0,-1901)"/>
168
+ <use href="#g2588" transform="translate(47460,14304) scale(1,-1) translate(0,-1901)"/>
169
+ <use href="#g2588" transform="translate(48816,14304) scale(1,-1) translate(0,-1901)"/>
170
+ <use href="#g2591" transform="translate(54240,14304) scale(1,-1) translate(0,-1901)"/>
171
+ <use href="#g2588" transform="translate(55596,14304) scale(1,-1) translate(0,-1901)"/>
172
+ <use href="#g2588" transform="translate(56952,14304) scale(1,-1) translate(0,-1901)"/>
173
+ <use href="#g2591" transform="translate(61020,14304) scale(1,-1) translate(0,-1901)"/>
174
+ <use href="#g2588" transform="translate(62376,14304) scale(1,-1) translate(0,-1901)"/>
175
+ <use href="#g2588" transform="translate(63732,14304) scale(1,-1) translate(0,-1901)"/>
176
+ <use href="#g2588" transform="translate(65088,14304) scale(1,-1) translate(0,-1901)"/>
177
+ <use href="#g2588" transform="translate(66444,14304) scale(1,-1) translate(0,-1901)"/>
178
+ <use href="#g2588" transform="translate(67800,14304) scale(1,-1) translate(0,-1901)"/>
179
+ <use href="#g2591" transform="translate(69156,14304) scale(1,-1) translate(0,-1901)"/>
180
+ <use href="#g2588" transform="translate(70512,14304) scale(1,-1) translate(0,-1901)"/>
181
+ <use href="#g2588" transform="translate(71868,14304) scale(1,-1) translate(0,-1901)"/>
182
+ </svg>
@@ -5,8 +5,8 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <meta name="color-scheme" content="light dark" />
7
7
  <title>lat.md</title>
8
- <script type="module" crossorigin src="/assets/index-xm2_px4q.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-B0n0u03y.css">
8
+ <script type="module" crossorigin src="/assets/index-KWi67IMz.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-C3iaZyYT.css">
10
10
  </head>
11
11
  <body>
12
12
  <div id="root"></div>
@@ -1,6 +1,8 @@
1
1
  import { parse } from '../parser.js';
2
2
  const MAX_DIFF_CELLS = 1_000_000;
3
+ const MIN_INLINE_WORD_OVERLAP = 0.6;
3
4
  const WORDS = /\s+|[\p{L}\p{N}_]+|[^\s\p{L}\p{N}_]+/gu;
5
+ const WORD_TOKENS = /[\p{L}\p{N}_]+/gu;
4
6
  function sequenceDiff(oldValues, newValues, key) {
5
7
  const oldKeys = oldValues.map(key);
6
8
  const newKeys = newValues.map(key);
@@ -83,6 +85,15 @@ function nodeText(node) {
83
85
  return node.value;
84
86
  return withChildren(node) ? node.children.map(nodeText).join('') : '';
85
87
  }
88
+ function inlineWordOverlap(oldNode, newNode) {
89
+ const oldWords = nodeText(oldNode).toLowerCase().match(WORD_TOKENS) ?? [];
90
+ const newWords = nodeText(newNode).toLowerCase().match(WORD_TOKENS) ?? [];
91
+ if (oldWords.length === 0 || newWords.length === 0) {
92
+ return oldWords.length === newWords.length ? 1 : 0;
93
+ }
94
+ const shared = sequenceDiff(oldWords, newWords, (word) => word).filter((change) => change.kind === 'same').length;
95
+ return shared / (oldWords.length + newWords.length - shared);
96
+ }
86
97
  function wrapperSignature(node) {
87
98
  switch (node.type) {
88
99
  case 'link':
@@ -166,6 +177,9 @@ function addClass(node, kind) {
166
177
  : current
167
178
  ? [String(current)]
168
179
  : [];
180
+ if (result.type === 'code' && result.lang) {
181
+ classes.push(`language-${result.lang}`);
182
+ }
169
183
  classes.push(`git-${kind}`);
170
184
  result.data = {
171
185
  ...result.data,
@@ -189,6 +203,9 @@ function pairedNode(oldNode, newNode, oldMarkdown, newMarkdown) {
189
203
  if ((newNode.type === 'heading' || newNode.type === 'paragraph') &&
190
204
  withChildren(oldNode) &&
191
205
  withChildren(newNode)) {
206
+ if (inlineWordOverlap(oldNode, newNode) < MIN_INLINE_WORD_OVERLAP) {
207
+ return null;
208
+ }
192
209
  return {
193
210
  ...structuredClone(newNode),
194
211
  children: diffInline(oldNode.children, newNode.children),
@@ -0,0 +1,6 @@
1
+ import { type Section } from '../lattice.js';
2
+ import type { ViewDocumentError, ViewGraph } from './protocol.js';
3
+ import type { ViewCodeReferenceFile, ViewParsedMarkdownFile } from './references.js';
4
+ import type { ViewGitSnapshot } from './git.js';
5
+ /** Project the cached view state into stable nodes and weighted relationships. */
6
+ export declare function buildViewGraph(markdownFiles: Iterable<ViewParsedMarkdownFile>, codeFiles: Iterable<ViewCodeReferenceFile>, allSections: Section[], diagnostics: ReadonlyMap<string, readonly ViewDocumentError[]>, git: ViewGitSnapshot, generation: number): ViewGraph;
@@ -0,0 +1,176 @@
1
+ import { posix } from 'node:path';
2
+ import { buildFileIndex, buildSectionSlugIndex, flattenSections, resolveRef, } from '../lattice.js';
3
+ import { linkedSection } from './references.js';
4
+ import { viewSourceTarget } from './source-target.js';
5
+ function encodedPath(path) {
6
+ return path.split('/').map(encodeURIComponent).join('/');
7
+ }
8
+ function documentUrl(path, fragment = '') {
9
+ return `/docs/${encodedPath(path)}${fragment ? `#${encodeURIComponent(fragment)}` : ''}`;
10
+ }
11
+ function sourceUrl(path, symbol = '', line = 0) {
12
+ const search = line > 0 ? `?at=${line}` : '';
13
+ const fragment = symbol ? `#${encodeURIComponent(symbol)}` : '';
14
+ return `/code/${encodedPath(path)}${search}${fragment}`;
15
+ }
16
+ function pathBreadcrumbs(path) {
17
+ return path.replace(/\.md$/i, '').split('/');
18
+ }
19
+ function nodeLabelFromPath(path) {
20
+ return posix.basename(path).replace(/\.md$/i, '');
21
+ }
22
+ /** Project the cached view state into stable nodes and weighted relationships. */
23
+ export function buildViewGraph(markdownFiles, codeFiles, allSections, diagnostics, git, generation) {
24
+ const files = [...markdownFiles].sort((left, right) => left.path.localeCompare(right.path));
25
+ const sections = flattenSections(allSections);
26
+ const sectionIds = new Set(sections.map((section) => section.id.toLowerCase()));
27
+ const fileIndex = buildFileIndex(allSections);
28
+ const slugIndex = buildSectionSlugIndex(allSections);
29
+ const sectionById = new Map(sections.map((section) => [section.id.toLowerCase(), section]));
30
+ const sectionsByPath = new Map();
31
+ const documentNodeBySection = new Map();
32
+ const nodes = new Map();
33
+ const edges = new Map();
34
+ const invalidWikiTargets = new Set();
35
+ for (const [path, errors] of diagnostics) {
36
+ for (const error of errors) {
37
+ invalidWikiTargets.add(`${path}\0${error.line}\0${error.target}`);
38
+ }
39
+ }
40
+ const addNode = (node) => {
41
+ if (!nodes.has(node.id))
42
+ nodes.set(node.id, node);
43
+ return node.id;
44
+ };
45
+ const addEdge = (from, to, kind) => {
46
+ if (from === to)
47
+ return;
48
+ const key = `${kind}\0${from}\0${to}`;
49
+ const existing = edges.get(key);
50
+ if (existing) {
51
+ existing.weight++;
52
+ return;
53
+ }
54
+ edges.set(key, {
55
+ id: `edge:${kind}:${from}->${to}`,
56
+ from,
57
+ to,
58
+ kind,
59
+ weight: 1,
60
+ });
61
+ };
62
+ for (const file of files) {
63
+ const flat = flattenSections(file.sections);
64
+ sectionsByPath.set(file.path.toLowerCase(), flat);
65
+ const root = file.sections[0];
66
+ const id = `document:${file.path}`;
67
+ for (const section of flat) {
68
+ documentNodeBySection.set(section.id.toLowerCase(), id);
69
+ }
70
+ const errorCount = diagnostics.get(file.path)?.length ?? 0;
71
+ addNode({
72
+ id,
73
+ kind: 'document',
74
+ label: root?.heading ?? nodeLabelFromPath(file.path),
75
+ url: documentUrl(file.path),
76
+ breadcrumbs: pathBreadcrumbs(file.path),
77
+ documentPath: file.path,
78
+ sectionId: root?.id,
79
+ inDegree: 0,
80
+ outDegree: 0,
81
+ ...(git.files.get(file.path)?.status
82
+ ? { gitStatus: git.files.get(file.path)?.status }
83
+ : {}),
84
+ ...(errorCount > 0 ? { errorCount } : {}),
85
+ });
86
+ }
87
+ const documentNodeForSection = (section) => documentNodeBySection.get(section.id.toLowerCase()) ?? null;
88
+ for (const file of files) {
89
+ const fileSections = flattenSections(file.sections).sort((left, right) => left.startLine - right.startLine);
90
+ const containingSection = (line) => fileSections.filter((section) => section.startLine <= line).at(-1) ??
91
+ file.sections[0];
92
+ for (const ref of file.wikiRefs) {
93
+ const sourceSection = sectionById.get(ref.fromSection.toLowerCase());
94
+ const from = sourceSection ? documentNodeForSection(sourceSection) : null;
95
+ if (!from)
96
+ continue;
97
+ const source = viewSourceTarget(ref.target);
98
+ if (source) {
99
+ if (invalidWikiTargets.has(`${file.path}\0${ref.line}\0${ref.target}`)) {
100
+ continue;
101
+ }
102
+ const sourceId = addNode({
103
+ id: `source:${source.path}${source.symbol ? `#${source.symbol}` : ''}`,
104
+ kind: 'source',
105
+ label: source.symbol || posix.basename(source.path),
106
+ url: sourceUrl(source.path, source.symbol),
107
+ breadcrumbs: [
108
+ ...source.path.split('/'),
109
+ ...(source.symbol ? [source.symbol] : []),
110
+ ],
111
+ sourcePath: source.path,
112
+ symbol: source.symbol || undefined,
113
+ inDegree: 0,
114
+ outDegree: 0,
115
+ });
116
+ addEdge(from, sourceId, 'source');
117
+ continue;
118
+ }
119
+ const resolved = resolveRef(ref.target, sectionIds, fileIndex, slugIndex);
120
+ if (resolved.ambiguous)
121
+ continue;
122
+ const target = sectionById.get(resolved.resolved.toLowerCase());
123
+ const to = target ? documentNodeForSection(target) : null;
124
+ if (to)
125
+ addEdge(from, to, 'wiki');
126
+ }
127
+ for (const link of file.markdownLinks) {
128
+ if (link.kind !== 'link')
129
+ continue;
130
+ const target = linkedSection(link.url, file.path, sectionsByPath);
131
+ const source = containingSection(link.line);
132
+ const from = source ? documentNodeForSection(source) : null;
133
+ const to = target ? documentNodeForSection(target) : null;
134
+ if (from && to)
135
+ addEdge(from, to, 'markdown');
136
+ }
137
+ }
138
+ for (const file of [...codeFiles].sort((left, right) => left.path.localeCompare(right.path))) {
139
+ for (const ref of [...file.refs].sort((left, right) => left.line - right.line)) {
140
+ const resolved = resolveRef(ref.target, sectionIds, fileIndex, slugIndex);
141
+ if (resolved.ambiguous)
142
+ continue;
143
+ const target = sectionById.get(resolved.resolved.toLowerCase());
144
+ const to = target ? documentNodeForSection(target) : null;
145
+ if (!to)
146
+ continue;
147
+ const snippet = file.lines[ref.line - 1]?.trim() ?? '';
148
+ const from = addNode({
149
+ id: `code-ref:${file.path}:${ref.line}`,
150
+ kind: 'code-reference',
151
+ label: `${posix.basename(file.path)}:${ref.line}`,
152
+ url: sourceUrl(file.path, '', ref.line),
153
+ breadcrumbs: [...file.path.split('/'), `line ${ref.line}`],
154
+ sourcePath: file.path,
155
+ line: ref.line,
156
+ snippet,
157
+ inDegree: 0,
158
+ outDegree: 0,
159
+ });
160
+ addEdge(from, to, 'code-mention');
161
+ }
162
+ }
163
+ for (const edge of edges.values()) {
164
+ const source = nodes.get(edge.from);
165
+ const target = nodes.get(edge.to);
166
+ if (source)
167
+ source.outDegree += edge.weight;
168
+ if (target)
169
+ target.inDegree += edge.weight;
170
+ }
171
+ return {
172
+ generation,
173
+ nodes: [...nodes.values()].sort((left, right) => left.id.localeCompare(right.id)),
174
+ edges: [...edges.values()].sort((left, right) => left.id.localeCompare(right.id)),
175
+ };
176
+ }
@@ -2,7 +2,11 @@ import type { Root } from 'mdast';
2
2
  export type WikiLinkContext = {
3
3
  line: number;
4
4
  };
5
- export type WikiLinkResolver = (target: string, context: WikiLinkContext) => string | null | Promise<string | null>;
5
+ export type WikiLinkResolution = {
6
+ href: string;
7
+ referenceCount: number;
8
+ };
9
+ export type WikiLinkResolver = (target: string, context: WikiLinkContext) => WikiLinkResolution | null | Promise<WikiLinkResolution | null>;
6
10
  export type MarkdownRenderOptions = {
7
11
  activeMarkdownLink?: string;
8
12
  activeWikiLink?: string;
@@ -10,6 +10,7 @@ const CODE_LINK_CLASSES = [
10
10
  'wiki-link-code',
11
11
  'wiki-link-active',
12
12
  'code-link-language',
13
+ 'code-link-leading',
13
14
  'code-language-ts',
14
15
  'code-language-js',
15
16
  'code-language-py',
@@ -18,11 +19,17 @@ const CODE_LINK_CLASSES = [
18
19
  'code-language-c',
19
20
  ];
20
21
  const ERROR_CLASS = 'markdown-error';
22
+ const EXTERNAL_LINK_CLASS = 'external-link';
23
+ const EXTERNAL_LINK_ICON_CLASS = 'external-link-icon';
21
24
  const GIT_CLASSES = ['git-added', 'git-removed'];
22
25
  function classAttributes(tag) {
26
+ const attributes = defaultSchema.attributes?.[tag] ?? [];
27
+ const allowedClasses = attributes.flatMap((attribute) => Array.isArray(attribute) && attribute[0] === 'className'
28
+ ? attribute.slice(1)
29
+ : []);
23
30
  return [
24
- ...(defaultSchema.attributes?.[tag] ?? []),
25
- ['className', ERROR_CLASS, ...GIT_CLASSES],
31
+ ...attributes.filter((attribute) => !(Array.isArray(attribute) && attribute[0] === 'className')),
32
+ ['className', ...allowedClasses, ERROR_CLASS, ...GIT_CLASSES],
26
33
  ];
27
34
  }
28
35
  const sanitizeSchema = {
@@ -38,6 +45,7 @@ const sanitizeSchema = {
38
45
  'wiki-link-segmented',
39
46
  'wiki-link-code',
40
47
  'wiki-link-active',
48
+ EXTERNAL_LINK_CLASS,
41
49
  ERROR_CLASS,
42
50
  ...GIT_CLASSES,
43
51
  ],
@@ -55,20 +63,25 @@ const sanitizeSchema = {
55
63
  img: classAttributes('img'),
56
64
  ins: classAttributes('ins'),
57
65
  li: classAttributes('li'),
66
+ ol: classAttributes('ol'),
58
67
  p: classAttributes('p'),
59
68
  pre: classAttributes('pre'),
60
69
  span: [
61
70
  ...(defaultSchema.attributes?.span ?? []),
62
71
  'ariaHidden',
72
+ 'ariaLabel',
63
73
  [
64
74
  'className',
65
75
  'wiki-link-context',
66
76
  'wiki-link-leaf',
77
+ 'wiki-link-ref-count',
78
+ EXTERNAL_LINK_ICON_CLASS,
67
79
  ...CODE_LINK_CLASSES.slice(2),
68
80
  ERROR_CLASS,
69
81
  ...GIT_CLASSES,
70
82
  ],
71
83
  ],
84
+ ul: classAttributes('ul'),
72
85
  },
73
86
  };
74
87
  const htmlProcessor = unified()
@@ -155,6 +168,61 @@ function languageIcon(language) {
155
168
  children: [{ type: 'text', value: language.label }],
156
169
  };
157
170
  }
171
+ function codeLinkContent(language, children) {
172
+ const [first, ...rest] = children;
173
+ if (!first)
174
+ return [languageIcon(language)];
175
+ let leading = first;
176
+ let remainder = null;
177
+ if (first.type === 'text') {
178
+ const breakAt = first.value.search(/\s/);
179
+ if (breakAt > 0) {
180
+ leading = { ...first, value: first.value.slice(0, breakAt) };
181
+ remainder = { ...first, value: first.value.slice(breakAt) };
182
+ }
183
+ }
184
+ return [
185
+ {
186
+ type: 'emphasis',
187
+ data: {
188
+ hName: 'span',
189
+ hProperties: { className: ['code-link-leading'] },
190
+ },
191
+ children: [languageIcon(language), leading],
192
+ },
193
+ ...(remainder ? [remainder] : []),
194
+ ...rest,
195
+ ];
196
+ }
197
+ function externalLinkIcon() {
198
+ return {
199
+ type: 'emphasis',
200
+ data: {
201
+ hName: 'span',
202
+ hProperties: {
203
+ ariaHidden: 'true',
204
+ className: [EXTERNAL_LINK_ICON_CLASS],
205
+ },
206
+ },
207
+ children: [],
208
+ };
209
+ }
210
+ function isExternalSiteUrl(url) {
211
+ return /^(?:https?:)?\/\//i.test(url);
212
+ }
213
+ function referenceCountBadge(count) {
214
+ return {
215
+ type: 'emphasis',
216
+ data: {
217
+ hName: 'span',
218
+ hProperties: {
219
+ className: ['wiki-link-ref-count'],
220
+ ariaLabel: `${count} ${count === 1 ? 'reference' : 'references'}`,
221
+ },
222
+ },
223
+ children: [{ type: 'text', value: String(count) }],
224
+ };
225
+ }
158
226
  function targetMatches(node, target) {
159
227
  if (node.type === 'wikiLink') {
160
228
  return node.value.toLowerCase() === target.toLowerCase();
@@ -229,24 +297,39 @@ export async function renderMarkdown(markdown, filePath, resolveWikiLink, option
229
297
  tree.children = tree.children.filter((node) => node.type !== 'yaml');
230
298
  if (options.errors)
231
299
  markMarkdownErrors(tree, options.errors);
232
- if (options.rewriteMarkdownLink || options.activeMarkdownLink) {
233
- visit(tree, 'link', (node) => {
234
- const authoredUrl = node.url;
235
- if (options.activeMarkdownLink &&
236
- authoredUrl === options.activeMarkdownLink) {
237
- node.data = {
238
- ...node.data,
239
- hProperties: {
240
- ...(node.data?.hProperties ?? {}),
241
- className: ['wiki-link-active'],
242
- },
243
- };
244
- }
245
- if (options.rewriteMarkdownLink) {
246
- node.url = options.rewriteMarkdownLink(authoredUrl);
247
- }
248
- });
249
- }
300
+ visit(tree, 'link', (node) => {
301
+ const authoredUrl = node.url;
302
+ if (options.activeMarkdownLink &&
303
+ authoredUrl === options.activeMarkdownLink) {
304
+ node.data = {
305
+ ...node.data,
306
+ hProperties: {
307
+ ...(node.data?.hProperties ?? {}),
308
+ className: ['wiki-link-active'],
309
+ },
310
+ };
311
+ }
312
+ if (options.rewriteMarkdownLink) {
313
+ node.url = options.rewriteMarkdownLink(authoredUrl);
314
+ }
315
+ if (!isExternalSiteUrl(node.url))
316
+ return;
317
+ const properties = node.data?.hProperties ?? {};
318
+ const currentClasses = properties.className;
319
+ const classes = Array.isArray(currentClasses)
320
+ ? currentClasses.map(String)
321
+ : currentClasses
322
+ ? [String(currentClasses)]
323
+ : [];
324
+ node.data = {
325
+ ...node.data,
326
+ hProperties: {
327
+ ...properties,
328
+ className: [...classes, EXTERNAL_LINK_CLASS],
329
+ },
330
+ };
331
+ node.children.push(externalLinkIcon());
332
+ });
250
333
  const firstHeading = tree.children.find((node) => node.type === 'heading');
251
334
  const title = firstHeading
252
335
  ? nodeText(firstHeading)
@@ -266,9 +349,10 @@ export async function renderMarkdown(markdown, filePath, resolveWikiLink, option
266
349
  visit(tree, 'wikiLink', (node, index, parent) => {
267
350
  if (index === undefined || !parent || !('children' in parent))
268
351
  return;
269
- const href = resolvedLinks.get(node);
352
+ const resolution = resolvedLinks.get(node);
270
353
  const markedProperties = node.data?.hProperties;
271
- if (href) {
354
+ if (resolution) {
355
+ const { href, referenceCount } = resolution;
272
356
  const content = wikiLinkContent(node);
273
357
  const language = href.startsWith('/code/')
274
358
  ? codeLanguage(node.value)
@@ -296,9 +380,12 @@ export async function renderMarkdown(markdown, filePath, resolveWikiLink, option
296
380
  },
297
381
  }
298
382
  : undefined,
299
- children: language
300
- ? [languageIcon(language), ...content.children]
301
- : content.children,
383
+ children: [
384
+ ...(language
385
+ ? codeLinkContent(language, content.children)
386
+ : content.children),
387
+ ...(referenceCount > 1 ? [referenceCountBadge(referenceCount)] : []),
388
+ ],
302
389
  };
303
390
  return;
304
391
  }