@haystackeditor/cli 0.10.1 → 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.
@@ -1,14 +1,10 @@
1
1
  /**
2
2
  * Config commands - manage preferences
3
3
  *
4
- * Repo-level preferences (sandbox_enabled, auto_merge) are stored in .haystack.json.
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>;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Config commands - manage preferences
3
3
  *
4
- * Repo-level preferences (sandbox_enabled, auto_merge) are stored in .haystack.json.
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
- // Default: sandbox_enabled=true, auto_merge=false
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() {
@@ -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
  }
@@ -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 Verification\n\nFollow .agents/skills/setup-haystack.md to set up Haystack verification for this repo.\n');
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(' /prepare-haystack ') + chalk.gray('- Add aria-labels and data-testid attributes'));
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(' /prepare-haystack ') + chalk.gray('- Add accessibility attributes'));
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
  }
@@ -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
@@ -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 secrets list # List stored secrets
19
+ * npx @haystackeditor/cli config # Manage preferences
20
20
  */
21
21
  export {};
package/dist/index.js CHANGED
@@ -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 secrets list # List stored secrets
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 { listSecrets, setSecret, getSecret, getSecretsForRepo, deleteSecret } from './commands/secrets.js';
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';
@@ -38,7 +37,7 @@ const program = new Command();
38
37
  program
39
38
  .name('haystack')
40
39
  .description('Haystack CLI — automated PR review, triage, and merge queue')
41
- .version('0.10.1');
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 sandbox environments
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 in a sandbox before surfacing to Feed')
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
- /prepare-haystack - Add accessibility attributes
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
- * The config schema matches what agent/modal/sandbox.py expects to read.
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 for sandbox verification */
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 for sandbox verification */
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
- * The config schema matches what agent/modal/sandbox.py expects to read.
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 for sandbox verification */
246
+ /** Auth configuration (legacy) */
247
247
  auth: AuthConfigSchema.optional(),
248
248
  /** Agentic configuration (project-level override) */
249
249
  agentic: AgenticSchema.optional(),
250
- /** Database configuration for sandbox verification */
250
+ /** Database configuration (legacy) */
251
251
  database: DatabaseConfigSchema.optional(),
252
252
  /** Network egress configuration */
253
253
  network: NetworkConfigSchema.optional(),
@@ -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 from Haystack platform.');
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@haystackeditor/cli",
3
- "version": "0.10.1",
3
+ "version": "0.10.2",
4
4
  "description": "Set up Haystack for your project — automated PR review, triage, and merge queue",
5
5
  "type": "module",
6
6
  "bin": {