| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
fix(tools): 审计器补齐 recv/selfCalls 索引与只读白名单;标注器定位修正 ## audit_parallel 的四个误判来源 **① indexMethods 没设 recv 和 selfCalls ⇒ 递归跟进空转** scanWritesDeep 靠 recv 组候选键、靠 selfCalls 才知道跟进谁,缺任一个 就静默漏判。handleRestart 只调 p.stopServer/startServer 两个方法, 因此被判成"只读" —— 而 stopServer 里有 p.server = nil。 (我先补了闭包那条分支的 selfCalls,误以为问题在闭包上,其实是 indexMethods 整体缺字段。) **② writePatterns 写了 ".Set(" 而 callString 收集的是方法名** p.sdk.Settings().Set(...) 是三段链,callString 返回 "Settings.Set", 永远匹配不上 ".Set("。漏判比误判更难发现:结果看着仍然合理。 → 模式改为不带括号。 **③ looksLikeExternal 用黑名单 ⇒ 纯读标准库调用全被判"可能写"** Marshal / ReadAll / NewRequest / NewReader 都不带写操作迹象,却被判写, 120 个工具里 119 个判成 SERIAL —— 等于工具没在工作,却**看上去在工作** (保守方向不会引起怀疑)。 → 改为 knownReadOnlyCalls 白名单。判定原则:**默认怀疑,明确信任** —— 写不动的东西要逐个列出来。 **④ 工具名提取打印 AST 内部结构** fmt.Sprintf("%v", a.Y) 输出 tp&{10500 10515 STRING "manage_social"}, 名字里混着指针地址,人没法核对。 → 改用 BasicLit.Value + 归一化去掉运行期前缀。 ## annotate_parallel 的插入点定位 改文本匹配改结构体字面量这条路走了三次弯: - 正则找"最后一个顶层字段"被嵌套 map 里的同形文本骗到,823 处重排改坏文件 - 变量前缀匹配没要求 RegisterTool( 在**同一行**,命中函数体里散落的字面量, 起点错到 switch case 中间,报错指向一处看起来完全无辜的分支 - 只按行末**净**深度判断:Parameters 写在单行时(进出同一行,净变化 0) 永远察觉不到曾进入深度 3,追踪一路跑到 1305 行才"收敛" → 最终按**行内峰值深度** + 记录进入深度 3 的行号判定。 ## 幂等 未标注过的工具重复跑会插入第二份 ParallelSafe(duplicate field 编译错误)。 → 加 blockHasDecl 预检。 | 15 天前 | |
feat(docs): 换品牌图标 + 补备案号 + 给 agent 的直读入口 三件事,都是「站点上线后看出来的」问题。 ## ① 图标用的是 Material 默认,不是我们的 站上 favicon 是 mkdocs-material 自带的那张( assets/images/favicon.png), 与主站 introduce 不一致。改为引入主站同一份 logo: - docs/assets/logo.svg —— 原样(浅色底,适合 favicon) - docs/assets/logo-mark.svg —— 去掉底色矩形(否则在靛蓝页头上是个白方块) theme.favicon / theme.logo 分别指向它们。实测子页面路径也正确 (mkdocs 生成 ../../assets/logo.svg,不是错误的相对路径)。 ## ② 缺备案号 introduce 底部有 ICP + 公安备案,文档站没有。Material 的 footer 只渲染 config.copyright 一个字符串,塞不进「两条带链接的备案」——所以覆盖了 overrides/partials/footer.html(theme.custom_dir),并顺带把许可也写进底部, 读者在任何一页都能看到,不必翻到首页。 ## ③ 没有给 agent 的入口 站点是给人看的(HTML + 主题 + JS 搜索),但越来越多读者是 agent。让它们爬 HTML 既浪费 token(样板占大头)又容易漏内容。 新增 tools/apidoc/gensite/agent.go,随构建产出: | 路径 | 内容 | |---|---| | /llms.txt | 站点目录:每页一行,带 URL 与一句话说明(4.3KB)| | /llms-full.txt | 全部文档正文拼成一份,可一次读完(115KB)| | /<page>.md | 每个页面的 Markdown 原文,含生成的 API 页(text/markdown)| 沿用 llms.txt 社区约定:llms.txt 读目录、llms-full.txt 一次读全。 **一个必须处理的坑**:mkdocs 只把 .md **渲染**成 HTML,不会把 Markdown 放进产物目录 —— 那样 llms.txt 里的链接会全部 404。所以 build.sh 增加了 第 4 步 copy_agent_files,在构建后把 23 个 Markdown 复制进 site_build/。 docs/llms-full.txt 已 gitignore:它是派生件,改任何一页都会整份重写, 进版本库只产生噪声(llms.txt 索引小且稳定,仍提交)。 验证:mkdocs build --strict 零告警;favicon/logo 可取(200,naturalWidth=400); 三页底部均含两个备案号;4 个 agent 入口均可访问且 content-type 正确。 | 18 天前 | |
feat: add example plugins (ai_image, calendar, music, rss, weather), fix .gitignore, move gengskill to tools/ | 2 个月前 | |
fix(hmapdev): SDK 模块识别要认新旧两个 module 名(迁移漏改的逻辑判定) 上一提交(b6a6168)只替换了 import 路径,**漏了用旧 module 名做逻辑判定 的五处**。CI 当场抓到一处( TestPrintVersionReportsInjectedVersion), 但那是测试断言;另外三处是**产品逻辑**,CI 抓不到,是静默失效。 ## 漏改的地方 | 位置 | 原判定 | 失效后果 | |---|---|---| | cmd_build.go | Contains(mod,"homeagent-sdk") | 认不出 SDK 依赖 ⇒ **不写 replace** | | cmd_skill.go | Contains(gm,"homeagent-sdk") | 认不出 SDK 仓 ⇒ 不安装 skills | | yaegi/interp.go ×2 | Contains(line,"homeagent-sdk") | findSDKGoPath 找不到 SDK ⇒ 退化到兜底 | 迁移后这些 Contains **恒为假**(新名是 homeagentsdk,没有连字符)。 三者都**不报错**,只是行为悄悄变成另一条分支——比直接崩更难发现。 ## 关键:不能只认新名 本机实测存量插件工作区的 go.mod **全部仍是旧名**: /home/program/qq-plugin (无 go.mod) /home/program/vanblog-plugin require gitcode.com/JianFeeeee/homeagent-sdk /home/program/mcquery-plugin require gitcode.com/JianFeeeee/homeagent-sdk /home/program/fileproc-plugin require gitcode.com/JianFeeeee/homeagent-sdk /home/program/agentmail/plugins/ require gitcode.com/JianFeeeee/homeagent-sdk 用户已创建的项目不会因为我们改仓就自动更新。所以判定必须 **两种都接受**,而不是把旧名换成新名(那只是把 bug 从"认不出新"换成"认不出旧")。 ## 改动 - meta 补 SDKModule / LegacySDKModule 常量(原注释引用了 SDKModule 但常量并不存在——注释先于实现) - 新增 tools/hmapdev/sdkmodule.go:isSDKModule / sdkModulePath / containsSDKModule - 新增 tools/hmapdev/yaegi/sdkmodule.go:同语义的最小副本 (yaegi 是独立子包,不能 import 父包) - 三处逻辑判定改用上述助手 ## 判据(可杀变异,逐个实测) sdkmodule_test.go + yaegi/sdkmodule_test.go:覆盖新名/旧名/带版本号的 旧名/空串/核心仓(HomeAgent,不是 SDK)/无关模块。 这三个判定点**此前零测试覆盖**——这正是它们能静默失效的原因。 变异验证: - 只认新名 → FAIL「旧名漏认会让存量插件静默走错分支」 - containsSDKModule 只认新名 → FAIL「必须认旧名」 ## 验证 - SDK 根 module + hmapdev module:go build / go test 全通过 - 20 个 example go vet 全通过 - go mod verify → all modules verified | 4 天前 | |
feat(vscode): 插件工程调试扩展(plg.json 诊断 / SDK 版本 / 构建运行 / 内核日志跟随) 插件的真实形态是「独立子进程 + 内核侧握手」,所以插件问题几乎都在 IDE 之外发生: 编不出来(多半是没声明用哪版 SDK,工具链拿了存储里的 current)、编出来起不来 (产物与内核协议绑定)、起来了行为不对(真因只在内核日志里)。这个扩展把这三件事 拉进 IDE。 - tools/vscode-hmapdev:TypeScript 扩展(零运行时依赖,仅 devDeps: typescript + @types/vscode) - **plg.json 诊断**:必需字段;sdk 必须是完整版本号(区间写法 1.2 报错并说明 「patch 位恒为 .0」,与工具链 ResolveSDKForProject 同一套规矩);声明的 SDK 未安装时 直接给 hmapdev sdk install vX.Y.Z; - **状态栏**:插件 · SDK <声明> · hmapdev <版本>,工具链缺失/工程有错时变色,tooltip 列已装 SDK; - **命令**:build / build --target all / clean / debug(解释执行)/ 工具链版本 / SDK 列表-安装-切换 / 跟随内核日志 / 停止跟随 / 刷新; - **任务**:同一批动作注册为 hmapdev 任务 + Go 问题匹配器(编译错误进 Problems); - **内核日志跟随**:读 <dataDir>/log 最新 homed_*.log,按插件名过滤持续输出; - schema 校验 + plg.json 骨架片段。 - 诚实边界(写进 README):**不是源码级调试器**——没有断点/单步,没有 DAP 会话; 做的是构建、运行、看内核日志、清单校验。 验证:tsc 零错误;node --test 13/13(版本规则、诊断分级、SDK 列表解析、状态栏文本、 以及**反向核对抓到的真缺陷**:hmapdev 未找到 这类输出曾被解析成版本号 → 已要求版本 token 以数字开头,否则「工具链不在」会被显示成「工具链 <垃圾词>」并让 SDK 诊断失真); 与真实工具链输出的集成核对 PASS(hmapdev version / sdk list 的真输出解析正确)。 README 同时补两节:plg.json 的 sdk 字段语义(含「为什么必须有」与「为什么拒区间写法」)、 本扩展的用法与边界。 | 30 天前 | |
fix(tools): 审计器补齐 recv/selfCalls 索引与只读白名单;标注器定位修正 ## audit_parallel 的四个误判来源 **① indexMethods 没设 recv 和 selfCalls ⇒ 递归跟进空转** scanWritesDeep 靠 recv 组候选键、靠 selfCalls 才知道跟进谁,缺任一个 就静默漏判。handleRestart 只调 p.stopServer/startServer 两个方法, 因此被判成"只读" —— 而 stopServer 里有 p.server = nil。 (我先补了闭包那条分支的 selfCalls,误以为问题在闭包上,其实是 indexMethods 整体缺字段。) **② writePatterns 写了 ".Set(" 而 callString 收集的是方法名** p.sdk.Settings().Set(...) 是三段链,callString 返回 "Settings.Set", 永远匹配不上 ".Set("。漏判比误判更难发现:结果看着仍然合理。 → 模式改为不带括号。 **③ looksLikeExternal 用黑名单 ⇒ 纯读标准库调用全被判"可能写"** Marshal / ReadAll / NewRequest / NewReader 都不带写操作迹象,却被判写, 120 个工具里 119 个判成 SERIAL —— 等于工具没在工作,却**看上去在工作** (保守方向不会引起怀疑)。 → 改为 knownReadOnlyCalls 白名单。判定原则:**默认怀疑,明确信任** —— 写不动的东西要逐个列出来。 **④ 工具名提取打印 AST 内部结构** fmt.Sprintf("%v", a.Y) 输出 tp&{10500 10515 STRING "manage_social"}, 名字里混着指针地址,人没法核对。 → 改用 BasicLit.Value + 归一化去掉运行期前缀。 ## annotate_parallel 的插入点定位 改文本匹配改结构体字面量这条路走了三次弯: - 正则找"最后一个顶层字段"被嵌套 map 里的同形文本骗到,823 处重排改坏文件 - 变量前缀匹配没要求 RegisterTool( 在**同一行**,命中函数体里散落的字面量, 起点错到 switch case 中间,报错指向一处看起来完全无辜的分支 - 只按行末**净**深度判断:Parameters 写在单行时(进出同一行,净变化 0) 永远察觉不到曾进入深度 3,追踪一路跑到 1305 行才"收敛" → 最终按**行内峰值深度** + 记录进入深度 3 的行号判定。 ## 幂等 未标注过的工具重复跑会插入第二份 ParallelSafe(duplicate field 编译错误)。 → 加 blockHasDecl 预检。 | 15 天前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 15 天前 | ||
| 18 天前 | ||
| 2 个月前 | ||
| 4 天前 | ||
| 30 天前 | ||
| 15 天前 |