@cortexkit/opencode-magic-context 0.31.3 → 0.31.5
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/config/index.d.ts.map +1 -1
- package/dist/config/project-security.d.ts +16 -12
- package/dist/config/project-security.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/classify-prompt.d.ts +2 -2
- package/dist/features/magic-context/dreamer/classify-prompt.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/classify.d.ts +8 -0
- package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/lease.d.ts +1 -0
- package/dist/features/magic-context/dreamer/lease.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/manifest-parser.d.ts +7 -0
- package/dist/features/magic-context/dreamer/manifest-parser.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/map-memories-prompt.d.ts +2 -3
- package/dist/features/magic-context/dreamer/map-memories-prompt.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/map-memories.d.ts +8 -0
- package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/promote-primers.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/retrospective-raw-provider.d.ts +5 -0
- package/dist/features/magic-context/dreamer/retrospective-raw-provider.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify-prompt.d.ts +2 -2
- package/dist/features/magic-context/dreamer/verify-prompt.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
- package/dist/features/magic-context/memory/storage-memory-embeddings.d.ts +4 -0
- package/dist/features/magic-context/memory/storage-memory-embeddings.d.ts.map +1 -1
- package/dist/features/magic-context/memory/storage-memory.d.ts +12 -0
- package/dist/features/magic-context/memory/storage-memory.d.ts.map +1 -1
- package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
- package/dist/features/magic-context/message-index.d.ts +6 -0
- package/dist/features/magic-context/message-index.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/search.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/capabilities.d.ts +1 -0
- package/dist/features/magic-context/smart-notes/capabilities.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/compiler.d.ts +3 -2
- package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/runner.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts +3 -2
- package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/schedule.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/ssrf-guard.d.ts +17 -6
- package/dist/features/magic-context/smart-notes/ssrf-guard.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/types.d.ts +6 -1
- package/dist/features/magic-context/smart-notes/types.d.ts.map +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 -0
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta.d.ts +1 -1
- package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +1 -1
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/workspaces.d.ts +8 -0
- package/dist/features/magic-context/workspaces.d.ts.map +1 -1
- package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner.d.ts +2 -0
- package/dist/hooks/magic-context/compartment-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts +1 -0
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/todo-view.d.ts +27 -2
- package/dist/hooks/magic-context/todo-view.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-message-helpers.d.ts +6 -3
- package/dist/hooks/magic-context/transform-message-helpers.d.ts.map +1 -1
- package/dist/hooks/magic-context/wrapup-orchestrator.d.ts +1 -0
- package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
- package/dist/index.js +1039 -331
- package/dist/shared/assistant-message-extractor.d.ts +1 -0
- package/dist/shared/assistant-message-extractor.d.ts.map +1 -1
- package/dist/shared/redaction.d.ts.map +1 -1
- package/dist/shared/rpc-notifications.d.ts +21 -16
- package/dist/shared/rpc-notifications.d.ts.map +1 -1
- package/dist/shared/rpc-server.d.ts +1 -0
- package/dist/shared/rpc-server.d.ts.map +1 -1
- package/dist/shared/rpc-utils.d.ts +3 -1
- package/dist/shared/rpc-utils.d.ts.map +1 -1
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
- package/dist/tools/ctx-search/tools.d.ts.map +1 -1
- package/dist/tools/ctx-search/types.d.ts +1 -1
- package/dist/tools/ctx-search/types.d.ts.map +1 -1
- package/dist/tui/data/notification-socket.d.ts +1 -0
- package/dist/tui/data/notification-socket.d.ts.map +1 -1
- package/dist/tui-compiled/badge-contrast.d.ts +46 -0
- package/dist/tui-compiled/badge-contrast.d.ts.map +1 -0
- package/dist/tui-compiled/data/context-db.d.ts +45 -0
- package/dist/tui-compiled/data/context-db.d.ts.map +1 -0
- package/dist/tui-compiled/data/notification-socket.d.ts +40 -0
- package/dist/tui-compiled/data/notification-socket.d.ts.map +1 -0
- package/package.json +3 -2
- package/src/shared/assistant-message-extractor.ts +20 -0
- package/src/shared/redaction.ts +1 -0
- package/src/shared/rpc-client.test.ts +164 -5
- package/src/shared/rpc-notifications.ts +73 -21
- package/src/shared/rpc-server.ts +69 -18
- package/src/shared/rpc-utils.ts +12 -2
- package/src/tui/data/notification-socket.test.ts +131 -0
- package/src/tui/data/notification-socket.ts +81 -16
- package/src/tui/entry.mjs +23 -3
- package/src/tui-compiled/data/notification-socket.ts +81 -16
|
@@ -51,9 +51,21 @@ let opts: NotificationSocketOptions | null = null;
|
|
|
51
51
|
/** Generation of the rpc client at connect time; a dispose/reinit bumps it and
|
|
52
52
|
* invalidates an in-flight socket so its late callbacks are ignored. */
|
|
53
53
|
let connectGeneration = 0;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
|
|
55
|
+
const GLOBAL_CURSOR_KEY = "global";
|
|
56
|
+
const SESSION_CURSOR_PREFIX = "session:";
|
|
57
|
+
const MAX_DEDUPED_NOTIFICATION_IDS = 500;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Notification ids are process-global, but acknowledgement cursors are scoped. A
|
|
61
|
+
* high id consumed in session A must not become the prune watermark for session B;
|
|
62
|
+
* global notifications also carry their own cursor so they cannot skip session
|
|
63
|
+
* backlog. The id set de-dupes at-least-once re-delivery when a reconnect sends
|
|
64
|
+
* a session cursor that is intentionally lower than the global cursor.
|
|
65
|
+
*/
|
|
66
|
+
const lastHandledIdByCursor = new Map<string, number>();
|
|
67
|
+
const handledNotificationIds = new Set<number>();
|
|
68
|
+
const handledNotificationIdOrder: number[] = [];
|
|
57
69
|
|
|
58
70
|
/** Open the persistent notification socket. Idempotent: a second call while open
|
|
59
71
|
* is a no-op. Reconnects on its own after any drop. */
|
|
@@ -118,8 +130,10 @@ async function connect(): Promise<void> {
|
|
|
118
130
|
|
|
119
131
|
let ws: WebSocket;
|
|
120
132
|
try {
|
|
121
|
-
|
|
133
|
+
const tokenQuery = `?token=${encodeURIComponent(endpoint.token ?? "")}`;
|
|
134
|
+
ws = new WebSocket(`ws://127.0.0.1:${endpoint.port}/ws${tokenQuery}`);
|
|
122
135
|
} catch {
|
|
136
|
+
client.reset();
|
|
123
137
|
scheduleReconnect();
|
|
124
138
|
return;
|
|
125
139
|
}
|
|
@@ -137,6 +151,7 @@ async function connect(): Promise<void> {
|
|
|
137
151
|
});
|
|
138
152
|
|
|
139
153
|
const onDown = () => {
|
|
154
|
+
client.reset();
|
|
140
155
|
if (socket === ws) {
|
|
141
156
|
socket = null;
|
|
142
157
|
helloedSession = null;
|
|
@@ -155,7 +170,8 @@ function sendHello(ws: WebSocket, token: string | null): void {
|
|
|
155
170
|
type: "hello",
|
|
156
171
|
token: token ?? "",
|
|
157
172
|
sessionId,
|
|
158
|
-
lastReceivedId:
|
|
173
|
+
lastReceivedId: cursorForKey(cursorKeyForSession(sessionId)),
|
|
174
|
+
globalLastReceivedId: cursorForKey(GLOBAL_CURSOR_KEY),
|
|
159
175
|
}),
|
|
160
176
|
);
|
|
161
177
|
}
|
|
@@ -180,6 +196,11 @@ async function handleSocketMessage(ws: WebSocket, raw: string): Promise<void> {
|
|
|
180
196
|
// session, or a later switch back, should still get it). Just skip.
|
|
181
197
|
return;
|
|
182
198
|
}
|
|
199
|
+
if (handledNotificationIds.has(notification.id)) {
|
|
200
|
+
sendAck(ws, notification);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
183
204
|
let consumed = false;
|
|
184
205
|
try {
|
|
185
206
|
consumed = await Promise.resolve(opts?.onNotification(notification) ?? false);
|
|
@@ -188,17 +209,13 @@ async function handleSocketMessage(ws: WebSocket, raw: string): Promise<void> {
|
|
|
188
209
|
}
|
|
189
210
|
// A dispose/reinit during an awaited dialog handler invalidates this socket.
|
|
190
211
|
if (socket !== ws || getRpcGeneration() !== connectGeneration) return;
|
|
191
|
-
if (consumed
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
//
|
|
195
|
-
//
|
|
196
|
-
//
|
|
197
|
-
|
|
198
|
-
ws.send(JSON.stringify({ type: "ack", lastReceivedId: lastHandledId }));
|
|
199
|
-
} catch {
|
|
200
|
-
// best-effort; reconnect hello re-syncs via lastReceivedId
|
|
201
|
-
}
|
|
212
|
+
if (consumed) {
|
|
213
|
+
rememberHandledId(notification.id);
|
|
214
|
+
advanceCursor(notificationCursorKey(notification), notification.id);
|
|
215
|
+
// Ack only the notification's own cursor scope. A dropped ack is safe:
|
|
216
|
+
// the next hello sends the same per-scope cursors and duplicates are
|
|
217
|
+
// ignored locally.
|
|
218
|
+
sendAck(ws, notification);
|
|
202
219
|
}
|
|
203
220
|
return;
|
|
204
221
|
}
|
|
@@ -214,6 +231,54 @@ async function handleSocketMessage(ws: WebSocket, raw: string): Promise<void> {
|
|
|
214
231
|
}
|
|
215
232
|
}
|
|
216
233
|
|
|
234
|
+
function cursorKeyForSession(sessionId: string | null | undefined): string {
|
|
235
|
+
return sessionId ? `${SESSION_CURSOR_PREFIX}${sessionId}` : GLOBAL_CURSOR_KEY;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function notificationCursorKey(notification: SocketNotification): string {
|
|
239
|
+
return notification.sessionId
|
|
240
|
+
? `${SESSION_CURSOR_PREFIX}${notification.sessionId}`
|
|
241
|
+
: GLOBAL_CURSOR_KEY;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function cursorForKey(key: string): number {
|
|
245
|
+
return lastHandledIdByCursor.get(key) ?? 0;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function advanceCursor(key: string, id: number): void {
|
|
249
|
+
if (id > cursorForKey(key)) lastHandledIdByCursor.set(key, id);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function rememberHandledId(id: number): void {
|
|
253
|
+
if (handledNotificationIds.has(id)) return;
|
|
254
|
+
handledNotificationIds.add(id);
|
|
255
|
+
handledNotificationIdOrder.push(id);
|
|
256
|
+
while (handledNotificationIdOrder.length > MAX_DEDUPED_NOTIFICATION_IDS) {
|
|
257
|
+
const evicted = handledNotificationIdOrder.shift();
|
|
258
|
+
if (evicted !== undefined) handledNotificationIds.delete(evicted);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function sendAck(ws: WebSocket, notification: SocketNotification): void {
|
|
263
|
+
const lastReceivedId = cursorForKey(notificationCursorKey(notification));
|
|
264
|
+
const ack = notification.sessionId
|
|
265
|
+
? { type: "ack", sessionId: notification.sessionId, lastReceivedId }
|
|
266
|
+
: { type: "ack", ackScope: "global", lastReceivedId };
|
|
267
|
+
try {
|
|
268
|
+
ws.send(JSON.stringify(ack));
|
|
269
|
+
} catch {
|
|
270
|
+
// best-effort; reconnect hello re-syncs via per-scope cursors
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export function _resetNotificationSocketStateForTesting(): void {
|
|
275
|
+
stopNotificationSocket();
|
|
276
|
+
opts = null;
|
|
277
|
+
lastHandledIdByCursor.clear();
|
|
278
|
+
handledNotificationIds.clear();
|
|
279
|
+
handledNotificationIdOrder.length = 0;
|
|
280
|
+
}
|
|
281
|
+
|
|
217
282
|
/** Cheap session-change watcher: re-scope the socket only when the active session
|
|
218
283
|
* actually changes. Reads a property; no network at idle. */
|
|
219
284
|
function watchSession(): void {
|