mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-18 13:23:33 +08:00
桌面端的工作区文件面板现在可以把文件或局部评论加入聊天,发送给 CLI 的内容保持为原生 @文件路径引用,聊天界面则保留用户可读的文件 chip。为了让本轮变更卡片和 checkpoint 回滚继续可靠,UI 消息会同时保存用于展示的内容和实际发给模型的 modelContent;历史转录里的 @文件路径也会在重载时还原成附件 chip。 Constraint: CLI 侧最稳定的文件上下文入口仍是原生 @文件路径 Constraint: 聊天 UI 不能把绝对路径裸露成用户消息正文 Rejected: 只发送隐藏提示文本 | CLI 对 @文件路径已有稳定读取行为 Rejected: 只依赖前端展示内容做回滚校验 | 会和真实转录内容不一致 Confidence: high Scope-risk: moderate Directive: 修改附件展示或回滚校验时必须同时验证 modelContent 与 UI content 的分离 Tested: cd desktop && bun run test -- src/stores/chatStore.test.ts src/components/chat/MessageList.test.tsx src/stores/workspaceChatContextStore.test.ts src/components/workspace/WorkspacePanel.test.tsx Tested: cd desktop && bun run lint Tested: cd desktop && bun run build Tested: SKIP_INSTALL=1 ./desktop/scripts/build-macos-arm64.sh Tested: codesign --verify --deep --strict --verbose=2 desktop/build-artifacts/macos-arm64/Claude\ Code\ Haha.app Tested: hdiutil verify desktop/build-artifacts/macos-arm64/Claude\ Code\ Haha_0.1.8_aarch64.dmg Tested: Computer Use macOS run with /private/tmp/cc-haha-computer-use-e2e verified file chip, @path model input, model sentinel response, workspace preview interactions Not-tested: Deep unloaded-folder fuzzy search in all-files view
70 lines
1.9 KiB
TypeScript
70 lines
1.9 KiB
TypeScript
import { beforeEach, describe, expect, it } from 'vitest'
|
|
import {
|
|
formatWorkspaceReferencePrompt,
|
|
useWorkspaceChatContextStore,
|
|
} from './workspaceChatContextStore'
|
|
|
|
const initialState = useWorkspaceChatContextStore.getInitialState()
|
|
|
|
describe('workspaceChatContextStore', () => {
|
|
beforeEach(() => {
|
|
useWorkspaceChatContextStore.setState(initialState, true)
|
|
})
|
|
|
|
it('deduplicates file references per session', () => {
|
|
const store = useWorkspaceChatContextStore.getState()
|
|
|
|
store.addReference('session-1', {
|
|
kind: 'file',
|
|
path: 'src/App.tsx',
|
|
absolutePath: '/repo/src/App.tsx',
|
|
name: 'App.tsx',
|
|
})
|
|
store.addReference('session-1', {
|
|
kind: 'file',
|
|
path: 'src/App.tsx',
|
|
absolutePath: '/repo/src/App.tsx',
|
|
name: 'App.tsx',
|
|
})
|
|
|
|
expect(useWorkspaceChatContextStore.getState().referencesBySession['session-1']).toHaveLength(1)
|
|
})
|
|
|
|
it('formats line comments into the request prompt', () => {
|
|
const prompt = formatWorkspaceReferencePrompt([
|
|
{
|
|
id: 'ref-1',
|
|
kind: 'code-comment',
|
|
path: 'src/App.tsx',
|
|
absolutePath: '/repo/src/App.tsx',
|
|
name: 'App.tsx',
|
|
lineStart: 12,
|
|
lineEnd: 12,
|
|
note: 'Use a clearer name',
|
|
quote: 'const value = 1',
|
|
},
|
|
])
|
|
|
|
expect(prompt).toContain('Notes for attached workspace files:')
|
|
expect(prompt).toContain('- src/App.tsx:L12')
|
|
expect(prompt).toContain('Comment: Use a clearer name')
|
|
expect(prompt).toContain('Selected code: const value = 1')
|
|
expect(prompt).not.toContain('Use the Read tool')
|
|
expect(prompt).not.toContain('Path: /repo/src/App.tsx')
|
|
})
|
|
|
|
it('does not add prompt text for plain file attachments', () => {
|
|
const prompt = formatWorkspaceReferencePrompt([
|
|
{
|
|
id: 'ref-1',
|
|
kind: 'file',
|
|
path: 'src/App.tsx',
|
|
absolutePath: '/repo/src/App.tsx',
|
|
name: 'App.tsx',
|
|
},
|
|
])
|
|
|
|
expect(prompt).toBe('')
|
|
})
|
|
})
|