@ggterm/core 0.2.20 → 0.3.1

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/dist/cli-plot.js CHANGED
@@ -3708,7 +3708,7 @@ function renderGeomVolcano(data, geom, aes, scales, canvas) {
3708
3708
  }
3709
3709
  if (nLabels > 0 && aes.label) {
3710
3710
  const significantPoints = points.filter((p) => p.status !== "ns" && p.label).sort((a, b) => b.significance - a.significance).slice(0, nLabels);
3711
- const labelColor = { r: 50, g: 50, b: 50, a: 1 };
3711
+ const labelColor = { r: 255, g: 255, b: 255, a: 1 };
3712
3712
  for (const point of significantPoints) {
3713
3713
  const cx = Math.round(scales.x.map(point.x));
3714
3714
  const cy = Math.round(scales.y.map(point.y));
@@ -4486,6 +4486,16 @@ function renderGeomForest(data, geom, aes, scales, canvas) {
4486
4486
  canvas.drawChar(x2, y, "┤", ciColor);
4487
4487
  const px = Math.round(mapX(row.estimate));
4488
4488
  canvas.drawChar(px, y, pointChar, pointColor);
4489
+ const label = row.study;
4490
+ const labelColor = { r: 200, g: 200, b: 200, a: 1 };
4491
+ const labelEnd = plotLeft - 1;
4492
+ const labelStart = labelEnd - label.length;
4493
+ for (let c = 0;c < label.length; c++) {
4494
+ const charX = labelStart + c;
4495
+ if (charX >= 0) {
4496
+ canvas.drawChar(charX, y, label[c], labelColor);
4497
+ }
4498
+ }
4489
4499
  }
4490
4500
  }
4491
4501
  function renderGeomRoc(data, geom, aes, scales, canvas) {
@@ -7907,11 +7917,23 @@ function calculateLayout(spec, options) {
7907
7917
  } else if (hasY2) {
7908
7918
  rightMargin = 8 + (hasY2Label ? 2 : 0);
7909
7919
  }
7920
+ let forestLabelWidth = 0;
7921
+ const isForestPlot = spec.geoms.some((g) => g.type === "forest");
7922
+ if (isForestPlot && Array.isArray(spec.data) && spec.data.length > 0) {
7923
+ const yField = typeof spec.aes.y === "string" ? spec.aes.y : "study";
7924
+ for (const row of spec.data) {
7925
+ const label = String(row[yField] ?? "");
7926
+ if (label.length > forestLabelWidth)
7927
+ forestLabelWidth = label.length;
7928
+ }
7929
+ }
7930
+ const defaultLeft = 8 + (hasYLabel ? 2 : 0);
7931
+ const neededLeft = forestLabelWidth > 0 ? forestLabelWidth + 2 : defaultLeft;
7910
7932
  const margins = {
7911
7933
  top: hasTitle ? 2 : 1,
7912
7934
  right: rightMargin,
7913
7935
  bottom: 2 + (hasXLabel ? 1 : 0) + (hasLegend && legendPosition === "bottom" ? 2 : 0),
7914
- left: 8 + (hasYLabel ? 2 : 0)
7936
+ left: Math.max(defaultLeft, neededLeft)
7915
7937
  };
7916
7938
  const plotArea = {
7917
7939
  x: margins.left,
@@ -8125,7 +8147,9 @@ function renderToCanvas(spec, options) {
8125
8147
  renderTitle(canvas, spec.labels.title, layout.width, spec.theme);
8126
8148
  }
8127
8149
  renderGridLines(canvas, scales, layout.plotArea, spec.theme);
8128
- renderAxes(canvas, scales, layout.plotArea, spec.labels, spec.theme);
8150
+ const isForest = spec.geoms.some((g) => g.type === "forest");
8151
+ const axisLabels = isForest ? { ...spec.labels, y: undefined } : spec.labels;
8152
+ renderAxes(canvas, scales, layout.plotArea, axisLabels, spec.theme);
8129
8153
  for (const geom of spec.geoms) {
8130
8154
  let geomData;
8131
8155
  let geomAes = spec.aes;
@@ -14412,11 +14436,6 @@ var init_src = __esm(() => {
14412
14436
  init_export();
14413
14437
  });
14414
14438
 
14415
- // src/cli-plot.ts
14416
- init_src();
14417
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
14418
- import { join as join3 } from "path";
14419
-
14420
14439
  // src/history/index.ts
14421
14440
  import { existsSync, mkdirSync, readFileSync, writeFileSync, appendFileSync, readdirSync } from "fs";
14422
14441
  import { join } from "path";
@@ -14573,6 +14592,652 @@ function getLatestPlotId() {
14573
14592
  }
14574
14593
  return history[history.length - 1].id;
14575
14594
  }
14595
+ var init_history = () => {};
14596
+
14597
+ // src/serve.ts
14598
+ var exports_serve = {};
14599
+ __export(exports_serve, {
14600
+ handleServe: () => handleServe
14601
+ });
14602
+ import { watch, writeFileSync as writeFileSync3, unlinkSync } from "fs";
14603
+ import { join as join3 } from "path";
14604
+ import { createServer } from "http";
14605
+ import { createHash } from "crypto";
14606
+ import { spawn } from "child_process";
14607
+ function plotToVegaLite(plot) {
14608
+ const geomTypes = plot._provenance.geomTypes;
14609
+ const hasCompositeMark = geomTypes.some((t) => COMPOSITE_MARKS.has(t));
14610
+ const spec = plotSpecToVegaLite(plot.spec, { interactive: !hasCompositeMark });
14611
+ return { spec, provenance: plot._provenance };
14612
+ }
14613
+ function getLatestPayload() {
14614
+ const id = getLatestPlotId();
14615
+ if (!id)
14616
+ return null;
14617
+ const plot = loadPlotFromHistory(id);
14618
+ if (!plot)
14619
+ return null;
14620
+ const { spec, provenance } = plotToVegaLite(plot);
14621
+ return JSON.stringify({ type: "plot", spec, provenance });
14622
+ }
14623
+ function encodeWebSocketFrame(data) {
14624
+ const payload = Buffer.from(data, "utf-8");
14625
+ const len = payload.length;
14626
+ let header;
14627
+ if (len < 126) {
14628
+ header = Buffer.alloc(2);
14629
+ header[0] = 129;
14630
+ header[1] = len;
14631
+ } else if (len < 65536) {
14632
+ header = Buffer.alloc(4);
14633
+ header[0] = 129;
14634
+ header[1] = 126;
14635
+ header.writeUInt16BE(len, 2);
14636
+ } else {
14637
+ header = Buffer.alloc(10);
14638
+ header[0] = 129;
14639
+ header[1] = 127;
14640
+ header.writeBigUInt64BE(BigInt(len), 2);
14641
+ }
14642
+ return Buffer.concat([header, payload]);
14643
+ }
14644
+ function jsonResponse(res, data, status = 200) {
14645
+ const body = JSON.stringify(data);
14646
+ res.writeHead(status, { "content-type": "application/json" });
14647
+ res.end(body);
14648
+ }
14649
+ function handleServe(port) {
14650
+ const p = port || 4242;
14651
+ ensureHistoryDirs();
14652
+ const clients = new Set;
14653
+ let debounceTimer = null;
14654
+ const plotsDir = getPlotsDir();
14655
+ watch(plotsDir, (_event, filename) => {
14656
+ if (!filename || !filename.endsWith(".json"))
14657
+ return;
14658
+ if (debounceTimer)
14659
+ clearTimeout(debounceTimer);
14660
+ debounceTimer = setTimeout(() => {
14661
+ const payload = getLatestPayload();
14662
+ if (!payload)
14663
+ return;
14664
+ const frame = encodeWebSocketFrame(payload);
14665
+ for (const client of clients) {
14666
+ try {
14667
+ client.write(frame);
14668
+ } catch {
14669
+ clients.delete(client);
14670
+ }
14671
+ }
14672
+ }, 150);
14673
+ });
14674
+ const server = createServer((req, res) => {
14675
+ const url = new URL(req.url || "/", `http://localhost:${p}`);
14676
+ if (url.pathname === "/api/latest") {
14677
+ const payload = getLatestPayload();
14678
+ if (!payload)
14679
+ return jsonResponse(res, { type: "empty" });
14680
+ res.writeHead(200, { "content-type": "application/json" });
14681
+ res.end(payload);
14682
+ return;
14683
+ }
14684
+ if (url.pathname === "/api/history") {
14685
+ const entries = getHistory().slice(-50);
14686
+ jsonResponse(res, entries);
14687
+ return;
14688
+ }
14689
+ if (url.pathname.startsWith("/api/plot/")) {
14690
+ const id = url.pathname.slice("/api/plot/".length);
14691
+ const plot = loadPlotFromHistory(id);
14692
+ if (!plot)
14693
+ return jsonResponse(res, { error: "not found" }, 404);
14694
+ const { spec, provenance } = plotToVegaLite(plot);
14695
+ jsonResponse(res, { type: "plot", spec, provenance });
14696
+ return;
14697
+ }
14698
+ res.writeHead(200, { "content-type": "text/html; charset=utf-8" });
14699
+ res.end(CLIENT_HTML);
14700
+ });
14701
+ server.on("upgrade", (req, socket, _head) => {
14702
+ const url = new URL(req.url || "/", `http://localhost:${p}`);
14703
+ if (url.pathname !== "/ws") {
14704
+ socket.destroy();
14705
+ return;
14706
+ }
14707
+ const key = req.headers["sec-websocket-key"];
14708
+ if (!key) {
14709
+ socket.destroy();
14710
+ return;
14711
+ }
14712
+ const accept = createHash("sha1").update(key + "258EAFA5-E914-47DA-95CA-5AB5DC85B7A8").digest("base64");
14713
+ socket.write(`HTTP/1.1 101 Switching Protocols\r
14714
+ ` + `Upgrade: websocket\r
14715
+ ` + `Connection: Upgrade\r
14716
+ ` + `Sec-WebSocket-Accept: ${accept}\r
14717
+ ` + `\r
14718
+ `);
14719
+ clients.add(socket);
14720
+ const payload = getLatestPayload();
14721
+ if (payload)
14722
+ socket.write(encodeWebSocketFrame(payload));
14723
+ socket.on("close", () => clients.delete(socket));
14724
+ socket.on("error", () => clients.delete(socket));
14725
+ socket.on("data", (data) => {
14726
+ if (data.length < 2)
14727
+ return;
14728
+ const opcode = data[0] & 15;
14729
+ if (opcode === 8) {
14730
+ const closeFrame = Buffer.alloc(2);
14731
+ closeFrame[0] = 136;
14732
+ closeFrame[1] = 0;
14733
+ try {
14734
+ socket.write(closeFrame);
14735
+ } catch {}
14736
+ socket.end();
14737
+ clients.delete(socket);
14738
+ return;
14739
+ }
14740
+ if (opcode === 9) {
14741
+ const pong = Buffer.from(data);
14742
+ pong[0] = pong[0] & 240 | 10;
14743
+ try {
14744
+ socket.write(pong);
14745
+ } catch {}
14746
+ }
14747
+ });
14748
+ });
14749
+ server.listen(p, () => {
14750
+ const url = `http://localhost:${p}`;
14751
+ console.log(`ggterm live viewer running at ${url}`);
14752
+ const markerPath = join3(getGGTermDir(), "serve.json");
14753
+ writeFileSync3(markerPath, JSON.stringify({ port: p, pid: process.pid }));
14754
+ const cleanup = () => {
14755
+ try {
14756
+ unlinkSync(markerPath);
14757
+ } catch {}
14758
+ };
14759
+ process.on("SIGINT", () => {
14760
+ cleanup();
14761
+ process.exit(0);
14762
+ });
14763
+ process.on("SIGTERM", () => {
14764
+ cleanup();
14765
+ process.exit(0);
14766
+ });
14767
+ process.on("exit", cleanup);
14768
+ if (process.env.TERM_PROGRAM === "waveterm") {
14769
+ spawn("wsh", ["web", "open", url], { stdio: "ignore", detached: true }).unref();
14770
+ console.log(`Opened Wave panel`);
14771
+ } else {
14772
+ console.log(`Open in browser or Wave panel: wsh web open ${url}`);
14773
+ }
14774
+ console.log(`Watching ${plotsDir} for new plots...`);
14775
+ console.log(`Press Ctrl+C to stop`);
14776
+ });
14777
+ }
14778
+ var COMPOSITE_MARKS, CLIENT_HTML = `<!DOCTYPE html>
14779
+ <html lang="en">
14780
+ <head>
14781
+ <meta charset="utf-8">
14782
+ <meta name="viewport" content="width=device-width, initial-scale=1">
14783
+ <title>ggterm</title>
14784
+ <script src="https://cdn.jsdelivr.net/npm/vega@5"></script>
14785
+ <script src="https://cdn.jsdelivr.net/npm/vega-lite@5"></script>
14786
+ <script src="https://cdn.jsdelivr.net/npm/vega-embed@6"></script>
14787
+ <style>
14788
+ * { margin: 0; padding: 0; box-sizing: border-box; }
14789
+ body {
14790
+ font-family: -apple-system, BlinkMacSystemFont, 'SF Mono', Menlo, monospace;
14791
+ background: #0d1117;
14792
+ color: #c9d1d9;
14793
+ height: 100vh;
14794
+ display: flex;
14795
+ overflow: hidden;
14796
+ }
14797
+ #sidebar {
14798
+ width: 260px;
14799
+ background: #161b22;
14800
+ border-right: 1px solid #30363d;
14801
+ display: flex;
14802
+ flex-direction: column;
14803
+ flex-shrink: 0;
14804
+ transform: translateX(-260px);
14805
+ transition: transform 0.2s ease;
14806
+ position: absolute;
14807
+ top: 0;
14808
+ left: 0;
14809
+ bottom: 0;
14810
+ z-index: 10;
14811
+ }
14812
+ #sidebar.open { transform: translateX(0); }
14813
+ #sidebar-header {
14814
+ padding: 12px;
14815
+ border-bottom: 1px solid #30363d;
14816
+ display: flex;
14817
+ align-items: center;
14818
+ justify-content: space-between;
14819
+ font-size: 12px;
14820
+ font-weight: 600;
14821
+ color: #c9d1d9;
14822
+ }
14823
+ #sidebar-header button {
14824
+ background: none;
14825
+ border: none;
14826
+ color: #8b949e;
14827
+ cursor: pointer;
14828
+ font-size: 14px;
14829
+ padding: 2px 6px;
14830
+ }
14831
+ #sidebar-header button:hover { color: #c9d1d9; }
14832
+ #history-list {
14833
+ flex: 1;
14834
+ overflow-y: auto;
14835
+ padding: 4px 0;
14836
+ }
14837
+ #history-list::-webkit-scrollbar { width: 6px; }
14838
+ #history-list::-webkit-scrollbar-track { background: transparent; }
14839
+ #history-list::-webkit-scrollbar-thumb { background: #30363d; border-radius: 3px; }
14840
+ .history-item {
14841
+ padding: 8px 12px;
14842
+ cursor: pointer;
14843
+ border-left: 2px solid transparent;
14844
+ transition: background 0.1s;
14845
+ }
14846
+ .history-item:hover { background: #21262d; }
14847
+ .history-item.active { background: #1c2128; border-left-color: #58a6ff; }
14848
+ .history-item .hi-id { font-size: 11px; color: #58a6ff; font-weight: 600; }
14849
+ .history-item .hi-desc { font-size: 11px; color: #8b949e; margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
14850
+ .history-item .hi-meta { font-size: 10px; color: #484f58; margin-top: 2px; display: flex; gap: 8px; }
14851
+ .history-item .hi-geom {
14852
+ background: #21262d;
14853
+ border: 1px solid #30363d;
14854
+ border-radius: 3px;
14855
+ padding: 0 4px;
14856
+ font-size: 10px;
14857
+ color: #8b949e;
14858
+ }
14859
+ #main {
14860
+ flex: 1;
14861
+ display: flex;
14862
+ flex-direction: column;
14863
+ min-width: 0;
14864
+ }
14865
+ #vis {
14866
+ flex: 1;
14867
+ display: flex;
14868
+ align-items: center;
14869
+ justify-content: center;
14870
+ padding: 16px;
14871
+ }
14872
+ #vis .vega-embed { width: 100%; }
14873
+ #vis .vega-embed canvas,
14874
+ #vis .vega-embed svg {
14875
+ max-width: 100%;
14876
+ max-height: calc(100vh - 80px);
14877
+ }
14878
+ #bar {
14879
+ display: flex;
14880
+ align-items: center;
14881
+ justify-content: space-between;
14882
+ padding: 8px 16px;
14883
+ background: #161b22;
14884
+ border-top: 1px solid #30363d;
14885
+ font-size: 12px;
14886
+ gap: 12px;
14887
+ min-height: 40px;
14888
+ }
14889
+ #meta { display: flex; gap: 16px; align-items: center; flex: 1; min-width: 0; }
14890
+ #plot-id { color: #58a6ff; font-weight: 600; }
14891
+ #plot-desc { color: #8b949e; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
14892
+ #plot-time { color: #484f58; }
14893
+ #nav { display: flex; gap: 4px; align-items: center; }
14894
+ .bar-btn {
14895
+ background: #21262d;
14896
+ border: 1px solid #30363d;
14897
+ color: #c9d1d9;
14898
+ border-radius: 4px;
14899
+ padding: 4px 10px;
14900
+ cursor: pointer;
14901
+ font-size: 12px;
14902
+ font-family: inherit;
14903
+ }
14904
+ .bar-btn:hover { background: #30363d; }
14905
+ .bar-btn:disabled { opacity: 0.3; cursor: default; }
14906
+ .bar-btn:disabled:hover { background: #21262d; }
14907
+ .bar-btn.active { background: #30363d; border-color: #58a6ff; }
14908
+ #actions { display: flex; gap: 4px; align-items: center; }
14909
+ #actions button {
14910
+ background: none;
14911
+ border: 1px solid #30363d;
14912
+ color: #8b949e;
14913
+ border-radius: 4px;
14914
+ padding: 4px 8px;
14915
+ cursor: pointer;
14916
+ font-size: 11px;
14917
+ font-family: inherit;
14918
+ }
14919
+ #actions button:hover { color: #c9d1d9; border-color: #58a6ff; }
14920
+ #status {
14921
+ width: 8px; height: 8px;
14922
+ border-radius: 50%;
14923
+ background: #f85149;
14924
+ flex-shrink: 0;
14925
+ }
14926
+ #status.connected { background: #3fb950; }
14927
+ .waiting {
14928
+ color: #484f58;
14929
+ font-size: 14px;
14930
+ text-align: center;
14931
+ }
14932
+ .waiting .hint { font-size: 12px; margin-top: 8px; color: #30363d; }
14933
+ #shortcuts {
14934
+ display: none;
14935
+ position: fixed;
14936
+ top: 50%;
14937
+ left: 50%;
14938
+ transform: translate(-50%, -50%);
14939
+ background: #161b22;
14940
+ border: 1px solid #30363d;
14941
+ border-radius: 8px;
14942
+ padding: 20px 24px;
14943
+ z-index: 20;
14944
+ font-size: 12px;
14945
+ min-width: 220px;
14946
+ }
14947
+ #shortcuts.open { display: block; }
14948
+ #shortcuts h3 { font-size: 13px; margin-bottom: 12px; color: #c9d1d9; }
14949
+ .shortcut-row { display: flex; justify-content: space-between; padding: 4px 0; }
14950
+ .shortcut-row kbd {
14951
+ background: #21262d;
14952
+ border: 1px solid #30363d;
14953
+ border-radius: 3px;
14954
+ padding: 1px 6px;
14955
+ font-family: inherit;
14956
+ font-size: 11px;
14957
+ color: #c9d1d9;
14958
+ }
14959
+ .shortcut-row span { color: #8b949e; }
14960
+ #overlay {
14961
+ display: none;
14962
+ position: fixed;
14963
+ inset: 0;
14964
+ background: rgba(0,0,0,0.5);
14965
+ z-index: 15;
14966
+ }
14967
+ #overlay.open { display: block; }
14968
+ </style>
14969
+ </head>
14970
+ <body>
14971
+ <div id="sidebar">
14972
+ <div id="sidebar-header">
14973
+ <span>History</span>
14974
+ <button onclick="toggleHistory()">&times;</button>
14975
+ </div>
14976
+ <div id="history-list"></div>
14977
+ </div>
14978
+ <div id="main">
14979
+ <div id="vis">
14980
+ <div class="waiting">
14981
+ <div>waiting for plots...</div>
14982
+ <div class="hint">create a plot in ggterm and it will appear here</div>
14983
+ </div>
14984
+ </div>
14985
+ <div id="bar">
14986
+ <div id="status"></div>
14987
+ <div id="meta">
14988
+ <span id="plot-id"></span>
14989
+ <span id="plot-desc"></span>
14990
+ <span id="plot-time"></span>
14991
+ </div>
14992
+ <div id="nav">
14993
+ <button id="hist-btn" class="bar-btn" onclick="toggleHistory()" title="History (h)">H</button>
14994
+ <button id="prev" class="bar-btn" disabled title="Previous plot (&larr;)">&larr;</button>
14995
+ <button id="next" class="bar-btn" disabled title="Next plot (&rarr;)">&rarr;</button>
14996
+ </div>
14997
+ <div id="actions">
14998
+ <button onclick="downloadSVG()" title="Download SVG (s)">SVG</button>
14999
+ <button onclick="downloadPNG()" title="Download PNG (p)">PNG</button>
15000
+ <button onclick="toggleShortcuts()" title="Keyboard shortcuts (?)">?</button>
15001
+ </div>
15002
+ </div>
15003
+ </div>
15004
+ <div id="overlay" onclick="closeOverlays()"></div>
15005
+ <div id="shortcuts">
15006
+ <h3>Keyboard Shortcuts</h3>
15007
+ <div class="shortcut-row"><span>Previous plot</span><kbd>&larr;</kbd></div>
15008
+ <div class="shortcut-row"><span>Next plot</span><kbd>&rarr;</kbd></div>
15009
+ <div class="shortcut-row"><span>Latest plot</span><kbd>End</kbd></div>
15010
+ <div class="shortcut-row"><span>First plot</span><kbd>Home</kbd></div>
15011
+ <div class="shortcut-row"><span>Toggle history</span><kbd>h</kbd></div>
15012
+ <div class="shortcut-row"><span>Download SVG</span><kbd>s</kbd></div>
15013
+ <div class="shortcut-row"><span>Download PNG</span><kbd>p</kbd></div>
15014
+ <div class="shortcut-row"><span>Fullscreen</span><kbd>f</kbd></div>
15015
+ <div class="shortcut-row"><span>Show shortcuts</span><kbd>?</kbd></div>
15016
+ <div class="shortcut-row"><span>Close panel</span><kbd>Esc</kbd></div>
15017
+ </div>
15018
+ <script>
15019
+ const vis = document.getElementById('vis');
15020
+ const main = document.getElementById('main');
15021
+ const statusEl = document.getElementById('status');
15022
+ const idEl = document.getElementById('plot-id');
15023
+ const descEl = document.getElementById('plot-desc');
15024
+ const timeEl = document.getElementById('plot-time');
15025
+ const prevBtn = document.getElementById('prev');
15026
+ const nextBtn = document.getElementById('next');
15027
+ const histBtn = document.getElementById('hist-btn');
15028
+ const sidebar = document.getElementById('sidebar');
15029
+ const historyList = document.getElementById('history-list');
15030
+ const shortcutsEl = document.getElementById('shortcuts');
15031
+ const overlayEl = document.getElementById('overlay');
15032
+
15033
+ let history = [];
15034
+ let historyIndex = {};
15035
+ let currentIdx = -1;
15036
+ let view = null;
15037
+ let ws = null;
15038
+
15039
+ function updateMeta(prov) {
15040
+ if (!prov) return;
15041
+ idEl.textContent = prov.id;
15042
+ descEl.textContent = prov.description || '';
15043
+ timeEl.textContent = prov.timestamp ? new Date(prov.timestamp).toLocaleTimeString() : '';
15044
+ }
15045
+
15046
+ function updateNav() {
15047
+ prevBtn.disabled = currentIdx <= 0;
15048
+ nextBtn.disabled = currentIdx >= history.length - 1;
15049
+ }
15050
+
15051
+ function updateHistoryHighlight() {
15052
+ historyList.querySelectorAll('.history-item').forEach((el, i) => {
15053
+ el.classList.toggle('active', i === currentIdx);
15054
+ });
15055
+ const active = historyList.querySelector('.active');
15056
+ if (active) active.scrollIntoView({ block: 'nearest' });
15057
+ }
15058
+
15059
+ function addHistoryItem(data, idx) {
15060
+ const prov = data.provenance;
15061
+ if (!prov) return;
15062
+ const div = document.createElement('div');
15063
+ div.className = 'history-item' + (idx === currentIdx ? ' active' : '');
15064
+ div.innerHTML =
15065
+ '<div class="hi-id">' + prov.id + '</div>' +
15066
+ '<div class="hi-desc">' + (prov.description || '') + '</div>' +
15067
+ '<div class="hi-meta">' +
15068
+ '<span class="hi-geom">' + (prov.geomTypes ? prov.geomTypes.join('+') : '') + '</span>' +
15069
+ '<span>' + (prov.timestamp ? new Date(prov.timestamp).toLocaleTimeString() : '') + '</span>' +
15070
+ '</div>';
15071
+ div.onclick = () => navigate(idx);
15072
+ historyList.appendChild(div);
15073
+ }
15074
+
15075
+ function rebuildHistoryList() {
15076
+ historyList.innerHTML = '';
15077
+ history.forEach((data, i) => addHistoryItem(data, i));
15078
+ }
15079
+
15080
+ const embedOpts = {
15081
+ actions: false,
15082
+ theme: 'dark',
15083
+ renderer: 'svg',
15084
+ config: {
15085
+ background: '#0d1117',
15086
+ axis: { domainColor: '#30363d', gridColor: '#21262d', tickColor: '#30363d', labelColor: '#8b949e', titleColor: '#c9d1d9' },
15087
+ legend: { labelColor: '#c9d1d9', titleColor: '#c9d1d9' },
15088
+ title: { color: '#c9d1d9', subtitleColor: '#8b949e' },
15089
+ view: { stroke: null }
15090
+ }
15091
+ };
15092
+
15093
+ async function renderSpec(spec) {
15094
+ vis.innerHTML = '';
15095
+ const vegaSpec = { ...spec, width: 'container', height: 'container', autosize: { type: 'fit', contains: 'padding' } };
15096
+ try {
15097
+ const result = await vegaEmbed(vis, vegaSpec, embedOpts);
15098
+ view = result.view;
15099
+ } catch (e) {
15100
+ // Retry without interactive params (composite marks like boxplot don't support selections)
15101
+ console.warn('Render failed, retrying without params:', e.message);
15102
+ const { params, ...cleanSpec } = vegaSpec;
15103
+ const result = await vegaEmbed(vis, cleanSpec, embedOpts);
15104
+ view = result.view;
15105
+ }
15106
+ }
15107
+
15108
+ async function showPlot(data) {
15109
+ await renderSpec(data.spec);
15110
+ updateMeta(data.provenance);
15111
+ }
15112
+
15113
+ function navigate(idx) {
15114
+ if (idx < 0 || idx >= history.length) return;
15115
+ currentIdx = idx;
15116
+ const data = history[idx];
15117
+ if (data.spec) {
15118
+ showPlot(data);
15119
+ } else {
15120
+ // Lazy-load full spec from server
15121
+ fetch('/api/plot/' + data.provenance.id)
15122
+ .then(r => r.json())
15123
+ .then(full => {
15124
+ history[idx] = full;
15125
+ showPlot(full);
15126
+ });
15127
+ }
15128
+ updateNav();
15129
+ updateHistoryHighlight();
15130
+ }
15131
+
15132
+ prevBtn.onclick = () => navigate(currentIdx - 1);
15133
+ nextBtn.onclick = () => navigate(currentIdx + 1);
15134
+
15135
+ function toggleHistory() {
15136
+ const open = sidebar.classList.toggle('open');
15137
+ histBtn.classList.toggle('active', open);
15138
+ }
15139
+
15140
+ function toggleShortcuts() {
15141
+ const open = shortcutsEl.classList.toggle('open');
15142
+ overlayEl.classList.toggle('open', open);
15143
+ }
15144
+
15145
+ function closeOverlays() {
15146
+ shortcutsEl.classList.remove('open');
15147
+ overlayEl.classList.remove('open');
15148
+ }
15149
+
15150
+ document.addEventListener('keydown', (e) => {
15151
+ // Ignore when typing in an input
15152
+ if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
15153
+
15154
+ switch (e.key) {
15155
+ case 'ArrowLeft': navigate(currentIdx - 1); break;
15156
+ case 'ArrowRight': navigate(currentIdx + 1); break;
15157
+ case 'Home': e.preventDefault(); navigate(0); break;
15158
+ case 'End': e.preventDefault(); navigate(history.length - 1); break;
15159
+ case 'h': toggleHistory(); break;
15160
+ case 's': downloadSVG(); break;
15161
+ case 'p': downloadPNG(); break;
15162
+ case 'f':
15163
+ if (!document.fullscreenElement) {
15164
+ document.documentElement.requestFullscreen();
15165
+ } else {
15166
+ document.exitFullscreen();
15167
+ }
15168
+ break;
15169
+ case '?': toggleShortcuts(); break;
15170
+ case 'Escape': closeOverlays(); if (sidebar.classList.contains('open')) toggleHistory(); break;
15171
+ }
15172
+ });
15173
+
15174
+ function downloadSVG() {
15175
+ if (!view) return;
15176
+ view.toSVG().then(svg => {
15177
+ const a = document.createElement('a');
15178
+ a.href = URL.createObjectURL(new Blob([svg], { type: 'image/svg+xml' }));
15179
+ a.download = (idEl.textContent || 'plot') + '.svg';
15180
+ a.click();
15181
+ });
15182
+ }
15183
+
15184
+ function downloadPNG() {
15185
+ if (!view) return;
15186
+ view.toCanvas(2).then(canvas => {
15187
+ const a = document.createElement('a');
15188
+ a.href = canvas.toDataURL('image/png');
15189
+ a.download = (idEl.textContent || 'plot') + '.png';
15190
+ a.click();
15191
+ });
15192
+ }
15193
+
15194
+ function connect() {
15195
+ const proto = location.protocol === 'https:' ? 'wss:' : 'ws:';
15196
+ ws = new WebSocket(proto + '//' + location.host + '/ws');
15197
+
15198
+ ws.onopen = () => { statusEl.classList.add('connected'); };
15199
+ ws.onclose = () => {
15200
+ statusEl.classList.remove('connected');
15201
+ setTimeout(connect, 2000);
15202
+ };
15203
+ ws.onerror = () => ws.close();
15204
+
15205
+ ws.onmessage = (e) => {
15206
+ const data = JSON.parse(e.data);
15207
+ if (data.type === 'plot') {
15208
+ history.push(data);
15209
+ currentIdx = history.length - 1;
15210
+ addHistoryItem(data, history.length - 1);
15211
+ showPlot(data);
15212
+ updateNav();
15213
+ updateHistoryHighlight();
15214
+ }
15215
+ };
15216
+ }
15217
+
15218
+ // Load initial history then connect
15219
+ fetch('/api/history')
15220
+ .then(r => r.json())
15221
+ .then(entries => {
15222
+ // Populate history with provenance-only stubs (lazy-load specs on navigate)
15223
+ history = entries.map(e => ({ provenance: e, spec: null }));
15224
+ rebuildHistoryList();
15225
+ })
15226
+ .then(() => connect());
15227
+ </script>
15228
+ </body>
15229
+ </html>`;
15230
+ var init_serve = __esm(() => {
15231
+ init_history();
15232
+ init_export();
15233
+ COMPOSITE_MARKS = new Set(["boxplot", "violin", "errorband", "errorbar"]);
15234
+ });
15235
+
15236
+ // src/cli-plot.ts
15237
+ init_src();
15238
+ init_history();
15239
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync4, existsSync as existsSync3 } from "fs";
15240
+ import { join as join4 } from "path";
14576
15241
 
14577
15242
  // src/init.ts
14578
15243
  import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, readFileSync as readFileSync2, existsSync as existsSync2, readdirSync as readdirSync2, statSync } from "fs";
@@ -15194,6 +15859,18 @@ function handleInit() {
15194
15859
  }
15195
15860
 
15196
15861
  // src/cli-plot.ts
15862
+ function isServeRunning() {
15863
+ const markerPath = join4(getGGTermDir(), "serve.json");
15864
+ if (!existsSync3(markerPath))
15865
+ return false;
15866
+ try {
15867
+ const info = JSON.parse(readFileSync3(markerPath, "utf-8"));
15868
+ process.kill(info.pid, 0);
15869
+ return true;
15870
+ } catch {
15871
+ return false;
15872
+ }
15873
+ }
15197
15874
  var GEOM_TYPES = [
15198
15875
  "point",
15199
15876
  "line",
@@ -16043,15 +16720,22 @@ If you want a univariate plot, try: histogram, density, bar, qq, or freqpoly`);
16043
16720
  if (facetVar && facetVar !== "-") {
16044
16721
  plot = plot.facet(facet_wrap(facetVar));
16045
16722
  }
16046
- console.log(plot.render({ width: 70, height: 20, colorMode: "truecolor" }));
16723
+ const serveActive = isServeRunning();
16724
+ if (!serveActive) {
16725
+ console.log(plot.render({ width: 70, height: 20, colorMode: "truecolor" }));
16726
+ }
16047
16727
  const spec = plot.spec();
16048
16728
  const commandStr = `cli-plot.ts ${args.join(" ")}`;
16049
16729
  const plotId = savePlotToHistory(spec, {
16050
16730
  dataFile,
16051
16731
  command: commandStr
16052
16732
  });
16053
- console.log(`
16733
+ if (serveActive) {
16734
+ console.log(`[${plotId}] → live viewer`);
16735
+ } else {
16736
+ console.log(`
16054
16737
  [Saved as ${plotId}]`);
16738
+ }
16055
16739
  }
16056
16740
  function handleHistory(searchQuery) {
16057
16741
  const entries = searchQuery ? searchHistory(searchQuery) : getHistory();
@@ -16130,7 +16814,7 @@ function handleExport(idOrFile, outputFile) {
16130
16814
  const spec = plotSpecToVegaLite2(plotSpec, {
16131
16815
  interactive: true
16132
16816
  });
16133
- writeFileSync3(join3(getGGTermDir(), "last-plot-vegalite.json"), JSON.stringify(spec, null, 2));
16817
+ writeFileSync4(join4(getGGTermDir(), "last-plot-vegalite.json"), JSON.stringify(spec, null, 2));
16134
16818
  const title = typeof spec.title === "string" ? spec.title : spec.title?.text || "Plot";
16135
16819
  const output = outputFile || `${plotId}.html`;
16136
16820
  const html = `<!DOCTYPE html>
@@ -16187,7 +16871,7 @@ function handleExport(idOrFile, outputFile) {
16187
16871
  </script>
16188
16872
  </body>
16189
16873
  </html>`;
16190
- writeFileSync3(output, html);
16874
+ writeFileSync4(output, html);
16191
16875
  console.log(`Created ${output} - open in browser to view and export`);
16192
16876
  }
16193
16877
  function printUsage() {
@@ -16201,6 +16885,7 @@ Commands:
16201
16885
  history [search] List all plots (optionally filter by search)
16202
16886
  show <id> Re-render a plot from history
16203
16887
  export [id] [output.html] Export plot to HTML (latest or by ID)
16888
+ serve [port] Start live plot viewer (default: 4242)
16204
16889
  <file> <x> <y> [color] [title] [geom] [facet] Create a plot
16205
16890
 
16206
16891
  Supported formats: CSV, JSON, JSONL (auto-detected by extension)
@@ -16225,6 +16910,8 @@ Examples:
16225
16910
  ggterm-plot history
16226
16911
  ggterm-plot show 2024-01-26-001
16227
16912
  ggterm-plot export 2024-01-26-001 figure.html
16913
+ ggterm-plot serve # Start live plot viewer
16914
+ ggterm-plot serve 8080 # Custom port
16228
16915
  `);
16229
16916
  }
16230
16917
  var args = process.argv.slice(2);
@@ -16257,6 +16944,10 @@ if (command === "init") {
16257
16944
  handleShow(args[1]);
16258
16945
  } else if (command === "export") {
16259
16946
  handleExport(args[1], args[2]);
16947
+ } else if (command === "serve") {
16948
+ Promise.resolve().then(() => (init_serve(), exports_serve)).then(({ handleServe: handleServe2 }) => {
16949
+ handleServe2(args[1] ? parseInt(args[1]) : undefined);
16950
+ });
16260
16951
  } else if (command === "help" || command === "--help" || command === "-h") {
16261
16952
  printUsage();
16262
16953
  } else {
package/dist/cli.js CHANGED
@@ -3708,7 +3708,7 @@ function renderGeomVolcano(data, geom, aes, scales, canvas) {
3708
3708
  }
3709
3709
  if (nLabels > 0 && aes.label) {
3710
3710
  const significantPoints = points.filter((p) => p.status !== "ns" && p.label).sort((a, b) => b.significance - a.significance).slice(0, nLabels);
3711
- const labelColor = { r: 50, g: 50, b: 50, a: 1 };
3711
+ const labelColor = { r: 255, g: 255, b: 255, a: 1 };
3712
3712
  for (const point of significantPoints) {
3713
3713
  const cx = Math.round(scales.x.map(point.x));
3714
3714
  const cy = Math.round(scales.y.map(point.y));
@@ -4486,6 +4486,16 @@ function renderGeomForest(data, geom, aes, scales, canvas) {
4486
4486
  canvas.drawChar(x2, y, "┤", ciColor);
4487
4487
  const px = Math.round(mapX(row.estimate));
4488
4488
  canvas.drawChar(px, y, pointChar, pointColor);
4489
+ const label = row.study;
4490
+ const labelColor = { r: 200, g: 200, b: 200, a: 1 };
4491
+ const labelEnd = plotLeft - 1;
4492
+ const labelStart = labelEnd - label.length;
4493
+ for (let c = 0;c < label.length; c++) {
4494
+ const charX = labelStart + c;
4495
+ if (charX >= 0) {
4496
+ canvas.drawChar(charX, y, label[c], labelColor);
4497
+ }
4498
+ }
4489
4499
  }
4490
4500
  }
4491
4501
  function renderGeomRoc(data, geom, aes, scales, canvas) {
@@ -7907,11 +7917,23 @@ function calculateLayout(spec, options) {
7907
7917
  } else if (hasY2) {
7908
7918
  rightMargin = 8 + (hasY2Label ? 2 : 0);
7909
7919
  }
7920
+ let forestLabelWidth = 0;
7921
+ const isForestPlot = spec.geoms.some((g) => g.type === "forest");
7922
+ if (isForestPlot && Array.isArray(spec.data) && spec.data.length > 0) {
7923
+ const yField = typeof spec.aes.y === "string" ? spec.aes.y : "study";
7924
+ for (const row of spec.data) {
7925
+ const label = String(row[yField] ?? "");
7926
+ if (label.length > forestLabelWidth)
7927
+ forestLabelWidth = label.length;
7928
+ }
7929
+ }
7930
+ const defaultLeft = 8 + (hasYLabel ? 2 : 0);
7931
+ const neededLeft = forestLabelWidth > 0 ? forestLabelWidth + 2 : defaultLeft;
7910
7932
  const margins = {
7911
7933
  top: hasTitle ? 2 : 1,
7912
7934
  right: rightMargin,
7913
7935
  bottom: 2 + (hasXLabel ? 1 : 0) + (hasLegend && legendPosition === "bottom" ? 2 : 0),
7914
- left: 8 + (hasYLabel ? 2 : 0)
7936
+ left: Math.max(defaultLeft, neededLeft)
7915
7937
  };
7916
7938
  const plotArea = {
7917
7939
  x: margins.left,
@@ -8125,7 +8147,9 @@ function renderToCanvas(spec, options) {
8125
8147
  renderTitle(canvas, spec.labels.title, layout.width, spec.theme);
8126
8148
  }
8127
8149
  renderGridLines(canvas, scales, layout.plotArea, spec.theme);
8128
- renderAxes(canvas, scales, layout.plotArea, spec.labels, spec.theme);
8150
+ const isForest = spec.geoms.some((g) => g.type === "forest");
8151
+ const axisLabels = isForest ? { ...spec.labels, y: undefined } : spec.labels;
8152
+ renderAxes(canvas, scales, layout.plotArea, axisLabels, spec.theme);
8129
8153
  for (const geom of spec.geoms) {
8130
8154
  let geomData;
8131
8155
  let geomAes = spec.aes;
package/dist/index.js CHANGED
@@ -3707,7 +3707,7 @@ function renderGeomVolcano(data, geom, aes, scales, canvas) {
3707
3707
  }
3708
3708
  if (nLabels > 0 && aes.label) {
3709
3709
  const significantPoints = points.filter((p) => p.status !== "ns" && p.label).sort((a, b) => b.significance - a.significance).slice(0, nLabels);
3710
- const labelColor = { r: 50, g: 50, b: 50, a: 1 };
3710
+ const labelColor = { r: 255, g: 255, b: 255, a: 1 };
3711
3711
  for (const point of significantPoints) {
3712
3712
  const cx = Math.round(scales.x.map(point.x));
3713
3713
  const cy = Math.round(scales.y.map(point.y));
@@ -4485,6 +4485,16 @@ function renderGeomForest(data, geom, aes, scales, canvas) {
4485
4485
  canvas.drawChar(x2, y, "┤", ciColor);
4486
4486
  const px = Math.round(mapX(row.estimate));
4487
4487
  canvas.drawChar(px, y, pointChar, pointColor);
4488
+ const label = row.study;
4489
+ const labelColor = { r: 200, g: 200, b: 200, a: 1 };
4490
+ const labelEnd = plotLeft - 1;
4491
+ const labelStart = labelEnd - label.length;
4492
+ for (let c = 0;c < label.length; c++) {
4493
+ const charX = labelStart + c;
4494
+ if (charX >= 0) {
4495
+ canvas.drawChar(charX, y, label[c], labelColor);
4496
+ }
4497
+ }
4488
4498
  }
4489
4499
  }
4490
4500
  function renderGeomRoc(data, geom, aes, scales, canvas) {
@@ -7906,11 +7916,23 @@ function calculateLayout(spec, options) {
7906
7916
  } else if (hasY2) {
7907
7917
  rightMargin = 8 + (hasY2Label ? 2 : 0);
7908
7918
  }
7919
+ let forestLabelWidth = 0;
7920
+ const isForestPlot = spec.geoms.some((g) => g.type === "forest");
7921
+ if (isForestPlot && Array.isArray(spec.data) && spec.data.length > 0) {
7922
+ const yField = typeof spec.aes.y === "string" ? spec.aes.y : "study";
7923
+ for (const row of spec.data) {
7924
+ const label = String(row[yField] ?? "");
7925
+ if (label.length > forestLabelWidth)
7926
+ forestLabelWidth = label.length;
7927
+ }
7928
+ }
7929
+ const defaultLeft = 8 + (hasYLabel ? 2 : 0);
7930
+ const neededLeft = forestLabelWidth > 0 ? forestLabelWidth + 2 : defaultLeft;
7909
7931
  const margins = {
7910
7932
  top: hasTitle ? 2 : 1,
7911
7933
  right: rightMargin,
7912
7934
  bottom: 2 + (hasXLabel ? 1 : 0) + (hasLegend && legendPosition === "bottom" ? 2 : 0),
7913
- left: 8 + (hasYLabel ? 2 : 0)
7935
+ left: Math.max(defaultLeft, neededLeft)
7914
7936
  };
7915
7937
  const plotArea = {
7916
7938
  x: margins.left,
@@ -8124,7 +8146,9 @@ function renderToCanvas(spec, options) {
8124
8146
  renderTitle(canvas, spec.labels.title, layout.width, spec.theme);
8125
8147
  }
8126
8148
  renderGridLines(canvas, scales, layout.plotArea, spec.theme);
8127
- renderAxes(canvas, scales, layout.plotArea, spec.labels, spec.theme);
8149
+ const isForest = spec.geoms.some((g) => g.type === "forest");
8150
+ const axisLabels = isForest ? { ...spec.labels, y: undefined } : spec.labels;
8151
+ renderAxes(canvas, scales, layout.plotArea, axisLabels, spec.theme);
8128
8152
  for (const geom of spec.geoms) {
8129
8153
  let geomData;
8130
8154
  let geomAes = spec.aes;
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/pipeline/pipeline.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAA6C,QAAQ,EAAE,aAAa,EAAQ,MAAM,UAAU,CAAA;AACxG,OAAO,EAAE,cAAc,EAAgB,MAAM,kBAAkB,CAAA;AAmB/D;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE;QACP,GAAG,EAAE,MAAM,CAAA;QACX,KAAK,EAAE,MAAM,CAAA;QACb,MAAM,EAAE,MAAM,CAAA;QACd,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;IACD,QAAQ,EAAE;QACR,CAAC,EAAE,MAAM,CAAA;QACT,CAAC,EAAE,MAAM,CAAA;QACT,KAAK,EAAE,MAAM,CAAA;QACb,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;IACD,UAAU,CAAC,EAAE;QACX,CAAC,EAAE,MAAM,CAAA;QACT,CAAC,EAAE,MAAM,CAAA;QACT,KAAK,EAAE,MAAM,CAAA;QACb,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;CACF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,aAAa,GACrB,UAAU,CAgEZ;AAwJD;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,aAAa,GACrB,cAAc,CA+MhB;AAwcD;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,aAAa,GACrB,MAAM,CASR"}
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/pipeline/pipeline.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAA6C,QAAQ,EAAE,aAAa,EAAQ,MAAM,UAAU,CAAA;AACxG,OAAO,EAAE,cAAc,EAAgB,MAAM,kBAAkB,CAAA;AAmB/D;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE;QACP,GAAG,EAAE,MAAM,CAAA;QACX,KAAK,EAAE,MAAM,CAAA;QACb,MAAM,EAAE,MAAM,CAAA;QACd,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;IACD,QAAQ,EAAE;QACR,CAAC,EAAE,MAAM,CAAA;QACT,CAAC,EAAE,MAAM,CAAA;QACT,KAAK,EAAE,MAAM,CAAA;QACb,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;IACD,UAAU,CAAC,EAAE;QACX,CAAC,EAAE,MAAM,CAAA;QACT,CAAC,EAAE,MAAM,CAAA;QACT,KAAK,EAAE,MAAM,CAAA;QACb,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;CACF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,aAAa,GACrB,UAAU,CA8EZ;AAwJD;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,aAAa,GACrB,cAAc,CAmNhB;AAwcD;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,aAAa,GACrB,MAAM,CASR"}
@@ -1 +1 @@
1
- {"version":3,"file":"render-geoms.d.ts","sourceRoot":"","sources":["../../src/pipeline/render-geoms.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"render-geoms.d.ts","sourceRoot":"","sources":["../../src/pipeline/render-geoms.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Live plot viewer server
3
+ *
4
+ * Watches .ggterm/plots/ for new plots and pushes them to connected
5
+ * browsers via WebSocket. Renders interactive Vega-Lite in a dark-themed page.
6
+ *
7
+ * Uses node:http and a minimal WebSocket implementation for Node.js compatibility.
8
+ */
9
+ export declare function handleServe(port?: number): void;
10
+ //# sourceMappingURL=serve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA6gBH,wBAAgB,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CA2I/C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ggterm/core",
3
- "version": "0.2.20",
3
+ "version": "0.3.1",
4
4
  "description": "Grammar of Graphics engine for terminals",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",