cognexdb 0.4.1__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.
@@ -0,0 +1,440 @@
1
+ Metadata-Version: 2.4
2
+ Name: cognexdb
3
+ Version: 0.4.1
4
+ Summary: Local-first human-readable file database with REST, SQL, CLI, and MCP interfaces.
5
+ Author: Cognex
6
+ License: MIT
7
+ Keywords: ai,mcp,local-first,codebase,semantic-search
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Requires-Python: >=3.10
13
+ Description-Content-Type: text/markdown
14
+
15
+ # Cognex
16
+
17
+ Cognex is a **local-first database built for humans, apps, and AI**. It turns folders of Markdown, JSON, and CSV files into a queryable backend with SQLite indexing, REST APIs, SQL reads, CLI commands, and MCP tools.
18
+
19
+ The source of truth stays human-readable:
20
+
21
+ ```text
22
+ customers/john.md
23
+ customers/sarah.json
24
+ orders/order_001.json
25
+ products/catalog.csv
26
+ ```
27
+
28
+ Apps can call Cognex like a backend. Developers can run SQL. AI assistants can query and write records through MCP. Humans can still open the files in an editor.
29
+
30
+ ## Local-first SDK
31
+
32
+ Cognex is meant to feel familiar to developers who already use cloud backends such as Supabase, but the default runtime is local files plus a SQLite index. Start with the SDK when you want database, search, sync, and AI-ready human-readable data without making cloud infrastructure the default.
33
+
34
+ ```python
35
+ from cognex import create_client
36
+
37
+ db = create_client("./data")
38
+
39
+ db.from_("customers").insert({
40
+ "id": "john",
41
+ "name": "John",
42
+ "status": "lead",
43
+ }).execute()
44
+
45
+ leads = db.from_("customers").select("*").eq("status", "lead").execute()
46
+ rows = db.sql("SELECT * FROM customers WHERE status = ?", ["lead"]).data
47
+ ```
48
+
49
+ This gives Supabase-style application code while keeping the source of truth in files like `customers/john.json`. Use `table("customers")` as an alias for `from_("customers")` when you prefer a Python keyword-safe name.
50
+
51
+ ## AI-native data tasks
52
+
53
+ Cognex now includes a provider-free AI-native command layer for natural-language database tasks. It creates an inspectable plan first, then safely executes supported operations against local human-readable files.
54
+
55
+ ```python
56
+ from cognex import create_client
57
+
58
+ db = create_client("./data")
59
+
60
+ # Search records by intent.
61
+ result = db.ai_run("Find every customer that bought iPad", collection="customers")
62
+
63
+ # Inspect before execution.
64
+ plan = db.ai_plan("update customers where status = lead set status = active")
65
+
66
+ # Import a CSV into JSON records.
67
+ imported = db.ai_run(
68
+ "Create a CRM from this CSV",
69
+ collection="crm",
70
+ csv_text="id,name,status\nada,Ada,lead\n",
71
+ )
72
+ ```
73
+
74
+ The same layer is exposed through REST (`/v1/ai/plan`, `/v1/ai/run`), CLI (`cognex ai ...`), SDK (`ai_plan`, `ai_run`), and MCP (`ai_run_database_task`). It is intentionally deterministic and local-first so AI assistants can automate database work without sending data to a model provider by default.
75
+
76
+ ## JavaScript and browser offline SDKs
77
+
78
+ Cognex includes a fetch-based JavaScript REST client and a browser IndexedDB helper:
79
+
80
+ ```js
81
+ import { createClient } from "./sdks/js/cognex.js";
82
+
83
+ const db = createClient("http://localhost:8080", { apiKey: "dev-secret" });
84
+ await db.from("customers").insert({ id: "john", data: { name: "John" } });
85
+ const rows = await db.sql("SELECT * FROM customers");
86
+ ```
87
+
88
+ ```js
89
+ import { createIndexedDbStore } from "./sdks/browser/cognex-indexeddb.js";
90
+
91
+ const local = createIndexedDbStore();
92
+ await local.put("customers", "john", { name: "John" });
93
+ await local.sync(db);
94
+ ```
95
+
96
+ ## Imports, row policies, and local functions
97
+
98
+ Import Supabase CSV/JSON exports or Firebase/Firestore JSON exports:
99
+
100
+ ```bash
101
+ ./bin/cognex --root ./data import supabase ./customers.csv
102
+ ./bin/cognex --root ./data import firebase ./firestore-export.json
103
+ ```
104
+
105
+ Add basic collection policies in `.cognex/policies.json`:
106
+
107
+ ```json
108
+ {
109
+ "collections": {
110
+ "customers": {"read": "owner", "write": "owner", "owner_field": "owner"}
111
+ }
112
+ }
113
+ ```
114
+
115
+ Add local functions in `.cognex/functions/name.py`. Functions read JSON from stdin and write JSON to stdout, then can be called with:
116
+
117
+ ```bash
118
+ ./bin/cognex --root ./data function name --data '{"hello":"world"}'
119
+ ```
120
+
121
+ Or through REST at `POST /v1/functions/{name}`.
122
+
123
+ ## Supabase-style capability status
124
+
125
+ Cognex is aiming for a Supabase-familiar developer experience, but it should not claim every Supabase feature is complete yet. This is the current honest status:
126
+
127
+ | Supabase feature | Cognex status today | How it works / gap |
128
+ | --- | ---: | --- |
129
+ | Postgres-style database | ✅ Available locally | Human-readable Markdown/JSON/CSV files are indexed into SQLite for queryable app data. |
130
+ | Tables | ✅ Available locally | Folders become collections, and files become records. |
131
+ | SQL reads | ✅ Available locally | Read-only `SELECT`/`WITH` queries run against SQLite materialized collection tables. |
132
+ | Storage | ✅ Available locally | Files and folders are the storage layer; JSON/Markdown writes stay human-readable. |
133
+ | SDK | ✅ Available locally | Python SDK plus JS REST SDK and browser IndexedDB offline helper are included. |
134
+ | REST API | ✅ Available locally / optionally hosted | The `/v1/*` server can run on localhost or on a host such as Railway with persistent storage. |
135
+ | CLI | ✅ Available locally | `bin/cognex` exposes index, query, CRUD, sync, CRDT, server, and project-intelligence commands. |
136
+ | MCP / AI tooling | ✅ Available locally | MCP tools expose project search/context, natural-language data tasks, database query/write, sync, and CRDT operations to AI assistants. |
137
+ | CRDT record merge | ✅ Available for structured JSON fields | Operation-based LWW field updates can be exported, imported, materialized, and synced. |
138
+ | Filesystem/Git sync | ✅ Available | Data files, manifests, and CRDT operation logs can move through local folders or Git-backed remotes. |
139
+ | Auth | ✅ Basic local auth | API-key protection plus local email/password signup, login, logout, and bearer session tokens stored under `.cognex/auth.json`. OAuth and hosted auth are not included. |
140
+ | Realtime | ✅ Basic local realtime | `/v1/realtime` streams Server-Sent Events for collection snapshots and file-backed record changes. |
141
+ | JavaScript SDK | ✅ Basic | `sdks/js/cognex.js` provides a fetch-based browser/Node REST client. |
142
+ | Dashboard / Studio | ✅ Basic local web UI | `/dashboard` provides a lightweight local web UI for collections, SQL, and JSON record writes. |
143
+ | Row-level security | ✅ Basic | `.cognex/policies.json` supports public/authenticated/owner/admin collection policies. |
144
+ | Functions/plugins | ✅ Basic local | `.cognex/functions/*.py` scripts can be called through REST/CLI as local plugins. |
145
+
146
+ So the accurate V1 claim is: Cognex provides the local-first file database, SQLite SQL reads, REST, CLI, MCP, Python SDK, basic JavaScript/browser SDKs, basic local auth, basic local realtime, a basic local dashboard, basic row policies, local functions/plugins, CRDT operations, and filesystem/Git sync. It does **not** yet provide full Supabase parity for OAuth/hosted auth, passkeys, PostgreSQL wire compatibility, advanced realtime channels, hosted edge runtimes, or managed multi-region infrastructure.
147
+
148
+ For deployment decisions and the exact boundary between "usable V1" and "not Supabase-equivalent yet," see [Cognex V1 production-readiness status](docs/PRODUCTION_READINESS.md).
149
+
150
+ ## Optional REST backend
151
+
152
+ Run the REST backend locally when another process, browser app, or phone app needs HTTP access to the same local data folder:
153
+
154
+ ```bash
155
+ PYTHONPATH=src python -m cognex.server --root ./data --port 8080 --api-key dev-secret
156
+ ```
157
+
158
+ Cloud deployment is optional rather than the default. If you later want a hosted endpoint, the included `Procfile` can run the same local-first backend on platforms such as Railway:
159
+
160
+ ```text
161
+ web: PYTHONPATH=src python -m cognex.server --root ${COGNEX_ROOT:-/data} --host 0.0.0.0 --port ${PORT:-8080}
162
+ ```
163
+
164
+ Useful deployment variables:
165
+
166
+ | Variable | Purpose |
167
+ | --- | --- |
168
+ | `COGNEX_ROOT` | Persistent mounted folder for user data, for example `/data`. |
169
+ | `COGNEX_API_KEY` | Bearer token required by the API. |
170
+ | `COGNEX_CORS_ORIGIN` | Frontend origin, or `*` while testing. |
171
+ | `COGNEX_WATCH_INTERVAL` | Background re-index interval in seconds. |
172
+
173
+ Use persistent storage for `COGNEX_ROOT` so files and SQLite state survive deploys.
174
+
175
+ ## REST API
176
+
177
+ All endpoints accept `Authorization: Bearer <COGNEX_API_KEY>` when `COGNEX_API_KEY` or `--api-key` is set.
178
+
179
+ | Method | Path | Purpose |
180
+ | --- | --- | --- |
181
+ | `GET` | `/health` | Health check for Railway and uptime. |
182
+ | `GET` | `/dashboard` | Basic local web dashboard for collections, SQL, and JSON writes. |
183
+ | `POST` | `/v1/index` | Re-index Markdown, JSON, and CSV files. |
184
+ | `POST` | `/v1/auth/signup` | Create a local email/password user and session token. |
185
+ | `POST` | `/v1/auth/login` | Create a bearer session token for a local user. |
186
+ | `POST` | `/v1/auth/logout` | Revoke the current bearer session token. |
187
+ | `GET` | `/v1/collections` | List detected collections. |
188
+ | `GET` | `/v1/transactions` | Inspect recent local write transactions and revisions. |
189
+ | `GET` | `/v1/sync/status?remote=/path` | Show pending push/pull/conflict state for a sync remote. |
190
+ | `GET` | `/v1/realtime?collection=name` | Stream Server-Sent Events for local record snapshots and changes. |
191
+ | `GET` | `/v1/collections/{collection}` | List records in a collection. |
192
+ | `GET` | `/v1/collections/{collection}/records/{id}` | Read one record. |
193
+ | `POST` | `/v1/collections/{collection}/records` | Create a JSON or Markdown record. |
194
+ | `PUT` | `/v1/collections/{collection}/records/{id}` | Replace a JSON or Markdown record. |
195
+ | `DELETE` | `/v1/collections/{collection}/records/{id}` | Soft-delete a record by moving the file to a `.deleted-*` backup. |
196
+ | `POST` | `/v1/query` | Run read-only SQL against file collections. |
197
+ | `POST` | `/v1/ai/plan` | Create an inspectable natural-language data-task plan. |
198
+ | `POST` | `/v1/ai/run` | Execute a supported natural-language data task locally. |
199
+ | `POST` | `/v1/import/supabase` | Import a Supabase CSV/JSON export from a server-local path. |
200
+ | `POST` | `/v1/import/firebase` | Import a Firebase/Firestore JSON export from a server-local path. |
201
+ | `POST` | `/v1/functions/{name}` | Run a local Cognex function/plugin. |
202
+ | `POST` | `/v1/search` | Full-text search across records. |
203
+ | `POST` | `/v1/sync/push` | Push local files to a filesystem/Git sync remote. |
204
+ | `POST` | `/v1/sync/pull` | Pull remote files into the local data root. |
205
+ | `POST` | `/v1/crdt/update` | Apply CRDT field operations and materialize the merged record. |
206
+ | `GET` | `/v1/crdt/export` | Export CRDT operations for another device. |
207
+ | `POST` | `/v1/crdt/import` | Import CRDT operations and merge them into local files. |
208
+
209
+ Create a customer:
210
+
211
+ ```bash
212
+ curl -X POST http://localhost:8080/v1/collections/customers/records \
213
+ -H 'Authorization: Bearer dev-secret' \
214
+ -H 'Content-Type: application/json' \
215
+ -d '{"id":"john","expected_revision":"","format":"json","data":{"name":"John","status":"lead","product":"iPad"}}'
216
+ ```
217
+
218
+ Query it with SQL:
219
+
220
+ ```bash
221
+ curl -X POST http://localhost:8080/v1/query \
222
+ -H 'Authorization: Bearer dev-secret' \
223
+ -H 'Content-Type: application/json' \
224
+ -d '{"sql":"SELECT * FROM customers WHERE status = ?","params":["lead"]}'
225
+ ```
226
+
227
+ Create a local user session instead of using a shared API key:
228
+
229
+ ```bash
230
+ curl -X POST http://localhost:8080/v1/auth/signup \
231
+ -H 'Content-Type: application/json' \
232
+ -d '{"email":"ada@example.com","password":"correct horse battery staple"}'
233
+ ```
234
+
235
+ Watch local collection changes with Server-Sent Events:
236
+
237
+ ```bash
238
+ curl -N http://localhost:8080/v1/realtime?collection=customers \
239
+ -H 'Authorization: Bearer dev-secret'
240
+ ```
241
+
242
+ Open the local dashboard at `http://localhost:8080/dashboard`.
243
+
244
+ ## CLI
245
+
246
+ Run from a checkout without installation:
247
+
248
+ ```bash
249
+ ./bin/cognex --root ./data collections
250
+ ./bin/cognex --root ./data upsert customers john --data '{"name":"John","status":"lead"}'
251
+ ./bin/cognex --root ./data sql 'SELECT * FROM customers'
252
+ ./bin/cognex --root ./data ai "Find every customer that bought iPad" --collection customers
253
+ ./bin/cognex --root ./data transactions
254
+ ./bin/cognex --root ./data sync-status ./remote-sync
255
+ ./bin/cognex --root ./data sync-push ./remote-sync
256
+ ./bin/cognex --root ./data sync-pull ./remote-sync
257
+ ./bin/cognex --root ./data crdt-update customers john --fields '{"name":"John","status":"lead"}'
258
+ ./bin/cognex --root ./data crdt-export ./ops.json
259
+ ./bin/cognex --root ./data crdt-import ./ops.json
260
+ ./bin/cognex --root ./data serve --port 8080 --api-key dev-secret
261
+ ```
262
+
263
+ The previous project-intelligence commands still exist:
264
+
265
+ ```bash
266
+ ./bin/cognex --root /path/to/project index
267
+ ./bin/cognex --root /path/to/project search "authentication stripe pricing page"
268
+ ./bin/cognex --root /path/to/project context "build another SaaS landing page using the existing design system"
269
+ ./bin/cognex --root /path/to/project graph
270
+ ```
271
+
272
+ ## MCP tools
273
+
274
+ Point an MCP client at:
275
+
276
+ ```json
277
+ {
278
+ "mcpServers": {
279
+ "cognex": {
280
+ "command": "cognex",
281
+ "args": ["--root", "/absolute/path/to/data", "mcp"]
282
+ }
283
+ }
284
+ }
285
+ ```
286
+
287
+ The MCP adapter exposes:
288
+
289
+ | Tool | Purpose |
290
+ | --- | --- |
291
+ | `index_project` | Refresh project intelligence and file database indexes. |
292
+ | `search_project` | Search project files by natural language. |
293
+ | `build_context` | Build AI-ready code/project context. |
294
+ | `project_graph` | Return files, symbols, imports, and inferred relations. |
295
+ | `query_database` | Run read-only SQL over local file collections. |
296
+ | `upsert_record` | Create or update JSON/Markdown records as files. |
297
+ | `delete_record` | Soft-delete a file-backed record. |
298
+ | `transaction_log` | List recent local write transactions with before/after revisions. |
299
+ | `sync_status` | Show pending push/pull/conflict state for a sync remote. |
300
+ | `sync_push` | Push local files to a filesystem/Git sync remote. |
301
+ | `sync_pull` | Pull remote files into the local data root. |
302
+ | `crdt_update` | Apply CRDT field updates that merge across imported operation logs. |
303
+ | `crdt_export` | Export CRDT operations for sync/merge. |
304
+ | `crdt_import` | Import CRDT operations and materialize merged records. |
305
+
306
+ ## How data maps to SQL
307
+
308
+ A folder becomes a collection. A file becomes a record.
309
+
310
+ ```text
311
+ customers/john.json -> collection `customers`, id `john`
312
+ customers/sarah.md -> collection `customers`, id `sarah`
313
+ products/catalog.csv -> collection `catalog`, one record per row
314
+ ```
315
+
316
+ Cognex materializes safe temporary SQLite tables for read-only SQL, so this works:
317
+
318
+ ```sql
319
+ SELECT * FROM customers WHERE status = 'lead';
320
+ ```
321
+
322
+ Writes go back to human-readable `.json` or `.md` files. CSV is indexed and queryable, but API writes currently target JSON/Markdown to avoid destructive spreadsheet rewrites. Every record response includes a `revision` hash. Send `expected_revision` in JSON bodies or `If-Match` on `PUT`/`DELETE` to prevent stale clients from overwriting newer edits.
323
+
324
+
325
+
326
+ ## Sync engine
327
+
328
+ Cognex now includes Option 2 sync for filesystem and Git-backed remotes. A sync remote is a directory with this structure:
329
+
330
+ ```text
331
+ remote/
332
+ data/
333
+ customers/john.json
334
+ orders/order_001.json
335
+ .cognex-sync/
336
+ manifest.json
337
+ crdt_ops.json
338
+ ```
339
+
340
+ That remote directory can be:
341
+
342
+ - another local folder;
343
+ - a mounted network drive;
344
+ - a Dropbox/iCloud/Google Drive folder managed by that provider's desktop sync client;
345
+ - a Git repository when using `--git`.
346
+
347
+ REST examples:
348
+
349
+ ```bash
350
+ curl -X POST http://localhost:8080/v1/sync/push \
351
+ -H 'Authorization: Bearer dev-secret' \
352
+ -H 'Content-Type: application/json' \
353
+ -d '{"remote":"/path/to/remote-sync"}'
354
+
355
+ curl -X POST http://localhost:8080/v1/sync/pull \
356
+ -H 'Authorization: Bearer dev-secret' \
357
+ -H 'Content-Type: application/json' \
358
+ -d '{"remote":"/path/to/remote-sync"}'
359
+ ```
360
+
361
+ Git-backed sync:
362
+
363
+ ```bash
364
+ ./bin/cognex --root ./data sync-push ./git-remote --git --message "Sync customer data"
365
+ ./bin/cognex --root ./data sync-pull ./git-remote --git
366
+ ```
367
+
368
+ The sync engine uses file revision manifests and the last synced base revision to detect divergent file edits. It also carries CRDT operation logs in `.cognex-sync/crdt_ops.json`, so structured JSON record operations can move through the same folder/Git/Dropbox/iCloud/Google Drive sync path. If both local and remote changed the same non-CRDT file since the last sync, Cognex reports a conflict instead of overwriting data. On pull conflicts, it also saves the remote version as a `.conflict-remote-*` copy beside the local file for manual resolution. Use `--force` or `force: true` only when you intentionally want one side to win.
369
+
370
+ This is working push/pull replication, cloud-folder backup, Git sync, and CRDT-operation sync for structured JSON records. Rich text CRDT editing remains a future specialized layer.
371
+
372
+
373
+ ## CRDT engine
374
+
375
+ Cognex now includes Option 3 for JSON-style records: an operation-based CRDT engine. Each field update becomes an idempotent operation with:
376
+
377
+ - `op_id`
378
+ - `actor`
379
+ - per-actor `seq`
380
+ - `collection`
381
+ - record `id`
382
+ - field name
383
+ - JSON value or delete marker
384
+ - timestamp
385
+
386
+ Different fields merge automatically across devices. If two actors edit the same field concurrently, Cognex resolves deterministically with a last-writer-wins tuple `(timestamp, actor, op_id)`. Imported operations are idempotent, so the same operation can be received more than once without duplicating state.
387
+
388
+ REST examples:
389
+
390
+ ```bash
391
+ curl -X POST http://localhost:8080/v1/crdt/update \
392
+ -H 'Authorization: Bearer dev-secret' \
393
+ -H 'Content-Type: application/json' \
394
+ -d '{"actor":"alice","collection":"customers","id":"john","fields":{"name":"John"}}'
395
+
396
+ curl -X GET http://localhost:8080/v1/crdt/export \
397
+ -H 'Authorization: Bearer dev-secret'
398
+
399
+ curl -X POST http://localhost:8080/v1/crdt/import \
400
+ -H 'Authorization: Bearer dev-secret' \
401
+ -H 'Content-Type: application/json' \
402
+ -d '{"ops":[...]}'
403
+ ```
404
+
405
+ CLI examples:
406
+
407
+ ```bash
408
+ ./bin/cognex --root ./data crdt-update customers john --fields '{"name":"John"}' --actor alice
409
+ ./bin/cognex --root ./data crdt-export ./ops.json
410
+ ./bin/cognex --root ./other-device crdt-import ./ops.json
411
+ ```
412
+
413
+ The CRDT layer is best for structured JSON record fields. Its operation log is synced by `sync-push`/`sync-pull` through folders, Git repositories, or provider-synced folders such as Dropbox, iCloud, and Google Drive. Markdown body text is still stored and synced as files; rich collaborative text editing would require a specialized text CRDT layer later.
414
+
415
+ ## Local-first safety model
416
+
417
+ Cognex is not trying to beat PostgreSQL at global multi-writer clustering. It is designed for local-first ownership first, then optional sync later. The backend now protects local writes with:
418
+
419
+ - an inter-process `.cognex/write.lock` so two local writers do not write the same store at the same time;
420
+ - atomic temp-file writes plus `os.replace()` and fsync so power loss is less likely to leave half-written JSON/Markdown;
421
+ - per-record `revision` hashes returned by the API;
422
+ - optimistic concurrency through `expected_revision` or `If-Match`;
423
+ - HTTP `409 Conflict` when a stale frontend, user, or AI tries to overwrite a newer record;
424
+ - a SQLite `tx_log` table so local write history can be inspected.
425
+
426
+ This makes Cognex safer for single-user, personal, internal, and small-business local-first apps today. Filesystem/Git push-pull sync and structured JSON record CRDT merging are included, and sync carries CRDT operation logs between devices.
427
+
428
+ ## Security and production notes
429
+
430
+ - Set `COGNEX_API_KEY` in production.
431
+ - Set `COGNEX_CORS_ORIGIN` to your frontend URL.
432
+ - Mount persistent storage at `COGNEX_ROOT` on Railway.
433
+ - `/v1/query` only accepts read-only `SELECT`/`WITH` statements.
434
+ - Local writes are protected by an inter-process file lock, atomic temp-file replacement, SQLite WAL mode, optimistic record revisions, and a `tx_log` audit trail.
435
+ - Deletes are soft deletes: files are moved to timestamped `.deleted-*` backups.
436
+ - The REST server uses Python's standard library `ThreadingHTTPServer`, SQLite WAL mode, and no external runtime dependencies.
437
+
438
+ ## What is not included yet
439
+
440
+ Cognex now provides the production backend shape for your frontend, filesystem/Git sync, and structured JSON record CRDT operations. These are still future layers: user accounts/multi-tenancy, browser IndexedDB-native sync, provider API integrations for iCloud/Google Drive, rich-text CRDT editing, and a hosted dashboard.