@haystackeditor/cli 0.8.1 → 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 +93 -87
- package/dist/assets/hooks/llm-rules-template.md +21 -0
- package/dist/assets/hooks/package.json +2 -2
- package/dist/assets/hooks/scripts/pre-push.sh +20 -0
- package/dist/assets/skills/prepare-haystack.md +323 -0
- package/dist/assets/skills/secrets.md +164 -0
- package/dist/assets/skills/setup-external-sandbox.md +243 -0
- package/dist/assets/skills/setup-haystack.md +639 -0
- package/dist/assets/skills/submit.md +154 -0
- package/dist/assets/templates/CLAUDE.md.snippet +42 -0
- package/dist/assets/templates/haystack.yml +193 -0
- package/dist/commands/check-pending.d.ts +19 -0
- package/dist/commands/check-pending.js +217 -0
- package/dist/commands/config.d.ts +13 -21
- package/dist/commands/config.js +278 -92
- package/dist/commands/dismiss.d.ts +17 -0
- package/dist/commands/dismiss.js +201 -0
- package/dist/commands/init.js +25 -28
- package/dist/commands/install-session-hooks.d.ts +16 -0
- package/dist/commands/install-session-hooks.js +302 -0
- package/dist/commands/login.js +1 -1
- package/dist/commands/policy.d.ts +31 -0
- package/dist/commands/policy.js +365 -0
- package/dist/commands/pr-status.d.ts +16 -0
- package/dist/commands/pr-status.js +188 -0
- package/dist/commands/setup.d.ts +13 -0
- package/dist/commands/setup.js +496 -0
- package/dist/commands/skills.d.ts +2 -2
- package/dist/commands/skills.js +51 -186
- package/dist/commands/submit.d.ts +23 -0
- package/dist/commands/submit.js +456 -0
- package/dist/commands/triage.d.ts +16 -0
- package/dist/commands/triage.js +354 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +344 -4
- package/dist/tools/detect.d.ts +50 -0
- package/dist/tools/detect.js +853 -0
- package/dist/tools/fixtures.d.ts +38 -0
- package/dist/tools/fixtures.js +199 -0
- package/dist/tools/setup.d.ts +43 -0
- package/dist/tools/setup.js +597 -0
- package/dist/triage/prompts.d.ts +31 -0
- package/dist/triage/prompts.js +296 -0
- package/dist/triage/runner.d.ts +21 -0
- package/dist/triage/runner.js +339 -0
- package/dist/triage/traces.d.ts +20 -0
- package/dist/triage/traces.js +305 -0
- package/dist/triage/types.d.ts +47 -0
- package/dist/triage/types.js +7 -0
- package/dist/types.d.ts +1387 -191
- package/dist/types.js +254 -2
- package/dist/utils/analysis-api.d.ts +108 -0
- package/dist/utils/analysis-api.js +194 -0
- package/dist/utils/config.js +1 -1
- package/dist/utils/git.d.ts +80 -0
- package/dist/utils/git.js +302 -0
- package/dist/utils/github-api.d.ts +83 -0
- package/dist/utils/github-api.js +266 -0
- package/dist/utils/pending-state.d.ts +40 -0
- package/dist/utils/pending-state.js +86 -0
- package/dist/utils/secrets.js +3 -3
- package/dist/utils/skill.js +257 -0
- package/package.json +11 -9
package/dist/index.js
CHANGED
|
@@ -7,8 +7,15 @@
|
|
|
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
|
|
13
|
+
* npx @haystackeditor/cli submit # Create a PR (auto-merge or review)
|
|
14
|
+
* npx @haystackeditor/cli check-pending # Check analysis status
|
|
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
|
|
12
19
|
* npx @haystackeditor/cli secrets list # List stored secrets
|
|
13
20
|
*/
|
|
14
21
|
import { Command } from 'commander';
|
|
@@ -16,14 +23,22 @@ import { statusCommand } from './commands/status.js';
|
|
|
16
23
|
import { initCommand } from './commands/init.js';
|
|
17
24
|
import { loginCommand, logoutCommand } from './commands/login.js';
|
|
18
25
|
import { listSecrets, setSecret, getSecret, getSecretsForRepo, deleteSecret } from './commands/secrets.js';
|
|
19
|
-
import { handleSandbox, handleAgenticTool } from './commands/config.js';
|
|
26
|
+
import { handleSandbox, handleAgenticTool, handleAutoMerge, handleWaitForReviewers } from './commands/config.js';
|
|
20
27
|
import { installSkills, listSkills } from './commands/skills.js';
|
|
21
28
|
import { hooksInstall, hooksStatus, hooksUpdate } from './commands/hooks.js';
|
|
29
|
+
import { submitCommand } from './commands/submit.js';
|
|
30
|
+
import { checkPendingCommand } from './commands/check-pending.js';
|
|
31
|
+
import { installSessionHooks, sessionHooksStatus } from './commands/install-session-hooks.js';
|
|
32
|
+
import { listPolicies, addPolicy, removePolicy, initPolicies, addInstruction } from './commands/policy.js';
|
|
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';
|
|
22
37
|
const program = new Command();
|
|
23
38
|
program
|
|
24
39
|
.name('haystack')
|
|
25
40
|
.description('Set up Haystack verification for your project')
|
|
26
|
-
.version('0.
|
|
41
|
+
.version('0.9.0');
|
|
27
42
|
program
|
|
28
43
|
.command('init')
|
|
29
44
|
.description('Create .haystack.json configuration')
|
|
@@ -34,10 +49,29 @@ This creates a .haystack.json file with auto-detected settings:
|
|
|
34
49
|
• Services (for monorepos)
|
|
35
50
|
• Auth bypass for sandbox environments
|
|
36
51
|
|
|
37
|
-
After running, use
|
|
38
|
-
|
|
52
|
+
After running, use \`haystack setup\` to scan your repos for rules,
|
|
53
|
+
CI signals, and review policies.
|
|
39
54
|
`)
|
|
40
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);
|
|
41
75
|
program
|
|
42
76
|
.command('status')
|
|
43
77
|
.description('Check if .haystack.json exists and is valid')
|
|
@@ -50,6 +84,191 @@ program
|
|
|
50
84
|
.command('logout')
|
|
51
85
|
.description('Remove stored credentials')
|
|
52
86
|
.action(logoutCommand);
|
|
87
|
+
program
|
|
88
|
+
.command('submit')
|
|
89
|
+
.description('Create a PR from current changes')
|
|
90
|
+
.option('--title <title>', 'PR title (default: last commit message)')
|
|
91
|
+
.option('--body <body>', 'PR body (default: commit messages since base)')
|
|
92
|
+
.option('--body-file <path>', 'Read PR body from file (use "-" for stdin)')
|
|
93
|
+
.option('--base <branch>', 'Base branch (default: main or master)')
|
|
94
|
+
.option('--draft', 'Create as draft PR')
|
|
95
|
+
.option('--review [reviewer]', 'Request human review (BLOCKS auto-merge — only use when explicitly asked)')
|
|
96
|
+
.option('--force', 'Skip pre-PR triage checks')
|
|
97
|
+
.option('--auto-fix', 'Auto-fix analysis issues in a sandbox before surfacing to Feed')
|
|
98
|
+
.option('--no-wait', 'Skip waiting for analysis results')
|
|
99
|
+
.addHelpText('after', `
|
|
100
|
+
This command is designed for AI coding agents to submit PRs.
|
|
101
|
+
|
|
102
|
+
1. Runs pre-PR triage (code review, rules, intent drift) via sub-agents
|
|
103
|
+
2. Pushes the current branch to origin
|
|
104
|
+
3. Creates a pull request on GitHub
|
|
105
|
+
4. Waits for Haystack analysis results (triggered via GitHub App webhook)
|
|
106
|
+
|
|
107
|
+
Pre-PR Triage:
|
|
108
|
+
Before creating the PR, haystack spawns parallel sub-agents to check for:
|
|
109
|
+
• Code review bugs (logic errors, null crashes, security issues)
|
|
110
|
+
• Rule violations (from .haystack/pr-rules.yml)
|
|
111
|
+
• Intent drift (AI agent deviations from user instructions)
|
|
112
|
+
|
|
113
|
+
Use --force to skip triage entirely.
|
|
114
|
+
Use --no-wait to skip waiting for analysis results.
|
|
115
|
+
Use --auto-fix to auto-fix analysis issues before surfacing to Feed.
|
|
116
|
+
|
|
117
|
+
Review Routing:
|
|
118
|
+
By default, PRs enter the auto-merge queue and merge automatically once
|
|
119
|
+
Haystack analysis passes. This is the correct default for most PRs.
|
|
120
|
+
|
|
121
|
+
⚠ Only use --review when the user EXPLICITLY asks for human review.
|
|
122
|
+
--review BLOCKS auto-merge — the PR will NOT merge until a human approves,
|
|
123
|
+
which delays merging. Do not add --review "just to be safe".
|
|
124
|
+
|
|
125
|
+
• --review Labels the PR "haystack:needs-review" for the
|
|
126
|
+
needs-assignment queue (a teammate will pick it up)
|
|
127
|
+
• --review <username> Same label, plus requests review from that GitHub user
|
|
128
|
+
|
|
129
|
+
Examples:
|
|
130
|
+
haystack submit --auto-fix # Recommended: triage, create PR, auto-fix issues
|
|
131
|
+
haystack submit # Triage, create PR, auto-merge queue (no auto-fix)
|
|
132
|
+
haystack submit --force # Skip triage
|
|
133
|
+
haystack submit --no-wait # Don't wait for analysis
|
|
134
|
+
haystack submit --title "Fix auth" # Custom PR title
|
|
135
|
+
haystack submit --body "## Summary" # Custom PR body (inline)
|
|
136
|
+
haystack submit --body-file body.md # Read body from file (supports markdown)
|
|
137
|
+
echo "## Summary" | haystack submit --body-file - # Read body from stdin
|
|
138
|
+
haystack submit --base develop # Target a different base branch
|
|
139
|
+
haystack submit --draft # Create as draft PR
|
|
140
|
+
haystack submit --review # ⚠ Blocks auto-merge, needs human approval
|
|
141
|
+
haystack submit --review octocat # ⚠ Blocks auto-merge, requests review from octocat
|
|
142
|
+
`)
|
|
143
|
+
.action(submitCommand);
|
|
144
|
+
program
|
|
145
|
+
.command('check-pending')
|
|
146
|
+
.description('Check status of pending Haystack analysis')
|
|
147
|
+
.option('--json', 'Output as JSON')
|
|
148
|
+
.option('--hook', 'Minimal output for session-start hooks')
|
|
149
|
+
.option('--clear', 'Clear pending submit state')
|
|
150
|
+
.addHelpText('after', `
|
|
151
|
+
After \`haystack submit\`, this checks whether the analysis finished
|
|
152
|
+
and shows a two-state verdict:
|
|
153
|
+
|
|
154
|
+
Good to merge — No issues found, safe to merge
|
|
155
|
+
Needs your input — Bugs or rule violations found
|
|
156
|
+
|
|
157
|
+
This runs automatically on CLI session start if session hooks are installed.
|
|
158
|
+
|
|
159
|
+
Examples:
|
|
160
|
+
haystack check-pending # Rich terminal output
|
|
161
|
+
haystack check-pending --hook # Minimal output (for hooks)
|
|
162
|
+
haystack check-pending --json # Machine-readable JSON
|
|
163
|
+
haystack check-pending --clear # Clear pending state
|
|
164
|
+
`)
|
|
165
|
+
.action(checkPendingCommand);
|
|
166
|
+
program
|
|
167
|
+
.command('triage <pr>')
|
|
168
|
+
.description('View Haystack analysis results for a PR')
|
|
169
|
+
.option('--json', 'Output as JSON')
|
|
170
|
+
.option('--no-wait', 'Exit immediately if analysis is still pending')
|
|
171
|
+
.addHelpText('after', `
|
|
172
|
+
Look up triage results (bugs, rule violations, verdict) for any PR.
|
|
173
|
+
|
|
174
|
+
PR identifier formats:
|
|
175
|
+
123 PR number (uses current repo)
|
|
176
|
+
#123 PR number with hash
|
|
177
|
+
owner/repo#123 Fully qualified
|
|
178
|
+
https://github.com/owner/repo/pull/123 GitHub URL
|
|
179
|
+
|
|
180
|
+
By default, if analysis is still in progress, the command will poll
|
|
181
|
+
for up to 5 minutes. Use --no-wait to exit immediately instead.
|
|
182
|
+
|
|
183
|
+
Examples:
|
|
184
|
+
haystack triage 42 # Current repo, PR #42
|
|
185
|
+
haystack triage acme/widgets#99 # Specific repo
|
|
186
|
+
haystack triage https://github.com/o/r/pull/1 # From URL
|
|
187
|
+
haystack triage 42 --json # Machine-readable output
|
|
188
|
+
haystack triage 42 --no-wait # Don't wait if pending
|
|
189
|
+
`)
|
|
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);
|
|
53
272
|
// Secrets subcommands
|
|
54
273
|
const secrets = program
|
|
55
274
|
.command('secrets')
|
|
@@ -123,6 +342,52 @@ Examples:
|
|
|
123
342
|
haystack config agentic-tool codex # Use your ChatGPT
|
|
124
343
|
`)
|
|
125
344
|
.action(handleAgenticTool);
|
|
345
|
+
config
|
|
346
|
+
.command('auto-merge [action]')
|
|
347
|
+
.description('Auto-merge safe PRs submitted via haystack submit (on|off|status)')
|
|
348
|
+
.addHelpText('after', `
|
|
349
|
+
Actions:
|
|
350
|
+
on, enable Enable auto-merge for safe PRs
|
|
351
|
+
off, disable Disable auto-merge
|
|
352
|
+
status Show current status (default)
|
|
353
|
+
|
|
354
|
+
When enabled, PRs submitted via \`haystack submit\` will be
|
|
355
|
+
automatically merged if Haystack analysis finds no issues
|
|
356
|
+
(safe to merge). PRs with bugs or rule violations still
|
|
357
|
+
require manual review.
|
|
358
|
+
|
|
359
|
+
Examples:
|
|
360
|
+
haystack config auto-merge # Show current status
|
|
361
|
+
haystack config auto-merge on # Enable auto-merge
|
|
362
|
+
haystack config auto-merge off # Disable auto-merge
|
|
363
|
+
`)
|
|
364
|
+
.action(handleAutoMerge);
|
|
365
|
+
config
|
|
366
|
+
.command('wait-for-reviewers [action] [reviewers...]')
|
|
367
|
+
.description('Configure which AI reviewers the merge queue waits for')
|
|
368
|
+
.addHelpText('after', `
|
|
369
|
+
Actions:
|
|
370
|
+
list Show current expected reviewers (default)
|
|
371
|
+
add <names> Add one or more AI reviewer sources
|
|
372
|
+
remove <names> Remove one or more AI reviewer sources
|
|
373
|
+
clear Remove all expected reviewers
|
|
374
|
+
|
|
375
|
+
AI reviewer sources are stored in .haystack.json under
|
|
376
|
+
babysitter.expected_ai_reviewers. The merge queue will
|
|
377
|
+
wait for these reviewers to post before starting the
|
|
378
|
+
grace period.
|
|
379
|
+
|
|
380
|
+
Run \`haystack config wait-for-reviewers list\` to see
|
|
381
|
+
all available reviewer sources and which are enabled.
|
|
382
|
+
|
|
383
|
+
Examples:
|
|
384
|
+
haystack config wait-for-reviewers # Show status
|
|
385
|
+
haystack config wait-for-reviewers add cursor # Wait for Cursor BugBot
|
|
386
|
+
haystack config wait-for-reviewers add cursor coderabbit # Add multiple
|
|
387
|
+
haystack config wait-for-reviewers remove cursor # Stop waiting for Cursor
|
|
388
|
+
haystack config wait-for-reviewers clear # Wait for none
|
|
389
|
+
`)
|
|
390
|
+
.action(handleWaitForReviewers);
|
|
126
391
|
// Skills subcommands
|
|
127
392
|
const skills = program
|
|
128
393
|
.command('skills')
|
|
@@ -186,6 +451,81 @@ hooks
|
|
|
186
451
|
.command('update')
|
|
187
452
|
.description('Update Entire CLI to the latest version')
|
|
188
453
|
.action(hooksUpdate);
|
|
454
|
+
hooks
|
|
455
|
+
.command('install-session')
|
|
456
|
+
.description('Install session-start hooks for coding CLIs')
|
|
457
|
+
.option('--cli <name>', 'Target CLI: claude, codex, gemini, or all')
|
|
458
|
+
.addHelpText('after', `
|
|
459
|
+
Configures your coding CLI to run \`haystack check-pending\` on session start.
|
|
460
|
+
This shows pending PR analysis results when you open a new terminal session.
|
|
461
|
+
|
|
462
|
+
Claude Code: Native SessionStart hook (.claude/settings.json)
|
|
463
|
+
Codex CLI: AGENTS.md instructions
|
|
464
|
+
Gemini CLI: GEMINI.md instructions
|
|
465
|
+
|
|
466
|
+
Examples:
|
|
467
|
+
haystack hooks install-session # Auto-detect CLIs
|
|
468
|
+
haystack hooks install-session --cli claude # Claude Code only
|
|
469
|
+
haystack hooks install-session --cli all # All detected CLIs
|
|
470
|
+
`)
|
|
471
|
+
.action(installSessionHooks);
|
|
472
|
+
hooks
|
|
473
|
+
.command('session-status')
|
|
474
|
+
.description('Check session hook installation status')
|
|
475
|
+
.action(sessionHooksStatus);
|
|
476
|
+
// Policy subcommands
|
|
477
|
+
const policy = program
|
|
478
|
+
.command('policy')
|
|
479
|
+
.description('Manage review policies (.haystack/review-policy.md)');
|
|
480
|
+
policy
|
|
481
|
+
.command('list')
|
|
482
|
+
.description('List all review policies')
|
|
483
|
+
.action(listPolicies);
|
|
484
|
+
policy
|
|
485
|
+
.command('add [name]')
|
|
486
|
+
.description('Add a new review policy interactively')
|
|
487
|
+
.addHelpText('after', `
|
|
488
|
+
This command prompts for:
|
|
489
|
+
• Policy name (e.g., "Infrastructure changes")
|
|
490
|
+
• File patterns (comma-separated globs, e.g., "terraform/**,*.tf")
|
|
491
|
+
• Severity (critical, high, medium, low)
|
|
492
|
+
• Reason (why this requires human review)
|
|
493
|
+
|
|
494
|
+
Examples:
|
|
495
|
+
haystack policy add # Interactive add
|
|
496
|
+
haystack policy add "Database changes" # Start with name
|
|
497
|
+
`)
|
|
498
|
+
.action(addPolicy);
|
|
499
|
+
policy
|
|
500
|
+
.command('remove <name>')
|
|
501
|
+
.description('Remove a review policy by name')
|
|
502
|
+
.action(removePolicy);
|
|
503
|
+
policy
|
|
504
|
+
.command('add-instruction [text]')
|
|
505
|
+
.description('Add a semantic review instruction')
|
|
506
|
+
.addHelpText('after', `
|
|
507
|
+
Instructions are natural language directives that override default review behavior.
|
|
508
|
+
They apply to all PRs (not file-pattern-gated).
|
|
509
|
+
|
|
510
|
+
Examples:
|
|
511
|
+
haystack policy add-instruction "Never flag weak test coverage as needing review"
|
|
512
|
+
haystack policy add-instruction # Interactive prompt
|
|
513
|
+
`)
|
|
514
|
+
.action(addInstruction);
|
|
515
|
+
policy
|
|
516
|
+
.command('init')
|
|
517
|
+
.description('Create initial review-policy.md with example policies')
|
|
518
|
+
.option('-f, --force', 'Overwrite existing file')
|
|
519
|
+
.addHelpText('after', `
|
|
520
|
+
Creates .haystack/review-policy.md with sensible defaults:
|
|
521
|
+
• Infrastructure changes (terraform, pulumi, cdk)
|
|
522
|
+
• Secret files (*.secret*, *.env*, credentials)
|
|
523
|
+
• CI/CD pipelines (GitHub Actions, GitLab CI, etc.)
|
|
524
|
+
|
|
525
|
+
The generated policies appear in Haystack's "Human Review Needed"
|
|
526
|
+
section when a PR touches matching files.
|
|
527
|
+
`)
|
|
528
|
+
.action(initPolicies);
|
|
189
529
|
// Show help if no command provided
|
|
190
530
|
if (process.argv.length === 2) {
|
|
191
531
|
program.help();
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-detection utilities for framework, monorepo, and service configuration.
|
|
3
|
+
* Used by the setup wizard to provide smart defaults.
|
|
4
|
+
*/
|
|
5
|
+
export interface DetectedFramework {
|
|
6
|
+
name: string;
|
|
7
|
+
devCommand: string;
|
|
8
|
+
port: number;
|
|
9
|
+
readyPattern: string;
|
|
10
|
+
configFile: string;
|
|
11
|
+
}
|
|
12
|
+
export interface DetectedService {
|
|
13
|
+
name: string;
|
|
14
|
+
root: string;
|
|
15
|
+
type: 'server' | 'batch';
|
|
16
|
+
framework?: DetectedFramework;
|
|
17
|
+
/** Services this service depends on (detected from proxy config) */
|
|
18
|
+
depends_on?: string[];
|
|
19
|
+
}
|
|
20
|
+
export interface ProxyTarget {
|
|
21
|
+
/** Path pattern being proxied (e.g., "/api") */
|
|
22
|
+
path: string;
|
|
23
|
+
/** Target URL (e.g., "http://localhost:8787") */
|
|
24
|
+
target: string;
|
|
25
|
+
/** Port extracted from target */
|
|
26
|
+
port: number;
|
|
27
|
+
}
|
|
28
|
+
export interface ProjectDetection {
|
|
29
|
+
isMonorepo: boolean;
|
|
30
|
+
packageManager: 'npm' | 'pnpm' | 'yarn' | 'bun';
|
|
31
|
+
frameworks: DetectedFramework[];
|
|
32
|
+
services: DetectedService[];
|
|
33
|
+
/** Proxy targets detected from config files */
|
|
34
|
+
proxyTargets: ProxyTarget[];
|
|
35
|
+
suggestions: {
|
|
36
|
+
projectName: string;
|
|
37
|
+
devCommand: string;
|
|
38
|
+
port: number;
|
|
39
|
+
readyPattern: string;
|
|
40
|
+
authBypassEnv?: string;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Main detection function - analyzes a project directory
|
|
45
|
+
*/
|
|
46
|
+
export declare function detectProject(rootDir?: string): ProjectDetection;
|
|
47
|
+
/**
|
|
48
|
+
* Format detection results for display to user
|
|
49
|
+
*/
|
|
50
|
+
export declare function formatDetectionSummary(detection: ProjectDetection): string;
|