Skip to content

Commit 87e293e

Browse files
committed
Release v0.9.0
0 parents  commit 87e293e

24 files changed

Lines changed: 2982 additions & 0 deletions

.github/workflows/publish.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: publish
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*"
7+
workflow_dispatch:
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: read
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@v4
17+
18+
- name: Set up Python
19+
uses: actions/setup-python@v5
20+
with:
21+
python-version: "3.11"
22+
23+
- name: Install uv
24+
uses: astral-sh/setup-uv@v4
25+
26+
- name: Build package
27+
run: uv build --no-sources
28+
29+
- name: Upload dist artifacts
30+
uses: actions/upload-artifact@v4
31+
with:
32+
name: dist
33+
path: dist/*
34+
35+
publish-pypi:
36+
needs: build
37+
runs-on: ubuntu-latest
38+
permissions:
39+
id-token: write
40+
environment:
41+
name: pypi
42+
url: https://pypi.org/p/sql-agent
43+
steps:
44+
- name: Download dist artifacts
45+
uses: actions/download-artifact@v4
46+
with:
47+
name: dist
48+
path: dist
49+
50+
- name: Publish to PyPI
51+
uses: pypa/gh-action-pypi-publish@release/v1

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.venv/
2+
__pycache__/
3+
*.pyc
4+
build/
5+
dist/
6+
tmp_smoke.db
7+
test-output/
8+
.test-output/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Paul
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.

README.md

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
# sql-agent
2+
3+
`sql-agent` is a read-only SQL CLI for agentic workflows.
4+
5+
It is designed to run safe, single-statement queries against configured database targets and return deterministic output that tools like Codex CLI and Claude Code can consume reliably.
6+
7+
V1 targets:
8+
9+
- MySQL
10+
- MariaDB
11+
- PostgreSQL
12+
- SQLite
13+
14+
## Status
15+
16+
This repo is currently spec-first and under active development.
17+
18+
The current behavior target is defined in [`spec.md`](./spec.md).
19+
20+
## Install and run
21+
22+
Local development:
23+
24+
```text
25+
uv run ./sql_agent.py --help
26+
uv run ./sql_agent.py "SELECT 1"
27+
```
28+
29+
Packaged command target:
30+
31+
```text
32+
uvx sql-agent --help
33+
sql-agent "SELECT 1"
34+
```
35+
36+
## Primary usage
37+
38+
Default target:
39+
40+
```text
41+
sql-agent "SELECT id, name FROM users LIMIT 10"
42+
```
43+
44+
Named target:
45+
46+
```text
47+
sql-agent --target reporting "SELECT COUNT(*) AS total FROM users"
48+
```
49+
50+
Explicit query flag:
51+
52+
```text
53+
sql-agent --target reporting --query "SELECT NOW()"
54+
```
55+
56+
SQL file:
57+
58+
```text
59+
sql-agent --target reporting --sql-file query.sql
60+
```
61+
62+
Stdin:
63+
64+
```text
65+
Get-Content query.sql | sql-agent --target reporting
66+
```
67+
68+
One-off SQLite query without config:
69+
70+
```text
71+
sql-agent --engine sqlite --path C:\data\app.db "SELECT * FROM customers LIMIT 5"
72+
```
73+
74+
## Auth
75+
76+
`sql-agent` is designed to prefer native client credential mechanisms over password arguments.
77+
78+
Supported v1 auth patterns:
79+
80+
- PostgreSQL: `PG*` environment variables and `.pgpass`
81+
- MySQL/MariaDB: option files such as `~/.my.cnf`
82+
- Generic fallback: `--password-stdin`
83+
- Optional human fallback: `--prompt-password`
84+
85+
`sql-agent` does not document or guarantee `MYSQL_PWD` as a public credential source.
86+
87+
### Bootstrap native auth files
88+
89+
Seed a PostgreSQL template:
90+
91+
```text
92+
sql-agent config init-native-auth --engine postgres
93+
sql-agent config init-native-auth --engine postgres --target reporting
94+
```
95+
96+
Seed a MySQL template:
97+
98+
```text
99+
sql-agent config init-native-auth --engine mysql
100+
sql-agent config init-native-auth --engine mysql --target dev
101+
```
102+
103+
When `--target NAME` is provided, the tool should prefill non-secret fields such as host, port, database, and user where possible, while leaving the password blank.
104+
105+
## Config
106+
107+
User config path:
108+
109+
```text
110+
~/.sql-agent/config.toml
111+
```
112+
113+
Example:
114+
115+
```toml
116+
[defaults]
117+
target = "dev"
118+
format = "json"
119+
max_rows = 200
120+
connect_timeout_seconds = 8
121+
query_timeout_seconds = 15
122+
123+
[targets.dev]
124+
engine = "mysql"
125+
host = "az-mysql-pub-sona-asia1-dev.mysql.database.azure.com"
126+
port = 3306
127+
database = "asiadev_2794"
128+
user = "paul"
129+
ssl_mode = "required"
130+
131+
[targets.reporting]
132+
engine = "postgres"
133+
host = "db.example.com"
134+
port = 5432
135+
database = "app"
136+
user = "report_reader"
137+
ssl_mode = "required"
138+
139+
[targets.local_sqlite]
140+
engine = "sqlite"
141+
path = "C:/data/app.db"
142+
```
143+
144+
Config commands:
145+
146+
```text
147+
sql-agent config show
148+
sql-agent config set-default-target NAME
149+
sql-agent config add-target NAME [options]
150+
sql-agent config remove-target NAME
151+
sql-agent config init-native-auth --engine postgres [--target NAME]
152+
sql-agent config init-native-auth --engine mysql [--target NAME]
153+
sql-agent targets
154+
```
155+
156+
`config show` should display effective target settings and credential-source hints without revealing secrets.
157+
158+
## Output
159+
160+
Supported formats:
161+
162+
- `json`
163+
- `markdown`
164+
- `table`
165+
- `csv`
166+
167+
Default format:
168+
169+
- `json`
170+
171+
Stdout is reserved for payload output. Diagnostics and errors go to stderr.
172+
173+
## Read-only guarantee
174+
175+
V1 is read-only by design.
176+
177+
Intended allowed statement classes include:
178+
179+
- `SELECT`
180+
- `WITH ... SELECT`
181+
- `SHOW`
182+
- `DESCRIBE` / `DESC`
183+
- `EXPLAIN`
184+
185+
The tool is intended to reject mutating or administrative statements before execution and to execute exactly one statement per invocation.
186+
187+
## SSL
188+
189+
Secure defaults are required by default for network databases.
190+
191+
Supported model:
192+
193+
- `--ssl-mode required`
194+
- `--ssl-mode preferred`
195+
- `--ssl-mode disabled`
196+
- `--insecure` as shorthand for `--ssl-mode preferred`
197+
198+
## Development direction
199+
200+
Implementation choices currently targeted by the spec:
201+
202+
- `PyMySQL[rsa]` for MySQL and MariaDB
203+
- `psycopg[binary]` for PostgreSQL
204+
- stdlib `sqlite3` for SQLite
205+
- `sqlglot` for parser-backed SQL validation
206+
207+
## License
208+
209+
MIT

pyproject.toml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
[build-system]
2+
requires = ["hatchling"]
3+
build-backend = "hatchling.build"
4+
5+
[project]
6+
name = "sql-agent"
7+
version = "0.9.0"
8+
description = "Read-only SQL CLI for agentic workflows"
9+
readme = "README.md"
10+
license = "MIT"
11+
requires-python = ">=3.11"
12+
authors = [
13+
{ name = "Paul" },
14+
]
15+
keywords = ["sql", "mysql", "postgresql", "sqlite", "cli", "agent"]
16+
classifiers = [
17+
"Development Status :: 4 - Beta",
18+
"Environment :: Console",
19+
"Intended Audience :: Developers",
20+
"License :: OSI Approved :: MIT License",
21+
"Operating System :: OS Independent",
22+
"Programming Language :: Python :: 3",
23+
"Programming Language :: Python :: 3.11",
24+
"Programming Language :: Python :: 3.12",
25+
"Programming Language :: Python :: 3.13",
26+
"Topic :: Database",
27+
"Topic :: Software Development :: Libraries :: Python Modules",
28+
"Topic :: Utilities",
29+
]
30+
dependencies = [
31+
"PyMySQL[rsa]>=1.1.0",
32+
"psycopg[binary]>=3.2.0",
33+
"sqlglot>=26.0.0",
34+
]
35+
36+
[project.urls]
37+
Homepage = "https://github.com/pseudosavant/sql-agent"
38+
Repository = "https://github.com/pseudosavant/sql-agent"
39+
Issues = "https://github.com/pseudosavant/sql-agent/issues"
40+
41+
[project.scripts]
42+
sql-agent = "sql_agent.cli:main"
43+
44+
[tool.hatch.build.targets.wheel]
45+
packages = ["src/sql_agent"]

0 commit comments

Comments
 (0)