fix(cli): Fix internal imports, centralize IPC types and improve daemon entry/start behavior
This commit is contained in:
@@ -1,5 +1,13 @@
|
|||||||
# Changelog
|
# 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)
|
## 2025-08-28 - 3.1.0 - feat(daemon)
|
||||||
Reorganize and refactor core into client/daemon/shared modules; add IPC protocol and tests
|
Reorganize and refactor core into client/daemon/shared modules; add IPC protocol and tests
|
||||||
|
|
||||||
|
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@git.zone/tspm',
|
name: '@git.zone/tspm',
|
||||||
version: '3.1.0',
|
version: '3.1.1',
|
||||||
description: 'a no fuzz process manager'
|
description: 'a no fuzz process manager'
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import * as plugins from '../../../plugins.js';
|
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 type { CliArguments } from '../../types.js';
|
||||||
import { registerIpcCommand } from '../../registration/index.js';
|
import { registerIpcCommand } from '../../registration/index.js';
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import * as plugins from '../../../plugins.js';
|
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 type { CliArguments } from '../../types.js';
|
||||||
import { registerIpcCommand } from '../../registration/index.js';
|
import { registerIpcCommand } from '../../registration/index.js';
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import * as plugins from '../../../plugins.js';
|
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 type { CliArguments } from '../../types.js';
|
||||||
import { registerIpcCommand } from '../../registration/index.js';
|
import { registerIpcCommand } from '../../registration/index.js';
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import * as plugins from '../../../plugins.js';
|
import * as plugins from '../../../plugins.js';
|
||||||
import * as paths from '../../../paths.js';
|
import * as paths from '../../../paths.js';
|
||||||
import { tspmIpcClient } from '../../../classes.ipcclient.js';
|
import { tspmIpcClient } from '../../../client/tspm.ipcclient.js';
|
||||||
import { Logger } from '../../../utils.errorhandler.js';
|
import { Logger } from '../../../shared/common/utils.errorhandler.js';
|
||||||
import type { CliArguments } from '../../types.js';
|
import type { CliArguments } from '../../types.js';
|
||||||
import { formatMemory } from '../../helpers/memory.js';
|
import { formatMemory } from '../../helpers/memory.js';
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ export function registerDaemonCommand(smartcli: plugins.smartcli.Smartcli) {
|
|||||||
case 'start-service':
|
case 'start-service':
|
||||||
// This is called by systemd - start the daemon directly
|
// This is called by systemd - start the daemon directly
|
||||||
console.log('Starting TSPM daemon for systemd service...');
|
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();
|
await startDaemon();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import * as plugins from '../../plugins.js';
|
import * as plugins from '../../plugins.js';
|
||||||
import * as paths from '../../paths.js';
|
import * as paths from '../../paths.js';
|
||||||
import { tspmIpcClient } from '../../classes.ipcclient.js';
|
import { tspmIpcClient } from '../../client/tspm.ipcclient.js';
|
||||||
import { Logger } from '../../utils.errorhandler.js';
|
import { Logger } from '../../shared/common/utils.errorhandler.js';
|
||||||
import type { CliArguments } from '../types.js';
|
import type { CliArguments } from '../types.js';
|
||||||
import { pad } from '../helpers/formatting.js';
|
import { pad } from '../helpers/formatting.js';
|
||||||
import { formatMemory } from '../helpers/memory.js';
|
import { formatMemory } from '../helpers/memory.js';
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import * as plugins from '../../../plugins.js';
|
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 type { CliArguments } from '../../types.js';
|
||||||
import { registerIpcCommand } from '../../registration/index.js';
|
import { registerIpcCommand } from '../../registration/index.js';
|
||||||
import { formatMemory } from '../../helpers/memory.js';
|
import { formatMemory } from '../../helpers/memory.js';
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import * as plugins from '../../../plugins.js';
|
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 type { CliArguments } from '../../types.js';
|
||||||
import { registerIpcCommand } from '../../registration/index.js';
|
import { registerIpcCommand } from '../../registration/index.js';
|
||||||
import { getBool, getNumber } from '../../helpers/argv.js';
|
import { getBool, getNumber } from '../../helpers/argv.js';
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import * as plugins from '../../../plugins.js';
|
import * as plugins from '../../../plugins.js';
|
||||||
import { tspmIpcClient } from '../../../client/tspm.ipcclient.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 type { CliArguments } from '../../types.js';
|
||||||
import { parseMemoryString, formatMemory } from '../../helpers/memory.js';
|
import { parseMemoryString, formatMemory } from '../../helpers/memory.js';
|
||||||
import { registerIpcCommand } from '../../registration/index.js';
|
import { registerIpcCommand } from '../../registration/index.js';
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import * as plugins from '../../../plugins.js';
|
import * as plugins from '../../../plugins.js';
|
||||||
import { TspmServiceManager } from '../../../classes.servicemanager.js';
|
import { TspmServiceManager } from '../../../client/tspm.servicemanager.js';
|
||||||
import { Logger } from '../../../utils.errorhandler.js';
|
import { Logger } from '../../../shared/common/utils.errorhandler.js';
|
||||||
import type { CliArguments } from '../../types.js';
|
import type { CliArguments } from '../../types.js';
|
||||||
|
|
||||||
export function registerDisableCommand(smartcli: plugins.smartcli.Smartcli) {
|
export function registerDisableCommand(smartcli: plugins.smartcli.Smartcli) {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import * as plugins from '../../../plugins.js';
|
import * as plugins from '../../../plugins.js';
|
||||||
import { TspmServiceManager } from '../../../classes.servicemanager.js';
|
import { TspmServiceManager } from '../../../client/tspm.servicemanager.js';
|
||||||
import { Logger } from '../../../utils.errorhandler.js';
|
import { Logger } from '../../../shared/common/utils.errorhandler.js';
|
||||||
import type { CliArguments } from '../../types.js';
|
import type { CliArguments } from '../../types.js';
|
||||||
|
|
||||||
export function registerEnableCommand(smartcli: plugins.smartcli.Smartcli) {
|
export function registerEnableCommand(smartcli: plugins.smartcli.Smartcli) {
|
||||||
|
@@ -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:
|
* Preflight the daemon if required. Uses getDaemonStatus() which is safe and cheap:
|
||||||
|
@@ -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
|
// Helper function to run IPC commands with automatic disconnect
|
||||||
export async function runIpcCommand<T>(body: () => Promise<T>): Promise<T> {
|
export async function runIpcCommand<T>(body: () => Promise<T>): Promise<T> {
|
||||||
|
@@ -1,9 +1,18 @@
|
|||||||
#!/usr/bin/env node
|
#!/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
|
export { startDaemon } from './tspm.daemon.js';
|
||||||
startDaemon().catch((error) => {
|
|
||||||
console.error('Failed to start daemon:', error);
|
// When executed directly (not imported), start the daemon
|
||||||
process.exit(1);
|
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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@@ -1,11 +1,7 @@
|
|||||||
import * as plugins from '../plugins.js';
|
import * as plugins from '../plugins.js';
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import * as paths from '../paths.js';
|
import * as paths from '../paths.js';
|
||||||
import {
|
import { ProcessMonitor } from './processmonitor.js';
|
||||||
ProcessMonitor,
|
|
||||||
type IMonitorConfig,
|
|
||||||
} from './processmonitor.js';
|
|
||||||
import { type IProcessLog } from './processwrapper.js';
|
|
||||||
import { TspmConfig } from './tspm.config.js';
|
import { TspmConfig } from './tspm.config.js';
|
||||||
import {
|
import {
|
||||||
Logger,
|
Logger,
|
||||||
@@ -14,23 +10,14 @@ import {
|
|||||||
ValidationError,
|
ValidationError,
|
||||||
handleError,
|
handleError,
|
||||||
} from '../shared/common/utils.errorhandler.js';
|
} 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 {
|
export class ProcessManager extends EventEmitter {
|
||||||
public processes: Map<string, ProcessMonitor> = new Map();
|
public processes: Map<string, ProcessMonitor> = new Map();
|
||||||
|
@@ -1,18 +1,8 @@
|
|||||||
import * as plugins from '../plugins.js';
|
import * as plugins from '../plugins.js';
|
||||||
import { EventEmitter } from 'events';
|
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';
|
import { Logger, ProcessError, handleError } from '../shared/common/utils.errorhandler.js';
|
||||||
|
import type { IMonitorConfig, IProcessLog } from '../shared/protocol/ipc.types.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)
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ProcessMonitor extends EventEmitter {
|
export class ProcessMonitor extends EventEmitter {
|
||||||
private processWrapper: ProcessWrapper | null = null;
|
private processWrapper: ProcessWrapper | null = null;
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import * as plugins from '../plugins.js';
|
import * as plugins from '../plugins.js';
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import { Logger, ProcessError, handleError } from '../shared/common/utils.errorhandler.js';
|
import { Logger, ProcessError, handleError } from '../shared/common/utils.errorhandler.js';
|
||||||
|
import type { IProcessLog } from '../shared/protocol/ipc.types.js';
|
||||||
|
|
||||||
export interface IProcessWrapperOptions {
|
export interface IProcessWrapperOptions {
|
||||||
command: string;
|
command: string;
|
||||||
@@ -11,14 +12,6 @@ export interface IProcessWrapperOptions {
|
|||||||
logBuffer?: number; // Number of log lines to keep in memory (default: 100)
|
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 {
|
export class ProcessWrapper extends EventEmitter {
|
||||||
private process: plugins.childProcess.ChildProcess | null = null;
|
private process: plugins.childProcess.ChildProcess | null = null;
|
||||||
private options: IProcessWrapperOptions;
|
private options: IProcessWrapperOptions;
|
||||||
|
14
ts/index.ts
14
ts/index.ts
@@ -1,9 +1,11 @@
|
|||||||
export * from './classes.tspm.js';
|
// Client exports - for library consumers
|
||||||
export * from './classes.processmonitor.js';
|
export * from './client/index.js';
|
||||||
export * from './classes.daemon.js';
|
|
||||||
export * from './classes.ipcclient.js';
|
// Protocol types - shared between client and daemon
|
||||||
export * from './classes.servicemanager.js';
|
export * from './shared/protocol/ipc.types.js';
|
||||||
export * from './ipc.types.js';
|
|
||||||
|
// Daemon exports - for direct daemon control
|
||||||
|
export { startDaemon } from './daemon/index.js';
|
||||||
|
|
||||||
import * as cli from './cli.js';
|
import * as cli from './cli.js';
|
||||||
|
|
||||||
|
@@ -1,5 +1,39 @@
|
|||||||
import type { IProcessConfig, IProcessInfo } from './classes.tspm.js';
|
// Process-related interfaces (used in IPC communication)
|
||||||
import type { IProcessLog } from './classes.processwrapper.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)
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
// Base message types
|
||||||
export interface IpcRequest<T = any> {
|
export interface IpcRequest<T = any> {
|
||||||
|
Reference in New Issue
Block a user