@fenfill/mcp 0.1.0 → 0.2.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 +98 -15
- package/THIRD_PARTY_NOTICES +1 -1
- package/dist/index.js +3423 -738
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,6 +19,8 @@ are stamped into the PDF locally and are never sent to fenfill or anywhere else.
|
|
|
19
19
|
on your machine. If a box is misplaced, missing or mislabeled, **`edit_template`** fixes it in a
|
|
20
20
|
local working copy that filling uses at once, and **`save_template`** keeps the fix in a saved
|
|
21
21
|
template.
|
|
22
|
+
5. **`reanalyze_template`** re-runs fenfill on some pages of a saved template (a page that was
|
|
23
|
+
never analyzed, or one that came out badly), from the blank PDF already stored with it.
|
|
22
24
|
|
|
23
25
|
### What is sent where
|
|
24
26
|
|
|
@@ -30,6 +32,7 @@ are stamped into the PDF locally and are never sent to fenfill or anywhere else.
|
|
|
30
32
|
| Saved templates (blank PDF, fields, your logo) | Downloaded from fenfill to fill locally |
|
|
31
33
|
| Page previews (`preview_page`) | **No**: rendered on your machine |
|
|
32
34
|
| Layout corrections (`edit_template`) | Only on `save_template`, and then only the layout and the form's own wording |
|
|
35
|
+
| Re-analysis (`reanalyze_template`) | Only the template id, pages, kind and version: nothing is uploaded |
|
|
33
36
|
|
|
34
37
|
`analyze_form` refuses PDFs whose form fields already hold answers, and PDFs this server wrote
|
|
35
38
|
itself, so a filled-in form isn't uploaded by mistake.
|
|
@@ -101,6 +104,7 @@ On native Windows, if the client can't find `npx`, use `"command": "cmd"` with
|
|
|
101
104
|
| `preview_page` | Renders one page (PNG) with every field box outlined and tagged, locally. |
|
|
102
105
|
| `edit_template` | Moves, resizes, relabels, retypes, adds, deletes or regroups fields, locally. |
|
|
103
106
|
| `save_template` | Saves `edit_template`'s working copy to a saved template. |
|
|
107
|
+
| `reanalyze_template` | Re-analyzes some pages of a saved template, with no upload, and shows the diff. |
|
|
104
108
|
|
|
105
109
|
`analyze_form` options: `pages` (e.g. `"1-3,5"`; long PDFs can be analyzed in chunks, and
|
|
106
110
|
`fill_form` merges them), `save_as_template` (also keep it as a fenfill template), `access`
|
|
@@ -130,16 +134,60 @@ workspace, free native-field (AcroForm) ones included.
|
|
|
130
134
|
`preview_page` takes `path` (an analyzed PDF) or `template_id`, a 1-based `page`, optional
|
|
131
135
|
`values` (to see them stamped; the same shapes as `fill_form`, e.g. `table_rows` =
|
|
132
136
|
`[{columnId: value}, …]`, `multiselect` = an array of option ids or labels) and `dpi` (default
|
|
133
|
-
110, max 200). It returns a PNG image plus a legend: each box's tag, id, type, label and `box
|
|
134
|
-
|
|
137
|
+
110, max 200). It returns a PNG image plus a legend: each box's tag, id, type, label and `box`;
|
|
138
|
+
a text/date field's stored `format` and `font_pt` (the size its value starts at; `font_auto`
|
|
139
|
+
when that follows the box height); a choice's options with their own boxes; a table's cells by
|
|
140
|
+
`(row, col)`, its `orientation` and headers (also printed on the image inside, or beside, the
|
|
141
|
+
first cell of each line as `R: …` / `C: …`; a character the bundled fonts lack is shown as `?`
|
|
142
|
+
there, with a warning, and the legend keeps the full text); a `table_rows` table's columns and printed cells
|
|
143
|
+
with their boxes (fill values still go by column id). `warnings` and `placement_warnings` are
|
|
144
|
+
always present (`[]` = checked and clean): placement covers every box shown, so a plain preview
|
|
145
|
+
is a read-only placement audit (see the checks under `edit_template`). `crop`
|
|
146
|
+
(`{x, y, w, h}`, fractions) with `zoom` (default 2, max 8) renders just a region, magnified, and
|
|
147
|
+
lists only what it shows; `legend: "changed"` returns only the rows that changed since your last
|
|
148
|
+
preview of that page (the first time: since fenfill's version), each with only its changed
|
|
149
|
+
options/cells/columns (`members_changed` counts them, so a header edit doesn't list the whole
|
|
150
|
+
grid), plus `removed` ids and `moved_into` (ids that now sit inside a table or group), and
|
|
151
|
+
`legend: "none"` omits the legend. It renders the local working copy (`edit_template`) when there is one, otherwise the saved
|
|
135
152
|
template or analyzed version; `edited: true` / `false` in the result says which. The page is rendered on your machine by
|
|
136
153
|
PDFium (WebAssembly, shipped in the package; nothing native is installed), nothing is written to
|
|
137
154
|
disk, and the image goes only to the calling client.
|
|
138
155
|
|
|
139
|
-
`edit_template` takes `path` or `template_id` and up to 200 `ops`:
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
`
|
|
156
|
+
`edit_template` takes `path` or `template_id` and up to 200 `ops`:
|
|
157
|
+
|
|
158
|
+
- fields: `set_box` (absolute `{id, x, y, w, h}` in one step), `move`, `resize`, `relabel`,
|
|
159
|
+
`retype`, `add`, `delete`, `set_format` (`date_format` is one of `DD/MM/YYYY`, `MM/DD/YYYY`,
|
|
160
|
+
`YYYY-MM-DD`, `DD.MM.YYYY`, `DD-MM-YYYY`), `set_required`, `set_description`,
|
|
161
|
+
`set_placeholder`, `set_autofill` (a browser autofill token such as `name` or `postal-code`,
|
|
162
|
+
or `null` to clear it);
|
|
163
|
+
- choices and combs: `group` (`kind: "choice" | "comb"`), `ungroup`, `set_options`, and
|
|
164
|
+
`add_option` / `remove_option`, which keep the group's id;
|
|
165
|
+
- tables: `group` with `kind: "table"` (a `cells` grid of field ids, rows × columns with `null`
|
|
166
|
+
for a gap, or `ids` laid out from their boxes; `header_cols`, `header_rows`, `orientation`,
|
|
167
|
+
`format`), `table_insert` / `table_delete` (a row or column; a new line's geometry is
|
|
168
|
+
interpolated from its neighbours unless you pass it), `table_add_cell` (fill an empty slot),
|
|
169
|
+
`table_adopt` (move a loose field into an empty slot), `set_column_type`, `set_orientation`
|
|
170
|
+
and `set_header` / `set_headers` (`{id, axis, texts: [...], start?}`, several in one op). Every cell of one column (or row, for `orientation: "row"`) has one type,
|
|
171
|
+
as in the web editor; `set_format` on a table cell applies to its whole column or row;
|
|
172
|
+
- order: `reorder {page, ids}` moves those top-level entries together, in that order, to where
|
|
173
|
+
the first of them sat, and stamps an explicit `order` on every entry of the page (the web
|
|
174
|
+
editor's layer-panel convention), so a later sub-pixel move no longer reshuffles questions.
|
|
175
|
+
|
|
176
|
+
Any id can be shortened to an unambiguous prefix of 6+ characters (the length of the preview
|
|
177
|
+
tags); an ambiguous prefix is rejected with the candidates. `add`, `move` and `set_box` take an
|
|
178
|
+
optional `snap`: `"underline"` fits the box onto the printed rule under it, `"cell"` into the
|
|
179
|
+
ruled box around it, `"answer"` into that cell's blank part (below a caption printed at its top,
|
|
180
|
+
or after one at its left), read from the page render on your machine; when nothing fits near the
|
|
181
|
+
box, the box is kept and a warning says so. Snap finds printed rules with its own simple line
|
|
182
|
+
finder (one ink threshold per page, not the web editor's wand): a very faint rule on a tinted
|
|
183
|
+
scan can be missed, and an underline box is one line of handwriting tall (as tall as the clear
|
|
184
|
+
space above the rule, within about 11–16 pt). `diff_summary.ops` lists every applied op with
|
|
185
|
+
`snapped: true/false` (when it asked for a snap) and `noop: true` when it changed nothing. After
|
|
186
|
+
each edit, the boxes you touched are checked for three placement problems: a value that would
|
|
187
|
+
print much larger than the page's other fields (an Auto box's text size follows its height), a
|
|
188
|
+
box over printed text (text layer only, so not on scans), and a box that runs a little past the
|
|
189
|
+
ruled cell it sits in (from the page render, so scans too). `set_format` merges into the stored
|
|
190
|
+
format (a date field keeps its date format when you only set `font_size`).
|
|
143
191
|
Coordinates are fractions of the page (0–1) with a top-left origin, the same as the legend's
|
|
144
192
|
`box`. Each op is checked against the rules fenfill applies when saving and is rejected with a
|
|
145
193
|
reason if it breaks them; ops apply in order, all-or-nothing each, except that a box only has to
|
|
@@ -160,7 +208,39 @@ memory). A working copy edited in an earlier session can't be checked against th
|
|
|
160
208
|
answers: `save_template` then answers `confirm_wording_needed` with the changed ids and
|
|
161
209
|
properties (never their text); review them and call again with `confirm_wording: true`. An
|
|
162
210
|
unsaved analysis can be edited for filling but not saved: to keep corrections,
|
|
163
|
-
analyze with `save_as_template: true` and edit that template.
|
|
211
|
+
analyze with `save_as_template: true` and edit that template. With nothing to save, it succeeds
|
|
212
|
+
with `saved: false, nothing_to_save: true`. `get_template` says `has_local_edits` (its fields
|
|
213
|
+
are fenfill's saved version; `preview_page` shows the working copy) and gives `field_count`
|
|
214
|
+
(entries listed) and `field_count_total` (the whole form); `save_template`'s `field_count` is
|
|
215
|
+
the whole saved template.
|
|
216
|
+
|
|
217
|
+
### Re-analyzing pages of a saved template
|
|
218
|
+
|
|
219
|
+
A template saved from only some pages (`analyze_form` with `pages` and `save_as_template`) has
|
|
220
|
+
pages fenfill never looked at: `get_template` lists them as `unanalyzed_pages`, and
|
|
221
|
+
`list_templates` shows `analyzed_pages` next to `page_count`. `reanalyze_template` takes
|
|
222
|
+
`template_id`, `pages` and a `kind`:
|
|
223
|
+
|
|
224
|
+
| `kind` | Use it to |
|
|
225
|
+
| --------------- | --------------------------------------------------------------------------------- |
|
|
226
|
+
| `scratch` | analyze a never-analyzed page, or replace a badly analyzed page's fields entirely |
|
|
227
|
+
| `find` | add blanks the first pass missed, keeping everything already there |
|
|
228
|
+
| `relabel` | re-derive labels, types, groups and sections, keeping the boxes |
|
|
229
|
+
| `label_missing` | fill in only the labels that are missing |
|
|
230
|
+
|
|
231
|
+
`kind` can be left out only when the pages have no fields (it then means `scratch`). Each page
|
|
232
|
+
costs one page scan; `label_missing` is free within the workspace's monthly free-label
|
|
233
|
+
allowance. `estimate: true` prices the run and starts nothing. `relabel` may reset table column
|
|
234
|
+
types and orientation, so check the template with `get_template` afterwards.
|
|
235
|
+
|
|
236
|
+
It uses the PDF already stored with the template, so nothing is uploaded. It refuses while the
|
|
237
|
+
template has unsaved `edit_template` edits (`local_edits_pending`): save them with
|
|
238
|
+
`save_template` first, or pass `discard: true` to drop them when the run finishes. The result
|
|
239
|
+
lists, per changed page, the fields `added`, `removed` and `changed` (label, type, box, or a
|
|
240
|
+
group's cells), then the new fields of those pages; review them with `preview_page` and correct
|
|
241
|
+
them with `edit_template` + `save_template`. Like `analyze_form`, it waits out capacity
|
|
242
|
+
refusals, and if it answers `"running"`, calling it again with the same arguments follows the
|
|
243
|
+
same run at no extra charge.
|
|
164
244
|
|
|
165
245
|
### Value shapes
|
|
166
246
|
|
|
@@ -168,7 +248,7 @@ analyze with `save_as_template: true` and edit that template.
|
|
|
168
248
|
| ------------------- | --------------------------------------------------------------------------- |
|
|
169
249
|
| `text`, `multiline` | string, stamped exactly as given |
|
|
170
250
|
| `comb` | string, one character per cell |
|
|
171
|
-
| `date` | `"YYYY-MM-DD"`, printed
|
|
251
|
+
| `date` | `"YYYY-MM-DD"`, printed in the field's `date_format` (e.g. `DD/MM/YYYY`) |
|
|
172
252
|
| `checkbox` | `true` / `false` |
|
|
173
253
|
| `radio` | option id, option label, or the bare option text (`"No"` for `"Smoke? No"`) |
|
|
174
254
|
| `multiselect` | array of those |
|
|
@@ -192,12 +272,12 @@ fenfill web app for that workspace (for example, your logo if you have set one u
|
|
|
192
272
|
|
|
193
273
|
## Configuration
|
|
194
274
|
|
|
195
|
-
| Variable | Default | Notes
|
|
196
|
-
| ------------------------------ | ------------------------- |
|
|
197
|
-
| `FENFILL_API_KEY` | (none) | `ff_live_…` from fenfill → Settings → API keys.
|
|
198
|
-
| `FENFILL_API_URL` | `https://api.fenfill.com` | https only (http allowed for localhost).
|
|
199
|
-
| `FENFILL_CACHE_DIR` | the OS cache folder | Holds schemas and blank forms only, never answers.
|
|
200
|
-
| `FENFILL_ANALYZE_WAIT_SECONDS` | `50` | How long `analyze_form`
|
|
275
|
+
| Variable | Default | Notes |
|
|
276
|
+
| ------------------------------ | ------------------------- | ---------------------------------------------------------------------------- |
|
|
277
|
+
| `FENFILL_API_KEY` | (none) | `ff_live_…` from fenfill → Settings → API keys. |
|
|
278
|
+
| `FENFILL_API_URL` | `https://api.fenfill.com` | https only (http allowed for localhost). |
|
|
279
|
+
| `FENFILL_CACHE_DIR` | the OS cache folder | Holds schemas and blank forms only, never answers. |
|
|
280
|
+
| `FENFILL_ANALYZE_WAIT_SECONDS` | `50` | How long `analyze_form` / `reanalyze_template` wait before saying "running". |
|
|
201
281
|
|
|
202
282
|
`fill_form` works without an API key once a form has been analyzed.
|
|
203
283
|
|
|
@@ -235,10 +315,13 @@ fenfill web app for that workspace (for example, your logo if you have set one u
|
|
|
235
315
|
| `too_many_active_jobs` | Other analyses in the workspace (free native-field ones too) are still running; try again in a minute, or analyze fewer at once. |
|
|
236
316
|
| `template_conflict` | The template changed in fenfill since your edits began. Your local edits are kept: `edit_template` with `discard: true`, re-apply the ops, save again. |
|
|
237
317
|
| `invalid_schema` | fenfill (or the local check before it) refused the edited layout; `details` lists each item and reason. Fix them with `edit_template`. |
|
|
318
|
+
| `check_copy_failed` | `preview_page` could not build its outlined copy; `stage` and `id` say where. Fix or remove that field or group with `edit_template`, then preview again. |
|
|
238
319
|
| `request_too_large` | The edited template is too large to save in one request. |
|
|
239
320
|
| `answer_in_template` | Edited wording matches an answer from this session, so nothing was sent. Put the form's own wording back with `edit_template`. |
|
|
240
321
|
| `confirm_wording_needed` | The working copy has wording edited in an earlier session. Review the ids and properties in `changed`, then `save_template` with `confirm_wording: true`. |
|
|
241
|
-
| `
|
|
322
|
+
| `local_edits_pending` | `reanalyze_template` won't run over unsaved edits: `save_template` them first, or pass `discard: true`. |
|
|
323
|
+
| `kind_required` | The pages already have fields: pass `kind` (`find`, `relabel`, `label_missing`, or `scratch` to replace them). |
|
|
324
|
+
| `job_in_progress` | A job is already running on the template; wait and retry (call `reanalyze_template` again with the same arguments if you started it). |
|
|
242
325
|
| `upload_outcome_unknown` | An earlier upload was interrupted. To avoid charging twice, the same file isn't re-uploaded for about 10 minutes; check `get_account` meanwhile. |
|
|
243
326
|
|
|
244
327
|
## API
|
package/THIRD_PARTY_NOTICES
CHANGED