Conversation
Add callback that fires when initialCommand finishes executing: - onInitialCommandComplete: ((success: Boolean, exitCode: Int?) -> Unit)? - success: true if exit code is 0 - exitCode: command exit code (requires OSC 133 shell integration) Uses one-shot CommandStateListener pattern to detect command completion via existing OSC 133 shell integration. Modified files: - EmbeddableTerminal.kt: Added parameter and one-shot listener - TabController.kt: Added parameter and one-shot listener - TabbedTerminal.kt: Added parameter, passed to first tab - Examples: Added demo usage in both embedded and tabbed examples 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Code Review - PR #218: Add onInitialCommandComplete callbackOverall, this is a well-implemented feature with clean code and good documentation. The implementation follows existing patterns in the codebase and properly handles the one-shot listener pattern. Here's my detailed feedback: ✅ Strengths
|
| Criteria | Rating | Notes |
|---|---|---|
| Correctness | 🟡 Medium | Works for happy path, race condition needs consideration |
| Maintainability | 🟢 Good | Clean, follows existing patterns |
| Performance | 🟢 Excellent | Minimal overhead, self-cleaning listener |
| Security | 🟢 Good | No security concerns |
| Documentation | 🟢 Good | PR description is thorough, inline docs could be enhanced |
| Testing | 🟡 Medium | Examples provided, but unit tests would be ideal |
🎯 Verdict
Recommendation: ✅ Approve with minor suggestions
This PR is functionally sound and ready to merge. The race condition is edge-case and could be addressed in a follow-up if it becomes a real-world issue. The implementation is clean and follows best practices.
Priority Actions (optional, can be done in follow-up PR):
- Add KDoc comments explaining OSC 133 requirement and edge cases
- Consider race condition mitigation if users report issues
- Add unit tests for listener registration/unregistration logic
Great work on this feature! The one-shot listener pattern is elegantly implemented. 🎉
Add initialCommand to TabbedTerminal in tabbed-example so onInitialCommandComplete callback can be tested. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Code Review: onInitialCommandComplete CallbackSummary: This PR adds a callback mechanism to notify when the initial command completes, which is a useful feature for workflow automation. The implementation is clean and follows the existing patterns in the codebase. ✅ Strengths
🔍 Potential Issues & Suggestions1. Thread Safety Concern - Race Condition Risk
|
| Aspect | Rating | Notes |
|---|---|---|
| Correctness | Race condition risk, cleanup gaps | |
| API Design | ✅ 9/10 | Clean, idiomatic Kotlin |
| Documentation | Missing KDoc, good examples | |
| Thread Safety | ✅ 8/10 | Uses thread-safe collections |
| Performance | ✅ 10/10 | Zero overhead when unused |
| Security | ✅ 10/10 | No security concerns |
🎯 Priority Recommendations
- HIGH: Fix race condition (Issue feat: Terminal rendering improvements + 4 high-priority features (#2, #3, #4, #5) #1) - register listener before sending command
- MEDIUM: Add KDoc to public API parameters (Issue ⚙️ Implement user settings and configuration system #4)
- LOW: Add cleanup for orphaned listeners (Issue 🔍 Implement text search/find functionality (Ctrl+F) #2)
- LOW: Document exitCode nullability (Issue 🔗 Implement hyperlink detection and click handling #3)
- OPTIONAL: Add unit tests
🚀 Final Verdict
Approval Status: ✅ Approve with suggestions
The core implementation is solid and follows best practices. The race condition is the only blocking issue - it's a simple fix (swap two lines) but important for reliability.
Once the ordering is fixed, this is production-ready! Nice work implementing this feature cleanly. 👍
References:
CommandStateListener.kt: Interface definitionBossTerminal.kt:368-409: Thread-safe listener implementationEmbeddableTerminal.kt:682-696: EmbeddableTerminal implementationTabController.kt:1187-1201: TabbedTerminal implementation
The one-shot listener for onInitialCommandComplete must be registered BEFORE the initial command is sent, not after. For fast commands like echo, the command completes and OSC 133;D is received before the listener could be registered. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Code Review: Add onInitialCommandComplete callback (#216)SummaryThis PR adds a callback to notify when the initial command completes execution. The implementation is clean and follows the existing OSC 133 shell integration pattern. Overall, this is a well-implemented feature with good code quality. ✅ Strengths1. Excellent Design Pattern
2. Good Documentation
3. Thread Safety
4. Backward Compatibility
|
🔍 Issues & Concerns1. Potential Race Condition with Listener Removal
|
🎯 Performance & SecurityPerformance ✅
Security ✅
📋 RecommendationsPriority: High
Priority: Medium
Priority: Low
|
🎉 VerdictApprove with minor fixes recommended This is a solid implementation that follows the project's existing patterns. The core logic is sound, but adding exception handling and tests would make it production-ready. The issues identified are edge cases that are unlikely to occur in normal usage, but should be addressed for robustness. Suggested Code FixApply this change to both if (onInitialCommandComplete != null) {
val completionListener = object : CommandStateListener {
override fun onCommandFinished(exitCode: Int) {
try {
onInitialCommandComplete(exitCode == 0, exitCode)
} catch (e: Exception) {
println("ERROR: onInitialCommandComplete threw exception")
e.printStackTrace()
} finally {
// Always unregister to ensure callback only fires once
session.terminal.removeCommandStateListener(this)
// Use tab.terminal for TabController
}
}
}
session.terminal.addCommandStateListener(completionListener)
}Great work overall! The feature is well-designed and the implementation is clean. Just needs those small robustness improvements. 👍 |
EmbeddableTerminal was missing the ShellIntegrationInjector call, so OSC 133 sequences weren't being emitted and onInitialCommandComplete callback couldn't fire. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Code Review - PR #218: Add onInitialCommandComplete callbackOverall AssessmentLGTM with minor suggestions. This is a well-implemented feature that adds useful functionality for tracking initial command completion. Strengths
Code Quality Observations
Minor Suggestions
Security & Performance
Test CoveragePR has manual test plan but no automated tests. Consider adding tests for callback firing once, correct exit codes, null initial command handling. Final RecommendationApprove with minor improvements. Implementation is solid and ready to merge. Suggestions are non-blocking enhancements for follow-up PR if desired. Priority: Consider making exitCode non-nullable Great work maintaining consistency with existing patterns! |
Document nullable exitCode: kept nullable for future timeout-based fallback where exit code is unknown (command completed but no OSC 133;D). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Code Review: onInitialCommandComplete Callback (#216)SummaryThis PR successfully implements the ✅ Strengths
|
- Add try-finally wrapper to ensure listener unregisters even if callback throws - Change exitCode from Int? to Int (always non-null from OSC 133) - Add debug logging when callback fires to help troubleshoot shell integration 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Code Review: PR #218 - Add onInitialCommandComplete callbackSummaryThis PR adds a callback mechanism to notify when an ✅ Strengths
🔍 Issues & Recommendations🐛 Issue 1: DEBUG println Left in Production CodeLocation: println("DEBUG: Initial command completed with exit code: $exitCode")Impact: Debug output will pollute production console logs. Recommendation: Remove or replace with proper logging: // Option 1: Remove entirely (preferred for production)
onInitialCommandComplete(exitCode == 0, exitCode)
// Option 2: Use proper logging if debugging is needed
if (settings.debugModeEnabled) {
println("Initial command completed with exit code: $exitCode")
}
|
Summary
onInitialCommandComplete: ((success: Boolean, exitCode: Int?) -> Unit)?callback toTabbedTerminalandEmbeddableTerminalinitialCommandfinishes executingsuccess: true if exit code is 0, false otherwiseexitCode: command exit code (requires OSC 133 shell integration to detect)Implementation
Uses one-shot
CommandStateListenerpattern:initialCommand, register a command state listeneronCommandFinished(exitCode)event, fire the callbackFiles Changed
EmbeddableTerminal.kt: Added parameter and one-shot listener ininitializeProcess()TabController.kt: Added parameter and one-shot listener ininitializeTerminalSession()TabbedTerminal.kt: Added parameter, passed to first tab creationembedded-example/Main.kt: Demo usage showing status message updatetabbed-example/Main.kt: Demo usage showing window title updateTest plan
Note
Callback requires OSC 133 shell integration to detect command completion. See CLAUDE.md for shell setup instructions.
Closes #216
🤖 Generated with Claude Code