Files
CodePilot/electron/preload.ts
T
7418andClaude Opus 4.6 8154130035 feat: add Setup Center onboarding and move commit/push to Git panel
Add a skippable first-use Setup Center that guides users through three
prerequisites: Claude Code CLI detection, API provider configuration,
and default project directory selection. Replace passive fail-then-hint
patterns with proactive guidance and actionable error recovery.

Setup Center (13 new files):
- SetupCenter overlay with 4 cards (Welcome, ClaudeCode, Provider, ProjectDir)
- Auto-close only when user completes last card in current session
- Re-openable from Settings > General > "首次设置引导"
- Claude Code conflict detection with per-install-type uninstall commands
- Provider detection covers DB providers, env vars, and legacy app-settings token
- ANTHROPIC_BASE_URL excluded from credential check (not a real credential)
- skipped != completed: /chat still prompts for provider after skip

Project directory:
- Validation via /api/files/browse before trusting saved paths
- Fallback chain: localStorage → setup_default_project → empty state
- Cross-component sync via project-directory-changed CustomEvent

Toast system:
- Global showToast() API with success/error/warning/info types
- FIFO eviction (max 3), action button support

Git panel:
- Move Commit + Push buttons from UnifiedTopBar into GitStatusSection
- Push enabled for new branches (backend auto-handles -u origin)

Other:
- Windows top-bar safe zone (138px spacer for caption buttons)
- Cross-platform path splitting with /[\\/]/ regex
- Platform-aware file manager name (Finder/Explorer/Files)
- ~80 new i18n keys (en + zh)
- Handover doc: docs/handover/onboarding-setup-center.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 15:19:52 +08:00

53 lines
2.2 KiB
TypeScript

// eslint-disable-next-line @typescript-eslint/no-require-imports
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
versions: {
electron: process.versions.electron,
node: process.versions.node,
chrome: process.versions.chrome,
platform: process.platform,
},
shell: {
openPath: (folderPath: string) => ipcRenderer.invoke('shell:open-path', folderPath),
},
dialog: {
openFolder: (options?: { defaultPath?: string; title?: string }) =>
ipcRenderer.invoke('dialog:open-folder', options),
},
install: {
checkPrerequisites: () => ipcRenderer.invoke('install:check-prerequisites'),
start: () => ipcRenderer.invoke('install:start'),
cancel: () => ipcRenderer.invoke('install:cancel'),
getLogs: () => ipcRenderer.invoke('install:get-logs'),
onProgress: (callback: (data: unknown) => void) => {
const listener = (_event: unknown, data: unknown) => callback(data);
ipcRenderer.on('install:progress', listener);
return () => { ipcRenderer.removeListener('install:progress', listener); };
},
},
bridge: {
isActive: () => ipcRenderer.invoke('bridge:is-active'),
},
terminal: {
create: (opts: { id: string; cwd: string; cols: number; rows: number }) =>
ipcRenderer.invoke('terminal:create', opts),
write: (id: string, data: string) =>
ipcRenderer.send('terminal:write', { id, data }),
resize: (id: string, cols: number, rows: number) =>
ipcRenderer.invoke('terminal:resize', { id, cols, rows }),
kill: (id: string) =>
ipcRenderer.invoke('terminal:kill', id),
onData: (callback: (data: { id: string; data: string }) => void) => {
const listener = (_event: unknown, data: { id: string; data: string }) => callback(data);
ipcRenderer.on('terminal:data', listener);
return () => { ipcRenderer.removeListener('terminal:data', listener); };
},
onExit: (callback: (data: { id: string; code: number }) => void) => {
const listener = (_event: unknown, data: { id: string; code: number }) => callback(data);
ipcRenderer.on('terminal:exit', listener);
return () => { ipcRenderer.removeListener('terminal:exit', listener); };
},
},
});