ethos-cli 0.4.0 → 0.5.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.
@@ -0,0 +1,513 @@
1
+ import { collect, compactObject, jsonRequest, withClient } from "../lib/command-helpers.js";
2
+ import { printResult } from "../lib/output.js";
3
+ import { getTableDetailWithOrgFallback } from "../lib/table-detail.js";
4
+ const linkedinProfileSlugPattern = /^[A-Za-z0-9._%-]+$/;
5
+ const linkedinProviderIdPattern = /^(?:ACo|ACw|AE|ADo)[A-Za-z0-9_-]+$/;
6
+ export function registerLists(program) {
7
+ const lists = program.command("lists").alias("list").description("Manage Ethos contact lists");
8
+ const importFromTableCommand = lists
9
+ .command("import-from-table <table-id>")
10
+ .description("Create a contact list from a people table")
11
+ .option("--name <name>", "list name; defaults to '<table name> contacts'")
12
+ .option("--description <description>", "list description")
13
+ .option("--linkedin-column <column>", "table column containing LinkedIn person profile URLs or identifiers")
14
+ .option("--custom-variable <column-or-column=key>", "table column to import as a custom variable; repeatable", collect, [])
15
+ .option("--no-dedupe-existing", "do not resolve matching workspace contacts before import");
16
+ importFromTableCommand.action(async (tableId) => {
17
+ await withClient(importFromTableCommand, async (client, config) => {
18
+ const options = importFromTableCommand.opts();
19
+ const detail = await getTableDetailWithOrgFallback(client, config, tableId);
20
+ const source = importSourceFromTableDetail(detail);
21
+ const linkedinColumn = resolveLinkedinColumn(options.linkedinColumn, source);
22
+ const customVariableColumns = parseCustomVariableColumns(options.customVariable, source.headers);
23
+ const standardFieldColumns = inferStandardFieldColumns(source.headers, linkedinColumn);
24
+ const existingContactsByIdentityKey = options.dedupeExisting === false ? new Map() : await fetchExistingContactMap(client);
25
+ const preview = buildImportPreview({
26
+ source,
27
+ linkedinColumn,
28
+ customVariableColumns,
29
+ standardFieldColumns,
30
+ existingContactsByIdentityKey,
31
+ });
32
+ if (!preview.contacts.length) {
33
+ throw new Error(`No importable contacts found in table ${detail.table.id}. ` +
34
+ `Skipped ${preview.missingCount} missing, ${preview.invalidCount} invalid, and ${preview.duplicateCount} duplicate rows.`);
35
+ }
36
+ const payload = {
37
+ name: options.name?.trim() || `${detail.table.name} contacts`,
38
+ ...compactObject({ description: options.description?.trim() || undefined }),
39
+ source_table_id: detail.table.id,
40
+ linkedin_column: linkedinColumn,
41
+ custom_variable_columns: customVariableColumns,
42
+ dedupe: {
43
+ contexts: options.dedupeExisting === false ? [] : ["workspace"],
44
+ context_duplicate_count: 0,
45
+ duplicate_count: preview.duplicateCount,
46
+ existing_count: preview.existingCount,
47
+ invalid_count: preview.invalidCount,
48
+ missing_count: preview.missingCount,
49
+ },
50
+ contacts: preview.contacts,
51
+ };
52
+ const listDetail = await client.request("/v1/lists/import", jsonRequest("POST", payload));
53
+ printResult(config, listImportCommandResult(listDetail, payload, preview));
54
+ });
55
+ });
56
+ }
57
+ function importSourceFromTableDetail(detail) {
58
+ const columns = detail.columns
59
+ .filter((column) => column.name !== "source_company_row_id")
60
+ .slice()
61
+ .sort((left, right) => left.position - right.position);
62
+ const rows = detail.rows.slice().sort((left, right) => left.row_index - right.row_index);
63
+ const cellsByPosition = new Map();
64
+ for (const cell of detail.cells) {
65
+ cellsByPosition.set(`${cell.row_id}:${cell.column_id}`, cell.value);
66
+ }
67
+ const headers = columns.map((column) => column.name);
68
+ validateUniqueColumnNames(headers);
69
+ const sourceRows = rows.map((row) => {
70
+ const entries = columns.map((column) => [
71
+ column.name,
72
+ stringifyCellValue(cellsByPosition.get(`${row.id}:${column.id}`)),
73
+ ]);
74
+ return Object.fromEntries(entries);
75
+ });
76
+ const inferredLinkedinColumn = columns.find((column) => column.semantic_attributes.is_linkedin_person_profile)?.name ?? guessLinkedinColumn(columns);
77
+ return {
78
+ headers,
79
+ rows: sourceRows,
80
+ rowIds: rows.map((row) => row.id),
81
+ inferredLinkedinColumn,
82
+ };
83
+ }
84
+ function validateUniqueColumnNames(headers) {
85
+ const seen = new Set();
86
+ const duplicates = new Set();
87
+ for (const header of headers) {
88
+ if (seen.has(header)) {
89
+ duplicates.add(header);
90
+ continue;
91
+ }
92
+ seen.add(header);
93
+ }
94
+ if (duplicates.size) {
95
+ throw new Error(`Table has duplicate column names: ${Array.from(duplicates).join(", ")}. ` +
96
+ "Rename duplicate columns before importing a list.");
97
+ }
98
+ }
99
+ function stringifyCellValue(value) {
100
+ if (value === null || value === undefined)
101
+ return "";
102
+ if (typeof value === "string")
103
+ return value.trim();
104
+ if (typeof value === "number" || typeof value === "boolean")
105
+ return String(value);
106
+ return JSON.stringify(value);
107
+ }
108
+ function guessLinkedinColumn(columns) {
109
+ const scored = columns
110
+ .map((column) => {
111
+ const normalized = normalizeHeader(column.name);
112
+ let score = 0;
113
+ if (normalized.includes("linkedin"))
114
+ score += 2;
115
+ if (normalized.includes("profile"))
116
+ score += 4;
117
+ if (normalized.includes("person"))
118
+ score += 4;
119
+ if (normalized.includes("contact"))
120
+ score += 2;
121
+ if (normalized.includes("identifier"))
122
+ score += 2;
123
+ if (normalized.includes("id"))
124
+ score += 1;
125
+ if (normalized.includes("url"))
126
+ score += 1;
127
+ if (normalized.includes("company"))
128
+ score -= 6;
129
+ return { column, score };
130
+ })
131
+ .filter((item) => item.score > 0 && normalizeHeader(item.column.name).includes("linkedin"))
132
+ .sort((left, right) => right.score - left.score);
133
+ return scored[0]?.column.name ?? "";
134
+ }
135
+ function resolveLinkedinColumn(value, source) {
136
+ if (value) {
137
+ return resolveColumnName(value, source.headers, "--linkedin-column");
138
+ }
139
+ if (source.inferredLinkedinColumn) {
140
+ return source.inferredLinkedinColumn;
141
+ }
142
+ throw new Error("Could not infer a LinkedIn person column. Pass --linkedin-column.");
143
+ }
144
+ function parseCustomVariableColumns(values, headers) {
145
+ const columns = [];
146
+ const usedKeys = new Set();
147
+ for (const value of values ?? []) {
148
+ const parsed = parseCustomVariableOption(value);
149
+ const sourceColumn = resolveColumnName(parsed.sourceColumn, headers, "--custom-variable");
150
+ const variableKey = parsed.variableKey ?? normalizeVariableKey(parsed.sourceColumn);
151
+ if (!isValidVariableKey(variableKey)) {
152
+ throw new Error(`Custom variable key "${variableKey}" must contain only lowercase letters, numbers, and underscores.`);
153
+ }
154
+ if (usedKeys.has(variableKey)) {
155
+ throw new Error(`Duplicate custom variable key "${variableKey}".`);
156
+ }
157
+ usedKeys.add(variableKey);
158
+ columns.push({
159
+ source_column: sourceColumn,
160
+ variable_key: variableKey,
161
+ label: sourceColumn,
162
+ });
163
+ }
164
+ return columns;
165
+ }
166
+ function parseCustomVariableOption(value) {
167
+ const separatorIndex = value.indexOf("=");
168
+ if (separatorIndex === -1) {
169
+ return { sourceColumn: value.trim() };
170
+ }
171
+ const sourceColumn = value.slice(0, separatorIndex).trim();
172
+ const variableKey = value.slice(separatorIndex + 1).trim();
173
+ if (!sourceColumn || !variableKey) {
174
+ throw new Error("--custom-variable entries must be '<column>' or '<column>=<variable_key>'.");
175
+ }
176
+ return { sourceColumn, variableKey };
177
+ }
178
+ function resolveColumnName(reference, headers, option) {
179
+ const trimmed = reference.trim();
180
+ if (!trimmed)
181
+ throw new Error(`${option} cannot be empty.`);
182
+ const exactMatch = headers.find((header) => header === trimmed);
183
+ if (exactMatch)
184
+ return exactMatch;
185
+ const lowerMatch = headers.find((header) => header.toLowerCase() === trimmed.toLowerCase());
186
+ if (lowerMatch)
187
+ return lowerMatch;
188
+ const normalized = normalizeVariableKey(trimmed);
189
+ const normalizedMatches = headers.filter((header) => normalizeVariableKey(header) === normalized);
190
+ if (normalizedMatches.length === 1)
191
+ return normalizedMatches[0] ?? trimmed;
192
+ if (normalizedMatches.length > 1) {
193
+ throw new Error(`${option} "${reference}" matches multiple columns: ${normalizedMatches.join(", ")}.`);
194
+ }
195
+ throw new Error(`${option} "${reference}" was not found. Available columns: ${headers.join(", ")}.`);
196
+ }
197
+ async function fetchExistingContactMap(client) {
198
+ const contacts = await client.request("/v1/contacts");
199
+ const contactsByIdentityKey = new Map();
200
+ for (const contact of contacts) {
201
+ for (const key of linkedinIdentityKeysForContact(contact)) {
202
+ if (!contactsByIdentityKey.has(key))
203
+ contactsByIdentityKey.set(key, contact);
204
+ }
205
+ }
206
+ return contactsByIdentityKey;
207
+ }
208
+ function buildImportPreview(input) {
209
+ const contacts = [];
210
+ const seenIdentityKeys = new Set();
211
+ const seenExistingContactIds = new Set();
212
+ let duplicateCount = 0;
213
+ let existingCount = 0;
214
+ let invalidCount = 0;
215
+ let missingCount = 0;
216
+ for (const [rowIndex, row] of input.source.rows.entries()) {
217
+ const rawValue = row[input.linkedinColumn]?.trim();
218
+ if (!rawValue) {
219
+ missingCount += 1;
220
+ continue;
221
+ }
222
+ const identity = parseLinkedinImportIdentity(rawValue);
223
+ if (!identity) {
224
+ invalidCount += 1;
225
+ continue;
226
+ }
227
+ if (identity.keys.some((key) => seenIdentityKeys.has(key))) {
228
+ duplicateCount += 1;
229
+ continue;
230
+ }
231
+ identity.keys.forEach((key) => seenIdentityKeys.add(key));
232
+ const customVariables = customVariablesForRow(row, input.customVariableColumns);
233
+ const sourceTableRowId = input.source.rowIds[rowIndex] ?? null;
234
+ const existingContact = lookupContactByIdentity(input.existingContactsByIdentityKey, identity.keys);
235
+ if (existingContact) {
236
+ if (seenExistingContactIds.has(existingContact.id)) {
237
+ duplicateCount += 1;
238
+ continue;
239
+ }
240
+ existingCount += 1;
241
+ seenExistingContactIds.add(existingContact.id);
242
+ contacts.push({
243
+ contact_id: existingContact.id,
244
+ custom_variables: customVariables,
245
+ source_table_row_id: sourceTableRowId,
246
+ });
247
+ continue;
248
+ }
249
+ contacts.push({
250
+ contact: contactFromRow(row, identity, input.standardFieldColumns),
251
+ custom_variables: customVariables,
252
+ source_table_row_id: sourceTableRowId,
253
+ });
254
+ }
255
+ return {
256
+ contacts,
257
+ duplicateCount,
258
+ existingCount,
259
+ invalidCount,
260
+ missingCount,
261
+ };
262
+ }
263
+ function lookupContactByIdentity(contactsByIdentityKey, keys) {
264
+ for (const key of keys) {
265
+ const contact = contactsByIdentityKey.get(key);
266
+ if (contact)
267
+ return contact;
268
+ }
269
+ return null;
270
+ }
271
+ function contactFromRow(row, identity, standardFieldColumns) {
272
+ return compactObject({
273
+ linkedin_profile_id: identity.publicIdentifier ?? undefined,
274
+ linkedin_profile_url: identity.url ?? undefined,
275
+ linkedin_public_identifier: identity.publicIdentifier ?? undefined,
276
+ linkedin_provider_id: identity.providerId ?? undefined,
277
+ external_profile_id: identity.providerId ?? undefined,
278
+ first_name: cellValue(row, standardFieldColumns.first_name) ?? undefined,
279
+ last_name: cellValue(row, standardFieldColumns.last_name) ?? undefined,
280
+ full_name: contactFullName(row, standardFieldColumns.full_name, standardFieldColumns.first_name, standardFieldColumns.last_name) ?? undefined,
281
+ title: cellValue(row, standardFieldColumns.title) ?? undefined,
282
+ company: cellValue(row, standardFieldColumns.company) ?? undefined,
283
+ company_domain: cellValue(row, standardFieldColumns.company_domain) ?? undefined,
284
+ email: cellValue(row, standardFieldColumns.email) ?? undefined,
285
+ phone: cellValue(row, standardFieldColumns.phone) ?? undefined,
286
+ location: cellValue(row, standardFieldColumns.location) ?? undefined,
287
+ });
288
+ }
289
+ function inferStandardFieldColumns(headers, linkedinColumn) {
290
+ const result = {};
291
+ const usedRoles = new Set();
292
+ for (const header of headers) {
293
+ if (header === linkedinColumn)
294
+ continue;
295
+ const normalized = normalizeHeader(header);
296
+ if (normalized.includes("linkedin"))
297
+ continue;
298
+ const role = initialRoleByExactHeader(normalized) ?? initialRoleByTerms(normalized);
299
+ if (!role || usedRoles.has(role))
300
+ continue;
301
+ result[role] = header;
302
+ usedRoles.add(role);
303
+ }
304
+ return result;
305
+ }
306
+ function initialRoleByExactHeader(normalized) {
307
+ const roles = {
308
+ name: "full_name",
309
+ fullname: "full_name",
310
+ contactname: "full_name",
311
+ person: "full_name",
312
+ personname: "full_name",
313
+ firstname: "first_name",
314
+ lastname: "last_name",
315
+ jobtitle: "title",
316
+ title: "title",
317
+ company: "company",
318
+ companyname: "company",
319
+ companydomain: "company_domain",
320
+ email: "email",
321
+ workemail: "email",
322
+ phone: "phone",
323
+ phonenumber: "phone",
324
+ mobile: "phone",
325
+ cellphone: "phone",
326
+ location: "location",
327
+ };
328
+ return roles[normalized] ?? null;
329
+ }
330
+ function initialRoleByTerms(normalized) {
331
+ const candidates = [
332
+ { role: "company_domain", terms: ["company", "domain"] },
333
+ { role: "first_name", terms: ["first", "name"] },
334
+ { role: "last_name", terms: ["last", "name"] },
335
+ { role: "full_name", terms: ["full", "name"] },
336
+ { role: "title", terms: ["title"] },
337
+ { role: "email", terms: ["email"] },
338
+ { role: "phone", terms: ["phone"] },
339
+ { role: "location", terms: ["location"] },
340
+ { role: "company", terms: ["company"] },
341
+ ];
342
+ const match = candidates.find((candidate) => candidate.terms.every((term) => normalized.includes(term)));
343
+ return match?.role ?? null;
344
+ }
345
+ function cellValue(row, sourceColumn) {
346
+ if (!sourceColumn)
347
+ return null;
348
+ const value = row[sourceColumn]?.trim();
349
+ return value || null;
350
+ }
351
+ function contactFullName(row, fullNameColumn, firstNameColumn, lastNameColumn) {
352
+ const fullName = cellValue(row, fullNameColumn);
353
+ if (fullName)
354
+ return fullName;
355
+ const firstName = cellValue(row, firstNameColumn);
356
+ const lastName = cellValue(row, lastNameColumn);
357
+ const nameParts = [firstName, lastName].filter((part) => Boolean(part));
358
+ return nameParts.length ? nameParts.join(" ") : null;
359
+ }
360
+ function customVariablesForRow(row, customVariableColumns) {
361
+ const variables = {};
362
+ for (const column of customVariableColumns) {
363
+ const value = row[column.source_column]?.trim() ?? "";
364
+ if (value)
365
+ variables[column.variable_key] = value;
366
+ }
367
+ return variables;
368
+ }
369
+ function parseLinkedinImportIdentity(value) {
370
+ const normalizedUrl = normalizeLinkedinProfileUrl(value);
371
+ if (normalizedUrl) {
372
+ const identifier = linkedinSlug(normalizedUrl);
373
+ const providerId = identifier && isLinkedinProviderId(identifier) ? identifier : null;
374
+ return {
375
+ keys: linkedinUrlIdentityKeys(normalizedUrl),
376
+ publicIdentifier: identifier && !providerId ? identifier : null,
377
+ providerId,
378
+ url: normalizedUrl,
379
+ };
380
+ }
381
+ const identifier = normalizeLinkedinProfileId(value);
382
+ if (!identifier)
383
+ return null;
384
+ const providerId = isLinkedinProviderId(identifier) ? identifier : null;
385
+ return {
386
+ keys: linkedinProfileIdIdentityKeys(identifier),
387
+ publicIdentifier: providerId ? null : identifier,
388
+ providerId,
389
+ url: linkedinProfileUrlFromIdentifier(identifier),
390
+ };
391
+ }
392
+ function linkedinIdentityKeysForContact(contact) {
393
+ const keys = new Set();
394
+ addLinkedinValueKeys(keys, contact.linkedin_profile_url);
395
+ addLinkedinValueKeys(keys, contact.linkedin_public_identifier);
396
+ addLinkedinValueKeys(keys, contact.linkedin_provider_id);
397
+ addLinkedinValueKeys(keys, contact.linkedin_profile_id);
398
+ addLinkedinValueKeys(keys, contact.external_profile_id);
399
+ return Array.from(keys);
400
+ }
401
+ function addLinkedinValueKeys(keys, value) {
402
+ const normalizedUrl = normalizeLinkedinProfileUrl(value);
403
+ if (normalizedUrl) {
404
+ for (const key of linkedinUrlIdentityKeys(normalizedUrl))
405
+ keys.add(key);
406
+ }
407
+ const profileId = normalizeLinkedinProfileId(value);
408
+ if (profileId) {
409
+ for (const key of linkedinProfileIdIdentityKeys(profileId))
410
+ keys.add(key);
411
+ }
412
+ }
413
+ function linkedinUrlIdentityKeys(normalizedUrl) {
414
+ const keys = new Set();
415
+ const slug = linkedinSlug(normalizedUrl);
416
+ if (slug)
417
+ keys.add(identityKey(isLinkedinProviderId(slug) ? "id" : "slug", slug));
418
+ keys.add(identityKey("url", normalizedUrl));
419
+ return Array.from(keys);
420
+ }
421
+ function linkedinProfileIdIdentityKeys(profileId) {
422
+ const keys = new Set([identityKey("id", profileId)]);
423
+ if (!isLinkedinProviderId(profileId) && isLikelyLinkedinSlugIdentifier(profileId)) {
424
+ keys.add(identityKey("slug", profileId));
425
+ }
426
+ return Array.from(keys);
427
+ }
428
+ function normalizeLinkedinProfileUrl(value) {
429
+ if (!value)
430
+ return null;
431
+ const trimmed = value.trim().replace(/^"+|"+$/g, "");
432
+ const withProtocol = /^https?:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;
433
+ try {
434
+ const url = new URL(withProtocol);
435
+ const hostname = url.hostname.toLowerCase();
436
+ if (hostname !== "linkedin.com" && hostname !== "www.linkedin.com")
437
+ return null;
438
+ const slug = url.pathname.match(/^\/in\/([^/]+)\/?$/)?.[1];
439
+ if (!slug || !linkedinProfileSlugPattern.test(slug))
440
+ return null;
441
+ return `https://www.linkedin.com/in/${slug}/`;
442
+ }
443
+ catch {
444
+ return null;
445
+ }
446
+ }
447
+ function linkedinSlug(value) {
448
+ const normalizedUrl = normalizeLinkedinProfileUrl(value);
449
+ if (!normalizedUrl)
450
+ return null;
451
+ return new URL(normalizedUrl).pathname.match(/^\/in\/([^/]+)\/?$/)?.[1] ?? null;
452
+ }
453
+ function normalizeLinkedinProfileId(value) {
454
+ if (!value)
455
+ return null;
456
+ const trimmed = value.trim().replace(/^"+|"+$/g, "");
457
+ if (!trimmed || /^https?:\/\//i.test(trimmed) || trimmed.toLowerCase().includes("linkedin.com"))
458
+ return null;
459
+ if (!/^[A-Za-z0-9:._%-]+$/.test(trimmed))
460
+ return null;
461
+ return trimmed;
462
+ }
463
+ function isLinkedinProviderId(value) {
464
+ return Boolean(value && linkedinProviderIdPattern.test(value.trim()));
465
+ }
466
+ function isLikelyLinkedinSlugIdentifier(value) {
467
+ return linkedinProfileSlugPattern.test(value) && !/^\d+$/.test(value) && !value.includes(":");
468
+ }
469
+ function linkedinProfileUrlFromIdentifier(value) {
470
+ const identifier = normalizeLinkedinProfileId(value);
471
+ if (!identifier || !linkedinProfileSlugPattern.test(identifier))
472
+ return null;
473
+ return `https://www.linkedin.com/in/${identifier}/`;
474
+ }
475
+ function identityKey(kind, value) {
476
+ return `${kind}:${value.trim().toLowerCase()}`;
477
+ }
478
+ function normalizeHeader(value) {
479
+ return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "");
480
+ }
481
+ function normalizeVariableKey(value) {
482
+ return value
483
+ .trim()
484
+ .toLowerCase()
485
+ .replace(/['"]/g, "")
486
+ .replace(/&/g, " and ")
487
+ .replace(/[^a-z0-9]+/g, "_")
488
+ .replace(/^_+|_+$/g, "")
489
+ .slice(0, 64);
490
+ }
491
+ function isValidVariableKey(value) {
492
+ return /^[a-z0-9_]+$/.test(value);
493
+ }
494
+ function listImportCommandResult(detail, payload, preview) {
495
+ const data = {
496
+ ...detail,
497
+ list_id: detail.list.id,
498
+ source_table_id: payload.source_table_id,
499
+ contact_count: detail.contacts.length,
500
+ accepted_row_count: preview.contacts.length,
501
+ existing_contact_count: preview.existingCount,
502
+ duplicate_count: preview.duplicateCount,
503
+ invalid_count: preview.invalidCount,
504
+ missing_count: preview.missingCount,
505
+ linkedin_column: payload.linkedin_column,
506
+ custom_variable_keys: payload.custom_variable_columns.map((column) => column.variable_key),
507
+ };
508
+ return {
509
+ label: `Imported list ${detail.list.id} from table ${payload.source_table_id} (${detail.contacts.length} contacts)`,
510
+ data,
511
+ };
512
+ }
513
+ //# sourceMappingURL=lists.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lists.js","sourceRoot":"","sources":["../../src/commands/lists.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { Command } from "commander";
2
- import { type EthosClient } from "../lib/client.js";
2
+ import type { EthosClient } from "../lib/client.js";
3
3
  import type { TableOutputField } from "../lib/table-types.js";
4
4
  type ColumnOptions = {
5
5
  name?: string;
@@ -1,7 +1,7 @@
1
1
  import { normalizeAgentClientId } from "../lib/agent-clients.js";
2
2
  import { collect, compactObject, jsonRequest, pathId, withClient } from "../lib/command-helpers.js";
3
- import { EthosApiError } from "../lib/client.js";
4
3
  import { printResult } from "../lib/output.js";
4
+ import { getTableDetailWithOrgFallback } from "../lib/table-detail.js";
5
5
  const allowedScopes = new Set(["first_5", "all", "empty", "count"]);
6
6
  const contactEnrichmentFields = new Set(["work_email", "phone"]);
7
7
  const outputFieldTypes = new Set(["text", "boolean", "integer"]);
@@ -520,44 +520,6 @@ function existingSourcePeopleColumnRunResult(run) {
520
520
  },
521
521
  };
522
522
  }
523
- async function getTableDetailWithOrgFallback(client, config, tableId) {
524
- const path = `/v1/tables/${pathId(tableId)}`;
525
- try {
526
- return await client.request(path);
527
- }
528
- catch (error) {
529
- if (!isRecoverableTableNotFound(error))
530
- throw error;
531
- return requestTableDetailAcrossAccessibleOrgs(client, config, path, error);
532
- }
533
- }
534
- async function requestTableDetailAcrossAccessibleOrgs(client, config, path, originalError) {
535
- let orgs = [];
536
- try {
537
- orgs = (await client.withOrgId(undefined).request("/v1/auth/orgs")).orgs;
538
- }
539
- catch {
540
- throw originalError;
541
- }
542
- for (const org of orgs) {
543
- if (org.org_id === config.orgId)
544
- continue;
545
- try {
546
- return await client.withOrgId(org.org_id).request(path);
547
- }
548
- catch (error) {
549
- if (isRecoverableTableNotFound(error))
550
- continue;
551
- throw error;
552
- }
553
- }
554
- const activeOrg = config.orgId ?? "default";
555
- const triedOrgs = orgs.map((org) => `${org.org_name || org.org_id} (${org.org_id})`).join(", ") || "none";
556
- throw new EthosApiError(`${originalError.message}. Active CLI org: ${activeOrg}. Tried accessible orgs: ${triedOrgs}.`, originalError.status, originalError.body);
557
- }
558
- function isRecoverableTableNotFound(error) {
559
- return error instanceof EthosApiError && error.status === 404;
560
- }
561
523
  function stringConfigValue(config, key) {
562
524
  const value = config?.[key];
563
525
  return typeof value === "string" ? value : null;