@lotics/cli 0.204.0 → 0.205.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 +35 -0
- package/README.md +17 -1
- package/dist/src/cli.js +340 -53
- package/dist/src/client.d.ts +88 -3
- package/dist/src/client.js +63 -13
- package/docs/cli_reference.md +9 -7
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -52,6 +52,34 @@ response there is *not* evidence the subcommand is absent. To find out whether s
|
|
|
52
52
|
code again; once the 15 minutes are up it says to ask again. `lotics setup` falls into the same
|
|
53
53
|
flow by itself when the email it was given already has an account: it stops having created
|
|
54
54
|
nothing, and the SAME command run again carries on.
|
|
55
|
+
- **A credential is either a SIGN-IN or an API KEY, and `logout` treats them differently.** A profile
|
|
56
|
+
from `auth login` / `auth signup` acts as the person who confirmed it and is theirs — `lotics auth
|
|
57
|
+
logout` revokes it server-side, and it lapses on its own after 90 idle days (each use pushes that
|
|
58
|
+
out). A profile from `auth api-key` holds a key an ADMIN issued. A key created in Settings carries
|
|
59
|
+
its OWN access — every app and table, or only the ones chosen on the key, so a listing that comes
|
|
60
|
+
back short is the key's reach, not a bug — while a key created FOR a person carries that
|
|
61
|
+
person's access and dies with their membership. Either is routinely also on a server and on
|
|
62
|
+
other machines, so logout only forgets it locally and says so; only an admin revokes it. A profile that states no kind (saved before the field existed) is resolved against the SERVER
|
|
63
|
+
and revoked only if the answer is a sign-in; a bare `--api-key` / `LOTICS_API_KEY` names no
|
|
64
|
+
profile to remove at all. Nothing is ever revoked on a guess — between two, the destructive one is
|
|
65
|
+
wrong. `lotics auth whoami` prints the kind, asking the server when the store cannot say.
|
|
66
|
+
- **A key created in Settings never administers the organization, whatever its access.** The verbs
|
|
67
|
+
`docs/cli_reference.md` marks *admin only* split in two under a key: the ones that BUILD inside a workspace
|
|
68
|
+
the key reaches — `scaffold apply`, `library init`, `app upgrade`, `workspace doctor`, `scaffold
|
|
69
|
+
export`, `field rename` — run as before, while managing people, sharing or ownership, creating or
|
|
70
|
+
deleting a workspace, changing workspace settings, setting credit limits, reading the access log
|
|
71
|
+
and publishing a starter or an app's API answer `403` and name the remedy: an admin signed in, so
|
|
72
|
+
`lotics auth login <email>` and run it again. A sign-in acts as that person and is refused none of
|
|
73
|
+
them. Do not retry a `403` with the same credential and do not ask for a wider key — no answer on
|
|
74
|
+
the key's own screen grants this.
|
|
75
|
+
- **A 401 names its remedy — act on the hint, do not retry.** "This credential expired / was
|
|
76
|
+
revoked / belongs to a member who is no longer active" carries the one remedy that ends this
|
|
77
|
+
credential: run `lotics auth login <email>` for a sign-in, or ask the admin who issued it for a
|
|
78
|
+
new key. A credential minted before that was recorded carries BOTH, because nothing on the row
|
|
79
|
+
tells them apart — so on a box with no browser, take the second. Only an UNRECOGNIZED key gets
|
|
80
|
+
the generic "Invalid or disabled API key", and that one is generic on purpose, so re-sending it
|
|
81
|
+
teaches nothing. A `reason` rides on the body for a script to branch on, since the code stays
|
|
82
|
+
`unauthorized` for every 401.
|
|
55
83
|
- **Large payloads bypass `ARG_MAX`** — `lotics run <tool> @args.json` or piped stdin. A leading `@` is
|
|
56
84
|
unambiguously a file path (JSON args start with `{`).
|
|
57
85
|
- **stdout is the payload, stderr is the narration.** Progress, status lines, and the target echo go to
|
|
@@ -66,6 +94,13 @@ response there is *not* evidence the subcommand is absent. To find out whether s
|
|
|
66
94
|
so `lotics run … && next-step` cannot walk past a refused run; `workspace doctor` exits non-zero on
|
|
67
95
|
findings. An unrecognized status exits 0 — the list is an allowlist of failure, so a status added
|
|
68
96
|
later never turns a working script red — and a parked run (`awaiting_input`) is not a failure.
|
|
97
|
+
- **An app that PUBLISHES an API turns every later manifest write into a release.** `lotics app api
|
|
98
|
+
publish` snapshots what the app's queries and workflows promise to callers outside it — a
|
|
99
|
+
customer's own site or server, which nobody here can redeploy. From then on an additive change
|
|
100
|
+
re-snapshots silently and a breaking one is REFUSED, naming each change;
|
|
101
|
+
`--acknowledge-breaking-api` (on `app deploy`, `app query set`, `app workflow set`, `app upgrade`)
|
|
102
|
+
is the answer that carries it out and snapshots the break as a new contract version. An app that
|
|
103
|
+
publishes nothing is untouched by any of it.
|
|
69
104
|
- **`--print-created` / `--cleanup` on any call that reports `side_effects`.** The first prints the
|
|
70
105
|
records created plus a paste-ready cleanup plan and what cannot be auto-undone; the second runs
|
|
71
106
|
those deletes (records only — never files, integrations or notifications). Neither is a rollback.
|
package/README.md
CHANGED
|
@@ -124,6 +124,10 @@ The CLI checks for updates once per day and prints a note on stderr, naming the
|
|
|
124
124
|
|
|
125
125
|
## Authentication
|
|
126
126
|
|
|
127
|
+
**Two kinds of credential, and which you hold decides what `logout` does.** `auth signup` / `auth login` give this machine a **sign-in** — it acts as you, carries whatever role you have, and is yours to see and revoke at Settings → Security → *Keys and terminals*; it lapses after 90 days of disuse, and each use pushes that out. `auth api-key` saves an **API key** an admin issued. A key an admin creates in Settings has its own name and its own access, reaching either every app and table or only the ones chosen on the key; a key created FOR a person carries that person's access and stops working when that person is removed. Either kind often lives on a server and on other people's machines too, and only an admin revokes it. `lotics auth whoami` prints which kind this machine holds — from the saved profile, or from the server when the profile does not say.
|
|
128
|
+
|
|
129
|
+
When a credential stops working the refusal says which of the three ways it is dead — "… was revoked." / "… expired." / "… belongs to a member who is no longer active in this organization." — and its `hint` names the remedy: `lotics auth login <email>` for a terminal sign-in, ask an admin for a new key for an API key. A credential whose record does not say which of the two it is gets both. A key the server does not recognize at all gets one generic answer, deliberately: an unrecognized key learns nothing from being refused.
|
|
130
|
+
|
|
127
131
|
**`lotics auth signup`** — Creates a new Lotics account, organization, workspace, and API key in one step. Sends a magic link email so you can access the web app.
|
|
128
132
|
|
|
129
133
|
```bash
|
|
@@ -157,7 +161,7 @@ lotics auth api-key # interactive prompt
|
|
|
157
161
|
lotics auth api-key ltk_... # registers the key's org as a profile (now active)
|
|
158
162
|
```
|
|
159
163
|
|
|
160
|
-
Run `lotics auth logout [<name|id>]` to remove a profile (default: the active org), or `lotics auth logout --all` to wipe the store. Inside a pinned directory the bare form removes the **pin**, not a profile — name the org to remove its credential.
|
|
164
|
+
Run `lotics auth logout [<name|id>]` to remove a profile (default: the active org), or `lotics auth logout --all` to wipe the store. Inside a pinned directory the bare form removes the **pin**, not a profile — name the org to remove its credential. A profile saved by `auth login` / `auth signup` is a **sign-in**, and logging out revokes it server-side too. One saved by `auth api-key` is an admin-issued key that other machines may also hold, so it is only removed from this machine and stays active until an admin revokes it under Settings → API keys. A profile saved before the kind was recorded states nothing, so the server is asked and the credential is revoked only if the answer is a sign-in.
|
|
161
165
|
|
|
162
166
|
## Organizations
|
|
163
167
|
|
|
@@ -349,6 +353,18 @@ lotics app versions app_... # ...for any app, without pulling it
|
|
|
349
353
|
lotics app upgrade # the app this directory's manifest names
|
|
350
354
|
lotics app upgrade app_... # ...for any app, without pulling it first
|
|
351
355
|
|
|
356
|
+
# The app's API: what its declared queries and workflows promise to a caller
|
|
357
|
+
# OUTSIDE the app — a customer's own site or server. Publishing snapshots that
|
|
358
|
+
# promise as a numbered contract; from then on a manifest write that would break
|
|
359
|
+
# it is refused and every breaking change is named, unless the write carries
|
|
360
|
+
# --acknowledge-breaking-api (app deploy / app query set / app workflow set /
|
|
361
|
+
# app upgrade). A query that does not name the columns it returns is refused at
|
|
362
|
+
# publish: those field names are the table's, not the app's to promise.
|
|
363
|
+
lotics app api publish # snapshot the contract; prints the version + warnings
|
|
364
|
+
lotics app api status # is one published, and which version callers hold
|
|
365
|
+
lotics app api spec -o api.openapi.json # the OpenAPI 3.1 document, for the consumer's generator
|
|
366
|
+
lotics app api unpublish # end the promise
|
|
367
|
+
|
|
352
368
|
# Regenerate .lotics/* WITHOUT a deploy: the .d.ts type companions (always) +
|
|
353
369
|
# the runtime app_fields.ts (when authenticated) — F/OPT maps that address
|
|
354
370
|
# fields + select options by stable display-name aliases instead of opaque ids.
|