dootask/tests/deep-links-parity.mjs
kuaifan 39b9a72b16 refactor(ai-assistant): 用内联深链替代 driver.js 页面引导
「带我去」分步引导(driver.js + 四级元素定位 + show_guide)定位不稳、
二级菜单不可达、点高亮按钮触发跳转即被杀,体验差。改为 AI 回复正文里把
可定位的页面/面板渲染成可点深链 chip,点击直达那一屏。

- 新增深链目录:_meta/page-links.yaml(语义,供 AI 选择)+ deep-links.js
  (可执行映射,21 个无需运行时 id 的导航目的地),两端 id 一致性由
  tests/deep-links-parity.mjs 校验
- markdown.js 加 processDeepLinks:[文字](dootask://link/<id>) 合法 id →
  chip,非法 id → 纯文字(绝不渲染死链);复用现有 dootask:// 点击拦截链路
- DialogMarkdown 加 link 分支调 openDeepLink;system.vue 支持 query.tab
  初始化,系统设置二级 Tab 可深链直达
- 彻底移除 driver.js 引导:删 guide-renderer.js/guide.css、show_guide
  前端通道、aiGuideStarted 监听、driver.js 依赖
- 同步 ai-kb:改写 guide/start-guide 两 chunk、tool-binding 去 show_guide
- 插件侧 prompt 改动规格见 docs/ai-deeplink-plugin-spec.md(独立仓库实施)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 23:55:09 +00:00

44 lines
1.7 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 深链目录一致性校验:
* resources/assets/js/components/AIAssistant/deep-links.js 的可执行 id 集合
* 必须与 resources/ai-kb/_meta/page-links.yaml 的语义 id 集合完全一致。
*
* 用法node tests/deep-links-parity.mjs (无依赖,纯正则解析)
* 不一致时打印差异并以非 0 退出,可接入 CI。
*/
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, resolve } from 'node:path';
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
// page-links.yamllinks: 下两空格缩进的一级 key
const yaml = readFileSync(resolve(root, 'resources/ai-kb/_meta/page-links.yaml'), 'utf8');
const yamlIds = new Set();
let inLinks = false;
for (const line of yaml.split('\n')) {
if (/^links:\s*$/.test(line)) { inLinks = true; continue; }
if (inLinks && /^\S/.test(line)) { inLinks = false; }
const m = inLinks && line.match(/^ {2}([a-z_]+):\s*$/);
if (m) yamlIds.add(m[1]);
}
// deep-links.jsLINKS 对象内四空格缩进、值为 { ... } 的 key
const js = readFileSync(resolve(root, 'resources/assets/js/components/AIAssistant/deep-links.js'), 'utf8');
const jsIds = new Set();
for (const m of js.matchAll(/^ {4}([a-z_]+):\s*\{/gm)) {
jsIds.add(m[1]);
}
const onlyYaml = [...yamlIds].filter(id => !jsIds.has(id));
const onlyJs = [...jsIds].filter(id => !yamlIds.has(id));
if (onlyYaml.length || onlyJs.length) {
console.error('✗ 深链目录不一致:');
if (onlyYaml.length) console.error(' 仅在 page-links.yaml', onlyYaml.join(', '));
if (onlyJs.length) console.error(' 仅在 deep-links.js', onlyJs.join(', '));
process.exit(1);
}
console.log(`✓ 深链目录一致,共 ${yamlIds.size} 个 id`);