@danielblomma/cortex-mcp 2.1.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -24
- package/bin/cortex.mjs +50 -21
- package/mcp-registry-submission.json +63 -0
- package/package.json +19 -5
- package/scaffold/AGENTS.md +13 -9
- package/scaffold/CLAUDE.md +13 -9
- package/scaffold/docs/architecture.md +1 -1
- package/scaffold/mcp/build.mjs +92 -0
- package/scaffold/mcp/package.json +4 -4
- package/scaffold/mcp/src/cli/query.ts +455 -0
- package/scaffold/mcp/src/embed.ts +181 -77
- package/scaffold/mcp/src/embedScheduler.ts +509 -0
- package/scaffold/mcp/src/embeddings.ts +31 -30
- package/scaffold/mcp/src/graphCsv.ts +65 -0
- package/scaffold/mcp/src/jsonl.ts +69 -14
- package/scaffold/mcp/src/loadGraph.ts +276 -40
- package/scaffold/mcp/src/lruCache.ts +41 -0
- package/scaffold/mcp/src/searchCore.ts +1 -1
- package/scaffold/mcp/src/searchResults.ts +3 -3
- package/scaffold/mcp/src/types.ts +6 -1
- package/scaffold/mcp/tests/embed-scheduler.test.mjs +474 -0
- package/scaffold/mcp/tests/embedding-jsonl.test.mjs +39 -0
- package/scaffold/mcp/tests/graph-bulk-load.test.mjs +258 -0
- package/scaffold/mcp/tests/graph-csv.test.mjs +118 -0
- package/scaffold/mcp/tests/lru-cache.test.mjs +37 -0
- package/scaffold/mcp/tests/query-cli.test.mjs +115 -0
- package/scaffold/mcp/tests/vector-index.test.mjs +109 -0
- package/scaffold/mcp/tsconfig.json +3 -1
- package/scaffold/scripts/bootstrap.sh +37 -4
- package/scaffold/scripts/dashboard.mjs +1 -1
- package/scaffold/scripts/doctor.sh +9 -8
- package/scaffold/scripts/embed.sh +3 -2
- package/scaffold/scripts/ingest-parsers.mjs +387 -0
- package/scaffold/scripts/ingest-worker.mjs +52 -0
- package/scaffold/scripts/ingest.mjs +550 -378
- package/scaffold/scripts/load-ryu.sh +3 -2
- package/scaffold/scripts/memory-compile.mjs +5 -2
- package/scaffold/scripts/memory-lint.mjs +5 -2
- package/scaffold/scripts/parsers/csharp.mjs +2 -1
- package/scaffold/scripts/parsers/javascript/ast.mjs +160 -8
- package/scaffold/scripts/parsers/javascript/chunks.mjs +129 -22
- package/scaffold/scripts/parsers/javascript/imports.mjs +38 -4
- package/scaffold/scripts/parsers/vbnet.mjs +2 -1
- package/scaffold/scripts/status.sh +50 -14
- package/scaffold/scripts/parsers/node_modules/.package-lock.json +0 -56
- package/scaffold/scripts/parsers/node_modules/acorn/CHANGELOG.md +0 -972
- package/scaffold/scripts/parsers/node_modules/acorn/LICENSE +0 -21
- package/scaffold/scripts/parsers/node_modules/acorn/README.md +0 -301
- package/scaffold/scripts/parsers/node_modules/acorn/bin/acorn +0 -4
- package/scaffold/scripts/parsers/node_modules/acorn/dist/acorn.d.mts +0 -883
- package/scaffold/scripts/parsers/node_modules/acorn/dist/acorn.d.ts +0 -883
- package/scaffold/scripts/parsers/node_modules/acorn/dist/acorn.js +0 -6295
- package/scaffold/scripts/parsers/node_modules/acorn/dist/acorn.mjs +0 -6266
- package/scaffold/scripts/parsers/node_modules/acorn/dist/bin.js +0 -90
- package/scaffold/scripts/parsers/node_modules/acorn/package.json +0 -50
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/CHANGELOG.md +0 -421
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/LICENSE +0 -21
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/README.md +0 -81
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/error.d.ts +0 -103
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/error.js +0 -78
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/error.js.map +0 -1
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/decorators.d.ts +0 -167
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/decorators.js +0 -75
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/decorators.js.map +0 -1
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/import-assertions.d.ts +0 -177
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/import-assertions.js +0 -56
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/import-assertions.js.map +0 -1
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/jsx/index.d.ts +0 -198
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/jsx/index.js +0 -327
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/jsx/index.js.map +0 -1
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/jsx/xhtml.d.ts +0 -256
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/jsx/xhtml.js +0 -256
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/jsx/xhtml.js.map +0 -1
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/index.d.ts +0 -472
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/index.js +0 -1
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/index.js.map +0 -1
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/index.mjs +0 -1
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/middleware.d.ts +0 -159
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/middleware.js +0 -2
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/middleware.js.map +0 -1
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/parseutil.d.ts +0 -10
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/parseutil.js +0 -38
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/parseutil.js.map +0 -1
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/scopeflags.d.ts +0 -12
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/scopeflags.js +0 -29
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/scopeflags.js.map +0 -1
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/tokenType.d.ts +0 -2
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/tokenType.js +0 -118
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/tokenType.js.map +0 -1
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/types.d.ts +0 -60
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/types.js +0 -2
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/types.js.map +0 -1
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/whitespace.d.ts +0 -2
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/whitespace.js +0 -19
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/whitespace.js.map +0 -1
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/package.json +0 -53
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/tsconfig.json +0 -19
- package/scaffold/scripts/parsers/node_modules/acorn-walk/CHANGELOG.md +0 -209
- package/scaffold/scripts/parsers/node_modules/acorn-walk/LICENSE +0 -21
- package/scaffold/scripts/parsers/node_modules/acorn-walk/README.md +0 -124
- package/scaffold/scripts/parsers/node_modules/acorn-walk/dist/walk.d.mts +0 -152
- package/scaffold/scripts/parsers/node_modules/acorn-walk/dist/walk.d.ts +0 -152
- package/scaffold/scripts/parsers/node_modules/acorn-walk/dist/walk.js +0 -485
- package/scaffold/scripts/parsers/node_modules/acorn-walk/dist/walk.mjs +0 -467
- package/scaffold/scripts/parsers/node_modules/acorn-walk/package.json +0 -50
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/LICENSE +0 -24
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/README.md +0 -23
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-bash.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-c.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-c_sharp.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-cpp.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-css.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-dart.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-elisp.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-elixir.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-elm.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-embedded_template.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-go.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-html.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-java.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-javascript.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-json.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-kotlin.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-lua.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-objc.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-ocaml.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-php.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-python.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-ql.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-rescript.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-ruby.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-rust.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-scala.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-solidity.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-swift.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-systemrdl.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-tlaplus.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-toml.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-tsx.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-typescript.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-vue.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-yaml.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/out/tree-sitter-zig.wasm +0 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/package.json +0 -64
- package/scaffold/scripts/parsers/node_modules/web-tree-sitter/LICENSE +0 -21
- package/scaffold/scripts/parsers/node_modules/web-tree-sitter/README.md +0 -198
- package/scaffold/scripts/parsers/node_modules/web-tree-sitter/package.json +0 -37
- package/scaffold/scripts/parsers/node_modules/web-tree-sitter/tree-sitter-web.d.ts +0 -242
- package/scaffold/scripts/parsers/node_modules/web-tree-sitter/tree-sitter.js +0 -1
- package/scaffold/scripts/parsers/node_modules/web-tree-sitter/tree-sitter.wasm +0 -0
|
@@ -3,7 +3,8 @@ set -euo pipefail
|
|
|
3
3
|
|
|
4
4
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
5
|
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
6
|
-
|
|
6
|
+
CONTEXT_RUNTIME_DIR="$REPO_ROOT/.context/mcp"
|
|
7
|
+
MCP_DIR="$CONTEXT_RUNTIME_DIR"
|
|
7
8
|
|
|
8
9
|
if [[ ! -f "$MCP_DIR/package.json" ]]; then
|
|
9
10
|
echo "[graph-load] missing $MCP_DIR/package.json"
|
|
@@ -11,7 +12,7 @@ if [[ ! -f "$MCP_DIR/package.json" ]]; then
|
|
|
11
12
|
fi
|
|
12
13
|
|
|
13
14
|
if [[ ! -d "$MCP_DIR/node_modules" ]]; then
|
|
14
|
-
echo "[graph-load] node_modules missing in .context/mcp
|
|
15
|
+
echo "[graph-load] node_modules missing in context runtime (.context/mcp compatibility path)"
|
|
15
16
|
echo "[graph-load] run: cd .context/mcp && NPM_CONFIG_CACHE=$MCP_DIR/.npm-cache npm install"
|
|
16
17
|
exit 1
|
|
17
18
|
fi
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { fileURLToPath } from "node:url";
|
|
5
|
-
import { parseFrontmatter, parseStringList } from "../mcp/dist/frontmatter.js";
|
|
4
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
6
5
|
|
|
7
6
|
const __filename = fileURLToPath(import.meta.url);
|
|
8
7
|
const __dirname = path.dirname(__filename);
|
|
8
|
+
const CONTEXT_RUNTIME_DIST = path.resolve(__dirname, "../mcp/dist");
|
|
9
|
+
const { parseFrontmatter, parseStringList } = await import(
|
|
10
|
+
pathToFileURL(path.join(CONTEXT_RUNTIME_DIST, "frontmatter.js")).href
|
|
11
|
+
);
|
|
9
12
|
|
|
10
13
|
function normalizeForWsl(rawPath) {
|
|
11
14
|
const m = rawPath.match(/^([A-Za-z]):[/\\](.*)/);
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { fileURLToPath } from "node:url";
|
|
5
|
-
import { parseFrontmatter, parseStringList } from "../mcp/dist/frontmatter.js";
|
|
4
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
6
5
|
|
|
7
6
|
const __filename = fileURLToPath(import.meta.url);
|
|
8
7
|
const __dirname = path.dirname(__filename);
|
|
8
|
+
const CONTEXT_RUNTIME_DIST = path.resolve(__dirname, "../mcp/dist");
|
|
9
|
+
const { parseFrontmatter, parseStringList } = await import(
|
|
10
|
+
pathToFileURL(path.join(CONTEXT_RUNTIME_DIST, "frontmatter.js")).href
|
|
11
|
+
);
|
|
9
12
|
|
|
10
13
|
function normalizeForWsl(rawPath) {
|
|
11
14
|
const m = rawPath.match(/^([A-Za-z]):[/\\](.*)/);
|
|
@@ -35,6 +35,8 @@ base.Class = (node, st, visit) => {
|
|
|
35
35
|
|
|
36
36
|
const tsNodeHandlers = {
|
|
37
37
|
TSAsExpression(node, st, visit) { visit(node.expression, st); },
|
|
38
|
+
TSSatisfiesExpression(node, st, visit) { visit(node.expression, st); },
|
|
39
|
+
TSTypeAssertion(node, st, visit) { visit(node.expression, st); },
|
|
38
40
|
TSTypeAnnotation(node, st, visit) {
|
|
39
41
|
if (node.typeAnnotation) {
|
|
40
42
|
visit(node.typeAnnotation, st);
|
|
@@ -63,15 +65,80 @@ const tsNodeHandlers = {
|
|
|
63
65
|
visit(node.typeParameters, st);
|
|
64
66
|
}
|
|
65
67
|
},
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
TSQualifiedName(node, st, visit) {
|
|
69
|
+
if (node.left) visit(node.left, st);
|
|
70
|
+
if (node.right) visit(node.right, st);
|
|
71
|
+
},
|
|
72
|
+
TSInterfaceDeclaration(node, st, visit) {
|
|
73
|
+
if (node.extends) {
|
|
74
|
+
for (const extendedType of node.extends) {
|
|
75
|
+
visit(extendedType, st);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (node.body) {
|
|
79
|
+
visit(node.body, st);
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
TSInterfaceBody(node, st, visit) {
|
|
83
|
+
for (const member of node.body || []) {
|
|
84
|
+
visit(member, st);
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
TSTypeAliasDeclaration(node, st, visit) {
|
|
88
|
+
if (node.typeParameters) {
|
|
89
|
+
visit(node.typeParameters, st);
|
|
90
|
+
}
|
|
91
|
+
if (node.typeAnnotation) {
|
|
92
|
+
visit(node.typeAnnotation, st);
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
TSEnumDeclaration(node, st, visit) {
|
|
96
|
+
for (const member of node.members || []) {
|
|
97
|
+
visit(member, st);
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
TSEnumMember(node, st, visit) {
|
|
101
|
+
if (node.initializer) {
|
|
102
|
+
visit(node.initializer, st);
|
|
103
|
+
}
|
|
104
|
+
},
|
|
69
105
|
TSModuleDeclaration() {},
|
|
70
106
|
TSDeclareFunction() {},
|
|
71
|
-
TSPropertySignature() {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
107
|
+
TSPropertySignature(node, st, visit) {
|
|
108
|
+
if (node.computed && node.key) {
|
|
109
|
+
visit(node.key, st);
|
|
110
|
+
}
|
|
111
|
+
if (node.typeAnnotation) {
|
|
112
|
+
visit(node.typeAnnotation, st);
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
TSMethodSignature(node, st, visit) {
|
|
116
|
+
if (node.computed && node.key) {
|
|
117
|
+
visit(node.key, st);
|
|
118
|
+
}
|
|
119
|
+
if (node.typeParameters) {
|
|
120
|
+
visit(node.typeParameters, st);
|
|
121
|
+
}
|
|
122
|
+
for (const param of node.params || []) {
|
|
123
|
+
visit(param, st);
|
|
124
|
+
}
|
|
125
|
+
if (node.returnType) {
|
|
126
|
+
visit(node.returnType, st);
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
TSIndexSignature(node, st, visit) {
|
|
130
|
+
for (const param of node.params || []) {
|
|
131
|
+
visit(param, st);
|
|
132
|
+
}
|
|
133
|
+
if (node.typeAnnotation) {
|
|
134
|
+
visit(node.typeAnnotation, st);
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
TSTypeLiteral(node, st, visit) {
|
|
138
|
+
for (const member of node.members || node.body || []) {
|
|
139
|
+
visit(member, st);
|
|
140
|
+
}
|
|
141
|
+
},
|
|
75
142
|
TSUnionType(node, st, visit) {
|
|
76
143
|
for (const typeNode of node.types || []) {
|
|
77
144
|
visit(typeNode, st);
|
|
@@ -132,9 +199,94 @@ const tsNodeHandlers = {
|
|
|
132
199
|
}
|
|
133
200
|
},
|
|
134
201
|
TSNonNullExpression(node, st, visit) { visit(node.expression, st); },
|
|
135
|
-
TSInstantiationExpression(node, st, visit) { visit(node.expression, st); }
|
|
202
|
+
TSInstantiationExpression(node, st, visit) { visit(node.expression, st); },
|
|
203
|
+
JSXElement(node, st, visit) {
|
|
204
|
+
if (node.openingElement) {
|
|
205
|
+
visit(node.openingElement, st);
|
|
206
|
+
}
|
|
207
|
+
for (const child of node.children || []) {
|
|
208
|
+
visit(child, st);
|
|
209
|
+
}
|
|
210
|
+
if (node.closingElement) {
|
|
211
|
+
visit(node.closingElement, st);
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
JSXFragment(node, st, visit) {
|
|
215
|
+
if (node.openingFragment) {
|
|
216
|
+
visit(node.openingFragment, st);
|
|
217
|
+
}
|
|
218
|
+
for (const child of node.children || []) {
|
|
219
|
+
visit(child, st);
|
|
220
|
+
}
|
|
221
|
+
if (node.closingFragment) {
|
|
222
|
+
visit(node.closingFragment, st);
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
JSXOpeningElement(node, st, visit) {
|
|
226
|
+
if (node.name) {
|
|
227
|
+
visit(node.name, st);
|
|
228
|
+
}
|
|
229
|
+
for (const attribute of node.attributes || []) {
|
|
230
|
+
visit(attribute, st);
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
JSXClosingElement(node, st, visit) {
|
|
234
|
+
if (node.name) {
|
|
235
|
+
visit(node.name, st);
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
JSXAttribute(node, st, visit) {
|
|
239
|
+
if (node.value) {
|
|
240
|
+
visit(node.value, st);
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
JSXExpressionContainer(node, st, visit) {
|
|
244
|
+
if (node.expression && node.expression.type !== "JSXEmptyExpression") {
|
|
245
|
+
visit(node.expression, st);
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
JSXSpreadAttribute(node, st, visit) {
|
|
249
|
+
if (node.argument) {
|
|
250
|
+
visit(node.argument, st);
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
JSXMemberExpression(node, st, visit) {
|
|
254
|
+
if (node.object) {
|
|
255
|
+
visit(node.object, st);
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
JSXNamespacedName(node, st, visit) {
|
|
259
|
+
if (node.namespace) {
|
|
260
|
+
visit(node.namespace, st);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
136
263
|
};
|
|
137
264
|
|
|
265
|
+
for (const nodeType of [
|
|
266
|
+
"JSXClosingFragment",
|
|
267
|
+
"JSXEmptyExpression",
|
|
268
|
+
"JSXIdentifier",
|
|
269
|
+
"JSXOpeningFragment",
|
|
270
|
+
"JSXText",
|
|
271
|
+
"TSAnyKeyword",
|
|
272
|
+
"TSBigIntKeyword",
|
|
273
|
+
"TSBooleanKeyword",
|
|
274
|
+
"TSIntrinsicKeyword",
|
|
275
|
+
"TSNeverKeyword",
|
|
276
|
+
"TSNullKeyword",
|
|
277
|
+
"TSNumberKeyword",
|
|
278
|
+
"TSObjectKeyword",
|
|
279
|
+
"TSStringKeyword",
|
|
280
|
+
"TSSymbolKeyword",
|
|
281
|
+
"TSUndefinedKeyword",
|
|
282
|
+
"TSUnknownKeyword",
|
|
283
|
+
"TSVoidKeyword",
|
|
284
|
+
"TSThisType",
|
|
285
|
+
"TSLiteralType"
|
|
286
|
+
]) {
|
|
287
|
+
tsNodeHandlers[nodeType] = () => {};
|
|
288
|
+
}
|
|
289
|
+
|
|
138
290
|
Object.assign(base, tsNodeHandlers);
|
|
139
291
|
|
|
140
292
|
export const WALK_BASE = base;
|
|
@@ -45,6 +45,18 @@ export function discoverChunks(ast, code, language = "javascript") {
|
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
|
|
48
|
+
TSInterfaceDeclaration(node) {
|
|
49
|
+
pushChunk(extractTypeDeclarationChunk(node, "interface", code));
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
TSTypeAliasDeclaration(node) {
|
|
53
|
+
pushChunk(extractTypeDeclarationChunk(node, "type", code));
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
TSEnumDeclaration(node) {
|
|
57
|
+
pushChunk(extractTypeDeclarationChunk(node, "enum", code));
|
|
58
|
+
},
|
|
59
|
+
|
|
48
60
|
VariableDeclaration(node) {
|
|
49
61
|
for (const declarator of node.declarations || []) {
|
|
50
62
|
if (!declarator.id || declarator.id.type !== "Identifier" || !declarator.init) {
|
|
@@ -100,6 +112,15 @@ function collectExportedNames(ast) {
|
|
|
100
112
|
exportedNames.add(node.declaration.id.name);
|
|
101
113
|
}
|
|
102
114
|
|
|
115
|
+
if (
|
|
116
|
+
(node.declaration.type === "TSInterfaceDeclaration" ||
|
|
117
|
+
node.declaration.type === "TSTypeAliasDeclaration" ||
|
|
118
|
+
node.declaration.type === "TSEnumDeclaration") &&
|
|
119
|
+
node.declaration.id?.name
|
|
120
|
+
) {
|
|
121
|
+
exportedNames.add(node.declaration.id.name);
|
|
122
|
+
}
|
|
123
|
+
|
|
103
124
|
if (node.declaration.type === "VariableDeclaration") {
|
|
104
125
|
for (const declarator of node.declaration.declarations || []) {
|
|
105
126
|
if (declarator.id?.type === "Identifier") {
|
|
@@ -292,34 +313,120 @@ function extractClassMethods(classNode, code, language) {
|
|
|
292
313
|
const className = classNode.id?.name || "UnknownClass";
|
|
293
314
|
|
|
294
315
|
for (const member of classNode.body.body || []) {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
316
|
+
const methodChunk =
|
|
317
|
+
member.type === "MethodDefinition"
|
|
318
|
+
? extractClassMethodChunk(member, className, code, language)
|
|
319
|
+
: extractClassFieldFunctionChunk(member, className, code, language);
|
|
298
320
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
const bodyStart = findLeadingCommentStart(code, member);
|
|
303
|
-
|
|
304
|
-
methods.push({
|
|
305
|
-
name: `${className}.${member.key.name}`,
|
|
306
|
-
kind: "method",
|
|
307
|
-
signature: `${prefix}${member.key.name}(${params.join(", ")})`,
|
|
308
|
-
body: code.slice(bodyStart, member.end),
|
|
309
|
-
startLine: member.loc.start.line,
|
|
310
|
-
endLine: member.loc.end.line,
|
|
311
|
-
callNode: member.value.body,
|
|
312
|
-
importNode: member,
|
|
313
|
-
static: isStatic,
|
|
314
|
-
async: member.value.async === true,
|
|
315
|
-
generator: member.value.generator === true,
|
|
316
|
-
language
|
|
317
|
-
});
|
|
321
|
+
if (methodChunk) {
|
|
322
|
+
methods.push(methodChunk);
|
|
323
|
+
}
|
|
318
324
|
}
|
|
319
325
|
|
|
320
326
|
return methods;
|
|
321
327
|
}
|
|
322
328
|
|
|
329
|
+
function extractClassMethodChunk(member, className, code, language) {
|
|
330
|
+
const methodName = getPropertyName(member.key, member.computed);
|
|
331
|
+
if (!methodName) {
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const params = (member.value.params || []).map(formatParameterName);
|
|
336
|
+
const isStatic = member.static === true;
|
|
337
|
+
const prefix = isStatic ? "static " : "";
|
|
338
|
+
const bodyStart = findLeadingCommentStart(code, member);
|
|
339
|
+
|
|
340
|
+
return {
|
|
341
|
+
name: `${className}.${methodName}`,
|
|
342
|
+
kind: "method",
|
|
343
|
+
signature: `${prefix}${methodName}(${params.join(", ")})`,
|
|
344
|
+
body: code.slice(bodyStart, member.end),
|
|
345
|
+
startLine: member.loc.start.line,
|
|
346
|
+
endLine: member.loc.end.line,
|
|
347
|
+
callNode: member.value.body,
|
|
348
|
+
importNode: member,
|
|
349
|
+
static: isStatic,
|
|
350
|
+
async: member.value.async === true,
|
|
351
|
+
generator: member.value.generator === true,
|
|
352
|
+
language
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function extractClassFieldFunctionChunk(member, className, code, language) {
|
|
357
|
+
if (member.type !== "PropertyDefinition" && member.type !== "FieldDefinition") {
|
|
358
|
+
return null;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
const value = member.value;
|
|
362
|
+
const isFunctionField =
|
|
363
|
+
value?.type === "FunctionExpression" || value?.type === "ArrowFunctionExpression";
|
|
364
|
+
if (!isFunctionField) {
|
|
365
|
+
return null;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
const fieldName = getPropertyName(member.key, member.computed);
|
|
369
|
+
if (!fieldName) {
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const params = (value.params || []).map(formatParameterName);
|
|
374
|
+
const isStatic = member.static === true;
|
|
375
|
+
const prefix = isStatic ? "static " : "";
|
|
376
|
+
const bodyStart = findLeadingCommentStart(code, member);
|
|
377
|
+
|
|
378
|
+
return {
|
|
379
|
+
name: `${className}.${fieldName}`,
|
|
380
|
+
kind: "method",
|
|
381
|
+
signature: `${prefix}${fieldName}(${params.join(", ")})`,
|
|
382
|
+
body: code.slice(bodyStart, member.end),
|
|
383
|
+
startLine: member.loc.start.line,
|
|
384
|
+
endLine: member.loc.end.line,
|
|
385
|
+
callNode: value.body || value,
|
|
386
|
+
importNode: member,
|
|
387
|
+
static: isStatic,
|
|
388
|
+
async: value.async === true,
|
|
389
|
+
generator: value.generator === true,
|
|
390
|
+
field: true,
|
|
391
|
+
language
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
function extractTypeDeclarationChunk(node, kind, code) {
|
|
396
|
+
const name = node.id?.name;
|
|
397
|
+
if (!name) {
|
|
398
|
+
return null;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
const bodyStart = findLeadingCommentStart(code, node);
|
|
402
|
+
return {
|
|
403
|
+
name,
|
|
404
|
+
kind,
|
|
405
|
+
signature: `${kind} ${name}`,
|
|
406
|
+
body: code.slice(bodyStart, node.end),
|
|
407
|
+
startLine: node.loc.start.line,
|
|
408
|
+
endLine: node.loc.end.line,
|
|
409
|
+
callNode: node,
|
|
410
|
+
importNode: node
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
function getPropertyName(key, computed = false) {
|
|
415
|
+
if (!key) {
|
|
416
|
+
return null;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
if (!computed && key.type === "Identifier") {
|
|
420
|
+
return key.name;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (key.type === "Literal" && typeof key.value === "string") {
|
|
424
|
+
return key.value;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
return null;
|
|
428
|
+
}
|
|
429
|
+
|
|
323
430
|
function findLeadingCommentStart(code, node) {
|
|
324
431
|
let bodyStart = node.start;
|
|
325
432
|
let lineStart = code.lastIndexOf("\n", node.start - 1) + 1;
|
|
@@ -103,16 +103,17 @@ function extractReferencedStaticImportSources(bodyNode, bindings) {
|
|
|
103
103
|
fullAncestor(
|
|
104
104
|
bodyNode,
|
|
105
105
|
(node, state, ancestors) => {
|
|
106
|
-
|
|
106
|
+
const localName = getReferencedImportName(node, ancestors);
|
|
107
|
+
if (!localName) {
|
|
107
108
|
return;
|
|
108
109
|
}
|
|
109
110
|
|
|
110
|
-
const source = importsByLocalName.get(
|
|
111
|
-
if (!source
|
|
111
|
+
const source = importsByLocalName.get(localName);
|
|
112
|
+
if (!source) {
|
|
112
113
|
return;
|
|
113
114
|
}
|
|
114
115
|
|
|
115
|
-
if (resolveIdentifier(
|
|
116
|
+
if (resolveIdentifier(localName, ancestors, scopeGraph)) {
|
|
116
117
|
return;
|
|
117
118
|
}
|
|
118
119
|
|
|
@@ -127,6 +128,39 @@ function extractReferencedStaticImportSources(bodyNode, bindings) {
|
|
|
127
128
|
return [...sources].sort();
|
|
128
129
|
}
|
|
129
130
|
|
|
131
|
+
function getReferencedImportName(node, ancestors) {
|
|
132
|
+
if (node.type === "Identifier") {
|
|
133
|
+
return isReferenceIdentifier(node, ancestors) ? node.name : null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (node.type !== "JSXIdentifier" || isIntrinsicJsxName(node.name)) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const parent = ancestors[ancestors.length - 2] ?? null;
|
|
141
|
+
if (!parent) {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (parent.type === "JSXOpeningElement" && parent.name === node) {
|
|
146
|
+
return node.name;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (parent.type === "JSXMemberExpression" && parent.object === node) {
|
|
150
|
+
return node.name;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (parent.type === "JSXNamespacedName" && parent.namespace === node) {
|
|
154
|
+
return node.name;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function isIntrinsicJsxName(name) {
|
|
161
|
+
return /^[a-z]/.test(name);
|
|
162
|
+
}
|
|
163
|
+
|
|
130
164
|
function extractDynamicImports(bodyNode) {
|
|
131
165
|
if (!bodyNode) {
|
|
132
166
|
return [];
|
|
@@ -255,23 +255,59 @@ try {
|
|
|
255
255
|
return raw.split(/\r?\n/)[0].trim();
|
|
256
256
|
};
|
|
257
257
|
|
|
258
|
-
|
|
259
|
-
|
|
258
|
+
// The latest-version lookup is a network call; cache it for a day so
|
|
259
|
+
// repeated bootstraps/status checks stay fast and offline-friendly.
|
|
260
|
+
const fs = require("node:fs");
|
|
261
|
+
const versionCheckCache = path.join(cacheDir, "version-check.json");
|
|
262
|
+
const VERSION_CHECK_TTL_MS = 24 * 60 * 60 * 1000;
|
|
263
|
+
let latestVersion = null;
|
|
260
264
|
try {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
265
|
+
const cached = JSON.parse(fs.readFileSync(versionCheckCache, "utf8"));
|
|
266
|
+
const age = cached ? Date.now() - cached.checked_at : NaN;
|
|
267
|
+
if (
|
|
268
|
+
cached &&
|
|
269
|
+
typeof cached.latest === "string" &&
|
|
270
|
+
Number.isFinite(cached.checked_at) &&
|
|
271
|
+
age >= 0 &&
|
|
272
|
+
age < VERSION_CHECK_TTL_MS &&
|
|
273
|
+
parseVersion(cached.latest)
|
|
274
|
+
) {
|
|
275
|
+
latestVersion = cached.latest;
|
|
276
|
+
}
|
|
277
|
+
} catch {
|
|
278
|
+
// No usable cache; fall through to the live lookup.
|
|
271
279
|
}
|
|
272
280
|
|
|
273
|
-
|
|
274
|
-
|
|
281
|
+
if (!latestVersion) {
|
|
282
|
+
const npmCache = path.join(cacheDir, "npm-cache");
|
|
283
|
+
let latestRaw = "";
|
|
284
|
+
try {
|
|
285
|
+
latestRaw = execSync("npm view github:DanielBlomma/cortex version --json", {
|
|
286
|
+
cwd: repoRoot,
|
|
287
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
288
|
+
encoding: "utf8",
|
|
289
|
+
timeout: 2500,
|
|
290
|
+
env: { ...process.env, NPM_CONFIG_CACHE: npmCache }
|
|
291
|
+
}).trim();
|
|
292
|
+
} catch (error) {
|
|
293
|
+
console.log(`[status] cortex_update_check=unavailable (${summarizeError(error)})`);
|
|
294
|
+
process.exit(0);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const parsedLatest = JSON.parse(latestRaw);
|
|
298
|
+
latestVersion = Array.isArray(parsedLatest) ? parsedLatest[parsedLatest.length - 1] : parsedLatest;
|
|
299
|
+
if (parseVersion(latestVersion)) {
|
|
300
|
+
try {
|
|
301
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
302
|
+
fs.writeFileSync(
|
|
303
|
+
versionCheckCache,
|
|
304
|
+
JSON.stringify({ checked_at: Date.now(), latest: latestVersion })
|
|
305
|
+
);
|
|
306
|
+
} catch {
|
|
307
|
+
// Cache write failures must never break status reporting.
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
275
311
|
|
|
276
312
|
const localParsed = parseVersion(localVersion);
|
|
277
313
|
const latestParsed = parseVersion(latestVersion);
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "parsers",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"lockfileVersion": 3,
|
|
5
|
-
"requires": true,
|
|
6
|
-
"packages": {
|
|
7
|
-
"node_modules/acorn": {
|
|
8
|
-
"version": "8.16.0",
|
|
9
|
-
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
|
|
10
|
-
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
|
|
11
|
-
"license": "MIT",
|
|
12
|
-
"bin": {
|
|
13
|
-
"acorn": "bin/acorn"
|
|
14
|
-
},
|
|
15
|
-
"engines": {
|
|
16
|
-
"node": ">=0.4.0"
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
"node_modules/acorn-typescript": {
|
|
20
|
-
"version": "1.4.13",
|
|
21
|
-
"resolved": "https://registry.npmjs.org/acorn-typescript/-/acorn-typescript-1.4.13.tgz",
|
|
22
|
-
"integrity": "sha512-xsc9Xv0xlVfwp2o7sQ+GCQ1PgbkdcpWdTzrwXxO3xDMTAywVS3oXVOcOHuRjAPkS4P9b+yc/qNF15460v+jp4Q==",
|
|
23
|
-
"license": "MIT",
|
|
24
|
-
"peerDependencies": {
|
|
25
|
-
"acorn": ">=8.9.0"
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
"node_modules/acorn-walk": {
|
|
29
|
-
"version": "8.3.5",
|
|
30
|
-
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz",
|
|
31
|
-
"integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==",
|
|
32
|
-
"license": "MIT",
|
|
33
|
-
"dependencies": {
|
|
34
|
-
"acorn": "^8.11.0"
|
|
35
|
-
},
|
|
36
|
-
"engines": {
|
|
37
|
-
"node": ">=0.4.0"
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
"node_modules/tree-sitter-wasms": {
|
|
41
|
-
"version": "0.1.13",
|
|
42
|
-
"resolved": "https://registry.npmjs.org/tree-sitter-wasms/-/tree-sitter-wasms-0.1.13.tgz",
|
|
43
|
-
"integrity": "sha512-wT+cR6DwaIz80/vho3AvSF0N4txuNx/5bcRKoXouOfClpxh/qqrF4URNLQXbbt8MaAxeksZcZd1j8gcGjc+QxQ==",
|
|
44
|
-
"license": "Unlicense",
|
|
45
|
-
"dependencies": {
|
|
46
|
-
"tree-sitter-wasms": "^0.1.11"
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
"node_modules/web-tree-sitter": {
|
|
50
|
-
"version": "0.22.6",
|
|
51
|
-
"resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.22.6.tgz",
|
|
52
|
-
"integrity": "sha512-hS87TH71Zd6mGAmYCvlgxeGDjqd9GTeqXNqTT+u0Gs51uIozNIaaq/kUAbV/Zf56jb2ZOyG8BxZs2GG9wbLi6Q==",
|
|
53
|
-
"license": "MIT"
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|