mirror of
https://github.com/kuaifan/dootask.git
synced 2026-07-04 13:25:23 +00:00
「带我去」分步引导(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>
44 lines
1.7 KiB
JavaScript
44 lines
1.7 KiB
JavaScript
/**
|
||
* 深链目录一致性校验:
|
||
* 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.yaml:links: 下两空格缩进的一级 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.js:LINKS 对象内四空格缩进、值为 { ... } 的 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`);
|