┌───────────────────────────────────────────────────────────────────────────────┐
│ Electron Desktop App │
│ │
│ ┌─────────────────────────────┐ ┌─────────────────────────────┐ │
│ │ Renderer (Electron) │ IPC │ Main Process (Node.js) │ │
│ │ - Sidebar / Chat / Panel │ ◄──────────► │ - IPC handlers │ │
│ │ - FileTree / TerminalDetail │ │ - ACPBridge │ │
│ │ - Skills / Settings UI │ │ - WebUI Server (ws) │ │
│ │ - Zustand session store │ │ - SocketServer (per session)│ │
│ │ - AskUserDialog │ │ - iLink Bridge │ │
│ │ │ │ - Skills Catalog │ │
│ └─────────────────────────────┘ └──────────┬──────────────────┘ │
│ │ │
│ ┌────────────────────────────────────────────┐ │ │
│ │ Shared frontend code (App.tsx / backend.ts)│ │ │
│ │ Electron: contextBridge → IPC │ │ │
│ │ WebUI: WebSocket → WebUI Server │ │ │
│ └────────────────────────────────────────────┘ │ │
│ │ │
│ ┌─────────────────────────────┐ │ │
│ │ Remote Browser (WebUI) │ WebSocket │ │
│ │ - Same App.tsx / backend.ts │─────────────────────────┘ │
│ └─────────────────────────────┘ │
│ │
│ ┌─────────────────────────┘│
│ │ Main Process spawns │
│ │ Agent │
│ ▼ │
│ ┌─────────────────────────────────────┐ │
│ │ Agent Process (2 types) │ │
│ │ │ │
│ │ Stdio: subprocess (kiro-cli acp) │ │
│ │ API: in-process (@ai-sdk) │ │
│ │ │ │
│ │ ┌─ MCP Client ────────────────┐ │ │
│ │ │ spawns & manages subprocs │ │ │
│ │ │ stdio (MCP protocol) │ │ │
│ │ └──────┬──────────┬───────────┘ │ │
│ └─────────┼──────────┼────────────────┘ │
│ │ │ │
│ stdio ────┘ │ │
│ (MCP) │ │
│ ┌──────────┘ │
│ ▼ │
│ ┌──────────────────────────────────┐ ┌──────────────────────────────────┐ │
│ │ mcp-skills │ │ mcp-ask-user │ │
│ │ (ELECTRON_RUN_AS_NODE) │ │ (ELECTRON_RUN_AS_NODE) │ │
│ │ Skills MCP server │ │ Ask User MCP server │ │
│ │ stdio ↔ Agent │ │ stdio ↔ Agent │ │
│ │ Unix Socket → Main SocketServer │ │ Unix Socket → Main SocketServer │ │
│ └──────────────┬───────────────────┘ └──────────────┬───────────────────┘ │
│ │ HTTP POST │ HTTP POST │
│ ▼ ▼ │
│ (Main Process SocketServer) │
└───────────────────────────────────────────────────────────────────────────────┘
src/electron/main.ts:窗口创建、应用菜单、Electron 原生 IPC 注册、系统对话框、全屏管理src/scripts/electron-preload/preload.ts:通过contextBridge暴露类型安全的window.fello.invoke/on/offsrc/backend/backend.ts:IPC 总入口,创建 BackendContext 与事件总线,按层级实例化各工厂模块,组装统一的backendHandlers对象并返回{ backendHandlers, closeBackend }src/backend/types.ts:共享类型定义(BackendContext、SendEventFn、EventListener)src/backend/session/index.ts:会话生命周期管理(new/load/sendPrompt/cancel/delete)、Socket Server 生命周期src/backend/session/mcp-config.ts:会话 MCP Server 配置构建(按 features 注入内置 MCP:skills/search/memory/image-generation/ask-user/share-to-user + 始终加载 toolbox)src/backend/session/notifications.ts:通知合并、广播、iLink 转发与 tool_call 状态追踪src/backend/bridge-connect.ts:Agent Bridge 连接管理(ensureBridge/rekeyBridge/killBridge/killBridgesByAgent/clearAll/setBroadcast),会话级 Bridge 生命周期、连接状态广播、权限路由src/backend/ask-user.ts:askUser 通用请求/响应机制、超时管理、Socket 路由注册src/backend/share-to-user.ts:shareToUser 文件分享机制、iLink 媒体队列src/backend/terminal.ts:PTY 终端管理(创建/销毁/resize/输入输出)src/backend/ilink/index.ts:iLink 微信集成(连接管理、状态、命令路由、消息转发),通过setHandlers延迟绑定解决与 session 的循环依赖src/backend/project/index.ts:项目 CRUD 操作,组合 filesystem 与 git 子模块src/backend/project/filesystem.ts:文件系统操作(搜索/读写/目录遍历/文件信息)src/backend/project/git.ts:Git 状态查询与 HEAD 文件读取src/backend/inference.ts:无头一次性推理原语(spawn 临时 Agent session → prompt → 收集结果 → 销毁),供 automation 使用src/backend/search/index.ts:搜索模块入口(ripgrep + file-outline),Socket 路由注册(search/search、search/rg、search/file_outline)与 MCP Server 构建src/backend/search/ripgrep.ts:基于 ripgrep worker 子进程的代码搜索src/backend/search/file-outline.ts:基于 tree-sitter WASM 的文件大纲提取src/backend/serve-file.ts:安全文件服务(路径穿越防护、MIME 检测、index.html fallback)src/backend/proxy.ts:HTTP/HTTPS 代理配置模块(基于 undici + proxy-agent),为 Agent API 请求和图片生成提供代理支持src/backend/watcher.ts:文件外部修改监听(基于 @parcel/watcher),检测工作区文件变更并广播fs-changed事件src/backend/i18n.ts:后端国际化模块,提供主进程侧的翻译能力src/backend/agent/agent-bridge.ts:Agent 进程生命周期管理,根据 Agent 类型(Stdio/API)路由到对应的 spawnersrc/backend/agent/agent-terminal-manager.ts:管理 Agent 请求创建的独立终端进程src/backend/agent/resolve-agent-info.ts:Agent 配置解析(Stdio/API 类型校验,被 backend 和 automation 共享)src/backend/webui.ts:WebUI 模式下的 WebSocket 及 HTTP 静态服务src/backend/skills.ts:Skills 目录扫描、解析、skills.sh 市场搜索与安装、Socket 路由注册(registerSkillsRoute/buildSkillsMcpServer)src/backend/memory.ts:项目级持久记忆模块(语义查询/存储 + memo 事务管理),Socket 路由注册(memory/query、memory/store、memo/read、memo/touch、memo/add、memo/delete、memo/set-weight)src/backend/image-generation.ts:图片生成模块,调用 OpenAI 兼容 API 生成图片,Socket 路由注册(image-generation/generate)src/backend/toolbox.ts:通用工具箱模块(编码/哈希/时间/UUID/随机数/图片处理/QR 码生成),Socket 路由注册(toolbox/*)src/backend/agent/stdio-agent.ts:Stdio Agent 进程 spawn(child_process),进程组管理src/backend/agent/openai-compatible-api-agent.ts:API Agent 进程内启动,通过 ndJsonStream 桥接src/backend/agent/base-agent.ts:AgentProcess 统一接口(input/output streams + close)src/backend/ilink/ilink-bridge.ts:微信 iLink 连接管理、QR 登录、长轮询、消息收发src/backend/ilink/ilink-client.ts:iLink REST API 客户端src/backend/ilink/ilink-crypto.ts:iLink 加密工具src/backend/storage/index.ts:持久化统一入口,组合设置与项目/会话 CRUD,提供消息日志(appendSessionMessage/readSessionMessages)与终端日志(appendTerminalOutput/readTerminalOutput)src/backend/storage/constant.ts:共享常量(FELLO_DIR、SOCKETS_DIR、PROJECTS_DIR、TEMP_DIR)src/backend/storage/settings.ts:全局设置读写(getSettings/updateSettings),含 Agent、MCP Server、主题、语言、iLink、snippets 等完整配置管理src/backend/storage/project-session.ts:项目与会话元数据 CRUD(addProject/createSession/listProjects/listSessions/getSession/updateSession/deleteProject/deleteSession),含内存缓存与磁盘持久化src/backend/file-routes.ts:统一文件 URL 路由解析与执行(parseFileRoute/serveRoute),支持项目文件、会话共享文件、自动化任务文件三种路由类型,同时服务于 Electron 自定义协议(fello://web/)和 WebUI HTTP 请求src/backend/socket-server.ts:Unix Domain Socket HTTP 服务器 +generateSocketPath()路径生成,用于 MCP 子进程与主进程间的 IPC(每个 session 独立实例)。详见docs/socket-server.mdsrc/shared/schema.ts:主进程与渲染进程请求/事件的统一契约src/shared/zod/mcp-ask-user-schema.ts:Shared Zod schema,用于校验 MCP ask-user 请求与响应的数据结构src/shared/zod/mcp-skills-schema.ts:Shared Zod schema,用于校验 Skills MCP 工具的请求与响应数据结构src/shared/zod/mcp-search-schema.ts:Search MCP 工具请求与响应数据结构src/shared/zod/mcp-share-to-user-schema.ts:Share-to-User MCP 工具请求与响应数据结构src/shared/zod/mcp-memory-schema.ts:Memory MCP 工具请求与响应数据结构src/shared/zod/mcp-memo-schema.ts:Memo MCP 工具请求与响应数据结构src/shared/zod/mcp-image-generation-schema.ts:Image Generation MCP 工具请求与响应数据结构src/shared/zod/mcp-toolbox-schema.ts:Toolbox MCP 工具请求与响应数据结构src/shared/zod/worker-ripgrep-schema.ts:Ripgrep Worker 子进程 IPC 通信数据结构src/shared/zod/worker-file-outline-schema.ts:File Outline Worker 子进程 IPC 通信数据结构
此目录是框架无关的 Agent 会话逻辑,同时被 backend(主进程)使用:
openai-compatible-agent.ts:实现 ACP Agent 接口,使用 Vercel AI SDK(streamText/generateText)驱动 LLM。支持流式文本、推理(reasoning)、文件内容、工具调用、会话持久化、自动标题生成。每轮生成结束后通过result.usage/result.totalUsage采集每轮 Token 用量,并通过 ACPusage_update事件发送上下文窗口占用通知session-state.ts:创建会话状态(SessionState),组装 ACP client tools + MCP session tools + 权限记忆。新增contextUsedTokens字段追踪当前上下文窗口已用 Token 数storage.ts:API Agent 会话持久化(session.json + history.jsonl),存储于~/.fello/api-agents/。session.json 新增contextUsedTokens字段,支持跨会话持久化上下文用量acp-client-tools.ts:创建 ACP 客户端工具集(文件读写、终端、搜索等)mcp-tools.ts:创建 MCP 会话工具集(动态加载 MCP Server 提供的工具)agent-client-proxy.ts:将 ACP Client 能力代理为 API Agent 可调用的客户端接口subagent-tool.ts:API Agent 的子代理工具与执行协调image-tools.ts:API Agent 图片输入与图片相关工具处理permission.ts:权限记忆系统,支持"始终允许"(Always Allow),持久化到会话状态system-prompts.ts:基础系统提示词utils.ts:ContentBlock 与 AI SDK Part 之间的转换工具
App.tsx:全局事件订阅、MessageProvider (全局对话框与 Toast 提示管理)、挂载基于react-router-dom的应用路由(HashRouter)router.tsx:使用react-router-dom定义路由拓扑(/欢迎页、/session-view/:sessionId会话页、/settings/*嵌套设置页、/skills/*Skills 管理页、/automation自动化页)store.ts:Zustand 全局 store,按 session 维护聊天状态与 UI 状态,包含 askUserRequests 队列、iLink 状态、全屏状态lib/session-state-reducer.ts:ACP 事件归一处理(消息、tool、usage)+ 流式收尾lib/session-selectors.ts:Zustand 细粒度选择器 Hooks(useSessionMessages/useSessionActiveToolCalls/useSessionIsLoading等),使用useShallow避免不必要的重渲染lib/file-url.ts:resolveFileUrl(pathname)工具函数,根据 Electron/WebUI 环境将路径名解析为完整文件 URLbackend.ts:IPC 客户端封装,支持在 Electron 环境下使用bridge.invoke,在 WebUI 环境下通过 WebSocket 连接到主进程electron.ts:纯客户端专属原生系统交互 API 封装(如showOpenDialog、revealInFinder等),在 WebUI 模式下会自动降级或屏蔽- 组件层:
sidebar.tsx:项目分组会话列表、会话切换、项目/会话重命名与删除session/session.tsx:主工作区布局,使用ResizablePanelGroup三栏结构(左:Chat + 可选详情,右:标签面板),并自动监听宽度切换紧凑模式session/chat/chat.tsx:聊天区容器(含 ChatHeader + AskUserDialog)session/chat/chat-ask-user-dialog.tsx:Ask User 对话框,支持选项选择与自定义输入、排队动画session/chat/chat-header.tsx:会话头部(Agent Badge、标题、项目路径、时间、MCP 服务器切换菜单、刷新、用量按钮)chat-bubbles/:各类消息气泡(agent、subagent、user、system、tool、thinking、plan、message、base)session/panel/panel.tsx:带标签的右侧面板(Files / Terminal 两个标签页切换)session/panel/file-panel/file-panel.tsx:文件树、重命名、拖拽移动、外部文件夹导入session/panel/terminal-panel/terminal-panel.tsx:垂直终端列表、创建/删除/切换终端session/detail/detail.tsx:详情视图容器,根据类型渲染文件预览或终端详情session/detail/file/file-detail.tsx:文件详情入口,根据文件类型分发到子目录(code-detail/、image-detail/、markdown-detail/、html-detail/、pdf-detail/、docx-detail/、xlsx-detail/、pptx-detail/、fallback-detail/),通过 subscribe 监听fs-changed事件检测文件外部修改session/detail/terminal/terminal-detail.tsx:终端详情展示(xterm.js,含 ResizeObserver 自适应)settings/:设置页面(general、agents、MCP、WebUI、iLink、snippets、memory、image-generation)skills/:Skills 管理页面(已安装列表 + skills.sh 市场)
Agent 启动时可以挂载多个 MCP Server,作为独立子进程运行(ELECTRON_RUN_AS_NODE=1),通过 stdio 与 Agent 通信:
src/scripts/mcp-skills/server.ts:Skills MCP server,提供list_skills和activate_skill工具。通过 Unix Domain Socket 回调主进程的SocketServer(路由/skills/catalog、/skills/detail)。Skills 本身是会话级 feature flag,可以通过features参数开关src/scripts/mcp-ask-user/server.ts:Ask User MCP server,提供ask_user工具。通过 Unix Domain Socket 回调主进程的SocketServer(路由/ask-user/ask),将 Agent 的询问请求转发到askUser()函数src/scripts/mcp-search/server.ts:Search MCP server,提供search、rg和file_outline工具。通过 Unix Domain Socket 回调主进程的SocketServer(路由/search/search、/search/rg、/search/file_outline)src/scripts/mcp-share-to-user/server.ts:Share-to-User MCP server,提供share_to_user工具。通过 Unix Domain Socket 回调主进程的SocketServer(路由/share-to-user/share),将 Agent 的文件分享请求转发到shareToUser()函数src/scripts/mcp-memory/server.ts:Memory MCP server,提供memory_query和memory_store工具。通过 Unix Domain Socket 回调主进程的SocketServer(路由/memory/query、/memory/store),用于项目级持久记忆的语义检索与存储src/scripts/mcp-memo/server.ts:Memo MCP server,提供memo_get_current、memo_touch、memo_add、memo_delete、memo_set_weight工具。通过 Unix Domain Socket 回调主进程的SocketServer(路由/memo/read、/memo/touch、/memo/add、/memo/delete、/memo/set-weight),用于项目记忆条目的事务性管理src/scripts/mcp-image-generation/server.ts:Image Generation MCP server,提供image_generation工具。通过 Unix Domain Socket 回调主进程的SocketServer(路由/image-generation/generate),用于文本生成图片src/scripts/mcp-toolbox/server.ts:Toolbox MCP server,提供编码解码(base64/url)、哈希、时间、UUID/短 ID、随机数、图片处理(metadata/thumbnail/resize/convert)、QR 码生成等工具集。通过 Unix Domain Socket 回调主进程的SocketServer(路由toolbox/*)。始终加载,不受 feature flag 控制
Skills、ask-user、search、share-to-user、memory 和 image-generation 的 MCP Server 是否启动由会话的 features 配置控制(ALL_FEATURES 默认为 ["skills", "search", "image_generation", "memory", "ask_user", "share_to_user"]),通过 session/mcp-config.ts 中的 buildMcpServersConfig() 按需注入。此外,toolbox MCP Server 始终加载,不受 feature flag 控制。
MCP 子进程的构建入口在 electron.vite.config.ts 中配置,输出到 out/scripts/。
以下 Worker 子进程不是 MCP Server,它们是普通工作子进程,通过 stdin/stdout JSON 消息与后端搜索模块通信:
src/scripts/worker-ripgrep/worker.ts:Ripgrep 搜索 Worker,由src/backend/search/ripgrep.ts以子进程方式启动,通过 stdin/stdout JSON 通信执行文件内容搜索src/scripts/worker-file-outline/worker.ts:File Outline Worker,由src/backend/search/file-outline.ts以子进程方式启动,使用 tree-sitter WASM 解析文件结构大纲
Stdio Agent:通过 child_process.spawn 启动,使用 ACP SDK 的 NDJSON stdio 通信
API Agent:进程内运行 OpenaiCompatibleAgent 实例,通过 ACP SDK 的 ndJsonStream 和 AgentSideConnection 桥接——对外表现为标准 ACP Agent
Fello 支持两种 Agent 类型,通过 src/shared/schema.ts 中的 AgentInfo 判别联合类型区分:
type AgentInfo = StdioAgentInfo | ApiAgentInfo- StdioAgentInfo:
type: "stdio",command,args,env - ApiAgentInfo:
type: "api",provider: "openai-compatible",baseUrl,apiKey,headers,以及可选的contextWindowTokens(默认 128000)、modelIdTemplate、models
ACPBridge 根据 AgentInfo.type 路由到对应的 spawner(spawnStdioAgent 或 spawnOpenaiCompatibleApiAgent),两者都实现统一的 AgentProcess 接口。
createBridgeConnectModule() 使用 Map<sessionKey, Promise<ACPBridge>> 管理连接。常规会话各自以 Fello session.id 作为 key 持有 Bridge;创建会话时先使用临时 key,取得 Agent resumeId 并持久化后再通过 rekeyBridge() 切换到正式 key。
- 新建会话:
ACPBridge.newSession() - 恢复会话:
ACPBridge.loadSession() - 发送消息:
ACPBridge.sendPrompt() - 取消生成:
ACPBridge.cancel() - 关闭与清理:
killBridge()/killBridgesByAgent()/clearAll()
每个 ACPBridge 封装对应的 Agent 连接/进程,并按 ACP resumeId 缓存模型、模式、思考级别、配置选项和已加载会话状态。
所有 ACP 增量事件统一经过同一链路进入 Zustand,再由 React 渲染:
ACPBridge.onSessionUpdate
→ bridge-connect.broadcastAndSaveSessionUpdate()
→ session/notifications.ts 持久化并调用 sendEvent("session-update")
→ Electron IPC / WebUI WebSocket 传输
→ mainview/backend.ts emit()
→ App.tsx handleSessionUpdate()
→ reduceSessionNotification(sessionId, currentState, notification)
→ useAppStore(sessionStates)
→ ChatArea / Bubble 组件更新
这种设计保证了实时流式更新与历史重放的处理逻辑一致。
store.ts 使用 Map<sessionId, SessionState> 管理每个会话隔离的:
- messages (
ChatMessage[]多态数组) usage: 上下文窗口用量(ACPusage_update事件更新)lastTurnUsage: 上轮 Token 明细(input/output/total/thought/cache)- permission 请求队列
- activeToolCalls
所有的消息通过 src/mainview/lib/chat-message.ts 中的 StreamableMessage 等接口实现了多态结构(基于 ContentBlock 数组),并且依靠 Zustand 的 Immutable 更新保证 React 流式渲染性能。
全局共享状态则直接挂载于 store 根层级:
configuredAgents:用户在设置中自定义的可用 Agent 及启动配置configuredMcpServers:用户在设置中自定义的可用 MCP 服务器配置theme:UI 主题配置(深色、浅色、跟随系统)i18n:应用语言配置(英语、简体中文)snippets:用户自定义的 Snippets 列表webUIStatus:WebUI 服务状态ilinkStatus:微信 iLink 连接状态activeIlinkSessionId:当前 iLink 活跃会话 IDisMacApp/isFullScreen:平台与窗口状态
此外,模型、模式、思考级别(models / modes / thoughtLevels)以及 Agent 初始化信息(initializeInfo)现在作为 SessionInfo 的一部分直接与每个独立的会话元数据绑定,前端会根据当前会话的 SessionInfo 直接渲染,避免了全局状态同步带来的界面闪烁问题。
敏感或系统相关能力全部由主进程执行:
- 文件树读取、创建、删除、重命名、移动
- 系统对话框(选择目录)
- 原生右键菜单
- Finder 定位
- PTY 终端创建/输入/销毁/resize
- iLink 微信连接与消息收发
- Skills 目录扫描与安装
渲染层只发起受限 RPC,不直接接触 Node API。
Renderer: addProject(pickWorkDir)
→ Main: storage.addProject(project.json)
→ Renderer: 在项目下触发 newSession(projectId, agentId, mcpServers, permissionMode)
→ Main: ensureBridge(tempKey, agentId, cwd) → spawn Agent process (Stdio or API)
→ Agent: newSession
→ Main: storage.createSession(session.json)
→ Main: rekeyBridge(tempKey, session.id) + 创建 Session Socket Server
→ Renderer: 刷新 sessions + 进入 active session
Renderer: resetSessionState(sessionId)
→ Main: loadSession(sessionId)
→ Agent: loadSession/resumeSession (服务端重放历史或从本地 history.jsonl 恢复)
→ session-update 持续推送
→ reduceSessionNotification 重建消息/工具/usage 状态
ChatInput submit
→ 立即写入本地 user message + isStreaming=true
→ Main: sendPrompt
→ Agent: sendPrompt
→ session-update chunk 持续到达(text-delta / reasoning-delta / file / tool-call / tool-result)
→ reduceSessionNotification / calculateToolCallUpdate
→ 生成结束: Agent 通过 result.usage 采集 Token 用量
→ 发送 sessionUpdate("usage_update", { used, size }) 更新上下文窗口进度
→ prompt 返回 { stopReason, usage } 包含本轮 Token 明细
→ ChatInput 收到 usage 后更新 sessionState.lastTurnUsage
→ reduceFlushStreaming 收尾,结束 streaming 状态
Agent requestPermission
→ Main: 通过 askUser() 统一通道
→ Renderer: 显示 AskUserDialog(选项含 danger 标记)
→ 用户选择 optionId
→ Main: resolve pending permission
→ Agent 继续执行 tool
→ 若选择"始终允许",持久化到 session state
Renderer: createTerminal(sessionId, cwd)
→ Main: node-pty spawn shell
→ Main event: terminal-output / terminal-exit (同时持久化到 sessionDir/terminals/ 下)
→ Renderer subscribe 更新 xterm 实例 (或通过 AgentTerminalOutput 渲染)
→ 用户输入 onData → writeTerminal 回传 PTY
用户微信 → iLink Server → Main: ILinkBridge.poll() → onMessage callback
→ Main emit "ilink-status-changed" / 转发消息到活跃 session
→ Renderer store 更新 ilinkStatus
→ Agent 处理消息并回复
→ Main: ILinkBridge.sendTextReply() → iLink Server → 用户微信
正向:Agent → 用户
Agent 调用 ask_user MCP tool
→ MCP ask-user server: HTTP POST /ask-user/ask over Unix Socket
→ Main SocketServer: askUserAskRequestSchema 校验
→ Main askUser(): 生成 askUserId, sendEvent("ask-user-request")
→ Renderer store: 追加到 askUserRequests 队列
→ AskUserDialog: 展示选项或输入框
反向:用户 → Agent
用户点击选项 / 提交输入
→ Renderer: backend.request.respondAskUser({ sessionId, askUserId, value })
→ Main: resolve pendingAskUserRequests Promise
→ SocketServer: 返回 { value, reason } 给 MCP server
→ MCP server: 格式化为 MCP 文本响应
→ Agent: 收到 tool call 结果
Agent 调用 list_skills / activate_skill MCP tool
→ MCP skills server: HTTP POST /skills/catalog 或 /skills/detail over Unix Socket
→ Main SocketServer: 查询 Skills 目录或读取指定 Skill 详情
→ 返回结果给 MCP server
→ Agent: 收到 tool call 结果
Agent 调用 search / rg / file_outline MCP tool
→ MCP search server: HTTP POST over Unix Socket(/search/search、/search/rg、/search/file_outline)
→ Main SocketServer: 查询 ripgrep worker 或 file-outline worker
→ 返回结果给 MCP server
→ Agent: 收到 tool call 结果
Agent 调用 share_to_user MCP tool
→ MCP share-to-user server: HTTP POST /share-to-user/share over Unix Socket
→ Main SocketServer: 执行文件分享逻辑(shareToUser())
→ 返回确认给 MCP server
→ Agent: 收到 tool call 结果
- 启动:
app.whenReady()后设置菜单、Dock 图标、创建主窗口,尝试恢复 iLink 会话 - 开发模式:附加 renderer console 与 did-fail-load 诊断日志
- macOS 行为:关闭窗口不退出进程,
activate时重建窗口 - 退出:
before-quit同步清理 Agent 进程组、iLink 连接与所有 PTY 终端
- 客户端本地保存项目元数据、会话元数据(
session.json) - Stdio Agent 会话的聊天历史通过主进程进行落盘拦截,每个会话在其独立目录下维护完整的
messages.jsonl事件流文件(NDJSON 格式) - API Agent 会话的聊天历史在
OpenaiCompatibleAgent内部直接写入history.jsonl - API Agent 会话状态(modelId、allowedToolKinds、contextUsedTokens)持久化到
session.json - 删除项目时删除对应
~/.fello/projects/<project-id>/目录(包含其所有会话和日志) - iLink 凭证和游标持久化到
~/.fello/ilink/