@simonfestl/husky-cli 1.32.0 → 1.33.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.
@@ -261,6 +261,154 @@ projectCommand
261
261
  process.exit(1);
262
262
  }
263
263
  });
264
+ projectCommand
265
+ .command("list-configs")
266
+ .description("List all project configurations")
267
+ .option("--json", "Output as JSON")
268
+ .action(async (options) => {
269
+ const config = ensureConfig();
270
+ try {
271
+ const res = await fetch(`${config.apiUrl}/api/project-configs`, {
272
+ headers: config.apiKey ? { "x-api-key": config.apiKey } : {},
273
+ });
274
+ if (!res.ok) {
275
+ throw new Error(`API error: ${res.status}`);
276
+ }
277
+ const configs = await res.json();
278
+ if (options.json) {
279
+ console.log(JSON.stringify(configs, null, 2));
280
+ }
281
+ else {
282
+ printProjectConfigs(configs);
283
+ }
284
+ }
285
+ catch (error) {
286
+ console.error("Error fetching project configs:", error);
287
+ process.exit(1);
288
+ }
289
+ });
290
+ projectCommand
291
+ .command("show-config <repo>")
292
+ .description("Show configuration for a repository (owner/repo)")
293
+ .option("--json", "Output as JSON")
294
+ .action(async (repo, options) => {
295
+ const config = ensureConfig();
296
+ try {
297
+ const url = new URL("/api/project-configs", config.apiUrl);
298
+ url.searchParams.set("repo", repo);
299
+ const res = await fetch(url.toString(), {
300
+ headers: config.apiKey ? { "x-api-key": config.apiKey } : {},
301
+ });
302
+ if (!res.ok) {
303
+ if (res.status === 404) {
304
+ console.error(`Error: No configuration found for repository ${repo}`);
305
+ }
306
+ else {
307
+ console.error(`Error: API returned ${res.status}`);
308
+ }
309
+ process.exit(1);
310
+ }
311
+ const projectConfig = await res.json();
312
+ if (options.json) {
313
+ console.log(JSON.stringify(projectConfig, null, 2));
314
+ }
315
+ else {
316
+ printProjectConfigDetail(projectConfig);
317
+ }
318
+ }
319
+ catch (error) {
320
+ console.error("Error fetching project config:", error);
321
+ process.exit(1);
322
+ }
323
+ });
324
+ projectCommand
325
+ .command("enable-pr-agent <repo>")
326
+ .description("Enable PR Agent for a repository (owner/repo)")
327
+ .option("--json", "Output as JSON")
328
+ .action(async (repo, options) => {
329
+ const config = ensureConfig();
330
+ try {
331
+ const res = await fetch(`${config.apiUrl}/api/project-configs`, {
332
+ method: "POST",
333
+ headers: {
334
+ "Content-Type": "application/json",
335
+ ...(config.apiKey ? { "x-api-key": config.apiKey } : {}),
336
+ },
337
+ body: JSON.stringify({
338
+ repo,
339
+ prAgentEnabled: true,
340
+ }),
341
+ });
342
+ if (!res.ok) {
343
+ const errorData = await res.json().catch(() => ({}));
344
+ throw new Error(errorData.error || `API error: ${res.status}`);
345
+ }
346
+ const projectConfig = await res.json();
347
+ if (options.json) {
348
+ console.log(JSON.stringify(projectConfig, null, 2));
349
+ }
350
+ else {
351
+ console.log(`✓ PR Agent enabled for ${repo}`);
352
+ console.log(` Repository: ${projectConfig.repo}`);
353
+ console.log(` PR Agent: ${projectConfig.prAgentEnabled ? "Enabled" : "Disabled"}`);
354
+ }
355
+ }
356
+ catch (error) {
357
+ console.error("Error enabling PR Agent:", error);
358
+ process.exit(1);
359
+ }
360
+ });
361
+ projectCommand
362
+ .command("disable-pr-agent <repo>")
363
+ .description("Disable PR Agent for a repository (owner/repo)")
364
+ .option("--json", "Output as JSON")
365
+ .action(async (repo, options) => {
366
+ const config = ensureConfig();
367
+ try {
368
+ const url = new URL("/api/project-configs", config.apiUrl);
369
+ url.searchParams.set("repo", repo);
370
+ const getRes = await fetch(url.toString(), {
371
+ headers: config.apiKey ? { "x-api-key": config.apiKey } : {},
372
+ });
373
+ if (!getRes.ok) {
374
+ if (getRes.status === 404) {
375
+ console.error(`Error: No configuration found for repository ${repo}`);
376
+ }
377
+ else {
378
+ console.error(`Error: API returned ${getRes.status}`);
379
+ }
380
+ process.exit(1);
381
+ }
382
+ const projectConfig = await getRes.json();
383
+ const updateRes = await fetch(`${config.apiUrl}/api/project-configs/${projectConfig.id}`, {
384
+ method: "PUT",
385
+ headers: {
386
+ "Content-Type": "application/json",
387
+ ...(config.apiKey ? { "x-api-key": config.apiKey } : {}),
388
+ },
389
+ body: JSON.stringify({
390
+ prAgentEnabled: false,
391
+ }),
392
+ });
393
+ if (!updateRes.ok) {
394
+ const errorData = await updateRes.json().catch(() => ({}));
395
+ throw new Error(errorData.error || `API error: ${updateRes.status}`);
396
+ }
397
+ const updatedConfig = await updateRes.json();
398
+ if (options.json) {
399
+ console.log(JSON.stringify(updatedConfig, null, 2));
400
+ }
401
+ else {
402
+ console.log(`✓ PR Agent disabled for ${repo}`);
403
+ console.log(` Repository: ${updatedConfig.repo}`);
404
+ console.log(` PR Agent: ${updatedConfig.prAgentEnabled ? "Enabled" : "Disabled"}`);
405
+ }
406
+ }
407
+ catch (error) {
408
+ console.error("Error disabling PR Agent:", error);
409
+ process.exit(1);
410
+ }
411
+ });
264
412
  // ============================================
265
413
  // KNOWLEDGE MANAGEMENT COMMANDS
266
414
  // ============================================
@@ -459,7 +607,6 @@ function printKnowledgeList(projectId, knowledge) {
459
607
  const truncatedTitle = entry.title.length > 33 ? entry.title.substring(0, 30) + "..." : entry.title;
460
608
  console.log(` ${entry.id.padEnd(24)} [${categoryConfig.icon}] ${categoryConfig.label.padEnd(10)} ${truncatedTitle}`);
461
609
  }
462
- // Summary by category
463
610
  const byCategory = {};
464
611
  for (const entry of knowledge) {
465
612
  byCategory[entry.category] = (byCategory[entry.category] || 0) + 1;
@@ -471,3 +618,32 @@ function printKnowledgeList(projectId, knowledge) {
471
618
  .join(", ");
472
619
  console.log(` By Category: ${categoryStr}\n`);
473
620
  }
621
+ function printProjectConfigs(configs) {
622
+ if (configs.length === 0) {
623
+ console.log("\n No project configurations found.");
624
+ console.log(" Enable PR Agent with: husky project enable-pr-agent <owner/repo>\n");
625
+ return;
626
+ }
627
+ console.log("\n PROJECT CONFIGURATIONS");
628
+ console.log(" " + "-".repeat(80));
629
+ console.log(` ${"REPOSITORY".padEnd(40)} ${"PR AGENT".padEnd(15)} ${"UPDATED".padEnd(20)}`);
630
+ console.log(" " + "-".repeat(80));
631
+ for (const config of configs) {
632
+ const status = config.prAgentEnabled ? "✓ Enabled" : "✗ Disabled";
633
+ const updated = new Date(config.updatedAt).toLocaleDateString();
634
+ const truncatedRepo = config.repo.length > 38 ? config.repo.substring(0, 35) + "..." : config.repo;
635
+ console.log(` ${truncatedRepo.padEnd(40)} ${status.padEnd(15)} ${updated}`);
636
+ }
637
+ console.log(" " + "-".repeat(80));
638
+ console.log(` Total: ${configs.length} configuration(s)\n`);
639
+ }
640
+ function printProjectConfigDetail(config) {
641
+ console.log(`\n Project Configuration: ${config.repo}`);
642
+ console.log(" " + "=".repeat(60));
643
+ console.log(` ID: ${config.id}`);
644
+ console.log(` Repository: ${config.repo}`);
645
+ console.log(` PR Agent: ${config.prAgentEnabled ? "✓ Enabled" : "✗ Disabled"}`);
646
+ console.log(` Created: ${new Date(config.createdAt).toLocaleString()}`);
647
+ console.log(` Updated: ${new Date(config.updatedAt).toLocaleString()}`);
648
+ console.log("");
649
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simonfestl/husky-cli",
3
- "version": "1.32.0",
3
+ "version": "1.33.0",
4
4
  "description": "CLI for Huskyv0 Task Orchestration with Claude Agent SDK",
5
5
  "type": "module",
6
6
  "bin": {