@webmcp-auto-ui/ui 2.5.38 → 2.5.39
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
CHANGED
|
@@ -79,8 +79,11 @@ export async function render(container: HTMLElement, data: Record<string, unknow
|
|
|
79
79
|
hidePublishBadge: (data as any).hidePublishBadge === true,
|
|
80
80
|
} as any);
|
|
81
81
|
|
|
82
|
-
// Default src visibility per mode (toggle remains usable for per-cell override).
|
|
83
|
-
for (const c of state.cells)
|
|
82
|
+
// Default src + logs visibility per mode (toggle remains usable for per-cell override).
|
|
83
|
+
for (const c of state.cells) {
|
|
84
|
+
c.hideSource = state.mode === 'view';
|
|
85
|
+
if (state.mode === 'view' && c.hideLogs === undefined) c.hideLogs = true;
|
|
86
|
+
}
|
|
84
87
|
|
|
85
88
|
// Live mode runtime overlay (created lazily). Never mutates state.
|
|
86
89
|
let overlay: RuntimeOverlay | null = null;
|
|
@@ -282,7 +285,7 @@ export async function render(container: HTMLElement, data: Record<string, unknow
|
|
|
282
285
|
const viewBtn = shell.querySelector('.nb-mode-view') as HTMLElement;
|
|
283
286
|
editBtn.addEventListener('click', () => {
|
|
284
287
|
state.mode = 'edit';
|
|
285
|
-
for (const c of state.cells) c.hideSource = false;
|
|
288
|
+
for (const c of state.cells) { c.hideSource = false; c.hideLogs = false; }
|
|
286
289
|
container.classList.remove('nb-view-mode');
|
|
287
290
|
editBtn.classList.add('nb-on'); viewBtn.classList.remove('nb-on');
|
|
288
291
|
// Leaving view: stop live refresh and clear overlay so frozen snapshots show.
|
|
@@ -291,7 +294,7 @@ export async function render(container: HTMLElement, data: Record<string, unknow
|
|
|
291
294
|
});
|
|
292
295
|
viewBtn.addEventListener('click', () => {
|
|
293
296
|
state.mode = 'view';
|
|
294
|
-
for (const c of state.cells) c.hideSource = true;
|
|
297
|
+
for (const c of state.cells) { c.hideSource = true; c.hideLogs = true; }
|
|
295
298
|
container.classList.add('nb-view-mode');
|
|
296
299
|
viewBtn.classList.add('nb-on'); editBtn.classList.remove('nb-on');
|
|
297
300
|
if (state.autoRun === true) bootstrapLive();
|
|
@@ -454,17 +457,25 @@ function renderCell(cell: NotebookCell, state: NotebookState, overlay: RuntimeOv
|
|
|
454
457
|
liveBadge = `<span class="nbe-cell-badge nbe-cell-frozen" title="JS cells are not re-executed in live mode">frozen</span>`;
|
|
455
458
|
}
|
|
456
459
|
}
|
|
460
|
+
const lastRes = effectiveResult(cell, overlay) ?? cell.lastResult;
|
|
461
|
+
const logCount = (lastRes?.logs as string[] | undefined)?.length ?? 0;
|
|
462
|
+
const logsToggle = logCount > 0
|
|
463
|
+
? `<button class="nb-icon-btn nb-toggle-logs" title="toggle console">${cell.hideLogs ? '▸' : '▾'} ${logCount}</button>`
|
|
464
|
+
: '';
|
|
457
465
|
head.innerHTML = `
|
|
458
466
|
<span class="nbe-run-controls"></span>
|
|
459
467
|
<span class="nbe-type-${cell.type}">${cell.type}</span>
|
|
460
468
|
<span class="nbe-meta-info">${escapeHtml(metaInfoFor(cell, overlay))}</span>
|
|
461
469
|
${liveBadge}
|
|
462
470
|
<div class="nbe-actions">
|
|
471
|
+
${logsToggle}
|
|
463
472
|
<button class="nb-icon-btn nb-toggle-src">${cell.hideSource ? '▸ src' : '◂ src'}</button>
|
|
464
473
|
<button class="nb-icon-btn nb-toggle-res">${cell.hideResult ? '▸ res' : '◂ res'}</button>
|
|
465
474
|
</div>`;
|
|
466
475
|
codeCell.appendChild(head);
|
|
467
476
|
mountRunControls(head.querySelector('.nbe-run-controls') as HTMLElement, cell, wrap, state, rerender);
|
|
477
|
+
const logsBtn = head.querySelector('.nb-toggle-logs') as HTMLElement | null;
|
|
478
|
+
if (logsBtn) logsBtn.addEventListener('click', () => { cell.hideLogs = !cell.hideLogs; rerender(); });
|
|
468
479
|
|
|
469
480
|
const body = document.createElement('div');
|
|
470
481
|
body.className = 'nbe-code-body' + (cell.hideSource ? ' nbe-hidden' : '');
|
|
@@ -847,12 +858,25 @@ function renderResultInto(el: HTMLElement, cell: NotebookCell, overlay: RuntimeO
|
|
|
847
858
|
const r = effectiveResult(cell, overlay) ?? cell.lastResult;
|
|
848
859
|
el.innerHTML = '';
|
|
849
860
|
if (!r) {
|
|
850
|
-
|
|
861
|
+
const isView = stateRef?.mode === 'view';
|
|
862
|
+
const rtStatus = cellRuntimeStatus(cell, overlay);
|
|
863
|
+
// In view mode (autoRun), any unresolved cell is effectively loading —
|
|
864
|
+
// the auto-runner will pick it up shortly. Show a continuous spinner so
|
|
865
|
+
// users don't see a static "—" placeholder during the idle→running gap.
|
|
866
|
+
if (isView && rtStatus !== 'frozen') {
|
|
867
|
+
el.innerHTML = `<div class="nbe-result-running"><span class="nbe-spinner"></span> running</div>`;
|
|
868
|
+
} else if (rtStatus === 'running') {
|
|
869
|
+
el.innerHTML = `<div class="nbe-result-running"><span class="nbe-spinner"></span> running</div>`;
|
|
870
|
+
} else {
|
|
871
|
+
el.innerHTML = `<div class="nbe-result-empty">press ▶ to run</div>`;
|
|
872
|
+
}
|
|
851
873
|
return;
|
|
852
874
|
}
|
|
853
875
|
// Logs panel (shared across all widgets), prepended above the main result
|
|
854
|
-
|
|
855
|
-
|
|
876
|
+
if (!cell.hideLogs) {
|
|
877
|
+
const logsEl = renderCellLogs(r);
|
|
878
|
+
if (logsEl) el.appendChild(logsEl);
|
|
879
|
+
}
|
|
856
880
|
if (!r.ok) {
|
|
857
881
|
const err = document.createElement('div');
|
|
858
882
|
err.className = 'nbe-result-error';
|
|
@@ -1080,6 +1104,30 @@ function injectLayoutStyles(): void {
|
|
|
1080
1104
|
.nbe-code-body { padding: 14px 16px; }
|
|
1081
1105
|
.nbe-hidden { display: none !important; }
|
|
1082
1106
|
|
|
1107
|
+
/* View-mode Option B: chrome hidden by default, revealed on hover in top-right corner. */
|
|
1108
|
+
.nb-root.nb-view-mode .nbe-code-cell { position: relative; min-height: 28px; }
|
|
1109
|
+
.nb-root.nb-view-mode .nbe-cell-head {
|
|
1110
|
+
position: absolute; top: 0; right: 0; z-index: 2;
|
|
1111
|
+
padding: 4px 8px; gap: 6px;
|
|
1112
|
+
background: var(--color-surface2);
|
|
1113
|
+
border: 1px solid var(--color-border);
|
|
1114
|
+
border-top: none; border-right: none;
|
|
1115
|
+
border-bottom-left-radius: 6px;
|
|
1116
|
+
opacity: 0; pointer-events: none;
|
|
1117
|
+
transition: opacity 120ms ease;
|
|
1118
|
+
font-size: 9.5px;
|
|
1119
|
+
}
|
|
1120
|
+
.nb-root.nb-view-mode .nbe-code-cell:hover .nbe-cell-head,
|
|
1121
|
+
.nb-root.nb-view-mode .nbe-cell-head:focus-within {
|
|
1122
|
+
opacity: 0.95; pointer-events: auto;
|
|
1123
|
+
}
|
|
1124
|
+
.nb-root.nb-view-mode .nbe-cell-head .nbe-meta-info,
|
|
1125
|
+
.nb-root.nb-view-mode .nbe-cell-head .nbe-type-sql,
|
|
1126
|
+
.nb-root.nb-view-mode .nbe-cell-head .nbe-type-js,
|
|
1127
|
+
.nb-root.nb-view-mode .nbe-cell-head .nbe-type-md { display: none; }
|
|
1128
|
+
.nb-root.nb-view-mode .nbe-code-body { padding: 10px 14px; }
|
|
1129
|
+
.nb-root.nb-view-mode .nbe-result { padding: 8px 14px; }
|
|
1130
|
+
|
|
1083
1131
|
.nbe-result {
|
|
1084
1132
|
background: var(--color-bg);
|
|
1085
1133
|
border-top: 1px solid var(--color-border);
|
|
@@ -1090,6 +1138,10 @@ function injectLayoutStyles(): void {
|
|
|
1090
1138
|
.nbe-result-empty {
|
|
1091
1139
|
color: var(--color-text2); font-style: italic; font-size: 11.5px;
|
|
1092
1140
|
}
|
|
1141
|
+
.nbe-result-running {
|
|
1142
|
+
display: inline-flex; align-items: center; gap: 6px;
|
|
1143
|
+
color: #2ea043; font-size: 11.5px;
|
|
1144
|
+
}
|
|
1093
1145
|
.nbe-result-error {
|
|
1094
1146
|
color: var(--color-accent2); white-space: pre-wrap; font-size: 12px;
|
|
1095
1147
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// 4 formats: JSON, Markdown, Hyperskill link (+ short), PNG snapshot.
|
|
5
5
|
// ---------------------------------------------------------------------------
|
|
6
6
|
|
|
7
|
-
import { encode, buildShortUrl } from '@webmcp-auto-ui/sdk';
|
|
7
|
+
import { encode, buildShortUrl, pickFence } from '@webmcp-auto-ui/sdk';
|
|
8
8
|
import { canvasVanilla } from '@webmcp-auto-ui/sdk/canvas-vanilla';
|
|
9
9
|
import type { NotebookState, NotebookCell } from './shared.js';
|
|
10
10
|
|
|
@@ -56,7 +56,9 @@ export function serializeToMarkdown(state: NotebookState): string {
|
|
|
56
56
|
const metaLine = cell.args && Object.keys(cell.args).length > 0
|
|
57
57
|
? `${commentPrefix} @meta ${JSON.stringify(cell.args)}\n`
|
|
58
58
|
: '';
|
|
59
|
-
|
|
59
|
+
const body = metaLine + cell.content.trim();
|
|
60
|
+
const fence = pickFence(body);
|
|
61
|
+
parts.push(fence + lang + varname, body, fence, '');
|
|
60
62
|
}
|
|
61
63
|
}
|
|
62
64
|
return parts.join('\n').trim() + '\n';
|
|
@@ -47,6 +47,8 @@ export interface NotebookCell {
|
|
|
47
47
|
varname?: string; // named output (compact)
|
|
48
48
|
hideSource?: boolean;
|
|
49
49
|
hideResult?: boolean;
|
|
50
|
+
/** view-mode: collapse the console logs panel under the head bar. Default true in view mode. */
|
|
51
|
+
hideLogs?: boolean;
|
|
50
52
|
runState?: RunState;
|
|
51
53
|
lastMs?: number;
|
|
52
54
|
status?: 'fresh' | 'stale';
|
|
@@ -1248,8 +1250,6 @@ const NOTEBOOK_STYLES = `
|
|
|
1248
1250
|
|
|
1249
1251
|
.nb-root.nb-view-mode .nb-drag-handle,
|
|
1250
1252
|
.nb-root.nb-view-mode .nb-icon-btn.nb-danger,
|
|
1251
|
-
.nb-root.nb-view-mode .nb-toggle-src,
|
|
1252
|
-
.nb-root.nb-view-mode .nb-toggle-res,
|
|
1253
1253
|
.nb-root.nb-view-mode .nb-add-cell,
|
|
1254
1254
|
.nb-root.nb-view-mode .nbe-cell-actionbar { display: none !important; }
|
|
1255
1255
|
|