尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Fabric Web UI 增强实践:Pattern 选择、搜索、收藏与 Obsidian 集成深度解析

Fabric Web UI 增强实践:Pattern 选择、搜索、收藏与 Obsidian 集成深度解析 Fabric Web UI 增强实践Pattern 选择、搜索、收藏与 Obsidian 集成深度解析【免费下载链接】FabricFabric is an open-source framework for augmenting humans using AI. It provides a modular system for solving specific problems using a crowdsourced set of AI prompts that can be used anywhere.项目地址: https://gitcode.com/GitHub_Trending/fa/FabricFabric 的 Web 界面web/目录下的 SvelteKit 前端围绕以人为中心的 AI 增强理念提供了一套可视化地浏览、筛选、选择并执行 Pattern提示词模板的操作体验。本文以仓库中的 enhanced-pattern-selection-update.md 为脉络系统讲解 Pattern 选择弹窗、实时搜索、收藏夹、标签过滤、System Instructions 滚动视图以及 Obsidian 笔记集成这组功能的前端实现、后端接口与安全设计。读完本文你将能理解 Fabric Web UI 中 Pattern 从列表加载 → 筛选 → 选中 → 注入系统提示词 → 保存到 Obsidian的完整数据链路并掌握每个模块对应的源码位置与可扩展点。功能总览一次升级五处体验增强该 PR 的核心诉求是让 Pattern 选择更直观、更有上下文。整组改进可以划分为三大块选择与描述为每个 Pattern 提供短描述short description、引入弹窗Modal选择界面、支持从弹窗内直接选中执行、为 System Instructions 框架增加滚动能力并新增实时搜索边输入边过滤、大小写不敏感的部分名称匹配、过滤时保持收藏排序。用户体验实现收藏favorites功能便于快速访问高频 Pattern改进 YouTube 转录transcript处理并新增Obsidian 集成支持从 Web 界面直接把 Pattern 执行结果保存到 Obsidian且笔记命名可配置无缝衔接既有笔记工作流。技术支撑后端新增相应接口与状态管理前端强化 Pattern 管理与收藏状态管理。从当前仓库的目录结构看上述改动已完整落地前端位于web/src/lib/components/patterns/PatternList.svelte、TagFilterPanel.svelte、web/src/lib/store/pattern-store.ts、favorites-store.ts、obsidian-store.ts后端路由注册于 internal/server/patterns.goObsidian 落盘逻辑位于 web/src/routes/obsidian/server.ts。Pattern 选择弹窗从列表到带描述的选择器弹窗形态与组件构成弹窗由 PatternList.svelte 实现固定为600px宽、85vh高的居中浮层bg-primary-800 rounded-lg flex flex-col h-[85vh] w-[600px] shadow-lg。弹窗内从上到下依次是标题栏Pattern Descriptions右侧提供关闭按钮通过dispatch(close)通知父组件收起弹窗。搜索与收藏区一个搜索输入框placeholderSearch patterns...与一个收藏过滤按钮☆ Favorites点击后切换showOnlyFavorites仅展示已收藏的 Pattern。标签展示区实时显示已选中的标签Tags支持逐个移除并提供reset一键清空。可滚动列表区每个 Pattern 条目渲染为名称 描述卡片名称按钮触发选中右侧星标按钮切换收藏。标签过滤面板复用 TagFilterPanel.svelte以标签砖块tag-brick形式展示全部标签支持多选组合过滤。选中即执行selectPattern 的调用链弹窗内点击 Pattern 名称会执行function selectPattern(patternName: string) { patternAPI.selectPattern(patternName); dispatch(select, patternName); }patternAPI.selectPattern定义在 pattern-store.ts 中核心逻辑是从内存中的allPatterns找到对应 Pattern取其Pattern字段即 system.md 内容写入systemPromptstore同时记录selectedPatternNameselectPattern(patternName: string) { const patterns get(allPatterns); const selectedPattern patterns.find(p p.Name patternName); if (selectedPattern) { setSystemPrompt(selectedPattern.Pattern); selectedPatternName.set(patternName); } else { setSystemPrompt(); selectedPatternName.set(); } }这一步把用户点选与系统提示词注入解耦选中动作只更新 Svelte store聊天组件通过订阅systemPrompt拿到最新提示词从而在发送消息时把 Pattern 作为 System Prompt 一并交给模型。这也是Select Pattern to execute from Modal的底层实现。实时搜索边输入边过滤的 Pattern 检索搜索过滤规则PatternList.svelte 中通过 Svelte 响应式声明$: filteredPatterns完成三层过滤的叠加$: filteredPatterns $patterns .filter(p { if (showOnlyFavorites !$favorites.includes(p.Name)) return false; // 收藏过滤 if (selectedTags.length 0) { if (!p.tags || !selectedTags.every(tag p.tags.includes(tag))) return false; // 标签过滤 } if (searchQuery.trim()) { return ( p.Name.toLowerCase().includes(searchQuery.toLowerCase()) || // 名称匹配 p.Description.toLowerCase().includes(searchQuery.toLowerCase()) || // 描述匹配 (p.tags p.tags.some(tag tag.toLowerCase().includes(searchQuery.toLowerCase()))) // 标签匹配 ); } return true; });搜索匹配范围并不局限于名称还覆盖描述与标签名称匹配p.Name.toLowerCase().includes(query)大小写不敏感的部分匹配描述匹配p.Description.toLowerCase().includes(query)标签匹配任意一个标签包含关键词即命中。过滤逻辑以声明式响应链驱动输入框每敲一个字符filteredPatterns立即重算实现实时过滤。由于过滤发生在$patterns已加载的全量列表之上收藏排序得以在过滤过程中保持——这正好对应原文档中Maintains favorites sorting while filtering的说明。标签过滤与复位TagFilterPanel.svelte 提供两类交互点击标签砖块切换选中状态通过dispatch(tagsChanged, selectedTags)把标签数组上抛给PatternList的handleTagFilter支持reset()复位方法弹窗内的reset按钮同时清空selectedTags并调用tagFilterRef.reset()保证标签选中态与面板展示态一致。面板还支持两种形态独立浮层position: fixed位于弹窗右侧left: calc(50% 300px)与嵌入式embedded类position: relative宽度 100%。hideToggleButton属性决定是否显示Open/Close Filter Tags折叠按钮弹窗内使用时通常传true隐藏折叠按钮、常驻展示。收藏功能快速访问高频 Pattern收藏的状态管理web/src/lib/store/favorites-store.ts 使用 Sveltewritablestring[]管理收藏的 Pattern 名称集合并借助浏览器localStorage实现持久化const storedFavorites browser ? JSON.parse(localStorage.getItem(favoritePatterns) || []) : []; const createFavoritesStore () { const { subscribe, set, update } writablestring[](storedFavorites); return { subscribe, toggleFavorite: (patternName: string) { update(favorites { const newFavorites favorites.includes(patternName) ? favorites.filter(name name ! patternName) : [...favorites, patternName]; if (browser) { localStorage.setItem(favoritePatterns, JSON.stringify(newFavorites)); } return newFavorites; }); }, reset: () { set([]); if (browser) localStorage.removeItem(favoritePatterns); } }; }; export const favorites createFavoritesStore();值得注意的细节SSR 安全通过browser来自$app/environment守卫localStorage访问避免服务端渲染时报错幂等切换toggleFavorite内部判断是否已存在存在则移除、不存在则追加天然支持再点一次取消收藏持久化键名favoritePatterns刷新页面后收藏自动恢复。收藏在列表中的视觉呈现在 PatternList.svelte 中每个条目右侧的星标按钮根据$favorites.includes(pattern.Name)渲染实心★黄色或空心☆点击时用on:click|stopPropagation阻止冒泡避免误触 Pattern 选中。顶部的 Favorites 按钮则通过showOnlyFavorites打开只看收藏模式。System Instructions 框架滚动与 Pattern 加载流程原文档提到的System Instructions frame 滚动功能对应弹窗与聊天界面中提示词区域的滚动容器。前端通过 CSS 自定义滚动条样式.custom-scrollbar、.patterns-container与overflow-y: auto保证长 Prompt 可完整浏览。Pattern 列表的加载入口在 pattern-store.ts 的patternAPI.loadPatterns()整体是一个两阶段拉取流程拉取描述元数据fetch(/data/pattern_descriptions.json)得到patterns数组每项含patternName、description、tags对应 scripts/pattern_descriptions/pattern_descriptions.json并行拉取 Pattern 内容先fetch(/api/patterns/names)获取全部名称再对每个名称并行fetch(/api/patterns/{name})取Pattern字段用Promise.all聚合。随后把描述与内容合并为Pattern对象Name、Description、Pattern、tags写入allPatterns。数据接口类型定义在 web/src/lib/interfaces/pattern-interface.tsPatternDescription描述元数据与Pattern含内容的存储实体。语言过滤patterns是allPatterns与languageStore的derived组合当选择了语言时通过正则/^([a-z]{2})_/提取 Pattern 名称的前缀语言码如en_、fr_仅保留无前缀或前缀与所选语言一致的 Pattern实现多语言 Pattern 的按需展示。后端 Pattern 接口存储、校验与变量应用后端在 internal/server/patterns.go 中通过PatternsHandler注册了一套完整的 Pattern 路由方法路由说明GET/patterns/:name获取指定 Pattern原始内容不做变量处理GET/patterns/names获取全部 Pattern 名称列表GET/patterns/exists/:name检查 Pattern 是否存在PUT/patterns/rename/:oldName/:newName重命名 PatternPOST/patterns/:name保存/更新 PatternDELETE/patterns/:name删除 PatternPOST/patterns/:name/apply应用 Pattern支持变量替换名称安全校验所有涉及名称的路由都会先经过rejectUnsafePatternNamefunc rejectUnsafePatternName(c *gin.Context, name string) bool { if name { return false } if fsdb.LooksLikePatternFilePath(name) || fsdb.ValidateStorageName(name) ! nil { setHSTS(c) c.JSON(http.StatusBadRequest, gin.H{error: fmt.Sprintf(i18n.T(pattern_invalid_name), name)}) return true } return false }它拒绝形如文件路径的名称以及未通过存储名称校验的值防止路径穿越与非法名称注入同时显式设置 HSTS 头。变量应用接口POST /patterns/:name/apply是新增的扩展点请求体结构为{ input: 用户输入内容, variables: { varName: value } }后端将 URL 查询参数与请求体variables合并body 优先调用h.patterns.GetApplyVariables(name, variables, request.Input)完成模板变量替换后返回结果。这为带变量的 Pattern 执行提供了服务端支持也是前端patternVariablesstore见 pattern-store.ts背后对应的能力。Obsidian 集成把 Pattern 执行结果直接写入笔记前端状态与命名配置web/src/lib/store/obsidian-store.ts 定义ObsidianSettingssaveToObsidian: boolean与noteName: string默认关闭保存、笔记名为空。updateObsidianSettings在保存成功后触发 3 秒的saveNotification提示Note saved to Obsidian!。笔记文件路径由getObsidianFilePath生成规则为return myfiles/Fabric_obsidian/${new Date().toISOString().split(T)[0]}-${noteName.trim()}.md;即以日期 自定义笔记名组织文件例如2026-09-09-提取洞见.md落盘目录为web/myfiles/Fabric_obsidian/。前端还通过 web/src/lib/config/features.ts 提供featureFlagsenableObsidianIntegration作为集成总开关并暴露toggleObsidianIntegration(enabled)供运行时切换。后端落盘端点与安全设计保存动作由 web/src/routes/obsidian/server.ts 的POST /obsidian端点完成请求体含pattern、noteName、content三个字段。实现要点必填校验三字段缺一即返回 400。防注入白名单先用basename()剥离目录成分再以正则/^[a-zA-Z0-9 _.-]$/校验笔记名注释中明确说明此举用于防御命令注入CWE-78与路径穿越CWE-22。内容包裹formattedContent \markdown\n${content}\n以 Markdown 代码块包裹便于 Obsidian 中直接识别。路径收敛校验解析resolve(myfiles/Fabric_obsidian)后join文件名二次确认filePath前缀属于该目录纵深防御CWE-22。原生 fs API 写入mkdir({recursive:true})确保目录存在后writeFile落盘再用stat校验文件大小并统计行数返回fileName、filePath给前端。整个过程不使用 shell彻底消除命令注入面。前端在ChatInput/Chat组件中调用该端点即可实现聊天结果一键存入 Obsidian。描述与标签的数据来源Pattern 描述与标签集中维护在 scripts/pattern_descriptions/pattern_descriptions.json由 scripts/pattern_descriptions/extract_patterns.py 脚本生成与管理配套说明见 README_Pattern_Descriptions_and_Tags_MGT.md。前端运行时通过/data/pattern_descriptions.json路径加载这份元数据与/api/patterns/names返回的 Pattern 集合按patternName关联为搜索、标签过滤与描述展示提供统一数据源。若某 Pattern 缺失描述前端会退化为名称首字母大写的兜底展示见 pattern-store.ts 中的pattern.charAt(0).toUpperCase() pattern.slice(1)。平台兼容性说明原文档末尾明确提醒该实现主要在 macOS 上开发与测试部分改动对 Windows 用户可能并非必需尤其是系统相关路径与配置。Windows 用户若遇到路径类问题需要按自身环境调整 Obsidian 落盘目录、myfiles等路径配置。这一点同样适用于自建部署场景实际运行目录以部署方式本地开发、容器化等为准。小结从enhanced-pattern-selection-update.md这份 PR 说明出发对照当前仓库源码可以看到整条功能链路已经完整落地前端以 PatternList.svelte 弹窗承载搜索 收藏 标签 描述的一体化选择体验以 pattern-store.ts 与 favorites-store.ts 管理状态后端以 internal/server/patterns.go 提供带校验的 Pattern CRUD 与变量应用接口Obsidian 集成则由 obsidian-store.ts 与 web/src/routes/obsidian/server.ts 共同完成兼顾命名可配置与命令注入/路径穿越防护。这些改进共同把 Fabric Web UI 的 Pattern 选择从名称列表升级为可检索、可收藏、可标签化、可一键沉淀到笔记的完整工作流为深度使用 Fabric 的 Pattern 体系提供了顺手的可视化入口。【免费下载链接】FabricFabric is an open-source framework for augmenting humans using AI. It provides a modular system for solving specific problems using a crowdsourced set of AI prompts that can be used anywhere.项目地址: https://gitcode.com/GitHub_Trending/fa/Fabric创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表