@mohantn/gate-keeper 2.2.0 → 2.2.1
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 +82 -46
- package/package.json +1 -1
- package/dist/cli/query-repl.d.ts +0 -37
- package/dist/cli/query-repl.d.ts.map +0 -1
- package/dist/cli/query-repl.js +0 -298
- package/dist/cli/query-repl.js.map +0 -1
- package/dist/cli/repl-algorithms.d.ts +0 -49
- package/dist/cli/repl-algorithms.d.ts.map +0 -1
- package/dist/cli/repl-algorithms.js +0 -147
- package/dist/cli/repl-algorithms.js.map +0 -1
- package/dist/cli/setup-core.d.ts +0 -38
- package/dist/cli/setup-core.d.ts.map +0 -1
- package/dist/cli/setup-core.js +0 -427
- package/dist/cli/setup-core.js.map +0 -1
- package/dist/cli/setup.d.ts +0 -25
- package/dist/cli/setup.d.ts.map +0 -1
- package/dist/cli/setup.js +0 -159
- package/dist/cli/setup.js.map +0 -1
- package/dist/github/app.d.ts +0 -34
- package/dist/github/app.d.ts.map +0 -1
- package/dist/github/app.js +0 -261
- package/dist/github/app.js.map +0 -1
- package/dist/github/commenter.d.ts +0 -67
- package/dist/github/commenter.d.ts.map +0 -1
- package/dist/github/commenter.js +0 -155
- package/dist/github/commenter.js.map +0 -1
- package/dist/hooks/git-hooks.d.ts +0 -30
- package/dist/hooks/git-hooks.d.ts.map +0 -1
- package/dist/hooks/git-hooks.js +0 -179
- package/dist/hooks/git-hooks.js.map +0 -1
- package/dist/mcp/cache-preload.d.ts +0 -29
- package/dist/mcp/cache-preload.d.ts.map +0 -1
- package/dist/mcp/cache-preload.js +0 -103
- package/dist/mcp/cache-preload.js.map +0 -1
- package/dist/mcp/handlers/context.d.ts +0 -25
- package/dist/mcp/handlers/context.d.ts.map +0 -1
- package/dist/mcp/handlers/context.js +0 -382
- package/dist/mcp/handlers/context.js.map +0 -1
- package/dist/mcp/handlers/graph-intelligence.d.ts +0 -26
- package/dist/mcp/handlers/graph-intelligence.d.ts.map +0 -1
- package/dist/mcp/handlers/graph-intelligence.js +0 -371
- package/dist/mcp/handlers/graph-intelligence.js.map +0 -1
- package/dist/mcp/handlers/graph-query.d.ts +0 -25
- package/dist/mcp/handlers/graph-query.d.ts.map +0 -1
- package/dist/mcp/handlers/graph-query.js +0 -410
- package/dist/mcp/handlers/graph-query.js.map +0 -1
- package/dist/mcp/handlers/impact.d.ts +0 -4
- package/dist/mcp/handlers/impact.d.ts.map +0 -1
- package/dist/mcp/handlers/impact.js +0 -139
- package/dist/mcp/handlers/impact.js.map +0 -1
- package/dist/mcp/handlers/improvement.d.ts +0 -4
- package/dist/mcp/handlers/improvement.d.ts.map +0 -1
- package/dist/mcp/handlers/improvement.js +0 -136
- package/dist/mcp/handlers/improvement.js.map +0 -1
- package/dist/mcp/handlers/platform-installer.d.ts +0 -10
- package/dist/mcp/handlers/platform-installer.d.ts.map +0 -1
- package/dist/mcp/handlers/platform-installer.js +0 -168
- package/dist/mcp/handlers/platform-installer.js.map +0 -1
- package/dist/mcp/handlers/pr-review.d.ts +0 -33
- package/dist/mcp/handlers/pr-review.d.ts.map +0 -1
- package/dist/mcp/handlers/pr-review.js +0 -170
- package/dist/mcp/handlers/pr-review.js.map +0 -1
- package/dist/mcp/token-tracker.d.ts +0 -47
- package/dist/mcp/token-tracker.d.ts.map +0 -1
- package/dist/mcp/token-tracker.js +0 -93
- package/dist/mcp/token-tracker.js.map +0 -1
- package/dist/quality-loop/file-lock.d.ts +0 -12
- package/dist/quality-loop/file-lock.d.ts.map +0 -1
- package/dist/quality-loop/file-lock.js +0 -38
- package/dist/quality-loop/file-lock.js.map +0 -1
- package/dist/quality-loop/fix-worker.d.ts +0 -44
- package/dist/quality-loop/fix-worker.d.ts.map +0 -1
- package/dist/quality-loop/fix-worker.js +0 -414
- package/dist/quality-loop/fix-worker.js.map +0 -1
- package/dist/quality-loop/orchestrator.d.ts +0 -137
- package/dist/quality-loop/orchestrator.d.ts.map +0 -1
- package/dist/quality-loop/orchestrator.js +0 -894
- package/dist/quality-loop/orchestrator.js.map +0 -1
- package/dist/quality-loop/queue-manager.d.ts +0 -45
- package/dist/quality-loop/queue-manager.d.ts.map +0 -1
- package/dist/quality-loop/queue-manager.js +0 -173
- package/dist/quality-loop/queue-manager.js.map +0 -1
package/README.md
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
<img src="https://img.shields.io/badge/node-%3E%3D18-brightgreen.svg" alt="Node >= 18">
|
|
4
4
|
<img src="https://img.shields.io/badge/TypeScript-5.0+-3178C6.svg" alt="TypeScript">
|
|
5
5
|
<img src="https://img.shields.io/badge/MCP-5_tools-6C47FF.svg" alt="MCP">
|
|
6
|
+
<img src="https://img.shields.io/npm/v/%40mohantn%2Fgate-keeper?color=red" alt="npm">
|
|
6
7
|
</p>
|
|
7
8
|
|
|
8
9
|
<h1 align="center">⬡ Gate Keeper</h1>
|
|
@@ -14,35 +15,44 @@
|
|
|
14
15
|
|
|
15
16
|
Gate Keeper analyzes every file your AI agent writes — TypeScript Compiler API for TS/JS/JSX, Roslyn (or text fallback) for C# — rates it 0–10, and publishes the result to a live dependency graph. Agents see the graph through a 5-tool MCP server; humans see it at `http://localhost:5378/viz`.
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
- **
|
|
20
|
-
- **GitHub Copilot / VS Code** — `.github/instructions/gate-keeper.instructions.md` is auto-injected on every file edit.
|
|
18
|
+
Two integration points:
|
|
19
|
+
- **Claude Code** — Pre/PostToolUse hooks that block low-quality or high-risk edits
|
|
20
|
+
- **GitHub Copilot / VS Code** — `.github/instructions/gate-keeper.instructions.md` + `.vscode/mcp.json` + `.vscode/tasks.json`
|
|
21
21
|
|
|
22
22
|
---
|
|
23
23
|
|
|
24
|
-
##
|
|
24
|
+
## Install
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
|
|
27
|
+
npm install -g @mohantn/gate-keeper
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
This installs the `gate-keeper` and `gk` CLI commands.
|
|
31
|
+
|
|
32
|
+
---
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
## Quick Start
|
|
33
35
|
|
|
34
36
|
```bash
|
|
35
|
-
|
|
36
|
-
npm run daemon # start daemon (ports 5378 / 5379)
|
|
37
|
-
npm run mcp # start MCP server (stdio)
|
|
38
|
-
npm test # run tests
|
|
37
|
+
gate-keeper setup
|
|
39
38
|
```
|
|
40
39
|
|
|
40
|
+
This installs dependencies, builds, starts the daemon, and configures Claude Code hooks. Open **http://localhost:5378/viz** for the live dashboard.
|
|
41
|
+
|
|
42
|
+
To run individual components:
|
|
43
|
+
|
|
44
|
+
| Command | Description |
|
|
45
|
+
|---------|-------------|
|
|
46
|
+
| `gate-keeper daemon` | Start the daemon (ports 5378 / 5379) |
|
|
47
|
+
| `gate-keeper mcp` | Start the MCP server (stdio) |
|
|
48
|
+
| `gate-keeper dashboard` | Open the dashboard in browser |
|
|
49
|
+
| `gate-keeper status` | Check daemon health |
|
|
50
|
+
|
|
41
51
|
---
|
|
42
52
|
|
|
43
|
-
## Claude Code
|
|
53
|
+
## Claude Code Integration
|
|
44
54
|
|
|
45
|
-
|
|
55
|
+
Gate Keeper uses two hooks in `~/.claude/settings.json`:
|
|
46
56
|
|
|
47
57
|
```json
|
|
48
58
|
{
|
|
@@ -50,29 +60,62 @@ Add these two hooks to `~/.claude/settings.json` (replace `/abs/path/to/gate-kee
|
|
|
50
60
|
"PreToolUse": [
|
|
51
61
|
{
|
|
52
62
|
"matcher": "Write|Edit|MultiEdit",
|
|
53
|
-
"hooks": [{ "type": "command", "command": "node /
|
|
63
|
+
"hooks": [{ "type": "command", "command": "node /path/to/gate-keeper/dist/hook-pre-tool-use.js" }]
|
|
54
64
|
}
|
|
55
65
|
],
|
|
56
66
|
"PostToolUse": [
|
|
57
67
|
{
|
|
58
68
|
"matcher": "Write|Edit|MultiEdit",
|
|
59
|
-
"hooks": [{ "type": "command", "command": "node /
|
|
69
|
+
"hooks": [{ "type": "command", "command": "node /path/to/gate-keeper/dist/hook-receiver.js" }]
|
|
60
70
|
}
|
|
61
71
|
]
|
|
62
72
|
}
|
|
63
73
|
}
|
|
64
74
|
```
|
|
65
75
|
|
|
66
|
-
|
|
67
|
-
- **PostToolUse** — analyzes the written file and blocks (exit 2) when the rating falls below `minRating` (default 6.5, configurable in `~/.gate-keeper/config.json`).
|
|
76
|
+
**PreToolUse** — before every Write/Edit, the daemon checks the impact set (BFS over reverse dependencies). If editing the file would break 3+ fragile dependents, a warning is printed and the agent is advised to proceed with care.
|
|
68
77
|
|
|
69
|
-
|
|
78
|
+
**PostToolUse** — after every Write/Edit, the hook-receiver analyzes the written file using the TypeScript Compiler API (AST-level, not regex). If the quality rating falls below the configured minimum (default 7.0/10), the hook exits with code 2, blocking the edit and surfacing violations inline. The agent self-corrects and retries, creating a tight quality feedback loop.
|
|
79
|
+
|
|
80
|
+
**Session start** — on `SessionStart` and `UserPromptSubmit`, the hook-receiver automatically registers the repository with the daemon. Claude agents should call `get_quality_rules` and `get_file_context` before editing files to understand the dependency landscape.
|
|
81
|
+
|
|
82
|
+
### Agent workflow inside Claude
|
|
83
|
+
|
|
84
|
+
At session start:
|
|
85
|
+
```
|
|
86
|
+
get_quality_rules ← Learn scoring thresholds and minimum rating
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Before editing any file:
|
|
90
|
+
```
|
|
91
|
+
get_file_context <file_path> ← Get rating, imports, importers, cycles, trend
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
After bulk changes (3+ files):
|
|
95
|
+
```
|
|
96
|
+
get_codebase_health ← Verify overall project quality hasn't degraded
|
|
97
|
+
```
|
|
70
98
|
|
|
71
99
|
---
|
|
72
100
|
|
|
73
|
-
## GitHub Copilot / VS Code
|
|
101
|
+
## GitHub Copilot / VS Code Integration
|
|
102
|
+
|
|
103
|
+
### 1. Repository registration (`tasks.json`)
|
|
104
|
+
|
|
105
|
+
`.vscode/tasks.json` ships in the repo with a task that runs on folder open. It calls `hook-receiver.js` with a `session_create` event to register the repo with the daemon. Copilot instructions handle all subsequent interaction.
|
|
106
|
+
|
|
107
|
+
No manual action needed — the task fires automatically when the workspace opens.
|
|
108
|
+
|
|
109
|
+
### 2. Agent instructions
|
|
110
|
+
|
|
111
|
+
`.github/instructions/gate-keeper.instructions.md` ships in the repo with `applyTo: "**/*.{ts,tsx,jsx,js,cs}"`. Copilot auto-loads it on every matching edit. The instructions tell the agent to:
|
|
74
112
|
|
|
75
|
-
|
|
113
|
+
- Call `get_quality_rules` at session start
|
|
114
|
+
- Call `get_file_context` before editing any file
|
|
115
|
+
- Call `get_codebase_health` after bulk changes
|
|
116
|
+
- Follow the quality thresholds
|
|
117
|
+
|
|
118
|
+
### 3. MCP server
|
|
76
119
|
|
|
77
120
|
To let VS Code discover the MCP server, add `.vscode/mcp.json`:
|
|
78
121
|
|
|
@@ -81,39 +124,35 @@ To let VS Code discover the MCP server, add `.vscode/mcp.json`:
|
|
|
81
124
|
"servers": {
|
|
82
125
|
"gate-keeper": {
|
|
83
126
|
"command": "node",
|
|
84
|
-
"args": ["/
|
|
127
|
+
"args": ["${workspaceFolder}/dist/mcp/server.js"]
|
|
85
128
|
}
|
|
86
129
|
}
|
|
87
130
|
}
|
|
88
131
|
```
|
|
89
132
|
|
|
133
|
+
This ships with the repo — no manual setup needed for existing clones.
|
|
134
|
+
|
|
90
135
|
---
|
|
91
136
|
|
|
92
|
-
## MCP
|
|
137
|
+
## MCP Tools (5)
|
|
93
138
|
|
|
94
139
|
| Tool | Purpose |
|
|
95
140
|
|------|---------|
|
|
96
141
|
| `get_quality_rules` | Scoring thresholds, deductions, minimum rating. Call once per session. |
|
|
97
142
|
| `get_file_context` | Single-file dossier: rating, imports, importers, cycles, trend, git diff. |
|
|
98
|
-
| `get_dependency_graph` | Full repo graph in compact LLM-optimized format
|
|
99
|
-
| `get_graph_summary` | Pre-computed analytics: rating distribution, hotspots
|
|
143
|
+
| `get_dependency_graph` | Full repo graph in compact LLM-optimized format. |
|
|
144
|
+
| `get_graph_summary` | Pre-computed analytics: rating distribution, hotspots, worst files, module coupling. |
|
|
100
145
|
| `get_codebase_health` | Avg rating, distribution, worst files, common violations, fix order. |
|
|
101
146
|
|
|
102
|
-
Test it manually:
|
|
103
|
-
|
|
104
|
-
```bash
|
|
105
|
-
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | node dist/mcp/server.js
|
|
106
|
-
```
|
|
107
|
-
|
|
108
147
|
---
|
|
109
148
|
|
|
110
|
-
## Quality
|
|
149
|
+
## Quality System
|
|
111
150
|
|
|
112
|
-
Each file rated 0–10 (10 minus deductions)
|
|
151
|
+
Each file rated 0–10 (10 minus deductions):
|
|
113
152
|
|
|
114
|
-
| Deduction |
|
|
115
|
-
|
|
116
|
-
| −1.5 / error |
|
|
153
|
+
| Deduction | Trigger |
|
|
154
|
+
|-----------|---------|
|
|
155
|
+
| −1.5 / error | Missing `key`, empty catch |
|
|
117
156
|
| −0.5 / warning | `any`, god class, long method, tight coupling |
|
|
118
157
|
| −0.1 / info | `console.log`, magic number |
|
|
119
158
|
| −2.0 / −1.0 | Cyclomatic complexity > 20 / > 10 |
|
|
@@ -122,9 +161,7 @@ Each file rated 0–10 (10 minus deductions). Defaults:
|
|
|
122
161
|
| −1.0 / cycle | Circular dependency |
|
|
123
162
|
| −2.5 / −2.0 / −1.0 | Test coverage < 30% / < 50% / < 80% |
|
|
124
163
|
|
|
125
|
-
**Minimum passing rating: 7.0** (
|
|
126
|
-
|
|
127
|
-
Override threshold in `~/.gate-keeper/config.json`.
|
|
164
|
+
**Minimum passing rating: 7.0/10** (configurable in `~/.gate-keeper/config.json`).
|
|
128
165
|
|
|
129
166
|
---
|
|
130
167
|
|
|
@@ -133,8 +170,7 @@ Override threshold in `~/.gate-keeper/config.json`.
|
|
|
133
170
|
```
|
|
134
171
|
Claude Code VS Code / Copilot
|
|
135
172
|
│ │
|
|
136
|
-
│ PreToolUse
|
|
137
|
-
│ PostToolUse → hook-receiver.js │ .github/instructions/*
|
|
173
|
+
│ Hooks (PreToolUse / PostToolUse) │ MCP + instructions
|
|
138
174
|
▼ ▼
|
|
139
175
|
┌──────────────────────────────────────────────────┐
|
|
140
176
|
│ daemon (ports 5378 / 5379) │
|
|
@@ -154,24 +190,24 @@ Claude Code VS Code / Copilot
|
|
|
154
190
|
| Path | Purpose |
|
|
155
191
|
|------|---------|
|
|
156
192
|
| `src/hook-pre-tool-use.ts` | PreToolUse hook — blocks risky edits, exit 2 |
|
|
157
|
-
| `src/hook-receiver.ts` | PostToolUse / SessionStart
|
|
193
|
+
| `src/hook-receiver.ts` | PostToolUse / SessionStart / session_create handler — < 100 ms |
|
|
158
194
|
| `src/daemon.ts` | Long-lived daemon, ports 5378 / 5379 |
|
|
159
195
|
| `src/analyzer/` | TS Compiler API + C# analyzers |
|
|
160
|
-
| `src/rating/rating-calculator.ts` | 0–10 scoring |
|
|
161
|
-
| `src/graph/` | Dependency graph,
|
|
196
|
+
| `src/rating/rating-calculator.ts` | 0–10 scoring engine |
|
|
197
|
+
| `src/graph/` | Dependency graph, BFS impact sets, centrality, cycle detection |
|
|
162
198
|
| `src/mcp/server.ts` | 5-tool MCP server (stdio) |
|
|
163
199
|
| `src/viz/` | Dashboard server + HTML visualizer |
|
|
164
200
|
|
|
165
201
|
---
|
|
166
202
|
|
|
167
|
-
## Ports &
|
|
203
|
+
## Ports & Files
|
|
168
204
|
|
|
169
205
|
| Resource | Purpose |
|
|
170
206
|
|----------|---------|
|
|
171
207
|
| `:5378` | Dashboard HTTP + WebSocket |
|
|
172
208
|
| `:5379` | Daemon IPC (localhost only) |
|
|
173
209
|
| `~/.gate-keeper/cache.db` | SQLite — analyses, rating history, repos |
|
|
174
|
-
| `~/.gate-keeper/config.json` | `minRating` threshold (default
|
|
210
|
+
| `~/.gate-keeper/config.json` | `minRating` threshold (default 7.0) |
|
|
175
211
|
| `~/.gate-keeper/daemon.pid` | PID file |
|
|
176
212
|
|
|
177
213
|
---
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mohantn/gate-keeper",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "Real-time code quality gates & dependency graph for AI-assisted development. MCP server for Claude Code, GitHub Copilot, and any MCP-compatible agent.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
package/dist/cli/query-repl.d.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* --query interactive REPL mode
|
|
4
|
-
*
|
|
5
|
-
* Starts a readline loop accepting natural language queries against the loaded
|
|
6
|
-
* dependency graph.
|
|
7
|
-
*
|
|
8
|
-
* Usage:
|
|
9
|
-
* npx tsx src/cli/query-repl.ts [--repo /path/to/repo]
|
|
10
|
-
*
|
|
11
|
-
* Queries are dispatched through the same deterministic pattern matcher used by
|
|
12
|
-
* the MCP `query_graph` tool — no LLM involved, purely graph-algorithm answers.
|
|
13
|
-
*
|
|
14
|
-
* Commands:
|
|
15
|
-
* query text — ask about the graph (god nodes, surprising connections, etc.)
|
|
16
|
-
* explain path — get detailed explanation of a file
|
|
17
|
-
* path src dst — shortest dependency path between two files
|
|
18
|
-
* help — show available query patterns
|
|
19
|
-
* quit / exit — leave the REPL
|
|
20
|
-
*/
|
|
21
|
-
import { ReplGraph } from './repl-algorithms';
|
|
22
|
-
type GraphData = ReplGraph;
|
|
23
|
-
export declare const QUERY_PATTERNS: Array<{
|
|
24
|
-
name: string;
|
|
25
|
-
desc: string;
|
|
26
|
-
match: RegExp;
|
|
27
|
-
handler: (m: RegExpExecArray, graph: GraphData, repo: string) => string;
|
|
28
|
-
}>;
|
|
29
|
-
export declare function handleExplain(target: string, graph: GraphData, repo: string): void;
|
|
30
|
-
export declare function handlePath(parts: string[], graph: GraphData, repo: string): void;
|
|
31
|
-
/**
|
|
32
|
-
* Exported for use by the daemon's --query mode.
|
|
33
|
-
* Loads the graph from the running daemon, then starts the REPL.
|
|
34
|
-
*/
|
|
35
|
-
export declare function startRepl(repo: string): Promise<void>;
|
|
36
|
-
export {};
|
|
37
|
-
//# sourceMappingURL=query-repl.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"query-repl.d.ts","sourceRoot":"","sources":["../../src/cli/query-repl.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;GAkBG;AAMH,OAAO,EACL,SAAS,EAEV,MAAM,mBAAmB,CAAC;AA4B3B,KAAK,SAAS,GAAG,SAAS,CAAC;AAI3B,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAC1C,OAAO,EAAE,CAAC,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACzE,CA+CA,CAAC;AAeF,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAmBlF;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAuBhF;AA0FD;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG3D"}
|
package/dist/cli/query-repl.js
DELETED
|
@@ -1,298 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
/**
|
|
4
|
-
* --query interactive REPL mode
|
|
5
|
-
*
|
|
6
|
-
* Starts a readline loop accepting natural language queries against the loaded
|
|
7
|
-
* dependency graph.
|
|
8
|
-
*
|
|
9
|
-
* Usage:
|
|
10
|
-
* npx tsx src/cli/query-repl.ts [--repo /path/to/repo]
|
|
11
|
-
*
|
|
12
|
-
* Queries are dispatched through the same deterministic pattern matcher used by
|
|
13
|
-
* the MCP `query_graph` tool — no LLM involved, purely graph-algorithm answers.
|
|
14
|
-
*
|
|
15
|
-
* Commands:
|
|
16
|
-
* query text — ask about the graph (god nodes, surprising connections, etc.)
|
|
17
|
-
* explain path — get detailed explanation of a file
|
|
18
|
-
* path src dst — shortest dependency path between two files
|
|
19
|
-
* help — show available query patterns
|
|
20
|
-
* quit / exit — leave the REPL
|
|
21
|
-
*/
|
|
22
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
23
|
-
if (k2 === undefined) k2 = k;
|
|
24
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
25
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
26
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
27
|
-
}
|
|
28
|
-
Object.defineProperty(o, k2, desc);
|
|
29
|
-
}) : (function(o, m, k, k2) {
|
|
30
|
-
if (k2 === undefined) k2 = k;
|
|
31
|
-
o[k2] = m[k];
|
|
32
|
-
}));
|
|
33
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
34
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
35
|
-
}) : function(o, v) {
|
|
36
|
-
o["default"] = v;
|
|
37
|
-
});
|
|
38
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
39
|
-
var ownKeys = function(o) {
|
|
40
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
41
|
-
var ar = [];
|
|
42
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
43
|
-
return ar;
|
|
44
|
-
};
|
|
45
|
-
return ownKeys(o);
|
|
46
|
-
};
|
|
47
|
-
return function (mod) {
|
|
48
|
-
if (mod && mod.__esModule) return mod;
|
|
49
|
-
var result = {};
|
|
50
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
51
|
-
__setModuleDefault(result, mod);
|
|
52
|
-
return result;
|
|
53
|
-
};
|
|
54
|
-
})();
|
|
55
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
56
|
-
exports.QUERY_PATTERNS = void 0;
|
|
57
|
-
exports.handleExplain = handleExplain;
|
|
58
|
-
exports.handlePath = handlePath;
|
|
59
|
-
exports.startRepl = startRepl;
|
|
60
|
-
const http = __importStar(require("http"));
|
|
61
|
-
const path = __importStar(require("path"));
|
|
62
|
-
const readline = __importStar(require("readline"));
|
|
63
|
-
const child_process_1 = require("child_process");
|
|
64
|
-
const repl_algorithms_1 = require("./repl-algorithms");
|
|
65
|
-
const DAEMON_PORT = 5378;
|
|
66
|
-
// ── Helpers ────────────────────────────────────────────────
|
|
67
|
-
function fetchApi(urlPath) {
|
|
68
|
-
return new Promise((resolve) => {
|
|
69
|
-
const req = http.get(`http://127.0.0.1:${DAEMON_PORT}${urlPath}`, { timeout: 5000 }, (res) => {
|
|
70
|
-
let body = '';
|
|
71
|
-
res.on('data', (chunk) => { body += chunk; });
|
|
72
|
-
res.on('end', () => {
|
|
73
|
-
try {
|
|
74
|
-
resolve(JSON.parse(body));
|
|
75
|
-
}
|
|
76
|
-
catch {
|
|
77
|
-
resolve(null);
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
req.on('error', () => resolve(null));
|
|
82
|
-
req.on('timeout', () => { req.destroy(); resolve(null); });
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
function findGitRoot(dir) {
|
|
86
|
-
const result = (0, child_process_1.spawnSync)('git', ['rev-parse', '--show-toplevel'], {
|
|
87
|
-
cwd: dir, encoding: 'utf8', timeout: 3000,
|
|
88
|
-
});
|
|
89
|
-
return result.status === 0 && result.stdout.trim() ? result.stdout.trim() : dir;
|
|
90
|
-
}
|
|
91
|
-
// ── REPL query patterns ────────────────────────────────────
|
|
92
|
-
exports.QUERY_PATTERNS = [
|
|
93
|
-
{
|
|
94
|
-
name: 'god nodes',
|
|
95
|
-
desc: 'most-connected files (highest blast radius)',
|
|
96
|
-
match: /god|hotspot|central|blast|connected/i,
|
|
97
|
-
handler: (_, graph, repo) => {
|
|
98
|
-
const ranked = (0, repl_algorithms_1.computeDegreeCentrality)(graph).slice(0, 8);
|
|
99
|
-
return ranked.length === 0 ? 'No files in graph.' :
|
|
100
|
-
ranked.map((n, i) => `${i + 1}. ${path.relative(repo, n.path)} — ${n.totalDegree} connections, rating ${n.rating}/10`).join('\n');
|
|
101
|
-
},
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
name: 'surprising',
|
|
105
|
-
desc: 'cross-module dependencies',
|
|
106
|
-
match: /surprising|unexpected|cross|strange/i,
|
|
107
|
-
handler: (_, graph, repo) => {
|
|
108
|
-
const s = (0, repl_algorithms_1.findSurprising)(graph, repo, 5);
|
|
109
|
-
if (s.length === 0)
|
|
110
|
-
return 'No surprising cross-module connections found.';
|
|
111
|
-
return s.map((c, i) => `${i + 1}. ${path.relative(repo, c.src)} → ${path.relative(repo, c.dst)} (${c.S} → ${c.T})`).join('\n');
|
|
112
|
-
},
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
name: 'questions / suggestions',
|
|
116
|
-
desc: 'auto-generated questions about the codebase',
|
|
117
|
-
match: /question|suggest|recommend/i,
|
|
118
|
-
handler: (_, graph, repo) => {
|
|
119
|
-
const qs = (0, repl_algorithms_1.suggestQuestions)(graph, repo);
|
|
120
|
-
return qs.map((q, i) => `${i + 1}. ${q}`).join('\n');
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
name: 'health / quality',
|
|
125
|
-
desc: 'worst-rated files and overall quality',
|
|
126
|
-
match: /health|quality|worst|bad|poor|rating/i,
|
|
127
|
-
handler: (_, graph) => {
|
|
128
|
-
if (graph.nodes.length === 0)
|
|
129
|
-
return 'No files in graph.';
|
|
130
|
-
const avg = graph.nodes.reduce((s, n) => s + n.rating, 0) / graph.nodes.length;
|
|
131
|
-
const worst = [...graph.nodes].sort((a, b) => a.rating - b.rating).slice(0, 5);
|
|
132
|
-
const lines = [`Overall: ${graph.nodes.length} files, avg rating ${avg.toFixed(1)}/10`];
|
|
133
|
-
for (const n of worst) {
|
|
134
|
-
const errors = n.violations.filter(v => v.severity === 'error').length;
|
|
135
|
-
const warnings = n.violations.filter(v => v.severity === 'warning').length;
|
|
136
|
-
lines.push(` ${n.rating}/10 — ${n.label} (${errors} errors, ${warnings} warnings)`);
|
|
137
|
-
}
|
|
138
|
-
return lines.join('\n');
|
|
139
|
-
},
|
|
140
|
-
},
|
|
141
|
-
];
|
|
142
|
-
// ── REPL command helpers ───────────────────────────────────
|
|
143
|
-
function printHelp() {
|
|
144
|
-
process.stdout.write('\n Natural language queries:\n');
|
|
145
|
-
for (const p of exports.QUERY_PATTERNS)
|
|
146
|
-
process.stdout.write(` ${p.desc}\n`);
|
|
147
|
-
process.stdout.write(' Commands:\n');
|
|
148
|
-
process.stdout.write(' explain <file> — detailed file explanation\n');
|
|
149
|
-
process.stdout.write(' path <a> <b> — shortest dependency path\n');
|
|
150
|
-
process.stdout.write(' refresh — reload the graph from the daemon\n');
|
|
151
|
-
process.stdout.write(' help — this message\n');
|
|
152
|
-
process.stdout.write(' quit / exit — leave the REPL\n\n');
|
|
153
|
-
}
|
|
154
|
-
function handleExplain(target, graph, repo) {
|
|
155
|
-
if (!target) {
|
|
156
|
-
process.stdout.write('No file specified.\n');
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
const match = graph.nodes.find(n => n.id.toLowerCase().includes(target.toLowerCase()) ||
|
|
160
|
-
n.label.toLowerCase().includes(target.toLowerCase()));
|
|
161
|
-
if (!match) {
|
|
162
|
-
process.stdout.write(`No file matching "${target}" found in graph.\n`);
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
const rel = path.relative(repo, match.id);
|
|
166
|
-
const errors = match.violations.filter(v => v.severity === 'error').length;
|
|
167
|
-
const warnings = match.violations.filter(v => v.severity === 'warning').length;
|
|
168
|
-
process.stdout.write(`\n ${rel}\n`);
|
|
169
|
-
process.stdout.write(` Rating: ${match.rating}/10 | LOC: ${match.metrics.linesOfCode} | Complexity: ${match.metrics.cyclomaticComplexity}\n`);
|
|
170
|
-
process.stdout.write(` Imports: ${match.metrics.importCount} | Errors: ${errors} | Warnings: ${warnings}\n`);
|
|
171
|
-
}
|
|
172
|
-
function handlePath(parts, graph, repo) {
|
|
173
|
-
if (parts.length < 2) {
|
|
174
|
-
process.stdout.write('Usage: path <source-file> <target-file>\n');
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
const a = parts[0];
|
|
178
|
-
const b = parts[1];
|
|
179
|
-
const src = graph.nodes.find(n => n.label.includes(a) || n.id.includes(a));
|
|
180
|
-
const dst = graph.nodes.find(n => n.label.includes(b) || n.id.includes(b));
|
|
181
|
-
if (!src || !dst) {
|
|
182
|
-
process.stdout.write(`Could not find matching files. Try: ${graph.nodes.slice(0, 10).map(n => n.label).join(', ')}\n`);
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
process.stdout.write(`Path from ${path.relative(repo, src.id)} to ${path.relative(repo, dst.id)}:\n`);
|
|
186
|
-
const found = (0, repl_algorithms_1.findPath)(src.id, dst.id, graph.edges);
|
|
187
|
-
if (found) {
|
|
188
|
-
for (const f of found) {
|
|
189
|
-
const n = graph.nodes.find(node => node.id === f);
|
|
190
|
-
process.stdout.write(` ${path.relative(repo, f)} (${n?.rating ?? '?'})\n`);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
process.stdout.write(' No dependency path found between these files.\n');
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
// ── Core REPL loop (shared by main() and startRepl()) ─────
|
|
198
|
-
async function runRepl(repo, graph) {
|
|
199
|
-
const repoName = path.basename(repo);
|
|
200
|
-
process.stdout.write(`\n ⬡ Gate Keeper Query REPL — ${repoName}\n`);
|
|
201
|
-
process.stdout.write(` ${graph.nodes.length} files, ${graph.edges.length} edges\n\n`);
|
|
202
|
-
const rl = readline.createInterface({
|
|
203
|
-
input: process.stdin,
|
|
204
|
-
output: process.stdout,
|
|
205
|
-
prompt: 'gk> ',
|
|
206
|
-
});
|
|
207
|
-
rl.prompt();
|
|
208
|
-
rl.on('line', async (line) => {
|
|
209
|
-
const trimmed = line.trim();
|
|
210
|
-
if (!trimmed) {
|
|
211
|
-
rl.prompt();
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
if (trimmed === 'quit' || trimmed === 'exit') {
|
|
215
|
-
rl.close();
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
if (trimmed === 'help') {
|
|
219
|
-
printHelp();
|
|
220
|
-
rl.prompt();
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
if (trimmed === 'refresh') {
|
|
224
|
-
const freshRaw = await fetchApi(`/api/graph?repo=${encodeURIComponent(repo)}`);
|
|
225
|
-
if (freshRaw) {
|
|
226
|
-
Object.assign(graph, freshRaw);
|
|
227
|
-
process.stdout.write(`Refreshed: ${graph.nodes.length} files, ${graph.edges.length} edges\n`);
|
|
228
|
-
}
|
|
229
|
-
else {
|
|
230
|
-
process.stdout.write('Refresh failed — daemon may be unavailable\n');
|
|
231
|
-
}
|
|
232
|
-
rl.prompt();
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
if (trimmed.startsWith('explain ')) {
|
|
236
|
-
handleExplain(trimmed.slice(8).trim(), graph, repo);
|
|
237
|
-
rl.prompt();
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
if (trimmed.startsWith('path ')) {
|
|
241
|
-
handlePath(trimmed.slice(5).trim().split(/\s+/), graph, repo);
|
|
242
|
-
rl.prompt();
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
let answered = false;
|
|
246
|
-
for (const p of exports.QUERY_PATTERNS) {
|
|
247
|
-
if (p.match.test(trimmed)) {
|
|
248
|
-
const m = p.match.exec(trimmed);
|
|
249
|
-
if (m) {
|
|
250
|
-
process.stdout.write(p.handler(m, graph, repo) + '\n');
|
|
251
|
-
answered = true;
|
|
252
|
-
}
|
|
253
|
-
break;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
if (!answered) {
|
|
257
|
-
process.stdout.write('Query not recognised. Try: "god nodes", "surprising connections", "health", "suggest questions", or type "help".\n');
|
|
258
|
-
}
|
|
259
|
-
rl.prompt();
|
|
260
|
-
});
|
|
261
|
-
rl.on('close', () => {
|
|
262
|
-
process.stdout.write('\nGoodbye.\n');
|
|
263
|
-
process.exit(0);
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
async function loadGraph(repo, startupHint) {
|
|
267
|
-
const graphRaw = await fetchApi(`/api/graph?repo=${encodeURIComponent(repo)}`);
|
|
268
|
-
if (!graphRaw) {
|
|
269
|
-
process.stderr.write('Error: Cannot connect to Gate Keeper daemon on port 5378.\n');
|
|
270
|
-
process.stderr.write(`${startupHint}\n`);
|
|
271
|
-
process.exit(1);
|
|
272
|
-
}
|
|
273
|
-
return graphRaw;
|
|
274
|
-
}
|
|
275
|
-
// ── Public entry points ────────────────────────────────────
|
|
276
|
-
/**
|
|
277
|
-
* Exported for use by the daemon's --query mode.
|
|
278
|
-
* Loads the graph from the running daemon, then starts the REPL.
|
|
279
|
-
*/
|
|
280
|
-
async function startRepl(repo) {
|
|
281
|
-
const graph = await loadGraph(repo, 'Start the daemon first: npm run dev (from the gate-keeper directory)');
|
|
282
|
-
await runRepl(repo, graph);
|
|
283
|
-
}
|
|
284
|
-
async function main() {
|
|
285
|
-
const args = process.argv.slice(2);
|
|
286
|
-
const repoIndex = args.indexOf('--repo');
|
|
287
|
-
const repoArg = repoIndex >= 0 ? args[repoIndex + 1] : undefined;
|
|
288
|
-
const repo = repoArg ?? findGitRoot(process.cwd());
|
|
289
|
-
const graph = await loadGraph(repo, 'Start it with: npm run dev (from the gate-keeper directory)');
|
|
290
|
-
await runRepl(repo, graph);
|
|
291
|
-
}
|
|
292
|
-
if (require.main === module) {
|
|
293
|
-
main().catch(err => {
|
|
294
|
-
process.stderr.write(String(err) + '\n');
|
|
295
|
-
process.exit(1);
|
|
296
|
-
});
|
|
297
|
-
}
|
|
298
|
-
//# sourceMappingURL=query-repl.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"query-repl.js","sourceRoot":"","sources":["../../src/cli/query-repl.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure graph-algorithm functions used by the query REPL.
|
|
3
|
-
* No I/O — all functions take graph data and return results.
|
|
4
|
-
*/
|
|
5
|
-
export interface ReplGraphNode {
|
|
6
|
-
id: string;
|
|
7
|
-
label: string;
|
|
8
|
-
rating: number;
|
|
9
|
-
metrics: {
|
|
10
|
-
linesOfCode: number;
|
|
11
|
-
importCount: number;
|
|
12
|
-
cyclomaticComplexity: number;
|
|
13
|
-
};
|
|
14
|
-
violations: Array<{
|
|
15
|
-
type: string;
|
|
16
|
-
severity: string;
|
|
17
|
-
}>;
|
|
18
|
-
}
|
|
19
|
-
export interface ReplGraphEdge {
|
|
20
|
-
source: string;
|
|
21
|
-
target: string;
|
|
22
|
-
type: string;
|
|
23
|
-
strength: number;
|
|
24
|
-
}
|
|
25
|
-
export interface ReplGraph {
|
|
26
|
-
nodes: ReplGraphNode[];
|
|
27
|
-
edges: ReplGraphEdge[];
|
|
28
|
-
}
|
|
29
|
-
export interface CentralityEntry {
|
|
30
|
-
path: string;
|
|
31
|
-
label: string;
|
|
32
|
-
rating: number;
|
|
33
|
-
inDegree: number;
|
|
34
|
-
outDegree: number;
|
|
35
|
-
totalDegree: number;
|
|
36
|
-
}
|
|
37
|
-
export interface SurprisingConnection {
|
|
38
|
-
src: string;
|
|
39
|
-
dst: string;
|
|
40
|
-
S: string;
|
|
41
|
-
T: string;
|
|
42
|
-
score: number;
|
|
43
|
-
}
|
|
44
|
-
export declare function getModule(filePath: string, repoRoot: string): string;
|
|
45
|
-
export declare function computeDegreeCentrality(graph: ReplGraph): CentralityEntry[];
|
|
46
|
-
export declare function findSurprising(graph: ReplGraph, repo: string, topN?: number): SurprisingConnection[];
|
|
47
|
-
export declare function suggestQuestions(graph: ReplGraph, repo: string): string[];
|
|
48
|
-
export declare function findPath(startId: string, endId: string, edges: ReplGraphEdge[]): string[] | null;
|
|
49
|
-
//# sourceMappingURL=repl-algorithms.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"repl-algorithms.d.ts","sourceRoot":"","sources":["../../src/cli/repl-algorithms.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,oBAAoB,EAAE,MAAM,CAAA;KAAE,CAAC;IACpF,UAAU,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;CACf;AAID,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMpE;AAID,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,SAAS,GAAG,eAAe,EAAE,CAc3E;AAID,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,SAAI,GAAG,oBAAoB,EAAE,CAiC/F;AAID,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAezE;AAID,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,MAAM,EAAE,GAAG,IAAI,CAchG"}
|