@haystackeditor/cli 0.9.0 → 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.
package/README.md CHANGED
@@ -1,68 +1,43 @@
1
1
  # @haystackeditor/cli
2
2
 
3
- Set up Haystack verification for your project. When PRs are opened, an AI agent spins up your app in a sandbox and verifies changes work correctly.
3
+ Set up Haystack for your project. When PRs are opened, Haystack automatically analyzes them for bugs, intent drift, and rule violations.
4
4
 
5
5
  ## Quick Start
6
6
 
7
- ### Fastest: AI-Assisted Setup
8
-
9
- ```bash
10
- npx @haystackeditor/cli skills install
11
- ```
12
-
13
- This auto-detects your coding CLI (Claude Code, Codex, Cursor) and installs the Haystack MCP server.
14
-
15
- Then invoke the setup in your coding CLI:
16
-
17
- | CLI | How to invoke |
18
- |-----|---------------|
19
- | **Claude Code** | `/setup-haystack` |
20
- | **Codex CLI** | `/setup-haystack` or ask "set up haystack verification" |
21
- | **Cursor** | `/setup-haystack` (in Composer) |
22
-
23
- The AI will analyze your codebase, create `.haystack.json`, and configure verification flows.
24
-
25
- ### Alternative: Direct CLI Setup
26
-
27
- For quick setup without AI assistance:
28
-
29
7
  ```bash
30
- npx @haystackeditor/cli init
8
+ npm install -g @haystackeditor/cli
9
+ haystack login
10
+ haystack setup
31
11
  ```
32
12
 
33
- This runs an interactive wizard that auto-detects your project and creates `.haystack.json`.
13
+ The `setup` command walks you through an interactive wizard:
34
14
 
35
- ### Additional Skills
36
-
37
- | Skill | Purpose |
38
- |-------|---------|
39
- | `/setup-haystack` | **Start here** - diagnoses project, creates config |
40
- | `/prepare-haystack` | Add aria-labels and data-testid for browser automation |
41
- | `/setup-haystack-secrets` | Configure API keys, LLM credentials, secrets |
15
+ 1. **Select repositories** to configure
16
+ 2. **Scan for coding rules** (conventions your team follows)
17
+ 3. **Scan for CI/bot signals** (checks to wait for before merging)
18
+ 4. **Scan for review policies** (who should review what)
19
+ 5. **Review and toggle** discovered items
20
+ 6. **Write `.haystack.json`** to your repos
42
21
 
43
22
  ---
44
23
 
45
24
  ## CLI Commands
46
25
 
47
- All commands can be run directly:
48
-
49
- ### `haystack skills`
26
+ ### `haystack setup`
50
27
 
51
- Install AI skills into your coding CLI (auto-detects Claude Code, Codex, Cursor):
28
+ Interactive onboarding wizard scan your repos and generate `.haystack.json`:
52
29
 
53
30
  ```bash
54
- npx @haystackeditor/cli skills install # Auto-detect CLI
55
- npx @haystackeditor/cli skills install --cli codex # Install for Codex
56
- npx @haystackeditor/cli skills install --cli cursor # Install for Cursor
57
- npx @haystackeditor/cli skills install --cli manual # Show manual setup
58
- npx @haystackeditor/cli skills list # List available skills
31
+ haystack setup
59
32
  ```
60
33
 
61
34
  ### `haystack init`
62
35
 
36
+ Quick local setup — auto-detects your project and creates `.haystack.json` without scanning:
37
+
63
38
  ```bash
64
- npx @haystackeditor/cli init # Interactive wizard
65
- npx @haystackeditor/cli init -y # Accept all defaults
39
+ haystack init # Auto-detect and create config
40
+ haystack init --force # Overwrite existing .haystack.json
66
41
  ```
67
42
 
68
43
  ### `haystack status`
@@ -70,22 +45,22 @@ npx @haystackeditor/cli init -y # Accept all defaults
70
45
  Check if your project is configured:
71
46
 
72
47
  ```bash
73
- npx @haystackeditor/cli status
48
+ haystack status
74
49
  ```
75
50
 
76
51
  ### `haystack login`
77
52
 
78
- Authenticate with GitHub (required for secrets management):
53
+ Authenticate with GitHub (required for setup and secrets):
79
54
 
80
55
  ```bash
81
- npx @haystackeditor/cli login
56
+ haystack login
82
57
  ```
83
58
 
84
59
  This uses GitHub's device flow - you'll get a code to enter at github.com/login/device.
85
60
 
86
61
  ```bash
87
62
  # Log out (removes stored credentials)
88
- npx @haystackeditor/cli logout
63
+ haystack logout
89
64
  ```
90
65
 
91
66
  ### `haystack secrets`
@@ -94,13 +69,13 @@ Manage secrets that will be injected into your sandbox environment:
94
69
 
95
70
  ```bash
96
71
  # List all secrets (keys only, values are never shown)
97
- npx @haystackeditor/cli secrets list
72
+ haystack secrets list
98
73
 
99
74
  # Set a secret
100
- npx @haystackeditor/cli secrets set OPENAI_API_KEY sk-xxx
75
+ haystack secrets set OPENAI_API_KEY sk-xxx
101
76
 
102
77
  # Delete a secret
103
- npx @haystackeditor/cli secrets delete OPENAI_API_KEY
78
+ haystack secrets delete OPENAI_API_KEY
104
79
  ```
105
80
 
106
81
  Secrets are encrypted and stored securely. They're automatically injected as environment variables when the sandbox runs your app.
@@ -109,10 +84,10 @@ Secrets are encrypted and stored securely. They're automatically injected as env
109
84
 
110
85
  ```bash
111
86
  # Org-scoped (available to all repos in the org)
112
- npx @haystackeditor/cli secrets set API_KEY xxx --scope org --scope-id myorg
87
+ haystack secrets set API_KEY xxx --scope org --scope-id myorg
113
88
 
114
89
  # Repo-scoped (available only to this repo)
115
- npx @haystackeditor/cli secrets set API_KEY xxx --scope repo --scope-id owner/repo
90
+ haystack secrets set API_KEY xxx --scope repo --scope-id owner/repo
116
91
  ```
117
92
 
118
93
  ### `haystack submit`
@@ -120,14 +95,14 @@ npx @haystackeditor/cli secrets set API_KEY xxx --scope repo --scope-id owner/re
120
95
  Create a PR from current changes. Runs pre-PR triage (code review, rules validation, intent drift), pushes your branch, and opens the PR.
121
96
 
122
97
  ```bash
123
- haystack submit # Triage create PR wait for analysis
98
+ haystack submit # Triage -> create PR -> wait for analysis
124
99
  haystack submit --title "Fix auth" # Custom PR title
125
100
  haystack submit --draft # Create as draft PR
126
101
  haystack submit --force # Skip triage checks
127
102
  haystack submit --no-wait # Don't wait for analysis results
128
103
  ```
129
104
 
130
- **Review routing**: By default, PRs go to the auto-merge queue if analysis passes, the PR is merged automatically. Use `--review` to route it for human review instead:
105
+ **Review routing**: By default, PRs go to the auto-merge queue -- if analysis passes, the PR is merged automatically. Use `--review` to route it for human review instead:
131
106
 
132
107
  ```bash
133
108
  haystack submit --review # Needs review (goes to assignment queue)
@@ -148,7 +123,7 @@ haystack triage 42 --json # Machine-readable JSON output
148
123
  haystack triage 42 --no-wait # Don't wait if analysis is pending
149
124
  ```
150
125
 
151
- The `--json` output includes `agentFixPrompt` fields ready-to-paste instructions for coding agents to fix each finding.
126
+ The `--json` output includes `agentFixPrompt` fields -- ready-to-paste instructions for coding agents to fix each finding.
152
127
 
153
128
  ### `haystack check-pending`
154
129
 
@@ -165,49 +140,34 @@ haystack check-pending --clear # Clear pending state
165
140
 
166
141
  ## Configuration
167
142
 
168
- The `init` command creates `.haystack.json`:
169
-
170
- ```yaml
171
- version: "1"
172
- name: my-app
173
-
174
- dev_server:
175
- command: pnpm dev
176
- port: 3000
177
- ready_pattern: "Local:"
178
- env:
179
- SKIP_AUTH: "true"
180
-
181
- verification:
182
- commands:
183
- - name: build
184
- run: pnpm build
185
- - name: lint
186
- run: pnpm lint
143
+ The `setup` wizard writes `.haystack.json` to your repos with discovered rules, signals, and policies. You can also create a base config locally with `haystack init`:
144
+
145
+ ```json
146
+ {
147
+ "version": "1",
148
+ "name": "my-app",
149
+ "dev_server": {
150
+ "command": "pnpm dev",
151
+ "port": 3000,
152
+ "ready_pattern": "Local:",
153
+ "env": {
154
+ "SKIP_AUTH": "true"
155
+ }
156
+ }
157
+ }
187
158
  ```
188
159
 
189
- ### Customizing After Init
190
-
191
- | If your app has... | Add this |
192
- |-------------------|----------|
193
- | Login/authentication | Auth bypass env var in `dev_server.env` |
194
- | Key user journeys | Flows describing what to verify |
195
- | API calls needing auth | Fixtures to mock responses |
196
-
197
- Use `/setup-haystack` in Claude Code for AI-assisted configuration of flows and fixtures.
198
-
199
160
  ---
200
161
 
201
162
  ## How It Works
202
163
 
203
- 1. Run `npx @haystackeditor/cli init` or use `/setup-haystack` in Claude Code
204
- 2. Commit the generated `.haystack.json`
205
- 3. Install the [Haystack GitHub App](https://haystackeditor.com/github-app)
206
- 4. When PRs are opened, Haystack's AI agent:
207
- - Spins up your app in a cloud sandbox
208
- - Runs verification commands
209
- - Captures screenshots and evidence
164
+ 1. Run `haystack setup` to configure your repos (or `haystack init` for local-only config)
165
+ 2. Install the [Haystack GitHub App](https://haystackeditor.com/github-app)
166
+ 3. When PRs are opened, Haystack automatically:
167
+ - Analyzes the code for bugs, intent drift, and rule violations
210
168
  - Reports results on the PR
169
+ - Routes the PR to the right inbox tab (Good to Merge, Issues Found, etc.)
170
+ - If auto-merge is enabled, clean PRs merge automatically
211
171
 
212
172
  ## License
213
173
 
@@ -5,7 +5,7 @@
5
5
  "type": "module",
6
6
  "description": "Git hooks for AI agent quality checks (installed by @haystackeditor/cli)",
7
7
  "dependencies": {
8
- "tree-sitter": "^0.22.4",
9
- "tree-sitter-typescript": "^0.23.2"
8
+ "tree-sitter": "0.22.4",
9
+ "tree-sitter-typescript": "0.23.2"
10
10
  }
11
11
  }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * dismiss & mark-reviewed commands — User overrides for PR findings.
3
+ *
4
+ * haystack dismiss <pr> — Dismiss analysis findings for a PR
5
+ * haystack mark-reviewed <pr> — Mark human review as not needed for a PR
6
+ *
7
+ * Each posts a user override to the Haystack API so the PR moves toward
8
+ * "Good to Merge" in the feed.
9
+ *
10
+ * Accepts a PR identifier in several formats:
11
+ * 123 # Uses current repo's owner/repo
12
+ * owner/repo#123 # Fully qualified
13
+ * https://github.com/owner/repo/pull/123 # GitHub URL
14
+ */
15
+ export declare function dismissCommand(identifier: string): Promise<void>;
16
+ export declare function markReviewedCommand(identifier: string): Promise<void>;
17
+ export declare function undismissCommand(identifier: string): Promise<void>;
@@ -0,0 +1,201 @@
1
+ /**
2
+ * dismiss & mark-reviewed commands — User overrides for PR findings.
3
+ *
4
+ * haystack dismiss <pr> — Dismiss analysis findings for a PR
5
+ * haystack mark-reviewed <pr> — Mark human review as not needed for a PR
6
+ *
7
+ * Each posts a user override to the Haystack API so the PR moves toward
8
+ * "Good to Merge" in the feed.
9
+ *
10
+ * Accepts a PR identifier in several formats:
11
+ * 123 # Uses current repo's owner/repo
12
+ * owner/repo#123 # Fully qualified
13
+ * https://github.com/owner/repo/pull/123 # GitHub URL
14
+ */
15
+ import chalk from 'chalk';
16
+ import { loadToken } from './login.js';
17
+ import { parseRemoteUrl } from '../utils/git.js';
18
+ // ============================================================================
19
+ // PR identifier parsing (shared with triage — duplicated to avoid circular deps)
20
+ // ============================================================================
21
+ function parsePRIdentifier(identifier, commandName) {
22
+ const urlMatch = identifier.match(/^https?:\/\/github\.com\/([^/]+)\/([^/]+)\/pull\/(\d+)\/?$/);
23
+ if (urlMatch) {
24
+ return { owner: urlMatch[1], repo: urlMatch[2], prNumber: parseInt(urlMatch[3], 10) };
25
+ }
26
+ const qualifiedMatch = identifier.match(/^([^/]+)\/([^#]+)#(\d+)$/);
27
+ if (qualifiedMatch) {
28
+ return { owner: qualifiedMatch[1], repo: qualifiedMatch[2], prNumber: parseInt(qualifiedMatch[3], 10) };
29
+ }
30
+ const numberMatch = identifier.match(/^#?(\d+)$/);
31
+ if (numberMatch) {
32
+ const prNumber = parseInt(numberMatch[1], 10);
33
+ try {
34
+ const remote = parseRemoteUrl('origin');
35
+ return { owner: remote.owner, repo: remote.repo, prNumber };
36
+ }
37
+ catch {
38
+ throw new Error(`Cannot determine repository for PR #${prNumber}.\n` +
39
+ `Use the full format: haystack ${commandName} owner/repo#${prNumber}`);
40
+ }
41
+ }
42
+ throw new Error(`Invalid PR identifier: "${identifier}"\n\n` +
43
+ `Accepted formats:\n` +
44
+ ` haystack ${commandName} 123\n` +
45
+ ` haystack ${commandName} owner/repo#123\n` +
46
+ ` haystack ${commandName} https://github.com/owner/repo/pull/123`);
47
+ }
48
+ // ============================================================================
49
+ // GitHub API helpers
50
+ // ============================================================================
51
+ async function getPRHeadSha(owner, repo, prNumber, token) {
52
+ const response = await fetch(`https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}`, {
53
+ headers: {
54
+ Authorization: `Bearer ${token}`,
55
+ Accept: 'application/vnd.github.v3+json',
56
+ 'User-Agent': 'Haystack-CLI',
57
+ },
58
+ });
59
+ if (!response.ok) {
60
+ if (response.status === 404) {
61
+ throw new Error(`PR #${prNumber} not found in ${owner}/${repo}`);
62
+ }
63
+ throw new Error(`Failed to fetch PR: HTTP ${response.status}`);
64
+ }
65
+ const data = await response.json();
66
+ return data.head.sha;
67
+ }
68
+ // ============================================================================
69
+ // User override API
70
+ // ============================================================================
71
+ const HAYSTACK_API = 'https://haystackeditor.com';
72
+ async function postUserOverride(repoFullName, prNumber, commitSha, type, token) {
73
+ const response = await fetch(`${HAYSTACK_API}/api/user-override`, {
74
+ method: 'POST',
75
+ headers: {
76
+ Authorization: `Bearer ${token}`,
77
+ 'Content-Type': 'application/json',
78
+ 'User-Agent': 'Haystack-CLI',
79
+ },
80
+ body: JSON.stringify({ repoFullName, prNumber, commitSha, type }),
81
+ });
82
+ if (!response.ok) {
83
+ const body = await response.text().catch(() => '');
84
+ if (response.status === 401) {
85
+ throw new Error('Authentication failed. Run `haystack login` to re-authenticate.');
86
+ }
87
+ if (response.status === 403) {
88
+ throw new Error('Access denied — you may not have permission to this repository.');
89
+ }
90
+ throw new Error(`API error (${response.status}): ${body}`);
91
+ }
92
+ }
93
+ async function deleteUserOverrides(repoFullName, prNumber, token) {
94
+ const response = await fetch(`${HAYSTACK_API}/api/user-override`, {
95
+ method: 'DELETE',
96
+ headers: {
97
+ Authorization: `Bearer ${token}`,
98
+ 'Content-Type': 'application/json',
99
+ 'User-Agent': 'Haystack-CLI',
100
+ },
101
+ body: JSON.stringify({ repoFullName, prNumber }),
102
+ });
103
+ if (!response.ok) {
104
+ const body = await response.text().catch(() => '');
105
+ if (response.status === 401) {
106
+ throw new Error('Authentication failed. Run `haystack login` to re-authenticate.');
107
+ }
108
+ if (response.status === 403) {
109
+ throw new Error('Access denied — you may not have permission to this repository.');
110
+ }
111
+ throw new Error(`API error (${response.status}): ${body}`);
112
+ }
113
+ }
114
+ // ============================================================================
115
+ // Shared runner
116
+ // ============================================================================
117
+ async function runOverride(identifier, type, commandName) {
118
+ // Parse PR identifier
119
+ let pr;
120
+ try {
121
+ pr = parsePRIdentifier(identifier, commandName);
122
+ }
123
+ catch (err) {
124
+ console.error(chalk.red(`\n${err.message}\n`));
125
+ process.exit(1);
126
+ }
127
+ // Require auth
128
+ const token = await loadToken();
129
+ if (!token) {
130
+ console.error(chalk.red('\nNot logged in. Run `haystack login` first.\n'));
131
+ process.exit(1);
132
+ }
133
+ const prLabel = `${pr.owner}/${pr.repo}#${pr.prNumber}`;
134
+ const repoFullName = `${pr.owner}/${pr.repo}`;
135
+ const actionLabel = type === 'findings-dismissed'
136
+ ? 'Dismissing findings'
137
+ : 'Marking review as not needed';
138
+ console.log(chalk.dim(`\n${actionLabel} for ${prLabel}...`));
139
+ // Get PR HEAD SHA
140
+ let headSha;
141
+ try {
142
+ headSha = await getPRHeadSha(pr.owner, pr.repo, pr.prNumber, token);
143
+ }
144
+ catch (err) {
145
+ console.error(chalk.red(`\n${err.message}\n`));
146
+ process.exit(1);
147
+ }
148
+ // Post the override
149
+ try {
150
+ await postUserOverride(repoFullName, pr.prNumber, headSha, type, token);
151
+ }
152
+ catch (err) {
153
+ console.error(chalk.red(`\n${err.message}\n`));
154
+ process.exit(1);
155
+ }
156
+ // Success
157
+ if (type === 'findings-dismissed') {
158
+ console.log(chalk.green(`\n Findings dismissed for ${prLabel}`));
159
+ }
160
+ else {
161
+ console.log(chalk.green(`\n Review marked as not needed for ${prLabel}`));
162
+ }
163
+ console.log(chalk.dim(` Commit: ${headSha.slice(0, 7)}`));
164
+ console.log(chalk.dim(' The PR will move to "Good to Merge" in the feed.\n'));
165
+ }
166
+ // ============================================================================
167
+ // Exported commands
168
+ // ============================================================================
169
+ export async function dismissCommand(identifier) {
170
+ await runOverride(identifier, 'findings-dismissed', 'dismiss');
171
+ }
172
+ export async function markReviewedCommand(identifier) {
173
+ await runOverride(identifier, 'review-not-needed', 'mark-reviewed');
174
+ }
175
+ export async function undismissCommand(identifier) {
176
+ let pr;
177
+ try {
178
+ pr = parsePRIdentifier(identifier, 'undismiss');
179
+ }
180
+ catch (err) {
181
+ console.error(chalk.red(`\n${err.message}\n`));
182
+ process.exit(1);
183
+ }
184
+ const token = await loadToken();
185
+ if (!token) {
186
+ console.error(chalk.red('\nNot logged in. Run `haystack login` first.\n'));
187
+ process.exit(1);
188
+ }
189
+ const prLabel = `${pr.owner}/${pr.repo}#${pr.prNumber}`;
190
+ const repoFullName = `${pr.owner}/${pr.repo}`;
191
+ console.log(chalk.dim(`\nClearing overrides for ${prLabel}...`));
192
+ try {
193
+ await deleteUserOverrides(repoFullName, pr.prNumber, token);
194
+ }
195
+ catch (err) {
196
+ console.error(chalk.red(`\n${err.message}\n`));
197
+ process.exit(1);
198
+ }
199
+ console.log(chalk.green(`\n Overrides cleared for ${prLabel}`));
200
+ console.log(chalk.dim(' The PR will return to its original feed bucket.\n'));
201
+ }
@@ -7,7 +7,8 @@ import chalk from 'chalk';
7
7
  import * as path from 'path';
8
8
  import { detectProject } from '../utils/detect.js';
9
9
  import { saveConfig, configExists } from '../utils/config.js';
10
- import { createSkillFile, createClaudeCommand } from '../utils/skill.js';
10
+ // HIDDEN: Verification flow uncomment to re-enable
11
+ // import { createSkillFile, createClaudeCommand } from '../utils/skill.js';
11
12
  import { validateConfigSecurity, formatSecurityReport } from '../utils/secrets.js';
12
13
  export async function initCommand(options) {
13
14
  console.log(chalk.cyan('\n🌾 Haystack Setup\n'));
@@ -36,23 +37,17 @@ export async function initCommand(options) {
36
37
  const config = buildConfigFromDetection(detected);
37
38
  const configPath = await saveConfig(config);
38
39
  console.log(chalk.green(`✓ Created ${configPath}`));
39
- // Create skill file for agent discovery
40
- const skillPath = await createSkillFile();
41
- console.log(chalk.green(`✓ Created ${skillPath}`));
42
- // Create Claude Code slash command
43
- const commandPath = await createClaudeCommand();
44
- console.log(chalk.green(`✓ Created ${commandPath}`));
40
+ // HIDDEN: Verification flow uncomment to re-enable
41
+ // // Create skill file for agent discovery
42
+ // const skillPath = await createSkillFile();
43
+ // console.log(chalk.green(`✓ Created ${skillPath}`));
44
+ //
45
+ // // Create Claude Code slash command
46
+ // const commandPath = await createClaudeCommand();
47
+ // console.log(chalk.green(`✓ Created ${commandPath}`));
45
48
  // Security validation
46
49
  await runSecurityCheck(configPath);
47
- // Print next steps - direct to skill
48
- console.log(chalk.cyan('\n━'.repeat(60)));
49
- console.log(chalk.cyan.bold('\n📋 NEXT: Add verification flows\n'));
50
- console.log(chalk.white('Base config created. Now an AI agent needs to add flows.\n'));
51
- console.log(chalk.bold('Option 1: Claude Code'));
52
- console.log(chalk.dim(' Run /setup-haystack in Claude Code\n'));
53
- console.log(chalk.bold('Option 2: Other AI agents'));
54
- console.log(chalk.dim(' Give your agent: "Read .agents/skills/setup-haystack.md and follow it"\n'));
55
- console.log(chalk.cyan('━'.repeat(60) + '\n'));
50
+ console.log(chalk.green('\nDone! Run `haystack setup` to configure rules, signals, and policies.\n'));
56
51
  }
57
52
  /**
58
53
  * Run security check on config file
@@ -91,12 +86,13 @@ function buildConfigFromDetection(detected) {
91
86
  version: '1',
92
87
  name: path.basename(process.cwd()),
93
88
  services,
94
- verification: {
95
- commands: [
96
- { name: 'build', run: `${detected.packageManager} build` },
97
- { name: 'lint', run: `${detected.packageManager} lint` },
98
- ],
99
- },
89
+ // HIDDEN: Verification flow — uncomment to re-enable
90
+ // verification: {
91
+ // commands: [
92
+ // { name: 'build', run: `${detected.packageManager} build` },
93
+ // { name: 'lint', run: `${detected.packageManager} lint` },
94
+ // ],
95
+ // },
100
96
  };
101
97
  }
102
98
  return {
@@ -108,11 +104,12 @@ function buildConfigFromDetection(detected) {
108
104
  ready_pattern: detected.suggestedReadyPattern || 'Local:',
109
105
  ...(Object.keys(env).length > 0 ? { env } : {}),
110
106
  },
111
- verification: {
112
- commands: [
113
- { name: 'build', run: `${detected.packageManager} build` },
114
- { name: 'lint', run: `${detected.packageManager} lint` },
115
- ],
116
- },
107
+ // HIDDEN: Verification flow — uncomment to re-enable
108
+ // verification: {
109
+ // commands: [
110
+ // { name: 'build', run: `${detected.packageManager} build` },
111
+ // { name: 'lint', run: `${detected.packageManager} lint` },
112
+ // ],
113
+ // },
117
114
  };
118
115
  }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * pr-status command — Show the current Haystack status of a PR.
3
+ *
4
+ * Calls the classify-debug endpoint to determine which inbox bucket the PR
5
+ * is in (analyzing, auto-fixing, good-to-merge, issues, needs-assignment, etc.)
6
+ * and displays a human-readable summary.
7
+ *
8
+ * Accepts a PR identifier in several formats:
9
+ * 123 # Uses current repo's owner/repo
10
+ * owner/repo#123 # Fully qualified
11
+ * https://github.com/owner/repo/pull/123 # GitHub URL
12
+ */
13
+ export interface PRStatusOptions {
14
+ json?: boolean;
15
+ }
16
+ export declare function prStatusCommand(identifier: string, options: PRStatusOptions): Promise<void>;