✨ 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:
1 parent
335cf9ca9f
commit
582ac4c987
49 files changed
+1730
-757
No files matched your search
@@ -2,7 +2,8 @@ import type { runClaudeLines } from '../../cc/spawnClaude'
|
||||
import type { AskDeps, AskRun } from './claudeAsk'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { CLAUDE_MISSING_MSG, ClaudeCancelledError, ClaudeError, ClaudeTimeoutError } from '../../cc/spawnClaude'
|
||||
import { askArgs, askClaude, askFailure } from './claudeAsk'
|
||||
import { COMMENT_SCHEMA } from '../commentRewrite'
|
||||
import { askArgs, askClaude, askCommentBody, askFailure } from './claudeAsk'
|
||||
|
||||
type RunLinesOptions = Parameters<typeof runClaudeLines>[0]
|
||||
|
||||
@@ -168,3 +169,28 @@ describe('失败了给人看的话', () => {
|
||||
expect(askFailure(new ClaudeCancelledError(''))).toBe('Claude Code 没答成:Claude 调用已停止')
|
||||
})
|
||||
})
|
||||
|
||||
describe('重写注释问一次', () => {
|
||||
const structured = (body: string): string => line({ type: 'result', subtype: 'success', is_error: false, result: JSON.stringify({ body }), structured_output: { body }, session_id: 's1' })
|
||||
|
||||
it('只读、按 JSON Schema 交结构化结果:参数在只读那套后面加 --json-schema,stdin 里只有那一句提示;返回结构化结果里的正文', async () => {
|
||||
const { deps, calls } = fakeClaude([{ lines: [structured('按名字找文件。')] }])
|
||||
const events: unknown[] = []
|
||||
const body = await askCommentBody({ prompt: '/ecc:writing-code-comments src/a.py:3-8', profilePath: '/p/sonnet.json', cwd: '/work', signal: new AbortController().signal, onEvent: event => events.push(event) }, deps)
|
||||
expect(body).toBe('按名字找文件。')
|
||||
expect(calls[0].args).toEqual([...askArgs({ profilePath: '/p/sonnet.json' }), '--json-schema', COMMENT_SCHEMA])
|
||||
expect(calls[0].args).toEqual(expect.arrayContaining(['--tools', 'Read,Grep,Glob', '--permission-mode', 'dontAsk']))
|
||||
expect(JSON.parse(COMMENT_SCHEMA)).toEqual({ type: 'object', properties: { body: { type: 'string' } }, required: ['body'], additionalProperties: false })
|
||||
expect(sent(calls[0])).toEqual({ text: '/ecc:writing-code-comments src/a.py:3-8', images: [] })
|
||||
expect(calls[0].cwd).toBe('/work')
|
||||
})
|
||||
|
||||
it('只回了一段话、没交结构化结果:没有正文;Claude Code 报错、没给结果:抛错', async () => {
|
||||
const free = fakeClaude([{ lines: [result('我改好了。', 's1')] }])
|
||||
expect(await askCommentBody({ prompt: 'p', cwd: '/w', signal: new AbortController().signal, onEvent: () => {} }, free.deps)).toBeUndefined()
|
||||
const failing = fakeClaude([{ lines: [line({ type: 'result', is_error: true, result: '额度用完了' })] }])
|
||||
await expect(askCommentBody({ prompt: 'p', cwd: '/w', signal: new AbortController().signal, onEvent: () => {} }, failing.deps)).rejects.toThrow('额度用完了')
|
||||
const empty = fakeClaude([{ lines: [] }])
|
||||
await expect(askCommentBody({ prompt: 'p', cwd: '/w', signal: new AbortController().signal, onEvent: () => {} }, empty.deps)).rejects.toThrow('没给出结果')
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user