mellos-mapping 0.16.0 → 0.18.0
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/README.md +6 -3
- package/README.zh-CN.md +4 -2
- package/dist/server.mjs +2 -2
- package/dist/watch.mjs +38 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -130,9 +130,12 @@ To watch the live pane beside a Codex session on Windows, run
|
|
|
130
130
|
terminal window hosting the session (or falls back to a dedicated
|
|
131
131
|
"mellos-mapping" window; `--window` picks that on purpose). Add
|
|
132
132
|
`--page <slug>` to open on a particular page — and with a pane already open,
|
|
133
|
-
rerunning with `--page` retargets it instead of opening another.
|
|
134
|
-
|
|
135
|
-
|
|
133
|
+
rerunning with `--page` retargets it instead of opening another. The pane
|
|
134
|
+
auto-follows the page being written — the map the agent is operating on
|
|
135
|
+
right now; press `f` to toggle that (a manual page switch also turns it
|
|
136
|
+
off), or start with `--no-follow`. Elsewhere run
|
|
137
|
+
`node <plugin root>/dist/watch.mjs` (same `--page` / `--no-follow` flags)
|
|
138
|
+
from the project directory in a second terminal (or any terminal split).
|
|
136
139
|
|
|
137
140
|
## Any MCP client
|
|
138
141
|
|
package/README.zh-CN.md
CHANGED
|
@@ -120,8 +120,10 @@ node ~/.codex/plugins/cache/mellos-mapping/mellos-mapping/<版本>/scripts/codex
|
|
|
120
120
|
终端窗口里分屏(识别不到就确定性地开到专属的 "mellos-mapping" 窗口;
|
|
121
121
|
`--window` 则是主动选择专属窗口)。加 `--page <slug>` 指定打开哪一页;
|
|
122
122
|
面板已经开着时,带 `--page` 重跑一次不会再开新面板,而是让现有面板
|
|
123
|
-
|
|
124
|
-
`
|
|
123
|
+
切到那一页。面板默认**自动跟随**正在被写入的页——AI 此刻操作哪张图,
|
|
124
|
+
就看哪张图;按 `f` 开关(手动切页也会关掉),或用 `--no-follow` 启动。
|
|
125
|
+
其他环境在项目目录下的第二个终端(或任意分屏)运行
|
|
126
|
+
`node <插件根>/dist/watch.mjs`(同样支持 `--page` / `--no-follow`)。
|
|
125
127
|
|
|
126
128
|
## 任意 MCP 客户端
|
|
127
129
|
|
package/dist/server.mjs
CHANGED
|
@@ -22515,7 +22515,7 @@ function summarize(map) {
|
|
|
22515
22515
|
|
|
22516
22516
|
// src/server/server.ts
|
|
22517
22517
|
var SERVER_NAME = "mellos-mapping";
|
|
22518
|
-
var SERVER_VERSION = "0.
|
|
22518
|
+
var SERVER_VERSION = "0.18.0";
|
|
22519
22519
|
var ID = external_exports.string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/, "lowercase letters, digits and dashes, 1-64 chars").describe("stable kebab-case identifier");
|
|
22520
22520
|
var PAGE = ID.optional().describe(
|
|
22521
22521
|
"page (parallel map) this call targets; omit for the default page. One effort = one page: start a NEW effort on its own page named after the effort, so concurrent sessions never write over each other and the pane can switch between pages."
|
|
@@ -22556,7 +22556,7 @@ function buildServer(stateFile) {
|
|
|
22556
22556
|
"mmap_declare",
|
|
22557
22557
|
{
|
|
22558
22558
|
title: "Declare map structure",
|
|
22559
|
-
description: "Grow the Mellos map: set the title and diagram kind, add layer bands, lanes and groups (labeled subsystems within
|
|
22559
|
+
description: "Grow the Mellos map: set the title and diagram kind, add layer bands, lanes and groups (labeled subsystems within ONE band \u2014 declare them when a single band grows crowded, roughly five or more nodes in that band; a group must be a strict subset of its band, and a map spread thin across many bands needs none), add nodes, add dependency edges. Declare the whole ghost design up front, then grow it as understanding deepens. Edges must point strictly downward (a node may only use nodes on lower layers); the batch is all-or-nothing.",
|
|
22560
22560
|
inputSchema: {
|
|
22561
22561
|
page: PAGE,
|
|
22562
22562
|
title: external_exports.string().max(120).optional().describe("map title, e.g. the feature being built"),
|
package/dist/watch.mjs
CHANGED
|
@@ -1259,6 +1259,7 @@ function parseInput(chunk) {
|
|
|
1259
1259
|
else if (ch === "-") events.push({ kind: "zoom", delta: -1 });
|
|
1260
1260
|
else if (ch === " ") events.push({ kind: "next-page" });
|
|
1261
1261
|
else if (ch === "\x7F" || ch === "\b") events.push({ kind: "back" });
|
|
1262
|
+
else if (ch === "f" || ch === "F") events.push({ kind: "follow-toggle" });
|
|
1262
1263
|
else if (ch >= "1" && ch <= "9") events.push({ kind: "page", index: ch.charCodeAt(0) - "1".charCodeAt(0) });
|
|
1263
1264
|
else if (KEY_PAN[ch]) events.push({ kind: "pan", ...KEY_PAN[ch] });
|
|
1264
1265
|
i += 1;
|
|
@@ -1274,6 +1275,7 @@ function parseArgs(argv, cwd) {
|
|
|
1274
1275
|
let color = true;
|
|
1275
1276
|
let mouse = true;
|
|
1276
1277
|
let page;
|
|
1278
|
+
let follow = true;
|
|
1277
1279
|
for (let i = 0; i < argv.length; i++) {
|
|
1278
1280
|
switch (argv[i]) {
|
|
1279
1281
|
case "--file":
|
|
@@ -1296,11 +1298,26 @@ function parseArgs(argv, cwd) {
|
|
|
1296
1298
|
case "--no-mouse":
|
|
1297
1299
|
mouse = false;
|
|
1298
1300
|
break;
|
|
1301
|
+
case "--no-follow":
|
|
1302
|
+
follow = false;
|
|
1303
|
+
break;
|
|
1299
1304
|
default:
|
|
1300
1305
|
break;
|
|
1301
1306
|
}
|
|
1302
1307
|
}
|
|
1303
|
-
return { file, intervalMs, unicode, color, mouse, page };
|
|
1308
|
+
return { file, intervalMs, unicode, color, mouse, page, follow };
|
|
1309
|
+
}
|
|
1310
|
+
function dividerRow(width, unicode, follow) {
|
|
1311
|
+
const grip = unicode ? " \u22EF " : " ~ ";
|
|
1312
|
+
let bar = (unicode ? "\u2500" : "-").repeat(width);
|
|
1313
|
+
const gripAt = Math.max(0, Math.floor((width - grip.length) / 2));
|
|
1314
|
+
if (width > grip.length + 2) bar = bar.slice(0, gripAt) + grip + bar.slice(gripAt + grip.length);
|
|
1315
|
+
if (follow) {
|
|
1316
|
+
const tag = unicode ? " \u21E2 follow " : " > follow ";
|
|
1317
|
+
const at = width - tag.length - 1;
|
|
1318
|
+
if (at > gripAt + grip.length) bar = bar.slice(0, at) + tag + bar.slice(at + tag.length);
|
|
1319
|
+
}
|
|
1320
|
+
return bar;
|
|
1304
1321
|
}
|
|
1305
1322
|
function mostRecentPageFile(files, mtimeOf) {
|
|
1306
1323
|
let best;
|
|
@@ -1678,6 +1695,7 @@ function main() {
|
|
|
1678
1695
|
let activeFile;
|
|
1679
1696
|
let firstScan = true;
|
|
1680
1697
|
let pendingFocusFile = cfg.page === void 0 ? void 0 : pageFilePath(cfg.file, cfg.page);
|
|
1698
|
+
let follow = cfg.follow;
|
|
1681
1699
|
let lastTabSegments = [];
|
|
1682
1700
|
let tabScroll = 0;
|
|
1683
1701
|
let offsetX = 0;
|
|
@@ -1744,6 +1762,10 @@ function main() {
|
|
|
1744
1762
|
};
|
|
1745
1763
|
const handSwitch = (file) => {
|
|
1746
1764
|
pendingFocusFile = void 0;
|
|
1765
|
+
if (follow) {
|
|
1766
|
+
follow = false;
|
|
1767
|
+
flash = { text: "auto-follow off \u2014 press f to re-enable", until: Date.now() + 3e3 };
|
|
1768
|
+
}
|
|
1747
1769
|
switchPage(file);
|
|
1748
1770
|
};
|
|
1749
1771
|
const hitTest = (termX, termY) => {
|
|
@@ -1805,10 +1827,7 @@ function main() {
|
|
|
1805
1827
|
} else {
|
|
1806
1828
|
panel = mapPanel(map, cfg.unicode, panelWidth, panelContentRows);
|
|
1807
1829
|
}
|
|
1808
|
-
const
|
|
1809
|
-
const bar = (cfg.unicode ? "\u2500" : "-").repeat(viewW);
|
|
1810
|
-
const gripAt = Math.max(0, Math.floor((viewW - grip.length) / 2));
|
|
1811
|
-
const separator = viewW > grip.length + 2 ? bar.slice(0, gripAt) + grip + bar.slice(gripAt + grip.length) : bar;
|
|
1830
|
+
const separator = dividerRow(viewW, cfg.unicode, follow);
|
|
1812
1831
|
const panelRows = [
|
|
1813
1832
|
cfg.color ? `\x1B[90m${separator}${RESET}` : separator,
|
|
1814
1833
|
...panel.map(
|
|
@@ -1875,6 +1894,7 @@ function main() {
|
|
|
1875
1894
|
pageViews.delete(known);
|
|
1876
1895
|
}
|
|
1877
1896
|
}
|
|
1897
|
+
const changedFiles = [];
|
|
1878
1898
|
for (const file of pageFiles) {
|
|
1879
1899
|
let mtimeMs;
|
|
1880
1900
|
try {
|
|
@@ -1886,6 +1906,7 @@ function main() {
|
|
|
1886
1906
|
if (mtimeMs === entry?.mtimeMs) continue;
|
|
1887
1907
|
const loaded = loadMapFile(file);
|
|
1888
1908
|
if (loaded.ok) {
|
|
1909
|
+
if (!firstScan) changedFiles.push(file);
|
|
1889
1910
|
const becameFresh = !firstScan && file !== activeFile;
|
|
1890
1911
|
pageData.set(file, { map: loaded.value, mtimeMs, fresh: becameFresh });
|
|
1891
1912
|
if (file === activeFile) {
|
|
@@ -1905,9 +1926,15 @@ function main() {
|
|
|
1905
1926
|
if (request !== void 0 && !(firstScan && pendingFocusFile !== void 0)) {
|
|
1906
1927
|
pendingFocusFile = pageFilePath(cfg.file, request.page);
|
|
1907
1928
|
}
|
|
1929
|
+
let requestApplied = false;
|
|
1908
1930
|
if (pendingFocusFile !== void 0 && pageFiles.includes(pendingFocusFile)) {
|
|
1909
1931
|
if (pendingFocusFile !== activeFile) switchPage(pendingFocusFile);
|
|
1910
1932
|
pendingFocusFile = void 0;
|
|
1933
|
+
requestApplied = true;
|
|
1934
|
+
}
|
|
1935
|
+
if (follow && !requestApplied && changedFiles.length > 0 && dragAnchor === void 0) {
|
|
1936
|
+
const target = mostRecentPageFile(changedFiles, (f) => pageData.get(f)?.mtimeMs);
|
|
1937
|
+
if (target !== activeFile) switchPage(target);
|
|
1911
1938
|
}
|
|
1912
1939
|
firstScan = false;
|
|
1913
1940
|
if (activeFile === void 0 || !pageFiles.includes(activeFile)) {
|
|
@@ -2076,6 +2103,11 @@ function main() {
|
|
|
2076
2103
|
case "back":
|
|
2077
2104
|
if (climbBack()) dirty = true;
|
|
2078
2105
|
break;
|
|
2106
|
+
case "follow-toggle":
|
|
2107
|
+
follow = !follow;
|
|
2108
|
+
flash = { text: follow ? "auto-follow on" : "auto-follow off", until: Date.now() + 2500 };
|
|
2109
|
+
dirty = true;
|
|
2110
|
+
break;
|
|
2079
2111
|
}
|
|
2080
2112
|
}
|
|
2081
2113
|
if (dirty) paint();
|
|
@@ -2110,6 +2142,7 @@ export {
|
|
|
2110
2142
|
anchorOffsets,
|
|
2111
2143
|
clampPanelRows,
|
|
2112
2144
|
diveOrigin,
|
|
2145
|
+
dividerRow,
|
|
2113
2146
|
fitWidth,
|
|
2114
2147
|
launchedAsEntry,
|
|
2115
2148
|
liveRipples,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mellos-mapping",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
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",
|