Skip to content

simplify prompt bar controls - #2183

Open
kevinjosethomas wants to merge 20 commits into
mainfrom
feat/ui-prompt-bar
Open

simplify prompt bar controls#2183
kevinjosethomas wants to merge 20 commits into
mainfrom
feat/ui-prompt-bar

Conversation

@kevinjosethomas

@kevinjosethomas kevinjosethomas commented Sep 10, 2026

Copy link
Copy Markdown
Member

Show muted conversation detail status directly above the prompt, with recap on the left and ellipsis truncation reserving room for the status. A blank line separates this row from the chat; there is no gap before the prompt surface. Empty extension widgets add no extra separator.

  • Show the provider-free model ID and lowercase reasoning effort as glm-5.3:high, followed by fast mode when active and live context usage, in the bottom-right tray. Keep manage navigation on the bottom left.
  • Remove unsolicited feature-discovery tips during agent runs, startup example prompts, and the fresh-chat shortcut hint. Explicit help and picker instructions remain available.
  • Keep the lower tray and subagent summary visible during slash-command autocomplete; hide them only for actual pickers and restore them on dismissal. Show depth only for subagent sessions.
  • Keep slash autocomplete completion-only: Tab or Enter completes, and a subsequent Enter runs the command.
  • Preserve drafts, custom editor headers, narrow layouts, configurable detail shortcuts, and live context tracking through streaming and compaction.

Validation: 216 focused prompt layout, startup, status/context usage, and recap regression tests passed after the final position swap; 61 startup tests, including 24 composed layout combinations and actual autocomplete/picker overlay transitions, passed after the final visibility fix; npm run check passed.

UI proposals (no ticket)

Note

Simplify prompt bar controls by removing feature hints and reworking context line

  • Removes the entire feature-discovery hint system: deletes FeatureHintComponent, all hint deck/timer/state from InteractiveMode, startup-hint selection, and related tests
  • Adds PromptContextLine component that renders a blank row plus a context row with left-aligned Recap: text and right-aligned conversation-detail status
  • Reworks tray labels: getModelContextLabel combines provider-stripped model ID, reasoning level, priority status, and context usage into one dim label; getTrayLocationLabel drops model and shortcut text and only shows depth and manage hint
  • Fixes slash-command completion in CombinedAutocompleteProvider.applyCompletion and Editor keyboard handler: no-argument commands complete without trailing space; argument-taking commands keep the separator; confirming an already-complete slash command now submits normally
  • Suppresses tray labels and SubagentSummaryLine output while an inline picker or overlay is open via isInlinePickerOpen
  • Behavioral Change: startup prompt hints and editor placeholders no longer appear; model slash command no longer takes a free-form argument; tray no longer shows exit/follow-up labels during picker interaction; slash-command completions no longer append a trailing space for no-argument commands

Macroscope summarized eb2ab0f.

@github-actions

github-actions Bot commented Sep 10, 2026

Copy link
Copy Markdown

Prime Agent performance — partial

PR eb2ab0f3 compared with main 1eee2938.

Overall: 0 regressed · 0 improved · 13 no clear change · 4 unavailable.

Metric Main This PR Change
Cold startup 2,761.4 ms
Warm startup 1,645.6 ms
Installation 25.35 s 25.77 s ≈ +0.42 s (+1.67%)
Compressed release artifacts 11.12 MB 11.09 MB ≈ -0.03 MB (-0.24%)
Installed footprint 597.49 MB
Idle memory, summed RSS 1,088.78 MB

Python runtime

Metric Main This PR Change
Python kernel startup 117.1 ms 119.1 ms ≈ +2.0 ms (+1.71%)
Python cell round trip 0.462 ms 0.474 ms ≈ +0.012 ms (+2.67%)
Empty bash command 9.8 ms 10.2 ms ≈ +0.3 ms (+3.37%)
Bash git status 14.7 ms 14.8 ms ≈ +0.021 ms (+0.14%)
Bash 32 KiB output 10.3 ms 10.6 ms ≈ +0.3 ms (+2.77%)
35 cells / 9 shell calls 146.5 ms 145.1 ms ≈ -1.4 ms (-0.95%)
Python interrupt to done 1.412 ms 1.412 ms ≈ +0.00024 ms (+0.02%)
Python state snapshot 24.6 ms 23.7 ms ≈ -0.9 ms (-3.85%)
Python state restore 330.1 ms 333.0 ms ≈ +2.9 ms (+0.87%)
Python idle RSS 37.20 MB 36.99 MB ≈ -0.21 MB (-0.56%)
Python RSS after pandas workload 98.38 MB 99.20 MB ≈ +0.82 MB (+0.84%)

Sandbox cost: ~$0.1739 — no inference calls.
Run, logs, and downloadable raw results

Methodology and samples

Main resolved at 2026-09-11T00:12:58.641557+00:00. Harness 1eee2938.
Linux x64, 4 vCPU, 8 GB RAM, 20 GB disk; region us.
Image: node:24-bookworm@sha256:be23f54a88d34e8824c741b19b91064094f92c1c97b194144bfc8b50d67258e2.
Stock tools, skills, daemon, and Python bootstrap enabled; fresh homes and a fixed Git fixture.
Onboarding is dismissed; the editor starts without a selected model or submitted prompt.
Medians shown. Arrows require a 20% timing/memory change plus absolute floors and IQR.
These practical noise floors are not a statistical significance test.
Cold means stopped Prime processes; OS filesystem caches are not flushed.
No model requests or credentials. Installation excludes build/setup time.
Installer tarballs use loopback; npm/Python downloads use the network with fresh caches.
Artifact size counts release tarballs; footprint after first use includes registry packages.
MB is decimal. Summed RSS can double-count shared pages; PSS is recorded when available.
Provisioning, setup, and build durations are recorded separately in the raw results.
Kernel probes use the installed JSONL runtime, outside the TUI/TypeScript host.
Per trial: 50 Python cells, 5 calls per shell case, and one 35-cell mix (9 git status calls).
Cell/shell values are batch means; other runtime timings are single operations.
State fixture: a 10,000-row × 8-column integer DataFrame and a 10,000-integer list.
Restore runs in a fresh kernel, including pandas imports; kernel startup is excluded.
Kernel RSS covers the isolated Python process; loaded RSS follows the pandas workload.
Costs estimate full sandbox lifetimes at configured rates, including setup and build.
Budget target: $1; not a billing cap. Checks are informational.

Metric Main successful/attempted PR successful/attempted Main spread PR spread
Cold startup 10/10 0/10 IQR 66.6 ms
Warm startup 10/10 0/10 IQR 64.3 ms
Installation 3/3 3/3 range 0.94 s range 0.74 s
Compressed release artifacts 1/1 1/1
Installed footprint 1/1 0/0
Idle memory, summed RSS 10/10 0/0 IQR 78.27 MB
Python kernel startup 10/10 10/10 IQR 5.7 ms IQR 4.3 ms
Python cell round trip 10/10 10/10 IQR 0.014 ms IQR 0.045 ms
Empty bash command 10/10 10/10 IQR 0.4 ms IQR 0.3 ms
Bash git status 10/10 10/10 IQR 0.7 ms IQR 0.7 ms
Bash 32 KiB output 10/10 10/10 IQR 0.1 ms IQR 0.6 ms
35 cells / 9 shell calls 10/10 10/10 IQR 5.1 ms IQR 6.2 ms
Python interrupt to done 10/10 10/10 IQR 0.120 ms IQR 0.150 ms
Python state snapshot 10/10 10/10 IQR 2.0 ms IQR 0.5 ms
Python state restore 10/10 10/10 IQR 15.5 ms IQR 10.9 ms
Python idle RSS 10/10 10/10 IQR 2.17 MB IQR 2.15 MB
Python RSS after pandas workload 10/10 10/10 IQR 2.56 MB IQR 2.36 MB

Failures:

  • PR cold trial 0: TimeoutError: Timed out waiting for the expected terminal state
  • PR cold trial 1: TimeoutError: Timed out waiting for the expected terminal state
  • PR cold trial 2: TimeoutError: Timed out waiting for the expected terminal state
  • PR cold trial 3: TimeoutError: Timed out waiting for the expected terminal state
  • PR cold trial 4: TimeoutError: Timed out waiting for the expected terminal state
  • PR cold trial 5: TimeoutError: Timed out waiting for the expected terminal state
  • PR cold trial 6: TimeoutError: Timed out waiting for the expected terminal state
  • PR cold trial 7: TimeoutError: Timed out waiting for the expected terminal state
  • PR cold trial 8: TimeoutError: Timed out waiting for the expected terminal state
  • PR cold trial 9: TimeoutError: Timed out waiting for the expected terminal state
  • PR warm trial 0: TimeoutError: Timed out waiting for the expected terminal state
  • PR warm trial 1: TimeoutError: Timed out waiting for the expected terminal state
  • PR warm trial 2: TimeoutError: Timed out waiting for the expected terminal state
  • PR warm trial 3: TimeoutError: Timed out waiting for the expected terminal state
  • PR warm trial 4: TimeoutError: Timed out waiting for the expected terminal state
  • PR warm trial 5: TimeoutError: Timed out waiting for the expected terminal state
  • PR warm trial 6: TimeoutError: Timed out waiting for the expected terminal state
  • PR warm trial 7: TimeoutError: Timed out waiting for the expected terminal state
  • PR warm trial 8: TimeoutError: Timed out waiting for the expected terminal state
  • PR warm trial 9: TimeoutError: Timed out waiting for the expected terminal state

Comment thread packages/coding-agent/src/modes/interactive/interactive-mode.ts Outdated
kevinjosethomas added a commit that referenced this pull request Sep 10, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

private readonly getLocationLabel: () => string | undefined = () => undefined,
private readonly getContextLabel: () => string | undefined = () => undefined,
private readonly getOverrideLabel: () => string | undefined = () => undefined,
private readonly getPickerOpen: () => boolean = () => false,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hidden summary remains focusable

Low Severity

render now returns no rows while a picker is open, but isSelectable still treats the summary as available. focusSubagentSummary only gates on isSelectable and getTrayOverrideLabel, and the override label is now forced off during pickers, so focus can move onto an invisible row and swallow input.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 9aff542. Configure here.

Comment thread packages/coding-agent/.changes/ui-prompt-bar.md Outdated
);
const isSlashCommand = slashContext?.kind === "name" && slashContext.prefix === prefix && command !== undefined;
if (isSlashCommand) {
const takesArgument =

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium src/autocomplete.ts:401

Commands that provide getArgumentCompletions but omit takesArgument are completed as /deploy without a separator, so typing an argument produces /deployprod and the command's argument completion cannot trigger. The fallback must treat getArgumentCompletions as indicating that the command takes an argument.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @packages/tui/src/autocomplete.ts around line 401:

Commands that provide `getArgumentCompletions` but omit `takesArgument` are completed as `/deploy` without a separator, so typing an argument produces `/deployprod` and the command's argument completion cannot trigger. The fallback must treat `getArgumentCompletions` as indicating that the command takes an argument.

Evidence trail:
Commit 9391a70b8561e05374b4083d8548f2640d71e956: packages/tui/src/autocomplete.ts:231-239, 345-360, 396-415; packages/tui/src/slash-command-context.ts:14-35; packages/coding-agent/docs/extensions.md:1423-1439; packages/coding-agent/src/modes/interactive/interactive-mode.ts:1377-1387.

this.autocompletePrefix.startsWith("/"));
const shouldSubmitSlashCommand =
isSlashCommandCompletion && slashContext?.kind === "name" && slashContext.isAtPromptStart;
const isTypedExactSlashCommand = this.isSlashNameCompletionAtPromptStart();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium components/editor.ts:756

Accepting an already typed no-argument slash command such as /model with Tab leaves it in the editor instead of submitting it, so the user must press Enter again. The tui.input.tab branch applies the completion, cancels autocomplete, and unconditionally returns; apply the same exact-match check used for Enter and fall through to submission when the completion is a no-op.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @packages/tui/src/components/editor.ts around line 756:

Accepting an already typed no-argument slash command such as `/model` with `Tab` leaves it in the editor instead of submitting it, so the user must press `Enter` again. The `tui.input.tab` branch applies the completion, cancels autocomplete, and unconditionally returns; apply the same exact-match check used for `Enter` and fall through to submission when the completion is a no-op.

Evidence trail:
Reviewed commit 9391a70. Inspect: packages/tui/src/components/editor.ts:732-750,753-780,857-870; packages/tui/src/autocomplete.ts:399-415; packages/tui/test/editor.test.ts:2242-2264,2356-2374. Commands: git_diff MERGE_BASE REVIEWED_COMMIT -- packages/tui/src/components/editor.ts; git_grep -F 'isSlashNameCompletionAtPromptStart' -- packages/tui/src/components/editor.ts.

}
} else {
this.cancelAutocomplete();
if (!isTypedExactSlashCommand || !completedExistingText) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium components/editor.ts:774

Pressing Enter on a partially typed no-argument slash command inserts the completion but does not submit it, so /mod becomes /model and requires a second Enter. The completedExistingText check rejects any completion that changes the line; submit should instead follow the existing slash-command-at-prompt-start and selected.takesArgument rules.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @packages/tui/src/components/editor.ts around line 774:

Pressing Enter on a partially typed no-argument slash command inserts the completion but does not submit it, so `/mod` becomes `/model` and requires a second Enter. The `completedExistingText` check rejects any completion that changes the line; submit should instead follow the existing slash-command-at-prompt-start and `selected.takesArgument` rules.

Evidence trail:
Reviewed commit 6176c0c: `packages/tui/src/components/editor.ts:753-780`; `packages/tui/src/autocomplete.ts:394-415`; `packages/tui/test/editor.test.ts:2266-2288`. Compare behavior with `git diff MERGE_BASE REVIEWED_COMMIT -- packages/tui/src/components/editor.ts packages/tui/test/editor.test.ts`.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0735532. Configure here.

private renderWidgets(): void {
if (!this.widgetContainerAbove || !this.widgetContainerBelow) return;
this.renderWidgetContainer(this.widgetContainerAbove, this.extensionWidgetsAbove, true, true);
this.renderWidgetContainer(this.widgetContainerAbove, this.extensionWidgetsAbove, false, true);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Always-false widget spacer parameter

Low Severity

Both renderWidgetContainer call sites now pass false for spacerWhenEmpty, so that flag no longer varies. The parameter and the empty-container spacer branch are leftover ceremony after the extra blank line was removed.

Additional Locations (1)
Fix in Cursor Fix in Web

Triggered by project rule: Review rules

Reviewed by Cursor Bugbot for commit 0735532. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant