@vpxa/aikit 0.1.350 → 0.1.352

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 (36) hide show
  1. package/package.json +1 -1
  2. package/packages/blocks-core/dist/index.mjs +91 -58
  3. package/packages/cli/dist/index.js +1 -1
  4. package/packages/core/dist/index.d.ts +3 -0
  5. package/packages/core/dist/index.js +1 -1
  6. package/packages/present/dist/annotation-layer.js +48 -74
  7. package/packages/present/dist/index.html +154 -114
  8. package/packages/server/dist/bin.js +1 -1
  9. package/packages/server/dist/index.js +288 -109
  10. package/packages/server/dist/prelude-CXds3AXY.js +2 -0
  11. package/packages/server/dist/prelude-Cms2H0-F.js +1 -0
  12. package/packages/server/dist/sampling-BoH5wpOJ.js +1 -0
  13. package/packages/server/dist/sampling-SoUYZhFs.js +2 -0
  14. package/packages/server/dist/{server-BYZo2XjK.js → server-Crfl8sRN.js} +174 -169
  15. package/packages/server/dist/{server-BtRv0mbH.js → server-Znp0a9J2.js} +174 -169
  16. package/packages/server/dist/{server-http-CatdRS-N.js → server-http-BGF1k0j9.js} +1 -1
  17. package/packages/server/dist/{server-http-L_WQ9v_b.js → server-http-BSGdxVRV.js} +1 -1
  18. package/packages/server/dist/{server-stdio-avLmmdEi.js → server-stdio-B2N-eM5T.js} +1 -1
  19. package/packages/server/dist/{server-stdio-CZuGZR4e.js → server-stdio-CTgwgIGC.js} +1 -1
  20. package/packages/server/viewers/canvas.html +127 -94
  21. package/packages/server/viewers/code-review-viewer.html +352 -0
  22. package/packages/server/viewers/report-template.html +100 -67
  23. package/packages/server/viewers/tour-viewer.html +94 -61
  24. package/packages/store/dist/index.d.ts +3 -0
  25. package/packages/store/dist/index.js +8 -8
  26. package/packages/tools/dist/index.d.ts +36 -2
  27. package/packages/tools/dist/index.js +90 -90
  28. package/scaffold/dist/definitions/agents.mjs +1 -1
  29. package/scaffold/dist/definitions/bodies.mjs +48 -3
  30. package/scaffold/dist/definitions/skills/c4-architecture.mjs +24 -2
  31. package/scaffold/dist/definitions/skills/docs.mjs +170 -15
  32. package/scaffold/dist/definitions/skills/present.mjs +317 -13
  33. package/packages/server/dist/prelude-DpX0QnqF.js +0 -2
  34. package/packages/server/dist/prelude-pJPHXvnQ.js +0 -1
  35. package/packages/server/dist/sampling-9GcILoHr.js +0 -2
  36. package/packages/server/dist/sampling-DuXB6-rK.js +0 -1
@@ -0,0 +1,352 @@
1
+ <!doctype html>
2
+ <html lang="en" data-theme="dark">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>Code Review</title>
7
+ <script>
8
+ // Apply-before-paint: localStorage > prefers-color-scheme
9
+ (function(){
10
+ var s, d;
11
+ try { s = localStorage.getItem('aikit-theme'); } catch(_) {}
12
+ d = s ? s === 'dark' : window.matchMedia('(prefers-color-scheme: dark)').matches;
13
+ document.documentElement.setAttribute('data-theme', d ? 'dark' : 'light');
14
+ })();
15
+ </script>
16
+ <style>
17
+ /* ═══════════════════════════════════════════════
18
+ Design Tokens — warm semantic palette
19
+ ═══════════════════════════════════════════════ */
20
+ :root {
21
+ --serif: ui-serif, Georgia, "Times New Roman", serif;
22
+ --sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
23
+ --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
24
+ }
25
+ :root,[data-theme="dark"] {
26
+ --bg: #141413; --surface: #1F1F1D; --surface2: #2A2A28;
27
+ --ink: #FAF9F5; --body: #D1CFC5; --muted: #87867F; --dim: #57534E;
28
+ --line: #3D3D3A; --line-soft: #2A2A28;
29
+ --clay: #E48A6E; --clay-soft: rgba(228,138,110,0.14);
30
+ --olive: #9DB07C; --olive-soft: rgba(157,176,124,0.16);
31
+ --gold: #D4B36F; --rust: #f87171; --blue: #7FA3BC;
32
+ }
33
+ [data-theme="light"] {
34
+ --bg: #FAF9F5; --surface: #FFFFFF; --surface2: #F0EEE6;
35
+ --ink: #141413; --body: #3D3D3A; --muted: #87867F; --dim: #A8A29E;
36
+ --line: #D1CFC5; --line-soft: #E6E3DA;
37
+ --clay: #D97757; --clay-soft: rgba(217,119,87,0.10);
38
+ --olive: #788C5D; --olive-soft: rgba(120,140,93,0.12);
39
+ --gold: #C9A45C; --rust: #ef4444; --blue: #5B7E96;
40
+ }
41
+
42
+ /* ═══════════════════════════════════════════════
43
+ Base
44
+ ═══════════════════════════════════════════════ */
45
+ *{box-sizing:border-box;margin:0;padding:0}
46
+ html{scroll-behavior:smooth}
47
+ body{
48
+ font-family:var(--sans);background:var(--bg);color:var(--body);
49
+ -webkit-font-smoothing:antialiased;padding:2rem 1.5rem 4rem;
50
+ transition:background .2s,color .2s
51
+ }
52
+ .page{max-width:960px;margin:0 auto}
53
+
54
+ /* ── Header ── */
55
+ .pr-head{border:1.5px solid var(--line);border-radius:12px;padding:1.5rem 1.75rem;background:var(--surface);margin-bottom:2rem}
56
+ .repo-line{font-family:var(--mono);font-size:.75rem;color:var(--muted);margin-bottom:.5rem}
57
+ h1{font-family:var(--serif);font-weight:500;font-size:1.65rem;color:var(--ink);margin-bottom:1rem;letter-spacing:-.01em}
58
+ .meta-row{display:flex;align-items:center;flex-wrap:wrap;gap:1rem;font-size:.85rem}
59
+ .author{display:flex;align-items:center;gap:.6rem}
60
+ .avatar{width:32px;height:32px;border-radius:50%;background:var(--clay-soft);color:var(--clay);display:flex;align-items:center;justify-content:center;font-weight:600;font-size:.75rem;border:1.5px solid var(--clay)}
61
+ .author-name{font-weight:500;color:var(--ink)}
62
+ .author-sub{font-size:.75rem;color:var(--muted)}
63
+ .branch{font-family:var(--mono);font-size:.75rem;background:var(--surface2);border:1px solid var(--line);border-radius:6px;padding:.35rem .6rem}
64
+ .branch .arrow{color:var(--muted);margin:0 .35rem}
65
+ .stat{font-family:var(--mono);font-size:.8rem}
66
+ .stat .add{color:var(--olive);font-weight:600}
67
+ .stat .del{color:var(--rust);font-weight:600}
68
+ .stat .files{color:var(--muted);margin-left:.5rem}
69
+
70
+ /* ── Description ── */
71
+ .description{margin-bottom:1.5rem;font-size:.9rem;color:var(--body);line-height:1.6}
72
+
73
+ /* ── Risk map ── */
74
+ section{margin-bottom:2rem}
75
+ h2{font-family:var(--serif);font-weight:500;font-size:1.2rem;color:var(--ink);margin-bottom:1rem}
76
+ .risk-map{display:flex;flex-wrap:wrap;gap:.5rem}
77
+ .chip{
78
+ display:inline-flex;align-items:center;gap:.4rem;
79
+ padding:.4rem .65rem;border-radius:6px;
80
+ border:1.5px solid var(--line);font-family:var(--mono);font-size:.75rem;
81
+ color:var(--body);text-decoration:none;background:var(--surface);
82
+ transition:transform .12s ease;cursor:pointer
83
+ }
84
+ .chip:hover{transform:translateY(-1px)}
85
+ .chip .dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
86
+ .chip.safe{background:var(--olive-soft);border-color:var(--olive);color:var(--olive)}
87
+ .chip.safe .dot{background:var(--olive)}
88
+ .chip.medium{background:rgba(212,179,111,0.15);border-color:var(--gold);color:var(--gold)}
89
+ .chip.medium .dot{background:var(--ink)}
90
+ .chip.attention{background:var(--clay-soft);border-color:var(--clay);color:var(--clay)}
91
+ .chip.attention .dot{background:var(--clay)}
92
+
93
+ /* ── Files ── */
94
+ .file-card{border:1.5px solid var(--line);border-radius:12px;background:var(--surface);margin-bottom:1.25rem;overflow:hidden}
95
+ .file-head{
96
+ padding:.85rem 1.25rem;border-bottom:1.5px solid var(--line-soft);
97
+ display:flex;align-items:center;justify-content:space-between;gap:.75rem
98
+ }
99
+ .file-path{font-family:var(--mono);font-size:.8rem;color:var(--ink);word-break:break-all}
100
+ .file-delta{font-family:var(--mono);font-size:.7rem;color:var(--muted);flex-shrink:0}
101
+ .file-delta .add{color:var(--olive)}.file-delta .del{color:var(--rust)}
102
+ .risk-tag{font-size:.65rem;text-transform:uppercase;letter-spacing:.06em;padding:.15rem .5rem;border-radius:4px;font-weight:600}
103
+ .risk-tag.safe{background:var(--olive-soft);color:var(--olive)}
104
+ .risk-tag.medium{background:var(--clay-soft);color:var(--gold)}
105
+ .risk-tag.attention{background:var(--clay-soft);color:var(--clay)}
106
+
107
+ /* ── Diff grid ── */
108
+ .diff{background:var(--ink);font-family:var(--mono);font-size:.75rem;line-height:1.7;overflow-x:auto}
109
+ .diff-row{display:grid;grid-template-columns:3rem 1.25rem 1fr;align-items:baseline;padding:0 .75rem;white-space:pre;min-height:1.7em}
110
+ .diff-row .ln{text-align:right;padding-right:.75rem;color:var(--muted);user-select:none}
111
+ .diff-row .mark{text-align:center;color:var(--muted)}
112
+ .diff-row .code{color:#E8E6DC;white-space:pre-wrap;word-break:break-all}
113
+ .diff-row.ctx{background:transparent}
114
+ .diff-row.add{background:rgba(157,176,124,0.12)}
115
+ .diff-row.add .mark{color:var(--olive)}
116
+ .diff-row.del{background:rgba(248,113,113,0.10)}
117
+ .diff-row.del .mark{color:var(--rust)}
118
+ .diff-row.hunk{background:rgba(255,255,255,0.04);color:var(--muted);font-size:.7rem}
119
+ .diff-row.hunk .code{color:var(--dim)}
120
+
121
+ /* ── Review bubbles ── */
122
+ .comments{padding:1rem 1.25rem;display:flex;flex-direction:column;gap:.75rem;background:var(--surface2)}
123
+ .bubble{
124
+ position:relative;background:var(--surface);border:1.5px solid var(--line);
125
+ border-left-width:4px;border-radius:8px;padding:.6rem .8rem .6rem 1rem;max-width:680px
126
+ }
127
+ .bubble.blocking{border-left-color:var(--clay)}
128
+ .bubble.nit{border-left-color:var(--muted)}
129
+ .bubble::before{
130
+ content:"";position:absolute;left:-9px;top:14px;
131
+ width:12px;height:12px;background:var(--surface);
132
+ border-left:1.5px solid var(--line);border-bottom:1.5px solid var(--line);
133
+ transform:rotate(45deg)
134
+ }
135
+ .bubble.blocking::before{border-left-color:var(--clay);border-bottom-color:var(--clay)}
136
+ .bubble .anchor{font-family:var(--mono);font-size:.7rem;color:var(--muted);margin-bottom:.2rem}
137
+ .bubble .label{display:inline-block;font-size:.65rem;text-transform:uppercase;letter-spacing:.08em;font-weight:700;margin-right:.4rem}
138
+ .bubble.blocking .label{color:var(--clay)}
139
+ .bubble.nit .label{color:var(--muted)}
140
+ .bubble p{font-size:.8rem;color:var(--body);line-height:1.5}
141
+ .bubble code{font-family:var(--mono);font-size:.75rem;background:var(--surface2);padding:1px 4px;border-radius:3px}
142
+
143
+ /* ── Collapsible details ── */
144
+ details.file-card{scroll-margin-top:1rem}
145
+ details.file-card summary{
146
+ list-style:none;cursor:pointer;padding:.85rem 1.25rem;
147
+ display:flex;align-items:center;justify-content:space-between;gap:.75rem;
148
+ -webkit-user-select:none;user-select:none
149
+ }
150
+ details.file-card summary::-webkit-details-marker{display:none}
151
+ details.file-card summary::after{content:"+";font-family:var(--mono);color:var(--muted);font-size:1.1rem}
152
+ details.file-card[open] summary::after{content:"−"}
153
+ details.file-card .body{padding:0 1.25rem 1rem;font-size:.8rem}
154
+
155
+ /* ── Conclusion ── */
156
+ .conclusion{border:1.5px solid var(--line);border-radius:12px;background:var(--surface);padding:1.25rem 1.5rem}
157
+ .conclusion h2{border-left:4px solid var(--clay);padding-left:.75rem}
158
+ .conclusion p{font-size:.85rem;line-height:1.55;color:var(--body);margin-bottom:.5rem}
159
+ .conclusion p:last-child{margin-bottom:0}
160
+ .conclusion code{font-family:var(--mono);font-size:.8rem;background:var(--surface2);padding:1px 4px;border-radius:3px}
161
+
162
+ /* ── Theme toggle button ── */
163
+ #themeToggle{
164
+ position:fixed;top:.75rem;right:.75rem;z-index:100;
165
+ font-family:var(--mono);font-size:.7rem;text-transform:uppercase;letter-spacing:.08em;
166
+ padding:.35rem .65rem;border:1px solid var(--line);border-radius:6px;
167
+ background:var(--toolbar-bg,var(--surface));color:var(--muted);cursor:pointer;
168
+ backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
169
+ transition:all .15s
170
+ }
171
+ #themeToggle:hover{color:var(--ink);border-color:var(--muted)}
172
+ :root{--toolbar-bg:rgba(31,31,29,0.9)}
173
+ [data-theme="light"]{--toolbar-bg:rgba(255,255,255,0.92)}
174
+
175
+ /* ── Loading state ── */
176
+ .loading{text-align:center;padding:4rem 2rem;color:var(--muted)}
177
+ .loading .spinner{width:32px;height:32px;border:3px solid var(--line);border-top-color:var(--clay);border-radius:50%;animation:spin .8s linear infinite;margin:0 auto 1rem}
178
+ @keyframes spin{to{transform:rotate(360deg)}}
179
+
180
+ /* ── Empty state ── */
181
+ .empty{text-align:center;padding:4rem 2rem;color:var(--muted)}
182
+ .empty h2{font-family:var(--serif);color:var(--muted);margin-bottom:.5rem}
183
+
184
+ /* ── Responsive ── */
185
+ @media(max-width:760px){
186
+ body{padding:1rem .75rem 3rem}
187
+ .pr-head{padding:1rem 1.25rem}
188
+ h1{font-size:1.3rem}
189
+ .diff-row{grid-template-columns:2.25rem 1rem 1fr;font-size:.7rem}
190
+ #themeToggle{top:.4rem;right:.4rem;padding:.25rem .5rem;font-size:.65rem}
191
+ }
192
+ @media(max-width:480px){
193
+ .meta-row{flex-direction:column;align-items:flex-start;gap:.5rem}
194
+ .file-head{flex-direction:column;align-items:flex-start;gap:.35rem}
195
+ .diff-row{grid-template-columns:1.75rem .85rem 1fr;font-size:.65rem}
196
+ }
197
+ </style>
198
+ </head>
199
+ <body>
200
+ <button id="themeToggle" onclick="var d=document.documentElement;var t=d.getAttribute('data-theme')==='dark'?'light':'dark';d.setAttribute('data-theme',t);try{localStorage.setItem('aikit-theme',t)}catch(_){}">Theme</button>
201
+ <div class="page" id="app">
202
+ <div class="loading" id="loading">
203
+ <div class="spinner"></div>
204
+ <p>Loading review...</p>
205
+ </div>
206
+ </div>
207
+
208
+ <script type="application/json" id="review-data">
209
+ {}
210
+ </script>
211
+
212
+ <script>
213
+ (function(){
214
+ var dataScript = document.getElementById('review-data');
215
+ var app = document.getElementById('app');
216
+ var loading = document.getElementById('loading');
217
+
218
+ try {
219
+ var data = JSON.parse(dataScript.textContent || '{}');
220
+ } catch(e) {
221
+ app.innerHTML = '<div class="empty"><h2>Invalid review data</h2><p>Could not parse the review payload.</p></div>';
222
+ return;
223
+ }
224
+
225
+ if (!data || Object.keys(data).length === 0) {
226
+ app.innerHTML = '<div class="empty"><h2>No review data</h2><p>Supply review data via the <code>review-data</code> script tag.</p></div>';
227
+ return;
228
+ }
229
+
230
+ // ── Render ──
231
+ var html = '';
232
+
233
+ // PR Header
234
+ var prTitle = esc(data.title || 'Code Review');
235
+ var prRepo = esc(data.repo || '');
236
+ var prAuthorName = esc(data.author || '');
237
+ var prAuthorInitials = (data.author || '??').split(' ').map(function(s){return s[0]}).join('').slice(0,2).toUpperCase();
238
+ var prBranch = esc(data.branch || '');
239
+ var prTargetBranch = esc(data.targetBranch || 'main');
240
+ var prAdds = data.additions || 0;
241
+ var prDeletes = data.deletions || 0;
242
+ var prFiles = data.files ? data.files.length : 0;
243
+
244
+ html += '<div class="pr-head">';
245
+ if (prRepo) html += '<div class="repo-line">' + prRepo + '</div>';
246
+ html += '<h1>' + prTitle + '</h1>';
247
+ html += '<div class="meta-row">';
248
+ if (data.author) {
249
+ html += '<div class="author"><div class="avatar">' + prAuthorInitials + '</div><div><div class="author-name">' + prAuthorName + '</div><div class="author-sub">opened ' + esc(data.date || 'recently') + '</div></div></div>';
250
+ }
251
+ if (prBranch) html += '<div class="branch">' + prBranch + ' <span class="arrow">→</span> ' + prTargetBranch + '</div>';
252
+ html += '<div class="stat"><span class="add">+' + prAdds + '</span> / <span class="del">−' + prDeletes + '</span><span class="files">' + prFiles + ' file' + (prFiles !== 1 ? 's' : '') + ' changed</span></div>';
253
+ html += '</div></div>';
254
+
255
+ // Description
256
+ if (data.description) {
257
+ html += '<div class="description">' + esc(data.description) + '</div>';
258
+ }
259
+
260
+ // Risk map
261
+ if (data.files && data.files.length > 0) {
262
+ var hasRisks = data.files.some(function(f){ return f.risk; });
263
+ if (hasRisks) {
264
+ html += '<section data-block-id="risk-map"><h2>Risk map</h2><div class="risk-map">';
265
+ data.files.forEach(function(f, i){
266
+ var risk = f.risk || 'safe';
267
+ var label = esc(f.path.split('/').pop());
268
+ html += '<a class="chip ' + risk + '" href="#file-' + i + '"><span class="dot"></span>' + label + '</a>';
269
+ });
270
+ html += '</div></section>';
271
+ }
272
+ }
273
+
274
+ // Files
275
+ if (data.files && data.files.length > 0) {
276
+ html += '<section data-block-id="files"><h2>Files</h2>';
277
+ data.files.forEach(function(file, fi){
278
+ var fRisk = file.risk || 'safe';
279
+ var fPath = esc(file.path);
280
+ var adds = file.additions || 0;
281
+ var dels = file.deletions || 0;
282
+ var collapsed = file.collapsed !== false;
283
+
284
+ if (collapsed) {
285
+ html += '<details class="file-card" id="file-' + fi + '">';
286
+ html += '<summary><span class="file-path">' + fPath + '</span><span style="display:flex;align-items:center;gap:.5rem">';
287
+ html += '<span class="risk-tag ' + fRisk + '">' + fRisk + '</span>';
288
+ html += '<span class="file-delta"><span class="add">+' + adds + '</span> <span class="del">−' + dels + '</span></span>';
289
+ html += '</span></summary><div class="body">';
290
+ } else {
291
+ html += '<div class="file-card" id="file-' + fi + '">';
292
+ html += '<div class="file-head"><span class="file-path">' + fPath + '</span>';
293
+ html += '<span style="display:flex;align-items:center;gap:.5rem">';
294
+ html += '<span class="risk-tag ' + fRisk + '">' + fRisk + '</span>';
295
+ html += '<span class="file-delta"><span class="add">+' + adds + '</span> <span class="del">−' + dels + '</span></span>';
296
+ html += '</span></div>';
297
+ }
298
+
299
+ // Diff
300
+ if (file.diff && file.diff.length > 0) {
301
+ html += '<div class="diff" data-block-id="diff-' + fi + '">';
302
+ file.diff.forEach(function(row){
303
+ var type = row.t || 'ctx';
304
+ var ln = row.n || '';
305
+ var mark = type === 'add' ? '+' : type === 'del' ? '−' : ' ';
306
+ var code = esc(row.c || '');
307
+ html += '<div class="diff-row ' + type + '"><span class="ln">' + ln + '</span><span class="mark">' + mark + '</span><span class="code">' + code + '</span></div>';
308
+ });
309
+ html += '</div>';
310
+ }
311
+
312
+ // Review comments
313
+ if (file.comments && file.comments.length > 0) {
314
+ html += '<div class="comments" data-block-id="comments-' + fi + '">';
315
+ file.comments.forEach(function(comment){
316
+ var kind = comment.blocking ? 'blocking' : 'nit';
317
+ html += '<div class="bubble ' + kind + '">';
318
+ if (comment.line) html += '<div class="anchor">line ' + comment.line + '</div>';
319
+ html += '<p><span class="label">' + (comment.blocking ? 'Blocking' : 'Nit') + '</span>' + esc(comment.text || '') + '</p>';
320
+ html += '</div>';
321
+ });
322
+ html += '</div>';
323
+ }
324
+
325
+ if (collapsed) {
326
+ html += '</div></details>';
327
+ } else {
328
+ html += '</div>';
329
+ }
330
+ });
331
+ html += '</section>';
332
+ }
333
+
334
+ // Conclusion / summary
335
+ if (data.summary || data.conclusion) {
336
+ html += '<div class="conclusion" data-block-id="conclusion"><h2>' + esc(data.summaryTitle || 'Summary') + '</h2>';
337
+ (data.conclusion || []).forEach(function(p){
338
+ html += '<p>' + esc(p) + '</p>';
339
+ });
340
+ html += '</div>';
341
+ }
342
+
343
+ app.innerHTML = html;
344
+
345
+ function esc(s){
346
+ if (typeof s !== 'string') return String(s || '');
347
+ return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,'&#39;');
348
+ }
349
+ })();
350
+ </script>
351
+ </body>
352
+ </html>