This repository was archived by the owner on Mar 7, 2026. It is now read-only.
feat: ChatGPT OAuth login and live agent session#9
Merged
Conversation
Rhai-powered REPL with terminal aesthetic, slash commands mapped to all 33 FFI functions, markdown rendering, and full accessibility. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Covers Rhai engine setup, function registration verified against source, Kotlin terminal UI, slash commands, Room migration, state refresh after mutations, and Console deprecation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add rhai 1.21 with sync feature to Cargo.toml. Derive serde::Serialize on all 9 FFI record/enum types (FfiCostSummary, FfiBudgetStatus, FfiComponentHealth, FfiHealthDetail, FfiCronJob, FfiSkill, FfiSkillTool, FfiToolSpec, FfiMemoryEntry) so they can be serialized to JSON for the terminal REPL output. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bundle JetBrains Mono v2.304 Regular and Bold weights as Android font resources and define TerminalTypography that overrides body, label, and title styles with the monospace font family while preserving sp-based sizes for Android 14+ nonlinear font scaling. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rsistence Add the Room persistence layer for terminal REPL history: - TerminalEntry domain model with content, entryType, timestamp, imageUris - TerminalEntryEntity Room entity (terminal_entries table) - TerminalEntryDao with observeAll, insert, and deleteAll operations - TerminalEntryRepository interface and RoomTerminalEntryRepository impl - Entity mapper extensions in EntityMappers.kt - Database migration 7->8 creating the terminal_entries table - Wired into ZeroClawApplication for manual DI Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…r composables - TerminalBlock: sealed interface with Input, Response, Structured, Error, and System variants for the REPL scrollback buffer - BrailleSpinner: animated braille dot spinner matching Claude Code CLI with power-save fallback to static ellipsis - TerminalOutputRenderer: composable functions that render each block variant with JSON pattern detection, accessibility semantics, and long-press copy support - Fix detekt CognitiveComplexMethod suppression in CommandRegistry - Apply spotless formatting to Type.kt and ZeroClawApplication.kt Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…and history Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ibility Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…om bar Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…inal REPL Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ting violations Rename internal MutableStateFlow fields that lack matching public properties to drop the underscore prefix (loadingState, pendingImagesState, processingImagesState). Apply spotless auto-format to import ordering and expression wrapping across 4 files. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Defence-in-depth: set max operations (100K), expression depth (32/16), string size (64KB), array size (1024), map size (256), and call stack depth (16). Two new tests verify infinite loops and deep recursion are terminated by the sandbox. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ommands When the terminal REPL executes a mutating command (cron add, skill install, send, etc.), emit a RefreshCommand through a SharedFlow on ZeroClawApplication so DaemonViewModel immediately re-fetches the affected data instead of waiting for the 15-30 second poll cycle. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Delete ChatMessage model, entity, DAO, and repository (5 files). Add Room migration v8→v9 to drop the chat_messages table. Replace the daemon restart handler's chatMessageRepository.clear() with terminalEntryRepository.clear(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace hardcoded /c/Users/Natal paths with $HOME-relative or env-var-with-fallback patterns in scripts. Gitignore .cargo/config.toml (contains machine-specific NDK linker paths) and add a .template. Delete terminal REPL plan/design docs (implementation complete). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Modern OpenAI keys use sk-proj-... prefix (up to 156 chars). The
startsWith("sk-") validation already accepts them correctly, but
the hint text was stale. Updated to "sk- (usually sk-proj-...)".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add ProviderAuthType.API_KEY_OR_OAUTH enum value and oauthClientId field to ProviderInfo for providers that support OAuth login alongside API keys. Update OpenAI entry to use the new auth type with client ID app_EMoamEEZ73f0CkXaXp7hrann, and refresh its suggested models to the current GPT-5/o-series lineup (gpt-5.2, gpt-5-mini, gpt-5-nano, o3, o4-mini, gpt-4.1, gpt-4.1-mini, gpt-4.1-nano). Also downgrade androidx.browser from 1.9.0 to 1.8.0 for compileSdk 35 compatibility. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add the core PKCE OAuth logic for the OpenAI authorization code flow, mirroring the upstream Rust implementation. Includes PKCE state generation, authorize URL construction, and token exchange via HttpURLConnection. Uses java.util.Base64 (not android.util.Base64) for JVM test compatibility. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements a lightweight HTTP server on localhost:1455 (with fallback to 1456) that captures the OAuth redirect callback from the browser. The server extracts the authorization code and state from query params, serves a success HTML page, and exposes the result via a coroutine CompletableDeferred. Includes two unit tests: callback extraction and timeout behavior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add provider parameter to refresh() with Anthropic default, provider-specific refresh URLs (Anthropic/OpenAI), OpenAI client_id in request body, and fallback when OpenAI omits refresh_token in response. Update ApiKeyRepository call site to pass key.provider. Add unit tests for refreshUrlForProvider. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…inator Wire the PKCE OAuth flow into the onboarding wizard. Add isOAuthInProgress, oauthEmail, oauthRefreshToken, and oauthExpiresAt fields to ProviderStepState. Implement startOAuthLogin() and disconnectOAuth() methods in the coordinator, and pass OAuth tokens through to ApiKey on completion. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add OAuth UI to ProviderSetupFlow: a "Login with ChatGPT" button with progress indicator, "or use API key" divider, and OAuthConnectedChip for the connected state. Wire the OAuth state and callbacks through ProviderStep into the onboarding ProviderStepCollector. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add startOAuthLogin() to ApiKeysViewModel with full PKCE flow using OAuthCallbackServer and OpenAiOAuthManager. In ApiKeysScreen, show "ChatGPT Login" label for OAuth tokens instead of masked key text and add a "Login with ChatGPT" button. Bump detekt TooManyFunctions threshold to accommodate the new method. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Hide openai-codex as internal provider (not user-selectable), fix port-aware redirect URIs for token exchange, clean up stale openai keys on successful OAuth, migrate agents to openai-codex provider, remove standalone OAuth button from API keys list, and add AuthProfileWriter for auth-profiles.json persistence. All three entry points (onboarding, connections, settings) now share identical OAuth flow via ProviderSetupFlow. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix reliability.api_keys type mismatch: emit flat Vec<String> array instead of dotted TOML table keys - Align default values to upstream schema.rs: gateway port (42617), max_actions_per_hour (100), max_cost_per_day_cents (1000), provider_backoff_ms (500), max_cpu_time_seconds (60), max_subprocesses (10) - Add coerceAtLeast(0) on all 24 integer fields that map to unsigned Rust types (u16/u32/u64/usize) to prevent TOML parse errors like "archive_after_days = -1" - Extract appendReliabilityApiKeys helper to fix detekt complexity - Clamp memory hygiene inputs in MemoryAdvancedScreen UI Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add SetupRoute data object for the post-onboarding daemon setup screen and a configuredChannelNames() suspend bridge method wrapping the new get_configured_channel_names FFI function. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace all daemonBridge.markRestartRequired() calls with triggerHotReload() which shows a SetupBottomSheet progress overlay when the daemon is running. Falls back to markRestartRequired() when the daemon is stopped. Adds config building helpers that mirror SetupViewModel/ZeroClawDaemonService patterns for constructing the TOML before calling SetupOrchestrator.runHotReload(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix detekt LongMethod: extract pollChannelHealth() and markChannelsTimedOut() from stepAwaitChannels in SetupOrchestrator - Fix detekt TooManyFunctions: bump class threshold from 23 to 24 - Fix detekt LargeClass: suppress pre-existing violation on ApiKeysViewModel - Fix detekt UnusedParameter: remove unused expectedChannels param - Fix spotless: reformat splitCsv single-expression function - Fix build: add futures-util dependency for streaming module - Fix build: add ACTION_OAUTH_HOLD constant and handleOAuthHold() to ZeroClawDaemonService (was referenced but never committed) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add SetupState.kt (SetupStepStatus/SetupProgress) and SetupViewModel.kt (secure ByteArray key handling with zero-fill) that were missing from earlier commits. Also harden security posture: - Sanitize streaming errors through LogSanitizer before Log.e - Mark terminal clipboard copies as IS_SENSITIVE (Android 13+) - Gate OAuth debug logs behind BuildConfig.DEBUG Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The onboarding OAuth flow was missing the Android 12+ process-freezing mitigation that the settings flow already had. When the user switched to a 2FA app during OAuth, Android's cached-app freezer would freeze the process and the NanoHTTPD callback server, causing the redirect to hang indefinitely. Add holdForegroundForOAuth(), releaseOAuthHold(), and bringAppToForeground() mirroring the pattern in ApiKeysViewModel. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…aemon Two bugs fixed: 1. Fresh install skipped SetupScreen: markComplete() in completeInternal() triggered AppShell recomposition before navigation to SetupRoute fired, causing the NavHost to reinitialize with DashboardRoute as start destination. Fix: move markComplete() to SetupViewModel.startSetup() so onboarding is only marked complete after the setup pipeline runs. 2. Re-run wizard failed with "daemon already running": runFullSetup() called daemonBridge.start() unconditionally. Fix: add stopDaemonIfRunning() check before stepStartDaemon() that gracefully stops any existing daemon instance first. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix extractFromIdentity() to navigate nested AIEOS JSON structure instead of flat root-level lookup (agent name under identity.names.first, other keys under identity object) - Fix identity key constants to match actual JSON keys (user_name, communication_style) - Move markComplete() to after setup pipeline completes - Replace broken OpenAI CDN icon URLs with Google Favicon API - Add ChatGPT favicon to OAuth login button in ProviderSetupFlow Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Intercept chat messages in TerminalViewModel when no provider is configured, showing a helpful system message instead of a cryptic auth error. Admin/scripting commands remain unaffected. Welcome banner now indicates "Admin Console" mode when unconfigured. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Defines the architecture for turning the blocking REPL into a live agent session with streaming responses, tool execution transparency, auto-compaction, and session seeding from Room persistence. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
13-task implementation plan covering Rust FFI session module, on_delta parser, Kotlin streaming state, ThinkingCard tool activity, and dual-path dispatch in TerminalViewModel. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add tokio-util 0.7 with the rt feature to support CancellationToken for cooperative cancellation in the upcoming session send loop. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduce the session module with: - Session struct and global singleton for single-session lifecycle - SessionMessage UniFFI record for FFI-safe conversation messages - FfiSessionListener callback interface with 10 event methods - dispatch_delta() parser that converts upstream emoji-prefixed progress strings into typed listener callbacks - parse_tool_completion() helper for extracting tool name and duration - 11 unit tests covering all delta dispatch paths and edge cases Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add clone_daemon_config() and clone_daemon_memory() runtime helpers, and implement session_start_inner() which mirrors upstream agent::run() setup: resolves provider/model/temperature from daemon config, builds Android-appropriate tool descriptions, queries native tool support via a temporary provider, constructs the full system prompt via build_system_prompt_with_mode, and stores the Session singleton. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add the core agent loop (session_send_inner) with provider chat integration, memory context building, history compaction, and cooperative cancellation via CancellationToken. Implement all lifecycle functions: session_seed_inner, session_cancel_inner, session_clear_inner, session_history_inner, and session_destroy_inner. Tool specs are passed for provider awareness but execution is deferred (SecurityPolicy is pub(crate) upstream). All 175 tests pass, clippy clean with -D warnings. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SecurityPolicy is pub(crate) in upstream zeroclaw, blocking all_tools_with_runtime() from the FFI crate. This commit adds FFI-specific tool wrappers for MemoryStoreTool and MemoryForgetTool that bypass SecurityPolicy (unnecessary on Android where user initiates all actions). Uses upstream MemoryRecallTool, CronListTool, CronRunsTool, and WebSearchTool directly (no SecurityPolicy needed). The agent loop now executes real tools instead of returning "Tool execution is not available" stubs: - memory_store, memory_recall, memory_forget (full CRUD) - cron_list, cron_runs (scheduling visibility) - web_search (when configured) - Unknown tools get a graceful "not available" fallback Also adds async-trait dependency for Tool trait implementation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Exports session_start, session_seed, session_send, session_cancel, session_clear, session_history, and session_destroy through UniFFI for Kotlin binding generation. All wrapped in catch_unwind with FfiError return types following the existing pattern. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds TOOL_EXECUTING and COMPACTING phases to StreamingPhase enum. Introduces ToolProgress and ToolResultEntry data classes for tracking in-flight and completed tool executions. ThinkingCard now shows a tool activity footer below thinking text: active tools with hourglass indicators, completed tools with success/failure icons and duration. Follows Material 3, accessibility, and battery-conscious rendering conventions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add KotlinSessionListener implementing FfiSessionListener with
MutableStateFlow.update{} for thread-safe streaming state transitions.
Dual-path dispatch: slash commands route to Rhai, chat messages to
agent session via sessionSend(). Wire TerminalScreen to display
ThinkingCard during agent turns, StreamingResponseBlock for progressive
response rendering, and disable input during active streaming.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update TOOL_CALL_TAG_REGEX to match self-closing format (<tool_call name="..." args="..."/>) leaked by some models. Add stripToolCallTags to KotlinSessionListener.onComplete so agent session responses get the same tag stripping as Rhai responses. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Upstream AIEOS renderer only outputs agent identity fields (name, bio, personality). Android onboarding also stores user_name, timezone, and communication_style in the identity JSON, but these are silently dropped by serde since the upstream IdentitySection struct lacks them. Add append_android_identity_extras() to parse the raw aieos_inline JSON and append a "## User Context" section with the user's name, timezone, and preferred communication style. Includes 3 unit tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
# Conflicts: # scripts/lint-all.sh # scripts/release.sh # scripts/test-local-all.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
/status,/cost, etc.) remain instant via Rhai.Test plan
🤖 Generated with Claude Code