@dboio/cli 0.19.7 → 0.20.0
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/README.md +18 -12
- package/bin/dbo.js +5 -0
- package/package.json +1 -1
- package/plugins/claude/dbo/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/dbo/commands/dbo.md +39 -12
- package/plugins/claude/dbo/docs/dbo-cli-readme.md +18 -12
- package/plugins/claude/dbo/skills/cookbook/SKILL.md +13 -3
- package/plugins/claude/dbo/skills/white-paper/SKILL.md +49 -8
- package/plugins/claude/dbo/skills/white-paper/references/api-reference.md +1 -1
- package/plugins/claude/track/.claude-plugin/plugin.json +1 -1
- package/src/commands/adopt.js +4 -3
- package/src/commands/clone.js +245 -55
- package/src/commands/init.js +2 -2
- package/src/commands/input.js +2 -2
- package/src/commands/login.js +3 -3
- package/src/commands/push.js +78 -18
- package/src/commands/status.js +15 -7
- package/src/lib/config.js +91 -11
- package/src/lib/filenames.js +54 -66
- package/src/lib/ignore.js +3 -0
- package/src/lib/insert.js +29 -45
- package/src/lib/structure.js +23 -8
- package/src/lib/ticketing.js +9 -8
- package/src/migrations/008-metadata-uid-in-suffix.js +4 -2
- package/src/migrations/009-fix-media-collision-metadata-names.js +9 -3
- package/src/migrations/013-remove-uid-from-meta-filenames.js +117 -0
- package/src/migrations/014-entity-dir-to-data-source.js +68 -0
package/README.md
CHANGED
|
@@ -140,7 +140,6 @@ my-project/
|
|
|
140
140
|
│ │ └── app/ # Default application bin
|
|
141
141
|
│ ├── automation/ # Automation entity records
|
|
142
142
|
│ ├── app_version/ # App version entity records
|
|
143
|
-
│ ├── entity/ # Entity definitions
|
|
144
143
|
│ ├── entity_column/ # Column definitions
|
|
145
144
|
│ ├── entity_column_value/ # Column value definitions
|
|
146
145
|
│ ├── extension/ # Extension entity records (organized by descriptor type)
|
|
@@ -149,7 +148,7 @@ my-project/
|
|
|
149
148
|
│ ├── integration/ # Integration entity records
|
|
150
149
|
│ ├── security/ # Security policy records
|
|
151
150
|
│ ├── security_column/ # Column-level security records
|
|
152
|
-
│ ├── data_source/ #
|
|
151
|
+
│ ├── data_source/ # Data source configs + entity (table) definitions
|
|
153
152
|
│ ├── group/ # (created when groups exist)
|
|
154
153
|
│ ├── site/ # (created when sites exist)
|
|
155
154
|
│ └── redirect/ # (created when redirects exist)
|
|
@@ -203,7 +202,9 @@ Per-user settings (plugin scopes, completed migrations) are stored globally in `
|
|
|
203
202
|
|
|
204
203
|
> **Upgrading to 0.16.0+**: `metadata_templates.json` is renamed to `metadata_schema.json`. The `_contentColumns` field in metadata files is renamed to `_companionReferenceColumns`. Extension companion file prompts during `dbo clone` are replaced by automatic derivation from `descriptor_definition` `form-control-code` data. Migration 011 runs automatically on first use.
|
|
205
204
|
|
|
206
|
-
> **Upgrading to 0.
|
|
205
|
+
> **Upgrading to 0.19.0+**: Metadata filenames no longer include `~UID` (e.g. `colors.metadata.json` instead of `colors.metadata~uid.json`). The UID is stored inside the JSON. Migration 013 automatically renames all metadata files.
|
|
206
|
+
|
|
207
|
+
> **Upgrading to 0.14.0+**: Metadata files previously used `name.metadata~uid.json` instead of `name~uid.metadata.json`. Migration 008 handles this rename automatically.
|
|
207
208
|
|
|
208
209
|
> **Upgrading to 0.13.3+**: Entity and extension companion files no longer include `~UID` in the filename. Migration 007 automatically renames legacy files.
|
|
209
210
|
|
|
@@ -298,8 +299,11 @@ Certain files live at the **project root** (not inside `lib/`) but are still tra
|
|
|
298
299
|
| `manifest.json` | content | Yes | [PWA web app manifest](https://developer.mozilla.org/en-US/docs/Web/Manifest) |
|
|
299
300
|
| `CLAUDE.md` | content | No | Claude Code project instructions |
|
|
300
301
|
| `README.md` | content | Yes | Project readme |
|
|
302
|
+
| `package.json` | content | No | Node.js package metadata and scripts |
|
|
303
|
+
| `.dboignore` | content | No | DBO CLI ignore patterns |
|
|
304
|
+
| `.gitignore` | content | No | Git ignore patterns |
|
|
301
305
|
|
|
302
|
-
**`dbo clone`** writes all
|
|
306
|
+
**`dbo clone`** writes all six to the project root. If the server has no record for a file, a stub is generated automatically (`manifest.json` from app metadata, `CLAUDE.md` and `README.md` from app name/description, `package.json` as a minimal stub). Matching works regardless of the server record's `BinID`: records are matched by name, `@`-reference, or `Path`, then relocated to the root — whether they live in `lib/bins/app/`, another bin, or have `BinID=null`. Records with `BinID=null` that aren't in the configured list are also promoted to the project root automatically.
|
|
303
307
|
|
|
304
308
|
**`dbo push`** auto-creates the companion metadata in `lib/bins/app/` for any listed root file that exists locally but has no tracked metadata yet — no manual `dbo adopt` needed before the first push.
|
|
305
309
|
|
|
@@ -322,11 +326,11 @@ The list of root content files is stored in `.app/config.json` under `rootConten
|
|
|
322
326
|
|
|
323
327
|
```json
|
|
324
328
|
{
|
|
325
|
-
"rootContentFiles": ["CLAUDE.md", "README.md", "manifest.json"]
|
|
329
|
+
"rootContentFiles": ["CLAUDE.md", "README.md", "manifest.json", "package.json", ".dboignore", ".gitignore"]
|
|
326
330
|
}
|
|
327
331
|
```
|
|
328
332
|
|
|
329
|
-
- **Absent**: defaults are written on the first `dbo push` — `["CLAUDE.md", "README.md", "manifest.json"]`
|
|
333
|
+
- **Absent**: defaults are written on the first `dbo push` — `["CLAUDE.md", "README.md", "manifest.json", "package.json", ".dboignore", ".gitignore"]`
|
|
330
334
|
- **`[]`, `false`, or `null`**: feature disabled — no root content files are auto-managed
|
|
331
335
|
- **Custom list**: any filename can be added; metadata is derived from the file extension
|
|
332
336
|
|
|
@@ -424,7 +428,7 @@ dbo init --scaffold --yes # scaffold dirs non-intera
|
|
|
424
428
|
| `--clone` | Clone the app after initialization |
|
|
425
429
|
| `-g, --global` | Install Claude commands globally (`~/.claude/commands/`) |
|
|
426
430
|
| `--local` | Install Claude commands to project (`.claude/commands/`) |
|
|
427
|
-
| `--scaffold` | Pre-create standard project directories (`app_version`, `automation`, `bins`, `data_source`, `docs`, `extension`, `group`, `integration`, `site`, `src`, `tests`, `trash`) |
|
|
431
|
+
| `--scaffold` | Pre-create standard project directories (`app_version`, `automation`, `bins`, `data_source`, `docs`, `extension`, `group`, `integration`, `site`, `src`, `tests`, `trash`). Note: `data_source/` is always scaffolded and also holds `entity` (table definition) records |
|
|
428
432
|
| `--dboignore` | Create `.dboignore` with default patterns (use with `--force` to overwrite existing) |
|
|
429
433
|
| `-y, --yes` | Skip all interactive prompts (legacy migration, Claude Code setup) |
|
|
430
434
|
| `--non-interactive` | Alias for `--yes` |
|
|
@@ -490,7 +494,7 @@ The project's reference domain is stored in `.app/<shortName>.metadata.json._dom
|
|
|
490
494
|
7. **Saves `.app/directories.json`** — maps BinIDs to directory paths for file placement
|
|
491
495
|
8. **Writes content files** — decodes base64 content, creates `*.metadata.json` + content files in the correct bin directory. Filename columns and companion file extraction preferences are auto-applied with sensible defaults on first clone (use `--configure` to re-prompt)
|
|
492
496
|
9. **Downloads media files** — classifies records into three scopes before downloading: `app` (`/media/<app>/app/...` or no FullPath — always downloaded), `user` (`/media/<app>/user/...` — opt-in, preference saved as `UserMedia` in `config.json`), and `foreign` (`/media/<other_app>/...` — silently skipped with stale metadata written). Fetches using a fallback chain: `FullPath` directly (`/media/{app}/{path}`) → `/dir/` route → `/api/media/{uid}`. 404 errors create stale metadata to prevent re-prompting. Errors are logged to `.app/errors.log`
|
|
493
|
-
10. **Processes entity-dir records** — entities matching project directories (`extension`, `app_version`, `data_source`, `site`, `group`, `integration`, `automation`) are saved as `.metadata.json` files in their corresponding directory (
|
|
497
|
+
10. **Processes entity-dir records** — entities matching project directories (`extension`, `app_version`, `data_source`, `entity`, `site`, `group`, `integration`, `automation`) are saved as `.metadata.json` files in their corresponding directory. Note: `entity` (table definitions) shares `lib/data_source/` with `data_source` records rather than using a separate directory
|
|
494
498
|
11. **Processes other entities** — remaining entities with a `BinID` are placed in the corresponding bin directory
|
|
495
499
|
12. **Saves `.app/<shortName>.metadata.json`** — clone of the original JSON with processed entries replaced by `@path/to/*.metadata.json` references
|
|
496
500
|
13. **Orphan cleanup** — any local `.metadata.json` files whose UID is absent from the server response are automatically moved to `trash/` along with their companion content and media files. This prevents stale records (deleted server-side) from causing false positives in `dbo push`. Skipped during `--entity-filter` clones
|
|
@@ -584,13 +588,14 @@ Where do you want me to place filename.ext?
|
|
|
584
588
|
|
|
585
589
|
#### Entity directory processing
|
|
586
590
|
|
|
587
|
-
Entity types that correspond to project directories (`extension`, `app_version`, `data_source`, `site`, `group`, `integration`, `automation`) are processed into their named directories without requiring a `BinID`:
|
|
591
|
+
Entity types that correspond to project directories (`extension`, `app_version`, `data_source`, `entity`, `site`, `group`, `integration`, `automation`) are processed into their named directories without requiring a `BinID`:
|
|
588
592
|
|
|
589
593
|
| Entity Key | Directory |
|
|
590
594
|
|------------|-----------|
|
|
591
595
|
| `extension` | `extension/<Descriptor>/` (see below) |
|
|
592
596
|
| `app_version` | `app_version/` |
|
|
593
597
|
| `data_source` | `data_source/` |
|
|
598
|
+
| `entity` | `data_source/` (co-located with data source records) |
|
|
594
599
|
| `site` | `site/` |
|
|
595
600
|
| `group` | `group/` |
|
|
596
601
|
| `integration` | `integration/` |
|
|
@@ -600,7 +605,7 @@ For each entity type, the CLI prompts to choose which column becomes the filenam
|
|
|
600
605
|
|
|
601
606
|
If any columns contain base64-encoded content, the CLI prompts to extract them as companion files. Extracted columns produce files named `<name>.<Column>.<ext>` alongside the metadata, with `@reference` entries in the metadata and a `_companionReferenceColumns` array (legacy name: `_contentColumns`, supported for backward compatibility).
|
|
602
607
|
|
|
603
|
-
**Companion file naming convention:**
|
|
608
|
+
**Companion file naming convention:** Metadata files use `name.metadata.json` (e.g. `Add-Asst-Execute-Security.metadata.json`). The UID is stored inside the JSON, not in the filename. Companion content files use the natural base name (e.g. `Add-Asst-Execute-Security.String5.html`). When a `{title}` is defined in the `@reference` expression (see [Metadata Schema](#metadata-schema)), the title replaces the column name in the filename (e.g. `Add-Asst-Execute-Security.Add-Form-Parameters.js` instead of `Add-Asst-Execute-Security.String5.js`). If two records share the same name within a directory, the second gets a `-1` suffix (e.g. `Add-Asst-Execute-Security-1.metadata.json`); content records have priority over output records for the unsuffixed slot.
|
|
604
609
|
|
|
605
610
|
Use `-y` to skip prompts (uses `Name` column, no content extraction).
|
|
606
611
|
|
|
@@ -644,7 +649,7 @@ dbo clone -e extension --descriptor-types false # Flat layout (no descript
|
|
|
644
649
|
|
|
645
650
|
#### Entity children embedding
|
|
646
651
|
|
|
647
|
-
When a server entity record contains nested child records (e.g., `entity_column` records nested under `entity` parents), `dbo clone` embeds them inline in the parent's `.metadata
|
|
652
|
+
When a server entity record contains nested child records (e.g., `entity_column` records nested under `entity` parents), `dbo clone` embeds them inline in the parent's `.metadata.json` file under a `children` key:
|
|
648
653
|
|
|
649
654
|
```json
|
|
650
655
|
{
|
|
@@ -693,7 +698,8 @@ project/
|
|
|
693
698
|
docs/ # ← root-placed documentation MD files (optional)
|
|
694
699
|
MyDoc.md
|
|
695
700
|
data_source/
|
|
696
|
-
MySQL-Primary.metadata.json
|
|
701
|
+
MySQL-Primary.metadata.json # _entity: "data_source"
|
|
702
|
+
Users.metadata.json # _entity: "entity" (table defs co-locate here)
|
|
697
703
|
site/
|
|
698
704
|
MainSite.metadata.json
|
|
699
705
|
# Media files placed by BinID into bins/ (alongside content)
|
package/bin/dbo.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dbo
|
|
3
|
-
description: Run DBO.io CLI commands for local file sync, project management, and deployment (push/pull/clone/
|
|
4
|
-
allowed-tools: Read, Write, Glob, Bash(git status:*), Bash(git branch:*), Bash(git diff:*), Bash(ls:*), Bash(dbo init:*), Bash(dbo login:*), Bash(dbo status:*), Bash(dbo deploy:*), Bash(dbo
|
|
3
|
+
description: Run DBO.io CLI commands for local file sync, project management, and deployment (push/pull/clone/adopt/rm/diff/build/deploy). NOT for direct API operations — for data reads/writes and runtime queries, use the REST API via curl with .app/cookies.txt instead.
|
|
4
|
+
allowed-tools: Read, Write, Glob, Bash(git status:*), Bash(git branch:*), Bash(git diff:*), Bash(ls:*), Bash(dbo init:*), Bash(dbo login:*), Bash(dbo status:*), Bash(dbo deploy:*), Bash(dbo adopt:*), Bash(dbo clone:*), Bash(dbo push:*), Bash(dbo pull:*), Bash(dbo diff:*), Bash(dbo rm:*), Bash(dbo mv:*), Bash(dbo run:*), Bash(dbo install:*), Bash(dbo build:*), Bash(git stash:*), Bash(grep:*), Bash(which dbo:*)
|
|
5
5
|
user-invokable: true
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -12,7 +12,7 @@ Run `dbo` CLI commands for local file operations, project management, and deploy
|
|
|
12
12
|
## CLI vs REST API — When to use what
|
|
13
13
|
|
|
14
14
|
**Use this CLI skill for file operations:**
|
|
15
|
-
- `pull`, `push`, `
|
|
15
|
+
- `pull`, `push`, `adopt`, `clone`, `rm`, `diff` — sync files between local project and server
|
|
16
16
|
- `deploy` — push a file to DBO by UID or named shorthand (shorthands defined in `.app/deploy_config.json`)
|
|
17
17
|
- `build`, `run` — compile source and run lifecycle scripts (configured in `.app/scripts.json`)
|
|
18
18
|
- `init`, `login`, `status` — project setup and auth
|
|
@@ -43,10 +43,10 @@ dbo $ARGUMENTS
|
|
|
43
43
|
| `init` | Initialize `.app/` configuration |
|
|
44
44
|
| `login` / `logout` | Authenticate / clear session |
|
|
45
45
|
| `status` | Show config, domain, session info |
|
|
46
|
-
| `clone` |
|
|
47
|
-
| `pull` |
|
|
46
|
+
| `clone` | Full project setup: config, bin dirs, dependencies, schema, then all records. Also used to refresh deps/schema without a full re-clone (see below). |
|
|
47
|
+
| `pull` | Content-only update — re-downloads changed records into existing local files. No dependency sync, no config changes, no scaffolding. Use this for routine day-to-day syncing. |
|
|
48
48
|
| `push` | Push local changes to server |
|
|
49
|
-
| `
|
|
49
|
+
| `adopt` | Create metadata companion for a local file (required before `push` for new files). Always pass `-e <entity>` — auto-inference is unreliable for content files. |
|
|
50
50
|
| `diff` | Compare local files vs server versions |
|
|
51
51
|
| `rm` | Remove file and stage server deletion |
|
|
52
52
|
| `deploy` | Push a file to DBO by UID or named shorthand |
|
|
@@ -54,6 +54,19 @@ dbo $ARGUMENTS
|
|
|
54
54
|
| `run` | Run a named script from `.app/scripts.json` |
|
|
55
55
|
| `install` | Install/upgrade CLI, plugins (alias: `i`) |
|
|
56
56
|
|
|
57
|
+
## clone vs pull — when to use each
|
|
58
|
+
|
|
59
|
+
| Situation | Command |
|
|
60
|
+
|-----------|---------|
|
|
61
|
+
| First-time project setup | `dbo clone` |
|
|
62
|
+
| Get latest file changes from server (routine) | `dbo pull` |
|
|
63
|
+
| Refresh a dependency app (`app_dependencies/`) | `dbo clone --dependencies <name> -y` |
|
|
64
|
+
| Refresh schema.json from server | `dbo clone --schema -y` (also re-clones records) |
|
|
65
|
+
| Add a new dependency app to the project | `dbo clone --dependencies <name> -y` |
|
|
66
|
+
| Re-clone without touching deps | `dbo clone --no-deps` |
|
|
67
|
+
|
|
68
|
+
`dbo pull` is a subset of `dbo clone`. It calls the same underlying logic but skips config setup, dependency sync, directory scaffolding, and collision detection. Use `pull` whenever you just need updated file content.
|
|
69
|
+
|
|
57
70
|
## Common workflows
|
|
58
71
|
|
|
59
72
|
```bash
|
|
@@ -61,6 +74,12 @@ dbo $ARGUMENTS
|
|
|
61
74
|
dbo init --domain my-domain.com --app myapp --clone
|
|
62
75
|
dbo login
|
|
63
76
|
|
|
77
|
+
# Routine content sync (day-to-day)
|
|
78
|
+
dbo pull # re-download changed records
|
|
79
|
+
dbo pull -y # auto-accept all incoming changes
|
|
80
|
+
dbo pull -e content # only content records
|
|
81
|
+
dbo pull --dry-run # preview what would change
|
|
82
|
+
|
|
64
83
|
# Edit and push
|
|
65
84
|
dbo push # push all changes in current dir
|
|
66
85
|
dbo push lib/bins/app/assets/ # push specific directory
|
|
@@ -76,14 +95,22 @@ dbo push --no-scripts # push without any hooks
|
|
|
76
95
|
dbo deploy css:colors # deploy using deploy_config.json shorthand
|
|
77
96
|
dbo deploy albain3dwkofbhnd1qtd1q # deploy by UID directly
|
|
78
97
|
|
|
79
|
-
#
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
dbo
|
|
84
|
-
dbo
|
|
98
|
+
# Add a new file (adopt → push — both steps required for new assets)
|
|
99
|
+
# Always pass -e <entity>. Auto-inference is unreliable; omitting -e causes failure.
|
|
100
|
+
dbo adopt -e content lib/bins/app/assets/css/newstyle.css # HTML/CSS/JS → content
|
|
101
|
+
dbo push lib/bins/app/assets/css/newstyle.css
|
|
102
|
+
dbo adopt -e media lib/bins/app/assets/img/logo.png # images/binaries → media
|
|
103
|
+
dbo push lib/bins/app/assets/img/logo.png
|
|
85
104
|
|
|
86
105
|
# Compare and merge
|
|
87
106
|
dbo diff # compare all local vs server
|
|
88
107
|
dbo diff -y # auto-accept all server changes
|
|
108
|
+
|
|
109
|
+
# Refresh dependencies and/or schema
|
|
110
|
+
# clone is the dependency/schema refresh mechanism — not intuitive from the name.
|
|
111
|
+
# --dependencies adds the app to config.json deps (union) then syncs only those apps (force).
|
|
112
|
+
dbo clone --dependencies operator -y # re-fetch one dependency
|
|
113
|
+
dbo clone --dependencies _system,operator -y # multiple deps (comma-separated)
|
|
114
|
+
dbo clone --schema -y # refresh schema.json (also re-clones records)
|
|
115
|
+
dbo clone --dependencies operator --schema -y # dep + schema in one pass
|
|
89
116
|
```
|
|
@@ -140,7 +140,6 @@ my-project/
|
|
|
140
140
|
│ │ └── app/ # Default application bin
|
|
141
141
|
│ ├── automation/ # Automation entity records
|
|
142
142
|
│ ├── app_version/ # App version entity records
|
|
143
|
-
│ ├── entity/ # Entity definitions
|
|
144
143
|
│ ├── entity_column/ # Column definitions
|
|
145
144
|
│ ├── entity_column_value/ # Column value definitions
|
|
146
145
|
│ ├── extension/ # Extension entity records (organized by descriptor type)
|
|
@@ -149,7 +148,7 @@ my-project/
|
|
|
149
148
|
│ ├── integration/ # Integration entity records
|
|
150
149
|
│ ├── security/ # Security policy records
|
|
151
150
|
│ ├── security_column/ # Column-level security records
|
|
152
|
-
│ ├── data_source/ #
|
|
151
|
+
│ ├── data_source/ # Data source configs + entity (table) definitions
|
|
153
152
|
│ ├── group/ # (created when groups exist)
|
|
154
153
|
│ ├── site/ # (created when sites exist)
|
|
155
154
|
│ └── redirect/ # (created when redirects exist)
|
|
@@ -203,7 +202,9 @@ Per-user settings (plugin scopes, completed migrations) are stored globally in `
|
|
|
203
202
|
|
|
204
203
|
> **Upgrading to 0.16.0+**: `metadata_templates.json` is renamed to `metadata_schema.json`. The `_contentColumns` field in metadata files is renamed to `_companionReferenceColumns`. Extension companion file prompts during `dbo clone` are replaced by automatic derivation from `descriptor_definition` `form-control-code` data. Migration 011 runs automatically on first use.
|
|
205
204
|
|
|
206
|
-
> **Upgrading to 0.
|
|
205
|
+
> **Upgrading to 0.19.0+**: Metadata filenames no longer include `~UID` (e.g. `colors.metadata.json` instead of `colors.metadata~uid.json`). The UID is stored inside the JSON. Migration 013 automatically renames all metadata files.
|
|
206
|
+
|
|
207
|
+
> **Upgrading to 0.14.0+**: Metadata files previously used `name.metadata~uid.json` instead of `name~uid.metadata.json`. Migration 008 handles this rename automatically.
|
|
207
208
|
|
|
208
209
|
> **Upgrading to 0.13.3+**: Entity and extension companion files no longer include `~UID` in the filename. Migration 007 automatically renames legacy files.
|
|
209
210
|
|
|
@@ -298,8 +299,11 @@ Certain files live at the **project root** (not inside `lib/`) but are still tra
|
|
|
298
299
|
| `manifest.json` | content | Yes | [PWA web app manifest](https://developer.mozilla.org/en-US/docs/Web/Manifest) |
|
|
299
300
|
| `CLAUDE.md` | content | No | Claude Code project instructions |
|
|
300
301
|
| `README.md` | content | Yes | Project readme |
|
|
302
|
+
| `package.json` | content | No | Node.js package metadata and scripts |
|
|
303
|
+
| `.dboignore` | content | No | DBO CLI ignore patterns |
|
|
304
|
+
| `.gitignore` | content | No | Git ignore patterns |
|
|
301
305
|
|
|
302
|
-
**`dbo clone`** writes all
|
|
306
|
+
**`dbo clone`** writes all six to the project root. If the server has no record for a file, a stub is generated automatically (`manifest.json` from app metadata, `CLAUDE.md` and `README.md` from app name/description, `package.json` as a minimal stub). Matching works regardless of the server record's `BinID`: records are matched by name, `@`-reference, or `Path`, then relocated to the root — whether they live in `lib/bins/app/`, another bin, or have `BinID=null`. Records with `BinID=null` that aren't in the configured list are also promoted to the project root automatically.
|
|
303
307
|
|
|
304
308
|
**`dbo push`** auto-creates the companion metadata in `lib/bins/app/` for any listed root file that exists locally but has no tracked metadata yet — no manual `dbo adopt` needed before the first push.
|
|
305
309
|
|
|
@@ -322,11 +326,11 @@ The list of root content files is stored in `.app/config.json` under `rootConten
|
|
|
322
326
|
|
|
323
327
|
```json
|
|
324
328
|
{
|
|
325
|
-
"rootContentFiles": ["CLAUDE.md", "README.md", "manifest.json"]
|
|
329
|
+
"rootContentFiles": ["CLAUDE.md", "README.md", "manifest.json", "package.json", ".dboignore", ".gitignore"]
|
|
326
330
|
}
|
|
327
331
|
```
|
|
328
332
|
|
|
329
|
-
- **Absent**: defaults are written on the first `dbo push` — `["CLAUDE.md", "README.md", "manifest.json"]`
|
|
333
|
+
- **Absent**: defaults are written on the first `dbo push` — `["CLAUDE.md", "README.md", "manifest.json", "package.json", ".dboignore", ".gitignore"]`
|
|
330
334
|
- **`[]`, `false`, or `null`**: feature disabled — no root content files are auto-managed
|
|
331
335
|
- **Custom list**: any filename can be added; metadata is derived from the file extension
|
|
332
336
|
|
|
@@ -424,7 +428,7 @@ dbo init --scaffold --yes # scaffold dirs non-intera
|
|
|
424
428
|
| `--clone` | Clone the app after initialization |
|
|
425
429
|
| `-g, --global` | Install Claude commands globally (`~/.claude/commands/`) |
|
|
426
430
|
| `--local` | Install Claude commands to project (`.claude/commands/`) |
|
|
427
|
-
| `--scaffold` | Pre-create standard project directories (`app_version`, `automation`, `bins`, `data_source`, `docs`, `extension`, `group`, `integration`, `site`, `src`, `tests`, `trash`) |
|
|
431
|
+
| `--scaffold` | Pre-create standard project directories (`app_version`, `automation`, `bins`, `data_source`, `docs`, `extension`, `group`, `integration`, `site`, `src`, `tests`, `trash`). Note: `data_source/` is always scaffolded and also holds `entity` (table definition) records |
|
|
428
432
|
| `--dboignore` | Create `.dboignore` with default patterns (use with `--force` to overwrite existing) |
|
|
429
433
|
| `-y, --yes` | Skip all interactive prompts (legacy migration, Claude Code setup) |
|
|
430
434
|
| `--non-interactive` | Alias for `--yes` |
|
|
@@ -490,7 +494,7 @@ The project's reference domain is stored in `.app/<shortName>.metadata.json._dom
|
|
|
490
494
|
7. **Saves `.app/directories.json`** — maps BinIDs to directory paths for file placement
|
|
491
495
|
8. **Writes content files** — decodes base64 content, creates `*.metadata.json` + content files in the correct bin directory. Filename columns and companion file extraction preferences are auto-applied with sensible defaults on first clone (use `--configure` to re-prompt)
|
|
492
496
|
9. **Downloads media files** — classifies records into three scopes before downloading: `app` (`/media/<app>/app/...` or no FullPath — always downloaded), `user` (`/media/<app>/user/...` — opt-in, preference saved as `UserMedia` in `config.json`), and `foreign` (`/media/<other_app>/...` — silently skipped with stale metadata written). Fetches using a fallback chain: `FullPath` directly (`/media/{app}/{path}`) → `/dir/` route → `/api/media/{uid}`. 404 errors create stale metadata to prevent re-prompting. Errors are logged to `.app/errors.log`
|
|
493
|
-
10. **Processes entity-dir records** — entities matching project directories (`extension`, `app_version`, `data_source`, `site`, `group`, `integration`, `automation`) are saved as `.metadata.json` files in their corresponding directory (
|
|
497
|
+
10. **Processes entity-dir records** — entities matching project directories (`extension`, `app_version`, `data_source`, `entity`, `site`, `group`, `integration`, `automation`) are saved as `.metadata.json` files in their corresponding directory. Note: `entity` (table definitions) shares `lib/data_source/` with `data_source` records rather than using a separate directory
|
|
494
498
|
11. **Processes other entities** — remaining entities with a `BinID` are placed in the corresponding bin directory
|
|
495
499
|
12. **Saves `.app/<shortName>.metadata.json`** — clone of the original JSON with processed entries replaced by `@path/to/*.metadata.json` references
|
|
496
500
|
13. **Orphan cleanup** — any local `.metadata.json` files whose UID is absent from the server response are automatically moved to `trash/` along with their companion content and media files. This prevents stale records (deleted server-side) from causing false positives in `dbo push`. Skipped during `--entity-filter` clones
|
|
@@ -584,13 +588,14 @@ Where do you want me to place filename.ext?
|
|
|
584
588
|
|
|
585
589
|
#### Entity directory processing
|
|
586
590
|
|
|
587
|
-
Entity types that correspond to project directories (`extension`, `app_version`, `data_source`, `site`, `group`, `integration`, `automation`) are processed into their named directories without requiring a `BinID`:
|
|
591
|
+
Entity types that correspond to project directories (`extension`, `app_version`, `data_source`, `entity`, `site`, `group`, `integration`, `automation`) are processed into their named directories without requiring a `BinID`:
|
|
588
592
|
|
|
589
593
|
| Entity Key | Directory |
|
|
590
594
|
|------------|-----------|
|
|
591
595
|
| `extension` | `extension/<Descriptor>/` (see below) |
|
|
592
596
|
| `app_version` | `app_version/` |
|
|
593
597
|
| `data_source` | `data_source/` |
|
|
598
|
+
| `entity` | `data_source/` (co-located with data source records) |
|
|
594
599
|
| `site` | `site/` |
|
|
595
600
|
| `group` | `group/` |
|
|
596
601
|
| `integration` | `integration/` |
|
|
@@ -600,7 +605,7 @@ For each entity type, the CLI prompts to choose which column becomes the filenam
|
|
|
600
605
|
|
|
601
606
|
If any columns contain base64-encoded content, the CLI prompts to extract them as companion files. Extracted columns produce files named `<name>.<Column>.<ext>` alongside the metadata, with `@reference` entries in the metadata and a `_companionReferenceColumns` array (legacy name: `_contentColumns`, supported for backward compatibility).
|
|
602
607
|
|
|
603
|
-
**Companion file naming convention:**
|
|
608
|
+
**Companion file naming convention:** Metadata files use `name.metadata.json` (e.g. `Add-Asst-Execute-Security.metadata.json`). The UID is stored inside the JSON, not in the filename. Companion content files use the natural base name (e.g. `Add-Asst-Execute-Security.String5.html`). When a `{title}` is defined in the `@reference` expression (see [Metadata Schema](#metadata-schema)), the title replaces the column name in the filename (e.g. `Add-Asst-Execute-Security.Add-Form-Parameters.js` instead of `Add-Asst-Execute-Security.String5.js`). If two records share the same name within a directory, the second gets a `-1` suffix (e.g. `Add-Asst-Execute-Security-1.metadata.json`); content records have priority over output records for the unsuffixed slot.
|
|
604
609
|
|
|
605
610
|
Use `-y` to skip prompts (uses `Name` column, no content extraction).
|
|
606
611
|
|
|
@@ -644,7 +649,7 @@ dbo clone -e extension --descriptor-types false # Flat layout (no descript
|
|
|
644
649
|
|
|
645
650
|
#### Entity children embedding
|
|
646
651
|
|
|
647
|
-
When a server entity record contains nested child records (e.g., `entity_column` records nested under `entity` parents), `dbo clone` embeds them inline in the parent's `.metadata
|
|
652
|
+
When a server entity record contains nested child records (e.g., `entity_column` records nested under `entity` parents), `dbo clone` embeds them inline in the parent's `.metadata.json` file under a `children` key:
|
|
648
653
|
|
|
649
654
|
```json
|
|
650
655
|
{
|
|
@@ -693,7 +698,8 @@ project/
|
|
|
693
698
|
docs/ # ← root-placed documentation MD files (optional)
|
|
694
699
|
MyDoc.md
|
|
695
700
|
data_source/
|
|
696
|
-
MySQL-Primary.metadata.json
|
|
701
|
+
MySQL-Primary.metadata.json # _entity: "data_source"
|
|
702
|
+
Users.metadata.json # _entity: "entity" (table defs co-locate here)
|
|
697
703
|
site/
|
|
698
704
|
MainSite.metadata.json
|
|
699
705
|
# Media files placed by BinID into bins/ (alongside content)
|
|
@@ -6,7 +6,7 @@ description: >-
|
|
|
6
6
|
or when the white-paper provides architecture context but you need behavioral
|
|
7
7
|
rules. Covers file operations, build recipes, metadata handling, and common
|
|
8
8
|
gotchas.
|
|
9
|
-
user-
|
|
9
|
+
user-invocable: true
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# DBO Project Cookbook
|
|
@@ -20,12 +20,13 @@ For architecture context, load the **white-paper** skill. For CLI command refere
|
|
|
20
20
|
## DOs
|
|
21
21
|
|
|
22
22
|
- **DO use UIDs, not numeric IDs, in templates.** Numeric IDs change across environments (dev → staging → prod). UIDs are stable and portable.
|
|
23
|
-
- **DO
|
|
23
|
+
- **DO always pass `-e <entity>` when running `dbo adopt`.** Every file in `lib/` needs a metadata companion. `dbo adopt path/to/file -e {entity}` creates one. Without it, `dbo push` won't know what server record to target. **Never omit `-e`** — auto-inference fails for most `lib/bins/` files because the directory maps to multiple entity types. Use `-e content` for HTML/CSS/JS/SQL, `-e media` for images and binaries.
|
|
24
24
|
- **DO build from `src/` before pushing compiled assets.** Check `.app/scripts.json` for the build command. Run `npm run build` or the specific build script, then push the compiled output from `lib/`.
|
|
25
25
|
- **DO check `.app/scripts.json` for build/postpush chains before manual deploys.** A file may have postpush hooks that auto-deploy dependent assets. Pushing manually with `dbo deploy` bypasses these chains.
|
|
26
|
-
- **DO read the metadata file before modifying a server-tracked file.** The `.metadata
|
|
26
|
+
- **DO read the metadata file before modifying a server-tracked file.** The `.metadata.json` companion tells you what entity, column, and record the file maps to (check the `UID` field inside the JSON). This context prevents wrong-target pushes.
|
|
27
27
|
- **DO use `dbo diff` to verify local vs server state before bulk pushes.** Catches unexpected server-side changes that would be overwritten.
|
|
28
28
|
- **DO check `app_dependencies/` for parent app patterns when building extensions.** Descriptor definitions, CSS design tokens, and JS APIs from the parent app define what's available.
|
|
29
|
+
- **DO know that `dbo clone` skips dependencies that are already up to date.** Before re-cloning a dependency, the CLI hits `/api/app/object/<name>?UpdatedAfter=<stored-date>` and compares `_LastUpdated`. If the server hasn't changed, the dep is skipped silently. Use `--force` or `--schema` to bypass this check and force a re-clone.
|
|
29
30
|
- **DO use the REST API with `.app/cookies.txt` for data operations, CLI for file operations.** The CLI handles metadata sync; the API handles data reads/writes. Don't cross these boundaries.
|
|
30
31
|
- **DO check `.app/deploy_config.json` for existing shorthands before creating deploy commands.** Shorthands are auto-generated by `dbo clone` and `dbo adopt`.
|
|
31
32
|
- **DO use `dbo push --confirm false` to validate before committing a push.** Dry-run catches issues without touching the server.
|
|
@@ -135,6 +136,15 @@ Look at `targets.{file}.build` for compile commands and `targets.{file}.postpush
|
|
|
135
136
|
**Cause:** You pushed only the content record but not the media companion (or vice versa).
|
|
136
137
|
**Fix:** Push both — check `deploy_config.json` for paired `{name}` and `{name}_media` entries.
|
|
137
138
|
|
|
139
|
+
### `dbo adopt` fails — entity cannot be inferred
|
|
140
|
+
**Symptom:** `dbo adopt path/to/file` errors with "entity cannot be inferred" or similar.
|
|
141
|
+
**Cause:** `-e <entity>` was omitted. Auto-inference only works for exact directive template matches. Files in `lib/bins/` (HTML, CSS, JS, SQL) almost never infer correctly because `lib/bins/` maps to multiple entity types.
|
|
142
|
+
**Fix:** Always pass `-e content` for text/code files, `-e media` for images and binaries:
|
|
143
|
+
```bash
|
|
144
|
+
dbo adopt lib/bins/app/user_first_names.html -e content
|
|
145
|
+
dbo adopt lib/bins/app/assets/img/logo.png -e media
|
|
146
|
+
```
|
|
147
|
+
|
|
138
148
|
### Wrong entity type on adopt
|
|
139
149
|
**Symptom:** Pushed file lands in unexpected server location.
|
|
140
150
|
**Cause:** Used wrong `-e` flag on `dbo adopt` (e.g., `-e media` for a text file).
|
|
@@ -49,10 +49,9 @@ project-root/
|
|
|
49
49
|
├── lib/ # Server-mapped files (mirrors DBO table data)
|
|
50
50
|
│ ├── bins/ # Bin entities and their children (see Bin Mapping below)
|
|
51
51
|
│ ├── extension/ # Extension records, sub-foldered by Descriptor
|
|
52
|
-
│ ├──
|
|
52
|
+
│ ├── data_source/ # Data source configs + entity (table) definitions
|
|
53
53
|
│ ├── site/ # Site definitions
|
|
54
54
|
│ ├── security/ # Security rule records
|
|
55
|
-
│ ├── data_source/ # Data source configurations
|
|
56
55
|
│ └── app_version/ # App version metadata
|
|
57
56
|
│
|
|
58
57
|
├── docs/ # Project documentation (scripts, embeds, pages, components)
|
|
@@ -83,11 +82,11 @@ Files belonging to a `bin` entity are placed in directories matching their BinID
|
|
|
83
82
|
}
|
|
84
83
|
```
|
|
85
84
|
|
|
86
|
-
So `lib/bins/app/assets/css/colors.css` lives inside the bin whose `fullPath` is `app/assets/css`. Every file has a companion `.metadata.json` (
|
|
85
|
+
So `lib/bins/app/assets/css/colors.css` lives inside the bin whose `fullPath` is `app/assets/css`. Every file has a companion `.metadata.json` (e.g. `colors.metadata.json`) containing the server record fields, including the `UID` field.
|
|
87
86
|
|
|
88
87
|
### Non-bin entities (no BinID column)
|
|
89
88
|
|
|
90
|
-
Entities without a BinID column get their own directory under `lib/`, named after the entity: `lib/extension/`, `lib/
|
|
89
|
+
Entities without a BinID column get their own directory under `lib/`, named after the entity: `lib/extension/`, `lib/site/`, `lib/security/`, `lib/data_source/`, `lib/app_version/`. Exception: `entity` (table definitions) shares `lib/data_source/` rather than getting its own directory — both `_entity: "data_source"` and `_entity: "entity"` records live there.
|
|
91
90
|
|
|
92
91
|
### Extension special case
|
|
93
92
|
|
|
@@ -96,7 +95,7 @@ The `extension` entity has sub-folders based on the **Descriptor** column value:
|
|
|
96
95
|
- `lib/extension/Widget/` — Widget extensions
|
|
97
96
|
- `lib/extension/Descriptor Definition/` — Descriptor definitions themselves
|
|
98
97
|
|
|
99
|
-
Each extension file follows: `{Name}.{ContentColumnName}.{ext}` with a companion `{Name}.metadata
|
|
98
|
+
Each extension file follows: `{Name}.{ContentColumnName}.{ext}` with a companion `{Name}.metadata.json` (UID stored inside the JSON).
|
|
100
99
|
|
|
101
100
|
## .app/ Configuration
|
|
102
101
|
|
|
@@ -152,10 +151,10 @@ When `app_dependencies/{app_name}/` exists (e.g., `app_dependencies/operator/`),
|
|
|
152
151
|
## CLI vs REST API
|
|
153
152
|
|
|
154
153
|
### Use the DBO CLI for:
|
|
155
|
-
- **File operations**: `pull`, `push`, `
|
|
154
|
+
- **File operations**: `pull`, `push`, `adopt`, `clone`, `rm`, `diff` — for `adopt`, always pass `-e <entity>` (e.g., `-e content` for HTML/CSS/JS, `-e media` for images/binaries); entity cannot be inferred for standalone files in `lib/bins/`
|
|
156
155
|
- **Deployment**: `deploy` (shorthand or UID), content deploy
|
|
157
156
|
- **Project setup**: `init`, `login`, `status`
|
|
158
|
-
- **Batch operations**: pushing directories, scanning for
|
|
157
|
+
- **Batch operations**: pushing directories, scanning for unadopted files
|
|
159
158
|
|
|
160
159
|
The CLI handles metadata management, change detection, and file-to-record synchronization automatically.
|
|
161
160
|
|
|
@@ -182,6 +181,48 @@ RowID:del{id};entity:entityName=true # Delete
|
|
|
182
181
|
```
|
|
183
182
|
Always include `_confirm=true`. Special values: `_{now}` (datetime), `_{null}` (null).
|
|
184
183
|
|
|
184
|
+
## Creating New Assets
|
|
185
|
+
|
|
186
|
+
Two approaches — choose based on whether the file exists locally first or on the server first.
|
|
187
|
+
|
|
188
|
+
### File-first (CLI)
|
|
189
|
+
|
|
190
|
+
Use when you're creating a new file locally and want the server to create the record.
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
# 1. Write the file in the correct lib/ subdirectory
|
|
194
|
+
# 2. Create the metadata companion (required before push)
|
|
195
|
+
dbo adopt -e content lib/bins/app/my-file.html # HTML/CSS/JS/SQL → content
|
|
196
|
+
dbo adopt -e media lib/bins/app/assets/img/x.png # images/binaries → media
|
|
197
|
+
|
|
198
|
+
# 3. Push — inserts a new record on the server, assigns a UID, updates local metadata
|
|
199
|
+
dbo push lib/bins/app/my-file.html
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Always pass `-e <entity>` to `adopt`. Entity cannot be inferred for standalone files in `lib/bins/` because the directory maps to multiple entity types.
|
|
203
|
+
|
|
204
|
+
### Server-first (REST API)
|
|
205
|
+
|
|
206
|
+
Use when you want to create the server record first, then pull the file locally. Required fields for the insert come from three local config files:
|
|
207
|
+
|
|
208
|
+
- **`.app/<app_short_name>.metadata_schema.json`** — entity schema: which columns are required, their types and allowed values
|
|
209
|
+
- **`.app/directories.json`** — BinID for the target directory (needed for bin-based entities like `content` and `media`)
|
|
210
|
+
- **`.app/config.json`** — `AppID`, `AppUID`, and other app-level fields required on most records
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
# 1. Insert the record via REST API (RowID:add1 — must use RowID:, not RowUID:)
|
|
214
|
+
curl -b .app/cookies.txt \
|
|
215
|
+
"https://{{domain}}/api/input/submit?_confirm=true" \
|
|
216
|
+
--data-urlencode 'RowID:add1;column:content.BinID=11042' \
|
|
217
|
+
--data-urlencode 'RowID:add1;column:content.AppID={{appID}}' \
|
|
218
|
+
--data-urlencode 'RowID:add1;column:content.Name=My File'
|
|
219
|
+
|
|
220
|
+
# 2. Pull to create the local file and metadata companion
|
|
221
|
+
dbo pull -e content --filter 'Name=My File'
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
After pull, the file appears in `lib/bins/` at the path matching its BinID in `directories.json`, with a `.metadata.json` companion.
|
|
225
|
+
|
|
185
226
|
## docs/ Directory
|
|
186
227
|
|
|
187
228
|
Contains Markdown documentation for this project's components — scripts, embeds, pages, UI features. These are project-specific references generated or maintained alongside development. Read these to understand documented behaviors of the current app.
|
|
@@ -213,7 +254,7 @@ The `test/` directory is for developer and Claude Code test scripts. Tests targe
|
|
|
213
254
|
| Write/update data | REST API | `POST /api/input/submit` |
|
|
214
255
|
| Pull files from server | CLI | `dbo pull -e content` |
|
|
215
256
|
| Push local changes | CLI | `dbo push path/to/file` |
|
|
216
|
-
| Add new file to server | CLI | `dbo
|
|
257
|
+
| Add new file to server | CLI | `dbo adopt path/to/file -e <entity>` |
|
|
217
258
|
| Deploy by shorthand | CLI | `dbo deploy css:colors` |
|
|
218
259
|
| Deploy by UID | CLI | `dbo deploy {uid}` |
|
|
219
260
|
| Compare with server | CLI | `dbo diff` |
|
|
@@ -87,7 +87,7 @@ RowID:{ref};column:{entity}.{Column}={value}
|
|
|
87
87
|
| `{id}` or `{uid}` | Update existing record |
|
|
88
88
|
| `del{id}` | Delete record |
|
|
89
89
|
|
|
90
|
-
`RowID:` and `RowUID:` are interchangeable. Use `RowUID:` for cross-environment stability.
|
|
90
|
+
`RowID:` and `RowUID:` are interchangeable for updates and deletes. Use `RowUID:` for cross-environment stability. **Inserts (`add1`, `add2`, …) must use `RowID:` — `RowUID:` does not work for inserts.**
|
|
91
91
|
|
|
92
92
|
### Cross-referencing within a batch
|
|
93
93
|
```
|
package/src/commands/adopt.js
CHANGED
|
@@ -159,7 +159,7 @@ async function adoptSingleFile(filePath, entityArg, options) {
|
|
|
159
159
|
// These files live at the project root but their metadata goes in lib/bins/app/.
|
|
160
160
|
// They bypass the dboignore check and entity inference.
|
|
161
161
|
const rootFiles = await loadRootContentFiles();
|
|
162
|
-
if (rootFiles.
|
|
162
|
+
if (rootFiles.some(f => f.toLowerCase() === fileName.toLowerCase()) && relPath === fileName) {
|
|
163
163
|
const appConfig = await loadAppConfig();
|
|
164
164
|
const structure = await loadStructureFile();
|
|
165
165
|
const appBin = findBinByPath('app', structure);
|
|
@@ -189,7 +189,8 @@ async function adoptSingleFile(filePath, entityArg, options) {
|
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
-
const
|
|
192
|
+
const tmplKey = Object.keys(ROOT_FILE_TEMPLATES).find(k => k.toLowerCase() === fileName.toLowerCase());
|
|
193
|
+
const tmpl = (tmplKey ? ROOT_FILE_TEMPLATES[tmplKey] : null) || { Extension: ext, Public: 0, Active: 1, Title: fileName };
|
|
193
194
|
const meta = {
|
|
194
195
|
_entity: 'content',
|
|
195
196
|
_companionReferenceColumns: ['Content'],
|
|
@@ -292,7 +293,7 @@ async function adoptSingleFile(filePath, entityArg, options) {
|
|
|
292
293
|
Name: docBase,
|
|
293
294
|
};
|
|
294
295
|
if (appConfig.AppID) docMeta.AppID = appConfig.AppID;
|
|
295
|
-
const contentCol = '
|
|
296
|
+
const contentCol = 'Text';
|
|
296
297
|
docMeta[contentCol] = `@/${relPath}`;
|
|
297
298
|
docMeta._companionReferenceColumns = [contentCol];
|
|
298
299
|
|