clay-server 2.9.3-beta.3 → 2.9.3-beta.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/bin/cli.js CHANGED
@@ -23,7 +23,11 @@ var net = require("net");
23
23
 
24
24
  // Detect dev mode — dev and prod use separate daemon files so they can run simultaneously
25
25
  var _isDev = (process.argv[1] && path.basename(process.argv[1]) === "clay-dev") || process.argv.includes("--dev");
26
- if (_isDev) process.env.CLAY_DEV = "1";
26
+ if (_isDev) {
27
+ process.env.CLAY_DEV = "1";
28
+ // Preserve console output in dev mode so logs remain readable
29
+ console.clear = function() {};
30
+ }
27
31
 
28
32
  var { loadConfig, saveConfig, configPath, socketPath, logPath, ensureConfigDir, isDaemonAlive, isDaemonAliveAsync, generateSlug, clearStaleConfig, loadClayrc, saveClayrc, readCrashInfo } = require("../lib/config");
29
33
  var { sendIPCCommand } = require("../lib/ipc");
package/lib/project.js CHANGED
@@ -3047,6 +3047,7 @@ function createProjectContext(opts) {
3047
3047
  stopAllDirWatches();
3048
3048
  // Abort all active sessions
3049
3049
  sm.sessions.forEach(function (session) {
3050
+ session.destroying = true;
3050
3051
  if (session.abortController) {
3051
3052
  try { session.abortController.abort(); } catch (e) {}
3052
3053
  }
package/lib/public/app.js CHANGED
@@ -2557,6 +2557,10 @@ import { initAdmin, checkAdminAccess } from './modules/admin.js';
2557
2557
  break;
2558
2558
 
2559
2559
  case "info":
2560
+ if (msg.text && !msg.project && !msg.cwd) {
2561
+ addSystemMessage(msg.text, false);
2562
+ break;
2563
+ }
2560
2564
  projectName = msg.project || msg.cwd;
2561
2565
  if (msg.slug) currentSlug = msg.slug;
2562
2566
  try { localStorage.setItem("clay-project-name-" + (currentSlug || "default"), projectName); } catch (e) {}
@@ -2994,10 +2998,6 @@ import { initAdmin, checkAdminAccess } from './modules/admin.js';
2994
2998
  addSystemMessage(msg.text, false);
2995
2999
  break;
2996
3000
 
2997
- case "info":
2998
- addSystemMessage(msg.text, false);
2999
- break;
3000
-
3001
3001
  case "error":
3002
3002
  setActivity(null);
3003
3003
  addSystemMessage(msg.text, true);
package/lib/sdk-bridge.js CHANGED
@@ -626,13 +626,27 @@ function createSDKBridge(opts) {
626
626
  for await (var msg of session.queryInstance) {
627
627
  processSDKMessage(session, msg);
628
628
  }
629
+ // Stream ended normally after a task stop — no "result" message was sent,
630
+ // so the session is still marked as processing. Send interrupted feedback.
631
+ if (session.isProcessing && session.taskStopRequested) {
632
+ session.isProcessing = false;
633
+ onProcessingChanged();
634
+ sendAndRecord(session, { type: "info", text: "Interrupted \u00b7 What should Claude do instead?" });
635
+ sendAndRecord(session, { type: "done", code: 0 });
636
+ sm.broadcastSessionList();
637
+ }
629
638
  } catch (err) {
630
639
  if (session.isProcessing) {
631
640
  session.isProcessing = false;
632
641
  onProcessingChanged();
633
- if (err.name === "AbortError" || (session.abortController && session.abortController.signal.aborted)) {
634
- sendAndRecord(session, { type: "info", text: "Interrupted \u00b7 What should Claude do instead?" });
635
- sendAndRecord(session, { type: "done", code: 0 });
642
+ if (err.name === "AbortError" || (session.abortController && session.abortController.signal.aborted) || session.taskStopRequested) {
643
+ if (!session.destroying) {
644
+ sendAndRecord(session, { type: "info", text: "Interrupted \u00b7 What should Claude do instead?" });
645
+ sendAndRecord(session, { type: "done", code: 0 });
646
+ }
647
+ } else if (session.destroying) {
648
+ // Suppress error messages during shutdown
649
+ console.log("[sdk-bridge] Suppressing stream error during shutdown for session " + session.localId);
636
650
  } else {
637
651
  var errDetail = err.message || String(err);
638
652
  if (err.stderr) errDetail += "\nstderr: " + err.stderr;
@@ -681,6 +695,7 @@ function createSDKBridge(opts) {
681
695
  session.queryInstance = null;
682
696
  session.messageQueue = null;
683
697
  session.abortController = null;
698
+ session.taskStopRequested = false;
684
699
  session.pendingPermissions = {};
685
700
  session.pendingAskUser = {};
686
701
  }
@@ -1007,11 +1022,17 @@ function createSDKBridge(opts) {
1007
1022
  async function stopTask(taskId) {
1008
1023
  var session = sm.getActiveSession();
1009
1024
  if (!session || !session.queryInstance) return;
1025
+ session.taskStopRequested = true;
1010
1026
  try {
1011
1027
  await session.queryInstance.stopTask(taskId);
1012
1028
  } catch (e) {
1013
1029
  console.error("[sdk-bridge] stopTask error:", e.message);
1014
1030
  }
1031
+ // SDK stopTask doesn't reliably stop the sub-agent, so abort the entire
1032
+ // session as a fallback to ensure the process actually stops.
1033
+ if (session.abortController) {
1034
+ session.abortController.abort();
1035
+ }
1015
1036
  }
1016
1037
 
1017
1038
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clay-server",
3
- "version": "2.9.3-beta.3",
3
+ "version": "2.9.3-beta.4",
4
4
  "description": "Web UI for Claude Code. Any device. Push notifications.",
5
5
  "bin": {
6
6
  "clay-server": "./bin/cli.js",