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,268 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.registerMessageCommands = registerMessageCommands;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const ora_1 = __importDefault(require("ora"));
9
+ const browser_1 = require("../core/browser");
10
+ const messages_1 = require("../linkedin/messages");
11
+ const message_sender_1 = require("../linkedin/message-sender");
12
+ const audit_1 = require("../core/audit");
13
+ const config_1 = require("../core/config");
14
+ function registerMessageCommands(program) {
15
+ const messages = program.command('messages').description('Message management commands');
16
+ // List conversations
17
+ messages
18
+ .command('list')
19
+ .description('List recent conversations')
20
+ .option('-l, --limit <number>', 'Number of conversations to show', '20')
21
+ .option('-u, --unread', 'Show only unread conversations', false)
22
+ .option('--headless', 'Run browser in headless mode', false)
23
+ .action(async (options) => {
24
+ const spinner = (0, ora_1.default)('Loading conversations...').start();
25
+ try {
26
+ // Launch browser - will connect to existing Edge/Chrome via CDP if available
27
+ const config = (0, config_1.getConfig)();
28
+ const browser = new browser_1.BrowserController({
29
+ headless: options.headless ?? config.getValue('headless'),
30
+ });
31
+ await browser.launch();
32
+ // Get the page (could be existing CDP tab or new page)
33
+ const page = browser.getPage();
34
+ if (!page)
35
+ throw new Error('Browser page not available');
36
+ // Check if user is on linkedin.cn (limited functionality)
37
+ if (browser.isOnLinkedInCN()) {
38
+ spinner.fail('Detected linkedin.cn - messaging requires linkedin.com');
39
+ console.error(chalk_1.default.red('\n⚠️ Network Issue Detected: linkedin.cn'));
40
+ console.error(chalk_1.default.yellow("\nlinkedin.cn (China's local LinkedIn) has limited functionality and does not support messaging."));
41
+ console.error(chalk_1.default.yellow('\nPlease enable your VPN or switch to a network that can access linkedin.com'));
42
+ console.error(chalk_1.default.gray('\nOnce your VPN is active, close this tab and run the command again.'));
43
+ await browser.close();
44
+ process.exit(1);
45
+ }
46
+ // If connected via CDP to existing browser, use the existing session
47
+ if (browser.isUsingCDP()) {
48
+ console.log('Using existing browser session...');
49
+ spinner.text = 'Navigating to LinkedIn messaging...';
50
+ // Check current URL
51
+ const currentUrl = page.url();
52
+ console.log('Current URL:', currentUrl);
53
+ // If already on messaging page, just refresh to get the list view
54
+ if (currentUrl.includes('/messaging/')) {
55
+ if (currentUrl.includes('/thread/')) {
56
+ // We're in a thread, navigate back to main messaging
57
+ console.log('In thread, navigating to messaging list...');
58
+ await page.goto('https://www.linkedin.com/messaging/', {
59
+ waitUntil: 'domcontentloaded',
60
+ timeout: 10000,
61
+ });
62
+ }
63
+ else {
64
+ // Already on messaging list, just reload
65
+ console.log('Already on messaging list, reloading...');
66
+ await page.reload({ waitUntil: 'domcontentloaded', timeout: 10000 });
67
+ }
68
+ }
69
+ else {
70
+ // Navigate from elsewhere to messaging
71
+ await page.goto('https://www.linkedin.com/messaging/', {
72
+ waitUntil: 'domcontentloaded',
73
+ timeout: 10000,
74
+ });
75
+ }
76
+ }
77
+ else {
78
+ // Fresh browser, navigate to messaging
79
+ await page.goto('https://www.linkedin.com/messaging/', {
80
+ waitUntil: 'domcontentloaded',
81
+ timeout: 30000,
82
+ });
83
+ }
84
+ // Wait a bit for the page to stabilize
85
+ await page.waitForTimeout(2000);
86
+ const linkedInMessages = new messages_1.LinkedInMessages(page, browser);
87
+ spinner.text = 'Fetching conversations from LinkedIn...';
88
+ const threads = await linkedInMessages.getThreads({
89
+ limit: parseInt(options.limit),
90
+ unreadOnly: options.unread,
91
+ });
92
+ spinner.succeed(`Found ${threads.length} conversations`);
93
+ // Display results
94
+ console.log('\n' + chalk_1.default.bold('Conversations:'));
95
+ console.log(chalk_1.default.gray('─'.repeat(80)));
96
+ threads.forEach((thread) => {
97
+ const participantNames = thread.participants.map((p) => p.name).join(', ');
98
+ const unreadIndicator = thread.unreadCount > 0 ? chalk_1.default.red('● ') : ' ';
99
+ const preview = thread.messages[0]?.content?.slice(0, 60) || 'No preview';
100
+ console.log(`${unreadIndicator}${chalk_1.default.bold(participantNames)}`);
101
+ console.log(` ${chalk_1.default.gray(preview)}${preview.length >= 60 ? '...' : ''}`);
102
+ console.log(` ${chalk_1.default.cyan(`ID: ${thread.id}`)}`);
103
+ console.log();
104
+ });
105
+ // Log action
106
+ const logger = (0, audit_1.getAuditLogger)();
107
+ logger.log('messages.list', { count: threads.length, unreadOnly: options.unread }, true);
108
+ await browser.close();
109
+ }
110
+ catch (error) {
111
+ spinner.fail('Failed to load conversations');
112
+ console.error(chalk_1.default.red('Error:'), error instanceof Error ? error.message : error);
113
+ process.exit(1);
114
+ }
115
+ });
116
+ // Show thread details
117
+ messages
118
+ .command('show')
119
+ .description('Show conversation thread details')
120
+ .requiredOption('-t, --thread <id>', 'Thread ID to show')
121
+ .option('-l, --limit <number>', 'Number of messages to show', '50')
122
+ .option('--json', 'Output as JSON for LLM processing', false)
123
+ .option('--headless', 'Run browser in headless mode', false)
124
+ .action(async (options) => {
125
+ const spinner = (0, ora_1.default)('Loading conversation...').start();
126
+ try {
127
+ // Launch browser - will connect to existing Edge/Chrome via CDP if available
128
+ const config = (0, config_1.getConfig)();
129
+ const browser = new browser_1.BrowserController({
130
+ headless: options.headless ?? config.getValue('headless'),
131
+ });
132
+ await browser.launch();
133
+ // Get the page (could be existing CDP tab or new page)
134
+ const page = browser.getPage();
135
+ if (!page)
136
+ throw new Error('Browser page not available');
137
+ // Check if user is on linkedin.cn (limited functionality)
138
+ if (browser.isOnLinkedInCN()) {
139
+ spinner.fail('Detected linkedin.cn - messaging requires linkedin.com');
140
+ console.error(chalk_1.default.red('\n⚠️ Network Issue Detected: linkedin.cn'));
141
+ console.error(chalk_1.default.yellow("\nlinkedin.cn (China's local LinkedIn) has limited functionality and does not support messaging."));
142
+ console.error(chalk_1.default.yellow('\nPlease enable your VPN or switch to a network that can access linkedin.com'));
143
+ console.error(chalk_1.default.gray('\nOnce your VPN is active, close this tab and run the command again.'));
144
+ await browser.close();
145
+ process.exit(1);
146
+ }
147
+ // If connected via CDP to existing browser, use the existing session
148
+ if (browser.isUsingCDP()) {
149
+ console.log('Using existing browser session...');
150
+ spinner.text = 'Navigating to conversation...';
151
+ // Only navigate to messaging list for ember ID lookup
152
+ // Real thread IDs can be accessed directly
153
+ const isEmberId = options.thread.startsWith('ember');
154
+ if (isEmberId) {
155
+ console.log('Navigating to messaging list for ember ID lookup...');
156
+ await page.goto('https://www.linkedin.com/messaging/', {
157
+ waitUntil: 'domcontentloaded',
158
+ timeout: 15000,
159
+ });
160
+ await page.waitForTimeout(2000);
161
+ }
162
+ }
163
+ const linkedInMessages = new messages_1.LinkedInMessages(page, browser);
164
+ spinner.text = 'Fetching messages from LinkedIn...';
165
+ const thread = await linkedInMessages.showThread(options.thread, parseInt(options.limit));
166
+ if (!thread) {
167
+ spinner.fail(`Thread ${options.thread} not found`);
168
+ process.exit(1);
169
+ }
170
+ spinner.succeed(`Loaded ${thread.messages.length} messages`);
171
+ // Display thread based on output format
172
+ if (options.json) {
173
+ // JSON output for LLM processing
174
+ console.log(linkedInMessages.formatThreadJson(thread));
175
+ }
176
+ else {
177
+ // Human-readable text output (Style A)
178
+ console.log('\n' + chalk_1.default.bold('='.repeat(60)));
179
+ console.log(chalk_1.default.bold(`Conversations with ${thread.participants.map((p) => p.name).join(', ')}`));
180
+ console.log(chalk_1.default.gray(`Thread ID: ${thread.id}`));
181
+ console.log(chalk_1.default.bold('='.repeat(60)));
182
+ console.log(linkedInMessages.formatThreadText(thread));
183
+ console.log('\n' + chalk_1.default.bold('='.repeat(60)));
184
+ }
185
+ // Log action
186
+ const logger = (0, audit_1.getAuditLogger)();
187
+ logger.log('messages.show', { threadId: options.thread, messageCount: thread.messages.length, json: options.json }, true);
188
+ await browser.close();
189
+ }
190
+ catch (error) {
191
+ spinner.fail('Failed to load conversation');
192
+ console.error(chalk_1.default.red('Error:'), error instanceof Error ? error.message : error);
193
+ process.exit(1);
194
+ }
195
+ });
196
+ // Send new message to a profile
197
+ messages
198
+ .command('send')
199
+ .description('Send a new message to a LinkedIn profile')
200
+ .requiredOption('-u, --url <profile>', 'LinkedIn profile URL')
201
+ .requiredOption('-m, --message <text>', 'Message text to send')
202
+ .option('--dry-run', 'Simulate sending without actually sending', false)
203
+ .option('--headless', 'Run browser in headless mode', false)
204
+ .action(async (options) => {
205
+ const spinner = (0, ora_1.default)('Preparing to send message...').start();
206
+ try {
207
+ spinner.text = 'Launching browser...';
208
+ // Launch browser - will connect to existing Edge/Chrome via CDP if available
209
+ const config = (0, config_1.getConfig)();
210
+ const browser = new browser_1.BrowserController({
211
+ headless: options.headless ?? config.getValue('headless'),
212
+ });
213
+ await browser.launch();
214
+ // Get the page
215
+ const page = browser.getPage();
216
+ if (!page)
217
+ throw new Error('Browser page not available');
218
+ // Check if user is on linkedin.cn (limited functionality, messaging won't work)
219
+ if (browser.isOnLinkedInCN()) {
220
+ spinner.fail('Detected linkedin.cn - messaging requires linkedin.com');
221
+ console.error(chalk_1.default.red('\n⚠️ Network Issue Detected: linkedin.cn'));
222
+ console.error(chalk_1.default.yellow("\nlinkedin.cn (China's local LinkedIn) has limited functionality and does not support messaging via API."));
223
+ console.error(chalk_1.default.yellow('\nPlease enable your VPN or switch to a network that can access linkedin.com'));
224
+ console.error(chalk_1.default.gray('\nOnce your VPN is active, close this tab and run the command again.'));
225
+ await browser.close();
226
+ process.exit(1);
227
+ }
228
+ spinner.text = options.dryRun ? 'Simulating message send...' : 'Sending message...';
229
+ const sender = new message_sender_1.LinkedInMessageSender(page);
230
+ const result = await sender.sendMessage({
231
+ profileUrl: options.url,
232
+ text: options.message,
233
+ dryRun: options.dryRun,
234
+ });
235
+ if (!result.success) {
236
+ spinner.fail(`Failed to send message: ${result.error}`);
237
+ await browser.close();
238
+ process.exit(1);
239
+ }
240
+ if (options.dryRun) {
241
+ spinner.succeed('Dry run completed - message would have been sent');
242
+ console.log(chalk_1.default.gray('Profile URL: ' + options.url));
243
+ console.log(chalk_1.default.gray('Message content:'));
244
+ console.log(chalk_1.default.cyan(options.message));
245
+ if (result.threadId) {
246
+ console.log(chalk_1.default.gray(`Thread ID: ${result.threadId}`));
247
+ }
248
+ }
249
+ else {
250
+ spinner.succeed('Message sent successfully!');
251
+ console.log(chalk_1.default.gray(`Thread ID: ${result.threadId}`));
252
+ if (result.messageId) {
253
+ console.log(chalk_1.default.gray(`Message ID: ${result.messageId}`));
254
+ }
255
+ }
256
+ // Log action
257
+ const logger = (0, audit_1.getAuditLogger)();
258
+ logger.log(options.dryRun ? 'messages.send.dry-run' : 'messages.send', { profileUrl: options.url, messageLength: options.message.length }, true);
259
+ await browser.close();
260
+ }
261
+ catch (error) {
262
+ spinner.fail('Failed to send message');
263
+ console.error(chalk_1.default.red('Error:'), error instanceof Error ? error.message : error);
264
+ process.exit(1);
265
+ }
266
+ });
267
+ }
268
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/cli/messages.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerProfileCommands(program: Command): void;
3
+ //# sourceMappingURL=profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../../src/cli/profile.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6D9D"}
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerProfileCommands = registerProfileCommands;
4
+ const browser_1 = require("../core/browser");
5
+ const profile_1 = require("../linkedin/profile");
6
+ const audit_1 = require("../core/audit");
7
+ const CDP_PORT = parseInt(process.env.PAGE_AGENT_CDP_PORT || '9222', 10);
8
+ function registerProfileCommands(program) {
9
+ const profile = program.command('profile').description('LinkedIn profile commands');
10
+ profile
11
+ .command('get <url>')
12
+ .description('Extract profile data from a LinkedIn URL')
13
+ .option('--include-contact', 'Extract contact info (email, phone)')
14
+ .option('--json', 'Output as JSON')
15
+ .option('--no-cdp', 'Do not connect to existing browser via CDP')
16
+ .option('--cdp-port <port>', 'CDP port number', String(CDP_PORT))
17
+ .action(async (url, options) => {
18
+ const browser = new browser_1.BrowserController();
19
+ try {
20
+ // Initialize browser
21
+ await browser.launch();
22
+ const page = browser.getPage();
23
+ if (!page) {
24
+ console.error('Failed to get page from browser');
25
+ process.exit(1);
26
+ }
27
+ const extractor = new profile_1.LinkedInProfile(page);
28
+ // Extract profile
29
+ const result = await extractor.extract({
30
+ profileUrl: url,
31
+ includeContact: options.includeContact,
32
+ });
33
+ // Log audit
34
+ (0, audit_1.getAuditLogger)().log('profile_extract', {
35
+ profileUrl: url,
36
+ includeContact: options.includeContact ?? false,
37
+ success: result.success,
38
+ extractedFields: result.data
39
+ ? Object.keys(result.data).filter((k) => result.data[k] !== null)
40
+ : [],
41
+ }, result.success);
42
+ if (result.success && result.data) {
43
+ if (options.json) {
44
+ console.log(JSON.stringify(result.data, null, 2));
45
+ }
46
+ else {
47
+ printProfileOutput(result.data, options.includeContact);
48
+ }
49
+ }
50
+ else {
51
+ console.error(`Error: ${result.error}`);
52
+ process.exit(1);
53
+ }
54
+ }
55
+ finally {
56
+ await browser.close();
57
+ }
58
+ });
59
+ }
60
+ /**
61
+ * Print profile data in human-readable format
62
+ */
63
+ function printProfileOutput(data, includeContact) {
64
+ console.log(`\nProfile: ${data.full_name}`);
65
+ console.log('━'.repeat(50));
66
+ console.log(`Headline: ${data.headline || 'N/A'}`);
67
+ console.log(`Location: ${data.location || 'N/A'}`);
68
+ console.log(`Company: ${data.current_company ?? 'N/A'}`);
69
+ console.log(`Title: ${data.current_title ?? 'N/A'}`);
70
+ console.log(`Company URL: ${data.company_linkedin_url ?? 'N/A'}`);
71
+ console.log(`Experience: ${data.years_experience !== null ? `${data.years_experience} years` : 'N/A'}`);
72
+ if (includeContact) {
73
+ console.log(`Email: ${data.email ?? 'Not available'}`);
74
+ console.log(`Phone: ${data.phone ?? 'Not available'}`);
75
+ }
76
+ else {
77
+ console.log(`Email: (use --include-contact to reveal)`);
78
+ console.log(`Phone: (use --include-contact to reveal)`);
79
+ }
80
+ }
81
+ //# sourceMappingURL=profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.js","sourceRoot":"","sources":["../../src/cli/profile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=profile.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.test.d.ts","sourceRoot":"","sources":["../../src/cli/profile.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // src/cli/profile.test.ts
4
+ const vitest_1 = require("vitest");
5
+ const commander_1 = require("commander");
6
+ const profile_1 = require("./profile");
7
+ (0, vitest_1.describe)('registerProfileCommands', () => {
8
+ (0, vitest_1.it)('should register profile command', () => {
9
+ const program = new commander_1.Command();
10
+ (0, profile_1.registerProfileCommands)(program);
11
+ const commands = program.commands;
12
+ (0, vitest_1.expect)(commands.some((c) => c.name() === 'profile')).toBe(true);
13
+ });
14
+ });
15
+ //# sourceMappingURL=profile.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.test.js","sourceRoot":"","sources":["../../src/cli/profile.test.ts"],"names":[],"mappings":";;AAAA,0BAA0B;AAC1B,mCAA8C;AAC9C,yCAAoC;AACpC,uCAAoD;AAEpD,IAAA,iBAAQ,EAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,IAAA,WAAE,EAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;QAC9B,IAAA,iCAAuB,EAAC,OAAO,CAAC,CAAC;QAEjC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QAClC,IAAA,eAAM,EAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerReplyCommands(program: Command): void;
3
+ //# sourceMappingURL=reply.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reply.d.ts","sourceRoot":"","sources":["../../src/cli/reply.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmG5D"}
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.registerReplyCommands = registerReplyCommands;
40
+ const chalk_1 = __importDefault(require("chalk"));
41
+ const ora_1 = __importDefault(require("ora"));
42
+ const fs = __importStar(require("fs"));
43
+ const browser_1 = require("../core/browser");
44
+ const reply_1 = require("../linkedin/reply");
45
+ const storage_1 = require("../core/storage");
46
+ const audit_1 = require("../core/audit");
47
+ const config_1 = require("../core/config");
48
+ function registerReplyCommands(program) {
49
+ const reply = program.command('reply').description('Reply to a conversation thread');
50
+ reply
51
+ .command('send')
52
+ .description('Send a reply to a thread')
53
+ .requiredOption('-t, --thread <id>', 'Thread ID to reply to')
54
+ .option('-m, --message <text>', 'Message text to send')
55
+ .option('-f, --file <path>', 'Read message from file')
56
+ .option('--dry-run', 'Simulate sending without actually sending', false)
57
+ .option('--headless', 'Run browser in headless mode', true)
58
+ .action(async (options) => {
59
+ const spinner = (0, ora_1.default)('Preparing to send message...').start();
60
+ try {
61
+ // Get message text
62
+ let messageText = options.message;
63
+ if (options.file) {
64
+ if (!fs.existsSync(options.file)) {
65
+ spinner.fail(`File not found: ${options.file}`);
66
+ process.exit(1);
67
+ }
68
+ messageText = fs.readFileSync(options.file, 'utf8');
69
+ }
70
+ if (!messageText || messageText.trim().length === 0) {
71
+ spinner.fail('Message text is required (use --message or --file)');
72
+ process.exit(1);
73
+ }
74
+ spinner.text = 'Checking authentication...';
75
+ // Check for existing session
76
+ const storage = (0, storage_1.getSecureStorage)();
77
+ const sessionData = storage.load('linkedin-session');
78
+ if (!sessionData) {
79
+ spinner.fail('Not logged in. Run: linkedin-cli auth login');
80
+ process.exit(1);
81
+ }
82
+ spinner.text = 'Launching browser...';
83
+ // Launch browser and restore session
84
+ const config = (0, config_1.getConfig)();
85
+ const browser = new browser_1.BrowserController({
86
+ headless: options.headless ?? config.getValue('headless'),
87
+ });
88
+ await browser.launch();
89
+ const session = JSON.parse(sessionData);
90
+ await browser.restoreSession(session);
91
+ const page = browser.getPage();
92
+ if (!page)
93
+ throw new Error('Browser page not available');
94
+ spinner.text = options.dryRun ? 'Simulating message send...' : 'Sending message...';
95
+ const linkedInReply = new reply_1.LinkedInReply(page);
96
+ const result = await linkedInReply.sendMessage({
97
+ threadId: options.thread,
98
+ text: messageText,
99
+ dryRun: options.dryRun,
100
+ });
101
+ if (!result.success) {
102
+ spinner.fail(`Failed to send message: ${result.error}`);
103
+ await browser.close();
104
+ process.exit(1);
105
+ }
106
+ if (options.dryRun) {
107
+ spinner.succeed('Dry run completed - message would have been sent');
108
+ console.log(chalk_1.default.gray('Message content:'));
109
+ console.log(chalk_1.default.cyan(messageText));
110
+ }
111
+ else {
112
+ spinner.succeed('Message sent successfully!');
113
+ if (result.messageId) {
114
+ console.log(chalk_1.default.gray(`Message ID: ${result.messageId}`));
115
+ }
116
+ }
117
+ // Log action
118
+ const logger = (0, audit_1.getAuditLogger)();
119
+ logger.log(options.dryRun ? 'reply.send.dry-run' : 'reply.send', { threadId: options.thread, messageLength: messageText.length }, true);
120
+ await browser.close();
121
+ }
122
+ catch (error) {
123
+ spinner.fail('Failed to send message');
124
+ console.error(chalk_1.default.red('Error:'), error instanceof Error ? error.message : error);
125
+ process.exit(1);
126
+ }
127
+ });
128
+ }
129
+ //# sourceMappingURL=reply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reply.js","sourceRoot":"","sources":["../../src/cli/reply.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export interface AuditEntry {
2
+ timestamp: string;
3
+ action: string;
4
+ details: Record<string, unknown>;
5
+ success: boolean;
6
+ }
7
+ export declare class AuditLogger {
8
+ private logPath;
9
+ private consoleEnabled;
10
+ constructor();
11
+ private ensureLogDirectory;
12
+ log(action: string, details?: Record<string, unknown>, success?: boolean): void;
13
+ readRecent(count?: number): AuditEntry[];
14
+ clear(): void;
15
+ }
16
+ export declare function getAuditLogger(): AuditLogger;
17
+ //# sourceMappingURL=audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/core/audit.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAAU;;IAShC,OAAO,CAAC,kBAAkB;IAO1B,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAAE,OAAO,GAAE,OAAc,GAAG,IAAI;IAqBzF,UAAU,CAAC,KAAK,GAAE,MAAY,GAAG,UAAU,EAAE;IA6B7C,KAAK,IAAI,IAAI;CASd;AAID,wBAAgB,cAAc,IAAI,WAAW,CAK5C"}