opentakeoff-mcp 0.9.73 → 0.9.76

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
@@ -44,9 +44,9 @@ what's missing where rendering isn't available.
44
44
  engine is re-validated against a wider plan corpus: `tools/list` never names them, the
45
45
  initialize `instructions` say so and point at `measure_polygon`, and no other tool's
46
46
  description sends an agent to a verb that is not there. A default build registers
47
- **45 tools**. Everything else — sweeps, counts, `derive_base`, `derive_transitions`, the
47
+ **52 tools**. Everything else — sweeps, counts, `derive_base`, `derive_transitions`, the
48
48
  exports — is unchanged. Set `OPENTAKEOFF_ONE_CLICK=1` in the server's environment to
49
- register both verbs (47 tools); the parity, conformance and e2e tests run that way, and
49
+ register both verbs (54 tools); the parity, conformance and e2e tests run that way, and
50
50
  `test/gate.test.ts` pins both surfaces. The rows and examples below that use `one_click`
51
51
  describe the lifted build. Design note: [`docs/design/ONE_CLICK_GATE.md`](../docs/design/ONE_CLICK_GATE.md).
52
52
 
@@ -121,8 +121,8 @@ includes document text, shape vertices, or result payload content.
121
121
 
122
122
  ### Staged tool exposure (opt-in)
123
123
 
124
- By default every client gets all 47 tool schemas on `tools/list`—the flat
125
- contract every published client already expects. Forty-three descriptions is real
124
+ By default every client gets all 52 tool schemas on `tools/list`—the flat
125
+ contract every published client already expects. Fifty-two descriptions is real
126
126
  token weight for an agent session that may never touch half of them, so the
127
127
  server can instead stage the surface along the workflow it already teaches:
128
128
 
@@ -162,6 +162,13 @@ reads the tool list once. ([#230](https://github.com/Kentucky-ai/opentakeoff/iss
162
162
  | `takeoff_summary` | Per-condition totals + grand totals, computed by the Report's rules. |
163
163
  | `export_takeoff` | The full `opentakeoff.takeoff_canvas.v1` payload—exactly what the app autosaves. Inline, and to disk with `path` (see **Writing to disk** below). |
164
164
  | `delete_shape` | Remove a committed shape by id. |
165
+ | `propose_takeoff` | **Open a named batch** (#365). Every shape you commit from here on attaches to it (`origin.proposal_id`, stamped centrally at the commit—hand traces, sweeps, derives, `cut_out` alike), so the estimator sees ONE Accept pill for the batch instead of one per shape. `label` is what they read on the pill, `rationale` is what decided the batch; both required. Commits nothing itself. |
166
+ | `revise_proposal` | Replace **every still-pending shape** in a batch with a new set, as one journal step. All-or-nothing: validated (sheet, scale, vertex minimum, a height for `surface_area`) before the first pending shape is removed, the error naming the entry. Accepted shapes are ink and stay. One `undo_last` puts the previous batch back. |
167
+ | `withdraw_proposal` | Remove a batch's pending shapes in one step; the record stays marked withdrawn, accepted shapes stay (the reply counts them). `undo_last` restores the whole batch. |
168
+ | `propose_condition_edit` | **Propose** a condition change instead of making it: a diff—new `finish_tag` (rename), `waste_pct`, `multiplier`, `height_ft`, `roll_setup`—held pending until the estimator accepts from the panel. Nothing changes until then: `takeoff_summary` and `export_report` compute from the current values and carry the diff beside them. Only differing fields are recorded; a no-op or a rename onto a taken tag is refused; one pending diff per condition (proposing again replaces it). `rationale` required. |
169
+ | `withdraw_condition_edit` | Drop a pending condition-edit diff without touching the condition. |
170
+ | `scope_duplicates` | **Two conditions claiming the same floor, as a list** (#366): every pair of committed floor shapes on one sheet whose EXACT polygon intersection exceeds `min_fraction` of the smaller (default 0.05), with the shared SF, each side's condition, label and review state, and a `look` region for `view_sheet {overlay: true}`. Different conditions = a collision (the floor is counted twice downstream); the same condition = a double trace, returned in `duplicates`. `shared_floor_sf` is Σ areas − union over the compared set, counted once per cell — the number `takeoff_summary` always carries. Deducts and runs are not claims; unscaled sheets and degenerate rings are `unmeasured`, never zero. Read-only. |
171
+ | `scope_merge` | **Resolve one collision**: given the pair and the winner, the loser gives up the shared floor — trimmed to its remainder (exact boolean difference, quantities re-measured) or deleted when the overlap is near-total (≥ 98% of the loser). One journal step; `undo_last` restores the loser verbatim. With `winner` omitted the reviewed shape wins; refuses when neither is reviewed (it does not guess), when both are (the estimator's call in the canvas), always when the loser is ink, when the trim would split the loser, and when the loser carries reconciled cutouts. |
165
172
  | `edit_shape` | **Revise** a committed shape instead of redoing it: new `verts`, a different `condition`, a different `role`, a `label` (the room it belongs to—what per-room reporting groups by; `""` clears it), or any combination—quantities recomputed from the result. Refuses shapes a human affirmed. |
166
173
  | `edit_materials` | Add/remove/patch supporting-materials rows on a condition—the coverage-rate lines (adhesive at N sf/gal, grout at N lf/bag, …) that turn a measured quantity into an order quantity, matching the canvas's Supporting Materials panel. `basis` is `area` \| `linear` \| `count` \| **`seam_lf`**—the last is the *figured* roll-layout seam length a weld rod or seam tape is bought by (set `roll_setup` on the condition first; without one it reads 0, because nothing has decided how that floor gets cut). `condition` mints on first touch, like `one_click`/`measure_polygon`. No review gate (materials rows are quantity config, not traced geometry)—edits directly, reversible with `undo_last`. |
167
174
  | `edit_condition` | Set a condition's **waste %**, **×N multiplier**, **height_ft** (the H knob `measure_surface` quantifies against), and **roll_setup** (the roll-goods opt-in: seams figured, cuts packed, the reply echoes the order—cuts, `order_lf`, rolls, `order_qty`—and `export_report`'s `roll_goods` block carries the same rows; `null` opts out)—the knobs that turn measured quantities into order quantities. Resolves an **existing** finish tag or errors—a typo must not mint an empty condition. No review gate; one `undo_last` step restores the knobs verbatim. |
@@ -171,7 +178,7 @@ reads the tool list once. ([#230](https://github.com/Kentucky-ai/opentakeoff/iss
171
178
  | `import_takeoff` | **The way back in**: load a `takeoff_canvas.v1` file (a prior `export_takeoff`, or the app's own save) through the SAME merge rules as the app's Sheet-menu import—finish-tag identity joins conditions (this session's knobs win), new ids append, duplicates skip (idempotent re-import), this session's calibration wins per sheet. Resume, extend, or audit. Correction rules (#88) ride the file too—`apply_rules` re-runs them. |
172
179
  | `apply_rules` | **Re-run the correction rules the takeoff arrived with** (#207)—the lessons an estimator TAUGHT the canvas (#88), for example, "every room like this loses the mechanical chase". Same pure `rules.ts` engine the canvas Preview runs; committed as the ONE batch its Apply makes (`reviewed: false`, one undo step, `origin {method rule_v1, actor rule}` with the rule/seed/room citation). The reply's per-rule disclosure—produced, skipped, ids—IS the preview an agent gets. Idempotent by construction: anything an existing deduct covers is dropped by the engine, so re-running after new rooms commit is the intended workflow. Rules arrive ONLY through `import_takeoff`; minting one is an estimator's correction and stays behind the canvas's human Preview→Apply gate. |
173
180
  | `export_dxf` | The takeoff as a **CAD drawing**—a DXF (R2000) that AutoCAD, BricsCAD, LibreCAD and Revit import as native geometry. One sheet per file, like a DWG: every committed shape becomes an `LWPOLYLINE` (floor rings closed, walls and linear runs open, counts a circle) on a layer named for its finish—`OT-<TAG>`, with `-DEDUCT` / `-HOLE` / `-WALL` / `-LINEAR` / `-COUNT` suffix layers and room labels on `OT-LABELS`. Real units in the sheet's frame (origin bottom-left, Y up; feet, or `units:"m"`), and a ring's CAD area equals its `export_report` area to rounding. Refuses without a scale; with several sheets carrying shapes, `sheet` picks the drawing. Names every shape left out and why. `path` required. |
174
- | `export_marked_pdf` | The **marked-up planset**—the deliverable. Writes a distribution-ready PDF: a legend cover (per-condition totals, swatches, by-sheet breakdown) plus every sheet that carries work, vector-copied from the source with shapes, hatches, per-shape quantity chips, and annotations burned in—built by the same module as the canvas's MARKED SET button. Machine-traced shapes are disclosed as pending human review on the document itself, and the cover states where the finish tags came from (`Finish assignment: N schedule-resolved · N agent-asserted · …`, plus any rooms the last assign run withheld). Default path: `<plan> - marked set.pdf` next to the plan (see **Writing to disk** below). Works without `@napi-rs/canvas`. |
181
+ | `export_marked_pdf` | The **marked-up planset**—the deliverable. Writes a distribution-ready PDF: a legend cover (per-condition totals, swatches, by-sheet breakdown) plus every sheet that carries work, vector-copied from the source with shapes, hatches, per-shape quantity chips, and annotations burned in—built by the same module as the canvas's MARKED SET button. Machine-traced shapes are disclosed as pending human review on the document itself, and the cover states where the finish tags came from (`Finish assignment: N schedule-resolved · N agent-asserted · …`, plus any rooms the last assign run withheld). Default path: `<plan> - marked set.pdf` next to the plan (see **Writing to disk** below). Works without `@napi-rs/canvas`. Refuses an **encrypted** source PDF (owner password, empty user password) with the sheet named — its pages cannot be vector-copied and the server has no canvas to render them; export from the app, or supply an unencrypted PDF. |
175
182
  | `list_shapes` | The **mid-session inventory**: every committed shape's id, sheet, condition, role, quantities, room `label`, review state, and assignment verdict (`schedule` \| `asserted`—where its finish tag came from) in one compact read—the ids `edit_shape`/`delete_shape` assume you have, without pulling the whole `export_takeoff` payload. Filters by sheet/condition narrow; empty is a result, not an error. |
176
183
  | `undo_last` | Step back over your own last `n` mutations, newest first. Exact inverses: a commit is removed, an edit restored verbatim, a delete re-inserted where it was, a materials edit's whole array restored, a condition edit's waste/multiplier pair restored. A whole `detect_rooms` sweep is **one** step. |
177
184
  | `annotate` | Place a note ABOUT the work—cloud/highlight (`rect`), text (`at`), callout (`at` + `target`), **arrow** (`from` + `to`—plank/seam direction), **bubble** (`at` + optional `r`—keynote circle, centered text), **dimension** (`from` + `to`—a dimension line with end ticks, labeled with the measured length at the sheet's scale; the one annotation the scale gate applies to—an unscaled sheet refuses like the measure tools). Attach to a condition and it wears that scope's color on the canvas and in the marked set. No review gate: notes are not geometry. |