opentakeoff-mcp 0.9.98 → 0.9.99

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
- **<!--tool-count-->53<!--/tool-count--> tools**. Everything else — sweeps, counts, `derive_base`, `derive_transitions`, the
47
+ **<!--tool-count-->58<!--/tool-count--> 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 (<!--tool-count-all-->55<!--/tool-count-all--> tools); the parity, conformance and e2e tests run that way, and
49
+ register both verbs (<!--tool-count-all-->60<!--/tool-count-all--> 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
 
@@ -123,7 +123,7 @@ includes document text, shape vertices, or result payload content.
123
123
 
124
124
  ### Staged tool exposure (opt-in)
125
125
 
126
- By default every client gets all <!--tool-count-->53<!--/tool-count--> tool schemas on `tools/list`—the flat
126
+ By default every client gets all <!--tool-count-->58<!--/tool-count--> tool schemas on `tools/list`—the flat
127
127
  contract every published client already expects. Fifty-two descriptions is real
128
128
  token weight for an agent session that may never touch half of them, so the
129
129
  server can instead stage the surface along the workflow it already teaches:
@@ -183,6 +183,9 @@ The [generated tool index](../docs/MCP_TOOL_INDEX.md) lists stages and required
183
183
  | `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. |
184
184
  | `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. |
185
185
  | `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. |
186
+ | `estimate_summary` | The **priced estimate** as data: one line per measured condition (unit, order and measured quantities, rates, costs, `status` priced / partial / unpriced with what is `missing`), then material, labor, sales tax, cost, overhead, profit and the base bid. `complete: false` means the total is *priced so far* and `unpriced` names every hole; report them, never fill them. Read-only. |
187
+ | `export_estimate` | The priced estimate as an **Excel workbook** (the canvas Estimate panel's Excel): Estimate, Materials and, when anything is unentered, Unpriced tabs; values only, unentered rates as empty cells, *Prepared with OpenTakeoff* on every tab. Default path beside the plan. |
188
+ | `export_proposal` | The **bid proposal PDF** (the canvas Proposal dialog): letterhead from `company` (pass what the estimator gave you), prepared-for, scope with measured quantities, base bid (lump sum or itemized to the cent), inclusions / exclusions / terms, signature blocks; the OpenTakeoff watermark on every page. Never refuses an incomplete estimate; `complete` and `unpriced` in the reply say what the base bid is missing. Default path beside the plan. |
186
189
  | `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. |
187
190
  | `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. |
188
191
  | `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. |
@@ -196,6 +199,8 @@ The [generated tool index](../docs/MCP_TOOL_INDEX.md) lists stages and required
196
199
  | `list_rfis` | Every RFI with status, sheet, who raised it (`actor`) and whether an agent-raised one is still `pending`, its linked markup ids, and the finish tags those markups touch. `withdrawn[]` names the numbers `delete_rfi` tombstoned, so a gap in the sequence is explained. |
197
200
  | `resolve_rfi` | Answer an **open** RFI: the answer lands as its response, status becomes `answered` (the register's own state), the response date stamps as the panel's would, plus an ISO `resolved_at`. Anything not open is refused—answered, closed, or void—rather than re-answered or revived. |
198
201
  | `delete_rfi` | Withdraw an RFI. A **tombstone, never a renumber**: the number stays reserved, the register and the marked set keep printing a gap where it was, and the next RFI takes the next number. Linked markups keep their note and lose the link (the canvas's own delete rule). `undo_last` puts the record and its links back. |
202
+ | `set_pricing` | Price one condition for the estimate (the canvas **Estimate** panel's row): `unit` (SF / SY / LF / EA), `material` and `labor` $ per unit, and `materials` [{name, price}] for its supporting-material rows per their own unit. Material prices the **order** quantity (waste applied), labor the **measured** one. `null` clears a price to *not entered*; `0` is an explicit $0. Prices come from the estimator, never from the agent. One `undo_last` step restores the condition's prices verbatim; they ride `export_takeoff` into the app. |
203
+ | `set_estimate_settings` | The project's **markups** (`tax_pct` on material, `overhead_pct`, `profit_pct` as a `markup` or a `margin`), **proposal** text and layout (`itemized`, `scope_note`, `inclusions`, `exclusions`, `terms`, `valid_days`) and **client** (name, address, reference): the canvas's `estimate_settings`, `bid_proposal` and `client_info`. Only what you pass changes; `undo_last` restores all three. |
199
204
  | `read_sheet_text` | Positioned page text (image px), optionally restricted to a region—title blocks, room labels, finish schedules. |
200
205
  | `find_text` | **Locate** a known string—the complement to `read_sheet_text` (which returns what a region *says*; this finds *where* a string sits). Case-insensitive substring match per pdf.js text run; each hit's center feeds straight into `one_click`'s seed. |
201
206
  | `sheet_graph` | The plan-set INDEX (#87): every sheet's role with evidence, the schedule tables found, every room tag with its stacked name, the detail callouts, and every revision marker (text `Δ2`/`REV 2` tags AND drawn deltas—a bare digit inside a triangle of linework, proven from the sheet's vector geometry—in `revisions`)—how an agent decides WHAT to measure without a human enumerating rooms. |