diff --git a/CHANGELOG.md b/CHANGELOG.md
index 51005576..9319dc6f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,4 @@
+- Fixed an unnumbered choice prompt (e.g. the "trust this folder" dialog) showing every line of the surrounding text as a bogus selectable option instead of just the real choices, and losing the "Yes" option entirely by merging it into the "No" option's description
- Fixed ChatGPT Subscription token refresh hanging indefinitely (freezing the session) when a profile's custom HTTPS/HTTP proxy hostname was slow or unreachable to resolve via DNS
- Fixed a choice-dialog prompt (e.g. a Bash-command permission prompt) flickering and repeatedly resizing when Claude's response text re-wrapped to a slightly different width after the dialog first appeared
diff --git a/pom.xml b/pom.xml
index 98a0e36c..cf0d2edd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
io.github.nbplugins
netbeans-plugin-claude-code-gui
- 1.3.33-SNAPSHOT
+ 1.3.34-SNAPSHOT
nbm
Netbeans Plugin 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/nbplugins/claudecodegui/process/ScreenContentDetector.java b/src/main/java/io/github/nbplugins/claudecodegui/process/ScreenContentDetector.java
index 658a8ca0..0b078d99 100644
--- a/src/main/java/io/github/nbplugins/claudecodegui/process/ScreenContentDetector.java
+++ b/src/main/java/io/github/nbplugins/claudecodegui/process/ScreenContentDetector.java
@@ -330,10 +330,20 @@ Optional detectUnnumberedChoiceMenu(List screenLines) {
int stopRow = -1; // row where we stopped (first non-option line above options)
int i = footerRow - 1;
+ boolean firstBlock = true;
while (i >= 0) {
- // Skip blank lines between blocks
- while (i >= 0 && screenLines.get(i).isBlank()) i--;
- if (i < 0) break;
+ if (screenLines.get(i).isBlank()) {
+ if (!firstBlock) {
+ // A blank line after at least one option block was already collected marks
+ // the end of the option list (real menu items are never blank-separated from
+ // each other) — stop here instead of skipping through unrelated prose above.
+ stopRow = i;
+ break;
+ }
+ // Allow a single blank gap between the footer and the first (bottom-most) option.
+ while (i >= 0 && screenLines.get(i).isBlank()) i--;
+ if (i < 0) break;
+ }
String raw = screenLines.get(i);
String trimmed = raw.trim();
@@ -360,12 +370,16 @@ Optional detectUnnumberedChoiceMenu(List screenLines) {
break;
}
- // Collect this block: desc = current line, main = line above (if non-blank)
+ // Collect this block: desc = current line, main = line above (if non-blank).
+ // Only pair the two lines when the lower one carries the metadata separator "·"
+ // (e.g. "23 hours ago · bugfix/new-kafka · 1MB") — the shape real 2-line unnumbered
+ // entries use. Without that marker, treat the line as its own single-line option so
+ // two genuinely separate options (e.g. "No, exit" / "Yes, I trust this folder") don't
+ // get fused into one.
String desc = trimmed;
- i--;
String main = null;
- if (i >= 0 && !screenLines.get(i).isBlank()) {
- String raw2 = screenLines.get(i);
+ if (desc.indexOf('·') >= 0 && i - 1 >= 0 && !screenLines.get(i - 1).isBlank()) {
+ String raw2 = screenLines.get(i - 1);
String trimmed2 = raw2.trim();
if (!isSeparatorLine(trimmed2) && !OPTION_LINE.matcher(trimmed2).matches()
&& !isBoxDrawingLine(trimmed2) && !trimmed2.contains("\u2315")
@@ -374,6 +388,7 @@ Optional detectUnnumberedChoiceMenu(List screenLines) {
i--;
}
}
+ i--;
if (main == null) {
// Single-line block — treat as main with no description
main = desc;
@@ -381,6 +396,7 @@ Optional detectUnnumberedChoiceMenu(List screenLines) {
}
blockMainLines.add(0, main);
blockDescLines.add(0, desc);
+ firstBlock = false;
}
if (blockMainLines.size() < 2) return Optional.empty();
diff --git a/src/test/resources/io/github/nbplugins/claudecodegui/process/screen-content-detector/detect-choice-menu/trust-folder-prompt.expectedRes.json b/src/test/resources/io/github/nbplugins/claudecodegui/process/screen-content-detector/detect-choice-menu/trust-folder-prompt.expectedRes.json
new file mode 100644
index 00000000..c2d19aef
--- /dev/null
+++ b/src/test/resources/io/github/nbplugins/claudecodegui/process/screen-content-detector/detect-choice-menu/trust-folder-prompt.expectedRes.json
@@ -0,0 +1,8 @@
+{
+ "text": "Security guide",
+ "options": [
+ {"display": "No, exit", "response": "ARROW:0"},
+ {"display": "Yes, I trust this folder", "response": "ARROW:1"}
+ ],
+ "defaultOptionIndex": 0
+}
diff --git a/src/test/resources/io/github/nbplugins/claudecodegui/process/screen-content-detector/detect-choice-menu/trust-folder-prompt.src.txt b/src/test/resources/io/github/nbplugins/claudecodegui/process/screen-content-detector/detect-choice-menu/trust-folder-prompt.src.txt
new file mode 100644
index 00000000..fdd88c0a
--- /dev/null
+++ b/src/test/resources/io/github/nbplugins/claudecodegui/process/screen-content-detector/detect-choice-menu/trust-folder-prompt.src.txt
@@ -0,0 +1,21 @@
+─────────────────────────────────────────────────────────────────────────────────────────────────────────
+ Accessing workspace:
+
+ /home/oleg/git/sigma/SigmaOperationStorage
+
+ Quick safety check: Is this a project you created or one you trust? (Like your own code, a well-known
+ open source project, or work from your team). If not, take a moment to review what's in this folder
+ first.
+
+ Claude Code'll be able to read, edit, and execute files here.
+
+ ⚠ This folder pre-approves 2 tool permissions in .claude/settings.local.json:
+ mcp__netbeans__show_markdown and mcp__netbeans__show_markdown_file
+ These will apply without asking. Only proceed if you trust this configuration.
+
+ Security guide
+
+ ❯ No, exit
+ Yes, I trust this folder
+
+ Enter to confirm · Esc to cancel