@oxygen-agent/cli 1.987.20 → 1.1010.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/README.md +1 -1
- package/dist/admin-primary-providers-render.d.ts +0 -2
- package/dist/admin-primary-providers-render.js +1 -1
- package/dist/browser-login.js +1 -4
- package/dist/column-decision-options.d.ts +20 -0
- package/dist/column-decision-options.js +54 -0
- package/dist/command-manifest.d.ts +3 -2
- package/dist/command-manifest.js +25 -2
- package/dist/credentials.d.ts +1 -1
- package/dist/functions-commands.js +13 -9
- package/dist/help.d.ts +8 -0
- package/dist/help.js +46 -0
- package/dist/index.js +2751 -242
- package/dist/knowledge-mirror.d.ts +2 -2
- package/dist/runtime.d.ts +0 -15
- package/dist/runtime.js +1 -1
- package/dist/search-ai-filter-notice.d.ts +17 -0
- package/dist/search-ai-filter-notice.js +38 -0
- package/dist/session.d.ts +4 -3
- package/dist/skills.d.ts +8 -7
- package/dist/skills.js +58 -20
- package/dist/transcript.d.ts +2 -1
- package/dist/util.d.ts +10 -1
- package/dist/util.js +14 -2
- package/node_modules/@oxygen/cli-ugc/dist/commands.js +296 -140
- package/node_modules/@oxygen/cli-ugc/dist/field-parser.d.ts +9 -0
- package/node_modules/@oxygen/cli-ugc/dist/field-parser.js +34 -0
- package/node_modules/@oxygen/formula/dist/coerce.d.ts +10 -0
- package/node_modules/@oxygen/formula/dist/coerce.js +10 -0
- package/node_modules/@oxygen/formula/dist/formula-functions.js +65 -0
- package/node_modules/@oxygen/formula/dist/hash.d.ts +19 -0
- package/node_modules/@oxygen/formula/dist/hash.js +199 -0
- package/node_modules/@oxygen/formula/dist/value-cleaners.d.ts +6 -1
- package/node_modules/@oxygen/formula/dist/value-cleaners.js +10 -26
- package/node_modules/@oxygen/recipe-sdk/dist/index.d.ts +13 -0
- package/node_modules/@oxygen/shared/dist/array-utils.d.ts +5 -0
- package/node_modules/@oxygen/shared/dist/array-utils.js +11 -0
- package/node_modules/@oxygen/shared/dist/billing.d.ts +99 -22
- package/node_modules/@oxygen/shared/dist/billing.js +195 -40
- package/node_modules/@oxygen/shared/dist/byok-connect.js +5 -0
- package/node_modules/@oxygen/shared/dist/capability-discovery.d.ts +27 -0
- package/node_modules/@oxygen/shared/dist/capability-discovery.js +311 -28
- package/node_modules/@oxygen/shared/dist/cli-http-error.d.ts +8 -0
- package/node_modules/@oxygen/shared/dist/cli-http-error.js +8 -0
- package/node_modules/@oxygen/shared/dist/cli-result.js +1 -0
- package/node_modules/@oxygen/shared/dist/column-autofill.d.ts +52 -0
- package/node_modules/@oxygen/shared/dist/column-autofill.js +62 -0
- package/node_modules/@oxygen/shared/dist/column-decision.d.ts +50 -0
- package/node_modules/@oxygen/shared/dist/column-decision.js +228 -0
- package/node_modules/@oxygen/shared/dist/column-output-fields.js +2 -6
- package/node_modules/@oxygen/shared/dist/company-enrichment-fields.d.ts +113 -0
- package/node_modules/@oxygen/shared/dist/company-enrichment-fields.js +548 -0
- package/node_modules/@oxygen/shared/dist/copilot-skills.generated.d.ts +6 -6
- package/node_modules/@oxygen/shared/dist/copilot-skills.generated.js +6 -6
- package/node_modules/@oxygen/shared/dist/cutover-freeze.d.ts +26 -0
- package/node_modules/@oxygen/shared/dist/cutover-freeze.js +52 -0
- package/node_modules/@oxygen/shared/dist/data-suppliers.d.ts +57 -0
- package/node_modules/@oxygen/shared/dist/data-suppliers.js +59 -0
- package/node_modules/@oxygen/shared/dist/deploy-env.d.ts +74 -0
- package/node_modules/@oxygen/shared/dist/deploy-env.js +82 -0
- package/node_modules/@oxygen/shared/dist/dnc-rules.d.ts +130 -0
- package/node_modules/@oxygen/shared/dist/dnc-rules.js +221 -0
- package/node_modules/@oxygen/shared/dist/enrichment-intents.d.ts +107 -0
- package/node_modules/@oxygen/shared/dist/enrichment-intents.js +809 -0
- package/node_modules/@oxygen/shared/dist/error-message.d.ts +1 -0
- package/node_modules/@oxygen/shared/dist/error-message.js +3 -0
- package/node_modules/@oxygen/shared/dist/error-redaction.js +1 -3
- package/node_modules/@oxygen/shared/dist/external-write-policy.d.ts +33 -0
- package/node_modules/@oxygen/shared/dist/external-write-policy.js +68 -0
- package/node_modules/@oxygen/shared/dist/format-percent.d.ts +8 -0
- package/node_modules/@oxygen/shared/dist/format-percent.js +13 -0
- package/node_modules/@oxygen/shared/dist/freemail-domains.d.ts +81 -0
- package/node_modules/@oxygen/shared/dist/freemail-domains.js +157 -0
- package/node_modules/@oxygen/shared/dist/future-signup-lifecycle-projection.d.ts +1 -0
- package/node_modules/@oxygen/shared/dist/future-signup-lifecycle-projection.js +1 -1
- package/node_modules/@oxygen/shared/dist/hosted-ai.d.ts +60 -4
- package/node_modules/@oxygen/shared/dist/hosted-ai.js +125 -10
- package/node_modules/@oxygen/shared/dist/index.d.ts +15 -0
- package/node_modules/@oxygen/shared/dist/index.js +15 -0
- package/node_modules/@oxygen/shared/dist/json-path.js +1 -3
- package/node_modules/@oxygen/shared/dist/knowledge-bases.js +1 -3
- package/node_modules/@oxygen/shared/dist/knowledge-bootstrap.d.ts +2 -2
- package/node_modules/@oxygen/shared/dist/knowledge-bootstrap.js +2 -2
- package/node_modules/@oxygen/shared/dist/langfuse.d.ts +44 -1
- package/node_modules/@oxygen/shared/dist/langfuse.js +416 -14
- package/node_modules/@oxygen/shared/dist/linkedin-countries.d.ts +33 -0
- package/node_modules/@oxygen/shared/dist/linkedin-countries.js +361 -0
- package/node_modules/@oxygen/shared/dist/linkedin-country-timezones.d.ts +24 -0
- package/node_modules/@oxygen/shared/dist/linkedin-country-timezones.js +276 -0
- package/node_modules/@oxygen/shared/dist/linkedin-message-deletion.d.ts +2 -0
- package/node_modules/@oxygen/shared/dist/linkedin-message-deletion.js +5 -0
- package/node_modules/@oxygen/shared/dist/linkedin-post-keywords.d.ts +44 -0
- package/node_modules/@oxygen/shared/dist/linkedin-post-keywords.js +116 -0
- package/node_modules/@oxygen/shared/dist/linkedin-sequences.d.ts +96 -0
- package/node_modules/@oxygen/shared/dist/linkedin-sequences.js +123 -0
- package/node_modules/@oxygen/shared/dist/llm-durable-capture.d.ts +24 -0
- package/node_modules/@oxygen/shared/dist/llm-durable-capture.js +89 -0
- package/node_modules/@oxygen/shared/dist/llm-prompts.d.ts +75 -0
- package/node_modules/@oxygen/shared/dist/llm-prompts.js +161 -0
- package/node_modules/@oxygen/shared/dist/log-sink-selector.d.ts +39 -0
- package/node_modules/@oxygen/shared/dist/log-sink-selector.js +56 -0
- package/node_modules/@oxygen/shared/dist/log.d.ts +1 -0
- package/node_modules/@oxygen/shared/dist/log.js +6 -1
- package/node_modules/@oxygen/shared/dist/mailbox-egress-ownership.d.ts +90 -0
- package/node_modules/@oxygen/shared/dist/mailbox-egress-ownership.js +130 -0
- package/node_modules/@oxygen/shared/dist/object-storage.d.ts +17 -0
- package/node_modules/@oxygen/shared/dist/object-storage.js +21 -0
- package/node_modules/@oxygen/shared/dist/operational-telemetry.d.ts +24 -0
- package/node_modules/@oxygen/shared/dist/operational-telemetry.js +73 -0
- package/node_modules/@oxygen/shared/dist/otlp-log-sink.d.ts +79 -0
- package/node_modules/@oxygen/shared/dist/otlp-log-sink.js +366 -0
- package/node_modules/@oxygen/shared/dist/plan-capabilities.js +1 -0
- package/node_modules/@oxygen/shared/dist/plan-limits.d.ts +23 -22
- package/node_modules/@oxygen/shared/dist/plan-limits.js +45 -18
- package/node_modules/@oxygen/shared/dist/pricing-sheet.d.ts +48 -41
- package/node_modules/@oxygen/shared/dist/pricing-sheet.js +36 -25
- package/node_modules/@oxygen/shared/dist/pricing-snapshot.generated.d.ts +22 -22
- package/node_modules/@oxygen/shared/dist/pricing-snapshot.generated.js +40 -34
- package/node_modules/@oxygen/shared/dist/product-analytics-environment.js +9 -0
- package/node_modules/@oxygen/shared/dist/product-analytics-events.d.ts +36 -2
- package/node_modules/@oxygen/shared/dist/product-analytics-events.js +36 -1
- package/node_modules/@oxygen/shared/dist/rate-window.d.ts +5 -0
- package/node_modules/@oxygen/shared/dist/rate-window.js +8 -0
- package/node_modules/@oxygen/shared/dist/redaction.js +4 -1
- package/node_modules/@oxygen/shared/dist/research-output-contract.js +1 -3
- package/node_modules/@oxygen/shared/dist/scraper-lane-credential.d.ts +18 -0
- package/node_modules/@oxygen/shared/dist/scraper-lane-credential.js +23 -0
- package/node_modules/@oxygen/shared/dist/search-vocab.js +4 -5
- package/node_modules/@oxygen/shared/dist/select-options.js +6 -1
- package/node_modules/@oxygen/shared/dist/sequence-failures.js +1 -5
- package/node_modules/@oxygen/shared/dist/sequences.d.ts +23 -0
- package/node_modules/@oxygen/shared/dist/sequences.js +115 -5
- package/node_modules/@oxygen/shared/dist/signup-lead-payload.d.ts +80 -0
- package/node_modules/@oxygen/shared/dist/signup-lead-payload.js +198 -0
- package/node_modules/@oxygen/shared/dist/social-capabilities.d.ts +6 -0
- package/node_modules/@oxygen/shared/dist/social-capabilities.js +25 -16
- package/node_modules/@oxygen/shared/dist/social-post-metrics-core.d.ts +32 -0
- package/node_modules/@oxygen/shared/dist/social-post-metrics-core.js +32 -0
- package/node_modules/@oxygen/shared/dist/social-post-metrics-linkedin.d.ts +31 -0
- package/node_modules/@oxygen/shared/dist/social-post-metrics-linkedin.js +103 -0
- package/node_modules/@oxygen/shared/dist/social-post-metrics-series.d.ts +96 -0
- package/node_modules/@oxygen/shared/dist/social-post-metrics-series.js +213 -0
- package/node_modules/@oxygen/shared/dist/social-post-metrics-x.d.ts +13 -0
- package/node_modules/@oxygen/shared/dist/social-post-metrics-x.js +78 -0
- package/node_modules/@oxygen/shared/dist/social-post-metrics.d.ts +36 -0
- package/node_modules/@oxygen/shared/dist/social-post-metrics.js +51 -0
- package/node_modules/@oxygen/shared/dist/spend-safety.d.ts +22 -10
- package/node_modules/@oxygen/shared/dist/spend-safety.js +15 -21
- package/node_modules/@oxygen/shared/dist/sql-rows.d.ts +1 -0
- package/node_modules/@oxygen/shared/dist/sql-rows.js +3 -0
- package/node_modules/@oxygen/shared/dist/stripe-price-catalog.d.ts +36 -0
- package/node_modules/@oxygen/shared/dist/stripe-price-catalog.js +184 -0
- package/node_modules/@oxygen/shared/dist/stripe-subscription-kind.d.ts +41 -0
- package/node_modules/@oxygen/shared/dist/stripe-subscription-kind.js +44 -0
- package/node_modules/@oxygen/shared/dist/table-limits.d.ts +3 -0
- package/node_modules/@oxygen/shared/dist/table-limits.js +3 -0
- package/node_modules/@oxygen/shared/dist/telemetry-export-observer.d.ts +94 -0
- package/node_modules/@oxygen/shared/dist/telemetry-export-observer.js +298 -0
- package/node_modules/@oxygen/shared/dist/telemetry.d.ts +11 -0
- package/node_modules/@oxygen/shared/dist/telemetry.js +28 -2
- package/node_modules/@oxygen/shared/dist/type-guards.d.ts +22 -0
- package/node_modules/@oxygen/shared/dist/type-guards.js +35 -0
- package/node_modules/@oxygen/shared/dist/ugc.d.ts +22 -11
- package/node_modules/@oxygen/shared/dist/ugc.js +10 -0
- package/node_modules/@oxygen/shared/dist/value-readers.d.ts +21 -0
- package/node_modules/@oxygen/shared/dist/value-readers.js +59 -0
- package/node_modules/@oxygen/shared/dist/version.generated.d.ts +1 -0
- package/node_modules/@oxygen/shared/dist/version.generated.js +2 -0
- package/node_modules/@oxygen/shared/dist/version.js +8 -1
- package/node_modules/@oxygen/shared/dist/workspace-event-catalog.js +0 -23
- package/node_modules/@oxygen/shared/dist/workspace-file-storage.d.ts +29 -0
- package/node_modules/@oxygen/shared/dist/workspace-file-storage.js +31 -0
- package/node_modules/@oxygen/shared/package.json +59 -0
- package/node_modules/@oxygen/workflows/dist/graph/expression.js +2 -5
- package/node_modules/@oxygen/workflows/dist/graph/params.js +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,548 @@
|
|
|
1
|
+
// The company-enrichment FIELD CATALOG: every field the company waterfall can
|
|
2
|
+
// resolve, with the vocabulary every surface shows for it.
|
|
3
|
+
//
|
|
4
|
+
// This is the single source of truth for the field list. The waterfall engine
|
|
5
|
+
// (packages/integrations/src/company-enrichment-waterfall.ts) owns HOW a field
|
|
6
|
+
// is resolved — provider lanes, derived extractors, pricing — and reads its
|
|
7
|
+
// labels, column keys and data types from here; the CLI, the MCP descriptor,
|
|
8
|
+
// the `company_enrich` column preset (tenant-db) and the web column picker
|
|
9
|
+
// read the same catalog, so a field cannot exist on one surface and not
|
|
10
|
+
// another. Three hand-copied 8-entry enums drifted independently before this
|
|
11
|
+
// module existed (route, MCP schema, engine), and only the engine's was tested.
|
|
12
|
+
//
|
|
13
|
+
// CLIENT-SAFE LEAF: exported as the `@oxygen/shared/company-enrichment-fields`
|
|
14
|
+
// subpath and imported by browser components through the tenant-db preset
|
|
15
|
+
// module. It must never gain a runtime import.
|
|
16
|
+
export const COMPANY_ENRICHMENT_FIELD_CATEGORIES = [
|
|
17
|
+
"identity",
|
|
18
|
+
"firmographics",
|
|
19
|
+
"funding",
|
|
20
|
+
"relationships",
|
|
21
|
+
"signals",
|
|
22
|
+
"technology",
|
|
23
|
+
"web_presence",
|
|
24
|
+
];
|
|
25
|
+
export const COMPANY_ENRICHMENT_FIELD_CATEGORY_LABELS = {
|
|
26
|
+
identity: "Identity",
|
|
27
|
+
firmographics: "Firmographics",
|
|
28
|
+
funding: "Funding",
|
|
29
|
+
relationships: "Relationships",
|
|
30
|
+
signals: "Signals",
|
|
31
|
+
technology: "Technology",
|
|
32
|
+
web_presence: "Web presence",
|
|
33
|
+
};
|
|
34
|
+
const PROFILE_THEN_FUNDING = [
|
|
35
|
+
{ field: "company_profile", autoRun: true },
|
|
36
|
+
{ field: "funding", autoRun: false },
|
|
37
|
+
];
|
|
38
|
+
export const COMPANY_ENRICHMENT_FIELD_DEFINITIONS = [
|
|
39
|
+
// ── identity ─────────────────────────────────────────────────────────────
|
|
40
|
+
{
|
|
41
|
+
field: "domain",
|
|
42
|
+
label: "Company domain",
|
|
43
|
+
category: "identity",
|
|
44
|
+
description: "The company's website domain, resolved from its name or LinkedIn page.",
|
|
45
|
+
columnKey: "company_domain",
|
|
46
|
+
dataType: "text",
|
|
47
|
+
semanticType: "company.domain",
|
|
48
|
+
derivedFrom: [],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
field: "linkedin_url",
|
|
52
|
+
label: "Company LinkedIn URL",
|
|
53
|
+
category: "identity",
|
|
54
|
+
description: "The company's LinkedIn page, resolved from its domain or name.",
|
|
55
|
+
columnKey: "company_linkedin_url",
|
|
56
|
+
dataType: "text",
|
|
57
|
+
semanticType: "company.linkedin_url",
|
|
58
|
+
derivedFrom: [],
|
|
59
|
+
},
|
|
60
|
+
// ── firmographics ────────────────────────────────────────────────────────
|
|
61
|
+
{
|
|
62
|
+
field: "headcount",
|
|
63
|
+
label: "Headcount",
|
|
64
|
+
category: "firmographics",
|
|
65
|
+
description: "Employee count, exact when the provider has it, otherwise the size band.",
|
|
66
|
+
columnKey: "company_headcount",
|
|
67
|
+
dataType: "text",
|
|
68
|
+
semanticType: "company.employee_count",
|
|
69
|
+
derivedFrom: [],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
field: "industry",
|
|
73
|
+
label: "Industry",
|
|
74
|
+
category: "firmographics",
|
|
75
|
+
description: "The industry the company lists for itself.",
|
|
76
|
+
columnKey: "company_industry",
|
|
77
|
+
dataType: "text",
|
|
78
|
+
semanticType: "company.industry",
|
|
79
|
+
derivedFrom: [],
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
field: "company_profile",
|
|
83
|
+
label: "Company profile",
|
|
84
|
+
category: "firmographics",
|
|
85
|
+
description: "The whole provider profile as one record; the free fields below are read out of it.",
|
|
86
|
+
columnKey: "company_profile",
|
|
87
|
+
dataType: "jsonb",
|
|
88
|
+
semanticType: null,
|
|
89
|
+
derivedFrom: [],
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
field: "description",
|
|
93
|
+
label: "Description",
|
|
94
|
+
category: "firmographics",
|
|
95
|
+
description: "The company's own about text, read from the profile already fetched.",
|
|
96
|
+
columnKey: "company_description",
|
|
97
|
+
dataType: "text",
|
|
98
|
+
semanticType: "company.description",
|
|
99
|
+
derivedFrom: PROFILE_THEN_FUNDING,
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
field: "founded_year",
|
|
103
|
+
label: "Founded year",
|
|
104
|
+
category: "firmographics",
|
|
105
|
+
description: "The year the company was founded, read from the profile already fetched.",
|
|
106
|
+
columnKey: "company_founded_year",
|
|
107
|
+
dataType: "numeric",
|
|
108
|
+
semanticType: "company.founded_year",
|
|
109
|
+
derivedFrom: PROFILE_THEN_FUNDING,
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
field: "hq_address",
|
|
113
|
+
label: "HQ address",
|
|
114
|
+
category: "firmographics",
|
|
115
|
+
description: "Headquarters street, city and country as one line, from the profile already fetched.",
|
|
116
|
+
columnKey: "company_hq_address",
|
|
117
|
+
dataType: "text",
|
|
118
|
+
semanticType: "company.hq_location",
|
|
119
|
+
derivedFrom: PROFILE_THEN_FUNDING,
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
field: "hq_country",
|
|
123
|
+
label: "HQ country",
|
|
124
|
+
category: "firmographics",
|
|
125
|
+
description: "Headquarters country, from the profile already fetched.",
|
|
126
|
+
columnKey: "company_hq_country",
|
|
127
|
+
dataType: "text",
|
|
128
|
+
semanticType: "company.hq_country",
|
|
129
|
+
derivedFrom: PROFILE_THEN_FUNDING,
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
field: "company_type",
|
|
133
|
+
label: "Company type",
|
|
134
|
+
category: "firmographics",
|
|
135
|
+
description: "Privately held, public, non-profit and the like, from the profile already fetched.",
|
|
136
|
+
columnKey: "company_type",
|
|
137
|
+
dataType: "text",
|
|
138
|
+
semanticType: null,
|
|
139
|
+
derivedFrom: PROFILE_THEN_FUNDING,
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
field: "specialties",
|
|
143
|
+
label: "Specialties",
|
|
144
|
+
category: "firmographics",
|
|
145
|
+
description: "The specialties or keywords the company lists, from the profile already fetched.",
|
|
146
|
+
columnKey: "company_specialties",
|
|
147
|
+
dataType: "jsonb",
|
|
148
|
+
semanticType: "company.specialties",
|
|
149
|
+
derivedFrom: [{ field: "company_profile", autoRun: true }],
|
|
150
|
+
},
|
|
151
|
+
// ── funding ──────────────────────────────────────────────────────────────
|
|
152
|
+
{
|
|
153
|
+
field: "funding",
|
|
154
|
+
label: "Funding",
|
|
155
|
+
category: "funding",
|
|
156
|
+
description: "The raw funding record from a funding provider: rounds, amounts, investors, total.",
|
|
157
|
+
columnKey: "company_funding",
|
|
158
|
+
dataType: "jsonb",
|
|
159
|
+
semanticType: null,
|
|
160
|
+
derivedFrom: [],
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
field: "revenue",
|
|
164
|
+
label: "Revenue (estimate)",
|
|
165
|
+
category: "funding",
|
|
166
|
+
description: "Estimated annual revenue, a figure when the source has one, otherwise a range band.",
|
|
167
|
+
columnKey: "company_revenue",
|
|
168
|
+
dataType: "text",
|
|
169
|
+
semanticType: "company.revenue",
|
|
170
|
+
derivedFrom: [],
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
field: "funding_stage",
|
|
174
|
+
label: "Funding stage",
|
|
175
|
+
category: "funding",
|
|
176
|
+
description: "The latest round's type, e.g. Seed or Series B; free when the LinkedIn page lists funding.",
|
|
177
|
+
columnKey: "company_funding_stage",
|
|
178
|
+
dataType: "text",
|
|
179
|
+
semanticType: null,
|
|
180
|
+
derivedFrom: PROFILE_THEN_FUNDING,
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
field: "latest_funding_round",
|
|
184
|
+
label: "Latest funding round",
|
|
185
|
+
category: "funding",
|
|
186
|
+
description: "Date, amount, round type and lead investors of the most recent round.",
|
|
187
|
+
columnKey: "company_latest_funding_round",
|
|
188
|
+
dataType: "jsonb",
|
|
189
|
+
semanticType: null,
|
|
190
|
+
derivedFrom: PROFILE_THEN_FUNDING,
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
field: "total_funding",
|
|
194
|
+
label: "Total funding",
|
|
195
|
+
category: "funding",
|
|
196
|
+
description: "Total raised to date in USD, from a funding provider (LinkedIn does not publish it).",
|
|
197
|
+
columnKey: "company_total_funding",
|
|
198
|
+
dataType: "numeric",
|
|
199
|
+
semanticType: "company.funding_raised",
|
|
200
|
+
derivedFrom: [
|
|
201
|
+
{ field: "funding", autoRun: true },
|
|
202
|
+
{ field: "company_profile", autoRun: false },
|
|
203
|
+
],
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
field: "funding_rounds_count",
|
|
207
|
+
label: "Number of funding rounds",
|
|
208
|
+
category: "funding",
|
|
209
|
+
description: "How many rounds the company has raised.",
|
|
210
|
+
columnKey: "company_funding_rounds_count",
|
|
211
|
+
dataType: "numeric",
|
|
212
|
+
semanticType: null,
|
|
213
|
+
derivedFrom: PROFILE_THEN_FUNDING,
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
field: "investors",
|
|
217
|
+
label: "Investors",
|
|
218
|
+
category: "funding",
|
|
219
|
+
description: "Named investors across the rounds a provider knows about.",
|
|
220
|
+
columnKey: "company_investors",
|
|
221
|
+
dataType: "jsonb",
|
|
222
|
+
semanticType: null,
|
|
223
|
+
derivedFrom: PROFILE_THEN_FUNDING,
|
|
224
|
+
},
|
|
225
|
+
// ── relationships ────────────────────────────────────────────────────────
|
|
226
|
+
{
|
|
227
|
+
field: "competitors",
|
|
228
|
+
label: "Competitors",
|
|
229
|
+
category: "relationships",
|
|
230
|
+
description: "Named competitors from a funding-intelligence provider; LinkedIn's similar pages when the profile is already on the row.",
|
|
231
|
+
columnKey: "company_competitors",
|
|
232
|
+
dataType: "jsonb",
|
|
233
|
+
semanticType: null,
|
|
234
|
+
derivedFrom: [
|
|
235
|
+
{ field: "funding", autoRun: false },
|
|
236
|
+
{ field: "company_profile", autoRun: false },
|
|
237
|
+
],
|
|
238
|
+
availability: "coming_soon",
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
field: "corporate_structure",
|
|
242
|
+
label: "Corporate structure",
|
|
243
|
+
category: "relationships",
|
|
244
|
+
description: "Parent company and subsidiaries as one record.",
|
|
245
|
+
columnKey: "company_corporate_structure",
|
|
246
|
+
dataType: "jsonb",
|
|
247
|
+
semanticType: null,
|
|
248
|
+
derivedFrom: [],
|
|
249
|
+
availability: "coming_soon",
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
field: "parent_company",
|
|
253
|
+
label: "Parent company",
|
|
254
|
+
category: "relationships",
|
|
255
|
+
description: "The company that owns this one, read from the corporate structure lookup.",
|
|
256
|
+
columnKey: "company_parent_company",
|
|
257
|
+
dataType: "text",
|
|
258
|
+
semanticType: null,
|
|
259
|
+
derivedFrom: [{ field: "corporate_structure", autoRun: true }],
|
|
260
|
+
availability: "coming_soon",
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
field: "subsidiaries",
|
|
264
|
+
label: "Subsidiaries",
|
|
265
|
+
category: "relationships",
|
|
266
|
+
description: "Companies this one owns, read from the corporate structure lookup.",
|
|
267
|
+
columnKey: "company_subsidiaries",
|
|
268
|
+
dataType: "jsonb",
|
|
269
|
+
semanticType: null,
|
|
270
|
+
derivedFrom: [{ field: "corporate_structure", autoRun: true }],
|
|
271
|
+
availability: "coming_soon",
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
field: "acquisitions",
|
|
275
|
+
label: "Acquisitions",
|
|
276
|
+
category: "relationships",
|
|
277
|
+
description: "Companies this one has acquired, with dates and sources.",
|
|
278
|
+
columnKey: "company_acquisitions",
|
|
279
|
+
dataType: "jsonb",
|
|
280
|
+
semanticType: null,
|
|
281
|
+
derivedFrom: [{ field: "funding", autoRun: false }],
|
|
282
|
+
availability: "coming_soon",
|
|
283
|
+
},
|
|
284
|
+
// ── signals ──────────────────────────────────────────────────────────────
|
|
285
|
+
{
|
|
286
|
+
field: "news",
|
|
287
|
+
label: "News",
|
|
288
|
+
category: "signals",
|
|
289
|
+
description: "Recent dated news items about the company.",
|
|
290
|
+
columnKey: "company_news",
|
|
291
|
+
dataType: "jsonb",
|
|
292
|
+
semanticType: null,
|
|
293
|
+
derivedFrom: [{ field: "funding", autoRun: false }],
|
|
294
|
+
availability: "coming_soon",
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
field: "hiring_signals",
|
|
298
|
+
label: "Hiring signals",
|
|
299
|
+
category: "signals",
|
|
300
|
+
description: "The raw open-roles payload from a jobs provider.",
|
|
301
|
+
columnKey: "company_hiring_signals",
|
|
302
|
+
dataType: "jsonb",
|
|
303
|
+
semanticType: null,
|
|
304
|
+
derivedFrom: [],
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
field: "job_openings",
|
|
308
|
+
label: "Job openings",
|
|
309
|
+
category: "signals",
|
|
310
|
+
description: "Open roles from the hiring lookup, listed (up to ten) with a count.",
|
|
311
|
+
columnKey: "company_job_openings",
|
|
312
|
+
dataType: "jsonb",
|
|
313
|
+
semanticType: null,
|
|
314
|
+
derivedFrom: [{ field: "hiring_signals", autoRun: true }],
|
|
315
|
+
},
|
|
316
|
+
// ── technology ───────────────────────────────────────────────────────────
|
|
317
|
+
{
|
|
318
|
+
field: "technologies",
|
|
319
|
+
label: "Tech stack",
|
|
320
|
+
category: "technology",
|
|
321
|
+
description: "Technologies the company runs, from its job postings (with confidence and first/last-seen dates) or its website.",
|
|
322
|
+
columnKey: "company_technologies",
|
|
323
|
+
dataType: "jsonb",
|
|
324
|
+
semanticType: null,
|
|
325
|
+
derivedFrom: [],
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
field: "technology_check",
|
|
329
|
+
label: "Technology check",
|
|
330
|
+
category: "technology",
|
|
331
|
+
description: "Yes or no per technology you name, checked against the detected stack.",
|
|
332
|
+
columnKey: "company_technology_check",
|
|
333
|
+
dataType: "jsonb",
|
|
334
|
+
semanticType: null,
|
|
335
|
+
derivedFrom: [{ field: "technologies", autoRun: true }],
|
|
336
|
+
requires: "check_technologies",
|
|
337
|
+
},
|
|
338
|
+
// ── web presence ─────────────────────────────────────────────────────────
|
|
339
|
+
{
|
|
340
|
+
field: "logo_url",
|
|
341
|
+
label: "Logo",
|
|
342
|
+
category: "web_presence",
|
|
343
|
+
description: "The company logo image URL, from the profile already fetched.",
|
|
344
|
+
columnKey: "company_logo_url",
|
|
345
|
+
dataType: "text",
|
|
346
|
+
semanticType: "company.logo_url",
|
|
347
|
+
derivedFrom: [{ field: "company_profile", autoRun: true }],
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
field: "crunchbase_url",
|
|
351
|
+
label: "Crunchbase URL",
|
|
352
|
+
category: "web_presence",
|
|
353
|
+
description: "The company's Crunchbase page; free when the LinkedIn page links it, otherwise one web search.",
|
|
354
|
+
columnKey: "company_crunchbase_url",
|
|
355
|
+
dataType: "text",
|
|
356
|
+
semanticType: null,
|
|
357
|
+
derivedFrom: [
|
|
358
|
+
{ field: "company_profile", autoRun: false },
|
|
359
|
+
{ field: "funding", autoRun: false },
|
|
360
|
+
],
|
|
361
|
+
availability: "coming_soon",
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
field: "github_url",
|
|
365
|
+
label: "GitHub URL",
|
|
366
|
+
category: "web_presence",
|
|
367
|
+
description: "The company's GitHub organization, found by one site-scoped web search.",
|
|
368
|
+
columnKey: "company_github_url",
|
|
369
|
+
dataType: "text",
|
|
370
|
+
semanticType: null,
|
|
371
|
+
derivedFrom: [],
|
|
372
|
+
availability: "coming_soon",
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
field: "facebook_url",
|
|
376
|
+
label: "Facebook URL",
|
|
377
|
+
category: "web_presence",
|
|
378
|
+
description: "The company's Facebook page, found by one site-scoped web search.",
|
|
379
|
+
columnKey: "company_facebook_url",
|
|
380
|
+
dataType: "text",
|
|
381
|
+
semanticType: "company.facebook_url",
|
|
382
|
+
derivedFrom: [{ field: "funding", autoRun: false }],
|
|
383
|
+
availability: "coming_soon",
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
field: "instagram_url",
|
|
387
|
+
label: "Instagram URL",
|
|
388
|
+
category: "web_presence",
|
|
389
|
+
description: "The company's Instagram profile, found by one site-scoped web search.",
|
|
390
|
+
columnKey: "company_instagram_url",
|
|
391
|
+
dataType: "text",
|
|
392
|
+
semanticType: "company.instagram_url",
|
|
393
|
+
derivedFrom: [],
|
|
394
|
+
availability: "coming_soon",
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
field: "youtube_url",
|
|
398
|
+
label: "YouTube URL",
|
|
399
|
+
category: "web_presence",
|
|
400
|
+
description: "The company's YouTube channel, found by one site-scoped web search.",
|
|
401
|
+
columnKey: "company_youtube_url",
|
|
402
|
+
dataType: "text",
|
|
403
|
+
semanticType: null,
|
|
404
|
+
derivedFrom: [],
|
|
405
|
+
availability: "coming_soon",
|
|
406
|
+
},
|
|
407
|
+
];
|
|
408
|
+
export const COMPANY_ENRICHMENT_FIELD_KEYS = COMPANY_ENRICHMENT_FIELD_DEFINITIONS.map((definition) => definition.field);
|
|
409
|
+
const DEFINITIONS_BY_FIELD = new Map(COMPANY_ENRICHMENT_FIELD_DEFINITIONS.map((definition) => [definition.field, definition]));
|
|
410
|
+
export function isCompanyEnrichmentFieldKey(value) {
|
|
411
|
+
return DEFINITIONS_BY_FIELD.has(value);
|
|
412
|
+
}
|
|
413
|
+
export function companyEnrichmentFieldDefinition(field) {
|
|
414
|
+
const definition = DEFINITIONS_BY_FIELD.get(field);
|
|
415
|
+
if (!definition)
|
|
416
|
+
throw new Error(`Unknown company enrichment field "${field}".`);
|
|
417
|
+
return definition;
|
|
418
|
+
}
|
|
419
|
+
/** D51: a field parked `coming_soon` has no lane, no picker group and is refused by `--fields`. */
|
|
420
|
+
export function isComingSoonCompanyEnrichmentField(field) {
|
|
421
|
+
return companyEnrichmentFieldDefinition(field).availability === "coming_soon";
|
|
422
|
+
}
|
|
423
|
+
/** A field whose value is read out of another field's payload, never a provider call of its own. */
|
|
424
|
+
export function isDerivedCompanyEnrichmentField(field) {
|
|
425
|
+
return companyEnrichmentFieldDefinition(field).derivedFrom.length > 0;
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* What `find company` resolves when the caller names no fields. Identity plus
|
|
429
|
+
* the firmographics that cost nothing beyond the one profile lookup the
|
|
430
|
+
* headcount/industry lanes already make; funding, relationship and web-presence
|
|
431
|
+
* fields stay opt-in because each adds a priced lane.
|
|
432
|
+
*/
|
|
433
|
+
export const DEFAULT_COMPANY_FIND_FIELDS = [
|
|
434
|
+
"domain",
|
|
435
|
+
"linkedin_url",
|
|
436
|
+
"headcount",
|
|
437
|
+
"industry",
|
|
438
|
+
"description",
|
|
439
|
+
"founded_year",
|
|
440
|
+
"hq_country",
|
|
441
|
+
];
|
|
442
|
+
/**
|
|
443
|
+
* What `columns add --preset company_enrich` creates when the caller names no
|
|
444
|
+
* fields: the identity/firmographic set plus the full profile and what it says
|
|
445
|
+
* about the company. Every lane-priced relationship, funding, signal,
|
|
446
|
+
* technology and web-presence field is opt-in through `--fields`, so the
|
|
447
|
+
* default bundle's per-row ceiling stays the profile chain's.
|
|
448
|
+
*
|
|
449
|
+
* Funding stage and latest round left the default on 2026-09-24 (founder, D55):
|
|
450
|
+
* the profile lane is Blitz first now, and Blitz's company profile carries no
|
|
451
|
+
* funding, so on the rows Blitz answers those two columns would sit empty. They
|
|
452
|
+
* live in the Funding details group instead.
|
|
453
|
+
*/
|
|
454
|
+
export const DEFAULT_COMPANY_PRESET_FIELDS = [
|
|
455
|
+
"domain",
|
|
456
|
+
"linkedin_url",
|
|
457
|
+
"headcount",
|
|
458
|
+
"industry",
|
|
459
|
+
"company_profile",
|
|
460
|
+
"description",
|
|
461
|
+
"founded_year",
|
|
462
|
+
"hq_country",
|
|
463
|
+
];
|
|
464
|
+
/**
|
|
465
|
+
* The opt-in company fields, grouped the way a customer asks for them ("add
|
|
466
|
+
* competitors", "add their tech stack"). Every surface that offers a company
|
|
467
|
+
* field beyond the default bundle reads THIS list: the enrichment column catalog
|
|
468
|
+
* (`oxygen enrichment catalog`, `oxygen_enrichment_catalog`), the web add-column
|
|
469
|
+
* picker, and the catalog pricing. Adding a group adds its fields to the SAME
|
|
470
|
+
* company enrichment column — re-applying the bundle widens the existing
|
|
471
|
+
* column's field list instead of creating a second paid column.
|
|
472
|
+
*/
|
|
473
|
+
export const COMPANY_ENRICHMENT_FIELD_GROUPS = [
|
|
474
|
+
{
|
|
475
|
+
id: "profile_details",
|
|
476
|
+
label: "Company profile details",
|
|
477
|
+
description: "HQ address, company type, specialties and logo, read from the company profile the bundle already fetches.",
|
|
478
|
+
fields: ["hq_address", "company_type", "specialties", "logo_url"],
|
|
479
|
+
cost: "included",
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
id: "funding_details",
|
|
483
|
+
label: "Funding details",
|
|
484
|
+
description: "Funding stage, latest round, total raised, number of rounds and investors, with the full funding history kept alongside.",
|
|
485
|
+
fields: ["funding", "revenue", "funding_stage", "latest_funding_round", "total_funding", "funding_rounds_count", "investors"],
|
|
486
|
+
cost: "extra",
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
id: "job_openings",
|
|
490
|
+
label: "Job openings",
|
|
491
|
+
description: "The roles each account is hiring for, as a count and a list.",
|
|
492
|
+
fields: ["hiring_signals", "job_openings"],
|
|
493
|
+
cost: "extra",
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
id: "tech_stack",
|
|
497
|
+
label: "Tech stack",
|
|
498
|
+
description: "The technologies each account runs, from its job postings (with confidence and first/last seen) or its website.",
|
|
499
|
+
fields: ["technologies"],
|
|
500
|
+
cost: "extra",
|
|
501
|
+
},
|
|
502
|
+
{
|
|
503
|
+
id: "technology_check",
|
|
504
|
+
label: "Technology check",
|
|
505
|
+
description: "Yes or no per account for each technology you name, such as HubSpot or Salesforce.",
|
|
506
|
+
fields: ["technology_check"],
|
|
507
|
+
cost: "extra",
|
|
508
|
+
requires: "check_technologies",
|
|
509
|
+
},
|
|
510
|
+
];
|
|
511
|
+
export function companyEnrichmentFieldGroup(id) {
|
|
512
|
+
return COMPANY_ENRICHMENT_FIELD_GROUPS.find((group) => group.id === id) ?? null;
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Parse a comma-separated or array field list against the catalog. Returns the
|
|
516
|
+
* unique, lowercased keys in request order, or throws naming every unknown
|
|
517
|
+
* entry with the supported list — never a silent fallback to a default set,
|
|
518
|
+
* which is how `--fields tech,hiring,profile` once ran the four default fields
|
|
519
|
+
* and billed for an answer nobody asked for (OXP-7.2.9).
|
|
520
|
+
*/
|
|
521
|
+
export function parseCompanyEnrichmentFieldList(value) {
|
|
522
|
+
const entries = Array.isArray(value)
|
|
523
|
+
? value
|
|
524
|
+
: typeof value === "string"
|
|
525
|
+
? value.split(",")
|
|
526
|
+
: [];
|
|
527
|
+
const cleaned = entries
|
|
528
|
+
.map((entry) => (typeof entry === "string" ? entry.trim().toLowerCase() : ""))
|
|
529
|
+
.filter((entry) => entry.length > 0);
|
|
530
|
+
const fields = [];
|
|
531
|
+
const unknown = [];
|
|
532
|
+
const coming_soon = [];
|
|
533
|
+
for (const entry of cleaned) {
|
|
534
|
+
if (isCompanyEnrichmentFieldKey(entry)) {
|
|
535
|
+
if (isComingSoonCompanyEnrichmentField(entry)) {
|
|
536
|
+
if (!coming_soon.includes(entry))
|
|
537
|
+
coming_soon.push(entry);
|
|
538
|
+
}
|
|
539
|
+
else if (!fields.includes(entry)) {
|
|
540
|
+
fields.push(entry);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
else if (!unknown.includes(entry)) {
|
|
544
|
+
unknown.push(entry);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
return { fields, unknown, coming_soon };
|
|
548
|
+
}
|