@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 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
- 1. **Update version in `package.json`:**
259
- ```bash
260
- cd packages/cli
261
- npm version patch # or minor/major
262
- ```
256
+ ```bash
257
+ cd packages/cli
258
+
259
+ # 1. Bump version
260
+ npm version patch # or minor/major
263
261
 
264
- 2. **Commit and push:**
265
- ```bash
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. **Automatic publishing:**
272
- - Changes in `packages/cli/**` trigger sync to `simon-sfxecom/husky-cli` (public repo)
273
- - Public repo publishes to npm with OIDC provenance
274
- - No `NPM_TOKEN` secret required (OIDC Trusted Publishing)
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
- ### Manual Trigger
271
+ ### Updating on Other Devices
277
272
 
278
- If needed, the workflow can be triggered manually:
279
- - GitHub > Actions > "Sync CLI to Public Repo" > "Run workflow"
273
+ ```bash
274
+ # Update to latest version
275
+ npm update -g @simonfestl/husky-cli
280
276
 
281
- ### npm Trusted Publishing Setup
277
+ # Or reinstall
278
+ npm install -g @simonfestl/husky-cli
282
279
 
283
- The package uses OIDC-based publishing. Configuration on npmjs.com:
284
- - Package Settings > Publishing access > Configure trusted publishing
285
- - Repository: `simon-sfxecom/husky-cli`
286
- - Workflow: `publish.yml`
280
+ # Check installed version
281
+ husky --version
282
+ ```
287
283
 
288
284
  ## Changelog
289
285
 
@@ -4,5 +4,6 @@ interface Config {
4
4
  apiKey?: string;
5
5
  }
6
6
  export declare function getConfig(): Config;
7
+ export declare function setConfig(key: "apiUrl" | "apiKey", value: string): void;
7
8
  export declare const configCommand: Command;
8
9
  export {};
@@ -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(" | Husky CLI - Interactive Mode |");
21
- console.log(" +-------------------------------------+");
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.4.0");
25
+ .version("0.5.1");
26
26
  program.addCommand(taskCommand);
27
27
  program.addCommand(configCommand);
28
28
  program.addCommand(agentCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simonfestl/husky-cli",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "CLI for Huskyv0 Task Orchestration with Claude Agent SDK",
5
5
  "type": "module",
6
6
  "bin": {