revise 2.2.0 → 3.0.0

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.
Files changed (134) hide show
  1. package/CHANGELOG.md +47 -1182
  2. package/LICENSE +24 -41
  3. package/README.md +103 -26
  4. package/agent.d.ts +139 -0
  5. package/chunks/chunk-U5X47PZ6.js +135 -0
  6. package/chunks/chunk-U6YKQBKL.js +15 -0
  7. package/chunks/chunk-ZLQVPMBN.js +1650 -0
  8. package/chunks/package-5SHL5FOJ.js +14 -0
  9. package/chunks/render-QD5VWKSV.js +109 -0
  10. package/cli-output.schema.json +1984 -0
  11. package/cli.js +3604 -0
  12. package/document.d.ts +320 -0
  13. package/docx.d.ts +73 -0
  14. package/errors.d.ts +14 -0
  15. package/index.d.ts +13 -975
  16. package/index.js +31 -1
  17. package/legacy/editor.d.ts +19 -0
  18. package/legacy/editor.js +16 -0
  19. package/legacy/server.d.ts +37 -0
  20. package/legacy/server.js +25 -0
  21. package/legacy/style.css +2 -0
  22. package/package.d.ts +23 -0
  23. package/package.json +49 -55
  24. package/render.d.ts +27 -0
  25. package/FONT-LICENSE-HAN-EXT-B.txt +0 -91
  26. package/FONT-LICENSE-KATEX.txt +0 -95
  27. package/FONT-LICENSE-LIBERATION.txt +0 -102
  28. package/FONT-LICENSE-NOTO-MULTILINGUAL.txt +0 -93
  29. package/FONT-LICENSE-NOTO-SANS-SC.txt +0 -93
  30. package/FONT-LICENSE-NOTO.txt +0 -94
  31. package/FONT-LICENSE-SOURCE-CODE-PRO.txt +0 -94
  32. package/FONT-LICENSE-SOURCE-SERIF-4.txt +0 -93
  33. package/THIRD-PARTY-NOTICES.md +0 -3376
  34. package/assets/historyMaterializeWorker-B51R08XN.js +0 -612
  35. package/backend.d.ts +0 -161
  36. package/backend.js +0 -3
  37. package/chunks/AgentPageRenderer-CH8kSTJn.js +0 -1
  38. package/chunks/AgentPageRenderer-P23XVguo.js +0 -1
  39. package/chunks/AttachmentDocumentImporter-B1WOaa7d.js +0 -1
  40. package/chunks/AttachmentDocumentImporter-CT_PJp_e.js +0 -1
  41. package/chunks/BidiText-Swm5fl9J.js +0 -160
  42. package/chunks/ColorParserFull-BKH72fK8.js +0 -446
  43. package/chunks/DocumentMutator-btiDK57e.js +0 -31
  44. package/chunks/DocumentScrubber-CMPfm_HF.js +0 -18
  45. package/chunks/DocumentScrubber-Cm2kH8op.js +0 -1
  46. package/chunks/DocumentScrubber-bJoKijol.js +0 -1
  47. package/chunks/DocumentStylesheet-DreoD7sD.js +0 -7
  48. package/chunks/DocxConverter-BcVG-p5K.js +0 -13
  49. package/chunks/DocxConverter-D2bO5RE-.js +0 -1125
  50. package/chunks/DocxConverter-haCfRuWb.js +0 -13
  51. package/chunks/DocxGraft-BRKh4mHQ.js +0 -1
  52. package/chunks/DocxGraft-BxSQtl12.js +0 -7
  53. package/chunks/DocxGraft-C9MBQCnf.js +0 -1
  54. package/chunks/FileImporter-CszqRfVU.js +0 -1
  55. package/chunks/FileImporter-DObFoCCn.js +0 -1
  56. package/chunks/HorizontalRuleOrnaments-gmUZ3R7Q.js +0 -3
  57. package/chunks/HtmlConverter-DwXB4IDh.js +0 -267
  58. package/chunks/ListNumbering-Qlu6AuRZ.js +0 -23
  59. package/chunks/MarkdownConverter-CUC8GgsS.js +0 -57
  60. package/chunks/MathRenderer-DT6GyJXb.js +0 -68
  61. package/chunks/OdtConverter-7h9HHMpL.js +0 -125
  62. package/chunks/OdtConverter-Ct4qypJk.js +0 -6
  63. package/chunks/OdtConverter-DFl__sJc.js +0 -6
  64. package/chunks/OfficeImportShared-BY6FdZ8d.js +0 -1
  65. package/chunks/OfficeImportShared-BrZoDM0j.js +0 -30
  66. package/chunks/OfficeImportShared-Bvm-mOyj.js +0 -1
  67. package/chunks/ParagraphDiffAnalysis-DrmStvmz.js +0 -36
  68. package/chunks/PdfConverter-1wyvoT7X.js +0 -21
  69. package/chunks/PdfConverter-BAoEHILo.js +0 -21
  70. package/chunks/PdfConverter-CKEvFj11.js +0 -448
  71. package/chunks/PdfImportService-BhLPp5uG.js +0 -2
  72. package/chunks/PdfImportService-xbzrN__L.js +0 -2
  73. package/chunks/RtfConverter-Bxn-enp8.js +0 -15
  74. package/chunks/RtfConverter-LZPzBDSr.js +0 -15
  75. package/chunks/RtfConverter-_bacXqr1.js +0 -186
  76. package/chunks/TableBorders-CwnF3jvH.js +0 -30
  77. package/chunks/TableGrid-DbroRucl.js +0 -12
  78. package/chunks/TextFileDecoder--rsVs3NR.js +0 -9
  79. package/chunks/TxtConverter-C7FOwHpH.js +0 -14
  80. package/chunks/UnicodeUtils-CXtusU4g.js +0 -10
  81. package/chunks/XmlConverter-7oo8oeQB.js +0 -2
  82. package/chunks/XmlConverter-DGORHJcZ.js +0 -96
  83. package/chunks/XmlConverter-DeLHReK_.js +0 -2
  84. package/chunks/__vite-browser-external-l0sNRNKZ.js +0 -0
  85. package/chunks/_commonjsHelpers-DaMA6jEr.js +0 -2
  86. package/chunks/_revise-sdk-lazy-harfbuzz-CDWdjF9f.js +0 -1
  87. package/chunks/_revise-sdk-lazy-harfbuzz-X8gnYTZL.js +0 -1
  88. package/chunks/ar-ComXvtmh.js +0 -13
  89. package/chunks/backend-DecaBz-I.js +0 -490
  90. package/chunks/base64-sSPOzq-u.js +0 -198
  91. package/chunks/browser-module-CFmqfGkE.js +0 -1791
  92. package/chunks/browser-module-Dj5o3kuL.js +0 -3
  93. package/chunks/browser-module-UuM_O36W.js +0 -3
  94. package/chunks/bundle.min-DRpfgV69.js +0 -782
  95. package/chunks/capture-1btcWcPF.js +0 -9
  96. package/chunks/carrier-DQeng6yq.js +0 -6
  97. package/chunks/de-BkbpIKxx.js +0 -13
  98. package/chunks/es-CKkXujOF.js +0 -13
  99. package/chunks/fil-piIHMc8F.js +0 -13
  100. package/chunks/footnoteFlatten-DUQticYy.js +0 -6
  101. package/chunks/fr-DuA8qLje.js +0 -13
  102. package/chunks/graftExport-CYnStOdU.js +0 -82
  103. package/chunks/html2canvas.esm-CntiHiYW.js +0 -997
  104. package/chunks/index-2TBhRkX7.js +0 -387
  105. package/chunks/index-BWdRWxoH.js +0 -1807
  106. package/chunks/index-Bf14eTEW.js +0 -1096
  107. package/chunks/index-BwcX_r62.js +0 -387
  108. package/chunks/index.es-CI0QPo8w.js +0 -780
  109. package/chunks/index.es-CI7cDExj.js +0 -5
  110. package/chunks/index.es-DHpGt6Y5.js +0 -5
  111. package/chunks/ja-DgrSs555.js +0 -13
  112. package/chunks/jspdf.es.min--GshOuIm.js +0 -77
  113. package/chunks/jspdf.es.min-DU74zN8b.js +0 -1792
  114. package/chunks/jspdf.es.min-DurJZ1zW.js +0 -77
  115. package/chunks/jszip.min-CPW0h1Kx.js +0 -476
  116. package/chunks/katex-DWj8TvwO.js +0 -1462
  117. package/chunks/pdf-BLWDCiFF.js +0 -1828
  118. package/chunks/persistInlineDocumentImages-DQj2iaqg.js +0 -1
  119. package/chunks/pseudoLocale-BoYTjmiK.js +0 -1
  120. package/chunks/pseudoLocale-DG2NnZmz.js +0 -1
  121. package/chunks/purify.es-BwLardii.js +0 -107
  122. package/chunks/serverDocumentSession-CJ1EH3Tp.js +0 -15
  123. package/chunks/signatures-Bwt_OGik.js +0 -17
  124. package/chunks/suggestionAuthorship-B-IuLQlE.js +0 -1
  125. package/chunks/tree-sitter-D6zWWUMP.js +0 -4
  126. package/chunks/wasmInline.generated-CBYFkdSM.js +0 -1
  127. package/chunks/web-tree-sitter-BXGZGnNj.js +0 -2
  128. package/chunks/zh-9OF3SWWO.js +0 -13
  129. package/full.js +0 -1
  130. package/root.d.ts +0 -5
  131. package/root.js +0 -2
  132. package/serverToolContract.d.ts +0 -391
  133. package/serverToolInputs.generated.d.ts +0 -250
  134. package/style.css +0 -1
package/LICENSE CHANGED
@@ -1,41 +1,24 @@
1
- # Revise SDK License
2
-
3
- Version 1.0
4
-
5
- Copyright © 2026 Migraine, Inc. (“Revise”). All rights reserved.
6
-
7
- By using the Revise SDK and accompanying documentation (“SDK”), you agree to these terms.
8
-
9
- ## Free use
10
-
11
- Revise grants you a nonexclusive, worldwide, royalty-free license to copy, run, and integrate the SDK for:
12
-
13
- - **Evaluation:** Development, testing, and prototyping, including for planned commercial applications, without prior permission or a time limit. Evaluation excludes production use.
14
- - **Personal noncommercial apps:** Production apps run by an individual that do not generate revenue and are not intended to monetize, promote a paid offering, or support the operations of any organization.
15
- - **Education:** Production use by accredited nonprofit or public schools, colleges, and universities for teaching, learning, research, and their own internal operations.
16
-
17
- ## Commercial use and source access
18
-
19
- Production use by businesses, nonprofit organizations, and government entities, whether internal or customer-facing, and all other production use outside the free permissions above, requires a separate written commercial license **before deployment**, including paid, subscription, ad-supported, and commercially intended apps that are temporarily free or not yet earning revenue. Obtain a license before converting a free permitted use to commercial use.
20
-
21
- Unpublished source code is not included. Source code access requires a separate commercial agreement expressly granting it.
22
-
23
- Please contact [sdk@revise.io](mailto:sdk@revise.io) for a commercial agreement.
24
-
25
- ## Distribution and restrictions
26
-
27
- You may bundle, minify, host, and distribute the compiled SDK within permitted apps, including to browsers. Preserve copyright and license notices. Recipients may run the embedded SDK within those apps. Standalone SDK resale, sublicensing, or redistribution—including reusable SDK wrappers—is prohibited without written permission.
28
-
29
- Except to the extent applicable law expressly permits despite this restriction, you may not decompile, disassemble, reverse engineer, or modify the SDK, or attempt to derive its source code, algorithms, or internal structure. Configuring the SDK through its documented options is not modification. Revise retains ownership and all ungranted rights, and this license grants no rights to Revise names or logos except to identify the SDK; you retain your apps and documents. Third-party components retain their separate licenses.
30
-
31
- The SDK sends an anonymous usage ping as described in its documentation; you may disable it.
32
-
33
- ## Termination
34
-
35
- A material breach terminates your rights and requires you to stop using and distributing the SDK. Rights are reinstated if a first breach is fully cured within 30 days of written notice.
36
-
37
- ## Warranty and liability
38
-
39
- TO THE EXTENT PERMITTED BY LAW, THE SDK IS PROVIDED “AS IS,” WITHOUT WARRANTIES, INCLUDING MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NONINFRINGEMENT, AND WITHOUT ANY SUPPORT OBLIGATION. REVISE AND ITS LICENSORS ARE NOT LIABLE FOR LOST PROFITS, LOST DATA, OR INDIRECT, INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES. THEIR TOTAL LIABILITY UNDER THIS LICENSE WILL NOT EXCEED US $100.
40
-
41
- Ownership, restrictions, and warranty/liability provisions survive termination. A separate written agreement controls conflicting terms. Invalid provisions do not invalidate the remainder. Each version of the SDK is licensed under the license included with it. This license is governed by the laws of the State of Delaware, USA, excluding its conflict-of-laws rules.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Migraine, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ This package depends on @reviseio/engine, which is distributed separately
24
+ under its own license (free for any use, including commercial).
package/README.md CHANGED
@@ -1,42 +1,119 @@
1
1
  # revise
2
2
 
3
- A document editor library for React apps, with full DOCX support and tools for AI agents.
3
+ The swiss army knife for documents. Read, edit, and redline Word documents
4
+ from the command line or from TypeScript. Edits land as tracked changes, with
5
+ comments, review, and undo, and untouched content is written back to the
6
+ .docx byte for byte. Built for AI agents and the programs that run them.
7
+
8
+ **Using a coding agent?** Paste this into it:
9
+
10
+ ```text
11
+ Read https://revise.io/skills/cli.md and follow it.
12
+ ```
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ npm i -g revise # or: npx revise <command>
18
+ ```
19
+
20
+ Node 20 or newer. No account, API key, or telemetry, and documents never
21
+ leave your machine. Two things fetch over the network: PDF export downloads
22
+ its fonts from revise.io, and an image you insert by URL is downloaded.
23
+
24
+ ## The CLI
25
+
26
+ Every command names its file. Edits save the file in place.
4
27
 
5
28
  ```bash
6
- npm i revise
29
+ revise outline contract.docx # headings with block ranges
30
+ revise read contract.docx 0 # blocks as HTML, with ids
31
+ revise replace-text contract.docx "Provider" "Northstar" # tracked change
32
+ revise changes contract.docx # what's pending
33
+ revise reject contract.docx --section 8 # review by section
34
+ revise export contract.docx contract.pdf # .docx .pdf .md .html .txt
35
+ revise compare v1.docx v2.docx --out redline.docx # redline two versions
36
+ revise undo contract.docx
37
+ ```
38
+
39
+ `revise tools` lists the editing tools (insert, replace, move, tables,
40
+ comments, footnotes, styles, headers and footers…) and `revise call` runs
41
+ one with JSON input. `--author "Legal bot"` signs tracked changes, `--out
42
+ copy.docx` saves an edit as a new file, and `-` reads or writes a pipe
43
+ (`cat notes.md | revise convert - notes.docx`). `--json` on any command prints
44
+ one versioned object ([contract](https://revise.io/developer/docs/revise/json)).
45
+ `revise examples` shows more.
46
+
47
+ ## Agent skills
48
+
49
+ The skill teaches a coding agent the CLI: reading by block id, tracked edits,
50
+ review, creating documents, and the `xml` escape hatch.
51
+
52
+ | Agent | Install |
53
+ | --------------------------------- | ------------------------------------------------------------------------------------------------- |
54
+ | Claude Code | `claude plugin marketplace add reviseio/skills`, then `claude plugin install revise@revise` |
55
+ | Codex, ChatGPT desktop | `codex plugin marketplace add reviseio/skills`, then `codex plugin add revise@revise` |
56
+ | Cursor, Copilot, Windsurf, Cline… | `npx skills add reviseio/skills --skill revise` |
57
+ | Anything else | `revise skill install` (into `.agents/skills` or `.claude/skills`), or `revise skill` to print it |
58
+
59
+ Building a browser editor instead? The `revise-editor` skill covers
60
+ [`@reviseio/editor`](https://www.npmjs.com/package/@reviseio/editor):
61
+ `npx skills add reviseio/skills --skill revise-editor`.
62
+
63
+ ## The library
64
+
65
+ ```ts
66
+ import { ReviseDocument } from "revise";
67
+
68
+ const doc = await ReviseDocument.open("contract.docx", { author: "Legal bot" });
69
+ await doc.replaceText("Provider", "Northstar"); // tracked changes
70
+ await doc.reject({ section: "8" });
71
+ const { bytes, fidelity } = await doc.export({ format: "docx" });
72
+ doc.dispose();
73
+ ```
74
+
75
+ Run the editing tools with typed input, or hand them to a model:
76
+
77
+ ```ts
78
+ import Anthropic from "@anthropic-ai/sdk";
79
+ import { ReviseDocument, agentTools } from "revise";
80
+
81
+ const doc = await ReviseDocument.open("brief.docx");
82
+ const { tools, handle } = agentTools(doc, { provider: "anthropic" });
83
+ const client = new Anthropic();
84
+ // Pass `tools` to client.messages.create(); answer each tool_use block in
85
+ // the response with `await handle(block)`, which returns its tool_result.
7
86
  ```
8
87
 
9
- ![The Revise editor embedded in a host application](https://developer.revise.io/images/revise-sdk-editor.png)
88
+ ### Collaboration servers
10
89
 
11
- ## Getting started
90
+ Seed a sync server's room from a file, and edit or export the live room:
12
91
 
13
- Get started with the [quickstart guide](https://developer.revise.io/editor-sdk/quickstart).
92
+ ```ts
93
+ import { ReviseDocument, seedYDoc } from "revise";
14
94
 
15
- ```tsx
16
- import ReviseEditor from "revise/editor";
17
- import "revise/style.css";
95
+ // e.g. Hocuspocus onLoadDocument: safe on every connection
96
+ await seedYDoc(room, "contract.docx");
18
97
 
19
- export function DocumentPane({ file }: { file: File }) {
20
- return (
21
- <ReviseEditor
22
- initialDocuments={[{ id: "contract-1", title: "Contract", source: file }]}
23
- onChange={(documentId, document) => {
24
- console.log(documentId, "now has", document.children.length, "blocks");
25
- }}
26
- />
27
- );
28
- }
98
+ const doc = await ReviseDocument.fromYDoc(room, { author: "Review bot" });
99
+ await doc.tools.call("replace", {
100
+ /* ... */
101
+ });
102
+ const { bytes } = await doc.export({ format: "docx" });
29
103
  ```
30
104
 
31
- The editor sends Revise one anonymous ping per page load, with its version and
32
- no user data or document content. Pass `telemetry={false}` to turn it off.
105
+ The browser editor for the same documents is
106
+ [`@reviseio/editor`](https://www.npmjs.com/package/@reviseio/editor).
107
+
108
+ ## Docs
33
109
 
34
- Refer to the [SDK Docs](https://developer.revise.io/editor-sdk) for the full editor API, including agentic tool calling.
110
+ - [revise.io/developer/docs](https://revise.io/developer/docs)
111
+ - [Build with AI](https://revise.io/developer/docs/build-with-ai): skills,
112
+ plugins, and Markdown versions of every page
113
+ - [Changelog](https://revise.io/developer/docs/revise/changelog)
35
114
 
36
115
  ## License
37
116
 
38
- Revise is closed-source software, free for evaluation, personal projects, and
39
- education. Production use by businesses, nonprofits, and government requires a
40
- commercial license: see [LICENSE](./LICENSE) and
41
- [developer.revise.io/editor-sdk/license](https://developer.revise.io/editor-sdk/license),
42
- or email [sdk@revise.io](mailto:sdk@revise.io).
117
+ MIT. `revise` runs on [`@reviseio/engine`](https://www.npmjs.com/package/@reviseio/engine),
118
+ Revise's document engine, which is installed with it and is free for any use,
119
+ including commercial, under its own license.
package/agent.d.ts ADDED
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Revise's editing tools for your own agent loop, in the shape each model
3
+ * API expects: hand `tools` to the model, pass each tool call it makes to
4
+ * `handle`, and send back what `handle` returns.
5
+ *
6
+ * const agent = agentTools(doc, { provider: "anthropic" });
7
+ * const reply = await anthropic.messages.create({ model, tools: agent.tools, messages });
8
+ * const results = await Promise.all(
9
+ * reply.content.filter((b) => b.type === "tool_use").map(agent.handle),
10
+ * );
11
+ * messages.push({ role: "assistant", content: reply.content }, { role: "user", content: results });
12
+ *
13
+ * OpenAI Responses: pass `agent.tools` as `tools`, append every output item
14
+ * the model returned (reasoning and function_call items included) to your
15
+ * input, then the `function_call_output` items `handle` returns, and call
16
+ * again until the model stops calling tools.
17
+ *
18
+ * No model SDK is a dependency: plain objects in, plain objects out. Every
19
+ * call runs on the document's one tool session, so reads, searches, and
20
+ * edits share context across turns, and calls run one at a time (parallel
21
+ * tool calls are safe; they queue). The session remembers what the model
22
+ * has read: when your host compacts or drops the transcript, call
23
+ * `reset()` so it stops assuming the model still has that text. Tool
24
+ * descriptions mention "turns": here a turn is one model response.
25
+ */
26
+ import type { ReviseToolResult } from "@reviseio/engine";
27
+ import type { ReviseDocument } from "./document.js";
28
+ export type AgentProvider = "anthropic" | "openai" | "openai-responses";
29
+ export interface AgentToolsOptions {
30
+ provider: AgentProvider;
31
+ /** Cap on one tool result's text, in characters (default 100,000). Longer
32
+ * results are cut with a note telling the model how to page. */
33
+ maxResultChars?: number;
34
+ /** Only these tools (by name). */
35
+ include?: string[];
36
+ /** Every tool except these. */
37
+ exclude?: string[];
38
+ }
39
+ /** Anthropic Messages API: a `tool_use` content block. */
40
+ export interface AnthropicToolUse {
41
+ type?: "tool_use";
42
+ id: string;
43
+ name: string;
44
+ input: unknown;
45
+ }
46
+ /** OpenAI Chat Completions: an entry of `message.tool_calls`. */
47
+ export interface OpenAIToolCall {
48
+ id: string;
49
+ type?: "function";
50
+ function: {
51
+ name: string;
52
+ arguments: string;
53
+ };
54
+ }
55
+ /** OpenAI Responses API: a `function_call` output item. */
56
+ export interface OpenAIResponsesFunctionCall {
57
+ type?: "function_call";
58
+ call_id: string;
59
+ name: string;
60
+ arguments: string;
61
+ }
62
+ interface ProviderShapes {
63
+ anthropic: {
64
+ tool: {
65
+ name: string;
66
+ description: string;
67
+ input_schema: {
68
+ type: "object";
69
+ [key: string]: unknown;
70
+ };
71
+ };
72
+ call: AnthropicToolUse;
73
+ result: {
74
+ type: "tool_result";
75
+ tool_use_id: string;
76
+ content: string;
77
+ is_error?: boolean;
78
+ };
79
+ };
80
+ openai: {
81
+ tool: {
82
+ type: "function";
83
+ function: {
84
+ name: string;
85
+ description: string;
86
+ parameters: {
87
+ [key: string]: unknown;
88
+ };
89
+ };
90
+ };
91
+ call: OpenAIToolCall;
92
+ result: {
93
+ role: "tool";
94
+ tool_call_id: string;
95
+ content: string;
96
+ };
97
+ };
98
+ "openai-responses": {
99
+ tool: {
100
+ type: "function";
101
+ name: string;
102
+ description: string;
103
+ parameters: {
104
+ [key: string]: unknown;
105
+ };
106
+ /** Revise's schemas use optional fields, which strict mode rejects. */
107
+ strict: false;
108
+ };
109
+ call: OpenAIResponsesFunctionCall;
110
+ result: {
111
+ type: "function_call_output";
112
+ call_id: string;
113
+ output: string;
114
+ };
115
+ };
116
+ }
117
+ export interface AgentTools<P extends AgentProvider> {
118
+ /** Tool definitions in the provider's format. */
119
+ tools: Array<ProviderShapes[P]["tool"]>;
120
+ /** Run one tool call; returns the provider's tool-result message. Never
121
+ * throws for a bad call: the model gets the error to correct itself. */
122
+ handle: (call: ProviderShapes[P]["call"]) => Promise<ProviderShapes[P]["result"]>;
123
+ /** Did the last handled calls change the document? Compare to decide
124
+ * whether to save. */
125
+ version: () => Uint8Array;
126
+ /** Forget what the model has read (after compacting its transcript). */
127
+ reset: () => Promise<void>;
128
+ }
129
+ /** A tool result as the text a model reads: the message, any tracked
130
+ * change ids, the document HTML it loaded, and its structured data (counts,
131
+ * paging, what changed), within a size budget. */
132
+ export declare function formatToolResult(result: ReviseToolResult<string>, maxChars?: number): {
133
+ text: string;
134
+ isError: boolean;
135
+ };
136
+ export declare function agentTools<P extends AgentProvider>(doc: ReviseDocument, options: AgentToolsOptions & {
137
+ provider: P;
138
+ }): AgentTools<P>;
139
+ export {};
@@ -0,0 +1,135 @@
1
+ // revise: MIT License. https://revise.io/developer/docs
2
+ import {
3
+ ReviseError
4
+ } from "./chunk-U6YKQBKL.js";
5
+
6
+ // src/embed-sdk/lib/package.ts
7
+ import { engineModules } from "@reviseio/engine";
8
+ import JSZip from "jszip";
9
+ import { installDomShims } from "@reviseio/engine";
10
+ async function listParts(bytes) {
11
+ const zip = await JSZip.loadAsync(bytes);
12
+ const parts = [];
13
+ for (const [path, entry] of Object.entries(zip.files)) {
14
+ if (entry.dir) continue;
15
+ parts.push({ path, bytes: (await entry.async("uint8array")).length });
16
+ }
17
+ return parts.sort((a, b) => a.path.localeCompare(b.path));
18
+ }
19
+ async function readPart(zip, part) {
20
+ const file = zip.file(part);
21
+ if (!file) {
22
+ throw new ReviseError(`No part "${part}" in this document.`, "no_such_part");
23
+ }
24
+ return file.async("string");
25
+ }
26
+ var UNITS = [
27
+ "w:rPr",
28
+ "w:pPr",
29
+ "w:p",
30
+ "w:tr",
31
+ "w:style",
32
+ "w:abstractNum",
33
+ "w:num",
34
+ "w:lvl",
35
+ "w:sectPr",
36
+ "w:tbl"
37
+ ];
38
+ var CAT_MATCH_LIMIT = 20;
39
+ async function catPart(bytes, part, match, limit = CAT_MATCH_LIMIT) {
40
+ const xml = await readPart(await JSZip.loadAsync(bytes), part);
41
+ if (!match) return [xml];
42
+ const found = /* @__PURE__ */ new Set();
43
+ let at = xml.indexOf(match);
44
+ while (at >= 0 && found.size < limit) {
45
+ let best;
46
+ for (const tag of UNITS) {
47
+ const start = Math.max(
48
+ xml.lastIndexOf(`<${tag} `, at),
49
+ xml.lastIndexOf(`<${tag}>`, at)
50
+ );
51
+ if (start < 0) continue;
52
+ const close = xml.indexOf(`</${tag}>`, start);
53
+ if (close < 0 || close < at) continue;
54
+ const unit = xml.slice(start, close + tag.length + 3);
55
+ if (!best || unit.length < best.length) best = unit;
56
+ }
57
+ found.add(
58
+ best ?? xml.slice(Math.max(0, at - 200), at + match.length + 200)
59
+ );
60
+ at = xml.indexOf(match, at + match.length);
61
+ }
62
+ return [...found];
63
+ }
64
+ var MODEL_READ_PARTS = /^word\/(document|styles|numbering|footnotes|endnotes|comments|header\d*|footer\d*)\.xml$/;
65
+ async function assertWellFormed(part, xml) {
66
+ await installDomShims();
67
+ const parsed = new DOMParser().parseFromString(xml, "application/xml");
68
+ const error = parsed.getElementsByTagName("parsererror")[0];
69
+ if (error) {
70
+ throw new ReviseError(
71
+ `The patched ${part} is not well-formed XML: ${error.textContent?.trim().split("\n")[0] ?? "parse error"}. Nothing was changed.`,
72
+ "malformed_xml"
73
+ );
74
+ }
75
+ }
76
+ async function patchPackage(pkg, request, readFile) {
77
+ const zip = await JSZip.loadAsync(pkg);
78
+ const before = await readPart(zip, request.part);
79
+ let after;
80
+ let replacements = 0;
81
+ if (request.file !== void 0) {
82
+ after = readFile(request.file);
83
+ replacements = 1;
84
+ } else {
85
+ if (!request.find) {
86
+ throw new ReviseError(
87
+ "Give --find and --replace, or --file to replace the whole part.",
88
+ "usage"
89
+ );
90
+ }
91
+ const occurrences = before.split(request.find).length - 1;
92
+ if (occurrences === 0) {
93
+ throw new ReviseError(
94
+ `"${request.find}" does not occur in ${request.part}.`,
95
+ "find_not_found"
96
+ );
97
+ }
98
+ if (occurrences > 1 && !request.all) {
99
+ throw new ReviseError(
100
+ `"${request.find}" occurs ${occurrences} times in ${request.part}; add context to match once, or pass --all.`,
101
+ "find_ambiguous"
102
+ );
103
+ }
104
+ after = before.split(request.find).join(request.replace ?? "");
105
+ replacements = request.all ? occurrences : 1;
106
+ }
107
+ await assertWellFormed(request.part, after);
108
+ if (request.part === "word/document.xml") {
109
+ const { scanElementChildren } = await engineModules.xmlScan();
110
+ const shape = (xml) => scanElementChildren(xml, "w:body").children.map((child) => child.tag).join(",");
111
+ if (shape(before) !== shape(after)) {
112
+ throw new ReviseError(
113
+ "This patch adds, removes, or reorders body elements, which a direct patch cannot do. Use the editing tools for body structure. Nothing was changed.",
114
+ "body_shape_changed"
115
+ );
116
+ }
117
+ }
118
+ zip.file(request.part, after);
119
+ const bytes = await zip.generateAsync({
120
+ type: "uint8array",
121
+ compression: "DEFLATE"
122
+ });
123
+ return {
124
+ bytes,
125
+ replacements,
126
+ modelRead: MODEL_READ_PARTS.test(request.part)
127
+ };
128
+ }
129
+
130
+ export {
131
+ listParts,
132
+ CAT_MATCH_LIMIT,
133
+ catPart,
134
+ patchPackage
135
+ };
@@ -0,0 +1,15 @@
1
+ // revise: MIT License. https://revise.io/developer/docs
2
+
3
+ // src/embed-sdk/lib/errors.ts
4
+ var ReviseError = class extends Error {
5
+ constructor(message, code = "error", options = {}) {
6
+ super(message);
7
+ this.code = code;
8
+ this.name = "ReviseError";
9
+ if (options.cause !== void 0) this.cause = options.cause;
10
+ }
11
+ };
12
+
13
+ export {
14
+ ReviseError
15
+ };