instar 0.24.5 → 0.24.7
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/cli.js +0 -0
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +82 -3
- package/dist/commands/server.js.map +1 -1
- package/dist/core/ResponseReviewGate.d.ts +182 -0
- package/dist/core/ResponseReviewGate.d.ts.map +1 -0
- package/dist/core/ResponseReviewGate.js +956 -0
- package/dist/core/ResponseReviewGate.js.map +1 -0
- package/dist/core/types.d.ts +41 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/lifeline/ServerSupervisor.d.ts.map +1 -1
- package/dist/lifeline/ServerSupervisor.js +16 -2
- package/dist/lifeline/ServerSupervisor.js.map +1 -1
- package/dist/lifeline/TelegramLifeline.d.ts.map +1 -1
- package/dist/lifeline/TelegramLifeline.js +14 -0
- package/dist/lifeline/TelegramLifeline.js.map +1 -1
- package/dist/monitoring/SessionMonitor.d.ts +8 -0
- package/dist/monitoring/SessionMonitor.d.ts.map +1 -1
- package/dist/monitoring/SessionMonitor.js +16 -0
- package/dist/monitoring/SessionMonitor.js.map +1 -1
- package/dist/monitoring/TelemetryCollector.d.ts +33 -0
- package/dist/monitoring/TelemetryCollector.d.ts.map +1 -1
- package/dist/monitoring/TelemetryCollector.js +35 -0
- package/dist/monitoring/TelemetryCollector.js.map +1 -1
- package/dist/monitoring/TriageOrchestrator.d.ts +9 -0
- package/dist/monitoring/TriageOrchestrator.d.ts.map +1 -1
- package/dist/monitoring/TriageOrchestrator.js +45 -1
- package/dist/monitoring/TriageOrchestrator.js.map +1 -1
- package/dist/tunnel/TunnelManager.d.ts +2 -0
- package/dist/tunnel/TunnelManager.d.ts.map +1 -1
- package/dist/tunnel/TunnelManager.js +45 -15
- package/dist/tunnel/TunnelManager.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +3 -3
- package/upgrades/0.24.5.md +19 -4
- package/upgrades/0.24.6.md +20 -0
- package/upgrades/0.24.7.md +24 -0
- package/upgrades/NEXT.md +35 -0
- /package/.claude/skills/secret-setup/{skill.md → SKILL.md} +0 -0
package/dist/cli.js
CHANGED
|
File without changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAyPH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAskCD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAqvFtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
|
package/dist/commands/server.js
CHANGED
|
@@ -48,6 +48,7 @@ import { SessionWatchdog } from '../monitoring/SessionWatchdog.js';
|
|
|
48
48
|
import { StallTriageNurse } from '../monitoring/StallTriageNurse.js';
|
|
49
49
|
import { TriageOrchestrator } from '../monitoring/TriageOrchestrator.js';
|
|
50
50
|
import { SessionMonitor } from '../monitoring/SessionMonitor.js';
|
|
51
|
+
import { SessionRecovery } from '../monitoring/SessionRecovery.js';
|
|
51
52
|
import { MultiMachineCoordinator } from '../core/MultiMachineCoordinator.js';
|
|
52
53
|
import { GitSyncManager } from '../core/GitSync.js';
|
|
53
54
|
import { ProjectMapper } from '../core/ProjectMapper.js';
|
|
@@ -1719,6 +1720,29 @@ export async function startServer(options) {
|
|
|
1719
1720
|
return { interventionsTotal: 0, interventionsByLevel: {}, recoveries: 0, sessionDeaths: 0, llmGateOverrides: 0 };
|
|
1720
1721
|
return watchdog.getStats(sinceMs);
|
|
1721
1722
|
},
|
|
1723
|
+
// Session recovery stats — lazy getter (declared later in scope via `let`)
|
|
1724
|
+
getRecoveryStats: (_sinceMs) => {
|
|
1725
|
+
return { attempts: { stall: 0, crash: 0, errorLoop: 0 }, successes: { stall: 0, crash: 0, errorLoop: 0 } };
|
|
1726
|
+
},
|
|
1727
|
+
// Triage orchestrator stats — lazy getter (declared later in scope via `let`)
|
|
1728
|
+
getTriageStats: (_sinceMs) => {
|
|
1729
|
+
return { activations: 0, heuristicResolutions: 0, llmResolutions: 0, failures: 0, actionCounts: {} };
|
|
1730
|
+
},
|
|
1731
|
+
// Notification batcher stats — lazy getter
|
|
1732
|
+
getNotificationStats: () => {
|
|
1733
|
+
if (!notificationBatcher)
|
|
1734
|
+
return { flushed: 0, suppressed: 0, summaryQueueSize: 0, digestQueueSize: 0 };
|
|
1735
|
+
const s = notificationBatcher.getStats();
|
|
1736
|
+
return { flushed: s.totalFlushed, suppressed: s.totalSuppressed, summaryQueueSize: s.summaryQueueSize, digestQueueSize: s.digestQueueSize };
|
|
1737
|
+
},
|
|
1738
|
+
// Process staleness stats — lazy getter
|
|
1739
|
+
getStalenessStats: () => {
|
|
1740
|
+
const pi = ProcessIntegrity.getInstance();
|
|
1741
|
+
if (!pi)
|
|
1742
|
+
return { versionMismatch: false, driftCount: 0 };
|
|
1743
|
+
const drifts = staleGuard.checkAll();
|
|
1744
|
+
return { versionMismatch: pi.versionMismatch, driftCount: drifts.length };
|
|
1745
|
+
},
|
|
1722
1746
|
});
|
|
1723
1747
|
telemetryHeartbeat.setCollector(collector);
|
|
1724
1748
|
console.log(pc.green(' Baseline telemetry collector wired'));
|
|
@@ -2450,6 +2474,42 @@ export async function startServer(options) {
|
|
|
2450
2474
|
};
|
|
2451
2475
|
console.log(pc.green(' Triage Orchestrator enabled (replaces Stall Triage Nurse for stall detection)'));
|
|
2452
2476
|
}
|
|
2477
|
+
// SessionRecovery — fast mechanical recovery (JSONL analysis, no LLM)
|
|
2478
|
+
let sessionRecovery;
|
|
2479
|
+
if (telegram) {
|
|
2480
|
+
sessionRecovery = new SessionRecovery({ enabled: true, projectDir: config.projectDir }, {
|
|
2481
|
+
isSessionAlive: (name) => sessionManager.isSessionAlive(name),
|
|
2482
|
+
getPanePid: (name) => {
|
|
2483
|
+
try {
|
|
2484
|
+
const tmux = detectTmuxPath();
|
|
2485
|
+
if (!tmux)
|
|
2486
|
+
return null;
|
|
2487
|
+
const pid = execFileSync(tmux, ['list-panes', '-t', `=${name}:`, '-F', '#{pane_pid}'], { encoding: 'utf-8', timeout: 5000 }).trim();
|
|
2488
|
+
return /^\d+$/.test(pid) ? parseInt(pid, 10) : null;
|
|
2489
|
+
}
|
|
2490
|
+
catch {
|
|
2491
|
+
return null;
|
|
2492
|
+
}
|
|
2493
|
+
},
|
|
2494
|
+
killSession: (name) => {
|
|
2495
|
+
try {
|
|
2496
|
+
const tmux = detectTmuxPath();
|
|
2497
|
+
if (!tmux)
|
|
2498
|
+
return;
|
|
2499
|
+
execFileSync(tmux, ['kill-session', '-t', `=${name}`], { encoding: 'utf-8' });
|
|
2500
|
+
}
|
|
2501
|
+
catch { /* may already be dead */ }
|
|
2502
|
+
},
|
|
2503
|
+
respawnSession: async (topicId, _sessionName, recoveryPrompt) => {
|
|
2504
|
+
const targetSession = telegram.getSessionForTopic(topicId);
|
|
2505
|
+
if (!targetSession)
|
|
2506
|
+
return;
|
|
2507
|
+
await respawnSessionForTopic(sessionManager, telegram, targetSession, topicId, undefined, topicMemory, undefined, recoveryPrompt, { silent: true });
|
|
2508
|
+
},
|
|
2509
|
+
sendToTopic: async (topicId, message) => { await telegram.sendToTopic(topicId, message); },
|
|
2510
|
+
});
|
|
2511
|
+
console.log(pc.green(' Session Recovery enabled (mechanical fast-path)'));
|
|
2512
|
+
}
|
|
2453
2513
|
// SessionMonitor — proactive session health monitoring
|
|
2454
2514
|
let sessionMonitor;
|
|
2455
2515
|
if (telegram) {
|
|
@@ -2478,6 +2538,7 @@ export async function startServer(options) {
|
|
|
2478
2538
|
return { resolved: result.resolved };
|
|
2479
2539
|
}
|
|
2480
2540
|
: undefined,
|
|
2541
|
+
sessionRecovery,
|
|
2481
2542
|
}, config.monitoring.sessionMonitor);
|
|
2482
2543
|
sessionMonitor.start();
|
|
2483
2544
|
console.log(pc.green(' Session Monitor enabled'));
|
|
@@ -2799,14 +2860,16 @@ export async function startServer(options) {
|
|
|
2799
2860
|
catch {
|
|
2800
2861
|
console.warn('[SleepWake] tmux check failed after wake');
|
|
2801
2862
|
}
|
|
2802
|
-
// Restart tunnel if configured —
|
|
2803
|
-
//
|
|
2804
|
-
//
|
|
2863
|
+
// Restart tunnel if configured — disable auto-reconnect first to prevent
|
|
2864
|
+
// a cascade of competing reconnection attempts, then forceStop to handle
|
|
2865
|
+
// zombie cloudflared processes that may be hung after sleep.
|
|
2805
2866
|
if (tunnel) {
|
|
2806
2867
|
try {
|
|
2807
2868
|
await Promise.race([
|
|
2808
2869
|
(async () => {
|
|
2870
|
+
tunnel.disableAutoReconnect();
|
|
2809
2871
|
await tunnel.forceStop(5000);
|
|
2872
|
+
tunnel.enableAutoReconnect();
|
|
2810
2873
|
const tunnelUrl = await tunnel.start();
|
|
2811
2874
|
console.log(`[SleepWake] Tunnel restarted: ${tunnelUrl}`);
|
|
2812
2875
|
// Re-broadcast dashboard URL after tunnel restart (quick tunnels get new URL)
|
|
@@ -2820,6 +2883,8 @@ export async function startServer(options) {
|
|
|
2820
2883
|
}
|
|
2821
2884
|
catch (err) {
|
|
2822
2885
|
console.error(`[SleepWake] Tunnel restart failed:`, err);
|
|
2886
|
+
// Re-enable auto-reconnect even on failure so it can self-heal
|
|
2887
|
+
tunnel.enableAutoReconnect();
|
|
2823
2888
|
}
|
|
2824
2889
|
}
|
|
2825
2890
|
// Notify via batcher — wake events are informational, not urgent
|
|
@@ -3698,6 +3763,20 @@ export async function startServer(options) {
|
|
|
3698
3763
|
// the "mutex lock failed" error on next start. This doesn't prevent the crash,
|
|
3699
3764
|
// but ensures the next boot is clean.
|
|
3700
3765
|
process.on('uncaughtException', (err) => {
|
|
3766
|
+
// Non-fatal HTTP errors — log and continue, don't crash the server.
|
|
3767
|
+
// "Cannot set headers" is a double-response race condition (common during
|
|
3768
|
+
// tunnel reconnect storms). The affected request is already handled; the
|
|
3769
|
+
// server can keep serving new requests.
|
|
3770
|
+
const nonFatalPatterns = [
|
|
3771
|
+
'Cannot set headers after they are sent',
|
|
3772
|
+
'write after end',
|
|
3773
|
+
'ERR_HTTP_HEADERS_SENT',
|
|
3774
|
+
'ERR_STREAM_WRITE_AFTER_END',
|
|
3775
|
+
];
|
|
3776
|
+
if (nonFatalPatterns.some(p => err.message?.includes(p))) {
|
|
3777
|
+
console.warn(`[WARN] Non-fatal uncaught exception (suppressed): ${err.message}`);
|
|
3778
|
+
return; // Don't crash — the server is fine
|
|
3779
|
+
}
|
|
3701
3780
|
console.error('[FATAL] Uncaught exception — closing databases before crash:', err.message);
|
|
3702
3781
|
try {
|
|
3703
3782
|
topicMemory?.close();
|