@dboio/cli 0.4.2 → 0.6.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 +294 -71
- package/bin/dbo.js +12 -3
- package/bin/postinstall.js +88 -0
- package/package.json +10 -3
- package/src/commands/clone.js +597 -19
- package/src/commands/diff.js +246 -0
- package/src/commands/init.js +30 -22
- package/src/commands/install.js +517 -69
- package/src/commands/mv.js +869 -0
- package/src/commands/pull.js +6 -0
- package/src/commands/push.js +289 -33
- package/src/commands/rm.js +337 -0
- package/src/commands/status.js +28 -1
- package/src/lib/config.js +265 -0
- package/src/lib/delta.js +204 -0
- package/src/lib/dependencies.js +131 -0
- package/src/lib/diff.js +740 -0
- package/src/lib/save-to-disk.js +71 -4
- package/src/lib/structure.js +36 -0
- package/src/plugins/claudecommands/dbo.md +37 -6
- package/src/commands/update.js +0 -168
package/README.md
CHANGED
|
@@ -31,6 +31,8 @@ npm link
|
|
|
31
31
|
npx @dboio/cli <command>
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
> **Shorthand:** You can use `dbo i` as a shortcut for `dbo install` (similar to `npm i`).
|
|
35
|
+
|
|
34
36
|
### Requirements
|
|
35
37
|
|
|
36
38
|
- **Node.js 18+** (uses native `fetch` and `FormData`)
|
|
@@ -46,6 +48,9 @@ The dbo CLI can be used as a `/dbo` slash command inside Claude Code sessions.
|
|
|
46
48
|
# Install the /dbo command into your project's .claude/commands/
|
|
47
49
|
dbo install claudecommands
|
|
48
50
|
|
|
51
|
+
# Install globally to ~/.claude/commands/ (shared across projects)
|
|
52
|
+
dbo install claudecommands --global
|
|
53
|
+
|
|
49
54
|
# Or install Claude Code CLI + commands together
|
|
50
55
|
dbo install claudecode
|
|
51
56
|
```
|
|
@@ -57,41 +62,34 @@ Once installed, use `/dbo` in Claude Code:
|
|
|
57
62
|
/dbo push assets/css/
|
|
58
63
|
```
|
|
59
64
|
|
|
60
|
-
The command source lives in `tools/dbo-cli/src/plugins/claudecommands/`. Installed copies in `.claude/commands/` are gitignored and managed by `dbo install
|
|
65
|
+
The command source lives in `tools/dbo-cli/src/plugins/claudecommands/`. Installed copies in `.claude/commands/` are gitignored and managed by `dbo install`. Each plugin's installation scope (project or global) is stored per-plugin in `.dbo/config.local.json`.
|
|
61
66
|
|
|
62
67
|
---
|
|
63
68
|
|
|
64
|
-
##
|
|
69
|
+
## Upgrading
|
|
70
|
+
|
|
71
|
+
The `dbo install` command handles both fresh installs and upgrades. If a component is already installed, it will prompt you to upgrade to the latest version.
|
|
65
72
|
|
|
66
73
|
```bash
|
|
67
|
-
#
|
|
68
|
-
dbo
|
|
74
|
+
# Upgrade CLI to latest version
|
|
75
|
+
dbo install dbo@latest
|
|
69
76
|
|
|
70
|
-
#
|
|
71
|
-
dbo
|
|
77
|
+
# Install/upgrade to a specific version
|
|
78
|
+
dbo install dbo@0.4.1
|
|
72
79
|
|
|
73
|
-
#
|
|
74
|
-
dbo
|
|
80
|
+
# Upgrade from local source
|
|
81
|
+
dbo install /path/to/local/cli/src
|
|
75
82
|
|
|
76
|
-
#
|
|
77
|
-
dbo
|
|
83
|
+
# Upgrade Claude Code commands (prompts if already installed)
|
|
84
|
+
dbo install plugins
|
|
85
|
+
|
|
86
|
+
# Upgrade a specific Claude command
|
|
87
|
+
dbo install --claudecommand dbo
|
|
78
88
|
|
|
79
89
|
# Check your version
|
|
80
90
|
dbo --version
|
|
81
91
|
```
|
|
82
92
|
|
|
83
|
-
For manual updates:
|
|
84
|
-
|
|
85
|
-
```bash
|
|
86
|
-
# From git repo
|
|
87
|
-
cd tools/dbo-cli && git pull && npm install
|
|
88
|
-
|
|
89
|
-
# From npm
|
|
90
|
-
npm update -g @dboio/cli
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
If you used `npm link`, the link updates automatically — no need to re-link.
|
|
94
|
-
|
|
95
93
|
---
|
|
96
94
|
|
|
97
95
|
## Quick Start
|
|
@@ -129,11 +127,12 @@ All configuration is **directory-scoped**. Each project folder maintains its own
|
|
|
129
127
|
| File | Purpose | Git |
|
|
130
128
|
|------|---------|-----|
|
|
131
129
|
| `config.json` | Domain, app metadata, placement preferences | Committable (shared) |
|
|
130
|
+
| `config.local.json` | Per-user settings: plugin scopes, future user prefs | Gitignored (per-user) |
|
|
132
131
|
| `credentials.json` | Username, user ID, UID, name, email (no password) | Gitignored (per-user) |
|
|
133
132
|
| `cookies.txt` | Session cookie (Netscape format) | Gitignored (per-user) |
|
|
134
133
|
| `structure.json` | Bin directory mapping (created by `dbo clone`) | Committable (shared) |
|
|
135
134
|
|
|
136
|
-
`dbo init` automatically adds `.dbo/credentials.json
|
|
135
|
+
`dbo init` automatically adds `.dbo/credentials.json`, `.dbo/cookies.txt`, and `.dbo/config.local.json` to `.gitignore` (creates the file if it doesn't exist).
|
|
137
136
|
|
|
138
137
|
#### config.json reference
|
|
139
138
|
|
|
@@ -158,6 +157,7 @@ All configuration is **directory-scoped**. Each project folder maintains its own
|
|
|
158
157
|
| `AppShortName` | string | App short name (used for `dbo clone --app`) |
|
|
159
158
|
| `ContentPlacement` | `bin` \| `path` \| `ask` | Where to place content files during clone |
|
|
160
159
|
| `MediaPlacement` | `bin` \| `fullpath` \| `ask` | Where to place media files during clone |
|
|
160
|
+
| `<Entity>FilenameCol` | column name | Filename column for entity-dir records (e.g., `ExtensionFilenameCol`) |
|
|
161
161
|
|
|
162
162
|
**Placement values:**
|
|
163
163
|
- `bin` — Place files in the BinID-mapped directory (from `structure.json`)
|
|
@@ -187,11 +187,12 @@ Environment variables override file-based configuration:
|
|
|
187
187
|
Initialize DBO CLI configuration for the current directory.
|
|
188
188
|
|
|
189
189
|
```bash
|
|
190
|
-
dbo init
|
|
191
|
-
dbo init --domain my-domain.com
|
|
192
|
-
dbo init --domain my-domain.com --username me@co.io
|
|
193
|
-
dbo init --force
|
|
194
|
-
dbo init --domain my-domain.com --app myapp --clone
|
|
190
|
+
dbo init # interactive prompts
|
|
191
|
+
dbo init --domain my-domain.com # non-interactive
|
|
192
|
+
dbo init --domain my-domain.com --username me@co.io # with credentials
|
|
193
|
+
dbo init --force # overwrite existing config
|
|
194
|
+
dbo init --domain my-domain.com --app myapp --clone # init + clone an app
|
|
195
|
+
dbo init --domain my-domain.com -y # skip all prompts
|
|
195
196
|
```
|
|
196
197
|
|
|
197
198
|
| Flag | Description |
|
|
@@ -201,6 +202,10 @@ dbo init --domain my-domain.com --app myapp --clone # init + clone an app
|
|
|
201
202
|
| `--force` | Overwrite existing configuration |
|
|
202
203
|
| `--app <shortName>` | App short name (triggers clone after init) |
|
|
203
204
|
| `--clone` | Clone the app after initialization |
|
|
205
|
+
| `-g, --global` | Install Claude commands globally (`~/.claude/commands/`) |
|
|
206
|
+
| `--local` | Install Claude commands to project (`.claude/commands/`) |
|
|
207
|
+
| `-y, --yes` | Skip all interactive prompts (legacy migration, Claude Code setup) |
|
|
208
|
+
| `--non-interactive` | Alias for `--yes` |
|
|
204
209
|
|
|
205
210
|
---
|
|
206
211
|
|
|
@@ -239,8 +244,13 @@ dbo init --domain my-domain.com --app myapp --clone
|
|
|
239
244
|
5. **Saves `.dbo/structure.json`** — maps BinIDs to directory paths for file placement
|
|
240
245
|
6. **Writes content files** — decodes base64 content, creates `*.metadata.json` + content files in the correct bin directory
|
|
241
246
|
7. **Downloads media files** — fetches binary files (images, CSS, fonts) from the server via `/api/media/{uid}` and saves with metadata
|
|
242
|
-
8. **Processes
|
|
243
|
-
9. **
|
|
247
|
+
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., `Extensions/`, `Data Sources/`)
|
|
248
|
+
9. **Processes other entities** — remaining entities with a `BinID` are placed in the corresponding bin directory
|
|
249
|
+
10. **Saves `app.json`** — clone of the original JSON with processed entries replaced by `@path/to/*.metadata.json` references
|
|
250
|
+
|
|
251
|
+
#### Change detection on re-clone
|
|
252
|
+
|
|
253
|
+
When cloning an app that was already cloned locally, the CLI detects existing files and compares modification times against the server's `_LastUpdated`. You'll be prompted to overwrite, compare differences, or skip — same as `dbo pull`. Use `-y` to auto-accept all changes.
|
|
244
254
|
|
|
245
255
|
#### Path resolution
|
|
246
256
|
|
|
@@ -251,6 +261,26 @@ Where do you want me to place filename.ext?
|
|
|
251
261
|
2. Into the BinID of 12345 (mapped BinName → bin/directory)
|
|
252
262
|
```
|
|
253
263
|
|
|
264
|
+
#### Entity directory processing
|
|
265
|
+
|
|
266
|
+
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`:
|
|
267
|
+
|
|
268
|
+
| Entity Key | Directory |
|
|
269
|
+
|------------|-----------|
|
|
270
|
+
| `extension` | `Extensions/` |
|
|
271
|
+
| `app_version` | `App Versions/` |
|
|
272
|
+
| `data_source` | `Data Sources/` |
|
|
273
|
+
| `site` | `Sites/` |
|
|
274
|
+
| `group` | `Groups/` |
|
|
275
|
+
| `integration` | `Integrations/` |
|
|
276
|
+
| `automation` | `Automations/` |
|
|
277
|
+
|
|
278
|
+
For each entity type, the CLI prompts to choose which column becomes the filename (defaults to `Name`, fallback `UID`). The choice is saved per entity type in `config.json` (e.g., `ExtensionFilenameCol`).
|
|
279
|
+
|
|
280
|
+
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 `_contentColumns` array.
|
|
281
|
+
|
|
282
|
+
Use `-y` to skip prompts (uses `Name` column, no content extraction).
|
|
283
|
+
|
|
254
284
|
#### Output structure
|
|
255
285
|
|
|
256
286
|
```
|
|
@@ -261,7 +291,7 @@ project/
|
|
|
261
291
|
.gitignore # credentials.json + cookies.txt added
|
|
262
292
|
package.json # Updated with app info + deploy script
|
|
263
293
|
app.json # Clone of original with @references
|
|
264
|
-
|
|
294
|
+
Bins/ # ← root for all bin-placed files
|
|
265
295
|
app/ # ← directory from children.bin
|
|
266
296
|
thomas-scratch.md
|
|
267
297
|
thomas-scratch.metadata.json
|
|
@@ -269,9 +299,61 @@ project/
|
|
|
269
299
|
CurrentTicketID.metadata.json
|
|
270
300
|
ticket_test/ # ← another bin directory
|
|
271
301
|
...
|
|
302
|
+
Extensions/ # ← entity-dir records
|
|
303
|
+
MyExtension.metadata.json
|
|
304
|
+
MyExtension.CustomCSS.css # ← extracted content column
|
|
305
|
+
Data Sources/
|
|
306
|
+
MySQL-Primary.metadata.json
|
|
307
|
+
Sites/
|
|
308
|
+
MainSite.metadata.json
|
|
272
309
|
media/operator/app/... # ← FullPath placement (when MediaPlacement=fullpath)
|
|
273
310
|
```
|
|
274
311
|
|
|
312
|
+
#### Understanding the `Bins/` directory structure
|
|
313
|
+
|
|
314
|
+
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.
|
|
315
|
+
|
|
316
|
+
**Directory Organization:**
|
|
317
|
+
|
|
318
|
+
- **`Bins/`** — Root directory for all bin-placed files (local organizational directory only)
|
|
319
|
+
- **`Bins/app/`** — Special subdirectory for the main app bin (typically the default bin)
|
|
320
|
+
- **`Bins/custom_name/`** — Custom bin directories (e.g., `tpl/`, `ticket_test/`, etc.)
|
|
321
|
+
|
|
322
|
+
**Important: The `Bins/app/` special case**
|
|
323
|
+
|
|
324
|
+
The `app/` subdirectory under `Bins/` is treated specially:
|
|
325
|
+
|
|
326
|
+
1. **It's organizational only** — The `Bins/app/` prefix exists only for local file organization and is **not part of the server-side path**.
|
|
327
|
+
|
|
328
|
+
2. **Path normalization** — When comparing paths (during `dbo push`), the CLI automatically strips both `Bins/` and `app/` from paths:
|
|
329
|
+
```
|
|
330
|
+
Local file: Bins/app/assets/css/operator.css
|
|
331
|
+
Server Path: assets/css/operator.css
|
|
332
|
+
→ These are considered the same path ✓
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
3. **Custom bins are preserved** — Other subdirectories like `Bins/tpl/` or `Bins/ticket_test/` represent actual bin hierarchies and their names are meaningful:
|
|
336
|
+
```
|
|
337
|
+
Local file: Bins/tpl/header.html
|
|
338
|
+
Server Path: tpl/header.html
|
|
339
|
+
→ The 'tpl/' directory is preserved ✓
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
**Why this matters:**
|
|
343
|
+
|
|
344
|
+
- When you `dbo push` files from `Bins/app/`, the CLI knows these paths should match the root-level paths in your metadata
|
|
345
|
+
- If your metadata `Path` column contains `assets/css/colors.css`, it will correctly match files in `Bins/app/assets/css/colors.css`
|
|
346
|
+
- Custom bin directories like `Bins/tpl/` serve from the `tpl/` directive and maintain their path structure
|
|
347
|
+
|
|
348
|
+
**Leading slash handling:**
|
|
349
|
+
|
|
350
|
+
The CLI handles leading `/` in metadata paths flexibly:
|
|
351
|
+
- `Path: assets/css/file.css` matches `Bins/app/assets/css/file.css` ✓
|
|
352
|
+
- `Path: /assets/css/file.css` also matches `Bins/app/assets/css/file.css` ✓
|
|
353
|
+
- `Path: /assets/css/file.css` matches `Bins/assets/css/file.css` ✓
|
|
354
|
+
|
|
355
|
+
This ensures compatibility with various path formats from the server while maintaining correct local file organization.
|
|
356
|
+
|
|
275
357
|
---
|
|
276
358
|
|
|
277
359
|
### `dbo login`
|
|
@@ -329,10 +411,15 @@ Output:
|
|
|
329
411
|
Directory: /Users/me/projects/operator
|
|
330
412
|
Session: Active (expires: 2026-03-15T10:30:00.000Z)
|
|
331
413
|
Cookies: /Users/me/projects/operator/.dbo/cookies.txt
|
|
414
|
+
|
|
415
|
+
Claude Code Plugins:
|
|
416
|
+
dbo: ✓ global (~/.claude/commands/dbo.md)
|
|
332
417
|
```
|
|
333
418
|
|
|
334
419
|
User ID and UID are populated by `dbo login`. If they show "(not set)", run `dbo login` to fetch them.
|
|
335
420
|
|
|
421
|
+
Plugin scopes (project or global) are displayed when plugins have been installed. Scopes are stored in `.dbo/config.local.json`.
|
|
422
|
+
|
|
336
423
|
---
|
|
337
424
|
|
|
338
425
|
### `dbo input`
|
|
@@ -380,7 +467,7 @@ dbo input -d 'RowUID:abc;column:content.Content@file.css' -v
|
|
|
380
467
|
#### Input expression syntax
|
|
381
468
|
|
|
382
469
|
```
|
|
383
|
-
RowID:identifier;column:entity.ColumnName=value
|
|
470
|
+
RowID:identifier;column:entity.ColumnName=value # direct value
|
|
384
471
|
RowUID:identifier;column:entity.ColumnName@filepath # value from file
|
|
385
472
|
RowID:delIdentifier;entity:entityName=true # delete
|
|
386
473
|
```
|
|
@@ -539,6 +626,17 @@ js/
|
|
|
539
626
|
app.metadata.json
|
|
540
627
|
```
|
|
541
628
|
|
|
629
|
+
#### Smart change detection
|
|
630
|
+
|
|
631
|
+
When pulling records that already exist locally, the CLI compares your local file modification times against the server's `_LastUpdated` timestamp. If the server has newer data, you'll be prompted:
|
|
632
|
+
|
|
633
|
+
1. **Overwrite** — replace local with server version
|
|
634
|
+
2. **Compare** — show a line-by-line diff and selectively merge
|
|
635
|
+
3. **Skip** — keep local unchanged
|
|
636
|
+
4. **Overwrite all** / **Skip all** — bulk action for remaining files
|
|
637
|
+
|
|
638
|
+
After writing, file modification times are synced to the server's `_LastUpdated` to establish a sync point for future comparisons. Use `dbo diff` to compare without pulling.
|
|
639
|
+
|
|
542
640
|
---
|
|
543
641
|
|
|
544
642
|
### `dbo media`
|
|
@@ -679,6 +777,55 @@ dbo instance export --confirm false
|
|
|
679
777
|
|
|
680
778
|
---
|
|
681
779
|
|
|
780
|
+
### `dbo diff`
|
|
781
|
+
|
|
782
|
+
Compare local files against their server versions and selectively merge changes. This is a one-directional comparison: only server → local changes can be accepted. To push local changes back, use `dbo push`.
|
|
783
|
+
|
|
784
|
+
```bash
|
|
785
|
+
# Compare all records in the current directory
|
|
786
|
+
dbo diff
|
|
787
|
+
|
|
788
|
+
# Compare a specific file
|
|
789
|
+
dbo diff assets/css/colors.css
|
|
790
|
+
|
|
791
|
+
# Compare all records in a directory
|
|
792
|
+
dbo diff assets/
|
|
793
|
+
|
|
794
|
+
# Display diffs without prompting
|
|
795
|
+
dbo diff --no-interactive
|
|
796
|
+
|
|
797
|
+
# Accept all server changes without prompting
|
|
798
|
+
dbo diff -y
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
| Flag | Description |
|
|
802
|
+
|------|-------------|
|
|
803
|
+
| `[path]` | File, directory, or `.` (default: current directory) |
|
|
804
|
+
| `--no-interactive` | Show diffs without prompting to accept |
|
|
805
|
+
| `-y, --yes` | Accept all server changes automatically |
|
|
806
|
+
| `-v, --verbose` | Show HTTP request details |
|
|
807
|
+
| `--domain <host>` | Override domain |
|
|
808
|
+
|
|
809
|
+
#### Interactive mode
|
|
810
|
+
|
|
811
|
+
For each file with differences, you can:
|
|
812
|
+
1. **Accept all changes** — overwrite local with server version
|
|
813
|
+
2. **Cherry-pick fields** — accept/skip individual field changes
|
|
814
|
+
3. **Skip** — keep local files unchanged
|
|
815
|
+
4. **Accept all remaining** — auto-accept for all remaining files
|
|
816
|
+
5. **Skip all remaining** — skip all remaining files
|
|
817
|
+
|
|
818
|
+
#### Diff output
|
|
819
|
+
|
|
820
|
+
Shows a unified diff format with color coding:
|
|
821
|
+
- Red lines (`-`) — content only in your local file
|
|
822
|
+
- Green lines (`+`) — content only on the server
|
|
823
|
+
- Cyan headers — hunk markers showing line positions
|
|
824
|
+
|
|
825
|
+
After accepting changes, file modification times are synced to the server's `_LastUpdated` timestamp to establish a new sync point.
|
|
826
|
+
|
|
827
|
+
---
|
|
828
|
+
|
|
682
829
|
### `dbo push`
|
|
683
830
|
|
|
684
831
|
Push local files back to DBO.io using metadata from a previous pull. This is the counterpart to `dbo content pull` and `dbo output --save`.
|
|
@@ -771,6 +918,85 @@ The `@colors.css` reference tells push to read the content from that file. All o
|
|
|
771
918
|
|
|
772
919
|
---
|
|
773
920
|
|
|
921
|
+
### `dbo rm`
|
|
922
|
+
|
|
923
|
+
Remove a file or directory locally and stage server deletions for the next `dbo push`. Similar to `git rm`.
|
|
924
|
+
|
|
925
|
+
#### Single file
|
|
926
|
+
|
|
927
|
+
```bash
|
|
928
|
+
# Remove a content file (finds companion .metadata.json automatically)
|
|
929
|
+
dbo rm Bins/app/some-file.txt
|
|
930
|
+
|
|
931
|
+
# Remove by metadata file directly
|
|
932
|
+
dbo rm Bins/app/some-file.metadata.json
|
|
933
|
+
|
|
934
|
+
# Skip confirmation prompt
|
|
935
|
+
dbo rm -f Bins/app/some-file.txt
|
|
936
|
+
|
|
937
|
+
# Stage server deletion without deleting local files
|
|
938
|
+
dbo rm --keep-local Bins/app/some-file.txt
|
|
939
|
+
```
|
|
940
|
+
|
|
941
|
+
#### Directory
|
|
942
|
+
|
|
943
|
+
```bash
|
|
944
|
+
# Remove a directory and all its contents (prompts for approach)
|
|
945
|
+
dbo rm Bins/app/ui/
|
|
946
|
+
|
|
947
|
+
# Remove directory without prompts
|
|
948
|
+
dbo rm -f Bins/app/ui/
|
|
949
|
+
|
|
950
|
+
# Stage deletions without removing local files/directories
|
|
951
|
+
dbo rm --keep-local Bins/app/ui/
|
|
952
|
+
```
|
|
953
|
+
|
|
954
|
+
When removing a directory, the CLI:
|
|
955
|
+
1. Looks up the BinID from `.dbo/structure.json`
|
|
956
|
+
2. Recursively collects all sub-directories (processed leaves-first)
|
|
957
|
+
3. Prompts: "Remove all files and directories", "Prompt for each file", or "Cancel"
|
|
958
|
+
4. Stages each file's deletion, then each bin's deletion (`entity:bin`)
|
|
959
|
+
5. Removes the local directory (unless `--keep-local`)
|
|
960
|
+
|
|
961
|
+
| Flag | Description |
|
|
962
|
+
|------|-------------|
|
|
963
|
+
| `<path>` | File, `.metadata.json`, or directory to remove |
|
|
964
|
+
| `-f, --force` | Skip all confirmation prompts |
|
|
965
|
+
| `--keep-local` | Only stage server deletions, keep local files/directories |
|
|
966
|
+
|
|
967
|
+
#### What rm does (single file)
|
|
968
|
+
|
|
969
|
+
1. **Resolves metadata** — if given a content file, finds the companion `.metadata.json`
|
|
970
|
+
2. **Reads row ID** — uses `_id` (shorthand) or derives from entity (e.g., `ContentID`, `MediaID`)
|
|
971
|
+
3. **Prompts for confirmation** — "Do you really want to remove this file and all of its nodes?"
|
|
972
|
+
4. **Stages deletion** — adds a delete entry to `.dbo/synchronize.json`
|
|
973
|
+
5. **Updates app.json** — removes the `@path/to/file.metadata.json` reference from children arrays
|
|
974
|
+
6. **Deletes local files** — removes the metadata file and all referenced content/media files (unless `--keep-local`)
|
|
975
|
+
|
|
976
|
+
#### synchronize.json
|
|
977
|
+
|
|
978
|
+
Pending deletions are stored in `.dbo/synchronize.json`:
|
|
979
|
+
|
|
980
|
+
```json
|
|
981
|
+
{
|
|
982
|
+
"delete": [
|
|
983
|
+
{
|
|
984
|
+
"UID": "a2dxvg23rk6xsmnum7pdxa",
|
|
985
|
+
"RowID": 16012,
|
|
986
|
+
"entity": "content",
|
|
987
|
+
"name": "nima-test-test",
|
|
988
|
+
"expression": "RowID:del16012;entity:content=true"
|
|
989
|
+
}
|
|
990
|
+
],
|
|
991
|
+
"edit": [],
|
|
992
|
+
"add": []
|
|
993
|
+
}
|
|
994
|
+
```
|
|
995
|
+
|
|
996
|
+
The next `dbo push` processes all pending deletions before pushing file changes. Successful deletions are removed from synchronize.json; failures remain staged for retry.
|
|
997
|
+
|
|
998
|
+
---
|
|
999
|
+
|
|
774
1000
|
### `dbo add`
|
|
775
1001
|
|
|
776
1002
|
Add a new file to DBO.io by creating a server record. Similar to `git add`, this registers a local file with the server.
|
|
@@ -893,63 +1119,60 @@ If no stored user info is available, it prompts for direct input. The CLI automa
|
|
|
893
1119
|
|
|
894
1120
|
---
|
|
895
1121
|
|
|
896
|
-
### `dbo install`
|
|
1122
|
+
### `dbo install` (alias: `dbo i`)
|
|
897
1123
|
|
|
898
|
-
Install dbo-cli components including Claude Code integration.
|
|
1124
|
+
Install or upgrade dbo-cli components including the CLI itself, plugins, and Claude Code integration.
|
|
899
1125
|
|
|
900
1126
|
```bash
|
|
901
1127
|
# Interactive — choose what to install
|
|
902
1128
|
dbo install
|
|
903
1129
|
|
|
904
|
-
# Install
|
|
905
|
-
dbo
|
|
1130
|
+
# Install/upgrade CLI from npm (latest)
|
|
1131
|
+
dbo i dbo
|
|
1132
|
+
dbo i dbo@latest
|
|
906
1133
|
|
|
907
|
-
# Install
|
|
908
|
-
dbo
|
|
1134
|
+
# Install a specific CLI version
|
|
1135
|
+
dbo i dbo@0.4.1
|
|
909
1136
|
|
|
910
|
-
# Install
|
|
911
|
-
dbo install
|
|
912
|
-
```
|
|
1137
|
+
# Install CLI from local source directory
|
|
1138
|
+
dbo install /path/to/local/cli/src
|
|
913
1139
|
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
| `--claudecommand <name>` | Install a specific command by name |
|
|
918
|
-
|
|
919
|
-
When installing Claude commands:
|
|
920
|
-
- Creates `.claude/commands/` if it doesn't exist (prompts first)
|
|
921
|
-
- Prompts before overwriting existing commands
|
|
922
|
-
- Adds installed files to `.gitignore` (source of truth is `src/plugins/claudecommands/`)
|
|
923
|
-
|
|
924
|
-
---
|
|
925
|
-
|
|
926
|
-
### `dbo update`
|
|
927
|
-
|
|
928
|
-
Update the dbo CLI, plugins, or Claude Code commands.
|
|
1140
|
+
# Install/upgrade Claude Code commands
|
|
1141
|
+
dbo install plugins
|
|
1142
|
+
dbo install claudecommands
|
|
929
1143
|
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
dbo update
|
|
1144
|
+
# Install Claude Code commands globally (shared across projects)
|
|
1145
|
+
dbo install plugins --global
|
|
933
1146
|
|
|
934
|
-
#
|
|
935
|
-
dbo
|
|
1147
|
+
# Explicitly install to project directory
|
|
1148
|
+
dbo install plugins --local
|
|
936
1149
|
|
|
937
|
-
#
|
|
938
|
-
dbo
|
|
1150
|
+
# Install Claude Code CLI (if not present) + commands
|
|
1151
|
+
dbo install claudecode
|
|
939
1152
|
|
|
940
|
-
#
|
|
941
|
-
dbo
|
|
1153
|
+
# Install/upgrade a specific command plugin
|
|
1154
|
+
dbo install --claudecommand dbo
|
|
942
1155
|
|
|
943
|
-
#
|
|
944
|
-
dbo
|
|
1156
|
+
# Install a specific command globally
|
|
1157
|
+
dbo install --claudecommand dbo --global
|
|
945
1158
|
```
|
|
946
1159
|
|
|
947
1160
|
| Flag | Description |
|
|
948
1161
|
|------|-------------|
|
|
949
|
-
| `[target]` | What to
|
|
950
|
-
| `--claudecommand <name>` |
|
|
951
|
-
|
|
952
|
-
|
|
1162
|
+
| `[target]` | What to install: `dbo[@version]`, `plugins`, `claudecommands`, `claudecode`, or a local path |
|
|
1163
|
+
| `--claudecommand <name>` | Install/upgrade a specific command by name |
|
|
1164
|
+
| `-g, --global` | Install commands to user home directory (`~/.claude/commands/`) |
|
|
1165
|
+
| `--local` | Install commands to project directory (`.claude/commands/`) |
|
|
1166
|
+
|
|
1167
|
+
Smart behavior:
|
|
1168
|
+
- If the CLI is already installed, prompts to upgrade (with version comparison)
|
|
1169
|
+
- If plugins are already installed and up to date, reports "already up to date"
|
|
1170
|
+
- If plugins differ from source, prompts to upgrade to the latest version
|
|
1171
|
+
- Compares file hashes — unchanged files are skipped
|
|
1172
|
+
- Adds project-scoped command files to `.gitignore` (source of truth is `src/plugins/claudecommands/`)
|
|
1173
|
+
- Per-plugin scope (project or global) is stored in `.dbo/config.local.json` and remembered for future upgrades
|
|
1174
|
+
- On first install of a plugin without a stored preference, prompts for scope
|
|
1175
|
+
- `--global` / `--local` flags override stored preferences and update them
|
|
953
1176
|
|
|
954
1177
|
---
|
|
955
1178
|
|
package/bin/dbo.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { Command } from 'commander';
|
|
4
|
+
import { createRequire } from 'module';
|
|
5
|
+
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
const packageJson = require('../package.json');
|
|
8
|
+
|
|
4
9
|
import { initCommand } from '../src/commands/init.js';
|
|
5
10
|
import { loginCommand } from '../src/commands/login.js';
|
|
6
11
|
import { logoutCommand } from '../src/commands/logout.js';
|
|
@@ -18,15 +23,17 @@ import { pushCommand } from '../src/commands/push.js';
|
|
|
18
23
|
import { pullCommand } from '../src/commands/pull.js';
|
|
19
24
|
import { addCommand } from '../src/commands/add.js';
|
|
20
25
|
import { installCommand } from '../src/commands/install.js';
|
|
21
|
-
import { updateCommand } from '../src/commands/update.js';
|
|
22
26
|
import { cloneCommand } from '../src/commands/clone.js';
|
|
27
|
+
import { diffCommand } from '../src/commands/diff.js';
|
|
28
|
+
import { rmCommand } from '../src/commands/rm.js';
|
|
29
|
+
import { mvCommand } from '../src/commands/mv.js';
|
|
23
30
|
|
|
24
31
|
const program = new Command();
|
|
25
32
|
|
|
26
33
|
program
|
|
27
34
|
.name('dbo')
|
|
28
35
|
.description('CLI for the DBO.io framework')
|
|
29
|
-
.version(
|
|
36
|
+
.version(packageJson.version, '-v, --version', 'output the version number');
|
|
30
37
|
|
|
31
38
|
program.addCommand(initCommand);
|
|
32
39
|
program.addCommand(loginCommand);
|
|
@@ -45,7 +52,9 @@ program.addCommand(pushCommand);
|
|
|
45
52
|
program.addCommand(pullCommand);
|
|
46
53
|
program.addCommand(addCommand);
|
|
47
54
|
program.addCommand(installCommand);
|
|
48
|
-
program.addCommand(updateCommand);
|
|
49
55
|
program.addCommand(cloneCommand);
|
|
56
|
+
program.addCommand(diffCommand);
|
|
57
|
+
program.addCommand(rmCommand);
|
|
58
|
+
program.addCommand(mvCommand);
|
|
50
59
|
|
|
51
60
|
program.parse();
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Post-install hook for `npm i @dboio/cli`
|
|
4
|
+
// Interactive plugin picker when TTY is available, static message otherwise.
|
|
5
|
+
|
|
6
|
+
const RESET = '\x1b[0m';
|
|
7
|
+
const BOLD = '\x1b[1m';
|
|
8
|
+
const DIM = '\x1b[2m';
|
|
9
|
+
const CYAN = '\x1b[36m';
|
|
10
|
+
const YELLOW = '\x1b[33m';
|
|
11
|
+
|
|
12
|
+
// Available plugins — add new entries here as plugins are created
|
|
13
|
+
const PLUGINS = [
|
|
14
|
+
{
|
|
15
|
+
name: 'dbo',
|
|
16
|
+
label: 'Claude Code — /dbo slash command',
|
|
17
|
+
command: 'dbo install --claudecommand dbo'
|
|
18
|
+
}
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
function printStaticMessage() {
|
|
22
|
+
console.log('');
|
|
23
|
+
console.log(`${BOLD}${CYAN} DBO.io CLI installed successfully.${RESET}`);
|
|
24
|
+
console.log('');
|
|
25
|
+
console.log(` ${DIM}Plugins available:${RESET}`);
|
|
26
|
+
for (const plugin of PLUGINS) {
|
|
27
|
+
console.log(` ${YELLOW}${plugin.label}${RESET}`);
|
|
28
|
+
console.log(` ${DIM}${plugin.command}${RESET}`);
|
|
29
|
+
}
|
|
30
|
+
console.log('');
|
|
31
|
+
console.log(` To install all plugins at once, run:`);
|
|
32
|
+
console.log(` ${BOLD}dbo install plugins${RESET}`);
|
|
33
|
+
console.log('');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function promptInteractive() {
|
|
37
|
+
console.log('');
|
|
38
|
+
console.log(`${BOLD}${CYAN} DBO.io CLI installed successfully.${RESET}`);
|
|
39
|
+
console.log('');
|
|
40
|
+
|
|
41
|
+
const { default: inquirer } = await import('inquirer');
|
|
42
|
+
|
|
43
|
+
const { selected } = await inquirer.prompt([
|
|
44
|
+
{
|
|
45
|
+
type: 'checkbox',
|
|
46
|
+
name: 'selected',
|
|
47
|
+
message: 'Select plugins to install:',
|
|
48
|
+
choices: PLUGINS.map(p => ({
|
|
49
|
+
name: p.label,
|
|
50
|
+
value: p.command,
|
|
51
|
+
checked: false
|
|
52
|
+
}))
|
|
53
|
+
}
|
|
54
|
+
]);
|
|
55
|
+
|
|
56
|
+
if (selected.length === 0) {
|
|
57
|
+
console.log('');
|
|
58
|
+
console.log(` ${DIM}No plugins selected. You can install them later with:${RESET}`);
|
|
59
|
+
console.log(` ${BOLD}dbo install plugins${RESET}`);
|
|
60
|
+
console.log('');
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const { execSync } = await import('child_process');
|
|
65
|
+
const combined = selected.join(' && ');
|
|
66
|
+
|
|
67
|
+
console.log('');
|
|
68
|
+
console.log(` ${DIM}Running: ${combined}${RESET}`);
|
|
69
|
+
console.log('');
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
execSync(combined, { stdio: 'inherit' });
|
|
73
|
+
} catch {
|
|
74
|
+
console.log('');
|
|
75
|
+
console.log(` ${YELLOW}Plugin installation had an issue. You can retry with:${RESET}`);
|
|
76
|
+
for (const cmd of selected) {
|
|
77
|
+
console.log(` ${BOLD}${cmd}${RESET}`);
|
|
78
|
+
}
|
|
79
|
+
console.log('');
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// TTY check — interactive prompt only works when user has a terminal
|
|
84
|
+
if (process.stdin.isTTY && process.stdout.isTTY) {
|
|
85
|
+
promptInteractive().catch(() => printStaticMessage());
|
|
86
|
+
} else {
|
|
87
|
+
printStaticMessage();
|
|
88
|
+
}
|
package/package.json
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dboio/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "CLI for the DBO.io framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"dbo": "./bin/dbo.js"
|
|
8
8
|
},
|
|
9
|
+
"files": [
|
|
10
|
+
"plugins/",
|
|
11
|
+
"bin/",
|
|
12
|
+
"src/",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
9
15
|
"engines": {
|
|
10
16
|
"node": ">=18.0.0"
|
|
11
17
|
},
|
|
12
18
|
"scripts": {
|
|
13
|
-
"
|
|
19
|
+
"postinstall": "node bin/postinstall.js",
|
|
20
|
+
"test": "node --test src/**/*.test.js tests/**/*.test.js"
|
|
14
21
|
},
|
|
15
22
|
"dependencies": {
|
|
16
23
|
"commander": "^12.1.0",
|
|
@@ -26,7 +33,7 @@
|
|
|
26
33
|
"rest",
|
|
27
34
|
"crud"
|
|
28
35
|
],
|
|
29
|
-
"license": "
|
|
36
|
+
"license": "MIT",
|
|
30
37
|
"repository": {
|
|
31
38
|
"type": "git",
|
|
32
39
|
"url": "https://github.com/dboio/api.git",
|