dsh-plugin-codegraph 0.1.7 → 0.3.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 CHANGED
@@ -40,6 +40,16 @@ Two tools, deliberately separate.
40
40
  | `explore` | Several related declarations with their source | `query` |
41
41
  | `context` | Everything relevant to a task | `task` |
42
42
 
43
+ The tool also reports its own state into the system prompt. Every prompt assembly carries one line describing the workspace's index — how many files, declarations and relationships it holds, when it was built, and how many generated artifacts were left out — or, when there is none, that `codegraph_index` has to run first. That line is a section whose text is a function, re-evaluated per request by the host; nothing is spent on a `status` round-trip to learn it.
44
+
45
+ **Re-indexing parses only what changed.** Every successful run leaves the extraction it produced for each file in `.codegraph/cache/`; the next run — a second `codegraph_index`, or a watch rebuild after one edit — confirms each file by its recorded modification time and size and reuses its extraction instead of reading and parsing it again. On a 337-file workspace measured here, a repeat run cost 45 ms against 991 ms for the first. Edges and call resolution are still rebuilt over the whole graph every time, deliberately: the rule that resolves a call by a workspace-unique name is global, so a symbol added in one file can invalidate edges pointing at another that never changed. `cacheVerify: 'hash'` trades that speed for correctness when a checkout can restore an older file without moving its mtime.
46
+
47
+ **A large workspace indexes in the background.** `codegraph_index` estimates the job from the previous run's summary: at or past `backgroundIndexThreshold` files it hands the run to the host's job registry and returns a job id immediately, instead of holding a tool call open for minutes. `job_output <id>` reads the report; `job_kill <id>` stops it. Small workspaces keep the synchronous path, so the common case never pays for a job round-trip. Set `backgroundIndex: true` or `false` to override the estimate.
48
+
49
+ **A new session starts with an index.** When an agent is created for a workspace that has no index yet, the plugin starts one in the background through the host's job registry, so the first structural question already has a graph to answer from instead of spending three round trips on `status` → `codegraph_index` → retry. A workspace that already has an index is left alone (the watcher maintains it), and a host without a job registry skips the auto-build rather than blocking session creation.
50
+
51
+ **Chinese task descriptions get English candidates.** `context` ranks by identifier overlap, and a task written in Chinese names no identifiers — measured on a React admin workspace, 「修改报表页的分页与筛选参数」 returned nothing at all. A built-in table now maps frequent Chinese development words to identifier candidates (报表 → `report`, 分页 → `page`/`pageSize`/`pagination`, 筛选 → `filter`/`search`, …) and appends them after the literal terms; the same task now leads with `report`, `page`, `filter`, `param`. `contextSynonyms` extends the table per deployment.
52
+
43
53
  ### `codegraph_index` — build or refresh the graph
44
54
 
45
55
  Separate from `codegraph` rather than an eleventh operation, because indexing a large workspace takes minutes while a query takes milliseconds, and a tool's timeout budget is fixed per registration. Folding them together would force one budget that is either too tight for a real build or too loose to catch a hung query.
@@ -80,6 +90,13 @@ The same-file tier applies to bare calls only. A member call (`x.map()`) names a
80
90
 
81
91
  That last rule is deliberate. The model acts on `callers` output, so a confidently wrong caller sends it to edit the wrong file, while a missing caller merely sends it back to text search. The index report's `unresolved_count` is not, by itself, that gap's size — a type-free resolver was never going to settle a member call (`x.map()`) or a name already imported from elsewhere, and those dominate the total in a typical workspace. `unresolved_likely_internal_count` is the subset worth judging completeness by: bare, undeclared names that were structurally plausible workspace calls.
82
92
 
93
+ ## Command and panel
94
+
95
+ Two human-facing surfaces over the same index, for when you would rather not ask the model:
96
+
97
+ - **`/codegraph [status|index|files <pattern>]`** — report the current workspace's index, rebuild it, or list indexed files. `status` is the default.
98
+ - **Settings → 代码图谱** — a panel showing the workspace's index state (files, declarations, relationships, unresolved counts, when it was built, how many generated artifacts were skipped), with a path box and a rebuild button. Its data comes from the plugin's own `/dsh-plugin-codegraph/api/state` and `/api/reindex` endpoints, which read nothing but `<root>/.codegraph/status.json` and never expose arbitrary files.
99
+
83
100
  ## Install
84
101
 
85
102
  ```sh
@@ -133,12 +150,12 @@ The split is not ceremony. The seam carries no source text and performs no files
133
150
 
134
151
  ## Known limits
135
152
 
136
- - **Watching is on by default, and self-limiting where it wouldn't help.** A successful `codegraph_index` starts watching that root automatically — a single recursive `fs.watch` on macOS/Windows, one inotify watch per directory on Linux — refreshing the index after a debounced quiet period. Set `watch: false` to keep indexing purely explicit instead. It's overridden back off on a WSL2 kernel watching a path mounted in from the Windows host (`/mnt/<drive>/...`), since inotify doesn't reliably deliver events over that mount; `CODEGRAPH_FORCE_WATCH=1` and `CODEGRAPH_NO_WATCH=1` override that default either way. Whether or not watching is on, `status` still reports how many indexed files have gone stale — modified or removed since the last run — found by statting the filesystem directly, so a caller can always tell a trustworthy index from a drifted one instead of assuming the best.
153
+ - **Watching is on by default, and it goes through the host's filesystem seam.** A successful `codegraph_index` starts watching that root automatically: one watch per in-scope directory, opened through `ctx.fs.watch` rather than `node:fs` directly, so a workspace a backend serves from another execution world is watched where it actually lives. The seam's change callback carries no filename, so a rebuild is triggered by re-listing the watched directories and diffing them against the previous snapshot; an empty diff schedules nothing, which is what keeps the indexer's own `.codegraph` writes from rebuilding forever. A backend that cannot watch degrades to explicit indexing with a logged reason instead of failing the plugin. Set `watch: false` to keep indexing purely explicit instead. It's overridden back off on a WSL2 kernel watching a path mounted in from the Windows host (`/mnt/<drive>/...`), since inotify doesn't reliably deliver events over that mount; `CODEGRAPH_FORCE_WATCH=1` and `CODEGRAPH_NO_WATCH=1` override that default either way. Whether or not watching is on, `status` still reports how many indexed files have gone stale — modified or removed since the last run — found by statting the filesystem directly, so a caller can always tell a trustworthy index from a drifted one instead of assuming the best.
137
154
  - **Git hooks and worktree detection ship as library functions only** — `installGitHooks`/`uninstallGitHooks` (a `post-checkout`/`post-merge`/`post-commit`/`post-rewrite` hook running a command of your choosing, for environments where live watching isn't available) and `detectWorktree` (whether a root is a linked `git worktree`, and where its main repository lives). Neither is wired into plugin load or exposed as a model-visible tool: `.git/hooks/*` is shared, ambient state this package doesn't own, so installing it is left to a caller's own init script, never automatic.
138
155
  - **Exclusion unions the built-in default directories with the project's own `.gitignore`.** Build output that lands outside `node_modules`/`dist`/`build`/`coverage` (a `lib` a TypeScript project compiles to, say) is almost always gitignored too, and indexing it alongside its own source would hand call resolution two same-named declarations of one symbol to pick between arbitrarily. Only a practical subset of gitignore syntax is understood — no `**`, character classes, or per-directory `.gitignore` files. Turn it off with `respectGitignore: false`.
139
156
  - **Committed build output is left out by shape, not by `.gitignore`.** Some deployments commit `dist/` so a server can serve it straight from the repository, which makes it neither gitignored nor named in `exclude`. Those files are still bundler output: a workspace sampled here had 25 such files that contributed 90% of the declarations, 86% of the edges, and 92% of the unresolved call sites in a graph that otherwise described 335 source files — and their mangled one-letter names collided with real symbols, making the unique-name rule refuse calls it could have settled. `skipMinified` (default on) skips a file whose path carries a `.min.` segment, or whose average line length is past 500 characters — roughly 7× the widest average found in hand-written source — and reports the count as `files_minified`. It is a heuristic, not a build-system integration: naming the artifact directory in `exclude` is still the exact fix, and `skipMinified: false` indexes such files anyway.
140
157
  - **The unresolved tail can be large**, and most of it is not a gap. `unresolved_count` includes every member call and already-imported name a type-free resolver could never have settled; `unresolved_likely_internal_count` is the narrower number that reflects re-exports and dynamic dispatch the graph actually missed.
141
- - **`context` ranks by identifier-term overlap**, so a task phrased without naming any symbol ranks poorly. There is no semantic matching.
158
+ - **`context` ranks by identifier-term overlap**, so a task phrased without naming any symbol ranks poorly. The Chinese synonym table covers common development vocabulary, not arbitrary prose, and there is no semantic matching — a task whose subject appears nowhere in the table still ranks poorly.
142
159
  - `dsh` itself is in developer preview and iterating fast; expect compatibility-breaking changes.
143
160
 
144
161
  ## Credits
package/cordis.patch.yml CHANGED
@@ -25,6 +25,13 @@
25
25
  name: 'dsh-plugin-codegraph-tree-sitter'
26
26
 
27
27
  # Consumer: the model-facing `codegraph` and `codegraph_index` tools plus
28
- # their system-prompt section.
28
+ # their system-prompt section, the `/codegraph` command, and the small HTTP
29
+ # surface the settings panel reads.
29
30
  - id: codegraph-tool
30
31
  name: 'dsh-plugin-codegraph-tool'
32
+
33
+ # Client bundle: one settings tab that shows the workspace's index state and
34
+ # offers a rebuild button. Mounted as a row here so `dsh plugin add` brings
35
+ # the UI along with the tools.
36
+ - id: codegraph-panel
37
+ name: 'dsh-plugin-codegraph-panel'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-codegraph",
3
- "version": "0.1.7",
3
+ "version": "0.3.0",
4
4
  "description": "Structural code intelligence for DeepSeek Harness — gives the agent codegraph and codegraph_index tools to find where a symbol is declared, what calls it, what a change reaches, and how one symbol reaches another, from a tree-sitter index it builds itself",
5
5
  "keywords": [
6
6
  "dsh",
@@ -42,9 +42,10 @@
42
42
  }
43
43
  },
44
44
  "dependencies": {
45
- "dsh-plugin-codegraph-sqlite": "^0.1.7",
46
- "dsh-plugin-codegraph-tree-sitter": "^0.1.7",
47
- "dsh-plugin-codegraph-service": "^0.1.7",
48
- "dsh-plugin-codegraph-tool": "^0.1.7"
45
+ "dsh-plugin-codegraph-panel": "^0.3.0",
46
+ "dsh-plugin-codegraph-service": "^0.3.0",
47
+ "dsh-plugin-codegraph-tool": "^0.3.0",
48
+ "dsh-plugin-codegraph-tree-sitter": "^0.3.0",
49
+ "dsh-plugin-codegraph-sqlite": "^0.3.0"
49
50
  }
50
51
  }