@haystackeditor/cli 0.15.30 → 0.16.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 (135) hide show
  1. package/README.md +111 -60
  2. package/dist/assets/hooks/scripts/commit-msg.sh +3 -0
  3. package/dist/assets/hooks/scripts/post-commit.sh +3 -0
  4. package/dist/assets/hooks/scripts/pre-commit.sh +11 -6
  5. package/dist/assets/hooks/scripts/pre-push.sh +3 -0
  6. package/dist/assets/hooks/scripts/prepare-commit-msg.sh +3 -0
  7. package/dist/commands/case-batch-contract.js +608 -0
  8. package/dist/commands/case-batch.js +713 -0
  9. package/dist/commands/cloud-verifier-identity-census.js +5 -2
  10. package/dist/commands/combination-search-hook.js +139 -0
  11. package/dist/commands/design-verify.js +27 -1
  12. package/dist/commands/dismiss.js +2 -1
  13. package/dist/commands/hooks.js +66 -7
  14. package/dist/commands/install-session-hooks.js +131 -44
  15. package/dist/commands/policy.js +32 -45
  16. package/dist/commands/precompute-delivery.js +6 -1
  17. package/dist/commands/scaffold-provisional-universe.js +8 -10
  18. package/dist/commands/setup.js +32 -10
  19. package/dist/commands/submit.js +7 -2
  20. package/dist/commands/telemetry.js +17 -2
  21. package/dist/commands/triage.js +2 -1
  22. package/dist/commands/verify-explore.js +1 -0
  23. package/dist/commands/verify-history.js +152 -0
  24. package/dist/commands/verify-hosted-mcp.js +3 -12
  25. package/dist/commands/verify-hosted-reproducibility.js +49 -547
  26. package/dist/commands/verify-hosted.js +180 -163
  27. package/dist/commands/verify-precompute.js +57 -10
  28. package/dist/commands/verify.js +51 -139
  29. package/dist/index.js +264 -348
  30. package/dist/lazy.js +8 -0
  31. package/dist/schema.js +1 -0
  32. package/dist/tools/detect.js +3 -24
  33. package/dist/triage/prompts.js +46 -45
  34. package/dist/triage/runner.js +119 -33
  35. package/dist/types/verify-history.js +1 -0
  36. package/dist/types.js +3 -3
  37. package/dist/utils/auth.js +14 -2
  38. package/dist/utils/design-verifier-api.js +23 -0
  39. package/dist/utils/design-verifier-history.js +79 -0
  40. package/dist/utils/git.js +60 -29
  41. package/dist/utils/github-api.js +14 -1
  42. package/dist/utils/haystack-api.js +26 -7
  43. package/dist/utils/hooks.js +43 -6
  44. package/dist/utils/prompter.js +25 -10
  45. package/dist/utils/safe-write.js +31 -0
  46. package/dist/utils/secret-paths.js +115 -0
  47. package/dist/utils/secrets.js +0 -1
  48. package/dist/utils/telemetry.js +34 -14
  49. package/dist/utils/update-check.js +151 -0
  50. package/package.json +18 -14
  51. package/schemas/case-batch.v1.json +184 -0
  52. package/schemas/cloud-verifier.v1.json +55 -100
  53. package/dist/commands/ask.d.ts +0 -14
  54. package/dist/commands/cloud-verifier-behaviors.d.ts +0 -27
  55. package/dist/commands/cloud-verifier-data-store-census.d.ts +0 -47
  56. package/dist/commands/cloud-verifier-data-store-drift.d.ts +0 -42
  57. package/dist/commands/cloud-verifier-identity-census.d.ts +0 -88
  58. package/dist/commands/cloud-verifier-materialization.d.ts +0 -16
  59. package/dist/commands/cloud-verifier-pascal-selector-census.d.ts +0 -29
  60. package/dist/commands/cloud-verifier-python-manifest-selector-census.d.ts +0 -27
  61. package/dist/commands/cloud-verifier-specialized-operational-census.d.ts +0 -51
  62. package/dist/commands/cloud-verifier-universe.d.ts +0 -31
  63. package/dist/commands/config.d.ts +0 -46
  64. package/dist/commands/design-verify.d.ts +0 -31
  65. package/dist/commands/dismiss.d.ts +0 -29
  66. package/dist/commands/hooks.d.ts +0 -13
  67. package/dist/commands/inbox.d.ts +0 -65
  68. package/dist/commands/init.d.ts +0 -10
  69. package/dist/commands/install-session-hooks.d.ts +0 -17
  70. package/dist/commands/login.d.ts +0 -8
  71. package/dist/commands/mcp.d.ts +0 -1
  72. package/dist/commands/policy.d.ts +0 -31
  73. package/dist/commands/pr-status.d.ts +0 -144
  74. package/dist/commands/pr.d.ts +0 -40
  75. package/dist/commands/precompute-delivery-contract.d.ts +0 -68
  76. package/dist/commands/precompute-delivery.d.ts +0 -20
  77. package/dist/commands/prepare-universe-review.d.ts +0 -115
  78. package/dist/commands/production-source-deny-policy.d.ts +0 -15
  79. package/dist/commands/request-review.d.ts +0 -26
  80. package/dist/commands/review.d.ts +0 -25
  81. package/dist/commands/rules.d.ts +0 -4
  82. package/dist/commands/scaffold-provisional-universe.d.ts +0 -468
  83. package/dist/commands/schema-cmd.d.ts +0 -2
  84. package/dist/commands/setup.d.ts +0 -28
  85. package/dist/commands/skills.d.ts +0 -8
  86. package/dist/commands/status.d.ts +0 -4
  87. package/dist/commands/submit.d.ts +0 -30
  88. package/dist/commands/system-map.d.ts +0 -42
  89. package/dist/commands/telemetry.d.ts +0 -53
  90. package/dist/commands/tokens.d.ts +0 -14
  91. package/dist/commands/triage.d.ts +0 -35
  92. package/dist/commands/verify-core.d.ts +0 -449
  93. package/dist/commands/verify-core.js +0 -789
  94. package/dist/commands/verify-explore.d.ts +0 -14
  95. package/dist/commands/verify-hosted-mcp.d.ts +0 -12
  96. package/dist/commands/verify-hosted-reproducibility.d.ts +0 -90
  97. package/dist/commands/verify-hosted.d.ts +0 -92
  98. package/dist/commands/verify-mcp.d.ts +0 -8
  99. package/dist/commands/verify-mcp.js +0 -517
  100. package/dist/commands/verify-ops.d.ts +0 -158
  101. package/dist/commands/verify-ops.js +0 -1148
  102. package/dist/commands/verify-precompute.d.ts +0 -30
  103. package/dist/commands/verify-reproducibility.d.ts +0 -85
  104. package/dist/commands/verify-reproducibility.js +0 -494
  105. package/dist/commands/verify-reseal.d.ts +0 -9
  106. package/dist/commands/verify-reseal.js +0 -148
  107. package/dist/commands/verify-sandboxes.d.ts +0 -95
  108. package/dist/commands/verify-sandboxes.js +0 -352
  109. package/dist/commands/verify.d.ts +0 -28
  110. package/dist/commands/webhooks.d.ts +0 -30
  111. package/dist/index.d.ts +0 -22
  112. package/dist/schema.d.ts +0 -28
  113. package/dist/states.d.ts +0 -29
  114. package/dist/tools/detect.d.ts +0 -50
  115. package/dist/triage/prompts.d.ts +0 -24
  116. package/dist/triage/runner.d.ts +0 -34
  117. package/dist/triage/types.d.ts +0 -42
  118. package/dist/types.d.ts +0 -1684
  119. package/dist/utils/action-output.d.ts +0 -24
  120. package/dist/utils/analysis-api.d.ts +0 -187
  121. package/dist/utils/auth.d.ts +0 -79
  122. package/dist/utils/config.d.ts +0 -24
  123. package/dist/utils/design-verifier-api.d.ts +0 -200
  124. package/dist/utils/design-verifier-result.d.ts +0 -74
  125. package/dist/utils/detect.d.ts +0 -43
  126. package/dist/utils/git.d.ts +0 -135
  127. package/dist/utils/github-api.d.ts +0 -104
  128. package/dist/utils/haystack-api.d.ts +0 -37
  129. package/dist/utils/hooks.d.ts +0 -12
  130. package/dist/utils/pending-state.d.ts +0 -40
  131. package/dist/utils/pr-ref.d.ts +0 -27
  132. package/dist/utils/prompter.d.ts +0 -85
  133. package/dist/utils/secrets.d.ts +0 -47
  134. package/dist/utils/telemetry.d.ts +0 -19
  135. /package/dist/commands/{precompute-delivery-worker.d.ts → combination-search-hook-contract.js} +0 -0
package/README.md CHANGED
@@ -10,6 +10,13 @@ haystack login
10
10
  haystack setup
11
11
  ```
12
12
 
13
+ Requires Node.js 22.18 or newer.
14
+
15
+ After a command finishes in an interactive terminal, the CLI checks npm at most
16
+ once a day and prints one line on stderr when a newer version exists. It never
17
+ runs with `--json`, when stdout is not a TTY, or when `CI` is set. Set
18
+ `HAYSTACK_NO_UPDATE_CHECK=1` to turn it off.
19
+
13
20
  The `setup` command walks you through an interactive wizard:
14
21
 
15
22
  1. **Select repositories** to configure
@@ -20,8 +27,9 @@ The `setup` command walks you through an interactive wizard:
20
27
  6. **Write `.haystack.json`** to your repos
21
28
 
22
29
  The CLI sends limited operational events to PostHog by default so Haystack can
23
- measure setup reliability. Events contain a pseudonymous machine identifier,
24
- CLI/version/platform fields, command-step and error categories, and numeric
30
+ measure setup reliability. Events contain a pseudonymous install identifier
31
+ (a random id generated once and stored in `~/.haystack/telemetry-id`; it is
32
+ not derived from your username or hostname), CLI/version/platform fields, command-step and error categories, and numeric
25
33
  outcomes. They exclude source code, repository names, local paths, usernames,
26
34
  hostnames, and raw error text. IP enrichment is disabled. Set `DO_NOT_TRACK=1`
27
35
  or `HAYSTACK_TELEMETRY_DISABLED=1` to turn this telemetry off.
@@ -72,90 +80,89 @@ haystack triage <ref> --json # poll findings later / after --no-wait
72
80
  `dismiss`, `mark_reviewed`, `undismiss`, `request_review`, `trigger_review`,
73
81
  and `schema`.
74
82
 
75
- **`haystack verify mcp`** runs the cloud-verifier MCP server. Retained
76
- application state is available through `verify_reopen`, `verify_refork`, and
77
- `verify_cleanup`. Agents select state by an exact Archil fork ID or a stable
78
- run/test/side coordinate; refork returns a durable child ID that can be
79
- reopened or nested again without receiving provider credentials. The matching
80
- CLI flow is:
83
+ **`haystack verify`** verifies the current change using the authenticated
84
+ Haystack fleet. Inside a git checkout, push your commit and run:
81
85
 
82
86
  ```bash
83
- haystack verify reopen latest 3
84
- # inspect or mutate the returned sandbox
85
- haystack verify refork latest 3 attempt:fix-2
86
- haystack verify reopen archil:<disk-id>:branch:<returned-child>
87
+ haystack verify
88
+ haystack verify --json
87
89
  ```
88
90
 
89
- **`haystack verify hosted`** is the authenticated production entry point for
90
- exact GitHub commit pairs. It uses the repository-default saved account,
91
- submits an idempotent run, and waits up to 35 minutes by default:
91
+ The repository defaults to `owner/repo` from the `origin` remote URL. The head
92
+ is the current `HEAD` commit. The base is `git merge-base HEAD
93
+ origin/<default branch>`, using `origin/HEAD` to discover the default branch
94
+ and falling back to `origin/main`. If the current commit is not reachable from
95
+ any remote-tracking branch, the command asks you to push first.
96
+ Explicit `--repo`, `--base`, and `--head` values override their defaults; supplying
97
+ all three also works outside a checkout:
92
98
 
93
99
  ```bash
94
- haystack verify hosted start owner/repo \
95
- --base <40-character-commit-sha> \
96
- --head <40-character-commit-sha> \
97
- --json
100
+ haystack verify --repo owner/repo --base main --head feature --json
98
101
  ```
99
102
 
100
- Use `--no-wait` to return as soon as the workflow is queued. The result includes
101
- an account-bound `next_command`; use it verbatim on machines with multiple
102
- saved GitHub accounts. Repeating the same repository/base/head tuple reuses the
103
- same production run by default. Pass a new explicit `--idempotency-key` only
104
- when a fresh execution is intentional. A bounded wait that expires still emits
105
- the `cloud-verifier` schema with `timed_out: true`, the last observed status,
106
- and `next_command`, then exits 2. Read or resume a known run with:
103
+ Intent is optional: `--intent-file <path>` accepts JSON with exactly `problem`,
104
+ `goal`, and `intended_outcomes`. The CLI uses your saved account and waits up to
105
+ 35 minutes by default. Pass `--no-wait` to return after the fleet run is queued.
106
+ Repeating the same repository, refs, and intent reuses the same run; choose a new
107
+ `--idempotency-key` when a fresh execution is intentional. A wait that expires
108
+ prints `timed_out: true` and `next_command`, then exits 2. Resume with:
107
109
 
108
110
  ```bash
109
- haystack verify hosted status cv_<48-lowercase-hex-characters> \
110
- --account <login> \
111
- --wait \
112
- --json
111
+ haystack verify hosted status cv_<48-lowercase-hex-characters> --wait --json
112
+ haystack verify history owner/repo --limit 20
113
113
  ```
114
114
 
115
- To execute a completed run's exact validated risk plan again, keep the same
116
- repository and commit pair and pass:
115
+ Use the returned account-bound `next_command` verbatim on machines with multiple
116
+ saved accounts. `haystack verify hosted start owner/repo --base <sha> --head
117
+ <sha>` starts the same fleet execution through an explicit subcommand.
118
+
119
+ Retained fleet cases remain available through their exact case IDs:
117
120
 
118
121
  ```bash
119
- haystack verify hosted start owner/repo \
120
- --base <40-character-commit-sha> \
121
- --head <40-character-commit-sha> \
122
- --replay-plan-from cv_<48-lowercase-hex-characters> \
123
- --json
122
+ haystack verify cases <run-id> --repo owner/repo
123
+ haystack verify explore <run-id> <case-id> --repo owner/repo
124
124
  ```
125
125
 
126
- A successful replay emits a schema-9 terminal result whose
127
- `riskPlanReplayReceipt` binds the source run and canonical risk-plan hash. The
128
- replay does not mint or deliver a planning-model credential.
126
+ Agents can use the same lifecycle with `haystack verify hosted mcp --account
127
+ <login>`. Its tools are `verify_start`, `verify_status`, and `verify_wait`.
129
128
 
130
- Agents can use the same production lifecycle over stdio MCP:
129
+ To repeat independent fleet runs for one exact commit pair:
131
130
 
132
131
  ```bash
133
- haystack verify hosted mcp --account <login>
132
+ haystack verify hosted reproducibility owner/repo \
133
+ --base <40-character-commit-sha> \
134
+ --head <40-character-commit-sha> \
135
+ --runs 3 --json
134
136
  ```
135
137
 
136
- The hosted server exposes only `verify_start`, `verify_status`, and
137
- `verify_wait`. Tool results use the same `cloud-verifier` schema as the CLI;
138
- credentials, repository source, provider metadata, and sandbox mutation are
139
- not exposed.
138
+ The report includes each run's fleet receipt. Each ordinal has a distinct
139
+ idempotency key derived from the printed series key, repository, commits, and
140
+ intent; `--series-key <key>` resumes the same series. Independent plans do not
141
+ share an execution identity, so reproducibility remains unestablished and the
142
+ command exits 2. A timeout stops the series and includes the active run's resume
143
+ command.
140
144
 
141
- Freeze one production plan and repeat its exact execution to detect executor or
142
- assessment drift:
145
+ **`haystack case-batch`** runs an already-generated product-fuzzing case
146
+ batch on the hosted coordinator. The laptop only submits and polls: it holds no
147
+ fleet credential, creates no VM, and kills nothing.
143
148
 
144
149
  ```bash
145
- haystack verify hosted reproducibility owner/repo \
146
- --base <40-character-commit-sha> \
147
- --head <40-character-commit-sha> \
148
- --runs 3 \
149
- --json
150
+ haystack case-batch submit --repository owner/repo \
151
+ --base <40-character-commit-sha> --head <40-character-commit-sha> \
152
+ --cases cases.json --combinations space.json --max-concurrent 200 --json
153
+ haystack case-batch status <run-id> --repository owner/repo --watch --json
154
+ haystack case-batch cancel <run-id> --repository owner/repo
155
+ haystack case-batch bundle <run-id> --repository owner/repo --out ./bundle
150
156
  ```
151
157
 
152
- The first run creates the source plan; every later run names it through
153
- `replayPlanFromRunId`. Each run gets a distinct idempotency key derived from one
154
- printed series key. Pass `--series-key <key>` to resume the same series without
155
- creating duplicate runs. The report verifies schema-9 replay provenance and
156
- compares stable risk-cell, capability, and comparison IDs. Missing replay
157
- provenance, assessment drift, timeouts, unsupported receipts, and inconclusive
158
- cells all prevent a reproducible verdict and exit 2.
158
+ Cases and the combination space travel inline and the whole request is bounded
159
+ at 8 MiB; no source patch is sent unless `--source-patch <file>` names the
160
+ precompute-captured `{ cacheKey, patchSha256, patchGzBase64 }` record.
161
+ `status` follows the case cursor to the end of the list and prints one row per
162
+ case — id, position, status, unknown reason, wall time and whether cleanup was
163
+ proven — including when the batch ends `incomplete`, which exits 2 with a
164
+ summary rather than a single failure. `haystack schema case-batch` prints the
165
+ `--json` schema.
159
166
 
160
167
  **`haystack setup --json`** speaks NDJSON: events (`question`, `permission`,
161
168
  `progress`, `result`) on stdout, replies on stdin keyed by
@@ -440,6 +447,50 @@ haystack hooks install-session --cli all # All detected CLIs
440
447
  haystack hooks session-status # Check session hook status
441
448
  ```
442
449
 
450
+ ### `haystack case-batch`
451
+
452
+ Submit and poll product-fuzzing case batches on the hosted coordinator
453
+ (`CASE-BATCH-V1`):
454
+
455
+ ```bash
456
+ # Submit an ordered batch against one frozen world pair
457
+ haystack case-batch submit --repository owner/repo \
458
+ --base <sha> --head <sha> \
459
+ --cases cases.json --combinations space.json \
460
+ --base-world frz_<16-hex> --head-world frz_<16-hex> \
461
+ --max-concurrent 200 --per-case-wall-ms 15000 --total-budget-ms 600000 --json
462
+
463
+ # Read every per-case outcome; --watch polls until terminal or --max-wall
464
+ haystack case-batch status <run-id> --repository owner/repo --watch --json
465
+
466
+ # Request cancellation (a claimed batch drains until its owner proves cleanup)
467
+ haystack case-batch cancel <run-id> --repository owner/repo
468
+
469
+ # Download the replay bundle, verifying every artifact digest
470
+ haystack case-batch bundle <run-id> --repository owner/repo --out ./bundle
471
+ ```
472
+
473
+ `bundle` requires the service's sealed SHA-256 for `manifest.json` (served as
474
+ its ETag), because the manifest is the one artifact with no parent digest to
475
+ check it against; without it the command fails and writes nothing. Every other
476
+ artifact is checked against the sha256 and byte length the manifest declares
477
+ for it.
478
+
479
+ Knobs and what turning them does:
480
+
481
+ | Flag | Default | Effect |
482
+ |------|---------|--------|
483
+ | `--max-concurrent <n>` | the case count, capped at 500 | Ceiling only. Admitted concurrency is the smaller of it and the fleet's free capacity; the run's receipt reports both. |
484
+ | `--per-case-wall-ms <ms>` | 120000 | A case that overruns is killed and recorded `UNKNOWN`/`wall-budget`, never dropped. Above the MVP's measured 103.8 s maximum, so it does not kill cases running at today's cost. |
485
+ | `--total-budget-ms <ms>` | 1800000 (the contract ceiling) | Bounds launches from the first launch. Cases already launched run to their own wall budget. |
486
+ | `--idempotency-key <key>` | derived from the whole submission | An exact retry returns the original run; a new key is a new execution. |
487
+ | `--interval <seconds>` | 10 | Polling interval while `--watch` is set. |
488
+ | `--max-wall <minutes>` | 45 | Total polling wall. Hitting it prints the snapshot, says `timed_out`, and exits 2. |
489
+
490
+ `status` exits 0 for a `completed` batch with cleanup proven, and 2 for
491
+ `incomplete`, `cancelled`, unproven cleanup, or a wait that hits `--max-wall`.
492
+ Either way every per-case row is printed.
493
+
443
494
  ### `haystack policy`
444
495
 
445
496
  Manage review policies (`.haystack/review-policy.md`):
@@ -1,2 +1,5 @@
1
1
  #!/bin/sh
2
2
  # Haystack commit-msg hook
3
+ # Haystack's own hooks never need the push credential the CLI exports for
4
+ # `git push`; drop it so nothing these hooks run can read it.
5
+ unset HAYSTACK_GIT_TOKEN
@@ -1,2 +1,5 @@
1
1
  #!/bin/sh
2
2
  # Haystack post-commit hook
3
+ # Haystack's own hooks never need the push credential the CLI exports for
4
+ # `git push`; drop it so nothing these hooks run can read it.
5
+ unset HAYSTACK_GIT_TOKEN
@@ -1,4 +1,7 @@
1
1
  #!/usr/bin/env bash
2
+ # Haystack's own hooks never need the push credential the CLI exports for
3
+ # `git push`; drop it so nothing these hooks run can read it.
4
+ unset HAYSTACK_GIT_TOKEN
2
5
  HOOKS_DIR="$(cd "$(dirname "$0")" && pwd)"
3
6
  REPO_ROOT="$(cd "$HOOKS_DIR/.." && pwd)"
4
7
  TSX_IMPORT="$HOOKS_DIR/node_modules/tsx/dist/loader.mjs"
@@ -72,14 +75,16 @@ run_tsx() {
72
75
  return
73
76
  fi
74
77
 
75
- if [ -x "$TSX_BIN" ]; then
76
- "$TSX_BIN" "$@"
77
- return
78
- fi
79
-
80
- npx tsx "$@"
78
+ "$TSX_BIN" "$@"
81
79
  }
82
80
 
81
+ # No network fallback: without a supported Node or the installed hook
82
+ # dependencies, fail rather than fetch an unpinned tsx with npx.
83
+ if ! node_supports_import && ! node_supports_loader && [ ! -x "$TSX_BIN" ]; then
84
+ echo "Haystack pre-commit: needs Node 18 or later, or hooks/node_modules (run npm ci in hooks/)." >&2
85
+ exit 1
86
+ fi
87
+
83
88
  # Extract agent context if running under an AI agent
84
89
  # Capture stderr to detect whether an AI agent is present
85
90
  AGENT_OUTPUT=$(run_tsx "$HOOKS_DIR/agent-context/index.ts" "$REPO_ROOT" 2>&1) || true
@@ -1,5 +1,8 @@
1
1
  #!/bin/sh
2
2
  # Haystack pre-push hook
3
+ # Haystack's own hooks never need the push credential the CLI exports for
4
+ # `git push`; drop it so nothing these hooks run can read it.
5
+ unset HAYSTACK_GIT_TOKEN
3
6
  # $1 is the remote name (e.g., "origin")
4
7
 
5
8
  # Check if pushing a non-haystack branch and remind about haystack submit
@@ -1,2 +1,5 @@
1
1
  #!/bin/sh
2
2
  # Haystack prepare-commit-msg hook
3
+ # Haystack's own hooks never need the push credential the CLI exports for
4
+ # `git push`; drop it so nothing these hooks run can read it.
5
+ unset HAYSTACK_GIT_TOKEN