Conversation
There was a problem hiding this comment.
Looks great!
IntentDescription has an optional categoryName argument that the Shortcuts UI will use to categorize (+ group) intents. There's also searchKeywords, which I haven't used before.
Not sure if you looked at these but might be useful given how many we offer.
| func entities(for identifiers: [TerminalEntity.ID]) async throws -> [TerminalEntity] { | ||
| return all.filter { | ||
| identifiers.contains($0.uuid) | ||
| }.map { | ||
| TerminalEntity($0) | ||
| } | ||
| } | ||
|
|
||
| @MainActor | ||
| func entities(matching string: String) async throws -> [TerminalEntity] { | ||
| return all.filter { | ||
| $0.title.localizedCaseInsensitiveContains(string) | ||
| }.map { | ||
| TerminalEntity($0) | ||
| } | ||
| } |
There was a problem hiding this comment.
I think both of these cases could be slightly improved using either a lazy collection (all.lazy.filter.map) or compactMap to avoid extra iterations.
There was a problem hiding this comment.
There's never going to be so many terminals that this will ever matter. Even if there were 1,000 terminals it'd be fast, so I don't think we need to worry about it...
Both sound good but not sure what I'd put as the category. Search keywords we can also continue to think of. |
|
Based on various feedback, I modified the |
This PR integrates Ghostty on macOS with the App Intents system. The focus of this initial work was on enabling Apple Shortcuts on macOS, but App Intents are the same underlying system that powers a number of other Apple features such as Spotlight, Siri, Widgets, and more. We don't do much with these latter ones yet, though.
Additionally, this PR begins to refactor and untangle some of our libghostty API calls from macOS views. Presently, macOS views and view controllers directly call into the libghostty API and own libghostty data models. This tight coupling is kind of nasty because it tends to also couple libghostty API calls to the main GUI thread when they don't really have to be (they just have to not be concurrently accessed). This becomes an issue because App Intents run on background threads. This PR starts to extract out some of this business logic into standalone classes, but we still force all execution onto the main thread during the transition.
Version requirement: Most of the shortcuts will work on macOS 13, but there are some that require macOS 14, and some functionality will require macOS 26. We gracefully degrade in all scenarios (the capabilities that are unavailable just don't show up on older systems).
Important
This bumps our build requirements on macOS to Xcode 26 and the macOS 26 SDK. You can still build on macOS 15, but you must be using the Xcode 26 beta. This includes a README update about that.
Why?
Apple Shortcuts is an extremely powerful scripting tool on Apple platforms. It comes with a number of built-in capabilities such as moving windows, taking screenshots, fetching secrets, and more. By integrating with Apple Shortcuts, it allows Ghostty to become scriptable to a certain extent while also being able to take advantage of this large ecosystem.
It is a huge downside that Shortcuts is Apple-only and I still would like to make Ghostty scriptable to some extent on Linux and other platforms as well. This work doesn't preclude that goal, but gives us an answer to a large subset of users (macOS users), which is great.
Beyond this, no terminals integrate with Apple Shortcuts except the built-in Terminal. And even then, the built-in Terminal only exposes two actions (run script and run script over SSH). I think there's a lot that can be done by exposing more functionality and I'm excited to see what people do with this.
Finally, I think Shortcuts is possibly a way we can do some GUI testing on macOS. That remains to be explored but it seems promising.
Capability
The initial set of Shortcut actions is shown in the screenshot below:
These can be combined with the built-in shortcuts to do some pretty interesting things.
Future
There are more capabilities I'd like to expose, but they require changing core parts of Ghostty that I didn't want to mix into this PR.
Security
Scripting Ghostty can be considered a security risk, since it allows arbitrary command execution, reading terminal output, etc. Therefore, Ghostty will ask for permission prior to allowing any Shortcut to remote control it:
This can be directly overridden using the new
macos-shortcutsconfiguration, which defaults toaskbut can also be set todenyorallowwith self-explanatory behaviors.