@opentabs-dev/opentabs-plugin-posthog 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 CHANGED
@@ -1,159 +1,122 @@
1
- # opentabs-plugin-posthog
1
+ # PostHog
2
2
 
3
- OpenTabs plugin for PostHog
3
+ OpenTabs plugin for PostHog — gives AI agents access to PostHog through your authenticated browser session.
4
4
 
5
- ## Project Structure
5
+ ## Install
6
6
 
7
+ ```bash
8
+ opentabs plugin install posthog
7
9
  ```
8
- posthog/
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
10
+
11
+ Or install globally via npm:
12
+
13
+ ```bash
14
+ npm install -g @opentabs-dev/opentabs-plugin-posthog
19
15
  ```
20
16
 
21
- ## Configuration
17
+ ## Setup
22
18
 
23
- Plugin metadata is defined in `package.json` under the `opentabs` field:
19
+ 1. Open [us.posthog.com](https://us.posthog.com) in Chrome and log in
20
+ 2. Open the OpenTabs side panel — the PostHog plugin should appear as **ready**
24
21
 
25
- ```json
26
- {
27
- "name": "opentabs-plugin-posthog",
28
- "main": "dist/adapter.iife.js",
29
- "opentabs": {
30
- "displayName": "PostHog",
31
- "description": "OpenTabs plugin for PostHog",
32
- "urlPatterns": ["*://*.us.posthog.com/*"]
33
- }
34
- }
35
- ```
22
+ ## Tools (32)
36
23
 
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
24
+ ### Users (1)
41
25
 
42
- ## Custom Icons
26
+ | Tool | Description | Type |
27
+ |---|---|---|
28
+ | `get_current_user` | Get your PostHog profile | Read |
43
29
 
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`):
30
+ ### Organization (1)
45
31
 
46
- ```
47
- posthog/
48
- ├── package.json
49
- ├── icon.svg ← custom icon (optional)
50
- ├── icon-inactive.svg ← manual inactive override (optional, requires icon.svg)
51
- ├── src/
52
- │ └── ...
53
- ```
32
+ | Tool | Description | Type |
33
+ |---|---|---|
34
+ | `get_organization` | Get current organization info | Read |
54
35
 
55
- **How it works:**
36
+ ### Projects (2)
56
37
 
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
38
+ | Tool | Description | Type |
39
+ |---|---|---|
40
+ | `list_projects` | List projects in the organization | Read |
41
+ | `get_project` | Get project details | Read |
60
42
 
61
- **Icon requirements:**
43
+ ### Dashboards (5)
62
44
 
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
45
+ | Tool | Description | Type |
46
+ |---|---|---|
47
+ | `list_dashboards` | List dashboards in the project | Read |
48
+ | `get_dashboard` | Get dashboard details | Read |
49
+ | `create_dashboard` | Create a new dashboard | Write |
50
+ | `update_dashboard` | Update a dashboard | Write |
51
+ | `delete_dashboard` | Delete a dashboard | Write |
67
52
 
68
- ## Development
53
+ ### Insights (4)
69
54
 
70
- ```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
76
- ```
55
+ | Tool | Description | Type |
56
+ |---|---|---|
57
+ | `list_insights` | List insights in the project | Read |
58
+ | `get_insight` | Get insight details | Read |
59
+ | `update_insight` | Update an insight | Write |
60
+ | `delete_insight` | Delete an insight | Write |
77
61
 
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
- ```
62
+ ### Feature Flags (5)
99
63
 
100
- Then register it in `src/index.ts` by adding it to the `tools` array.
64
+ | Tool | Description | Type |
65
+ |---|---|---|
66
+ | `list_feature_flags` | List feature flags | Read |
67
+ | `get_feature_flag` | Get feature flag details | Read |
68
+ | `create_feature_flag` | Create a new feature flag | Write |
69
+ | `update_feature_flag` | Update a feature flag | Write |
70
+ | `delete_feature_flag` | Delete a feature flag | Write |
101
71
 
102
- ## Authentication
72
+ ### Experiments (3)
103
73
 
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:
74
+ | Tool | Description | Type |
75
+ |---|---|---|
76
+ | `list_experiments` | List experiments | Read |
77
+ | `get_experiment` | Get experiment details | Read |
78
+ | `create_experiment` | Create a new experiment | Write |
105
79
 
106
- ```ts
107
- import { getLocalStorage, getCookie, getPageGlobal } from '@opentabs-dev/plugin-sdk';
80
+ ### Annotations (3)
108
81
 
109
- // localStorage most common
110
- const token = getLocalStorage('token');
82
+ | Tool | Description | Type |
83
+ |---|---|---|
84
+ | `list_annotations` | List annotations | Read |
85
+ | `create_annotation` | Create a new annotation | Write |
86
+ | `delete_annotation` | Delete an annotation | Write |
111
87
 
112
- // Cookies — session tokens, JWTs
113
- const session = getCookie('session_id');
88
+ ### Persons (2)
114
89
 
115
- // Page globals SPA boot data (e.g., window.__APP_STATE__)
116
- const appState = getPageGlobal('__APP_STATE__');
117
- ```
90
+ | Tool | Description | Type |
91
+ |---|---|---|
92
+ | `list_persons` | List tracked persons | Read |
93
+ | `get_person` | Get person details | Read |
118
94
 
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.
95
+ ### Cohorts (2)
120
96
 
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.
97
+ | Tool | Description | Type |
98
+ |---|---|---|
99
+ | `list_cohorts` | List cohorts | Read |
100
+ | `get_cohort` | Get cohort details | Read |
122
101
 
123
- ## Shared Schemas
102
+ ### Surveys (2)
124
103
 
125
- When 3 or more tools share the same input or output shape, extract common Zod schemas into a shared file to avoid duplication:
104
+ | Tool | Description | Type |
105
+ |---|---|---|
106
+ | `list_surveys` | List surveys | Read |
107
+ | `get_survey` | Get survey details | Read |
126
108
 
127
- ```ts
128
- // src/schemas/channel.ts
129
- import { z } from 'zod';
109
+ ### Actions (2)
130
110
 
131
- export const channelSchema = z.object({
132
- id: z.string().describe('Channel ID'),
133
- name: z.string().describe('Channel name'),
134
- });
111
+ | Tool | Description | Type |
112
+ |---|---|---|
113
+ | `list_actions` | List actions | Read |
114
+ | `get_action` | Get action details | Read |
135
115
 
136
- export type Channel = z.infer<typeof channelSchema>;
137
- ```
116
+ ## How It Works
138
117
 
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
- ```
118
+ This plugin runs inside your PostHog 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.
119
+
120
+ ## License
158
121
 
159
- This keeps your tool schemas DRY and makes it easy to evolve shared types in one place.
122
+ MIT
@@ -434,6 +434,8 @@
434
434
  * (e.g., 'https://github.com'), not a match pattern.
435
435
  */
436
436
  homepage;
437
+ /** Typed configuration schema — declares settings that users provide via config.json or the side panel. */
438
+ configSchema;
437
439
  };
438
440
 
439
441
  // src/posthog-api.ts
@@ -15394,21 +15396,21 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15394
15396
  };
15395
15397
  var src_default = new PostHogPlugin();
15396
15398
 
15397
- // dist/_adapter_entry_719e1959-e2dc-4352-b7c3-a0d6eddab4e8.ts
15399
+ // dist/_adapter_entry_8879e093-4fe7-42ca-ac0e-945e76210a57.ts
15398
15400
  if (!globalThis.__openTabs) {
15399
15401
  globalThis.__openTabs = {};
15400
15402
  } else {
15401
15403
  const desc = Object.getOwnPropertyDescriptor(globalThis.__openTabs, "adapters");
15402
15404
  if (desc && !desc.writable) {
15403
- const ot2 = globalThis.__openTabs;
15405
+ const ot3 = globalThis.__openTabs;
15404
15406
  const newAdaptersObj = {};
15405
- if (ot2.adapters) {
15406
- for (const key of Object.keys(ot2.adapters)) {
15407
- const d = Object.getOwnPropertyDescriptor(ot2.adapters, key);
15407
+ if (ot3.adapters) {
15408
+ for (const key of Object.keys(ot3.adapters)) {
15409
+ const d = Object.getOwnPropertyDescriptor(ot3.adapters, key);
15408
15410
  if (d) Object.defineProperty(newAdaptersObj, key, d);
15409
15411
  }
15410
15412
  }
15411
- globalThis.__openTabs = Object.assign({}, ot2, { adapters: newAdaptersObj });
15413
+ globalThis.__openTabs = Object.assign({}, ot3, { adapters: newAdaptersObj });
15412
15414
  }
15413
15415
  }
15414
15416
  if (!globalThis.__openTabs.adapters) {
@@ -15446,6 +15448,16 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15446
15448
  }
15447
15449
  };
15448
15450
  var restoreTransport = setLogTransport ? setLogTransport(logTransport) : void 0;
15451
+ var ot2 = globalThis.__openTabs;
15452
+ ot2._notifyReadinessChanged = () => {
15453
+ try {
15454
+ const nonce = globalThis.__openTabs?._readinessNonce;
15455
+ if (nonce) {
15456
+ window.postMessage({ type: "opentabs:readiness-changed", plugin: "posthog", nonce }, "*");
15457
+ }
15458
+ } catch {
15459
+ }
15460
+ };
15449
15461
  var existing = adapters["posthog"];
15450
15462
  if (existing) {
15451
15463
  if (typeof existing.teardown === "function") {
@@ -15457,7 +15469,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15457
15469
  }
15458
15470
  }
15459
15471
  if (!Reflect.deleteProperty(adapters, "posthog")) {
15460
- const ot2 = globalThis.__openTabs;
15472
+ const ot3 = globalThis.__openTabs;
15461
15473
  const newAdapters = {};
15462
15474
  for (const key of Object.keys(adapters)) {
15463
15475
  if (key !== "posthog") {
@@ -15465,7 +15477,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15465
15477
  if (desc) Object.defineProperty(newAdapters, key, desc);
15466
15478
  }
15467
15479
  }
15468
- globalThis.__openTabs = Object.assign({}, ot2, { adapters: newAdapters });
15480
+ globalThis.__openTabs = Object.assign({}, ot3, { adapters: newAdapters });
15469
15481
  }
15470
15482
  var hasLifecycleHooks = typeof src_default.onToolInvocationStart === "function" || typeof src_default.onToolInvocationEnd === "function";
15471
15483
  for (const tool of src_default.tools) {
@@ -15526,12 +15538,12 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15526
15538
  }
15527
15539
  }
15528
15540
  };
15529
- const ot2 = globalThis.__openTabs;
15530
- if (!ot2._navigationInterceptor) {
15541
+ const ot3 = globalThis.__openTabs;
15542
+ if (!ot3._navigationInterceptor) {
15531
15543
  const origPushState = history.pushState.bind(history);
15532
15544
  const origReplaceState = history.replaceState.bind(history);
15533
15545
  const callbacks = /* @__PURE__ */ new Map();
15534
- ot2._navigationInterceptor = { callbacks, origPushState, origReplaceState };
15546
+ ot3._navigationInterceptor = { callbacks, origPushState, origReplaceState };
15535
15547
  history.pushState = function(...args) {
15536
15548
  origPushState(...args);
15537
15549
  for (const cb of callbacks.values()) {
@@ -15545,7 +15557,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15545
15557
  }
15546
15558
  };
15547
15559
  }
15548
- const interceptor = ot2._navigationInterceptor;
15560
+ const interceptor = ot3._navigationInterceptor;
15549
15561
  interceptor.callbacks.set("posthog", checkUrl);
15550
15562
  window.addEventListener("popstate", checkUrl);
15551
15563
  window.addEventListener("hashchange", checkUrl);
@@ -15600,5 +15612,5 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15600
15612
  };
15601
15613
  delete src_default.onDeactivate;
15602
15614
  }
15603
- })();(function(){var o=(globalThis).__openTabs;if(o&&o.adapters&&o.adapters["posthog"]){var a=o.adapters["posthog"];a.__adapterHash="883dd185f19a15438e7e0b8108b7eb6e4a9bf93a8b0d0b88c0aa09608a5ee083";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,"posthog",{value:a,writable:false,configurable:false,enumerable:true});Object.defineProperty(o,"adapters",{value:o.adapters,writable:false,configurable:false});}})();
15615
+ })();(function(){var o=(globalThis).__openTabs;if(o&&o.adapters&&o.adapters["posthog"]){var a=o.adapters["posthog"];a.__adapterHash="035553abb6aacff6266a07e6e49574b69d5e35e9dd9a44a241231abe551fba5e";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,"posthog",{value:a,writable:false,configurable:false,enumerable:true});Object.defineProperty(o,"adapters",{value:o.adapters,writable:false,configurable:false});}})();
15604
15616
  //# sourceMappingURL=adapter.iife.js.map