higherdata 0.4.0 → 0.5.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 (3) hide show
  1. package/README.md +8 -0
  2. package/dist/index.js +513 -100
  3. package/package.json +4 -1
package/README.md CHANGED
@@ -251,3 +251,11 @@ higherdata config set auto-update true
251
251
  Explicit `higherdata update` remains available with an opt-out or a server
252
252
  minimum-version refusal. Users on 0.3.0 must reinstall once to obtain the update
253
253
  command: `npm install --global higherdata@latest`.
254
+
255
+ ### Credentials and diagnostics
256
+
257
+ The CLI stores saved API keys in macOS Keychain, Windows Credential Manager, or Linux Secret Service (for example GNOME Keyring or KWallet). Existing plaintext profiles migrate on first use. Config files retain only a keychain reference. On platforms without a supported keychain, or when a persistent Linux service is absent, the CLI keeps the existing file fallback with mode 0600. A missing native binding, locked store or inaccessible keychain returns an error rather than downgrading credentials. `higherdata logout` removes the active profile's keychain entry. `HIGHERDATA_API_KEY` remains available for CI.
258
+
259
+ Server failures print the error code, user-safe message and request id to stderr. JSON and JSONL results stay on stdout. Non-interactive commands also print a one-line newer-version notice on stderr using the existing daily compatibility check.
260
+
261
+ When `higherdata tools email.find` returns `status: ambiguous`, select an opaque id from `companyCandidates` and retry with `--company-id`. This choice does not submit verification requests. An exact match to one primary domain is selected automatically when the complete company match set is available.
package/dist/index.js CHANGED
@@ -20487,11 +20487,50 @@ var init_zod = __esm({
20487
20487
  }
20488
20488
  });
20489
20489
 
20490
+ // src/keychain.ts
20491
+ async function nativeKeychain(platform = process.platform, load = () => import("@napi-rs/keyring")) {
20492
+ if (!["darwin", "linux", "win32"].includes(platform)) return null;
20493
+ let binding;
20494
+ try {
20495
+ binding = await load();
20496
+ } catch {
20497
+ return null;
20498
+ }
20499
+ const entry = (account) => new binding.AsyncEntry(service, account, { linux: { store: "secret-service" } });
20500
+ try {
20501
+ entry("availability");
20502
+ } catch (error63) {
20503
+ const message = error63 instanceof Error ? error63.message : "";
20504
+ if (platform === "linux" && /org\.freedesktop\.DBus\.Error\.(?:ServiceUnknown|NameHasNoOwner)|DBUS_SESSION_BUS_ADDRESS|Unable to autolaunch a dbus-daemon|Failed to connect to socket|No such file or directory/u.test(message)) return null;
20505
+ throw error63;
20506
+ }
20507
+ return {
20508
+ get: (account) => entry(account).getPassword(AbortSignal.timeout(3e3)),
20509
+ set: (account, secret) => entry(account).setPassword(secret, AbortSignal.timeout(3e3)),
20510
+ remove: async (account) => {
20511
+ await entry(account).deleteCredential(AbortSignal.timeout(3e3));
20512
+ }
20513
+ };
20514
+ }
20515
+ var service, systemKeychain;
20516
+ var init_keychain = __esm({
20517
+ "src/keychain.ts"() {
20518
+ "use strict";
20519
+ service = "io.higherdata.cli";
20520
+ systemKeychain = () => nativeKeychain();
20521
+ }
20522
+ });
20523
+
20490
20524
  // src/config.ts
20491
20525
  import { chmod, mkdir, open as open2, readFile, rename, unlink } from "fs/promises";
20492
20526
  import { homedir } from "os";
20493
20527
  import { dirname, join } from "path";
20494
20528
  import { randomUUID } from "crypto";
20529
+ function warnAboutFileKeychainFallback() {
20530
+ if (warnedAboutFileKeychainFallback) return;
20531
+ warnedAboutFileKeychainFallback = true;
20532
+ process.stderr.write("HigherData could not access a system keychain. Credentials will be stored in the config file with 0600 permissions.\n");
20533
+ }
20495
20534
  function configPath(home = homedir()) {
20496
20535
  return join(home, ".config", "higherdata", "config.json");
20497
20536
  }
@@ -20500,7 +20539,7 @@ function validateConfig(value) {
20500
20539
  if (!result.success) throw new ConfigError("Invalid HigherData config: check profiles and activeProfile");
20501
20540
  return result.data;
20502
20541
  }
20503
- async function readConfig(path2 = configPath()) {
20542
+ async function readDiskConfig(path2) {
20504
20543
  let contents2;
20505
20544
  try {
20506
20545
  contents2 = await readFile(path2, "utf8");
@@ -20519,8 +20558,56 @@ async function readConfig(path2 = configPath()) {
20519
20558
  }
20520
20559
  return validateConfig(value);
20521
20560
  }
20522
- async function writeConfig(config2, path2 = configPath()) {
20561
+ async function readConfig(path2 = configPath(), loadKeychain = systemKeychain) {
20562
+ let config2 = await readDiskConfig(path2);
20563
+ if (!Object.values(config2.profiles).some((profile) => profile.apiKey || profile.keychainId)) return config2;
20564
+ try {
20565
+ const keychain = await loadKeychain();
20566
+ const migrate = keychain && Object.values(config2.profiles).some((profile) => profile.apiKey);
20567
+ for (const profile of Object.values(config2.profiles)) {
20568
+ if (!profile.keychainId) continue;
20569
+ if (!keychain) throw new Error();
20570
+ const secret = await keychain.get(profile.keychainId);
20571
+ if (secret) profile.apiKey = secret;
20572
+ else delete profile.apiKey;
20573
+ }
20574
+ if (migrate) {
20575
+ await writeConfig(config2, path2, async () => keychain);
20576
+ config2 = await readConfig(path2, async () => keychain);
20577
+ }
20578
+ return config2;
20579
+ } catch {
20580
+ throw new ConfigError("Cannot access the HigherData keychain. Unlock it or restore access before retrying.");
20581
+ }
20582
+ }
20583
+ async function writeConfig(config2, path2 = configPath(), loadKeychain = systemKeychain) {
20523
20584
  const value = validateConfig(config2);
20585
+ const previous = await readDiskConfig(path2);
20586
+ const profiles = Object.values(value.profiles);
20587
+ const previousIds = Object.values(previous.profiles).flatMap((profile) => profile.keychainId ? [profile.keychainId] : []);
20588
+ if (profiles.some((profile) => profile.apiKey || profile.keychainId) || previousIds.length) {
20589
+ try {
20590
+ const keychain = await loadKeychain();
20591
+ if (!keychain && (previousIds.length || profiles.some((profile) => profile.keychainId))) throw new Error();
20592
+ if (!keychain && profiles.some((profile) => profile.apiKey)) warnAboutFileKeychainFallback();
20593
+ if (keychain) {
20594
+ for (const profile of profiles) {
20595
+ if (profile.apiKey) {
20596
+ profile.keychainId ??= randomUUID();
20597
+ await keychain.set(profile.keychainId, profile.apiKey);
20598
+ delete profile.apiKey;
20599
+ } else if (profile.keychainId) {
20600
+ if (!previousIds.includes(profile.keychainId)) await keychain.remove(profile.keychainId);
20601
+ delete profile.keychainId;
20602
+ }
20603
+ }
20604
+ const retained = new Set(profiles.map((profile) => profile.keychainId));
20605
+ for (const id of previousIds) if (!retained.has(id)) await keychain.remove(id);
20606
+ }
20607
+ } catch {
20608
+ throw new ConfigError("Cannot update the HigherData keychain. Unlock it or restore access before retrying.");
20609
+ }
20610
+ }
20524
20611
  await mkdir(dirname(path2), { recursive: true, mode: 448 });
20525
20612
  const temporaryPath = `${path2}.${randomUUID()}.tmp`;
20526
20613
  try {
@@ -20552,11 +20639,12 @@ function resolveSettings(config2, options = {}, env = process.env) {
20552
20639
  space: profile.space
20553
20640
  };
20554
20641
  }
20555
- var DEFAULT_API_URL, apiUrlSchema, profileSchema, configSchema, ConfigError;
20642
+ var DEFAULT_API_URL, apiUrlSchema, profileSchema, configSchema, ConfigError, warnedAboutFileKeychainFallback;
20556
20643
  var init_config = __esm({
20557
20644
  "src/config.ts"() {
20558
20645
  "use strict";
20559
20646
  init_zod();
20647
+ init_keychain();
20560
20648
  DEFAULT_API_URL = "https://higherdata.io";
20561
20649
  apiUrlSchema = external_exports.url().refine((value) => {
20562
20650
  try {
@@ -20570,6 +20658,7 @@ var init_config = __esm({
20570
20658
  profileSchema = external_exports.strictObject({
20571
20659
  apiUrl: apiUrlSchema.optional(),
20572
20660
  apiKey: external_exports.string().min(1).optional(),
20661
+ keychainId: external_exports.uuid().optional(),
20573
20662
  space: external_exports.string().min(1).optional()
20574
20663
  });
20575
20664
  configSchema = external_exports.strictObject({
@@ -20585,6 +20674,7 @@ var init_config = __esm({
20585
20674
  this.name = "ConfigError";
20586
20675
  }
20587
20676
  };
20677
+ warnedAboutFileKeychainFallback = false;
20588
20678
  }
20589
20679
  });
20590
20680
 
@@ -21657,6 +21747,11 @@ var init_generated = __esm({
21657
21747
  "type": "string",
21658
21748
  "maxLength": 120
21659
21749
  },
21750
+ "domain": {
21751
+ "description": "Exact normalized company domain. Company searches only.",
21752
+ "type": "string",
21753
+ "maxLength": 253
21754
+ },
21660
21755
  "missingField": {
21661
21756
  "description": "Only records with an empty synced property.",
21662
21757
  "type": "string",
@@ -21939,6 +22034,44 @@ var init_generated = __esm({
21939
22034
  "additionalProperties": false
21940
22035
  }
21941
22036
  },
22037
+ {
22038
+ "name": "crm.list_enrichment_jobs",
22039
+ "description": "List your CRM enrichment previews and proposal jobs in this space, newest first. History contains no record samples.",
22040
+ "risk": "read",
22041
+ "scopes": [
22042
+ "crm:write"
22043
+ ],
22044
+ "input": {
22045
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
22046
+ "type": "object",
22047
+ "properties": {
22048
+ "cursor": {
22049
+ "description": "Continuation from the previous history page.",
22050
+ "type": "object",
22051
+ "properties": {
22052
+ "createdAt": {
22053
+ "type": "string",
22054
+ "format": "date-time",
22055
+ "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
22056
+ "description": "Creation time of the last job on the previous page."
22057
+ },
22058
+ "id": {
22059
+ "type": "string",
22060
+ "format": "uuid",
22061
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
22062
+ "description": "Id of the last job on the previous page."
22063
+ }
22064
+ },
22065
+ "required": [
22066
+ "createdAt",
22067
+ "id"
22068
+ ],
22069
+ "additionalProperties": false
22070
+ }
22071
+ },
22072
+ "additionalProperties": false
22073
+ }
22074
+ },
21942
22075
  {
21943
22076
  "name": "crm.push",
21944
22077
  "description": "Propose CRM changes for human review. Creates a pending-approval change set. It never dispatches a HubSpot write; approve fields and call changes.apply separately. Dry run returns the proposal only.",
@@ -22339,6 +22472,11 @@ var init_generated = __esm({
22339
22472
  "type": "string",
22340
22473
  "maxLength": 120
22341
22474
  },
22475
+ "domain": {
22476
+ "description": "Exact normalized company domain. Company searches only.",
22477
+ "type": "string",
22478
+ "maxLength": 253
22479
+ },
22342
22480
  "missingField": {
22343
22481
  "description": "Only records with an empty synced property.",
22344
22482
  "type": "string",
@@ -24895,6 +25033,36 @@ var init_generated = __esm({
24895
25033
  "filters": {
24896
25034
  "type": "object",
24897
25035
  "properties": {
25036
+ "companyNames": {
25037
+ "description": "Company name prefixes. Match any name.",
25038
+ "minItems": 1,
25039
+ "maxItems": 5,
25040
+ "type": "array",
25041
+ "items": {
25042
+ "type": "string",
25043
+ "minLength": 1,
25044
+ "maxLength": 120,
25045
+ "pattern": "\\S"
25046
+ }
25047
+ },
25048
+ "excludeCompanyNames": {
25049
+ "description": "Company name prefixes to leave out.",
25050
+ "minItems": 1,
25051
+ "maxItems": 5,
25052
+ "type": "array",
25053
+ "items": {
25054
+ "type": "string",
25055
+ "minLength": 1,
25056
+ "maxLength": 120,
25057
+ "pattern": "\\S"
25058
+ }
25059
+ },
25060
+ "domain": {
25061
+ "description": "Company website domain. Exact host matching; root sites rank first.",
25062
+ "type": "string",
25063
+ "minLength": 1,
25064
+ "maxLength": 320
25065
+ },
24898
25066
  "countryCodes": {
24899
25067
  "description": "Two-letter country codes to include.",
24900
25068
  "minItems": 1,
@@ -25066,9 +25234,7 @@ var init_generated = __esm({
25066
25234
  "type": "array",
25067
25235
  "items": {
25068
25236
  "type": "string",
25069
- "minLength": 1,
25070
- "maxLength": 120,
25071
- "pattern": "\\S"
25237
+ "pattern": "^[0-9]{6}$"
25072
25238
  }
25073
25239
  },
25074
25240
  "excludeNaics2022Codes": {
@@ -25078,9 +25244,7 @@ var init_generated = __esm({
25078
25244
  "type": "array",
25079
25245
  "items": {
25080
25246
  "type": "string",
25081
- "minLength": 1,
25082
- "maxLength": 120,
25083
- "pattern": "\\S"
25247
+ "pattern": "^[0-9]{6}$"
25084
25248
  }
25085
25249
  },
25086
25250
  "fundingTypes": {
@@ -25209,12 +25373,6 @@ var init_generated = __esm({
25209
25373
  "maxLength": 320
25210
25374
  }
25211
25375
  },
25212
- "domain": {
25213
- "description": "Website domain. Matching is exact on the host, and a root site ranks first.",
25214
- "type": "string",
25215
- "minLength": 1,
25216
- "maxLength": 320
25217
- },
25218
25376
  "insights": {
25219
25377
  "description": "Insights filters. Supply at least one.",
25220
25378
  "type": "object",
@@ -25918,6 +26076,36 @@ var init_generated = __esm({
25918
26076
  "filters": {
25919
26077
  "type": "object",
25920
26078
  "properties": {
26079
+ "companyNames": {
26080
+ "description": "Company name alternatives or a domain. Finds the 50 closest token or prefix matches, ignoring punctuation, accents and legal suffixes.",
26081
+ "minItems": 1,
26082
+ "maxItems": 5,
26083
+ "type": "array",
26084
+ "items": {
26085
+ "type": "string",
26086
+ "minLength": 1,
26087
+ "maxLength": 120,
26088
+ "pattern": "\\S"
26089
+ }
26090
+ },
26091
+ "excludeCompanyNames": {
26092
+ "description": "Company name prefixes to leave out.",
26093
+ "minItems": 1,
26094
+ "maxItems": 5,
26095
+ "type": "array",
26096
+ "items": {
26097
+ "type": "string",
26098
+ "minLength": 1,
26099
+ "maxLength": 120,
26100
+ "pattern": "\\S"
26101
+ }
26102
+ },
26103
+ "domain": {
26104
+ "description": "Company website domain. Exact host matching; root sites rank first.",
26105
+ "type": "string",
26106
+ "minLength": 1,
26107
+ "maxLength": 320
26108
+ },
25921
26109
  "countryCodes": {
25922
26110
  "description": "Two-letter country codes to include.",
25923
26111
  "minItems": 1,
@@ -26017,9 +26205,7 @@ var init_generated = __esm({
26017
26205
  "type": "array",
26018
26206
  "items": {
26019
26207
  "type": "string",
26020
- "minLength": 1,
26021
- "maxLength": 120,
26022
- "pattern": "\\S"
26208
+ "pattern": "^[0-9]{6}$"
26023
26209
  }
26024
26210
  },
26025
26211
  "excludeNaics2022Codes": {
@@ -26029,9 +26215,7 @@ var init_generated = __esm({
26029
26215
  "type": "array",
26030
26216
  "items": {
26031
26217
  "type": "string",
26032
- "minLength": 1,
26033
- "maxLength": 120,
26034
- "pattern": "\\S"
26218
+ "pattern": "^[0-9]{6}$"
26035
26219
  }
26036
26220
  },
26037
26221
  "fundingTypes": {
@@ -26160,6 +26344,25 @@ var init_generated = __esm({
26160
26344
  "maxLength": 320
26161
26345
  }
26162
26346
  },
26347
+ "personNames": {
26348
+ "description": "Person name alternatives. Requires a company name, domain or id. Matches first or last name for one token, or first and last name for two tokens, ignoring case and accents.",
26349
+ "minItems": 1,
26350
+ "maxItems": 5,
26351
+ "type": "array",
26352
+ "items": {
26353
+ "type": "string",
26354
+ "minLength": 1,
26355
+ "maxLength": 120,
26356
+ "pattern": "\\S"
26357
+ }
26358
+ },
26359
+ "email": {
26360
+ "description": "Exact work email address, matched through the email index.",
26361
+ "type": "string",
26362
+ "maxLength": 320,
26363
+ "format": "email",
26364
+ "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
26365
+ },
26163
26366
  "personCities": {
26164
26367
  "description": "Person cities to include. Requires personCountryCodes.",
26165
26368
  "minItems": 1,
@@ -26716,7 +26919,7 @@ var init_generated = __esm({
26716
26919
  },
26717
26920
  {
26718
26921
  "name": "lists.refresh",
26719
- "description": "Preview or refresh a static selection or audience in bounded pages. Record and new-record caps stop a refresh before list changes. Dry run reports additions, flags and removals.",
26922
+ "description": "Preview or refresh a static selection or audience in bounded pages. Record caps keep the first matching records that fit. New-record caps can block a refresh before changes. Dry run reports additions, flags and removals.",
26720
26923
  "risk": "write_local",
26721
26924
  "scopes": [
26722
26925
  "data:read",
@@ -26748,7 +26951,7 @@ var init_generated = __esm({
26748
26951
  },
26749
26952
  {
26750
26953
  "name": "lists.run",
26751
- "description": "Queue a bounded static-list data refresh for the current warehouse release when background jobs are configured, or return jobs_unavailable. Runs are idempotent per list and release. Dry run returns the proposed release without writing or dispatching.",
26954
+ "description": "Queue a background preview or refresh. Only one job runs per list. Owners and admins can refresh dynamic lists now, including the current release. Dry run reports the proposed release without queueing.",
26752
26955
  "risk": "write_local",
26753
26956
  "scopes": [
26754
26957
  "data:read",
@@ -26763,6 +26966,15 @@ var init_generated = __esm({
26763
26966
  "format": "uuid",
26764
26967
  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
26765
26968
  "description": "Saved list id."
26969
+ },
26970
+ "purpose": {
26971
+ "default": "refresh",
26972
+ "description": "Preview counts without changing records, or refresh using the saved caps.",
26973
+ "type": "string",
26974
+ "enum": [
26975
+ "preview",
26976
+ "refresh"
26977
+ ]
26766
26978
  }
26767
26979
  },
26768
26980
  "required": [
@@ -26771,6 +26983,37 @@ var init_generated = __esm({
26771
26983
  "additionalProperties": false
26772
26984
  }
26773
26985
  },
26986
+ {
26987
+ "name": "lists.status",
26988
+ "description": "Read the progress and count-only summary of a background list preview or refresh.",
26989
+ "risk": "read",
26990
+ "scopes": [
26991
+ "data:read"
26992
+ ],
26993
+ "input": {
26994
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
26995
+ "type": "object",
26996
+ "properties": {
26997
+ "id": {
26998
+ "type": "string",
26999
+ "format": "uuid",
27000
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
27001
+ "description": "Saved list id."
27002
+ },
27003
+ "runId": {
27004
+ "type": "string",
27005
+ "format": "uuid",
27006
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
27007
+ "description": "Background run id returned by lists.run."
27008
+ }
27009
+ },
27010
+ "required": [
27011
+ "id",
27012
+ "runId"
27013
+ ],
27014
+ "additionalProperties": false
27015
+ }
27016
+ },
26774
27017
  {
26775
27018
  "name": "lookup.company",
26776
27019
  "description": "Look up a company by exactly one domain, exact name (optionally with location), or opaque hdo_ id. Returns bounded candidates and ambiguity metadata. Insights fields and filters require the Insights or Unlimited plan.",
@@ -27079,6 +27322,36 @@ var init_generated = __esm({
27079
27322
  "$schema": "https://json-schema.org/draft/2020-12/schema",
27080
27323
  "type": "object",
27081
27324
  "properties": {
27325
+ "companyNames": {
27326
+ "description": "Company name prefixes. Match any name.",
27327
+ "minItems": 1,
27328
+ "maxItems": 5,
27329
+ "type": "array",
27330
+ "items": {
27331
+ "type": "string",
27332
+ "minLength": 1,
27333
+ "maxLength": 120,
27334
+ "pattern": "\\S"
27335
+ }
27336
+ },
27337
+ "excludeCompanyNames": {
27338
+ "description": "Company name prefixes to leave out.",
27339
+ "minItems": 1,
27340
+ "maxItems": 5,
27341
+ "type": "array",
27342
+ "items": {
27343
+ "type": "string",
27344
+ "minLength": 1,
27345
+ "maxLength": 120,
27346
+ "pattern": "\\S"
27347
+ }
27348
+ },
27349
+ "domain": {
27350
+ "description": "Company website domain. Exact host matching; root sites rank first.",
27351
+ "type": "string",
27352
+ "minLength": 1,
27353
+ "maxLength": 320
27354
+ },
27082
27355
  "countryCodes": {
27083
27356
  "description": "Two-letter country codes to include.",
27084
27357
  "minItems": 1,
@@ -27250,9 +27523,7 @@ var init_generated = __esm({
27250
27523
  "type": "array",
27251
27524
  "items": {
27252
27525
  "type": "string",
27253
- "minLength": 1,
27254
- "maxLength": 120,
27255
- "pattern": "\\S"
27526
+ "pattern": "^[0-9]{6}$"
27256
27527
  }
27257
27528
  },
27258
27529
  "excludeNaics2022Codes": {
@@ -27262,9 +27533,7 @@ var init_generated = __esm({
27262
27533
  "type": "array",
27263
27534
  "items": {
27264
27535
  "type": "string",
27265
- "minLength": 1,
27266
- "maxLength": 120,
27267
- "pattern": "\\S"
27536
+ "pattern": "^[0-9]{6}$"
27268
27537
  }
27269
27538
  },
27270
27539
  "fundingTypes": {
@@ -27406,12 +27675,6 @@ var init_generated = __esm({
27406
27675
  "minLength": 1,
27407
27676
  "maxLength": 2048
27408
27677
  },
27409
- "domain": {
27410
- "description": "Website domain. Matching is exact on the host, and a root site ranks first.",
27411
- "type": "string",
27412
- "minLength": 1,
27413
- "maxLength": 320
27414
- },
27415
27678
  "insights": {
27416
27679
  "description": "Insights filters. Supply at least one.",
27417
27680
  "type": "object",
@@ -28114,6 +28377,36 @@ var init_generated = __esm({
28114
28377
  "$schema": "https://json-schema.org/draft/2020-12/schema",
28115
28378
  "type": "object",
28116
28379
  "properties": {
28380
+ "companyNames": {
28381
+ "description": "Company name prefixes. Match any name.",
28382
+ "minItems": 1,
28383
+ "maxItems": 5,
28384
+ "type": "array",
28385
+ "items": {
28386
+ "type": "string",
28387
+ "minLength": 1,
28388
+ "maxLength": 120,
28389
+ "pattern": "\\S"
28390
+ }
28391
+ },
28392
+ "excludeCompanyNames": {
28393
+ "description": "Company name prefixes to leave out.",
28394
+ "minItems": 1,
28395
+ "maxItems": 5,
28396
+ "type": "array",
28397
+ "items": {
28398
+ "type": "string",
28399
+ "minLength": 1,
28400
+ "maxLength": 120,
28401
+ "pattern": "\\S"
28402
+ }
28403
+ },
28404
+ "domain": {
28405
+ "description": "Company website domain. Exact host matching; root sites rank first.",
28406
+ "type": "string",
28407
+ "minLength": 1,
28408
+ "maxLength": 320
28409
+ },
28117
28410
  "countryCodes": {
28118
28411
  "description": "Two-letter country codes to include.",
28119
28412
  "minItems": 1,
@@ -28285,9 +28578,7 @@ var init_generated = __esm({
28285
28578
  "type": "array",
28286
28579
  "items": {
28287
28580
  "type": "string",
28288
- "minLength": 1,
28289
- "maxLength": 120,
28290
- "pattern": "\\S"
28581
+ "pattern": "^[0-9]{6}$"
28291
28582
  }
28292
28583
  },
28293
28584
  "excludeNaics2022Codes": {
@@ -28297,9 +28588,7 @@ var init_generated = __esm({
28297
28588
  "type": "array",
28298
28589
  "items": {
28299
28590
  "type": "string",
28300
- "minLength": 1,
28301
- "maxLength": 120,
28302
- "pattern": "\\S"
28591
+ "pattern": "^[0-9]{6}$"
28303
28592
  }
28304
28593
  },
28305
28594
  "fundingTypes": {
@@ -28428,12 +28717,6 @@ var init_generated = __esm({
28428
28717
  "maxLength": 320
28429
28718
  }
28430
28719
  },
28431
- "domain": {
28432
- "description": "Website domain. Matching is exact on the host, and a root site ranks first.",
28433
- "type": "string",
28434
- "minLength": 1,
28435
- "maxLength": 320
28436
- },
28437
28720
  "insights": {
28438
28721
  "description": "Insights filters. Supply at least one.",
28439
28722
  "type": "object",
@@ -29121,7 +29404,7 @@ var init_generated = __esm({
29121
29404
  },
29122
29405
  {
29123
29406
  "name": "search.facets",
29124
- "description": "Read available country, state, industry, NAICS and funding filter values from HigherData Core, with optional country-scoped company, person or job city suggestions. Eligible plans also receive technology product suggestions.",
29407
+ "description": "Read release-built country, state, industry, NAICS, funding, department, seniority and role family values from HigherData Core, with optional country-scoped company, person or job city suggestions. Eligible plans also receive technology product suggestions.",
29125
29408
  "risk": "read",
29126
29409
  "scopes": [
29127
29410
  "data:read"
@@ -29220,7 +29503,7 @@ var init_generated = __esm({
29220
29503
  },
29221
29504
  {
29222
29505
  "name": "search.people",
29223
- "description": "Find people in HigherData Core, with 1 to 5 positive company HQ country codes or industries required unless companyId scopes the search to one company. Person, job and company location use distinct filters; each city filter requires its corresponding country. Company-scoped contacts also support legacy contactLocation filters. Pages contain at most 50 people and opaque ids. ",
29506
+ "description": "Find people in HigherData Core, with 1 to 5 positive company HQ country codes or industries required unless a company id, company name, domain or indexed email scopes the search. Person names require a company scope. Person, job and company location use distinct filters; each city filter requires its corresponding country. Company-scoped contacts also support legacy contactLocation filters. Pages contain at most 50 people and opaque ids. ",
29224
29507
  "risk": "read",
29225
29508
  "scopes": [
29226
29509
  "data:read"
@@ -29229,6 +29512,36 @@ var init_generated = __esm({
29229
29512
  "$schema": "https://json-schema.org/draft/2020-12/schema",
29230
29513
  "type": "object",
29231
29514
  "properties": {
29515
+ "companyNames": {
29516
+ "description": "Company name alternatives or a domain. Finds the 50 closest token or prefix matches, ignoring punctuation, accents and legal suffixes.",
29517
+ "minItems": 1,
29518
+ "maxItems": 5,
29519
+ "type": "array",
29520
+ "items": {
29521
+ "type": "string",
29522
+ "minLength": 1,
29523
+ "maxLength": 120,
29524
+ "pattern": "\\S"
29525
+ }
29526
+ },
29527
+ "excludeCompanyNames": {
29528
+ "description": "Company name prefixes to leave out.",
29529
+ "minItems": 1,
29530
+ "maxItems": 5,
29531
+ "type": "array",
29532
+ "items": {
29533
+ "type": "string",
29534
+ "minLength": 1,
29535
+ "maxLength": 120,
29536
+ "pattern": "\\S"
29537
+ }
29538
+ },
29539
+ "domain": {
29540
+ "description": "Company website domain. Exact host matching; root sites rank first.",
29541
+ "type": "string",
29542
+ "minLength": 1,
29543
+ "maxLength": 320
29544
+ },
29232
29545
  "countryCodes": {
29233
29546
  "description": "Two-letter country codes to include.",
29234
29547
  "minItems": 1,
@@ -29328,9 +29641,7 @@ var init_generated = __esm({
29328
29641
  "type": "array",
29329
29642
  "items": {
29330
29643
  "type": "string",
29331
- "minLength": 1,
29332
- "maxLength": 120,
29333
- "pattern": "\\S"
29644
+ "pattern": "^[0-9]{6}$"
29334
29645
  }
29335
29646
  },
29336
29647
  "excludeNaics2022Codes": {
@@ -29340,9 +29651,7 @@ var init_generated = __esm({
29340
29651
  "type": "array",
29341
29652
  "items": {
29342
29653
  "type": "string",
29343
- "minLength": 1,
29344
- "maxLength": 120,
29345
- "pattern": "\\S"
29654
+ "pattern": "^[0-9]{6}$"
29346
29655
  }
29347
29656
  },
29348
29657
  "fundingTypes": {
@@ -29471,6 +29780,25 @@ var init_generated = __esm({
29471
29780
  "maxLength": 320
29472
29781
  }
29473
29782
  },
29783
+ "personNames": {
29784
+ "description": "Person name alternatives. Requires a company name, domain or id. Matches first or last name for one token, or first and last name for two tokens, ignoring case and accents.",
29785
+ "minItems": 1,
29786
+ "maxItems": 5,
29787
+ "type": "array",
29788
+ "items": {
29789
+ "type": "string",
29790
+ "minLength": 1,
29791
+ "maxLength": 120,
29792
+ "pattern": "\\S"
29793
+ }
29794
+ },
29795
+ "email": {
29796
+ "description": "Exact work email address, matched through the email index.",
29797
+ "type": "string",
29798
+ "maxLength": 320,
29799
+ "format": "email",
29800
+ "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
29801
+ },
29474
29802
  "personCities": {
29475
29803
  "description": "Person cities to include. Requires personCountryCodes.",
29476
29804
  "minItems": 1,
@@ -29955,6 +30283,36 @@ var init_generated = __esm({
29955
30283
  "filters": {
29956
30284
  "type": "object",
29957
30285
  "properties": {
30286
+ "companyNames": {
30287
+ "description": "Company name prefixes. Match any name.",
30288
+ "minItems": 1,
30289
+ "maxItems": 5,
30290
+ "type": "array",
30291
+ "items": {
30292
+ "type": "string",
30293
+ "minLength": 1,
30294
+ "maxLength": 120,
30295
+ "pattern": "\\S"
30296
+ }
30297
+ },
30298
+ "excludeCompanyNames": {
30299
+ "description": "Company name prefixes to leave out.",
30300
+ "minItems": 1,
30301
+ "maxItems": 5,
30302
+ "type": "array",
30303
+ "items": {
30304
+ "type": "string",
30305
+ "minLength": 1,
30306
+ "maxLength": 120,
30307
+ "pattern": "\\S"
30308
+ }
30309
+ },
30310
+ "domain": {
30311
+ "description": "Company website domain. Exact host matching; root sites rank first.",
30312
+ "type": "string",
30313
+ "minLength": 1,
30314
+ "maxLength": 320
30315
+ },
29958
30316
  "countryCodes": {
29959
30317
  "description": "Two-letter country codes to include.",
29960
30318
  "minItems": 1,
@@ -30126,9 +30484,7 @@ var init_generated = __esm({
30126
30484
  "type": "array",
30127
30485
  "items": {
30128
30486
  "type": "string",
30129
- "minLength": 1,
30130
- "maxLength": 120,
30131
- "pattern": "\\S"
30487
+ "pattern": "^[0-9]{6}$"
30132
30488
  }
30133
30489
  },
30134
30490
  "excludeNaics2022Codes": {
@@ -30138,9 +30494,7 @@ var init_generated = __esm({
30138
30494
  "type": "array",
30139
30495
  "items": {
30140
30496
  "type": "string",
30141
- "minLength": 1,
30142
- "maxLength": 120,
30143
- "pattern": "\\S"
30497
+ "pattern": "^[0-9]{6}$"
30144
30498
  }
30145
30499
  },
30146
30500
  "fundingTypes": {
@@ -30269,12 +30623,6 @@ var init_generated = __esm({
30269
30623
  "maxLength": 320
30270
30624
  }
30271
30625
  },
30272
- "domain": {
30273
- "description": "Website domain. Matching is exact on the host, and a root site ranks first.",
30274
- "type": "string",
30275
- "minLength": 1,
30276
- "maxLength": 320
30277
- },
30278
30626
  "insights": {
30279
30627
  "description": "Insights filters. Supply at least one.",
30280
30628
  "type": "object",
@@ -30978,6 +31326,36 @@ var init_generated = __esm({
30978
31326
  "filters": {
30979
31327
  "type": "object",
30980
31328
  "properties": {
31329
+ "companyNames": {
31330
+ "description": "Company name alternatives or a domain. Finds the 50 closest token or prefix matches, ignoring punctuation, accents and legal suffixes.",
31331
+ "minItems": 1,
31332
+ "maxItems": 5,
31333
+ "type": "array",
31334
+ "items": {
31335
+ "type": "string",
31336
+ "minLength": 1,
31337
+ "maxLength": 120,
31338
+ "pattern": "\\S"
31339
+ }
31340
+ },
31341
+ "excludeCompanyNames": {
31342
+ "description": "Company name prefixes to leave out.",
31343
+ "minItems": 1,
31344
+ "maxItems": 5,
31345
+ "type": "array",
31346
+ "items": {
31347
+ "type": "string",
31348
+ "minLength": 1,
31349
+ "maxLength": 120,
31350
+ "pattern": "\\S"
31351
+ }
31352
+ },
31353
+ "domain": {
31354
+ "description": "Company website domain. Exact host matching; root sites rank first.",
31355
+ "type": "string",
31356
+ "minLength": 1,
31357
+ "maxLength": 320
31358
+ },
30981
31359
  "countryCodes": {
30982
31360
  "description": "Two-letter country codes to include.",
30983
31361
  "minItems": 1,
@@ -31077,9 +31455,7 @@ var init_generated = __esm({
31077
31455
  "type": "array",
31078
31456
  "items": {
31079
31457
  "type": "string",
31080
- "minLength": 1,
31081
- "maxLength": 120,
31082
- "pattern": "\\S"
31458
+ "pattern": "^[0-9]{6}$"
31083
31459
  }
31084
31460
  },
31085
31461
  "excludeNaics2022Codes": {
@@ -31089,9 +31465,7 @@ var init_generated = __esm({
31089
31465
  "type": "array",
31090
31466
  "items": {
31091
31467
  "type": "string",
31092
- "minLength": 1,
31093
- "maxLength": 120,
31094
- "pattern": "\\S"
31468
+ "pattern": "^[0-9]{6}$"
31095
31469
  }
31096
31470
  },
31097
31471
  "fundingTypes": {
@@ -31220,6 +31594,25 @@ var init_generated = __esm({
31220
31594
  "maxLength": 320
31221
31595
  }
31222
31596
  },
31597
+ "personNames": {
31598
+ "description": "Person name alternatives. Requires a company name, domain or id. Matches first or last name for one token, or first and last name for two tokens, ignoring case and accents.",
31599
+ "minItems": 1,
31600
+ "maxItems": 5,
31601
+ "type": "array",
31602
+ "items": {
31603
+ "type": "string",
31604
+ "minLength": 1,
31605
+ "maxLength": 120,
31606
+ "pattern": "\\S"
31607
+ }
31608
+ },
31609
+ "email": {
31610
+ "description": "Exact work email address, matched through the email index.",
31611
+ "type": "string",
31612
+ "maxLength": 320,
31613
+ "format": "email",
31614
+ "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
31615
+ },
31223
31616
  "personCities": {
31224
31617
  "description": "Person cities to include. Requires personCountryCodes.",
31225
31618
  "minItems": 1,
@@ -32012,7 +32405,7 @@ function retryAfter(response, data, now) {
32012
32405
  }
32013
32406
  function apiError(response, data, now) {
32014
32407
  const parsed = failure2.safeParse(data), error63 = parsed.success ? parsed.data.error : null;
32015
- return new HigherDataError(typeof error63 === "object" && error63?.message ? error63.message : "The HigherData API request failed.", typeof error63 === "string" ? error63 : error63?.code ?? "http_error", response.status, retryAfter(response, data, now));
32408
+ return new HigherDataError(typeof error63 === "object" && error63?.message ? error63.message : "The HigherData API request failed.", typeof error63 === "string" ? error63 : error63?.code ?? "http_error", response.status, retryAfter(response, data, now), response.headers.get("x-request-id") ?? void 0);
32016
32409
  }
32017
32410
  async function responseJson(response) {
32018
32411
  if (!response.body) throw new HigherDataError("The API returned an invalid response.", "invalid_response");
@@ -32067,16 +32460,18 @@ var init_transport = __esm({
32067
32460
  init_zod();
32068
32461
  failure2 = external_exports.object({ error: external_exports.union([external_exports.string(), external_exports.object({ code: external_exports.string().max(128), message: external_exports.string().max(2048).optional(), retry_after: external_exports.number().nonnegative().finite().optional() })]) });
32069
32462
  HigherDataError = class extends Error {
32070
- constructor(message, code, status = 0, retryAfter2) {
32463
+ constructor(message, code, status = 0, retryAfter2, requestId) {
32071
32464
  super(message);
32072
32465
  this.code = code;
32073
32466
  this.status = status;
32074
32467
  this.retryAfter = retryAfter2;
32468
+ this.requestId = requestId;
32075
32469
  this.name = "HigherDataError";
32076
32470
  }
32077
32471
  code;
32078
32472
  status;
32079
32473
  retryAfter;
32474
+ requestId;
32080
32475
  };
32081
32476
  limits = external_exports.object({ maxRetries: external_exports.number().int().min(0).max(5), timeoutMs: external_exports.number().int().min(1).max(3e5), maxRetryDelayMs: external_exports.number().int().min(0).max(3e5) });
32082
32477
  MAX_RESPONSE = 8 * 1024 * 1024;
@@ -32228,7 +32623,11 @@ var init_api2 = __esm({
32228
32623
  }
32229
32624
  } catch (error63) {
32230
32625
  if (error63 instanceof HigherDataError) {
32231
- if (error63.status) throw apiFailure(error63.status, { error: { code: error63.code, message: error63.message } });
32626
+ if (error63.status) {
32627
+ const mapped = apiFailure(error63.status, { error: { code: error63.code, message: error63.message } });
32628
+ const plain = (value) => (this.settings.apiKey ? value.replaceAll(this.settings.apiKey, "[redacted]") : value).replace(/[\u0000-\u001f\u007f-\u009f]/gu, " ");
32629
+ throw new CliError(`${plain(error63.code)}: ${plain(error63.message === "The HigherData API request failed." ? mapped.message : error63.message)}${error63.requestId ? ` (request: ${plain(error63.requestId)})` : ""}`, mapped.exitCode);
32630
+ }
32232
32631
  if (error63.code === "response_too_large") throw new CliError("The API response exceeded the CLI size limit.");
32233
32632
  throw new CliError(error63.message);
32234
32633
  }
@@ -35798,7 +36197,7 @@ var init_package = __esm({
35798
36197
  "package.json"() {
35799
36198
  package_default = {
35800
36199
  name: "higherdata",
35801
- version: "0.4.0",
36200
+ version: "0.5.0",
35802
36201
  type: "module",
35803
36202
  bin: {
35804
36203
  higherdata: "dist/index.js"
@@ -35848,6 +36247,9 @@ var init_package = __esm({
35848
36247
  },
35849
36248
  higherdata: {
35850
36249
  minimumServerVersion: "0.2.0"
36250
+ },
36251
+ optionalDependencies: {
36252
+ "@napi-rs/keyring": "2.1.0"
35851
36253
  }
35852
36254
  };
35853
36255
  }
@@ -38788,6 +39190,12 @@ function customerOutput(value) {
38788
39190
  }
38789
39191
  function renderOutput(value, mode) {
38790
39192
  value = customerOutput(value);
39193
+ if (value.status === "ambiguous" && Array.isArray(value.companyCandidates)) {
39194
+ if (mode === "human") return `${cell(value.message)}
39195
+ ${renderOutput({ items: value.companyCandidates }, "human")}`;
39196
+ return `${JSON.stringify(value)}
39197
+ `;
39198
+ }
38791
39199
  if (mode === "json") return `${JSON.stringify(value)}
38792
39200
  `;
38793
39201
  const scoped = value.peopleAtCompany && typeof value.peopleAtCompany === "object" ? value.peopleAtCompany.people : void 0;
@@ -43835,18 +44243,19 @@ function suggestionOptions(kind, known, key) {
43835
44243
  if (kind === "cities") return known.cities?.[key ?? ""] ?? [];
43836
44244
  if (kind === "industries") return known.industries.map((value) => ({ value, label: value }));
43837
44245
  if (kind === "funding") return known.fundingTypes.map((value) => ({ value, label: value }));
43838
- if (kind === "levels") return JOB_LEVELS.map((value) => ({ value, label: value }));
43839
- if (kind === "functions") return JOB_FUNCTIONS.map((value) => ({ value, label: value }));
44246
+ if (kind === "levels") return (known.jobLevels ?? JOB_LEVELS).map((value) => ({ value, label: value }));
44247
+ if (kind === "functions") return (known.jobFunctions ?? []).map((value) => ({ value, label: value }));
44248
+ if (kind === "roles") return (known.gtmRoleFamilies ?? []).map((value) => ({ value, label: value.replace(/_/g, " ") }));
43840
44249
  if (kind === "products") {
43841
44250
  const leaf = key?.split(".").pop() ?? "";
43842
44251
  const included = leaf.startsWith("exclude") ? leaf.charAt(7).toLowerCase() + leaf.slice(8) : leaf;
43843
44252
  return (known.technologyProducts?.[included] ?? []).map((value) => ({ value, label: value }));
43844
44253
  }
43845
- if (kind === "naics") return (known.naics2022Codes ?? []).map((value) => ({ value, label: naicsLabel(value) }));
44254
+ if (kind === "naics") return (known.naics2022Codes ?? []).map((value) => ({ value, label: known.naicsLabels?.[value] ?? naicsLabel(value) }));
43846
44255
  if (kind === "technologies") return technologyCategories.map((value) => ({ value, label: TECH_LABELS[value] }));
43847
44256
  return [];
43848
44257
  }
43849
- var EMPTY_KNOWN, COUNTRY_CODES, COUNTRY_ALIASES, US_STATES, CA_REGIONS, JOB_LEVELS, JOB_FUNCTIONS, TECH_LABELS, regions, countriesByName;
44258
+ var EMPTY_KNOWN, COUNTRY_CODES, COUNTRY_ALIASES, US_STATES, CA_REGIONS, JOB_LEVELS, TECH_LABELS, regions, countriesByName;
43850
44259
  var init_values = __esm({
43851
44260
  "../../src/lib/search-ui/values.ts"() {
43852
44261
  "use strict";
@@ -43937,21 +44346,6 @@ var init_values = __esm({
43937
44346
  YT: "Yukon"
43938
44347
  };
43939
44348
  JOB_LEVELS = ["C-Team", "VP", "Director", "Manager", "Staff"];
43940
- JOB_FUNCTIONS = [
43941
- "Operations",
43942
- "Sales",
43943
- "Marketing",
43944
- "Engineering",
43945
- "Finance",
43946
- "Human Resources",
43947
- "Information Technology",
43948
- "Product",
43949
- "Support",
43950
- "Legal",
43951
- "Customer Success",
43952
- "Business Development",
43953
- "Data"
43954
- ];
43955
44349
  TECH_LABELS = {
43956
44350
  crm: "CRM",
43957
44351
  marketingAutomation: "Marketing automation",
@@ -43994,6 +44388,25 @@ function range2(min, max, estimate, money = false) {
43994
44388
  const value = estimate ?? min ?? max;
43995
44389
  return value === null ? null : format2(value);
43996
44390
  }
44391
+ function stringValues(value) {
44392
+ if (!value) return [];
44393
+ if (!value.trim().startsWith("[")) return [value.trim()];
44394
+ try {
44395
+ const parsed = JSON.parse(value);
44396
+ return Array.isArray(parsed) ? parsed.map((item) => typeof item === "string" || typeof item === "number" ? String(item).trim() : "") : [];
44397
+ } catch {
44398
+ return [];
44399
+ }
44400
+ }
44401
+ function naicsDisplay(codes, titles) {
44402
+ const descriptions = stringValues(titles), seen = /* @__PURE__ */ new Set();
44403
+ const labels = stringValues(codes).flatMap((code, index) => {
44404
+ if (!/^[0-9]{6}$/.test(code) || seen.has(code)) return [];
44405
+ seen.add(code);
44406
+ return [descriptions[index] ? `${code} ${descriptions[index]}` : naicsLabel(code)];
44407
+ });
44408
+ return labels.length ? labels.join("; ") : null;
44409
+ }
43997
44410
  function recordDisplayValues(record2) {
43998
44411
  const text2 = (key) => typeof record2[key] === "string" ? record2[key] : null;
43999
44412
  const number5 = (key) => typeof record2[key] === "number" ? record2[key] : null;
@@ -44001,7 +44414,7 @@ function recordDisplayValues(record2) {
44001
44414
  ...record2,
44002
44415
  location: locationLabel(text2("headquartersCity"), text2("headquartersStateCode"), text2("headquartersCountryCode")),
44003
44416
  address: [text2("headquartersStreet"), text2("headquartersPostcode")].filter(Boolean).join(", "),
44004
- naics: [text2("industryNaics2022Code"), text2("industryNaics2022Description")].filter(Boolean).join(" "),
44417
+ naics: naicsDisplay(text2("industryNaics2022Code"), text2("industryNaics2022Description")),
44005
44418
  employees: range2(number5("employeeCountMin"), number5("employeeCountMax"), number5("employeeCountEstimate") ?? number5("employeeCount")),
44006
44419
  revenue: range2(number5("revenueMinUsd"), number5("revenueMaxUsd"), number5("revenueEstimateUsd"), true)
44007
44420
  };
@@ -44021,6 +44434,7 @@ var init_format2 = __esm({
44021
44434
  // ../../src/lib/search-ui/filter-groups.ts
44022
44435
  function groupFor(key) {
44023
44436
  const leaf = key.split(".").pop() ?? key;
44437
+ if (["companyNames", "excludeCompanyNames", "domain", "excludeDomains", "personNames", "email"].includes(leaf)) return "Name and contact";
44024
44438
  if (key.startsWith("insights") || /technolog/i.test(leaf)) return "Insights";
44025
44439
  if (/country|state|cities|city|region|postcode/i.test(leaf)) return "Location";
44026
44440
  if (/industr|naics/i.test(leaf)) return "Industry";
@@ -44044,6 +44458,7 @@ var init_filter_groups = __esm({
44044
44458
  "../../src/lib/search-ui/filter-groups.ts"() {
44045
44459
  "use strict";
44046
44460
  GROUP_ORDER = [
44461
+ "Name and contact",
44047
44462
  "Location",
44048
44463
  "Industry",
44049
44464
  "Company size",
@@ -45892,9 +46307,7 @@ function createProgram(overrides = {}) {
45892
46307
  if (["login", "update", "upgrade"].includes(command.name()) || ["mcp", "skills", "config"].includes(command.parent?.name() ?? "")) return;
45893
46308
  if (command === program2 && (!runtime.updater.stdinTTY || !runtime.updater.stdoutTTY || Object.hasOwn(runtime.env, "CI") || program2.opts().json || program2.opts().jsonl)) return;
45894
46309
  const settings = resolveSettings(await runtime.readConfig(), command.optsWithGlobals(), runtime.env);
45895
- const interactive = runtime.updater.stdinTTY && runtime.updater.stdoutTTY && !Object.hasOwn(runtime.env, "CI") && !command.optsWithGlobals().json && !command.optsWithGlobals().jsonl;
45896
- await checkCliVersion({ apiUrl: settings.apiUrl, version: package_default.version, cache: runtime.versionCache, fetchImpl: runtime.fetchImpl, now: runtime.now, warn: interactive ? runtime.err : () => {
45897
- } });
46310
+ await checkCliVersion({ apiUrl: settings.apiUrl, version: package_default.version, cache: runtime.versionCache, fetchImpl: runtime.fetchImpl, now: runtime.now, warn: runtime.err });
45898
46311
  });
45899
46312
  program2.command("update").alias("upgrade").description("Install the latest HigherData CLI release").action(() => updateCli({ version: package_default.version, fetchImpl: runtime.fetchImpl, runtime: runtime.updater, env: runtime.env, out: runtime.out }));
45900
46313
  program2.command("config").description("Configure the CLI").command("set <key> <value>").action(async (key, value) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "higherdata",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "higherdata": "dist/index.js"
@@ -50,5 +50,8 @@
50
50
  },
51
51
  "higherdata": {
52
52
  "minimumServerVersion": "0.2.0"
53
+ },
54
+ "optionalDependencies": {
55
+ "@napi-rs/keyring": "2.1.0"
53
56
  }
54
57
  }