opentakeoff-mcp 0.9.65 → 0.9.71

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
@@ -109,8 +109,8 @@ includes document text, shape vertices, or result payload content.
109
109
 
110
110
  ### Staged tool exposure (opt-in)
111
111
 
112
- By default every client gets all 40 tool schemas on `tools/list`—the flat
113
- contract every published client already expects. Forty descriptions is real
112
+ By default every client gets all 47 tool schemas on `tools/list`—the flat
113
+ contract every published client already expects. Forty-three descriptions is real
114
114
  token weight for an agent session that may never touch half of them, so the
115
115
  server can instead stage the surface along the workflow it already teaches:
116
116
 
@@ -118,7 +118,7 @@ server can instead stage the surface along the workflow it already teaches:
118
118
  OPENTAKEOFF_MCP_STAGED_TOOLS=1 npx -y opentakeoff-mcp
119
119
  ```
120
120
 
121
- Staged, only the **setup** stage (load, scale, read the set—10 tools) starts
121
+ Staged, only the **setup** stage (load, scale, read the set—11 tools) starts
122
122
  enabled, plus one opener: `open_tool_stage`. Calling it with `"measure"`,
123
123
  `"revise"`, or `"handoff"` enables that stage's tools and fires
124
124
  `tools/list_changed`, so any client that supports dynamic tool lists (Claude
@@ -167,12 +167,17 @@ reads the tool list once. ([#230](https://github.com/Kentucky-ai/opentakeoff/iss
167
167
  | `link_annotation` | Attach an existing annotation to a condition (or detach with an empty tag)—the canvas's Attach/Detach control, reachable by an agent. |
168
168
  | `mark_verdict` | The **agent's pencil-signature** on work it checked—the agent half of the approval family (#176). Mints the graphite AGENT diamond, and structurally nothing else: the tool takes no actor input, so the estimator's APPROVED ring stays behind the canvas's human-only Approve tool. Target a committed `shape_id` (anchored on the shape—a room's centroid, a run's midpoint—with the id recorded as provenance) or a `sheet` + `at` point; optional short `text` rides the record. Touches no quantity; renders on the canvas and in the marked set, whose cover tallies the split (`Approval stamps: N estimator-approved · M agent-marked`); rides the annotations payload through `export_takeoff`/`import_takeoff` and the app's own saves. One mark per shape. |
169
169
  | `delete_verdict` | Lift an agent verdict mark by id. Agent marks only—the estimator's seal is human ink and is refused, the same line `edit_shape` holds on reviewed shapes. `undo_last` re-seats a lifted mark exactly where it was. |
170
+ | `create_rfi` | **Raise an RFI** (#364)—a Request For Information—when the drawing set contradicts itself: a schedule row the plan never draws, a room the schedule has no row for, a finish called out two ways. Lands in the canvas's RFI register with the **next number in the register's own sequence**, status open, dated today, on the sheet you name; `markup_ids` pins it to annotations already on the sheet (they carry the RFI number on the canvas and in the marked set). Raised **as the agent**: `origin {actor: "agent", reviewed: false}`—PENDING in the register until the estimator accepts it there, because an RFI goes to the architect and nothing sends without a human. Prints in the marked set's RFI schedule like any other RFI. Journaled; `undo_last` takes it back. |
171
+ | `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. |
172
+ | `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. |
173
+ | `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. |
170
174
  | `read_sheet_text` | Positioned page text (image px), optionally restricted to a region—title blocks, room labels, finish schedules. |
171
175
  | `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. |
172
176
  | `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. |
173
177
  | `resolve_tag` | ONE room tag → its room-finish schedule row → each code's finish/material definition, every edge cited (sheet + literal text + bbox). Refusal over guessing: `unresolved` comes back with a reason, never as silence. A delta/REV marker on the answering row rides the result as `revisions`—the codes are the post-revision answer, and you're told the ink changed. |
174
178
  | `find_schedule` | Locate a schedule table by kind ("room finish", "material")—sheet, title, headers, row count, a `view_sheet`-ready region, and `revised_rows` when delta/REV-marked rows exist. |
175
179
  | `sheet_context` | The region's STRUCTURE in one frame: classified vector segments (endpoints as drawn, meta byte per segment), text spans with bboxes, and hatch-family instances with content-derived ids—same pattern spec ⇒ same id anywhere on the sheet, so plan↔legend matching is `id === id`. Decimation is declared and counted on every reply: `kept + dropped === total_in_region`, cap applies longest-first so walls survive. |
180
+ | `get_sheet_vectors` | The STROKES (#367): the sheet's vector layer exactly as the engine is fed it—flat `[x1, y1, x2, y2, …]` points in image px, one meta byte per segment (curve / clip / fill-only / polyline-arc flags, pen width in the high nibble), per-segment stroke luminance, the drawn figure each segment belongs to, the placed-image area, and the PDF layer table with a per-segment layer index. Nothing classified, decimated, or merged—so a reader can run its own room finder, symbol matcher, or wall classifier against the same array and commit through the existing verbs. Paged (default 20,000 segments, ceiling 100,000) with `offset + returned + dropped === total` on every page; `next_cursor` recovers exactly what `dropped` counts. Read-only and stateless. Refuses on a scan and names `view_sheet` as the path. |
176
181
  | `view_sheet` | The agent's eyes: render the sheet (or an image-px crop) to PNG. `overlay` burns committed shapes in (solid = human-affirmed, dashed = unreviewed) to verify geometry landed; `grid` burns in a calibrated 1-ft/5-ft measuring grid with foot labels (`"auto"` from the set scale, or the drawing scale like `"1/4"`) so dimensions are counted off cells, not guessed; `marks` (#297) burns disclosure layers in — `question` (withheld placements, orange ?-circle), `struck` (rejections, magenta struck ×), `ring` (the sweep's seed, violet double ring) — in colors off the common CAD pens, so what a reply names, the picture shows. |
177
182
 
178
183
  ### The agent revises its own work