@opentabs-dev/opentabs-plugin-pinterest 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 +54 -134
- package/dist/adapter.iife.js +25 -13
- 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,79 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Pinterest
|
|
2
2
|
|
|
3
|
-
OpenTabs plugin for Pinterest
|
|
3
|
+
OpenTabs plugin for Pinterest — gives AI agents access to Pinterest through your authenticated browser session.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Install
|
|
6
6
|
|
|
7
|
+
```bash
|
|
8
|
+
opentabs plugin install pinterest
|
|
7
9
|
```
|
|
8
|
-
pinterest/
|
|
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-pinterest",
|
|
28
|
-
"main": "dist/adapter.iife.js",
|
|
29
|
-
"opentabs": {
|
|
30
|
-
"displayName": "Pinterest",
|
|
31
|
-
"description": "OpenTabs plugin for Pinterest",
|
|
32
|
-
"urlPatterns": ["*://*.pinterest.com/*"]
|
|
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
|
-
|
|
44
|
-
By default, the side panel shows a colored letter avatar for your plugin. To use a custom icon, place an `icon.svg` file in the plugin root (next to `package.json`):
|
|
45
|
-
|
|
46
|
-
```
|
|
47
|
-
pinterest/
|
|
48
|
-
├── package.json
|
|
49
|
-
├── icon.svg ← custom icon (optional)
|
|
50
|
-
├── icon-inactive.svg ← manual inactive override (optional, requires icon.svg)
|
|
51
|
-
├── src/
|
|
52
|
-
│ └── ...
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
**How it works:**
|
|
56
|
-
|
|
57
|
-
- `opentabs-plugin build` reads `icon.svg`, validates it, auto-generates a grayscale inactive variant, and embeds both in `dist/tools.json`
|
|
58
|
-
- To override the auto-generated inactive icon, provide `icon-inactive.svg` (must use only grayscale colors)
|
|
59
|
-
- If no `icon.svg` is provided, the letter avatar is used automatically
|
|
60
|
-
|
|
61
|
-
**Icon requirements:**
|
|
62
10
|
|
|
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
|
|
67
|
-
|
|
68
|
-
## Development
|
|
11
|
+
Or install globally via npm:
|
|
69
12
|
|
|
70
13
|
```bash
|
|
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
|
|
14
|
+
npm install -g @opentabs-dev/opentabs-plugin-pinterest
|
|
76
15
|
```
|
|
77
16
|
|
|
78
|
-
##
|
|
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
|
-
```
|
|
17
|
+
## Setup
|
|
99
18
|
|
|
100
|
-
|
|
19
|
+
1. Open [pinterest.com](https://www.pinterest.com) in Chrome and log in
|
|
20
|
+
2. Open the OpenTabs side panel — the Pinterest plugin should appear as **ready**
|
|
101
21
|
|
|
102
|
-
##
|
|
22
|
+
## Tools (24)
|
|
103
23
|
|
|
104
|
-
|
|
24
|
+
### Account (2)
|
|
105
25
|
|
|
106
|
-
|
|
107
|
-
|
|
26
|
+
| Tool | Description | Type |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| `get_current_user` | Get the authenticated user profile | Read |
|
|
29
|
+
| `get_notification_counts` | Get notification badge counts | Read |
|
|
108
30
|
|
|
109
|
-
|
|
110
|
-
const token = getLocalStorage('token');
|
|
31
|
+
### Users (1)
|
|
111
32
|
|
|
112
|
-
|
|
113
|
-
|
|
33
|
+
| Tool | Description | Type |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| `get_user_profile` | Get a user profile by username | Read |
|
|
114
36
|
|
|
115
|
-
|
|
116
|
-
const appState = getPageGlobal('__APP_STATE__');
|
|
117
|
-
```
|
|
37
|
+
### Boards (9)
|
|
118
38
|
|
|
119
|
-
|
|
39
|
+
| Tool | Description | Type |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| `list_boards` | List boards for a user | Read |
|
|
42
|
+
| `get_board_pins` | Get pins from a board | Read |
|
|
43
|
+
| `get_board_sections` | Get sections for a board | Read |
|
|
44
|
+
| `create_board` | Create a new board | Write |
|
|
45
|
+
| `update_board` | Update a board | Write |
|
|
46
|
+
| `delete_board` | Delete a board | Write |
|
|
47
|
+
| `create_board_section` | Create a section in a board | Write |
|
|
48
|
+
| `delete_board_section` | Delete a board section | Write |
|
|
49
|
+
| `search_boards` | Search for boards by keyword | Read |
|
|
120
50
|
|
|
121
|
-
|
|
51
|
+
### Pins (8)
|
|
122
52
|
|
|
123
|
-
|
|
53
|
+
| Tool | Description | Type |
|
|
54
|
+
|---|---|---|
|
|
55
|
+
| `get_pin` | Get pin details by ID | Read |
|
|
56
|
+
| `create_pin` | Create a new pin on a board | Write |
|
|
57
|
+
| `save_pin` | Save an existing pin to a board | Write |
|
|
58
|
+
| `delete_pin` | Delete a pin | Write |
|
|
59
|
+
| `get_home_feed` | Get the personalized home feed | Read |
|
|
60
|
+
| `get_related_pins` | Get pins related to a specific pin | Read |
|
|
61
|
+
| `search_pins` | Search for pins by keyword | Read |
|
|
62
|
+
| `get_user_pins` | Get pins created by a user | Read |
|
|
124
63
|
|
|
125
|
-
|
|
64
|
+
### Social (4)
|
|
126
65
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
66
|
+
| Tool | Description | Type |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| `follow_user` | Follow a Pinterest user | Write |
|
|
69
|
+
| `unfollow_user` | Unfollow a Pinterest user | Write |
|
|
70
|
+
| `list_followers` | List followers of a user | Read |
|
|
71
|
+
| `list_following` | List users a user is following | Read |
|
|
130
72
|
|
|
131
|
-
|
|
132
|
-
id: z.string().describe('Channel ID'),
|
|
133
|
-
name: z.string().describe('Channel name'),
|
|
134
|
-
});
|
|
73
|
+
## How It Works
|
|
135
74
|
|
|
136
|
-
|
|
137
|
-
```
|
|
75
|
+
This plugin runs inside your Pinterest 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.
|
|
138
76
|
|
|
139
|
-
|
|
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
|
-
```
|
|
77
|
+
## License
|
|
158
78
|
|
|
159
|
-
|
|
79
|
+
MIT
|
package/dist/adapter.iife.js
CHANGED
|
@@ -343,6 +343,8 @@
|
|
|
343
343
|
* (e.g., 'https://github.com'), not a match pattern.
|
|
344
344
|
*/
|
|
345
345
|
homepage;
|
|
346
|
+
/** Typed configuration schema — declares settings that users provide via config.json or the side panel. */
|
|
347
|
+
configSchema;
|
|
346
348
|
};
|
|
347
349
|
|
|
348
350
|
// src/pinterest-api.ts
|
|
@@ -15070,21 +15072,21 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15070
15072
|
};
|
|
15071
15073
|
var src_default = new PinterestPlugin();
|
|
15072
15074
|
|
|
15073
|
-
// dist/
|
|
15075
|
+
// dist/_adapter_entry_5d1679a7-ac1c-4fc8-af93-14820a376a82.ts
|
|
15074
15076
|
if (!globalThis.__openTabs) {
|
|
15075
15077
|
globalThis.__openTabs = {};
|
|
15076
15078
|
} else {
|
|
15077
15079
|
const desc = Object.getOwnPropertyDescriptor(globalThis.__openTabs, "adapters");
|
|
15078
15080
|
if (desc && !desc.writable) {
|
|
15079
|
-
const
|
|
15081
|
+
const ot3 = globalThis.__openTabs;
|
|
15080
15082
|
const newAdaptersObj = {};
|
|
15081
|
-
if (
|
|
15082
|
-
for (const key of Object.keys(
|
|
15083
|
-
const d = Object.getOwnPropertyDescriptor(
|
|
15083
|
+
if (ot3.adapters) {
|
|
15084
|
+
for (const key of Object.keys(ot3.adapters)) {
|
|
15085
|
+
const d = Object.getOwnPropertyDescriptor(ot3.adapters, key);
|
|
15084
15086
|
if (d) Object.defineProperty(newAdaptersObj, key, d);
|
|
15085
15087
|
}
|
|
15086
15088
|
}
|
|
15087
|
-
globalThis.__openTabs = Object.assign({},
|
|
15089
|
+
globalThis.__openTabs = Object.assign({}, ot3, { adapters: newAdaptersObj });
|
|
15088
15090
|
}
|
|
15089
15091
|
}
|
|
15090
15092
|
if (!globalThis.__openTabs.adapters) {
|
|
@@ -15122,6 +15124,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15122
15124
|
}
|
|
15123
15125
|
};
|
|
15124
15126
|
var restoreTransport = setLogTransport ? setLogTransport(logTransport) : void 0;
|
|
15127
|
+
var ot2 = globalThis.__openTabs;
|
|
15128
|
+
ot2._notifyReadinessChanged = () => {
|
|
15129
|
+
try {
|
|
15130
|
+
const nonce = globalThis.__openTabs?._readinessNonce;
|
|
15131
|
+
if (nonce) {
|
|
15132
|
+
window.postMessage({ type: "opentabs:readiness-changed", plugin: "pinterest", nonce }, "*");
|
|
15133
|
+
}
|
|
15134
|
+
} catch {
|
|
15135
|
+
}
|
|
15136
|
+
};
|
|
15125
15137
|
var existing = adapters["pinterest"];
|
|
15126
15138
|
if (existing) {
|
|
15127
15139
|
if (typeof existing.teardown === "function") {
|
|
@@ -15133,7 +15145,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15133
15145
|
}
|
|
15134
15146
|
}
|
|
15135
15147
|
if (!Reflect.deleteProperty(adapters, "pinterest")) {
|
|
15136
|
-
const
|
|
15148
|
+
const ot3 = globalThis.__openTabs;
|
|
15137
15149
|
const newAdapters = {};
|
|
15138
15150
|
for (const key of Object.keys(adapters)) {
|
|
15139
15151
|
if (key !== "pinterest") {
|
|
@@ -15141,7 +15153,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15141
15153
|
if (desc) Object.defineProperty(newAdapters, key, desc);
|
|
15142
15154
|
}
|
|
15143
15155
|
}
|
|
15144
|
-
globalThis.__openTabs = Object.assign({},
|
|
15156
|
+
globalThis.__openTabs = Object.assign({}, ot3, { adapters: newAdapters });
|
|
15145
15157
|
}
|
|
15146
15158
|
var hasLifecycleHooks = typeof src_default.onToolInvocationStart === "function" || typeof src_default.onToolInvocationEnd === "function";
|
|
15147
15159
|
for (const tool of src_default.tools) {
|
|
@@ -15202,12 +15214,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15202
15214
|
}
|
|
15203
15215
|
}
|
|
15204
15216
|
};
|
|
15205
|
-
const
|
|
15206
|
-
if (!
|
|
15217
|
+
const ot3 = globalThis.__openTabs;
|
|
15218
|
+
if (!ot3._navigationInterceptor) {
|
|
15207
15219
|
const origPushState = history.pushState.bind(history);
|
|
15208
15220
|
const origReplaceState = history.replaceState.bind(history);
|
|
15209
15221
|
const callbacks = /* @__PURE__ */ new Map();
|
|
15210
|
-
|
|
15222
|
+
ot3._navigationInterceptor = { callbacks, origPushState, origReplaceState };
|
|
15211
15223
|
history.pushState = function(...args) {
|
|
15212
15224
|
origPushState(...args);
|
|
15213
15225
|
for (const cb of callbacks.values()) {
|
|
@@ -15221,7 +15233,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15221
15233
|
}
|
|
15222
15234
|
};
|
|
15223
15235
|
}
|
|
15224
|
-
const interceptor =
|
|
15236
|
+
const interceptor = ot3._navigationInterceptor;
|
|
15225
15237
|
interceptor.callbacks.set("pinterest", checkUrl);
|
|
15226
15238
|
window.addEventListener("popstate", checkUrl);
|
|
15227
15239
|
window.addEventListener("hashchange", checkUrl);
|
|
@@ -15276,5 +15288,5 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15276
15288
|
};
|
|
15277
15289
|
delete src_default.onDeactivate;
|
|
15278
15290
|
}
|
|
15279
|
-
})();(function(){var o=(globalThis).__openTabs;if(o&&o.adapters&&o.adapters["pinterest"]){var a=o.adapters["pinterest"];a.__adapterHash="
|
|
15291
|
+
})();(function(){var o=(globalThis).__openTabs;if(o&&o.adapters&&o.adapters["pinterest"]){var a=o.adapters["pinterest"];a.__adapterHash="a9a0bdbba43135d4b8c3b93533c1f32b4165d8ba9f1144f3721703c5be495c62";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,"pinterest",{value:a,writable:false,configurable:false,enumerable:true});Object.defineProperty(o,"adapters",{value:o.adapters,writable:false,configurable:false});}})();
|
|
15280
15292
|
//# sourceMappingURL=adapter.iife.js.map
|