native macOS codings agent orchestrator
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

Execute terminal-input commands via return key event

onevcat 562042fc b5c58e4d

+60 -10
+1 -2
supacode/Features/App/Reducer/AppFeature.swift
··· 464 464 ) 465 465 } 466 466 case .terminalInput: 467 - let input = command.hasSuffix("\n") ? command : "\(command)\n" 468 467 return .run { _ in 469 - await terminalClient.send(.insertText(worktree, text: input)) 468 + await terminalClient.send(.insertText(worktree, text: command)) 470 469 } 471 470 } 472 471
+1 -1
supacode/Features/Terminal/BusinessLogic/WorktreeTerminalManager.swift
··· 42 42 case .runScript(let worktree, let script): 43 43 _ = state(for: worktree).runScript(script) 44 44 case .insertText(let worktree, let text): 45 - if !state(for: worktree).focusAndInsertText(text) { 45 + if !state(for: worktree).focusAndRunCommand(text) { 46 46 Task { 47 47 createTabAsync( 48 48 in: worktree,
+14
supacode/Features/Terminal/Models/WorktreeTerminalState.swift
··· 209 209 return true 210 210 } 211 211 212 + @discardableResult 213 + func focusAndRunCommand(_ text: String) -> Bool { 214 + guard let tabId = tabManager.selectedTabId, 215 + let focusedId = focusedSurfaceIdByTab[tabId], 216 + let surface = surfaces[focusedId] 217 + else { return false } 218 + let trimmed = text.trimmingCharacters(in: .whitespacesAndNewlines) 219 + guard !trimmed.isEmpty else { return false } 220 + let command = text.trimmingCharacters(in: .newlines) 221 + surface.requestFocus() 222 + surface.insertText(command, replacementRange: NSRange(location: 0, length: 0)) 223 + return surface.submitLine() 224 + } 225 + 212 226 func syncFocus(windowIsKey: Bool, windowIsVisible: Bool) { 213 227 let selectedTabId = tabManager.selectedTabId 214 228 var surfaceToFocus: GhosttySurfaceView?
+37
supacode/Infrastructure/Ghostty/GhosttySurfaceView.swift
··· 1398 1398 ghostty_surface_text(surface, ptr, UInt(len - 1)) 1399 1399 } 1400 1400 } 1401 + 1402 + @discardableResult 1403 + func submitLine() -> Bool { 1404 + let timestamp = ProcessInfo.processInfo.systemUptime 1405 + let windowNumber = window?.windowNumber ?? 0 1406 + guard 1407 + let keyDownEvent = NSEvent.keyEvent( 1408 + with: .keyDown, 1409 + location: .zero, 1410 + modifierFlags: [], 1411 + timestamp: timestamp, 1412 + windowNumber: windowNumber, 1413 + context: nil, 1414 + characters: "\r", 1415 + charactersIgnoringModifiers: "\r", 1416 + isARepeat: false, 1417 + keyCode: 36 1418 + ), 1419 + let keyUpEvent = NSEvent.keyEvent( 1420 + with: .keyUp, 1421 + location: .zero, 1422 + modifierFlags: [], 1423 + timestamp: timestamp, 1424 + windowNumber: windowNumber, 1425 + context: nil, 1426 + characters: "\r", 1427 + charactersIgnoringModifiers: "\r", 1428 + isARepeat: false, 1429 + keyCode: 36 1430 + ) 1431 + else { 1432 + return false 1433 + } 1434 + keyDown(with: keyDownEvent) 1435 + keyUp(with: keyUpEvent) 1436 + return true 1437 + } 1401 1438 } 1402 1439 1403 1440 extension GhosttySurfaceView: NSServicesMenuRequestor {
+7 -7
supacodeTests/AppFeatureCustomCommandTests.swift
··· 20 20 systemImage: "checkmark.circle", 21 21 command: "swift test", 22 22 execution: .shellScript, 23 - shortcut: nil 23 + shortcut: nil, 24 24 ), 25 25 ] 26 26 ··· 37 37 38 38 #expect( 39 39 sent.value == [ 40 - .createTabWithInput(worktree, input: "swift test", runSetupScriptIfNew: false) 41 - ] 40 + .createTabWithInput(worktree, input: "swift test", runSetupScriptIfNew: false), 41 + ], 42 42 ) 43 43 } 44 44 45 - @Test(.dependencies) func terminalInputCommandInsertsTextWithNewline() async { 45 + @Test(.dependencies) func terminalInputCommandSendsRawCommandText() async { 46 46 let worktree = makeWorktree() 47 47 let sent = LockIsolated<[TerminalClient.Command]>([]) 48 48 var state = AppFeature.State( ··· 55 55 systemImage: "terminal", 56 56 command: "pnpm test --watch", 57 57 execution: .terminalInput, 58 - shortcut: nil 58 + shortcut: nil, 59 59 ), 60 60 ] 61 61 ··· 72 72 73 73 #expect( 74 74 sent.value == [ 75 - .insertText(worktree, text: "pnpm test --watch\n") 76 - ] 75 + .insertText(worktree, text: "pnpm test --watch"), 76 + ], 77 77 ) 78 78 } 79 79