@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.
Files changed (63) hide show
  1. package/README.md +93 -87
  2. package/dist/assets/hooks/llm-rules-template.md +21 -0
  3. package/dist/assets/hooks/package.json +2 -2
  4. package/dist/assets/hooks/scripts/pre-push.sh +20 -0
  5. package/dist/assets/skills/prepare-haystack.md +323 -0
  6. package/dist/assets/skills/secrets.md +164 -0
  7. package/dist/assets/skills/setup-external-sandbox.md +243 -0
  8. package/dist/assets/skills/setup-haystack.md +639 -0
  9. package/dist/assets/skills/submit.md +154 -0
  10. package/dist/assets/templates/CLAUDE.md.snippet +42 -0
  11. package/dist/assets/templates/haystack.yml +193 -0
  12. package/dist/commands/check-pending.d.ts +19 -0
  13. package/dist/commands/check-pending.js +217 -0
  14. package/dist/commands/config.d.ts +13 -21
  15. package/dist/commands/config.js +278 -92
  16. package/dist/commands/dismiss.d.ts +17 -0
  17. package/dist/commands/dismiss.js +201 -0
  18. package/dist/commands/init.js +25 -28
  19. package/dist/commands/install-session-hooks.d.ts +16 -0
  20. package/dist/commands/install-session-hooks.js +302 -0
  21. package/dist/commands/login.js +1 -1
  22. package/dist/commands/policy.d.ts +31 -0
  23. package/dist/commands/policy.js +365 -0
  24. package/dist/commands/pr-status.d.ts +16 -0
  25. package/dist/commands/pr-status.js +188 -0
  26. package/dist/commands/setup.d.ts +13 -0
  27. package/dist/commands/setup.js +496 -0
  28. package/dist/commands/skills.d.ts +2 -2
  29. package/dist/commands/skills.js +51 -186
  30. package/dist/commands/submit.d.ts +23 -0
  31. package/dist/commands/submit.js +456 -0
  32. package/dist/commands/triage.d.ts +16 -0
  33. package/dist/commands/triage.js +354 -0
  34. package/dist/index.d.ts +7 -0
  35. package/dist/index.js +344 -4
  36. package/dist/tools/detect.d.ts +50 -0
  37. package/dist/tools/detect.js +853 -0
  38. package/dist/tools/fixtures.d.ts +38 -0
  39. package/dist/tools/fixtures.js +199 -0
  40. package/dist/tools/setup.d.ts +43 -0
  41. package/dist/tools/setup.js +597 -0
  42. package/dist/triage/prompts.d.ts +31 -0
  43. package/dist/triage/prompts.js +296 -0
  44. package/dist/triage/runner.d.ts +21 -0
  45. package/dist/triage/runner.js +339 -0
  46. package/dist/triage/traces.d.ts +20 -0
  47. package/dist/triage/traces.js +305 -0
  48. package/dist/triage/types.d.ts +47 -0
  49. package/dist/triage/types.js +7 -0
  50. package/dist/types.d.ts +1387 -191
  51. package/dist/types.js +254 -2
  52. package/dist/utils/analysis-api.d.ts +108 -0
  53. package/dist/utils/analysis-api.js +194 -0
  54. package/dist/utils/config.js +1 -1
  55. package/dist/utils/git.d.ts +80 -0
  56. package/dist/utils/git.js +302 -0
  57. package/dist/utils/github-api.d.ts +83 -0
  58. package/dist/utils/github-api.js +266 -0
  59. package/dist/utils/pending-state.d.ts +40 -0
  60. package/dist/utils/pending-state.js +86 -0
  61. package/dist/utils/secrets.js +3 -3
  62. package/dist/utils/skill.js +257 -0
  63. package/package.json +11 -9
@@ -1,200 +1,73 @@
1
1
  /**
2
- * Skills command - Registers the haystack-verify MCP server with coding CLIs
3
- * Supports: Claude Code, Codex CLI, Cursor, and manual setup
2
+ * Skills command - Copies Haystack skill files into the project
3
+ * for AI agent discovery (Claude Code, Codex CLI, Cursor)
4
4
  */
5
- import { execSync } from 'child_process';
6
5
  import chalk from 'chalk';
7
6
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
8
- import { homedir } from 'os';
9
- import { join } from 'path';
10
- const CLI_CONFIGS = {
11
- claude: {
12
- name: 'claude',
13
- displayName: 'Claude Code',
14
- checkCommand: 'which claude',
15
- installCommand: 'claude mcp add haystack-verify -- npx @haystackeditor/verify',
16
- },
17
- codex: {
18
- name: 'codex',
19
- displayName: 'Codex CLI',
20
- checkCommand: 'which codex',
21
- installCommand: 'codex mcp add haystack-verify -- npx @haystackeditor/verify',
22
- },
23
- cursor: {
24
- name: 'cursor',
25
- displayName: 'Cursor',
26
- checkCommand: '', // Cursor is always "available" - we check config file
27
- installCommand: '', // We modify config directly
28
- configPath: join(homedir(), '.cursor', 'mcp.json'),
29
- },
30
- manual: {
31
- name: 'manual',
32
- displayName: 'Manual Setup',
33
- checkCommand: '',
34
- installCommand: '',
35
- },
36
- };
37
- function detectAvailableCLIs() {
38
- const available = [];
39
- // Check Claude Code
40
- try {
41
- execSync('which claude', { stdio: 'ignore' });
42
- available.push('claude');
43
- }
44
- catch { }
45
- // Check Codex CLI
46
- try {
47
- execSync('which codex', { stdio: 'ignore' });
48
- available.push('codex');
49
- }
50
- catch { }
51
- // Check Cursor (config-based)
52
- const cursorConfigDir = join(homedir(), '.cursor');
53
- if (existsSync(cursorConfigDir)) {
54
- available.push('cursor');
55
- }
56
- return available;
57
- }
58
- function installForClaude() {
59
- const config = CLI_CONFIGS.claude;
60
- console.log(chalk.gray(`Running: ${config.installCommand}\n`));
61
- try {
62
- execSync(config.installCommand, { stdio: 'inherit' });
63
- return true;
64
- }
65
- catch {
66
- return false;
67
- }
7
+ import { join, dirname } from 'path';
8
+ import { fileURLToPath } from 'url';
9
+ const __dirname = dirname(fileURLToPath(import.meta.url));
10
+ /** Directory containing bundled skill files */
11
+ function getSkillsSourceDir() {
12
+ // In dist/commands/skills.js → assets are at dist/assets/skills/
13
+ return join(__dirname, '..', 'assets', 'skills');
68
14
  }
69
- function installForCodex() {
70
- const config = CLI_CONFIGS.codex;
71
- console.log(chalk.gray(`Running: ${config.installCommand}\n`));
72
- try {
73
- execSync(config.installCommand, { stdio: 'inherit' });
74
- return true;
75
- }
76
- catch {
15
+ const SKILL_FILES = [
16
+ 'setup-haystack.md',
17
+ 'prepare-haystack.md',
18
+ 'secrets.md',
19
+ 'setup-external-sandbox.md',
20
+ 'submit.md',
21
+ ];
22
+ function installSkillFiles(targetDir) {
23
+ const sourceDir = getSkillsSourceDir();
24
+ if (!existsSync(sourceDir)) {
25
+ console.error(chalk.red(`Skills source directory not found: ${sourceDir}`));
77
26
  return false;
78
27
  }
79
- }
80
- function installForCursor() {
81
- const configPath = CLI_CONFIGS.cursor.configPath;
82
- const configDir = join(homedir(), '.cursor');
83
- console.log(chalk.gray(`Updating: ${configPath}\n`));
84
- try {
85
- // Ensure directory exists
86
- if (!existsSync(configDir)) {
87
- mkdirSync(configDir, { recursive: true });
88
- }
89
- // Read or create config
90
- let config = {};
91
- if (existsSync(configPath)) {
92
- const content = readFileSync(configPath, 'utf-8');
93
- config = JSON.parse(content);
28
+ // Ensure target directory exists
29
+ if (!existsSync(targetDir)) {
30
+ mkdirSync(targetDir, { recursive: true });
31
+ }
32
+ let copied = 0;
33
+ for (const file of SKILL_FILES) {
34
+ const src = join(sourceDir, file);
35
+ if (existsSync(src)) {
36
+ const dest = join(targetDir, file);
37
+ writeFileSync(dest, readFileSync(src, 'utf-8'));
38
+ copied++;
94
39
  }
95
- // Add haystack-verify server
96
- config.mcpServers = config.mcpServers || {};
97
- config.mcpServers['haystack-verify'] = {
98
- command: 'npx',
99
- args: ['@haystackeditor/verify'],
100
- };
101
- // Write config
102
- writeFileSync(configPath, JSON.stringify(config, null, 2));
103
- return true;
104
- }
105
- catch (error) {
106
- console.error(chalk.red(`Failed to update Cursor config: ${error}`));
107
- return false;
108
40
  }
109
- }
110
- function showManualInstructions() {
111
- console.log(chalk.white('\nšŸ“‹ Manual Setup Instructions\n'));
112
- console.log(chalk.cyan('Claude Code:'));
113
- console.log(chalk.gray(' claude mcp add haystack-verify -- npx @haystackeditor/verify\n'));
114
- console.log(chalk.cyan('Codex CLI:'));
115
- console.log(chalk.gray(' codex mcp add haystack-verify -- npx @haystackeditor/verify\n'));
116
- console.log(chalk.cyan('Cursor:'));
117
- console.log(chalk.gray(' Add to ~/.cursor/mcp.json:'));
118
- console.log(chalk.gray(` {
119
- "mcpServers": {
120
- "haystack-verify": {
121
- "command": "npx",
122
- "args": ["@haystackeditor/verify"]
123
- }
124
- }
125
- }\n`));
126
- console.log(chalk.cyan('VS Code + Continue:'));
127
- console.log(chalk.gray(' Add to .continue/config.json or settings\n'));
41
+ return copied > 0;
128
42
  }
129
43
  export async function installSkills(options) {
130
44
  console.log(chalk.cyan('\nšŸ“¦ Installing Haystack skills...\n'));
131
- // If CLI specified, use it directly
132
- if (options.cli) {
133
- const cli = options.cli.toLowerCase();
134
- if (cli === 'manual') {
135
- showManualInstructions();
136
- return;
137
- }
138
- if (!['claude', 'codex', 'cursor'].includes(cli)) {
139
- console.log(chalk.red(`Unknown CLI: ${options.cli}`));
140
- console.log(chalk.gray('Supported: claude, codex, cursor, manual'));
141
- process.exit(1);
142
- }
143
- const success = await installForCLI(cli);
144
- if (success) {
145
- showSuccessMessage(cli);
146
- }
147
- return;
148
- }
149
- // Auto-detect available CLIs
150
- const available = detectAvailableCLIs();
151
- if (available.length === 0) {
152
- console.log(chalk.yellow('No supported coding CLI detected.\n'));
153
- showManualInstructions();
154
- return;
155
- }
156
- if (available.length === 1) {
157
- // Only one CLI available, use it
158
- const cli = available[0];
159
- console.log(chalk.gray(`Detected: ${CLI_CONFIGS[cli].displayName}\n`));
160
- const success = await installForCLI(cli);
161
- if (success) {
162
- showSuccessMessage(cli);
163
- }
164
- return;
165
- }
166
- // Multiple CLIs available - install for all
167
- console.log(chalk.gray(`Detected: ${available.map(c => CLI_CONFIGS[c].displayName).join(', ')}\n`));
168
- for (const cli of available) {
169
- console.log(chalk.white(`\nInstalling for ${CLI_CONFIGS[cli].displayName}...`));
170
- await installForCLI(cli);
171
- }
172
- console.log(chalk.green('\nāœ… Haystack skills installed!\n'));
173
- console.log(chalk.white('Run one of these in your coding CLI:'));
174
- console.log(chalk.cyan(' /setup-haystack'));
175
- console.log();
176
- }
177
- async function installForCLI(cli) {
178
- switch (cli) {
179
- case 'claude':
180
- return installForClaude();
181
- case 'codex':
182
- return installForCodex();
183
- case 'cursor':
184
- return installForCursor();
185
- default:
186
- return false;
187
- }
45
+ const projectRoot = process.cwd();
46
+ // Install to .agents/skills/ for generic agent discovery
47
+ const agentsSkillsDir = join(projectRoot, '.agents', 'skills');
48
+ console.log(chalk.gray(`Copying skills to ${agentsSkillsDir}\n`));
49
+ const success = installSkillFiles(agentsSkillsDir);
50
+ if (!success) {
51
+ console.error(chalk.red('Failed to install skill files.'));
52
+ process.exit(1);
53
+ }
54
+ // Also create .claude/commands/ entry for Claude Code slash commands
55
+ const claudeCommandsDir = join(projectRoot, '.claude', 'commands');
56
+ if (!existsSync(claudeCommandsDir)) {
57
+ mkdirSync(claudeCommandsDir, { recursive: true });
58
+ }
59
+ const claudeCommandPath = join(claudeCommandsDir, 'setup-haystack.md');
60
+ writeFileSync(claudeCommandPath, '# Set Up Haystack Verification\n\nFollow .agents/skills/setup-haystack.md to set up Haystack verification for this repo.\n');
61
+ showSuccessMessage();
188
62
  }
189
- function showSuccessMessage(cli) {
190
- const config = CLI_CONFIGS[cli];
63
+ function showSuccessMessage() {
191
64
  console.log(chalk.green('\nāœ… Haystack skills installed!\n'));
192
65
  console.log(chalk.white('Available skills:'));
193
66
  console.log(chalk.cyan(' /setup-haystack ') + chalk.gray('- Create .haystack.json with AI assistance'));
194
67
  console.log(chalk.cyan(' /prepare-haystack ') + chalk.gray('- Add aria-labels and data-testid attributes'));
195
68
  console.log(chalk.cyan(' /setup-haystack-secrets ') + chalk.gray('- Configure API keys and secrets'));
196
69
  console.log();
197
- console.log(chalk.white(`Open ${config.displayName} and run:`));
70
+ console.log(chalk.white('Run in your coding CLI:'));
198
71
  console.log(chalk.cyan(' /setup-haystack'));
199
72
  console.log();
200
73
  }
@@ -204,12 +77,4 @@ export async function listSkills() {
204
77
  console.log(chalk.cyan(' /prepare-haystack ') + chalk.gray('- Add accessibility attributes'));
205
78
  console.log(chalk.cyan(' /setup-haystack-secrets ') + chalk.gray('- Configure secrets for sandboxes'));
206
79
  console.log();
207
- const available = detectAvailableCLIs();
208
- if (available.length > 0) {
209
- console.log(chalk.gray('Detected CLIs: ') + chalk.white(available.map(c => CLI_CONFIGS[c].displayName).join(', ')));
210
- }
211
- else {
212
- console.log(chalk.gray('No coding CLI detected. Run: ') + chalk.white('haystack skills install --cli manual'));
213
- }
214
- console.log();
215
80
  }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Submit command - Create a PR from current changes
3
+ *
4
+ * Runs pre-PR triage (code review, rules, intent drift) via parallel sub-agents,
5
+ * then pushes the current branch and creates a PR.
6
+ *
7
+ * PRs are routed based on flags:
8
+ * - Default: auto-merge queue (analysis runs, auto-merged if approved)
9
+ * - --review: human review required
10
+ * - --force: skip triage checks
11
+ */
12
+ export interface SubmitOptions {
13
+ title?: string;
14
+ body?: string;
15
+ bodyFile?: string;
16
+ base?: string;
17
+ draft?: boolean;
18
+ review?: string | true;
19
+ force?: boolean;
20
+ wait?: boolean;
21
+ autoFix?: boolean;
22
+ }
23
+ export declare function submitCommand(options: SubmitOptions): Promise<void>;