morphdb 0.1.4__tar.gz → 0.1.5__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.
- {morphdb-0.1.4 → morphdb-0.1.5}/PKG-INFO +1 -1
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/__init__.py +1 -1
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/skill/SKILL.md +26 -10
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/skill/scripts/morphdb_schema.py +12 -2
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb.egg-info/PKG-INFO +1 -1
- {morphdb-0.1.4 → morphdb-0.1.5}/pyproject.toml +1 -1
- {morphdb-0.1.4 → morphdb-0.1.5}/LICENSE +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/README.md +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/__main__.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/apps.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/associations.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/cli/__init__.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/cli/dashboard.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/cli/main.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/cli/mcp.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/cli/service.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/cli/skill.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/db.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/errors.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/fieldindex.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/fieldtypes.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/objects.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/router.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/routes.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/schema.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/server.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb/util.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb.egg-info/SOURCES.txt +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb.egg-info/dependency_links.txt +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb.egg-info/entry_points.txt +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb.egg-info/requires.txt +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/morphdb.egg-info/top_level.txt +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/setup.cfg +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/tests/test_apps.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/tests/test_cli.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/tests/test_core.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/tests/test_field_index.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/tests/test_hardening.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/tests/test_includes.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/tests/test_mcp.py +0 -0
- {morphdb-0.1.4 → morphdb-0.1.5}/tests/test_relations.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: morphdb
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: A coding-agent-friendly, multi-tenant backend for vibe-coded websites. One process hosts many isolated apps; reshape each app's schema as fast as your agent iterates while the frontend keeps calling the same generic endpoints.
|
|
5
5
|
Author: morphdb contributors
|
|
6
6
|
License: MIT
|
|
@@ -34,11 +34,18 @@ localhost-scale dev tool.
|
|
|
34
34
|
|
|
35
35
|
## The MorphDB tools (how you reshape the data model)
|
|
36
36
|
|
|
37
|
-
These come from the `morphdb` MCP server.
|
|
38
|
-
`
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
These come from the `morphdb` MCP server. **First, check which path you're on:**
|
|
38
|
+
look for tools named `add_field` / `add_relation` (in Claude Code they appear as
|
|
39
|
+
`mcp__morphdb__add_field`). **If you see them, use them** (this section). **If you
|
|
40
|
+
don't** — a hosted `MORPHDB_HOST` setup, or the MCP server just isn't wired up —
|
|
41
|
+
don't keep trying to call them and don't give up: skip to the **"Fallback: no
|
|
42
|
+
MorphDB tools available?"** section at the end and drive the bundled script
|
|
43
|
+
instead. Everything else in this skill (the data model, the endpoints, the
|
|
44
|
+
queries) applies either way.
|
|
45
|
+
|
|
46
|
+
When the tools are present, they each take the app key as `app` (or default to the
|
|
47
|
+
`$MORPHDB_APP` env var). The tools talk to the backend for you and **auto-start it**
|
|
48
|
+
if it is not running, so you don't have to manage the server in the common case.
|
|
42
49
|
|
|
43
50
|
| Tool | What it does |
|
|
44
51
|
| --- | --- |
|
|
@@ -276,6 +283,12 @@ applies here — cheap context that keeps later edits consistent.
|
|
|
276
283
|
strings → numbers. A boolean for a `number` field is rejected.
|
|
277
284
|
- A relation may not share a name with a field on the same type. A non-symmetric
|
|
278
285
|
self-relation needs distinct forward/inverse names (or use `symmetric`).
|
|
286
|
+
- The **inverse** of a relation shows up on the *other* type, not in the
|
|
287
|
+
`add_relation` response — `describe_type` the target type to see it (declare
|
|
288
|
+
`order.customer`, and `customer.orders` appears on `customer`). Inverse names only
|
|
289
|
+
need to be unique on the type they land on, so two relations can reuse an inverse
|
|
290
|
+
label when they point at **different** target types (`review.book` and
|
|
291
|
+
`review.author` can both use inverse `reviews`).
|
|
279
292
|
- Setting a relation is set-as-field (the value becomes its full set). For a
|
|
280
293
|
single-valued slot already taken, **last write wins** (the old link is moved).
|
|
281
294
|
`null`/`[]` clears.
|
|
@@ -296,12 +309,15 @@ still do schema edits with the bundled zero-dependency script — it hits the sa
|
|
|
296
309
|
HTTP API and takes `--app KEY` (or `$MORPHDB_APP`):
|
|
297
310
|
|
|
298
311
|
```bash
|
|
299
|
-
|
|
300
|
-
|
|
312
|
+
# define a helper (a function works in both bash and zsh; a "VAR=…; $VAR"
|
|
313
|
+
# alias does NOT word-split in zsh, so use this form)
|
|
314
|
+
mdb() { python3 ~/.claude/skills/morphdb/scripts/morphdb_schema.py "$@"; }
|
|
315
|
+
mdb register-app my-cool-site
|
|
301
316
|
export MORPHDB_APP=my-cool-site
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
317
|
+
mdb add-field task title string
|
|
318
|
+
mdb add-field task status string --index # --index → filterable/sortable (like index:true)
|
|
319
|
+
mdb add-relation task assignee --to user --cardinality many_to_one --inverse tasks
|
|
320
|
+
mdb list ; mdb show task
|
|
305
321
|
```
|
|
306
322
|
|
|
307
323
|
Prefer the tools when they exist; the script is the no-MCP fallback. To wire the
|
|
@@ -23,7 +23,7 @@ Usage:
|
|
|
23
23
|
list Show every type in the app (fields + relations).
|
|
24
24
|
show <type> Show one type's schema.
|
|
25
25
|
|
|
26
|
-
add-field <type> <name> <ftype> [--default V] [--required]
|
|
26
|
+
add-field <type> <name> <ftype> [--default V] [--required] [--index]
|
|
27
27
|
drop-field <type> <name>
|
|
28
28
|
|
|
29
29
|
add-relation <type> <name> --to T --cardinality C
|
|
@@ -43,6 +43,10 @@ Cardinalities: one_to_one, one_to_many, many_to_one, many_to_many.
|
|
|
43
43
|
A relation is declared once (on the "from" side); its inverse appears
|
|
44
44
|
automatically on the other type. Use --symmetric for mutual links within one
|
|
45
45
|
type (to == <type>, cardinality one_to_one or many_to_many).
|
|
46
|
+
|
|
47
|
+
Indexing: a field can only be filtered or sorted (GET /objects/{type}?field=…)
|
|
48
|
+
if it was added with --index (json fields can't be indexed). Relations are
|
|
49
|
+
always filterable without a flag. Index the few fields you actually query.
|
|
46
50
|
"""
|
|
47
51
|
|
|
48
52
|
import argparse
|
|
@@ -141,6 +145,8 @@ def cmd_add_field(url, app, args):
|
|
|
141
145
|
fdef["default"] = _parse_default(args.default)
|
|
142
146
|
if args.required:
|
|
143
147
|
fdef["required"] = True
|
|
148
|
+
if args.index:
|
|
149
|
+
fdef["index"] = True
|
|
144
150
|
# merge:true so existing fields/relations are untouched.
|
|
145
151
|
doc = {"merge": True, "fields": {args.name: fdef}}
|
|
146
152
|
_pretty(_put_type(url, app, args.type, doc))
|
|
@@ -222,7 +228,8 @@ def cmd_set(url, app, args):
|
|
|
222
228
|
def build_parser():
|
|
223
229
|
p = argparse.ArgumentParser(prog="morphdb_schema", description=__doc__,
|
|
224
230
|
formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
225
|
-
p.add_argument("--url", default=DEFAULT_URL,
|
|
231
|
+
p.add_argument("--url", default=DEFAULT_URL,
|
|
232
|
+
help=f"MorphDB base URL (default {DEFAULT_URL}; or set $MORPHDB_HOST)")
|
|
226
233
|
p.add_argument("--app", default=None,
|
|
227
234
|
help="App key (default $MORPHDB_APP). Required except for register-app/delete-app.")
|
|
228
235
|
sub = p.add_subparsers(dest="command", required=True)
|
|
@@ -241,6 +248,9 @@ def build_parser():
|
|
|
241
248
|
sp.add_argument("type"); sp.add_argument("name")
|
|
242
249
|
sp.add_argument("ftype", choices=["string", "number", "boolean", "json", "datetime"])
|
|
243
250
|
sp.add_argument("--default"); sp.add_argument("--required", action="store_true")
|
|
251
|
+
sp.add_argument("--index", action="store_true",
|
|
252
|
+
help="make this field filterable/sortable (backfills existing "
|
|
253
|
+
"objects; json can't be indexed)")
|
|
244
254
|
sp.set_defaults(func=cmd_add_field)
|
|
245
255
|
|
|
246
256
|
sp = sub.add_parser("drop-field")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: morphdb
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: A coding-agent-friendly, multi-tenant backend for vibe-coded websites. One process hosts many isolated apps; reshape each app's schema as fast as your agent iterates while the frontend keeps calling the same generic endpoints.
|
|
5
5
|
Author: morphdb contributors
|
|
6
6
|
License: MIT
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "morphdb"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.5"
|
|
8
8
|
description = "A coding-agent-friendly, multi-tenant backend for vibe-coded websites. One process hosts many isolated apps; reshape each app's schema as fast as your agent iterates while the frontend keeps calling the same generic endpoints."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|