mahbot 0.8.0

An autonomous agentic engineering system that manages software development through role separation, subagents, and deterministic diagnostics.
Create and edit documents: write a new .docx/.xlsx/.pptx/.pdf, fill a user's own sample, edit an existing Office file, and edit PDF pages. Every action is data — a fixed operation over the values you pass — and every path you pass is {{input_location}}.

**Every action.** The file you pass is never modified: each call writes a new file into the workspace's `generated/` directory, whose name the tool owns — `file_name` is only a base name. Name every produced file in your reply with `[FILE:path]` — the media sweep deletes generated files that no session mentions. An input may be up to {{input_mb}} MB, and an embedded image's bytes must be PNG, JPEG or WebP — a PDF takes PNG or JPEG.

**Editing** (`docx_edit`/`xlsx_edit`/`pptx_edit`): an edit is applied whole or not at all, and every part it does not name — images, fields, headers and footers, comments, macros, anything else — is carried into the copy unchanged. An unsized picture is fitted whole into its page or slide — a picture placed in a sheet keeps its own size — while a named size is placed exactly as named, and the answer says when a placed picture reaches past the slide or page. Only the parts the edit names are rebuilt: styles, themes, a presentation's layouts and animations, charts and pivot tables are re-compressed as they were, so their look may not reflect the edit, and the answer names every loss the call found. A signature the file carried is invalidated.

**Documents.** A text op addresses a fragment of the document's own body text, matched inside one paragraph and never across paragraphs — every occurrence in every matching paragraph is rewritten, while `remove_paragraph` removes every paragraph holding it. A text box's own text and a table cell's are addressed; a header's, footer's, footnote's, endnote's, comment's, a field's cached result and a table of contents' own entries are not, and a fragment only they hold is refused as that part's text. A heading a table of contents lists keeps its text and level: an edit changing either is refused with the table named, while formatting it is not. What a reading prints around the text is the reader's, not the file's: the bracketed marks ({{docx_inline_marks}}), the labels it adds ({{docx_label_marks}}) and the indentation under a block are not text an edit addresses, so a fragment holding only one is refused for what it is. A tab and a line break a reading shows are markup (`<w:tab/>`, `<w:br/>`): a fragment holding one is refused, and a rewrite may not match across one. A fragment found nowhere is refused with the reason. A fragment or replacement is at most {{edit_text_max}} characters. Making a fragment bold, italic, underlined, struck through, sized or coloured formats its whole run; the answer says so. `add_image` and `add_table` place a picture or table after the first paragraph holding the text `after` names — a table cell's anchor means after the whole table — and a fragment the body does not hold is refused rather than appended at the end. A picture's `width`/`height` are points: one side alone keeps its proportions, and with neither named the picture is fitted whole into the page's text column.

**Sheets.** `set_cell` writes a value and leaves the cell's formatting alone. `format_cells` gives a table its look — the one op that changes how cells appear without touching what they hold — and a cell keeps the look its row and column give it. `clear_cell` empties a cell and keeps its formatting. `merge_cells` merges a range and never clears the covered cells' content; `unmerge_cells` names a range that must match a merge; a merge overlapping one already there is refused naming that merge, a range of one cell is refused as too small to merge, and `create`'s sheet takes `merges`, the ranges it writes merged. `add_sheet` appends a sheet; `rename_sheet`, `move_sheet` (a 1-based position) and `delete_sheet` change one; the workbook always keeps at least one visible sheet. A rename or removal does not rewrite formulas, defined names, chart series or links — they keep their text, and the answer names what it left pointing at a name that is gone. `xlsx_edit`'s `add_image` anchors a picture's top-left corner in the named cell, sized in points with its proportions kept, and with no side named at its own size; it only places pictures in an existing workbook (`create` writes none), and a picture placed this way is not moved by a later row or column insert or delete.

**Presentations.** A slide is its 1-based number as the reader shows it, and a text op names a fragment that must be on it — whitespace alone matches nothing. `add_table` adds a table to a slide after what is already there — `headers`/`rows` are its text, placed by the same fractions as `add_image`, and an unnamed size is the table's own — shrunk only as far as the slide forces, never grown. `create` lays out its content by the deck's own proportions. The labels and marks a reading prints — {{ppt_slide_label}}, {{ppt_notes_label}}, {{ppt_comments_label}}, {{ppt_title_mark}}, {{ppt_hidden_slide_mark}}, {{ppt_diagram_text_mark}}, {{ppt_diagram_text_lost_mark}} and {{ppt_no_text_mark}} — are that printing, not text on the slide, nor a diagram's text, which no edit changes, nor a comment's text, which no edit addresses, nor a slide's speaker notes: `replace_notes`, `remove_notes` and `add_notes` address those.

**Filling.** `fill_template` and `pdf_form_fill` substitute `values` keyed by name. A Word or PowerPoint sample is filled at its `{name}` placeholders; a spreadsheet cell by cell, where a cell holding exactly one placeholder takes a number as a number. Elsewhere a substitute is written as text and never becomes a formula. A placeholder you give no value is left as it was and reported back. A PDF's form fields are separate from its page content.

**PDF pages.** `pdf_text` and `pdf_image` change the pages they name: what they draw becomes page content rather than an annotation object, and existing text is never reflowed to make room. `pdf_rotate` adds a rotation to the pages it names and draws nothing. `pdf_crop` narrows the visible area to an `area` named in fractions of what the page currently shows, measured from the top-left as the page reads (rotation included): it changes only what is visible — nothing is removed — and an area outside the page or with no size is refused. `pdf_resize` names BOTH a `width` and a `height`: the content is fitted uniformly (never stretched), any spare strip is left blank, the page afterwards reads as the named size, and links and form widgets move with the content — an annotation that cannot follow is reported. `pdf_text` takes an `opacity` (just above zero to one) applied to the text and its stamp box; unnamed is fully opaque. Anything landing outside the page's visible area is drawn as asked, and the answer carries a note naming the page. A picture is turned with the page, so it reads upright on a page displayed at a rotation; drawn text and its stamp are not — they follow only their own `rotate` and read sideways on such a page. A `create` PDF whose content is pictures only gives each its own page, fitted whole, with no empty page before the first. A PDF's existing text is not addressable — there is no PDF find-and-replace.

**PDF files.** `pdf_merge` and `pdf_split` build a fresh document and carry only the pages: a document's description, bookmarks and named destinations, tags, page labels, embedded files and form fields — a merged form is no longer fillable — are not carried, while page content, rotation, annotations and the visible area are, and a carried link or annotation may name a page the new file does not have; a `metadata` object may describe the new file.

**PDF description.** Editing a PDF does not rewrite a description it does not name; an existing `modified` date advances to the write unless you name it, and no entry is invented for a file that carries none. A file the tool builds names `mahbot` as its producer.