@huanlin/dsh-plugin-codegraph-sqlite 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,17 @@
1
+ # @huanlin/dsh-plugin-codegraph-sqlite
2
+
3
+ Read-only SQLite store for the code-graph seam. Serves structural queries from the graph at `.codegraph/codegraph.db` — the same on-disk format the `codegraph` CLI writes — opening it read-only and gating on its recorded format version. Reads schema v4 (what `@huanlin/dsh-plugin-codegraph-tree-sitter` builds) and schema v8 (what the `codegraph` CLI ≥1.5 writes); the queries touch only the tables both versions share.
4
+
5
+ Part of **[dsh-plugin-codegraph](https://github.com/CC19990113/dsh-plugin-codegraph)** — structural code intelligence for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness).
6
+
7
+ Most users should install the bundle instead, which mounts this package and its siblings in one layer:
8
+
9
+ ```sh
10
+ dsh plugin --profile <name> add dsh-plugin-codegraph
11
+ ```
12
+
13
+ See the [project README](https://github.com/CC19990113/dsh-plugin-codegraph#readme) for setup, configuration, and the full tool reference.
14
+
15
+ ## License
16
+
17
+ [MIT](LICENSE)
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Connection ownership for the on-disk knowledge graph: where a project root's database lives, the
3
+ * format-version gate every connection passes before serving a query, and the bounded pool that
4
+ * keeps recently queried projects open.
5
+ *
6
+ * Databases open READ-ONLY. The external indexer may be writing through its own daemon while the
7
+ * harness reads, so this store never takes a write lock, never recovers a journal, and never repairs
8
+ * an index it does not own.
9
+ * @module @huanlin/dsh-plugin-codegraph-sqlite/database
10
+ */
11
+ import { DatabaseSync } from 'node:sqlite';
12
+ /**
13
+ * Where the external indexer keeps a project's graph, relative to the project root. Fixed by that
14
+ * tool's on-disk layout rather than configurable: pointing this store at another path would not make
15
+ * a different file readable, it would only fail later and less clearly.
16
+ */
17
+ export declare const DATABASE_RELATIVE_PATH = ".codegraph/codegraph.db";
18
+ /**
19
+ * The on-disk format versions this store reads. The format is an external specification, so support
20
+ * is a fixed fact rather than a deployment choice; a database at any other version fails loud
21
+ * instead of being read through assumptions that no longer hold.
22
+ *
23
+ * Two writers share this file, one per version: `@huanlin/dsh-plugin-codegraph-tree-sitter` builds schema v4,
24
+ * and the `@colbymchenry/codegraph` CLI (≥1.5, whose daemon may own the same index) stamps schema
25
+ * v8 — its `nodes`/`edges`/`files`/`nodes_fts` tables keep every column the store reads and only add
26
+ * ones the store never touches (`unresolved_refs` is reshaped, `project_metadata` and
27
+ * `name_segment_vocab` are new, and no store query reads any of the three).
28
+ */
29
+ export declare const SUPPORTED_FORMAT_VERSIONS: readonly number[];
30
+ /**
31
+ * The absolute path of a project root's graph database.
32
+ * @param projectRoot - absolute path of the indexed project root.
33
+ * @returns the database path, whether or not it exists.
34
+ */
35
+ export declare function databasePath(projectRoot: string): string;
36
+ /**
37
+ * Open one project's graph read-only and verify its format version.
38
+ * @param projectRoot - absolute path of the indexed project root.
39
+ * @returns the open, version-checked connection.
40
+ */
41
+ export declare function openGraph(projectRoot: string): DatabaseSync;
42
+ /**
43
+ * A bounded set of open graph connections keyed by project root, evicting the least recently used
44
+ * one when full. Every connection the pool hands out stays valid until {@link close}: eviction and
45
+ * disposal both close connections, so a caller holds a connection only for the duration of one
46
+ * synchronous query.
47
+ *
48
+ * A connection is opened against one specific on-disk file. An indexing run replaces that file
49
+ * wholesale (rename over the old path), and POSIX unlink semantics mean an already-open read-only
50
+ * connection keeps serving the REPLACED file's bytes indefinitely — reopening is the only way to see
51
+ * the new graph. `acquire` detects that swap by comparing the device/inode recorded at open time
52
+ * against the path's current identity, so a cache hit never silently serves a graph an indexing run
53
+ * has already superseded.
54
+ */
55
+ export declare class GraphPool {
56
+ private readonly capacity;
57
+ private readonly open;
58
+ private disposed;
59
+ /**
60
+ * @param capacity - largest number of simultaneously open databases; at least 1.
61
+ */
62
+ constructor(capacity: number);
63
+ /**
64
+ * The connection for a project root, opening and caching it on first use. Reopens automatically
65
+ * when the file on disk is no longer the one the cached connection was opened against.
66
+ * @param projectRoot - absolute path of the indexed project root.
67
+ * @returns the open, version-checked connection, current as of this call.
68
+ */
69
+ acquire(projectRoot: string): DatabaseSync;
70
+ /** Close every open connection; further {@link acquire} calls fail as `CODEGRAPH_DISPOSED`. */
71
+ close(): void;
72
+ /** Close least-recently-used connections until the pool fits its capacity. */
73
+ private evictOverflow;
74
+ }
75
+ //# sourceMappingURL=database.d.ts.map
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Connection ownership for the on-disk knowledge graph: where a project root's database lives, the
3
+ * format-version gate every connection passes before serving a query, and the bounded pool that
4
+ * keeps recently queried projects open.
5
+ *
6
+ * Databases open READ-ONLY. The external indexer may be writing through its own daemon while the
7
+ * harness reads, so this store never takes a write lock, never recovers a journal, and never repairs
8
+ * an index it does not own.
9
+ * @module @huanlin/dsh-plugin-codegraph-sqlite/database
10
+ */
11
+ import { DatabaseSync } from 'node:sqlite';
12
+ import { statSync } from 'node:fs';
13
+ import { join } from 'node:path';
14
+ import { CodegraphError } from '@huanlin/dsh-plugin-codegraph-service';
15
+ /**
16
+ * Where the external indexer keeps a project's graph, relative to the project root. Fixed by that
17
+ * tool's on-disk layout rather than configurable: pointing this store at another path would not make
18
+ * a different file readable, it would only fail later and less clearly.
19
+ */
20
+ export const DATABASE_RELATIVE_PATH = '.codegraph/codegraph.db';
21
+ /**
22
+ * The on-disk format versions this store reads. The format is an external specification, so support
23
+ * is a fixed fact rather than a deployment choice; a database at any other version fails loud
24
+ * instead of being read through assumptions that no longer hold.
25
+ *
26
+ * Two writers share this file, one per version: `@huanlin/dsh-plugin-codegraph-tree-sitter` builds schema v4,
27
+ * and the `@colbymchenry/codegraph` CLI (≥1.5, whose daemon may own the same index) stamps schema
28
+ * v8 — its `nodes`/`edges`/`files`/`nodes_fts` tables keep every column the store reads and only add
29
+ * ones the store never touches (`unresolved_refs` is reshaped, `project_metadata` and
30
+ * `name_segment_vocab` are new, and no store query reads any of the three).
31
+ */
32
+ export const SUPPORTED_FORMAT_VERSIONS = [4, 8];
33
+ /**
34
+ * The absolute path of a project root's graph database.
35
+ * @param projectRoot - absolute path of the indexed project root.
36
+ * @returns the database path, whether or not it exists.
37
+ */
38
+ export function databasePath(projectRoot) {
39
+ return join(projectRoot, DATABASE_RELATIVE_PATH);
40
+ }
41
+ /**
42
+ * The format version recorded in an open database.
43
+ * @param db - an open connection.
44
+ * @returns the highest applied schema version.
45
+ */
46
+ function readFormatVersion(db) {
47
+ const row = db.prepare('SELECT MAX(version) AS version FROM schema_versions').get();
48
+ const version = row?.version;
49
+ if (version === null || version === undefined) {
50
+ throw new CodegraphError('the code graph records no schema version', 'CODEGRAPH_MALFORMED_INDEX');
51
+ }
52
+ return Number(version);
53
+ }
54
+ /**
55
+ * A path's current on-disk identity, or `undefined` when it cannot be stat'd (most commonly: an
56
+ * indexing run's atomic replace is between removing the old file and renaming the new one into place).
57
+ * That absence is treated as "unknown, not gone" by every caller — a transient rebuild window must
58
+ * never look like a missing graph.
59
+ * @param path - the file to identify.
60
+ */
61
+ function identify(path) {
62
+ try {
63
+ const stats = statSync(path);
64
+ return { dev: stats.dev, ino: stats.ino };
65
+ }
66
+ catch {
67
+ return undefined;
68
+ }
69
+ }
70
+ /** Whether two identities name the same underlying file. */
71
+ function sameIdentity(a, b) {
72
+ return a.dev === b.dev && a.ino === b.ino;
73
+ }
74
+ /**
75
+ * Open one project's graph read-only and verify its format version.
76
+ * @param projectRoot - absolute path of the indexed project root.
77
+ * @returns the open, version-checked connection.
78
+ */
79
+ export function openGraph(projectRoot) {
80
+ const path = databasePath(projectRoot);
81
+ let db;
82
+ try {
83
+ db = new DatabaseSync(path, { readOnly: true });
84
+ }
85
+ catch (cause) {
86
+ throw new CodegraphError(`cannot open the code graph at "${path}"`, 'CODEGRAPH_UNAVAILABLE', { cause });
87
+ }
88
+ let version;
89
+ try {
90
+ version = readFormatVersion(db);
91
+ }
92
+ catch (error) {
93
+ db.close();
94
+ throw error;
95
+ }
96
+ if (!SUPPORTED_FORMAT_VERSIONS.includes(version)) {
97
+ db.close();
98
+ throw new CodegraphError(`the code graph at "${path}" is format version ${version}; this store reads version ${SUPPORTED_FORMAT_VERSIONS.join(' or ')}`, 'CODEGRAPH_UNSUPPORTED_FORMAT');
99
+ }
100
+ return db;
101
+ }
102
+ /**
103
+ * A bounded set of open graph connections keyed by project root, evicting the least recently used
104
+ * one when full. Every connection the pool hands out stays valid until {@link close}: eviction and
105
+ * disposal both close connections, so a caller holds a connection only for the duration of one
106
+ * synchronous query.
107
+ *
108
+ * A connection is opened against one specific on-disk file. An indexing run replaces that file
109
+ * wholesale (rename over the old path), and POSIX unlink semantics mean an already-open read-only
110
+ * connection keeps serving the REPLACED file's bytes indefinitely — reopening is the only way to see
111
+ * the new graph. `acquire` detects that swap by comparing the device/inode recorded at open time
112
+ * against the path's current identity, so a cache hit never silently serves a graph an indexing run
113
+ * has already superseded.
114
+ */
115
+ export class GraphPool {
116
+ capacity;
117
+ open = new Map();
118
+ disposed = false;
119
+ /**
120
+ * @param capacity - largest number of simultaneously open databases; at least 1.
121
+ */
122
+ constructor(capacity) {
123
+ this.capacity = capacity;
124
+ }
125
+ /**
126
+ * The connection for a project root, opening and caching it on first use. Reopens automatically
127
+ * when the file on disk is no longer the one the cached connection was opened against.
128
+ * @param projectRoot - absolute path of the indexed project root.
129
+ * @returns the open, version-checked connection, current as of this call.
130
+ */
131
+ acquire(projectRoot) {
132
+ if (this.disposed) {
133
+ throw new CodegraphError('the code-graph store is disposed', 'CODEGRAPH_DISPOSED');
134
+ }
135
+ const cached = this.open.get(projectRoot);
136
+ if (cached !== undefined) {
137
+ const current = identify(databasePath(projectRoot));
138
+ // `undefined` means the path is transiently unstatable — most likely an indexing run's replace
139
+ // is mid-flight between removing the old file and renaming the new one into place. Keep serving
140
+ // the connection we have rather than treating a rebuild-in-progress as a missing graph.
141
+ if (current === undefined || sameIdentity(current, cached.identity)) {
142
+ // Re-insert to mark most recently used; Map iteration order is insertion order.
143
+ this.open.delete(projectRoot);
144
+ this.open.set(projectRoot, cached);
145
+ return cached.db;
146
+ }
147
+ cached.db.close();
148
+ this.open.delete(projectRoot);
149
+ }
150
+ const db = openGraph(projectRoot);
151
+ const identity = identify(databasePath(projectRoot));
152
+ // Only `undefined` when the file vanishes in the instant between opening it and this stat — an
153
+ // unprovokable race in tests. The sentinel never matches a real identity, so the next acquire()
154
+ // is forced to re-verify rather than trusting an unconfirmed connection indefinitely.
155
+ /* v8 ignore next */
156
+ this.open.set(projectRoot, { db, identity: identity ?? { dev: -1, ino: -1 } });
157
+ this.evictOverflow();
158
+ return db;
159
+ }
160
+ /** Close every open connection; further {@link acquire} calls fail as `CODEGRAPH_DISPOSED`. */
161
+ close() {
162
+ this.disposed = true;
163
+ for (const { db } of this.open.values())
164
+ db.close();
165
+ this.open.clear();
166
+ }
167
+ /** Close least-recently-used connections until the pool fits its capacity. */
168
+ evictOverflow() {
169
+ while (this.open.size > this.capacity) {
170
+ // Map iteration starts at the least recently used entry, and `acquire` re-inserts on a hit,
171
+ // so the first entry is always the eviction candidate.
172
+ for (const [root, entry] of this.open) {
173
+ entry.db.close();
174
+ this.open.delete(root);
175
+ break;
176
+ }
177
+ }
178
+ }
179
+ }
180
+ //# sourceMappingURL=database.js.map
package/lib/index.d.ts ADDED
@@ -0,0 +1,66 @@
1
+ /**
2
+ * SQLite graph store for `ctx.codegraph`. One plugin instance registers one store that answers every
3
+ * seam operation from the on-disk knowledge graph an external `codegraph` indexer writes to
4
+ * `<projectRoot>/.codegraph/codegraph.db`, opening each project read-only and keeping a bounded set
5
+ * of connections warm.
6
+ *
7
+ * The store is host-local by construction: `node:sqlite` opens a path on the machine running the
8
+ * harness, so availability is decided against the host filesystem rather than `ctx.fs`. A workspace
9
+ * that lives in a remote sandbox is not served by this store even when `ctx.fs` can read its files —
10
+ * reporting availability from `ctx.fs` would claim a root the store then fails to open.
11
+ *
12
+ * Namespace plugin (named exports, no default export). Lifecycle is effect-scoped: disposal
13
+ * unregisters from `ctx.codegraph` first, then closes every open connection.
14
+ * @module @huanlin/dsh-plugin-codegraph-sqlite
15
+ */
16
+ import type { Context } from '@deepseek-ai/cordis';
17
+ import z from '@deepseek-ai/schemastery';
18
+ export { DATABASE_RELATIVE_PATH, GraphPool, SUPPORTED_FORMAT_VERSIONS, databasePath, openGraph, } from './database.ts';
19
+ export { toEdge, toFile, toNode } from './rows.ts';
20
+ export { ftsPhrase, likeAnywhere } from './sql.ts';
21
+ export { walkImpact, walkTrace, type ImpactHit, type ImpactWalk, type Step, type TraceWalk } from './traverse.ts';
22
+ /** Cordis plugin name for loader diagnostics. */
23
+ export declare const name = "codegraph-sqlite";
24
+ /** Services required by this plugin. */
25
+ export declare const inject: string[];
26
+ /** Default branded identity this store reserves on the seam. */
27
+ export declare const DEFAULT_STORE_ID = "codegraph-sqlite";
28
+ /** Default number of project databases kept open at once. */
29
+ export declare const DEFAULT_MAX_OPEN_DATABASES = 4;
30
+ /** Default ceiling on distinct nodes one `impact` or `trace` walk may visit. */
31
+ export declare const DEFAULT_MAX_TRAVERSAL_NODES = 20000;
32
+ /** Default ceiling on indexed files one `status` call stats on the host filesystem for freshness. */
33
+ export declare const DEFAULT_MAX_STALENESS_CHECKS = 2000;
34
+ /** Plugin configuration: store identity and the bounds the seam's requests cannot express. */
35
+ export interface Config {
36
+ /**
37
+ * Branded identity to reserve on `ctx.codegraph`. Give each instance its own id when mounting
38
+ * more than one, so a duplicate registration fails at load instead of shadowing the first store.
39
+ */
40
+ storeId?: string;
41
+ /**
42
+ * Largest number of project databases held open at once (default 4). The least recently queried
43
+ * connection closes when the limit is exceeded; a project queried again simply reopens.
44
+ */
45
+ maxOpenDatabases?: number;
46
+ /**
47
+ * Largest number of distinct nodes one `impact` or `trace` walk may visit (default 20000). A
48
+ * request's `depth`, `limit`, and `maxPaths` bound the answer; this bounds the work, so a query
49
+ * against a large monorepo returns a truncated answer instead of running unboundedly.
50
+ */
51
+ maxTraversalNodes?: number;
52
+ /**
53
+ * Largest number of indexed files one `status` call stats on the host filesystem to detect
54
+ * staleness (default 2000). A repository indexing more files than this gets a lower-bound stale
55
+ * count instead of a `status` call that stats every file it ever indexed.
56
+ */
57
+ maxStalenessChecks?: number;
58
+ }
59
+ export declare const Config: z<Config>;
60
+ /**
61
+ * Register the SQLite graph store.
62
+ * @param ctx - the plugin context (must inject `codegraph`).
63
+ * @param config - the resolved plugin configuration.
64
+ */
65
+ export declare function apply(ctx: Context, config: Config): void;
66
+ //# sourceMappingURL=index.d.ts.map
package/lib/index.js ADDED
@@ -0,0 +1,119 @@
1
+ /**
2
+ * SQLite graph store for `ctx.codegraph`. One plugin instance registers one store that answers every
3
+ * seam operation from the on-disk knowledge graph an external `codegraph` indexer writes to
4
+ * `<projectRoot>/.codegraph/codegraph.db`, opening each project read-only and keeping a bounded set
5
+ * of connections warm.
6
+ *
7
+ * The store is host-local by construction: `node:sqlite` opens a path on the machine running the
8
+ * harness, so availability is decided against the host filesystem rather than `ctx.fs`. A workspace
9
+ * that lives in a remote sandbox is not served by this store even when `ctx.fs` can read its files —
10
+ * reporting availability from `ctx.fs` would claim a root the store then fails to open.
11
+ *
12
+ * Namespace plugin (named exports, no default export). Lifecycle is effect-scoped: disposal
13
+ * unregisters from `ctx.codegraph` first, then closes every open connection.
14
+ * @module @huanlin/dsh-plugin-codegraph-sqlite
15
+ */
16
+ import { access } from 'node:fs/promises';
17
+ import z from '@deepseek-ai/schemastery';
18
+ import { CodegraphStoreId } from '@huanlin/dsh-plugin-codegraph-service';
19
+ import { assertNever } from '@deepseek-ai/dsh-util-values';
20
+ import { GraphPool, databasePath } from "./database.js";
21
+ import { files, impact, node, relations, search, status, trace } from "./queries.js";
22
+ import { walkImpact, walkTrace } from "./traverse.js";
23
+ export { DATABASE_RELATIVE_PATH, GraphPool, SUPPORTED_FORMAT_VERSIONS, databasePath, openGraph, } from "./database.js";
24
+ export { toEdge, toFile, toNode } from "./rows.js";
25
+ export { ftsPhrase, likeAnywhere } from "./sql.js";
26
+ export { walkImpact, walkTrace } from "./traverse.js";
27
+ /** Cordis plugin name for loader diagnostics. */
28
+ export const name = 'codegraph-sqlite';
29
+ /** Services required by this plugin. */
30
+ export const inject = ['codegraph'];
31
+ /** Default branded identity this store reserves on the seam. */
32
+ export const DEFAULT_STORE_ID = 'codegraph-sqlite';
33
+ /** Default number of project databases kept open at once. */
34
+ export const DEFAULT_MAX_OPEN_DATABASES = 4;
35
+ /** Default ceiling on distinct nodes one `impact` or `trace` walk may visit. */
36
+ export const DEFAULT_MAX_TRAVERSAL_NODES = 20_000;
37
+ /** Default ceiling on indexed files one `status` call stats on the host filesystem for freshness. */
38
+ export const DEFAULT_MAX_STALENESS_CHECKS = 2_000;
39
+ export const Config = z.object({
40
+ storeId: z.string().default(DEFAULT_STORE_ID),
41
+ maxOpenDatabases: z.number().default(DEFAULT_MAX_OPEN_DATABASES),
42
+ maxTraversalNodes: z.number().default(DEFAULT_MAX_TRAVERSAL_NODES),
43
+ maxStalenessChecks: z.number().default(DEFAULT_MAX_STALENESS_CHECKS),
44
+ });
45
+ /**
46
+ * Register the SQLite graph store.
47
+ * @param ctx - the plugin context (must inject `codegraph`).
48
+ * @param config - the resolved plugin configuration.
49
+ */
50
+ export function apply(ctx, config) {
51
+ const resolved = config;
52
+ assertPositiveInteger('maxOpenDatabases', resolved.maxOpenDatabases);
53
+ assertPositiveInteger('maxTraversalNodes', resolved.maxTraversalNodes);
54
+ assertPositiveInteger('maxStalenessChecks', resolved.maxStalenessChecks);
55
+ const pool = new GraphPool(resolved.maxOpenDatabases);
56
+ const store = {
57
+ id: CodegraphStoreId(resolved.storeId),
58
+ async indexes(projectRoot) {
59
+ try {
60
+ await access(databasePath(projectRoot));
61
+ return true;
62
+ }
63
+ catch {
64
+ // Only the existence probe runs in the try. Any rejection — missing file, missing
65
+ // directory, or no permission to look — means this store cannot serve the root, which is
66
+ // the answer the seam asked for rather than a failure to report.
67
+ return false;
68
+ }
69
+ },
70
+ query(request) {
71
+ return Promise.resolve(run(pool, resolved, request));
72
+ },
73
+ };
74
+ ctx.effect(function* () {
75
+ // Registered first, so it disposes LAST: the store unregisters before its connections close,
76
+ // and no query can be routed to a pool that is already shut.
77
+ yield () => {
78
+ pool.close();
79
+ };
80
+ yield ctx.codegraph.registerStore(store);
81
+ }, 'codegraph-sqlite');
82
+ }
83
+ /**
84
+ * Answer one request from the pooled connection for its project root.
85
+ * @param pool - the store's connection pool.
86
+ * @param config - the resolved plugin configuration.
87
+ * @param request - the normalized seam request.
88
+ * @returns the result member matching `request.operation`.
89
+ */
90
+ function run(pool, config, request) {
91
+ const db = pool.acquire(request.projectRoot);
92
+ switch (request.operation) {
93
+ case 'search':
94
+ return search(db, request);
95
+ case 'node':
96
+ return node(db, request);
97
+ case 'callers':
98
+ case 'callees':
99
+ return relations(db, request);
100
+ case 'impact':
101
+ return impact(db, request, (origin, depth) => walkImpact(db, origin, depth, config.maxTraversalNodes));
102
+ case 'trace':
103
+ return trace(db, request, (from, to, maxDepth, maxPaths) => walkTrace(db, from, to, maxDepth, maxPaths, config.maxTraversalNodes));
104
+ case 'files':
105
+ return files(db, request);
106
+ case 'status':
107
+ return status(db, request.projectRoot, config.maxStalenessChecks);
108
+ /* v8 ignore next -- exhaustive over the seam's closed operation union; unreachable. */
109
+ default:
110
+ return assertNever(request, 'codegraph-sqlite request');
111
+ }
112
+ }
113
+ /** Reject a non-positive-integer config value at load, so misconfiguration fails loud. */
114
+ function assertPositiveInteger(field, value) {
115
+ if (!Number.isInteger(value) || value < 1) {
116
+ throw new Error(`codegraph-sqlite: ${field} must be a positive integer`);
117
+ }
118
+ }
119
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Package-owned invariant companion for `dsh-plugin-codegraph-sqlite`.
3
+ * @module dsh-plugin-codegraph-sqlite/invariant
4
+ */
5
+ import type { Context } from '@deepseek-ai/cordis';
6
+ /** Cordis companion plugin name. */
7
+ export declare const name = "codegraph-sqlite-invariant";
8
+ /** Service required before the companion can reserve package ownership. */
9
+ export declare const inject: string[];
10
+ /**
11
+ * Register this package's invariant companion.
12
+ * @param ctx - Cordis context carrying the invariant service.
13
+ * @returns the installed registration's disposer after setup succeeds.
14
+ */
15
+ export declare const apply: (ctx: Context) => Promise<() => void>;
16
+ //# sourceMappingURL=invariant.d.ts.map
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Package-owned invariant companion for `dsh-plugin-codegraph-sqlite`.
3
+ * @module dsh-plugin-codegraph-sqlite/invariant
4
+ */
5
+ const PACKAGE_NAME = 'dsh-plugin-codegraph-sqlite';
6
+ /** Cordis companion plugin name. */
7
+ export const name = 'codegraph-sqlite-invariant';
8
+ /** Service required before the companion can reserve package ownership. */
9
+ export const inject = ['invariants'];
10
+ /**
11
+ * No runtime invariant: the store owns no mutable harness data and emits no event. Its connection
12
+ * pool is private, and the graph it reads is a file another tool writes, so there is no owned
13
+ * relation between two harness-visible values to compare.
14
+ */
15
+ const install = () => { };
16
+ /**
17
+ * Register this package's invariant companion.
18
+ * @param ctx - Cordis context carrying the invariant service.
19
+ * @returns the installed registration's disposer after setup succeeds.
20
+ */
21
+ export const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
22
+ /* jscpd:ignore-end */
23
+ //# sourceMappingURL=invariant.js.map
@@ -0,0 +1,66 @@
1
+ /**
2
+ * The eight seam operations against one open graph database. Every function here is synchronous:
3
+ * `node:sqlite` is a synchronous binding, so a query either completes within one turn or throws,
4
+ * and the store's async surface exists for the seam's contract rather than for I/O interleaving.
5
+ * @module @huanlin/dsh-plugin-codegraph-sqlite/queries
6
+ */
7
+ import type { DatabaseSync } from 'node:sqlite';
8
+ import type { CodegraphCalleesRequest, CodegraphCallersRequest, CodegraphFilesRequest, CodegraphFilesResult, CodegraphImpactRequest, CodegraphImpactResult, CodegraphNodeRequest, CodegraphNodeResult, CodegraphRelationsResult, CodegraphSearchRequest, CodegraphSearchResult, CodegraphStatusResult, CodegraphTraceRequest, CodegraphTraceResult } from '@huanlin/dsh-plugin-codegraph-service';
9
+ import type { ImpactWalk, TraceWalk } from './traverse.ts';
10
+ /**
11
+ * Find declarations matching a free-text query.
12
+ * @param db - the open graph connection.
13
+ * @param request - the search query with its resolved bounds.
14
+ * @returns the matching declarations, most relevant first, with the pre-limit total.
15
+ */
16
+ export declare function search(db: DatabaseSync, request: CodegraphSearchRequest): CodegraphSearchResult;
17
+ /**
18
+ * Resolve one symbol and read its immediate neighbourhood.
19
+ * @param db - the open graph connection.
20
+ * @param request - the node query with its resolved bounds.
21
+ * @returns the resolved declaration with its one-hop relations, or a null subject when the name
22
+ * matches nothing.
23
+ */
24
+ export declare function node(db: DatabaseSync, request: CodegraphNodeRequest): CodegraphNodeResult;
25
+ /**
26
+ * Find the declarations that call, or are called by, one symbol.
27
+ * @param db - the open graph connection.
28
+ * @param request - the callers or callees query; its operation picks the direction walked.
29
+ * @returns the distinct related declarations with their earliest call sites and repeat counts.
30
+ */
31
+ export declare function relations(db: DatabaseSync, request: CodegraphCallersRequest | CodegraphCalleesRequest): CodegraphRelationsResult;
32
+ /**
33
+ * Walk dependents transitively.
34
+ * @param db - the open graph connection.
35
+ * @param request - the impact query.
36
+ * @param walk - the reverse-reachability walk, injected so the traversal budget stays with the
37
+ * plugin that configures it.
38
+ * @returns the affected declarations, nearest first.
39
+ */
40
+ export declare function impact(db: DatabaseSync, request: CodegraphImpactRequest, walk: ImpactWalk): CodegraphImpactResult;
41
+ /**
42
+ * Find shortest directed paths between two symbols.
43
+ * @param db - the open graph connection.
44
+ * @param request - the trace query.
45
+ * @param walk - the shortest-path sweep, injected so the traversal budget stays with the plugin that
46
+ * configures it.
47
+ * @returns the paths, each as ordered hops from origin to destination.
48
+ */
49
+ export declare function trace(db: DatabaseSync, request: CodegraphTraceRequest, walk: TraceWalk): CodegraphTraceResult;
50
+ /**
51
+ * List indexed files under an optional subtree and glob.
52
+ * @param db - the open graph connection.
53
+ * @param request - the files query with its resolved bounds.
54
+ * @returns the matching files ordered by path, with the pre-limit total.
55
+ */
56
+ export declare function files(db: DatabaseSync, request: CodegraphFilesRequest): CodegraphFilesResult;
57
+ /**
58
+ * Report index size, language coverage, and freshness.
59
+ * @param db - the open graph connection.
60
+ * @param projectRoot - the project root the result echoes back, since the graph does not record it.
61
+ * @param maxStalenessChecks - largest number of indexed files to stat on the host filesystem when
62
+ * looking for drift, so a call against a very large index stays cheap.
63
+ * @returns the index summary.
64
+ */
65
+ export declare function status(db: DatabaseSync, projectRoot: string, maxStalenessChecks: number): CodegraphStatusResult;
66
+ //# sourceMappingURL=queries.d.ts.map