@flowscripter/dynamic-cli-framework 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +3 -0
  2. package/dist/index.d.ts +5 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +4 -1
  5. package/dist/src/cli/BaseCLI.d.ts +8 -1
  6. package/dist/src/cli/BaseCLI.d.ts.map +1 -1
  7. package/dist/src/cli/BaseCLI.js +38 -6
  8. package/dist/src/cli/BaseCLIFeatureOptions.d.ts +1 -0
  9. package/dist/src/cli/BaseCLIFeatureOptions.d.ts.map +1 -1
  10. package/dist/src/cli/DefaultRuntimeCLI.d.ts +4 -0
  11. package/dist/src/cli/DefaultRuntimeCLI.d.ts.map +1 -1
  12. package/dist/src/cli/DefaultRuntimeCLI.js +29 -1
  13. package/dist/src/service/plugin/DefaultPluginService.d.ts +1 -1
  14. package/dist/src/service/plugin/DefaultPluginService.d.ts.map +1 -1
  15. package/dist/src/service/plugin/DefaultPluginServiceProvider.d.ts +3 -2
  16. package/dist/src/service/plugin/DefaultPluginServiceProvider.d.ts.map +1 -1
  17. package/dist/src/service/plugin/DefaultPluginServiceProvider.js +22 -2
  18. package/dist/src/service/plugin/SpawnInterfaceAdapter.d.ts +19 -0
  19. package/dist/src/service/plugin/SpawnInterfaceAdapter.d.ts.map +1 -0
  20. package/dist/src/service/plugin/SpawnInterfaceAdapter.js +40 -0
  21. package/dist/src/service/printer/DefaultPrinterService.d.ts.map +1 -1
  22. package/dist/src/service/printer/DefaultPrinterService.js +15 -10
  23. package/dist/src/service/spawn/DefaultSpawnService.d.ts +7 -0
  24. package/dist/src/service/spawn/DefaultSpawnService.d.ts.map +1 -0
  25. package/dist/src/service/spawn/DefaultSpawnService.js +94 -0
  26. package/dist/src/service/spawn/SpawnServiceProvider.d.ts +12 -0
  27. package/dist/src/service/spawn/SpawnServiceProvider.d.ts.map +1 -0
  28. package/dist/src/service/spawn/SpawnServiceProvider.js +24 -0
  29. package/dist/src/terminal/NonTtyTerminal.d.ts +14 -0
  30. package/dist/src/terminal/NonTtyTerminal.d.ts.map +1 -0
  31. package/dist/src/terminal/NonTtyTerminal.js +36 -0
  32. package/dist/src/terminal/Terminal.d.ts +1 -0
  33. package/dist/src/terminal/Terminal.d.ts.map +1 -1
  34. package/dist/src/terminal/TtyStyler.d.ts +1 -0
  35. package/dist/src/terminal/TtyStyler.d.ts.map +1 -1
  36. package/dist/src/terminal/TtyStyler.js +6 -2
  37. package/dist/src/terminal/TtyTerminal.d.ts +1 -0
  38. package/dist/src/terminal/TtyTerminal.d.ts.map +1 -1
  39. package/dist/src/terminal/TtyTerminal.js +3 -0
  40. package/index.ts +10 -1
  41. package/package.json +3 -3
  42. package/src/cli/BaseCLI.ts +54 -13
  43. package/src/cli/BaseCLIFeatureOptions.ts +1 -0
  44. package/src/cli/DefaultRuntimeCLI.ts +52 -8
  45. package/src/service/plugin/DefaultPluginService.ts +1 -1
  46. package/src/service/plugin/DefaultPluginServiceProvider.ts +39 -3
  47. package/src/service/plugin/SpawnInterfaceAdapter.ts +62 -0
  48. package/src/service/printer/DefaultPrinterService.ts +16 -10
  49. package/src/service/spawn/DefaultSpawnService.ts +119 -0
  50. package/src/service/spawn/SpawnServiceProvider.ts +32 -0
  51. package/src/terminal/NonTtyTerminal.ts +48 -0
  52. package/src/terminal/Terminal.ts +1 -0
  53. package/src/terminal/TtyStyler.ts +6 -2
  54. package/src/terminal/TtyTerminal.ts +4 -0
package/README.md CHANGED
@@ -40,6 +40,9 @@
40
40
  configuration management, and user input prompting.
41
41
  - Graceful signal handling (SIGINT/SIGTERM) with shutdown hooks, cooperative
42
42
  cancellation for long-running commands, and triple-interrupt force exit.
43
+ - Graceful degradation when piped or run non-interactively: color,
44
+ hyperlinks, prompting, spinners/progress bars and image rendering are
45
+ automatically disabled based on which of `stdin`/`stdout`/`stderr` are TTYs.
43
46
  - Core (but optional) support for dynamic discovery and installation of commands
44
47
  and services using
45
48
  [dynamic-plugin-framework](https://github.com/flowscripter/dynamic-plugin-framework)
package/dist/index.d.ts CHANGED
@@ -43,6 +43,10 @@ export { SHUTDOWN_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
43
43
  export type { ShutdownService } from "@flowscripter/dynamic-cli-framework-api";
44
44
  export { default as DefaultShutdownService } from "./src/service/shutdown/DefaultShutdownService.ts";
45
45
  export { default as ShutdownServiceProvider } from "./src/service/shutdown/ShutdownServiceProvider.ts";
46
+ export { SPAWN_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
47
+ export type { SpawnOptions, SpawnResult, SpawnService, } from "@flowscripter/dynamic-cli-framework-api";
48
+ export { default as DefaultSpawnService } from "./src/service/spawn/DefaultSpawnService.ts";
49
+ export { default as SpawnServiceProvider } from "./src/service/spawn/SpawnServiceProvider.ts";
46
50
  export { SYNTAX_HIGHLIGHTER_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
47
51
  export type { SyntaxHighlighterService } from "@flowscripter/dynamic-cli-framework-api";
48
52
  export type { ColorScheme } from "@flowscripter/dynamic-cli-framework-api";
@@ -112,5 +116,5 @@ export type { default as Styler } from "./src/terminal/Styler.ts";
112
116
  export type { default as KeyReader, KeyEvent } from "./src/terminal/KeyReader.ts";
113
117
  export { SpecialKey } from "./src/terminal/KeyReader.ts";
114
118
  export { default as TtyKeyReader } from "./src/terminal/TtyKeyReader.ts";
115
- export { launchMultiCommandCLI, launchSingleCommandCLI, launchDynamicPluginMultiCommandCLI, } from "./src/launcher.ts";
119
+ export { launchDynamicPluginMultiCommandCLI, launchMultiCommandCLI, launchSingleCommandCLI, } from "./src/launcher.ts";
116
120
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -20,6 +20,9 @@ export { default as PrinterServiceProvider } from "./src/service/printer/Printer
20
20
  export { SHUTDOWN_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
21
21
  export { default as DefaultShutdownService } from "./src/service/shutdown/DefaultShutdownService.js";
22
22
  export { default as ShutdownServiceProvider } from "./src/service/shutdown/ShutdownServiceProvider.js";
23
+ export { SPAWN_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
24
+ export { default as DefaultSpawnService } from "./src/service/spawn/DefaultSpawnService.js";
25
+ export { default as SpawnServiceProvider } from "./src/service/spawn/SpawnServiceProvider.js";
23
26
  export { SYNTAX_HIGHLIGHTER_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
24
27
  export { default as DefaultSyntaxHighlighterService } from "./src/service/syntaxHighlighter/DefaultSyntaxHighlighterService.js";
25
28
  export { default as SyntaxHighlighterServiceProvider } from "./src/service/syntaxHighlighter/SyntaxHighlighterServiceProvider.js";
@@ -68,4 +71,4 @@ export { default as DynamicPluginRuntimeCLI } from "./src/cli/DynamicPluginRunti
68
71
  export { SpecialKey } from "./src/terminal/KeyReader.js";
69
72
  export { default as TtyKeyReader } from "./src/terminal/TtyKeyReader.js";
70
73
  // Convenience functions
71
- export { launchMultiCommandCLI, launchSingleCommandCLI, launchDynamicPluginMultiCommandCLI, } from "./src/launcher.js";
74
+ export { launchDynamicPluginMultiCommandCLI, launchMultiCommandCLI, launchSingleCommandCLI, } from "./src/launcher.js";
@@ -24,6 +24,13 @@ import type BaseCLIFeatureOptions from "./BaseCLIFeatureOptions.ts";
24
24
  * Optionally enabled via {@link BaseCLIFeatureOptions}:
25
25
  *
26
26
  * * {@link ImagePrinterServiceProvider}
27
+ * * {@link SpawnServiceProvider}
28
+ *
29
+ * `keyReader` is optional. If omitted, or if the stderr {@link Terminal} is not a TTY, prompting is
30
+ * unavailable: {@link PrompterServiceProvider} (and {@link ArgumentPrompterServiceProvider}, if
31
+ * enabled) are simply not registered. If `promptingEnabled` is `true` in that situation, {@link run}
32
+ * throws rather than failing later inside a prompt. Similarly {@link ImagePrinterServiceProvider} is
33
+ * only registered if the stdout {@link Terminal} is a TTY.
27
34
  *
28
35
  * By default the following commands are added:
29
36
  *
@@ -34,7 +41,7 @@ import type BaseCLIFeatureOptions from "./BaseCLIFeatureOptions.ts";
34
41
  */
35
42
  export default class BaseCLI implements CLI {
36
43
  #private;
37
- constructor(cliConfig: CLIConfig, stdoutWritableStream: WritableStream, stderrWritableStream: WritableStream, stdoutIsColor: boolean, stderrIsColor: boolean, stdoutTerminal: Terminal, stderrTerminal: Terminal, styler: Styler, keyReader: KeyReader, options?: BaseCLIFeatureOptions);
44
+ constructor(cliConfig: CLIConfig, stdoutWritableStream: WritableStream, stderrWritableStream: WritableStream, stdoutIsColor: boolean, stderrIsColor: boolean, stdoutTerminal: Terminal, stderrTerminal: Terminal, styler: Styler, keyReader: KeyReader | undefined, options?: BaseCLIFeatureOptions);
38
45
  /**
39
46
  * Add a {@link ServiceProvider} to the CLI's {@link ServiceProviderRegistry}.
40
47
  *
@@ -1 +1 @@
1
- {"version":3,"file":"BaseCLI.d.ts","sourceRoot":"","sources":["../../../src/cli/BaseCLI.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,yCAAyC,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAGvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA4BzE,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,QAAQ,MAAM,yBAAyB,CAAC;AAGpD,OAAO,KAAK,MAAM,MAAM,uBAAuB,CAAC;AAChD,OAAO,KAAK,SAAS,MAAM,0BAA0B,CAAC;AACtD,OAAO,KAAK,qBAAqB,MAAM,4BAA4B,CAAC;AAYpE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,OAAO,OAAO,OAAQ,YAAW,GAAG;;gBAavC,SAAS,EAAE,SAAS,EACpB,oBAAoB,EAAE,cAAc,EACpC,oBAAoB,EAAE,cAAc,EACpC,aAAa,EAAE,OAAO,EACtB,aAAa,EAAE,OAAO,EACtB,cAAc,EAAE,QAAQ,EACxB,cAAc,EAAE,QAAQ,EACxB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,EACpB,OAAO,CAAC,EAAE,qBAAqB;IA2DjC;;;;;;;OAOG;IACI,kBAAkB,CAAC,eAAe,EAAE,eAAe;IAI1D;;;;;;;;OAQG;IACI,UAAU,CAAC,OAAO,EAAE,OAAO;IAU5B,GAAG,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC;CAuJ3D"}
1
+ {"version":3,"file":"BaseCLI.d.ts","sourceRoot":"","sources":["../../../src/cli/BaseCLI.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,yCAAyC,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAGvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA4BzE,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,QAAQ,MAAM,yBAAyB,CAAC;AAGpD,OAAO,KAAK,MAAM,MAAM,uBAAuB,CAAC;AAChD,OAAO,KAAK,SAAS,MAAM,0BAA0B,CAAC;AACtD,OAAO,KAAK,qBAAqB,MAAM,4BAA4B,CAAC;AAapE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,CAAC,OAAO,OAAO,OAAQ,YAAW,GAAG;;gBAavC,SAAS,EAAE,SAAS,EACpB,oBAAoB,EAAE,cAAc,EACpC,oBAAoB,EAAE,cAAc,EACpC,aAAa,EAAE,OAAO,EACtB,aAAa,EAAE,OAAO,EACtB,cAAc,EAAE,QAAQ,EACxB,cAAc,EAAE,QAAQ,EACxB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,OAAO,CAAC,EAAE,qBAAqB;IA4DjC;;;;;;;OAOG;IACI,kBAAkB,CAAC,eAAe,EAAE,eAAe;IAI1D;;;;;;;;OAQG;IACI,UAAU,CAAC,OAAO,EAAE,OAAO;IAU5B,GAAG,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC;CAuL3D"}
@@ -25,6 +25,7 @@ import ArgumentPrompterServiceProvider from "../service/argumentPrompter/Argumen
25
25
  import DefaultCompletionService from "../service/completion/DefaultCompletionService.js";
26
26
  import CompletionServiceProvider from "../service/completion/CompletionServiceProvider.js";
27
27
  import ImagePrinterServiceProvider from "../service/imagePrinter/ImagePrinterServiceProvider.js";
28
+ import SpawnServiceProvider from "../service/spawn/SpawnServiceProvider.js";
28
29
  const logger = getLogger("BaseCLI");
29
30
  /**
30
31
  * Base implementation of a {@link CLI}.
@@ -42,6 +43,13 @@ const logger = getLogger("BaseCLI");
42
43
  * Optionally enabled via {@link BaseCLIFeatureOptions}:
43
44
  *
44
45
  * * {@link ImagePrinterServiceProvider}
46
+ * * {@link SpawnServiceProvider}
47
+ *
48
+ * `keyReader` is optional. If omitted, or if the stderr {@link Terminal} is not a TTY, prompting is
49
+ * unavailable: {@link PrompterServiceProvider} (and {@link ArgumentPrompterServiceProvider}, if
50
+ * enabled) are simply not registered. If `promptingEnabled` is `true` in that situation, {@link run}
51
+ * throws rather than failing later inside a prompt. Similarly {@link ImagePrinterServiceProvider} is
52
+ * only registered if the stdout {@link Terminal} is a TTY.
45
53
  *
46
54
  * By default the following commands are added:
47
55
  *
@@ -83,6 +91,7 @@ export default class BaseCLI {
83
91
  argumentPrompterServiceEnabled: false,
84
92
  completionServiceEnabled: false,
85
93
  imagePrinterServiceEnabled: false,
94
+ spawnServiceEnabled: false,
86
95
  validateAllCommands: false,
87
96
  promptingEnabled: true,
88
97
  ...options,
@@ -145,15 +154,38 @@ export default class BaseCLI {
145
154
  this.addServiceProvider(new ShutdownServiceProvider(100));
146
155
  this.addServiceProvider(new PrinterServiceProvider(80, this.#printerService));
147
156
  this.addServiceProvider(new TableGeneratorServiceProvider(70));
148
- const prompterService = new DefaultPrompterService(DEFAULT_PROMPTER_CONFIG, this.#stderrTerminal, this.#keyReader, this.#printerService);
149
- prompterService.promptEnabled = this.#options.promptingEnabled;
150
- this.addServiceProvider(new PrompterServiceProvider(75, prompterService));
157
+ const canPrompt = this.#keyReader !== undefined && this.#stderrTerminal.isTty();
158
+ if (this.#options.promptingEnabled && !canPrompt) {
159
+ throw new Error("promptingEnabled requires a keyReader and a TTY stderr terminal");
160
+ }
161
+ let prompterService;
162
+ if (canPrompt) {
163
+ prompterService = new DefaultPrompterService(DEFAULT_PROMPTER_CONFIG, this.#stderrTerminal, this.#keyReader, this.#printerService);
164
+ prompterService.promptEnabled = this.#options.promptingEnabled;
165
+ this.addServiceProvider(new PrompterServiceProvider(75, prompterService));
166
+ }
167
+ else {
168
+ logger.debug(() => `Skipping PrompterServiceProvider: keyReader present: ${this.#keyReader !== undefined}, stderr isTty: ${this.#stderrTerminal.isTty()}`);
169
+ }
151
170
  if (this.#options.argumentPrompterServiceEnabled) {
152
- const argumentPrompterService = new DefaultArgumentPrompterService(prompterService);
153
- this.addServiceProvider(new ArgumentPrompterServiceProvider(65, argumentPrompterService));
171
+ if (prompterService !== undefined) {
172
+ const argumentPrompterService = new DefaultArgumentPrompterService(prompterService);
173
+ this.addServiceProvider(new ArgumentPrompterServiceProvider(65, argumentPrompterService));
174
+ }
175
+ else {
176
+ logger.debug("Skipping ArgumentPrompterServiceProvider: argumentPrompterServiceEnabled is true but prompting is unavailable");
177
+ }
154
178
  }
155
179
  if (this.#options.imagePrinterServiceEnabled) {
156
- this.addServiceProvider(new ImagePrinterServiceProvider(55, this.#stdoutTerminal));
180
+ if (this.#stdoutTerminal.isTty()) {
181
+ this.addServiceProvider(new ImagePrinterServiceProvider(55, this.#stdoutTerminal));
182
+ }
183
+ else {
184
+ logger.debug("Skipping ImagePrinterServiceProvider: imagePrinterServiceEnabled is true but stdout is not a TTY");
185
+ }
186
+ }
187
+ if (this.#options.spawnServiceEnabled) {
188
+ this.addServiceProvider(new SpawnServiceProvider(58));
157
189
  }
158
190
  if (this.#options.completionServiceEnabled) {
159
191
  const completionService = new DefaultCompletionService();
@@ -6,6 +6,7 @@ export default interface BaseCLIFeatureOptions {
6
6
  readonly argumentPrompterServiceEnabled?: boolean;
7
7
  readonly completionServiceEnabled?: boolean;
8
8
  readonly imagePrinterServiceEnabled?: boolean;
9
+ readonly spawnServiceEnabled?: boolean;
9
10
  readonly validateAllCommands?: boolean;
10
11
  readonly promptingEnabled?: boolean;
11
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"BaseCLIFeatureOptions.d.ts","sourceRoot":"","sources":["../../../src/cli/BaseCLIFeatureOptions.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,WAAW,qBAAqB;IAC5C,QAAQ,CAAC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAC5C,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAC1C,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC,QAAQ,CAAC,8BAA8B,CAAC,EAAE,OAAO,CAAC;IAClD,QAAQ,CAAC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAC5C,QAAQ,CAAC,0BAA0B,CAAC,EAAE,OAAO,CAAC;IAC9C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CACrC"}
1
+ {"version":3,"file":"BaseCLIFeatureOptions.d.ts","sourceRoot":"","sources":["../../../src/cli/BaseCLIFeatureOptions.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,WAAW,qBAAqB;IAC5C,QAAQ,CAAC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAC5C,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAC1C,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC,QAAQ,CAAC,8BAA8B,CAAC,EAAE,OAAO,CAAC;IAClD,QAAQ,CAAC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAC5C,QAAQ,CAAC,0BAA0B,CAAC,EAAE,OAAO,CAAC;IAC9C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CACrC"}
@@ -4,6 +4,10 @@ import type { CLIConfig } from "@flowscripter/dynamic-cli-framework-api";
4
4
  import type BaseCLIFeatureOptions from "./BaseCLIFeatureOptions.ts";
5
5
  /**
6
6
  * Default Bun implementation of a {@link CLI} using `process.stdout`, `process.stderr` and `process.argv`.
7
+ *
8
+ * Degrades gracefully when `stdin`, `stdout` or `stderr` are not TTYs (e.g. piped or redirected):
9
+ * color and hyperlinks are disabled, prompting is disabled, and non-TTY streams are wrapped in a
10
+ * {@link NonTtyTerminal} rather than the usual {@link TtyTerminal}.
7
11
  */
8
12
  export default class DefaultRuntimeCLI extends BaseCLI {
9
13
  constructor(cliConfig: CLIConfig, options?: BaseCLIFeatureOptions);
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultRuntimeCLI.d.ts","sourceRoot":"","sources":["../../../src/cli/DefaultRuntimeCLI.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,qBAAqB,MAAM,4BAA4B,CAAC;AAQpE;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,OAAO;gBACxC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,qBAAqB;IAkBlD,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC;CAIzC"}
1
+ {"version":3,"file":"DefaultRuntimeCLI.d.ts","sourceRoot":"","sources":["../../../src/cli/DefaultRuntimeCLI.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,qBAAqB,MAAM,4BAA4B,CAAC;AAYpE;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,OAAO;gBACxC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,qBAAqB;IAsDlD,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC;CAIzC"}
@@ -2,16 +2,44 @@ import process from "node:process";
2
2
  import BaseCLI from "./BaseCLI.js";
3
3
  import { Writable } from "node:stream";
4
4
  import TtyTerminal from "../terminal/TtyTerminal.js";
5
+ import NonTtyTerminal from "../terminal/NonTtyTerminal.js";
5
6
  import TtyKeyReader from "../terminal/TtyKeyReader.js";
6
7
  import TtyStyler from "../terminal/TtyStyler.js";
7
8
  import supportsColor from "supports-color";
8
9
  import supportsHyperlinks from "../terminal/supportsHyperlinks.js";
10
+ import getLogger from "../util/logger.js";
11
+ const logger = getLogger("DefaultRuntimeCLI");
9
12
  /**
10
13
  * Default Bun implementation of a {@link CLI} using `process.stdout`, `process.stderr` and `process.argv`.
14
+ *
15
+ * Degrades gracefully when `stdin`, `stdout` or `stderr` are not TTYs (e.g. piped or redirected):
16
+ * color and hyperlinks are disabled, prompting is disabled, and non-TTY streams are wrapped in a
17
+ * {@link NonTtyTerminal} rather than the usual {@link TtyTerminal}.
11
18
  */
12
19
  export default class DefaultRuntimeCLI extends BaseCLI {
13
20
  constructor(cliConfig, options) {
14
- super(cliConfig, Writable.toWeb(process.stdout), Writable.toWeb(process.stderr), supportsColor.stdout !== false, supportsColor.stderr !== false, new TtyTerminal(process.stdout), new TtyTerminal(process.stderr), new TtyStyler(supportsColor.stderr === false ? 1 : supportsColor.stderr.level, supportsHyperlinks(process.stderr)), new TtyKeyReader(process.stdin), { promptingEnabled: process.stdin.isTTY === true, ...options });
21
+ const stdinIsTty = process.stdin.isTTY === true;
22
+ const stdoutIsTty = process.stdout.isTTY === true;
23
+ const stderrIsTty = process.stderr.isTTY === true;
24
+ logger.debug(() => `stdin isTTY: ${stdinIsTty}, stdout isTTY: ${stdoutIsTty}, stderr isTTY: ${stderrIsTty}`);
25
+ const stdoutTerminal = stdoutIsTty
26
+ ? new TtyTerminal(process.stdout)
27
+ : new NonTtyTerminal(process.stdout);
28
+ const stderrTerminal = stderrIsTty
29
+ ? new TtyTerminal(process.stderr)
30
+ : new NonTtyTerminal(process.stderr);
31
+ logger.debug(() => `stdout terminal: ${stdoutIsTty ? "TtyTerminal" : "NonTtyTerminal"}, stderr terminal: ${stderrIsTty ? "TtyTerminal" : "NonTtyTerminal"}`);
32
+ const colorLevel = stderrIsTty
33
+ ? supportsColor.stderr === false
34
+ ? 1
35
+ : supportsColor.stderr.level
36
+ : 0;
37
+ logger.debug(() => `color level: ${colorLevel}`);
38
+ const keyReader = stdinIsTty ? new TtyKeyReader(process.stdin) : undefined;
39
+ logger.debug(() => `keyReader constructed: ${keyReader !== undefined}`);
40
+ const promptingEnabled = stdinIsTty && stderrIsTty;
41
+ logger.debug(() => `promptingEnabled default: ${promptingEnabled}`);
42
+ super(cliConfig, Writable.toWeb(process.stdout), Writable.toWeb(process.stderr), supportsColor.stdout !== false, supportsColor.stderr !== false, stdoutTerminal, stderrTerminal, new TtyStyler(colorLevel, supportsHyperlinks(process.stderr)), keyReader, { promptingEnabled, ...options });
15
43
  }
16
44
  async run() {
17
45
  const runResult = await super.run(process.argv.slice(2));
@@ -1,5 +1,5 @@
1
1
  import type { PluginService } from "@flowscripter/dynamic-cli-framework-api";
2
- import type { MarketplacePluginManager, VersionedPluginDescriptor, SearchQuery } from "@flowscripter/dynamic-plugin-framework";
2
+ import type { MarketplacePluginManager, SearchQuery, VersionedPluginDescriptor } from "@flowscripter/dynamic-plugin-framework";
3
3
  export default class DefaultPluginService implements PluginService {
4
4
  #private;
5
5
  constructor(pluginManager: MarketplacePluginManager);
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultPluginService.d.ts","sourceRoot":"","sources":["../../../../src/service/plugin/DefaultPluginService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,KAAK,EACV,wBAAwB,EACxB,yBAAyB,EACzB,WAAW,EACZ,MAAM,wCAAwC,CAAC;AAEhD,MAAM,CAAC,OAAO,OAAO,oBAAqB,YAAW,aAAa;;gBAGpD,aAAa,EAAE,wBAAwB;IAInD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,aAAa,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC;IAIlF,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,yBAAyB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvE,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,aAAa,IAAI,aAAa,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC;IAInE,eAAe,IAAI,aAAa,CAAC;QAC/B,UAAU,EAAE,QAAQ,CAAC,yBAAyB,CAAC,CAAC;QAChD,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;CAGH"}
1
+ {"version":3,"file":"DefaultPluginService.d.ts","sourceRoot":"","sources":["../../../../src/service/plugin/DefaultPluginService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,KAAK,EACV,wBAAwB,EACxB,WAAW,EACX,yBAAyB,EAC1B,MAAM,wCAAwC,CAAC;AAEhD,MAAM,CAAC,OAAO,OAAO,oBAAqB,YAAW,aAAa;;gBAGpD,aAAa,EAAE,wBAAwB;IAInD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,aAAa,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC;IAIlF,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,yBAAyB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvE,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,aAAa,IAAI,aAAa,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC;IAInE,eAAe,IAAI,aAAa,CAAC;QAC/B,UAAU,EAAE,QAAQ,CAAC,yBAAyB,CAAC,CAAC;QAChD,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;CAGH"}
@@ -2,12 +2,13 @@ import type { ServiceInfo, ServiceProvider } from "@flowscripter/dynamic-cli-fra
2
2
  import type { Context } from "@flowscripter/dynamic-cli-framework-api";
3
3
  import type { CLIConfig } from "@flowscripter/dynamic-cli-framework-api";
4
4
  import type { MarketplacePluginManager } from "@flowscripter/dynamic-plugin-framework";
5
+ import { type SpawnInterfaceAdapterOptions } from "./SpawnInterfaceAdapter.ts";
5
6
  export default class DefaultPluginServiceProvider implements ServiceProvider {
6
7
  #private;
7
8
  readonly serviceId = "PLUGIN_SERVICE";
8
9
  readonly servicePriority: number;
9
- constructor(pluginManager: MarketplacePluginManager, servicePriority?: number);
10
+ constructor(pluginManager: MarketplacePluginManager, servicePriority?: number, spawnInterfaceAdapterOptions?: SpawnInterfaceAdapterOptions);
10
11
  getServiceInfo(_cliConfig: CLIConfig): Promise<ServiceInfo>;
11
- initService(_context: Context): Promise<void>;
12
+ initService(context: Context): Promise<void>;
12
13
  }
13
14
  //# sourceMappingURL=DefaultPluginServiceProvider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultPluginServiceProvider.d.ts","sourceRoot":"","sources":["../../../../src/service/plugin/DefaultPluginServiceProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC5F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AAKvF,MAAM,CAAC,OAAO,OAAO,4BAA6B,YAAW,eAAe;;IAC1E,QAAQ,CAAC,SAAS,oBAAqB;IACvC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;gBAIrB,aAAa,EAAE,wBAAwB,EAAE,eAAe,SAAK;IAKnE,cAAc,CAAC,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC;IAQ3D,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CACpD"}
1
+ {"version":3,"file":"DefaultPluginServiceProvider.d.ts","sourceRoot":"","sources":["../../../../src/service/plugin/DefaultPluginServiceProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC5F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,KAAK,EACV,wBAAwB,EAEzB,MAAM,wCAAwC,CAAC;AAIhD,OAA8B,EAC5B,KAAK,4BAA4B,EAClC,MAAM,4BAA4B,CAAC;AAKpC,MAAM,CAAC,OAAO,OAAO,4BAA6B,YAAW,eAAe;;IAC1E,QAAQ,CAAC,SAAS,oBAAqB;IACvC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;gBAM/B,aAAa,EAAE,wBAAwB,EACvC,eAAe,SAAK,EACpB,4BAA4B,GAAE,4BAAiC;IAO3D,cAAc,CAAC,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC;IAQjE,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAoB7C"}
@@ -1,14 +1,20 @@
1
+ import { PRINTER_SERVICE_ID, SPAWN_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
1
2
  import { PLUGIN_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
2
3
  import DefaultPluginService from "./DefaultPluginService.js";
3
4
  import { PluginGroupCommand } from "./command/PluginGroupCommand.js";
5
+ import SpawnInterfaceAdapter, {} from "./SpawnInterfaceAdapter.js";
6
+ import getLogger from "../../util/logger.js";
7
+ const logger = getLogger("DefaultPluginServiceProvider");
4
8
  export default class DefaultPluginServiceProvider {
5
9
  serviceId = PLUGIN_SERVICE_ID;
6
10
  servicePriority;
7
11
  #pluginManager;
12
+ #spawnInterfaceAdapterOptions;
8
13
  #pluginService;
9
- constructor(pluginManager, servicePriority = 50) {
14
+ constructor(pluginManager, servicePriority = 50, spawnInterfaceAdapterOptions = {}) {
10
15
  this.#pluginManager = pluginManager;
11
16
  this.servicePriority = servicePriority;
17
+ this.#spawnInterfaceAdapterOptions = spawnInterfaceAdapterOptions;
12
18
  }
13
19
  async getServiceInfo(_cliConfig) {
14
20
  this.#pluginService = new DefaultPluginService(this.#pluginManager);
@@ -17,5 +23,19 @@ export default class DefaultPluginServiceProvider {
17
23
  commands: [new PluginGroupCommand()],
18
24
  };
19
25
  }
20
- async initService(_context) { }
26
+ initService(context) {
27
+ if (!context.doesServiceExist(SPAWN_SERVICE_ID)) {
28
+ logger.debug("SpawnService not available, plugin manager will spawn processes directly");
29
+ return Promise.resolve();
30
+ }
31
+ if (!("setSpawn" in this.#pluginManager)) {
32
+ logger.debug("Plugin manager does not support SpawnCapable, skipping spawn injection");
33
+ return Promise.resolve();
34
+ }
35
+ const spawnService = context.getServiceById(SPAWN_SERVICE_ID);
36
+ const printerService = context.getServiceById(PRINTER_SERVICE_ID);
37
+ const adapter = new SpawnInterfaceAdapter(spawnService, printerService, this.#spawnInterfaceAdapterOptions);
38
+ this.#pluginManager.setSpawn(adapter);
39
+ return Promise.resolve();
40
+ }
21
41
  }
@@ -0,0 +1,19 @@
1
+ import type { PrinterService, SpawnService } from "@flowscripter/dynamic-cli-framework-api";
2
+ import type { SpawnInterface, SpawnResult } from "@flowscripter/dynamic-plugin-framework";
3
+ export interface SpawnInterfaceAdapterOptions {
4
+ quoteColor?: string;
5
+ markMinimumDisplayTimeMs?: number;
6
+ }
7
+ /**
8
+ * Adapts a {@link SpawnService} to dynamic-plugin-framework's {@link SpawnInterface}, wrapping
9
+ * spawned process output in a quoted, marked block via {@link PrinterService} that is cleared
10
+ * again once the process exits (subject to {@link SpawnInterfaceAdapterOptions.markMinimumDisplayTimeMs}).
11
+ */
12
+ export default class SpawnInterfaceAdapter implements SpawnInterface {
13
+ #private;
14
+ constructor(spawnService: SpawnService, printerService: PrinterService, options?: SpawnInterfaceAdapterOptions);
15
+ spawn(command: ReadonlyArray<string>, options: {
16
+ cwd: string;
17
+ }): Promise<SpawnResult>;
18
+ }
19
+ //# sourceMappingURL=SpawnInterfaceAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SpawnInterfaceAdapter.d.ts","sourceRoot":"","sources":["../../../../src/service/plugin/SpawnInterfaceAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAC5F,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAC;AAE1F,MAAM,WAAW,4BAA4B;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wBAAwB,CAAC,EAAE,MAAM,CAAC;CACnC;AAED;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,qBAAsB,YAAW,cAAc;;gBAOhE,YAAY,EAAE,YAAY,EAC1B,cAAc,EAAE,cAAc,EAC9B,OAAO,GAAE,4BAAiC;IAQ/B,KAAK,CAChB,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,EAC9B,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GACvB,OAAO,CAAC,WAAW,CAAC;CA4BxB"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Adapts a {@link SpawnService} to dynamic-plugin-framework's {@link SpawnInterface}, wrapping
3
+ * spawned process output in a quoted, marked block via {@link PrinterService} that is cleared
4
+ * again once the process exits (subject to {@link SpawnInterfaceAdapterOptions.markMinimumDisplayTimeMs}).
5
+ */
6
+ export default class SpawnInterfaceAdapter {
7
+ #spawnService;
8
+ #printerService;
9
+ #quoteColor;
10
+ #markMinimumDisplayTimeMs;
11
+ constructor(spawnService, printerService, options = {}) {
12
+ this.#spawnService = spawnService;
13
+ this.#printerService = printerService;
14
+ this.#quoteColor = options.quoteColor;
15
+ this.#markMinimumDisplayTimeMs = options.markMinimumDisplayTimeMs ?? 1000;
16
+ }
17
+ async spawn(command, options) {
18
+ this.#printerService.startQuote(this.#quoteColor);
19
+ this.#printerService.startMark();
20
+ // onOutput is synchronous and may be called concurrently for stdout/stderr lines, but
21
+ // printerService.info() is async and must not be invoked concurrently with itself - queue
22
+ // writes so they're applied one at a time, in call order.
23
+ let writeQueue = Promise.resolve();
24
+ const onOutput = (line) => {
25
+ writeQueue = writeQueue.then(() => this.#printerService.info(`${line}\n`));
26
+ };
27
+ const result = await this.#spawnService.spawn(command, {
28
+ cwd: options.cwd,
29
+ stdio: "wrapped",
30
+ onOutput,
31
+ });
32
+ await writeQueue;
33
+ this.#printerService.endQuote();
34
+ this.#printerService.endMark();
35
+ await this.#printerService.clearMarked(this.#markMinimumDisplayTimeMs);
36
+ return result.ok
37
+ ? { ok: true, exitCode: result.exitCode }
38
+ : { ok: false, exitCode: result.exitCode, error: result.error };
39
+ }
40
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultPrinterService.d.ts","sourceRoot":"","sources":["../../../../src/service/printer/DefaultPrinterService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DefaultPrinterService.d.ts","sourceRoot":"","sources":["../../../../src/service/printer/DefaultPrinterService.ts"],"names":[],"mappings":"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"}
@@ -22,16 +22,14 @@ export default class DefaultPrinterService {
22
22
  #quote;
23
23
  #markedLineCount;
24
24
  #markEndedAt;
25
- #markedTerminal;
26
25
  #countLines(message) {
27
26
  return message.split("\n").length - (message.endsWith("\n") ? 1 : 0);
28
27
  }
29
- #recordMarkedWrite(terminal, message) {
28
+ #recordMarkedWrite(message) {
30
29
  if (this.#markedLineCount === undefined) {
31
30
  return;
32
31
  }
33
32
  this.#markedLineCount += this.#countLines(message);
34
- this.#markedTerminal = terminal;
35
33
  }
36
34
  async #log(level, message, icon) {
37
35
  if (this.#threshold > level) {
@@ -40,7 +38,7 @@ export default class DefaultPrinterService {
40
38
  await this.#spinner.pause();
41
39
  await this.#progress.pause();
42
40
  const composed = `${icon !== undefined ? `${this.#iconDefinitions[icon]} ` : ""}${message}`;
43
- this.#recordMarkedWrite(this.#stderrTerminal, composed);
41
+ this.#recordMarkedWrite(composed);
44
42
  await this.#stderrTerminal.write(this.#quote.prefixLines(composed));
45
43
  this.#spinner.resume();
46
44
  this.#progress.resume();
@@ -214,8 +212,7 @@ export default class DefaultPrinterService {
214
212
  const writer = this.stdoutWritable.getWriter();
215
213
  const colorMessage = this.#stdoutIsColor ? this.primary(message) : message;
216
214
  const composed = `${icon !== undefined ? `${this.#iconDefinitions[icon]} ` : ""}${colorMessage}`;
217
- this.#recordMarkedWrite(this.#stdoutTerminal, composed);
218
- const encoded = this.#encoder.encode(this.#quote.prefixLines(composed));
215
+ const encoded = this.#encoder.encode(composed);
219
216
  await writer.ready;
220
217
  await writer.write(encoded);
221
218
  writer.releaseLock();
@@ -248,16 +245,18 @@ export default class DefaultPrinterService {
248
245
  if (this.#markedLineCount === undefined || this.#markEndedAt === undefined) {
249
246
  throw new Error("clearMarked() called without a preceding endMark()");
250
247
  }
248
+ if (!this.#stderrTerminal.isTty()) {
249
+ this.#markedLineCount = undefined;
250
+ this.#markEndedAt = undefined;
251
+ return;
252
+ }
251
253
  const remaining = minimumDisplayTimeMs - (Date.now() - this.#markEndedAt);
252
254
  if (remaining > 0) {
253
255
  await new Promise((resolve) => setTimeout(resolve, remaining));
254
256
  }
255
- if (this.#markedTerminal !== undefined) {
256
- await this.#markedTerminal.clearUpLines(this.#markedLineCount);
257
- }
257
+ await this.#stderrTerminal.clearUpLines(this.#markedLineCount);
258
258
  this.#markedLineCount = undefined;
259
259
  this.#markEndedAt = undefined;
260
- this.#markedTerminal = undefined;
261
260
  }
262
261
  async setLevel(level) {
263
262
  if (this.#threshold > Level.INFO) {
@@ -270,6 +269,9 @@ export default class DefaultPrinterService {
270
269
  return this.#threshold;
271
270
  }
272
271
  async showSpinner(message, style) {
272
+ if (!this.#stderrTerminal.isTty()) {
273
+ return;
274
+ }
273
275
  await this.#progress.hideAll();
274
276
  if (this.#threshold > Level.INFO) {
275
277
  return;
@@ -283,6 +285,9 @@ export default class DefaultPrinterService {
283
285
  await this.#spinner.hide();
284
286
  }
285
287
  async showProgressBar(units, message = "", total = 100, current = 0, style) {
288
+ if (!this.#stderrTerminal.isTty()) {
289
+ return -1;
290
+ }
286
291
  await this.#spinner.hide();
287
292
  if (this.#threshold > Level.INFO) {
288
293
  return -1;
@@ -0,0 +1,7 @@
1
+ import type { PrinterService, ShutdownService, SpawnOptions, SpawnResult, SpawnService } from "@flowscripter/dynamic-cli-framework-api";
2
+ export default class DefaultSpawnService implements SpawnService {
3
+ #private;
4
+ setDependencies(printerService: PrinterService, shutdownService: ShutdownService): void;
5
+ spawn(command: ReadonlyArray<string>, options?: SpawnOptions): Promise<SpawnResult>;
6
+ }
7
+ //# sourceMappingURL=DefaultSpawnService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DefaultSpawnService.d.ts","sourceRoot":"","sources":["../../../../src/service/spawn/DefaultSpawnService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,YAAY,EACZ,WAAW,EACX,YAAY,EACb,MAAM,yCAAyC,CAAC;AAOjD,MAAM,CAAC,OAAO,OAAO,mBAAoB,YAAW,YAAY;;IAIvD,eAAe,CAAC,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,GAAG,IAAI;IAkCjF,KAAK,CAChB,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,EAC9B,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,WAAW,CAAC;CAgExB"}
@@ -0,0 +1,94 @@
1
+ import getLogger from "../../util/logger.js";
2
+ const logger = getLogger("DefaultSpawnService");
3
+ const SHUTDOWN_GRACE_PERIOD_MS = 5000;
4
+ export default class DefaultSpawnService {
5
+ #printerService;
6
+ #shutdownService;
7
+ setDependencies(printerService, shutdownService) {
8
+ this.#printerService = printerService;
9
+ this.#shutdownService = shutdownService;
10
+ }
11
+ async #pipeLines(stream, streamName, onOutput) {
12
+ if (typeof stream !== "object" || stream === null) {
13
+ return;
14
+ }
15
+ const decoder = new TextDecoder();
16
+ const reader = stream.getReader();
17
+ let buffer = "";
18
+ for (;;) {
19
+ const { done, value } = await reader.read();
20
+ if (done) {
21
+ break;
22
+ }
23
+ buffer += decoder.decode(value, { stream: true });
24
+ let newlineIndex = buffer.indexOf("\n");
25
+ while (newlineIndex !== -1) {
26
+ onOutput(buffer.slice(0, newlineIndex), streamName);
27
+ buffer = buffer.slice(newlineIndex + 1);
28
+ newlineIndex = buffer.indexOf("\n");
29
+ }
30
+ }
31
+ if (buffer.length > 0) {
32
+ onOutput(buffer, streamName);
33
+ }
34
+ }
35
+ async spawn(command, options = {}) {
36
+ if (this.#printerService === undefined || this.#shutdownService === undefined) {
37
+ throw new Error("DefaultSpawnService.spawn() called before setDependencies()");
38
+ }
39
+ const printerService = this.#printerService;
40
+ const shutdownService = this.#shutdownService;
41
+ const stdio = options.stdio ?? "inherit";
42
+ const longRunning = options.longRunning ?? true;
43
+ if (stdio === "inherit") {
44
+ await printerService.hideSpinner();
45
+ await printerService.hideAllProgressBars();
46
+ }
47
+ let proc;
48
+ try {
49
+ proc = Bun.spawn([...command], {
50
+ cwd: options.cwd,
51
+ stdout: stdio === "wrapped" ? "pipe" : "inherit",
52
+ stderr: stdio === "wrapped" ? "pipe" : "inherit",
53
+ });
54
+ }
55
+ catch (error) {
56
+ logger.debug(() => `Failed to launch command '${command.join(" ")}': ${error}`);
57
+ return { ok: false, error: error };
58
+ }
59
+ let settled = false;
60
+ if (longRunning) {
61
+ shutdownService.enterLongRunningMode();
62
+ }
63
+ shutdownService.addShutdownListener(async () => {
64
+ if (settled) {
65
+ return;
66
+ }
67
+ logger.debug(() => `Sending SIGTERM to spawned command '${command.join(" ")}'`);
68
+ proc.kill("SIGTERM");
69
+ await Promise.race([
70
+ proc.exited.then(() => { }),
71
+ new Promise((resolve) => setTimeout(resolve, SHUTDOWN_GRACE_PERIOD_MS)),
72
+ ]);
73
+ if (!settled) {
74
+ logger.debug(() => `Sending SIGKILL to spawned command '${command.join(" ")}'`);
75
+ proc.kill("SIGKILL");
76
+ }
77
+ });
78
+ if (stdio === "wrapped" && options.onOutput) {
79
+ const onOutput = options.onOutput;
80
+ void this.#pipeLines(proc.stdout, "stdout", onOutput);
81
+ void this.#pipeLines(proc.stderr, "stderr", onOutput);
82
+ }
83
+ try {
84
+ const exitCode = await proc.exited;
85
+ settled = true;
86
+ return exitCode === 0 ? { ok: true, exitCode } : { ok: false, exitCode };
87
+ }
88
+ finally {
89
+ if (longRunning) {
90
+ shutdownService.leaveLongRunningMode();
91
+ }
92
+ }
93
+ }
94
+ }