@flowscripter/dynamic-cli-framework 5.4.8 → 5.4.10

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.
@@ -1 +1 @@
1
- {"version":3,"file":"PluginAddSubCommand.d.ts","sourceRoot":"","sources":["../../../../../src/service/plugin/command/PluginAddSubCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AASxE,qBAAa,mBAAoB,YAAW,UAAU;IACpD,QAAQ,CAAC,IAAI,SAAS;IACtB,QAAQ,CAAC,WAAW,6BAA6B;IACjD,QAAQ,CAAC,mBAAmB,SAAS;IACrC,QAAQ,CAAC,OAAO,UAAM;IACtB,QAAQ,CAAC,WAAW;;;;QAMlB;IAEI,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgFrE;CACF"}
1
+ {"version":3,"file":"PluginAddSubCommand.d.ts","sourceRoot":"","sources":["../../../../../src/service/plugin/command/PluginAddSubCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AASxE,qBAAa,mBAAoB,YAAW,UAAU;IACpD,QAAQ,CAAC,IAAI,SAAS;IACtB,QAAQ,CAAC,WAAW,6BAA6B;IACjD,QAAQ,CAAC,mBAAmB,SAAS;IACrC,QAAQ,CAAC,OAAO,UAAM;IACtB,QAAQ,CAAC,WAAW;;;;QAMlB;IAEI,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsGrE;CACF"}
@@ -22,13 +22,17 @@ export class PluginAddSubCommand {
22
22
  const searchLabel = version ? `${pluginId}@${version}` : pluginId;
23
23
  await printerService.showSpinner(`Searching for plugin: ${searchLabel}`);
24
24
  let descriptor;
25
- for await (const d of pluginService.search({ text: pluginId })) {
26
- if (getPluginId(d) === pluginId || d.pluginId === pluginId) {
27
- descriptor = d;
28
- break;
25
+ try {
26
+ for await (const d of pluginService.search({ text: pluginId })) {
27
+ if (getPluginId(d) === pluginId || d.pluginId === pluginId) {
28
+ descriptor = d;
29
+ break;
30
+ }
29
31
  }
30
32
  }
31
- await printerService.hideSpinner();
33
+ finally {
34
+ await printerService.hideSpinner();
35
+ }
32
36
  if (descriptor && version) {
33
37
  // search only ever returns the latest version - substitute the explicitly requested
34
38
  // version so install() is asked for the correct one.
@@ -53,6 +57,17 @@ export class PluginAddSubCommand {
53
57
  const installLabel = descriptor.version && descriptor.version !== "latest"
54
58
  ? `${descriptor.pluginId}@${descriptor.version}`
55
59
  : descriptor.pluginId;
60
+ // If the exact same plugin+version is already installed, there's nothing to do - avoids a
61
+ // needless reinstall and the registry round-trip below.
62
+ if (descriptor.version && descriptor.version !== "latest") {
63
+ for await (const installed of pluginService.listInstalled()) {
64
+ if (installed.pluginId === descriptor.pluginId &&
65
+ installed.version === descriptor.version) {
66
+ await printerService.print(`Plugin ${descriptor.pluginId}@${installed.version} is already installed.\n`, Icon.INFORMATION);
67
+ return;
68
+ }
69
+ }
70
+ }
56
71
  // Confirm the package (and specific version/tag, if requested) actually exists on the
57
72
  // remote marketplace before invoking the package manager - so a non-existent plugin or
58
73
  // version is reported clearly instead of failing later (and less clearly) inside
@@ -64,7 +79,12 @@ export class PluginAddSubCommand {
64
79
  : `Plugin ${descriptor.pluginId} was not found in the configured plugin registry`);
65
80
  }
66
81
  await printerService.showSpinner(`Installing ${installLabel}...`);
67
- await pluginService.install(descriptor);
82
+ try {
83
+ await pluginService.install(descriptor);
84
+ }
85
+ finally {
86
+ await printerService.hideSpinner();
87
+ }
68
88
  // Look up the actually-installed version rather than trusting `descriptor.version`: when no
69
89
  // version was requested and the plugin wasn't found via search (direct-install fallback),
70
90
  // `descriptor.version` is still the literal placeholder "latest", not a real version number.
@@ -75,7 +95,6 @@ export class PluginAddSubCommand {
75
95
  break;
76
96
  }
77
97
  }
78
- await printerService.hideSpinner();
79
98
  await printerService.print(`Plugin ${descriptor.pluginId}@${installedVersion} installed.\n`, Icon.SUCCESS);
80
99
  }
81
100
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PluginRemoveSubCommand.d.ts","sourceRoot":"","sources":["../../../../../src/service/plugin/command/PluginRemoveSubCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAMxE,qBAAa,sBAAuB,YAAW,UAAU;IACvD,QAAQ,CAAC,IAAI,YAAY;IACzB,QAAQ,CAAC,WAAW,uCAAuC;IAC3D,QAAQ,CAAC,mBAAmB,SAAS;IACrC,QAAQ,CAAC,OAAO,UAAM;IACtB,QAAQ,CAAC,WAAW;;;;QAMlB;IAEI,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASrE;CACF"}
1
+ {"version":3,"file":"PluginRemoveSubCommand.d.ts","sourceRoot":"","sources":["../../../../../src/service/plugin/command/PluginRemoveSubCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAMxE,qBAAa,sBAAuB,YAAW,UAAU;IACvD,QAAQ,CAAC,IAAI,YAAY;IACzB,QAAQ,CAAC,WAAW,uCAAuC;IAC3D,QAAQ,CAAC,mBAAmB,SAAS;IACrC,QAAQ,CAAC,OAAO,UAAM;IACtB,QAAQ,CAAC,WAAW;;;;QAMlB;IAEI,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBrE;CACF"}
@@ -17,9 +17,24 @@ export class PluginRemoveSubCommand {
17
17
  const printerService = context.getServiceById(PRINTER_SERVICE_ID);
18
18
  const pluginService = context.getServiceById(PLUGIN_SERVICE_ID);
19
19
  const pluginId = argumentValues["pluginId"];
20
+ let isInstalled = false;
21
+ for await (const installed of pluginService.listInstalled()) {
22
+ if (installed.pluginId === pluginId) {
23
+ isInstalled = true;
24
+ break;
25
+ }
26
+ }
27
+ if (!isInstalled) {
28
+ await printerService.print(`Plugin ${pluginId} is not installed.\n`, Icon.INFORMATION);
29
+ return;
30
+ }
20
31
  await printerService.showSpinner(`Removing plugin: ${pluginId}...`);
21
- await pluginService.uninstall(pluginId);
22
- await printerService.hideSpinner();
32
+ try {
33
+ await pluginService.uninstall(pluginId);
34
+ }
35
+ finally {
36
+ await printerService.hideSpinner();
37
+ }
23
38
  await printerService.print(`Plugin ${pluginId} removed.\n`, Icon.SUCCESS);
24
39
  }
25
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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"}
@@ -274,6 +274,10 @@ export default class DefaultPrinterService {
274
274
  if (remaining > 0) {
275
275
  await new Promise((resolve) => setTimeout(resolve, remaining));
276
276
  }
277
+ // A spinner left running through the marked region resumes on its own row once the last
278
+ // marked write's pause/resume cycle completes - that row isn't part of #markedLineCount, so
279
+ // it must be cleared separately before erasing the counted rows.
280
+ await this.#spinner.hide();
277
281
  await this.#stderrTerminal.clearUpLines(this.#markedLineCount);
278
282
  this.#markedLineCount = undefined;
279
283
  this.#markEndedAt = undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"Progress.d.ts","sourceRoot":"","sources":["../../../../../src/service/printer/terminal/Progress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,6BAA6B,CAAC;AACtD,OAAO,KAAK,QAAQ,MAAM,+BAA+B,CAAC;AAM1D,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAkBxE,MAAM,CAAC,OAAO,OAAO,QAAQ;;IAc3B,YAAmB,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAGpD;IAEM,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CA8BjF;IAgBM,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAyBrE;IAEY,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAe/C;IAEY,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAKpC;IAEY,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAkBlC;IAEM,MAAM,IAAI,IAAI,CAepB;IA0JD,IAAI,aAAa,CAAC,KAAK,EAAE,MAAM,EAE9B;IAED,IAAI,cAAc,CAAC,KAAK,EAAE,MAAM,EAE/B;IAED,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,EAE3B;IAED,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,EAE3B;IAED,IAAI,aAAa,CAAC,KAAK,EAAE,aAAa,EAErC;CAmDF"}
1
+ {"version":3,"file":"Progress.d.ts","sourceRoot":"","sources":["../../../../../src/service/printer/terminal/Progress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,6BAA6B,CAAC;AACtD,OAAO,KAAK,QAAQ,MAAM,+BAA+B,CAAC;AAM1D,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAkBxE,MAAM,CAAC,OAAO,OAAO,QAAQ;;IAe3B,YAAmB,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAGpD;IAEM,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CA4BjF;IA4BM,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAyBrE;IAEY,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAe/C;IAEY,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAKpC;IAEY,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAqBlC;IAEM,MAAM,IAAI,IAAI,CAapB;IA0JD,IAAI,aAAa,CAAC,KAAK,EAAE,MAAM,EAE9B;IAED,IAAI,cAAc,CAAC,KAAK,EAAE,MAAM,EAE/B;IAED,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,EAE3B;IAED,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,EAE3B;IAED,IAAI,aAAa,CAAC,KAAK,EAAE,aAAa,EAErC;CAmDF"}
@@ -12,6 +12,7 @@ export default class Progress {
12
12
  #styler;
13
13
  #bars = new Map();
14
14
  #timer;
15
+ #renderInFlight;
15
16
  #isDirty = false;
16
17
  #currentRenderedBarCount = 0;
17
18
  #lastRenderTime = 0;
@@ -45,12 +46,21 @@ export default class Progress {
45
46
  this.#isDirty = true;
46
47
  // start rendering timer
47
48
  if (this.#timer === undefined) {
48
- this.#timer = setInterval(async () => {
49
- await this.#renderBars();
50
- }, 100);
49
+ this.#startTimer();
51
50
  }
52
51
  return this.#bars.size;
53
52
  }
53
+ #startTimer() {
54
+ this.#timer = setInterval(() => {
55
+ const renderPromise = this.#renderBars();
56
+ this.#renderInFlight = renderPromise;
57
+ void renderPromise.finally(() => {
58
+ if (this.#renderInFlight === renderPromise) {
59
+ this.#renderInFlight = undefined;
60
+ }
61
+ });
62
+ }, 100);
63
+ }
54
64
  #updateRate(bar, current) {
55
65
  const now = Date.now();
56
66
  if (bar.lastMillis === undefined) {
@@ -113,6 +123,9 @@ export default class Progress {
113
123
  // stop rendering timer
114
124
  clearInterval(this.#timer);
115
125
  this.#timer = undefined;
126
+ if (this.#renderInFlight) {
127
+ await this.#renderInFlight;
128
+ }
116
129
  // clear the previously rendered bars
117
130
  await this.#terminal.clearUpLines(this.#currentRenderedBarCount * 2);
118
131
  this.#currentRenderedBarCount = 0;
@@ -128,9 +141,7 @@ export default class Progress {
128
141
  this.#isDirty = true;
129
142
  // start rendering timer
130
143
  if (this.#timer === undefined) {
131
- this.#timer = setInterval(async () => {
132
- await this.#renderBars();
133
- }, 100);
144
+ this.#startTimer();
134
145
  }
135
146
  }
136
147
  async #renderBars() {
@@ -1 +1 @@
1
- {"version":3,"file":"Spinner.d.ts","sourceRoot":"","sources":["../../../../../src/service/printer/terminal/Spinner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,6BAA6B,CAAC;AACtD,OAAO,KAAK,QAAQ,MAAM,+BAA+B,CAAC;AAM1D,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAEvE,MAAM,CAAC,OAAO,OAAO,OAAO;;IAW1B,YAAmB,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAGpD;IA2BY,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWjD;IAEY,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CASjC;IAEY,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAOlC;IAEM,MAAM,IAAI,IAAI,CAOpB;IAED,IAAI,YAAY,CAAC,KAAK,EAAE,MAAM,EAE7B;IAED,IAAI,YAAY,CAAC,KAAK,EAAE,MAAM,EAE7B;IAED,IAAI,YAAY,CAAC,KAAK,EAAE,YAAY,EAEnC;CACF"}
1
+ {"version":3,"file":"Spinner.d.ts","sourceRoot":"","sources":["../../../../../src/service/printer/terminal/Spinner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,6BAA6B,CAAC;AACtD,OAAO,KAAK,QAAQ,MAAM,+BAA+B,CAAC;AAM1D,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAEvE,MAAM,CAAC,OAAO,OAAO,OAAO;;IAY1B,YAAmB,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAGpD;IAuCY,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASjD;IAEY,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAajC;IAEY,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAUlC;IAEM,MAAM,IAAI,IAAI,CAKpB;IAED,IAAI,YAAY,CAAC,KAAK,EAAE,MAAM,EAE7B;IAED,IAAI,YAAY,CAAC,KAAK,EAAE,MAAM,EAE7B;IAED,IAAI,YAAY,CAAC,KAAK,EAAE,YAAY,EAEnC;CACF"}
@@ -7,6 +7,7 @@ export default class Spinner {
7
7
  #message;
8
8
  #frameIndex = 0;
9
9
  #timer;
10
+ #renderInFlight;
10
11
  #spinColor = 0x8a8a8a;
11
12
  #msgColor = 0x808080;
12
13
  #style = SpinnerStyle.BOX;
@@ -33,6 +34,17 @@ export default class Spinner {
33
34
  }
34
35
  this.#frameIndex = (this.#frameIndex + 1) % frames.length;
35
36
  }
37
+ #startTimer() {
38
+ this.#timer = setInterval(() => {
39
+ const renderPromise = this.#nextFrame();
40
+ this.#renderInFlight = renderPromise;
41
+ void renderPromise.finally(() => {
42
+ if (this.#renderInFlight === renderPromise) {
43
+ this.#renderInFlight = undefined;
44
+ }
45
+ });
46
+ }, 100);
47
+ }
36
48
  async show(message) {
37
49
  this.#message = message;
38
50
  if (this.#isShown) {
@@ -40,9 +52,7 @@ export default class Spinner {
40
52
  }
41
53
  this.#isShown = true;
42
54
  this.#frameIndex = 0;
43
- this.#timer = setInterval(async () => {
44
- await this.#nextFrame();
45
- }, 100);
55
+ this.#startTimer();
46
56
  await this.#terminal.hideCursor();
47
57
  }
48
58
  async hide() {
@@ -51,6 +61,10 @@ export default class Spinner {
51
61
  }
52
62
  this.#isShown = false;
53
63
  clearInterval(this.#timer);
64
+ this.#timer = undefined;
65
+ if (this.#renderInFlight) {
66
+ await this.#renderInFlight;
67
+ }
54
68
  await this.#terminal.clearLine();
55
69
  await this.#terminal.showCursor();
56
70
  this.#message = undefined;
@@ -61,15 +75,16 @@ export default class Spinner {
61
75
  }
62
76
  clearInterval(this.#timer);
63
77
  this.#timer = undefined;
78
+ if (this.#renderInFlight) {
79
+ await this.#renderInFlight;
80
+ }
64
81
  await this.#terminal.clearLine();
65
82
  }
66
83
  resume() {
67
84
  if (!this.#isShown || this.#timer !== undefined) {
68
85
  return;
69
86
  }
70
- this.#timer = setInterval(async () => {
71
- await this.#nextFrame();
72
- }, 100);
87
+ this.#startTimer();
73
88
  }
74
89
  set spinnerColor(color) {
75
90
  this.#spinColor = color;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowscripter/dynamic-cli-framework",
3
- "version": "5.4.8",
3
+ "version": "5.4.10",
4
4
  "description": "A framework for developing CLI applications which supports dynamic discovery and installation of new commands",
5
5
  "keywords": [
6
6
  "bun",
@@ -30,15 +30,17 @@ export class PluginAddSubCommand implements SubCommand {
30
30
  const { pluginId, version } = parsePluginSpecifier(argumentValues["pluginId"] as string);
31
31
  const searchLabel = version ? `${pluginId}@${version}` : pluginId;
32
32
  await printerService.showSpinner(`Searching for plugin: ${searchLabel}`);
33
-
34
33
  let descriptor: VersionedPluginDescriptor | undefined;
35
- for await (const d of pluginService.search({ text: pluginId })) {
36
- if (getPluginId(d) === pluginId || d.pluginId === pluginId) {
37
- descriptor = d;
38
- break;
34
+ try {
35
+ for await (const d of pluginService.search({ text: pluginId })) {
36
+ if (getPluginId(d) === pluginId || d.pluginId === pluginId) {
37
+ descriptor = d;
38
+ break;
39
+ }
39
40
  }
41
+ } finally {
42
+ await printerService.hideSpinner();
40
43
  }
41
- await printerService.hideSpinner();
42
44
 
43
45
  if (descriptor && version) {
44
46
  // search only ever returns the latest version - substitute the explicitly requested
@@ -71,6 +73,23 @@ export class PluginAddSubCommand implements SubCommand {
71
73
  ? `${descriptor.pluginId}@${descriptor.version}`
72
74
  : descriptor.pluginId;
73
75
 
76
+ // If the exact same plugin+version is already installed, there's nothing to do - avoids a
77
+ // needless reinstall and the registry round-trip below.
78
+ if (descriptor.version && descriptor.version !== "latest") {
79
+ for await (const installed of pluginService.listInstalled()) {
80
+ if (
81
+ installed.pluginId === descriptor.pluginId &&
82
+ installed.version === descriptor.version
83
+ ) {
84
+ await printerService.print(
85
+ `Plugin ${descriptor.pluginId}@${installed.version} is already installed.\n`,
86
+ Icon.INFORMATION,
87
+ );
88
+ return;
89
+ }
90
+ }
91
+ }
92
+
74
93
  // Confirm the package (and specific version/tag, if requested) actually exists on the
75
94
  // remote marketplace before invoking the package manager - so a non-existent plugin or
76
95
  // version is reported clearly instead of failing later (and less clearly) inside
@@ -85,7 +104,11 @@ export class PluginAddSubCommand implements SubCommand {
85
104
  }
86
105
 
87
106
  await printerService.showSpinner(`Installing ${installLabel}...`);
88
- await pluginService.install(descriptor);
107
+ try {
108
+ await pluginService.install(descriptor);
109
+ } finally {
110
+ await printerService.hideSpinner();
111
+ }
89
112
 
90
113
  // Look up the actually-installed version rather than trusting `descriptor.version`: when no
91
114
  // version was requested and the plugin wasn't found via search (direct-install fallback),
@@ -97,7 +120,6 @@ export class PluginAddSubCommand implements SubCommand {
97
120
  break;
98
121
  }
99
122
  }
100
- await printerService.hideSpinner();
101
123
 
102
124
  await printerService.print(
103
125
  `Plugin ${descriptor.pluginId}@${installedVersion} installed.\n`,
@@ -25,9 +25,25 @@ export class PluginRemoveSubCommand implements SubCommand {
25
25
  const pluginService = context.getServiceById(PLUGIN_SERVICE_ID) as PluginService;
26
26
 
27
27
  const pluginId = argumentValues["pluginId"] as string;
28
+
29
+ let isInstalled = false;
30
+ for await (const installed of pluginService.listInstalled()) {
31
+ if (installed.pluginId === pluginId) {
32
+ isInstalled = true;
33
+ break;
34
+ }
35
+ }
36
+ if (!isInstalled) {
37
+ await printerService.print(`Plugin ${pluginId} is not installed.\n`, Icon.INFORMATION);
38
+ return;
39
+ }
40
+
28
41
  await printerService.showSpinner(`Removing plugin: ${pluginId}...`);
29
- await pluginService.uninstall(pluginId);
30
- await printerService.hideSpinner();
42
+ try {
43
+ await pluginService.uninstall(pluginId);
44
+ } finally {
45
+ await printerService.hideSpinner();
46
+ }
31
47
  await printerService.print(`Plugin ${pluginId} removed.\n`, Icon.SUCCESS);
32
48
  }
33
49
  }
@@ -346,6 +346,10 @@ export default class DefaultPrinterService implements PrinterService {
346
346
  if (remaining > 0) {
347
347
  await new Promise((resolve) => setTimeout(resolve, remaining));
348
348
  }
349
+ // A spinner left running through the marked region resumes on its own row once the last
350
+ // marked write's pause/resume cycle completes - that row isn't part of #markedLineCount, so
351
+ // it must be cleared separately before erasing the counted rows.
352
+ await this.#spinner.hide();
349
353
  await this.#stderrTerminal.clearUpLines(this.#markedLineCount);
350
354
  this.#markedLineCount = undefined;
351
355
  this.#markEndedAt = undefined;
@@ -29,6 +29,7 @@ export default class Progress {
29
29
  readonly #styler: Styler;
30
30
  readonly #bars: Map<number, Bar> = new Map();
31
31
  #timer: Timer | undefined;
32
+ #renderInFlight: Promise<void> | undefined;
32
33
  #isDirty = false;
33
34
  #currentRenderedBarCount = 0;
34
35
  #lastRenderTime = 0;
@@ -67,14 +68,24 @@ export default class Progress {
67
68
 
68
69
  // start rendering timer
69
70
  if (this.#timer === undefined) {
70
- this.#timer = setInterval(async () => {
71
- await this.#renderBars();
72
- }, 100);
71
+ this.#startTimer();
73
72
  }
74
73
 
75
74
  return this.#bars.size;
76
75
  }
77
76
 
77
+ #startTimer(): void {
78
+ this.#timer = setInterval(() => {
79
+ const renderPromise = this.#renderBars();
80
+ this.#renderInFlight = renderPromise;
81
+ void renderPromise.finally(() => {
82
+ if (this.#renderInFlight === renderPromise) {
83
+ this.#renderInFlight = undefined;
84
+ }
85
+ });
86
+ }, 100);
87
+ }
88
+
78
89
  #updateRate(bar: Bar, current: number): void {
79
90
  const now = Date.now();
80
91
  if (bar.lastMillis === undefined) {
@@ -150,6 +161,9 @@ export default class Progress {
150
161
  // stop rendering timer
151
162
  clearInterval(this.#timer);
152
163
  this.#timer = undefined;
164
+ if (this.#renderInFlight) {
165
+ await this.#renderInFlight;
166
+ }
153
167
 
154
168
  // clear the previously rendered bars
155
169
  await this.#terminal.clearUpLines(this.#currentRenderedBarCount * 2);
@@ -171,9 +185,7 @@ export default class Progress {
171
185
 
172
186
  // start rendering timer
173
187
  if (this.#timer === undefined) {
174
- this.#timer = setInterval(async () => {
175
- await this.#renderBars();
176
- }, 100);
188
+ this.#startTimer();
177
189
  }
178
190
  }
179
191
 
@@ -13,6 +13,7 @@ export default class Spinner {
13
13
  #message: string | undefined;
14
14
  #frameIndex = 0;
15
15
  #timer: Timer | undefined;
16
+ #renderInFlight: Promise<void> | undefined;
16
17
  #spinColor = 0x8a8a8a;
17
18
  #msgColor = 0x808080;
18
19
  #style: SpinnerStyle = SpinnerStyle.BOX;
@@ -49,6 +50,18 @@ export default class Spinner {
49
50
  this.#frameIndex = (this.#frameIndex + 1) % frames.length;
50
51
  }
51
52
 
53
+ #startTimer(): void {
54
+ this.#timer = setInterval(() => {
55
+ const renderPromise = this.#nextFrame();
56
+ this.#renderInFlight = renderPromise;
57
+ void renderPromise.finally(() => {
58
+ if (this.#renderInFlight === renderPromise) {
59
+ this.#renderInFlight = undefined;
60
+ }
61
+ });
62
+ }, 100);
63
+ }
64
+
52
65
  public async show(message?: string): Promise<void> {
53
66
  this.#message = message;
54
67
  if (this.#isShown) {
@@ -56,9 +69,7 @@ export default class Spinner {
56
69
  }
57
70
  this.#isShown = true;
58
71
  this.#frameIndex = 0;
59
- this.#timer = setInterval(async () => {
60
- await this.#nextFrame();
61
- }, 100);
72
+ this.#startTimer();
62
73
  await this.#terminal.hideCursor();
63
74
  }
64
75
 
@@ -68,6 +79,10 @@ export default class Spinner {
68
79
  }
69
80
  this.#isShown = false;
70
81
  clearInterval(this.#timer);
82
+ this.#timer = undefined;
83
+ if (this.#renderInFlight) {
84
+ await this.#renderInFlight;
85
+ }
71
86
  await this.#terminal.clearLine();
72
87
  await this.#terminal.showCursor();
73
88
  this.#message = undefined;
@@ -79,6 +94,9 @@ export default class Spinner {
79
94
  }
80
95
  clearInterval(this.#timer);
81
96
  this.#timer = undefined;
97
+ if (this.#renderInFlight) {
98
+ await this.#renderInFlight;
99
+ }
82
100
  await this.#terminal.clearLine();
83
101
  }
84
102
 
@@ -86,9 +104,7 @@ export default class Spinner {
86
104
  if (!this.#isShown || this.#timer !== undefined) {
87
105
  return;
88
106
  }
89
- this.#timer = setInterval(async () => {
90
- await this.#nextFrame();
91
- }, 100);
107
+ this.#startTimer();
92
108
  }
93
109
 
94
110
  set spinnerColor(color: number) {