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

83 lines
3.5 KiB
JavaScript
Vendored
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.

/**
* AI 回复内联深链目录(可执行映射)
*
* AI 在回复正文里用标准 markdown 链接把"可定位的页面/面板"包成深链:
* [系统设置](dootask://link/setting_system)
* 渲染时 markdown.js 用 isDeepLinkId 校验(非法 id 退化为纯文字,绝不渲染死链),
* 点击时 DialogMarkdown 调 openDeepLink 直接导航到那一屏。
*
* 这里是「可执行映射」id → 怎么打开。语义目录id/title/aliases供 AI 选择)在
* resources/ai-kb/_meta/page-links.yaml —— 两份的 id 集合必须一致CI 校验见
* tests/.. 或 page-links 解析)。本期均为无需运行时 id 的纯导航目的地。
*/
// id → 打开方式。route 走 window.$A.goForward与 action-executor.js 一致)。
const LINKS = {
// 顶层功能页
dashboard: { route: { name: 'manage-dashboard' } },
messenger: { route: { name: 'manage-messenger' } },
calendar: { route: { name: 'manage-calendar' } },
files: { route: { name: 'manage-file' } },
application: { route: { name: 'manage-application' } },
project_list: { route: { name: 'manage-project' } },
// 设置12 个 manage-setting-* 独立路由)
setting_personal: { route: { name: 'manage-setting-personal' } },
setting_checkin: { route: { name: 'manage-setting-checkin' } },
setting_language: { route: { name: 'manage-setting-language' } },
setting_theme: { route: { name: 'manage-setting-theme' } },
setting_keyboard: { route: { name: 'manage-setting-keyboard' } },
setting_license: { route: { name: 'manage-setting-license' } },
setting_password: { route: { name: 'manage-setting-password' } },
setting_email: { route: { name: 'manage-setting-email' } },
setting_system: { route: { name: 'manage-setting-system', query: { tab: 'setting' } } },
setting_device: { route: { name: 'manage-setting-device' } },
setting_version: { route: { name: 'manage-setting-version' } },
setting_delete: { route: { name: 'manage-setting-delete' } },
// 系统设置内的二级 Tabsystem.vue 据 query.tab 切换)
setting_system_task_priority: { route: { name: 'manage-setting-system', query: { tab: 'taskPriority' } } },
setting_system_column_template: { route: { name: 'manage-setting-system', query: { tab: 'columnTemplate' } } },
setting_system_file: { route: { name: 'manage-setting-system', query: { tab: 'fileSetting' } } },
};
export const CATALOG_IDS = Object.keys(LINKS);
/**
* 校验 id 是否在目录内(渲染与点击两端都用,防死链)
* @param {string} id
* @returns {boolean}
*/
export function isDeepLinkId(id) {
return Object.prototype.hasOwnProperty.call(LINKS, id);
}
/**
* 打开深链目的地
* @param {string} id 目录 id
* @returns {boolean} 是否成功派发导航
*/
export function openDeepLink(id) {
const entry = LINKS[id];
if (!entry) {
return false;
}
if (entry.route && typeof window !== 'undefined' && window.$A?.goForward) {
// 浅拷贝避免 goForward 内部改动污染目录
window.$A.goForward({
name: entry.route.name,
...(entry.route.params ? { params: { ...entry.route.params } } : {}),
...(entry.route.query ? { query: { ...entry.route.query } } : {}),
});
return true;
}
return false;
}
// 暴露调试钩子供 Playwright/E2E 验证(对标原 __startAiGuide
if (typeof window !== 'undefined') {
window.__openDeepLink = (id) => openDeepLink(id);
}
export default openDeepLink;