You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Peekaboo permission probes no longer invalidate active UI snapshots between observation and mutation, and delivered-but-unconfirmed foreground outcomes are surfaced as ambiguous results that require observation instead of hard tool errors.
Desktop automation now runs the pinned Peekaboo 4.5+ MCP surface with explicit foreground authority, exposing 22 native desktop tools including coordinate input, move/drag, dialogs, paste, capture, clipboard mutation, app/window/Space lifecycle and verify_state while keeping duplicate Peekaboo AI/browser stacks out of the gateway.
MCP replay suppression now treats transport request IDs as recyclable hints: only in-flight/same-signal redelivery is exact-deduplicated, while a settled ID reused for a new call executes normally.
Source-restart recovery explicitly forbids launchctl submit one-shot wrappers because macOS infers submitted jobs as KeepAlive and can loop successful restarts.
Source restart now preserves the whitespace-free private Node alias instead of forwarding Node's resolved process.execPath, preventing preflight rejection when the real runtime lives under Application Support.
Source-checkout runtime restart is now single-flight, waits for helper spawn acknowledgement, bounds launch/tunnel lifecycle commands, and records the exact failure stage instead of silently stalling after restart scheduling.
MCP tool delivery is now replay-safe: duplicate transport delivery reuses the original invocation/result instead of re-running side effects, while intentional new identical calls still execute normally.
Source-checkout restart now automatically prefers the stable whitespace-free developer Node alias at ~/.local/share/equinox-local-developer/bin/node and rejects whitespace-bearing Node executable paths before tunnel startup, preventing Application Support/... command-path splitting from breaking Local.
Refreshed current runtime dependencies to Node 26.10.0 and Peekaboo 4.5.0; fast-uri now follows the normal compatible ^4.2.1 range instead of an unnecessary exact pin. tunnel-client remains current at 0.0.14, and node-pty remains on 1.2.0-beta.15 because npm's latest tag still points to the older 1.1.0 line.
Fixed native Control Center confirmation actions such as Task Mark complete / Cancel task by wiring trusted same-origin window.confirm() calls to a macOS sheet.
Added
Added a default-on Telegram remote control switch in Control Center → Services. Turning it off keeps outbound Telegram delivery available while inbound updates are acknowledged and discarded without delayed replay; browser-bound active assistant turns refresh Telegram's short-lived typing indicator from the existing Turn Budget signal.
Fixed Telegram task-card reconciliation so Bot API message is not modified responses are treated as idempotent success; Local now refreshes the persisted display key, emits a recovered observability event, and stops repeated Activity/health warnings.
Hardened Telegram New task creation against ChatGPT startup ref/hydration churn: startup composer replacement, empty/missing transient composers, and stale refs are recovered only while the live composer proves no prompt has been submitted; staged prompt text is postcondition-checked before the trusted send-button click, duplicate typing is avoided, and safe pre-submit failure still rolls back the temporary Task/tab. New Task bootstrap uses the real ChatGPT send control instead of relying on Enter; successful creation auto-selects the Task chat and its Task card exposes Unbind. Transitional /c/ routes are ignored until the URL exposes a conversation id that satisfies the same binding contract as Task Capsule storage.
Added Telegram Chat Bridge round-trip with exact Task chats and local-file handoff. /tasks is the interactive Task control hub and includes ➕ New task; every active Task exposes Continue / Mark complete / Cancel, while verified/current chats add Use for chat / Unbind / Open in ChatGPT; selected/current Task chat cards expose ↗ Open in ChatGPT and 🔌 Unbind; only that explicit Task-creation flow opens one new root ChatGPT conversation and binds it to the new Task Capsule. Normal unbound Telegram messages never create chats. Task-bound turns carry only user text + task_id + optional local_file. The earlier opaque Chat Bridge attachment resolver layer was removed. Chat Bridge v9 supports the new Task conversation's first assistant response with a null previous-assistant key. Browser-side file re-upload remains removed; guarded Input.insertText, real send-button submission, exact user-epoch confirmation, unique stale-tab reacquire and fail-closed ambiguity remain.
Added Telegram Remote Control for the paired private user: chat-scoped native /status, /tasks and /help command discovery, with /tasks acting as an interactive Task control hub instead of a chat-only selector, a sectioned phone-friendly /status card, Mark complete plus bounded next-step/terminal-state polish on durable Task Capsule cards, and short-lived /status controls for Emergency Stop / Resume / Restart. Emergency Stop and Restart use action-specific two-step confirmation with bounded expiry; the controls reuse the same Agent Control/runtime restart services as Control Center and keep restart-ambiguous mutations fail-closed.
Added generic Authenticated HTTP Profiles under integrations_call. Agents can discover safe profile metadata, create/update/delete profile structure and issue bounded authenticated requests without receiving credential values. Control Center provides profile CRUD, Ready/Needs credential state, a default-on agent-management toggle and a write-only credential field.
Added Bearer and validated secret-header authentication profiles with exact HTTPS origin + base-path scoping, allowed HTTP methods/path prefixes, optional allowed agent headers, bounded query/body/response/timeout handling and redirect refusal.
Added short-lived HTTP Response Bindings for multi-step authenticated JSON APIs. A response exposes an opaque response_id; preferred chaining keeps reuse metadata outside the body through response_bindings with source/target RFC 6901 pointers. Local injects the same-profile/same-trust string only immediately before fetch. The inline $equinox_response_ref form remains supported for compatibility.
Replaced the old dashboard onboarding card with a dedicated First-time Setup Mode. Fresh managed installs keep normal Control Center sections locked while guiding Tunnel ID + restricted Runtime API key creation, ChatGPT tunnel connector setup, required Equinox Browser consent/control, and a final real ChatGPT→Mac MCP verification call. Setup completion is persisted privately and later connection failures do not reopen onboarding; pre-milestone managed upgrades are treated as legacy-complete.
Added layered Control Center auto-refresh so task completion, runtime/browser state, activity, onboarding, Doctor/integrations and cached config/update changes appear without pressing Refresh. Polling pauses while hidden, refreshes immediately on focus, suppresses overlap/transient errors and preserves active local edit drafts.
Fixed three Control Center live-refresh regressions: Overview no longer derives live ChatGPT/MCP connection status from onboarding availability, fast partial status refreshes no longer erase richer Peekaboo version/readiness state, and background auto-refresh GETs and the native menu-bar heartbeat no longer inflate the user-facing Control Center request counter.
Added secure Telegram private-user pairing and first-time Setup guidance. Telegram is optional but marked Recommended; Setup teaches BotFather /newbot, token copy, bot /start, detected-account confirmation and an explicit Skip for now path. Manual Telegram user-ID entry is no longer required by the UI.
Added a private bounded Telegram inbound-update foundation with persisted next-update offsets, private-user-only filtering, restart-safe replay prevention and a 50-message local queue. The agent surface still exposes no generic Telegram inbox/read operation.
Added the Telegram task inbox layer: one durable/editable Telegram card per changed Task Capsule, bounded Continue/Cancel/Open-in-ChatGPT controls, reply→Task Capsule humanInput routing, private exact ChatGPT task binding and guarded bound Auto Continue for replies/Continue actions. Telegram task-message mappings and action reservations are durable; processing actions interrupted by restart become ambiguous and are never replayed automatically.
Added bounded Telegram file/photo exchange. A photo/document attached to an exact mapped task-card reply is downloaded through Bot API getFile and exposed to the task only as opaque attachment metadata; telegram_attachment_open requires the exact task + attachment id. Agents can send accessible local files/photos back with telegram_send_file, which keeps the paired recipient fixed and reuses Local's normal file-export access policy.
Telegram inbound files now default to the visible ~/Downloads/Equinox Local/Telegram/ folder. Control Center can switch the destination or reset it to default without restart; prior roots remain known so existing task attachments keep working, and user-visible downloads are not auto-deleted or removed on Telegram disconnect.
Web file transfer imports now default to the visible ~/Downloads/Equinox Local/Web/ folder when file_import has no explicit destination. Control Center can change/reset that default immediately, and user-visible imported files are not auto-deleted.
Fixed
Resolved release-gate CodeQL findings in authenticated-HTTP and Telegram tests, and documented the intentionally bounded/private persistence boundary for validated Telegram network state.
Removed a host-PID collision from the process-manager stop regression test so CI no longer mistakes an unrelated runner process group for a fake managed-process descendant.
Completed/cancelled Task Capsules no longer remain usable as Telegram Chat Bridge targets. Any already-pending final response may settle first, then Local auto-unbinds the Task; terminal cards keep Open in ChatGPT but cannot be rebound, and each new bridged send re-checks Task status before browser mutation.
Fixed clean first installs spawning two Equinox Local foreground shells (and therefore duplicate menu-bar/Nyx companion instances). The installer now leaves foreground-shell ownership entirely to the LaunchAgent runtime host; a fresh profile defaults the first runtime-host shell to a visible Control Center, while later restarts continue honoring the user's stored window visibility.
Fixed Turn Budget / Auto Continue passive state checks keeping Chrome's “Equinox Browser started debugging this browser” infobar visible throughout long turns. ChatGPT continuity state now comes from a narrowly scoped content-script observer/cache, while chrome.debugger remains reserved for actual browser-control and continuation-delivery mutations.
Fixed the Turn Budget elapsed counter continuing after an assistant turn had finished. Browser-bound identity now uses the latest user epoch as its primary turn key, and passive status reads retire finished turns to Idle without starting the next turn's timer before its first Local call.
Shortened debugger lifetime after one-shot Auto Continue and Fresh Chat Resume delivery mutations: a delivery-acquired attachment now releases after 250 ms, while an already-active normal browser-automation attachment keeps its existing 60-second sliding lease.
Security
Authenticated HTTP credentials remain private local data: agent schemas/results never contain the secret, trust-boundary changes clear an existing credential, request validation happens before Local attaches authentication, and the exact credential is redacted from returned response/error material. Emergency Stop blocks authenticated HTTP mutations through the normal mutation gate.
Response references are memory-only and bounded (10-minute TTL, 64 entries, 16 MiB), bind both profile ID and credential trust identity, capture only valid non-truncated JSON, resolve only strings in V1, and transiently redact resolved opaque values if a downstream service echoes them. Profile credentials are exact-redacted before any internal reference body is cached.