@opentabs-dev/opentabs-plugin-microsoft-word 0.0.75 → 0.0.77
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 +61 -133
- package/dist/adapter.iife.js +40 -27
- package/dist/adapter.iife.js.map +3 -3
- package/dist/tools.json +1 -1
- package/package.json +10 -4
package/README.md
CHANGED
|
@@ -1,159 +1,87 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Microsoft Word
|
|
2
2
|
|
|
3
|
-
OpenTabs plugin for Microsoft Word Online
|
|
3
|
+
OpenTabs plugin for Microsoft Word Online — gives AI agents access to Microsoft Word through your authenticated browser session.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Install
|
|
6
6
|
|
|
7
|
+
```bash
|
|
8
|
+
opentabs plugin install microsoft-word
|
|
7
9
|
```
|
|
8
|
-
microsoft-word/
|
|
9
|
-
├── package.json # Plugin metadata (name, opentabs field, dependencies)
|
|
10
|
-
├── icon.svg # Optional custom icon (square SVG, max 8KB)
|
|
11
|
-
├── icon-inactive.svg # Optional manual inactive icon override
|
|
12
|
-
├── src/
|
|
13
|
-
│ ├── index.ts # Plugin class (extends OpenTabsPlugin)
|
|
14
|
-
│ └── tools/ # One file per tool (using defineTool)
|
|
15
|
-
│ └── example.ts
|
|
16
|
-
└── dist/ # Build output (generated)
|
|
17
|
-
├── adapter.iife.js # Bundled adapter injected into matching tabs
|
|
18
|
-
└── tools.json # Tool schemas for MCP registration
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
## Configuration
|
|
22
|
-
|
|
23
|
-
Plugin metadata is defined in `package.json` under the `opentabs` field:
|
|
24
|
-
|
|
25
|
-
```json
|
|
26
|
-
{
|
|
27
|
-
"name": "opentabs-plugin-microsoft-word",
|
|
28
|
-
"main": "dist/adapter.iife.js",
|
|
29
|
-
"opentabs": {
|
|
30
|
-
"displayName": "Microsoft Word",
|
|
31
|
-
"description": "OpenTabs plugin for Microsoft Word Online",
|
|
32
|
-
"urlPatterns": ["*://*.word.cloud.microsoft/*"]
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
- **`main`** — entry point for the bundled adapter IIFE
|
|
38
|
-
- **`opentabs.displayName`** — human-readable name shown in the side panel
|
|
39
|
-
- **`opentabs.description`** — short description of what the plugin does
|
|
40
|
-
- **`opentabs.urlPatterns`** — Chrome match patterns for tabs where the adapter is injected
|
|
41
|
-
|
|
42
|
-
## Custom Icons
|
|
43
10
|
|
|
44
|
-
|
|
11
|
+
Or install globally via npm:
|
|
45
12
|
|
|
46
|
-
```
|
|
47
|
-
microsoft-word
|
|
48
|
-
├── package.json
|
|
49
|
-
├── icon.svg ← custom icon (optional)
|
|
50
|
-
├── icon-inactive.svg ← manual inactive override (optional, requires icon.svg)
|
|
51
|
-
├── src/
|
|
52
|
-
│ └── ...
|
|
13
|
+
```bash
|
|
14
|
+
npm install -g @opentabs-dev/opentabs-plugin-microsoft-word
|
|
53
15
|
```
|
|
54
16
|
|
|
55
|
-
|
|
17
|
+
## Setup
|
|
56
18
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
- If no `icon.svg` is provided, the letter avatar is used automatically
|
|
19
|
+
1. Open [word.cloud.microsoft](https://word.cloud.microsoft) in Chrome and log in
|
|
20
|
+
2. Open the OpenTabs side panel — the Microsoft Word plugin should appear as **ready**
|
|
60
21
|
|
|
61
|
-
|
|
22
|
+
## Tools (27)
|
|
62
23
|
|
|
63
|
-
|
|
64
|
-
- Maximum 8 KB file size
|
|
65
|
-
- No embedded `<image>`, `<script>`, or event handler attributes (`onclick`, etc.)
|
|
66
|
-
- Manual `icon-inactive.svg` must use only achromatic (grayscale) colors
|
|
24
|
+
### Account (1)
|
|
67
25
|
|
|
68
|
-
|
|
26
|
+
| Tool | Description | Type |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| `get_current_user` | Get the current user profile | Read |
|
|
69
29
|
|
|
70
|
-
|
|
71
|
-
npm install
|
|
72
|
-
npm run build # tsc && opentabs-plugin build
|
|
73
|
-
npm run dev # watch mode (tsc --watch + opentabs-plugin build --watch)
|
|
74
|
-
npm run type-check # tsc --noEmit
|
|
75
|
-
npm run lint # biome
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
## Adding Tools
|
|
79
|
-
|
|
80
|
-
Create a new file in `src/tools/` using `defineTool`:
|
|
81
|
-
|
|
82
|
-
```ts
|
|
83
|
-
import { z } from 'zod';
|
|
84
|
-
import { defineTool } from '@opentabs-dev/plugin-sdk';
|
|
85
|
-
|
|
86
|
-
export const myTool = defineTool({
|
|
87
|
-
name: 'my_tool',
|
|
88
|
-
displayName: 'My Tool',
|
|
89
|
-
description: 'What this tool does',
|
|
90
|
-
icon: 'wrench',
|
|
91
|
-
input: z.object({ /* ... */ }),
|
|
92
|
-
output: z.object({ /* ... */ }),
|
|
93
|
-
handle: async (params) => {
|
|
94
|
-
// Tool implementation runs in the browser tab context
|
|
95
|
-
return { /* ... */ };
|
|
96
|
-
},
|
|
97
|
-
});
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
Then register it in `src/index.ts` by adding it to the `tools` array.
|
|
30
|
+
### Drive (1)
|
|
101
31
|
|
|
102
|
-
|
|
32
|
+
| Tool | Description | Type |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| `get_drive` | Get OneDrive details | Read |
|
|
103
35
|
|
|
104
|
-
|
|
36
|
+
### Documents (6)
|
|
105
37
|
|
|
106
|
-
|
|
107
|
-
|
|
38
|
+
| Tool | Description | Type |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| `get_active_document` | Get the currently open document | Read |
|
|
41
|
+
| `get_document_text` | Extract text from a Word document | Read |
|
|
42
|
+
| `create_document` | Create a new Word document with text | Write |
|
|
43
|
+
| `update_document` | Replace all text in a Word document | Write |
|
|
44
|
+
| `append_to_document` | Append paragraphs to a Word document | Write |
|
|
45
|
+
| `replace_text_in_document` | Find and replace text in a Word document | Write |
|
|
108
46
|
|
|
109
|
-
|
|
110
|
-
const token = getLocalStorage('token');
|
|
47
|
+
### Files (14)
|
|
111
48
|
|
|
112
|
-
|
|
113
|
-
|
|
49
|
+
| Tool | Description | Type |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| `get_file_content` | Read text content of a file | Read |
|
|
52
|
+
| `list_recent_documents` | List recent documents | Read |
|
|
53
|
+
| `list_children` | List files and folders | Read |
|
|
54
|
+
| `get_item` | Get file or folder details | Read |
|
|
55
|
+
| `search_files` | Search files and folders | Read |
|
|
56
|
+
| `create_folder` | Create a folder | Write |
|
|
57
|
+
| `upload_file` | Upload a text file to OneDrive | Write |
|
|
58
|
+
| `update_file_content` | Update a file's content | Write |
|
|
59
|
+
| `rename_item` | Rename a file or folder | Write |
|
|
60
|
+
| `move_item` | Move a file or folder | Write |
|
|
61
|
+
| `copy_item` | Copy a file or folder | Write |
|
|
62
|
+
| `delete_item` | Delete a file or folder | Write |
|
|
63
|
+
| `list_shared_with_me` | List files shared with me | Read |
|
|
64
|
+
| `get_preview_url` | Get a document preview URL | Read |
|
|
114
65
|
|
|
115
|
-
|
|
116
|
-
const appState = getPageGlobal('__APP_STATE__');
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
**Iframe fallback:** Some apps (e.g., Discord) delete `window.localStorage` after boot. `getLocalStorage` automatically tries a hidden same-origin iframe fallback before returning `null`, so you don't need to handle this case manually.
|
|
66
|
+
### Sharing (3)
|
|
120
67
|
|
|
121
|
-
|
|
68
|
+
| Tool | Description | Type |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| `create_sharing_link` | Create a sharing link for a file or folder | Write |
|
|
71
|
+
| `list_permissions` | List sharing permissions | Read |
|
|
72
|
+
| `delete_permission` | Remove a sharing permission | Write |
|
|
122
73
|
|
|
123
|
-
|
|
74
|
+
### Versions (2)
|
|
124
75
|
|
|
125
|
-
|
|
76
|
+
| Tool | Description | Type |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| `list_versions` | List file version history | Read |
|
|
79
|
+
| `restore_version` | Restore a file version | Write |
|
|
126
80
|
|
|
127
|
-
|
|
128
|
-
// src/schemas/channel.ts
|
|
129
|
-
import { z } from 'zod';
|
|
81
|
+
## How It Works
|
|
130
82
|
|
|
131
|
-
|
|
132
|
-
id: z.string().describe('Channel ID'),
|
|
133
|
-
name: z.string().describe('Channel name'),
|
|
134
|
-
});
|
|
83
|
+
This plugin runs inside your Microsoft Word tab through the [OpenTabs](https://opentabs.dev) Chrome extension. It uses your existing browser session — no API tokens or OAuth apps required. All operations happen as you, with your permissions.
|
|
135
84
|
|
|
136
|
-
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
Then import and reuse in your tools:
|
|
140
|
-
|
|
141
|
-
```ts
|
|
142
|
-
// src/tools/list-channels.ts
|
|
143
|
-
import { channelSchema } from '../schemas/channel.js';
|
|
144
|
-
|
|
145
|
-
export const listChannels = defineTool({
|
|
146
|
-
name: 'list_channels',
|
|
147
|
-
displayName: 'List Channels',
|
|
148
|
-
description: 'List all available channels',
|
|
149
|
-
icon: 'list',
|
|
150
|
-
input: z.object({}),
|
|
151
|
-
output: z.object({ channels: z.array(channelSchema) }),
|
|
152
|
-
handle: async () => {
|
|
153
|
-
// ...
|
|
154
|
-
return { channels: [] };
|
|
155
|
-
},
|
|
156
|
-
});
|
|
157
|
-
```
|
|
85
|
+
## License
|
|
158
86
|
|
|
159
|
-
|
|
87
|
+
MIT
|
package/dist/adapter.iife.js
CHANGED
|
@@ -248,18 +248,18 @@
|
|
|
248
248
|
|
|
249
249
|
// node_modules/@opentabs-dev/plugin-sdk/dist/storage.js
|
|
250
250
|
var getLocalStorage = (key) => {
|
|
251
|
-
try {
|
|
252
|
-
return localStorage.getItem(key);
|
|
253
|
-
} catch {
|
|
254
|
-
}
|
|
255
251
|
let storage;
|
|
256
252
|
try {
|
|
257
|
-
storage = localStorage;
|
|
253
|
+
storage = window.localStorage;
|
|
258
254
|
} catch {
|
|
259
255
|
return null;
|
|
260
256
|
}
|
|
261
|
-
if (storage
|
|
262
|
-
|
|
257
|
+
if (storage) {
|
|
258
|
+
try {
|
|
259
|
+
return storage.getItem(key);
|
|
260
|
+
} catch {
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
263
|
}
|
|
264
264
|
try {
|
|
265
265
|
const iframe = document.createElement("iframe");
|
|
@@ -287,18 +287,19 @@
|
|
|
287
287
|
}
|
|
288
288
|
return null;
|
|
289
289
|
};
|
|
290
|
-
try {
|
|
291
|
-
return search(localStorage);
|
|
292
|
-
} catch {
|
|
293
|
-
}
|
|
294
290
|
let storage;
|
|
295
291
|
try {
|
|
296
|
-
storage = localStorage;
|
|
292
|
+
storage = window.localStorage;
|
|
297
293
|
} catch {
|
|
298
294
|
return null;
|
|
299
295
|
}
|
|
300
|
-
if (storage
|
|
301
|
-
|
|
296
|
+
if (storage) {
|
|
297
|
+
try {
|
|
298
|
+
return search(storage);
|
|
299
|
+
} catch {
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
302
303
|
try {
|
|
303
304
|
const iframe = document.createElement("iframe");
|
|
304
305
|
iframe.style.display = "none";
|
|
@@ -364,6 +365,8 @@
|
|
|
364
365
|
* (e.g., 'https://github.com'), not a match pattern.
|
|
365
366
|
*/
|
|
366
367
|
homepage;
|
|
368
|
+
/** Typed configuration schema — declares settings that users provide via config.json or the side panel. */
|
|
369
|
+
configSchema;
|
|
367
370
|
};
|
|
368
371
|
|
|
369
372
|
// src/microsoft-word-api.ts
|
|
@@ -15653,21 +15656,21 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15653
15656
|
};
|
|
15654
15657
|
var src_default = new MicrosoftWordPlugin();
|
|
15655
15658
|
|
|
15656
|
-
// dist/
|
|
15659
|
+
// dist/_adapter_entry_0965f804-0cca-408d-832b-ab16d60163f1.ts
|
|
15657
15660
|
if (!globalThis.__openTabs) {
|
|
15658
15661
|
globalThis.__openTabs = {};
|
|
15659
15662
|
} else {
|
|
15660
15663
|
const desc = Object.getOwnPropertyDescriptor(globalThis.__openTabs, "adapters");
|
|
15661
15664
|
if (desc && !desc.writable) {
|
|
15662
|
-
const
|
|
15665
|
+
const ot3 = globalThis.__openTabs;
|
|
15663
15666
|
const newAdaptersObj = {};
|
|
15664
|
-
if (
|
|
15665
|
-
for (const key of Object.keys(
|
|
15666
|
-
const d = Object.getOwnPropertyDescriptor(
|
|
15667
|
+
if (ot3.adapters) {
|
|
15668
|
+
for (const key of Object.keys(ot3.adapters)) {
|
|
15669
|
+
const d = Object.getOwnPropertyDescriptor(ot3.adapters, key);
|
|
15667
15670
|
if (d) Object.defineProperty(newAdaptersObj, key, d);
|
|
15668
15671
|
}
|
|
15669
15672
|
}
|
|
15670
|
-
globalThis.__openTabs = Object.assign({},
|
|
15673
|
+
globalThis.__openTabs = Object.assign({}, ot3, { adapters: newAdaptersObj });
|
|
15671
15674
|
}
|
|
15672
15675
|
}
|
|
15673
15676
|
if (!globalThis.__openTabs.adapters) {
|
|
@@ -15705,6 +15708,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15705
15708
|
}
|
|
15706
15709
|
};
|
|
15707
15710
|
var restoreTransport = setLogTransport ? setLogTransport(logTransport) : void 0;
|
|
15711
|
+
var ot2 = globalThis.__openTabs;
|
|
15712
|
+
ot2._notifyReadinessChanged = () => {
|
|
15713
|
+
try {
|
|
15714
|
+
const nonce = globalThis.__openTabs?._readinessNonce;
|
|
15715
|
+
if (nonce) {
|
|
15716
|
+
window.postMessage({ type: "opentabs:readiness-changed", plugin: "microsoft-word", nonce }, "*");
|
|
15717
|
+
}
|
|
15718
|
+
} catch {
|
|
15719
|
+
}
|
|
15720
|
+
};
|
|
15708
15721
|
var existing = adapters["microsoft-word"];
|
|
15709
15722
|
if (existing) {
|
|
15710
15723
|
if (typeof existing.teardown === "function") {
|
|
@@ -15716,7 +15729,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15716
15729
|
}
|
|
15717
15730
|
}
|
|
15718
15731
|
if (!Reflect.deleteProperty(adapters, "microsoft-word")) {
|
|
15719
|
-
const
|
|
15732
|
+
const ot3 = globalThis.__openTabs;
|
|
15720
15733
|
const newAdapters = {};
|
|
15721
15734
|
for (const key of Object.keys(adapters)) {
|
|
15722
15735
|
if (key !== "microsoft-word") {
|
|
@@ -15724,7 +15737,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15724
15737
|
if (desc) Object.defineProperty(newAdapters, key, desc);
|
|
15725
15738
|
}
|
|
15726
15739
|
}
|
|
15727
|
-
globalThis.__openTabs = Object.assign({},
|
|
15740
|
+
globalThis.__openTabs = Object.assign({}, ot3, { adapters: newAdapters });
|
|
15728
15741
|
}
|
|
15729
15742
|
var hasLifecycleHooks = typeof src_default.onToolInvocationStart === "function" || typeof src_default.onToolInvocationEnd === "function";
|
|
15730
15743
|
for (const tool of src_default.tools) {
|
|
@@ -15785,12 +15798,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15785
15798
|
}
|
|
15786
15799
|
}
|
|
15787
15800
|
};
|
|
15788
|
-
const
|
|
15789
|
-
if (!
|
|
15801
|
+
const ot3 = globalThis.__openTabs;
|
|
15802
|
+
if (!ot3._navigationInterceptor) {
|
|
15790
15803
|
const origPushState = history.pushState.bind(history);
|
|
15791
15804
|
const origReplaceState = history.replaceState.bind(history);
|
|
15792
15805
|
const callbacks = /* @__PURE__ */ new Map();
|
|
15793
|
-
|
|
15806
|
+
ot3._navigationInterceptor = { callbacks, origPushState, origReplaceState };
|
|
15794
15807
|
history.pushState = function(...args) {
|
|
15795
15808
|
origPushState(...args);
|
|
15796
15809
|
for (const cb of callbacks.values()) {
|
|
@@ -15804,7 +15817,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15804
15817
|
}
|
|
15805
15818
|
};
|
|
15806
15819
|
}
|
|
15807
|
-
const interceptor =
|
|
15820
|
+
const interceptor = ot3._navigationInterceptor;
|
|
15808
15821
|
interceptor.callbacks.set("microsoft-word", checkUrl);
|
|
15809
15822
|
window.addEventListener("popstate", checkUrl);
|
|
15810
15823
|
window.addEventListener("hashchange", checkUrl);
|
|
@@ -15859,5 +15872,5 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15859
15872
|
};
|
|
15860
15873
|
delete src_default.onDeactivate;
|
|
15861
15874
|
}
|
|
15862
|
-
})();(function(){var o=(globalThis).__openTabs;if(o&&o.adapters&&o.adapters["microsoft-word"]){var a=o.adapters["microsoft-word"];a.__adapterHash="
|
|
15875
|
+
})();(function(){var o=(globalThis).__openTabs;if(o&&o.adapters&&o.adapters["microsoft-word"]){var a=o.adapters["microsoft-word"];a.__adapterHash="6fc1f6fc3b766ecb52568d6141d0a378c3ff666d5bc0255b8cc8be3f7887569d";if(a.tools&&Array.isArray(a.tools)){for(var i=0;i<a.tools.length;i++){Object.freeze(a.tools[i]);}Object.freeze(a.tools);}Object.freeze(a);Object.defineProperty(o.adapters,"microsoft-word",{value:a,writable:false,configurable:false,enumerable:true});Object.defineProperty(o,"adapters",{value:o.adapters,writable:false,configurable:false});}})();
|
|
15863
15876
|
//# sourceMappingURL=adapter.iife.js.map
|