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,124 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.SecureStorage = void 0;
37
+ exports.encrypt = encrypt;
38
+ exports.decrypt = decrypt;
39
+ exports.getSecureStorage = getSecureStorage;
40
+ const fs = __importStar(require("fs"));
41
+ const crypto = __importStar(require("crypto"));
42
+ const path = __importStar(require("path"));
43
+ const paths_1 = require("../utils/paths");
44
+ const ALGORITHM = 'aes-256-gcm';
45
+ const KEY_LENGTH = 32;
46
+ const IV_LENGTH = 16;
47
+ const SALT_LENGTH = 32;
48
+ function deriveKey(salt) {
49
+ const machineData = [
50
+ process.env.USER || process.env.USERNAME || 'unknown',
51
+ process.env.HOME || process.env.USERPROFILE || 'unknown',
52
+ process.platform,
53
+ ].join('|');
54
+ return crypto.pbkdf2Sync(machineData, salt, 100000, KEY_LENGTH, 'sha256');
55
+ }
56
+ function encrypt(data) {
57
+ const salt = crypto.randomBytes(SALT_LENGTH);
58
+ const iv = crypto.randomBytes(IV_LENGTH);
59
+ const key = deriveKey(salt);
60
+ const cipher = crypto.createCipheriv(ALGORITHM, key, iv);
61
+ const encrypted = Buffer.concat([cipher.update(data, 'utf8'), cipher.final()]);
62
+ const tag = cipher.getAuthTag();
63
+ return {
64
+ encrypted: encrypted.toString('base64'),
65
+ iv: iv.toString('base64'),
66
+ salt: salt.toString('base64'),
67
+ tag: tag.toString('base64'),
68
+ };
69
+ }
70
+ function decrypt(data) {
71
+ const salt = Buffer.from(data.salt, 'base64');
72
+ const iv = Buffer.from(data.iv, 'base64');
73
+ const key = deriveKey(salt);
74
+ const encrypted = Buffer.from(data.encrypted, 'base64');
75
+ const tag = Buffer.from(data.tag, 'base64');
76
+ const decipher = crypto.createDecipheriv(ALGORITHM, key, iv);
77
+ decipher.setAuthTag(tag);
78
+ const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
79
+ return decrypted.toString('utf8');
80
+ }
81
+ class SecureStorage {
82
+ baseDir;
83
+ constructor() {
84
+ this.baseDir = (0, paths_1.getSessionsDir)();
85
+ this.ensureDir();
86
+ }
87
+ ensureDir() {
88
+ if (!fs.existsSync(this.baseDir)) {
89
+ fs.mkdirSync(this.baseDir, { recursive: true, mode: 0o700 });
90
+ }
91
+ }
92
+ save(key, data) {
93
+ const encrypted = encrypt(data);
94
+ const filePath = path.join(this.baseDir, `${key}.json`);
95
+ fs.writeFileSync(filePath, JSON.stringify(encrypted, null, 2), { mode: 0o600 });
96
+ }
97
+ load(key) {
98
+ const filePath = path.join(this.baseDir, `${key}.json`);
99
+ if (!fs.existsSync(filePath))
100
+ return null;
101
+ const encrypted = JSON.parse(fs.readFileSync(filePath, 'utf8'));
102
+ return decrypt(encrypted);
103
+ }
104
+ delete(key) {
105
+ const filePath = path.join(this.baseDir, `${key}.json`);
106
+ if (fs.existsSync(filePath)) {
107
+ fs.unlinkSync(filePath);
108
+ return true;
109
+ }
110
+ return false;
111
+ }
112
+ exists(key) {
113
+ const filePath = path.join(this.baseDir, `${key}.json`);
114
+ return fs.existsSync(filePath);
115
+ }
116
+ }
117
+ exports.SecureStorage = SecureStorage;
118
+ let secureStorage = null;
119
+ function getSecureStorage() {
120
+ if (!secureStorage)
121
+ secureStorage = new SecureStorage();
122
+ return secureStorage;
123
+ }
124
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/core/storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=storage.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.test.d.ts","sourceRoot":"","sources":["../../src/core/storage.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,142 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const vitest_1 = require("vitest");
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const os = __importStar(require("os"));
40
+ // Mock the paths module
41
+ vitest_1.vi.mock('../utils/paths', () => {
42
+ const testDir = path.join(os.tmpdir(), 'linkedin-cli-test');
43
+ return {
44
+ getConfigDir: () => testDir,
45
+ getSessionsDir: () => path.join(testDir, 'sessions'),
46
+ getTemplatesDir: () => path.join(testDir, 'templates'),
47
+ getDefaultsDir: () => path.join(testDir, 'templates', 'defaults'),
48
+ getCustomDir: () => path.join(testDir, 'templates', 'custom'),
49
+ getConfigFile: () => path.join(testDir, 'config.json'),
50
+ getLogFile: () => path.join(testDir, 'audit.log'),
51
+ };
52
+ });
53
+ const storage_1 = require("./storage");
54
+ (0, vitest_1.describe)('SecureStorage', () => {
55
+ let storage;
56
+ const testDir = path.join(os.tmpdir(), 'linkedin-cli-test');
57
+ (0, vitest_1.beforeEach)(() => {
58
+ // Clean up test directory
59
+ if (fs.existsSync(testDir)) {
60
+ fs.rmSync(testDir, { recursive: true, force: true });
61
+ }
62
+ storage = new storage_1.SecureStorage();
63
+ });
64
+ (0, vitest_1.afterEach)(() => {
65
+ // Clean up after tests
66
+ if (fs.existsSync(testDir)) {
67
+ fs.rmSync(testDir, { recursive: true, force: true });
68
+ }
69
+ });
70
+ (0, vitest_1.describe)('save and load', () => {
71
+ (0, vitest_1.it)('should save and retrieve data', () => {
72
+ const testData = 'test-secret-data';
73
+ storage.save('test-key', testData);
74
+ const loaded = storage.load('test-key');
75
+ (0, vitest_1.expect)(loaded).toBe(testData);
76
+ });
77
+ (0, vitest_1.it)('should return null for non-existent key', () => {
78
+ const loaded = storage.load('non-existent-key');
79
+ (0, vitest_1.expect)(loaded).toBeNull();
80
+ });
81
+ (0, vitest_1.it)('should overwrite existing key', () => {
82
+ storage.save('test-key', 'first-value');
83
+ storage.save('test-key', 'second-value');
84
+ const loaded = storage.load('test-key');
85
+ (0, vitest_1.expect)(loaded).toBe('second-value');
86
+ });
87
+ });
88
+ (0, vitest_1.describe)('delete', () => {
89
+ (0, vitest_1.it)('should delete existing key and return true', () => {
90
+ storage.save('test-key', 'test-data');
91
+ const deleted = storage.delete('test-key');
92
+ (0, vitest_1.expect)(deleted).toBe(true);
93
+ (0, vitest_1.expect)(storage.load('test-key')).toBeNull();
94
+ });
95
+ (0, vitest_1.it)('should return false for non-existent key', () => {
96
+ const deleted = storage.delete('non-existent-key');
97
+ (0, vitest_1.expect)(deleted).toBe(false);
98
+ });
99
+ });
100
+ (0, vitest_1.describe)('exists', () => {
101
+ (0, vitest_1.it)('should return true for existing key', () => {
102
+ storage.save('test-key', 'test-data');
103
+ (0, vitest_1.expect)(storage.exists('test-key')).toBe(true);
104
+ });
105
+ (0, vitest_1.it)('should return false for non-existent key', () => {
106
+ (0, vitest_1.expect)(storage.exists('non-existent-key')).toBe(false);
107
+ });
108
+ });
109
+ });
110
+ (0, vitest_1.describe)('encryption', () => {
111
+ (0, vitest_1.it)('should encrypt and decrypt data correctly', () => {
112
+ const originalData = 'sensitive-information';
113
+ const encrypted = (0, storage_1.encrypt)(originalData);
114
+ (0, vitest_1.expect)(encrypted).toHaveProperty('encrypted');
115
+ (0, vitest_1.expect)(encrypted).toHaveProperty('iv');
116
+ (0, vitest_1.expect)(encrypted).toHaveProperty('salt');
117
+ (0, vitest_1.expect)(encrypted).toHaveProperty('tag');
118
+ const decrypted = (0, storage_1.decrypt)(encrypted);
119
+ (0, vitest_1.expect)(decrypted).toBe(originalData);
120
+ });
121
+ (0, vitest_1.it)('should produce different encrypted output each time', () => {
122
+ const data = 'test-data';
123
+ const encrypted1 = (0, storage_1.encrypt)(data);
124
+ const encrypted2 = (0, storage_1.encrypt)(data);
125
+ // Salt should be different (random)
126
+ (0, vitest_1.expect)(encrypted1.salt).not.toBe(encrypted2.salt);
127
+ // But both should decrypt to the same value
128
+ (0, vitest_1.expect)((0, storage_1.decrypt)(encrypted1)).toBe(data);
129
+ (0, vitest_1.expect)((0, storage_1.decrypt)(encrypted2)).toBe(data);
130
+ });
131
+ (0, vitest_1.it)('should throw on tampered data', () => {
132
+ const originalData = 'important-data';
133
+ const encrypted = (0, storage_1.encrypt)(originalData);
134
+ // Tamper with the encrypted data
135
+ const tampered = {
136
+ ...encrypted,
137
+ encrypted: encrypted.encrypted.split('').reverse().join(''),
138
+ };
139
+ (0, vitest_1.expect)(() => (0, storage_1.decrypt)(tampered)).toThrow();
140
+ });
141
+ });
142
+ //# sourceMappingURL=storage.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.test.js","sourceRoot":"","sources":["../../src/core/storage.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const commander_1 = require("commander");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const cli_1 = require("./cli");
10
+ const config_1 = require("./core/config");
11
+ const packageJson = require('../package.json');
12
+ commander_1.program
13
+ .name('linkedin-cli')
14
+ .description('LinkedIn automation CLI for sales representatives')
15
+ .version(packageJson.version);
16
+ // Register command groups
17
+ (0, cli_1.registerAuthCommands)(commander_1.program);
18
+ (0, cli_1.registerMessageCommands)(commander_1.program);
19
+ (0, cli_1.registerReplyCommands)(commander_1.program);
20
+ (0, cli_1.registerConnectionCommands)(commander_1.program);
21
+ (0, cli_1.registerCompanyCommands)(commander_1.program);
22
+ (0, cli_1.registerProfileCommands)(commander_1.program);
23
+ // Config command
24
+ commander_1.program
25
+ .command('config')
26
+ .description('Manage configuration')
27
+ .option('--get', 'Show current configuration')
28
+ .option('--set <key=value>', 'Set a configuration value')
29
+ .action((options) => {
30
+ const config = (0, config_1.getConfig)();
31
+ if (options.get || !options.set) {
32
+ console.log(chalk_1.default.bold('Current Configuration:'));
33
+ console.log(JSON.stringify(config.get(), null, 2));
34
+ return;
35
+ }
36
+ if (options.set) {
37
+ const [key, value] = options.set.split('=');
38
+ if (!key || value === undefined) {
39
+ console.error(chalk_1.default.red('Invalid format. Use: --set key=value'));
40
+ process.exit(1);
41
+ }
42
+ // Try to parse as boolean or number
43
+ let parsedValue = value;
44
+ if (value === 'true')
45
+ parsedValue = true;
46
+ else if (value === 'false')
47
+ parsedValue = false;
48
+ else if (!isNaN(Number(value)))
49
+ parsedValue = Number(value);
50
+ config.set(key, parsedValue);
51
+ console.log(chalk_1.default.green(`✓ Set ${key} = ${parsedValue}`));
52
+ }
53
+ });
54
+ // Global error handler
55
+ commander_1.program.exitOverride();
56
+ try {
57
+ commander_1.program.parse();
58
+ }
59
+ catch (error) {
60
+ console.error(chalk_1.default.red('Error:'), error instanceof Error ? error.message : error);
61
+ process.exit(1);
62
+ }
63
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AACA,yCAAoC;AACpC,kDAA0B;AAC1B,+BAOe;AACf,0CAA0C;AAE1C,MAAM,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAE/C,mBAAO;KACJ,IAAI,CAAC,cAAc,CAAC;KACpB,WAAW,CAAC,mDAAmD,CAAC;KAChE,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;AAEhC,0BAA0B;AAC1B,IAAA,0BAAoB,EAAC,mBAAO,CAAC,CAAC;AAC9B,IAAA,6BAAuB,EAAC,mBAAO,CAAC,CAAC;AACjC,IAAA,2BAAqB,EAAC,mBAAO,CAAC,CAAC;AAC/B,IAAA,gCAA0B,EAAC,mBAAO,CAAC,CAAC;AACpC,IAAA,6BAAuB,EAAC,mBAAO,CAAC,CAAC;AACjC,IAAA,6BAAuB,EAAC,mBAAO,CAAC,CAAC;AAEjC,iBAAiB;AACjB,mBAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,sBAAsB,CAAC;KACnC,MAAM,CAAC,OAAO,EAAE,4BAA4B,CAAC;KAC7C,MAAM,CAAC,mBAAmB,EAAE,2BAA2B,CAAC;KACxD,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;IAClB,MAAM,MAAM,GAAG,IAAA,kBAAS,GAAE,CAAC;IAE3B,IAAI,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACnD,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC5C,IAAI,CAAC,GAAG,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC,CAAC;YACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,oCAAoC;QACpC,IAAI,WAAW,GAA8B,KAAK,CAAC;QACnD,IAAI,KAAK,KAAK,MAAM;YAAE,WAAW,GAAG,IAAI,CAAC;aACpC,IAAI,KAAK,KAAK,OAAO;YAAE,WAAW,GAAG,KAAK,CAAC;aAC3C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAAE,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAE5D,MAAM,CAAC,GAAG,CAAC,GAAU,EAAE,WAAkB,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,SAAS,GAAG,MAAM,WAAW,EAAE,CAAC,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,uBAAuB;AACvB,mBAAO,CAAC,YAAY,EAAE,CAAC;AAEvB,IAAI,CAAC;IACH,mBAAO,CAAC,KAAK,EAAE,CAAC;AAClB,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACnF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { BrowserController } from '../core/browser';
2
+ import type { Session } from '../types';
3
+ export interface LoginCredentials {
4
+ email: string;
5
+ password: string;
6
+ totpCode?: string;
7
+ }
8
+ export interface LoginResult {
9
+ success: boolean;
10
+ session?: Session;
11
+ error?: string;
12
+ requires2FA?: boolean;
13
+ }
14
+ export declare class LinkedInAuth {
15
+ private browser;
16
+ private debug;
17
+ constructor(browser: BrowserController, debug?: boolean);
18
+ private findElementWithFallbacks;
19
+ login(credentials: LoginCredentials): Promise<LoginResult>;
20
+ isSessionValid(): Promise<boolean>;
21
+ }
22
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/linkedin/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAGxC,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,KAAK,CAAU;gBAEX,OAAO,EAAE,iBAAiB,EAAE,KAAK,GAAE,OAAe;YAIhD,wBAAwB;IA0BhC,KAAK,CAAC,WAAW,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC;IAkJ1D,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;CAoBzC"}
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LinkedInAuth = void 0;
4
+ const selectors_1 = require("./selectors");
5
+ class LinkedInAuth {
6
+ browser;
7
+ debug;
8
+ constructor(browser, debug = false) {
9
+ this.browser = browser;
10
+ this.debug = debug;
11
+ }
12
+ async findElementWithFallbacks(selectors, elementName) {
13
+ const page = this.browser.getPage();
14
+ if (!page)
15
+ return null;
16
+ for (const selector of selectors) {
17
+ try {
18
+ const element = await page.$(selector);
19
+ if (element) {
20
+ console.log(`Found ${elementName} using selector: ${selector}`);
21
+ if (this.debug)
22
+ this.browser.debugLog(`Found ${elementName} using selector: ${selector}`);
23
+ return { element, selectorUsed: selector };
24
+ }
25
+ }
26
+ catch {
27
+ // Continue to next selector
28
+ }
29
+ }
30
+ return null;
31
+ }
32
+ async login(credentials) {
33
+ const page = this.browser.getPage();
34
+ if (!page) {
35
+ return { success: false, error: 'Browser not initialized' };
36
+ }
37
+ try {
38
+ // Navigate to LinkedIn login
39
+ console.log('Navigating to LinkedIn login page...');
40
+ await page.goto('https://www.linkedin.com/login', {
41
+ waitUntil: 'domcontentloaded',
42
+ timeout: 30000,
43
+ });
44
+ const currentUrl = page.url();
45
+ console.log(`Current page URL: ${currentUrl}`);
46
+ // Debug: Log all input elements on the page
47
+ console.log('Scanning for form elements...');
48
+ const inputs = await page.$$('input');
49
+ console.log(`Found ${inputs.length} input elements`);
50
+ for (let i = 0; i < Math.min(inputs.length, 5); i++) {
51
+ const type = await inputs[i].getAttribute('type');
52
+ const id = await inputs[i].getAttribute('id');
53
+ const name = await inputs[i].getAttribute('name');
54
+ console.log(` Input ${i}: type=${type}, id=${id}, name=${name}`);
55
+ }
56
+ // Find and fill email input
57
+ console.log('Looking for email input...');
58
+ const emailResult = await this.findElementWithFallbacks(selectors_1.SELECTORS.login.emailInput, 'email input');
59
+ if (!emailResult) {
60
+ return {
61
+ success: false,
62
+ error: 'Could not find email input field - LinkedIn may have changed their page structure',
63
+ };
64
+ }
65
+ await page.fill(emailResult.selectorUsed, credentials.email);
66
+ console.log('Email filled successfully');
67
+ // Find and fill password input
68
+ console.log('Looking for password input...');
69
+ const passwordResult = await this.findElementWithFallbacks(selectors_1.SELECTORS.login.passwordInput, 'password input');
70
+ if (!passwordResult) {
71
+ return {
72
+ success: false,
73
+ error: 'Could not find password input field - LinkedIn may have changed their page structure',
74
+ };
75
+ }
76
+ await page.fill(passwordResult.selectorUsed, credentials.password);
77
+ console.log('Password filled successfully');
78
+ // Find and click submit button
79
+ console.log('Looking for submit button...');
80
+ const submitResult = await this.findElementWithFallbacks(selectors_1.SELECTORS.login.submitButton, 'submit button');
81
+ if (!submitResult) {
82
+ return {
83
+ success: false,
84
+ error: 'Could not find submit button - LinkedIn may have changed their page structure',
85
+ };
86
+ }
87
+ if (!submitResult.element) {
88
+ return {
89
+ success: false,
90
+ error: 'Submit button element is null',
91
+ };
92
+ }
93
+ await submitResult.element.click();
94
+ console.log('Submit button clicked');
95
+ // Wait for navigation or 2FA prompt
96
+ console.log('Waiting for page to load...');
97
+ await page.waitForLoadState('networkidle');
98
+ // Check for 2FA prompt
99
+ console.log('Checking for 2FA prompt...');
100
+ const has2FA = await this.findElementWithFallbacks(selectors_1.SELECTORS.twoFA.pinInput, '2FA pin input');
101
+ if (has2FA) {
102
+ console.log('2FA prompt detected');
103
+ if (credentials.totpCode) {
104
+ // Fill in TOTP code
105
+ await page.fill(has2FA.selectorUsed, credentials.totpCode);
106
+ const submit2FA = await this.findElementWithFallbacks(selectors_1.SELECTORS.twoFA.submitButton, '2FA submit button');
107
+ if (submit2FA && submit2FA.element) {
108
+ await submit2FA.element.click();
109
+ }
110
+ await page.waitForLoadState('networkidle');
111
+ }
112
+ else {
113
+ return { success: false, requires2FA: true, error: '2FA required - provide TOTP code' };
114
+ }
115
+ }
116
+ // Check if login succeeded (look for feed or profile element)
117
+ console.log('Checking if login was successful...');
118
+ const navElement = await this.findElementWithFallbacks(selectors_1.SELECTORS.nav.globalNav, 'global navigation');
119
+ if (!navElement) {
120
+ // Check for error message
121
+ const errorElement = await page.$('div[role="alert"] div, div.error, .alert-content');
122
+ const errorText = errorElement ? await errorElement.textContent() : null;
123
+ if (errorText) {
124
+ return { success: false, error: `LinkedIn error: ${errorText.trim()}` };
125
+ }
126
+ // Take a screenshot for debugging
127
+ console.log('Login may have failed - no global nav found');
128
+ return { success: false, error: 'Login failed - could not verify successful login' };
129
+ }
130
+ console.log('Login successful! Saving session...');
131
+ // Save session
132
+ const session = await this.browser.saveSession();
133
+ if (!session) {
134
+ return { success: false, error: 'Failed to save session' };
135
+ }
136
+ console.log('Session saved successfully');
137
+ return { success: true, session };
138
+ }
139
+ catch (error) {
140
+ const errorMessage = error instanceof Error ? error.message : String(error);
141
+ console.error('Login error:', errorMessage);
142
+ return {
143
+ success: false,
144
+ error: `Login error: ${errorMessage}`,
145
+ };
146
+ }
147
+ }
148
+ async isSessionValid() {
149
+ const page = this.browser.getPage();
150
+ if (!page)
151
+ return false;
152
+ try {
153
+ // Navigate to LinkedIn and check if we're logged in
154
+ await page.goto('https://www.linkedin.com/feed', {
155
+ waitUntil: 'domcontentloaded',
156
+ timeout: 10000,
157
+ });
158
+ const navElement = await this.findElementWithFallbacks(selectors_1.SELECTORS.nav.globalNav, 'global navigation');
159
+ return !!navElement;
160
+ }
161
+ catch {
162
+ return false;
163
+ }
164
+ }
165
+ }
166
+ exports.LinkedInAuth = LinkedInAuth;
167
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/linkedin/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Company Profile Extractor
3
+ *
4
+ * Extracts structured data from LinkedIn company profile pages.
5
+ * No authentication required - company pages are public.
6
+ */
7
+ import type { Page } from 'playwright';
8
+ import type { CompanyProfile } from '../types';
9
+ /**
10
+ * Validate if a URL is a valid LinkedIn company URL
11
+ */
12
+ export declare function isValidCompanyUrl(url: string): boolean;
13
+ /**
14
+ * Parse follower count string to number
15
+ * Handles formats like "2.5M followers", "12K", "1,234"
16
+ */
17
+ export declare function parseFollowerCount(text: string | null): number | null;
18
+ /**
19
+ * Parse specialties string to array
20
+ * Splits by comma and trims whitespace
21
+ */
22
+ export declare function parseSpecialties(text: string | null): string[] | null;
23
+ /**
24
+ * Company Profile Extractor
25
+ *
26
+ * Extracts structured data from LinkedIn company profile pages.
27
+ */
28
+ export declare class CompanyExtractor {
29
+ private page;
30
+ constructor(page: Page);
31
+ /**
32
+ * Extract company profile data from a LinkedIn company URL
33
+ */
34
+ extract(url: string): Promise<CompanyProfile>;
35
+ }
36
+ //# sourceMappingURL=company-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"company-extractor.d.ts","sourceRoot":"","sources":["../../src/linkedin/company-extractor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAM/C;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAcrE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,EAAE,GAAG,IAAI,CASrE;AAgED;;;;GAIG;AACH,qBAAa,gBAAgB;IACf,OAAO,CAAC,IAAI;gBAAJ,IAAI,EAAE,IAAI;IAE9B;;OAEG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;CA4FpD"}