@series-a/cli 0.20.1 → 0.22.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 +21 -0
- package/package.json +1 -1
- package/src/commands/resources.mjs +40 -9
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,27 @@ 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
|
+
|
|
20
|
+
## 0.21.0 — Automatic voice checks, real citations, grounded drafts
|
|
21
|
+
|
|
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.
|
|
23
|
+
- `content citations` now writes a real citation record per source used: inline citation markers are inserted into the draft body where each source's findings appear, then persisted and returned with counts. Calling it on a draft with no citations syncs them automatically instead of returning empty.
|
|
24
|
+
- Draft generation is evidence-locked: required source signals must be quoted and attributed with a distinctive finding (topic-only mentions fail), copied source wording is rejected, rhythm is compared against the author's own benchmark, and the pre-release gate now blocks drafts on grounding, citations, framework fidelity, and pending/timed-out voice checks. Publication stays blocked until all checks pass.
|
|
25
|
+
- Restored Agent API actions: `graphics` accepts `refine` again, plus the platform/account listing operations; legacy sequence and campaign action names are accepted as aliases.
|
|
26
|
+
- Fixed `meetings` / `integrations` reads in the Agent API returning 500s (wrong sync-timestamp column).
|
|
27
|
+
|
|
7
28
|
## 0.20.0 — Sequence migration fixes and hour-level waits
|
|
8
29
|
|
|
9
30
|
- Hour- and minute-level waits from the terminal: `sequences add-step --delay-hours 3` and `--delay-minutes 45` (also on `update-step`), and in `replace-steps` JSON via `delay_hours` / `delay_minutes`. The step table now prints `3h` / `45m` instead of forcing days.
|
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));
|