English · 中文
Office Transforms · Tracked · Edited & Reviewed · surgical Patch write-back. Circle a region, describe the change, review each edit, then write back to the original format.
Development preview (
0.0.1). The safety boundaries described below are enforced in code, but format support is intentionally narrow and the API may still change. Keep a backup of any important document and check the capability table before relying on a workflow.
Product scope: Excel and Word are the active product mainline. drawio remains a secondary compatibility integration and is not a feature-expansion target. PDF support has been removed. The retained PPTX adapter is frozen and explicit opt-in only; stock runtime, desktop, MCP, HTTP, and CLI surfaces do not expose it.
An agent never receives a general-purpose file mutation tool. It may answer, ask for clarification,
or propose one structured ChangeSet. OtterPatch then:
- keeps document content in an explicitly untrusted user-data envelope;
- validates the ChangeSet schema, semantics, resource budgets, and format capability manifest;
- runs the strongest available deterministic proposal check and builds a reviewable diff;
- signs a proposal bound to the ChangeSet, format, policy, source SHA-256, and revision;
- commits only the edit IDs in a signed, expiring, single-use review receipt;
- serializes writes per document, applies the selected backend, reopens the output, and requires a structured verification report before returning bytes to the host.
For the active OOXML writers and uncompressed drawio, surgical write-back changes only intended
package parts or diagrams. On a 531 KB .docx fixture, 30 of 31 package parts remained
byte-identical.
The capabilities-v2 manifest in packages/core/src/capabilities.ts
is the source of truth for availability, lifecycle, proposal, preview, verification, and
write-back gates.
| Format | Availability | Current write-back operations | Proposal preview/check | Important boundary |
|---|---|---|---|---|
Excel (xlsx) |
mainline, default | value, formula, style, number format, clear range | headless grid shadow and deterministic simulation | supported formula subset only; unknown functions, cycles, missing observations, and oversized ranges fail closed; post-commit read-back verifies each edit's effect (values, formulas, formats, cleared cells) |
Word (docx) |
mainline, default | anchored text replacement/deletion, scoped character and paragraph style, page columns/margins/orientation, image remove/resize, table insertion | unique quote/paragraph anchor checks; rich preview is rendered by the desktop host | writes native revisions in word/document.xml; post-commit read-back accepts every revision and verifies each edit's observable effect |
| drawio | secondary compatibility, default | label/property updates, move, add, delete | headless board replay and topology verification | only uncompressed diagrams; identity/topology fields are constrained; no planned feature expansion |
PowerPoint (pptx) |
frozen, opt-in | unique single-run text replacement | exact slide/paragraph/run boundary check | retained for explicit host registration only; absent from every stock product surface |
PDF is unsupported and no longer exists as an adapter, dependency, Agent dialect, skill, schema, or write-back test. It is not an experimental product option.
Unsupported operations are hidden from the model and rejected again at runtime. A host cannot make them available by constructing a plausible-looking ChangeSet.
Prerequisite: Node.js 22 and npm.
npm ci
npm run typecheck
npm test
npm run buildUse two terminals:
# Terminal A: build TypeScript, start the loopback HTTP service, print one-time local tokens
npm run serve
# Terminal B: start the Vite cockpit at http://localhost:5173
npm run devIn the cockpit model settings, enter a provider API key and the Local service token and
Review token printed by npm run serve. Browser-development tokens are stored only for the
local Vite origin and must be updated when a service restart generates new values. Every local
POST requires X-OtterPatch-Token; /review additionally requires
X-OtterPatch-Review-Token. GET /health is the only anonymous endpoint.
To pin development credentials or origins instead of generating defaults:
OtterPatch_TOKEN
OtterPatch_REVIEW_TOKEN
OtterPatch_ALLOWED_ORIGINS
OtterPatch_PORT
OtterPatch_REVIEW_STATE_DIR # shared review-authority store (multi-process deployments)
OtterPatch_AUDIT_DIR # durable commit audit ledger ("merged PR" records)
OtterPatch_SKILLS_DIR # external skill directory (demonstration-distilled skills)
OtterPatch_AUDIT_DIR turns on the append-only commit audit ledger: every commit
(reviewed or the explicitly-enabled unreviewed kind) appends one JSONL record per
document — reviewer session, accepted edit ids, source→output SHA-256, backend, and
the verification outcome. The runtime never reads it back for control flow; it is
evidence for after-the-fact audit and a Git-like commit history for hosts to display.
Keep the directory private to the service user.
OtterPatch_REVIEW_STATE_DIR points the service at a shared ReviewAuthorityStore
(FileReviewAuthorityStore): the HMAC secret, consumed receipt nonces, and committed-source
ledger live in that directory, so receipts minted by one service instance verify and
replay-block in another. Without it the review authority stays process-local. Keep the
directory private to the service user — it contains the signing secret.
OtterPatch_ALLOWED_ORIGINS accepts only exact loopback HTTP(S) origins or null, separated by
commas. The service always binds to 127.0.0.1.
npm run build
npm run app --workspace @otterpatch/desktop
# Build an unpacked installer directory
npm run app:pack:dir --workspace @otterpatch/desktopElectron starts the local service itself. Service and review tokens stay in the main process; the sandboxed renderer receives only bounded propose, cancel, and reviewed-commit IPC methods.
apps/mcp-server exposes the same runtime through MCP stdio, a headless CLI, and the local HTTP
bridge. These stock surfaces accept only Excel, Word, and drawio formats (including xlsx/docx
aliases).
otterpatch_skills list immutable built-in skill metadata
otterpatch_propose intent + trusted request identity + read-only snapshot -> ChangeSet, diff, signed proposal
otterpatch_diff ChangeSet + host snapshot -> shadow-derived diff or an explicit unavailable reason
otterpatch_commit source file + ChangeSet + signed proposal + review receipt -> verified output
The stock MCP stdio surface does not mint a human review receipt. A host that embeds
@otterpatch/runtime can use its own trusted review UI and the same ReviewAuthority; a plain
stdio client can propose and diff, but cannot use the default reviewed commit by itself. The
HTTP/Electron path is the complete built-in reviewed flow. Unreviewed MCP commit is off by default
and can only be enabled explicitly with OTTERPATCH_ALLOW_UNREVIEWED_COMMIT=1; even then,
acceptedEditIds and a live currentRev are required.
Build and register the stdio entry point with an MCP client:
{
"mcpServers": {
"otterpatch": {
"command": "node",
"args": ["/absolute/path/to/otterpatch/apps/mcp-server/dist/mcp.js"],
"env": { "OtterPatch_API_KEY": "your-provider-key" }
}
}
}Run an explicitly confirmed headless pass:
npm run run --workspace @otterpatch/mcp-server -- \
--yes --format excel --intent "fill amount = quantity * price" \
--in book.xlsx --out book.out.xlsxWithout --yes, the CLI emits the proposal and diff but refuses to write a file.
When --out points at an existing file, the CLI backs it up to --out.bak first (disable with
--no-backup) and then replaces it atomically: the bytes land in a temp file that is renamed
over the target, so a crash mid-write can never leave a half-written document.
FidelityReport.score remains only as a compatibility alias for locality. Consumers should use
the structured dimensions:
verification.packageValid
verification.locality intended parts, unexpected parts, unchanged outside-part ratio
verification.semantic verified, unverifiable, and failed edit IDs
verification.compatibility explicit format/backend warnings
Runtime rejects legacy or edit-incomplete reports, invalid packages, and unexpected drift. It returns the final read-back report, not the backend's optimistic commit-time estimate.
Built-in skills are immutable capability cards; the flywheel (design.md 创新点②) closes the
loop: after a reviewed commit, the desktop offers 保存为技能 — the demonstration
(intent + accepted ChangeSet) is distilled deterministically (no model call) into an external
SKILL.md under OtterPatch_SKILLS_DIR and installed into the live library, so similar
future requests match it automatically. Distillation output is validated by the SKILL.md
parser before install; external skills stay untrusted tool-result data.
packages/core/ ChangeSet, validation, capability, risk, limits, adapter contracts
packages/agent/ bounded multi-provider agent loop, read tools, provenance
packages/skills/ immutable built-ins, generated playbooks, external-skill isolation
packages/adapter-univer/ Excel shadow, verifier, and worksheet compiler
packages/adapter-word/ Word anchors, native redlines, style/page/table/image write-back
packages/adapter-drawio/ mxCell model, topology verifier, diagram write-back
packages/adapter-pptx/ frozen opt-in single-run slide-text writer (not stock-registered)
packages/writeback-surgical/ budgeted OOXML read/repack and locality verification
packages/runtime/ adapter-owned propose/diff/review/commit orchestration
apps/mcp-server/ MCP, CLI, and authenticated loopback HTTP service
apps/desktop/ Vite/React cockpit and sandboxed Electron shell
Start at docs/:
architecture · security ·
agent loop · skills ·
review UX · testing ·
Word OOXML notes
