Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
- Reorganized General and Advanced settings tabs: moved technical settings (hang timeout, MCP port, Enable MCP integration, session list limit, debug mode) to Advanced
- Fixed prompt area being collapsible to zero height by dragging the divider
- Fixed terminal scrolling to the beginning and locking when a choice/confirmation menu appears (https://github.com/nbclaudecodegui/NetbeansClaudeCodeGui/issues/22)
- Added a setting to control whether the choice menu grabs keyboard focus (https://github.com/nbclaudecodegui/NetbeansClaudeCodeGui/issues/20)
Expand Down
Binary file modified docs/screenshots/settings-advanced.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/settings-general.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 10 additions & 10 deletions docs/user-manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -337,15 +337,10 @@ Open **Tools → Options → Claude Code** in NetBeans.

| Setting | Default | Description |
|---------|---------|-------------|
| Claude CLI path | (empty) | Absolute path to the `claude` executable. Leave empty to use the system `PATH`. |
| MCP server port | 28991 | Port for the internal MCP SSE server. Change only if 28991 conflicts. Requires IDE restart. |
| History max depth | 200 | Maximum number of history entries kept per working directory. |
| History TTL (days) | 0 | Number of days after which history entries expire. 0 = keep forever. |
| Send prompt key | Ctrl+Enter | Key combination that sends the prompt from the input area. |
| Insert newline key | Enter | Key combination that inserts a newline in the input area. The send and newline keys are configured independently but cannot be set to the same value. |
| Start new session when opening with Claude | Off (Continue last) | Checked → always start a **New session** when opening with the project context menu or when NetBeans restores a closed session tab on restart. Unchecked → **Continue last**. |
| Session list limit | 30 | Maximum number of past sessions shown in the session selector table. |
| Session tab dock position | Editor area | Where the Claude Code session tab is docked when first opened. Choices: Editor area, Right side, Left side top, Left side bottom, Bottom dock. |
| Send prompt key | Ctrl+Enter | Key combination that sends the prompt from the input area. |
| Insert newline key | Enter | Key combination that inserts a newline in the input area. The send and newline keys are configured independently but cannot be set to the same value. |
| Open file diff in a separate tab | Off | Opens the diff panel in a new IDE tab instead of embedding it in the session tab. |
| File diff tab dock position | Editor area | Where the File Diff tab is docked when opened as a separate tab. Enabled only when "Open file diff in a separate tab" is checked. |
| Show markdown preview for .md files in diff | On | Shows a rendered markdown preview alongside the raw diff for `.md` files. |
Expand All @@ -358,9 +353,14 @@ Open **Tools → Options → Claude Code** in NetBeans.

| Setting | Default | Description |
|---------|---------|-------------|
| Debug mode | Off | Enables verbose logging of all Claude I/O to the NetBeans log file and the Output window. |
| Claude CLI path | (empty) | Absolute path to the `claude` executable. Leave empty to use the system `PATH`. |
| Hang timeout (seconds) | 60 | Kill the process if no PTY output is received within this many seconds after launch. Set to 0 to disable. |
| MCP server port | 28991 | Port for the internal MCP SSE server. Change only if 28991 conflicts. Requires IDE restart. |
| Enable MCP integration | On | When unchecked, the `--mcp-config` flag is not passed to `claude`. Hooks (PreToolUse) are always configured regardless of this setting. Disable only if MCP causes issues. |
| History max depth | 200 | Maximum number of history entries kept per working directory. |
| History TTL (days) | 0 | Number of days after which history entries expire. 0 = keep forever. |
| Session list limit | 30 | Maximum number of past sessions shown in the session selector table. |
| Debug mode | Off | Enables verbose logging of all Claude I/O to the NetBeans log file and the Output window. |

### Favorites tab

Expand Down Expand Up @@ -671,7 +671,7 @@ As you move the cursor or change the selection in any open editor, the plugin au

If Claude says a tool is unavailable (e.g. "I don't have access to `getWorkspaceFolders`"):

1. Check that no other application is using the MCP server port (**Tools → Options → Claude Code → General → MCP server port**, default: 28991). Change the port if needed and restart the IDE.
1. Check that no other application is using the MCP server port (**Tools → Options → Claude Code → Advanced → MCP server port**, default: 28991). Change the port if needed and restart the IDE.
2. Enable **Debug mode** (**Tools → Options → Claude Code → Advanced**) and check the log file (`~/.netbeans/<version>/var/log/messages.log`) for `MCP SSE server started on port`.

---
Expand All @@ -691,7 +691,7 @@ For example: `~/.netbeans/28/var/log/messages.log`

| Symptom | Likely cause | Fix |
|---------|-------------|-----|
| Session tab does not open | `claude` not found on PATH | Set the full path in **Tools → Options → Claude Code → General → Claude CLI path** |
| Session tab does not open | `claude` not found on PATH | Set the full path in **Tools → Options → Claude Code → Advanced → Claude CLI path** |
| Diff panel shows but Accept/Decline have no effect | Claude timed out waiting for the hook response (600 s limit) | Respond to the diff panel within ~9 minutes; if this happens regularly, check for blocking processes |
| Claude asked a question but the Choice Menu panel did not appear | The plugin did not recognise the prompt format | Switch to the terminal area and answer directly by typing |
| Choice Menu appeared but Claude did not ask anything (false trigger) | The plugin mis-detected a numbered list as a menu | Dismiss the panel with **Esc** or ignore it; Claude will continue on its own |
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>io.github.nbclaudecodegui</groupId>
<artifactId>netbeans-claude-code-gui</artifactId>
<version>0.22.13-SNAPSHOT</version>
<version>0.22.16-SNAPSHOT</version>
<packaging>nbm</packaging>
<name>Netbeans Claude Code GUI</name>
<description>NetBeans plugin that provides a GUI for Claude Code CLI — run claude code sessions directly inside the IDE.</description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,45 +137,28 @@ private JPanel buildGeneralPanel() {
JPanel form = new JPanel(new GridBagLayout());
int row = 0;

// --- executable path ---
form.add(new JLabel("Claude CLI path:"), gbc(0, row, false));
executablePathField = new JTextField(30);
executablePathField.setToolTipText("Leave empty to detect 'claude' from PATH");
form.add(executablePathField, gbcFill(1, row));
JButton browseButton = new JButton("Browse\u2026");
browseButton.addActionListener(e -> {
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
executablePathField.setText(
chooser.getSelectedFile().getAbsolutePath());
}
});
form.add(browseButton, gbc(2, row, false));
row++;

// --- MCP port ---
form.add(new JLabel("MCP server port:"), gbc(0, row, false));
mcpPortSpinner = new JSpinner(new SpinnerNumberModel(
ClaudeCodePreferences.DEFAULT_MCP_PORT, 1024, 65535, 1));
mcpPortSpinner.setToolTipText("Port for the NetBeans MCP SSE server (restart required)");
form.add(mcpPortSpinner, gbc(1, row, false));
row++;

// --- history max depth ---
form.add(new JLabel("History max depth:"), gbc(0, row, false));
historyMaxDepthSpinner = new JSpinner(new SpinnerNumberModel(
ClaudeCodePreferences.DEFAULT_HISTORY_MAX_DEPTH, 1, 2000, 10));
historyMaxDepthSpinner.setToolTipText("Maximum number of history entries to keep per project");
form.add(historyMaxDepthSpinner, gbc(1, row, false));
// --- context-menu session mode ---
startNewSessionCheck = new javax.swing.JCheckBox("Start new session when opening with Claude");
GridBagConstraints cmGbc = new GridBagConstraints();
cmGbc.gridx = 0; cmGbc.gridy = row;
cmGbc.gridwidth = 3;
cmGbc.anchor = GridBagConstraints.WEST;
cmGbc.insets = new Insets(8, 8, 4, 8);
form.add(startNewSessionCheck, cmGbc);
row++;

// --- history TTL ---
form.add(new JLabel("History TTL (days, 0 = keep forever):"), gbc(0, row, false));
historyTtlDaysSpinner = new JSpinner(new SpinnerNumberModel(
ClaudeCodePreferences.DEFAULT_HISTORY_TTL_DAYS, 0, 3650, 1));
historyTtlDaysSpinner.setToolTipText("Delete history entries older than this many days (0 = keep forever)");
form.add(historyTtlDaysSpinner, gbc(1, row, false));
// --- session tab dock position ---
form.add(new JLabel("Session tab dock position:"), gbc(0, row, false));
dockModeCombo = new javax.swing.JComboBox<>(
DockMode.labels(ClaudeCodePreferences.DEFAULT_SESSION_DOCK_MODE));
dockModeCombo.setToolTipText("Where to dock the Claude Code session tab when opening it");
form.add(dockModeCombo, gbc(1, row, false));
GridBagConstraints hSpacer = new GridBagConstraints();
hSpacer.gridx = 2; hSpacer.gridy = row;
hSpacer.weightx = 1.0;
hSpacer.fill = GridBagConstraints.HORIZONTAL;
hSpacer.insets = new Insets(0, 0, 0, 8);
form.add(new JLabel(""), hSpacer);
row++;

// --- send key ---
Expand Down Expand Up @@ -205,32 +188,6 @@ private JPanel buildGeneralPanel() {
newlineRadios.get(val).addActionListener(e -> syncExclusion(val, false));
}

// --- context-menu session mode ---
startNewSessionCheck = new javax.swing.JCheckBox("Start new session when opening with Claude");
GridBagConstraints cmGbc = new GridBagConstraints();
cmGbc.gridx = 0; cmGbc.gridy = row;
cmGbc.gridwidth = 3;
cmGbc.anchor = GridBagConstraints.WEST;
cmGbc.insets = new Insets(4, 8, 4, 8);
form.add(startNewSessionCheck, cmGbc);
row++;

// --- session list limit ---
form.add(new JLabel("Session list limit:"), gbc(0, row, false));
sessionListLimitSpinner = new JSpinner(new SpinnerNumberModel(
ClaudeCodePreferences.DEFAULT_SESSION_LIST_LIMIT, 1, 500, 5));
sessionListLimitSpinner.setToolTipText("Maximum number of sessions shown in the session list");
form.add(sessionListLimitSpinner, gbc(1, row, false));
row++;

// --- session tab dock position ---
form.add(new JLabel("Session tab dock position:"), gbc(0, row, false));
dockModeCombo = new javax.swing.JComboBox<>(
DockMode.labels(ClaudeCodePreferences.DEFAULT_SESSION_DOCK_MODE));
dockModeCombo.setToolTipText("Where to dock the Claude Code session tab when opening it");
form.add(dockModeCombo, gbc(1, row, false));
row++;

// --- diff in session ---
diffInSessionCheck = new javax.swing.JCheckBox("Open file diff in a separate tab");
GridBagConstraints diffGbc = new GridBagConstraints();
Expand Down Expand Up @@ -298,14 +255,21 @@ private JPanel buildAdvancedPanel() {
JPanel form = new JPanel(new GridBagLayout());
int row = 0;

// --- debug mode ---
debugCheckBox = new javax.swing.JCheckBox("Debug mode (log all claude I/O to NetBeans log and output area)");
GridBagConstraints dbgGbc = new GridBagConstraints();
dbgGbc.gridx = 0; dbgGbc.gridy = row;
dbgGbc.gridwidth = 2;
dbgGbc.anchor = GridBagConstraints.WEST;
dbgGbc.insets = new Insets(8, 8, 4, 8);
form.add(debugCheckBox, dbgGbc);
// --- executable path ---
form.add(new JLabel("Claude CLI path:"), gbc(0, row, false));
executablePathField = new JTextField(30);
executablePathField.setToolTipText("Leave empty to detect 'claude' from PATH");
form.add(executablePathField, gbcFill(1, row));
JButton browseButton = new JButton("Browse\u2026");
browseButton.addActionListener(e -> {
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
executablePathField.setText(
chooser.getSelectedFile().getAbsolutePath());
}
});
form.add(browseButton, gbc(2, row, false));
row++;

// --- hang timeout ---
Expand All @@ -318,6 +282,14 @@ private JPanel buildAdvancedPanel() {
form.add(hangTimeoutSpinner, hangSpinnerGbc);
row++;

// --- MCP port ---
form.add(new JLabel("MCP server port:"), gbc(0, row, false));
mcpPortSpinner = new JSpinner(new SpinnerNumberModel(
ClaudeCodePreferences.DEFAULT_MCP_PORT, 1024, 65535, 1));
mcpPortSpinner.setToolTipText("Port for the NetBeans MCP SSE server (restart required)");
form.add(mcpPortSpinner, gbc(1, row, false));
row++;

// --- MCP enabled ---
mcpEnabledCheckBox = new javax.swing.JCheckBox("Enable MCP integration");
GridBagConstraints mcpGbc = new GridBagConstraints();
Expand All @@ -331,16 +303,52 @@ private JPanel buildAdvancedPanel() {
JLabel mcpDesc = new JLabel("<html><small>When disabled, the --mcp-config flag is not passed to claude. Hooks are always configured.</small></html>");
GridBagConstraints mcpDescGbc = new GridBagConstraints();
mcpDescGbc.gridx = 0; mcpDescGbc.gridy = row;
mcpDescGbc.gridwidth = 2;
mcpDescGbc.gridwidth = 3;
mcpDescGbc.fill = GridBagConstraints.HORIZONTAL;
mcpDescGbc.weightx = 1.0;
mcpDescGbc.anchor = GridBagConstraints.WEST;
mcpDescGbc.insets = new Insets(0, 28, 4, 8);
form.add(mcpDesc, mcpDescGbc);
row++;

// --- history max depth ---
form.add(new JLabel("History max depth:"), gbc(0, row, false));
historyMaxDepthSpinner = new JSpinner(new SpinnerNumberModel(
ClaudeCodePreferences.DEFAULT_HISTORY_MAX_DEPTH, 1, 2000, 10));
historyMaxDepthSpinner.setToolTipText("Maximum number of history entries to keep per project");
form.add(historyMaxDepthSpinner, gbc(1, row, false));
row++;

// --- history TTL ---
form.add(new JLabel("History TTL (days, 0 = keep forever):"), gbc(0, row, false));
historyTtlDaysSpinner = new JSpinner(new SpinnerNumberModel(
ClaudeCodePreferences.DEFAULT_HISTORY_TTL_DAYS, 0, 3650, 1));
historyTtlDaysSpinner.setToolTipText("Delete history entries older than this many days (0 = keep forever)");
form.add(historyTtlDaysSpinner, gbc(1, row, false));
row++;

// --- session list limit ---
form.add(new JLabel("Session list limit:"), gbc(0, row, false));
sessionListLimitSpinner = new JSpinner(new SpinnerNumberModel(
ClaudeCodePreferences.DEFAULT_SESSION_LIST_LIMIT, 1, 500, 5));
sessionListLimitSpinner.setToolTipText("Maximum number of sessions shown in the session list");
form.add(sessionListLimitSpinner, gbc(1, row, false));
row++;

// --- debug mode ---
debugCheckBox = new javax.swing.JCheckBox("Debug mode (log all claude I/O to NetBeans log and output area)");
GridBagConstraints dbgGbc = new GridBagConstraints();
dbgGbc.gridx = 0; dbgGbc.gridy = row;
dbgGbc.gridwidth = 2;
dbgGbc.anchor = GridBagConstraints.WEST;
dbgGbc.insets = new Insets(8, 8, 4, 8);
form.add(debugCheckBox, dbgGbc);
row++;

// spacer
GridBagConstraints spacer = new GridBagConstraints();
spacer.gridx = 0; spacer.gridy = row;
spacer.gridwidth = 2; spacer.weighty = 1.0;
spacer.gridwidth = 3; spacer.weighty = 1.0;
spacer.fill = GridBagConstraints.VERTICAL;
form.add(new JPanel(), spacer);

Expand Down
Loading