@danielblomma/cortex-mcp 1.3.1 → 1.4.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 +62 -14
- package/package.json +2 -2
- package/scaffold/mcp/package-lock.json +3 -7
- package/scaffold/mcp/package.json +1 -1
- package/scaffold/scripts/dashboard.mjs +15 -1
- package/scaffold/scripts/doctor.sh +64 -10
- package/scaffold/scripts/ingest.mjs +323 -50
- package/scaffold/scripts/parsers/bash-treesitter.mjs +229 -0
- package/scaffold/scripts/parsers/cpp-dispatch.mjs +56 -0
- package/scaffold/scripts/parsers/cpp-treesitter.mjs +333 -0
- package/scaffold/scripts/parsers/csharp.mjs +197 -10
- package/scaffold/scripts/parsers/dotnet/CSharpParser/CSharpParser.csproj +1 -0
- package/scaffold/scripts/parsers/dotnet/CSharpParser/Program.cs +126 -21
- package/scaffold/scripts/parsers/go-treesitter.mjs +283 -0
- package/scaffold/scripts/parsers/java-treesitter.mjs +250 -0
- package/scaffold/scripts/parsers/javascript/ast.mjs +118 -12
- package/scaffold/scripts/parsers/javascript/chunks.mjs +4 -0
- package/scaffold/scripts/parsers/javascript/patterns.mjs +6 -0
- package/scaffold/scripts/parsers/javascript.mjs +4 -19
- package/scaffold/scripts/parsers/node_modules/.package-lock.json +57 -0
- package/scaffold/scripts/parsers/node_modules/acorn/CHANGELOG.md +972 -0
- package/scaffold/scripts/parsers/node_modules/acorn/LICENSE +21 -0
- package/scaffold/scripts/parsers/node_modules/acorn/README.md +301 -0
- package/scaffold/scripts/parsers/node_modules/acorn/bin/acorn +4 -0
- package/scaffold/scripts/parsers/node_modules/acorn/dist/acorn.d.mts +883 -0
- package/scaffold/scripts/parsers/node_modules/acorn/dist/acorn.d.ts +883 -0
- package/scaffold/scripts/parsers/node_modules/acorn/dist/acorn.js +6295 -0
- package/scaffold/scripts/parsers/node_modules/acorn/dist/acorn.mjs +6266 -0
- package/scaffold/scripts/parsers/node_modules/acorn/dist/bin.js +90 -0
- package/scaffold/scripts/parsers/node_modules/acorn/package.json +50 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/CHANGELOG.md +421 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/LICENSE +21 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/README.md +81 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/error.d.ts +103 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/error.js +78 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/error.js.map +1 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/decorators.d.ts +167 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/decorators.js +75 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/decorators.js.map +1 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/import-assertions.d.ts +177 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/import-assertions.js +56 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/import-assertions.js.map +1 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/jsx/index.d.ts +198 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/jsx/index.js +327 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/jsx/index.js.map +1 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/jsx/xhtml.d.ts +256 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/jsx/xhtml.js +256 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/extentions/jsx/xhtml.js.map +1 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/index.d.ts +472 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/index.js +1 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/index.js.map +1 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/index.mjs +1 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/middleware.d.ts +159 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/middleware.js +2 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/middleware.js.map +1 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/parseutil.d.ts +10 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/parseutil.js +38 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/parseutil.js.map +1 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/scopeflags.d.ts +12 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/scopeflags.js +29 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/scopeflags.js.map +1 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/tokenType.d.ts +2 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/tokenType.js +118 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/tokenType.js.map +1 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/types.d.ts +60 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/types.js +2 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/types.js.map +1 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/whitespace.d.ts +2 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/whitespace.js +19 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/lib/whitespace.js.map +1 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/package.json +53 -0
- package/scaffold/scripts/parsers/node_modules/acorn-typescript/tsconfig.json +19 -0
- package/scaffold/scripts/parsers/node_modules/acorn-walk/CHANGELOG.md +209 -0
- package/scaffold/scripts/parsers/node_modules/acorn-walk/LICENSE +21 -0
- package/scaffold/scripts/parsers/node_modules/acorn-walk/README.md +124 -0
- package/scaffold/scripts/parsers/node_modules/acorn-walk/dist/walk.d.mts +152 -0
- package/scaffold/scripts/parsers/node_modules/acorn-walk/dist/walk.d.ts +152 -0
- package/scaffold/scripts/parsers/node_modules/acorn-walk/dist/walk.js +485 -0
- package/scaffold/scripts/parsers/node_modules/acorn-walk/dist/walk.mjs +467 -0
- package/scaffold/scripts/parsers/node_modules/acorn-walk/package.json +50 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/LICENSE +24 -0
- package/scaffold/scripts/parsers/node_modules/tree-sitter-wasms/README.md +23 -0
- 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 +64 -0
- package/scaffold/scripts/parsers/node_modules/web-tree-sitter/LICENSE +21 -0
- package/scaffold/scripts/parsers/node_modules/web-tree-sitter/README.md +198 -0
- package/scaffold/scripts/parsers/node_modules/web-tree-sitter/package.json +37 -0
- package/scaffold/scripts/parsers/node_modules/web-tree-sitter/tree-sitter-web.d.ts +242 -0
- package/scaffold/scripts/parsers/node_modules/web-tree-sitter/tree-sitter.js +1 -0
- package/scaffold/scripts/parsers/node_modules/web-tree-sitter/tree-sitter.wasm +0 -0
- package/scaffold/scripts/parsers/package-lock.json +19 -1
- package/scaffold/scripts/parsers/package.json +3 -1
- package/scaffold/scripts/parsers/python-treesitter.mjs +271 -0
- package/scaffold/scripts/parsers/ruby-treesitter.mjs +271 -0
- package/scaffold/scripts/parsers/rust-dispatch.mjs +43 -0
- package/scaffold/scripts/parsers/rust-treesitter.mjs +291 -0
- package/scaffold/scripts/parsers/tree-sitter/base.mjs +163 -0
- package/scaffold/scripts/parsers/tree-sitter/queries/bash.calls.scm +7 -0
- package/scaffold/scripts/parsers/tree-sitter/queries/bash.chunks.scm +6 -0
- package/scaffold/scripts/parsers/tree-sitter/queries/bash.imports.scm +5 -0
- package/scaffold/scripts/parsers/tree-sitter/queries/cpp.calls.scm +17 -0
- package/scaffold/scripts/parsers/tree-sitter/queries/cpp.chunks.scm +30 -0
- package/scaffold/scripts/parsers/tree-sitter/queries/cpp.imports.scm +6 -0
- package/scaffold/scripts/parsers/tree-sitter/queries/go.calls.scm +11 -0
- package/scaffold/scripts/parsers/tree-sitter/queries/go.chunks.scm +19 -0
- package/scaffold/scripts/parsers/tree-sitter/queries/go.imports.scm +6 -0
- package/scaffold/scripts/parsers/tree-sitter/queries/java.calls.scm +6 -0
- package/scaffold/scripts/parsers/tree-sitter/queries/java.chunks.scm +23 -0
- package/scaffold/scripts/parsers/tree-sitter/queries/java.imports.scm +6 -0
- package/scaffold/scripts/parsers/tree-sitter/queries/python.calls.scm +11 -0
- package/scaffold/scripts/parsers/tree-sitter/queries/python.chunks.scm +11 -0
- package/scaffold/scripts/parsers/tree-sitter/queries/python.imports.scm +13 -0
- package/scaffold/scripts/parsers/tree-sitter/queries/ruby.calls.scm +6 -0
- package/scaffold/scripts/parsers/tree-sitter/queries/ruby.chunks.scm +16 -0
- package/scaffold/scripts/parsers/tree-sitter/queries/ruby.imports.scm +8 -0
- package/scaffold/scripts/parsers/tree-sitter/queries/rust.calls.scm +31 -0
- package/scaffold/scripts/parsers/tree-sitter/queries/rust.chunks.scm +29 -0
- package/scaffold/scripts/parsers/tree-sitter/queries/rust.imports.scm +5 -0
- package/scaffold/scripts/parsers/vb6.mjs +395 -0
package/README.md
CHANGED
|
@@ -2,30 +2,78 @@
|
|
|
2
2
|
<img src="docs/logo.png" alt="Cortex" width="600" />
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
# Cortex
|
|
5
|
+
# Cortex
|
|
6
|
+
|
|
7
|
+
**The context layer for AI-assisted software engineering.**
|
|
6
8
|
|
|
7
9
|
[](https://www.npmjs.com/package/@danielblomma/cortex-mcp)
|
|
8
10
|
[](https://www.npmjs.com/package/@danielblomma/cortex-mcp)
|
|
11
|
+
[](./LICENSE)
|
|
9
12
|
|
|
10
|
-
|
|
11
|
-
It indexes your codebase into structured entities (files, rules, ADRs) and exposes that context over MCP (JSON-RPC over stdio).
|
|
13
|
+
---
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
## What Cortex is
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
Cortex is a local, repository-scoped context engine for coding assistants. It parses your source code with tree-sitter, indexes it into a structured knowledge graph of entities (files, symbols, rules, ADRs) and their relationships (calls, defines, constrains, implements, supersedes), and serves that context to AI assistants over the Model Context Protocol (MCP).
|
|
16
18
|
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
Where a general-purpose AI assistant sees your codebase as a pile of text files, Cortex gives it a precise map: what exists, how it is connected, which rules govern it, and which parts are source-of-truth versus deprecated.
|
|
20
|
+
|
|
21
|
+
Cortex runs entirely on the developer's machine. Source code never leaves the host.
|
|
22
|
+
|
|
23
|
+
## When to use Cortex
|
|
24
|
+
|
|
25
|
+
Cortex is designed for engineering teams that rely on AI assistants for non-trivial work on real codebases. Use it when:
|
|
26
|
+
|
|
27
|
+
- Your codebase is large or fragmented enough that assistants waste context window on irrelevant files.
|
|
28
|
+
- You need assistants to respect architectural rules, deprecations, and source-of-truth decisions already made by the team.
|
|
29
|
+
- You work across multiple languages and want consistent, structured retrieval across all of them.
|
|
30
|
+
- Security or compliance requires that source code stay on-premise and that all AI interactions remain auditable.
|
|
31
|
+
- You want retrieval to surface *existing* functionality before an assistant proposes new code — reducing duplication and drift.
|
|
32
|
+
|
|
33
|
+
Cortex is not a replacement for your editor, your version control, or your coding assistant. It is the grounding layer that makes those assistants act with knowledge of your specific repository.
|
|
34
|
+
|
|
35
|
+
## Benefits
|
|
36
|
+
|
|
37
|
+
- **Higher-quality suggestions.** Assistants see the right files and rules instead of guessing from filenames.
|
|
38
|
+
- **Lower token cost.** Targeted retrieval replaces broad file reads. Typical sessions use a fraction of the context a raw assistant would consume.
|
|
39
|
+
- **Architectural governance.** Rules and ADRs are surfaced with every answer, so assistants follow the team's established patterns rather than generic best practices.
|
|
40
|
+
- **Multi-language coverage.** A single engine indexes multiple languages through tree-sitter grammars, giving polyglot teams consistent tooling.
|
|
41
|
+
- **Privacy by design.** Your code and its derived index stay on your machine. No upload, no cloud dependency for the core product.
|
|
42
|
+
- **Low friction.** One command (`cortex init --bootstrap`) scaffolds everything: indexing, git hooks, MCP registration for Claude Code, Claude Desktop, and Codex.
|
|
43
|
+
|
|
44
|
+
## How it works
|
|
45
|
+
|
|
46
|
+
Cortex operates as a five-stage pipeline between your repository and your AI assistant.
|
|
47
|
+
|
|
48
|
+
1. **Ingestion.** Source files are parsed with tree-sitter, producing structured entities (files, functions, classes, rules, ADRs) and relations (`CALLS`, `DEFINES`, `CONSTRAINS`, `IMPLEMENTS`, `IMPORTS`, `SUPERSEDES`).
|
|
49
|
+
2. **Storage.** Entities and relations are persisted to a local graph database (RyuGraph). An optional vector index provides semantic search across entity content.
|
|
50
|
+
3. **Retrieval.** MCP tools combine semantic search with graph traversal to assemble the smallest context package that answers the task.
|
|
51
|
+
4. **Policy.** Architectural rules and source-of-truth markers filter conflicting or deprecated content before it reaches the assistant.
|
|
52
|
+
5. **Assembly.** Results are delivered to the assistant as a compact, ranked context package over MCP.
|
|
53
|
+
|
|
54
|
+
Git hooks keep the index fresh on every checkout, pull, commit, and rewrite. A live TUI dashboard (`cortex dashboard`) shows what Cortex adds to the repository in real time.
|
|
55
|
+
|
|
56
|
+
## Why it works
|
|
57
|
+
|
|
58
|
+
Modern coding assistants are bottlenecked by context, not by model capability. Feeding a model more files rarely helps; feeding it the *right* files almost always does.
|
|
59
|
+
|
|
60
|
+
Cortex is built on one principle: **prefer retrieval quality over analysis completeness.** A smaller, sharper context package outperforms a broad dump of files. Every component — from tree-sitter parsing to graph traversal to rule filtering — exists to raise the signal-to-noise ratio of what the assistant sees.
|
|
61
|
+
|
|
62
|
+
The result is an assistant that behaves as if it already knows your codebase, because — through Cortex — it does.
|
|
63
|
+
|
|
64
|
+
## Quick demo
|
|
65
|
+
|
|
66
|
+

|
|
22
67
|
|
|
23
|
-
## Core
|
|
68
|
+
## Core capabilities
|
|
24
69
|
|
|
25
|
-
- Semantic search across
|
|
70
|
+
- Semantic search across code, rules, and ADRs.
|
|
26
71
|
- Graph relationships between entities and architectural constraints.
|
|
27
|
-
-
|
|
28
|
-
-
|
|
72
|
+
- Call-graph traversal, caller lookup, and impact analysis.
|
|
73
|
+
- Architectural rules and ADR enforcement at retrieval time.
|
|
74
|
+
- Incremental index updates driven by git hooks.
|
|
75
|
+
- Live TUI dashboard showing what Cortex adds to your repository.
|
|
76
|
+
- First-class integrations with Claude Code, Claude Desktop, and Codex.
|
|
29
77
|
|
|
30
78
|
## Requirements
|
|
31
79
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danielblomma/cortex-mcp",
|
|
3
3
|
"mcpName": "io.github.DanielBlomma/cortex",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.0",
|
|
5
5
|
"description": "Local, repo-scoped context platform for coding assistants. Semantic search, graph relationships, and architectural rule context.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"author": "Daniel Blomma",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"docs/MCP_MARKETPLACE.md"
|
|
47
47
|
],
|
|
48
48
|
"scripts": {
|
|
49
|
-
"test": "node tests/context-regressions.test.mjs && node --test tests/ingest-units.test.mjs tests/javascript-parser.test.mjs tests/sql-parser.test.mjs tests/config-parser.test.mjs tests/resources-parser.test.mjs tests/vbnet-parser.test.mjs tests/cpp-parser.test.mjs tests/multi-level.test.mjs",
|
|
49
|
+
"test": "node tests/context-regressions.test.mjs && node --test tests/ingest-units.test.mjs tests/javascript-parser.test.mjs tests/sql-parser.test.mjs tests/config-parser.test.mjs tests/resources-parser.test.mjs tests/vbnet-parser.test.mjs tests/cpp-parser.test.mjs tests/multi-level.test.mjs tests/no-legacy-paths.test.mjs",
|
|
50
50
|
"release:sync-version": "node scripts/sync-release-version.mjs",
|
|
51
51
|
"release:check-version-sync": "node scripts/sync-release-version.mjs --check",
|
|
52
52
|
"prepublishOnly": "echo 'Ready to publish to npm'"
|
|
@@ -236,7 +236,6 @@
|
|
|
236
236
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.13.tgz",
|
|
237
237
|
"integrity": "sha512-akNQMv0wW5uyRpD2v2IEyRSZiR+BeGuoB6L310EgGObO44HSMNT8z1xzio28V8qOrgYaopIDNA18YgdXd+qTiw==",
|
|
238
238
|
"license": "MIT",
|
|
239
|
-
"peer": true,
|
|
240
239
|
"dependencies": {
|
|
241
240
|
"undici-types": "~6.21.0"
|
|
242
241
|
}
|
|
@@ -1285,11 +1284,10 @@
|
|
|
1285
1284
|
}
|
|
1286
1285
|
},
|
|
1287
1286
|
"node_modules/hono": {
|
|
1288
|
-
"version": "4.12.
|
|
1289
|
-
"resolved": "https://registry.npmjs.org/hono/-/hono-4.12.
|
|
1290
|
-
"integrity": "sha512-
|
|
1287
|
+
"version": "4.12.14",
|
|
1288
|
+
"resolved": "https://registry.npmjs.org/hono/-/hono-4.12.14.tgz",
|
|
1289
|
+
"integrity": "sha512-am5zfg3yu6sqn5yjKBNqhnTX7Cv+m00ox+7jbaKkrLMRJ4rAdldd1xPd/JzbBWspqaQv6RSTrgFN95EsfhC+7w==",
|
|
1291
1290
|
"license": "MIT",
|
|
1292
|
-
"peer": true,
|
|
1293
1291
|
"engines": {
|
|
1294
1292
|
"node": ">=16.9.0"
|
|
1295
1293
|
}
|
|
@@ -2446,7 +2444,6 @@
|
|
|
2446
2444
|
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
|
2447
2445
|
"dev": true,
|
|
2448
2446
|
"license": "Apache-2.0",
|
|
2449
|
-
"peer": true,
|
|
2450
2447
|
"bin": {
|
|
2451
2448
|
"tsc": "bin/tsc",
|
|
2452
2449
|
"tsserver": "bin/tsserver"
|
|
@@ -2605,7 +2602,6 @@
|
|
|
2605
2602
|
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
|
|
2606
2603
|
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
|
|
2607
2604
|
"license": "MIT",
|
|
2608
|
-
"peer": true,
|
|
2609
2605
|
"funding": {
|
|
2610
2606
|
"url": "https://github.com/sponsors/colinhacks"
|
|
2611
2607
|
}
|
|
@@ -543,6 +543,19 @@ function emptyLine(width) {
|
|
|
543
543
|
return col("│", C.gray) + " ".repeat(width - 2) + col("│", C.gray);
|
|
544
544
|
}
|
|
545
545
|
|
|
546
|
+
// ── Edition detection ────────────────────────────────────────
|
|
547
|
+
import { createRequire } from "node:module";
|
|
548
|
+
const __require = createRequire(import.meta.url);
|
|
549
|
+
|
|
550
|
+
function detectEdition() {
|
|
551
|
+
try {
|
|
552
|
+
__require.resolve("@danielblomma/cortex-enterprise");
|
|
553
|
+
return "Enterprise";
|
|
554
|
+
} catch {
|
|
555
|
+
return "Community";
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
|
|
546
559
|
// ── Render sections ──────────────────────────────────────────
|
|
547
560
|
function render(data, isTTY) {
|
|
548
561
|
const termWidth = process.stdout.columns || 80;
|
|
@@ -551,7 +564,8 @@ function render(data, isTTY) {
|
|
|
551
564
|
|
|
552
565
|
// Header
|
|
553
566
|
const clock = new Date().toLocaleTimeString("sv-SE", { hour: "2-digit", minute: "2-digit" });
|
|
554
|
-
const
|
|
567
|
+
const edition = detectEdition();
|
|
568
|
+
const title = `─ cortex dashboard [${edition}] `;
|
|
555
569
|
const clockPart = ` ${clock} ─`;
|
|
556
570
|
const fillLen = w - 2 - title.length - clockPart.length;
|
|
557
571
|
lines.push(col(`┌${title}${"─".repeat(Math.max(0, fillLen))}${clockPart}┐`, C.gray));
|
|
@@ -221,19 +221,59 @@ if [[ -n "$ENTERPRISE_CONFIG" ]]; then
|
|
|
221
221
|
console.log(fields["policy.endpoint"] || "");
|
|
222
222
|
' "$ENTERPRISE_CONFIG" 2>/dev/null || echo "")
|
|
223
223
|
|
|
224
|
+
TELEMETRY_API_KEY=$(node -e '
|
|
225
|
+
const fs = require("node:fs");
|
|
226
|
+
const raw = fs.readFileSync(process.argv[1], "utf8");
|
|
227
|
+
let section = "", fields = {};
|
|
228
|
+
for (const line of raw.split("\n")) {
|
|
229
|
+
const t = line.trimEnd();
|
|
230
|
+
if (!t || t.startsWith("#")) continue;
|
|
231
|
+
const sm = t.match(/^(\w+):\s*$/);
|
|
232
|
+
if (sm) { section = sm[1]; continue; }
|
|
233
|
+
const kv = t.match(/^\s+(\w+):\s*(.+?)\s*$/);
|
|
234
|
+
if (kv && section) fields[section + "." + kv[1]] = kv[2].replace(/^["\x27]|["\x27]$/g, "");
|
|
235
|
+
}
|
|
236
|
+
console.log(fields["telemetry.api_key"] || "");
|
|
237
|
+
' "$ENTERPRISE_CONFIG" 2>/dev/null || echo "")
|
|
238
|
+
|
|
239
|
+
POLICY_API_KEY=$(node -e '
|
|
240
|
+
const fs = require("node:fs");
|
|
241
|
+
const raw = fs.readFileSync(process.argv[1], "utf8");
|
|
242
|
+
let section = "", fields = {};
|
|
243
|
+
for (const line of raw.split("\n")) {
|
|
244
|
+
const t = line.trimEnd();
|
|
245
|
+
if (!t || t.startsWith("#")) continue;
|
|
246
|
+
const sm = t.match(/^(\w+):\s*$/);
|
|
247
|
+
if (sm) { section = sm[1]; continue; }
|
|
248
|
+
const kv = t.match(/^\s+(\w+):\s*(.+?)\s*$/);
|
|
249
|
+
if (kv && section) fields[section + "." + kv[1]] = kv[2].replace(/^["\x27]|["\x27]$/g, "");
|
|
250
|
+
}
|
|
251
|
+
console.log(fields["policy.api_key"] || "");
|
|
252
|
+
' "$ENTERPRISE_CONFIG" 2>/dev/null || echo "")
|
|
253
|
+
|
|
224
254
|
# Telemetry
|
|
225
255
|
if [[ -n "$TELEMETRY_ENDPOINT" ]]; then
|
|
226
256
|
pass "Telemetry: endpoint configured"
|
|
227
|
-
|
|
228
|
-
-H "Content-Type: application/json"
|
|
229
|
-
|
|
230
|
-
|
|
257
|
+
TELEMETRY_CURL_ARGS=(-so /dev/null -w '%{http_code}' --max-time 5 -X POST \
|
|
258
|
+
-H "Content-Type: application/json" -d '{}')
|
|
259
|
+
if [[ -n "$TELEMETRY_API_KEY" ]]; then
|
|
260
|
+
TELEMETRY_CURL_ARGS+=(-H "Authorization: Bearer ${TELEMETRY_API_KEY}")
|
|
261
|
+
fi
|
|
262
|
+
HTTP_CODE=$(curl "${TELEMETRY_CURL_ARGS[@]}" "$TELEMETRY_ENDPOINT" 2>/dev/null | tail -c 3 || echo "000")
|
|
231
263
|
if [[ "$HTTP_CODE" == "000" ]]; then
|
|
232
264
|
fail "Telemetry: endpoint not reachable (timeout/DNS)"
|
|
233
265
|
elif [[ "$HTTP_CODE" =~ ^[23] ]]; then
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
266
|
+
if [[ -n "$TELEMETRY_API_KEY" ]]; then
|
|
267
|
+
pass "Telemetry: endpoint authenticated (HTTP ${HTTP_CODE})"
|
|
268
|
+
else
|
|
269
|
+
pass "Telemetry: endpoint reachable (HTTP ${HTTP_CODE})"
|
|
270
|
+
fi
|
|
271
|
+
elif [[ "$HTTP_CODE" == "401" || "$HTTP_CODE" == "403" ]]; then
|
|
272
|
+
if [[ -n "$TELEMETRY_API_KEY" ]]; then
|
|
273
|
+
fail "Telemetry: auth rejected (HTTP ${HTTP_CODE}) — check telemetry.api_key in enterprise.yaml"
|
|
274
|
+
else
|
|
275
|
+
pass "Telemetry: endpoint reachable (auth required — expected)"
|
|
276
|
+
fi
|
|
237
277
|
else
|
|
238
278
|
warn "Telemetry: endpoint returned HTTP ${HTTP_CODE}"
|
|
239
279
|
fi
|
|
@@ -258,11 +298,25 @@ if [[ -n "$ENTERPRISE_CONFIG" ]]; then
|
|
|
258
298
|
fi
|
|
259
299
|
|
|
260
300
|
if [[ -n "$POLICY_ENDPOINT" ]]; then
|
|
261
|
-
|
|
301
|
+
POLICY_CURL_ARGS=(-so /dev/null -w '%{http_code}' --max-time 5)
|
|
302
|
+
if [[ -n "$POLICY_API_KEY" ]]; then
|
|
303
|
+
POLICY_CURL_ARGS+=(-H "Authorization: Bearer ${POLICY_API_KEY}")
|
|
304
|
+
fi
|
|
305
|
+
POLICY_HTTP=$(curl "${POLICY_CURL_ARGS[@]}" "$POLICY_ENDPOINT" 2>/dev/null | tail -c 3 || echo "000")
|
|
262
306
|
if [[ "$POLICY_HTTP" == "000" ]]; then
|
|
263
307
|
fail "Policy: endpoint not reachable (timeout/DNS)"
|
|
264
|
-
elif [[ "$POLICY_HTTP" =~ ^[23] ]]
|
|
265
|
-
|
|
308
|
+
elif [[ "$POLICY_HTTP" =~ ^[23] ]]; then
|
|
309
|
+
if [[ -n "$POLICY_API_KEY" ]]; then
|
|
310
|
+
pass "Policy: endpoint authenticated (HTTP ${POLICY_HTTP})"
|
|
311
|
+
else
|
|
312
|
+
pass "Policy: endpoint reachable (HTTP ${POLICY_HTTP})"
|
|
313
|
+
fi
|
|
314
|
+
elif [[ "$POLICY_HTTP" == "401" || "$POLICY_HTTP" == "403" ]]; then
|
|
315
|
+
if [[ -n "$POLICY_API_KEY" ]]; then
|
|
316
|
+
fail "Policy: auth rejected (HTTP ${POLICY_HTTP}) — check policy.api_key in enterprise.yaml"
|
|
317
|
+
else
|
|
318
|
+
pass "Policy: endpoint reachable (auth required — expected)"
|
|
319
|
+
fi
|
|
266
320
|
else
|
|
267
321
|
warn "Policy: endpoint returned HTTP ${POLICY_HTTP}"
|
|
268
322
|
fi
|