@curviate/cli 0.14.0 → 0.15.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.
- package/CHANGELOG.md +104 -0
- package/README.md +52 -79
- package/dist/{account-7AUDAMIK.js → account-VB52GIUA.js} +34 -369
- package/dist/{chunk-SSPILTKF.js → chunk-45KHSWCV.js} +56 -48
- package/dist/chunk-BGZW6B7G.js +59 -0
- package/dist/{chunk-GXTZION6.js → chunk-DNTRQZBT.js} +13 -1
- package/dist/chunk-QJZ3LWOX.js +24 -0
- package/dist/{chunk-HMAGEMF7.js → chunk-ZE7QGR3F.js} +4 -0
- package/dist/cli.js +75 -12
- package/dist/comment-Y5IU42CR.js +550 -0
- package/dist/{company-RU2CA5DY.js → company-LGID3SK3.js} +21 -72
- package/dist/{connect-QT6ZOS75.js → connect-A7HEKKEE.js} +86 -43
- package/dist/{exit-codes-ZTY2NY3X.js → exit-codes-SL3GQF7W.js} +1 -1
- package/dist/{inbox-DN7X7CM2.js → inbox-44JRTJAP.js} +50 -122
- package/dist/job-TFTTCP5B.js +561 -0
- package/dist/{message-6K5E3CUF.js → message-FOJTDPW3.js} +47 -47
- package/dist/{post-2JQZ3OSF.js → post-FC6NZXM5.js} +177 -219
- package/dist/profile-I6YMVXSS.js +799 -0
- package/dist/{recruiter-XHVMQWK6.js → recruiter-BHT5OJD7.js} +731 -224
- package/dist/{sales-nav-QTSTJMKA.js → sales-nav-6IYKQ4TC.js} +109 -75
- package/dist/{search-ZGTS45BT.js → search-6C72M563.js} +95 -37
- package/dist/{webhook-EIY5WWTE.js → webhook-NSXEIU44.js} +4 -43
- package/package.json +4 -3
- package/dist/chunk-Q43HZUN3.js +0 -29
- package/dist/job-FGGQEXSU.js +0 -105
- package/dist/profile-DD5GMGNL.js +0 -501
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
BinaryOutputError,
|
|
4
|
-
writeBinaryOutput
|
|
5
|
-
} from "./chunk-UWO2D4HW.js";
|
|
6
2
|
import {
|
|
7
3
|
DEFAULT_FILTER_READERS,
|
|
8
4
|
assembleFilters,
|
|
@@ -10,21 +6,26 @@ import {
|
|
|
10
6
|
} from "./chunk-42VUUKQ3.js";
|
|
11
7
|
import {
|
|
12
8
|
AttachError,
|
|
13
|
-
readAttachment
|
|
14
|
-
|
|
9
|
+
readAttachment,
|
|
10
|
+
toAttachmentPayload
|
|
11
|
+
} from "./chunk-BGZW6B7G.js";
|
|
12
|
+
import {
|
|
13
|
+
BinaryOutputError,
|
|
14
|
+
writeBinaryOutput
|
|
15
|
+
} from "./chunk-UWO2D4HW.js";
|
|
15
16
|
import {
|
|
16
17
|
buildPreviewOutput
|
|
17
18
|
} from "./chunk-R3VLWLVV.js";
|
|
18
|
-
import {
|
|
19
|
-
streamAll
|
|
20
|
-
} from "./chunk-GXTZION6.js";
|
|
21
19
|
import {
|
|
22
20
|
slimJob
|
|
23
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-45KHSWCV.js";
|
|
24
22
|
import {
|
|
25
23
|
resolveIdentifier,
|
|
26
24
|
resolveJobIdentifier
|
|
27
25
|
} from "./chunk-DMQZEPQE.js";
|
|
26
|
+
import {
|
|
27
|
+
streamAll
|
|
28
|
+
} from "./chunk-DNTRQZBT.js";
|
|
28
29
|
import {
|
|
29
30
|
createClient,
|
|
30
31
|
renderError,
|
|
@@ -35,7 +36,8 @@ import {
|
|
|
35
36
|
import {
|
|
36
37
|
GLOBAL_FLAGS,
|
|
37
38
|
READ_SINGLE_FLAGS,
|
|
38
|
-
WRITE_FLAGS
|
|
39
|
+
WRITE_FLAGS,
|
|
40
|
+
WRITE_SINGLE_FLAGS
|
|
39
41
|
} from "./chunk-4JHGVY7R.js";
|
|
40
42
|
|
|
41
43
|
// src/commands/recruiter.ts
|
|
@@ -75,13 +77,18 @@ function normalizeAttachPaths(attach) {
|
|
|
75
77
|
async function handleSdkError(err, outOpts, out) {
|
|
76
78
|
const { CurviateError } = await import("@curviate/sdk");
|
|
77
79
|
if (err instanceof CurviateError) {
|
|
78
|
-
const { getExitCode } = await import("./exit-codes-
|
|
80
|
+
const { getExitCode } = await import("./exit-codes-SL3GQF7W.js");
|
|
79
81
|
renderError(err, outOpts, out);
|
|
80
82
|
process.exit(getExitCode(err.code));
|
|
81
83
|
}
|
|
82
84
|
renderUnexpectedError(err, out);
|
|
83
85
|
process.exit(1);
|
|
84
86
|
}
|
|
87
|
+
function buildRecruiterRef(idValue, nameValue) {
|
|
88
|
+
if (idValue) return { id: idValue };
|
|
89
|
+
if (nameValue) return { name: nameValue };
|
|
90
|
+
return void 0;
|
|
91
|
+
}
|
|
85
92
|
async function readStdin() {
|
|
86
93
|
const chunks = [];
|
|
87
94
|
for await (const chunk of process.stdin) {
|
|
@@ -93,7 +100,7 @@ var DEFAULT_JOB_CREATE_READERS = {
|
|
|
93
100
|
readFile: (path) => readFile(path, "utf8"),
|
|
94
101
|
readStdin
|
|
95
102
|
};
|
|
96
|
-
async function
|
|
103
|
+
async function assembleRecruiterJobBody(flags, readers) {
|
|
97
104
|
let base = {};
|
|
98
105
|
let raw;
|
|
99
106
|
let source;
|
|
@@ -122,33 +129,72 @@ async function assembleJobCreateBody(flags, readers) {
|
|
|
122
129
|
}
|
|
123
130
|
base = parsed;
|
|
124
131
|
}
|
|
125
|
-
if (flags["job-title"] !== void 0
|
|
132
|
+
if (flags["job-title-id"] !== void 0 || flags["job-title"] !== void 0) {
|
|
133
|
+
base["job_title"] = {
|
|
134
|
+
...flags["job-title-id"] !== void 0 ? { id: flags["job-title-id"] } : {},
|
|
135
|
+
...flags["job-title"] !== void 0 ? { name: flags["job-title"] } : {}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
const company = buildRecruiterRef(flags["company-id"], flags["company-name"]);
|
|
139
|
+
if (company) base["company"] = company;
|
|
140
|
+
if (flags["workplace-type"] !== void 0) base["workplace_type"] = flags["workplace-type"];
|
|
141
|
+
if (flags.location !== void 0) base["location"] = flags.location;
|
|
142
|
+
if (flags["employment-status"] !== void 0) base["employment_status"] = flags["employment-status"];
|
|
143
|
+
if (flags["seniority-level"] !== void 0) base["seniority_level"] = flags["seniority-level"];
|
|
126
144
|
if (flags.description !== void 0) base["description"] = flags.description;
|
|
127
|
-
if (flags
|
|
145
|
+
if (flags.industry !== void 0) base["industry"] = splitCsv(flags.industry);
|
|
146
|
+
if (flags["job-function"] !== void 0) base["job_function"] = splitCsv(flags["job-function"]);
|
|
147
|
+
if (flags["apply-method"] !== void 0) {
|
|
148
|
+
const method = flags["apply-method"];
|
|
149
|
+
base["apply_method"] = {
|
|
150
|
+
method,
|
|
151
|
+
...method === "linkedin" && flags["notification-email"] !== void 0 ? { notification_email: flags["notification-email"] } : {},
|
|
152
|
+
...method === "external" && flags["website-url"] !== void 0 ? { website_url: flags["website-url"] } : {}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
if (flags["project-name"] !== void 0) base["project_name"] = flags["project-name"];
|
|
128
156
|
return { body: base };
|
|
129
157
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
158
|
+
var RECRUITER_JOB_REQUIRED_FIELDS = [
|
|
159
|
+
["job_title", "--job-title-id (paired with --job-title)"],
|
|
160
|
+
["company", "--company-id or --company-name"],
|
|
161
|
+
["workplace_type", "--workplace-type"],
|
|
162
|
+
["location", "--location"],
|
|
163
|
+
["employment_status", "--employment-status"],
|
|
164
|
+
["seniority_level", "--seniority-level"],
|
|
165
|
+
["description", "--description"],
|
|
166
|
+
["industry", "--industry"],
|
|
167
|
+
["job_function", "--job-function"],
|
|
168
|
+
["apply_method", "--apply-method"]
|
|
169
|
+
];
|
|
170
|
+
function requireRecruiterJobFields(body, extra, out) {
|
|
171
|
+
for (const [key, flagDesc] of [...RECRUITER_JOB_REQUIRED_FIELDS, ...extra]) {
|
|
172
|
+
const value = body[key];
|
|
173
|
+
const missing = value === void 0 || value === null || Array.isArray(value) && value.length === 0;
|
|
174
|
+
if (missing) {
|
|
175
|
+
out.stderr.write(`error: ${flagDesc} is required (or ${key} in --body-file/--body -).
|
|
176
|
+
`);
|
|
177
|
+
process.exit(2);
|
|
178
|
+
}
|
|
143
179
|
}
|
|
144
180
|
}
|
|
145
181
|
async function runRecruiterMessageNew(client, flags, out) {
|
|
146
182
|
const accountId = requireAccount(flags.account, out);
|
|
147
183
|
const to = flags.to ?? "";
|
|
148
184
|
const text = flags.text ?? "";
|
|
185
|
+
const subject = flags.subject ?? "";
|
|
186
|
+
const signature = flags.signature ?? "";
|
|
149
187
|
const attachPaths = normalizeAttachPaths(flags.attach);
|
|
150
188
|
const voicePath = flags.voice;
|
|
151
189
|
const videoPath = flags.video;
|
|
190
|
+
if (!subject) {
|
|
191
|
+
out.stderr.write("error: --subject is required (v2: REQUIRED for Recruiter messaging).\n");
|
|
192
|
+
process.exit(2);
|
|
193
|
+
}
|
|
194
|
+
if (!signature) {
|
|
195
|
+
out.stderr.write("error: --signature is required (v2: REQUIRED for Recruiter messaging).\n");
|
|
196
|
+
process.exit(2);
|
|
197
|
+
}
|
|
152
198
|
let attachBuffers = [];
|
|
153
199
|
let voiceBuffer;
|
|
154
200
|
let videoBuffer;
|
|
@@ -164,15 +210,11 @@ async function runRecruiterMessageNew(client, flags, out) {
|
|
|
164
210
|
}
|
|
165
211
|
throw err;
|
|
166
212
|
}
|
|
167
|
-
const body = {
|
|
168
|
-
attendees_ids: [to],
|
|
169
|
-
text
|
|
170
|
-
};
|
|
171
213
|
if (flags.preview) {
|
|
172
214
|
const preview = buildPreviewOutput({
|
|
173
215
|
method: "recruiter.startChat",
|
|
174
216
|
args: { attendees_ids: [to] },
|
|
175
|
-
body: {
|
|
217
|
+
body: { attendees_ids: [to], text, subject, signature },
|
|
176
218
|
account: accountId,
|
|
177
219
|
attachments: [
|
|
178
220
|
...attachBuffers.map((buf, i) => ({
|
|
@@ -186,9 +228,18 @@ async function runRecruiterMessageNew(client, flags, out) {
|
|
|
186
228
|
out.stdout.write(JSON.stringify(preview) + "\n");
|
|
187
229
|
return;
|
|
188
230
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
231
|
+
const attachments = [
|
|
232
|
+
...attachPaths.map((p, i) => toAttachmentPayload(p, attachBuffers[i])),
|
|
233
|
+
...voiceBuffer && voicePath ? [{ ...toAttachmentPayload(voicePath, voiceBuffer), send_mode: "native" }] : [],
|
|
234
|
+
...videoBuffer && videoPath ? [{ ...toAttachmentPayload(videoPath, videoBuffer), send_mode: "native" }] : []
|
|
235
|
+
];
|
|
236
|
+
const body = {
|
|
237
|
+
attendees_ids: [to],
|
|
238
|
+
text,
|
|
239
|
+
subject,
|
|
240
|
+
signature,
|
|
241
|
+
...attachments.length > 0 ? { attachments } : {}
|
|
242
|
+
};
|
|
192
243
|
const ns = client.account(accountId);
|
|
193
244
|
const outOpts = resolveOutputOpts(flags);
|
|
194
245
|
try {
|
|
@@ -249,8 +300,7 @@ async function runRecruiterSearchPeople(client, flags, out, readers = DEFAULT_FI
|
|
|
249
300
|
};
|
|
250
301
|
for await (const item of streamAll(fn, params, {
|
|
251
302
|
maxPages,
|
|
252
|
-
|
|
253
|
-
`)
|
|
303
|
+
out
|
|
254
304
|
})) {
|
|
255
305
|
out.stdout.write(JSON.stringify(item) + "\n");
|
|
256
306
|
}
|
|
@@ -262,22 +312,73 @@ async function runRecruiterSearchPeople(client, flags, out, readers = DEFAULT_FI
|
|
|
262
312
|
await handleSdkError(err, outOpts, out);
|
|
263
313
|
}
|
|
264
314
|
}
|
|
265
|
-
async function
|
|
315
|
+
async function runRecruiterSearchParameters(client, flags, out) {
|
|
266
316
|
rejectPreviewOnRead(flags.preview, out);
|
|
317
|
+
if (!flags.source) {
|
|
318
|
+
out.stderr.write("error: --source is required (APPLICANTS, PIPELINE, SEARCH, JOB_POSTING, or JOBS).\n");
|
|
319
|
+
process.exit(2);
|
|
320
|
+
}
|
|
321
|
+
if (!flags.type) {
|
|
322
|
+
out.stderr.write("error: --type is required.\n");
|
|
323
|
+
process.exit(2);
|
|
324
|
+
}
|
|
267
325
|
const accountId = requireAccount(flags.account, out);
|
|
268
326
|
const ns = client.account(accountId);
|
|
269
327
|
const outOpts = resolveOutputOpts(flags);
|
|
328
|
+
const body = {
|
|
329
|
+
source: flags.source,
|
|
330
|
+
type: flags.type,
|
|
331
|
+
...flags.keywords ? { keywords: flags.keywords } : {},
|
|
332
|
+
...flags["project-id"] ? { project_id: flags["project-id"] } : {},
|
|
333
|
+
...flags["stage-id"] ? { stage_id: flags["stage-id"] } : {}
|
|
334
|
+
};
|
|
270
335
|
const params = {};
|
|
271
|
-
if (flags.type) params["type"] = flags.type;
|
|
272
|
-
if (flags.keywords) params["keywords"] = flags.keywords;
|
|
273
336
|
if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
|
|
274
337
|
try {
|
|
275
|
-
const result = await ns.recruiter.
|
|
338
|
+
const result = await ns.recruiter.searchParameters(body, Object.keys(params).length > 0 ? params : void 0);
|
|
276
339
|
renderSuccess(result, outOpts, out);
|
|
277
340
|
} catch (err) {
|
|
278
341
|
await handleSdkError(err, outOpts, out);
|
|
279
342
|
}
|
|
280
343
|
}
|
|
344
|
+
async function runRecruiterSearchFromUrl(client, flags, out) {
|
|
345
|
+
rejectPreviewOnRead(flags.preview, out);
|
|
346
|
+
const accountId = requireAccount(flags.account, out);
|
|
347
|
+
const url = flags.url ?? "";
|
|
348
|
+
const ns = client.account(accountId);
|
|
349
|
+
const outOpts = resolveOutputOpts(flags);
|
|
350
|
+
const all = flags.all ?? false;
|
|
351
|
+
const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
|
|
352
|
+
const limit = flags.limit ? parseInt(flags.limit, 10) : void 0;
|
|
353
|
+
const cursor = flags.cursor;
|
|
354
|
+
const body = { url };
|
|
355
|
+
const params = {};
|
|
356
|
+
if (limit !== void 0) params["limit"] = limit;
|
|
357
|
+
if (cursor) params["cursor"] = cursor;
|
|
358
|
+
try {
|
|
359
|
+
if (all) {
|
|
360
|
+
const fn = (p) => {
|
|
361
|
+
const { cursor: c, limit: l, ...restP } = p;
|
|
362
|
+
const callParams = {};
|
|
363
|
+
if (c) callParams["cursor"] = c;
|
|
364
|
+
if (l) callParams["limit"] = l;
|
|
365
|
+
void restP;
|
|
366
|
+
return ns.recruiter.searchFromUrl(body, callParams);
|
|
367
|
+
};
|
|
368
|
+
for await (const item of streamAll(fn, params, {
|
|
369
|
+
maxPages,
|
|
370
|
+
out
|
|
371
|
+
})) {
|
|
372
|
+
out.stdout.write(JSON.stringify(item) + "\n");
|
|
373
|
+
}
|
|
374
|
+
} else {
|
|
375
|
+
const result = await ns.recruiter.searchFromUrl(body, Object.keys(params).length > 0 ? params : void 0);
|
|
376
|
+
renderSuccess(result, outOpts, out);
|
|
377
|
+
}
|
|
378
|
+
} catch (err) {
|
|
379
|
+
await handleSdkError(err, outOpts, out);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
281
382
|
async function runRecruiterListProjects(client, flags, out) {
|
|
282
383
|
rejectPreviewOnRead(flags.preview, out);
|
|
283
384
|
const accountId = requireAccount(flags.account, out);
|
|
@@ -295,8 +396,7 @@ async function runRecruiterListProjects(client, flags, out) {
|
|
|
295
396
|
const fn = (p) => ns.recruiter.listProjects(p);
|
|
296
397
|
for await (const item of streamAll(fn, params, {
|
|
297
398
|
maxPages,
|
|
298
|
-
|
|
299
|
-
`)
|
|
399
|
+
out
|
|
300
400
|
})) {
|
|
301
401
|
out.stdout.write(JSON.stringify(item) + "\n");
|
|
302
402
|
}
|
|
@@ -321,17 +421,28 @@ async function runRecruiterGetProject(client, flags, out) {
|
|
|
321
421
|
await handleSdkError(err, outOpts, out);
|
|
322
422
|
}
|
|
323
423
|
}
|
|
324
|
-
async function
|
|
424
|
+
async function runRecruiterUpdateProject(client, flags, out) {
|
|
325
425
|
const accountId = requireAccount(flags.account, out);
|
|
326
|
-
const
|
|
426
|
+
const projectId = flags.projectId ?? "";
|
|
327
427
|
const outOpts = resolveOutputOpts(flags);
|
|
328
428
|
const body = {};
|
|
329
|
-
if (flags
|
|
330
|
-
if (flags.
|
|
429
|
+
if (flags.name !== void 0) body["name"] = flags.name;
|
|
430
|
+
if (flags.visibility !== void 0) body["visibility"] = flags.visibility;
|
|
431
|
+
if (flags.description !== void 0) body["description"] = flags.description;
|
|
432
|
+
const company = buildRecruiterRef(flags["company-id"], flags["company-name"]);
|
|
433
|
+
if (company) body["company"] = company;
|
|
434
|
+
if (flags["job-title-id"] !== void 0 || flags["job-title"] !== void 0) {
|
|
435
|
+
body["job_title"] = {
|
|
436
|
+
...flags["job-title-id"] !== void 0 ? { id: flags["job-title-id"] } : {},
|
|
437
|
+
...flags["job-title"] !== void 0 ? { name: flags["job-title"] } : {}
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
if (flags.location !== void 0) body["location"] = flags.location;
|
|
441
|
+
if (flags["seniority-level"] !== void 0) body["seniority_level"] = flags["seniority-level"];
|
|
331
442
|
if (flags.preview) {
|
|
332
443
|
const preview = buildPreviewOutput({
|
|
333
|
-
method: "recruiter.
|
|
334
|
-
args: {
|
|
444
|
+
method: "recruiter.updateProject",
|
|
445
|
+
args: { project_id: projectId },
|
|
335
446
|
body,
|
|
336
447
|
account: accountId
|
|
337
448
|
});
|
|
@@ -340,67 +451,97 @@ async function runRecruiterAddCandidate(client, flags, out) {
|
|
|
340
451
|
}
|
|
341
452
|
const ns = client.account(accountId);
|
|
342
453
|
try {
|
|
343
|
-
const result = await ns.recruiter.
|
|
454
|
+
const result = await ns.recruiter.updateProject(projectId, body);
|
|
344
455
|
renderSuccess(result, outOpts, out);
|
|
345
456
|
} catch (err) {
|
|
346
457
|
await handleSdkError(err, outOpts, out);
|
|
347
458
|
}
|
|
348
459
|
}
|
|
349
|
-
async function
|
|
460
|
+
async function runRecruiterListPipeline(client, flags, out) {
|
|
461
|
+
rejectPreviewOnRead(flags.preview, out);
|
|
350
462
|
const accountId = requireAccount(flags.account, out);
|
|
351
|
-
const
|
|
463
|
+
const projectId = flags.projectId ?? "";
|
|
464
|
+
const ns = client.account(accountId);
|
|
352
465
|
const outOpts = resolveOutputOpts(flags);
|
|
466
|
+
const all = flags.all ?? false;
|
|
467
|
+
const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
|
|
468
|
+
const limit = flags.limit ? parseInt(flags.limit, 10) : void 0;
|
|
469
|
+
const cursor = flags.cursor;
|
|
353
470
|
const body = {};
|
|
354
|
-
if (flags
|
|
355
|
-
if (flags
|
|
356
|
-
if (flags
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
471
|
+
if (flags.keywords) body["keywords"] = flags.keywords;
|
|
472
|
+
if (flags["stage-id"]) body["stage_id"] = flags["stage-id"];
|
|
473
|
+
if (flags["sort-by"]) body["sort_by"] = flags["sort-by"];
|
|
474
|
+
if (flags.spotlights) body["spotlights"] = splitCsv(flags.spotlights);
|
|
475
|
+
const params = {};
|
|
476
|
+
if (limit !== void 0) params["limit"] = limit;
|
|
477
|
+
if (cursor) params["cursor"] = cursor;
|
|
478
|
+
try {
|
|
479
|
+
if (all) {
|
|
480
|
+
const fn = (p) => {
|
|
481
|
+
const { cursor: c, limit: l, ...restP } = p;
|
|
482
|
+
const callParams = {};
|
|
483
|
+
if (c) callParams["cursor"] = c;
|
|
484
|
+
if (l) callParams["limit"] = l;
|
|
485
|
+
void restP;
|
|
486
|
+
return ns.recruiter.listPipeline(projectId, body, callParams);
|
|
487
|
+
};
|
|
488
|
+
for await (const item of streamAll(fn, params, {
|
|
489
|
+
maxPages,
|
|
490
|
+
out
|
|
491
|
+
})) {
|
|
492
|
+
out.stdout.write(JSON.stringify(item) + "\n");
|
|
493
|
+
}
|
|
494
|
+
} else {
|
|
495
|
+
const result = await ns.recruiter.listPipeline(
|
|
496
|
+
projectId,
|
|
497
|
+
Object.keys(body).length > 0 ? body : void 0,
|
|
498
|
+
Object.keys(params).length > 0 ? params : void 0
|
|
499
|
+
);
|
|
500
|
+
renderSuccess(result, outOpts, out);
|
|
501
|
+
}
|
|
502
|
+
} catch (err) {
|
|
503
|
+
await handleSdkError(err, outOpts, out);
|
|
365
504
|
}
|
|
505
|
+
}
|
|
506
|
+
async function runRecruiterGetProjectJob(client, flags, out) {
|
|
507
|
+
rejectPreviewOnRead(flags.preview, out);
|
|
508
|
+
const accountId = requireAccount(flags.account, out);
|
|
509
|
+
const projectId = flags.projectId ?? "";
|
|
366
510
|
const ns = client.account(accountId);
|
|
511
|
+
const outOpts = resolveOutputOpts(flags);
|
|
367
512
|
try {
|
|
368
|
-
const result = await ns.recruiter.
|
|
513
|
+
const result = await ns.recruiter.getProjectJob(projectId);
|
|
369
514
|
renderSuccess(result, outOpts, out);
|
|
370
515
|
} catch (err) {
|
|
371
516
|
await handleSdkError(err, outOpts, out);
|
|
372
517
|
}
|
|
373
518
|
}
|
|
374
|
-
async function
|
|
519
|
+
async function runRecruiterGetProjectJobBudget(client, flags, out) {
|
|
520
|
+
rejectPreviewOnRead(flags.preview, out);
|
|
375
521
|
const accountId = requireAccount(flags.account, out);
|
|
376
|
-
const
|
|
522
|
+
const projectId = flags.projectId ?? "";
|
|
523
|
+
const jobId = flags.jobId ?? "";
|
|
524
|
+
const ns = client.account(accountId);
|
|
377
525
|
const outOpts = resolveOutputOpts(flags);
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
}
|
|
384
|
-
let notifyAt;
|
|
385
|
-
if (flags["notify-at"]) {
|
|
386
|
-
notifyAt = Number(flags["notify-at"]);
|
|
387
|
-
if (!Number.isFinite(notifyAt)) {
|
|
388
|
-
out.stderr.write("error: --notify-at must be a UNIX milliseconds timestamp (a number).\n");
|
|
389
|
-
process.exit(2);
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
const body = {};
|
|
393
|
-
if (flags["hiring-project-id"]) body["hiring_project_id"] = flags["hiring-project-id"];
|
|
394
|
-
if (flags.reason) body["reason"] = flags.reason;
|
|
395
|
-
if (flags.message) {
|
|
396
|
-
const rejectionNotification = { message: flags.message };
|
|
397
|
-
if (notifyAt !== void 0) rejectionNotification["send_notification_at"] = notifyAt;
|
|
398
|
-
body["rejection_notification"] = rejectionNotification;
|
|
526
|
+
try {
|
|
527
|
+
const result = await ns.recruiter.getProjectJobBudget(projectId, jobId);
|
|
528
|
+
renderSuccess(result, outOpts, out);
|
|
529
|
+
} catch (err) {
|
|
530
|
+
await handleSdkError(err, outOpts, out);
|
|
399
531
|
}
|
|
532
|
+
}
|
|
533
|
+
async function runRecruiterSaveCandidate(client, flags, out) {
|
|
534
|
+
const accountId = requireAccount(flags.account, out);
|
|
535
|
+
const projectId = flags.projectId ?? "";
|
|
536
|
+
const outOpts = resolveOutputOpts(flags);
|
|
537
|
+
const body = {
|
|
538
|
+
stage_id: flags["stage-id"] ?? "",
|
|
539
|
+
candidate_id: flags["candidate-id"] ?? ""
|
|
540
|
+
};
|
|
400
541
|
if (flags.preview) {
|
|
401
542
|
const preview = buildPreviewOutput({
|
|
402
|
-
method: "recruiter.
|
|
403
|
-
args: {
|
|
543
|
+
method: "recruiter.saveCandidate",
|
|
544
|
+
args: { project_id: projectId },
|
|
404
545
|
body,
|
|
405
546
|
account: accountId
|
|
406
547
|
});
|
|
@@ -409,7 +550,7 @@ async function runRecruiterRejectApplicant(client, flags, out) {
|
|
|
409
550
|
}
|
|
410
551
|
const ns = client.account(accountId);
|
|
411
552
|
try {
|
|
412
|
-
const result = await ns.recruiter.
|
|
553
|
+
const result = await ns.recruiter.saveCandidate(projectId, body);
|
|
413
554
|
renderSuccess(result, outOpts, out);
|
|
414
555
|
} catch (err) {
|
|
415
556
|
await handleSdkError(err, outOpts, out);
|
|
@@ -432,8 +573,7 @@ async function runRecruiterListJobs(client, flags, out) {
|
|
|
432
573
|
const fn = (p) => ns.recruiter.listJobs(p);
|
|
433
574
|
for await (const item of streamAll(fn, params, {
|
|
434
575
|
maxPages,
|
|
435
|
-
|
|
436
|
-
`)
|
|
576
|
+
out
|
|
437
577
|
})) {
|
|
438
578
|
out.stdout.write(JSON.stringify(item) + "\n");
|
|
439
579
|
}
|
|
@@ -448,13 +588,14 @@ async function runRecruiterListJobs(client, flags, out) {
|
|
|
448
588
|
async function runRecruiterCreateJob(client, flags, out, readers = DEFAULT_JOB_CREATE_READERS) {
|
|
449
589
|
const accountId = requireAccount(flags.account, out);
|
|
450
590
|
const outOpts = resolveOutputOpts(flags);
|
|
451
|
-
const assembled = await
|
|
591
|
+
const assembled = await assembleRecruiterJobBody(flags, readers);
|
|
452
592
|
if ("error" in assembled) {
|
|
453
593
|
out.stderr.write(`error: ${assembled.error}
|
|
454
594
|
`);
|
|
455
595
|
process.exit(2);
|
|
456
596
|
}
|
|
457
597
|
const body = assembled.body;
|
|
598
|
+
requireRecruiterJobFields(body, [["project_name", "--project-name"]], out);
|
|
458
599
|
if (flags.preview) {
|
|
459
600
|
const preview = buildPreviewOutput({
|
|
460
601
|
method: "recruiter.createJob",
|
|
@@ -473,16 +614,52 @@ async function runRecruiterCreateJob(client, flags, out, readers = DEFAULT_JOB_C
|
|
|
473
614
|
await handleSdkError(err, outOpts, out);
|
|
474
615
|
}
|
|
475
616
|
}
|
|
476
|
-
async function
|
|
617
|
+
async function runRecruiterCreateProjectJob(client, flags, out, readers = DEFAULT_JOB_CREATE_READERS) {
|
|
618
|
+
const accountId = requireAccount(flags.account, out);
|
|
619
|
+
const projectId = flags.projectId ?? "";
|
|
620
|
+
const outOpts = resolveOutputOpts(flags);
|
|
621
|
+
const assembled = await assembleRecruiterJobBody(flags, readers);
|
|
622
|
+
if ("error" in assembled) {
|
|
623
|
+
out.stderr.write(`error: ${assembled.error}
|
|
624
|
+
`);
|
|
625
|
+
process.exit(2);
|
|
626
|
+
}
|
|
627
|
+
const body = assembled.body;
|
|
628
|
+
requireRecruiterJobFields(body, [], out);
|
|
629
|
+
if (flags.preview) {
|
|
630
|
+
const preview = buildPreviewOutput({
|
|
631
|
+
method: "recruiter.createProjectJob",
|
|
632
|
+
args: { project_id: projectId },
|
|
633
|
+
body,
|
|
634
|
+
account: accountId
|
|
635
|
+
});
|
|
636
|
+
out.stdout.write(JSON.stringify(preview) + "\n");
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
const ns = client.account(accountId);
|
|
640
|
+
try {
|
|
641
|
+
const result = await ns.recruiter.createProjectJob(projectId, body);
|
|
642
|
+
renderSuccess(result, outOpts, out);
|
|
643
|
+
} catch (err) {
|
|
644
|
+
await handleSdkError(err, outOpts, out);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
async function runRecruiterUpdateProjectJob(client, flags, out, readers = DEFAULT_JOB_CREATE_READERS) {
|
|
477
648
|
const accountId = requireAccount(flags.account, out);
|
|
649
|
+
const projectId = flags.projectId ?? "";
|
|
478
650
|
const jobId = flags.jobId ?? "";
|
|
479
651
|
const outOpts = resolveOutputOpts(flags);
|
|
480
|
-
const
|
|
481
|
-
if (
|
|
652
|
+
const assembled = await assembleRecruiterJobBody(flags, readers);
|
|
653
|
+
if ("error" in assembled) {
|
|
654
|
+
out.stderr.write(`error: ${assembled.error}
|
|
655
|
+
`);
|
|
656
|
+
process.exit(2);
|
|
657
|
+
}
|
|
658
|
+
const body = assembled.body;
|
|
482
659
|
if (flags.preview) {
|
|
483
660
|
const preview = buildPreviewOutput({
|
|
484
|
-
method: "recruiter.
|
|
485
|
-
args: { job_id: jobId },
|
|
661
|
+
method: "recruiter.updateProjectJob",
|
|
662
|
+
args: { project_id: projectId, job_id: jobId },
|
|
486
663
|
body,
|
|
487
664
|
account: accountId
|
|
488
665
|
});
|
|
@@ -491,22 +668,59 @@ async function runRecruiterPublishJob(client, flags, out) {
|
|
|
491
668
|
}
|
|
492
669
|
const ns = client.account(accountId);
|
|
493
670
|
try {
|
|
494
|
-
const result = await ns.recruiter.
|
|
671
|
+
const result = await ns.recruiter.updateProjectJob(projectId, jobId, body);
|
|
495
672
|
renderSuccess(result, outOpts, out);
|
|
496
673
|
} catch (err) {
|
|
497
674
|
await handleSdkError(err, outOpts, out);
|
|
498
675
|
}
|
|
499
676
|
}
|
|
500
|
-
|
|
677
|
+
var RECRUITER_PUBLISH_MODES = ["FREE", "PROMOTED", "PROMOTED_PLUS"];
|
|
678
|
+
var RECRUITER_BUDGET_SCOPES = ["DAILY", "TOTAL"];
|
|
679
|
+
async function runRecruiterPublishJob(client, flags, out) {
|
|
501
680
|
const accountId = requireAccount(flags.account, out);
|
|
681
|
+
const projectId = flags.projectId ?? "";
|
|
502
682
|
const jobId = flags.jobId ?? "";
|
|
503
683
|
const outOpts = resolveOutputOpts(flags);
|
|
504
|
-
|
|
505
|
-
|
|
684
|
+
if (!flags.mode) {
|
|
685
|
+
out.stderr.write("error: --mode is required (FREE, PROMOTED, or PROMOTED_PLUS).\n");
|
|
686
|
+
process.exit(2);
|
|
687
|
+
}
|
|
688
|
+
if (!RECRUITER_PUBLISH_MODES.includes(flags.mode)) {
|
|
689
|
+
out.stderr.write(`error: --mode must be one of: ${RECRUITER_PUBLISH_MODES.join(", ")}. Got "${flags.mode}".
|
|
690
|
+
`);
|
|
691
|
+
process.exit(2);
|
|
692
|
+
}
|
|
693
|
+
const mode = flags.mode;
|
|
694
|
+
let body = { mode };
|
|
695
|
+
if (mode === "PROMOTED" || mode === "PROMOTED_PLUS") {
|
|
696
|
+
if (!flags["budget-currency"]) {
|
|
697
|
+
out.stderr.write("error: --budget-currency is required for a paid publish (PROMOTED/PROMOTED_PLUS).\n");
|
|
698
|
+
process.exit(2);
|
|
699
|
+
}
|
|
700
|
+
if (!flags["budget-amount"]) {
|
|
701
|
+
out.stderr.write("error: --budget-amount is required for a paid publish (PROMOTED/PROMOTED_PLUS).\n");
|
|
702
|
+
process.exit(2);
|
|
703
|
+
}
|
|
704
|
+
if (!flags["budget-scope"]) {
|
|
705
|
+
out.stderr.write("error: --budget-scope is required for a paid publish (PROMOTED/PROMOTED_PLUS).\n");
|
|
706
|
+
process.exit(2);
|
|
707
|
+
}
|
|
708
|
+
if (!RECRUITER_BUDGET_SCOPES.includes(flags["budget-scope"])) {
|
|
709
|
+
out.stderr.write(`error: --budget-scope must be one of: ${RECRUITER_BUDGET_SCOPES.join(", ")}. Got "${flags["budget-scope"]}".
|
|
710
|
+
`);
|
|
711
|
+
process.exit(2);
|
|
712
|
+
}
|
|
713
|
+
const amount = Number(flags["budget-amount"]);
|
|
714
|
+
if (!Number.isFinite(amount) || amount < 0) {
|
|
715
|
+
out.stderr.write("error: --budget-amount must be a non-negative number.\n");
|
|
716
|
+
process.exit(2);
|
|
717
|
+
}
|
|
718
|
+
body = { mode, budget: { currency: flags["budget-currency"], amount, scope: flags["budget-scope"] } };
|
|
719
|
+
}
|
|
506
720
|
if (flags.preview) {
|
|
507
721
|
const preview = buildPreviewOutput({
|
|
508
|
-
method: "recruiter.
|
|
509
|
-
args: { job_id: jobId },
|
|
722
|
+
method: "recruiter.publishJob",
|
|
723
|
+
args: { project_id: projectId, job_id: jobId },
|
|
510
724
|
body,
|
|
511
725
|
account: accountId
|
|
512
726
|
});
|
|
@@ -515,23 +729,101 @@ async function runRecruiterJobCheckpoint(client, flags, out) {
|
|
|
515
729
|
}
|
|
516
730
|
const ns = client.account(accountId);
|
|
517
731
|
try {
|
|
518
|
-
const result = await ns.recruiter.
|
|
732
|
+
const result = await ns.recruiter.publishJob(projectId, jobId, body);
|
|
519
733
|
renderSuccess(result, outOpts, out);
|
|
520
734
|
} catch (err) {
|
|
521
735
|
await handleSdkError(err, outOpts, out);
|
|
522
736
|
}
|
|
523
737
|
}
|
|
738
|
+
async function runRecruiterCloseJob(client, flags, out) {
|
|
739
|
+
const accountId = requireAccount(flags.account, out);
|
|
740
|
+
const projectId = flags.projectId ?? "";
|
|
741
|
+
const jobId = flags.jobId ?? "";
|
|
742
|
+
if (flags.preview) {
|
|
743
|
+
const preview = buildPreviewOutput({
|
|
744
|
+
method: "recruiter.closeJob",
|
|
745
|
+
args: { project_id: projectId, job_id: jobId },
|
|
746
|
+
body: {},
|
|
747
|
+
account: accountId
|
|
748
|
+
});
|
|
749
|
+
out.stdout.write(JSON.stringify(preview) + "\n");
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
const ns = client.account(accountId);
|
|
753
|
+
const outOpts = resolveOutputOpts(flags);
|
|
754
|
+
try {
|
|
755
|
+
const result = await ns.recruiter.closeJob(projectId, jobId);
|
|
756
|
+
renderSuccess(result, outOpts, out);
|
|
757
|
+
} catch (err) {
|
|
758
|
+
await handleSdkError(err, outOpts, out);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
async function runRecruiterSearchTalentPool(client, flags, out, readers = DEFAULT_FILTER_READERS) {
|
|
762
|
+
rejectPreviewOnRead(flags.preview, out);
|
|
763
|
+
if (!flags["channel-id"]) {
|
|
764
|
+
out.stderr.write("error: --channel-id is required.\n");
|
|
765
|
+
process.exit(2);
|
|
766
|
+
}
|
|
767
|
+
const accountId = requireAccount(flags.account, out);
|
|
768
|
+
const projectId = flags.projectId ?? "";
|
|
769
|
+
const ns = client.account(accountId);
|
|
770
|
+
const outOpts = resolveOutputOpts(flags);
|
|
771
|
+
const all = flags.all ?? false;
|
|
772
|
+
const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
|
|
773
|
+
const limit = flags.limit ? parseInt(flags.limit, 10) : void 0;
|
|
774
|
+
const cursor = flags.cursor;
|
|
775
|
+
const assembled = await assembleFilters(flags, readers);
|
|
776
|
+
if ("error" in assembled) {
|
|
777
|
+
out.stderr.write(`error: ${assembled.error}
|
|
778
|
+
`);
|
|
779
|
+
process.exit(2);
|
|
780
|
+
}
|
|
781
|
+
const body = assembled.body;
|
|
782
|
+
body["channel_id"] = flags["channel-id"];
|
|
783
|
+
if (flags.keywords) body["keywords"] = flags.keywords;
|
|
784
|
+
const params = {};
|
|
785
|
+
if (limit !== void 0) params["limit"] = limit;
|
|
786
|
+
if (cursor) params["cursor"] = cursor;
|
|
787
|
+
try {
|
|
788
|
+
if (all) {
|
|
789
|
+
const fn = (p) => {
|
|
790
|
+
const { cursor: c, limit: l, ...restP } = p;
|
|
791
|
+
const callParams = {};
|
|
792
|
+
if (c) callParams["cursor"] = c;
|
|
793
|
+
if (l) callParams["limit"] = l;
|
|
794
|
+
void restP;
|
|
795
|
+
return ns.recruiter.searchTalentPool(projectId, body, callParams);
|
|
796
|
+
};
|
|
797
|
+
for await (const item of streamAll(fn, params, {
|
|
798
|
+
maxPages,
|
|
799
|
+
out
|
|
800
|
+
})) {
|
|
801
|
+
out.stdout.write(JSON.stringify(item) + "\n");
|
|
802
|
+
}
|
|
803
|
+
} else {
|
|
804
|
+
const result = await ns.recruiter.searchTalentPool(projectId, body, Object.keys(params).length > 0 ? params : void 0);
|
|
805
|
+
renderSuccess(result, outOpts, out);
|
|
806
|
+
}
|
|
807
|
+
} catch (err) {
|
|
808
|
+
await handleSdkError(err, outOpts, out);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
524
811
|
async function runRecruiterListApplicants(client, flags, out) {
|
|
525
812
|
rejectPreviewOnRead(flags.preview, out);
|
|
813
|
+
if (!flags["channel-id"]) {
|
|
814
|
+
out.stderr.write("error: --channel-id is required.\n");
|
|
815
|
+
process.exit(2);
|
|
816
|
+
}
|
|
526
817
|
const accountId = requireAccount(flags.account, out);
|
|
527
|
-
const
|
|
818
|
+
const projectId = flags.projectId ?? "";
|
|
528
819
|
const ns = client.account(accountId);
|
|
529
820
|
const outOpts = resolveOutputOpts(flags);
|
|
821
|
+
const body = { channel_id: flags["channel-id"] };
|
|
530
822
|
const params = {};
|
|
531
823
|
if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
|
|
532
824
|
if (flags.cursor) params["cursor"] = flags.cursor;
|
|
533
825
|
try {
|
|
534
|
-
const result = await ns.recruiter.listApplicants(
|
|
826
|
+
const result = await ns.recruiter.listApplicants(projectId, body, Object.keys(params).length > 0 ? params : void 0);
|
|
535
827
|
renderSuccess(result, outOpts, out);
|
|
536
828
|
} catch (err) {
|
|
537
829
|
await handleSdkError(err, outOpts, out);
|
|
@@ -554,11 +846,12 @@ async function runRecruiterGetJob(client, flags, out) {
|
|
|
554
846
|
async function runRecruiterGetApplicant(client, flags, out) {
|
|
555
847
|
rejectPreviewOnRead(flags.preview, out);
|
|
556
848
|
const accountId = requireAccount(flags.account, out);
|
|
849
|
+
const projectId = flags.projectId ?? "";
|
|
557
850
|
const applicantId = flags.applicantId ?? "";
|
|
558
851
|
const ns = client.account(accountId);
|
|
559
852
|
const outOpts = resolveOutputOpts(flags);
|
|
560
853
|
try {
|
|
561
|
-
const result = await ns.recruiter.getApplicant(applicantId);
|
|
854
|
+
const result = await ns.recruiter.getApplicant(projectId, applicantId);
|
|
562
855
|
renderSuccess(result, outOpts, out);
|
|
563
856
|
} catch (err) {
|
|
564
857
|
await handleSdkError(err, outOpts, out);
|
|
@@ -567,10 +860,11 @@ async function runRecruiterGetApplicant(client, flags, out) {
|
|
|
567
860
|
async function runRecruiterDownloadResume(client, flags, out, isTTY) {
|
|
568
861
|
rejectPreviewOnRead(flags.preview, out);
|
|
569
862
|
const accountId = requireAccount(flags.account, out);
|
|
863
|
+
const projectId = flags.projectId ?? "";
|
|
570
864
|
const applicantId = flags.applicantId ?? "";
|
|
571
865
|
const ns = client.account(accountId);
|
|
572
866
|
try {
|
|
573
|
-
const data = await ns.recruiter.downloadResume(applicantId);
|
|
867
|
+
const data = await ns.recruiter.downloadResume(projectId, applicantId);
|
|
574
868
|
await writeBinaryOutput(data, {
|
|
575
869
|
outputPath: flags.output,
|
|
576
870
|
isTTY,
|
|
@@ -586,27 +880,6 @@ async function runRecruiterDownloadResume(client, flags, out, isTTY) {
|
|
|
586
880
|
await handleSdkError(err, outOpts, out);
|
|
587
881
|
}
|
|
588
882
|
}
|
|
589
|
-
var recruiterSyncCommand = defineCommand({
|
|
590
|
-
meta: { name: "sync", description: "Sync Recruiter message history for an account." },
|
|
591
|
-
args: { ...GLOBAL_FLAGS },
|
|
592
|
-
async run({ args }) {
|
|
593
|
-
const flags = args;
|
|
594
|
-
const cfg = await resolveEffectiveConfig({
|
|
595
|
-
apiKey: flags["api-key"],
|
|
596
|
-
baseUrl: flags["base-url"],
|
|
597
|
-
timeout: flags.timeout,
|
|
598
|
-
account: flags.account,
|
|
599
|
-
profile: flags.profile
|
|
600
|
-
});
|
|
601
|
-
if (!cfg.apiKey) {
|
|
602
|
-
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
603
|
-
process.exit(3);
|
|
604
|
-
}
|
|
605
|
-
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
606
|
-
const out = buildOutputStreams();
|
|
607
|
-
await runRecruiterSync(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
608
|
-
}
|
|
609
|
-
});
|
|
610
883
|
var recruiterMessageNewCommand = defineCommand({
|
|
611
884
|
meta: { name: "new", description: "Start a new Recruiter chat with a member." },
|
|
612
885
|
args: {
|
|
@@ -617,6 +890,8 @@ var recruiterMessageNewCommand = defineCommand({
|
|
|
617
890
|
description: "Recipient's LinkedIn provider ID (AE\u2026 format, e.g. from a Recruiter search result or profile). Not resolved from a URL/slug \u2014 pass the provider ID directly.",
|
|
618
891
|
required: true
|
|
619
892
|
},
|
|
893
|
+
subject: { type: "string", description: "Message subject line (required for Recruiter InMail).", required: true },
|
|
894
|
+
signature: { type: "string", description: "Sender signature (required for Recruiter InMail).", required: true },
|
|
620
895
|
text: { type: "positional", description: "Opening message text." },
|
|
621
896
|
attach: { type: "string", description: "File to attach (repeatable, max 7 MiB each)." },
|
|
622
897
|
voice: { type: "string", description: "Voice message file (max 7 MiB)." },
|
|
@@ -706,15 +981,22 @@ var recruiterSearchPeopleCommand = defineCommand({
|
|
|
706
981
|
}
|
|
707
982
|
});
|
|
708
983
|
var recruiterSearchParametersCommand = defineCommand({
|
|
709
|
-
meta: { name: "parameters", description: "Resolve Recruiter filter parameter IDs." },
|
|
984
|
+
meta: { name: "parameters", description: "Resolve Recruiter filter parameter IDs (POST \u2014 source-scoped)." },
|
|
710
985
|
args: {
|
|
711
986
|
...GLOBAL_FLAGS,
|
|
987
|
+
source: {
|
|
988
|
+
type: "string",
|
|
989
|
+
description: "Filter family to resolve within: APPLICANTS or PIPELINE (both require --project-id), SEARCH, JOB_POSTING, or JOBS.",
|
|
990
|
+
required: true
|
|
991
|
+
},
|
|
712
992
|
type: {
|
|
713
993
|
type: "string",
|
|
714
|
-
description: "Parameter type to resolve
|
|
994
|
+
description: "Parameter type to resolve; the valid set depends on --source (e.g. SKILL/LOCATION/JOB_TITLE for APPLICANTS, CONTRACT/SEAT/LOCATION for JOBS).",
|
|
715
995
|
required: true
|
|
716
996
|
},
|
|
717
|
-
keywords: { type: "string", description: "Human term to resolve (e.g. Berlin)." }
|
|
997
|
+
keywords: { type: "string", description: "Human term to resolve (e.g. Berlin)." },
|
|
998
|
+
"project-id": { type: "string", description: "Recruiter project ID (required for --source APPLICANTS or PIPELINE)." },
|
|
999
|
+
"stage-id": { type: "string", description: "Pipeline stage ID to filter to (only meaningful for --source PIPELINE)." }
|
|
718
1000
|
},
|
|
719
1001
|
async run({ args }) {
|
|
720
1002
|
const flags = args;
|
|
@@ -731,20 +1013,45 @@ var recruiterSearchParametersCommand = defineCommand({
|
|
|
731
1013
|
}
|
|
732
1014
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
733
1015
|
const out = buildOutputStreams();
|
|
734
|
-
await
|
|
1016
|
+
await runRecruiterSearchParameters(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
735
1017
|
}
|
|
736
1018
|
});
|
|
737
1019
|
var recruiterSearchCommand = defineCommand({
|
|
738
|
-
meta: { name: "search", description: "Recruiter search operations." },
|
|
739
|
-
args: {
|
|
1020
|
+
meta: { name: "search", description: "Recruiter search operations. Also runs a pasted Recruiter search/talent-pool/applicant URL directly." },
|
|
1021
|
+
args: {
|
|
1022
|
+
...GLOBAL_FLAGS,
|
|
1023
|
+
url: {
|
|
1024
|
+
type: "positional",
|
|
1025
|
+
required: false,
|
|
1026
|
+
description: "A pasted Recruiter search, talent-pool, or applicant URL. Runs it directly (recruiter.searchFromUrl)."
|
|
1027
|
+
}
|
|
1028
|
+
},
|
|
740
1029
|
subCommands: {
|
|
741
1030
|
people: recruiterSearchPeopleCommand,
|
|
742
1031
|
parameters: recruiterSearchParametersCommand
|
|
743
1032
|
},
|
|
744
|
-
async run() {
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
1033
|
+
async run({ args }) {
|
|
1034
|
+
const flags = args;
|
|
1035
|
+
if (!flags.url) {
|
|
1036
|
+
process.stderr.write(
|
|
1037
|
+
"Usage: curviate recruiter search <url>\n curviate recruiter search people [--keywords <k>]\n curviate recruiter search parameters --source <s> --type <t>\n"
|
|
1038
|
+
);
|
|
1039
|
+
return;
|
|
1040
|
+
}
|
|
1041
|
+
const cfg = await resolveEffectiveConfig({
|
|
1042
|
+
apiKey: flags["api-key"],
|
|
1043
|
+
baseUrl: flags["base-url"],
|
|
1044
|
+
timeout: flags.timeout,
|
|
1045
|
+
account: flags.account,
|
|
1046
|
+
profile: flags.profile
|
|
1047
|
+
});
|
|
1048
|
+
if (!cfg.apiKey) {
|
|
1049
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
1050
|
+
process.exit(3);
|
|
1051
|
+
}
|
|
1052
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
1053
|
+
const out = buildOutputStreams();
|
|
1054
|
+
await runRecruiterSearchFromUrl(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
748
1055
|
}
|
|
749
1056
|
});
|
|
750
1057
|
var recruiterProjectsCommand = defineCommand({
|
|
@@ -768,12 +1075,21 @@ var recruiterProjectsCommand = defineCommand({
|
|
|
768
1075
|
await runRecruiterListProjects(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
769
1076
|
}
|
|
770
1077
|
});
|
|
771
|
-
var
|
|
772
|
-
meta: { name: "
|
|
1078
|
+
var recruiterProjectUpdateCommand = defineCommand({
|
|
1079
|
+
meta: { name: "update", description: "Edit a Recruiter project's config. All fields optional \u2014 omitted fields are left unchanged." },
|
|
773
1080
|
args: {
|
|
774
|
-
//
|
|
775
|
-
...
|
|
776
|
-
projectId: { type: "positional", description: "Recruiter project ID." }
|
|
1081
|
+
// Write command: WRITE_SINGLE_FLAGS omits pagination flags, keeps --fields
|
|
1082
|
+
...WRITE_SINGLE_FLAGS,
|
|
1083
|
+
projectId: { type: "positional", description: "Recruiter project ID." },
|
|
1084
|
+
name: { type: "string", description: "New project name." },
|
|
1085
|
+
visibility: { type: "string", description: "New project visibility: PRIVATE or PUBLIC." },
|
|
1086
|
+
description: { type: "string", description: "New project description." },
|
|
1087
|
+
"company-id": { type: "string", description: "Target company id." },
|
|
1088
|
+
"company-name": { type: "string", description: "Target company as free text (used when no id is given)." },
|
|
1089
|
+
"job-title-id": { type: "string", description: "Target job-title parameter id." },
|
|
1090
|
+
"job-title": { type: "string", description: "Target job-title display name." },
|
|
1091
|
+
location: { type: "string", description: "A LOCATION parameter id (resolve via search parameters)." },
|
|
1092
|
+
"seniority-level": { type: "string", description: "Target seniority level: INTERNSHIP|ENTRY_LEVEL|ASSOCIATE|MID_SENIOR_LEVEL|DIRECTOR|EXECUTIVE|NOT_APPLICABLE." }
|
|
777
1093
|
},
|
|
778
1094
|
async run({ args }) {
|
|
779
1095
|
const flags = args;
|
|
@@ -790,20 +1106,27 @@ var recruiterProjectCommand = defineCommand({
|
|
|
790
1106
|
}
|
|
791
1107
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
792
1108
|
const out = buildOutputStreams();
|
|
793
|
-
await
|
|
1109
|
+
await runRecruiterUpdateProject(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
794
1110
|
}
|
|
795
1111
|
});
|
|
796
|
-
var
|
|
797
|
-
meta: { name: "
|
|
1112
|
+
var recruiterProjectCommand = defineCommand({
|
|
1113
|
+
meta: { name: "project", description: "Get a Recruiter hiring project by ID." },
|
|
798
1114
|
args: {
|
|
799
|
-
//
|
|
800
|
-
...
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
1115
|
+
// Single-object read: READ_SINGLE_FLAGS omits pagination flags, keeps --fields
|
|
1116
|
+
...READ_SINGLE_FLAGS,
|
|
1117
|
+
projectId: { type: "positional", description: "Recruiter project ID." }
|
|
1118
|
+
},
|
|
1119
|
+
subCommands: {
|
|
1120
|
+
update: recruiterProjectUpdateCommand
|
|
804
1121
|
},
|
|
805
1122
|
async run({ args }) {
|
|
806
1123
|
const flags = args;
|
|
1124
|
+
if (!flags.projectId) {
|
|
1125
|
+
process.stderr.write(
|
|
1126
|
+
"Usage: curviate recruiter project <project_id>\n curviate recruiter project update <project_id> [flags\u2026]\n"
|
|
1127
|
+
);
|
|
1128
|
+
return;
|
|
1129
|
+
}
|
|
807
1130
|
const cfg = await resolveEffectiveConfig({
|
|
808
1131
|
apiKey: flags["api-key"],
|
|
809
1132
|
baseUrl: flags["base-url"],
|
|
@@ -817,17 +1140,18 @@ var recruiterAddCandidateCommand = defineCommand({
|
|
|
817
1140
|
}
|
|
818
1141
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
819
1142
|
const out = buildOutputStreams();
|
|
820
|
-
await
|
|
1143
|
+
await runRecruiterGetProject(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
821
1144
|
}
|
|
822
1145
|
});
|
|
823
|
-
var
|
|
824
|
-
meta: { name: "
|
|
1146
|
+
var recruiterPipelineCommand = defineCommand({
|
|
1147
|
+
meta: { name: "pipeline", description: "List candidates in a project's pipeline (POST-as-list)." },
|
|
825
1148
|
args: {
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
"
|
|
830
|
-
|
|
1149
|
+
...GLOBAL_FLAGS,
|
|
1150
|
+
projectId: { type: "positional", description: "Recruiter project ID." },
|
|
1151
|
+
keywords: { type: "string", description: "Free-text keyword search." },
|
|
1152
|
+
"stage-id": { type: "string", description: "Filter to a single pipeline stage id." },
|
|
1153
|
+
"sort-by": { type: "string", description: "Sort field: LAST_MODIFIED or ALPHABETICAL." },
|
|
1154
|
+
spotlights: { type: "string", description: "Spotlight tags (comma-separated): OPEN_TO_WORK, ACTIVE_TALENT, MISSED_CANDIDATES." }
|
|
831
1155
|
},
|
|
832
1156
|
async run({ args }) {
|
|
833
1157
|
const flags = args;
|
|
@@ -844,29 +1168,17 @@ var recruiterAddApplicantCommand = defineCommand({
|
|
|
844
1168
|
}
|
|
845
1169
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
846
1170
|
const out = buildOutputStreams();
|
|
847
|
-
await
|
|
1171
|
+
await runRecruiterListPipeline(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
848
1172
|
}
|
|
849
1173
|
});
|
|
850
|
-
var
|
|
851
|
-
meta: { name: "
|
|
1174
|
+
var recruiterSaveCandidateCommand = defineCommand({
|
|
1175
|
+
meta: { name: "save-candidate", description: "Save a candidate to a project's pipeline at a given stage." },
|
|
852
1176
|
args: {
|
|
853
1177
|
// Write command: WRITE_FLAGS omits pagination/projection flags
|
|
854
1178
|
...WRITE_FLAGS,
|
|
855
|
-
|
|
856
|
-
"
|
|
857
|
-
|
|
858
|
-
type: "string",
|
|
859
|
-
description: "Rejection reason (NOT_MEET_BASIC_QUALIFICATIONS, NOT_IN_DESIRED_LOCATION, MORE_QUALIFIED_CANDIDATES, WITHDREW_APPLICATION, NOT_CONSIDERED_OR_REASON_NOT_SPECIFIED).",
|
|
860
|
-
required: true
|
|
861
|
-
},
|
|
862
|
-
message: {
|
|
863
|
-
type: "string",
|
|
864
|
-
description: "Rejection notification text. The applicant is only notified when --message is provided; omit it to reject silently."
|
|
865
|
-
},
|
|
866
|
-
"notify-at": {
|
|
867
|
-
type: "string",
|
|
868
|
-
description: "UNIX milliseconds timestamp to schedule the notification (default: now). Requires --message."
|
|
869
|
-
}
|
|
1179
|
+
projectId: { type: "positional", description: "Recruiter project ID." },
|
|
1180
|
+
"stage-id": { type: "string", description: "Pipeline stage ID to save the candidate into.", required: true },
|
|
1181
|
+
"candidate-id": { type: "string", description: "Candidate id or user-profile id to save.", required: true }
|
|
870
1182
|
},
|
|
871
1183
|
async run({ args }) {
|
|
872
1184
|
const flags = args;
|
|
@@ -883,7 +1195,7 @@ var recruiterRejectApplicantCommand = defineCommand({
|
|
|
883
1195
|
}
|
|
884
1196
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
885
1197
|
const out = buildOutputStreams();
|
|
886
|
-
await
|
|
1198
|
+
await runRecruiterSaveCandidate(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
887
1199
|
}
|
|
888
1200
|
});
|
|
889
1201
|
var recruiterJobsCommand = defineCommand({
|
|
@@ -907,16 +1219,31 @@ var recruiterJobsCommand = defineCommand({
|
|
|
907
1219
|
await runRecruiterListJobs(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
908
1220
|
}
|
|
909
1221
|
});
|
|
1222
|
+
var RECRUITER_JOB_BODY_FLAGS = {
|
|
1223
|
+
"body-file": { type: "string", description: "Path to a JSON file with the full job body." },
|
|
1224
|
+
body: { type: "string", description: "Read the JSON job body from stdin (pass '-')." },
|
|
1225
|
+
"job-title-id": { type: "string", description: "Resolved job-title parameter id (merged with --job-title into job_title:{id,name})." },
|
|
1226
|
+
"job-title": { type: "string", description: "Job title display name (merged with --job-title-id into job_title:{id,name})." },
|
|
1227
|
+
"company-id": { type: "string", description: "Resolved company id (or use --company-name for free text)." },
|
|
1228
|
+
"company-name": { type: "string", description: "Company as free text (used when no resolved id is available)." },
|
|
1229
|
+
"workplace-type": { type: "string", description: "Workplace arrangement: ON_SITE|HYBRID|REMOTE." },
|
|
1230
|
+
location: { type: "string", description: "A resolved LOCATION parameter id." },
|
|
1231
|
+
"employment-status": { type: "string", description: "Employment type: FULL_TIME|PART_TIME|CONTRACT|TEMPORARY|OTHER|VOLUNTEER|INTERNSHIP." },
|
|
1232
|
+
"seniority-level": { type: "string", description: "Seniority level: INTERNSHIP|ENTRY_LEVEL|ASSOCIATE|MID_SENIOR_LEVEL|DIRECTOR|EXECUTIVE|NOT_APPLICABLE." },
|
|
1233
|
+
description: { type: "string", description: "Full job description (min 200 chars; merged over the JSON)." },
|
|
1234
|
+
industry: { type: "string", description: "Industry parameter ids, 1-3 (comma-separated)." },
|
|
1235
|
+
"job-function": { type: "string", description: "Job-function parameter ids, 1-3 (comma-separated)." },
|
|
1236
|
+
"apply-method": { type: "string", description: "How candidates apply: linkedin|external." },
|
|
1237
|
+
"notification-email": { type: "string", description: "Email notified of new applicants (used when --apply-method is linkedin)." },
|
|
1238
|
+
"website-url": { type: "string", description: "External apply URL (used when --apply-method is external)." }
|
|
1239
|
+
};
|
|
910
1240
|
var recruiterJobCreateCommand = defineCommand({
|
|
911
|
-
meta: { name: "create", description: "Create a Recruiter job posting draft." },
|
|
1241
|
+
meta: { name: "create", description: "Create a Recruiter job posting draft, opening a brand-new hiring project." },
|
|
912
1242
|
args: {
|
|
913
1243
|
// Write command: WRITE_FLAGS omits pagination/projection flags
|
|
914
1244
|
...WRITE_FLAGS,
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
"job-title": { type: "string", description: "Job title text (merged over the JSON as job_title.text)." },
|
|
918
|
-
description: { type: "string", description: "Job description (merged over the JSON)." },
|
|
919
|
-
"employment-type": { type: "string", description: "Employment type, e.g. FULL_TIME (merged over the JSON)." }
|
|
1245
|
+
...RECRUITER_JOB_BODY_FLAGS,
|
|
1246
|
+
"project-name": { type: "string", description: "Name for the new hiring project this job opens (required).", required: true }
|
|
920
1247
|
},
|
|
921
1248
|
async run({ args }) {
|
|
922
1249
|
const flags = args;
|
|
@@ -937,12 +1264,16 @@ var recruiterJobCreateCommand = defineCommand({
|
|
|
937
1264
|
}
|
|
938
1265
|
});
|
|
939
1266
|
var recruiterJobPublishCommand = defineCommand({
|
|
940
|
-
meta: { name: "publish", description: "Publish a Recruiter job posting draft." },
|
|
1267
|
+
meta: { name: "publish", description: "Publish a Recruiter job posting draft. PROMOTED/PROMOTED_PLUS spend real money and require --budget-*." },
|
|
941
1268
|
args: {
|
|
942
|
-
// Write command:
|
|
943
|
-
...
|
|
1269
|
+
// Write command: WRITE_SINGLE_FLAGS omits pagination flags, keeps --fields
|
|
1270
|
+
...WRITE_SINGLE_FLAGS,
|
|
1271
|
+
projectId: { type: "positional", description: "Recruiter project ID." },
|
|
944
1272
|
jobId: { type: "positional", description: "Job posting ID." },
|
|
945
|
-
mode: { type: "string", description: "Publish mode
|
|
1273
|
+
mode: { type: "string", description: "Publish mode (required): FREE|PROMOTED|PROMOTED_PLUS.", required: true },
|
|
1274
|
+
"budget-currency": { type: "string", description: "ISO-4217 currency (required for a paid publish), e.g. EUR." },
|
|
1275
|
+
"budget-amount": { type: "string", description: "Budget amount (required for a paid publish)." },
|
|
1276
|
+
"budget-scope": { type: "string", description: "Budget scope (required for a paid publish): DAILY|TOTAL." }
|
|
946
1277
|
},
|
|
947
1278
|
async run({ args }) {
|
|
948
1279
|
const flags = args;
|
|
@@ -962,13 +1293,12 @@ var recruiterJobPublishCommand = defineCommand({
|
|
|
962
1293
|
await runRecruiterPublishJob(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
963
1294
|
}
|
|
964
1295
|
});
|
|
965
|
-
var
|
|
966
|
-
meta: { name: "
|
|
1296
|
+
var recruiterApplicantsCommand = defineCommand({
|
|
1297
|
+
meta: { name: "applicants", description: "List applicants in a Recruiter project's talent pool." },
|
|
967
1298
|
args: {
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
input: { type: "string", description: "Verification value (OTP or email confirmation).", required: true }
|
|
1299
|
+
...GLOBAL_FLAGS,
|
|
1300
|
+
projectId: { type: "positional", description: "Recruiter project ID." },
|
|
1301
|
+
"channel-id": { type: "string", description: "The project's JOB_POSTING talent-pool channel ID (required).", required: true }
|
|
972
1302
|
},
|
|
973
1303
|
async run({ args }) {
|
|
974
1304
|
const flags = args;
|
|
@@ -985,14 +1315,14 @@ var recruiterJobCheckpointCommand = defineCommand({
|
|
|
985
1315
|
}
|
|
986
1316
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
987
1317
|
const out = buildOutputStreams();
|
|
988
|
-
await
|
|
1318
|
+
await runRecruiterListApplicants(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
989
1319
|
}
|
|
990
1320
|
});
|
|
991
|
-
var
|
|
992
|
-
meta: { name: "
|
|
1321
|
+
var recruiterJobGetCommand = defineCommand({
|
|
1322
|
+
meta: { name: "get", description: "Get a job posting via the Recruiter lens (any public posting, not only your own)." },
|
|
993
1323
|
args: {
|
|
994
|
-
...
|
|
995
|
-
jobId: { type: "positional", description: "Job
|
|
1324
|
+
...READ_SINGLE_FLAGS,
|
|
1325
|
+
jobId: { type: "positional", description: "Job URL (e.g. https://www.linkedin.com/jobs/view/4428113858) or a bare numeric job id." }
|
|
996
1326
|
},
|
|
997
1327
|
async run({ args }) {
|
|
998
1328
|
const flags = args;
|
|
@@ -1009,14 +1339,16 @@ var recruiterJobApplicantsCommand = defineCommand({
|
|
|
1009
1339
|
}
|
|
1010
1340
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
1011
1341
|
const out = buildOutputStreams();
|
|
1012
|
-
await
|
|
1342
|
+
await runRecruiterGetJob(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
1013
1343
|
}
|
|
1014
1344
|
});
|
|
1015
|
-
var
|
|
1016
|
-
meta: { name: "
|
|
1345
|
+
var recruiterJobCloseCommand = defineCommand({
|
|
1346
|
+
meta: { name: "close", description: "Stop a project's job posting from accepting applications (irreversible once LISTED)." },
|
|
1017
1347
|
args: {
|
|
1018
|
-
|
|
1019
|
-
|
|
1348
|
+
// Write command: WRITE_SINGLE_FLAGS omits pagination flags, keeps --fields
|
|
1349
|
+
...WRITE_SINGLE_FLAGS,
|
|
1350
|
+
projectId: { type: "positional", description: "Recruiter project ID." },
|
|
1351
|
+
jobId: { type: "positional", description: "Job posting ID." }
|
|
1020
1352
|
},
|
|
1021
1353
|
async run({ args }) {
|
|
1022
1354
|
const flags = args;
|
|
@@ -1033,7 +1365,7 @@ var recruiterJobGetCommand = defineCommand({
|
|
|
1033
1365
|
}
|
|
1034
1366
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
1035
1367
|
const out = buildOutputStreams();
|
|
1036
|
-
await
|
|
1368
|
+
await runRecruiterCloseJob(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
1037
1369
|
}
|
|
1038
1370
|
});
|
|
1039
1371
|
var recruiterJobCommand = defineCommand({
|
|
@@ -1042,21 +1374,189 @@ var recruiterJobCommand = defineCommand({
|
|
|
1042
1374
|
subCommands: {
|
|
1043
1375
|
create: recruiterJobCreateCommand,
|
|
1044
1376
|
publish: recruiterJobPublishCommand,
|
|
1045
|
-
|
|
1046
|
-
applicants: recruiterJobApplicantsCommand,
|
|
1377
|
+
close: recruiterJobCloseCommand,
|
|
1047
1378
|
get: recruiterJobGetCommand
|
|
1048
1379
|
},
|
|
1049
1380
|
async run() {
|
|
1050
1381
|
process.stderr.write(
|
|
1051
|
-
"Usage: curviate recruiter job create [flags\u2026]\n curviate recruiter job publish <job_id>
|
|
1382
|
+
"Usage: curviate recruiter job create [flags\u2026]\n curviate recruiter job publish <project_id> <job_id> --mode <FREE|PROMOTED|PROMOTED_PLUS>\n curviate recruiter job close <project_id> <job_id>\n curviate recruiter job get <url|id>\n"
|
|
1052
1383
|
);
|
|
1053
1384
|
}
|
|
1054
1385
|
});
|
|
1386
|
+
var recruiterProjectJobGetCommand = defineCommand({
|
|
1387
|
+
meta: { name: "get", description: "Get the single job posting attached to a project (404 when none is attached)." },
|
|
1388
|
+
args: {
|
|
1389
|
+
// Single-object read: READ_SINGLE_FLAGS omits pagination flags, keeps --fields
|
|
1390
|
+
...READ_SINGLE_FLAGS,
|
|
1391
|
+
projectId: { type: "positional", description: "Recruiter project ID." }
|
|
1392
|
+
},
|
|
1393
|
+
async run({ args }) {
|
|
1394
|
+
const flags = args;
|
|
1395
|
+
const cfg = await resolveEffectiveConfig({
|
|
1396
|
+
apiKey: flags["api-key"],
|
|
1397
|
+
baseUrl: flags["base-url"],
|
|
1398
|
+
timeout: flags.timeout,
|
|
1399
|
+
account: flags.account,
|
|
1400
|
+
profile: flags.profile
|
|
1401
|
+
});
|
|
1402
|
+
if (!cfg.apiKey) {
|
|
1403
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
1404
|
+
process.exit(3);
|
|
1405
|
+
}
|
|
1406
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
1407
|
+
const out = buildOutputStreams();
|
|
1408
|
+
await runRecruiterGetProjectJob(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
1409
|
+
}
|
|
1410
|
+
});
|
|
1411
|
+
var recruiterProjectJobCreateCommand = defineCommand({
|
|
1412
|
+
meta: { name: "create", description: "Create a job-posting draft attached to an existing project." },
|
|
1413
|
+
args: {
|
|
1414
|
+
// Write command: WRITE_SINGLE_FLAGS omits pagination flags, keeps --fields
|
|
1415
|
+
...WRITE_SINGLE_FLAGS,
|
|
1416
|
+
...RECRUITER_JOB_BODY_FLAGS,
|
|
1417
|
+
projectId: { type: "positional", description: "Recruiter project ID." }
|
|
1418
|
+
},
|
|
1419
|
+
async run({ args }) {
|
|
1420
|
+
const flags = args;
|
|
1421
|
+
const cfg = await resolveEffectiveConfig({
|
|
1422
|
+
apiKey: flags["api-key"],
|
|
1423
|
+
baseUrl: flags["base-url"],
|
|
1424
|
+
timeout: flags.timeout,
|
|
1425
|
+
account: flags.account,
|
|
1426
|
+
profile: flags.profile
|
|
1427
|
+
});
|
|
1428
|
+
if (!cfg.apiKey) {
|
|
1429
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
1430
|
+
process.exit(3);
|
|
1431
|
+
}
|
|
1432
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
1433
|
+
const out = buildOutputStreams();
|
|
1434
|
+
await runRecruiterCreateProjectJob(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
1435
|
+
}
|
|
1436
|
+
});
|
|
1437
|
+
var recruiterProjectJobBudgetCommand = defineCommand({
|
|
1438
|
+
meta: { name: "budget", description: "Get pricing to publish a project's job posting." },
|
|
1439
|
+
args: {
|
|
1440
|
+
// Single-object read: READ_SINGLE_FLAGS omits pagination flags, keeps --fields
|
|
1441
|
+
...READ_SINGLE_FLAGS,
|
|
1442
|
+
projectId: { type: "positional", description: "Recruiter project ID." },
|
|
1443
|
+
jobId: { type: "positional", description: "Job posting ID." }
|
|
1444
|
+
},
|
|
1445
|
+
async run({ args }) {
|
|
1446
|
+
const flags = args;
|
|
1447
|
+
const cfg = await resolveEffectiveConfig({
|
|
1448
|
+
apiKey: flags["api-key"],
|
|
1449
|
+
baseUrl: flags["base-url"],
|
|
1450
|
+
timeout: flags.timeout,
|
|
1451
|
+
account: flags.account,
|
|
1452
|
+
profile: flags.profile
|
|
1453
|
+
});
|
|
1454
|
+
if (!cfg.apiKey) {
|
|
1455
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
1456
|
+
process.exit(3);
|
|
1457
|
+
}
|
|
1458
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
1459
|
+
const out = buildOutputStreams();
|
|
1460
|
+
await runRecruiterGetProjectJobBudget(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
1461
|
+
}
|
|
1462
|
+
});
|
|
1463
|
+
var recruiterProjectJobUpdateCommand = defineCommand({
|
|
1464
|
+
meta: { name: "update", description: "Apply a partial update to a project's job posting." },
|
|
1465
|
+
args: {
|
|
1466
|
+
// Write command: WRITE_SINGLE_FLAGS omits pagination flags, keeps --fields
|
|
1467
|
+
...WRITE_SINGLE_FLAGS,
|
|
1468
|
+
...RECRUITER_JOB_BODY_FLAGS,
|
|
1469
|
+
projectId: { type: "positional", description: "Recruiter project ID." },
|
|
1470
|
+
jobId: { type: "positional", description: "Job posting ID." }
|
|
1471
|
+
},
|
|
1472
|
+
async run({ args }) {
|
|
1473
|
+
const flags = args;
|
|
1474
|
+
const cfg = await resolveEffectiveConfig({
|
|
1475
|
+
apiKey: flags["api-key"],
|
|
1476
|
+
baseUrl: flags["base-url"],
|
|
1477
|
+
timeout: flags.timeout,
|
|
1478
|
+
account: flags.account,
|
|
1479
|
+
profile: flags.profile
|
|
1480
|
+
});
|
|
1481
|
+
if (!cfg.apiKey) {
|
|
1482
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
1483
|
+
process.exit(3);
|
|
1484
|
+
}
|
|
1485
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
1486
|
+
const out = buildOutputStreams();
|
|
1487
|
+
await runRecruiterUpdateProjectJob(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
1488
|
+
}
|
|
1489
|
+
});
|
|
1490
|
+
var recruiterProjectJobCommand = defineCommand({
|
|
1491
|
+
meta: { name: "project-job", description: "The single job posting attached to a Recruiter project." },
|
|
1492
|
+
args: {
|
|
1493
|
+
...READ_SINGLE_FLAGS,
|
|
1494
|
+
projectId: { type: "positional", description: "Recruiter project ID.", required: false }
|
|
1495
|
+
},
|
|
1496
|
+
subCommands: {
|
|
1497
|
+
get: recruiterProjectJobGetCommand,
|
|
1498
|
+
create: recruiterProjectJobCreateCommand,
|
|
1499
|
+
budget: recruiterProjectJobBudgetCommand,
|
|
1500
|
+
update: recruiterProjectJobUpdateCommand
|
|
1501
|
+
},
|
|
1502
|
+
async run({ args }) {
|
|
1503
|
+
const flags = args;
|
|
1504
|
+
if (!flags.projectId) {
|
|
1505
|
+
process.stderr.write(
|
|
1506
|
+
"Usage: curviate recruiter project-job get <project_id>\n curviate recruiter project-job create <project_id> [flags\u2026]\n curviate recruiter project-job budget <project_id> <job_id>\n curviate recruiter project-job update <project_id> <job_id> [flags\u2026]\n"
|
|
1507
|
+
);
|
|
1508
|
+
return;
|
|
1509
|
+
}
|
|
1510
|
+
const cfg = await resolveEffectiveConfig({
|
|
1511
|
+
apiKey: flags["api-key"],
|
|
1512
|
+
baseUrl: flags["base-url"],
|
|
1513
|
+
timeout: flags.timeout,
|
|
1514
|
+
account: flags.account,
|
|
1515
|
+
profile: flags.profile
|
|
1516
|
+
});
|
|
1517
|
+
if (!cfg.apiKey) {
|
|
1518
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
1519
|
+
process.exit(3);
|
|
1520
|
+
}
|
|
1521
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
1522
|
+
const out = buildOutputStreams();
|
|
1523
|
+
await runRecruiterGetProjectJob(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
1524
|
+
}
|
|
1525
|
+
});
|
|
1526
|
+
var recruiterTalentSearchCommand = defineCommand({
|
|
1527
|
+
meta: { name: "talent-search", description: "Search a project's talent pool." },
|
|
1528
|
+
args: {
|
|
1529
|
+
...GLOBAL_FLAGS,
|
|
1530
|
+
projectId: { type: "positional", description: "Recruiter project ID." },
|
|
1531
|
+
"channel-id": { type: "string", description: "The project's RECRUITER_SEARCH talent-pool channel ID (required).", required: true },
|
|
1532
|
+
keywords: { type: "string", description: "Free-text keyword search." },
|
|
1533
|
+
filters: { type: "string", description: "Filter body as a JSON object (escape hatch for the full filter surface); '-' reads JSON from stdin." },
|
|
1534
|
+
"filters-file": { type: "string", description: "Path to a JSON file with the filter body." }
|
|
1535
|
+
},
|
|
1536
|
+
async run({ args }) {
|
|
1537
|
+
const flags = args;
|
|
1538
|
+
const cfg = await resolveEffectiveConfig({
|
|
1539
|
+
apiKey: flags["api-key"],
|
|
1540
|
+
baseUrl: flags["base-url"],
|
|
1541
|
+
timeout: flags.timeout,
|
|
1542
|
+
account: flags.account,
|
|
1543
|
+
profile: flags.profile
|
|
1544
|
+
});
|
|
1545
|
+
if (!cfg.apiKey) {
|
|
1546
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
1547
|
+
process.exit(3);
|
|
1548
|
+
}
|
|
1549
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
1550
|
+
const out = buildOutputStreams();
|
|
1551
|
+
await runRecruiterSearchTalentPool(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
1552
|
+
}
|
|
1553
|
+
});
|
|
1055
1554
|
var recruiterApplicantResumeCommand = defineCommand({
|
|
1056
1555
|
meta: { name: "resume", description: "Download a job applicant's resume." },
|
|
1057
1556
|
args: {
|
|
1058
1557
|
// Single-object read: READ_SINGLE_FLAGS omits pagination flags, keeps --fields
|
|
1059
1558
|
...READ_SINGLE_FLAGS,
|
|
1559
|
+
projectId: { type: "positional", description: "Recruiter project ID." },
|
|
1060
1560
|
applicantId: { type: "positional", description: "Applicant ID." },
|
|
1061
1561
|
output: { type: "string", alias: "o", description: "Path to write the resume file." }
|
|
1062
1562
|
},
|
|
@@ -1088,6 +1588,7 @@ var recruiterApplicantCommand = defineCommand({
|
|
|
1088
1588
|
args: {
|
|
1089
1589
|
// Single-object read: READ_SINGLE_FLAGS omits pagination flags, keeps --fields
|
|
1090
1590
|
...READ_SINGLE_FLAGS,
|
|
1591
|
+
projectId: { type: "positional", description: "Recruiter project ID.", required: false },
|
|
1091
1592
|
applicantId: { type: "positional", description: "Applicant ID.", required: false }
|
|
1092
1593
|
},
|
|
1093
1594
|
subCommands: {
|
|
@@ -1095,9 +1596,9 @@ var recruiterApplicantCommand = defineCommand({
|
|
|
1095
1596
|
},
|
|
1096
1597
|
async run({ args }) {
|
|
1097
1598
|
const flags = args;
|
|
1098
|
-
if (!flags.applicantId) {
|
|
1599
|
+
if (!flags.projectId || !flags.applicantId) {
|
|
1099
1600
|
process.stderr.write(
|
|
1100
|
-
"Usage: curviate recruiter applicant <applicant_id>\n curviate recruiter applicant resume <applicant_id> -o <file>\n"
|
|
1601
|
+
"Usage: curviate recruiter applicant <project_id> <applicant_id>\n curviate recruiter applicant resume <project_id> <applicant_id> -o <file>\n"
|
|
1101
1602
|
);
|
|
1102
1603
|
return;
|
|
1103
1604
|
}
|
|
@@ -1121,43 +1622,49 @@ var recruiterCommand = defineCommand({
|
|
|
1121
1622
|
meta: { name: "recruiter", description: "LinkedIn Recruiter operations (requires the Recruiter add-on)." },
|
|
1122
1623
|
args: { ...GLOBAL_FLAGS },
|
|
1123
1624
|
subCommands: {
|
|
1124
|
-
sync: recruiterSyncCommand,
|
|
1125
1625
|
message: recruiterMessageCommand,
|
|
1126
1626
|
profile: recruiterProfileCommand,
|
|
1127
1627
|
search: recruiterSearchCommand,
|
|
1128
1628
|
projects: recruiterProjectsCommand,
|
|
1129
1629
|
project: recruiterProjectCommand,
|
|
1130
|
-
|
|
1131
|
-
"
|
|
1132
|
-
"
|
|
1630
|
+
pipeline: recruiterPipelineCommand,
|
|
1631
|
+
"project-job": recruiterProjectJobCommand,
|
|
1632
|
+
"talent-search": recruiterTalentSearchCommand,
|
|
1633
|
+
"save-candidate": recruiterSaveCandidateCommand,
|
|
1634
|
+
applicants: recruiterApplicantsCommand,
|
|
1133
1635
|
jobs: recruiterJobsCommand,
|
|
1134
1636
|
job: recruiterJobCommand,
|
|
1135
1637
|
applicant: recruiterApplicantCommand
|
|
1136
1638
|
},
|
|
1137
1639
|
async run() {
|
|
1138
1640
|
process.stderr.write(
|
|
1139
|
-
'Usage: curviate recruiter
|
|
1641
|
+
'Usage: curviate recruiter message new --to <id> "<text>"\n curviate recruiter profile <identifier>\n curviate recruiter search people [--keywords <k>]\n curviate recruiter search parameters --source <s> --type <t>\n curviate recruiter search <url>\n curviate recruiter projects\n curviate recruiter project <project_id>\n curviate recruiter project update <project_id> [flags\u2026]\n curviate recruiter pipeline <project_id>\n curviate recruiter project-job get <project_id>\n curviate recruiter project-job create <project_id> [flags\u2026]\n curviate recruiter project-job budget <project_id> <job_id>\n curviate recruiter project-job update <project_id> <job_id> [flags\u2026]\n curviate recruiter talent-search <project_id> --channel-id <id>\n curviate recruiter save-candidate <project_id> --stage-id <id> --candidate-id <id>\n curviate recruiter applicants <project_id> --channel-id <id>\n curviate recruiter jobs\n curviate recruiter job create [flags\u2026]\n curviate recruiter job publish <project_id> <job_id> --mode <FREE|PROMOTED|PROMOTED_PLUS>\n curviate recruiter job close <project_id> <job_id>\n curviate recruiter job get <url|id>\n curviate recruiter applicant <project_id> <applicant_id>\n curviate recruiter applicant resume <project_id> <applicant_id> -o <file>\n'
|
|
1140
1642
|
);
|
|
1141
1643
|
}
|
|
1142
1644
|
});
|
|
1143
1645
|
export {
|
|
1144
1646
|
recruiterCommand,
|
|
1145
|
-
|
|
1146
|
-
runRecruiterAddCandidate,
|
|
1647
|
+
runRecruiterCloseJob,
|
|
1147
1648
|
runRecruiterCreateJob,
|
|
1649
|
+
runRecruiterCreateProjectJob,
|
|
1148
1650
|
runRecruiterDownloadResume,
|
|
1149
1651
|
runRecruiterGetApplicant,
|
|
1150
1652
|
runRecruiterGetJob,
|
|
1151
|
-
runRecruiterGetParameters,
|
|
1152
1653
|
runRecruiterGetProject,
|
|
1153
|
-
|
|
1654
|
+
runRecruiterGetProjectJob,
|
|
1655
|
+
runRecruiterGetProjectJobBudget,
|
|
1154
1656
|
runRecruiterListApplicants,
|
|
1155
1657
|
runRecruiterListJobs,
|
|
1658
|
+
runRecruiterListPipeline,
|
|
1156
1659
|
runRecruiterListProjects,
|
|
1157
1660
|
runRecruiterMessageNew,
|
|
1158
1661
|
runRecruiterProfile,
|
|
1159
1662
|
runRecruiterPublishJob,
|
|
1160
|
-
|
|
1663
|
+
runRecruiterSaveCandidate,
|
|
1664
|
+
runRecruiterSearchFromUrl,
|
|
1665
|
+
runRecruiterSearchParameters,
|
|
1161
1666
|
runRecruiterSearchPeople,
|
|
1162
|
-
|
|
1667
|
+
runRecruiterSearchTalentPool,
|
|
1668
|
+
runRecruiterUpdateProject,
|
|
1669
|
+
runRecruiterUpdateProjectJob
|
|
1163
1670
|
};
|