@series-a/cli 0.21.1 → 0.22.2
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 +13 -0
- package/package.json +1 -1
- package/src/commands/resources.mjs +40 -9
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,19 @@ All notable changes to this package are documented here. This project follows
|
|
|
4
4
|
[Semantic Versioning](https://semver.org/) and uses
|
|
5
5
|
[Changesets](https://github.com/changesets/changesets) to manage releases.
|
|
6
6
|
|
|
7
|
+
## 0.22.0 — Admin keys, analytics parity, safety hardening, Obsidian sync
|
|
8
|
+
|
|
9
|
+
- Admin keys work end-to-end. `login --admin` persists admin scope and reports reachable workspace count, `whoami` shows `scope: admin (cross-workspace)` plus reachable workspaces, and the caller identity is no longer hardcoded — override with `--as-agent <name>` or `ADVISOROS_AGENT_NAME`, persisted per profile.
|
|
10
|
+
- Full analytics, safety and resource parity: `campaigns stats|events|health|leads`, new `analytics`, `safety`, `ctas`, `audiences`, `notifications`, `newsletter`, `video`, `watchlist`, `meetings`, `activity`, `workspaces` groups, and a generic `export` command that writes any list action to CSV.
|
|
11
|
+
- Safety and coverage hardening:
|
|
12
|
+
- `campaigns preflight`, and `campaigns launch|resume` now dry-run by default and require `--confirm`; the API refuses to launch a campaign with no leads, no sequence, no steps or no sender.
|
|
13
|
+
- New `campaigns archive|clone|delete|remove-leads` and `sequences delete|update-step|delete-step`.
|
|
14
|
+
- Every destructive command prompts, and requires `--yes` when scripted; `--dry-run` previews.
|
|
15
|
+
- List actions now return honest `pagination` metadata (total, limit, offset, next_cursor) and allow up to 1000 rows.
|
|
16
|
+
- Not-found reads return 404 and a non-zero exit; unknown resources/actions return 400 with the supported list instead of a 500.
|
|
17
|
+
- Add `advisoros kb link|sync|status|unlink` — two-way sync between a workspace Knowledge Base and a local offline Obsidian vault (Markdown + frontmatter + wikilinks, hash-based conflict detection).
|
|
18
|
+
|
|
19
|
+
|
|
7
20
|
## 0.21.0 — Automatic voice checks, real citations, grounded drafts
|
|
8
21
|
|
|
9
22
|
- Voice results are always up to date: every draft now runs a voice check automatically the moment it is created or its text is edited, and the fresh score and report are stamped onto the draft. `content show` and release decisions always see the latest voice result — no manual scoring step. Drafts whose voice check cannot finish are held back (`needs_revision`) instead of being left in a hanging "pending" state.
|
package/package.json
CHANGED
|
@@ -1211,23 +1211,53 @@ export function registerContent(program) {
|
|
|
1211
1211
|
.option("--signal <id...>", "intelligence_signals ids to ground on (repeatable)")
|
|
1212
1212
|
.option("--reference <id...>", "knowledge_items ids to ground on (repeatable)")
|
|
1213
1213
|
.option("--grounding-text <text>", "extra freeform grounding to append")
|
|
1214
|
-
.option("--wait", "
|
|
1214
|
+
.option("--wait", "poll until the job finishes (up to 10 min)")
|
|
1215
|
+
.option("--timeout <seconds>", "how long --wait polls before giving up", "600")
|
|
1215
1216
|
.action(async function (opts) {
|
|
1216
1217
|
try {
|
|
1218
|
+
// Always dispatch asynchronously and poll the returned job id. Holding
|
|
1219
|
+
// one long HTTP request open was what produced spurious timeouts, and
|
|
1220
|
+
// polling by the id the server handed back is what keeps --wait from
|
|
1221
|
+
// ever reporting job_not_found for a job that exists.
|
|
1222
|
+
const ctx = ctxFrom(this);
|
|
1217
1223
|
const r = await call("content", "generate", {
|
|
1218
1224
|
angle: opts.angle,
|
|
1219
1225
|
format: opts.format,
|
|
1220
1226
|
signal_ids: opts.signal,
|
|
1221
1227
|
reference_item_ids: opts.reference,
|
|
1222
1228
|
grounding_text: opts.groundingText,
|
|
1223
|
-
async:
|
|
1224
|
-
},
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
process.stdout.write(`⏳ Queued job ${d.job_id} — poll with: advisoros agents job-status ${d.job_id}\n`);
|
|
1229
|
+
async: true,
|
|
1230
|
+
}, ctx);
|
|
1231
|
+
const jobId = r?.job_id || r?.job?.id || null;
|
|
1232
|
+
if (!opts.wait || !jobId) {
|
|
1233
|
+
emit(this, r, (d) => {
|
|
1234
|
+
if (d.content) process.stdout.write(`✓ Draft ${d.content.id} (${d.content.type}, ${d.citations?.length ?? 0} citations)\n`);
|
|
1235
|
+
else process.stdout.write(`⏳ Queued job ${d.job_id} — poll with: advisoros agents job-status ${d.job_id}\n`);
|
|
1236
|
+
});
|
|
1237
|
+
return;
|
|
1238
|
+
}
|
|
1239
|
+
const deadline = Date.now() + Number(opts.timeout || 600) * 1000;
|
|
1240
|
+
let last = null;
|
|
1241
|
+
while (Date.now() < deadline) {
|
|
1242
|
+
await new Promise((res) => setTimeout(res, 5000));
|
|
1243
|
+
let st;
|
|
1244
|
+
try {
|
|
1245
|
+
st = await call("agents", "job_status", { job_id: jobId }, ctx);
|
|
1246
|
+
} catch (e) {
|
|
1247
|
+
// A transient lookup failure must never end the wait — the job id
|
|
1248
|
+
// came from the server, so keep polling until the deadline.
|
|
1249
|
+
continue;
|
|
1230
1250
|
}
|
|
1251
|
+
last = st?.job || st;
|
|
1252
|
+
const status = last?.status;
|
|
1253
|
+
if (status === "completed" || status === "succeeded" || status === "failed") break;
|
|
1254
|
+
}
|
|
1255
|
+
emit(this, { job_id: jobId, job: last }, (d) => {
|
|
1256
|
+
const st = d.job?.status || "unknown";
|
|
1257
|
+
const ids = d.job?.result?.content_ids || [];
|
|
1258
|
+
process.stdout.write(st === "completed" || st === "succeeded"
|
|
1259
|
+
? `✓ Job ${d.job_id} ${st}${ids.length ? ` — draft ${ids[0]}` : ""}\n`
|
|
1260
|
+
: `⏳ Job ${d.job_id} is ${st} — check with: advisoros agents job-status ${d.job_id}\n`);
|
|
1231
1261
|
});
|
|
1232
1262
|
} catch (e) { fail(e); }
|
|
1233
1263
|
});
|
|
@@ -1827,7 +1857,8 @@ export function registerAgents(program) {
|
|
|
1827
1857
|
});
|
|
1828
1858
|
|
|
1829
1859
|
withCommonOpts(a.command("job <id>"))
|
|
1830
|
-
.
|
|
1860
|
+
.alias("job-status")
|
|
1861
|
+
.description("Check agent_jobs status (accepts a full or short job id)")
|
|
1831
1862
|
.action(async function (id) {
|
|
1832
1863
|
try {
|
|
1833
1864
|
const r = await call("agents", "job_status", { job_id: id }, ctxFrom(this));
|