@simonfestl/husky-cli 0.3.0 → 0.5.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.
- package/README.md +228 -58
- package/dist/commands/changelog.d.ts +2 -0
- package/dist/commands/changelog.js +401 -0
- package/dist/commands/completion.d.ts +2 -0
- package/dist/commands/completion.js +400 -0
- package/dist/commands/config.d.ts +1 -0
- package/dist/commands/config.js +101 -1
- package/dist/commands/department.d.ts +2 -0
- package/dist/commands/department.js +240 -0
- package/dist/commands/explain.d.ts +2 -0
- package/dist/commands/explain.js +411 -0
- package/dist/commands/idea.d.ts +2 -0
- package/dist/commands/idea.js +340 -0
- package/dist/commands/interactive.d.ts +1 -0
- package/dist/commands/interactive.js +1397 -0
- package/dist/commands/jules.d.ts +2 -0
- package/dist/commands/jules.js +593 -0
- package/dist/commands/process.d.ts +2 -0
- package/dist/commands/process.js +289 -0
- package/dist/commands/project.d.ts +2 -0
- package/dist/commands/project.js +473 -0
- package/dist/commands/roadmap.js +318 -0
- package/dist/commands/settings.d.ts +2 -0
- package/dist/commands/settings.js +153 -0
- package/dist/commands/strategy.d.ts +2 -0
- package/dist/commands/strategy.js +706 -0
- package/dist/commands/task.js +244 -1
- package/dist/commands/vm-config.d.ts +2 -0
- package/dist/commands/vm-config.js +318 -0
- package/dist/commands/vm.d.ts +2 -0
- package/dist/commands/vm.js +621 -0
- package/dist/commands/workflow.d.ts +2 -0
- package/dist/commands/workflow.js +545 -0
- package/dist/index.js +35 -2
- package/package.json +8 -2
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { getConfig } from "./config.js";
|
|
3
|
+
export const departmentCommand = new Command("department")
|
|
4
|
+
.description("Manage departments");
|
|
5
|
+
// Helper: Ensure API is configured
|
|
6
|
+
function ensureConfig() {
|
|
7
|
+
const config = getConfig();
|
|
8
|
+
if (!config.apiUrl) {
|
|
9
|
+
console.error("Error: API URL not configured. Run: husky config set api-url <url>");
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
return config;
|
|
13
|
+
}
|
|
14
|
+
// husky department list
|
|
15
|
+
departmentCommand
|
|
16
|
+
.command("list")
|
|
17
|
+
.description("List all departments")
|
|
18
|
+
.option("--json", "Output as JSON")
|
|
19
|
+
.action(async (options) => {
|
|
20
|
+
const config = ensureConfig();
|
|
21
|
+
try {
|
|
22
|
+
const res = await fetch(`${config.apiUrl}/api/departments`, {
|
|
23
|
+
headers: config.apiKey ? { "x-api-key": config.apiKey } : {},
|
|
24
|
+
});
|
|
25
|
+
if (!res.ok) {
|
|
26
|
+
throw new Error(`API error: ${res.status}`);
|
|
27
|
+
}
|
|
28
|
+
const departments = await res.json();
|
|
29
|
+
if (options.json) {
|
|
30
|
+
console.log(JSON.stringify(departments, null, 2));
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
printDepartments(departments);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
console.error("Error fetching departments:", error);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
// husky department create <name>
|
|
42
|
+
departmentCommand
|
|
43
|
+
.command("create <name>")
|
|
44
|
+
.description("Create a new department")
|
|
45
|
+
.option("-d, --description <description>", "Department description")
|
|
46
|
+
.option("--json", "Output as JSON")
|
|
47
|
+
.action(async (name, options) => {
|
|
48
|
+
const config = ensureConfig();
|
|
49
|
+
try {
|
|
50
|
+
const res = await fetch(`${config.apiUrl}/api/departments`, {
|
|
51
|
+
method: "POST",
|
|
52
|
+
headers: {
|
|
53
|
+
"Content-Type": "application/json",
|
|
54
|
+
...(config.apiKey ? { "x-api-key": config.apiKey } : {}),
|
|
55
|
+
},
|
|
56
|
+
body: JSON.stringify({
|
|
57
|
+
name,
|
|
58
|
+
description: options.description,
|
|
59
|
+
}),
|
|
60
|
+
});
|
|
61
|
+
if (!res.ok) {
|
|
62
|
+
throw new Error(`API error: ${res.status}`);
|
|
63
|
+
}
|
|
64
|
+
const department = await res.json();
|
|
65
|
+
if (options.json) {
|
|
66
|
+
console.log(JSON.stringify(department, null, 2));
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
console.log(`✓ Created department: ${department.name}`);
|
|
70
|
+
console.log(` ID: ${department.id}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.error("Error creating department:", error);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
// husky department get <id>
|
|
79
|
+
departmentCommand
|
|
80
|
+
.command("get <id>")
|
|
81
|
+
.description("Get department details")
|
|
82
|
+
.option("--json", "Output as JSON")
|
|
83
|
+
.action(async (id, options) => {
|
|
84
|
+
const config = ensureConfig();
|
|
85
|
+
try {
|
|
86
|
+
const res = await fetch(`${config.apiUrl}/api/departments/${id}`, {
|
|
87
|
+
headers: config.apiKey ? { "x-api-key": config.apiKey } : {},
|
|
88
|
+
});
|
|
89
|
+
if (!res.ok) {
|
|
90
|
+
if (res.status === 404) {
|
|
91
|
+
console.error(`Error: Department ${id} not found`);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
console.error(`Error: API returned ${res.status}`);
|
|
95
|
+
}
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
const department = await res.json();
|
|
99
|
+
if (options.json) {
|
|
100
|
+
console.log(JSON.stringify(department, null, 2));
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
printDepartmentDetail(department);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
console.error("Error fetching department:", error);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
// husky department update <id>
|
|
112
|
+
departmentCommand
|
|
113
|
+
.command("update <id>")
|
|
114
|
+
.description("Update a department")
|
|
115
|
+
.option("-n, --name <name>", "New name")
|
|
116
|
+
.option("-d, --description <description>", "New description")
|
|
117
|
+
.option("--json", "Output as JSON")
|
|
118
|
+
.action(async (id, options) => {
|
|
119
|
+
const config = ensureConfig();
|
|
120
|
+
// Build update payload
|
|
121
|
+
const updateData = {};
|
|
122
|
+
if (options.name) {
|
|
123
|
+
updateData.name = options.name;
|
|
124
|
+
}
|
|
125
|
+
if (options.description) {
|
|
126
|
+
updateData.description = options.description;
|
|
127
|
+
}
|
|
128
|
+
if (Object.keys(updateData).length === 0) {
|
|
129
|
+
console.error("Error: No update options provided. Use -n or -d");
|
|
130
|
+
process.exit(1);
|
|
131
|
+
}
|
|
132
|
+
try {
|
|
133
|
+
const res = await fetch(`${config.apiUrl}/api/departments/${id}`, {
|
|
134
|
+
method: "PATCH",
|
|
135
|
+
headers: {
|
|
136
|
+
"Content-Type": "application/json",
|
|
137
|
+
...(config.apiKey ? { "x-api-key": config.apiKey } : {}),
|
|
138
|
+
},
|
|
139
|
+
body: JSON.stringify(updateData),
|
|
140
|
+
});
|
|
141
|
+
if (!res.ok) {
|
|
142
|
+
if (res.status === 404) {
|
|
143
|
+
console.error(`Error: Department ${id} not found`);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
const errorBody = await res.json().catch(() => ({}));
|
|
147
|
+
console.error(`Error: API returned ${res.status}`, errorBody.error || "");
|
|
148
|
+
}
|
|
149
|
+
process.exit(1);
|
|
150
|
+
}
|
|
151
|
+
const department = await res.json();
|
|
152
|
+
if (options.json) {
|
|
153
|
+
console.log(JSON.stringify(department, null, 2));
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
console.log(`✓ Department updated successfully`);
|
|
157
|
+
console.log(` Name: ${department.name}`);
|
|
158
|
+
if (department.description) {
|
|
159
|
+
console.log(` Description: ${department.description}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
console.error("Error updating department:", error);
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
// husky department delete <id>
|
|
169
|
+
departmentCommand
|
|
170
|
+
.command("delete <id>")
|
|
171
|
+
.description("Delete a department")
|
|
172
|
+
.option("--force", "Skip confirmation")
|
|
173
|
+
.option("--json", "Output as JSON")
|
|
174
|
+
.action(async (id, options) => {
|
|
175
|
+
const config = ensureConfig();
|
|
176
|
+
if (!options.force) {
|
|
177
|
+
console.log("Warning: This will permanently delete the department.");
|
|
178
|
+
console.log("Use --force to confirm deletion.");
|
|
179
|
+
process.exit(1);
|
|
180
|
+
}
|
|
181
|
+
try {
|
|
182
|
+
const res = await fetch(`${config.apiUrl}/api/departments/${id}`, {
|
|
183
|
+
method: "DELETE",
|
|
184
|
+
headers: config.apiKey ? { "x-api-key": config.apiKey } : {},
|
|
185
|
+
});
|
|
186
|
+
if (!res.ok) {
|
|
187
|
+
if (res.status === 404) {
|
|
188
|
+
console.error(`Error: Department ${id} not found`);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
console.error(`Error: API returned ${res.status}`);
|
|
192
|
+
}
|
|
193
|
+
process.exit(1);
|
|
194
|
+
}
|
|
195
|
+
if (options.json) {
|
|
196
|
+
console.log(JSON.stringify({ deleted: true, id }, null, 2));
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
console.log(`✓ Department deleted`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
console.error("Error deleting department:", error);
|
|
204
|
+
process.exit(1);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
function printDepartments(departments) {
|
|
208
|
+
if (departments.length === 0) {
|
|
209
|
+
console.log("\n No departments found.");
|
|
210
|
+
console.log(" Create one with: husky department create <name>\n");
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
console.log("\n DEPARTMENTS");
|
|
214
|
+
console.log(" " + "─".repeat(70));
|
|
215
|
+
console.log(` ${"ID".padEnd(24)} ${"NAME".padEnd(25)} DESCRIPTION`);
|
|
216
|
+
console.log(" " + "─".repeat(70));
|
|
217
|
+
for (const dept of departments) {
|
|
218
|
+
const truncatedName = dept.name.length > 23 ? dept.name.substring(0, 20) + "..." : dept.name;
|
|
219
|
+
const description = dept.description
|
|
220
|
+
? (dept.description.length > 30 ? dept.description.substring(0, 27) + "..." : dept.description)
|
|
221
|
+
: "-";
|
|
222
|
+
console.log(` ${dept.id.padEnd(24)} ${truncatedName.padEnd(25)} ${description}`);
|
|
223
|
+
}
|
|
224
|
+
console.log(" " + "─".repeat(70));
|
|
225
|
+
console.log(`\n Total: ${departments.length} departments`);
|
|
226
|
+
console.log("");
|
|
227
|
+
}
|
|
228
|
+
function printDepartmentDetail(department) {
|
|
229
|
+
console.log(`\n Department: ${department.name}`);
|
|
230
|
+
console.log(" " + "─".repeat(50));
|
|
231
|
+
console.log(` ID: ${department.id}`);
|
|
232
|
+
console.log(` Name: ${department.name}`);
|
|
233
|
+
if (department.description) {
|
|
234
|
+
console.log(` Description:`);
|
|
235
|
+
console.log(` ${department.description}`);
|
|
236
|
+
}
|
|
237
|
+
console.log(` Created: ${new Date(department.createdAt).toLocaleString()}`);
|
|
238
|
+
console.log(` Updated: ${new Date(department.updatedAt).toLocaleString()}`);
|
|
239
|
+
console.log("");
|
|
240
|
+
}
|
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
export const explainCommand = new Command("explain")
|
|
3
|
+
.description("Explain CLI commands for AI agents")
|
|
4
|
+
.argument("[command]", "Command to explain (task, roadmap, changelog, config, agent)")
|
|
5
|
+
.action((command) => {
|
|
6
|
+
if (!command) {
|
|
7
|
+
printOverview();
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
switch (command.toLowerCase()) {
|
|
11
|
+
case "task":
|
|
12
|
+
printTaskHelp();
|
|
13
|
+
break;
|
|
14
|
+
case "roadmap":
|
|
15
|
+
printRoadmapHelp();
|
|
16
|
+
break;
|
|
17
|
+
case "changelog":
|
|
18
|
+
printChangelogHelp();
|
|
19
|
+
break;
|
|
20
|
+
case "config":
|
|
21
|
+
printConfigHelp();
|
|
22
|
+
break;
|
|
23
|
+
case "agent":
|
|
24
|
+
printAgentWorkflowHelp();
|
|
25
|
+
break;
|
|
26
|
+
default:
|
|
27
|
+
console.log(`Unknown command: ${command}`);
|
|
28
|
+
console.log("Available: task, roadmap, changelog, config, agent");
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
function printOverview() {
|
|
34
|
+
console.log(`
|
|
35
|
+
HUSKY CLI - AI Task Orchestration
|
|
36
|
+
|
|
37
|
+
Available Commands:
|
|
38
|
+
task Task management (list, create, start, complete, qa)
|
|
39
|
+
roadmap Roadmap & feature planning
|
|
40
|
+
changelog Generate changelogs from commits
|
|
41
|
+
config Configure API URL and key
|
|
42
|
+
|
|
43
|
+
Quick Start:
|
|
44
|
+
1. Configure: husky config set api-url <dashboard-url>
|
|
45
|
+
2. Set key: husky config set api-key <key>
|
|
46
|
+
3. Get task: husky task get --id <id>
|
|
47
|
+
4. Work: husky task status "Working on..."
|
|
48
|
+
5. Complete: husky task complete --pr <url>
|
|
49
|
+
|
|
50
|
+
For detailed help on a command: husky explain <command>
|
|
51
|
+
For agent workflow guidance: husky explain agent
|
|
52
|
+
|
|
53
|
+
Environment Variables:
|
|
54
|
+
HUSKY_TASK_ID Default task ID for commands (avoids --id flag)
|
|
55
|
+
`);
|
|
56
|
+
}
|
|
57
|
+
function printTaskHelp() {
|
|
58
|
+
console.log(`
|
|
59
|
+
HUSKY TASK COMMANDS
|
|
60
|
+
|
|
61
|
+
Task ID can be passed via --id flag or HUSKY_TASK_ID environment variable.
|
|
62
|
+
|
|
63
|
+
LIST TASKS
|
|
64
|
+
husky task list
|
|
65
|
+
husky task list --status backlog
|
|
66
|
+
husky task list --status in_progress
|
|
67
|
+
|
|
68
|
+
Options:
|
|
69
|
+
-s, --status <status> Filter by status (backlog, in_progress, review, done)
|
|
70
|
+
|
|
71
|
+
GET TASK DETAILS
|
|
72
|
+
husky task get --id <id>
|
|
73
|
+
husky task get --id <id> --json
|
|
74
|
+
|
|
75
|
+
Options:
|
|
76
|
+
--id <id> Task ID (or set HUSKY_TASK_ID)
|
|
77
|
+
--json Output as JSON (useful for parsing)
|
|
78
|
+
|
|
79
|
+
CREATE TASK
|
|
80
|
+
husky task create "Task title"
|
|
81
|
+
husky task create "Task title" -d "Description" --project proj123
|
|
82
|
+
|
|
83
|
+
Options:
|
|
84
|
+
-d, --description <desc> Task description
|
|
85
|
+
--project <projectId> Project ID
|
|
86
|
+
--path <path> Path in project
|
|
87
|
+
-p, --priority <priority> Priority: low, medium, high (default: medium)
|
|
88
|
+
|
|
89
|
+
START TASK
|
|
90
|
+
husky task start <id>
|
|
91
|
+
|
|
92
|
+
Marks task as in_progress and assigns to agent.
|
|
93
|
+
|
|
94
|
+
REPORT STATUS
|
|
95
|
+
husky task status "Working on feature X"
|
|
96
|
+
husky task status "Fixing tests" --id <id>
|
|
97
|
+
|
|
98
|
+
Options:
|
|
99
|
+
--id <id> Task ID (or set HUSKY_TASK_ID)
|
|
100
|
+
|
|
101
|
+
Use this to report progress during task execution.
|
|
102
|
+
|
|
103
|
+
SUBMIT PLAN
|
|
104
|
+
husky task plan --summary "Implementation plan"
|
|
105
|
+
husky task plan --file plan.md
|
|
106
|
+
husky task plan --steps "step1,step2,step3"
|
|
107
|
+
echo "Plan content" | husky task plan --stdin
|
|
108
|
+
|
|
109
|
+
Options:
|
|
110
|
+
--id <id> Task ID (or set HUSKY_TASK_ID)
|
|
111
|
+
--summary <text> Plan summary
|
|
112
|
+
--file <path> Read plan from file
|
|
113
|
+
--stdin Read plan from stdin
|
|
114
|
+
--steps <steps> Comma-separated steps
|
|
115
|
+
|
|
116
|
+
WAIT FOR APPROVAL
|
|
117
|
+
husky task wait-approval
|
|
118
|
+
husky task wait-approval --timeout 3600
|
|
119
|
+
|
|
120
|
+
Options:
|
|
121
|
+
--id <id> Task ID (or set HUSKY_TASK_ID)
|
|
122
|
+
--timeout <seconds> Timeout in seconds (default: 1800)
|
|
123
|
+
|
|
124
|
+
Exit codes:
|
|
125
|
+
0 = approved
|
|
126
|
+
1 = rejected
|
|
127
|
+
2 = timeout
|
|
128
|
+
|
|
129
|
+
COMPLETE TASK
|
|
130
|
+
husky task complete --output "Task completed successfully"
|
|
131
|
+
husky task complete --pr https://github.com/org/repo/pull/123
|
|
132
|
+
husky task complete --error "Failed due to X"
|
|
133
|
+
|
|
134
|
+
Options:
|
|
135
|
+
--id <id> Task ID (or set HUSKY_TASK_ID)
|
|
136
|
+
--output <text> Completion summary
|
|
137
|
+
--pr <url> Pull request URL
|
|
138
|
+
--error <text> Error message (marks task as failed)
|
|
139
|
+
|
|
140
|
+
DONE (Simple completion)
|
|
141
|
+
husky task done <id>
|
|
142
|
+
husky task done <id> --pr <url>
|
|
143
|
+
|
|
144
|
+
Options:
|
|
145
|
+
--pr <url> Link to PR
|
|
146
|
+
|
|
147
|
+
QA VALIDATION COMMANDS
|
|
148
|
+
|
|
149
|
+
husky task qa-start [--max-iterations <n>] [--no-auto-fix]
|
|
150
|
+
Start QA validation for a task.
|
|
151
|
+
|
|
152
|
+
husky task qa-status [--json]
|
|
153
|
+
Get current QA validation status.
|
|
154
|
+
|
|
155
|
+
husky task qa-approve [--notes <text>]
|
|
156
|
+
Manually approve QA.
|
|
157
|
+
|
|
158
|
+
husky task qa-reject [--notes <text>]
|
|
159
|
+
Manually reject QA.
|
|
160
|
+
|
|
161
|
+
husky task qa-iteration --iteration <n> --status <status> [--issues <json>]
|
|
162
|
+
Add a QA iteration result (for automated agents).
|
|
163
|
+
Status: approved, rejected, error
|
|
164
|
+
|
|
165
|
+
husky task qa-escalate
|
|
166
|
+
Escalate QA to human review.
|
|
167
|
+
|
|
168
|
+
MERGE CONFLICT RESOLUTION
|
|
169
|
+
husky task merge-conflict --file <path> --ours <content> --theirs <content>
|
|
170
|
+
husky task merge-conflict --file <path> --ours-file ours.txt --theirs-file theirs.txt
|
|
171
|
+
|
|
172
|
+
Options:
|
|
173
|
+
--file <path> Path to conflicted file (required)
|
|
174
|
+
--ours <content> Content from current branch
|
|
175
|
+
--theirs <content> Content from incoming branch
|
|
176
|
+
--base <content> Content from common ancestor (3-way merge)
|
|
177
|
+
--context <text> Additional context about the merge
|
|
178
|
+
--json Output as JSON
|
|
179
|
+
--ours-file <path> Read ours content from file
|
|
180
|
+
--theirs-file <path> Read theirs content from file
|
|
181
|
+
--base-file <path> Read base content from file
|
|
182
|
+
`);
|
|
183
|
+
}
|
|
184
|
+
function printRoadmapHelp() {
|
|
185
|
+
console.log(`
|
|
186
|
+
HUSKY ROADMAP COMMANDS
|
|
187
|
+
|
|
188
|
+
LIST ROADMAPS
|
|
189
|
+
husky roadmap list
|
|
190
|
+
husky roadmap list --type global
|
|
191
|
+
husky roadmap list --project proj123 --json
|
|
192
|
+
|
|
193
|
+
Options:
|
|
194
|
+
--type <type> Filter by type (global, project)
|
|
195
|
+
--project <id> Filter by project ID
|
|
196
|
+
--json Output as JSON
|
|
197
|
+
|
|
198
|
+
GET ROADMAP
|
|
199
|
+
husky roadmap get <id>
|
|
200
|
+
husky roadmap get <id> --json
|
|
201
|
+
|
|
202
|
+
Options:
|
|
203
|
+
--json Output as JSON
|
|
204
|
+
|
|
205
|
+
CREATE ROADMAP
|
|
206
|
+
husky roadmap create "Roadmap name"
|
|
207
|
+
husky roadmap create "Project roadmap" --type project --project proj123
|
|
208
|
+
|
|
209
|
+
Options:
|
|
210
|
+
--type <type> Roadmap type: global, project (default: global)
|
|
211
|
+
--project <projectId> Project ID (required for project type)
|
|
212
|
+
--vision <vision> Product vision
|
|
213
|
+
--audience <audience> Primary target audience
|
|
214
|
+
|
|
215
|
+
ADD PHASE
|
|
216
|
+
husky roadmap add-phase <roadmapId> "Phase name"
|
|
217
|
+
husky roadmap add-phase rm123 "MVP" --description "Minimum viable product"
|
|
218
|
+
|
|
219
|
+
Options:
|
|
220
|
+
--description <desc> Phase description
|
|
221
|
+
|
|
222
|
+
ADD FEATURE
|
|
223
|
+
husky roadmap add-feature <roadmapId> <phaseId> "Feature title"
|
|
224
|
+
husky roadmap add-feature rm123 ph456 "User auth" --priority must --complexity high
|
|
225
|
+
|
|
226
|
+
Options:
|
|
227
|
+
--description <desc> Feature description
|
|
228
|
+
--priority <priority> Priority: must, should, could, wont (default: should)
|
|
229
|
+
--complexity <complexity> Complexity: low, medium, high (default: medium)
|
|
230
|
+
--impact <impact> Impact: low, medium, high (default: medium)
|
|
231
|
+
|
|
232
|
+
GENERATE WITH AI
|
|
233
|
+
husky roadmap generate <roadmapId>
|
|
234
|
+
husky roadmap generate rm123 --context "E-commerce platform"
|
|
235
|
+
|
|
236
|
+
Options:
|
|
237
|
+
--context <context> Additional context for AI generation
|
|
238
|
+
--project <projectId> Project ID for context
|
|
239
|
+
|
|
240
|
+
DELETE ROADMAP
|
|
241
|
+
husky roadmap delete <id> --force
|
|
242
|
+
|
|
243
|
+
Options:
|
|
244
|
+
--force Skip confirmation (required)
|
|
245
|
+
`);
|
|
246
|
+
}
|
|
247
|
+
function printChangelogHelp() {
|
|
248
|
+
console.log(`
|
|
249
|
+
HUSKY CHANGELOG COMMANDS
|
|
250
|
+
|
|
251
|
+
GENERATE FROM GIT COMMITS
|
|
252
|
+
husky changelog generate --version 1.0.0 --project proj123
|
|
253
|
+
husky changelog generate --since v0.9.0 --until HEAD --version 1.0.0 --project proj123
|
|
254
|
+
husky changelog generate --version 1.0.0 --project proj123 --dry-run
|
|
255
|
+
|
|
256
|
+
Options:
|
|
257
|
+
--since <ref> Git ref to start from (tag, commit, branch)
|
|
258
|
+
--until <ref> Git ref to end at (default: HEAD)
|
|
259
|
+
-v, --version <ver> Version for changelog (required)
|
|
260
|
+
-p, --project <id> Project ID (required)
|
|
261
|
+
--dry-run Preview commits without generating
|
|
262
|
+
|
|
263
|
+
LIST CHANGELOGS
|
|
264
|
+
husky changelog list
|
|
265
|
+
husky changelog list --project proj123 --json
|
|
266
|
+
|
|
267
|
+
Options:
|
|
268
|
+
-p, --project <id> Filter by project ID
|
|
269
|
+
--json Output as JSON
|
|
270
|
+
|
|
271
|
+
SHOW CHANGELOG
|
|
272
|
+
husky changelog show <id>
|
|
273
|
+
husky changelog show <id> --json
|
|
274
|
+
husky changelog show <id> --markdown
|
|
275
|
+
|
|
276
|
+
Options:
|
|
277
|
+
--json Output as JSON
|
|
278
|
+
--markdown Output as Markdown
|
|
279
|
+
|
|
280
|
+
PUBLISH CHANGELOG
|
|
281
|
+
husky changelog publish <id>
|
|
282
|
+
|
|
283
|
+
Changes status from draft to published.
|
|
284
|
+
|
|
285
|
+
DELETE CHANGELOG
|
|
286
|
+
husky changelog delete <id> --yes
|
|
287
|
+
|
|
288
|
+
Options:
|
|
289
|
+
-y, --yes Skip confirmation (required)
|
|
290
|
+
`);
|
|
291
|
+
}
|
|
292
|
+
function printConfigHelp() {
|
|
293
|
+
console.log(`
|
|
294
|
+
HUSKY CONFIG COMMANDS
|
|
295
|
+
|
|
296
|
+
SET CONFIGURATION
|
|
297
|
+
husky config set api-url https://dashboard.example.com
|
|
298
|
+
husky config set api-key your-api-key
|
|
299
|
+
|
|
300
|
+
Available keys:
|
|
301
|
+
api-url Dashboard API URL (required for all commands)
|
|
302
|
+
api-key API key for authentication
|
|
303
|
+
|
|
304
|
+
GET CONFIGURATION
|
|
305
|
+
husky config get api-url
|
|
306
|
+
husky config get api-key
|
|
307
|
+
|
|
308
|
+
LIST ALL CONFIGURATION
|
|
309
|
+
husky config list
|
|
310
|
+
|
|
311
|
+
Shows all configured values (api-key is masked).
|
|
312
|
+
|
|
313
|
+
Configuration is stored in: ~/.husky/config.json
|
|
314
|
+
`);
|
|
315
|
+
}
|
|
316
|
+
function printAgentWorkflowHelp() {
|
|
317
|
+
console.log(`
|
|
318
|
+
HUSKY AGENT WORKFLOW
|
|
319
|
+
|
|
320
|
+
This guide explains how an AI agent should use the Husky CLI to work on tasks.
|
|
321
|
+
|
|
322
|
+
TYPICAL WORKFLOW
|
|
323
|
+
|
|
324
|
+
1. SETUP (once per session)
|
|
325
|
+
export HUSKY_TASK_ID="<task-id>"
|
|
326
|
+
|
|
327
|
+
2. GET TASK DETAILS
|
|
328
|
+
husky task get --json
|
|
329
|
+
|
|
330
|
+
3. REPORT PROGRESS (during work)
|
|
331
|
+
husky task status "Analyzing codebase..."
|
|
332
|
+
husky task status "Implementing feature X..."
|
|
333
|
+
husky task status "Running tests..."
|
|
334
|
+
|
|
335
|
+
4. SUBMIT PLAN (for complex tasks)
|
|
336
|
+
husky task plan --summary "Will implement X by doing Y"
|
|
337
|
+
husky task wait-approval
|
|
338
|
+
|
|
339
|
+
5. COMPLETE TASK
|
|
340
|
+
husky task complete --output "Implemented feature X" --pr https://github.com/...
|
|
341
|
+
|
|
342
|
+
Or if failed:
|
|
343
|
+
husky task complete --error "Could not complete due to X"
|
|
344
|
+
|
|
345
|
+
EXAMPLE: FULL TASK EXECUTION
|
|
346
|
+
|
|
347
|
+
# Setup
|
|
348
|
+
export HUSKY_TASK_ID="abc123"
|
|
349
|
+
|
|
350
|
+
# Check task details
|
|
351
|
+
husky task get
|
|
352
|
+
|
|
353
|
+
# Start working
|
|
354
|
+
husky task status "Starting task..."
|
|
355
|
+
|
|
356
|
+
# Do the work (code changes, etc.)
|
|
357
|
+
husky task status "Implementing changes..."
|
|
358
|
+
|
|
359
|
+
# If plan approval needed
|
|
360
|
+
husky task plan --summary "Will add new endpoint and update tests"
|
|
361
|
+
husky task wait-approval
|
|
362
|
+
|
|
363
|
+
# Continue work after approval
|
|
364
|
+
husky task status "Running tests..."
|
|
365
|
+
|
|
366
|
+
# Complete
|
|
367
|
+
husky task complete --output "Added /api/users endpoint" --pr "https://..."
|
|
368
|
+
|
|
369
|
+
QA WORKFLOW
|
|
370
|
+
|
|
371
|
+
After implementation, run QA validation:
|
|
372
|
+
|
|
373
|
+
husky task qa-start
|
|
374
|
+
husky task qa-status
|
|
375
|
+
|
|
376
|
+
# If issues found, fix and report
|
|
377
|
+
husky task qa-iteration --iteration 1 --status rejected --issues '[{"type":"major","title":"Test failure"}]'
|
|
378
|
+
|
|
379
|
+
# After fixes
|
|
380
|
+
husky task qa-iteration --iteration 2 --status approved
|
|
381
|
+
|
|
382
|
+
# If stuck, escalate
|
|
383
|
+
husky task qa-escalate
|
|
384
|
+
|
|
385
|
+
MERGE CONFLICT RESOLUTION
|
|
386
|
+
|
|
387
|
+
When encountering git merge conflicts:
|
|
388
|
+
|
|
389
|
+
husky task merge-conflict \\
|
|
390
|
+
--file src/app.ts \\
|
|
391
|
+
--ours-file .git/MERGE_HEAD/app.ts \\
|
|
392
|
+
--theirs-file .git/HEAD/app.ts \\
|
|
393
|
+
--context "Merging feature branch"
|
|
394
|
+
|
|
395
|
+
BEST PRACTICES
|
|
396
|
+
|
|
397
|
+
1. Always set HUSKY_TASK_ID at the start
|
|
398
|
+
2. Report status frequently (every significant step)
|
|
399
|
+
3. Use --json flag when parsing output programmatically
|
|
400
|
+
4. Submit plans for tasks that modify multiple files
|
|
401
|
+
5. Include PR URL when completing tasks
|
|
402
|
+
6. Use qa-escalate if stuck after max iterations
|
|
403
|
+
|
|
404
|
+
EXIT CODES
|
|
405
|
+
|
|
406
|
+
Most commands use standard exit codes:
|
|
407
|
+
0 = Success
|
|
408
|
+
1 = Error/Failure
|
|
409
|
+
2 = Timeout (for wait-approval)
|
|
410
|
+
`);
|
|
411
|
+
}
|