DevLog:2026年1月21日

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

1.DoitWith

-设置-已完成 Todo,数据统计不正确

-首次启动应用时无需示例数据

-已完成Todo页面同样以分组形式显示

-已过期的Todo需要在显示上有所差异

2.ChatWith(目标是对齐ChatWith for Mac)

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

-在与支持深度思考的模型对话时,看不到思考内容,我需要增加一个展示思考内容的区域,默认折叠,可以点击展开,并且显示样式要和回答内容有所区别(两轮修改后已有思考内容区域,但看不到具体的思考内容)

-参考链接放到AI回答内容气泡下方,不要合并到AI回答内容的气泡内

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

-不要给所有填写了Tavily Key的模型开启联网搜索功能,由用户自行开启/关闭联网搜索功能

-发送按钮上方设置联网搜索开关,并调整布局,拉高消息框,右侧有竖向排列的联网搜索开关和发送按钮

-设置界面删掉多余的说明文字“管理您的AI模型配置,包括API Key、Base URL、模型名称等”

-针对API Key和Tavily Key添加加密机制,提升安全性

-目前已有默认模型机制,但还不能在对话中切换模型,需要添加切换模型机制,点击对话界面右上角的模型备注信息,弹出切换界面,切换界面列出当前的所有模型,点击可切换,并与新模型对话

-对话界面右上角显示的模型信息太长了,改为只显示备注,不显示模型名称

-对话列表中显示的标题是用户的第一个问题,需要改为用户的最后一个问题

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

3.ChatWith for Mac

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

2、首先让Cursor修正ChatWith移动版的启动即闪退问题,包括在main.dart中添加错误处理,防止初始化失败导致崩溃、添加全局错误处理,捕获未处理的异常、检查并修复数据库初始化可能的错误等步骤,再次测试暂时没有出现闪退问题,后面再继续测试,发现一个新问题,在对话页右上角点加号创建新对话时,会先闪过一个红屏,但也能正常创建新对话

3、Cursor表示问题可能出现在chat_page.dart中,当找不到对话时,之前会抛出Exeption,导致红屏,修改之后会返回一个默认的Conversation对象,显示“新会话”标题,在重新构建之前,发现再次出现了闪退问题,并且是“首次安装、启动后应用可以正常运行,一旦清了后台再打开,就会闪退”,Cursor认为这可能是应用从后台恢复时数据库连接已失效,但静态变量仍保留引用,使用失效连接会抛出异常,Provider初始化时未捕获异常,导致崩溃,于是对数据库层、Provider层进行了修改,并对main.dart添加了全局错误处理,主要是在获取数据库时检查连接有效性,失效则重新初始化

4、再次测试,依然会遇到清除后台后重新打开时闪退的问题,并且在真机测试过程中,控制台的日志也找不到ChatGPT和Cursor都在说的Exeption、Error、Fatal相关的错误,Cursor添加了更详细的调试信息,先看下在模拟器中测试时能否复现这一问题,以及返回怎样的错误信息,但在测试过程中并未看到“应用从后台恢复”及以后的调试信息,并且之后添加了更详细调试信息之后,也没能看到Cursor提及的可能有用的调试信息,在清除后台后重新打开时,没有返回任何调试信息

5、修改过程中反复遇到了因为没有添加缺失的导入,导致构建失败——反馈问题——添加导入的问题, 跟Cursor明确了下,以后在添加或修改代码时,主动检查并添加所有必需的导入,避免等构建失败后再修复

6、多次反馈、反复修改后依然存在清除后台后无法启动的问题,接下来先测试其他功能,暂时搁置对这一问题的修正

7、逐步调整ChatWith的其他功能,首批修改内容如下:

1.在与支持深度思考的模型对话时,看不到思考内容,我需要增加一个展示思考内容的区域,默认折叠,可以点击展开,并且显示样式要和回答内容有所区别

2.参考链接放到AI回答内容气泡下方,不要合并到AI回答内容的气泡内

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

4.对话界面右上角显示的模型信息太长了,改为只显示备注,不显示模型名称

5.设置界面删掉多余的说明文字“管理您的AI模型配置,包括API Key、Base URL、模型名称等”

8、在切换到Composer 1模型后(Cursor内置的GPT、Gemini、Claude等模型都因为区域受限无法使用,即使我开了梯子),响应速度明显快了很多,进行了调整思考内容展示区域、参考链接移到气泡下方、发送消息后立刻显示、模型信息只显示备注、删除设置界面多余的说明文字等修改,真机测试,上面的需求1未实现,2参考链接气泡和回答内容气泡未对齐,要继续改,3未实现,4、5已实现,另外在对话窗口顶部,对话的标题应该居左显示,再次反馈并修改

9、继续真机测试,思考内容区域只显示“思考中”,不显示具体的思考内容,发送消息后仍然要等一下才会显示在对话界面,参考链接气泡对齐方式已调整,标题已居左,继续修改,这两个问题依然没能解决,暂时搁置

10、继续进行其他修改,本轮需求包括:

1.针对API Key和Tavily Key添加加密机制,提升安全性

2.目前已有默认模型机制,但还不能在对话中切换模型,需要添加切换模型机制,点击对话界面右上角的模型备注信息,弹出切换界面,切换界面列出当前的所有模型,点击可切换,并与新模型对话

11、修改过程中,Cursor引入了encrypt和flutter_secure_storage用于AES加密存储,创建了model_selector_dialog.dart用于选择模型,并将model_display.dart修改为可点击,接下来真机测试(又要运行pod install以同步iOS依赖),模型切换和选择功能已经实现,但Tavily联网搜索功能好像失效了,重新填写Tavily Key(猜测可能是因为加密机制的问题?),依然无法在对话中获取参考链接和最新信息

12、Cursor添加了调试信息,测试发现Tavily Key解密成功,但出现网络错误,错误信息为null,继续添加更详细的调试信息,再次测试,结合调试信息中的错误HandshakeExeption: Connection terminated during handshake,Cursor认为是SSL/TLS握手失败,于是在Info.plist中添加了App Transport Security配置,在ApiClient中配置了SSL证书验证,再次测试,虽然可以联网搜索并获取链接,但搜索到的信息并未整合到回答内容里,反馈之后,Cursor改进了搜索结果的格式,添加了系统信息(明确指导AI要基于搜索结果回答问题),并且改进了消息构建逻辑,测试发现此问题仍然存在,后续再修改

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清理缓存、测试,版本号已可正常显示,明天继续丰富功能、优化体验