@formlm/cli 0.3.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +326 -65
- package/dist/commands/app.d.ts.map +1 -1
- package/dist/commands/app.js +74 -16
- package/dist/commands/app.js.map +1 -1
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +186 -7
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/connect.js +3 -3
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/doctor.d.ts +11 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +109 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/expert.d.ts.map +1 -1
- package/dist/commands/expert.js +42 -18
- package/dist/commands/expert.js.map +1 -1
- package/dist/commands/field.d.ts.map +1 -1
- package/dist/commands/field.js +9 -11
- package/dist/commands/field.js.map +1 -1
- package/dist/commands/profile.js +1 -1
- package/dist/commands/profile.js.map +1 -1
- package/dist/commands/report.d.ts.map +1 -1
- package/dist/commands/report.js +39 -12
- package/dist/commands/report.js.map +1 -1
- package/dist/commands/scale.d.ts.map +1 -1
- package/dist/commands/scale.js +4 -1
- package/dist/commands/scale.js.map +1 -1
- package/dist/commands/share.d.ts.map +1 -1
- package/dist/commands/share.js +258 -28
- package/dist/commands/share.js.map +1 -1
- package/dist/commands/skill.d.ts.map +1 -1
- package/dist/commands/skill.js +2 -3
- package/dist/commands/skill.js.map +1 -1
- package/dist/commands/smart.d.ts.map +1 -1
- package/dist/commands/smart.js +337 -59
- package/dist/commands/smart.js.map +1 -1
- package/dist/commands/snapshot.d.ts +0 -11
- package/dist/commands/snapshot.d.ts.map +1 -1
- package/dist/commands/snapshot.js +168 -42
- package/dist/commands/snapshot.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/doctor.d.ts +51 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +202 -0
- package/dist/doctor.js.map +1 -0
- package/dist/exec.d.ts +39 -1
- package/dist/exec.d.ts.map +1 -1
- package/dist/exec.js +309 -4
- package/dist/exec.js.map +1 -1
- package/dist/index.js +55 -6
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +283 -67
- package/dist/mcp.js.map +1 -1
- package/dist/output.d.ts +23 -1
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +69 -7
- package/dist/output.js.map +1 -1
- package/dist/summary.d.ts +17 -0
- package/dist/summary.d.ts.map +1 -0
- package/dist/summary.js +64 -0
- package/dist/summary.js.map +1 -0
- package/dist/utils.d.ts +10 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +45 -6
- package/dist/utils.js.map +1 -1
- package/package.json +11 -2
package/README.md
CHANGED
|
@@ -20,6 +20,28 @@ With `formlm-cli`, you can control FormLM directly from your terminal or plug it
|
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
23
|
+
## What's New in v0.5.0
|
|
24
|
+
|
|
25
|
+
Hardening round driven by real agent field reports (batch runs of 50 apps), plus a second pass that re-checked every reported item against the code and machine-verified all documented commands.
|
|
26
|
+
|
|
27
|
+
- **`share publish` now defaults to anonymous access** (`--access visitor`) and exposes `--access / --perm / --days / --no-style`; a new `share set` subcommand passes the raw server parameters through, so "anyone + permanent" no longer requires calling the internal API. Previously publish was hard-wired to `form-type all`, which **requires login** — anonymous respondents got the login page.
|
|
28
|
+
- **`expert config --enable` no longer self-destructs**: the value is forwarded space-separated (`--enable true`) and the server accepts it again. Before, `--enable=true` was rejected as an unknown option, the whole command was discarded, yet the envelope still reported success.
|
|
29
|
+
- **Parameter errors are no longer reported as success**: `picocli` validation failures now map to `code != 0` / `ok:false` instead of hiding the error text inside `data` with `code:0`.
|
|
30
|
+
- **Uniform machine output**: `snapshot` and `auth status` now honour `--json`/`FORMLM_JSON=1` with the same `{ok,code,message,data}` envelope as everything else, and human guidance lines moved to stderr, so stdout is a single parseable line.
|
|
31
|
+
- **`app remove` is a real alias of `app delete`**; `app list` gained `--all / --limit / --page / --with-urls`; `app urls` returns `shareToken`, `published`, `shareType/Perm/Day` and absolute https URLs.
|
|
32
|
+
- **New `doctor` command** (and MCP `formlm_doctor` tool): one read-only call per app covering scoring coverage, dead/empty experts, styling, unexpected certificate pages, language consistency (`--expect-lang`, `--deep` scans widget text) and share access + reachability.
|
|
33
|
+
- **New `snapshot --summary`** compact audit profile (counts, dimension names, report pages, expert flags, share type/perm/day + shareToken) — batch verification no longer needs to parse full module payloads.
|
|
34
|
+
- **Resume after the plan cache expires**: `smart plan --save-plan <file>` + `smart execute --plan-file <file>` (the server plan cache is ~10 minutes, and the docs now say so).
|
|
35
|
+
- **Retry/backoff**: read-only commands retry with exponential backoff on 408/429/5xx; writes are never auto-retried. Tunable via `FORMLM_RETRIES` / `FORMLM_TIMEOUT_MS`.
|
|
36
|
+
- `report page remove --name "结业证书"` resolves page names server-side; `report page update` verifies the page exists (opt into upsert with `--upsert`); write confirmations are compact; `widget remove` now persists (it previously returned success without saving).
|
|
37
|
+
|
|
38
|
+
- **`smart generate` now exists** as a resumability-preserving wrapper over `plan → execute×N → (--publish) → (--doctor)`, and the README finally matches the command surface. Earlier versions documented a `smart generate` that was never implemented (the first command every agent ran, and it failed).
|
|
39
|
+
- **Generation is now pin-able**: `smart plan --dimensions "A|B|C"` fixes the scoring dimension names and count, `--app-name` fixes the app display name, `--dry-run` validates a prompt without leaving a residue app. Unpinned dimensions used to be renamed/recounted by the AI, forcing page↔app rework (batch measurement: 11/13 pages).
|
|
40
|
+
- **Docs are now machine-verified against the command surface**: every `formlm-cli …` example in README/INSTALL is executed and checked for unknown/missing options (149 examples, 0 drifts), so documented commands cannot silently diverge again.
|
|
41
|
+
- `smart plan` output carries structured `modules` / `missingModules`, so callers can detect coverage gaps (e.g. no `expert` for non-consultation plans) without parsing prose; the raw exec `403` now lists the whitelisted command set.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
23
45
|
## What's New in v0.2.1
|
|
24
46
|
|
|
25
47
|
- **Field ID validation**: `field add --id` now enforces snake_case regex (`^[a-zA-Z0-9_]+$`)
|
|
@@ -46,7 +68,7 @@ The MCP architecture has been completely redesigned from the ground up:
|
|
|
46
68
|
│ AI Agent (any MCP Client: Claude / Cursor / │
|
|
47
69
|
│ Codex CLI / Windsurf / Cline / ...) │
|
|
48
70
|
├─────────────────────────────────────────────────────────┤
|
|
49
|
-
│ Tier 0: auth_login, auth_status
|
|
71
|
+
│ Tier 0: auth_login, auth_email_code, auth_status │
|
|
50
72
|
│ Tier 1: formlm_generate ← Smart Pipeline │
|
|
51
73
|
│ Tier 2: formlm_snapshot, formlm_skill ← State + Knowledge│
|
|
52
74
|
│ Tier 3: formlm_exec ← Direct Commands │
|
|
@@ -84,43 +106,96 @@ For a detailed step-by-step guide (including MCP setup for Claude Desktop / Curs
|
|
|
84
106
|
### 1. Login
|
|
85
107
|
|
|
86
108
|
```bash
|
|
87
|
-
|
|
88
|
-
#
|
|
109
|
+
# Recommended: copy your Access Token from the web app
|
|
110
|
+
# (formlm.me → sign in → Workspace → top-right user menu → Account Settings → Access Token → Copy)
|
|
89
111
|
formlm-cli auth login --token <your-token>
|
|
112
|
+
|
|
113
|
+
# Interactive login — pick one of three methods:
|
|
114
|
+
# 1) Access Token (same as above)
|
|
115
|
+
# 2) Email verification code (no password, no browser — fully in the terminal)
|
|
116
|
+
# 3) Email + password (only if your account has set a password —
|
|
117
|
+
# email-verification-code and Google accounts have none)
|
|
118
|
+
formlm-cli auth login
|
|
90
119
|
```
|
|
91
120
|
|
|
92
121
|
### 2. Smart Pipeline (AI-recommended)
|
|
93
122
|
|
|
123
|
+
Creation is a **two-phase pipeline** (`plan` → `execute` per module). `smart generate` is the one-shot wrapper
|
|
124
|
+
of the same steps when you do not need per-module control:
|
|
125
|
+
|
|
94
126
|
```bash
|
|
95
|
-
#
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
127
|
+
# One-shot: plan → execute every module → publish anonymously → quality audit
|
|
128
|
+
formlm-cli smart generate \
|
|
129
|
+
--input "Create a workplace stress assessment with 10 questions, 3 dimensions (workload, autonomy, support), and detailed score interpretations" \
|
|
130
|
+
--plan-type assessment --question-count 10-15 --lang en --publish --doctor
|
|
99
131
|
```
|
|
100
132
|
|
|
101
|
-
|
|
133
|
+
Or step by step (recommended for batches — every step is resumable):
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# Phase 1 — plan (~10-30s): creates the app and returns appId + task list.
|
|
137
|
+
# --save-plan keeps the full plan JSON on disk so modules can still be executed
|
|
138
|
+
# after the server-side plan cache (~10 min) expires.
|
|
139
|
+
formlm-cli smart plan --input "Create a workplace stress assessment with 10 questions, 3 dimensions, and detailed score interpretations" \
|
|
140
|
+
--plan-type assessment --question-count 10-15 --lang en --dimensions "Workload|Autonomy|Support" --save-plan plan.json
|
|
141
|
+
|
|
142
|
+
# Phase 2 — execute every module listed by the plan, in order (~30-120s each):
|
|
143
|
+
formlm-cli smart execute --app <appId> --module form
|
|
144
|
+
formlm-cli smart execute --app <appId> --module scale
|
|
145
|
+
formlm-cli smart execute --app <appId> --module connect
|
|
146
|
+
formlm-cli smart execute --app <appId> --module report
|
|
147
|
+
formlm-cli smart execute --app <appId> --module share
|
|
148
|
+
|
|
149
|
+
# Publish so anonymous visitors can fill it in (each respondent submits once, permanent):
|
|
150
|
+
formlm-cli share publish --app <appId> # --access visitor is the default
|
|
151
|
+
|
|
152
|
+
# Verify quality in one read-only call (see Doctor below):
|
|
153
|
+
formlm-cli doctor --app <appId> --expect-lang en
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
> **⚠️ Module coverage depends on planType.** Only `consultation` plans include an `expert` task;
|
|
157
|
+
> `assessment / exam / report / survey / learn` do not. `smart plan` prints a warning when a module is
|
|
158
|
+
> missing — add an expert explicitly with `formlm-cli expert config --app <appId> --name ... --role ... --kbText ...`.
|
|
159
|
+
|
|
160
|
+
> **⚠️ Styling:** the `connect` module of the pipeline applies the visual style. If you skip the pipeline and use
|
|
161
|
+
> Direct Commands instead, you MUST run `connect style apply-all`, otherwise the form keeps the plain unstyled look.
|
|
102
162
|
|
|
103
163
|
### 3. Get All App URLs (after creating)
|
|
104
164
|
|
|
105
165
|
```bash
|
|
106
|
-
# Get fill-in, editor,
|
|
166
|
+
# Get fill-in, editor, data management, and Data API URLs in one call
|
|
107
167
|
formlm-cli app urls --app <appId>
|
|
108
|
-
# Returns: shareUrl (
|
|
168
|
+
# Returns: shareUrl (relative /s/<token>), shareUrlAbsolute (https, iframe-ready),
|
|
169
|
+
# shareToken, published, shareType/sharePerm/shareDay,
|
|
170
|
+
# builderUrl (editor), dataUrl (data management),
|
|
171
|
+
# apiUrl + apiHelpUrl (Data API, empty until enabled)
|
|
109
172
|
```
|
|
110
173
|
|
|
111
|
-
### 4.
|
|
174
|
+
### 4. Enable the Data API (form backend for any page)
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
# Turn a form into a data endpoint — static sites, local pages, and AI apps
|
|
178
|
+
# can POST submissions straight to it (CORS enabled, no server needed)
|
|
179
|
+
formlm-cli share api --app <appId> --submit true --query true
|
|
180
|
+
# Then point your HTML form / fetch / curl at the returned endpoint.
|
|
181
|
+
# Append ?help to the endpoint for its Markdown docs (readable by AI agents).
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### 5. Beautify Your Form (if using Direct Commands)
|
|
112
185
|
|
|
113
186
|
```bash
|
|
114
187
|
# Apply AI-generated visual style to all pages (takes 30-120s)
|
|
115
188
|
formlm-cli connect style apply-all --app <appId> --look "职场压力评估,深蓝专业风格" --theme minimalist
|
|
116
189
|
```
|
|
117
190
|
|
|
118
|
-
###
|
|
191
|
+
### 6. Direct Commands (for fine-grained control)
|
|
119
192
|
|
|
120
193
|
```bash
|
|
121
194
|
# Get a snapshot of all module states
|
|
122
195
|
formlm-cli snapshot --app <appId>
|
|
123
196
|
formlm-cli snapshot --app <appId> --md # Markdown format (token-efficient for AI)
|
|
197
|
+
formlm-cli snapshot --app <appId> --summary # compact audit profile (batch verification)
|
|
198
|
+
formlm-cli snapshot --app <appId> --with-values # include report widget body text
|
|
124
199
|
|
|
125
200
|
# Read a skill document before constructing commands
|
|
126
201
|
formlm-cli skill form
|
|
@@ -130,25 +205,31 @@ formlm-cli skill scale
|
|
|
130
205
|
formlm-cli scale query --app <appId>
|
|
131
206
|
formlm-cli scale add --app <appId> --id stress --name "Stress Level" --format sum --kbText "..."
|
|
132
207
|
formlm-cli scale keys add --app <appId> --scale stress --fields q1,q2,q3
|
|
133
|
-
formlm-cli scale data add --app <appId> --scale stress --
|
|
208
|
+
formlm-cli scale data add --app <appId> --scale stress --bands "Low:desc||Moderate:desc||High:desc" # recommended: server auto-computes even boundaries + 999 sentinel
|
|
134
209
|
|
|
135
210
|
# Report commands
|
|
136
211
|
formlm-cli report query --app <appId>
|
|
137
|
-
formlm-cli report page add --app <appId> --name "Summary"
|
|
138
|
-
formlm-cli report widget add --app <appId> --page <pageId> --type chart --
|
|
212
|
+
formlm-cli report page add --app <appId> --name "Summary" # page type defaults to A4
|
|
213
|
+
formlm-cli report widget add --app <appId> --page <pageId> --type scale-chart --format bar --scaleId <dim> --x 0 --y 0 --w 24 --h 12
|
|
214
|
+
formlm-cli report widget logic add --app <appId> --page <pageId> --id <widgetId> --min 0 --max 20 --content "<p>Keep it up</p>"
|
|
139
215
|
|
|
140
|
-
# Expert commands
|
|
216
|
+
# Expert commands (--name and --kbText are required by the server)
|
|
141
217
|
formlm-cli expert query --app <appId>
|
|
142
|
-
formlm-cli expert config --app <appId> --
|
|
218
|
+
formlm-cli expert config --app <appId> --name "Career Coach" --role "资深职业规划师" --kbText "..." --theme Warm
|
|
219
|
+
formlm-cli expert set --app <appId> --property enable --value true # single-property toggle
|
|
220
|
+
|
|
221
|
+
# Quality audit (read-only)
|
|
222
|
+
formlm-cli doctor --app <appId>
|
|
223
|
+
formlm-cli doctor --app <appId> --expect-lang en --deep
|
|
143
224
|
```
|
|
144
225
|
|
|
145
|
-
###
|
|
226
|
+
### 7. Use as MCP Server
|
|
146
227
|
|
|
147
228
|
```bash
|
|
148
229
|
formlm-cli mcp
|
|
149
230
|
```
|
|
150
231
|
|
|
151
|
-
This starts the MCP Server (stdio transport) with
|
|
232
|
+
This starts the MCP Server (stdio transport) with 9 tools + 6 resources, ready for AI Agents to connect.
|
|
152
233
|
|
|
153
234
|
---
|
|
154
235
|
|
|
@@ -156,11 +237,37 @@ This starts the MCP Server (stdio transport) with 6 tools + 6 resources, ready f
|
|
|
156
237
|
|
|
157
238
|
### Smart Pipeline (AI-recommended)
|
|
158
239
|
|
|
240
|
+
There are two ways in: `smart plan` + `smart execute` (explicit, resumable — recommended for batches),
|
|
241
|
+
or `smart generate`, which is a thin wrapper over exactly those steps:
|
|
242
|
+
|
|
159
243
|
```bash
|
|
160
|
-
#
|
|
161
|
-
formlm-cli smart
|
|
244
|
+
# Phase 1 — plan only (creates the app, returns appId + tasks; cached server-side ~10min)
|
|
245
|
+
formlm-cli smart plan --input "..." [--plan-type assessment] [--style "温暖亲切"] [--question-count 10-15] \
|
|
246
|
+
[--lang en] [--dimensions "Focus|Sleep|Load"] [--app-name "Team Focus Check"] \
|
|
247
|
+
[--save-plan plan.json] [--dry-run]
|
|
248
|
+
|
|
249
|
+
# Phase 2 — execute one module at a time (form / scale / connect / report / expert / share)
|
|
250
|
+
formlm-cli smart execute --app <appId> --module form
|
|
251
|
+
formlm-cli smart execute --app <appId> --module scale --plan-file plan.json # after the cache expired
|
|
252
|
+
formlm-cli smart execute --app <appId> --module scale --clear-first # re-run without duplicating dimensions
|
|
253
|
+
|
|
254
|
+
# One-shot wrapper — plan → execute every module → optional publish → optional doctor
|
|
255
|
+
formlm-cli smart generate --input "..." --plan-type assessment --lang en --publish --doctor
|
|
256
|
+
formlm-cli smart generate --input "..." --only form,scale,report # partial build
|
|
257
|
+
formlm-cli smart generate --input "..." --skip connect # leave styling out
|
|
162
258
|
```
|
|
163
259
|
|
|
260
|
+
> **Pinning vs. improvising.** By default the Plan AI invents dimension names/count and the app name, which
|
|
261
|
+
> breaks page↔app consistency in batch runs. Use `--dimensions` to pin the dimension list (exact names + count)
|
|
262
|
+
> and `--app-name` to pin the display name; verify afterwards with `snapshot --summary` (it reports `dimNames`).
|
|
263
|
+
>
|
|
264
|
+
> **`--dry-run`** validates a prompt/spec and deletes the probe app again (the server always creates an app when
|
|
265
|
+
> planning), so experimentation leaves no residue.
|
|
266
|
+
>
|
|
267
|
+
> **Success is machine-readable**: `smart execute` returns `data.taskStatus` (`success` / `error`), and
|
|
268
|
+
> `smart generate` returns `{appId, modules:[{module,status,error}], publish, doctor, resumeHint}` — trust those
|
|
269
|
+
> fields, not the human wording. On a mid-run failure the app is kept and `resumeHint` gives the exact resume command.
|
|
270
|
+
|
|
164
271
|
### Snapshot
|
|
165
272
|
|
|
166
273
|
```bash
|
|
@@ -168,8 +275,38 @@ formlm-cli smart generate --input "..." [--plan-type assessment] [--style "温
|
|
|
168
275
|
formlm-cli snapshot --app <appId>
|
|
169
276
|
formlm-cli snapshot --app <appId> --module scale # Only scale module
|
|
170
277
|
formlm-cli snapshot --app <appId> --md # Markdown format (token-efficient for AI)
|
|
278
|
+
formlm-cli snapshot --app <appId> --summary # Compact audit profile (counts/dim names/report pages/expert/share + shareToken)
|
|
279
|
+
formlm-cli snapshot --app <appId> --with-values # + report widget body text (per-page queries)
|
|
280
|
+
formlm-cli snapshot --apps <id1,id2,...> --summary # Batch: N apps in ONE process (connection reuse, FORMLM_CONCURRENCY parallel apps, default 4)
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Measured: 5 apps × 7 module queries = 35 requests in ~13s in a single process, versus one cold Node
|
|
284
|
+
process per app before (the old serial-subprocess pattern took roughly 5× that, plus no connection reuse).
|
|
285
|
+
|
|
286
|
+
`snapshot` is **client-synthesized**: it fans out to the 6 `assess <module> query` commands. There is no
|
|
287
|
+
server-side `assess snapshot`, so calling that over raw `POST /api/v1/mcp/exec` returns 403 by design — loop
|
|
288
|
+
the 6 queries yourself when you need HTTP-side batching. If a module fetch fails, the result carries
|
|
289
|
+
`_errors` / `_degraded` (treat it as unknown, not as "empty module").
|
|
290
|
+
|
|
291
|
+
### Doctor (read-only quality audit)
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
# One call per app: content/scoring coverage, expert sanity, styling,
|
|
295
|
+
# unexpected certificate pages, share access semantics, link reachability
|
|
296
|
+
formlm-cli doctor --app <appId>
|
|
297
|
+
|
|
298
|
+
# Whole batch in one process (aggregate envelope; exit 1 if any app fails)
|
|
299
|
+
formlm-cli doctor --apps <id1,id2,...> --expect-lang en
|
|
300
|
+
|
|
301
|
+
# Add the language-consistency scan (classic batch defect: English app shipped with Chinese boilerplate)
|
|
302
|
+
formlm-cli doctor --app <appId> --expect-lang en # titles/labels
|
|
303
|
+
formlm-cli doctor --app <appId> --expect-lang zh-hant --deep # also scan report widget body text
|
|
304
|
+
formlm-cli doctor --app <appId> --no-probe # skip the fill-in URL reachability probe
|
|
171
305
|
```
|
|
172
306
|
|
|
307
|
+
Output is the standard envelope; `ok:false` + exit 1 when a `fail`-level finding exists, so batch drivers
|
|
308
|
+
can gate on it. Each finding carries a ready-to-run `fix` command. Read-only — it never writes.
|
|
309
|
+
|
|
173
310
|
### Skill Documents
|
|
174
311
|
|
|
175
312
|
```bash
|
|
@@ -185,9 +322,9 @@ formlm-cli skill share # Share/publish rules
|
|
|
185
322
|
### Auth
|
|
186
323
|
|
|
187
324
|
```bash
|
|
188
|
-
formlm-cli auth login
|
|
189
|
-
formlm-cli auth login
|
|
190
|
-
formlm-cli auth status # Check current login state
|
|
325
|
+
formlm-cli auth login --token <tok> # Login with Access Token (recommended: formlm.me → Account Settings)
|
|
326
|
+
formlm-cli auth login # Interactive login — 1) Access Token, 2) email verification code (no password needed), 3) email + password
|
|
327
|
+
formlm-cli auth status # Check current login state (tokens expire after 7 days)
|
|
191
328
|
formlm-cli auth logout # Clear local token
|
|
192
329
|
```
|
|
193
330
|
|
|
@@ -203,11 +340,17 @@ formlm-cli --profile work app list # Use a profile for one command
|
|
|
203
340
|
### App
|
|
204
341
|
|
|
205
342
|
```bash
|
|
206
|
-
formlm-cli app list
|
|
343
|
+
formlm-cli app list # first page (latest 20)
|
|
344
|
+
formlm-cli app list --all # full inventory (server page size capped at 500)
|
|
345
|
+
formlm-cli app list --limit 100 --page 2 # explicit paging
|
|
346
|
+
formlm-cli app list --all --with-urls # + published/shareType/sharePerm/shareDay/shareUrl/shareToken per app
|
|
347
|
+
formlm-cli app list --name "wellness" # filter by app name
|
|
207
348
|
formlm-cli app create --name "My Form" --description "..."
|
|
349
|
+
formlm-cli app get --app <appId>
|
|
208
350
|
formlm-cli app update --app <appId> --name "New Name" --theme blue
|
|
209
|
-
formlm-cli app
|
|
210
|
-
formlm-cli app
|
|
351
|
+
formlm-cli app delete --app <appId> # Delete an app (irreversible)
|
|
352
|
+
formlm-cli app remove --app <appId> # alias of app delete
|
|
353
|
+
formlm-cli app urls --app <appId> # Get fill-in / editor / data URLs + shareToken
|
|
211
354
|
```
|
|
212
355
|
|
|
213
356
|
### Field
|
|
@@ -230,7 +373,7 @@ formlm-cli scale query --app <appId> # List all dimensi
|
|
|
230
373
|
formlm-cli scale find --app <appId> --id <scaleId> # Find a dimension
|
|
231
374
|
formlm-cli scale add --app <appId> --id stress --name "Stress" --format sum --kbText "..."
|
|
232
375
|
formlm-cli scale update --app <appId> --id stress --name "Stress Level"
|
|
233
|
-
formlm-cli scale set --app <appId> --id stress --direction negative
|
|
376
|
+
formlm-cli scale set --app <appId> --id stress --property direction --value negative
|
|
234
377
|
formlm-cli scale remove --app <appId> --id stress
|
|
235
378
|
formlm-cli scale clear --app <appId>
|
|
236
379
|
formlm-cli scale config --app <appId> --enable-single true
|
|
@@ -242,7 +385,8 @@ formlm-cli scale keys list --app <appId> --scale stress
|
|
|
242
385
|
formlm-cli scale keys set --app <appId> --scale stress --fields q3 --negScore true
|
|
243
386
|
|
|
244
387
|
# Configure score ranges
|
|
245
|
-
formlm-cli scale data add --app <appId> --scale stress --
|
|
388
|
+
formlm-cli scale data add --app <appId> --scale stress --bands "Low:desc||Moderate:desc||High:desc" # recommended: server auto-computes even boundaries + 999 sentinel (ordered lowest→highest score)
|
|
389
|
+
formlm-cli scale data add --app <appId> --scale stress --ranges "0-10:Low,11-20:High" # manual boundaries; only for non-even knowledge-specified thresholds
|
|
246
390
|
formlm-cli scale data update --app <appId> --scale stress --id <dataId> --value "Moderate"
|
|
247
391
|
formlm-cli scale data remove --app <appId> --scale stress --id <dataId>
|
|
248
392
|
formlm-cli scale data list --app <appId> --scale stress
|
|
@@ -258,7 +402,7 @@ formlm-cli connect types [--category cover|main|final] --verbose
|
|
|
258
402
|
formlm-cli connect config --category cover --format rich-text
|
|
259
403
|
|
|
260
404
|
# Cover page management
|
|
261
|
-
formlm-cli connect cover-page add --app <appId> --id cover_main --name "Welcome" --format text --value "<h1>Hello</h1>"
|
|
405
|
+
formlm-cli connect cover-page add --app <appId> --id cover_main --name "Welcome" --format rich-text --value "<h1>Hello</h1>"
|
|
262
406
|
formlm-cli connect cover-page update --app <appId> --id cover_main --name "New Title"
|
|
263
407
|
formlm-cli connect cover-page find --app <appId> [--id cover_main]
|
|
264
408
|
formlm-cli connect cover-page remove --app <appId> [--id cover_main]
|
|
@@ -286,50 +430,85 @@ formlm-cli connect style move --app <appId> --id <pageId> --direction up
|
|
|
286
430
|
```bash
|
|
287
431
|
formlm-cli report query --app <appId> # List all report pages
|
|
288
432
|
formlm-cli report find --app <appId> --filter <keyword> # Find report widget
|
|
289
|
-
formlm-cli report update --app <appId> --page <pageId> --name "New Name"
|
|
290
433
|
|
|
291
|
-
#
|
|
292
|
-
|
|
293
|
-
|
|
434
|
+
# Note: update goes through the explicit owners — `report page update` (page name/bg/style/svg)
|
|
435
|
+
# and `report widget update` (widget props). The server also accepts the merged
|
|
436
|
+
# `assess report update --page <pageId> [--id <widgetId>]` form on the raw exec channel.
|
|
437
|
+
|
|
438
|
+
# Page management (a page is a 48-col × 68-row grid canvas; layout comes from widget x/y/w/h, not a page flag)
|
|
439
|
+
formlm-cli report page add --app <appId> --name "Summary" [--type A4]
|
|
440
|
+
formlm-cli report page update --app <appId> --id <pageId> --name "Overview" # fails if the id does not exist
|
|
441
|
+
formlm-cli report page update --app <appId> --id <pageId> --name "Overview" --upsert # opt into the server upsert (creates a blank page)
|
|
294
442
|
formlm-cli report page remove --app <appId> --id <pageId>
|
|
443
|
+
formlm-cli report page remove --app <appId> --name "结业证书" # locate by human-readable name
|
|
295
444
|
|
|
296
|
-
# Widget management
|
|
445
|
+
# Widget management (every widget command needs --page; set/find/update/remove also need --id)
|
|
297
446
|
formlm-cli report widget list --app <appId> --page <pageId>
|
|
298
|
-
formlm-cli report widget find --app <appId> --
|
|
299
|
-
formlm-cli report widget set --app <appId> --id <widgetId> --value "{{TotalScore}}"
|
|
300
|
-
formlm-cli report widget add --app <appId> --page <pageId> --type chart --
|
|
301
|
-
formlm-cli report widget update --app <appId> --id <widgetId> --name "Updated Chart"
|
|
302
|
-
formlm-cli report widget remove --app <appId> --id <widgetId>
|
|
303
|
-
formlm-cli report widget types --
|
|
304
|
-
formlm-cli report widget config --type chart
|
|
305
|
-
|
|
306
|
-
#
|
|
307
|
-
formlm-cli report logic add --app <appId> --page <pageId> --
|
|
308
|
-
formlm-cli report logic list --app <appId> --page <pageId>
|
|
309
|
-
formlm-cli report logic remove --app <appId> --id <logicId>
|
|
447
|
+
formlm-cli report widget find --app <appId> --page <pageId> --id <widgetId> # full detail incl. HTML value
|
|
448
|
+
formlm-cli report widget set --app <appId> --page <pageId> --id <widgetId> --property value --value "{{TotalScore}}"
|
|
449
|
+
formlm-cli report widget add --app <appId> --page <pageId> --type scale-chart --format bar --scaleId <dim> --x 0 --y 0 --w 24 --h 12
|
|
450
|
+
formlm-cli report widget update --app <appId> --page <pageId> --id <widgetId> --name "Updated Chart"
|
|
451
|
+
formlm-cli report widget remove --app <appId> --page <pageId> --id <widgetId>
|
|
452
|
+
formlm-cli report widget types --verbose # all widget types (+ descriptions)
|
|
453
|
+
formlm-cli report widget config --type scale-chart # configurable properties of one type
|
|
454
|
+
|
|
455
|
+
# Conditional display rules (logic lives UNDER widget)
|
|
456
|
+
formlm-cli report widget logic add --app <appId> --page <pageId> --id <widgetId> --min 0 --max 20 --content "<p>Low band text</p>"
|
|
457
|
+
formlm-cli report widget logic list --app <appId> --page <pageId> --id <widgetId>
|
|
458
|
+
formlm-cli report widget logic remove --app <appId> --page <pageId> --id <widgetId> --logicId <logicId>
|
|
310
459
|
```
|
|
311
460
|
|
|
312
461
|
### Expert (AI Interpretation)
|
|
313
462
|
|
|
314
463
|
```bash
|
|
315
|
-
formlm-cli expert query --app <appId> # Query expert config
|
|
316
|
-
formlm-cli expert find --app <appId> #
|
|
317
|
-
formlm-cli expert config --app <appId> --
|
|
318
|
-
|
|
319
|
-
formlm-cli expert
|
|
464
|
+
formlm-cli expert query --app <appId> # Query expert config (--md for a compact table)
|
|
465
|
+
formlm-cli expert find --app <appId> # Full config incl. prompt/welcome text
|
|
466
|
+
formlm-cli expert config --app <appId> --name "Dr. AI" --role "Career coach" \
|
|
467
|
+
--kbText "..." [--welcome ...] [--question1 ...] [--theme Warm] [--enable true] # create/update (name + kbText required)
|
|
468
|
+
formlm-cli expert set --app <appId> --property enable --value true # single-property toggle;
|
|
469
|
+
# properties: name/role/description/style/welcome/
|
|
470
|
+
# prompt/question1..3/kbText/enable/enableWelcome/theme
|
|
471
|
+
formlm-cli expert avatar --app <appId> --url <url> --enable true # needs an existing expert (config first)
|
|
320
472
|
formlm-cli expert remove --app <appId>
|
|
321
|
-
formlm-cli expert chat --app <appId> --
|
|
473
|
+
formlm-cli expert chat --app <appId> --input "Explain my score"
|
|
322
474
|
```
|
|
323
475
|
|
|
324
|
-
|
|
476
|
+
> Boolean flags are forwarded space-separated (`--enable true`), never `--enable=true` — the server parses them
|
|
477
|
+
> with picocli `arity 0..1`. `expert config` enables the agent by default; pass `--enable false` to configure it
|
|
478
|
+
> while leaving it switched off.
|
|
479
|
+
|
|
480
|
+
### Share (Publish & Access)
|
|
325
481
|
|
|
326
482
|
```bash
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
483
|
+
# Access types (know these — "public" is ambiguous):
|
|
484
|
+
# visitor = anonymous, no login required → "anyone can fill" (the usual public form)
|
|
485
|
+
# all = every LOGGED-IN FormLM user → anonymous visitors hit the login page
|
|
486
|
+
# secret = password-protected | owner = creator only | no = unpublish
|
|
487
|
+
formlm-cli share publish --app <appId> # anonymous (visitor) + one submission + permanent
|
|
488
|
+
formlm-cli share publish --app <appId> --access all --perm 2 --days 14 # explicit control
|
|
489
|
+
formlm-cli share publish --app <appId> --no-style # skip the automatic style fallback
|
|
490
|
+
formlm-cli share set --app <appId> --type visitor --perm 1 --day 0 # raw server parameters (idempotent)
|
|
491
|
+
formlm-cli share unpublish --app <appId>
|
|
492
|
+
formlm-cli share query --app <appId> # authoritative type/perm/day triple
|
|
493
|
+
formlm-cli share verify --app <appId> # published + anonymous + permanent + reachability in one call
|
|
494
|
+
formlm-cli share url --app <appId> # URLs incl. shareToken
|
|
495
|
+
formlm-cli share api --app <appId> # Configure the Data API (form backend endpoint)
|
|
496
|
+
formlm-cli share api --app <appId> --submit true --query true --auto-create true
|
|
331
497
|
```
|
|
332
498
|
|
|
499
|
+
> **Validity rule (server-side):** only `--days 1..30` are honoured as a finite window; `0`, `forever`, or anything
|
|
500
|
+
> above 30 normalizes to permanent (sentinel `3650000`). There is no 90-day/1-year publish window on this channel.
|
|
501
|
+
>
|
|
502
|
+
> **Verifying "anyone can access":** `curl` returning 200 on the share URL proves nothing — the SPA shell answers 200
|
|
503
|
+
> even behind the login gate. Use `share verify` (or read `share query`'s type/perm/day triple).
|
|
504
|
+
>
|
|
505
|
+
> **`smart execute --module share` vs `share publish`:** the pipeline's share module applies the plan's publish
|
|
506
|
+
> settings; `share publish` is the explicit, idempotent CLI entry that also guarantees anonymous + permanent
|
|
507
|
+
> defaults and prints the final URLs/`shareToken`. Re-running `share publish` is safe. If you never styled the
|
|
508
|
+
> app, publish auto-applies a default style first (30-120s AI generation) — pass `--no-style` to skip that.
|
|
509
|
+
|
|
510
|
+
The Data API turns a form into an HTTP data endpoint: `POST` JSON to the endpoint (or use the `/form` path for native HTML forms), read records back via the query endpoint, and hand the `?help` URL to an AI agent so it can discover the API on its own.
|
|
511
|
+
|
|
333
512
|
---
|
|
334
513
|
|
|
335
514
|
## MCP Integration
|
|
@@ -338,18 +517,21 @@ FormLM CLI works as a standard MCP Server over stdio and plugs into **any MCP-co
|
|
|
338
517
|
|
|
339
518
|
> **⚠️ macOS/Linux users:** desktop AI clients often launch the MCP server without your full terminal PATH, which can cause `command not found` errors. See **[INSTALL.md → Step 4](INSTALL.md#step-4--connect-to-an-ai-agent-mcp-mode)** for the `env.PATH` fix, per-platform config file locations (including Codex CLI's TOML format), and the full setup guide.
|
|
340
519
|
|
|
341
|
-
> **No token? No problem.** If you omit `FORMLM_TOKEN`, the AI will prompt you to authenticate via the `auth_login` tool —
|
|
520
|
+
> **No token? No problem.** If you omit `FORMLM_TOKEN`, the AI will prompt you to authenticate via the `auth_login` tool — paste your Access Token (from formlm.me → Workspace → Account Settings; recommended), complete an in-chat email verification-code login via `auth_email_code` (no browser needed), or use email + password directly in the chat.
|
|
342
521
|
|
|
343
522
|
---
|
|
344
523
|
|
|
345
|
-
## Available MCP Tools (
|
|
524
|
+
## Available MCP Tools (9)
|
|
346
525
|
|
|
347
526
|
| Tier | Tool | Description |
|
|
348
527
|
|---|---|---|
|
|
349
|
-
| 0 | `auth_login` | Login with
|
|
528
|
+
| 0 | `auth_login` | Login with Access Token (recommended), email verification code, or email + password |
|
|
529
|
+
| 0 | `auth_email_code` | Email verification-code login — fetch the captcha image & send the code (fully in-chat) |
|
|
350
530
|
| 0 | `auth_status` | Check current login status |
|
|
351
|
-
| 1 | `formlm_generate` | Generate
|
|
352
|
-
|
|
|
531
|
+
| 1 | `formlm_generate` | Generate the execution plan (Phase 1: creates the app, returns appId + tasks) |
|
|
532
|
+
| 1 | `formlm_execute` | Execute plan modules one by one after `formlm_generate` |
|
|
533
|
+
| 2 | `formlm_doctor` | Read-only quality audit of one app (scoring coverage, dead experts, styling, certificate pages, language consistency, share access, reachability) |
|
|
534
|
+
| 2 | `formlm_snapshot` | Aggregated state of all modules; `summary: true` returns the compact audit profile |
|
|
353
535
|
| 2 | `formlm_skill` | Fetch SKILL.md domain knowledge for a skill module |
|
|
354
536
|
| 3 | `formlm_exec` | Execute any whitelisted CLI command directly |
|
|
355
537
|
|
|
@@ -371,7 +553,86 @@ FormLM CLI works as a standard MCP Server over stdio and plugs into **any MCP-co
|
|
|
371
553
|
| Variable | Description |
|
|
372
554
|
|---|---|
|
|
373
555
|
| `FORMLM_BASE_URL` | FormLM server URL (default: `https://formlm.me`) |
|
|
374
|
-
| `FORMLM_TOKEN` | Your auth token (alternative to `auth login
|
|
556
|
+
| `FORMLM_TOKEN` | Your auth token (alternative to `auth login`; keeps secrets out of shell history) |
|
|
557
|
+
| `FORMLM_JSON=1` | Machine output: every command prints ONE parseable line `{ok,code,message,data}` on stdout (equivalent to the global `--json` flag) |
|
|
558
|
+
| `FORMLM_NO_EXIT=1` | Batch safety: never `process.exit()` on failure — a bad command cannot kill your driver loop (errors surface as `ok:false` envelopes / thrown errors) |
|
|
559
|
+
| `FORMLM_TIMEOUT_MS` | Default per-command request timeout (ms, default 60000) |
|
|
560
|
+
| `FORMLM_TIMEOUT_PLAN` / `FORMLM_TIMEOUT_EXECUTE` / `FORMLM_TIMEOUT_STYLE` | Override the smart-plan (120s), smart-execute (300s) and style (600s) timeouts |
|
|
561
|
+
| `FORMLM_RETRIES` | Max attempts for transient failures (default 3). Read-only commands retry on 408/429/5xx; writes are never auto-retried |
|
|
562
|
+
| `FORMLM_CONCURRENCY` | In-process parallelism for batch commands (`snapshot --apps`, `doctor --apps`), default 4 |
|
|
563
|
+
|
|
564
|
+
---
|
|
565
|
+
|
|
566
|
+
## Scripting & Batch Use
|
|
567
|
+
|
|
568
|
+
```bash
|
|
569
|
+
# One parseable line per command; guidance/hints go to stderr, stdout stays clean:
|
|
570
|
+
FORMLM_JSON=1 FORMLM_NO_EXIT=1 formlm-cli snapshot --app <appId> --summary
|
|
571
|
+
FORMLM_JSON=1 formlm-cli share verify --app <appId> # {ok, data:{type,forever,anonymous,httpStatus,shareToken}}
|
|
572
|
+
FORMLM_JSON=1 formlm-cli doctor --app <appId> --expect-lang en # ok:false when a fail-level finding exists
|
|
573
|
+
|
|
574
|
+
# Whole batch in one process (no per-app Node cold start; tunable with FORMLM_CONCURRENCY):
|
|
575
|
+
FORMLM_JSON=1 formlm-cli doctor --apps id1,id2,id3 --expect-lang en
|
|
576
|
+
FORMLM_JSON=1 formlm-cli snapshot --apps id1,id2,id3 --summary
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
Envelope: `{ "ok": bool, "code": int, "message": string, "data": object|null }` — `data` is always parsed
|
|
580
|
+
(no double-decoding needed), and validation/parameter errors now come back with a non-zero `code`
|
|
581
|
+
instead of hiding the error text inside `data` while reporting success.
|
|
582
|
+
|
|
583
|
+
### Status codes
|
|
584
|
+
|
|
585
|
+
| Code | Meaning | What to do |
|
|
586
|
+
|---|---|---|
|
|
587
|
+
| `0` | Success | — |
|
|
588
|
+
| `207` | Partial (multi-module reads where one module failed) | Result carries `_errors`/`_degraded`; re-check that module, don't assume it is empty |
|
|
589
|
+
| `400` | Bad request / parameter or validation error | Read `message`; the server echoes picocli's hint (valid values, missing option) |
|
|
590
|
+
| `401` | Not authenticated | `formlm-cli auth login --token-stdin` (or set `FORMLM_TOKEN`) |
|
|
591
|
+
| `403` | Command not on the exec whitelist, or wrong credentials/verification code | See the whitelist below; for MCP check `auth_status` |
|
|
592
|
+
| `408` | Request timed out client-side | Retry read-only; for `smart execute` re-run that module (writes are not auto-retried) |
|
|
593
|
+
| `429` | Rate limited (login attempts, send-code quotas) | Wait, then retry with backoff |
|
|
594
|
+
| `500` | Transport failure or server error | Retried automatically for read-only commands |
|
|
595
|
+
|
|
596
|
+
### Raw `POST /api/v1/mcp/exec` whitelist
|
|
597
|
+
|
|
598
|
+
The exec channel accepts 3-token command paths only (`assess <module> <action>`). Everything else returns
|
|
599
|
+
`403 not allowed via MCP` **by design** — notably `assess snapshot` and `assess field …` do not exist on the
|
|
600
|
+
server (they are client-side wrappers), so batch HTTP consumers must call the underlying queries:
|
|
601
|
+
|
|
602
|
+
```
|
|
603
|
+
assess app list | create | use | current | update | remove | urls
|
|
604
|
+
assess form query | find | types | config | add | update | remove | move | set-property
|
|
605
|
+
assess scale query | find | add | update | set | remove | clear | config | keys | data
|
|
606
|
+
assess connect query | find | types | config | cover-page | final-page | main-page | style
|
|
607
|
+
assess report query | find | update | page | widget (conditional logic is `report widget logic …`)
|
|
608
|
+
assess expert query | find | config | set | avatar | remove | chat
|
|
609
|
+
assess share set | query | url | api | flavor
|
|
610
|
+
assess smart plan | execute
|
|
611
|
+
assess skill form | scale | connect | report | expert | share
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
### Throughput notes
|
|
615
|
+
|
|
616
|
+
- Every CLI invocation is a fresh Node process plus its own HTTP calls; for large batches, run independent
|
|
617
|
+
apps concurrently (the server tolerates moderate parallelism) rather than serially.
|
|
618
|
+
- `snapshot`/`doctor` fan out their module queries in parallel; use `--module` / `--summary` to keep payloads small.
|
|
619
|
+
- Slow server? Raise `FORMLM_TIMEOUT_MS` and `FORMLM_RETRIES` instead of hand-rolling retry loops.
|
|
620
|
+
- Batch over many apps **inside one process**: `snapshot --apps …` / `doctor --apps …`, or import the built
|
|
621
|
+
module directly (`import { execCommand } from '@formlm/cli/dist/exec.js'`) and loop — HTTP connections are
|
|
622
|
+
reused and there is no per-app Node cold start.
|
|
623
|
+
|
|
624
|
+
### Version coupling (CLI ↔ server)
|
|
625
|
+
|
|
626
|
+
Some commands rely on server options added together with them; against an older server they fail with a
|
|
627
|
+
visible `400 Unknown option …` (never a silent success, thanks to the false-success guard):
|
|
628
|
+
|
|
629
|
+
| Needs server support | Command / flag |
|
|
630
|
+
|---|---|
|
|
631
|
+
| ✔ | `app list --all / --limit / --page / --with-urls` |
|
|
632
|
+
| ✔ | `app urls` native `shareToken` + `published/shareType/…` (the CLI fills `shareToken` from `shareUrl` as a fallback) |
|
|
633
|
+
| ✔ | `report page remove --name "…"` (name→id resolution moved server-side, so raw exec benefits too) |
|
|
634
|
+
| ✔ | `expert config --enable true\|false` (fall back to `expert set --property enable` on an old server) |
|
|
635
|
+
| ✔ | `smart plan --dimensions / --app-name`, `smart execute --plan-file` (`--plan-b64` transport) |
|
|
375
636
|
|
|
376
637
|
---
|
|
377
638
|
|
|
@@ -388,7 +649,7 @@ FormLM CLI works as a standard MCP Server over stdio and plugs into **any MCP-co
|
|
|
388
649
|
|
|
389
650
|
Have questions, feedback, or need help getting started?
|
|
390
651
|
|
|
391
|
-
📧 **[formlm.me
|
|
652
|
+
📧 **[hello@formlm.me](mailto:hello@formlm.me)**
|
|
392
653
|
|
|
393
654
|
Feel free to reach out — we're happy to help.
|
|
394
655
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/commands/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/commands/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAwHxD"}
|