@moduna/qcp 0.1.1-alpha.12
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/LICENSE +21 -0
- package/README.md +402 -0
- package/dist/index.js +98857 -0
- package/dist/qcp.js +98857 -0
- package/package.json +84 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Moduna AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# ◆ qcp — Query Companion
|
|
4
|
+
|
|
5
|
+
**AI-powered natural language interface for PostgreSQL**
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/qcp)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
[](https://github.com/Moduna-AI/qcp/actions)
|
|
10
|
+
|
|
11
|
+
Ask questions about your PostgreSQL database in plain English. Get safe, read-only SQL, results, and natural language summaries — all in your terminal.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
$ qcp ask "What were our top customers last month?"
|
|
15
|
+
|
|
16
|
+
Question:
|
|
17
|
+
What were our top customers last month?
|
|
18
|
+
|
|
19
|
+
Generated SQL:
|
|
20
|
+
SELECT c.name, SUM(o.total) AS revenue
|
|
21
|
+
FROM customers c
|
|
22
|
+
JOIN orders o ON c.id = o.customer_id
|
|
23
|
+
WHERE o.created_at >= date_trunc('month', NOW() - INTERVAL '1 month')
|
|
24
|
+
AND o.created_at < date_trunc('month', NOW())
|
|
25
|
+
GROUP BY c.name
|
|
26
|
+
ORDER BY revenue DESC
|
|
27
|
+
LIMIT 100
|
|
28
|
+
|
|
29
|
+
Safety:
|
|
30
|
+
✓ Read-only connection
|
|
31
|
+
✓ SELECT-only query
|
|
32
|
+
✓ LIMIT applied
|
|
33
|
+
✓ Query validated
|
|
34
|
+
|
|
35
|
+
Results:
|
|
36
|
+
┌──────────────────────┬───────────────┐
|
|
37
|
+
│ name │ revenue │
|
|
38
|
+
├──────────────────────┼───────────────┤
|
|
39
|
+
│ Acme Corporation │ 125432.00 │
|
|
40
|
+
│ TechCorp Inc │ 98765.00 │
|
|
41
|
+
└──────────────────────┴───────────────┘
|
|
42
|
+
2 row(s) · 48ms
|
|
43
|
+
|
|
44
|
+
Insight:
|
|
45
|
+
Acme Corporation led last month with $125,432 in revenue, followed closely
|
|
46
|
+
by TechCorp Inc at $98,765. Together they represent the top tier of customers.
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Why qcp?
|
|
54
|
+
|
|
55
|
+
Most data questions never get answered because they require SQL knowledge or data team availability. qcp bridges that gap — letting any developer or analyst query their PostgreSQL database using plain English, with full transparency into the generated SQL and a safety model that makes it impossible to accidentally modify data.
|
|
56
|
+
|
|
57
|
+
**Three principles:**
|
|
58
|
+
1. **Safety** — Read-only enforcement at the AST level. No string matching. Impossible to run INSERT, UPDATE, DELETE, or any write operation.
|
|
59
|
+
2. **Trust** — Every generated SQL query is shown before execution. You always know what ran against your database.
|
|
60
|
+
3. **Privacy** — No row data, schema metadata, SQL queries, or credentials are ever sent to telemetry. Your data stays yours.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Installation
|
|
65
|
+
|
|
66
|
+
### Homebrew (macOS/Linux)
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
brew tap Moduna-AI/qcp https://github.com/Moduna-AI/qcp
|
|
70
|
+
brew install qcp
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### curl (macOS/Linux)
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
curl -fsSL https://raw.githubusercontent.com/Moduna-AI/qcp/main/scripts/install.sh | sh
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### PowerShell (Windows)
|
|
80
|
+
|
|
81
|
+
```powershell
|
|
82
|
+
irm https://raw.githubusercontent.com/Moduna-AI/qcp/main/scripts/install.ps1 | iex
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### npm / pnpm / bun
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npm install -g qcp
|
|
89
|
+
pnpm add -g qcp
|
|
90
|
+
bun add -g qcp
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Quick Start
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# 1. Set up your AI provider (Gemini is the default — free tier available)
|
|
99
|
+
qcp auth
|
|
100
|
+
|
|
101
|
+
# 2. Connect to your PostgreSQL database
|
|
102
|
+
qcp connect postgres://readonly_user:password@localhost:5432/mydb
|
|
103
|
+
|
|
104
|
+
# 3. Index your schema (runs locally — no data leaves your machine)
|
|
105
|
+
qcp schema scan
|
|
106
|
+
|
|
107
|
+
# 4. Ask a question
|
|
108
|
+
qcp ask "Which products have the lowest inventory?"
|
|
109
|
+
|
|
110
|
+
# 5. Or start an interactive session
|
|
111
|
+
qcp chat
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Commands
|
|
117
|
+
|
|
118
|
+
### Core
|
|
119
|
+
|
|
120
|
+
| Command | Description |
|
|
121
|
+
|---|---|
|
|
122
|
+
| `qcp auth` | Interactive wizard to configure your AI provider |
|
|
123
|
+
| `qcp init` | Initialize qcp config and local project files |
|
|
124
|
+
| `qcp connect <url>` | Connect to a PostgreSQL database |
|
|
125
|
+
| `qcp schema scan` | Index the database schema locally |
|
|
126
|
+
| `qcp ask "<question>"` | Query your database in plain English |
|
|
127
|
+
| `qcp chat` | Start interactive multi-question session |
|
|
128
|
+
| `qcp explain "<question>"` | Generate SQL without executing it |
|
|
129
|
+
| `qcp doctor` | Run system diagnostics |
|
|
130
|
+
|
|
131
|
+
### Model Management
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
qcp model list # List all providers and models
|
|
135
|
+
qcp model set gemini # Switch to Gemini (default)
|
|
136
|
+
qcp model set gemini-2.5-pro # Use a specific model
|
|
137
|
+
qcp model set openai # Switch to OpenAI
|
|
138
|
+
qcp model set gpt-4o-mini
|
|
139
|
+
qcp model set anthropic # Switch to Anthropic
|
|
140
|
+
qcp model set ollama # Local models via Ollama
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Configuration
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
qcp config show # View current settings
|
|
147
|
+
qcp config set safeMode true # Require approval for sensitive queries
|
|
148
|
+
qcp config set showSql false # Hide generated SQL
|
|
149
|
+
qcp config set showMetrics true # Always show token/timing metrics
|
|
150
|
+
qcp config set-key gemini AIza... # Save API key
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Diagnostics
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
qcp doctor # Human-readable health report
|
|
157
|
+
qcp doctor --json # Machine-readable JSON output
|
|
158
|
+
qcp doctor --bundle # Create support bundle (no credentials)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### ask options
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
qcp ask "question" --metrics # Show token counts and latency
|
|
165
|
+
qcp ask "question" --verbose # Show generation details
|
|
166
|
+
qcp ask "question" --debug # Show raw LLM output and EXPLAIN plan
|
|
167
|
+
qcp ask "question" --yes # Skip approval prompts
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Supported Providers
|
|
173
|
+
|
|
174
|
+
| Provider | Default Model | API Key |
|
|
175
|
+
|---|---|---|
|
|
176
|
+
| **Gemini** (default) | `gemini-2.5-flash` | [Google AI Studio](https://aistudio.google.com/app/apikey) |
|
|
177
|
+
| **OpenAI** | `gpt-4o` | [OpenAI Platform](https://platform.openai.com/api-keys) |
|
|
178
|
+
| **Anthropic** | `claude-opus-4-5` | [Anthropic Console](https://console.anthropic.com) |
|
|
179
|
+
| **Ollama** | `qwen3` | No key needed (local) |
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Safety Model
|
|
184
|
+
|
|
185
|
+
qcp enforces read-only access at **two independent layers**:
|
|
186
|
+
|
|
187
|
+
### 1. SQL Safety (AST-based)
|
|
188
|
+
|
|
189
|
+
Every generated SQL is parsed into an Abstract Syntax Tree and validated before execution. This is **not string matching** — it's a structural parse of the SQL.
|
|
190
|
+
|
|
191
|
+
**Allowed:** `SELECT`, `WITH` (CTEs), `EXPLAIN`
|
|
192
|
+
|
|
193
|
+
**Rejected:** `INSERT`, `UPDATE`, `DELETE`, `DROP`, `ALTER`, `TRUNCATE`, `CREATE`, `GRANT`, `REVOKE`, `COPY`
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
# What happens with a dangerous query
|
|
197
|
+
$ qcp ask "delete all users"
|
|
198
|
+
|
|
199
|
+
Safety:
|
|
200
|
+
✗ SELECT-only query
|
|
201
|
+
✗ Dangerous operation rejected: DELETE is not permitted.
|
|
202
|
+
qcp is read-only and only allows SELECT, WITH, and EXPLAIN.
|
|
203
|
+
|
|
204
|
+
✗ Query rejected — does not meet safety requirements.
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### 2. Transaction-level enforcement
|
|
208
|
+
|
|
209
|
+
All queries run inside a `BEGIN READ ONLY` transaction. Even if the safety parser were somehow bypassed, the database itself would reject any write operation.
|
|
210
|
+
|
|
211
|
+
### 3. Human-in-the-loop approval
|
|
212
|
+
|
|
213
|
+
When `safeMode` is enabled (default), qcp prompts for confirmation before executing queries that:
|
|
214
|
+
- Access potentially sensitive tables (`users`, `customers`, `payments`, etc.)
|
|
215
|
+
- Scan an estimated large number of rows
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
⚠ Potentially sensitive query detected
|
|
219
|
+
Reasons:
|
|
220
|
+
• Query accesses potentially sensitive tables: customers
|
|
221
|
+
• Estimated 5,200,000 rows scanned
|
|
222
|
+
|
|
223
|
+
? Execute this query? (y/N)
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Privacy Model
|
|
229
|
+
|
|
230
|
+
### What qcp sends to telemetry (PostHog)
|
|
231
|
+
|
|
232
|
+
- qcp version
|
|
233
|
+
- Operating system and CPU architecture
|
|
234
|
+
- Which commands you run
|
|
235
|
+
- Error event types (not error content)
|
|
236
|
+
|
|
237
|
+
### What qcp NEVER sends
|
|
238
|
+
|
|
239
|
+
- SQL queries or query results
|
|
240
|
+
- Database connection URLs or credentials
|
|
241
|
+
- Schema metadata (table/column names)
|
|
242
|
+
- API keys or tokens
|
|
243
|
+
- Any row data from your database
|
|
244
|
+
|
|
245
|
+
Disable telemetry at any time:
|
|
246
|
+
```bash
|
|
247
|
+
qcp telemetry off
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Schema scanning
|
|
251
|
+
|
|
252
|
+
`qcp schema scan` reads **structure only** — table names, column names, types, and relationships. It never reads row data. The schema is stored locally in `.qcp/schema.json` and never sent to any external service.
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## Configuration
|
|
257
|
+
|
|
258
|
+
Settings are stored in `~/.qcp/config.json`.
|
|
259
|
+
|
|
260
|
+
```json
|
|
261
|
+
{
|
|
262
|
+
"provider": "gemini",
|
|
263
|
+
"model": "gemini-2.5-flash",
|
|
264
|
+
"safeMode": true,
|
|
265
|
+
"showSql": true,
|
|
266
|
+
"showMetrics": false,
|
|
267
|
+
"telemetry": true,
|
|
268
|
+
"sensitiveTablePatterns": ["user", "customer", "payment", "billing"]
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Environment variables
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
QCP_DATABASE_URL=postgres://... # Database connection URL
|
|
276
|
+
GEMINI_API_KEY=AIza... # Gemini API key
|
|
277
|
+
OPENAI_API_KEY=sk-... # OpenAI API key
|
|
278
|
+
ANTHROPIC_API_KEY=sk-ant-... # Anthropic API key
|
|
279
|
+
OLLAMA_HOST=http://localhost:11434 # Ollama server URL
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## Local Development
|
|
285
|
+
|
|
286
|
+
### Prerequisites
|
|
287
|
+
|
|
288
|
+
- [Bun](https://bun.sh) ≥ 1.1.0
|
|
289
|
+
- Node.js ≥ 18 (for npm distribution)
|
|
290
|
+
- A PostgreSQL database for testing
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
# Clone
|
|
294
|
+
git clone https://github.com/Moduna-AI/qcp
|
|
295
|
+
cd qcp
|
|
296
|
+
|
|
297
|
+
# Install dependencies
|
|
298
|
+
bun install
|
|
299
|
+
|
|
300
|
+
# Run in dev mode
|
|
301
|
+
bun run dev -- ask "show me all tables"
|
|
302
|
+
|
|
303
|
+
# Run tests
|
|
304
|
+
bun test
|
|
305
|
+
|
|
306
|
+
# Build Node.js bundle
|
|
307
|
+
bun run build
|
|
308
|
+
|
|
309
|
+
# Build self-contained binary
|
|
310
|
+
bun run build:binary
|
|
311
|
+
|
|
312
|
+
# Type check
|
|
313
|
+
bun run lint
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Project Structure
|
|
317
|
+
|
|
318
|
+
```
|
|
319
|
+
src/
|
|
320
|
+
cli/ CLI entry point (Commander.js)
|
|
321
|
+
commands/ One file per command
|
|
322
|
+
config/ Config read/write + paths
|
|
323
|
+
db/ PostgreSQL connection (postgres.js)
|
|
324
|
+
llm/ LLM provider abstraction + streaming
|
|
325
|
+
safety/ AST-based SQL validation
|
|
326
|
+
schema/ Schema introspection + context builder
|
|
327
|
+
telemetry/ PostHog (privacy-safe)
|
|
328
|
+
logger/ Winston file logger
|
|
329
|
+
output/ Terminal formatting (chalk, cli-table3)
|
|
330
|
+
types/ TypeScript interfaces
|
|
331
|
+
tests/
|
|
332
|
+
safety.test.ts SQL safety validation tests
|
|
333
|
+
schema.test.ts Schema context tests
|
|
334
|
+
Formula/
|
|
335
|
+
qcp.rb Homebrew formula
|
|
336
|
+
scripts/
|
|
337
|
+
install.sh curl installer (Linux/macOS)
|
|
338
|
+
install.ps1 PowerShell installer (Windows)
|
|
339
|
+
.github/workflows/
|
|
340
|
+
ci.yml Test + build on push/PR
|
|
341
|
+
release.yml Binary build + GitHub Release + npm publish
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## Local Homebrew Testing
|
|
347
|
+
|
|
348
|
+
To test the Homebrew formula before publishing a release:
|
|
349
|
+
|
|
350
|
+
```bash
|
|
351
|
+
# Build binary
|
|
352
|
+
make build-binary
|
|
353
|
+
|
|
354
|
+
# Tap from local path
|
|
355
|
+
brew tap Moduna-AI/qcp "$(pwd)"
|
|
356
|
+
|
|
357
|
+
# Install HEAD (builds from source)
|
|
358
|
+
brew install --HEAD Moduna-AI/qcp/qcp
|
|
359
|
+
|
|
360
|
+
# Verify
|
|
361
|
+
qcp --version
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|
|
366
|
+
## Contributing
|
|
367
|
+
|
|
368
|
+
Contributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) first.
|
|
369
|
+
|
|
370
|
+
**Key guidelines:**
|
|
371
|
+
- Safety is non-negotiable. The SQL safety module must remain AST-based.
|
|
372
|
+
- No write operations can ever be executed under any circumstances.
|
|
373
|
+
- No sensitive data (SQL, DB URLs, schema, API keys) in telemetry.
|
|
374
|
+
- All PRs must pass `bun test` and `bun run lint`.
|
|
375
|
+
|
|
376
|
+
```bash
|
|
377
|
+
# Run all checks before submitting a PR
|
|
378
|
+
bun test
|
|
379
|
+
bun run lint
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
## Releasing (maintainers)
|
|
385
|
+
|
|
386
|
+
```bash
|
|
387
|
+
# Create and push a version tag
|
|
388
|
+
git tag v0.1.1
|
|
389
|
+
git push origin v0.1.1
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
This triggers the release workflow which:
|
|
393
|
+
1. Builds binaries for all 5 platforms
|
|
394
|
+
2. Creates a GitHub Release with artifacts and checksums
|
|
395
|
+
3. Updates the Homebrew formula SHA256 automatically
|
|
396
|
+
4. Publishes to npm
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
## License
|
|
401
|
+
|
|
402
|
+
[MIT](LICENSE) © Moduna AI
|