From 4ee4bcdda29b78a89111ec29693f4b97f9a88043 Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Thu, 28 Aug 2025 18:34:56 +0000 Subject: [PATCH] fix(cli): Fix internal imports, centralize IPC types and improve daemon entry/start behavior --- changelog.md | 8 ++++++ ts/00_commitinfo_data.ts | 2 +- ts/cli/commands/batch/restart-all.ts | 2 +- ts/cli/commands/batch/start-all.ts | 2 +- ts/cli/commands/batch/stop-all.ts | 2 +- ts/cli/commands/daemon/index.ts | 6 ++--- ts/cli/commands/default.ts | 4 +-- ts/cli/commands/process/describe.ts | 2 +- ts/cli/commands/process/logs.ts | 2 +- ts/cli/commands/process/start.ts | 2 +- ts/cli/commands/service/disable.ts | 4 +-- ts/cli/commands/service/enable.ts | 4 +-- ts/cli/registration/daemon-check.ts | 2 +- ts/cli/utils/ipc.ts | 2 +- ts/daemon/index.ts | 21 ++++++++++----- ts/daemon/processmanager.ts | 27 +++++--------------- ts/daemon/processmonitor.ts | 14 ++-------- ts/daemon/processwrapper.ts | 9 +------ ts/index.ts | 14 +++++----- ts/shared/protocol/ipc.types.ts | 38 ++++++++++++++++++++++++++-- 20 files changed, 95 insertions(+), 72 deletions(-) diff --git a/changelog.md b/changelog.md index a35c806..7b1351c 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,13 @@ # Changelog +## 2025-08-28 - 3.1.1 - fix(cli) +Fix internal imports, centralize IPC types and improve daemon entry/start behavior + +- Corrected import paths in CLI commands and utilities to use client/tspm.ipcclient and shared/common/utils.errorhandler +- Centralized process/IPC type definitions into ts/shared/protocol/ipc.types.ts and updated references across daemon and client code +- Refactored ts/daemon/index.ts to export startDaemon and only auto-start the daemon when the module is executed directly +- Adjusted ts/index.ts exports to expose client API, shared protocol types, and daemon start entrypoint + ## 2025-08-28 - 3.1.0 - feat(daemon) Reorganize and refactor core into client/daemon/shared modules; add IPC protocol and tests diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 1b53454..acc40c9 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@git.zone/tspm', - version: '3.1.0', + version: '3.1.1', description: 'a no fuzz process manager' } diff --git a/ts/cli/commands/batch/restart-all.ts b/ts/cli/commands/batch/restart-all.ts index d525385..75134bc 100644 --- a/ts/cli/commands/batch/restart-all.ts +++ b/ts/cli/commands/batch/restart-all.ts @@ -1,5 +1,5 @@ import * as plugins from '../../../plugins.js'; -import { tspmIpcClient } from '../../../classes.ipcclient.js'; +import { tspmIpcClient } from '../../../client/tspm.ipcclient.js'; import type { CliArguments } from '../../types.js'; import { registerIpcCommand } from '../../registration/index.js'; diff --git a/ts/cli/commands/batch/start-all.ts b/ts/cli/commands/batch/start-all.ts index c514c93..93ed7bf 100644 --- a/ts/cli/commands/batch/start-all.ts +++ b/ts/cli/commands/batch/start-all.ts @@ -1,5 +1,5 @@ import * as plugins from '../../../plugins.js'; -import { tspmIpcClient } from '../../../classes.ipcclient.js'; +import { tspmIpcClient } from '../../../client/tspm.ipcclient.js'; import type { CliArguments } from '../../types.js'; import { registerIpcCommand } from '../../registration/index.js'; diff --git a/ts/cli/commands/batch/stop-all.ts b/ts/cli/commands/batch/stop-all.ts index c7c533f..4d08018 100644 --- a/ts/cli/commands/batch/stop-all.ts +++ b/ts/cli/commands/batch/stop-all.ts @@ -1,5 +1,5 @@ import * as plugins from '../../../plugins.js'; -import { tspmIpcClient } from '../../../classes.ipcclient.js'; +import { tspmIpcClient } from '../../../client/tspm.ipcclient.js'; import type { CliArguments } from '../../types.js'; import { registerIpcCommand } from '../../registration/index.js'; diff --git a/ts/cli/commands/daemon/index.ts b/ts/cli/commands/daemon/index.ts index 7766ef2..3c7ba45 100644 --- a/ts/cli/commands/daemon/index.ts +++ b/ts/cli/commands/daemon/index.ts @@ -1,7 +1,7 @@ import * as plugins from '../../../plugins.js'; import * as paths from '../../../paths.js'; -import { tspmIpcClient } from '../../../classes.ipcclient.js'; -import { Logger } from '../../../utils.errorhandler.js'; +import { tspmIpcClient } from '../../../client/tspm.ipcclient.js'; +import { Logger } from '../../../shared/common/utils.errorhandler.js'; import type { CliArguments } from '../../types.js'; import { formatMemory } from '../../helpers/memory.js'; @@ -83,7 +83,7 @@ export function registerDaemonCommand(smartcli: plugins.smartcli.Smartcli) { case 'start-service': // This is called by systemd - start the daemon directly console.log('Starting TSPM daemon for systemd service...'); - const { startDaemon } = await import('../../../classes.daemon.js'); + const { startDaemon } = await import('../../../daemon/tspm.daemon.js'); await startDaemon(); break; diff --git a/ts/cli/commands/default.ts b/ts/cli/commands/default.ts index ed79b15..4bd6122 100644 --- a/ts/cli/commands/default.ts +++ b/ts/cli/commands/default.ts @@ -1,7 +1,7 @@ import * as plugins from '../../plugins.js'; import * as paths from '../../paths.js'; -import { tspmIpcClient } from '../../classes.ipcclient.js'; -import { Logger } from '../../utils.errorhandler.js'; +import { tspmIpcClient } from '../../client/tspm.ipcclient.js'; +import { Logger } from '../../shared/common/utils.errorhandler.js'; import type { CliArguments } from '../types.js'; import { pad } from '../helpers/formatting.js'; import { formatMemory } from '../helpers/memory.js'; diff --git a/ts/cli/commands/process/describe.ts b/ts/cli/commands/process/describe.ts index 4121d96..8994195 100644 --- a/ts/cli/commands/process/describe.ts +++ b/ts/cli/commands/process/describe.ts @@ -1,5 +1,5 @@ import * as plugins from '../../../plugins.js'; -import { tspmIpcClient } from '../../../classes.ipcclient.js'; +import { tspmIpcClient } from '../../../client/tspm.ipcclient.js'; import type { CliArguments } from '../../types.js'; import { registerIpcCommand } from '../../registration/index.js'; import { formatMemory } from '../../helpers/memory.js'; diff --git a/ts/cli/commands/process/logs.ts b/ts/cli/commands/process/logs.ts index adb5b78..2e3322b 100644 --- a/ts/cli/commands/process/logs.ts +++ b/ts/cli/commands/process/logs.ts @@ -1,5 +1,5 @@ import * as plugins from '../../../plugins.js'; -import { tspmIpcClient } from '../../../classes.ipcclient.js'; +import { tspmIpcClient } from '../../../client/tspm.ipcclient.js'; import type { CliArguments } from '../../types.js'; import { registerIpcCommand } from '../../registration/index.js'; import { getBool, getNumber } from '../../helpers/argv.js'; diff --git a/ts/cli/commands/process/start.ts b/ts/cli/commands/process/start.ts index bf36bd6..f26c433 100644 --- a/ts/cli/commands/process/start.ts +++ b/ts/cli/commands/process/start.ts @@ -1,6 +1,6 @@ import * as plugins from '../../../plugins.js'; import { tspmIpcClient } from '../../../client/tspm.ipcclient.js'; -import type { IProcessConfig } from '../../../classes.tspm.js'; +import type { IProcessConfig } from '../../../shared/protocol/ipc.types.js'; import type { CliArguments } from '../../types.js'; import { parseMemoryString, formatMemory } from '../../helpers/memory.js'; import { registerIpcCommand } from '../../registration/index.js'; diff --git a/ts/cli/commands/service/disable.ts b/ts/cli/commands/service/disable.ts index 2c4e18b..f55f66f 100644 --- a/ts/cli/commands/service/disable.ts +++ b/ts/cli/commands/service/disable.ts @@ -1,6 +1,6 @@ import * as plugins from '../../../plugins.js'; -import { TspmServiceManager } from '../../../classes.servicemanager.js'; -import { Logger } from '../../../utils.errorhandler.js'; +import { TspmServiceManager } from '../../../client/tspm.servicemanager.js'; +import { Logger } from '../../../shared/common/utils.errorhandler.js'; import type { CliArguments } from '../../types.js'; export function registerDisableCommand(smartcli: plugins.smartcli.Smartcli) { diff --git a/ts/cli/commands/service/enable.ts b/ts/cli/commands/service/enable.ts index 918d80e..91767b6 100644 --- a/ts/cli/commands/service/enable.ts +++ b/ts/cli/commands/service/enable.ts @@ -1,6 +1,6 @@ import * as plugins from '../../../plugins.js'; -import { TspmServiceManager } from '../../../classes.servicemanager.js'; -import { Logger } from '../../../utils.errorhandler.js'; +import { TspmServiceManager } from '../../../client/tspm.servicemanager.js'; +import { Logger } from '../../../shared/common/utils.errorhandler.js'; import type { CliArguments } from '../../types.js'; export function registerEnableCommand(smartcli: plugins.smartcli.Smartcli) { diff --git a/ts/cli/registration/daemon-check.ts b/ts/cli/registration/daemon-check.ts index 860f948..6a6d35c 100644 --- a/ts/cli/registration/daemon-check.ts +++ b/ts/cli/registration/daemon-check.ts @@ -1,4 +1,4 @@ -import { tspmIpcClient } from '../../classes.ipcclient.js'; +import { tspmIpcClient } from '../../client/tspm.ipcclient.js'; /** * Preflight the daemon if required. Uses getDaemonStatus() which is safe and cheap: diff --git a/ts/cli/utils/ipc.ts b/ts/cli/utils/ipc.ts index 59d7cac..6c97562 100644 --- a/ts/cli/utils/ipc.ts +++ b/ts/cli/utils/ipc.ts @@ -1,4 +1,4 @@ -import { tspmIpcClient } from '../../classes.ipcclient.js'; +import { tspmIpcClient } from '../../client/tspm.ipcclient.js'; // Helper function to run IPC commands with automatic disconnect export async function runIpcCommand(body: () => Promise): Promise { diff --git a/ts/daemon/index.ts b/ts/daemon/index.ts index 632fe6d..00e2599 100644 --- a/ts/daemon/index.ts +++ b/ts/daemon/index.ts @@ -1,9 +1,18 @@ #!/usr/bin/env node -import { startDaemon } from './tspm.daemon.js'; +/** + * Daemon entry point - runs process management server + * This should only be run directly by the CLI or as a systemd service + */ -// Start the daemon -startDaemon().catch((error) => { - console.error('Failed to start daemon:', error); - process.exit(1); -}); +export { startDaemon } from './tspm.daemon.js'; + +// When executed directly (not imported), start the daemon +if (import.meta.url === `file://${process.argv[1]}`) { + import('./tspm.daemon.js').then(({ startDaemon }) => { + startDaemon().catch((error) => { + console.error('Failed to start daemon:', error); + process.exit(1); + }); + }); +} diff --git a/ts/daemon/processmanager.ts b/ts/daemon/processmanager.ts index cd36c7d..d098803 100644 --- a/ts/daemon/processmanager.ts +++ b/ts/daemon/processmanager.ts @@ -1,11 +1,7 @@ import * as plugins from '../plugins.js'; import { EventEmitter } from 'events'; import * as paths from '../paths.js'; -import { - ProcessMonitor, - type IMonitorConfig, -} from './processmonitor.js'; -import { type IProcessLog } from './processwrapper.js'; +import { ProcessMonitor } from './processmonitor.js'; import { TspmConfig } from './tspm.config.js'; import { Logger, @@ -14,23 +10,14 @@ import { ValidationError, handleError, } from '../shared/common/utils.errorhandler.js'; +import type { + IProcessConfig, + IProcessInfo, + IProcessLog, + IMonitorConfig +} from '../shared/protocol/ipc.types.js'; -export interface IProcessConfig extends IMonitorConfig { - id: string; // Unique identifier for the process - autorestart: boolean; // Whether to restart the process automatically on crash - watch?: boolean; // Whether to watch for file changes and restart - watchPaths?: string[]; // Paths to watch for changes -} -export interface IProcessInfo { - id: string; - pid?: number; - status: 'online' | 'stopped' | 'errored'; - memory: number; - cpu?: number; - uptime?: number; - restarts: number; -} export class ProcessManager extends EventEmitter { public processes: Map = new Map(); diff --git a/ts/daemon/processmonitor.ts b/ts/daemon/processmonitor.ts index afee984..31a494d 100644 --- a/ts/daemon/processmonitor.ts +++ b/ts/daemon/processmonitor.ts @@ -1,18 +1,8 @@ import * as plugins from '../plugins.js'; import { EventEmitter } from 'events'; -import { ProcessWrapper, type IProcessLog } from './processwrapper.js'; +import { ProcessWrapper } from './processwrapper.js'; import { Logger, ProcessError, handleError } from '../shared/common/utils.errorhandler.js'; - -export interface IMonitorConfig { - name?: string; // Optional name to identify the instance - projectDir: string; // Directory where the command will run - command: string; // Full command to run (e.g., "npm run xyz") - args?: string[]; // Optional: arguments for the command - memoryLimitBytes: number; // Maximum allowed memory (in bytes) for the process group - monitorIntervalMs?: number; // Interval (in ms) at which memory is checked (default: 5000) - env?: NodeJS.ProcessEnv; // Optional: custom environment variables - logBufferSize?: number; // Optional: number of log lines to keep (default: 100) -} +import type { IMonitorConfig, IProcessLog } from '../shared/protocol/ipc.types.js'; export class ProcessMonitor extends EventEmitter { private processWrapper: ProcessWrapper | null = null; diff --git a/ts/daemon/processwrapper.ts b/ts/daemon/processwrapper.ts index f2b86ad..208e573 100644 --- a/ts/daemon/processwrapper.ts +++ b/ts/daemon/processwrapper.ts @@ -1,6 +1,7 @@ import * as plugins from '../plugins.js'; import { EventEmitter } from 'events'; import { Logger, ProcessError, handleError } from '../shared/common/utils.errorhandler.js'; +import type { IProcessLog } from '../shared/protocol/ipc.types.js'; export interface IProcessWrapperOptions { command: string; @@ -11,14 +12,6 @@ export interface IProcessWrapperOptions { logBuffer?: number; // Number of log lines to keep in memory (default: 100) } -export interface IProcessLog { - timestamp: Date; - type: 'stdout' | 'stderr' | 'system'; - message: string; - seq: number; - runId: string; -} - export class ProcessWrapper extends EventEmitter { private process: plugins.childProcess.ChildProcess | null = null; private options: IProcessWrapperOptions; diff --git a/ts/index.ts b/ts/index.ts index 3282157..193ed5f 100644 --- a/ts/index.ts +++ b/ts/index.ts @@ -1,9 +1,11 @@ -export * from './classes.tspm.js'; -export * from './classes.processmonitor.js'; -export * from './classes.daemon.js'; -export * from './classes.ipcclient.js'; -export * from './classes.servicemanager.js'; -export * from './ipc.types.js'; +// Client exports - for library consumers +export * from './client/index.js'; + +// Protocol types - shared between client and daemon +export * from './shared/protocol/ipc.types.js'; + +// Daemon exports - for direct daemon control +export { startDaemon } from './daemon/index.js'; import * as cli from './cli.js'; diff --git a/ts/shared/protocol/ipc.types.ts b/ts/shared/protocol/ipc.types.ts index 3d245a5..25eb0df 100644 --- a/ts/shared/protocol/ipc.types.ts +++ b/ts/shared/protocol/ipc.types.ts @@ -1,5 +1,39 @@ -import type { IProcessConfig, IProcessInfo } from './classes.tspm.js'; -import type { IProcessLog } from './classes.processwrapper.js'; +// Process-related interfaces (used in IPC communication) +export interface IMonitorConfig { + name?: string; // Optional name to identify the instance + projectDir: string; // Directory where the command will run + command: string; // Full command to run (e.g., "npm run xyz") + args?: string[]; // Optional: arguments for the command + memoryLimitBytes: number; // Maximum allowed memory (in bytes) for the process group + monitorIntervalMs?: number; // Interval (in ms) at which memory is checked (default: 5000) + env?: NodeJS.ProcessEnv; // Optional: custom environment variables + logBufferSize?: number; // Optional: number of log lines to keep (default: 100) +} + +export interface IProcessConfig extends IMonitorConfig { + id: string; // Unique identifier for the process + autorestart: boolean; // Whether to restart the process automatically on crash + watch?: boolean; // Whether to watch for file changes and restart + watchPaths?: string[]; // Paths to watch for changes +} + +export interface IProcessInfo { + id: string; + pid?: number; + status: 'online' | 'stopped' | 'errored'; + memory: number; + cpu?: number; + uptime?: number; + restarts: number; +} + +export interface IProcessLog { + timestamp: Date; + type: 'stdout' | 'stderr' | 'system'; + message: string; + seq: number; + runId: string; +} // Base message types export interface IpcRequest {