@lotics/cli 0.315.17 → 0.316.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +37 -24
- package/README.md +42 -37
- package/dist/src/cli.js +27215 -48999
- package/dist/src/client.d.ts +12 -88
- package/dist/src/client.js +10 -74
- package/dist/src/invocation.d.ts +1 -1
- package/docs/agent_surface.md +121 -114
- package/docs/app_architecture.md +39 -0
- package/docs/app_bindings.md +24 -62
- package/docs/building_an_app.md +97 -81
- package/docs/cli_reference.md +18 -19
- package/docs/data_model.md +129 -183
- package/docs/design.md +156 -170
- package/docs/document_templates.md +125 -99
- package/docs/examples.md +1599 -1238
- package/docs/field_values.md +14 -11
- package/docs/filters.md +47 -9
- package/docs/first_build.md +180 -0
- package/docs/getting_started.md +15 -0
- package/docs/knowledge_docs.md +73 -209
- package/docs/migration.md +22 -26
- package/docs/workflow_steps.md +22 -579
- package/docs/workflows.md +407 -208
- package/docs/working_in_a_workspace.md +60 -0
- package/package.json +1 -1
package/docs/knowledge_docs.md
CHANGED
|
@@ -1,228 +1,109 @@
|
|
|
1
1
|
# Knowledge Docs
|
|
2
2
|
|
|
3
|
-
Knowledge docs are the
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
Knowledge docs are the workspace's **rulebook layer** — the facts and rules an agent can't know on its own: a
|
|
4
|
+
procedure, a policy, a glossary of in-house terms, a tariff book. You write them once; the agent **searches and reads
|
|
5
|
+
them on demand** while it works, pulling in only the lines it needs. They are not injected wholesale, so a 10,000-line
|
|
6
|
+
tariff costs nothing until a question touches it.
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
question actually touches it, and a 10MB one is no different.
|
|
11
|
-
|
|
12
|
-
This is a **capability + usage** guide. For the exact input schema of any tool named here, run
|
|
13
|
-
`lotics tools <tool_name>`.
|
|
8
|
+
A menu with its prices, the customer list and the open orders are not knowledge: they are rows of tables, so apps, queries and documents
|
|
9
|
+
can use them.
|
|
14
10
|
|
|
15
11
|
## Rulebook, not methodology
|
|
16
12
|
|
|
17
|
-
Put in a knowledge doc the things the model **cannot guess**: your specific numbers, codes,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
the doc, the doc is noise.
|
|
21
|
-
|
|
22
|
-
## Creating a doc — `lotics knowledge create`
|
|
13
|
+
Put in a knowledge doc the things the model **cannot guess**: your specific numbers, codes, names, exceptions and
|
|
14
|
+
policies. Do **not** put in it general skills the model already has ("how to write a polite email"). If the agent would
|
|
15
|
+
get it right without the doc, the doc is noise.
|
|
23
16
|
|
|
24
|
-
|
|
25
|
-
lotics knowledge create --name "Shipping tariffs" \
|
|
26
|
-
--description "HS-coded rates; searchable by lane and code" \
|
|
27
|
-
--tags "HS,nhập khẩu" \ # file it as you make it — see Classifying, below
|
|
28
|
-
--from ./tariffs.md # the body is a Markdown file; or --content '<inline>'
|
|
29
|
-
```
|
|
17
|
+
## Writing a doc — `set_knowledge`
|
|
30
18
|
|
|
31
|
-
|
|
32
|
-
(prints the new id). A raw `lotics run create_knowledge @doc.json` works too — read a large
|
|
33
|
-
`content` from a file or stdin. `create_knowledge` takes five fields, three of them required:
|
|
19
|
+
`set_knowledge` creates a doc when it is given no `knowledge_doc_id` and changes the named one when it is given one:
|
|
34
20
|
|
|
35
|
-
- `name` — what it is. Just the name: **grouping belongs in `tags`, not in a prefix baked into
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
an ambiguous query would use. Surfaced in the tree before any body is read, and truncated at
|
|
39
|
-
200 characters. See *Write for grep* below.
|
|
21
|
+
- `name` — what it is. Just the name: **grouping belongs in `tags`, not in a prefix baked into every title.**
|
|
22
|
+
- `description` — what the doc is **and what to grep it for**: its vocabulary and the synonyms an ambiguous query would
|
|
23
|
+
use. Surfaced in the listing before any body is read, and truncated at 200 characters.
|
|
40
24
|
- `content` — Markdown.
|
|
41
|
-
- `tags` *(optional)* — the labels someone would filter by, e.g. `["Hồ sơ NOXH", "Khoản 13"]`.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
- `files` *(optional)* — file ids of the source `.docx`/`.pdf`/`.xlsx` the doc was built from,
|
|
46
|
-
stored alongside it so a reader can open the original. The body stays the searchable text.
|
|
47
|
-
|
|
48
|
-
A new doc is created **owned by you, active in your own agent context, and private** — no one
|
|
49
|
-
else can see it yet. Changing a doc's default-active state is done through the web app / REST
|
|
50
|
-
surface, not this tool.
|
|
51
|
-
|
|
52
|
-
## Access
|
|
25
|
+
- `tags` *(optional)* — the labels someone would filter by, e.g. `["Hồ sơ NOXH", "Khoản 13"]`. Give **every** one that is
|
|
26
|
+
true of the doc: a corpus is narrowed by intersecting tags, so a doc carrying one label is found down one path only.
|
|
27
|
+
On a change the array **replaces** what is stored, so resend the labels it should keep.
|
|
28
|
+
- `files` *(optional)* — file ids of the source `.docx`/`.pdf`/`.xlsx`, stored alongside so a reader can open the original.
|
|
53
29
|
|
|
54
|
-
A
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
exception: they read a doc only once it is shared with them, or once they share it with
|
|
58
|
-
themselves, which the audit log records. An API key acting as itself keeps the access set on the
|
|
59
|
-
key.
|
|
30
|
+
A change sends only the fields it changes. `edits` (anchored replace, insert, append) makes a surgical change to the
|
|
31
|
+
body. Refine structure as you learn what users ask: add the synonym that failed to match, split a line that was too
|
|
32
|
+
coarse, restate a term the heading was carrying.
|
|
60
33
|
|
|
61
|
-
|
|
34
|
+
A new doc is **owned by you and private**. `set_access` shares it: `resources[]` with `resource_type` `knowledge_doc`, and `principals[]` (a
|
|
35
|
+
member, a member group, or `organization` for everyone), each with a `role` of `user` or `manager`; a principal without a `role` has
|
|
36
|
+
its access taken away. A doc reaches an agent only when the member can `use` it, an organization admin included.
|
|
62
37
|
|
|
63
|
-
|
|
64
|
-
verbs respect access, so only docs the caller may use ever surface.
|
|
38
|
+
## How an agent uses a doc
|
|
65
39
|
|
|
66
|
-
|
|
67
|
-
description; `tag` narrows it. No bodies.
|
|
68
|
-
2. **`grep_knowledge`** — `grep -rn`. Match across every readable doc (or one doc, or one
|
|
69
|
-
tag), returning **doc, line number, and the matching line**. It runs inside Postgres,
|
|
70
|
-
so only matching lines cross the wire.
|
|
71
|
-
3. **`read_knowledge`** — `cat` / `sed -n 'X,Yp'`. Read a doc whole or by line range, to see
|
|
72
|
-
the context around a hit.
|
|
40
|
+
Retrieval works like a filesystem, and respects access: only docs the caller may use ever surface.
|
|
73
41
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
`
|
|
42
|
+
1. **List and search** — `get_workspace` kind `knowledge` lists the corpus (id, name, tags, a truncated
|
|
43
|
+
description); a search term matches a doc's name, description and tags. `get_workspace` with `search` finds where something is said: it
|
|
44
|
+
matches across every readable doc and returns the **doc, line number and matching line**;
|
|
45
|
+
`knowledge_doc_id` or `tag` confines the lines to one doc or to the docs carrying that tag.
|
|
46
|
+
2. **Read** — `read_knowledge`, a doc whole or by line range, to see the context around a hit.
|
|
78
47
|
|
|
79
|
-
|
|
48
|
+
Matching is **not ranked**: the *agent* does the narrowing. A distinctive phrase is sharply selective, a whole question
|
|
49
|
+
matches everything. A search always reports `total_matches`, so "too broad" is visible and cheap to fix.
|
|
80
50
|
|
|
81
|
-
`
|
|
82
|
-
a
|
|
51
|
+
The `search` is **literal text** — every character matches itself. Set `regex: true` to read it as a POSIX regular
|
|
52
|
+
expression (a word boundary is `\y`, not `\b`):
|
|
83
53
|
|
|
84
54
|
```
|
|
85
|
-
|
|
86
|
-
|
|
55
|
+
{ "search": "C/O (Form E)", "kind": "knowledge" }
|
|
56
|
+
{ "search": "\\yNK\\y", "kind": "knowledge", "regex": true, "case_sensitive": true }
|
|
87
57
|
```
|
|
88
58
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
ran and what to pass instead. That last part is **measured, not guessed** — an empty result tells
|
|
95
|
-
you whether reading the pattern as an expression would have matched, so an alternation sent without
|
|
96
|
-
the flag (`phrase A|phrase B`) comes back naming `regex: true` rather than advising you to shorten a
|
|
97
|
-
pattern that was never too broad.
|
|
98
|
-
|
|
99
|
-
### Matching options
|
|
100
|
-
|
|
101
|
-
- **Tone marks match exactly by default.** `diacritic_insensitive: true` folds them, so `ca phe`
|
|
102
|
-
matches `cà phê` — reach for it when the pattern was typed without them, not by habit: folding
|
|
103
|
-
strips the pattern to ASCII, where a short Vietnamese word matches inside unrelated words
|
|
104
|
-
(`mã` finds `manifest`). An empty result tells you when folding would have matched.
|
|
105
|
-
- **Case folds by default**, independently of diacritics. `case_sensitive: true` matches case
|
|
106
|
-
exactly — useful for an acronym (`NK` vs `nk`) that a folded search would blur.
|
|
107
|
-
- **Whitespace is normalized on both sides.** A body converted from PDF, Word or Excel carries
|
|
108
|
-
non-breaking spaces, soft hyphens, zero-width marks and padded runs that nobody types into a
|
|
109
|
-
query; those fold to ordinary single spaces before matching, so a correct search does not return
|
|
110
|
-
a silent zero on text that is present. A literal pattern is normalized the same way; an
|
|
111
|
-
expression is left byte-exact, since collapsing its whitespace would rewrite it.
|
|
112
|
-
- **What `regex: true` supports**: quantifiers, character classes, alternation, anchors,
|
|
113
|
-
backreferences, non-greedy forms, `(?i)`, and both lookahead and lookbehind. A word boundary
|
|
114
|
-
is **`\y`**, not `\b` — Postgres spells it differently, and `\b` is rewritten for you rather
|
|
115
|
-
than silently matching nothing. Named groups and `\p{…}` are likewise rewritten to their POSIX
|
|
116
|
-
equivalents. A `\p{…}` with no POSIX equivalent, and a malformed expression, are both refused
|
|
117
|
-
with the reason.
|
|
118
|
-
|
|
119
|
-
Where an expression cannot express the question at all — a value that must be computed, a
|
|
120
|
-
layout matching cannot address — stage the doc into a code run instead (`code_exec`, in chat or an app agent, with
|
|
121
|
-
`knowledge_doc_ids` puts it at `inputs/knowledge/<id>.md` as a real file).
|
|
122
|
-
|
|
123
|
-
### What a result is bounded by
|
|
124
|
-
|
|
125
|
-
A result carries at most 40.000 characters. Matched lines are admitted first and context fills
|
|
126
|
-
what remains, so an answer is never dropped to make room for a neighbouring line. Anything the
|
|
127
|
-
budget cut is REPORTED — `chars_elided_matches` (an answer was dropped) and
|
|
128
|
-
`context_omitted_matches` (an answer was kept without the context you asked for) mean different
|
|
129
|
-
things and call for different fixes: narrow the pattern, or ask for fewer `context_lines`.
|
|
130
|
-
Individual lines longer than 600 characters are clipped and marked, with `read_knowledge` giving
|
|
131
|
-
the rest.
|
|
132
|
-
|
|
133
|
-
`total_matches` is always the true total, even when fewer are shown.
|
|
134
|
-
|
|
135
|
-
## Write for grep — the rules that decide whether an answer is findable
|
|
136
|
-
|
|
137
|
-
Retrieval addresses **lines**. Every rule below follows from that one fact.
|
|
138
|
-
|
|
139
|
-
- **One self-contained fact per line.** A grep hit returns *that line*. For dense or tabular
|
|
140
|
-
data — a price row, a tariff code, a charge entry — put the whole record on one line.
|
|
141
|
-
- **Repeat the searchable terms on every line; headings do not carry down.** A line reading
|
|
142
|
-
`Rate: 15%` under a heading `Roasted coffee` will never match a search for `coffee`. Restate
|
|
143
|
-
the identifying terms inline, even when it reads redundantly to a human. This is the single
|
|
144
|
-
rule most often got wrong.
|
|
145
|
-
- **Keep a line under ~600 characters.** Past that the line is truncated in the agent's view
|
|
146
|
-
and marked as cut; the agent can still `read_knowledge` for the rest, but it costs a round
|
|
147
|
-
trip. Put the identifying terms early and the long tail late.
|
|
148
|
-
- **Put synonyms and translations on the line itself.** A bilingual row (`Cà phê, đã rang /
|
|
149
|
-
Coffee, roasted`) matches queries in either language for free. The same trick carries
|
|
150
|
-
colloquial terms next to official ones.
|
|
151
|
-
- **For prose, keep a rule and its exception close.** A hit returns one line, so a rule on line
|
|
152
|
-
40 and its exception on line 90 can be retrieved apart. Use `context_lines` when reading, and
|
|
153
|
-
keep related clauses adjacent when writing.
|
|
154
|
-
|
|
155
|
-
Markdown headings are ordinary text — useful for a human (a doc's `##` headings outside its
|
|
156
|
-
blocks, two or more, are listed on its page as its sections) and for orienting a
|
|
157
|
-
`read_knowledge`, but they carry no retrieval weight of their own.
|
|
158
|
-
|
|
159
|
-
**The description is the discovery hint.** It is what the agent sees in the tree before it has
|
|
160
|
-
read a byte of the body, so it is the only clue for *what term to grep for*. Write it to name
|
|
161
|
-
the doc's vocabulary — the words that actually appear inside it. Keep it to a sentence: it is
|
|
162
|
-
truncated at 200 characters, and a keyword-stuffed description is cut, not rewarded.
|
|
163
|
-
|
|
164
|
-
## Updating a doc — `lotics knowledge update`
|
|
165
|
-
|
|
166
|
-
```bash
|
|
167
|
-
lotics knowledge update kdc_... --from ./tariffs.md # replace the body (--name / --description too)
|
|
168
|
-
```
|
|
59
|
+
As an expression `C/O (Form E)` would search for `C/O Form E`, which is not in the document, and return a confident
|
|
60
|
+
zero; the literal default has no such failure. With `regex` omitted, a literal search that finds nothing while the
|
|
61
|
+
pattern, read as an expression, matches (`a|b`, the commonest) returns those lines under a note saying how they were
|
|
62
|
+
read. `regex: false` keeps the literal zero; a search that finds nothing either
|
|
63
|
+
way says so.
|
|
169
64
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
structure as you learn what users actually ask: add the synonym that failed to match, split a
|
|
176
|
-
line that was too coarse, restate a term the heading was carrying.
|
|
65
|
+
- **Tone marks match exactly by default.** `diacritic_insensitive: true` folds them (`ca phe` matches `cà phê`); use it
|
|
66
|
+
when the pattern was typed without them, since folding lets a short word match inside unrelated ones.
|
|
67
|
+
- **Case folds by default.** `case_sensitive: true` matches exactly, for an acronym (`NK` vs `nk`).
|
|
68
|
+
- **Whitespace is normalized on both sides.** Non-breaking spaces, soft hyphens and padded runs from PDF, Word or Excel
|
|
69
|
+
bodies fold to single spaces before matching.
|
|
177
70
|
|
|
178
|
-
|
|
71
|
+
A search shows at most 16,000 characters, shared by what it finds in knowledge, in structure and in records. Matched
|
|
72
|
+
lines are admitted first and context fills what remains; anything cut is reported, with the true number of matching
|
|
73
|
+
lines. Lines longer than 600 characters are clipped and marked; `read_knowledge` gives the rest.
|
|
179
74
|
|
|
180
|
-
|
|
181
|
-
the vocabulary is whatever the docs themselves use — a tag stops existing the moment nothing
|
|
182
|
-
carries it.
|
|
75
|
+
## Write for grep
|
|
183
76
|
|
|
184
|
-
|
|
185
|
-
lotics knowledge update kdc_... --tags "HS,nhập khẩu" # ONE doc: state its complete set
|
|
186
|
-
lotics knowledge tag kdc_a kdc_b --add HS --remove draft # MANY docs: a diff applied to each
|
|
187
|
-
```
|
|
77
|
+
Retrieval addresses **lines**. Every rule follows from that one fact.
|
|
188
78
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
79
|
+
- **One self-contained fact per line.** A hit returns *that line*. For dense or tabular data — a price row, a tariff
|
|
80
|
+
code — put the whole record on one line.
|
|
81
|
+
- **Repeat the searchable terms on every line; headings do not carry down.** A line reading `Rate: 15%` under a heading
|
|
82
|
+
`Roasted coffee` will never match a search for `coffee`. Restate the identifying terms inline, even when it reads
|
|
83
|
+
redundantly to a human. This is the rule most often got wrong.
|
|
84
|
+
- **Keep a line under ~600 characters,** the identifying terms early and the long tail late.
|
|
85
|
+
- **Put synonyms and translations on the line itself.** A bilingual row (`Cà phê, đã rang / Coffee, roasted`) matches
|
|
86
|
+
queries in either language.
|
|
87
|
+
- **For prose, keep a rule and its exception close.** A rule on line 40 and its exception on line 90 can be retrieved apart.
|
|
193
88
|
|
|
194
|
-
|
|
89
|
+
Markdown headings carry no retrieval weight of their own; a doc's `##` headings outside its blocks, two or more, are
|
|
90
|
+
listed on its page as its sections.
|
|
195
91
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
lotics tools grep_knowledge # same
|
|
199
|
-
```
|
|
92
|
+
The **description is the discovery hint**: it is the only clue for *what term to grep for* before a body is read. Name
|
|
93
|
+
the doc's vocabulary in a sentence.
|
|
200
94
|
|
|
201
|
-
##
|
|
202
|
-
|
|
203
|
-
```bash
|
|
204
|
-
lotics knowledge hide kdc_... # superseded, draft, source material
|
|
205
|
-
lotics knowledge list --include-hidden # find it again
|
|
206
|
-
lotics knowledge unhide kdc_... # put it back
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
A hidden doc is out of every **listing**: it is gone from the Library's list, from
|
|
210
|
-
`list_knowledge`, and from the corpus `grep_knowledge` searches, so nothing finds it by browsing.
|
|
211
|
-
It is not deleted, not unshared, and still **reads when addressed by id** — `read_knowledge` with
|
|
212
|
-
its id, a code run staging it, an app agent that declares it. That is the point: hiding is a
|
|
213
|
-
statement about discovery, so it cannot silently break an app that depends on a doc by name.
|
|
95
|
+
## Classifying a corpus — tags
|
|
214
96
|
|
|
215
|
-
|
|
216
|
-
|
|
97
|
+
A doc carries a SET of labels, not a folder. Order does not matter, a doc can wear several, and the vocabulary is
|
|
98
|
+
whatever the docs themselves use. `tags` on `set_knowledge` states one doc's complete set.
|
|
217
99
|
|
|
218
100
|
## Deleting and restoring
|
|
219
101
|
|
|
220
|
-
`
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
owner. A doc that an app or workflow still names cannot be deleted.
|
|
102
|
+
`delete_knowledge` deletes docs: they leave every listing, search and read. **Their sharing and version history are
|
|
103
|
+
kept**, so a deleted doc is recoverable. `get_workspace` kind `knowledge` with `include_archived: true` lists the deleted
|
|
104
|
+
docs you manage, and `restore_knowledge` brings them back with the access they had. Both take many ids and are all or
|
|
105
|
+
none: every id must be a doc you manage, or nothing changes. A doc with no owner is restored only by an admin, who
|
|
106
|
+
becomes its owner. A doc that an app or workflow still names cannot be deleted.
|
|
226
107
|
|
|
227
108
|
## Formatting — what a doc draws
|
|
228
109
|
|
|
@@ -242,20 +123,3 @@ A doc is markdown with GFM tables. Beyond that it draws a few blocks, each in sy
|
|
|
242
123
|
Each tag stands on a line of its own, and a tag line inside a fenced code block is code. Attributes are text in double quotes or a number in braces; nothing in a tag runs. A write that adds a tag that does not close, nests wrongly, carries an attribute the tag does not take, or names a component this list lacks (`<Frame>`, `<CodeGroup>`) is refused with the lines to fix; lowercase HTML (`<br>`) stays text.
|
|
243
124
|
|
|
244
125
|
A chart's numbers live in its mermaid source, which agents read and grep like any text: write them there once, not again in a table.
|
|
245
|
-
|
|
246
|
-
## Reaching the tools
|
|
247
|
-
|
|
248
|
-
```bash
|
|
249
|
-
lotics knowledge list # catalog: id, name, tags, description
|
|
250
|
-
lotics knowledge get kdc_... -o doc.md # read a body to a file (omit -o for stdout)
|
|
251
|
-
lotics tools update_knowledge # full input schema for any knowledge tool
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
The Knowledge category covers `list_knowledge`, `create_knowledge`, `update_knowledge`,
|
|
255
|
-
`delete_knowledge` and `restore_knowledge` — fronted by the `lotics knowledge list | create | get |
|
|
256
|
-
update | tag | hide | unhide | rm | restore` commands, and all but `delete_knowledge` and
|
|
257
|
-
`restore_knowledge` reachable over MCP as well, so a corpus can be
|
|
258
|
-
authored from whichever surface you already work in. `list` (without `--deleted`), `tag`, `hide` and `unhide` go over REST rather than a tool, because
|
|
259
|
-
they are a person's view of the corpus: the tools answer what the ASSISTANT may browse, and a
|
|
260
|
-
hidden doc is out of that set by definition. Sharing a doc to other members is `share_resource` / `unshare_resource` on the
|
|
261
|
-
CLI or in chat (category **Admin**).
|
package/docs/migration.md
CHANGED
|
@@ -6,54 +6,50 @@ already on disk no longer matches what the CLI does.
|
|
|
6
6
|
|
|
7
7
|
## Local app projects are gone
|
|
8
8
|
|
|
9
|
-
An app
|
|
10
|
-
each change mints a new version of it, and
|
|
9
|
+
An app stated as a tree no longer lives in a directory. The live app is the only edit surface:
|
|
10
|
+
each change mints a new version of it, and applying the earlier tree again is the undo. What
|
|
11
11
|
the app is — its screens (`app.json`), its queries, workflows, agents and capabilities, and the
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
tree it was compiled from — is held by that version, and the tables, fields, options, templates and
|
|
13
|
+
roles are the workspace's own.
|
|
14
14
|
|
|
15
15
|
| What you ran | What replaces it |
|
|
16
16
|
|---|---|
|
|
17
|
-
| `lotics scaffold check` + `scaffold apply
|
|
18
|
-
| `lotics
|
|
19
|
-
| `lotics app
|
|
20
|
-
| `lotics
|
|
21
|
-
| `lotics scaffold
|
|
22
|
-
| `lotics scaffold export` | `lotics model pull [-o <model.json>]` — the workspace's model, rebuilt from what owns each part |
|
|
17
|
+
| `lotics scaffold check` + `scaffold apply`, `lotics workspace build <model.json>`, `lotics setup <file>` | `lotics run set_tables` with the tables of the workspace in one list (at most 50 a call), then `set_app` for each app (`lotics app apply <file>`); `dry_run` checks and writes nothing |
|
|
18
|
+
| `lotics app create --from <model.json>#<app>` | `lotics app apply <file>` — `set_app` creates the app from its tree |
|
|
19
|
+
| `lotics app regenerate` | change the tree, then `lotics app apply <file>` |
|
|
20
|
+
| `lotics scaffold diff` | `lotics app apply <file> --check` — what would refuse the tree, writing nothing |
|
|
21
|
+
| `lotics scaffold export` | `lotics app pull <app_id> [path]` — the app's tree as JSON, one app at a time |
|
|
23
22
|
| `lotics app codegen`, `app check`, `app dev`, `app preview` | nothing local: read an app with `lotics run get_app`, and change it through its tools |
|
|
24
|
-
| `lotics app workflow set` / `app query set`
|
|
25
|
-
| `lotics app versions` + a redeploy of an old tree |
|
|
26
|
-
| `lotics app rename`, `app subdomain`, `package.json#lotics.capabilities` | `lotics run
|
|
23
|
+
| `lotics app workflow set` / `app query set` | `lotics run set_app_workflow` / `set_app_queries` — each mints a version |
|
|
24
|
+
| `lotics app versions` + a redeploy of an old tree | apply the earlier tree again (`lotics app apply <file>`), or deploy the earlier source; table changes and data writes stay |
|
|
25
|
+
| `lotics app rename`, `app subdomain`, `package.json#lotics.capabilities` | `lotics run set_app` with the app's id (`public_subdomain`, `capabilities`; its name is the tree's `name`) |
|
|
27
26
|
| `lotics app api publish` / `unpublish` | `lotics run publish_app_api` / `unpublish_app_api` |
|
|
28
|
-
| `lotics field rename` | `lotics run
|
|
27
|
+
| `lotics field rename` | `lotics run set_tables` with a merge patch of the table's document |
|
|
29
28
|
| `lotics app kit` | nothing: a custom-code app depends on `@lotics/app-sdk` (below) |
|
|
30
29
|
| `@lotics/xlsx` / `@lotics/docx` to build a template's file | any `.xlsx` / `.docx` library, then `lotics upload` (`lotics docs document_templates`) |
|
|
31
30
|
| `lotics file preview` | `lotics file download <fil_id>`, then open it |
|
|
32
|
-
| `
|
|
33
|
-
| `lotics library
|
|
34
|
-
| `model.json#from` (with `variants`, `rename`) | state every table under `entities` — a model carrying `from` is refused |
|
|
35
|
-
| `lotics library init <apg_id>`, `lotics setup <apg_id>`, `lotics app upgrade`, `lotics library fixtures` | nothing copies a package any more: write a `model.json` (`lotics docs model`), then `lotics setup model.json` or `lotics model apply model.json` |
|
|
31
|
+
| `lotics library list` / `library show <slug>`, `lotics preset list` / `preset show <slug>` | the example files at `https://lotics.ai/presets/index.json`, each read and its tables passed to `set_tables` |
|
|
32
|
+
| `lotics library init <apg_id>`, `lotics app upgrade`, `lotics library fixtures` | nothing copies a package any more: state the tables (`lotics docs model`) and pass them to `set_tables` |
|
|
36
33
|
|
|
37
34
|
`lotics tools` lists every tool, and `lotics tools <name>` prints its input.
|
|
38
35
|
|
|
39
|
-
**An existing JSON app moves
|
|
40
|
-
apply
|
|
41
|
-
|
|
42
|
-
with `plan`, `queries` or `workflows`) is no longer read by anything; keep the model file, delete the
|
|
36
|
+
**An existing JSON app moves with `lotics app pull <app_id>`**: it writes the app's tree, and
|
|
37
|
+
`lotics app apply` of that file edits the app and mints its next version. A directory an earlier CLI wrote (`app.json`, `src/workflows/`, `.lotics/`, `package.json#lotics`
|
|
38
|
+
with `plan`, `queries` or `workflows`) is no longer read by anything; keep the pulled tree, delete the
|
|
43
39
|
rest.
|
|
44
40
|
|
|
45
41
|
**Authored workflow bodies** an act names (`workflow` on an act) are the live workflow's own body:
|
|
46
|
-
|
|
42
|
+
`lotics run set_app_workflow` changes it.
|
|
47
43
|
|
|
48
|
-
**A
|
|
49
|
-
picture shows no initials: state `party` (`person` or `organization`)
|
|
44
|
+
**A table written before `party`** draws its people and organisations as things — a row with no
|
|
45
|
+
picture shows no initials: state `party` (`person` or `organization`) in that table's `records`.
|
|
50
46
|
|
|
51
47
|
## Custom-code apps use `@lotics/app-sdk`
|
|
52
48
|
|
|
53
49
|
A hand-written app depends on `@lotics/app-sdk` alone — the hooks (`useQuery`, `useWorkflow`, …),
|
|
54
50
|
`mount`, and `AppRouter` from `@lotics/app-sdk/router` — and draws with its own React.
|
|
55
51
|
`@lotics/app-runtime` and `@lotics/ui` are no longer published: the runtime is what the platform
|
|
56
|
-
draws
|
|
52
|
+
draws an app with, and it ships with the platform.
|
|
57
53
|
|
|
58
54
|
An app that listed `@lotics/app-runtime`:
|
|
59
55
|
|