feat(client): drop the collapsed file row's error dot
Failures now surface only on the expanded op rows. The collapsed row's aggregate tally added little on its own (its edit ops already flag the failing tool call), so FileEntry.errs — which existed only for that dot — and the files.errs strings go with it; each op keeps its own err flag for the expanded dots.
This commit is contained in:
1 parent
abce91a6a6
commit
a3f572244b
7 files changed
+7
-16
No files matched your search
@@ -319,7 +319,6 @@ export function makeFileCard(kit: ViewKit, settings: ContextSettings): Component
|
||||
<span className="lc-fa-badge lc-fa-b-search" title={t('files.kind.search')}><i />{fmt(e.searches)}</span>
|
||||
) : null}
|
||||
{e.added + e.removed > 0 ? <DeltaPair added={e.added} removed={e.removed} /> : null}
|
||||
{e.errs > 0 ? <span className="lc-br-err-dot" title={t('files.errs', { n: e.errs })} /> : null}
|
||||
{e.ops[0].time !== undefined
|
||||
? <span className="lc-fa-time">{fmtTime(e.ops[0].time)}</span>
|
||||
: null}
|
||||
|
||||
@@ -28,7 +28,6 @@ export interface FileEntry {
|
||||
searches: number
|
||||
added: number
|
||||
removed: number
|
||||
errs: number
|
||||
ops: FileOp[]
|
||||
/** Set when `path` is a pathless search's PATTERN, not a file path — display must not relativize it. */
|
||||
pattern?: true
|
||||
@@ -243,7 +242,6 @@ function aggregateOps(ops: readonly FileOp[], before: number | null): FileActivi
|
||||
searches: 0,
|
||||
added: 0,
|
||||
removed: 0,
|
||||
errs: 0,
|
||||
ops: [],
|
||||
...(op.pattern === true ? { pattern: true as const } : {}),
|
||||
}
|
||||
@@ -254,7 +252,6 @@ function aggregateOps(ops: readonly FileOp[], before: number | null): FileActivi
|
||||
else entry.searches++
|
||||
entry.added += op.added
|
||||
entry.removed += op.removed
|
||||
if (op.err) entry.errs++
|
||||
entry.ops.push(op)
|
||||
}
|
||||
const entries = [...byPath.values()]
|
||||
|
||||
@@ -173,7 +173,6 @@ export const DICT_EN = {
|
||||
'files.open': 'Open on your system',
|
||||
'files.preview': 'Preview in the sidebar',
|
||||
'files.readEst': 'Lines read, estimated from the limit argument',
|
||||
'files.errs': '{n} failed',
|
||||
'files.form.image': 'Image',
|
||||
'files.form.dir': 'Directory',
|
||||
'files.form.text': 'File',
|
||||
|
||||
@@ -171,7 +171,6 @@ export const DICT_ZH = {
|
||||
'files.open': '在系统中打开',
|
||||
'files.preview': '在侧边栏预览',
|
||||
'files.readEst': '按调用参数 limit 估算的读取行数',
|
||||
'files.errs': '{n} 次失败',
|
||||
'files.form.image': '图片',
|
||||
'files.form.dir': '目录',
|
||||
'files.form.text': '文件',
|
||||
|
||||
@@ -18,7 +18,7 @@ function fileOp(seq: number, kind: FileOp['kind'], tool: string, over: Partial<F
|
||||
}
|
||||
|
||||
function entry(path: string, over: Partial<FileEntry>): FileEntry {
|
||||
return { path, form: 'text', reads: 0, writes: 0, searches: 0, added: 0, removed: 0, errs: 0, ops: [], ...over }
|
||||
return { path, form: 'text', reads: 0, writes: 0, searches: 0, added: 0, removed: 0, ops: [], ...over }
|
||||
}
|
||||
|
||||
function richActivity(over: Partial<FileActivity> = {}): FileActivity {
|
||||
@@ -29,7 +29,6 @@ function richActivity(over: Partial<FileActivity> = {}): FileActivity {
|
||||
writes: 2,
|
||||
added: 2,
|
||||
removed: 3,
|
||||
errs: 1,
|
||||
ops: [
|
||||
fileOp(7, 'read', 'read'),
|
||||
fileOp(5, 'write', 'edit', { added: 2, removed: 1 }),
|
||||
@@ -129,7 +128,8 @@ describe('FileCard — header, rows, and filters', () => {
|
||||
assert.ok(aRow.querySelector('.lc-fa-path b')?.textContent === 'a.ts')
|
||||
assert.equal(queryAll(aRow, '.lc-fa-badge').length, 2) // read + write
|
||||
assert.ok(text(aRow).includes('+2') && text(aRow).includes('−3'))
|
||||
assert.ok(aRow.querySelector('.lc-br-err-dot') !== null)
|
||||
// Failures surface on the expanded op rows only: the collapsed row keeps no error dot.
|
||||
assert.equal(queryAll(aRow, '.lc-br-err-dot').length, 0)
|
||||
assert.ok(aRow.title === '/src/a.ts')
|
||||
const dirRow = rows.find(r => r.title === '/src/')
|
||||
assert.ok(dirRow !== undefined)
|
||||
|
||||
@@ -75,7 +75,7 @@ afterAll(() => {
|
||||
|
||||
function entry(index: number): FileEntry {
|
||||
const op: FileOp = { seq: index, kind: 'read', tool: 'read', time: T0 + index, err: false, added: 0, removed: 0, path: '' }
|
||||
return { path: `/src/file-${String(index).padStart(3, '0')}.ts`, form: 'text', reads: 1, writes: 0, searches: 0, added: 0, removed: 0, errs: 0, ops: [op] }
|
||||
return { path: `/src/file-${String(index).padStart(3, '0')}.ts`, form: 'text', reads: 1, writes: 0, searches: 0, added: 0, removed: 0, ops: [op] }
|
||||
}
|
||||
|
||||
function activityOf(count: number): FileActivity {
|
||||
|
||||
@@ -108,7 +108,6 @@ describe('activityOf', () => {
|
||||
assert.equal(file.searches, 0)
|
||||
assert.equal(file.added, 2) // edit new_string: 'x\nq'
|
||||
assert.equal(file.removed, 3) // edit old_string: 'x\ny\nz'
|
||||
assert.equal(file.errs, 0)
|
||||
// Ops newest first inside the entry.
|
||||
assert.deepEqual(file.ops.map(o => o.seq), [7, 5, 3])
|
||||
assert.equal(file.ops[0].kind, 'read')
|
||||
@@ -148,16 +147,14 @@ describe('activityOf', () => {
|
||||
assert.deepEqual(a.totals.image, { files: 2, ops: 2 })
|
||||
})
|
||||
|
||||
test('counts failures from the fold stamp or the snapshot error flag', () => {
|
||||
test('stamps the error flag from the fold or the snapshot', () => {
|
||||
const a = run([
|
||||
op(3, 'read', { file_path: '/a.ts' }, { err: true }),
|
||||
op(5, 'read', { file_path: '/a.ts' }, {}, { isError: true }),
|
||||
op(7, 'read', { file_path: '/b.ts' }),
|
||||
])
|
||||
const file = a.entries[1]
|
||||
assert.equal(file.errs, 2)
|
||||
assert.equal(file.ops[0].err, true)
|
||||
assert.equal(a.entries[0].errs, 0)
|
||||
assert.deepEqual(a.entries[1].ops.map(o => o.err), [true, true])
|
||||
assert.equal(a.entries[0].ops[0].err, false)
|
||||
})
|
||||
|
||||
test('carries the archive removal stamp onto the op for locate targeting', () => {
|
||||
|
||||
Reference in new issue
Block a user