DevLog:2026年1月25日

1、截至目前,四款应用问题如下,加粗内容暂未修复:

1.DoitWith

-不包含任何Todo的分组下会显示“该分组暂无待办”,但底下还有半截分隔线,需要和正常的Todo条目下的分隔线格式一致

-设置-关于,DoitWith下面的小字和开屏上的小字是否一致?以设置-关于中的小字为准

-在Todo页面,没有“下一步”的Todo,在标题下显示“仅此一步”

-在已完成Todo页面,有下一步的Todo,在标题下显示“包含下一步”,没有“下一步”的Todo,在标题下显示“仅此一步”

-考虑到后续可能要和Mac版数据打通/同步(通过CloudKit,两个App绑定同一个iCloud Container),趁早将应用的数据持久化方式由Core Data改成SwiftData,和DoitWith for Mac的数据持久化方式保持一致,仅外观设置使用UserDefaults保存

-当天到期的Todo,早上九点推送通知

-添加小组件,小组件上显示当天到期的Todo,信息包括所在分组、标题、下一步

2.DoitWith for Mac

-调整新建分组、添加和编辑Todo窗口的视觉效果,部分图标和文字太小

-设置-关于页面下方增加“近期更新”区域,由Cursor总结近期更新了哪些功能

3.ChatWith

-清除后台后,再打开应用秒闪退,无法使用

-在与支持深度思考的模型对话时,可以看到思考内容区域,但看不到具体的思考内容

-发送消息后立刻显示在对话界面内,现在好像是在AI有响应后才会显示

-虽然可以看到Tavily已经联网获取了一些链接,但AI回答内容好像没有结合Tavily搜索结果

-参考链接引用10条,参考链接区域默认折叠,可展开

4.ChatWith for Mac

-关于页面的“初始版本发布”放到最上边

-优化上传附件和图片后的显示效果,比如取消附件和图标的红叉需要改小一些

2、近期的重点在于对齐移动版和Mac版的现有功能,修复明显问题,首先是DoitWith移动版,将数据持久化方式由Core Data改成SwiftData,步骤包括创建SwiftData模型文件,更新PersistenceController.swift、更新TodoData.swift、更新所有视图文件,删除旧的Core Data文件,修改过程中发现虽然Composer 1模型的修改速度非常快,但修改后出现多个语法错误,未能自动检测出来

3、接下来测试功能,让Cursor修复问题,首先是待办页的空状态提示,“暂无任务”改成“暂无待办”,“添加任务开始使用”改成“添加待办或分组以开始使用”,另外待办页无待办时,这些文字上方会显示一条分割线,需要去掉,出现分割线的原因是,以前在无待办时,List里仍有一个底部占位Section(Spacer高度200),该Section上方会出现分割线,修改之后,仅在有待办或分组时显示底部占位Section

4、然后测试添加、完成、修改、删除、搜索Todo和分组,测试发现问题如下:

1.不包含任何Todo的分组下会显示“该分组暂无待办”,但底下还有半截分隔线,需要和正常的Todo条目下的分隔线格式一致

2.在Todo页面,没有“下一步”的Todo,在标题下显示“仅此一步”

3.在已完成Todo页面,有下一步的Todo,在标题下显示“包含下一步”,没有“下一步”的Todo,在标题下显示“仅此一步”

5、之前遇到过的同一分组内的Todo无法通过拖动调整顺序的问题,这次测试未能复现,可能在修改数据持久化方式之后也给解决了?

6、继续优化ChatWith移动版,主要针对之前测试遇到的问题,包括:

1.在与支持深度思考的模型对话时,现在可以看到思考内容区域,但看不到具体的思考内容,只能看到“思考中…”的提示

2.用户发送消息后,需要立刻显示在对话界面内,现在好像是在AI有响应后才会显示

3.虽然可以看到Tavily已经联网获取了一些链接,但AI回答内容好像没有结合Tavily搜索结果

4.参考链接引用由5条加到10条,并且参考链接区域默认折叠,可展开

7、首轮修改之后,上述问题只有4已经被修复,换用内置的Kimi K2试一下,卡在分析问题的过程中,等了一段时间也没有对代码进行实际的修改,然后切换到Composer 1,修改速度很快,并且解决了“看不到具体的思考内容”、“回答内容未结合Tavily搜索结果”的问题,再次测试,要求进行如下修改:

1.思考内容区域要整合到AI消息区域中,即 最上面是思考区域(如果支持深度思考的话),然后是回答内容、参考链接,并且这三块要对齐

2.用户问题发送之后,对话界面应该立刻跳到新问题的位置,现在好像还需要手动往上划一下才能看到?

8、再次测试,上述问题好像也已经修复,但应用非常卡顿,可能是添加了太多调试信息导致的,后面再去掉,先继续用Composer 1尝试修复“清除后台后,再打开应用秒闪退”的问题,这次修改涉及生命周期管理、错误回复、超时保护、友好错误提示等,再次测试,应用直接无法正常启动了,要求Cursor清理所有的调试信息,并检查语法错误,首次启动速度是快了一点儿,但依然没有解决清除后台后无法启动的问题

9、决定换个思路,在ChatWith for Mac的基础上,适配一个iOS版,先让Curosr评估了下,首先,核心业务逻辑100%兼容,且有部分Flutter依赖已支持iOS,需要适配的部分包括部分原生平台代码、UI布局、几个macOS平台的特定功能(比如拖拽、粘贴、word文档和PDF文档解析),Cursor给出了完全兼容(使用条件编译和抽象层)和最小化适配两个方案,决定采纳方案1,希望这样可以减少后续对单独某个功能在Mac和iOS端的重复修改

10、由于存在代码隔离机制,macos和ios是独立的目录和Xcode项目,另有lib统一管理两个平台共用的代码,在后续测试时需要打开.xcworkspace文件,而非.xcodeproj文件,并且在修改共享的代码时要注意平台兼容性

11、分析的很简单,但实际操作时反复出错,比如因为权限问题不能创建项目文件,因为网络问题不能运行pod install等等,按照Cursor提供的文档手动创建项目后,又提示创建的项目不正确,反复修改了一段时间,仍未能修复

12、使用Cursor中的Codex插件检查该版本iOS应用的构建失败问题,几次修改后可以正常构建,但同样出现了ChatWith移动版存在的“清除后台后再打开应用秒闪退”的问题,结合Device Logs,Codex认为可能是一些依赖导致的崩溃,于是先暂时将其在iOS上禁用,避免启动时注册崩溃,多次修改后依然未能解决,而且基于ChatWith for Mac修改的iOS版应用在界面上还是Mac版的样子,完全没有适配移动设备,可能将使用Flutter开发的桌面版应用改为移动版并没有Cursor说的那么简单

13、用Codex,结合Device Logs检查一下“清除后台后再打开应用秒闪退”和首次打开时启动速度很慢的问题,也进行了多次反馈和调整,甚至还暂时去掉了可能导致崩溃的SwiftFlutterSecureStoragePlugin,即flutter_secure_storage依赖,但还是不管用

14、换个思路,从应用的首次启动速度入手,Codex加上了首屏耗时分析,包括First frame: startup=26145ms build=7611ms raster=11ms total=8631ms,针对这一问题进行多次修改,包括把启动阶段的初始化拆到首帧后执行、把设置读取和服务配置的初始化延后到首帧之后、把原生启动页改成橙色背景+标题和副标题以跳过白屏、去掉启动阶段的首帧调试输出等,首屏耗时变成了flutter: First frame: startup=18011ms build=4065ms raster=5ms total=4074ms

15、然后按照Codex的建议,删除App,运行flutter clean、flutter pub get,再重新构建,解决构建错误等等,首次启动可以正常启动,但启动速度比之前更慢了,而且清除后台后无法启动的问题依然存在,后面还得继续修改

DevLog:2026年1月20日

1、继续测试昨天对DoitWith的完成Todo逻辑的修改效果,目前已经实现如果一个Todo中有多个下一步,点击完成按钮会先完成下一步,如果一个Todo中没有下一步,点击完成按钮会完成整个Todo的功能,但仍有两个问题,在编辑有“下一步”的Todo后,这条Todo会被分类到General中,而不是保持在原本的分组,另外已完成的Todo就不要再显示在首页的Todo列表里了,只显示在“已完成”页面就行

2、Cursor在修改过程中调整了编辑时的分组逻辑,如果在编辑时选择了分组,且与当前分组不同,才更新分组,如果在编辑时没有选择分组,且原来有分组,那就移动到General,如果原来就是General,那就保持在General,针对第二个问题,添加了过滤条件,已完成的Todo只会显示在“已完成”页面,即CompletedTodosView

3、再次构建测试,发现点击完成一条Todo后,已完成页面仍然是空的,看不到我刚刚完成的Todo,继续修复,Cursor表示修复后会直接从CoreData查询所有已完成的Todo(包括Genral和分组中的),并且按创建日期降序排列,在已完成视图出现时自动刷新,显示最新的已完成Todo

4、再次构建测试,发现在添加Todo——点击完成Todo或完成下一步时,会有一条之前已经完成的Todo变回未完成状态,出现在Todo列表里,即已完成的Todo被重置了,反馈给Cursor修改,Cursor认为这是因为重新排序时没有排除已完成的Todo,导致已完成的Todo的order被错误地重新赋值,可能会影响已完成的Todo的状态

5、再次测试,以上问题已解决,接下来对界面布局进行一些调整:

1.搜索栏挪到顶部,“添加”按钮放在搜索栏右侧

2.待办、已完成、设置 三个按钮放在底部,点击可切换至对应界面

3.设置界面底部增加“关于DoitWith”板块,展示应用名DoitWith和副标题(Manage things with next steps)

6、修改过程中,Cursor创建了MainView(底部导航栏),使用TabView管理三个页面,并修改了TodoView(搜索栏和添加按钮)、CompletedTodosView(改为Tab页面)、SettingsView(添加关于板块),更新了ContentView(将TodoView替换为MainView,使用新的底部导航结构),由于项目使用了PBXFileSystemSynchronizedRootGroup,Xcode会自动检测并包含DoitWith文件夹中的新文件,所以刚刚创建的MainView就不需要手动更新到项目中了

7、构建测试,已实现上述界面调整需求,但在待办界面,搜索栏和顶部的“待办”、下方的快速导航栏之间的间距有些大,需要稍微改小一些,Cursor同步调整了搜索栏与导航栏之间、搜索栏与快速导航栏、快速导航栏与第一个分组之间的间距,再次构建测试,界面比之前稍微紧凑了一些,基本达成需求

8、接下来给DoitWith添加图标,使用ChatGPT创建图标包,指令是“我有一个待办类iOS应用,叫DoitWith,我需要给它加上图标,你先帮我创建一张1024*1024的底图,格式要符合iOS应用对图标文件的要求,颜色和DoitWith的启动页面颜色保持一致(red: 27/255, green: 94/255, blue: 32/255),需要稍微有一点创意,同时保持简洁”

9、ChatGPT给了我两张图,但都不是很满意,元素和色彩都稍微有点多,并且还出现了“图标套图标”的问题,虽然主体基本可用,但还有一个明显的“内层圆角块/底座”的感觉,在裁切成图标文件后就会像是套了一层,为了让图标更简洁,多次跟ChatGPT对话,去掉了内层圆角容器的感觉,并且微调了色彩,生成了图标包,放到Assets.xcassets文件夹里之后,应用图标搞定

10、ChatGPT还提示我可以在真机上测试时注意看桌面、Spotlight搜索结果、设置App列表这三个位置里的图标是否干净、清晰、锐利,如果都OK,那就可以长期使用

11、我发现目前应用在一些界面上还存在英文提示,比如搜索页未搜索到结果时的提示、Todo的日期信息(月份)、点击完成Todo时的弹窗提示等,需要改成对应的汉字,让Cursor排查下还有没有其它地方要改,但启动页、设置-关于页中的英文不要改,Cursor修改了TodoView中的提示文本、弹窗按钮文本、日期格式化、导航标题(我又让改回去了),以及General分组的名称,另外添加Todo和编辑Todo界面里的日期选择器还是英文的,反馈后Cursor给这两处增加了locale环境变量,这样DatePicker就会使用中文界面,构建测试,需求达成

12、接下来暂时不增加新功能,昨天询问了如何在真机上测试iOS App,Cursor指出这种方式只要有Xcode+Apple ID就可以,不需要通过TestFlight,也不需要上架,步骤包括用数据线把iPhone连到Mac、在Xcode中打开项目、设置签名、选择真机为运行设备、点击RUN等,并且我有已付费的开发者账号,通过这种形式进行测试时不会有7天过期的限制

13、按照ChatGPT的提示连接自己的手机进行测试,发现ChatGPT少写了一步,在选择真机为运行设备前,需要在手机的设置中打开开发者模式

14、想用同样的方法把之前使用Flutter重构的ChatWith移动版安装到手机上,但我发现目前的ChatWith移动版在模拟器中安装后,面上显示的是Flutter的图标,名字叫Chatwith Flutter,于是让Cursor修改了应用的名字(将Info.plist中的CFBundleDisplayName由Chatwith Flutter改为ChatWith),并且用ChatGPT制作了图标包(18张,包含Contents.json),替换了原来的Flutter图标

15、然后连接手机并且在手机上运行ChatWith,首次启动时竟然出现了“允许ChatWith查找本地网络中的设备?”的提示,为啥功能这么简单的应用居然会有这种权限要求呢?

16、到目前为止,已经把ChatWith for Mac(使用Flutter重构)安装到了电脑上,并且把ChatWith(使用Flutter重构)和DoitWith(使用SwiftUI原生开发)移动端安装到了电脑上,接下来在日常使用中测试一段时间,并修复使用中发现的问题

17、同步开发DoitWith for Mac,在之前的NoteWith for Mac基础上修改,之前已经有了对话、笔记、Todo三个板块,功能比较杂乱,也不太符合实际的使用需求,让Cursor简化当前应用的功能,去掉对话和笔记功能,并且将应用名称和所有的NoteWith都改成DoitWith,这个应用今后也尽量只用SwiftUI原生开发

18、Cursor陆续进行了这些操作:删除AI对话和笔记相关的文件,更新ContentView、SearchWindowView、RecycleBinView、DataManager等文件以移除AI和笔记功能,将所有文件中的NoteWith重命名为DoitWith,重命名项目文件夹和配置文件,更新项目配置文件等等,几分钟时间完成

19、构建测试,需要重新在Xcode中打开项目文件,并且让Cursor修正了CoreDataManager.swift路径配置错误、应用已删除的文件等多个问题,主要是清除已经删掉的AI对话、笔记相关功能代码,终于可以顺利构建

20、首先调整了最左侧栏、待办分组栏的宽度设置,最左侧栏固定为200,待办分组栏固定为300,并且禁止用户拖动调整宽度,然后我发现在Xcode中,当前项目好像仍在引用MarkdownUI,但涉及这个依赖的AI对话、笔记功能已经都删掉了,让Cursor从项目文件中移除对MarkdownUI的引用,重新构建、功能正常

21、明天开始,在使用并记录ChatWith for Mac、ChatWith、DoitWith的问题的同时,持续优化DoitWith for Mac,包括修改数据存储方式、增加下一步功能、调整界面、增加图标等等,之前使用SwiftUI开发的NoteWith移动版暂时搁置

DevLog:2026年1月15日

1、昨天的遗留问题包括:通过command+N在AI对话和备忘录界面新建对话、新建备忘录,和通过拖拽上传图片/文档,再次测试已支持通过拖拽上传图片/文档,但控制台里依然返回了“图片文件不存在”的调试信息,Cursor优化了错误处理,将“图片文件不存在”的提示改为仅在调试模式下打印,并添加说明,再次构建,功能依然正常,调试信息依然是“图片文件不存在”,先不管了,后面会统一去掉所有的调试信息

2、然后是在AI对话界面用command+N新建对话,在笔记界面用command+N新建笔记这两个功能,目前还不是很稳定,比如在AI对话界面,光标停留在AI对话列表页、详情页、输入框等位置时,有时可以用快捷键新建对话,有时不能,而在笔记界面,只有点开一条笔记的编辑模式后,才能通过command+N新建笔记,我的需求是,只要打开了AI对话界面,不管是未选中任何对话,还是打开了一条对话,或者光标停留在输入框,都可以通过command+N新建对话,只要打开了笔记界面,不管是未选中任何笔记,还是打开了一条笔记,或者切换到了编辑模式,都可以通过command+N新建笔记

3、Cursor为Shortcuts添加了autofocus:true和canRequestFocus:true,据称能确保快捷键始终可用,再次构建测试,依然未能实现需求,决定回退一点,在AI对话界面,只有打开对话并且在输入框聚焦时,才能通过command+N新建对话,并且在设置-快捷键的“新建对话”后面增加“(在输入框聚焦时)”说明文字;在笔记界面,只有打开笔记且在编辑模式时,才能通过command+N新建笔记,并且在设置-快捷键的“新建笔记”后面增加“(在编辑模式时)”说明文字

4、再次构建测试,在修正两个文件中括号不匹配的问题之后,可以正常构建,快捷键功能也可正常使用

5、前两天在询问千问时,它有提到可以通过macOS的textutil实现对word文档的解析,Cursor也认为该方案可行,textutil支持.doc和.docx格式,可将word文档转换为纯文本,支持UTF-8编码输出,并且是macOS系统自带的功能,无需额外依赖,可以使用MethodChannel实现(当前的PDF解析实现方式),优点在于性能、稳定性好、实现简单,但仅限于macOS,无法跨平台,无法提取文档中的图片,无法处理某些复杂的word对象,这些在我看来都可以接受

6、要求Cursor直接使用textutil来实现AI对话过程中对word文档的解析,实现方式与现有的PDF解析一致,同时添加文件大小限制,单个word文档不能超过10MB,Cursor创建了新的文件WordTextExtractor.swift并更新了项目文件,新增功能包括文件大小限制、错误处理、与PDF解析一致的实现方式

7、构建测试,发现已经支持上传并解读word文档,通过附件按钮上传、拖拽上传均可,但目前还不支持将图片、文档粘贴到对话框并解读,询问Cursor能否增加对粘贴图片、文档并解读的支持,效果要和通过附件按钮上传、拖拽到对话窗口的效果一致,在修改过程中,Cursor扩展了Swift端剪贴板处理,更新了Dart端粘贴处理,据称实现的效果包括支持粘贴图片、支持粘贴文档、与拖拽和附件上传效果一致,并且自动去重

8、继续构建测试,已经支持粘贴图片和文档,需要更新一下AI对话界面输入框的提示文字,改为“输入消息…(支持拖拽或粘贴文本/图片/文档)”,这种比较小且非常明确的需求,可以先在代码中搜索找到对应的位置,选中所在行并Add to Chat,修改起来会更快

9、在通过命令行进行构建测试的过程中,多次出现对依赖版本的检查,其中12个包有更新版本可用,1个包已被官方弃用,询问ChatGPT后得知这不是错误,不影响编译或运行,且并不是所有的包都建议升级,升级后也可能会导致新的编译问题,其中的flutter_lints、lints、package_info_plus、pointycastle版本号变化较大,后面可以考虑升级,flutter_markdown官方已经不维护了,建议改用flutter_markdown_plus,等后面更熟悉Flutter了再尝试更新

10、刷新一下README.MD和设置-关于ChatWith界面的“近期更新”内容,版本号不变,接下来打包(flutter build macos –release -v)、测试几天,然后下一个版本重点优化笔记板块的功能和界面

11、记录一下在终端中用指令打包的方法,首先cd+空格,打开项目文件夹,直接拖到终端窗口里,就会自动补全路径,然后回车,然后再输入flutter build macos –release -v,接下来等着它完成就行,正常的话会有BUILD SUCCEED、Building macOS application…(completed in 44.6s),并用绿色对号和加粗的文字提示路径Built build/macOS/Build/Products/Release/chatwith.app,去项目文件夹下这个路径里找就行了,然后把这个.app文件拖到访达的“应用程序”文件夹里,就可以正常使用了

12、再补充一些基础知识,flutter build macos –release -v只能用于打包使用Flutter开发的macOS应用,使用Xcode原生、Electron/Tauri、.NET/Qt/C++开发的应用有各自的打包指令,但如果要正常分发甚至想上架的话,还都需要经过代码签名、公证等步骤,macOS应用如果不公开分发,有.app文件就够了,只是会面临Gatekeeper的拦截

13、了解一下如果把当前这个使用Flutter开发的macOS应用部署到iOS设备上,可能会涉及哪些调整,根据ChatGPT的回复,这会涉及项目结构与构建目标、UI/交互、生命周期与状态管理差异、文件系统与文档上传能力改造、权限与能力声明、依赖/插件、原生集成与性能、发布与合规等方面,在将目前项目的pubspec.yaml复制给ChatGPT后,它指出目前的大多数依赖本身是支持iOS的,如果要将macOS版本迁移到iOS,可能主要会卡在数据库实现、文件选择/文件访问、iOS权限与plist配置以及少量插件的iOS兼容性细节上

14、从现在的情况来看我好像没有必要再单独去修改使用flutter重构的ChatWith移动版了,因为功能上的需求都是一样的,重复开发也只是徒增工作量,后面可以等ChatWith for Mac功能稳定了,直接让Cursor搞一个功能一致的iOS版

15、在测试的这段时间,也筹划一下其他的应用,目前已有的几个半成品项目中,只有DoitWith的功能与其他几个不同,目前是一款使用Swift开发的待办应用,已经具备了常用的添加/修改/删除待办、完成待办、待办分组、重复提醒、数量统计等功能,但不知道下一步该往哪个方向走,将目前已有的功能清单、核心的代码文件和主界面截图发给ChatGPT后,ChatGPT指出目前我已经把一个标准的To-Do App该有的东西几乎都做完了,现在不是“功能不够”,而是“任务本身是死的”,只是起到了“记录我要做什么”的作用,但市面上几乎所有成熟的To-Do App的竞争点已经是“系统如何帮我更容易把事情做完”,所以我才会遇到“我不知道加什么功能,但又不想和别人一样”的典型问题

16、而且ChatGPT还指出了目前应用的几个问题,比如每条待办都是孤立的,没有前后关系/状态演进/行动提示,目前的分组是静态分组,所有的事都会被同等对待,完成一个任务也没有反馈感,ChatGPT不建议再横向加功能(比如子任务、优先级、项目/文件夹、日历视图),而是给出了三个进化路线:让待办变成过程,而不是清单(增加“下一步”功能);让DoitWith变成节奏型待办(每天只能标记3个重点任务,超过就要替换);为macOS/iOS原生体验而生(利用Spotlight、菜单栏快速完成、Live Activity/Widget驱动行动、支持快捷指令等macOS/iOS原生能力)

17、这三个建议中的“最小可执行版本”是给任务加一个字段:nextAction或statusNote,UI上显示在标题下,用户完成的是“这一步”,不是整个任务,这样就会让列表变“活”

18、还得再思考思考具体往哪个方向演进,或许也可以结合我的日常工作来调整,做成一款通用性没有苹果的“提醒事项App”那么强的待办App,比如设置项目、稿件、视觉等标签?增加由哪个员工来写,和哪个客户对接等字段?

DevLog:2026年1月13日

1、今天先解决应用签名和打包分发的问题,我对这个也不太了解,只是知道如果想要正常分发、不被macOS的Gatekeeper安全机制拦截,需要签名,Cursor检测后发现当前应用的签名方式为自动签名,可以在Xcode中打开项目,选择左侧栏的Runner,在中间栏的Signing&Capabilities中勾选Automatically manage signing,并选择Team,登录Apple Developer账号,Xcode就会自动处理签名

2、在这里还需要填写Bundle Identifier,这里默认的是com.example.chatwith,ChatGPT建议这里用反向域名+产品名(全局唯一),并且要和未来在App Store Connect/证书体系里用的一致,格式可以是com.<公司或个人>.<应用名>,且且只能用字母/数字/连字符,通常全小写更稳妥,但不要用Flutter的默认值(中间的公司或个人默认是example)

3、然后就是反复进行Archive并在ChatGPT的帮助下排查问题,比如要Enable Hardened Runtime,在账户设置中Manage Certificates——+Developer ID Application,然后Archieve——Direct Distribution上传到Notary——等待公证结果——Ready for distribution,但在等待公证结果时等了比较长的时间,ChatGPT认为一般1到5分钟,偶尔5到15分钟,极少数高峰期可能需要20到30分钟,即使失败,也能看到具体原因并进行针对性的修复

4、继续等待公证,大概两个小时依然在in progress,运行ChatGPT提供的在终端中用notarytool查看真实状态的指令

xcrun notarytool history –apple-id “<你的AppleID邮箱>” –team-id “<你的TeamID>” –password “<app专用密码>”

xcrun notarytool info <submission-id> –apple-id “<邮箱>” –team-id “<TeamID>” –password “<app专用密码>”

之后,得知并不是UI端卡住,而是确实在in progress,这种情况要么继续等待,要么重新提交一次,我选择继续等待

5、查看Archieve路径下的文件,竟然有600多M,但询问Cursor后得知当前应用打包分发后安装包大小可能在40-60M之间,比Swift版本要大很多的原因在于其中包含了FlutterMacOS.framework,即Flutter框架核心,占用了超过一半的大小,并且当前应用同时支持Intel和Apple Silicon架构,即通用二进制(Universal Binary)

6、跟ChatGPT确认了下即使在等待Notary的过程中也能修改代码,不影响继续开发,但在Xcode中构建时发现,由于之前在Xcode中其中了Hardened Runtime,禁用了JIT,但Flutter的Dart VM需要JIT编译来运行,特别是在Debug模式下,导致构建失败,于是添加了必要的权限,并重新生成了缺失的文件,构建成功,继续测试并增加功能

7、由于过往对话数据已经被清空,打开应用之后可以看到所有界面的空状态提示,其中在“选择AI模型”界面,昨天已经新增了“添加更多模型”卡片,点击可以跳转到设置-AI模型管理界面,我需要在未添加任何模型时,“选择AI模型”界面也显示“添加更多模型”卡片,并且点击可以跳转到设置-AI模型管理界面,不再显示“还没有配置模型,请前往设置中添加”的提示文字

8、修改后的效果是,没有模型时只显示“添加更多模型”卡片,有模型时在模型列表最后显示“添加更多模型”卡片,并且都可以点击跳转到设置-AI模型管理界面

9、然后添加模型,一个支持深度思考的DeepSeek官方的Reasoner,一个不支持深度思考的OpenRouter的Claude 3.7 Sonnet,用于测试后续新增的功能,首先要增加的就是上传和解读文档功能,在现有的上传图片功能上增加:

1.在AI模型管理界面,点击测试按钮时同步测试是否支持文档,测试结果和目前的“支持图片/不支持图片”在同一行显示

2.在选择AI模型界面,根据测试结果,每个模型下方的支持图片/不支持图片后面加上是否支持文档

3.消息框右边的别针图标,鼠标划过时的提示文字由“上传图片”改为“上传图片或文档”

4.点击别针图标,可通过文件选择器选择图片或文档,在支持现有的图片格式的基础上,增加对word、excel、ppt、txt、pdf等常见文档格式的支持

10、修改过程中涉及数据模型、AI模型管理界面、选择AI模型界面和消息框文件选择器,扩展了文件选择器支持格式,包括doc、docx、xls、xlsx、ppt、pptx、txt、pdf,重新在Xcode中构建,经过测试,claude 3.7模型就支持文档,但在对话中选择并上传文档后,浮窗上仍然显示“已选择图片”,并且图标显示也不正常,Xcode中出现了DB Error: 1 “table ai_messages has no column named image_paths”等错误信息,我需要将浮窗中的“已选择图片”改为“已选择附件”,如果附件是图片就显示缩略图,如果附件是文档就显示文档的扩展名,另外我在点击发送消息后,对话窗口中看不到任何内容,即使只是简单的“你好”,也收不到任何回复

11、Cursor在修改过程中,修复了数据库问题,更新了变量名,调整了界面显示并添加了文件图标(根据扩展名返回对应图标),再次测试,普通文字消息可以正常回复,图片可以正常上传、解读,文档可以正常上传,但会回复我“错误:访问被拒绝,请检查API Key权限”,但这个模型在测试时是支持文档的,调试信息中出现了这些内容:flutter: 图片加载失败: /Users/jinlei.wu/Library/Containers/com.jinleiwu.chatwith/Data/Documents/chat_images/1768290385014_文档解读测试.docx, 错误: Exception: Invalid image data,另外,我发送带有附件(图片或文档)的消息之后,消息中包含一行文字“[包含1张图片]”需要改为“[包含1个附件]”

12、本轮修改涉及数据库问题修复、文档处理逻辑(仅支持读取TXT格式的文本内容并添加到消息中,其他格式暂时先提示用户当前版本暂不支持自动提取内容)、消息显示文本更新、消息界面显示和变量名更新,Cursor指出大多数AI API不支持支持上传文档文件,如果需要支持更多文档格式,可以使用文档解析库或支持文件上传的API(如OpenAI的Assistants API)

13、先测试一下TXT格式的附件,再次遇到错误,可能是因为这个TXT的编码不是UTF-8导致的?Cursor再次修改ai_service以支持更多编码,修改后,会首先尝试UTF-8编码,如果失败就读取字节并检测BOM,如果再失败就使用Latin1作为后备,但它也指出对于GBK/GB2312等中文编码,可能会出现乱码,可以添加charset_convert或encoding包来处理GBK编码,先试试同一个附件,再看要不要添加新的包

14、测试后果然遇到了“由于您提供的文档内容是乱码,我无法直接提炼要点。这可能是因为文档编码格式不兼容导致的。”的回答,那既然要添加新的包,就让Cursor同时添加支持word文档、pdf文档和更多编码的txt文档的解析库,一通操作之后只添加了charset_converter包,可以支持多种编码格式,但针对PDF和word文档,由于Flutter生态中缺少合适的免费包,暂时只能等用户上传后提示用户手动输入内容,再次测试TXT文档已经可以正常解读

15、继续修复一些小问题,比如我在收藏消息到笔记时,目前的规则是以用户提问作为标题,以AI回答作为正文,但用户提问中如果包含附件,笔记标题就会有“[包含1个附件]”,我不需要“[包含1个附件]”,只用用户提问的纯文本作为标题就好,Cursor在收藏按钮的onPressed回调中,添加了清理附件标记的逻辑,使用纯文本作为笔记标题,再次测试问题已解决

16、针对PDF文档,Cursor在前边的修改中有建议到使用syncfusion_flutter_pdf(可能需要商业授权)或使用macOS原生的API,询问ChatGPT后了解到macOS有提供PDFKit,可以用于解读非扫描版PDF,如果是扫描版PDF,则需要使用PDFKit+Vision OCR,比较复杂,这次先让Cursor整合macOS的PDFKit,以实现对非扫描版PDF文档的解读功能

17、修改过程包含:创建PDFTextExtractor.swift(使用macOS的PDFKit框架提取PDF文本)、注册方法通道、更新Flutter代码和Xcode项目,修改后,当用户上传PDF文档时,系统会自动调用macOS PDFKit提取文本,如果成功,文本内容会被添加到消息中,如果失败(比如遇到扫描版PDF)会提示用户,测试发现已经可以解读非扫描版PDF,并且速度也挺快

18、结合目前的应用功能刷新一下README.md,其中现有的版本历史部分增加一条“支持文档输入(目前支持TXT和非扫描版PDF)”,放到“支持图片输入(多图片支持)”下面,然后在设置-关于ChatWith里,近期更新内容和README.md的版本历史部分保持一致,但需要分别匹配emoji,再次构建测试,设置-关于ChatWith页面已修改完成,但Archive的Notary依然in progress,服了,另外明天再问问Cursor能否使用macOS的textutil实现对word文档的解析(来自千问的建议)

DevLog:2026年1月12日

1、昨天对发送图片、解读图片的功能进行了修正,并且修改了切换模型后仅界面发生变化,实际仍未切换模型的问题,接下来继续丰富应用功能,优化体验

2、有一个遗留问题,在AI输出过程中对话列表频繁刷新,不是很影响使用体验,只是视觉上感觉不太好,之前多次修改后问题仍然存在,试试看能否修正,Cursor在修复时在Consumer中添加了缓存机制,并在_ChatSessionRow的_onViewModelChanged中添加检查,对话列表只在如下情况刷新:AI回答结束后、创建新对话、删除对话、修改标题、置顶/取消置顶,测试发现已修复,对话列表不再频繁刷新,看来如果在一个对话里多次提出某个需求未能解决的话,打开一个新对话再重新提需求,或许真的能解决问题

3、到目前,使用Flutter重构的ChatWith for Mac已经基本对齐了之前的Swift版本,并且还增加了对笔记(原收藏)的富文本编辑、上传和解读图片的功能,接下来将版本号修改为v0.1,并刷新一下README.md,再看看Cursor有哪些增加功能、优化体验的建议

4、Cursor列举了大量不同优先级的建议,结合个人的使用习惯,我觉得这些功能可以作为下一步的开发重点:对话导出(导出为Markdown,放在设置-数据管理中)、收藏导出(导出为Markdown,放在设置-数据管理中)、多模态支持(支持word、pdf等文档)、快捷键支持(新建对话/笔记command+N、发送消息command+enter、复制消息command+C,并且在设置中列出这些快捷键)、拖拽功能(拖拽图片、拖拽文档)、API Key和Tavily Key加密存储

5、先逐个增加这些功能,不更改版本号:

1.选择AI模型的界面,增加“添加更多模型”功能,也用目前的模型卡片样式,放在已有模型的下方,点击直接跳转设置-AI模型管理界面

2.选择AI模型的界面,底部的“取消”按钮改为确认

3.API Key和Tavily Key加密存储,之前竟然不是加密存储?也需要跟Cursor确认下

4.设置列表增加“数据管理”,放在“外观设置”和“数据统计”之间,包含导出所有对话、导出所有笔记两个功能,但要询问下Cursor到底是导出为Markdown还是JSON

6、首先是“添加更多模型”功能,Cursor在模型选择界面添加了“添加更多模型”卡片,并实现了跳转功能(使用GlobalKey实现跨组件导航),方便添加新模型,另外由于目前在选择AI模型界面点击模型即可实现切换,那就把底部的“取消”按钮改成“确定”就行了,不需要在功能上有啥变化

7、然后是API Key和Tavily Key的加密存储,询问Cursor后得知目前是以明文存储在SharedPreferences中,感觉还是挺不安全的,Cursor建议了三种加密方式:使用flutter_secure_storage或encrypt包对敏感信息加密、使用macOS的Keychain存储密钥,或者至少使用AES进行基础加密

8、我选择了使用AES进行基础加密,这也需要添加encrypt依赖,实现的效果包括AES-256加密(使用256位密钥),每个应用实例生成唯一的加密密钥,密钥存储在SharedPreferences中,并且在保存时自动加密,加载时自动解密,Cursor还增加了“旧的未加密数据在首次加载时会保持原样,下次保存时会被加密”的功能,测试一下,现有模型功能未受影响,但与新添加的模型对话时,“AI正在思考中”的提示一闪而过,看不到回答的内容,不清楚是否与刚刚的加密功能有关

9、可能是在加密之后,应用会将加密的字符串误当做API Key导致的?Cursor进行了调整并添加了详细的调试信息,收到了“这可能表示API返回格式不符合预期,或者模型配置有问题”的调试信息,结合调试信息,Cursor认为原因是DeepSeek API在流式响应中返回的usage字段为null,代码直接将其转换为Map<String, dynamic>导致类型转换错误,修改之后再次测试,新模型也可以正常使用了

10、还有一个问题,貌似在对话过程中将模型A切换为模型B后,如果对话中有前文,就会继续和模型A对话,如果是新的对话,没有前文,就会和模型B对话,这个逻辑也不对,应该是我切换到模型B后,就直接跟模型B对话,让Cursor检查下是否存在这个问题,Cursor在检查后认为sendMessage中获取的session可能不是最新的,于是修复了这部分的逻辑,切换模型后,无论是否有前文,都会使用新的模型进行对话,测试发现该需求已成功搞定

11、然后就是数据导出功能了,我先询问了ChatGPT,我有一个使用Flutter开发的AI对话应用,包含AI对话和笔记两个模块,我需要增加数据导出功能,点击可以导出所有的AI对话和笔记,你建议默认导出为哪种格式?ChatGPT回答是“笔记以 Markdown 为主形态,对话以 JSON 为主形态;但完整导出时,两者都应同时提供。”感觉没能解决我的问题,反而更复杂了,Cursor则建议AI对话和笔记都导出为Markdown,AI对话的导出内容包含会话标题、时间范围、消息列表(用户/AI)、时间戳、token统计(可选,话说不知道Cursor啥时候给我加上了这个功能,AI每次回答的底部现在都有统计信息),笔记的导出内容包含标题、内容、创建/修改时间、字数统计(可选)

12、结合ChatGPT和Cursor的回答,明确我的需求如下:

1.在设置列表增加“数据管理”,放在“外观设置”和“数据统计”之间

2.点击设置列表中的“数据管理”,右侧详情包含“导出所有AI对话”和“导出所有笔记”两个功能

3.点击“导出所有AI对话”,即将所有AI对话内容,包括会话标题、时间范围、消息列表(用户/AI)、时间戳、token统计导出为一个.md文件,命名为“AI对话+当前时间”,并提醒用户选择保存路径

4.点击“导出所有笔记”,即将所有笔记内容,包括标题、内容、创建/修改时间、字数统计导出为一个.md文件,命名为“笔记+当前时间”,并提醒用户选择保存路径

13、上述需求提交给Cursor,修改过程中,Cursor进一步细化了导出的AI对话和笔记涉及的内容,并且会有错误提示和成功提示、自动排除已删除的对话和笔记,测试发现顶部的“数据管理”和“导出所有数据为Markdown格式文件”提示文字都可以去掉,但点击导出按钮后Xcode提示错误:Unable to display save panel: your app has the User Selected File Read entitlement but it needs User Selected File Read/Write to display save panels. Please ensure that your app’s target capabilities include the proper entitlements.可能还是权限问题?

14、Cursor指出这是macOS权限配置问题,目前的entitlements文件只有只读权限,但保存文件需要读写权限,将两处read-only改成read-write后再次测试,AI对话和笔记都可以正常导出并选择保存路径了

15、然后给应用增加一个关于页面,设置列表的最后增加一个“关于ChatWith”,点击后在右侧设置详情显示如下内容:

第一行,标题:ChatWith

第二行,文本:Any AI LLM you like.

第三行,版本号:v0.1.0(当前版本号)

分割线

近期更新:罗列一下近期的更新点

然后,设置-数据管理顶部的“数据管理”和“导出所有数据为Markdown格式文件”提示文字一并去掉

16、修改过程中添加了新的依赖package_info_plus,但未自动运行pod install,导致构建失败,再次提示Cursor运行pod install更新CocoaPods依赖,然后修复了一个package_info_plus中的版本号显示逻辑问题,但还有一些地方版本号显示有问题,梳理之后发现主要版本定义(源头)在于pubspec.yaml,这是Flutter的版本定义源,但有些地方甚至采用了硬编码来定义版本号,于是要求所有显示版本号的地方都统一采用pubspec.yaml中的版本号,并移除硬编码,以后要修改版本号只需修改这一处就好了,再次测试、Clean Build Folder、测试、用Cursor清理缓存、测试,版本号已可正常显示,明天继续丰富功能、优化体验

DevLog:2026年1月8日

1、昨天在引入flutter_quill之后未做测试,今天首次测试又遇到了The sandbox is not in sync with the Podfile.lock. Run ‘pod install’ or update your CocoaPods installation.的错误提示,这是CocoaPods同步问题,通常发生在添加新依赖后,需要运行pod install以同步Podfile.lock,并且flutter_quill在macOS上需要原生桥接库(quill_native_bridge_macos),Cursor还提醒我如果后续添加新的原生依赖,记得在macos/目录下运行pod install

2、把这条也添加到了Cursor的User Rules里,并且也跟Cursor明确了这个要求,完整的说法应该是“以后在Flutter macOS项目中添加新依赖后,会自动在macos/目录下运行pod install以同步CocoaPods依赖”,看看以后是否还会出现类似问题

3、测试发现编辑模式无法正常使用,切换到编辑模式后,提示“UnimplementedError:FlutterQuillLocalizations instance in required and could not found. Add the delegate ’FlutterQuillLocalizations.delegate’ to your widget app (e.g., MaterialApp) to fix.”

4、原因在于flutter_quill需要FlutterQuillLocalizations.delegate来提供本地化字符串,Cursor在修改过程中添加了flutter_localizations依赖,在MaterialApp中添加了本地化支持,再次测试可正常启用编辑模式,其中的格式按钮也基本都可正常使用,但是我自己创建的笔记在预览状态下只能显示纯文本,即使我添加了Markdown语法标记也看不到Markdown渲染的效果,然后也看不到使用富文本编辑器编辑后的所有效果(试了几个不同的格式,只有斜体可以在预览状态下看到),并且所有的文字内容都没有左对齐,像是每一行前面都有很多空白

5、Cursor认为原因在于之前使用了toPlainText()保存,会丢失所有格式,改成了保存Delta JSON格式,保留所有富文本格式(粗体、斜体、列表、代码块等),关于预览模式的显示,对于富文本内容使用QuillEditor只读模式显示,可显示所有格式,对于纯文本/Markdown内容使用MarkdownBody显示,支持Markdown语法渲染,并且可以自动检测内容格式,选择合适的显示方式,关于左对齐的问题,移除了可能导致对齐问题的外层滚动视图,使用Padding直接包裹编辑器,确保内容左对齐

6、测试发现基本实现了上面所说的效果,富文本内容和Markdown内容都可以在预览界面正常显示了,但在过程中反复出现了构建失败-反馈错误-Cursor修改的过程,最后原因是前面修改功能后出现了语法错误,比如括号匹配问题、readOnly参数使用问题,修复后可以正常构建,于是要求Cursor以后在修改文件后先检查有没有语法错误,再总结具体都修改了哪些,这样也能减少一些反复测试、反馈、修改的工作量

7、Cursor回复:已记录该工作流程,新的工作流程是

1.修改代码

2.立即检查语法错误(运行flutter analyze检查分析错误、使用read_lints检查linter错误、修复所有语法和编译错误)

3.确认无误后,再总结修改内容

8、继续丰富功能,目前比较刚需的功能是上传和解读图片功能,需要加高消息输入框,并在消息输入框右侧的联网搜索按钮上方增加一个附件按钮,点击可以打开系统的文件浏览器选择图片,需要支持常见的图片格式,并且在选择-上传图片之后,不立即发送给AI,而是在输入框上方以浮窗形式显示缩略图,需要用户输入文字形式的指令,并点击发送按钮,才能发送给AI,看下Cursor对这种比较复杂的指令的理解和实现程度如何

9、修改过程包括添加依赖(file_picker文件选择和image图片处理)、修改输入框(加高、添加_selectedImages列表存储选中的图片)、添加附件按钮、实现图片选择功能(使用FilePicker.platform.pickFiles打开系统文件浏览器,支持jpg/jpeg/png/gif/webp/bmp,且支持多选)、实现图片预览浮窗(显示80*80的缩略图、每张图片右上角有删除按钮、提供清除按钮清除所有图片、仅在选中图片时显示)、修改发送逻辑、修改ViewModel、修改AI Service,实现的功能包括图片选择、图片预览、延迟发送、组合发送、图片管理

10、构建应用并测试一下图片上传功能,首先点击新增的附件按钮就出现了选择图片失败的提示,Invalid argument(allowedExtensions),并且上传附件的按钮样式,和联网搜索、发送按钮的样式区别也比较大,也需要调整一下

11、反馈后,Cursor修复了图片选择错误,原因在于FileType.image与allowedExtensions不能同时使用,将FileType.image改为FileType.custom,同时修改了附件按钮的样式为Icons.attach_file_outlined和Icons.attach_file

12、再次测试,点击添加附件按钮出现了如下调试信息,Cursor认为这是macOS沙盒权限的问题

Unable to obtain a task name port right for pid 601: (os/kern) failure (0x5)

Unable to display open panel: your app is missing the User Selected File Read app sandbox entitlement. Please ensure that your app’s target capabilities include the proper entitlements.

13、于是在两个entitlements文件(DebugProfile.entitlements-DEBUG和Profile构建配置、Release.entitlements-Release构建配置)中添加了必要的权限:启用应用沙盒、允许读取用户通过文件选择器选择的文件、允许网络请求,之后Clean Build Folder,继续测试

14、重新生成Flutter ephemeral文件后,可以正常构建,可以选择图片、上传图片、发送图片及问题,但发送之后看不到缩略图,需要优化下,即使发送图片之后,也要在对话界面看到缩略图,可以和文字消息合并到一起

15、另外发图片给DeepSeek系列模型的API后才发现它不支持多模态输入输出,会报错HTTP 400,Invalid content type.image_url is only supported by certain models,看样子在模型管理界面还需要识别并标示一下哪个模型支持读取图片,比如点击测试按钮即可同步测试连通性以及是否支持图片及附件,并在模型列表中标示

16、以上两个问题同时反馈给Cursor,修改过程包括消息显示优化(支持图片缩略图)、数据模型扩展(支持图片路径)、数据库升级(添加图片路径字段)、发送消息逻辑(保存图片路径)、模型管理界面(图片支持测试,如果模型支持图片,显示“支持图片标识”)、模型配置扩展(图片支持标识)

17、测试修改效果,支持图片的模型可以看到蓝色的“支持图片”的标识,我需要给测试之后不支持图片的模型加上“不支持图片”的标识,但颜色上要有所区别,比如不支持图片的标识和文字用红色,同时,是否支持图片的标识也需要在AI对话的模型选择界面显示,方便用户选择模型,另外,虽然Claude Sonnet 4支持读取图片,但给它发图之后依然收到了不支持图片的Invalid content type.image_url is only supported by certain models错误提示

18、修改后再次测试发现,虽然在测试时可以看到“不支持图片”的红色标识,但这个红色标识并不会像“支持图片”的蓝色标识一样会一直存在,并且在AI对话的模型选择页面里,也看不到“不支持图片”的红色标识,只能看到“支持图片”的蓝色标识,另外,AI对话的模型选择页面需要优化一下显示效果,使用类似“设置-数据统计”页面的卡片形式,继续让Cursor修改

19、Cursor添加了imageSupportTested字段,修复模型管理界面的标识持久化,并优化了模型选择界面,再次测试功能正常

20、然后就是上面提到的,虽然Claude Sonnet 4的API支持读取图片,但给它发图之后依然返回了“Invalid content type.image_url is only supported by certain models”错误提示,Cursor认为这是因为Claude API使用了与OpenAI不同的图片格式,导致发送图片时出现这种错误提示,在修改过程中添加了_isClaudeAPI()方法,检测是否为Claude API(通过baseURL、模型名称或备注判断),并且进行了图片格式适配、请求头适配、请求体适配、流式响应处理等操作,再次测试,遇到了新BUG,上传图片后看不到缩略图了,并且还有同样的HTTP 400错误信息,明天再修改

DevLog:2026年1月7日

1、今天继续测试并优化应用功能,首先把收藏板块修改成“笔记”板块,功能不变,比如点击AI回答底部的收藏按钮后创建新的笔记,目前的收藏页面的“收藏”都改成“笔记”,“新建收藏”改成“新建笔记”,搜索界面的搜索框内提示词“收藏”改成“笔记”,设置界面的数据统计、回收站中“收藏”改成“笔记”,并且图标也要做对应调整

2、共涉及9个文件的修改,在修改过程中,除了我提到的这些地方外,还修改了AI对话界面的提示信息、收藏界面的空状态提示等,不过AI对话消息底部的按钮文字我还是希望用“收藏”,纠正之后此需求搞定

3、目前还缺失一些自己日常使用AI应用时经常用到的功能,比如AI对话的内容无法选择文字并复制,只能复制完整的回答内容,与AI对话的方式仅限于文字,不能发图片、发文件,且笔记的编辑功能过于简单,目前只能在切换到编辑模式后使用Markdown语法对笔记内容进行修改,但自己创建的笔记又不能通过添加Markdown语法标记来实现编辑操作(预览状态下没有任何渲染效果),而且感觉Markdown对普通用户来说还是有一些门槛,不如富文本编辑器直观

4、以上共涉及三个功能,首先从选择AI对话内容的文字并复制开始,要求Cursor:我需要给AI对话界面增加选择对话内容文字并复制的功能,选择文字后弹出复制按钮,点击即可复制到剪贴板,Cursor多次更换了实现方式,最后使用了SelectionArea来包装MarkdownBody,使文本可选择,并使用透明的SelectableText覆盖在MarkdownBody上,用于检测文本选择,测试发现选择文本时的选中效果很差,而且看起来像是选中了两行,结果点击复制按钮后才发现只复制了半行,要求Cursor试试其他的实现方式

5、Cursor换成了使用SeletableText.rich渲染Markdown内容,保持格式的同时支持文本选择,但这样一来又看不到哪些文字已经被选中了,即使添加了选择高亮颜色,也没有解决问题,决定先舍弃这个功能,回退到将收藏改为笔记,并且AI对话消息底部的按钮文字仍然用“收藏”的应用版本

6、然后尝试修改第三个功能,丰富一下笔记的编辑功能,开启一个新对话,先询问Cursor目前的笔记模块使用的是怎样的编辑器,有没有比较好用的富文本编辑器可以使用?Cursor回答目前应用的编辑模式是使用Flutter原生的TextField(纯文本),显示模式是使用flutter_markdown渲染Markdown,推荐的富文本编辑器包括flutter_quill、super_editor、flutter_markdown_editor、rich_text_editor,其中最推荐使用flutter_quill,支持富文本编辑,并可导出为Markdown,以及flutter_markdown_editor,可以保持Markdown工作流,从我个人的使用习惯来看,我更偏向flutter_quill

7、让Cursor集成flutter_quill,步骤包括在pubspec.yaml中添加flutter_quill依赖,修改note_edit_view.dart使用QuillController替代TextField,实现Delta格式与纯文本/Markdown的转换逻辑,更新编辑和显示模式的UI,中途可能是因为网络问题?flutter_quill 11.5.0的安装过程一直卡住,也知道有没有正常安装

8、回家之后继续安装flutter_quill 11.5.0,后修改问题后,Cursor总结已完成这些工作:更新依赖、集成富文本编辑器(含添加QuillSimpleToolbar工具栏)、实现内容转换、更新UI,目前已具备的功能包括富文本编辑器、工具栏、与现有数据兼容、非编辑模式下仍使用Markdown渲染,明天再测试实际实现了哪些功能、有哪些问题需要修复,这个功能实现的差不多之后,再添加上传图片、文件的功能

DevLog:2026年1月6日

1、继续测试使用Flutter重写的ChatWith for Mac,还有很多问题需要修改,先修改这几处:

1.把右上角的搜索按钮挪到最左侧,放在“对话”上面

2.明确对话列表、收藏列表的显示规则,对话列表中,标题是用户提出的最后一个问题,下面小字显示最后一次回答的内容,只显示一行,收藏列表中,标题是收藏的回答对应的问题,下面小字显示收藏的回答内容,只显示一行

3.对话列表和收藏列表的宽度都固定为300,且不需要拖动调整

4.应用最顶部标题栏的chatwith改成ChatWith

2、上述问题1、2、3均已修改,问题4仍未修改,而且还存在如下问题,继续修改

1.顶部居中显示的ChatWith没有用,可以去掉

2.每次打开应用时窗口大小都会回到初始值,没有保存上次打开时对窗口大小的调整,还需要手动调整一下

3.简化一下设置界面,第三列即设置详情的顶部,需要去掉AI模型管理、外观设置、数据统计、回收站这些标题

4.添加和修改模型时,底部的高级设置展开后显示不全,并且有一条多余的分割线,可以去掉

3、继续修改一些界面上的小问题,之后重点测试对话流程,比如切换模型对话、联网搜索功能等等

1、左上角搜索按钮,鼠标划过时不需要显示提示,并且划过时的背景大小要和下面的对话、收藏、设置按钮背景大小一致,在搜索按钮下方增加“搜索”二字,与其他三个按钮样式保持一致

2.去掉对话列表顶部的“新建对话”按钮,去掉收藏列表顶部的“新建收藏”按钮

3.About chatwith界面的应用名是哪里规定的?可否改成ChatWith?

4.每条AI回答内容的底部除现有的收藏、复制按钮外,增加一个删除按钮

4、Cursor修改之后,上面2、3、4都已经OK,但是1鼠标在划过时显示成了方形的背景,而非划过对话、收藏、设置按钮时的圆角矩形按钮,继续修改,并且给最左侧导航栏顶部添加了8像素的间距,不再紧贴顶部

5、收藏界面打开一条收藏后,列表顶部的分割线和收藏详情顶部的分割线没有对齐,让Cursor把收藏详情顶部的“编辑”和“复制”按钮改成和对话详情顶部的“新建对话”按钮一致的样式,虽然仍然没有完全对齐,但相比之前已经美观很多了

6、继续修改对话和收藏页,首次打开应用时对话界面虽然有空状态提示,但没有新建对话按钮,还需要把刚才删掉的对话列表顶部的“新建对话”按钮加回来,同时右侧详情页顶部的模型切换按钮、新建对话按钮,即使未打开任何对话,也要一直显示;针对收藏页,收藏列表顶部的“新建收藏”按钮也加回来,如果没有打开任何一条收藏,右侧详情页顶部就只显示一个“新建收藏”按钮,如果打开了任何一条收藏,右侧详情页顶部就显示“编辑”和“复制”按钮,这样修改之后对话和收藏页面的列表、详情页分割线就对齐了

7、接下来给收藏详情页底部增加一行信息栏,打开一条收藏后,可显示该条收藏的添加时间、修改时间(最后一次修改的时间)、字数统计三个信息;然后在对话详情页,需要给每条消息增加时间信息,显示在消息下方,Cursor先使用了比较复杂的相对时间(近期)+完整日期时间(较早的日期)的方式,今天的时间只显示时分,昨天的时间显示为昨天+时分,一周内的时间显示为几天前,更早的显示为完整日期时间,貌似这也是苹果设备上的应用比较常用的时间显示方式

8、然后把回收站的收藏和对话换个顺序,左边是已删除的对话,右边是已删除的收藏,到此,对于应用界面的首轮修改就差不多了,备份了之前使用Swift写的ChatWith for Mac,然后清理了对应的文件、刷新了README.md文档

9、接下来开始对各项功能进行测试和完善,在对话过程中发现如下问题,先集中修改一波:

1.新建对话时,有时会出现这样的问题:新对话在列表里会显示和上一个对话一样的标题和副标题,再次新建对话才会以“新对话”为标题

2.启用联网搜索功能后,联网搜索结果的显示需要优化,我只需要看到标题-网站名和来源链接,不需要从中摘取的内容,并且这些链接我需要可以点击,点击后直接用默认浏览器打开

3.对话列表的置顶功能有问题,比如我将对话A和B都置顶,再取消对话A的置顶,这时应该只有对话B置顶,但实际使用时却是对话A置顶,对话B被取消了置顶,并且置顶的对话应该有个区别于非置顶对话的底色,可以对比下收藏列表的置顶功能,收藏列表的置顶功能正常

4.对话列表和收藏列表,都应当支持用户修改标题(点击标题后面的三个圆点,菜单里需要有置顶/取消置顶、修改、删除三个功能,在在现在的基础上增加“修改”功能),如果用户修改了标题,就一直用用户修改的标题,如果没有修改,就沿用之前的标题获取逻辑

10、修改后测试,构建失败,问题:The sandbox is not in sync with the Podfile.lock. Run ‘pod install’ or update your CocoaPods installation.原因在于刚刚为了实现参考链接可点击的功能,添加了url_launcher依赖,需要重新安装Pods以包含新的macOS插件(url_launcher_macos),否则就会出现Podfile.lock与实际的Pods目录不同步的问题,修改之后解决

11、再次测试,其他问题基本都已修正,还需要继续进行一些优化:对话列表可能存在刷新机制的问题,对标题进行修改、置顶/取消置顶、新建对话等操作后,列表有时不会立即刷新;联网搜索功能参考的链接需要增加到10个,5个链接可能参考性不足;AI回答内容背景的灰色太深了,需要浅一些

12、再次测试,发现对话列表的刷新机制还是有点问题,比如AI正在回答时,对话列表就会频繁刷新,其实不需要,让Cursor改成了回答结束后刷新对话列表,但发现在联网搜索过程中和回答过程中还是在频繁刷新,于是和Cursor明确:在联网搜索过程中也不要频繁刷新,只有回答结束后、置顶/取消置顶后、修改标题后、创建新对话后 这几种情况下才触发对话列表的刷新操作,再次修改后对话列表仍然会在AI回答过程中频繁刷新,这个问题后面再开一个新对话再修改

13、继续测试应用的功能,接下来是收藏模块,首先收藏的内容比较长时,收藏详情底部会出现“BOTTOM OVERFLOWED BY XXX PIXELS”这种提示,并且无法滚动查看,只有在点击编辑后才能滚动查看,修改过程中将非编辑模式下的MarkdownBody包裹在SingleChildScrollView中,使内容可滚动,问题已解决

14、发现新问题,有些回答内容中就会带一些文字形式的链接,但只显示为蓝色文字,无法打开,我需要让这些链接也像Tavily提供的参考链接那样可以直接点开,在回答内容、收藏内容都是如此,都要点击可以直接点开,为实现这一需求,针对AI回答内容中的链接,Cursor给MarkdownBody添加了onTapLink回调,点击链接时使用url_launcher在默认浏览器中打开,并且添加了链接样式,针对收藏内容中的链接,Cursor导入了url_launcher包,并为MarkdownBody添加了onTapLink回调,实测问题已解决

15、对话和收藏删除之后,回收站里第一条内容和分割线之间没有任何间距,需要稍微增加一点间距(可以用第一条和第二条之间的间距),视觉上更好一些,针对这一问题,Cursor给第一条删除的内容和TabBar分割线之间增加了8像素的间距,与列表项之间的间距一致,视觉上更统一了

16、还有,数据统计界面的收藏、对话、模型三个图标颜色有些突兀,需要改一下,针对这种比较模糊的需求,Cursor将Colors.red、Colors.blue和Colors.purple改成了Colors.pink.shade300、Colors.blue.shade300和Colors.grey.shade300,认为这些颜色比较柔和,与界面更协调,再次构建看效果,的确比之前要好些了

17、AI模型管理界面,每个模型卡片的整体高度需要稍微缩减一下,稍微紧凑一点点,现在每个卡片的高度都比较高,默认窗口大小的情况下只能显示两三个模型,Cursor同步修改了卡片内边距、标题字体大小、垂直间距、文字大小、按钮尺寸等等,显示效果好多了

18、然后调整数据统计界面的卡片间距,之前间距过大,要求统一成8,但视觉上还是很大,可能每个卡片上下各有8的间距?另外还需要增加已删除的对话、已删除的收藏 两个数据统计卡片,图标颜色用灰色,整体顺序用:AI模型数量、对话数量、已删除对话数量、收藏数量、已删除收藏数量,再次构建测试,需求已达成,今天到此结束

DevLog:2026年1月5日

1、年前对目前的项目进行了盘点,暂定先主要推进ChatWith移动端(已使用Flutter重写)和ChatWith for Mac的开发工作

2、针对ChatWith for Mac,节前要求Cursor进行了微调,以实现“所有网络请求必须在后台线程执行,所有UI更新操作必须在主线程执行”的需求,今天起对应用进行测试,主要看是否还会在切换对话时遇到卡死问题,已经去掉了在对话中切换模型的功能,如果测试没有什么明显的问题就修改设置-关于页面、刷新README文档,并打包,版本号用v0.3

3、对比Chatbox,有几个功能后面还是要加上,比如上传图片、上传文件并由AI进行解读,这两个功能留到后面v0.5时再添加

4、接下来调整一下UI,特别是输入框,目前应用的输入框看不到边框线,且右侧的联网搜索和发送/停止按钮大小不一样,要求Cursor给对话界面的输入框增加灰色边框线,并修改联网搜索按钮,去掉已关闭、已开启的文字,只留图标

5、输入框和按钮的修改基本完成,但总感觉发送/停止按钮和联网搜索按钮大小不一样,且在测试时再次遇到了应用卡死问题,从调试信息来看,对话的输入和输出是正常的,但没有看到UI更新,继续反馈问题给Cursor,修改一次之后卡死问题更加严重,只要打开应用-打开历史对话就会卡死,再次反馈、修改

6、目前打开应用-打开历史对话暂时不会卡死了,但在翻看更早的历史对话消息时又会卡死,要求Cursor添加调试信息来定位问题,同时还询问了豆包,豆包认为所有的耗时操作都不应该放在主线程执行,比如网络请求(之前已经挪到了后台线程)和本地数据读写(涉及DataManager和MessageView等文件),修改之后Cursor指出,虽然Core Data的保存操作必须在主线程执行,但由于使用了异步执行,不会阻塞调用线程

7、再次测试,仍然会出现卡死问题,逐渐失去耐心了,询问豆包,换用 Flutter 完全可以从根源上解决这类卡死问题,且Flutter对「消息列表加载/渲染」的适配性远优于原生Swift,99%的原生卡死场景在Flutter中都能彻底规避;更关键的是,Flutter无需像原生那样做大量「线程切换、异步处理」的繁琐适配,基础写法就自带防卡死能力,开发效率更高

8、开启了一个新对话,决定在新对话中先梳理目前应用的功能,并且用Flutter来重写当前应用,步骤包括创建Flutter项目结构和基础配置、创建数据模型、实现数据层、实现AI服务层、实现视图模型、创建主界面、实现AI对话视图、实现收藏视图、实现设置视图、实现搜索视图、检查并完善所有模型类等等,耗时大概50分钟,中间还中断了一次,点击继续之后Cursor首先查可能了已有文件,了解进度,并逐步完成剩余部分

9、使用Flutter的项目结构包含models-数据模型、services-服务层、viewmodels-视图模型、views-UI视图,之后让Cursor生成了该应用的的macOS平台代码,并且在生成ephemeral文件,并修复编译错误、图标问题后,项目成功构建

10、使用Flutter构建的应用界面稍显简陋,主要的功能板块已经有了,包括对话、收藏、设置三个页面,设置中包含了AI模型管理、外观设置和数据统计,但每个界面右上角都带了一个DEBUG的标志,不知道是干啥用的,先让Cursor去掉它(debugShowCheckedModBanner),同时也问问能否把之前已有的图标文件复制过来一份,继续使用(将Swift版本的图标复制到Flutter版本,并重命名为Flutter所需的文件名格式)

11、修改过程中再次出现了频繁创建.md说明文件的情况,其实我用不到,要求Cusor清理掉

12、目前ChatWith for Mac已经实现了基于Flutter的改写,并且可以成功构建,接下来需要对各个功能进行详细测试和修改,目前已发现的问题包括:

1.在添加和修改模型时,我需要让添加和修改窗口在最前,只有点了取消或确定后才能回到主界面,现在只要一点主界面,添加和修改窗口就会被关闭

2.对话时,点击发送按钮后问题发不出去,没有任何反应

3.设置-外观设置-主题模式中,我需要跟随系统、浅色模式、深色模式三个选项,并且点击选项后可实现对应的主题模式

4.需要增加回收站功能(删除和恢复对话和收藏)和搜索功能(搜索对话和收藏)

5.设置-AI模型管理界面,需要增加删除模型按钮

13、初步修改了一轮之后,发现上面的五个问题里,

1.已解决

2.未解决,发送按钮有时可用有时不可用

3.已解决

4.需要把回收站挪到设置页的数据统计下边,即设置界面共有AI模型管理、外观设置、数据统计、回收站四个功能

5.未解决,AI模型管理界面还是没有删除模型按钮

14、继续修正问题2和问题4,问题2通过添加输入框监听器和_cansend状态变量,已完成修改,问题4主要是在entitlements文件中添加了com.apple.security.network.client权限,允许应用进行网络请求,已完成修改,并且在测试过程中发现之前使用Swift实现的深度思考、流式输出等功能均可正常使用

15、继续修正问题5,通过移除if(config.isCustom)条件判断,改为每个模型后边都会显示删除按钮,解决了问题

16、明天继续修改其他问题,包括:

1.把右上角的搜索按钮挪到最左侧,放在“对话”上面

2.明确对话列表的显示规则,标题直接用用户提出的最后一个问题,下面小字显示最后一次回答的内容,只显示一行

3.对话列表和收藏列表的宽度都固定为300,且不需要拖动调整

4.其他问题视测试情况而定

DevLog:2025年12月24日

1、询问ChatGPT使用Flutter开发的iOS应用,如何打包成用于Mac的版本,ChatGPT指出思路不是把iOS的ipa直接变成Mac版,而是用同一套Flutter代码开启macOS平台支持,然后构建出macOS App(.app),然后再分发,ChatGPT推荐开发一个Flutter macOS桌面端,适配窗口/鼠标/键盘,且同时支持Intel/Apple Silicon两大平台,如果是让iPad App跑在Mac上,仅支持Apple Silicon,且可能会遇到插件/权限的问题

2、若使用ChatGPT推荐的方案,需要开启macOS平台支持,检查插件是否支持macOS,并且需要处理UI/交互的适配,如尽享使用响应式布局,适配鼠标滚轮、右键、hover、快捷键等操作,以及文件选择、拖拽、菜单栏等等

3、以上两点留到后面再修改ChatWith移动端时再看,可以一并询问Cursor能否支持macOS,以及需要做哪些调整

4、今天继续测试修改后的ChatWith for Mac(Swift原生版),上周增加了设置默认模型功能,去掉了自动创建新对话功能,改为提示用户开启新对话,并且新对话直接使用默认模型,还未测试,ChatGPT认为所有网络请求必须在后台线程执行,所有UI更新操作必须在主线程执行,但我没有给它代码,先让Cursor检查下目前是否使用了这种方式

5、Cursor对将AIService.swift进行了两处修改,包括:isLoading和errorMessage的更新现在使用Task { @MainActor in }确保在主线程,stopStreaming()中的isLoading = false现在也在主线程更新,这样整个应用就统一成了网络请求在后台线程执行,UI更新在主线程执行