@flowscripter/dynamic-cli-framework 1.7.3 → 1.7.4

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 (367) hide show
  1. package/cli-plugin.ts +1 -1
  2. package/dist/cli-plugin.d.ts +1 -1
  3. package/dist/cli-plugin.d.ts.map +1 -1
  4. package/dist/cli-plugin.js +25 -247
  5. package/dist/index.js +70 -105754
  6. package/dist/src/api/BaseCLIFeatureOptions.js +0 -0
  7. package/dist/src/api/CLI.js +0 -0
  8. package/dist/src/api/CLIConfig.js +0 -0
  9. package/dist/src/api/Context.js +0 -0
  10. package/dist/src/api/RunResult.js +73 -0
  11. package/dist/src/api/argument/Argument.js +0 -0
  12. package/dist/src/api/argument/ArgumentValueTypes.js +18 -0
  13. package/dist/src/api/argument/ComplexOption.js +1 -0
  14. package/dist/src/api/argument/GlobalCommandArgument.js +0 -0
  15. package/dist/src/api/argument/Option.js +0 -0
  16. package/dist/src/api/argument/Positional.js +0 -0
  17. package/dist/src/api/argument/SubCommandArgument.js +1 -0
  18. package/dist/src/api/command/Command.js +0 -0
  19. package/dist/src/api/command/GlobalCommand.js +0 -0
  20. package/dist/src/api/command/GlobalModifierCommand.js +0 -0
  21. package/dist/src/api/command/GroupCommand.js +0 -0
  22. package/dist/src/api/command/SubCommand.js +0 -0
  23. package/dist/src/api/command/UsageExample.js +0 -0
  24. package/dist/src/api/plugin/CLIPlugin.js +2 -0
  25. package/dist/src/api/plugin/CommandFactory.js +7 -0
  26. package/dist/src/api/plugin/ServiceProviderFactory.js +7 -0
  27. package/dist/src/api/plugin/createCLIPlugin.js +30 -0
  28. package/dist/src/api/service/ServiceProvider.js +0 -0
  29. package/dist/src/api/service/core/ArgumentPrompterService.js +1 -0
  30. package/dist/src/api/service/core/AsciiBannerGeneratorService.js +1 -0
  31. package/dist/src/api/service/core/CompletionService.js +8 -0
  32. package/dist/src/api/service/core/DataDumpGeneratorService.js +7 -0
  33. package/dist/src/api/service/core/ImagePrinterService.js +1 -0
  34. package/dist/src/api/service/core/KeyValueService.js +7 -0
  35. package/dist/src/api/service/core/PluginService.js +6 -0
  36. package/dist/src/api/service/core/PrettyPrinterService.js +1 -0
  37. package/dist/src/api/service/core/PrinterService.js +42 -0
  38. package/dist/src/api/service/core/PrompterService.js +10 -0
  39. package/dist/src/api/service/core/SecretService.js +0 -0
  40. package/dist/src/api/service/core/ShutdownService.js +1 -0
  41. package/dist/src/api/service/core/SyntaxHighlighterService.js +1 -0
  42. package/dist/src/api/service/core/Table.js +49 -0
  43. package/dist/src/api/service/core/TableGeneratorService.d.ts +1 -0
  44. package/dist/src/api/service/core/TableGeneratorService.d.ts.map +1 -1
  45. package/dist/src/api/service/core/TableGeneratorService.js +7 -0
  46. package/dist/src/api/service/core/TreePrinterService.js +1 -0
  47. package/dist/src/cli/BaseCLI.d.ts.map +1 -1
  48. package/dist/src/cli/BaseCLI.js +233 -0
  49. package/dist/src/cli/DefaultRuntimeCLI.js +20 -0
  50. package/dist/src/cli/DynamicPluginRuntimeCLI.js +50 -0
  51. package/dist/src/command/MultiCommandCliHelpCommand.js +238 -0
  52. package/dist/src/command/SingleCommandCliHelpCommand.js +104 -0
  53. package/dist/src/command/UsageCommand.js +16 -0
  54. package/dist/src/command/VersionCommand.js +13 -0
  55. package/dist/src/launcher.js +61 -0
  56. package/dist/src/runtime/DefaultContext.js +25 -0
  57. package/dist/src/runtime/argument/ArgumentTypeGuards.js +3 -0
  58. package/dist/src/runtime/command/CommandTypeGuards.js +12 -0
  59. package/dist/src/runtime/command/CommandValidator.js +371 -0
  60. package/dist/src/runtime/parser.js +105 -0
  61. package/dist/src/runtime/registry/CommandRegistry.js +0 -0
  62. package/dist/src/runtime/registry/DefaultCommandRegistry.js +190 -0
  63. package/dist/src/runtime/registry/DefaultServiceProviderRegistry.js +20 -0
  64. package/dist/src/runtime/registry/ServiceProviderRegistry.js +0 -0
  65. package/dist/src/runtime/runner.js +507 -0
  66. package/dist/src/runtime/scanner.js +244 -0
  67. package/dist/src/runtime/values/ValuePopulationResult.js +0 -0
  68. package/dist/src/runtime/values/argumentValueMerge.js +122 -0
  69. package/dist/src/runtime/values/argumentValueValidation.js +505 -0
  70. package/dist/src/runtime/values/globalCommandValuePopulation.js +67 -0
  71. package/dist/src/runtime/values/subCommandValuePopulation.js +549 -0
  72. package/dist/src/service/argumentPrompter/ArgumentPrompterServiceProvider.js +19 -0
  73. package/dist/src/service/argumentPrompter/DefaultArgumentPrompterService.js +197 -0
  74. package/dist/src/service/asciiBannerGenerator/AsciiBannerGeneratorServiceProvider.js +28 -0
  75. package/dist/src/service/asciiBannerGenerator/DefaultAsciiBannerGeneratorService.js +233 -0
  76. package/dist/src/service/asciiBannerGenerator/standard.flf.json +3 -0
  77. package/dist/src/service/banner/BannerServiceProvider.js +60 -0
  78. package/dist/src/service/banner/command/NoBannerCommand.js +24 -0
  79. package/dist/src/service/chiselAsciiBannerGenerator/ChiselFontAsciiBannerGeneratorService.js +51 -0
  80. package/dist/src/service/chiselAsciiBannerGenerator/chisel.flf.json +3 -0
  81. package/dist/src/service/completion/CompletionServiceProvider.d.ts +2 -1
  82. package/dist/src/service/completion/CompletionServiceProvider.d.ts.map +1 -1
  83. package/dist/src/service/completion/CompletionServiceProvider.js +160 -0
  84. package/dist/src/service/completion/DefaultCompletionService.js +279 -0
  85. package/dist/src/service/completion/command/CompletionCompleteSubCommand.d.ts +15 -0
  86. package/dist/src/service/completion/command/CompletionCompleteSubCommand.d.ts.map +1 -0
  87. package/dist/src/service/completion/command/CompletionCompleteSubCommand.js +37 -0
  88. package/dist/src/service/completion/command/CompletionGroupCommand.d.ts +14 -0
  89. package/dist/src/service/completion/command/CompletionGroupCommand.d.ts.map +1 -0
  90. package/dist/src/service/completion/command/CompletionGroupCommand.js +10 -0
  91. package/dist/src/service/completion/command/CompletionIntegrationSubCommand.d.ts +14 -0
  92. package/dist/src/service/completion/command/CompletionIntegrationSubCommand.d.ts.map +1 -0
  93. package/dist/src/service/completion/command/CompletionIntegrationSubCommand.js +67 -0
  94. package/dist/src/service/completion/shell/ShellHandler.js +0 -0
  95. package/dist/src/service/completion/shell/bash.js +39 -0
  96. package/dist/src/service/completion/shell/fish.js +35 -0
  97. package/dist/src/service/completion/shell/powershell.js +51 -0
  98. package/dist/src/service/completion/shell/zsh.js +42 -0
  99. package/dist/src/service/configuration/ConfigurationServiceProvider.js +482 -0
  100. package/dist/src/service/configuration/DefaultKeyValueService.js +80 -0
  101. package/dist/src/service/configuration/DefaultSecretService.js +60 -0
  102. package/dist/src/service/configuration/command/ConfigCommand.js +24 -0
  103. package/dist/src/service/configuration/command/DumpConfigCommand.js +18 -0
  104. package/dist/src/service/dataDumpGenerator/DataDumpGeneratorServiceProvider.js +24 -0
  105. package/dist/src/service/dataDumpGenerator/DefaultDataDumpGeneratorService.js +59 -0
  106. package/dist/src/service/imagePrinter/DefaultImagePrinterService.js +10 -0
  107. package/dist/src/service/imagePrinter/ImagePrinterServiceProvider.js +20 -0
  108. package/dist/src/service/plugin/DefaultPluginService.js +21 -0
  109. package/dist/src/service/plugin/DefaultPluginServiceProvider.d.ts +1 -1
  110. package/dist/src/service/plugin/DefaultPluginServiceProvider.d.ts.map +1 -1
  111. package/dist/src/service/plugin/DefaultPluginServiceProvider.js +21 -0
  112. package/dist/src/service/plugin/command/PluginAddSubCommand.d.ts +17 -0
  113. package/dist/src/service/plugin/command/PluginAddSubCommand.d.ts.map +1 -0
  114. package/dist/src/service/plugin/command/PluginAddSubCommand.js +49 -0
  115. package/dist/src/service/plugin/command/PluginGroupCommand.d.ts +12 -0
  116. package/dist/src/service/plugin/command/PluginGroupCommand.d.ts.map +1 -0
  117. package/dist/src/service/plugin/command/PluginGroupCommand.js +21 -0
  118. package/dist/src/service/plugin/command/PluginListSubCommand.d.ts +12 -0
  119. package/dist/src/service/plugin/command/PluginListSubCommand.d.ts.map +1 -0
  120. package/dist/src/service/plugin/command/PluginListSubCommand.js +25 -0
  121. package/dist/src/service/plugin/command/PluginRemoveSubCommand.d.ts +17 -0
  122. package/dist/src/service/plugin/command/PluginRemoveSubCommand.d.ts.map +1 -0
  123. package/dist/src/service/plugin/command/PluginRemoveSubCommand.js +24 -0
  124. package/dist/src/service/plugin/command/PluginSearchSubCommand.d.ts +18 -0
  125. package/dist/src/service/plugin/command/PluginSearchSubCommand.d.ts.map +1 -0
  126. package/dist/src/service/plugin/command/PluginSearchSubCommand.js +34 -0
  127. package/dist/src/service/plugin/command/PluginUpgradeSubCommand.d.ts +12 -0
  128. package/dist/src/service/plugin/command/PluginUpgradeSubCommand.d.ts.map +1 -0
  129. package/dist/src/service/plugin/command/PluginUpgradeSubCommand.js +25 -0
  130. package/dist/src/service/plugin/command/getPluginId.d.ts +3 -0
  131. package/dist/src/service/plugin/command/getPluginId.d.ts.map +1 -0
  132. package/dist/src/service/plugin/command/getPluginId.js +3 -0
  133. package/dist/src/service/prettyPrinter/DefaultPrettyPrinterService.js +45 -0
  134. package/dist/src/service/prettyPrinter/PrettyPrinterServiceProvider.js +28 -0
  135. package/dist/src/service/printer/DefaultPrinterService.js +250 -0
  136. package/dist/src/service/printer/PrinterServiceProvider.js +43 -0
  137. package/dist/src/service/printer/command/DarkModeCommand.js +24 -0
  138. package/dist/src/service/printer/command/LogLevelCommand.js +41 -0
  139. package/dist/src/service/printer/command/NoColorCommand.js +24 -0
  140. package/dist/src/service/printer/command/NoHyperlinksCommand.js +21 -0
  141. package/dist/src/service/printer/terminal/Color.js +15 -0
  142. package/dist/src/service/printer/terminal/Progress.js +271 -0
  143. package/dist/src/service/printer/terminal/Spinner.js +83 -0
  144. package/dist/src/service/printer/terminal/Theme.js +26 -0
  145. package/dist/src/service/prompter/DefaultPrompterService.js +52 -0
  146. package/dist/src/service/prompter/PrompterServiceProvider.js +20 -0
  147. package/dist/src/service/prompter/command/NoPromptCommand.js +21 -0
  148. package/dist/src/service/prompter/prompt/PromptContext.js +22 -0
  149. package/dist/src/service/prompter/prompt/promptAcknowledge.js +19 -0
  150. package/dist/src/service/prompter/prompt/promptMultiSelect.js +74 -0
  151. package/dist/src/service/prompter/prompt/promptOpenUrl.js +70 -0
  152. package/dist/src/service/prompter/prompt/promptSingleSelect.js +73 -0
  153. package/dist/src/service/prompter/prompt/promptText.js +75 -0
  154. package/dist/src/service/prompter/prompt/promptToggle.js +21 -0
  155. package/dist/src/service/shutdown/DefaultShutdownService.js +16 -0
  156. package/dist/src/service/shutdown/ShutdownServiceProvider.js +60 -0
  157. package/dist/src/service/shutdown/ShutdownState.js +5 -0
  158. package/dist/src/service/syntaxHighlighter/DefaultSyntaxHighlighterService.js +54 -0
  159. package/dist/src/service/syntaxHighlighter/SyntaxHighlighterServiceProvider.js +32 -0
  160. package/dist/src/service/tableGenerator/DefaultTableGeneratorService.d.ts +3 -1
  161. package/dist/src/service/tableGenerator/DefaultTableGeneratorService.d.ts.map +1 -1
  162. package/dist/src/service/tableGenerator/DefaultTableGeneratorService.js +344 -0
  163. package/dist/src/service/tableGenerator/TableGeneratorServiceProvider.js +26 -0
  164. package/dist/src/service/treePrinter/DefaultTreePrinterService.js +35 -0
  165. package/dist/src/service/treePrinter/TreePrinterServiceProvider.js +24 -0
  166. package/dist/src/terminal/Ansi.js +23 -0
  167. package/dist/src/terminal/ImageRenderer.js +164 -0
  168. package/dist/src/terminal/KeyReader.js +13 -0
  169. package/dist/src/terminal/PngDecoder.js +115 -0
  170. package/dist/src/terminal/Styler.js +0 -0
  171. package/dist/src/terminal/Terminal.js +0 -0
  172. package/dist/src/terminal/TtyKeyReader.js +87 -0
  173. package/dist/src/terminal/TtyStyler.js +55 -0
  174. package/dist/src/terminal/TtyTerminal.js +52 -0
  175. package/dist/src/terminal/supportsHyperlinks.js +95 -0
  176. package/dist/src/util/configHelper.js +61 -0
  177. package/dist/src/util/envVarHelper.js +216 -0
  178. package/dist/src/util/helpHelper.d.ts.map +1 -1
  179. package/dist/src/util/helpHelper.js +497 -0
  180. package/dist/src/util/logger.js +81 -0
  181. package/dist/src/util/runnerHelper.js +80 -0
  182. package/package.json +2 -2
  183. package/src/api/service/core/TableGeneratorService.ts +1 -0
  184. package/src/cli/BaseCLI.ts +4 -18
  185. package/src/service/completion/CompletionServiceProvider.ts +16 -2
  186. package/src/service/completion/command/CompletionCompleteSubCommand.ts +59 -0
  187. package/src/service/completion/command/CompletionGroupCommand.ts +21 -0
  188. package/src/{command/CompletionCommand.ts → service/completion/command/CompletionIntegrationSubCommand.ts} +12 -73
  189. package/src/service/completion/shell/bash.ts +1 -1
  190. package/src/service/completion/shell/fish.ts +1 -1
  191. package/src/service/completion/shell/powershell.ts +1 -1
  192. package/src/service/completion/shell/zsh.ts +1 -1
  193. package/src/service/plugin/DefaultPluginServiceProvider.ts +2 -2
  194. package/src/service/plugin/command/PluginAddSubCommand.ts +64 -0
  195. package/src/service/plugin/command/PluginGroupCommand.ts +27 -0
  196. package/src/service/plugin/command/PluginListSubCommand.ts +33 -0
  197. package/src/service/plugin/command/PluginRemoveSubCommand.ts +32 -0
  198. package/src/service/plugin/command/PluginSearchSubCommand.ts +42 -0
  199. package/src/service/plugin/command/PluginUpgradeSubCommand.ts +36 -0
  200. package/src/service/plugin/command/getPluginId.ts +5 -0
  201. package/src/service/tableGenerator/DefaultTableGeneratorService.ts +6 -1
  202. package/src/util/helpHelper.ts +1 -2
  203. package/dist/src/command/CompletionCommand.d.ts +0 -32
  204. package/dist/src/command/CompletionCommand.d.ts.map +0 -1
  205. package/dist/src/command/PluginCommand.d.ts +0 -67
  206. package/dist/src/command/PluginCommand.d.ts.map +0 -1
  207. package/dist/tests/cli/BaseCLI.test.d.ts +0 -2
  208. package/dist/tests/cli/BaseCLI.test.d.ts.map +0 -1
  209. package/dist/tests/cli/DynamicPluginRuntimeCLI.test.d.ts +0 -2
  210. package/dist/tests/cli/DynamicPluginRuntimeCLI.test.d.ts.map +0 -1
  211. package/dist/tests/command/CompletionCommand.test.d.ts +0 -2
  212. package/dist/tests/command/CompletionCommand.test.d.ts.map +0 -1
  213. package/dist/tests/command/MultiCommandCliHelpCommand.test.d.ts +0 -2
  214. package/dist/tests/command/MultiCommandCliHelpCommand.test.d.ts.map +0 -1
  215. package/dist/tests/command/PluginCommand.test.d.ts +0 -2
  216. package/dist/tests/command/PluginCommand.test.d.ts.map +0 -1
  217. package/dist/tests/command/SingleCommandCliHelpCommand.test.d.ts +0 -2
  218. package/dist/tests/command/SingleCommandCliHelpCommand.test.d.ts.map +0 -1
  219. package/dist/tests/command/UsageCommand.test.d.ts +0 -2
  220. package/dist/tests/command/UsageCommand.test.d.ts.map +0 -1
  221. package/dist/tests/command/VersionCommand.test.d.ts +0 -2
  222. package/dist/tests/command/VersionCommand.test.d.ts.map +0 -1
  223. package/dist/tests/fixtures/CLIConfig.d.ts +0 -3
  224. package/dist/tests/fixtures/CLIConfig.d.ts.map +0 -1
  225. package/dist/tests/fixtures/Command.d.ts +0 -20
  226. package/dist/tests/fixtures/Command.d.ts.map +0 -1
  227. package/dist/tests/fixtures/CommandRegistry.d.ts +0 -4
  228. package/dist/tests/fixtures/CommandRegistry.d.ts.map +0 -1
  229. package/dist/tests/fixtures/ConfigurationServiceProvider.d.ts +0 -10
  230. package/dist/tests/fixtures/ConfigurationServiceProvider.d.ts.map +0 -1
  231. package/dist/tests/fixtures/Context.d.ts +0 -4
  232. package/dist/tests/fixtures/Context.d.ts.map +0 -1
  233. package/dist/tests/fixtures/ServiceProviderRegistry.d.ts +0 -4
  234. package/dist/tests/fixtures/ServiceProviderRegistry.d.ts.map +0 -1
  235. package/dist/tests/fixtures/StreamString.d.ts +0 -10
  236. package/dist/tests/fixtures/StreamString.d.ts.map +0 -1
  237. package/dist/tests/fixtures/prettierPluginFoo.d.ts +0 -4
  238. package/dist/tests/fixtures/prettierPluginFoo.d.ts.map +0 -1
  239. package/dist/tests/fixtures/util.d.ts +0 -8
  240. package/dist/tests/fixtures/util.d.ts.map +0 -1
  241. package/dist/tests/runtime/DefaultContext.test.d.ts +0 -2
  242. package/dist/tests/runtime/DefaultContext.test.d.ts.map +0 -1
  243. package/dist/tests/runtime/argument/ArgumentTypeGuards.test.d.ts +0 -2
  244. package/dist/tests/runtime/argument/ArgumentTypeGuards.test.d.ts.map +0 -1
  245. package/dist/tests/runtime/command/CommandTypeGuards.test.d.ts +0 -2
  246. package/dist/tests/runtime/command/CommandTypeGuards.test.d.ts.map +0 -1
  247. package/dist/tests/runtime/command/CommandValidator.test.d.ts +0 -2
  248. package/dist/tests/runtime/command/CommandValidator.test.d.ts.map +0 -1
  249. package/dist/tests/runtime/parser.test.d.ts +0 -2
  250. package/dist/tests/runtime/parser.test.d.ts.map +0 -1
  251. package/dist/tests/runtime/registry/DefaultCommandRegistry.test.d.ts +0 -2
  252. package/dist/tests/runtime/registry/DefaultCommandRegistry.test.d.ts.map +0 -1
  253. package/dist/tests/runtime/registry/DefaultServiceProviderRegistry.test.d.ts +0 -2
  254. package/dist/tests/runtime/registry/DefaultServiceProviderRegistry.test.d.ts.map +0 -1
  255. package/dist/tests/runtime/runner.test.d.ts +0 -2
  256. package/dist/tests/runtime/runner.test.d.ts.map +0 -1
  257. package/dist/tests/runtime/scanner.test.d.ts +0 -2
  258. package/dist/tests/runtime/scanner.test.d.ts.map +0 -1
  259. package/dist/tests/runtime/values/argumentValueMerge.test.d.ts +0 -2
  260. package/dist/tests/runtime/values/argumentValueMerge.test.d.ts.map +0 -1
  261. package/dist/tests/runtime/values/argumentValueValidation.test.d.ts +0 -2
  262. package/dist/tests/runtime/values/argumentValueValidation.test.d.ts.map +0 -1
  263. package/dist/tests/runtime/values/globalCommandValuePopulation.test.d.ts +0 -2
  264. package/dist/tests/runtime/values/globalCommandValuePopulation.test.d.ts.map +0 -1
  265. package/dist/tests/runtime/values/subCommandValuePopulation.test.d.ts +0 -2
  266. package/dist/tests/runtime/values/subCommandValuePopulation.test.d.ts.map +0 -1
  267. package/dist/tests/service/argumentPrompter/ArgumentPrompterServiceProvider.test.d.ts +0 -2
  268. package/dist/tests/service/argumentPrompter/ArgumentPrompterServiceProvider.test.d.ts.map +0 -1
  269. package/dist/tests/service/argumentPrompter/DefaultArgumentPrompterService.test.d.ts +0 -2
  270. package/dist/tests/service/argumentPrompter/DefaultArgumentPrompterService.test.d.ts.map +0 -1
  271. package/dist/tests/service/asciiBannerGenerator/AsciiBannerGeneratorServiceProvider.test.d.ts +0 -2
  272. package/dist/tests/service/asciiBannerGenerator/AsciiBannerGeneratorServiceProvider.test.d.ts.map +0 -1
  273. package/dist/tests/service/asciiBannerGenerator/DefaultAsciiBannerGeneratorService.test.d.ts +0 -2
  274. package/dist/tests/service/asciiBannerGenerator/DefaultAsciiBannerGeneratorService.test.d.ts.map +0 -1
  275. package/dist/tests/service/banner/BannerServiceProvider.test.d.ts +0 -2
  276. package/dist/tests/service/banner/BannerServiceProvider.test.d.ts.map +0 -1
  277. package/dist/tests/service/banner/command/NoBannerCommand.test.d.ts +0 -2
  278. package/dist/tests/service/banner/command/NoBannerCommand.test.d.ts.map +0 -1
  279. package/dist/tests/service/chiselAsciiBannerGenerator/ChiselFontAsciiBannerGeneratorService.test.d.ts +0 -2
  280. package/dist/tests/service/chiselAsciiBannerGenerator/ChiselFontAsciiBannerGeneratorService.test.d.ts.map +0 -1
  281. package/dist/tests/service/completion/CompletionServiceProvider.test.d.ts +0 -2
  282. package/dist/tests/service/completion/CompletionServiceProvider.test.d.ts.map +0 -1
  283. package/dist/tests/service/completion/DefaultCompletionService.test.d.ts +0 -2
  284. package/dist/tests/service/completion/DefaultCompletionService.test.d.ts.map +0 -1
  285. package/dist/tests/service/completion/shell/bash.test.d.ts +0 -2
  286. package/dist/tests/service/completion/shell/bash.test.d.ts.map +0 -1
  287. package/dist/tests/service/completion/shell/fish.test.d.ts +0 -2
  288. package/dist/tests/service/completion/shell/fish.test.d.ts.map +0 -1
  289. package/dist/tests/service/completion/shell/powershell.test.d.ts +0 -2
  290. package/dist/tests/service/completion/shell/powershell.test.d.ts.map +0 -1
  291. package/dist/tests/service/completion/shell/zsh.test.d.ts +0 -2
  292. package/dist/tests/service/completion/shell/zsh.test.d.ts.map +0 -1
  293. package/dist/tests/service/configuration/ConfigurationServiceProvider.test.d.ts +0 -2
  294. package/dist/tests/service/configuration/ConfigurationServiceProvider.test.d.ts.map +0 -1
  295. package/dist/tests/service/configuration/DefaultKeyValueService.test.d.ts +0 -2
  296. package/dist/tests/service/configuration/DefaultKeyValueService.test.d.ts.map +0 -1
  297. package/dist/tests/service/configuration/DefaultSecretService.test.d.ts +0 -2
  298. package/dist/tests/service/configuration/DefaultSecretService.test.d.ts.map +0 -1
  299. package/dist/tests/service/configuration/command/ConfigCommand.test.d.ts +0 -2
  300. package/dist/tests/service/configuration/command/ConfigCommand.test.d.ts.map +0 -1
  301. package/dist/tests/service/configuration/command/DumpConfigCommand.test.d.ts +0 -2
  302. package/dist/tests/service/configuration/command/DumpConfigCommand.test.d.ts.map +0 -1
  303. package/dist/tests/service/dataDumpGenerator/DataDumpGeneratorServiceProvider.test.d.ts +0 -2
  304. package/dist/tests/service/dataDumpGenerator/DataDumpGeneratorServiceProvider.test.d.ts.map +0 -1
  305. package/dist/tests/service/dataDumpGenerator/DefaultDataDumpGeneratorService.test.d.ts +0 -2
  306. package/dist/tests/service/dataDumpGenerator/DefaultDataDumpGeneratorService.test.d.ts.map +0 -1
  307. package/dist/tests/service/imagePrinter/DefaultImagePrinterService.test.d.ts +0 -2
  308. package/dist/tests/service/imagePrinter/DefaultImagePrinterService.test.d.ts.map +0 -1
  309. package/dist/tests/service/imagePrinter/ImagePrinterServiceProvider.test.d.ts +0 -2
  310. package/dist/tests/service/imagePrinter/ImagePrinterServiceProvider.test.d.ts.map +0 -1
  311. package/dist/tests/service/plugin/DefaultPluginServiceProvider.test.d.ts +0 -2
  312. package/dist/tests/service/plugin/DefaultPluginServiceProvider.test.d.ts.map +0 -1
  313. package/dist/tests/service/prettyPrinter/DefaultPrettyPrinterService.test.d.ts +0 -2
  314. package/dist/tests/service/prettyPrinter/DefaultPrettyPrinterService.test.d.ts.map +0 -1
  315. package/dist/tests/service/prettyPrinter/PrettyPrinterServiceProvider.test.d.ts +0 -2
  316. package/dist/tests/service/prettyPrinter/PrettyPrinterServiceProvider.test.d.ts.map +0 -1
  317. package/dist/tests/service/printer/DefaultPrinterService.test.d.ts +0 -2
  318. package/dist/tests/service/printer/DefaultPrinterService.test.d.ts.map +0 -1
  319. package/dist/tests/service/printer/PrinterServiceProvider.test.d.ts +0 -2
  320. package/dist/tests/service/printer/PrinterServiceProvider.test.d.ts.map +0 -1
  321. package/dist/tests/service/printer/command/DarkModeCommand.test.d.ts +0 -2
  322. package/dist/tests/service/printer/command/DarkModeCommand.test.d.ts.map +0 -1
  323. package/dist/tests/service/printer/command/LogLevelCommand.test.d.ts +0 -2
  324. package/dist/tests/service/printer/command/LogLevelCommand.test.d.ts.map +0 -1
  325. package/dist/tests/service/printer/command/NoColorCommand.test.d.ts +0 -2
  326. package/dist/tests/service/printer/command/NoColorCommand.test.d.ts.map +0 -1
  327. package/dist/tests/service/printer/command/NoHyperlinksCommand.test.d.ts +0 -2
  328. package/dist/tests/service/printer/command/NoHyperlinksCommand.test.d.ts.map +0 -1
  329. package/dist/tests/service/printer/terminal/Progress.test.d.ts +0 -2
  330. package/dist/tests/service/printer/terminal/Progress.test.d.ts.map +0 -1
  331. package/dist/tests/service/printer/terminal/Spinner.test.d.ts +0 -2
  332. package/dist/tests/service/printer/terminal/Spinner.test.d.ts.map +0 -1
  333. package/dist/tests/service/prompter/DefaultPrompterService.test.d.ts +0 -2
  334. package/dist/tests/service/prompter/DefaultPrompterService.test.d.ts.map +0 -1
  335. package/dist/tests/service/prompter/PrompterServiceProvider.test.d.ts +0 -2
  336. package/dist/tests/service/prompter/PrompterServiceProvider.test.d.ts.map +0 -1
  337. package/dist/tests/service/prompter/command/NoPromptCommand.test.d.ts +0 -2
  338. package/dist/tests/service/prompter/command/NoPromptCommand.test.d.ts.map +0 -1
  339. package/dist/tests/service/prompter/prompt/PromptContext.test.d.ts +0 -2
  340. package/dist/tests/service/prompter/prompt/PromptContext.test.d.ts.map +0 -1
  341. package/dist/tests/service/shutdown/ShutdownServiceProvider.test.d.ts +0 -2
  342. package/dist/tests/service/shutdown/ShutdownServiceProvider.test.d.ts.map +0 -1
  343. package/dist/tests/service/syntaxHighlighter/DefaultSyntaxHighlighterService.test.d.ts +0 -2
  344. package/dist/tests/service/syntaxHighlighter/DefaultSyntaxHighlighterService.test.d.ts.map +0 -1
  345. package/dist/tests/service/syntaxHighlighter/SyntaxHighlighterServiceProvider.test.d.ts +0 -2
  346. package/dist/tests/service/syntaxHighlighter/SyntaxHighlighterServiceProvider.test.d.ts.map +0 -1
  347. package/dist/tests/service/tableGenerator/DefaultTableGeneratorService.test.d.ts +0 -2
  348. package/dist/tests/service/tableGenerator/DefaultTableGeneratorService.test.d.ts.map +0 -1
  349. package/dist/tests/service/tableGenerator/TableGeneratorServiceProvider.test.d.ts +0 -2
  350. package/dist/tests/service/tableGenerator/TableGeneratorServiceProvider.test.d.ts.map +0 -1
  351. package/dist/tests/service/treePrinter/DefaultTreePrinterService.test.d.ts +0 -2
  352. package/dist/tests/service/treePrinter/DefaultTreePrinterService.test.d.ts.map +0 -1
  353. package/dist/tests/service/treePrinter/TreePrinterServiceProvider.test.d.ts +0 -2
  354. package/dist/tests/service/treePrinter/TreePrinterServiceProvider.test.d.ts.map +0 -1
  355. package/dist/tests/terminal/ImageRenderer.test.d.ts +0 -2
  356. package/dist/tests/terminal/ImageRenderer.test.d.ts.map +0 -1
  357. package/dist/tests/terminal/PngDecoder.test.d.ts +0 -2
  358. package/dist/tests/terminal/PngDecoder.test.d.ts.map +0 -1
  359. package/dist/tests/terminal/supportsHyperlinks.test.d.ts +0 -2
  360. package/dist/tests/terminal/supportsHyperlinks.test.d.ts.map +0 -1
  361. package/dist/tests/util/configHelper.test.d.ts +0 -2
  362. package/dist/tests/util/configHelper.test.d.ts.map +0 -1
  363. package/dist/tests/util/envVarHelper.test.d.ts +0 -2
  364. package/dist/tests/util/envVarHelper.test.d.ts.map +0 -1
  365. package/dist/tests/util/logger.test.d.ts +0 -2
  366. package/dist/tests/util/logger.test.d.ts.map +0 -1
  367. package/src/command/PluginCommand.ts +0 -197
@@ -0,0 +1,160 @@
1
+ import process from "node:process";
2
+ import { COMPLETION_SERVICE_ID } from "../../api/service/core/CompletionService.js";
3
+ import { ShellType } from "../../api/service/core/CompletionService.js";
4
+ import { PROMPTER_SERVICE_ID } from "../../api/service/core/PrompterService.js";
5
+ import { PromptType } from "../../api/service/core/PrompterService.js";
6
+ import { KEY_VALUE_SERVICE_ID } from "../../api/service/core/KeyValueService.js";
7
+ import { Icon, PRINTER_SERVICE_ID } from "../../api/service/core/PrinterService.js";
8
+ import getLogger from "../../util/logger.js";
9
+ import { CompletionIntegrationSubCommand } from "./command/CompletionIntegrationSubCommand.js";
10
+ import { CompletionCompleteSubCommand } from "./command/CompletionCompleteSubCommand.js";
11
+ import { CompletionGroupCommand } from "./command/CompletionGroupCommand.js";
12
+ const logger = getLogger("CompletionServiceProvider");
13
+ export default class CompletionServiceProvider {
14
+ serviceId = COMPLETION_SERVICE_ID;
15
+ servicePriority;
16
+ #completionService;
17
+ #cliName = "";
18
+ constructor(servicePriority, completionService, commandRegistry) {
19
+ this.servicePriority = servicePriority;
20
+ this.#completionService = completionService;
21
+ this.#completionService.setCommandRegistry(commandRegistry);
22
+ }
23
+ getServiceInfo(cliConfig) {
24
+ this.#cliName = cliConfig.name;
25
+ return Promise.resolve({
26
+ service: this.#completionService,
27
+ commands: [
28
+ new CompletionGroupCommand(new CompletionIntegrationSubCommand(), new CompletionCompleteSubCommand()),
29
+ ],
30
+ });
31
+ }
32
+ async initService(context) {
33
+ if (!context.doesServiceExist(PROMPTER_SERVICE_ID)) {
34
+ logger.debug(() => "PrompterService not available, skipping auto-prompt");
35
+ return;
36
+ }
37
+ if (!context.doesServiceExist(KEY_VALUE_SERVICE_ID)) {
38
+ logger.debug(() => "KeyValueService not available, skipping auto-prompt");
39
+ return;
40
+ }
41
+ const keyValueService = context.getServiceById(KEY_VALUE_SERVICE_ID);
42
+ if (await keyValueService.hasKey("completion-status")) {
43
+ const status = await keyValueService.getKey("completion-status");
44
+ if (status === "installed" || status === "declined") {
45
+ logger.debug(() => `Completion status is '${status}', skipping auto-prompt`);
46
+ return;
47
+ }
48
+ }
49
+ const prompterService = context.getServiceById(PROMPTER_SERVICE_ID);
50
+ if (!prompterService.promptEnabled) {
51
+ logger.debug(() => "Prompting is disabled, skipping auto-prompt");
52
+ return;
53
+ }
54
+ const detectedShells = await this.#detectAvailableShells();
55
+ if (detectedShells.length === 0) {
56
+ logger.debug(() => "No supported shells detected, skipping auto-prompt");
57
+ return;
58
+ }
59
+ let enableResult;
60
+ try {
61
+ enableResult = await prompterService.prompt({
62
+ name: "enable-completion",
63
+ promptText: "Would you like to enable autocompletion?",
64
+ description: "This will set up your terminal so that pressing TAB while typing commands will show possible options and autocomplete arguments.\n(Enabling autocompletion will modify configuration files in your home directory.)",
65
+ type: PromptType.TOGGLE,
66
+ options: [
67
+ { displayValue: "Yes", returnedValue: true },
68
+ { displayValue: "No", returnedValue: false },
69
+ ],
70
+ });
71
+ }
72
+ catch {
73
+ return;
74
+ }
75
+ if (enableResult.value !== true) {
76
+ await keyValueService.setKey("completion-status", "declined");
77
+ return;
78
+ }
79
+ let shellType;
80
+ if (detectedShells.length === 1) {
81
+ shellType = detectedShells[0];
82
+ }
83
+ else {
84
+ const shellOptions = detectedShells.map((shell) => ({
85
+ displayValue: shell,
86
+ returnedValue: shell,
87
+ }));
88
+ let shellResult;
89
+ try {
90
+ shellResult = await prompterService.prompt({
91
+ name: "shell-type",
92
+ promptText: "Which shell would you like to configure?",
93
+ type: PromptType.SINGLE_SELECT,
94
+ defaultOption: shellOptions[0],
95
+ options: shellOptions,
96
+ });
97
+ }
98
+ catch {
99
+ return;
100
+ }
101
+ shellType = shellResult.value;
102
+ }
103
+ try {
104
+ await this.#installCompletion(context, shellType);
105
+ await keyValueService.setKey("completion-status", "installed");
106
+ }
107
+ catch (error) {
108
+ logger.error("Failed to install completion: %s", error.message);
109
+ if (context.doesServiceExist(PRINTER_SERVICE_ID)) {
110
+ const printerService = context.getServiceById(PRINTER_SERVICE_ID);
111
+ await printerService.error(`Failed to install completion: ${error.message}`, Icon.FAILURE);
112
+ }
113
+ }
114
+ }
115
+ async #detectAvailableShells() {
116
+ const available = [];
117
+ for (const shell of Object.values(ShellType)) {
118
+ if (await this.#completionService.validateShellEnvironment(shell)) {
119
+ available.push(shell);
120
+ }
121
+ }
122
+ return available;
123
+ }
124
+ async #installCompletion(context, shellType) {
125
+ const configPath = this.#completionService.getDefaultConfigPath(shellType);
126
+ const bootstrapScript = this.#completionService.getBootstrapScript(shellType, this.#cliName, process.execPath);
127
+ const beginMarker = `# BEGIN ${this.#cliName} completion`;
128
+ const endMarker = `# END ${this.#cliName} completion`;
129
+ const block = `${beginMarker}\n${bootstrapScript}\n${endMarker}`;
130
+ let existingContent = "";
131
+ try {
132
+ existingContent = await Bun.file(configPath).text();
133
+ }
134
+ catch {
135
+ // File doesn't exist yet
136
+ }
137
+ let newContent;
138
+ const beginIdx = existingContent.indexOf(beginMarker);
139
+ const endIdx = existingContent.indexOf(endMarker);
140
+ if (beginIdx !== -1 && endIdx !== -1) {
141
+ newContent =
142
+ existingContent.substring(0, beginIdx) +
143
+ block +
144
+ existingContent.substring(endIdx + endMarker.length);
145
+ }
146
+ else {
147
+ const separator = existingContent.length > 0 && !existingContent.endsWith("\n")
148
+ ? "\n\n"
149
+ : existingContent.length > 0
150
+ ? "\n"
151
+ : "";
152
+ newContent = existingContent + separator + block + "\n";
153
+ }
154
+ await Bun.write(configPath, newContent);
155
+ if (context.doesServiceExist(PRINTER_SERVICE_ID)) {
156
+ const printerService = context.getServiceById(PRINTER_SERVICE_ID);
157
+ await printerService.info(`Shell completion installed for ${shellType}. Restart your shell or run 'source ${configPath}' to activate.`, Icon.SUCCESS);
158
+ }
159
+ }
160
+ }
@@ -0,0 +1,279 @@
1
+ import { ShellType } from "../../api/service/core/CompletionService.js";
2
+ import BashShellHandler from "./shell/bash.js";
3
+ import ZshShellHandler from "./shell/zsh.js";
4
+ import FishShellHandler from "./shell/fish.js";
5
+ import PowerShellShellHandler from "./shell/powershell.js";
6
+ export default class DefaultCompletionService {
7
+ #commandRegistry;
8
+ #shellHandlers = new Map([
9
+ [ShellType.BASH, new BashShellHandler()],
10
+ [ShellType.ZSH, new ZshShellHandler()],
11
+ [ShellType.FISH, new FishShellHandler()],
12
+ [ShellType.POWERSHELL, new PowerShellShellHandler()],
13
+ ]);
14
+ setCommandRegistry(registry) {
15
+ this.#commandRegistry = registry;
16
+ }
17
+ getBootstrapScript(shellType, cliName, executablePath) {
18
+ return this.#getHandler(shellType).getBootstrapScript(cliName, executablePath);
19
+ }
20
+ getDefaultConfigPath(shellType) {
21
+ return this.#getHandler(shellType).getDefaultConfigPath();
22
+ }
23
+ validateShellEnvironment(shellType) {
24
+ return this.#getHandler(shellType).validateEnvironment();
25
+ }
26
+ formatCompletions(shellType, completions) {
27
+ return this.#getHandler(shellType).formatCompletions(completions);
28
+ }
29
+ parseCompletionContext(shell, args) {
30
+ return this.#getHandler(shell).parseCompletionContext(args);
31
+ }
32
+ generateCompletions(_shellType, line, cursorPosition) {
33
+ if (!this.#commandRegistry) {
34
+ return Promise.resolve([]);
35
+ }
36
+ const beforeCursor = line.substring(0, cursorPosition);
37
+ const words = this.#tokenize(beforeCursor);
38
+ // Remove CLI name (first word)
39
+ const relevantWords = words.slice(1);
40
+ const currentWord = relevantWords[relevantWords.length - 1] ?? "";
41
+ const previousWords = relevantWords.slice(0, -1);
42
+ const endsWithSpace = beforeCursor.endsWith(" ");
43
+ if (relevantWords.length === 0 || (relevantWords.length === 1 && !endsWithSpace)) {
44
+ return Promise.resolve(this.#completeCommandName(currentWord));
45
+ }
46
+ if (endsWithSpace) {
47
+ const commandWord = relevantWords[0];
48
+ return Promise.resolve(this.#completeAfterCommand(commandWord, relevantWords.slice(1), ""));
49
+ }
50
+ const commandWord = previousWords[0];
51
+ if (commandWord) {
52
+ return Promise.resolve(this.#completeAfterCommand(commandWord, previousWords.slice(1), currentWord));
53
+ }
54
+ return Promise.resolve(this.#completeCommandName(currentWord));
55
+ }
56
+ #completeAfterCommand(commandWord, intermediateWords, currentWord) {
57
+ // Check for group:member pattern
58
+ if (commandWord.includes(":")) {
59
+ const result = this.#commandRegistry.getGroupCommandAndMemberSubCommandByJoinedName(commandWord);
60
+ if (result) {
61
+ return this.#completeSubCommandArgs(result.command, intermediateWords, currentWord);
62
+ }
63
+ }
64
+ // Check if partial group:member (e.g. "completions:" completing member)
65
+ if (currentWord.includes(":")) {
66
+ const colonIdx = currentWord.indexOf(":");
67
+ const groupPart = currentWord.substring(0, colonIdx);
68
+ const groupCommand = this.#commandRegistry.getGroupCommandByName(groupPart);
69
+ if (groupCommand) {
70
+ return groupCommand.memberSubCommands
71
+ .filter((sc) => `${groupPart}:${sc.name}`.startsWith(currentWord))
72
+ .map((sc) => ({
73
+ value: `${groupPart}:${sc.name}`,
74
+ description: sc.description,
75
+ }));
76
+ }
77
+ }
78
+ // Check global command (--name pattern)
79
+ if (commandWord.startsWith("--")) {
80
+ const globalCommandName = commandWord.substring(2);
81
+ const globalCommand = this.#commandRegistry.getGlobalCommandByName(globalCommandName);
82
+ if (globalCommand) {
83
+ if (globalCommand.argument?.allowableValues) {
84
+ return globalCommand.argument.allowableValues
85
+ .filter((v) => String(v).startsWith(currentWord))
86
+ .map((v) => ({ value: String(v) }));
87
+ }
88
+ return [];
89
+ }
90
+ }
91
+ // Check sub-command
92
+ const subCommand = this.#commandRegistry.getSubCommandByName(commandWord);
93
+ if (subCommand) {
94
+ return this.#completeSubCommandArgs(subCommand, intermediateWords, currentWord);
95
+ }
96
+ // Check group command (suggest members)
97
+ const groupCommand = this.#commandRegistry.getGroupCommandByName(commandWord);
98
+ if (groupCommand) {
99
+ return groupCommand.memberSubCommands
100
+ .filter((sc) => sc.name.startsWith(currentWord))
101
+ .map((sc) => ({
102
+ value: `${commandWord}:${sc.name}`,
103
+ description: sc.description,
104
+ }));
105
+ }
106
+ return this.#completeCommandName(currentWord);
107
+ }
108
+ #completeCommandName(prefix) {
109
+ const completions = [];
110
+ // Sub-commands
111
+ const subCommands = this.#commandRegistry.getSubCommands();
112
+ for (const cmd of subCommands) {
113
+ if (cmd.name.startsWith(prefix)) {
114
+ completions.push({ value: cmd.name, description: cmd.description });
115
+ }
116
+ }
117
+ // Group:member joined names
118
+ const groupAndMembers = this.#commandRegistry.getGroupAndMemberCommandsByJoinedName();
119
+ for (const [joinedName, entry] of groupAndMembers) {
120
+ if (joinedName.startsWith(prefix)) {
121
+ completions.push({
122
+ value: joinedName,
123
+ description: entry.command.description,
124
+ });
125
+ }
126
+ }
127
+ // Group command names (to suggest further typing "group:")
128
+ const groupCommands = this.#commandRegistry.getGroupCommands();
129
+ for (const cmd of groupCommands) {
130
+ if (cmd.name.startsWith(prefix) && !prefix.includes(":")) {
131
+ completions.push({
132
+ value: cmd.name,
133
+ description: cmd.description,
134
+ });
135
+ }
136
+ }
137
+ // Global commands (with -- prefix)
138
+ const globalCommands = this.#commandRegistry.getGlobalCommands();
139
+ for (const cmd of globalCommands) {
140
+ const prefixed = `--${cmd.name}`;
141
+ if (prefixed.startsWith(prefix)) {
142
+ completions.push({ value: prefixed, description: cmd.description });
143
+ }
144
+ }
145
+ // Global modifier commands (with -- prefix)
146
+ const modifierCommands = this.#commandRegistry.getGlobalModifierCommands();
147
+ for (const cmd of modifierCommands) {
148
+ const prefixed = `--${cmd.name}`;
149
+ if (prefixed.startsWith(prefix)) {
150
+ completions.push({ value: prefixed, description: cmd.description });
151
+ }
152
+ }
153
+ return completions;
154
+ }
155
+ #completeSubCommandArgs(subCommand, previousArgs, currentWord) {
156
+ const completions = [];
157
+ // If current word starts with --, complete option names
158
+ if (currentWord.startsWith("--")) {
159
+ const prefix = currentWord.substring(2);
160
+ for (const opt of subCommand.options) {
161
+ if ("name" in opt && opt.name.startsWith(prefix)) {
162
+ completions.push({
163
+ value: `--${opt.name}`,
164
+ description: opt.description,
165
+ });
166
+ }
167
+ }
168
+ return completions;
169
+ }
170
+ // If current word starts with -, complete short aliases
171
+ if (currentWord.startsWith("-") && currentWord.length <= 2) {
172
+ for (const opt of subCommand.options) {
173
+ if ("shortAlias" in opt && opt.shortAlias) {
174
+ const alias = `-${opt.shortAlias}`;
175
+ if (alias.startsWith(currentWord)) {
176
+ completions.push({
177
+ value: alias,
178
+ description: opt.description,
179
+ });
180
+ }
181
+ }
182
+ }
183
+ return completions;
184
+ }
185
+ // Check if previous word was an option expecting a value
186
+ const lastPrevWord = previousArgs[previousArgs.length - 1];
187
+ if (lastPrevWord && lastPrevWord.startsWith("--")) {
188
+ const optName = lastPrevWord.substring(2);
189
+ const option = subCommand.options.find((o) => "name" in o && o.name === optName);
190
+ if (option && option.allowableValues) {
191
+ return option.allowableValues
192
+ .filter((v) => String(v).startsWith(currentWord))
193
+ .map((v) => ({ value: String(v) }));
194
+ }
195
+ }
196
+ // Suggest options that haven't been used
197
+ for (const opt of subCommand.options) {
198
+ if ("name" in opt) {
199
+ const optName = `--${opt.name}`;
200
+ if (!previousArgs.includes(optName) && optName.startsWith(currentWord)) {
201
+ completions.push({
202
+ value: optName,
203
+ description: opt.description,
204
+ });
205
+ }
206
+ }
207
+ }
208
+ // Suggest positional allowable values
209
+ const positionalIndex = this.#countPositionalArgs(previousArgs, subCommand);
210
+ if (positionalIndex < subCommand.positionals.length) {
211
+ const positional = subCommand.positionals[positionalIndex];
212
+ if (positional.allowableValues) {
213
+ for (const v of positional.allowableValues) {
214
+ if (String(v).startsWith(currentWord)) {
215
+ completions.push({ value: String(v) });
216
+ }
217
+ }
218
+ }
219
+ }
220
+ return completions;
221
+ }
222
+ #countPositionalArgs(args, subCommand) {
223
+ let count = 0;
224
+ let i = 0;
225
+ while (i < args.length) {
226
+ const arg = args[i];
227
+ if (arg.startsWith("-")) {
228
+ // Skip option and its value
229
+ const optName = arg.startsWith("--") ? arg.substring(2) : undefined;
230
+ const option = optName
231
+ ? subCommand.options.find((o) => "name" in o && o.name === optName)
232
+ : undefined;
233
+ if (option && option.type !== undefined) {
234
+ i++; // skip the option value
235
+ }
236
+ }
237
+ else {
238
+ count++;
239
+ }
240
+ i++;
241
+ }
242
+ return count;
243
+ }
244
+ #tokenize(input) {
245
+ const words = [];
246
+ let current = "";
247
+ let inSingleQuote = false;
248
+ let inDoubleQuote = false;
249
+ for (let i = 0; i < input.length; i++) {
250
+ const ch = input[i];
251
+ if (ch === "'" && !inDoubleQuote) {
252
+ inSingleQuote = !inSingleQuote;
253
+ }
254
+ else if (ch === '"' && !inSingleQuote) {
255
+ inDoubleQuote = !inDoubleQuote;
256
+ }
257
+ else if (ch === " " && !inSingleQuote && !inDoubleQuote) {
258
+ if (current.length > 0) {
259
+ words.push(current);
260
+ current = "";
261
+ }
262
+ }
263
+ else {
264
+ current += ch;
265
+ }
266
+ }
267
+ if (current.length > 0) {
268
+ words.push(current);
269
+ }
270
+ return words;
271
+ }
272
+ #getHandler(shellType) {
273
+ const handler = this.#shellHandlers.get(shellType);
274
+ if (!handler) {
275
+ throw new Error(`Unsupported shell type: ${shellType}`);
276
+ }
277
+ return handler;
278
+ }
279
+ }
@@ -0,0 +1,15 @@
1
+ import type SubCommand from "../../../api/command/SubCommand.ts";
2
+ import type Option from "../../../api/argument/Option.ts";
3
+ import type Positional from "../../../api/argument/Positional.ts";
4
+ import type Context from "../../../api/Context.ts";
5
+ import { type ArgumentValues } from "../../../api/argument/ArgumentValueTypes.ts";
6
+ export declare class CompletionCompleteSubCommand implements SubCommand {
7
+ readonly name = "complete";
8
+ readonly description = "Generate completions for shell integration";
9
+ readonly enableConfiguration = false;
10
+ readonly disableGenericHelpDisplay = true;
11
+ readonly options: ReadonlyArray<Option>;
12
+ readonly positionals: ReadonlyArray<Positional>;
13
+ execute(context: Context, argumentValues: ArgumentValues): Promise<void>;
14
+ }
15
+ //# sourceMappingURL=CompletionCompleteSubCommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CompletionCompleteSubCommand.d.ts","sourceRoot":"","sources":["../../../../../src/service/completion/command/CompletionCompleteSubCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,oCAAoC,CAAC;AACjE,OAAO,KAAK,MAAM,MAAM,iCAAiC,CAAC;AAC1D,OAAO,KAAK,UAAU,MAAM,qCAAqC,CAAC;AAClE,OAAO,KAAK,OAAO,MAAM,yBAAyB,CAAC;AACnD,OAAO,EACL,KAAK,cAAc,EAEpB,MAAM,6CAA6C,CAAC;AAMrD,qBAAa,4BAA6B,YAAW,UAAU;IAC7D,QAAQ,CAAC,IAAI,cAAc;IAC3B,QAAQ,CAAC,WAAW,gDAAgD;IACpE,QAAQ,CAAC,mBAAmB,SAAS;IACrC,QAAQ,CAAC,yBAAyB,QAAQ;IAE1C,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAM;IAE7C,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,CAc7C;IAEI,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CAqB/E"}
@@ -0,0 +1,37 @@
1
+ import { ArgumentValueTypeName, } from "../../../api/argument/ArgumentValueTypes.js";
2
+ import { COMPLETION_SERVICE_ID, ShellType } from "../../../api/service/core/CompletionService.js";
3
+ import { PRINTER_SERVICE_ID } from "../../../api/service/core/PrinterService.js";
4
+ export class CompletionCompleteSubCommand {
5
+ name = "complete";
6
+ description = "Generate completions for shell integration";
7
+ enableConfiguration = false;
8
+ disableGenericHelpDisplay = true;
9
+ options = [];
10
+ positionals = [
11
+ {
12
+ name: "shell",
13
+ type: ArgumentValueTypeName.STRING,
14
+ allowableValues: Object.values(ShellType),
15
+ description: "Shell type",
16
+ },
17
+ {
18
+ name: "args",
19
+ type: ArgumentValueTypeName.STRING,
20
+ isVarargMultiple: true,
21
+ isVarargOptional: true,
22
+ description: "Shell-specific completion context arguments",
23
+ },
24
+ ];
25
+ async execute(context, argumentValues) {
26
+ const completionService = context.getServiceById(COMPLETION_SERVICE_ID);
27
+ const printerService = context.getServiceById(PRINTER_SERVICE_ID);
28
+ const shellType = argumentValues.shell;
29
+ const args = (argumentValues.args || []);
30
+ const completionContext = completionService.parseCompletionContext(shellType, args);
31
+ const completions = await completionService.generateCompletions(shellType, completionContext.line, completionContext.cursorPosition);
32
+ const output = completionService.formatCompletions(shellType, completions);
33
+ if (output.length > 0) {
34
+ await printerService.print(output + "\n");
35
+ }
36
+ }
37
+ }
@@ -0,0 +1,14 @@
1
+ import type GroupCommand from "../../../api/command/GroupCommand.ts";
2
+ import type SubCommand from "../../../api/command/SubCommand.ts";
3
+ import type Context from "../../../api/Context.ts";
4
+ import type { CompletionIntegrationSubCommand } from "./CompletionIntegrationSubCommand.ts";
5
+ import type { CompletionCompleteSubCommand } from "./CompletionCompleteSubCommand.ts";
6
+ export declare class CompletionGroupCommand implements GroupCommand {
7
+ readonly name = "completion";
8
+ readonly description = "Manage shell auto-completion";
9
+ readonly enableConfiguration = false;
10
+ readonly memberSubCommands: ReadonlyArray<SubCommand>;
11
+ constructor(integrationCommand: CompletionIntegrationSubCommand, completeCommand: CompletionCompleteSubCommand);
12
+ execute(_context: Context): Promise<void>;
13
+ }
14
+ //# sourceMappingURL=CompletionGroupCommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CompletionGroupCommand.d.ts","sourceRoot":"","sources":["../../../../../src/service/completion/command/CompletionGroupCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,sCAAsC,CAAC;AACrE,OAAO,KAAK,UAAU,MAAM,oCAAoC,CAAC;AACjE,OAAO,KAAK,OAAO,MAAM,yBAAyB,CAAC;AACnD,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,sCAAsC,CAAC;AAC5F,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AAEtF,qBAAa,sBAAuB,YAAW,YAAY;IACzD,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,WAAW,kCAAkC;IACtD,QAAQ,CAAC,mBAAmB,SAAS;IACrC,QAAQ,CAAC,iBAAiB,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;gBAGpD,kBAAkB,EAAE,+BAA+B,EACnD,eAAe,EAAE,4BAA4B;IAKzC,OAAO,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAChD"}
@@ -0,0 +1,10 @@
1
+ export class CompletionGroupCommand {
2
+ name = "completion";
3
+ description = "Manage shell auto-completion";
4
+ enableConfiguration = false;
5
+ memberSubCommands;
6
+ constructor(integrationCommand, completeCommand) {
7
+ this.memberSubCommands = [integrationCommand, completeCommand];
8
+ }
9
+ async execute(_context) { }
10
+ }
@@ -0,0 +1,14 @@
1
+ import type SubCommand from "../../../api/command/SubCommand.ts";
2
+ import type Option from "../../../api/argument/Option.ts";
3
+ import type Positional from "../../../api/argument/Positional.ts";
4
+ import type Context from "../../../api/Context.ts";
5
+ import { type ArgumentValues } from "../../../api/argument/ArgumentValueTypes.ts";
6
+ export declare class CompletionIntegrationSubCommand implements SubCommand {
7
+ readonly name = "integration";
8
+ readonly description = "Install shell completion integration";
9
+ readonly enableConfiguration = false;
10
+ readonly options: ReadonlyArray<Option>;
11
+ readonly positionals: ReadonlyArray<Positional>;
12
+ execute(context: Context, argumentValues: ArgumentValues): Promise<void>;
13
+ }
14
+ //# sourceMappingURL=CompletionIntegrationSubCommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CompletionIntegrationSubCommand.d.ts","sourceRoot":"","sources":["../../../../../src/service/completion/command/CompletionIntegrationSubCommand.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,UAAU,MAAM,oCAAoC,CAAC;AACjE,OAAO,KAAK,MAAM,MAAM,iCAAiC,CAAC;AAC1D,OAAO,KAAK,UAAU,MAAM,qCAAqC,CAAC;AAClE,OAAO,KAAK,OAAO,MAAM,yBAAyB,CAAC;AACnD,OAAO,EACL,KAAK,cAAc,EAEpB,MAAM,6CAA6C,CAAC;AAMrD,qBAAa,+BAAgC,YAAW,UAAU;IAChE,QAAQ,CAAC,IAAI,iBAAiB;IAC9B,QAAQ,CAAC,WAAW,0CAA0C;IAC9D,QAAQ,CAAC,mBAAmB,SAAS;IAErC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAOrC;IAEF,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,CAO7C;IAEI,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CA4D/E"}
@@ -0,0 +1,67 @@
1
+ import process from "node:process";
2
+ import { ArgumentValueTypeName, } from "../../../api/argument/ArgumentValueTypes.js";
3
+ import { COMPLETION_SERVICE_ID, ShellType } from "../../../api/service/core/CompletionService.js";
4
+ import { Icon, PRINTER_SERVICE_ID } from "../../../api/service/core/PrinterService.js";
5
+ export class CompletionIntegrationSubCommand {
6
+ name = "integration";
7
+ description = "Install shell completion integration";
8
+ enableConfiguration = false;
9
+ options = [
10
+ {
11
+ name: "config-path",
12
+ type: ArgumentValueTypeName.STRING,
13
+ isOptional: true,
14
+ description: "Path to shell configuration file",
15
+ },
16
+ ];
17
+ positionals = [
18
+ {
19
+ name: "shell",
20
+ type: ArgumentValueTypeName.STRING,
21
+ allowableValues: Object.values(ShellType),
22
+ description: "Shell type to configure",
23
+ },
24
+ ];
25
+ async execute(context, argumentValues) {
26
+ const completionService = context.getServiceById(COMPLETION_SERVICE_ID);
27
+ const printerService = context.getServiceById(PRINTER_SERVICE_ID);
28
+ const shellType = argumentValues.shell;
29
+ const configPathArg = argumentValues["config-path"];
30
+ const isValid = await completionService.validateShellEnvironment(shellType);
31
+ if (!isValid) {
32
+ await printerService.warn(`Shell '${shellType}' was not detected in the current environment. Proceeding anyway.\n`, Icon.ALERT);
33
+ }
34
+ const configPath = configPathArg || completionService.getDefaultConfigPath(shellType);
35
+ const cliName = context.cliConfig.name;
36
+ const bootstrapScript = completionService.getBootstrapScript(shellType, cliName, process.execPath);
37
+ const beginMarker = `# BEGIN ${cliName} completion`;
38
+ const endMarker = `# END ${cliName} completion`;
39
+ const block = `${beginMarker}\n${bootstrapScript}\n${endMarker}`;
40
+ let existingContent = "";
41
+ try {
42
+ existingContent = await Bun.file(configPath).text();
43
+ }
44
+ catch {
45
+ // File doesn't exist yet
46
+ }
47
+ let newContent;
48
+ const beginIdx = existingContent.indexOf(beginMarker);
49
+ const endIdx = existingContent.indexOf(endMarker);
50
+ if (beginIdx !== -1 && endIdx !== -1) {
51
+ newContent =
52
+ existingContent.substring(0, beginIdx) +
53
+ block +
54
+ existingContent.substring(endIdx + endMarker.length);
55
+ }
56
+ else {
57
+ const separator = existingContent.length > 0 && !existingContent.endsWith("\n")
58
+ ? "\n\n"
59
+ : existingContent.length > 0
60
+ ? "\n"
61
+ : "";
62
+ newContent = existingContent + separator + block + "\n";
63
+ }
64
+ await Bun.write(configPath, newContent);
65
+ await printerService.info(`Shell completion installed for ${shellType}. Restart your shell or run 'source ${configPath}' to activate.\n`);
66
+ }
67
+ }
@@ -0,0 +1,39 @@
1
+ import process from "node:process";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ // Reference: https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion.html
5
+ export default class BashShellHandler {
6
+ getDefaultConfigPath() {
7
+ return join(homedir(), ".bashrc");
8
+ }
9
+ getBootstrapScript(cliName, executablePath) {
10
+ return [
11
+ `_${cliName}_completions() {`,
12
+ ` local IFS=$'\\n'`,
13
+ ` COMPREPLY=( $("${executablePath}" completion:complete bash "\${COMP_LINE}" "\${COMP_POINT}" 2>/dev/null) )`,
14
+ `}`,
15
+ `complete -F _${cliName}_completions ${cliName}`,
16
+ ].join("\n");
17
+ }
18
+ validateEnvironment() {
19
+ const shell = process.env.SHELL || "";
20
+ if (shell.endsWith("/bash")) {
21
+ return Promise.resolve(true);
22
+ }
23
+ try {
24
+ const result = Bun.spawnSync(["bash", "--version"]);
25
+ return Promise.resolve(result.exitCode === 0);
26
+ }
27
+ catch {
28
+ return Promise.resolve(false);
29
+ }
30
+ }
31
+ formatCompletions(completions) {
32
+ return completions.map((c) => c.value).join("\n");
33
+ }
34
+ parseCompletionContext(args) {
35
+ const line = args[0] || "";
36
+ const cursorPosition = parseInt(args[1] || "0", 10) || line.length;
37
+ return { line, cursorPosition };
38
+ }
39
+ }