vortex-cli 5.0.1__tar.gz → 6.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/PKG-INFO +185 -5
  2. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/README.md +184 -4
  3. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/pyproject.toml +1 -1
  4. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/cli.py +287 -20
  5. vortex_cli-6.1.0/vortex/commands/agenda.py +163 -0
  6. vortex_cli-6.1.0/vortex/commands/clean.py +214 -0
  7. vortex_cli-6.1.0/vortex/commands/clone.py +630 -0
  8. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/commands/compile.py +7 -2
  9. vortex_cli-6.1.0/vortex/commands/config.py +126 -0
  10. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/commands/copy.py +29 -4
  11. vortex_cli-6.1.0/vortex/commands/db.py +375 -0
  12. vortex_cli-6.1.0/vortex/commands/delete.py +141 -0
  13. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/commands/execute.py +33 -1
  14. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/commands/export.py +16 -4
  15. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/commands/list.py +84 -9
  16. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/commands/log.py +35 -4
  17. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/commands/new.py +78 -17
  18. vortex_cli-6.1.0/vortex/commands/pull.py +398 -0
  19. vortex_cli-6.1.0/vortex/commands/push.py +132 -0
  20. vortex_cli-6.1.0/vortex/commands/render.py +77 -0
  21. vortex_cli-6.1.0/vortex/commands/schema.py +669 -0
  22. vortex_cli-6.1.0/vortex/commands/status.py +86 -0
  23. vortex_cli-6.1.0/vortex/commands/undo.py +144 -0
  24. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/commands/watch.py +117 -4
  25. vortex_cli-6.1.0/vortex/gateway.py +859 -0
  26. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/main.py +102 -3
  27. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/models.py +199 -2
  28. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/soap.py +59 -0
  29. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/templates/agent/AGENTS.md +43 -9
  30. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/templates/agent/skills/puakma-design-elements/SKILL.md +23 -8
  31. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/templates/agent/skills/puakma-overview/SKILL.md +23 -13
  32. vortex_cli-6.1.0/vortex/templates/agent/skills/vortex-workflow/SKILL.md +262 -0
  33. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/util.py +10 -0
  34. vortex_cli-6.1.0/vortex/webdesign.py +653 -0
  35. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/workspace.py +63 -5
  36. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex_cli.egg-info/PKG-INFO +185 -5
  37. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex_cli.egg-info/SOURCES.txt +7 -0
  38. vortex_cli-5.0.1/vortex/commands/clean.py +0 -58
  39. vortex_cli-5.0.1/vortex/commands/clone.py +0 -319
  40. vortex_cli-5.0.1/vortex/commands/config.py +0 -67
  41. vortex_cli-5.0.1/vortex/commands/db.py +0 -187
  42. vortex_cli-5.0.1/vortex/commands/delete.py +0 -83
  43. vortex_cli-5.0.1/vortex/commands/schema.py +0 -400
  44. vortex_cli-5.0.1/vortex/templates/agent/skills/vortex-workflow/SKILL.md +0 -148
  45. vortex_cli-5.0.1/vortex/webdesign.py +0 -120
  46. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/LICENSE +0 -0
  47. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/setup.cfg +0 -0
  48. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/__init__.py +0 -0
  49. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/__main__.py +0 -0
  50. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/colour.py +0 -0
  51. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/commands/__init__.py +0 -0
  52. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/commands/agent.py +0 -0
  53. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/commands/code.py +0 -0
  54. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/commands/docs.py +0 -0
  55. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/commands/find.py +0 -0
  56. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/commands/grep.py +0 -0
  57. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/commands/import_.py +0 -0
  58. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/commands/libs.py +0 -0
  59. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/commands/use.py +0 -0
  60. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/constants.py +0 -0
  61. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/docs/Blackbook v2.md +0 -0
  62. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/docs/Blackbook.pdf +0 -0
  63. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/docs/index.html +0 -0
  64. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/docs/marked.min.js +0 -0
  65. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/lib/puakma-6.0.40.jar +0 -0
  66. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/libs.py +0 -0
  67. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/logging.py +0 -0
  68. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/spinner.py +0 -0
  69. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/templates/agent/skills/puakma-database/SKILL.md +0 -0
  70. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex/templates/agent/vortex.code-snippets +0 -0
  71. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex_cli.egg-info/dependency_links.txt +0 -0
  72. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex_cli.egg-info/entry_points.txt +0 -0
  73. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex_cli.egg-info/requires.txt +0 -0
  74. {vortex_cli-5.0.1 → vortex_cli-6.1.0}/vortex_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vortex_cli
3
- Version: 5.0.1
3
+ Version: 6.1.0
4
4
  Summary: Vortex CLI
5
5
  Author-email: Jordan Amos <jordan.amos@gmail.com>
6
6
  License: MIT License
@@ -95,10 +95,12 @@ While it is possible to use without it, this software has been purposefully desi
95
95
  [server1] ; This can be called whatever you want and can be referenced using the '--server' flag
96
96
  host = example.com
97
97
  port = 8080 ; we can overwrite the DEFAULT value
98
- puakma_db_conn_id = 13
99
98
  username = myuser ; Optional - Prompted at runtime if not provided
100
99
  password = mypassword ; Optional - Prompted at runtime if not provided
101
100
  ; Optional
101
+ puakma_db_conn_id = 13 ; Optional - discovered from the server when omitted
102
+ backend = soap ; 'soap' (default) or 'gateway' - see The Agent Gateway below
103
+ gateway_path = vortex/gateway.pma ; only used when backend = gateway
102
104
  clone_with_resources = html,css,js ; resources with these extensions are always cloned - 'clone --get-resources' still clones ALL resources
103
105
  lib_path = ; optional extra jars to add to the classpath (the server's own jars are downloaded automatically - see 'vortex libs')
104
106
  workspace_folders = ~/dev/shared,notes ; extra folders to mount in the generated .code-workspace files. Relative paths resolve against the workspace root. Under [DEFAULT] they are added to every workspace; here they apply to this server's workspace (and the global one)
@@ -106,6 +108,22 @@ While it is possible to use without it, this software has been purposefully desi
106
108
  java_environment_name = JavaSE-17 ; Java Execution Environment name https://docs.osgi.org/reference/eenames.html
107
109
  ```
108
110
 
111
+ ## Upgrading to 6.0
112
+
113
+ 6.0 is additive - **the default behaviour is unchanged**. Every server keeps using the SOAP
114
+ designer path unless you opt it in.
115
+
116
+ - **New optional backend: the agent gateway.** Set `backend = gateway` on a server definition
117
+ to route supported operations through the `vortex/gateway` Puakma application instead of
118
+ SOAPDesigner. The default is `backend = soap`, which never contacts the gateway at all - so
119
+ servers without it installed are unaffected. See [The Agent Gateway](#the-agent-gateway).
120
+ - **New commands**: `status`, `agenda`, `push`, `pull`, `render` and `undo`. `agenda`, `pull`,
121
+ `render` and `undo` require `backend = gateway`; `status` and `push` fall back to the
122
+ existing paths.
123
+ - **`puakma_db_conn_id` is now optional.** When omitted it is discovered from the server on
124
+ both backends. Existing configs that set it explicitly keep working.
125
+ - **`vortex list` gains Version and Last Modified columns** when run against a gateway server.
126
+
109
127
  ## Upgrading to 5.0
110
128
 
111
129
  5.0 changes some defaults you may rely on:
@@ -132,11 +150,23 @@ For a full list of commands see `--help`.
132
150
  - `code`: Open the workspace in Visual Studio Code (`-s <server>` opens that server's own workspace with exactly its jars on the Java classpath).
133
151
  - `use`: Set the default server so you don't need to pass `--server` on every command. e.g. `vortex use production`
134
152
  - `list` (or `ls`): List Puakma Applications on the server or cloned locally. (`ls` is an alias for `vortex list --local`)
135
- - `clone`: Clone Puakma Applications and their design objects into the workspace. Apps can be referenced by ID (`vortex clone 13`), by TemplateName (`vortex clone bettrackr_app`), or by group/name (`vortex clone bettrackr/app`) - all optionally server-qualified (`dev:13`, `dev:bettrackr/app`).
153
+ - `clone`: Clone Puakma Applications and their design objects into the workspace. Apps can be referenced by ID (`vortex clone 13`), by TemplateName (`vortex clone bettrackr_app`), or by group/name (`vortex clone bettrackr/app`). A bare application group clones every active, non-inherited application in it (`vortex clone BetTrackr`; add `--all`/`-a` for the disabled and inherited ones too) - all optionally server-qualified (`dev:13`, `dev:bettrackr/app`, `dev:BetTrackr`). `--reclone` re-clones what is already cloned: every server's clones, or one server's with `--server`. See [Cloning a whole group](#cloning-a-whole-group).
136
154
  - `watch`: Watch the workspace for changes to Design Objects and automatically upload them to the server each app was cloned from. Watches all servers at once unless `--server` is given.
137
155
  - `clean`: Delete the locally cloned Puakma Application directories in the workspace.
138
- - `config`: View and manage configuration.
156
+ Takes optional `APP_ID`s to clean just those clones (all of the server's, if none are
157
+ given). Deletes immediately and needs no network - there is no undo. With `--check`
158
+ it first asks the server for its design element hashes and refuses to delete a clone
159
+ holding local changes the server doesn't have, naming each file; that needs a
160
+ reachable `backend=gateway` server, and a clone it can't verify is refused rather
161
+ than silently deleted.
162
+ - `config`: View and manage configuration. `--check-gateway` reports the agent gateway negotiation and which gateway roles your identity holds.
139
163
  - `log`: View the server log.
164
+ - `status`: Show the server status - via the agent gateway when available, otherwise the raw console `status` output.
165
+ - `agenda`: List every scheduled action with its decoded schedule, last and next run, and whether it is overdue (read-only, gateway only).
166
+ - `push`: Upload local design files (source, compiled classes, pages, resources) to the server without a watch session - journaled and deploy-confirmed when routed via the gateway.
167
+ - `pull`: Refresh cloned applications in place via the gateway's incremental sync - only elements changed since the last sync are downloaded. Refuses to overwrite locally modified files without `--force`.
168
+ - `render`: Render a PAGE server-side as your identity and print it (or `--out FILE`) - see a change without a browser login (gateway only).
169
+ - `undo`: The server-side undo journal. No arguments lists journal entries; with an entry id it dry-runs a restore, and `--confirm` writes the journaled version back (gateway only).
140
170
  - `find`: Find Design Objects of cloned applications by name.
141
171
  - `grep`: Search the contents of cloned Design Objects using a Regular Expression.
142
172
  - `new`: Create new Design Objects, Applications, or Keywords. Use `--update <ID>` to update instead. Run without flags to launch an interactive wizard.
@@ -150,6 +180,36 @@ For a full list of commands see `--help`.
150
180
  - `docs`: Open the Tornado Server Blackbook.
151
181
  - `execute`: Execute a command on the server.
152
182
 
183
+ ### Cloning a whole group
184
+
185
+ `vortex clone` takes an ID, a TemplateName, an application group, or `group/name`:
186
+
187
+ ```
188
+ vortex clone 13 # by ID
189
+ vortex clone bettrackr_app # by TemplateName
190
+ vortex clone bettrackr/app # by group/name
191
+ vortex clone BetTrackr # every active application in the BetTrackr group
192
+ vortex clone -a BetTrackr # ... including its disabled and inherited ones
193
+ vortex clone dev:BetTrackr # ... on the 'dev' server
194
+ vortex clone --group BetTrackr # explicitly a group, never a TemplateName
195
+ ```
196
+
197
+ A group clone skips disabled and inherited applications (the ones `vortex list`
198
+ hides by default) unless `--all`/`-a` is given. An application you name outright -
199
+ by ID, TemplateName or `group/name` - is always cloned, whatever its state.
200
+
201
+ Groups are matched the way `vortex list --group` matches them - a
202
+ case-insensitive substring - except that an exact (case-insensitive) group name
203
+ always wins, so cloning `BetTrackr` never drags in `BetTrackrLegacy`. If a
204
+ partial name still spans several groups, vortex stops and lists them rather
205
+ than cloning the lot.
206
+
207
+ A bare word is looked up as **both** a TemplateName and a group. In the rare
208
+ case that it is genuinely both, vortex refuses to guess: use `--group NAME` for
209
+ the group, or the ID / `group/name` for the single application. Every flag
210
+ (`--reclone`, `--all`, `--get-resources`, `--open-urls`, `--timeout`, `--server`)
211
+ applies to group clones as it does to single apps.
212
+
153
213
  ### Working with Multiple Servers
154
214
 
155
215
  Each section in `servers.ini` defines a server (hosts must be unique across
@@ -173,7 +233,9 @@ apps from several servers at the same time:
173
233
  watcher doesn't know about). Finer-grained commands that alter design
174
234
  elements (`delete`, `copy`, `new`, `compile --upload`) lock
175
235
  per-application: they are refused for apps a watch is watching and run
176
- concurrently otherwise.
236
+ concurrently otherwise. `push` and `pull` lock the same way - per
237
+ application, never workspace-wide - so they can run against one app while
238
+ a watch holds others.
177
239
  - In VS Code, app folders are listed in per-server blocks (`dev: group/app`,
178
240
  ...) with the server's jars on the Java classpath (see them in the Java
179
241
  Projects view). vscode-java's classpath settings are
@@ -216,6 +278,112 @@ hard to change by accident:
216
278
  - `vortex watch` skips protected servers unless `--include-protected` is
217
279
  given, so saving a file can never hot-deploy to production by accident.
218
280
 
281
+ ### The Agent Gateway
282
+
283
+ The **agent gateway** is a JSON API served by the Puakma server itself - a companion Puakma
284
+ application (`vortex/gateway`) that you deploy to a server. Where SOAPDesigner is a transport,
285
+ the gateway is a transport *plus* the guarantees only server-side code can enforce:
286
+
287
+ - **Role-gated operations** - every endpoint requires one declared application role, checked on
288
+ the server. Roles are rows in *that server's* copy of the app, so a grant on dev confers
289
+ nothing on prod.
290
+ - **An undo journal** - destructive design writes snapshot the element first (bytes, metadata,
291
+ design params). `vortex undo` lists those snapshots and restores any of them; deleted
292
+ elements are recreatable.
293
+ - **Dry-run by default** - `undo`, element deletes, single-statement DML and whole-server
294
+ refresh do nothing without an explicit confirmation.
295
+ - **Deploy confirmation** - writes reply with the sizes and hashes of what is really on the
296
+ server now.
297
+ - **Database guardrails** - the Puakma system database is unreachable through it, and DDL is
298
+ never executed, only generated as text.
299
+
300
+ Opt in per server:
301
+
302
+ ```ini
303
+ [dev]
304
+ host = dev.example.com
305
+ backend = gateway ; default is 'soap', which never contacts the gateway
306
+ ; gateway_path = vortex/gateway.pma (this is the default)
307
+ ```
308
+
309
+ With `backend = gateway`, `watch`/`push` uploads, `delete`, `log`, `status`, `db`, `execute`
310
+ and the journal commands route through it, and `agenda`, `pull`, `render` and `undo` become
311
+ available. Everything the gateway does not offer goes to the **webdesign vortex API** (the
312
+ JSON action served by `system/webdesign`) - see [SOAP-free on backend = gateway](#soap-free-on-backend--gateway).
313
+ A `backend = gateway` server never talks to SOAPDesigner at all. Check what you are talking
314
+ to and what you may do:
315
+
316
+ ```
317
+ vortex config --check-gateway -s dev
318
+ ```
319
+
320
+ **There is no fallback in either direction, by design.** A gateway refusal (for example, your
321
+ identity lacks the required role) is reported as an error - vortex never quietly retries the
322
+ same operation over SOAP, because that would let anyone with SOAP access bypass every role,
323
+ journal and guardrail above. Likewise `backend = soap` never contacts the gateway. The one
324
+ deliberate exception is the gateway application's *own* deployments, which never go through
325
+ the gateway (webdesign on `backend = gateway`, SOAP on `backend = soap`) so that a broken
326
+ gateway deploy never needs the gateway to fix itself.
327
+
328
+ The gateway application is **not bundled with this CLI** - deploy it to a server with
329
+ `vortex export` / `vortex import`, then run its `Setup` scheduled action. It ships its own
330
+ `API.md`, `README.md` and `DECISIONS.md` as DOCUMENTATION design elements, so once installed
331
+ the running server documents its own endpoints, roles and setup steps.
332
+
333
+ > **Note:** the gateway's roles are only a real boundary for an identity whose *sole* route to
334
+ > the server is the gateway. Any identity that can reach `system/webdesign` or deploy code can
335
+ > grant itself any role. Keep webdesign access for operators; agent identities should not have
336
+ > it.
337
+
338
+ ### SOAP-free on `backend = gateway`
339
+
340
+ SOAPDesigner is legacy. On a `backend = gateway` server the commands the gateway does not
341
+ cover use the JSON API of `system/webdesign`'s `vortex` action instead - with the same
342
+ credentials, and the webdesign app's own ACL. SOAP is used only when a server is explicitly
343
+ `backend = soap`. The data dictionary (`schema`, `db --list/--schema`) is the exception that
344
+ proves the rule: the gateway's `dictionary` endpoint runs that same webdesign `vortex` action
345
+ server-side behind `GatewayDBRead`/`GatewayDBWrite`, so an agent identity with no webdesign
346
+ access gets a clean role answer rather than a login page, and a change to `vortex.java`
347
+ needs no change to the gateway.
348
+
349
+ | Command | `backend = gateway` | `backend = soap` |
350
+ |---|---|---|
351
+ | `push`, `watch` (modify), `compile --upload` | gateway `upload` (journalled); the gateway app itself: webdesign `PUT design` | SOAP `uploadDesign` |
352
+ | `watch` (create / delete) | webdesign `POST` / `DELETE design` | SOAP |
353
+ | `delete` | gateway `delete` (journalled); the gateway app itself: webdesign | SOAP |
354
+ | `copy`, `new object` | webdesign `POST`/`PUT design`, `PUT design/params` | SOAP |
355
+ | `new app` | webdesign `POST vortex` | SOAP `saveApplication` |
356
+ | `new keyword` | gateway `keyword` (upsert) | SOAP `saveKeyword` |
357
+ | `schema`, `db --list`, `db --schema` | gateway `dictionary` (webdesign's `database`/`table`/`column` routes run server-side; `GatewayDBRead`/`GatewayDBWrite`) | SOAP SQL + `savePuakma*` |
358
+ | `export` | webdesign `ExportPMX` action | SOAP `downloadPmx` |
359
+ | `import` | **still SOAP** - webdesign has no import route yet | SOAP `uploadPmx` |
360
+ | `db --sql`, `list`, `log`, `execute`, `status`, `clone`, `pull` | gateway | SOAP |
361
+
362
+ Where the webdesign API behaves differently from SOAP, the CLI compensates so the commands
363
+ behave as they did. The differences that remain visible:
364
+
365
+ - **Design element writes are whole-row.** The CLI reads the row back first and re-sends what
366
+ it does not model (the other blob, `Options`), so a `DATA`-only upload never wipes source.
367
+ One consequence: every write is one extra `GET`.
368
+ - **Renaming with `new object --update --name` does not rewrite references.** SOAP's
369
+ `updateDesignObject` also updated design params in the app that referred to the old name;
370
+ the webdesign route does not. Fix `OpenAction`/`ParentPage`-style params by hand after a rename.
371
+ - **`schema` cannot record `--default`, `--position` or the column half of `--ref`.** The
372
+ webdesign column write has no `DefaultValue`/`Position`/`RefColumn` fields (SOAP's
373
+ `savePuakmaAttribute2` had them). `--default`/`--position` are refused with a message;
374
+ `--ref TABLE.COLUMN` records the table and warns. Updates leave existing values untouched.
375
+ Extend `POST`/`PUT .../column` in webdesign's `vortex.java` to lift this.
376
+ - **Every write flushes the application's design cache**, where SOAP flushed one element.
377
+ - **No per-application `Developer` role check** - the webdesign app's ACL is the boundary. An
378
+ identity that can reach `system/webdesign` can edit every application through it.
379
+ - **`db --list` orders by table name** (SOAP's `SELECT DISTINCT` had no order); `--schema`
380
+ output is identical.
381
+ - **Database-name resolution is app-scoped.** `schema`/`db --list` find the connection whose
382
+ dictionary holds the tables (as SOAP did by `pmatable` count), asking locally cloned
383
+ applications first and scanning the server inventory only if none of them has it.
384
+ - **`import` remains SOAP** on every backend until webdesign gains a PMX import route
385
+ (`SaveImportPMX` is a multipart UI form, not an API).
386
+
219
387
  ### Interactive Wizards
220
388
 
221
389
  Run `vortex new object` or `vortex new app` without any flags to launch a step-by-step wizard:
@@ -311,6 +479,11 @@ vortex schema mydb --add-column invoice customer_id --type BIGINT --ref customer
311
479
  vortex schema mydb --ddl invoice # print CREATE TABLE from the dictionary
312
480
  ```
313
481
 
482
+ On a `backend = gateway` server the dictionary is reached through webdesign's vortex API via
483
+ the gateway's `dictionary` endpoint (`GatewayDBRead` to read, `GatewayDBWrite` to change).
484
+ That API cannot record `--default` or `--position` (refused) nor the column half of `--ref`
485
+ (warned) - see [SOAP-free on backend = gateway](#soap-free-on-backend--gateway).
486
+
314
487
  ### Agent Support Files
315
488
 
316
489
  `vortex agent` copies bundled support files into the workspace `.vscode` directory so they are
@@ -321,5 +494,12 @@ and the vortex workflow, and a `vortex.code-snippets` file with common Puakma Ja
321
494
  snippets. Existing files are never overwritten, so they are safe to customise. These files are
322
495
  also generated automatically on `vortex --init` and before `vortex code` opens the workspace.
323
496
 
497
+ The guidance is backend-aware: on a `backend = gateway` server the skills teach the explicit
498
+ `vortex compile` + `vortex push` deploy loop (journaled, `undo`-recoverable, no workspace lock),
499
+ and the `vortex watch` save-to-deploy loop is scoped to `backend = soap`. Because existing files
500
+ are never overwritten, workspaces generated before 6.0.0 keep their old watch-centric copies -
501
+ delete a file (or the `.claude/skills` directory) and re-run `vortex agent` to pick up the
502
+ current version.
503
+
324
504
  Workspaces created before AGENTS.md existed keep their full `CLAUDE.md` (existing files are
325
505
  never touched); the new `AGENTS.md` is simply added alongside it.
@@ -51,10 +51,12 @@ While it is possible to use without it, this software has been purposefully desi
51
51
  [server1] ; This can be called whatever you want and can be referenced using the '--server' flag
52
52
  host = example.com
53
53
  port = 8080 ; we can overwrite the DEFAULT value
54
- puakma_db_conn_id = 13
55
54
  username = myuser ; Optional - Prompted at runtime if not provided
56
55
  password = mypassword ; Optional - Prompted at runtime if not provided
57
56
  ; Optional
57
+ puakma_db_conn_id = 13 ; Optional - discovered from the server when omitted
58
+ backend = soap ; 'soap' (default) or 'gateway' - see The Agent Gateway below
59
+ gateway_path = vortex/gateway.pma ; only used when backend = gateway
58
60
  clone_with_resources = html,css,js ; resources with these extensions are always cloned - 'clone --get-resources' still clones ALL resources
59
61
  lib_path = ; optional extra jars to add to the classpath (the server's own jars are downloaded automatically - see 'vortex libs')
60
62
  workspace_folders = ~/dev/shared,notes ; extra folders to mount in the generated .code-workspace files. Relative paths resolve against the workspace root. Under [DEFAULT] they are added to every workspace; here they apply to this server's workspace (and the global one)
@@ -62,6 +64,22 @@ While it is possible to use without it, this software has been purposefully desi
62
64
  java_environment_name = JavaSE-17 ; Java Execution Environment name https://docs.osgi.org/reference/eenames.html
63
65
  ```
64
66
 
67
+ ## Upgrading to 6.0
68
+
69
+ 6.0 is additive - **the default behaviour is unchanged**. Every server keeps using the SOAP
70
+ designer path unless you opt it in.
71
+
72
+ - **New optional backend: the agent gateway.** Set `backend = gateway` on a server definition
73
+ to route supported operations through the `vortex/gateway` Puakma application instead of
74
+ SOAPDesigner. The default is `backend = soap`, which never contacts the gateway at all - so
75
+ servers without it installed are unaffected. See [The Agent Gateway](#the-agent-gateway).
76
+ - **New commands**: `status`, `agenda`, `push`, `pull`, `render` and `undo`. `agenda`, `pull`,
77
+ `render` and `undo` require `backend = gateway`; `status` and `push` fall back to the
78
+ existing paths.
79
+ - **`puakma_db_conn_id` is now optional.** When omitted it is discovered from the server on
80
+ both backends. Existing configs that set it explicitly keep working.
81
+ - **`vortex list` gains Version and Last Modified columns** when run against a gateway server.
82
+
65
83
  ## Upgrading to 5.0
66
84
 
67
85
  5.0 changes some defaults you may rely on:
@@ -88,11 +106,23 @@ For a full list of commands see `--help`.
88
106
  - `code`: Open the workspace in Visual Studio Code (`-s <server>` opens that server's own workspace with exactly its jars on the Java classpath).
89
107
  - `use`: Set the default server so you don't need to pass `--server` on every command. e.g. `vortex use production`
90
108
  - `list` (or `ls`): List Puakma Applications on the server or cloned locally. (`ls` is an alias for `vortex list --local`)
91
- - `clone`: Clone Puakma Applications and their design objects into the workspace. Apps can be referenced by ID (`vortex clone 13`), by TemplateName (`vortex clone bettrackr_app`), or by group/name (`vortex clone bettrackr/app`) - all optionally server-qualified (`dev:13`, `dev:bettrackr/app`).
109
+ - `clone`: Clone Puakma Applications and their design objects into the workspace. Apps can be referenced by ID (`vortex clone 13`), by TemplateName (`vortex clone bettrackr_app`), or by group/name (`vortex clone bettrackr/app`). A bare application group clones every active, non-inherited application in it (`vortex clone BetTrackr`; add `--all`/`-a` for the disabled and inherited ones too) - all optionally server-qualified (`dev:13`, `dev:bettrackr/app`, `dev:BetTrackr`). `--reclone` re-clones what is already cloned: every server's clones, or one server's with `--server`. See [Cloning a whole group](#cloning-a-whole-group).
92
110
  - `watch`: Watch the workspace for changes to Design Objects and automatically upload them to the server each app was cloned from. Watches all servers at once unless `--server` is given.
93
111
  - `clean`: Delete the locally cloned Puakma Application directories in the workspace.
94
- - `config`: View and manage configuration.
112
+ Takes optional `APP_ID`s to clean just those clones (all of the server's, if none are
113
+ given). Deletes immediately and needs no network - there is no undo. With `--check`
114
+ it first asks the server for its design element hashes and refuses to delete a clone
115
+ holding local changes the server doesn't have, naming each file; that needs a
116
+ reachable `backend=gateway` server, and a clone it can't verify is refused rather
117
+ than silently deleted.
118
+ - `config`: View and manage configuration. `--check-gateway` reports the agent gateway negotiation and which gateway roles your identity holds.
95
119
  - `log`: View the server log.
120
+ - `status`: Show the server status - via the agent gateway when available, otherwise the raw console `status` output.
121
+ - `agenda`: List every scheduled action with its decoded schedule, last and next run, and whether it is overdue (read-only, gateway only).
122
+ - `push`: Upload local design files (source, compiled classes, pages, resources) to the server without a watch session - journaled and deploy-confirmed when routed via the gateway.
123
+ - `pull`: Refresh cloned applications in place via the gateway's incremental sync - only elements changed since the last sync are downloaded. Refuses to overwrite locally modified files without `--force`.
124
+ - `render`: Render a PAGE server-side as your identity and print it (or `--out FILE`) - see a change without a browser login (gateway only).
125
+ - `undo`: The server-side undo journal. No arguments lists journal entries; with an entry id it dry-runs a restore, and `--confirm` writes the journaled version back (gateway only).
96
126
  - `find`: Find Design Objects of cloned applications by name.
97
127
  - `grep`: Search the contents of cloned Design Objects using a Regular Expression.
98
128
  - `new`: Create new Design Objects, Applications, or Keywords. Use `--update <ID>` to update instead. Run without flags to launch an interactive wizard.
@@ -106,6 +136,36 @@ For a full list of commands see `--help`.
106
136
  - `docs`: Open the Tornado Server Blackbook.
107
137
  - `execute`: Execute a command on the server.
108
138
 
139
+ ### Cloning a whole group
140
+
141
+ `vortex clone` takes an ID, a TemplateName, an application group, or `group/name`:
142
+
143
+ ```
144
+ vortex clone 13 # by ID
145
+ vortex clone bettrackr_app # by TemplateName
146
+ vortex clone bettrackr/app # by group/name
147
+ vortex clone BetTrackr # every active application in the BetTrackr group
148
+ vortex clone -a BetTrackr # ... including its disabled and inherited ones
149
+ vortex clone dev:BetTrackr # ... on the 'dev' server
150
+ vortex clone --group BetTrackr # explicitly a group, never a TemplateName
151
+ ```
152
+
153
+ A group clone skips disabled and inherited applications (the ones `vortex list`
154
+ hides by default) unless `--all`/`-a` is given. An application you name outright -
155
+ by ID, TemplateName or `group/name` - is always cloned, whatever its state.
156
+
157
+ Groups are matched the way `vortex list --group` matches them - a
158
+ case-insensitive substring - except that an exact (case-insensitive) group name
159
+ always wins, so cloning `BetTrackr` never drags in `BetTrackrLegacy`. If a
160
+ partial name still spans several groups, vortex stops and lists them rather
161
+ than cloning the lot.
162
+
163
+ A bare word is looked up as **both** a TemplateName and a group. In the rare
164
+ case that it is genuinely both, vortex refuses to guess: use `--group NAME` for
165
+ the group, or the ID / `group/name` for the single application. Every flag
166
+ (`--reclone`, `--all`, `--get-resources`, `--open-urls`, `--timeout`, `--server`)
167
+ applies to group clones as it does to single apps.
168
+
109
169
  ### Working with Multiple Servers
110
170
 
111
171
  Each section in `servers.ini` defines a server (hosts must be unique across
@@ -129,7 +189,9 @@ apps from several servers at the same time:
129
189
  watcher doesn't know about). Finer-grained commands that alter design
130
190
  elements (`delete`, `copy`, `new`, `compile --upload`) lock
131
191
  per-application: they are refused for apps a watch is watching and run
132
- concurrently otherwise.
192
+ concurrently otherwise. `push` and `pull` lock the same way - per
193
+ application, never workspace-wide - so they can run against one app while
194
+ a watch holds others.
133
195
  - In VS Code, app folders are listed in per-server blocks (`dev: group/app`,
134
196
  ...) with the server's jars on the Java classpath (see them in the Java
135
197
  Projects view). vscode-java's classpath settings are
@@ -172,6 +234,112 @@ hard to change by accident:
172
234
  - `vortex watch` skips protected servers unless `--include-protected` is
173
235
  given, so saving a file can never hot-deploy to production by accident.
174
236
 
237
+ ### The Agent Gateway
238
+
239
+ The **agent gateway** is a JSON API served by the Puakma server itself - a companion Puakma
240
+ application (`vortex/gateway`) that you deploy to a server. Where SOAPDesigner is a transport,
241
+ the gateway is a transport *plus* the guarantees only server-side code can enforce:
242
+
243
+ - **Role-gated operations** - every endpoint requires one declared application role, checked on
244
+ the server. Roles are rows in *that server's* copy of the app, so a grant on dev confers
245
+ nothing on prod.
246
+ - **An undo journal** - destructive design writes snapshot the element first (bytes, metadata,
247
+ design params). `vortex undo` lists those snapshots and restores any of them; deleted
248
+ elements are recreatable.
249
+ - **Dry-run by default** - `undo`, element deletes, single-statement DML and whole-server
250
+ refresh do nothing without an explicit confirmation.
251
+ - **Deploy confirmation** - writes reply with the sizes and hashes of what is really on the
252
+ server now.
253
+ - **Database guardrails** - the Puakma system database is unreachable through it, and DDL is
254
+ never executed, only generated as text.
255
+
256
+ Opt in per server:
257
+
258
+ ```ini
259
+ [dev]
260
+ host = dev.example.com
261
+ backend = gateway ; default is 'soap', which never contacts the gateway
262
+ ; gateway_path = vortex/gateway.pma (this is the default)
263
+ ```
264
+
265
+ With `backend = gateway`, `watch`/`push` uploads, `delete`, `log`, `status`, `db`, `execute`
266
+ and the journal commands route through it, and `agenda`, `pull`, `render` and `undo` become
267
+ available. Everything the gateway does not offer goes to the **webdesign vortex API** (the
268
+ JSON action served by `system/webdesign`) - see [SOAP-free on backend = gateway](#soap-free-on-backend--gateway).
269
+ A `backend = gateway` server never talks to SOAPDesigner at all. Check what you are talking
270
+ to and what you may do:
271
+
272
+ ```
273
+ vortex config --check-gateway -s dev
274
+ ```
275
+
276
+ **There is no fallback in either direction, by design.** A gateway refusal (for example, your
277
+ identity lacks the required role) is reported as an error - vortex never quietly retries the
278
+ same operation over SOAP, because that would let anyone with SOAP access bypass every role,
279
+ journal and guardrail above. Likewise `backend = soap` never contacts the gateway. The one
280
+ deliberate exception is the gateway application's *own* deployments, which never go through
281
+ the gateway (webdesign on `backend = gateway`, SOAP on `backend = soap`) so that a broken
282
+ gateway deploy never needs the gateway to fix itself.
283
+
284
+ The gateway application is **not bundled with this CLI** - deploy it to a server with
285
+ `vortex export` / `vortex import`, then run its `Setup` scheduled action. It ships its own
286
+ `API.md`, `README.md` and `DECISIONS.md` as DOCUMENTATION design elements, so once installed
287
+ the running server documents its own endpoints, roles and setup steps.
288
+
289
+ > **Note:** the gateway's roles are only a real boundary for an identity whose *sole* route to
290
+ > the server is the gateway. Any identity that can reach `system/webdesign` or deploy code can
291
+ > grant itself any role. Keep webdesign access for operators; agent identities should not have
292
+ > it.
293
+
294
+ ### SOAP-free on `backend = gateway`
295
+
296
+ SOAPDesigner is legacy. On a `backend = gateway` server the commands the gateway does not
297
+ cover use the JSON API of `system/webdesign`'s `vortex` action instead - with the same
298
+ credentials, and the webdesign app's own ACL. SOAP is used only when a server is explicitly
299
+ `backend = soap`. The data dictionary (`schema`, `db --list/--schema`) is the exception that
300
+ proves the rule: the gateway's `dictionary` endpoint runs that same webdesign `vortex` action
301
+ server-side behind `GatewayDBRead`/`GatewayDBWrite`, so an agent identity with no webdesign
302
+ access gets a clean role answer rather than a login page, and a change to `vortex.java`
303
+ needs no change to the gateway.
304
+
305
+ | Command | `backend = gateway` | `backend = soap` |
306
+ |---|---|---|
307
+ | `push`, `watch` (modify), `compile --upload` | gateway `upload` (journalled); the gateway app itself: webdesign `PUT design` | SOAP `uploadDesign` |
308
+ | `watch` (create / delete) | webdesign `POST` / `DELETE design` | SOAP |
309
+ | `delete` | gateway `delete` (journalled); the gateway app itself: webdesign | SOAP |
310
+ | `copy`, `new object` | webdesign `POST`/`PUT design`, `PUT design/params` | SOAP |
311
+ | `new app` | webdesign `POST vortex` | SOAP `saveApplication` |
312
+ | `new keyword` | gateway `keyword` (upsert) | SOAP `saveKeyword` |
313
+ | `schema`, `db --list`, `db --schema` | gateway `dictionary` (webdesign's `database`/`table`/`column` routes run server-side; `GatewayDBRead`/`GatewayDBWrite`) | SOAP SQL + `savePuakma*` |
314
+ | `export` | webdesign `ExportPMX` action | SOAP `downloadPmx` |
315
+ | `import` | **still SOAP** - webdesign has no import route yet | SOAP `uploadPmx` |
316
+ | `db --sql`, `list`, `log`, `execute`, `status`, `clone`, `pull` | gateway | SOAP |
317
+
318
+ Where the webdesign API behaves differently from SOAP, the CLI compensates so the commands
319
+ behave as they did. The differences that remain visible:
320
+
321
+ - **Design element writes are whole-row.** The CLI reads the row back first and re-sends what
322
+ it does not model (the other blob, `Options`), so a `DATA`-only upload never wipes source.
323
+ One consequence: every write is one extra `GET`.
324
+ - **Renaming with `new object --update --name` does not rewrite references.** SOAP's
325
+ `updateDesignObject` also updated design params in the app that referred to the old name;
326
+ the webdesign route does not. Fix `OpenAction`/`ParentPage`-style params by hand after a rename.
327
+ - **`schema` cannot record `--default`, `--position` or the column half of `--ref`.** The
328
+ webdesign column write has no `DefaultValue`/`Position`/`RefColumn` fields (SOAP's
329
+ `savePuakmaAttribute2` had them). `--default`/`--position` are refused with a message;
330
+ `--ref TABLE.COLUMN` records the table and warns. Updates leave existing values untouched.
331
+ Extend `POST`/`PUT .../column` in webdesign's `vortex.java` to lift this.
332
+ - **Every write flushes the application's design cache**, where SOAP flushed one element.
333
+ - **No per-application `Developer` role check** - the webdesign app's ACL is the boundary. An
334
+ identity that can reach `system/webdesign` can edit every application through it.
335
+ - **`db --list` orders by table name** (SOAP's `SELECT DISTINCT` had no order); `--schema`
336
+ output is identical.
337
+ - **Database-name resolution is app-scoped.** `schema`/`db --list` find the connection whose
338
+ dictionary holds the tables (as SOAP did by `pmatable` count), asking locally cloned
339
+ applications first and scanning the server inventory only if none of them has it.
340
+ - **`import` remains SOAP** on every backend until webdesign gains a PMX import route
341
+ (`SaveImportPMX` is a multipart UI form, not an API).
342
+
175
343
  ### Interactive Wizards
176
344
 
177
345
  Run `vortex new object` or `vortex new app` without any flags to launch a step-by-step wizard:
@@ -267,6 +435,11 @@ vortex schema mydb --add-column invoice customer_id --type BIGINT --ref customer
267
435
  vortex schema mydb --ddl invoice # print CREATE TABLE from the dictionary
268
436
  ```
269
437
 
438
+ On a `backend = gateway` server the dictionary is reached through webdesign's vortex API via
439
+ the gateway's `dictionary` endpoint (`GatewayDBRead` to read, `GatewayDBWrite` to change).
440
+ That API cannot record `--default` or `--position` (refused) nor the column half of `--ref`
441
+ (warned) - see [SOAP-free on backend = gateway](#soap-free-on-backend--gateway).
442
+
270
443
  ### Agent Support Files
271
444
 
272
445
  `vortex agent` copies bundled support files into the workspace `.vscode` directory so they are
@@ -277,5 +450,12 @@ and the vortex workflow, and a `vortex.code-snippets` file with common Puakma Ja
277
450
  snippets. Existing files are never overwritten, so they are safe to customise. These files are
278
451
  also generated automatically on `vortex --init` and before `vortex code` opens the workspace.
279
452
 
453
+ The guidance is backend-aware: on a `backend = gateway` server the skills teach the explicit
454
+ `vortex compile` + `vortex push` deploy loop (journaled, `undo`-recoverable, no workspace lock),
455
+ and the `vortex watch` save-to-deploy loop is scoped to `backend = soap`. Because existing files
456
+ are never overwritten, workspaces generated before 6.0.0 keep their old watch-centric copies -
457
+ delete a file (or the `.claude/skills` directory) and re-run `vortex agent` to pick up the
458
+ current version.
459
+
280
460
  Workspaces created before AGENTS.md existed keep their full `CLAUDE.md` (existing files are
281
461
  never touched); the new `AGENTS.md` is simply added alongside it.
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
 
6
6
  [project]
7
7
  name = "vortex_cli"
8
- version = "5.0.1"
8
+ version = "6.1.0"
9
9
  description = "Vortex CLI"
10
10
  requires-python = ">=3.10"
11
11
  readme = { file = "README.md", content-type = "text/markdown" }