✨ feat(vscode): 代码阅读的注释挂到它讲的代码块上成「注释」一行,重写注释改用技能一句话加结构化结果

- 普通注释不再单独成卡片:同一层挂到后面最近的块(隔空行也算),后面没有挂到前面那块,整层没代码挂到父块;只有文件开头隔着空行的注释、模块 docstring、//!、@file 单独成「文件开头的说明」
- 各语言(Python、TypeScript、Rust、Shell、Dockerfile)建好树后统一调 attachComments;块的编辑范围连着挂上的注释,差异、跳转、钉住卡片都按它
- 宿主统一给每张卡片(语言卡片、翻译插件的属性表、库规则卡片、一行译文的语句卡片)插「注释」一行,排在名称、说明后面
- TypeScript 的 JSDoc 也能当常量、变量的说明;sqlx、React 不再单独处理前面的注释
- 「重写注释」每块都有:提示只发 /ecc:writing-code-comments 路径:起-止,模型只读、按 --json-schema 交 body,没交结构化正文就失败不写;扩展换掉块前面的注释或在块上面新写一段
This commit is contained in:
cruldra committed 2026-10-08 07:51:21 +08:00
1 parent 335cf9ca9f
commit 582ac4c987
49 files changed
+1730 -757

No files matched your search

@@ -27,9 +27,9 @@ const FETCH_READING = [
'interpreter 1',
' 解释器: bash',
' 怎么找: 按 PATH 去找(/usr/bin/env bash)',
'comment 2: 下载执行器自带的 git 与 python, 放到 src-tauri/resources/runtime/<target>/{git,python}。',
'options 14',
'options 2',
' 出错就停: 是 -e',
' 注释: 下载执行器自带的 git 与 python, 放到 src-tauri/resources/runtime/<target>/{git,python}。',
' 用到没设的变量就报错: 是 -u',
' 管道里任一步失败都算失败: 是 -o pipefail',
'variable 16',
@@ -101,41 +101,41 @@ const FETCH_READING = [
'case 68: 按 git_pkg 分情况',
' 以 .zip 结尾 | 解压 zip git_pkg 到 dest/git(不打印过程)',
' 其他 | 解压 tar.gz git_pkg 到 dest/git',
'comment 72: python-build-standalone 的包里顶层目录就叫 python',
'command 73: 解压 tar.gz py_pkg 到 dest',
'comment 75: ── 去掉 Git Credential Manager ──────────────────────────────────────────────',
'case 78: 按 target 分情况',
'command 72: 解压 tar.gz py_pkg 到 dest',
' 注释: python-build-standalone 的包里顶层目录就叫 python',
'case 75: 按 target 分情况',
' 注释: ── 去掉 Git Credential Manager ──────────────────────────────────────────────',
' case 79: 情况:以 -apple-darwin 结尾',
' variable 80',
' 名称: gc',
' 初始值: dest/git/libexec/git-core',
' command 81: 删除 gc/git-credential-manager*、gc/*.dll、gc/*.dylib、gc/createdump、gc/NOTICE、gc/uninstall.sh(连同里面的东西、不提示)',
' comment 83: .NET 的各语言资源目录; git 自己的子目录只有 mergetools',
' command 84: 找出 gc 下一层的目录,除了 mergetools,逐个 删除(连同里面的东西、不提示)',
' command 83: 找出 gc 下一层的目录,除了 mergetools,逐个 删除(连同里面的东西、不提示)',
' 注释: .NET 的各语言资源目录; git 自己的子目录只有 mergetools',
' case 86: 情况:以 -windows-msvc 结尾',
' comment 87: mingw64/bin 里 git 自己依赖的 DLL 都以 lib 开头 (外加 zlib1.dll), 其余 DLL 都属于 GCM;',
' variable 89',
' variable 87',
' 名称: mb',
' 注释: mingw64/bin 里 git 自己依赖的 DLL 都以 lib 开头 (外加 zlib1.dll), 其余 DLL 都属于 GCM;',
' 初始值: dest/git/mingw64/bin',
' command 90: 删除 mb/git-credential-manager.exe*、mb/libHarfBuzzSharp.dll、mb/libSkiaSharp.dll(不提示)',
' command 91: 找出 mb 这一层的 *.dll,除了 lib* 和 zlib1.dll,逐个 删除',
'comment 95: Windows 版 python 只有 python.exe; 平台脚本按 python3 这个名字再调起它时 (它的目录前置在',
'if 98: 如果 target 以 -windows-msvc 结尾',
'if 95: 如果 target 以 -windows-msvc 结尾',
' 注释: Windows 版 python 只有 python.exe; 平台脚本按 python3 这个名字再调起它时 (它的目录前置在',
' command 99: 复制 dest/python/python.exe 到 dest/python/python3.exe',
'comment 102: ── 去掉符号链接 ─────────────────────────────────────────────────────────────',
'if 105: 如果 target 以 -apple-darwin 结尾',
'if 102: 如果 target 以 -apple-darwin 结尾',
' 注释: ── 去掉符号链接 ─────────────────────────────────────────────────────────────',
' variable 106',
' 名称: gc',
' 初始值: dest/git/libexec/git-core',
' comment 107: 内建命令的短横线别名 (git-add -> git …): git 自己调内建命令不走它们。同 git 构建选项',
' loop 109: 遍历 gc/git-* 匹配到的每个文件 f',
' loop 107: 遍历 gc/git-* 匹配到的每个文件 f',
' 注释: 内建命令的短横线别名 (git-add -> git …): git 自己调内建命令不走它们。同 git 构建选项',
' if 110: 如果不是 〔f 是符号链接 并且 〔读出 f 指向的路径〕 等于 git〕,跳过这一个',
' case 111: 按 〔取文件名 f〕 分情况',
' git-upload-pack 或 git-receive-pack 或 git-upload-archive | 什么也不做',
' 其他 | 删除 f',
' comment 116: python 只留 bin/python3 这一个入口 (执行器按它找), 版本号命名的本体挪过来',
' variable 117',
' variable 116',
' 名称: pybin',
' 注释: python 只留 bin/python3 这一个入口 (执行器按它找), 版本号命名的本体挪过来',
' 初始值: dest/python/bin',
' variable 118',
' 名称: real',
@@ -143,8 +143,8 @@ const FETCH_READING = [
' command 119: 删除 pybin/python3',
' command 120: 改名 pybin/real → pybin/python3',
' command 121: 找出 dest/python 下面所有符号链接,逐个 删除',
' comment 122: 剩下的 (传输程序、git-remote-https 之类) 换成实体文件',
' pipeline 123: 找出 dest 下面所有符号链接 → 逐行读进 link',
' pipeline 122: 找出 dest 下面所有符号链接 → 逐行读进 link',
' 注释: 剩下的 (传输程序、git-remote-https 之类) 换成实体文件',
' command 124: 复制 link 指向的实体文件 到 link.tmp',
' command 125: 改名 link.tmp → link',
'command 129: 打印 "自带运行时就绪: dest"(打印到错误输出)',
@@ -54,9 +54,9 @@ const NEXT_READING = [
' variable 14',
' 环境变量: NEXT_TELEMETRY_DISABLED',
' 值: 1',
' comment 15: 部署 ID 烙进本次构建: Next 据此给静态资源加 ?dpl=、页内跳转时比对版本;',
' variable 17',
' variable 15',
' 构建参数: DEPLOYMENT_ID',
' 注释: 部署 ID 烙进本次构建: Next 据此给静态资源加 ?dpl=、页内跳转时比对版本;',
' 默认值: 没写,构建时传',
' variable 18',
' 环境变量: NEXT_DEPLOYMENT_ID',
@@ -84,8 +84,8 @@ const NEXT_READING = [
' copy 33: 复制(2 条连着写,属主都是 nextjs:nodejs)',
' 阶段 builder | /app/.next/standalone | ./',
' 阶段 builder | /app/.next/static | ./.next/static',
' comment 35: standalone 输出不含 public/, 必须显式拷贝 (字体等静态资源)',
' copy 36: 从阶段 builder 复制 /app/public → ./public(属主 nextjs:nodejs)',
' copy 35: 从阶段 builder 复制 /app/public → ./public(属主 nextjs:nodejs)',
' 注释: standalone 输出不含 public/, 必须显式拷贝 (字体等静态资源)',
' setting 38: 之后以 nextjs 身份运行',
' setting 39: 开放端口 3000',
' start 41',
@@ -102,8 +102,8 @@ const BACKEND_READING = [
' label 6: 标签',
' maintainer | Cruldra',
' description | luffy-agent-platform - 统一 Backend 镜像 (API/Worker/Beat/Flower)',
' comment 9: git: deployment 模块创建 bare repo;postgresql-client: alembic / psql 运维;curl: healthcheck',
' run 13: 执行(10 条命令,一条失败就停)',
' run 9: 执行(10 条命令,一条失败就停)',
' 注释: git: deployment 模块创建 bare repo;postgresql-client: alembic / psql 运维;curl: healthcheck',
' command 13: 更新软件包列表',
' command 14: 安装 ca-certificates、curl、gnupg、postgresql-client、git(不装推荐的包、不用确认)',
' command 16: 建目录 /usr/share/keyrings',
@@ -114,16 +114,16 @@ const BACKEND_READING = [
' command 23: 安装 postgresql-16-repack(不装推荐的包、不用确认)',
' command 24: 打印 pg_repack 的版本',
' command 25: 删除 /var/lib/apt/lists/*(连同里面的东西、不提示)',
' comment 27: Node.js:agent MCP 节点 (如 context7) 用 stdio + npx 拉子进程, api 容器必须有 npx。',
' copy 32: 复制(2 条连着写)',
' copy 27: 复制(2 条连着写)',
' 镜像 node:22-slim | /usr/local/bin/node | /usr/local/bin/node',
' 镜像 node:22-slim | /usr/local/lib/node_modules | /usr/local/lib/node_modules',
' 注释: Node.js:agent MCP 节点 (如 context7) 用 stdio + npx 拉子进程, api 容器必须有 npx。',
' run 34: 执行',
' command 34: 建符号链接 /usr/local/bin/npm → /usr/local/lib/node_modules/npm/bin/npm-cli.js(已有就替换)',
' command 35: 建符号链接 /usr/local/bin/npx → /usr/local/lib/node_modules/npm/bin/npx-cli.js(已有就替换)',
' copy 37: 从镜像 ghcr.io/astral-sh/uv:latest 复制 /uv、/uvx → /bin/',
' comment 39: appuser 先建、/app /lib 先归属:.venv 由 appuser 直接创建,末尾无需 chown -R',
' run 42: 执行(3 条命令,一条失败就停)',
' run 39: 执行(3 条命令,一条失败就停)',
' 注释: appuser 先建、/app /lib 先归属:.venv 由 appuser 直接创建,末尾无需 chown -R',
' command 42: 新建用户 appuser(建主目录、不能登录)',
' command 43: 建目录 /app、/lib(连同上级目录)',
' command 44: 把 /app、/lib 的属主改成 appuser:appuser',
@@ -132,8 +132,7 @@ const BACKEND_READING = [
' 环境变量: UV_CACHE_DIR',
' 值: /home/appuser/.cache/uv',
' setting 48: 工作目录 /app',
' comment 50: ── 依赖层(仅随 pyproject/uv.lock 变化重建)───────────────────────────',
' copy 54: 复制(12 条连着写,属主都是 appuser:appuser)',
' copy 50: 复制(12 条连着写,属主都是 appuser:appuser)',
' backend/pyproject.toml、backend/uv.lock | ./',
' lib/agent-dsl/pyproject.toml | /lib/agent-dsl/',
' lib/agent-compiler-deepagents/pyproject.toml | /lib/agent-compiler-deepagents/',
@@ -146,39 +145,40 @@ const BACKEND_READING = [
' lib/code-publish-compose-runner/pyproject.toml | /lib/code-publish-compose-runner/',
' lib/luffy-billing-sdk/pyproject.toml | /lib/luffy-billing-sdk/',
' lib/luffy-observability/pyproject.toml | /lib/luffy-observability/',
' comment 67: 三方依赖先装;本项目与 lib editable 包此时无源码,跳过安装留给第二次 sync',
' run 68: uv 按 lock 同步依赖 · 4 个选项',
' 注释: ── 依赖层(仅随 pyproject/uv.lock 变化重建)───────────────────────────',
' run 67: uv 按 lock 同步依赖 · 4 个选项',
' --frozen | 严格按 lock 文件,不改它',
' --no-dev | 不装开发依赖',
' --no-install-project | 不装本项目',
' --no-install-package × 11 | 不装这些包:agent-dsl、agent-compiler-deepagents、vendor-tools、code-sandbox-core、code-sandbox-daytona、code-sandbox-e2b、code-sandbox-local、code-publish-core、code-publish-compose-runner、luffy-billing-sdk、luffy-observability',
' comment 81: ── 源码层(每次代码变更只重建这里往下)────────────────────────────────',
' copy 82: 复制 lib → /lib(属主 appuser:appuser)',
' comment 83: agent 定义 (vendor/agents/*/agent.yaml + nodes/*.py) 与代码是同一个版本, 必须随镜像原子切换;',
' copy 85: 复制(5 条连着写,属主都是 appuser:appuser)',
' 注释: 三方依赖先装;本项目与 lib editable 包此时无源码,跳过安装留给第二次 sync',
' copy 81: 复制 lib → /lib(属主 appuser:appuser)',
' 注释: ── 源码层(每次代码变更只重建这里往下)────────────────────────────────',
' copy 83: 复制(5 条连着写,属主都是 appuser:appuser)',
' vendor | /vendor',
' backend/src/ | ./src/',
' backend/alembic/ | ./alembic/',
' backend/alembic.ini | ./',
' backend/scripts/ | ./scripts/',
' comment 91: 补装本项目 + lib editable 包(三方依赖已就位,秒级)',
' run 92: uv 按 lock 同步依赖(严格按 lock 文件,不改它、不装开发依赖)',
' comment 94: 远程调试支持:装入 uv 创建的 venv,按需通过 DEBUGPY_ENABLE=1 开启。',
' run 96: uv 安装 debugpy',
' 注释: agent 定义 (vendor/agents/*/agent.yaml + nodes/*.py) 与代码是同一个版本, 必须随镜像原子切换;',
' run 91: uv 按 lock 同步依赖(严格按 lock 文件,不改它、不装开发依赖)',
' 注释: 补装本项目 + lib editable 包(三方依赖已就位,秒级)',
' run 94: uv 安装 debugpy',
' 注释: 远程调试支持:装入 uv 创建的 venv,按需通过 DEBUGPY_ENABLE=1 开启。',
' variable 98',
' 环境变量: UV_NO_SYNC',
' 值: 1',
' comment 100: 部署 ID (Jenkins IMAGE_TAG): /health 回显、日志定位后端出自哪次构建. 选择性发布时 api 与 client 镜像 tag 可不同, 客户端是否过期以 client 镜像 (浏览器包 vs BFF) 为准.',
' variable 101',
' variable 100',
' 构建参数: DEPLOYMENT_ID',
' 注释: 部署 ID (Jenkins IMAGE_TAG): /health 回显、日志定位后端出自哪次构建. 选择性发布时 api 与 client 镜像 tag 可不同, 客户端是否过期以 client 镜像 (浏览器包 vs BFF) 为准.',
' 默认值: 没写,构建时传',
' variable 102',
' 环境变量: DEPLOYMENT_ID',
' 值: DEPLOYMENT_ID(构建参数)',
' setting 104: 开放端口 8000',
' comment 106: 默认 CMD 走 api,celery worker/beat/flower 由 compose 覆盖 command',
' health 107',
' health 106',
' 间隔: 30 秒',
' 注释: 默认 CMD 走 api,celery worker/beat/flower 由 compose 覆盖 command',
' 超时: 5 秒',
' 启动后宽限: 10 秒',
' 失败几次算不健康: 3 次',
@@ -15,21 +15,22 @@ const py = createPythonAdapter(WASM_DIR)
interface Translated { kind: string, segments: Inline[], markdown?: string, table?: PreviewTable }
/**
* 一行译文块、注释块的译文,按 header 起始行(1 起)索引;同一行有多块时取外层那块。属性表块见 describeAll。
* 一行译文块、注释块(单独成块的、挂在块上的)的译文,按 header 起始行(1 起)索引;同一行有多块时取外层那块。属性表块见 describeAll。
* calleeKind 同 SourceDocument.calleeKind(调用的名字定义成哪种块),不给就是宿主不查。
*/
function translateAll(adapter: LanguageAdapter, languageId: string, translator: Translator, source: string, calleeKind?: SourceDocument['calleeKind']): Promise<Map<number, Translated>> {
return withBlocks(adapter, languageId, source, (blocks) => {
const byLine = new Map<number, Translated>()
walk(blocks, (block) => {
const line = block.header.startRow + 1
if (byLine.has(line) || 'facts' in block)
// 挂在块上的注释(BlockShape.comments)同样按它自己的起始行翻
walk(blocks, block => [...(block.comments ?? []), block].forEach((item) => {
const line = item.header.startRow + 1
if (byLine.has(line) || 'facts' in item)
return
const { text: translation, table } = translator.translate(block, { source, language: adapter, markers: [], ...(calleeKind && { calleeKind }) })
const { text: translation, table } = translator.translate(item, { source, language: adapter, markers: [], ...(calleeKind && { calleeKind }) })
byLine.set(line, 'markdown' in translation
? { kind: block.kind, segments: [], markdown: translation.markdown }
: { kind: block.kind, segments: translation, ...(table && { table }) })
})
? { kind: item.kind, segments: [], markdown: translation.markdown }
: { kind: item.kind, segments: translation, ...(table && { table }) })
}))
return byLine
})
}