✨ 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

+17 -13
View File
@@ -97,13 +97,13 @@ describe('库规则:启用', () => {
})
describe('库规则:认领', () => {
it('认领的块换成替身:种类、badge、编辑范围是整个类;规则没并进来的子块(夹在中间的注释、方法)照源码顺序留下', async () => {
it('认领的块换成替身:种类、badge、编辑范围是整个类;规则没并进来的子块(方法)照源码顺序留下,讲并进来的子块的注释跟着并进来', async () => {
const rule: LibraryRule = {
...cardRule('orm'),
claim: (block) => {
if (block.kind !== 'class')
return undefined
const [table, , column] = block.children
const [table, column] = block.children
return { kind: 'orm.card', badge: { label: '卡片', color: { dark: '#fff', light: '#000' }, icon: 'box' }, rows: [{ label: '名称', value: [{ text: 'User', role: 'type' }] }], absorbs: [table, column] }
},
}
@@ -117,7 +117,7 @@ describe('库规则:认领', () => {
attributes: { kind: 'orm.card', access: 'public' },
properties: [{ label: '名称' }],
})
expect(card.children.map(child => [child.id, child.kind, child.startLine])).toEqual([['1.0', 'comment', 4], ['1.1', 'function', 7]])
expect(card.children.map(child => [child.id, child.kind, child.startLine])).toEqual([['1.0', 'function', 7]])
})
it('两个字段中间写着的方法:预览里照常是卡片的子块;卡片「编辑」写回整个类', async () => {
@@ -166,7 +166,7 @@ describe('库规则:认领', () => {
const alone = await views(MODEL, [throwing])
expect(alone[1]).toMatchObject({ kind: 'class', startLine: 2, headerEndLine: 2, endLine: 8 })
expect(alone[1].children.map(child => child.kind)).toEqual(['variable', 'comment', 'variable', 'function'])
expect(alone[1].children.map(child => child.kind)).toEqual(['variable', 'variable', 'function'])
})
it('替身不合约定(种类 id 没带规则 id、并进来的不是子块):记下来,照常显示', async () => {
@@ -183,15 +183,20 @@ describe('库规则:认领', () => {
])
})
it('略去的块不出块,后面的块 id 接着往下数;还有子块的块不能略去,记下来、照常显示', async () => {
it('略去的块不出块,后面的块 id 接着往下数;还有子块、挂着注释的块不能略去,记下来、照常显示', async () => {
const omitting = (kind: string): LibraryRule => ({ ...cardRule('omit'), claim: block => block.kind === kind ? { omit: true } : undefined })
const list = await views(MODEL, [omitting('import')])
expect(list.map(view => [view.id, view.kind])).toEqual([['0', 'class']])
expect(list[0].children.map(child => child.id)).toEqual(['0.0', '0.1', '0.2', '0.3'])
expect(list[0].children.map(child => child.id)).toEqual(['0.0', '0.1', '0.2'])
const reports: string[] = []
expect((await views(MODEL, [omitting('class')], reports)).map(view => view.kind)).toEqual(['import', 'class'])
expect(reports).toEqual(['库规则 omit 给第 3 行的 class 块的替身不合约定,这块照常显示:要略去的块还有子块'])
const commented: string[] = []
const [, kept] = await views(MODEL, [omitting('variable')], commented)
expect(kept.children.map(child => [child.kind, child.startLine])).toEqual([['variable', 4], ['function', 7]])
expect(commented).toEqual(['库规则 omit 给第 6 行的 variable 块的替身不合约定,这块照常显示:要略去的块挂着注释'])
})
it('挂在卡片子行上的子块:照常转成块,记下挂在哪一行的哪个子行;不是留下的子块、没有那一行 / 子行、放了两处的不合约定', async () => {
@@ -205,15 +210,15 @@ describe('库规则:认领', () => {
? { kind: `${id}.card`, badge: { label: '卡片', color: { dark: '#fff', light: '#000' }, icon: 'box' }, rows, absorbs: block.children.slice(0, 1), slots: slots(block) }
: undefined,
})
const [, card] = await views(MODEL, [slotting(block => [{ block: block.children[2], row: 0, item: 0 }, { block: block.children[3], row: 1, item: 0 }])])
expect(card.children.map(child => [child.kind, child.slot])).toEqual([['comment', undefined], ['variable', { row: 0, item: 0 }], ['function', { row: 1, item: 0 }]])
const [, card] = await views(MODEL, [slotting(block => [{ block: block.children[1], row: 0, item: 0 }, { block: block.children[2], row: 1, item: 0 }])])
expect(card.children.map(child => [child.kind, child.slot])).toEqual([['variable', { row: 0, item: 0 }], ['function', { row: 1, item: 0 }]])
const reports: string[] = []
const bad = await views(MODEL, [
slotting(block => [{ block: block.children[0], row: 1, item: 0 }], 'absorbed'),
slotting(block => [{ block: block.children[3], row: 5, item: 0 }], 'row'),
slotting(block => [{ block: block.children[3], row: 1, item: 1 }], 'item'),
slotting(block => [{ block: block.children[3], row: 1, item: 0 }, { block: block.children[3], row: 0, item: 0 }], 'twice'),
slotting(block => [{ block: block.children[2], row: 5, item: 0 }], 'row'),
slotting(block => [{ block: block.children[2], row: 1, item: 1 }], 'item'),
slotting(block => [{ block: block.children[2], row: 1, item: 0 }, { block: block.children[2], row: 0, item: 0 }], 'twice'),
], reports)
expect(bad[1].kind).toBe('class')
expect(reports.map(report => report.replace(/^.*照常显示:/, ''))).toEqual([
@@ -235,7 +240,7 @@ describe('库规则:认领', () => {
expect(recognized).toMatchObject({ kind: 'enum', startLine: 2, endLine: 8, attributes: { kind: 'enum', access: 'public' } })
expect(recognized.badge).toBeUndefined()
expect(propertyLines('properties' in recognized ? recognized.properties : [])).toEqual(['名称: User', '访问级别: 公共', '成员: 无'])
expect(recognized.children.map(child => child.kind)).toEqual(['comment', 'variable', 'function'])
expect(recognized.children.map(child => child.kind)).toEqual(['variable', 'function'])
const reports: string[] = []
const stranger: CodeBlock[] = []
@@ -250,7 +255,6 @@ describe('库规则:认领', () => {
expect(fileAttributes(list, pythonZhTranslator.attributeNames).find(attribute => attribute.id === 'kind')?.values).toEqual([
{ id: 'import', name: '导入', count: 1 },
{ id: 'orm.card', name: 'orm 卡片', count: 1 },
{ id: 'comment', name: '注释', count: 1 },
{ id: 'variable', name: '变量', count: 1 },
{ id: 'function', name: '函数', count: 1 },
{ id: 'return', name: '返回', count: 1 },