@songsid/agend 2.1.10 → 2.1.11-beta.1
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/dist/backend/antigravity.js +3 -2
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/backend/claude-code.d.ts +7 -0
- package/dist/backend/claude-code.js +107 -3
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/cli-env-probe-worker.js +2 -10
- package/dist/backend/cli-env-probe-worker.js.map +1 -1
- package/dist/backend/cli-env-probe.d.ts +14 -0
- package/dist/backend/cli-env-probe.js +13 -0
- package/dist/backend/cli-env-probe.js.map +1 -0
- package/dist/backend/codex-metadata.d.ts +14 -0
- package/dist/backend/codex-metadata.js +70 -0
- package/dist/backend/codex-metadata.js.map +1 -0
- package/dist/backend/codex.d.ts +1 -2
- package/dist/backend/codex.js +112 -65
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/effort-metadata.d.ts +32 -0
- package/dist/backend/effort-metadata.js +21 -0
- package/dist/backend/effort-metadata.js.map +1 -0
- package/dist/backend/grok.js +3 -2
- package/dist/backend/grok.js.map +1 -1
- package/dist/backend/kiro.d.ts +3 -0
- package/dist/backend/kiro.js +19 -4
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/muse.js +3 -2
- package/dist/backend/muse.js.map +1 -1
- package/dist/backend/opencode.d.ts +31 -4
- package/dist/backend/opencode.js +66 -23
- package/dist/backend/opencode.js.map +1 -1
- package/dist/backend/types.d.ts +14 -1
- package/dist/backend/types.js.map +1 -1
- package/dist/channel/adapters/discord.js +10 -2
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/cli.js +48 -6
- package/dist/cli.js.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/daemon.d.ts +24 -0
- package/dist/daemon.js +109 -12
- package/dist/daemon.js.map +1 -1
- package/dist/doctor.d.ts +3 -1
- package/dist/doctor.js +11 -0
- package/dist/doctor.js.map +1 -1
- package/dist/fleet-context.d.ts +2 -2
- package/dist/fleet-control-audit.d.ts +83 -0
- package/dist/fleet-control-audit.js +195 -0
- package/dist/fleet-control-audit.js.map +1 -0
- package/dist/fleet-manager.d.ts +45 -35
- package/dist/fleet-manager.js +327 -384
- package/dist/fleet-manager.js.map +1 -1
- package/dist/full-restart.js +2 -1
- package/dist/full-restart.js.map +1 -1
- package/dist/general-knowledge/skills/fleet-config/SKILL.md +3 -2
- package/dist/host-memory.d.ts +16 -0
- package/dist/host-memory.js +32 -0
- package/dist/host-memory.js.map +1 -0
- package/dist/instance-lifecycle.js +4 -1
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/locale.js +62 -16
- package/dist/locale.js.map +1 -1
- package/dist/log-tail.d.ts +34 -0
- package/dist/log-tail.js +66 -0
- package/dist/log-tail.js.map +1 -0
- package/dist/logger.d.ts +15 -0
- package/dist/logger.js +89 -1
- package/dist/logger.js.map +1 -1
- package/dist/login-controller.d.ts +1 -3
- package/dist/login-controller.js +2 -6
- package/dist/login-controller.js.map +1 -1
- package/dist/login-flows.d.ts +0 -8
- package/dist/login-flows.js +1 -11
- package/dist/login-flows.js.map +1 -1
- package/dist/login-manager.d.ts +5 -20
- package/dist/login-manager.js +0 -53
- package/dist/login-manager.js.map +1 -1
- package/dist/login-window-lock.d.ts +1 -1
- package/dist/login-window-lock.js +1 -1
- package/dist/memory-pressure.d.ts +41 -0
- package/dist/memory-pressure.js +117 -0
- package/dist/memory-pressure.js.map +1 -0
- package/dist/probe-worker-pool.d.ts +28 -0
- package/dist/probe-worker-pool.js +129 -0
- package/dist/probe-worker-pool.js.map +1 -0
- package/dist/resource-report.d.ts +31 -0
- package/dist/resource-report.js +209 -0
- package/dist/resource-report.js.map +1 -0
- package/dist/rollout-index.d.ts +66 -0
- package/dist/rollout-index.js +124 -0
- package/dist/rollout-index.js.map +1 -0
- package/dist/slash-authz.d.ts +50 -0
- package/dist/slash-authz.js +19 -0
- package/dist/slash-authz.js.map +1 -0
- package/dist/spawn-gate.d.ts +13 -1
- package/dist/spawn-gate.js +108 -39
- package/dist/spawn-gate.js.map +1 -1
- package/dist/storm-window.d.ts +42 -0
- package/dist/storm-window.js +84 -1
- package/dist/storm-window.js.map +1 -1
- package/dist/topic-commands.d.ts +29 -2
- package/dist/topic-commands.js +77 -21
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-sources.d.ts +21 -4
- package/dist/transcript-sources.js +55 -41
- package/dist/transcript-sources.js.map +1 -1
- package/dist/types.d.ts +5 -1
- package/dist/ui/settings.html +14 -13
- package/package.json +1 -1
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type HostMemory } from "./host-memory.js";
|
|
2
|
+
export type MemoryPressureLevel = "normal" | "elevated" | "critical" | "unknown";
|
|
3
|
+
export interface MemoryPressureSnapshot {
|
|
4
|
+
level: MemoryPressureLevel;
|
|
5
|
+
memory: HostMemory | null;
|
|
6
|
+
sampledAt: number | null;
|
|
7
|
+
recovering: boolean;
|
|
8
|
+
samples: number;
|
|
9
|
+
/** Change per minute over the bounded observation window; negative means draining. */
|
|
10
|
+
trend: {
|
|
11
|
+
availableBytesPerMinute: number;
|
|
12
|
+
swapFreeBytesPerMinute: number | null;
|
|
13
|
+
} | null;
|
|
14
|
+
}
|
|
15
|
+
interface Options {
|
|
16
|
+
read?: () => HostMemory;
|
|
17
|
+
now?: () => number;
|
|
18
|
+
onSample?: (snapshot: MemoryPressureSnapshot) => void;
|
|
19
|
+
criticalBytes?: number;
|
|
20
|
+
}
|
|
21
|
+
export declare const MEMORY_SAMPLE_MS = 30000;
|
|
22
|
+
export declare const MEMORY_RECOVERY_MS = 30000;
|
|
23
|
+
/** One fleet sampler/policy, shared by spawn admission and health. No subprocesses. */
|
|
24
|
+
export declare class MemoryPressure {
|
|
25
|
+
private readonly options;
|
|
26
|
+
private readonly read;
|
|
27
|
+
private readonly now;
|
|
28
|
+
private timer;
|
|
29
|
+
private history;
|
|
30
|
+
private recoveryUntil;
|
|
31
|
+
private current;
|
|
32
|
+
constructor(options?: Options);
|
|
33
|
+
start(): void;
|
|
34
|
+
stop(): void;
|
|
35
|
+
/** Sampling may detect recovery before a long admission backoff expires. */
|
|
36
|
+
startRecoveryWindow(): MemoryPressureSnapshot;
|
|
37
|
+
/** Health readers cannot create samples or move recovery deadlines. */
|
|
38
|
+
snapshot(): MemoryPressureSnapshot;
|
|
39
|
+
sample(): MemoryPressureSnapshot;
|
|
40
|
+
}
|
|
41
|
+
export {};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { readHostMemory } from "./host-memory.js";
|
|
2
|
+
const MiB = 1024 * 1024;
|
|
3
|
+
export const MEMORY_SAMPLE_MS = 30_000;
|
|
4
|
+
export const MEMORY_RECOVERY_MS = 30_000;
|
|
5
|
+
/** One fleet sampler/policy, shared by spawn admission and health. No subprocesses. */
|
|
6
|
+
export class MemoryPressure {
|
|
7
|
+
options;
|
|
8
|
+
read;
|
|
9
|
+
now;
|
|
10
|
+
timer = null;
|
|
11
|
+
history = [];
|
|
12
|
+
recoveryUntil = 0;
|
|
13
|
+
current = {
|
|
14
|
+
level: "unknown", memory: null, sampledAt: null, recovering: false, samples: 0, trend: null,
|
|
15
|
+
};
|
|
16
|
+
constructor(options = {}) {
|
|
17
|
+
this.options = options;
|
|
18
|
+
this.read = options.read ?? readHostMemory;
|
|
19
|
+
this.now = options.now ?? Date.now;
|
|
20
|
+
}
|
|
21
|
+
start() {
|
|
22
|
+
if (this.timer)
|
|
23
|
+
return;
|
|
24
|
+
this.timer = setInterval(() => this.sample(), MEMORY_SAMPLE_MS);
|
|
25
|
+
this.timer.unref?.();
|
|
26
|
+
this.sample();
|
|
27
|
+
}
|
|
28
|
+
stop() {
|
|
29
|
+
if (this.timer)
|
|
30
|
+
clearInterval(this.timer);
|
|
31
|
+
this.timer = null;
|
|
32
|
+
}
|
|
33
|
+
/** Sampling may detect recovery before a long admission backoff expires. */
|
|
34
|
+
startRecoveryWindow() {
|
|
35
|
+
this.recoveryUntil = this.now() + MEMORY_RECOVERY_MS;
|
|
36
|
+
this.current = { ...this.current, recovering: true,
|
|
37
|
+
level: this.current.level === "normal" ? "elevated" : this.current.level };
|
|
38
|
+
return this.snapshot();
|
|
39
|
+
}
|
|
40
|
+
/** Health readers cannot create samples or move recovery deadlines. */
|
|
41
|
+
snapshot() {
|
|
42
|
+
return { ...this.current, memory: this.current.memory && { ...this.current.memory }, trend: this.current.trend && { ...this.current.trend } };
|
|
43
|
+
}
|
|
44
|
+
sample() {
|
|
45
|
+
const at = this.now();
|
|
46
|
+
let memory = null;
|
|
47
|
+
try {
|
|
48
|
+
const value = this.read();
|
|
49
|
+
if (Number.isFinite(value.totalBytes) && value.totalBytes > 0
|
|
50
|
+
&& Number.isFinite(value.availableBytes) && value.availableBytes >= 0 && value.availableBytes <= value.totalBytes) {
|
|
51
|
+
memory = { ...value };
|
|
52
|
+
if (value.swapTotalBytes === null || value.swapFreeBytes === null
|
|
53
|
+
|| !Number.isFinite(value.swapTotalBytes) || !Number.isFinite(value.swapFreeBytes)
|
|
54
|
+
|| value.swapTotalBytes < 0 || value.swapFreeBytes < 0 || value.swapFreeBytes > value.swapTotalBytes) {
|
|
55
|
+
memory.swapTotalBytes = memory.swapFreeBytes = null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch { /* Unavailable data slows admissions; it cannot deadlock the fleet. */ }
|
|
60
|
+
let level = "unknown";
|
|
61
|
+
if (memory) {
|
|
62
|
+
const critical = Math.max(this.options.criticalBytes ?? 300 * MiB, memory.totalBytes * 0.02);
|
|
63
|
+
const low = Math.max(critical * 2, memory.totalBytes * 0.05);
|
|
64
|
+
const swapRatio = memory.swapTotalBytes && memory.swapFreeBytes !== null
|
|
65
|
+
? memory.swapFreeBytes / memory.swapTotalBytes : null;
|
|
66
|
+
const swapTight = swapRatio !== null && swapRatio <= 0.05;
|
|
67
|
+
const criticalNow = memory.availableKind === "available"
|
|
68
|
+
&& (memory.availableBytes < critical || (memory.availableBytes < low && swapTight));
|
|
69
|
+
// MemFree alone cannot distinguish healthy reclaimable cache from pressure.
|
|
70
|
+
// It can throttle, but must never impose an indefinite Linux procfs-failure hold.
|
|
71
|
+
if (criticalNow || (this.current.level === "critical"
|
|
72
|
+
&& memory.availableKind === "available" && memory.availableBytes < critical * 1.5)) {
|
|
73
|
+
level = "critical";
|
|
74
|
+
this.recoveryUntil = 0;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
if (this.current.level === "critical")
|
|
78
|
+
this.recoveryUntil = at + MEMORY_RECOVERY_MS;
|
|
79
|
+
const lingering = this.current.level === "elevated"
|
|
80
|
+
&& (memory.availableBytes < low * 1.2 || (swapRatio !== null && swapRatio <= 0.1));
|
|
81
|
+
level = memory.availableBytes < low || swapTight || lingering || at < this.recoveryUntil ? "elevated" : "normal";
|
|
82
|
+
}
|
|
83
|
+
const last = this.history.at(-1);
|
|
84
|
+
// Admission bursts must not fill history with near-identical microsecond samples.
|
|
85
|
+
if (!last || at - last.at >= MEMORY_SAMPLE_MS) {
|
|
86
|
+
this.history.push({ at, memory });
|
|
87
|
+
if (this.history.length > 12)
|
|
88
|
+
this.history.shift();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
this.history = [];
|
|
93
|
+
this.recoveryUntil = 0;
|
|
94
|
+
}
|
|
95
|
+
let trend = null;
|
|
96
|
+
const first = this.history[0];
|
|
97
|
+
const last = this.history.at(-1);
|
|
98
|
+
if (first && last && last.at - first.at >= 60_000 && first.memory.totalBytes === last.memory.totalBytes) {
|
|
99
|
+
const minutes = (last.at - first.at) / 60_000;
|
|
100
|
+
trend = {
|
|
101
|
+
availableBytesPerMinute: (last.memory.availableBytes - first.memory.availableBytes) / minutes,
|
|
102
|
+
swapFreeBytesPerMinute: first.memory.swapFreeBytes !== null && last.memory.swapFreeBytes !== null
|
|
103
|
+
&& first.memory.swapTotalBytes === last.memory.swapTotalBytes
|
|
104
|
+
? (last.memory.swapFreeBytes - first.memory.swapFreeBytes) / minutes : null,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
this.current = { level, memory, sampledAt: at, recovering: at < this.recoveryUntil, samples: this.history.length, trend };
|
|
108
|
+
if (this.timer) {
|
|
109
|
+
try {
|
|
110
|
+
this.options.onSample?.(this.snapshot());
|
|
111
|
+
}
|
|
112
|
+
catch { /* Diagnostics must not break admission or polling. */ }
|
|
113
|
+
}
|
|
114
|
+
return this.snapshot();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=memory-pressure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-pressure.js","sourceRoot":"","sources":["../src/memory-pressure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAmB,MAAM,kBAAkB,CAAC;AAoBnE,MAAM,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AACxB,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AACvC,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAEzC,uFAAuF;AACvF,MAAM,OAAO,cAAc;IAUI;IATZ,IAAI,CAAmB;IACvB,GAAG,CAAe;IAC3B,KAAK,GAA0C,IAAI,CAAC;IACpD,OAAO,GAA8C,EAAE,CAAC;IACxD,aAAa,GAAG,CAAC,CAAC;IAClB,OAAO,GAA2B;QACxC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI;KAC5F,CAAC;IAEF,YAA6B,UAAmB,EAAE;QAArB,YAAO,GAAP,OAAO,CAAc;QAChD,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,cAAc,CAAC;QAC3C,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACrC,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO;QACvB,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,gBAAgB,CAAC,CAAC;QAChE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QACrB,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,KAAK;YAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED,4EAA4E;IAC5E,mBAAmB;QACjB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,kBAAkB,CAAC;QACrD,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI;YAChD,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC7E,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAED,uEAAuE;IACvE,QAAQ;QACN,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;IAChJ,CAAC;IAED,MAAM;QACJ,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACtB,IAAI,MAAM,GAAsB,IAAI,CAAC;QACrC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC1B,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC;mBACxD,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,KAAK,CAAC,cAAc,IAAI,CAAC,IAAI,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;gBACpH,MAAM,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC;gBACtB,IAAI,KAAK,CAAC,cAAc,KAAK,IAAI,IAAI,KAAK,CAAC,aAAa,KAAK,IAAI;uBAC5D,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC;uBAC/E,KAAK,CAAC,cAAc,GAAG,CAAC,IAAI,KAAK,CAAC,aAAa,GAAG,CAAC,IAAI,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC,cAAc,EAAE,CAAC;oBACvG,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC,aAAa,GAAG,IAAI,CAAC;gBACtD,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,sEAAsE,CAAC,CAAC;QAElF,IAAI,KAAK,GAAwB,SAAS,CAAC;QAC3C,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI,GAAG,GAAG,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;YAC7F,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;YAC7D,MAAM,SAAS,GAAG,MAAM,CAAC,cAAc,IAAI,MAAM,CAAC,aAAa,KAAK,IAAI;gBACtE,CAAC,CAAC,MAAM,CAAC,aAAa,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC;YACxD,MAAM,SAAS,GAAG,SAAS,KAAK,IAAI,IAAI,SAAS,IAAI,IAAI,CAAC;YAC1D,MAAM,WAAW,GAAG,MAAM,CAAC,aAAa,KAAK,WAAW;mBACnD,CAAC,MAAM,CAAC,cAAc,GAAG,QAAQ,IAAI,CAAC,MAAM,CAAC,cAAc,GAAG,GAAG,IAAI,SAAS,CAAC,CAAC,CAAC;YACtF,4EAA4E;YAC5E,kFAAkF;YAClF,IAAI,WAAW,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,UAAU;mBAChD,MAAM,CAAC,aAAa,KAAK,WAAW,IAAI,MAAM,CAAC,cAAc,GAAG,QAAQ,GAAG,GAAG,CAAC,EAAE,CAAC;gBACrF,KAAK,GAAG,UAAU,CAAC;gBACnB,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;YACzB,CAAC;iBAAM,CAAC;gBACN,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,UAAU;oBAAE,IAAI,CAAC,aAAa,GAAG,EAAE,GAAG,kBAAkB,CAAC;gBACpF,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,UAAU;uBAC9C,CAAC,MAAM,CAAC,cAAc,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,SAAS,IAAI,GAAG,CAAC,CAAC,CAAC;gBACrF,KAAK,GAAG,MAAM,CAAC,cAAc,GAAG,GAAG,IAAI,SAAS,IAAI,SAAS,IAAI,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC;YACnH,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACjC,kFAAkF;YAClF,IAAI,CAAC,IAAI,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE,IAAI,gBAAgB,EAAE,CAAC;gBAC9C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;gBAClC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,EAAE;oBAAE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACrD,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;YAClB,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;QACzB,CAAC;QACD,IAAI,KAAK,GAAoC,IAAI,CAAC;QAClD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACjC,IAAI,KAAK,IAAI,IAAI,IAAI,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE,IAAI,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,UAAU,KAAK,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YACxG,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC;YAC9C,KAAK,GAAG;gBACN,uBAAuB,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,OAAO;gBAC7F,sBAAsB,EAAE,KAAK,CAAC,MAAM,CAAC,aAAa,KAAK,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,KAAK,IAAI;uBAC5F,KAAK,CAAC,MAAM,CAAC,cAAc,KAAK,IAAI,CAAC,MAAM,CAAC,cAAc;oBAC7D,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI;aAC9E,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,GAAG,IAAI,CAAC,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;QAC1H,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC;gBAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,sDAAsD,CAAC,CAAC;QACpH,CAAC;QACD,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;CACF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** A caller can time out before its isolate has actually stopped. */
|
|
2
|
+
export interface ProbeWorker<T> {
|
|
3
|
+
promise: Promise<T | null>;
|
|
4
|
+
stopped: Promise<void>;
|
|
5
|
+
terminate(): void;
|
|
6
|
+
}
|
|
7
|
+
/** Shared admission limit, including workers still completing termination. */
|
|
8
|
+
export declare class ProbeWorkerPool {
|
|
9
|
+
private readonly concurrency;
|
|
10
|
+
private queued;
|
|
11
|
+
private active;
|
|
12
|
+
private activeKeys;
|
|
13
|
+
private closed;
|
|
14
|
+
constructor(concurrency?: number);
|
|
15
|
+
run<T>(key: string, start: () => ProbeWorker<T>, options: {
|
|
16
|
+
deadlineMs: number;
|
|
17
|
+
onTimeout?: () => void;
|
|
18
|
+
onError?: (error: unknown) => void;
|
|
19
|
+
}): Promise<T | null>;
|
|
20
|
+
close(): void;
|
|
21
|
+
/** Restart keeps old physical reservations until those isolates stop. */
|
|
22
|
+
reopen(): void;
|
|
23
|
+
private expire;
|
|
24
|
+
private cancel;
|
|
25
|
+
private settle;
|
|
26
|
+
private release;
|
|
27
|
+
private pump;
|
|
28
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/** Shared admission limit, including workers still completing termination. */
|
|
2
|
+
export class ProbeWorkerPool {
|
|
3
|
+
concurrency;
|
|
4
|
+
queued = [];
|
|
5
|
+
active = new Set();
|
|
6
|
+
activeKeys = new Set();
|
|
7
|
+
closed = false;
|
|
8
|
+
constructor(concurrency = 2) {
|
|
9
|
+
this.concurrency = concurrency;
|
|
10
|
+
}
|
|
11
|
+
run(key, start, options) {
|
|
12
|
+
if (this.closed)
|
|
13
|
+
return Promise.resolve(null);
|
|
14
|
+
return new Promise(resolve => {
|
|
15
|
+
const job = { key, start, resolve: value => resolve(value),
|
|
16
|
+
onTimeout: options.onTimeout, onError: options.onError, settled: false,
|
|
17
|
+
deadlineAt: performance.now() + options.deadlineMs };
|
|
18
|
+
// Includes queue time: commands retain their existing response deadline.
|
|
19
|
+
job.timer = setTimeout(() => {
|
|
20
|
+
this.expire(job);
|
|
21
|
+
this.pump();
|
|
22
|
+
}, options.deadlineMs);
|
|
23
|
+
this.queued.push(job);
|
|
24
|
+
this.pump();
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
close() {
|
|
28
|
+
this.closed = true;
|
|
29
|
+
for (const job of [...this.queued, ...this.active]) {
|
|
30
|
+
this.settle(job, null);
|
|
31
|
+
this.cancel(job);
|
|
32
|
+
}
|
|
33
|
+
this.queued = [];
|
|
34
|
+
}
|
|
35
|
+
/** Restart keeps old physical reservations until those isolates stop. */
|
|
36
|
+
reopen() { this.closed = false; }
|
|
37
|
+
expire(job) {
|
|
38
|
+
if (job.settled)
|
|
39
|
+
return;
|
|
40
|
+
this.settle(job, null);
|
|
41
|
+
try {
|
|
42
|
+
job.onTimeout?.();
|
|
43
|
+
}
|
|
44
|
+
catch { /* logging must not break cancellation */ }
|
|
45
|
+
this.cancel(job);
|
|
46
|
+
}
|
|
47
|
+
cancel(job) {
|
|
48
|
+
try {
|
|
49
|
+
job.handle?.terminate();
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
try {
|
|
53
|
+
job.onError?.(error);
|
|
54
|
+
}
|
|
55
|
+
catch { /* keep the occupied slot */ }
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
settle(job, result) {
|
|
59
|
+
if (job.settled)
|
|
60
|
+
return;
|
|
61
|
+
job.settled = true;
|
|
62
|
+
clearTimeout(job.timer);
|
|
63
|
+
job.resolve(result);
|
|
64
|
+
}
|
|
65
|
+
release(job) {
|
|
66
|
+
if (!this.active.delete(job))
|
|
67
|
+
return;
|
|
68
|
+
this.activeKeys.delete(job.key);
|
|
69
|
+
this.pump();
|
|
70
|
+
}
|
|
71
|
+
pump() {
|
|
72
|
+
this.queued = this.queued.filter(job => {
|
|
73
|
+
// Releasing a worker can run between two due timer callbacks. Recheck
|
|
74
|
+
// the clock so an already-expired queued job is never briefly spawned.
|
|
75
|
+
if (!job.settled && performance.now() >= job.deadlineAt)
|
|
76
|
+
this.expire(job);
|
|
77
|
+
return !job.settled;
|
|
78
|
+
});
|
|
79
|
+
while (!this.closed && this.active.size < this.concurrency) {
|
|
80
|
+
// Ordinary/vendor flights remain distinct, but never write the same
|
|
81
|
+
// backend's account cache concurrently. Other backends can progress.
|
|
82
|
+
const index = this.queued.findIndex(job => !this.activeKeys.has(job.key));
|
|
83
|
+
if (index < 0)
|
|
84
|
+
return;
|
|
85
|
+
const job = this.queued.splice(index, 1)[0];
|
|
86
|
+
// An earlier constructor can consume the remaining time before failing.
|
|
87
|
+
// Recheck every admission even if its deadline timer has not run yet.
|
|
88
|
+
if (performance.now() >= job.deadlineAt) {
|
|
89
|
+
this.expire(job);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
this.active.add(job);
|
|
93
|
+
this.activeKeys.add(job.key);
|
|
94
|
+
try {
|
|
95
|
+
const handle = job.handle = job.start();
|
|
96
|
+
handle.promise.then(value => {
|
|
97
|
+
if (performance.now() >= job.deadlineAt)
|
|
98
|
+
this.expire(job);
|
|
99
|
+
else
|
|
100
|
+
this.settle(job, value);
|
|
101
|
+
}, error => {
|
|
102
|
+
try {
|
|
103
|
+
job.onError?.(error);
|
|
104
|
+
}
|
|
105
|
+
catch { /* diagnostics are best effort */ }
|
|
106
|
+
this.settle(job, null);
|
|
107
|
+
this.cancel(job);
|
|
108
|
+
});
|
|
109
|
+
// A timed-out result does NOT free the physical worker slot.
|
|
110
|
+
handle.stopped.then(() => this.release(job), error => {
|
|
111
|
+
try {
|
|
112
|
+
job.onError?.(error);
|
|
113
|
+
}
|
|
114
|
+
catch { /* keep the occupied slot */ }
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
try {
|
|
119
|
+
job.onError?.(error);
|
|
120
|
+
}
|
|
121
|
+
catch { /* diagnostics are best effort */ }
|
|
122
|
+
this.settle(job, null);
|
|
123
|
+
this.active.delete(job);
|
|
124
|
+
this.activeKeys.delete(job.key);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=probe-worker-pool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe-worker-pool.js","sourceRoot":"","sources":["../src/probe-worker-pool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type HostMemory } from "./host-memory.js";
|
|
2
|
+
export { readHostMemory, type HostMemory } from "./host-memory.js";
|
|
3
|
+
export interface DirectoryUsage {
|
|
4
|
+
path: string;
|
|
5
|
+
names: string[];
|
|
6
|
+
bytes: number | null;
|
|
7
|
+
}
|
|
8
|
+
export interface ResourceReport {
|
|
9
|
+
memory: HostMemory;
|
|
10
|
+
workspaces: DirectoryUsage[];
|
|
11
|
+
/** null means classification is unavailable, not that there are no unregistered directories. */
|
|
12
|
+
orphans: DirectoryUsage[] | null;
|
|
13
|
+
notes: string[];
|
|
14
|
+
}
|
|
15
|
+
interface ResourceDeps {
|
|
16
|
+
memory: () => HostMemory;
|
|
17
|
+
diskUsage: (path: string, timeoutMs: number) => Promise<number | null>;
|
|
18
|
+
now: () => number;
|
|
19
|
+
budgetMs: number;
|
|
20
|
+
}
|
|
21
|
+
/** Allocated disk space. No shell, no descendant symlink traversal; kill slow scans. */
|
|
22
|
+
export declare function probeDiskUsage(path: string, timeoutMs: number, binary?: string): Promise<number | null>;
|
|
23
|
+
/** A bounded, read-only snapshot. Shared directories are measured once, never summed twice. */
|
|
24
|
+
export declare function collectResourceReport(dataDir: string, overrides?: Partial<ResourceDeps>): Promise<ResourceReport>;
|
|
25
|
+
export declare function formatResourceBytes(bytes: number): string;
|
|
26
|
+
export declare function resourceChecks(report: ResourceReport): Array<{
|
|
27
|
+
status: "ok" | "warn";
|
|
28
|
+
label: string;
|
|
29
|
+
detail: string;
|
|
30
|
+
}>;
|
|
31
|
+
export declare function formatResourceReport(report: ResourceReport): string;
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { readdir, realpath } from "node:fs/promises";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
|
+
import { execFile } from "node:child_process";
|
|
5
|
+
import yaml from "js-yaml";
|
|
6
|
+
import { classicInstanceName } from "./classic-channel-manager.js";
|
|
7
|
+
import { sanitizeInstanceName } from "./topic-commands.js";
|
|
8
|
+
import { t } from "./locale.js";
|
|
9
|
+
import { readHostMemory } from "./host-memory.js";
|
|
10
|
+
export { readHostMemory } from "./host-memory.js";
|
|
11
|
+
/** Allocated disk space. No shell, no descendant symlink traversal; kill slow scans. */
|
|
12
|
+
export function probeDiskUsage(path, timeoutMs, binary = "du") {
|
|
13
|
+
return new Promise(resolveResult => {
|
|
14
|
+
execFile(binary, ["-sk", "-x", path], {
|
|
15
|
+
encoding: "utf8", timeout: Math.max(1, Math.floor(timeoutMs)), killSignal: "SIGKILL", maxBuffer: 64 * 1024,
|
|
16
|
+
}, (err, stdout) => {
|
|
17
|
+
// du can print a partial total and still fail (permissions / concurrent removal).
|
|
18
|
+
if (err) {
|
|
19
|
+
resolveResult(null);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const match = stdout.match(/^(\d+)\s/);
|
|
23
|
+
const bytes = match ? Number(match[1]) * 1024 : NaN;
|
|
24
|
+
resolveResult(Number.isSafeInteger(bytes) ? bytes : null);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
function mapping(value) {
|
|
29
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
30
|
+
}
|
|
31
|
+
function readRegistry(path, optional) {
|
|
32
|
+
let text;
|
|
33
|
+
try {
|
|
34
|
+
text = readFileSync(path, "utf8");
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
if (optional && err.code === "ENOENT")
|
|
38
|
+
return { raw: {}, text: null };
|
|
39
|
+
throw err;
|
|
40
|
+
}
|
|
41
|
+
// Same ID-preserving parse as loadRawFleetConfig, without loadFleetConfig's mkdir/git-init.
|
|
42
|
+
const parsed = yaml.load(text.replace(/(?<=:\s+|[-]\s+)(\d{16,})(?=\s*$)/gm, (_, id) => `"${id}"`));
|
|
43
|
+
if (parsed != null && !mapping(parsed))
|
|
44
|
+
throw new Error("invalid registry");
|
|
45
|
+
return { raw: parsed ?? {}, text };
|
|
46
|
+
}
|
|
47
|
+
/** A bounded, read-only snapshot. Shared directories are measured once, never summed twice. */
|
|
48
|
+
export async function collectResourceReport(dataDir, overrides = {}) {
|
|
49
|
+
const deps = { memory: readHostMemory, diskUsage: probeDiskUsage, now: () => performance.now(), budgetMs: 5_000, ...overrides };
|
|
50
|
+
const deadline = deps.now() + deps.budgetMs;
|
|
51
|
+
const report = { memory: deps.memory(), workspaces: [], orphans: null, notes: [] };
|
|
52
|
+
const known = new Set();
|
|
53
|
+
const candidates = new Map();
|
|
54
|
+
const addWorkspace = (path, name) => {
|
|
55
|
+
const absolute = resolve(path);
|
|
56
|
+
const names = candidates.get(absolute) ?? new Set();
|
|
57
|
+
if (name)
|
|
58
|
+
names.add(name);
|
|
59
|
+
candidates.set(absolute, names);
|
|
60
|
+
};
|
|
61
|
+
const snapshots = [];
|
|
62
|
+
let registryComplete = true;
|
|
63
|
+
let fleet = {};
|
|
64
|
+
for (const [filename, optional] of [["fleet.yaml", false], ["classicBot.yaml", true]]) {
|
|
65
|
+
const path = join(dataDir, filename);
|
|
66
|
+
try {
|
|
67
|
+
const snapshot = readRegistry(path, optional);
|
|
68
|
+
snapshots.push({ path, text: snapshot.text });
|
|
69
|
+
const raw = snapshot.raw;
|
|
70
|
+
const entries = raw[filename === "fleet.yaml" ? "instances" : "channels"] ?? {};
|
|
71
|
+
if (!mapping(entries) || Object.values(entries).some(entry => !mapping(entry)))
|
|
72
|
+
throw new Error("invalid entries");
|
|
73
|
+
if (filename === "fleet.yaml") {
|
|
74
|
+
fleet = raw;
|
|
75
|
+
for (const [name, config] of Object.entries(entries)) {
|
|
76
|
+
known.add(name);
|
|
77
|
+
const workDir = config.working_directory ?? raw.defaults?.working_directory;
|
|
78
|
+
if (workDir != null && typeof workDir !== "string")
|
|
79
|
+
throw new Error("invalid workspace");
|
|
80
|
+
addWorkspace(workDir || join(dataDir, "workspaces", name), name);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
const firstChannel = Array.isArray(fleet.channels) && fleet.channels.length > 0 ? fleet.channels[0] : fleet.channel;
|
|
85
|
+
const primaryAdapter = firstChannel?.id ?? firstChannel?.type;
|
|
86
|
+
for (const [key, entry] of Object.entries(entries)) {
|
|
87
|
+
const channelId = entry.channelId ?? key;
|
|
88
|
+
if (typeof channelId !== "string" || (entry.name != null && typeof entry.name !== "string")
|
|
89
|
+
|| (entry.instanceName != null && typeof entry.instanceName !== "string")
|
|
90
|
+
|| (entry.adapterId != null && typeof entry.adapterId !== "string"))
|
|
91
|
+
throw new Error("invalid classic identity");
|
|
92
|
+
const adapterSuffix = entry.adapterId && entry.adapterId !== primaryAdapter ? entry.adapterId : undefined;
|
|
93
|
+
const name = entry.instanceName ?? classicInstanceName(sanitizeInstanceName(entry.name ?? channelId), channelId, adapterSuffix);
|
|
94
|
+
known.add(name);
|
|
95
|
+
addWorkspace(join(dataDir, "workspaces", name), name);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
registryComplete = false;
|
|
101
|
+
report.notes.push(t("resources.registry_unknown", filename));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Include retained managed workspaces, even when no configured instance uses them.
|
|
105
|
+
try {
|
|
106
|
+
for (const entry of await readdir(join(dataDir, "workspaces"), { withFileTypes: true })) {
|
|
107
|
+
if (entry.isDirectory())
|
|
108
|
+
addWorkspace(join(dataDir, "workspaces", entry.name));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
if (err.code !== "ENOENT")
|
|
113
|
+
report.notes.push(t("resources.scan_unknown", join(dataDir, "workspaces")));
|
|
114
|
+
}
|
|
115
|
+
const canonical = new Map();
|
|
116
|
+
for (const [path, names] of candidates) {
|
|
117
|
+
let key = path;
|
|
118
|
+
try {
|
|
119
|
+
key = await realpath(path);
|
|
120
|
+
}
|
|
121
|
+
catch { /* missing workspace remains visible as unknown */ }
|
|
122
|
+
const merged = canonical.get(key) ?? new Set();
|
|
123
|
+
for (const name of names)
|
|
124
|
+
merged.add(name);
|
|
125
|
+
canonical.set(key, merged);
|
|
126
|
+
}
|
|
127
|
+
report.workspaces = [...canonical].map(([path, names]) => ({ path, names: [...names].sort(), bytes: null })).sort((a, b) => a.path.localeCompare(b.path));
|
|
128
|
+
if (registryComplete) {
|
|
129
|
+
try {
|
|
130
|
+
report.orphans = (await readdir(join(dataDir, "instances"), { withFileTypes: true }))
|
|
131
|
+
.filter(entry => entry.isDirectory() && !known.has(entry.name))
|
|
132
|
+
.map(entry => ({ path: join(dataDir, "instances", entry.name), names: [entry.name], bytes: null }))
|
|
133
|
+
.sort((a, b) => a.path.localeCompare(b.path));
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
if (err.code === "ENOENT")
|
|
137
|
+
report.orphans = [];
|
|
138
|
+
else
|
|
139
|
+
report.notes.push(t("resources.scan_unknown", join(dataDir, "instances")));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Small retained state directories get a measurement before potentially large repos.
|
|
143
|
+
const rows = [...(report.orphans ?? []), ...report.workspaces];
|
|
144
|
+
let next = 0;
|
|
145
|
+
const worker = async () => {
|
|
146
|
+
while (next < rows.length) {
|
|
147
|
+
const row = rows[next++];
|
|
148
|
+
const remaining = deadline - deps.now();
|
|
149
|
+
if (remaining <= 0)
|
|
150
|
+
continue;
|
|
151
|
+
try {
|
|
152
|
+
row.bytes = await deps.diskUsage(row.path, Math.min(2_000, remaining));
|
|
153
|
+
}
|
|
154
|
+
catch { /* unknown, not zero */ }
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
await Promise.all([worker(), worker()]);
|
|
158
|
+
// A registry changed during the scan: do not present a stale orphan verdict.
|
|
159
|
+
for (const snapshot of snapshots) {
|
|
160
|
+
try {
|
|
161
|
+
if (readRegistry(snapshot.path, snapshot.text === null).text !== snapshot.text)
|
|
162
|
+
throw new Error("changed");
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
report.orphans = null;
|
|
166
|
+
report.notes.push(t("resources.registry_changed"));
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return report;
|
|
171
|
+
}
|
|
172
|
+
export function formatResourceBytes(bytes) {
|
|
173
|
+
const units = ["B", "KiB", "MiB", "GiB", "TiB"];
|
|
174
|
+
const index = Math.min(units.length - 1, Math.max(0, Math.floor(Math.log2(bytes || 1) / 10)));
|
|
175
|
+
return `${(bytes / 1024 ** index).toFixed(index === 0 ? 0 : 1)} ${units[index]}`;
|
|
176
|
+
}
|
|
177
|
+
// Filenames/config labels must not inject terminal control sequences into the report.
|
|
178
|
+
function display(value) {
|
|
179
|
+
return value.replace(/[\u0000-\u001f\u007f-\u009f]/g, char => `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}`);
|
|
180
|
+
}
|
|
181
|
+
export function resourceChecks(report) {
|
|
182
|
+
const size = (bytes) => bytes === null ? t("resources.size_unknown") : formatResourceBytes(bytes);
|
|
183
|
+
const memory = report.memory;
|
|
184
|
+
const checks = [{
|
|
185
|
+
status: "ok", label: t("resources.memory"),
|
|
186
|
+
detail: t(memory.availableKind === "available" ? "resources.memory_available" : "resources.memory_free", size(memory.availableBytes), size(memory.totalBytes)),
|
|
187
|
+
}, {
|
|
188
|
+
status: "ok", label: t("resources.swap"),
|
|
189
|
+
detail: memory.swapTotalBytes === null ? t("resources.swap_unknown") : t("resources.swap_free", size(memory.swapFreeBytes), size(memory.swapTotalBytes)),
|
|
190
|
+
}];
|
|
191
|
+
for (const row of report.workspaces)
|
|
192
|
+
checks.push({
|
|
193
|
+
status: row.bytes === null ? "warn" : "ok", label: `${t("resources.workspace")} ${display(row.path)}`,
|
|
194
|
+
detail: `${size(row.bytes)}${row.names.length ? ` (${row.names.map(display).join(", ")})` : ""}`,
|
|
195
|
+
});
|
|
196
|
+
checks.push({
|
|
197
|
+
status: report.orphans === null || report.orphans.length > 0 ? "warn" : "ok", label: t("resources.orphans"),
|
|
198
|
+
detail: report.orphans === null ? t("resources.orphans_unknown") : t("resources.orphans_count", report.orphans.length),
|
|
199
|
+
});
|
|
200
|
+
for (const row of report.orphans ?? [])
|
|
201
|
+
checks.push({ status: "warn", label: display(row.path), detail: size(row.bytes) });
|
|
202
|
+
for (const note of report.notes)
|
|
203
|
+
checks.push({ status: "warn", label: t("resources.note"), detail: display(note) });
|
|
204
|
+
return checks;
|
|
205
|
+
}
|
|
206
|
+
export function formatResourceReport(report) {
|
|
207
|
+
return ["", t("resources.title"), ...resourceChecks(report).map(check => ` ${check.status === "warn" ? "⚠" : "•"} ${check.label}: ${check.detail}`)].join("\n");
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=resource-report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-report.js","sourceRoot":"","sources":["../src/resource-report.ts"],"names":[],"mappings":"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"}
|