mellos-mapping 0.20.0 → 0.20.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/README.md +360 -63
- package/README.zh-CN.md +314 -54
- package/dist/hook-session-start.mjs +239 -0
- package/dist/mmap.mjs +338 -0
- package/dist/server.mjs +1614 -809
- package/dist/store-paths.mjs +107 -0
- package/dist/watch.mjs +1391 -760
- package/lib/domain/ops.d.ts +71 -12
- package/lib/domain/ops.js +145 -14
- package/lib/domain/types.d.ts +47 -6
- package/lib/domain/types.js +34 -3
- package/lib/render/canvas.d.ts +50 -0
- package/lib/render/canvas.js +210 -0
- package/lib/render/draw.d.ts +37 -0
- package/lib/render/draw.js +111 -0
- package/lib/render/layout.d.ts +89 -0
- package/lib/render/layout.js +200 -0
- package/lib/render/options.d.ts +39 -0
- package/lib/render/options.js +10 -0
- package/lib/render/render.d.ts +32 -46
- package/lib/render/render.js +58 -789
- package/lib/render/routing.d.ts +56 -0
- package/lib/render/routing.js +244 -0
- package/lib/render/skins.d.ts +54 -0
- package/lib/render/skins.js +99 -0
- package/lib/render/width.d.ts +24 -0
- package/lib/render/width.js +139 -0
- package/lib/render/zoom-geometry.d.ts +52 -0
- package/lib/render/zoom-geometry.js +56 -0
- package/lib/semantics/semantics.d.ts +53 -4
- package/lib/semantics/semantics.js +130 -6
- package/lib/semantics/vocabulary.d.ts +79 -0
- package/lib/semantics/vocabulary.js +112 -0
- package/lib/store/format.d.ts +17 -0
- package/lib/store/format.js +185 -66
- package/lib/store/store.d.ts +220 -20
- package/lib/store/store.js +491 -38
- package/package.json +12 -4
- package/scripts/codex-register.mjs +89 -20
- package/scripts/install-mmap-command.mjs +293 -0
- package/scripts/mmap.mjs +213 -0
- package/scripts/open-pane.mjs +115 -254
- package/scripts/pane-core.mjs +418 -0
package/README.zh-CN.md
CHANGED
|
@@ -86,7 +86,37 @@ claude plugin marketplace add GuangminJu/mellos-mapping && claude plugin install
|
|
|
86
86
|
```
|
|
87
87
|
|
|
88
88
|
需要 PATH 上有 Node.js 18+(Claude Code 本身就依赖 Node,所以你已经有了)。
|
|
89
|
-
|
|
89
|
+
没有构建步骤:`dist/` 是提交进仓库的,克隆即用——`dist/server.mjs`(MCP
|
|
90
|
+
服务器)、`dist/watch.mjs`(面板)、`dist/mmap.mjs`(`mmap` 开关)、
|
|
91
|
+
`dist/hook-session-start.mjs`(由 `hooks/hooks.json` 注册的 `SessionStart`
|
|
92
|
+
钩子),以及 `dist/store-paths.mjs`(存储的路径词汇;纯 node 的面板启动
|
|
93
|
+
脚本从这里导入,而不是自己抄一份文件名)。
|
|
94
|
+
|
|
95
|
+
装完之后的第一个会话只会问你**一个**问题——建图要多积极——并把答案记成
|
|
96
|
+
你以后打开的每一个项目的默认。此后钩子会自己把它带进每个新会话;再也没有
|
|
97
|
+
"每个项目设置一遍"这回事。见
|
|
98
|
+
[Setup:选择什么时候建图](#setup选择什么时候建图)。
|
|
99
|
+
|
|
100
|
+
`mmap` 终端命令(面板的开关切换)在 Windows 上会自己装好:还是这个钩子,
|
|
101
|
+
在会话启动时发现 shim 缺失或者还指向旧版本安装,就把 `mmap.cmd`(cmd、
|
|
102
|
+
PowerShell)和 `mmap`(git-bash)写进 `%LOCALAPPDATA%\mellos-mapping\bin`,
|
|
103
|
+
把这一个目录追加进你的**用户** PATH,并通过助手告诉你这件事。PATH 改动
|
|
104
|
+
只对新进程生效——而且运行中的 Windows Terminal 连新标签页都继承旧环境,
|
|
105
|
+
所以第一次敲 `mmap` 之前要把终端应用整个关掉重开。PATH 的编辑保持安装器
|
|
106
|
+
原有的承诺:条目已经在里面
|
|
107
|
+
就什么都不做;遇到 `setx` 会损坏的 PATH(`%VARIABLE%` 被展平、超长被截
|
|
108
|
+
断),它干脆拒绝,改为把要手动添加的条目说清楚。
|
|
109
|
+
|
|
110
|
+
它背后的那一步仍然是个独立命令,留给钩子管不到的情形——`--uninstall`,
|
|
111
|
+
或者 shim 还在、PATH 条目却被你删掉之后重新加回去:
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
node "<插件目录>/scripts/install-mmap-command.mjs" [--uninstall]
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
(`--json` 把安装结果打成一行 JSON 而不是散文——钩子自己调用它时用的就是
|
|
118
|
+
这个模式。)`npm i -g mellos-mapping` 通过 `bin` 提供同一个 `mmap`,不涉及
|
|
119
|
+
shim。
|
|
90
120
|
|
|
91
121
|
## 更新
|
|
92
122
|
|
|
@@ -98,6 +128,27 @@ claude plugin marketplace update mellos-mapping && claude plugin update mellos-m
|
|
|
98
128
|
拉取本仓库的是第一条命令。重启 Claude Code 生效。发布即 `master` 分支
|
|
99
129
|
上的版本号提升。(在对话里输入 `/plugin` 也能打开同一个管理界面。)
|
|
100
130
|
|
|
131
|
+
### 从 0.19 升级
|
|
132
|
+
|
|
133
|
+
0.20 把地图存储从 `.claude/` 挪到了 `.mellos/`——地图属于这个工具,不属于
|
|
134
|
+
某一个客户端。服务器和 watcher 都会在启动时做一次搬迁,并在 stderr 打**一行**
|
|
135
|
+
提示(`mellos-mapping: moved the legacy .claude map store to .mellos/ — commit
|
|
136
|
+
the move.`):
|
|
137
|
+
|
|
138
|
+
| 0.19 及更早 | 0.20 及之后 |
|
|
139
|
+
| --- | --- |
|
|
140
|
+
| `.claude/mellos-mapping.json` | `.mellos/map.json` |
|
|
141
|
+
| `.claude/mellos-mapping.pages/` | `.mellos/pages/` |
|
|
142
|
+
| `.claude/mellos-mapping.config.json` | `.mellos/config.json` |
|
|
143
|
+
|
|
144
|
+
搬迁不合并、也不覆盖:`.mellos/` 里已经有东西(地图、页目录或配置)的项目
|
|
145
|
+
原样不动,无论旧目录里还剩什么。如果地图跟着 git 走,记得把这次搬迁提交
|
|
146
|
+
上去——`git add -A .claude .mellos` 会把它记成重命名,而不是一堆删除加一堆
|
|
147
|
+
未跟踪文件。
|
|
148
|
+
|
|
149
|
+
这一次搬迁是两个进程唯一会碰 `.claude/` 的时刻。此后工具只往 `.mellos/`
|
|
150
|
+
里写,也绝不会写到启动时解析出的项目目录之外。
|
|
151
|
+
|
|
101
152
|
## Codex CLI
|
|
102
153
|
|
|
103
154
|
同一个仓库也是 Codex 插件(codex-cli 0.147+)。三行装完:
|
|
@@ -123,7 +174,8 @@ node ~/.codex/plugins/cache/mellos-mapping/mellos-mapping/<版本>/scripts/codex
|
|
|
123
174
|
切到那一页。面板默认**自动跟随**正在被写入的页——AI 此刻操作哪张图,
|
|
124
175
|
就看哪张图;按 `f` 开关(手动切页也会关掉),或用 `--no-follow` 启动。
|
|
125
176
|
其他环境在项目目录下的第二个终端(或任意分屏)运行
|
|
126
|
-
`node <插件根>/dist/watch.mjs
|
|
177
|
+
`node <插件根>/dist/watch.mjs`。两者接受同一套参数,见
|
|
178
|
+
[面板参数](#面板参数)。
|
|
127
179
|
|
|
128
180
|
## 任意 MCP 客户端
|
|
129
181
|
|
|
@@ -141,18 +193,26 @@ npx -y mellos-mapping
|
|
|
141
193
|
npx -y -p mellos-mapping mellos-mapping-watch
|
|
142
194
|
```
|
|
143
195
|
|
|
144
|
-
|
|
196
|
+
服务器按这个顺序确定项目目录:`MELLOS_MAPPING_CWD`(显式覆盖,给那些会
|
|
197
|
+
在固定目录里拉起服务器的客户端用)、`CLAUDE_PROJECT_DIR`(Claude Code 为
|
|
198
|
+
插件 MCP 服务器设置的约定),最后才是服务器进程自己的工作目录。如果你的
|
|
199
|
+
客户端会在你实际工作的项目之外启动服务器,就设 `MELLOS_MAPPING_CWD`。
|
|
200
|
+
|
|
201
|
+
技能/纪律层是 Claude Code 与 Codex 专属的;其他客户端获得五个 `mmap_*`
|
|
145
202
|
工具和面板,提示词自备。
|
|
146
203
|
|
|
147
204
|
## 使用
|
|
148
205
|
|
|
149
206
|
1. 让 Claude 构建一个非平凡的东西。捆绑的 skill 会让 Claude 先声明幽灵
|
|
150
207
|
设计,并在工作过程中保持地图与现实一致。
|
|
151
|
-
2.
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
208
|
+
2. 面板会自己打开。每一次写入都会告诉 Claude 到底有没有人在看
|
|
209
|
+
(见[谁在看](#谁在看));没人看的时候,Claude 用 `mmap_open` 自己
|
|
210
|
+
把面板开出来或切到该看的那一页——你不需要记着去开它。想自己开关,
|
|
211
|
+
在任意终端敲 `mmap`,或者在对话里用 `/mellos-mapping:mmap`
|
|
212
|
+
(Windows 上是 Windows Terminal 分屏,tmux 里是 tmux 分屏,其他
|
|
213
|
+
环境会打印一条命令让你在第二个终端里运行)。Windows 上即使开着多个
|
|
214
|
+
终端窗口,分屏也会落在**你的会话所在的窗口**;想让地图独占一个窗口
|
|
215
|
+
就加 `--window`。字体缺少制表符字形时用 `--ascii`。
|
|
156
216
|
3. 看着节点从底部一路亮起。图让你不安的时候就打断它——这正是它存在的
|
|
157
217
|
意义。
|
|
158
218
|
|
|
@@ -166,22 +226,31 @@ npx -y -p mellos-mapping mellos-mapping-watch
|
|
|
166
226
|
| 滚轮 / `+` `-` | 缩放,以焦点节点为锚(阶梯见下) |
|
|
167
227
|
| 按住左键拖动 | 地图超出面板时抓取平移 |
|
|
168
228
|
| shift+滚轮 | 垂直滚动 |
|
|
229
|
+
| 滚轮横向拨动 | 左右平移 |
|
|
169
230
|
| `hjkl` / 方向键 | 微移视口 |
|
|
170
231
|
| `Tab` / `Shift+Tab` / `1-9` / 点击标签 | 切换页(并行的多张地图) |
|
|
232
|
+
| 在标签行上滚轮 / 点击 `‹` `›` | 浏览放不下的标签栏,但不切页 |
|
|
233
|
+
| `f` | 开关自动跟随(见[页](#页)) |
|
|
234
|
+
| `x`,或点击当前标签上的 `×` | 请求删除屏幕上这一页;在确认窗口内再按一次,它的文件就被删掉(见[页](#页)) |
|
|
171
235
|
| 双击带 `⊞` 的节点 | 下潜进它的子图(一个子页面) |
|
|
172
236
|
| `Backspace` / `Esc` | 从上一次下潜爬回父图 |
|
|
173
237
|
| 拖动 `⋯` 分隔线 | 调整详情面板高度——向上拉,完整阅读长设计笔记 |
|
|
174
238
|
| `0` | 重置平移和缩放 |
|
|
175
|
-
| `q` | 退出面板 |
|
|
239
|
+
| `q` / `Ctrl+C` | 退出面板 |
|
|
240
|
+
|
|
241
|
+
其他按键一律无效,这是有意的:面板不认识的转义序列(F 键、Home/End、
|
|
242
|
+
PgUp/PgDn、Insert/Delete、带修饰的方向键)会被整段吞掉、什么都不做,
|
|
243
|
+
而不是让它的载荷字节被当成热键读进来。
|
|
176
244
|
|
|
177
245
|
缩放先做几何缩小,只在阶梯两端才切换显示模式——每一级都能看到有意义的
|
|
178
246
|
数据:
|
|
179
247
|
|
|
180
248
|
```
|
|
181
|
-
细读 ← 100% ← 85% ← 70% ← 55% ← 概览
|
|
249
|
+
细读+ ← 细读 ← 100% ← 85% ← 70% ← 55% ← 概览
|
|
182
250
|
```
|
|
183
251
|
|
|
184
|
-
- **放大过 100
|
|
252
|
+
- **放大过 100%**——`detail` 在盒子里展开验证证据和设计笔记的前三行;
|
|
253
|
+
`detail+` 把盒子撑成一张阅读卡(最多十二行笔记);
|
|
185
254
|
- **85–55%**——留白收紧、标签按比例截断,盒子还是盒子;
|
|
186
255
|
- **低于 55%**——标签已短到无意义,此时地图**聚合**:每个已声明的分组
|
|
187
256
|
(层内的具名子系统)变成一个盒子,如 `地基子系统 1/2`,状态由成员推导,
|
|
@@ -189,24 +258,117 @@ npx -y -p mellos-mapping mellos-mapping-watch
|
|
|
189
258
|
把城市变成无名光点。(没有声明分组的地图退化为纯字形星座 + 每层计数。)
|
|
190
259
|
页脚始终显示当前级别。
|
|
191
260
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
261
|
+
地图下方、提示行之上,是一块**固定高度**的详情面板:一条可拖动的分隔线、
|
|
262
|
+
一行按状态着色的表头、焦点节点的验证证据、两个方向的连线(`uses → … ·
|
|
263
|
+
used by ← …`,每个邻居各带自己的状态字形),以及自动折行的设计笔记。没有
|
|
264
|
+
焦点时显示整图的仪表盘。高度固定——详情不会悬浮遮挡地图,版面也不会跳。
|
|
265
|
+
|
|
266
|
+
### 字形
|
|
267
|
+
|
|
268
|
+
一个状态一个字形,画地图的地方都一样——面板里的盒子、标签栏、详情面板,
|
|
269
|
+
以及任何读同一份存储的客户端:
|
|
270
|
+
|
|
271
|
+
| Unicode | ASCII | 含义 |
|
|
272
|
+
| --- | --- | --- |
|
|
273
|
+
| `·` | `.` | planned——已声明,未开工 |
|
|
274
|
+
| `⠿` | `*` | in-progress 的静止形态——能做动画的盒子转的是盲文帧 `⠋⠙⠹…`,ASCII 下是四帧的转杠 |
|
|
275
|
+
| `■` | `#` | done,且有证据 |
|
|
276
|
+
| `□` | `o` | done,但**没有**记录证据——同一个断言,背后空无一物 |
|
|
277
|
+
| `✗` | `X` | regressed:曾经 done,现在坏了 |
|
|
278
|
+
| `⊞` | `+` | 徽标:这个节点链着子图,双击下潜 |
|
|
279
|
+
|
|
280
|
+
图下方的图例列出四个状态;`□ done, no evidence` 只在这张图里真的出现了
|
|
281
|
+
这种节点时才加入——四个状态是词汇表,那一个是此时此地正在被违反的规则。
|
|
282
|
+
文档型图种用节点 kind 的字形取代状态图例。
|
|
283
|
+
|
|
284
|
+
### 面板参数
|
|
285
|
+
|
|
286
|
+
面板启动脚本(`scripts/open-pane.mjs <项目目录>`)和 watcher
|
|
287
|
+
(`dist/watch.mjs`)接受同一套 watcher 参数;启动脚本原样转发它们,遇到
|
|
288
|
+
不认识的参数会报错,而不是悄悄丢掉。
|
|
289
|
+
|
|
290
|
+
| 参数 | 作用 |
|
|
291
|
+
| --- | --- |
|
|
292
|
+
| `--page <slug>` | 打开时定位到这一页;已经有面板在跑时,改为让那个面板切过去,而不是再开一个 |
|
|
293
|
+
| `--ascii` | 纯 ASCII 字形,给缺制表符字形的字体用 |
|
|
294
|
+
| `--no-color` | 不输出 ANSI 颜色 |
|
|
295
|
+
| `--no-mouse` | 关闭鼠标上报,把鼠标留给你的终端复用器 |
|
|
296
|
+
| `--no-follow` | 启动时就关掉自动跟随 |
|
|
297
|
+
| `--interval <ms>` | 轮询间隔,缺省 250,下限 50 |
|
|
298
|
+
|
|
299
|
+
只属于启动脚本的:`--window` 直接开到专属的 "mellos-mapping" 窗口而不是
|
|
300
|
+
在会话窗口里分屏,`--force` 即使本项目已有面板在跑也再开一个。只属于
|
|
301
|
+
watcher 的:`--file <path>` 指定默认页的状态文件(启动脚本会从项目目录
|
|
302
|
+
自己推导出来)。
|
|
303
|
+
|
|
304
|
+
### mmap 命令
|
|
305
|
+
|
|
306
|
+
在任何终端里敲 `mmap`,它是一个**开关**:本项目还没有面板就开一个,已经
|
|
307
|
+
有面板就把它关掉。
|
|
195
308
|
|
|
196
|
-
|
|
309
|
+
| 你敲的 | 发生什么 |
|
|
310
|
+
| --- | --- |
|
|
311
|
+
| `mmap` | 本项目没有面板在跑 → 开一个;有 → 关掉它 |
|
|
312
|
+
| `mmap <页 slug>` | 打开时定位到这一页,或者让已开的面板切过去——永远不关 |
|
|
313
|
+
| `mmap --window` | 开到专属的 "mellos-mapping" 窗口,而不是把当前窗口分屏 |
|
|
314
|
+
| `mmap --force` | 即使已经有面板在跑也再开一个 |
|
|
315
|
+
|
|
316
|
+
项目是像 git 找仓库根那样找出来的:从当前目录往上走,找最近一个含
|
|
317
|
+
`.mellos/` 存储的目录。站在一个还没有地图的项目里也没问题——面板会开在
|
|
318
|
+
待机画面上,等第一次 `mmap_declare`。
|
|
319
|
+
|
|
320
|
+
关闭走的是存储,不是信号:`mmap` 在地图旁边写一份一次性请求,面板在下一次
|
|
321
|
+
轮询(缺省 250 毫秒)时消费掉它并退出,并把终端原样还回去——关掉鼠标上报、
|
|
322
|
+
恢复光标。还停在待机画面上的面板也一样关得掉。请求读到即删;上一个面板死掉
|
|
323
|
+
留下的残留会在下一个面板启动时被清扫,所以过期的请求永远关不掉新面板。
|
|
324
|
+
|
|
325
|
+
上面每一个 watcher 参数在这里同样有效,原样转发;不认识的参数会报用法错误,
|
|
326
|
+
绝不悄悄丢掉。除非你装的是 npm 包,否则 `mmap` 需要
|
|
327
|
+
[装一次](#安装)。在 Claude Code 对话里,`/mellos-mapping:mmap` 打开的是
|
|
328
|
+
同一个面板。
|
|
197
329
|
|
|
198
330
|
### 页
|
|
199
331
|
|
|
200
332
|
一个项目可以并排保有多张地图——**一个工作努力 = 一页**。Claude 在任何
|
|
201
333
|
`mmap_*` 工具里传 `page` 参数即可定向到某页;出现第二页时面板顶部自动长出
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
334
|
+
标签栏。当前页加粗、按整图状态着色。每页记住自己的平移/缩放/钉住状态。
|
|
335
|
+
|
|
336
|
+
面板默认**自动跟随正在被写入的那一页**——AI 此刻在操作哪张图,就看哪张图,
|
|
337
|
+
于是 declare 和 update 自己就把观众带过去了。按 `f` 开关,手动切页也会关掉
|
|
338
|
+
它,`--no-follow` 则是一开始就关着;跟随关掉之后,后台页有变化时它的标签会
|
|
339
|
+
亮起状态色提示你,而不是抢走你的视线。显式的 `--page` 优先级高于跟随;请求
|
|
340
|
+
一个还不存在的页会一直挂着,等它出现的那一刻显示出来。
|
|
341
|
+
|
|
342
|
+
**删除一页。** 一件事做完了,它那一页不必留着。在面板里按 `x`——或者点击
|
|
343
|
+
当前标签上的 `×`(开着鼠标时才画)——只是**发问**:页脚出现
|
|
344
|
+
`press x again to delete <页>`,三秒内再按一次,这一页的文件就被删掉。切页、
|
|
345
|
+
`Esc`、或者干脆等它过期,请求就收回了。`×` 只长在当前标签上,所以点一个
|
|
346
|
+
非当前标签是先切过去,下一帧它才带上自己的 `×`。工具那边是
|
|
347
|
+
`mmap_remove {pages: ["slug", …]}`,在这次调用的地图修改**之后**执行。两条
|
|
348
|
+
路都一样:文件是真的没了——地图是纯 JSON,提交进 git 是唯一的后悔药。
|
|
206
349
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
350
|
+
地图状态存在项目根目录下、属于本工具的 `.mellos/` 目录里:
|
|
351
|
+
|
|
352
|
+
| 路径 | 是什么 |
|
|
353
|
+
| --- | --- |
|
|
354
|
+
| `.mellos/map.json` | 默认页——可选;工作全在命名页上的项目根本没有这个文件 |
|
|
355
|
+
| `.mellos/pages/<slug>.json` | 一个命名页一个文件 |
|
|
356
|
+
| `.mellos/config.json` | 本项目的建图策略(见 [Setup](#setup选择什么时候建图)) |
|
|
357
|
+
| `.mellos/focus` | 启动脚本发给运行中面板的一次性"切到这一页"请求;面板在一个轮询周期内消费并删除它 |
|
|
358
|
+
| `.mellos/quit` | `mmap` 开关发出的一次性"自己关掉"请求,以同样的方式被消费和删除 |
|
|
359
|
+
| `.mellos/viewers/<pid>.json` | 每个活着的面板一份报告——它正显示哪一页、自动跟随是否打开——运行期间每秒刷新一次(见[谁在看](#谁在看)) |
|
|
360
|
+
| `<上面任一文件>.<pid>.<随机>.tmp` | 正在落盘的一次写入;它要么被改名覆盖目标,要么被删掉。留下来说明那次写入失败(并已被报告),连清理都没能跑成 |
|
|
361
|
+
|
|
362
|
+
地图文件是纯 JSON,想在 git 里留下地图的历史就把它们提交进去。另外三个是
|
|
363
|
+
面板和跟它说话的人之间的运行期闲聊——如果你要提交这个仓库,把 `focus`、
|
|
364
|
+
`quit` 和 `viewers/` 加进 gitignore。
|
|
365
|
+
|
|
366
|
+
**并发模型,直说。** 每次保存都是原子的——先写进一个私有的同级临时文件,
|
|
367
|
+
再改名覆盖目标——所以轮询存储的读者要么看到上一张完整的地图,要么看到新的
|
|
368
|
+
那张,绝不会读到写了一半的。但**没有丢失更新保护**:两个写者保存*同一页*
|
|
369
|
+
就是在赛跑,最后那次改名赢,另一个基于旧读取算出来的东西被静默丢弃。页就是
|
|
370
|
+
隔离单位——不许互相覆盖的两个会话,就该在两页上,这也是同一项目里跑多个
|
|
371
|
+
Claude 会话的正确姿势。
|
|
210
372
|
|
|
211
373
|
### 图种
|
|
212
374
|
|
|
@@ -230,7 +392,10 @@ npx -y -p mellos-mapping mellos-mapping-watch
|
|
|
230
392
|
下潜进子图,`Backspace` 爬回父图。图中图,完全由页组合而成:没有新存储、
|
|
231
393
|
没有新不变量。一个节点值不值得配子图,由 AI 自行判断——大多数不需要。
|
|
232
394
|
|
|
233
|
-
|
|
395
|
+
子图是节点的内部细节,不是兄弟页:被*别的*页潜进去的页**不占标签栏**。
|
|
396
|
+
有两条修正保证标签栏不会把自己抹掉——节点指向自己所在页的,谁也不藏;
|
|
397
|
+
链接成环的一组页保留各自的标签,除非环外有页潜进来,因为环本身没有"外面"
|
|
398
|
+
可以爬回去。下潜
|
|
234
399
|
之后标签行变成面包屑——`⌫ 父图 ▸ 节点`——点击它(或按 `Backspace`)爬
|
|
235
400
|
回去。隐藏的子图在后台有变化时,底栏会提示。
|
|
236
401
|
|
|
@@ -238,59 +403,154 @@ npx -y -p mellos-mapping mellos-mapping-watch
|
|
|
238
403
|
|
|
239
404
|
| 工具 | 用途 |
|
|
240
405
|
| --- | --- |
|
|
241
|
-
| `mmap_declare` |
|
|
242
|
-
| `mmap_update` |
|
|
243
|
-
| `mmap_remove` |
|
|
244
|
-
| `mmap_view` | 把当前地图渲染成文本,直接在对话里看(可选 `zoom`
|
|
406
|
+
| `mmap_declare` | 生长地图:标题(传 `null` 删掉)、图种、层级横条、泳道、分组(子系统)、节点(可带 `status`、`evidence`、`detail`、`kind`、`group`、`lane`、`submap`)、边(可带标签);批量,全有或全无 |
|
|
407
|
+
| `mmap_update` | 记录进度**并修订**:状态(`planned → in-progress → done` 附证据、`regressed`)、改节点标签、把节点搬到另一层(`layer`)、加入/退出分组或泳道、设节点 kind 或 `submap`;给层改名和改 rank(`layers`)、给分组改标签(`groups`)、给泳道改标签(`lanes`);任何可清空的字段传 `null` 即清空 |
|
|
408
|
+
| `mmap_remove` | 修订:删除边、节点、分组、泳道、空层——以及用 `pages` 删掉整页,连文件一起(永久;在本次调用的地图修改之后执行) |
|
|
409
|
+
| `mmap_view` | 把当前地图渲染成文本,直接在对话里看(可选 `zoom`,`-4`…`2`);每次响应结尾都有一行 `pages:`,列出本项目有哪些页、以及你正在看哪一页 |
|
|
245
410
|
| `mmap_setup` | 查/设本项目的建图策略——什么时候开地图 |
|
|
411
|
+
| `mmap_open` | 把地图放到你屏幕上:开面板,或把已开的面板切到某一 `page`(`window: true` 用独立窗口)。它回答的是"事后有没有面板真的报到",而不只是"命令跑过了"——而且它永远关不掉面板 |
|
|
412
|
+
|
|
413
|
+
一个批次的施加顺序是 层 → 分组 → 泳道 → 节点更新;同一条节点更新里
|
|
414
|
+
`layer` 先于其他字段生效,所以一个节点可以在一条更新里搬层并加入新层上的
|
|
415
|
+
分组。
|
|
416
|
+
|
|
417
|
+
边界会拒绝下面这些,好让账本不会记下它并不想记的东西:
|
|
418
|
+
|
|
419
|
+
- **不认识的键**,并把键名说出来——拼错的 `evidance` 是错误,不是被悄悄
|
|
420
|
+
丢掉的字段;任何嵌套深度都一样;
|
|
421
|
+
- 文本字段里的**控制字符**——藏在标签里的 ESC 序列,会让这张图重绘每一个
|
|
422
|
+
打开它的人的终端。`detail` 是例外:换行和制表符本来就是写笔记的方式,
|
|
423
|
+
其余(ESC、BEL、单独的 CR)照样拒绝;
|
|
424
|
+
- 可选字段上的**空字符串**——清空字段用 `null`,而不是一个渲染出来跟真盒子
|
|
425
|
+
分不清的空白;
|
|
426
|
+
- **`submap` 指向本次调用所针对的那一页的节点**——那是个没有底的环,不是
|
|
427
|
+
指向父图的链接;
|
|
428
|
+
- **删页请求指向本次调用自己所针对的那一页,或者指向本项目根本没有的
|
|
429
|
+
slug**——一次调用不能一边改一张图一边删掉它;而对不上任何一页的名字,
|
|
430
|
+
是拼错的概率远大于"刚被别人删了",拒绝时会把真实存在的页列出来。
|
|
431
|
+
|
|
432
|
+
没有落盘的写入回答 `save failed, nothing changed (retry)`:之前的文件完好
|
|
433
|
+
无损,重试一次就是全部的恢复手段。
|
|
434
|
+
|
|
435
|
+
### 谁在看
|
|
436
|
+
|
|
437
|
+
没人开在屏幕上的地图不是地图,是文件——而系统以前根本分不出这两者。
|
|
438
|
+
助手声明幽灵设计、一个个把节点点亮,然后把这一切写进一个你从来没打开过
|
|
439
|
+
面板的仓库里。
|
|
440
|
+
|
|
441
|
+
现在每个面板在运行期间都会发布一份小小的报告——`.mellos/viewers/`,
|
|
442
|
+
一个面板一个文件,每秒刷新一次——而每一次写入、每一次查看的结尾,都会
|
|
443
|
+
把这些报告说出来:
|
|
444
|
+
|
|
445
|
+
| 这一行 | 意思 |
|
|
446
|
+
| --- | --- |
|
|
447
|
+
| `pane: CLOSED` | 没人在看这张图;助手会用 `mmap_open` 自己开,而不是回过头来要求你开 |
|
|
448
|
+
| `pane: open on this page` | 你正看着它落地 |
|
|
449
|
+
| `pane: open on <其他页>, auto-follow on` | 面板跟随最后被写入的那一页,它自己会过来 |
|
|
450
|
+
| `pane: open on <其他页>, auto-follow OFF` | 那一页是你亲手钉住的:这次改动是真的,但**不在**你屏幕上。助手被要求把这件事说出来,而不是把你的视图搬走 |
|
|
451
|
+
|
|
452
|
+
同一批报告也回答了 `mmap` 和启动脚本要问的"面板是不是已经开着"——这个
|
|
453
|
+
问题以前得靠一次只有 Windows 才有的进程扫描,而且答不出屏幕上是哪一页。
|
|
454
|
+
超过五秒没被刷新的报告不再算数,超过一分钟就被读到它的人删掉,所以被强杀
|
|
455
|
+
的面板不会一直冒领观众。
|
|
246
456
|
|
|
247
457
|
### Setup:选择什么时候建图
|
|
248
458
|
|
|
249
|
-
|
|
250
|
-
|
|
459
|
+
建图要多积极,是一个人的工作习惯,不是某个仓库的属性——所以它**只为你选
|
|
460
|
+
一次**,就在你装完之后的第一个会话里:
|
|
251
461
|
|
|
252
|
-
- `always` —— 任何有结构的任务都建图:流程、设计、架构、技术依赖。
|
|
253
|
-
|
|
254
|
-
- `
|
|
462
|
+
- `always` —— 任何有结构的任务都建图:流程、设计、架构、技术依赖。AI 会
|
|
463
|
+
主动开面板;你记下的这个答案就是它的长期授权,它不会再问。
|
|
464
|
+
- `complex` —— 同样的做法,但只用在中等或复杂任务上:牵涉多个模块、一个
|
|
465
|
+
新子系统,大约一小时以上的活。
|
|
466
|
+
- `on-request` —— 只在你明确要求时建图。在还没有地图的项目里,插件对此
|
|
467
|
+
一个字都不说——零噪音就是目的。
|
|
255
468
|
|
|
256
|
-
|
|
257
|
-
|
|
469
|
+
答案落在 `<你的用户目录>/.mellos/config.json`,并通过插件的 `SessionStart`
|
|
470
|
+
钩子进入每一个会话:钩子把它读出来,在你敲下第一个字之前就把对应的指令交给
|
|
471
|
+
AI。从此再也不需要按项目设置什么。
|
|
258
472
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
473
|
+
单个项目仍然可以不一样:`mmap_setup {policy, scope: "project"}` 把策略写进
|
|
474
|
+
那个项目的 `.mellos/config.json`,项目策略压过用户策略。想改主意时,
|
|
475
|
+
`/mmap setup` 会把这个问题按任一作用域重新问一遍。策略只是引导 AI;它从不
|
|
476
|
+
阻止工具本身——无论什么策略,明确要求建图永远有效。
|
|
477
|
+
|
|
478
|
+
没有钩子的宿主(Codex CLI、裸 MCP 客户端)用另一条路拿到这个问题:只要两个
|
|
479
|
+
作用域里都还没有策略,每一次 `mmap_declare` 的响应都会带一条提示,让 AI 来
|
|
480
|
+
问你。你在任何一个作用域答完之后,这条提示就永远闭嘴了——在每一个项目里。
|
|
481
|
+
|
|
482
|
+
工具强制的结构不变量:层按 rank 构成全序(rank 是 0..99 的整数,0 在最底,
|
|
483
|
+
一张图里不许重复);每个节点恰好属于一层;边**严格向下**——因此图从构造上
|
|
484
|
+
就是无环的;节点不能依赖同层兄弟(如果 A 需要兄弟 B,要么 B 其实是更低层的
|
|
485
|
+
概念,要么 A 和 B 本来就是一个节点);分组只在一层之内聚拢节点;节点 id 和
|
|
486
|
+
分组 id 共用**同一个命名空间**——一个 id 要么命名节点、要么命名分组,绝不
|
|
487
|
+
两者兼有,因为它们都渲染成盒子,一个 id 必须只意味着一个盒子。
|
|
262
488
|
|
|
263
489
|
## 开发
|
|
264
490
|
|
|
265
491
|
```
|
|
266
492
|
npm install
|
|
267
|
-
npm run verify
|
|
493
|
+
npm run verify
|
|
268
494
|
```
|
|
269
495
|
|
|
496
|
+
`verify` 是按顺序的五步:`typecheck`(本仓库自己的源码)、
|
|
497
|
+
`typecheck:packages`(dsh 插件包里不依赖框架的模块,且把 `mellos-mapping/*`
|
|
498
|
+
指向本仓库源码)、`test`、`build`(打包 `dist/`、产出带声明的 `lib/`,两个
|
|
499
|
+
目录都先清空),以及 `check:package`——它按真实的 `prepack` 生命周期打出
|
|
500
|
+
tarball,只要 `exports` 或 `bin` 里有任何目标没被打进去就失败。
|
|
501
|
+
|
|
270
502
|
这个仓库本身就是自下而上分层的,每一层都有自己的规格测试:
|
|
271
503
|
|
|
272
|
-
| 层 | 代码 | 职责 |
|
|
273
|
-
| --- | --- | --- |
|
|
274
|
-
| 0 domain | `src/domain/` | 地图值、结构不变量、纯操作 |
|
|
275
|
-
| 1 format | `src/store/format.ts` | 状态文件格式:重放校验的解析与序列化,零 I/O |
|
|
276
|
-
| 1 store | `src/store/store.ts` | Node 上的原子化状态文件持久化 |
|
|
277
|
-
| 1 semantics | `src/semantics/` |
|
|
278
|
-
| 2 apply | `src/server/apply.ts` | 工具输入 → 事务性操作序列 |
|
|
279
|
-
| 3 server | `src/server/server.ts` | stdio
|
|
280
|
-
| 4 render | `src/render
|
|
504
|
+
| 层 | 代码 | 规格 | 职责 |
|
|
505
|
+
| --- | --- | --- | --- |
|
|
506
|
+
| 0 domain | `src/domain/` | `ops.test.ts` | 地图值、结构不变量、纯操作 |
|
|
507
|
+
| 1 format | `src/store/format.ts` | `store.test.ts` | 状态文件格式:重放校验的解析与序列化,零 I/O |
|
|
508
|
+
| 1 store | `src/store/store.ts` | `store.test.ts`、`atomic-save.test.ts` | Node 上的原子化状态文件持久化 |
|
|
509
|
+
| 1 semantics | `src/semantics/` | `semantics.test.ts` | 媒介无关的视图语义:缩放阶梯、分组聚合、页集规则、时序翻转、共享字形词汇表 |
|
|
510
|
+
| 2 apply | `src/server/apply.ts` | `apply.test.ts` | 工具输入 → 事务性操作序列 |
|
|
511
|
+
| 3 server | `src/server/server.ts` | `server.test.ts`、`save-failure.test.ts` | stdio 上的五个 MCP 工具 |
|
|
512
|
+
| 4 render | `src/render/` | `render.test.ts`、`routing.test.ts` | ASCII 渲染器与它的走线 |
|
|
513
|
+
| 4 pane | `src/watch/` | `watch.test.ts`、`pane-state.test.ts`、`input.test.ts` | 轮询面板:页集、输入解析、详情面板与外框 |
|
|
514
|
+
| — 启动脚本 | `scripts/` | `open-pane.test.mjs`、`codex-register.test.mjs` | 纯 node 的入口 |
|
|
515
|
+
| — 打包 | `package.json`、`packages/` | `tests/lockfile.test.ts`、`tests/packages.test.ts`、`browser-safe.test.ts` | 发出去的是什么、发给谁 |
|
|
281
516
|
|
|
282
517
|
`dist/` 是刻意提交的:插件安装就是克隆本仓库、不运行任何东西,所以入口
|
|
283
|
-
文件以打包形式随仓库分发。
|
|
518
|
+
文件以打包形式随仓库分发。CI 会把提交的 `dist/` 和一次全新构建做 diff,
|
|
519
|
+
所以改了源码却忘了重新构建会直接失败。
|
|
520
|
+
|
|
521
|
+
### dsh 插件包
|
|
522
|
+
|
|
523
|
+
`packages/dsh` 与 `packages/dsh-client` 是 DeepSeek Harness 的那一面:一个
|
|
524
|
+
读取并监视工作区 `.mellos/` 存储的宿主插件,加上用同一套语义作画的浏览器
|
|
525
|
+
地图面板。它们在 dsh workspace 检出里*开发*(由那边的工具链构建),从这里
|
|
526
|
+
*发布*——源码、规格测试和 `lib/` 都提交在这儿,用
|
|
527
|
+
`node scripts/sync-dsh-plugin.mjs <deepseek-harness 检出路径>` 刷新,该脚本
|
|
528
|
+
会把 dsh 内部包名改写成发布用的名字。本仓库构建不了它们,所以只证明它能
|
|
529
|
+
证明的:`typecheck:packages` 和不依赖框架的规格测试在 CI 里跑,
|
|
530
|
+
`tests/packages.test.ts` 守住 src↔lib 的结构、共享版本线和 MCP 行的拉起
|
|
531
|
+
方式。需要 `@deepseek-ai` 框架或 DOM 的规格测试连同理由一起写在
|
|
532
|
+
`vitest.config.ts` 里。详见
|
|
533
|
+
[`packages/dsh/README.md`](packages/dsh/README.md)。
|
|
284
534
|
|
|
285
535
|
### 库
|
|
286
536
|
|
|
287
537
|
底部各层同时是一个库(`npm run build` 产出带类型声明的 `lib/`,npm 打包
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
538
|
+
收录)。子路径导出与源码结构一一对应:
|
|
539
|
+
|
|
540
|
+
| 子路径 | 内容 | 浏览器安全 |
|
|
541
|
+
| --- | --- | --- |
|
|
542
|
+
| `mellos-mapping/domain/types` | 地图值、id、rank、状态、错误 | 是 |
|
|
543
|
+
| `mellos-mapping/domain/ops` | 地图上的纯操作 | 是 |
|
|
544
|
+
| `mellos-mapping/format` | 状态文件的解析/序列化、页 id | 是 |
|
|
545
|
+
| `mellos-mapping/semantics` | 缩放阶梯、分组聚合、焦点与页集规则、共享字形词汇表 | 是 |
|
|
546
|
+
| `mellos-mapping/render` | 终端渲染器 | 同样受门禁守护(它是纯的),但产出是字符格——给终端宿主 |
|
|
547
|
+
| `mellos-mapping/store` | 文件系统持久化、原子保存、focus 文件、策略 | 仅 Node |
|
|
548
|
+
| `mellos-mapping/server` | 打包好的 MCP 服务器入口——用来拉起的进程,不是拿来 import 的模块 | 仅 Node |
|
|
549
|
+
|
|
550
|
+
**浏览器安全**的意思是 import 闭包里没有任何 Node 内建模块,由测试门禁
|
|
551
|
+
守护——图形客户端(web 面板、编辑器视图)可以直接解析状态文件,并复用与
|
|
552
|
+
终端面板完全一致的聚合、缩放与字形语义。`packages/dsh-client` 就是这样一个
|
|
553
|
+
客户端。
|
|
294
554
|
|
|
295
555
|
## 许可证
|
|
296
556
|
|