@haystackeditor/cli 0.9.0 → 0.10.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.
@@ -18,5 +18,6 @@ export interface SubmitOptions {
18
18
  review?: string | true;
19
19
  force?: boolean;
20
20
  wait?: boolean;
21
+ autoFix?: boolean;
21
22
  }
22
23
  export declare function submitCommand(options: SubmitOptions): Promise<void>;
@@ -287,6 +287,19 @@ export async function submitCommand(options) {
287
287
  }
288
288
  }
289
289
  // -------------------------------------------------------------------------
290
+ // Step 6b: Apply auto-fix label if --auto-fix
291
+ // -------------------------------------------------------------------------
292
+ if (options.autoFix) {
293
+ try {
294
+ await ensureHaystackLabels(remoteInfo.owner, remoteInfo.repo, ['haystack:auto-fix']);
295
+ await addLabelsToIssue(remoteInfo.owner, remoteInfo.repo, prNumber, ['haystack:auto-fix']);
296
+ console.log(chalk.green('✓ Auto-fix enabled for this PR'));
297
+ }
298
+ catch (err) {
299
+ console.log(chalk.yellow(`⚠ Could not set auto-fix label: ${err.message}`));
300
+ }
301
+ }
302
+ // -------------------------------------------------------------------------
290
303
  // Step 7: Request review if --review
291
304
  // -------------------------------------------------------------------------
292
305
  if (options.review) {
@@ -318,6 +331,9 @@ export async function submitCommand(options) {
318
331
  if (autoMergeEnabled) {
319
332
  console.log(` ${chalk.dim('Merge:')} ${chalk.green('Auto-merge if safe')}`);
320
333
  }
334
+ if (options.autoFix) {
335
+ console.log(` ${chalk.dim('Fix:')} ${chalk.cyan('Auto-fix issues before Feed')}`);
336
+ }
321
337
  if (options.review) {
322
338
  const reviewer = typeof options.review === 'string' ? options.review : 'needs assignment';
323
339
  console.log(` ${chalk.dim('Review:')} ${chalk.yellow(reviewer)}`);
@@ -388,6 +404,16 @@ export async function submitCommand(options) {
388
404
  console.log(chalk.dim(` ${verdict.summary}`));
389
405
  }
390
406
  }
407
+ else if (options.autoFix) {
408
+ // Auto-fix flow: agent fixes straightforward issues in the background.
409
+ // Issues appear in Feed immediately — user can review while agent works.
410
+ console.log(chalk.cyan.bold(' ⚙ Auto-fix triggered\n'));
411
+ console.log(chalk.dim(` ${verdict.summary}\n`));
412
+ console.log(chalk.dim(' Coding agent is fixing straightforward issues in the background.'));
413
+ console.log(chalk.dim(' Issues that need your judgment are in the Feed now.\n'));
414
+ const reviewUrl = `https://haystackeditor.com/review/${remoteInfo.owner}/${remoteInfo.repo}/${prNumber}`;
415
+ console.log(` ${chalk.dim('Feed:')} ${chalk.cyan(reviewUrl)}\n`);
416
+ }
391
417
  else {
392
418
  console.log(chalk.yellow.bold(' ⚠ Needs your input\n'));
393
419
  console.log(chalk.dim(` ${verdict.summary}\n`));
@@ -397,7 +423,9 @@ export async function submitCommand(options) {
397
423
  console.log(` ${icon} ${chalk.dim(loc)} ${issue.message}`);
398
424
  }
399
425
  }
400
- console.log(`\n ${chalk.dim('Review:')} ${chalk.cyan(verdict.reviewUrl)}\n`);
426
+ if (!options.autoFix || verdict.state === 'good-to-merge') {
427
+ console.log(`\n ${chalk.dim('Review:')} ${chalk.cyan(verdict.reviewUrl)}\n`);
428
+ }
401
429
  }
402
430
  catch {
403
431
  console.log(chalk.yellow('⚠ Analysis complete but could not fetch results.'));
package/dist/index.d.ts CHANGED
@@ -2,16 +2,20 @@
2
2
  /**
3
3
  * Haystack CLI
4
4
  *
5
- * Set up your project for Haystack verification.
6
- * This enables AI agents to spin up sandboxes of your app for testing.
5
+ * Set up your project for Haystack.
6
+ * Automated PR review, triage, and merge queue for AI-assisted development.
7
7
  *
8
8
  * Usage:
9
9
  * npx @haystackeditor/cli init # Set up .haystack.json
10
+ * npx @haystackeditor/cli setup # Interactive onboarding wizard
10
11
  * npx @haystackeditor/cli status # Check configuration
11
12
  * npx @haystackeditor/cli login # Authenticate with GitHub
12
13
  * npx @haystackeditor/cli submit # Create a PR (auto-merge or review)
13
14
  * npx @haystackeditor/cli check-pending # Check analysis status
14
15
  * npx @haystackeditor/cli triage 123 # View analysis results for a PR
16
+ * npx @haystackeditor/cli dismiss 123 # Dismiss findings for a PR
17
+ * npx @haystackeditor/cli mark-reviewed 123 # Mark review as not needed
18
+ * npx @haystackeditor/cli pr-status 123 # Show PR status in Haystack pipeline
15
19
  * npx @haystackeditor/cli secrets list # List stored secrets
16
20
  */
17
21
  export {};
package/dist/index.js CHANGED
@@ -2,16 +2,20 @@
2
2
  /**
3
3
  * Haystack CLI
4
4
  *
5
- * Set up your project for Haystack verification.
6
- * This enables AI agents to spin up sandboxes of your app for testing.
5
+ * Set up your project for Haystack.
6
+ * Automated PR review, triage, and merge queue for AI-assisted development.
7
7
  *
8
8
  * Usage:
9
9
  * npx @haystackeditor/cli init # Set up .haystack.json
10
+ * npx @haystackeditor/cli setup # Interactive onboarding wizard
10
11
  * npx @haystackeditor/cli status # Check configuration
11
12
  * npx @haystackeditor/cli login # Authenticate with GitHub
12
13
  * npx @haystackeditor/cli submit # Create a PR (auto-merge or review)
13
14
  * npx @haystackeditor/cli check-pending # Check analysis status
14
15
  * npx @haystackeditor/cli triage 123 # View analysis results for a PR
16
+ * npx @haystackeditor/cli dismiss 123 # Dismiss findings for a PR
17
+ * npx @haystackeditor/cli mark-reviewed 123 # Mark review as not needed
18
+ * npx @haystackeditor/cli pr-status 123 # Show PR status in Haystack pipeline
15
19
  * npx @haystackeditor/cli secrets list # List stored secrets
16
20
  */
17
21
  import { Command } from 'commander';
@@ -27,11 +31,14 @@ import { checkPendingCommand } from './commands/check-pending.js';
27
31
  import { installSessionHooks, sessionHooksStatus } from './commands/install-session-hooks.js';
28
32
  import { listPolicies, addPolicy, removePolicy, initPolicies, addInstruction } from './commands/policy.js';
29
33
  import { triageCommand } from './commands/triage.js';
34
+ import { dismissCommand, markReviewedCommand, undismissCommand } from './commands/dismiss.js';
35
+ import { prStatusCommand } from './commands/pr-status.js';
36
+ import { setupCommand } from './commands/setup.js';
30
37
  const program = new Command();
31
38
  program
32
39
  .name('haystack')
33
- .description('Set up Haystack verification for your project')
34
- .version('0.9.0');
40
+ .description('Haystack CLI automated PR review, triage, and merge queue')
41
+ .version('0.10.1');
35
42
  program
36
43
  .command('init')
37
44
  .description('Create .haystack.json configuration')
@@ -42,10 +49,29 @@ This creates a .haystack.json file with auto-detected settings:
42
49
  • Services (for monorepos)
43
50
  • Auth bypass for sandbox environments
44
51
 
45
- After running, use /setup-haystack in Claude Code (or give your AI agent
46
- .agents/skills/setup-haystack.md) to add verification flows.
52
+ After running, use \`haystack setup\` to scan your repos for rules,
53
+ CI signals, and review policies.
47
54
  `)
48
55
  .action(initCommand);
56
+ program
57
+ .command('setup')
58
+ .description('Interactive onboarding wizard — scan repos for rules, signals, and policies')
59
+ .addHelpText('after', `
60
+ This walks you through Haystack setup step by step:
61
+
62
+ 1. Select GitHub repositories to configure
63
+ 2. Scan for coding rules (conventions your team follows)
64
+ 3. Scan for CI/bot signals (checks to wait for before merging)
65
+ 4. Scan for review policies (who should review what)
66
+ 5. Review and toggle discovered items
67
+ 6. Write .haystack.json to your repos
68
+
69
+ Requires authentication — run \`haystack login\` first.
70
+
71
+ Examples:
72
+ haystack setup
73
+ `)
74
+ .action(setupCommand);
49
75
  program
50
76
  .command('status')
51
77
  .description('Check if .haystack.json exists and is valid')
@@ -68,6 +94,7 @@ program
68
94
  .option('--draft', 'Create as draft PR')
69
95
  .option('--review [reviewer]', 'Request human review (BLOCKS auto-merge — only use when explicitly asked)')
70
96
  .option('--force', 'Skip pre-PR triage checks')
97
+ .option('--auto-fix', 'Auto-fix analysis issues in a sandbox before surfacing to Feed')
71
98
  .option('--no-wait', 'Skip waiting for analysis results')
72
99
  .addHelpText('after', `
73
100
  This command is designed for AI coding agents to submit PRs.
@@ -85,6 +112,7 @@ Pre-PR Triage:
85
112
 
86
113
  Use --force to skip triage entirely.
87
114
  Use --no-wait to skip waiting for analysis results.
115
+ Use --auto-fix to auto-fix analysis issues before surfacing to Feed.
88
116
 
89
117
  Review Routing:
90
118
  By default, PRs enter the auto-merge queue and merge automatically once
@@ -99,7 +127,8 @@ Review Routing:
99
127
  • --review <username> Same label, plus requests review from that GitHub user
100
128
 
101
129
  Examples:
102
- haystack submit # Triage, create PR, auto-merge queue
130
+ haystack submit --auto-fix # Recommended: triage, create PR, auto-fix issues
131
+ haystack submit # Triage, create PR, auto-merge queue (no auto-fix)
103
132
  haystack submit --force # Skip triage
104
133
  haystack submit --no-wait # Don't wait for analysis
105
134
  haystack submit --title "Fix auth" # Custom PR title
@@ -159,6 +188,87 @@ Examples:
159
188
  haystack triage 42 --no-wait # Don't wait if pending
160
189
  `)
161
190
  .action(triageCommand);
191
+ program
192
+ .command('dismiss <pr>')
193
+ .description('Dismiss analysis findings for a PR')
194
+ .addHelpText('after', `
195
+ Dismiss analysis findings for a PR, moving it from "Issues Found" to
196
+ "Good to Merge" in the Haystack feed.
197
+
198
+ The override is tied to the PR's current HEAD commit. If a new commit is
199
+ pushed, the override is invalidated and you'll need to dismiss again.
200
+
201
+ PR identifier formats:
202
+ 123 PR number (uses current repo)
203
+ #123 PR number with hash
204
+ owner/repo#123 Fully qualified
205
+ https://github.com/owner/repo/pull/123 GitHub URL
206
+
207
+ Examples:
208
+ haystack dismiss 42 # Dismiss findings for PR #42
209
+ haystack dismiss acme/widgets#99 # Dismiss for specific repo
210
+ `)
211
+ .action(dismissCommand);
212
+ program
213
+ .command('mark-reviewed <pr>')
214
+ .description('Mark human review as not needed for a PR')
215
+ .addHelpText('after', `
216
+ Mark human review as not needed for a PR, moving it from "Needs Review"
217
+ to "Good to Merge" in the Haystack feed.
218
+
219
+ The override is tied to the PR's current HEAD commit. If a new commit is
220
+ pushed, the override is invalidated and you'll need to mark it again.
221
+
222
+ PR identifier formats:
223
+ 123 PR number (uses current repo)
224
+ #123 PR number with hash
225
+ owner/repo#123 Fully qualified
226
+ https://github.com/owner/repo/pull/123 GitHub URL
227
+
228
+ Examples:
229
+ haystack mark-reviewed 42 # Mark review not needed for PR #42
230
+ haystack mark-reviewed acme/widgets#99 # Mark for specific repo
231
+ `)
232
+ .action(markReviewedCommand);
233
+ program
234
+ .command('undismiss <pr>')
235
+ .description('Undo a dismiss or mark-reviewed override for a PR')
236
+ .addHelpText('after', `
237
+ Clear all overrides (dismissed findings and/or review-not-needed) for a PR,
238
+ returning it to its original feed bucket.
239
+
240
+ PR identifier formats:
241
+ 123 PR number (uses current repo)
242
+ #123 PR number with hash
243
+ owner/repo#123 Fully qualified
244
+ https://github.com/owner/repo/pull/123 GitHub URL
245
+
246
+ Examples:
247
+ haystack undismiss 42 # Undo overrides for PR #42
248
+ haystack undismiss acme/widgets#99 # Undo for specific repo
249
+ `)
250
+ .action(undismissCommand);
251
+ program
252
+ .command('pr-status <pr>')
253
+ .description('Show the current Haystack status of a PR')
254
+ .option('--json', 'Output as JSON')
255
+ .addHelpText('after', `
256
+ Show what bucket a PR is in within the Haystack pipeline:
257
+ analyzing, auto-fixing, good-to-merge, issues, needs-assignment, etc.
258
+
259
+ PR identifier formats:
260
+ 123 PR number (uses current repo)
261
+ #123 PR number with hash
262
+ owner/repo#123 Fully qualified
263
+ https://github.com/owner/repo/pull/123 GitHub URL
264
+
265
+ Examples:
266
+ haystack pr-status 42 # Current repo, PR #42
267
+ haystack pr-status acme/widgets#99 # Specific repo
268
+ haystack pr-status https://github.com/o/r/pull/1 # From URL
269
+ haystack pr-status 42 --json # Machine-readable output
270
+ `)
271
+ .action(prStatusCommand);
162
272
  // Secrets subcommands
163
273
  const secrets = program
164
274
  .command('secrets')
@@ -11,7 +11,7 @@
11
11
  * Build the code review prompt.
12
12
  * Always runs — looks for objective bugs in the diff.
13
13
  */
14
- export declare function buildCodeReviewPrompt(baseBranch: string, outputPath: string): string;
14
+ export declare function buildCodeReviewPrompt(baseBranch: string, outputPath: string, precomputedDiff?: string | null): string;
15
15
  /**
16
16
  * Build the rules validator prompt.
17
17
  * Runs if .haystack/pr-rules.yml exists OR agent instruction files are found.
@@ -21,11 +21,11 @@ export declare function buildCodeReviewPrompt(baseBranch: string, outputPath: st
21
21
  export declare function buildRulesValidatorPrompt(baseBranch: string, rulesYaml: string, outputPath: string, agentPolicies?: {
22
22
  filename: string;
23
23
  content: string;
24
- }[]): string | null;
24
+ }[], precomputedDiff?: string | null): string | null;
25
25
  /**
26
26
  * Build the intent drift prompt.
27
27
  * Only runs if relevant trace files exist.
28
28
  *
29
29
  * @returns The prompt string, or null if no trace files provided.
30
30
  */
31
- export declare function buildIntentDriftPrompt(baseBranch: string, traceFiles: string[], outputPath: string): string | null;
31
+ export declare function buildIntentDriftPrompt(baseBranch: string, traceFiles: string[], outputPath: string, precomputedDiff?: string | null): string | null;
@@ -59,15 +59,27 @@ const INTENT_DRIFT_SCHEMA = `{
59
59
  * Build the code review prompt.
60
60
  * Always runs — looks for objective bugs in the diff.
61
61
  */
62
- export function buildCodeReviewPrompt(baseBranch, outputPath) {
63
- return `You are a pre-PR code reviewer. Your job is to find OBJECTIVE BUGS in the code changes that will cause incorrect runtime behavior.
62
+ export function buildCodeReviewPrompt(baseBranch, outputPath, precomputedDiff) {
63
+ const diffSection = precomputedDiff
64
+ ? `## Diff (precomputed)
65
+
66
+ \`\`\`diff
67
+ ${precomputedDiff}
68
+ \`\`\`
64
69
 
65
70
  ## Instructions
66
71
 
67
- 1. Run \`git diff ${baseBranch}...HEAD --name-only\` to see which files changed.
68
- 2. Run \`git diff ${baseBranch}...HEAD\` to see the full diff. For large diffs, review file by file.
69
- 3. For each changed file, read the surrounding code if needed to understand context.
70
- 4. Identify only REAL BUGS — things that will definitely crash, produce wrong results, or corrupt data.
72
+ 1. Review the diff above.
73
+ 2. If you need more context for a specific function, read just that section of the file do NOT read entire large files.
74
+ 3. Identify only REAL BUGS things that will definitely crash, produce wrong results, or corrupt data.`
75
+ : `## Instructions
76
+
77
+ 1. Run \`git diff ${baseBranch}...HEAD\` to see the full diff.
78
+ 2. If you need more context for a specific function, read just that section of the file — do NOT read entire large files.
79
+ 3. Identify only REAL BUGS — things that will definitely crash, produce wrong results, or corrupt data.`;
80
+ return `You are a pre-PR code reviewer. Your job is to find OBJECTIVE BUGS in the code changes that will cause incorrect runtime behavior.
81
+
82
+ ${diffSection}
71
83
 
72
84
  ## What to flag
73
85
 
@@ -110,7 +122,7 @@ Be extremely conservative. False positives waste the developer's time. Only flag
110
122
  *
111
123
  * @returns The prompt string, or null if no rules content or agent policies provided.
112
124
  */
113
- export function buildRulesValidatorPrompt(baseBranch, rulesYaml, outputPath, agentPolicies) {
125
+ export function buildRulesValidatorPrompt(baseBranch, rulesYaml, outputPath, agentPolicies, precomputedDiff) {
114
126
  const hasRules = rulesYaml.trim().length > 0;
115
127
  const hasPolicies = agentPolicies && agentPolicies.length > 0;
116
128
  if (!hasRules && !hasPolicies)
@@ -165,14 +177,26 @@ For each extracted policy violation:
165
177
 
166
178
  `;
167
179
  }
168
- return `You are a PR rules validator. Your job is to check the code changes against project rules and policies, then flag violations.
180
+ const diffInstructions = precomputedDiff
181
+ ? `## Diff (precomputed)
169
182
 
170
- ${rulesSection}${policiesSection}## Instructions
183
+ \`\`\`diff
184
+ ${precomputedDiff}
185
+ \`\`\`
171
186
 
172
- 1. Run \`git diff ${baseBranch}...HEAD --name-only\` to see which files changed.
173
- 2. Run \`git diff ${baseBranch}...HEAD\` to see the full diff.
174
- 3. Check ONLY the changed code (lines added or modified in the diff), not pre-existing code.
175
- 4. If you need more context, read the relevant source files.
187
+ ## Instructions
188
+
189
+ 1. Review the diff above.
190
+ 2. Check ONLY the changed code (lines added or modified in the diff), not pre-existing code.
191
+ 3. If you need more context, read just the relevant section of the file — do NOT read entire large files.`
192
+ : `## Instructions
193
+
194
+ 1. Run \`git diff ${baseBranch}...HEAD\` to see the full diff.
195
+ 2. Check ONLY the changed code (lines added or modified in the diff), not pre-existing code.
196
+ 3. If you need more context, read just the relevant section of the file — do NOT read entire large files.`;
197
+ return `You are a PR rules validator. Your job is to check the code changes against project rules and policies, then flag violations.
198
+
199
+ ${rulesSection}${policiesSection}${diffInstructions}
176
200
 
177
201
  ## Important
178
202
 
@@ -199,7 +223,7 @@ ${RULES_VALIDATOR_SCHEMA}
199
223
  *
200
224
  * @returns The prompt string, or null if no trace files provided.
201
225
  */
202
- export function buildIntentDriftPrompt(baseBranch, traceFiles, outputPath) {
226
+ export function buildIntentDriftPrompt(baseBranch, traceFiles, outputPath, precomputedDiff) {
203
227
  if (traceFiles.length === 0)
204
228
  return null;
205
229
  const traceFileList = traceFiles.map(f => `- \`${f}\``).join('\n');
@@ -218,7 +242,7 @@ ${traceFileList}
218
242
  - The user's original instruction/prompt (the first message)
219
243
  - Any follow-up instructions or corrections from the user
220
244
 
221
- 3. Run \`git diff ${baseBranch}...HEAD\` to see what was actually implemented.
245
+ 3. ${precomputedDiff ? 'Review the diff below' : `Run \`git diff ${baseBranch}...HEAD\``} to see what was actually implemented.
222
246
 
223
247
  4. Compare the user's intent against the actual implementation. Look for:
224
248
 
@@ -262,5 +286,11 @@ ${INTENT_DRIFT_SCHEMA}
262
286
 
263
287
  - **error**: Core user intent violated — the main thing they asked for is wrong or missing
264
288
  - **warning**: Secondary requirement missed or approximated
265
- - **info**: Minor simplification that mostly still works as intended`;
289
+ - **info**: Minor simplification that mostly still works as intended${precomputedDiff ? `
290
+
291
+ ## Diff (precomputed)
292
+
293
+ \`\`\`diff
294
+ ${precomputedDiff}
295
+ \`\`\`` : ''}`;
266
296
  }
@@ -15,11 +15,11 @@ import { findRelevantTraces } from './traces.js';
15
15
  // ============================================================================
16
16
  const TRIAGE_DIR = '.haystack/triage';
17
17
  const TIMEOUT_MS = 300_000; // 5 minutes per checker
18
- /** Max agentic turns per checker */
18
+ /** Max agentic turns per checker — kept tight since these are read-only tasks */
19
19
  const MAX_TURNS = {
20
- 'code-review': 30,
21
- 'rules-validator': 30,
22
- 'intent-drift': 30,
20
+ 'code-review': 10,
21
+ 'rules-validator': 10,
22
+ 'intent-drift': 10,
23
23
  };
24
24
  // ============================================================================
25
25
  // Agent policy file discovery
@@ -232,13 +232,27 @@ export async function runTriage(gitRoot, baseBranch) {
232
232
  rmSync(triageDir, { recursive: true });
233
233
  }
234
234
  mkdirSync(triageDir, { recursive: true });
235
+ // Pre-compute the diff once so sub-agents don't waste turns running git diff.
236
+ // Includes 10 lines of context around each hunk for reviewability.
237
+ let precomputedDiff = null;
238
+ try {
239
+ const diffOutput = execSync(`git diff ${baseBranch}...HEAD -U10`, { cwd: gitRoot, encoding: 'utf-8', maxBuffer: 5 * 1024 * 1024 }).trim();
240
+ // Only inline if the diff is under 100K chars — beyond that, let the agent
241
+ // run git diff itself (it can paginate or review file-by-file).
242
+ if (diffOutput.length > 0 && diffOutput.length <= 100_000) {
243
+ precomputedDiff = diffOutput;
244
+ }
245
+ }
246
+ catch {
247
+ // git diff failed — agents will run it themselves
248
+ }
235
249
  // Build checker configs
236
250
  const checkers = [];
237
251
  // 1. Code review (always runs)
238
252
  const codeReviewOutput = join(triageDir, 'code-review.json');
239
253
  checkers.push({
240
254
  name: 'code-review',
241
- prompt: buildCodeReviewPrompt(baseBranch, codeReviewOutput),
255
+ prompt: buildCodeReviewPrompt(baseBranch, codeReviewOutput, precomputedDiff),
242
256
  outputFile: codeReviewOutput,
243
257
  maxTurns: MAX_TURNS['code-review'],
244
258
  });
@@ -249,7 +263,7 @@ export async function runTriage(gitRoot, baseBranch) {
249
263
  const agentPolicyFiles = discoverAgentPolicyFiles(gitRoot);
250
264
  if (hasRulesYaml || agentPolicyFiles.length > 0) {
251
265
  const rulesValidatorOutput = join(triageDir, 'rules-validator.json');
252
- const rulesPrompt = buildRulesValidatorPrompt(baseBranch, rulesYaml, rulesValidatorOutput, agentPolicyFiles);
266
+ const rulesPrompt = buildRulesValidatorPrompt(baseBranch, rulesYaml, rulesValidatorOutput, agentPolicyFiles, precomputedDiff);
253
267
  if (rulesPrompt) {
254
268
  checkers.push({
255
269
  name: 'rules-validator',
@@ -263,7 +277,7 @@ export async function runTriage(gitRoot, baseBranch) {
263
277
  const traceFiles = findRelevantTraces(gitRoot, baseBranch);
264
278
  if (traceFiles.length > 0) {
265
279
  const intentDriftOutput = join(triageDir, 'intent-drift.json');
266
- const driftPrompt = buildIntentDriftPrompt(baseBranch, traceFiles, intentDriftOutput);
280
+ const driftPrompt = buildIntentDriftPrompt(baseBranch, traceFiles, intentDriftOutput, precomputedDiff);
267
281
  if (driftPrompt) {
268
282
  checkers.push({
269
283
  name: 'intent-drift',
@@ -18,6 +18,8 @@ export interface PendingSubmit {
18
18
  status: 'polling' | 'completed' | 'failed' | 'stale';
19
19
  analysisResult?: AnalysisVerdict;
20
20
  resolvedAt?: string;
21
+ autoFix?: boolean;
22
+ autoFixStatus?: 'pending' | 'fixing' | 'fixed' | 'failed' | 'timed_out';
21
23
  }
22
24
  /**
23
25
  * Save pending submit state to disk.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@haystackeditor/cli",
3
- "version": "0.9.0",
4
- "description": "Set up Haystack verification for your project",
3
+ "version": "0.10.1",
4
+ "description": "Set up Haystack for your project — automated PR review, triage, and merge queue",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "haystack": "./dist/index.js"
@@ -14,10 +14,10 @@
14
14
  },
15
15
  "keywords": [
16
16
  "haystack",
17
- "verification",
18
- "sandbox",
17
+ "code-review",
19
18
  "ai-agent",
20
- "testing",
19
+ "pull-request",
20
+ "triage",
21
21
  "cli"
22
22
  ],
23
23
  "author": "Haystack",
@@ -32,18 +32,18 @@
32
32
  "url": "https://github.com/haystackeditor/haystack-review/issues"
33
33
  },
34
34
  "dependencies": {
35
- "chalk": "^5.3.0",
36
- "commander": "^12.0.0",
37
- "fast-glob": "^3.3.0",
38
- "glob": "^10.3.10",
39
- "inquirer": "^9.2.0",
40
- "yaml": "^2.3.4",
41
- "zod": "^3.22.4"
35
+ "chalk": "5.6.2",
36
+ "commander": "12.1.0",
37
+ "fast-glob": "3.3.3",
38
+ "glob": "10.5.0",
39
+ "inquirer": "9.3.8",
40
+ "yaml": "2.8.2",
41
+ "zod": "3.25.76"
42
42
  },
43
43
  "devDependencies": {
44
- "@types/inquirer": "^9.0.0",
45
- "@types/node": "^20.10.0",
46
- "typescript": "^5.3.0"
44
+ "@types/inquirer": "9.0.9",
45
+ "@types/node": "20.19.30",
46
+ "typescript": "5.9.3"
47
47
  },
48
48
  "files": [
49
49
  "dist"