@huanlin/dsh-plugin-codegraph 0.1.8

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CC ZHAO
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,157 @@
1
+ # dsh-plugin-codegraph
2
+
3
+ English | [中文](README.zh.md)
4
+
5
+ <p align="center">
6
+ <a href="https://dshfind.com/zh/plugins/huanlinoto/dsh-plugin-codegraph"><img src="https://dshfind.com/api/card/huanlinoto/dsh-plugin-codegraph?lang=zh" alt="dsh-plugin-codegraph card"></a>
7
+ </p>
8
+
9
+ Structural code intelligence for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (`dsh`).
10
+
11
+ Gives the agent two tools — `codegraph` and `codegraph_index` — so it can ask **where is this declared**, **who calls it**, **what breaks if I change it**, and **how does one symbol reach another**, answered from a pre-built index instead of from text search.
12
+
13
+ ```sh
14
+ dsh plugin --profile <name> add @huanlin/dsh-plugin-codegraph
15
+ ```
16
+
17
+
18
+ > **Fork notice:** This is the actively maintained fork of [CC19990113/dsh-plugin-codegraph](https://github.com/CC19990113/dsh-plugin-codegraph) (upstream inactive since v0.1.6, 2026-08). This fork tracks the DSH `0.1.2-rc.1` line and publishes under the `@huanlin` npm scope.
19
+
20
+ ## Why
21
+
22
+ An agent editing code asks structural questions before it touches anything. The tools it usually has answer them badly or not at all:
23
+
24
+ - **grep** matches a name inside comments, strings, and unrelated identifiers, and cannot answer "who calls this" at all.
25
+ - **LSP** answers precisely, but needs a running server per language, a warm workspace index, and a *cursor position* rather than a name.
26
+
27
+ A symbol graph answers all of it from one cheap lookup. This plugin ships both halves: a **store** that serves queries from an on-disk graph, and an **indexer** that builds one, so a fresh workspace needs no external tooling.
28
+
29
+ ## What the model gets
30
+
31
+ Two tools, deliberately separate.
32
+
33
+ ### `codegraph` — ten read-only operations
34
+
35
+ | Operation | Answers | Required |
36
+ |---|---|---|
37
+ | `search` | Where is a symbol declared? | `query` |
38
+ | `node` | One symbol with its immediate callers and callees | `symbol` |
39
+ | `callers` | What calls this? | `symbol` |
40
+ | `callees` | What does this call? | `symbol` |
41
+ | `impact` | What can a change to this reach? | `symbol` |
42
+ | `trace` | How does one symbol reach another? | `from`, `to` |
43
+ | `files` | What is indexed, under a directory or glob? | — |
44
+ | `status` | How large and how fresh is the index? | — |
45
+ | `explore` | Several related declarations with their source | `query` |
46
+ | `context` | Everything relevant to a task | `task` |
47
+
48
+ ### `codegraph_index` — build or refresh the graph
49
+
50
+ 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.
51
+
52
+ Indexing is always explicit. No query ever triggers it implicitly: a `callers` call that silently took four minutes would be indistinguishable, to the model, from a hung tool.
53
+
54
+ When no index exists, `status` answers plainly rather than failing — it says there is no index and names `codegraph_index` as the fix. Every other operation fails loudly instead, so an unindexed workspace is never mistaken for an empty one.
55
+
56
+ ## Interoperability with the `codegraph` CLI
57
+
58
+ The on-disk format is **not ours**. This plugin reads and writes **schema version 4 at `<projectRoot>/.codegraph/codegraph.db`** — the same path and format that [`@colbymchenry/codegraph`](https://github.com/colbymchenry/codegraph) writes.
59
+
60
+ That means:
61
+
62
+ - **Already using the `codegraph` CLI?** Its index is picked up as-is. Mount the plugin, skip `codegraph_index` entirely, and query.
63
+ - **Indexed with this plugin?** The CLI still reads it.
64
+ - There is never a second, disagreeing graph for one workspace.
65
+
66
+ ## Why not just spawn the CLI
67
+
68
+ A plugin can wrap `@colbymchenry/codegraph`'s own CLI instead of reimplementing the store and indexer: `spawn` it as a subprocess, expose each of its commands as a separate tool, done in an afternoon. This plugin chose not to, for three concrete reasons:
69
+
70
+ - **No second thing to install.** Shelling out to a CLI means the host needs that binary on `PATH`, at a version the plugin was actually tested against — an extra install step, and an extra way for the two to drift out of sync. `npm install` is the whole story here; the indexer and store run in-process.
71
+ - **Fewer tools, not more.** Every tool's schema rides along in the system prompt on every turn, whether or not it gets called that turn. Ten single-purpose tools (one per CLI subcommand) cost more of that budget, every turn, than the two this plugin exposes — `codegraph`'s `operation` field is a dispatch, not a compromise.
72
+ - **No incremental reparse, on purpose.** "Sync only the changed files" sounds obviously faster, but the rule this graph resolves calls by — one unique name wins workspace-wide — is global: adding a symbol in file A that collides with one already indexed from file B should invalidate edges that point at B, even though B never changed. A parser that reparses only the touched files and patches in their own new edges has no way to notice that. `codegraph_index` always rebuilds the whole graph instead — cheaper to reparse everything than to get that invalidation wrong — leaving incremental reparse as a future optimization only once it's an actual, measured bottleneck, not a default.
73
+
74
+ ## Language coverage
75
+
76
+ The bundled indexer parses **TypeScript, TSX, JavaScript, JSX, Python, Go, Java, C, C++, C#, PHP, Rust, Ruby, Zig, Kotlin, Swift, Dart, and Scala**. Grammars load lazily — one per language, on first sight of a matching file — so a Go-only workspace never loads a Python grammar.
77
+
78
+ The **store is format-bound, not language-bound**: a graph built by the `codegraph` CLI over languages this indexer does not parse is still fully queryable. If you need broader indexing coverage today, index with the CLI and query through this plugin.
79
+
80
+ ## Call resolution never guesses
81
+
82
+ Every call site resolves in a fixed order: an import that lands on an indexed file wins; otherwise a unique workspace-wide name wins; otherwise **no edge is emitted** and the site is recorded as unresolved.
83
+
84
+ 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.
85
+
86
+ ## Install
87
+
88
+ ```sh
89
+ dsh plugin --profile <name> add @huanlin/dsh-plugin-codegraph
90
+ ```
91
+
92
+ That one command is the whole install: it fetches the package and reconciles the profile's manifest for you, appending `dsh-plugin-codegraph` to `dsh.profile.bundles`. There is no JSON to edit by hand. Afterwards, `$DSH_HOME/profiles/<name>/package.json` — `$DSH_HOME` defaults to `~/.dsh` — reads like this, shown here so you can check it rather than write it:
93
+
94
+ ```jsonc
95
+ {
96
+ "dsh": {
97
+ "profile": {
98
+ "bundles": ["@deepseek-ai/dsh-base", "dsh-plugin-codegraph"]
99
+ }
100
+ }
101
+ }
102
+ ```
103
+
104
+ To confirm the four plugins mounted without spending an API key, run `dsh --profile <name> --dump-default-config`; they appear grouped under a `# == dsh-plugin-codegraph` heading.
105
+
106
+ The bundle mounts all four plugins in one layer. Retune any of them from the profile's own `cordis.patch.yml`, addressing rows by the ids the bundle declares (`codegraph`, `codegraph-sqlite`, `codegraph-tree-sitter`, `codegraph-tool`):
107
+
108
+ ```yaml
109
+ - id: codegraph-tree-sitter
110
+ config:
111
+ languages: ['typescript', 'tsx']
112
+ exclude: ['node_modules', 'dist', 'vendor']
113
+ respectGitignore: true
114
+ watch: true # the default; shown for clarity — set false to keep indexing purely explicit
115
+
116
+ - id: codegraph-tool
117
+ config:
118
+ maxLimit: 50
119
+ indexTimeoutMs: 600000
120
+ ```
121
+
122
+ ## Packages
123
+
124
+ Installing the bundle is enough; these are listed for anyone composing by hand.
125
+
126
+ | Package | Role |
127
+ |---|---|
128
+ | [`dsh-plugin-codegraph`](packages/bundle) | The bundle — depends on the four below and ships the patch layer |
129
+ | [`dsh-plugin-codegraph-service`](packages/service) | Service Definition: `ctx.codegraph`, the provider registries, the query vocabulary |
130
+ | [`dsh-plugin-codegraph-sqlite`](packages/sqlite) | Service Provider: read-only SQLite store over the on-disk graph |
131
+ | [`dsh-plugin-codegraph-tree-sitter`](packages/tree-sitter) | Service Provider: the tree-sitter indexer that writes that graph |
132
+ | [`dsh-plugin-codegraph-tool`](packages/tool) | Consumer: the model-facing tools, their bounds, and their rendering |
133
+
134
+ The split is not ceremony. The seam carries no source text and performs no filesystem access, so a store needs no filesystem capability at all; retrieving a declaration's code composes a graph query with a `ctx.fs` read in the consumer, which is the only role that can reach a remote workspace's files.
135
+
136
+ ## Known limits
137
+
138
+ - **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.
139
+ - **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.
140
+ - **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`.
141
+ - **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.
142
+ - **`context` ranks by identifier-term overlap**, so a task phrased without naming any symbol ranks poorly. There is no semantic matching.
143
+ - `dsh` itself is in developer preview and iterating fast; expect compatibility-breaking changes.
144
+
145
+ ## Credits
146
+
147
+ The on-disk graph format — schema version 4 at `.codegraph/codegraph.db` — originates with [`@colbymchenry/codegraph`](https://github.com/colbymchenry/codegraph) (MIT), a local-first code-intelligence tool for AI agents. This plugin adopts that format deliberately so the two remain mutually readable; the indexer, store, and tool here are independent implementations written against the DeepSeek Harness plugin model.
148
+
149
+ Built on [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) and [Cordis](https://github.com/cordiverse/cordis).
150
+
151
+ ## Feedback
152
+
153
+ Questions or need support? Open an [issue](https://github.com/HuanLinOTO/dsh-plugin-codegraph/issues).
154
+
155
+ ## License
156
+
157
+ [MIT](LICENSE)
@@ -0,0 +1,30 @@
1
+ # The @huanlin/dsh-plugin-codegraph bundle patch: mounts the whole code-graph capability
2
+ # as ONE layer over an existing dsh profile.
3
+ #
4
+ # Row order carries no load semantics — activation is service-availability
5
+ # driven — so the seam may appear before or after the providers that fill it.
6
+ # The user's own profile patch layer can address any row below by `id` to
7
+ # retune it (last write per row wins), e.g. restricting `languages` on the
8
+ # indexer or lowering `maxLimit` on the tool.
9
+
10
+ - insert:
11
+ # Service Definition: publishes ctx.codegraph, the store/indexer registries,
12
+ # and the eight normalized graph queries. Carries no store of its own.
13
+ - id: codegraph
14
+ name: '@huanlin/dsh-plugin-codegraph-service'
15
+
16
+ # Service Provider (read): serves queries from .codegraph/codegraph.db.
17
+ # Claims a project root only when that file already exists.
18
+ - id: codegraph-sqlite
19
+ name: '@huanlin/dsh-plugin-codegraph-sqlite'
20
+
21
+ # Service Provider (write): builds that same schema-v4 file with
22
+ # web-tree-sitter. Registers ONLY an indexer, never a store, so the seam's
23
+ # one-claimant-per-root rule stays intact.
24
+ - id: codegraph-tree-sitter
25
+ name: '@huanlin/dsh-plugin-codegraph-tree-sitter'
26
+
27
+ # Consumer: the model-facing `codegraph` and `codegraph_index` tools plus
28
+ # their system-prompt section.
29
+ - id: codegraph-tool
30
+ name: '@huanlin/dsh-plugin-codegraph-tool'
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@huanlin/dsh-plugin-codegraph",
3
+ "version": "0.1.8",
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
+ "keywords": [
6
+ "dsh",
7
+ "dsh-plugin",
8
+ "deepseek-harness",
9
+ "deepseek",
10
+ "cordis",
11
+ "cordis-plugin",
12
+ "codegraph",
13
+ "code-graph",
14
+ "call-graph",
15
+ "tree-sitter",
16
+ "code-intelligence",
17
+ "static-analysis",
18
+ "ai-agent",
19
+ "llm-tools",
20
+ "agent-tools"
21
+ ],
22
+ "license": "MIT",
23
+ "author": "CC ZHAO",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/HuanLinOTO/dsh-plugin-codegraph.git",
27
+ "directory": "packages/bundle"
28
+ },
29
+ "homepage": "https://github.com/HuanLinOTO/dsh-plugin-codegraph#readme",
30
+ "bugs": "https://github.com/HuanLinOTO/dsh-plugin-codegraph/issues",
31
+ "type": "module",
32
+ "files": [
33
+ "cordis.patch.yml"
34
+ ],
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "dsh": {
39
+ "bundle": {
40
+ "patch": "./cordis.patch.yml"
41
+ }
42
+ },
43
+ "dependencies": {
44
+ "@huanlin/dsh-plugin-codegraph-sqlite": "^0.1.8",
45
+ "@huanlin/dsh-plugin-codegraph-service": "^0.1.8",
46
+ "@huanlin/dsh-plugin-codegraph-tool": "^0.1.8",
47
+ "@huanlin/dsh-plugin-codegraph-tree-sitter": "^0.1.8"
48
+ }
49
+ }