@dboio/cli 0.10.1 → 0.11.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/README.md +135 -70
- package/bin/postinstall.js +9 -1
- package/package.json +3 -3
- package/plugins/claude/dbo/commands/dbo.md +3 -3
- package/plugins/claude/dbo/skills/cli/SKILL.md +3 -3
- package/src/commands/add.js +4 -0
- package/src/commands/clone.js +249 -399
- package/src/commands/content.js +7 -3
- package/src/commands/deploy.js +22 -7
- package/src/commands/diff.js +41 -3
- package/src/commands/init.js +25 -60
- package/src/commands/input.js +5 -0
- package/src/commands/login.js +2 -2
- package/src/commands/mv.js +3 -0
- package/src/commands/output.js +8 -10
- package/src/commands/pull.js +12 -8
- package/src/commands/push.js +317 -42
- package/src/commands/rm.js +3 -0
- package/src/commands/status.js +12 -1
- package/src/commands/sync.js +3 -0
- package/src/lib/client.js +10 -0
- package/src/lib/config.js +31 -0
- package/src/lib/delta.js +92 -0
- package/src/lib/diff.js +143 -19
- package/src/lib/ignore.js +1 -2
- package/src/lib/metadata-templates.js +21 -4
- package/src/lib/migrations.js +75 -0
- package/src/lib/save-to-disk.js +1 -1
- package/src/lib/scaffold.js +3 -28
- package/src/lib/structure.js +158 -23
- package/src/lib/toe-stepping.js +381 -0
- package/src/migrations/001-transaction-key-preset-scope.js +35 -0
- package/src/migrations/002-move-entity-dirs-to-lib.js +190 -0
- package/src/migrations/003-move-deploy-config.js +50 -0
- package/src/migrations/004-rename-output-files.js +101 -0
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ This installs the `dbo` command globally on your system.
|
|
|
20
20
|
### From the repository (local development)
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
cd tools/
|
|
23
|
+
cd tools/cli
|
|
24
24
|
npm install
|
|
25
25
|
npm link
|
|
26
26
|
```
|
|
@@ -108,7 +108,7 @@ dbo login
|
|
|
108
108
|
dbo status
|
|
109
109
|
|
|
110
110
|
# 4. Query some data
|
|
111
|
-
dbo output -e user --
|
|
111
|
+
dbo output -e user --template json_indented --maxrows 5
|
|
112
112
|
|
|
113
113
|
# 5. Deploy a CSS file
|
|
114
114
|
dbo content deploy albain3dwkofbhnd1qtd1q assets/css/colors.css
|
|
@@ -124,28 +124,38 @@ When you run `dbo init --scaffold` or `dbo clone`, the following standard direct
|
|
|
124
124
|
my-project/
|
|
125
125
|
├── .dbo/ # Config, synchronization and session info for dbo cli commands
|
|
126
126
|
├── .claude/ # Claude Code plugin config (commands, specs, plans, skills)
|
|
127
|
-
├──
|
|
127
|
+
├── lib/ # All DBO server-managed assets
|
|
128
|
+
│ ├── bins/ # Assets (contents, outputs, images, HTML, CSS)
|
|
129
|
+
│ │ └── app/ # Default application bin
|
|
130
|
+
│ ├── automation/ # Automation entity records
|
|
131
|
+
│ ├── app_version/ # App version entity records
|
|
132
|
+
│ ├── entity/ # Entity definitions
|
|
133
|
+
│ ├── entity_column/ # Column definitions
|
|
134
|
+
│ ├── entity_column_value/ # Column value definitions
|
|
135
|
+
│ ├── extension/ # Extension entity records (organized by descriptor type)
|
|
136
|
+
│ │ ├── widget/
|
|
137
|
+
│ │ ├── documentation/
|
|
138
|
+
│ │ └── _unsupported/
|
|
139
|
+
│ ├── integration/ # Integration entity records
|
|
140
|
+
│ ├── security/ # Security policy records
|
|
141
|
+
│ ├── security_column/ # Column-level security records
|
|
142
|
+
│ ├── data_source/ # (created when data sources exist)
|
|
143
|
+
│ ├── group/ # (created when groups exist)
|
|
144
|
+
│ ├── site/ # (created when sites exist)
|
|
145
|
+
│ └── redirect/ # (created when redirects exist)
|
|
128
146
|
├── src/ # Your actual source code (sass, typescript, etc.)
|
|
129
|
-
├──
|
|
130
|
-
├── bins/ # Assets (contents, outputs, images, HTML, CSS)
|
|
147
|
+
├── test/ # Project-level tests
|
|
131
148
|
├── trash/ # Staged soft-deleted files from dbo rm
|
|
132
|
-
├── automation/ # Automation entity records
|
|
133
|
-
├── app_version/ # App version entity records
|
|
134
|
-
├── data_source/ # Data source entity records
|
|
135
149
|
├── docs/ # Project documentation and docs entities
|
|
136
|
-
├──
|
|
137
|
-
|
|
138
|
-
│ └── _unsupported/ # Extensions with unrecognized descriptor types
|
|
139
|
-
├── group/ # Group entity records
|
|
140
|
-
├── integration/ # Integration entity records
|
|
141
|
-
├── site/ # Site entity records
|
|
150
|
+
├── app.json # Clone of original app JSON with @references
|
|
151
|
+
├── manifest.json # PWA web app manifest (auto-generated from app metadata)
|
|
142
152
|
├── .gitignore # Tells Git to ignore files in the repo sync
|
|
143
153
|
├── .dboignore # Tells dbo cli to ignore files in commands
|
|
144
154
|
├── package.json # Metadata, scripts, and dependency list
|
|
145
155
|
└── package-lock.json # Records exact versions of dependencies installed
|
|
146
156
|
```
|
|
147
157
|
|
|
148
|
-
> **Breaking change
|
|
158
|
+
> **Breaking change in 0.11.1**: All server-managed directories (`bins/`, `extension/`, `automation/`, etc.) have moved into a `lib/` subdirectory. Existing projects are migrated **automatically** on the first `dbo` command after upgrade. Also, `tests/` has been renamed to `test/`.
|
|
149
159
|
|
|
150
160
|
---
|
|
151
161
|
|
|
@@ -163,18 +173,34 @@ All configuration is **directory-scoped**. Each project folder maintains its own
|
|
|
163
173
|
| File | Purpose | Git |
|
|
164
174
|
|------|---------|-----|
|
|
165
175
|
| `config.json` | Domain, app metadata, placement preferences | Committable (shared) |
|
|
166
|
-
| `config.local.json` | Per-user settings: plugin scopes,
|
|
176
|
+
| `config.local.json` | Per-user settings: plugin scopes, `_completedMigrations` (system-managed) | Gitignored (per-user) |
|
|
167
177
|
| `ticketing.local.json` | Stored ticket IDs for submission error recovery | Gitignored (per-user) |
|
|
168
178
|
| `credentials.json` | Username, user ID, UID, name, email (no password) | Gitignored (per-user) |
|
|
169
179
|
| `cookies.txt` | Session cookie (Netscape format) | Gitignored (per-user) |
|
|
170
180
|
| `structure.json` | Bin directory mapping (created by `dbo clone`) | Committable (shared) |
|
|
171
181
|
| `metadata_templates.json` | Column templates per entity/descriptor (auto-generated by `dbo clone`) | Committable (shared) |
|
|
172
|
-
|
|
|
182
|
+
| `synchronize.json` | Pending deletions and sync state (updated by `dbo rm` and `dbo push`) | Committable (shared) |
|
|
183
|
+
| `.app_baseline.json` | Server-state snapshot for delta detection — stores column values at last clone/push so `dbo push` can detect which columns changed locally. Read-only (chmod 444); auto-migrated from legacy root `.app.json`. | Committable (shared) |
|
|
173
184
|
|
|
174
185
|
`dbo init` automatically adds `.dbo/credentials.json`, `.dbo/cookies.txt`, `.dbo/config.local.json`, and `.dbo/ticketing.local.json` to `.gitignore` (creates the file if it doesn't exist).
|
|
175
186
|
|
|
176
187
|
> **Upgrading from pre-0.9.9**: The baseline file `.app.json` in the project root has moved to `.dbo/.app_baseline.json`. Running any `dbo` command will auto-migrate the file. You can also manually remove the `.app.json` entry from your `.gitignore`.
|
|
177
188
|
|
|
189
|
+
> **Upgrading from pre-0.11.0**: `TransactionKeyPreset` now applies only to records that carry a `UID` column (core assets). Data records without a UID are always submitted with `RowID` regardless of the preset. Migration 001 runs automatically on first command after upgrade and logs a one-time notice.
|
|
190
|
+
|
|
191
|
+
#### Automatic migrations
|
|
192
|
+
|
|
193
|
+
When the CLI version is upgraded, one-time migration scripts in `tools/cli/src/migrations/` run automatically on the first command invocation in a project directory. Completed migration IDs are recorded in `.dbo/config.local.json` under `_completedMigrations` (per-user, gitignored) so each developer runs them independently and they never re-fire.
|
|
194
|
+
|
|
195
|
+
To skip migrations for a single command run:
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
dbo push bins/ --no-migrate
|
|
199
|
+
dbo clone --app myapp --no-migrate
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Use `dbo status` to see how many pending migrations exist.
|
|
203
|
+
|
|
178
204
|
#### config.json reference
|
|
179
205
|
|
|
180
206
|
```json
|
|
@@ -185,8 +211,7 @@ All configuration is **directory-scoped**. Each project folder maintains its own
|
|
|
185
211
|
"AppName": "My App",
|
|
186
212
|
"AppShortName": "myapp",
|
|
187
213
|
"cloneSource": "default",
|
|
188
|
-
"ContentPlacement": "bin"
|
|
189
|
-
"MediaPlacement": "fullpath"
|
|
214
|
+
"ContentPlacement": "bin"
|
|
190
215
|
}
|
|
191
216
|
```
|
|
192
217
|
|
|
@@ -198,24 +223,39 @@ All configuration is **directory-scoped**. Each project folder maintains its own
|
|
|
198
223
|
| `AppName` | string | App display name |
|
|
199
224
|
| `AppShortName` | string | App short name (used for `dbo clone --app`) |
|
|
200
225
|
| `AppModifyKey` | string | ModifyKey for locked/production apps (set by `dbo clone`, used for submission guards) |
|
|
201
|
-
| `TransactionKeyPreset` | `RowUID` \| `RowID` | Row key type
|
|
202
|
-
| `TicketSuggestionOutput` | string | Output UID for
|
|
226
|
+
| `TransactionKeyPreset` | `RowUID` \| `RowID` | Row key type (auto-set to `RowUID` during init/clone) |
|
|
227
|
+
| `TicketSuggestionOutput` | string | Output UID for ticket suggestions (auto-set during init, default `ojaie9t3o0kfvliahnuuda`) |
|
|
203
228
|
| `cloneSource` | `"default"` \| file path \| URL | Where the last `dbo clone` fetched app JSON from. `"default"` = server fetch via `AppShortName`; any other value = the explicit local file path or URL used. Set automatically after each successful clone. |
|
|
204
|
-
| `ContentPlacement` | `bin` \| `path`
|
|
205
|
-
| `MediaPlacement` | `bin` \| `fullpath` \| `ask` | Where to place media files during clone |
|
|
229
|
+
| `ContentPlacement` | `bin` \| `path` | Where to place content files during clone (default: `bin`) |
|
|
206
230
|
| `<Entity>FilenameCol` | column name | Filename column for entity-dir records (e.g., `ExtensionFilenameCol`) |
|
|
207
231
|
|
|
208
|
-
**
|
|
209
|
-
|
|
210
|
-
-
|
|
211
|
-
- `ask` — Prompt for each file that has both a BinID and a Path/FullPath
|
|
232
|
+
**File placement:** All content, media, and output files are placed by BinID into the `lib/bins/` directory structure. Records without a BinID go into `lib/bins/` root. Media always uses BinID — no FullPath option. Bins with `Name=null` (legacy) map directly to `lib/bins/` root.
|
|
233
|
+
|
|
234
|
+
### Root-level project files
|
|
212
235
|
|
|
213
|
-
|
|
236
|
+
#### `app.json`
|
|
237
|
+
|
|
238
|
+
Clone of the original app JSON from the server with entity entries replaced by `@path/to/*.metadata.json` references. Created by `dbo init` (empty `{}`) and populated by `dbo clone`. Committed to git.
|
|
214
239
|
|
|
215
240
|
#### `app.json._domain`
|
|
216
241
|
|
|
217
242
|
The `_domain` field in `app.json` stores the project's reference domain (set during `dbo clone`). This is committed to git and used for domain-change detection when running `dbo init --force` or `dbo clone --domain`. It provides a stable cross-user baseline — all collaborators share the same reference domain.
|
|
218
243
|
|
|
244
|
+
#### `manifest.json`
|
|
245
|
+
|
|
246
|
+
A [PWA web app manifest](https://developer.mozilla.org/en-US/docs/Web/Manifest) auto-generated during scaffolding (`dbo init` or `dbo clone`). Values are derived from `app.json` when available:
|
|
247
|
+
|
|
248
|
+
| Field | Source |
|
|
249
|
+
|-------|--------|
|
|
250
|
+
| `name` | `<AppName> \| <domain>` |
|
|
251
|
+
| `short_name` | `AppShortName` |
|
|
252
|
+
| `description` | `App.Description` |
|
|
253
|
+
| `start_url` / `scope` | `/app/<ShortName>/ui/` |
|
|
254
|
+
| `background_color` | Extracted from the `widget` extension matching the app's `ShortName` (field `String4`), defaults to `#ffffff` |
|
|
255
|
+
| `theme_color` | `#000000` |
|
|
256
|
+
|
|
257
|
+
The file is only created if absent — it is never overwritten by subsequent clones, so local edits (icons, screenshots, display overrides) are preserved. A companion `manifest.metadata.json` is auto-created by `dbo push` if missing, allowing the manifest to be pushed to the server as a content record.
|
|
258
|
+
|
|
219
259
|
### `.dboignore`
|
|
220
260
|
|
|
221
261
|
A gitignore-style file in the project root that controls which files and directories are excluded from CLI operations. Created automatically by `dbo init` with sensible defaults.
|
|
@@ -251,7 +291,6 @@ bins/
|
|
|
251
291
|
.dbo/ # DBO internal
|
|
252
292
|
*.dboio.json # Export files
|
|
253
293
|
app.json # Clone output
|
|
254
|
-
dbo.deploy.json # Deployment manifest
|
|
255
294
|
.git/ # Version control
|
|
256
295
|
.gitignore
|
|
257
296
|
node_modules/ # Node
|
|
@@ -259,7 +298,10 @@ package.json
|
|
|
259
298
|
package-lock.json
|
|
260
299
|
.claude/ # AI / tooling
|
|
261
300
|
.mcp.json
|
|
262
|
-
.
|
|
301
|
+
.DS_Store # Editor / IDE / OS
|
|
302
|
+
Thumbs.db
|
|
303
|
+
Icon\r
|
|
304
|
+
.idea/
|
|
263
305
|
.vscode/
|
|
264
306
|
*.codekit3
|
|
265
307
|
README.md # Repo scaffolding
|
|
@@ -310,7 +352,6 @@ dbo init --scaffold --yes # scaffold dirs non-intera
|
|
|
310
352
|
| `--local` | Install Claude commands to project (`.claude/commands/`) |
|
|
311
353
|
| `--scaffold` | Pre-create standard project directories (`app_version`, `automation`, `bins`, `data_source`, `docs`, `extension`, `group`, `integration`, `site`, `src`, `tests`, `trash`) |
|
|
312
354
|
| `--dboignore` | Create `.dboignore` with default patterns (use with `--force` to overwrite existing) |
|
|
313
|
-
| `--media-placement <placement>` | Set media placement when cloning: `fullpath` or `binpath` (default: `bin`) |
|
|
314
355
|
| `-y, --yes` | Skip all interactive prompts (legacy migration, Claude Code setup) |
|
|
315
356
|
| `--non-interactive` | Alias for `--yes` |
|
|
316
357
|
|
|
@@ -347,7 +388,6 @@ dbo clone -e extension --descriptor-types false # Clone extensions flat (no de
|
|
|
347
388
|
| `-e, --entity <type>` | Only clone a specific entity type (e.g. `output`, `content`, `media`, `extension`) |
|
|
348
389
|
| `--documentation-only` | When used with `-e extension`, clone only documentation extensions |
|
|
349
390
|
| `--descriptor-types <bool>` | Sort extensions into descriptor sub-directories (default: `true`). Set to `false` to use flat `extension/` layout |
|
|
350
|
-
| `--media-placement <placement>` | Set media placement: `fullpath` or `binpath` (default: `bin`). Skips interactive media placement prompt |
|
|
351
391
|
| `--domain <host>` | Override domain. Triggers a domain-change confirmation prompt when it differs from the project reference domain |
|
|
352
392
|
| `--force` | Skip source mismatch confirmation and change detection; re-processes all files |
|
|
353
393
|
| `-y, --yes` | Auto-accept all prompts (also skips source mismatch confirmation) |
|
|
@@ -367,7 +407,7 @@ The project's reference domain is stored in `app.json._domain` (committed to git
|
|
|
367
407
|
4. **Creates directories** — processes `children.bin` to build the directory hierarchy based on `ParentBinID` relationships
|
|
368
408
|
5. **Saves `.dbo/structure.json`** — maps BinIDs to directory paths for file placement
|
|
369
409
|
6. **Writes content files** — decodes base64 content, creates `*.metadata.json` + content files in the correct bin directory. When a record's `Extension` field is empty, prompts you to choose from `css`, `js`, `html`, `xml`, `txt`, `md`, `cs`, `json`, `sql` (or skip to keep no extension). The chosen extension is saved back into the `metadata.json` `Extension` field
|
|
370
|
-
7. **Downloads media files** — fetches binary files (images, CSS, fonts) from the server
|
|
410
|
+
7. **Downloads media files** — fetches binary files (images, CSS, fonts) from the server using a fallback chain: `FullPath` directly (`/media/{app}/{path}`) → `/dir/` route → `/api/media/{uid}`, and saves with metadata. Errors are logged to `.dbo/errors.log`
|
|
371
411
|
8. **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 (e.g., `extension/`, `data_source/`)
|
|
372
412
|
9. **Processes other entities** — remaining entities with a `BinID` are placed in the corresponding bin directory
|
|
373
413
|
10. **Saves `app.json`** — clone of the original JSON with processed entries replaced by `@path/to/*.metadata.json` references
|
|
@@ -526,54 +566,72 @@ project/
|
|
|
526
566
|
MySQL-Primary.metadata.json
|
|
527
567
|
site/
|
|
528
568
|
MainSite.metadata.json
|
|
529
|
-
|
|
569
|
+
# Media files placed by BinID into bins/ (alongside content)
|
|
530
570
|
```
|
|
531
571
|
|
|
532
|
-
#### Understanding the `bins/` directory structure
|
|
572
|
+
#### Understanding the `lib/bins/` directory structure
|
|
533
573
|
|
|
534
|
-
The `bins/` directory is the default location for all bin-placed content files during clone. It organizes files according to your app's bin hierarchy from DBO.io.
|
|
574
|
+
The `lib/bins/` directory is the default location for all bin-placed content files during clone. It organizes files according to your app's bin hierarchy from DBO.io.
|
|
535
575
|
|
|
536
576
|
**Directory Organization:**
|
|
537
577
|
|
|
538
|
-
- **`bins/`** — Root directory for all bin-placed files (local organizational directory only)
|
|
539
|
-
- **`bins/app/`** — Special subdirectory for the main app bin (typically the default bin)
|
|
540
|
-
- **`bins/custom_name/`** — Custom bin directories (e.g., `tpl/`, `ticket_test/`, etc.)
|
|
578
|
+
- **`lib/bins/`** — Root directory for all bin-placed files (local organizational directory only)
|
|
579
|
+
- **`lib/bins/app/`** — Special subdirectory for the main app bin (typically the default bin)
|
|
580
|
+
- **`lib/bins/custom_name/`** — Custom bin directories (e.g., `tpl/`, `ticket_test/`, etc.)
|
|
541
581
|
|
|
542
|
-
**Important: The `bins/app/` special case**
|
|
582
|
+
**Important: The `lib/bins/app/` special case**
|
|
543
583
|
|
|
544
|
-
The `app/` subdirectory under `bins/` is treated specially:
|
|
584
|
+
The `app/` subdirectory under `lib/bins/` is treated specially:
|
|
545
585
|
|
|
546
|
-
1. **It's organizational only** — The `bins/app/` prefix exists only for local file organization and is **not part of the server-side path**.
|
|
586
|
+
1. **It's organizational only** — The `lib/bins/app/` prefix exists only for local file organization and is **not part of the server-side path**.
|
|
547
587
|
|
|
548
|
-
2. **Path normalization** — When comparing paths (during `dbo push`), the CLI automatically strips both `bins/` and `app/` from paths:
|
|
588
|
+
2. **Path normalization** — When comparing paths (during `dbo push`), the CLI automatically strips both `lib/bins/` and `app/` from paths:
|
|
549
589
|
```
|
|
550
|
-
Local file: bins/app/assets/css/operator.css
|
|
590
|
+
Local file: lib/bins/app/assets/css/operator.css
|
|
551
591
|
Server Path: assets/css/operator.css
|
|
552
592
|
→ These are considered the same path ✓
|
|
553
593
|
```
|
|
554
594
|
|
|
555
|
-
3. **Custom bins are preserved** — Other subdirectories like `bins/tpl/` or `bins/ticket_test/` represent actual bin hierarchies and their names are meaningful:
|
|
595
|
+
3. **Custom bins are preserved** — Other subdirectories like `lib/bins/tpl/` or `lib/bins/ticket_test/` represent actual bin hierarchies and their names are meaningful:
|
|
556
596
|
```
|
|
557
|
-
Local file: bins/tpl/header.html
|
|
597
|
+
Local file: lib/bins/tpl/header.html
|
|
558
598
|
Server Path: tpl/header.html
|
|
559
599
|
→ The 'tpl/' directory is preserved ✓
|
|
560
600
|
```
|
|
561
601
|
|
|
562
602
|
**Why this matters:**
|
|
563
603
|
|
|
564
|
-
- When you `dbo push` files from `bins/app/`, the CLI knows these paths should match the root-level paths in your metadata
|
|
565
|
-
- If your metadata `Path` column contains `assets/css/colors.css`, it will correctly match files in `bins/app/assets/css/colors.css`
|
|
566
|
-
- Custom bin directories like `bins/tpl/` serve from the `tpl/` directive and maintain their path structure
|
|
604
|
+
- When you `dbo push` files from `lib/bins/app/`, the CLI knows these paths should match the root-level paths in your metadata
|
|
605
|
+
- If your metadata `Path` column contains `assets/css/colors.css`, it will correctly match files in `lib/bins/app/assets/css/colors.css`
|
|
606
|
+
- Custom bin directories like `lib/bins/tpl/` serve from the `tpl/` directive and maintain their path structure
|
|
567
607
|
|
|
568
608
|
**Leading slash handling:**
|
|
569
609
|
|
|
570
610
|
The CLI handles leading `/` in metadata paths flexibly:
|
|
571
|
-
- `Path: assets/css/file.css` matches `bins/app/assets/css/file.css` ✓
|
|
572
|
-
- `Path: /assets/css/file.css` also matches `bins/app/assets/css/file.css` ✓
|
|
573
|
-
- `Path: /assets/css/file.css` matches `bins/assets/css/file.css` ✓
|
|
611
|
+
- `Path: assets/css/file.css` matches `lib/bins/app/assets/css/file.css` ✓
|
|
612
|
+
- `Path: /assets/css/file.css` also matches `lib/bins/app/assets/css/file.css` ✓
|
|
613
|
+
- `Path: /assets/css/file.css` matches `lib/bins/assets/css/file.css` ✓
|
|
574
614
|
|
|
575
615
|
This ensures compatibility with various path formats from the server while maintaining correct local file organization.
|
|
576
616
|
|
|
617
|
+
#### Media file serving (API)
|
|
618
|
+
|
|
619
|
+
The DBO.io server provides three routes for serving media files:
|
|
620
|
+
|
|
621
|
+
| Route | Example | Description |
|
|
622
|
+
|-------|---------|-------------|
|
|
623
|
+
| `/media/{app}/{path}` | `/media/todoes/App/assets/fonts/file.ttf` | Legacy FullPath — the value stored in the media record's `FullPath` column |
|
|
624
|
+
| `/dir/{app}/{bins}/{file}` | `/dir/todoes/App/assets/fonts/file.ttf` | Modern BinID-based route — parses `appShortName/binHierarchy/filename` |
|
|
625
|
+
| `/api/media/{uid}` | `/api/media/ujrOQPCdUEamNJdAjUQdYA` | UID-based endpoint — looks up media by unique identifier |
|
|
626
|
+
|
|
627
|
+
During `dbo clone`, the CLI downloads media using a **fallback chain**:
|
|
628
|
+
|
|
629
|
+
1. **FullPath** (`/media/...`) — uses the record's `FullPath` column directly
|
|
630
|
+
2. **`/dir/` route** — strips the `/media/` prefix from FullPath and uses the `/dir/` route
|
|
631
|
+
3. **`/api/media/{uid}`** — UID-based endpoint as last resort (when no FullPath exists)
|
|
632
|
+
|
|
633
|
+
If all attempts fail, the error is logged to `.dbo/errors.log` (JSONL format) with the record's UID, filename, FullPath, and error details.
|
|
634
|
+
|
|
577
635
|
#### Output hierarchy format
|
|
578
636
|
|
|
579
637
|
Each root output record produces a **single compound JSON file** containing all child entities (columns, joins, filters) embedded inline:
|
|
@@ -767,16 +825,16 @@ Query data from DBO.io outputs or entities.
|
|
|
767
825
|
dbo output qfkyyp2vxeaggdeo7dwbig
|
|
768
826
|
|
|
769
827
|
# Entity query
|
|
770
|
-
dbo output -e user --
|
|
828
|
+
dbo output -e user --template json_indented
|
|
771
829
|
|
|
772
830
|
# Single record
|
|
773
831
|
dbo output -e user --row 10296
|
|
774
832
|
|
|
775
833
|
# With filtering and sorting
|
|
776
|
-
dbo output -e user --filter 'FirstName=John' --sort 'LastName:asc' --
|
|
834
|
+
dbo output -e user --filter 'FirstName=John' --sort 'LastName:asc' --template json_indented
|
|
777
835
|
|
|
778
836
|
# Contains filter
|
|
779
|
-
dbo output -e content --filter 'Name:contains=color' --
|
|
837
|
+
dbo output -e content --filter 'Name:contains=color' --template json_indented
|
|
780
838
|
|
|
781
839
|
# Pagination
|
|
782
840
|
dbo output -e user --page 2 --rows-per-page 25
|
|
@@ -800,18 +858,17 @@ dbo output myOutputUID --debug-sql
|
|
|
800
858
|
| `-e, --entity <uid>` | Query by entity UID |
|
|
801
859
|
| `--row <id>` | Specific row ID |
|
|
802
860
|
| `--filter <expr>` | Filter expression (repeatable) |
|
|
803
|
-
| `--
|
|
861
|
+
| `--template <value>` | Output template: `json_raw` (default), `json_indented`, `json`, `html`, `csv`, `xml`, `txt`, `pdf`, or a content UID for custom templates |
|
|
804
862
|
| `--sort <expr>` | Sort expression (repeatable), e.g., `LastName:asc` |
|
|
805
863
|
| `--search <expr>` | Full-text search |
|
|
806
864
|
| `--page <n>` | Page number |
|
|
807
865
|
| `--rows-per-page <n>` | Rows per page |
|
|
808
866
|
| `--maxrows <n>` | Maximum rows |
|
|
809
867
|
| `--rows <range>` | Row range, e.g., `1-10` |
|
|
810
|
-
| `--template <value>` | Custom template |
|
|
811
868
|
| `--limit <n>` | Maximum rows to return (preferred over `--maxrows`) |
|
|
812
869
|
| `--rowcount <bool>` | Include row count: `true` (default) or `false` for performance |
|
|
813
870
|
| `--display <expr>` | Show/hide template tags (repeatable), e.g., `sidebar=hide` |
|
|
814
|
-
| `--format-values` | Enable value formatting
|
|
871
|
+
| `--format-values` | Enable value formatting with `--template json_raw` |
|
|
815
872
|
| `--empty-response-code <code>` | HTTP status code when output returns no results |
|
|
816
873
|
| `--fallback-content <expr>` | Fallback content UID for error codes, e.g., `404=contentUID` |
|
|
817
874
|
| `--escape-html <bool>` | Control HTML escaping: `true` or `false` |
|
|
@@ -877,14 +934,14 @@ dbo content ykqucv0eb0ggjqgcncj6dq
|
|
|
877
934
|
dbo content ykqucv0eb0ggjqgcncj6dq -o local/file.html
|
|
878
935
|
|
|
879
936
|
# Get as plain text (disable minification)
|
|
880
|
-
dbo content ykqucv0eb0ggjqgcncj6dq --
|
|
937
|
+
dbo content ykqucv0eb0ggjqgcncj6dq --template txt --no-minify
|
|
881
938
|
```
|
|
882
939
|
|
|
883
940
|
| Flag | Description |
|
|
884
941
|
|------|-------------|
|
|
885
942
|
| `<uid>` | Content UID |
|
|
886
943
|
| `-o, --output <path>` | Save to local file |
|
|
887
|
-
| `--
|
|
944
|
+
| `--template <value>` | Output template (e.g., `json_raw`, `html`, `txt`, or a content UID) |
|
|
888
945
|
| `--no-minify` | Disable minification |
|
|
889
946
|
| `--json` | Output raw JSON |
|
|
890
947
|
|
|
@@ -1231,9 +1288,16 @@ The `@colors.css` reference tells push to read the content from that file. All o
|
|
|
1231
1288
|
| `--meta-only` | Only push metadata, skip file content |
|
|
1232
1289
|
| `--content-only` | Only push file content, skip metadata |
|
|
1233
1290
|
| `-y, --yes` | Auto-accept all prompts |
|
|
1291
|
+
| `--toe-stepping <true\|false>` | Check server for conflicts before pushing (default: `true`). Set to `false` to skip the check and push unconditionally |
|
|
1234
1292
|
| `--json` | Output raw JSON |
|
|
1235
1293
|
| `--jq <expr>` | Filter JSON response |
|
|
1236
1294
|
|
|
1295
|
+
#### Server conflict detection (toe-stepping)
|
|
1296
|
+
|
|
1297
|
+
By default, `dbo push` checks the live server state before submitting changes. For each record being pushed, it fetches the current server version and compares `_LastUpdated` against the local baseline. If another user has modified a record since your last `dbo clone` or `dbo push`, you'll see a conflict warning with the name of the user who made the server-side change and a per-column diff of what changed.
|
|
1298
|
+
|
|
1299
|
+
You can then choose to overwrite the server changes or cancel and pull first. Use `--toe-stepping false` to disable the check entirely, or `--yes` to auto-accept conflicts (useful for CI/scripts).
|
|
1300
|
+
|
|
1237
1301
|
---
|
|
1238
1302
|
|
|
1239
1303
|
### `dbo rm`
|
|
@@ -1563,7 +1627,7 @@ If no stored user info is available, it prompts for direct input. The CLI automa
|
|
|
1563
1627
|
|
|
1564
1628
|
### `dbo install` (alias: `dbo i`)
|
|
1565
1629
|
|
|
1566
|
-
Install or upgrade dbo
|
|
1630
|
+
Install or upgrade dbo cli components including the CLI itself, plugins, and Claude Code integration.
|
|
1567
1631
|
|
|
1568
1632
|
```bash
|
|
1569
1633
|
# Interactive — choose what to install
|
|
@@ -1621,7 +1685,7 @@ Smart behavior:
|
|
|
1621
1685
|
|
|
1622
1686
|
### `dbo deploy`
|
|
1623
1687
|
|
|
1624
|
-
Deploy files to DBO.io using a
|
|
1688
|
+
Deploy files to DBO.io using a `.dbo/deploy_config.json` manifest or direct arguments.
|
|
1625
1689
|
|
|
1626
1690
|
```bash
|
|
1627
1691
|
# Deploy a named entry from the manifest
|
|
@@ -1642,7 +1706,7 @@ dbo deploy img:logo
|
|
|
1642
1706
|
|
|
1643
1707
|
| Flag | Description |
|
|
1644
1708
|
|------|-------------|
|
|
1645
|
-
| `<name>` | Deployment name from
|
|
1709
|
+
| `<name>` | Deployment name from `.dbo/deploy_config.json` |
|
|
1646
1710
|
| `--all` | Deploy all entries in the manifest |
|
|
1647
1711
|
| `-C, --confirm <true\|false>` | Commit (default: `true`) |
|
|
1648
1712
|
| `--ticket <id>` | Override ticket ID |
|
|
@@ -1654,9 +1718,9 @@ dbo deploy img:logo
|
|
|
1654
1718
|
|
|
1655
1719
|
The `deploy` command includes the same automatic error recovery as `push`, `input`, and `add` — including ticket error handling, repository mismatch recovery, user identity prompts, and ModifyKey protection. When a stored ticket exists, you'll be prompted before the first submission (see [Pre-submission ticket prompt](#pre-submission-ticket-prompt)).
|
|
1656
1720
|
|
|
1657
|
-
####
|
|
1721
|
+
#### `.dbo/deploy_config.json` manifest
|
|
1658
1722
|
|
|
1659
|
-
Create a
|
|
1723
|
+
Create a `.dbo/deploy_config.json` file to define named deployments:
|
|
1660
1724
|
|
|
1661
1725
|
```json
|
|
1662
1726
|
{
|
|
@@ -1786,7 +1850,7 @@ dbo message myUID --jq '.Successful'
|
|
|
1786
1850
|
| `.[] \| .field` | Pipe: iterate then access |
|
|
1787
1851
|
| `.["key.name"]` | Bracket notation for keys with dots |
|
|
1788
1852
|
|
|
1789
|
-
When `--jq` is used, the API request is automatically made with `
|
|
1853
|
+
When `--jq` is used, the API request is automatically made with `_template=json_raw`.
|
|
1790
1854
|
|
|
1791
1855
|
### JSON syntax highlighting
|
|
1792
1856
|
|
|
@@ -1871,14 +1935,15 @@ _search@ColumnName=keyword # search specific column
|
|
|
1871
1935
|
#### Template & Format
|
|
1872
1936
|
|
|
1873
1937
|
```
|
|
1874
|
-
_template=json_raw #
|
|
1938
|
+
_template=json_raw # system template name: json_raw, json_indented, json, html, csv, xml, txt, pdf
|
|
1875
1939
|
_template=3iX9fHFTL064Shgol8Bktw # content UID (custom template)
|
|
1876
1940
|
_format_values=true # enable value formatting in json_raw
|
|
1877
|
-
_format=json # legacy format specifier
|
|
1878
1941
|
_mime=application/json # override MIME/content type
|
|
1879
1942
|
_escape_html=false # disable HTML escaping of data values
|
|
1880
1943
|
```
|
|
1881
1944
|
|
|
1945
|
+
> **`_format` is deprecated.** Do not use `_format` — use `_template` instead. The `_format` key is demoted and retained only for backwards compatibility in the API. Do not use `_format` in combination with `_template` — combining both in a single request causes broken responses.
|
|
1946
|
+
|
|
1882
1947
|
#### Display Control
|
|
1883
1948
|
|
|
1884
1949
|
```
|
|
@@ -2010,12 +2075,12 @@ dbo upload image.jpg --bin 12345 --app 67890 --ownership app --path assets/image
|
|
|
2010
2075
|
|
|
2011
2076
|
**Before:**
|
|
2012
2077
|
```bash
|
|
2013
|
-
curl -b .cookies "https://my-domain.com/api/output/entity/user?
|
|
2078
|
+
curl -b .cookies "https://my-domain.com/api/output/entity/user?_template=json_indented&_filter@FirstName=John"
|
|
2014
2079
|
```
|
|
2015
2080
|
|
|
2016
2081
|
**After:**
|
|
2017
2082
|
```bash
|
|
2018
|
-
dbo output -e user --filter 'FirstName=John' --
|
|
2083
|
+
dbo output -e user --filter 'FirstName=John' --template json_indented
|
|
2019
2084
|
```
|
|
2020
2085
|
|
|
2021
2086
|
### Cookie compatibility
|
package/bin/postinstall.js
CHANGED
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
// Post-install hook for `npm i @dboio/cli`
|
|
4
4
|
// Interactive plugin picker when TTY is available, static message otherwise.
|
|
5
5
|
|
|
6
|
+
import { dirname, join } from 'path';
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
|
+
|
|
6
9
|
const RESET = '\x1b[0m';
|
|
7
10
|
const BOLD = '\x1b[1m';
|
|
8
11
|
const DIM = '\x1b[2m';
|
|
@@ -14,12 +17,17 @@ function write(message) {
|
|
|
14
17
|
console.log(message);
|
|
15
18
|
}
|
|
16
19
|
|
|
20
|
+
// Resolve path to dbo.js entrypoint — used instead of bare `dbo` command
|
|
21
|
+
// because during npm postinstall the bin symlink may not be on PATH yet.
|
|
22
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
const DBO_BIN = join(__dirname, 'dbo.js');
|
|
24
|
+
|
|
17
25
|
// Available plugins — add new entries here as plugins are created
|
|
18
26
|
const PLUGINS = [
|
|
19
27
|
{
|
|
20
28
|
name: 'dbo',
|
|
21
29
|
label: 'Claude Code — /dbo:cli slash command',
|
|
22
|
-
command:
|
|
30
|
+
command: `node "${DBO_BIN}" install --claudecommand dbo`
|
|
23
31
|
}
|
|
24
32
|
];
|
|
25
33
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dboio/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"description": "CLI for the DBO.io framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
"repository": {
|
|
40
40
|
"type": "git",
|
|
41
41
|
"url": "https://github.com/dboio/api.git",
|
|
42
|
-
"directory": "tools/
|
|
42
|
+
"directory": "tools/cli"
|
|
43
43
|
},
|
|
44
|
-
"homepage": "https://github.com/dboio/api/tree/master/tools/
|
|
44
|
+
"homepage": "https://github.com/dboio/api/tree/master/tools/cli#readme",
|
|
45
45
|
"bugs": {
|
|
46
46
|
"url": "https://github.com/dboio/api/issues"
|
|
47
47
|
}
|
|
@@ -74,7 +74,7 @@ Available subcommands:
|
|
|
74
74
|
- `rm <directory>` — Remove a directory, all files, and sub-directories recursively
|
|
75
75
|
- `rm -f <path>` — Remove without confirmation prompts
|
|
76
76
|
- `rm --keep-local <path>` — Stage server deletions without deleting local files/directories
|
|
77
|
-
- `deploy [name]` — Deploy via dbo.
|
|
77
|
+
- `deploy [name]` — Deploy via .dbo/deploy_config.json manifest
|
|
78
78
|
- `install` (alias: `i`) — Install or upgrade CLI, plugins, or Claude commands
|
|
79
79
|
- `i dbo` or `i dbo@latest` — Install/upgrade the CLI from npm
|
|
80
80
|
- `i dbo@0.4.1` — Install a specific CLI version
|
|
@@ -235,8 +235,8 @@ Flags: `--app <name>`, `--domain <host>`, `-y/--yes`, `-v/--verbose`
|
|
|
235
235
|
3. Updates `package.json` with `name`, `productName`, `description`, `homepage`, and `deploy` script
|
|
236
236
|
4. Creates directory structure from `children.bin` hierarchy → saves `.dbo/structure.json`
|
|
237
237
|
5. Writes content files (decodes base64) with `*.metadata.json` into bin directories
|
|
238
|
-
6. Downloads media files from server
|
|
239
|
-
7. Processes entity-dir records (`extension`, `app_version`, `data_source`, `site`, `group`, `integration`, `automation`) into project directories
|
|
238
|
+
6. Downloads media files from server using fallback chain: FullPath (`/media/{app}/{path}`) → `/dir/` route → `/api/media/{uid}`, with `*.metadata.json`. Errors logged to `.dbo/errors.log`
|
|
239
|
+
7. Processes entity-dir records (`extension`, `app_version`, `data_source`, `site`, `group`, `integration`, `automation`) into `lib/` project directories as `.metadata.json` files with optional companion content files
|
|
240
240
|
8. Processes remaining entities with BinID into corresponding bin directories
|
|
241
241
|
9. Saves `app.json` to project root with `@path/to/*.metadata.json` references
|
|
242
242
|
|
|
@@ -80,7 +80,7 @@ Available subcommands:
|
|
|
80
80
|
- `rm <directory>` — Remove a directory, all files, and sub-directories recursively
|
|
81
81
|
- `rm -f <path>` — Remove without confirmation prompts
|
|
82
82
|
- `rm --keep-local <path>` — Stage server deletions without deleting local files/directories
|
|
83
|
-
- `deploy [name]` — Deploy via dbo.
|
|
83
|
+
- `deploy [name]` — Deploy via .dbo/deploy_config.json manifest
|
|
84
84
|
- `install` (alias: `i`) — Install or upgrade CLI, plugins, or Claude commands
|
|
85
85
|
- `i dbo` or `i dbo@latest` — Install/upgrade the CLI from npm
|
|
86
86
|
- `i dbo@0.4.1` — Install a specific CLI version
|
|
@@ -241,8 +241,8 @@ Flags: `--app <name>`, `--domain <host>`, `-y/--yes`, `-v/--verbose`
|
|
|
241
241
|
3. Updates `package.json` with `name`, `productName`, `description`, `homepage`, and `deploy` script
|
|
242
242
|
4. Creates directory structure from `children.bin` hierarchy → saves `.dbo/structure.json`
|
|
243
243
|
5. Writes content files (decodes base64) with `*.metadata.json` into bin directories
|
|
244
|
-
6. Downloads media files from server
|
|
245
|
-
7. Processes entity-dir records (`extension`, `app_version`, `data_source`, `site`, `group`, `integration`, `automation`) into project directories
|
|
244
|
+
6. Downloads media files from server using fallback chain: FullPath (`/media/{app}/{path}`) → `/dir/` route → `/api/media/{uid}`, with `*.metadata.json`. Errors logged to `.dbo/errors.log`
|
|
245
|
+
7. Processes entity-dir records (`extension`, `app_version`, `data_source`, `site`, `group`, `integration`, `automation`) into `lib/` project directories as `.metadata.json` files with optional companion content files
|
|
246
246
|
8. Processes remaining entities with BinID into corresponding bin directories
|
|
247
247
|
9. Saves `app.json` to project root with `@path/to/*.metadata.json` references
|
|
248
248
|
|
package/src/commands/add.js
CHANGED
|
@@ -14,6 +14,7 @@ import { checkStoredTicket, clearGlobalTicket } from '../lib/ticketing.js';
|
|
|
14
14
|
import { checkModifyKey, isModifyKeyError, handleModifyKeyError } from '../lib/modify-key.js';
|
|
15
15
|
import { loadIgnore } from '../lib/ignore.js';
|
|
16
16
|
import { loadStructureFile, findBinByPath } from '../lib/structure.js';
|
|
17
|
+
import { runPendingMigrations } from '../lib/migrations.js';
|
|
17
18
|
|
|
18
19
|
export const addCommand = new Command('add')
|
|
19
20
|
.description('Add a new file to DBO.io (creates record on server)')
|
|
@@ -27,8 +28,10 @@ export const addCommand = new Command('add')
|
|
|
27
28
|
.option('--jq <expr>', 'Filter JSON response')
|
|
28
29
|
.option('-v, --verbose', 'Show HTTP request details')
|
|
29
30
|
.option('--domain <host>', 'Override domain')
|
|
31
|
+
.option('--no-migrate', 'Skip pending migrations for this invocation')
|
|
30
32
|
.action(async (targetPath, options) => {
|
|
31
33
|
try {
|
|
34
|
+
await runPendingMigrations(options);
|
|
32
35
|
const client = new DboClient({ domain: options.domain, verbose: options.verbose });
|
|
33
36
|
|
|
34
37
|
// ModifyKey guard
|
|
@@ -432,6 +435,7 @@ async function submitAdd(meta, metaPath, filePath, client, options) {
|
|
|
432
435
|
result = await client.postUrlEncoded('/api/input/submit', body);
|
|
433
436
|
}
|
|
434
437
|
|
|
438
|
+
if (result.successful) await client.voidCache();
|
|
435
439
|
formatResponse(result, { json: options.json, jq: options.jq, verbose: options.verbose });
|
|
436
440
|
|
|
437
441
|
if (!result.successful) {
|