支持分类、家庭共享和购买记录的对话式购物清单。可通过自然语言添加项目、勾选及分类管理。
购物列表 管理家庭购物列表是一项面向实际任务的技能,主要用于添加数量的项目, 检查它们;按类别排列;
使用时应结合输入条件选择合适的执行方式,核对必要参数、依赖环境与输出内容,并按原始要求处理异常情况。该技能适合需要稳定复用相关能力的场景,可作为自动化工作流的一部分,也便于后续检查、调整和扩展。从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。
实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;涉及批量任务时,还应保存进度,避免中断后重复操作。
管理家庭购物清单。可添加带数量的物品、勾选已完成项、按类别组织。数据存于 skills/shopping-list/data/ 目录中。
完整命令参考及输出格式详见 skills/shopping-list/references/commands.md。
在执行任何购物清单操作前,须按顺序完成以下检查:
skills/shopping-list/data/ 目录不存在,则创建该目录。data/active.json 不存在,则创建该文件,内容如下:{
"items": [],
"categories": ["Produce", "Dairy", "Meat", "Pantry", "Frozen", "Beverages", "Household", "Personal"],
"lastModified": "<当前 ISO 时间戳>"
}
data/active.json 存在但无法解析为合法 JSON,则将其重命名为 data/active.json.corrupt,并新建一个默认文件。同时向用户提示:「购物清单数据已损坏。已将备份保存为 active.json.corrupt,并新建了一份空白清单。」data/config.json 不存在,则创建该文件,内容为:{ "user": null, "snoozes": {} }config.json 中 "user": null,则向用户询问:「您叫什么名字?我将用它来记录每项物品的添加者。」将用户回答(转为小写)存入 config.json 后,再继续执行原始命令。本文档中所有文件路径均相对于 skills/shopping-list/,除非另有说明。
当前活跃的购物清单,包含所有尚未归档的物品。
{
"items": [
{
"id": "F47AC10B-58CC-4372-A567-0E02B2C3D479",
"name": "Whole Milk",
"normalizedName": "whole milk",
"quantity": 2,
"unit": "gallons",
"category": "Dairy",
"checkedOff": false,
"checkedOffDate": null,
"addedBy": "aj",
"addedDate": "2026-02-24T10:00:00Z",
"notes": null
}
],
"categories": ["Produce", "Dairy", "Meat", "Pantry", "Frozen", "Beverages", "Household", "Personal"],
"lastModified": "2026-02-24T10:00:00Z"
}
字段规则:
id —— 使用 bash 中的 uuidgen 命令生成。若该命令不可用,则由当前 ISO 时间戳拼接 4 位随机十六进制字符构成(例如:2026-02-24T10:00:00Z-a3f1)。name —— 用户输入的物品名称,首尾空格已去除;显示时保留原始大小写。normalizedName —— 恒为 name.toLowerCase().trim() 的计算结果。每次新增或编辑时均需重新计算。该字段用于所有匹配与去重逻辑。quantity —— 可选字段。若用户未指定数量,则默认为 null;若存在,则必须为大于 0 的数值(支持小数,例如 0.5 表示半磅)。unit —— 可选自由文本(如 “gallons”、“lbs”、“bunch”、“bag”)。未指定时默认为 null。category —— 必须为 categories 数组中的值之一,或为 “Uncategorized”。checkedOff —— 布尔值。初始为 false;当用户勾选该物品时设为 true。checkedOffDate —— 物品被勾选时的 ISO 时间戳;未勾选时为 null。addedBy —— 来自 config.json 中 user 字段的小写字符串(例如 “aj” 或 “shal”)。addedDate —— 物品首次添加时的 ISO 时间戳。notes —— 可选自由文本,用于特殊说明(如 “the organic one”、“Costco size”),默认为 null。categories(顶层数组)—— 已知类别的主列表,初始含 8 个预设值;自定义类别将在创建时追加至该数组末尾。lastModified —— ISO 时间戳,每次向该文件写入时更新。存储会话级持久化的用户配置。
{ "user": "aj", "snoozes": {} }
user —— 首次交互时设置,跨会话持久化。值为小写字符串。snoozes —— 预留用于 Phase 2 的补货建议功能。现阶段忽略;写入时须保留该字段。已购物品的月度归档文件。每月一个文件,按需创建。
{
"month": "2026-02",
"archivedItems": [
{ "...与活跃项相同字段...", "archivedDate": "2026-02-25T08:00:00Z" }
]
}
当物品从活跃清单移入历史归档时,为其添加 archivedDate 字段。原活跃项的所有字段均完整保留。若某月尚无对应 history 文件,且首次有物品归档至该月,则自动创建新文件。
将用户的自然语言输入解析为每个物品的名称、数量和单位。
类别推断: 静默推断物品所属类别。常见映射关系如下:牛奶/奶酪/酸奶/黄油 → Dairy;鸡肉/牛肉/鱼类 → Meat;香蕉/生菜/洋葱 → Produce;大米/意面/面粉 → Pantry;洗洁精/纸巾 → Household;洗发水/牙膏 → Personal;啤酒/葡萄酒/果汁 → Beverages;披萨/冰淇淋 → Frozen。若映射不明确,则归为 “Uncategorized”。切勿向用户询问类别;如需修改,用户可使用 “move X to Y category” 指令。
多物品输入: 用户可一次性添加多个物品,例如:“add eggs, bread, and 2 gallons milk” 应生成 3 个独立条目。以逗号与 “and” 作为分隔符。当解析存在歧义(如 “hot dog buns” 等复合名称靠近分隔符)时,应向用户确认,而非错误猜测。
重复处理: 创建新物品前,先检查活跃清单中是否存在 normalizedName 相同的已有物品。
checkedOff: false,checkedOffDate: null),并按需更新数量。新增类别: 若用户显式指定了一个不在 categories 数组中的类别,则将其加入该数组,并将物品分配至该类别。
从 config.json 中读取 user 值作为 addedBy;addedDate 设为当前 ISO 时间戳;checkedOff 设为 false,checkedOffDate 设为 null;写入完成后更新 lastModified。
通过 normalizedName 进行匹配(不区分大小写,支持模糊匹配;例如仅有一项 “whole milk” 时,“milk” 即可匹配成功)。
checkedOff 设为 true,checkedOffDate 设为当前 ISO 时间戳,并向用户确认。已勾选的物品仍保留在 active.json 中,并以删除线样式显示,直至归档流程将其移入历史(24 小时后)。
从活跃清单中永久删除某项物品。不生成归档记录,也不写入历史。此功能专用于纠正“误添加”情形。
匹配方式与勾选一致(基于 normalizedName)。执行前须向用户确认。
通过 normalizedName 定位目标物品,然后更新指定字段。支持编辑的字段包括:name、quantity、unit、category、notes。
若修改了 name,则需重新计算 normalizedName;若 category 改为 categories 数组中不存在的值,则将其加入该数组;写入完成后更新 lastModified。
当用户说 “switch to Shal”、“I'm AJ” 或类似语句时,更新 config.json 中的 user 字段。此后所有新增物品的 addedBy 均使用该新值。
该流程在每次购物清单命令启动时自动执行,早于用户请求的实际处理。
data/active.json。checkedOff 为 true,且 checkedOffDate 距今已超过 24 小时。data/history-2026-02.json;若不存在,则新建文件,内容为:{ "month": "2026-02", "archivedItems": [] }。archivedItems 数组中,并新增 archivedDate 字段,值为当前 ISO 时间戳。data/active.json 的 items 数组中移除已归档的物品。写入顺序至关重要: 务必先写入历史文件,再写入活跃文件。若两步之间发生中断,最坏情况仅为历史文件中出现无害的重复条目;反之(先写活跃后写历史),则可能导致数据丢失——物品已从活跃清单中移除,却未能写入历史。
shopping clear 命令将立即触发该归档流程,对所有已勾选项执行归档,跳过 24 小时等待期。
展示购物清单时,类别排序遵循以下固定顺序:
跳过所有无物品的类别(此处仅统计未勾选的物品)。每个类别内,物品按 normalizedName 字母序排序,不得依赖 JSON 中原始数组顺序。
已勾选物品在其所属类别中以删除线样式呈现,视觉上区别于未勾选项。它们将持续可见,直至被归档。
当用户询问过往采购情况(例如:“上个月买了什么?”、“采购历史”、“一月份买了什么?”)时,读取对应 data/history-YYYY-MM.json 文件。结果按日期分组呈现(最新日期优先),列出物品名称与数量。若所查时间段无对应 history 文件,则告知用户:“该月份未找到采购历史。”
注意:历史记录反映的是归档时间,而非实际购买时间。例如某物品于 2 月 28 日勾选,但于 3 月 1 日归档,则出现在 3 月的历史中。
相关专题
热门下载
相关下载
精品课程
共6课时 | 54.7万人学习
共89课时 | 134.1万人学习
共49课时 | 82.6万人学习
最新文章