mellos-mapping 0.26.0 → 0.26.2

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/server.mjs CHANGED
@@ -24650,7 +24650,7 @@ function launcherViewerPid(run) {
24650
24650
 
24651
24651
  // src/server/server.ts
24652
24652
  var SERVER_NAME = "mellos-mapping";
24653
- var SERVER_VERSION = "0.26.0";
24653
+ var SERVER_VERSION = "0.26.2";
24654
24654
  function text(s, isError = false) {
24655
24655
  return { content: [{ type: "text", text: s }], ...isError ? { isError: true } : {} };
24656
24656
  }
@@ -4,8 +4,11 @@ header{display:flex;align-items:center;justify-content:space-between;gap:12px;pa
4
4
  .brand{color:#e5edf7;text-decoration:none;font-weight:650;white-space:nowrap}.brand span{font-weight:400;color:#97a7bd;font-size:12px;margin-left:12px}.brand:hover span{color:#81dbae}
5
5
  .tools{display:flex;align-items:center;gap:8px;font-size:12px;color:#aab8cb}button,select{font:inherit;color:#d9e2ed;background:#202b3a;border:1px solid #3b4b60;border-radius:5px;padding:4px 7px;cursor:pointer}button:hover,select:hover{border-color:#81dbae}button:focus-visible,select:focus-visible,a:focus-visible{outline:2px solid #81dbae;outline-offset:2px}
6
6
  #terminal{min-width:0;min-height:0;padding:0;overflow:hidden;user-select:none;background:#10151c}#terminal .xterm{height:100%;padding:8px 10px 0}#terminal .xterm-viewport{overscroll-behavior:contain}
7
+ #terminal .xterm-helper-textarea:disabled{pointer-events:none}
7
8
  footer{min-height:32px;display:flex;flex-wrap:wrap;align-items:center;gap:8px 12px;padding:5px 14px;border-top:1px solid #283343;color:#8c9eb5;font-size:11px}#connection{overflow-wrap:anywhere}#connection[data-state="connected"]{color:#81dbae}#connection[data-state="error"]{color:#ffaf87}.hint{margin-left:auto}[hidden]{display:none!important}
8
- @media(max-width:440px){.brand span{margin-left:6px}.hint{margin-left:0;width:100%}header{padding:0 10px}#terminal .xterm{padding-left:4px;padding-right:4px}}
9
+ button:disabled{opacity:.65;cursor:default}
10
+ @media(max-width:600px){.brand span{display:none}}
11
+ @media(max-width:440px){.tools label{display:none}.hint{margin-left:0;width:100%}header{padding:0 10px}#terminal .xterm{padding-left:4px;padding-right:4px}}
9
12
  dialog{max-width:min(420px,90vw);border:1px solid #3b4b60;border-radius:10px;background:#151c25;color:#d9e2ed;padding:24px}dialog::backdrop{background:#0009}dialog h2{font-size:18px;margin-top:0}dialog p{line-height:1.9;font-size:13px}dialog form{text-align:right}
10
13
 
11
14
  #star-reminder {
@@ -1,7 +1,7 @@
1
1
  <!doctype html>
2
2
  <html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Mellos · 终端地图</title><link rel="icon" href="data:,"><link rel="stylesheet" href="./xterm.css"><link rel="stylesheet" href="./terminal.css"><script type="module" src="./terminal.js"></script></head>
3
- <body><header><a class="brand" id="graphic" href="./" title="切换到图形地图">Mellos <span>图形地图 ↗</span></a><div class="tools"><label for="font-size">字号</label><select id="font-size" aria-label="终端字号"><option>10</option><option>11</option><option>12</option><option selected>13</option><option>14</option><option>15</option><option>16</option><option>18</option><option>20</option><option>24</option><option>28</option></select><button id="help" aria-label="操作帮助">?</button></div></header>
3
+ <body><header><a class="brand" id="graphic" href="./" title="切换到图形地图">Mellos <span>图形地图 ↗</span></a><div class="tools"><button id="keyboard">启用快捷键</button><label for="font-size">字号</label><select id="font-size" aria-label="终端字号"><option>10</option><option>11</option><option>12</option><option selected>13</option><option>14</option><option>15</option><option>16</option><option>18</option><option>20</option><option>24</option><option>28</option></select><button id="help" aria-label="操作帮助">?</button></div></header>
4
4
  <main id="terminal" aria-label="Mellos 终端地图"></main>
5
- <footer><span id="connection" role="status" aria-live="polite">正在连接…</span><button id="restart" hidden>重新连接</button><span class="hint">滚轮缩放 · 拖动平移 · 点击选择 · ? 帮助</span><aside id="star-reminder" aria-label="支持 Mellos Mapping" hidden><span>地图有帮到你?欢迎在 GitHub 点个 Star。</span><a href="https://github.com/GuangminJu/mellos-mapping" target="_blank" rel="noopener noreferrer">去点 Star ↗</a><button type="button">不再提醒</button></aside></footer>
6
- <dialog id="help-dialog"><h2>终端地图操作</h2><p>滚轮 / + / −:总览 → 模块 → 细节<br>拖动:平移 · 单击:固定详情<br>双击带 ⊞ 的节点:进入子地图<br>Backspace:返回父地图<br>Tab / 数字 1–9:切换页面<br>f:自动跟随 · 0:重置视图<br>x 按两次:确认删除当前页<br>q:关闭地图,可用「重新连接」再次打开</p><p>右上角字号只影响此网页终端。</p><form method="dialog"><button>关闭帮助</button></form></dialog>
5
+ <footer><span id="connection" role="status" aria-live="polite">正在连接…</span><button id="restart" hidden>重新连接</button><span class="hint">滚轮缩放 · 拖动平移 · 快捷键需手动启用,离开地图即释放</span><aside id="star-reminder" aria-label="支持 Mellos Mapping" hidden><span>地图有帮到你?欢迎在 GitHub 点个 Star。</span><a href="https://github.com/GuangminJu/mellos-mapping" target="_blank" rel="noopener noreferrer">去点 Star ↗</a><button type="button">不再提醒</button></aside></footer>
6
+ <dialog id="help-dialog"><h2>终端地图操作</h2><p>鼠标操作可直接使用。键盘操作请先点击「启用快捷键」;Esc 或离开地图后释放,需再次启用。</p><p>滚轮 / + / −:总览 → 模块 → 细节<br>拖动:平移 · 单击:固定详情<br>双击带 ⊞ 的节点:进入子地图<br>Backspace:返回父地图<br>Tab / 数字 1–9:切换页面<br>f:自动跟随 · 0:重置视图<br>x 按两次:确认删除当前页<br>q:关闭地图,可用「重新连接」再次打开</p><p>右上角字号只影响此网页终端。</p><form method="dialog"><button>关闭帮助</button></form></dialog>
7
7
  </body></html>
@@ -9213,6 +9213,36 @@ function createStarNotice(base2) {
9213
9213
  };
9214
9214
  }
9215
9215
 
9216
+ // src/web/terminal-input.ts
9217
+ function bindTerminalInput(textarea, button, surface) {
9218
+ const listeners = new AbortController();
9219
+ const options = { signal: listeners.signal };
9220
+ const release = () => {
9221
+ textarea.blur();
9222
+ textarea.disabled = true;
9223
+ button.disabled = false;
9224
+ button.textContent = "\u542F\u7528\u5FEB\u6377\u952E";
9225
+ };
9226
+ button.addEventListener("click", () => {
9227
+ textarea.disabled = false;
9228
+ textarea.focus({ preventScroll: true });
9229
+ button.disabled = true;
9230
+ button.textContent = "\u5FEB\u6377\u952E\u5DF2\u542F\u7528";
9231
+ }, options);
9232
+ textarea.addEventListener("blur", release, options);
9233
+ window.addEventListener("blur", release, options);
9234
+ surface.addEventListener("pointerleave", release, options);
9235
+ document.documentElement.addEventListener("pointerleave", release, options);
9236
+ document.addEventListener("visibilitychange", () => {
9237
+ if (document.visibilityState !== "visible") release();
9238
+ }, options);
9239
+ release();
9240
+ return { release, dispose: () => {
9241
+ release();
9242
+ listeners.abort();
9243
+ } };
9244
+ }
9245
+
9216
9246
  // src/web/terminal-app.ts
9217
9247
  var element = (id) => document.getElementById(id);
9218
9248
  var container = element("terminal");
@@ -9246,6 +9276,8 @@ var terminal = new Dl({
9246
9276
  var fit = new o();
9247
9277
  terminal.loadAddon(fit);
9248
9278
  terminal.open(container);
9279
+ var keyboard = element("keyboard");
9280
+ var input = bindTerminalInput(terminal.textarea, keyboard, container);
9249
9281
  function setStatus(text, state) {
9250
9282
  status.textContent = text;
9251
9283
  status.dataset.state = state;
@@ -9289,19 +9321,24 @@ font.addEventListener("change", () => {
9289
9321
  } catch {
9290
9322
  }
9291
9323
  resize();
9292
- terminal.focus();
9293
9324
  });
9294
9325
  var help = element("help-dialog");
9295
9326
  element("help").addEventListener("click", () => help.showModal());
9296
- help.addEventListener("close", () => terminal.focus());
9297
9327
  terminal.attachCustomKeyEventHandler((event) => {
9298
- if (event.key === "?") {
9299
- if (event.type === "keydown" && !help.open) help.showModal();
9328
+ if (terminal.textarea.disabled || !document.hasFocus()) return false;
9329
+ if (event.isComposing || event.keyCode === 229) return true;
9330
+ if (event.key === "Escape" || event.key === "?") {
9331
+ if (event.type === "keydown") {
9332
+ input.release();
9333
+ keyboard.focus();
9334
+ if (event.key === "?" && !help.open) help.showModal();
9335
+ }
9300
9336
  return false;
9301
9337
  }
9302
9338
  return true;
9303
9339
  });
9304
9340
  restart.addEventListener("click", () => {
9341
+ input.release();
9305
9342
  retries = 0;
9306
9343
  connect();
9307
9344
  });
@@ -9322,7 +9359,6 @@ function connect() {
9322
9359
  if (socket !== connection) return;
9323
9360
  connection.send(JSON.stringify({ type: "start", ...dimensions() }));
9324
9361
  setStatus("\u5DF2\u8FDE\u63A5 \xB7 \u7EC8\u7AEF\u5730\u56FE", "connected");
9325
- terminal.focus();
9326
9362
  });
9327
9363
  connection.addEventListener("message", (event) => {
9328
9364
  if (socket !== connection) return;
@@ -9353,12 +9389,16 @@ function connect() {
9353
9389
  });
9354
9390
  }
9355
9391
  window.addEventListener("pagehide", (event) => {
9392
+ input.release();
9356
9393
  disposed = true;
9357
9394
  clearTimeout(retryTimer);
9358
9395
  cancelAnimationFrame(resizeFrame);
9359
9396
  observer.disconnect();
9360
9397
  socket?.close();
9361
- if (!event.persisted) terminal.dispose();
9398
+ if (!event.persisted) {
9399
+ input.dispose();
9400
+ terminal.dispose();
9401
+ }
9362
9402
  });
9363
9403
  window.addEventListener("pageshow", (event) => {
9364
9404
  if (event.persisted) {
package/docs/codex.md CHANGED
@@ -66,6 +66,14 @@ changes remeasure terminal cells rather than stretching an image, and do not
66
66
  change the host's global terminal font. The terminal uses xterm.js cell rendering;
67
67
  the graphical mode remains native SVG and supports SVG export.
68
68
 
69
+ Mouse zoom, dragging and selection work immediately. To use keyboard shortcuts,
70
+ click **启用快捷键**, or Tab to that button and press Enter. The hidden terminal
71
+ input stays disabled until this explicit action. Escape, leaving the map, losing
72
+ focus or hiding the page releases keyboard input; enable it again when needed.
73
+ Loading, reconnecting and restoring the page do not activate keyboard input.
74
+ Font selection keeps its own focus; closing keyboard help returns to the
75
+ activation button without reactivating the terminal.
76
+
69
77
  Both modes use the same project maps. Terminal input/output goes over a local
70
78
  WebSocket to a dedicated mmap worker. Each connected browser owns its own
71
79
  page/zoom/selection state and renderer; there is no shared shell. Closing the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mellos-mapping",
3
- "version": "0.26.0",
3
+ "version": "0.26.2",
4
4
  "mcpName": "io.github.GuangminJu/mellos-mapping",
5
5
  "description": "A live layered dependency map for bottom-up development — MCP server + terminal pane. Ghost the design first, then light nodes up from the bottom as they are built and verified.",
6
6
  "type": "module",