superacli 1.1.13 → 1.1.14

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.
Files changed (75) hide show
  1. package/.agents/skills/humanenv-usage/SKILL.md +19 -0
  2. package/AGENTS.md +62 -0
  3. package/CONTRIBUTING.md +6 -2
  4. package/cli/plugin-install-guidance.js +25 -11
  5. package/cli/plugins-registry.js +25 -6
  6. package/cli/skills-catalog.js +85 -10
  7. package/coverage/clover.xml +1073 -965
  8. package/coverage/lcov-report/cli/adapter-schema.js.html +32 -32
  9. package/coverage/lcov-report/cli/adapters/builtin.js.html +1 -1
  10. package/coverage/lcov-report/cli/adapters/http.js.html +1 -1
  11. package/coverage/lcov-report/cli/adapters/index.html +1 -1
  12. package/coverage/lcov-report/cli/adapters/mcp.js.html +1 -1
  13. package/coverage/lcov-report/cli/adapters/openapi.js.html +1 -1
  14. package/coverage/lcov-report/cli/adapters/process.js.html +1 -1
  15. package/coverage/lcov-report/cli/adapters/shell.js.html +1 -1
  16. package/coverage/lcov-report/cli/ask.js.html +1 -1
  17. package/coverage/lcov-report/cli/config.js.html +109 -109
  18. package/coverage/lcov-report/cli/discover.js.html +1 -1
  19. package/coverage/lcov-report/cli/executor.js.html +1 -1
  20. package/coverage/lcov-report/cli/help-json.js.html +1 -1
  21. package/coverage/lcov-report/cli/index.html +92 -92
  22. package/coverage/lcov-report/cli/mcp-diagnostics.js.html +1 -1
  23. package/coverage/lcov-report/cli/mcp-discovery.js.html +1 -1
  24. package/coverage/lcov-report/cli/mcp-local.js.html +1 -1
  25. package/coverage/lcov-report/cli/mcp-stdio-jsonrpc.js.html +1 -1
  26. package/coverage/lcov-report/cli/namespace-passthrough.js.html +1 -1
  27. package/coverage/lcov-report/cli/plan-runtime.js.html +1 -1
  28. package/coverage/lcov-report/cli/planner.js.html +1 -1
  29. package/coverage/lcov-report/cli/plugin-install-guidance.js.html +919 -877
  30. package/coverage/lcov-report/cli/plugins-command.js.html +452 -452
  31. package/coverage/lcov-report/cli/plugins-learn.js.html +60 -60
  32. package/coverage/lcov-report/cli/plugins-manager.js.html +133 -133
  33. package/coverage/lcov-report/cli/plugins-registry.js.html +105 -48
  34. package/coverage/lcov-report/cli/plugins-store.js.html +106 -106
  35. package/coverage/lcov-report/cli/skills-catalog.js.html +366 -141
  36. package/coverage/lcov-report/cli/skills-mcp.js.html +1 -1
  37. package/coverage/lcov-report/cli/skills.js.html +1 -1
  38. package/coverage/lcov-report/index.html +19 -19
  39. package/coverage/lcov-report/server/app.js.html +1 -1
  40. package/coverage/lcov-report/server/index.html +1 -1
  41. package/coverage/lcov-report/server/routes/ask.js.html +1 -1
  42. package/coverage/lcov-report/server/routes/commands.js.html +1 -1
  43. package/coverage/lcov-report/server/routes/config.js.html +1 -1
  44. package/coverage/lcov-report/server/routes/index.html +1 -1
  45. package/coverage/lcov-report/server/routes/jobs.js.html +1 -1
  46. package/coverage/lcov-report/server/routes/mcp.js.html +1 -1
  47. package/coverage/lcov-report/server/routes/plans.js.html +1 -1
  48. package/coverage/lcov-report/server/routes/plugins.js.html +1 -1
  49. package/coverage/lcov-report/server/routes/specs.js.html +1 -1
  50. package/coverage/lcov-report/server/services/configService.js.html +1 -1
  51. package/coverage/lcov-report/server/services/index.html +1 -1
  52. package/coverage/lcov-report/server/services/pluginsService.js.html +1 -1
  53. package/coverage/lcov-report/server/storage/adapter.js.html +1 -1
  54. package/coverage/lcov-report/server/storage/file.js.html +1 -1
  55. package/coverage/lcov-report/server/storage/index.html +1 -1
  56. package/coverage/lcov-report/server/storage/mongo.js.html +1 -1
  57. package/coverage/lcov.info +1423 -1120
  58. package/package.json +1 -1
  59. package/plugins/beads/install-guidance.json +10 -0
  60. package/plugins/beads/meta.json +5 -0
  61. package/plugins/codedb/meta.json +5 -0
  62. package/plugins/codedb/plugin.json +169 -0
  63. package/plugins/codedb/skills/quickstart/SKILL.md +65 -0
  64. package/plugins/humanenv/.agents/skills/humanenv-sdk-python-usage/SKILL.md +37 -0
  65. package/plugins/humanenv/.agents/skills/humanenv-usage/SKILL.md +32 -0
  66. package/plugins/humanenv/plugin.json +65 -0
  67. package/plugins/humanenv/skills/quickstart/SKILL.md +95 -0
  68. package/plugins/mmx/install-guidance.json +10 -0
  69. package/plugins/mmx/meta.json +5 -0
  70. package/plugins/mmx/plugin.json +413 -0
  71. package/plugins/mmx/skills/quickstart/SKILL.md +234 -0
  72. package/plugins/plugins.json +21 -9
  73. package/plugins/rtk/README.md +63 -0
  74. package/plugins/rtk/plugin.json +79 -0
  75. package/plugins/rtk/skills/quickstart/SKILL.md +78 -0
@@ -23,30 +23,30 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">0% </span>
26
+ <span class="strong">100% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>0/221</span>
28
+ <span class='fraction'>221/221</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">0% </span>
33
+ <span class="strong">95.23% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>0/1</span>
35
+ <span class='fraction'>80/84</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
- <span class="strong">0% </span>
40
+ <span class="strong">100% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>0/1</span>
42
+ <span class='fraction'>2/2</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">0% </span>
47
+ <span class="strong">100% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>0/221</span>
49
+ <span class='fraction'>221/221</span>
50
50
  </div>
51
51
 
52
52
 
@@ -61,7 +61,7 @@
61
61
  </div>
62
62
  </template>
63
63
  </div>
64
- <div class='status-line low'></div>
64
+ <div class='status-line high'></div>
65
65
  <pre><table class="coverage">
66
66
  <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
67
  <a name='L2'></a><a href='#L2'>2</a>
@@ -284,448 +284,448 @@
284
284
  <a name='L219'></a><a href='#L219'>219</a>
285
285
  <a name='L220'></a><a href='#L220'>220</a>
286
286
  <a name='L221'></a><a href='#L221'>221</a>
287
- <a name='L222'></a><a href='#L222'>222</a></td><td class="line-coverage quiet"><span class="cline-any cline-no">&nbsp;</span>
288
- <span class="cline-any cline-no">&nbsp;</span>
289
- <span class="cline-any cline-no">&nbsp;</span>
290
- <span class="cline-any cline-no">&nbsp;</span>
291
- <span class="cline-any cline-no">&nbsp;</span>
292
- <span class="cline-any cline-no">&nbsp;</span>
293
- <span class="cline-any cline-no">&nbsp;</span>
294
- <span class="cline-any cline-no">&nbsp;</span>
295
- <span class="cline-any cline-no">&nbsp;</span>
296
- <span class="cline-any cline-no">&nbsp;</span>
297
- <span class="cline-any cline-no">&nbsp;</span>
298
- <span class="cline-any cline-no">&nbsp;</span>
299
- <span class="cline-any cline-no">&nbsp;</span>
300
- <span class="cline-any cline-no">&nbsp;</span>
301
- <span class="cline-any cline-no">&nbsp;</span>
302
- <span class="cline-any cline-no">&nbsp;</span>
303
- <span class="cline-any cline-no">&nbsp;</span>
304
- <span class="cline-any cline-no">&nbsp;</span>
305
- <span class="cline-any cline-no">&nbsp;</span>
306
- <span class="cline-any cline-no">&nbsp;</span>
307
- <span class="cline-any cline-no">&nbsp;</span>
308
- <span class="cline-any cline-no">&nbsp;</span>
309
- <span class="cline-any cline-no">&nbsp;</span>
310
- <span class="cline-any cline-no">&nbsp;</span>
311
- <span class="cline-any cline-no">&nbsp;</span>
312
- <span class="cline-any cline-no">&nbsp;</span>
313
- <span class="cline-any cline-no">&nbsp;</span>
314
- <span class="cline-any cline-no">&nbsp;</span>
315
- <span class="cline-any cline-no">&nbsp;</span>
316
- <span class="cline-any cline-no">&nbsp;</span>
317
- <span class="cline-any cline-no">&nbsp;</span>
318
- <span class="cline-any cline-no">&nbsp;</span>
319
- <span class="cline-any cline-no">&nbsp;</span>
320
- <span class="cline-any cline-no">&nbsp;</span>
321
- <span class="cline-any cline-no">&nbsp;</span>
322
- <span class="cline-any cline-no">&nbsp;</span>
323
- <span class="cline-any cline-no">&nbsp;</span>
324
- <span class="cline-any cline-no">&nbsp;</span>
325
- <span class="cline-any cline-no">&nbsp;</span>
326
- <span class="cline-any cline-no">&nbsp;</span>
327
- <span class="cline-any cline-no">&nbsp;</span>
328
- <span class="cline-any cline-no">&nbsp;</span>
329
- <span class="cline-any cline-no">&nbsp;</span>
330
- <span class="cline-any cline-no">&nbsp;</span>
331
- <span class="cline-any cline-no">&nbsp;</span>
332
- <span class="cline-any cline-no">&nbsp;</span>
333
- <span class="cline-any cline-no">&nbsp;</span>
334
- <span class="cline-any cline-no">&nbsp;</span>
335
- <span class="cline-any cline-no">&nbsp;</span>
336
- <span class="cline-any cline-no">&nbsp;</span>
337
- <span class="cline-any cline-no">&nbsp;</span>
338
- <span class="cline-any cline-no">&nbsp;</span>
339
- <span class="cline-any cline-no">&nbsp;</span>
340
- <span class="cline-any cline-no">&nbsp;</span>
341
- <span class="cline-any cline-no">&nbsp;</span>
342
- <span class="cline-any cline-no">&nbsp;</span>
343
- <span class="cline-any cline-no">&nbsp;</span>
344
- <span class="cline-any cline-no">&nbsp;</span>
345
- <span class="cline-any cline-no">&nbsp;</span>
346
- <span class="cline-any cline-no">&nbsp;</span>
347
- <span class="cline-any cline-no">&nbsp;</span>
348
- <span class="cline-any cline-no">&nbsp;</span>
349
- <span class="cline-any cline-no">&nbsp;</span>
350
- <span class="cline-any cline-no">&nbsp;</span>
351
- <span class="cline-any cline-no">&nbsp;</span>
352
- <span class="cline-any cline-no">&nbsp;</span>
353
- <span class="cline-any cline-no">&nbsp;</span>
354
- <span class="cline-any cline-no">&nbsp;</span>
355
- <span class="cline-any cline-no">&nbsp;</span>
356
- <span class="cline-any cline-no">&nbsp;</span>
357
- <span class="cline-any cline-no">&nbsp;</span>
358
- <span class="cline-any cline-no">&nbsp;</span>
359
- <span class="cline-any cline-no">&nbsp;</span>
360
- <span class="cline-any cline-no">&nbsp;</span>
361
- <span class="cline-any cline-no">&nbsp;</span>
362
- <span class="cline-any cline-no">&nbsp;</span>
363
- <span class="cline-any cline-no">&nbsp;</span>
364
- <span class="cline-any cline-no">&nbsp;</span>
365
- <span class="cline-any cline-no">&nbsp;</span>
366
- <span class="cline-any cline-no">&nbsp;</span>
367
- <span class="cline-any cline-no">&nbsp;</span>
368
- <span class="cline-any cline-no">&nbsp;</span>
369
- <span class="cline-any cline-no">&nbsp;</span>
370
- <span class="cline-any cline-no">&nbsp;</span>
371
- <span class="cline-any cline-no">&nbsp;</span>
372
- <span class="cline-any cline-no">&nbsp;</span>
373
- <span class="cline-any cline-no">&nbsp;</span>
374
- <span class="cline-any cline-no">&nbsp;</span>
375
- <span class="cline-any cline-no">&nbsp;</span>
376
- <span class="cline-any cline-no">&nbsp;</span>
377
- <span class="cline-any cline-no">&nbsp;</span>
378
- <span class="cline-any cline-no">&nbsp;</span>
379
- <span class="cline-any cline-no">&nbsp;</span>
380
- <span class="cline-any cline-no">&nbsp;</span>
381
- <span class="cline-any cline-no">&nbsp;</span>
382
- <span class="cline-any cline-no">&nbsp;</span>
383
- <span class="cline-any cline-no">&nbsp;</span>
384
- <span class="cline-any cline-no">&nbsp;</span>
385
- <span class="cline-any cline-no">&nbsp;</span>
386
- <span class="cline-any cline-no">&nbsp;</span>
387
- <span class="cline-any cline-no">&nbsp;</span>
388
- <span class="cline-any cline-no">&nbsp;</span>
389
- <span class="cline-any cline-no">&nbsp;</span>
390
- <span class="cline-any cline-no">&nbsp;</span>
391
- <span class="cline-any cline-no">&nbsp;</span>
392
- <span class="cline-any cline-no">&nbsp;</span>
393
- <span class="cline-any cline-no">&nbsp;</span>
394
- <span class="cline-any cline-no">&nbsp;</span>
395
- <span class="cline-any cline-no">&nbsp;</span>
396
- <span class="cline-any cline-no">&nbsp;</span>
397
- <span class="cline-any cline-no">&nbsp;</span>
398
- <span class="cline-any cline-no">&nbsp;</span>
399
- <span class="cline-any cline-no">&nbsp;</span>
400
- <span class="cline-any cline-no">&nbsp;</span>
401
- <span class="cline-any cline-no">&nbsp;</span>
402
- <span class="cline-any cline-no">&nbsp;</span>
403
- <span class="cline-any cline-no">&nbsp;</span>
404
- <span class="cline-any cline-no">&nbsp;</span>
405
- <span class="cline-any cline-no">&nbsp;</span>
406
- <span class="cline-any cline-no">&nbsp;</span>
407
- <span class="cline-any cline-no">&nbsp;</span>
408
- <span class="cline-any cline-no">&nbsp;</span>
409
- <span class="cline-any cline-no">&nbsp;</span>
410
- <span class="cline-any cline-no">&nbsp;</span>
411
- <span class="cline-any cline-no">&nbsp;</span>
412
- <span class="cline-any cline-no">&nbsp;</span>
413
- <span class="cline-any cline-no">&nbsp;</span>
414
- <span class="cline-any cline-no">&nbsp;</span>
415
- <span class="cline-any cline-no">&nbsp;</span>
416
- <span class="cline-any cline-no">&nbsp;</span>
417
- <span class="cline-any cline-no">&nbsp;</span>
418
- <span class="cline-any cline-no">&nbsp;</span>
419
- <span class="cline-any cline-no">&nbsp;</span>
420
- <span class="cline-any cline-no">&nbsp;</span>
421
- <span class="cline-any cline-no">&nbsp;</span>
422
- <span class="cline-any cline-no">&nbsp;</span>
423
- <span class="cline-any cline-no">&nbsp;</span>
424
- <span class="cline-any cline-no">&nbsp;</span>
425
- <span class="cline-any cline-no">&nbsp;</span>
426
- <span class="cline-any cline-no">&nbsp;</span>
427
- <span class="cline-any cline-no">&nbsp;</span>
428
- <span class="cline-any cline-no">&nbsp;</span>
429
- <span class="cline-any cline-no">&nbsp;</span>
430
- <span class="cline-any cline-no">&nbsp;</span>
431
- <span class="cline-any cline-no">&nbsp;</span>
432
- <span class="cline-any cline-no">&nbsp;</span>
433
- <span class="cline-any cline-no">&nbsp;</span>
434
- <span class="cline-any cline-no">&nbsp;</span>
435
- <span class="cline-any cline-no">&nbsp;</span>
436
- <span class="cline-any cline-no">&nbsp;</span>
437
- <span class="cline-any cline-no">&nbsp;</span>
438
- <span class="cline-any cline-no">&nbsp;</span>
439
- <span class="cline-any cline-no">&nbsp;</span>
440
- <span class="cline-any cline-no">&nbsp;</span>
441
- <span class="cline-any cline-no">&nbsp;</span>
442
- <span class="cline-any cline-no">&nbsp;</span>
443
- <span class="cline-any cline-no">&nbsp;</span>
444
- <span class="cline-any cline-no">&nbsp;</span>
445
- <span class="cline-any cline-no">&nbsp;</span>
446
- <span class="cline-any cline-no">&nbsp;</span>
447
- <span class="cline-any cline-no">&nbsp;</span>
448
- <span class="cline-any cline-no">&nbsp;</span>
449
- <span class="cline-any cline-no">&nbsp;</span>
450
- <span class="cline-any cline-no">&nbsp;</span>
451
- <span class="cline-any cline-no">&nbsp;</span>
452
- <span class="cline-any cline-no">&nbsp;</span>
453
- <span class="cline-any cline-no">&nbsp;</span>
454
- <span class="cline-any cline-no">&nbsp;</span>
455
- <span class="cline-any cline-no">&nbsp;</span>
456
- <span class="cline-any cline-no">&nbsp;</span>
457
- <span class="cline-any cline-no">&nbsp;</span>
458
- <span class="cline-any cline-no">&nbsp;</span>
459
- <span class="cline-any cline-no">&nbsp;</span>
460
- <span class="cline-any cline-no">&nbsp;</span>
461
- <span class="cline-any cline-no">&nbsp;</span>
462
- <span class="cline-any cline-no">&nbsp;</span>
463
- <span class="cline-any cline-no">&nbsp;</span>
464
- <span class="cline-any cline-no">&nbsp;</span>
465
- <span class="cline-any cline-no">&nbsp;</span>
466
- <span class="cline-any cline-no">&nbsp;</span>
467
- <span class="cline-any cline-no">&nbsp;</span>
468
- <span class="cline-any cline-no">&nbsp;</span>
469
- <span class="cline-any cline-no">&nbsp;</span>
470
- <span class="cline-any cline-no">&nbsp;</span>
471
- <span class="cline-any cline-no">&nbsp;</span>
472
- <span class="cline-any cline-no">&nbsp;</span>
473
- <span class="cline-any cline-no">&nbsp;</span>
474
- <span class="cline-any cline-no">&nbsp;</span>
475
- <span class="cline-any cline-no">&nbsp;</span>
476
- <span class="cline-any cline-no">&nbsp;</span>
477
- <span class="cline-any cline-no">&nbsp;</span>
478
- <span class="cline-any cline-no">&nbsp;</span>
479
- <span class="cline-any cline-no">&nbsp;</span>
480
- <span class="cline-any cline-no">&nbsp;</span>
481
- <span class="cline-any cline-no">&nbsp;</span>
482
- <span class="cline-any cline-no">&nbsp;</span>
483
- <span class="cline-any cline-no">&nbsp;</span>
484
- <span class="cline-any cline-no">&nbsp;</span>
485
- <span class="cline-any cline-no">&nbsp;</span>
486
- <span class="cline-any cline-no">&nbsp;</span>
487
- <span class="cline-any cline-no">&nbsp;</span>
488
- <span class="cline-any cline-no">&nbsp;</span>
489
- <span class="cline-any cline-no">&nbsp;</span>
490
- <span class="cline-any cline-no">&nbsp;</span>
491
- <span class="cline-any cline-no">&nbsp;</span>
492
- <span class="cline-any cline-no">&nbsp;</span>
493
- <span class="cline-any cline-no">&nbsp;</span>
494
- <span class="cline-any cline-no">&nbsp;</span>
495
- <span class="cline-any cline-no">&nbsp;</span>
496
- <span class="cline-any cline-no">&nbsp;</span>
497
- <span class="cline-any cline-no">&nbsp;</span>
498
- <span class="cline-any cline-no">&nbsp;</span>
499
- <span class="cline-any cline-no">&nbsp;</span>
500
- <span class="cline-any cline-no">&nbsp;</span>
501
- <span class="cline-any cline-no">&nbsp;</span>
502
- <span class="cline-any cline-no">&nbsp;</span>
503
- <span class="cline-any cline-no">&nbsp;</span>
504
- <span class="cline-any cline-no">&nbsp;</span>
505
- <span class="cline-any cline-no">&nbsp;</span>
506
- <span class="cline-any cline-no">&nbsp;</span>
507
- <span class="cline-any cline-no">&nbsp;</span>
508
- <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js"><span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" ><span class="branch-0 cbranch-no" title="branch not covered" >const {</span></span></span>
509
- <span class="cstat-no" title="statement not covered" > installPlugin,</span>
510
- <span class="cstat-no" title="statement not covered" > removePlugin,</span>
511
- <span class="cstat-no" title="statement not covered" > getPlugin,</span>
512
- <span class="cstat-no" title="statement not covered" > listInstalledPlugins,</span>
513
- <span class="cstat-no" title="statement not covered" > getPluginInstallGuidance,</span>
514
- <span class="cstat-no" title="statement not covered" > doctorPlugin,</span>
515
- <span class="cstat-no" title="statement not covered" > doctorAllPlugins</span>
516
- <span class="cstat-no" title="statement not covered" >} = require("./plugins-manager")</span>
517
- <span class="cstat-no" title="statement not covered" >const { listRegistryPlugins } = require("./plugins-registry")</span>
518
- <span class="cstat-no" title="statement not covered" >const { loadConfig } = require("./config")</span>
519
- <span class="cstat-no" title="statement not covered" >const { getPluginLearn } = require("./plugins-learn")</span>
520
- <span class="cstat-no" title="statement not covered" ></span>
521
- <span class="cstat-no" title="statement not covered" >async function handlePluginsCommand(options) {</span>
522
- <span class="cstat-no" title="statement not covered" > const { positional, flags, humanMode, output, outputHumanTable, outputError } = options</span>
523
- <span class="cstat-no" title="statement not covered" > const subcommand = positional[1]</span>
524
- <span class="cstat-no" title="statement not covered" ></span>
525
- <span class="cstat-no" title="statement not covered" > function parseBooleanFlag(name, value) {</span>
526
- <span class="cstat-no" title="statement not covered" > if (value === undefined) return null</span>
527
- <span class="cstat-no" title="statement not covered" > const raw = String(value).trim().toLowerCase()</span>
528
- <span class="cstat-no" title="statement not covered" > if (raw === "true") return true</span>
529
- <span class="cstat-no" title="statement not covered" > if (raw === "false") return false</span>
530
- <span class="cstat-no" title="statement not covered" > outputError({</span>
531
- <span class="cstat-no" title="statement not covered" > code: 85,</span>
532
- <span class="cstat-no" title="statement not covered" > type: "invalid_argument",</span>
533
- <span class="cstat-no" title="statement not covered" > message: `Invalid --${name}. Use true or false`,</span>
534
- <span class="cstat-no" title="statement not covered" > recoverable: false</span>
535
- <span class="cstat-no" title="statement not covered" > })</span>
536
- <span class="cstat-no" title="statement not covered" > return null</span>
537
- <span class="cstat-no" title="statement not covered" > }</span>
538
- <span class="cstat-no" title="statement not covered" ></span>
539
- <span class="cstat-no" title="statement not covered" > if (subcommand === "list") {</span>
540
- <span class="cstat-no" title="statement not covered" > const plugins = listInstalledPlugins().map(p =&gt; ({</span>
541
- <span class="cstat-no" title="statement not covered" > name: p.name,</span>
542
- <span class="cstat-no" title="statement not covered" > version: p.version,</span>
543
- <span class="cstat-no" title="statement not covered" > commands: (p.commands || []).length,</span>
544
- <span class="cstat-no" title="statement not covered" > description: p.description || ""</span>
545
- <span class="cstat-no" title="statement not covered" > }))</span>
546
- <span class="cstat-no" title="statement not covered" > if (humanMode) {</span>
547
- <span class="cstat-no" title="statement not covered" > console.log("\n ⚡ Plugins\n")</span>
548
- <span class="cstat-no" title="statement not covered" > outputHumanTable(plugins, [</span>
549
- <span class="cstat-no" title="statement not covered" > { key: "name", label: "Name" },</span>
550
- <span class="cstat-no" title="statement not covered" > { key: "version", label: "Version" },</span>
551
- <span class="cstat-no" title="statement not covered" > { key: "commands", label: "Commands" },</span>
552
- <span class="cstat-no" title="statement not covered" > { key: "description", label: "Description" }</span>
553
- <span class="cstat-no" title="statement not covered" > ])</span>
554
- <span class="cstat-no" title="statement not covered" > console.log("")</span>
555
- <span class="cstat-no" title="statement not covered" > } else {</span>
556
- <span class="cstat-no" title="statement not covered" > output({ plugins })</span>
557
- <span class="cstat-no" title="statement not covered" > }</span>
558
- <span class="cstat-no" title="statement not covered" > return true</span>
559
- <span class="cstat-no" title="statement not covered" > }</span>
560
- <span class="cstat-no" title="statement not covered" ></span>
561
- <span class="cstat-no" title="statement not covered" > if (subcommand === "install") {</span>
562
- <span class="cstat-no" title="statement not covered" > const ref = positional[2]</span>
563
- <span class="cstat-no" title="statement not covered" > const gitRepo = flags.git</span>
564
- <span class="cstat-no" title="statement not covered" > const manifestPath = flags["manifest-path"]</span>
565
- <span class="cstat-no" title="statement not covered" > const gitRef = flags.ref</span>
566
- <span class="cstat-no" title="statement not covered" ></span>
567
- <span class="cstat-no" title="statement not covered" > if (!ref &amp;&amp; !gitRepo) {</span>
568
- <span class="cstat-no" title="statement not covered" > outputError({</span>
569
- <span class="cstat-no" title="statement not covered" > code: 85,</span>
570
- <span class="cstat-no" title="statement not covered" > type: "invalid_argument",</span>
571
- <span class="cstat-no" title="statement not covered" > message: "Usage: dcli plugins install &lt;name|path&gt; [--on-conflict fail|skip|replace] OR dcli plugins install --git &lt;repo&gt; --manifest-path &lt;path&gt; [--ref &lt;ref&gt;]",</span>
572
- <span class="cstat-no" title="statement not covered" > recoverable: false</span>
573
- <span class="cstat-no" title="statement not covered" > })</span>
574
- <span class="cstat-no" title="statement not covered" > return true</span>
575
- <span class="cstat-no" title="statement not covered" > }</span>
576
- <span class="cstat-no" title="statement not covered" > const config = await loadConfig()</span>
577
- <span class="cstat-no" title="statement not covered" > const result = installPlugin(ref || "(git)", {</span>
578
- <span class="cstat-no" title="statement not covered" > onConflict: flags["on-conflict"] || "fail",</span>
579
- <span class="cstat-no" title="statement not covered" > currentCommands: config.commands || [],</span>
580
- <span class="cstat-no" title="statement not covered" > git: gitRepo,</span>
581
- <span class="cstat-no" title="statement not covered" > manifestPath,</span>
582
- <span class="cstat-no" title="statement not covered" > ref: gitRef</span>
583
- <span class="cstat-no" title="statement not covered" > })</span>
584
- <span class="cstat-no" title="statement not covered" > const guidance = getPluginInstallGuidance(result.plugin)</span>
585
- <span class="cstat-no" title="statement not covered" > output({ ok: true, ...result, install_guidance: guidance })</span>
586
- <span class="cstat-no" title="statement not covered" > return true</span>
587
- <span class="cstat-no" title="statement not covered" > }</span>
588
- <span class="cstat-no" title="statement not covered" ></span>
589
- <span class="cstat-no" title="statement not covered" > if (subcommand === "explore") {</span>
590
- <span class="cstat-no" title="statement not covered" > const tags = String(flags.tags || "")</span>
591
- <span class="cstat-no" title="statement not covered" > .split(",")</span>
592
- <span class="cstat-no" title="statement not covered" > .map(t =&gt; t.trim())</span>
593
- <span class="cstat-no" title="statement not covered" > .filter(Boolean)</span>
594
- <span class="cstat-no" title="statement not covered" > const name = flags.name ? String(flags.name).trim() : ""</span>
595
- <span class="cstat-no" title="statement not covered" > const hasLearnFilter = parseBooleanFlag("has-learn", flags["has-learn"])</span>
596
- <span class="cstat-no" title="statement not covered" > if (flags["has-learn"] !== undefined &amp;&amp; hasLearnFilter === null) return true</span>
597
- <span class="cstat-no" title="statement not covered" ></span>
598
- <span class="cstat-no" title="statement not covered" > const installedFilter = parseBooleanFlag("installed", flags.installed)</span>
599
- <span class="cstat-no" title="statement not covered" > if (flags.installed !== undefined &amp;&amp; installedFilter === null) return true</span>
600
- <span class="cstat-no" title="statement not covered" ></span>
601
- <span class="cstat-no" title="statement not covered" > const sourceFilter = flags.source ? String(flags.source).trim().toLowerCase() : null</span>
602
- <span class="cstat-no" title="statement not covered" > if (sourceFilter &amp;&amp; !["bundled", "git"].includes(sourceFilter)) {</span>
603
- <span class="cstat-no" title="statement not covered" > outputError({</span>
604
- <span class="cstat-no" title="statement not covered" > code: 85,</span>
605
- <span class="cstat-no" title="statement not covered" > type: "invalid_argument",</span>
606
- <span class="cstat-no" title="statement not covered" > message: "Invalid --source. Use bundled or git",</span>
607
- <span class="cstat-no" title="statement not covered" > recoverable: false</span>
608
- <span class="cstat-no" title="statement not covered" > })</span>
609
- <span class="cstat-no" title="statement not covered" > return true</span>
610
- <span class="cstat-no" title="statement not covered" > }</span>
611
- <span class="cstat-no" title="statement not covered" ></span>
612
- <span class="cstat-no" title="statement not covered" > const limit = flags.limit === undefined ? null : Number(flags.limit)</span>
613
- <span class="cstat-no" title="statement not covered" > if (flags.limit !== undefined &amp;&amp; (!Number.isFinite(limit) || limit &lt;= 0 || !Number.isInteger(limit))) {</span>
614
- <span class="cstat-no" title="statement not covered" > outputError({</span>
615
- <span class="cstat-no" title="statement not covered" > code: 85,</span>
616
- <span class="cstat-no" title="statement not covered" > type: "invalid_argument",</span>
617
- <span class="cstat-no" title="statement not covered" > message: "Invalid --limit. Use a positive integer",</span>
618
- <span class="cstat-no" title="statement not covered" > recoverable: false</span>
619
- <span class="cstat-no" title="statement not covered" > })</span>
620
- <span class="cstat-no" title="statement not covered" > return true</span>
621
- <span class="cstat-no" title="statement not covered" > }</span>
622
- <span class="cstat-no" title="statement not covered" ></span>
623
- <span class="cstat-no" title="statement not covered" > const installedSet = new Set(listInstalledPlugins().map(p =&gt; p.name))</span>
624
- <span class="cstat-no" title="statement not covered" ></span>
625
- <span class="cstat-no" title="statement not covered" > let plugins = listRegistryPlugins({ name, tags }).map(p =&gt; ({</span>
626
- <span class="cstat-no" title="statement not covered" > name: p.name,</span>
627
- <span class="cstat-no" title="statement not covered" > description: p.description,</span>
628
- <span class="cstat-no" title="statement not covered" > tags: p.tags,</span>
629
- <span class="cstat-no" title="statement not covered" > has_learn: p.has_learn === true,</span>
630
- <span class="cstat-no" title="statement not covered" > installed: installedSet.has(p.name),</span>
631
- <span class="cstat-no" title="statement not covered" > source_type: (p.source &amp;&amp; p.source.type) || "bundled",</span>
632
- <span class="cstat-no" title="statement not covered" > source_repo: p.source &amp;&amp; p.source.repo ? p.source.repo : ""</span>
633
- <span class="cstat-no" title="statement not covered" > }))</span>
634
- <span class="cstat-no" title="statement not covered" ></span>
635
- <span class="cstat-no" title="statement not covered" > if (hasLearnFilter !== null) {</span>
636
- <span class="cstat-no" title="statement not covered" > plugins = plugins.filter(p =&gt; p.has_learn === hasLearnFilter)</span>
637
- <span class="cstat-no" title="statement not covered" > }</span>
638
- <span class="cstat-no" title="statement not covered" > if (installedFilter !== null) {</span>
639
- <span class="cstat-no" title="statement not covered" > plugins = plugins.filter(p =&gt; p.installed === installedFilter)</span>
640
- <span class="cstat-no" title="statement not covered" > }</span>
641
- <span class="cstat-no" title="statement not covered" > if (sourceFilter) {</span>
642
- <span class="cstat-no" title="statement not covered" > plugins = plugins.filter(p =&gt; p.source_type === sourceFilter)</span>
643
- <span class="cstat-no" title="statement not covered" > }</span>
644
- <span class="cstat-no" title="statement not covered" ></span>
645
- <span class="cstat-no" title="statement not covered" > const total = plugins.length</span>
646
- <span class="cstat-no" title="statement not covered" > if (limit !== null) plugins = plugins.slice(0, limit)</span>
647
- <span class="cstat-no" title="statement not covered" ></span>
648
- <span class="cstat-no" title="statement not covered" > if (humanMode) {</span>
649
- <span class="cstat-no" title="statement not covered" > console.log("\n ⚡ Plugin Registry\n")</span>
650
- <span class="cstat-no" title="statement not covered" > outputHumanTable(plugins, [</span>
651
- <span class="cstat-no" title="statement not covered" > { key: "name", label: "Name" },</span>
652
- <span class="cstat-no" title="statement not covered" > { key: "installed", label: "Installed" },</span>
653
- <span class="cstat-no" title="statement not covered" > { key: "has_learn", label: "Learn" },</span>
654
- <span class="cstat-no" title="statement not covered" > { key: "source_type", label: "Source" },</span>
655
- <span class="cstat-no" title="statement not covered" > { key: "tags", label: "Tags" },</span>
656
- <span class="cstat-no" title="statement not covered" > { key: "description", label: "Description" }</span>
657
- <span class="cstat-no" title="statement not covered" > ])</span>
658
- <span class="cstat-no" title="statement not covered" > console.log("")</span>
659
- <span class="cstat-no" title="statement not covered" > } else {</span>
660
- <span class="cstat-no" title="statement not covered" > output({</span>
661
- <span class="cstat-no" title="statement not covered" > plugins,</span>
662
- <span class="cstat-no" title="statement not covered" > total,</span>
663
- <span class="cstat-no" title="statement not covered" > returned: plugins.length,</span>
664
- <span class="cstat-no" title="statement not covered" > filters: {</span>
665
- <span class="cstat-no" title="statement not covered" > name: name || null,</span>
666
- <span class="cstat-no" title="statement not covered" > tags,</span>
667
- <span class="cstat-no" title="statement not covered" > has_learn: hasLearnFilter,</span>
668
- <span class="cstat-no" title="statement not covered" > installed: installedFilter,</span>
669
- <span class="cstat-no" title="statement not covered" > source: sourceFilter,</span>
670
- <span class="cstat-no" title="statement not covered" > limit: limit === null ? null : limit</span>
671
- <span class="cstat-no" title="statement not covered" > }</span>
672
- <span class="cstat-no" title="statement not covered" > })</span>
673
- <span class="cstat-no" title="statement not covered" > }</span>
674
- <span class="cstat-no" title="statement not covered" > return true</span>
675
- <span class="cstat-no" title="statement not covered" > }</span>
676
- <span class="cstat-no" title="statement not covered" ></span>
677
- <span class="cstat-no" title="statement not covered" > if (subcommand === "remove") {</span>
678
- <span class="cstat-no" title="statement not covered" > const name = positional[2]</span>
679
- <span class="cstat-no" title="statement not covered" > if (!name) {</span>
680
- <span class="cstat-no" title="statement not covered" > outputError({ code: 85, type: "invalid_argument", message: "Usage: dcli plugins remove &lt;name&gt;", recoverable: false })</span>
681
- <span class="cstat-no" title="statement not covered" > return true</span>
682
- <span class="cstat-no" title="statement not covered" > }</span>
683
- <span class="cstat-no" title="statement not covered" > output({ ok: true, removed: removePlugin(name) })</span>
684
- <span class="cstat-no" title="statement not covered" > return true</span>
685
- <span class="cstat-no" title="statement not covered" > }</span>
686
- <span class="cstat-no" title="statement not covered" ></span>
687
- <span class="cstat-no" title="statement not covered" > if (subcommand === "show") {</span>
688
- <span class="cstat-no" title="statement not covered" > const name = positional[2]</span>
689
- <span class="cstat-no" title="statement not covered" > if (!name) {</span>
690
- <span class="cstat-no" title="statement not covered" > outputError({ code: 85, type: "invalid_argument", message: "Usage: dcli plugins show &lt;name&gt;", recoverable: false })</span>
691
- <span class="cstat-no" title="statement not covered" > return true</span>
692
- <span class="cstat-no" title="statement not covered" > }</span>
693
- <span class="cstat-no" title="statement not covered" > const plugin = getPlugin(name)</span>
694
- <span class="cstat-no" title="statement not covered" > if (!plugin) {</span>
695
- <span class="cstat-no" title="statement not covered" > outputError({ code: 92, type: "resource_not_found", message: `Plugin '${name}' is not installed`, suggestions: ["Run: dcli plugins list"] })</span>
696
- <span class="cstat-no" title="statement not covered" > return true</span>
697
- <span class="cstat-no" title="statement not covered" > }</span>
698
- <span class="cstat-no" title="statement not covered" > output({ plugin, install_guidance: getPluginInstallGuidance(name) })</span>
699
- <span class="cstat-no" title="statement not covered" > return true</span>
700
- <span class="cstat-no" title="statement not covered" > }</span>
701
- <span class="cstat-no" title="statement not covered" ></span>
702
- <span class="cstat-no" title="statement not covered" > if (subcommand === "doctor") {</span>
703
- <span class="cstat-no" title="statement not covered" > const name = positional[2]</span>
704
- <span class="cstat-no" title="statement not covered" > const report = name ? doctorPlugin(name) : doctorAllPlugins()</span>
705
- <span class="cstat-no" title="statement not covered" > output(report)</span>
706
- <span class="cstat-no" title="statement not covered" > return true</span>
707
- <span class="cstat-no" title="statement not covered" > }</span>
708
- <span class="cstat-no" title="statement not covered" ></span>
709
- <span class="cstat-no" title="statement not covered" > if (subcommand === "learn") {</span>
710
- <span class="cstat-no" title="statement not covered" > const name = positional[2]</span>
711
- <span class="cstat-no" title="statement not covered" > if (!name) {</span>
712
- <span class="cstat-no" title="statement not covered" > outputError({ code: 85, type: "invalid_argument", message: "Usage: dcli plugins learn &lt;name&gt;", recoverable: false })</span>
713
- <span class="cstat-no" title="statement not covered" > return true</span>
714
- <span class="cstat-no" title="statement not covered" > }</span>
715
- <span class="cstat-no" title="statement not covered" > const info = getPluginLearn(name)</span>
716
- <span class="cstat-no" title="statement not covered" > if (humanMode) {</span>
717
- <span class="cstat-no" title="statement not covered" > console.log(info.learn_markdown)</span>
718
- <span class="cstat-no" title="statement not covered" > } else {</span>
719
- <span class="cstat-no" title="statement not covered" > output(info)</span>
720
- <span class="cstat-no" title="statement not covered" > }</span>
721
- <span class="cstat-no" title="statement not covered" > return true</span>
722
- <span class="cstat-no" title="statement not covered" > }</span>
723
- <span class="cstat-no" title="statement not covered" ></span>
724
- <span class="cstat-no" title="statement not covered" > outputError({ code: 85, type: "invalid_argument", message: "Unknown plugins subcommand. Use: list, explore, install, remove, show, doctor, learn", recoverable: false })</span>
725
- <span class="cstat-no" title="statement not covered" > return true</span>
726
- <span class="cstat-no" title="statement not covered" >}</span>
727
- <span class="cstat-no" title="statement not covered" ></span>
728
- <span class="cstat-no" title="statement not covered" >module.exports = { handlePluginsCommand }</span>
287
+ <a name='L222'></a><a href='#L222'>222</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
288
+ <span class="cline-any cline-yes">1x</span>
289
+ <span class="cline-any cline-yes">1x</span>
290
+ <span class="cline-any cline-yes">1x</span>
291
+ <span class="cline-any cline-yes">1x</span>
292
+ <span class="cline-any cline-yes">1x</span>
293
+ <span class="cline-any cline-yes">1x</span>
294
+ <span class="cline-any cline-yes">1x</span>
295
+ <span class="cline-any cline-yes">1x</span>
296
+ <span class="cline-any cline-yes">1x</span>
297
+ <span class="cline-any cline-yes">1x</span>
298
+ <span class="cline-any cline-yes">1x</span>
299
+ <span class="cline-any cline-yes">1x</span>
300
+ <span class="cline-any cline-yes">22x</span>
301
+ <span class="cline-any cline-yes">22x</span>
302
+ <span class="cline-any cline-yes">22x</span>
303
+ <span class="cline-any cline-yes">22x</span>
304
+ <span class="cline-any cline-yes">22x</span>
305
+ <span class="cline-any cline-yes">11x</span>
306
+ <span class="cline-any cline-yes">3x</span>
307
+ <span class="cline-any cline-yes">11x</span>
308
+ <span class="cline-any cline-yes">11x</span>
309
+ <span class="cline-any cline-yes">1x</span>
310
+ <span class="cline-any cline-yes">1x</span>
311
+ <span class="cline-any cline-yes">1x</span>
312
+ <span class="cline-any cline-yes">1x</span>
313
+ <span class="cline-any cline-yes">1x</span>
314
+ <span class="cline-any cline-yes">1x</span>
315
+ <span class="cline-any cline-yes">1x</span>
316
+ <span class="cline-any cline-yes">1x</span>
317
+ <span class="cline-any cline-yes">22x</span>
318
+ <span class="cline-any cline-yes">22x</span>
319
+ <span class="cline-any cline-yes">2x</span>
320
+ <span class="cline-any cline-yes">1x</span>
321
+ <span class="cline-any cline-yes">1x</span>
322
+ <span class="cline-any cline-yes">1x</span>
323
+ <span class="cline-any cline-yes">1x</span>
324
+ <span class="cline-any cline-yes">2x</span>
325
+ <span class="cline-any cline-yes">2x</span>
326
+ <span class="cline-any cline-yes">1x</span>
327
+ <span class="cline-any cline-yes">1x</span>
328
+ <span class="cline-any cline-yes">1x</span>
329
+ <span class="cline-any cline-yes">1x</span>
330
+ <span class="cline-any cline-yes">1x</span>
331
+ <span class="cline-any cline-yes">1x</span>
332
+ <span class="cline-any cline-yes">1x</span>
333
+ <span class="cline-any cline-yes">1x</span>
334
+ <span class="cline-any cline-yes">1x</span>
335
+ <span class="cline-any cline-yes">1x</span>
336
+ <span class="cline-any cline-yes">1x</span>
337
+ <span class="cline-any cline-yes">2x</span>
338
+ <span class="cline-any cline-yes">2x</span>
339
+ <span class="cline-any cline-yes">20x</span>
340
+ <span class="cline-any cline-yes">22x</span>
341
+ <span class="cline-any cline-yes">3x</span>
342
+ <span class="cline-any cline-yes">3x</span>
343
+ <span class="cline-any cline-yes">3x</span>
344
+ <span class="cline-any cline-yes">3x</span>
345
+ <span class="cline-any cline-yes">3x</span>
346
+ <span class="cline-any cline-yes">3x</span>
347
+ <span class="cline-any cline-yes">1x</span>
348
+ <span class="cline-any cline-yes">1x</span>
349
+ <span class="cline-any cline-yes">1x</span>
350
+ <span class="cline-any cline-yes">1x</span>
351
+ <span class="cline-any cline-yes">1x</span>
352
+ <span class="cline-any cline-yes">1x</span>
353
+ <span class="cline-any cline-yes">1x</span>
354
+ <span class="cline-any cline-yes">1x</span>
355
+ <span class="cline-any cline-yes">2x</span>
356
+ <span class="cline-any cline-yes">3x</span>
357
+ <span class="cline-any cline-yes">3x</span>
358
+ <span class="cline-any cline-yes">3x</span>
359
+ <span class="cline-any cline-yes">3x</span>
360
+ <span class="cline-any cline-yes">3x</span>
361
+ <span class="cline-any cline-yes">3x</span>
362
+ <span class="cline-any cline-yes">3x</span>
363
+ <span class="cline-any cline-yes">3x</span>
364
+ <span class="cline-any cline-yes">3x</span>
365
+ <span class="cline-any cline-yes">3x</span>
366
+ <span class="cline-any cline-yes">3x</span>
367
+ <span class="cline-any cline-yes">17x</span>
368
+ <span class="cline-any cline-yes">22x</span>
369
+ <span class="cline-any cline-yes">6x</span>
370
+ <span class="cline-any cline-yes">6x</span>
371
+ <span class="cline-any cline-yes">6x</span>
372
+ <span class="cline-any cline-yes">6x</span>
373
+ <span class="cline-any cline-yes">6x</span>
374
+ <span class="cline-any cline-yes">6x</span>
375
+ <span class="cline-any cline-yes">6x</span>
376
+ <span class="cline-any cline-yes">5x</span>
377
+ <span class="cline-any cline-yes">5x</span>
378
+ <span class="cline-any cline-yes">6x</span>
379
+ <span class="cline-any cline-yes">5x</span>
380
+ <span class="cline-any cline-yes">6x</span>
381
+ <span class="cline-any cline-yes">6x</span>
382
+ <span class="cline-any cline-yes">1x</span>
383
+ <span class="cline-any cline-yes">1x</span>
384
+ <span class="cline-any cline-yes">1x</span>
385
+ <span class="cline-any cline-yes">1x</span>
386
+ <span class="cline-any cline-yes">1x</span>
387
+ <span class="cline-any cline-yes">1x</span>
388
+ <span class="cline-any cline-yes">1x</span>
389
+ <span class="cline-any cline-yes">1x</span>
390
+ <span class="cline-any cline-yes">4x</span>
391
+ <span class="cline-any cline-yes">6x</span>
392
+ <span class="cline-any cline-yes">6x</span>
393
+ <span class="cline-any cline-yes">1x</span>
394
+ <span class="cline-any cline-yes">1x</span>
395
+ <span class="cline-any cline-yes">1x</span>
396
+ <span class="cline-any cline-yes">1x</span>
397
+ <span class="cline-any cline-yes">1x</span>
398
+ <span class="cline-any cline-yes">1x</span>
399
+ <span class="cline-any cline-yes">1x</span>
400
+ <span class="cline-any cline-yes">1x</span>
401
+ <span class="cline-any cline-yes">3x</span>
402
+ <span class="cline-any cline-yes">3x</span>
403
+ <span class="cline-any cline-yes">3x</span>
404
+ <span class="cline-any cline-yes">3x</span>
405
+ <span class="cline-any cline-yes">4x</span>
406
+ <span class="cline-any cline-yes">4x</span>
407
+ <span class="cline-any cline-yes">4x</span>
408
+ <span class="cline-any cline-yes">4x</span>
409
+ <span class="cline-any cline-yes">4x</span>
410
+ <span class="cline-any cline-yes">4x</span>
411
+ <span class="cline-any cline-yes">4x</span>
412
+ <span class="cline-any cline-yes">3x</span>
413
+ <span class="cline-any cline-yes">3x</span>
414
+ <span class="cline-any cline-yes">6x</span>
415
+ <span class="cline-any cline-yes">1x</span>
416
+ <span class="cline-any cline-yes">1x</span>
417
+ <span class="cline-any cline-yes">6x</span>
418
+ <span class="cline-any cline-yes">1x</span>
419
+ <span class="cline-any cline-yes">1x</span>
420
+ <span class="cline-any cline-yes">6x</span>
421
+ <span class="cline-any cline-yes">1x</span>
422
+ <span class="cline-any cline-yes">1x</span>
423
+ <span class="cline-any cline-yes">3x</span>
424
+ <span class="cline-any cline-yes">3x</span>
425
+ <span class="cline-any cline-yes">6x</span>
426
+ <span class="cline-any cline-yes">3x</span>
427
+ <span class="cline-any cline-yes">6x</span>
428
+ <span class="cline-any cline-yes">1x</span>
429
+ <span class="cline-any cline-yes">1x</span>
430
+ <span class="cline-any cline-yes">1x</span>
431
+ <span class="cline-any cline-yes">1x</span>
432
+ <span class="cline-any cline-yes">1x</span>
433
+ <span class="cline-any cline-yes">1x</span>
434
+ <span class="cline-any cline-yes">1x</span>
435
+ <span class="cline-any cline-yes">1x</span>
436
+ <span class="cline-any cline-yes">1x</span>
437
+ <span class="cline-any cline-yes">1x</span>
438
+ <span class="cline-any cline-yes">6x</span>
439
+ <span class="cline-any cline-yes">2x</span>
440
+ <span class="cline-any cline-yes">2x</span>
441
+ <span class="cline-any cline-yes">2x</span>
442
+ <span class="cline-any cline-yes">2x</span>
443
+ <span class="cline-any cline-yes">2x</span>
444
+ <span class="cline-any cline-yes">2x</span>
445
+ <span class="cline-any cline-yes">2x</span>
446
+ <span class="cline-any cline-yes">2x</span>
447
+ <span class="cline-any cline-yes">2x</span>
448
+ <span class="cline-any cline-yes">2x</span>
449
+ <span class="cline-any cline-yes">2x</span>
450
+ <span class="cline-any cline-yes">2x</span>
451
+ <span class="cline-any cline-yes">2x</span>
452
+ <span class="cline-any cline-yes">2x</span>
453
+ <span class="cline-any cline-yes">3x</span>
454
+ <span class="cline-any cline-yes">3x</span>
455
+ <span class="cline-any cline-yes">11x</span>
456
+ <span class="cline-any cline-yes">22x</span>
457
+ <span class="cline-any cline-yes">2x</span>
458
+ <span class="cline-any cline-yes">2x</span>
459
+ <span class="cline-any cline-yes">1x</span>
460
+ <span class="cline-any cline-yes">1x</span>
461
+ <span class="cline-any cline-yes">1x</span>
462
+ <span class="cline-any cline-yes">1x</span>
463
+ <span class="cline-any cline-yes">1x</span>
464
+ <span class="cline-any cline-yes">1x</span>
465
+ <span class="cline-any cline-yes">9x</span>
466
+ <span class="cline-any cline-yes">22x</span>
467
+ <span class="cline-any cline-yes">3x</span>
468
+ <span class="cline-any cline-yes">3x</span>
469
+ <span class="cline-any cline-yes">1x</span>
470
+ <span class="cline-any cline-yes">1x</span>
471
+ <span class="cline-any cline-yes">1x</span>
472
+ <span class="cline-any cline-yes">2x</span>
473
+ <span class="cline-any cline-yes">3x</span>
474
+ <span class="cline-any cline-yes">1x</span>
475
+ <span class="cline-any cline-yes">1x</span>
476
+ <span class="cline-any cline-yes">1x</span>
477
+ <span class="cline-any cline-yes">1x</span>
478
+ <span class="cline-any cline-yes">1x</span>
479
+ <span class="cline-any cline-yes">1x</span>
480
+ <span class="cline-any cline-yes">6x</span>
481
+ <span class="cline-any cline-yes">22x</span>
482
+ <span class="cline-any cline-yes">2x</span>
483
+ <span class="cline-any cline-yes">2x</span>
484
+ <span class="cline-any cline-yes">2x</span>
485
+ <span class="cline-any cline-yes">2x</span>
486
+ <span class="cline-any cline-yes">2x</span>
487
+ <span class="cline-any cline-yes">4x</span>
488
+ <span class="cline-any cline-yes">22x</span>
489
+ <span class="cline-any cline-yes">3x</span>
490
+ <span class="cline-any cline-yes">3x</span>
491
+ <span class="cline-any cline-yes">1x</span>
492
+ <span class="cline-any cline-yes">1x</span>
493
+ <span class="cline-any cline-yes">1x</span>
494
+ <span class="cline-any cline-yes">2x</span>
495
+ <span class="cline-any cline-yes">3x</span>
496
+ <span class="cline-any cline-yes">1x</span>
497
+ <span class="cline-any cline-yes">1x</span>
498
+ <span class="cline-any cline-yes">1x</span>
499
+ <span class="cline-any cline-yes">1x</span>
500
+ <span class="cline-any cline-yes">2x</span>
501
+ <span class="cline-any cline-yes">2x</span>
502
+ <span class="cline-any cline-yes">1x</span>
503
+ <span class="cline-any cline-yes">1x</span>
504
+ <span class="cline-any cline-yes">1x</span>
505
+ <span class="cline-any cline-yes">1x</span>
506
+ <span class="cline-any cline-yes">1x</span>
507
+ <span class="cline-any cline-yes">1x</span>
508
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">const {
509
+ installPlugin,
510
+ removePlugin,
511
+ getPlugin,
512
+ listInstalledPlugins,
513
+ getPluginInstallGuidance,
514
+ doctorPlugin,
515
+ doctorAllPlugins
516
+ } = require("./plugins-manager")
517
+ const { listRegistryPlugins } = require("./plugins-registry")
518
+ const { loadConfig } = require("./config")
519
+ const { getPluginLearn } = require("./plugins-learn")
520
+ &nbsp;
521
+ async function handlePluginsCommand(options) {
522
+ const { positional, flags, humanMode, output, outputHumanTable, outputError } = options
523
+ const subcommand = positional[1]
524
+ &nbsp;
525
+ function parseBooleanFlag(name, value) {
526
+ if (value === undefined) return null
527
+ const raw = String(value).trim().toLowerCase()
528
+ if (raw === "true") return true
529
+ if (raw === "false") return false
530
+ outputError({
531
+ code: 85,
532
+ type: "invalid_argument",
533
+ message: `Invalid --${name}. Use true or false`,
534
+ recoverable: false
535
+ })
536
+ return null
537
+ }
538
+ &nbsp;
539
+ if (subcommand === "list") {
540
+ const plugins = listInstalledPlugins().map(p =&gt; ({
541
+ name: p.name,
542
+ version: p.version,
543
+ commands: (p.commands<span class="branch-0 cbranch-no" title="branch not covered" > || [])</span>.length,
544
+ description: p.description || ""
545
+ }))
546
+ if (humanMode) {
547
+ console.log("\n ⚡ Plugins\n")
548
+ outputHumanTable(plugins, [
549
+ { key: "name", label: "Name" },
550
+ { key: "version", label: "Version" },
551
+ { key: "commands", label: "Commands" },
552
+ { key: "description", label: "Description" }
553
+ ])
554
+ console.log("")
555
+ } else {
556
+ output({ plugins })
557
+ }
558
+ return true
559
+ }
560
+ &nbsp;
561
+ if (subcommand === "install") {
562
+ const ref = positional[2]
563
+ const gitRepo = flags.git
564
+ const manifestPath = flags["manifest-path"]
565
+ const gitRef = flags.ref
566
+ &nbsp;
567
+ if (!ref &amp;&amp; !gitRepo) {
568
+ outputError({
569
+ code: 85,
570
+ type: "invalid_argument",
571
+ message: "Usage: dcli plugins install &lt;name|path&gt; [--on-conflict fail|skip|replace] OR dcli plugins install --git &lt;repo&gt; --manifest-path &lt;path&gt; [--ref &lt;ref&gt;]",
572
+ recoverable: false
573
+ })
574
+ return true
575
+ }
576
+ const config = await loadConfig()
577
+ const result = installPlugin(ref || "(git)", {
578
+ onConflict: flags["on-conflict"] || "fail",
579
+ currentCommands: config.commands<span class="branch-0 cbranch-no" title="branch not covered" > || [],</span>
580
+ git: gitRepo,
581
+ manifestPath,
582
+ ref: gitRef
583
+ })
584
+ const guidance = getPluginInstallGuidance(result.plugin)
585
+ output({ ok: true, ...result, install_guidance: guidance })
586
+ return true
587
+ }
588
+ &nbsp;
589
+ if (subcommand === "explore") {
590
+ const tags = String(flags.tags || "")
591
+ .split(",")
592
+ .map(t =&gt; t.trim())
593
+ .filter(Boolean)
594
+ const name = flags.name ? String(flags.name).trim() : ""
595
+ const hasLearnFilter = parseBooleanFlag("has-learn", flags["has-learn"])
596
+ if (flags["has-learn"] !== undefined &amp;&amp; hasLearnFilter === null) return true
597
+ &nbsp;
598
+ const installedFilter = parseBooleanFlag("installed", flags.installed)
599
+ if (flags.installed !== undefined &amp;&amp; installedFilter === null) <span class="branch-0 cbranch-no" title="branch not covered" >return true</span>
600
+ &nbsp;
601
+ const sourceFilter = flags.source ? String(flags.source).trim().toLowerCase() : null
602
+ if (sourceFilter &amp;&amp; !["bundled", "git"].includes(sourceFilter)) {
603
+ outputError({
604
+ code: 85,
605
+ type: "invalid_argument",
606
+ message: "Invalid --source. Use bundled or git",
607
+ recoverable: false
608
+ })
609
+ return true
610
+ }
611
+ &nbsp;
612
+ const limit = flags.limit === undefined ? null : Number(flags.limit)
613
+ if (flags.limit !== undefined &amp;&amp; (!Number.isFinite(limit) || limit &lt;= 0 || !Number.isInteger(limit))) {
614
+ outputError({
615
+ code: 85,
616
+ type: "invalid_argument",
617
+ message: "Invalid --limit. Use a positive integer",
618
+ recoverable: false
619
+ })
620
+ return true
621
+ }
622
+ &nbsp;
623
+ const installedSet = new Set(listInstalledPlugins().map(p =&gt; p.name))
624
+ &nbsp;
625
+ let plugins = listRegistryPlugins({ name, tags }).map(p =&gt; ({
626
+ name: p.name,
627
+ description: p.description,
628
+ tags: p.tags,
629
+ has_learn: p.has_learn === true,
630
+ installed: installedSet.has(p.name),
631
+ source_type: (p.source &amp;&amp; p.source.type) || "bundled",
632
+ source_repo: p.source &amp;&amp; p.source.repo<span class="branch-0 cbranch-no" title="branch not covered" > ? p.source.repo </span>: ""
633
+ }))
634
+ &nbsp;
635
+ if (hasLearnFilter !== null) {
636
+ plugins = plugins.filter(p =&gt; p.has_learn === hasLearnFilter)
637
+ }
638
+ if (installedFilter !== null) {
639
+ plugins = plugins.filter(p =&gt; p.installed === installedFilter)
640
+ }
641
+ if (sourceFilter) {
642
+ plugins = plugins.filter(p =&gt; p.source_type === sourceFilter)
643
+ }
644
+ &nbsp;
645
+ const total = plugins.length
646
+ if (limit !== null) plugins = plugins.slice(0, limit)
647
+ &nbsp;
648
+ if (humanMode) {
649
+ console.log("\n ⚡ Plugin Registry\n")
650
+ outputHumanTable(plugins, [
651
+ { key: "name", label: "Name" },
652
+ { key: "installed", label: "Installed" },
653
+ { key: "has_learn", label: "Learn" },
654
+ { key: "source_type", label: "Source" },
655
+ { key: "tags", label: "Tags" },
656
+ { key: "description", label: "Description" }
657
+ ])
658
+ console.log("")
659
+ } else {
660
+ output({
661
+ plugins,
662
+ total,
663
+ returned: plugins.length,
664
+ filters: {
665
+ name: name || null,
666
+ tags,
667
+ has_learn: hasLearnFilter,
668
+ installed: installedFilter,
669
+ source: sourceFilter,
670
+ limit: limit === null ? null : limit
671
+ }
672
+ })
673
+ }
674
+ return true
675
+ }
676
+ &nbsp;
677
+ if (subcommand === "remove") {
678
+ const name = positional[2]
679
+ if (!name) {
680
+ outputError({ code: 85, type: "invalid_argument", message: "Usage: dcli plugins remove &lt;name&gt;", recoverable: false })
681
+ return true
682
+ }
683
+ output({ ok: true, removed: removePlugin(name) })
684
+ return true
685
+ }
686
+ &nbsp;
687
+ if (subcommand === "show") {
688
+ const name = positional[2]
689
+ if (!name) {
690
+ outputError({ code: 85, type: "invalid_argument", message: "Usage: dcli plugins show &lt;name&gt;", recoverable: false })
691
+ return true
692
+ }
693
+ const plugin = getPlugin(name)
694
+ if (!plugin) {
695
+ outputError({ code: 92, type: "resource_not_found", message: `Plugin '${name}' is not installed`, suggestions: ["Run: dcli plugins list"] })
696
+ return true
697
+ }
698
+ output({ plugin, install_guidance: getPluginInstallGuidance(name) })
699
+ return true
700
+ }
701
+ &nbsp;
702
+ if (subcommand === "doctor") {
703
+ const name = positional[2]
704
+ const report = name ? doctorPlugin(name) : doctorAllPlugins()
705
+ output(report)
706
+ return true
707
+ }
708
+ &nbsp;
709
+ if (subcommand === "learn") {
710
+ const name = positional[2]
711
+ if (!name) {
712
+ outputError({ code: 85, type: "invalid_argument", message: "Usage: dcli plugins learn &lt;name&gt;", recoverable: false })
713
+ return true
714
+ }
715
+ const info = getPluginLearn(name)
716
+ if (humanMode) {
717
+ console.log(info.learn_markdown)
718
+ } else {
719
+ output(info)
720
+ }
721
+ return true
722
+ }
723
+ &nbsp;
724
+ outputError({ code: 85, type: "invalid_argument", message: "Unknown plugins subcommand. Use: list, explore, install, remove, show, doctor, learn", recoverable: false })
725
+ return true
726
+ }
727
+ &nbsp;
728
+ module.exports = { handlePluginsCommand }
729
729
  &nbsp;</pre></td></tr></table></pre>
730
730
 
731
731
  <div class='push'></div><!-- for sticky footer -->
@@ -733,7 +733,7 @@
733
733
  <div class='footer quiet pad2 space-top1 center small'>
734
734
  Code coverage generated by
735
735
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
736
- at 2026-03-18T21:19:48.416Z
736
+ at 2026-04-10T17:55:25.401Z
737
737
  </div>
738
738
  <script src="../prettify.js"></script>
739
739
  <script>