@haystackeditor/cli 0.10.0 → 0.10.2
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 +117 -37
- package/dist/commands/config.d.ts +1 -5
- package/dist/commands/config.js +2 -56
- package/dist/commands/init.js +0 -30
- package/dist/commands/skills.js +3 -8
- package/dist/commands/status.js +0 -7
- package/dist/index.d.ts +3 -3
- package/dist/index.js +9 -61
- package/dist/types.d.ts +4 -4
- package/dist/types.js +4 -4
- package/dist/utils/secrets.js +1 -2
- package/package.json +5 -5
- package/dist/assets/skills/prepare-haystack.md +0 -323
- package/dist/assets/skills/secrets.md +0 -164
- package/dist/assets/skills/setup-external-sandbox.md +0 -243
- package/dist/assets/skills/setup-haystack.md +0 -639
- package/dist/assets/templates/CLAUDE.md.snippet +0 -42
- package/dist/assets/templates/haystack.yml +0 -193
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @haystackeditor/cli
|
|
2
2
|
|
|
3
|
-
Set up Haystack for your project. When PRs are opened, Haystack automatically
|
|
3
|
+
Set up Haystack for your project. When PRs are opened, Haystack automatically reviews them for bugs, intent drift, and rule violations — then routes them to the right place.
|
|
4
4
|
|
|
5
5
|
## Quick Start
|
|
6
6
|
|
|
@@ -63,33 +63,6 @@ This uses GitHub's device flow - you'll get a code to enter at github.com/login/
|
|
|
63
63
|
haystack logout
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
-
### `haystack secrets`
|
|
67
|
-
|
|
68
|
-
Manage secrets that will be injected into your sandbox environment:
|
|
69
|
-
|
|
70
|
-
```bash
|
|
71
|
-
# List all secrets (keys only, values are never shown)
|
|
72
|
-
haystack secrets list
|
|
73
|
-
|
|
74
|
-
# Set a secret
|
|
75
|
-
haystack secrets set OPENAI_API_KEY sk-xxx
|
|
76
|
-
|
|
77
|
-
# Delete a secret
|
|
78
|
-
haystack secrets delete OPENAI_API_KEY
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
Secrets are encrypted and stored securely. They're automatically injected as environment variables when the sandbox runs your app.
|
|
82
|
-
|
|
83
|
-
**Scopes**: By default, secrets are user-scoped. You can also scope to an org or repo:
|
|
84
|
-
|
|
85
|
-
```bash
|
|
86
|
-
# Org-scoped (available to all repos in the org)
|
|
87
|
-
haystack secrets set API_KEY xxx --scope org --scope-id myorg
|
|
88
|
-
|
|
89
|
-
# Repo-scoped (available only to this repo)
|
|
90
|
-
haystack secrets set API_KEY xxx --scope repo --scope-id owner/repo
|
|
91
|
-
```
|
|
92
|
-
|
|
93
66
|
### `haystack submit`
|
|
94
67
|
|
|
95
68
|
Create a PR from current changes. Runs pre-PR triage (code review, rules validation, intent drift), pushes your branch, and opens the PR.
|
|
@@ -136,6 +109,121 @@ haystack check-pending --json # Machine-readable JSON
|
|
|
136
109
|
haystack check-pending --clear # Clear pending state
|
|
137
110
|
```
|
|
138
111
|
|
|
112
|
+
### `haystack dismiss`
|
|
113
|
+
|
|
114
|
+
Dismiss analysis findings for a PR, moving it from "Issues Found" to "Good to Merge" in the feed. The override is tied to the PR's current HEAD commit.
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
haystack dismiss 42 # Dismiss findings for PR #42
|
|
118
|
+
haystack dismiss acme/widgets#99 # Dismiss for specific repo
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### `haystack undismiss`
|
|
122
|
+
|
|
123
|
+
Clear all overrides (dismissed findings and/or review-not-needed) for a PR, returning it to its original feed bucket.
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
haystack undismiss 42 # Undo overrides for PR #42
|
|
127
|
+
haystack undismiss acme/widgets#99 # Undo for specific repo
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### `haystack mark-reviewed`
|
|
131
|
+
|
|
132
|
+
Mark human review as not needed for a PR, moving it from "Needs Review" to "Good to Merge" in the feed. The override is tied to the PR's current HEAD commit.
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
haystack mark-reviewed 42 # Mark review not needed for PR #42
|
|
136
|
+
haystack mark-reviewed acme/widgets#99 # Mark for specific repo
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### `haystack pr-status`
|
|
140
|
+
|
|
141
|
+
Show what bucket a PR is in within the Haystack pipeline (analyzing, auto-fixing, good-to-merge, issues, needs-assignment, etc.):
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
haystack pr-status 42 # Current repo, PR #42
|
|
145
|
+
haystack pr-status acme/widgets#99 # Specific repo
|
|
146
|
+
haystack pr-status https://github.com/o/r/pull/1 # From URL
|
|
147
|
+
haystack pr-status 42 --json # Machine-readable output
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### `haystack config`
|
|
151
|
+
|
|
152
|
+
Manage user preferences:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
# Agentic tool selection
|
|
156
|
+
haystack config agentic-tool # Show current setting
|
|
157
|
+
haystack config agentic-tool opencode # Use Haystack billing (default)
|
|
158
|
+
haystack config agentic-tool claude-code # Use your Claude Max subscription
|
|
159
|
+
haystack config agentic-tool codex # Use your ChatGPT subscription
|
|
160
|
+
|
|
161
|
+
# Auto-merge for safe PRs
|
|
162
|
+
haystack config auto-merge # Show current status
|
|
163
|
+
haystack config auto-merge on # Enable auto-merge
|
|
164
|
+
haystack config auto-merge off # Disable auto-merge
|
|
165
|
+
|
|
166
|
+
# AI reviewer wait list
|
|
167
|
+
haystack config wait-for-reviewers # Show status
|
|
168
|
+
haystack config wait-for-reviewers add cursor # Wait for Cursor BugBot
|
|
169
|
+
haystack config wait-for-reviewers add cursor coderabbit # Add multiple
|
|
170
|
+
haystack config wait-for-reviewers remove cursor # Stop waiting
|
|
171
|
+
haystack config wait-for-reviewers clear # Wait for none
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### `haystack skills`
|
|
175
|
+
|
|
176
|
+
Manage AI skills for your coding CLI:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
haystack skills install # Auto-detect CLI and install
|
|
180
|
+
haystack skills install --cli codex # Install for Codex only
|
|
181
|
+
haystack skills install --cli manual # Show manual setup instructions
|
|
182
|
+
haystack skills list # List available skills
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### `haystack hooks`
|
|
186
|
+
|
|
187
|
+
Manage git hooks for AI agent quality checks:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# Install hooks + Entire CLI
|
|
191
|
+
haystack hooks install # Install with pinned Entire version
|
|
192
|
+
haystack hooks install --force # Overwrite existing hooks
|
|
193
|
+
haystack hooks install --skip-entire # Only install Haystack hooks
|
|
194
|
+
|
|
195
|
+
# Status and updates
|
|
196
|
+
haystack hooks status # Check installation status
|
|
197
|
+
haystack hooks update # Update Entire CLI to latest
|
|
198
|
+
|
|
199
|
+
# Session hooks (check-pending on CLI start)
|
|
200
|
+
haystack hooks install-session # Auto-detect CLIs
|
|
201
|
+
haystack hooks install-session --cli claude # Claude Code only
|
|
202
|
+
haystack hooks install-session --cli all # All detected CLIs
|
|
203
|
+
haystack hooks session-status # Check session hook status
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### `haystack policy`
|
|
207
|
+
|
|
208
|
+
Manage review policies (`.haystack/review-policy.md`):
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
# List and inspect
|
|
212
|
+
haystack policy list # List all policies
|
|
213
|
+
|
|
214
|
+
# Add policies
|
|
215
|
+
haystack policy add # Interactive add
|
|
216
|
+
haystack policy add "Database changes" # Start with name
|
|
217
|
+
haystack policy add-instruction "Never flag weak test coverage as needing review"
|
|
218
|
+
|
|
219
|
+
# Remove policies
|
|
220
|
+
haystack policy remove "Database changes"
|
|
221
|
+
|
|
222
|
+
# Initialize with defaults
|
|
223
|
+
haystack policy init # Create with sensible defaults
|
|
224
|
+
haystack policy init --force # Overwrite existing
|
|
225
|
+
```
|
|
226
|
+
|
|
139
227
|
---
|
|
140
228
|
|
|
141
229
|
## Configuration
|
|
@@ -145,15 +233,7 @@ The `setup` wizard writes `.haystack.json` to your repos with discovered rules,
|
|
|
145
233
|
```json
|
|
146
234
|
{
|
|
147
235
|
"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
|
-
}
|
|
236
|
+
"name": "my-app"
|
|
157
237
|
}
|
|
158
238
|
```
|
|
159
239
|
|
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Config commands - manage preferences
|
|
3
3
|
*
|
|
4
|
-
* Repo-level preferences (
|
|
4
|
+
* Repo-level preferences (auto_merge) are stored in .haystack.json.
|
|
5
5
|
* User-level preferences (agentic_tool) are stored on the Haystack Platform API.
|
|
6
6
|
*/
|
|
7
7
|
type AgenticTool = 'opencode' | 'claude-code' | 'codex';
|
|
8
|
-
export declare function getSandboxStatus(): Promise<void>;
|
|
9
|
-
export declare function enableSandbox(): Promise<void>;
|
|
10
|
-
export declare function disableSandbox(): Promise<void>;
|
|
11
|
-
export declare function handleSandbox(action?: string): Promise<void>;
|
|
12
8
|
export declare function getAgenticToolStatus(): Promise<void>;
|
|
13
9
|
export declare function setAgenticTool(tool: AgenticTool): Promise<void>;
|
|
14
10
|
export declare function handleAgenticTool(tool?: string): Promise<void>;
|
package/dist/commands/config.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Config commands - manage preferences
|
|
3
3
|
*
|
|
4
|
-
* Repo-level preferences (
|
|
4
|
+
* Repo-level preferences (auto_merge) are stored in .haystack.json.
|
|
5
5
|
* User-level preferences (agentic_tool) are stored on the Haystack Platform API.
|
|
6
6
|
*/
|
|
7
7
|
import chalk from 'chalk';
|
|
@@ -49,8 +49,7 @@ function saveHaystackConfig(config, configPath) {
|
|
|
49
49
|
}
|
|
50
50
|
function getPreference(key) {
|
|
51
51
|
const { config } = loadHaystackConfig();
|
|
52
|
-
|
|
53
|
-
const defaults = { sandbox_enabled: true, auto_merge: false };
|
|
52
|
+
const defaults = { auto_merge: false };
|
|
54
53
|
return config.preferences?.[key] ?? defaults[key];
|
|
55
54
|
}
|
|
56
55
|
function setPreference(key, value) {
|
|
@@ -84,59 +83,6 @@ async function apiRequest(method, token, body) {
|
|
|
84
83
|
});
|
|
85
84
|
}
|
|
86
85
|
// ============================================================================
|
|
87
|
-
// Sandbox (repo-level via .haystack.json)
|
|
88
|
-
// ============================================================================
|
|
89
|
-
export async function getSandboxStatus() {
|
|
90
|
-
const enabled = getPreference('sandbox_enabled');
|
|
91
|
-
console.log(chalk.bold('\nSandbox mode:'), enabled
|
|
92
|
-
? chalk.green('enabled')
|
|
93
|
-
: chalk.yellow('disabled'));
|
|
94
|
-
console.log();
|
|
95
|
-
if (enabled) {
|
|
96
|
-
console.log(chalk.dim('Haystack can clone and store your repos for verification.'));
|
|
97
|
-
console.log(chalk.dim('All data is deleted after 24 hours.'));
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
console.log(chalk.dim('Sandbox mode is disabled. Automated verification will not work.'));
|
|
101
|
-
console.log(chalk.dim('Enable with: haystack config sandbox on'));
|
|
102
|
-
}
|
|
103
|
-
console.log(chalk.dim('(Stored in .haystack.json — applies to all repo contributors)'));
|
|
104
|
-
console.log();
|
|
105
|
-
}
|
|
106
|
-
export async function enableSandbox() {
|
|
107
|
-
setPreference('sandbox_enabled', true);
|
|
108
|
-
console.log(chalk.green('\nSandbox mode enabled.\n'));
|
|
109
|
-
console.log(chalk.dim('Haystack can now clone and store your repos for verification.'));
|
|
110
|
-
console.log(chalk.dim('All data is deleted after 24 hours.'));
|
|
111
|
-
console.log(chalk.dim('Commit .haystack.json to share with your team.\n'));
|
|
112
|
-
}
|
|
113
|
-
export async function disableSandbox() {
|
|
114
|
-
setPreference('sandbox_enabled', false);
|
|
115
|
-
console.log(chalk.yellow('\nSandbox mode disabled.\n'));
|
|
116
|
-
console.log(chalk.dim('Automated verification will not work until you re-enable sandbox mode.'));
|
|
117
|
-
console.log(chalk.dim('Re-enable with: haystack config sandbox on'));
|
|
118
|
-
console.log(chalk.dim('Commit .haystack.json to share with your team.\n'));
|
|
119
|
-
}
|
|
120
|
-
export async function handleSandbox(action) {
|
|
121
|
-
switch (action?.toLowerCase()) {
|
|
122
|
-
case 'on':
|
|
123
|
-
case 'enable':
|
|
124
|
-
case 'true':
|
|
125
|
-
return enableSandbox();
|
|
126
|
-
case 'off':
|
|
127
|
-
case 'disable':
|
|
128
|
-
case 'false':
|
|
129
|
-
return disableSandbox();
|
|
130
|
-
case 'status':
|
|
131
|
-
case undefined:
|
|
132
|
-
return getSandboxStatus();
|
|
133
|
-
default:
|
|
134
|
-
console.error(chalk.red(`\nUnknown action: ${action}`));
|
|
135
|
-
console.log('\nUsage: haystack config sandbox [on|off|status]\n');
|
|
136
|
-
process.exit(1);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
// ============================================================================
|
|
140
86
|
// Agentic tool (user-level via API)
|
|
141
87
|
// ============================================================================
|
|
142
88
|
export async function getAgenticToolStatus() {
|
package/dist/commands/init.js
CHANGED
|
@@ -7,8 +7,6 @@ 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
|
-
// HIDDEN: Verification flow — uncomment to re-enable
|
|
11
|
-
// import { createSkillFile, createClaudeCommand } from '../utils/skill.js';
|
|
12
10
|
import { validateConfigSecurity, formatSecurityReport } from '../utils/secrets.js';
|
|
13
11
|
export async function initCommand(options) {
|
|
14
12
|
console.log(chalk.cyan('\n🌾 Haystack Setup\n'));
|
|
@@ -37,14 +35,6 @@ export async function initCommand(options) {
|
|
|
37
35
|
const config = buildConfigFromDetection(detected);
|
|
38
36
|
const configPath = await saveConfig(config);
|
|
39
37
|
console.log(chalk.green(`✓ Created ${configPath}`));
|
|
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}`));
|
|
48
38
|
// Security validation
|
|
49
39
|
await runSecurityCheck(configPath);
|
|
50
40
|
console.log(chalk.green('\nDone! Run `haystack setup` to configure rules, signals, and policies.\n'));
|
|
@@ -86,30 +76,10 @@ function buildConfigFromDetection(detected) {
|
|
|
86
76
|
version: '1',
|
|
87
77
|
name: path.basename(process.cwd()),
|
|
88
78
|
services,
|
|
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
|
-
// },
|
|
96
79
|
};
|
|
97
80
|
}
|
|
98
81
|
return {
|
|
99
82
|
version: '1',
|
|
100
83
|
name: path.basename(process.cwd()),
|
|
101
|
-
dev_server: {
|
|
102
|
-
command: detected.suggestedDevCommand || 'pnpm dev',
|
|
103
|
-
port: detected.suggestedPort || 3000,
|
|
104
|
-
ready_pattern: detected.suggestedReadyPattern || 'Local:',
|
|
105
|
-
...(Object.keys(env).length > 0 ? { env } : {}),
|
|
106
|
-
},
|
|
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
|
-
// },
|
|
114
84
|
};
|
|
115
85
|
}
|
package/dist/commands/skills.js
CHANGED
|
@@ -14,9 +14,6 @@ function getSkillsSourceDir() {
|
|
|
14
14
|
}
|
|
15
15
|
const SKILL_FILES = [
|
|
16
16
|
'setup-haystack.md',
|
|
17
|
-
'prepare-haystack.md',
|
|
18
|
-
'secrets.md',
|
|
19
|
-
'setup-external-sandbox.md',
|
|
20
17
|
'submit.md',
|
|
21
18
|
];
|
|
22
19
|
function installSkillFiles(targetDir) {
|
|
@@ -57,15 +54,14 @@ export async function installSkills(options) {
|
|
|
57
54
|
mkdirSync(claudeCommandsDir, { recursive: true });
|
|
58
55
|
}
|
|
59
56
|
const claudeCommandPath = join(claudeCommandsDir, 'setup-haystack.md');
|
|
60
|
-
writeFileSync(claudeCommandPath, '# Set Up Haystack
|
|
57
|
+
writeFileSync(claudeCommandPath, '# Set Up Haystack\n\nFollow .agents/skills/setup-haystack.md to set up Haystack for this repo.\n');
|
|
61
58
|
showSuccessMessage();
|
|
62
59
|
}
|
|
63
60
|
function showSuccessMessage() {
|
|
64
61
|
console.log(chalk.green('\n✅ Haystack skills installed!\n'));
|
|
65
62
|
console.log(chalk.white('Available skills:'));
|
|
66
63
|
console.log(chalk.cyan(' /setup-haystack ') + chalk.gray('- Create .haystack.json with AI assistance'));
|
|
67
|
-
console.log(chalk.cyan(' /
|
|
68
|
-
console.log(chalk.cyan(' /setup-haystack-secrets ') + chalk.gray('- Configure API keys and secrets'));
|
|
64
|
+
console.log(chalk.cyan(' /submit ') + chalk.gray('- Submit a PR via Haystack'));
|
|
69
65
|
console.log();
|
|
70
66
|
console.log(chalk.white('Run in your coding CLI:'));
|
|
71
67
|
console.log(chalk.cyan(' /setup-haystack'));
|
|
@@ -74,7 +70,6 @@ function showSuccessMessage() {
|
|
|
74
70
|
export async function listSkills() {
|
|
75
71
|
console.log(chalk.white('\nAvailable Haystack skills:\n'));
|
|
76
72
|
console.log(chalk.cyan(' /setup-haystack ') + chalk.gray('- Master setup - creates .haystack.json'));
|
|
77
|
-
console.log(chalk.cyan(' /
|
|
78
|
-
console.log(chalk.cyan(' /setup-haystack-secrets ') + chalk.gray('- Configure secrets for sandboxes'));
|
|
73
|
+
console.log(chalk.cyan(' /submit ') + chalk.gray('- Submit a PR via Haystack'));
|
|
79
74
|
console.log();
|
|
80
75
|
}
|
package/dist/commands/status.js
CHANGED
|
@@ -22,17 +22,10 @@ export async function statusCommand() {
|
|
|
22
22
|
if (config.name) {
|
|
23
23
|
console.log(` ${chalk.dim('Name:')} ${config.name}`);
|
|
24
24
|
}
|
|
25
|
-
if (config.dev_server) {
|
|
26
|
-
console.log(` ${chalk.dim('Dev server:')} ${config.dev_server.command} (port ${config.dev_server.port})`);
|
|
27
|
-
}
|
|
28
25
|
if (config.services) {
|
|
29
26
|
const serviceNames = Object.keys(config.services);
|
|
30
27
|
console.log(` ${chalk.dim('Services:')} ${serviceNames.join(', ')}`);
|
|
31
28
|
}
|
|
32
|
-
if (config.verification?.commands?.length) {
|
|
33
|
-
const cmdNames = config.verification.commands.map((c) => c.name);
|
|
34
|
-
console.log(` ${chalk.dim('Verification:')} ${cmdNames.join(', ')}`);
|
|
35
|
-
}
|
|
36
29
|
console.log('');
|
|
37
30
|
}
|
|
38
31
|
catch (e) {
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Haystack CLI
|
|
4
4
|
*
|
|
5
|
-
* Set up your project for Haystack
|
|
6
|
-
*
|
|
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
|
|
@@ -16,6 +16,6 @@
|
|
|
16
16
|
* npx @haystackeditor/cli dismiss 123 # Dismiss findings for a PR
|
|
17
17
|
* npx @haystackeditor/cli mark-reviewed 123 # Mark review as not needed
|
|
18
18
|
* npx @haystackeditor/cli pr-status 123 # Show PR status in Haystack pipeline
|
|
19
|
-
* npx @haystackeditor/cli
|
|
19
|
+
* npx @haystackeditor/cli config # Manage preferences
|
|
20
20
|
*/
|
|
21
21
|
export {};
|
package/dist/index.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Haystack CLI
|
|
4
4
|
*
|
|
5
|
-
* Set up your project for Haystack
|
|
6
|
-
*
|
|
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
|
|
@@ -16,14 +16,13 @@
|
|
|
16
16
|
* npx @haystackeditor/cli dismiss 123 # Dismiss findings for a PR
|
|
17
17
|
* npx @haystackeditor/cli mark-reviewed 123 # Mark review as not needed
|
|
18
18
|
* npx @haystackeditor/cli pr-status 123 # Show PR status in Haystack pipeline
|
|
19
|
-
* npx @haystackeditor/cli
|
|
19
|
+
* npx @haystackeditor/cli config # Manage preferences
|
|
20
20
|
*/
|
|
21
21
|
import { Command } from 'commander';
|
|
22
22
|
import { statusCommand } from './commands/status.js';
|
|
23
23
|
import { initCommand } from './commands/init.js';
|
|
24
24
|
import { loginCommand, logoutCommand } from './commands/login.js';
|
|
25
|
-
import {
|
|
26
|
-
import { handleSandbox, handleAgenticTool, handleAutoMerge, handleWaitForReviewers } from './commands/config.js';
|
|
25
|
+
import { handleAgenticTool, handleAutoMerge, handleWaitForReviewers } from './commands/config.js';
|
|
27
26
|
import { installSkills, listSkills } from './commands/skills.js';
|
|
28
27
|
import { hooksInstall, hooksStatus, hooksUpdate } from './commands/hooks.js';
|
|
29
28
|
import { submitCommand } from './commands/submit.js';
|
|
@@ -37,8 +36,8 @@ import { setupCommand } from './commands/setup.js';
|
|
|
37
36
|
const program = new Command();
|
|
38
37
|
program
|
|
39
38
|
.name('haystack')
|
|
40
|
-
.description('
|
|
41
|
-
.version('0.
|
|
39
|
+
.description('Haystack CLI — automated PR review, triage, and merge queue')
|
|
40
|
+
.version('0.10.2');
|
|
42
41
|
program
|
|
43
42
|
.command('init')
|
|
44
43
|
.description('Create .haystack.json configuration')
|
|
@@ -47,7 +46,7 @@ program
|
|
|
47
46
|
This creates a .haystack.json file with auto-detected settings:
|
|
48
47
|
• Dev server command and port
|
|
49
48
|
• Services (for monorepos)
|
|
50
|
-
• Auth bypass for
|
|
49
|
+
• Auth bypass for CI environments
|
|
51
50
|
|
|
52
51
|
After running, use \`haystack setup\` to scan your repos for rules,
|
|
53
52
|
CI signals, and review policies.
|
|
@@ -94,7 +93,7 @@ program
|
|
|
94
93
|
.option('--draft', 'Create as draft PR')
|
|
95
94
|
.option('--review [reviewer]', 'Request human review (BLOCKS auto-merge — only use when explicitly asked)')
|
|
96
95
|
.option('--force', 'Skip pre-PR triage checks')
|
|
97
|
-
.option('--auto-fix', 'Auto-fix analysis issues
|
|
96
|
+
.option('--auto-fix', 'Auto-fix analysis issues before surfacing to Feed')
|
|
98
97
|
.option('--no-wait', 'Skip waiting for analysis results')
|
|
99
98
|
.addHelpText('after', `
|
|
100
99
|
This command is designed for AI coding agents to submit PRs.
|
|
@@ -269,59 +268,10 @@ Examples:
|
|
|
269
268
|
haystack pr-status 42 --json # Machine-readable output
|
|
270
269
|
`)
|
|
271
270
|
.action(prStatusCommand);
|
|
272
|
-
// Secrets subcommands
|
|
273
|
-
const secrets = program
|
|
274
|
-
.command('secrets')
|
|
275
|
-
.description('Manage secrets for sandbox environments');
|
|
276
|
-
secrets
|
|
277
|
-
.command('list')
|
|
278
|
-
.description('List all secrets (keys only)')
|
|
279
|
-
.action(listSecrets);
|
|
280
|
-
secrets
|
|
281
|
-
.command('set <key> <value>')
|
|
282
|
-
.description('Set a secret')
|
|
283
|
-
.option('--scope <scope>', 'Scope: user, org, or repo (default: user)')
|
|
284
|
-
.option('--scope-id <id>', 'Scope ID (org name or owner/repo)')
|
|
285
|
-
.action((key, value, options) => {
|
|
286
|
-
setSecret(key, value, options);
|
|
287
|
-
});
|
|
288
|
-
secrets
|
|
289
|
-
.command('get <key>')
|
|
290
|
-
.description('Get a secret value')
|
|
291
|
-
.option('-q, --quiet', 'Output only the value (for piping)')
|
|
292
|
-
.action((key, options) => {
|
|
293
|
-
getSecret(key, options);
|
|
294
|
-
});
|
|
295
|
-
secrets
|
|
296
|
-
.command('get-for-repo <keys...>')
|
|
297
|
-
.description('Get multiple secrets needed by a repo')
|
|
298
|
-
.option('--json', 'Output as JSON')
|
|
299
|
-
.action((keys, options) => {
|
|
300
|
-
getSecretsForRepo(keys, options);
|
|
301
|
-
});
|
|
302
|
-
secrets
|
|
303
|
-
.command('delete <key>')
|
|
304
|
-
.description('Delete a secret')
|
|
305
|
-
.action(deleteSecret);
|
|
306
271
|
// Config subcommands
|
|
307
272
|
const config = program
|
|
308
273
|
.command('config')
|
|
309
274
|
.description('Manage user preferences');
|
|
310
|
-
config
|
|
311
|
-
.command('sandbox [action]')
|
|
312
|
-
.description('Manage sandbox mode (on|off|status)')
|
|
313
|
-
.addHelpText('after', `
|
|
314
|
-
Actions:
|
|
315
|
-
on, enable Enable sandbox mode (allow repo cloning)
|
|
316
|
-
off, disable Disable sandbox mode
|
|
317
|
-
status Show current status (default)
|
|
318
|
-
|
|
319
|
-
Examples:
|
|
320
|
-
haystack config sandbox # Show current status
|
|
321
|
-
haystack config sandbox on # Enable sandbox mode
|
|
322
|
-
haystack config sandbox off # Disable sandbox mode
|
|
323
|
-
`)
|
|
324
|
-
.action(handleSandbox);
|
|
325
275
|
config
|
|
326
276
|
.command('agentic-tool [tool]')
|
|
327
277
|
.description('Set agentic tool (opencode|claude-code|codex|status)')
|
|
@@ -399,9 +349,7 @@ skills
|
|
|
399
349
|
.addHelpText('after', `
|
|
400
350
|
This registers the Haystack MCP server with your coding CLI, enabling:
|
|
401
351
|
/setup-haystack - AI-assisted project setup
|
|
402
|
-
/
|
|
403
|
-
/setup-haystack-secrets - Configure secrets
|
|
404
|
-
|
|
352
|
+
/submit - Submit a PR via Haystack
|
|
405
353
|
Supported CLIs:
|
|
406
354
|
claude Claude Code (auto-detected)
|
|
407
355
|
codex Codex CLI (auto-detected)
|
package/dist/types.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Haystack CLI Types
|
|
3
3
|
*
|
|
4
4
|
* Zod schemas for .haystack.json configuration + CLI-only types.
|
|
5
|
-
*
|
|
5
|
+
* Zod schemas for .haystack.json configuration.
|
|
6
6
|
*/
|
|
7
7
|
import { z } from 'zod';
|
|
8
8
|
declare const VerificationCommandSchema: z.ZodObject<{
|
|
@@ -711,7 +711,7 @@ export declare const HaystackConfigSchema: z.ZodObject<{
|
|
|
711
711
|
root?: string | undefined;
|
|
712
712
|
depends_on?: string[] | undefined;
|
|
713
713
|
}>>>;
|
|
714
|
-
/** Verification configuration */
|
|
714
|
+
/** Verification configuration (legacy) */
|
|
715
715
|
verification: z.ZodOptional<z.ZodObject<{
|
|
716
716
|
/** Commands to run for verification (build, lint, test, etc.) */
|
|
717
717
|
commands: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -764,7 +764,7 @@ export declare const HaystackConfigSchema: z.ZodObject<{
|
|
|
764
764
|
cookies?: string | undefined;
|
|
765
765
|
}> | undefined;
|
|
766
766
|
}>>;
|
|
767
|
-
/** Auth configuration
|
|
767
|
+
/** Auth configuration (legacy) */
|
|
768
768
|
auth: z.ZodOptional<z.ZodObject<{
|
|
769
769
|
strategy: z.ZodDefault<z.ZodEnum<["bypass", "fixture", "token", "test_account"]>>;
|
|
770
770
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
@@ -944,7 +944,7 @@ export declare const HaystackConfigSchema: z.ZodObject<{
|
|
|
944
944
|
}, {
|
|
945
945
|
tool?: "opencode" | "claude-code" | "codex" | undefined;
|
|
946
946
|
}>>;
|
|
947
|
-
/** Database configuration
|
|
947
|
+
/** Database configuration (legacy) */
|
|
948
948
|
database: z.ZodOptional<z.ZodObject<{
|
|
949
949
|
strategy: z.ZodDefault<z.ZodEnum<["fixture", "memory", "seed", "docker", "remote"]>>;
|
|
950
950
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
package/dist/types.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Haystack CLI Types
|
|
3
3
|
*
|
|
4
4
|
* Zod schemas for .haystack.json configuration + CLI-only types.
|
|
5
|
-
*
|
|
5
|
+
* Zod schemas for .haystack.json configuration.
|
|
6
6
|
*/
|
|
7
7
|
import { z } from 'zod';
|
|
8
8
|
// =============================================================================
|
|
@@ -241,13 +241,13 @@ export const HaystackConfigSchema = z.object({
|
|
|
241
241
|
dev_server: DevServerSchema.optional(),
|
|
242
242
|
/** Multiple services (for monorepos) */
|
|
243
243
|
services: z.record(z.string(), ServiceSchema).optional(),
|
|
244
|
-
/** Verification configuration */
|
|
244
|
+
/** Verification configuration (legacy) */
|
|
245
245
|
verification: VerificationSchema.optional(),
|
|
246
|
-
/** Auth configuration
|
|
246
|
+
/** Auth configuration (legacy) */
|
|
247
247
|
auth: AuthConfigSchema.optional(),
|
|
248
248
|
/** Agentic configuration (project-level override) */
|
|
249
249
|
agentic: AgenticSchema.optional(),
|
|
250
|
-
/** Database configuration
|
|
250
|
+
/** Database configuration (legacy) */
|
|
251
251
|
database: DatabaseConfigSchema.optional(),
|
|
252
252
|
/** Network egress configuration */
|
|
253
253
|
network: NetworkConfigSchema.optional(),
|
package/dist/utils/secrets.js
CHANGED
|
@@ -235,7 +235,6 @@ export function formatSecurityReport(findings) {
|
|
|
235
235
|
lines.push(` ${finding.description}`);
|
|
236
236
|
lines.push(` Matched: ${finding.match}\n`);
|
|
237
237
|
}
|
|
238
|
-
lines.push('Use $VARIABLE syntax to reference secrets
|
|
239
|
-
lines.push('Run `haystack secrets set KEY value` to store secrets securely.\n');
|
|
238
|
+
lines.push('Use $VARIABLE syntax to reference secrets instead of hardcoding values.\n');
|
|
240
239
|
return lines.join('\n');
|
|
241
240
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haystackeditor/cli",
|
|
3
|
-
"version": "0.10.
|
|
4
|
-
"description": "Set up Haystack
|
|
3
|
+
"version": "0.10.2",
|
|
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
|
-
"
|
|
18
|
-
"sandbox",
|
|
17
|
+
"code-review",
|
|
19
18
|
"ai-agent",
|
|
20
|
-
"
|
|
19
|
+
"pull-request",
|
|
20
|
+
"triage",
|
|
21
21
|
"cli"
|
|
22
22
|
],
|
|
23
23
|
"author": "Haystack",
|