sql-harness 0.1.0__tar.gz
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.
- sql_harness-0.1.0/.claude-plugin/marketplace.json +26 -0
- sql_harness-0.1.0/.claude-plugin/plugin.json +13 -0
- sql_harness-0.1.0/.env.example +20 -0
- sql_harness-0.1.0/.github/ISSUE_TEMPLATE/bug-report.yml +49 -0
- sql_harness-0.1.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
- sql_harness-0.1.0/.github/ISSUE_TEMPLATE/feature-request.yml +37 -0
- sql_harness-0.1.0/.gitignore +34 -0
- sql_harness-0.1.0/AGENTS.md +37 -0
- sql_harness-0.1.0/PKG-INFO +137 -0
- sql_harness-0.1.0/README.md +114 -0
- sql_harness-0.1.0/SKILL.md +61 -0
- sql_harness-0.1.0/agent-workspace/README.md +42 -0
- sql_harness-0.1.0/agent-workspace/agent_helpers.example.py +124 -0
- sql_harness-0.1.0/agent-workspace/agent_helpers.py +14 -0
- sql_harness-0.1.0/agent-workspace/skills/pool.md +43 -0
- sql_harness-0.1.0/agent-workspace/skills/ssh.md +89 -0
- sql_harness-0.1.0/agent-workspace/skills/workspace.md +58 -0
- sql_harness-0.1.0/agent-workspace/zones/example_pg/scripts/sh_demo_crud.py +114 -0
- sql_harness-0.1.0/agent-workspace/zones/example_pg/skills/sh_demo-schema.md +106 -0
- sql_harness-0.1.0/docs/connections-toml-example.toml +74 -0
- sql_harness-0.1.0/docs/headless-notes.md +78 -0
- sql_harness-0.1.0/docs/maintainer.md +60 -0
- sql_harness-0.1.0/docs/standalone-install.md +167 -0
- sql_harness-0.1.0/install.md +77 -0
- sql_harness-0.1.0/interaction-skills/aggregations.md +105 -0
- sql_harness-0.1.0/interaction-skills/encoding-and-charset.md +34 -0
- sql_harness-0.1.0/interaction-skills/indexes-and-explain.md +61 -0
- sql_harness-0.1.0/interaction-skills/joins.md +123 -0
- sql_harness-0.1.0/interaction-skills/json-columns.md +30 -0
- sql_harness-0.1.0/interaction-skills/large-result-sets.md +28 -0
- sql_harness-0.1.0/interaction-skills/migrations.md +32 -0
- sql_harness-0.1.0/interaction-skills/pooling.md +51 -0
- sql_harness-0.1.0/interaction-skills/postgres/btree-indexes.md +92 -0
- sql_harness-0.1.0/interaction-skills/postgres/plan-reading.md +68 -0
- sql_harness-0.1.0/interaction-skills/postgres/slow-queries-joins.md +99 -0
- sql_harness-0.1.0/interaction-skills/postgres/specialized-indexes.md +97 -0
- sql_harness-0.1.0/interaction-skills/postgres/table-optimization.md +104 -0
- sql_harness-0.1.0/interaction-skills/recursive-ctes.md +97 -0
- sql_harness-0.1.0/interaction-skills/save-run-cycle.md +138 -0
- sql_harness-0.1.0/interaction-skills/schema-introspection.md +48 -0
- sql_harness-0.1.0/interaction-skills/ssh.md +96 -0
- sql_harness-0.1.0/interaction-skills/timeouts-and-cancellation.md +64 -0
- sql_harness-0.1.0/interaction-skills/transactions.md +57 -0
- sql_harness-0.1.0/interaction-skills/window-functions.md +104 -0
- sql_harness-0.1.0/interaction-skills/zone-skill-auto-surface.md +138 -0
- sql_harness-0.1.0/pyproject.toml +58 -0
- sql_harness-0.1.0/skills/sql-harness/README.txt +8 -0
- sql_harness-0.1.0/skills/sql-harness/SKILL.md +1 -0
- sql_harness-0.1.0/skills/sql-harness/references/install.md +93 -0
- sql_harness-0.1.0/sql-harness +34 -0
- sql_harness-0.1.0/src/sql_harness/SKILL.md +61 -0
- sql_harness-0.1.0/src/sql_harness/__init__.py +27 -0
- sql_harness-0.1.0/src/sql_harness/agent_loader.py +55 -0
- sql_harness-0.1.0/src/sql_harness/cli.py +869 -0
- sql_harness-0.1.0/src/sql_harness/config.py +241 -0
- sql_harness-0.1.0/src/sql_harness/drivers/__init__.py +59 -0
- sql_harness-0.1.0/src/sql_harness/drivers/mysql.py +43 -0
- sql_harness-0.1.0/src/sql_harness/drivers/postgres.py +55 -0
- sql_harness-0.1.0/src/sql_harness/drivers/redis.py +33 -0
- sql_harness-0.1.0/src/sql_harness/drivers/sqlite.py +39 -0
- sql_harness-0.1.0/src/sql_harness/drivers/ssh.py +293 -0
- sql_harness-0.1.0/src/sql_harness/helpers.py +789 -0
- sql_harness-0.1.0/src/sql_harness/manager.py +122 -0
- sql_harness-0.1.0/src/sql_harness/paths.py +112 -0
- sql_harness-0.1.0/src/sql_harness/run.py +85 -0
- sql_harness-0.1.0/tests/__init__.py +0 -0
- sql_harness-0.1.0/tests/conftest.py +19 -0
- sql_harness-0.1.0/tests/integration/__init__.py +0 -0
- sql_harness-0.1.0/tests/integration/test_mysql.py +40 -0
- sql_harness-0.1.0/tests/integration/test_pg_optimization.py +144 -0
- sql_harness-0.1.0/tests/integration/test_pgexercises_practice.py +62 -0
- sql_harness-0.1.0/tests/integration/test_postgres.py +68 -0
- sql_harness-0.1.0/tests/integration/test_ssh.py +56 -0
- sql_harness-0.1.0/tests/unit/__init__.py +0 -0
- sql_harness-0.1.0/tests/unit/test_agent_loader.py +48 -0
- sql_harness-0.1.0/tests/unit/test_cli.py +222 -0
- sql_harness-0.1.0/tests/unit/test_config.py +142 -0
- sql_harness-0.1.0/tests/unit/test_helpers.py +196 -0
- sql_harness-0.1.0/tests/unit/test_manager.py +91 -0
- sql_harness-0.1.0/tests/unit/test_paths.py +51 -0
- sql_harness-0.1.0/tests/unit/test_ssh.py +54 -0
- sql_harness-0.1.0/uv.lock +474 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sql-harness",
|
|
3
|
+
"description": "Install sql-harness skills directly from this repo.",
|
|
4
|
+
"owner": {
|
|
5
|
+
"name": "much-bigpy",
|
|
6
|
+
"url": "https://github.com/zhaoliuxue"
|
|
7
|
+
},
|
|
8
|
+
"plugins": [
|
|
9
|
+
{
|
|
10
|
+
"name": "sql-harness",
|
|
11
|
+
"description": "Direct SQL access for agents: query, execute, schema inspection, transactions across PostgreSQL and MySQL. Plaintext credentials in one TOML file; auto-imported helpers. Ships skills only; the `sql-harness` CLI is a one-time `uv sync` install prerequisite.",
|
|
12
|
+
"category": "automation",
|
|
13
|
+
"source": ".",
|
|
14
|
+
"homepage": "https://github.com/zhaoliuxue/much_bigpy",
|
|
15
|
+
"keywords": [
|
|
16
|
+
"sql",
|
|
17
|
+
"postgres",
|
|
18
|
+
"mysql",
|
|
19
|
+
"redis",
|
|
20
|
+
"agent",
|
|
21
|
+
"automation",
|
|
22
|
+
"database"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sql-harness",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Single-process SQL CLI for LLM agents. Drives PostgreSQL, MySQL (and Redis soon) via SQLAlchemy engines, with auto-imported Python helpers and plaintext credentials in one TOML file. Requires the one-time `uv sync` install (see the skill's references/install.md).",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "much-bigpy",
|
|
7
|
+
"url": "https://github.com/zhaoliuxue"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/zhaoliuxue/much_bigpy",
|
|
10
|
+
"repository": "https://github.com/zhaoliuxue/much_bigpy",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"keywords": ["sql", "postgres", "mysql", "redis", "agent", "cli", "automation", "database"]
|
|
13
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Copy to .env — auto-loaded. Only needed for integration tests.
|
|
2
|
+
#
|
|
3
|
+
# sql-harness does NOT use an API key. Instead, prod secrets live in
|
|
4
|
+
# connections.toml via ${env:VAR} indirection, e.g.:
|
|
5
|
+
#
|
|
6
|
+
# [[connections]]
|
|
7
|
+
# name = "prod_pg"
|
|
8
|
+
# driver = "postgres"
|
|
9
|
+
# url = "${env:PROD_PG_URL}"
|
|
10
|
+
#
|
|
11
|
+
# Set these env vars (here or in your shell) for integration tests.
|
|
12
|
+
|
|
13
|
+
# PostgreSQL integration test target.
|
|
14
|
+
BH_PG_URL=postgresql://postgres:postgres@localhost:5432/postgres
|
|
15
|
+
|
|
16
|
+
# MySQL integration test target.
|
|
17
|
+
BH_MYSQL_URL=mysql+pymysql://root:root@localhost:3306/mysql?charset=utf8mb4
|
|
18
|
+
|
|
19
|
+
# Example prod secret referenced via ${env:PROD_PG_URL} in connections.toml.
|
|
20
|
+
# PROD_PG_URL=postgresql://user:pw@prod-host:5432/db
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report a reproducible bug in sql-harness.
|
|
3
|
+
labels: [bug]
|
|
4
|
+
body:
|
|
5
|
+
- type: checkboxes
|
|
6
|
+
id: preflight
|
|
7
|
+
attributes:
|
|
8
|
+
label: Before submitting
|
|
9
|
+
options:
|
|
10
|
+
- label: I searched existing issues for duplicates.
|
|
11
|
+
required: true
|
|
12
|
+
- label: I ran `sql-harness doctor` and read the output.
|
|
13
|
+
required: true
|
|
14
|
+
- label: I read the troubleshooting section of `install.md`.
|
|
15
|
+
required: true
|
|
16
|
+
- label: This is a reproducible bug in sql-harness — not a question, feature request, or connection-config problem.
|
|
17
|
+
required: true
|
|
18
|
+
|
|
19
|
+
- type: textarea
|
|
20
|
+
id: summary
|
|
21
|
+
attributes:
|
|
22
|
+
label: Summary
|
|
23
|
+
description: What's broken, in one or two sentences.
|
|
24
|
+
validations:
|
|
25
|
+
required: true
|
|
26
|
+
|
|
27
|
+
- type: textarea
|
|
28
|
+
id: repro
|
|
29
|
+
attributes:
|
|
30
|
+
label: Repro
|
|
31
|
+
description: Numbered steps. Include the exact command, the full output, and the driver being used.
|
|
32
|
+
placeholder: |
|
|
33
|
+
1. PostgreSQL 17, localhost:5432
|
|
34
|
+
2. sql-harness test my_pg
|
|
35
|
+
3. ConnectionError: password authentication failed
|
|
36
|
+
validations:
|
|
37
|
+
required: true
|
|
38
|
+
|
|
39
|
+
- type: textarea
|
|
40
|
+
id: environment
|
|
41
|
+
attributes:
|
|
42
|
+
label: Environment
|
|
43
|
+
placeholder: |
|
|
44
|
+
OS:
|
|
45
|
+
Database version (PG/MySQL/Redis):
|
|
46
|
+
sql-harness --version:
|
|
47
|
+
sql-harness doctor output:
|
|
48
|
+
validations:
|
|
49
|
+
required: true
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Question or how-to
|
|
4
|
+
url: https://github.com/zhaoliuxue/much_bigpy/discussions
|
|
5
|
+
about: Ask in Discussions, not Issues.
|
|
6
|
+
- name: Install or setup troubleshooting
|
|
7
|
+
url: https://github.com/zhaoliuxue/much_bigpy/blob/main/lab/sql_harness/install.md
|
|
8
|
+
about: Most connection and config errors are covered here.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Propose a new feature or change.
|
|
3
|
+
labels: [feature-request]
|
|
4
|
+
body:
|
|
5
|
+
- type: checkboxes
|
|
6
|
+
id: preflight
|
|
7
|
+
attributes:
|
|
8
|
+
label: Before submitting
|
|
9
|
+
options:
|
|
10
|
+
- label: I searched existing issues and discussions.
|
|
11
|
+
required: true
|
|
12
|
+
- label: This is a feature request, not a bug.
|
|
13
|
+
required: true
|
|
14
|
+
|
|
15
|
+
- type: textarea
|
|
16
|
+
id: problem
|
|
17
|
+
attributes:
|
|
18
|
+
label: Problem
|
|
19
|
+
description: What user pain or limitation motivates this? (Missing driver? Connection pain? Missing skill?)
|
|
20
|
+
validations:
|
|
21
|
+
required: true
|
|
22
|
+
|
|
23
|
+
- type: textarea
|
|
24
|
+
id: proposal
|
|
25
|
+
attributes:
|
|
26
|
+
label: Proposal
|
|
27
|
+
description: What you'd like to happen.
|
|
28
|
+
validations:
|
|
29
|
+
required: true
|
|
30
|
+
|
|
31
|
+
- type: textarea
|
|
32
|
+
id: alternatives
|
|
33
|
+
attributes:
|
|
34
|
+
label: Alternatives considered
|
|
35
|
+
description: What else you tried, or why other approaches fall short.
|
|
36
|
+
validations:
|
|
37
|
+
required: true
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
|
|
7
|
+
# Build / dist
|
|
8
|
+
build/
|
|
9
|
+
dist/
|
|
10
|
+
*.egg-info/
|
|
11
|
+
.eggs/
|
|
12
|
+
|
|
13
|
+
# Virtual envs
|
|
14
|
+
.venv/
|
|
15
|
+
venv/
|
|
16
|
+
.tool-venv/
|
|
17
|
+
|
|
18
|
+
# Test / coverage
|
|
19
|
+
.pytest_cache/
|
|
20
|
+
.coverage
|
|
21
|
+
htmlcov/
|
|
22
|
+
|
|
23
|
+
# IDE
|
|
24
|
+
.vscode/
|
|
25
|
+
.idea/
|
|
26
|
+
*.swp
|
|
27
|
+
|
|
28
|
+
# OS
|
|
29
|
+
.DS_Store
|
|
30
|
+
Thumbs.db
|
|
31
|
+
|
|
32
|
+
# Secrets (the connections.toml at runtime can have real DSNs; never commit)
|
|
33
|
+
.env
|
|
34
|
+
*.env.local
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
browser-harness is a thin layer that connects agents to browsers via a CDP daemon.
|
|
2
|
+
sql-harness is the same idea for SQL — connects agents to relational databases via SQLAlchemy engines. Single-process; no daemon.
|
|
3
|
+
|
|
4
|
+
# Code priorities
|
|
5
|
+
- Clarity
|
|
6
|
+
- Precision
|
|
7
|
+
- Low verbosity
|
|
8
|
+
- Versatility
|
|
9
|
+
|
|
10
|
+
# Overview
|
|
11
|
+
Core code lives in `lab/sql_harness/src/sql_harness/` (src-layout, mirrors browser-harness's `src/browser_harness/`):
|
|
12
|
+
- `config.py` — TOML schema + ConnectionConfig / ConnectionsConfig dataclasses
|
|
13
|
+
- `paths.py` — XDG-style state directory resolution (mirrors browser-harness paths.py)
|
|
14
|
+
- `drivers/` — backend abstractions (postgres, mysql, redis stub, sqlite for tests)
|
|
15
|
+
- `manager.py` — SqlHarness class: holds engines, workspaces, skills registry
|
|
16
|
+
- `helpers.py` — heredoc helpers (auto-imported)
|
|
17
|
+
- `agent_loader.py` — loads `$BH_SQL_AGENT_WORKSPACE/agent_helpers.py` (mirrors browser-harness helpers.py:493-508)
|
|
18
|
+
- `run.py` — heredoc entry; delegates to CLI otherwise
|
|
19
|
+
- `cli.py` — argparse subparser CLI (~10 subcommands)
|
|
20
|
+
|
|
21
|
+
`SKILL.md` tells agents how to use the harness.
|
|
22
|
+
`install.md` tells agents how to install and configure it.
|
|
23
|
+
|
|
24
|
+
An agent operating the harness only edits inside `agent-workspace/`:
|
|
25
|
+
- `agent_helpers.py` — task-specific query helpers the agent adds
|
|
26
|
+
- `skills/<name>.md` — per-task or per-table knowledge the agent writes/reads
|
|
27
|
+
|
|
28
|
+
# Contributing
|
|
29
|
+
Consider what is really needed. Prefer the smallest diff that fixes the bug.
|
|
30
|
+
|
|
31
|
+
# Driver extension
|
|
32
|
+
To add a new backend (Redis is the obvious next target):
|
|
33
|
+
1. Add the package to `pyproject.toml` via `uv add <pkg>`.
|
|
34
|
+
2. Create `drivers/<name>.py` implementing the `Driver` protocol (see `drivers/__init__.py`).
|
|
35
|
+
3. Register it in `drivers/__init__.py:get_driver()`.
|
|
36
|
+
4. Add a unit test in `tests/unit/test_<name>.py`.
|
|
37
|
+
5. Optionally add an integration test in `tests/integration/test_<name>.py` gated on `BH_<NAME>_URL`.
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sql-harness
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Single-process SQL + SSH CLI for LLM agents. PostgreSQL/MySQL/SSH via SQLAlchemy + paramiko. Plaintext credentials in one TOML file. Helpers auto-injected into the heredoc namespace.
|
|
5
|
+
Project-URL: Source, https://github.com/zhaoliuxue/much_bigpy/tree/master/lab/sql_harness
|
|
6
|
+
Project-URL: Issues, https://github.com/zhaoliuxue/much_bigpy/issues
|
|
7
|
+
Author: much-bigpy
|
|
8
|
+
License: MIT
|
|
9
|
+
Keywords: agent,cli,database,heredoc,mysql,postgres,sql,ssh
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Topic :: Database
|
|
16
|
+
Classifier: Topic :: System :: Shells
|
|
17
|
+
Requires-Python: >=3.12
|
|
18
|
+
Requires-Dist: paramiko<4,>=3.4
|
|
19
|
+
Requires-Dist: psycopg[binary]<4,>=3.2
|
|
20
|
+
Requires-Dist: pymysql<2,>=1.1
|
|
21
|
+
Requires-Dist: sqlalchemy<3,>=2.0
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# sql-harness
|
|
25
|
+
|
|
26
|
+
A thin, single-process SQL CLI for LLM agents. Mirrors [browser-harness](https://github.com/browser-use/browser-harness)'s structure but targets relational databases (Postgres, MySQL, Redis-soon).
|
|
27
|
+
|
|
28
|
+
## Quickstart
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# 1. Install deps (one-time)
|
|
32
|
+
uv sync
|
|
33
|
+
|
|
34
|
+
# 2. Scaffold a starter connections.toml
|
|
35
|
+
uv run sql-harness init
|
|
36
|
+
|
|
37
|
+
# 3. Add a connection
|
|
38
|
+
uv run sql-harness add local_pg --driver postgres --url 'postgresql://postgres:postgres@localhost:5432/postgres'
|
|
39
|
+
|
|
40
|
+
# 4. Test it
|
|
41
|
+
uv run sql-harness test local_pg
|
|
42
|
+
|
|
43
|
+
# 5. Use it
|
|
44
|
+
uv run sql-harness <<'PY'
|
|
45
|
+
use_workspace("local_pg")
|
|
46
|
+
print(query("SELECT version()"))
|
|
47
|
+
print(list_tables())
|
|
48
|
+
print(describe("pg_class"))
|
|
49
|
+
PY
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Architecture (~1k lines across 8 core files)
|
|
53
|
+
|
|
54
|
+
- `install.md` — first-time install + first connection
|
|
55
|
+
- `SKILL.md` — day-to-day usage
|
|
56
|
+
- `lab/sql_harness/src/sql_harness/` — protected core package (src-layout, mirrors browser-harness)
|
|
57
|
+
- `${XDG_CONFIG_HOME:-~/.config}/sql-harness/connections.toml` — plaintext credentials in ONE place
|
|
58
|
+
- `${XDG_CONFIG_HOME:-~/.config}/sql-harness/agent-workspace/agent_helpers.py` — task-specific helpers
|
|
59
|
+
- `${XDG_CONFIG_HOME:-~/.config}/sql-harness/agent-workspace/skills/` — per-task/per-table skills
|
|
60
|
+
|
|
61
|
+
## Why mirror browser-harness?
|
|
62
|
+
|
|
63
|
+
- Same operational ergonomics for agents: heredoc CLI with auto-imported helpers.
|
|
64
|
+
- Same agent-workspace pattern (helpers + skills stay editable per-project).
|
|
65
|
+
- Same path/state layout (XDG-style state directory).
|
|
66
|
+
- Same doc layering: `SKILL.md` body + `interaction-skills/*.md` for stuck points.
|
|
67
|
+
|
|
68
|
+
## What this is NOT
|
|
69
|
+
|
|
70
|
+
- Not a database migration framework.
|
|
71
|
+
- Not an ORM.
|
|
72
|
+
- Not a connection-string parser (`pgcli`/`mycli` already exist for interactive REPL use; this is for *agents*).
|
|
73
|
+
- Not a long-running daemon. SQL connections don't need one.
|
|
74
|
+
|
|
75
|
+
## Connection file format
|
|
76
|
+
|
|
77
|
+
Default: `${XDG_CONFIG_HOME:-~/.config}/sql-harness/connections.toml`.
|
|
78
|
+
|
|
79
|
+
```toml
|
|
80
|
+
default_workspace = "local_pg"
|
|
81
|
+
|
|
82
|
+
[pool_defaults]
|
|
83
|
+
size = 5
|
|
84
|
+
recycle = 3600
|
|
85
|
+
pre_ping = true
|
|
86
|
+
echo = false
|
|
87
|
+
|
|
88
|
+
[[connections]]
|
|
89
|
+
name = "local_pg"
|
|
90
|
+
driver = "postgres"
|
|
91
|
+
url = "postgresql+psycopg://postgres:postgres@localhost:5432/postgres"
|
|
92
|
+
description = "Local PostgreSQL for dev"
|
|
93
|
+
|
|
94
|
+
[[connections]]
|
|
95
|
+
name = "prod_pg"
|
|
96
|
+
driver = "postgres"
|
|
97
|
+
url = "${env:PROD_PG_URL}" # env-var indirection
|
|
98
|
+
pool_size = 10
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Use `${env:VAR}` placeholders inside `url` for prod secrets — they're expanded at load time from the process environment.
|
|
102
|
+
|
|
103
|
+
## Configuration env vars
|
|
104
|
+
|
|
105
|
+
| Var | Purpose |
|
|
106
|
+
|---|---|
|
|
107
|
+
| `BH_SQL_HOME` | Override state root (`~/.config/sql-harness` by default) |
|
|
108
|
+
| `BH_SQL_CONFIG_FILE` | Override connections.toml path |
|
|
109
|
+
| `BH_SQL_AGENT_WORKSPACE` | Override agent-workspace directory |
|
|
110
|
+
| `BH_SQL_RUNTIME_DIR` | Override runtime state dir |
|
|
111
|
+
| `BH_SQL_TMP_DIR` | Override temp dir |
|
|
112
|
+
| `BH_PG_URL` | Used by integration tests (skipped if unset) |
|
|
113
|
+
| `BH_MYSQL_URL` | Used by integration tests (skipped if unset) |
|
|
114
|
+
|
|
115
|
+
## Drivers
|
|
116
|
+
|
|
117
|
+
| Driver | Backend | Package | Status |
|
|
118
|
+
|---|---|---|---|
|
|
119
|
+
| `postgres` | PostgreSQL | `psycopg[binary]>=3.2` | ✅ |
|
|
120
|
+
| `mysql` | MySQL | `pymysql>=1.1` | ✅ |
|
|
121
|
+
| `redis` | Redis | `redis>=5.0` (not yet added) | 🚧 stub |
|
|
122
|
+
| `sqlite` | SQLite | stdlib (`sqlite3`) | ✅ (test-only) |
|
|
123
|
+
| `ssh` / `ssh+password` / `ssh+key` | remote shell + SFTP (paramiko) | `paramiko>=3.4` | ✅ |
|
|
124
|
+
|
|
125
|
+
To enable Redis: `uv add "redis>=5.0,<6"` then implement `drivers/redis.py`.
|
|
126
|
+
To add another SSH host: append a `[[connections]]` block with `driver = "ssh"` and an `ssh://...` URL.
|
|
127
|
+
|
|
128
|
+
## Contributing
|
|
129
|
+
|
|
130
|
+
PRs and improvements welcome. See `AGENTS.md` for code priorities.
|
|
131
|
+
|
|
132
|
+
- **Skills are written by the harness, not by you.** When you figure out a non-obvious SQL flow (a weird schema, a slow query, a JSON column trick), file a skill in `agent-workspace/skills/<name>.md`. Future sessions will read it before re-discovering it.
|
|
133
|
+
- Bug fixes, new drivers, helper additions all welcome.
|
|
134
|
+
|
|
135
|
+
## License
|
|
136
|
+
|
|
137
|
+
MIT.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# sql-harness
|
|
2
|
+
|
|
3
|
+
A thin, single-process SQL CLI for LLM agents. Mirrors [browser-harness](https://github.com/browser-use/browser-harness)'s structure but targets relational databases (Postgres, MySQL, Redis-soon).
|
|
4
|
+
|
|
5
|
+
## Quickstart
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# 1. Install deps (one-time)
|
|
9
|
+
uv sync
|
|
10
|
+
|
|
11
|
+
# 2. Scaffold a starter connections.toml
|
|
12
|
+
uv run sql-harness init
|
|
13
|
+
|
|
14
|
+
# 3. Add a connection
|
|
15
|
+
uv run sql-harness add local_pg --driver postgres --url 'postgresql://postgres:postgres@localhost:5432/postgres'
|
|
16
|
+
|
|
17
|
+
# 4. Test it
|
|
18
|
+
uv run sql-harness test local_pg
|
|
19
|
+
|
|
20
|
+
# 5. Use it
|
|
21
|
+
uv run sql-harness <<'PY'
|
|
22
|
+
use_workspace("local_pg")
|
|
23
|
+
print(query("SELECT version()"))
|
|
24
|
+
print(list_tables())
|
|
25
|
+
print(describe("pg_class"))
|
|
26
|
+
PY
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Architecture (~1k lines across 8 core files)
|
|
30
|
+
|
|
31
|
+
- `install.md` — first-time install + first connection
|
|
32
|
+
- `SKILL.md` — day-to-day usage
|
|
33
|
+
- `lab/sql_harness/src/sql_harness/` — protected core package (src-layout, mirrors browser-harness)
|
|
34
|
+
- `${XDG_CONFIG_HOME:-~/.config}/sql-harness/connections.toml` — plaintext credentials in ONE place
|
|
35
|
+
- `${XDG_CONFIG_HOME:-~/.config}/sql-harness/agent-workspace/agent_helpers.py` — task-specific helpers
|
|
36
|
+
- `${XDG_CONFIG_HOME:-~/.config}/sql-harness/agent-workspace/skills/` — per-task/per-table skills
|
|
37
|
+
|
|
38
|
+
## Why mirror browser-harness?
|
|
39
|
+
|
|
40
|
+
- Same operational ergonomics for agents: heredoc CLI with auto-imported helpers.
|
|
41
|
+
- Same agent-workspace pattern (helpers + skills stay editable per-project).
|
|
42
|
+
- Same path/state layout (XDG-style state directory).
|
|
43
|
+
- Same doc layering: `SKILL.md` body + `interaction-skills/*.md` for stuck points.
|
|
44
|
+
|
|
45
|
+
## What this is NOT
|
|
46
|
+
|
|
47
|
+
- Not a database migration framework.
|
|
48
|
+
- Not an ORM.
|
|
49
|
+
- Not a connection-string parser (`pgcli`/`mycli` already exist for interactive REPL use; this is for *agents*).
|
|
50
|
+
- Not a long-running daemon. SQL connections don't need one.
|
|
51
|
+
|
|
52
|
+
## Connection file format
|
|
53
|
+
|
|
54
|
+
Default: `${XDG_CONFIG_HOME:-~/.config}/sql-harness/connections.toml`.
|
|
55
|
+
|
|
56
|
+
```toml
|
|
57
|
+
default_workspace = "local_pg"
|
|
58
|
+
|
|
59
|
+
[pool_defaults]
|
|
60
|
+
size = 5
|
|
61
|
+
recycle = 3600
|
|
62
|
+
pre_ping = true
|
|
63
|
+
echo = false
|
|
64
|
+
|
|
65
|
+
[[connections]]
|
|
66
|
+
name = "local_pg"
|
|
67
|
+
driver = "postgres"
|
|
68
|
+
url = "postgresql+psycopg://postgres:postgres@localhost:5432/postgres"
|
|
69
|
+
description = "Local PostgreSQL for dev"
|
|
70
|
+
|
|
71
|
+
[[connections]]
|
|
72
|
+
name = "prod_pg"
|
|
73
|
+
driver = "postgres"
|
|
74
|
+
url = "${env:PROD_PG_URL}" # env-var indirection
|
|
75
|
+
pool_size = 10
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Use `${env:VAR}` placeholders inside `url` for prod secrets — they're expanded at load time from the process environment.
|
|
79
|
+
|
|
80
|
+
## Configuration env vars
|
|
81
|
+
|
|
82
|
+
| Var | Purpose |
|
|
83
|
+
|---|---|
|
|
84
|
+
| `BH_SQL_HOME` | Override state root (`~/.config/sql-harness` by default) |
|
|
85
|
+
| `BH_SQL_CONFIG_FILE` | Override connections.toml path |
|
|
86
|
+
| `BH_SQL_AGENT_WORKSPACE` | Override agent-workspace directory |
|
|
87
|
+
| `BH_SQL_RUNTIME_DIR` | Override runtime state dir |
|
|
88
|
+
| `BH_SQL_TMP_DIR` | Override temp dir |
|
|
89
|
+
| `BH_PG_URL` | Used by integration tests (skipped if unset) |
|
|
90
|
+
| `BH_MYSQL_URL` | Used by integration tests (skipped if unset) |
|
|
91
|
+
|
|
92
|
+
## Drivers
|
|
93
|
+
|
|
94
|
+
| Driver | Backend | Package | Status |
|
|
95
|
+
|---|---|---|---|
|
|
96
|
+
| `postgres` | PostgreSQL | `psycopg[binary]>=3.2` | ✅ |
|
|
97
|
+
| `mysql` | MySQL | `pymysql>=1.1` | ✅ |
|
|
98
|
+
| `redis` | Redis | `redis>=5.0` (not yet added) | 🚧 stub |
|
|
99
|
+
| `sqlite` | SQLite | stdlib (`sqlite3`) | ✅ (test-only) |
|
|
100
|
+
| `ssh` / `ssh+password` / `ssh+key` | remote shell + SFTP (paramiko) | `paramiko>=3.4` | ✅ |
|
|
101
|
+
|
|
102
|
+
To enable Redis: `uv add "redis>=5.0,<6"` then implement `drivers/redis.py`.
|
|
103
|
+
To add another SSH host: append a `[[connections]]` block with `driver = "ssh"` and an `ssh://...` URL.
|
|
104
|
+
|
|
105
|
+
## Contributing
|
|
106
|
+
|
|
107
|
+
PRs and improvements welcome. See `AGENTS.md` for code priorities.
|
|
108
|
+
|
|
109
|
+
- **Skills are written by the harness, not by you.** When you figure out a non-obvious SQL flow (a weird schema, a slow query, a JSON column trick), file a skill in `agent-workspace/skills/<name>.md`. Future sessions will read it before re-discovering it.
|
|
110
|
+
- Bug fixes, new drivers, helper additions all welcome.
|
|
111
|
+
|
|
112
|
+
## License
|
|
113
|
+
|
|
114
|
+
MIT.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sql-harness
|
|
3
|
+
description: "Use sql-harness for SQL work — querying, schema inspection, migrations, and cross-database workflows."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# sql-harness
|
|
7
|
+
|
|
8
|
+
Direct SQL access via a thin Python heredoc CLI. Connections live in plaintext in a single TOML file (default: `~/.config/sql-harness/connections.toml`).
|
|
9
|
+
|
|
10
|
+
For setup or install problems, read `install.md`. For stuck-point mechanics, see `interaction-skills/` (cross-DB) and `interaction-skills/postgres/` (PG optimization depth: plan reading, B-Tree scans, specialized indexes, table optimization, slow-query detection).
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
sql-harness --help
|
|
16
|
+
sql-harness list
|
|
17
|
+
sql-harness add <name> --driver postgres --url 'postgresql://...'
|
|
18
|
+
sql-harness test <name>
|
|
19
|
+
|
|
20
|
+
sql-harness <<'PY'
|
|
21
|
+
use_workspace("local_pg")
|
|
22
|
+
print(query("SELECT version()"))
|
|
23
|
+
print(list_tables())
|
|
24
|
+
PY
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
- Helpers are pre-imported; you can call them by name in heredoc mode.
|
|
28
|
+
- **First call requires `use_workspace(name)`** — there is no implicit default.
|
|
29
|
+
- For task-specific helpers, drop them into `$BH_SQL_AGENT_WORKSPACE/agent_helpers.py` and they'll merge into the heredoc namespace.
|
|
30
|
+
|
|
31
|
+
## Connection-pool skill + workspace skill
|
|
32
|
+
|
|
33
|
+
Read these when working across multiple connections or tuning pool behavior:
|
|
34
|
+
|
|
35
|
+
- `agent-workspace/skills/pool.md` — pool sizing, `pre_ping`, idle reuse
|
|
36
|
+
- `agent-workspace/skills/workspace.md` — workspace isolation, multi-DB workflows
|
|
37
|
+
- `interaction-skills/save-run-cycle.md` — the correct workflow: write a block, `save` it, `run` it; repeat. Don't batch-save at the end.
|
|
38
|
+
- `interaction-skills/zone-skill-auto-surface.md` — set `$BH_SQL_ZONE_SKILLS=1` and `use_workspace(name)` returns a dict auto-attaching `zone_skills` + `zone_scripts` (mirrors browser-harness's `BH_DOMAIN_SKILLS=1` + `goto_url` returning domain skills).
|
|
39
|
+
|
|
40
|
+
## Local Chrome? No, this is SQL.
|
|
41
|
+
|
|
42
|
+
There is no Chrome and no remote "cloud" backend. SQL is single-process. All engines live in `SqlHarness`'s in-memory registry.
|
|
43
|
+
|
|
44
|
+
## Design Constraints
|
|
45
|
+
|
|
46
|
+
- One connection = one workspace; never share engines across workspaces.
|
|
47
|
+
- Connection pool defaults: `size=5, recycle=3600, pre_ping=True` (per-connection overrides win).
|
|
48
|
+
- `with_transaction()` yields a `Connection`; use `conn.execute(text(...))` for raw control.
|
|
49
|
+
- `query()` returns `list[dict]`; use `execute()` for INSERT/UPDATE/DELETE.
|
|
50
|
+
- `list_tables()` and `describe()` are read-only schema introspection helpers.
|
|
51
|
+
|
|
52
|
+
## Gotchas
|
|
53
|
+
|
|
54
|
+
- Driver label in TOML must match the URL scheme (`postgres` ⇄ `postgresql://`, `mysql` ⇄ `mysql+pymysql://`).
|
|
55
|
+
- Passwords in TOML are plaintext; use `${env:VAR}` indirection for prod secrets.
|
|
56
|
+
- `query()` is for SELECTs only. For INSERTs, use `execute()`.
|
|
57
|
+
- For tables > 10k rows, use `engine.connect().execution_options(stream_results=True)` and iterate manually — `query()` loads everything into memory.
|
|
58
|
+
|
|
59
|
+
## Domain / table skills
|
|
60
|
+
|
|
61
|
+
PG optimization practice: 71 real [pgexercises](https://pgexercises.com/) problems in `practice/pgexercises/` — one `.sql` file per problem (header = question, body = answer). Load schema/seed and replay an answer with `run_sql_file`; tune it with `explain_analyze`. To add a per-table or per-schema skill, drop a markdown file into `agent-workspace/skills/<name>.md`. Read with `apply_skill(name)`.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Generated-code examples (mirrors browser-harness/agent-workspace/domain-skills/)
|
|
2
|
+
|
|
3
|
+
These are **committed examples** of code the harness generated during real
|
|
4
|
+
sessions. The live runtime copies live in `$BH_SQL_AGENT_WORKSPACE` (default
|
|
5
|
+
`~/.config/sql-harness/agent-workspace/`); these repo copies are the
|
|
6
|
+
"historical code" you can read in-tree, the same way browser-harness ships
|
|
7
|
+
`agent-workspace/domain-skills/<site>/` examples.
|
|
8
|
+
|
|
9
|
+
## Contents
|
|
10
|
+
|
|
11
|
+
- `scripts/sh_demo_crud.py` — full e-commerce CRUD walkthrough against a live
|
|
12
|
+
PostgreSQL. Generated via `sql-harness save sh_demo_crud`. Idempotent (drops
|
|
13
|
+
+ recreates the `sh_demo` schema each run). Re-run with
|
|
14
|
+
`sql-harness run sh_demo_crud`.
|
|
15
|
+
- `agent_helpers.py` — reusable helpers (`seed_users`, `place_order`,
|
|
16
|
+
`ship_pending_orders`, `list_orders`, `user_by_email`, `product_by_sku`)
|
|
17
|
+
auto-imported into the heredoc/run namespace.
|
|
18
|
+
- `skills/sh_demo-schema.md` — schema knowledge the agent captured for reuse.
|
|
19
|
+
|
|
20
|
+
## How this code was produced
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# 1. Save the DSN once
|
|
24
|
+
sql-harness add --name test_pg --driver postgres --url 'postgres://...'
|
|
25
|
+
|
|
26
|
+
# 2. Iterate in heredoc mode until the flow works
|
|
27
|
+
sql-harness <<'PY'
|
|
28
|
+
use_workspace("test_pg")
|
|
29
|
+
...
|
|
30
|
+
PY
|
|
31
|
+
|
|
32
|
+
# 3. Persist the working heredoc as reusable code
|
|
33
|
+
sql-harness save sh_demo_crud <<'PY'
|
|
34
|
+
... the working code ...
|
|
35
|
+
PY
|
|
36
|
+
|
|
37
|
+
# 4. Re-run anytime (no re-typing)
|
|
38
|
+
sql-harness run sh_demo_crud
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
That last step — **executed code is saved and re-runnable** — is the essence
|
|
42
|
+
this harness inherits from browser-harness.
|