@openez-graph/cli 0.3.0 → 0.3.2
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 +21 -0
- package/README.md +94 -14
- package/dist/cli.cjs +206 -118
- package/package.json +33 -2
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Asta Nguyen
|
|
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
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
# @openez-graph/cli
|
|
2
2
|
|
|
3
|
-
Local-first code intelligence
|
|
3
|
+
> Local-first code intelligence engine — index, query, and graph your codebase with zero config.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@openez-graph/cli)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
OpenEZ Graph indexes your codebase into a local SQLite database, builds a code graph (symbols, files, chunks, edges), and exposes it through MCP tools for AI coding agents like Claude Code, Codex, and OpenCode.
|
|
9
|
+
|
|
10
|
+
**Zero config. No Docker. No Postgres. No Redis. Just install and go.**
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- **Zero-config** — auto-registers workspace, auto-indexes, auto-syncs on file changes
|
|
15
|
+
- **SQLite-first** — all data stored locally in `.openez/` per workspace
|
|
16
|
+
- **MCP-first** — exposes `memory_query`, `code_context`, `graph_neighbors`, `memory_write`, `index_workspace`, `list_workspaces` tools
|
|
17
|
+
- **Multi-workspace** — register and query across multiple codebases
|
|
18
|
+
- **Code graph** — symbols, files, chunks, and edges (calls, imports, contains)
|
|
19
|
+
- **Web dashboard** — built-in graph explorer and workspace management UI
|
|
20
|
+
- **Auto-sync** — file watcher re-indexes on changes (2s debounce)
|
|
4
21
|
|
|
5
22
|
## Install
|
|
6
23
|
|
|
@@ -9,24 +26,87 @@ npm install -g @openez-graph/cli
|
|
|
9
26
|
openez setup claude # or: codex, opencode
|
|
10
27
|
```
|
|
11
28
|
|
|
29
|
+
Restart your agent. Done.
|
|
30
|
+
|
|
31
|
+
## Quick start
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# 1. Install
|
|
35
|
+
npm install -g @openez-graph/cli
|
|
36
|
+
|
|
37
|
+
# 2. Wire up your agent
|
|
38
|
+
openez setup claude # Claude Code
|
|
39
|
+
openez setup codex # Codex
|
|
40
|
+
openez setup opencode # OpenCode
|
|
41
|
+
|
|
42
|
+
# 3. Restart your agent — it will auto-index and auto-sync
|
|
43
|
+
```
|
|
44
|
+
|
|
12
45
|
## Commands
|
|
13
46
|
|
|
14
47
|
```bash
|
|
15
|
-
openez init [path]
|
|
16
|
-
openez index [path]
|
|
17
|
-
openez reindex [path]
|
|
18
|
-
openez watch [path]
|
|
19
|
-
openez serve --mcp
|
|
20
|
-
openez serve --web
|
|
21
|
-
openez serve --web --port 8080
|
|
22
|
-
openez status [path]
|
|
23
|
-
openez list
|
|
24
|
-
openez setup claude
|
|
25
|
-
openez setup codex
|
|
26
|
-
openez setup opencode
|
|
48
|
+
openez init [path] # register + index a workspace
|
|
49
|
+
openez index [path] # incremental index
|
|
50
|
+
openez reindex [path] # full rebuild
|
|
51
|
+
openez watch [path] # watch + auto-reindex on changes
|
|
52
|
+
openez serve --mcp # start MCP server (auto-index + auto-sync)
|
|
53
|
+
openez serve --web # start web dashboard (default port 17881)
|
|
54
|
+
openez serve --web --port 8080 # start web dashboard on custom port
|
|
55
|
+
openez status [path] # show workspace status
|
|
56
|
+
openez list # list registered workspaces
|
|
57
|
+
openez setup claude # wire up Claude Code
|
|
58
|
+
openez setup codex # wire up Codex
|
|
59
|
+
openez setup opencode # wire up OpenCode
|
|
27
60
|
```
|
|
28
61
|
|
|
62
|
+
## MCP Tools
|
|
63
|
+
|
|
64
|
+
| Tool | Description |
|
|
65
|
+
|------|-------------|
|
|
66
|
+
| `list_workspaces` | List all registered workspaces |
|
|
67
|
+
| `memory_query` | Full-text search + graph expansion for retrieval context |
|
|
68
|
+
| `code_context` | Get symbol context with callers, callees, and related files |
|
|
69
|
+
| `graph_neighbors` | Traverse graph edges from a node or label |
|
|
70
|
+
| `memory_write` | Write a memory entry (notes, decisions, patterns) |
|
|
71
|
+
| `index_workspace` | Trigger indexing for a workspace |
|
|
72
|
+
|
|
73
|
+
## How it works
|
|
74
|
+
|
|
75
|
+
1. **`openez setup claude`** writes MCP server config to `~/.claude/settings.json`
|
|
76
|
+
2. When Claude Code starts, it launches the MCP server via `openez serve --mcp`
|
|
77
|
+
3. The MCP server auto-registers the current project as a workspace
|
|
78
|
+
4. It auto-indexes if the workspace has no documents yet
|
|
79
|
+
5. It watches for file changes and re-indexes automatically (2s debounce)
|
|
80
|
+
6. All data is stored in `<project>/.openez/index.sqlite` — local, portable, gitignored
|
|
81
|
+
|
|
82
|
+
## Supported languages
|
|
83
|
+
|
|
84
|
+
| Language | Indexing depth |
|
|
85
|
+
|----------|---------------|
|
|
86
|
+
| TypeScript / JavaScript | Richest — `ts-morph` symbol extraction, imports, calls |
|
|
87
|
+
| Python | Basic top-level symbol extraction |
|
|
88
|
+
| Go | Basic top-level symbol extraction |
|
|
89
|
+
| Rust | Basic top-level symbol extraction |
|
|
90
|
+
| YAML / JSON / TOML | Structure-aware chunking |
|
|
91
|
+
| Markdown | Section-oriented chunking |
|
|
92
|
+
|
|
93
|
+
## Web dashboard
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
openez serve --web
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Opens a full web dashboard at `http://localhost:17881` with:
|
|
100
|
+
- Workspace overview (documents, chunks, nodes, edges)
|
|
101
|
+
- Graph explorer with force-directed layout
|
|
102
|
+
- Query interface for memory retrieval
|
|
103
|
+
- Indexing control and run history
|
|
104
|
+
|
|
29
105
|
## Requirements
|
|
30
106
|
|
|
31
107
|
- Node.js 20+
|
|
32
|
-
- No
|
|
108
|
+
- No external services needed
|
|
109
|
+
|
|
110
|
+
## License
|
|
111
|
+
|
|
112
|
+
MIT © [Asta Nguyen](https://github.com/asta-nguyen)
|
package/dist/cli.cjs
CHANGED
|
@@ -2912,7 +2912,7 @@ var require_command = __commonJS({
|
|
|
2912
2912
|
var EventEmitter2 = require("events").EventEmitter;
|
|
2913
2913
|
var childProcess = require("child_process");
|
|
2914
2914
|
var path19 = require("path");
|
|
2915
|
-
var
|
|
2915
|
+
var fs17 = require("fs");
|
|
2916
2916
|
var process3 = require("process");
|
|
2917
2917
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
2918
2918
|
var { CommanderError: CommanderError2 } = require_error();
|
|
@@ -3906,7 +3906,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3906
3906
|
* @param {string} subcommandName
|
|
3907
3907
|
*/
|
|
3908
3908
|
_checkForMissingExecutable(executableFile, executableDir, subcommandName) {
|
|
3909
|
-
if (
|
|
3909
|
+
if (fs17.existsSync(executableFile)) return;
|
|
3910
3910
|
const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
|
|
3911
3911
|
const executableMissing = `'${executableFile}' does not exist
|
|
3912
3912
|
- if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
|
|
@@ -3925,10 +3925,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3925
3925
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
3926
3926
|
function findFile(baseDir, baseName) {
|
|
3927
3927
|
const localBin = path19.resolve(baseDir, baseName);
|
|
3928
|
-
if (
|
|
3928
|
+
if (fs17.existsSync(localBin)) return localBin;
|
|
3929
3929
|
if (sourceExt.includes(path19.extname(baseName))) return void 0;
|
|
3930
3930
|
const foundExt = sourceExt.find(
|
|
3931
|
-
(ext) =>
|
|
3931
|
+
(ext) => fs17.existsSync(`${localBin}${ext}`)
|
|
3932
3932
|
);
|
|
3933
3933
|
if (foundExt) return `${localBin}${foundExt}`;
|
|
3934
3934
|
return void 0;
|
|
@@ -3940,7 +3940,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3940
3940
|
if (this._scriptPath) {
|
|
3941
3941
|
let resolvedScriptPath;
|
|
3942
3942
|
try {
|
|
3943
|
-
resolvedScriptPath =
|
|
3943
|
+
resolvedScriptPath = fs17.realpathSync(this._scriptPath);
|
|
3944
3944
|
} catch {
|
|
3945
3945
|
resolvedScriptPath = this._scriptPath;
|
|
3946
3946
|
}
|
|
@@ -12514,7 +12514,7 @@ var require_package = __commonJS({
|
|
|
12514
12514
|
var require_main = __commonJS({
|
|
12515
12515
|
"../../node_modules/.pnpm/dotenv@16.6.1/node_modules/dotenv/lib/main.js"(exports2, module3) {
|
|
12516
12516
|
"use strict";
|
|
12517
|
-
var
|
|
12517
|
+
var fs17 = require("fs");
|
|
12518
12518
|
var path19 = require("path");
|
|
12519
12519
|
var os6 = require("os");
|
|
12520
12520
|
var crypto4 = require("crypto");
|
|
@@ -12623,7 +12623,7 @@ var require_main = __commonJS({
|
|
|
12623
12623
|
if (options && options.path && options.path.length > 0) {
|
|
12624
12624
|
if (Array.isArray(options.path)) {
|
|
12625
12625
|
for (const filepath of options.path) {
|
|
12626
|
-
if (
|
|
12626
|
+
if (fs17.existsSync(filepath)) {
|
|
12627
12627
|
possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
|
|
12628
12628
|
}
|
|
12629
12629
|
}
|
|
@@ -12633,7 +12633,7 @@ var require_main = __commonJS({
|
|
|
12633
12633
|
} else {
|
|
12634
12634
|
possibleVaultPath = path19.resolve(process.cwd(), ".env.vault");
|
|
12635
12635
|
}
|
|
12636
|
-
if (
|
|
12636
|
+
if (fs17.existsSync(possibleVaultPath)) {
|
|
12637
12637
|
return possibleVaultPath;
|
|
12638
12638
|
}
|
|
12639
12639
|
return null;
|
|
@@ -12682,7 +12682,7 @@ var require_main = __commonJS({
|
|
|
12682
12682
|
const parsedAll = {};
|
|
12683
12683
|
for (const path20 of optionPaths) {
|
|
12684
12684
|
try {
|
|
12685
|
-
const parsed = DotenvModule.parse(
|
|
12685
|
+
const parsed = DotenvModule.parse(fs17.readFileSync(path20, { encoding }));
|
|
12686
12686
|
DotenvModule.populate(parsedAll, parsed, options);
|
|
12687
12687
|
} catch (e) {
|
|
12688
12688
|
if (debug) {
|
|
@@ -29609,11 +29609,11 @@ var require_source_map_support = __commonJS({
|
|
|
29609
29609
|
"use strict";
|
|
29610
29610
|
var SourceMapConsumer = require_source_map().SourceMapConsumer;
|
|
29611
29611
|
var path19 = require("path");
|
|
29612
|
-
var
|
|
29612
|
+
var fs17;
|
|
29613
29613
|
try {
|
|
29614
|
-
|
|
29615
|
-
if (!
|
|
29616
|
-
|
|
29614
|
+
fs17 = require("fs");
|
|
29615
|
+
if (!fs17.existsSync || !fs17.readFileSync) {
|
|
29616
|
+
fs17 = null;
|
|
29617
29617
|
}
|
|
29618
29618
|
} catch (err) {
|
|
29619
29619
|
}
|
|
@@ -29684,7 +29684,7 @@ var require_source_map_support = __commonJS({
|
|
|
29684
29684
|
}
|
|
29685
29685
|
var contents = "";
|
|
29686
29686
|
try {
|
|
29687
|
-
if (!
|
|
29687
|
+
if (!fs17) {
|
|
29688
29688
|
var xhr = new XMLHttpRequest();
|
|
29689
29689
|
xhr.open(
|
|
29690
29690
|
"GET",
|
|
@@ -29696,8 +29696,8 @@ var require_source_map_support = __commonJS({
|
|
|
29696
29696
|
if (xhr.readyState === 4 && xhr.status === 200) {
|
|
29697
29697
|
contents = xhr.responseText;
|
|
29698
29698
|
}
|
|
29699
|
-
} else if (
|
|
29700
|
-
contents =
|
|
29699
|
+
} else if (fs17.existsSync(path20)) {
|
|
29700
|
+
contents = fs17.readFileSync(path20, "utf8");
|
|
29701
29701
|
}
|
|
29702
29702
|
} catch (er) {
|
|
29703
29703
|
}
|
|
@@ -29961,9 +29961,9 @@ var require_source_map_support = __commonJS({
|
|
|
29961
29961
|
var line = +match[2];
|
|
29962
29962
|
var column = +match[3];
|
|
29963
29963
|
var contents = fileContentsCache[source];
|
|
29964
|
-
if (!contents &&
|
|
29964
|
+
if (!contents && fs17 && fs17.existsSync(source)) {
|
|
29965
29965
|
try {
|
|
29966
|
-
contents =
|
|
29966
|
+
contents = fs17.readFileSync(source, "utf8");
|
|
29967
29967
|
} catch (er) {
|
|
29968
29968
|
contents = "";
|
|
29969
29969
|
}
|
|
@@ -33724,10 +33724,10 @@ var require_typescript = __commonJS({
|
|
|
33724
33724
|
function and2(f, g2) {
|
|
33725
33725
|
return (arg) => f(arg) && g2(arg);
|
|
33726
33726
|
}
|
|
33727
|
-
function or2(...
|
|
33727
|
+
function or2(...fs17) {
|
|
33728
33728
|
return (...args) => {
|
|
33729
33729
|
let lastResult;
|
|
33730
|
-
for (const f of
|
|
33730
|
+
for (const f of fs17) {
|
|
33731
33731
|
lastResult = f(...args);
|
|
33732
33732
|
if (lastResult) {
|
|
33733
33733
|
return lastResult;
|
|
@@ -35302,7 +35302,7 @@ ${lanes.join("\n")}
|
|
|
35302
35302
|
var tracing;
|
|
35303
35303
|
var tracingEnabled;
|
|
35304
35304
|
((tracingEnabled2) => {
|
|
35305
|
-
let
|
|
35305
|
+
let fs17;
|
|
35306
35306
|
let traceCount = 0;
|
|
35307
35307
|
let traceFd = 0;
|
|
35308
35308
|
let mode;
|
|
@@ -35311,9 +35311,9 @@ ${lanes.join("\n")}
|
|
|
35311
35311
|
const legend = [];
|
|
35312
35312
|
function startTracing2(tracingMode, traceDir, configFilePath) {
|
|
35313
35313
|
Debug.assert(!tracing, "Tracing already started");
|
|
35314
|
-
if (
|
|
35314
|
+
if (fs17 === void 0) {
|
|
35315
35315
|
try {
|
|
35316
|
-
|
|
35316
|
+
fs17 = require("fs");
|
|
35317
35317
|
} catch (e) {
|
|
35318
35318
|
throw new Error(`tracing requires having fs
|
|
35319
35319
|
(original error: ${e.message || e})`);
|
|
@@ -35324,8 +35324,8 @@ ${lanes.join("\n")}
|
|
|
35324
35324
|
if (legendPath === void 0) {
|
|
35325
35325
|
legendPath = combinePaths(traceDir, "legend.json");
|
|
35326
35326
|
}
|
|
35327
|
-
if (!
|
|
35328
|
-
|
|
35327
|
+
if (!fs17.existsSync(traceDir)) {
|
|
35328
|
+
fs17.mkdirSync(traceDir, { recursive: true });
|
|
35329
35329
|
}
|
|
35330
35330
|
const countPart = mode === "build" ? `.${process.pid}-${++traceCount}` : mode === "server" ? `.${process.pid}` : ``;
|
|
35331
35331
|
const tracePath = combinePaths(traceDir, `trace${countPart}.json`);
|
|
@@ -35335,10 +35335,10 @@ ${lanes.join("\n")}
|
|
|
35335
35335
|
tracePath,
|
|
35336
35336
|
typesPath
|
|
35337
35337
|
});
|
|
35338
|
-
traceFd =
|
|
35338
|
+
traceFd = fs17.openSync(tracePath, "w");
|
|
35339
35339
|
tracing = tracingEnabled2;
|
|
35340
35340
|
const meta = { cat: "__metadata", ph: "M", ts: 1e3 * timestamp(), pid: 1, tid: 1 };
|
|
35341
|
-
|
|
35341
|
+
fs17.writeSync(
|
|
35342
35342
|
traceFd,
|
|
35343
35343
|
"[\n" + [{ name: "process_name", args: { name: "tsc" }, ...meta }, { name: "thread_name", args: { name: "Main" }, ...meta }, { name: "TracingStartedInBrowser", ...meta, cat: "disabled-by-default-devtools.timeline" }].map((v) => JSON.stringify(v)).join(",\n")
|
|
35344
35344
|
);
|
|
@@ -35347,10 +35347,10 @@ ${lanes.join("\n")}
|
|
|
35347
35347
|
function stopTracing() {
|
|
35348
35348
|
Debug.assert(tracing, "Tracing is not in progress");
|
|
35349
35349
|
Debug.assert(!!typeCatalog.length === (mode !== "server"));
|
|
35350
|
-
|
|
35350
|
+
fs17.writeSync(traceFd, `
|
|
35351
35351
|
]
|
|
35352
35352
|
`);
|
|
35353
|
-
|
|
35353
|
+
fs17.closeSync(traceFd);
|
|
35354
35354
|
tracing = void 0;
|
|
35355
35355
|
if (typeCatalog.length) {
|
|
35356
35356
|
dumpTypes(typeCatalog);
|
|
@@ -35422,11 +35422,11 @@ ${lanes.join("\n")}
|
|
|
35422
35422
|
function writeEvent(eventType, phase, name, args, extras, time3 = 1e3 * timestamp()) {
|
|
35423
35423
|
if (mode === "server" && phase === "checkTypes") return;
|
|
35424
35424
|
mark("beginTracing");
|
|
35425
|
-
|
|
35425
|
+
fs17.writeSync(traceFd, `,
|
|
35426
35426
|
{"pid":1,"tid":1,"ph":"${eventType}","cat":"${phase}","ts":${time3},"name":"${name}"`);
|
|
35427
|
-
if (extras)
|
|
35428
|
-
if (args)
|
|
35429
|
-
|
|
35427
|
+
if (extras) fs17.writeSync(traceFd, `,${extras}`);
|
|
35428
|
+
if (args) fs17.writeSync(traceFd, `,"args":${JSON.stringify(args)}`);
|
|
35429
|
+
fs17.writeSync(traceFd, `}`);
|
|
35430
35430
|
mark("endTracing");
|
|
35431
35431
|
measure("Tracing", "beginTracing", "endTracing");
|
|
35432
35432
|
}
|
|
@@ -35448,9 +35448,9 @@ ${lanes.join("\n")}
|
|
|
35448
35448
|
var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
|
|
35449
35449
|
mark("beginDumpTypes");
|
|
35450
35450
|
const typesPath = legend[legend.length - 1].typesPath;
|
|
35451
|
-
const typesFd =
|
|
35451
|
+
const typesFd = fs17.openSync(typesPath, "w");
|
|
35452
35452
|
const recursionIdentityMap = /* @__PURE__ */ new Map();
|
|
35453
|
-
|
|
35453
|
+
fs17.writeSync(typesFd, "[");
|
|
35454
35454
|
const numTypes = types.length;
|
|
35455
35455
|
for (let i = 0; i < numTypes; i++) {
|
|
35456
35456
|
const type = types[i];
|
|
@@ -35546,13 +35546,13 @@ ${lanes.join("\n")}
|
|
|
35546
35546
|
flags: Debug.formatTypeFlags(type.flags).split("|"),
|
|
35547
35547
|
display
|
|
35548
35548
|
};
|
|
35549
|
-
|
|
35549
|
+
fs17.writeSync(typesFd, JSON.stringify(descriptor));
|
|
35550
35550
|
if (i < numTypes - 1) {
|
|
35551
|
-
|
|
35551
|
+
fs17.writeSync(typesFd, ",\n");
|
|
35552
35552
|
}
|
|
35553
35553
|
}
|
|
35554
|
-
|
|
35555
|
-
|
|
35554
|
+
fs17.writeSync(typesFd, "]\n");
|
|
35555
|
+
fs17.closeSync(typesFd);
|
|
35556
35556
|
mark("endDumpTypes");
|
|
35557
35557
|
measure("Dump types", "beginDumpTypes", "endDumpTypes");
|
|
35558
35558
|
}
|
|
@@ -35560,7 +35560,7 @@ ${lanes.join("\n")}
|
|
|
35560
35560
|
if (!legendPath) {
|
|
35561
35561
|
return;
|
|
35562
35562
|
}
|
|
35563
|
-
|
|
35563
|
+
fs17.writeFileSync(legendPath, JSON.stringify(legend));
|
|
35564
35564
|
}
|
|
35565
35565
|
tracingEnabled2.dumpLegend = dumpLegend;
|
|
35566
35566
|
})(tracingEnabled || (tracingEnabled = {}));
|
|
@@ -244613,8 +244613,8 @@ var require_utils3 = __commonJS({
|
|
|
244613
244613
|
exports2.array = array2;
|
|
244614
244614
|
var errno = require_errno();
|
|
244615
244615
|
exports2.errno = errno;
|
|
244616
|
-
var
|
|
244617
|
-
exports2.fs =
|
|
244616
|
+
var fs17 = require_fs();
|
|
244617
|
+
exports2.fs = fs17;
|
|
244618
244618
|
var path19 = require_path();
|
|
244619
244619
|
exports2.path = path19;
|
|
244620
244620
|
var pattern = require_pattern();
|
|
@@ -244798,12 +244798,12 @@ var require_fs2 = __commonJS({
|
|
|
244798
244798
|
"use strict";
|
|
244799
244799
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
244800
244800
|
exports2.createFileSystemAdapter = exports2.FILE_SYSTEM_ADAPTER = void 0;
|
|
244801
|
-
var
|
|
244801
|
+
var fs17 = require("fs");
|
|
244802
244802
|
exports2.FILE_SYSTEM_ADAPTER = {
|
|
244803
|
-
lstat:
|
|
244804
|
-
stat:
|
|
244805
|
-
lstatSync:
|
|
244806
|
-
statSync:
|
|
244803
|
+
lstat: fs17.lstat,
|
|
244804
|
+
stat: fs17.stat,
|
|
244805
|
+
lstatSync: fs17.lstatSync,
|
|
244806
|
+
statSync: fs17.statSync
|
|
244807
244807
|
};
|
|
244808
244808
|
function createFileSystemAdapter(fsMethods) {
|
|
244809
244809
|
if (fsMethods === void 0) {
|
|
@@ -244820,12 +244820,12 @@ var require_settings = __commonJS({
|
|
|
244820
244820
|
"../../node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/settings.js"(exports2) {
|
|
244821
244821
|
"use strict";
|
|
244822
244822
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
244823
|
-
var
|
|
244823
|
+
var fs17 = require_fs2();
|
|
244824
244824
|
var Settings = class {
|
|
244825
244825
|
constructor(_options = {}) {
|
|
244826
244826
|
this._options = _options;
|
|
244827
244827
|
this.followSymbolicLink = this._getValue(this._options.followSymbolicLink, true);
|
|
244828
|
-
this.fs =
|
|
244828
|
+
this.fs = fs17.createFileSystemAdapter(this._options.fs);
|
|
244829
244829
|
this.markSymbolicLink = this._getValue(this._options.markSymbolicLink, false);
|
|
244830
244830
|
this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true);
|
|
244831
244831
|
}
|
|
@@ -244982,8 +244982,8 @@ var require_utils4 = __commonJS({
|
|
|
244982
244982
|
"use strict";
|
|
244983
244983
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
244984
244984
|
exports2.fs = void 0;
|
|
244985
|
-
var
|
|
244986
|
-
exports2.fs =
|
|
244985
|
+
var fs17 = require_fs3();
|
|
244986
|
+
exports2.fs = fs17;
|
|
244987
244987
|
}
|
|
244988
244988
|
});
|
|
244989
244989
|
|
|
@@ -245178,14 +245178,14 @@ var require_fs4 = __commonJS({
|
|
|
245178
245178
|
"use strict";
|
|
245179
245179
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
245180
245180
|
exports2.createFileSystemAdapter = exports2.FILE_SYSTEM_ADAPTER = void 0;
|
|
245181
|
-
var
|
|
245181
|
+
var fs17 = require("fs");
|
|
245182
245182
|
exports2.FILE_SYSTEM_ADAPTER = {
|
|
245183
|
-
lstat:
|
|
245184
|
-
stat:
|
|
245185
|
-
lstatSync:
|
|
245186
|
-
statSync:
|
|
245187
|
-
readdir:
|
|
245188
|
-
readdirSync:
|
|
245183
|
+
lstat: fs17.lstat,
|
|
245184
|
+
stat: fs17.stat,
|
|
245185
|
+
lstatSync: fs17.lstatSync,
|
|
245186
|
+
statSync: fs17.statSync,
|
|
245187
|
+
readdir: fs17.readdir,
|
|
245188
|
+
readdirSync: fs17.readdirSync
|
|
245189
245189
|
};
|
|
245190
245190
|
function createFileSystemAdapter(fsMethods) {
|
|
245191
245191
|
if (fsMethods === void 0) {
|
|
@@ -245204,12 +245204,12 @@ var require_settings2 = __commonJS({
|
|
|
245204
245204
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
245205
245205
|
var path19 = require("path");
|
|
245206
245206
|
var fsStat = require_out();
|
|
245207
|
-
var
|
|
245207
|
+
var fs17 = require_fs4();
|
|
245208
245208
|
var Settings = class {
|
|
245209
245209
|
constructor(_options = {}) {
|
|
245210
245210
|
this._options = _options;
|
|
245211
245211
|
this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, false);
|
|
245212
|
-
this.fs =
|
|
245212
|
+
this.fs = fs17.createFileSystemAdapter(this._options.fs);
|
|
245213
245213
|
this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path19.sep);
|
|
245214
245214
|
this.stats = this._getValue(this._options.stats, false);
|
|
245215
245215
|
this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true);
|
|
@@ -246590,16 +246590,16 @@ var require_settings4 = __commonJS({
|
|
|
246590
246590
|
"use strict";
|
|
246591
246591
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
246592
246592
|
exports2.DEFAULT_FILE_SYSTEM_ADAPTER = void 0;
|
|
246593
|
-
var
|
|
246593
|
+
var fs17 = require("fs");
|
|
246594
246594
|
var os6 = require("os");
|
|
246595
246595
|
var CPU_COUNT = Math.max(os6.cpus().length, 1);
|
|
246596
246596
|
exports2.DEFAULT_FILE_SYSTEM_ADAPTER = {
|
|
246597
|
-
lstat:
|
|
246598
|
-
lstatSync:
|
|
246599
|
-
stat:
|
|
246600
|
-
statSync:
|
|
246601
|
-
readdir:
|
|
246602
|
-
readdirSync:
|
|
246597
|
+
lstat: fs17.lstat,
|
|
246598
|
+
lstatSync: fs17.lstatSync,
|
|
246599
|
+
stat: fs17.stat,
|
|
246600
|
+
statSync: fs17.statSync,
|
|
246601
|
+
readdir: fs17.readdir,
|
|
246602
|
+
readdirSync: fs17.readdirSync
|
|
246603
246603
|
};
|
|
246604
246604
|
var Settings = class {
|
|
246605
246605
|
constructor(_options = {}) {
|
|
@@ -279303,30 +279303,30 @@ type XMLHttpRequestResponseType = "" | "arraybuffer" | "blob" | "document" | "js
|
|
|
279303
279303
|
yield path20;
|
|
279304
279304
|
}
|
|
279305
279305
|
}
|
|
279306
|
-
var
|
|
279306
|
+
var fs17 = runtime.fs;
|
|
279307
279307
|
var RealFileSystemHost = class {
|
|
279308
279308
|
async delete(path20) {
|
|
279309
279309
|
try {
|
|
279310
|
-
await
|
|
279310
|
+
await fs17.delete(path20);
|
|
279311
279311
|
} catch (err) {
|
|
279312
279312
|
throw this.#getFileNotFoundErrorIfNecessary(err, path20);
|
|
279313
279313
|
}
|
|
279314
279314
|
}
|
|
279315
279315
|
deleteSync(path20) {
|
|
279316
279316
|
try {
|
|
279317
|
-
|
|
279317
|
+
fs17.deleteSync(path20);
|
|
279318
279318
|
} catch (err) {
|
|
279319
279319
|
throw this.#getFileNotFoundErrorIfNecessary(err, path20);
|
|
279320
279320
|
}
|
|
279321
279321
|
}
|
|
279322
279322
|
readDirSync(dirPath) {
|
|
279323
279323
|
try {
|
|
279324
|
-
const entries =
|
|
279324
|
+
const entries = fs17.readDirSync(dirPath);
|
|
279325
279325
|
for (const entry of entries) {
|
|
279326
279326
|
entry.name = FileUtils.pathJoin(dirPath, entry.name);
|
|
279327
279327
|
if (entry.isSymlink) {
|
|
279328
279328
|
try {
|
|
279329
|
-
const info =
|
|
279329
|
+
const info = fs17.statSync(entry.name);
|
|
279330
279330
|
if (info != null) {
|
|
279331
279331
|
entry.isDirectory = info.isDirectory();
|
|
279332
279332
|
entry.isFile = info.isFile();
|
|
@@ -279342,84 +279342,84 @@ type XMLHttpRequestResponseType = "" | "arraybuffer" | "blob" | "document" | "js
|
|
|
279342
279342
|
}
|
|
279343
279343
|
async readFile(filePath, encoding = "utf-8") {
|
|
279344
279344
|
try {
|
|
279345
|
-
return await
|
|
279345
|
+
return await fs17.readFile(filePath, encoding);
|
|
279346
279346
|
} catch (err) {
|
|
279347
279347
|
throw this.#getFileNotFoundErrorIfNecessary(err, filePath);
|
|
279348
279348
|
}
|
|
279349
279349
|
}
|
|
279350
279350
|
readFileSync(filePath, encoding = "utf-8") {
|
|
279351
279351
|
try {
|
|
279352
|
-
return
|
|
279352
|
+
return fs17.readFileSync(filePath, encoding);
|
|
279353
279353
|
} catch (err) {
|
|
279354
279354
|
throw this.#getFileNotFoundErrorIfNecessary(err, filePath);
|
|
279355
279355
|
}
|
|
279356
279356
|
}
|
|
279357
279357
|
async writeFile(filePath, fileText) {
|
|
279358
|
-
return
|
|
279358
|
+
return fs17.writeFile(filePath, fileText);
|
|
279359
279359
|
}
|
|
279360
279360
|
writeFileSync(filePath, fileText) {
|
|
279361
|
-
|
|
279361
|
+
fs17.writeFileSync(filePath, fileText);
|
|
279362
279362
|
}
|
|
279363
279363
|
mkdir(dirPath) {
|
|
279364
|
-
return
|
|
279364
|
+
return fs17.mkdir(dirPath);
|
|
279365
279365
|
}
|
|
279366
279366
|
mkdirSync(dirPath) {
|
|
279367
|
-
|
|
279367
|
+
fs17.mkdirSync(dirPath);
|
|
279368
279368
|
}
|
|
279369
279369
|
move(srcPath, destPath) {
|
|
279370
|
-
return
|
|
279370
|
+
return fs17.move(srcPath, destPath);
|
|
279371
279371
|
}
|
|
279372
279372
|
moveSync(srcPath, destPath) {
|
|
279373
|
-
|
|
279373
|
+
fs17.moveSync(srcPath, destPath);
|
|
279374
279374
|
}
|
|
279375
279375
|
copy(srcPath, destPath) {
|
|
279376
|
-
return
|
|
279376
|
+
return fs17.copy(srcPath, destPath);
|
|
279377
279377
|
}
|
|
279378
279378
|
copySync(srcPath, destPath) {
|
|
279379
|
-
|
|
279379
|
+
fs17.copySync(srcPath, destPath);
|
|
279380
279380
|
}
|
|
279381
279381
|
async fileExists(filePath) {
|
|
279382
279382
|
try {
|
|
279383
|
-
return (await
|
|
279383
|
+
return (await fs17.stat(filePath))?.isFile() ?? false;
|
|
279384
279384
|
} catch {
|
|
279385
279385
|
return false;
|
|
279386
279386
|
}
|
|
279387
279387
|
}
|
|
279388
279388
|
fileExistsSync(filePath) {
|
|
279389
279389
|
try {
|
|
279390
|
-
return
|
|
279390
|
+
return fs17.statSync(filePath)?.isFile() ?? false;
|
|
279391
279391
|
} catch {
|
|
279392
279392
|
return false;
|
|
279393
279393
|
}
|
|
279394
279394
|
}
|
|
279395
279395
|
async directoryExists(dirPath) {
|
|
279396
279396
|
try {
|
|
279397
|
-
return (await
|
|
279397
|
+
return (await fs17.stat(dirPath))?.isDirectory() ?? false;
|
|
279398
279398
|
} catch {
|
|
279399
279399
|
return false;
|
|
279400
279400
|
}
|
|
279401
279401
|
}
|
|
279402
279402
|
directoryExistsSync(dirPath) {
|
|
279403
279403
|
try {
|
|
279404
|
-
return
|
|
279404
|
+
return fs17.statSync(dirPath)?.isDirectory() ?? false;
|
|
279405
279405
|
} catch {
|
|
279406
279406
|
return false;
|
|
279407
279407
|
}
|
|
279408
279408
|
}
|
|
279409
279409
|
realpathSync(path20) {
|
|
279410
|
-
return
|
|
279410
|
+
return fs17.realpathSync(path20);
|
|
279411
279411
|
}
|
|
279412
279412
|
getCurrentDirectory() {
|
|
279413
|
-
return FileUtils.standardizeSlashes(
|
|
279413
|
+
return FileUtils.standardizeSlashes(fs17.getCurrentDirectory());
|
|
279414
279414
|
}
|
|
279415
279415
|
glob(patterns) {
|
|
279416
|
-
return
|
|
279416
|
+
return fs17.glob(backSlashesToForward(patterns));
|
|
279417
279417
|
}
|
|
279418
279418
|
globSync(patterns) {
|
|
279419
|
-
return
|
|
279419
|
+
return fs17.globSync(backSlashesToForward(patterns));
|
|
279420
279420
|
}
|
|
279421
279421
|
isCaseSensitive() {
|
|
279422
|
-
return
|
|
279422
|
+
return fs17.isCaseSensitive();
|
|
279423
279423
|
}
|
|
279424
279424
|
#getDirectoryNotFoundErrorIfNecessary(err, path20) {
|
|
279425
279425
|
return FileUtils.isNotExistsError(err) ? new exports2.errors.DirectoryNotFoundError(FileUtils.getStandardizedAbsolutePath(this, path20)) : err;
|
|
@@ -317461,12 +317461,12 @@ var require_dist = __commonJS({
|
|
|
317461
317461
|
throw new Error(`Unknown format "${name}"`);
|
|
317462
317462
|
return f;
|
|
317463
317463
|
};
|
|
317464
|
-
function addFormats(ajv, list,
|
|
317464
|
+
function addFormats(ajv, list, fs17, exportName) {
|
|
317465
317465
|
var _a3;
|
|
317466
317466
|
var _b;
|
|
317467
317467
|
(_a3 = (_b = ajv.opts.code).formats) !== null && _a3 !== void 0 ? _a3 : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
317468
317468
|
for (const f of list)
|
|
317469
|
-
ajv.addFormat(f,
|
|
317469
|
+
ajv.addFormat(f, fs17[f]);
|
|
317470
317470
|
}
|
|
317471
317471
|
module3.exports = exports2 = formatsPlugin;
|
|
317472
317472
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -318403,6 +318403,27 @@ function jsonResponse(result) {
|
|
|
318403
318403
|
]
|
|
318404
318404
|
};
|
|
318405
318405
|
}
|
|
318406
|
+
async function catchUpWorkspaceIndex(workspaceId) {
|
|
318407
|
+
const now = Date.now();
|
|
318408
|
+
const current = catchupState.get(workspaceId);
|
|
318409
|
+
if (current?.inFlight) {
|
|
318410
|
+
await current.inFlight;
|
|
318411
|
+
return;
|
|
318412
|
+
}
|
|
318413
|
+
if (current && now - current.lastRunAt < MCP_CATCHUP_INTERVAL_MS) {
|
|
318414
|
+
return;
|
|
318415
|
+
}
|
|
318416
|
+
const inFlight = indexWorkspace({ workspaceId, mode: "incremental" }).then(() => void 0).catch((error2) => {
|
|
318417
|
+
console.error(`OpenEZ MCP catch-up indexing failed: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
318418
|
+
}).finally(() => {
|
|
318419
|
+
catchupState.set(workspaceId, { lastRunAt: Date.now() });
|
|
318420
|
+
});
|
|
318421
|
+
catchupState.set(workspaceId, { lastRunAt: current?.lastRunAt ?? 0, inFlight });
|
|
318422
|
+
await inFlight;
|
|
318423
|
+
}
|
|
318424
|
+
async function catchUpReadWorkspaces(workspaces2) {
|
|
318425
|
+
await Promise.all(workspaces2.map((workspace) => catchUpWorkspaceIndex(workspace.id)));
|
|
318426
|
+
}
|
|
318406
318427
|
async function createAndStartMcpServer(options) {
|
|
318407
318428
|
const resolver = createWorkspaceResolver(options);
|
|
318408
318429
|
const server2 = new Server(
|
|
@@ -318514,6 +318535,7 @@ async function createAndStartMcpServer(options) {
|
|
|
318514
318535
|
case "memory_query": {
|
|
318515
318536
|
const input = memoryQuerySchema.parse(request.params.arguments ?? {});
|
|
318516
318537
|
const workspaces2 = await resolver.resolveReadWorkspaces(input);
|
|
318538
|
+
await catchUpReadWorkspaces(workspaces2);
|
|
318517
318539
|
const results = await Promise.all(
|
|
318518
318540
|
workspaces2.map(async (workspace) => ({
|
|
318519
318541
|
workspace,
|
|
@@ -318548,6 +318570,7 @@ ${result.answerContext}`).join("\n\n");
|
|
|
318548
318570
|
case "code_context": {
|
|
318549
318571
|
const input = codeContextSchema.parse(request.params.arguments ?? {});
|
|
318550
318572
|
const workspaces2 = await resolver.resolveReadWorkspaces(input);
|
|
318573
|
+
await catchUpReadWorkspaces(workspaces2);
|
|
318551
318574
|
const results = await Promise.all(
|
|
318552
318575
|
workspaces2.map(async (workspace) => ({
|
|
318553
318576
|
workspaceId: workspace.id,
|
|
@@ -318565,6 +318588,7 @@ ${result.answerContext}`).join("\n\n");
|
|
|
318565
318588
|
case "graph_neighbors": {
|
|
318566
318589
|
const input = graphNeighborsSchema.parse(request.params.arguments ?? {});
|
|
318567
318590
|
const workspaces2 = await resolver.resolveReadWorkspaces(input);
|
|
318591
|
+
await catchUpReadWorkspaces(workspaces2);
|
|
318568
318592
|
const results = await Promise.all(
|
|
318569
318593
|
workspaces2.map(async (workspace) => ({
|
|
318570
318594
|
workspaceId: workspace.id,
|
|
@@ -318615,8 +318639,7 @@ async function autoIndexAndSync(searchRoot) {
|
|
|
318615
318639
|
}
|
|
318616
318640
|
}
|
|
318617
318641
|
if (!workspace) {
|
|
318618
|
-
|
|
318619
|
-
await writeLocalWorkspaceConfig(workspace);
|
|
318642
|
+
return;
|
|
318620
318643
|
}
|
|
318621
318644
|
if (workspace.indexingStatus === "pending" || workspace.documentCount === 0) {
|
|
318622
318645
|
try {
|
|
@@ -318624,6 +318647,9 @@ async function autoIndexAndSync(searchRoot) {
|
|
|
318624
318647
|
} catch {
|
|
318625
318648
|
}
|
|
318626
318649
|
}
|
|
318650
|
+
if (!WATCH_ENABLED) {
|
|
318651
|
+
return;
|
|
318652
|
+
}
|
|
318627
318653
|
let debounceTimer = null;
|
|
318628
318654
|
const watcher = esm_default.watch(resolvedRoot, {
|
|
318629
318655
|
ignored: WATCH_IGNORE_PATTERNS,
|
|
@@ -318642,8 +318668,12 @@ async function autoIndexAndSync(searchRoot) {
|
|
|
318642
318668
|
watcher.on("add", triggerReindex);
|
|
318643
318669
|
watcher.on("change", triggerReindex);
|
|
318644
318670
|
watcher.on("unlink", triggerReindex);
|
|
318671
|
+
watcher.on("error", (error2) => {
|
|
318672
|
+
console.error(`OpenEZ MCP auto-sync watcher disabled: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
318673
|
+
void watcher.close();
|
|
318674
|
+
});
|
|
318645
318675
|
}
|
|
318646
|
-
var import_node_fs8, import_node_path12, memoryQuerySchema, codeContextSchema, graphNeighborsSchema, memoryWriteSchema, indexWorkspaceSchema, WATCH_DEBOUNCE_MS, WATCH_IGNORE_PATTERNS;
|
|
318676
|
+
var import_node_fs8, import_node_path12, memoryQuerySchema, codeContextSchema, graphNeighborsSchema, memoryWriteSchema, indexWorkspaceSchema, MCP_CATCHUP_INTERVAL_MS, catchupState, WATCH_DEBOUNCE_MS, WATCH_ENABLED, WATCH_IGNORE_PATTERNS;
|
|
318647
318677
|
var init_mcp_core = __esm({
|
|
318648
318678
|
"../mcp/src/mcp-core.ts"() {
|
|
318649
318679
|
"use strict";
|
|
@@ -318697,7 +318727,10 @@ var init_mcp_core = __esm({
|
|
|
318697
318727
|
path: external_exports.string().optional(),
|
|
318698
318728
|
mode: external_exports.enum(["incremental", "full"]).optional()
|
|
318699
318729
|
});
|
|
318730
|
+
MCP_CATCHUP_INTERVAL_MS = Number(process.env.OPENEZ_MCP_CATCHUP_INTERVAL_MS ?? 5e3);
|
|
318731
|
+
catchupState = /* @__PURE__ */ new Map();
|
|
318700
318732
|
WATCH_DEBOUNCE_MS = 2e3;
|
|
318733
|
+
WATCH_ENABLED = ["1", "true", "yes"].includes((process.env.OPENEZ_MCP_WATCH ?? "").toLowerCase());
|
|
318701
318734
|
WATCH_IGNORE_PATTERNS = [
|
|
318702
318735
|
"**/node_modules/**",
|
|
318703
318736
|
"**/.git/**",
|
|
@@ -318914,6 +318947,9 @@ function initializeWorkspaceSchema2(db) {
|
|
|
318914
318947
|
}
|
|
318915
318948
|
function getWorkspaceDb2(rootPath) {
|
|
318916
318949
|
const normalized = normalizeRootPath2(rootPath);
|
|
318950
|
+
if (normalized === "/" || normalized === "" || !import_node_fs9.default.existsSync(normalized)) {
|
|
318951
|
+
throw new Error(`Workspace root path does not exist: "${rootPath}"`);
|
|
318952
|
+
}
|
|
318917
318953
|
const cached2 = workspaceDbs.get(normalized);
|
|
318918
318954
|
if (cached2) {
|
|
318919
318955
|
return cached2;
|
|
@@ -319175,9 +319211,9 @@ function mapWorkspace2(ws) {
|
|
|
319175
319211
|
}
|
|
319176
319212
|
function resolveWebDist() {
|
|
319177
319213
|
const sourceDist = import_node_path14.default.resolve(__dirname, "..", "dist");
|
|
319178
|
-
if ((0,
|
|
319214
|
+
if ((0, import_node_fs10.existsSync)(import_node_path14.default.join(sourceDist, "index.html"))) return sourceDist;
|
|
319179
319215
|
const cliDist = import_node_path14.default.resolve(__dirname, "web");
|
|
319180
|
-
if ((0,
|
|
319216
|
+
if ((0, import_node_fs10.existsSync)(import_node_path14.default.join(cliDist, "index.html"))) return cliDist;
|
|
319181
319217
|
return null;
|
|
319182
319218
|
}
|
|
319183
319219
|
function createWebServer() {
|
|
@@ -319186,22 +319222,21 @@ function createWebServer() {
|
|
|
319186
319222
|
app.use("/*", (0, import_serve_static.serveStatic)({ root: webDist, rewriteRequestPath: (p) => p }));
|
|
319187
319223
|
app.get("*", (c) => {
|
|
319188
319224
|
const indexPath = import_node_path14.default.join(webDist, "index.html");
|
|
319189
|
-
const index2 = (0,
|
|
319225
|
+
const index2 = (0, import_node_fs10.readFileSync)(indexPath, "utf-8");
|
|
319190
319226
|
return c.html(index2);
|
|
319191
319227
|
});
|
|
319192
319228
|
}
|
|
319193
319229
|
return app;
|
|
319194
319230
|
}
|
|
319195
|
-
var import_hono, import_cors,
|
|
319231
|
+
var import_serve_static, import_hono, import_cors, import_node_crypto3, import_node_fs10, import_node_path14, app, DEFAULT_INCLUDE_GLOBS, DEFAULT_EXCLUDE_GLOBS;
|
|
319196
319232
|
var init_server3 = __esm({
|
|
319197
319233
|
"../web/src/server/index.ts"() {
|
|
319198
319234
|
"use strict";
|
|
319235
|
+
import_serve_static = require("@hono/node-server/serve-static");
|
|
319199
319236
|
import_hono = require("hono");
|
|
319200
319237
|
import_cors = require("hono/cors");
|
|
319201
|
-
import_serve_static = require("@hono/node-server/serve-static");
|
|
319202
319238
|
import_node_crypto3 = __toESM(require("crypto"), 1);
|
|
319203
319239
|
import_node_fs10 = require("fs");
|
|
319204
|
-
import_node_fs11 = require("fs");
|
|
319205
319240
|
import_node_path14 = __toESM(require("path"), 1);
|
|
319206
319241
|
init_sqlite2();
|
|
319207
319242
|
init_src3();
|
|
@@ -319231,7 +319266,13 @@ var init_server3 = __esm({
|
|
|
319231
319266
|
app.get("/api/dashboard", (c) => {
|
|
319232
319267
|
try {
|
|
319233
319268
|
const all = listRegistryWorkspaces();
|
|
319234
|
-
const target = all
|
|
319269
|
+
const target = all.find((ws) => {
|
|
319270
|
+
try {
|
|
319271
|
+
return ws.rootPath && ws.rootPath !== "/" && (0, import_node_fs10.existsSync)(ws.rootPath);
|
|
319272
|
+
} catch {
|
|
319273
|
+
return false;
|
|
319274
|
+
}
|
|
319275
|
+
}) ?? all[0];
|
|
319235
319276
|
if (!target) {
|
|
319236
319277
|
return c.json({
|
|
319237
319278
|
workspace: { id: "", name: "No workspace", root: "" },
|
|
@@ -319312,11 +319353,20 @@ var init_server3 = __esm({
|
|
|
319312
319353
|
try {
|
|
319313
319354
|
const dbPath = resolveRegistryDbPath2();
|
|
319314
319355
|
const all = listRegistryWorkspaces();
|
|
319315
|
-
const data = all.map((ws) =>
|
|
319316
|
-
|
|
319317
|
-
|
|
319318
|
-
|
|
319319
|
-
|
|
319356
|
+
const data = all.map((ws) => {
|
|
319357
|
+
let latestIndexRun = null;
|
|
319358
|
+
let latestGraphRun = null;
|
|
319359
|
+
try {
|
|
319360
|
+
latestIndexRun = getLatestIndexRun(ws.rootPath);
|
|
319361
|
+
latestGraphRun = getLatestGraphRun(ws.rootPath);
|
|
319362
|
+
} catch {
|
|
319363
|
+
}
|
|
319364
|
+
return {
|
|
319365
|
+
...mapWorkspace2(ws),
|
|
319366
|
+
latestIndexRun,
|
|
319367
|
+
latestGraphRun
|
|
319368
|
+
};
|
|
319369
|
+
});
|
|
319320
319370
|
return c.json({ ok: true, data });
|
|
319321
319371
|
} catch (err) {
|
|
319322
319372
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -319577,6 +319627,14 @@ function resolveCliInvocation() {
|
|
|
319577
319627
|
};
|
|
319578
319628
|
}
|
|
319579
319629
|
const repoRoot = import_node_path15.default.resolve(thisDir, "../../..");
|
|
319630
|
+
const builtCliPath = import_node_path15.default.resolve(thisDir, "../dist/cli.cjs");
|
|
319631
|
+
if (import_node_fs11.default.existsSync(builtCliPath)) {
|
|
319632
|
+
return {
|
|
319633
|
+
command: process.execPath,
|
|
319634
|
+
args: [builtCliPath, "serve", "--mcp"],
|
|
319635
|
+
repoRoot
|
|
319636
|
+
};
|
|
319637
|
+
}
|
|
319580
319638
|
const tsxPath = import_node_path15.default.join(repoRoot, "node_modules", ".bin", "tsx");
|
|
319581
319639
|
const cliPath = import_node_path15.default.resolve(thisDir, "./cli.ts");
|
|
319582
319640
|
return {
|
|
@@ -319585,10 +319643,11 @@ function resolveCliInvocation() {
|
|
|
319585
319643
|
repoRoot
|
|
319586
319644
|
};
|
|
319587
319645
|
}
|
|
319588
|
-
var import_node_path15, import_meta4;
|
|
319646
|
+
var import_node_fs11, import_node_path15, import_meta4;
|
|
319589
319647
|
var init_resolve_cli = __esm({
|
|
319590
319648
|
"src/resolve-cli.ts"() {
|
|
319591
319649
|
"use strict";
|
|
319650
|
+
import_node_fs11 = __toESM(require("fs"), 1);
|
|
319592
319651
|
import_node_path15 = __toESM(require("path"), 1);
|
|
319593
319652
|
import_meta4 = {};
|
|
319594
319653
|
}
|
|
@@ -320714,7 +320773,7 @@ var {
|
|
|
320714
320773
|
init_src();
|
|
320715
320774
|
init_src4();
|
|
320716
320775
|
var program2 = new Command();
|
|
320717
|
-
program2.name("openez").description("OpenEZ Graph - Local-first knowledge retrieval system").version("0.
|
|
320776
|
+
program2.name("openez").description("OpenEZ Graph - Local-first knowledge retrieval system").version("0.3.0");
|
|
320718
320777
|
program2.command("init").description("Initialize a workspace at the given path and run initial index").argument("[path]", "path to the project directory", process.cwd()).option("--no-index", "skip initial indexing").action(async (targetPath, options) => {
|
|
320719
320778
|
const resolvedPath = import_node_path19.default.resolve(targetPath);
|
|
320720
320779
|
if (!import_node_fs15.default.existsSync(resolvedPath)) {
|
|
@@ -320758,6 +320817,7 @@ program2.command("index").description("Index files in a workspace").argument("[p
|
|
|
320758
320817
|
});
|
|
320759
320818
|
console.log(`Auto-registered workspace '${workspace.name}' (${workspace.id})`);
|
|
320760
320819
|
}
|
|
320820
|
+
await writeLocalWorkspaceConfig(workspace);
|
|
320761
320821
|
const summary = await indexWorkspace({ workspaceId: workspace.id });
|
|
320762
320822
|
console.log(JSON.stringify(summary, null, 2));
|
|
320763
320823
|
});
|
|
@@ -320769,6 +320829,7 @@ program2.command("reindex").description("Full rebuild of a workspace index").arg
|
|
|
320769
320829
|
console.error(`Error: no workspace registered at ${resolvedPath}. Run 'openez init' first.`);
|
|
320770
320830
|
process.exit(1);
|
|
320771
320831
|
}
|
|
320832
|
+
await writeLocalWorkspaceConfig(workspace);
|
|
320772
320833
|
const summary = await indexWorkspace({ workspaceId: workspace.id, mode: "full" });
|
|
320773
320834
|
console.log(JSON.stringify(summary, null, 2));
|
|
320774
320835
|
});
|
|
@@ -320782,8 +320843,10 @@ program2.command("watch").description("Watch files and re-index on changes").arg
|
|
|
320782
320843
|
});
|
|
320783
320844
|
console.log(`Auto-registered workspace '${workspace.name}' (${workspace.id})`);
|
|
320784
320845
|
}
|
|
320846
|
+
await writeLocalWorkspaceConfig(workspace);
|
|
320847
|
+
const workspaceId = workspace.id;
|
|
320785
320848
|
console.log(`Running initial index for ${resolvedPath}...`);
|
|
320786
|
-
await indexWorkspace({ workspaceId
|
|
320849
|
+
await indexWorkspace({ workspaceId });
|
|
320787
320850
|
const watcher = esm_default.watch(resolvedPath, {
|
|
320788
320851
|
ignored: [
|
|
320789
320852
|
"**/node_modules/**",
|
|
@@ -320798,14 +320861,39 @@ program2.command("watch").description("Watch files and re-index on changes").arg
|
|
|
320798
320861
|
ignoreInitial: true,
|
|
320799
320862
|
persistent: true
|
|
320800
320863
|
});
|
|
320801
|
-
|
|
320802
|
-
|
|
320803
|
-
|
|
320804
|
-
|
|
320864
|
+
let debounceTimer;
|
|
320865
|
+
let isIndexing = false;
|
|
320866
|
+
let hasPendingChange = false;
|
|
320867
|
+
const runReindex = async () => {
|
|
320868
|
+
if (isIndexing) {
|
|
320869
|
+
hasPendingChange = true;
|
|
320870
|
+
return;
|
|
320871
|
+
}
|
|
320872
|
+
isIndexing = true;
|
|
320873
|
+
do {
|
|
320874
|
+
hasPendingChange = false;
|
|
320875
|
+
console.log("Change detected, re-indexing...");
|
|
320876
|
+
try {
|
|
320877
|
+
const summary = await indexWorkspace({ workspaceId });
|
|
320878
|
+
console.log(JSON.stringify(summary, null, 2));
|
|
320879
|
+
} catch (error2) {
|
|
320880
|
+
console.error("Re-index failed:");
|
|
320881
|
+
console.error(error2);
|
|
320882
|
+
}
|
|
320883
|
+
} while (hasPendingChange);
|
|
320884
|
+
isIndexing = false;
|
|
320885
|
+
};
|
|
320886
|
+
const scheduleReindex = () => {
|
|
320887
|
+
if (debounceTimer) {
|
|
320888
|
+
clearTimeout(debounceTimer);
|
|
320889
|
+
}
|
|
320890
|
+
debounceTimer = setTimeout(() => {
|
|
320891
|
+
void runReindex();
|
|
320892
|
+
}, 250);
|
|
320805
320893
|
};
|
|
320806
|
-
watcher.on("add",
|
|
320807
|
-
watcher.on("change",
|
|
320808
|
-
watcher.on("unlink",
|
|
320894
|
+
watcher.on("add", scheduleReindex);
|
|
320895
|
+
watcher.on("change", scheduleReindex);
|
|
320896
|
+
watcher.on("unlink", scheduleReindex);
|
|
320809
320897
|
console.log(`Watching ${resolvedPath} for changes...`);
|
|
320810
320898
|
});
|
|
320811
320899
|
program2.command("serve").description("Start the web dashboard or MCP server").option("--mcp", "run as MCP server instead of web").option("--web", "start the web dashboard API server").option("-p, --path <path>", "workspace path").option("--port <port>", "API server port (default: 11368)").action(async (options) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openez-graph/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
|
+
"description": "Local-first code intelligence engine — index, query, and graph your codebase with zero config. SQLite-only, MCP-first.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Asta Nguyen",
|
|
7
|
+
"homepage": "https://github.com/asta-nguyen/openez-graph",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/asta-nguyen/openez-graph.git",
|
|
11
|
+
"directory": "apps/cli"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/asta-nguyen/openez-graph/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"code-intelligence",
|
|
18
|
+
"code-graph",
|
|
19
|
+
"mcp",
|
|
20
|
+
"model-context-protocol",
|
|
21
|
+
"code-indexing",
|
|
22
|
+
"codebase",
|
|
23
|
+
"retrieval",
|
|
24
|
+
"sqlite",
|
|
25
|
+
"local-first",
|
|
26
|
+
"developer-tools",
|
|
27
|
+
"ai-coding",
|
|
28
|
+
"claude-code",
|
|
29
|
+
"codex"
|
|
30
|
+
],
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=20"
|
|
33
|
+
},
|
|
4
34
|
"type": "module",
|
|
5
35
|
"main": "./src/cli.ts",
|
|
6
36
|
"types": "./src/cli.ts",
|
|
@@ -9,7 +39,8 @@
|
|
|
9
39
|
},
|
|
10
40
|
"files": [
|
|
11
41
|
"dist",
|
|
12
|
-
"README.md"
|
|
42
|
+
"README.md",
|
|
43
|
+
"LICENSE"
|
|
13
44
|
],
|
|
14
45
|
"publishConfig": {
|
|
15
46
|
"main": "./dist/cli.cjs",
|