@cavuno/board 4.12.0 → 4.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/{_spec-ChuT3QX8.d.mts → _spec-CzS_E61o.d.mts} +52 -0
  3. package/dist/{_spec-ChuT3QX8.d.ts → _spec-CzS_E61o.d.ts} +52 -0
  4. package/dist/{blog-VbcrwKk9.d.ts → blog-CtRz0ZlI.d.ts} +1 -1
  5. package/dist/{blog-BB_l6xes.d.mts → blog-D4R04cZP.d.mts} +1 -1
  6. package/dist/{board-CWQjFHWJ.d.ts → board-CXE7dnk9.d.mts} +2 -2
  7. package/dist/{board-BJCKz-Is.d.mts → board-MqLMXY48.d.ts} +2 -2
  8. package/dist/{breadcrumbs-6TB8Lw-C.d.ts → breadcrumbs-DdEy2bpQ.d.ts} +18 -6
  9. package/dist/{breadcrumbs-BoIXFh0q.d.mts → breadcrumbs-bbEYB2CD.d.mts} +18 -6
  10. package/dist/browser/cavuno-board.global.min.js +1 -1
  11. package/dist/{chunk-6454IFHS.mjs → chunk-OPMJ6YH5.mjs} +6 -3
  12. package/dist/{chunk-XEJWXRLK.mjs → chunk-W73BOGOQ.mjs} +4 -0
  13. package/dist/filters.d.mts +2 -2
  14. package/dist/filters.d.ts +2 -2
  15. package/dist/format.d.mts +4 -4
  16. package/dist/format.d.ts +4 -4
  17. package/dist/format.mjs +1 -1
  18. package/dist/index.d.mts +113 -13
  19. package/dist/index.d.ts +113 -13
  20. package/dist/index.js +145 -1
  21. package/dist/index.mjs +142 -2
  22. package/dist/{jobs-CV41Msa7.d.mts → jobs-CsrNGyvS.d.mts} +1 -1
  23. package/dist/{jobs-CsoxD0mU.d.ts → jobs-DDJDUH3q.d.ts} +1 -1
  24. package/dist/{search-ACYoyhh3.d.ts → search-B3nCRBqd.d.ts} +1 -1
  25. package/dist/{search-DEVb6pdX.d.mts → search-Bnx30Fe2.d.mts} +1 -1
  26. package/dist/{seo-BrC9ue1U.d.ts → seo-BUDWv2pv.d.ts} +1 -1
  27. package/dist/{seo-DvS9_GxS.d.mts → seo-aSJ3zVx9.d.mts} +1 -1
  28. package/dist/seo-files.d.mts +2 -2
  29. package/dist/seo-files.d.ts +2 -2
  30. package/dist/seo.d.mts +6 -6
  31. package/dist/seo.d.ts +6 -6
  32. package/dist/seo.js +6 -3
  33. package/dist/seo.mjs +1 -1
  34. package/dist/server.d.mts +6 -6
  35. package/dist/server.d.ts +6 -6
  36. package/dist/server.mjs +1 -1
  37. package/dist/sitemap.d.mts +6 -6
  38. package/dist/sitemap.d.ts +6 -6
  39. package/dist/suggest.d.mts +2 -2
  40. package/dist/suggest.d.ts +2 -2
  41. package/package.json +1 -1
  42. package/skills/cavuno-board-seo/JOB_AND_BREADCRUMBS.md +5 -2
  43. package/skills/manifest.json +1 -1
package/CHANGELOG.md CHANGED
@@ -3,6 +3,45 @@
3
3
  This changelog records changes that affect Board API compatibility, exported
4
4
  types, runtime behavior, or supported integration patterns.
5
5
 
6
+ ## 4.14.0 — 2026-08-29
7
+
8
+ - **Talent lists**: `board.me.companies.talentLists` (`list` / `create` /
9
+ `update` / `remove`). Company-owned saved predicates over the talent
10
+ directory. `filters` reuse the frozen `/talent` query (`q`, `skill`,
11
+ `jobSearchStatus`, `languages`, `openToRelocate`, `place`, `sort`,
12
+ `seniority`, `permitCountry`, `interestedRole`). Optional `job` binds a
13
+ list to one company job; pass `job: null` on update to unbind. Approved
14
+ members share the same lists.
15
+ - **Sourced candidates**: `board.me.companies.sourcedCandidates` (`list` /
16
+ `add` / `remove` / `convert`). Per-job membership rail. Saving a candidate
17
+ always writes here. `convert` creates a pipeline application with source
18
+ `sourced` (hidden from the candidate until they apply themselves).
19
+ `stage: 'applied'` aliases to `review`. A board without a native pipeline
20
+ raises `sourced_convert_unavailable` (409). `add` is idempotent
21
+ (`created: false` on a second save).
22
+ - **Error codes**: `talent_list_not_found`, `sourced_candidate_not_found`,
23
+ and `sourced_convert_unavailable` join `BOARD_API_ERROR_CODES`.
24
+ - **`board.auth.verifyWorkEmail({ token })`**: confirm an employer
25
+ work-email token without a session (`POST /auth/verify-work-email`).
26
+ `board.me.companies.workEmail.confirm(slug, { token })` is deprecated —
27
+ `slug` is ignored; the token alone identifies the membership.
28
+ - **OAuth employer sign-up**: `getOAuthAuthorizationUrl(provider, { role:
29
+ 'employer' })` creates an employer profile for a new user. The role is
30
+ fixed at authorize time and cannot be changed on the callback. Defaults
31
+ to `candidate`.
32
+
33
+ ## 4.13.0 — 2026-08-28
34
+
35
+ - **`board.context().contact.legalName`**: the operating company's registered
36
+ legal name, or `null` when unset. Use it as the JobPosting
37
+ `hiringOrganization` name when a job has no company of its own, ahead of the
38
+ board name — that is the order the hosted board emits, so a headless board
39
+ produces identical structured data. `buildJobPostingJsonLd` reads it from
40
+ `contact.legalName` automatically; a top-level `legalName` is also accepted.
41
+ - **Candidate profile visibility default**: a board can set the visibility new
42
+ candidate profiles start with, rather than every profile defaulting the same
43
+ way.
44
+
6
45
  ## 4.12.0 — 2026-08-28
7
46
 
8
47
  - **`resolveApplyDecision`**: the apply-decision ladder now takes the board's
@@ -63,6 +63,10 @@ interface components {
63
63
  /** @description The note text. */
64
64
  body: string;
65
65
  };
66
+ AddSourcedCandidateBody: {
67
+ job: string;
68
+ candidateBoardUserId: string;
69
+ };
66
70
  Alert: {
67
71
  /** @description Job-alert preference ID. Also the path key. */
68
72
  id: string;
@@ -674,6 +678,9 @@ interface components {
674
678
  object: "conversation_ref";
675
679
  conversationId: string | null;
676
680
  };
681
+ ConvertSourcedCandidateBody: {
682
+ stage: string;
683
+ };
677
684
  CreateApplyApprovalBody: {
678
685
  sessionKey: string;
679
686
  };
@@ -819,6 +826,11 @@ interface components {
819
826
  /** @description The stage label. */
820
827
  label: string;
821
828
  };
829
+ CreateTalentListBody: {
830
+ name: string;
831
+ filters?: components["schemas"]["TalentListFilters"];
832
+ job?: string;
833
+ };
822
834
  CustomFieldDefinition: {
823
835
  /** @description Immutable per-board slug used as the key in a job’s `customFieldValues`. */
824
836
  key: string;
@@ -1893,6 +1905,8 @@ interface components {
1893
1905
  contact: {
1894
1906
  /** @description Public contact email (render as `mailto:`). Operator-set in settings › Contact & company details. */
1895
1907
  email: string | null;
1908
+ /** @description The operating company's registered legal name, or `null` when unset. Use it as the JobPosting `hiringOrganization` name when a job has no company of its own, ahead of the board name — that is the order the hosted board emits, so a headless board produces identical structured data. */
1909
+ legalName: string | null;
1896
1910
  /** @description Company website URL, sanitized to absolute http(s). Null when unset or non-http(s). */
1897
1911
  websiteUrl: string | null;
1898
1912
  /** @description X (Twitter) profile URL, normalized from the stored handle. */
@@ -2558,6 +2572,14 @@ interface components {
2558
2572
  boardMedianMax: number | null;
2559
2573
  currency: string;
2560
2574
  };
2575
+ SourcedCandidate: {
2576
+ id: string;
2577
+ /** @enum {string} */
2578
+ object: "sourced_candidate";
2579
+ candidate: components["schemas"]["TalentDirectoryEntry"];
2580
+ sourcedAt: number;
2581
+ sourcedBy: string;
2582
+ };
2561
2583
  StartAboutApplicationBody: {
2562
2584
  applicationId: string;
2563
2585
  body: string;
@@ -2672,6 +2694,31 @@ interface components {
2672
2694
  endDate: string | null;
2673
2695
  }[];
2674
2696
  };
2697
+ TalentList: {
2698
+ id: string;
2699
+ /** @enum {string} */
2700
+ object: "talent_list";
2701
+ name: string;
2702
+ filters: components["schemas"]["TalentListFilters"];
2703
+ jobId: string | null;
2704
+ createdBy: string;
2705
+ createdAt: number;
2706
+ updatedAt: number;
2707
+ };
2708
+ TalentListFilters: {
2709
+ q?: string;
2710
+ skill?: string;
2711
+ /** @enum {string} */
2712
+ jobSearchStatus?: "actively_looking" | "open_to_offers" | "not_looking";
2713
+ languages?: string[];
2714
+ openToRelocate?: boolean;
2715
+ place?: string;
2716
+ /** @enum {string} */
2717
+ sort?: "relevance" | "newest";
2718
+ seniority?: string;
2719
+ permitCountry?: string;
2720
+ interestedRole?: string;
2721
+ };
2675
2722
  TalentProfile: {
2676
2723
  /** @enum {string} */
2677
2724
  object: "talent_profile";
@@ -3015,6 +3062,11 @@ interface components {
3015
3062
  UpdateSkillsBody: {
3016
3063
  skills: string[];
3017
3064
  };
3065
+ UpdateTalentListBody: {
3066
+ name?: string;
3067
+ filters?: components["schemas"]["TalentListFilters"];
3068
+ job?: string | unknown | unknown;
3069
+ };
3018
3070
  VerifyEmailOtpBody: {
3019
3071
  code: string;
3020
3072
  };
@@ -63,6 +63,10 @@ interface components {
63
63
  /** @description The note text. */
64
64
  body: string;
65
65
  };
66
+ AddSourcedCandidateBody: {
67
+ job: string;
68
+ candidateBoardUserId: string;
69
+ };
66
70
  Alert: {
67
71
  /** @description Job-alert preference ID. Also the path key. */
68
72
  id: string;
@@ -674,6 +678,9 @@ interface components {
674
678
  object: "conversation_ref";
675
679
  conversationId: string | null;
676
680
  };
681
+ ConvertSourcedCandidateBody: {
682
+ stage: string;
683
+ };
677
684
  CreateApplyApprovalBody: {
678
685
  sessionKey: string;
679
686
  };
@@ -819,6 +826,11 @@ interface components {
819
826
  /** @description The stage label. */
820
827
  label: string;
821
828
  };
829
+ CreateTalentListBody: {
830
+ name: string;
831
+ filters?: components["schemas"]["TalentListFilters"];
832
+ job?: string;
833
+ };
822
834
  CustomFieldDefinition: {
823
835
  /** @description Immutable per-board slug used as the key in a job’s `customFieldValues`. */
824
836
  key: string;
@@ -1893,6 +1905,8 @@ interface components {
1893
1905
  contact: {
1894
1906
  /** @description Public contact email (render as `mailto:`). Operator-set in settings › Contact & company details. */
1895
1907
  email: string | null;
1908
+ /** @description The operating company's registered legal name, or `null` when unset. Use it as the JobPosting `hiringOrganization` name when a job has no company of its own, ahead of the board name — that is the order the hosted board emits, so a headless board produces identical structured data. */
1909
+ legalName: string | null;
1896
1910
  /** @description Company website URL, sanitized to absolute http(s). Null when unset or non-http(s). */
1897
1911
  websiteUrl: string | null;
1898
1912
  /** @description X (Twitter) profile URL, normalized from the stored handle. */
@@ -2558,6 +2572,14 @@ interface components {
2558
2572
  boardMedianMax: number | null;
2559
2573
  currency: string;
2560
2574
  };
2575
+ SourcedCandidate: {
2576
+ id: string;
2577
+ /** @enum {string} */
2578
+ object: "sourced_candidate";
2579
+ candidate: components["schemas"]["TalentDirectoryEntry"];
2580
+ sourcedAt: number;
2581
+ sourcedBy: string;
2582
+ };
2561
2583
  StartAboutApplicationBody: {
2562
2584
  applicationId: string;
2563
2585
  body: string;
@@ -2672,6 +2694,31 @@ interface components {
2672
2694
  endDate: string | null;
2673
2695
  }[];
2674
2696
  };
2697
+ TalentList: {
2698
+ id: string;
2699
+ /** @enum {string} */
2700
+ object: "talent_list";
2701
+ name: string;
2702
+ filters: components["schemas"]["TalentListFilters"];
2703
+ jobId: string | null;
2704
+ createdBy: string;
2705
+ createdAt: number;
2706
+ updatedAt: number;
2707
+ };
2708
+ TalentListFilters: {
2709
+ q?: string;
2710
+ skill?: string;
2711
+ /** @enum {string} */
2712
+ jobSearchStatus?: "actively_looking" | "open_to_offers" | "not_looking";
2713
+ languages?: string[];
2714
+ openToRelocate?: boolean;
2715
+ place?: string;
2716
+ /** @enum {string} */
2717
+ sort?: "relevance" | "newest";
2718
+ seniority?: string;
2719
+ permitCountry?: string;
2720
+ interestedRole?: string;
2721
+ };
2675
2722
  TalentProfile: {
2676
2723
  /** @enum {string} */
2677
2724
  object: "talent_profile";
@@ -3015,6 +3062,11 @@ interface components {
3015
3062
  UpdateSkillsBody: {
3016
3063
  skills: string[];
3017
3064
  };
3065
+ UpdateTalentListBody: {
3066
+ name?: string;
3067
+ filters?: components["schemas"]["TalentListFilters"];
3068
+ job?: string | unknown | unknown;
3069
+ };
3018
3070
  VerifyEmailOtpBody: {
3019
3071
  code: string;
3020
3072
  };
@@ -1,4 +1,4 @@
1
- import { S as Schemas } from './_spec-ChuT3QX8.js';
1
+ import { S as Schemas } from './_spec-CzS_E61o.js';
2
2
 
3
3
  /** Author shape embedded on posts (no `object` discriminator). */
4
4
  type BlogAuthorEmbed = Schemas['PublicBlogAuthorEmbed'];
@@ -1,4 +1,4 @@
1
- import { S as Schemas } from './_spec-ChuT3QX8.mjs';
1
+ import { S as Schemas } from './_spec-CzS_E61o.mjs';
2
2
 
3
3
  /** Author shape embedded on posts (no `object` discriminator). */
4
4
  type BlogAuthorEmbed = Schemas['PublicBlogAuthorEmbed'];
@@ -1,5 +1,5 @@
1
- import { S as Schemas } from './_spec-ChuT3QX8.js';
2
- import { L as ListEnvelope, m as RelatedSearch } from './jobs-CsoxD0mU.js';
1
+ import { S as Schemas } from './_spec-CzS_E61o.mjs';
2
+ import { L as ListEnvelope, m as RelatedSearch } from './jobs-CsrNGyvS.mjs';
3
3
 
4
4
  type PublicCompany = Schemas['CompanyPublic'];
5
5
  /** A market (sector) a company operates in — name + its source slug. */
@@ -1,5 +1,5 @@
1
- import { S as Schemas } from './_spec-ChuT3QX8.mjs';
2
- import { L as ListEnvelope, m as RelatedSearch } from './jobs-CV41Msa7.mjs';
1
+ import { S as Schemas } from './_spec-CzS_E61o.js';
2
+ import { L as ListEnvelope, m as RelatedSearch } from './jobs-DDJDUH3q.js';
3
3
 
4
4
  type PublicCompany = Schemas['CompanyPublic'];
5
5
  /** A market (sector) a company operates in — name + its source slug. */
@@ -1,5 +1,5 @@
1
- import { P as PublicBoard, a as CompanyCategorySalary, b as CompanySalary, L as LocationSalaryDetail, S as SkillSalaryDetail, T as TitleSalaryDetail } from './board-CWQjFHWJ.js';
2
- import { P as PublicJob } from './jobs-CsoxD0mU.js';
1
+ import { P as PublicBoard, a as CompanyCategorySalary, b as CompanySalary, L as LocationSalaryDetail, S as SkillSalaryDetail, T as TitleSalaryDetail } from './board-MqLMXY48.js';
2
+ import { P as PublicJob } from './jobs-DDJDUH3q.js';
3
3
 
4
4
  /**
5
5
  * Wire enum for `salaryTimeframe`. Defined here (not re-exported from any
@@ -91,9 +91,6 @@ declare function formatSalaryRange(language: string, min: number | null, max: nu
91
91
  *
92
92
  * Named exclusions (hosted behaviours with no wire twin, recorded in the
93
93
  * public API contract):
94
- * - `board.companyLegalName` — hosted falls back to it for the
95
- * organization name between `company.name` and `board.name`; the wire
96
- * board context does not expose it.
97
94
  * - `board.companyWebsiteUrl` — hosted falls back to it for `sameAs` when
98
95
  * the company has no website; not on the wire.
99
96
  * - the hosted `job.place`/`locationLabel` jobLocation fallback (used when
@@ -103,7 +100,22 @@ declare function formatSalaryRange(language: string, min: number | null, max: nu
103
100
 
104
101
  type JsonLdObject = Record<string, unknown>;
105
102
  /** The only board fields JSON-LD needs — keeps callers' shapes flexible. */
106
- type JsonLdBoard = Pick<PublicBoard, 'name' | 'logoUrl'>;
103
+ type JsonLdBoard = Pick<PublicBoard, 'name' | 'logoUrl'> & {
104
+ /**
105
+ * The operating company's registered name, used as the organization name
106
+ * for a job with no company of its own — ahead of the board's display
107
+ * name, matching the hosted board.
108
+ *
109
+ * Read from `contact.legalName`, which is where `board.context()` puts it,
110
+ * so passing the context object straight through (the documented call
111
+ * shape) just works. `legalName` at the top level is accepted too, for
112
+ * callers that flatten the board into their own view model.
113
+ */
114
+ contact?: {
115
+ legalName?: string | null;
116
+ } | null;
117
+ legalName?: string | null;
118
+ };
107
119
  /**
108
120
  * Worldwide-remote jobs must still emit `applicantLocationRequirements`
109
121
  * next to TELECOMMUTE (Google requires a location signal), so the hosted
@@ -1,5 +1,5 @@
1
- import { P as PublicBoard, a as CompanyCategorySalary, b as CompanySalary, L as LocationSalaryDetail, S as SkillSalaryDetail, T as TitleSalaryDetail } from './board-BJCKz-Is.mjs';
2
- import { P as PublicJob } from './jobs-CV41Msa7.mjs';
1
+ import { P as PublicBoard, a as CompanyCategorySalary, b as CompanySalary, L as LocationSalaryDetail, S as SkillSalaryDetail, T as TitleSalaryDetail } from './board-CXE7dnk9.mjs';
2
+ import { P as PublicJob } from './jobs-CsrNGyvS.mjs';
3
3
 
4
4
  /**
5
5
  * Wire enum for `salaryTimeframe`. Defined here (not re-exported from any
@@ -91,9 +91,6 @@ declare function formatSalaryRange(language: string, min: number | null, max: nu
91
91
  *
92
92
  * Named exclusions (hosted behaviours with no wire twin, recorded in the
93
93
  * public API contract):
94
- * - `board.companyLegalName` — hosted falls back to it for the
95
- * organization name between `company.name` and `board.name`; the wire
96
- * board context does not expose it.
97
94
  * - `board.companyWebsiteUrl` — hosted falls back to it for `sameAs` when
98
95
  * the company has no website; not on the wire.
99
96
  * - the hosted `job.place`/`locationLabel` jobLocation fallback (used when
@@ -103,7 +100,22 @@ declare function formatSalaryRange(language: string, min: number | null, max: nu
103
100
 
104
101
  type JsonLdObject = Record<string, unknown>;
105
102
  /** The only board fields JSON-LD needs — keeps callers' shapes flexible. */
106
- type JsonLdBoard = Pick<PublicBoard, 'name' | 'logoUrl'>;
103
+ type JsonLdBoard = Pick<PublicBoard, 'name' | 'logoUrl'> & {
104
+ /**
105
+ * The operating company's registered name, used as the organization name
106
+ * for a job with no company of its own — ahead of the board's display
107
+ * name, matching the hosted board.
108
+ *
109
+ * Read from `contact.legalName`, which is where `board.context()` puts it,
110
+ * so passing the context object straight through (the documented call
111
+ * shape) just works. `legalName` at the top level is accepted too, for
112
+ * callers that flatten the board into their own view model.
113
+ */
114
+ contact?: {
115
+ legalName?: string | null;
116
+ } | null;
117
+ legalName?: string | null;
118
+ };
107
119
  /**
108
120
  * Worldwide-remote jobs must still emit `applicantLocationRequirements`
109
121
  * next to TELECOMMUTE (Google requires a location signal), so the hosted