import { ChildProcess, SpawnOptions } from 'node:child_process';
import { ServiceSchema } from 'moleculer';
interface SpawnedProcess {
    readonly pid: number;
    readonly nodeId: string;
    readonly name: string;
    /**
     * For per-addon processes: the single addon hosted by this child.
     * For group-runner processes: a synthetic label `group:${groupId}` —
     * the real list of hosted addons lives on `groupAddons`.
     */
    readonly addonId: string;
    readonly addonDir: string;
    /** Set when this process was launched as a group-runner. */
    readonly groupAddons?: readonly {
        readonly addonId: string;
        readonly addonDir: string;
    }[];
    readonly startedAt: number;
    restartCount: number;
    state: 'starting' | 'running' | 'stopped' | 'crashed';
    child: ChildProcess;
}
interface ProcessInfo {
    readonly pid: number;
    readonly nodeId: string;
    readonly name: string;
    readonly addonId: string;
    /**
     * For group-runner processes hosting multiple addons: the full list
     * of addon ids inside this subprocess. `undefined` for legacy single-
     * addon spawns. Cluster page UI expands this to render every addon
     * under the same process card so operators see what's running where.
     */
    readonly addonIds?: readonly string[];
    /** Group label when this is a group-runner subprocess; `undefined` otherwise. */
    readonly groupId?: string;
    readonly isolated: boolean;
    readonly spawnedBy: string | null;
    readonly startedAt: number;
    readonly restartCount: number;
    readonly state: string;
    readonly cpuPercent: number;
    readonly memoryRss: number;
    readonly uptimeSeconds: number;
}
/**
 * Subprocess spawner injected into `createProcessService`. Production
 * code passes `child_process.spawn`; tests pass a fake that records
 * the call shape and returns a stub `ChildProcess`. Centralising the
 * dependency here is the only ESM-safe way to intercept spawn — the
 * `node:child_process` module export is non-configurable so `vi.spyOn`
 * fails. The injection point is private to this module: callers don't
 * see it, so the public `createProcessService(parentNodeId, dataDir)`
 * shape stays unchanged.
 */
type SpawnFn = (command: string, args: readonly string[], opts: SpawnOptions) => ChildProcess;
interface ProcessServiceDeps {
    readonly spawnFn?: SpawnFn;
}
declare function createProcessService(parentNodeId: string, dataDir: string, deps?: ProcessServiceDeps): ServiceSchema;
export { createProcessService };
export type { ProcessInfo, SpawnedProcess };
//# sourceMappingURL=process-service.d.ts.map