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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Broker: `spawn:<harness>` capabilities now declare `metadata.configured.node_kind: "broker"`, so Cloud keeps placing spawns on unclaimed CLI brokers instead of refusing them until `agent-relay node claim`. An already-declared kind (e.g. `desktop`) is preserved.
- `relay init` downloads the standalone Relaycast server (`relaycast-engine`) for your platform into the install directory's `bin` when it is missing, verifying its SHA-256, so the local server now starts from an npm install on any Node.js version and with npm install scripts disabled. It falls back to the `@relaycast/engine` npm package only if the download fails.
- After `relay init` sets up Pi or OpenCode, new Pi and OpenCode sessions now join Relay on their own and receive injected messages, like Codex and Claude Code. New core settings `pi_auto_activate` and `opencode_auto_activate` (off by default; `relay init` turns on the one for each tool you choose and `--uninstall` turns it off again) gate this, so turning on `auto_activate` alone still leaves Pi and OpenCode sessions joining only when added.
- Codex 0.16x workers no longer dead-letter their initial task with `initial_injection_incomplete` when the composer scrolls long input. The broker now checks that the end of each typed chunk is visible and ignores Codex's `↑`/`↓` scroll markers.
- `relay agent rotate <name>`, and `agent register` for a name that already exists, now issue a new token through the audited owner takeover instead of failing with "already exists", so a lost token can always be replaced.
- `@agent-relay/sdk` docs for `workspace.register()` now say registration is create-only: an existing name fails with `name_conflict` (with or without `{ strict: true }`) and keeps its token. Resume an agent with `workspace.reconnect({ apiToken })`, and get a new token with `relay agent rotate <name>`.
Expand Down
36 changes: 34 additions & 2 deletions crates/probe/contract/CoreContract.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7443,7 +7443,13 @@ public struct SettingsChange: Codable, Equatable, Hashable, Sendable {
public let mobileNativeContinuation: Bool?
/// Turns the OpenClaw Gateway route on or off.
public let openclawGateway: Bool?
/// Whether open OpenCode sessions join by themselves while
/// `auto_activate` is on.
public let opencodeAutoActivate: Bool?
public let opencodePlugin: Bool?
/// Whether open Pi sessions join by themselves while `auto_activate`
/// is on.
public let piAutoActivate: Bool?
/// Installs (`true`) or removes (`false`) Agent Relay's Pi extension.
public let piExtension: Bool?
/// Shows each relay message whole in agent chats (`true`), or hides it
Expand All @@ -7466,7 +7472,7 @@ public struct SettingsChange: Codable, Equatable, Hashable, Sendable {
/// Replaces the relay senders trusted like the person.
public let trustedRelaySenders: [String]?

public init(acceptSpawns: Bool? = nil, allowSelfRegistration: Bool? = nil, analyticsEnabled: Bool? = nil, autoActivate: Bool? = nil, autoJoinGeneral: Bool? = nil, claudeCloudSessions: Bool? = nil, claudeConfigDir: ClaudeConfigDirChange? = nil, claudeConfigDirs: [String]? = nil, claudeSessionHook: Bool? = nil, codexStopHook: Bool? = nil, contractorAccess: Bool? = nil, cursorDirectDelivery: Bool? = nil, devinDirectDelivery: Bool? = nil, directDelivery: Bool? = nil, directDeliveryDefault: Bool? = nil, grokLeader: Bool? = nil, hermesAgent: Bool? = nil, historyRetentionDays: Int? = nil, mobileClaudeHandoff: Bool? = nil, mobileNativeContinuation: Bool? = nil, openclawGateway: Bool? = nil, opencodePlugin: Bool? = nil, piExtension: Bool? = nil, showRelayMessages: Bool? = nil, spawnAllowTeammates: Bool? = nil, spawnBillingClaude: String? = nil, spawnBillingCodex: String? = nil, spawnFullAccessClaude: Bool? = nil, spawnFullAccessCodex: Bool? = nil, spawnHarnesses: [String: SpawnHarnessSettings]? = nil, spawnMaxAgents: Int? = nil, spawnNativeInput: Bool? = nil, spawnRepositories: [String]? = nil, teammateNativeInput: Bool? = nil, trustWorkspaceMembers: Bool? = nil, trustedRelaySenders: [String]? = nil) {
public init(acceptSpawns: Bool? = nil, allowSelfRegistration: Bool? = nil, analyticsEnabled: Bool? = nil, autoActivate: Bool? = nil, autoJoinGeneral: Bool? = nil, claudeCloudSessions: Bool? = nil, claudeConfigDir: ClaudeConfigDirChange? = nil, claudeConfigDirs: [String]? = nil, claudeSessionHook: Bool? = nil, codexStopHook: Bool? = nil, contractorAccess: Bool? = nil, cursorDirectDelivery: Bool? = nil, devinDirectDelivery: Bool? = nil, directDelivery: Bool? = nil, directDeliveryDefault: Bool? = nil, grokLeader: Bool? = nil, hermesAgent: Bool? = nil, historyRetentionDays: Int? = nil, mobileClaudeHandoff: Bool? = nil, mobileNativeContinuation: Bool? = nil, openclawGateway: Bool? = nil, opencodeAutoActivate: Bool? = nil, opencodePlugin: Bool? = nil, piAutoActivate: Bool? = nil, piExtension: Bool? = nil, showRelayMessages: Bool? = nil, spawnAllowTeammates: Bool? = nil, spawnBillingClaude: String? = nil, spawnBillingCodex: String? = nil, spawnFullAccessClaude: Bool? = nil, spawnFullAccessCodex: Bool? = nil, spawnHarnesses: [String: SpawnHarnessSettings]? = nil, spawnMaxAgents: Int? = nil, spawnNativeInput: Bool? = nil, spawnRepositories: [String]? = nil, teammateNativeInput: Bool? = nil, trustWorkspaceMembers: Bool? = nil, trustedRelaySenders: [String]? = nil) {
self.acceptSpawns = acceptSpawns
self.allowSelfRegistration = allowSelfRegistration
self.analyticsEnabled = analyticsEnabled
Expand All @@ -7488,7 +7494,9 @@ public struct SettingsChange: Codable, Equatable, Hashable, Sendable {
self.mobileClaudeHandoff = mobileClaudeHandoff
self.mobileNativeContinuation = mobileNativeContinuation
self.openclawGateway = openclawGateway
self.opencodeAutoActivate = opencodeAutoActivate
self.opencodePlugin = opencodePlugin
self.piAutoActivate = piAutoActivate
self.piExtension = piExtension
self.showRelayMessages = showRelayMessages
self.spawnAllowTeammates = spawnAllowTeammates
Expand Down Expand Up @@ -7527,7 +7535,9 @@ public struct SettingsChange: Codable, Equatable, Hashable, Sendable {
case mobileClaudeHandoff = "mobile_claude_handoff"
case mobileNativeContinuation = "mobile_native_continuation"
case openclawGateway = "openclaw_gateway"
case opencodeAutoActivate = "opencode_auto_activate"
case opencodePlugin = "opencode_plugin"
case piAutoActivate = "pi_auto_activate"
case piExtension = "pi_extension"
case showRelayMessages = "show_relay_messages"
case spawnAllowTeammates = "spawn_allow_teammates"
Expand Down Expand Up @@ -7567,7 +7577,9 @@ public struct SettingsChange: Codable, Equatable, Hashable, Sendable {
self.mobileClaudeHandoff = try c.decodeIfPresent(Bool.self, forKey: .mobileClaudeHandoff)
self.mobileNativeContinuation = try c.decodeIfPresent(Bool.self, forKey: .mobileNativeContinuation)
self.openclawGateway = try c.decodeIfPresent(Bool.self, forKey: .openclawGateway)
self.opencodeAutoActivate = try c.decodeIfPresent(Bool.self, forKey: .opencodeAutoActivate)
self.opencodePlugin = try c.decodeIfPresent(Bool.self, forKey: .opencodePlugin)
self.piAutoActivate = try c.decodeIfPresent(Bool.self, forKey: .piAutoActivate)
self.piExtension = try c.decodeIfPresent(Bool.self, forKey: .piExtension)
self.showRelayMessages = try c.decodeIfPresent(Bool.self, forKey: .showRelayMessages)
self.spawnAllowTeammates = try c.decodeIfPresent(Bool.self, forKey: .spawnAllowTeammates)
Expand Down Expand Up @@ -7607,7 +7619,9 @@ public struct SettingsChange: Codable, Equatable, Hashable, Sendable {
try c.encodeIfPresent(self.mobileClaudeHandoff, forKey: .mobileClaudeHandoff)
try c.encodeIfPresent(self.mobileNativeContinuation, forKey: .mobileNativeContinuation)
try c.encodeIfPresent(self.openclawGateway, forKey: .openclawGateway)
try c.encodeIfPresent(self.opencodeAutoActivate, forKey: .opencodeAutoActivate)
try c.encodeIfPresent(self.opencodePlugin, forKey: .opencodePlugin)
try c.encodeIfPresent(self.piAutoActivate, forKey: .piAutoActivate)
try c.encodeIfPresent(self.piExtension, forKey: .piExtension)
try c.encodeIfPresent(self.showRelayMessages, forKey: .showRelayMessages)
try c.encodeIfPresent(self.spawnAllowTeammates, forKey: .spawnAllowTeammates)
Expand Down Expand Up @@ -7712,10 +7726,20 @@ public struct SettingsValues: Codable, Equatable, Hashable, Sendable {
/// limit relay sessions (older than 2026.8.1): its relay senders then
/// get the agent's usual tools. Read-only; absent otherwise.
public let openclawUnlimitedVersion: String?
/// Whether an open OpenCode session joins the relay by itself while
/// `auto_activate` is on. Off unless turned on (`relay init` turns it on
/// for a person who chose OpenCode): with it off, an OpenCode session
/// joins only when added. Absent in older cores.
public let opencodeAutoActivate: Bool?
/// Whether Agent Relay's OpenCode plugin is installed in OpenCode's
/// global `plugins/`, the route into a plain OpenCode session. Absent
/// where OpenCode has never run.
public let opencodePlugin: Bool?
/// Whether an open Pi session joins the relay by itself while
/// `auto_activate` is on. Off unless turned on (`relay init` turns it on
/// for a person who chose Pi): with it off, a Pi session joins only when
/// added. Absent in older cores.
public let piAutoActivate: Bool?
/// Whether Agent Relay's Pi extension is installed in Pi's global
/// `extensions/`, the route into a Pi session. The desktop's core
/// installs it at start unless it was turned off; a core `relay init`
Expand Down Expand Up @@ -7773,7 +7797,7 @@ public struct SettingsValues: Codable, Equatable, Hashable, Sendable {
/// off, signed out, or Cloud's list has not been read lately.
public let workspaceMembers: [TrustedWorkspaceMember]?

public init(acceptSpawns: Bool? = nil, agentChanges: [AgentSettingsChange]? = nil, allowSelfRegistration: Bool, analyticsEnabled: Bool? = nil, autoActivate: Bool, autoJoinGeneral: Bool? = nil, claudeCloudSessions: Bool? = nil, claudeConfigDirs: [ClaudeConfigDir]? = nil, claudeSessionHook: Bool? = nil, codexStopHook: Bool? = nil, contractorAccess: Bool? = nil, cursorDirectDelivery: Bool? = nil, devinDirectDelivery: Bool? = nil, directDelivery: Bool? = nil, directDeliveryManaged: String? = nil, grokLeader: Bool? = nil, hermesAgent: Bool? = nil, historyRetentionDays: Int? = nil, mobileClaudeHandoff: Bool? = nil, mobileClaudeHandoffSupported: Bool? = nil, mobileNativeContinuation: Bool? = nil, mobileNativeContinuationSupported: Bool? = nil, openclawGateway: Bool? = nil, openclawUnlimitedVersion: String? = nil, opencodePlugin: Bool? = nil, piExtension: Bool? = nil, showRelayMessages: Bool? = nil, spawnAllowTeammates: Bool? = nil, spawnBillingClaude: String? = nil, spawnBillingCodex: String? = nil, spawnFullAccessClaude: Bool? = nil, spawnFullAccessCodex: Bool? = nil, spawnHarnesses: [String: SpawnHarnessSettings]? = nil, spawnMaxAgents: Int? = nil, spawnNativeInput: Bool? = nil, spawnRepositories: [String]? = nil, teammateNativeInput: Bool? = nil, trustWorkspaceMembers: Bool? = nil, trustedRelaySenders: [String]? = nil, workspaceMembers: [TrustedWorkspaceMember]? = nil) {
public init(acceptSpawns: Bool? = nil, agentChanges: [AgentSettingsChange]? = nil, allowSelfRegistration: Bool, analyticsEnabled: Bool? = nil, autoActivate: Bool, autoJoinGeneral: Bool? = nil, claudeCloudSessions: Bool? = nil, claudeConfigDirs: [ClaudeConfigDir]? = nil, claudeSessionHook: Bool? = nil, codexStopHook: Bool? = nil, contractorAccess: Bool? = nil, cursorDirectDelivery: Bool? = nil, devinDirectDelivery: Bool? = nil, directDelivery: Bool? = nil, directDeliveryManaged: String? = nil, grokLeader: Bool? = nil, hermesAgent: Bool? = nil, historyRetentionDays: Int? = nil, mobileClaudeHandoff: Bool? = nil, mobileClaudeHandoffSupported: Bool? = nil, mobileNativeContinuation: Bool? = nil, mobileNativeContinuationSupported: Bool? = nil, openclawGateway: Bool? = nil, openclawUnlimitedVersion: String? = nil, opencodeAutoActivate: Bool? = nil, opencodePlugin: Bool? = nil, piAutoActivate: Bool? = nil, piExtension: Bool? = nil, showRelayMessages: Bool? = nil, spawnAllowTeammates: Bool? = nil, spawnBillingClaude: String? = nil, spawnBillingCodex: String? = nil, spawnFullAccessClaude: Bool? = nil, spawnFullAccessCodex: Bool? = nil, spawnHarnesses: [String: SpawnHarnessSettings]? = nil, spawnMaxAgents: Int? = nil, spawnNativeInput: Bool? = nil, spawnRepositories: [String]? = nil, teammateNativeInput: Bool? = nil, trustWorkspaceMembers: Bool? = nil, trustedRelaySenders: [String]? = nil, workspaceMembers: [TrustedWorkspaceMember]? = nil) {
self.acceptSpawns = acceptSpawns
self.agentChanges = agentChanges
self.allowSelfRegistration = allowSelfRegistration
Expand All @@ -7798,7 +7822,9 @@ public struct SettingsValues: Codable, Equatable, Hashable, Sendable {
self.mobileNativeContinuationSupported = mobileNativeContinuationSupported
self.openclawGateway = openclawGateway
self.openclawUnlimitedVersion = openclawUnlimitedVersion
self.opencodeAutoActivate = opencodeAutoActivate
self.opencodePlugin = opencodePlugin
self.piAutoActivate = piAutoActivate
self.piExtension = piExtension
self.showRelayMessages = showRelayMessages
self.spawnAllowTeammates = spawnAllowTeammates
Expand Down Expand Up @@ -7841,7 +7867,9 @@ public struct SettingsValues: Codable, Equatable, Hashable, Sendable {
case mobileNativeContinuationSupported = "mobile_native_continuation_supported"
case openclawGateway = "openclaw_gateway"
case openclawUnlimitedVersion = "openclaw_unlimited_version"
case opencodeAutoActivate = "opencode_auto_activate"
case opencodePlugin = "opencode_plugin"
case piAutoActivate = "pi_auto_activate"
case piExtension = "pi_extension"
case showRelayMessages = "show_relay_messages"
case spawnAllowTeammates = "spawn_allow_teammates"
Expand Down Expand Up @@ -7885,7 +7913,9 @@ public struct SettingsValues: Codable, Equatable, Hashable, Sendable {
self.mobileNativeContinuationSupported = try c.decodeIfPresent(Bool.self, forKey: .mobileNativeContinuationSupported)
self.openclawGateway = try c.decodeIfPresent(Bool.self, forKey: .openclawGateway)
self.openclawUnlimitedVersion = try c.decodeIfPresent(String.self, forKey: .openclawUnlimitedVersion)
self.opencodeAutoActivate = try c.decodeIfPresent(Bool.self, forKey: .opencodeAutoActivate)
self.opencodePlugin = try c.decodeIfPresent(Bool.self, forKey: .opencodePlugin)
self.piAutoActivate = try c.decodeIfPresent(Bool.self, forKey: .piAutoActivate)
self.piExtension = try c.decodeIfPresent(Bool.self, forKey: .piExtension)
self.showRelayMessages = try c.decodeIfPresent(Bool.self, forKey: .showRelayMessages)
self.spawnAllowTeammates = try c.decodeIfPresent(Bool.self, forKey: .spawnAllowTeammates)
Expand Down Expand Up @@ -7929,7 +7959,9 @@ public struct SettingsValues: Codable, Equatable, Hashable, Sendable {
try c.encodeIfPresent(self.mobileNativeContinuationSupported, forKey: .mobileNativeContinuationSupported)
try c.encodeIfPresent(self.openclawGateway, forKey: .openclawGateway)
try c.encodeIfPresent(self.openclawUnlimitedVersion, forKey: .openclawUnlimitedVersion)
try c.encodeIfPresent(self.opencodeAutoActivate, forKey: .opencodeAutoActivate)
try c.encodeIfPresent(self.opencodePlugin, forKey: .opencodePlugin)
try c.encodeIfPresent(self.piAutoActivate, forKey: .piAutoActivate)
try c.encodeIfPresent(self.piExtension, forKey: .piExtension)
try c.encodeIfPresent(self.showRelayMessages, forKey: .showRelayMessages)
try c.encodeIfPresent(self.spawnAllowTeammates, forKey: .spawnAllowTeammates)
Expand Down
Loading
Loading