@fenfill/mcp 0.1.0 → 0.2.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/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,59 @@ 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
- It renders the local working copy (`edit_template`) when there is one, otherwise the saved
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 `table_rows` table's columns and printed cells
142
+ with their boxes (fill values still go by column id). `warnings` and `placement_warnings` are
143
+ always present (`[]` = checked and clean): placement covers every box shown, so a plain preview
144
+ is a read-only placement audit (see the checks under `edit_template`). `crop`
145
+ (`{x, y, w, h}`, fractions) with `zoom` (default 2, max 8) renders just a region, magnified, and
146
+ lists only what it shows; `legend: "changed"` returns only the rows that changed since your last
147
+ preview of that page (the first time: since fenfill's version), each with only its changed
148
+ options/cells/columns (`members_changed` counts them, so a header edit doesn't list the whole
149
+ grid), plus `removed` ids and `moved_into` (ids that now sit inside a table or group), and
150
+ `legend: "none"` omits the legend. It renders the local working copy (`edit_template`) when there is one, otherwise the saved
135
151
  template or analyzed version; `edited: true` / `false` in the result says which. The page is rendered on your machine by
136
152
  PDFium (WebAssembly, shipped in the package; nothing native is installed), nothing is written to
137
153
  disk, and the image goes only to the calling client.
138
154
 
139
- `edit_template` takes `path` or `template_id` and up to 200 `ops`: `set_box` (absolute
140
- `{id, x, y, w, h}` in one step), `move`, `resize`, `relabel`,
141
- `retype`, `add`, `delete`, `set_format`, `group`, `ungroup`, `set_options`, `set_required`,
142
- `set_description`, `set_placeholder` (table rows and columns can't be added or removed yet).
155
+ `edit_template` takes `path` or `template_id` and up to 200 `ops`:
156
+
157
+ - fields: `set_box` (absolute `{id, x, y, w, h}` in one step), `move`, `resize`, `relabel`,
158
+ `retype`, `add`, `delete`, `set_format` (`date_format` is one of `DD/MM/YYYY`, `MM/DD/YYYY`,
159
+ `YYYY-MM-DD`, `DD.MM.YYYY`, `DD-MM-YYYY`), `set_required`, `set_description`,
160
+ `set_placeholder`, `set_autofill` (a browser autofill token such as `name` or `postal-code`,
161
+ or `null` to clear it);
162
+ - choices and combs: `group` (`kind: "choice" | "comb"`), `ungroup`, `set_options`, and
163
+ `add_option` / `remove_option`, which keep the group's id;
164
+ - tables: `group` with `kind: "table"` (a `cells` grid of field ids, rows × columns with `null`
165
+ for a gap, or `ids` laid out from their boxes; `header_cols`, `header_rows`, `orientation`,
166
+ `format`), `table_insert` / `table_delete` (a row or column; a new line's geometry is
167
+ interpolated from its neighbours unless you pass it), `table_add_cell` (fill an empty slot),
168
+ `table_adopt` (move a loose field into an empty slot), `set_column_type`, `set_orientation`
169
+ 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,
170
+ as in the web editor; `set_format` on a table cell applies to its whole column or row;
171
+ - order: `reorder {page, ids}` moves those top-level entries together, in that order, to where
172
+ the first of them sat, and stamps an explicit `order` on every entry of the page (the web
173
+ editor's layer-panel convention), so a later sub-pixel move no longer reshuffles questions.
174
+
175
+ Any id can be shortened to an unambiguous prefix of 6+ characters (the length of the preview
176
+ tags); an ambiguous prefix is rejected with the candidates. `add`, `move` and `set_box` take an
177
+ optional `snap`: `"underline"` fits the box onto the printed rule under it, `"cell"` into the
178
+ ruled box around it, `"answer"` into that cell's blank part (below a caption printed at its top,
179
+ or after one at its left), read from the page render on your machine; when nothing fits near the
180
+ box, the box is kept and a warning says so. Snap finds printed rules with its own simple line
181
+ finder (one ink threshold per page, not the web editor's wand): a very faint rule on a tinted
182
+ scan can be missed, and an underline box is one line of handwriting tall (as tall as the clear
183
+ space above the rule, within about 11–16 pt). `diff_summary.ops` lists every applied op with
184
+ `snapped: true/false` (when it asked for a snap) and `noop: true` when it changed nothing. After
185
+ each edit, the boxes you touched are checked for three placement problems: a value that would
186
+ print much larger than the page's other fields (an Auto box's text size follows its height), a
187
+ box over printed text (text layer only, so not on scans), and a box that runs a little past the
188
+ ruled cell it sits in (from the page render, so scans too). `set_format` merges into the stored
189
+ format (a date field keeps its date format when you only set `font_size`).
143
190
  Coordinates are fractions of the page (0–1) with a top-left origin, the same as the legend's
144
191
  `box`. Each op is checked against the rules fenfill applies when saving and is rejected with a
145
192
  reason if it breaks them; ops apply in order, all-or-nothing each, except that a box only has to
@@ -160,7 +207,39 @@ memory). A working copy edited in an earlier session can't be checked against th
160
207
  answers: `save_template` then answers `confirm_wording_needed` with the changed ids and
161
208
  properties (never their text); review them and call again with `confirm_wording: true`. An
162
209
  unsaved analysis can be edited for filling but not saved: to keep corrections,
163
- analyze with `save_as_template: true` and edit that template.
210
+ analyze with `save_as_template: true` and edit that template. With nothing to save, it succeeds
211
+ with `saved: false, nothing_to_save: true`. `get_template` says `has_local_edits` (its fields
212
+ are fenfill's saved version; `preview_page` shows the working copy) and gives `field_count`
213
+ (entries listed) and `field_count_total` (the whole form); `save_template`'s `field_count` is
214
+ the whole saved template.
215
+
216
+ ### Re-analyzing pages of a saved template
217
+
218
+ A template saved from only some pages (`analyze_form` with `pages` and `save_as_template`) has
219
+ pages fenfill never looked at: `get_template` lists them as `unanalyzed_pages`, and
220
+ `list_templates` shows `analyzed_pages` next to `page_count`. `reanalyze_template` takes
221
+ `template_id`, `pages` and a `kind`:
222
+
223
+ | `kind` | Use it to |
224
+ | --------------- | --------------------------------------------------------------------------------- |
225
+ | `scratch` | analyze a never-analyzed page, or replace a badly analyzed page's fields entirely |
226
+ | `find` | add blanks the first pass missed, keeping everything already there |
227
+ | `relabel` | re-derive labels, types, groups and sections, keeping the boxes |
228
+ | `label_missing` | fill in only the labels that are missing |
229
+
230
+ `kind` can be left out only when the pages have no fields (it then means `scratch`). Each page
231
+ costs one page scan; `label_missing` is free within the workspace's monthly free-label
232
+ allowance. `estimate: true` prices the run and starts nothing. `relabel` may reset table column
233
+ types and orientation, so check the template with `get_template` afterwards.
234
+
235
+ It uses the PDF already stored with the template, so nothing is uploaded. It refuses while the
236
+ template has unsaved `edit_template` edits (`local_edits_pending`): save them with
237
+ `save_template` first, or pass `discard: true` to drop them when the run finishes. The result
238
+ lists, per changed page, the fields `added`, `removed` and `changed` (label, type, box, or a
239
+ group's cells), then the new fields of those pages; review them with `preview_page` and correct
240
+ them with `edit_template` + `save_template`. Like `analyze_form`, it waits out capacity
241
+ refusals, and if it answers `"running"`, calling it again with the same arguments follows the
242
+ same run at no extra charge.
164
243
 
165
244
  ### Value shapes
166
245
 
@@ -168,7 +247,7 @@ analyze with `save_as_template: true` and edit that template.
168
247
  | ------------------- | --------------------------------------------------------------------------- |
169
248
  | `text`, `multiline` | string, stamped exactly as given |
170
249
  | `comb` | string, one character per cell |
171
- | `date` | `"YYYY-MM-DD"`, printed as `YYYY-MM-DD` |
250
+ | `date` | `"YYYY-MM-DD"`, printed in the field's `date_format` (e.g. `DD/MM/YYYY`) |
172
251
  | `checkbox` | `true` / `false` |
173
252
  | `radio` | option id, option label, or the bare option text (`"No"` for `"Smoke? No"`) |
174
253
  | `multiselect` | array of those |
@@ -192,12 +271,12 @@ fenfill web app for that workspace (for example, your logo if you have set one u
192
271
 
193
272
  ## Configuration
194
273
 
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` waits before saying "running". |
274
+ | Variable | Default | Notes |
275
+ | ------------------------------ | ------------------------- | ---------------------------------------------------------------------------- |
276
+ | `FENFILL_API_KEY` | (none) | `ff_live_…` from fenfill → Settings → API keys. |
277
+ | `FENFILL_API_URL` | `https://api.fenfill.com` | https only (http allowed for localhost). |
278
+ | `FENFILL_CACHE_DIR` | the OS cache folder | Holds schemas and blank forms only, never answers. |
279
+ | `FENFILL_ANALYZE_WAIT_SECONDS` | `50` | How long `analyze_form` / `reanalyze_template` wait before saying "running". |
201
280
 
202
281
  `fill_form` works without an API key once a form has been analyzed.
203
282
 
@@ -238,7 +317,9 @@ fenfill web app for that workspace (for example, your logo if you have set one u
238
317
  | `request_too_large` | The edited template is too large to save in one request. |
239
318
  | `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
319
  | `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
- | `no_local_edits` | `save_template` has nothing to save for that template (edits to an unsaved analysis can't be saved; see above). |
320
+ | `local_edits_pending` | `reanalyze_template` won't run over unsaved edits: `save_template` them first, or pass `discard: true`. |
321
+ | `kind_required` | The pages already have fields: pass `kind` (`find`, `relabel`, `label_missing`, or `scratch` to replace them). |
322
+ | `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
323
  | `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
324
 
244
325
  ## API
@@ -1,4 +1,4 @@
1
- @fenfill/mcp 0.1.0 bundles the following third-party software.
1
+ @fenfill/mcp 0.2.0 bundles the following third-party software.
2
2
 
3
3
  @cantoo/pdf-lib@2.11.1 (MIT)
4
4
  ------------------------------------------------------------------------