diff --git a/CHANGELOG.md b/CHANGELOG.md
index df48bbc7..323dcf69 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,4 @@
+- Fixed process start errors and hang timeouts now logged to the IDE log file at SEVERE level
- Added hang detection: configurable timeout (default 60 s) kills the process and shows an error if no PTY output is received after launch; set to 0 to disable
- Fixed authentication for profiles with the "Claude API" connection type: the API key is now correctly recognised by Claude Code on session start
- Added capability of changing the profile storage directory and sharing a single directory with several profiles
diff --git a/pom.xml b/pom.xml
index 35a46541..574403db 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
io.github.nbclaudecodegui
netbeans-claude-code-gui
- 0.21.29-SNAPSHOT
+ 0.21.34-SNAPSHOT
nbm
Netbeans Claude Code GUI
NetBeans plugin that provides a GUI for Claude Code CLI — run claude code sessions directly inside the IDE.
diff --git a/src/main/java/io/github/nbclaudecodegui/controller/ClaudeSessionController.java b/src/main/java/io/github/nbclaudecodegui/controller/ClaudeSessionController.java
index 4c4eb232..dfe80c14 100644
--- a/src/main/java/io/github/nbclaudecodegui/controller/ClaudeSessionController.java
+++ b/src/main/java/io/github/nbclaudecodegui/controller/ClaudeSessionController.java
@@ -73,6 +73,7 @@ public final class ClaudeSessionController {
private ClaudeProcess claudeProcess;
private PtyTtyConnector connector;
+ private java.io.File workingDir;
/** Polls screen state every 500 ms; owned here to allow proper teardown. */
private javax.swing.Timer statusTimer;
@@ -200,6 +201,7 @@ public void startProcess(java.io.File dir, String profileName, String extraCliAr
SessionMode mode, String resumeSessionId,
JediTermWidget widget) throws IOException {
String tag = "[" + dir.getName() + "] ";
+ workingDir = dir;
claudeProcess = new ClaudeProcess();
ClaudeProfile profile = ClaudeProfileStore.findByName(profileName);
customModelIds = profile != null ? new ArrayList<>(profile.getCustomModels()) : List.of();
@@ -979,7 +981,7 @@ public void setHangCallback(java.util.function.BiConsumer callba
* @param timeoutSec the configured timeout that elapsed (for the error message)
*/
private void handleHang(int timeoutSec) {
- LOG.warning("Hang detected: no PTY output received within " + timeoutSec + " s — killing process");
+ LOG.severe("Hang detected in " + workingDir + ": no PTY output received within " + timeoutSec + " s — killing process");
String command = claudeProcess != null ? claudeProcess.getLastCommand() : "";
stopProcess();
java.util.function.BiConsumer cb = hangCallback;
diff --git a/src/main/java/io/github/nbclaudecodegui/process/ClaudeProcess.java b/src/main/java/io/github/nbclaudecodegui/process/ClaudeProcess.java
index d44b97a1..92c5f9c4 100644
--- a/src/main/java/io/github/nbclaudecodegui/process/ClaudeProcess.java
+++ b/src/main/java/io/github/nbclaudecodegui/process/ClaudeProcess.java
@@ -178,7 +178,7 @@ public PtyProcess start(String workingDir, ClaudeProfile profile, String extraCl
appendSessionFlags(cmd, workingDir, env, extraCliArgs, mode, resumeSessionId);
lastCommand = toShellCommand(cmd);
- LOG.info("Claude command: " + lastCommand);
+ LOG.info("Claude command: " + lastCommand + " (dir: " + workingDir + ")");
PtyProcessBuilder builder = new PtyProcessBuilder(cmd.toArray(new String[0]))
.setEnvironment(env)
.setDirectory(workingDir)
diff --git a/src/main/java/io/github/nbclaudecodegui/ui/ClaudeSessionTab.java b/src/main/java/io/github/nbclaudecodegui/ui/ClaudeSessionTab.java
index 85164ad8..8938baa3 100644
--- a/src/main/java/io/github/nbclaudecodegui/ui/ClaudeSessionTab.java
+++ b/src/main/java/io/github/nbclaudecodegui/ui/ClaudeSessionTab.java
@@ -25,6 +25,7 @@
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.List;
+import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.Box;
@@ -665,6 +666,7 @@ private void startSession(File dir, String profileName, String extraCliArgs,
try {
controller.startProcess(dir, profileName, extraCliArgs, mode, resumeSessionId, widget);
} catch (IOException ex) {
+ LOG.log(Level.SEVERE, "Claude process failed to start in " + dir, ex);
String command = controller.getLastAttemptedCommand();
String errorMsg = ex.getMessage() != null ? ex.getMessage() : ex.getClass().getSimpleName();
showStartError(command, errorMsg);