fix(daemon): Fix daemon IPC id handling, reload configs on demand and correct CLI daemon start path

This commit is contained in:
2025-08-29 21:22:03 +00:00
parent 3676bff04c
commit 97a8377a75
6 changed files with 43 additions and 20 deletions

View File

@@ -1,5 +1,14 @@
# Changelog
## 2025-08-29 - 4.4.2 - fix(daemon)
Fix daemon IPC id handling, reload configs on demand and correct CLI daemon start path
- Normalize process IDs in daemon IPC handlers (trim strings) to avoid lookup mismatches
- Attempt to reload saved process configurations when a startById request cannot find a config (handles races/stale state)
- Use normalized IDs in responses and messages for stop/restart/delete/remove/describe handlers
- Fix CLI daemon start path to point at dist_ts/daemon/tspm.daemon.js when launching the background daemon
- Ensure the IPC client disconnects after showing CLI version/status to avoid leaked connections
## 2025-08-29 - 4.4.1 - fix(cli)
Use server-side start-by-id flow for starting processes

View File

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

View File

@@ -33,7 +33,8 @@ export function registerDaemonCommand(smartcli: plugins.smartcli.Smartcli) {
const daemonScript = plugins.path.join(
paths.packageDir,
'dist_ts',
'daemon.js',
'daemon',
'tspm.daemon.js',
);
// Start daemon as a detached background process

View File

@@ -52,6 +52,8 @@ export const run = async (): Promise<void> => {
} else {
console.log('Daemon: not running');
}
// Ensure we disconnect any IPC client connection used for status
try { await tspmIpcClient.disconnect(); } catch {}
return; // do not start parser
}
// Keep Smartcli version info for help output but not used for -v now

View File

@@ -141,15 +141,21 @@ export class TspmDaemon {
'startById',
async (request: RequestForMethod<'startById'>) => {
try {
const config = this.tspmInstance.processConfigs.get(request.id);
const id = String(request.id).trim();
let config = this.tspmInstance.processConfigs.get(id);
if (!config) {
throw new Error(`Process ${request.id} not found`);
// Try to reload configs if not found (handles races or stale state)
await this.tspmInstance.loadProcessConfigs();
config = this.tspmInstance.processConfigs.get(id) || null as any;
}
await this.tspmInstance.setDesiredState(request.id, 'online');
if (!config) {
throw new Error(`Process ${id} not found`);
}
await this.tspmInstance.setDesiredState(id, 'online');
await this.tspmInstance.start(config);
const processInfo = this.tspmInstance.processInfo.get(request.id);
const processInfo = this.tspmInstance.processInfo.get(id);
return {
processId: request.id,
processId: id,
pid: processInfo?.pid,
status: processInfo?.status || 'stopped',
};
@@ -163,11 +169,12 @@ export class TspmDaemon {
'stop',
async (request: RequestForMethod<'stop'>) => {
try {
await this.tspmInstance.setDesiredState(request.id, 'stopped');
await this.tspmInstance.stop(request.id);
const id = String(request.id).trim();
await this.tspmInstance.setDesiredState(id, 'stopped');
await this.tspmInstance.stop(id);
return {
success: true,
message: `Process ${request.id} stopped successfully`,
message: `Process ${id} stopped successfully`,
};
} catch (error) {
throw new Error(`Failed to stop process: ${error.message}`);
@@ -179,11 +186,12 @@ export class TspmDaemon {
'restart',
async (request: RequestForMethod<'restart'>) => {
try {
await this.tspmInstance.setDesiredState(request.id, 'online');
await this.tspmInstance.restart(request.id);
const processInfo = this.tspmInstance.processInfo.get(request.id);
const id = String(request.id).trim();
await this.tspmInstance.setDesiredState(id, 'online');
await this.tspmInstance.restart(id);
const processInfo = this.tspmInstance.processInfo.get(id);
return {
processId: request.id,
processId: id,
pid: processInfo?.pid,
status: processInfo?.status || 'stopped',
};
@@ -197,10 +205,11 @@ export class TspmDaemon {
'delete',
async (request: RequestForMethod<'delete'>) => {
try {
await this.tspmInstance.delete(request.id);
const id = String(request.id).trim();
await this.tspmInstance.delete(id);
return {
success: true,
message: `Process ${request.id} deleted successfully`,
message: `Process ${id} deleted successfully`,
};
} catch (error) {
throw new Error(`Failed to delete process: ${error.message}`);
@@ -226,8 +235,9 @@ export class TspmDaemon {
'remove',
async (request: RequestForMethod<'remove'>) => {
try {
await this.tspmInstance.delete(request.id);
return { success: true, message: `Process ${request.id} deleted successfully` };
const id = String(request.id).trim();
await this.tspmInstance.delete(id);
return { success: true, message: `Process ${id} deleted successfully` };
} catch (error) {
throw new Error(`Failed to remove process: ${error.message}`);
}
@@ -245,9 +255,10 @@ export class TspmDaemon {
this.ipcServer.onMessage(
'describe',
async (request: RequestForMethod<'describe'>) => {
const result = await this.tspmInstance.describe(request.id);
const id = String(request.id).trim();
const result = await this.tspmInstance.describe(id);
if (!result) {
throw new Error(`Process ${request.id} not found`);
throw new Error(`Process ${id} not found`);
}
// Return correctly shaped response
return {