Add OAuth provider flows and agent runtime fixes#58
Merged
Conversation
…ding isAwaitingReply in light rows and tracking local streamingThreadId
…h to POSIX-only on Windows, fix URL/local-path detection Task* tools (TaskCreate / TaskList / TaskGet / TaskOutput / TaskUpdate / TaskStop) take over from TodoWrite. They are not a todo list — they are thin handles over the existing managedSubagents runtime: TaskCreate spawns a sub-agent in the background and returns immediately, then the model can poll/inspect/drive/cancel via the other five. Prompt guidance now explicitly tells the model NOT to use TaskCreate as a personal todo list, removing the old "proactive TodoWrite" nudges that caused the model to write task lists for trivial work. The legacy TodoWrite tool definition is removed from the model surface but its executor case is kept so historical thread transcripts still parse. Bash tool now requires POSIX bash on every platform. detectShell prefers Git Bash / MSYS2 / Cygwin / WSL on Windows and refuses to fall back to PowerShell for the LLM tool — the prompt and tool description no longer have any "Windows uses PowerShell / avoid sed/awk" caveats, and the Windows-side Unix command interceptor in the executor is gone. PowerShell provider is kept for the built-in terminal profiles only. AgentRightSidebar URL normalization no longer treats Windows drive paths as URL schemes (`D:\foo`, `C:/bar` were being opened as protocols, then read_page hung). The scheme regex now requires 2+ chars, and an explicit local-filesystem-path detector routes such inputs to a Bing search. Bottom-bubble CSS: clamp long user messages to a few lines with an ellipsis instead of the previous scrollable max-height layout. All 563 vitest tests pass; tsc --noEmit is clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds 11 Feishu-specific platform-scoped tools available only when an
integration has platform === 'feishu' and valid app credentials. Tools
are mounted as a per-turn bundle inside the bot leader pool, so other
platforms (Telegram/Slack/Discord) never see them.
Tools:
Tasks (4): list_feishu_tasks, create_feishu_task,
update_feishu_task, delete_feishu_task
Contacts (1): get_feishu_users (search by name OR batch by id)
Documents (4): create_feishu_document, get_feishu_document_blocks,
batch_create_feishu_blocks, search_feishu_documents
Folders (2): get_feishu_folder_files, create_feishu_folder
Document/folder tools work with tenant_access_token. Task and contact
tools require user_access_token; they are filtered out of the leader
tool pool when the integration has no user token, so the LLM never
sees a tool it cannot successfully call.
A compact block-descriptor -> Feishu docx_v1 payload converter covers
text/heading/list/code/quote/divider/callout, sized for what an agent
actually needs to write. The 681-line upstream blockFactory is not
ported.
OAuth flow:
- feishu:runOauth IPC binds a local HTTP callback server on
127.0.0.1 with a fixed port chain [53782, 53783, 53784],
opens accounts.feishu.cn/.../authorize via shell.openExternal,
awaits the redirect with state CSRF check + 5-minute timeout,
exchanges the code via client.authen.oidcAccessToken.create,
fetches open_id and display name via authen.userInfo, persists
tokens via a new updateBotIntegrationFeishuTokens helper that
writes settings.json in place without round-tripping through
the renderer.
- feishuApiClient owns a mutable token holder. Before every
user-token call it checks expiresAt against a 60-second leeway
and serializes refresh through a single in-flight Promise to
coalesce concurrent callers. On 99991661/99991663/99991664 it
runs one forced refresh and retries the failed request once.
Refreshes are persisted via an onTokensRefreshed callback wired
from botRuntime to settingsStore.
- feishu:cancelOauth aborts an in-flight flow; feishu:disconnect
clears tokens; feishu:getCallbackUrls exposes the three URLs the
user needs to allowlist in their Feishu app.
UI: SettingsBotsPanel grows a FeishuAuthSection with a status pill
("Not authorized" / "Authorized as Alice · 1h45m remaining"), an
Authorize button (disabled until appId/appSecret are filled), a
cancel button while the flow is open, a disconnect link, and inline
hints listing the three required redirect URLs and the required
Feishu scopes (task:task, contact:user.base:readonly). A 30-second
tick re-renders the remaining-time label.
Leader prompt: when feishu tools are mounted, the orchestrator system
prompt explicitly instructs the LLM to use them only on user-driven
Feishu requests, not to advertise them spontaneously, and surfaces a
different tool list depending on whether user_access_token is present.
Type changes: FeishuBotConfig grows userRefreshToken,
userAccessTokenExpiresAt, userAuthorizedOpenId, userAuthorizedName.
Twin types in main-src/botSettingsTypes.ts and src/botSettingsTypes.ts
stay in lockstep.
Tests: 7 new files / 50 cases under main-src/bots/platforms/feishu.
Coverage includes platform scoping, per-tool argument shaping,
pagination, nested subtask creation with per-path error capture,
search-vs-batch user lookups, OAuth state mismatch, timeout, cancel,
exchange failure, and refresh + retry-on-401 in the API client.
Also includes a small unrelated provider-identity settings tweak
that was already staged.
All 99 vitest files / 613 tests pass; tsc --noEmit is clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Append OAuth login providers instead of replacing existing accounts. Group manual and OAuth providers in settings and show login failures via toast. Use the system browser for legacy Codex login and add provider expand animations.
Force OAuth providers to use their matching runtime identities, repair Antigravity project discovery and fallback behavior, and remove Async-specific Codex login artifacts.
Agent write-file snapshots used to live only in `agentRevertSnapshotsByThread`
in main memory, so an app restart silently emptied the map. The renderer
ignored the backend's `reverted: 0` reply and hid the file-changes panel
anyway, leaving the on-disk edits intact while pretending the user had
rolled them back.
This change makes revert actually work across restarts and stops faking
success when it cannot:
* New `agentSnapshotStore` writes each thread's snapshots to
`{userData}/async/agent-snapshots/{threadId}.json` via atomic
tmp+rename. `initAgentSnapshotStore` repopulates the in-memory map at
app boot.
* Every snapshot mutation now flushes to disk: `beforeWrite` hook,
per-turn reset in `runChatStream`, and the keep/revert/seed/accept-hunk
/revert-hunk IPC handlers. `threads:delete` clears the matching file.
* New `agent:hasSnapshots` IPC lets the renderer learn the truly
revertable path set so the panel can disable buttons that would no-op.
* `useAgentPatchActions` now inspects `reverted` from `agent:revertLastTurn`
/ `agent:revertFile`. When zero, it skips the dismiss/persist path and
raises a notice instead. The panel renders a warning banner and greys
out revert buttons with a tooltip explaining the snapshot is gone.
* App refreshes the revertable set on thread switch and after each turn
finishes (awaiting-reply true→false transition).
* Adds en/zh i18n strings for the new banner / tooltip / dismiss button.
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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
Verification