dsh-gitnexus-plus 0.1.3 → 0.1.4

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.
Files changed (56) hide show
  1. package/README-CN.md +22 -7
  2. package/README.md +41 -8
  3. package/lib/bin/graph-helper.d.ts +21 -0
  4. package/lib/bin/graph-helper.d.ts.map +1 -0
  5. package/lib/bin/graph-helper.js +71 -0
  6. package/lib/bin/graph-helper.js.map +1 -0
  7. package/lib/client.js +4081 -2370
  8. package/lib/gitnexus/analyze.d.ts +48 -8
  9. package/lib/gitnexus/analyze.d.ts.map +1 -1
  10. package/lib/gitnexus/analyze.js +345 -84
  11. package/lib/gitnexus/analyze.js.map +1 -1
  12. package/lib/gitnexus/commands.d.ts +8 -1
  13. package/lib/gitnexus/commands.d.ts.map +1 -1
  14. package/lib/gitnexus/commands.js +19 -0
  15. package/lib/gitnexus/commands.js.map +1 -1
  16. package/lib/gitnexus/delta.d.ts +144 -0
  17. package/lib/gitnexus/delta.d.ts.map +1 -0
  18. package/lib/gitnexus/delta.js +347 -0
  19. package/lib/gitnexus/delta.js.map +1 -0
  20. package/lib/gitnexus/git-activity.d.ts +13 -21
  21. package/lib/gitnexus/git-activity.d.ts.map +1 -1
  22. package/lib/gitnexus/git-activity.js +60 -26
  23. package/lib/gitnexus/git-activity.js.map +1 -1
  24. package/lib/gitnexus/graph.d.ts +126 -0
  25. package/lib/gitnexus/graph.d.ts.map +1 -0
  26. package/lib/gitnexus/graph.js +472 -0
  27. package/lib/gitnexus/graph.js.map +1 -0
  28. package/lib/gitnexus/root.d.ts +0 -3
  29. package/lib/gitnexus/root.d.ts.map +1 -1
  30. package/lib/gitnexus/root.js +64 -5
  31. package/lib/gitnexus/root.js.map +1 -1
  32. package/lib/gitnexus/search.d.ts +21 -8
  33. package/lib/gitnexus/search.d.ts.map +1 -1
  34. package/lib/gitnexus/search.js +87 -13
  35. package/lib/gitnexus/search.js.map +1 -1
  36. package/lib/index.d.ts +6 -0
  37. package/lib/index.d.ts.map +1 -1
  38. package/lib/index.js +165 -3
  39. package/lib/index.js.map +1 -1
  40. package/lib/routes/analyze.d.ts +3 -2
  41. package/lib/routes/analyze.d.ts.map +1 -1
  42. package/lib/routes/analyze.js +8 -2
  43. package/lib/routes/analyze.js.map +1 -1
  44. package/lib/routes/delta.d.ts +22 -0
  45. package/lib/routes/delta.d.ts.map +1 -0
  46. package/lib/routes/delta.js +50 -0
  47. package/lib/routes/delta.js.map +1 -0
  48. package/lib/routes/file-diff.d.ts +19 -0
  49. package/lib/routes/file-diff.d.ts.map +1 -0
  50. package/lib/routes/file-diff.js +69 -0
  51. package/lib/routes/file-diff.js.map +1 -0
  52. package/lib/routes/graph.d.ts +22 -0
  53. package/lib/routes/graph.d.ts.map +1 -0
  54. package/lib/routes/graph.js +71 -0
  55. package/lib/routes/graph.js.map +1 -0
  56. package/package.json +2 -2
package/README-CN.md CHANGED
@@ -2,18 +2,21 @@
2
2
 
3
3
  [English](README.md) · **简体中文**
4
4
 
5
- **当前版本:0.1.3** · [npm](https://www.npmjs.com/package/dsh-gitnexus-plus) ·
5
+ **当前版本:0.1.4** · [npm](https://www.npmjs.com/package/dsh-gitnexus-plus) ·
6
6
  [问题反馈](https://github.com/Moowningstar/gitnexus-plus/issues)
7
7
 
8
8
  [插件做什么](#插件做什么) · [安装](#安装) · [遇到问题怎么解决](#遇到问题怎么解决) ·
9
9
  [上游 GitNexus 文档](#上游-gitnexus-文档路径)
10
10
 
11
- 一个 DeepSeek Harness 插件:查看 GitNexus 索引**覆盖了什么、漏掉了什么**,在右侧栏刷新索引,并按关键词搜索图里的符号。
11
+ 一个 DeepSeek Harness 插件:查看 GitNexus 索引**覆盖了什么、漏掉了什么**,判断这次刷新值不值得跑,
12
+ 看图,在右侧栏刷新索引,并按关键词搜索图里的符号。
12
13
 
13
14
  它不 fork GitNexus、不重写解析器、不打包或再分发 GitNexus。`gitnexus` 是 **peer**,需要你自己提供。
14
15
 
15
16
  ## 插件做什么
16
17
 
18
+ - **刷新门禁(Tier 0)**:在给出刷新按钮之前,用工作区文件与索引记录的 sha256(`.gitnexus/gitnexus.json` 的 `fileHashes`)比对,报告真正变化的内容:改 / 增 / 删,以及被索引策略排除的文件。工作区没变时毫秒级给出结论、**不启动分析器**,按钮直接说明"无需刷新",而不是让你等一次几分钟的重建。只有比对**锚定在索引记录的提交**上时才会说"已是最新";索引没记录提交时会退化为工作区与 `HEAD` 比较,并明确说"无法确认",而不是冒充新鲜。
19
+ - **图视图**:把索引里的社区画在 canvas 上,跨社区关系按权重聚合;点社区看成员符号及它们之间的关系,点符号在文件查看器里定位到行。节点与边预算由宿主限制,并明确写出省略了多少。
17
20
  - **索引覆盖**:列出被 `gitnexus analyze` 跳过的超大文件,给出大小、语言占比,以及生成物/压缩文件的判断信号。
18
21
  - **索引新鲜度**:索引提交与 `HEAD` 对比,分为 `current` / `behind` / `diverged` / `unknown`,并给出未提交变更数。
19
22
  - **图构成**:节点、边、社区、流程、embedding、边/节点比。
@@ -22,7 +25,7 @@
22
25
  - **关键词搜索**:按图节点的 `name` / `filePath` 匹配,返回 kind、path、line;点击结果打开文件并定位到行,右侧“复制”按钮复制 `path:line`。
23
26
  - **源码回退**:图查询子进程起不来时(无可用 shell 沙箱、DLL/ABI、索引忙),在索引清单内的文件里做有界源码行匹配,结果标为 `mode: "text"`。
24
27
  - **无索引也有信息**:git 项目尚未建索引时,显示扫描概览、语言分布和初始化命令,而不是空白面板。
25
- - **维护**:初始化、增量刷新、全量重建(`--force`)都通过 DSH 的 shell 执行器运行,不自行请求提权。
28
+ - **维护**:初始化、增量刷新、全量重建(`--force`)都通过 DSH 的 shell 执行器运行,不自行请求提权。索引报告 FTS 不可用时,面板另外提供 **修复搜索索引(FTS)**,只跑 `analyze --repair-fts`,不重跑分析。
26
29
 
27
30
  ## 安装
28
31
 
@@ -73,11 +76,16 @@ npm install --prefix <DSH_HOME>/gitnexus-plus/gitnexus gitnexus@^1.6.12
73
76
  DSH 内暴露:
74
77
 
75
78
  - 工具 `gitnexus_coverage`:`{ repo, includeLanguages? }`
79
+ - 工具 `gitnexus_delta`:`{ repo }` —— 这次刷新会不会改变索引
76
80
  - 路由 `GET /api/gitnexus/coverage?repo=<project>`
77
81
  - 路由 `GET /api/gitnexus/search?repo=<project>&q=<keyword>&limit=20`
78
82
  - 路由 `GET /api/gitnexus/file-history?repo=<project>&path=<file>&days=7`:单个文件的
79
83
  有界提交时间线
80
- - 路由 `POST/GET/DELETE /api/gitnexus/analyze`(唯一会改动索引的入口)
84
+ - 路由 `GET /api/gitnexus/delta?repo=<project>`:Tier 0 差量判断
85
+ - 路由 `GET /api/gitnexus/graph?repo=<project>&view=communities|community&id=<community>`:
86
+ 有界图投影
87
+ - 路由 `POST/GET/DELETE /api/gitnexus/analyze`(唯一会改动索引的入口;`force=1` 全量重建,
88
+ `mode=repair-fts` 只修搜索索引)
81
89
  - 右侧栏 tab `gitnexus`
82
90
 
83
91
  CLI:
@@ -108,10 +116,14 @@ npm test
108
116
  | 面板说 GitNexus 不存在 | 自己安装,或用面板的安装按钮;非标准位置设 `GITNEXUS_CLI=/path/to/gitnexus/dist/cli/index.js`。 | [`gitnexus/README.md` — Requirements](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/README.md#requirements)、[Quick Start](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/README.md#quick-start) |
109
117
  | 项目还没有索引 | 点 **初始化索引**,或执行 `gitnexus analyze --index-only <repo>`。 | [`README.md` — CLI Reference](https://github.com/abhigyanpatwari/GitNexus/blob/main/README.md#cli-reference)、[`RUNBOOK.md` — Index out of date](https://github.com/abhigyanpatwari/GitNexus/blob/main/RUNBOOK.md#index-out-of-date--stale-tools) |
110
118
  | 刷新失败、`spawn EPERM`,或索引停在 `incremental-in-progress` | 面板命令已带 `GITNEXUS_MEMORY=off`、`NODE_OPTIONS=--max-old-space-size=8192`、`GITNEXUS_HOME=<repo>/.gitnexus/plugin-home`、`--index-only`。沙箱仍拒绝时,把命令复制到自己的终端跑;插件不会扩权。 | [`RUNBOOK.md` — LadybugDB / lock errors](https://github.com/abhigyanpatwari/GitNexus/blob/main/RUNBOOK.md#ladybugdb--lock-errors)、[Memory / analyze crashes](https://github.com/abhigyanpatwari/GitNexus/blob/main/RUNBOOK.md#memory--analyze-crashes) |
111
- | 刷新报 `EPERM … mkdir '<repo>\.gitnexus\parsedfile-store'` | GitNexus 1.6.12 会从 parse worker 创建这个缓存目录。插件现在在启动 analyze 前由宿主预建缓存目录;升级后重启 DSH。仍失败说明沙箱令牌不能写 `.gitnexus`,把复制出的命令放到普通终端执行。 | [`RUNBOOK.md` — LadybugDB / lock errors](https://github.com/abhigyanpatwari/GitNexus/blob/main/RUNBOOK.md#ladybugdb--lock-errors)、[`RUNBOOK.md` — Clean slate](https://github.com/abhigyanpatwari/GitNexus/blob/main/RUNBOOK.md#clean-slate-corrupt-or-huge-gitnexus) |
119
+ | 刷新报 `EPERM … mkdir` 或 `rmdir '<repo>\.gitnexus\parsedfile-store'` | GitNexus 在每次解析开始时**删除**这个 run 级存储,解析过程中再由 worker 重新创建——两个方向都可能被拒。0.1.4 处理了两个成因:不再预建该目录(那是 0.1.3 的 `rmdir` 来源);同时让分析器的 shell 调用带上**仓库**作为沙箱工作区根。面板路由没有 session,沙箱以前会回退到 DSH 应用目录,那条路径的写能力是**另一个身份**,仓库的写授权对它无效,于是 `.gitnexus` 里的写入全被拒。若仍失败,说明部署模式是只读——把复制出的命令放到普通终端执行。 | [`RUNBOOK.md` — LadybugDB / lock errors](https://github.com/abhigyanpatwari/GitNexus/blob/main/RUNBOOK.md#ladybugdb--lock-errors)、[`RUNBOOK.md` — Clean slate](https://github.com/abhigyanpatwari/GitNexus/blob/main/RUNBOOK.md#clean-slate-corrupt-or-huge-gitnexus) |
112
120
  | 增量分析卡住,或数据库报 `Maximum database size … has been reached` | 用 **全量重建**(`--force`),或按 clean slate 清理后重建。 | [`RUNBOOK.md` — Clean slate](https://github.com/abhigyanpatwari/GitNexus/blob/main/RUNBOOK.md#clean-slate-corrupt-or-huge-gitnexus)、[`gitnexus/README.md` — Troubleshooting](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/README.md#troubleshooting) |
121
+ | 刷新报 `EPERM … open '<repo>\.gitnexus\lbug.init.lock'` 或 `unable to acquire init lock` | 这是瞬时的文件锁,不是权限问题:报出该错误的机器上做过权限体检,`.gitnexus` 的权限是健康的。GitNexus 的第一个写操作就是这把锁,杀毒、索引器或上一次崩溃都可能持有它。插件会清掉残留锁并自动重试一次(运行状态里 `attempts: 2`)。仍失败就等一会儿再刷新,或把复制出的命令放到普通终端执行。 | 本插件的重试 + 分析器自己的锁文件;无上游 GitNexus 路径。 |
113
122
  | 搜索报 `A dynamic link library (DLL) initialization routine failed` / `lbugjs.node` | 图查询在 `lib/bin/search-helper.js` 里跑,不在 Electron 宿主里加载原生模块;升级后重启 DSH,并确保 shell PATH 上有 `node`。helper 起不来时会回退源码。 | [`gitnexus/README.md` — Troubleshooting](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/README.md#troubleshooting) |
114
- | Windows 上搜索命中很少,或面板提示 FTS 不可用 | 索引是 `--skip-fts` 建的,或 FTS 扩展加载不了。关键词搜索仍按名称/路径匹配,源码回退按行匹配;修复 FTS 是上游操作。 | [`gitnexus/README.md` — Windows: full-text search unavailable](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/README.md#windows-full-text-search-unavailable)、[Analyze warns about unavailable FTS](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/README.md#analyze-warns-about-unavailable-fts-or-vector-extensions) |
123
+ | Windows 上搜索命中很少,或面板提示 FTS 不可用 | 索引是 `--skip-fts` 建的,或 FTS 扩展加载不了。关键词搜索仍按名称/路径匹配,源码回退按行匹配。此时面板提供 **修复搜索索引(FTS)**,只跑 `analyze --repair-fts`,不动图。它仍可能失败,面板会区分两种原因:修复需要在**子进程**里安装/加载扩展,受限 shell 会拒绝(`spawn EPERM` → 把命令复制到终端跑);或扩展文件存在但加载不了,那是 Windows 缺少原生运行时(VC++ 2015-2022 x64 与 OpenSSL 3),不是索引坏了。 | [`gitnexus/README.md` — Windows: full-text search unavailable](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/README.md#windows-full-text-search-unavailable)、[Analyze warns about unavailable FTS](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/README.md#analyze-warns-about-unavailable-fts-or-vector-extensions) |
124
+ | 刷新按钮显示“无需刷新”且不可点 | 这是 Tier 0 的判断,不是故障:索引记录的文件内容哈希全部没变,再跑分析器也不会改变索引。**仍然刷新** 可以强制跑一次(例如 GitNexus 升级或 schema 变化后)。如果索引没有记录提交基线,面板**不会**说“无需刷新”,而是显示“无法确认”并保持按钮可用。 | 本插件的差量引擎;无上游 GitNexus 路径。 |
125
+ | 门禁显示“无法确认”,而不是“无需刷新” | 索引没有记录提交,所以只能比较工作区。受限沙箱里的 analyze 起不了 `git` 子进程,manifest 的 `lastCommit` 因此为空——本机实测:同一条命令在普通终端会写入提交,在沙箱里留空。想要更强的结论,把复制出的命令在沙箱外跑一次;无论哪种状态,刷新按钮都可用。 | 本插件差量引擎 + 分析器的 git 访问;无上游 GitNexus 路径。 |
126
+ | 图视图空白,或报 404 | 404 说明宿主还没有 `/api/gitnexus/graph` 路由,重启 DSH,而不是只刷新页面。空白画布但下面有说明,通常是索引还没有社区(旧索引)或索引忙:刷新索引即可。节点数按预算截断,卡片会写明省略了多少。 | 本插件宿主路由;图数据本身来自 GitNexus 索引。 |
115
127
  | 点击搜索结果没有打开文件 | 点击依赖 `ctx.sidebarRight.openResourceIn`;没有该服务的 profile 会退回复制 `path:line`。重启 DSH;仍不行就用“复制”。 | 面板/DSH 边界,无上游 GitNexus 路径。 |
116
128
  | 文件时间线报 404/401 | 客户端先热更新了,宿主还没加载 `/api/gitnexus/file-history` 路由。重启 DSH,不是只刷新页面。 | 本插件宿主路由;无上游 GitNexus 路径。 |
117
129
  | 分析内存不足 | 保留面板的 `NODE_OPTIONS` / `GITNEXUS_MEMORY`,或手动提高 heap;必要时全量重建。 | [`gitnexus/README.md` — Analysis runs out of memory](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/README.md#analysis-runs-out-of-memory)、[`RUNBOOK.md` — Memory / analyze crashes](https://github.com/abhigyanpatwari/GitNexus/blob/main/RUNBOOK.md#memory--analyze-crashes) |
@@ -146,7 +158,8 @@ $env:GITNEXUS_MEMORY='off'; $env:NODE_OPTIONS='--max-old-space-size=8192'; `
146
158
  gitnexus analyze --index-only '<repo>'
147
159
  ```
148
160
 
149
- 全量重建再加 `--force`。
161
+ 全量重建再加 `--force`;只修搜索索引用 `--repair-fts`(面板在索引报告 FTS 不可用时提供
162
+ **修复搜索索引(FTS)**,不会重跑分析)。
150
163
 
151
164
  - `GITNEXUS_MEMORY=off`:阻止 CLI 通过管道重新 spawn 自己(受限沙箱会 `spawn EPERM`)。
152
165
  - `NODE_OPTIONS=--max-old-space-size=8192`:补上它本来想通过 respawn 拿到的 heap。
@@ -168,6 +181,8 @@ $env:GITNEXUS_MEMORY='off'; $env:NODE_OPTIONS='--max-old-space-size=8192'; `
168
181
  ## 边界
169
182
 
170
183
  - 覆盖与搜索是只读的;维护是单独确认的写操作,不会自动触发。
184
+ - 刷新门禁比对的是索引记录过的文件内容哈希。它看不到分析器因自身原因必须重跑的情况(schema 升级、新的分析特性);**仍然刷新** 就是为这种情况留的。
185
+ - 图视图画的是社区,不是全部符号:总览是社区图,下钻最多显示一个社区的节点预算那么多成员。两者都会标注是否截断。
171
186
  - 只报告 GitNexus 索引的事实,不重写解析器,不重新实现图数据库。
172
187
  - 搜索的 graph 模式是名称/路径匹配,不搜正文;text 模式才按行匹配,且有上限。
173
188
  - 源码回退只覆盖索引清单里的文件,新文件需先刷新索引。
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  **English** · [简体中文](README-CN.md)
4
4
 
5
- **Current release: [0.1.3](https://github.com/Moowningstar/gitnexus-plus/releases/tag/v0.1.3)** ·
5
+ **Current release: [0.1.4](https://github.com/Moowningstar/gitnexus-plus/releases/tag/v0.1.4)** ·
6
6
  [npm](https://www.npmjs.com/package/dsh-gitnexus-plus) ·
7
7
  [Issues](https://github.com/Moowningstar/gitnexus-plus/issues)
8
8
 
@@ -10,13 +10,26 @@
10
10
  [Upstream GitNexus docs](#upstream-gitnexus-documentation)
11
11
 
12
12
  A DeepSeek Harness plugin: see what a GitNexus index **covers and what it leaves out**,
13
- refresh it from the sidebar, and search its symbols by keyword.
13
+ decide whether a refresh is worth running, browse the graph, refresh it from the sidebar,
14
+ and search its symbols by keyword.
14
15
 
15
16
  It does not fork GitNexus, rewrite its parser, or bundle/redistribute it. `gitnexus` is a
16
17
  **peer**; you provide it.
17
18
 
18
19
  ## What it does
19
20
 
21
+ - **Refresh gate (Tier 0)** — before offering a refresh, the panel compares the working
22
+ tree with the sha256 hashes the index recorded in `.gitnexus/gitnexus.json` and reports
23
+ what actually differs: modified / added / deleted, plus files the index's own policy
24
+ excludes. A clean tree answers in milliseconds without starting the analyzer, and the
25
+ button says so instead of running a minutes-long rebuild. The verdict is only called
26
+ "up to date" when it is anchored to the commit the index recorded; an index that
27
+ recorded none falls back to comparing the working tree with `HEAD` and says it cannot
28
+ confirm instead of claiming freshness.
29
+ - **Graph view** — the index's communities drawn on a canvas, with aggregated
30
+ cross-community edges; click a community to see its member symbols and the relations
31
+ among them, click a symbol to open its file at the line. Node and edge budgets are
32
+ applied by the host, and the view states what it left out.
20
33
  - **Index coverage** — lists the oversized files `gitnexus analyze` skipped, with size,
21
34
  language share, and generated/minified signals.
22
35
  - **Index freshness** — indexed commit vs `HEAD`, classified `current` / `behind` /
@@ -39,7 +52,9 @@ It does not fork GitNexus, rewrite its parser, or bundle/redistribute it. `gitne
39
52
  - **No-index visibility** — a git project without an index shows a scan overview,
40
53
  language split and the initialize command instead of an empty panel.
41
54
  - **Maintenance** — initialize, incremental refresh and full rebuild (`--force`) run
42
- through DSH's shell executor, with no self-escalation.
55
+ through DSH's shell executor, with no self-escalation. When the index reports FTS as
56
+ unavailable, a **修复搜索索引(FTS)** action runs `analyze --repair-fts` — the search
57
+ indexes only, without re-analysing the repository.
43
58
 
44
59
  ## Install
45
60
 
@@ -95,11 +110,16 @@ it cannot become a filesystem probe.
95
110
  Inside DSH:
96
111
 
97
112
  - tool `gitnexus_coverage`: `{ repo, includeLanguages? }`
113
+ - tool `gitnexus_delta`: `{ repo }` — would a refresh change anything?
98
114
  - route `GET /api/gitnexus/coverage?repo=<project>`
99
115
  - route `GET /api/gitnexus/search?repo=<project>&q=<keyword>&limit=20`
100
116
  - route `GET /api/gitnexus/file-history?repo=<project>&path=<file>&days=7` — one file's
101
117
  bounded commit timeline
102
- - route `POST/GET/DELETE /api/gitnexus/analyze` (the only entry that changes an index)
118
+ - route `GET /api/gitnexus/delta?repo=<project>` — Tier 0 comparison against the index
119
+ - route `GET /api/gitnexus/graph?repo=<project>&view=communities|community&id=<community>`
120
+ — a bounded graph projection
121
+ - route `POST/GET/DELETE /api/gitnexus/analyze` (the only entry that changes an index;
122
+ `force=1` for a full rebuild, `mode=repair-fts` for the search indexes only)
103
123
  - right-sidebar tab `gitnexus`
104
124
 
105
125
  CLI:
@@ -138,10 +158,14 @@ GitNexus path owns the rest.
138
158
  | The panel says GitNexus is absent | Install it yourself, or use the panel's install. For a non-standard location set `GITNEXUS_CLI=/path/to/gitnexus/dist/cli/index.js`. | [`gitnexus/README.md` — Requirements](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/README.md#requirements), [Quick Start](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/README.md#quick-start) |
139
159
  | The project has no index | Use **初始化索引** in the panel, or run `gitnexus analyze --index-only <repo>`. | [`README.md` — CLI Reference](https://github.com/abhigyanpatwari/GitNexus/blob/main/README.md#cli-reference), [`RUNBOOK.md` — Index out of date](https://github.com/abhigyanpatwari/GitNexus/blob/main/RUNBOOK.md#index-out-of-date--stale-tools) |
140
160
  | Refresh fails, `spawn EPERM`, or the index stays `incremental-in-progress` | The panel's command already sets `GITNEXUS_MEMORY=off`, `NODE_OPTIONS=--max-old-space-size=8192`, `GITNEXUS_HOME=<repo>/.gitnexus/plugin-home` and `--index-only`. If the sandbox still refuses, run the copied command in your own shell; the plugin will not escalate. | [`RUNBOOK.md` — LadybugDB / lock errors](https://github.com/abhigyanpatwari/GitNexus/blob/main/RUNBOOK.md#ladybugdb--lock-errors), [Memory / analyze crashes](https://github.com/abhigyanpatwari/GitNexus/blob/main/RUNBOOK.md#memory--analyze-crashes) |
141
- | Refresh fails with `EPERM … mkdir '<repo>\.gitnexus\parsedfile-store'` | GitNexus 1.6.12 creates this cache directory from the parse worker. The plugin pre-creates the cache directories before spawning; restart DSH after upgrading. If it still fails, the sandbox token cannot write `.gitnexus`; run the copied command in a normal terminal. | [`RUNBOOK.md` — LadybugDB / lock errors](https://github.com/abhigyanpatwari/GitNexus/blob/main/RUNBOOK.md#ladybugdb--lock-errors), [`RUNBOOK.md` — Clean slate](https://github.com/abhigyanpatwari/GitNexus/blob/main/RUNBOOK.md#clean-slate-corrupt-or-huge-gitnexus) |
161
+ | Refresh fails with `EPERM … mkdir` or `rmdir '<repo>\.gitnexus\parsedfile-store'` | GitNexus deletes this run-scoped store at the start of every parse, and a parse worker creates it again during the parse — both directions can be refused. Two causes, both addressed in 0.1.4: the plugin no longer pre-creates the directory (that was 0.1.3's `rmdir`), and the analyzer's shell call now carries the **repository** as its sandbox workspace root. A panel route has no session, so the sandbox used to fall back to the DSH application directory, whose write capability is a different identity — the repository's write grant never applied. If it still fails, the deployment's mode is read-only: run the copied command in a normal terminal. | [`RUNBOOK.md` — LadybugDB / lock errors](https://github.com/abhigyanpatwari/GitNexus/blob/main/RUNBOOK.md#ladybugdb--lock-errors), [`RUNBOOK.md` — Clean slate](https://github.com/abhigyanpatwari/GitNexus/blob/main/RUNBOOK.md#clean-slate-corrupt-or-huge-gitnexus) |
142
162
  | Incremental analyze hangs, or the database reports `Maximum database size … has been reached` | Use **全量重建** (`--force`), or the clean-slate steps. | [`RUNBOOK.md` — Clean slate](https://github.com/abhigyanpatwari/GitNexus/blob/main/RUNBOOK.md#clean-slate-corrupt-or-huge-gitnexus), [`gitnexus/README.md` — Troubleshooting](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/README.md#troubleshooting) |
163
+ | Refresh fails with `EPERM … open '<repo>\.gitnexus\lbug.init.lock'` or `unable to acquire init lock` | A transient file lock, not a permissions problem: the ACL for `.gitnexus` was checked on the machine that reported it and came back healthy. GitNexus's first write is that lock, and a scanner, the indexer, or a crashed run can hold it. The plugin clears a stale lock and retries once automatically (the run shows `attempts: 2`). If it still fails, wait a moment and retry, or run the copied command in a normal terminal. | This plugin's retry plus the analyzer's own lock file; no upstream GitNexus path. |
143
164
  | Search fails with `A dynamic link library (DLL) initialization routine failed` / `lbugjs.node` | Graph search runs in `lib/bin/search-helper.js`, never in the Electron host. Restart DSH after upgrading and keep `node` on the shell PATH. If the helper cannot start at all, search falls back to source text. | [`gitnexus/README.md` — Troubleshooting](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/README.md#troubleshooting) |
144
- | Windows search returns very few hits, or the panel warns FTS is unavailable | The index was built with `--skip-fts`, or the FTS extension cannot load. Keyword search still matches names and paths; the source fallback matches lines. Repairing FTS is an upstream action. | [`gitnexus/README.md` — Windows: full-text search unavailable](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/README.md#windows-full-text-search-unavailable), [Analyze warns about unavailable FTS](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/README.md#analyze-warns-about-unavailable-fts-or-vector-extensions) |
165
+ | Windows search returns very few hits, or the panel warns FTS is unavailable | The index was built with `--skip-fts`, or the FTS extension cannot load. Keyword search still matches names and paths; the source fallback matches lines. The panel then offers **修复搜索索引(FTS)**, which runs `analyze --repair-fts` and leaves the graph alone. Two ways it still fails, and the panel names which: the repair must install/load the extension **out of process**, which a confined shell refuses (`spawn EPERM` — run the copied command in a terminal), or the extension file exists but cannot load, which is a missing Windows runtime (VC++ 2015-2022 x64 and OpenSSL 3), not an index problem. | [`gitnexus/README.md` — Windows: full-text search unavailable](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/README.md#windows-full-text-search-unavailable), [Analyze warns about unavailable FTS](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/README.md#analyze-warns-about-unavailable-fts-or-vector-extensions) |
166
+ | The refresh button says 无需刷新 and is disabled | That is the Tier 0 verdict, not a failure: every file the index recorded still hashes the same, so re-running the analyzer would change nothing. **仍然刷新** forces it anyway (useful after a schema or GitNexus upgrade). If the index recorded no commit baseline, the panel does **not** claim 无需刷新 — it says it cannot confirm and leaves the button enabled. | This plugin's delta engine; no upstream GitNexus path. |
167
+ | The gate says 无法确认 instead of 无需刷新 | The index recorded no commit, so the comparison can only see the working tree. A confined analyze cannot start `git`, which is how the manifest ends up with an empty `lastCommit` — measured here: the same command writes it in a normal terminal and leaves it empty under the sandbox. Run the copied command outside the sandbox once if you want the stronger verdict; the refresh button stays usable either way. | This plugin's delta engine plus the analyzer's git access; no upstream GitNexus path. |
168
+ | The graph card is empty, or fails with 404 | A 404 means the host predates `/api/gitnexus/graph` — restart DSH, not just the page. An empty canvas with a message means the index has no communities yet (an old index), or the store is busy: refresh the index. Nodes are capped by design; the card states how much it left out. | This plugin's host route; graph data itself comes from the GitNexus index. |
145
169
  | Clicking a search hit does not open a file | The click uses `ctx.sidebarRight.openResourceIn`; a profile without that service falls back to copying `path:line`. Restart DSH; if it persists, use the Copy button. | This panel/DSH boundary; no upstream GitNexus path. |
146
170
  | The file timeline fails with 404/401 | The client hot-reloaded before the host did, so `/api/gitnexus/file-history` is not mounted yet. Restart DSH (not just refresh the page). | This plugin's host route; no upstream GitNexus path. |
147
171
  | Analyze runs out of memory | Keep the panel's `NODE_OPTIONS` / `GITNEXUS_MEMORY` settings, or raise the heap manually; the index may need a full rebuild. | [`gitnexus/README.md` — Analysis runs out of memory](https://github.com/abhigyanpatwari/GitNexus/blob/main/gitnexus/README.md#analysis-runs-out-of-memory), [`RUNBOOK.md` — Memory / analyze crashes](https://github.com/abhigyanpatwari/GitNexus/blob/main/RUNBOOK.md#memory--analyze-crashes) |
@@ -177,7 +201,9 @@ $env:GITNEXUS_MEMORY='off'; $env:NODE_OPTIONS='--max-old-space-size=8192'; `
177
201
  gitnexus analyze --index-only '<repo>'
178
202
  ```
179
203
 
180
- Add `--force` for a full rebuild.
204
+ Add `--force` for a full rebuild, or `--repair-fts` alone to rebuild the search indexes
205
+ without touching the graph (the panel offers that as **修复搜索索引(FTS)** when the index
206
+ reports FTS as unavailable).
181
207
 
182
208
  - `GITNEXUS_MEMORY=off` — stops the CLI from re-spawning itself over piped stdio, which a
183
209
  confined sandbox denies (`spawn EPERM`).
@@ -190,7 +216,8 @@ Add `--force` for a full rebuild.
190
216
  `--skip-fts` is **adaptive per index**: no flag when the manifest says FTS is available,
191
217
  and the flag when it is not. `skipFts: true` can force the flag; there is no config that
192
218
  forces FTS on, because enabling it is a repair (`gitnexus analyze --repair-fts`), not an
193
- incremental refresh.
219
+ incremental refresh — so the panel exposes it as its own action, and a repair run never
220
+ carries `--skip-fts` (the CLI accepts that pair and exits 0 having done nothing).
194
221
 
195
222
  ## License (read before commercial use)
196
223
 
@@ -211,6 +238,12 @@ the related features puts that use under it.**
211
238
 
212
239
  - Coverage and search are read-only; maintenance is a separately confirmed write and
213
240
  never starts by itself.
241
+ - The refresh gate compares content hashes of the files the index recorded. It cannot
242
+ see a change the analyzer would make for its own reasons (a schema upgrade, a new
243
+ feature mode); **仍然刷新** exists for exactly that case.
244
+ - The graph view draws communities, not every symbol: the overview is the community
245
+ graph, and a drill-down shows at most the configured node budget of one community's
246
+ members. Both say when they are truncated.
214
247
  - The plugin reports facts about a GitNexus index; it does not rewrite the parser or
215
248
  reimplement the graph database.
216
249
  - Graph search matches names/paths, not bodies; the text fallback matches lines and is
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Graph projection helper, run by the **system Node** rather than the DSH host.
4
+ *
5
+ * The host is Electron's Node and cannot load GitNexus's LadybugDB native addon
6
+ * (ABI mismatch: "A dynamic link library (DLL) initialization routine failed").
7
+ * This process is started with the platform Node the CLI already uses, imports the
8
+ * same adapter, runs the bounded projection, and prints exactly one JSON object.
9
+ *
10
+ * Invocation:
11
+ * node graph-helper.js <repo> <view> <id> [managedPrefix] [nodeBudget] [edgeBudget]
12
+ *
13
+ * Success: `{ "ok": true, "projection": GraphProjection }`
14
+ * Failure: `{ "ok": false, "status": <number>, "code": <GraphErrorCode>, "message": string }`
15
+ *
16
+ * It always exits 0 for a reported failure, so the host reads a structured answer
17
+ * instead of inferring one from an exit code. A process-level crash (native fault)
18
+ * is the one case the host handles from an unparseable stdout/stderr pair.
19
+ */
20
+ export {};
21
+ //# sourceMappingURL=graph-helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-helper.d.ts","sourceRoot":"","sources":["../../src/bin/graph-helper.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;GAiBG"}
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Graph projection helper, run by the **system Node** rather than the DSH host.
4
+ *
5
+ * The host is Electron's Node and cannot load GitNexus's LadybugDB native addon
6
+ * (ABI mismatch: "A dynamic link library (DLL) initialization routine failed").
7
+ * This process is started with the platform Node the CLI already uses, imports the
8
+ * same adapter, runs the bounded projection, and prints exactly one JSON object.
9
+ *
10
+ * Invocation:
11
+ * node graph-helper.js <repo> <view> <id> [managedPrefix] [nodeBudget] [edgeBudget]
12
+ *
13
+ * Success: `{ "ok": true, "projection": GraphProjection }`
14
+ * Failure: `{ "ok": false, "status": <number>, "code": <GraphErrorCode>, "message": string }`
15
+ *
16
+ * It always exits 0 for a reported failure, so the host reads a structured answer
17
+ * instead of inferring one from an exit code. A process-level crash (native fault)
18
+ * is the one case the host handles from an unparseable stdout/stderr pair.
19
+ */
20
+ import { GraphError, isGraphView, projectGraph } from '../gitnexus/graph.js';
21
+ /** Write the one object, then exit once stdout has flushed. */
22
+ function emit(payload) {
23
+ const text = JSON.stringify(payload);
24
+ process.stdout.write(text, () => process.exit(0));
25
+ // A native handle can keep the event loop alive; the payload is already queued.
26
+ setTimeout(() => process.exit(0), 2000).unref();
27
+ }
28
+ const [, , repoArg, viewArg, idArg, managedArg, nodeArg, edgeArg] = process.argv;
29
+ const parseBudget = (value) => {
30
+ if (value === undefined || value === '')
31
+ return undefined;
32
+ const parsed = Number.parseInt(value, 10);
33
+ return Number.isFinite(parsed) ? parsed : undefined;
34
+ };
35
+ if (typeof repoArg !== 'string' || repoArg === '') {
36
+ emit({
37
+ ok: false,
38
+ status: 400,
39
+ code: 'invalid-view',
40
+ message: 'usage: graph-helper <repo> <view> [id] [managedPrefix] [nodeBudget] [edgeBudget]',
41
+ });
42
+ }
43
+ else if (!isGraphView(viewArg)) {
44
+ emit({
45
+ ok: false,
46
+ status: 400,
47
+ code: 'invalid-view',
48
+ message: `未知的图视图:${String(viewArg)}(可用:communities、community)`,
49
+ });
50
+ }
51
+ else {
52
+ try {
53
+ const projection = await projectGraph(repoArg, {
54
+ view: viewArg,
55
+ id: typeof idArg === 'string' && idArg !== '' ? idArg : undefined,
56
+ managedPrefix: managedArg === undefined || managedArg === '' ? undefined : managedArg,
57
+ nodeBudget: parseBudget(nodeArg),
58
+ edgeBudget: parseBudget(edgeArg),
59
+ });
60
+ emit({ ok: true, projection });
61
+ }
62
+ catch (error) {
63
+ emit({
64
+ ok: false,
65
+ status: error instanceof GraphError ? error.status : 500,
66
+ code: error instanceof GraphError ? error.code : 'graph-failed',
67
+ message: error instanceof Error ? error.message : String(error),
68
+ });
69
+ }
70
+ }
71
+ //# sourceMappingURL=graph-helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-helper.js","sourceRoot":"","sources":["../../src/bin/graph-helper.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAE7E,+DAA+D;AAC/D,SAAS,IAAI,CAAC,OAAgB;IAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,gFAAgF;IAChF,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,CAAC,EAAE,AAAD,EAAG,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;AAEjF,MAAM,WAAW,GAAG,CAAC,KAAyB,EAAsB,EAAE;IACpE,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,SAAS,CAAC;IAC1D,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AACtD,CAAC,CAAC;AAEF,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;IAClD,IAAI,CAAC;QACH,EAAE,EAAE,KAAK;QACT,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,kFAAkF;KAC5F,CAAC,CAAC;AACL,CAAC;KAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;IACjC,IAAI,CAAC;QACH,EAAE,EAAE,KAAK;QACT,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,UAAU,MAAM,CAAC,OAAO,CAAC,4BAA4B;KAC/D,CAAC,CAAC;AACL,CAAC;KAAM,CAAC;IACN,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE;YAC7C,IAAI,EAAE,OAAO;YACb,EAAE,EAAE,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;YACjE,aAAa,EAAE,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU;YACrF,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC;YAChC,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC;SACjC,CAAC,CAAC;QACH,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC;YACH,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,KAAK,YAAY,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG;YACxD,IAAI,EAAE,KAAK,YAAY,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc;YAC/D,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAChE,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}