✨ feat(vscode): 代码阅读「了解一块代码」改成按路径列调用树:结果是几条路径(用户的一种操作一条),每条从入口一路调到后端服务、数据表,跨进程的写明怎么连过去(via),结构用扁平的 nodes 加 parent 连成树、不用递归;侧栏路径下面一层层展开节点,回答里用嵌套列表画树;回答和找的过程里的代码位置写成仓库链接,功能对话页上的链接按找代码用的工作区文件夹检查、打开、悬停;旧格式的结果当没有,栏上方提示打开对话重新找;删功能前先弹模态框确认,说清连带删掉调用树和问答记录,点「删除」才删
This commit is contained in:
1 parent
cc445e7123
commit
c6de46ad37
17 files changed
+978
-253
No files matched your search
@@ -1,6 +1,9 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { featureAnswer } from '../../../src/codeReader/features/featureResult'
|
||||
import { codeLink } from '../../../src/codeReader/qa/linkRule'
|
||||
import { renderMarkdown, renderMarkdownDiff, renderMarkdownOnce } from './markdown'
|
||||
import { repoImageInner } from './repoImage'
|
||||
import { parseRepoLink } from './repoLink'
|
||||
|
||||
describe('renderMarkdown', () => {
|
||||
it('一行文字是一个段落;段内换行是软换行,空行分段', () => {
|
||||
@@ -167,3 +170,42 @@ describe('问 AI 的回答里写成行内代码的代码位置', () => {
|
||||
expect(renderMarkdown('见 `backend/app/routes.py:96-135`')).toBe('<p>见 <code>backend/app/routes.py:96-135</code></p>\n')
|
||||
})
|
||||
})
|
||||
|
||||
describe('「了解一块代码」的回答', () => {
|
||||
/** 回答里各个链接的地址,按页面认仓库链接的办法拆开 */
|
||||
const links = (html: string): unknown[] => [...html.matchAll(/<a href="([^"]*)">/g)].map(([, href]) => parseRepoLink(href.replaceAll('&', '&')))
|
||||
|
||||
it('调用树画成嵌套列表,节点是仓库链接:路径带成对的括号(Next.js 的路由分组)也认成链接,via 是行内代码', () => {
|
||||
const answer = featureAnswer({ paths: [{ name: '首页发出首句', nodes: [
|
||||
{ id: '1', folder: 'web', path: 'src/app/(main)/chat/code/page.tsx', symbol: 'ChatCodePage', role: '会话页' },
|
||||
{ id: '2', parent: '1', folder: 'server', path: 'app/routes.py', symbol: 'create_app', via: 'POST /apps', role: '建应用' },
|
||||
{ id: '3', parent: '2', folder: 'server', path: 'app/models.py', role: '应用表' },
|
||||
] }] }, ['web', 'server'])
|
||||
const html = renderMarkdown(answer, 'answer')
|
||||
expect(html).toBe([
|
||||
'<p><strong>1. 首页发出首句</strong></p>',
|
||||
'<ul>',
|
||||
'<li><a href="web/src/app/(main)/chat/code/page.tsx#ChatCodePage">ChatCodePage</a>:会话页',
|
||||
'<ul>',
|
||||
'<li><code>POST /apps</code> → <a href="server/app/routes.py#create_app">create_app</a>:建应用',
|
||||
'<ul>',
|
||||
'<li><a href="server/app/models.py">models.py</a>:应用表</li>',
|
||||
'</ul>',
|
||||
'</li>',
|
||||
'</ul>',
|
||||
'</li>',
|
||||
'</ul>',
|
||||
'',
|
||||
].join('\n'))
|
||||
expect(links(html)).toEqual([
|
||||
{ path: 'web/src/app/(main)/chat/code/page.tsx', symbol: 'ChatCodePage' },
|
||||
{ path: 'server/app/routes.py', symbol: 'create_app' },
|
||||
{ path: 'server/app/models.py' },
|
||||
])
|
||||
})
|
||||
|
||||
it('路径里有空白、百分号、不成对的括号:编码后照样认成链接,拆出来是原来的路径', () => {
|
||||
const html = renderMarkdown([codeLink('a', 'docs/a b.md'), codeLink('b', 'docs/100%.md'), codeLink('c', 'docs/a(b.md', 'Doc')].join(' '), 'answer')
|
||||
expect(links(html)).toEqual([{ path: 'docs/a b.md' }, { path: 'docs/100%.md' }, { path: 'docs/a(b.md', symbol: 'Doc' }])
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user