@simonfestl/husky-cli 1.6.4 → 1.7.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 +42 -0
- package/dist/commands/agent.js +43 -0
- package/dist/commands/biz/qdrant.js +29 -0
- package/dist/commands/chat.js +16 -1
- package/dist/commands/completion.js +2 -2
- package/dist/commands/e2e.d.ts +11 -0
- package/dist/commands/e2e.js +773 -0
- package/dist/commands/infra.d.ts +11 -0
- package/dist/commands/infra.js +273 -0
- package/dist/commands/interactive/vm-sessions.js +2 -1
- package/dist/commands/pr.d.ts +11 -0
- package/dist/commands/pr.js +450 -0
- package/dist/commands/task.js +28 -5
- package/dist/commands/vm.js +274 -2
- package/dist/index.js +6 -0
- package/dist/lib/permissions.d.ts +17 -1
- package/dist/lib/permissions.js +27 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -111,6 +111,34 @@ husky vm update <session-id> --status approved
|
|
|
111
111
|
husky vm delete <session-id>
|
|
112
112
|
```
|
|
113
113
|
|
|
114
|
+
### E2E Testing (E2E Agent)
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# Run E2E tests for a task
|
|
118
|
+
husky e2e run <task-id>
|
|
119
|
+
husky e2e run <task-id> --secret ADMIN_PASSWORD --retries 2
|
|
120
|
+
husky e2e run <task-id> --env TEST_USER=admin --headed
|
|
121
|
+
|
|
122
|
+
# E2E Inbox (pending test requests)
|
|
123
|
+
husky e2e inbox # List all inbox messages
|
|
124
|
+
husky e2e inbox --status pending # Filter by status
|
|
125
|
+
husky e2e inbox --task <task-id> # Filter by task
|
|
126
|
+
|
|
127
|
+
# Watch for new E2E requests (auto-processing)
|
|
128
|
+
husky e2e watch --interval 30
|
|
129
|
+
husky e2e watch --once # Process once and exit
|
|
130
|
+
|
|
131
|
+
# Browser automation utilities
|
|
132
|
+
husky e2e screenshot <url> # Take screenshot
|
|
133
|
+
husky e2e screenshot <url> --upload # Upload to GCS
|
|
134
|
+
husky e2e record <url> # Record browser session
|
|
135
|
+
|
|
136
|
+
# Artifact management
|
|
137
|
+
husky e2e upload <file> --task <id> # Upload to GCS
|
|
138
|
+
husky e2e list --task <id> # List artifacts
|
|
139
|
+
husky e2e clean --older-than 7 # Clean old artifacts
|
|
140
|
+
```
|
|
141
|
+
|
|
114
142
|
### Business Strategy
|
|
115
143
|
|
|
116
144
|
```bash
|
|
@@ -296,6 +324,20 @@ husky --version
|
|
|
296
324
|
|
|
297
325
|
## Changelog
|
|
298
326
|
|
|
327
|
+
### v1.7.0 (2026-01-11) - E2E Agent Production Ready
|
|
328
|
+
|
|
329
|
+
**New Features:**
|
|
330
|
+
- `husky e2e inbox` - List E2E test requests from API
|
|
331
|
+
- `husky e2e watch` - Watch for and auto-process E2E requests
|
|
332
|
+
- `husky e2e run --secret` - Inject secrets from GCP Secret Manager
|
|
333
|
+
- `husky e2e run --env` - Set environment variables for tests
|
|
334
|
+
- `husky e2e run --retries` - Retry failed tests automatically
|
|
335
|
+
|
|
336
|
+
**Improvements:**
|
|
337
|
+
- All artifact URLs now use HTTPS
|
|
338
|
+
- Better error handling in E2E commands
|
|
339
|
+
- Updated permissions for e2e_agent role
|
|
340
|
+
|
|
299
341
|
### v1.1.0 (2026-01-09) - Unified Reply System
|
|
300
342
|
|
|
301
343
|
**New Features:**
|
package/dist/commands/agent.js
CHANGED
|
@@ -376,6 +376,49 @@ agentCommand
|
|
|
376
376
|
process.exit(1);
|
|
377
377
|
}
|
|
378
378
|
});
|
|
379
|
+
// husky agent qa-review
|
|
380
|
+
agentCommand
|
|
381
|
+
.command("qa-review <taskId>")
|
|
382
|
+
.description("Trigger QA review for a task")
|
|
383
|
+
.option("--pr <url>", "PR URL to review")
|
|
384
|
+
.option("--json", "Output as JSON")
|
|
385
|
+
.action(async (taskId, options) => {
|
|
386
|
+
const config = getConfig();
|
|
387
|
+
if (!config.apiUrl) {
|
|
388
|
+
console.error("Error: API URL not configured. Run: husky config set api-url <url>");
|
|
389
|
+
process.exit(1);
|
|
390
|
+
}
|
|
391
|
+
try {
|
|
392
|
+
const res = await fetch(`${config.apiUrl}/api/tasks/${taskId}/assign-reviewer`, {
|
|
393
|
+
method: "POST",
|
|
394
|
+
headers: {
|
|
395
|
+
"Content-Type": "application/json",
|
|
396
|
+
...(config.apiKey ? { "x-api-key": config.apiKey } : {}),
|
|
397
|
+
},
|
|
398
|
+
body: JSON.stringify({
|
|
399
|
+
prUrl: options.pr,
|
|
400
|
+
}),
|
|
401
|
+
});
|
|
402
|
+
if (!res.ok) {
|
|
403
|
+
const error = await res.text();
|
|
404
|
+
console.error(`Error assigning reviewer: ${res.status} - ${error}`);
|
|
405
|
+
process.exit(1);
|
|
406
|
+
}
|
|
407
|
+
const data = await res.json();
|
|
408
|
+
if (options.json) {
|
|
409
|
+
console.log(JSON.stringify(data, null, 2));
|
|
410
|
+
}
|
|
411
|
+
else {
|
|
412
|
+
console.log(`\n✓ Task ${taskId} assigned to reviewer`);
|
|
413
|
+
console.log(` Inbox ID: ${data.inboxId}`);
|
|
414
|
+
console.log(` Message: ${data.message}`);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
catch (error) {
|
|
418
|
+
console.error("Error triggering QA review:", error);
|
|
419
|
+
process.exit(1);
|
|
420
|
+
}
|
|
421
|
+
});
|
|
379
422
|
// husky agent register
|
|
380
423
|
agentCommand
|
|
381
424
|
.command("register")
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { Command } from "commander";
|
|
7
7
|
import { QdrantClient } from "../../lib/biz/index.js";
|
|
8
|
+
import { requireRole } from "../../lib/permissions.js";
|
|
8
9
|
export const qdrantCommand = new Command("qdrant")
|
|
9
10
|
.description("Vector database operations (Qdrant)");
|
|
10
11
|
// husky biz qdrant collections
|
|
@@ -167,4 +168,32 @@ qdrantCommand
|
|
|
167
168
|
process.exit(1);
|
|
168
169
|
}
|
|
169
170
|
});
|
|
171
|
+
// husky biz qdrant delete-collection <name> (ADMIN ONLY)
|
|
172
|
+
qdrantCommand
|
|
173
|
+
.command("delete-collection <name>")
|
|
174
|
+
.description("Delete an entire collection (ADMIN ONLY)")
|
|
175
|
+
.option("-f, --force", "Skip confirmation")
|
|
176
|
+
.action(async (name, options) => {
|
|
177
|
+
try {
|
|
178
|
+
// Require admin role
|
|
179
|
+
requireRole("admin");
|
|
180
|
+
const client = QdrantClient.fromConfig();
|
|
181
|
+
// Get collection info first
|
|
182
|
+
const info = await client.getCollection(name);
|
|
183
|
+
if (!options.force) {
|
|
184
|
+
console.log(`\n ⚠️ DANGER: About to DELETE collection "${name}"`);
|
|
185
|
+
console.log(` Points: ${info.pointsCount}`);
|
|
186
|
+
console.log(` Vectors: ${info.vectorsCount}`);
|
|
187
|
+
console.log(`\n This action is IRREVERSIBLE!`);
|
|
188
|
+
console.log(` Use --force to confirm deletion\n`);
|
|
189
|
+
process.exit(0);
|
|
190
|
+
}
|
|
191
|
+
await client.deleteCollection(name);
|
|
192
|
+
console.log(`✓ Deleted collection "${name}"`);
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
console.error("Error:", error.message);
|
|
196
|
+
process.exit(1);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
170
199
|
export default qdrantCommand;
|
package/dist/commands/chat.js
CHANGED
|
@@ -446,7 +446,22 @@ chatCommand
|
|
|
446
446
|
method: "POST",
|
|
447
447
|
headers: config.apiKey ? { "x-api-key": config.apiKey } : {},
|
|
448
448
|
});
|
|
449
|
-
|
|
449
|
+
// Add reaction to original message if messageName is available
|
|
450
|
+
if (msg.messageName) {
|
|
451
|
+
try {
|
|
452
|
+
await fetch(`${huskyApiUrl}/api/google-chat/messages/${encodeURIComponent(msg.messageName)}/react`, {
|
|
453
|
+
method: "POST",
|
|
454
|
+
headers: {
|
|
455
|
+
"Content-Type": "application/json",
|
|
456
|
+
...(config.apiKey ? { "x-api-key": config.apiKey } : {}),
|
|
457
|
+
},
|
|
458
|
+
body: JSON.stringify({ emoji: "✅" }),
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
catch {
|
|
462
|
+
// Reaction is optional - don't fail if it doesn't work
|
|
463
|
+
}
|
|
464
|
+
}
|
|
450
465
|
}
|
|
451
466
|
}
|
|
452
467
|
catch (error) {
|
|
@@ -135,7 +135,7 @@ ${subcommandCases}
|
|
|
135
135
|
return 0
|
|
136
136
|
;;
|
|
137
137
|
--agent)
|
|
138
|
-
COMPREPLY=( $(compgen -W "claude-code gemini-cli custom" -- \${cur}) )
|
|
138
|
+
COMPREPLY=( $(compgen -W "claude-code gemini-cli opencode custom" -- \${cur}) )
|
|
139
139
|
return 0
|
|
140
140
|
;;
|
|
141
141
|
--type)
|
|
@@ -268,7 +268,7 @@ complete -c husky -l project -d "Project ID" -r
|
|
|
268
268
|
complete -c husky -l status -d "Filter by status" -r -a "backlog in_progress review done pending running completed failed"
|
|
269
269
|
complete -c husky -l priority -d "Priority level" -r -a "low medium high urgent must should could wont"
|
|
270
270
|
complete -c husky -l assignee -d "Assignee type" -r -a "human llm unassigned"
|
|
271
|
-
complete -c husky -l agent -d "Agent type" -r -a "claude-code gemini-cli custom"
|
|
271
|
+
complete -c husky -l agent -d "Agent type" -r -a "claude-code gemini-cli opencode custom"
|
|
272
272
|
complete -c husky -l type -d "Type filter" -r -a "global project architecture patterns decisions learnings"
|
|
273
273
|
complete -c husky -l value-stream -d "Value stream" -r -a "order_to_delivery procure_to_pay returns_management product_lifecycle customer_service marketing_sales finance_accounting hr_operations it_operations general"
|
|
274
274
|
complete -c husky -l action -d "Action type" -r -a "manual semi_automated fully_automated"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* E2E Testing commands for E2E Agent
|
|
3
|
+
*
|
|
4
|
+
* Commands for browser automation and E2E testing:
|
|
5
|
+
* - husky e2e run <task-id> - Run E2E tests for a task
|
|
6
|
+
* - husky e2e record <url> - Record a browser session with Playwright
|
|
7
|
+
* - husky e2e upload <file> - Upload recording to GCS bucket husky-files-tigerv0
|
|
8
|
+
* - husky e2e screenshot <url> - Take a screenshot of a URL
|
|
9
|
+
*/
|
|
10
|
+
import { Command } from "commander";
|
|
11
|
+
export declare const e2eCommand: Command;
|