@oxygen-agent/cli 1.1014.135 → 1.1014.618
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.js +27 -19
- package/dist/cli-output.d.ts +12 -0
- package/dist/cli-output.js +395 -0
- package/dist/cli-paths.d.ts +1 -0
- package/dist/cli-paths.js +3 -0
- package/dist/cli-profile-context.d.ts +3 -0
- package/dist/cli-profile-context.js +13 -0
- package/dist/command-manifest.d.ts +15 -0
- package/dist/command-manifest.js +23 -1
- package/dist/command-support.d.ts +438 -0
- package/dist/command-support.js +1610 -0
- package/dist/commands/action-column.d.ts +3 -0
- package/dist/commands/action-column.js +43 -0
- package/dist/commands/activation.d.ts +3 -0
- package/dist/commands/activation.js +24 -0
- package/dist/commands/admin.d.ts +3 -0
- package/dist/commands/admin.js +347 -0
- package/dist/commands/ads.d.ts +3 -0
- package/dist/commands/ads.js +62 -0
- package/dist/commands/agent.d.ts +3 -0
- package/dist/commands/agent.js +274 -0
- package/dist/commands/api-keys.d.ts +3 -0
- package/dist/commands/api-keys.js +77 -0
- package/dist/commands/approvals.d.ts +3 -0
- package/dist/commands/approvals.js +518 -0
- package/dist/commands/auth.d.ts +3 -0
- package/dist/commands/auth.js +230 -0
- package/dist/commands/billing.d.ts +3 -0
- package/dist/commands/billing.js +357 -0
- package/dist/commands/blueprints.d.ts +3 -0
- package/dist/commands/blueprints.js +312 -0
- package/dist/commands/budget.d.ts +3 -0
- package/dist/commands/budget.js +55 -0
- package/dist/commands/callables.d.ts +3 -0
- package/dist/commands/callables.js +111 -0
- package/dist/commands/capabilities.d.ts +3 -0
- package/dist/commands/capabilities.js +44 -0
- package/dist/commands/cells.d.ts +3 -0
- package/dist/commands/cells.js +94 -0
- package/dist/commands/columns.d.ts +3 -0
- package/dist/commands/columns.js +1628 -0
- package/dist/commands/commands.d.ts +3 -0
- package/dist/commands/commands.js +45 -0
- package/dist/commands/comments.d.ts +3 -0
- package/dist/commands/comments.js +188 -0
- package/dist/commands/companies.d.ts +3 -0
- package/dist/commands/companies.js +312 -0
- package/dist/commands/connections.d.ts +3 -0
- package/dist/commands/connections.js +39 -0
- package/dist/commands/context.d.ts +3 -0
- package/dist/commands/context.js +170 -0
- package/dist/commands/copilot.d.ts +3 -0
- package/dist/commands/copilot.js +565 -0
- package/dist/commands/crm.d.ts +3 -0
- package/dist/commands/crm.js +1669 -0
- package/dist/commands/custom-integrations.d.ts +3 -0
- package/dist/commands/custom-integrations.js +140 -0
- package/dist/commands/dashboards.d.ts +3 -0
- package/dist/commands/dashboards.js +240 -0
- package/dist/commands/db.d.ts +3 -0
- package/dist/commands/db.js +190 -0
- package/dist/commands/deliverability.d.ts +3 -0
- package/dist/commands/deliverability.js +90 -0
- package/dist/commands/directory.d.ts +3 -0
- package/dist/commands/directory.js +101 -0
- package/dist/commands/domains.d.ts +3 -0
- package/dist/commands/domains.js +604 -0
- package/dist/commands/egress.d.ts +3 -0
- package/dist/commands/egress.js +130 -0
- package/dist/commands/email.d.ts +3 -0
- package/dist/commands/email.js +49 -0
- package/dist/commands/engagement.d.ts +3 -0
- package/dist/commands/engagement.js +189 -0
- package/dist/commands/enrich-column.d.ts +3 -0
- package/dist/commands/enrich-column.js +149 -0
- package/dist/commands/enrichment.d.ts +3 -0
- package/dist/commands/enrichment.js +49 -0
- package/dist/commands/feedback.d.ts +3 -0
- package/dist/commands/feedback.js +96 -0
- package/dist/commands/feeds.d.ts +3 -0
- package/dist/commands/feeds.js +486 -0
- package/dist/commands/find.d.ts +3 -0
- package/dist/commands/find.js +159 -0
- package/dist/commands/followers.d.ts +3 -0
- package/dist/commands/followers.js +39 -0
- package/dist/commands/formulas.d.ts +3 -0
- package/dist/commands/formulas.js +43 -0
- package/dist/commands/home.d.ts +3 -0
- package/dist/commands/home.js +22 -0
- package/dist/commands/inbox.d.ts +3 -0
- package/dist/commands/inbox.js +779 -0
- package/dist/commands/integrations.d.ts +3 -0
- package/dist/commands/integrations.js +290 -0
- package/dist/commands/knowledge.d.ts +3 -0
- package/dist/commands/knowledge.js +874 -0
- package/dist/commands/lead-sourcing.d.ts +3 -0
- package/dist/commands/lead-sourcing.js +52 -0
- package/dist/commands/limits.d.ts +3 -0
- package/dist/commands/limits.js +54 -0
- package/dist/commands/linkedin.d.ts +3 -0
- package/dist/commands/linkedin.js +275 -0
- package/dist/commands/login.d.ts +3 -0
- package/dist/commands/login.js +347 -0
- package/dist/commands/logout.d.ts +3 -0
- package/dist/commands/logout.js +12 -0
- package/dist/commands/mailboxes.d.ts +3 -0
- package/dist/commands/mailboxes.js +1290 -0
- package/dist/commands/managed-inboxes.d.ts +3 -0
- package/dist/commands/managed-inboxes.js +361 -0
- package/dist/commands/messages.d.ts +3 -0
- package/dist/commands/messages.js +78 -0
- package/dist/commands/notetaker.d.ts +3 -0
- package/dist/commands/notetaker.js +79 -0
- package/dist/commands/observability.d.ts +3 -0
- package/dist/commands/observability.js +125 -0
- package/dist/commands/orgs.d.ts +3 -0
- package/dist/commands/orgs.js +237 -0
- package/dist/commands/people.d.ts +3 -0
- package/dist/commands/people.js +353 -0
- package/dist/commands/posts.d.ts +3 -0
- package/dist/commands/posts.js +139 -0
- package/dist/commands/profiles.d.ts +3 -0
- package/dist/commands/profiles.js +250 -0
- package/dist/commands/projects.d.ts +3 -0
- package/dist/commands/projects.js +94 -0
- package/dist/commands/prompts.d.ts +3 -0
- package/dist/commands/prompts.js +84 -0
- package/dist/commands/publishing.d.ts +3 -0
- package/dist/commands/publishing.js +1419 -0
- package/dist/commands/recipes.d.ts +3 -0
- package/dist/commands/recipes.js +120 -0
- package/dist/commands/reviews.d.ts +3 -0
- package/dist/commands/reviews.js +75 -0
- package/dist/commands/rows.d.ts +3 -0
- package/dist/commands/rows.js +27 -0
- package/dist/commands/runs.d.ts +3 -0
- package/dist/commands/runs.js +37 -0
- package/dist/commands/search.d.ts +3 -0
- package/dist/commands/search.js +182 -0
- package/dist/commands/senders.d.ts +3 -0
- package/dist/commands/senders.js +393 -0
- package/dist/commands/sequences.d.ts +3 -0
- package/dist/commands/sequences.js +2322 -0
- package/dist/commands/session.d.ts +3 -0
- package/dist/commands/session.js +109 -0
- package/dist/commands/signals.d.ts +3 -0
- package/dist/commands/signals.js +289 -0
- package/dist/commands/signup-leads.d.ts +3 -0
- package/dist/commands/signup-leads.js +46 -0
- package/dist/commands/skills.d.ts +3 -0
- package/dist/commands/skills.js +50 -0
- package/dist/commands/sourcing.d.ts +3 -0
- package/dist/commands/sourcing.js +27 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.js +51 -0
- package/dist/commands/supabase.d.ts +3 -0
- package/dist/commands/supabase.js +128 -0
- package/dist/commands/support.d.ts +3 -0
- package/dist/commands/support.js +651 -0
- package/dist/commands/suppressions.d.ts +3 -0
- package/dist/commands/suppressions.js +577 -0
- package/dist/commands/table-ingestions.d.ts +3 -0
- package/dist/commands/table-ingestions.js +145 -0
- package/dist/commands/table-runs.d.ts +3 -0
- package/dist/commands/table-runs.js +277 -0
- package/dist/commands/tables.d.ts +3 -0
- package/dist/commands/tables.js +3492 -0
- package/dist/commands/tags.d.ts +3 -0
- package/dist/commands/tags.js +147 -0
- package/dist/commands/tools.d.ts +3 -0
- package/dist/commands/tools.js +246 -0
- package/dist/commands/update.d.ts +3 -0
- package/dist/commands/update.js +106 -0
- package/dist/commands/verify.d.ts +3 -0
- package/dist/commands/verify.js +27 -0
- package/dist/commands/viewers.d.ts +3 -0
- package/dist/commands/viewers.js +72 -0
- package/dist/commands/voice.d.ts +3 -0
- package/dist/commands/voice.js +351 -0
- package/dist/commands/whatsapp.d.ts +3 -0
- package/dist/commands/whatsapp.js +226 -0
- package/dist/commands/whoami.d.ts +3 -0
- package/dist/commands/whoami.js +110 -0
- package/dist/commands/worker.d.ts +3 -0
- package/dist/commands/worker.js +60 -0
- package/dist/commands/workflows.d.ts +3 -0
- package/dist/commands/workflows.js +1752 -0
- package/dist/commands/workspace.d.ts +3 -0
- package/dist/commands/workspace.js +94 -0
- package/dist/compact-list-flags.d.ts +7 -0
- package/dist/compact-list-flags.js +12 -0
- package/dist/crm-support-flags.js +14 -5
- package/dist/customer-operation-commands.js +8 -6
- package/dist/diagnostic-uploader.d.ts +3 -1
- package/dist/diagnostic-uploader.js +29 -8
- package/dist/help.d.ts +5 -0
- package/dist/help.js +22 -0
- package/dist/index.d.ts +98 -1
- package/dist/index.js +331 -30719
- package/dist/local-module-loader.d.ts +4 -0
- package/dist/local-module-loader.js +156 -0
- package/dist/visual-commands.js +9 -5
- package/node_modules/@oxygen/cli-ugc/dist/commands.js +2 -2
- package/node_modules/@oxygen/shared/dist/agent-session-schedule.d.ts +36 -0
- package/node_modules/@oxygen/shared/dist/agent-session-schedule.js +69 -0
- package/node_modules/@oxygen/shared/dist/agent-sessions.d.ts +14 -5
- package/node_modules/@oxygen/shared/dist/agent-sessions.js +14 -3
- package/node_modules/@oxygen/shared/dist/capability-discovery.js +175 -14
- package/node_modules/@oxygen/shared/dist/compact-list-result.d.ts +6 -0
- package/node_modules/@oxygen/shared/dist/compact-list-result.js +27 -0
- package/node_modules/@oxygen/shared/dist/contracts/agent-sessions.d.ts +12 -1
- package/node_modules/@oxygen/shared/dist/contracts/agent-sessions.js +5 -2
- package/node_modules/@oxygen/shared/dist/contracts/browser-operations.js +4 -2
- package/node_modules/@oxygen/shared/dist/contracts/compact-list-reads.d.ts +57 -0
- package/node_modules/@oxygen/shared/dist/contracts/compact-list-reads.js +23 -0
- package/node_modules/@oxygen/shared/dist/contracts/crm-support.d.ts +52 -0
- package/node_modules/@oxygen/shared/dist/contracts/crm-support.js +43 -2
- package/node_modules/@oxygen/shared/dist/contracts/customer-operations.js +17 -14
- package/node_modules/@oxygen/shared/dist/contracts/knowledge-content-reads.js +1 -1
- package/node_modules/@oxygen/shared/dist/contracts/knowledge-proposal-reads.d.ts +49 -0
- package/node_modules/@oxygen/shared/dist/contracts/knowledge-proposal-reads.js +14 -0
- package/node_modules/@oxygen/shared/dist/contracts/knowledge-sync.js +1 -1
- package/node_modules/@oxygen/shared/dist/contracts/limits-read.js +60 -7
- package/node_modules/@oxygen/shared/dist/contracts/operations.d.ts +9 -1
- package/node_modules/@oxygen/shared/dist/contracts/operations.js +13 -5
- package/node_modules/@oxygen/shared/dist/contracts/publishing-reads.js +1 -1
- package/node_modules/@oxygen/shared/dist/contracts/teammates.d.ts +16 -0
- package/node_modules/@oxygen/shared/dist/contracts/teammates.js +115 -0
- package/node_modules/@oxygen/shared/dist/cost-estimate-view.js +21 -3
- package/node_modules/@oxygen/shared/dist/cost-estimate.d.ts +31 -1
- package/node_modules/@oxygen/shared/dist/cost-estimate.js +56 -15
- package/node_modules/@oxygen/shared/dist/diagnostic-credentials.d.ts +2 -0
- package/node_modules/@oxygen/shared/dist/diagnostic-credentials.js +2 -0
- package/node_modules/@oxygen/shared/dist/diagnostic-lock.js +71 -44
- package/node_modules/@oxygen/shared/dist/diagnostic-spool.d.ts +18 -0
- package/node_modules/@oxygen/shared/dist/diagnostic-spool.js +348 -0
- package/node_modules/@oxygen/shared/dist/diagnostic-storage-failure.d.ts +10 -0
- package/node_modules/@oxygen/shared/dist/diagnostic-storage-failure.js +42 -0
- package/node_modules/@oxygen/shared/dist/diagnostic-storage.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/diagnostic-storage.js +59 -213
- package/node_modules/@oxygen/shared/dist/diagnostics.js +3 -2
- package/node_modules/@oxygen/shared/dist/email-dsn.d.ts +16 -5
- package/node_modules/@oxygen/shared/dist/email-dsn.js +97 -1
- package/node_modules/@oxygen/shared/dist/emailguard-placement-probe.js +5 -0
- package/node_modules/@oxygen/shared/dist/enrichment-intents.js +4 -5
- package/node_modules/@oxygen/shared/dist/file-import.js +5 -2
- package/node_modules/@oxygen/shared/dist/hosted-ai.d.ts +30 -0
- package/node_modules/@oxygen/shared/dist/hosted-ai.js +20 -0
- package/node_modules/@oxygen/shared/dist/knowledge-bootstrap.d.ts +6 -2
- package/node_modules/@oxygen/shared/dist/knowledge-seed-content.d.ts +17 -7
- package/node_modules/@oxygen/shared/dist/knowledge-seed-content.js +81 -17
- package/node_modules/@oxygen/shared/dist/langfuse.js +8 -4
- package/node_modules/@oxygen/shared/dist/mailbox-egress-ownership.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/mailbox-import.d.ts +6 -3
- package/node_modules/@oxygen/shared/dist/mailbox-import.js +9 -9
- package/node_modules/@oxygen/shared/dist/mcp-server-info.d.ts +8 -0
- package/node_modules/@oxygen/shared/dist/mcp-server-info.js +10 -0
- package/node_modules/@oxygen/shared/dist/object-storage.d.ts +10 -0
- package/node_modules/@oxygen/shared/dist/object-storage.js +14 -0
- package/node_modules/@oxygen/shared/dist/plan-limits-view.d.ts +5 -0
- package/node_modules/@oxygen/shared/dist/plan-limits-view.js +17 -1
- package/node_modules/@oxygen/shared/dist/pricing-sheet.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/pricing-sheet.js +1 -1
- package/node_modules/@oxygen/shared/dist/provider-selection.d.ts +15 -0
- package/node_modules/@oxygen/shared/dist/provider-selection.js +3 -0
- package/node_modules/@oxygen/shared/dist/repricing.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/repricing.js +2 -2
- package/node_modules/@oxygen/shared/dist/schedule-label.d.ts +6 -0
- package/node_modules/@oxygen/shared/dist/schedule-label.js +12 -0
- package/node_modules/@oxygen/shared/dist/sequence-failures.d.ts +1 -0
- package/node_modules/@oxygen/shared/dist/sequence-failures.js +20 -6
- package/node_modules/@oxygen/shared/dist/teammate-groups.d.ts +55 -0
- package/node_modules/@oxygen/shared/dist/teammate-groups.js +74 -0
- package/node_modules/@oxygen/shared/dist/teammate-messages.d.ts +52 -0
- package/node_modules/@oxygen/shared/dist/teammate-messages.js +88 -0
- package/node_modules/@oxygen/shared/dist/teammate-notes.d.ts +58 -0
- package/node_modules/@oxygen/shared/dist/teammate-notes.js +73 -0
- package/node_modules/@oxygen/shared/dist/teammate-routines.d.ts +95 -0
- package/node_modules/@oxygen/shared/dist/teammate-routines.js +266 -0
- package/node_modules/@oxygen/shared/dist/teammate-tasks.d.ts +56 -0
- package/node_modules/@oxygen/shared/dist/teammate-tasks.js +114 -0
- package/node_modules/@oxygen/shared/dist/teammates.d.ts +78 -0
- package/node_modules/@oxygen/shared/dist/teammates.js +140 -0
- package/node_modules/@oxygen/shared/dist/user-capability-routing.js +120 -0
- package/node_modules/@oxygen/shared/dist/version.generated.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/version.generated.js +1 -1
- package/node_modules/@oxygen/shared/dist/visual-render.d.ts +9 -1
- package/node_modules/@oxygen/shared/dist/visual-render.js +12 -5
- package/node_modules/@oxygen/shared/dist/warmup-metrics.d.ts +5 -0
- package/node_modules/@oxygen/shared/dist/warmup-metrics.js +44 -0
- package/package.json +1 -1
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { readCreditCeilingOrZero, readPositiveNumber } from "../command-support.js";
|
|
2
|
+
import { requestOxygen } from "../http-client.js";
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
function buildFindBody(capability, options) {
|
|
5
|
+
const body = { capability };
|
|
6
|
+
const set = (key, value) => {
|
|
7
|
+
if (value)
|
|
8
|
+
body[key] = value;
|
|
9
|
+
};
|
|
10
|
+
if (capability === "person") {
|
|
11
|
+
set("linkedin_url", options.linkedinUrl);
|
|
12
|
+
set("linkedin_id", options.linkedinId);
|
|
13
|
+
set("sales_navigator_url", options.salesNavigatorUrl);
|
|
14
|
+
set("email", options.email);
|
|
15
|
+
set("full_name", options.fullName);
|
|
16
|
+
set("first_name", options.firstName);
|
|
17
|
+
set("last_name", options.lastName);
|
|
18
|
+
set("company_domain", options.companyDomain);
|
|
19
|
+
set("company_name", options.companyName);
|
|
20
|
+
if (options.includeRaw)
|
|
21
|
+
body.include_raw = true;
|
|
22
|
+
}
|
|
23
|
+
else if (capability === "company") {
|
|
24
|
+
// The catalog needs no identity and spends nothing; it is the answer to
|
|
25
|
+
// "which fields exist and what do they cost" before any field is named.
|
|
26
|
+
if (options.listFields) {
|
|
27
|
+
body.list_fields = true;
|
|
28
|
+
return body;
|
|
29
|
+
}
|
|
30
|
+
set("domain", options.domain);
|
|
31
|
+
set("name", options.name);
|
|
32
|
+
set("linkedin_url", options.linkedinUrl);
|
|
33
|
+
if (options.fields) {
|
|
34
|
+
const fields = options.fields.split(",").map((field) => field.trim()).filter(Boolean);
|
|
35
|
+
if (fields.length > 0)
|
|
36
|
+
body.fields = fields;
|
|
37
|
+
}
|
|
38
|
+
if (options.checkTechnologies) {
|
|
39
|
+
const technologies = options.checkTechnologies.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
40
|
+
if (technologies.length > 0)
|
|
41
|
+
body.check_technologies = technologies;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
set("linkedin_url", options.linkedinUrl);
|
|
46
|
+
set("full_name", options.fullName);
|
|
47
|
+
set("first_name", options.firstName);
|
|
48
|
+
set("last_name", options.lastName);
|
|
49
|
+
set("email", options.email);
|
|
50
|
+
set("company_domain", options.companyDomain);
|
|
51
|
+
set("company_name", options.companyName);
|
|
52
|
+
set("company_linkedin_url", options.companyLinkedinUrl);
|
|
53
|
+
}
|
|
54
|
+
if (options.mode)
|
|
55
|
+
body.mode = options.mode;
|
|
56
|
+
// Company only: 0 is a real ceiling meaning "run only the zero-credit lanes".
|
|
57
|
+
// The person capabilities are paid on every lane, so 0 stays a usage error
|
|
58
|
+
// there. `!== undefined` because 0 is falsy and would otherwise be dropped.
|
|
59
|
+
const maxCredits = capability === "company"
|
|
60
|
+
? readCreditCeilingOrZero(options.maxCredits)
|
|
61
|
+
: readPositiveNumber(options.maxCredits);
|
|
62
|
+
if (maxCredits !== undefined)
|
|
63
|
+
body.max_credits = maxCredits;
|
|
64
|
+
// Phone-only opt-in; the route ignores it for other capabilities.
|
|
65
|
+
if (options.verify)
|
|
66
|
+
body.verify = true;
|
|
67
|
+
return body;
|
|
68
|
+
}
|
|
69
|
+
export function registerFindFamily(program, handleAsyncAction) {
|
|
70
|
+
program
|
|
71
|
+
.command("find")
|
|
72
|
+
.description("One-shot contact and company lookups over enrichment waterfalls (no table). dry_run previews the plan for free (which lanes would run, in order, and what each costs — not the answer); live spends and needs --max-credits.")
|
|
73
|
+
.addCommand(new Command("email")
|
|
74
|
+
.description("Find a person's work email via an input-aware multi-provider waterfall: a LinkedIn URL, name+domain, or first/last+domain each select the best provider profile, with an email-pattern pre-step and verification. dry_run shows the resolved profile + chain for free.")
|
|
75
|
+
.option("--linkedin-url <url>", "Person LinkedIn profile URL (strongest signal).")
|
|
76
|
+
.option("--full-name <name>", "Person full name.")
|
|
77
|
+
.option("--first-name <name>", "Person first name.")
|
|
78
|
+
.option("--last-name <name>", "Person last name.")
|
|
79
|
+
.option("--company-domain <domain>", "Company apex domain, e.g. acme.com.")
|
|
80
|
+
.option("--company-name <name>", "Company name.")
|
|
81
|
+
.option("--mode <mode>", "dry_run (default) previews the plan and spends nothing; live spends credits and returns the answer.")
|
|
82
|
+
.option("--max-credits <credits>", "Spend ceiling in Oxygen credits, including the platform fee on each successful own-key call, even on a miss. Your provider may separately bill your account under its own rules, outside this ceiling (cap own-key calls with `oxygen limits provider set`). Required for --mode live. Run the free dry_run first: it returns estimate.recommended_max_credits, the ceiling that lets the WHOLE resolved waterfall run, plus estimate.min_credits and a per-leg breakdown. When the resolved chain runs the guessed-address pass (the name+domain and first/last+domain profiles, not the LinkedIn-URL one) the block also carries estimate.pattern_guess_verification_credits — the verification checks that pass bills before any named provider is dialled. A lower ceiling does NOT stop the run: each lane priced above what is left of it is refused on its own (spend_cap_too_low) and the waterfall advances, so a cheaper lane further down the chain can still run and bill.")
|
|
83
|
+
.option("--json", "Print a JSON envelope.")
|
|
84
|
+
.action(async (options) => {
|
|
85
|
+
await handleAsyncAction("find email", options, () => requestOxygen("/api/cli/find/run", { method: "POST", body: buildFindBody("email", options) }));
|
|
86
|
+
}))
|
|
87
|
+
.addCommand(new Command("personal-email")
|
|
88
|
+
.description("Find a person's personal (non-work) email — for ad-audience uploads, recruiting, or founder outreach — via a cost-ordered multi-provider waterfall that bills only on a hit and grades the address with MillionVerifier before returning it. Every default lane keys on a LinkedIn URL; ContactOut also accepts a known email or full name + company. dry_run previews the chain and its price for free.")
|
|
89
|
+
.option("--linkedin-url <url>", "Person LinkedIn profile URL (strongest signal; every default lane accepts it).")
|
|
90
|
+
.option("--email <email>", "Known email as an identity fallback (ContactOut lane).")
|
|
91
|
+
.option("--full-name <name>", "Person full name (with a company domain or name; ContactOut lane).")
|
|
92
|
+
.option("--company-domain <domain>", "Company apex domain, e.g. acme.com.")
|
|
93
|
+
.option("--company-name <name>", "Company name.")
|
|
94
|
+
.option("--mode <mode>", "dry_run (default) previews the plan and spends nothing; live spends credits and returns the answer.")
|
|
95
|
+
.option("--max-credits <credits>", "Spend ceiling in Oxygen credits, including the platform fee on each successful own-key call, even on a miss. Your provider may separately bill your account under its own rules, outside this ceiling (cap own-key calls with `oxygen limits provider set`). Required for --mode live. Run the free dry_run first: it returns estimate.recommended_max_credits, the ceiling that lets the WHOLE resolved waterfall run, plus estimate.min_credits and a per-leg breakdown. A lower ceiling does NOT stop the run: each lane priced above what is left of it is refused on its own (spend_cap_too_low) and the waterfall advances, so a cheaper lane further down the chain can still run and bill.")
|
|
96
|
+
.option("--json", "Print a JSON envelope.")
|
|
97
|
+
.action(async (options) => {
|
|
98
|
+
await handleAsyncAction("find personal-email", options, () => requestOxygen("/api/cli/find/run", { method: "POST", body: buildFindBody("personal_email", options) }));
|
|
99
|
+
}))
|
|
100
|
+
.addCommand(new Command("phone")
|
|
101
|
+
.description("Find a person's mobile phone via a multi-provider waterfall. The provider chain is input-aware: a LinkedIn URL unlocks the full cost-ordered chain (Blitz first), email/name use the providers that accept them.")
|
|
102
|
+
.option("--linkedin-url <url>", "Person LinkedIn profile URL (strongest signal for phone).")
|
|
103
|
+
.option("--email <email>", "Known email as an identity fallback.")
|
|
104
|
+
.option("--full-name <name>", "Person full name.")
|
|
105
|
+
.option("--company-domain <domain>", "Company apex domain.")
|
|
106
|
+
.option("--company-name <name>", "Company name.")
|
|
107
|
+
.option("--verify", "Verify the found number with ClearoutPhone — adds line_type/carrier and keeps the number on a non-verdict (only a genuine 'not valid' is discarded).")
|
|
108
|
+
.option("--mode <mode>", "dry_run (default) previews the plan and spends nothing; live spends credits and returns the answer.")
|
|
109
|
+
.option("--max-credits <credits>", "Spend ceiling in Oxygen credits, including the platform fee on each successful own-key call, even on a miss. Your provider may separately bill your account under its own rules, outside this ceiling (cap own-key calls with `oxygen limits provider set`). Required for --mode live. Run the free dry_run first: it returns estimate.recommended_max_credits, the ceiling that lets the WHOLE resolved waterfall run, plus estimate.min_credits and a per-leg breakdown. A lower ceiling does NOT stop the run: each lane priced above what is left of it is refused on its own (spend_cap_too_low) and the waterfall advances, so a cheaper lane further down the chain can still run and bill.")
|
|
110
|
+
.option("--json", "Print a JSON envelope.")
|
|
111
|
+
.action(async (options) => {
|
|
112
|
+
await handleAsyncAction("find phone", options, () => requestOxygen("/api/cli/find/run", { method: "POST", body: buildFindBody("phone", options) }));
|
|
113
|
+
}))
|
|
114
|
+
.addCommand(new Command("linkedin")
|
|
115
|
+
.description("Resolve a person's LinkedIn URL from name + company (or email), with identity validation. Each lane tried bills until the 2026-09 repricing date; from it a URL found that matches the person costs a flat 5 credits and a miss costs 0.")
|
|
116
|
+
.option("--full-name <name>", "Person full name.")
|
|
117
|
+
.option("--email <email>", "Known email.")
|
|
118
|
+
.option("--company-domain <domain>", "Company apex domain.")
|
|
119
|
+
.option("--company-name <name>", "Company name.")
|
|
120
|
+
.option("--company-linkedin-url <url>", "Company LinkedIn URL.")
|
|
121
|
+
.option("--mode <mode>", "dry_run (default) previews the plan and spends nothing; live spends credits and returns the answer.")
|
|
122
|
+
.option("--max-credits <credits>", "Spend ceiling in Oxygen credits, including the platform fee on each successful own-key call, even on a miss. Your provider may separately bill your account under its own rules, outside this ceiling (cap own-key calls with `oxygen limits provider set`). Required for --mode live. Run the free dry_run first: it returns estimate.recommended_max_credits, the ceiling that lets the WHOLE resolved waterfall run, plus estimate.min_credits and a per-leg breakdown. A lower ceiling does NOT stop the run: each lane priced above what is left of it is refused on its own (spend_cap_too_low) and the waterfall advances, so a cheaper lane further down the chain can still run and bill.")
|
|
123
|
+
.option("--json", "Print a JSON envelope.")
|
|
124
|
+
.action(async (options) => {
|
|
125
|
+
await handleAsyncAction("find linkedin", options, () => requestOxygen("/api/cli/find/run", { method: "POST", body: buildFindBody("linkedin", options) }));
|
|
126
|
+
}))
|
|
127
|
+
.addCommand(new Command("person")
|
|
128
|
+
.description("Enrich one person from a LinkedIn URL, a LinkedIn public id or member id, a Sales Navigator link, or an email / name + company: one managed profile lookup returns the profile block — first, last and full name, current company and its LinkedIn URL, job title, job start date, education and school, headline, bio, location and follower count — the same fields the person_enrich table preset extracts for free. An email or name is first resolved to the profile through the LinkedIn URL waterfall (priced as an identity prerequisite). A member id uses managed enrichment. A Sales Navigator link resolves on the workspace's own HarvestAPI key. dry_run previews the lookup and its price for free.")
|
|
129
|
+
.option("--linkedin-url <url>", "Person LinkedIn profile URL (linkedin.com/in/<handle>).")
|
|
130
|
+
.option("--linkedin-id <id>", "LinkedIn public identifier (the part after /in/), or a member ID beginning ACo/ACw; both support managed enrichment. Preview checks input shape and price without resolving the ID.")
|
|
131
|
+
.option("--sales-navigator-url <url>", "Sales Navigator lead or people link; resolved on the workspace's own HarvestAPI key.")
|
|
132
|
+
.option("--email <email>", "Known email; resolved to the profile through the LinkedIn URL waterfall first.")
|
|
133
|
+
.option("--full-name <name>", "Person full name; with --company-domain or --company-name, resolved through the LinkedIn URL waterfall first.")
|
|
134
|
+
.option("--first-name <name>", "Person first name.")
|
|
135
|
+
.option("--last-name <name>", "Person last name.")
|
|
136
|
+
.option("--company-domain <domain>", "Company apex domain, e.g. acme.com.")
|
|
137
|
+
.option("--company-name <name>", "Company name.")
|
|
138
|
+
.option("--include-raw", "Also return the provider's raw profile payload (profile_raw) for fields the profile block does not carry.")
|
|
139
|
+
.option("--mode <mode>", "dry_run (default) previews the plan and spends nothing; live spends credits and returns the profile.")
|
|
140
|
+
.option("--max-credits <credits>", "Spend ceiling in Oxygen credits, including the platform fee on each successful own-key call, even on a miss. Your provider may separately bill your account under its own rules, outside this ceiling (cap own-key calls with `oxygen limits provider set`). Required for --mode live. Run the free dry_run first: estimate.recommended_max_credits funds the profile lookup plus, for an email or name input, every lane of the LinkedIn URL waterfall that resolves it.")
|
|
141
|
+
.option("--json", "Print a JSON envelope.")
|
|
142
|
+
.action(async (options) => {
|
|
143
|
+
await handleAsyncAction("find person", options, () => requestOxygen("/api/cli/find/run", { method: "POST", body: buildFindBody("person", options) }));
|
|
144
|
+
}))
|
|
145
|
+
.addCommand(new Command("company")
|
|
146
|
+
.description("Enrich a company via a waterfall: identity, firmographics, structured funding, competitors, corporate structure, acquisitions, news, job openings, tech stack, web-presence URLs. `--list-fields` prints the catalog with per-field cost.")
|
|
147
|
+
.option("--domain <domain>", "Company apex domain.")
|
|
148
|
+
.option("--name <name>", "Company name.")
|
|
149
|
+
.option("--linkedin-url <url>", "Company LinkedIn URL.")
|
|
150
|
+
.option("--fields <fields>", "Comma-separated field keys from --list-fields (e.g. headcount,industry,funding_stage,latest_funding_round,competitors,technologies,job_openings). Defaults to domain,linkedin_url,headcount,industry,description,founded_year,hq_country — the identity plus everything one profile lookup answers for free. Unknown keys are refused, never silently dropped.")
|
|
151
|
+
.option("--list-fields", "Print the field catalog (category, description, provider count, per-row credits: free / fixed / ~estimated) and exit. Needs no identity; spends nothing.")
|
|
152
|
+
.option("--check-technologies <names>", "Comma-separated technology names for the technology_check field, answered yes/no against the detected stack (e.g. hubspot,salesforce).")
|
|
153
|
+
.option("--mode <mode>", "dry_run (default) previews the plan and spends nothing; live spends credits and returns the answer.")
|
|
154
|
+
.option("--max-credits <credits>", "Spend ceiling in Oxygen credits, including the platform fee on each successful own-key call, even on a miss. Your provider may separately bill your account under its own rules, outside this ceiling (cap own-key calls with `oxygen limits provider set`). Required for --mode live; 0 can still call providers on zero-credit lanes and reuse any priced lane this workspace already has a cached answer for (the other priced lanes are skipped as credit_ceiling_reached). Run the free dry_run first: it returns estimate.recommended_max_credits, the ceiling that funds every lane in the plan, and estimate.min_credits, what the plan costs if each field is answered by its first lane.")
|
|
155
|
+
.option("--json", "Print a JSON envelope.")
|
|
156
|
+
.action(async (options) => {
|
|
157
|
+
await handleAsyncAction("find company", options, () => requestOxygen("/api/cli/find/run", { method: "POST", body: buildFindBody("company", options) }));
|
|
158
|
+
}));
|
|
159
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { requestOxygen } from "../http-client.js";
|
|
2
|
+
import { readOption } from "../util.js";
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
export function registerFollowersFamily(program, handleAsyncAction) {
|
|
5
|
+
program.addCommand(new Command("followers")
|
|
6
|
+
.description("Read the followers of YOUR OWN connected LinkedIn account into a Clay-like workspace table you can enrich, qualify, and enroll from. Imports run as a slow, durable background drip under a dedicated conservative read budget — they never burst and never starve the sequencer's own reads. For the followers of a company page — a competitor's audience — use `oxygen tables followers check` instead.")
|
|
7
|
+
.addCommand(new Command("import")
|
|
8
|
+
.description("Start (or re-arm) a followers import. Followers drip into a workspace table + the deduped mirror over many ticks; poll `followers status` to watch them accrue. The import keeps itself fresh by periodically re-walking followers in the background (new followers dedupe in). No messages are sent and no Oxygen credits are charged.")
|
|
9
|
+
.option("--account <ref>", "Sender account to import (sender id, connection id, or Unipile account id). Omit to import every active LinkedIn account.")
|
|
10
|
+
.option("--table <ref>", "Existing workspace table (id or slug) to import into. Omit to create or reuse a 'LinkedIn Followers' table.")
|
|
11
|
+
.option("--json", "Print a JSON envelope.")
|
|
12
|
+
.action(async (options) => {
|
|
13
|
+
await handleAsyncAction("followers import", options, () => {
|
|
14
|
+
const account = readOption(options.account);
|
|
15
|
+
const table = readOption(options.table);
|
|
16
|
+
return requestOxygen("/api/cli/linkedin/followers/import", {
|
|
17
|
+
method: "POST",
|
|
18
|
+
body: {
|
|
19
|
+
...(account ? { account } : {}),
|
|
20
|
+
...(table ? { table } : {}),
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
}))
|
|
25
|
+
.addCommand(new Command("status")
|
|
26
|
+
.description("Show followers-import progress (per-sender drip status, followers ingested, last error) plus a preview of the followers table and a deep-link to open it.")
|
|
27
|
+
.option("--account <ref>", "Scope to one sender account (sender id, connection id, or Unipile account id).")
|
|
28
|
+
.option("--json", "Print a JSON envelope.")
|
|
29
|
+
.action(async (options) => {
|
|
30
|
+
await handleAsyncAction("followers status", options, () => {
|
|
31
|
+
const account = readOption(options.account);
|
|
32
|
+
const params = new URLSearchParams();
|
|
33
|
+
if (account)
|
|
34
|
+
params.set("account", account);
|
|
35
|
+
const suffix = params.toString();
|
|
36
|
+
return requestOxygen(`/api/cli/linkedin/followers/status${suffix ? `?${suffix}` : ""}`);
|
|
37
|
+
});
|
|
38
|
+
})));
|
|
39
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { requestOxygen } from "../http-client.js";
|
|
2
|
+
import { readOption } from "../util.js";
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
export function registerFormulasFamily(program, handleAsyncAction) {
|
|
5
|
+
program
|
|
6
|
+
.command("formulas")
|
|
7
|
+
.description("Formula language for formula columns and per-column run conditions (only-run-if).")
|
|
8
|
+
.addCommand(new Command("functions")
|
|
9
|
+
.description("List every formula function (name, signature, examples), the operator grammar, and the expression_notes that a signature cannot teach (bare column keys, string escapes, no regex flags, read-time evaluation). The same language powers formula columns and --run-condition gates.")
|
|
10
|
+
.option("--category <category>", "Filter by category: logic, string, number, date, url_email, array, json, null_handling, cross_row.")
|
|
11
|
+
.option("--query <text>", "Find functions by name, signature or description.")
|
|
12
|
+
.option("--json", "Print a JSON envelope.")
|
|
13
|
+
.action(async (options) => {
|
|
14
|
+
await handleAsyncAction("formulas functions", options, () => {
|
|
15
|
+
const category = readOption(options.category);
|
|
16
|
+
const params = new URLSearchParams();
|
|
17
|
+
if (category)
|
|
18
|
+
params.set("category", category);
|
|
19
|
+
if (readOption(options.query))
|
|
20
|
+
params.set("query", readOption(options.query));
|
|
21
|
+
const query = params.size ? `?${params.toString()}` : "";
|
|
22
|
+
return requestOxygen(`/api/cli/tables/formulas/functions${query}`, { method: "GET" });
|
|
23
|
+
});
|
|
24
|
+
}))
|
|
25
|
+
.addCommand(new Command("validate")
|
|
26
|
+
.description("Validate a formula against a table and preview its output on sample rows — free, no writes. Draft → validate → attach with `oxygen columns add --kind formula`.")
|
|
27
|
+
.argument("<table>", "Table id or slug.")
|
|
28
|
+
.requiredOption("--expression <expr>", "The formula expression to validate, e.g. \"if(score > 80, 'hot', 'warm')\".")
|
|
29
|
+
.option("--rows <n>", "How many sample rows to evaluate (0-25, default 5).")
|
|
30
|
+
.option("--row-id <id...>", "Evaluate specific row ids instead of the first rows.")
|
|
31
|
+
.option("--json", "Print a JSON envelope.")
|
|
32
|
+
.action(async (table, options) => {
|
|
33
|
+
await handleAsyncAction("formulas validate", options, () => requestOxygen("/api/cli/tables/formulas/validate", {
|
|
34
|
+
method: "POST",
|
|
35
|
+
body: {
|
|
36
|
+
table,
|
|
37
|
+
expression: options.expression,
|
|
38
|
+
...(readOption(options.rows) ? { sample_limit: Number(readOption(options.rows)) } : {}),
|
|
39
|
+
...(options.rowId && options.rowId.length > 0 ? { row_ids: options.rowId } : {}),
|
|
40
|
+
},
|
|
41
|
+
}));
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { homeStandupMarksSeen } from "../home-standup.js";
|
|
2
|
+
import { requestOxygen } from "../http-client.js";
|
|
3
|
+
/**
|
|
4
|
+
* `oxygen home`: the outcome-neutral workspace standup. Only the plain view printed to
|
|
5
|
+
* an interactive terminal is the person looking and marks Home as seen; `--json`, or
|
|
6
|
+
* output an agent's shell or a pipe captures, sends `mark_seen=false` and leaves the
|
|
7
|
+
* person's Home marker alone (founder decision, 2026-10-05; see home-standup.ts).
|
|
8
|
+
*/
|
|
9
|
+
async function readHomeStandup(options) {
|
|
10
|
+
return requestOxygen(homeStandupMarksSeen({ json: options.json, isTTY: process.stdout.isTTY })
|
|
11
|
+
? "/api/cli/home/standup"
|
|
12
|
+
: "/api/cli/home/standup?mark_seen=false");
|
|
13
|
+
}
|
|
14
|
+
export function registerHomeFamily(program, handleAsyncAction) {
|
|
15
|
+
program
|
|
16
|
+
.command("home")
|
|
17
|
+
.description("Your workspace standup: what happened since you last looked, what needs you, and a year of workspace activity. 0 credits. With --json, or when the output is not a terminal (an agent's shell or a pipe), it is a pure read: the same window, and your Home \"last seen\" marker stays where you left it. Only the plain view in a terminal counts as you looking: like opening Home on the web, it marks Home as seen (at most every four hours), so your next standup counts from then.")
|
|
18
|
+
.option("--json", "Print a JSON envelope. A pure read: leaves your Home \"last seen\" marker alone.")
|
|
19
|
+
.action(async (options) => {
|
|
20
|
+
await handleAsyncAction("home standup", options, () => readHomeStandup(options));
|
|
21
|
+
});
|
|
22
|
+
}
|