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