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.
Files changed (82) hide show
  1. sql_harness-0.1.0/.claude-plugin/marketplace.json +26 -0
  2. sql_harness-0.1.0/.claude-plugin/plugin.json +13 -0
  3. sql_harness-0.1.0/.env.example +20 -0
  4. sql_harness-0.1.0/.github/ISSUE_TEMPLATE/bug-report.yml +49 -0
  5. sql_harness-0.1.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
  6. sql_harness-0.1.0/.github/ISSUE_TEMPLATE/feature-request.yml +37 -0
  7. sql_harness-0.1.0/.gitignore +34 -0
  8. sql_harness-0.1.0/AGENTS.md +37 -0
  9. sql_harness-0.1.0/PKG-INFO +137 -0
  10. sql_harness-0.1.0/README.md +114 -0
  11. sql_harness-0.1.0/SKILL.md +61 -0
  12. sql_harness-0.1.0/agent-workspace/README.md +42 -0
  13. sql_harness-0.1.0/agent-workspace/agent_helpers.example.py +124 -0
  14. sql_harness-0.1.0/agent-workspace/agent_helpers.py +14 -0
  15. sql_harness-0.1.0/agent-workspace/skills/pool.md +43 -0
  16. sql_harness-0.1.0/agent-workspace/skills/ssh.md +89 -0
  17. sql_harness-0.1.0/agent-workspace/skills/workspace.md +58 -0
  18. sql_harness-0.1.0/agent-workspace/zones/example_pg/scripts/sh_demo_crud.py +114 -0
  19. sql_harness-0.1.0/agent-workspace/zones/example_pg/skills/sh_demo-schema.md +106 -0
  20. sql_harness-0.1.0/docs/connections-toml-example.toml +74 -0
  21. sql_harness-0.1.0/docs/headless-notes.md +78 -0
  22. sql_harness-0.1.0/docs/maintainer.md +60 -0
  23. sql_harness-0.1.0/docs/standalone-install.md +167 -0
  24. sql_harness-0.1.0/install.md +77 -0
  25. sql_harness-0.1.0/interaction-skills/aggregations.md +105 -0
  26. sql_harness-0.1.0/interaction-skills/encoding-and-charset.md +34 -0
  27. sql_harness-0.1.0/interaction-skills/indexes-and-explain.md +61 -0
  28. sql_harness-0.1.0/interaction-skills/joins.md +123 -0
  29. sql_harness-0.1.0/interaction-skills/json-columns.md +30 -0
  30. sql_harness-0.1.0/interaction-skills/large-result-sets.md +28 -0
  31. sql_harness-0.1.0/interaction-skills/migrations.md +32 -0
  32. sql_harness-0.1.0/interaction-skills/pooling.md +51 -0
  33. sql_harness-0.1.0/interaction-skills/postgres/btree-indexes.md +92 -0
  34. sql_harness-0.1.0/interaction-skills/postgres/plan-reading.md +68 -0
  35. sql_harness-0.1.0/interaction-skills/postgres/slow-queries-joins.md +99 -0
  36. sql_harness-0.1.0/interaction-skills/postgres/specialized-indexes.md +97 -0
  37. sql_harness-0.1.0/interaction-skills/postgres/table-optimization.md +104 -0
  38. sql_harness-0.1.0/interaction-skills/recursive-ctes.md +97 -0
  39. sql_harness-0.1.0/interaction-skills/save-run-cycle.md +138 -0
  40. sql_harness-0.1.0/interaction-skills/schema-introspection.md +48 -0
  41. sql_harness-0.1.0/interaction-skills/ssh.md +96 -0
  42. sql_harness-0.1.0/interaction-skills/timeouts-and-cancellation.md +64 -0
  43. sql_harness-0.1.0/interaction-skills/transactions.md +57 -0
  44. sql_harness-0.1.0/interaction-skills/window-functions.md +104 -0
  45. sql_harness-0.1.0/interaction-skills/zone-skill-auto-surface.md +138 -0
  46. sql_harness-0.1.0/pyproject.toml +58 -0
  47. sql_harness-0.1.0/skills/sql-harness/README.txt +8 -0
  48. sql_harness-0.1.0/skills/sql-harness/SKILL.md +1 -0
  49. sql_harness-0.1.0/skills/sql-harness/references/install.md +93 -0
  50. sql_harness-0.1.0/sql-harness +34 -0
  51. sql_harness-0.1.0/src/sql_harness/SKILL.md +61 -0
  52. sql_harness-0.1.0/src/sql_harness/__init__.py +27 -0
  53. sql_harness-0.1.0/src/sql_harness/agent_loader.py +55 -0
  54. sql_harness-0.1.0/src/sql_harness/cli.py +869 -0
  55. sql_harness-0.1.0/src/sql_harness/config.py +241 -0
  56. sql_harness-0.1.0/src/sql_harness/drivers/__init__.py +59 -0
  57. sql_harness-0.1.0/src/sql_harness/drivers/mysql.py +43 -0
  58. sql_harness-0.1.0/src/sql_harness/drivers/postgres.py +55 -0
  59. sql_harness-0.1.0/src/sql_harness/drivers/redis.py +33 -0
  60. sql_harness-0.1.0/src/sql_harness/drivers/sqlite.py +39 -0
  61. sql_harness-0.1.0/src/sql_harness/drivers/ssh.py +293 -0
  62. sql_harness-0.1.0/src/sql_harness/helpers.py +789 -0
  63. sql_harness-0.1.0/src/sql_harness/manager.py +122 -0
  64. sql_harness-0.1.0/src/sql_harness/paths.py +112 -0
  65. sql_harness-0.1.0/src/sql_harness/run.py +85 -0
  66. sql_harness-0.1.0/tests/__init__.py +0 -0
  67. sql_harness-0.1.0/tests/conftest.py +19 -0
  68. sql_harness-0.1.0/tests/integration/__init__.py +0 -0
  69. sql_harness-0.1.0/tests/integration/test_mysql.py +40 -0
  70. sql_harness-0.1.0/tests/integration/test_pg_optimization.py +144 -0
  71. sql_harness-0.1.0/tests/integration/test_pgexercises_practice.py +62 -0
  72. sql_harness-0.1.0/tests/integration/test_postgres.py +68 -0
  73. sql_harness-0.1.0/tests/integration/test_ssh.py +56 -0
  74. sql_harness-0.1.0/tests/unit/__init__.py +0 -0
  75. sql_harness-0.1.0/tests/unit/test_agent_loader.py +48 -0
  76. sql_harness-0.1.0/tests/unit/test_cli.py +222 -0
  77. sql_harness-0.1.0/tests/unit/test_config.py +142 -0
  78. sql_harness-0.1.0/tests/unit/test_helpers.py +196 -0
  79. sql_harness-0.1.0/tests/unit/test_manager.py +91 -0
  80. sql_harness-0.1.0/tests/unit/test_paths.py +51 -0
  81. sql_harness-0.1.0/tests/unit/test_ssh.py +54 -0
  82. 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.