ccqa 1.16.1 → 1.17.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.
package/README.md CHANGED
@@ -133,7 +133,7 @@ grade the calls on the hub, and it learns from your grades.
133
133
 
134
134
  ```
135
135
  deploy lands
136
- ├─ ccqa hub deploy record --select what shipped, which specs it reaches
136
+ ├─ ccqa hub deploy record what shipped, which specs it reaches
137
137
  ├─ ccqa audit --only-hub-audit-needed --report-to-hub
138
138
  │ does each spec still describe it?
139
139
  └─ ccqa run --only-hub-rerun-needed --on-fail-explain \
@@ -141,9 +141,10 @@ deploy lands
141
141
  ```
142
142
 
143
143
  The audit costs cents; a live spec costs dollars. Filtering first leaves
144
- a run whose failures are worth reading. Record every deploy with
145
- `--select` a range recorded without it answers `unanswerable` forever, and
146
- nothing fills the hole later.
144
+ a run whose failures are worth reading. `deploy record` decides which specs
145
+ the range reaches unless you pass `--no-select-specs`; a range recorded
146
+ without that decision answers `unanswerable` forever, and nothing fills the
147
+ hole later.
147
148
 
148
149
  | Job | Trigger | Question it answers |
149
150
  |---|---|---|
package/dist/bin/ccqa.mjs CHANGED
@@ -8805,7 +8805,7 @@ const promptRm = new Command("rm").description("Delete a prompt from the hub.").
8805
8805
  info(`deleted prompt "${name}" from the hub`);
8806
8806
  }));
8807
8807
  const promptCommand = new Command("prompt").description("Manage prompt assets (per-flow user/agent guidance, triage user guidance, analysis custom prompt) stored on the hub (fetched automatically by `ccqa run` at run time).").addCommand(promptPush).addCommand(promptLs).addCommand(promptRm);
8808
- const deployRecord = new Command("record").description("Tell the hub what a deploy shipped, so it can answer which specs need a re-run (`ccqa run --only-hub-rerun-needed`). Run this from the deploy job, after the deploy succeeds. The changed paths are computed locally with a two-dot `git diff <previous> <sha>`; a job that has only curl and git can POST the same body directly (see docs/hub.md).").requiredOption("--profile <name>", "Environment this deploy landed in (e.g. 'stg'). Required: dev and stg sit at different commits, so the deploy log is per-profile.").requiredOption("--sha <sha>", "Commit that was deployed.").option("--previous <sha>", "Commit this deploy replaced. Defaults to the profile's current deploy-log head on the hub. With neither, there's nothing to diff against: changedPaths is unset and --select is skipped.").option("--ref <ref>", "Ref that was deployed (branch or tag). Recorded for display only.").option("--select", "Also decide which specs this deploy reaches (`ccqa select-specs`) and send the verdict with it. Without it the deploy is a hole in the range: specs behind it report 'unknown' rather than 'not needed'.").option("-m, --model <name>", "Model for --select. Claude alias ('sonnet'|'opus'|'haiku') or full ID. Overrides CCQA_MODEL.").option(...hubUrlOption).option(...hubTokenOption).option("--project <name>", "Project whose deploy log this entry joins. Defaults to the current directory's name.").option("--cwd <path>", "Directory the git diff and the default --project name are resolved against.").action(withHubErrors(async (opts) => {
8808
+ const deployRecord = new Command("record").description("Tell the hub what a deploy shipped, so it can answer which specs need a re-run (`ccqa run --only-hub-rerun-needed`). Run this from the deploy job, after the deploy succeeds. The changed paths are computed locally with a two-dot `git diff <previous> <sha>`; a job that has only curl and git can POST the same body directly (see docs/hub.md).").requiredOption("--profile <name>", "Environment this deploy landed in (e.g. 'stg'). Required: dev and stg sit at different commits, so the deploy log is per-profile.").requiredOption("--sha <sha>", "Commit that was deployed.").option("--previous <sha>", "Commit this deploy replaced. Defaults to the profile's current deploy-log head on the hub. With neither, there's nothing to diff against: changedPaths is unset and the spec selection is skipped.").option("--ref <ref>", "Ref that was deployed (branch or tag). Recorded for display only.").option("--no-select-specs", "Record the deploy without deciding which specs it reaches. The entry then becomes a hole in the range every spec behind it answers 'unanswerable' rather than being cleared, and nothing can fill it in later, since the hub has no checkout to diff. Only pass this when no Claude credential is available; it costs one model call to leave the log answerable.").option("-m, --model <name>", "Model for the spec selection. Claude alias ('sonnet'|'opus'|'haiku') or full ID. Overrides CCQA_MODEL.").option(...hubUrlOption).option(...hubTokenOption).option("--project <name>", "Project whose deploy log this entry joins. Defaults to the current directory's name.").option("--cwd <path>", "Directory the git diff and the default --project name are resolved against.").action(withHubErrors(async (opts) => {
8809
8809
  const cwd = resolveCwd(opts.cwd);
8810
8810
  const project = resolveProject(opts);
8811
8811
  const hub = connect(opts);
@@ -8813,7 +8813,7 @@ const deployRecord = new Command("record").description("Tell the hub what a depl
8813
8813
  const runUrl = githubRunUrl();
8814
8814
  const diff = previous === null ? null : await diffOrNull(previous, opts.sha, cwd);
8815
8815
  const changedPaths = diff ? capDeployPaths(diff.map((f) => f.path)) : null;
8816
- const selection = opts.select && previous !== null && diff !== null ? await selectionForDeploy(diff, previous, opts.sha, cwd, opts.model) : void 0;
8816
+ const selection = opts.selectSpecs !== false && previous !== null && diff !== null ? await selectionForDeploy(diff, previous, opts.sha, cwd, opts.model) : void 0;
8817
8817
  const entry = await hub.recordDeploy(project, opts.profile, {
8818
8818
  sha: opts.sha,
8819
8819
  previousSha: previous,
@@ -8827,7 +8827,7 @@ const deployRecord = new Command("record").description("Tell the hub what a depl
8827
8827
  meta("profile", opts.profile);
8828
8828
  meta("previous", previous ? previous.slice(0, 12) : "(none)");
8829
8829
  meta("changed paths", changedPaths === null ? "(not reported)" : String(changedPaths.length));
8830
- if (opts.select) meta("selection", describeSelection(selection, diff !== null));
8830
+ if (opts.selectSpecs !== false) meta("selection", describeSelection(selection, diff !== null));
8831
8831
  if (entry.gapBefore) warn("this deploy does not chain onto the log head, so a gap is recorded — specs whose baseline sits behind it report 'unanswerable' rather than 'verified'");
8832
8832
  if (selection && !entry.hasSelection) {
8833
8833
  error("the hub recorded this deploy but could not store its spec selection — the range answers 'unanswerable' from here on, and nothing fills it in later. Re-record this deploy.");
@@ -8870,7 +8870,7 @@ async function selectionForDeploy(changed, previous, sha, cwd, model) {
8870
8870
  /**
8871
8871
  * The two-dot diff for this deploy's range, or `null` when git can't produce
8872
8872
  * one (a shallow checkout that never fetched `previous`, a rolled-back sha
8873
- * that isn't local). Shared by `changedPaths` and `--select`'s input, so a
8873
+ * that isn't local). Shared by `changedPaths` and the selection's input, so a
8874
8874
  * diff failure skips both rather than each attempting — and separately
8875
8875
  * failing — its own git call.
8876
8876
  */
@@ -8882,7 +8882,7 @@ async function diffOrNull(previous, sha, cwd) {
8882
8882
  return null;
8883
8883
  }
8884
8884
  }
8885
- /** The `--select` summary line: verdict counts, or why there isn't one. */
8885
+ /** The selection summary line: verdict counts, or why there isn't one. */
8886
8886
  function describeSelection(selection, diffAvailable) {
8887
8887
  if (!selection) return diffAvailable ? "(skipped — see warning above)" : "(skipped — no diff to select against)";
8888
8888
  const values = Object.values(selection);
@@ -388,8 +388,8 @@ declare const ReportSpecResultSchema: z.ZodObject<{
388
388
  title: z.ZodNullable<z.ZodString>;
389
389
  target: z.ZodOptional<z.ZodString>;
390
390
  mode: z.ZodOptional<z.ZodEnum<{
391
- deterministic: "deterministic";
392
391
  live: "live";
392
+ deterministic: "deterministic";
393
393
  }>>;
394
394
  status: z.ZodEnum<{
395
395
  passed: "passed";
@@ -574,8 +574,8 @@ declare const RunReportDataSchema: z.ZodObject<{
574
574
  title: z.ZodNullable<z.ZodString>;
575
575
  target: z.ZodOptional<z.ZodString>;
576
576
  mode: z.ZodOptional<z.ZodEnum<{
577
- deterministic: "deterministic";
578
577
  live: "live";
578
+ deterministic: "deterministic";
579
579
  }>>;
580
580
  status: z.ZodEnum<{
581
581
  passed: "passed";
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccqa",
3
- "version": "1.16.1",
3
+ "version": "1.17.0",
4
4
  "type": "module",
5
5
  "description": "Browser test recorder powered by Claude Code and agent-browser",
6
6
  "repository": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccqa",
3
- "version": "1.16.1",
3
+ "version": "1.17.0",
4
4
  "type": "module",
5
5
  "description": "Browser test recorder powered by Claude Code and agent-browser",
6
6
  "repository": {