Compare commits

...

6 Commits

Author SHA1 Message Date
d8709d8b94 5.4.2
Some checks failed
Default (tags) / security (push) Successful in 49s
Default (tags) / test (push) Failing after 3m58s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-08-30 22:16:44 +00:00
43799f3431 fix(cli/process/logs): Reset log sequence on process restart to avoid false log gap warnings 2025-08-30 22:16:44 +00:00
f4cbdd51e1 5.4.1
Some checks failed
Default (tags) / security (push) Successful in 38s
Default (tags) / test (push) Failing after 3m58s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-08-30 22:08:24 +00:00
1340c1c248 fix(processmonitor): Bump tsbuild devDependency and relax ps-tree callback typing in ProcessMonitor 2025-08-30 22:08:24 +00:00
92a6ecac71 5.4.0
Some checks failed
Default (tags) / security (push) Successful in 40s
Default (tags) / test (push) Failing after 3m58s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-08-30 22:01:19 +00:00
5e26b0ab5f feat(daemon): Add CLI systemd service refresh on version mismatch and fix daemon memory leak; update dependencies 2025-08-30 22:01:19 +00:00
9 changed files with 148 additions and 19 deletions

View File

@@ -1,5 +1,27 @@
# Changelog # Changelog
## 2025-08-30 - 5.4.2 - fix(cli/process/logs)
Reset log sequence on process restart to avoid false log gap warnings
- Track process runId when streaming logs and initialize lastRunId from fetched logs
- When a new runId is detected, reset lastSeq so that subsequent streamed logs are accepted (prevents spurious gap warnings)
- Emit an informational message when a restart/runId change is detected to aid debugging of log streams
## 2025-08-30 - 5.4.1 - fix(processmonitor)
Bump tsbuild devDependency and relax ps-tree callback typing in ProcessMonitor
- Update devDependency @git.zone/tsbuild from ^2.6.7 to ^2.6.8
- Change psTree callback types in ts/daemon/processmonitor.ts to accept any error and ReadonlyArray for children to improve type compatibility
## 2025-08-30 - 5.4.0 - feat(daemon)
Add CLI systemd service refresh on version mismatch and fix daemon memory leak; update dependencies
- CLI: when client and daemon versions differ, prompt to refresh the systemd service and optionally disable/enable the service automatically
- Daemon: clear pidusage state for PIDs on process exit/stop to prevent memory leaks in long-running monitors
- Client: expose smartdaemon in client plugin exports and fix import path for tspm.servicemanager
- Package: tighten dependency ranges (set specific versions) and add @types for pidusage and ps-tree
- Misc: ensure IPC disconnects and PID/socket handling improvements were integrated alongside the above changes
## 2025-08-30 - 5.3.2 - fix(daemon) ## 2025-08-30 - 5.3.2 - fix(daemon)
Improve daemon log delivery and process monitor memory accounting; gate debug output and update tests to numeric ProcessId Improve daemon log delivery and process monitor memory accounting; gate debug output and update tests to numeric ProcessId

View File

@@ -1,6 +1,6 @@
{ {
"name": "@git.zone/tspm", "name": "@git.zone/tspm",
"version": "5.3.2", "version": "5.4.2",
"private": false, "private": false,
"description": "a no fuzz process manager", "description": "a no fuzz process manager",
"main": "dist_ts/index.js", "main": "dist_ts/index.js",
@@ -24,7 +24,7 @@
"tspm": "./cli.js" "tspm": "./cli.js"
}, },
"devDependencies": { "devDependencies": {
"@git.zone/tsbuild": "^2.6.7", "@git.zone/tsbuild": "^2.6.8",
"@git.zone/tsbundle": "^2.5.1", "@git.zone/tsbundle": "^2.5.1",
"@git.zone/tsrun": "^1.2.46", "@git.zone/tsrun": "^1.2.46",
"@git.zone/tstest": "^2.3.5", "@git.zone/tstest": "^2.3.5",
@@ -40,6 +40,8 @@
"@push.rocks/smartinteract": "^2.0.16", "@push.rocks/smartinteract": "^2.0.16",
"@push.rocks/smartipc": "^2.2.2", "@push.rocks/smartipc": "^2.2.2",
"@push.rocks/smartpath": "^6.0.0", "@push.rocks/smartpath": "^6.0.0",
"@types/pidusage": "^2.0.5",
"@types/ps-tree": "^1.1.6",
"pidusage": "^4.0.1", "pidusage": "^4.0.1",
"ps-tree": "^1.2.0", "ps-tree": "^1.2.0",
"tsx": "^4.20.5" "tsx": "^4.20.5"

74
pnpm-lock.yaml generated
View File

@@ -32,6 +32,12 @@ importers:
'@push.rocks/smartpath': '@push.rocks/smartpath':
specifier: ^6.0.0 specifier: ^6.0.0
version: 6.0.0 version: 6.0.0
'@types/pidusage':
specifier: ^2.0.5
version: 2.0.5
'@types/ps-tree':
specifier: ^1.1.6
version: 1.1.6
pidusage: pidusage:
specifier: ^4.0.1 specifier: ^4.0.1
version: 4.0.1 version: 4.0.1
@@ -43,8 +49,8 @@ importers:
version: 4.20.5 version: 4.20.5
devDependencies: devDependencies:
'@git.zone/tsbuild': '@git.zone/tsbuild':
specifier: ^2.6.7 specifier: ^2.6.8
version: 2.6.7 version: 2.6.8
'@git.zone/tsbundle': '@git.zone/tsbundle':
specifier: ^2.5.1 specifier: ^2.5.1
version: 2.5.1 version: 2.5.1
@@ -530,8 +536,8 @@ packages:
'@esm-bundle/chai@4.3.4-fix.0': '@esm-bundle/chai@4.3.4-fix.0':
resolution: {integrity: sha512-26SKdM4uvDWlY8/OOOxSB1AqQWeBosCX3wRYUZO7enTAj03CtVxIiCimYVG2WpULcyV51qapK4qTovwkUr5Mlw==} resolution: {integrity: sha512-26SKdM4uvDWlY8/OOOxSB1AqQWeBosCX3wRYUZO7enTAj03CtVxIiCimYVG2WpULcyV51qapK4qTovwkUr5Mlw==}
'@git.zone/tsbuild@2.6.7': '@git.zone/tsbuild@2.6.8':
resolution: {integrity: sha512-nLRYk1V4gxdEAp5mbLYNdr/in9mFA26L4MPKBKqzASID4lXSYya5sDbLRdDTv+mD0ZRBgdn6e+WMylA0SU4hSw==} resolution: {integrity: sha512-g1z7+MxiYD0xMfuqn8NSWitbfK1OaF0Qolmw7WOmUsHmNF60T1AR02Lo4DtNmnjSpchA+xzDFAQzL1xTcQA39w==}
hasBin: true hasBin: true
'@git.zone/tsbundle@2.5.1': '@git.zone/tsbundle@2.5.1':
@@ -769,8 +775,8 @@ packages:
'@push.rocks/isounique@1.0.5': '@push.rocks/isounique@1.0.5':
resolution: {integrity: sha512-Z0BVqZZOCif1THTbIKWMgg0wxCzt9CyBtBBqQJiZ+jJ0KlQFrQHNHrPt81/LXe/L4x0cxWsn0bpL6W5DNSvNLw==} resolution: {integrity: sha512-Z0BVqZZOCif1THTbIKWMgg0wxCzt9CyBtBBqQJiZ+jJ0KlQFrQHNHrPt81/LXe/L4x0cxWsn0bpL6W5DNSvNLw==}
'@push.rocks/levelcache@3.1.1': '@push.rocks/levelcache@3.2.0':
resolution: {integrity: sha512-+JpDNEt+EuvmbtADGH9SkODxBy+slHDDzs43mAbuMbwpVvi6uNuMK0Mkhrfz9UFpxUSp+cJE/jl/OxdpD0xL1A==} resolution: {integrity: sha512-Ch0Oguta2I0SVi704kHghhBcgfyfS92ua1elRu9d8X1/9LMRYuqvvBAnyXyFxQzI3S8q8QC6EkRdd8CAAYSzRg==}
'@push.rocks/lik@6.1.0': '@push.rocks/lik@6.1.0':
resolution: {integrity: sha512-BoSAIRFNryQ8Sd5EP+35ZBj6vAQ1C60/XjZIO2O65XDyLG8xz7xJ+u5Wm8/fjIJ0WX3h8GkkaCz2tJM34nFT3A==} resolution: {integrity: sha512-BoSAIRFNryQ8Sd5EP+35ZBj6vAQ1C60/XjZIO2O65XDyLG8xz7xJ+u5Wm8/fjIJ0WX3h8GkkaCz2tJM34nFT3A==}
@@ -805,6 +811,9 @@ packages:
'@push.rocks/smartcache@1.0.16': '@push.rocks/smartcache@1.0.16':
resolution: {integrity: sha512-UAXf74eDuH4/RebJhydIbHlYVR3ACYJjniEY/9ZePblu7bIPgwFZqLBE9g1lcKVogbH9yY62dk3rSpgBzenyfQ==} resolution: {integrity: sha512-UAXf74eDuH4/RebJhydIbHlYVR3ACYJjniEY/9ZePblu7bIPgwFZqLBE9g1lcKVogbH9yY62dk3rSpgBzenyfQ==}
'@push.rocks/smartcache@1.0.18':
resolution: {integrity: sha512-3+cmLu9chbnmi4yD4kjlFP/Tn4NReaZIoicEcGTtwbcokTrSDMs3YPdJzIpDZkAs83PW7OcVSHa3Ak5KU5OWzA==}
'@push.rocks/smartchok@1.1.1': '@push.rocks/smartchok@1.1.1':
resolution: {integrity: sha512-WmNigGmn1muBJMANVuJb4F8x3TzgYrnn6YZm6ixTsG+0WFbYevivEwp+J4S7npobLHsR7ynf+Ky8LxRYmsL50A==} resolution: {integrity: sha512-WmNigGmn1muBJMANVuJb4F8x3TzgYrnn6YZm6ixTsG+0WFbYevivEwp+J4S7npobLHsR7ynf+Ky8LxRYmsL50A==}
@@ -832,6 +841,9 @@ packages:
'@push.rocks/smartenv@5.0.13': '@push.rocks/smartenv@5.0.13':
resolution: {integrity: sha512-ACXmUcHZHl2CF2jnVuRw9saRRrZvJblCRs2d+K5aLR1DfkYFX3eA21kcMlKeLisI3aGNbIj9vz/rowN5qkRkfA==} resolution: {integrity: sha512-ACXmUcHZHl2CF2jnVuRw9saRRrZvJblCRs2d+K5aLR1DfkYFX3eA21kcMlKeLisI3aGNbIj9vz/rowN5qkRkfA==}
'@push.rocks/smarterror@2.0.1':
resolution: {integrity: sha512-iCcH1D8tlDJgMFsaJ6lhdOTKhbU0KoprNv9MRP9o7691QOx4JEDXiHtr/lNtxVo8BUtdb9CF6kazaknO9KuORA==}
'@push.rocks/smartexit@1.0.23': '@push.rocks/smartexit@1.0.23':
resolution: {integrity: sha512-WmwKYcwbHBByoABhHHB+PAjr5475AtD/xBh1mDcqPrFsOOUOZq3BBUdpq25wI3ccu/SZB5IwaimiVzadls6HkA==} resolution: {integrity: sha512-WmwKYcwbHBByoABhHHB+PAjr5475AtD/xBh1mDcqPrFsOOUOZq3BBUdpq25wI3ccu/SZB5IwaimiVzadls6HkA==}
@@ -1012,6 +1024,9 @@ packages:
'@push.rocks/tapbundle@6.0.3': '@push.rocks/tapbundle@6.0.3':
resolution: {integrity: sha512-SuP14V6TPdtd1y1CYTvwTKJdpHa7EzY55NfaaEMxW4oRKvHgJiOiPEiR/IrtL9tSiDMSfrx12waTMgZheYaBug==} resolution: {integrity: sha512-SuP14V6TPdtd1y1CYTvwTKJdpHa7EzY55NfaaEMxW4oRKvHgJiOiPEiR/IrtL9tSiDMSfrx12waTMgZheYaBug==}
'@push.rocks/taskbuffer@3.1.10':
resolution: {integrity: sha512-jT+FxRSk0+IP17q9LD1/Ks8GJBn5TZWgLtfnKRHW/LAZ1bHX/2ARZvAV8fm1T4WMU5s7PyId+y4fkoohG/5Nkg==}
'@push.rocks/taskbuffer@3.1.7': '@push.rocks/taskbuffer@3.1.7':
resolution: {integrity: sha512-QktGVJPucqQmW/QNGnscf4FAigT1H7JWKFGFdRuDEaOHKFh9qN+PXG3QY7DtZ4jfXdGLxPN4yAufDuPSAJYFnw==} resolution: {integrity: sha512-QktGVJPucqQmW/QNGnscf4FAigT1H7JWKFGFdRuDEaOHKFh9qN+PXG3QY7DtZ4jfXdGLxPN4yAufDuPSAJYFnw==}
@@ -1647,9 +1662,15 @@ packages:
'@types/parse5@6.0.3': '@types/parse5@6.0.3':
resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==} resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==}
'@types/pidusage@2.0.5':
resolution: {integrity: sha512-MIiyZI4/MK9UGUXWt0jJcCZhVw7YdhBuTOuqP/BjuLDLZ2PmmViMIQgZiWxtaMicQfAz/kMrZ5T7PKxFSkTeUA==}
'@types/ping@0.4.4': '@types/ping@0.4.4':
resolution: {integrity: sha512-ifvo6w2f5eJYlXm+HiVx67iJe8WZp87sfa683nlqED5Vnt9Z93onkokNoWqOG21EaE8fMxyKPobE+mkPEyxsdw==} resolution: {integrity: sha512-ifvo6w2f5eJYlXm+HiVx67iJe8WZp87sfa683nlqED5Vnt9Z93onkokNoWqOG21EaE8fMxyKPobE+mkPEyxsdw==}
'@types/ps-tree@1.1.6':
resolution: {integrity: sha512-PtrlVaOaI44/3pl3cvnlK+GxOM3re2526TJvPvh7W+keHIXdV4TE0ylpPBAcvFQCbGitaTXwL9u+RF7qtVeazQ==}
'@types/qs@6.14.0': '@types/qs@6.14.0':
resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==}
@@ -5599,7 +5620,7 @@ snapshots:
dependencies: dependencies:
'@types/chai': 4.3.20 '@types/chai': 4.3.20
'@git.zone/tsbuild@2.6.7': '@git.zone/tsbuild@2.6.8':
dependencies: dependencies:
'@git.zone/tspublish': 1.10.3 '@git.zone/tspublish': 1.10.3
'@push.rocks/early': 4.0.4 '@push.rocks/early': 4.0.4
@@ -6015,21 +6036,21 @@ snapshots:
'@push.rocks/isounique@1.0.5': {} '@push.rocks/isounique@1.0.5': {}
'@push.rocks/levelcache@3.1.1': '@push.rocks/levelcache@3.2.0':
dependencies: dependencies:
'@push.rocks/lik': 6.2.2 '@push.rocks/lik': 6.2.2
'@push.rocks/smartbucket': 3.3.10 '@push.rocks/smartbucket': 3.3.10
'@push.rocks/smartcache': 1.0.16 '@push.rocks/smartcache': 1.0.18
'@push.rocks/smartenv': 5.0.13 '@push.rocks/smartenv': 5.0.13
'@push.rocks/smartexit': 1.0.23 '@push.rocks/smartexit': 1.0.23
'@push.rocks/smartfile': 11.2.7 '@push.rocks/smartfile': 11.2.7
'@push.rocks/smartjson': 5.0.20 '@push.rocks/smartjson': 5.0.20
'@push.rocks/smartpath': 5.1.0 '@push.rocks/smartpath': 6.0.0
'@push.rocks/smartpromise': 4.2.3 '@push.rocks/smartpromise': 4.2.3
'@push.rocks/smartstring': 4.0.15 '@push.rocks/smartstring': 4.0.15
'@push.rocks/smartunique': 3.0.9 '@push.rocks/smartunique': 3.0.9
'@push.rocks/taskbuffer': 3.1.7 '@push.rocks/taskbuffer': 3.1.10
'@tsclass/tsclass': 4.4.4 '@tsclass/tsclass': 9.2.0
transitivePeerDependencies: transitivePeerDependencies:
- aws-crt - aws-crt
@@ -6158,6 +6179,14 @@ snapshots:
'@pushrocks/smartpromise': 3.1.10 '@pushrocks/smartpromise': 3.1.10
'@pushrocks/smarttime': 4.0.1 '@pushrocks/smarttime': 4.0.1
'@push.rocks/smartcache@1.0.18':
dependencies:
'@push.rocks/smartdelay': 3.0.5
'@push.rocks/smarterror': 2.0.1
'@push.rocks/smarthash': 3.2.3
'@push.rocks/smartpromise': 4.2.3
'@push.rocks/smarttime': 4.1.1
'@push.rocks/smartchok@1.1.1': '@push.rocks/smartchok@1.1.1':
dependencies: dependencies:
'@push.rocks/lik': 6.2.2 '@push.rocks/lik': 6.2.2
@@ -6237,6 +6266,11 @@ snapshots:
dependencies: dependencies:
'@push.rocks/smartpromise': 4.2.3 '@push.rocks/smartpromise': 4.2.3
'@push.rocks/smarterror@2.0.1':
dependencies:
clean-stack: 1.3.0
make-error-cause: 2.3.0
'@push.rocks/smartexit@1.0.23': '@push.rocks/smartexit@1.0.23':
dependencies: dependencies:
'@push.rocks/lik': 6.1.0 '@push.rocks/lik': 6.1.0
@@ -6443,7 +6477,7 @@ snapshots:
'@push.rocks/smartnpm@2.0.6': '@push.rocks/smartnpm@2.0.6':
dependencies: dependencies:
'@push.rocks/consolecolor': 2.0.3 '@push.rocks/consolecolor': 2.0.3
'@push.rocks/levelcache': 3.1.1 '@push.rocks/levelcache': 3.2.0
'@push.rocks/smartarchive': 4.2.2 '@push.rocks/smartarchive': 4.2.2
'@push.rocks/smartfile': 11.2.7 '@push.rocks/smartfile': 11.2.7
'@push.rocks/smartpath': 6.0.0 '@push.rocks/smartpath': 6.0.0
@@ -6745,6 +6779,16 @@ snapshots:
- supports-color - supports-color
- utf-8-validate - utf-8-validate
'@push.rocks/taskbuffer@3.1.10':
dependencies:
'@push.rocks/lik': 6.2.2
'@push.rocks/smartdelay': 3.0.5
'@push.rocks/smartlog': 3.1.8
'@push.rocks/smartpromise': 4.2.3
'@push.rocks/smartrx': 3.0.10
'@push.rocks/smarttime': 4.1.1
'@push.rocks/smartunique': 3.0.9
'@push.rocks/taskbuffer@3.1.7': '@push.rocks/taskbuffer@3.1.7':
dependencies: dependencies:
'@push.rocks/lik': 6.2.2 '@push.rocks/lik': 6.2.2
@@ -7592,8 +7636,12 @@ snapshots:
'@types/parse5@6.0.3': {} '@types/parse5@6.0.3': {}
'@types/pidusage@2.0.5': {}
'@types/ping@0.4.4': {} '@types/ping@0.4.4': {}
'@types/ps-tree@1.1.6': {}
'@types/qs@6.14.0': {} '@types/qs@6.14.0': {}
'@types/randomatic@3.1.5': {} '@types/randomatic@3.1.5': {}

View File

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

View File

@@ -50,6 +50,7 @@ export function registerLogsCommand(smartcli: plugins.smartcli.Smartcli) {
console.log('─'.repeat(60)); console.log('─'.repeat(60));
let lastSeq = 0; let lastSeq = 0;
let lastRunId: string | undefined = undefined;
for (const log of response.logs) { for (const log of response.logs) {
const timestamp = new Date(log.timestamp).toLocaleTimeString(); const timestamp = new Date(log.timestamp).toLocaleTimeString();
const prefix = const prefix =
@@ -60,11 +61,18 @@ export function registerLogsCommand(smartcli: plugins.smartcli.Smartcli) {
: '[SYS]'; : '[SYS]';
console.log(`${timestamp} ${prefix} ${log.message}`); console.log(`${timestamp} ${prefix} ${log.message}`);
if (log.seq !== undefined) lastSeq = Math.max(lastSeq, log.seq); if (log.seq !== undefined) lastSeq = Math.max(lastSeq, log.seq);
if ((log as any).runId) lastRunId = (log as any).runId;
} }
await withStreamingLifecycle( await withStreamingLifecycle(
async () => { async () => {
await tspmIpcClient.subscribe(id, (log: any) => { await tspmIpcClient.subscribe(id, (log: any) => {
// Reset sequence if runId changed (e.g., process restarted)
if (log.runId && log.runId !== lastRunId) {
console.log(`[INFO] Detected process restart (runId changed).`);
lastSeq = -1;
lastRunId = log.runId;
}
if (log.seq !== undefined && log.seq <= lastSeq) return; if (log.seq !== undefined && log.seq <= lastSeq) return;
if (log.seq !== undefined && log.seq > lastSeq + 1) { if (log.seq !== undefined && log.seq > lastSeq + 1) {
console.log( console.log(

View File

@@ -2,6 +2,7 @@ import * as plugins from './plugins.js';
import { tspmIpcClient } from '../client/tspm.ipcclient.js'; import { tspmIpcClient } from '../client/tspm.ipcclient.js';
import * as paths from '../paths.js'; import * as paths from '../paths.js';
import { Logger, LogLevel } from '../shared/common/utils.errorhandler.js'; import { Logger, LogLevel } from '../shared/common/utils.errorhandler.js';
import { TspmServiceManager } from '../client/tspm.servicemanager.js';
// Import command registration functions // Import command registration functions
import { registerDefaultCommand } from './commands/default.js'; import { registerDefaultCommand } from './commands/default.js';
@@ -51,6 +52,38 @@ export const run = async (): Promise<void> => {
console.log( console.log(
`Daemon: running v${status.version || 'unknown'} (pid ${status.pid})`, `Daemon: running v${status.version || 'unknown'} (pid ${status.pid})`,
); );
// If versions mismatch, offer to refresh the systemd service
if (status.version && status.version !== cliVersion) {
console.log('\nVersion mismatch detected:');
console.log(` CLI: v${cliVersion}`);
console.log(` Daemon: v${status.version}`);
console.log(
'\nThis can happen after upgrading tspm. The systemd service may still point to an older version.\n' +
'You can refresh the service (equivalent to "tspm disable" then "tspm enable").',
);
// Ask the user for confirmation
const confirm = await plugins.smartinteract.SmartInteract.getCliConfirmation(
'Refresh the systemd service now?',
true,
);
if (confirm) {
try {
const sm = new TspmServiceManager();
console.log('Refreshing TSPM system service...');
await sm.disableService();
await sm.enableService();
console.log('✓ Service refreshed. Daemon restarted via systemd.');
} catch (err: any) {
console.error(
'Failed to refresh service automatically. You can try manually:\n tspm disable && tspm enable',
);
console.error(err?.message || String(err));
}
} else {
console.log('Skipped service refresh.');
}
}
} else { } else {
console.log('Daemon: not running'); console.log('Daemon: not running');
} }

View File

@@ -1,6 +1,7 @@
// Minimal plugin set for lightweight client startup // Minimal plugin set for lightweight client startup
import * as path from 'node:path'; import * as path from 'node:path';
import * as smartdaemon from '@push.rocks/smartdaemon';
import * as smartipc from '@push.rocks/smartipc'; import * as smartipc from '@push.rocks/smartipc';
export { path, smartipc }; export { path, smartdaemon, smartipc };

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 * as paths from '../paths.js';
/** /**

View File

@@ -139,6 +139,14 @@ export class ProcessMonitor extends EventEmitter {
this.logger.info(exitMsg); this.logger.info(exitMsg);
this.log(exitMsg); this.log(exitMsg);
// Clear pidusage internal state for this PID to prevent memory leaks
try {
const pidToClear = this.processWrapper?.getPid();
if (pidToClear) {
(plugins.pidusage as any)?.clear?.(pidToClear);
}
} catch {}
// Flush logs to disk on exit // Flush logs to disk on exit
if (this.processId && this.logs.length > 0) { if (this.processId && this.logs.length > 0) {
try { try {
@@ -303,7 +311,7 @@ export class ProcessMonitor extends EventEmitter {
plugins.psTree( plugins.psTree(
pid, pid,
(err: Error | null, children: Array<{ PID: string }>) => { (err: any, children: ReadonlyArray<{ PID: string }>) => {
if (err) { if (err) {
const processError = new ProcessError( const processError = new ProcessError(
`Failed to get process tree: ${err.message}`, `Failed to get process tree: ${err.message}`,
@@ -385,6 +393,13 @@ export class ProcessMonitor extends EventEmitter {
clearInterval(this.intervalId); clearInterval(this.intervalId);
} }
if (this.processWrapper) { if (this.processWrapper) {
// Clear pidusage state for current PID before stopping to avoid leaks
try {
const pidToClear = this.processWrapper.getPid();
if (pidToClear) {
(plugins.pidusage as any)?.clear?.(pidToClear);
}
} catch {}
this.processWrapper.stop(); this.processWrapper.stop();
} }
} }