Skip to content

release: prepare Zyra v0.6.0 desktop candidate - #4

Merged
justelson merged 18 commits into
masterfrom
release/v0.6.0
Aug 30, 2026
Merged

release: prepare Zyra v0.6.0 desktop candidate#4
justelson merged 18 commits into
masterfrom
release/v0.6.0

Conversation

@justelson

@justelson justelson commented Aug 15, 2026

Copy link
Copy Markdown
Owner

Summary

Prepare Zyra v0.6.0 as one lockstep TUI, Desktop, and Browser candidate.

  • migrate Desktop provider execution to the Pi-backed runtime and remove production Codex executable dependencies
  • add mandatory, resumable, main-owned Desktop onboarding and secure device preference/secret boundaries
  • complete the local Browser bridge, owner-scoped Voice transport, native platform chrome, packaging, updater, signing, and runtime validation contracts
  • finish the five-step onboarding redesign with a prewarmed narrow ChatGPT auth worker, quota-free verification, fixed navigation anchors, and a lighter theme-aware background
  • add the paired Appearance system with 27 light themes, 45 dark themes, one active selector, immediate persistence, runtime System switching, Bricolage defaults, and explicit custom-accent preservation
  • fix Pi's current OAuth callback contract and refine the Connect and Review surfaces

Validation completed locally

  • Desktop and Browser TypeScript checks
  • Desktop and Browser production builds
  • onboarding, preference ownership, settings, theme, account action, Browser authorization, provider migration, and release contracts
  • theme matrix: 72 themes × 16 accents
  • packaged runtime staging/validation and Windows unsigned installation/cold-launch rehearsal
  • privacy and whitespace checks

Release policy and blockers

  • This PR creates no public tag and publishes no updater-visible release.
  • The existing unsigned Windows rehearsal remains an unpublished GitHub draft.
  • Native GitHub Actions jobs are currently prevented from starting by the repository account's billing/payment authorization lock.
  • Public merge/release still requires successful Windows/macOS/Linux CI, genuine Windows and Apple signing, and Apple notarization.
  • Failed CI, signing, notarization, updater, or publication gates must not be bypassed.

# Conflicts:
#	docs/README.md
#	package.json
- route Git and typed Voice text through tool-free agent-server utility generation\n- signal ChatGPT Frameless WebRTC directly with owner-scoped browser commands\n- retire Desktop Codex executable paths and add deterministic migration contracts
Gate setup and destructive credential IPC in main, keep connection lifecycle out of durable Agent Inbox history, and complete account/secret handling. Correct per-platform asset validation, require signing for every public tag, include license/source assets, and validate packaged launch/runtime metadata.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @justelson, your pull request is larger than the review limit of 150000 diff characters

@sourcery-ai

sourcery-ai Bot commented Aug 15, 2026

Copy link
Copy Markdown

Reviewer's Guide

This PR prepares Zyra Desktop v0.6.0 as a unified, packaged release by replacing Codex-based realtime voice with a direct ChatGPT/WebRTC integration, introducing main-owned onboarding and device preference/secret services, tightening Browser/Desktop authorization, and adding cross-platform packaging, runtime staging, and updater contracts and tests.

Sequence diagram for ChatGPT realtime voice startup

sequenceDiagram
    participant Renderer as useInstructorVoiceSession
    participant Devscope as window.devscope.assistant
    participant Service as AssistantService
    participant Runtime as ChatGptRealtimeVoiceRuntime
    participant Account as createChatGptRealtimeCall

    Renderer->>Devscope: startRealtimeVoice(input)
    Devscope->>Service: startRealtimeVoice(input, senderId)
    Service->>Runtime: start({cwd,sdp,instructions,voice,initialItems,adapterSessionId,conversationId,realtimeSessionGeneration,signal})
    Runtime->>Account: createChatGptRealtimeCall({sdp,instructions,voice,initialItems,sessionId,threadId,signal})
    Account-->>Runtime: {sdp,callId}
    Runtime-->>Service: {threadId,sdp,realtimeVersion:'v3',realtimeSessionId,adapterSessionId,realtimeSessionGeneration}
    Service-->>Devscope: startRealtimeVoice result
    Devscope-->>Renderer: startRealtimeVoice result
    Runtime-->>Service: AssistantRealtimeVoiceEvent session.started
    Service-->>Renderer: onRealtimeVoiceEvent(session.started)
Loading

File-Level Changes

Change Details Files
Replace Codex realtime voice process/signaling with direct ChatGPT Frameless WebRTC and client-command routing between main and renderer.
  • Introduce ChatGptRealtimeVoiceRuntime that owns direct WebRTC signaling via chatgpt-account.mjs, tracks sessions and generations, and emits owner-scoped client.command events.
  • Refactor foreground voice adapter to use ChatGPT capability evidence, owner-scoped client commands, typed voice response delivery, and transcript identity-bearing WebRTC events.
  • Update renderer voice session hook to bind to owner-specific adapterSessionId/realtimeSessionId/generation, queue and dedupe client commands, and coordinate response activity with oai-events data channel.
  • Expand realtime transcript handling and tests to consume new WebRTC transcript events, deduplicate optimistic typed bubbles, and enforce provider identity constraints.
desktop/src/main/assistant/codex-realtime-voice.ts
desktop/src/main/assistant/voice/codex-realtime-foreground-adapter.ts
desktop/src/main/assistant/voice/codex-realtime-capability-probe.ts
desktop/src/main/assistant/codex-realtime-voice-contract.ts
desktop/src/renderer/src/pages/assistant/useInstructorVoiceSession.ts
desktop/src/renderer/src/pages/assistant/instructor-voice-transcript.ts
desktop/scripts/test-assistant-realtime-voice.ts
desktop/scripts/test-assistant-voice-core.ts
desktop/src/shared/assistant/contracts/realtime-voice.ts
Add ChatGPT account realtime call helper and utility connection test paths wired through Zyra Pi runtime and agent server.
  • Implement chatgpt-account.mjs realtime call builder with strict SDP, header, timeout, and initial_items bounds plus callId parsing.
  • Expose getChatGptAccountAuthStatus and createChatGptRealtimeCall for Desktop voice runtime and Pi utility paths.
  • Extend zyra-sdk warmup and listAvailableModels to support skipAvailability and reuse provider registry without live pings.
  • Add ZyraPiRuntime.generateText and testChatGptUtilityConnection and bridge them through the agent server for no-session utility text generation.
src/chatgpt-account.mjs
src/zyra-sdk.mjs
src/agent-server/server.mjs
scripts/test-zyra-agent-server.mjs
scripts/test-chatgpt-realtime-call.mjs
Introduce mandatory Desktop onboarding, device preference, and device secret services, and gate Assistant, updates, Browser bridge, and IPC on setup completion.
  • Add DevicePreferencesService with shared/surface key ownership, revision-based updates, Desktop v4 migration, and per-surface snapshots.
  • Add DeviceSecretsService using Electron safeStorage for Groq/Gemini keys, legacy migration, confirmation on destructive clears, and OS-unavailable handling.
  • Implement OnboardingService with ordered steps, main-owned checkpoints, recovery from corrupt/invalid/future schemas, and OpenAI connection verification via OpenAIConnectionService.
  • Wire setup services into main index bootstrap, BrowserClientRuntime, IPC handlers, and renderer Settings/Onboarding context and gate Assistant, updates, and Browser Assistant/devscope before completion.
desktop/src/main/setup/device-preferences-service.ts
desktop/src/main/setup/device-secrets-service.ts
desktop/src/main/setup/onboarding-service.ts
desktop/src/main/setup/openai-connection-service.ts
desktop/src/main/setup/index.ts
desktop/src/main/index.ts
desktop/src/main/ipc/handlers/setup-handlers.ts
desktop/src/main/ipc/onboarding-ipc-gate.ts
desktop/src/preload/adapters/setup-adapter.ts
desktop/src/shared/preferences/contracts.ts
desktop/src/shared/preferences/secrets-contracts.ts
desktop/src/shared/onboarding/contracts.ts
desktop/src/renderer/src/lib/settings.tsx
desktop/src/renderer/src/lib/onboarding.tsx
desktop/src/renderer/src/onboarding/OnboardingGate.tsx
desktop/src/renderer/src/onboarding/OnboardingFlow.tsx
desktop/src/renderer/src/onboarding/OnboardingSteps.tsx
desktop/src/renderer/src/onboarding/BrowserSetupRequired.tsx
desktop/scripts/test-onboarding-state.ts
desktop/scripts/test-device-preference-ownership.ts
desktop/scripts/test-device-secret-renderer-boundary.ts
desktop/scripts/test-onboarding-ipc-gate.ts
desktop/scripts/test-onboarding-renderer-gate.ts
desktop/scripts/test-onboarding-browser-authorization.ts
Stage and validate a packaged Zyra runtime, pin native dependencies, and add cross-platform desktop packaging, signature/notarization verification, and release asset contracts.
  • Add zyra-runtime staging script and manifest builder, validate source and dependencies, and have resolveZyraRoot prefer resources/zyra-runtime in packaged apps.
  • Pin Electron 43.4.0, electron-builder 26.15.3, and node-pty 1.1.0, disable npmRebuild, and smoke node-pty under Electron via test-node-pty-electron.mjs and verify-node-pty-install.mjs.
  • Define platform-specific artifact naming and electron-builder targets (Windows NSIS, macOS dmg/zip universal, Linux AppImage/deb) plus macOS entitlements, icons, and sidecar resources.
  • Add release-contract helpers (asset names, updater contracts, SHA256SUMS), validate-packaged-app and signature markers, platform packaging script, prepare-release-resources staging, and GitHub Actions desktop-ci and desktop-release workflows.
desktop/package.json
desktop/package-lock.json
package.json
package-lock.json
desktop/src/main/zyra/zyra-root.ts
desktop/scripts/release/runtime-contract.mjs
desktop/scripts/release/stage-zyra-runtime.mjs
desktop/scripts/release/validate-zyra-runtime.mjs
desktop/scripts/release/node-pty-electron-smoke.cjs
desktop/scripts/release/test-node-pty-electron.mjs
desktop/scripts/release/verify-node-pty-install.mjs
desktop/scripts/release/release-contract.mjs
desktop/scripts/release/validate-packaged-app.mjs
desktop/scripts/release/package-desktop.mjs
desktop/scripts/release/prepare-release-resources.mjs
desktop/scripts/release/verify-platform-signature.mjs
desktop/scripts/release/validate-github-draft.mjs
.github/workflows/desktop-ci.yml
.github/workflows/desktop-release.yml
desktop/electron.vite.config.ts
desktop/vite.browser.config.ts
desktop/build/entitlements.mac.plist
desktop/build/entitlements.mac.inherit.plist
desktop/scripts/test-packaged-runtime-contract.ts
desktop/scripts/test-desktop-release-contract.ts
desktop/scripts/test-desktop-updater-release-feed.ts
desktop/scripts/test-release-asset-contract.mjs
Tighten Browser↔Desktop Assistant bridge and devscope authorization, including setup-aware gating, preferences scoping, and update-feed selection for all platforms.
  • Extend BrowserAssistantBridge to depend on optional AssistantService via getService(), close streams when onboarding revokes access, and scope preferences calls to the browser surface.
  • Adjust browser devscope adapter to expose onboarding/preference events, gate Desktop-only window and setup actions, and report host Desktop version and release channel using build metadata.
  • Generalize GitHub release feed logic for Windows, macOS, and Linux, respecting per-platform artifacts, semver/channel precedence, and current channel eligibility.
  • Add local update-feed server that validates platform assets before serving and adapt check-github-update-feed to surface platform/arch, metadata file, and feed URL.
desktop/src/main/assistant/browser-assistant-bridge.ts
desktop/src/renderer/src/lib/browser-devscope-adapter.ts
desktop/src/shared/browser-assistant-bridge.ts
desktop/src/main/update/github-release-feed.ts
desktop/scripts/maint/check-github-update-feed.mjs
desktop/scripts/maint/serve-update-feed.mjs
desktop/src/renderer/src/lib/app-updates.tsx
desktop/src/renderer/src/lib/release-build-metadata.ts
desktop/scripts/test-browser-assistant-bridge.ts
desktop/scripts/test-browser-client-host.ts
desktop/scripts/test-browser-devscope-live-adapter.ts
Refine host window chrome policy and renderer title bars for cross-platform native frame usage and custom controls, and report host runtime in About/settings/terminal UI.
  • Add platform-window-chrome resolver for nativeFrame/customWindowControls/titleBarStyle and use it in main window creation and IPC window runtime info.
  • Update Assistant and Quick Preview title bars to use useWindowChrome runtime/policy, align padding for macOS traffic lights, and conditionally render window control buttons.
  • Expose window runtime info and app-menu commands via preload adapter and wire renderer TitleBar to respond to platform-native menu actions.
  • Reflect host platform, version, channel, Electron/arch, and license in About settings and terminal runtime settings, and update settings search targets to match new wording.
desktop/src/shared/platform-window-chrome.ts
desktop/src/main/index.ts
desktop/src/main/ipc/handlers.ts
desktop/src/preload/adapters/window-adapter.ts
desktop/src/renderer/src/lib/useWindowChrome.ts
desktop/src/renderer/src/components/layout/TitleBar.tsx
desktop/src/renderer/src/pages/QuickPreviewTitleBar.tsx
desktop/src/renderer/src/pages/settings/AboutSettings.tsx
desktop/src/renderer/src/pages/settings/TerminalRuntimeSettings.tsx
desktop/src/renderer/src/pages/settings/settings-search.ts
desktop/scripts/test-platform-window-chrome.ts
Re-home hosted AI provider credentials (Groq/Gemini) to main-owned OS-encrypted storage and adjust Git provider selection and AI settings UI accordingly.
  • Remove direct groqApiKey/geminiApiKey usage from renderer, add groqApiKeyConfigured/geminiApiKeyConfigured flags, and use DeviceSecretsService to store encrypted keys.
  • Change Git provider resolution to rely on configured-hosted flags rather than localStorage, and update labels to use 'Zyra · ChatGPT' for the codex provider.
  • Revise AI settings to use Desktop-only actions for adding/replacing/clearing hosted keys, add a destructive clear confirmation, and ensure API keys never return to the renderer after saving.
  • Adjust settings tests and logs to reflect provider renames and secret boundaries.
desktop/src/renderer/src/lib/settings.tsx
desktop/src/renderer/src/lib/gitAi.ts
desktop/src/main/ipc/handlers/settings-ai-handlers.ts
desktop/src/renderer/src/pages/settings/AISettings.tsx
desktop/src/renderer/src/pages/settings/ai-settings/AISettingsCards.tsx
desktop/src/renderer/src/pages/settings/ai-settings/aiSettingsConfig.ts
desktop/src/renderer/src/pages/settings/LogsSettings.tsx
desktop/scripts/test-device-secret-renderer-boundary.ts
Document updated release, voice-agent architecture, repository map, and contribution policies to match the v0.6.0 packaging and voice/runtime changes.
  • Rewrite RELEASE.md with lockstep version policy, packaged runtime contract, native matrix, updater feed validation, CI/release workflows, signing/notarization gates, release checks, and licensing.
  • Extend README.md with Open Voice-Agent Architecture section and licensing/provenance notes and link into docs/architecture/voice-agent.
  • Update docs/architecture and docs/repository-map.md to cover onboarding, device preferences, local browser client, agent server, voice-agent ADRs, and ignored generated directories.
  • Add CONTRIBUTING.md, voice-architecture proposal issue template, and PR template to guide public contributions and voice-architecture changes.
RELEASE.md
README.md
docs/README.md
docs/architecture/agent-server.md
docs/architecture/agent-surface.md
docs/architecture/local-browser-client.md
docs/handoffs/desktop-root-migration.md
docs/repository-map.md
docs/security/agent-control.md
docs/architecture/canonical-chat-integrity.md
docs/architecture/desktop-onboarding-and-device-preferences.md
CONTRIBUTING.md
.github/ISSUE_TEMPLATE/voice-architecture-proposal.yml
.github/PULL_REQUEST_TEMPLATE.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cfd773d8a0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +125 to +126
await sdk.configureZyraOpenAIApiKey(key)
await sdk.verifyZyraOpenAIApiAuth()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Persist an API model when API-key setup succeeds

When a new user completes onboarding with only an API key, both verification results are discarded and no openai/... model is written to assistantDefaultModel. The new-chat composer consequently falls back to its canonical latest model, openai-codex/gpt-5.6-sol, which requires the ChatGPT subscription credential the user does not have; their first chat therefore fails until they discover Account settings and manually choose “Use for new chats.” Derive an API-backed model from the verification response and save it as the new-chat default as part of this setup path.

Useful? React with 👍 / 👎.

function isUsableSubscription(status: ChatGptStatusResult): boolean {
if (status.status?.configured !== true) return false
if (status.usage && !status.usageError) return true
if (!status.tokenExpiresAt || status.usageError) return false

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Accept unexpired subscriptions when usage lookup fails

If the ChatGPT usage endpoint is temporarily unavailable or rate-limited, buildChatGptAccountStatus supplies both usageError and the OAuth token expiry, but this condition immediately rejects the account without checking that unexpired token. Because onboarding calls this predicate before allowing the Connect and Review steps to complete, an otherwise valid signed-in user can be locked out by a transient usage-service failure; the existing expiry fallback should remain usable when usage cannot be fetched.

Useful? React with 👍 / 👎.

Persist active theme choices across setup and Settings, add the browser-first OpenAI auth boundary, refine the mandatory onboarding surfaces, and expand the validated light/dark theme catalogs with focused contracts.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6cc8f0a450

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +190 to +193
const result = await window.devscope.onboarding.disconnectOpenAI({ method: disconnectMethod, confirmed: true })
if (!result.success) throw new Error(result.error || 'Could not disconnect OpenAI.')
setConnections(result.status)
setDisconnectMethod(null)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reassign the default before disconnecting its provider

When the disconnected method owns settings.assistantDefaultModel and the other connection remains verified, this success path updates only the connection state and leaves the removed provider’s model as the new-chat default. The page therefore continues to report that provider as configured, and subsequent chats attempt to use a credential that was just deleted until the user manually selects “Use for new chats”; switch the default to an available model or clear it as part of this disconnect path.

Useful? React with 👍 / 👎.

@justelson
justelson merged commit f1b1904 into master Aug 30, 2026
2 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant