linkedin-automation-cli 1.0.0

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.
Files changed (314) hide show
  1. package/.env.example +12 -0
  2. package/.github/workflows/ci.yml +66 -0
  3. package/.github/workflows/publish.yml +48 -0
  4. package/.husky/pre-commit +6 -0
  5. package/.prettierignore +4 -0
  6. package/.prettierrc +10 -0
  7. package/AGENTS.md +294 -0
  8. package/CHANGELOG.md +40 -0
  9. package/GIT_RELEASE.md +167 -0
  10. package/LICENSE +21 -0
  11. package/Makefile +30 -0
  12. package/NPM_PUBLISHING.md +230 -0
  13. package/PYEOF +0 -0
  14. package/README.md +295 -0
  15. package/TESTING-GUIDE.md +151 -0
  16. package/cmd/linkedin/main.go +9 -0
  17. package/dist/agent/action-executor.d.ts +81 -0
  18. package/dist/agent/action-executor.d.ts.map +1 -0
  19. package/dist/agent/action-executor.js +170 -0
  20. package/dist/agent/action-executor.js.map +1 -0
  21. package/dist/agent/action-executor.test.d.ts +2 -0
  22. package/dist/agent/action-executor.test.d.ts.map +1 -0
  23. package/dist/agent/action-executor.test.js +366 -0
  24. package/dist/agent/action-executor.test.js.map +1 -0
  25. package/dist/agent/claude-client.d.ts +74 -0
  26. package/dist/agent/claude-client.d.ts.map +1 -0
  27. package/dist/agent/claude-client.js +314 -0
  28. package/dist/agent/claude-client.js.map +1 -0
  29. package/dist/agent/claude-client.test.d.ts +2 -0
  30. package/dist/agent/claude-client.test.d.ts.map +1 -0
  31. package/dist/agent/claude-client.test.js +590 -0
  32. package/dist/agent/claude-client.test.js.map +1 -0
  33. package/dist/agent/dom-extractor.d.ts +50 -0
  34. package/dist/agent/dom-extractor.d.ts.map +1 -0
  35. package/dist/agent/dom-extractor.js +374 -0
  36. package/dist/agent/dom-extractor.js.map +1 -0
  37. package/dist/agent/dom-extractor.test.d.ts +7 -0
  38. package/dist/agent/dom-extractor.test.d.ts.map +1 -0
  39. package/dist/agent/dom-extractor.test.js +504 -0
  40. package/dist/agent/dom-extractor.test.js.map +1 -0
  41. package/dist/agent/extension-client.d.ts +75 -0
  42. package/dist/agent/extension-client.d.ts.map +1 -0
  43. package/dist/agent/extension-client.js +245 -0
  44. package/dist/agent/extension-client.js.map +1 -0
  45. package/dist/agent/index.d.ts +8 -0
  46. package/dist/agent/index.d.ts.map +1 -0
  47. package/dist/agent/index.js +16 -0
  48. package/dist/agent/index.js.map +1 -0
  49. package/dist/agent/page-agent.d.ts +76 -0
  50. package/dist/agent/page-agent.d.ts.map +1 -0
  51. package/dist/agent/page-agent.js +236 -0
  52. package/dist/agent/page-agent.js.map +1 -0
  53. package/dist/agent/types.d.ts +236 -0
  54. package/dist/agent/types.d.ts.map +1 -0
  55. package/dist/agent/types.js +37 -0
  56. package/dist/agent/types.js.map +1 -0
  57. package/dist/cli/agent-commands.d.ts +3 -0
  58. package/dist/cli/agent-commands.d.ts.map +1 -0
  59. package/dist/cli/agent-commands.js +250 -0
  60. package/dist/cli/agent-commands.js.map +1 -0
  61. package/dist/cli/auth.d.ts +3 -0
  62. package/dist/cli/auth.d.ts.map +1 -0
  63. package/dist/cli/auth.js +288 -0
  64. package/dist/cli/auth.js.map +1 -0
  65. package/dist/cli/company.d.ts +3 -0
  66. package/dist/cli/company.d.ts.map +1 -0
  67. package/dist/cli/company.js +55 -0
  68. package/dist/cli/company.js.map +1 -0
  69. package/dist/cli/connection.d.ts +3 -0
  70. package/dist/cli/connection.d.ts.map +1 -0
  71. package/dist/cli/connection.js +79 -0
  72. package/dist/cli/connection.js.map +1 -0
  73. package/dist/cli/index.d.ts +7 -0
  74. package/dist/cli/index.d.ts.map +1 -0
  75. package/dist/cli/index.js +17 -0
  76. package/dist/cli/index.js.map +1 -0
  77. package/dist/cli/messages.d.ts +3 -0
  78. package/dist/cli/messages.d.ts.map +1 -0
  79. package/dist/cli/messages.js +268 -0
  80. package/dist/cli/messages.js.map +1 -0
  81. package/dist/cli/profile.d.ts +3 -0
  82. package/dist/cli/profile.d.ts.map +1 -0
  83. package/dist/cli/profile.js +81 -0
  84. package/dist/cli/profile.js.map +1 -0
  85. package/dist/cli/profile.test.d.ts +2 -0
  86. package/dist/cli/profile.test.d.ts.map +1 -0
  87. package/dist/cli/profile.test.js +15 -0
  88. package/dist/cli/profile.test.js.map +1 -0
  89. package/dist/cli/reply.d.ts +3 -0
  90. package/dist/cli/reply.d.ts.map +1 -0
  91. package/dist/cli/reply.js +129 -0
  92. package/dist/cli/reply.js.map +1 -0
  93. package/dist/core/audit.d.ts +17 -0
  94. package/dist/core/audit.d.ts.map +1 -0
  95. package/dist/core/audit.js +121 -0
  96. package/dist/core/audit.js.map +1 -0
  97. package/dist/core/audit.test.d.ts +2 -0
  98. package/dist/core/audit.test.d.ts.map +1 -0
  99. package/dist/core/audit.test.js +142 -0
  100. package/dist/core/audit.test.js.map +1 -0
  101. package/dist/core/browser-cookies.d.ts +19 -0
  102. package/dist/core/browser-cookies.d.ts.map +1 -0
  103. package/dist/core/browser-cookies.js +181 -0
  104. package/dist/core/browser-cookies.js.map +1 -0
  105. package/dist/core/browser.d.ts +50 -0
  106. package/dist/core/browser.d.ts.map +1 -0
  107. package/dist/core/browser.js +318 -0
  108. package/dist/core/browser.js.map +1 -0
  109. package/dist/core/config.d.ts +20 -0
  110. package/dist/core/config.d.ts.map +1 -0
  111. package/dist/core/config.js +103 -0
  112. package/dist/core/config.js.map +1 -0
  113. package/dist/core/config.test.d.ts +2 -0
  114. package/dist/core/config.test.d.ts.map +1 -0
  115. package/dist/core/config.test.js +111 -0
  116. package/dist/core/config.test.js.map +1 -0
  117. package/dist/core/storage.d.ts +19 -0
  118. package/dist/core/storage.d.ts.map +1 -0
  119. package/dist/core/storage.js +124 -0
  120. package/dist/core/storage.js.map +1 -0
  121. package/dist/core/storage.test.d.ts +2 -0
  122. package/dist/core/storage.test.d.ts.map +1 -0
  123. package/dist/core/storage.test.js +142 -0
  124. package/dist/core/storage.test.js.map +1 -0
  125. package/dist/index.d.ts +3 -0
  126. package/dist/index.d.ts.map +1 -0
  127. package/dist/index.js +63 -0
  128. package/dist/index.js.map +1 -0
  129. package/dist/linkedin/auth.d.ts +22 -0
  130. package/dist/linkedin/auth.d.ts.map +1 -0
  131. package/dist/linkedin/auth.js +167 -0
  132. package/dist/linkedin/auth.js.map +1 -0
  133. package/dist/linkedin/company-extractor.d.ts +36 -0
  134. package/dist/linkedin/company-extractor.d.ts.map +1 -0
  135. package/dist/linkedin/company-extractor.js +211 -0
  136. package/dist/linkedin/company-extractor.js.map +1 -0
  137. package/dist/linkedin/company-extractor.test.d.ts +2 -0
  138. package/dist/linkedin/company-extractor.test.d.ts.map +1 -0
  139. package/dist/linkedin/company-extractor.test.js +52 -0
  140. package/dist/linkedin/company-extractor.test.js.map +1 -0
  141. package/dist/linkedin/connector.d.ts +45 -0
  142. package/dist/linkedin/connector.d.ts.map +1 -0
  143. package/dist/linkedin/connector.js +245 -0
  144. package/dist/linkedin/connector.js.map +1 -0
  145. package/dist/linkedin/message-sender.d.ts +32 -0
  146. package/dist/linkedin/message-sender.d.ts.map +1 -0
  147. package/dist/linkedin/message-sender.js +112 -0
  148. package/dist/linkedin/message-sender.js.map +1 -0
  149. package/dist/linkedin/messages.d.ts +78 -0
  150. package/dist/linkedin/messages.d.ts.map +1 -0
  151. package/dist/linkedin/messages.js +745 -0
  152. package/dist/linkedin/messages.js.map +1 -0
  153. package/dist/linkedin/profile.d.ts +37 -0
  154. package/dist/linkedin/profile.d.ts.map +1 -0
  155. package/dist/linkedin/profile.js +268 -0
  156. package/dist/linkedin/profile.js.map +1 -0
  157. package/dist/linkedin/profile.test.d.ts +2 -0
  158. package/dist/linkedin/profile.test.d.ts.map +1 -0
  159. package/dist/linkedin/profile.test.js +68 -0
  160. package/dist/linkedin/profile.test.js.map +1 -0
  161. package/dist/linkedin/reply.d.ts +21 -0
  162. package/dist/linkedin/reply.d.ts.map +1 -0
  163. package/dist/linkedin/reply.js +76 -0
  164. package/dist/linkedin/reply.js.map +1 -0
  165. package/dist/linkedin/selector-engine.d.ts +69 -0
  166. package/dist/linkedin/selector-engine.d.ts.map +1 -0
  167. package/dist/linkedin/selector-engine.js +339 -0
  168. package/dist/linkedin/selector-engine.js.map +1 -0
  169. package/dist/linkedin/selector-engine.test.d.ts +2 -0
  170. package/dist/linkedin/selector-engine.test.d.ts.map +1 -0
  171. package/dist/linkedin/selector-engine.test.js +135 -0
  172. package/dist/linkedin/selector-engine.test.js.map +1 -0
  173. package/dist/linkedin/selectors.d.ts +65 -0
  174. package/dist/linkedin/selectors.d.ts.map +1 -0
  175. package/dist/linkedin/selectors.js +261 -0
  176. package/dist/linkedin/selectors.js.map +1 -0
  177. package/dist/templates/engine.d.ts +37 -0
  178. package/dist/templates/engine.d.ts.map +1 -0
  179. package/dist/templates/engine.js +215 -0
  180. package/dist/templates/engine.js.map +1 -0
  181. package/dist/templates/engine.test.d.ts +2 -0
  182. package/dist/templates/engine.test.d.ts.map +1 -0
  183. package/dist/templates/engine.test.js +212 -0
  184. package/dist/templates/engine.test.js.map +1 -0
  185. package/dist/templates/index.d.ts +2 -0
  186. package/dist/templates/index.d.ts.map +1 -0
  187. package/dist/templates/index.js +7 -0
  188. package/dist/templates/index.js.map +1 -0
  189. package/dist/types/index.d.ts +113 -0
  190. package/dist/types/index.d.ts.map +1 -0
  191. package/dist/types/index.js +3 -0
  192. package/dist/types/index.js.map +1 -0
  193. package/dist/types/index.test.d.ts +2 -0
  194. package/dist/types/index.test.d.ts.map +1 -0
  195. package/dist/types/index.test.js +90 -0
  196. package/dist/types/index.test.js.map +1 -0
  197. package/dist/utils/paths.d.ts +8 -0
  198. package/dist/utils/paths.d.ts.map +1 -0
  199. package/dist/utils/paths.js +68 -0
  200. package/dist/utils/paths.js.map +1 -0
  201. package/dist/utils/rate-limiter.d.ts +22 -0
  202. package/dist/utils/rate-limiter.d.ts.map +1 -0
  203. package/dist/utils/rate-limiter.js +57 -0
  204. package/dist/utils/rate-limiter.js.map +1 -0
  205. package/dist/utils/retry.d.ts +18 -0
  206. package/dist/utils/retry.d.ts.map +1 -0
  207. package/dist/utils/retry.js +49 -0
  208. package/dist/utils/retry.js.map +1 -0
  209. package/docs/connection-command.md +52 -0
  210. package/docs/plans/2025-03-03-linkedin-cli-design.md +280 -0
  211. package/docs/plans/2025-03-03-linkedin-cli-implementation-plan.md +2087 -0
  212. package/docs/plans/2025-03-03-linkedin-cli-implementation.md +2420 -0
  213. package/docs/plans/2026-02-19-linkedin-connection-feature.md +596 -0
  214. package/docs/plans/2026-02-28-messages-send-feature.md +480 -0
  215. package/docs/plans/2026-02-28-messages-show-design.md +243 -0
  216. package/docs/plans/2026-03-03-linkedin-cli-oss-publishing-design.md +394 -0
  217. package/docs/plans/2026-03-03-linkedin-cli-oss-publishing-plan.md +1592 -0
  218. package/docs/superpowers/plans/2026-03-13-linkedin-automation-resilience-migration.md +425 -0
  219. package/docs/superpowers/plans/2026-03-13-playwright-fara-migration.md +1112 -0
  220. package/docs/superpowers/plans/2026-03-14-page-agent-plan.md +1598 -0
  221. package/docs/superpowers/plans/2026-03-15-company-profile-extraction.md +591 -0
  222. package/docs/superpowers/plans/2026-03-15-profile-extraction-plan.md +943 -0
  223. package/docs/superpowers/specs/2026-03-14-company-profile-extraction-design.md +371 -0
  224. package/docs/superpowers/specs/2026-03-14-page-agent-design.md +385 -0
  225. package/docs/superpowers/specs/2026-03-15-profile-extraction-design.md +409 -0
  226. package/eslint.config.mjs +58 -0
  227. package/go.mod +9 -0
  228. package/go.sum +10 -0
  229. package/import-cookies.js +376 -0
  230. package/internal/cmd/actions.go +123 -0
  231. package/internal/cmd/auth.go +108 -0
  232. package/internal/cmd/connect.go +42 -0
  233. package/internal/cmd/message.go +44 -0
  234. package/internal/cmd/people.go +454 -0
  235. package/internal/cmd/profiles.go +121 -0
  236. package/internal/cmd/root.go +89 -0
  237. package/internal/cmd/sequence.go +192 -0
  238. package/internal/config/config.go +187 -0
  239. package/internal/config/config_test.go +121 -0
  240. package/internal/config/profile.go +65 -0
  241. package/internal/linkedin/navigator.go +195 -0
  242. package/internal/linkedin/selectors.go +39 -0
  243. package/internal/linkedin/validator.go +69 -0
  244. package/internal/pinchtab/client.go +183 -0
  245. package/internal/pinchtab/client_test.go +67 -0
  246. package/internal/pinchtab/types.go +50 -0
  247. package/internal/ratelimit/limiter.go +115 -0
  248. package/internal/ratelimit/limits.go +32 -0
  249. package/package.json +67 -0
  250. package/release.sh +66 -0
  251. package/scripts/debug-linkedin.js +156 -0
  252. package/scripts/debug-login.js +193 -0
  253. package/scripts/extract-from-edge.js +96 -0
  254. package/scripts/import-cookies.js +101 -0
  255. package/scripts/poc-show-data.js +205 -0
  256. package/scripts/proof-of-access.js +87 -0
  257. package/scripts/prove-connection.js +110 -0
  258. package/scripts/show-linkedin-data.js +173 -0
  259. package/src/agent/action-executor.test.ts +464 -0
  260. package/src/agent/action-executor.ts +203 -0
  261. package/src/agent/claude-client.test.ts +707 -0
  262. package/src/agent/claude-client.ts +422 -0
  263. package/src/agent/dom-extractor.test.ts +574 -0
  264. package/src/agent/dom-extractor.ts +437 -0
  265. package/src/agent/extension-client.ts +306 -0
  266. package/src/agent/index.ts +28 -0
  267. package/src/agent/page-agent.ts +292 -0
  268. package/src/agent/types.ts +288 -0
  269. package/src/cli/agent-commands.ts +274 -0
  270. package/src/cli/auth.ts +343 -0
  271. package/src/cli/company.ts +66 -0
  272. package/src/cli/connection.ts +89 -0
  273. package/src/cli/index.ts +7 -0
  274. package/src/cli/messages.ts +338 -0
  275. package/src/cli/profile.test.ts +14 -0
  276. package/src/cli/profile.ts +95 -0
  277. package/src/cli/reply.ts +110 -0
  278. package/src/core/audit.test.ts +134 -0
  279. package/src/core/audit.ts +98 -0
  280. package/src/core/browser-cookies.ts +203 -0
  281. package/src/core/browser.ts +304 -0
  282. package/src/core/config.test.ts +90 -0
  283. package/src/core/config.ts +81 -0
  284. package/src/core/storage.test.ts +129 -0
  285. package/src/core/storage.ts +100 -0
  286. package/src/index.ts +70 -0
  287. package/src/linkedin/auth.ts +218 -0
  288. package/src/linkedin/company-extractor.test.ts +58 -0
  289. package/src/linkedin/company-extractor.ts +222 -0
  290. package/src/linkedin/connector.ts +336 -0
  291. package/src/linkedin/message-sender.ts +141 -0
  292. package/src/linkedin/messages.ts +894 -0
  293. package/src/linkedin/profile.test.ts +79 -0
  294. package/src/linkedin/profile.ts +314 -0
  295. package/src/linkedin/reply.ts +96 -0
  296. package/src/linkedin/selector-engine.test.ts +167 -0
  297. package/src/linkedin/selector-engine.ts +393 -0
  298. package/src/linkedin/selectors.ts +268 -0
  299. package/src/templates/defaults/followup.txt +14 -0
  300. package/src/templates/defaults/meeting.txt +16 -0
  301. package/src/templates/defaults/welcome.txt +14 -0
  302. package/src/templates/engine.test.ts +228 -0
  303. package/src/templates/engine.ts +208 -0
  304. package/src/templates/index.ts +1 -0
  305. package/src/types/index.test.ts +94 -0
  306. package/src/types/index.ts +143 -0
  307. package/src/types/sql.js.d.ts +23 -0
  308. package/src/utils/paths.ts +33 -0
  309. package/src/utils/rate-limiter.ts +75 -0
  310. package/src/utils/retry.ts +78 -0
  311. package/test-cli.sh +85 -0
  312. package/test-real-data.sh +97 -0
  313. package/tsconfig.json +23 -0
  314. package/vitest.config.ts +35 -0
@@ -0,0 +1,245 @@
1
+ "use strict";
2
+ /**
3
+ * Page Agent Extension Client
4
+ *
5
+ * Uses direct WebSocket connection to Chrome DevTools Protocol
6
+ * following the official Page Agent usage guide.
7
+ */
8
+ var __importDefault = (this && this.__importDefault) || function (mod) {
9
+ return (mod && mod.__esModule) ? mod : { "default": mod };
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.PageAgentExtensionClient = void 0;
13
+ exports.getAuthToken = getAuthToken;
14
+ const ws_1 = __importDefault(require("ws"));
15
+ const DEFAULT_BASE_URL = 'https://open.bigmodel.cn/api/paas/v4';
16
+ const DEFAULT_MODEL = 'glm-5';
17
+ const DEFAULT_PORT = 9222;
18
+ /**
19
+ * Client for the Alibaba Page Agent browser extension
20
+ */
21
+ class PageAgentExtensionClient {
22
+ config;
23
+ debug;
24
+ constructor(config) {
25
+ this.config = {
26
+ baseURL: config.baseURL ?? DEFAULT_BASE_URL,
27
+ model: config.model ?? DEFAULT_MODEL,
28
+ port: config.port ?? DEFAULT_PORT,
29
+ authToken: config.authToken,
30
+ apiKey: config.apiKey,
31
+ debug: config.debug ?? false,
32
+ };
33
+ this.debug = config.debug ?? false;
34
+ }
35
+ /**
36
+ * List available browser pages
37
+ */
38
+ async listPages() {
39
+ const response = await fetch(`http://localhost:${this.config.port}/json/list`);
40
+ const pages = await response.json();
41
+ return pages
42
+ .filter((p) => p.type === 'page')
43
+ .map((p) => ({ id: p.id, url: p.url, title: p.title }));
44
+ }
45
+ /**
46
+ * Find a page by URL pattern
47
+ */
48
+ async findPage(urlPattern) {
49
+ const pages = await this.listPages();
50
+ const page = pages.find((p) => p.url.includes(urlPattern));
51
+ return page?.id ?? null;
52
+ }
53
+ /**
54
+ * Execute JavaScript on a page via CDP WebSocket
55
+ * Simplified version following the guide pattern
56
+ */
57
+ async evaluate(ws, expression, awaitPromise = false) {
58
+ return new Promise((resolve, reject) => {
59
+ const id = Math.floor(Math.random() * 1000000);
60
+ let resolved = false;
61
+ const timeout = setTimeout(() => {
62
+ if (!resolved) {
63
+ resolved = true;
64
+ ws.off('message', handler);
65
+ reject(new Error('Evaluation timeout'));
66
+ }
67
+ }, 60000);
68
+ const handler = (data) => {
69
+ if (resolved)
70
+ return;
71
+ try {
72
+ const response = JSON.parse(data.toString());
73
+ if (response.id === id) {
74
+ resolved = true;
75
+ clearTimeout(timeout);
76
+ ws.off('message', handler);
77
+ if (response.error) {
78
+ reject(new Error(response.error.message));
79
+ }
80
+ else {
81
+ resolve(response.result?.result?.value);
82
+ }
83
+ }
84
+ }
85
+ catch {
86
+ // Ignore parse errors
87
+ }
88
+ };
89
+ ws.on('message', handler);
90
+ ws.send(JSON.stringify({
91
+ id,
92
+ method: 'Runtime.evaluate',
93
+ params: {
94
+ expression,
95
+ returnByValue: true,
96
+ awaitPromise,
97
+ },
98
+ }));
99
+ });
100
+ }
101
+ /**
102
+ * Execute a task on a specific page
103
+ */
104
+ async executeOnPage(pageId, task) {
105
+ const wsUrl = `ws://localhost:${this.config.port}/devtools/page/${pageId}`;
106
+ this.log('Connecting to:', wsUrl);
107
+ return new Promise((resolve, reject) => {
108
+ const ws = new ws_1.default(wsUrl);
109
+ let settled = false;
110
+ ws.on('error', (err) => {
111
+ if (!settled) {
112
+ settled = true;
113
+ reject(new Error(`WebSocket error: ${err.message}`));
114
+ }
115
+ });
116
+ ws.on('open', async () => {
117
+ if (settled)
118
+ return;
119
+ try {
120
+ this.log('Connected, setting auth token...');
121
+ // Step 1: Set auth token
122
+ await this.evaluate(ws, `localStorage.setItem('PageAgentExtUserAuthToken', '${this.config.authToken}')`);
123
+ this.log('Auth token set');
124
+ // Step 2: Wait for extension to inject API (3 seconds as per guide)
125
+ this.log('Waiting 3 seconds for extension injection...');
126
+ await new Promise((r) => setTimeout(r, 3000));
127
+ // Step 3: Verify extension is available
128
+ const extCheck = await this.evaluate(ws, `({
129
+ version: window.PAGE_AGENT_EXT_VERSION,
130
+ hasExt: !!window.PAGE_AGENT_EXT,
131
+ canExecute: typeof window.PAGE_AGENT_EXT?.execute === 'function'
132
+ })`);
133
+ this.log('Extension check:', extCheck);
134
+ if (!extCheck?.hasExt) {
135
+ settled = true;
136
+ ws.close();
137
+ resolve({
138
+ success: false,
139
+ status: 'error',
140
+ message: 'Page Agent extension not found. Check auth token.',
141
+ });
142
+ return;
143
+ }
144
+ this.log('Extension detected, version:', extCheck.version);
145
+ // Step 4: Execute task
146
+ this.log('Executing task:', task.substring(0, 100) + '...');
147
+ const result = await this.evaluate(ws, `(async () => {
148
+ try {
149
+ const response = await window.PAGE_AGENT_EXT.execute(
150
+ ${JSON.stringify(task)},
151
+ {
152
+ baseURL: ${JSON.stringify(this.config.baseURL)},
153
+ apiKey: ${JSON.stringify(this.config.apiKey)},
154
+ model: ${JSON.stringify(this.config.model)},
155
+ includeInitialTab: true,
156
+ onStatusChange: (status) => console.log('[Status]', status),
157
+ onActivity: (activity) => console.log('[Activity]', JSON.stringify(activity))
158
+ }
159
+ );
160
+ return { success: true, data: response };
161
+ } catch (error) {
162
+ return { success: false, error: error.message };
163
+ }
164
+ })()`, true // awaitPromise
165
+ );
166
+ this.log('Task result:', JSON.stringify(result)?.substring(0, 500));
167
+ settled = true;
168
+ ws.close();
169
+ resolve({
170
+ success: result?.success ?? false,
171
+ status: result?.success ? 'completed' : 'error',
172
+ message: result?.success ? 'Task completed' : result?.error || 'Unknown error',
173
+ data: typeof result?.data === 'string' ? result.data : JSON.stringify(result?.data),
174
+ });
175
+ }
176
+ catch (err) {
177
+ settled = true;
178
+ ws.close();
179
+ resolve({
180
+ success: false,
181
+ status: 'error',
182
+ message: err.message,
183
+ });
184
+ }
185
+ });
186
+ });
187
+ }
188
+ /**
189
+ * Send a connection request on a LinkedIn profile
190
+ */
191
+ async connect(_profileUrl, note) {
192
+ // Step 1: Find LinkedIn page
193
+ this.log('Looking for LinkedIn page...');
194
+ let pageId = await this.findPage('linkedin.com/in/');
195
+ if (!pageId) {
196
+ pageId = await this.findPage('linkedin.com');
197
+ }
198
+ if (!pageId) {
199
+ return {
200
+ success: false,
201
+ status: 'error',
202
+ message: 'No LinkedIn page found. Please open a LinkedIn profile in your browser.',
203
+ };
204
+ }
205
+ this.log('Found LinkedIn page:', pageId);
206
+ // Step 2: Build task
207
+ const task = `On this LinkedIn profile page:
208
+ 1. Click the "Connect" button (or find it in "More" menu if not visible)
209
+ 2. If a modal opens with "Add a note" option, click it
210
+ 3. Type this message: "${note}"
211
+ 4. STOP - Do NOT click Send button
212
+ 5. Report success
213
+
214
+ Important: Work on the current page. Do not navigate away.`;
215
+ // Step 3: Execute on that page
216
+ return this.executeOnPage(pageId, task);
217
+ }
218
+ /**
219
+ * Log debug messages
220
+ */
221
+ log(message, data) {
222
+ if (this.debug) {
223
+ if (data !== undefined) {
224
+ console.log(`[ExtensionClient] ${message}`, data);
225
+ }
226
+ else {
227
+ console.log(`[ExtensionClient] ${message}`);
228
+ }
229
+ }
230
+ }
231
+ }
232
+ exports.PageAgentExtensionClient = PageAgentExtensionClient;
233
+ /**
234
+ * Get the Page Agent auth token from environment variable
235
+ * @throws Error if PAGE_AGENT_AUTH_TOKEN is not set
236
+ */
237
+ function getAuthToken() {
238
+ const token = process.env.PAGE_AGENT_AUTH_TOKEN;
239
+ if (!token) {
240
+ throw new Error('PAGE_AGENT_AUTH_TOKEN environment variable is required. ' +
241
+ 'Get your auth token from the Page Agent extension side panel.');
242
+ }
243
+ return token;
244
+ }
245
+ //# sourceMappingURL=extension-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-client.js","sourceRoot":"","sources":["../../src/agent/extension-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export type { Action, ActionContext, ActionPlan, BoundingBox, ClaudeClientConfig, ClickAction, ConnectionResult, DOMElement, DOMRepresentation, ExecutedAction, MessageResult, NavigateAction, PageMetadata, Task, TaskResult, TypeAction, WaitAction, } from './types';
2
+ export { DOMExtractor } from './dom-extractor';
3
+ export { ClaudeClient } from './claude-client';
4
+ export { ActionExecutor } from './action-executor';
5
+ export { PageAgent } from './page-agent';
6
+ export { PageAgentExtensionClient, getAuthToken } from './extension-client';
7
+ export type { ExtensionClientConfig, ExtensionResult } from './extension-client';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,MAAM,EACN,aAAa,EACb,UAAU,EACV,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,gBAAgB,EAChB,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,cAAc,EACd,YAAY,EACZ,IAAI,EACJ,UAAU,EACV,UAAU,EACV,UAAU,GACX,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,wBAAwB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC5E,YAAY,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAuthToken = exports.PageAgentExtensionClient = exports.PageAgent = exports.ActionExecutor = exports.ClaudeClient = exports.DOMExtractor = void 0;
4
+ // Classes
5
+ var dom_extractor_1 = require("./dom-extractor");
6
+ Object.defineProperty(exports, "DOMExtractor", { enumerable: true, get: function () { return dom_extractor_1.DOMExtractor; } });
7
+ var claude_client_1 = require("./claude-client");
8
+ Object.defineProperty(exports, "ClaudeClient", { enumerable: true, get: function () { return claude_client_1.ClaudeClient; } });
9
+ var action_executor_1 = require("./action-executor");
10
+ Object.defineProperty(exports, "ActionExecutor", { enumerable: true, get: function () { return action_executor_1.ActionExecutor; } });
11
+ var page_agent_1 = require("./page-agent");
12
+ Object.defineProperty(exports, "PageAgent", { enumerable: true, get: function () { return page_agent_1.PageAgent; } });
13
+ var extension_client_1 = require("./extension-client");
14
+ Object.defineProperty(exports, "PageAgentExtensionClient", { enumerable: true, get: function () { return extension_client_1.PageAgentExtensionClient; } });
15
+ Object.defineProperty(exports, "getAuthToken", { enumerable: true, get: function () { return extension_client_1.getAuthToken; } });
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":";;;AAqBA,UAAU;AACV,iDAA+C;AAAtC,6GAAA,YAAY,OAAA;AACrB,iDAA+C;AAAtC,6GAAA,YAAY,OAAA;AACrB,qDAAmD;AAA1C,iHAAA,cAAc,OAAA;AACvB,2CAAyC;AAAhC,uGAAA,SAAS,OAAA;AAClB,uDAA4E;AAAnE,4HAAA,wBAAwB,OAAA;AAAE,gHAAA,YAAY,OAAA"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Page Agent Orchestrator Module
3
+ *
4
+ * Combines DOM extractor, Claude client, and action executor into a cohesive workflow.
5
+ * Provides high-level methods for LinkedIn automation tasks with retry logic and error recovery.
6
+ */
7
+ import type { Page } from 'playwright';
8
+ import type { Task, TaskResult, ConnectionResult, MessageResult, ClaudeClientConfig } from './types';
9
+ /**
10
+ * Configuration options for PageAgent
11
+ */
12
+ export interface PageAgentOptions {
13
+ /** Configuration for Claude API client */
14
+ claudeConfig: ClaudeClientConfig;
15
+ /** Maximum number of retry attempts for failed actions (default: 3) */
16
+ maxRetries?: number;
17
+ /** Enable debug logging (default: false) */
18
+ debug?: boolean;
19
+ }
20
+ /**
21
+ * High-level agent for executing tasks on LinkedIn pages
22
+ * Orchestrates DOM extraction, action planning, and execution
23
+ */
24
+ export declare class PageAgent {
25
+ private readonly claudeClient;
26
+ private readonly domExtractor;
27
+ private readonly maxRetries;
28
+ private readonly debug;
29
+ /**
30
+ * Creates a new PageAgent instance
31
+ * @param options - Configuration options including Claude client config
32
+ */
33
+ constructor(options: PageAgentOptions);
34
+ /**
35
+ * Execute a task on the given page with retry logic
36
+ * @param task - The task to execute
37
+ * @param page - Playwright page instance
38
+ * @returns Promise<TaskResult> with execution results
39
+ */
40
+ execute(task: Task, page: Page): Promise<TaskResult>;
41
+ /**
42
+ * Send a connection request to a LinkedIn profile
43
+ * @param profileUrl - URL of the LinkedIn profile
44
+ * @param note - Optional personalized note for the connection request
45
+ * @param page - Playwright page instance
46
+ * @returns Promise<ConnectionResult> with connection status
47
+ */
48
+ connect(profileUrl: string, note: string | undefined, page: Page): Promise<ConnectionResult>;
49
+ /**
50
+ * Send a message to a LinkedIn connection
51
+ * @param profileUrl - URL of the LinkedIn profile
52
+ * @param message - Message text to send
53
+ * @param page - Playwright page instance
54
+ * @returns Promise<MessageResult> with message status
55
+ */
56
+ sendMessage(profileUrl: string, message: string, page: Page): Promise<MessageResult>;
57
+ /**
58
+ * Build a goal string from task properties
59
+ * @param task - Task with goal, note, or message
60
+ * @returns Goal string for the agent
61
+ */
62
+ private buildGoal;
63
+ /**
64
+ * Log debug message if debug mode is enabled
65
+ * @param message - Message to log
66
+ * @param data - Optional data to log
67
+ */
68
+ private logDebug;
69
+ }
70
+ /**
71
+ * Create a new PageAgent instance
72
+ * @param options - Configuration options
73
+ * @returns PageAgent instance
74
+ */
75
+ export declare function createPageAgent(options: PageAgentOptions): PageAgent;
76
+ //# sourceMappingURL=page-agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-agent.d.ts","sourceRoot":"","sources":["../../src/agent/page-agent.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAIvC,OAAO,KAAK,EACV,IAAI,EACJ,UAAU,EACV,gBAAgB,EAChB,aAAa,EAGb,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,0CAA0C;IAC1C,YAAY,EAAE,kBAAkB,CAAC;IACjC,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;IAEhC;;;OAGG;gBACS,OAAO,EAAE,gBAAgB;IAOrC;;;;;OAKG;IACG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC;IAqF1D;;;;;;OAMG;IACG,OAAO,CACX,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,IAAI,EAAE,IAAI,GACT,OAAO,CAAC,gBAAgB,CAAC;IAgD5B;;;;;;OAMG;IACG,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC;IAgC1F;;;;OAIG;IACH,OAAO,CAAC,SAAS;IAoBjB;;;;OAIG;IACH,OAAO,CAAC,QAAQ;CASjB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAEpE"}
@@ -0,0 +1,236 @@
1
+ "use strict";
2
+ /**
3
+ * Page Agent Orchestrator Module
4
+ *
5
+ * Combines DOM extractor, Claude client, and action executor into a cohesive workflow.
6
+ * Provides high-level methods for LinkedIn automation tasks with retry logic and error recovery.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.PageAgent = void 0;
10
+ exports.createPageAgent = createPageAgent;
11
+ const dom_extractor_1 = require("./dom-extractor");
12
+ const claude_client_1 = require("./claude-client");
13
+ const action_executor_1 = require("./action-executor");
14
+ /**
15
+ * High-level agent for executing tasks on LinkedIn pages
16
+ * Orchestrates DOM extraction, action planning, and execution
17
+ */
18
+ class PageAgent {
19
+ claudeClient;
20
+ domExtractor;
21
+ maxRetries;
22
+ debug;
23
+ /**
24
+ * Creates a new PageAgent instance
25
+ * @param options - Configuration options including Claude client config
26
+ */
27
+ constructor(options) {
28
+ this.claudeClient = new claude_client_1.ClaudeClient(options.claudeConfig);
29
+ this.domExtractor = new dom_extractor_1.DOMExtractor();
30
+ this.maxRetries = options.maxRetries ?? 3;
31
+ this.debug = options.debug ?? false;
32
+ }
33
+ /**
34
+ * Execute a task on the given page with retry logic
35
+ * @param task - The task to execute
36
+ * @param page - Playwright page instance
37
+ * @returns Promise<TaskResult> with execution results
38
+ */
39
+ async execute(task, page) {
40
+ const goal = this.buildGoal(task);
41
+ const previousActions = [];
42
+ let retryCount = 0;
43
+ this.logDebug(`Starting task execution: ${goal}`);
44
+ while (retryCount < this.maxRetries) {
45
+ // Step 1: Extract DOM
46
+ const dom = await this.domExtractor.extract(page);
47
+ this.logDebug(`Extracted DOM with ${dom.elements.length} elements`);
48
+ if (this.debug) {
49
+ this.logDebug('DOM:', JSON.stringify(dom, null, 2));
50
+ }
51
+ // Step 2: Build action context
52
+ const context = {
53
+ goal,
54
+ previousActions,
55
+ retryCount,
56
+ };
57
+ // Step 3: Get action plan from Claude
58
+ const plan = await this.claudeClient.generateActionPlan(dom, context);
59
+ this.logDebug(`Action plan status: ${plan.status}`);
60
+ // Step 4: Handle plan status
61
+ if (plan.status === 'completed') {
62
+ this.logDebug('Task completed successfully');
63
+ return {
64
+ success: true,
65
+ message: `Task completed successfully. ${plan.reasoning}`,
66
+ actionsTaken: previousActions.map((ea) => ea.action),
67
+ finalUrl: page.url(),
68
+ };
69
+ }
70
+ if (plan.status === 'failed') {
71
+ this.logDebug(`Task failed: ${plan.error}`);
72
+ return {
73
+ success: false,
74
+ message: `Task failed: ${plan.error || 'Unknown error'}`,
75
+ actionsTaken: previousActions.map((ea) => ea.action),
76
+ finalUrl: page.url(),
77
+ };
78
+ }
79
+ // Step 5: Execute actions
80
+ const executor = new action_executor_1.ActionExecutor(page, dom);
81
+ const executedActions = await executor.executeAll(plan.actions);
82
+ // Step 6: Add executed actions to history
83
+ previousActions.push(...executedActions);
84
+ // Step 7: Check for failures
85
+ const hasFailures = executedActions.some((ea) => !ea.success);
86
+ if (hasFailures) {
87
+ const failedActions = executedActions.filter((ea) => !ea.success);
88
+ this.logDebug(`Action execution failed: ${failedActions.map((ea) => ea.error).join(', ')}`);
89
+ retryCount++;
90
+ if (retryCount < this.maxRetries) {
91
+ this.logDebug(`Retrying (${retryCount}/${this.maxRetries})...`);
92
+ await page.waitForTimeout(2000);
93
+ }
94
+ }
95
+ else {
96
+ this.logDebug('Actions executed successfully');
97
+ }
98
+ // Step 8: Wait between iterations
99
+ await page.waitForTimeout(1000);
100
+ }
101
+ // Max retries exceeded
102
+ this.logDebug('Max retries exceeded');
103
+ return {
104
+ success: false,
105
+ message: `Task failed after ${this.maxRetries} retries`,
106
+ actionsTaken: previousActions.map((ea) => ea.action),
107
+ finalUrl: page.url(),
108
+ };
109
+ }
110
+ /**
111
+ * Send a connection request to a LinkedIn profile
112
+ * @param profileUrl - URL of the LinkedIn profile
113
+ * @param note - Optional personalized note for the connection request
114
+ * @param page - Playwright page instance
115
+ * @returns Promise<ConnectionResult> with connection status
116
+ */
117
+ async connect(profileUrl, note, page) {
118
+ this.logDebug(`Navigating to profile: ${profileUrl}`);
119
+ // Step 1: Navigate to profile
120
+ await page.goto(profileUrl, {
121
+ waitUntil: 'domcontentloaded',
122
+ timeout: 30000,
123
+ });
124
+ // Step 2: Wait for page to settle
125
+ await page.waitForTimeout(3000);
126
+ // Step 3: Create and execute task
127
+ const task = {
128
+ goal: 'Send connection request',
129
+ profileUrl,
130
+ note,
131
+ };
132
+ const result = await this.execute(task, page);
133
+ // Step 4: Extract final DOM to check connection state
134
+ const finalDom = await this.domExtractor.extract(page);
135
+ const connectionState = finalDom.metadata.connectionState;
136
+ // Determine the outcome
137
+ const sent = result.success && connectionState === 'pending';
138
+ const alreadyConnected = connectionState === 'connected';
139
+ const pending = connectionState === 'pending';
140
+ let message = result.message;
141
+ if (alreadyConnected) {
142
+ message = 'Already connected with this user';
143
+ }
144
+ else if (sent) {
145
+ message = 'Connection request sent successfully';
146
+ }
147
+ else if (pending) {
148
+ message = 'Connection request is pending';
149
+ }
150
+ return {
151
+ ...result,
152
+ sent,
153
+ pending,
154
+ alreadyConnected,
155
+ message,
156
+ };
157
+ }
158
+ /**
159
+ * Send a message to a LinkedIn connection
160
+ * @param profileUrl - URL of the LinkedIn profile
161
+ * @param message - Message text to send
162
+ * @param page - Playwright page instance
163
+ * @returns Promise<MessageResult> with message status
164
+ */
165
+ async sendMessage(profileUrl, message, page) {
166
+ this.logDebug(`Navigating to profile for messaging: ${profileUrl}`);
167
+ // Step 1: Navigate to profile
168
+ await page.goto(profileUrl, {
169
+ waitUntil: 'domcontentloaded',
170
+ timeout: 30000,
171
+ });
172
+ // Step 2: Wait for page to settle
173
+ await page.waitForTimeout(3000);
174
+ // Step 3: Create and execute task
175
+ const task = {
176
+ goal: 'Send message',
177
+ profileUrl,
178
+ message,
179
+ };
180
+ const result = await this.execute(task, page);
181
+ // Determine the outcome
182
+ const sent = result.success;
183
+ const finalMessage = sent ? 'Message sent successfully' : result.message;
184
+ return {
185
+ ...result,
186
+ sent,
187
+ message: finalMessage,
188
+ };
189
+ }
190
+ /**
191
+ * Build a goal string from task properties
192
+ * @param task - Task with goal, note, or message
193
+ * @returns Goal string for the agent
194
+ */
195
+ buildGoal(task) {
196
+ // Use explicit goal if provided
197
+ if (task.goal) {
198
+ return task.goal;
199
+ }
200
+ // Build goal from note (connection request)
201
+ if (task.note !== undefined) {
202
+ return `Send connection request to ${task.profileUrl || 'profile'} with note: ${task.note}`;
203
+ }
204
+ // Build goal from message
205
+ if (task.message !== undefined) {
206
+ return `Send message to ${task.profileUrl || 'profile'}: ${task.message}`;
207
+ }
208
+ // Default goal
209
+ return 'Complete task on LinkedIn';
210
+ }
211
+ /**
212
+ * Log debug message if debug mode is enabled
213
+ * @param message - Message to log
214
+ * @param data - Optional data to log
215
+ */
216
+ logDebug(message, data) {
217
+ if (this.debug) {
218
+ if (data !== undefined) {
219
+ console.log(`[PageAgent] ${message}`, data);
220
+ }
221
+ else {
222
+ console.log(`[PageAgent] ${message}`);
223
+ }
224
+ }
225
+ }
226
+ }
227
+ exports.PageAgent = PageAgent;
228
+ /**
229
+ * Create a new PageAgent instance
230
+ * @param options - Configuration options
231
+ * @returns PageAgent instance
232
+ */
233
+ function createPageAgent(options) {
234
+ return new PageAgent(options);
235
+ }
236
+ //# sourceMappingURL=page-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-agent.js","sourceRoot":"","sources":["../../src/agent/page-agent.ts"],"names":[],"mappings":"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"}