材料卡 · dsh-material-cards
简体中文 · English
输入框旁边多一个按钮。点开、输入材料名、回车——一张写好的材料卡直接落进你正在打的那段话里,出处跟着走。
这是一个通用插件:任何按「一篇笔记讲一种材料」组织的 markdown 目录都能用。库在哪由你自己配置,包里不含任何人的路径。
为什么不直接让我去读文件
笔记本来就在你的磁盘上,问题不是「读不到」,是每次都从头读:
- 模型要先找候选、再读两三篇、再自己拼「这材料的卖点是什么」——同一件事在每个会话里重做一遍;
- 拼出来的东西没有出处,下次没人知道这句话来自哪篇笔记的哪一节;
- 笔记里的「规格(待补充)」「溢美」这类段落经常是空的或自我提醒,一起塞进去只会稀释上下文。
所以这里做的不是「文件浏览器」,是把整个库预先压成卡:标题、一句话定义、标签、三个最有用的分节,加一行出处。1400 字符以内,够模型直接用,也够你自己核对。
怎么用
- 输入区工具栏左侧出现一个「材料卡」图标。
- 点开,光标自动进搜索框;直接打字就是在滤(180ms 防抖,走宿主检索,不是本地过滤)。
↑↓选,HomeEnd跳首尾,Enter插入;Esc分两级——先清空搜索,再按一次才关面板。- 卡片追加到当前草稿末尾(草稿为空就直接落),中间空一行;已经有内容时插入是一次可撤销的编辑,不会覆盖你写的字。
搜索框为空时不是一串平铺的笔记,而是三个架子:
| 架子 | 里面是什么 | 怎么进去的 |
|---|---|---|
| 置顶 | 你钉住的笔记 | 行尾图钉按钮,点一下钉住,再点取消 |
| 最近 | 最近插入过的笔记(最多 8 条) | 自动的,插入时记一笔 |
| 全部 | 其余笔记,按最近改动 | — |
只有一个架子里有东西时不显示标题——标题的作用是分开两个架子,不是装饰。一旦开始搜索,三个架子收成一个平铺结果列表:搜索是关于整个库的问题,不该把某条笔记挪到别处。
搜索框右侧是清空按钮(×)、命中计数和行距开关(宽松 / 紧凑)。置顶、最近、行距都只存在这台机器的 localStorage 里,不进仓库、不上传。行内左侧的 medium / low 是笔记 frontmatter 里自报的置信度,没有就不显示。
卡片长什么样
插进输入框的实际文本(示例材料,约 600 字符):
【材料】棉麻混纺面料
亚麻与棉的混纺,夏季面套常见,手感粗爽、吸湿快干
标签:面料 · 亚麻 · 夏季 · 透气 · 置信度:medium
## 定义
- 亚麻(Flax)纤维与棉纤维按比例混纺的机织面料
- 常见配比 55% 亚麻 / 45% 棉;亚麻比例越高越挺括,也越容易起皱
## 核心特性
**优点**
- 吸湿快干:回潮率高,出汗后不黏身
- 挺括有筋骨:比亚麻纯纺更抗皱
**缺点/注意**
- 易起皱:日常穿着需要熨烫
- 缩水:首次水洗缩率可达 3%–5%
## 应用
- 面套顶层面料,定位夏季面
- 与冬季面料做双面设计:翻面只改温度、不改睡感
(出处:notes/棉麻混纺面料.md)
三点是刻意的:给事实和相对出处,不给绝对路径(绝对路径会让模型再去读一遍文件,也会把某台机器的目录结构写进你的对话)、表头不当数据(按 markdown 的 --- 分隔行判断,不靠白名单)、分组标签单独成行(**优点** 下面是条目,不是 - 优点: 这种读起来像渲染 bug 的空条目)。
想要绝对路径做溯源,把 fullPath 设成 true(见下面「配置库在哪」)。
配置库在哪
包本身不带路径。优先级从高到低:
| 顺序 | 来源 | 说明 |
|---|---|---|
| 1 | 插件 config 的 root / dir |
在 bundle patch 里写,随 profile 走 |
| 2 | 环境变量 DSH_MATERIAL_CARDS_ROOT |
只覆盖 root |
| 3 | ~/.dsh/material-cards.json |
本机文件,最省事;不进仓库 |
| 4 | 兜底 ~/materials |
dir 为空时就用它本身 |
本机文件长这样(dir 可省略,省略时 root 直接就是笔记目录):
{
"root": "D:\\notes",
"dir": "materials",
"fullPath": false
}
dir 不存在、或目录里没有 .md,检索返回空列表而不是报错——插件装上但还没配库时,面板会显示「材料库里还没有笔记」。
把规则注入提示词(可选)
同一个本机文件里还能写一个 rules:它会被注册成一段系统提示词,省掉「每个会话都重新翻一遍规范」这一步。不配就没有这段,插件其余行为完全不变。
{
"root": "D:\\\\notes",
"dir": "materials",
"rules": "brand/design-system.md",
"rulesSections": ["概述", "色彩", "红线"],
"rulesMax": 4000
}
| 键 | 作用 |
|---|---|
rules |
文件路径(相对 root,或绝对路径);不含分隔符时当成正文本身 |
rulesSections |
只保留标题里含这些关键词的 ## 小节;省略就是整篇 |
rulesMax |
字符上限,默认 6000,夹在 500–12000;超了在最后一个换行处截断并标注 |
这一段前缀写着「只在相关内容上生效」——插件拿不到「当前是哪个工作区」(提示词装配上下文里只有 scope 和 signal,没有 cwd),与其根据路径去猜,不如把适用范围写进正文,由模型判断相关性。
GET /plugins/material-cards/rules 返回当前生效的正文、来源和 registered(提示词段是否真的注册上了),用来区分「路径写错」和「没接上」。
笔记格式
只要求 frontmatter + 二级标题分节,其余自由:
---
type: material
title: 棉麻混纺面料
description: 一句话说清它是什么、用在哪
tags: [面料, 亚麻, 夏季]
confidence: medium
---
# 棉麻混纺面料
## 定义
...
## 核心特性
**优点**
- ...
**缺点/注意**
- ...
title / description / tags / confidence / status 都可缺省:没有 title 就用第一个 # 标题,再不行用文件名;没有 description 就取第一个正文段落。
取节规则
二级标题的写法通常很杂(同一个库里能出现几十种,从「定义」到「它为什么被这么叫」)。白名单必然漏,所以按这一节干什么用分五档打分,取分数最高的三节:
| 档 | 用途 | 包含 |
|---|---|---|
| 0 | 这是什么 | 定义 / 是什么 / 本质 / 含义 / 区别对比 |
| 1 | 好在哪里 | 核心特性 / 特性 / 特点 / 优点 / 体感 / 卖点 / 支撑 |
| 2 | 数字 | 规格 / 参数 / 指标 / 克重 / 含量 / 密度 / 厚度 |
| 3 | 用在哪 | 应用 / 产品 / 角色 / 关系 / 场景 / 用途 |
| 4 | 别夸大 | 局限 / 注意 / 缺点 / 溢美 / 可信 / 对比 |
检索
打分:标题 8、description 4、标签 4、slug 3、正文 2(正文命中数封顶 99,用于排序提示)。整个库在内存里过一遍,5 秒缓存——笔记量在几百个文件的量级,重读比维护索引更简单,也不会出现「索引和笔记不同步」这种失真。
路由
三个只读接口,都只认 loopback、只认 GET:
| 路由 | 参数 | 返回 |
|---|---|---|
GET /plugins/material-cards/search |
q(≤64 字)、limit(默认 8,上限 35) |
{ok, query, total, results[]} |
GET /plugins/material-cards/card |
slug |
{ok, card, prompt} |
GET /plugins/material-cards/rules |
无 | {ok, registered, source, sections, length, text} |
card 的 prompt 就是上面那段要插入的文本,客户端不再二次拼装——渲染只有一处实现,宿主和界面不会各自漂移。
安装
plugin_manager action: install_bundle
target: <绝对路径>\dsh-material-cards
装完把插件关掉再打开(set_plugin + enabled:false → true)让新代码加载,然后 Ctrl+R 刷新页面,再用 ~/.dsh/material-cards.json 指向你的笔记目录。
不做什么
- 不写回笔记:只读
.md,不改内容。 - 不做向量检索:几百个文件的量级,字段加权就够了;上向量反而要为「索引何时过期」负责。
- 不替你判断该不该说:卡片里带置信度和出处,但哪种说法能引用、能不能这么宣传,是你的判断。
- 不猜你的库在哪:没配置就是空的,不会去扫全盘。
开发
node --check index.js client.js
node ../.tmp-codex/materials-render-test.mjs # 干跑生产 client bundle
materials-render-test.mjs 用 mock 的平台加载生产 client.js 原件(不是副本),断言两个座位都注册、面板用真宿主数据渲染、Enter 走 inputActions.insertText 而不是直接改 DOM、插入文本带出处。
许可
MIT。
No comments yet. Be the first to write one.