@webmcp-auto-ui/agent 2.5.27 → 2.5.28
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.
- package/package.json +10 -2
- package/src/autoui-server.ts +63 -75
- package/src/index.ts +7 -2
- package/src/loop.ts +48 -21
- package/src/providers/factory.ts +15 -1
- package/src/providers/hawk-models.ts +22 -0
- package/src/providers/hawk.ts +181 -0
- package/src/providers/transformers.worker.ts +5 -32
- package/src/recipes/_generated.ts +81 -17
- package/src/recipes/notebook-playbook.md +81 -17
- package/src/server/hawkProxy.ts +54 -0
- package/src/server/index.ts +2 -0
- package/src/util/opfs-cache.ts +101 -2
- package/src/util/storage-inventory.ts +195 -0
- package/src/notebook-widgets/compact.ts +0 -312
- package/src/notebook-widgets/document.ts +0 -372
- package/src/notebook-widgets/editorial.ts +0 -348
- package/src/notebook-widgets/recipes/compact.md +0 -104
- package/src/notebook-widgets/recipes/document.md +0 -100
- package/src/notebook-widgets/recipes/editorial.md +0 -104
- package/src/notebook-widgets/recipes/workspace.md +0 -94
- package/src/notebook-widgets/shared.ts +0 -1064
- package/src/notebook-widgets/workspace.ts +0 -328
|
@@ -1,328 +0,0 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
|
-
// ---------------------------------------------------------------------------
|
|
3
|
-
// notebook-workspace — dense analyst workspace (hex-like)
|
|
4
|
-
// Header bar + sidebar (sources + cells nav) + main cells area.
|
|
5
|
-
// ---------------------------------------------------------------------------
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
createState, injectStyles, mountRunControls, mountHistoryPanel,
|
|
9
|
-
setupDnD, deleteCellWithConfirm, restoreCellFromSnapshot, addCell,
|
|
10
|
-
autosize, openShareModal, registerHistoryObserver,
|
|
11
|
-
buildServersButton,
|
|
12
|
-
type NotebookState, type NotebookCell,
|
|
13
|
-
} from './shared.js';
|
|
14
|
-
|
|
15
|
-
export async function render(container: HTMLElement, data: Record<string, unknown>): Promise<() => void> {
|
|
16
|
-
injectStyles();
|
|
17
|
-
injectLayoutStyles();
|
|
18
|
-
|
|
19
|
-
const state: NotebookState = createState({
|
|
20
|
-
id: data.id as string,
|
|
21
|
-
title: data.title as string ?? 'Untitled notebook',
|
|
22
|
-
mode: (data.mode as any) ?? 'edit',
|
|
23
|
-
cells: data.cells as any,
|
|
24
|
-
});
|
|
25
|
-
let activeCellId: string | null = state.cells.find((c) => c.type !== 'md')?.id ?? state.cells[0]?.id ?? null;
|
|
26
|
-
|
|
27
|
-
container.classList.add('nb-root');
|
|
28
|
-
container.classList.toggle('nb-view-mode', state.mode === 'view');
|
|
29
|
-
|
|
30
|
-
container.innerHTML = `
|
|
31
|
-
<div class="nbw-shell">
|
|
32
|
-
<div class="nbw-header">
|
|
33
|
-
<div class="nbw-logo"></div>
|
|
34
|
-
<input class="nbw-title-edit nb-title-edit" value="${escapeAttr(state.title)}">
|
|
35
|
-
<span class="nbw-tag">draft</span>
|
|
36
|
-
<div class="nbw-ctx">
|
|
37
|
-
<span class="nbw-source">no source connected</span>
|
|
38
|
-
<div class="nb-mode-switch">
|
|
39
|
-
<button class="nb-mode-edit nb-on">edit</button>
|
|
40
|
-
<button class="nb-mode-view">view</button>
|
|
41
|
-
</div>
|
|
42
|
-
<button class="nb-btn nbw-history-btn">⟲ history</button>
|
|
43
|
-
<span class="nbw-servers-slot"></span>
|
|
44
|
-
<button class="nb-btn">run all</button>
|
|
45
|
-
<button class="nb-btn nbw-share-btn">share</button>
|
|
46
|
-
<button class="nb-btn nb-btn-primary">publish</button>
|
|
47
|
-
</div>
|
|
48
|
-
</div>
|
|
49
|
-
<div class="nb-history-panel nbw-history-panel"></div>
|
|
50
|
-
<div class="nbw-body">
|
|
51
|
-
<aside class="nbw-sidebar">
|
|
52
|
-
<div class="nbw-section">sources</div>
|
|
53
|
-
<div class="nbw-item">◉ no source</div>
|
|
54
|
-
<div class="nbw-item nbw-indent nbw-dim">connect via mcp…</div>
|
|
55
|
-
<div class="nbw-section">cells</div>
|
|
56
|
-
<div class="nbw-cells-nav"></div>
|
|
57
|
-
<div class="nbw-add">
|
|
58
|
-
<button class="nb-btn nb-add-cell" data-add="md">+ md</button>
|
|
59
|
-
<button class="nb-btn nb-add-cell" data-add="sql">+ sql</button>
|
|
60
|
-
<button class="nb-btn nb-add-cell" data-add="js">+ js</button>
|
|
61
|
-
</div>
|
|
62
|
-
</aside>
|
|
63
|
-
<div class="nbw-cells"></div>
|
|
64
|
-
</div>
|
|
65
|
-
</div>`;
|
|
66
|
-
|
|
67
|
-
const shell = container.querySelector('.nbw-shell') as HTMLElement;
|
|
68
|
-
const cellsEl = shell.querySelector('.nbw-cells') as HTMLElement;
|
|
69
|
-
const navEl = shell.querySelector('.nbw-cells-nav') as HTMLElement;
|
|
70
|
-
const historyPanel = shell.querySelector('.nbw-history-panel') as HTMLElement;
|
|
71
|
-
|
|
72
|
-
function renderCells() {
|
|
73
|
-
cellsEl.innerHTML = '';
|
|
74
|
-
navEl.innerHTML = '';
|
|
75
|
-
state.cells.forEach((cell, idx) => {
|
|
76
|
-
const navItem = document.createElement('div');
|
|
77
|
-
navItem.className = 'nbw-item' + (cell.id === activeCellId ? ' nbw-active' : '');
|
|
78
|
-
navItem.textContent = `${idx + 1} · ${cell.name || cell.type}`;
|
|
79
|
-
navItem.addEventListener('click', () => { activeCellId = cell.id; rerender(); });
|
|
80
|
-
navEl.appendChild(navItem);
|
|
81
|
-
|
|
82
|
-
cellsEl.appendChild(renderCell(cell, idx, state, rerender));
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function rerender() {
|
|
87
|
-
mountHistoryPanel(historyPanel, state, (snap) => { restoreCellFromSnapshot(state, snap); rerender(); });
|
|
88
|
-
renderCells();
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
shell.querySelectorAll<HTMLElement>('[data-add]').forEach((btn) => {
|
|
92
|
-
btn.addEventListener('click', () => {
|
|
93
|
-
const type = btn.dataset.add as any;
|
|
94
|
-
const name = type === 'md' ? 'note' : type === 'sql' ? 'query_' + (state.cells.length + 1) : 'cell_' + (state.cells.length + 1);
|
|
95
|
-
const cell = addCell(state, type, { name });
|
|
96
|
-
activeCellId = cell.id;
|
|
97
|
-
rerender();
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
(shell.querySelector('.nbw-history-btn') as HTMLElement).addEventListener('click', () => {
|
|
101
|
-
historyPanel.classList.toggle('nb-open');
|
|
102
|
-
});
|
|
103
|
-
(shell.querySelector('.nbw-share-btn') as HTMLElement).addEventListener('click', () => {
|
|
104
|
-
openShareModal(state, (fmt) => console.log('[notebook-workspace] share as', fmt, state));
|
|
105
|
-
});
|
|
106
|
-
(shell.querySelector('.nbw-title-edit') as HTMLInputElement).addEventListener('input', (e) => {
|
|
107
|
-
state.title = (e.target as HTMLInputElement).value;
|
|
108
|
-
});
|
|
109
|
-
const editBtn = shell.querySelector('.nb-mode-edit') as HTMLElement;
|
|
110
|
-
const viewBtn = shell.querySelector('.nb-mode-view') as HTMLElement;
|
|
111
|
-
editBtn.addEventListener('click', () => {
|
|
112
|
-
state.mode = 'edit';
|
|
113
|
-
container.classList.remove('nb-view-mode');
|
|
114
|
-
editBtn.classList.add('nb-on'); viewBtn.classList.remove('nb-on');
|
|
115
|
-
});
|
|
116
|
-
viewBtn.addEventListener('click', () => {
|
|
117
|
-
state.mode = 'view';
|
|
118
|
-
container.classList.add('nb-view-mode');
|
|
119
|
-
viewBtn.classList.add('nb-on'); editBtn.classList.remove('nb-on');
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
buildServersButton(state, shell.querySelector('.nbw-servers-slot') as HTMLElement, data, rerender);
|
|
123
|
-
|
|
124
|
-
setupDnD(cellsEl, state, rerender);
|
|
125
|
-
const unsubHistory = registerHistoryObserver(() => mountHistoryPanel(historyPanel, state, (snap) => { restoreCellFromSnapshot(state, snap); rerender(); }));
|
|
126
|
-
|
|
127
|
-
rerender();
|
|
128
|
-
return () => { unsubHistory(); };
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
function renderCell(cell: NotebookCell, idx: number, state: NotebookState, rerender: () => void): HTMLElement {
|
|
132
|
-
const wrap = document.createElement('div');
|
|
133
|
-
wrap.className = 'nb-cell-wrapper nbw-cell';
|
|
134
|
-
wrap.dataset.id = cell.id;
|
|
135
|
-
|
|
136
|
-
const inner = document.createElement('div');
|
|
137
|
-
inner.className = 'nb-cell';
|
|
138
|
-
|
|
139
|
-
const head = document.createElement('div');
|
|
140
|
-
head.className = 'nbw-cell-head';
|
|
141
|
-
const isCode = cell.type !== 'md';
|
|
142
|
-
head.innerHTML = `
|
|
143
|
-
<span class="nb-drag-handle" draggable="true" title="drag">⋮⋮</span>
|
|
144
|
-
${isCode ? '<span class="nbw-run-controls"></span>' : ''}
|
|
145
|
-
<span class="nbw-type nbw-type-${cell.type}">${cell.type}</span>
|
|
146
|
-
<input class="nbw-cell-name-edit" value="${idx + 1} · ${escapeAttr(cell.name || '')}">
|
|
147
|
-
<div class="nbw-meta">
|
|
148
|
-
${isCode ? `<span class="nbw-meta-info">${cell.lastMs != null ? cell.lastMs + 'ms' : '—'} · 4 rows</span>` : ''}
|
|
149
|
-
<button class="nb-icon-btn nb-toggle-src">${cell.hideSource ? '▸ src' : '◂ src'}</button>
|
|
150
|
-
${isCode ? `<button class="nb-icon-btn nb-toggle-res">${cell.hideResult ? '▸ res' : '◂ res'}</button>` : ''}
|
|
151
|
-
<button class="nb-icon-btn nb-danger nbw-del">✕</button>
|
|
152
|
-
</div>`;
|
|
153
|
-
inner.appendChild(head);
|
|
154
|
-
|
|
155
|
-
if (isCode) {
|
|
156
|
-
mountRunControls(head.querySelector('.nbw-run-controls') as HTMLElement, cell, wrap, rerender);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const body = document.createElement('div');
|
|
160
|
-
body.className = 'nbw-cell-body' + (isCode ? ' nbw-code' : '') + (cell.hideSource ? ' nbw-hidden' : '');
|
|
161
|
-
const ta = document.createElement('textarea');
|
|
162
|
-
ta.className = isCode ? 'nb-code-edit' : 'nb-md-edit';
|
|
163
|
-
ta.value = cell.content;
|
|
164
|
-
ta.rows = 1;
|
|
165
|
-
ta.spellcheck = false;
|
|
166
|
-
ta.addEventListener('input', () => { cell.content = ta.value; autosize(ta); cell.status = 'stale'; });
|
|
167
|
-
body.appendChild(ta);
|
|
168
|
-
inner.appendChild(body);
|
|
169
|
-
setTimeout(() => autosize(ta), 0);
|
|
170
|
-
|
|
171
|
-
if (cell.type === 'sql' && !cell.hideResult) {
|
|
172
|
-
const resWrap = document.createElement('div');
|
|
173
|
-
resWrap.innerHTML = `
|
|
174
|
-
<table class="nbw-result-table">
|
|
175
|
-
<thead><tr><th>col_a</th><th>col_b</th><th>share</th></tr></thead>
|
|
176
|
-
<tbody>
|
|
177
|
-
<tr><td>row_1</td><td>42</td><td><div class="nbw-share-bar" style="width:100%"></div></td></tr>
|
|
178
|
-
<tr><td>row_2</td><td>29</td><td><div class="nbw-share-bar" style="width:69%"></div></td></tr>
|
|
179
|
-
<tr><td>row_3</td><td>22</td><td><div class="nbw-share-bar" style="width:52%"></div></td></tr>
|
|
180
|
-
<tr><td>row_4</td><td>9</td><td><div class="nbw-share-bar" style="width:22%"></div></td></tr>
|
|
181
|
-
</tbody>
|
|
182
|
-
</table>`;
|
|
183
|
-
inner.appendChild(resWrap);
|
|
184
|
-
} else if (cell.type === 'js' && !cell.hideResult) {
|
|
185
|
-
const chart = document.createElement('div');
|
|
186
|
-
chart.className = 'nbw-chart';
|
|
187
|
-
chart.innerHTML = `
|
|
188
|
-
<div class="nbw-bar" style="height:100%"></div>
|
|
189
|
-
<div class="nbw-bar" style="height:68%"></div>
|
|
190
|
-
<div class="nbw-bar" style="height:52%"></div>
|
|
191
|
-
<div class="nbw-bar" style="height:22%"></div>`;
|
|
192
|
-
inner.appendChild(chart);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
(head.querySelector('.nb-toggle-src') as HTMLElement).addEventListener('click', () => { cell.hideSource = !cell.hideSource; rerender(); });
|
|
196
|
-
const togRes = head.querySelector('.nb-toggle-res') as HTMLElement | null;
|
|
197
|
-
if (togRes) togRes.addEventListener('click', () => { cell.hideResult = !cell.hideResult; rerender(); });
|
|
198
|
-
(head.querySelector('.nbw-del') as HTMLElement).addEventListener('click', () =>
|
|
199
|
-
deleteCellWithConfirm(state, cell, (c) => `${c.type} cell "${c.name}"`, rerender)
|
|
200
|
-
);
|
|
201
|
-
(head.querySelector('.nbw-cell-name-edit') as HTMLInputElement).addEventListener('input', (e) => {
|
|
202
|
-
const v = (e.target as HTMLInputElement).value;
|
|
203
|
-
const m = v.match(/^\d+\s*·\s*(.+)$/);
|
|
204
|
-
cell.name = m ? m[1] : v;
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
wrap.appendChild(inner);
|
|
208
|
-
return wrap;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
function escapeAttr(s: string): string {
|
|
212
|
-
return (s ?? '').replace(/"/g, '"');
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
function injectLayoutStyles(): void {
|
|
216
|
-
if (document.getElementById('nbw-styles')) return;
|
|
217
|
-
const style = document.createElement('style');
|
|
218
|
-
style.id = 'nbw-styles';
|
|
219
|
-
style.textContent = `
|
|
220
|
-
.nbw-shell {
|
|
221
|
-
background: var(--color-surface); border: 1px solid var(--color-border);
|
|
222
|
-
border-radius: 12px; overflow: hidden;
|
|
223
|
-
}
|
|
224
|
-
.nbw-header {
|
|
225
|
-
display: flex; align-items: center; padding: 10px 14px; gap: 12px;
|
|
226
|
-
border-bottom: 1px solid var(--color-border); background: var(--color-surface2);
|
|
227
|
-
}
|
|
228
|
-
.nbw-logo { width: 14px; height: 14px; background: var(--color-accent); border-radius: 3px; }
|
|
229
|
-
.nbw-title-edit {
|
|
230
|
-
font-size: 13px; font-weight: 500; color: var(--color-text1);
|
|
231
|
-
background: transparent; border: none; outline: none;
|
|
232
|
-
font-family: var(--font-sans, 'Syne', sans-serif);
|
|
233
|
-
width: 260px; padding: 2px 4px; border-radius: 3px;
|
|
234
|
-
}
|
|
235
|
-
.nbw-title-edit:focus { background: var(--color-bg); }
|
|
236
|
-
.nbw-tag {
|
|
237
|
-
font-family: var(--font-mono, 'IBM Plex Mono', monospace);
|
|
238
|
-
font-size: 10px; color: var(--color-text2);
|
|
239
|
-
background: var(--color-bg); padding: 2px 7px; border-radius: 3px;
|
|
240
|
-
border: 1px solid var(--color-border);
|
|
241
|
-
}
|
|
242
|
-
.nbw-ctx {
|
|
243
|
-
font-family: var(--font-mono, 'IBM Plex Mono', monospace);
|
|
244
|
-
font-size: 11px; color: var(--color-text2);
|
|
245
|
-
margin-left: auto; display: flex; gap: 8px; align-items: center;
|
|
246
|
-
}
|
|
247
|
-
.nbw-history-panel { margin: 0 14px; }
|
|
248
|
-
.nbw-body { display: grid; grid-template-columns: 180px 1fr; min-height: 380px; }
|
|
249
|
-
.nbw-sidebar {
|
|
250
|
-
border-right: 1px solid var(--color-border);
|
|
251
|
-
background: var(--color-surface2); padding: 14px 12px; font-size: 12px;
|
|
252
|
-
}
|
|
253
|
-
.nbw-section {
|
|
254
|
-
color: var(--color-text2);
|
|
255
|
-
font-family: var(--font-mono, 'IBM Plex Mono', monospace);
|
|
256
|
-
font-size: 10px; letter-spacing: 0.1em;
|
|
257
|
-
margin: 0 0 8px; text-transform: uppercase;
|
|
258
|
-
}
|
|
259
|
-
.nbw-section:not(:first-child) { margin-top: 16px; }
|
|
260
|
-
.nbw-item {
|
|
261
|
-
padding: 4px 6px; color: var(--color-text2);
|
|
262
|
-
border-radius: 4px; cursor: pointer;
|
|
263
|
-
display: flex; align-items: center; gap: 6px;
|
|
264
|
-
}
|
|
265
|
-
.nbw-item:hover { background: var(--color-surface); color: var(--color-text1); }
|
|
266
|
-
.nbw-item.nbw-indent { padding-left: 18px; }
|
|
267
|
-
.nbw-item.nbw-dim { opacity: 0.5; }
|
|
268
|
-
.nbw-item.nbw-active {
|
|
269
|
-
background: var(--color-surface); color: var(--color-text1);
|
|
270
|
-
border-left: 2px solid var(--color-accent); border-radius: 0 4px 4px 0;
|
|
271
|
-
}
|
|
272
|
-
.nbw-add { margin-top: 10px; display: flex; gap: 4px; flex-wrap: wrap; }
|
|
273
|
-
.nbw-add .nb-btn { flex: 1; font-size: 10px; padding: 3px 4px; }
|
|
274
|
-
|
|
275
|
-
.nbw-cells { display: flex; flex-direction: column; }
|
|
276
|
-
.nbw-cell .nb-cell { border-bottom: 1px solid var(--color-border); position: relative; }
|
|
277
|
-
.nbw-cell:last-child .nb-cell { border-bottom: none; }
|
|
278
|
-
.nbw-cell-head {
|
|
279
|
-
padding: 8px 16px;
|
|
280
|
-
display: flex; align-items: center; gap: 8px;
|
|
281
|
-
background: var(--color-surface2);
|
|
282
|
-
font-family: var(--font-mono, 'IBM Plex Mono', monospace);
|
|
283
|
-
font-size: 10px; color: var(--color-text2);
|
|
284
|
-
letter-spacing: 0.06em;
|
|
285
|
-
}
|
|
286
|
-
.nbw-type {
|
|
287
|
-
padding: 1px 7px; border-radius: 3px; font-weight: 500;
|
|
288
|
-
text-transform: uppercase; letter-spacing: 0.08em; font-size: 9.5px;
|
|
289
|
-
}
|
|
290
|
-
.nbw-type-md { background: rgba(160,160,184,0.15); color: var(--color-text2); }
|
|
291
|
-
.nbw-type-sql { background: rgba(124,109,250,0.18); color: var(--color-accent); }
|
|
292
|
-
.nbw-type-js { background: rgba(62,207,178,0.15); color: var(--color-teal); }
|
|
293
|
-
.nbw-cell-name-edit {
|
|
294
|
-
background: transparent; border: none; outline: none;
|
|
295
|
-
color: var(--color-text1);
|
|
296
|
-
font-family: var(--font-mono, 'IBM Plex Mono', monospace);
|
|
297
|
-
font-size: 10px; width: 140px;
|
|
298
|
-
}
|
|
299
|
-
.nbw-meta { margin-left: auto; display: flex; gap: 8px; align-items: center; }
|
|
300
|
-
.nbw-cell-body { padding: 14px 16px; font-size: 13.5px; line-height: 1.6; }
|
|
301
|
-
.nbw-cell-body.nbw-code {
|
|
302
|
-
font-family: var(--font-mono, 'IBM Plex Mono', monospace);
|
|
303
|
-
font-size: 12.5px; line-height: 1.65;
|
|
304
|
-
}
|
|
305
|
-
.nbw-hidden { display: none !important; }
|
|
306
|
-
|
|
307
|
-
.nbw-result-table { width: 100%; border-collapse: collapse; font-size: 12px; }
|
|
308
|
-
.nbw-result-table thead tr { background: var(--color-surface2); }
|
|
309
|
-
.nbw-result-table th {
|
|
310
|
-
text-align: left; padding: 7px 16px; font-weight: 500;
|
|
311
|
-
color: var(--color-text2);
|
|
312
|
-
font-family: var(--font-mono, 'IBM Plex Mono', monospace);
|
|
313
|
-
font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase;
|
|
314
|
-
border-top: 1px solid var(--color-border);
|
|
315
|
-
border-bottom: 1px solid var(--color-border);
|
|
316
|
-
}
|
|
317
|
-
.nbw-result-table td {
|
|
318
|
-
padding: 6px 16px; border-bottom: 1px solid var(--color-border);
|
|
319
|
-
font-variant-numeric: tabular-nums;
|
|
320
|
-
}
|
|
321
|
-
.nbw-result-table td:first-child { color: var(--color-text1); font-variant-numeric: normal; }
|
|
322
|
-
.nbw-share-bar { height: 8px; background: var(--color-accent); border-radius: 2px; }
|
|
323
|
-
|
|
324
|
-
.nbw-chart { padding: 16px; display: flex; align-items: flex-end; gap: 10px; height: 110px; }
|
|
325
|
-
.nbw-bar { flex: 1; background: var(--color-accent); border-radius: 2px 2px 0 0; }
|
|
326
|
-
`;
|
|
327
|
-
document.head.appendChild(style);
|
|
328
|
-
}
|