diff --git a/CHANGELOG.md b/CHANGELOG.md
index 897340e3..74379d5d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,4 @@
+- Fixed Default profile settings not saving in Tools → Options → Profiles (https://github.com/nbclaudecodegui/NetbeansClaudeCodeGui/issues/31)
- Fixed "Open with Claude Code" context menu not applying Default profile settings (API key, proxy, Extra CLI args, etc.) (https://github.com/nbclaudecodegui/NetbeansClaudeCodeGui/issues/23)
- Added Advanced tab in Tools → Options → Claude Code with Debug mode, Hang timeout, and a new "Enable MCP integration" toggle (disabling it skips the --mcp-config flag while hooks remain active)
- Fixed process start errors and hang timeouts now logged to the IDE log file at SEVERE level
diff --git a/pom.xml b/pom.xml
index ec59dc01..91d144ab 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
io.github.nbclaudecodegui
netbeans-claude-code-gui
- 0.20.6-SNAPSHOT
+ 0.20.7-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/settings/ClaudeProfileStore.java b/src/main/java/io/github/nbclaudecodegui/settings/ClaudeProfileStore.java
index eda7dd48..659af658 100644
--- a/src/main/java/io/github/nbclaudecodegui/settings/ClaudeProfileStore.java
+++ b/src/main/java/io/github/nbclaudecodegui/settings/ClaudeProfileStore.java
@@ -34,6 +34,9 @@ public final class ClaudeProfileStore {
/** NbPreferences key under which the JSON array is stored. */
public static final String KEY_PROFILES = "profiles";
+ /** NbPreferences key under which the full Default profile JSON is stored. */
+ private static final String KEY_DEFAULT_PROFILE = "defaultProfile";
+
private static final ObjectMapper MAPPER = new ObjectMapper()
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
private static final TypeReference> LIST_TYPE =
@@ -56,7 +59,19 @@ private ClaudeProfileStore() {}
public static List getProfiles() {
List result = new ArrayList<>();
ClaudeProfile def = ClaudeProfile.createDefault();
- def.setExtraCliArgs(ClaudeCodePreferences.getDefaultExtraCliArgs());
+ String defJson = NbPreferences.forModule(ClaudeProfileStore.class)
+ .get(KEY_DEFAULT_PROFILE, null);
+ if (defJson != null) {
+ try {
+ def = MAPPER.readValue(defJson, ClaudeProfile.class);
+ } catch (Exception e) {
+ LOG.warning("Could not parse stored Default profile JSON, using defaults. Cause: " + e);
+ def.setExtraCliArgs(ClaudeCodePreferences.getDefaultExtraCliArgs());
+ }
+ } else {
+ // back-compat: read only extraCliArgs from old key
+ def.setExtraCliArgs(ClaudeCodePreferences.getDefaultExtraCliArgs());
+ }
result.add(def);
String json = NbPreferences.forModule(ClaudeProfileStore.class)
@@ -117,10 +132,12 @@ public static ClaudeProfile findByName(String name) {
*/
public static void saveProfiles(List profiles) {
List toSave = new ArrayList<>();
+ ClaudeProfile defaultProfile = null;
if (profiles != null) {
for (ClaudeProfile p : profiles) {
if (p.isDefault()) {
- ClaudeCodePreferences.setDefaultExtraCliArgs(p.getExtraCliArgs());
+ defaultProfile = p;
+ ClaudeCodePreferences.setDefaultExtraCliArgs(p.getExtraCliArgs()); // back-compat
} else {
toSave.add(p);
}
@@ -130,6 +147,11 @@ public static void saveProfiles(List profiles) {
String json = MAPPER.writeValueAsString(toSave);
NbPreferences.forModule(ClaudeProfileStore.class)
.put(KEY_PROFILES, json);
+ if (defaultProfile != null) {
+ String defJson = MAPPER.writeValueAsString(defaultProfile);
+ NbPreferences.forModule(ClaudeProfileStore.class)
+ .put(KEY_DEFAULT_PROFILE, defJson);
+ }
LOG.fine(() -> "Saved " + toSave.size() + " profile(s): " + profileNames(toSave));
} catch (Exception e) {
LOG.severe("Could not serialise profiles: " + e.getMessage());
diff --git a/src/test/java/io/github/nbclaudecodegui/settings/ClaudeProfileStoreTest.java b/src/test/java/io/github/nbclaudecodegui/settings/ClaudeProfileStoreTest.java
index 3428db72..ca70cbe6 100644
--- a/src/test/java/io/github/nbclaudecodegui/settings/ClaudeProfileStoreTest.java
+++ b/src/test/java/io/github/nbclaudecodegui/settings/ClaudeProfileStoreTest.java
@@ -228,6 +228,50 @@ void defaultProfile_extraCliArgs_roundTrip() {
}
}
+ // -------------------------------------------------------------------------
+ // Default profile all-fields round-trip (issue #31)
+ // -------------------------------------------------------------------------
+
+ @Test
+ void defaultProfile_allFields_roundTrip() {
+ try {
+ ClaudeProfile def = ClaudeProfile.createDefault();
+ def.setApiKey("sk-ant-default");
+ def.setExtraCliArgs("--verbose");
+ ClaudeProfileStore.saveProfiles(java.util.List.of(def));
+
+ ClaudeProfile loaded = ClaudeProfileStore.getDefaultProfile();
+ assertTrue(loaded.isDefault());
+ assertEquals("sk-ant-default", loaded.getApiKey(),
+ "Default profile apiKey must survive save/load");
+ assertEquals("--verbose", loaded.getExtraCliArgs(),
+ "Default profile extraCliArgs must survive save/load");
+ } catch (Exception e) {
+ org.junit.jupiter.api.Assumptions.assumeTrue(false, "NbPreferences not available");
+ }
+ }
+
+ @Test
+ void namedProfile_allFields_roundTrip() {
+ try {
+ ClaudeProfile p = ClaudeProfile.createNamed("Work");
+ p.setApiKey("sk-ant-work");
+ p.setExtraCliArgs("--model claude-3-5-sonnet-20241022");
+ ClaudeProfileStore.saveProfiles(java.util.List.of(p));
+
+ List loaded = ClaudeProfileStore.getProfiles();
+ assertEquals(2, loaded.size(), "Expected Default + Work");
+ ClaudeProfile work = loaded.get(1);
+ assertEquals("Work", work.getName());
+ assertEquals("sk-ant-work", work.getApiKey(),
+ "Named profile apiKey must survive save/load");
+ assertEquals("--model claude-3-5-sonnet-20241022", work.getExtraCliArgs(),
+ "Named profile extraCliArgs must survive save/load");
+ } catch (Exception e) {
+ org.junit.jupiter.api.Assumptions.assumeTrue(false, "NbPreferences not available");
+ }
+ }
+
// -------------------------------------------------------------------------
// extraCliArgs serialization round-trip
// -------------------------------------------------------------------------