@curviate/cli 0.8.0 → 0.10.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 CHANGED
@@ -8,6 +8,31 @@ a new command or flag is a minor; a breaking command/flag/exit-code change is a
8
8
 
9
9
  ## [Unreleased]
10
10
 
11
+ ## [0.10.0] - 2026-07-03
12
+
13
+ ### Added
14
+
15
+ - `job get <url|id>` — a new top-level `job` command retrieving one public LinkedIn job posting's full detail. Accepts a job URL (`https://www.linkedin.com/jobs/view/<id>`) or a bare numeric id — a job URL is resolved to its numeric id client-side; anything else passes through and the API is the final validator. Slim-default output: `object`, `id`, `title`, `company`, `company_id`, `location`, `state`, `applicants_counter`, `published_at`, `description` — `description` stays in the default output since retrieving it is the point of the command. Pass `--verbose` for the full response (adds `cost`, `created_at`, `hiring_team`). An unknown job id exits with the not-found exit code. This is a read command — `--preview` is a usage error, matching every other single-object read.
16
+ - `recruiter job get <url|id>` — the Recruiter-lens sibling of `job get`, joining the existing `recruiter job` command group. Retrieves any public job posting (not only postings you manage) — unlike `recruiter jobs`, which lists your own. Same URL/id resolution and slim/verbose projection as the top-level command; requires the Recruiter add-on tier (exit `5` without it).
17
+ - README gained a new numbered example chaining `search jobs` into `job get`, and a "Get any public job posting through the Recruiter lens" example in the Recruiter section.
18
+
19
+ ### Changed
20
+
21
+ - `@curviate/sdk` dependency bumped to `^0.10.0`.
22
+ - `recruiter job get --help` does not advertise `--limit`/`--cursor`/`--all`/`--max-pages` — a single-object read, consistent with the other Recruiter single-reads (`profile`, `project`, `applicant`). `--fields` and `--verbose` are unchanged and available.
23
+
24
+ ## [0.9.0] - 2026-07-03
25
+
26
+ ### Added
27
+
28
+ - `account list` and `account get` gain a compact **slim-default** output — pass `--verbose` for the full API response. Slim `account list` items: `account_id`, `status`, `auth_method`, `full_name`, `headline`, `seat_id`, `connected_at`. Slim `account get`: the same seven fields plus `last_checked_at` and `quotas`. Six cached account-detail fields (`username`, `premium_id`, `public_identifier`, `substrate_created_at`, `signatures`, `groups`) are verbose-only on both commands — they are `null`/`[]` on an account that hasn't been enriched yet, never a missing key. `--all` NDJSON streaming on `account list` applies the same slim projection per item unless `--verbose` is passed.
29
+ - `account get` gains `seat_id` in its slim output (previously only `account list` carried it) — the seat the account occupies, `null` for an admin seatless account.
30
+
31
+ ### Changed
32
+
33
+ - `@curviate/sdk` dependency bumped to `^0.9.0`.
34
+ - `account get --help` no longer advertises `--limit`/`--cursor`/`--all`/`--max-pages` — a single-object read, those flags never applied. `--fields` is unchanged and still available. `account list` is unaffected (a genuine list read, keeps all pagination flags).
35
+
11
36
  ## [0.8.0] - 2026-07-02
12
37
 
13
38
  ### Added
package/README.md CHANGED
@@ -158,6 +158,20 @@ curviate account list --all --json \
158
158
  > accounts.csv
159
159
  ```
160
160
 
161
+ ### 7. Search jobs, then fetch full detail on the top result
162
+
163
+ `job get` accepts either a job URL or the bare numeric id — including the `job_urn` field a
164
+ job-search result already returns:
165
+
166
+ ```bash
167
+ curviate search jobs --keywords "founding engineer" --location "Berlin" --account acc_1 --json \
168
+ | jq -r '.items[0].job_urn' \
169
+ | xargs -I{} curviate job get {} --account acc_1 --json
170
+
171
+ # A pasted job URL works identically:
172
+ curviate job get "https://www.linkedin.com/jobs/view/4428113858" --account acc_1
173
+ ```
174
+
161
175
  ## Sales Navigator
162
176
 
163
177
  Sales Navigator commands (`curviate sales-nav ...`) require an account with the Sales Navigator
@@ -327,6 +341,19 @@ curviate recruiter message new \
327
341
  "Hi — I came across your profile and think you'd be a great fit for a role we're hiring for."
328
342
  ```
329
343
 
344
+ ### 10. Get any public job posting through the Recruiter lens
345
+
346
+ Unlike `recruiter jobs` (which lists postings you manage), `recruiter job get` retrieves the full
347
+ detail of *any* public LinkedIn job posting — the Recruiter-seated counterpart to the top-level
348
+ `job get` command:
349
+
350
+ ```bash
351
+ curviate recruiter job get "https://www.linkedin.com/jobs/view/4428113858" --account acc_1 --json
352
+
353
+ # Bare numeric id works identically:
354
+ curviate recruiter job get 4428113858 --account acc_1 --verbose
355
+ ```
356
+
330
357
  ## Exit codes
331
358
 
332
359
  | Code | Meaning |
@@ -1,10 +1,15 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ streamAll
4
+ } from "./chunk-GXTZION6.js";
2
5
  import {
3
6
  buildPreviewOutput
4
7
  } from "./chunk-R3VLWLVV.js";
5
8
  import {
6
- streamAll
7
- } from "./chunk-GXTZION6.js";
9
+ slimAccountGet,
10
+ slimAccountList,
11
+ slimAccountListItem
12
+ } from "./chunk-SSPILTKF.js";
8
13
  import {
9
14
  createClient,
10
15
  renderError,
@@ -13,7 +18,8 @@ import {
13
18
  resolveEffectiveConfig
14
19
  } from "./chunk-47SYFQRF.js";
15
20
  import {
16
- GLOBAL_FLAGS
21
+ GLOBAL_FLAGS,
22
+ READ_SINGLE_FLAGS
17
23
  } from "./chunk-TDYIQHQX.js";
18
24
 
19
25
  // src/commands/account.ts
@@ -40,7 +46,8 @@ function resolveOutputOpts(flags) {
40
46
  return {
41
47
  json: (flags.json ?? false) || !process.stdout.isTTY,
42
48
  isTTY: process.stdout.isTTY ?? false,
43
- fields: flags.fields
49
+ fields: flags.fields,
50
+ verbose: flags.verbose ?? false
44
51
  };
45
52
  }
46
53
  async function handleError(err, outOpts, out) {
@@ -71,11 +78,12 @@ async function runAccountList(client, flags, out) {
71
78
  onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
72
79
  `)
73
80
  })) {
74
- out.stdout.write(JSON.stringify(item) + "\n");
81
+ const projected = outOpts.verbose ? item : slimAccountListItem(item);
82
+ out.stdout.write(JSON.stringify(projected) + "\n");
75
83
  }
76
84
  } else {
77
85
  const result = await client.accounts.list(params);
78
- renderSuccess(result, outOpts, out);
86
+ renderSuccess(result, { ...outOpts, slim: slimAccountList }, out);
79
87
  }
80
88
  } catch (err) {
81
89
  await handleError(err, outOpts, out);
@@ -88,7 +96,7 @@ async function runAccountGet(client, flags, out) {
88
96
  const outOpts = resolveOutputOpts(flags);
89
97
  try {
90
98
  const result = await client.accounts.get(accountId);
91
- renderSuccess(result, outOpts, out);
99
+ renderSuccess(result, { ...outOpts, slim: slimAccountGet }, out);
92
100
  } catch (err) {
93
101
  await handleError(err, outOpts, out);
94
102
  }
@@ -340,7 +348,8 @@ var accountListCommand = defineCommand({
340
348
  var accountGetCommand = defineCommand({
341
349
  meta: { name: "get", description: "Get a connected LinkedIn account." },
342
350
  args: {
343
- ...GLOBAL_FLAGS,
351
+ // Single-object read: READ_SINGLE_FLAGS omits pagination flags, keeps --fields
352
+ ...READ_SINGLE_FLAGS,
344
353
  "account-id": { type: "positional", description: "Account id (acc_\u2026)." }
345
354
  },
346
355
  async run({ args }) {
@@ -33,8 +33,15 @@ function normalizeChatId(raw) {
33
33
  if (match?.[1]) return match[1];
34
34
  return raw;
35
35
  }
36
+ var JOB_URL_RE = /\/jobs\/view\/(\d+)/;
37
+ function resolveJobIdentifier(raw) {
38
+ const match = JOB_URL_RE.exec(raw);
39
+ if (match?.[1]) return match[1];
40
+ return raw;
41
+ }
36
42
 
37
43
  export {
38
44
  resolveIdentifier,
39
- normalizeChatId
45
+ normalizeChatId,
46
+ resolveJobIdentifier
40
47
  };
@@ -179,6 +179,51 @@ function slimSearchPosts(data) {
179
179
  const items = Array.isArray(d["items"]) ? d["items"].map(slimSearchPostsItem) : [];
180
180
  return { ...d, items };
181
181
  }
182
+ function slimAccountListItem(item) {
183
+ return {
184
+ account_id: item["account_id"] ?? null,
185
+ status: item["status"] ?? null,
186
+ auth_method: item["auth_method"] ?? null,
187
+ full_name: item["full_name"] ?? null,
188
+ headline: item["headline"] ?? null,
189
+ seat_id: item["seat_id"] ?? null,
190
+ connected_at: item["connected_at"] ?? null
191
+ };
192
+ }
193
+ function slimAccountList(data) {
194
+ const d = data !== null && data !== void 0 && typeof data === "object" ? data : {};
195
+ const items = Array.isArray(d["items"]) ? d["items"].map(slimAccountListItem) : [];
196
+ return { object: d["object"] ?? null, items, cursor: d["cursor"] ?? null };
197
+ }
198
+ function slimAccountGet(data) {
199
+ const d = data !== null && data !== void 0 && typeof data === "object" ? data : {};
200
+ return {
201
+ account_id: d["account_id"] ?? null,
202
+ status: d["status"] ?? null,
203
+ auth_method: d["auth_method"] ?? null,
204
+ full_name: d["full_name"] ?? null,
205
+ headline: d["headline"] ?? null,
206
+ seat_id: d["seat_id"] ?? null,
207
+ connected_at: d["connected_at"] ?? null,
208
+ last_checked_at: d["last_checked_at"] ?? null,
209
+ quotas: d["quotas"] ?? []
210
+ };
211
+ }
212
+ function slimJob(data) {
213
+ const d = data !== null && data !== void 0 && typeof data === "object" ? data : {};
214
+ return {
215
+ object: d["object"] ?? null,
216
+ id: d["id"] ?? null,
217
+ title: d["title"] ?? null,
218
+ company: d["company"] ?? null,
219
+ company_id: d["company_id"] ?? null,
220
+ location: d["location"] ?? null,
221
+ state: d["state"] ?? null,
222
+ applicants_counter: d["applicants_counter"] ?? null,
223
+ published_at: d["published_at"] ?? null,
224
+ description: d["description"] ?? null
225
+ };
226
+ }
182
227
  function slimCompany(data) {
183
228
  const d = data !== null && data !== void 0 && typeof data === "object" ? data : {};
184
229
  const rawMessaging = d["messaging"] !== null && d["messaging"] !== void 0 && typeof d["messaging"] === "object" ? d["messaging"] : null;
@@ -218,5 +263,9 @@ export {
218
263
  slimSearchJobs,
219
264
  slimSearchPostsItem,
220
265
  slimSearchPosts,
266
+ slimAccountListItem,
267
+ slimAccountList,
268
+ slimAccountGet,
269
+ slimJob,
221
270
  slimCompany
222
271
  };
package/dist/cli.js CHANGED
@@ -143,17 +143,18 @@ var main = defineCommand({
143
143
  // ---------------------------------------------------------------------------
144
144
  // Noun groups — lazy-loaded on first invocation.
145
145
  // ---------------------------------------------------------------------------
146
- profile: () => import("./profile-GGUBDI3P.js").then((m) => m.profileCommand),
147
- company: () => import("./company-HPHLJCKB.js").then((m) => m.companyCommand),
148
- connect: () => import("./connect-EUJBSLNM.js").then((m) => m.connectCommand),
149
- search: () => import("./search-RZYVGGMN.js").then((m) => m.searchCommand),
150
- inbox: () => import("./inbox-YV6GPRG6.js").then((m) => m.inboxCommand),
151
- message: () => import("./message-YRMLMHK7.js").then((m) => m.messageCommand),
152
- post: () => import("./post-KBSR3ADF.js").then((m) => m.postCommand),
153
- account: () => import("./account-O5GZNE72.js").then((m) => m.accountCommand),
154
- webhook: () => import("./webhook-F6CRIISR.js").then((m) => m.webhookCommand),
155
- "sales-nav": () => import("./sales-nav-4DYBMHKN.js").then((m) => m.salesNavCommand),
156
- recruiter: () => import("./recruiter-B5UIHTIN.js").then((m) => m.recruiterCommand)
146
+ profile: () => import("./profile-2YE3IC3O.js").then((m) => m.profileCommand),
147
+ company: () => import("./company-QB7VCLXJ.js").then((m) => m.companyCommand),
148
+ job: () => import("./job-QCKWY257.js").then((m) => m.jobCommand),
149
+ connect: () => import("./connect-2OAOLYQO.js").then((m) => m.connectCommand),
150
+ search: () => import("./search-5BBFRE6T.js").then((m) => m.searchCommand),
151
+ inbox: () => import("./inbox-AFVIF6ZU.js").then((m) => m.inboxCommand),
152
+ message: () => import("./message-MP4TJJXS.js").then((m) => m.messageCommand),
153
+ post: () => import("./post-Q3KR3TN3.js").then((m) => m.postCommand),
154
+ account: () => import("./account-XV3MU5S5.js").then((m) => m.accountCommand),
155
+ webhook: () => import("./webhook-7BJUYU4H.js").then((m) => m.webhookCommand),
156
+ "sales-nav": () => import("./sales-nav-SG6IXCTR.js").then((m) => m.salesNavCommand),
157
+ recruiter: () => import("./recruiter-2CETQNCU.js").then((m) => m.recruiterCommand)
157
158
  },
158
159
  async run() {
159
160
  const { runMain } = await import("citty");
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- resolveIdentifier
4
- } from "./chunk-SZB3CFRZ.js";
5
2
  import {
6
3
  slimCompany
7
- } from "./chunk-J5KGG2EE.js";
4
+ } from "./chunk-SSPILTKF.js";
5
+ import {
6
+ resolveIdentifier
7
+ } from "./chunk-DMQZEPQE.js";
8
8
  import {
9
9
  createClient,
10
10
  renderError,
@@ -1,19 +1,19 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- buildPreviewOutput
4
- } from "./chunk-R3VLWLVV.js";
5
- import {
6
- resolveIdentifier
7
- } from "./chunk-SZB3CFRZ.js";
8
2
  import {
9
3
  streamAll
10
4
  } from "./chunk-GXTZION6.js";
5
+ import {
6
+ buildPreviewOutput
7
+ } from "./chunk-R3VLWLVV.js";
11
8
  import {
12
9
  slimInviteReceived,
13
10
  slimInviteReceivedItem,
14
11
  slimInviteSent,
15
12
  slimInviteSentItem
16
- } from "./chunk-J5KGG2EE.js";
13
+ } from "./chunk-SSPILTKF.js";
14
+ import {
15
+ resolveIdentifier
16
+ } from "./chunk-DMQZEPQE.js";
17
17
  import {
18
18
  createClient,
19
19
  renderError,
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- normalizeChatId
4
- } from "./chunk-SZB3CFRZ.js";
5
2
  import {
6
3
  streamAll
7
4
  } from "./chunk-GXTZION6.js";
5
+ import {
6
+ normalizeChatId
7
+ } from "./chunk-DMQZEPQE.js";
8
8
  import {
9
9
  createClient,
10
10
  renderError,
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ slimJob
4
+ } from "./chunk-SSPILTKF.js";
5
+ import {
6
+ resolveJobIdentifier
7
+ } from "./chunk-DMQZEPQE.js";
8
+ import {
9
+ createClient,
10
+ renderError,
11
+ renderSuccess,
12
+ renderUnexpectedError,
13
+ resolveEffectiveConfig
14
+ } from "./chunk-47SYFQRF.js";
15
+ import {
16
+ READ_SINGLE_FLAGS
17
+ } from "./chunk-TDYIQHQX.js";
18
+
19
+ // src/commands/job.ts
20
+ import { defineCommand } from "citty";
21
+ function buildOutputStreams() {
22
+ return {
23
+ stdout: { write: (s) => process.stdout.write(s) },
24
+ stderr: { write: (s) => process.stderr.write(s) }
25
+ };
26
+ }
27
+ function requireAccount(account, out) {
28
+ if (!account) {
29
+ out.stderr.write("error: --account is required for this command. Set it via --account, CURVIATE_ACCOUNT, or `curviate config set-account`.\n");
30
+ process.exit(2);
31
+ }
32
+ return account;
33
+ }
34
+ function resolveOutputOpts(flags) {
35
+ return {
36
+ json: (flags.json ?? false) || !process.stdout.isTTY,
37
+ isTTY: process.stdout.isTTY ?? false,
38
+ fields: flags.fields,
39
+ verbose: flags.verbose ?? false
40
+ };
41
+ }
42
+ async function runJobGet(client, flags, out) {
43
+ if (flags.preview) {
44
+ out.stderr.write("error: --preview is only valid on write commands (mutations). Reads just run.\n");
45
+ process.exit(2);
46
+ }
47
+ const accountId = requireAccount(flags.account, out);
48
+ const rawId = flags.id ?? "";
49
+ const resolvedId = resolveJobIdentifier(rawId);
50
+ const ns = client.account(accountId);
51
+ const outOpts = resolveOutputOpts(flags);
52
+ try {
53
+ const result = await ns.jobs.get(resolvedId);
54
+ renderSuccess(result, { ...outOpts, slim: slimJob }, out);
55
+ } catch (err) {
56
+ const { CurviateError } = await import("@curviate/sdk");
57
+ if (err instanceof CurviateError) {
58
+ const { getExitCode } = await import("./exit-codes-NFIR57ZA.js");
59
+ renderError(err, outOpts, out);
60
+ process.exit(getExitCode(err.code));
61
+ }
62
+ renderUnexpectedError(err, out);
63
+ process.exit(1);
64
+ }
65
+ }
66
+ var jobGetCommand = defineCommand({
67
+ meta: { name: "get", description: "Retrieve one public LinkedIn job posting's full detail." },
68
+ args: {
69
+ ...READ_SINGLE_FLAGS,
70
+ id: { type: "positional", description: "Job URL (e.g. https://www.linkedin.com/jobs/view/4428113858) or a bare numeric job id." }
71
+ },
72
+ async run({ args }) {
73
+ const flags = args;
74
+ const cfg = await resolveEffectiveConfig({
75
+ apiKey: flags["api-key"],
76
+ baseUrl: flags["base-url"],
77
+ timeout: flags.timeout,
78
+ account: flags.account,
79
+ profile: flags.profile
80
+ });
81
+ if (!cfg.apiKey) {
82
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
83
+ process.exit(3);
84
+ }
85
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
86
+ const out = buildOutputStreams();
87
+ await runJobGet(client, { ...flags, account: flags.account ?? cfg.account }, out);
88
+ }
89
+ });
90
+ var jobCommand = defineCommand({
91
+ meta: { name: "job", description: "Public LinkedIn job posting operations." },
92
+ args: { ...READ_SINGLE_FLAGS },
93
+ subCommands: {
94
+ get: jobGetCommand
95
+ },
96
+ async run() {
97
+ process.stderr.write(
98
+ "Usage: curviate job get <url|id>\n"
99
+ );
100
+ }
101
+ });
102
+ export {
103
+ jobCommand,
104
+ runJobGet
105
+ };
@@ -16,7 +16,7 @@ import {
16
16
  import {
17
17
  normalizeChatId,
18
18
  resolveIdentifier
19
- } from "./chunk-SZB3CFRZ.js";
19
+ } from "./chunk-DMQZEPQE.js";
20
20
  import {
21
21
  createClient,
22
22
  renderError,
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- buildPreviewOutput
4
- } from "./chunk-R3VLWLVV.js";
5
- import {
6
- resolveIdentifier
7
- } from "./chunk-SZB3CFRZ.js";
8
2
  import {
9
3
  streamAll
10
4
  } from "./chunk-GXTZION6.js";
5
+ import {
6
+ buildPreviewOutput
7
+ } from "./chunk-R3VLWLVV.js";
11
8
  import {
12
9
  slimProfile,
13
10
  slimProfileMe
14
- } from "./chunk-J5KGG2EE.js";
11
+ } from "./chunk-SSPILTKF.js";
12
+ import {
13
+ resolveIdentifier
14
+ } from "./chunk-DMQZEPQE.js";
15
15
  import {
16
16
  createClient,
17
17
  renderError,
@@ -3,24 +3,28 @@ import {
3
3
  BinaryOutputError,
4
4
  writeBinaryOutput
5
5
  } from "./chunk-UWO2D4HW.js";
6
+ import {
7
+ DEFAULT_FILTER_READERS,
8
+ assembleFilters,
9
+ splitCsv
10
+ } from "./chunk-42VUUKQ3.js";
6
11
  import {
7
12
  AttachError,
8
13
  readAttachment
9
14
  } from "./chunk-Q43HZUN3.js";
15
+ import {
16
+ streamAll
17
+ } from "./chunk-GXTZION6.js";
10
18
  import {
11
19
  buildPreviewOutput
12
20
  } from "./chunk-R3VLWLVV.js";
13
21
  import {
14
- resolveIdentifier
15
- } from "./chunk-SZB3CFRZ.js";
16
- import {
17
- DEFAULT_FILTER_READERS,
18
- assembleFilters,
19
- splitCsv
20
- } from "./chunk-42VUUKQ3.js";
22
+ slimJob
23
+ } from "./chunk-SSPILTKF.js";
21
24
  import {
22
- streamAll
23
- } from "./chunk-GXTZION6.js";
25
+ resolveIdentifier,
26
+ resolveJobIdentifier
27
+ } from "./chunk-DMQZEPQE.js";
24
28
  import {
25
29
  createClient,
26
30
  renderError,
@@ -60,7 +64,8 @@ function resolveOutputOpts(flags) {
60
64
  return {
61
65
  json: (flags.json ?? false) || !process.stdout.isTTY,
62
66
  isTTY: process.stdout.isTTY ?? false,
63
- fields: flags.fields
67
+ fields: flags.fields,
68
+ verbose: flags.verbose ?? false
64
69
  };
65
70
  }
66
71
  function normalizeAttachPaths(attach) {
@@ -532,6 +537,20 @@ async function runRecruiterListApplicants(client, flags, out) {
532
537
  await handleSdkError(err, outOpts, out);
533
538
  }
534
539
  }
540
+ async function runRecruiterGetJob(client, flags, out) {
541
+ rejectPreviewOnRead(flags.preview, out);
542
+ const accountId = requireAccount(flags.account, out);
543
+ const rawJobId = flags.jobId ?? "";
544
+ const jobId = resolveJobIdentifier(rawJobId);
545
+ const ns = client.account(accountId);
546
+ const outOpts = resolveOutputOpts(flags);
547
+ try {
548
+ const result = await ns.recruiter.getJob(jobId);
549
+ renderSuccess(result, { ...outOpts, slim: slimJob }, out);
550
+ } catch (err) {
551
+ await handleSdkError(err, outOpts, out);
552
+ }
553
+ }
535
554
  async function runRecruiterGetApplicant(client, flags, out) {
536
555
  rejectPreviewOnRead(flags.preview, out);
537
556
  const accountId = requireAccount(flags.account, out);
@@ -993,6 +1012,30 @@ var recruiterJobApplicantsCommand = defineCommand({
993
1012
  await runRecruiterListApplicants(client, { ...flags, account: flags.account ?? cfg.account }, out);
994
1013
  }
995
1014
  });
1015
+ var recruiterJobGetCommand = defineCommand({
1016
+ meta: { name: "get", description: "Get a job posting via the Recruiter lens (any public posting, not only your own)." },
1017
+ args: {
1018
+ ...READ_SINGLE_FLAGS,
1019
+ jobId: { type: "positional", description: "Job URL (e.g. https://www.linkedin.com/jobs/view/4428113858) or a bare numeric job id." }
1020
+ },
1021
+ async run({ args }) {
1022
+ const flags = args;
1023
+ const cfg = await resolveEffectiveConfig({
1024
+ apiKey: flags["api-key"],
1025
+ baseUrl: flags["base-url"],
1026
+ timeout: flags.timeout,
1027
+ account: flags.account,
1028
+ profile: flags.profile
1029
+ });
1030
+ if (!cfg.apiKey) {
1031
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
1032
+ process.exit(3);
1033
+ }
1034
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
1035
+ const out = buildOutputStreams();
1036
+ await runRecruiterGetJob(client, { ...flags, account: flags.account ?? cfg.account }, out);
1037
+ }
1038
+ });
996
1039
  var recruiterJobCommand = defineCommand({
997
1040
  meta: { name: "job", description: "Recruiter job posting operations." },
998
1041
  args: { ...GLOBAL_FLAGS },
@@ -1000,11 +1043,12 @@ var recruiterJobCommand = defineCommand({
1000
1043
  create: recruiterJobCreateCommand,
1001
1044
  publish: recruiterJobPublishCommand,
1002
1045
  checkpoint: recruiterJobCheckpointCommand,
1003
- applicants: recruiterJobApplicantsCommand
1046
+ applicants: recruiterJobApplicantsCommand,
1047
+ get: recruiterJobGetCommand
1004
1048
  },
1005
1049
  async run() {
1006
1050
  process.stderr.write(
1007
- "Usage: curviate recruiter job create [flags\u2026]\n curviate recruiter job publish <job_id> [--mode <m>]\n curviate recruiter job checkpoint <job_id> --input <v>\n curviate recruiter job applicants <job_id>\n"
1051
+ "Usage: curviate recruiter job create [flags\u2026]\n curviate recruiter job publish <job_id> [--mode <m>]\n curviate recruiter job checkpoint <job_id> --input <v>\n curviate recruiter job applicants <job_id>\n curviate recruiter job get <url|id>\n"
1008
1052
  );
1009
1053
  }
1010
1054
  });
@@ -1092,7 +1136,7 @@ var recruiterCommand = defineCommand({
1092
1136
  },
1093
1137
  async run() {
1094
1138
  process.stderr.write(
1095
- 'Usage: curviate recruiter sync\n curviate recruiter message new --to <id> "<text>"\n curviate recruiter profile <identifier>\n curviate recruiter search people [--keywords <k>]\n curviate recruiter search parameters --type <t>\n curviate recruiter projects\n curviate recruiter project <project_id>\n curviate recruiter add-candidate <user_id> --hiring-project-id <id>\n curviate recruiter add-applicant <user_id> --hiring-project-id <id>\n curviate recruiter reject-applicant <user_id> --hiring-project-id <id> --reason <r>\n curviate recruiter jobs\n curviate recruiter job create [flags\u2026]\n curviate recruiter job publish <job_id> [--mode <m>]\n curviate recruiter job checkpoint <job_id> --input <v>\n curviate recruiter job applicants <job_id>\n curviate recruiter applicant <applicant_id>\n curviate recruiter applicant resume <applicant_id> -o <file>\n'
1139
+ 'Usage: curviate recruiter sync\n curviate recruiter message new --to <id> "<text>"\n curviate recruiter profile <identifier>\n curviate recruiter search people [--keywords <k>]\n curviate recruiter search parameters --type <t>\n curviate recruiter projects\n curviate recruiter project <project_id>\n curviate recruiter add-candidate <user_id> --hiring-project-id <id>\n curviate recruiter add-applicant <user_id> --hiring-project-id <id>\n curviate recruiter reject-applicant <user_id> --hiring-project-id <id> --reason <r>\n curviate recruiter jobs\n curviate recruiter job create [flags\u2026]\n curviate recruiter job publish <job_id> [--mode <m>]\n curviate recruiter job checkpoint <job_id> --input <v>\n curviate recruiter job applicants <job_id>\n curviate recruiter job get <url|id>\n curviate recruiter applicant <applicant_id>\n curviate recruiter applicant resume <applicant_id> -o <file>\n'
1096
1140
  );
1097
1141
  }
1098
1142
  });
@@ -1103,6 +1147,7 @@ export {
1103
1147
  runRecruiterCreateJob,
1104
1148
  runRecruiterDownloadResume,
1105
1149
  runRecruiterGetApplicant,
1150
+ runRecruiterGetJob,
1106
1151
  runRecruiterGetParameters,
1107
1152
  runRecruiterGetProject,
1108
1153
  runRecruiterJobCheckpoint,
@@ -1,23 +1,23 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- AttachError,
4
- readAttachment
5
- } from "./chunk-Q43HZUN3.js";
6
- import {
7
- buildPreviewOutput
8
- } from "./chunk-R3VLWLVV.js";
9
- import {
10
- resolveIdentifier
11
- } from "./chunk-SZB3CFRZ.js";
12
2
  import {
13
3
  DEFAULT_FILTER_READERS,
14
4
  assembleFilters,
15
5
  splitCsv,
16
6
  splitCsvNumbers
17
7
  } from "./chunk-42VUUKQ3.js";
8
+ import {
9
+ AttachError,
10
+ readAttachment
11
+ } from "./chunk-Q43HZUN3.js";
18
12
  import {
19
13
  streamAll
20
14
  } from "./chunk-GXTZION6.js";
15
+ import {
16
+ buildPreviewOutput
17
+ } from "./chunk-R3VLWLVV.js";
18
+ import {
19
+ resolveIdentifier
20
+ } from "./chunk-DMQZEPQE.js";
21
21
  import {
22
22
  createClient,
23
23
  renderError,
@@ -17,7 +17,7 @@ import {
17
17
  slimSearchPeopleItem,
18
18
  slimSearchPosts,
19
19
  slimSearchPostsItem
20
- } from "./chunk-J5KGG2EE.js";
20
+ } from "./chunk-SSPILTKF.js";
21
21
  import {
22
22
  createClient,
23
23
  renderError,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@curviate/cli",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "private": false,
5
5
  "description": "Official command-line interface for the Curviate API.",
6
6
  "license": "MIT",
@@ -40,7 +40,7 @@
40
40
  "clean": "rm -rf dist *.tsbuildinfo"
41
41
  },
42
42
  "dependencies": {
43
- "@curviate/sdk": "^0.8.0",
43
+ "@curviate/sdk": "^0.10.0",
44
44
  "citty": "^0.1.6"
45
45
  },
46
46
  "devDependencies": {
@@ -6,12 +6,12 @@ import {
6
6
  import {
7
7
  resolveTextOrStdin
8
8
  } from "./chunk-CHFKVAEI.js";
9
- import {
10
- buildPreviewOutput
11
- } from "./chunk-R3VLWLVV.js";
12
9
  import {
13
10
  streamAll
14
11
  } from "./chunk-GXTZION6.js";
12
+ import {
13
+ buildPreviewOutput
14
+ } from "./chunk-R3VLWLVV.js";
15
15
  import {
16
16
  createClient,
17
17
  renderError,
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- buildPreviewOutput
4
- } from "./chunk-R3VLWLVV.js";
5
2
  import {
6
3
  streamAll
7
4
  } from "./chunk-GXTZION6.js";
5
+ import {
6
+ buildPreviewOutput
7
+ } from "./chunk-R3VLWLVV.js";
8
8
  import {
9
9
  createClient,
10
10
  renderError,