@codragraph/cli 1.6.4 → 2.1.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 +34 -0
- package/dist/_shared/cgdb/schema-constants.d.ts +16 -0
- package/dist/_shared/cgdb/schema-constants.d.ts.map +1 -0
- package/dist/_shared/cgdb/schema-constants.js +67 -0
- package/dist/_shared/cgdb/schema-constants.js.map +1 -0
- package/dist/_shared/index.d.ts +2 -2
- package/dist/_shared/index.js +1 -1
- package/dist/cli/analyze.d.ts +22 -0
- package/dist/cli/analyze.js +109 -6
- package/dist/cli/compress-stats.d.ts +29 -0
- package/dist/cli/compress-stats.js +97 -0
- package/dist/cli/graphstore.d.ts +6 -2
- package/dist/cli/graphstore.js +45 -23
- package/dist/cli/index-repo.js +3 -3
- package/dist/cli/index.js +16 -2
- package/dist/cli/profile-heap.d.ts +35 -0
- package/dist/cli/profile-heap.js +126 -0
- package/dist/cli/setup.d.ts +13 -0
- package/dist/cli/setup.js +22 -11
- package/dist/cli/skill-gen.d.ts +14 -2
- package/dist/cli/skill-gen.js +52 -19
- package/dist/cli/tool.js +4 -0
- package/dist/cli/wiki.js +3 -3
- package/dist/core/augmentation/engine.js +7 -7
- package/dist/core/cgdb/cgdb-adapter.d.ts +176 -0
- package/dist/core/cgdb/cgdb-adapter.js +1320 -0
- package/dist/core/cgdb/content-read.d.ts +46 -0
- package/dist/core/cgdb/content-read.js +64 -0
- package/dist/core/cgdb/csv-generator.d.ts +29 -0
- package/dist/core/cgdb/csv-generator.js +492 -0
- package/dist/core/cgdb/pool-adapter.d.ts +93 -0
- package/dist/core/cgdb/pool-adapter.js +550 -0
- package/dist/core/cgdb/schema.d.ts +62 -0
- package/dist/core/cgdb/schema.js +502 -0
- package/dist/core/embeddings/embedding-pipeline.js +27 -10
- package/dist/core/graphstore/cgdb-row-source.d.ts +19 -0
- package/dist/core/graphstore/cgdb-row-source.js +141 -0
- package/dist/core/graphstore/index.d.ts +1 -1
- package/dist/core/graphstore/index.js +3 -3
- package/dist/core/group/bridge-db.d.ts +2 -2
- package/dist/core/group/bridge-db.js +123 -36
- package/dist/core/group/bridge-schema.d.ts +4 -4
- package/dist/core/group/bridge-schema.js +4 -4
- package/dist/core/group/cross-impact.js +3 -3
- package/dist/core/group/sync.js +4 -4
- package/dist/core/lbug/content-read.d.ts +46 -0
- package/dist/core/lbug/content-read.js +64 -0
- package/dist/core/lbug/csv-generator.d.ts +2 -6
- package/dist/core/lbug/csv-generator.js +45 -12
- package/dist/core/lbug/lbug-adapter.d.ts +4 -1
- package/dist/core/lbug/lbug-adapter.js +153 -21
- package/dist/core/lbug/schema.d.ts +7 -7
- package/dist/core/lbug/schema.js +18 -0
- package/dist/core/run-analyze.d.ts +13 -0
- package/dist/core/run-analyze.js +114 -27
- package/dist/core/search/bm25-index.d.ts +3 -3
- package/dist/core/search/bm25-index.js +75 -23
- package/dist/core/search/hybrid-search.js +2 -2
- package/dist/core/wiki/generator.d.ts +2 -2
- package/dist/core/wiki/generator.js +4 -4
- package/dist/core/wiki/graph-queries.d.ts +2 -2
- package/dist/core/wiki/graph-queries.js +5 -5
- package/dist/mcp/core/cgdb-adapter.d.ts +5 -0
- package/dist/mcp/core/cgdb-adapter.js +5 -0
- package/dist/mcp/core/embedder.js +1 -1
- package/dist/mcp/local/local-backend.d.ts +2 -2
- package/dist/mcp/local/local-backend.js +36 -19
- package/dist/mcp/server.js +3 -3
- package/dist/mcp/tools.js +1 -1
- package/dist/server/analyze-worker.js +2 -2
- package/dist/server/api.js +34 -33
- package/dist/storage/repo-manager.d.ts +42 -3
- package/dist/storage/repo-manager.js +23 -4
- package/hooks/claude/codragraph-hook.cjs +98 -5
- package/package.json +4 -4
- package/scripts/build-tree-sitter-proto.cjs +15 -3
- package/scripts/build.js +8 -9
- package/scripts/patch-tree-sitter-swift.cjs +17 -4
- package/skills/codragraph-api-surface.md +110 -0
- package/skills/codragraph-config-audit.md +146 -0
- package/skills/codragraph-cross-repo-impact.md +135 -0
- package/skills/codragraph-data-lineage.md +137 -0
- package/skills/codragraph-dead-code.md +119 -0
- package/skills/codragraph-gh-actions-debug.md +162 -0
- package/skills/codragraph-gh-issue-workflow.md +178 -0
- package/skills/codragraph-gh-pr-workflow.md +176 -0
- package/skills/codragraph-gh-release-workflow.md +187 -0
- package/skills/codragraph-git-bisect.md +176 -0
- package/skills/codragraph-git-force-push.md +147 -0
- package/skills/codragraph-git-history-rewrite.md +174 -0
- package/skills/codragraph-git-rebase-vs-merge.md +138 -0
- package/skills/codragraph-git-recovery.md +181 -0
- package/skills/codragraph-git-worktree.md +145 -0
- package/skills/codragraph-migration-tracking.md +130 -0
- package/skills/codragraph-notebook-context.md +136 -0
- package/skills/codragraph-observability-coverage.md +125 -0
- package/skills/codragraph-onboarding.md +129 -0
- package/skills/codragraph-perf-hotspots.md +132 -0
- package/skills/codragraph-project-switcher.md +116 -0
- package/skills/codragraph-security-audit.md +144 -0
- package/skills/codragraph-sql-tracing.md +122 -0
- package/skills/codragraph-supply-chain-audit.md +153 -0
- package/skills/codragraph-test-coverage.md +97 -0
- package/vendor/tree-sitter-proto/bindings/node/index.js +3 -3
- package/vendor/tree-sitter-proto/src/node-types.json +1 -1
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: codragraph-project-switcher
|
|
3
|
+
description: "Use when the user works across many parallel projects and needs to switch context, find which repo a symbol is in, list all indexed projects, or run a query against a specific repo without ambiguity. Examples: \"what projects am I working on\", \"switch to repo X\", \"which of my repos has function Y\", \"list my repositories\""
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Multi-Project / Vibecoding Context Switcher
|
|
7
|
+
|
|
8
|
+
## When to Use
|
|
9
|
+
|
|
10
|
+
- "What projects do I have indexed?"
|
|
11
|
+
- "Switch to my `<project>` repo for this query."
|
|
12
|
+
- "Which of my repos has the `<symbol>` function?"
|
|
13
|
+
- "Run this query across all my repos."
|
|
14
|
+
- Solo dev juggling 4+ side projects with different agents
|
|
15
|
+
- Picking up a project after weeks away
|
|
16
|
+
|
|
17
|
+
## Why CodraGraph helps here
|
|
18
|
+
|
|
19
|
+
CodraGraph maintains a global registry of every indexed repo at
|
|
20
|
+
`~/.codragraph/registry.json`. Every MCP tool accepts a `repo` parameter
|
|
21
|
+
to disambiguate. So switching context isn't "open a new editor / cd into
|
|
22
|
+
the project / re-orient your agent" — it's just passing `repo: "<name>"`
|
|
23
|
+
to the next call. Combine with **groups** (multiple repos that share
|
|
24
|
+
contracts) and you get cross-repo queries with one call.
|
|
25
|
+
|
|
26
|
+
## Workflow
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
1. List every indexed repo:
|
|
30
|
+
codragraph_list_repos({})
|
|
31
|
+
→ name, path, file count, last analyze time
|
|
32
|
+
|
|
33
|
+
2. (Optional) List groups (sets of related repos):
|
|
34
|
+
codragraph_group_list({})
|
|
35
|
+
→ group name + member repos
|
|
36
|
+
|
|
37
|
+
3. Query against a specific repo:
|
|
38
|
+
codragraph_query({repo: "<name>", query: "<concept>"})
|
|
39
|
+
→ answers come from that repo only
|
|
40
|
+
|
|
41
|
+
4. Find which repo has a symbol you remember:
|
|
42
|
+
For each repo from list_repos:
|
|
43
|
+
codragraph_query({repo: "<name>", query: "<remembered name>"})
|
|
44
|
+
→ first hit identifies the repo
|
|
45
|
+
|
|
46
|
+
5. For cross-repo questions (group-mode):
|
|
47
|
+
codragraph_query({repo: "@<group>", query: "<concept>"})
|
|
48
|
+
→ fans out across every group member, RRF-merges results
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
> If `list_repos` returns nothing, the user has no indexed projects yet.
|
|
52
|
+
> Run `codragraph analyze` in each project once to register them.
|
|
53
|
+
|
|
54
|
+
## Checklist
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
- [ ] list_repos to see what's indexed
|
|
58
|
+
- [ ] group_list to see related-repo groups
|
|
59
|
+
- [ ] Pick the right repo (or group) for the question
|
|
60
|
+
- [ ] Pass repo: "<name>" or repo: "@<group>" to subsequent calls
|
|
61
|
+
- [ ] If a project isn't indexed yet, suggest the user run analyze in it
|
|
62
|
+
- [ ] Mention staleness ("repo X last indexed 12 days ago — re-analyze?")
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Multi-Project Patterns
|
|
66
|
+
|
|
67
|
+
| Situation | What to do |
|
|
68
|
+
| --- | --- |
|
|
69
|
+
| Switching from one solo project to another | `list_repos` → pick → all subsequent tools take `repo: "<name>"` |
|
|
70
|
+
| "Did I solve this in another repo?" | `query` over each repo, look for matching symbols |
|
|
71
|
+
| Shared library used by multiple repos | Define a group (group.yaml); use `repo: "@<group>"` |
|
|
72
|
+
| Resuming a project after weeks | Check staleness (`list_repos` last-indexed timestamps); re-analyze if old |
|
|
73
|
+
|
|
74
|
+
## Example: "Switch me to my SaaS side project and find the auth code"
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
1. codragraph_list_repos({})
|
|
78
|
+
→ 4 indexed repos:
|
|
79
|
+
- codragraph (~/code/codragraph, 4325 symbols, indexed 2 hours ago)
|
|
80
|
+
- my-saas (~/projects/my-saas, 1180 symbols, indexed 3 days ago)
|
|
81
|
+
- portfolio (~/code/portfolio, 240 symbols, indexed 2 weeks ago)
|
|
82
|
+
- data-eda (~/notebooks/data-eda, 95 symbols, indexed 1 month ago)
|
|
83
|
+
|
|
84
|
+
2. codragraph_query({repo: "my-saas", query: "authentication login session"})
|
|
85
|
+
→ top 5 symbols in my-saas, none in other repos
|
|
86
|
+
|
|
87
|
+
3. codragraph_context({repo: "my-saas", name: "validateSession"})
|
|
88
|
+
→ callers: requireAuth, refreshToken (both in my-saas)
|
|
89
|
+
|
|
90
|
+
4. (Optional) Reminder: my-saas was indexed 3 days ago — fine for navigation
|
|
91
|
+
but if I just made commits, run `cd ~/projects/my-saas && codragraph analyze`
|
|
92
|
+
to refresh.
|
|
93
|
+
|
|
94
|
+
Switched. Subsequent queries default to my-saas now.
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Output Format
|
|
98
|
+
|
|
99
|
+
```markdown
|
|
100
|
+
## Project Switch: → `<repo>`
|
|
101
|
+
|
|
102
|
+
### Available projects
|
|
103
|
+
1. **<repo-1>** — N symbols, last indexed Xh ago
|
|
104
|
+
2. **<repo-2>** — M symbols, last indexed Yd ago (stale?)
|
|
105
|
+
3. ...
|
|
106
|
+
|
|
107
|
+
### Active for this conversation
|
|
108
|
+
`<chosen-repo>` (path: `<path>`).
|
|
109
|
+
|
|
110
|
+
### Staleness note
|
|
111
|
+
Last indexed `<duration>` ago. Re-analyze if recent commits matter.
|
|
112
|
+
|
|
113
|
+
### Quick links
|
|
114
|
+
- `query` already scoped to this repo
|
|
115
|
+
- For cross-repo: pass `repo: "@<group>"` instead
|
|
116
|
+
```
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: codragraph-security-audit
|
|
3
|
+
description: "Use for security-focused codebase audits — finding auth bypass paths, missing input validation, secrets in code, untrusted-input flow, and routes that skip auth middleware. Examples: \"security audit\", \"find auth bypass\", \"unvalidated input\", \"untrusted data flow\", \"missing authentication\""
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Security Audit with CodraGraph
|
|
7
|
+
|
|
8
|
+
## When to Use
|
|
9
|
+
|
|
10
|
+
- "Audit auth coverage — which routes skip the auth middleware?"
|
|
11
|
+
- "Find input that flows from request to SQL/template/exec without validation."
|
|
12
|
+
- "Find hardcoded secrets / credentials in source."
|
|
13
|
+
- "Trace untrusted-input flow for `<endpoint>`."
|
|
14
|
+
- Pre-release security pass on a PR-heavy week.
|
|
15
|
+
|
|
16
|
+
## Why CodraGraph helps here
|
|
17
|
+
|
|
18
|
+
Static-analysis tools find pattern matches; CodraGraph adds the
|
|
19
|
+
**call-graph**, so you can answer "*which* request handlers reach this
|
|
20
|
+
unsafe sink?" rather than just "this sink is unsafe somewhere." Combined
|
|
21
|
+
with `query` for sensitive identifier strings and `cypher` for structural
|
|
22
|
+
filters, you can build an audit that's far more targeted than grep.
|
|
23
|
+
|
|
24
|
+
## Workflow
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
1. Identify the boundary symbols:
|
|
28
|
+
codragraph_query({query: "request handler route controller"})
|
|
29
|
+
→ all entry points where untrusted input arrives
|
|
30
|
+
|
|
31
|
+
2. Identify the dangerous sinks:
|
|
32
|
+
codragraph_query({query: "exec spawn eval query raw_sql innerHTML"})
|
|
33
|
+
→ places where untrusted input becomes harmful
|
|
34
|
+
|
|
35
|
+
3. For each (handler → sink) pair, walk the call graph:
|
|
36
|
+
codragraph_impact({target: "<sink>", direction: "upstream"})
|
|
37
|
+
→ which handlers REACH this sink?
|
|
38
|
+
|
|
39
|
+
4. For each path, look for a validator on the way:
|
|
40
|
+
codragraph_context({name: "<handler>"})
|
|
41
|
+
→ is `validate / sanitize / escape / parse` called between handler and sink?
|
|
42
|
+
→ if not: candidate vulnerability
|
|
43
|
+
|
|
44
|
+
5. Cross-check against secrets:
|
|
45
|
+
codragraph_cypher({query: "MATCH (n) WHERE n.body =~ '.*(?i)(api[_-]?key|secret|password|token)[ ]*=[ ]*[\\'\"][a-zA-Z0-9]{16,}.*' RETURN n"})
|
|
46
|
+
→ suspicious literals that look like real keys
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Audit Patterns
|
|
50
|
+
|
|
51
|
+
| Pattern | What to look for | CodraGraph approach |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| Auth bypass | Routes not wrapped by `requireAuth` middleware | `query` for routes; check `context` for middleware in callers |
|
|
54
|
+
| SQL injection | Raw query string built from request input | `query` SQL literals → `impact` upstream → flag handlers |
|
|
55
|
+
| XSS | Untrusted input rendered without escape | `query` `innerHTML` / `dangerouslySetInnerHTML` → impact upstream |
|
|
56
|
+
| Command injection | `exec` / `spawn` with concatenated input | `query` exec/spawn → impact upstream → check for shell escape |
|
|
57
|
+
| Open redirect | Redirect URL from request | `query` `redirect` / `Location:` → trace input source |
|
|
58
|
+
| Hardcoded secrets | API keys in source | `cypher` regex over `n.body` |
|
|
59
|
+
| Missing CSRF | State-changing routes without CSRF middleware | `query` POST / PUT / DELETE handlers → check middleware chain |
|
|
60
|
+
|
|
61
|
+
## Why "missing validator" is a great query
|
|
62
|
+
|
|
63
|
+
The graph cleanly shows the call path: `handler → … → sink`. Validators
|
|
64
|
+
appear in that chain or they don't. If `validateInput` / `sanitize` /
|
|
65
|
+
`escape` is NOT in the path between a handler and a sink, that's a
|
|
66
|
+
*provable* gap, not a guess.
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
codragraph_cypher({query: `
|
|
70
|
+
// Find handler→sink paths that don't pass through ANY validator
|
|
71
|
+
MATCH path = (handler {label: 'Function'})-[:CALLS*1..6]->(sink {label: 'Function'})
|
|
72
|
+
WHERE handler.isEntryPoint = true
|
|
73
|
+
AND sink.name IN ['exec', 'query', 'innerHTML', 'eval']
|
|
74
|
+
AND NONE(n IN nodes(path) WHERE n.name STARTS WITH 'validate'
|
|
75
|
+
OR n.name STARTS WITH 'sanitize'
|
|
76
|
+
OR n.name STARTS WITH 'escape')
|
|
77
|
+
RETURN handler.name, sink.name, length(path) AS hops
|
|
78
|
+
ORDER BY hops ASC
|
|
79
|
+
`})
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Checklist
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
- [ ] Listed entry-point handlers (query for "handler"/"route"/"controller")
|
|
86
|
+
- [ ] Listed dangerous sinks (exec/query/eval/innerHTML/raw)
|
|
87
|
+
- [ ] Built handler→sink table; flagged paths missing validators
|
|
88
|
+
- [ ] Cypher scan for hardcoded-secret literal patterns
|
|
89
|
+
- [ ] codragraph_context on each flagged handler — confirm coverage / propose fix
|
|
90
|
+
- [ ] Document findings as severity-tagged report
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Example: "Audit which routes skip our requireAuth middleware"
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
1. codragraph_query({query: "Express router get post put delete handler"})
|
|
97
|
+
→ 28 route handlers across 6 router files
|
|
98
|
+
|
|
99
|
+
2. For each handler, codragraph_context({name: "<handler>"}):
|
|
100
|
+
→ check that callers include `requireAuth` (a known middleware function)
|
|
101
|
+
|
|
102
|
+
3. codragraph_cypher({
|
|
103
|
+
query: `MATCH (handler {isEntryPoint: true})-[:CALLS]->()
|
|
104
|
+
WHERE NOT EXISTS {
|
|
105
|
+
MATCH (handler)<-[:CALLS]-(mw {name: 'requireAuth'})
|
|
106
|
+
}
|
|
107
|
+
RETURN handler.name, handler.filePath`
|
|
108
|
+
})
|
|
109
|
+
→ 4 handlers have no requireAuth caller:
|
|
110
|
+
- publicHealthCheck (intentional ✓)
|
|
111
|
+
- signup, login (intentional ✓ — these CREATE auth)
|
|
112
|
+
- debugDumpUser ⚠ (NOT intentional — leaks user data)
|
|
113
|
+
|
|
114
|
+
4. Findings report:
|
|
115
|
+
- HIGH: debugDumpUser at src/routes/debug.ts:42
|
|
116
|
+
reaches db.query → returns full user record. No auth.
|
|
117
|
+
Fix: wrap with requireAuth or remove from production builds.
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Output Format
|
|
121
|
+
|
|
122
|
+
```markdown
|
|
123
|
+
## Security Audit: <scope>
|
|
124
|
+
|
|
125
|
+
### Summary
|
|
126
|
+
- N handlers audited
|
|
127
|
+
- M handler→sink paths inspected
|
|
128
|
+
- K validator-missing paths flagged
|
|
129
|
+
- Severity: 1 HIGH, 2 MEDIUM, 0 CRITICAL
|
|
130
|
+
|
|
131
|
+
### Findings
|
|
132
|
+
|
|
133
|
+
#### HIGH — debugDumpUser at src/routes/debug.ts:42
|
|
134
|
+
- Reachable without `requireAuth`
|
|
135
|
+
- Calls `db.query` with no input validation
|
|
136
|
+
- Returns full user record
|
|
137
|
+
- **Fix:** wrap with auth middleware OR strip from production builds
|
|
138
|
+
|
|
139
|
+
#### MEDIUM — …
|
|
140
|
+
|
|
141
|
+
### Hardcoded-secret scan
|
|
142
|
+
- 0 high-confidence matches
|
|
143
|
+
- 1 false-positive: example token in test fixture
|
|
144
|
+
```
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: codragraph-sql-tracing
|
|
3
|
+
description: "Use when finding where SQL queries are constructed in code, tracing which functions execute a given query, auditing query patterns, or finding the call sites of a stored procedure. Examples: \"where is this SELECT defined\", \"who calls this query\", \"find all SQL in the auth module\", \"trace this stored procedure call\""
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SQL Query Tracing with CodraGraph
|
|
7
|
+
|
|
8
|
+
## When to Use
|
|
9
|
+
|
|
10
|
+
- "Where is the query for `<table>` constructed?"
|
|
11
|
+
- "Which functions execute `<sql snippet>`?"
|
|
12
|
+
- "Find all SQL string literals in `<area>`."
|
|
13
|
+
- Auditing query patterns (N+1, missing indexes, etc.) before optimization
|
|
14
|
+
- Tracing a stored-procedure call from production logs back to the caller
|
|
15
|
+
|
|
16
|
+
## Why CodraGraph helps here
|
|
17
|
+
|
|
18
|
+
SQL queries are usually plain string literals — the language-server knows
|
|
19
|
+
nothing about them, but `query` over the index plus `cypher` against the
|
|
20
|
+
graph can find them, and `context` / `impact` can trace who calls the
|
|
21
|
+
enclosing function. This works equally well for raw SQL strings, query
|
|
22
|
+
builders (Knex, SQLAlchemy, Diesel), and ORM-generated queries that
|
|
23
|
+
include a recognizable identifier.
|
|
24
|
+
|
|
25
|
+
## Workflow
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
1. codragraph_query({query: "SELECT FROM <table>"})
|
|
29
|
+
OR
|
|
30
|
+
codragraph_query({query: "<unique substring of the SQL>"})
|
|
31
|
+
→ symbols whose body contains the SQL fragment
|
|
32
|
+
|
|
33
|
+
2. For each candidate function:
|
|
34
|
+
codragraph_context({name: "<function>"})
|
|
35
|
+
→ see who calls it (the actual query-execution site)
|
|
36
|
+
|
|
37
|
+
3. codragraph_impact({target: "<function>", direction: "upstream"})
|
|
38
|
+
→ blast radius: every caller of the SQL-executing function
|
|
39
|
+
|
|
40
|
+
4. For ORM / query-builder users:
|
|
41
|
+
codragraph_query({query: "<table>.find OR <table>.where"})
|
|
42
|
+
→ find ORM calls that compile to SQL touching the table
|
|
43
|
+
|
|
44
|
+
5. Categorize: reads vs writes, hot paths vs cold paths
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
> CodraGraph indexes the *source* of the query, not the *executed* SQL.
|
|
48
|
+
> Dynamically built queries (`f"SELECT * FROM {table}"`) require both a
|
|
49
|
+
> string-literal search AND a check on the variable's binding via `context`.
|
|
50
|
+
|
|
51
|
+
## Checklist
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
- [ ] query for the SQL substring or table name
|
|
55
|
+
- [ ] context on each candidate function
|
|
56
|
+
- [ ] impact upstream on the executor → who calls it from the application
|
|
57
|
+
- [ ] Filter for ORM call patterns separately if relevant
|
|
58
|
+
- [ ] Group results: read paths vs write paths, hot vs cold paths
|
|
59
|
+
- [ ] Flag any query with no test reach (cross-ref with codragraph-test-coverage)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## SQL Patterns to Search
|
|
63
|
+
|
|
64
|
+
| Pattern | Search query |
|
|
65
|
+
| --- | --- |
|
|
66
|
+
| Raw string SELECT | `"SELECT FROM users"` (with table name) |
|
|
67
|
+
| Query builder (Knex) | `.from('users').where` |
|
|
68
|
+
| ORM (SQLAlchemy) | `session.query(User)` |
|
|
69
|
+
| Stored procedure call | `CALL sp_name` or `EXEC sp_name` |
|
|
70
|
+
| Migration | `CREATE TABLE` / `ALTER TABLE` |
|
|
71
|
+
|
|
72
|
+
## Example: "Find every place we read from the `audit_log` table"
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
1. codragraph_query({query: "FROM audit_log"})
|
|
76
|
+
→ 5 symbols:
|
|
77
|
+
- getAuditByUser (src/admin/audit.ts)
|
|
78
|
+
- getAuditByAction (src/admin/audit.ts)
|
|
79
|
+
- exportAuditCSV (src/admin/audit.ts)
|
|
80
|
+
- countRecentAuditEntries (src/dashboard/health.ts)
|
|
81
|
+
- debugAuditDump (src/scripts/debug.ts)
|
|
82
|
+
|
|
83
|
+
2. codragraph_query({query: "auditLog.find OR auditLog.where"})
|
|
84
|
+
→ 0 (we're using raw SQL, not an ORM)
|
|
85
|
+
|
|
86
|
+
3. codragraph_context({name: "getAuditByUser"})
|
|
87
|
+
→ callers: AuditController.show, AuditController.export
|
|
88
|
+
→ callees: db.query, parseAuditRow
|
|
89
|
+
|
|
90
|
+
4. codragraph_impact({target: "getAuditByUser", direction: "upstream"})
|
|
91
|
+
→ d=1: AuditController.show (admin UI), AuditController.export (CSV download)
|
|
92
|
+
→ d=2: AdminRouter (HTTP layer)
|
|
93
|
+
|
|
94
|
+
Findings: 5 read sites in 3 files. All go through AuditController. The
|
|
95
|
+
debug script reads with no auth — flag for review.
|
|
96
|
+
|
|
97
|
+
5. Cross-reference with codragraph-test-coverage:
|
|
98
|
+
- getAuditByUser: covered by AuditController.test
|
|
99
|
+
- debugAuditDump: NO TESTS, NO AUTH ⚠
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Output Format
|
|
103
|
+
|
|
104
|
+
```markdown
|
|
105
|
+
## SQL Trace: `audit_log` (reads)
|
|
106
|
+
|
|
107
|
+
### Read sites
|
|
108
|
+
| Function | File | Caller chain | Test reach |
|
|
109
|
+
|----------|------|--------------|------------|
|
|
110
|
+
| getAuditByUser | src/admin/audit.ts | Controller → Router | ✓ |
|
|
111
|
+
| getAuditByAction | src/admin/audit.ts | Controller → Router | ✓ |
|
|
112
|
+
| exportAuditCSV | src/admin/audit.ts | Controller → Router | ✗ |
|
|
113
|
+
| countRecentAuditEntries | src/dashboard/health.ts | HealthCheck → cron | ✗ |
|
|
114
|
+
| debugAuditDump | src/scripts/debug.ts | (no auth?) ⚠ | ✗ |
|
|
115
|
+
|
|
116
|
+
### Hot path
|
|
117
|
+
`AuditController` is the gateway for 3 of 5 read sites. Optimizations
|
|
118
|
+
that route through it benefit the most.
|
|
119
|
+
|
|
120
|
+
### Risks
|
|
121
|
+
- `debugAuditDump` has no auth and no tests. Investigate.
|
|
122
|
+
```
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: codragraph-supply-chain-audit
|
|
3
|
+
description: "Use to audit external dependency risk — which packages does the codebase actually use, where are the deepest integration points (a single dep used across N modules is high-blast-radius), what would break if a dep was removed. Examples: \"audit dependencies\", \"supply chain risk\", \"what would break if I drop X\", \"deep dep usage\", \"vendor in or replace\""
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Supply Chain / Dependency Audit with CodraGraph
|
|
7
|
+
|
|
8
|
+
## When to Use
|
|
9
|
+
|
|
10
|
+
- "Which deps are used the most?"
|
|
11
|
+
- "What would actually break if I removed `<package>`?"
|
|
12
|
+
- "Find deps imported in only 1-2 places (cheap to replace)."
|
|
13
|
+
- "Which deps are deeply integrated and risky to change?"
|
|
14
|
+
- "Pre-vendor audit: should I vendor `<dep>` to lock the version?"
|
|
15
|
+
- "Post-CVE: which of our code paths reach this vulnerable function?"
|
|
16
|
+
|
|
17
|
+
## Why CodraGraph helps here
|
|
18
|
+
|
|
19
|
+
`npm ls` / `pip list` / `go.sum` tell you which packages are *installed*.
|
|
20
|
+
CodraGraph tells you where they're *imported and called* — which is the
|
|
21
|
+
real measure of how integrated a dep is. Pair with `impact` for "what
|
|
22
|
+
breaks if this dep changes" and you have a much sharper risk picture
|
|
23
|
+
than pure dependency-tree analysis.
|
|
24
|
+
|
|
25
|
+
## Workflow
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
1. List external dependency import sites:
|
|
29
|
+
codragraph_cypher({query: `
|
|
30
|
+
MATCH (n)-[:IMPORTS]->(dep)
|
|
31
|
+
WHERE dep.isExternal = true OR dep.id STARTS WITH 'package:'
|
|
32
|
+
RETURN dep.id, dep.name, count(DISTINCT n) AS importers
|
|
33
|
+
ORDER BY importers DESC
|
|
34
|
+
`})
|
|
35
|
+
→ per-package import counts
|
|
36
|
+
|
|
37
|
+
2. For each high-import package, find which symbols call into it:
|
|
38
|
+
codragraph_cypher({query: `
|
|
39
|
+
MATCH (caller)-[:CALLS]->(target)
|
|
40
|
+
WHERE target.filePath CONTAINS 'node_modules/<pkg>'
|
|
41
|
+
OR target.id STARTS WITH 'package:<pkg>:'
|
|
42
|
+
RETURN caller.name, caller.filePath, count(*) AS calls
|
|
43
|
+
ORDER BY calls DESC
|
|
44
|
+
`})
|
|
45
|
+
→ per-package call sites; high-call-site = deeply integrated
|
|
46
|
+
|
|
47
|
+
3. Identify shallow deps (cheap-to-replace):
|
|
48
|
+
- 1-2 importers → easy to swap out
|
|
49
|
+
- usage limited to one cluster → bounded blast radius
|
|
50
|
+
|
|
51
|
+
4. Identify deep deps (high replacement cost):
|
|
52
|
+
- imported across many clusters → cross-cutting
|
|
53
|
+
- referenced in critical processes → request-path criticality
|
|
54
|
+
|
|
55
|
+
5. CVE-specific: given a vulnerable function name from the advisory,
|
|
56
|
+
find which of YOUR symbols reach it:
|
|
57
|
+
codragraph_impact({target: "<vulnerableFn>", direction: "upstream"})
|
|
58
|
+
→ only paths through this function are actually exposed
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Risk categorization
|
|
62
|
+
|
|
63
|
+
| Category | Signal | Action |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| **Trivial** | 1-2 importers, one cluster | Easy to replace; consider native impl |
|
|
66
|
+
| **Local** | Many importers in 1-2 clusters | Wrap behind a façade for future swap |
|
|
67
|
+
| **Cross-cutting** | Importers spread across most clusters | Treat as core infra; vendor if licensing allows |
|
|
68
|
+
| **Critical** | In every request-path process | Pin version, monitor CVEs, plan migration before EOL |
|
|
69
|
+
| **Vulnerable now** | Reachable code path to a known-CVE function | Patch / replace ASAP |
|
|
70
|
+
|
|
71
|
+
## CVE response workflow
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
1. CVE published: "<package> <vulnerable-fn> allows X"
|
|
75
|
+
|
|
76
|
+
2. Quick check: do we even reach the vulnerable function?
|
|
77
|
+
codragraph_query({query: "<vulnerable-fn>"})
|
|
78
|
+
→ list of call sites in YOUR code
|
|
79
|
+
|
|
80
|
+
3. For each call site, walk upstream:
|
|
81
|
+
codragraph_impact({target: "<our-caller>", direction: "upstream"})
|
|
82
|
+
→ which entry points / processes reach the vulnerable code
|
|
83
|
+
|
|
84
|
+
4. If 0 reachable paths → not exposed. Patch when convenient.
|
|
85
|
+
5. If reachable from request-path → patch ASAP, communicate scope.
|
|
86
|
+
6. If reachable from internal-only paths → patch in the next maintenance window.
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Checklist
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
- [ ] Cypher: per-package importer + caller counts
|
|
93
|
+
- [ ] Categorize each top-N package: trivial / local / cross-cutting / critical
|
|
94
|
+
- [ ] For deep deps: identify a façade boundary if one exists / propose one
|
|
95
|
+
- [ ] CVE list cross-check: any current advisories against our deps?
|
|
96
|
+
- [ ] For each open advisory: codragraph_impact on the vulnerable function
|
|
97
|
+
- [ ] Output: ranked deps with risk tier + replaceability cost
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Example: "Should I replace lodash with native?"
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
1. codragraph_cypher for lodash imports:
|
|
104
|
+
→ 47 importers across all 8 clusters
|
|
105
|
+
→ Cross-cutting category.
|
|
106
|
+
|
|
107
|
+
2. codragraph_cypher for lodash calls:
|
|
108
|
+
→ top-called: _.get (78), _.isEmpty (54), _.cloneDeep (32),
|
|
109
|
+
_.debounce (12), 25 other functions ≤ 5 calls each
|
|
110
|
+
|
|
111
|
+
3. Replacement cost analysis:
|
|
112
|
+
- _.get → optional chaining `?.` (47 sites)
|
|
113
|
+
- _.isEmpty → custom helper (3 lines)
|
|
114
|
+
- _.cloneDeep → structuredClone() (Node 17+)
|
|
115
|
+
- _.debounce → keep (lodash version is well-tuned, native lacks)
|
|
116
|
+
- 25 long-tail functions → ~75 individual replacement decisions
|
|
117
|
+
|
|
118
|
+
4. Decision matrix:
|
|
119
|
+
- High-frequency simple ones: easy native swap (saves 70%% of bundle hit)
|
|
120
|
+
- _.debounce: keep lodash for this one (or use a 50-line single-purpose dep)
|
|
121
|
+
- Long-tail: case-by-case during routine refactors
|
|
122
|
+
|
|
123
|
+
5. Migration plan:
|
|
124
|
+
- Phase 1: replace _.get / _.isEmpty / _.cloneDeep (top 3 = ~200 call sites)
|
|
125
|
+
- Phase 2: revisit long-tail in next major refactor
|
|
126
|
+
- Phase 3: keep lodash only if _.debounce's replacement isn't ready
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Output Format
|
|
130
|
+
|
|
131
|
+
```markdown
|
|
132
|
+
## Supply Chain Audit: <scope>
|
|
133
|
+
|
|
134
|
+
### Top deps by integration depth
|
|
135
|
+
| Package | Importers | Call sites | Clusters touched | Tier |
|
|
136
|
+
|---|--:|--:|--:|---|
|
|
137
|
+
| react | 142 | 380 | 4 | critical |
|
|
138
|
+
| lodash | 47 | 220 | 8 | cross-cutting |
|
|
139
|
+
| date-fns | 12 | 45 | 3 | local |
|
|
140
|
+
| classnames | 4 | 9 | 2 | local |
|
|
141
|
+
| md5 | 1 | 1 | 1 | trivial |
|
|
142
|
+
|
|
143
|
+
### Replacement candidates
|
|
144
|
+
- `md5` — 1 call site, ~5 lines of native crypto. Trivial removal.
|
|
145
|
+
- `lodash` — replace top 3 functions for 70%% of usage; keep for `_.debounce`.
|
|
146
|
+
|
|
147
|
+
### CVE exposure
|
|
148
|
+
- 0 active advisories matching code paths reachable from request handlers.
|
|
149
|
+
|
|
150
|
+
### Recommended next step
|
|
151
|
+
1. Drop `md5` (5-line PR).
|
|
152
|
+
2. Phase-1 lodash slim-down (~200 sites; can be incremental).
|
|
153
|
+
```
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: codragraph-test-coverage
|
|
3
|
+
description: "Use when the user wants to find untested code paths, audit test coverage gaps, identify functions or execution flows that have no test reach, or assess whether a refactor needs new tests. Examples: \"what isn't tested\", \"test coverage gaps\", \"which flows have no tests\", \"do I need a test for X\""
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Test Coverage Audit with CodraGraph
|
|
7
|
+
|
|
8
|
+
## When to Use
|
|
9
|
+
|
|
10
|
+
- "What's not tested in this codebase?"
|
|
11
|
+
- "Which execution flows have no test coverage?"
|
|
12
|
+
- "Are there tests that cover X?"
|
|
13
|
+
- "Do I need to add a test for this function?"
|
|
14
|
+
- Auditing coverage before a release / freeze
|
|
15
|
+
- Justifying a "needs more tests" review comment with evidence
|
|
16
|
+
|
|
17
|
+
## Why CodraGraph helps here
|
|
18
|
+
|
|
19
|
+
Line-coverage tools (jest --coverage, c8, pytest-cov) tell you *which lines
|
|
20
|
+
ran*. They don't tell you *which call paths an agent / engineer should be
|
|
21
|
+
worried about*. CodraGraph's `impact({includeTests: true})` walks the call
|
|
22
|
+
graph and lists every test that transitively reaches a symbol — direct or
|
|
23
|
+
indirect — so you can prove a flow is exercised, or prove it isn't.
|
|
24
|
+
|
|
25
|
+
## Workflow
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
1. codragraph_query({query: "<area you care about>"}) → find candidate symbols
|
|
29
|
+
2. For each non-trivial symbol:
|
|
30
|
+
codragraph_impact({target: "<symbol>", direction: "upstream", includeTests: true})
|
|
31
|
+
→ returns: callers + tests that transitively reach this symbol
|
|
32
|
+
3. READ codragraph://repo/{name}/processes
|
|
33
|
+
→ list every execution flow
|
|
34
|
+
4. For each flow, codragraph_impact on the flow's entry point with includeTests: true
|
|
35
|
+
→ flows with 0 tests = real gaps
|
|
36
|
+
5. Summarize: which symbols and flows have no test reach
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
> If "Index is stale" → run `npx @codragraph/cli analyze` first.
|
|
40
|
+
|
|
41
|
+
## Checklist
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
- [ ] List candidate symbols (query) or take from a recent diff (detect_changes)
|
|
45
|
+
- [ ] Run impact({includeTests: true}) on each
|
|
46
|
+
- [ ] Note symbols where the test list is empty
|
|
47
|
+
- [ ] Cross-reference with processes — flows with no test coverage are the real risk
|
|
48
|
+
- [ ] Report: gaps + the cheapest test that would close each gap (entry point)
|
|
49
|
+
- [ ] If reviewing a PR: limit to symbols changed in the PR
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Example: "What's not tested in the auth area?"
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
1. codragraph_query({query: "auth validation login session"})
|
|
56
|
+
→ 14 symbols across 6 files
|
|
57
|
+
|
|
58
|
+
2. codragraph_impact({target: "validateSession", direction: "upstream", includeTests: true})
|
|
59
|
+
→ callers: requireAuth, refreshToken
|
|
60
|
+
→ tests: 0 (no test reaches validateSession)
|
|
61
|
+
⚠ GAP
|
|
62
|
+
|
|
63
|
+
3. codragraph_impact({target: "hashPassword", direction: "upstream", includeTests: true})
|
|
64
|
+
→ tests: hashPassword.test.ts [direct], auth.integration.test.ts [via signup]
|
|
65
|
+
✓ covered
|
|
66
|
+
|
|
67
|
+
4. READ codragraph://repo/CodraGraph/processes
|
|
68
|
+
→ 3 auth flows: SignupFlow, LoginFlow, PasswordResetFlow
|
|
69
|
+
|
|
70
|
+
5. codragraph_impact for each flow's entry point with includeTests: true
|
|
71
|
+
→ SignupFlow: covered (3 tests)
|
|
72
|
+
→ LoginFlow: covered (2 tests)
|
|
73
|
+
→ PasswordResetFlow: NO TESTS ⚠
|
|
74
|
+
|
|
75
|
+
Findings:
|
|
76
|
+
- 2 untested gaps: validateSession (symbol), PasswordResetFlow (entire flow)
|
|
77
|
+
- Cheapest fix: one integration test calling resetPassword end-to-end would
|
|
78
|
+
close both gaps simultaneously (it's the entry point for the flow that
|
|
79
|
+
also calls validateSession).
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Output Format
|
|
83
|
+
|
|
84
|
+
```markdown
|
|
85
|
+
## Test Coverage Audit: <scope>
|
|
86
|
+
|
|
87
|
+
### Gaps (no test reach)
|
|
88
|
+
- **[symbol]** `validateSession` — called by 2 functions, no transitive test
|
|
89
|
+
- **[flow]** `PasswordResetFlow` — entire flow untested
|
|
90
|
+
|
|
91
|
+
### Covered (for reference)
|
|
92
|
+
- `hashPassword` — direct + integration test
|
|
93
|
+
|
|
94
|
+
### Suggested fixes
|
|
95
|
+
1. Add integration test for `resetPassword` → covers PasswordResetFlow + validateSession
|
|
96
|
+
2. ...
|
|
97
|
+
```
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
const root = require(
|
|
1
|
+
const root = require('path').join(__dirname, '..', '..');
|
|
2
2
|
|
|
3
|
-
module.exports = require(
|
|
3
|
+
module.exports = require('node-gyp-build')(root);
|
|
4
4
|
|
|
5
5
|
try {
|
|
6
|
-
module.exports.nodeTypeInfo = require(
|
|
6
|
+
module.exports.nodeTypeInfo = require('../../src/node-types.json');
|
|
7
7
|
} catch (_) {}
|