@optave/codegraph 3.1.3 → 3.1.5
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 +38 -84
- package/package.json +13 -8
- package/src/ast-analysis/engine.js +32 -12
- package/src/ast-analysis/shared.js +6 -5
- package/src/cli/commands/ast.js +22 -0
- package/src/cli/commands/audit.js +45 -0
- package/src/cli/commands/batch.js +68 -0
- package/src/cli/commands/branch-compare.js +21 -0
- package/src/cli/commands/build.js +26 -0
- package/src/cli/commands/cfg.js +26 -0
- package/src/cli/commands/check.js +74 -0
- package/src/cli/commands/children.js +28 -0
- package/src/cli/commands/co-change.js +67 -0
- package/src/cli/commands/communities.js +19 -0
- package/src/cli/commands/complexity.js +46 -0
- package/src/cli/commands/context.js +30 -0
- package/src/cli/commands/cycles.js +32 -0
- package/src/cli/commands/dataflow.js +28 -0
- package/src/cli/commands/deps.js +12 -0
- package/src/cli/commands/diff-impact.js +26 -0
- package/src/cli/commands/embed.js +30 -0
- package/src/cli/commands/export.js +78 -0
- package/src/cli/commands/exports.js +14 -0
- package/src/cli/commands/flow.js +32 -0
- package/src/cli/commands/fn-impact.js +26 -0
- package/src/cli/commands/impact.js +12 -0
- package/src/cli/commands/info.js +76 -0
- package/src/cli/commands/map.js +19 -0
- package/src/cli/commands/mcp.js +18 -0
- package/src/cli/commands/models.js +19 -0
- package/src/cli/commands/owners.js +25 -0
- package/src/cli/commands/path.js +36 -0
- package/src/cli/commands/plot.js +89 -0
- package/src/cli/commands/query.js +45 -0
- package/src/cli/commands/registry.js +100 -0
- package/src/cli/commands/roles.js +30 -0
- package/src/cli/commands/search.js +42 -0
- package/src/cli/commands/sequence.js +28 -0
- package/src/cli/commands/snapshot.js +66 -0
- package/src/cli/commands/stats.js +15 -0
- package/src/cli/commands/structure.js +33 -0
- package/src/cli/commands/triage.js +78 -0
- package/src/cli/commands/watch.js +12 -0
- package/src/cli/commands/where.js +20 -0
- package/src/cli/index.js +124 -0
- package/src/cli/shared/open-graph.js +13 -0
- package/src/cli/shared/options.js +59 -0
- package/src/cli/shared/output.js +1 -0
- package/src/cli.js +11 -1522
- package/src/db/connection.js +130 -7
- package/src/{db.js → db/index.js} +17 -5
- package/src/db/migrations.js +42 -1
- package/src/db/query-builder.js +20 -12
- package/src/db/repository/base.js +201 -0
- package/src/db/repository/graph-read.js +7 -4
- package/src/db/repository/in-memory-repository.js +575 -0
- package/src/db/repository/index.js +5 -1
- package/src/db/repository/nodes.js +60 -6
- package/src/db/repository/sqlite-repository.js +219 -0
- package/src/domain/analysis/context.js +408 -0
- package/src/domain/analysis/dependencies.js +341 -0
- package/src/domain/analysis/exports.js +134 -0
- package/src/domain/analysis/impact.js +466 -0
- package/src/domain/analysis/module-map.js +322 -0
- package/src/domain/analysis/roles.js +45 -0
- package/src/domain/analysis/symbol-lookup.js +238 -0
- package/src/domain/graph/builder/context.js +85 -0
- package/src/domain/graph/builder/helpers.js +218 -0
- package/src/domain/graph/builder/incremental.js +178 -0
- package/src/domain/graph/builder/pipeline.js +130 -0
- package/src/domain/graph/builder/stages/build-edges.js +297 -0
- package/src/domain/graph/builder/stages/build-structure.js +113 -0
- package/src/domain/graph/builder/stages/collect-files.js +44 -0
- package/src/domain/graph/builder/stages/detect-changes.js +413 -0
- package/src/domain/graph/builder/stages/finalize.js +139 -0
- package/src/domain/graph/builder/stages/insert-nodes.js +195 -0
- package/src/domain/graph/builder/stages/parse-files.js +28 -0
- package/src/domain/graph/builder/stages/resolve-imports.js +143 -0
- package/src/domain/graph/builder/stages/run-analyses.js +44 -0
- package/src/domain/graph/builder.js +11 -0
- package/src/{change-journal.js → domain/graph/change-journal.js} +1 -1
- package/src/domain/graph/cycles.js +82 -0
- package/src/{journal.js → domain/graph/journal.js} +1 -1
- package/src/{resolve.js → domain/graph/resolve.js} +3 -3
- package/src/{watcher.js → domain/graph/watcher.js} +10 -150
- package/src/{parser.js → domain/parser.js} +5 -5
- package/src/domain/queries.js +48 -0
- package/src/domain/search/generator.js +163 -0
- package/src/domain/search/index.js +13 -0
- package/src/domain/search/models.js +218 -0
- package/src/domain/search/search/cli-formatter.js +151 -0
- package/src/domain/search/search/filters.js +46 -0
- package/src/domain/search/search/hybrid.js +121 -0
- package/src/domain/search/search/keyword.js +68 -0
- package/src/domain/search/search/prepare.js +66 -0
- package/src/domain/search/search/semantic.js +145 -0
- package/src/domain/search/stores/fts5.js +27 -0
- package/src/domain/search/stores/sqlite-blob.js +24 -0
- package/src/domain/search/strategies/source.js +14 -0
- package/src/domain/search/strategies/structured.js +43 -0
- package/src/domain/search/strategies/text-utils.js +43 -0
- package/src/extractors/csharp.js +10 -2
- package/src/extractors/go.js +3 -1
- package/src/extractors/helpers.js +71 -0
- package/src/extractors/java.js +9 -2
- package/src/extractors/javascript.js +39 -2
- package/src/extractors/php.js +3 -1
- package/src/extractors/python.js +14 -3
- package/src/extractors/rust.js +3 -1
- package/src/{ast.js → features/ast.js} +8 -8
- package/src/{audit.js → features/audit.js} +16 -44
- package/src/{batch.js → features/batch.js} +6 -5
- package/src/{boundaries.js → features/boundaries.js} +2 -2
- package/src/{branch-compare.js → features/branch-compare.js} +3 -3
- package/src/{cfg.js → features/cfg.js} +11 -12
- package/src/{check.js → features/check.js} +13 -30
- package/src/{cochange.js → features/cochange.js} +5 -5
- package/src/{communities.js → features/communities.js} +18 -90
- package/src/{complexity.js → features/complexity.js} +13 -13
- package/src/{dataflow.js → features/dataflow.js} +12 -13
- package/src/features/export.js +378 -0
- package/src/{flow.js → features/flow.js} +4 -4
- package/src/features/graph-enrichment.js +327 -0
- package/src/{manifesto.js → features/manifesto.js} +6 -6
- package/src/{owners.js → features/owners.js} +2 -2
- package/src/{sequence.js → features/sequence.js} +16 -52
- package/src/{snapshot.js → features/snapshot.js} +8 -7
- package/src/{structure.js → features/structure.js} +20 -45
- package/src/{triage.js → features/triage.js} +27 -79
- package/src/graph/algorithms/bfs.js +49 -0
- package/src/graph/algorithms/centrality.js +16 -0
- package/src/graph/algorithms/index.js +5 -0
- package/src/graph/algorithms/louvain.js +26 -0
- package/src/graph/algorithms/shortest-path.js +41 -0
- package/src/graph/algorithms/tarjan.js +49 -0
- package/src/graph/builders/dependency.js +110 -0
- package/src/graph/builders/index.js +3 -0
- package/src/graph/builders/structure.js +40 -0
- package/src/graph/builders/temporal.js +33 -0
- package/src/graph/classifiers/index.js +2 -0
- package/src/graph/classifiers/risk.js +85 -0
- package/src/graph/classifiers/roles.js +64 -0
- package/src/graph/index.js +13 -0
- package/src/graph/model.js +230 -0
- package/src/index.cjs +16 -0
- package/src/index.js +42 -219
- package/src/{native.js → infrastructure/native.js} +3 -1
- package/src/infrastructure/result-formatter.js +2 -21
- package/src/mcp/index.js +2 -0
- package/src/mcp/middleware.js +26 -0
- package/src/mcp/server.js +128 -0
- package/src/{mcp.js → mcp/tool-registry.js} +6 -675
- package/src/mcp/tools/ast-query.js +14 -0
- package/src/mcp/tools/audit.js +21 -0
- package/src/mcp/tools/batch-query.js +11 -0
- package/src/mcp/tools/branch-compare.js +12 -0
- package/src/mcp/tools/cfg.js +21 -0
- package/src/mcp/tools/check.js +43 -0
- package/src/mcp/tools/co-changes.js +20 -0
- package/src/mcp/tools/code-owners.js +12 -0
- package/src/mcp/tools/communities.js +15 -0
- package/src/mcp/tools/complexity.js +18 -0
- package/src/mcp/tools/context.js +17 -0
- package/src/mcp/tools/dataflow.js +26 -0
- package/src/mcp/tools/diff-impact.js +24 -0
- package/src/mcp/tools/execution-flow.js +26 -0
- package/src/mcp/tools/export-graph.js +57 -0
- package/src/mcp/tools/file-deps.js +12 -0
- package/src/mcp/tools/file-exports.js +13 -0
- package/src/mcp/tools/find-cycles.js +15 -0
- package/src/mcp/tools/fn-impact.js +15 -0
- package/src/mcp/tools/impact-analysis.js +12 -0
- package/src/mcp/tools/index.js +71 -0
- package/src/mcp/tools/list-functions.js +14 -0
- package/src/mcp/tools/list-repos.js +11 -0
- package/src/mcp/tools/module-map.js +6 -0
- package/src/mcp/tools/node-roles.js +14 -0
- package/src/mcp/tools/path.js +12 -0
- package/src/mcp/tools/query.js +30 -0
- package/src/mcp/tools/semantic-search.js +65 -0
- package/src/mcp/tools/sequence.js +17 -0
- package/src/mcp/tools/structure.js +15 -0
- package/src/mcp/tools/symbol-children.js +14 -0
- package/src/mcp/tools/triage.js +35 -0
- package/src/mcp/tools/where.js +13 -0
- package/src/{commands → presentation}/audit.js +2 -2
- package/src/{commands → presentation}/batch.js +1 -1
- package/src/{commands → presentation}/branch-compare.js +2 -2
- package/src/{commands → presentation}/cfg.js +1 -1
- package/src/{commands → presentation}/check.js +6 -6
- package/src/presentation/colors.js +44 -0
- package/src/{commands → presentation}/communities.js +1 -1
- package/src/{commands → presentation}/complexity.js +1 -1
- package/src/{commands → presentation}/dataflow.js +1 -1
- package/src/presentation/export.js +444 -0
- package/src/{commands → presentation}/flow.js +2 -2
- package/src/{commands → presentation}/manifesto.js +4 -4
- package/src/{commands → presentation}/owners.js +1 -1
- package/src/presentation/queries-cli/exports.js +46 -0
- package/src/presentation/queries-cli/impact.js +198 -0
- package/src/presentation/queries-cli/index.js +5 -0
- package/src/presentation/queries-cli/inspect.js +334 -0
- package/src/presentation/queries-cli/overview.js +197 -0
- package/src/presentation/queries-cli/path.js +58 -0
- package/src/presentation/queries-cli.js +27 -0
- package/src/{commands → presentation}/query.js +1 -1
- package/src/presentation/result-formatter.js +144 -0
- package/src/presentation/sequence-renderer.js +43 -0
- package/src/{commands → presentation}/sequence.js +2 -2
- package/src/{commands → presentation}/structure.js +2 -2
- package/src/presentation/table.js +47 -0
- package/src/{commands → presentation}/triage.js +1 -1
- package/src/{viewer.js → presentation/viewer.js} +68 -382
- package/src/{constants.js → shared/constants.js} +1 -1
- package/src/shared/errors.js +78 -0
- package/src/shared/file-utils.js +153 -0
- package/src/shared/generators.js +125 -0
- package/src/shared/hierarchy.js +27 -0
- package/src/shared/normalize.js +59 -0
- package/src/builder.js +0 -1486
- package/src/cycles.js +0 -137
- package/src/embedder.js +0 -1097
- package/src/export.js +0 -681
- package/src/queries-cli.js +0 -866
- package/src/queries.js +0 -2289
- /package/src/{config.js → infrastructure/config.js} +0 -0
- /package/src/{logger.js → infrastructure/logger.js} +0 -0
- /package/src/{registry.js → infrastructure/registry.js} +0 -0
- /package/src/{update-check.js → infrastructure/update-check.js} +0 -0
- /package/src/{commands → presentation}/cochange.js +0 -0
- /package/src/{kinds.js → shared/kinds.js} +0 -0
- /package/src/{paginate.js → shared/paginate.js} +0 -0
package/src/cli/index.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
import { setVerbose } from '../infrastructure/logger.js';
|
|
6
|
+
import { checkForUpdates, printUpdateNotification } from '../infrastructure/update-check.js';
|
|
7
|
+
import { ConfigError } from '../shared/errors.js';
|
|
8
|
+
import {
|
|
9
|
+
applyQueryOpts,
|
|
10
|
+
config,
|
|
11
|
+
formatSize,
|
|
12
|
+
resolveNoTests,
|
|
13
|
+
resolveQueryOpts,
|
|
14
|
+
} from './shared/options.js';
|
|
15
|
+
import { outputResult } from './shared/output.js';
|
|
16
|
+
|
|
17
|
+
const __cliDir = path.dirname(new URL(import.meta.url).pathname.replace(/^\/([A-Z]:)/i, '$1'));
|
|
18
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(__cliDir, '..', '..', 'package.json'), 'utf-8'));
|
|
19
|
+
|
|
20
|
+
const program = new Command();
|
|
21
|
+
program
|
|
22
|
+
.name('codegraph')
|
|
23
|
+
.description('Local code dependency graph tool')
|
|
24
|
+
.version(pkg.version)
|
|
25
|
+
.option('-v, --verbose', 'Enable verbose/debug output')
|
|
26
|
+
.option('--engine <engine>', 'Parser engine: native, wasm, or auto (default: auto)', 'auto')
|
|
27
|
+
.hook('preAction', (thisCommand) => {
|
|
28
|
+
const opts = thisCommand.opts();
|
|
29
|
+
if (opts.verbose) setVerbose(true);
|
|
30
|
+
})
|
|
31
|
+
.hook('postAction', async (_thisCommand, actionCommand) => {
|
|
32
|
+
const name = actionCommand.name();
|
|
33
|
+
if (name === 'mcp' || name === 'watch') return;
|
|
34
|
+
if (actionCommand.opts().json) return;
|
|
35
|
+
try {
|
|
36
|
+
const result = await checkForUpdates(pkg.version);
|
|
37
|
+
if (result) printUpdateNotification(result.current, result.latest);
|
|
38
|
+
} catch {
|
|
39
|
+
/* never break CLI */
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
/** Shared context passed to every command's execute(). */
|
|
44
|
+
const ctx = { config, resolveNoTests, resolveQueryOpts, formatSize, outputResult, program };
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Register a command definition onto a Commander parent.
|
|
48
|
+
*
|
|
49
|
+
* Command shape:
|
|
50
|
+
* { name, description, queryOpts?, options?, validate?, execute(args, opts, ctx), subcommands? }
|
|
51
|
+
*
|
|
52
|
+
* - `name` includes positional args, e.g. 'build [dir]' or 'path <from> <to>'
|
|
53
|
+
* - `queryOpts` (boolean) — if true, attaches shared query options
|
|
54
|
+
* - `options` — array of arrays passed to cmd.option(), e.g. [['--depth <n>', 'Max depth', '3']]
|
|
55
|
+
* - `validate(args, opts, ctx)` — return an error string to abort, or falsy to proceed
|
|
56
|
+
* - `execute(args, opts, ctx)` — the action handler
|
|
57
|
+
* - `subcommands` — nested command definitions (for groups like registry, snapshot)
|
|
58
|
+
*/
|
|
59
|
+
function registerCommand(parent, def) {
|
|
60
|
+
const cmd = parent.command(def.name).description(def.description);
|
|
61
|
+
|
|
62
|
+
if (def.queryOpts) applyQueryOpts(cmd);
|
|
63
|
+
|
|
64
|
+
for (const opt of def.options || []) {
|
|
65
|
+
cmd.option(...opt);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (def.execute) {
|
|
69
|
+
const argCount = (def.name.match(/<[^>]+>|\[[^\]]+\]/g) || []).length;
|
|
70
|
+
|
|
71
|
+
cmd.action((...actionArgs) => {
|
|
72
|
+
const args = actionArgs.slice(0, argCount);
|
|
73
|
+
const opts = actionArgs[argCount];
|
|
74
|
+
|
|
75
|
+
if (def.validate) {
|
|
76
|
+
const err = def.validate(args, opts, ctx);
|
|
77
|
+
if (err) {
|
|
78
|
+
throw new ConfigError(err);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return def.execute(args, opts, ctx);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (def.subcommands) {
|
|
87
|
+
for (const sub of def.subcommands) {
|
|
88
|
+
registerCommand(cmd, sub);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return cmd;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Auto-discover and register all command modules from src/cli/commands/.
|
|
97
|
+
* Each module must export a `command` (single definition) or `commands` (array).
|
|
98
|
+
*/
|
|
99
|
+
async function discoverCommands() {
|
|
100
|
+
const commandsDir = path.join(__cliDir, 'commands');
|
|
101
|
+
const files = fs
|
|
102
|
+
.readdirSync(commandsDir)
|
|
103
|
+
.filter((f) => f.endsWith('.js'))
|
|
104
|
+
.sort();
|
|
105
|
+
|
|
106
|
+
for (const file of files) {
|
|
107
|
+
const mod = await import(pathToFileURL(path.join(commandsDir, file)).href);
|
|
108
|
+
if (mod.command) {
|
|
109
|
+
registerCommand(program, mod.command);
|
|
110
|
+
}
|
|
111
|
+
if (mod.commands) {
|
|
112
|
+
for (const def of mod.commands) {
|
|
113
|
+
registerCommand(program, def);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export async function run() {
|
|
120
|
+
await discoverCommands();
|
|
121
|
+
await program.parseAsync();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export { ctx, program, registerCommand };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { openReadonlyOrFail } from '../../db/index.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Open the graph database in readonly mode with a clean close() handle.
|
|
5
|
+
*
|
|
6
|
+
* @param {object} [opts]
|
|
7
|
+
* @param {string} [opts.db] - Custom path to graph.db
|
|
8
|
+
* @returns {{ db: import('better-sqlite3').Database, close: () => void }}
|
|
9
|
+
*/
|
|
10
|
+
export function openGraph(opts = {}) {
|
|
11
|
+
const db = openReadonlyOrFail(opts.db);
|
|
12
|
+
return { db, close: () => db.close() };
|
|
13
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { loadConfig } from '../../infrastructure/config.js';
|
|
2
|
+
|
|
3
|
+
const config = loadConfig(process.cwd());
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Attach the common query options shared by most analysis commands.
|
|
7
|
+
* @param {import('commander').Command} cmd
|
|
8
|
+
* @returns {import('commander').Command}
|
|
9
|
+
*/
|
|
10
|
+
export function applyQueryOpts(cmd) {
|
|
11
|
+
return cmd
|
|
12
|
+
.option('-d, --db <path>', 'Path to graph.db')
|
|
13
|
+
.option('-T, --no-tests', 'Exclude test/spec files from results')
|
|
14
|
+
.option('--include-tests', 'Include test/spec files (overrides excludeTests config)')
|
|
15
|
+
.option('-j, --json', 'Output as JSON')
|
|
16
|
+
.option('--limit <number>', 'Max results to return')
|
|
17
|
+
.option('--offset <number>', 'Skip N results (default: 0)')
|
|
18
|
+
.option('--ndjson', 'Newline-delimited JSON output')
|
|
19
|
+
.option('--table', 'Output as aligned table')
|
|
20
|
+
.option('--csv', 'Output as CSV');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Resolve the effective noTests value: CLI flag > config > false.
|
|
25
|
+
* Commander sets opts.tests to false when --no-tests is passed.
|
|
26
|
+
* When --include-tests is passed, always return false (include tests).
|
|
27
|
+
* Otherwise, fall back to config.query.excludeTests.
|
|
28
|
+
*/
|
|
29
|
+
export function resolveNoTests(opts) {
|
|
30
|
+
if (opts.includeTests) return false;
|
|
31
|
+
if (opts.tests === false) return true;
|
|
32
|
+
return config.query?.excludeTests || false;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Extract the common query option fields shared by most analysis commands.
|
|
37
|
+
*
|
|
38
|
+
* Spreads cleanly into per-command option objects:
|
|
39
|
+
* `{ ...resolveQueryOpts(opts), depth: parseInt(opts.depth, 10) }`
|
|
40
|
+
*/
|
|
41
|
+
export function resolveQueryOpts(opts) {
|
|
42
|
+
return {
|
|
43
|
+
noTests: resolveNoTests(opts),
|
|
44
|
+
json: opts.json,
|
|
45
|
+
ndjson: opts.ndjson,
|
|
46
|
+
table: opts.table,
|
|
47
|
+
csv: opts.csv,
|
|
48
|
+
limit: opts.limit ? parseInt(opts.limit, 10) : undefined,
|
|
49
|
+
offset: opts.offset ? parseInt(opts.offset, 10) : undefined,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function formatSize(bytes) {
|
|
54
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
55
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
56
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export { config };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { outputResult } from '../../infrastructure/result-formatter.js';
|