✨ 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
@@ -1,14 +1,14 @@
|
||||
import { renderToStaticMarkup } from 'react-dom/server'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { BlockTools } from './BlockTools'
|
||||
import { BlockTools, RewriteButton } from './BlockTools'
|
||||
|
||||
function render(editing: boolean, ask?: { asking: boolean }, rewrite?: { rewriting: boolean }): string {
|
||||
function render(editing: boolean, ask?: { asking: boolean }, rewrite?: { rewriting: boolean, fresh?: boolean }): string {
|
||||
return renderToStaticMarkup(
|
||||
<BlockTools
|
||||
editing={editing}
|
||||
onToggleEdit={() => {}}
|
||||
{...(ask && { asking: ask.asking, onToggleAsk: () => {} })}
|
||||
{...(rewrite && { rewriting: rewrite.rewriting, onRewrite: () => {} })}
|
||||
{...(rewrite && { rewrite: { rewriting: rewrite.rewriting, fresh: rewrite.fresh ?? false, onRewrite: () => {} } })}
|
||||
/>,
|
||||
)
|
||||
}
|
||||
@@ -54,4 +54,12 @@ describe('块右上角的图标按钮', () => {
|
||||
expect(busy).toContain('aria-busy="true"')
|
||||
expect(busy).not.toContain('cr-qa-spin')
|
||||
})
|
||||
|
||||
it('块还没有注释时按钮叫「按注释规范写注释」;「注释」一行上的按钮是同一个,只有图标', () => {
|
||||
const fresh = render(false, undefined, { rewriting: false, fresh: true })
|
||||
expect(fresh).toContain('data-tooltip="按注释规范写注释" aria-label="按注释规范写注释"')
|
||||
const onRow = renderToStaticMarkup(<RewriteButton tool={{ rewriting: false, fresh: false, onRewrite: () => {} }} />)
|
||||
expect(onRow).toMatch(/^<button[^>]*data-tooltip="按注释规范重写" aria-label="按注释规范重写"[^>]*><svg/)
|
||||
expect(visibleText(onRow)).toBe('')
|
||||
})
|
||||
})
|
||||
@@ -1,41 +1,55 @@
|
||||
import type { ReactElement } from 'react'
|
||||
import { Eye, MessageSquareText, Pencil, Sparkles } from 'lucide-react'
|
||||
|
||||
/** 「重写注释」按钮的样子和动作:fresh 是块还没有注释、点了新写一段;正在重写时不能再点。 */
|
||||
export interface RewriteTool {
|
||||
fresh: boolean
|
||||
rewriting: boolean
|
||||
onRewrite: () => void
|
||||
}
|
||||
|
||||
/**
|
||||
* 「按注释规范重写」:用写注释的技能重写这块代码的注释并写回文件(块还没有注释时是「按注释规范写注释」,新写一段);正在重写时不能再点。
|
||||
* 只有图标(注释),名字在悬停提示和 aria-label 里。卡片有「注释」一行时画在那一行上,没有时排在右上角那排按钮里。
|
||||
*/
|
||||
export function RewriteButton({ tool }: { tool: RewriteTool }): ReactElement {
|
||||
const label = tool.fresh ? '按注释规范写注释' : '按注释规范重写'
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="cr-tool flex h-5 w-6 shrink-0 items-center justify-center rounded"
|
||||
data-tooltip={label}
|
||||
aria-label={label}
|
||||
aria-busy={tool.rewriting}
|
||||
disabled={tool.rewriting}
|
||||
onClick={tool.onRewrite}
|
||||
>
|
||||
<MessageSquareText size={14} strokeWidth={1.8} aria-hidden />
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 块右上角的一排图标按钮(普通块、属性表、库规则的卡片共用):只放图标,名字写在悬停提示(data-tooltip)和读屏用的 aria-label 里。
|
||||
* 「按注释规范重写」:只给注释块。点了用写注释的技能重写这一段并写回文件;正在重写时不能再点。图标是注释。
|
||||
* 「按注释规范重写」(见 RewriteButton):卡片没有「注释」一行时排在这里。
|
||||
* 「问 AI」:点开 / 收起块下面的问答区,展开时带按下的底色。
|
||||
* 「编辑 / 预览」切换:预览时是铅笔「编辑」,编辑时是眼睛「预览」、带按下的底色。
|
||||
*/
|
||||
export function BlockTools({ editing, onToggleEdit, asking, onToggleAsk, rewriting, onRewrite }: {
|
||||
export function BlockTools({ editing, onToggleEdit, asking, onToggleAsk, rewrite }: {
|
||||
editing: boolean
|
||||
onToggleEdit: () => void
|
||||
/** 块下面的问答区展开着 */
|
||||
asking?: boolean
|
||||
/** 没给就不显示「问 AI」(文件不在工作区文件夹里,问答没地方存) */
|
||||
onToggleAsk?: () => void
|
||||
/** 这段注释正在重写 */
|
||||
rewriting?: boolean
|
||||
/** 没给就不显示「按注释规范重写」(不是注释块) */
|
||||
onRewrite?: () => void
|
||||
/** 没给就不显示「按注释规范重写」(不能写注释,或按钮画在「注释」一行上) */
|
||||
rewrite?: RewriteTool
|
||||
}): ReactElement {
|
||||
const label = editing ? '预览' : '编辑'
|
||||
const Icon = editing ? Eye : Pencil
|
||||
return (
|
||||
<div className="flex h-5 shrink-0 items-center gap-0.5" role="group" aria-label="块操作">
|
||||
{onRewrite && (
|
||||
<button
|
||||
type="button"
|
||||
className="cr-tool flex h-5 w-6 items-center justify-center rounded"
|
||||
data-tooltip="按注释规范重写"
|
||||
aria-label="按注释规范重写"
|
||||
aria-busy={rewriting === true}
|
||||
disabled={rewriting === true}
|
||||
onClick={onRewrite}
|
||||
>
|
||||
<MessageSquareText size={14} strokeWidth={1.8} aria-hidden />
|
||||
</button>
|
||||
)}
|
||||
{rewrite && <RewriteButton tool={rewrite} />}
|
||||
{onToggleAsk && (
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@@ -32,7 +32,7 @@ function view(id: string, kind: string, text: string, extra: Partial<BlockView>
|
||||
} as BlockView
|
||||
}
|
||||
|
||||
/** 一张卡片:第 1 行的两个子行各挂一张子卡片,后面还有一个留下的注释块。 */
|
||||
/** 一张卡片:第 1 行的两个子行各挂一张子卡片,后面还有一块留下的语句。 */
|
||||
const CARD: BlockView = {
|
||||
...view('0', 'demo.card', ''),
|
||||
badge: BADGE,
|
||||
@@ -46,13 +46,12 @@ const CARD: BlockView = {
|
||||
children: [
|
||||
view('0.0', 'demo.method', '启动服务', { slot: { row: 1, item: 0 }, badge: { ...BADGE, label: '方法', icon: 'square-function' } }),
|
||||
view('0.1', 'demo.method', '停止服务', { slot: { row: 1, item: 1 }, badge: { ...BADGE, label: '方法', icon: 'square-function' } }),
|
||||
view('0.2', 'comment', '留下的注释'),
|
||||
view('0.2', 'statement', '留下的语句'),
|
||||
],
|
||||
}
|
||||
|
||||
function render(folds: Record<string, boolean>): string {
|
||||
const collapsed = collapsedIds([CARD], folds)
|
||||
const tree: BlockTreeState = {
|
||||
function state(collapsed: ReadonlySet<string>): BlockTreeState {
|
||||
return {
|
||||
edit: {
|
||||
version: 1,
|
||||
editing: new Set(),
|
||||
@@ -72,7 +71,10 @@ function render(folds: Record<string, boolean>): string {
|
||||
onSetFolds: () => {},
|
||||
onOpenRun: () => {},
|
||||
}
|
||||
return renderToStaticMarkup(<BlockLevel blocks={[CARD]} tree={tree} />)
|
||||
}
|
||||
|
||||
function render(folds: Record<string, boolean>): string {
|
||||
return renderToStaticMarkup(<BlockLevel blocks={[CARD]} tree={state(collapsedIds([CARD], folds))} />)
|
||||
}
|
||||
|
||||
describe('挂在卡片子行上的子块', () => {
|
||||
@@ -80,7 +82,7 @@ describe('挂在卡片子行上的子块', () => {
|
||||
const html = render({})
|
||||
expect(html).not.toContain('启动服务')
|
||||
expect(html).not.toContain('停止服务')
|
||||
expect(html).not.toContain('留下的注释')
|
||||
expect(html).not.toContain('留下的语句')
|
||||
expect(html).toContain('<button type="button" class="cr-item-toggle" aria-expanded="false" aria-label="展开start">')
|
||||
})
|
||||
|
||||
@@ -90,7 +92,7 @@ describe('挂在卡片子行上的子块', () => {
|
||||
expect(html).not.toContain('停止服务')
|
||||
expect(html).toContain('data-open="" data-badge="" style="--kind-dark:#61dafb;--kind-light:#0a7ea4"')
|
||||
expect(html).toContain('aria-label="收起"')
|
||||
expect(html).toContain('留下的注释')
|
||||
expect(html).toContain('留下的语句')
|
||||
// 子卡片画在「方法」那一行后面
|
||||
expect(html.indexOf('启动服务')).toBeGreaterThan(html.indexOf('方法</button>'))
|
||||
})
|
||||
@@ -105,3 +107,33 @@ describe('挂在卡片子行上的子块', () => {
|
||||
expect(render({ '0.0': false, '0': false }).match(/data-owner="0"/g)).toHaveLength(2)
|
||||
})
|
||||
})
|
||||
|
||||
describe('「注释」一行和「重写注释」按钮', () => {
|
||||
const comment = { label: '注释', value: { markdown: '按名字找' } }
|
||||
const html = (block: BlockView): string => renderToStaticMarkup(<BlockLevel blocks={[block]} tree={state(new Set())} />)
|
||||
/** 「注释」那一行(cr-prop-row)里的 HTML */
|
||||
const commentRowHtml = (markup: string): string => markup.split('cr-prop-row').find(part => part.includes('按名字找')) ?? ''
|
||||
|
||||
it('属性表卡片:「注释」一行照属性表画,按钮画在这一行上,右上角那排不再有', () => {
|
||||
const card = view('1', 'function', '', {
|
||||
properties: [{ label: '名称', value: [{ text: 'find', role: 'function' }] }, comment, { label: '异步', value: [{ text: '否', role: 'storage' }] }],
|
||||
commentRow: 1,
|
||||
commentTarget: { kind: 'replace', startLine: 0, endLine: 0 },
|
||||
})
|
||||
const markup = html(card)
|
||||
expect(commentRowHtml(markup)).toContain('aria-label="按注释规范重写"')
|
||||
expect(markup.match(/aria-label="按注释规范重写"/g)).toHaveLength(1)
|
||||
expect(markup.indexOf('按名字找')).toBeLessThan(markup.indexOf('异步'))
|
||||
})
|
||||
|
||||
it('一行译文的卡片:「注释」一行排在译文下面,按钮同样在这一行上', () => {
|
||||
const markup = html(view('2', 'statement', 'save()', { rows: [comment], commentRow: 0, commentTarget: { kind: 'replace', startLine: 0, endLine: 0 } }))
|
||||
expect(markup.indexOf('save()')).toBeLessThan(markup.indexOf('按名字找'))
|
||||
expect(commentRowHtml(markup)).toContain('aria-label="按注释规范重写"')
|
||||
})
|
||||
|
||||
it('还没有注释的块:按钮在右上角那排,叫「按注释规范写注释」;不能写注释的块没有按钮', () => {
|
||||
expect(html(view('3', 'statement', 'save()', { commentTarget: { kind: 'insert', line: 0 } }))).toMatch(/role="group" aria-label="块操作"><button[^>]*aria-label="按注释规范写注释"/)
|
||||
expect(html(view('4', 'statement', 'save()'))).not.toContain('按注释规范')
|
||||
})
|
||||
})
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { CSSProperties, ReactElement, ReactNode } from 'react'
|
||||
import type { RewriteTool } from './BlockTools'
|
||||
import type { DiffTree, FoldedRuns, PlacedRemoved } from './diffView'
|
||||
import type { GridSlots } from './PropertyGrid'
|
||||
import type { QaState } from './qa'
|
||||
@@ -8,7 +9,7 @@ import type { BlockMarks, BlockView } from './types'
|
||||
import { ChevronDown, ChevronRight, ChevronsUpDown, EyeOff } from 'lucide-react'
|
||||
import { Fragment, useState } from 'react'
|
||||
import { AskThread, RewriteThread } from './AskThread'
|
||||
import { BlockTools } from './BlockTools'
|
||||
import { BlockTools, RewriteButton } from './BlockTools'
|
||||
import { CodeEditor } from './CodeEditor'
|
||||
import { DiffText } from './DiffText'
|
||||
import { removedTitle } from './diffView'
|
||||
@@ -202,11 +203,13 @@ function BlockRewrite({ anchor, edit }: { anchor: string, edit: EditTree }): Rea
|
||||
|
||||
/**
|
||||
* 预览状态的内容:函数、类、枚举、导入、常量、变量块和库规则的卡片是属性表,其余是一行译文;
|
||||
* 译文下面依次接着摊开实参的表(跨几行写的调用)、说明。标差异时 marks 是这块自己的内容改了哪些(页面上正是差异算的那一版才给)。
|
||||
* 译文下面依次接着摊开实参的表(跨几行写的调用)、说明、几行属性(「注释」一行)。标差异时 marks 是这块自己的内容改了哪些(页面上正是差异算的那一版才给)。
|
||||
* rewrite 是「重写注释」按钮,画在「注释」一行上(commentRow);只读的块树(定义卡片浮窗)、删掉的块没有。
|
||||
*/
|
||||
function BlockPreview({ block, tree, marks }: { block: BlockView, tree: BlockTreeState, marks?: BlockMarks }): ReactElement {
|
||||
function BlockPreview({ block, tree, marks, rewrite }: { block: BlockView, tree: BlockTreeState, marks?: BlockMarks, rewrite?: RewriteTool }): ReactElement {
|
||||
const rowTools = rewrite && block.commentRow !== undefined ? new Map([[block.commentRow, <RewriteButton key="rewrite" tool={rewrite} />]]) : undefined
|
||||
if ('properties' in block)
|
||||
return <PropertyGrid blockId={block.id} rows={block.properties} collapsed={tree.collapsed} onToggleFold={tree.onToggleFold} marks={marks?.rows} slots={cardSlots(block, tree)} />
|
||||
return <PropertyGrid blockId={block.id} rows={block.properties} collapsed={tree.collapsed} onToggleFold={tree.onToggleFold} marks={marks?.rows} slots={cardSlots(block, tree)} rowTools={rowTools} />
|
||||
return (
|
||||
<>
|
||||
{marks?.translation ? <DiffText diff={marks.translation} /> : <TextPreview text={block.translation} />}
|
||||
@@ -216,10 +219,26 @@ function BlockPreview({ block, tree, marks }: { block: BlockView, tree: BlockTre
|
||||
</div>
|
||||
)}
|
||||
{marks?.doc ? <DiffText diff={marks.doc} className="mt-0.5" /> : block.doc && <TextPreview text={block.doc} className="mt-0.5" />}
|
||||
{block.rows && (
|
||||
<div className="mt-[3px]">
|
||||
<PropertyGrid blockId={block.id} rows={block.rows} collapsed={tree.collapsed} onToggleFold={tree.onToggleFold} marks={marks?.rows} rowTools={rowTools} />
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
/** 这块的「重写注释」按钮:能写注释(commentTarget)、页面上能改代码时才有。 */
|
||||
function rewriteTool(block: BlockView, edit: EditTree | undefined): RewriteTool | undefined {
|
||||
if (!edit || !block.commentTarget)
|
||||
return undefined
|
||||
return {
|
||||
fresh: block.commentTarget.kind === 'insert',
|
||||
rewriting: edit.rewrites.get(block.anchor)?.status === 'running',
|
||||
onRewrite: () => edit.onRewriteComment(block.anchor),
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 挂在卡片子行上的子块(BlockSlot)怎么画:一行下面展开着的几块画成一层块(同块树);点那个子行的第一格展开它、
|
||||
* 同一行里别的收起,展开着的再点收起。卡片没有挂在子行上的子块时没有。
|
||||
@@ -252,6 +271,7 @@ function BlockCard({ block, tree }: { block: BlockView, tree: BlockTreeState }):
|
||||
const hasChildren = toggled || hasShownChildren(block, tree)
|
||||
const Chevron = collapsed && !toggled ? ChevronRight : ChevronDown
|
||||
const change = tree.diff?.changes.get(block.id)
|
||||
const rewrite = rewriteTool(block, edit)
|
||||
return (
|
||||
<div
|
||||
className="cr-block relative flex items-start gap-2.5 rounded-lg py-2 pr-2.5 pl-2"
|
||||
@@ -287,7 +307,7 @@ function BlockCard({ block, tree }: { block: BlockView, tree: BlockTreeState }):
|
||||
onExit={() => edit.onToggleEdit(block.id)}
|
||||
/>
|
||||
)
|
||||
: <BlockPreview block={block} tree={tree} marks={tree.diff?.current ? change?.marks : undefined} />}
|
||||
: <BlockPreview block={block} tree={tree} marks={tree.diff?.current ? change?.marks : undefined} rewrite={rewrite} />}
|
||||
</div>
|
||||
{tree.temporary.has(block.id) && (
|
||||
<span className="cr-temporary flex h-5 shrink-0 items-center gap-1 rounded px-1.5 text-[11px] whitespace-nowrap">
|
||||
@@ -301,8 +321,7 @@ function BlockCard({ block, tree }: { block: BlockView, tree: BlockTreeState }):
|
||||
onToggleEdit={() => edit.onToggleEdit(block.id)}
|
||||
asking={tree.qa?.state.open.includes(block.anchor)}
|
||||
onToggleAsk={tree.qa && (() => tree.qa?.onToggle(block.anchor))}
|
||||
rewriting={edit.rewrites.get(block.anchor)?.status === 'running'}
|
||||
onRewrite={block.commentStartLine !== undefined ? () => edit.onRewriteComment(block.anchor) : undefined}
|
||||
{...(rewrite && block.commentRow === undefined && { rewrite })}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -252,7 +252,7 @@ export function PropertyTable({ parentId, columns, items, marks, toggles }: {
|
||||
* 给了列名的(输入参数、数据表的字段)排成表格,没给的排成列表。
|
||||
* 标差异时(marks)新加的行淡绿底、左边 +,删掉的行放回原来的位置、淡红底划掉、左边 −,值改了的按旧值 → 新值或逐词标。
|
||||
*/
|
||||
export function PropertyGrid({ blockId, rows, collapsed, onToggleFold, marks, slots }: {
|
||||
export function PropertyGrid({ blockId, rows, collapsed, onToggleFold, marks, slots, rowTools }: {
|
||||
blockId: string
|
||||
rows: PropertyRow[]
|
||||
collapsed: ReadonlySet<string>
|
||||
@@ -261,6 +261,8 @@ export function PropertyGrid({ blockId, rows, collapsed, onToggleFold, marks, sl
|
||||
marks?: RowsDiff
|
||||
/** 挂在这张属性表子行上的子块(库规则的卡片),见 GridSlots */
|
||||
slots?: GridSlots
|
||||
/** 排在某一行值右边的按钮(「注释」一行的「重写注释」),按行的下标 */
|
||||
rowTools?: ReadonlyMap<number, ReactNode>
|
||||
}): ReactElement {
|
||||
const removed = (after: number): ReactElement[] => removedAt(marks?.removed, after)
|
||||
.map(({ value, index }) => <RemovedRow key={`removed-${index}`} id={`${blockId}/x${index}`} row={value} />)
|
||||
@@ -296,7 +298,14 @@ export function PropertyGrid({ blockId, rows, collapsed, onToggleFold, marks, sl
|
||||
</button>
|
||||
)
|
||||
: <span className="cr-prop-label flex h-5 items-center">{row.label}</span>}
|
||||
<RowValue row={row} mark={mark} />
|
||||
{rowTools?.has(index)
|
||||
? (
|
||||
<div className="flex min-w-0 items-start gap-1">
|
||||
<div className="min-w-0 flex-1"><RowValue row={row} mark={mark} /></div>
|
||||
{rowTools.get(index)}
|
||||
</div>
|
||||
)
|
||||
: <RowValue row={row} mark={mark} />}
|
||||
</div>
|
||||
{!folded && layout === 'table' && <PropertyTable parentId={id} columns={row.columns ?? []} items={row.items ?? []} marks={mark?.items} toggles={toggles} />}
|
||||
{!folded && layout === 'list' && <PropertyItems parentId={id} items={row.items ?? []} folding={{ collapsed, onToggleFold }} marks={mark?.items} />}
|
||||
|
||||
@@ -143,9 +143,10 @@ interface BlockViewBase {
|
||||
attributes: Record<string, string>
|
||||
/** 这块认出来的概念,从左到右。webview 按图标名画,不自己用种类查 */
|
||||
concepts: BlockConcept[]
|
||||
/** 能重写的那段注释的起止行。注释块是整块;函数、类等是它的说明。没有就不显示重写按钮。 */
|
||||
commentStartLine?: number
|
||||
commentEndLine?: number
|
||||
/** 「注释」一行(讲这块的普通注释)排在第几行,0 起:属性表卡片是 properties 里的下标,一行译文的卡片是 rows 里的下标。「重写注释」按钮画在这一行上 */
|
||||
commentRow?: number
|
||||
/** 「重写注释」写到哪(扩展端用,这边只看有没有、是换掉还是新写);没有就不显示按钮 */
|
||||
commentTarget?: CommentTarget
|
||||
/** 库规则的卡片才有:卡片边框的颜色,筛选栏里这个种类的名字。和类块一样默认收起子块 */
|
||||
badge?: KindBadge
|
||||
/** 库规则挂在父卡片子行上的子块才有:展开时画在父卡片属性表第 row 行下面,不排在父卡片的子块里;见 BlockSlot */
|
||||
@@ -163,10 +164,18 @@ export interface BlockSlot {
|
||||
}
|
||||
|
||||
/**
|
||||
* 函数、类、枚举、导入、常量、变量块和库规则的卡片预览时是属性表,注释块是 Markdown 说明,其余是一行译文;
|
||||
* 一行译文下面依次是:跨几行写的调用摊开各个实参的表(table),块的说明(doc,Markdown 原文)
|
||||
* 「重写注释」写到哪,行号 0 起:replace 换掉 startLine..endLine 这几行(块前面的普通注释;文件开头的说明卡片是它自己),
|
||||
* insert 是块还没有注释,新写一段插在 line 这一行上面
|
||||
*/
|
||||
export type BlockView = BlockViewBase & ({ translation: PreviewText, table?: PreviewTable, doc?: Markdown } | { properties: PropertyRow[] })
|
||||
export type CommentTarget
|
||||
= | { kind: 'replace', startLine: number, endLine: number }
|
||||
| { kind: 'insert', line: number }
|
||||
|
||||
/**
|
||||
* 函数、类、枚举、导入、常量、变量块和库规则的卡片预览时是属性表,文件开头的说明是 Markdown,其余是一行译文;
|
||||
* 一行译文下面依次是:跨几行写的调用摊开各个实参的表(table),块的说明(doc,Markdown 原文),几行属性(rows:「注释」一行)
|
||||
*/
|
||||
export type BlockView = BlockViewBase & ({ translation: PreviewText, table?: PreviewTable, doc?: Markdown, rows?: PropertyRow[] } | { properties: PropertyRow[] })
|
||||
|
||||
export interface TranslatorOption { id: string, label: string }
|
||||
|
||||
@@ -360,7 +369,7 @@ export interface RowDiff {
|
||||
items?: ItemsDiff
|
||||
}
|
||||
|
||||
/** 一块自己的内容(不算子块)改了哪些:属性表逐行,一行译文逐截,摊开实参的表逐行,说明逐词 */
|
||||
/** 一块自己的内容(不算子块)改了哪些:属性表(一行译文的卡片是下面那几行 rows)逐行,一行译文逐截,摊开实参的表逐行,说明逐词 */
|
||||
export interface BlockMarks {
|
||||
rows?: RowsDiff
|
||||
translation?: TextDiff
|
||||
@@ -429,7 +438,7 @@ export interface StickyScrollSettings {
|
||||
* askProfiles:「问 AI」的 profile 下拉;ready 后来一次,任何一个预览改了都会来
|
||||
* answer:askId 那个问题的回答长了(text 是到现在为止的全文)、或换了在做的事
|
||||
* answerEnd:askId 那个问题答完了,见 AnswerEnd
|
||||
* rewriteProgress:anchor 这段注释正在按规范重写。question 是发给模型的要求,text 是到现在为止的全文,activity 是正在读什么
|
||||
* rewriteProgress:anchor 那块的注释正在按规范重写。question 是发给模型的那一句(技能命令和块在哪),text 是注释正文到现在为止写出来的,activity 是正在读什么
|
||||
* rewriteEnd:这段重写结束了。done 是正文已经写进文件;failed 带给人看的原因,文件没改;stopped 是被叫停,文件没改
|
||||
* moveOccurrence:跳到高亮着的名字的下一处(step 1)/ 上一处(step -1)出现
|
||||
* displayNames:version 这份文档里显示成中文名的名字,查到一步来一步;不是页面上这个版本的不理
|
||||
@@ -476,7 +485,7 @@ export type ExtensionToWebview
|
||||
* setOnlyChanges:打开 / 关掉「只看改动」;同样等扩展端发回 filter 再按它显示
|
||||
* ask:问 anchor 那块代码;askId 由这边起,回答的消息带回来;扩展端接着这块最近一次问答的会话问,用眼下选的 profile;
|
||||
* images 是贴进输入框的图片(没贴是空的),随问题发给 Claude Code,答成了跟这条一起存
|
||||
* rewriteComment:按注释规范重写 anchor 这段注释。过程用 rewriteProgress / rewriteEnd 回来,不写入问答
|
||||
* rewriteComment:按注释规范重写 anchor 那块的注释(还没有就新写一段)。过程用 rewriteProgress / rewriteEnd 回来,不写入问答
|
||||
* stopRewrite:叫停 anchor 这段正在进行的重写,不写文件
|
||||
* stopAsk:叫停 askId 那个问题,这次不存
|
||||
* deleteQa:删掉 anchor 那块下面的一次问答(已经理解了)
|
||||
|
||||
Reference in new issue
Block a user