@mcptoolshop/claude-guardian 1.1.0
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 +45 -0
- package/HANDBOOK.md +209 -0
- package/LICENSE +21 -0
- package/README.es.md +185 -0
- package/README.fr.md +185 -0
- package/README.hi.md +184 -0
- package/README.it.md +184 -0
- package/README.ja.md +185 -0
- package/README.md +184 -0
- package/README.pt-BR.md +184 -0
- package/README.zh.md +185 -0
- package/dist/budget-store.d.ts +33 -0
- package/dist/budget-store.js +62 -0
- package/dist/budget-store.js.map +1 -0
- package/dist/budget.d.ts +52 -0
- package/dist/budget.js +136 -0
- package/dist/budget.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +387 -0
- package/dist/cli.js.map +1 -0
- package/dist/defaults.d.ts +51 -0
- package/dist/defaults.js +67 -0
- package/dist/defaults.js.map +1 -0
- package/dist/doctor.d.ts +69 -0
- package/dist/doctor.js +294 -0
- package/dist/doctor.js.map +1 -0
- package/dist/errors.d.ts +21 -0
- package/dist/errors.js +46 -0
- package/dist/errors.js.map +1 -0
- package/dist/fs-utils.d.ts +23 -0
- package/dist/fs-utils.js +184 -0
- package/dist/fs-utils.js.map +1 -0
- package/dist/handle-count.d.ts +9 -0
- package/dist/handle-count.js +68 -0
- package/dist/handle-count.js.map +1 -0
- package/dist/incident.d.ts +33 -0
- package/dist/incident.js +115 -0
- package/dist/incident.js.map +1 -0
- package/dist/log-manager.d.ts +17 -0
- package/dist/log-manager.js +418 -0
- package/dist/log-manager.js.map +1 -0
- package/dist/mcp-server.d.ts +8 -0
- package/dist/mcp-server.js +503 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/process-monitor.d.ts +56 -0
- package/dist/process-monitor.js +214 -0
- package/dist/process-monitor.js.map +1 -0
- package/dist/recovery-plan.d.ts +22 -0
- package/dist/recovery-plan.js +146 -0
- package/dist/recovery-plan.js.map +1 -0
- package/dist/state.d.ts +64 -0
- package/dist/state.js +140 -0
- package/dist/state.js.map +1 -0
- package/dist/types.d.ts +64 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/watch-daemon.d.ts +7 -0
- package/dist/watch-daemon.js +162 -0
- package/dist/watch-daemon.js.map +1 -0
- package/dist/watchdog.d.ts +30 -0
- package/dist/watchdog.js +225 -0
- package/dist/watchdog.js.map +1 -0
- package/package.json +50 -0
package/dist/budget.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { RiskLevel } from './process-monitor.js';
|
|
2
|
+
import type { BudgetData, BudgetLease } from './budget-store.js';
|
|
3
|
+
/** Result of an acquire attempt. */
|
|
4
|
+
export interface AcquireResult {
|
|
5
|
+
granted: boolean;
|
|
6
|
+
lease: BudgetLease | null;
|
|
7
|
+
reason: string;
|
|
8
|
+
currentCap: number;
|
|
9
|
+
slotsInUse: number;
|
|
10
|
+
slotsAvailable: number;
|
|
11
|
+
}
|
|
12
|
+
/** Summary for display in status/banner. */
|
|
13
|
+
export interface BudgetSummary {
|
|
14
|
+
currentCap: number;
|
|
15
|
+
baseCap: number;
|
|
16
|
+
slotsInUse: number;
|
|
17
|
+
slotsAvailable: number;
|
|
18
|
+
activeLeases: number;
|
|
19
|
+
capSetByRisk: RiskLevel | null;
|
|
20
|
+
okSinceAt: string | null;
|
|
21
|
+
hysteresisRemainingSeconds: number;
|
|
22
|
+
}
|
|
23
|
+
/** Budget controller — manages cap transitions, leases, TTL expiry. */
|
|
24
|
+
export declare class Budget {
|
|
25
|
+
private data;
|
|
26
|
+
constructor(data: BudgetData);
|
|
27
|
+
/** Current effective cap. */
|
|
28
|
+
get currentCap(): number;
|
|
29
|
+
/** Slots currently held by active leases. */
|
|
30
|
+
get slotsInUse(): number;
|
|
31
|
+
/** Slots available for new leases. */
|
|
32
|
+
get slotsAvailable(): number;
|
|
33
|
+
/**
|
|
34
|
+
* Adjust cap based on current risk level. Returns true if cap changed.
|
|
35
|
+
*
|
|
36
|
+
* Rules:
|
|
37
|
+
* - ok: restore to baseCap after hysteresisSeconds sustained ok
|
|
38
|
+
* - warn: cap = warnCap (2)
|
|
39
|
+
* - critical: cap = criticalCap (1)
|
|
40
|
+
*/
|
|
41
|
+
adjustCap(riskLevel: RiskLevel, now?: number): boolean;
|
|
42
|
+
/** Acquire N slots with a TTL. */
|
|
43
|
+
acquire(n: number, ttlSeconds: number, reason: string): AcquireResult;
|
|
44
|
+
/** Release a lease by ID. Returns true if found and released. */
|
|
45
|
+
release(id: string): boolean;
|
|
46
|
+
/** Expire any leases past their TTL. Returns count of expired leases. */
|
|
47
|
+
expireLeases(now?: number): number;
|
|
48
|
+
/** Summary for display. */
|
|
49
|
+
summarize(now?: number): BudgetSummary;
|
|
50
|
+
/** Get the raw data for persistence. */
|
|
51
|
+
getData(): BudgetData;
|
|
52
|
+
}
|
package/dist/budget.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { randomUUID } from 'crypto';
|
|
2
|
+
import { BUDGET_THRESHOLDS } from './defaults.js';
|
|
3
|
+
/** Budget controller — manages cap transitions, leases, TTL expiry. */
|
|
4
|
+
export class Budget {
|
|
5
|
+
data;
|
|
6
|
+
constructor(data) {
|
|
7
|
+
// Deep copy to avoid external mutation
|
|
8
|
+
this.data = JSON.parse(JSON.stringify(data));
|
|
9
|
+
}
|
|
10
|
+
/** Current effective cap. */
|
|
11
|
+
get currentCap() {
|
|
12
|
+
return this.data.currentCap;
|
|
13
|
+
}
|
|
14
|
+
/** Slots currently held by active leases. */
|
|
15
|
+
get slotsInUse() {
|
|
16
|
+
return this.data.leases.reduce((sum, l) => sum + l.slots, 0);
|
|
17
|
+
}
|
|
18
|
+
/** Slots available for new leases. */
|
|
19
|
+
get slotsAvailable() {
|
|
20
|
+
return Math.max(0, this.data.currentCap - this.slotsInUse);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Adjust cap based on current risk level. Returns true if cap changed.
|
|
24
|
+
*
|
|
25
|
+
* Rules:
|
|
26
|
+
* - ok: restore to baseCap after hysteresisSeconds sustained ok
|
|
27
|
+
* - warn: cap = warnCap (2)
|
|
28
|
+
* - critical: cap = criticalCap (1)
|
|
29
|
+
*/
|
|
30
|
+
adjustCap(riskLevel, now = Date.now()) {
|
|
31
|
+
const oldCap = this.data.currentCap;
|
|
32
|
+
if (riskLevel === 'critical') {
|
|
33
|
+
this.data.currentCap = BUDGET_THRESHOLDS.criticalCap;
|
|
34
|
+
this.data.okSinceAt = null;
|
|
35
|
+
this.data.capSetByRisk = 'critical';
|
|
36
|
+
}
|
|
37
|
+
else if (riskLevel === 'warn') {
|
|
38
|
+
this.data.currentCap = BUDGET_THRESHOLDS.warnCap;
|
|
39
|
+
this.data.okSinceAt = null;
|
|
40
|
+
this.data.capSetByRisk = 'warn';
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
// ok — start or continue hysteresis timer
|
|
44
|
+
if (this.data.okSinceAt === null) {
|
|
45
|
+
this.data.okSinceAt = new Date(now).toISOString();
|
|
46
|
+
}
|
|
47
|
+
const okDuration = (now - new Date(this.data.okSinceAt).getTime()) / 1000;
|
|
48
|
+
if (okDuration >= BUDGET_THRESHOLDS.hysteresisSeconds) {
|
|
49
|
+
this.data.currentCap = this.data.baseCap;
|
|
50
|
+
this.data.capSetByRisk = null;
|
|
51
|
+
}
|
|
52
|
+
// Otherwise cap stays where it is until hysteresis expires
|
|
53
|
+
}
|
|
54
|
+
if (this.data.currentCap !== oldCap) {
|
|
55
|
+
this.data.capChangedAt = new Date(now).toISOString();
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
/** Acquire N slots with a TTL. */
|
|
61
|
+
acquire(n, ttlSeconds, reason) {
|
|
62
|
+
const base = {
|
|
63
|
+
currentCap: this.data.currentCap,
|
|
64
|
+
slotsInUse: this.slotsInUse,
|
|
65
|
+
slotsAvailable: this.slotsAvailable,
|
|
66
|
+
};
|
|
67
|
+
if (n <= 0) {
|
|
68
|
+
return { granted: false, lease: null, reason: 'Slots must be > 0', ...base };
|
|
69
|
+
}
|
|
70
|
+
if (ttlSeconds <= 0) {
|
|
71
|
+
return { granted: false, lease: null, reason: 'TTL must be > 0', ...base };
|
|
72
|
+
}
|
|
73
|
+
if (n > this.slotsAvailable) {
|
|
74
|
+
return {
|
|
75
|
+
granted: false,
|
|
76
|
+
lease: null,
|
|
77
|
+
reason: `Requested ${n} slots but only ${this.slotsAvailable} available (cap=${this.data.currentCap}, in-use=${this.slotsInUse})`,
|
|
78
|
+
...base,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
const now = new Date();
|
|
82
|
+
const lease = {
|
|
83
|
+
id: randomUUID().slice(0, 8),
|
|
84
|
+
slots: n,
|
|
85
|
+
reason,
|
|
86
|
+
grantedAt: now.toISOString(),
|
|
87
|
+
expiresAt: new Date(now.getTime() + ttlSeconds * 1000).toISOString(),
|
|
88
|
+
};
|
|
89
|
+
this.data.leases.push(lease);
|
|
90
|
+
return {
|
|
91
|
+
granted: true,
|
|
92
|
+
lease: { ...lease },
|
|
93
|
+
reason: 'Granted',
|
|
94
|
+
currentCap: this.data.currentCap,
|
|
95
|
+
slotsInUse: this.slotsInUse,
|
|
96
|
+
slotsAvailable: this.slotsAvailable,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/** Release a lease by ID. Returns true if found and released. */
|
|
100
|
+
release(id) {
|
|
101
|
+
const idx = this.data.leases.findIndex(l => l.id === id);
|
|
102
|
+
if (idx === -1)
|
|
103
|
+
return false;
|
|
104
|
+
this.data.leases.splice(idx, 1);
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
/** Expire any leases past their TTL. Returns count of expired leases. */
|
|
108
|
+
expireLeases(now = Date.now()) {
|
|
109
|
+
const before = this.data.leases.length;
|
|
110
|
+
this.data.leases = this.data.leases.filter(l => new Date(l.expiresAt).getTime() > now);
|
|
111
|
+
return before - this.data.leases.length;
|
|
112
|
+
}
|
|
113
|
+
/** Summary for display. */
|
|
114
|
+
summarize(now = Date.now()) {
|
|
115
|
+
let hysteresisRemaining = 0;
|
|
116
|
+
if (this.data.okSinceAt && this.data.currentCap < this.data.baseCap) {
|
|
117
|
+
const okDuration = (now - new Date(this.data.okSinceAt).getTime()) / 1000;
|
|
118
|
+
hysteresisRemaining = Math.max(0, Math.round(BUDGET_THRESHOLDS.hysteresisSeconds - okDuration));
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
currentCap: this.data.currentCap,
|
|
122
|
+
baseCap: this.data.baseCap,
|
|
123
|
+
slotsInUse: this.slotsInUse,
|
|
124
|
+
slotsAvailable: this.slotsAvailable,
|
|
125
|
+
activeLeases: this.data.leases.length,
|
|
126
|
+
capSetByRisk: this.data.capSetByRisk,
|
|
127
|
+
okSinceAt: this.data.okSinceAt,
|
|
128
|
+
hysteresisRemainingSeconds: hysteresisRemaining,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/** Get the raw data for persistence. */
|
|
132
|
+
getData() {
|
|
133
|
+
return JSON.parse(JSON.stringify(this.data));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../src/budget.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { scanLogs, fixLogs, formatPreflightReport, formatFixReport, healthBanner } from './log-manager.js';
|
|
4
|
+
import { generateBundle, formatDoctorReport } from './doctor.js';
|
|
5
|
+
import { Watchdog } from './watchdog.js';
|
|
6
|
+
import { startMcpServer, formatBanner } from './mcp-server.js';
|
|
7
|
+
import { startWatchDaemon } from './watch-daemon.js';
|
|
8
|
+
import { findClaudeProcesses, checkActivitySignals, assessHangRisk, recommendActions } from './process-monitor.js';
|
|
9
|
+
import { readState, isStateFresh, computeAttention } from './state.js';
|
|
10
|
+
import { getDiskFreeGB, bytesToMB, pathExists, dirSize } from './fs-utils.js';
|
|
11
|
+
import { DEFAULT_CONFIG, getClaudeProjectsPath } from './defaults.js';
|
|
12
|
+
import { Budget } from './budget.js';
|
|
13
|
+
import { readBudget, writeBudget, emptyBudget } from './budget-store.js';
|
|
14
|
+
import { GuardianError } from './errors.js';
|
|
15
|
+
import { homedir } from 'os';
|
|
16
|
+
/**
|
|
17
|
+
* Exit codes:
|
|
18
|
+
* 0 = success
|
|
19
|
+
* 1 = user error (bad arguments, missing input)
|
|
20
|
+
* 2 = runtime error (IO failure, unexpected crash)
|
|
21
|
+
* 3 = partial success (some actions failed)
|
|
22
|
+
*/
|
|
23
|
+
const program = new Command();
|
|
24
|
+
program
|
|
25
|
+
.name('claude-guardian')
|
|
26
|
+
.description('Flight computer for Claude Code — log rotation, watchdog, crash bundles, and MCP self-awareness')
|
|
27
|
+
.version('1.1.0')
|
|
28
|
+
.option('--debug', 'Print full stack traces on error', false);
|
|
29
|
+
// ─── preflight ───
|
|
30
|
+
program
|
|
31
|
+
.command('preflight')
|
|
32
|
+
.description('Scan Claude logs and report issues. Use --fix to auto-repair.')
|
|
33
|
+
.option('--fix', 'Automatically rotate/trim/compress oversized logs', false)
|
|
34
|
+
.option('--aggressive', 'Enable aggressive mode: shorter retention, lower thresholds', false)
|
|
35
|
+
.option('--max-log-mb <mb>', 'Max project log directory size in MB', String(DEFAULT_CONFIG.maxProjectLogDirMB))
|
|
36
|
+
.action(async (opts) => {
|
|
37
|
+
const config = {
|
|
38
|
+
...DEFAULT_CONFIG,
|
|
39
|
+
maxProjectLogDirMB: parseInt(opts.maxLogMb, 10),
|
|
40
|
+
};
|
|
41
|
+
console.log('Scanning Claude logs...\n');
|
|
42
|
+
const result = await scanLogs(config);
|
|
43
|
+
console.log(formatPreflightReport(result));
|
|
44
|
+
console.log('\n' + healthBanner(result));
|
|
45
|
+
if (opts.fix) {
|
|
46
|
+
console.log('\nApplying fixes...\n');
|
|
47
|
+
const actions = await fixLogs(config, opts.aggressive);
|
|
48
|
+
console.log(formatFixReport(actions));
|
|
49
|
+
}
|
|
50
|
+
else if (result.actions.length > 0) {
|
|
51
|
+
console.log('\nRun with --fix to auto-repair issues.');
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
// ─── doctor ───
|
|
55
|
+
program
|
|
56
|
+
.command('doctor')
|
|
57
|
+
.description('Generate a diagnostics bundle (zip) with system info, log tails, and action journal.')
|
|
58
|
+
.option('-o, --out <path>', 'Output path for the zip bundle')
|
|
59
|
+
.action(async (opts) => {
|
|
60
|
+
console.log('Generating diagnostics bundle...\n');
|
|
61
|
+
const bundle = await generateBundle(opts.out);
|
|
62
|
+
console.log(formatDoctorReport(bundle.summary));
|
|
63
|
+
console.log(`\nBundle saved: ${bundle.zipPath}`);
|
|
64
|
+
});
|
|
65
|
+
// ─── run ───
|
|
66
|
+
program
|
|
67
|
+
.command('run')
|
|
68
|
+
.description('Launch a command with watchdog monitoring. Captures bundles on crash/hang.')
|
|
69
|
+
.argument('<command...>', 'The command to run (e.g., "claude" or "node server.js")')
|
|
70
|
+
.option('--auto-restart', 'Automatically restart on crash/hang', DEFAULT_CONFIG.autoRestart)
|
|
71
|
+
.option('--hang-timeout <seconds>', 'Seconds of inactivity before declaring a hang', String(DEFAULT_CONFIG.hangNoActivitySeconds))
|
|
72
|
+
.option('--max-log-mb <mb>', 'Max project log directory size in MB', String(DEFAULT_CONFIG.maxProjectLogDirMB))
|
|
73
|
+
.action(async (commandParts, opts) => {
|
|
74
|
+
const config = {
|
|
75
|
+
maxProjectLogDirMB: parseInt(opts.maxLogMb, 10),
|
|
76
|
+
hangNoActivitySeconds: parseInt(opts.hangTimeout, 10),
|
|
77
|
+
autoRestart: opts.autoRestart,
|
|
78
|
+
};
|
|
79
|
+
// Run preflight first
|
|
80
|
+
console.log('[guardian] Running preflight check...');
|
|
81
|
+
const preflight = await scanLogs(config);
|
|
82
|
+
const banner = healthBanner(preflight);
|
|
83
|
+
console.log(`[guardian] ${banner}`);
|
|
84
|
+
if (preflight.diskFreeWarning) {
|
|
85
|
+
console.log('[guardian] WARNING: Low disk space. Running aggressive log cleanup...');
|
|
86
|
+
const actions = await fixLogs(config, true);
|
|
87
|
+
if (actions.length > 0) {
|
|
88
|
+
console.log(`[guardian] Cleaned up ${actions.length} items.`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Parse command
|
|
92
|
+
const cmd = commandParts[0];
|
|
93
|
+
const args = commandParts.slice(1);
|
|
94
|
+
console.log(`[guardian] Starting: ${commandParts.join(' ')}`);
|
|
95
|
+
console.log(`[guardian] Auto-restart: ${config.autoRestart}`);
|
|
96
|
+
console.log(`[guardian] Hang timeout: ${config.hangNoActivitySeconds}s`);
|
|
97
|
+
console.log('');
|
|
98
|
+
const watchdog = new Watchdog(cmd, args, config, (event, detail) => {
|
|
99
|
+
const timestamp = new Date().toISOString().substring(11, 19);
|
|
100
|
+
switch (event) {
|
|
101
|
+
case 'started':
|
|
102
|
+
console.log(`[guardian ${timestamp}] Started: ${detail}`);
|
|
103
|
+
break;
|
|
104
|
+
case 'hang-detected':
|
|
105
|
+
console.error(`[guardian ${timestamp}] HANG DETECTED: ${detail}`);
|
|
106
|
+
break;
|
|
107
|
+
case 'crash-detected':
|
|
108
|
+
console.error(`[guardian ${timestamp}] CRASH DETECTED: ${detail}`);
|
|
109
|
+
break;
|
|
110
|
+
case 'bundle-created':
|
|
111
|
+
console.log(`[guardian ${timestamp}] ${detail}`);
|
|
112
|
+
break;
|
|
113
|
+
case 'restarting':
|
|
114
|
+
console.log(`[guardian ${timestamp}] ${detail}`);
|
|
115
|
+
break;
|
|
116
|
+
case 'max-restarts':
|
|
117
|
+
console.error(`[guardian ${timestamp}] ${detail}`);
|
|
118
|
+
break;
|
|
119
|
+
case 'stopped':
|
|
120
|
+
console.log(`[guardian ${timestamp}] ${detail}`);
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
// Handle graceful shutdown
|
|
125
|
+
const shutdown = () => {
|
|
126
|
+
console.log('\n[guardian] Shutting down...');
|
|
127
|
+
watchdog.stop();
|
|
128
|
+
process.exit(0);
|
|
129
|
+
};
|
|
130
|
+
process.on('SIGINT', shutdown);
|
|
131
|
+
process.on('SIGTERM', shutdown);
|
|
132
|
+
watchdog.start();
|
|
133
|
+
});
|
|
134
|
+
// ─── watch ───
|
|
135
|
+
program
|
|
136
|
+
.command('watch')
|
|
137
|
+
.description('Run background daemon: monitor Claude Code processes, track health, persist state for MCP.')
|
|
138
|
+
.option('--hang-timeout <seconds>', 'Seconds of inactivity before warning', String(DEFAULT_CONFIG.hangNoActivitySeconds))
|
|
139
|
+
.option('--auto-fix', 'Auto-run preflight fixes when disk is low', false)
|
|
140
|
+
.option('--verbose', 'Print every poll cycle', false)
|
|
141
|
+
.action(async (opts) => {
|
|
142
|
+
await startWatchDaemon({
|
|
143
|
+
hangTimeoutSeconds: parseInt(opts.hangTimeout, 10),
|
|
144
|
+
autoFix: opts.autoFix,
|
|
145
|
+
verbose: opts.verbose,
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
// ─── status ───
|
|
149
|
+
program
|
|
150
|
+
.command('status')
|
|
151
|
+
.description('Show current health status: processes, hang risk, disk, logs.')
|
|
152
|
+
.option('--banner', 'Print a single-line banner (for embedding in prompts)', false)
|
|
153
|
+
.action(async (opts) => {
|
|
154
|
+
// Try daemon state first
|
|
155
|
+
const state = await readState();
|
|
156
|
+
if (state && isStateFresh(state)) {
|
|
157
|
+
if (opts.banner) {
|
|
158
|
+
console.log(formatBanner(state));
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
printFullStatus(state);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
// No daemon — build a live state snapshot
|
|
165
|
+
const diskFreeGB = await getDiskFreeGB(homedir());
|
|
166
|
+
const claudePath = getClaudeProjectsPath();
|
|
167
|
+
let claudeLogSizeMB = 0;
|
|
168
|
+
if (await pathExists(claudePath)) {
|
|
169
|
+
claudeLogSizeMB = bytesToMB(await dirSize(claudePath));
|
|
170
|
+
}
|
|
171
|
+
const processes = await findClaudeProcesses();
|
|
172
|
+
const activity = await checkActivitySignals(processes);
|
|
173
|
+
const hangRisk = assessHangRisk(processes, activity, diskFreeGB, DEFAULT_CONFIG.hangNoActivitySeconds, 0, // processAgeSeconds — unknown without daemon
|
|
174
|
+
0);
|
|
175
|
+
const actions = recommendActions(hangRisk);
|
|
176
|
+
const liveState = {
|
|
177
|
+
updatedAt: new Date().toISOString(),
|
|
178
|
+
daemonRunning: false,
|
|
179
|
+
daemonPid: null,
|
|
180
|
+
claudeProcesses: processes,
|
|
181
|
+
activity,
|
|
182
|
+
hangRisk,
|
|
183
|
+
recommendedActions: actions,
|
|
184
|
+
diskFreeGB: Math.round(diskFreeGB * 100) / 100,
|
|
185
|
+
claudeLogSizeMB,
|
|
186
|
+
activeIncident: null,
|
|
187
|
+
processAgeSeconds: 0,
|
|
188
|
+
compositeQuietSeconds: 0,
|
|
189
|
+
budgetSummary: null,
|
|
190
|
+
attention: computeAttention(hangRisk, null, null),
|
|
191
|
+
};
|
|
192
|
+
if (opts.banner) {
|
|
193
|
+
console.log(formatBanner(liveState));
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
printFullStatus(liveState);
|
|
197
|
+
// Also show log scan when no daemon
|
|
198
|
+
console.log('');
|
|
199
|
+
const result = await scanLogs();
|
|
200
|
+
console.log(formatPreflightReport(result));
|
|
201
|
+
console.log('\n' + healthBanner(result));
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
/** Print the full multi-line status from a GuardianState. */
|
|
205
|
+
function printFullStatus(state) {
|
|
206
|
+
if (state.daemonRunning) {
|
|
207
|
+
console.log(`[guardian] daemon=active | pid=${state.daemonPid}`);
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
console.log('[guardian] daemon=inactive (run `claude-guardian watch` to enable background monitoring)');
|
|
211
|
+
}
|
|
212
|
+
console.log(`[guardian] disk=${state.diskFreeGB}GB | logs=${state.claudeLogSizeMB}MB | risk=${state.hangRisk.level}`);
|
|
213
|
+
console.log('');
|
|
214
|
+
if (state.claudeProcesses.length > 0) {
|
|
215
|
+
console.log(`Claude processes: ${state.claudeProcesses.length}`);
|
|
216
|
+
for (const p of state.claudeProcesses) {
|
|
217
|
+
let line = ` PID ${p.pid} (${p.name}): CPU ${p.cpuPercent}% | RAM ${p.memoryMB}MB`;
|
|
218
|
+
if (p.handleCount != null) {
|
|
219
|
+
line += ` | handles=${p.handleCount}`;
|
|
220
|
+
}
|
|
221
|
+
line += ` | up ${fmtUptime(p.uptimeSeconds)}`;
|
|
222
|
+
console.log(line);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
console.log('Claude processes: none detected');
|
|
227
|
+
}
|
|
228
|
+
console.log('');
|
|
229
|
+
// Signals
|
|
230
|
+
console.log('Signals:');
|
|
231
|
+
console.log(` Log activity: ${state.activity.logLastModifiedSecondsAgo >= 0 ? state.activity.logLastModifiedSecondsAgo + 's ago' : 'unknown'}`);
|
|
232
|
+
console.log(` CPU active: ${state.activity.cpuActive ? 'yes' : 'no'}`);
|
|
233
|
+
if (state.hangRisk.graceRemainingSeconds > 0) {
|
|
234
|
+
console.log(` Grace remaining: ${state.hangRisk.graceRemainingSeconds}s`);
|
|
235
|
+
}
|
|
236
|
+
console.log(` Composite quiet: ${state.compositeQuietSeconds}s`);
|
|
237
|
+
console.log('');
|
|
238
|
+
console.log(`Hang risk: ${state.hangRisk.level.toUpperCase()}`);
|
|
239
|
+
if (state.hangRisk.reasons.length > 0) {
|
|
240
|
+
for (const r of state.hangRisk.reasons) {
|
|
241
|
+
console.log(` - ${r}`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
// Incident
|
|
245
|
+
if (state.activeIncident) {
|
|
246
|
+
console.log('');
|
|
247
|
+
console.log(`Incident: ${state.activeIncident.id} (${state.activeIncident.peakLevel}) — ${state.activeIncident.reason}`);
|
|
248
|
+
console.log(` Started: ${state.activeIncident.startedAt}`);
|
|
249
|
+
console.log(` Bundle captured: ${state.activeIncident.bundleCaptured ? 'yes' : 'no'}`);
|
|
250
|
+
if (state.activeIncident.bundlePath) {
|
|
251
|
+
console.log(` Bundle: ${state.activeIncident.bundlePath}`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
// Budget
|
|
255
|
+
if (state.budgetSummary) {
|
|
256
|
+
console.log('');
|
|
257
|
+
const b = state.budgetSummary;
|
|
258
|
+
console.log(`Budget: cap=${b.currentCap}/${b.baseCap} | in-use=${b.slotsInUse} | available=${b.slotsAvailable}`);
|
|
259
|
+
if (b.capSetByRisk) {
|
|
260
|
+
console.log(` Reduced by: ${b.capSetByRisk}`);
|
|
261
|
+
}
|
|
262
|
+
if (b.hysteresisRemainingSeconds > 0) {
|
|
263
|
+
console.log(` Recovery in: ${b.hysteresisRemainingSeconds}s`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
// Attention
|
|
267
|
+
console.log('');
|
|
268
|
+
console.log(`Attention: ${state.attention.level.toUpperCase()} — ${state.attention.reason}`);
|
|
269
|
+
if (state.attention.level !== 'none' && state.attention.recommendedActions.length > 0) {
|
|
270
|
+
for (const a of state.attention.recommendedActions) {
|
|
271
|
+
console.log(` - ${a}`);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
function fmtUptime(seconds) {
|
|
276
|
+
if (seconds < 60)
|
|
277
|
+
return `${seconds}s`;
|
|
278
|
+
const mins = Math.floor(seconds / 60);
|
|
279
|
+
const secs = seconds % 60;
|
|
280
|
+
if (mins < 60)
|
|
281
|
+
return `${mins}m ${secs}s`;
|
|
282
|
+
const hours = Math.floor(mins / 60);
|
|
283
|
+
const remMins = mins % 60;
|
|
284
|
+
return `${hours}h ${remMins}m`;
|
|
285
|
+
}
|
|
286
|
+
// ─── budget ───
|
|
287
|
+
const budgetCmd = program
|
|
288
|
+
.command('budget')
|
|
289
|
+
.description('View and manage the concurrency budget.');
|
|
290
|
+
budgetCmd
|
|
291
|
+
.command('show', { isDefault: true })
|
|
292
|
+
.description('Show current budget: cap, leases, availability.')
|
|
293
|
+
.action(async () => {
|
|
294
|
+
const data = await readBudget();
|
|
295
|
+
if (!data) {
|
|
296
|
+
console.log('[guardian] No budget state. Start the daemon or run `budget acquire` to initialize.');
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
const budget = new Budget(data);
|
|
300
|
+
budget.expireLeases();
|
|
301
|
+
const s = budget.summarize();
|
|
302
|
+
console.log(`Budget: cap=${s.currentCap}/${s.baseCap} | in-use=${s.slotsInUse} | available=${s.slotsAvailable}`);
|
|
303
|
+
console.log(`Active leases: ${s.activeLeases}`);
|
|
304
|
+
if (s.capSetByRisk) {
|
|
305
|
+
console.log(`Cap reduced by: ${s.capSetByRisk}`);
|
|
306
|
+
}
|
|
307
|
+
if (s.hysteresisRemainingSeconds > 0) {
|
|
308
|
+
console.log(`Recovery in: ${s.hysteresisRemainingSeconds}s`);
|
|
309
|
+
}
|
|
310
|
+
// Show individual leases
|
|
311
|
+
if (data.leases.length > 0) {
|
|
312
|
+
console.log('');
|
|
313
|
+
for (const l of data.leases) {
|
|
314
|
+
const expiresIn = Math.max(0, Math.round((new Date(l.expiresAt).getTime() - Date.now()) / 1000));
|
|
315
|
+
console.log(` ${l.id}: ${l.slots} slot(s) — "${l.reason}" (expires in ${expiresIn}s)`);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
budgetCmd
|
|
320
|
+
.command('acquire')
|
|
321
|
+
.description('Acquire concurrency slots.')
|
|
322
|
+
.argument('<slots>', 'Number of slots to acquire')
|
|
323
|
+
.option('--ttl <seconds>', 'Lease time-to-live in seconds', '60')
|
|
324
|
+
.option('--reason <text>', 'Reason for acquiring', 'manual')
|
|
325
|
+
.action(async (slotsStr, opts) => {
|
|
326
|
+
const data = await readBudget() ?? emptyBudget();
|
|
327
|
+
const budget = new Budget(data);
|
|
328
|
+
budget.expireLeases();
|
|
329
|
+
const result = budget.acquire(parseInt(slotsStr, 10), parseInt(opts.ttl, 10), opts.reason);
|
|
330
|
+
await writeBudget(budget.getData());
|
|
331
|
+
if (result.granted) {
|
|
332
|
+
console.log(`Lease granted: ${result.lease.id} (${result.lease.slots} slot(s), TTL ${opts.ttl}s)`);
|
|
333
|
+
console.log(`Budget: ${result.slotsInUse}/${result.currentCap} in use`);
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
console.error(`Denied: ${result.reason}`);
|
|
337
|
+
process.exitCode = 1;
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
budgetCmd
|
|
341
|
+
.command('release')
|
|
342
|
+
.description('Release a lease by ID.')
|
|
343
|
+
.argument('<id>', 'Lease ID to release')
|
|
344
|
+
.action(async (id) => {
|
|
345
|
+
const data = await readBudget();
|
|
346
|
+
if (!data) {
|
|
347
|
+
console.log('[guardian] No budget state.');
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
const budget = new Budget(data);
|
|
351
|
+
const released = budget.release(id);
|
|
352
|
+
await writeBudget(budget.getData());
|
|
353
|
+
console.log(released ? `Lease ${id} released.` : `Lease ${id} not found.`);
|
|
354
|
+
});
|
|
355
|
+
// ─── mcp ───
|
|
356
|
+
program
|
|
357
|
+
.command('mcp')
|
|
358
|
+
.description('Start the MCP server on stdio. Register in ~/.claude.json for Claude Code integration.')
|
|
359
|
+
.action(async () => {
|
|
360
|
+
await startMcpServer();
|
|
361
|
+
});
|
|
362
|
+
// ─── Global error handler ───
|
|
363
|
+
function handleFatalError(err) {
|
|
364
|
+
const debug = program.opts().debug;
|
|
365
|
+
if (err instanceof GuardianError) {
|
|
366
|
+
console.error(err.toCliText());
|
|
367
|
+
if (debug && err.cause?.stack) {
|
|
368
|
+
console.error('\nStack trace:');
|
|
369
|
+
console.error(err.cause.stack);
|
|
370
|
+
}
|
|
371
|
+
process.exit(2);
|
|
372
|
+
}
|
|
373
|
+
if (err instanceof Error) {
|
|
374
|
+
console.error(`[guardian] Error: ${err.message}`);
|
|
375
|
+
if (debug && err.stack) {
|
|
376
|
+
console.error('\nStack trace:');
|
|
377
|
+
console.error(err.stack);
|
|
378
|
+
}
|
|
379
|
+
process.exit(2);
|
|
380
|
+
}
|
|
381
|
+
console.error(`[guardian] Error: ${String(err)}`);
|
|
382
|
+
process.exit(2);
|
|
383
|
+
}
|
|
384
|
+
process.on('uncaughtException', handleFatalError);
|
|
385
|
+
process.on('unhandledRejection', handleFatalError);
|
|
386
|
+
program.parseAsync().catch(handleFatalError);
|
|
387
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { GuardianConfig } from './types.js';
|
|
2
|
+
/** The 3 user-facing knobs with sane defaults. */
|
|
3
|
+
export declare const DEFAULT_CONFIG: GuardianConfig;
|
|
4
|
+
/** Hardcoded thresholds — not user-configurable in v1. */
|
|
5
|
+
export declare const THRESHOLDS: {
|
|
6
|
+
/** Disk free below this triggers aggressive mode. */
|
|
7
|
+
readonly diskFreeWarningGB: 5;
|
|
8
|
+
/** Max single file size before trimming. */
|
|
9
|
+
readonly maxFileMB: 25;
|
|
10
|
+
/** How many days of logs to retain during rotation. */
|
|
11
|
+
readonly retainDays: 7;
|
|
12
|
+
/** Days before a session transcript is considered stale and eligible for cleanup. */
|
|
13
|
+
readonly staleSessionDays: 3;
|
|
14
|
+
/** Tail lines to include in doctor bundle per log file. */
|
|
15
|
+
readonly doctorTailLines: 500;
|
|
16
|
+
/** Watchdog poll interval in ms. */
|
|
17
|
+
readonly watchdogPollMs: 2000;
|
|
18
|
+
/** Restart backoff schedule in ms. */
|
|
19
|
+
readonly restartBackoffMs: readonly [2000, 5000, 15000, 60000];
|
|
20
|
+
/** Max restarts before giving up. */
|
|
21
|
+
readonly maxRestarts: 5;
|
|
22
|
+
/** Grace period after first discovering a PID — risk stays ok. */
|
|
23
|
+
readonly graceWindowSeconds: 60;
|
|
24
|
+
/** CPU below this % counts as "low" for hang detection. */
|
|
25
|
+
readonly cpuLowThreshold: 5;
|
|
26
|
+
/** After warn, escalate to critical after this many additional seconds. */
|
|
27
|
+
readonly criticalAfterSeconds: 600;
|
|
28
|
+
/** Rate limit: min seconds between bundles for the same PID. */
|
|
29
|
+
readonly bundleCooldownSeconds: 300;
|
|
30
|
+
};
|
|
31
|
+
/** Budget thresholds for concurrency control. */
|
|
32
|
+
export declare const BUDGET_THRESHOLDS: {
|
|
33
|
+
/** Maximum concurrency slots (base cap). */
|
|
34
|
+
readonly baseCap: 4;
|
|
35
|
+
/** Cap when risk = warn. */
|
|
36
|
+
readonly warnCap: 2;
|
|
37
|
+
/** Cap when risk = critical. */
|
|
38
|
+
readonly criticalCap: 1;
|
|
39
|
+
/** Seconds of sustained ok before restoring base cap. */
|
|
40
|
+
readonly hysteresisSeconds: 60;
|
|
41
|
+
};
|
|
42
|
+
/** Resolve the Claude projects directory. */
|
|
43
|
+
export declare function getClaudeProjectsPath(): string;
|
|
44
|
+
/** Resolve the guardian data directory. */
|
|
45
|
+
export declare function getGuardianDataPath(): string;
|
|
46
|
+
/** Resolve the journal file path. */
|
|
47
|
+
export declare function getJournalPath(): string;
|
|
48
|
+
/** Resolve the archive directory. */
|
|
49
|
+
export declare function getArchivePath(): string;
|
|
50
|
+
/** Resolve the budget file path. */
|
|
51
|
+
export declare function getBudgetPath(): string;
|