@haystackeditor/cli 0.8.0 → 0.9.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 (76) hide show
  1. package/README.md +105 -12
  2. package/dist/assets/hooks/agent-context/detect.ts +136 -0
  3. package/dist/assets/hooks/agent-context/format.ts +99 -0
  4. package/dist/assets/hooks/agent-context/index.ts +39 -0
  5. package/dist/assets/hooks/agent-context/parsers/claude.ts +253 -0
  6. package/dist/assets/hooks/agent-context/parsers/gemini.ts +155 -0
  7. package/dist/assets/hooks/agent-context/parsers/opencode.ts +174 -0
  8. package/dist/assets/hooks/agent-context/tsconfig.json +13 -0
  9. package/dist/assets/hooks/agent-context/types.ts +58 -0
  10. package/dist/assets/hooks/llm-rules-template.md +56 -0
  11. package/dist/assets/hooks/package.json +11 -0
  12. package/dist/assets/hooks/scripts/commit-msg.sh +4 -0
  13. package/dist/assets/hooks/scripts/post-commit.sh +4 -0
  14. package/dist/assets/hooks/scripts/pre-commit.sh +92 -0
  15. package/dist/assets/hooks/scripts/pre-push.sh +25 -0
  16. package/dist/assets/hooks/scripts/prepare-commit-msg.sh +3 -0
  17. package/dist/assets/hooks/truncation-checker/ast-analyzer.ts +528 -0
  18. package/dist/assets/hooks/truncation-checker/index.ts +595 -0
  19. package/dist/assets/hooks/truncation-checker/tsconfig.json +13 -0
  20. package/dist/assets/skills/prepare-haystack.md +323 -0
  21. package/dist/assets/skills/secrets.md +164 -0
  22. package/dist/assets/skills/setup-external-sandbox.md +243 -0
  23. package/dist/assets/skills/setup-haystack.md +639 -0
  24. package/dist/assets/skills/submit.md +154 -0
  25. package/dist/assets/templates/CLAUDE.md.snippet +42 -0
  26. package/dist/assets/templates/haystack.yml +193 -0
  27. package/dist/commands/check-pending.d.ts +19 -0
  28. package/dist/commands/check-pending.js +217 -0
  29. package/dist/commands/config.d.ts +18 -12
  30. package/dist/commands/config.js +327 -52
  31. package/dist/commands/hooks.d.ts +17 -0
  32. package/dist/commands/hooks.js +269 -0
  33. package/dist/commands/install-session-hooks.d.ts +16 -0
  34. package/dist/commands/install-session-hooks.js +302 -0
  35. package/dist/commands/login.js +1 -1
  36. package/dist/commands/policy.d.ts +31 -0
  37. package/dist/commands/policy.js +365 -0
  38. package/dist/commands/skills.d.ts +8 -0
  39. package/dist/commands/skills.js +80 -0
  40. package/dist/commands/submit.d.ts +22 -0
  41. package/dist/commands/submit.js +428 -0
  42. package/dist/commands/triage.d.ts +16 -0
  43. package/dist/commands/triage.js +354 -0
  44. package/dist/index.d.ts +3 -0
  45. package/dist/index.js +317 -2
  46. package/dist/tools/detect.d.ts +50 -0
  47. package/dist/tools/detect.js +853 -0
  48. package/dist/tools/fixtures.d.ts +38 -0
  49. package/dist/tools/fixtures.js +199 -0
  50. package/dist/tools/setup.d.ts +43 -0
  51. package/dist/tools/setup.js +597 -0
  52. package/dist/triage/prompts.d.ts +31 -0
  53. package/dist/triage/prompts.js +266 -0
  54. package/dist/triage/runner.d.ts +21 -0
  55. package/dist/triage/runner.js +325 -0
  56. package/dist/triage/traces.d.ts +20 -0
  57. package/dist/triage/traces.js +305 -0
  58. package/dist/triage/types.d.ts +47 -0
  59. package/dist/triage/types.js +7 -0
  60. package/dist/types.d.ts +1387 -191
  61. package/dist/types.js +254 -2
  62. package/dist/utils/analysis-api.d.ts +108 -0
  63. package/dist/utils/analysis-api.js +194 -0
  64. package/dist/utils/config.js +1 -1
  65. package/dist/utils/git.d.ts +80 -0
  66. package/dist/utils/git.js +302 -0
  67. package/dist/utils/github-api.d.ts +83 -0
  68. package/dist/utils/github-api.js +266 -0
  69. package/dist/utils/hooks.d.ts +26 -0
  70. package/dist/utils/hooks.js +226 -0
  71. package/dist/utils/pending-state.d.ts +38 -0
  72. package/dist/utils/pending-state.js +86 -0
  73. package/dist/utils/secrets.js +3 -3
  74. package/dist/utils/skill.d.ts +1 -1
  75. package/dist/utils/skill.js +658 -1
  76. package/package.json +5 -3
@@ -0,0 +1,323 @@
1
+ # Prepare Codebase for Verification
2
+
3
+ > **PRO Feature**: Verification Flow requires a Haystack PRO subscription to run cloud sandboxes. Free users can still prepare their codebase — it will be ready when they upgrade. See https://haystackeditor.com/pricing for details.
4
+
5
+ **Your job**: Make this codebase easy to verify by adding semantic identifiers that the verification system can target.
6
+
7
+ The verification Planner needs to find UI elements by selectors. Generic selectors like `div` or `.flex` are useless. Your job is to add meaningful identifiers throughout the codebase.
8
+
9
+ ---
10
+
11
+ ## What to Add
12
+
13
+ ### 1. `aria-label` on Interactive Elements
14
+
15
+ Every clickable/interactive element should have an aria-label describing what it does:
16
+
17
+ ```tsx
18
+ // Before
19
+ <button onClick={onSave}>💾</button>
20
+ <button onClick={() => setOpen(true)}>
21
+ <MenuIcon />
22
+ </button>
23
+
24
+ // After
25
+ <button onClick={onSave} aria-label="Save document">💾</button>
26
+ <button onClick={() => setOpen(true)} aria-label="Open menu">
27
+ <MenuIcon />
28
+ </button>
29
+ ```
30
+
31
+ **Target elements:**
32
+ - Buttons (especially icon-only buttons)
33
+ - Links without descriptive text
34
+ - Toggle switches
35
+ - Dropdown triggers
36
+ - Modal open/close buttons
37
+ - Form submit buttons
38
+
39
+ ### 2. `data-testid` on Key Sections
40
+
41
+ Major UI sections should have data-testid for easy targeting:
42
+
43
+ ```tsx
44
+ // Before
45
+ <div className="flex flex-col p-4">
46
+ <h1>Dashboard</h1>
47
+ {/* content */}
48
+ </div>
49
+
50
+ // After
51
+ <div className="flex flex-col p-4" data-testid="dashboard-container">
52
+ <h1>Dashboard</h1>
53
+ {/* content */}
54
+ </div>
55
+ ```
56
+
57
+ **Target sections:**
58
+ - Page containers (dashboard, settings, profile)
59
+ - Navigation bars/sidebars
60
+ - Modal/dialog content
61
+ - Form containers
62
+ - Data tables/lists
63
+ - Card components
64
+ - Loading states
65
+ - Error states
66
+ - Empty states
67
+
68
+ ### 3. `role` Attributes for Semantic Structure
69
+
70
+ Add ARIA roles where HTML semantics aren't clear:
71
+
72
+ ```tsx
73
+ // Before
74
+ <div className="modal-overlay">
75
+ <div className="modal-content">
76
+
77
+ // After
78
+ <div className="modal-overlay" role="presentation">
79
+ <div className="modal-content" role="dialog" aria-modal="true">
80
+ ```
81
+
82
+ **Common roles:**
83
+ - `role="dialog"` - Modals/dialogs
84
+ - `role="navigation"` - Nav sections
85
+ - `role="main"` - Main content area
86
+ - `role="alert"` - Error/success messages
87
+ - `role="status"` - Loading indicators
88
+ - `role="tablist"`, `role="tab"`, `role="tabpanel"` - Tab interfaces
89
+
90
+ ### 4. State Indicators
91
+
92
+ Add attributes that indicate UI state:
93
+
94
+ ```tsx
95
+ // Before
96
+ <button onClick={toggle}>
97
+ {isOpen ? 'Close' : 'Open'}
98
+ </button>
99
+
100
+ // After
101
+ <button
102
+ onClick={toggle}
103
+ aria-expanded={isOpen}
104
+ aria-label={isOpen ? 'Close panel' : 'Open panel'}
105
+ >
106
+ {isOpen ? 'Close' : 'Open'}
107
+ </button>
108
+ ```
109
+
110
+ **State attributes:**
111
+ - `aria-expanded` - Collapsible sections
112
+ - `aria-selected` - Selected items in lists
113
+ - `aria-checked` - Checkboxes/toggles
114
+ - `aria-disabled` - Disabled elements
115
+ - `aria-busy` - Loading states
116
+ - `data-state="loading|error|success"` - Custom states
117
+
118
+ ### 5. Form Accessibility
119
+
120
+ Forms should have proper labels and descriptions:
121
+
122
+ ```tsx
123
+ // Before
124
+ <input type="email" placeholder="Email" />
125
+ <span className="text-red-500">{error}</span>
126
+
127
+ // After
128
+ <input
129
+ type="email"
130
+ placeholder="Email"
131
+ aria-label="Email address"
132
+ aria-describedby={error ? "email-error" : undefined}
133
+ aria-invalid={!!error}
134
+ />
135
+ {error && <span id="email-error" role="alert" className="text-red-500">{error}</span>}
136
+ ```
137
+
138
+ ---
139
+
140
+ ## Step 1: Scan for Missing Identifiers
141
+
142
+ ```bash
143
+ # Find buttons without aria-label
144
+ grep -rn "<button" src/ --include="*.tsx" | grep -v "aria-label" | head -20
145
+
146
+ # Find icon-only buttons (likely missing labels)
147
+ grep -rn "<button.*Icon\|<button.*>.*</.*Icon>" src/ --include="*.tsx" | head -20
148
+
149
+ # Find modals/dialogs without role
150
+ grep -rn "modal\|dialog\|Modal\|Dialog" src/ --include="*.tsx" | grep -v "role=" | head -20
151
+
152
+ # Find forms without proper labeling
153
+ grep -rn "<input\|<select\|<textarea" src/ --include="*.tsx" | grep -v "aria-label\|id=" | head -20
154
+
155
+ # Find major components (likely need data-testid)
156
+ ls src/components/ src/pages/ 2>/dev/null
157
+ ```
158
+
159
+ ---
160
+
161
+ ## Step 2: Prioritize by Impact
162
+
163
+ Focus on elements the verification system is most likely to need:
164
+
165
+ **High Priority (do first):**
166
+ 1. Navigation elements (header, sidebar, menu buttons)
167
+ 2. Primary actions (submit buttons, save buttons, CTAs)
168
+ 3. Modal triggers and dialogs
169
+ 4. Form inputs and submit buttons
170
+ 5. Page-level containers
171
+
172
+ **Medium Priority:**
173
+ 1. Toggle switches and checkboxes
174
+ 2. Dropdown menus
175
+ 3. Tab interfaces
176
+ 4. Cards and list items
177
+ 5. Loading/error states
178
+
179
+ **Lower Priority:**
180
+ 1. Decorative elements
181
+ 2. Static content sections
182
+ 3. Footer links
183
+
184
+ ---
185
+
186
+ ## Step 3: Add Identifiers Systematically
187
+
188
+ Go component by component. For each component:
189
+
190
+ 1. **Check the component's purpose** - What does it DO?
191
+ 2. **Add aria-label** to interactive elements describing the ACTION
192
+ 3. **Add data-testid** to the container if it's a major section
193
+ 4. **Add role** if the semantic HTML isn't clear
194
+ 5. **Add state attributes** if the component has dynamic states
195
+
196
+ ### Naming Conventions
197
+
198
+ **aria-label**: Describe the action, not the element
199
+ - ✅ `aria-label="Close modal"`
200
+ - ✅ `aria-label="Submit contact form"`
201
+ - ❌ `aria-label="Button"`
202
+ - ❌ `aria-label="Click here"`
203
+
204
+ **data-testid**: Use kebab-case, describe the section
205
+ - ✅ `data-testid="user-profile-card"`
206
+ - ✅ `data-testid="search-results-list"`
207
+ - ❌ `data-testid="div1"`
208
+ - ❌ `data-testid="container"`
209
+
210
+ ---
211
+
212
+ ## Step 4: Verify Coverage
213
+
214
+ After adding identifiers, check coverage:
215
+
216
+ ```bash
217
+ # Count aria-labels added
218
+ grep -r "aria-label" src/ --include="*.tsx" | wc -l
219
+
220
+ # Count data-testid added
221
+ grep -r "data-testid" src/ --include="*.tsx" | wc -l
222
+
223
+ # Count role attributes
224
+ grep -r "role=" src/ --include="*.tsx" | wc -l
225
+
226
+ # List all data-testid values (check for meaningful names)
227
+ grep -oh 'data-testid="[^"]*"' src/ -r --include="*.tsx" | sort -u
228
+ ```
229
+
230
+ ---
231
+
232
+ ## Step 5: Commit
233
+
234
+ ```bash
235
+ git add src/
236
+ git commit -m "Add accessibility attributes for verification
237
+
238
+ - Added aria-labels to interactive elements
239
+ - Added data-testid to major sections
240
+ - Added ARIA roles for semantic structure
241
+ - Added state indicators (aria-expanded, etc.)"
242
+ ```
243
+
244
+ ---
245
+
246
+ ## Quick Reference: Common Patterns
247
+
248
+ ### Icon Button
249
+ ```tsx
250
+ <button onClick={onAction} aria-label="Descriptive action name">
251
+ <Icon />
252
+ </button>
253
+ ```
254
+
255
+ ### Modal
256
+ ```tsx
257
+ <div role="dialog" aria-modal="true" aria-labelledby="modal-title" data-testid="settings-modal">
258
+ <h2 id="modal-title">Settings</h2>
259
+ <button onClick={onClose} aria-label="Close settings">×</button>
260
+ </div>
261
+ ```
262
+
263
+ ### Navigation
264
+ ```tsx
265
+ <nav aria-label="Main navigation" data-testid="main-nav">
266
+ <a href="/dashboard" aria-current={isActive ? "page" : undefined}>Dashboard</a>
267
+ </nav>
268
+ ```
269
+
270
+ ### Toggle
271
+ ```tsx
272
+ <button
273
+ onClick={toggle}
274
+ aria-pressed={isOn}
275
+ aria-label={`${isOn ? 'Disable' : 'Enable'} notifications`}
276
+ >
277
+ {isOn ? 'On' : 'Off'}
278
+ </button>
279
+ ```
280
+
281
+ ### Loading State
282
+ ```tsx
283
+ <div data-testid="content-area" aria-busy={isLoading}>
284
+ {isLoading ? (
285
+ <div role="status" aria-label="Loading content">
286
+ <Spinner />
287
+ </div>
288
+ ) : (
289
+ content
290
+ )}
291
+ </div>
292
+ ```
293
+
294
+ ### Form Field
295
+ ```tsx
296
+ <div data-testid="email-field">
297
+ <label htmlFor="email">Email</label>
298
+ <input
299
+ id="email"
300
+ type="email"
301
+ aria-describedby={error ? "email-error" : "email-hint"}
302
+ aria-invalid={!!error}
303
+ />
304
+ <span id="email-hint">We'll never share your email</span>
305
+ {error && <span id="email-error" role="alert">{error}</span>}
306
+ </div>
307
+ ```
308
+
309
+ ### Expandable Section
310
+ ```tsx
311
+ <div data-testid="faq-section">
312
+ <button
313
+ onClick={() => setExpanded(!expanded)}
314
+ aria-expanded={expanded}
315
+ aria-controls="faq-content"
316
+ >
317
+ FAQ
318
+ </button>
319
+ <div id="faq-content" hidden={!expanded}>
320
+ {content}
321
+ </div>
322
+ </div>
323
+ ```
@@ -0,0 +1,164 @@
1
+ # /secrets
2
+
3
+ Manage secrets for Haystack sandbox access to external services.
4
+
5
+ ## Purpose
6
+
7
+ Store sensitive values (API keys, database URLs, tokens) that your sandbox needs to access external services. Secrets are:
8
+ - **Zero-knowledge encrypted** - Encrypted locally before leaving your machine
9
+ - **Injected at runtime** - Available as environment variables in the sandbox
10
+ - **Scoped** - User, org, or repo level with cascading resolution
11
+
12
+ ## When to Use This
13
+
14
+ Use secrets when your project needs:
15
+ - Database connections (`DATABASE_URL`)
16
+ - API keys for external services (`STRIPE_SECRET_KEY`, `OPENAI_API_KEY`)
17
+ - Authentication tokens (`GITHUB_TOKEN`, `AWS_ACCESS_KEY_ID`)
18
+ - Any sensitive values referenced in `.haystack.json`
19
+
20
+ ## Workflow
21
+
22
+ ### 1. Check for Existing Secrets
23
+
24
+ First, see what secrets are already configured:
25
+
26
+ ```
27
+ Call haystack_secrets_list
28
+
29
+ If user wants org/repo scope:
30
+ haystack_secrets_list with scope="org" and scope_id="<org-name>"
31
+ haystack_secrets_list with scope="repo" and scope_id="<owner/repo>"
32
+ ```
33
+
34
+ ### 2. Set a Secret
35
+
36
+ ```
37
+ Call haystack_secrets_set with:
38
+ key: "DATABASE_URL" # Must be UPPERCASE_WITH_UNDERSCORES
39
+ value: "postgres://..." # The secret value (encrypted before sending)
40
+ scope: "user" # Optional: user (default), org, or repo
41
+ scope_id: "acme/myapp" # Required for org/repo scope
42
+ ```
43
+
44
+ ### 3. Reference in Config
45
+
46
+ Update `.haystack.json` to use the secret:
47
+
48
+ ```yaml
49
+ dev_server:
50
+ command: pnpm dev
51
+ env:
52
+ DATABASE_URL: $DATABASE_URL # Injected from secrets
53
+ STRIPE_KEY: $STRIPE_SECRET_KEY # Another secret
54
+
55
+ fixtures:
56
+ "/api/external":
57
+ source: "https://api.example.com/data"
58
+ headers:
59
+ Authorization: "Bearer $API_TOKEN" # Secret in headers
60
+ ```
61
+
62
+ ### 4. Delete a Secret
63
+
64
+ ```
65
+ Call haystack_secrets_delete with:
66
+ key: "OLD_API_KEY"
67
+ scope: "user" # Match the scope where it was set
68
+ scope_id: "..." # Required for org/repo
69
+ ```
70
+
71
+ ## Scopes Explained
72
+
73
+ | Scope | Who Can Access | Use Case |
74
+ |-------|----------------|----------|
75
+ | `user` | Only you | Personal API keys, dev credentials |
76
+ | `org` | All org members | Shared staging credentials |
77
+ | `repo` | Repo collaborators | Project-specific secrets |
78
+
79
+ **Resolution order** (first match wins):
80
+ 1. `repo` secrets (most specific)
81
+ 2. `org` secrets
82
+ 3. `user` secrets (fallback)
83
+
84
+ This allows repo-specific overrides of org defaults.
85
+
86
+ ## Examples
87
+
88
+ ### Add a Database URL
89
+
90
+ ```
91
+ User: "I need to connect to my Postgres database in the sandbox"
92
+
93
+ 1. Call haystack_secrets_set:
94
+ key: "DATABASE_URL"
95
+ value: "postgres://user:pass@host:5432/db"
96
+
97
+ 2. Update .haystack.json:
98
+ dev_server:
99
+ env:
100
+ DATABASE_URL: $DATABASE_URL
101
+
102
+ 3. Confirm: "Added DATABASE_URL. Your sandbox will now have access to your database."
103
+ ```
104
+
105
+ ### Add Stripe Keys for a Repo
106
+
107
+ ```
108
+ User: "Set up Stripe keys for this project"
109
+
110
+ 1. Call haystack_secrets_set:
111
+ key: "STRIPE_SECRET_KEY"
112
+ value: "sk_test_..."
113
+ scope: "repo"
114
+ scope_id: "acme/checkout-service"
115
+
116
+ 2. Call haystack_secrets_set:
117
+ key: "STRIPE_WEBHOOK_SECRET"
118
+ value: "whsec_..."
119
+ scope: "repo"
120
+ scope_id: "acme/checkout-service"
121
+
122
+ 3. Update .haystack.json with $STRIPE_SECRET_KEY and $STRIPE_WEBHOOK_SECRET
123
+ ```
124
+
125
+ ### Check What Secrets Are Configured
126
+
127
+ ```
128
+ User: "What secrets do I have?"
129
+
130
+ 1. Call haystack_secrets_list (user scope)
131
+ 2. Call haystack_secrets_list with scope="org", scope_id="acme" (if applicable)
132
+ 3. Call haystack_secrets_list with scope="repo", scope_id="acme/myapp" (if applicable)
133
+
134
+ Report: "You have 3 user secrets, 2 org secrets, and 1 repo secret configured."
135
+ ```
136
+
137
+ ## Tips
138
+
139
+ - **Key naming**: Use `UPPERCASE_WITH_UNDERSCORES` (e.g., `DATABASE_URL`, `API_SECRET_KEY`)
140
+ - **Never log secrets**: The MCP tools never return secret values, only keys
141
+ - **Rotation**: To rotate, just call `haystack_secrets_set` again with the new value
142
+ - **Cleanup**: Use `haystack_secrets_delete` to remove unused secrets
143
+
144
+ ## Troubleshooting
145
+
146
+ ### "Not authenticated"
147
+ Run `haystack login` first to authenticate with Haystack.
148
+
149
+ ### "scope_id required"
150
+ For `org` or `repo` scope, you must provide `scope_id`:
151
+ - Org: `scope_id: "my-org-name"`
152
+ - Repo: `scope_id: "owner/repo-name"`
153
+
154
+ ### "Invalid key format"
155
+ Secret keys must be:
156
+ - Start with a letter
157
+ - Uppercase letters only
158
+ - Underscores allowed
159
+ - Examples: `DATABASE_URL`, `AWS_ACCESS_KEY_ID`, `STRIPE_SECRET_KEY`
160
+
161
+ ### Secret not available in sandbox
162
+ 1. Check the secret exists: `haystack_secrets_list`
163
+ 2. Verify `.haystack.json` references it with `$KEY_NAME`
164
+ 3. Check resolution order - repo secrets override org/user secrets