@curviate/cli 0.1.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.
@@ -0,0 +1,984 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ BinaryOutputError,
4
+ writeBinaryOutput
5
+ } from "./chunk-UWO2D4HW.js";
6
+ import {
7
+ AttachError,
8
+ readAttachment
9
+ } from "./chunk-Q43HZUN3.js";
10
+ import {
11
+ buildPreviewOutput
12
+ } from "./chunk-R3VLWLVV.js";
13
+ import {
14
+ resolveIdentifier
15
+ } from "./chunk-BNUTM6KD.js";
16
+ import {
17
+ streamAll
18
+ } from "./chunk-SND3NHCT.js";
19
+ import {
20
+ createClient,
21
+ renderError,
22
+ renderSuccess,
23
+ renderUnexpectedError,
24
+ resolveEffectiveConfig
25
+ } from "./chunk-2NCPJJPC.js";
26
+ import {
27
+ GLOBAL_FLAGS
28
+ } from "./chunk-6JNCLLNY.js";
29
+
30
+ // src/commands/recruiter.ts
31
+ import { defineCommand } from "citty";
32
+ function buildOutputStreams() {
33
+ return {
34
+ stdout: { write: (s) => process.stdout.write(s) },
35
+ stderr: { write: (s) => process.stderr.write(s) }
36
+ };
37
+ }
38
+ function requireAccount(account, out) {
39
+ if (!account) {
40
+ out.stderr.write("error: --account is required for this command. Set it via --account, CURVIATE_ACCOUNT, or `curviate config set-account`.\n");
41
+ process.exit(2);
42
+ }
43
+ return account;
44
+ }
45
+ function rejectPreviewOnRead(preview, out) {
46
+ if (preview) {
47
+ out.stderr.write("error: --preview is only valid on write commands (mutations). Reads just run.\n");
48
+ process.exit(2);
49
+ }
50
+ }
51
+ function resolveOutputOpts(flags) {
52
+ return {
53
+ json: (flags.json ?? false) || !process.stdout.isTTY,
54
+ isTTY: process.stdout.isTTY ?? false,
55
+ fields: flags.fields
56
+ };
57
+ }
58
+ function normalizeAttachPaths(attach) {
59
+ if (!attach) return [];
60
+ return Array.isArray(attach) ? attach : [attach];
61
+ }
62
+ async function handleSdkError(err, outOpts, out) {
63
+ const { CurviateError } = await import("@curviate/sdk");
64
+ if (err instanceof CurviateError) {
65
+ const { getExitCode } = await import("./exit-codes-NFIR57ZA.js");
66
+ renderError(err, outOpts, out);
67
+ process.exit(getExitCode(err.code));
68
+ }
69
+ renderUnexpectedError(err, out);
70
+ process.exit(1);
71
+ }
72
+ async function runRecruiterSync(client, flags, out) {
73
+ rejectPreviewOnRead(flags.preview, out);
74
+ const accountId = requireAccount(flags.account, out);
75
+ const ns = client.account(accountId);
76
+ const outOpts = resolveOutputOpts(flags);
77
+ const params = {};
78
+ if (flags.cursor) params["cursor"] = flags.cursor;
79
+ if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
80
+ try {
81
+ const result = await ns.recruiter.syncMessages(params);
82
+ renderSuccess(result, outOpts, out);
83
+ } catch (err) {
84
+ await handleSdkError(err, outOpts, out);
85
+ }
86
+ }
87
+ async function runRecruiterMessageNew(client, flags, out) {
88
+ const accountId = requireAccount(flags.account, out);
89
+ const to = flags.to ?? "";
90
+ const text = flags.text ?? "";
91
+ const attachPaths = normalizeAttachPaths(flags.attach);
92
+ const voicePath = flags.voice;
93
+ const videoPath = flags.video;
94
+ let attachBuffers = [];
95
+ let voiceBuffer;
96
+ let videoBuffer;
97
+ try {
98
+ attachBuffers = await Promise.all(attachPaths.map((p) => readAttachment(p)));
99
+ if (voicePath) voiceBuffer = await readAttachment(voicePath);
100
+ if (videoPath) videoBuffer = await readAttachment(videoPath);
101
+ } catch (err) {
102
+ if (err instanceof AttachError) {
103
+ out.stderr.write(`error: ${err.message}
104
+ `);
105
+ process.exit(err.exitCode);
106
+ }
107
+ throw err;
108
+ }
109
+ const body = {
110
+ attendees_ids: [to],
111
+ text
112
+ };
113
+ if (flags.preview) {
114
+ const preview = buildPreviewOutput({
115
+ method: "recruiter.startChat",
116
+ args: { attendees_ids: [to] },
117
+ body: { ...body },
118
+ account: accountId,
119
+ attachments: [
120
+ ...attachBuffers.map((buf, i) => ({
121
+ name: attachPaths[i] ? attachPaths[i].split("/").pop() ?? attachPaths[i] : `attachment_${i}`,
122
+ buffer: buf
123
+ })),
124
+ ...voiceBuffer ? [{ name: voicePath ? voicePath.split("/").pop() ?? voicePath : "voice", buffer: voiceBuffer }] : [],
125
+ ...videoBuffer ? [{ name: videoPath ? videoPath.split("/").pop() ?? videoPath : "video", buffer: videoBuffer }] : []
126
+ ]
127
+ });
128
+ out.stdout.write(JSON.stringify(preview) + "\n");
129
+ return;
130
+ }
131
+ if (attachBuffers.length > 0) body["attachments"] = attachBuffers;
132
+ if (voiceBuffer) body["voice_message"] = voiceBuffer;
133
+ if (videoBuffer) body["video_message"] = videoBuffer;
134
+ const ns = client.account(accountId);
135
+ const outOpts = resolveOutputOpts(flags);
136
+ try {
137
+ const result = await ns.recruiter.startChat(body);
138
+ renderSuccess(result, outOpts, out);
139
+ } catch (err) {
140
+ await handleSdkError(err, outOpts, out);
141
+ }
142
+ }
143
+ async function runRecruiterProfile(client, flags, out) {
144
+ rejectPreviewOnRead(flags.preview, out);
145
+ const accountId = requireAccount(flags.account, out);
146
+ const rawId = flags.identifier ?? "";
147
+ const resolvedId = resolveIdentifier(rawId);
148
+ const ns = client.account(accountId);
149
+ const outOpts = resolveOutputOpts(flags);
150
+ try {
151
+ const result = await ns.recruiter.getProfile(resolvedId, {});
152
+ renderSuccess(result, outOpts, out);
153
+ } catch (err) {
154
+ await handleSdkError(err, outOpts, out);
155
+ }
156
+ }
157
+ async function runRecruiterSearchPeople(client, flags, out) {
158
+ rejectPreviewOnRead(flags.preview, out);
159
+ const accountId = requireAccount(flags.account, out);
160
+ const ns = client.account(accountId);
161
+ const outOpts = resolveOutputOpts(flags);
162
+ const all = flags.all ?? false;
163
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
164
+ const limit = flags.limit ? parseInt(flags.limit, 10) : void 0;
165
+ const cursor = flags.cursor;
166
+ const body = {};
167
+ if (flags.keywords) body["keywords"] = flags.keywords;
168
+ const params = {};
169
+ if (limit !== void 0) params["limit"] = limit;
170
+ if (cursor) params["cursor"] = cursor;
171
+ try {
172
+ if (all) {
173
+ const fn = (p) => {
174
+ const mergedBody = { ...body };
175
+ const { cursor: c, limit: l, ...restP } = p;
176
+ const callParams = {};
177
+ if (c) callParams["cursor"] = c;
178
+ if (l) callParams["limit"] = l;
179
+ void restP;
180
+ return ns.recruiter.searchPeople(mergedBody, callParams);
181
+ };
182
+ for await (const item of streamAll(fn, params, {
183
+ maxPages,
184
+ onTruncated: (msg) => out.stderr.write(msg + "\n")
185
+ })) {
186
+ out.stdout.write(JSON.stringify(item) + "\n");
187
+ }
188
+ } else {
189
+ const result = await ns.recruiter.searchPeople(body, Object.keys(params).length > 0 ? params : void 0);
190
+ renderSuccess(result, outOpts, out);
191
+ }
192
+ } catch (err) {
193
+ await handleSdkError(err, outOpts, out);
194
+ }
195
+ }
196
+ async function runRecruiterGetParameters(client, flags, out) {
197
+ rejectPreviewOnRead(flags.preview, out);
198
+ const accountId = requireAccount(flags.account, out);
199
+ const ns = client.account(accountId);
200
+ const outOpts = resolveOutputOpts(flags);
201
+ const params = {};
202
+ if (flags.type) params["type"] = flags.type;
203
+ try {
204
+ const result = await ns.recruiter.getParameters(params);
205
+ renderSuccess(result, outOpts, out);
206
+ } catch (err) {
207
+ await handleSdkError(err, outOpts, out);
208
+ }
209
+ }
210
+ async function runRecruiterListProjects(client, flags, out) {
211
+ rejectPreviewOnRead(flags.preview, out);
212
+ const accountId = requireAccount(flags.account, out);
213
+ const ns = client.account(accountId);
214
+ const outOpts = resolveOutputOpts(flags);
215
+ const all = flags.all ?? false;
216
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
217
+ const limit = flags.limit ? parseInt(flags.limit, 10) : void 0;
218
+ const cursor = flags.cursor;
219
+ const params = {};
220
+ if (limit !== void 0) params["limit"] = limit;
221
+ if (cursor) params["cursor"] = cursor;
222
+ try {
223
+ if (all) {
224
+ const fn = (p) => ns.recruiter.listProjects(p);
225
+ for await (const item of streamAll(fn, params, {
226
+ maxPages,
227
+ onTruncated: (msg) => out.stderr.write(msg + "\n")
228
+ })) {
229
+ out.stdout.write(JSON.stringify(item) + "\n");
230
+ }
231
+ } else {
232
+ const result = await ns.recruiter.listProjects(Object.keys(params).length > 0 ? params : void 0);
233
+ renderSuccess(result, outOpts, out);
234
+ }
235
+ } catch (err) {
236
+ await handleSdkError(err, outOpts, out);
237
+ }
238
+ }
239
+ async function runRecruiterGetProject(client, flags, out) {
240
+ rejectPreviewOnRead(flags.preview, out);
241
+ const accountId = requireAccount(flags.account, out);
242
+ const projectId = flags.projectId ?? "";
243
+ const ns = client.account(accountId);
244
+ const outOpts = resolveOutputOpts(flags);
245
+ try {
246
+ const result = await ns.recruiter.getProject(projectId);
247
+ renderSuccess(result, outOpts, out);
248
+ } catch (err) {
249
+ await handleSdkError(err, outOpts, out);
250
+ }
251
+ }
252
+ async function runRecruiterAddCandidate(client, flags, out) {
253
+ const accountId = requireAccount(flags.account, out);
254
+ const userId = flags.userId ?? "";
255
+ const outOpts = resolveOutputOpts(flags);
256
+ const body = {};
257
+ if (flags["hiring-project-id"]) body["hiring_project_id"] = flags["hiring-project-id"];
258
+ if (flags.stage) body["stage"] = flags.stage;
259
+ if (flags.preview) {
260
+ const preview = buildPreviewOutput({
261
+ method: "recruiter.addCandidate",
262
+ args: { user_id: userId },
263
+ body,
264
+ account: accountId
265
+ });
266
+ out.stdout.write(JSON.stringify(preview) + "\n");
267
+ return;
268
+ }
269
+ const ns = client.account(accountId);
270
+ try {
271
+ const result = await ns.recruiter.addCandidate(userId, body);
272
+ renderSuccess(result, outOpts, out);
273
+ } catch (err) {
274
+ await handleSdkError(err, outOpts, out);
275
+ }
276
+ }
277
+ async function runRecruiterAddApplicant(client, flags, out) {
278
+ const accountId = requireAccount(flags.account, out);
279
+ const userId = flags.userId ?? "";
280
+ const outOpts = resolveOutputOpts(flags);
281
+ const body = {};
282
+ if (flags["hiring-project-id"]) body["hiring_project_id"] = flags["hiring-project-id"];
283
+ if (flags.stage) body["stage"] = flags.stage;
284
+ if (flags.preview) {
285
+ const preview = buildPreviewOutput({
286
+ method: "recruiter.addApplicant",
287
+ args: { user_id: userId },
288
+ body,
289
+ account: accountId
290
+ });
291
+ out.stdout.write(JSON.stringify(preview) + "\n");
292
+ return;
293
+ }
294
+ const ns = client.account(accountId);
295
+ try {
296
+ const result = await ns.recruiter.addApplicant(userId, body);
297
+ renderSuccess(result, outOpts, out);
298
+ } catch (err) {
299
+ await handleSdkError(err, outOpts, out);
300
+ }
301
+ }
302
+ async function runRecruiterRejectApplicant(client, flags, out) {
303
+ const accountId = requireAccount(flags.account, out);
304
+ const userId = flags.userId ?? "";
305
+ const outOpts = resolveOutputOpts(flags);
306
+ const body = {};
307
+ if (flags["hiring-project-id"]) body["hiring_project_id"] = flags["hiring-project-id"];
308
+ if (flags.reason) body["reason"] = flags.reason;
309
+ if (flags.preview) {
310
+ const preview = buildPreviewOutput({
311
+ method: "recruiter.rejectApplicant",
312
+ args: { user_id: userId },
313
+ body,
314
+ account: accountId
315
+ });
316
+ out.stdout.write(JSON.stringify(preview) + "\n");
317
+ return;
318
+ }
319
+ const ns = client.account(accountId);
320
+ try {
321
+ const result = await ns.recruiter.rejectApplicant(userId, body);
322
+ renderSuccess(result, outOpts, out);
323
+ } catch (err) {
324
+ await handleSdkError(err, outOpts, out);
325
+ }
326
+ }
327
+ async function runRecruiterListJobs(client, flags, out) {
328
+ rejectPreviewOnRead(flags.preview, out);
329
+ const accountId = requireAccount(flags.account, out);
330
+ const ns = client.account(accountId);
331
+ const outOpts = resolveOutputOpts(flags);
332
+ const all = flags.all ?? false;
333
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
334
+ const limit = flags.limit ? parseInt(flags.limit, 10) : void 0;
335
+ const cursor = flags.cursor;
336
+ const params = {};
337
+ if (limit !== void 0) params["limit"] = limit;
338
+ if (cursor) params["cursor"] = cursor;
339
+ try {
340
+ if (all) {
341
+ const fn = (p) => ns.recruiter.listJobs(p);
342
+ for await (const item of streamAll(fn, params, {
343
+ maxPages,
344
+ onTruncated: (msg) => out.stderr.write(msg + "\n")
345
+ })) {
346
+ out.stdout.write(JSON.stringify(item) + "\n");
347
+ }
348
+ } else {
349
+ const result = await ns.recruiter.listJobs(Object.keys(params).length > 0 ? params : void 0);
350
+ renderSuccess(result, outOpts, out);
351
+ }
352
+ } catch (err) {
353
+ await handleSdkError(err, outOpts, out);
354
+ }
355
+ }
356
+ async function runRecruiterCreateJob(client, flags, out) {
357
+ const accountId = requireAccount(flags.account, out);
358
+ const outOpts = resolveOutputOpts(flags);
359
+ const body = {};
360
+ if (flags.preview) {
361
+ const preview = buildPreviewOutput({
362
+ method: "recruiter.createJob",
363
+ args: {},
364
+ body,
365
+ account: accountId
366
+ });
367
+ out.stdout.write(JSON.stringify(preview) + "\n");
368
+ return;
369
+ }
370
+ const ns = client.account(accountId);
371
+ try {
372
+ const result = await ns.recruiter.createJob(body);
373
+ renderSuccess(result, outOpts, out);
374
+ } catch (err) {
375
+ await handleSdkError(err, outOpts, out);
376
+ }
377
+ }
378
+ async function runRecruiterPublishJob(client, flags, out) {
379
+ const accountId = requireAccount(flags.account, out);
380
+ const jobId = flags.jobId ?? "";
381
+ const outOpts = resolveOutputOpts(flags);
382
+ const body = {};
383
+ if (flags.mode) body["mode"] = flags.mode;
384
+ if (flags.preview) {
385
+ const preview = buildPreviewOutput({
386
+ method: "recruiter.publishJob",
387
+ args: { job_id: jobId },
388
+ body,
389
+ account: accountId
390
+ });
391
+ out.stdout.write(JSON.stringify(preview) + "\n");
392
+ return;
393
+ }
394
+ const ns = client.account(accountId);
395
+ try {
396
+ const result = await ns.recruiter.publishJob(jobId, body);
397
+ renderSuccess(result, outOpts, out);
398
+ } catch (err) {
399
+ await handleSdkError(err, outOpts, out);
400
+ }
401
+ }
402
+ async function runRecruiterJobCheckpoint(client, flags, out) {
403
+ const accountId = requireAccount(flags.account, out);
404
+ const jobId = flags.jobId ?? "";
405
+ const outOpts = resolveOutputOpts(flags);
406
+ const body = {};
407
+ if (flags.input) body["input"] = flags.input;
408
+ if (flags.preview) {
409
+ const preview = buildPreviewOutput({
410
+ method: "recruiter.solveJobCheckpoint",
411
+ args: { job_id: jobId },
412
+ body,
413
+ account: accountId
414
+ });
415
+ out.stdout.write(JSON.stringify(preview) + "\n");
416
+ return;
417
+ }
418
+ const ns = client.account(accountId);
419
+ try {
420
+ const result = await ns.recruiter.solveJobCheckpoint(jobId, body);
421
+ renderSuccess(result, outOpts, out);
422
+ } catch (err) {
423
+ await handleSdkError(err, outOpts, out);
424
+ }
425
+ }
426
+ async function runRecruiterListApplicants(client, flags, out) {
427
+ rejectPreviewOnRead(flags.preview, out);
428
+ const accountId = requireAccount(flags.account, out);
429
+ const jobId = flags.jobId ?? "";
430
+ const ns = client.account(accountId);
431
+ const outOpts = resolveOutputOpts(flags);
432
+ const params = {};
433
+ if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
434
+ if (flags.cursor) params["cursor"] = flags.cursor;
435
+ try {
436
+ const result = await ns.recruiter.listApplicants(jobId, Object.keys(params).length > 0 ? params : void 0);
437
+ renderSuccess(result, outOpts, out);
438
+ } catch (err) {
439
+ await handleSdkError(err, outOpts, out);
440
+ }
441
+ }
442
+ async function runRecruiterGetApplicant(client, flags, out) {
443
+ rejectPreviewOnRead(flags.preview, out);
444
+ const accountId = requireAccount(flags.account, out);
445
+ const applicantId = flags.applicantId ?? "";
446
+ const ns = client.account(accountId);
447
+ const outOpts = resolveOutputOpts(flags);
448
+ try {
449
+ const result = await ns.recruiter.getApplicant(applicantId);
450
+ renderSuccess(result, outOpts, out);
451
+ } catch (err) {
452
+ await handleSdkError(err, outOpts, out);
453
+ }
454
+ }
455
+ async function runRecruiterDownloadResume(client, flags, out, isTTY) {
456
+ rejectPreviewOnRead(flags.preview, out);
457
+ const accountId = requireAccount(flags.account, out);
458
+ const applicantId = flags.applicantId ?? "";
459
+ const ns = client.account(accountId);
460
+ try {
461
+ const data = await ns.recruiter.downloadResume(applicantId);
462
+ await writeBinaryOutput(data, {
463
+ outputPath: flags.output,
464
+ isTTY,
465
+ stdout: process.stdout
466
+ });
467
+ } catch (err) {
468
+ if (err instanceof BinaryOutputError) {
469
+ out.stderr.write(`error: ${err.message}
470
+ `);
471
+ process.exit(err.exitCode);
472
+ }
473
+ const outOpts = resolveOutputOpts(flags);
474
+ await handleSdkError(err, outOpts, out);
475
+ }
476
+ }
477
+ var recruiterSyncCommand = defineCommand({
478
+ meta: { name: "sync", description: "Sync Recruiter message history for an account." },
479
+ args: { ...GLOBAL_FLAGS },
480
+ async run({ args }) {
481
+ const flags = args;
482
+ const cfg = await resolveEffectiveConfig({
483
+ apiKey: flags["api-key"],
484
+ baseUrl: flags["base-url"],
485
+ timeout: flags.timeout,
486
+ account: flags.account,
487
+ profile: flags.profile
488
+ });
489
+ if (!cfg.apiKey) {
490
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
491
+ process.exit(3);
492
+ }
493
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
494
+ const out = buildOutputStreams();
495
+ await runRecruiterSync(client, { ...flags, account: flags.account ?? cfg.account }, out);
496
+ }
497
+ });
498
+ var recruiterMessageNewCommand = defineCommand({
499
+ meta: { name: "new", description: "Start a new Recruiter chat (InMail)." },
500
+ args: {
501
+ ...GLOBAL_FLAGS,
502
+ to: { type: "string", description: "Recipient provider ID.", required: true },
503
+ text: { type: "positional", description: "Message text." },
504
+ attach: { type: "string", description: "File to attach (repeatable)." },
505
+ voice: { type: "string", description: "Voice message file." },
506
+ video: { type: "string", description: "Video message file." }
507
+ },
508
+ async run({ args }) {
509
+ const flags = args;
510
+ const cfg = await resolveEffectiveConfig({
511
+ apiKey: flags["api-key"],
512
+ baseUrl: flags["base-url"],
513
+ timeout: flags.timeout,
514
+ account: flags.account,
515
+ profile: flags.profile
516
+ });
517
+ if (!cfg.apiKey) {
518
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
519
+ process.exit(3);
520
+ }
521
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
522
+ const out = buildOutputStreams();
523
+ await runRecruiterMessageNew(client, { ...flags, account: flags.account ?? cfg.account }, out);
524
+ }
525
+ });
526
+ var recruiterMessageCommand = defineCommand({
527
+ meta: { name: "message", description: "Recruiter messaging operations." },
528
+ args: { ...GLOBAL_FLAGS },
529
+ subCommands: {
530
+ new: recruiterMessageNewCommand
531
+ },
532
+ async run() {
533
+ process.stderr.write('Usage: curviate recruiter message new --to <id> "<text>" [--attach <file>\u2026]\n');
534
+ }
535
+ });
536
+ var recruiterProfileCommand = defineCommand({
537
+ meta: { name: "profile", description: "Get a Recruiter enriched member profile." },
538
+ args: {
539
+ ...GLOBAL_FLAGS,
540
+ identifier: { type: "positional", description: "LinkedIn URL, slug, or native id." }
541
+ },
542
+ async run({ args }) {
543
+ const flags = args;
544
+ const cfg = await resolveEffectiveConfig({
545
+ apiKey: flags["api-key"],
546
+ baseUrl: flags["base-url"],
547
+ timeout: flags.timeout,
548
+ account: flags.account,
549
+ profile: flags.profile
550
+ });
551
+ if (!cfg.apiKey) {
552
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
553
+ process.exit(3);
554
+ }
555
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
556
+ const out = buildOutputStreams();
557
+ await runRecruiterProfile(client, { ...flags, account: flags.account ?? cfg.account }, out);
558
+ }
559
+ });
560
+ var recruiterSearchPeopleCommand = defineCommand({
561
+ meta: { name: "people", description: "Search Recruiter member profiles." },
562
+ args: {
563
+ ...GLOBAL_FLAGS,
564
+ keywords: { type: "string", description: "Keyword search string." }
565
+ },
566
+ async run({ args }) {
567
+ const flags = args;
568
+ const cfg = await resolveEffectiveConfig({
569
+ apiKey: flags["api-key"],
570
+ baseUrl: flags["base-url"],
571
+ timeout: flags.timeout,
572
+ account: flags.account,
573
+ profile: flags.profile
574
+ });
575
+ if (!cfg.apiKey) {
576
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
577
+ process.exit(3);
578
+ }
579
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
580
+ const out = buildOutputStreams();
581
+ await runRecruiterSearchPeople(client, { ...flags, account: flags.account ?? cfg.account }, out);
582
+ }
583
+ });
584
+ var recruiterSearchParametersCommand = defineCommand({
585
+ meta: { name: "parameters", description: "Resolve Recruiter filter parameter IDs." },
586
+ args: {
587
+ ...GLOBAL_FLAGS,
588
+ type: { type: "string", description: "Parameter type (e.g. LOCATION, INDUSTRY, TITLE).", required: true }
589
+ },
590
+ async run({ args }) {
591
+ const flags = args;
592
+ const cfg = await resolveEffectiveConfig({
593
+ apiKey: flags["api-key"],
594
+ baseUrl: flags["base-url"],
595
+ timeout: flags.timeout,
596
+ account: flags.account,
597
+ profile: flags.profile
598
+ });
599
+ if (!cfg.apiKey) {
600
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
601
+ process.exit(3);
602
+ }
603
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
604
+ const out = buildOutputStreams();
605
+ await runRecruiterGetParameters(client, { ...flags, account: flags.account ?? cfg.account }, out);
606
+ }
607
+ });
608
+ var recruiterSearchCommand = defineCommand({
609
+ meta: { name: "search", description: "Recruiter search operations." },
610
+ args: { ...GLOBAL_FLAGS },
611
+ subCommands: {
612
+ people: recruiterSearchPeopleCommand,
613
+ parameters: recruiterSearchParametersCommand
614
+ },
615
+ async run() {
616
+ process.stderr.write(
617
+ "Usage: curviate recruiter search people [--keywords <k>]\n curviate recruiter search parameters --type <t>\n"
618
+ );
619
+ }
620
+ });
621
+ var recruiterProjectsCommand = defineCommand({
622
+ meta: { name: "projects", description: "List Recruiter hiring projects." },
623
+ args: { ...GLOBAL_FLAGS },
624
+ async run({ args }) {
625
+ const flags = args;
626
+ const cfg = await resolveEffectiveConfig({
627
+ apiKey: flags["api-key"],
628
+ baseUrl: flags["base-url"],
629
+ timeout: flags.timeout,
630
+ account: flags.account,
631
+ profile: flags.profile
632
+ });
633
+ if (!cfg.apiKey) {
634
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
635
+ process.exit(3);
636
+ }
637
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
638
+ const out = buildOutputStreams();
639
+ await runRecruiterListProjects(client, { ...flags, account: flags.account ?? cfg.account }, out);
640
+ }
641
+ });
642
+ var recruiterProjectCommand = defineCommand({
643
+ meta: { name: "project", description: "Get a Recruiter hiring project by ID." },
644
+ args: {
645
+ ...GLOBAL_FLAGS,
646
+ projectId: { type: "positional", description: "Recruiter project ID." }
647
+ },
648
+ async run({ args }) {
649
+ const flags = args;
650
+ const cfg = await resolveEffectiveConfig({
651
+ apiKey: flags["api-key"],
652
+ baseUrl: flags["base-url"],
653
+ timeout: flags.timeout,
654
+ account: flags.account,
655
+ profile: flags.profile
656
+ });
657
+ if (!cfg.apiKey) {
658
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
659
+ process.exit(3);
660
+ }
661
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
662
+ const out = buildOutputStreams();
663
+ await runRecruiterGetProject(client, { ...flags, account: flags.account ?? cfg.account }, out);
664
+ }
665
+ });
666
+ var recruiterAddCandidateCommand = defineCommand({
667
+ meta: { name: "add-candidate", description: "Add a member as a candidate in a hiring project." },
668
+ args: {
669
+ ...GLOBAL_FLAGS,
670
+ userId: { type: "positional", description: "Member ID (AEM\u2026 format)." },
671
+ "hiring-project-id": { type: "string", description: "Recruiter hiring project ID.", required: true },
672
+ stage: { type: "string", description: "Pipeline stage (UNCONTACTED, CONTACTED, REPLIED)." }
673
+ },
674
+ async run({ args }) {
675
+ const flags = args;
676
+ const cfg = await resolveEffectiveConfig({
677
+ apiKey: flags["api-key"],
678
+ baseUrl: flags["base-url"],
679
+ timeout: flags.timeout,
680
+ account: flags.account,
681
+ profile: flags.profile
682
+ });
683
+ if (!cfg.apiKey) {
684
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
685
+ process.exit(3);
686
+ }
687
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
688
+ const out = buildOutputStreams();
689
+ await runRecruiterAddCandidate(client, { ...flags, account: flags.account ?? cfg.account }, out);
690
+ }
691
+ });
692
+ var recruiterAddApplicantCommand = defineCommand({
693
+ meta: { name: "add-applicant", description: "Add a member as an applicant in a hiring project." },
694
+ args: {
695
+ ...GLOBAL_FLAGS,
696
+ userId: { type: "positional", description: "Member ID (AEM\u2026 format)." },
697
+ "hiring-project-id": { type: "string", description: "Recruiter hiring project ID.", required: true },
698
+ stage: { type: "string", description: "Pipeline stage (UNCONTACTED, CONTACTED, REPLIED)." }
699
+ },
700
+ async run({ args }) {
701
+ const flags = args;
702
+ const cfg = await resolveEffectiveConfig({
703
+ apiKey: flags["api-key"],
704
+ baseUrl: flags["base-url"],
705
+ timeout: flags.timeout,
706
+ account: flags.account,
707
+ profile: flags.profile
708
+ });
709
+ if (!cfg.apiKey) {
710
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
711
+ process.exit(3);
712
+ }
713
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
714
+ const out = buildOutputStreams();
715
+ await runRecruiterAddApplicant(client, { ...flags, account: flags.account ?? cfg.account }, out);
716
+ }
717
+ });
718
+ var recruiterRejectApplicantCommand = defineCommand({
719
+ meta: { name: "reject-applicant", description: "Reject an applicant from a hiring project." },
720
+ args: {
721
+ ...GLOBAL_FLAGS,
722
+ userId: { type: "positional", description: "Member ID (AEM\u2026 format)." },
723
+ "hiring-project-id": { type: "string", description: "Recruiter hiring project ID.", required: true },
724
+ reason: {
725
+ type: "string",
726
+ description: "Rejection reason (NOT_MEET_BASIC_QUALIFICATIONS, NOT_IN_DESIRED_LOCATION, MORE_QUALIFIED_CANDIDATES, WITHDREW_APPLICATION, NOT_CONSIDERED_OR_REASON_NOT_SPECIFIED).",
727
+ required: true
728
+ }
729
+ },
730
+ async run({ args }) {
731
+ const flags = args;
732
+ const cfg = await resolveEffectiveConfig({
733
+ apiKey: flags["api-key"],
734
+ baseUrl: flags["base-url"],
735
+ timeout: flags.timeout,
736
+ account: flags.account,
737
+ profile: flags.profile
738
+ });
739
+ if (!cfg.apiKey) {
740
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
741
+ process.exit(3);
742
+ }
743
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
744
+ const out = buildOutputStreams();
745
+ await runRecruiterRejectApplicant(client, { ...flags, account: flags.account ?? cfg.account }, out);
746
+ }
747
+ });
748
+ var recruiterJobsCommand = defineCommand({
749
+ meta: { name: "jobs", description: "List Recruiter job postings." },
750
+ args: { ...GLOBAL_FLAGS },
751
+ async run({ args }) {
752
+ const flags = args;
753
+ const cfg = await resolveEffectiveConfig({
754
+ apiKey: flags["api-key"],
755
+ baseUrl: flags["base-url"],
756
+ timeout: flags.timeout,
757
+ account: flags.account,
758
+ profile: flags.profile
759
+ });
760
+ if (!cfg.apiKey) {
761
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
762
+ process.exit(3);
763
+ }
764
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
765
+ const out = buildOutputStreams();
766
+ await runRecruiterListJobs(client, { ...flags, account: flags.account ?? cfg.account }, out);
767
+ }
768
+ });
769
+ var recruiterJobCreateCommand = defineCommand({
770
+ meta: { name: "create", description: "Create a Recruiter job posting draft." },
771
+ args: { ...GLOBAL_FLAGS },
772
+ async run({ args }) {
773
+ const flags = args;
774
+ const cfg = await resolveEffectiveConfig({
775
+ apiKey: flags["api-key"],
776
+ baseUrl: flags["base-url"],
777
+ timeout: flags.timeout,
778
+ account: flags.account,
779
+ profile: flags.profile
780
+ });
781
+ if (!cfg.apiKey) {
782
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
783
+ process.exit(3);
784
+ }
785
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
786
+ const out = buildOutputStreams();
787
+ await runRecruiterCreateJob(client, { ...flags, account: flags.account ?? cfg.account }, out);
788
+ }
789
+ });
790
+ var recruiterJobPublishCommand = defineCommand({
791
+ meta: { name: "publish", description: "Publish a Recruiter job posting draft." },
792
+ args: {
793
+ ...GLOBAL_FLAGS,
794
+ jobId: { type: "positional", description: "Job posting ID." },
795
+ mode: { type: "string", description: "Publish mode: FREE (default), PROMOTED, or PROMOTED_PLUS." }
796
+ },
797
+ async run({ args }) {
798
+ const flags = args;
799
+ const cfg = await resolveEffectiveConfig({
800
+ apiKey: flags["api-key"],
801
+ baseUrl: flags["base-url"],
802
+ timeout: flags.timeout,
803
+ account: flags.account,
804
+ profile: flags.profile
805
+ });
806
+ if (!cfg.apiKey) {
807
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
808
+ process.exit(3);
809
+ }
810
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
811
+ const out = buildOutputStreams();
812
+ await runRecruiterPublishJob(client, { ...flags, account: flags.account ?? cfg.account }, out);
813
+ }
814
+ });
815
+ var recruiterJobCheckpointCommand = defineCommand({
816
+ meta: { name: "checkpoint", description: "Solve a job posting publish verification checkpoint." },
817
+ args: {
818
+ ...GLOBAL_FLAGS,
819
+ jobId: { type: "positional", description: "Job posting ID." },
820
+ input: { type: "string", description: "Verification value (OTP or email confirmation).", required: true }
821
+ },
822
+ async run({ args }) {
823
+ const flags = args;
824
+ const cfg = await resolveEffectiveConfig({
825
+ apiKey: flags["api-key"],
826
+ baseUrl: flags["base-url"],
827
+ timeout: flags.timeout,
828
+ account: flags.account,
829
+ profile: flags.profile
830
+ });
831
+ if (!cfg.apiKey) {
832
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
833
+ process.exit(3);
834
+ }
835
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
836
+ const out = buildOutputStreams();
837
+ await runRecruiterJobCheckpoint(client, { ...flags, account: flags.account ?? cfg.account }, out);
838
+ }
839
+ });
840
+ var recruiterJobApplicantsCommand = defineCommand({
841
+ meta: { name: "applicants", description: "List applicants for a Recruiter job posting." },
842
+ args: {
843
+ ...GLOBAL_FLAGS,
844
+ jobId: { type: "positional", description: "Job posting ID." }
845
+ },
846
+ async run({ args }) {
847
+ const flags = args;
848
+ const cfg = await resolveEffectiveConfig({
849
+ apiKey: flags["api-key"],
850
+ baseUrl: flags["base-url"],
851
+ timeout: flags.timeout,
852
+ account: flags.account,
853
+ profile: flags.profile
854
+ });
855
+ if (!cfg.apiKey) {
856
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
857
+ process.exit(3);
858
+ }
859
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
860
+ const out = buildOutputStreams();
861
+ await runRecruiterListApplicants(client, { ...flags, account: flags.account ?? cfg.account }, out);
862
+ }
863
+ });
864
+ var recruiterJobCommand = defineCommand({
865
+ meta: { name: "job", description: "Recruiter job posting operations." },
866
+ args: { ...GLOBAL_FLAGS },
867
+ subCommands: {
868
+ create: recruiterJobCreateCommand,
869
+ publish: recruiterJobPublishCommand,
870
+ checkpoint: recruiterJobCheckpointCommand,
871
+ applicants: recruiterJobApplicantsCommand
872
+ },
873
+ async run() {
874
+ process.stderr.write(
875
+ "Usage: curviate recruiter job create [flags\u2026]\n curviate recruiter job publish <job_id> [--mode <m>]\n curviate recruiter job checkpoint <job_id> --input <v>\n curviate recruiter job applicants <job_id>\n"
876
+ );
877
+ }
878
+ });
879
+ var recruiterApplicantResumeCommand = defineCommand({
880
+ meta: { name: "resume", description: "Download a job applicant's resume." },
881
+ args: {
882
+ ...GLOBAL_FLAGS,
883
+ applicantId: { type: "positional", description: "Applicant ID." },
884
+ output: { type: "string", alias: "o", description: "Path to write the resume file." }
885
+ },
886
+ async run({ args }) {
887
+ const flags = args;
888
+ const cfg = await resolveEffectiveConfig({
889
+ apiKey: flags["api-key"],
890
+ baseUrl: flags["base-url"],
891
+ timeout: flags.timeout,
892
+ account: flags.account,
893
+ profile: flags.profile
894
+ });
895
+ if (!cfg.apiKey) {
896
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
897
+ process.exit(3);
898
+ }
899
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
900
+ const out = buildOutputStreams();
901
+ await runRecruiterDownloadResume(
902
+ client,
903
+ { ...flags, account: flags.account ?? cfg.account },
904
+ out,
905
+ process.stdout.isTTY ?? false
906
+ );
907
+ }
908
+ });
909
+ var recruiterApplicantCommand = defineCommand({
910
+ meta: { name: "applicant", description: "Recruiter job applicant operations." },
911
+ args: {
912
+ ...GLOBAL_FLAGS,
913
+ applicantId: { type: "positional", description: "Applicant ID.", required: false }
914
+ },
915
+ subCommands: {
916
+ resume: recruiterApplicantResumeCommand
917
+ },
918
+ async run({ args }) {
919
+ const flags = args;
920
+ if (!flags.applicantId) {
921
+ process.stderr.write(
922
+ "Usage: curviate recruiter applicant <applicant_id>\n curviate recruiter applicant resume <applicant_id> -o <file>\n"
923
+ );
924
+ return;
925
+ }
926
+ const cfg = await resolveEffectiveConfig({
927
+ apiKey: flags["api-key"],
928
+ baseUrl: flags["base-url"],
929
+ timeout: flags.timeout,
930
+ account: flags.account,
931
+ profile: flags.profile
932
+ });
933
+ if (!cfg.apiKey) {
934
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
935
+ process.exit(3);
936
+ }
937
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
938
+ const out = buildOutputStreams();
939
+ await runRecruiterGetApplicant(client, { ...flags, account: flags.account ?? cfg.account }, out);
940
+ }
941
+ });
942
+ var recruiterCommand = defineCommand({
943
+ meta: { name: "recruiter", description: "LinkedIn Recruiter operations (requires the Recruiter add-on)." },
944
+ args: { ...GLOBAL_FLAGS },
945
+ subCommands: {
946
+ sync: recruiterSyncCommand,
947
+ message: recruiterMessageCommand,
948
+ profile: recruiterProfileCommand,
949
+ search: recruiterSearchCommand,
950
+ projects: recruiterProjectsCommand,
951
+ project: recruiterProjectCommand,
952
+ "add-candidate": recruiterAddCandidateCommand,
953
+ "add-applicant": recruiterAddApplicantCommand,
954
+ "reject-applicant": recruiterRejectApplicantCommand,
955
+ jobs: recruiterJobsCommand,
956
+ job: recruiterJobCommand,
957
+ applicant: recruiterApplicantCommand
958
+ },
959
+ async run() {
960
+ process.stderr.write(
961
+ 'Usage: curviate recruiter sync\n curviate recruiter message new --to <id> "<text>"\n curviate recruiter profile <identifier>\n curviate recruiter search people [--keywords <k>]\n curviate recruiter search parameters --type <t>\n curviate recruiter projects\n curviate recruiter project <project_id>\n curviate recruiter add-candidate <user_id> --hiring-project-id <id>\n curviate recruiter add-applicant <user_id> --hiring-project-id <id>\n curviate recruiter reject-applicant <user_id> --hiring-project-id <id> --reason <r>\n curviate recruiter jobs\n curviate recruiter job create [flags\u2026]\n curviate recruiter job publish <job_id> [--mode <m>]\n curviate recruiter job checkpoint <job_id> --input <v>\n curviate recruiter job applicants <job_id>\n curviate recruiter applicant <applicant_id>\n curviate recruiter applicant resume <applicant_id> -o <file>\n'
962
+ );
963
+ }
964
+ });
965
+ export {
966
+ recruiterCommand,
967
+ runRecruiterAddApplicant,
968
+ runRecruiterAddCandidate,
969
+ runRecruiterCreateJob,
970
+ runRecruiterDownloadResume,
971
+ runRecruiterGetApplicant,
972
+ runRecruiterGetParameters,
973
+ runRecruiterGetProject,
974
+ runRecruiterJobCheckpoint,
975
+ runRecruiterListApplicants,
976
+ runRecruiterListJobs,
977
+ runRecruiterListProjects,
978
+ runRecruiterMessageNew,
979
+ runRecruiterProfile,
980
+ runRecruiterPublishJob,
981
+ runRecruiterRejectApplicant,
982
+ runRecruiterSearchPeople,
983
+ runRecruiterSync
984
+ };