fix: localize frontend status metadata

This commit is contained in:
Yoilun
2026-05-25 20:09:14 +08:00
parent 75e49c9552
commit 8463d43e2e
9 changed files with 59 additions and 38 deletions

View File

@@ -70,7 +70,7 @@ cd web
pnpm dev pnpm dev
``` ```
前端开发地址为 `http://127.0.0.1:13083/`。Phase 4 前端仅使用本地静态示例数据,页面文案会标明“示例数据”或“等待连接后端 API”Phase 5 才接入真实只读 API。 前端开发地址为 `http://127.0.0.1:13083/`。Phase 4 前端仅使用本地静态示例数据,页面文案会标明“示例数据”或“等待连接后端 API”Phase 5 才接入真实只读 API。前端可保留 `local_sample``api_missing` 等内部 source kind但用户界面必须显示中文来源和 `高 / 中 / 低` 置信度。
## Security Boundaries ## Security Boundaries

View File

@@ -18,6 +18,8 @@
| 2026-05-25 | 3 | coding agent | TDD 实现项目配置、运行线程和动态工作流只读模型 | 完成;新增 `/api/projects``/api/runtime/threads``/api/workflow/events` | | 2026-05-25 | 3 | coding agent | TDD 实现项目配置、运行线程和动态工作流只读模型 | 完成;新增 `/api/projects``/api/runtime/threads``/api/workflow/events` |
| 2026-05-25 | 3 | spec review | 规格审查未通过SQLite 依赖提升 Go 下限到 1.25;单侧 DB 缺失来源证据不足 | coding agent 按 blocking 范围修复 | | 2026-05-25 | 3 | spec review | 规格审查未通过SQLite 依赖提升 Go 下限到 1.25;单侧 DB 缺失来源证据不足 | coding agent 按 blocking 范围修复 |
| 2026-05-25 | 3 | quality review | 代码质量审查未通过SQLite schema drift 可导致 500、`partial` 置信度不在契约内、workflow nil Runtime panic | coding agent 按 blocking 范围修复 | | 2026-05-25 | 3 | quality review | 代码质量审查未通过SQLite schema drift 可导致 500、`partial` 置信度不在契约内、workflow nil Runtime panic | coding agent 按 blocking 范围修复 |
| 2026-05-25 | 4 | coding agent | 实现 Vue 中文只读工作台外壳 | 完成;提交 `feat: add chinese vue workbench shell` |
| 2026-05-25 | 4 | spec review | 规格审查未通过:状态徽标和部分视图直接展示 `local_sample``low` 等内部英文值 | 已修复为中文来源和置信度展示 |
| 2026-05-25 | 4 | coding agent | 创建 Vue 3 + Vite 中文只读前端工作台,包含五个 tabs、静态示例数据、来源/置信度和空状态 | 完成;未接入真实 API未提供写回入口 | | 2026-05-25 | 4 | coding agent | 创建 Vue 3 + Vite 中文只读前端工作台,包含五个 tabs、静态示例数据、来源/置信度和空状态 | 完成;未接入真实 API未提供写回入口 |
## Test Results ## Test Results
@@ -102,6 +104,8 @@
| 2026-05-25 | `curl -I http://127.0.0.1:13083/` | PASS | 本地前端返回 HTTP 200 | | 2026-05-25 | `curl -I http://127.0.0.1:13083/` | PASS | 本地前端返回 HTTP 200 |
| 2026-05-25 | Browser plugin check | DONE_WITH_CONCERNS | 内置浏览器返回 `Browser is not available: iab`,未完成视觉截图核验 | | 2026-05-25 | Browser plugin check | DONE_WITH_CONCERNS | 内置浏览器返回 `Browser is not available: iab`,未完成视觉截图核验 |
| 2026-05-25 | `git diff --check` | PASS | Phase 4 whitespace 检查通过 | | 2026-05-25 | `git diff --check` | PASS | Phase 4 whitespace 检查通过 |
| 2026-05-25 | `pnpm build` | PASS | Phase 4 规格修复后前端构建通过 |
| 2026-05-25 | `git diff --check` | PASS | Phase 4 规格修复 whitespace 检查通过 |
## Bug Loop ## Bug Loop
@@ -121,3 +125,4 @@
| 3 | SQLite schema drift、NULL 或数值字段可让 Snapshot 返回 error 并导致 API 500 | 使用 `PRAGMA table_info` 构造宽容 SELECT缺关键列返回空表和 `sqlite_schema_drift` 证据;可选列/NULL/数值字段转为空字符串或文本 | `go test ./internal/runtime` PASS | | 3 | SQLite schema drift、NULL 或数值字段可让 Snapshot 返回 error 并导致 API 500 | 使用 `PRAGMA table_info` 构造宽容 SELECT缺关键列返回空表和 `sqlite_schema_drift` 证据;可选列/NULL/数值字段转为空字符串或文本 | `go test ./internal/runtime` PASS |
| 3 | `SourceEvidence.Confidence` 出现设计外值 `partial` | 保留 `Kind: sqlite_partial`,将 `Confidence` 改为 `medium` | `go test ./internal/runtime ./internal/server` PASS | | 3 | `SourceEvidence.Confidence` 出现设计外值 `partial` | 保留 `Kind: sqlite_partial`,将 `Confidence` 改为 `medium` | `go test ./internal/runtime ./internal/server` PASS |
| 3 | `workflow.Store` 未配置 Runtime 会 panic | nil Runtime 返回空 view 和 `runtime_missing`/`low` 证据 | `go test ./internal/workflow` PASS | | 3 | `workflow.Store` 未配置 Runtime 会 panic | nil Runtime 返回空 view 和 `runtime_missing`/`low` 证据 | `go test ./internal/workflow` PASS |
| 4 | UI 直接展示 `local_sample``api_missing``low``medium` 等内部英文值 | `StatusBadge` 增加中文映射,并将示例数据来源/置信度改为中文展示值 | `pnpm build` PASS |

View File

@@ -34,3 +34,4 @@
| 2026-05-25 | 1 | 规格复审发现 `ResolveAgentTOML` 可通过 `agents/*.toml` symlink 指向 root `auth.json` 绕过 forbidden 检查 | TDD 补充 symlink-to-auth 测试后检查 resolved final target | 已通过最终验证 | | 2026-05-25 | 1 | 规格复审发现 `ResolveAgentTOML` 可通过 `agents/*.toml` symlink 指向 root `auth.json` 绕过 forbidden 检查 | TDD 补充 symlink-to-auth 测试后检查 resolved final target | 已通过最终验证 |
| 2026-05-25 | 2 | 规格审查发现重复键 TOML 被报告为 valid且 agent symlink 可读取 Codex home 内非 agent TOML | TDD 补充 duplicate key、invalid key、symlink-to-config 测试后修复 parser 和 agent store 边界 | 已通过最终验证 | | 2026-05-25 | 2 | 规格审查发现重复键 TOML 被报告为 valid且 agent symlink 可读取 Codex home 内非 agent TOML | TDD 补充 duplicate key、invalid key、symlink-to-config 测试后修复 parser 和 agent store 边界 | 已通过最终验证 |
| 2026-05-25 | 2 | 复审发现 `agents -> .` 目录 symlink 可把 root `config.toml` 当作 agent 读取 | TDD 补充 symlinked agents directory 测试后在 `Store.List` 拒绝 symlinked `agents` 目录 | 已通过最终验证 | | 2026-05-25 | 2 | 复审发现 `agents -> .` 目录 symlink 可把 root `config.toml` 当作 agent 读取 | TDD 补充 symlinked agents directory 测试后在 `Store.List` 拒绝 symlinked `agents` 目录 | 已通过最终验证 |
| 2026-05-25 | 4 | 规格审查发现 UI 直接展示 `local_sample``low` 等内部英文值 | 将状态徽标、示例数据和硬编码来源/置信度改为中文展示 | 待复审 |

View File

@@ -29,7 +29,7 @@ const activeComponent = computed(() => tabs.find((tab) => tab.id === activeTab.v
<p class="lede">中文前端壳已就位真实 API 接入将在 Phase 5 进行</p> <p class="lede">中文前端壳已就位真实 API 接入将在 Phase 5 进行</p>
</div> </div>
<div class="connection-card" aria-label="连接状态"> <div class="connection-card" aria-label="连接状态">
<StatusBadge label="未连接" status="unknown" confidence="low" source="local_sample" /> <StatusBadge label="未连接" status="unknown" confidence="" source="本地示例" />
<strong>{{ connection.label }}</strong> <strong>{{ connection.label }}</strong>
<span>{{ connection.detail }}</span> <span>{{ connection.detail }}</span>
</div> </div>

View File

@@ -1,16 +1,31 @@
<script setup> <script setup>
defineProps({ import { computed } from 'vue'
const sourceLabels = {
local_sample: '本地示例',
api_missing: '等待 API',
pending_api: '等待 API',
'task_plan.md': '计划文件',
low: '低',
medium: '中',
high: '高',
}
const props = defineProps({
label: { type: String, required: true }, label: { type: String, required: true },
status: { type: String, default: 'unknown' }, status: { type: String, default: 'unknown' },
confidence: { type: String, default: 'low' }, confidence: { type: String, default: '' },
source: { type: String, default: 'local_sample' }, source: { type: String, default: '本地示例' },
}) })
const sourceText = computed(() => sourceLabels[props.source] ?? props.source)
const confidenceText = computed(() => sourceLabels[props.confidence] ?? props.confidence)
</script> </script>
<template> <template>
<span class="status-badge" :data-status="status"> <span class="status-badge" :data-status="status">
<span class="status-dot" aria-hidden="true"></span> <span class="status-dot" aria-hidden="true"></span>
<span>{{ label }}</span> <span>{{ label }}</span>
<small>{{ source }} / {{ confidence }}</small> <small>{{ sourceText }} / {{ confidenceText }}</small>
</span> </span>
</template> </template>

View File

@@ -1,8 +1,8 @@
export const connection = { export const connection = {
label: '等待连接后端 API', label: '等待连接后端 API',
detail: 'Phase 4 仅展示只读工作台外壳;以下内容均为本地示例数据。', detail: 'Phase 4 仅展示只读工作台外壳;以下内容均为本地示例数据。',
source: 'local_sample', source: '本地示例',
confidence: 'low', confidence: '',
} }
export const projects = [ export const projects = [
@@ -18,7 +18,7 @@ export const projects = [
drafts: 1, drafts: 1,
lastActivity: '示例18:42', lastActivity: '示例18:42',
source: '示例数据', source: '示例数据',
confidence: 'low', confidence: '',
}, },
{ {
id: 'codex-home', id: 'codex-home',
@@ -32,7 +32,7 @@ export const projects = [
drafts: 0, drafts: 0,
lastActivity: '等待 API', lastActivity: '等待 API',
source: '未连接', source: '未连接',
confidence: 'low', confidence: '',
}, },
{ {
id: 'example', id: 'example',
@@ -46,7 +46,7 @@ export const projects = [
drafts: 0, drafts: 0,
lastActivity: '示例:昨天', lastActivity: '示例:昨天',
source: '示例数据', source: '示例数据',
confidence: 'low', confidence: '',
}, },
] ]
@@ -59,8 +59,8 @@ export const agentMatrix = [
statusZh: '最近活跃', statusZh: '最近活跃',
goal: 'Phase 4 前端工作台', goal: 'Phase 4 前端工作台',
process: '等待进程表', process: '等待进程表',
source: 'local_sample', source: '本地示例',
confidence: 'low', confidence: '',
lastActivity: '示例18:42', lastActivity: '示例18:42',
}, },
{ {
@@ -71,8 +71,8 @@ export const agentMatrix = [
statusZh: '运行中', statusZh: '运行中',
goal: '搭建中文工作台', goal: '搭建中文工作台',
process: '等待 API 连接', process: '等待 API 连接',
source: 'local_sample', source: '本地示例',
confidence: 'low', confidence: '',
lastActivity: '示例:刚刚', lastActivity: '示例:刚刚',
}, },
{ {
@@ -83,28 +83,28 @@ export const agentMatrix = [
statusZh: '未知', statusZh: '未知',
goal: '等待阶段 5 数据', goal: '等待阶段 5 数据',
process: '未连接', process: '未连接',
source: 'api_missing', source: '等待 API',
confidence: 'low', confidence: '',
lastActivity: '等待连接', lastActivity: '等待连接',
}, },
] ]
export const workflow = { export const workflow = {
phases: [ phases: [
{ name: 'Phase 0-3', status: 'complete', label: '已完成', gate: 'Go 后端只读模型', evidence: 'task_plan.md / progress.md', confidence: 'medium' }, { name: 'Phase 0-3', status: 'complete', label: '已完成', gate: 'Go 后端只读模型', evidence: 'task_plan.md / progress.md', confidence: '' },
{ name: 'Phase 4', status: 'running', label: '进行中', gate: '中文只读前端工作台', evidence: '本地示例视图', confidence: 'low' }, { name: 'Phase 4', status: 'running', label: '进行中', gate: '中文只读前端工作台', evidence: '本地示例视图', confidence: '' },
{ name: 'Phase 5', status: 'pending', label: '未开始', gate: '连接只读 API', evidence: '等待后续阶段', confidence: 'low' }, { name: 'Phase 5', status: 'pending', label: '未开始', gate: '连接只读 API', evidence: '等待后续阶段', confidence: '' },
{ name: 'Phase 6', status: 'pending', label: '未开始', gate: '草稿校验与写回', evidence: '当前禁用写回', confidence: 'low' }, { name: 'Phase 6', status: 'pending', label: '未开始', gate: '草稿校验与写回', evidence: '当前禁用写回', confidence: '' },
], ],
handoffs: [ handoffs: [
{ from: '主智能体', to: '前端实现智能体', summary: '派发 Phase 4构建只读工作台外壳', time: '示例18:45', source: 'local_sample', confidence: 'low' }, { from: '主智能体', to: '前端实现智能体', summary: '派发 Phase 4构建只读工作台外壳', time: '示例18:45', source: '本地示例', confidence: '' },
{ from: '前端实现智能体', to: '审查智能体', summary: '等待构建和界面验证证据', time: '等待连接', source: 'pending_api', confidence: 'low' }, { from: '前端实现智能体', to: '审查智能体', summary: '等待构建和界面验证证据', time: '等待连接', source: '等待 API', confidence: '' },
{ from: '审查智能体', to: '主智能体', summary: '阶段 5 才接入真实 API 和错误态', time: '计划中', source: 'task_plan.md', confidence: 'medium' }, { from: '审查智能体', to: '主智能体', summary: '阶段 5 才接入真实 API 和错误态', time: '计划中', source: '计划文件', confidence: '' },
], ],
edges: [ edges: [
{ parent: '主线程', child: '前端实现', status: '示例运行', source: 'local_sample', confidence: 'low' }, { parent: '主线程', child: '前端实现', status: '示例运行', source: '本地示例', confidence: '' },
{ parent: '前端实现', child: '界面审查', status: '等待', source: 'pending_api', confidence: 'low' }, { parent: '前端实现', child: '界面审查', status: '等待', source: '等待 API', confidence: '' },
{ parent: '界面审查', child: '修复回路', status: '未开始', source: 'task_plan.md', confidence: 'medium' }, { parent: '界面审查', child: '修复回路', status: '未开始', source: '计划文件', confidence: '' },
], ],
} }
@@ -116,8 +116,8 @@ export const agents = [
description: '实现现代 Web 应用、响应式界面和无障碍体验。', description: '实现现代 Web 应用、响应式界面和无障碍体验。',
role: 'Vue / Vite / CSS / 可访问性', role: 'Vue / Vite / CSS / 可访问性',
status: '示例草稿', status: '示例草稿',
source: 'local_sample', source: '本地示例',
confidence: 'low', confidence: '',
toml: '[agent]\nname = "前端开发者"\ndescription = "实现现代 Web 应用"\nmode = "readonly-preview"', toml: '[agent]\nname = "前端开发者"\ndescription = "实现现代 Web 应用"\nmode = "readonly-preview"',
}, },
{ {
@@ -127,8 +127,8 @@ export const agents = [
description: '优先发现行为回归、安全边界和遗漏测试。', description: '优先发现行为回归、安全边界和遗漏测试。',
role: '审查 / 风险 / 验证', role: '审查 / 风险 / 验证',
status: '等待读取', status: '等待读取',
source: 'api_missing', source: '等待 API',
confidence: 'low', confidence: '',
toml: '# 等待 Phase 5 从 /api/agents 读取真实 TOML', toml: '# 等待 Phase 5 从 /api/agents 读取真实 TOML',
}, },
] ]
@@ -139,8 +139,8 @@ export const drafts = [
changedFields: ['描述', '角色设定'], changedFields: ['描述', '角色设定'],
validation: '示例:未校验', validation: '示例:未校验',
backup: '等待 Phase 6', backup: '等待 Phase 6',
source: 'local_sample', source: '本地示例',
confidence: 'low', confidence: '',
steps: ['草稿'], steps: ['草稿'],
}, },
{ {
@@ -148,8 +148,8 @@ export const drafts = [
changedFields: [], changedFields: [],
validation: '无草稿', validation: '无草稿',
backup: '无', backup: '无',
source: 'api_missing', source: '等待 API',
confidence: 'low', confidence: '',
steps: [], steps: [],
}, },
] ]

View File

@@ -71,7 +71,7 @@ import { agentMatrix, projects } from '../data'
<p class="eyebrow">详情</p> <p class="eyebrow">详情</p>
<h2>前端实现智能体</h2> <h2>前端实现智能体</h2>
</div> </div>
<StatusBadge label="运行中" status="running" source="local_sample" confidence="low" /> <StatusBadge label="运行中" status="running" source="本地示例" confidence="" />
<div class="detail-block"> <div class="detail-block">
<h3>角色摘要</h3> <h3>角色摘要</h3>
<p>负责 Vue 3 + Vite 只读工作台中文界面移动响应式布局和空数据状态</p> <p>负责 Vue 3 + Vite 只读工作台中文界面移动响应式布局和空数据状态</p>

View File

@@ -11,7 +11,7 @@ import { settings } from '../data'
<p class="eyebrow">设置</p> <p class="eyebrow">设置</p>
<h2>只读配置摘要</h2> <h2>只读配置摘要</h2>
</div> </div>
<StatusBadge label="等待 API" status="unknown" source="local_sample" confidence="low" /> <StatusBadge label="等待 API" status="unknown" source="本地示例" confidence="" />
</div> </div>
<div class="settings-list"> <div class="settings-list">

View File

@@ -49,7 +49,7 @@ import { workflow } from '../data'
<p class="eyebrow">监管</p> <p class="eyebrow">监管</p>
<h2> agent 监管状态</h2> <h2> agent 监管状态</h2>
</div> </div>
<StatusBadge label="最近活跃" status="recent" source="local_sample" confidence="low" /> <StatusBadge label="最近活跃" status="recent" source="本地示例" confidence="" />
<dl class="detail-grid"> <dl class="detail-grid">
<span>当前门禁</span><strong>Phase 4 构建通过</strong> <span>当前门禁</span><strong>Phase 4 构建通过</strong>
<span>计划文件</span><strong>已存在</strong> <span>计划文件</span><strong>已存在</strong>