feat(cli): Correct CLI plugin imports and add reset command/IPC to stop processes and clear persisted configs

This commit is contained in:
2025-08-29 16:52:00 +00:00
parent 51aa6eddad
commit cbea3f6187
24 changed files with 112 additions and 45 deletions

View File

@@ -1,5 +1,15 @@
# Changelog
## 2025-08-29 - 4.3.0 - feat(cli)
Correct CLI plugin imports and add reset command/IPC to stop processes and clear persisted configs
- Fixed relative plugin imports in many CLI command modules to use the local CLI plugin wrapper (reduces startup surface and fixes import paths).
- Added a lightweight ts/cli/plugins.ts that exposes only the minimal plugin set used by the CLI.
- Implemented ProcessManager.reset(): stops running processes, collects per-id stop errors, clears in-memory maps and removes persisted configurations (with fallback to write an empty list on delete failure).
- Daemon now exposes a 'reset' IPC handler that delegates to ProcessManager.reset() so CLI can perform a single RPC to reset TSPM state.
- Updated shared IPC protocol types to include ResetRequest and ResetResponse.
- Refactored the CLI reset command to call the new 'reset' RPC (replaces previous stopAll + per-config removal logic).
## 2025-08-29 - 4.2.0 - feat(cli)
Add 'reset' CLI command to stop all processes and clear saved configurations; integrate interactive confirmation and client plugin updates

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@git.zone/tspm',
version: '4.2.0',
version: '4.3.0',
description: 'a no fuzz process manager'
}

View File

@@ -1,4 +1,4 @@
import * as plugins from '../../../plugins.js';
import * as plugins from '../../plugins.js';
import { tspmIpcClient } from '../../../client/tspm.ipcclient.js';
import type { CliArguments } from '../../types.js';
import { registerIpcCommand } from '../../registration/index.js';

View File

@@ -1,4 +1,4 @@
import * as plugins from '../../../plugins.js';
import * as plugins from '../../plugins.js';
import { tspmIpcClient } from '../../../client/tspm.ipcclient.js';
import type { CliArguments } from '../../types.js';
import { registerIpcCommand } from '../../registration/index.js';

View File

@@ -1,4 +1,4 @@
import * as plugins from '../../../plugins.js';
import * as plugins from '../../plugins.js';
import { tspmIpcClient } from '../../../client/tspm.ipcclient.js';
import type { CliArguments } from '../../types.js';
import { registerIpcCommand } from '../../registration/index.js';

View File

@@ -1,4 +1,4 @@
import * as plugins from '../../../plugins.js';
import * as plugins from '../../plugins.js';
import * as paths from '../../../paths.js';
import { tspmIpcClient } from '../../../client/tspm.ipcclient.js';
import { Logger } from '../../../shared/common/utils.errorhandler.js';

View File

@@ -1,4 +1,4 @@
import * as plugins from '../../plugins.js';
import * as plugins from '../plugins.js';
import * as paths from '../../paths.js';
import { tspmIpcClient } from '../../client/tspm.ipcclient.js';
import { Logger } from '../../shared/common/utils.errorhandler.js';

View File

@@ -1,4 +1,4 @@
import * as plugins from '../../../plugins.js';
import * as plugins from '../../plugins.js';
import { tspmIpcClient } from '../../../client/tspm.ipcclient.js';
import type { CliArguments } from '../../types.js';
import { parseMemoryString, formatMemory } from '../../helpers/memory.js';
@@ -88,4 +88,3 @@ export function registerAddCommand(smartcli: plugins.smartcli.Smartcli) {
{ actionLabel: 'add process config' },
);
}

View File

@@ -1,4 +1,4 @@
import * as plugins from '../../../plugins.js';
import * as plugins from '../../plugins.js';
import { tspmIpcClient } from '../../../client/tspm.ipcclient.js';
import type { CliArguments } from '../../types.js';
import { registerIpcCommand } from '../../registration/index.js';

View File

@@ -1,4 +1,4 @@
import * as plugins from '../../../plugins.js';
import * as plugins from '../../plugins.js';
import { tspmIpcClient } from '../../../client/tspm.ipcclient.js';
import type { CliArguments } from '../../types.js';
import { registerIpcCommand } from '../../registration/index.js';

View File

@@ -1,4 +1,4 @@
import * as plugins from '../../../plugins.js';
import * as plugins from '../../plugins.js';
import { tspmIpcClient } from '../../../client/tspm.ipcclient.js';
import type { CliArguments } from '../../types.js';
import { registerIpcCommand } from '../../registration/index.js';

View File

@@ -1,4 +1,4 @@
import * as plugins from '../../../plugins.js';
import * as plugins from '../../plugins.js';
import { tspmIpcClient } from '../../../client/tspm.ipcclient.js';
import type { CliArguments } from '../../types.js';
import { registerIpcCommand } from '../../registration/index.js';

View File

@@ -1,4 +1,4 @@
import * as plugins from '../../../plugins.js';
import * as plugins from '../../plugins.js';
import { tspmIpcClient } from '../../../client/tspm.ipcclient.js';
import type { CliArguments } from '../../types.js';
import { registerIpcCommand } from '../../registration/index.js';

View File

@@ -1,4 +1,4 @@
import * as plugins from '../../../plugins.js';
import * as plugins from '../../plugins.js';
import { tspmIpcClient } from '../../../client/tspm.ipcclient.js';
import type { IProcessConfig } from '../../../shared/protocol/ipc.types.js';
import type { CliArguments } from '../../types.js';

View File

@@ -1,4 +1,4 @@
import * as plugins from '../../../plugins.js';
import * as plugins from '../../plugins.js';
import { tspmIpcClient } from '../../../client/tspm.ipcclient.js';
import type { CliArguments } from '../../types.js';
import { registerIpcCommand } from '../../registration/index.js';

View File

@@ -1,4 +1,4 @@
import * as plugins from '../../plugins.js';
import * as plugins from '../plugins.js';
import { registerIpcCommand } from '../registration/index.js';
import { tspmIpcClient } from '../../client/tspm.ipcclient.js';
@@ -18,33 +18,16 @@ export function registerResetCommand(smartcli: plugins.smartcli.Smartcli) {
return;
}
// Stop all processes first
const stopAllRes = await tspmIpcClient.request('stopAll', {});
if (stopAllRes.failed.length) {
console.log(
`Stopped ${stopAllRes.stopped.length}, ${stopAllRes.failed.length} failed to stop. Proceeding with config reset...`,
);
} else {
console.log(`Stopped ${stopAllRes.stopped.length} processes.`);
// Single IPC call to reset
const result = await tspmIpcClient.request('reset', {});
const failedCount = result.failed.length;
console.log(`Stopped ${result.stopped.length} processes.`);
if (failedCount) {
console.log(`${failedCount} processes failed to stop (configs cleared anyway).`);
}
// List all processes/configs currently known
const listRes = await tspmIpcClient.request('list', {});
// Remove each config
for (const proc of listRes.processes) {
try {
// Prefer 'remove' which handles stop-if-running semantics as well
await tspmIpcClient.request('remove', { id: proc.id });
console.log(`Removed config for process ${proc.id}.`);
} catch (err) {
console.error(`Failed to remove config for ${proc.id}:`, (err as Error)?.message || String(err));
}
}
console.log('TSPM has been reset: processes stopped and configs cleared.');
console.log(`Cleared ${result.removed.length} saved configurations.`);
console.log('TSPM has been reset.');
},
{ actionLabel: 'reset TSPM' },
);
}

View File

@@ -1,4 +1,4 @@
import * as plugins from '../../../plugins.js';
import * as plugins from '../../plugins.js';
import { TspmServiceManager } from '../../../client/tspm.servicemanager.js';
import { Logger } from '../../../shared/common/utils.errorhandler.js';
import type { CliArguments } from '../../types.js';

View File

@@ -1,4 +1,4 @@
import * as plugins from '../../../plugins.js';
import * as plugins from '../../plugins.js';
import { TspmServiceManager } from '../../../client/tspm.servicemanager.js';
import { Logger } from '../../../shared/common/utils.errorhandler.js';
import type { CliArguments } from '../../types.js';

View File

@@ -1,4 +1,4 @@
import * as plugins from '../plugins.js';
import * as plugins from './plugins.js';
import * as paths from '../paths.js';
import { Logger, LogLevel } from '../shared/common/utils.errorhandler.js';

8
ts/cli/plugins.ts Normal file
View File

@@ -0,0 +1,8 @@
// Minimal plugin set for the CLI to keep startup light
import * as path from 'node:path';
import * as projectinfo from '@push.rocks/projectinfo';
import * as smartcli from '@push.rocks/smartcli';
import * as smartinteract from '@push.rocks/smartinteract';
export { path, projectinfo, smartcli, smartinteract };

View File

@@ -1,4 +1,4 @@
import * as plugins from '../../plugins.js';
import * as plugins from '../plugins.js';
import type {
CliArguments,
CommandAction,

View File

@@ -470,4 +470,47 @@ export class ProcessManager extends EventEmitter {
);
}
}
/**
* Reset: stop all running processes and clear all saved configurations
*/
public async reset(): Promise<{
stopped: string[];
removed: string[];
failed: Array<{ id: string; error: string }>;
}> {
this.logger.info('Resetting TSPM: stopping all processes and clearing configs');
const removed = Array.from(this.processConfigs.keys());
const stopped: string[] = [];
const failed: Array<{ id: string; error: string }> = [];
// Attempt to stop all currently running processes with per-id error collection
for (const id of Array.from(this.processes.keys())) {
try {
await this.stop(id);
stopped.push(id);
} catch (error: any) {
failed.push({ id, error: error?.message || String(error) });
}
}
// Clear in-memory maps regardless of stop outcomes
this.processes.clear();
this.processInfo.clear();
this.processConfigs.clear();
// Remove persisted configs
try {
await this.config.deleteKey(this.configStorageKey);
this.logger.debug('Cleared persisted process configurations');
} catch (error) {
// Fallback: write empty list if deleteKey fails for any reason
this.logger.warn('deleteKey failed, writing empty process list instead');
await this.saveProcessConfigs().catch(() => {});
}
this.logger.info('TSPM reset complete');
return { stopped, removed, failed };
}
}

View File

@@ -293,6 +293,15 @@ export class TspmDaemon {
},
);
// Reset handler: stops all and clears configs
this.ipcServer.onMessage(
'reset',
async (request: RequestForMethod<'reset'>) => {
const result = await this.tspmInstance.reset();
return result;
},
);
// Daemon management handlers
this.ipcServer.onMessage(
'daemon:status',

View File

@@ -165,6 +165,20 @@ export interface RestartAllResponse {
}>;
}
// Reset command (stop all and clear configs)
export interface ResetRequest {
// No parameters needed
}
export interface ResetResponse {
stopped: string[];
removed: string[];
failed: Array<{
id: string;
error: string;
}>;
}
// Daemon status command
export interface DaemonStatusRequest {
// No parameters needed
@@ -235,6 +249,7 @@ export type IpcMethodMap = {
startAll: { request: StartAllRequest; response: StartAllResponse };
stopAll: { request: StopAllRequest; response: StopAllResponse };
restartAll: { request: RestartAllRequest; response: RestartAllResponse };
reset: { request: ResetRequest; response: ResetResponse };
'daemon:status': {
request: DaemonStatusRequest;
response: DaemonStatusResponse;