diff --git a/.gitignore b/.gitignore index af326290..b03dc1a3 100644 --- a/.gitignore +++ b/.gitignore @@ -26,7 +26,7 @@ src/pages.gen.ts .env .vercel .vocs - +.env*.local src/pages/protocol/tips/tip-* # Playwright diff --git a/package.json b/package.json index 763472f2..d9628469 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "monaco-editor": "^0.55.1", "ox": "^0.11.3", "posthog-js": "^1.333.0", + "posthog-node": "^5.24.8", "prool": "^0.2.2", "react": "^19.2.3", "react-dom": "^19.2.3", @@ -44,14 +45,14 @@ "devDependencies": { "@biomejs/biome": "^2.3.11", "@playwright/test": "^1.58.0", - "@types/node": "^25.0.10", + "@types/node": "^25.1.0", "@types/react": "^19.2.9", "@types/react-dom": "^19.2.3", "@typescript/native-preview": "7.0.0-dev.20260122.3", "@vitejs/plugin-react": "^5.1.2", "anser": "^2.3.5", "tsx": "^4.21.0", - "typescript": "~5.9.3", + "typescript": "^5.9.3", "use-sync-external-store": "^1.6.0", "vite": "^7.3.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 52c23f20..17c1ea14 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -52,6 +52,9 @@ importers: posthog-js: specifier: ^1.333.0 version: 1.333.0 + posthog-node: + specifier: ^5.24.8 + version: 5.24.10 prool: specifier: ^0.2.2 version: 0.2.2 @@ -87,13 +90,13 @@ importers: version: 2.44.4(typescript@5.9.3)(zod@4.3.5) vocs: specifier: https://pkg.pr.new/wevm/vocs@d02f8c5 - version: https://pkg.pr.new/wevm/vocs@d02f8c5(@types/react@19.2.9)(mermaid@11.12.2)(react-dom@19.2.3(react@19.2.3))(react-server-dom-webpack@19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1))(react@19.2.3)(rollup@4.56.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(waku@1.0.0-alpha.2(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(react-dom@19.2.3(react@19.2.3))(react-server-dom-webpack@19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1))(react@19.2.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + version: https://pkg.pr.new/wevm/vocs@d02f8c5(@types/react@19.2.9)(mermaid@11.12.2)(react-dom@19.2.3(react@19.2.3))(react-server-dom-webpack@19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1))(react@19.2.3)(rollup@4.56.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(waku@1.0.0-alpha.2(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(react-dom@19.2.3(react@19.2.3))(react-server-dom-webpack@19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1))(react@19.2.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) wagmi: specifier: 3.4.1 version: 3.4.1(@tanstack/query-core@5.90.19)(@tanstack/react-query@5.90.19(react@19.2.3))(@types/react@19.2.9)(ox@0.11.3(typescript@5.9.3)(zod@4.3.5))(react@19.2.3)(typescript@5.9.3)(viem@2.44.4(typescript@5.9.3)(zod@4.3.5)) waku: specifier: 1.0.0-alpha.2 - version: 1.0.0-alpha.2(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(react-dom@19.2.3(react@19.2.3))(react-server-dom-webpack@19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1))(react@19.2.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + version: 1.0.0-alpha.2(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(react-dom@19.2.3(react@19.2.3))(react-server-dom-webpack@19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1))(react@19.2.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) zod: specifier: ^4.3.5 version: 4.3.5 @@ -105,8 +108,8 @@ importers: specifier: ^1.58.0 version: 1.58.0 '@types/node': - specifier: ^25.0.10 - version: 25.0.10 + specifier: ^25.1.0 + version: 25.2.0 '@types/react': specifier: ^19.2.9 version: 19.2.9 @@ -118,7 +121,7 @@ importers: version: 7.0.0-dev.20260122.3 '@vitejs/plugin-react': specifier: ^5.1.2 - version: 5.1.2(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + version: 5.1.2(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) anser: specifier: ^2.3.5 version: 2.3.5 @@ -129,14 +132,14 @@ importers: specifier: ^4.21.0 version: 4.21.0 typescript: - specifier: ~5.9.3 + specifier: ^5.9.3 version: 5.9.3 use-sync-external-store: specifier: ^1.6.0 version: 1.6.0(react@19.2.3) vite: specifier: ^7.3.1 - version: 7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + version: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) packages: @@ -732,6 +735,9 @@ packages: '@posthog/core@1.13.0': resolution: {integrity: sha512-knjncrk7qRmssFRbGzBl1Tunt21GRpe0Wv+uVelyL0Rh7PdQUsgguulzXFTps8hA6wPwTU4kq85qnbAJ3eH6Wg==} + '@posthog/core@1.20.0': + resolution: {integrity: sha512-e/F20we0t6bPMuDOVOe53f908s23vuKEpFKNXmZcx4bSYsPkjRN49akIIHU621HBJdcsFx537vhJYKZxu8uS9w==} + '@posthog/types@1.333.0': resolution: {integrity: sha512-9Wg/2ez+EZh6NmtOjhtYSkBHz/yIq8WMS0QSIizUoggh35hHVg4BTMXl3rz/tPearJNKU/8oRjEyuZ0OYTEDOA==} @@ -1350,8 +1356,8 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/node@25.0.10': - resolution: {integrity: sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==} + '@types/node@25.2.0': + resolution: {integrity: sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==} '@types/react-dom@19.2.3': resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} @@ -3143,6 +3149,10 @@ packages: posthog-js@1.333.0: resolution: {integrity: sha512-c7vquERMedjuGE2GnaDDJW/V1BIMMQG7BlYKrH0z8O7fc3WpEsQ/IyQ+9aD9+DLxlDCFpzrwgoxVDWi9K37mdA==} + posthog-node@5.24.10: + resolution: {integrity: sha512-C4ueZUrifTJMDFngybSWQ+GthcqCqPiCcGg5qnjoh+f6ie3+tdhFROqqshjttpQ6Q4DPM40USPTmU/UBYqgsbA==} + engines: {node: ^20.20.0 || >=22.22.0} + preact@10.28.2: resolution: {integrity: sha512-lbteaWGzGHdlIuiJ0l2Jq454m6kcpI1zNje6d8MlGAFlYvP2GO4ibnat7P74Esfz4sPTdM6UxtTwh/d3pwM9JA==} @@ -4620,6 +4630,10 @@ snapshots: dependencies: cross-spawn: 7.0.6 + '@posthog/core@1.20.0': + dependencies: + cross-spawn: 7.0.6 + '@posthog/types@1.333.0': {} '@protobufjs/aspromise@1.1.2': {} @@ -4962,12 +4976,12 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.1.18 '@tailwindcss/oxide-win32-x64-msvc': 4.1.18 - '@tailwindcss/vite@4.1.18(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@tailwindcss/vite@4.1.18(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@tailwindcss/node': 4.1.18 '@tailwindcss/oxide': 4.1.18 tailwindcss: 4.1.18 - vite: 7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) '@takumi-rs/core-darwin-arm64@0.62.8': optional: true @@ -5195,7 +5209,7 @@ snapshots: '@types/ms@2.1.0': {} - '@types/node@25.0.10': + '@types/node@25.2.0': dependencies: undici-types: 7.16.0 @@ -5262,7 +5276,7 @@ snapshots: optionalDependencies: react: 19.2.3 - '@vitejs/plugin-react@5.1.2(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@vitejs/plugin-react@5.1.2(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@babel/core': 7.28.6 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.6) @@ -5270,11 +5284,11 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.53 '@types/babel__core': 7.20.5 react-refresh: 0.18.0 - vite: 7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color - '@vitejs/plugin-rsc@0.5.16(react-dom@19.2.3(react@19.2.3))(react-server-dom-webpack@19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1))(react@19.2.3)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@vitejs/plugin-rsc@0.5.16(react-dom@19.2.3(react@19.2.3))(react-server-dom-webpack@19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1))(react@19.2.3)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: es-module-lexer: 2.0.0 estree-walker: 3.0.3 @@ -5285,8 +5299,8 @@ snapshots: srvx: 0.10.1 strip-literal: 3.1.0 turbo-stream: 3.1.0 - vite: 7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - vitefu: 1.1.1(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + vite: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vitefu: 1.1.1(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) optionalDependencies: react-server-dom-webpack: 19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1) @@ -6327,7 +6341,7 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 25.0.10 + '@types/node': 25.2.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -7183,6 +7197,10 @@ snapshots: query-selector-shadow-dom: 1.0.1 web-vitals: 4.2.4 + posthog-node@5.24.10: + dependencies: + '@posthog/core': 1.20.0 + preact@10.28.2: {} pretty-ms@9.3.0: @@ -7214,7 +7232,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 25.0.10 + '@types/node': 25.2.0 long: 5.3.2 proxy-addr@2.0.7: @@ -7931,11 +7949,11 @@ snapshots: vite-plugin-arraybuffer@0.1.2: {} - vite-plugin-wasm@3.5.0(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + vite-plugin-wasm@3.5.0(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): dependencies: - vite: 7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: esbuild: 0.27.2 fdir: 6.5.0(picomatch@4.0.3) @@ -7944,7 +7962,7 @@ snapshots: rollup: 4.56.0 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 25.0.10 + '@types/node': 25.2.0 fsevents: 2.3.3 jiti: 2.6.1 lightningcss: 1.30.2 @@ -7952,11 +7970,11 @@ snapshots: tsx: 4.21.0 yaml: 2.8.2 - vitefu@1.1.1(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + vitefu@1.1.1(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): optionalDependencies: - vite: 7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - vocs@https://pkg.pr.new/wevm/vocs@d02f8c5(@types/react@19.2.9)(mermaid@11.12.2)(react-dom@19.2.3(react@19.2.3))(react-server-dom-webpack@19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1))(react@19.2.3)(rollup@4.56.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(waku@1.0.0-alpha.2(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(react-dom@19.2.3(react@19.2.3))(react-server-dom-webpack@19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1))(react@19.2.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + vocs@https://pkg.pr.new/wevm/vocs@d02f8c5(@types/react@19.2.9)(mermaid@11.12.2)(react-dom@19.2.3(react@19.2.3))(react-server-dom-webpack@19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1))(react@19.2.3)(rollup@4.56.0)(typescript@5.9.3)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(waku@1.0.0-alpha.2(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(react-dom@19.2.3(react@19.2.3))(react-server-dom-webpack@19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1))(react@19.2.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): dependencies: '@base-ui/react': 1.1.0(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@codesandbox/sandpack-react': 2.20.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -7976,11 +7994,11 @@ snapshots: '@shikijs/types': 3.21.0 '@svgr/core': 8.1.0(typescript@5.9.3) '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3)) - '@tailwindcss/vite': 4.1.18(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@tailwindcss/vite': 4.1.18(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@takumi-rs/image-response': 0.62.8 '@takumi-rs/wasm': 0.62.8 - '@vitejs/plugin-react': 5.1.2(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) - '@vitejs/plugin-rsc': 0.5.16(react-dom@19.2.3(react@19.2.3))(react-server-dom-webpack@19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1))(react@19.2.3)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@vitejs/plugin-react': 5.1.2(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@vitejs/plugin-rsc': 0.5.16(react-dom@19.2.3(react@19.2.3))(react-server-dom-webpack@19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1))(react@19.2.3)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) cac: 6.7.14 cva: class-variance-authority@0.7.1 debug: 4.4.3 @@ -8026,13 +8044,13 @@ snapshots: urlpattern-polyfill: 10.1.0 vfile: 6.0.3 vite-plugin-arraybuffer: 0.1.2 - vite-plugin-wasm: 3.5.0(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + vite-plugin-wasm: 3.5.0(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) yaml: 2.8.2 zod: 4.3.5 optionalDependencies: mermaid: 11.12.2 - vite: 7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - waku: 1.0.0-alpha.2(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(react-dom@19.2.3(react@19.2.3))(react-server-dom-webpack@19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1))(react@19.2.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + waku: 1.0.0-alpha.2(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(react-dom@19.2.3(react@19.2.3))(react-server-dom-webpack@19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1))(react@19.2.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@cfworker/json-schema' - '@remix-run/react' @@ -8094,11 +8112,11 @@ snapshots: - ox - porto - waku@1.0.0-alpha.2(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(react-dom@19.2.3(react@19.2.3))(react-server-dom-webpack@19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1))(react@19.2.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + waku@1.0.0-alpha.2(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(react-dom@19.2.3(react@19.2.3))(react-server-dom-webpack@19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1))(react@19.2.3)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: '@hono/node-server': 1.19.9(hono@4.11.5) - '@vitejs/plugin-react': 5.1.2(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) - '@vitejs/plugin-rsc': 0.5.16(react-dom@19.2.3(react@19.2.3))(react-server-dom-webpack@19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1))(react@19.2.3)(vite@7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@vitejs/plugin-react': 5.1.2(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@vitejs/plugin-rsc': 0.5.16(react-dom@19.2.3(react@19.2.3))(react-server-dom-webpack@19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1))(react@19.2.3)(vite@7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) dotenv: 17.2.3 hono: 4.11.5 magic-string: 0.30.21 @@ -8107,7 +8125,7 @@ snapshots: react-dom: 19.2.3(react@19.2.3) react-server-dom-webpack: 19.2.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(webpack@5.104.1) rsc-html-stream: 0.0.7 - vite: 7.3.1(@types/node@25.0.10)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.1(@types/node@25.2.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - '@types/node' - jiti diff --git a/src/components/PostHogSetup.tsx b/src/components/PostHogSetup.tsx index d2e6e508..3b1e93ca 100644 --- a/src/components/PostHogSetup.tsx +++ b/src/components/PostHogSetup.tsx @@ -15,6 +15,12 @@ function PostHogInitializer() { defaults: '2025-05-24', capture_exceptions: true, debug: import.meta.env.MODE === 'development', + session_recording: { + maskAllInputs: false, + maskInputOptions: { + password: true, + }, + }, loaded: (posthog) => { posthog.capture('$pageview') }, diff --git a/src/lib/feedback-adapter.ts b/src/lib/feedback-adapter.ts new file mode 100644 index 00000000..6574b587 --- /dev/null +++ b/src/lib/feedback-adapter.ts @@ -0,0 +1,75 @@ +import { Feedback } from 'vocs/config' +import { PostHog } from 'posthog-node' +import { POSTHOG_EVENTS, POSTHOG_PROPERTIES } from './posthog' + +type FeedbackData = { + helpful: boolean + category?: string | undefined + message?: string | undefined + pageUrl: string + timestamp: string +} + +/** + * Creates a combined feedback adapter that sends to both Slack and PostHog. + * + * PostHog events captured: + * - docs_feedback_submitted: All feedback submissions + * - docs_feedback_helpful: When user marks page as helpful + * - docs_feedback_not_helpful: When user marks page as not helpful + */ +export function createFeedbackAdapter() { + const slackAdapter = Feedback.slack() + + const posthogKey = process.env['VITE_POSTHOG_KEY'] + const posthogHost = process.env['VITE_POSTHOG_HOST'] || 'https://us.i.posthog.com' + + const posthog = posthogKey + ? new PostHog(posthogKey, { host: posthogHost }) + : null + + return Feedback.from({ + type: 'slack+posthog', + async submit(data: FeedbackData) { + const promises: Promise[] = [] + + // Send to Slack + promises.push(slackAdapter.submit(data)) + + // Send to PostHog + if (posthog) { + const distinctId = `docs_feedback_${Date.now()}_${Math.random().toString(36).slice(2)}` + + const commonProperties = { + [POSTHOG_PROPERTIES.FEEDBACK_HELPFUL]: data.helpful, + [POSTHOG_PROPERTIES.FEEDBACK_CATEGORY]: data.category, + [POSTHOG_PROPERTIES.FEEDBACK_MESSAGE]: data.message, + [POSTHOG_PROPERTIES.FEEDBACK_PAGE_URL]: data.pageUrl, + [POSTHOG_PROPERTIES.PAGE_PATH]: new URL(data.pageUrl).pathname, + [POSTHOG_PROPERTIES.SITE]: 'docs', + timestamp: data.timestamp, + } + + // Capture main feedback event + posthog.capture({ + distinctId, + event: POSTHOG_EVENTS.FEEDBACK_SUBMITTED, + properties: commonProperties, + }) + + // Capture sentiment-specific event for easier filtering + posthog.capture({ + distinctId, + event: data.helpful + ? POSTHOG_EVENTS.FEEDBACK_HELPFUL + : POSTHOG_EVENTS.FEEDBACK_NOT_HELPFUL, + properties: commonProperties, + }) + + promises.push(posthog.flush().then(() => {})) + } + + await Promise.all(promises) + }, + }) +} diff --git a/src/lib/posthog.ts b/src/lib/posthog.ts index f4310352..32878481 100644 --- a/src/lib/posthog.ts +++ b/src/lib/posthog.ts @@ -35,6 +35,11 @@ export const POSTHOG_EVENTS = { // Code interactions CODE_EXAMPLE_VIEW: 'docs_code_example_view', CODE_EXAMPLE_COPY: 'docs_code_example_copy', + + // Feedback + FEEDBACK_SUBMITTED: 'docs_feedback_submitted', + FEEDBACK_HELPFUL: 'docs_feedback_helpful', + FEEDBACK_NOT_HELPFUL: 'docs_feedback_not_helpful', } as const /** @@ -68,6 +73,12 @@ export const POSTHOG_PROPERTIES = { SEARCH_QUERY: 'search_query', SEARCH_RESULT_TITLE: 'search_result_title', SEARCH_RESULT_URL: 'search_result_url', + + // Feedback properties + FEEDBACK_HELPFUL: 'feedback_helpful', + FEEDBACK_CATEGORY: 'feedback_category', + FEEDBACK_MESSAGE: 'feedback_message', + FEEDBACK_PAGE_URL: 'feedback_page_url', } as const /** diff --git a/vocs.config.ts b/vocs.config.ts index 900c8ed2..450eaa5d 100644 --- a/vocs.config.ts +++ b/vocs.config.ts @@ -1,4 +1,5 @@ -import { Changelog, defineConfig, Feedback, McpSource } from 'vocs/config' +import { Changelog, defineConfig, McpSource } from 'vocs/config' +import { createFeedbackAdapter } from './src/lib/feedback-adapter' const baseUrl = (() => { if (process.env.VERCEL_ENV === 'production') @@ -14,7 +15,7 @@ export default defineConfig({ title: 'Tempo', titleTemplate: '%s ⋅ Tempo', description: 'Documentation for the Tempo network and protocol specifications', - feedback: Feedback.slack(), + feedback: createFeedbackAdapter(), mcp: { enabled: true, sources: [