@haystackeditor/cli 0.7.2 → 0.8.1

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 (36) hide show
  1. package/README.md +59 -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 +35 -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 +5 -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/commands/config.d.ts +14 -0
  21. package/dist/commands/config.js +89 -0
  22. package/dist/commands/hooks.d.ts +17 -0
  23. package/dist/commands/hooks.js +269 -0
  24. package/dist/commands/init.d.ts +1 -1
  25. package/dist/commands/init.js +20 -239
  26. package/dist/commands/secrets.d.ts +15 -0
  27. package/dist/commands/secrets.js +83 -0
  28. package/dist/commands/skills.d.ts +8 -0
  29. package/dist/commands/skills.js +215 -0
  30. package/dist/index.js +107 -7
  31. package/dist/types.d.ts +32 -8
  32. package/dist/utils/hooks.d.ts +26 -0
  33. package/dist/utils/hooks.js +226 -0
  34. package/dist/utils/skill.d.ts +1 -1
  35. package/dist/utils/skill.js +481 -13
  36. package/package.json +2 -2
@@ -104,17 +104,32 @@ grep '"name":' .haystack.json
104
104
  }
105
105
  \`\`\`
106
106
 
107
- ### Finding Golden Inputs
107
+ ---
108
108
 
109
- For analysis/processing pipelines:
110
- - Pick a **small, stable PR** that won't change
111
- - Document what the expected output should be
112
- - Add it as a comment in the flow description
109
+ ## STOP - Confirm Golden URLs and Golden Data
113
110
 
114
- \`\`\`bash
115
- # Find a good golden PR (small, merged, stable)
116
- gh pr list --state merged --limit 10 --json number,title,changedFiles | jq '.[] | select(.changedFiles < 5)'
117
- \`\`\`
111
+ **If you identified backend services that need verification, you MUST ask the user with a proposed example:**
112
+
113
+ First, explore the codebase to find:
114
+ - Example inputs used in tests, scripts, or documentation
115
+ - Default/demo values in config files or environment variables
116
+ - IDs or URLs referenced in comments or READMEs
117
+
118
+ Then propose a specific example:
119
+
120
+ > I found these backend services that need verification:
121
+ > - **[service name]**: [what it does]
122
+ >
123
+ > For backend verification, I need **golden test data** - stable inputs that produce predictable output.
124
+ >
125
+ > **Based on what I found in the codebase, here's my suggestion:**
126
+ > - **Golden URL/Input**: \`[specific example you found, e.g., a test ID, demo endpoint, or sample file]\`
127
+ > - **Command**: \`[the command to run with this input]\`
128
+ > - **Expected Output**: \`[what success looks like based on the code]\`
129
+ >
130
+ > Does this look right? Or should I use different test data?
131
+
132
+ **Wait for the user to confirm or provide alternatives before adding backend flows.**
118
133
 
119
134
  ---
120
135
 
@@ -153,6 +168,92 @@ grep -r "https://" src/ --include="*.ts" --include="*.tsx" | grep -v node_module
153
168
 
154
169
  ---
155
170
 
171
+ ## STOP - Confirm Frontend Golden URLs
172
+
173
+ **Goldens are URLs with real staging data** - they let verification test pages that need actual content to render properly. You need MULTIPLE goldens to cover different scenarios.
174
+
175
+ **Before writing flows for dynamic routes, explore the codebase to find example data:**
176
+
177
+ 1. Check test files (\`*.test.ts\`, \`cypress/\`, \`playwright/\`) for example IDs/URLs
178
+ 2. Check README/docs for demo links or example usage
179
+ 3. Check seed data, fixtures, or mock files
180
+ 4. Check \`.env.example\` or config for staging URLs
181
+ 5. Check existing routes to understand the URL format
182
+
183
+ **Then propose MULTIPLE golden URLs (aim for 3-5) covering different scenarios:**
184
+
185
+ > I found these dynamic routes that need staging data to render:
186
+ >
187
+ > **[Route Name]** (\`/path/:param1/:param2\`)
188
+ >
189
+ > | Golden | URL | Why |
190
+ > |--------|-----|-----|
191
+ > | Large dataset | \`/path/example/large-123\` | Tests performance with many items |
192
+ > | Typical case | \`/path/example/medium-456\` | Common user scenario |
193
+ > | Edge case | \`/path/example/empty-789\` | Tests empty/minimal state |
194
+ > | Error state | \`/path/example/error-000\` | Tests error handling UI |
195
+ >
196
+ > **Evidence:**
197
+ > - Found \`large-123\` in \`cypress/fixtures/test-data.json\`
198
+ > - Found \`medium-456\` in README as demo example
199
+ > - Found \`empty-789\` in \`src/tests/edge-cases.test.ts\`
200
+ >
201
+ > Does this look right?
202
+ > 1. ✅ Yes, use these goldens
203
+ > 2. 🔄 Use different URLs (I'll provide them)
204
+
205
+ **Add goldens to \`verification.goldens\` in \`.haystack.json\` using this EXACT format:**
206
+
207
+ \`\`\`json
208
+ {
209
+ "verification": {
210
+ "goldens": {
211
+ "frontend": [
212
+ {
213
+ "id": "large-dataset",
214
+ "description": "100+ items - tests rendering performance",
215
+ "route": "/the/actual/url/with/data"
216
+ },
217
+ {
218
+ "id": "typical-case",
219
+ "description": "Standard 10-20 items",
220
+ "route": "/another/url/with/typical/data"
221
+ },
222
+ {
223
+ "id": "empty-state",
224
+ "description": "No items - tests empty state UI",
225
+ "route": "/url/that/shows/empty/state"
226
+ }
227
+ ],
228
+ "backend": [
229
+ {
230
+ "id": "golden-input-1",
231
+ "description": "Known-good input for pipeline testing",
232
+ "input": { "type": "github_pr", "value": "owner/repo#123" }
233
+ }
234
+ ]
235
+ },
236
+ "commands": [...]
237
+ }
238
+ }
239
+ \`\`\`
240
+
241
+ **DO NOT:**
242
+ - Ask the user what format to use - USE THIS FORMAT
243
+ - Put goldens at the top level - they go inside \`verification.goldens\`
244
+ - Use a flat object like \`{ "goldens": { "name": "url" } }\` - use the array format above
245
+ - Embed golden URLs only in flow steps - also add them to the goldens section for discoverability
246
+
247
+ **CRITICAL**:
248
+ - Propose MULTIPLE goldens (3-5), not just one
249
+ - Cover different scenarios: large, typical, empty, error states
250
+ - Always propose SPECIFIC URLs, never ask the user to freestyle
251
+ - Show WHERE you found the example data (file path, line if possible)
252
+ - Make sure URLs match the app's actual route format (check \`<Route path=\`)
253
+ - Wait for confirmation before writing flows with these URLs
254
+
255
+ ---
256
+
156
257
  ## Step 5: Write Flows
157
258
 
158
259
  Flows tell the Planner about your app's routes, UI elements, and user journeys.
@@ -596,6 +697,49 @@ The verification Planner needs to find UI elements by selectors. Generic selecto
596
697
 
597
698
  ---
598
699
 
700
+ ## ⚠️ CRITICAL RULE: Every Button MUST Have \`data-testid\` and \`aria-label\`
701
+
702
+ **This is non-negotiable.** Every \`<button>\` element in the codebase MUST have:
703
+ 1. \`data-testid="descriptive-name"\` - For automated testing/verification
704
+ 2. \`aria-label="Action description"\` - For accessibility AND verification
705
+
706
+ **Why?** The verification system clicks buttons by their \`data-testid\` or \`aria-label\`. Without these, buttons are invisible to automation. We learned this the hard way - a theme toggle button without these attributes broke our entire verification pipeline.
707
+
708
+ \`\`\`tsx
709
+ // ❌ WRONG - No identifiers, verification cannot click this
710
+ <button onClick={toggleTheme}>
711
+ <SunIcon />
712
+ </button>
713
+
714
+ // ✅ CORRECT - Both data-testid AND aria-label
715
+ <button
716
+ onClick={toggleTheme}
717
+ data-testid="theme-toggle"
718
+ aria-label="Toggle dark mode"
719
+ >
720
+ <SunIcon />
721
+ </button>
722
+ \`\`\`
723
+
724
+ **For button wrapper components**, pass through these props:
725
+ \`\`\`tsx
726
+ interface ButtonProps {
727
+ 'data-testid'?: string;
728
+ 'aria-label'?: string;
729
+ // ...other props
730
+ }
731
+
732
+ function IconButton({ 'data-testid': testId, 'aria-label': ariaLabel, ...props }: ButtonProps) {
733
+ return (
734
+ <button data-testid={testId} aria-label={ariaLabel} {...props}>
735
+ {props.children}
736
+ </button>
737
+ );
738
+ }
739
+ \`\`\`
740
+
741
+ ---
742
+
599
743
  ## What to Add
600
744
 
601
745
  ### 1. \`aria-label\` on Interactive Elements
@@ -727,13 +871,21 @@ Forms should have proper labels and descriptions:
727
871
 
728
872
  ## Step 1: Scan for Missing Identifiers
729
873
 
874
+ **Start with buttons - these are the most critical:**
875
+
730
876
  \`\`\`bash
731
- # Find buttons without aria-label
732
- grep -rn "<button" src/ --include="*.tsx" | grep -v "aria-label" | head -20
877
+ # CRITICAL: Find ALL buttons missing data-testid (fix ALL of these!)
878
+ grep -rn "<button" src/ --include="*.tsx" | grep -v "data-testid" | head -30
879
+
880
+ # CRITICAL: Find ALL buttons missing aria-label (fix ALL of these!)
881
+ grep -rn "<button" src/ --include="*.tsx" | grep -v "aria-label" | head -30
733
882
 
734
- # Find icon-only buttons (likely missing labels)
883
+ # Find icon-only buttons (MUST have aria-label since no visible text)
735
884
  grep -rn "<button.*Icon\\|<button.*>.*</.*Icon>" src/ --include="*.tsx" | head -20
736
885
 
886
+ # Find button wrapper components that need to pass through data-testid/aria-label
887
+ grep -rn "function.*Button\\|const.*Button.*=" src/ --include="*.tsx" | head -10
888
+
737
889
  # Find modals/dialogs without role
738
890
  grep -rn "modal\\|dialog\\|Modal\\|Dialog" src/ --include="*.tsx" | grep -v "role=" | head -20
739
891
 
@@ -744,6 +896,8 @@ grep -rn "<input\\|<select\\|<textarea" src/ --include="*.tsx" | grep -v "aria-l
744
896
  ls src/components/ src/pages/ 2>/dev/null
745
897
  \`\`\`
746
898
 
899
+ **Every button found without \`data-testid\` or \`aria-label\` MUST be fixed.**
900
+
747
901
  ---
748
902
 
749
903
  ## Step 2: Prioritize by Impact
@@ -916,31 +1070,345 @@ Follow .agents/skills/prepare-haystack.md to add accessibility attributes that m
916
1070
 
917
1071
  Run this BEFORE /setup-haystack to ensure your codebase has good selectors.
918
1072
  `;
1073
+ const SECRETS_COMMAND_CONTENT = `# Set Up Haystack Secrets
1074
+
1075
+ Follow .agents/skills/setup-haystack-secrets.md to configure secrets (API keys, credentials) for Haystack verification.
1076
+ `;
1077
+ const SECRETS_SKILL_CONTENT = `# Set Up Haystack Secrets
1078
+
1079
+ **Your job**: Help the user configure secrets needed for Haystack verification, especially LLM API keys for backend services.
1080
+
1081
+ ---
1082
+
1083
+ ## Step 1: Detect Services That Need Secrets
1084
+
1085
+ Scan the codebase to identify services that might need API keys or credentials:
1086
+
1087
+ \`\`\`bash
1088
+ # Find LLM/AI SDK usage
1089
+ grep -rn "openai\\|anthropic\\|bedrock\\|OPENAI_API_KEY\\|ANTHROPIC_API_KEY" --include="*.ts" --include="*.py" --include="*.js" | grep -v node_modules | head -20
1090
+
1091
+ # Find environment variable references
1092
+ grep -rn "process.env\\.\\|os.environ\\|env\\." --include="*.ts" --include="*.py" --include="*.js" | grep -v node_modules | grep -iE "key|secret|token|api" | head -20
1093
+
1094
+ # Check for .env.example or similar
1095
+ cat .env.example .env.sample 2>/dev/null || echo "No .env example found"
1096
+
1097
+ # Check existing secrets in .haystack.json
1098
+ grep -A10 '"secrets"' .haystack.json 2>/dev/null || echo "No secrets configured yet"
1099
+ \`\`\`
1100
+
1101
+ ---
1102
+
1103
+ ## Step 2: Categorize the Secrets Found
1104
+
1105
+ Group secrets by type and service:
1106
+
1107
+ | Category | Examples | Storage Recommendation |
1108
+ |----------|----------|------------------------|
1109
+ | **LLM API Keys** | \`OPENAI_API_KEY\`, \`ANTHROPIC_API_KEY\` | Haystack Secrets (encrypted) |
1110
+ | **Cloud Credentials** | \`AWS_ACCESS_KEY_ID\`, \`GCP_SERVICE_ACCOUNT\` | Use OIDC in CI, not static keys |
1111
+ | **Database** | \`DATABASE_URL\`, \`REDIS_URL\` | Haystack Secrets or passthrough |
1112
+ | **Third-party APIs** | \`STRIPE_KEY\`, \`SENDGRID_KEY\` | Haystack Secrets |
1113
+ | **Internal Services** | \`API_TOKEN\`, \`WEBHOOK_SECRET\` | Haystack Secrets |
1114
+
1115
+ ---
1116
+
1117
+ ## STOP - Present Findings and Ask User
1118
+
1119
+ **You MUST present what you found and ask the user before proceeding:**
1120
+
1121
+ > I scanned the codebase and found these services that may need secrets for verification:
1122
+ >
1123
+ > **Services detected:**
1124
+ > - [Service 1]: Uses \`OPENAI_API_KEY\` for [purpose]
1125
+ > - [Service 2]: Uses \`DATABASE_URL\` for [purpose]
1126
+ > - ...
1127
+ >
1128
+ > **Questions:**
1129
+ >
1130
+ > 1. **LLM API Keys**: Which provider do you use?
1131
+ > - OpenAI (\`OPENAI_API_KEY\`)
1132
+ > - Anthropic (\`ANTHROPIC_API_KEY\`)
1133
+ > - AWS Bedrock (use OIDC, no static keys needed)
1134
+ > - Other: ___
1135
+ >
1136
+ > 2. **For each secret**, should verification use:
1137
+ > - **Real credentials** (stored securely in Haystack Secrets)
1138
+ > - **Test/sandbox credentials** (separate keys for verification only)
1139
+ > - **Mock/skip** (service not needed for visual verification)
1140
+ >
1141
+ > 3. **Do you have separate test credentials?**
1142
+ > - Yes, I have sandbox/test API keys
1143
+ > - No, I'll use production keys (with usage limits)
1144
+ > - I need to create test credentials first
1145
+
1146
+ **Wait for the user's response before continuing.**
1147
+
1148
+ ---
1149
+
1150
+ ## Step 3: Configure Secrets in .haystack.json
1151
+
1152
+ Based on user's answers, add secrets to the config:
1153
+
1154
+ \`\`\`json
1155
+ {
1156
+ "secrets": {
1157
+ "OPENAI_API_KEY": {
1158
+ "description": "OpenAI API key for analysis service",
1159
+ "required": true,
1160
+ "services": ["analysis"]
1161
+ },
1162
+ "DATABASE_URL": {
1163
+ "description": "PostgreSQL connection string",
1164
+ "required": false,
1165
+ "services": ["api"]
1166
+ }
1167
+ }
1168
+ }
1169
+ \`\`\`
1170
+
1171
+ ### Secret Properties
1172
+
1173
+ | Property | Description |
1174
+ |----------|-------------|
1175
+ | \`description\` | What this secret is for (shown to user) |
1176
+ | \`required\` | If \`true\`, verification fails without it |
1177
+ | \`services\` | Which services need this secret (for scoping) |
1178
+
1179
+ ---
1180
+
1181
+ ## Step 4: Guide User to Store Secrets
1182
+
1183
+ ### Option A: Haystack CLI (Recommended)
1184
+
1185
+ \`\`\`bash
1186
+ # Store secrets securely (encrypted at rest)
1187
+ npx @haystackeditor/cli secrets set OPENAI_API_KEY
1188
+ # Prompts for value, never shown in terminal history
1189
+
1190
+ # Verify it's stored
1191
+ npx @haystackeditor/cli secrets list
1192
+ \`\`\`
1193
+
1194
+ ### Option B: Environment Variables (Local Development)
1195
+
1196
+ \`\`\`bash
1197
+ # Add to .env.local (gitignored)
1198
+ echo 'OPENAI_API_KEY=sk-...' >> .env.local
1199
+
1200
+ # Make sure .env.local is in .gitignore
1201
+ grep -q '.env.local' .gitignore || echo '.env.local' >> .gitignore
1202
+ \`\`\`
1203
+
1204
+ ### Option C: CI/CD Secrets (GitHub Actions)
1205
+
1206
+ \`\`\`yaml
1207
+ # .github/workflows/haystack.yml
1208
+ env:
1209
+ OPENAI_API_KEY: \${{ secrets.OPENAI_API_KEY }}
1210
+ \`\`\`
1211
+
1212
+ ---
1213
+
1214
+ ## Step 5: Handle Cloud Provider Credentials
1215
+
1216
+ **Never store long-lived cloud credentials.** Use OIDC instead:
1217
+
1218
+ ### AWS (Bedrock, S3, etc.)
1219
+
1220
+ \`\`\`yaml
1221
+ # GitHub Actions with OIDC - no secrets needed!
1222
+ jobs:
1223
+ verify:
1224
+ permissions:
1225
+ id-token: write
1226
+ contents: read
1227
+ steps:
1228
+ - uses: aws-actions/configure-aws-credentials@v4
1229
+ with:
1230
+ role-to-assume: arn:aws:iam::123456789:role/haystack-verify
1231
+ aws-region: us-west-2
1232
+ \`\`\`
1233
+
1234
+ ### GCP (Vertex AI, Cloud Storage, etc.)
1235
+
1236
+ \`\`\`yaml
1237
+ jobs:
1238
+ verify:
1239
+ permissions:
1240
+ id-token: write
1241
+ steps:
1242
+ - uses: google-github-actions/auth@v2
1243
+ with:
1244
+ workload_identity_provider: projects/123/locations/global/...
1245
+ service_account: haystack-verify@project.iam.gserviceaccount.com
1246
+ \`\`\`
1247
+
1248
+ ---
1249
+
1250
+ ## Step 6: Test Secret Access
1251
+
1252
+ After storing secrets, verify they're accessible:
1253
+
1254
+ \`\`\`bash
1255
+ # Test locally
1256
+ npx @haystackeditor/cli secrets test
1257
+
1258
+ # Or check manually
1259
+ npx @haystackeditor/cli secrets get OPENAI_API_KEY --masked
1260
+ # Shows: sk-...xxxx (last 4 chars only)
1261
+ \`\`\`
1262
+
1263
+ ---
1264
+
1265
+ ## Step 7: Update .haystack.json
1266
+
1267
+ Add the secrets configuration:
1268
+
1269
+ \`\`\`bash
1270
+ # Show what to add
1271
+ cat << 'EOF'
1272
+ Add this to your .haystack.json:
1273
+
1274
+ {
1275
+ "secrets": {
1276
+ "OPENAI_API_KEY": {
1277
+ "description": "OpenAI API key for LLM analysis",
1278
+ "required": true
1279
+ }
1280
+ }
1281
+ }
1282
+ EOF
1283
+ \`\`\`
1284
+
1285
+ ---
1286
+
1287
+ ## Common Patterns
1288
+
1289
+ ### Analysis Pipeline with LLM
1290
+
1291
+ \`\`\`json
1292
+ {
1293
+ "services": {
1294
+ "analysis": {
1295
+ "root": "packages/analysis",
1296
+ "command": "pnpm start",
1297
+ "env": {
1298
+ "PR_IDENTIFIER": "$PR_IDENTIFIER"
1299
+ }
1300
+ }
1301
+ },
1302
+ "secrets": {
1303
+ "OPENAI_API_KEY": {
1304
+ "description": "OpenAI API for code analysis",
1305
+ "required": true,
1306
+ "services": ["analysis"]
1307
+ }
1308
+ }
1309
+ }
1310
+ \`\`\`
1311
+
1312
+ ### Multiple LLM Providers
1313
+
1314
+ \`\`\`json
1315
+ {
1316
+ "secrets": {
1317
+ "OPENAI_API_KEY": {
1318
+ "description": "OpenAI for embeddings",
1319
+ "services": ["search"]
1320
+ },
1321
+ "ANTHROPIC_API_KEY": {
1322
+ "description": "Claude for code review",
1323
+ "services": ["review"]
1324
+ }
1325
+ }
1326
+ }
1327
+ \`\`\`
1328
+
1329
+ ### Database + API Keys
1330
+
1331
+ \`\`\`json
1332
+ {
1333
+ "secrets": {
1334
+ "DATABASE_URL": {
1335
+ "description": "PostgreSQL for test database",
1336
+ "required": true
1337
+ },
1338
+ "STRIPE_TEST_KEY": {
1339
+ "description": "Stripe test mode key",
1340
+ "required": false
1341
+ }
1342
+ }
1343
+ }
1344
+ \`\`\`
1345
+
1346
+ ---
1347
+
1348
+ ## Security Best Practices
1349
+
1350
+ 1. **Use test/sandbox credentials** when available (OpenAI, Stripe, etc. offer these)
1351
+ 2. **Set usage limits** on API keys used for verification
1352
+ 3. **Never commit secrets** - use \`.gitignore\` for \`.env.local\`
1353
+ 4. **Rotate regularly** - especially if verification runs on external PRs
1354
+ 5. **Scope narrowly** - use \`services\` array to limit which services see which secrets
1355
+ 6. **Prefer OIDC** for cloud providers instead of static credentials
1356
+
1357
+ ---
1358
+
1359
+ ## Troubleshooting
1360
+
1361
+ ### "Secret not found" errors
1362
+
1363
+ \`\`\`bash
1364
+ # Check if secret is stored
1365
+ npx @haystackeditor/cli secrets list
1366
+
1367
+ # Check if it's in the right scope
1368
+ npx @haystackeditor/cli secrets get SECRET_NAME --show-metadata
1369
+ \`\`\`
1370
+
1371
+ ### "Permission denied" for cloud resources
1372
+
1373
+ - Verify OIDC trust policy includes your repo
1374
+ - Check IAM role has required permissions
1375
+ - Ensure GitHub Actions has \`id-token: write\` permission
1376
+
1377
+ ### Secrets work locally but not in CI
1378
+
1379
+ - Secrets stored via CLI are user-scoped by default
1380
+ - For CI, use GitHub Secrets or organization-level Haystack secrets
1381
+ - Check \`npx @haystackeditor/cli secrets list --scope=org\`
1382
+ `;
919
1383
  export async function createSkillFile() {
920
1384
  const skillDir = path.join(process.cwd(), '.agents', 'skills');
921
1385
  const setupPath = path.join(skillDir, 'setup-haystack.md');
922
1386
  const refPath = path.join(skillDir, 'haystack-reference.md');
923
1387
  const prepPath = path.join(skillDir, 'prepare-haystack.md');
1388
+ const secretsPath = path.join(skillDir, 'setup-haystack-secrets.md');
924
1389
  // Create directory if needed
925
1390
  await fs.mkdir(skillDir, { recursive: true });
926
1391
  // Write all skill files
927
1392
  await fs.writeFile(setupPath, SKILL_CONTENT, 'utf-8');
928
1393
  await fs.writeFile(refPath, REFERENCE_CONTENT, 'utf-8');
929
1394
  await fs.writeFile(prepPath, PREPARE_VERIFICATION_CONTENT, 'utf-8');
1395
+ await fs.writeFile(secretsPath, SECRETS_SKILL_CONTENT, 'utf-8');
930
1396
  return setupPath;
931
1397
  }
932
1398
  /**
933
1399
  * Create the .claude/commands/ files for Claude Code slash commands
934
- * Users can invoke with /setup-haystack or /prepare-haystack
1400
+ * Users can invoke with /setup-haystack, /prepare-haystack, or /setup-haystack-secrets
935
1401
  */
936
1402
  export async function createClaudeCommand() {
937
1403
  const commandDir = path.join(process.cwd(), '.claude', 'commands');
938
1404
  const setupPath = path.join(commandDir, 'setup-haystack.md');
939
1405
  const prepPath = path.join(commandDir, 'prepare-haystack.md');
1406
+ const secretsPath = path.join(commandDir, 'setup-haystack-secrets.md');
940
1407
  // Create directory if needed
941
1408
  await fs.mkdir(commandDir, { recursive: true });
942
1409
  // Write command files
943
1410
  await fs.writeFile(setupPath, CLAUDE_COMMAND_CONTENT, 'utf-8');
944
1411
  await fs.writeFile(prepPath, PREPARE_HAYSTACK_COMMAND, 'utf-8');
1412
+ await fs.writeFile(secretsPath, SECRETS_COMMAND_CONTENT, 'utf-8');
945
1413
  return setupPath;
946
1414
  }
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@haystackeditor/cli",
3
- "version": "0.7.2",
3
+ "version": "0.8.1",
4
4
  "description": "Set up Haystack verification for your project",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "haystack": "./dist/index.js"
8
8
  },
9
9
  "scripts": {
10
- "build": "tsc",
10
+ "build": "tsc && rm -rf dist/assets && cp -r src/assets dist/assets",
11
11
  "dev": "tsc --watch",
12
12
  "start": "node dist/index.js",
13
13
  "prepublishOnly": "npm run build"