@cortexkit/opencode-magic-context 0.32.0 → 0.32.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/README.md +3 -3
- package/dist/features/magic-context/dreamer/cron.d.ts +2 -2
- package/dist/features/magic-context/dreamer/cron.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
- package/dist/features/magic-context/message-index-async.d.ts +4 -1
- package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
- package/dist/features/magic-context/message-index.d.ts +7 -4
- package/dist/features/magic-context/message-index.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts +8 -16
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/plugin-messages.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/session-project-backfill.d.ts +6 -3
- package/dist/features/magic-context/session-project-backfill.d.ts.map +1 -1
- package/dist/features/magic-context/session-project-storage.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/capabilities.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/compiler.d.ts +3 -1
- package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/runner.d.ts +1 -0
- package/dist/features/magic-context/smart-notes/runner.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts +8 -1
- package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/ssrf-guard.d.ts +10 -0
- package/dist/features/magic-context/smart-notes/ssrf-guard.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/storage.d.ts +16 -1
- package/dist/features/magic-context/smart-notes/storage.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts +1 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +8 -5
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
- package/dist/features/magic-context/storage-schema-helpers.d.ts +3 -4
- package/dist/features/magic-context/storage-schema-helpers.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/tool-owner-backfill.d.ts +2 -0
- package/dist/features/magic-context/tool-owner-backfill.d.ts.map +1 -1
- package/dist/features/magic-context/transform-decision-log.d.ts +1 -1
- package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-render-epoch.d.ts +12 -0
- package/dist/hooks/magic-context/compartment-render-epoch.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
- package/dist/hooks/magic-context/decay-render.d.ts.map +1 -1
- package/dist/hooks/magic-context/emergency-drop.d.ts +1 -0
- package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts +29 -0
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -0
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts +1 -0
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/historian-prompt.generated.d.ts +1 -1
- package/dist/hooks/magic-context/historian-prompt.generated.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts +1 -0
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts +15 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts +24 -2
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
- package/dist/hooks/magic-context/shadow-sender.d.ts +65 -27
- package/dist/hooks/magic-context/shadow-sender.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +27 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4128 -1207
- package/dist/plugin/rpc-handlers.d.ts +3 -0
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/shared/models-dev-cache.d.ts +5 -0
- package/dist/shared/models-dev-cache.d.ts.map +1 -1
- package/dist/shared/rpc-client.d.ts +3 -1
- package/dist/shared/rpc-client.d.ts.map +1 -1
- package/dist/shared/rpc-notifications.d.ts +11 -6
- package/dist/shared/rpc-notifications.d.ts.map +1 -1
- package/dist/shared/rpc-server.d.ts +2 -2
- package/dist/shared/rpc-server.d.ts.map +1 -1
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/shared/tui-config.d.ts +5 -3
- package/dist/shared/tui-config.d.ts.map +1 -1
- package/dist/tui/data/context-db.d.ts +9 -2
- package/dist/tui/data/context-db.d.ts.map +1 -1
- package/dist/tui/data/notification-socket.d.ts +4 -5
- package/dist/tui/data/notification-socket.d.ts.map +1 -1
- package/dist/tui-compiled/data/context-db.d.ts +9 -2
- package/dist/tui-compiled/data/context-db.d.ts.map +1 -1
- package/dist/tui-compiled/data/notification-socket.d.ts +4 -5
- package/dist/tui-compiled/data/notification-socket.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/shared/models-dev-cache.test.ts +5 -0
- package/src/shared/models-dev-cache.ts +44 -6
- package/src/shared/opencode-compaction-detector.test.ts +11 -2
- package/src/shared/rpc-client.test.ts +213 -9
- package/src/shared/rpc-client.ts +48 -39
- package/src/shared/rpc-notifications.test.ts +26 -5
- package/src/shared/rpc-notifications.ts +44 -35
- package/src/shared/rpc-server.ts +69 -33
- package/src/shared/sqlite.ts +22 -3
- package/src/shared/tui-config.test.ts +4 -12
- package/src/shared/tui-config.ts +6 -6
- package/src/tui/data/context-db.test.ts +113 -0
- package/src/tui/data/context-db.ts +26 -19
- package/src/tui/data/notification-socket.test.ts +277 -11
- package/src/tui/data/notification-socket.ts +257 -86
- package/src/tui/index.tsx +33 -25
- package/src/tui/slots/sidebar-content.tsx +62 -24
- package/src/tui-compiled/data/context-db.ts +26 -19
- package/src/tui-compiled/data/notification-socket.ts +257 -86
- package/src/tui-compiled/index.tsx +41 -24
- package/src/tui-compiled/slots/sidebar-content.tsx +45 -23
|
@@ -40,11 +40,10 @@ function createSidebarController(initialPrefs) {
|
|
|
40
40
|
let lastPersistedCollapsed = initialPrefs.collapsed;
|
|
41
41
|
let lastApplied = JSON.stringify(initialPrefs);
|
|
42
42
|
|
|
43
|
-
// Watcher lives for the process lifetime — intentionally never disposed.
|
|
44
43
|
// Collapse echo guard: lastPersistedCollapsed advances only once our own
|
|
45
44
|
// write lands, so a watcher echo of the value we just wrote is rejected by
|
|
46
45
|
// the `!==` check and cannot revert a user click.
|
|
47
|
-
watchTuiPreferences(() => {
|
|
46
|
+
const stopWatchingPreferences = watchTuiPreferences(() => {
|
|
48
47
|
void (async () => {
|
|
49
48
|
const next = resolveMagicContextPrefs(await readTuiPreferencesFile());
|
|
50
49
|
const serialized = JSON.stringify(next);
|
|
@@ -69,7 +68,8 @@ function createSidebarController(initialPrefs) {
|
|
|
69
68
|
return {
|
|
70
69
|
prefs,
|
|
71
70
|
collapsed,
|
|
72
|
-
toggleCollapsed
|
|
71
|
+
toggleCollapsed,
|
|
72
|
+
dispose: stopWatchingPreferences
|
|
73
73
|
};
|
|
74
74
|
}
|
|
75
75
|
function compactTokens(value) {
|
|
@@ -524,6 +524,8 @@ const SidebarContent = props => {
|
|
|
524
524
|
let recompSawPhase = false;
|
|
525
525
|
let recompPollCount = 0;
|
|
526
526
|
let recompConsecutiveAbsent = 0;
|
|
527
|
+
let recompSessionId = null;
|
|
528
|
+
let snapshotRequestSequence = 0;
|
|
527
529
|
const RECOMP_PROBE_MAX = 12; // ~15s for the server's "Starting…" to land
|
|
528
530
|
// After we've SEEN an active phase, a momentarily absent snapshot is almost
|
|
529
531
|
// always transient — the server's sticky cache serves a pre-recomp snapshot
|
|
@@ -539,12 +541,13 @@ const SidebarContent = props => {
|
|
|
539
541
|
const refresh = () => {
|
|
540
542
|
const sid = props.sessionID();
|
|
541
543
|
if (!sid) return;
|
|
544
|
+
const sequence = ++snapshotRequestSequence;
|
|
542
545
|
const directory = props.api.state.path.directory ?? "";
|
|
543
546
|
void loadSidebarSnapshot(sid, directory).then(data => {
|
|
544
547
|
// Guard against a session switch while this load was in flight:
|
|
545
548
|
// painting session A's snapshot into the now-active session B shows
|
|
546
549
|
// the wrong session's numbers until B's own refresh resolves.
|
|
547
|
-
if (props.sessionID() !== sid) return;
|
|
550
|
+
if (props.sessionID() !== sid || sequence !== snapshotRequestSequence) return;
|
|
548
551
|
setSnapshot(data);
|
|
549
552
|
try {
|
|
550
553
|
props.api.renderer.requestRender();
|
|
@@ -557,10 +560,15 @@ const SidebarContent = props => {
|
|
|
557
560
|
const phase = data?.recompProgress?.phase;
|
|
558
561
|
if ((phase === "recomp" || phase === "migration") && !recompActive) {
|
|
559
562
|
kickRecompPoll();
|
|
563
|
+
} else if (recompActive && recompSessionId === sid) {
|
|
564
|
+
scheduleRecompTick();
|
|
560
565
|
}
|
|
561
566
|
}).catch(() => {
|
|
562
|
-
// one-shot refresh failure is non-fatal
|
|
563
|
-
//
|
|
567
|
+
// A one-shot refresh failure is non-fatal. If it superseded a fast
|
|
568
|
+
// poll request, keep that poll moving for the captured session.
|
|
569
|
+
if (recompActive && recompSessionId === sid && props.sessionID() === sid) {
|
|
570
|
+
scheduleRecompTick();
|
|
571
|
+
}
|
|
564
572
|
});
|
|
565
573
|
};
|
|
566
574
|
const scheduleRefresh = () => {
|
|
@@ -570,25 +578,33 @@ const SidebarContent = props => {
|
|
|
570
578
|
refresh();
|
|
571
579
|
}, REFRESH_DEBOUNCE_MS);
|
|
572
580
|
};
|
|
581
|
+
const stopRecompPoll = () => {
|
|
582
|
+
recompActive = false;
|
|
583
|
+
recompSessionId = null;
|
|
584
|
+
snapshotRequestSequence += 1;
|
|
585
|
+
if (recompPollTimer) clearTimeout(recompPollTimer);
|
|
586
|
+
recompPollTimer = undefined;
|
|
587
|
+
};
|
|
573
588
|
const scheduleRecompTick = () => {
|
|
574
589
|
if (!recompActive) return;
|
|
575
590
|
if (recompPollTimer) clearTimeout(recompPollTimer);
|
|
576
591
|
recompPollTimer = setTimeout(recompTick, RECOMP_POLL_MS);
|
|
577
592
|
};
|
|
578
593
|
function recompTick() {
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
recompActive = false;
|
|
594
|
+
const sid = recompSessionId;
|
|
595
|
+
if (!recompActive || !sid || props.sessionID() !== sid) {
|
|
596
|
+
stopRecompPoll();
|
|
583
597
|
return;
|
|
584
598
|
}
|
|
585
|
-
|
|
586
|
-
if (
|
|
587
|
-
|
|
599
|
+
recompPollCount += 1;
|
|
600
|
+
if (recompPollCount > RECOMP_MAX_POLLS) {
|
|
601
|
+
stopRecompPoll();
|
|
588
602
|
return;
|
|
589
603
|
}
|
|
604
|
+
const sequence = ++snapshotRequestSequence;
|
|
590
605
|
const directory = props.api.state.path.directory ?? "";
|
|
591
606
|
void loadSidebarSnapshot(sid, directory).then(data => {
|
|
607
|
+
if (!recompActive || recompSessionId !== sid || props.sessionID() !== sid || sequence !== snapshotRequestSequence) return;
|
|
592
608
|
const phase = data?.recompProgress?.phase;
|
|
593
609
|
// While a recomp is known-active, a transient snapshot that lost
|
|
594
610
|
// recompProgress (sticky cache / busy-DB empty) must NOT wipe the
|
|
@@ -613,14 +629,14 @@ const SidebarContent = props => {
|
|
|
613
629
|
// Terminal state rendered — stop. The server keeps "done"/
|
|
614
630
|
// "skipped" for a grace window and "failed" until the next run,
|
|
615
631
|
// so the outcome stays visible without further polling.
|
|
616
|
-
|
|
632
|
+
stopRecompPoll();
|
|
617
633
|
} else {
|
|
618
634
|
// Phase absent this poll.
|
|
619
635
|
recompConsecutiveAbsent += 1;
|
|
620
636
|
if (!recompSawPhase) {
|
|
621
637
|
// Still waiting for the server's first "Starting…".
|
|
622
638
|
if (recompPollCount < RECOMP_PROBE_MAX) scheduleRecompTick();else {
|
|
623
|
-
|
|
639
|
+
stopRecompPoll();
|
|
624
640
|
}
|
|
625
641
|
} else if (recompConsecutiveAbsent < RECOMP_ABSENT_GIVEUP) {
|
|
626
642
|
// Seen it active — absent is almost certainly the sticky
|
|
@@ -630,13 +646,13 @@ const SidebarContent = props => {
|
|
|
630
646
|
scheduleRecompTick();
|
|
631
647
|
} else {
|
|
632
648
|
// Long continuous absence — the entry is genuinely gone.
|
|
633
|
-
|
|
649
|
+
stopRecompPoll();
|
|
634
650
|
}
|
|
635
651
|
}
|
|
636
|
-
}).catch(
|
|
637
|
-
//
|
|
638
|
-
//
|
|
639
|
-
scheduleRecompTick();
|
|
652
|
+
}).catch(() => {
|
|
653
|
+
// A failed fetch must not kill the loop, but a response from a
|
|
654
|
+
// superseded session or sequence must not restart it either.
|
|
655
|
+
if (recompActive && recompSessionId === sid && props.sessionID() === sid && sequence === snapshotRequestSequence) scheduleRecompTick();
|
|
640
656
|
});
|
|
641
657
|
}
|
|
642
658
|
|
|
@@ -644,8 +660,12 @@ const SidebarContent = props => {
|
|
|
644
660
|
// first detects an active recomp). The server emits an immediate "Starting…"
|
|
645
661
|
// entry; the probe window covers the brief RPC race before it lands.
|
|
646
662
|
function kickRecompPoll() {
|
|
647
|
-
|
|
663
|
+
const sid = props.sessionID();
|
|
664
|
+
if (!sid) return;
|
|
665
|
+
if (recompActive && recompSessionId === sid) return;
|
|
666
|
+
stopRecompPoll();
|
|
648
667
|
recompActive = true;
|
|
668
|
+
recompSessionId = sid;
|
|
649
669
|
recompSawPhase = false;
|
|
650
670
|
recompPollCount = 0;
|
|
651
671
|
recompConsecutiveAbsent = 0;
|
|
@@ -654,13 +674,14 @@ const SidebarContent = props => {
|
|
|
654
674
|
activeRecompPollKick = kickRecompPoll;
|
|
655
675
|
onCleanup(() => {
|
|
656
676
|
if (refreshTimer) clearTimeout(refreshTimer);
|
|
657
|
-
|
|
658
|
-
recompActive = false;
|
|
677
|
+
stopRecompPoll();
|
|
659
678
|
if (activeRecompPollKick === kickRecompPoll) activeRecompPollKick = null;
|
|
660
679
|
});
|
|
661
680
|
|
|
662
681
|
// Refresh on session change
|
|
663
682
|
createEffect(on(props.sessionID, () => {
|
|
683
|
+
stopRecompPoll();
|
|
684
|
+
setSnapshot(null);
|
|
664
685
|
refresh();
|
|
665
686
|
}));
|
|
666
687
|
|
|
@@ -1035,6 +1056,7 @@ export function createSidebarContentSlot(api) {
|
|
|
1035
1056
|
const effectiveOrder = computeEffectiveOrder(seedRoot, PLUGIN_KEY, DEFAULT_SLOT_ORDER);
|
|
1036
1057
|
return {
|
|
1037
1058
|
order: effectiveOrder,
|
|
1059
|
+
dispose: controller.dispose,
|
|
1038
1060
|
slots: {
|
|
1039
1061
|
sidebar_content: (ctx, value) => {
|
|
1040
1062
|
const theme = createMemo(() => ctx.theme.current);
|