Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/desktop/src/__tests__/attachment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ describe('attachment utils', () => {
});

it('extracts filename from windows path', () => {
expect(pathBasename('C:\\Users\\file.ts')).toBe('file.ts');
expect(pathBasename('C:\\Users\\Example\\file.ts')).toBe('file.ts');
});

it('returns input when no separator', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe('UserMessage rendering', () => {
it('renders user markdown tables through the shared markdown renderer', () => {
const item: TranscriptUserItem = {
type: 'user',
name: 'Ding',
name: 'Alice',
text: '| Scope | Status |\n| --- | --- |\n| Desktop/Web | aligned |',
};

Expand All @@ -27,7 +27,7 @@ describe('UserMessage rendering', () => {
it('renders Hub message display metadata on user input cards', () => {
const item: TranscriptUserItem = {
type: 'user',
name: 'Ding',
name: 'Alice',
text: '@Reviewer 帮我复核这个改动',
displayTitle: 'Group @Agent',
displayDetail: 'IM project_group · mentions @Reviewer · task task-reviewer-1',
Expand All @@ -50,7 +50,7 @@ describe('UserMessage rendering', () => {
const item: TranscriptUserItem = {
type: 'user',
id: 'hub-message-1',
name: 'Ding',
name: 'Alice',
text: '来自 Hub 的消息',
};
const onContextMenu = vi.fn();
Expand Down Expand Up @@ -121,7 +121,7 @@ describe('UserMessage attachments (#1957)', () => {
it('renders an image attachment thumbnail through the shared platform port', async () => {
unregister = registerAttachmentImageUrlResolver(async () => 'blob:user-upload');
const item: TranscriptUserItem = {
type: 'user', id: 'u1', name: 'Ding', text: '', attachments: [imageRow()],
type: 'user', id: 'u1', name: 'Alice', text: '', attachments: [imageRow()],
};

const { container } = render(<UserMessage item={item} chatMode="dm" />);
Expand All @@ -146,7 +146,7 @@ describe('UserMessage attachments (#1957)', () => {
it('degrades to the chip notice when no surface registered a resolver', async () => {
expect(getAttachmentImageUrlResolver()).toBeUndefined();
const item: TranscriptUserItem = {
type: 'user', id: 'u1', name: 'Ding', text: '', attachments: [imageRow()],
type: 'user', id: 'u1', name: 'Alice', text: '', attachments: [imageRow()],
};

render(<UserMessage item={item} chatMode="dm" />);
Expand All @@ -159,7 +159,7 @@ describe('UserMessage attachments (#1957)', () => {
it('renders non-image attachments as file chips without touching the port', () => {
expect(getAttachmentImageUrlResolver()).toBeUndefined();
const item: TranscriptUserItem = {
type: 'user', id: 'u1', name: 'Ding', text: '', attachments: [fileRow()],
type: 'user', id: 'u1', name: 'Alice', text: '', attachments: [fileRow()],
};

const { container } = render(<UserMessage item={item} chatMode="group" />);
Expand All @@ -173,7 +173,7 @@ describe('UserMessage attachments (#1957)', () => {
it('renders text and attachments together when both are present', async () => {
unregister = registerAttachmentImageUrlResolver(async () => 'blob:user-upload');
const item: TranscriptUserItem = {
type: 'user', id: 'u1', name: 'Ding', text: 'here is the screenshot',
type: 'user', id: 'u1', name: 'Alice', text: 'here is the screenshot',
attachments: [imageRow()],
};

Expand Down
2 changes: 1 addition & 1 deletion app/workbench/src/__tests__/inspector.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ describe('AgentHubWorkbench', () => {
{
id: 'user-subtask-prompt',
kind: 'text',
author: { id: 'user', name: 'Ding', role: 'human' },
author: { id: 'user', name: 'Alice', role: 'human' },
text: '继续修复聊天流。',
},
{
Expand Down
4 changes: 2 additions & 2 deletions app/workbench/src/workbenchRoutesHelpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,13 +343,13 @@ describe('buildSettingsPageProps', () => {
const props = buildSettingsPageProps({
settingsRoute,
onOpenAgentConfig,
userDisplayName: 'Ding',
userDisplayName: 'Alice',
});

expect(props.theme).toBe('dark');
expect(props.spaceTitle).toBe('AgentHub Desktop');
expect(props.spaceMeta).toBe('桌面设计 demo');
expect(props.currentUserDisplayName).toBe('Ding');
expect(props.currentUserDisplayName).toBe('Alice');
expect(props.onOpenAgentConfig).toBe(onOpenAgentConfig);
expect(Object.prototype.hasOwnProperty.call(props, 'onRetrySettingsLoad')).toBe(false);
expect(Object.prototype.hasOwnProperty.call(props, 'onDismissSettingsError')).toBe(false);
Expand Down
6 changes: 3 additions & 3 deletions app/workbench/src/workbenchTasksRouteHelpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,13 +324,13 @@ describe('workbenchTasksRouteHandlers — selection plans and chrome', () => {
it('handleAssignSelectedTaskToMe patches the assignee to the acting user', () => {
const { state, build } = createTasksHarness(
{ selectedTaskId: 't1' },
{ currentUserId: 'ding', userDisplayName: 'Ding' },
{ currentUserId: 'alice', userDisplayName: 'Alice' },
);

build().handleAssignSelectedTaskToMe();

expect(state.taskGroups[0]?.tasks.find((task) => task.id === 't1')?.assignee).toBe('Ding');
expect(state.taskActionLabel).toContain('已指派给 Ding');
expect(state.taskGroups[0]?.tasks.find((task) => task.id === 't1')?.assignee).toBe('Alice');
expect(state.taskActionLabel).toContain('已指派给 Alice');
});

it('handleGroupBySelectedTaskProject switches to the project-grouped list view', () => {
Expand Down
2 changes: 1 addition & 1 deletion docs/component-acceptance/ui-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

### 表单组件族:Input / Switch(#1827;Select 验收并入本段)

迁移背景(动机):19 个文件裸 `<input>/<textarea>`、error 态各自手写;AuthPage `.input` desktop/web 双份分叉(web 带边框 10px radius、desktop 无边框 10px radius,同约定不同值);SettingsPage 自造 `.switch`。#1827 建族 6 原语,实际仅 Input(web/desktop AuthPage)与 Switch(workbench SettingSwitch)被采用;FormField/Textarea/Checkbox/Radio 四原语始终零消费,已于 round-42 删除(#2154 候选 A)。产品面仍有约 22 处裸 `<input>` + 1 处裸 `<textarea>`(workbench/web 若干弹层),登记为 adoption debt(#2154 跟踪)。error 态统一约定为 **语义(`aria-invalid` + `aria-describedby` 接线)与 token(`--td-danger`)**。组件三件套齐全(`.test.tsx` + `.stories.tsx` + 本表)。
迁移背景(动机):19 个文件裸 `<input>/<textarea>`、error 态各自手写;AuthPage `.input` desktop/web 双份分叉(web 带边框 10px radius、desktop 无边框 10px radius,同约定不同值);SettingsPage 自造 `.switch`。#1827 建族 6 原语,实际仅 Input(web/desktop AuthPage)与 Switch(workbench SettingSwitch)被采用;FormField/Textarea/Checkbox/Radio 四原语始终零消费,已删除(#2154 候选 A)。产品面仍有约 22 处裸 `<input>` + 1 处裸 `<textarea>`(workbench/web 若干弹层),登记为 adoption debt(#2154 跟踪)。error 态统一约定为 **语义(`aria-invalid` + `aria-describedby` 接线)与 token(`--td-danger`)**。组件三件套齐全(`.test.tsx` + `.stories.tsx` + 本表)。

| 组件 | 维度 | 必选项 | 状态 | 备注 |
|---|---|---|---|---|
Expand Down
4 changes: 2 additions & 2 deletions docs/governance/known-flaky.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ Go 车道 job ID 分工(登记「车道」字段时按此写,勿再写聚合

| 日期 | 动作 | 结果 |
|---|---|---|
| 2026-09-01 | round-31 `make fe-test` 全量跑偶发红(5s 超时);单文件重跑 15/15 绿 | 当日登记;同 PR 提高超时并全量复跑验证 |
| 2026-09-01 | `make fe-test` 全量跑偶发红(5s 超时);单文件重跑 15/15 绿 | 当日登记;同 PR 提高超时并全量复跑验证 |

### FLK-004 desktop App.v4 渲染用例全量并行负载下偶发超时

Expand All @@ -158,7 +158,7 @@ Go 车道 job ID 分工(登记「车道」字段时按此写,勿再写聚合

| 日期 | 动作 | 结果 |
|---|---|---|
| 2026-09-01 | round-34 desktop 全量跑偶发红(唯一失败项);单文件重跑 14/14 绿 | 当日登记;同 PR 提高超时并全量复跑验证 |
| 2026-09-01 | desktop 全量跑偶发红(唯一失败项);单文件重跑 14/14 绿 | 当日登记;同 PR 提高超时并全量复跑验证 |

## 维护规则

Expand Down
2 changes: 1 addition & 1 deletion docs/governance/verifier-map.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
| Design token SSOT(CSS 硬编码颜色禁令) | `scripts/verify/verify-design-token-ssot.py` | checks.yml → validate |
| 核心 token/theme/preset CSS 仅 parser 语法门禁(fail-closed;Stylelint 被 ignore 排除,规则债另立,#1720) | `app/scripts/verify-design-css-syntax.mjs`(内置 `--self-test` 负向自测) | checks.yml → design-css |
| shared UI i18n callsite ratchet(#1612;违规文件数棘轮:仅当含 CJK 字面量且未导入 `useTranslation` 的违规文件数超过 baseline 时 fail,不比较字面量行数——既有违规文件内新增 CJK 字面量行不会触发;当前 advisory:validate step 带 `continue-on-error`,存量违规文件回填低于 baseline 后转硬门禁) | `scripts/verify/verify-i18n-callsites.py` | checks.yml → validate |
| zh 术语收敛棘轮(#2154 round-38;zh i18n 定义面禁用「对话」,豁免「对话框」;硬编码残留与数据域由清理轮分治) | `scripts/verify/verify-i18n-terminology.py` | checks.yml → validate |
| zh 术语收敛棘轮(#2154;zh i18n 定义面禁用「对话」,豁免「对话框」;硬编码残留与数据域由清理轮分治) | `scripts/verify/verify-i18n-terminology.py` | checks.yml → validate |
| shared 组件三件套棘轮(#1951:扫描 `app/shared/src/ui/**` 的 PascalCase 组件 `.tsx`;必须配对 `<组件>.test.tsx`(或 `__tests__/<组件>.test.tsx`)+ `<组件>.stories.tsx`,无关测试不得代替;验收标准见 `docs/component-acceptance.md`;存量缺件显式登记在基线、只缩不增) | `scripts/verify/verify-shared-trio-ratchet.py`(负向自测 `scripts/verify/tests/verify-shared-trio-ratchet.Tests.py`,基线 `scripts/verify/shared-trio-baseline.json`) | checks.yml → validate |
| 演示诚实:stub/fixture 不得冒充真实登录/API | `scripts/verify/verify-real-e2e-contract.py` | checks.yml → validate |
| 真实 E2E lane evidence manifest 六字段合同 + 私有信息脱敏(#1839/#1873:非 loopback URL host / 内网 IP / 绝对路径 / 内网后缀 hostname fail-closed;L3 仅 dispatch,不阻塞 PR) | `scripts/verify/verify-real-e2e-lane-manifest.py`(负向自测 `scripts/verify/tests/verify-real-e2e-lane-manifest.Tests.py`) | checks.yml → real-e2e-stack(自测 → validate) |
Expand Down
4 changes: 2 additions & 2 deletions edge-server/internal/adapters/claude/claude_acp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ func TestCLIInvocationPlanRedactsPromptEnvAndPaths(t *testing.T) {
AgentID: "claude-code",
Model: "sonnet",
PermissionMode: "plan",
WorkDir: "C:\\Users\\Ding\\private\\workspace",
WorkDir: "C:\\Users\\Example\\private\\workspace",
})

if plan.AdapterID != "claude-code" {
Expand All @@ -445,7 +445,7 @@ func TestCLIInvocationPlanRedactsPromptEnvAndPaths(t *testing.T) {
if err != nil {
t.Fatalf("marshal invocation plan payload: %v", err)
}
if strings.Contains(string(encoded), "SECRET_PROMPT_SHOULD_NOT_APPEAR") || strings.Contains(string(encoded), "C:\\Users\\Ding") {
if strings.Contains(string(encoded), "SECRET_PROMPT_SHOULD_NOT_APPEAR") || strings.Contains(string(encoded), "C:\\Users\\Example") {
t.Fatalf("invocation plan leaked prompt or absolute path:\n%s", encoded)
}
if !strings.Contains(string(encoded), `"--permission-mode"`) || !strings.Contains(string(encoded), `"--model"`) {
Expand Down
4 changes: 2 additions & 2 deletions edge-server/internal/adapters/sdk/runtime_manifest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func TestRuntimeManifestAdapterFixtureFileContract(t *testing.T) {
t.Fatalf("capability metadata = %#v", health["capabilities"])
}

cmdPath, args, env, workDir := adapter.BuildCommand(RunProcessContext{Prompt: "secret prompt", WorkDir: "C:\\Users\\Ding\\private\\workspace"})
cmdPath, args, env, workDir := adapter.BuildCommand(RunProcessContext{Prompt: "secret prompt", WorkDir: "C:\\Users\\Example\\private\\workspace"})
currentExecutable, err := os.Executable()
if err != nil {
t.Fatalf("os.Executable: %v", err)
Expand All @@ -132,7 +132,7 @@ func TestRuntimeManifestAdapterFixtureFileContract(t *testing.T) {
if len(env) != 0 {
t.Fatalf("fixture-file env = %#v, want no manifest env exposure", env)
}
if workDir != "C:\\Users\\Ding\\private\\workspace" {
if workDir != "C:\\Users\\Example\\private\\workspace" {
t.Fatalf("workDir = %q", workDir)
}

Expand Down
40 changes: 20 additions & 20 deletions edge-server/internal/adapters/sdk/sdk_fixture_mapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ func TestSDKFixtureMapperKeepsOutputWorkspaceRelativeAndRedacted(t *testing.T) {
ToolName: "Write",
ToolUseID: "toolu_secret",
Input: map[string]any{
"file_path": "C:\\Users\\Ding\\server\\secret.env",
"file_path": "C:\\Users\\Example\\server\\secret.env",
"api_key": "sk-live-secret",
"nested": map[string]any{"authorization": "Bearer secret", "path": "../outside.txt"},
"safe_value": "kept",
Expand All @@ -414,7 +414,7 @@ func TestSDKFixtureMapperKeepsOutputWorkspaceRelativeAndRedacted(t *testing.T) {
{
ID: "artifact_secret_path",
Type: "artifact",
Path: "/home/ding/private/report.md",
Path: "/home/example/private/report.md",
},
},
}
Expand Down Expand Up @@ -463,7 +463,7 @@ func TestSDKFixtureMapperProviderNeutralReplayContract(t *testing.T) {
ConfigKeys: []string{"approval.mode"},
PositionalArgCount: 1,
EnvNames: []string{"AGENTHUB_TOKEN=secret-value", "OPENAI_API_KEY=sk-not-real"},
WorkDir: "C:\\Users\\Ding\\private\\workspace",
WorkDir: "C:\\Users\\Example\\private\\workspace",
PromptRedacted: true,
ExecutionMode: "fixture",
},
Expand Down Expand Up @@ -530,7 +530,7 @@ func TestSDKFixtureMapperProviderNeutralReplayContract(t *testing.T) {
ID: "contract_error_1",
Type: "error",
SessionID: "session_contract",
Error: "fixture runtime failed after redacted path C:\\Users\\Ding\\secret.txt",
Error: "fixture runtime failed after redacted path C:\\Users\\Example\\secret.txt",
Reason: "adapter_error",
},
{
Expand Down Expand Up @@ -604,7 +604,7 @@ func TestSDKFixtureMapperProviderNeutralReplayContract(t *testing.T) {
}

hubReplay := marshalSDKFixtureJSON(t, mapSDKEventsForHubReplay(mapped))
for _, leaked := range []string{"secret-token", "secret-value", "sk-not-real", "C:\\Users\\Ding", "D:\\Projects\\ExampleAgentHub"} {
for _, leaked := range []string{"secret-token", "secret-value", "sk-not-real", "C:\\Users\\Example", "D:\\Projects\\ExampleAgentHub"} {
if strings.Contains(hubReplay, leaked) {
t.Fatalf("Hub replay contract leaked %q:\n%s", leaked, hubReplay)
}
Expand All @@ -618,7 +618,7 @@ func TestSDKFixtureMapperRedactsFreeTextBeforeReplay(t *testing.T) {
{
ID: "free_text_progress",
Type: "progress",
Description: "reading C:\\Users\\Ding\\secrets\\trace.txt with Authorization: Bearer bearer-secret-123456",
Description: "reading C:\\Users\\Example\\secrets\\trace.txt with Authorization: Bearer bearer-secret-123456",
Summary: "system_prompt: dump private trace body",
Reason: "api_key=sk-progress-secret-123456",
},
Expand All @@ -632,14 +632,14 @@ func TestSDKFixtureMapperRedactsFreeTextBeforeReplay(t *testing.T) {
"command": "curl -H \"Authorization: Bearer command-secret-123456\" https://example.test && echo sk-command-secret-123456",
"note": "trace_body={\"prompt\":\"read D:\\Private\\prompt.txt\"}",
},
Output: "wrote /home/ding/private/result.txt using sk-output-secret-123456",
Output: "wrote /home/example/private/result.txt using sk-output-secret-123456",
Error: "ignored error with Authorization: Bearer output-bearer-secret",
Metadata: map[string]any{
"traceBody": "prompt: include C:\\Users\\Ding\\private\\raw-prompt.md",
"traceBody": "prompt: include C:\\Users\\Example\\private\\raw-prompt.md",
},
Attachments: []map[string]any{
{
"path": "C:\\Users\\Ding\\private\\attachment.json",
"path": "C:\\Users\\Example\\private\\attachment.json",
"summary": "token=attachment-secret-123456",
},
},
Expand All @@ -650,7 +650,7 @@ func TestSDKFixtureMapperRedactsFreeTextBeforeReplay(t *testing.T) {
CallID: "call_error_text",
ToolName: "bash",
Status: "error",
Error: "tool error leaked sk-error-secret-123456 at C:\\Users\\Ding\\error.log",
Error: "tool error leaked sk-error-secret-123456 at C:\\Users\\Example\\error.log",
},
{
ID: "free_text_direct_result",
Expand All @@ -660,14 +660,14 @@ func TestSDKFixtureMapperRedactsFreeTextBeforeReplay(t *testing.T) {
Output: "direct result leaked sk-direct-secret-123456 and /var/private/direct.txt",
Attachments: []map[string]any{{"path": "/tmp/private/direct-attachment.txt", "note": "Authorization: Bearer direct-attach-secret"}},
Metadata: map[string]any{
"promptLike": "system_prompt=show C:\\Users\\Ding\\direct.env",
"promptLike": "system_prompt=show C:\\Users\\Example\\direct.env",
},
},
{
ID: "free_text_file",
Type: "file_change",
Path: "D:\\Projects\\ExampleAgentHub\\secret.env",
Diff: "+ OPENAI_API_KEY=sk-diff-secret-123456\n+ Authorization: Bearer diff-bearer-secret\n+ path=C:\\Users\\Ding\\secret.env",
Diff: "+ OPENAI_API_KEY=sk-diff-secret-123456\n+ Authorization: Bearer diff-bearer-secret\n+ path=C:\\Users\\Example\\secret.env",
Summary: "private_key=-----BEGIN PRIVATE KEY-----",
Reason: "prompt=copy /Users/example/private/prompt.md",
},
Expand All @@ -676,7 +676,7 @@ func TestSDKFixtureMapperRedactsFreeTextBeforeReplay(t *testing.T) {
Type: "terminal_result",
Success: boolPtr(false),
Reason: "provider_timeout_with_sk-terminal-secret-123456",
Summary: "failed after reading C:\\Users\\Ding\\terminal-secret.txt",
Summary: "failed after reading C:\\Users\\Example\\terminal-secret.txt",
},
},
}
Expand All @@ -700,10 +700,10 @@ func TestSDKFixtureMapperRedactsFreeTextBeforeReplay(t *testing.T) {
"-----BEGIN PRIVATE KEY-----",
"dump private trace body",
"raw-prompt.md",
"C:\\Users\\Ding",
"C:\\Users\\Example",
"D:\\Private",
"D:\\Projects\\ExampleAgentHub",
"/home/ding/private",
"/home/example/private",
"/var/private",
"/Users/example/private",
} {
Expand Down Expand Up @@ -739,10 +739,10 @@ func TestSDKFixtureMapperRedactsTopLevelRefsAndPreservesSanitizedTerminalReason(
ID: "ref_terminal",
Type: "terminal_result",
Success: boolPtr(false),
TraceID: "trace-C:\\Users\\Ding\\private\\trace.json-sk-traceid-secret-123456",
TraceRefs: []string{"trace:/home/ding/private/span.json", "trace:Authorization: Bearer trace-ref-secret-123456"},
TraceID: "trace-C:\\Users\\Example\\private\\trace.json-sk-traceid-secret-123456",
TraceRefs: []string{"trace:/home/example/private/span.json", "trace:Authorization: Bearer trace-ref-secret-123456"},
EvidenceRefs: []string{
"artifact:C:\\Users\\Ding\\private\\evidence.json",
"artifact:C:\\Users\\Example\\private\\evidence.json",
"event:sk-evidence-secret-123456",
},
Reason: "provider_timeout sk-reason-secret-123456 at D:\\Private\\reason.txt",
Expand Down Expand Up @@ -770,9 +770,9 @@ func TestSDKFixtureMapperRedactsTopLevelRefsAndPreservesSanitizedTerminalReason(
"trace-ref-secret-123456",
"sk-evidence-secret-123456",
"sk-reason-secret-123456",
"C:\\Users\\Ding",
"C:\\Users\\Example",
"D:\\Private",
"/home/ding/private",
"/home/example/private",
} {
if strings.Contains(replay, leaked) {
t.Fatalf("top-level refs or reason leaked %q:\n%s", leaked, replay)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/agenthub/edge-server/internal/permission"
)

// Ownership slice for the human approval gates (#2241 round-64 lane A):
// Ownership slice for the human approval gates (#2241 lane A):
//
// POST /v1/permissions/decide — allow/deny a live tool call of a run
// POST /v1/plans/decide — approve/reject an orchestrator plan of a run
Expand Down
2 changes: 1 addition & 1 deletion edge-server/internal/api/handlers_node_config_gate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/agenthub/edge-server/internal/store"
)

// Node-level shared configuration write gate (#2250 round-65 wave lane A):
// Node-level shared configuration write gate (#2250 wave lane A):
//
// POST /v1/agent-profiles — create an agent profile
// PATCH /v1/agent-profiles/{profileId} — mutate systemPrompt/allowedTools/mcpConfig/permissionMode
Expand Down
Loading
Loading