@dboio/cli 0.4.2 → 0.5.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 CHANGED
@@ -46,6 +46,9 @@ The dbo CLI can be used as a `/dbo` slash command inside Claude Code sessions.
46
46
  # Install the /dbo command into your project's .claude/commands/
47
47
  dbo install claudecommands
48
48
 
49
+ # Install globally to ~/.claude/commands/ (shared across projects)
50
+ dbo install claudecommands --global
51
+
49
52
  # Or install Claude Code CLI + commands together
50
53
  dbo install claudecode
51
54
  ```
@@ -57,41 +60,34 @@ Once installed, use `/dbo` in Claude Code:
57
60
  /dbo push assets/css/
58
61
  ```
59
62
 
60
- The command source lives in `tools/dbo-cli/src/plugins/claudecommands/`. Installed copies in `.claude/commands/` are gitignored and managed by `dbo install` / `dbo update`.
63
+ 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
64
 
62
65
  ---
63
66
 
64
- ## Updating
67
+ ## Upgrading
68
+
69
+ 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
70
 
66
71
  ```bash
67
- # Update everything (CLI + Claude commands)
68
- dbo update
72
+ # Upgrade CLI to latest version
73
+ dbo install dbo@latest
74
+
75
+ # Install/upgrade to a specific version
76
+ dbo install dbo@0.4.1
69
77
 
70
- # Update only the CLI
71
- dbo update cli
78
+ # Upgrade from local source
79
+ dbo install /path/to/local/cli/src
72
80
 
73
- # Update only Claude Code commands
74
- dbo update claudecommands
81
+ # Upgrade Claude Code commands (prompts if already installed)
82
+ dbo install plugins
75
83
 
76
- # Update a specific Claude command
77
- dbo update --claudecommand dbo
84
+ # Upgrade a specific Claude command
85
+ dbo install --claudecommand dbo
78
86
 
79
87
  # Check your version
80
88
  dbo --version
81
89
  ```
82
90
 
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
91
  ---
96
92
 
97
93
  ## Quick Start
@@ -129,11 +125,12 @@ All configuration is **directory-scoped**. Each project folder maintains its own
129
125
  | File | Purpose | Git |
130
126
  |------|---------|-----|
131
127
  | `config.json` | Domain, app metadata, placement preferences | Committable (shared) |
128
+ | `config.local.json` | Per-user settings: plugin scopes, future user prefs | Gitignored (per-user) |
132
129
  | `credentials.json` | Username, user ID, UID, name, email (no password) | Gitignored (per-user) |
133
130
  | `cookies.txt` | Session cookie (Netscape format) | Gitignored (per-user) |
134
131
  | `structure.json` | Bin directory mapping (created by `dbo clone`) | Committable (shared) |
135
132
 
136
- `dbo init` automatically adds `.dbo/credentials.json` and `.dbo/cookies.txt` to `.gitignore` (creates the file if it doesn't exist).
133
+ `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
134
 
138
135
  #### config.json reference
139
136
 
@@ -158,6 +155,7 @@ All configuration is **directory-scoped**. Each project folder maintains its own
158
155
  | `AppShortName` | string | App short name (used for `dbo clone --app`) |
159
156
  | `ContentPlacement` | `bin` \| `path` \| `ask` | Where to place content files during clone |
160
157
  | `MediaPlacement` | `bin` \| `fullpath` \| `ask` | Where to place media files during clone |
158
+ | `<Entity>FilenameCol` | column name | Filename column for entity-dir records (e.g., `ExtensionFilenameCol`) |
161
159
 
162
160
  **Placement values:**
163
161
  - `bin` — Place files in the BinID-mapped directory (from `structure.json`)
@@ -187,11 +185,12 @@ Environment variables override file-based configuration:
187
185
  Initialize DBO CLI configuration for the current directory.
188
186
 
189
187
  ```bash
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
188
+ dbo init # interactive prompts
189
+ dbo init --domain my-domain.com # non-interactive
190
+ dbo init --domain my-domain.com --username me@co.io # with credentials
191
+ dbo init --force # overwrite existing config
192
+ dbo init --domain my-domain.com --app myapp --clone # init + clone an app
193
+ dbo init --domain my-domain.com -y # skip all prompts
195
194
  ```
196
195
 
197
196
  | Flag | Description |
@@ -201,6 +200,10 @@ dbo init --domain my-domain.com --app myapp --clone # init + clone an app
201
200
  | `--force` | Overwrite existing configuration |
202
201
  | `--app <shortName>` | App short name (triggers clone after init) |
203
202
  | `--clone` | Clone the app after initialization |
203
+ | `-g, --global` | Install Claude commands globally (`~/.claude/commands/`) |
204
+ | `--local` | Install Claude commands to project (`.claude/commands/`) |
205
+ | `-y, --yes` | Skip all interactive prompts (legacy migration, Claude Code setup) |
206
+ | `--non-interactive` | Alias for `--yes` |
204
207
 
205
208
  ---
206
209
 
@@ -239,8 +242,13 @@ dbo init --domain my-domain.com --app myapp --clone
239
242
  5. **Saves `.dbo/structure.json`** — maps BinIDs to directory paths for file placement
240
243
  6. **Writes content files** — decodes base64 content, creates `*.metadata.json` + content files in the correct bin directory
241
244
  7. **Downloads media files** — fetches binary files (images, CSS, fonts) from the server via `/api/media/{uid}` and saves with metadata
242
- 8. **Processes other entities** — entities with a `BinID` are placed in the corresponding directory
243
- 9. **Saves `app.json`**clone of the original JSON with processed entries replaced by `@path/to/*.metadata.json` references
245
+ 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/`)
246
+ 9. **Processes other entities** remaining entities with a `BinID` are placed in the corresponding bin directory
247
+ 10. **Saves `app.json`** — clone of the original JSON with processed entries replaced by `@path/to/*.metadata.json` references
248
+
249
+ #### Change detection on re-clone
250
+
251
+ 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
252
 
245
253
  #### Path resolution
246
254
 
@@ -251,6 +259,26 @@ Where do you want me to place filename.ext?
251
259
  2. Into the BinID of 12345 (mapped BinName → bin/directory)
252
260
  ```
253
261
 
262
+ #### Entity directory processing
263
+
264
+ 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`:
265
+
266
+ | Entity Key | Directory |
267
+ |------------|-----------|
268
+ | `extension` | `Extensions/` |
269
+ | `app_version` | `App Versions/` |
270
+ | `data_source` | `Data Sources/` |
271
+ | `site` | `Sites/` |
272
+ | `group` | `Groups/` |
273
+ | `integration` | `Integrations/` |
274
+ | `automation` | `Automations/` |
275
+
276
+ 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`).
277
+
278
+ 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.
279
+
280
+ Use `-y` to skip prompts (uses `Name` column, no content extraction).
281
+
254
282
  #### Output structure
255
283
 
256
284
  ```
@@ -261,7 +289,7 @@ project/
261
289
  .gitignore # credentials.json + cookies.txt added
262
290
  package.json # Updated with app info + deploy script
263
291
  app.json # Clone of original with @references
264
- bins/ # ← root for all bin-placed files
292
+ Bins/ # ← root for all bin-placed files
265
293
  app/ # ← directory from children.bin
266
294
  thomas-scratch.md
267
295
  thomas-scratch.metadata.json
@@ -269,6 +297,13 @@ project/
269
297
  CurrentTicketID.metadata.json
270
298
  ticket_test/ # ← another bin directory
271
299
  ...
300
+ Extensions/ # ← entity-dir records
301
+ MyExtension.metadata.json
302
+ MyExtension.CustomCSS.css # ← extracted content column
303
+ Data Sources/
304
+ MySQL-Primary.metadata.json
305
+ Sites/
306
+ MainSite.metadata.json
272
307
  media/operator/app/... # ← FullPath placement (when MediaPlacement=fullpath)
273
308
  ```
274
309
 
@@ -329,10 +364,15 @@ Output:
329
364
  Directory: /Users/me/projects/operator
330
365
  Session: Active (expires: 2026-03-15T10:30:00.000Z)
331
366
  Cookies: /Users/me/projects/operator/.dbo/cookies.txt
367
+
368
+ Claude Code Plugins:
369
+ dbo: ✓ global (~/.claude/commands/dbo.md)
332
370
  ```
333
371
 
334
372
  User ID and UID are populated by `dbo login`. If they show "(not set)", run `dbo login` to fetch them.
335
373
 
374
+ Plugin scopes (project or global) are displayed when plugins have been installed. Scopes are stored in `.dbo/config.local.json`.
375
+
336
376
  ---
337
377
 
338
378
  ### `dbo input`
@@ -380,7 +420,7 @@ dbo input -d 'RowUID:abc;column:content.Content@file.css' -v
380
420
  #### Input expression syntax
381
421
 
382
422
  ```
383
- RowID:identifier;column:entity.ColumnName=value # direct value
423
+ RowID:identifier;column:entity.ColumnName=value # direct value
384
424
  RowUID:identifier;column:entity.ColumnName@filepath # value from file
385
425
  RowID:delIdentifier;entity:entityName=true # delete
386
426
  ```
@@ -539,6 +579,17 @@ js/
539
579
  app.metadata.json
540
580
  ```
541
581
 
582
+ #### Smart change detection
583
+
584
+ 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:
585
+
586
+ 1. **Overwrite** — replace local with server version
587
+ 2. **Compare** — show a line-by-line diff and selectively merge
588
+ 3. **Skip** — keep local unchanged
589
+ 4. **Overwrite all** / **Skip all** — bulk action for remaining files
590
+
591
+ 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.
592
+
542
593
  ---
543
594
 
544
595
  ### `dbo media`
@@ -679,6 +730,55 @@ dbo instance export --confirm false
679
730
 
680
731
  ---
681
732
 
733
+ ### `dbo diff`
734
+
735
+ 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`.
736
+
737
+ ```bash
738
+ # Compare all records in the current directory
739
+ dbo diff
740
+
741
+ # Compare a specific file
742
+ dbo diff assets/css/colors.css
743
+
744
+ # Compare all records in a directory
745
+ dbo diff assets/
746
+
747
+ # Display diffs without prompting
748
+ dbo diff --no-interactive
749
+
750
+ # Accept all server changes without prompting
751
+ dbo diff -y
752
+ ```
753
+
754
+ | Flag | Description |
755
+ |------|-------------|
756
+ | `[path]` | File, directory, or `.` (default: current directory) |
757
+ | `--no-interactive` | Show diffs without prompting to accept |
758
+ | `-y, --yes` | Accept all server changes automatically |
759
+ | `-v, --verbose` | Show HTTP request details |
760
+ | `--domain <host>` | Override domain |
761
+
762
+ #### Interactive mode
763
+
764
+ For each file with differences, you can:
765
+ 1. **Accept all changes** — overwrite local with server version
766
+ 2. **Cherry-pick fields** — accept/skip individual field changes
767
+ 3. **Skip** — keep local files unchanged
768
+ 4. **Accept all remaining** — auto-accept for all remaining files
769
+ 5. **Skip all remaining** — skip all remaining files
770
+
771
+ #### Diff output
772
+
773
+ Shows a unified diff format with color coding:
774
+ - Red lines (`-`) — content only in your local file
775
+ - Green lines (`+`) — content only on the server
776
+ - Cyan headers — hunk markers showing line positions
777
+
778
+ After accepting changes, file modification times are synced to the server's `_LastUpdated` timestamp to establish a new sync point.
779
+
780
+ ---
781
+
682
782
  ### `dbo push`
683
783
 
684
784
  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 +871,85 @@ The `@colors.css` reference tells push to read the content from that file. All o
771
871
 
772
872
  ---
773
873
 
874
+ ### `dbo rm`
875
+
876
+ Remove a file or directory locally and stage server deletions for the next `dbo push`. Similar to `git rm`.
877
+
878
+ #### Single file
879
+
880
+ ```bash
881
+ # Remove a content file (finds companion .metadata.json automatically)
882
+ dbo rm Bins/app/some-file.txt
883
+
884
+ # Remove by metadata file directly
885
+ dbo rm Bins/app/some-file.metadata.json
886
+
887
+ # Skip confirmation prompt
888
+ dbo rm -f Bins/app/some-file.txt
889
+
890
+ # Stage server deletion without deleting local files
891
+ dbo rm --keep-local Bins/app/some-file.txt
892
+ ```
893
+
894
+ #### Directory
895
+
896
+ ```bash
897
+ # Remove a directory and all its contents (prompts for approach)
898
+ dbo rm Bins/app/ui/
899
+
900
+ # Remove directory without prompts
901
+ dbo rm -f Bins/app/ui/
902
+
903
+ # Stage deletions without removing local files/directories
904
+ dbo rm --keep-local Bins/app/ui/
905
+ ```
906
+
907
+ When removing a directory, the CLI:
908
+ 1. Looks up the BinID from `.dbo/structure.json`
909
+ 2. Recursively collects all sub-directories (processed leaves-first)
910
+ 3. Prompts: "Remove all files and directories", "Prompt for each file", or "Cancel"
911
+ 4. Stages each file's deletion, then each bin's deletion (`entity:bin`)
912
+ 5. Removes the local directory (unless `--keep-local`)
913
+
914
+ | Flag | Description |
915
+ |------|-------------|
916
+ | `<path>` | File, `.metadata.json`, or directory to remove |
917
+ | `-f, --force` | Skip all confirmation prompts |
918
+ | `--keep-local` | Only stage server deletions, keep local files/directories |
919
+
920
+ #### What rm does (single file)
921
+
922
+ 1. **Resolves metadata** — if given a content file, finds the companion `.metadata.json`
923
+ 2. **Reads row ID** — uses `_id` (shorthand) or derives from entity (e.g., `ContentID`, `MediaID`)
924
+ 3. **Prompts for confirmation** — "Do you really want to remove this file and all of its nodes?"
925
+ 4. **Stages deletion** — adds a delete entry to `.dbo/synchronize.json`
926
+ 5. **Updates app.json** — removes the `@path/to/file.metadata.json` reference from children arrays
927
+ 6. **Deletes local files** — removes the metadata file and all referenced content/media files (unless `--keep-local`)
928
+
929
+ #### synchronize.json
930
+
931
+ Pending deletions are stored in `.dbo/synchronize.json`:
932
+
933
+ ```json
934
+ {
935
+ "delete": [
936
+ {
937
+ "UID": "a2dxvg23rk6xsmnum7pdxa",
938
+ "RowID": 16012,
939
+ "entity": "content",
940
+ "name": "nima-test-test",
941
+ "expression": "RowID:del16012;entity:content=true"
942
+ }
943
+ ],
944
+ "edit": [],
945
+ "add": []
946
+ }
947
+ ```
948
+
949
+ The next `dbo push` processes all pending deletions before pushing file changes. Successful deletions are removed from synchronize.json; failures remain staged for retry.
950
+
951
+ ---
952
+
774
953
  ### `dbo add`
775
954
 
776
955
  Add a new file to DBO.io by creating a server record. Similar to `git add`, this registers a local file with the server.
@@ -895,61 +1074,58 @@ If no stored user info is available, it prompts for direct input. The CLI automa
895
1074
 
896
1075
  ### `dbo install`
897
1076
 
898
- Install dbo-cli components including Claude Code integration.
1077
+ Install or upgrade dbo-cli components including the CLI itself, plugins, and Claude Code integration.
899
1078
 
900
1079
  ```bash
901
1080
  # Interactive — choose what to install
902
1081
  dbo install
903
1082
 
904
- # Install Claude Code commands into .claude/commands/
905
- dbo install claudecommands
906
-
907
- # Install Claude Code CLI (if not present) + commands
908
- dbo install claudecode
909
-
910
- # Install a specific command plugin
911
- dbo install --claudecommand dbo
912
- ```
913
-
914
- | Flag | Description |
915
- |------|-------------|
916
- | `[target]` | What to install: `claudecode`, `claudecommands` |
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/`)
1083
+ # Install/upgrade CLI from npm (latest)
1084
+ dbo install dbo
1085
+ dbo install dbo@latest
923
1086
 
924
- ---
1087
+ # Install a specific CLI version
1088
+ dbo install dbo@0.4.1
925
1089
 
926
- ### `dbo update`
1090
+ # Install CLI from local source directory
1091
+ dbo install /path/to/local/cli/src
927
1092
 
928
- Update the dbo CLI, plugins, or Claude Code commands.
1093
+ # Install/upgrade Claude Code commands
1094
+ dbo install plugins
1095
+ dbo install claudecommands
929
1096
 
930
- ```bash
931
- # Update CLI + ask about Claude commands
932
- dbo update
1097
+ # Install Claude Code commands globally (shared across projects)
1098
+ dbo install plugins --global
933
1099
 
934
- # Update only the CLI (git pull or npm update)
935
- dbo update cli
1100
+ # Explicitly install to project directory
1101
+ dbo install plugins --local
936
1102
 
937
- # Update all plugins
938
- dbo update plugins
1103
+ # Install Claude Code CLI (if not present) + commands
1104
+ dbo install claudecode
939
1105
 
940
- # Re-sync Claude commands from source
941
- dbo update claudecommands
1106
+ # Install/upgrade a specific command plugin
1107
+ dbo install --claudecommand dbo
942
1108
 
943
- # Update a specific Claude command
944
- dbo update --claudecommand dbo
1109
+ # Install a specific command globally
1110
+ dbo install --claudecommand dbo --global
945
1111
  ```
946
1112
 
947
1113
  | Flag | Description |
948
1114
  |------|-------------|
949
- | `[target]` | What to update: `cli`, `plugins`, `claudecommands` |
950
- | `--claudecommand <name>` | Update a specific command by name |
951
-
952
- The update compares file hashes unchanged files are skipped with "already up to date".
1115
+ | `[target]` | What to install: `dbo[@version]`, `plugins`, `claudecommands`, `claudecode`, or a local path |
1116
+ | `--claudecommand <name>` | Install/upgrade a specific command by name |
1117
+ | `-g, --global` | Install commands to user home directory (`~/.claude/commands/`) |
1118
+ | `--local` | Install commands to project directory (`.claude/commands/`) |
1119
+
1120
+ Smart behavior:
1121
+ - If the CLI is already installed, prompts to upgrade (with version comparison)
1122
+ - If plugins are already installed and up to date, reports "already up to date"
1123
+ - If plugins differ from source, prompts to upgrade to the latest version
1124
+ - Compares file hashes — unchanged files are skipped
1125
+ - Adds project-scoped command files to `.gitignore` (source of truth is `src/plugins/claudecommands/`)
1126
+ - Per-plugin scope (project or global) is stored in `.dbo/config.local.json` and remembered for future upgrades
1127
+ - On first install of a plugin without a stored preference, prompts for scope
1128
+ - `--global` / `--local` flags override stored preferences and update them
953
1129
 
954
1130
  ---
955
1131
 
package/bin/dbo.js CHANGED
@@ -18,15 +18,17 @@ import { pushCommand } from '../src/commands/push.js';
18
18
  import { pullCommand } from '../src/commands/pull.js';
19
19
  import { addCommand } from '../src/commands/add.js';
20
20
  import { installCommand } from '../src/commands/install.js';
21
- import { updateCommand } from '../src/commands/update.js';
22
21
  import { cloneCommand } from '../src/commands/clone.js';
22
+ import { diffCommand } from '../src/commands/diff.js';
23
+ import { rmCommand } from '../src/commands/rm.js';
24
+ import { mvCommand } from '../src/commands/mv.js';
23
25
 
24
26
  const program = new Command();
25
27
 
26
28
  program
27
29
  .name('dbo')
28
30
  .description('CLI for the DBO.io framework')
29
- .version('0.4.2');
31
+ .version('0.5.0');
30
32
 
31
33
  program.addCommand(initCommand);
32
34
  program.addCommand(loginCommand);
@@ -45,7 +47,9 @@ program.addCommand(pushCommand);
45
47
  program.addCommand(pullCommand);
46
48
  program.addCommand(addCommand);
47
49
  program.addCommand(installCommand);
48
- program.addCommand(updateCommand);
49
50
  program.addCommand(cloneCommand);
51
+ program.addCommand(diffCommand);
52
+ program.addCommand(rmCommand);
53
+ program.addCommand(mvCommand);
50
54
 
51
55
  program.parse();
package/package.json CHANGED
@@ -1,16 +1,22 @@
1
1
  {
2
2
  "name": "@dboio/cli",
3
- "version": "0.4.2",
3
+ "version": "0.5.1",
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
- "test": "node --test src/**/*.test.js"
19
+ "test": "node --test src/**/*.test.js tests/**/*.test.js"
14
20
  },
15
21
  "dependencies": {
16
22
  "commander": "^12.1.0",
@@ -26,7 +32,7 @@
26
32
  "rest",
27
33
  "crud"
28
34
  ],
29
- "license": "UNLICENSED",
35
+ "license": "MIT",
30
36
  "repository": {
31
37
  "type": "git",
32
38
  "url": "https://github.com/dboio/api.git",