happy-imou-cloud 2.0.0 → 2.0.2

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.
Files changed (27) hide show
  1. package/dist/{BaseReasoningProcessor-BRCQXCZY.cjs → BaseReasoningProcessor-B6tJ_eL5.cjs} +96 -9
  2. package/dist/{BaseReasoningProcessor-BKLRCKTU.mjs → BaseReasoningProcessor-D8VhEbs2.mjs} +95 -10
  3. package/dist/{api-D7OK-mML.cjs → api-D2Njw9Im.cjs} +124 -6
  4. package/dist/{api-BGXYX0yH.mjs → api-MYhAGPLn.mjs} +122 -7
  5. package/dist/{command-G85giEAF.cjs → command-CVldr51S.cjs} +3 -3
  6. package/dist/{command-CnLtKtP-.mjs → command-nmK6O-ab.mjs} +3 -3
  7. package/dist/{index-C7Y0R-MI.mjs → index-B97L7qLD.mjs} +689 -229
  8. package/dist/{index-B_wlQBy2.cjs → index-Bg-YziG2.cjs} +691 -229
  9. package/dist/index.cjs +4 -4
  10. package/dist/index.mjs +4 -4
  11. package/dist/lib.cjs +1 -1
  12. package/dist/lib.d.cts +7 -0
  13. package/dist/lib.d.mts +7 -0
  14. package/dist/lib.mjs +1 -1
  15. package/dist/{persistence-DHgf1CTG.cjs → persistence-D_2GkJAO.cjs} +28 -6
  16. package/dist/{persistence-BA_unuca.mjs → persistence-Dkm7rm8k.mjs} +29 -7
  17. package/dist/{registerKillSessionHandler-C2-yHm1V.mjs → registerKillSessionHandler-5GbrO0FM.mjs} +6 -4
  18. package/dist/{registerKillSessionHandler-CLREXN11.cjs → registerKillSessionHandler-BAXmJQRt.cjs} +6 -4
  19. package/dist/{runClaude-CwAitpX-.cjs → runClaude-B-GNEkKg.cjs} +237 -45
  20. package/dist/{runClaude-uNC5Eym4.mjs → runClaude-Cii3R2Fv.mjs} +238 -46
  21. package/dist/{runCodex-B-05E-YZ.mjs → runCodex-C--ZwAhl.mjs} +636 -819
  22. package/dist/{runCodex-Cm0VTqw_.cjs → runCodex-CPHyGwj9.cjs} +639 -819
  23. package/dist/{runGemini-_biXvQAH.mjs → runGemini-CQp7Nuzn.mjs} +20 -16
  24. package/dist/{runGemini-CLWjwDYS.cjs → runGemini-DaDz1bzQ.cjs} +20 -16
  25. package/package.json +14 -15
  26. package/scripts/env-wrapper.cjs +11 -11
  27. package/scripts/setup-dev.cjs +4 -4
@@ -2,15 +2,15 @@
2
2
 
3
3
  var os = require('node:os');
4
4
  var node_crypto = require('node:crypto');
5
- var api = require('./api-D7OK-mML.cjs');
6
- var index = require('./index-B_wlQBy2.cjs');
5
+ var api = require('./api-D2Njw9Im.cjs');
6
+ var index = require('./index-Bg-YziG2.cjs');
7
7
  var future = require('./future-Dq4Ha1Dn.cjs');
8
8
  var types = require('./types-DVk3crez.cjs');
9
9
  var path = require('node:path');
10
10
  var promises = require('node:fs/promises');
11
11
  var fs = require('fs/promises');
12
12
  var ink = require('ink');
13
- var registerKillSessionHandler = require('./registerKillSessionHandler-CLREXN11.cjs');
13
+ var registerKillSessionHandler = require('./registerKillSessionHandler-BAXmJQRt.cjs');
14
14
  var React = require('react');
15
15
  var node_child_process = require('node:child_process');
16
16
  var node_readline = require('node:readline');
@@ -23,7 +23,7 @@ require('tweetnacl');
23
23
  require('expo-server-sdk');
24
24
  require('chalk');
25
25
  var node_util = require('node:util');
26
- var persistence = require('./persistence-DHgf1CTG.cjs');
26
+ var persistence = require('./persistence-D_2GkJAO.cjs');
27
27
  var node_http = require('node:http');
28
28
  require('fs');
29
29
  require('zod');
@@ -62,6 +62,7 @@ class Session {
62
62
  /** JavaScript runtime to use for spawning Claude Code (default: 'node') */
63
63
  jsRuntime;
64
64
  sessionId;
65
+ transcriptPath = null;
65
66
  mode = "local";
66
67
  thinking = false;
67
68
  /** Callbacks to be notified when session ID is found/changed */
@@ -115,15 +116,33 @@ class Session {
115
116
  * Updates internal state, syncs to API metadata, and notifies
116
117
  * all registered callbacks (e.g., SessionScanner) about the change.
117
118
  */
118
- onSessionFound = (sessionId) => {
119
+ onSessionFound = (sessionId, hookData) => {
120
+ const nextTranscriptPathRaw = hookData?.transcript_path ?? hookData?.transcriptPath;
121
+ const nextTranscriptPath = typeof nextTranscriptPathRaw === "string" ? nextTranscriptPathRaw : null;
122
+ const previousSessionId = this.sessionId;
123
+ const previousTranscriptPath = this.transcriptPath;
119
124
  this.sessionId = sessionId;
125
+ if (previousSessionId !== sessionId) {
126
+ this.transcriptPath = nextTranscriptPath;
127
+ } else if (nextTranscriptPath) {
128
+ this.transcriptPath = nextTranscriptPath;
129
+ }
120
130
  this.client.updateMetadata((metadata) => ({
121
131
  ...metadata,
122
- claudeSessionId: sessionId
132
+ claudeSessionId: sessionId,
133
+ claudeTranscriptPath: this.transcriptPath || void 0
123
134
  }));
124
- api.logger.debug(`[Session] Claude Code session ID ${sessionId} added to metadata`);
135
+ api.logger.debug(`[Session] Claude session info updated: sessionId=${sessionId}, transcriptPath=${this.transcriptPath ?? "none"}`);
136
+ const didTranscriptPathChange = nextTranscriptPath !== null && nextTranscriptPath !== previousTranscriptPath;
137
+ if (previousSessionId === sessionId && !didTranscriptPathChange) {
138
+ return;
139
+ }
140
+ const info = {
141
+ sessionId,
142
+ transcriptPath: this.transcriptPath
143
+ };
125
144
  for (const callback of this.sessionFoundCallbacks) {
126
- callback(sessionId);
145
+ callback(info);
127
146
  }
128
147
  };
129
148
  /**
@@ -146,6 +165,7 @@ class Session {
146
165
  */
147
166
  clearSessionId = () => {
148
167
  this.sessionId = null;
168
+ this.transcriptPath = null;
149
169
  api.logger.debug("[Session] Session ID cleared");
150
170
  };
151
171
  /**
@@ -250,9 +270,51 @@ class InvalidateSync {
250
270
 
251
271
  function startFileWatcher(file, onFileChange) {
252
272
  const abortController = new AbortController();
273
+ const parentDir = path.dirname(file);
274
+ const targetName = path.basename(file);
253
275
  void (async () => {
254
276
  while (true) {
255
277
  try {
278
+ try {
279
+ await fs.stat(file);
280
+ } catch (e) {
281
+ if (abortController.signal.aborted) {
282
+ return;
283
+ }
284
+ if (e?.code === "ENOENT") {
285
+ api.logger.debug(`[FILE_WATCHER] Waiting for file to exist: ${file}`);
286
+ const dirWatcher = fs.watch(parentDir, { persistent: true, signal: abortController.signal });
287
+ try {
288
+ await fs.stat(file);
289
+ } catch (err) {
290
+ if (err?.code !== "ENOENT") {
291
+ throw err;
292
+ }
293
+ for await (const event of dirWatcher) {
294
+ if (abortController.signal.aborted) {
295
+ return;
296
+ }
297
+ const name = typeof event?.filename === "string" ? String(event.filename) : null;
298
+ if (name && name !== targetName) {
299
+ continue;
300
+ }
301
+ try {
302
+ await fs.stat(file);
303
+ api.logger.debug(`[FILE_WATCHER] File appeared: ${file}`);
304
+ break;
305
+ } catch (nextErr) {
306
+ if (nextErr?.code === "ENOENT") {
307
+ continue;
308
+ }
309
+ throw nextErr;
310
+ }
311
+ }
312
+ }
313
+ } else {
314
+ throw e;
315
+ }
316
+ }
317
+ onFileChange(file);
256
318
  api.logger.debug(`[FILE_WATCHER] Starting watcher for ${file}`);
257
319
  const watcher = fs.watch(file, { persistent: true, signal: abortController.signal });
258
320
  for await (const event of watcher) {
@@ -282,19 +344,67 @@ const INTERNAL_CLAUDE_EVENT_TYPES = /* @__PURE__ */ new Set([
282
344
  "queue-operation"
283
345
  ]);
284
346
  async function createSessionScanner(opts) {
285
- const projectDir = index.getProjectPath(opts.workingDirectory);
347
+ const initialProjectDir = index.getProjectPath(opts.workingDirectory);
348
+ let projectDirOverride = null;
349
+ const sessionFileOverrides = /* @__PURE__ */ new Map();
350
+ const transcriptMissingWarningMs = opts.transcriptMissingWarningMs ?? 5e3;
351
+ const warnedMissingTranscripts = /* @__PURE__ */ new Set();
352
+ const missingTranscriptTimers = /* @__PURE__ */ new Map();
353
+ function effectiveProjectDir() {
354
+ return projectDirOverride ?? initialProjectDir;
355
+ }
356
+ function getSessionFilePath(sessionId) {
357
+ const override = sessionFileOverrides.get(sessionId);
358
+ return override ?? path.join(effectiveProjectDir(), `${sessionId}.jsonl`);
359
+ }
360
+ function scheduleTranscriptMissingWarning(sessionId) {
361
+ if (!opts.onTranscriptMissing) {
362
+ return;
363
+ }
364
+ if (!Number.isFinite(transcriptMissingWarningMs) || transcriptMissingWarningMs <= 0) {
365
+ return;
366
+ }
367
+ if (warnedMissingTranscripts.has(sessionId) || missingTranscriptTimers.has(sessionId)) {
368
+ return;
369
+ }
370
+ const timeoutId = setTimeout(async () => {
371
+ missingTranscriptTimers.delete(sessionId);
372
+ if (warnedMissingTranscripts.has(sessionId)) {
373
+ return;
374
+ }
375
+ const filePath = getSessionFilePath(sessionId);
376
+ try {
377
+ await promises.readFile(filePath, "utf-8");
378
+ return;
379
+ } catch {
380
+ }
381
+ warnedMissingTranscripts.add(sessionId);
382
+ try {
383
+ opts.onTranscriptMissing?.({ sessionId, filePath });
384
+ } catch (err) {
385
+ api.logger.debug("[SESSION_SCANNER] onTranscriptMissing callback threw:", err);
386
+ }
387
+ }, transcriptMissingWarningMs);
388
+ missingTranscriptTimers.set(sessionId, timeoutId);
389
+ }
286
390
  let finishedSessions = /* @__PURE__ */ new Set();
287
391
  let pendingSessions = /* @__PURE__ */ new Set();
288
392
  let currentSessionId = null;
289
393
  let watchers = /* @__PURE__ */ new Map();
290
394
  let processedMessageKeys = /* @__PURE__ */ new Set();
395
+ if (opts.sessionId && typeof opts.transcriptPath === "string" && opts.transcriptPath.trim()) {
396
+ const transcriptPath = opts.transcriptPath.trim();
397
+ sessionFileOverrides.set(opts.sessionId, transcriptPath);
398
+ projectDirOverride = path.dirname(transcriptPath);
399
+ }
291
400
  if (opts.sessionId) {
292
- let messages = await readSessionLog(projectDir, opts.sessionId);
401
+ let messages = await readSessionLog(getSessionFilePath(opts.sessionId));
293
402
  api.logger.debug(`[SESSION_SCANNER] Marking ${messages.length} existing messages as processed from session ${opts.sessionId}`);
294
403
  for (let m of messages) {
295
404
  processedMessageKeys.add(messageKey(m));
296
405
  }
297
406
  currentSessionId = opts.sessionId;
407
+ scheduleTranscriptMissingWarning(opts.sessionId);
298
408
  }
299
409
  const sync = new InvalidateSync(async () => {
300
410
  let sessions = [];
@@ -310,7 +420,7 @@ async function createSessionScanner(opts) {
310
420
  }
311
421
  }
312
422
  for (let session of sessions) {
313
- const sessionMessages = await readSessionLog(projectDir, session);
423
+ const sessionMessages = await readSessionLog(getSessionFilePath(session));
314
424
  let skipped = 0;
315
425
  let sent = 0;
316
426
  for (let file of sessionMessages) {
@@ -335,11 +445,27 @@ async function createSessionScanner(opts) {
335
445
  }
336
446
  }
337
447
  for (let p of sessions) {
338
- if (!watchers.has(p)) {
448
+ const desiredPath = getSessionFilePath(p);
449
+ const existing = watchers.get(p);
450
+ if (!existing) {
339
451
  api.logger.debug(`[SESSION_SCANNER] Starting watcher for session: ${p}`);
340
- watchers.set(p, startFileWatcher(path.join(projectDir, `${p}.jsonl`), () => {
341
- sync.invalidate();
342
- }));
452
+ watchers.set(p, {
453
+ filePath: desiredPath,
454
+ stop: startFileWatcher(desiredPath, () => {
455
+ sync.invalidate();
456
+ })
457
+ });
458
+ continue;
459
+ }
460
+ if (existing.filePath !== desiredPath) {
461
+ api.logger.debug(`[SESSION_SCANNER] Restarting watcher for session: ${p} (${existing.filePath} -> ${desiredPath})`);
462
+ existing.stop();
463
+ watchers.set(p, {
464
+ filePath: desiredPath,
465
+ stop: startFileWatcher(desiredPath, () => {
466
+ sync.invalidate();
467
+ })
468
+ });
343
469
  }
344
470
  }
345
471
  });
@@ -351,23 +477,55 @@ async function createSessionScanner(opts) {
351
477
  cleanup: async () => {
352
478
  clearInterval(intervalId);
353
479
  for (let w of watchers.values()) {
354
- w();
480
+ w.stop();
355
481
  }
356
482
  watchers.clear();
483
+ for (const timeoutId of missingTranscriptTimers.values()) {
484
+ clearTimeout(timeoutId);
485
+ }
486
+ missingTranscriptTimers.clear();
357
487
  await sync.invalidateAndAwait();
358
488
  sync.stop();
359
489
  },
360
- onNewSession: (sessionId) => {
490
+ onNewSession: (arg) => {
491
+ const sessionId = typeof arg === "string" ? arg : arg.sessionId;
492
+ const transcriptPathRaw = typeof arg === "string" ? null : arg.transcriptPath;
493
+ const transcriptPath = typeof transcriptPathRaw === "string" && transcriptPathRaw.trim() ? transcriptPathRaw.trim() : null;
494
+ let didUpdatePaths = false;
495
+ if (transcriptPath) {
496
+ const previousOverride = sessionFileOverrides.get(sessionId);
497
+ if (previousOverride !== transcriptPath) {
498
+ sessionFileOverrides.set(sessionId, transcriptPath);
499
+ didUpdatePaths = true;
500
+ }
501
+ const nextProjectDir = path.dirname(transcriptPath);
502
+ if (projectDirOverride !== nextProjectDir) {
503
+ projectDirOverride = nextProjectDir;
504
+ didUpdatePaths = true;
505
+ }
506
+ }
361
507
  if (currentSessionId === sessionId) {
362
- api.logger.debug(`[SESSION_SCANNER] New session: ${sessionId} is the same as the current session, skipping`);
508
+ if (didUpdatePaths) {
509
+ sync.invalidate();
510
+ } else {
511
+ api.logger.debug(`[SESSION_SCANNER] New session: ${sessionId} is the same as the current session, skipping`);
512
+ }
363
513
  return;
364
514
  }
365
515
  if (finishedSessions.has(sessionId)) {
366
- api.logger.debug(`[SESSION_SCANNER] New session: ${sessionId} is already finished, skipping`);
516
+ if (didUpdatePaths) {
517
+ sync.invalidate();
518
+ } else {
519
+ api.logger.debug(`[SESSION_SCANNER] New session: ${sessionId} is already finished, skipping`);
520
+ }
367
521
  return;
368
522
  }
369
523
  if (pendingSessions.has(sessionId)) {
370
- api.logger.debug(`[SESSION_SCANNER] New session: ${sessionId} is already pending, skipping`);
524
+ if (didUpdatePaths) {
525
+ sync.invalidate();
526
+ } else {
527
+ api.logger.debug(`[SESSION_SCANNER] New session: ${sessionId} is already pending, skipping`);
528
+ }
371
529
  return;
372
530
  }
373
531
  if (currentSessionId) {
@@ -375,6 +533,7 @@ async function createSessionScanner(opts) {
375
533
  }
376
534
  api.logger.debug(`[SESSION_SCANNER] New session: ${sessionId}`);
377
535
  currentSessionId = sessionId;
536
+ scheduleTranscriptMissingWarning(sessionId);
378
537
  sync.invalidate();
379
538
  }
380
539
  };
@@ -392,14 +551,13 @@ function messageKey(message) {
392
551
  throw Error();
393
552
  }
394
553
  }
395
- async function readSessionLog(projectDir, sessionId) {
396
- const expectedSessionFile = path.join(projectDir, `${sessionId}.jsonl`);
397
- api.logger.debug(`[SESSION_SCANNER] Reading session file: ${expectedSessionFile}`);
554
+ async function readSessionLog(sessionFilePath) {
555
+ api.logger.debug(`[SESSION_SCANNER] Reading session file: ${sessionFilePath}`);
398
556
  let file;
399
557
  try {
400
- file = await promises.readFile(expectedSessionFile, "utf-8");
558
+ file = await promises.readFile(sessionFilePath, "utf-8");
401
559
  } catch (error) {
402
- api.logger.debug(`[SESSION_SCANNER] Session file not found: ${expectedSessionFile}`);
560
+ api.logger.debug(`[SESSION_SCANNER] Session file not found: ${sessionFilePath}`);
403
561
  return [];
404
562
  }
405
563
  let lines = file.split("\n");
@@ -429,15 +587,25 @@ async function readSessionLog(projectDir, sessionId) {
429
587
  async function claudeLocalLauncher(session) {
430
588
  const scanner = await createSessionScanner({
431
589
  sessionId: session.sessionId,
590
+ transcriptPath: session.transcriptPath,
432
591
  workingDirectory: session.path,
433
592
  onMessage: (message) => {
434
593
  if (message.type !== "summary") {
435
594
  session.client.sendClaudeSessionMessage(message);
436
595
  }
596
+ },
597
+ onTranscriptMissing: () => {
598
+ session.client.sendSessionEvent({
599
+ type: "message",
600
+ message: "Claude transcript file not found yet, waiting for it to appear..."
601
+ });
437
602
  }
438
603
  });
439
- const scannerSessionCallback = (sessionId) => {
440
- scanner.onNewSession(sessionId);
604
+ const scannerSessionCallback = (info) => {
605
+ scanner.onNewSession({
606
+ sessionId: info.sessionId,
607
+ transcriptPath: info.transcriptPath
608
+ });
441
609
  };
442
610
  session.addSessionFoundCallback(scannerSessionCallback);
443
611
  let exitReason = null;
@@ -475,7 +643,6 @@ async function claudeLocalLauncher(session) {
475
643
  }
476
644
  const handleSessionStart = (sessionId) => {
477
645
  session.onSessionFound(sessionId);
478
- scanner.onNewSession(sessionId);
479
646
  };
480
647
  while (true) {
481
648
  if (exitReason) {
@@ -750,7 +917,7 @@ class AbortError extends Error {
750
917
  }
751
918
  }
752
919
 
753
- const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('runClaude-CwAitpX-.cjs', document.baseURI).href)));
920
+ const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('runClaude-B-GNEkKg.cjs', document.baseURI).href)));
754
921
  const __dirname$1 = path.join(__filename$1, "..");
755
922
  function getGlobalClaudeVersion() {
756
923
  try {
@@ -1424,7 +1591,7 @@ const systemPrompt = (() => {
1424
1591
 
1425
1592
  async function claudeRemote(opts) {
1426
1593
  let startFrom = opts.sessionId;
1427
- if (opts.sessionId && !index.claudeCheckSession(opts.sessionId, opts.path)) {
1594
+ if (opts.sessionId && !index.claudeCheckSession(opts.sessionId, opts.path, opts.transcriptPath)) {
1428
1595
  startFrom = null;
1429
1596
  }
1430
1597
  if (!startFrom && opts.claudeArgs) {
@@ -1526,11 +1693,14 @@ async function claudeRemote(opts) {
1526
1693
  updateThinking(true);
1527
1694
  const systemInit = message;
1528
1695
  if (systemInit.session_id) {
1529
- api.logger.debug(`[claudeRemote] Waiting for session file to be written to disk: ${systemInit.session_id}`);
1530
- const projectDir = index.getProjectPath(opts.path);
1531
- const found = await awaitFileExist(path.join(projectDir, `${systemInit.session_id}.jsonl`));
1696
+ const transcriptPath = opts.transcriptPath && opts.sessionId === systemInit.session_id ? opts.transcriptPath : path.join(index.getProjectPath(opts.path), `${systemInit.session_id}.jsonl`);
1697
+ api.logger.debug(`[claudeRemote] Waiting for session file to be written to disk: ${transcriptPath}`);
1698
+ const found = await awaitFileExist(transcriptPath);
1532
1699
  api.logger.debug(`[claudeRemote] Session file found: ${systemInit.session_id} ${found}`);
1533
- opts.onSessionFound(systemInit.session_id);
1700
+ opts.onSessionFound(systemInit.session_id, {
1701
+ transcript_path: transcriptPath,
1702
+ transcriptPath
1703
+ });
1534
1704
  }
1535
1705
  }
1536
1706
  if (message.type === "result") {
@@ -1983,11 +2153,21 @@ function formatClaudeMessageForInk(message, messageBuffer, onAssistantResult) {
1983
2153
  case "assistant": {
1984
2154
  const assistantMsg = message;
1985
2155
  if (assistantMsg.message && assistantMsg.message.content) {
1986
- messageBuffer.addMessage("\u{1F916} Assistant:", "assistant");
2156
+ let assistantHeaderShown = false;
1987
2157
  for (const block of assistantMsg.message.content) {
1988
- if (block.type === "text") {
2158
+ if (block.type === "thinking" && typeof block.thinking === "string" && block.thinking.trim()) {
2159
+ messageBuffer.addMessage(`[Thinking] ${block.thinking}`, "status");
2160
+ } else if (block.type === "text") {
2161
+ if (!assistantHeaderShown) {
2162
+ messageBuffer.addMessage("\u{1F916} Assistant:", "assistant");
2163
+ assistantHeaderShown = true;
2164
+ }
1989
2165
  messageBuffer.addMessage(block.text || "", "assistant");
1990
2166
  } else if (block.type === "tool_use") {
2167
+ if (!assistantHeaderShown) {
2168
+ messageBuffer.addMessage("\u{1F916} Assistant:", "assistant");
2169
+ assistantHeaderShown = true;
2170
+ }
1991
2171
  messageBuffer.addMessage(`\u{1F527} Tool: ${block.name}`, "tool");
1992
2172
  if (block.input) {
1993
2173
  const inputStr = JSON.stringify(block.input, null, 2);
@@ -2633,6 +2813,7 @@ async function claudeRemoteLauncher(session) {
2633
2813
  try {
2634
2814
  const remoteResult = await claudeRemote({
2635
2815
  sessionId: session.sessionId,
2816
+ transcriptPath: session.transcriptPath,
2636
2817
  path: session.path,
2637
2818
  allowedTools: session.allowedTools ?? [],
2638
2819
  mcpServers: session.mcpServers,
@@ -2666,9 +2847,9 @@ async function claudeRemoteLauncher(session) {
2666
2847
  }
2667
2848
  return null;
2668
2849
  },
2669
- onSessionFound: (sessionId) => {
2850
+ onSessionFound: (sessionId, data) => {
2670
2851
  sdkToLogConverter.updateSessionId(sessionId);
2671
- session.onSessionFound(sessionId);
2852
+ session.onSessionFound(sessionId, data);
2672
2853
  },
2673
2854
  onThinkingChange: session.onThinkingChange,
2674
2855
  claudeEnvVars: session.claudeEnvVars,
@@ -2857,13 +3038,20 @@ async function startHookServer(options) {
2857
3038
  }
2858
3039
  clearTimeout(timeout);
2859
3040
  const body = Buffer.concat(chunks).toString("utf-8");
2860
- api.logger.debug("[hookServer] Received session hook:", body);
2861
3041
  let data = {};
2862
3042
  try {
2863
3043
  data = JSON.parse(body);
2864
3044
  } catch (parseError) {
2865
3045
  api.logger.debug("[hookServer] Failed to parse hook data as JSON:", parseError);
2866
3046
  }
3047
+ api.logger.debug("[hookServer] Received session hook", {
3048
+ sessionId: data.session_id || data.sessionId || null,
3049
+ transcriptPath: data.transcript_path || data.transcriptPath || null,
3050
+ cwd: data.cwd,
3051
+ hookEventName: data.hook_event_name,
3052
+ source: data.source,
3053
+ bodyLength: body.length
3054
+ });
2867
3055
  const sessionId = data.session_id || data.sessionId;
2868
3056
  if (sessionId) {
2869
3057
  api.logger.debug(`[hookServer] Session hook received session ID: ${sessionId}`);
@@ -2985,7 +3173,15 @@ async function runClaude(credentials, options = {}) {
2985
3173
  lifecycleStateSince: Date.now(),
2986
3174
  flavor: "claude"
2987
3175
  };
2988
- const response = await api$1.getOrCreateSession({ tag: sessionTag, metadata, state });
3176
+ let response = null;
3177
+ try {
3178
+ response = await api$1.getOrCreateSession({ tag: sessionTag, metadata, state });
3179
+ } catch (error) {
3180
+ if (!api.isAuthenticationRequiredError(error)) {
3181
+ throw error;
3182
+ }
3183
+ api.logger.debug("[START] Falling back to local/offline mode after authentication failure");
3184
+ }
2989
3185
  if (!response) {
2990
3186
  let offlineSessionId = null;
2991
3187
  const reconnection = api.startOfflineReconnection({
@@ -3057,11 +3253,7 @@ async function runClaude(credentials, options = {}) {
3057
3253
  onSessionHook: (sessionId, data) => {
3058
3254
  api.logger.debug(`[START] Session hook received: ${sessionId}`, data);
3059
3255
  if (currentSession) {
3060
- const previousSessionId = currentSession.sessionId;
3061
- if (previousSessionId !== sessionId) {
3062
- api.logger.debug(`[START] Claude session ID changed: ${previousSessionId} -> ${sessionId}`);
3063
- currentSession.onSessionFound(sessionId);
3064
- }
3256
+ currentSession.onSessionFound(sessionId, data);
3065
3257
  }
3066
3258
  }
3067
3259
  });