Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ permissions:
jobs:
swift:
name: Swift build and test
runs-on: macos-15
runs-on: macos-26
timeout-minutes: 20

steps:
Expand Down
4 changes: 2 additions & 2 deletions Sources/Catch/Models/Session.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@ struct Session: Identifiable, Equatable {
}
}

var gooseInternalSessionURL: URL? {
var berdSessionURL: URL? {
let trimmedSessionID = sessionID.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmedSessionID.isEmpty,
let encodedSessionID = trimmedSessionID.addingPercentEncoding(withAllowedCharacters: .urlPathSegmentAllowed)
else {
return nil
}

return URL(string: "goose-internal://session/\(encodedSessionID)")
return URL(string: "berd://session/\(encodedSessionID)")
}
}

Expand Down
2 changes: 2 additions & 0 deletions Sources/Catch/Services/GooseServeClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,8 @@ final class GooseServeClient: NSObject, @unchecked Sendable {
let session = URLSession(configuration: .default, delegate: delegate, delegateQueue: nil)
self.session = session
let task = session.webSocketTask(with: try webSocketURL())
// Large ACP metadata responses otherwise close the websocket with "Message too long".
task.maximumMessageSize = 64 * 1024 * 1024
webSocketTask = task

task.resume()
Expand Down
4 changes: 2 additions & 2 deletions Sources/Catch/Views/MainView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ private extension MainView {
TextField(
text: $store.prompt,
selection: $promptSelection,
prompt: Text("Chat with Goose, @ for agents, or / for skills"),
prompt: Text("Chat with Berd, @ for agents, or / for skills"),
axis: .vertical
) {
Text("Prompt")
Expand Down Expand Up @@ -538,7 +538,7 @@ private extension MainView {

@discardableResult
func activateSession(_ session: Session) -> Bool {
guard let url = session.gooseInternalSessionURL else { return false }
guard let url = session.berdSessionURL else { return false }
openURL(url)
NotificationCenter.default.post(name: .hideFloatingWindow, object: nil)
return true
Expand Down
8 changes: 4 additions & 4 deletions Tests/CatchTests/SessionDeepLinkTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Testing
@Suite
struct SessionDeepLinkTests {
@Test
func buildsGooseInternalSessionURL() {
func buildsBerdSessionURL() {
let session = Session(
provider: .goose,
sessionID: "abc-123",
Expand All @@ -16,7 +16,7 @@ struct SessionDeepLinkTests {
lastEvent: ""
)

#expect(session.gooseInternalSessionURL?.absoluteString == "goose-internal://session/abc-123")
#expect(session.berdSessionURL?.absoluteString == "berd://session/abc-123")
}

@Test
Expand All @@ -31,7 +31,7 @@ struct SessionDeepLinkTests {
lastEvent: ""
)

#expect(session.gooseInternalSessionURL?.absoluteString == "goose-internal://session/id%2Fwith%20spaces")
#expect(session.berdSessionURL?.absoluteString == "berd://session/id%2Fwith%20spaces")
}

@Test
Expand All @@ -46,6 +46,6 @@ struct SessionDeepLinkTests {
lastEvent: ""
)

#expect(session.gooseInternalSessionURL == nil)
#expect(session.berdSessionURL == nil)
}
}
4 changes: 2 additions & 2 deletions docs/focus-hiding.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ Catch behaves like a transient command panel. The window should feel ready for t

## Session Activation

- Pressing Return while a session row is highlighted opens that session in Goose through `goose-internal://session/<session-id>`.
- Pressing Return while a session row is highlighted opens that session in Berd through `berd://session/<session-id>`.
- Clicking a session row opens the session immediately instead of only selecting the row.
- Session IDs in Goose deep links must be percent-encoded as a single URL path segment.
- Session IDs in Berd deep links must be percent-encoded as a single URL path segment.
- Opening a session hides the Catch panel using the same direct order-out path as Escape.

## Session Creation
Expand Down