@qodalis/cli 2.4.0 → 2.4.2

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.
package/README.md CHANGED
@@ -20,7 +20,7 @@
20
20
 
21
21
  ![Help command](https://raw.githubusercontent.com/qodalis-solutions/web-cli/main/assets/help_command.gif)
22
22
 
23
- Qodalis CLI renders an [xterm.js](https://xtermjs.org/) terminal in your app with a shell-like command line, built-in commands, themes and a runtime package manager. You add commands as **modules** (`ICliModule`): the 40 official plugins, your own commands, or packages installed at runtime with `pkg add`. It can also connect to a Node.js, .NET or Python backend to run server-side commands.
23
+ Qodalis CLI renders an [xterm.js](https://xtermjs.org/) terminal in your app with a shell-like command line, built-in commands, themes and a runtime package manager. You add commands as **modules** (`ICliModule`): the 40 official plugins (34 here, 6 games in [cli-games](https://github.com/qodalis-solutions/cli-games)), your own commands, or packages installed at runtime with `pkg add`. It can also connect to a Node.js, .NET or Python backend to run server-side commands.
24
24
 
25
25
  ## Try it online
26
26
 
@@ -210,7 +210,7 @@ Install from npm and pass the module, or run `pkg add <name>` in the terminal.
210
210
  | [`@qodalis/cli-wget`](https://www.npmjs.com/package/@qodalis/cli-wget) | `wgetModule` | `wget` |
211
211
  | [`@qodalis/cli-yesno`](https://www.npmjs.com/package/@qodalis/cli-yesno) | `yesnoModule` | `yesno` |
212
212
 
213
- **Games**: [`@qodalis/cli-2048`](https://www.npmjs.com/package/@qodalis/cli-2048) (`game2048Module`), [`@qodalis/cli-minesweeper`](https://www.npmjs.com/package/@qodalis/cli-minesweeper), [`@qodalis/cli-snake`](https://www.npmjs.com/package/@qodalis/cli-snake), [`@qodalis/cli-sudoku`](https://www.npmjs.com/package/@qodalis/cli-sudoku), [`@qodalis/cli-tetris`](https://www.npmjs.com/package/@qodalis/cli-tetris), [`@qodalis/cli-wordle`](https://www.npmjs.com/package/@qodalis/cli-wordle).
213
+ **Games** ([cli-games](https://github.com/qodalis-solutions/cli-games), same `@qodalis/cli-<game>` names): [`@qodalis/cli-2048`](https://www.npmjs.com/package/@qodalis/cli-2048) (`game2048Module`), [`@qodalis/cli-minesweeper`](https://www.npmjs.com/package/@qodalis/cli-minesweeper), [`@qodalis/cli-snake`](https://www.npmjs.com/package/@qodalis/cli-snake), [`@qodalis/cli-sudoku`](https://www.npmjs.com/package/@qodalis/cli-sudoku), [`@qodalis/cli-tetris`](https://www.npmjs.com/package/@qodalis/cli-tetris), [`@qodalis/cli-wordle`](https://www.npmjs.com/package/@qodalis/cli-wordle).
214
214
 
215
215
  **Language packs**: `@qodalis/cli-lang-<code>` for `de`, `es`, `fr`, `it`, `ja`, `ko`, `pt`, `ro`, `ru`, `zh` (`langDeModule`, ...).
216
216
 
@@ -220,6 +220,7 @@ Details and examples for each plugin: [Plugins](https://cli.qodalis.com/docs/plu
220
220
 
221
221
  | Repository | What it is |
222
222
  | --- | --- |
223
+ | [cli-games](https://github.com/qodalis-solutions/cli-games) | The six game plugins (`@qodalis/cli-2048`, `-minesweeper`, `-snake`, `-sudoku`, `-tetris`, `-wordle`) |
223
224
  | [cli-server-node](https://github.com/qodalis-solutions/cli-server-node) | Node.js server (`@qodalis/cli-server-node`): server commands, shell, filesystem, data explorer, jobs, MCP |
224
225
  | [cli-server-dotnet](https://github.com/qodalis-solutions/cli-server-dotnet) | The same server for ASP.NET Core (NuGet `Qodalis.Cli`) |
225
226
  | [cli-server-python](https://github.com/qodalis-solutions/cli-server-python) | The same server for FastAPI (PyPI `qodalis-cli-server`) |
@@ -263,7 +264,7 @@ pnpm run create-plugin -- --name <name> --description "<desc>" --processor-name
263
264
  | `packages/cli` | `@qodalis/cli`: the engine and built-in commands |
264
265
  | `packages/angular-cli`, `react-cli`, `vue-cli`, `electron-cli` | Framework wrappers |
265
266
  | `packages/create-cli-plugin` | Plugin scaffolder |
266
- | `packages/plugins/*` | The 40 plugins |
267
+ | `packages/plugins/*` | The 34 plugins (the 6 games live in [cli-games](https://github.com/qodalis-solutions/cli-games)) |
267
268
  | `apps/` | Docs site and demo apps |
268
269
 
269
270
  [CONTRIBUTING.md](https://github.com/qodalis-solutions/web-cli/blob/main/CONTRIBUTING.md) covers branches and pull requests, [DEVELOPER.md](https://github.com/qodalis-solutions/web-cli/blob/main/DEVELOPER.md) the architecture and build details.
@@ -1069,6 +1069,41 @@
1069
1069
  color: var(--cli-status-running, #f0883e);
1070
1070
  }
1071
1071
 
1072
+ /* Stop button of the running command: a finger-sized target on touch screens */
1073
+ .cli-panel-status-stop {
1074
+ appearance: none;
1075
+ flex-shrink: 0;
1076
+ min-width: 44px;
1077
+ min-height: 28px;
1078
+ margin: -4px 0;
1079
+ padding: 0 8px;
1080
+ background: transparent;
1081
+ border: 1px solid var(--cli-status-running, #f0883e);
1082
+ border-radius: calc(var(--cli-panel-radius, 8px) - 2px);
1083
+ color: var(--cli-status-running, #f0883e);
1084
+ font-family: inherit;
1085
+ font-size: 11px;
1086
+ line-height: 1;
1087
+ cursor: pointer;
1088
+ touch-action: manipulation;
1089
+ transition:
1090
+ background-color 0.15s ease,
1091
+ border-color 0.15s ease,
1092
+ color 0.15s ease;
1093
+ }
1094
+
1095
+ .cli-panel-status-stop:hover,
1096
+ .cli-panel-status-stop:focus-visible {
1097
+ color: var(--cli-panel-danger, #f87171);
1098
+ border-color: var(--cli-panel-danger, #f87171);
1099
+ background-color: color-mix(in srgb, var(--cli-panel-danger, #f87171) 14%, transparent);
1100
+ }
1101
+
1102
+ .cli-panel-status-stop:focus-visible {
1103
+ outline: 2px solid var(--cli-panel-accent, #818cf8);
1104
+ outline-offset: 1px;
1105
+ }
1106
+
1072
1107
  .cli-panel-status-item.status-clickable {
1073
1108
  cursor: pointer;
1074
1109
  transition: color 0.15s ease;
@@ -1283,6 +1318,42 @@
1283
1318
  margin-top: 1px;
1284
1319
  }
1285
1320
 
1321
+ /* Stop button of a running service: a finger-sized target on touch screens */
1322
+ .cli-panel-svc-stop {
1323
+ appearance: none;
1324
+ flex-shrink: 0;
1325
+ align-self: center;
1326
+ min-width: 44px;
1327
+ min-height: 32px;
1328
+ margin: -6px 0;
1329
+ padding: 0 10px;
1330
+ background: transparent;
1331
+ border: 1px solid var(--cli-panel-border, rgba(255, 255, 255, 0.12));
1332
+ border-radius: calc(var(--cli-panel-radius, 8px) - 2px);
1333
+ color: var(--cli-panel-text-secondary, #94a3b8);
1334
+ font-family: inherit;
1335
+ font-size: 11px;
1336
+ line-height: 1;
1337
+ cursor: pointer;
1338
+ touch-action: manipulation;
1339
+ transition:
1340
+ background-color 0.15s ease,
1341
+ border-color 0.15s ease,
1342
+ color 0.15s ease;
1343
+ }
1344
+
1345
+ .cli-panel-svc-stop:hover,
1346
+ .cli-panel-svc-stop:focus-visible {
1347
+ color: var(--cli-panel-danger, #f87171);
1348
+ border-color: var(--cli-panel-danger, #f87171);
1349
+ background-color: color-mix(in srgb, var(--cli-panel-danger, #f87171) 14%, transparent);
1350
+ }
1351
+
1352
+ .cli-panel-svc-stop:focus-visible {
1353
+ outline: 2px solid var(--cli-panel-accent, #818cf8);
1354
+ outline-offset: 1px;
1355
+ }
1356
+
1286
1357
  .cli-panel-srv-meta {
1287
1358
  display: flex;
1288
1359
  flex-direction: column;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qodalis/cli",
3
- "version": "2.4.0",
3
+ "version": "2.4.2",
4
4
  "description": "Framework-agnostic CLI engine for @qodalis terminal applications.",
5
5
  "author": "Nicolae Lupei, Qodalis Solutions",
6
6
  "license": "MIT",
@@ -30,7 +30,7 @@
30
30
  "./assets/*": "./assets/*"
31
31
  },
32
32
  "dependencies": {
33
- "@qodalis/cli-core": "2.4.0",
33
+ "@qodalis/cli-core": "2.4.2",
34
34
  "@xterm/xterm": "^6.0.0",
35
35
  "@xterm/addon-fit": "^0.11.0",
36
36
  "@xterm/addon-web-links": "^0.12.0",
package/public-api.d.mts CHANGED
@@ -165,7 +165,7 @@ declare const CliKeyValueStore_TOKEN: any;
165
165
  */
166
166
  declare const SyntaxHighlighterRegistry_TOKEN: any;
167
167
 
168
- declare const LIBRARY_VERSION = "2.4.0";
168
+ declare const LIBRARY_VERSION = "2.4.2";
169
169
  declare const API_VERSION = 2;
170
170
 
171
171
  declare class CliAliasCommandProcessor implements ICliCommandProcessor {
@@ -1431,6 +1431,12 @@ declare class CliExecutionContext implements ICliExecutionContext, InputModeHost
1431
1431
  createInterval(callback: () => void, ms: number): ICliManagedInterval;
1432
1432
  createTimeout(callback: () => void, ms: number): ICliManagedTimer;
1433
1433
  isProgressRunning(): boolean;
1434
+ /**
1435
+ * What pressing Ctrl+C does: the current input mode handles the key, so a
1436
+ * running command is aborted, a prompt cancelled or a context left exactly
1437
+ * as with the keyboard.
1438
+ */
1439
+ interrupt(): void;
1434
1440
  abort(): void;
1435
1441
  setSession(session: ICliUserSession): void;
1436
1442
  getPromptOptions(): PromptOptions;
@@ -3589,6 +3595,8 @@ interface CliPanelContextMenu {
3589
3595
  tabId: number;
3590
3596
  }
3591
3597
  interface CliPanelServiceDetail {
3598
+ /** Process id in the engine's process registry (`ps`), the handle of the stop button. */
3599
+ pid?: number;
3592
3600
  name: string;
3593
3601
  status: string;
3594
3602
  description?: string;
@@ -3782,6 +3790,17 @@ declare const GLOBAL_POLL_MS = 2000;
3782
3790
  declare function computeTabStatus(engines: Iterable<CliEngine>): CliPanelTabStatus;
3783
3791
  /** Services, servers and uptime of one engine. */
3784
3792
  declare function computeGlobalStatus(engine: CliEngine | undefined, now?: number): CliPanelGlobalStatus;
3793
+ /**
3794
+ * Kill process `pid` of the engine, as `kill <pid>` does: a background
3795
+ * service is stopped (and shows as killed in `ps`). False when the engine
3796
+ * has no process registry or no running process with that pid.
3797
+ */
3798
+ declare function killProcess(engine: CliEngine | undefined, pid: number): boolean;
3799
+ /**
3800
+ * Interrupt the command running in any of the engines, as Ctrl+C does (the
3801
+ * prompt comes back once the command has stopped). False when none runs.
3802
+ */
3803
+ declare function interruptCommand(engines: Iterable<CliEngine>): boolean;
3785
3804
  interface CliPanelStatusTrackerListener {
3786
3805
  onTabStatus(tabId: number, status: CliPanelTabStatus): void;
3787
3806
  onGlobalStatus(status: CliPanelGlobalStatus): void;
@@ -3803,6 +3822,10 @@ declare class CliPanelStatusTracker {
3803
3822
  unregisterPane(paneId: number): void;
3804
3823
  unregisterTab(tabId: number): void;
3805
3824
  setActiveTab(tabId: number): void;
3825
+ /** The engine the global status (services, servers) is computed from: the first pane of the active tab. */
3826
+ get globalEngine(): CliEngine | undefined;
3827
+ /** The engines of the active tab, one per pane. */
3828
+ get activeTabEngines(): CliEngine[];
3806
3829
  /** Recompute everything now. */
3807
3830
  refresh(): void;
3808
3831
  destroy(): void;
@@ -3916,6 +3939,17 @@ declare class CliPanelController implements ICliPanelRef<CliEngine> {
3916
3939
  openContextMenu(tabId: number, x: number, y: number): void;
3917
3940
  closeContextMenu(): void;
3918
3941
  togglePositionDropdown(): void;
3942
+ /**
3943
+ * Stop the command running in the active tab, as Ctrl+C does. False when
3944
+ * no command runs there.
3945
+ */
3946
+ stopCommand(): boolean;
3947
+ /**
3948
+ * Stop a running background service listed in the services dropdown, as
3949
+ * `kill <pid>` does; the list refreshes. False when nothing was running
3950
+ * under that pid.
3951
+ */
3952
+ killProcess(pid: number): boolean;
3919
3953
  /** `anchor` is the clicked status item; the dropdown is placed next to it. */
3920
3954
  toggleServicesDropdown(anchor?: Element | null): void;
3921
3955
  toggleServersDropdown(anchor?: Element | null): void;
@@ -4029,6 +4063,9 @@ declare const PANEL_LABELS: {
4029
4063
  readonly closePane: "Close pane";
4030
4064
  readonly servicesHeader: "Background Services";
4031
4065
  readonly servicesEmpty: "No services registered";
4066
+ readonly stopService: "Stop";
4067
+ readonly stopCommand: "Stop";
4068
+ readonly stopCommandTitle: "Stop the running command (Ctrl+C)";
4032
4069
  readonly serversHeader: "Server Connections";
4033
4070
  readonly serversEmpty: "No servers configured";
4034
4071
  };
@@ -4079,6 +4116,11 @@ interface PanelStatusIndicator {
4079
4116
  compactDotClass?: string;
4080
4117
  /** Which dropdown a click opens. */
4081
4118
  dropdown?: 'services' | 'servers';
4119
+ /** Stop button of the running command (`controller.stopCommand()`); the compact item stops it on click. */
4120
+ stop?: {
4121
+ label: string;
4122
+ title: string;
4123
+ };
4082
4124
  }
4083
4125
  /** Items of the header status bar, in display order. */
4084
4126
  declare function statusIndicators(s: CliPanelSnapshot): PanelStatusIndicator[];
@@ -4112,6 +4154,12 @@ interface PanelDropdownRow {
4112
4154
  status: string;
4113
4155
  /** Extra lines under the status (servers: API version, command count). */
4114
4156
  meta: string[];
4157
+ /** Stop button of a running service (`controller.killProcess(pid)`); absent for stopped services and servers. */
4158
+ stop?: {
4159
+ pid: number;
4160
+ label: string;
4161
+ title: string;
4162
+ };
4115
4163
  }
4116
4164
  interface PanelStatusDropdown {
4117
4165
  kind: 'services' | 'servers';
@@ -4123,5 +4171,5 @@ interface PanelStatusDropdown {
4123
4171
  /** The open services or servers dropdown, or null when neither is open. */
4124
4172
  declare function openStatusDropdown(s: CliPanelSnapshot): PanelStatusDropdown | null;
4125
4173
 
4126
- export { API_VERSION, CLI_ENV_GLOBAL_PERMISSION, CLI_FRAMEWORK_SERVICE, CLOSE_GLYPH, CLOSE_ICON, CapturingTerminalWriter, CliAliasCommandProcessor, CliArgsParser, CliBackgroundServiceRegistry_TOKEN, CliBoot, CliBootLog, CliBootLog_TOKEN, CliCalCommandProcessor, CliCaptureCommandProcessor, CliClearCommandProcessor, CliClipboard, CliClipboardCommandProcessor, CliColorCommandProcessor, CliCommandExecutionContext, CliCommandExecutor, CliCommandHistory, CliCommandHistory_TOKEN, CliCommandProcessorRegistry, CliConfigureCommandProcessor, CliConvertCommandProcessor, CliDebugCommandProcessor, CliDefaultPingServerService, CliDiffCommandProcessor, CliDragDropService, CliEchoCommandProcessor, CliEngine, CliEnvCommandProcessor, CliEnvironment, CliEvalCommandProcessor, CliEventsCommandProcessor, CliExecutionContext, CliExecutionProcess, CliExportCommandProcessor, CliFalseCommandProcessor, CliFeedbackCommandProcessor, CliFontSizeCommandProcessor, CliFullScreenManager, CliHelpCommandProcessor, CliHistoryCommandProcessor, CliHotKeysCommandProcessor, CliHtopCommandProcessor, CliHttpClient, CliInputReader, CliJsonCommandProcessor, CliKeyValueStore, CliKeyValueStore_TOKEN, CliKillCommandProcessor, CliLogger, CliLoremCommandProcessor, CliModuleRegistry_TOKEN, CliNanoCommandProcessor, CliNotifier, CliOpenCommandProcessor, CliPackageManagerService, CliPackageManagerService_TOKEN, CliPackagesCommandProcessor, CliPanelController, CliPanelStatusTracker, CliPermissionRegistry, CliPingCommandProcessor, CliProcessRegistry, CliProcessRegistry_TOKEN, CliProcessorsRegistry_TOKEN, CliPsCommandProcessor, CliRandomCommandProcessor, CliScreenCommandProcessor, CliScriptSyntaxError, CliSeqCommandProcessor, CliServerCommandProcessor, CliServerConnection, CliServerManager, CliServerManager_TOKEN, CliServerMultiProxyProcessor, CliServerProxyProcessor, CliServiceContainer, CliServicesCommandProcessor, CliSleepCommandProcessor, CliSnippetCommandProcessor, CliSshCommandProcessor, CliStateStore, CliStateStoreManager, CliStateStoreManager_TOKEN, CliTerminalProgressBar, CliTerminalSpinner, CliTerminalTextAnimator, CliTerminalWriter, CliTestCommandProcessor, CliTestHarness, CliThemeCommandProcessor, CliTimeCommandProcessor, CliTimerManager, CliTimestampCommandProcessor, CliTrueCommandProcessor, CliUnAliasCommandProcessor, CliUnameCommandProcessor, CliUnsetCommandProcessor, CliUptimeCommandProcessor, CliVersionCommandProcessor, CliYesCommandProcessor, CommandParser, DEFAULT_CLI_NAME, DEFAULT_GLOBAL_STATUS, DEFAULT_PANEL_HEIGHT, DEFAULT_PANEL_WIDTH, DEFAULT_TAB_STATUS, ERROR_ICON, EXEC_POLL_MS, GLOBAL_POLL_MS, HIDE_ICON, HIDE_TAB_TERMINAL_ICON, ICliEnvironment_TOKEN, ICliPingServerService_TOKEN, ICliScriptRunner_TOKEN, JsFallbackAccelerator, LIBRARY_VERSION, MAXIMIZE_ICON, MIN_PANEL_SIZE, MIN_PANE_WIDTH_PERCENT, OverlayAddon, PANEL_LABELS, PANEL_POSITIONS, ProcessExitedError, RESTORE_ICON, SERVICES_ICON, SUCCESS_ICON, SVG_COMMON_ATTRS, SVG_VIEW_BOX, ScriptLoaderService, SyntaxHighlighterRegistry_TOKEN, TERMINAL_ICON, UPTIME_ICON, appendOutputToFile, appendStderrToFile, applyEnvironmentChange, builtinProcessors, capitalize, clampPanelSize, cliScriptRunner, collapseChevronIcon, computeDiff, computeGlobalStatus, computeTabStatus, contextGlobalParameter, contextMenuItems, contextMenuStyle, createCliEngine, createServerModule, defaultFontSize, describeShellClose, distributePaneWidths, dropdownAnchorStyle, executeOnServer, expandBraces, expandEnvironmentVars, expandGlobs, formatDiff, formatUptime, getAccelerator, getCliNameArt, getGreetingBasedOnTime, getTerminalOptions, glowLineClass, greetingModule, groupBy, handleRenameKey, helpGlobalParameter, hideTabChevronIcon, hotkeysInfo, initWasmAccelerator, initializeServices, initializeTerminal, isHorizontalPosition, isWasmAccelerated, joinClasses, matchGlob, mergeCliOptions, miscProcessors, nextRowsCommand, normalizePaneWidths, openLink, openStatusDropdown, paneClass, paneStyle, panelBranding, panelTabClass, panelTabDotClass, panelWrapperClass, panelWrapperStyle, panesContainerClass, panesContainerWidth, parseAssignments, parseScript, positionDropdownItemClass, positionIcon, positionOptions, reconcileArgs, renderServerResponse, renderSingleOutput, resizePaneWidths, resizedPanelSize, resolveCliBranding, resolveCliHostConfig, runContextMenuAction, runScript, splitWords, statusIndicators, substituteCommands, substituteVars, svgAttrs, systemProcessors, tabDotClass, themeInfos, themes, tryExecuteScript, versionGlobalParameter, waitForLayout, welcomeModule, writeOutputToFile, writeStderrToFile };
4174
+ export { API_VERSION, CLI_ENV_GLOBAL_PERMISSION, CLI_FRAMEWORK_SERVICE, CLOSE_GLYPH, CLOSE_ICON, CapturingTerminalWriter, CliAliasCommandProcessor, CliArgsParser, CliBackgroundServiceRegistry_TOKEN, CliBoot, CliBootLog, CliBootLog_TOKEN, CliCalCommandProcessor, CliCaptureCommandProcessor, CliClearCommandProcessor, CliClipboard, CliClipboardCommandProcessor, CliColorCommandProcessor, CliCommandExecutionContext, CliCommandExecutor, CliCommandHistory, CliCommandHistory_TOKEN, CliCommandProcessorRegistry, CliConfigureCommandProcessor, CliConvertCommandProcessor, CliDebugCommandProcessor, CliDefaultPingServerService, CliDiffCommandProcessor, CliDragDropService, CliEchoCommandProcessor, CliEngine, CliEnvCommandProcessor, CliEnvironment, CliEvalCommandProcessor, CliEventsCommandProcessor, CliExecutionContext, CliExecutionProcess, CliExportCommandProcessor, CliFalseCommandProcessor, CliFeedbackCommandProcessor, CliFontSizeCommandProcessor, CliFullScreenManager, CliHelpCommandProcessor, CliHistoryCommandProcessor, CliHotKeysCommandProcessor, CliHtopCommandProcessor, CliHttpClient, CliInputReader, CliJsonCommandProcessor, CliKeyValueStore, CliKeyValueStore_TOKEN, CliKillCommandProcessor, CliLogger, CliLoremCommandProcessor, CliModuleRegistry_TOKEN, CliNanoCommandProcessor, CliNotifier, CliOpenCommandProcessor, CliPackageManagerService, CliPackageManagerService_TOKEN, CliPackagesCommandProcessor, CliPanelController, CliPanelStatusTracker, CliPermissionRegistry, CliPingCommandProcessor, CliProcessRegistry, CliProcessRegistry_TOKEN, CliProcessorsRegistry_TOKEN, CliPsCommandProcessor, CliRandomCommandProcessor, CliScreenCommandProcessor, CliScriptSyntaxError, CliSeqCommandProcessor, CliServerCommandProcessor, CliServerConnection, CliServerManager, CliServerManager_TOKEN, CliServerMultiProxyProcessor, CliServerProxyProcessor, CliServiceContainer, CliServicesCommandProcessor, CliSleepCommandProcessor, CliSnippetCommandProcessor, CliSshCommandProcessor, CliStateStore, CliStateStoreManager, CliStateStoreManager_TOKEN, CliTerminalProgressBar, CliTerminalSpinner, CliTerminalTextAnimator, CliTerminalWriter, CliTestCommandProcessor, CliTestHarness, CliThemeCommandProcessor, CliTimeCommandProcessor, CliTimerManager, CliTimestampCommandProcessor, CliTrueCommandProcessor, CliUnAliasCommandProcessor, CliUnameCommandProcessor, CliUnsetCommandProcessor, CliUptimeCommandProcessor, CliVersionCommandProcessor, CliYesCommandProcessor, CommandParser, DEFAULT_CLI_NAME, DEFAULT_GLOBAL_STATUS, DEFAULT_PANEL_HEIGHT, DEFAULT_PANEL_WIDTH, DEFAULT_TAB_STATUS, ERROR_ICON, EXEC_POLL_MS, GLOBAL_POLL_MS, HIDE_ICON, HIDE_TAB_TERMINAL_ICON, ICliEnvironment_TOKEN, ICliPingServerService_TOKEN, ICliScriptRunner_TOKEN, JsFallbackAccelerator, LIBRARY_VERSION, MAXIMIZE_ICON, MIN_PANEL_SIZE, MIN_PANE_WIDTH_PERCENT, OverlayAddon, PANEL_LABELS, PANEL_POSITIONS, ProcessExitedError, RESTORE_ICON, SERVICES_ICON, SUCCESS_ICON, SVG_COMMON_ATTRS, SVG_VIEW_BOX, ScriptLoaderService, SyntaxHighlighterRegistry_TOKEN, TERMINAL_ICON, UPTIME_ICON, appendOutputToFile, appendStderrToFile, applyEnvironmentChange, builtinProcessors, capitalize, clampPanelSize, cliScriptRunner, collapseChevronIcon, computeDiff, computeGlobalStatus, computeTabStatus, contextGlobalParameter, contextMenuItems, contextMenuStyle, createCliEngine, createServerModule, defaultFontSize, describeShellClose, distributePaneWidths, dropdownAnchorStyle, executeOnServer, expandBraces, expandEnvironmentVars, expandGlobs, formatDiff, formatUptime, getAccelerator, getCliNameArt, getGreetingBasedOnTime, getTerminalOptions, glowLineClass, greetingModule, groupBy, handleRenameKey, helpGlobalParameter, hideTabChevronIcon, hotkeysInfo, initWasmAccelerator, initializeServices, initializeTerminal, interruptCommand, isHorizontalPosition, isWasmAccelerated, joinClasses, killProcess, matchGlob, mergeCliOptions, miscProcessors, nextRowsCommand, normalizePaneWidths, openLink, openStatusDropdown, paneClass, paneStyle, panelBranding, panelTabClass, panelTabDotClass, panelWrapperClass, panelWrapperStyle, panesContainerClass, panesContainerWidth, parseAssignments, parseScript, positionDropdownItemClass, positionIcon, positionOptions, reconcileArgs, renderServerResponse, renderSingleOutput, resizePaneWidths, resizedPanelSize, resolveCliBranding, resolveCliHostConfig, runContextMenuAction, runScript, splitWords, statusIndicators, substituteCommands, substituteVars, svgAttrs, systemProcessors, tabDotClass, themeInfos, themes, tryExecuteScript, versionGlobalParameter, waitForLayout, welcomeModule, writeOutputToFile, writeStderrToFile };
4127
4175
  export type { AnchorRect, CdnSourceName, CliBootLogOptions, CliEngineOptions, CliEnvironmentChange, CliEnvironmentProfile, CliEnvironmentScope, CliEnvironmentSnapshot, CliEnvironmentSource, CliExecutionContextDeps, CliHiddenServerCommand, CliHostConfig, CliPanelCallbacks, CliPanelContextMenu, CliPanelControlledState, CliPanelControllerOptions, CliPanelExecutionState, CliPanelGlobalStatus, CliPanelPane, CliPanelServerDetail, CliPanelServerState, CliPanelServiceDetail, CliPanelSnapshot, CliPanelStatusTrackerListener, CliPanelTab, CliPanelTabStatus, CliPanelViewport, CliTestResult, CliWelcomeMessageConfig, CommandParserOutput, CommandPart, ConfigureState, CreateCliEngineConfig, DefaultServerProvider, DiffLine, DiffType, ICliEnvironment, ICliExecutionHost, ICliScriptRunOptions, ICliScriptRunner, ICliStateStoreManager, ICliWasmAccelerator, InitializeServicesOptions, InitializeServicesResult, MultiProxyEntry, PanelContextMenuAction, PanelContextMenuItem, PanelDropdownRow, PanelPositionOption, PanelStatusDropdown, PanelStatusIndicator, ParsedArg, ParsedToken, ResolvedCliBranding, SvgIcon, SvgShape, TerminalSetupResult, ThemeState };
package/public-api.d.ts CHANGED
@@ -165,7 +165,7 @@ declare const CliKeyValueStore_TOKEN: any;
165
165
  */
166
166
  declare const SyntaxHighlighterRegistry_TOKEN: any;
167
167
 
168
- declare const LIBRARY_VERSION = "2.4.0";
168
+ declare const LIBRARY_VERSION = "2.4.2";
169
169
  declare const API_VERSION = 2;
170
170
 
171
171
  declare class CliAliasCommandProcessor implements ICliCommandProcessor {
@@ -1431,6 +1431,12 @@ declare class CliExecutionContext implements ICliExecutionContext, InputModeHost
1431
1431
  createInterval(callback: () => void, ms: number): ICliManagedInterval;
1432
1432
  createTimeout(callback: () => void, ms: number): ICliManagedTimer;
1433
1433
  isProgressRunning(): boolean;
1434
+ /**
1435
+ * What pressing Ctrl+C does: the current input mode handles the key, so a
1436
+ * running command is aborted, a prompt cancelled or a context left exactly
1437
+ * as with the keyboard.
1438
+ */
1439
+ interrupt(): void;
1434
1440
  abort(): void;
1435
1441
  setSession(session: ICliUserSession): void;
1436
1442
  getPromptOptions(): PromptOptions;
@@ -3589,6 +3595,8 @@ interface CliPanelContextMenu {
3589
3595
  tabId: number;
3590
3596
  }
3591
3597
  interface CliPanelServiceDetail {
3598
+ /** Process id in the engine's process registry (`ps`), the handle of the stop button. */
3599
+ pid?: number;
3592
3600
  name: string;
3593
3601
  status: string;
3594
3602
  description?: string;
@@ -3782,6 +3790,17 @@ declare const GLOBAL_POLL_MS = 2000;
3782
3790
  declare function computeTabStatus(engines: Iterable<CliEngine>): CliPanelTabStatus;
3783
3791
  /** Services, servers and uptime of one engine. */
3784
3792
  declare function computeGlobalStatus(engine: CliEngine | undefined, now?: number): CliPanelGlobalStatus;
3793
+ /**
3794
+ * Kill process `pid` of the engine, as `kill <pid>` does: a background
3795
+ * service is stopped (and shows as killed in `ps`). False when the engine
3796
+ * has no process registry or no running process with that pid.
3797
+ */
3798
+ declare function killProcess(engine: CliEngine | undefined, pid: number): boolean;
3799
+ /**
3800
+ * Interrupt the command running in any of the engines, as Ctrl+C does (the
3801
+ * prompt comes back once the command has stopped). False when none runs.
3802
+ */
3803
+ declare function interruptCommand(engines: Iterable<CliEngine>): boolean;
3785
3804
  interface CliPanelStatusTrackerListener {
3786
3805
  onTabStatus(tabId: number, status: CliPanelTabStatus): void;
3787
3806
  onGlobalStatus(status: CliPanelGlobalStatus): void;
@@ -3803,6 +3822,10 @@ declare class CliPanelStatusTracker {
3803
3822
  unregisterPane(paneId: number): void;
3804
3823
  unregisterTab(tabId: number): void;
3805
3824
  setActiveTab(tabId: number): void;
3825
+ /** The engine the global status (services, servers) is computed from: the first pane of the active tab. */
3826
+ get globalEngine(): CliEngine | undefined;
3827
+ /** The engines of the active tab, one per pane. */
3828
+ get activeTabEngines(): CliEngine[];
3806
3829
  /** Recompute everything now. */
3807
3830
  refresh(): void;
3808
3831
  destroy(): void;
@@ -3916,6 +3939,17 @@ declare class CliPanelController implements ICliPanelRef<CliEngine> {
3916
3939
  openContextMenu(tabId: number, x: number, y: number): void;
3917
3940
  closeContextMenu(): void;
3918
3941
  togglePositionDropdown(): void;
3942
+ /**
3943
+ * Stop the command running in the active tab, as Ctrl+C does. False when
3944
+ * no command runs there.
3945
+ */
3946
+ stopCommand(): boolean;
3947
+ /**
3948
+ * Stop a running background service listed in the services dropdown, as
3949
+ * `kill <pid>` does; the list refreshes. False when nothing was running
3950
+ * under that pid.
3951
+ */
3952
+ killProcess(pid: number): boolean;
3919
3953
  /** `anchor` is the clicked status item; the dropdown is placed next to it. */
3920
3954
  toggleServicesDropdown(anchor?: Element | null): void;
3921
3955
  toggleServersDropdown(anchor?: Element | null): void;
@@ -4029,6 +4063,9 @@ declare const PANEL_LABELS: {
4029
4063
  readonly closePane: "Close pane";
4030
4064
  readonly servicesHeader: "Background Services";
4031
4065
  readonly servicesEmpty: "No services registered";
4066
+ readonly stopService: "Stop";
4067
+ readonly stopCommand: "Stop";
4068
+ readonly stopCommandTitle: "Stop the running command (Ctrl+C)";
4032
4069
  readonly serversHeader: "Server Connections";
4033
4070
  readonly serversEmpty: "No servers configured";
4034
4071
  };
@@ -4079,6 +4116,11 @@ interface PanelStatusIndicator {
4079
4116
  compactDotClass?: string;
4080
4117
  /** Which dropdown a click opens. */
4081
4118
  dropdown?: 'services' | 'servers';
4119
+ /** Stop button of the running command (`controller.stopCommand()`); the compact item stops it on click. */
4120
+ stop?: {
4121
+ label: string;
4122
+ title: string;
4123
+ };
4082
4124
  }
4083
4125
  /** Items of the header status bar, in display order. */
4084
4126
  declare function statusIndicators(s: CliPanelSnapshot): PanelStatusIndicator[];
@@ -4112,6 +4154,12 @@ interface PanelDropdownRow {
4112
4154
  status: string;
4113
4155
  /** Extra lines under the status (servers: API version, command count). */
4114
4156
  meta: string[];
4157
+ /** Stop button of a running service (`controller.killProcess(pid)`); absent for stopped services and servers. */
4158
+ stop?: {
4159
+ pid: number;
4160
+ label: string;
4161
+ title: string;
4162
+ };
4115
4163
  }
4116
4164
  interface PanelStatusDropdown {
4117
4165
  kind: 'services' | 'servers';
@@ -4123,5 +4171,5 @@ interface PanelStatusDropdown {
4123
4171
  /** The open services or servers dropdown, or null when neither is open. */
4124
4172
  declare function openStatusDropdown(s: CliPanelSnapshot): PanelStatusDropdown | null;
4125
4173
 
4126
- export { API_VERSION, CLI_ENV_GLOBAL_PERMISSION, CLI_FRAMEWORK_SERVICE, CLOSE_GLYPH, CLOSE_ICON, CapturingTerminalWriter, CliAliasCommandProcessor, CliArgsParser, CliBackgroundServiceRegistry_TOKEN, CliBoot, CliBootLog, CliBootLog_TOKEN, CliCalCommandProcessor, CliCaptureCommandProcessor, CliClearCommandProcessor, CliClipboard, CliClipboardCommandProcessor, CliColorCommandProcessor, CliCommandExecutionContext, CliCommandExecutor, CliCommandHistory, CliCommandHistory_TOKEN, CliCommandProcessorRegistry, CliConfigureCommandProcessor, CliConvertCommandProcessor, CliDebugCommandProcessor, CliDefaultPingServerService, CliDiffCommandProcessor, CliDragDropService, CliEchoCommandProcessor, CliEngine, CliEnvCommandProcessor, CliEnvironment, CliEvalCommandProcessor, CliEventsCommandProcessor, CliExecutionContext, CliExecutionProcess, CliExportCommandProcessor, CliFalseCommandProcessor, CliFeedbackCommandProcessor, CliFontSizeCommandProcessor, CliFullScreenManager, CliHelpCommandProcessor, CliHistoryCommandProcessor, CliHotKeysCommandProcessor, CliHtopCommandProcessor, CliHttpClient, CliInputReader, CliJsonCommandProcessor, CliKeyValueStore, CliKeyValueStore_TOKEN, CliKillCommandProcessor, CliLogger, CliLoremCommandProcessor, CliModuleRegistry_TOKEN, CliNanoCommandProcessor, CliNotifier, CliOpenCommandProcessor, CliPackageManagerService, CliPackageManagerService_TOKEN, CliPackagesCommandProcessor, CliPanelController, CliPanelStatusTracker, CliPermissionRegistry, CliPingCommandProcessor, CliProcessRegistry, CliProcessRegistry_TOKEN, CliProcessorsRegistry_TOKEN, CliPsCommandProcessor, CliRandomCommandProcessor, CliScreenCommandProcessor, CliScriptSyntaxError, CliSeqCommandProcessor, CliServerCommandProcessor, CliServerConnection, CliServerManager, CliServerManager_TOKEN, CliServerMultiProxyProcessor, CliServerProxyProcessor, CliServiceContainer, CliServicesCommandProcessor, CliSleepCommandProcessor, CliSnippetCommandProcessor, CliSshCommandProcessor, CliStateStore, CliStateStoreManager, CliStateStoreManager_TOKEN, CliTerminalProgressBar, CliTerminalSpinner, CliTerminalTextAnimator, CliTerminalWriter, CliTestCommandProcessor, CliTestHarness, CliThemeCommandProcessor, CliTimeCommandProcessor, CliTimerManager, CliTimestampCommandProcessor, CliTrueCommandProcessor, CliUnAliasCommandProcessor, CliUnameCommandProcessor, CliUnsetCommandProcessor, CliUptimeCommandProcessor, CliVersionCommandProcessor, CliYesCommandProcessor, CommandParser, DEFAULT_CLI_NAME, DEFAULT_GLOBAL_STATUS, DEFAULT_PANEL_HEIGHT, DEFAULT_PANEL_WIDTH, DEFAULT_TAB_STATUS, ERROR_ICON, EXEC_POLL_MS, GLOBAL_POLL_MS, HIDE_ICON, HIDE_TAB_TERMINAL_ICON, ICliEnvironment_TOKEN, ICliPingServerService_TOKEN, ICliScriptRunner_TOKEN, JsFallbackAccelerator, LIBRARY_VERSION, MAXIMIZE_ICON, MIN_PANEL_SIZE, MIN_PANE_WIDTH_PERCENT, OverlayAddon, PANEL_LABELS, PANEL_POSITIONS, ProcessExitedError, RESTORE_ICON, SERVICES_ICON, SUCCESS_ICON, SVG_COMMON_ATTRS, SVG_VIEW_BOX, ScriptLoaderService, SyntaxHighlighterRegistry_TOKEN, TERMINAL_ICON, UPTIME_ICON, appendOutputToFile, appendStderrToFile, applyEnvironmentChange, builtinProcessors, capitalize, clampPanelSize, cliScriptRunner, collapseChevronIcon, computeDiff, computeGlobalStatus, computeTabStatus, contextGlobalParameter, contextMenuItems, contextMenuStyle, createCliEngine, createServerModule, defaultFontSize, describeShellClose, distributePaneWidths, dropdownAnchorStyle, executeOnServer, expandBraces, expandEnvironmentVars, expandGlobs, formatDiff, formatUptime, getAccelerator, getCliNameArt, getGreetingBasedOnTime, getTerminalOptions, glowLineClass, greetingModule, groupBy, handleRenameKey, helpGlobalParameter, hideTabChevronIcon, hotkeysInfo, initWasmAccelerator, initializeServices, initializeTerminal, isHorizontalPosition, isWasmAccelerated, joinClasses, matchGlob, mergeCliOptions, miscProcessors, nextRowsCommand, normalizePaneWidths, openLink, openStatusDropdown, paneClass, paneStyle, panelBranding, panelTabClass, panelTabDotClass, panelWrapperClass, panelWrapperStyle, panesContainerClass, panesContainerWidth, parseAssignments, parseScript, positionDropdownItemClass, positionIcon, positionOptions, reconcileArgs, renderServerResponse, renderSingleOutput, resizePaneWidths, resizedPanelSize, resolveCliBranding, resolveCliHostConfig, runContextMenuAction, runScript, splitWords, statusIndicators, substituteCommands, substituteVars, svgAttrs, systemProcessors, tabDotClass, themeInfos, themes, tryExecuteScript, versionGlobalParameter, waitForLayout, welcomeModule, writeOutputToFile, writeStderrToFile };
4174
+ export { API_VERSION, CLI_ENV_GLOBAL_PERMISSION, CLI_FRAMEWORK_SERVICE, CLOSE_GLYPH, CLOSE_ICON, CapturingTerminalWriter, CliAliasCommandProcessor, CliArgsParser, CliBackgroundServiceRegistry_TOKEN, CliBoot, CliBootLog, CliBootLog_TOKEN, CliCalCommandProcessor, CliCaptureCommandProcessor, CliClearCommandProcessor, CliClipboard, CliClipboardCommandProcessor, CliColorCommandProcessor, CliCommandExecutionContext, CliCommandExecutor, CliCommandHistory, CliCommandHistory_TOKEN, CliCommandProcessorRegistry, CliConfigureCommandProcessor, CliConvertCommandProcessor, CliDebugCommandProcessor, CliDefaultPingServerService, CliDiffCommandProcessor, CliDragDropService, CliEchoCommandProcessor, CliEngine, CliEnvCommandProcessor, CliEnvironment, CliEvalCommandProcessor, CliEventsCommandProcessor, CliExecutionContext, CliExecutionProcess, CliExportCommandProcessor, CliFalseCommandProcessor, CliFeedbackCommandProcessor, CliFontSizeCommandProcessor, CliFullScreenManager, CliHelpCommandProcessor, CliHistoryCommandProcessor, CliHotKeysCommandProcessor, CliHtopCommandProcessor, CliHttpClient, CliInputReader, CliJsonCommandProcessor, CliKeyValueStore, CliKeyValueStore_TOKEN, CliKillCommandProcessor, CliLogger, CliLoremCommandProcessor, CliModuleRegistry_TOKEN, CliNanoCommandProcessor, CliNotifier, CliOpenCommandProcessor, CliPackageManagerService, CliPackageManagerService_TOKEN, CliPackagesCommandProcessor, CliPanelController, CliPanelStatusTracker, CliPermissionRegistry, CliPingCommandProcessor, CliProcessRegistry, CliProcessRegistry_TOKEN, CliProcessorsRegistry_TOKEN, CliPsCommandProcessor, CliRandomCommandProcessor, CliScreenCommandProcessor, CliScriptSyntaxError, CliSeqCommandProcessor, CliServerCommandProcessor, CliServerConnection, CliServerManager, CliServerManager_TOKEN, CliServerMultiProxyProcessor, CliServerProxyProcessor, CliServiceContainer, CliServicesCommandProcessor, CliSleepCommandProcessor, CliSnippetCommandProcessor, CliSshCommandProcessor, CliStateStore, CliStateStoreManager, CliStateStoreManager_TOKEN, CliTerminalProgressBar, CliTerminalSpinner, CliTerminalTextAnimator, CliTerminalWriter, CliTestCommandProcessor, CliTestHarness, CliThemeCommandProcessor, CliTimeCommandProcessor, CliTimerManager, CliTimestampCommandProcessor, CliTrueCommandProcessor, CliUnAliasCommandProcessor, CliUnameCommandProcessor, CliUnsetCommandProcessor, CliUptimeCommandProcessor, CliVersionCommandProcessor, CliYesCommandProcessor, CommandParser, DEFAULT_CLI_NAME, DEFAULT_GLOBAL_STATUS, DEFAULT_PANEL_HEIGHT, DEFAULT_PANEL_WIDTH, DEFAULT_TAB_STATUS, ERROR_ICON, EXEC_POLL_MS, GLOBAL_POLL_MS, HIDE_ICON, HIDE_TAB_TERMINAL_ICON, ICliEnvironment_TOKEN, ICliPingServerService_TOKEN, ICliScriptRunner_TOKEN, JsFallbackAccelerator, LIBRARY_VERSION, MAXIMIZE_ICON, MIN_PANEL_SIZE, MIN_PANE_WIDTH_PERCENT, OverlayAddon, PANEL_LABELS, PANEL_POSITIONS, ProcessExitedError, RESTORE_ICON, SERVICES_ICON, SUCCESS_ICON, SVG_COMMON_ATTRS, SVG_VIEW_BOX, ScriptLoaderService, SyntaxHighlighterRegistry_TOKEN, TERMINAL_ICON, UPTIME_ICON, appendOutputToFile, appendStderrToFile, applyEnvironmentChange, builtinProcessors, capitalize, clampPanelSize, cliScriptRunner, collapseChevronIcon, computeDiff, computeGlobalStatus, computeTabStatus, contextGlobalParameter, contextMenuItems, contextMenuStyle, createCliEngine, createServerModule, defaultFontSize, describeShellClose, distributePaneWidths, dropdownAnchorStyle, executeOnServer, expandBraces, expandEnvironmentVars, expandGlobs, formatDiff, formatUptime, getAccelerator, getCliNameArt, getGreetingBasedOnTime, getTerminalOptions, glowLineClass, greetingModule, groupBy, handleRenameKey, helpGlobalParameter, hideTabChevronIcon, hotkeysInfo, initWasmAccelerator, initializeServices, initializeTerminal, interruptCommand, isHorizontalPosition, isWasmAccelerated, joinClasses, killProcess, matchGlob, mergeCliOptions, miscProcessors, nextRowsCommand, normalizePaneWidths, openLink, openStatusDropdown, paneClass, paneStyle, panelBranding, panelTabClass, panelTabDotClass, panelWrapperClass, panelWrapperStyle, panesContainerClass, panesContainerWidth, parseAssignments, parseScript, positionDropdownItemClass, positionIcon, positionOptions, reconcileArgs, renderServerResponse, renderSingleOutput, resizePaneWidths, resizedPanelSize, resolveCliBranding, resolveCliHostConfig, runContextMenuAction, runScript, splitWords, statusIndicators, substituteCommands, substituteVars, svgAttrs, systemProcessors, tabDotClass, themeInfos, themes, tryExecuteScript, versionGlobalParameter, waitForLayout, welcomeModule, writeOutputToFile, writeStderrToFile };
4127
4175
  export type { AnchorRect, CdnSourceName, CliBootLogOptions, CliEngineOptions, CliEnvironmentChange, CliEnvironmentProfile, CliEnvironmentScope, CliEnvironmentSnapshot, CliEnvironmentSource, CliExecutionContextDeps, CliHiddenServerCommand, CliHostConfig, CliPanelCallbacks, CliPanelContextMenu, CliPanelControlledState, CliPanelControllerOptions, CliPanelExecutionState, CliPanelGlobalStatus, CliPanelPane, CliPanelServerDetail, CliPanelServerState, CliPanelServiceDetail, CliPanelSnapshot, CliPanelStatusTrackerListener, CliPanelTab, CliPanelTabStatus, CliPanelViewport, CliTestResult, CliWelcomeMessageConfig, CommandParserOutput, CommandPart, ConfigureState, CreateCliEngineConfig, DefaultServerProvider, DiffLine, DiffType, ICliEnvironment, ICliExecutionHost, ICliScriptRunOptions, ICliScriptRunner, ICliStateStoreManager, ICliWasmAccelerator, InitializeServicesOptions, InitializeServicesResult, MultiProxyEntry, PanelContextMenuAction, PanelContextMenuItem, PanelDropdownRow, PanelPositionOption, PanelStatusDropdown, PanelStatusIndicator, ParsedArg, ParsedToken, ResolvedCliBranding, SvgIcon, SvgShape, TerminalSetupResult, ThemeState };
package/public-api.js CHANGED
@@ -519,7 +519,7 @@ var CliKeyValueStore_TOKEN = cliCore.createCliToken("cli-key-value-store");
519
519
  var SyntaxHighlighterRegistry_TOKEN = cliCore.createCliToken("syntax-highlighter-registry");
520
520
 
521
521
  // src/lib/version.ts
522
- var LIBRARY_VERSION = "2.4.0";
522
+ var LIBRARY_VERSION = "2.4.2";
523
523
  var API_VERSION = 2;
524
524
  var ANONYMOUS = "\0anonymous";
525
525
  function aliasOwner(context2) {
@@ -14843,6 +14843,7 @@ var CliTerminalSpinner = class {
14843
14843
  }, 80);
14844
14844
  }
14845
14845
  hide() {
14846
+ if (!this.isRunning) return;
14846
14847
  this.isRunning = false;
14847
14848
  if (this.spinnerInterval) {
14848
14849
  clearInterval(this.spinnerInterval);
@@ -17999,6 +18000,19 @@ var CliExecutionContext = class {
17999
18000
  isProgressRunning() {
18000
18001
  return this.progressBar.isRunning || this.spinner.isRunning || this.textAnimator.isRunning;
18001
18002
  }
18003
+ /**
18004
+ * What pressing Ctrl+C does: the current input mode handles the key, so a
18005
+ * running command is aborted, a prompt cancelled or a context left exactly
18006
+ * as with the keyboard.
18007
+ */
18008
+ interrupt() {
18009
+ const event = new KeyboardEvent("keydown", {
18010
+ key: "c",
18011
+ code: "KeyC",
18012
+ ctrlKey: true
18013
+ });
18014
+ this.currentMode?.handleKeyEvent(event);
18015
+ }
18002
18016
  abort() {
18003
18017
  if (this.progressBar.isRunning) {
18004
18018
  this.progressBar.complete();
@@ -20205,8 +20219,8 @@ var CliBootLog = class {
20205
20219
  if (this.problems.length > 0) {
20206
20220
  this.terminal.write("\r\n");
20207
20221
  }
20208
- if (this.captured.length > 0) {
20209
- const output2 = this.captured.join("").replace(/(?:\s|\x1b\[[0-9;?]*[A-Za-z])+$/, "");
20222
+ const output2 = this.captured.join("").replace(/(?:\s|\x1b\[[0-9;?]*[A-Za-z])+$/, "");
20223
+ if (output2) {
20210
20224
  this.terminal.write(output2 + RESET4 + "\r\n\r\n");
20211
20225
  }
20212
20226
  }
@@ -23942,6 +23956,7 @@ function computeGlobalStatus(engine, now = Date.now()) {
23942
23956
  total: services.length
23943
23957
  };
23944
23958
  serviceDetails = services.map((s) => ({
23959
+ pid: s.pid,
23945
23960
  name: s.name,
23946
23961
  status: s.status,
23947
23962
  description: s.description
@@ -23988,6 +24003,27 @@ function computeGlobalStatus(engine, now = Date.now()) {
23988
24003
  const uptime = engine.startedAt ? now - engine.startedAt : 0;
23989
24004
  return { serviceCount, serviceDetails, serverState, serverDetails, uptime };
23990
24005
  }
24006
+ function killProcess(engine, pid) {
24007
+ const context2 = engine?.getContext();
24008
+ let registry;
24009
+ try {
24010
+ registry = context2?.services?.get?.(CliProcessRegistry_TOKEN);
24011
+ } catch {
24012
+ }
24013
+ return registry?.kill(pid) ?? false;
24014
+ }
24015
+ function interruptCommand(engines) {
24016
+ let interrupted = false;
24017
+ for (const engine of engines) {
24018
+ const context2 = engine.getContext();
24019
+ if (!context2?.interrupt) continue;
24020
+ if (context2.isExecuting || context2.contextProcessor) {
24021
+ context2.interrupt();
24022
+ interrupted = true;
24023
+ }
24024
+ }
24025
+ return interrupted;
24026
+ }
23991
24027
  var CliPanelStatusTracker = class {
23992
24028
  constructor(listener) {
23993
24029
  this.listener = listener;
@@ -24052,6 +24088,16 @@ var CliPanelStatusTracker = class {
24052
24088
  this.activeTabId = tabId;
24053
24089
  this.refreshGlobal();
24054
24090
  }
24091
+ /** The engine the global status (services, servers) is computed from: the first pane of the active tab. */
24092
+ get globalEngine() {
24093
+ const entry = this.activeTabId != null ? this.tabs.get(this.activeTabId) : void 0;
24094
+ return entry?.engines.values().next().value;
24095
+ }
24096
+ /** The engines of the active tab, one per pane. */
24097
+ get activeTabEngines() {
24098
+ const entry = this.activeTabId != null ? this.tabs.get(this.activeTabId) : void 0;
24099
+ return entry ? [...entry.engines.values()] : [];
24100
+ }
24055
24101
  /** Recompute everything now. */
24056
24102
  refresh() {
24057
24103
  for (const tabId of this.tabs.keys()) this.refreshTab(tabId);
@@ -24088,9 +24134,7 @@ var CliPanelStatusTracker = class {
24088
24134
  this.listener.onTabStatus(tabId, next);
24089
24135
  }
24090
24136
  refreshGlobal() {
24091
- const entry = this.activeTabId != null ? this.tabs.get(this.activeTabId) : void 0;
24092
- const engine = entry?.engines.values().next().value;
24093
- const next = computeGlobalStatus(engine);
24137
+ const next = computeGlobalStatus(this.globalEngine);
24094
24138
  if (sameJson(next, this.globalStatus)) return;
24095
24139
  this.globalStatus = next;
24096
24140
  this.listener.onGlobalStatus(next);
@@ -24572,6 +24616,25 @@ var CliPanelController = class {
24572
24616
  serversDropdownOpen: false
24573
24617
  });
24574
24618
  }
24619
+ /**
24620
+ * Stop the command running in the active tab, as Ctrl+C does. False when
24621
+ * no command runs there.
24622
+ */
24623
+ stopCommand() {
24624
+ const stopped = interruptCommand(this.tracker.activeTabEngines);
24625
+ if (stopped) this.tracker.refresh();
24626
+ return stopped;
24627
+ }
24628
+ /**
24629
+ * Stop a running background service listed in the services dropdown, as
24630
+ * `kill <pid>` does; the list refreshes. False when nothing was running
24631
+ * under that pid.
24632
+ */
24633
+ killProcess(pid) {
24634
+ const killed = killProcess(this.tracker.globalEngine, pid);
24635
+ if (killed) this.tracker.refresh();
24636
+ return killed;
24637
+ }
24575
24638
  /** `anchor` is the clicked status item; the dropdown is placed next to it. */
24576
24639
  toggleServicesDropdown(anchor) {
24577
24640
  const open = !this.snapshot.servicesDropdownOpen;
@@ -25000,6 +25063,9 @@ var PANEL_LABELS = {
25000
25063
  closePane: "Close pane",
25001
25064
  servicesHeader: "Background Services",
25002
25065
  servicesEmpty: "No services registered",
25066
+ stopService: "Stop",
25067
+ stopCommand: "Stop",
25068
+ stopCommandTitle: "Stop the running command (Ctrl+C)",
25003
25069
  serversHeader: "Server Connections",
25004
25070
  serversEmpty: "No servers configured"
25005
25071
  };
@@ -25064,10 +25130,11 @@ function statusIndicators(s) {
25064
25130
  items.push({
25065
25131
  key: "execution",
25066
25132
  itemClass: running ? "status-running" : "",
25067
- compactClass: "",
25133
+ compactClass: running ? "status-clickable" : "",
25068
25134
  dotClass: running ? "dot-running" : "dot-idle",
25069
25135
  label: s.status.executionState,
25070
- title: s.status.executionState
25136
+ title: running ? PANEL_LABELS.stopCommandTitle : s.status.executionState,
25137
+ stop: running ? { label: PANEL_LABELS.stopCommand, title: PANEL_LABELS.stopCommandTitle } : void 0
25071
25138
  });
25072
25139
  if (s.global.serviceCount.total > 0) {
25073
25140
  const label = `${s.global.serviceCount.running}/${s.global.serviceCount.total} services`;
@@ -25180,7 +25247,8 @@ function openStatusDropdown(s) {
25180
25247
  name: svc.name,
25181
25248
  description: svc.description,
25182
25249
  status: svc.status,
25183
- meta: []
25250
+ meta: [],
25251
+ stop: svc.status === "running" && svc.pid !== void 0 ? { pid: svc.pid, label: PANEL_LABELS.stopService, title: `${PANEL_LABELS.stopService} ${svc.name} (kill ${svc.pid})` } : void 0
25184
25252
  }))
25185
25253
  };
25186
25254
  }
@@ -25387,9 +25455,11 @@ exports.hotkeysInfo = hotkeysInfo;
25387
25455
  exports.initWasmAccelerator = initWasmAccelerator;
25388
25456
  exports.initializeServices = initializeServices;
25389
25457
  exports.initializeTerminal = initializeTerminal;
25458
+ exports.interruptCommand = interruptCommand;
25390
25459
  exports.isHorizontalPosition = isHorizontalPosition;
25391
25460
  exports.isWasmAccelerated = isWasmAccelerated;
25392
25461
  exports.joinClasses = joinClasses;
25462
+ exports.killProcess = killProcess;
25393
25463
  exports.matchGlob = matchGlob;
25394
25464
  exports.mergeCliOptions = mergeCliOptions;
25395
25465
  exports.miscProcessors = miscProcessors;