libero3 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. package/COLD_START.md +31 -0
  2. package/LICENSE +21 -0
  3. package/README.md +43 -0
  4. package/data/migrations/001_initial_schema.sql +43 -0
  5. package/data/migrations/002_seed_categories.sql +18 -0
  6. package/data/migrations/003_add_rating.sql +4 -0
  7. package/data/migrations/004_timer_sessions.sql +21 -0
  8. package/data/migrations/005_profile_settings.sql +5 -0
  9. package/data/migrations/006_add_timeblock_status.sql +1 -0
  10. package/data/migrations/007_reminders.sql +17 -0
  11. package/data/migrations/008_timer_target_ms.sql +5 -0
  12. package/data/migrations/009_tasks.sql +22 -0
  13. package/data/migrations/010_timer_task_id.sql +4 -0
  14. package/data/migrations/011_profile_default_confirmed.sql +4 -0
  15. package/data/migrations/012_identity_tables.sql +68 -0
  16. package/data/migrations/013_identity_managed_by.sql +3 -0
  17. package/data/migrations/014_task_difficulty_priority.sql +6 -0
  18. package/data/migrations/015_timeblock_asked_at.sql +5 -0
  19. package/data/migrations/016_intent_columns.sql +8 -0
  20. package/data/migrations/017_ap_wallet.sql +25 -0
  21. package/data/migrations/018_ap_rewards.sql +21 -0
  22. package/data/migrations/019_ap_bounty.sql +10 -0
  23. package/data/migrations/020_chat_turns.sql +10 -0
  24. package/data/migrations/021_portrait.sql +4 -0
  25. package/data/migrations/022_family_emoji_single.sql +3 -0
  26. package/data/migrations/023_ap_balance_view_log.sql +9 -0
  27. package/data/schema.sql +75 -0
  28. package/dist/data/db.js +83 -0
  29. package/dist/data/migrations/001_initial_schema.sql +43 -0
  30. package/dist/data/migrations/002_seed_categories.sql +18 -0
  31. package/dist/data/migrations/003_add_rating.sql +4 -0
  32. package/dist/data/migrations/004_timer_sessions.sql +21 -0
  33. package/dist/data/migrations/005_profile_settings.sql +5 -0
  34. package/dist/data/migrations/006_add_timeblock_status.sql +1 -0
  35. package/dist/data/migrations/007_reminders.sql +17 -0
  36. package/dist/data/migrations/008_timer_target_ms.sql +5 -0
  37. package/dist/data/migrations/009_tasks.sql +22 -0
  38. package/dist/data/migrations/010_timer_task_id.sql +4 -0
  39. package/dist/data/migrations/011_profile_default_confirmed.sql +4 -0
  40. package/dist/data/migrations/012_identity_tables.sql +68 -0
  41. package/dist/data/migrations/013_identity_managed_by.sql +3 -0
  42. package/dist/data/migrations/014_task_difficulty_priority.sql +6 -0
  43. package/dist/data/migrations/015_timeblock_asked_at.sql +5 -0
  44. package/dist/data/migrations/016_intent_columns.sql +8 -0
  45. package/dist/data/migrations/017_ap_wallet.sql +25 -0
  46. package/dist/data/migrations/018_ap_rewards.sql +21 -0
  47. package/dist/data/migrations/019_ap_bounty.sql +10 -0
  48. package/dist/data/migrations/020_chat_turns.sql +10 -0
  49. package/dist/data/migrations/021_portrait.sql +4 -0
  50. package/dist/data/migrations/022_family_emoji_single.sql +3 -0
  51. package/dist/data/migrations/023_ap_balance_view_log.sql +9 -0
  52. package/dist/data/schema.sql +75 -0
  53. package/dist/knowledge/_registry/dimensions.yaml +10 -0
  54. package/dist/knowledge/_registry/personas.yaml +7 -0
  55. package/dist/knowledge/_schema/analysis-model.schema.js +32 -0
  56. package/dist/knowledge/_schema/entry.schema.js +45 -0
  57. package/dist/knowledge/_schema/persona.schema.js +23 -0
  58. package/dist/knowledge/_schema/scenario-pack.schema.js +29 -0
  59. package/dist/knowledge/analysis-models/review-default.yaml +16 -0
  60. package/dist/knowledge/analysis-models/review-summer-plan.yaml +15 -0
  61. package/dist/knowledge/brain-science/brain-deep-warmup.yaml +22 -0
  62. package/dist/knowledge/brain-science/brain-emotion-granularity.yaml +22 -0
  63. package/dist/knowledge/brain-science/brain-env-engineering.yaml +22 -0
  64. package/dist/knowledge/brain-science/brain-extended-mind.yaml +22 -0
  65. package/dist/knowledge/brain-science/brain-friction-barrier.yaml +22 -0
  66. package/dist/knowledge/brain-science/brain-peak-end.yaml +29 -0
  67. package/dist/knowledge/brain-science/brain-pomodoro.yaml +31 -0
  68. package/dist/knowledge/brain-science/brain-revenge-bedtime.yaml +22 -0
  69. package/dist/knowledge/brain-science/brain-single-variable.yaml +15 -0
  70. package/dist/knowledge/brain-science/brain-tiny-habits.yaml +22 -0
  71. package/dist/knowledge/energy/energy-active-recovery.yaml +22 -0
  72. package/dist/knowledge/energy/energy-deliberate-rest.yaml +22 -0
  73. package/dist/knowledge/energy/energy-exercise-embedded.yaml +22 -0
  74. package/dist/knowledge/energy/energy-fixed-wake-time.yaml +22 -0
  75. package/dist/knowledge/energy/energy-four-energy-radar.yaml +22 -0
  76. package/dist/knowledge/energy/energy-intensity-recovery.yaml +22 -0
  77. package/dist/knowledge/scenario-packs/pack-summer-kid.yaml +12 -0
  78. package/dist/knowledge/src/repo/fs-yaml.js +252 -0
  79. package/dist/knowledge/src/repo/types.js +1 -0
  80. package/dist/knowledge/time/time-batch-windows.yaml +22 -0
  81. package/dist/knowledge/time/time-conscious-abandon.yaml +22 -0
  82. package/dist/knowledge/time/time-deep-work-block.yaml +22 -0
  83. package/dist/knowledge/time/time-finite-commitment.yaml +22 -0
  84. package/dist/knowledge/time/time-forced-whitespace.yaml +22 -0
  85. package/dist/knowledge/time/time-gtd-next-action.yaml +22 -0
  86. package/dist/knowledge/time/time-three-tier-list.yaml +22 -0
  87. package/dist/mcp/cold-start.js +43 -0
  88. package/dist/mcp/contract/v1/rest.js +56 -0
  89. package/dist/mcp/rest-server.js +52 -0
  90. package/dist/mcp/server-core.js +1334 -0
  91. package/dist/mcp/server.js +34 -0
  92. package/dist/mcp/src/ap/index.js +14 -0
  93. package/dist/mcp/src/ap/rewards.js +44 -0
  94. package/dist/mcp/src/categories/index.js +12 -0
  95. package/dist/mcp/src/chat/from-env.js +111 -0
  96. package/dist/mcp/src/chat/history.js +35 -0
  97. package/dist/mcp/src/chat/loop.js +131 -0
  98. package/dist/mcp/src/chat/portrait.js +133 -0
  99. package/dist/mcp/src/chat/system-prompt.js +23 -0
  100. package/dist/mcp/src/chat/tool-names.js +27 -0
  101. package/dist/mcp/src/chat/tool-schema.js +20 -0
  102. package/dist/mcp/src/chat/types.js +1 -0
  103. package/dist/mcp/src/clock/index.js +78 -0
  104. package/dist/mcp/src/coachmod/index.js +135 -0
  105. package/dist/mcp/src/host-adapters/hermes-cron.js +185 -0
  106. package/dist/mcp/src/host-adapters/index.js +61 -0
  107. package/dist/mcp/src/host-adapters/types.js +7 -0
  108. package/dist/mcp/src/identity/equivalent-ids.js +41 -0
  109. package/dist/mcp/src/identity/in-memory.js +100 -0
  110. package/dist/mcp/src/identity/resolve.js +60 -0
  111. package/dist/mcp/src/identity/types.js +4 -0
  112. package/dist/mcp/src/matrix/index.js +15 -0
  113. package/dist/mcp/src/profile/confirm-default.js +48 -0
  114. package/dist/mcp/src/profile/index.js +298 -0
  115. package/dist/mcp/src/profile-confirm.js +28 -0
  116. package/dist/mcp/src/profile-helpers.js +109 -0
  117. package/dist/mcp/src/reminder/hermes-channel.js +40 -0
  118. package/dist/mcp/src/reminder/index.js +70 -0
  119. package/dist/mcp/src/reminder/push-channel.js +10 -0
  120. package/dist/mcp/src/repo/factory.js +34 -0
  121. package/dist/mcp/src/repo/in-memory.js +469 -0
  122. package/dist/mcp/src/repo/sqlite-ap.js +188 -0
  123. package/dist/mcp/src/repo/sqlite-helpers.js +39 -0
  124. package/dist/mcp/src/repo/sqlite-identity.js +129 -0
  125. package/dist/mcp/src/repo/sqlite.js +754 -0
  126. package/dist/mcp/src/repo/types.js +4 -0
  127. package/dist/mcp/src/rest/app.js +121 -0
  128. package/dist/mcp/src/rest/invoke-tool.js +98 -0
  129. package/dist/mcp/src/rest/short-token.js +38 -0
  130. package/dist/mcp/src/rest/tokens.js +55 -0
  131. package/dist/mcp/src/scheduler/index.js +319 -0
  132. package/dist/mcp/src/stats/index.js +29 -0
  133. package/dist/mcp/src/stickiness/report.js +174 -0
  134. package/dist/mcp/src/stickiness/types.js +1 -0
  135. package/dist/mcp/src/task/index.js +412 -0
  136. package/dist/mcp/src/timeblock/index.js +206 -0
  137. package/dist/mcp/src/timeline/index.js +705 -0
  138. package/dist/mcp/src/timer/index.js +234 -0
  139. package/dist/mcp/src/user-id-resolver.js +30 -0
  140. package/dist/mcp/src/weixin/app.js +97 -0
  141. package/dist/mcp/src/weixin/custom-send.js +82 -0
  142. package/dist/mcp/src/weixin/handle-text.js +49 -0
  143. package/dist/mcp/src/weixin/reminder-loop.js +39 -0
  144. package/dist/mcp/src/weixin/signature.js +13 -0
  145. package/dist/mcp/src/weixin/tencent-asr.js +101 -0
  146. package/dist/mcp/src/weixin/xml.js +37 -0
  147. package/dist/mcp/weixin-server.js +158 -0
  148. package/knowledge/_registry/dimensions.yaml +10 -0
  149. package/knowledge/_registry/personas.yaml +7 -0
  150. package/knowledge/_schema/analysis-model.schema.ts +36 -0
  151. package/knowledge/_schema/entry.schema.ts +50 -0
  152. package/knowledge/_schema/persona.schema.ts +30 -0
  153. package/knowledge/_schema/scenario-pack.schema.ts +33 -0
  154. package/knowledge/analysis-models/review-default.yaml +16 -0
  155. package/knowledge/analysis-models/review-summer-plan.yaml +15 -0
  156. package/knowledge/brain-science/brain-deep-warmup.yaml +22 -0
  157. package/knowledge/brain-science/brain-emotion-granularity.yaml +22 -0
  158. package/knowledge/brain-science/brain-env-engineering.yaml +22 -0
  159. package/knowledge/brain-science/brain-extended-mind.yaml +22 -0
  160. package/knowledge/brain-science/brain-friction-barrier.yaml +22 -0
  161. package/knowledge/brain-science/brain-peak-end.yaml +29 -0
  162. package/knowledge/brain-science/brain-pomodoro.yaml +31 -0
  163. package/knowledge/brain-science/brain-revenge-bedtime.yaml +22 -0
  164. package/knowledge/brain-science/brain-single-variable.yaml +15 -0
  165. package/knowledge/brain-science/brain-tiny-habits.yaml +22 -0
  166. package/knowledge/energy/energy-active-recovery.yaml +22 -0
  167. package/knowledge/energy/energy-deliberate-rest.yaml +22 -0
  168. package/knowledge/energy/energy-exercise-embedded.yaml +22 -0
  169. package/knowledge/energy/energy-fixed-wake-time.yaml +22 -0
  170. package/knowledge/energy/energy-four-energy-radar.yaml +22 -0
  171. package/knowledge/energy/energy-intensity-recovery.yaml +22 -0
  172. package/knowledge/scenario-packs/pack-summer-kid.yaml +12 -0
  173. package/knowledge/src/repo/fs-yaml.ts +282 -0
  174. package/knowledge/src/repo/types.ts +24 -0
  175. package/knowledge/tests/fixtures/base/_registry/dimensions.yaml +4 -0
  176. package/knowledge/tests/fixtures/base/time/valid-entry.yaml +24 -0
  177. package/knowledge/tests/fixtures/dup/_registry/dimensions.yaml +4 -0
  178. package/knowledge/tests/fixtures/dup/time/entry-a.yaml +13 -0
  179. package/knowledge/tests/fixtures/dup/time/entry-b.yaml +13 -0
  180. package/knowledge/tests/fixtures/unregistered/_registry/dimensions.yaml +7 -0
  181. package/knowledge/tests/fixtures/unregistered/time/anxiety-entry.yaml +13 -0
  182. package/knowledge/tests/repo/fs-yaml-knowledge-repo.test.ts +333 -0
  183. package/knowledge/time/time-batch-windows.yaml +22 -0
  184. package/knowledge/time/time-conscious-abandon.yaml +22 -0
  185. package/knowledge/time/time-deep-work-block.yaml +22 -0
  186. package/knowledge/time/time-finite-commitment.yaml +22 -0
  187. package/knowledge/time/time-forced-whitespace.yaml +22 -0
  188. package/knowledge/time/time-gtd-next-action.yaml +22 -0
  189. package/knowledge/time/time-three-tier-list.yaml +22 -0
  190. package/knowledge/validate.ts +50 -0
  191. package/package.json +76 -0
  192. package/scripts/postinstall-cold-start.js +45 -0
@@ -0,0 +1,22 @@
1
+ id: brain-extended-mind
2
+ kind: prescription
3
+ dimension: brain-science
4
+ title: 用身体思考
5
+ triggers:
6
+ signals:
7
+ - quadrant: 能耗黑洞
8
+ symptoms:
9
+ - 卡壳
10
+ - 灵感枯竭
11
+ prescription:
12
+ one_liner: 卡住时立刻起身走 10 分钟 + 手写关键问题 + 找人讲一遍
13
+ steps:
14
+ - 卡住时立刻起身
15
+ - 走 10 分钟(不戴耳机)
16
+ - 手写关键问题或找人讲一遍
17
+ micro_experiment: 下次卡壳时起身走 10 分钟
18
+ verify: 走动后是否能突破卡壳点
19
+ source:
20
+ ref: The Extended Mind (Annie Murphy Paul)
21
+ evidence_level: book
22
+ tags: [认知, 身体]
@@ -0,0 +1,22 @@
1
+ id: brain-friction-barrier
2
+ kind: prescription
3
+ dimension: brain-science
4
+ title: 增加行为摩擦力
5
+ triggers:
6
+ signals:
7
+ - quadrant: 能耗黑洞
8
+ symptoms:
9
+ - 刷视频/游戏过度
10
+ - 失控刷手机
11
+ prescription:
12
+ one_liner: 手机放另一个房间充电 + App 设时间限制 + 卸载最常刷的那个
13
+ steps:
14
+ - 手机放另一个房间充电
15
+ - 给最常刷的 App 设时间限制
16
+ - 考虑卸载最常刷的那个
17
+ micro_experiment: 今晚手机放客厅充电,卧室不放手机
18
+ verify: 一天中无意识刷手机的时长变化
19
+ source:
20
+ ref: 《多巴胺国度》(Dopamine Nation, Anna Lembke)
21
+ evidence_level: book
22
+ tags: [多巴胺, 行为设计]
@@ -0,0 +1,29 @@
1
+ id: brain-peak-end
2
+ kind: prescription
3
+ dimension: brain-science
4
+ title: 峰终定律——用峰值体验+强收尾设计子任务序列
5
+ triggers:
6
+ signals:
7
+ - quadrant: 能耗黑洞
8
+ symptoms:
9
+ - 长时间无正反馈
10
+ - 任务中途放弃
11
+ - 做完一大块却没成就感
12
+ prescription:
13
+ one_liner: 把子任务序列排成 前置一个快速小胜做峰 + 结尾一个可庆祝收尾做终
14
+ steps:
15
+ - 前端放一个 ≤5 分钟就能拿下的冷启动小胜,制造正反馈峰值
16
+ - 中段按循序渐进排,单块 ≤25 分钟
17
+ - 收尾子任务设计成明确完成、可庆祝的形态(如产出草稿或提交一次)
18
+ - 每完成一块立刻标记加一句鼓励,强化峰终记忆
19
+ micro_experiment: 选一个大任务,把第一块拆成 5 分钟内能拿下的小胜,做完立刻庆祝,观察后续启动阻力
20
+ verify: 序列完成后,主观成就感与干劲是否高于平铺直叙地做
21
+ source:
22
+ ref: 峰终定律(Kahneman, Fredrickson, Schreiber & Redelmeier, 1993)
23
+ evidence_level: research-observational
24
+ evidence_note: 原研究针对事后体验评价(痛觉与噪声实验);此处正向迁移到前向设计子任务序列,属合理外推而非直接 RCT
25
+ applicability:
26
+ boundaries:
27
+ - 原理讲事后回忆,用于事前设计是外推,别当铁律
28
+ - 若任务本身无明确胜利点(纯重复劳动),峰终设计收益有限
29
+ tags: [峰终定律, 正反馈, 子任务排序, 任务拆解]
@@ -0,0 +1,31 @@
1
+ id: brain-pomodoro
2
+ kind: prescription
3
+ dimension: brain-science
4
+ title: 番茄工作法
5
+ triggers:
6
+ signals:
7
+ - quadrant: 能耗黑洞
8
+ symptoms:
9
+ - 碎片化严重
10
+ - 频繁切换
11
+ - 任务启动困难
12
+ prescription:
13
+ one_liner: 25 分钟专注 + 5 分钟休息,休息期间集中回消息——既清了消息又不干扰专注
14
+ steps:
15
+ - 设定 25 分钟专注时段,只做一件事
16
+ - 时段内不切任务、不回消息(记到便签,不立刻处理)
17
+ - 5 分钟休息时集中处理积累的消息
18
+ - 循环
19
+ micro_experiment: 明天用一次番茄钟——25 分钟只做一件事,休息 5 分钟集中回消息
20
+ verify: 一天中任务切换次数是否下降、专注时段产出感知是否提升
21
+ source:
22
+ ref: 番茄工作法 (The Pomodoro Technique, Francesco Cirillo)
23
+ evidence_level: framework
24
+ evidence_note: 方法论框架,非单一 RCT 证据;P4 碎片化诊断的三个标准选项之一(另两个为环境工程/深度工作块)
25
+ applicability:
26
+ personas_fit: []
27
+ personas_avoid: []
28
+ boundaries:
29
+ - 对被强同步约束岗位(如客服、即时响应),25 分钟不可达窗口可能不现实
30
+ - 专注时长可按个人调整(部分人更适合 50/10 配比)
31
+ tags: [专注, 切换成本, 碎片化]
@@ -0,0 +1,22 @@
1
+ id: brain-revenge-bedtime
2
+ kind: prescription
3
+ dimension: brain-science
4
+ title: 给转场时刻设替代动作
5
+ triggers:
6
+ signals:
7
+ - quadrant: 能耗黑洞
8
+ symptoms:
9
+ - 报复性熬夜
10
+ - 不想结束这一天
11
+ prescription:
12
+ one_liner: 睡前 1 小时启动固定流程:断屏 → 洗漱 → 读纸质书 10 页
13
+ steps:
14
+ - 设定睡前 1 小时的闹钟
15
+ - 断屏(手机放客厅)
16
+ - 洗漱 → 读纸质书 10 页
17
+ micro_experiment: 今晚睡前 1 小时断屏+洗漱+读纸质书 10 页
18
+ verify: 实际入睡时间是否提前
19
+ source:
20
+ ref: Indistractable (Nir Eyal)
21
+ evidence_level: book
22
+ tags: [睡眠, 习惯设计]
@@ -0,0 +1,15 @@
1
+ id: brain-single-variable
2
+ kind: principle
3
+ dimension: brain-science
4
+ title: 单一动作原则
5
+ triggers:
6
+ symptoms:
7
+ - 想全部改
8
+ - 多个痛点同时存在
9
+ prescription:
10
+ one_liner: 一个微实验只含一个核心动作,等复查确认稳了再加第二个
11
+ micro_experiment: 每次只执行一个微实验
12
+ source:
13
+ ref: libero 内部设计原则(来自 coaching-framework §5.3)
14
+ evidence_level: framework
15
+ tags: [方法论, 单一变量]
@@ -0,0 +1,22 @@
1
+ id: brain-tiny-habits
2
+ kind: prescription
3
+ dimension: brain-science
4
+ title: B=MAP 微习惯配方
5
+ triggers:
6
+ signals:
7
+ - quadrant: 能耗黑洞
8
+ symptoms:
9
+ - 拖延
10
+ - 任务反复无进展
11
+ prescription:
12
+ one_liner: "After 我[现有行为], I will [30秒微动作] + 完成立刻握拳庆祝"
13
+ steps:
14
+ - 找到锚点行为(你已经在做的事)
15
+ - 设计 ≤30 秒的微动作
16
+ - 完成立刻庆祝
17
+ micro_experiment: 设计一个 B=MAP 微习惯配方,试 3 天
18
+ verify: 微习惯的连续完成天数
19
+ source:
20
+ ref: 《福格行为模型》(Tiny Habits, BJ Fogg)
21
+ evidence_level: book
22
+ tags: [习惯, 微习惯]
@@ -0,0 +1,22 @@
1
+ id: energy-active-recovery
2
+ kind: prescription
3
+ dimension: energy
4
+ title: 活动性恢复
5
+ triggers:
6
+ signals:
7
+ - quadrant: 能耗黑洞
8
+ symptoms:
9
+ - 午后低效
10
+ - 下午犯困
11
+ prescription:
12
+ one_liner: 每天下午安排一次 15 分钟散步/拉伸——不戴耳机,观察环境
13
+ steps:
14
+ - 下午 2-3 点安排 15 分钟恢复
15
+ - 散步或拉伸,不戴耳机
16
+ - 观察周围环境而非思考工作
17
+ micro_experiment: 明天下午安排 15 分钟不戴耳机的散步
18
+ verify: 散步后的精神状态和下午工作效率
19
+ source:
20
+ ref: 《倦怠》(Burnout, Emily & Amelia Nagoski)
21
+ evidence_level: book
22
+ tags: [恢复, 精力循环]
@@ -0,0 +1,22 @@
1
+ id: energy-deliberate-rest
2
+ kind: prescription
3
+ dimension: energy
4
+ title: 刻意休息
5
+ triggers:
6
+ signals:
7
+ - quadrant: 可放弃
8
+ symptoms:
9
+ - 周末恢复失效
10
+ - 刷屏式休息
11
+ prescription:
12
+ one_liner: 用散步/手工/园艺等"活动性恢复"替代刷屏式休息
13
+ steps:
14
+ - 识别你的"假休息"行为(刷手机/追剧等)
15
+ - 替换为活动性恢复(散步/手工/园艺)
16
+ - 周末至少一次刻意休息
17
+ micro_experiment: 这个周末用一次散步替代一次刷手机
18
+ verify: 活动性恢复后的精力感知 vs 刷屏后的精力感知
19
+ source:
20
+ ref: 《休息的艺术》(The Art of Rest, Claudia Hammond)
21
+ evidence_level: book
22
+ tags: [休息, 恢复]
@@ -0,0 +1,22 @@
1
+ id: energy-exercise-embedded
2
+ kind: prescription
3
+ dimension: energy
4
+ title: 运动嵌入日程
5
+ triggers:
6
+ signals:
7
+ - quadrant: 可放弃
8
+ symptoms:
9
+ - 运动缺失
10
+ - 精力不足
11
+ prescription:
12
+ one_liner: 从频率开始而非强度:每周固定 3 次,每次 20 分钟快走即可
13
+ steps:
14
+ - 选定每周 3 个固定时间
15
+ - 每次 20 分钟快走(不追求强度)
16
+ - 只关注"是否做了"不关注"做得多好"
17
+ micro_experiment: 本周固定 3 次 20 分钟快走
18
+ verify: 运动后精力感知是否改善
19
+ source:
20
+ ref: 《运动改造大脑》(Spark, John Ratey)
21
+ evidence_level: book
22
+ tags: [运动, 精力]
@@ -0,0 +1,22 @@
1
+ id: energy-fixed-wake-time
2
+ kind: prescription
3
+ dimension: energy
4
+ title: 先固化起床时间
5
+ triggers:
6
+ signals:
7
+ - quadrant: 可放弃
8
+ symptoms:
9
+ - 睡眠缺失
10
+ - 作息混乱
11
+ prescription:
12
+ one_liner: 连续两周固定起床时间(如 7:00),起床后立刻接触自然光 5 分钟;睡前一小时断屏
13
+ steps:
14
+ - 选定一个起床时间(如 7:00)
15
+ - 起床后立刻接触自然光 5 分钟
16
+ - 睡前一小时断屏
17
+ micro_experiment: 连续两周固定 7:00 起床+起床后自然光 5 分钟
18
+ verify: 两周后入睡时间和睡眠质量的变化
19
+ source:
20
+ ref: 《为什么我们要睡觉》(Why We Sleep, Matthew Walker)
21
+ evidence_level: book
22
+ tags: [睡眠, 节律]
@@ -0,0 +1,22 @@
1
+ id: energy-four-energy-radar
2
+ kind: prescription
3
+ dimension: energy
4
+ title: 四类精力雷达图
5
+ triggers:
6
+ signals:
7
+ - quadrant: 能耗黑洞
8
+ symptoms:
9
+ - 整体评分趋势下降
10
+ - 倦怠
11
+ prescription:
12
+ one_liner: 身体/情绪/心智/意义各打分 1-10,找最低维度先修
13
+ steps:
14
+ - 给身体/情绪/心智/意义各打 1-10 分
15
+ - 找出最低维度
16
+ - 针对最低维度选一条处方
17
+ micro_experiment: 今晚给四类精力各打分,找出最低维度
18
+ verify: 一周后重新打分看是否改善
19
+ source:
20
+ ref: 《精力管理》(The Power of Full Engagement, Jim Loehr & Tony Schwartz)
21
+ evidence_level: book
22
+ tags: [精力管理, 自评]
@@ -0,0 +1,22 @@
1
+ id: energy-intensity-recovery
2
+ kind: prescription
3
+ dimension: energy
4
+ title: 强度+恢复交替
5
+ triggers:
6
+ signals:
7
+ - quadrant: 能耗黑洞
8
+ symptoms:
9
+ - 连续高强度无恢复
10
+ - 精力透支
11
+ prescription:
12
+ one_liner: 高强度 1-1.5 小时后强制物理走动 5-10 分钟
13
+ steps:
14
+ - 设定 60-90 分钟高强度工作块
15
+ - 时间到强制起身物理走动 5-10 分钟
16
+ - 循环
17
+ micro_experiment: 明天每工作 90 分钟后强制走动 5 分钟
18
+ verify: 一天结束时的疲惫感是否低于平时
19
+ source:
20
+ ref: Peak Performance (Brad Stulberg & Steve Magness)
21
+ evidence_level: book
22
+ tags: [恢复, 节奏]
@@ -0,0 +1,12 @@
1
+ id: pack-summer-kid
2
+ kind: scenario-pack
3
+ title: 暑期计划(小学生)
4
+ triggers:
5
+ context_tags: [小学生, 暑假, 帮孩子, 暑期, 孩子]
6
+ recommends:
7
+ persona_id: kid-primary-school
8
+ analysis_model_ids: [review-summer-plan]
9
+ subskill_prompt: |
10
+ 对象是小学生 + 家长协作:语言更具体、目标更小、
11
+ 强调玩与学平衡、尊重孩子自主,不把家长焦虑转嫁孩子。
12
+ description: 家长帮小学生规划/复盘暑假的情境包
@@ -0,0 +1,252 @@
1
+ import { readFileSync, readdirSync, existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import yaml from "js-yaml";
4
+ import { validateEntry } from "../../_schema/entry.schema.js";
5
+ import { validateAnalysisModel } from "../../_schema/analysis-model.schema.js";
6
+ import { validateScenarioPack } from "../../_schema/scenario-pack.schema.js";
7
+ import { validatePersonaRegistry } from "../../_schema/persona.schema.js";
8
+ /** Repository root dir (two levels up from knowledge/src/repo/ → knowledge/) */
9
+ function defaultBasePath() {
10
+ // When running via tsx, import.meta.dirname is the dir of this file
11
+ return join(import.meta.dirname, "..", "..");
12
+ }
13
+ export class FsYamlKnowledgeRepo {
14
+ basePath;
15
+ _all = null;
16
+ _dimensions = null;
17
+ _analysisModels = null;
18
+ _scenarioPacks = null;
19
+ _personas = null;
20
+ constructor(basePath) {
21
+ this.basePath = basePath ?? defaultBasePath();
22
+ }
23
+ /** Load the dimensions registry from _registry/dimensions.yaml */
24
+ loadDimensions() {
25
+ if (this._dimensions)
26
+ return this._dimensions;
27
+ const path = join(this.basePath, "_registry", "dimensions.yaml");
28
+ if (!existsSync(path)) {
29
+ throw new Error(`维度注册表不存在: ${path}`);
30
+ }
31
+ const raw = yaml.load(readFileSync(path, "utf-8"));
32
+ if (!raw || !Array.isArray(raw.dimensions)) {
33
+ throw new Error(`维度注册表格式错误: ${path}`);
34
+ }
35
+ const dims = raw.dimensions.map((d) => d.id);
36
+ this._dimensions = dims;
37
+ return dims;
38
+ }
39
+ /** Collect all .yaml file paths under basePath, excluding _schema/, _registry/ and tests/ */
40
+ collectYamlFiles(dir, root) {
41
+ const files = [];
42
+ const entries = readdirSync(dir, { withFileTypes: true });
43
+ for (const entry of entries) {
44
+ const fullPath = join(dir, entry.name);
45
+ if (entry.isDirectory()) {
46
+ // Skip non-content directories.
47
+ // analysis-models/ 与 scenario-packs/ 是 COACH-MOD 新增内容类型,
48
+ // 用独立 schema(非 knowledgeEntrySchema),不能被 loadAll 当处方条目校验,
49
+ // 否则 validate 报错 / T13 迁移等价性断言崩。它们由 loadAnalysisModels
50
+ // / loadScenarioPacks 单独加载。
51
+ if (entry.name === "_schema" ||
52
+ entry.name === "_registry" ||
53
+ entry.name === "tests" ||
54
+ entry.name === "analysis-models" ||
55
+ entry.name === "scenario-packs")
56
+ continue;
57
+ files.push(...this.collectYamlFiles(fullPath, root));
58
+ }
59
+ else if (entry.isFile() && entry.name.endsWith(".yaml")) {
60
+ files.push(fullPath);
61
+ }
62
+ }
63
+ return files;
64
+ }
65
+ async loadAll() {
66
+ if (this._all)
67
+ return this._all;
68
+ // Load registry first
69
+ const validDimensions = this.loadDimensions();
70
+ const yamlFiles = this.collectYamlFiles(this.basePath, this.basePath);
71
+ const entries = [];
72
+ const seenIds = new Set();
73
+ for (const filePath of yamlFiles) {
74
+ const raw = yaml.load(readFileSync(filePath, "utf-8"));
75
+ const entry = validateEntry(raw);
76
+ // Check dimension is registered
77
+ if (!validDimensions.includes(entry.dimension)) {
78
+ throw new Error(`维度 "${entry.dimension}" 未在 _registry/dimensions.yaml 中登记 ` +
79
+ `(文件: ${filePath})`);
80
+ }
81
+ // Check duplicate ID
82
+ if (seenIds.has(entry.id)) {
83
+ throw new Error(`重复 ID: "${entry.id}" (文件: ${filePath})`);
84
+ }
85
+ seenIds.add(entry.id);
86
+ entries.push(entry);
87
+ }
88
+ this._all = entries;
89
+ return entries;
90
+ }
91
+ async getById(id) {
92
+ const entries = await this.loadAll();
93
+ return entries.find((e) => e.id === id) ?? null;
94
+ }
95
+ async byDimension(dimension) {
96
+ const entries = await this.loadAll();
97
+ return entries.filter((e) => e.dimension === dimension);
98
+ }
99
+ async matchBySignal(signal) {
100
+ const entries = await this.loadAll();
101
+ return entries.filter((e) => {
102
+ const signals = e.triggers.signals ?? [];
103
+ return signals.some((s) => {
104
+ // Quadrant match: exact
105
+ if (signal.quadrant && s.quadrant) {
106
+ if (s.quadrant !== signal.quadrant)
107
+ return false;
108
+ }
109
+ else if (signal.quadrant && !s.quadrant) {
110
+ return false;
111
+ }
112
+ // Daily total minutes: parse threshold
113
+ if (signal.daily_total_minutes && s.daily_total_minutes) {
114
+ const sv = parseThreshold(s.daily_total_minutes);
115
+ const qv = parseThreshold(signal.daily_total_minutes);
116
+ if (sv === null || qv === null) {
117
+ // If we can't parse, fall back to string equality
118
+ if (s.daily_total_minutes !== signal.daily_total_minutes)
119
+ return false;
120
+ }
121
+ else if (!matchesThreshold(s.daily_total_minutes, signal.daily_total_minutes)) {
122
+ return false;
123
+ }
124
+ }
125
+ else if (signal.daily_total_minutes && !s.daily_total_minutes) {
126
+ return false;
127
+ }
128
+ // If neither signal field is being queried, no match
129
+ if (!signal.quadrant && !signal.daily_total_minutes)
130
+ return false;
131
+ return true;
132
+ });
133
+ });
134
+ }
135
+ async matchBySymptom(symptom) {
136
+ const entries = await this.loadAll();
137
+ const lowerSymptom = symptom.toLowerCase();
138
+ return entries.filter((e) => {
139
+ const symptoms = e.triggers.symptoms ?? [];
140
+ return symptoms.some((s) => s.toLowerCase().includes(lowerSymptom));
141
+ });
142
+ }
143
+ /** Collect .yaml files directly under one content subdir (non-recursive). */
144
+ collectDirYamlFiles(subdir) {
145
+ const dir = join(this.basePath, subdir);
146
+ if (!existsSync(dir))
147
+ return [];
148
+ return readdirSync(dir, { withFileTypes: true })
149
+ .filter((e) => e.isFile() && e.name.endsWith(".yaml"))
150
+ .map((e) => join(dir, e.name));
151
+ }
152
+ /** COACH-MOD: load all analysis models from analysis-models/. */
153
+ async loadAnalysisModels() {
154
+ if (this._analysisModels)
155
+ return this._analysisModels;
156
+ const files = this.collectDirYamlFiles("analysis-models");
157
+ const models = [];
158
+ const seenIds = new Set();
159
+ for (const filePath of files) {
160
+ const raw = yaml.load(readFileSync(filePath, "utf-8"));
161
+ const model = validateAnalysisModel(raw);
162
+ if (seenIds.has(model.id)) {
163
+ throw new Error(`重复分析模型 ID: "${model.id}" (文件: ${filePath})`);
164
+ }
165
+ seenIds.add(model.id);
166
+ models.push(model);
167
+ }
168
+ this._analysisModels = models;
169
+ return models;
170
+ }
171
+ /** COACH-MOD: load all scenario packs from scenario-packs/. */
172
+ async loadScenarioPacks() {
173
+ if (this._scenarioPacks)
174
+ return this._scenarioPacks;
175
+ const files = this.collectDirYamlFiles("scenario-packs");
176
+ const packs = [];
177
+ const seenIds = new Set();
178
+ for (const filePath of files) {
179
+ const raw = yaml.load(readFileSync(filePath, "utf-8"));
180
+ const pack = validateScenarioPack(raw);
181
+ if (seenIds.has(pack.id)) {
182
+ throw new Error(`重复场景包 ID: "${pack.id}" (文件: ${filePath})`);
183
+ }
184
+ seenIds.add(pack.id);
185
+ packs.push(pack);
186
+ }
187
+ this._scenarioPacks = packs;
188
+ return packs;
189
+ }
190
+ /** COACH-MOD: load personas from _registry/personas.yaml. */
191
+ async loadPersonas() {
192
+ if (this._personas)
193
+ return this._personas;
194
+ const path = join(this.basePath, "_registry", "personas.yaml");
195
+ if (!existsSync(path)) {
196
+ this._personas = [];
197
+ return [];
198
+ }
199
+ const raw = yaml.load(readFileSync(path, "utf-8"));
200
+ const { personas } = validatePersonaRegistry(raw ?? {});
201
+ const seenIds = new Set();
202
+ for (const p of personas) {
203
+ if (seenIds.has(p.id)) {
204
+ throw new Error(`重复画像 ID: "${p.id}" (文件: ${path})`);
205
+ }
206
+ seenIds.add(p.id);
207
+ }
208
+ this._personas = personas;
209
+ return personas;
210
+ }
211
+ /**
212
+ * COACH-MOD: return the single default analysis model (is_default: true).
213
+ * §4.5 显式声明:0 个或 >1 个默认都抛错(不静默返回 undefined / 第一个),
214
+ * 因为"复盘默认装一个基线"是硬约束(spec §2 ①原则·基线)。
215
+ */
216
+ async getDefaultAnalysisModel() {
217
+ const models = await this.loadAnalysisModels();
218
+ const defaults = models.filter((m) => m.is_default);
219
+ if (defaults.length === 0) {
220
+ throw new Error("没有默认分析模型(需要恰好一个 is_default: true)");
221
+ }
222
+ if (defaults.length > 1) {
223
+ throw new Error(`默认分析模型不唯一:${defaults.map((m) => m.id).join(", ")}(需要恰好一个 is_default: true)`);
224
+ }
225
+ return defaults[0];
226
+ }
227
+ }
228
+ /** Parse a threshold string like ">600" into { op: ">", value: 600 } */
229
+ function parseThreshold(s) {
230
+ const match = s.match(/^([><=]?)\s*(\d+)$/);
231
+ if (!match)
232
+ return null;
233
+ return { op: match[1] || ">=", value: parseInt(match[2], 10) };
234
+ }
235
+ /** Check if the entry's daily_total_minutes matches the query threshold */
236
+ function matchesThreshold(entryValue, queryValue) {
237
+ const pv = parseThreshold(queryValue);
238
+ if (!pv)
239
+ return entryValue === queryValue;
240
+ // For entry values that are plain numbers or threshold expressions
241
+ const entryMatch = entryValue.match(/^(\d+)$/);
242
+ if (entryMatch) {
243
+ const num = parseInt(entryMatch[1], 10);
244
+ switch (pv.op) {
245
+ case ">": return num > pv.value;
246
+ case "<": return num < pv.value;
247
+ case "=": return num === pv.value;
248
+ default: return num >= pv.value;
249
+ }
250
+ }
251
+ return entryValue === queryValue;
252
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,22 @@
1
+ id: time-batch-windows
2
+ kind: prescription
3
+ dimension: time
4
+ title: 窗口期批处理
5
+ triggers:
6
+ signals:
7
+ - quadrant: 能耗黑洞
8
+ symptoms:
9
+ - 浅薄工作占比大
10
+ - 消息太多
11
+ prescription:
12
+ one_liner: 邮件/消息每天只在固定 2 个时段处理,其余时间默认不可达
13
+ steps:
14
+ - 选定 2 个批处理时段(如 11:00 和 16:00)
15
+ - 批处理时段集中回邮件/消息
16
+ - 其余时间关闭通知
17
+ micro_experiment: 明天只在 11:00 和 16:00 各花 15 分钟处理消息
18
+ verify: 一天中被消息打断的次数是否显著下降
19
+ source:
20
+ ref: 《深度工作》(Deep Work, Cal Newport)
21
+ evidence_level: book
22
+ tags: [批处理, 消息管理]
@@ -0,0 +1,22 @@
1
+ id: time-conscious-abandon
2
+ kind: prescription
3
+ dimension: time
4
+ title: 有意识的放弃
5
+ triggers:
6
+ signals:
7
+ - quadrant: 可放弃
8
+ symptoms:
9
+ - 可放弃事项多
10
+ - 做减法
11
+ prescription:
12
+ one_liner: 选一个低分分类,直接砍掉或砍半。空出来的时间不填新东西——感受"留白"
13
+ steps:
14
+ - 找出可放弃象限中耗时最长但满意度最低的 1 个分类
15
+ - 直接砍掉或砍半
16
+ - 空出来的时间不填新东西
17
+ micro_experiment: 选一个低分分类砍掉,空出来的时间不填新东西
18
+ verify: 一周后看总耗时是否下降、满意度是否提升
19
+ source:
20
+ ref: 《四千周》(Four Thousand Weeks, Oliver Burkeman)
21
+ evidence_level: book
22
+ tags: [做减法, 放弃]
@@ -0,0 +1,22 @@
1
+ id: time-deep-work-block
2
+ kind: prescription
3
+ dimension: time
4
+ title: 深度工作块
5
+ triggers:
6
+ signals:
7
+ - quadrant: 能耗黑洞
8
+ symptoms:
9
+ - 碎片化严重
10
+ - 频繁切换
11
+ prescription:
12
+ one_liner: 每天锁定 1-1.5 小时无干扰深度时段:关通知、手机放抽屉、只做一件事
13
+ steps:
14
+ - 选定每天的深度时段(如上午 9:00-10:30)
15
+ - 关掉所有通知,手机放抽屉
16
+ - 只做一件需要深度思考的事
17
+ micro_experiment: 明天上午锁定 90 分钟无干扰深度工作,关通知+手机放抽屉
18
+ verify: 深度工作块后的产出感和满意度
19
+ source:
20
+ ref: 《深度工作》(Deep Work, Cal Newport)
21
+ evidence_level: book
22
+ tags: [专注, 深度工作]
@@ -0,0 +1,22 @@
1
+ id: time-finite-commitment
2
+ kind: prescription
3
+ dimension: time
4
+ title: 有限承诺清单
5
+ triggers:
6
+ signals:
7
+ - quadrant: 能耗黑洞
8
+ symptoms:
9
+ - 承诺过多
10
+ - 焦虑忙乱
11
+ prescription:
12
+ one_liner: 列出 3-5 个核心承诺,新任务进入前必须先挤掉一个旧的
13
+ steps:
14
+ - 写下当前所有在进行的承诺
15
+ - 只保留最重要的 3-5 个为"核心承诺层"
16
+ - 任何新任务进入,必须先从核心层挤掉一个
17
+ micro_experiment: 本周把活跃承诺压到 ≤5 个,新任务来必须先删一个旧的
18
+ verify: 一周后看高投入低满足分类的耗时是否下降
19
+ source:
20
+ ref: 《四千周》(Four Thousand Weeks, Oliver Burkeman)
21
+ evidence_level: book
22
+ tags: [做减法, 承诺管理]