文件历史

提交图

201 次代码提交

作者 SHA1 备注 提交日期
dependabot[bot] fb671d5790 chore(deps): bump axios from 1.14.0 to 1.15.0
Build & Push Docker Image / Build and push multi-arch image (push) Failing after 0s
Bumps [axios](https://github.com/axios/axios) from 1.14.0 to 1.15.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.14.0...v1.15.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.15.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-13 00:30:13 +08:00
caorushizi e32bfd1cb2 v3.5.0-beta.1 2026-04-13 00:27:24 +08:00
caorushizi 50a1a90e6a docs: rewrite README in English and polish UI translations
- Rewrite README.md in idiomatic English as the default language
- Move original Chinese README to README.zh.md, delete README.en.md
- Polish ~80 UI translation strings in en.ts for natural English
- Fix hardcoded Chinese in Skills setup commands (setting-page)
- Fix mismatched translation key: reppeatPassword → repeatPassword

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 00:19:14 +08:00
caorushizi 2406b5b617 chore(electron,server): remove verbose startup logs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 00:19:14 +08:00
caorushizi 913d645d89 fix(electron): resolve deprecation warnings and unhandled promise rejection
- Replace deprecated webContents.canGoBack/goBack with navigationHistory API
- Add try/catch to autoUpdater.checkForUpdates to handle ERR_CONNECTION_REFUSED
- Replace cross-fetch with Node native fetch to fix url.parse() deprecation
- Remove unused cross-fetch dependency

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 00:19:14 +08:00
caorushizi c7dd925a34 feat(core): add yt-dlp plugin and consolidate binary paths into --deps-dir
- Add youtube download type with yt-dlp schema (CLI args, progress regex)
- Replace 6 individual --xxx-bin flags with single --deps-dir flag
- Add BinaryNames map in Go core to auto-resolve binary paths from deps dir
- Simplify Electron/Server binary resolvers to return depsDir only
- Add yt-dlp to deps-versions.json (v2026.03.17)
- Add YouTube option to UI download form with URL auto-detection
- Fix download-terminal.tsx writing [object Object] instead of log content
- Improve error messages when binary not found (include path and type)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 00:19:14 +08:00
caorushizi 8224c68f66 refactor(ui): optimize source-extract page and browser navigation flow
Extract shared navigation logic into useBrowserActions hook, fix race conditions
in sniffing helper, add event listener cleanup in webview service, split store
selectors for granular re-renders, memoize list items, throttle ResizeObserver,
and add loading/error states to favorites list. Also remove unused getMachineId
IPC handler and fix IPC callback type signatures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 00:19:14 +08:00
caorushizi 6571fc022d refactor(ipc): namespace IPC events and consolidate similar methods
Replace flat IPC string constants with namespaced groups (browser.*,
app.*, dialog.*, shell.*, contextMenu.*, update.*) and consolidate
similar operations into generic methods:
- dialog.open/save replaces selectFile, selectDownloadDir, export/import
- shell.open replaces openDir, openUrl, openBrowser
- contextMenu.show replaces 3 separate context menu handlers
- on/off replaces rendererEvent/removeEventListener

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 00:19:14 +08:00
caorushizi 109c09a911 refactor(electron): replace screenshot hack with overlay WebContentsView for download dialog
Instead of capturing a screenshot, transferring a large DataURL via IPC,
and hiding the browser WebContentsView, use a separate overlay
WebContentsView layered above the browser view to render the download
form. This eliminates flicker, avoids potential page state loss, and
removes the inefficient screenshot transfer.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 00:19:14 +08:00
caorushizi 90d7fe578f feat(core): upgrade mediago-core to v0.2.1 and adapt log parsing
- Bump mediago-core from v0.1.0 to v0.2.1 in deps-versions.json
- Update ConsoleReg to match new structured log format:
  speed regex for B/s units, start/isLive/error patterns
- Remove --no-log flag so structured logs are visible for parsing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 00:19:14 +08:00
caorushizi 82f948cdd9 fix(ui): fix openDir using wrong field names and antd 6 form warnings
- Use correct GoEnvPath fields (configDir/binDir) instead of non-existent workspace/binPath
- Defer form.setFieldsValue after modal opens so Form is mounted
- Add Input child to hidden Form.Item with name prop to satisfy antd 6

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 00:19:14 +08:00
caorushizi 25d149e9ef feat(core): integrate mediago-core as new download type
Add mediago-core (caorushizi/mediago-core) as a fourth download type
alongside m3u8, bilibili, and direct. This enables HLS/DASH streaming
downloads using the custom Go-based downloader.

Changes span the full integration path: dependency download config,
Go Core backend (type, schema, CLI flag, binary map), binary resolution
for Electron/Server, shared TypeScript types, i18n labels, UI dropdown,
dev scripts, and Dockerfile.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 00:19:14 +08:00
caorushizi 0c377b7cb8 chore: bump version to 3.5.0-beta.0
Build & Push Docker Image / Build and push multi-arch image (push) Failing after 0s
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 17:56:51 +08:00
caorushizi c2db365729 fix(core): add User-Agent and Referer for Bilibili title fetching
Bilibili returns an error page ("出错了") when requests lack a proper
User-Agent. Add browser User-Agent and Referer headers to both
GetPageTitle (service/helpers.go) and fetchTitle (handler/util.go).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 16:12:42 +08:00
caorushizi 7e21097175 fix(core): prioritize CLI --local-dir over appStore value
When --local-dir is explicitly passed (e.g. Docker's /app/mediago/downloads),
use it directly and write back to appStore. Previously appStore's stale value
(e.g. home directory) would override the CLI flag.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 15:45:56 +08:00
caorushizi 0a36e39156 fix(core): whitelist static assets and SPA routes in auth middleware
Docker mode with --enable-auth was returning 401 for the homepage
and all static assets. Add /assets/, /favicon.ico, / and SPA
frontend routes (non-API paths without dots) to the auth whitelist.

Verified locally: homepage 200, /signin 200, /api/config 401 without key.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 12:34:16 +08:00
caorushizi 8ca4d443c4 feat(skills,docs,ui): add OpenClaw Skill with docs and settings tab
Skills:
- Rewrite SKILL.md as OpenClaw Skill (remove scripts dependency)
- Guide users to install MediaGo + initialize config in one message
- Support Chinese and English natural language commands
- Remove mediago-api.sh (use curl directly, cross-platform)

Docs:
- Add OpenClaw Skill page (zh/en/jp) with install, config, usage guide
- Add to VitePress sidebar for all 3 languages

Settings UI:
- Add "Skills 设置" tab with install command + init command
- Electron mode: init shows URL only
- Docker mode: init shows URL + API key
- One-click copy buttons

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 11:54:59 +08:00
caorushizi 05da1e1a75 fix(core): persist default download directory to config store
On first run, the CLI --local-dir value was used by the Go core
but never written to appStore. The UI reads the download directory
from /api/config (appStore), so it showed empty. Now writes the
resolved local-dir to appStore when the stored value is empty.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 01:35:48 +08:00
caorushizi b5e0456786 fix(ui): fix auth redirect using wrong field name from API
The auth status API returns { setuped: bool } but the frontend was
checking for non-existent fields (initialized, enableAuth). Fix to
use the correct field name so unauthenticated users are properly
redirected to the signin page in server mode.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 01:29:26 +08:00
caorushizi 218603ff9f refactor(video): use ID-based video streaming and fix playback issues
- Change video stream route from /videos/*filepath to /videos/:id
  (lookup file path from database by task ID instead of filename)
- Add mimeType field to Video API response so video.js knows the format
- Fix getVideoURL double-slash bug (/videos/... → //videos/...)
- Handle directory downloads: scan inside for first video file when
  CheckFileExists returns a directory (e.g. multi-part bilibili downloads)
- Remove unused videoRoot field and ServeVideo function
- Update player-ui PlaylistItem to pass full VideoItem object

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 01:22:15 +08:00
caorushizi 6f19d08a08 fix(electron): bind core service to LAN address for mobile access
Change internal flag from true to false so the Go core listens on
LAN IP instead of 127.0.0.1, enabling mobile player access via QR code.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 00:52:11 +08:00
caorushizi 5079180a31 refactor(server): use APP_NAME from env for data root directory
Load dotenv-flow to read APP_NAME, use it to derive the server data
root directory (~/.${APP_NAME}-server/) instead of hardcoding.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 00:46:44 +08:00
caorushizi b291e30b13 docs(docker,server): unify data paths under single root directory
Consolidate all persistent paths under one mountable root:
- Docker: /app/mediago/{data,logs,downloads} with single VOLUME
- Server dev: ~/.mediago-server/{data,logs,downloads}
- DB renamed from app.db to data/mediago.db for consistency
- Update docker run command in README and docs (zh/en/jp)
- Add disclaimer to README

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 00:40:11 +08:00
caorushizi 5f8b1442c9 refactor(service-runner): remove portfinder, use fixed port
Remove dynamic port finding via portfinder. ServiceRunner now uses
preferredPort directly as the fixed port. Electron mode uses port 39719.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 00:01:37 +08:00
caorushizi 1dd39a6973 chore(docker): rewrite Dockerfile and CI for GHCR multi-arch builds
- Rewrite Dockerfile as 3-stage build (Node builder → Go builder → runtime)
- Use --platform=$BUILDPLATFORM for native Node/Go compilation (no QEMU)
- Cross-compile Go binary via GOOS/GOARCH for target architecture
- Add --platform flag to download-deps.ts for target-specific deps
- Map Docker TARGETARCH to Node arch naming (amd64 → linux-x64)
- Flatten deps directory structure in runtime image
- Rewrite build-server.yml to push to ghcr.io with docker/metadata-action
- Single job multi-arch build (linux/amd64 + linux/arm64) via QEMU
- Update .dockerignore to exclude electron, docs, build artifacts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 23:14:42 +08:00
caorushizi de3b805ea0 feat(core,player-ui): refactor video API to use database and fix playback
Refactor video player API from filesystem scanning to database-backed:
- Video list queries downloads with status="success" + file existence check
- Add GET /api/v1/videos/:id endpoint for playing specific video by task ID
- Add playerUrl to /api/env response (computed from request host)
- Whitelist player/video paths in auth middleware
- Fix video URL generation to preserve folder structure (relative path)
- Fix player-ui Vite base path and video URL resolution under /player/
- Add openUrl implementation to web platform stubs
- Player-UI supports ?id= query param to auto-play specific video
- Play button now passes task.id instead of filename

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 22:45:27 +08:00
caorushizi 452bbc3b7d refactor: merge player Go backend into core
Merge the standalone mediago-player binary into mediago-core. The core
now serves the player UI at /player/ via go:embed, and provides video
listing/streaming endpoints. Video root reuses the existing download
directory (local-dir) so no separate flag is needed.

Changes:
- Add internal/video package to core (handler, service, types)
- Embed player-ui assets via //go:embed in assets/embed.go
- Add SPA handler for /player/ path
- Register /api/v1/videos and /videos/* routes in core router
- core:build now builds player-ui before Go compilation
- Remove apps/player/ entirely (Go app, scripts, configs)
- Remove VideoServer from Electron, derive playerUrl from coreUrl
- Remove player binary management from server app
- Update CI workflow to remove player go.sum cache path

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 21:05:42 +08:00
caorushizi ae50e1d995 feat: add node service 2026-04-02 20:34:37 +08:00
caorushizi 7fd898a23a fix(core,player): quote args with spaces for Windows shell mode
Node.js spawn with shell:true joins args with spaces without quoting,
so `-s -w` becomes two separate args on Windows cmd.exe. Manually
wrap args containing spaces in double quotes before passing to spawn.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 20:00:45 +08:00
caorushizi b7527a012a fix(core): fix Windows build by using array-based spawn for Go commands
Refactor core build scripts to use the same array-based spawn pattern
that fixed the player build (5349295d). The single-string command with
shell quoting caused ldflags parsing failures on Windows cmd.exe.

- Change runCommand to spawn(command, args) with shell only on Windows
- Remove Unix-only 2>/dev/null redirect in getVersion()
- Replace shell chmod glob with native Node.js chmodSync loop
- Add child process cleanup on SIGINT/SIGTERM

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 19:52:58 +08:00
caorushizi 5349295df8 fix(player): fix go build ldflags parsing on Windows
Split "-ldflags=-s -w" into separate "-ldflags" and "-s -w" args
so that "-w" is not misinterpreted as a go build flag when shell
mode is enabled on Windows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 19:05:27 +08:00
caorushizi 38a4f63269 fix(ci,player): fix Windows build and add deps download step
- Add shell option for Windows in player's runCommand to fix
  "spawn pnpm ENOENT" error (Windows needs shell:true to find .cmd)
- Add deps:download step to CI workflow so third-party tools
  (ffmpeg, BBDown, etc.) are available during packaging

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 18:52:09 +08:00
caorushizi 7c2a0474cd fix(ui): fix download progress polling and taskItem reference error
1. events.ts: progress polling was using /api/downloads/active which
   returns DB records without percent/speed fields. Changed to /api/tasks
   which returns TaskInfo with real-time progress data.

2. download-item.tsx: lint fix had renamed callback params from `task`
   to `taskItem` but missed updating all references in the function body,
   causing ReferenceError. Reverted param names back to `task`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 16:57:01 +08:00
caorushizi 8d4903bdff refactor(electron): use dynamic app name for custom URL scheme
Replace hardcoded "mediago" protocol scheme with dynamic `appName`
from environment, so community/dev builds use their own scheme
(e.g. "mediago-community://"). Applies to:

- constants: defaultScheme = appName
- main.window.ts: production URL uses defaultScheme
- browser.window.ts: same
- build.ts: CFBundleURLSchemes uses dynamic scheme

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 16:46:52 +08:00
caorushizi 7eb654b6a5 feat(core,ui): move password hashing to backend with bcrypt
Previously the frontend hashed passwords with MD5 + a hardcoded salt
before sending to the backend. This exposed the salt in client-side JS
and used an insecure hash algorithm.

Backend changes:
- Setup: accepts plain password, bcrypt hashes it, generates UUID apiKey
- Signin: accepts plain password, bcrypt verifies, returns stored apiKey
- Status: checks passwordHash instead of apiKey
- AppStore: new passwordHash field
- Middleware: add X-API-Key header support (was only reading Authorization)
- CORS: allow X-API-Key header

Frontend changes:
- Signin page: send plain password, receive apiKey from response
- Remove md5/crypto-js dependency and APIKEY_SALT_KEY constant
- api/download-task: auto-inject localPath/deleteSegments from store
  (was lost during go-adapter migration, caused EOF errors)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 16:27:09 +08:00
caorushizi 403e01b28a fix(ui): auto-inject apiKey from Zustand store on every request
Instead of manually calling setHttpApiKey() after signin, use an axios
request interceptor that reads apiKey from useAppStore.getState() on
every request. This ensures the header is always in sync with the
stored apiKey, regardless of when or how it was set.

Removed: setHttpApiKey() function (no longer needed).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 15:21:44 +08:00
caorushizi da5fa76c04 fix(ui): call setHttpApiKey after signin to fix 401 errors
After login, the apiKey was saved to Zustand/localStorage but never
set on the http axios instance header, causing subsequent API calls
to return 401.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 15:18:20 +08:00
caorushizi b2fa4d2fbc feat(ui): add response types to all api/ functions and SWR hooks
Add proper TypeScript return types to every api/ function, using
existing shared types (Favorite, Video, Conversion, AppStore, etc.)
from @mediago/shared-common.

New types added:
- GoEnvPath (api/config.ts) for /api/env response
- AuthStatus (api/auth.ts) for /api/auth/status response

Updated SWR hooks to use typed data instead of Record<string, unknown>
casts: useFavorites, useConfig, useEnvPath, useAuthApi, useConversions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 15:10:05 +08:00
caorushizi c0bbfa5b09 fix(ui): fix auth redirect in server mode
Two issues:
1. http.ts 401 handler used window.location.hash (HashRouter syntax)
   but the app uses BrowserRouter — changed to window.location.pathname
2. useAuth() blindly checked localStorage apiKey, which is always empty
   on first visit. Now queries Go Core auth status first: only redirects
   to /signin when auth is enabled and configured (or needs setup)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 14:50:51 +08:00
caorushizi f6e59e864a fix(core): allow X-API-Key header in CORS config
The UI sends X-API-Key for authentication, but the CORS AllowHeaders
config only listed Authorization. This caused preflight failures in
server mode where UI (localhost:8555) and Go Core (127.0.0.1:9900)
are on different origins.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 14:47:04 +08:00
caorushizi ee669f94ab refactor(electron,ui): improve sidebar extract toggle and cleanup
- Sidebar: toggle between embedded and external browser window mode,
  show extract page in sidebar even when opened externally
- Home page: remove redundant material extraction button
- Converter: temporarily disable video format options, keep audio only
- Electron: remove node-machine-id dependency from package.json
- Tool bar: fix combineToHomePage argument structure

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 13:28:19 +08:00
caorushizi fa79482682 fix(ui): fix converter page pagination layout
PageContainer was missing flex-col, causing pagination to render inline
with the list. Add flex-col + gap-3 to PageContainer and remove
duplicate padding/bg from the inner list container.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 13:04:07 +08:00
caorushizi 69cd2e6394 feat(ui): add pagination to converter page
Replace hardcoded { current: 1, pageSize: 500 } with dynamic pagination
state. Default pageSize is 50 with an Ant Design Pagination component
at the bottom of the list.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 13:00:24 +08:00
caorushizi b363b3dd7d refactor(electron): remove getMachineId controller method
machineId is now generated by Go Core on first startup (uuid),
so the Electron IPC handler using node-machine-id is no longer needed.

Removes: getMachineId handler, node-machine-id import, nanoid import.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 12:53:33 +08:00
caorushizi 23fc28805b feat(core,ui): generate machineId in Go Core instead of Electron IPC
Move machineId generation from Electron (node-machine-id) to Go Core.
On first startup, if machineId is empty in appStore config, Go Core
generates a UUID and persists it. This makes machineId available in
both Electron and Web modes via the config API.

UI now reads machineId from getConfig() instead of getMachineId() IPC.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 12:50:36 +08:00
caorushizi ba9e22381b fix(ui): add unwrapResponse to usePlatform() IPC method returns
PlatformApi methods via Electron IPC return { code, data, msg } objects.
After migrating from useAPI() to usePlatform(), the auto-unwrap logic was
lost, causing consumers to receive raw objects instead of extracted data
(e.g. onSelectDownloadDir() returned [object Object] instead of a path).

Fix: wrap all PlatformApi function calls in the Proxy get trap to
auto-unwrap { code, data } responses, matching the old useAPI() behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 12:43:15 +08:00
caorushizi ec2f82db37 refactor(ui): replace monolithic useAPI() with domain-specific api/ + SWR hooks
Split the monolithic useAPI() hook into a clean layered architecture:

1. api/ layer: domain-specific axios request functions
   - download-task.ts, favorite.ts, conversion.ts, config.ts, auth.ts, util.ts
   - events.ts: native EventSource for Go Core SSE (no sdk dependency)

2. SWR hooks: thin wrappers with auto-caching and mutation
   - useFavorites(), useConversions(), useConfig(), useEnvPath(), useAuthApi()

3. usePlatform(): pure Electron IPC methods (Proxy-safe delegation)

4. http.ts: axios instance with setupHttp() + response interceptor

Go SSE events and Electron IPC events are now fully separated:
- Go SSE (download/config) → api/events.ts → onDownloadEvent/onConfigChanged
- Electron IPC (webview/update) → usePlatform() → addIpcListener

Deleted: use-api.ts, go-adapter.ts, go-event-bridge.ts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 12:39:55 +08:00
caorushizi 8f47bf93af feat: size 2026-04-02 00:15:20 +08:00
caorushizi 0bb8f93e94 fix(electron,core,ui): improve startup robustness and logging
- core: move defer logger.Sync() after logger re-init to avoid nil panic
  on early startup
- electron: replace console.log with ElectronLogger in DownloaderServer
  and ElectronApp for consistent log output
- ui: add 1s delay before fetching coreUrl in Electron mode to wait for
  Go core to finish starting
- ui: guard data?.list access in converter-page to prevent crash when
  data is undefined

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 23:12:00 +08:00
caorushizi 23108c342b fix(electron): ensure window always shows regardless of Go core startup errors
Previously, init() was not awaited in index.ts, so any failure in the async
chain (e.g. getConfig() timing out) was silently swallowed and the window
was never created.

Fix:
1. Await mediago.init() in index.ts so errors surface properly
2. Move serviceInit() (window creation) before Go core startup so the UI
   always appears, even if the backend fails to start

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 16:05:16 +08:00