instar 0.28.16 → 0.28.18
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/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +104 -63
- package/dist/commands/server.js.map +1 -1
- package/dist/config/ConfigDefaults.d.ts.map +1 -1
- package/dist/config/ConfigDefaults.js +5 -0
- package/dist/config/ConfigDefaults.js.map +1 -1
- package/dist/core/Config.d.ts.map +1 -1
- package/dist/core/Config.js +4 -0
- package/dist/core/Config.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +2 -1
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/Prerequisites.d.ts.map +1 -1
- package/dist/core/Prerequisites.js +50 -1
- package/dist/core/Prerequisites.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +22 -0
- package/dist/server/routes.js.map +1 -1
- package/package.json +2 -3
- package/src/data/builtin-manifest.json +66 -66
- package/src/templates/hooks/compaction-recovery.sh +18 -0
- package/upgrades/0.28.16.md +27 -3
- package/upgrades/0.28.17.md +11 -0
- package/upgrades/0.28.18.md +12 -0
- package/upgrades/NEXT.md +35 -0
- package/.claude/settings.json +0 -211
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA2PH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA6zCD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA2PH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA6zCD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA2oItE;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
|
@@ -3727,58 +3727,82 @@ export async function startServer(options) {
|
|
|
3727
3727
|
const { HookEventReceiver } = await import('../monitoring/HookEventReceiver.js');
|
|
3728
3728
|
const hookEventReceiver = new HookEventReceiver({ stateDir: config.stateDir });
|
|
3729
3729
|
console.log(pc.green(' Hook event receiver enabled'));
|
|
3730
|
-
//
|
|
3731
|
-
//
|
|
3732
|
-
//
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3730
|
+
// ── Compaction Resume: unified recovery for one session ──────────────
|
|
3731
|
+
// Robust against subsystem misconfiguration: works with or without
|
|
3732
|
+
// triageOrchestrator. If the orchestrator is available we prefer it
|
|
3733
|
+
// (richer recovery semantics); otherwise we fall back to a direct
|
|
3734
|
+
// tmux re-injection of the unanswered user message.
|
|
3735
|
+
//
|
|
3736
|
+
// Three independent triggers call into this:
|
|
3737
|
+
// 1. PreCompact hook event (Claude Code fires it — unreliable)
|
|
3738
|
+
// 2. SessionWatchdog 'compaction-idle' polling (default-enabled)
|
|
3739
|
+
// 3. POST /internal/compaction-resume (compaction-recovery.sh hook)
|
|
3740
|
+
const recoverCompactedSession = async (sessionName, triggerLabel) => {
|
|
3741
|
+
if (!sessionManager.isSessionAlive(sessionName))
|
|
3742
|
+
return false;
|
|
3743
|
+
// Telegram path
|
|
3744
|
+
if (telegram) {
|
|
3745
|
+
const topicId = telegram.getTopicForSession(sessionName);
|
|
3746
|
+
if (topicId) {
|
|
3747
|
+
const history = telegram.getTopicHistory(topicId, 5);
|
|
3748
|
+
const lastMsg = history[history.length - 1];
|
|
3749
|
+
if (lastMsg?.fromUser) {
|
|
3750
|
+
console.log(`[CompactionResume] (${triggerLabel}) topic ${topicId} session "${sessionName}" has unanswered message — recovering`);
|
|
3751
|
+
if (triageOrchestrator) {
|
|
3752
|
+
try {
|
|
3753
|
+
await triageOrchestrator.activate(topicId, sessionName, 'watchdog', lastMsg.text, Date.now());
|
|
3754
|
+
return true;
|
|
3755
|
+
}
|
|
3756
|
+
catch (err) {
|
|
3757
|
+
console.warn(`[CompactionResume] orchestrator failed, falling back to direct inject:`, err);
|
|
3758
|
+
}
|
|
3750
3759
|
}
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
// don't fire (Claude Code doesn't reliably emit them). The watchdog polls
|
|
3758
|
-
// every 30s and detects sessions that compacted + are idle at a prompt.
|
|
3759
|
-
if (watchdog && triageOrchestrator) {
|
|
3760
|
-
const _triageOrch2 = triageOrchestrator;
|
|
3761
|
-
watchdog.on('compaction-idle', (sessionName) => {
|
|
3762
|
-
// Check Telegram topics
|
|
3763
|
-
if (telegram) {
|
|
3764
|
-
const topicId = telegram.getTopicForSession(sessionName);
|
|
3765
|
-
if (topicId) {
|
|
3766
|
-
const history = telegram.getTopicHistory(topicId, 5);
|
|
3767
|
-
const lastMsg = history[history.length - 1];
|
|
3768
|
-
if (lastMsg?.fromUser) {
|
|
3769
|
-
console.log(`[CompactionResume] Watchdog detected compaction-idle, topic ${topicId} has unanswered message — activating triage`);
|
|
3770
|
-
_triageOrch2.activate(topicId, sessionName, 'watchdog', lastMsg.text, Date.now()).catch(err => {
|
|
3771
|
-
console.warn(`[CompactionResume] Triage activation failed for topic ${topicId}:`, err);
|
|
3772
|
-
});
|
|
3773
|
-
return;
|
|
3760
|
+
// Fallback: direct injection with topic tag so InputGuard accepts it.
|
|
3761
|
+
const tagged = `[telegram:${topicId}] ${lastMsg.text}`;
|
|
3762
|
+
const ok = sessionManager.injectMessage(sessionName, tagged);
|
|
3763
|
+
if (ok) {
|
|
3764
|
+
console.log(`[CompactionResume] (${triggerLabel}) direct re-inject OK for topic ${topicId}`);
|
|
3765
|
+
return true;
|
|
3774
3766
|
}
|
|
3767
|
+
console.warn(`[CompactionResume] (${triggerLabel}) direct re-inject FAILED for topic ${topicId}`);
|
|
3775
3768
|
}
|
|
3776
3769
|
}
|
|
3777
|
-
|
|
3778
|
-
|
|
3770
|
+
}
|
|
3771
|
+
// Slack path — handled in the Slack-aware block below (needs slackChannelToSyntheticId).
|
|
3772
|
+
// We attempt it here lazily via a deferred handler set on globalThis to avoid TDZ.
|
|
3773
|
+
const slackHandler = globalThis.__instarSlackCompactionResume;
|
|
3774
|
+
if (slackHandler) {
|
|
3775
|
+
try {
|
|
3776
|
+
return await slackHandler(sessionName, triggerLabel);
|
|
3777
|
+
}
|
|
3778
|
+
catch { /* fall through */ }
|
|
3779
|
+
}
|
|
3780
|
+
return false;
|
|
3781
|
+
};
|
|
3782
|
+
// Trigger 1: PreCompact hook event — wired unconditionally now.
|
|
3783
|
+
hookEventReceiver.on('PreCompact', () => {
|
|
3784
|
+
// Delay to let compaction + recovery hooks finish
|
|
3785
|
+
setTimeout(() => {
|
|
3786
|
+
if (!telegram)
|
|
3787
|
+
return;
|
|
3788
|
+
const topicSessions = telegram.getAllTopicSessions();
|
|
3789
|
+
for (const [, sessionName] of topicSessions) {
|
|
3790
|
+
recoverCompactedSession(sessionName, 'PreCompact').catch(() => { });
|
|
3791
|
+
}
|
|
3792
|
+
}, 10_000);
|
|
3793
|
+
});
|
|
3794
|
+
console.log(pc.green(' Compaction auto-resume wired (PreCompact hook event)'));
|
|
3795
|
+
// Trigger 2: Watchdog 'compaction-idle' polling — wired unconditionally.
|
|
3796
|
+
if (watchdog) {
|
|
3797
|
+
watchdog.on('compaction-idle', (sessionName) => {
|
|
3798
|
+
recoverCompactedSession(sessionName, 'watchdog-poll').catch(() => { });
|
|
3779
3799
|
});
|
|
3780
|
-
console.log(pc.green(' Compaction auto-resume wired
|
|
3800
|
+
console.log(pc.green(' Compaction auto-resume wired (watchdog poll)'));
|
|
3781
3801
|
}
|
|
3802
|
+
// Trigger 3: stash the recovery function on globalThis so the HTTP route
|
|
3803
|
+
// (registered later in AgentServer) and the compaction-recovery.sh hook
|
|
3804
|
+
// can invoke it via POST /internal/compaction-resume.
|
|
3805
|
+
globalThis.__instarCompactionRecover = recoverCompactedSession;
|
|
3782
3806
|
// Subagent Tracker — monitors subagent lifecycle via hook events
|
|
3783
3807
|
const { SubagentTracker } = await import('../monitoring/SubagentTracker.js');
|
|
3784
3808
|
const subagentTracker = new SubagentTracker({ stateDir: config.stateDir });
|
|
@@ -3913,17 +3937,18 @@ export async function startServer(options) {
|
|
|
3913
3937
|
slackChannelToSyntheticId(channelId);
|
|
3914
3938
|
}
|
|
3915
3939
|
}
|
|
3916
|
-
// Slack compaction-resume wiring —
|
|
3917
|
-
|
|
3918
|
-
|
|
3940
|
+
// Slack compaction-resume wiring — registered as a deferred handler the
|
|
3941
|
+
// unified recoverCompactedSession() helper above will call. Works with or
|
|
3942
|
+
// without triageOrchestrator (falls back to direct sessionManager inject).
|
|
3943
|
+
if (_slackAdapter) {
|
|
3919
3944
|
const _slack = _slackAdapter;
|
|
3920
|
-
|
|
3945
|
+
const slackRecover = async (sessionName, triggerLabel) => {
|
|
3921
3946
|
const channelId = _slack.getChannelForSession(sessionName);
|
|
3922
3947
|
if (!channelId)
|
|
3923
|
-
return;
|
|
3948
|
+
return false;
|
|
3924
3949
|
const syntheticId = slackChannelToSyntheticId(channelId);
|
|
3925
|
-
// Read from the Slack messages JSONL log (local, no API call)
|
|
3926
3950
|
const slackLogPath = path.join(config.stateDir, 'slack-messages.jsonl');
|
|
3951
|
+
let lastUserMsg = null;
|
|
3927
3952
|
try {
|
|
3928
3953
|
const content = fs.readFileSync(slackLogPath, 'utf-8');
|
|
3929
3954
|
const lines = content.trim().split('\n').slice(-10);
|
|
@@ -3931,21 +3956,37 @@ export async function startServer(options) {
|
|
|
3931
3956
|
try {
|
|
3932
3957
|
const msg = JSON.parse(lines[i]);
|
|
3933
3958
|
if (msg.channelId === channelId) {
|
|
3934
|
-
if (msg.fromUser)
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
console.warn(`[CompactionResume] Triage activation failed for Slack channel ${channelId}:`, err);
|
|
3938
|
-
});
|
|
3939
|
-
}
|
|
3940
|
-
break; // Only check the most recent message for this channel
|
|
3959
|
+
if (msg.fromUser)
|
|
3960
|
+
lastUserMsg = msg;
|
|
3961
|
+
break;
|
|
3941
3962
|
}
|
|
3942
3963
|
}
|
|
3943
|
-
catch { /* skip malformed
|
|
3964
|
+
catch { /* skip malformed */ }
|
|
3944
3965
|
}
|
|
3945
3966
|
}
|
|
3946
|
-
catch { /*
|
|
3947
|
-
|
|
3948
|
-
|
|
3967
|
+
catch { /* no log */ }
|
|
3968
|
+
if (!lastUserMsg)
|
|
3969
|
+
return false;
|
|
3970
|
+
const text = lastUserMsg.text || 'message after compaction';
|
|
3971
|
+
console.log(`[CompactionResume] (${triggerLabel}) Slack channel ${channelId} has unanswered message — recovering`);
|
|
3972
|
+
if (triageOrchestrator) {
|
|
3973
|
+
try {
|
|
3974
|
+
await triageOrchestrator.activate(syntheticId, sessionName, 'watchdog', text, Date.now());
|
|
3975
|
+
return true;
|
|
3976
|
+
}
|
|
3977
|
+
catch (err) {
|
|
3978
|
+
console.warn(`[CompactionResume] Slack orchestrator failed, falling back to direct inject:`, err);
|
|
3979
|
+
}
|
|
3980
|
+
}
|
|
3981
|
+
const ok = sessionManager.injectMessage(sessionName, text);
|
|
3982
|
+
if (ok) {
|
|
3983
|
+
console.log(`[CompactionResume] (${triggerLabel}) Slack direct re-inject OK for channel ${channelId}`);
|
|
3984
|
+
return true;
|
|
3985
|
+
}
|
|
3986
|
+
return false;
|
|
3987
|
+
};
|
|
3988
|
+
globalThis.__instarSlackCompactionResume = slackRecover;
|
|
3989
|
+
console.log(pc.green(' Compaction auto-resume registered (Slack channels)'));
|
|
3949
3990
|
}
|
|
3950
3991
|
let presenceProxy;
|
|
3951
3992
|
if (sharedIntelligence && telegram) {
|