新增: 批次工作落地(推进链/评估闭环/事件总线/并发/加固) + 技术债清理 + 文档整理
后端: - 工作流推进链(D-03):advance_task/状态机/闸门走 df-nodes Node trait,conditions 条件引擎扩展 - 想法评估闭环:启发式评分+对抗评估,df-ideas/scoring + df-storage/idea_eval_repo + idea 前端打通 - 全局事件数据总线:df-ai/context+context_helpers+augmentation 跨模块解耦 - AI planner/plan_hint/intent:aichat B 路线并行多轮基础 - patch_file 加固(TD-03/04):读改写整体锁防 lost update,expected_hash 合约闭环 - 压缩超时兜底(F-15 卡死根治) - F-09 多会话并发:LlmConcurrency per-conv + streamingGuard 前端守护 + verify 脚本 - 知识注入 DRY/skills/audit 扩展 清理: - aichat 技术债(误报 allow/死导入/过时注释 30 项) - URGENT.md 删除(11 项加急全解决/迁 todo) - 文档整理(todo/待决策/待审查/ARCHITECTURE/INDEX + 总线/技术债审查新文档)
This commit is contained in:
@@ -57,6 +57,44 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- grep 结果:跨文件内容搜索(content/files_with_matches/count 三模式,F-260621)
|
||||
对齐 search_files 文件栏样式;content 模式按命中行渲染(文件:行:内容),支持 -C 上下文折叠 -->
|
||||
<div v-else-if="tc.name === 'grep' && tc.result && tc.status === 'completed' && parsed" class="ai-tool-grep-result">
|
||||
<div class="ai-tool-file-bar">
|
||||
<span class="ai-tool-file-icon" v-html="searchIcon"></span>
|
||||
<span class="ai-tool-file-path">{{ parsed?.path }}</span>
|
||||
<span v-if="parsed?.pattern" class="ai-tool-file-meta">「{{ parsed?.pattern }}」</span>
|
||||
<span class="ai-tool-file-meta">{{ grepHitLabel }}</span>
|
||||
<span v-if="parsed?.truncated" class="ai-tool-file-meta ai-tool-file-meta--warn">{{ $t('aiTool.grepTruncated') }}</span>
|
||||
</div>
|
||||
<!-- files_with_matches 模式:仅文件列表 -->
|
||||
<div v-if="parsed?.output_mode === 'files_with_matches'" class="ai-tool-dir-entries">
|
||||
<div v-for="(f, i) in parsed?.files" :key="i" class="ai-tool-dir-entry">
|
||||
<span class="ai-tool-dir-icon ai-tool-dir-icon--file" v-html="fileIcon"></span>
|
||||
<span class="ai-tool-dir-name">{{ f }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- count 模式:文件 + 命中行数 -->
|
||||
<div v-else-if="parsed?.output_mode === 'count'" class="ai-tool-dir-entries">
|
||||
<div v-for="(c, i) in parsed?.counts" :key="i" class="ai-tool-dir-entry">
|
||||
<span class="ai-tool-dir-icon ai-tool-dir-icon--file" v-html="fileIcon"></span>
|
||||
<span class="ai-tool-dir-name">{{ c.file }}</span>
|
||||
<span class="ai-tool-dir-size">{{ $t('aiTool.grepCountLines', { n: c.count }) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- content 模式:命中行(文件:行:内容),支持上下文折叠 -->
|
||||
<div v-else class="ai-tool-grep-matches">
|
||||
<div v-for="(m, i) in parsed?.matches" :key="i" class="ai-tool-grep-match">
|
||||
<div class="ai-tool-grep-match-head">
|
||||
<span class="ai-tool-grep-file">{{ m.file }}</span>
|
||||
<span v-if="m.line !== null && m.line !== undefined" class="ai-tool-grep-line">:{{ m.line }}</span>
|
||||
</div>
|
||||
<code class="ai-tool-grep-content">{{ m.content }}</code>
|
||||
<pre v-if="m.context" class="ai-tool-grep-context"><code>{{ m.context }}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- write_file 结果 -->
|
||||
<div v-else-if="tc.name === 'write_file' && tc.result && tc.status === 'completed' && parsed" class="ai-tool-write-result">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="var(--df-success)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 11-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
|
||||
@@ -142,8 +180,10 @@ import {
|
||||
formatSizeDiff,
|
||||
combineOutputs,
|
||||
formatToolResult,
|
||||
formatGrep,
|
||||
dirIcon,
|
||||
fileIcon,
|
||||
searchIcon,
|
||||
} from '@/composables/ai/useToolCard'
|
||||
import { parseDiffLines } from '@/composables/ai/useToolCardRender'
|
||||
import type { AiToolCallInfo } from '@/api/types'
|
||||
@@ -201,6 +241,16 @@ const cmdOutput = computed(() => {
|
||||
*/
|
||||
const resultDiffLines = computed(() => parseDiffLines(parsed.value?.diff, 120))
|
||||
|
||||
/**
|
||||
* grep 命中计数标签(F-260621):G-1 复用 useToolCard.formatGrep 单一函数,
|
||||
* 消除原与 ToolResultBody 重复的三分支(files_with_matches/count/content 文案)。
|
||||
* parsed 为 null 返空串,等价原逻辑;非 null 委托 formatGrep。
|
||||
*/
|
||||
const grepHitLabel = computed(() => {
|
||||
const r = parsed.value
|
||||
return r ? formatGrep(r) : ''
|
||||
})
|
||||
|
||||
// SW-260618-06: status 切到 completed 时按成功/失败初始化折叠态(失败默认展开便于看 stderr/错误 body)。
|
||||
// immediate 时若初始非 completed,两 ref 保持默认 false,无副作用。
|
||||
watch(() => props.tc.status, (s) => {
|
||||
@@ -266,6 +316,71 @@ watch(() => props.tc.status, (s) => {
|
||||
color: var(--df-text-dim);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.ai-tool-file-meta--warn {
|
||||
color: var(--df-warning);
|
||||
}
|
||||
|
||||
/* grep 结果(F-260621):文件栏复用 ai-tool-file-bar,命中行用等宽渲染 */
|
||||
.ai-tool-grep-result {
|
||||
border-top: 0.5px solid var(--df-border);
|
||||
}
|
||||
.ai-tool-grep-matches {
|
||||
padding: 4px 0;
|
||||
max-height: 260px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.ai-tool-grep-match {
|
||||
padding: 3px 12px;
|
||||
border-bottom: 0.5px solid rgba(255,255,255,0.03);
|
||||
}
|
||||
.ai-tool-grep-match:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.ai-tool-grep-match-head {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 1px;
|
||||
font-family: var(--df-font-mono);
|
||||
font-size: 10px;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
.ai-tool-grep-file {
|
||||
color: var(--df-accent);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.ai-tool-grep-line {
|
||||
color: var(--df-text-dim);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.ai-tool-grep-content {
|
||||
display: block;
|
||||
font-family: var(--df-font-mono);
|
||||
font-size: 11px;
|
||||
color: var(--df-text);
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
background: rgba(61,219,160,0.05);
|
||||
padding: 2px 6px;
|
||||
border-radius: var(--df-radius-xs, 3px);
|
||||
}
|
||||
.ai-tool-grep-context {
|
||||
margin: 2px 0 0;
|
||||
padding: 0;
|
||||
max-height: 120px;
|
||||
overflow: auto;
|
||||
font-family: var(--df-font-mono);
|
||||
font-size: 10px;
|
||||
color: var(--df-text-dim);
|
||||
background: rgba(255,255,255,0.02);
|
||||
border-radius: var(--df-radius-xs, 3px);
|
||||
}
|
||||
.ai-tool-grep-context code {
|
||||
display: block;
|
||||
padding: 4px 6px;
|
||||
white-space: pre;
|
||||
}
|
||||
.ai-tool-expand-btn {
|
||||
font-family: var(--df-font-sans);
|
||||
font-size: 10px;
|
||||
|
||||
Reference in New Issue
Block a user