@opentabs-dev/opentabs-plugin-linkedin 0.0.76 → 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 CHANGED
@@ -1,159 +1,46 @@
1
- # opentabs-plugin-linkedin
1
+ # LinkedIn
2
2
 
3
- OpenTabs plugin for LinkedIn
3
+ OpenTabs plugin for LinkedIn — gives AI agents access to LinkedIn through your authenticated browser session.
4
4
 
5
- ## Project Structure
5
+ ## Install
6
6
 
7
+ ```bash
8
+ opentabs plugin install linkedin
7
9
  ```
8
- linkedin/
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-linkedin",
28
- "main": "dist/adapter.iife.js",
29
- "opentabs": {
30
- "displayName": "LinkedIn",
31
- "description": "OpenTabs plugin for LinkedIn",
32
- "urlPatterns": ["*://*.linkedin.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
- linkedin/
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
10
 
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
-
63
- - Square SVG with a `viewBox` attribute (e.g., `viewBox="0 0 32 32"`)
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-linkedin
76
15
  ```
77
16
 
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
- ```
17
+ ## Setup
99
18
 
100
- Then register it in `src/index.ts` by adding it to the `tools` array.
19
+ 1. Open [linkedin.com](https://linkedin.com) in Chrome and log in
20
+ 2. Open the OpenTabs side panel — the LinkedIn plugin should appear as **ready**
101
21
 
102
- ## Authentication
22
+ ## Tools (6)
103
23
 
104
- Plugin tools run in the browser tab context, so they can read auth tokens directly from the page. The SDK provides utilities for the most common patterns:
24
+ ### Profile (2)
105
25
 
106
- ```ts
107
- import { getLocalStorage, getCookie, getPageGlobal } from '@opentabs-dev/plugin-sdk';
26
+ | Tool | Description | Type |
27
+ |---|---|---|
28
+ | `get_current_user` | Get the current authenticated user | Read |
29
+ | `get_user_profile` | Get a user's LinkedIn profile | Read |
108
30
 
109
- // localStorage — most common
110
- const token = getLocalStorage('token');
111
-
112
- // Cookies — session tokens, JWTs
113
- const session = getCookie('session_id');
114
-
115
- // Page globals — SPA boot data (e.g., window.__APP_STATE__)
116
- const appState = getPageGlobal('__APP_STATE__');
117
- ```
31
+ ### Messaging (4)
118
32
 
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.
33
+ | Tool | Description | Type |
34
+ |---|---|---|
35
+ | `list_conversations` | List messaging conversations | Read |
36
+ | `get_conversation_messages` | Read messages in a conversation | Read |
37
+ | `send_message` | Send a message in a conversation | Write |
38
+ | `get_mailbox_counts` | Get unread message counts | Read |
120
39
 
121
- **SPA hydration:** Auth tokens may not be available immediately on page load. Implement polling in `isReady()` to wait until the app has hydrated before your tools run. See the comments in `src/index.ts` for an example polling pattern.
40
+ ## How It Works
122
41
 
123
- ## Shared Schemas
42
+ This plugin runs inside your LinkedIn 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.
124
43
 
125
- When 3 or more tools share the same input or output shape, extract common Zod schemas into a shared file to avoid duplication:
126
-
127
- ```ts
128
- // src/schemas/channel.ts
129
- import { z } from 'zod';
130
-
131
- export const channelSchema = z.object({
132
- id: z.string().describe('Channel ID'),
133
- name: z.string().describe('Channel name'),
134
- });
135
-
136
- export type Channel = z.infer<typeof channelSchema>;
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
- ```
44
+ ## License
158
45
 
159
- This keeps your tool schemas DRY and makes it easy to evolve shared types in one place.
46
+ MIT
@@ -279,6 +279,8 @@
279
279
  * (e.g., 'https://github.com'), not a match pattern.
280
280
  */
281
281
  homepage;
282
+ /** Typed configuration schema — declares settings that users provide via config.json or the side panel. */
283
+ configSchema;
282
284
  };
283
285
 
284
286
  // src/linkedin-api.ts
@@ -14513,7 +14515,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14513
14515
  };
14514
14516
  var src_default = new LinkedInPlugin();
14515
14517
 
14516
- // dist/_adapter_entry_dfa2ccf7-2053-45ef-ac51-c48181617753.ts
14518
+ // dist/_adapter_entry_b1869b49-2a5d-47f5-9cac-00925399e130.ts
14517
14519
  if (!globalThis.__openTabs) {
14518
14520
  globalThis.__openTabs = {};
14519
14521
  } else {
@@ -14729,5 +14731,5 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14729
14731
  };
14730
14732
  delete src_default.onDeactivate;
14731
14733
  }
14732
- })();(function(){var o=(globalThis).__openTabs;if(o&&o.adapters&&o.adapters["linkedin"]){var a=o.adapters["linkedin"];a.__adapterHash="c6a76ed97a57482e77d51134afa22fddd6834f0e72e1878acf02cb8fb42a72d2";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,"linkedin",{value:a,writable:false,configurable:false,enumerable:true});Object.defineProperty(o,"adapters",{value:o.adapters,writable:false,configurable:false});}})();
14734
+ })();(function(){var o=(globalThis).__openTabs;if(o&&o.adapters&&o.adapters["linkedin"]){var a=o.adapters["linkedin"];a.__adapterHash="b526e860c8b2cfc63167d58930d0f651cdf92ef83b79225ba19c82011352adf1";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,"linkedin",{value:a,writable:false,configurable:false,enumerable:true});Object.defineProperty(o,"adapters",{value:o.adapters,writable:false,configurable:false});}})();
14733
14735
  //# sourceMappingURL=adapter.iife.js.map