infrawise 0.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.
Files changed (3) hide show
  1. package/README.md +425 -0
  2. package/dist/index.js +3462 -0
  3. package/package.json +92 -0
package/README.md ADDED
@@ -0,0 +1,425 @@
1
+ # Infrawise
2
+
3
+ **Understand your infrastructure, not just your code.**
4
+
5
+ Infrawise is a CLI tool that scans your TypeScript codebase, maps every function-to-database relationship into a graph, detects anti-patterns (full table scans, missing indexes, hot partitions, N+1 queries), and exposes all of it as an MCP server — so AI coding assistants like Claude Code have live, deterministic knowledge of your infrastructure when helping you write database code.
6
+
7
+ ---
8
+
9
+ ## Why this exists
10
+
11
+ When AI coding assistants help you write database queries, they read your source files but have no knowledge of your actual infrastructure. They don't know your DynamoDB partition keys, which GSIs exist, or which functions are already doing expensive scans. They guess.
12
+
13
+ Infrawise fixes that. It runs a static analysis of your repo, builds an infrastructure graph, and starts a local MCP server. Claude Code can then call tools like `get_graph_summary`, `analyze_function`, and `suggest_gsi` in real time — giving it exact knowledge of your schema and access patterns before writing a single line of database code.
14
+
15
+ **Without Infrawise**, Claude might:
16
+ - Suggest a `.scan()` on your Orders table that has 50M rows
17
+ - Recommend adding a GSI on `status` that you already have
18
+ - Write a `SELECT *` when you need to keep query cost low
19
+ - Not notice that 5 functions are already hammering the same partition key
20
+
21
+ **With Infrawise**, Claude knows:
22
+ - Your exact table schemas, partition keys, sort keys, and GSIs
23
+ - Which functions query which tables and how
24
+ - Which patterns are already flagged as high severity in your codebase
25
+ - The exact `CREATE INDEX` SQL or GSI config for your specific tables — not generic advice
26
+
27
+ ---
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ npm install -g infrawise
33
+ ```
34
+
35
+ or use without installing:
36
+
37
+ ```bash
38
+ npx infrawise init
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Quick start
44
+
45
+ **1. Initialize in your repo**
46
+
47
+ ```bash
48
+ cd your-project
49
+ infrawise init
50
+ ```
51
+
52
+ Detects your AWS profile and region, asks a few questions, writes `infrawise.yaml`. That's the only file it creates in your project.
53
+
54
+ ```
55
+ ✔ Detected repository: payments-service
56
+ ✔ Repository type: typescript
57
+ ✔ AWS profile: default
58
+ ✔ Found DynamoDB tables: Orders, Users, Sessions
59
+ ✔ Created infrawise.yaml
60
+ ```
61
+
62
+ **2. Validate everything is connected**
63
+
64
+ ```bash
65
+ infrawise doctor
66
+ ```
67
+
68
+ **3. Run analysis**
69
+
70
+ ```bash
71
+ infrawise analyze
72
+ ```
73
+
74
+ ```
75
+ Findings (3 total)
76
+
77
+ 1. [HIGH] Full table scan detected on DynamoDB table "Orders"
78
+ listAllOrders() scans without any filter — reads every item in the table.
79
+ Recommendation: Replace Scan with Query using a partition key or add a GSI.
80
+
81
+ 2. [MEDIUM] PostgreSQL table "users" has no index on column "email"
82
+ Filtering on "email" causes sequential scans.
83
+ Recommendation: CREATE INDEX CONCURRENTLY idx_users_email ON users(email);
84
+
85
+ 3. [MEDIUM] DynamoDB table "Sessions" accessed by 6 distinct code paths
86
+ High access concentration may create hot partition issues at scale.
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Using with Claude Code
92
+
93
+ This is where Infrawise becomes most useful. Once wired up, Claude Code has live access to your infrastructure graph — it stops guessing and starts knowing.
94
+
95
+ ### Step 1: Start the MCP server
96
+
97
+ ```bash
98
+ infrawise dev
99
+ ```
100
+
101
+ ```
102
+ ✔ Tool server running
103
+ ✔ Context engine initialized
104
+
105
+ MCP endpoint: http://localhost:3000/mcp
106
+ Available tools: http://localhost:3000/mcp/tools
107
+ ```
108
+
109
+ ### Step 2: Add to Claude Code settings
110
+
111
+ Edit `.claude/settings.json` in your repo (project-level) or `~/.claude/settings.json` (global):
112
+
113
+ ```json
114
+ {
115
+ "mcpServers": {
116
+ "infrawise": {
117
+ "url": "http://localhost:3000/mcp"
118
+ }
119
+ }
120
+ }
121
+ ```
122
+
123
+ Restart Claude Code. The tools are now available in every conversation.
124
+
125
+ Alternatively, let Claude Code manage the server lifecycle automatically:
126
+
127
+ ```json
128
+ {
129
+ "mcpServers": {
130
+ "infrawise": {
131
+ "command": "infrawise",
132
+ "args": ["dev"]
133
+ }
134
+ }
135
+ }
136
+ ```
137
+
138
+ ### Step 3: What Claude can now do
139
+
140
+ Claude gains four tools it calls silently while helping you:
141
+
142
+ | Tool | What it gives Claude |
143
+ |---|---|
144
+ | `get_graph_summary` | Full infrastructure graph — tables, GSIs, function relationships, all findings |
145
+ | `analyze_function` | Issues introduced by a specific function — scans, missing indexes, N+1 |
146
+ | `suggest_gsi` | Exact GSI config for a DynamoDB table + attribute |
147
+ | `postgres_index_suggestions` | Exact `CREATE INDEX` SQL for your actual table |
148
+ | `suggest_mongo_index` | Exact `createIndex` command for a MongoDB collection + field |
149
+ | `mysql_index_suggestions` | Exact `ALTER TABLE ADD INDEX` SQL for your MySQL table |
150
+
151
+ ### What changes in practice
152
+
153
+ **Before Infrawise:**
154
+ > You: "Write a function to get all orders by userId"
155
+ > Claude: *writes a DynamoDB `.scan()` filtered client-side — no schema context*
156
+
157
+ **After Infrawise:**
158
+ > You: "Write a function to get all orders by userId"
159
+ > Claude: *calls `get_graph_summary` → sees Orders has a `userId-index` GSI → writes a `.query()` against the GSI → notes `listAllOrders()` already does a full scan and flags it proactively*
160
+
161
+ ### Using with other AI editors
162
+
163
+ Infrawise works with any editor or tool that supports MCP or can call an HTTP API:
164
+
165
+ - **Cursor** — add `http://localhost:3000/mcp` as an MCP server in Cursor settings
166
+ - **Windsurf** — same, via MCP server configuration
167
+ - **Any Claude API project** — call the endpoint directly from your own tooling
168
+
169
+ ---
170
+
171
+ ## CLI reference
172
+
173
+ | Command | What it does |
174
+ |---|---|
175
+ | `infrawise init` | Detect AWS + repo, generate `infrawise.yaml` |
176
+ | `infrawise auth` | Select or switch AWS profile |
177
+ | `infrawise analyze` | Scan repo + AWS, build graph, print findings |
178
+ | `infrawise dev` | Start MCP server at `http://localhost:3000/mcp` |
179
+ | `infrawise doctor` | Validate AWS access, DB connectivity, and config |
180
+
181
+ ---
182
+
183
+ ## Configuration
184
+
185
+ `infrawise.yaml` is generated by `infrawise init` and lives in your repo root:
186
+
187
+ ```yaml
188
+ project: payments-service
189
+
190
+ aws:
191
+ profile: default # AWS profile from ~/.aws/credentials
192
+ region: ap-south-1
193
+
194
+ dynamodb:
195
+ includeTables: # omit to include all tables
196
+ - Orders
197
+ - Users
198
+
199
+ postgres:
200
+ enabled: true
201
+ connectionString: postgresql://infrawise_ro:password@host:5432/mydb
202
+
203
+ analysis:
204
+ sampleSize: 100
205
+ ```
206
+
207
+ ### AWS setup
208
+
209
+ Infrawise is **read-only**. Minimum IAM policy required:
210
+
211
+ ```json
212
+ {
213
+ "Version": "2012-10-17",
214
+ "Statement": [
215
+ {
216
+ "Effect": "Allow",
217
+ "Action": [
218
+ "dynamodb:ListTables",
219
+ "dynamodb:DescribeTable"
220
+ ],
221
+ "Resource": "*"
222
+ }
223
+ ]
224
+ }
225
+ ```
226
+
227
+ For SSO profiles, log in before running infrawise:
228
+
229
+ ```bash
230
+ aws sso login --profile myprofile
231
+ ```
232
+
233
+ ### PostgreSQL setup (optional)
234
+
235
+ Create a read-only user for infrawise:
236
+
237
+ ```sql
238
+ CREATE USER infrawise_ro WITH PASSWORD 'yourpassword';
239
+ GRANT CONNECT ON DATABASE yourdb TO infrawise_ro;
240
+ GRANT USAGE ON SCHEMA public TO infrawise_ro;
241
+ GRANT SELECT ON ALL TABLES IN SCHEMA public TO infrawise_ro;
242
+ ```
243
+
244
+ For Amazon RDS: allow inbound on port 5432 from your machine's IP in the security group.
245
+
246
+ ---
247
+
248
+ ## What gets analyzed
249
+
250
+ ### DynamoDB
251
+
252
+ | Analyzer | Severity | What it detects |
253
+ |---|---|---|
254
+ | Full Table Scan | High | `.scan()` calls without filters |
255
+ | Missing GSI | Medium | Tables queried without a matching GSI |
256
+ | Hot Partition | Medium | 5+ distinct code paths hitting the same table |
257
+
258
+ ### PostgreSQL
259
+
260
+ | Analyzer | Severity | What it detects |
261
+ |---|---|---|
262
+ | Missing Index | Medium/High | Columns filtered without indexes |
263
+ | N+1 Query | Medium | Repeated query patterns from ORM inefficiencies |
264
+ | Large SELECT | Low | `SELECT *` usage |
265
+
266
+ ### MySQL
267
+
268
+ | Analyzer | Severity | What it detects |
269
+ |---|---|---|
270
+ | Missing MySQL Index | Medium | Tables queried without indexes |
271
+ | MySQL Full Table Scan | High | Scan operations on MySQL tables |
272
+
273
+ ### MongoDB
274
+
275
+ | Analyzer | Severity | What it detects |
276
+ |---|---|---|
277
+ | Missing Mongo Index | Medium | Collections queried without secondary indexes |
278
+ | Collection Scan | High | Full collection scan operations |
279
+
280
+ ### Terraform / CloudFormation (IaC Drift)
281
+
282
+ | Analyzer | Severity | What it detects |
283
+ |---|---|---|
284
+ | IaC Drift | Medium | DynamoDB tables defined in IaC but not deployed in AWS |
285
+ | IaC Drift | Medium | DynamoDB tables deployed in AWS but not defined in IaC |
286
+
287
+ ---
288
+
289
+ ## Security
290
+
291
+ - **Read-only** — never writes to AWS or your database, never executes DDL
292
+ - **Local-first** — everything runs on your machine, nothing sent to external servers
293
+ - **No telemetry** — zero data collection
294
+ - **Credentials** — uses your existing AWS credential chain, never stored by infrawise
295
+
296
+ ---
297
+
298
+ ## Architecture
299
+
300
+ ```
301
+ Your TypeScript repo
302
+
303
+ ┌───────────────────────────────────────────────────────┐
304
+ │ infrawise analyze │
305
+ │ │
306
+ │ Repository Scanner AWS DynamoDB PostgreSQL │
307
+ │ (ts-morph AST) ↓ ↓ │
308
+ │ ↓ └──────┬───────┘ │
309
+ │ └────────────────────► │ │
310
+ │ Graph Engine │
311
+ │ (nodes + edges) │
312
+ │ ↓ │
313
+ │ Analyzer Engine │
314
+ │ (rule-based, deterministic) │
315
+ └──────────────────────────────┬────────────────────────┘
316
+
317
+ ┌──────────────────┐
318
+ │ MCP Server │ ◄── Claude Code
319
+ │ localhost:3000 │ ◄── Cursor
320
+ └──────────────────┘ ◄── Windsurf
321
+ ```
322
+
323
+ The analysis is entirely deterministic — no LLM is involved in extracting or analyzing your infrastructure. AI is only at the consumption layer.
324
+
325
+ ### Package structure
326
+
327
+ | Package | Description |
328
+ |---|---|
329
+ | `@infrawise/shared` | Shared TypeScript types |
330
+ | `@infrawise/core` | Config (Zod + YAML), logger (Pino), local cache |
331
+ | `@infrawise/graph` | Graph engine — nodes, edges, builder |
332
+ | `@infrawise/adapters-dynamodb` | DynamoDB extractor (AWS SDK v3) |
333
+ | `@infrawise/adapters-postgres` | PostgreSQL extractor (pg) |
334
+ | `@infrawise/adapters-mysql` | MySQL extractor (mysql2) |
335
+ | `@infrawise/adapters-mongodb` | MongoDB extractor (mongodb driver) |
336
+ | `@infrawise/adapters-terraform` | Terraform and CloudFormation IaC schema extractor |
337
+ | `@infrawise/context` | Repository scanner (ts-morph AST) |
338
+ | `@infrawise/analyzers` | 11 rule-based analyzers |
339
+ | `@infrawise/server` | Fastify MCP HTTP server |
340
+ | `infrawise` | CLI (Commander.js) |
341
+
342
+ ---
343
+
344
+ ## Roadmap
345
+
346
+ - [x] MySQL adapter
347
+ - [x] MongoDB adapter
348
+ - [x] Terraform / CloudFormation schema correlation
349
+ - [ ] Latency tracing integration
350
+ - [ ] VS Code extension
351
+ - [ ] Kubernetes workload graph
352
+ - [ ] Infra drift detection
353
+
354
+ ---
355
+
356
+ ## Contributing
357
+
358
+ ### Prerequisites
359
+
360
+ | Requirement | Version |
361
+ |---|---|
362
+ | Node.js | 22+ |
363
+ | pnpm | 9+ |
364
+ | AWS CLI | any (for integration testing) |
365
+
366
+ ```bash
367
+ # Install pnpm if you don't have it
368
+ npm install -g pnpm
369
+ ```
370
+
371
+ ### Setup
372
+
373
+ ```bash
374
+ git clone https://github.com/Sidd27/infrawise
375
+ cd infrawise
376
+ pnpm install
377
+ pnpm build
378
+ ```
379
+
380
+ ### Development workflow
381
+
382
+ ```bash
383
+ pnpm build # build all packages
384
+ pnpm test # run all tests
385
+ pnpm typecheck # TypeScript strict check
386
+ pnpm lint # ESLint
387
+ ```
388
+
389
+ Tests live in:
390
+ - `packages/core/src/__tests__/` — config validation
391
+ - `packages/graph/src/__tests__/` — graph builder
392
+ - `packages/analyzers/src/__tests__/` — all 6 analyzers
393
+
394
+ ### Adding a new analyzer
395
+
396
+ 1. Create your analyzer in `packages/analyzers/src/`
397
+ 2. Implement the `Analyzer` interface:
398
+ ```ts
399
+ export class MyAnalyzer implements Analyzer {
400
+ name = 'MyAnalyzer';
401
+ async analyze(graph: SystemGraph): Promise<Finding[]> { ... }
402
+ }
403
+ ```
404
+ 3. Register it in `packages/analyzers/src/index.ts`
405
+ 4. Add tests in `packages/analyzers/src/__tests__/`
406
+
407
+ ### Adding a new database adapter
408
+
409
+ 1. Create a new package under `packages/adapters/yourdb/`
410
+ 2. Export a function returning `Promise<YourTableMetadata[]>`
411
+ 3. Extend `SystemGraph` node types in `@infrawise/shared` if needed
412
+ 4. Wire it into `packages/cli/src/commands/analyze.ts`
413
+
414
+ ### PR checklist
415
+
416
+ - `pnpm test` passes
417
+ - `pnpm typecheck` passes
418
+ - New analyzers have unit tests with mock graph data
419
+ - No hardcoded AWS regions or credentials
420
+
421
+ ---
422
+
423
+ ## License
424
+
425
+ MIT