Added os.Logger-based logging (subsystem: com.xorbitlab.bugger) covering:
- FeishuAuthService.send(): raw HTTP request URL, method, body, auth header,
response status code, and raw response body (up to 1000 chars)
- exchangeCode(): before/after token exchange with token previews
- TokenManager.handleCallback(): each step with success/failure
- LocalOAuthServer: server start, connection received, code extracted
View logs in: Xcode debug console, or Console.app → filter 'bugger'
Also fixed type inference ambiguity in generic send<T>() calls.
Co-Authored-By: Claude <noreply@anthropic.com>
The /authen/v1/oidc/access_token and refresh_access_token endpoints return
token fields (access_token, refresh_token, expires_in) at the top level
of the JSON response, not nested under a 'data' key like standard Feishu
API responses. This caused 'Feishu API error (0): ok' — code 0 with no
wrapped data.
Changed exchangeCode and refreshAccessToken to decode OAuthTokenData
directly from the response. Removed unused decodeAPIResponse helper.
Also removed redirect_uri from token exchange body (not required by
Feishu's token endpoint).
Co-Authored-By: Claude <noreply@anthropic.com>
- SettingsWindow: widened to 500pt min, connection result on its own line
with multiline support (error messages no longer truncated)
- OAuthSetupView: clear statusMessage on error, added 'Try again' button
when authorization fails, disable Connect button while in progress
- TokenManager: guard against empty refresh token strings (was stored as ''
when Feishu didn't return refresh_token, causing confusing 'No Feishu
session' error after access token expired)
Co-Authored-By: Claude <noreply@anthropic.com>
Feishu rejected the 'bugger://' custom URL scheme redirect with 参数不合法.
Switched to the standard desktop OAuth flow: a one-shot local HTTP server
on 127.0.0.1:18923 that receives the authorization code from the browser.
Changes:
- Added LocalOAuthServer (Network.framework, one-shot HTTP listener)
- FeishuAuthService now uses dynamic http://127.0.0.1:PORT/callback redirect
- Removed CFBundleURLTypes from Info.plist (no custom scheme needed)
- Removed NSAppleEventManager handler from AppDelegate
- TokenManager.handleCallback changed from URL to code string
- OAuthSetupView starts server before opening browser
- Added offline_access scope for refresh token support
- generate_xcode_project.py: removed dev cert requirements,
auto-quotes paths with special chars
Builds successfully with xcodebuild.
Co-Authored-By: Claude <noreply@anthropic.com>
SwiftUI macOS menu bar app for tracking Feishu Bitable bugs:
- Menu bar icon with active bug count badge
- Popover with bug list sorted by priority, click to open in Feishu
- Floating always-on-top widget (NSPanel, optional)
- OAuth 2.0 flow with Feishu Open API (user_access_token + refresh)
- PollerService with configurable interval (default 5 min)
- Diff engine detecting new bugs, status/priority/assignee changes
- Native macOS notifications (UserNotifications framework)
- Keychain-backed token storage
- Settings window with field mapping, polling interval, widget toggle
- Support for custom Bitable column name mappings
- Zero third-party dependencies
17 source files across Models/Services/Views/ViewModels/Utils layers.
Xcode project generated via scripts/generate_xcode_project.py.
Co-Authored-By: Claude <noreply@anthropic.com>