-
Notifications
You must be signed in to change notification settings - Fork 69
Open
Description
What
Add intelligent browser tab closing after plan approval/deny, with environment-aware behavior:
- Local Claude Code: Auto-close tab after decision (1-2s delay for UX confirmation)
- Local OpenCode: Auto-close tab after decision (1-2s delay for UX confirmation)
- Remote sessions: Keep tab open (already no browser opened, but if user opens manually, don't close)
Why
Current Problem: Browser tabs remain open indefinitely after plan decisions, creating friction:
- Manual cleanup required: Users must manually close tabs after each plan review
- Tab accumulation: Frequent plan reviews lead to many open tabs
- Broken workflow flow: The UI says "Return to your Claude Code terminal" but the tab stays open, requiring manual action
- Inconsistent with expectations: Users expect the tool to disappear after completing its purpose
User Impact: Every plan approval requires an extra manual step (closing tab) that breaks the seamless workflow.
How
Phase 1: Environment Detection (packages/server/remote.ts)
// Add new detection function
export function getPlanEnvironment(): 'claude-code' | 'opencode' | 'unknown' {
// Check for Claude Code hook environment
if (process.env.CLAIDE_HOOK !== undefined) {
return 'claude-code'
}
// Check for OpenCode plugin environment
if (process.env.OPENCODE_PLUGIN !== undefined) {
return 'opencode'
}
// Fallback: detect via hook file presence or command context
return 'unknown'
}Phase 2: Frontend Closing Logic (packages/ui/components/Viewer.tsx)
// After approve/deny success:
const shouldCloseTab = !isRemoteSession && environment !== 'unknown'
if (shouldCloseTab) {
setTimeout(() => {
// Show brief "closing..." message
setClosingState(true)
// Attempt close (note: window.close() only works for window.open() windows)
window.close()
// Fallback: show message if close blocked
setTimeout(() => {
if (!window.closed) {
setCloseFailed(true)
}
}, 500)
}, 1500) // 1.5s delay to show success message
}Phase 3: Graceful Fallback UI
If window.close() is blocked by browser security (script-opened windows restriction):
{closeFailed && (
<div className="banner">
You can safely close this tab and return to your terminal.
</div>
)}Implementation Files
- packages/server/remote.ts: Add
getPlanEnvironment()function - packages/ui/components/Viewer.tsx: Add close logic after approve/deny
- packages/ui/types.ts: Add
PlanEnvironmenttype - packages/server/index.ts: Pass environment to frontend via
/api/planresponse
Browser Security Note
window.close() only works on windows opened by window.open(). Since we use open/xdg-open/start, the browser may block closing. Fallback UI is essential.
Acceptance Criteria
- Local Claude Code: Tab closes 1.5s after approval
- Local OpenCode: Tab closes 1.5s after approval
- Remote sessions: No close attempt (tab stays open if manually opened)
- Fallback message shown if browser blocks
window.close() - Success message visible for at least 1s before close attempt
- Environment detection works for both plugins
Open Questions
- Should there be a user setting to disable auto-close? (e.g.,
PLANNOTATOR_NO_AUTO_CLOSE=1) - Should the delay be configurable? Currently hardcoded 1500ms
Related: Current behavior shows "Return to your Claude Code terminal" message but doesn't actually close the tab.
PaulRBerg, kylerm42 and ovitrif
Metadata
Metadata
Assignees
Labels
No labels