@kraki/tentacle 0.17.2 → 0.17.4
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/adapters/base.d.ts +3 -0
- package/dist/adapters/base.js +3 -0
- package/dist/adapters/base.js.map +1 -1
- package/dist/adapters/copilot.d.ts +11 -0
- package/dist/adapters/copilot.js +60 -6
- package/dist/adapters/copilot.js.map +1 -1
- package/dist/events-watcher.d.ts +44 -0
- package/dist/events-watcher.js +183 -0
- package/dist/events-watcher.js.map +1 -0
- package/dist/history-parser.d.ts +12 -0
- package/dist/history-parser.js +2 -2
- package/dist/history-parser.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/relay-client.d.ts +6 -1
- package/dist/relay-client.js +116 -76
- package/dist/relay-client.js.map +1 -1
- package/dist/session-manager.d.ts +10 -0
- package/dist/session-manager.js +24 -0
- package/dist/session-manager.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events-watcher.js","sourceRoot":"","sources":["../src/events-watcher.ts"],"names":[],"mappings":"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"}
|
package/dist/history-parser.d.ts
CHANGED
|
@@ -7,6 +7,12 @@
|
|
|
7
7
|
* Reads events.jsonl line by line (streaming) to handle large files.
|
|
8
8
|
* Caps output at MAX_BACKFILL_MESSAGES most recent messages.
|
|
9
9
|
*/
|
|
10
|
+
interface SdkEvent {
|
|
11
|
+
type: string;
|
|
12
|
+
data: Record<string, unknown>;
|
|
13
|
+
id?: string;
|
|
14
|
+
timestamp?: string;
|
|
15
|
+
}
|
|
10
16
|
export interface BackfilledMessage {
|
|
11
17
|
seq: number;
|
|
12
18
|
type: string;
|
|
@@ -35,3 +41,9 @@ export declare function parseSessionHistory(sessionDir: string): {
|
|
|
35
41
|
messages: BackfilledMessage[];
|
|
36
42
|
meta: ParsedSessionMeta;
|
|
37
43
|
};
|
|
44
|
+
export declare function convertEvent(event: SdkEvent, ts: string, meta: ParsedSessionMeta): {
|
|
45
|
+
type: string;
|
|
46
|
+
payload: string;
|
|
47
|
+
ts: string;
|
|
48
|
+
} | null;
|
|
49
|
+
export {};
|
package/dist/history-parser.js
CHANGED
|
@@ -61,8 +61,8 @@ export function parseEventsFile(eventsPath) {
|
|
|
61
61
|
export function parseSessionHistory(sessionDir) {
|
|
62
62
|
return parseEventsFile(join(sessionDir, 'events.jsonl'));
|
|
63
63
|
}
|
|
64
|
-
// ── Event conversion
|
|
65
|
-
function convertEvent(event, ts, meta) {
|
|
64
|
+
// ── Event conversion (exported for use by events-watcher) ───
|
|
65
|
+
export function convertEvent(event, ts, meta) {
|
|
66
66
|
switch (event.type) {
|
|
67
67
|
case 'session.start': {
|
|
68
68
|
// Extract metadata, don't emit a message
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"history-parser.js","sourceRoot":"","sources":["../src/history-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC9E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,MAAM,GAAG,YAAY,CAAC,gBAAgB,CAAC,CAAC;AAE9C,qEAAqE;AACrE,MAAM,qBAAqB,GAAG,GAAG,CAAC;AA8BlC,2DAA2D;AAE3D;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,UAAkB;IAIhD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;IACpC,CAAC;IAED,MAAM,QAAQ,GAAwB,EAAE,CAAC;IACzC,MAAM,IAAI,GAAsB,EAAE,CAAC;IACnC,IAAI,GAAG,GAAG,CAAC,CAAC;IAEZ,2DAA2D;IAC3D,MAAM,OAAO,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAE5C,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YAAE,SAAS;QAE3B,IAAI,KAAe,CAAC;QACpB,IAAI,CAAC;YACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,SAAS,CAAC,qBAAqB;QACjC,CAAC;QAED,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACvD,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;QAChD,IAAI,SAAS,EAAE,CAAC;YACd,GAAG,EAAE,CAAC;YACN,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,SAAS,EAAE,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED,qCAAqC;IACrC,IAAI,QAAQ,CAAC,MAAM,GAAG,qBAAqB,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,qBAAqB,CAAC,CAAC;QACxE,gCAAgC;QAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACrC,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAAkB;IAIpD,OAAO,eAAe,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"history-parser.js","sourceRoot":"","sources":["../src/history-parser.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -10,3 +10,4 @@ export { scanLocalSessions, filterSessions } from './session-scanner.js';
|
|
|
10
10
|
export type { ScanOptions, SessionFilter } from './session-scanner.js';
|
|
11
11
|
export { parseEventsFile, parseSessionHistory } from './history-parser.js';
|
|
12
12
|
export type { BackfilledMessage, ParsedSessionMeta } from './history-parser.js';
|
|
13
|
+
export { EventsWatcher } from './events-watcher.js';
|
package/dist/index.js
CHANGED
|
@@ -10,4 +10,5 @@ export { RelayClient } from './relay-client.js';
|
|
|
10
10
|
export { KeyManager } from './key-manager.js';
|
|
11
11
|
export { scanLocalSessions, filterSessions } from './session-scanner.js';
|
|
12
12
|
export { parseEventsFile, parseSessionHistory } from './history-parser.js';
|
|
13
|
+
export { EventsWatcher } from './events-watcher.js';
|
|
13
14
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,EAAE;AACF,0DAA0D;AAC1D,+DAA+D;AAC/D,0CAA0C;AAE1C,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAkBpF,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACxF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEzE,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,EAAE;AACF,0DAA0D;AAC1D,+DAA+D;AAC/D,0CAA0C;AAE1C,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAkBpF,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACxF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEzE,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE3E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/relay-client.d.ts
CHANGED
|
@@ -45,7 +45,9 @@ export declare class RelayClient {
|
|
|
45
45
|
private pendingE2eQueue;
|
|
46
46
|
/** Maps pre-generated sessionId → requestId for concurrent create_session correlation */
|
|
47
47
|
private pendingRequestIds;
|
|
48
|
-
|
|
48
|
+
/** Message types that write to events.jsonl and should be persisted to messages.jsonl.
|
|
49
|
+
* New types default to NOT persisting/pausing the watcher — safer than the inverse. */
|
|
50
|
+
private static readonly PERSISTENT_TYPES;
|
|
49
51
|
/** Global seq counter for envelope ordering (not used for replay — per-session seq handles that). */
|
|
50
52
|
private seqCounter;
|
|
51
53
|
/** Prefer challenge auth when the relay already knows this device */
|
|
@@ -75,6 +77,8 @@ export declare class RelayClient {
|
|
|
75
77
|
onAuthenticated: ((info: AuthOkMessage) => void) | null;
|
|
76
78
|
/** Called on fatal error (won't reconnect) */
|
|
77
79
|
onFatalError: ((message: string) => void) | null;
|
|
80
|
+
/** Watches imported sessions' events.jsonl for external changes */
|
|
81
|
+
private eventsWatcher;
|
|
78
82
|
constructor(adapter: AgentAdapter, sessionManager: SessionManager, options: RelayClientOptions, keyManager?: KeyManager | null, attachmentStore?: import('./attachment-store.js').AttachmentStore);
|
|
79
83
|
private readonly attachmentStore?;
|
|
80
84
|
/** Track attachment ids already broadcast per session — prevents double-push
|
|
@@ -131,6 +135,7 @@ export declare class RelayClient {
|
|
|
131
135
|
private handleForkSession;
|
|
132
136
|
private handleRequestLocalSessions;
|
|
133
137
|
private handleImportSession;
|
|
138
|
+
private initEventsWatcher;
|
|
134
139
|
/**
|
|
135
140
|
* Process queued unicast envelopes delivered by the relay in auth_ok.
|
|
136
141
|
* These are messages sent by arms while this tentacle was offline — they
|
package/dist/relay-client.js
CHANGED
|
@@ -12,6 +12,7 @@ import { homedir } from 'node:os';
|
|
|
12
12
|
import { importPublicKey, encryptToBlob, decryptFromBlob, signChallenge } from '@kraki/crypto';
|
|
13
13
|
import { scanLocalSessions, filterSessions } from './session-scanner.js';
|
|
14
14
|
import { parseSessionHistory } from './history-parser.js';
|
|
15
|
+
import { EventsWatcher } from './events-watcher.js';
|
|
15
16
|
import { createLogger } from './logger.js';
|
|
16
17
|
import { getKrakiHome } from './config.js';
|
|
17
18
|
import { makeHeadline } from './tool-headline.js';
|
|
@@ -35,16 +36,22 @@ export class RelayClient {
|
|
|
35
36
|
pendingE2eQueue = [];
|
|
36
37
|
/** Maps pre-generated sessionId → requestId for concurrent create_session correlation */
|
|
37
38
|
pendingRequestIds = new Map();
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
'
|
|
42
|
-
'
|
|
43
|
-
'
|
|
44
|
-
'
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
'
|
|
39
|
+
/** Message types that write to events.jsonl and should be persisted to messages.jsonl.
|
|
40
|
+
* New types default to NOT persisting/pausing the watcher — safer than the inverse. */
|
|
41
|
+
static PERSISTENT_TYPES = new Set([
|
|
42
|
+
'session_created',
|
|
43
|
+
'agent_message',
|
|
44
|
+
'user_message',
|
|
45
|
+
'permission',
|
|
46
|
+
'permission_resolved',
|
|
47
|
+
'question',
|
|
48
|
+
'question_resolved',
|
|
49
|
+
'tool_start',
|
|
50
|
+
'tool_complete',
|
|
51
|
+
'error',
|
|
52
|
+
'session_ended',
|
|
53
|
+
'idle',
|
|
54
|
+
'session_replay_batch',
|
|
48
55
|
]);
|
|
49
56
|
/** Global seq counter for envelope ordering (not used for replay — per-session seq handles that). */
|
|
50
57
|
seqCounter = 0;
|
|
@@ -79,6 +86,8 @@ export class RelayClient {
|
|
|
79
86
|
onAuthenticated = null;
|
|
80
87
|
/** Called on fatal error (won't reconnect) */
|
|
81
88
|
onFatalError = null;
|
|
89
|
+
/** Watches imported sessions' events.jsonl for external changes */
|
|
90
|
+
eventsWatcher = null;
|
|
82
91
|
constructor(adapter, sessionManager, options, keyManager, attachmentStore) {
|
|
83
92
|
this.adapter = adapter;
|
|
84
93
|
this.sessionManager = sessionManager;
|
|
@@ -219,6 +228,10 @@ export class RelayClient {
|
|
|
219
228
|
disconnect() {
|
|
220
229
|
this.intentionalDisconnect = true;
|
|
221
230
|
this.stopStaleCheck();
|
|
231
|
+
if (this.eventsWatcher) {
|
|
232
|
+
this.eventsWatcher.close();
|
|
233
|
+
this.eventsWatcher = null;
|
|
234
|
+
}
|
|
222
235
|
if (this.reconnectTimer) {
|
|
223
236
|
clearTimeout(this.reconnectTimer);
|
|
224
237
|
this.reconnectTimer = null;
|
|
@@ -252,6 +265,8 @@ export class RelayClient {
|
|
|
252
265
|
}
|
|
253
266
|
this.setState('connected');
|
|
254
267
|
this.onAuthenticated?.(this.authInfo);
|
|
268
|
+
// Initialize events watcher for imported sessions
|
|
269
|
+
this.initEventsWatcher();
|
|
255
270
|
// Process queued messages from the relay BEFORE broadcasting session list
|
|
256
271
|
// so that deletes/mode changes are applied first
|
|
257
272
|
this.processPendingMessages(this.authInfo.pendingMessages);
|
|
@@ -510,6 +525,7 @@ export class RelayClient {
|
|
|
510
525
|
this.purgeSessionToolState(sessionId);
|
|
511
526
|
this.broadcastedAttachmentIds.delete(sessionId);
|
|
512
527
|
this.send({ type: 'session_deleted', sessionId, payload: {} });
|
|
528
|
+
this.eventsWatcher?.unwatch(sessionId);
|
|
513
529
|
this.adapter.killSession(sessionId)
|
|
514
530
|
.catch((err) => logger.error({ err, sessionId }, 'killSession on delete failed'));
|
|
515
531
|
break;
|
|
@@ -716,7 +732,7 @@ export class RelayClient {
|
|
|
716
732
|
async handleImportSession(msg) {
|
|
717
733
|
if (msg.type !== 'import_session')
|
|
718
734
|
return;
|
|
719
|
-
const { requestId, localSessionId } = msg.payload;
|
|
735
|
+
const { requestId, localSessionId, meta: clientMeta } = msg.payload;
|
|
720
736
|
// Check if already linked
|
|
721
737
|
const existing = this.sessionManager.getLink(localSessionId);
|
|
722
738
|
if (existing) {
|
|
@@ -728,84 +744,64 @@ export class RelayClient {
|
|
|
728
744
|
return;
|
|
729
745
|
}
|
|
730
746
|
try {
|
|
731
|
-
// Use localSessionId as Kraki session ID (shared identity)
|
|
732
747
|
const krakiSessionId = localSessionId;
|
|
733
|
-
//
|
|
748
|
+
// ── Phase 1: Prepare locally (~85ms) ──────────────────
|
|
749
|
+
// Parse events.jsonl for backfill + metadata
|
|
734
750
|
const sessionStateDir = join(homedir(), '.copilot', 'session-state', localSessionId);
|
|
735
751
|
const { messages: backfilledMessages, meta: parsedMeta } = parseSessionHistory(sessionStateDir);
|
|
736
|
-
//
|
|
737
|
-
const
|
|
738
|
-
const
|
|
752
|
+
// Use metadata from the client (picker already has it) or parsed fallback
|
|
753
|
+
const source = clientMeta?.source ?? 'copilot-cli';
|
|
754
|
+
const model = parsedMeta.model ?? clientMeta?.model;
|
|
755
|
+
const autoTitle = clientMeta?.summary?.slice(0, 100);
|
|
756
|
+
const cwd = clientMeta?.cwd ?? parsedMeta.cwd ?? '/';
|
|
739
757
|
// Create Kraki session
|
|
740
|
-
this.sessionManager.createSession('copilot',
|
|
741
|
-
// Persist
|
|
758
|
+
this.sessionManager.createSession('copilot', model, krakiSessionId);
|
|
759
|
+
// Persist metadata
|
|
742
760
|
this.sessionManager.updateMeta(krakiSessionId, {
|
|
743
|
-
source
|
|
744
|
-
autoTitle
|
|
745
|
-
model
|
|
746
|
-
createdAt:
|
|
761
|
+
source,
|
|
762
|
+
autoTitle,
|
|
763
|
+
model,
|
|
764
|
+
createdAt: clientMeta?.startTime,
|
|
747
765
|
});
|
|
748
|
-
//
|
|
749
|
-
|
|
750
|
-
this.sessionManager.appendMessage(krakiSessionId, m.type, m.payload);
|
|
751
|
-
}
|
|
766
|
+
// Batch-write all backfilled messages (single write instead of N appends)
|
|
767
|
+
const lastSeq = this.sessionManager.appendMessagesBatch(krakiSessionId, backfilledMessages);
|
|
752
768
|
// Write link table entry
|
|
753
769
|
this.sessionManager.addLink({
|
|
754
770
|
localSessionId,
|
|
755
771
|
krakiSessionId,
|
|
756
|
-
source
|
|
757
|
-
cwd
|
|
758
|
-
branch:
|
|
772
|
+
source,
|
|
773
|
+
cwd,
|
|
774
|
+
branch: clientMeta?.branch,
|
|
759
775
|
linkedAt: new Date().toISOString(),
|
|
760
776
|
});
|
|
761
|
-
//
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
// so the CLI server discovers the state on disk. resumeSession only works
|
|
767
|
-
// for sessions the CLI server has already loaded in memory.
|
|
768
|
-
const cwd = localSession?.cwd ?? parsedMeta.cwd ?? '/';
|
|
777
|
+
// ── Phase 2: Resume adapter (blocking) ────────────────
|
|
778
|
+
// Clear the requestId so onSessionCreated doesn't send a duplicate session_created
|
|
779
|
+
if (requestId)
|
|
780
|
+
this.pendingRequestIds.delete(krakiSessionId);
|
|
781
|
+
let adapterFailed = false;
|
|
769
782
|
try {
|
|
770
|
-
await this.adapter.createSession({
|
|
771
|
-
sessionId: krakiSessionId,
|
|
772
|
-
model: parsedMeta.model,
|
|
773
|
-
cwd,
|
|
774
|
-
});
|
|
783
|
+
await this.adapter.createSession({ sessionId: krakiSessionId, model: parsedMeta.model, cwd });
|
|
775
784
|
}
|
|
776
|
-
catch (
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
logger.warn({ err: createErr.message, krakiSessionId }, 'SDK resume failed — session imported as idle');
|
|
780
|
-
const meta = this.sessionManager.getMeta(krakiSessionId);
|
|
781
|
-
this.send({
|
|
782
|
-
type: 'session_created',
|
|
783
|
-
sessionId: krakiSessionId,
|
|
784
|
-
payload: {
|
|
785
|
-
agent: 'copilot',
|
|
786
|
-
model: parsedMeta.model ?? localSession?.model,
|
|
787
|
-
requestId,
|
|
788
|
-
lastSeq: meta?.lastSeq ?? 0,
|
|
789
|
-
},
|
|
790
|
-
});
|
|
791
|
-
if (requestId)
|
|
792
|
-
this.pendingRequestIds.delete(krakiSessionId);
|
|
785
|
+
catch (err) {
|
|
786
|
+
adapterFailed = true;
|
|
787
|
+
logger.warn({ err: err.message, krakiSessionId }, 'SDK resume failed — session imported as read-only');
|
|
793
788
|
}
|
|
794
|
-
//
|
|
795
|
-
|
|
796
|
-
this.send({
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
789
|
+
// ── Phase 3: Broadcast to arms ────────────────────────
|
|
790
|
+
// session_created = session is fully ready (or at least browsable)
|
|
791
|
+
this.send({
|
|
792
|
+
type: 'session_created',
|
|
793
|
+
sessionId: krakiSessionId,
|
|
794
|
+
payload: { agent: 'copilot', model, requestId, lastSeq },
|
|
795
|
+
});
|
|
796
|
+
// Send title
|
|
797
|
+
if (autoTitle) {
|
|
800
798
|
this.send({
|
|
801
799
|
type: 'session_title_updated',
|
|
802
800
|
sessionId: krakiSessionId,
|
|
803
|
-
payload: {
|
|
801
|
+
payload: { autoTitle },
|
|
804
802
|
});
|
|
805
803
|
}
|
|
806
|
-
//
|
|
807
|
-
// Don't rely on the web requesting it — the encrypted request_session_replay
|
|
808
|
-
// may fail in some auth configurations.
|
|
804
|
+
// Send backfilled history as replay batch
|
|
809
805
|
if (backfilledMessages.length > 0) {
|
|
810
806
|
const replayMessages = this.sessionManager.getMessagesAfterSeq(krakiSessionId, 0, 500);
|
|
811
807
|
const asProducerMessages = replayMessages.map(m => {
|
|
@@ -823,24 +819,54 @@ export class RelayClient {
|
|
|
823
819
|
payload: {
|
|
824
820
|
sessionId: krakiSessionId,
|
|
825
821
|
messages: asProducerMessages,
|
|
826
|
-
lastSeq
|
|
827
|
-
totalLastSeq:
|
|
822
|
+
lastSeq,
|
|
823
|
+
totalLastSeq: lastSeq,
|
|
828
824
|
},
|
|
829
825
|
});
|
|
830
826
|
}
|
|
831
|
-
//
|
|
827
|
+
// Notify user if adapter failed — session is browsable but not interactive
|
|
828
|
+
if (adapterFailed) {
|
|
829
|
+
this.send({
|
|
830
|
+
type: 'error',
|
|
831
|
+
sessionId: krakiSessionId,
|
|
832
|
+
payload: { message: 'Session imported but could not connect to agent — history is browsable, but new messages will not work.' },
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
// Mark idle + broadcast session list
|
|
836
|
+
this.sessionManager.markIdle(krakiSessionId);
|
|
837
|
+
this.send({ type: 'idle', sessionId: krakiSessionId, payload: {} });
|
|
832
838
|
this.broadcastSessionList();
|
|
833
|
-
logger.info({ localSessionId, krakiSessionId, backfilled: backfilledMessages.length }, 'Session imported');
|
|
839
|
+
logger.info({ localSessionId, krakiSessionId, backfilled: backfilledMessages.length, adapterFailed }, 'Session imported');
|
|
840
|
+
// Start watching events.jsonl for external changes (CLI, VS Code)
|
|
841
|
+
this.eventsWatcher?.watch(krakiSessionId);
|
|
834
842
|
}
|
|
835
843
|
catch (err) {
|
|
836
844
|
logger.error({ err, localSessionId }, 'Import session failed');
|
|
837
845
|
this.send({
|
|
838
846
|
type: 'error',
|
|
839
|
-
sessionId:
|
|
847
|
+
sessionId: localSessionId,
|
|
840
848
|
payload: { message: `Failed to import session: ${err.message} (requestId: ${requestId})` },
|
|
841
849
|
});
|
|
842
850
|
}
|
|
843
851
|
}
|
|
852
|
+
// ── Events watcher for imported sessions ──────────────
|
|
853
|
+
initEventsWatcher() {
|
|
854
|
+
if (this.eventsWatcher)
|
|
855
|
+
this.eventsWatcher.close();
|
|
856
|
+
this.eventsWatcher = new EventsWatcher((msg) => {
|
|
857
|
+
// Broadcast external events to all arms + append to SessionManager
|
|
858
|
+
const sessionId = msg.sessionId;
|
|
859
|
+
this.sessionManager.appendMessage(sessionId, msg.type, JSON.stringify(msg.payload));
|
|
860
|
+
this.send({
|
|
861
|
+
...msg,
|
|
862
|
+
deviceId: this.authInfo?.deviceId ?? '',
|
|
863
|
+
});
|
|
864
|
+
}, this.authInfo?.deviceId ?? '');
|
|
865
|
+
// Start watching all currently linked sessions
|
|
866
|
+
for (const link of this.sessionManager.getAllLinks()) {
|
|
867
|
+
this.eventsWatcher.watch(link.localSessionId);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
844
870
|
// ── Pending message processing ─────────────────────
|
|
845
871
|
/**
|
|
846
872
|
* Process queued unicast envelopes delivered by the relay in auth_ok.
|
|
@@ -898,6 +924,11 @@ export class RelayClient {
|
|
|
898
924
|
const requestId = this.pendingRequestIds.get(event.sessionId);
|
|
899
925
|
if (requestId)
|
|
900
926
|
this.pendingRequestIds.delete(event.sessionId);
|
|
927
|
+
// Skip duplicate broadcast for imported sessions — handleImportSession
|
|
928
|
+
// already sent session_created and cleared the requestId.
|
|
929
|
+
if (!requestId && this.sessionManager.getLink(event.sessionId)) {
|
|
930
|
+
return;
|
|
931
|
+
}
|
|
901
932
|
const meta = this.sessionManager.getMeta(event.sessionId);
|
|
902
933
|
this.send({
|
|
903
934
|
type: 'session_created',
|
|
@@ -1059,6 +1090,9 @@ export class RelayClient {
|
|
|
1059
1090
|
this.send({ type: 'idle', sessionId, payload: { usage } });
|
|
1060
1091
|
this.maybeGenerateTitle(sessionId);
|
|
1061
1092
|
};
|
|
1093
|
+
this.adapter.onFlushComplete = (sessionId) => {
|
|
1094
|
+
this.eventsWatcher?.resume(sessionId);
|
|
1095
|
+
};
|
|
1062
1096
|
this.adapter.onUsageUpdate = (sessionId, usage) => {
|
|
1063
1097
|
this.sessionManager.setUsage(sessionId, usage);
|
|
1064
1098
|
};
|
|
@@ -1174,7 +1208,7 @@ export class RelayClient {
|
|
|
1174
1208
|
// belong in the content stream and would create seq gaps on the arm.
|
|
1175
1209
|
const parsed = [];
|
|
1176
1210
|
for (const entry of logged) {
|
|
1177
|
-
if (RelayClient.
|
|
1211
|
+
if (!RelayClient.PERSISTENT_TYPES.has(entry.type))
|
|
1178
1212
|
continue;
|
|
1179
1213
|
try {
|
|
1180
1214
|
const msg = JSON.parse(entry.payload);
|
|
@@ -1344,9 +1378,15 @@ export class RelayClient {
|
|
|
1344
1378
|
// on reconnect and don't need per-session seq or replay logging.
|
|
1345
1379
|
const type = enriched.type;
|
|
1346
1380
|
const sessionId = enriched.sessionId;
|
|
1347
|
-
if (sessionId &&
|
|
1381
|
+
if (sessionId && RelayClient.PERSISTENT_TYPES.has(type)) {
|
|
1348
1382
|
enriched.seq = this.sessionManager.appendMessage(sessionId, type, JSON.stringify(enriched));
|
|
1349
1383
|
}
|
|
1384
|
+
// Advance the events watcher past any events the adapter just wrote,
|
|
1385
|
+
// so the watcher only picks up external changes (CLI, VS Code).
|
|
1386
|
+
// Only for persistent message types — transient metadata doesn't touch events.jsonl.
|
|
1387
|
+
if (sessionId && this.eventsWatcher && RelayClient.PERSISTENT_TYPES.has(type)) {
|
|
1388
|
+
this.eventsWatcher.skipToEnd(sessionId);
|
|
1389
|
+
}
|
|
1350
1390
|
if (this.keyManager) {
|
|
1351
1391
|
if (this.consumerKeys.size === 0) {
|
|
1352
1392
|
// No consumer keys at all — queue until a device registers
|