daedalus-cli 1.97.1 → 1.97.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/utils/sys-stats.d.ts +1 -33
- package/dist/utils/sys-stats.d.ts.map +1 -1
- package/dist/utils/sys-stats.js +31 -58
- package/dist/utils/sys-stats.js.map +1 -1
- package/dist/utils/sys-stats.test.d.ts +2 -0
- package/dist/utils/sys-stats.test.d.ts.map +1 -0
- package/dist/utils/sys-stats.test.js +43 -0
- package/dist/utils/sys-stats.test.js.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [1.97.2](https://github.com/bgill55/daedalus/compare/v1.97.1...v1.97.2) (2026-07-30)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **sys-stats:** resolve Qodo review findings - replace df/wmic with fs.statfsSync, guard formatBytes against invalid ranges, and remove redundant JSDoc ([2350dc3](https://github.com/bgill55/daedalus/commit/2350dc3f39ce64f376756644cec35c9420c753b5))
|
|
7
|
+
|
|
1
8
|
## [1.97.1](https://github.com/bgill55/daedalus/compare/v1.97.0...v1.97.1) (2026-07-30)
|
|
2
9
|
|
|
3
10
|
|
|
@@ -1,49 +1,17 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memory statistics for the current system.
|
|
3
|
-
*/
|
|
4
1
|
export interface MemoryStats {
|
|
5
|
-
/** Total system memory in bytes */
|
|
6
2
|
total: number;
|
|
7
|
-
/** Free (available) memory in bytes */
|
|
8
3
|
free: number;
|
|
9
|
-
/** Used memory in bytes */
|
|
10
4
|
used: number;
|
|
11
|
-
/** Percentage of memory used (0‑100) */
|
|
12
5
|
usagePercent: number;
|
|
13
6
|
}
|
|
14
|
-
/**
|
|
15
|
-
* Disk statistics for a given path/volume.
|
|
16
|
-
*/
|
|
17
7
|
export interface DiskStats {
|
|
18
|
-
/** Path that was inspected, e.g. '/' or 'C:\\' */
|
|
19
8
|
path: string;
|
|
20
|
-
/** Total size of the disk/volume in bytes */
|
|
21
9
|
total: number;
|
|
22
|
-
/** Free space on the disk/volume in bytes */
|
|
23
10
|
free: number;
|
|
24
|
-
/** Used space on the disk/volume in bytes */
|
|
25
11
|
used: number;
|
|
26
|
-
/** Percentage of disk space used (0‑100) */
|
|
27
12
|
usagePercent: number;
|
|
28
13
|
}
|
|
29
|
-
/**
|
|
30
|
-
* Retrieve memory usage statistics.
|
|
31
|
-
*/
|
|
32
14
|
export declare function getMemoryStats(): Promise<MemoryStats>;
|
|
33
|
-
|
|
34
|
-
* Retrieve disk usage statistics for the supplied path.
|
|
35
|
-
*
|
|
36
|
-
* This implementation uses the `df` command on Unix‑like systems and falls back
|
|
37
|
-
* to a simple `wmic` query on Windows. The command output is parsed to extract
|
|
38
|
-
* total, used, and free space in bytes.
|
|
39
|
-
*/
|
|
40
|
-
export declare function getDiskStats(path: string): Promise<DiskStats>;
|
|
41
|
-
/**
|
|
42
|
-
* Convert a byte count into a human‑readable string.
|
|
43
|
-
*
|
|
44
|
-
* @param bytes Number of bytes.
|
|
45
|
-
* @param decimals Number of decimal places (default 2).
|
|
46
|
-
* @returns Human readable string, e.g. "1.23 MB".
|
|
47
|
-
*/
|
|
15
|
+
export declare function getDiskStats(targetPath: string): Promise<DiskStats>;
|
|
48
16
|
export declare function formatBytes(bytes: number, decimals?: number): string;
|
|
49
17
|
//# sourceMappingURL=sys-stats.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sys-stats.d.ts","sourceRoot":"","sources":["../../src/utils/sys-stats.ts"],"names":[],"mappings":"AAGA
|
|
1
|
+
{"version":3,"file":"sys-stats.d.ts","sourceRoot":"","sources":["../../src/utils/sys-stats.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC,CAW3D;AAED,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CA4BzE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,SAAI,GAAG,MAAM,CAa/D"}
|
package/dist/utils/sys-stats.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import fs from 'fs';
|
|
2
2
|
import os from 'os';
|
|
3
|
-
/**
|
|
4
|
-
* Retrieve memory usage statistics.
|
|
5
|
-
*/
|
|
6
3
|
export async function getMemoryStats() {
|
|
7
4
|
const total = os.totalmem();
|
|
8
5
|
const free = os.freemem();
|
|
9
|
-
const used = total - free;
|
|
10
|
-
const usagePercent = total === 0 ? 0 : (used / total) * 100;
|
|
6
|
+
const used = Math.max(0, total - free);
|
|
7
|
+
const usagePercent = total === 0 ? 0 : Number(((used / total) * 100).toFixed(2));
|
|
11
8
|
return {
|
|
12
9
|
total,
|
|
13
10
|
free,
|
|
@@ -15,69 +12,45 @@ export async function getMemoryStats() {
|
|
|
15
12
|
usagePercent,
|
|
16
13
|
};
|
|
17
14
|
}
|
|
18
|
-
|
|
19
|
-
* Retrieve disk usage statistics for the supplied path.
|
|
20
|
-
*
|
|
21
|
-
* This implementation uses the `df` command on Unix‑like systems and falls back
|
|
22
|
-
* to a simple `wmic` query on Windows. The command output is parsed to extract
|
|
23
|
-
* total, used, and free space in bytes.
|
|
24
|
-
*/
|
|
25
|
-
export async function getDiskStats(path) {
|
|
26
|
-
let output;
|
|
15
|
+
export async function getDiskStats(targetPath) {
|
|
27
16
|
try {
|
|
28
|
-
|
|
29
|
-
|
|
17
|
+
if (typeof fs.statfsSync === 'function') {
|
|
18
|
+
const stats = fs.statfsSync(targetPath);
|
|
19
|
+
const bsize = stats.bsize || 4096;
|
|
20
|
+
const total = stats.blocks * bsize;
|
|
21
|
+
const free = stats.bavail * bsize;
|
|
22
|
+
const used = Math.max(0, total - free);
|
|
23
|
+
const usagePercent = total === 0 ? 0 : Number(((used / total) * 100).toFixed(2));
|
|
24
|
+
return {
|
|
25
|
+
path: targetPath,
|
|
26
|
+
total,
|
|
27
|
+
free,
|
|
28
|
+
used,
|
|
29
|
+
usagePercent,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
30
32
|
}
|
|
31
|
-
catch
|
|
32
|
-
//
|
|
33
|
-
// Example: wmic logicaldisk where "DeviceID='C:'" get Size,FreeSpace /format:csv
|
|
34
|
-
const winPath = path.replace(/\\$/, ''); // remove trailing backslash if present
|
|
35
|
-
output = execSync(`wmic logicaldisk where "DeviceID='${winPath}'" get Size,FreeSpace /format:csv`, { encoding: 'utf8' });
|
|
36
|
-
}
|
|
37
|
-
// Split output into lines and ignore empty ones.
|
|
38
|
-
const lines = output.split(/\r?\n/).filter((l) => l.trim().length > 0);
|
|
39
|
-
// The first line is a header; the second line contains the values.
|
|
40
|
-
const dataLine = lines[1] ?? '';
|
|
41
|
-
const parts = dataLine.trim().split(/\s+/);
|
|
42
|
-
// `df` format: Filesystem 1K-blocks Used Available Use% Mounted on
|
|
43
|
-
// `wmic` CSV format may differ; we handle the `df` case which is used in tests.
|
|
44
|
-
let total = 0;
|
|
45
|
-
let used = 0;
|
|
46
|
-
let free = 0;
|
|
47
|
-
let usagePercent = 0;
|
|
48
|
-
if (parts.length >= 5) {
|
|
49
|
-
// Assume df output.
|
|
50
|
-
const totalK = Number(parts[1]);
|
|
51
|
-
const usedK = Number(parts[2]);
|
|
52
|
-
const availableK = Number(parts[3]);
|
|
53
|
-
const percentStr = parts[4];
|
|
54
|
-
total = totalK * 1024;
|
|
55
|
-
used = usedK * 1024;
|
|
56
|
-
free = availableK * 1024;
|
|
57
|
-
usagePercent = Number(percentStr.replace('%', ''));
|
|
33
|
+
catch {
|
|
34
|
+
// Fallback if statfsSync fails
|
|
58
35
|
}
|
|
59
36
|
return {
|
|
60
|
-
path,
|
|
61
|
-
total,
|
|
62
|
-
free,
|
|
63
|
-
used,
|
|
64
|
-
usagePercent,
|
|
37
|
+
path: targetPath,
|
|
38
|
+
total: 0,
|
|
39
|
+
free: 0,
|
|
40
|
+
used: 0,
|
|
41
|
+
usagePercent: 0,
|
|
65
42
|
};
|
|
66
43
|
}
|
|
67
|
-
/**
|
|
68
|
-
* Convert a byte count into a human‑readable string.
|
|
69
|
-
*
|
|
70
|
-
* @param bytes Number of bytes.
|
|
71
|
-
* @param decimals Number of decimal places (default 2).
|
|
72
|
-
* @returns Human readable string, e.g. "1.23 MB".
|
|
73
|
-
*/
|
|
74
44
|
export function formatBytes(bytes, decimals = 2) {
|
|
75
|
-
if (bytes
|
|
45
|
+
if (!Number.isFinite(bytes) || bytes <= 0) {
|
|
76
46
|
return '0 Bytes';
|
|
47
|
+
}
|
|
77
48
|
const k = 1024;
|
|
78
49
|
const dm = decimals < 0 ? 0 : decimals;
|
|
79
50
|
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
|
80
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
51
|
+
const i = Math.min(Math.floor(Math.log(bytes) / Math.log(k)), sizes.length - 1);
|
|
52
|
+
if (i < 0)
|
|
53
|
+
return '0 Bytes';
|
|
81
54
|
const size = parseFloat((bytes / Math.pow(k, i)).toFixed(dm));
|
|
82
55
|
return `${size} ${sizes[i]}`;
|
|
83
56
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sys-stats.js","sourceRoot":"","sources":["../../src/utils/sys-stats.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"sys-stats.js","sourceRoot":"","sources":["../../src/utils/sys-stats.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sys-stats.test.d.ts","sourceRoot":"","sources":["../../src/utils/sys-stats.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import { getMemoryStats, getDiskStats, formatBytes } from './sys-stats.js';
|
|
4
|
+
describe('sys-stats utility', () => {
|
|
5
|
+
it('returns valid memory statistics', async () => {
|
|
6
|
+
const stats = await getMemoryStats();
|
|
7
|
+
expect(stats.total).toBeGreaterThan(0);
|
|
8
|
+
expect(stats.free).toBeGreaterThanOrEqual(0);
|
|
9
|
+
expect(stats.used).toBeGreaterThanOrEqual(0);
|
|
10
|
+
expect(stats.usagePercent).toBeGreaterThanOrEqual(0);
|
|
11
|
+
expect(stats.usagePercent).toBeLessThanOrEqual(100);
|
|
12
|
+
});
|
|
13
|
+
it('returns valid disk statistics via fs.statfsSync', async () => {
|
|
14
|
+
const stats = await getDiskStats(process.cwd());
|
|
15
|
+
expect(stats.path).toBe(process.cwd());
|
|
16
|
+
expect(stats.total).toBeGreaterThanOrEqual(0);
|
|
17
|
+
expect(stats.free).toBeGreaterThanOrEqual(0);
|
|
18
|
+
});
|
|
19
|
+
it('handles disk stats fallback gracefully when statfs throws', async () => {
|
|
20
|
+
const spy = vi.spyOn(fs, 'statfsSync').mockImplementation(() => {
|
|
21
|
+
throw new Error('Permission denied');
|
|
22
|
+
});
|
|
23
|
+
const stats = await getDiskStats('/invalid/path');
|
|
24
|
+
expect(stats.total).toBe(0);
|
|
25
|
+
expect(stats.free).toBe(0);
|
|
26
|
+
spy.mockRestore();
|
|
27
|
+
});
|
|
28
|
+
describe('formatBytes', () => {
|
|
29
|
+
it('formats 0 and negative bytes safely', () => {
|
|
30
|
+
expect(formatBytes(0)).toBe('0 Bytes');
|
|
31
|
+
expect(formatBytes(-100)).toBe('0 Bytes');
|
|
32
|
+
expect(formatBytes(NaN)).toBe('0 Bytes');
|
|
33
|
+
expect(formatBytes(Infinity)).toBe('0 Bytes');
|
|
34
|
+
});
|
|
35
|
+
it('formats bytes, KB, MB, GB, TB accurately', () => {
|
|
36
|
+
expect(formatBytes(500)).toBe('500 Bytes');
|
|
37
|
+
expect(formatBytes(1024)).toBe('1 KB');
|
|
38
|
+
expect(formatBytes(1048576)).toBe('1 MB');
|
|
39
|
+
expect(formatBytes(1073741824)).toBe('1 GB');
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
//# sourceMappingURL=sys-stats.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sys-stats.test.js","sourceRoot":"","sources":["../../src/utils/sys-stats.test.ts"],"names":[],"mappings":"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"}
|