@fadhilp/stateql 0.12.0 → 0.13.1

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/docs/usage.md ADDED
@@ -0,0 +1,352 @@
1
+ # Usage
2
+
3
+ [Home](../README.md) · [Usage](usage.md) · [Database support](databases.md) · [TypeScript library](library.md)
4
+
5
+ - [Connections and profiles](#connections-and-profiles)
6
+ - [CLI reference](#cli-reference)
7
+ - [Durable state and result reuse](#durable-state-and-result-reuse)
8
+ - [Write safety](#write-safety)
9
+ - [Batch and pipes](#batch-and-pipes)
10
+
11
+ ## Connections and profiles
12
+
13
+ A connection accepts exactly one source: a direct target, `--env`,
14
+ `--credential-ref`, or `--profile`. Library and batch callers may additionally
15
+ attach a [password reference](library.md#password-references) to a literal
16
+ password-free remote target; it is not an additional connection source.
17
+
18
+ ```bash
19
+ stql connect <target> [--name NAME] [--read-only|--read-write]
20
+ stql connect --env ENV [--name NAME] [--read-only|--read-write]
21
+ stql connect --credential-ref REF [--name NAME] [--read-only|--read-write]
22
+ stql connect --profile NAME
23
+ stql disconnect
24
+ stql status
25
+ ```
26
+
27
+ Direct targets accept SQLite paths or password-free PostgreSQL, MySQL, MongoDB,
28
+ and Redis/Rediss URLs. Connections default to read-only unless a profile or an
29
+ explicit flag selects read-write access.
30
+
31
+ ### Environment-backed credentials
32
+
33
+ PostgreSQL, MySQL, MongoDB, and Redis credentials should come from environment
34
+ variables. The variable must contain the complete connection URL, not only its
35
+ password. Environment-backed SQLite paths require an explicit `sqlite:` prefix.
36
+ The URLs below are placeholders; supply real values through your secret-management
37
+ workflow rather than recording them in shell history.
38
+
39
+ ```bash
40
+ export APP_DATABASE_URL='postgres://user:password@host/app'
41
+ stql connect --env APP_DATABASE_URL --name app --read-only
42
+
43
+ export MYSQL_DATABASE_URL='mysql://user:password@host/app'
44
+ stql connect --env MYSQL_DATABASE_URL --name mysql-app --read-only
45
+
46
+ export MONGODB_URL='mongodb://user:password@host/app'
47
+ stql connect --env MONGODB_URL --name mongo-app --read-only
48
+
49
+ export REDIS_URL='rediss://user:password@host/0'
50
+ stql connect --env REDIS_URL --name redis-app --read-only
51
+
52
+ export SQLITE_DATABASE='sqlite:./app.sqlite'
53
+ stql connect --env SQLITE_DATABASE --name local --read-only
54
+ ```
55
+
56
+ StateQL stores no PostgreSQL, MySQL, MongoDB, or Redis password.
57
+ Credential-bearing URLs must be supplied through `--env` or an opaque full-URL
58
+ credential reference. SQLite paths remain persisted as connection metadata.
59
+
60
+ ### Local profiles
61
+
62
+ Profiles store exactly one connection target, environment-variable name, or
63
+ opaque credential reference together with read-only policy. A remote literal
64
+ target may additionally store a `password_ref`; SQLite, environment-backed, and
65
+ full-URL `credential_ref` profiles cannot. Credential values are never stored.
66
+ Profiles persist under `STQL_HOME` with other StateQL metadata, and list/show
67
+ responses include nullable `credential_ref` and `password_ref` fields.
68
+
69
+ ```bash
70
+ stql profile add local ./app.sqlite --read-only
71
+ stql profile add production --env PROD_DATABASE_URL --read-only
72
+ stql profile add hosted --credential-ref 'vault://team/app' --read-only
73
+ stql profile list
74
+ stql profile show production
75
+ stql profile update production --read-only
76
+ stql connect local
77
+ stql connect --profile production
78
+ ```
79
+
80
+ Credential references are bounded nonempty opaque strings; StateQL does not
81
+ apply environment-variable syntax or normalization to them. They can only be
82
+ resolved by a trusted host `CredentialResolver`, so the standalone CLI may
83
+ store them in profiles but cannot connect with them.
84
+
85
+ A bare connection target matching a profile name resolves to that profile;
86
+ otherwise it remains a path or database URL.
87
+
88
+ `profile update` changes subsequent connections, not an already-open connection.
89
+ Omitting the source keeps it; supplying a new source replaces the old one.
90
+ Password references are configured through the library or batch API, not a CLI
91
+ `--password-ref` flag. See [safe profile updates](library.md#safe-profile-updates)
92
+ for source-replacement and downgrade restrictions.
93
+
94
+ ## CLI reference
95
+
96
+ ```text
97
+ stql connect <target> [--name NAME] [--read-only|--read-write]
98
+ stql connect --env ENV [--name NAME] [--read-only|--read-write]
99
+ stql connect --credential-ref REF [--name NAME] [--read-only|--read-write]
100
+ stql connect --profile NAME
101
+ stql disconnect
102
+ stql status
103
+ stql profile add|update NAME [TARGET | --env ENV | --credential-ref REF]
104
+ [--read-only|--read-write]
105
+ stql profile list|show|remove
106
+ stql session start|list|show|summary|close
107
+ stql query <sql> [--params JSON | --param VALUE...] [--cache auto|bypass|require]
108
+ stql filter <result-handle> <predicate> [--params JSON | --param VALUE...]
109
+ stql exec <sql> [--params JSON | --param VALUE...] [--idempotency-key KEY] [--replay]
110
+ [--allow-unbounded] [--allow-destructive]
111
+ stql mongo query|exec|plan '<EJSON command>' [--cache MODE] [--idempotency-key KEY]
112
+ [--replay] [--allow-unbounded] [--allow-destructive]
113
+ stql redis query '<JSON command>' [--cache auto|bypass|require]
114
+ stql redis exec '<JSON command>' [--idempotency-key KEY] [--replay]
115
+ stql redis plan '<JSON command>'
116
+ stql show|count|columns <result-handle>
117
+ stql rows <result-handle> [--offset N] [--limit N]
118
+ stql alias set <name> <result-handle>
119
+ stql export <result-handle> --output FILE [--format json|jsonl|csv]
120
+ stql inspect schema|table|collection|collections|columns|indexes|constraints [name]
121
+ stql objects [KIND] [--schema NAME] [--search TEXT] [--offset N|--cursor CURSOR] [--limit N]
122
+ stql object KIND NAME [IDENTITY] [--schema NAME]
123
+ stql transaction begin|status|commit|rollback [--isolation LEVEL]
124
+ stql plan <sql> [--params JSON | --param VALUE...] [--allow-unbounded] [--allow-destructive]
125
+ stql apply <plan-handle>
126
+ stql history [--limit N] [--offset N] [--category statement|introspection|management]
127
+ [--internal|--external]
128
+ stql receipt <operation-handle>
129
+ stql doctor
130
+ stql purge [expired|results|history|all]
131
+ stql capabilities
132
+ stql batch [commands.json|commands.jsonl|-] [--continue-on-error]
133
+ stql pipe [--continue-on-error]
134
+ ```
135
+
136
+ ### SQL parameters
137
+
138
+ For shell-safe positional parameters, repeat `--param`. JSON scalars become
139
+ their native types; other values remain strings.
140
+
141
+ ```powershell
142
+ stql exec "INSERT INTO users (name, status) VALUES (?, ?)" `
143
+ --param Ada --param trial
144
+ ```
145
+
146
+ Use `--params JSON` for a JSON array or named parameters. Use
147
+ `--params-file FILE` when JSON is awkward to quote; `--params-file -` reads
148
+ JSON from standard input.
149
+
150
+ ### Catalog inspection
151
+
152
+ Use `objects` to list a bounded page and `object` to describe an entry:
153
+
154
+ ```bash
155
+ stql objects table --search users --limit 50
156
+ stql object table users
157
+ ```
158
+
159
+ SQL/MongoDB offsets are non-negative numbers; limits default to 50 and are at
160
+ most 200. Redis uses `--cursor` with the opaque numeric SCAN cursor string
161
+ returned as `next_offset`. Its limit is a SCAN `COUNT` hint with a hard 200-item
162
+ response bound. Redis pages are not snapshots and can be empty or contain
163
+ duplicates while keys change.
164
+
165
+ Search is a case-insensitive name substring for SQL/MongoDB and escaped glob
166
+ substring matching for Redis. No exact counts are forced. Supported kinds are
167
+ returned on every page: SQLite `table,view,trigger`; PostgreSQL
168
+ `table,view,function,trigger,enum`; MySQL `table,view,function,trigger`; MongoDB
169
+ `collection,view`; Redis `key`. PostgreSQL function identities include identity
170
+ arguments; pass the returned identity to `object` to distinguish overloads.
171
+
172
+ Library equivalents are `listObjects(filter, options?)` and
173
+ `describeObject(object, options?)`, where `object` is a returned structured
174
+ catalog entry. The older `inspect` commands remain available for SQL and
175
+ MongoDB, but not Redis. See [database support](databases.md) for native commands.
176
+
177
+ ### Output modes
178
+
179
+ CLI output defaults to compact, one-line `agent` JSON. Successful responses
180
+ flatten useful data and expose the primary durable ID as `handle`. Errors retain
181
+ their complete error object. Empty warnings and tracing metadata are omitted.
182
+
183
+ ```json
184
+ {"ok":false,"error":{"code":"UNBOUNDED_MUTATION","message":"Mutation has no WHERE clause.","retryable":false,"executed":false,"override_flag":"--allow-unbounded"}}
185
+ ```
186
+
187
+ Other modes are:
188
+
189
+ - `--output json`: original pretty, verbose envelope.
190
+ - `--output jsonl`: verbose envelope on one line.
191
+ - `--output text`: short human-readable status.
192
+ - `--output silent`: only a successful handle.
193
+
194
+ Set `STQL_OUTPUT` to choose a mode globally. For `export`, `--output` names the
195
+ file, so use `STQL_OUTPUT` to choose the command's response mode. Library
196
+ responses always keep the full envelope.
197
+
198
+ ### Deadlines and cancellation
199
+
200
+ Database commands accept `--timeout-ms N`; the default is 30,000 ms. `Ctrl+C`
201
+ cancels active work.
202
+
203
+ - SQLite runs in a killable child process so long synchronous statements cannot
204
+ block StateQL's event loop.
205
+ - PostgreSQL combines server-side `statement_timeout` with client deadlines.
206
+ - MySQL deadlines destroy the active connection.
207
+ - MongoDB uses driver deadlines and closes stopped operations.
208
+
209
+ A timed-out or cancelled write may return `OUTCOME_UNKNOWN` when its commit
210
+ status cannot be proven. Cancellation stops that command's driver work; it does
211
+ not close the `StateQL` actor, and later commands remain usable.
212
+
213
+ ## Durable state and result reuse
214
+
215
+ State metadata lives under `STQL_HOME`, or the platform data directory when
216
+ unset. StateQL keeps connections, sessions, handles, aliases, cache entries,
217
+ plans, transactions, history, and receipts available across CLI invocations.
218
+
219
+ ### Sessions and actors
220
+
221
+ Set `STQL_SESSION` to select a named session and `STQL_ACTOR` to select an
222
+ attached actor. A session is a shared workspace: attached actors reuse its
223
+ connection, handles, aliases, cache, and state version. Plans and staged
224
+ transactions remain owned by the actor that created them.
225
+
226
+ Callers that omit `actor` keep the legacy behavior where the actor ID is the
227
+ session name.
228
+
229
+ ### Result lifetime and limits
230
+
231
+ Result rows are materialized locally for durable access. By default, read cache
232
+ entries expire after five minutes, and materialized handles expire after 24
233
+ hours. Expired results and plans are deleted the next time StateQL opens.
234
+
235
+ By default, queries exceeding 10,000 rows or 16 MiB of serialized row data fail
236
+ before persistence. Narrow the `WHERE` clause, add `LIMIT`, or select fewer
237
+ columns. These caps bound persisted materialization; the independent deadline
238
+ bounds execution time. Native commands may impose stricter
239
+ [database-specific limits](databases.md).
240
+
241
+ Command history keeps the latest 10,000 entries per session. SQLite cache reuse
242
+ also checks the database file signature. PostgreSQL, MySQL, and MongoDB cache
243
+ reuse is labeled `ttl_based` and is never authoritative.
244
+
245
+ StateQL limits persisted result payloads to 256 MiB by default. When that quota
246
+ is reached it removes the oldest unaliased results; aliases remain protected. A
247
+ single result that cannot fit fails with `STATE_QUOTA_EXCEEDED`. Configure the
248
+ limit with `maxStateBytes` in the library or `--max-state-bytes` in the CLI.
249
+ Cache and result retention can be configured with `cacheTtlSeconds` and
250
+ `resultTtlSeconds`, or their `--cache-ttl-seconds` and
251
+ `--result-ttl-seconds` CLI equivalents.
252
+
253
+ `stql doctor` checks SQLite integrity and stored payload shapes without printing
254
+ SQL, parameters, or result values. `stql purge` removes expired data by default;
255
+ use `results`, `history`, or `all` for explicit session cleanup. On POSIX
256
+ systems, StateQL removes group and world access from its state directory,
257
+ database, and SQLite sidecar files.
258
+
259
+ ### Local filtering
260
+
261
+ `filter` evaluates one scalar SQLite predicate against a stored result. It
262
+ preserves source order, state metadata, and expiry, and never accesses the
263
+ original database.
264
+
265
+ Use parameters for values. Subqueries, query-shaping clauses, and
266
+ non-allowlisted functions are rejected. Common deterministic functions such as
267
+ `lower`, `upper`, `length`, and `coalesce` are supported.
268
+
269
+ ## Write safety
270
+
271
+ Writes require a read-write connection. Destructive and unbounded SQL/MongoDB
272
+ operations require `--allow-destructive` and `--allow-unbounded`, respectively.
273
+ The flags are independent.
274
+
275
+ `plan` validates and stores a write for later application. A plan persists only
276
+ the flags explicitly supplied when it is created; `apply` never adds
277
+ authorization.
278
+
279
+ Use an idempotency key to protect retryable writes from duplicate execution:
280
+
281
+ ```bash
282
+ stql exec "UPDATE jobs SET claimed = 1 WHERE id = ?" \
283
+ --param 42 \
284
+ --idempotency-key claim-job-42
285
+ ```
286
+
287
+ If a write starts but StateQL cannot safely record its final outcome, it returns
288
+ `OUTCOME_UNKNOWN` and blocks automatic replay. Inspect database state before
289
+ using `--replay`. Interrupted commits remain fail-closed; stale `committing`
290
+ records become `outcome_unknown` after five minutes.
291
+
292
+ ### Transactions
293
+
294
+ Transactions are staged in local state so they survive CLI invocations, then
295
+ executed atomically on commit. While a transaction is active, StateQL rejects
296
+ database reads, plans, connection changes, and disconnects. Commit or roll back
297
+ first.
298
+
299
+ SQLite supports `serializable`. PostgreSQL and MySQL also support
300
+ `repeatable read`, `read committed`, and `read uncommitted`. Server reads run
301
+ inside database-enforced read-only transactions. MySQL staged transactions
302
+ reject DDL because MySQL implicitly commits those statements.
303
+ MongoDB transactions use `snapshot` isolation and require a replica set or
304
+ sharded deployment; standalone servers do not support them.
305
+ Redis does not support StateQL staged transactions; see its
306
+ [native write guarantees](databases.md#native-redis).
307
+
308
+ ## Batch and pipes
309
+
310
+ `batch` reads a JSON array from a `.json` file or JSONL from a `.jsonl` file.
311
+ `pipe` reads JSONL from standard input. Commands run sequentially and stop on
312
+ the first error unless `--continue-on-error` is set. Output defaults to one
313
+ compact `agent` JSON object per line.
314
+
315
+ Pipe commands directly:
316
+
317
+ ```bash
318
+ printf '%s\n' \
319
+ '{"command":"query","sql":"SELECT id, email FROM users ORDER BY id","as":"users"}' \
320
+ '{"command":"filter","handle":"users","where":"email LIKE ?","params":["%@example.com"],"as":"example_users"}' \
321
+ '{"command":"rows","handle":"example_users","limit":10}' |
322
+ stql pipe
323
+ ```
324
+
325
+ Or save a JSON array as `commands.json`:
326
+
327
+ ```json
328
+ [
329
+ {
330
+ "command": "exec",
331
+ "sql": "UPDATE jobs SET claimed = 1 WHERE id = ?",
332
+ "params": [42],
333
+ "idempotency_key": "claim-job-42"
334
+ },
335
+ {
336
+ "command": "query",
337
+ "sql": "SELECT * FROM jobs WHERE id = ?",
338
+ "params": [42]
339
+ }
340
+ ]
341
+ ```
342
+
343
+ ```bash
344
+ stql batch commands.json
345
+ ```
346
+
347
+ Batch fields use snake case. Supported command names match CLI paths, such as
348
+ `filter`, `transaction.begin`, `session.summary`, `alias.set`, `plan`, and
349
+ `apply`. Native MongoDB batches use `mongo.query`, `mongo.exec`, or `mongo.plan`
350
+ with the command object in `mongo`; the same cache, replay, idempotency, safety,
351
+ and timeout fields apply. Database commands may set `timeout_ms`; otherwise they
352
+ use the 30-second default.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fadhilp/stateql",
3
- "version": "0.12.0",
3
+ "version": "0.13.1",
4
4
  "description": "Stateful, agent-oriented database CLI for safe result reuse",
5
5
  "repository": {
6
6
  "type": "git",
@@ -21,6 +21,7 @@
21
21
  "files": [
22
22
  "dist/src",
23
23
  "README.md",
24
+ "docs",
24
25
  "SQL_COMMAND_ROADMAP.md",
25
26
  "LICENSE"
26
27
  ],