@lotics/cli 0.315.18 → 0.316.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/AGENTS.md CHANGED
@@ -8,18 +8,22 @@ conventions are, and where the traps are.
8
8
  | `lotics --help` | The verb inventory (§ COMMANDS) and global flags. The verb LIST is generated and never stale; the prose beside each verb is hand-written, so where it disagrees with `docs/cli_reference.md`, the reference wins. |
9
9
  | `lotics tools` · `lotics tools <name>` | The agent tool registry and one tool's full JSON Schema. |
10
10
  | `lotics docs` · `lotics docs <area>[/<section>]` · `lotics docs [<area>] --grep <text>` | This CLI's references, carried inside it so each describes the binary answering. Capped at a page: a doc that does not fit hands back its opening and the addresses into it, so the next call is smaller than the last. A page the copy lacks — one the server added since this binary was built, which a refusal can cite — is read from the server's `docs` tool with this machine's credential, and so is every `--grep`, over the references the server serves. A custom-code app's SDK reference is `node_modules/@lotics/app-sdk/AGENTS.md` inside the app. |
11
- | `lotics docs model` · `lotics docs model/<section>` | How to write a `model.json` — the file a workspace is built from: its tables, how a row of each is recognised (`records`), and the apps stated over them. Every top-level key, every field type with the config it needs, the row format, the rules, and a worked example; complete example models of several trades are listed at `https://lotics.ai/presets/index.json`. `lotics model apply` checks the file (every problem in one run), applies its tables and mints a version of each app; the WORKSPACE remembers what each alias became, so every later apply binds by id and a relabel on either side is a rename it reports rather than a second table it adds. `lotics model pull` goes the other way — the workspace's model, rebuilt from what owns each part. |
12
- | `lotics docs design` · `lotics docs design/<section>` | Designing an app — where an app starts: the method, the treatment each kind of row takes with the `model` page stating its keys, the visual bar, and looking at what an apply built. A finding of the apply names its section. |
13
- | `lotics docs examples` · `lotics docs examples/<treatment>` | Each treatment worked through in an app of a complete model: the job, the keys to read, where it is the wrong one, and the excerpt. |
14
- | [docs/building_an_app.md](./docs/building_an_app.md) | The SEQUENCE — clarify, model, apply or build, prove, look — for an app stated in a model and for a custom-code app. Read it once before starting an app. Looking is `lotics run screenshot_app '<json>' -o <dir>`, which saves each PNG and its text snapshot there. |
11
+ | `lotics docs model` · `lotics docs model/<section>` | The keys of a table document and the components of an app tree: a table's fields keyed by alias, how a row of each table is recognised (`records`), and the apps stated over them. Every key, every field type with the config it needs, the rules, and a worked example; example files of several trades are listed at `https://lotics.ai/presets/index.json` — read one and pass its tables to `set_tables`. |
12
+ | `lotics docs design` · `lotics docs design/<section>` | Designing an app — the treatment each kind of row takes with the `model` page stating its keys, the visual bar, and looking at what a write built. Opens on the common treatments; a finding names its section. |
13
+ | `lotics docs examples` · `lotics docs examples/<treatment>` | Each treatment worked through in an app of a complete workspace: the job, the props to read, where it is the wrong one, and the excerpt. |
14
+ | [docs/getting_started.md](./docs/getting_started.md) | What a workspace holds, and the one page to open for each job: building a workspace, changing an app, a rule on a table, a document, data and questions, a connected service, sharing. The first page an agent outside the product reads. |
15
+ | [docs/first_build.md](./docs/first_build.md) | A whole workspace built call by call — understand the work, tables with a check, the paper, the app (which apps, a treatment per kind of row, what the check refuses, who gets it), the owner's rows, pressing it — in one worked example. |
16
+ | [docs/app_architecture.md](./docs/app_architecture.md) | One factory's split into apps: each app's job sentence, person, register and what sits inside it. The questions that split a business are in first_build. |
17
+ | [docs/working_in_a_workspace.md](./docs/working_in_a_workspace.md) | The right means for each job once the apps exist: an app's act for a business operation, a record write for data entry, a query for a figure the business defines, a count for the rest. |
18
+ | [docs/building_an_app.md](./docs/building_an_app.md) | The SEQUENCE — clarify, tables, apps, prove, look — for an app stated as a tree and for a custom-code app. Read it once before starting an app. Looking is `lotics run screenshot_app '<json>' -o <dir>`, which saves each PNG and its text snapshot there. |
15
19
  | [docs/cli_reference.md](./docs/cli_reference.md) | Per-command contracts, flags, exit codes, and gotchas — the detail `--help` compresses. |
16
- | [docs/data_model.md](./docs/data_model.md) | Tables, their fields, and how they relate — one fact per column, one entity per table and the NAME-OVERLAP probe that says when a split has broken, one vocabulary wherever values are copied, a copy boundary that accounts for every source field, provenance as a link, a declared natural key, history as rows, and why derived DEPTH costs more than row count; then every field type, its properties, computed fields, and what `update_fields` takes. Separate from building_an_app because every workspace starts with tables and many never get an app. |
20
+ | [docs/data_model.md](./docs/data_model.md) | Tables, their fields, and how they relate — one fact per column, one table per kind of thing and the NAME-OVERLAP probe that says when a split has broken, one vocabulary wherever values are copied, a copy boundary that accounts for every source field, provenance as a link, a declared natural key, history as rows, and why derived DEPTH costs more than row count; then the choices around a field's type, and how a field is changed (a list replaces whole, what refuses a deletion, what `force` consents to). Separate from building_an_app because every workspace starts with tables and many never get an app. |
17
21
  | [docs/filters.md](./docs/filters.md) | The one filter grammar every filter-taking tool, view and rollup reads — conditions, groups, and the operators per field type. |
18
22
  | [docs/field_values.md](./docs/field_values.md) | The value each field type takes in a write. |
19
23
  | [docs/workflows.md](./docs/workflows.md) | Writing a workflow body — triggers, steps, what an expression reads, the helpers, approvals and agent steps, and table checks. |
20
24
  | [docs/app_bindings.md](./docs/app_bindings.md) | The queries, workflows and agents an app binds — the query tree, typed inputs and outputs, and an agent's declaration. |
21
- | [docs/document_templates.md](./docs/document_templates.md) | Generating PDF/Excel/Word/email from reusable templates. |
22
- | [docs/knowledge_docs.md](./docs/knowledge_docs.md) | Authoring the workspace facts an agent can't guess; who can read a doc; catalog-then-stage retrieval. |
25
+ | [docs/document_templates.md](./docs/document_templates.md) | Generating PDF/Excel/Word/email from reusable templates, and what a template an app's Act makes is handed. |
26
+ | [docs/knowledge_docs.md](./docs/knowledge_docs.md) | Authoring the procedures, policies and glossary an agent can't guess with `set_knowledge`; who can read a doc; searching and reading it line by line. |
23
27
  | [docs/migration.md](./docs/migration.md) | What to DO when something an earlier CLI wrote to disk no longer matches what it does — local app projects are gone, and each verb that read one has a replacement. |
24
28
  | [README.md](./README.md) | Install, auth, and worked examples. |
25
29
 
@@ -30,14 +34,14 @@ conventions are, and where the traps are.
30
34
  - **Tools** (`lotics tools`, `lotics run <tool>`) — the *agent tool registry*: what an agent, workflow,
31
35
  or automation may call. Workspace data, templates, knowledge, admin.
32
36
  - **Commands** (`lotics --help` § COMMANDS) — the CLI's *own verbs*: auth and org/workspace scoping,
33
- file upload and download, and those that touch a local file for an app — `model apply`,
34
- `model check`, `model pull`, `app create --custom`, `app pull` and `app deploy`.
37
+ file upload and download, and those that touch a local file for an app — `app apply`,
38
+ `app create --custom`, `app pull` and `app deploy`.
35
39
 
36
40
  Several capabilities exist **only** as commands and appear nowhere in `lotics tools` — downloading a
37
41
  file is the one most often mistaken for missing. Concluding "the platform can't do X" from the tool
38
42
  list alone is a mistake; check both.
39
43
 
40
- **`lotics <verb> --help` prints that verb's entries from § COMMANDS** (`lotics model --help`,
44
+ **`lotics <verb> --help` prints that verb's entries from § COMMANDS** (`lotics app --help`,
41
45
  `lotics file download --help`); `lotics report --help` prints the report frame. To find out whether
42
46
  something exists, read `lotics --help` § COMMANDS — the whole section, not a narrow grep.
43
47
 
@@ -55,9 +59,8 @@ something exists, read `lotics --help` § COMMANDS — the whole section, not a
55
59
  and then re-running what you wanted. Never wrap it in a timeout waiting for a human — `--wait`
56
60
  exists if you really want one blocking command, and killing that one is safe too (the request
57
61
  survives and the next command claims it). A command run before Confirm exits 1 naming the page and
58
- code again; once the 15 minutes are up it says to ask again. `lotics setup` falls into the same
59
- flow by itself when the email it was given already has an account: it stops having created
60
- nothing, and the SAME command run again carries on.
62
+ code again; once the 15 minutes are up it says to ask again. `lotics auth signup <email>` for an email that
63
+ already has an account creates nothing and names `auth login`.
61
64
  - **A credential is either a SIGN-IN or an API KEY, and `logout` treats them differently.** A profile
62
65
  from `auth login` / `auth signup` acts as the person who confirmed it and is theirs — `lotics auth
63
66
  logout` revokes it server-side, and it lapses on its own after 90 idle days (each use pushes that
@@ -71,8 +74,7 @@ something exists, read `lotics --help` § COMMANDS — the whole section, not a
71
74
  wrong. `lotics auth whoami` prints the kind, asking the server when the store cannot say.
72
75
  - **A key created in Settings never administers the organization, whatever its access.** The verbs
73
76
  `docs/cli_reference.md` marks *admin only* split in two under a key: `workspace doctor`, which only
74
- reads inside a workspace the key reaches, runs as before, while applying or pulling a model
75
- (`model apply`, `model pull`, `setup`), managing people, sharing or
77
+ reads inside a workspace the key reaches, runs as before, while managing people, sharing or
76
78
  ownership, creating or deleting a workspace, changing workspace settings, setting credit limits,
77
79
  reading the access log and publishing an app's API answer `403` and name the remedy: an admin signed in, so
78
80
  `lotics auth login <email>` and run it again. A sign-in acts as that person and is refused none of
@@ -92,16 +94,27 @@ something exists, read `lotics --help` § COMMANDS — the whole section, not a
92
94
  stderr; the result goes to stdout, so piping stays clean. `--json` switches stdout from the
93
95
  agent-readable summary to the full structured object.
94
96
  - **Every tool is invoked one way — `lotics run <tool>`.** Including the ones that RUN something
95
- (`run_app_workflow`, `run_app_agent`, `run_app_query`) and every one that changes an app
96
- (`set_app_queries`, `set_app_workflow`, `set_app_agent`, `update_app`, `rollback_app`). A command
97
+ (`run_app_workflow`, `run_app_query`) and every one that builds
98
+ (`set_tables`, `set_app`, `set_app_queries`, `set_app_workflow`). A command
97
99
  exists only for work that touches a local file.
98
- - **Every change to an app mints a version of it, and rolling back is the undo.** An apply, a
99
- deploy, a single `set_app_*` or `remove_app_binding`: each is a new version, and `rollback_app` makes an
100
- earlier one current again. It restores the app — never a table change or a row a workflow wrote,
100
+ - **Building is two tools, each a writer that creates without an id and edits with one.** `set_tables`
101
+ takes `{ "tables": [...] }` — always a list, one or many, all or nothing — each table a document keyed
102
+ by alias (fields keyed by alias; a link names its table by id, or by the `ref` of another table of the
103
+ same call, and states `multi`; a two-way link states `pair` on both tables), edited by an RFC 7396
104
+ merge patch of that document, where `null` deletes. A call carries at most 50 tables, 200 first rows a table,
105
+ and 2000 rows and 2000 documents in all. `set_app` takes ONE app: `{ "body": <the App tree> }` to create, the app's
106
+ `name`, `description`, `icon` and `color` being props of the App node; `{ "app_id": …, "nodes": { "<address>": <patch> } }`
107
+ to change a node, refused with `base_version_id` when the app has moved past the version you read. `dry_run` checks
108
+ without writing, a refusal lists everything wrong in the call, and every answer states the permissions the write
109
+ granted and removed. The answer notes the treatments an author leaves unstated; nothing is written into the tree for them. A new workspace: one `set_tables` call with
110
+ the tables, then every `set_app` call, then fixes. The example files under `https://lotics.ai/presets/index.json` are read and their tables passed to
111
+ `set_tables`.
112
+ - **Every change to an app mints a version of it, and applying the earlier tree again is the undo.** An apply, a
113
+ deploy, a single `set_app_*` or `remove_app_binding`: each is a new version. Applying the earlier tree again restores the app — never a table change or a row a workflow wrote,
101
114
  so try a write on a throwaway record.
102
115
  - **Exit codes are assertable, and they report the WORK rather than the call.** `lotics run` exits
103
- non-zero when a `run_app_workflow` or `run_app_agent` result's own envelope carries a failed
104
- `status` (`error`/`failed`/`cancelled`, or `not_previewed`: a preview asked for and not given) — any other tool's top-level status is data and exits 0 —
116
+ non-zero when a `run_app_workflow` result's own envelope carries a failed
117
+ `status` (`error`/`failed`/`cancelled`, or `not_previewed`: a dry run asked for and not given) — any other tool's top-level status is data and exits 0 —
105
118
  so `lotics run … && next-step` cannot walk past a refused run; `workspace doctor` exits non-zero on
106
119
  findings. An unrecognized status exits 0 — the list is an allowlist of failure, so a status added
107
120
  later never turns a working script red — and a parked run (`awaiting_input`) is not a failure.
@@ -134,7 +147,7 @@ something exists, read `lotics --help` § COMMANDS — the whole section, not a
134
147
 
135
148
  ## Where this CLI is not the answer
136
149
 
137
- - **Editing an app in a local directory.** An app stated in a model is changed by applying the
138
- model again; its bindings through their `set_app_*` tools; a custom-code app's code by deploying
150
+ - **Editing an app in a local directory.** An app stated as a tree is changed by applying the
151
+ tree again; its bindings through their `set_app_*` tools; a custom-code app's code by deploying
139
152
  its directory again. Nothing reads a local copy of a live app back.
140
153
  - **OAuth connections.** Attaching a connected account is web-only; the CLI can list them.
package/README.md CHANGED
@@ -28,8 +28,11 @@ Per-command contracts, flags, exit codes and gotchas are in
28
28
  The platform's primary surfaces have dedicated usage guides that ship inside this
29
29
  package (reachable at `node_modules/@lotics/cli/docs/*.md` once installed):
30
30
 
31
+ - [`docs/getting_started.md`](docs/getting_started.md) — what a workspace holds and the one page
32
+ to open for each job.
33
+ - [`docs/first_build.md`](docs/first_build.md) — a whole workspace built call by call: which apps, a treatment per kind of row, what the check refuses.
31
34
  - [`docs/building_an_app.md`](docs/building_an_app.md) — building an app end to end: an app
32
- stated in a model and applied with `lotics model apply`, or a custom-code app on
35
+ stated as a tree and written with `set_app`, or a custom-code app on
33
36
  `@lotics/app-sdk`. Read it once before starting an app.
34
37
  - [`docs/document_templates.md`](docs/document_templates.md) — generate finished documents
35
38
  (PDF, Excel, Word, email) by filling reusable templates: the five template types, the
@@ -37,48 +40,52 @@ package (reachable at `node_modules/@lotics/cli/docs/*.md` once installed):
37
40
  - [`docs/migration.md`](docs/migration.md) — what to do when a release changes what the CLI once
38
41
  wrote to disk; read once, when something on disk no longer matches what the CLI does.
39
42
  - [`docs/knowledge_docs.md`](docs/knowledge_docs.md) — the AI's rulebook layer: authoring the
40
- workspace facts an agent can't guess, who can read a doc, and the
41
- catalog-then-stage retrieval model agents use to pull only the lines they need.
43
+ procedures and policies an agent can't guess, who can read a doc, and the
44
+ search-then-read retrieval agents use to pull only the lines they need.
45
+ - [`docs/app_architecture.md`](docs/app_architecture.md) — one factory's split into apps, and
46
+ [`docs/working_in_a_workspace.md`](docs/working_in_a_workspace.md) — the means for each job once they exist.
42
47
 
43
- ## Start in one command
48
+ ## Start in two commands
44
49
 
45
- Install the CLI, write a `model.json` and apply it; `setup` creates the account, applies the model
46
- to its workspace, and prints a one-time sign-in link:
50
+ Install the CLI and create an account; the account's workspace is then built with the tools:
47
51
 
48
52
  ```bash
49
53
  curl -fsSL https://lotics.ai/install.sh | bash
50
- lotics setup model.json --email you@company.com
54
+ lotics auth signup you@company.com
51
55
  ```
52
56
 
53
57
  The installer downloads one compiled executable — no Node.js, no npm: every app is deployed on
54
58
  Lotics. Node 18+ comes in only for a custom-code app, which is built on this machine to deploy.
55
59
 
56
- Add `--json` for one machine-readable object instead of progress — the organization, the
57
- workspace, the app ids, the sign-in link, and any warnings. Already signed in? Drop `--email` and
58
- `lotics setup model.json` applies to the account you have.
59
-
60
60
  ## Describe your workspace
61
61
 
62
- A `model.json` names the tables, fields, options, links, views, roles and first rows, how a row
63
- of each table is recognised, and the apps over them. Complete example models of several trades are
64
- listed at `https://lotics.ai/presets/index.json` (each at `https://lotics.ai/presets/<slug>.json`) —
65
- read the closest one and write your own in your business's words.
62
+ Tables and apps are written by two tools, the same on the CLI and over MCP. `set_tables` takes
63
+ `{ "tables": [...] }` — always a list, all or nothing — each table a document keyed by alias: its fields
64
+ (keyed by alias), options, links, views and how a row is recognised. A link names its table by id, or
65
+ by the `ref` of another table of the same call, and states `multi`; a two-way link states `pair` on
66
+ both tables. A table is edited by an RFC 7396 merge patch of its document, where `null` deletes.
67
+ `set_app` takes one app per call: `{ "body": <the App tree> }` to create, the tree stating the app's `name`; `{ "app_id": …,
68
+ "nodes": { "<address>": <patch> } }` to change one node (the App's own props change through `body`). Both create when
69
+ given no id and edit when given one, and `dry_run` checks without writing. Every answer states the permissions the
70
+ write granted and removed.
71
+
72
+ A new workspace: one `set_tables` call with the tables (at most 50, 200 first rows each, a call), then every `set_app` call, then fixes. Example
73
+ files of several trades are listed at `https://lotics.ai/presets/index.json` (each at
74
+ `https://lotics.ai/presets/<slug>.json`) — read the closest one, write your own in your business's
75
+ words, and pass its tables to `set_tables`.
66
76
 
67
77
  ```bash
68
- lotics docs model # how to write one, with a worked example
69
- lotics setup model.json --email you@company.com # a new account, then the model applied to it
70
- lotics model apply model.json # an account you already have: the tables, then every app
78
+ lotics docs model # the keys, with a worked example
79
+ lotics run set_tables @tables.json # every table of the workspace, in one call
80
+ lotics app apply orders.app.json --check # set_app as a dry run: everything wrong, nothing written
81
+ lotics app apply orders.app.json # set_app: creates the app, or edits the one the file records
71
82
  ```
72
83
 
73
- `model apply` checks the whole file first — every problem at once — then adopts or creates each
74
- table (the table this workspace bound it to, else one of the same label, is adopted and given
75
- what it lacks; no stored value changes), writes the first rows only where every bound table is empty, and mints a new version of
76
- each app the model declares. Change the file and apply it again; `--app <alias>` applies only the
77
- apps named. Rolling an app back (`lotics run rollback_app`) restores its earlier version — table
78
- changes and data writes stay.
84
+ The answer notes the treatments an app leaves unstated that its rows call for; nothing is written into the
85
+ tree for you. Change the file and apply it again; applying an earlier tree again is the undo — table changes
86
+ and data writes stay.
79
87
 
80
- The other direction: `lotics model pull -o model.json` writes this workspace's model as that same
81
- file, rebuilt from what owns each part — its tables, how rows are recognised, and each app's body.
88
+ The other direction: `lotics app pull <app_id>` writes an app's tree as a file.
82
89
 
83
90
  ## Install
84
91
 
@@ -125,7 +132,7 @@ lotics auth login a@b.com --local # pins this directory to that org (implies
125
132
 
126
133
  A command run before you press Confirm names the page and the code again and exits 1; the request is good for 15 minutes, after which the next command says to ask again. Re-running `auth login` is always safe — it replaces the request, so only the newest code is the live one.
127
134
 
128
- **`lotics auth web`** — Send a magic link email to access the web app (requires prior signup or setup).
135
+ **`lotics auth web`** — Send a magic link email to access the web app (requires prior signup).
129
136
 
130
137
  ```bash
131
138
  lotics auth web
@@ -182,7 +189,7 @@ In a custom-code app's directory, `lotics app deploy` derives the credential fro
182
189
 
183
190
  ### Diagnostics
184
191
 
185
- Every request identifies the CLI (`user-agent: lotics-cli/<version> node/<v> <platform>`) and names the command that made it (`x-lotics-cli-command: model.apply`), so a failure in the server's logs can be traced to the verb and version that produced it. Neither header carries arguments: the command chain stops before any id, path, `@file`, or JSON payload. It also names what it can do that an older CLI cannot (`x-lotics-cli-capabilities: docs-fallback`), so the server answers in a form it reads: an error names a page as `lotics docs <path>` to a CLI that declares `docs-fallback`, and as `lotics run docs '{"path":"<path>"}'` to any other.
192
+ Every request identifies the CLI (`user-agent: lotics-cli/<version> node/<v> <platform>`) and names the command that made it (`x-lotics-cli-command: app.apply`), so a failure in the server's logs can be traced to the verb and version that produced it. Neither header carries arguments: the command chain stops before any id, path, `@file`, or JSON payload. It also names what it can do that an older CLI cannot (`x-lotics-cli-capabilities: docs-fallback`), so the server answers in a form it reads: an error names a page as `lotics docs <path>` to a CLI that declares `docs-fallback`, and as `lotics run docs '{"path":"<path>"}'` to any other.
186
193
 
187
194
  **`LOTICS_TELEMETRY=1` additionally records the session.** Off by default. Set it in your shell profile rather than per command — each invocation is its own process. When set:
188
195
 
@@ -255,13 +262,13 @@ lotics tools # list tools by category with descriptions
255
262
  lotics tools query_records # show full description + input schema
256
263
 
257
264
  # Execute
258
- lotics run query_tables '{}'
265
+ lotics run get_workspace '{"kind":"tables"}'
259
266
  lotics run query_records '{"table_id":"tbl_...","field_keys":["name"]}'
260
267
 
261
268
  # Large args (a knowledge-doc `content`, a bulk update) exceed the OS arg limit —
262
269
  # read them from a file or stdin instead of an inline arg:
263
- lotics run create_knowledge @args.json
264
- cat args.json | lotics run create_knowledge - # the trailing - reads stdin
270
+ lotics run set_knowledge @args.json
271
+ cat args.json | lotics run set_knowledge - # the trailing - reads stdin
265
272
  echo '{"table_id":"tbl_..."}' | lotics run query_records -
266
273
 
267
274
  # Upload files (multiple files and directories supported)
@@ -276,10 +283,10 @@ lotics file list --limit 50
276
283
  lotics file delete <file_id> # refused while anything still references it
277
284
 
278
285
  # CI / non-interactive (key inline)
279
- LOTICS_API_KEY=ltk_... lotics run query_tables '{}'
286
+ LOTICS_API_KEY=ltk_... lotics run get_workspace '{}'
280
287
 
281
288
  # One-off against a saved org/workspace, no switching
282
- LOTICS_ORG=acme LOTICS_WORKSPACE=wks_... lotics run query_tables '{}'
289
+ LOTICS_ORG=acme LOTICS_WORKSPACE=wks_... lotics run get_workspace '{}'
283
290
  ```
284
291
 
285
292
  ## Knowledge docs
@@ -298,7 +305,7 @@ lotics knowledge list --deleted # deleted docs you
298
305
  lotics knowledge restore kdc_... [kdc_...] # bring them back, all or none
299
306
  ```
300
307
 
301
- `create` / `update` send the body inline; the server mints and version-chains the content file (and `update` diffs + resolves concurrency internally — no token to pass). `get` is the one content-read path, hydrating the body server-side.
308
+ `create` / `update` are the tool `set_knowledge` (no `knowledge_doc_id` makes a doc, one patches it) and send the body inline; the server mints and version-chains the content file (and `update` diffs + resolves concurrency internally — no token to pass). `get` is the one content-read path, hydrating the body server-side.
302
309
 
303
310
  ## Custom-code apps
304
311
 
@@ -312,14 +319,12 @@ lotics app pull # in the project: bring it up to the
312
319
  # What the app reads and writes is bound on the app, and each change mints a version:
313
320
  lotics run set_app_queries '{"app_id":"app_...","queries":{"openInvoices":{...}}}'
314
321
  lotics run set_app_workflow '{"app_id":"app_...","alias":"issueInvoice","source":"..."}'
315
- lotics run rollback_app '{"app_id":"app_...","version_id":"apv_..."}' # the undo; data stays
316
322
 
317
323
  # Running an app's alias is a TOOL call, like every other tool. Exits non-zero
318
324
  # when the RUN failed, not only when the call did.
319
325
  lotics run run_app_query '{"app_id":"app_abc","alias":"openInvoices","params":{}}'
320
326
  lotics run run_app_workflow '{"app_id":"app_abc","alias":"issueInvoice","inputs":{...}}'
321
327
  lotics run run_app_workflow '{...}' --print-created # the records it created + a cleanup plan
322
- lotics run run_app_agent '{"app_id":"app_abc","alias":"recognize","input":{"image_file_id":"fil_..."}}'
323
328
  ```
324
329
 
325
330
  The app's SDK reference is `node_modules/@lotics/app-sdk/AGENTS.md` inside the project. `lotics tools <name>` prints any tool's input.
@@ -331,7 +336,7 @@ import { LoticsClient } from "@lotics/cli";
331
336
 
332
337
  const client = new LoticsClient({ apiKey: "ltk_..." });
333
338
 
334
- const { result } = await client.execute("query_tables", {});
339
+ const { result } = await client.execute("get_workspace", {});
335
340
  const upload = await client.uploadFiles(["./report.pdf", "./data.csv"]);
336
341
  await client.downloadFile(url, "./output.xlsx");
337
342
  const { tools, categories } = await client.listTools();