feat: Add initialCommand parameter to TabbedTerminal - #318
Open
Shivang (kshivang) wants to merge 947 commits into
Open
feat: Add initialCommand parameter to TabbedTerminal#318Shivang (kshivang) wants to merge 947 commits into
Shivang (kshivang) wants to merge 947 commits into
Conversation
- Update release notes to include Homebrew install instructions - Add update-homebrew job that auto-updates kshivang/homebrew-bossterm - Calculates SHA256 and updates Cask formula on each release Requires HOMEBREW_TAP_TOKEN secret (PAT with repo scope) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Requires approval from @kshivang before release runs. Only master and dev branches can trigger releases. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat: CI/CD, Homebrew tap, and multiple fixes
feat: CI/CD, Homebrew tap, code signing & fixes
- Add vanniktech maven-publish plugin for KMP publishing - Configure bossterm-core for Maven Central + GitHub Packages - Configure bossterm-compose for Maven Central + GitHub Packages - Add publish-libraries job to release workflow - Libraries will publish on each release Artifacts: - ai.rever.bossterm:bossterm-core - ai.rever.bossterm:bossterm-compose Requires secrets: - MAVEN_CENTRAL_USERNAME - MAVEN_CENTRAL_PASSWORD - GPG_SIGNING_KEY - GPG_SIGNING_KEY_ID - GPG_SIGNING_PASSPHRASE 🤖 Generated with [Claude Code](https://claude.com/claude-code)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
- Add vanniktech maven-publish plugin for KMP publishing - Configure bossterm-core for Maven Central + GitHub Packages - Configure bossterm-compose for Maven Central + GitHub Packages - Add publish-libraries job to release workflow - Libraries will publish on each release Artifacts: - ai.rever.bossterm:bossterm-core - ai.rever.bossterm:bossterm-compose Requires secrets: - MAVEN_CENTRAL_USERNAME - MAVEN_CENTRAL_PASSWORD - GPG_SIGNING_KEY - GPG_SIGNING_KEY_ID - GPG_SIGNING_PASSPHRASE 🤖 Generated with [Claude Code](https://claude.com/claude-code)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
- Add Homebrew installation instructions - Add DMG download section - Add Maven Central, JitPack, GitHub Packages dependency setup - Add release and Maven Central badges 🤖 Generated with [Claude Code](https://claude.com/claude-code)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
These targets were declared but had no actual source implementations, causing the CI build to fail during artifact generation. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
compose-ui is Desktop-only. The core library (bossterm-core-mpp) still supports Android. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Maven Central doesn't support snapshot versions. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Allows manual triggering to publish to GitHub Packages, Maven Central, or both. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix: Add GPG signing env vars to GitHub Packages publish step
- Rename parameters to match supertype (isCursorVisible, scrollRegionSize, bracketedPasteModeEnabled) - Replace Divider with HorizontalDivider - Replace Icons.Filled.KeyboardArrow* with Icons.AutoMirrored.Filled.* - Replace deprecated PtyProcess.exec with PtyProcessBuilder 🤖 Generated with [Claude Code](https://claude.com/claude-code)
- Migrate ScrollbarAdapter from deprecated v1 to v2 API - TerminalScrollbarAdapter: Use contentSize/viewportSize properties - AlwaysVisibleScrollbar: Update to v2 interface with Double types - Fix parameter naming to match supertype interfaces - equals(o: Any?) → equals(other: Any?) in 9 classes - sendBytes(bytes:) → sendBytes(response:) in TerminalStarter - designateCharacterSet(charset:) → designateCharacterSet(ch:) in BossTerminal - resize(columns:) → resize(width:) in BossTerminal.DefaultTabulator - subSequence(start:, end:) → subSequence(startIndex:, endIndex:) in CharBuffer - Remove redundant code - Remove redundant else branch in exhaustive when statement (BossTerminal) - Remove deprecated resize(Dimension) methods from TtyConnector - Remove @deprecated from Questioner interface (actively used) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat: Linux Distribution Support (Snap, Deb, RPM)
On Linux, the app was always showing version 1.0.0 because there's no Info.plist like on macOS. The Version.kt code falls back to system property bossterm.version which was never set. Add -Dbossterm.version to JVM args in native distribution config so the correct version is available at runtime on all platforms. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The approval gate should be on the first job (prepare-version) which handles version bumping and commits, not on build-macos. This ensures no release actions happen without approval. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix: Pass version to JVM args for Linux runtime detection
Previously, prepare-version computed the version but each build job recalculated it from VERSION + BUILD_NUMBER. This caused mismatches when triggered by tags (tag version != run_number). Now: - prepare-version computes version once - All build jobs receive APP_VERSION env var - Gradle uses APP_VERSION if set, else falls back to local computation - Ensures artifact names match actual binary versions 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Add comprehensive About section as the last tab in settings navigation: - Application info (version, release channel) - System info (OS, architecture, Java version/vendor) - Clickable links (GitHub repo, releases, issues) - Keyboard shortcuts table with platform-aware keys - License information (Apache 2.0 + LGPLv3) - Acknowledgments (JediTerm, Compose Multiplatform, ICU4J, Meslo Nerd Font) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
- Derive release channel from Version.preRelease (shows "beta" for pre-release) - Show "(dev)" indicator for fallback version 1.0.0 - Add Java Runtime name to system info (identifies JBR, OpenJDK, etc.) - Log errors when browser opening fails 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Working directory inheritance now works without shell OSC 7 configuration: - Added getPid() and getWorkingDirectory() to ProcessHandle interface - Implemented process CWD detection via /proc/<pid>/cwd (Linux) and lsof (macOS) - TabController.getActiveWorkingDirectory() now falls back to process query - Split panes also use the fallback mechanism The setting "Inherit Working Directory" now works immediately without requiring shell integration setup. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
New tabs now always start in home directory. Only splits inherit working directory (controlled by splitInheritWorkingDirectory setting). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat: Add About BossTerm section to settings
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The snapcraft.yaml had a hardcoded version that wasn't being updated during releases. Added a step to update the version using sed before building the snap. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
…-reactive Problem: Cursor state used mutableStateOf() which triggered immediate Compose recomposition, while requestRedraw() was delayed through debouncing. This caused two renders per cursor update - one with new cursor + old snapshot (flicker). Solution: Changed cursor state from reactive mutableStateOf to @volatile plain variables. Now only redrawTrigger controls recomposition, and cursor is captured atomically with snapshot in remember() blocks. Changes: - ComposeTerminalDisplay.kt: Cursor state now uses @volatile vars with snapshot getters - ProperTerminal.kt: Cursor captured inside remember(currentTrigger) blocks Result: Single atomic render per update, no partial state = no flickering. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
… output Changed ModelListener to use requestRedraw() instead of requestImmediateRedraw() to enable adaptive debouncing (16ms interactive, 50ms high-volume) for buffer changes. Also fixed debouncing logic to always wait before rendering, ensuring clear+write sequences coalesce into a single frame instead of showing intermediate "cleared" state. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Dev to master: TUI flickering fix + snap version update
Allow snap to build for all supported architectures instead of limiting to amd64/arm64. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix: Remove architecture constraints from snapcraft.yaml
Add continue-on-error to snap publish step so builds don't fail when snap store has pending reviews in queue. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix: Make snap publish step non-blocking
- Add VersionSelector.kt with version management UI components - Settings-style dropdown to select available versions - Pre-release toggle to show/hide beta versions - Download progress indicator - Downgrade warning dialog with confirmation - Platform-specific install instructions dialog - Extend DesktopUpdateService with: - getAllReleases() to fetch all GitHub releases - downloadRelease() to download specific version assets - Update AboutSection to include Version Management section 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Version Selector & Platform Improvements
Add support for passing an initial command to run when a terminal tab is first created. This enables embedding applications (like BOSS) to open a terminal and automatically execute a specific command. Changes: - Add `initialCommand` parameter to TabbedTerminal composable - Add `initialCommand` parameter to TabController.createTab() - Send initial command to PTY after shell is ready (500ms delay) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Shivang (kshivang)
force-pushed
the
feat/initial-command-support
branch
from
December 14, 2025 23:06
9a17f3c to
7caa082
Compare
Add a configurable setting to run a command automatically when new terminal tabs are created. This complements the programmatic initialCommand parameter added in the previous commit. Changes: - Add `initialCommand` setting to TerminalSettings (default: empty) - Add "Initial Command" text field in Behavior > Shell settings - Wire up setting to all createTab() calls in TabbedTerminal - Priority: programmatic parameter > setting > none Use case: Users can configure commands like "neofetch", "cd ~/projects", or custom startup scripts to run automatically in every new tab. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Add verticalScroll to NavigationRail so categories can be scrolled when the window is too small to show all items. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The LaunchedEffect that wires up menu callbacks (onSplitVertical, onSplitHorizontal) only had keys (menuActions, activeTabIndex). It ran before any tabs existed and returned early. When the first tab was created, activeTabIndex stayed at 0, so the effect never re-ran to set up the callbacks. Added tabController.tabs.size to the LaunchedEffect keys so it re-runs when tabs are added, ensuring menu actions are properly wired up. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The initial command was sent after a hardcoded 500ms delay which was a brittle race condition - too short for slow shells, too long for fast ones, and varying by machine performance. Changes: - Use OSC 133;A (prompt started) signal to detect when shell is ready - Add configurable fallback delay (initialCommandDelayMs) for shells without OSC 133 integration (default: 500ms, range: 100-2000ms) - Add UI slider in Behavior Settings to configure the fallback delay - Clean up temporary listener after initial command is sent With OSC 133 shell integration configured, the initial command is sent immediately when the prompt appears. Without it, falls back to the configurable delay. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Updated descriptions for Initial Command and Initial Command Delay settings to clarify they only affect newly created tabs. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
When clicking on a split pane running a mouse-aware TUI app (like nvim), the click was being forwarded to the app without first focusing the pane. This made it impossible to switch focus to panes running such apps. Changes: - Add onPaneFocus callback to ProperTerminal - Call onPaneFocus at the start of press handler, before any other processing (including mouse event forwarding) - Remove redundant pointerInput handler from SplitContainer - Clean up unused imports Now clicking on any split pane will focus it first, then forward the mouse event to the terminal application if applicable. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
initialCommandparameter toTabbedTerminalcomposable to run a command when terminal startsTabController.createTab()Use Case
This enables embedding applications (like BOSS) to open a terminal and automatically execute a specific command. For example:
Test plan
initialCommand = "echo test"and verify command runstoporhtop🤖 Generated with Claude Code