@series-a/cli 0.2.1 → 0.6.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.
@@ -110,6 +110,77 @@ export function registerLeads(program) {
110
110
  } catch (e) { fail(e); }
111
111
  });
112
112
 
113
+ withCommonOpts(leads.command("import-from <source>"))
114
+ .description("Import leads from any source: linkedin_search | company_search | post_reactors | paste_profiles | csv | heyreach")
115
+ .option("--query <q>", "search keywords (linkedin_search / company_search)")
116
+ .option("--post <url>", "LinkedIn post URL (post_reactors)")
117
+ .option("--file <path>", "CSV or pasted-profile text file (csv / paste_profiles / heyreach)")
118
+ .option("--audience <name>", "audience (segment) name or id to attach to")
119
+ .option("--campaign <id>", "campaign id (required for heyreach)")
120
+ .option("--limit <n>", "max prospects for LinkedIn sources", "50")
121
+ .option("--no-enrich", "skip the LinkedIn verify + enrich chain")
122
+ .action(async function (source) {
123
+ try {
124
+ const o = this.optsWithGlobals();
125
+ const params = {
126
+ source,
127
+ query: o.query,
128
+ post_url: o.post,
129
+ audience: o.audience,
130
+ campaign_id: o.campaign,
131
+ limit: Number(o.limit),
132
+ enrich: o.enrich !== false,
133
+ };
134
+ if (o.file) {
135
+ const text = await readFile(o.file, "utf8");
136
+ if (source === "paste_profiles") params.text = text;
137
+ else params.csv = text;
138
+ }
139
+ const r = await call("leads", "import", params, ctxFrom(this));
140
+ emit(this, r, (d) => process.stdout.write(
141
+ `✓ Imported ${d.imported ?? 0} leads (${d.duplicates ?? 0} duplicates, ${d.skipped ?? 0} skipped, ${d.failed ?? 0} failed)\n` +
142
+ (d.job_id ? ` job: ${d.job_id}\n` : "")));
143
+ } catch (e) { fail(e); }
144
+ });
145
+
146
+ withCommonOpts(leads.command("import-status <jobId>"))
147
+ .description("Poll a running lead import")
148
+ .action(async function (jobId) {
149
+ try {
150
+ const r = await call("leads", "import_status", { job_id: jobId }, ctxFrom(this));
151
+ emit(this, r, (d) => process.stdout.write(JSON.stringify(d.job, null, 2) + "\n"));
152
+ } catch (e) { fail(e); }
153
+ });
154
+
155
+ withCommonOpts(leads.command("update <id>"))
156
+ .description("Update a single lead")
157
+ .option("--name <v>").option("--title <v>").option("--company <v>")
158
+ .option("--email <v>").option("--linkedin <v>").option("--persona <v>")
159
+ .option("--score <n>").option("--status <v>").option("--notes <v>")
160
+ .action(async function (id) {
161
+ try {
162
+ const o = this.optsWithGlobals();
163
+ const params = { id };
164
+ for (const [k, v] of Object.entries({
165
+ name: o.name, title: o.title, company: o.company, email: o.email,
166
+ linkedin_url: o.linkedin, persona_tag: o.persona,
167
+ score: o.score !== undefined ? Number(o.score) : undefined,
168
+ status: o.status, notes: o.notes,
169
+ })) if (v !== undefined) params[k] = v;
170
+ const r = await call("leads", "update", params, ctxFrom(this));
171
+ emit(this, r, (d) => process.stdout.write(`✓ Updated ${d.lead?.name ?? id}\n`));
172
+ } catch (e) { fail(e); }
173
+ });
174
+
175
+ withCommonOpts(leads.command("delete <id>"))
176
+ .description("Delete a lead")
177
+ .action(async function (id) {
178
+ try {
179
+ const r = await call("leads", "delete", { id }, ctxFrom(this));
180
+ emit(this, r, () => process.stdout.write(`✓ Deleted ${id}\n`));
181
+ } catch (e) { fail(e); }
182
+ });
183
+
113
184
  withCommonOpts(leads.command("verify <id>"))
114
185
  .description("Run LinkedIn verification on a lead")
115
186
  .action(async function (id) {
@@ -300,13 +371,16 @@ export function registerSequences(program) {
300
371
 
301
372
  withCommonOpts(s.command("add-step <id>"))
302
373
  .description("Append a step to a sequence")
303
- .requiredOption("--action <action>", "viewProfile|addReaction|addComment|sendInvitation|sendMessage|wait")
374
+ .requiredOption(
375
+ "--action <action>",
376
+ "viewProfile|addReaction|addComment|sendInvitation|sendMessage|loopBack|createOpportunity|enrichLead|ifAccepted|ifReplied|ifConnection|ifNetworkDistance|stopOnReply|wait|wait_3h|wait_1d|wait_2d|wait_3d|wait_5d",
377
+ )
304
378
  .option("--text <message>", "message_content (required for addComment/sendInvitation/sendMessage)")
305
379
  .option("--delay <days>", "delay_days before this step", "0")
306
380
  .option("--variant <v>", "variant label", "A")
307
- .option("--step-type <t>", "action|branch|wait", "action")
308
- .option("--channel <c>", "channel", "linkedin")
309
- .option("--branch <label>", "branch_label (for branching steps)")
381
+ .option("--step-type <t>", "action|condition|delay (defaults from --action)")
382
+ .option("--channel <c>", "channel (defaults from --action)")
383
+ .option("--branch <label>", "branch_label: yes|no (for steps under a condition)")
310
384
  .option("--parent-step <id>", "parent_step_id (for branches)")
311
385
  .option("--order <n>", "explicit step_order (defaults to max+1)")
312
386
  .action(async function (id, opts) {
@@ -552,6 +626,8 @@ export function registerKnowledge(program) {
552
626
  .option("--visibility <v>", "workspace | private (default: workspace)")
553
627
  .option("--no-summarize", "skip AI auto-tag/classify (raw insert only)")
554
628
  .option("--no-scrape", "skip Firecrawl scrape for --url (URL stored as bookmark)")
629
+ .option("--style-reference", "flag as a Tone-of-Voice style reference (for known author documents)")
630
+ .option("--auto-style", "score as a style reference on arrival and auto-flag if it meets the threshold (default 70)")
555
631
  .action(async function (opts) {
556
632
  try {
557
633
  const sources = [opts.url, opts.text, opts.file].filter(Boolean);
@@ -575,6 +651,8 @@ export function registerKnowledge(program) {
575
651
  visibility: opts.visibility,
576
652
  skip_summarize: opts.summarize === false ? true : undefined,
577
653
  skip_scrape: opts.scrape === false ? true : undefined,
654
+ is_style_reference: opts.styleReference === true ? true : undefined,
655
+ auto_style_reference: opts.autoStyle === true ? true : undefined,
578
656
  };
579
657
  const r = await call("knowledge", "add", params, ctxFrom(this));
580
658
  emit(this, r, (d) => {
@@ -586,7 +664,11 @@ export function registerKnowledge(program) {
586
664
  ` category: ${it.category}\n` +
587
665
  ` tags: ${(it.tags || []).join(", ") || "(none)"}\n` +
588
666
  (it.summary ? ` summary: ${truncate(it.summary, 240)}\n` : "") +
589
- (d.ai?.success === false ? ` ⚠ AI classify: ${d.ai.error}\n` : ""),
667
+ (it.is_style_reference ? ` ★ style reference\n` : "") +
668
+ (d.ai?.success === false ? ` ⚠ AI classify: ${d.ai.error}\n` : "") +
669
+ (d.style_reference_triage?.data?.results?.[0] && !it.is_style_reference
670
+ ? ` style triage: ${d.style_reference_triage.data.results[0].score}/100 — ${d.style_reference_triage.data.results[0].reason}\n`
671
+ : ""),
590
672
  );
591
673
  });
592
674
  } catch (e) { fail(e); }
@@ -599,6 +681,7 @@ export function registerKnowledge(program) {
599
681
  .option("--category <c>", "set category")
600
682
  .option("--tags <csv>", "replace tags (comma-separated)")
601
683
  .option("--visibility <v>", "workspace | private")
684
+ .option("--style-reference <on|off>", "flag/unflag as a Tone-of-Voice style reference")
602
685
  .action(async function (id, opts) {
603
686
  try {
604
687
  const patch = {
@@ -608,6 +691,7 @@ export function registerKnowledge(program) {
608
691
  category: opts.category,
609
692
  tags: opts.tags ? opts.tags.split(",").map((s) => s.trim()).filter(Boolean) : undefined,
610
693
  visibility: opts.visibility,
694
+ is_style_reference: opts.styleReference === "on" ? true : opts.styleReference === "off" ? false : undefined,
611
695
  };
612
696
  const r = await call("knowledge", "update", patch, ctxFrom(this));
613
697
  emit(this, r, (d) => process.stdout.write(`✓ Updated ${d.item?.id}\n`));
@@ -759,8 +843,51 @@ export function registerContent(program) {
759
843
  emit(this, r, (d) => process.stdout.write(`✓ Deleted ${d.deleted}\n`));
760
844
  } catch (e) { fail(e); }
761
845
  });
846
+
847
+ withCommonOpts(c.command("generate"))
848
+ .description("Generate a draft via agent-content-creator (KB + reference library grounded, URL-sanitised, citations recorded)")
849
+ .requiredOption("--angle <text>", "topic / angle for the draft")
850
+ .option("--format <f>", "blog | linkedin_post | video | explainer_video", "blog")
851
+ .option("--signal <id...>", "intelligence_signals ids to ground on (repeatable)")
852
+ .option("--reference <id...>", "knowledge_items ids to ground on (repeatable)")
853
+ .option("--grounding-text <text>", "extra freeform grounding to append")
854
+ .option("--wait", "block until the job completes (up to 4 min)")
855
+ .action(async function (opts) {
856
+ try {
857
+ const r = await call("content", "generate", {
858
+ angle: opts.angle,
859
+ format: opts.format,
860
+ signal_ids: opts.signal,
861
+ reference_item_ids: opts.reference,
862
+ grounding_text: opts.groundingText,
863
+ async: !opts.wait,
864
+ }, ctxFrom(this));
865
+ emit(this, r, (d) => {
866
+ if (d.content) {
867
+ process.stdout.write(`✓ Draft ${d.content.id} (${d.content.type}, ${d.citations?.length ?? 0} citations)\n`);
868
+ } else {
869
+ process.stdout.write(`⏳ Queued job ${d.job_id} — poll with: advisoros agents job-status ${d.job_id}\n`);
870
+ }
871
+ });
872
+ } catch (e) { fail(e); }
873
+ });
874
+
875
+ withCommonOpts(c.command("citations <id>"))
876
+ .description("List every source (signal, reference, transcript, published) recorded for a content item")
877
+ .action(async function (id) {
878
+ try {
879
+ const r = await call("content", "citations", { id }, ctxFrom(this));
880
+ emit(this, r, (d) => {
881
+ process.stdout.write(table(
882
+ ["kind", "id", "title", "url"],
883
+ (d.citations || []).map((c) => [c.source_kind, truncate(c.source_id ?? "", 8), truncate(c.title ?? "", 40), truncate(c.source_url ?? "", 60)]),
884
+ ) + `\n${d.citations?.length ?? 0} citations\n`);
885
+ });
886
+ } catch (e) { fail(e); }
887
+ });
762
888
  }
763
889
 
890
+
764
891
  export function registerCalendar(program) {
765
892
  const cal = program.command("calendar").description("Manage the content calendar");
766
893
 
@@ -1104,6 +1231,42 @@ export function registerPipelines(program) {
1104
1231
  export function registerAgents(program) {
1105
1232
  const a = program.command("agents").description("List, create, configure and invoke agents");
1106
1233
 
1234
+ withCommonOpts(a.command("trigger <name>"))
1235
+ .description("Trigger an agent by name with optional JSON input")
1236
+ .option("--input <json>", "JSON input payload", "{}")
1237
+ .action(async function (name) {
1238
+ try {
1239
+ const o = this.optsWithGlobals();
1240
+ let input = {};
1241
+ try { input = JSON.parse(o.input); } catch { throw new Error("--input must be valid JSON"); }
1242
+ const r = await call("agents", "trigger", { agent_name: name, input }, ctxFrom(this));
1243
+ emit(this, r, (d) => process.stdout.write(JSON.stringify(d.run, null, 2) + "\n"));
1244
+ } catch (e) { fail(e); }
1245
+ });
1246
+
1247
+ withCommonOpts(a.command("history"))
1248
+ .description("Recent agent runs and jobs")
1249
+ .option("--agent <name>", "filter by agent name")
1250
+ .option("--days <n>", "look-back window", "30")
1251
+ .option("--limit <n>", "max rows", "50")
1252
+ .action(async function () {
1253
+ try {
1254
+ const o = this.optsWithGlobals();
1255
+ const r = await call("agents", "history", {
1256
+ agent_name: o.agent, days: Number(o.days), limit: Number(o.limit),
1257
+ }, ctxFrom(this));
1258
+ emit(this, r, (d) => {
1259
+ process.stdout.write(table(
1260
+ ["when", "agent", "status", "results"],
1261
+ (d.runs || []).map((x) => [
1262
+ String(x.created_at ?? "").slice(0, 16), truncate(x.agent_name, 30),
1263
+ x.status ?? "", String(x.results_count ?? ""),
1264
+ ]),
1265
+ ) + `\n${d.runs?.length ?? 0} runs, ${d.jobs?.length ?? 0} jobs\n`);
1266
+ });
1267
+ } catch (e) { fail(e); }
1268
+ });
1269
+
1107
1270
  withCommonOpts(a.command("list"))
1108
1271
  .description("List available agents")
1109
1272
  .option("--scope <s>", "workspace | global | both (default: both)")
package/src/index.mjs CHANGED
@@ -6,14 +6,21 @@ import {
6
6
  registerCalendar, registerSignals, registerPipelines, registerAuthority,
7
7
  registerBriefs,
8
8
  } from "./commands/resources.mjs";
9
+ import {
10
+ registerCampaignAnalytics, registerAnalytics, registerSafety, registerCtas,
11
+ registerNotifications, registerAudiences, registerNewsletter, registerVideo,
12
+ registerWatchlist, registerMeetings, registerActivity, registerWorkspacesExtras,
13
+ registerExport, registerIntegrations,
14
+ } from "./commands/insights.mjs";
9
15
  import { registerFlow } from "./commands/flow.mjs";
16
+ import { registerVaultSync } from "./commands/knowledge-sync.mjs";
10
17
 
11
18
  const program = new Command();
12
19
 
13
20
  program
14
21
  .name("advisoros")
15
- .description("AdvisorOS CLI — drive leads, campaigns, sequences and agents from your terminal.")
16
- .version("0.1.0")
22
+ .description("AdvisorPro CLI — drive leads, campaigns, sequences and agents from your terminal.")
23
+ .version("0.5.0")
17
24
  .option("--json", "machine-readable JSON output (applies to all subcommands)");
18
25
 
19
26
  registerAuth(program);
@@ -29,9 +36,29 @@ registerPipelines(program);
29
36
  registerAuthority(program);
30
37
  registerBriefs(program);
31
38
  registerAgents(program);
39
+ registerIntegrations(program);
40
+
41
+ // Analytics, safety guardrails and the remaining resource surface.
42
+ registerCampaignAnalytics(program);
43
+ registerAnalytics(program);
44
+ registerSafety(program);
45
+ registerCtas(program);
46
+ registerNotifications(program);
47
+ registerAudiences(program);
48
+ registerNewsletter(program);
49
+ registerVideo(program);
50
+ registerWatchlist(program);
51
+ registerMeetings(program);
52
+ registerActivity(program);
53
+ registerWorkspacesExtras(program);
54
+ registerExport(program);
55
+
56
+ registerVaultSync(program);
57
+
32
58
  registerFlow(program);
33
59
 
34
60
  program.parseAsync(process.argv).catch((e) => {
35
61
  process.stderr.write(`✖ ${e?.message ?? e}\n`);
36
62
  process.exit(1);
37
63
  });
64
+