> ⚠️ 课搭子已升级为「大学生内阁(College Cabinet)」v1.0.0。 新品牌、新功能(通知处理),数据完全兼容。本版本(v1.3.0)仅作为迁移跳板,建议尽快升级。
管课表、记日程、盯 DDL、理账本。一个 skill,三个 JSON。
大学生内阁是课搭子的品牌升级版,数据格式完全兼容,新增通知原文一键处理功能。迁移零风险。
用户说"迁移到大学生内阁"时,AI 执行:
skills/college-cabinet/data/ 目录存在,不存在则创建skills/course-buddy/data/ 下的 schedule.json、courses.json、ledger.json 复制到新路径三个 JSON 无需任何格式转换,复制即用。
| 用户说 | 做什么 |
|---|---|
| -------- | -------- |
| "迁移到大学生内阁" | 执行上述迁移流程 |
| "大学生内阁是什么" | 介绍新版本功能改进 |
大学不止上课。课表轮换、实验分组、DDL 追命、通知轰炸、账目乱飞——靠脑袋记早晚崩。
课搭子做的事:课表、日程、账本各一个 JSON。AI 只读不写冗余,不跨文件同步。查课表自动算周次、过假期、理补课;实验轮换自动展开,只显示你那一组。日程分三种类型各不同提醒策略。记账自动更新余额,转账双记防漏。
skills/course-buddy/data/ 目录schedule.json → {"version":"3.0","events":[]}ledger.json → {"version":"1.0","accounts":[],"transactions":[]}courses.json → 见下方课表章节| 文件 | 内容 |
|---|---|
| ------ | ------ |
data/schedule.json | 日程事件(一般日程、DDL、时刻提醒) |
data/ledger.json | 账户与交易 |
data/courses.json | 学期课表(含实验轮换和调停课) |
三个文件是各自领域的唯一数据源。memory 文件只记对话摘要,不从中提取结构化数据。
{
"version": "2.0",
"semester": "2026年春季学期",
"first_week_date": "2026-03-09",
"total_weeks": 16,
"holidays": [
{"name": "劳动节", "start": "2026-05-01", "end": "2026-05-05"}
],
"makeup_days": [
{"date": "2026-05-09", "replace_weekday": 1}
],
"courses": [
{
"name": "大学物理实验B",
"weekday": 2,
"time_start": "08:00",
"time_end": "11:30",
"weeks": [2,3,4,5,6,7,8,9,10,11,12,13],
"location": "分组实验",
"teacher": "",
"parallel": true,
"group": 1,
"schedule": {
"2": {"topic": "基本力学量测量", "location": "201室", "teacher": "高志华"},
"3": {"topic": "单摆运动", "location": "229室", "teacher": "周亚洲"}
},
"overrides": {
"11": {"status": "cancelled", "note": "临时停课"}
}
}
]
}
每个 course 必填:name、weekday(0=周一~6=周日)、time_start、time_end、weeks(包含该课程的周次数组)、location、teacher。
可选字段:
parallel:true 表示分组实验,多个平行班同时段上课。未告知用户分组时合并显示为一行group:用户所在组号schedule:周次 → {topic, location, teacher}。每周内容不同的实验课用。无 schedule 的周次使用默认 location/teacheroverrides:周次 → {status, note}。status 取值:cancelled(该周停课)、postponed_to(顺延至某周)、room_change(换教室)对周次 W,确定具体内容的优先级:
当前周 = floor((今天 - first_week_date) / 7) + 1
当用户提供轮换表、分组名单、或每周具体安排时:
同一时段同名课程有多条记录时,标注 parallel: true。查询时合并显示为一行。用户告知分组后只显示对应那组的内容。
新课表来了 → 解析生成新的 courses.json 覆盖。旧文件改名为 courses-上赛季名称.json 备份。
日程事件有三种类型,行为各不相同。课程不进入 schedule,课表由 courses.json 独立管理。
| type | 含义 | 时间粒度 | 提醒方式 |
|---|---|---|---|
| ------ | ------ | ---------- | ---------- |
event | 一般日程 | 时段 | 当天时段前提醒,结束后标 done |
ddl | 截止日期 | 日期(可指定时刻) | 从今天到截止日,每天提醒 |
moment | 时刻提醒 | 精确时刻 | 临近时刻提醒,写入心跳 |
{
"version": "3.0",
"events": [
{
"id": "s-20260517-001",
"date": "2026-05-17",
"title": "排练",
"type": "event",
"time": "14:00-16:00",
"location": "化一教室",
"status": "active",
"category": "活动",
"note": ""
},
{
"id": "s-20260520-001",
"date": "2026-05-20",
"title": "无机化学作业",
"type": "ddl",
"time": "",
"location": "",
"status": "active",
"category": "作业",
"note": "第六章习题"
},
{
"id": "s-20260517-002",
"date": "2026-05-17",
"title": "给张三打电话",
"type": "moment",
"time": "10:00",
"location": "",
"status": "active",
"category": "电话",
"note": "确认实验分组"
}
]
}
| 字段 | 必填 | 说明 |
|---|---|---|
| ------ | ------ | ------ |
| id | 是 | 唯一标识,格式 s-YYYYMMDD-序号 |
| date | 是 | 日期,YYYY-MM-DD |
| title | 是 | 事件名称 |
| type | 是 | event / ddl / moment |
| time | 看 type | event 用时段 HH:MM-HH:MM;ddl 用时刻 HH:MM(选填,不填为全天);moment 用时刻 HH:MM |
| location | 否 | 地点 |
| status | 是 | active / cancelled / done |
| category | 否 | 用户自定义分类,随便填,skill 层不预设枚举 |
| note | 否 | 备注 |
格式自动判断:含 - 为时段,不含为时刻。
"14:00-16:00""23:59""10:00"字段值判断替代文本标记解析。
| 用户说 | 做什么 |
|---|---|
| -------- | -------- |
| "5月17日 14:00 排练 化一" | 添加 type=event |
| "下周五前交分析化学报告" | 添加 type=ddl,date=下周五,time 不填 |
| "今晚 23:59 前交作业" | 添加 type=ddl,time=23:59 |
| "十点提醒我给张三打电话" | 添加 type=moment,time=10:00 |
| "明天的排练取消了" | 对应 event status → cancelled |
| "排练搞完了" | 对应 event status → done |
| "今天有什么" | 查今天所有 active 事件 |
| "这周有什么" | 查未来 7 天所有 active 事件 |
多账户收支管理。每次交易自动更新余额,转账强制双记防漏。
{
"version": "1.0",
"accounts": [
{"id": "campus_card", "name": "校园卡", "balance": 579.25},
{"id": "wechat", "name": "微信", "balance": 320.00}
],
"transactions": [
{
"id": "txn-001",
"date": "2026-05-17",
"time": "12:30",
"account": "校园卡",
"amount": -9.50,
"type": "expense",
"category": "餐饮",
"item": "午餐",
"note": ""
}
]
}
accounts
| 字段 | 说明 |
|---|---|
| ------ | ------ |
| id | 账户唯一标识(英文) |
| name | 账户显示名 |
| balance | 当前余额 |
transactions
| 字段 | 必填 | 说明 |
|---|---|---|
| ------ | ------ | ------ |
| id | 是 | 唯一标识,格式 txn-序号 |
| date | 是 | 日期,YYYY-MM-DD |
| time | 否 | 时间,HH:MM |
| account | 是 | 账户名(对应 accounts[].name) |
| amount | 是 | 金额。支出为负数,收入为正数 |
| type | 是 | expense / income / transfer |
| category | 否 | 用户自定义分类。建议:餐饮 交通 购物 居住 娱乐 教育 医疗 其他 |
| item | 否 | 项目/商品名 |
| note | 否 | 备注 |
转账(type=transfer)必须双记:一条从源账户出(负数),一条入目标账户(正数)。写入后立即验证两账户余额变动是否匹配,不匹配则回滚。
不修改、不删除原始交易。修正方式:
| 用户说 | 做什么 |
|---|---|
| -------- | -------- |
| "午饭校园卡 9.5" | 添加 expense,校园卡余额 -9.5 |
| "微信收入 32" | 添加 income,微信余额 +32 |
| "校园卡转微信 400" | 两条 transfer,更新双方余额 |
| "查余额" | 列出所有账户及余额 |
| "这周花了多少" | 汇总本周支出 |
| "这个月餐饮花了多少" | 按 category 筛选汇总 |
提醒分两层:定时简报(cron 触发,推送摘要)和实时提醒(心跳/定时任务触发,即时推送)。
简报档位、时间、模块均可自由设定。默认提供四档,用户可增删。
默认简报:
| id | 标签 | 默认时间 | 默认模块 |
|---|---|---|---|
| ------ | ------ | ---------- | ---------- |
morning | 晨间简报 | 06:40 | weather, courses, events, ddl |
noon | 午间简报 | 12:40 | weather, courses_pm, events, ddl |
evening | 晚间简报 | 19:00 | events, courses_tomorrow, ddl |
night | 睡前简报 | 22:00 | weather_tomorrow, ddl, balance, backup |
模块仅限以下预设,不可超出:
| 模块名 | 内容 |
|---|---|
| -------- | ------ |
weather | 今日天气 |
weather_tomorrow | 明日天气 |
courses | 今日全部课程 |
courses_pm | 今日下午课程 |
courses_tomorrow | 明日课程 |
events | 今日全部日程 |
events_pm | 今日下午日程 |
events_tonight | 今晚日程 |
ddl | 所有活跃 DDL 及倒计时 |
balance | 各账户余额 |
backup | 数据备份提醒 |
三种 type 在简报中出现的方式不同:
以上 strategy 参数可配置,见下方。
心跳或短周期定时任务(建议每 5-10 分钟)检查:
schedule.json 顶层可加入 reminder 字段,覆盖默认值。不填则使用默认。
{
"version": "3.0",
"reminder": {
"briefings": [
{ "id": "morning", "time": "06:40", "label": "晨间简报", "modules": ["weather", "courses", "events", "ddl"] },
{ "id": "noon", "time": "12:40", "label": "午间简报", "modules": ["weather", "courses_pm", "events", "ddl"] },
{ "id": "evening", "time": "19:00", "label": "晚间简报", "modules": ["events", "courses_tomorrow", "ddl"] },
{ "id": "night", "time": "22:00", "label": "睡前简报", "modules": ["weather_tomorrow", "ddl", "balance", "backup"] }
],
"advance": {
"event": { "briefings": 2 },
"moment": { "briefings": 1, "heartbeat": true },
"ddl": { "briefings": "all", "urgent_days": 3 }
}
},
"events": [...]
}
| 参数 | 默认 | 说明 |
|---|---|---|
| ------ | ------ | ------ |
briefings | 四档 | 简报列表,每条含 id、time、label(选填)、modules。可增减档位、调时间、自由组合模块 |
briefings[].modules | 见上表 | 每档简报包含的模块。模块必须从预设列表中选取,不可超出 |
advance.event.briefings | 2 | event 提前几个简报周期开始出现 |
advance.moment.briefings | 1 | moment 提前几个简报周期出现 |
advance.moment.heartbeat | true | moment 是否写入心跳待提醒列表 |
advance.ddl.briefings | "all" | ddl 出现范围:"all" 所有简报 / 数字 = 截止前 N 天开始出现 |
advance.ddl.urgent_days | 3 | ddl 距截止日 ≤ N 天时语气加重 |
用户口头调整("早上改成 7:00 推送"、"晚间只保留 DDL 和课表"、"去掉午间简报")→ AI 更新 reminder 配置。
时间比较规则:只比较结束时间是否已过。开始时间在未来不等于已过。
data/backups/文件名-YYYY-MM-DD.jsonpython3 -c "import json; json.load(open('...'))")每次大版本变化的迁移路径在此记录。AI 读取数据时自动检测版本并执行迁移,用户无感知。
| schedule.json version | 对应版本 | 主要变化 |
|---|---|---|
| ---------------------- | --------- | --------- |
| 2.0 | v1.0.0 | 初始版本。type 含 7 种枚举(course/exam/ddl/meeting/activity/lecture/personal),有 weekday 字段 |
| 3.0 | v1.1.0+ | type 重构为 event/ddl/moment,新增 category 和 reminder 字段 |
AI 每次读取 schedule.json 时执行以下检查,按优先级逐一处理:
1. version < "3.0" → 来自 v1.0.0
旧七种 type 映射为新三种:
| 旧 type | 新 type | category |
|---|---|---|
| --------- | --------- | ---------- |
ddl | ddl | (不变) |
course | event | "课程" |
exam | event | "考试" |
meeting | event | "会议" |
activity | event | "活动" |
lecture | event | "讲座" |
personal | event | "个人" |
同时删除每条 event 的 weekday 字段。time 格式不变(旧版均为时段格式)。完成后将 version 写为 "3.0"。
2. 无 reminder 顶层字段 → 来自 v1.1.0
以默认值写入:四档简报、advance 默认参数。
3. reminder.briefings 为对象而非数组 → 旧版格式
转为数组结构,每个 key 作为 id 字段,值保持不变。
迁移完成后立即执行备份与格式验证(遵守安全规则)。迁移失败则回滚并告知用户。
课搭子的课表、日程、记账功能是自包含的。以下可作为独立 skill 配合使用:
共 4 个版本