@drip-apex/apex-cli 0.8.1 → 0.10.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.
Files changed (3) hide show
  1. package/README.md +20 -1
  2. package/dist/cli.js +20 -7
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -129,7 +129,7 @@ including every subcommand, argument, option, and alias.
129
129
  - `apex experiments` — create, inspect, operate, and synchronize experiments.
130
130
  Use `apex experiments screenshots <id-or-slug>` to force-assign every capture, including control, to its variation server-side for deterministic screenshots. Resume a job that outlives the CLI timeout with `--job <id>`; polling continues without creating another job, and the stored job's devices and variations win, so `--devices`/`--variations` are ignored (the CLI warns). The command attaches terminal jobs to the QA run by default; use `--no-attach-qa` to opt out. Choose devices with `--devices`, filter treatments with `--variations`, and use `--json` for the signed result payload. Use `apex experiments qa evidence` with `--job`, repeatable `--file`, or `--records` to write QA evidence directly.
131
131
  - `apex push` — synchronize `.drip.config.ts` with Apex.
132
- - `apex preview` — open a variation QA preview.
132
+ - `apex preview` — open a variation QA preview; `--proxy` returns a `qa_run` receipt. Its `automated_evidence_count` counts the normalized `evidenceRecords` across all evidence kinds, matching the list shown by `apex experiments qa status`.
133
133
  - `apex roadmap` — consume approved roadmap ideas and handoffs.
134
134
  - `apex harness` — develop AB Test Harness projects with live QA sessions.
135
135
  - `apex workspace` — check out, preview, and publish draft workspace files.
@@ -313,3 +313,22 @@ Create/get return `dashboard_url`; apply returns `dashboardUrl`. These links
313
313
  switch the signed-in dashboard user's active shop before opening the experiment.
314
314
 
315
315
  Filesystem apply caches uploaded asset URLs by byte SHA-256 in `.apex/experiment-filesystem.json`, so unchanged images reuse their URL across applies without rewriting authored files.
316
+
317
+ `--instructions` cannot be combined with `--out` (or its legacy alias `--output`); file exports always contain the full JSON contract.
318
+
319
+ Roadmap handoff JSON identifies itself as `apex.roadmap_handoff.v1`; backlog get/list
320
+ items identify themselves as `apex.backlog_item.v1`, both with `schema_version: 1`.
321
+ The handoff embeds the same closed item projection that backlog responses serve
322
+ alongside their existing raw fields. Published schemas and fixtures live in
323
+ [`docs/contracts/experiment-os`](../../docs/contracts/experiment-os/README.md).
324
+ Breaking changes require a new v2 contract; the backlog `version` is a separate
325
+ optimistic concurrency token.
326
+
327
+ | Key | Source |
328
+ | --- | --- |
329
+ | `approval` | Roadmap decision status (`proposed` without a decision), item stage, and decision's nullable `decided_at`. Top-level `status` remains the item lifecycle status. |
330
+ | `goals` | `apex_goal_id` is the linked experiment goal or null. |
331
+
332
+ QA status creates a run only when none exists. Reading an existing run never writes
333
+ to it: `updatedAt` is its last stored mutation time, while `computedAt` is the ISO
334
+ timestamp when the current checklist and summary were computed.
package/dist/cli.js CHANGED
@@ -7112,7 +7112,7 @@ var import_node_os3 = __toESM(require("node:os"));
7112
7112
  // package.json
7113
7113
  var package_default = {
7114
7114
  name: "@drip-apex/apex-cli",
7115
- version: "0.8.1",
7115
+ version: "0.10.0",
7116
7116
  license: "MIT",
7117
7117
  description: "Apex CLI for managing experiments, approved roadmap ideas, and draft workspaces.",
7118
7118
  private: false,
@@ -9639,6 +9639,7 @@ function printQaPreviewUrls(experimentId, result) {
9639
9639
  function printQaRun(run3) {
9640
9640
  console.log();
9641
9641
  console.log(source_default.bold(`QA run ${run3.id}`));
9642
+ console.log(` computedAt: ${run3.computedAt}`);
9642
9643
  console.log(` Status: ${statusBadge(run3.summary.status)}`);
9643
9644
  console.log(` Required: ${run3.summary.completedRequired}/${run3.summary.required}`);
9644
9645
  if (run3.approvedAt) console.log(` Approved: ${run3.approvedAt}`);
@@ -10826,7 +10827,9 @@ var applyFilesystem = new Command("apply").option("--sync", "Refresh local autho
10826
10827
  fail(this, error instanceof Error ? error.message : String(error));
10827
10828
  }
10828
10829
  });
10829
- var qaStatus = new Command("status").description("Show or create the latest experiment QA run").argument(
10830
+ var qaStatus = new Command("status").description(
10831
+ "Show the latest experiment QA run (creates one only when none exists; reads never change updatedAt)"
10832
+ ).argument(
10830
10833
  "[folder-or-id]",
10831
10834
  "Experiment filesystem folder, ID, slug, or test key (for example BIO-085)",
10832
10835
  "."
@@ -11791,7 +11794,9 @@ var pushCommand = new Command("push").description("Push experiment definitions f
11791
11794
 
11792
11795
  // src/commands/preview.ts
11793
11796
  init_source();
11794
- var previewCommand = new Command("preview").description("Open QA preview URL for an experiment variation").argument("<id-or-slug>", "Experiment ID or slug").argument("[variation-id]", "Variation ID (defaults to first non-control)").option("--store-url <url>", "Override experiment store_url (target website URL)").option("--proxy", "Create an artifact-injecting proxy preview").option("--ttl <hours>", "Proxy preview lifetime in hours (1-168)").option("--no-open", "Print URL instead of opening browser").action(
11797
+ var previewCommand = new Command("preview").description(
11798
+ "Open QA preview URL for an experiment variation; proxy previews return a QA run receipt"
11799
+ ).argument("<id-or-slug>", "Experiment ID or slug").argument("[variation-id]", "Variation ID (defaults to first non-control)").option("--store-url <url>", "Override experiment store_url (target website URL)").option("--proxy", "Create an artifact-injecting proxy preview").option("--ttl <hours>", "Proxy preview lifetime in hours (1-168)").option("--no-open", "Print URL instead of opening browser").action(
11795
11800
  async (idOrSlug, variationId, opts) => {
11796
11801
  const creds = requireCredentials();
11797
11802
  if (opts?.proxy) {
@@ -11819,6 +11824,9 @@ var previewCommand = new Command("preview").description("Open QA preview URL for
11819
11824
  const data = created.data;
11820
11825
  output(previewCommand, data, () => {
11821
11826
  console.log(source_default.cyan(data.preview_url));
11827
+ console.log(
11828
+ data.qa_run.created ? `QA run ${data.qa_run.id} created` : `QA run ${data.qa_run.id} refreshed (${data.qa_run.automated_evidence_count} automated evidence records)`
11829
+ );
11822
11830
  const expiresAt = new Date(data.expires_at);
11823
11831
  const remainingMs = expiresAt.getTime() - Date.now();
11824
11832
  const value = remainingMs < 864e5 ? Math.max(1, Math.round(remainingMs / 36e5)) : Math.round(remainingMs / 864e5);
@@ -12790,7 +12798,11 @@ More results: --cursor ${res.data.pagination.next_cursor}`));
12790
12798
  }
12791
12799
  );
12792
12800
  });
12793
- var handoff = new Command("handoff").description("Get the full build brief for an approved roadmap item").argument("<id>", "Roadmap/backlog item ID").option("--out <path>", "Write handoff JSON to a file").addOption(new Option("-o, --output <path>", "Legacy alias for --out").hideHelp()).option("--instructions", "Print only the build instructions").action(async function action32(id, opts) {
12801
+ var handoff = new Command("handoff").description(
12802
+ "Get apex.roadmap_handoff.v1 JSON: contract, schema_version, item, experiment, instructions, goals, mockups, acceptance_criteria, harness, scoring, source, metadata"
12803
+ ).argument("<id>", "Roadmap/backlog item ID").option("--out <path>", "Write handoff JSON to a file").addOption(new Option("-o, --output <path>", "Legacy alias for --out").hideHelp()).addOption(
12804
+ new Option("--instructions", "Print only the build instructions").conflicts(["out", "output"])
12805
+ ).action(async function action32(id, opts) {
12794
12806
  if (opts.output !== void 0) {
12795
12807
  process.stderr.write(
12796
12808
  `Warning: --output is deprecated for apex roadmap handoff; use --out instead. --output will be removed in v${LEGACY_OUTPUT_REMOVAL_VERSION}.
@@ -12811,7 +12823,8 @@ var handoff = new Command("handoff").description("Get the full build brief for a
12811
12823
  classifyStatus(res.status),
12812
12824
  res.errorDetails
12813
12825
  );
12814
- const payload = res.data ?? {};
12826
+ const payload = res.data;
12827
+ if (!payload) fail(this, "Missing roadmap handoff response");
12815
12828
  const rendered = opts.instructions ? String(payload.instructions ?? "") : `${JSON.stringify(payload, null, 2)}
12816
12829
  `;
12817
12830
  const outputData = opts.instructions ? { roadmapItemId: id, instructions: String(payload.instructions ?? "") } : payload;
@@ -17011,7 +17024,7 @@ async function fieldLabels(command, item) {
17011
17024
  (fields3.ok && fields3.data ? fields3.data.data : []).map((field) => [field.key, field.label])
17012
17025
  );
17013
17026
  }
17014
- var list7 = new Command("list").alias("ls").description("List backlog").option("-n, --limit <n>", "Max results", "50").option("--cursor <cursor>", "Continue from cursor").option("--include-archived", "Include archived backlog items").action(async function(o) {
17027
+ var list7 = new Command("list").alias("ls").description("List backlog items identified as apex.backlog_item.v1").option("-n, --limit <n>", "Max results", "50").option("--cursor <cursor>", "Continue from cursor").option("--include-archived", "Include archived backlog items").action(async function(o) {
17015
17028
  const r = await listInsights(
17016
17029
  requireCredentials(),
17017
17030
  kind2,
@@ -17035,7 +17048,7 @@ var list7 = new Command("list").alias("ls").description("List backlog").option("
17035
17048
  )
17036
17049
  );
17037
17050
  });
17038
- var get6 = new Command("get").description("Get a backlog item").argument("<id>", "backlog item ID").action(async function(id) {
17051
+ var get6 = new Command("get").description("Get a backlog item identified as apex.backlog_item.v1").argument("<id>", "backlog item ID").action(async function(id) {
17039
17052
  const r = await getInsight(requireCredentials(), kind2, id);
17040
17053
  if (!r.ok || !r.data)
17041
17054
  fail(this, r.error ?? "Failed to get", classifyStatus(r.status), r.errorDetails);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drip-apex/apex-cli",
3
- "version": "0.8.1",
3
+ "version": "0.10.0",
4
4
  "license": "MIT",
5
5
  "description": "Apex CLI for managing experiments, approved roadmap ideas, and draft workspaces.",
6
6
  "private": false,