@simonfestl/husky-cli 0.5.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 +21 -25
- package/dist/commands/config.d.ts +1 -0
- package/dist/commands/config.js +6 -0
- package/dist/commands/interactive.js +114 -4
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -251,39 +251,35 @@ npm link
|
|
|
251
251
|
|
|
252
252
|
## Publishing / Release
|
|
253
253
|
|
|
254
|
-
The CLI is automatically published to npm via GitHub Actions using OIDC Trusted Publishing.
|
|
255
|
-
|
|
256
254
|
### Publishing a New Version
|
|
257
255
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
256
|
+
```bash
|
|
257
|
+
cd packages/cli
|
|
258
|
+
|
|
259
|
+
# 1. Bump version
|
|
260
|
+
npm version patch # or minor/major
|
|
263
261
|
|
|
264
|
-
2.
|
|
265
|
-
|
|
266
|
-
git add .
|
|
267
|
-
git commit -m "chore(cli): bump version to x.x.x"
|
|
268
|
-
git push origin main
|
|
269
|
-
```
|
|
262
|
+
# 2. Publish to npm (opens browser for authentication)
|
|
263
|
+
npm publish --access public
|
|
270
264
|
|
|
271
|
-
3.
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
265
|
+
# 3. Commit and push
|
|
266
|
+
git add .
|
|
267
|
+
git commit -m "chore(cli): release vX.X.X"
|
|
268
|
+
git push origin main
|
|
269
|
+
```
|
|
275
270
|
|
|
276
|
-
###
|
|
271
|
+
### Updating on Other Devices
|
|
277
272
|
|
|
278
|
-
|
|
279
|
-
|
|
273
|
+
```bash
|
|
274
|
+
# Update to latest version
|
|
275
|
+
npm update -g @simonfestl/husky-cli
|
|
280
276
|
|
|
281
|
-
|
|
277
|
+
# Or reinstall
|
|
278
|
+
npm install -g @simonfestl/husky-cli
|
|
282
279
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
- Workflow: `publish.yml`
|
|
280
|
+
# Check installed version
|
|
281
|
+
husky --version
|
|
282
|
+
```
|
|
287
283
|
|
|
288
284
|
## Changelog
|
|
289
285
|
|
package/dist/commands/config.js
CHANGED
|
@@ -45,6 +45,12 @@ function saveConfig(config) {
|
|
|
45
45
|
}
|
|
46
46
|
writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
47
47
|
}
|
|
48
|
+
// Helper to set a single config value (used by interactive mode)
|
|
49
|
+
export function setConfig(key, value) {
|
|
50
|
+
const config = getConfig();
|
|
51
|
+
config[key] = value;
|
|
52
|
+
saveConfig(config);
|
|
53
|
+
}
|
|
48
54
|
export const configCommand = new Command("config")
|
|
49
55
|
.description("Manage CLI configuration");
|
|
50
56
|
// husky config set <key> <value>
|
|
@@ -15,10 +15,18 @@ function clearScreen() {
|
|
|
15
15
|
}
|
|
16
16
|
// Print header
|
|
17
17
|
function printHeader() {
|
|
18
|
+
const config = getConfig();
|
|
18
19
|
console.log("\n");
|
|
19
|
-
console.log("
|
|
20
|
-
console.log("
|
|
21
|
-
|
|
20
|
+
console.log(" 🐕 Husky CLI - Interactive Mode");
|
|
21
|
+
console.log(" " + "─".repeat(35));
|
|
22
|
+
if (!config.apiUrl) {
|
|
23
|
+
console.log("");
|
|
24
|
+
console.log(" ⚠️ Getting Started:");
|
|
25
|
+
console.log(" Go to 'CLI Config' to set up your API URL and Key");
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
console.log(` Connected to: ${config.apiUrl.substring(0, 40)}`);
|
|
29
|
+
}
|
|
22
30
|
console.log("");
|
|
23
31
|
}
|
|
24
32
|
// ============================================
|
|
@@ -38,7 +46,8 @@ export async function runInteractiveMode() {
|
|
|
38
46
|
{ name: "VM Sessions", value: "vm", description: "Manage VM sessions" },
|
|
39
47
|
{ name: "Jules Sessions", value: "jules", description: "Manage Jules AI sessions" },
|
|
40
48
|
{ name: "Business Strategy", value: "strategy", description: "Manage business strategy" },
|
|
41
|
-
{ name: "Settings", value: "settings", description: "Manage settings" },
|
|
49
|
+
{ name: "Dashboard Settings", value: "settings", description: "Manage dashboard settings" },
|
|
50
|
+
{ name: "CLI Config", value: "config", description: "Configure CLI (API URL, API Key)" },
|
|
42
51
|
{ name: "---", value: "separator", description: "" },
|
|
43
52
|
{ name: "Exit", value: "exit", description: "Exit interactive mode" },
|
|
44
53
|
];
|
|
@@ -75,6 +84,9 @@ export async function runInteractiveMode() {
|
|
|
75
84
|
case "settings":
|
|
76
85
|
await settingsMenu();
|
|
77
86
|
break;
|
|
87
|
+
case "config":
|
|
88
|
+
await cliConfigMenu();
|
|
89
|
+
break;
|
|
78
90
|
case "exit":
|
|
79
91
|
running = false;
|
|
80
92
|
console.log("\n Goodbye!\n");
|
|
@@ -1278,6 +1290,104 @@ async function updateSetting(config) {
|
|
|
1278
1290
|
}
|
|
1279
1291
|
}
|
|
1280
1292
|
// ============================================
|
|
1293
|
+
// CLI CONFIG MENU
|
|
1294
|
+
// ============================================
|
|
1295
|
+
async function cliConfigMenu() {
|
|
1296
|
+
const menuItems = [
|
|
1297
|
+
{ name: "Show current config", value: "show" },
|
|
1298
|
+
{ name: "Set API URL", value: "api-url" },
|
|
1299
|
+
{ name: "Set API Key", value: "api-key" },
|
|
1300
|
+
{ name: "Test connection", value: "test" },
|
|
1301
|
+
{ name: "Back to main menu", value: "back" },
|
|
1302
|
+
];
|
|
1303
|
+
const choice = await select({
|
|
1304
|
+
message: "CLI Config:",
|
|
1305
|
+
choices: menuItems,
|
|
1306
|
+
});
|
|
1307
|
+
switch (choice) {
|
|
1308
|
+
case "show":
|
|
1309
|
+
await showCliConfig();
|
|
1310
|
+
break;
|
|
1311
|
+
case "api-url":
|
|
1312
|
+
await setApiUrl();
|
|
1313
|
+
break;
|
|
1314
|
+
case "api-key":
|
|
1315
|
+
await setApiKey();
|
|
1316
|
+
break;
|
|
1317
|
+
case "test":
|
|
1318
|
+
await testConnection();
|
|
1319
|
+
break;
|
|
1320
|
+
case "back":
|
|
1321
|
+
return;
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
async function showCliConfig() {
|
|
1325
|
+
const config = getConfig();
|
|
1326
|
+
console.log("\n CLI CONFIGURATION (local)");
|
|
1327
|
+
console.log(" " + "-".repeat(50));
|
|
1328
|
+
console.log(` API URL: ${config.apiUrl || "(not set)"}`);
|
|
1329
|
+
console.log(` API Key: ${config.apiKey ? config.apiKey.substring(0, 8) + "..." : "(not set)"}`);
|
|
1330
|
+
console.log("");
|
|
1331
|
+
await pressEnterToContinue();
|
|
1332
|
+
}
|
|
1333
|
+
async function setApiUrl() {
|
|
1334
|
+
const { setConfig } = await import("./config.js");
|
|
1335
|
+
const url = await input({
|
|
1336
|
+
message: "API URL (e.g., https://your-dashboard.run.app):",
|
|
1337
|
+
validate: (value) => {
|
|
1338
|
+
if (!value)
|
|
1339
|
+
return "URL is required";
|
|
1340
|
+
if (!value.startsWith("http"))
|
|
1341
|
+
return "URL must start with http:// or https://";
|
|
1342
|
+
return true;
|
|
1343
|
+
},
|
|
1344
|
+
});
|
|
1345
|
+
setConfig("apiUrl", url);
|
|
1346
|
+
console.log("\n ✅ API URL saved!\n");
|
|
1347
|
+
await pressEnterToContinue();
|
|
1348
|
+
}
|
|
1349
|
+
async function setApiKey() {
|
|
1350
|
+
const { setConfig } = await import("./config.js");
|
|
1351
|
+
const key = await input({
|
|
1352
|
+
message: "API Key:",
|
|
1353
|
+
validate: (value) => (value.length > 0 ? true : "API Key is required"),
|
|
1354
|
+
});
|
|
1355
|
+
setConfig("apiKey", key);
|
|
1356
|
+
console.log("\n ✅ API Key saved!\n");
|
|
1357
|
+
await pressEnterToContinue();
|
|
1358
|
+
}
|
|
1359
|
+
async function testConnection() {
|
|
1360
|
+
const config = getConfig();
|
|
1361
|
+
if (!config.apiUrl) {
|
|
1362
|
+
console.log("\n ❌ API URL not configured. Set it first.\n");
|
|
1363
|
+
await pressEnterToContinue();
|
|
1364
|
+
return;
|
|
1365
|
+
}
|
|
1366
|
+
console.log("\n Testing connection...\n");
|
|
1367
|
+
try {
|
|
1368
|
+
const res = await fetch(`${config.apiUrl}/api/tasks`, {
|
|
1369
|
+
headers: config.apiKey ? { "x-api-key": config.apiKey } : {},
|
|
1370
|
+
});
|
|
1371
|
+
if (res.ok) {
|
|
1372
|
+
console.log(" ✅ Connection successful!");
|
|
1373
|
+
console.log(` Status: ${res.status}`);
|
|
1374
|
+
}
|
|
1375
|
+
else if (res.status === 401) {
|
|
1376
|
+
console.log(" ⚠️ Connection works but authentication failed.");
|
|
1377
|
+
console.log(" Check your API Key.");
|
|
1378
|
+
}
|
|
1379
|
+
else {
|
|
1380
|
+
console.log(` ❌ Connection failed with status: ${res.status}`);
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
catch (error) {
|
|
1384
|
+
console.log(" ❌ Connection failed!");
|
|
1385
|
+
console.log(` Error: ${error.message}`);
|
|
1386
|
+
}
|
|
1387
|
+
console.log("");
|
|
1388
|
+
await pressEnterToContinue();
|
|
1389
|
+
}
|
|
1390
|
+
// ============================================
|
|
1281
1391
|
// UTILITY FUNCTIONS
|
|
1282
1392
|
// ============================================
|
|
1283
1393
|
async function pressEnterToContinue() {
|
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ const program = new Command();
|
|
|
22
22
|
program
|
|
23
23
|
.name("husky")
|
|
24
24
|
.description("CLI for Huskyv0 Task Orchestration with Claude Agent")
|
|
25
|
-
.version("0.
|
|
25
|
+
.version("0.5.1");
|
|
26
26
|
program.addCommand(taskCommand);
|
|
27
27
|
program.addCommand(configCommand);
|
|
28
28
|
program.addCommand(agentCommand);
|