@series-a/cli 1.2.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +175 -39
- package/LICENSE +7 -0
- package/README.md +257 -91
- package/SKILLS.md +344 -0
- package/bin/advisoros.mjs +2 -0
- package/package.json +50 -15
- package/src/api.mjs +102 -0
- package/src/commands/auth.mjs +193 -0
- package/src/commands/brand.mjs +439 -0
- package/src/commands/flow.mjs +175 -0
- package/src/commands/insights.mjs +1813 -0
- package/src/commands/knowledge-sync.mjs +519 -0
- package/src/commands/resources.mjs +2196 -0
- package/src/commands/strategies.mjs +242 -0
- package/src/commands/voice.mjs +212 -0
- package/src/config.mjs +82 -0
- package/src/index.mjs +77 -0
- package/src/ui.mjs +104 -0
- package/bin/setu.mjs +0 -607
- package/lib/api.mjs +0 -84
- package/lib/config.mjs +0 -42
- package/lib/ui.mjs +0 -68
package/README.md
CHANGED
|
@@ -1,151 +1,317 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @series-a/cli
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A command-line interface to the AdvisorPro platform — drive leads, campaigns, sequences and agents from your terminal. Built on top of the [`/agent-api`](https://github.com/series-a/advisoros/blob/main/docs/agent-api.md) M2M router, so anything the CLI does is auditable and workspace-scoped.
|
|
4
|
+
|
|
5
|
+
---
|
|
4
6
|
|
|
5
7
|
## Install
|
|
6
8
|
|
|
7
9
|
```bash
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
# Run without installing — always fetches latest
|
|
11
|
+
npx @series-a/cli@latest --help
|
|
12
|
+
|
|
13
|
+
# Pin a version (recommended for CI)
|
|
14
|
+
npx @series-a/cli@0.1.0 --help
|
|
15
|
+
|
|
16
|
+
# Or install globally
|
|
17
|
+
npm i -g @series-a/cli
|
|
18
|
+
advisoros --help
|
|
10
19
|
```
|
|
11
20
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
21
|
+
Requires **Node.js ≥ 20**.
|
|
22
|
+
|
|
23
|
+
> Releases are tagged `cli-vX.Y.Z` in the repo and published to npm with [provenance](https://docs.npmjs.com/generating-provenance-statements). See [`CHANGELOG.md`](./CHANGELOG.md).
|
|
24
|
+
|
|
25
|
+
## 1. Get an API key
|
|
26
|
+
|
|
27
|
+
1. Sign in to AdvisorPro.
|
|
28
|
+
2. Open **Settings → API Keys**.
|
|
29
|
+
3. Click **New key** → choose **Workspace** scope (recommended).
|
|
30
|
+
4. Copy the key — you won't see it again.
|
|
31
|
+
|
|
32
|
+
The **CLI quickstart** card on that page shows a copy-paste `npx` command pre-filled with your workspace ID.
|
|
33
|
+
|
|
34
|
+
> Admin keys (cross-workspace) also work but are intentionally restricted. Default to workspace keys.
|
|
15
35
|
|
|
16
|
-
##
|
|
36
|
+
## 2. Log in
|
|
17
37
|
|
|
18
38
|
```bash
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
setu practice review <draft-id>
|
|
22
|
-
setu practice publish <draft-id>
|
|
39
|
+
npx @series-a/cli@latest login
|
|
40
|
+
# Prompts for API key + workspace ID (the 6-char slug, e.g. dmw9wj)
|
|
23
41
|
```
|
|
24
42
|
|
|
25
|
-
|
|
26
|
-
pulls their Google listing (address, phone, rating, reviews, opening hours) and
|
|
27
|
-
returns a readiness score. Nothing is public until `publish`.
|
|
43
|
+
### Admin login
|
|
28
44
|
|
|
29
|
-
|
|
30
|
-
"Unclaimed" badge, ranked below live subscribed practices, with enquiry capture
|
|
31
|
-
instead of booking. It also seeds any clinicians the AI detected (skip with
|
|
32
|
-
`--no-dentists`).
|
|
45
|
+
Admin keys (`advos_admin_…`) are detected automatically — no workspace prompt:
|
|
33
46
|
|
|
34
|
-
|
|
47
|
+
```bash
|
|
48
|
+
advisoros login --admin
|
|
49
|
+
# ✓ Logged in as admin profile "default" — N workspaces reachable
|
|
50
|
+
|
|
51
|
+
advisoros workspaces list # admin-only, no workspace needed
|
|
52
|
+
advisoros campaigns list --workspace dmw9wj # pass workspace per command
|
|
53
|
+
advisoros whoami # shows scope: admin (cross-workspace)
|
|
54
|
+
```
|
|
35
55
|
|
|
36
|
-
|
|
56
|
+
Multiple workspaces?
|
|
37
57
|
|
|
38
58
|
```bash
|
|
39
|
-
|
|
59
|
+
advisoros login --profile acme # save as "acme"
|
|
60
|
+
advisoros leads list --profile acme # use the named profile
|
|
40
61
|
```
|
|
41
62
|
|
|
42
|
-
|
|
43
|
-
are listed at the end so you can retry them.
|
|
44
|
-
|
|
45
|
-
## Claim links
|
|
63
|
+
Config is stored at `~/.advisoros/config.json` with mode `0600`. You can also use env vars: `ADVISOROS_API_KEY`, `ADVISOROS_WORKSPACE_ID`, `ADVISOROS_PROFILE`, `ADVISOROS_BASE_URL`.
|
|
46
64
|
|
|
47
65
|
```bash
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
66
|
+
advisoros whoami
|
|
67
|
+
advisoros profiles
|
|
68
|
+
advisoros logout --profile acme
|
|
51
69
|
```
|
|
52
70
|
|
|
53
|
-
|
|
54
|
-
by their email domain matching their website, or by a code sent to the public
|
|
55
|
-
contact address on their Google listing. On success the profile transfers to
|
|
56
|
-
them, pre-filled, and they continue through the normal onboarding and
|
|
57
|
-
subscription flow.
|
|
71
|
+
## 3. Command reference
|
|
58
72
|
|
|
59
|
-
|
|
73
|
+
Global flags (work on every subcommand):
|
|
74
|
+
|
|
75
|
+
| Flag | Description |
|
|
76
|
+
|---|---|
|
|
77
|
+
| `--json` | Emit raw JSON instead of formatted tables. |
|
|
78
|
+
| `-w, --workspace <id>` | Override the workspace from your profile. |
|
|
79
|
+
| `-p, --profile <name>` | Pick a saved profile. |
|
|
80
|
+
| `--api-key <key>` | Override the saved API key. |
|
|
81
|
+
|
|
82
|
+
### Leads
|
|
60
83
|
|
|
61
84
|
```bash
|
|
62
|
-
|
|
85
|
+
advisoros leads list [--status new] [--persona founder] [--search acme] [--limit 50]
|
|
86
|
+
advisoros leads get <id>
|
|
87
|
+
advisoros leads set-status <id> <new|engaged|won|lost>
|
|
88
|
+
advisoros leads import --file leads.csv [--persona founder]
|
|
89
|
+
advisoros leads import-from <source> [--query ...] [--post <url>] [--file <path>] [--audience <name>] [--campaign <id>] [--limit 50] [--no-enrich]
|
|
90
|
+
advisoros leads import-status <jobId>
|
|
91
|
+
advisoros leads update <id> [--name ...] [--title ...] [--company ...] [--email ...] [--linkedin ...] [--persona ...] [--score ...] [--status ...] [--notes ...]
|
|
92
|
+
advisoros leads delete <id>
|
|
93
|
+
advisoros leads verify <id>
|
|
63
94
|
```
|
|
64
95
|
|
|
65
|
-
|
|
96
|
+
`leads import` accepts CSV (header row), JSON array, or JSONL. Upserts on `(workspace_id, linkedin_url)`. Bulk requests are auto-chunked at 200/call (server cap: 500/call).
|
|
97
|
+
|
|
98
|
+
`leads import-from` runs any of the import sources in **Get Leads → Import Leads**:
|
|
66
99
|
|
|
67
|
-
|
|
68
|
-
|
|
100
|
+
| source | required params | what it does |
|
|
101
|
+
|---|---|---|
|
|
102
|
+
| `linkedin_search` | `--query` | keyword / title / company people search via Unipile |
|
|
103
|
+
| `company_search` | `--query` | LinkedIn company search |
|
|
104
|
+
| `post_reactors` | `--post <url>` | everyone who reacted to a LinkedIn post |
|
|
105
|
+
| `paste_profiles` | `--file <path>` | name + LinkedIn URL lines; rest is enriched |
|
|
106
|
+
| `csv` | `--file <path>` | same CSV parser the UI uses |
|
|
107
|
+
| `heyreach` | `--file <path>` `--campaign <id>` | HeyReach campaign CSV, statuses preserved |
|
|
108
|
+
| `sales_nav_url` | `--url <sales-nav-search-url>` | queues a background Sales Navigator import, drip-fed inside the LinkedIn read limits |
|
|
109
|
+
| `sales_nav_keywords` | `--query` | same background queue, from Sales Navigator keywords |
|
|
69
110
|
|
|
70
|
-
|
|
111
|
+
All sources accept `--audience` to attach leads to a segment (created if missing). LinkedIn-backed sources run at bulk read priority so live campaigns are not starved. Long-running imports return a `job_id`; poll with `advisoros leads import-status <jobId>`.
|
|
71
112
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
(`SETU_RETRIES`, default 3). `Retry-After` is honoured.
|
|
75
|
-
- `--verbose` prints retry attempts and stack traces.
|
|
76
|
-
- `setu logout` removes the stored key from this machine.
|
|
77
|
-
- Unknown commands and failed bulk imports exit non-zero (safe for scripts/CI).
|
|
113
|
+
Sales Navigator sources do not run inline — they create a **scheduled import** that the
|
|
114
|
+
cap-aware scheduler drip-feeds over hours or days:
|
|
78
115
|
|
|
79
|
-
|
|
116
|
+
```bash
|
|
117
|
+
advisoros leads import-from sales_nav_url --url "https://www.linkedin.com/sales/search/people?..." \
|
|
118
|
+
--limit 500 --audience "Q3 ICP" --priority high
|
|
119
|
+
advisoros leads import-schedules
|
|
120
|
+
advisoros leads import-schedule pause|resume|cancel <id>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Cancelling keeps the leads already imported.
|
|
124
|
+
|
|
125
|
+
### Campaigns
|
|
80
126
|
|
|
81
127
|
```bash
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
128
|
+
advisoros campaigns list [--status active]
|
|
129
|
+
advisoros campaigns show <id>
|
|
130
|
+
advisoros campaigns create --name "Founder Pitch Club" \
|
|
131
|
+
--sequence <sequenceId> \
|
|
132
|
+
--senders acc_a,acc_b \
|
|
133
|
+
--daily-limit 25
|
|
134
|
+
advisoros campaigns add-leads <campaignId> --lead-ids id1,id2,id3
|
|
135
|
+
advisoros campaigns add-leads <campaignId> --file lead-ids.txt
|
|
136
|
+
advisoros campaigns launch <id>
|
|
137
|
+
advisoros campaigns pause <id>
|
|
138
|
+
advisoros campaigns resume <id>
|
|
139
|
+
advisoros campaigns rename <id> "New name" # rename without touching other settings
|
|
86
140
|
```
|
|
87
141
|
|
|
88
|
-
|
|
89
|
-
else is reported and skipped before any API call is made.
|
|
142
|
+
`launch` flips status to `active` — the `enforce_campaign_char_limits` trigger validates every step's copy against LinkedIn limits before allowing the transition.
|
|
90
143
|
|
|
91
|
-
|
|
144
|
+
### Sequences / Inbox / Content / Agents / Meetings / Newsletter / Integrations
|
|
92
145
|
|
|
93
146
|
```bash
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
147
|
+
advisoros sequences list
|
|
148
|
+
advisoros sequences show <id>
|
|
149
|
+
|
|
150
|
+
advisoros inbox threads [--campaign <id>] [--lead <id>] [--needs-attention] [--limit 50]
|
|
151
|
+
|
|
152
|
+
advisoros content list [--status published] [--type post] [--search ...]
|
|
153
|
+
advisoros content show <id>
|
|
154
|
+
advisoros content publish <id>
|
|
155
|
+
|
|
156
|
+
advisoros agents list
|
|
157
|
+
advisoros agents run <name> --input '{"foo":"bar"}'
|
|
158
|
+
advisoros agents trigger <name> --input '{"foo":"bar"}'
|
|
159
|
+
advisoros agents history [--agent <name>] [--days 30] [--limit 50]
|
|
160
|
+
advisoros agents job <jobId>
|
|
161
|
+
|
|
162
|
+
advisoros meetings list [--limit 50]
|
|
163
|
+
advisoros meetings transcripts [--provider fireflies|roam] [--since 2026-01-01] [--limit 50]
|
|
164
|
+
advisoros meetings transcript <transcriptId> [--original | --mode anonymised|original]
|
|
165
|
+
|
|
166
|
+
advisoros newsletter list
|
|
167
|
+
advisoros newsletter create --subject "Weekly roundup" --body "<html>..." [--preview-text "..."]
|
|
168
|
+
advisoros newsletter edit <id> [--subject ...] [--body ...] [--preview-text ...] [--status draft|scheduled]
|
|
169
|
+
advisoros newsletter delete <id>
|
|
170
|
+
|
|
171
|
+
advisoros integrations status
|
|
172
|
+
advisoros integrations check <platform>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
> **Heads-up:** `inbox send`/`reply` are intentionally **not** in v1. Outbound goes through `campaigns launch` (sender resolution + char limits + per-sender daily budget). For one-off DMs, use the web inbox.
|
|
176
|
+
|
|
177
|
+
`meetings transcript` returns anonymised text by default, once anonymisation is ready; otherwise metadata is returned with an explicit reason. Add `--original` to get the original text and speaker identities — your key needs this permission (all unrestricted keys already have it) and every original read is audited.
|
|
178
|
+
|
|
179
|
+
`integrations status` is read-only and never returns credentials. `integrations check <platform>` runs a live health probe for the requested platform (e.g. `linkedin_tool`).
|
|
180
|
+
|
|
181
|
+
### Obsidian vault mirror (`kb`) — one-way
|
|
97
182
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
183
|
+
```bash
|
|
184
|
+
advisoros kb link ./client-vault --workspace dmw9wj
|
|
185
|
+
advisoros kb status ./client-vault # dry-run preview
|
|
186
|
+
advisoros kb pull ./client-vault # mirror notes + graph entities
|
|
187
|
+
advisoros kb pull ./client-vault --preserve-local
|
|
101
188
|
```
|
|
102
189
|
|
|
103
|
-
|
|
190
|
+
One-way push, AdvisorPro → Obsidian. Markdown notes with frontmatter, `[[wikilinks]]` and an
|
|
191
|
+
`## Entities` block, plus `Entities/<Type>/*.md` for graph nodes. Local edits are overwritten unless
|
|
192
|
+
`--preserve-local` is used (remote copy lands as `<slug>.remote.md`). Nothing is pushed back.
|
|
193
|
+
|
|
104
194
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
195
|
+
## Examples
|
|
196
|
+
|
|
197
|
+
**Spin up a campaign from a fresh CSV:**
|
|
108
198
|
|
|
109
199
|
```bash
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
200
|
+
advisoros leads import --file ./prospects.csv --persona founder
|
|
201
|
+
advisoros leads list --persona founder --limit 200 --json \
|
|
202
|
+
| jq -r '.leads[].id' > lead-ids.txt
|
|
203
|
+
|
|
204
|
+
advisoros campaigns create --name "Q3 Founder Outreach" \
|
|
205
|
+
--sequence 1a2b3c4d-... --senders acc_milan --daily-limit 25
|
|
206
|
+
# → ✓ Created campaign 8297f04d-...
|
|
207
|
+
|
|
208
|
+
advisoros campaigns add-leads 8297f04d-... --file lead-ids.txt
|
|
209
|
+
advisoros campaigns launch 8297f04d-...
|
|
115
210
|
```
|
|
116
211
|
|
|
117
|
-
|
|
212
|
+
**Tail a long-running agent job:**
|
|
118
213
|
|
|
119
214
|
```bash
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
215
|
+
JOB=$(advisoros agents run lead-intelligence --input '{}' --json | jq -r '.run.job_id')
|
|
216
|
+
watch -n 5 "advisoros agents job $JOB --json | jq '{status,progress}'"
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Safety rails
|
|
220
|
+
|
|
221
|
+
Anything that stops sending, un-enrols leads or deletes data now asks first.
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
# Launch is a dry run until you confirm — preflight runs server-side.
|
|
225
|
+
advisoros campaigns preflight 9884b9ec
|
|
226
|
+
advisoros campaigns launch 9884b9ec # shows blockers, changes nothing
|
|
227
|
+
advisoros campaigns launch 9884b9ec --confirm # actually launches
|
|
228
|
+
|
|
229
|
+
# Destructive commands prompt; scripts must pass --yes.
|
|
230
|
+
advisoros campaigns delete 9884b9ec --dry-run
|
|
231
|
+
advisoros campaigns delete 9884b9ec --yes
|
|
232
|
+
advisoros sequences delete-step 6b60d6ad --yes
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
A campaign with no leads, no sequence, no steps or no sender account is
|
|
236
|
+
**refused**, not silently activated. `--force` overrides once you know why.
|
|
237
|
+
|
|
238
|
+
New commands: `campaigns preflight|archive|clone|delete|remove-leads`,
|
|
239
|
+
`sequences delete|update-step|delete-step`.
|
|
240
|
+
|
|
241
|
+
## Reading more than 200 rows
|
|
242
|
+
|
|
243
|
+
List commands accept `--limit` up to 1000 and every list response carries
|
|
244
|
+
`pagination` (`total`, `limit`, `offset`, `next_cursor`, `has_more`). If you ask
|
|
245
|
+
for more than the maximum, the response says it was clamped instead of quietly
|
|
246
|
+
truncating.
|
|
247
|
+
|
|
248
|
+
## Exit codes
|
|
249
|
+
|
|
250
|
+
| Code | Meaning |
|
|
251
|
+
|---|---|
|
|
252
|
+
| 0 | Success |
|
|
253
|
+
| 1 | Generic failure (`error` in JSON response or thrown). Stderr contains the message. |
|
|
254
|
+
|
|
255
|
+
## Programmatic use
|
|
256
|
+
|
|
257
|
+
```js
|
|
258
|
+
import { call } from "@series-a/cli/src/api.mjs";
|
|
259
|
+
|
|
260
|
+
const { campaigns } = await call("campaigns", "list", { status: "active" }, {
|
|
261
|
+
apiKey: process.env.ADVISOROS_API_KEY,
|
|
262
|
+
workspaceId: "dmw9wj",
|
|
263
|
+
});
|
|
127
264
|
```
|
|
128
265
|
|
|
129
|
-
##
|
|
266
|
+
## Troubleshooting
|
|
267
|
+
|
|
268
|
+
- **401 Unauthorized** — key wrong / revoked / wrong base URL. Re-run `advisoros login`.
|
|
269
|
+
- **403 not authorized for the requested workspace_id** — workspace-scoped key + `--workspace` to a different workspace. Use the matching key.
|
|
270
|
+
- **CHAR_LIMIT_EXCEEDED on launch** — a sequence step exceeds LinkedIn limits (200 invitations / 8000 DMs / 1250 comments). Fix in web app.
|
|
271
|
+
- **Network error** — check `ADVISOROS_BASE_URL` if you're pointing at a non-default deployment.
|
|
272
|
+
|
|
273
|
+
## Releasing (maintainers)
|
|
130
274
|
|
|
131
275
|
```bash
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
276
|
+
cd tools/cli
|
|
277
|
+
npx changeset # describe the change
|
|
278
|
+
npm run version-packages # bump package.json + CHANGELOG.md
|
|
279
|
+
git commit -am "chore(cli): release v$(node -p "require('./package.json').version")"
|
|
280
|
+
git tag "cli-v$(node -p "require('./package.json').version")"
|
|
281
|
+
git push --follow-tags
|
|
282
|
+
# → .github/workflows/cli-release.yml publishes to npm with provenance
|
|
137
283
|
```
|
|
138
284
|
|
|
139
|
-
|
|
140
|
-
|
|
285
|
+
`NPM_TOKEN` must be set in the repo's GitHub Actions secrets (automation token with publish access to the `@series-a` org).
|
|
286
|
+
|
|
287
|
+
## Roadmap (v1.1)
|
|
141
288
|
|
|
142
|
-
|
|
289
|
+
- `inbox send` / `inbox reply` with explicit `--confirm` + per-sender budget enforcement.
|
|
290
|
+
- `agents tail <jobId>` (SSE).
|
|
291
|
+
- `admin workspaces …` (admin keys only).
|
|
292
|
+
- Single-binary builds via `pkg`.
|
|
293
|
+
|
|
294
|
+
## Full API reference
|
|
295
|
+
|
|
296
|
+
See [`docs/agent-api.md`](../../docs/agent-api.md) for the underlying `/agent-api` envelope.
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
## Admin keys
|
|
301
|
+
|
|
302
|
+
Admin keys (`advos_admin_…`) are authorised by the key itself — they do **not** need an
|
|
303
|
+
`agent_workspace_bindings` row. `agent_name` is an audit label only.
|
|
143
304
|
|
|
144
305
|
```bash
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
306
|
+
advisoros login --admin --profile ops # no workspace prompt; prints reachable workspace count
|
|
307
|
+
advisoros whoami --profile ops # scope: admin (cross-workspace) + reachable count
|
|
308
|
+
advisoros workspaces list --profile ops # every reachable workspace (paginated, up to 1000)
|
|
309
|
+
advisoros analytics overview --workspace dmw9wj --profile ops
|
|
149
310
|
```
|
|
150
311
|
|
|
151
|
-
|
|
312
|
+
Caller identity is overridable: `--as-agent <name>` on any command, `ADVISOROS_AGENT_NAME`
|
|
313
|
+
in the environment, or the `agentName` stored on the profile at login (default `advisoros-cli`).
|
|
314
|
+
|
|
315
|
+
Workspace-scoped keys are unchanged: they can only reach their own workspace (403 otherwise)
|
|
316
|
+
and cannot use the `workspaces` resource. An agent without bindings now gets a typed 403
|
|
317
|
+
explaining to use an admin key, instead of a 500.
|