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,206 @@
1
+ import { effectiveUserId, lookupTargetUserLabel, resolveTargetUserLabel, } from "../profile-helpers.js";
2
+ import { needsConfirmIfMissing, } from "../profile-confirm.js";
3
+ function labelFor(db, userId) {
4
+ if (db)
5
+ return lookupTargetUserLabel(db, userId);
6
+ return resolveTargetUserLabel(userId);
7
+ }
8
+ export function createTimeBlockTools(repo, db) {
9
+ return {
10
+ async create(input) {
11
+ if (!input.title || input.title.trim() === "") {
12
+ throw new Error("事件名不能为空");
13
+ }
14
+ if (input.rating !== undefined && (input.rating < 1 || input.rating > 5)) {
15
+ throw new Error("评分必须在 1-5 之间");
16
+ }
17
+ if (input.status !== undefined && !["planned", "unverified", "completed"].includes(input.status)) {
18
+ throw new Error("status 只能为 planned / unverified / completed(MV-COACH-3 Slice 4 用户主权模型)");
19
+ }
20
+ if (input.start_time > input.end_time) {
21
+ throw new Error("开始时间不能晚于结束时间");
22
+ }
23
+ const userId = effectiveUserId(input);
24
+ const userExists = await repo.userExists(userId);
25
+ const gate = needsConfirmIfMissing(userExists, userId);
26
+ if (gate)
27
+ return gate;
28
+ const status = input.status ?? "completed";
29
+ const existing = await repo.findExactWindow({
30
+ user_id: userId,
31
+ title: input.title,
32
+ start: input.start_time,
33
+ end: input.end_time,
34
+ status,
35
+ });
36
+ if (existing) {
37
+ return { ...existing, target_user_label: labelFor(db, userId) };
38
+ }
39
+ const row = await repo.create({ ...input, user_id: userId, status });
40
+ return { ...row, target_user_label: labelFor(db, userId) };
41
+ },
42
+ async getById(id, userId) {
43
+ const row = await repo.getById(id);
44
+ // S41 multi-user isolation: 如果调用方传了 user_id,校验 ownership。
45
+ // 没传 user_id = 旧行为(单用户 / 兼容路径),不阻塞。
46
+ if (row && userId && row.user_id !== userId) {
47
+ return null;
48
+ }
49
+ return row;
50
+ },
51
+ async list(filters) {
52
+ if (!filters.user_id) {
53
+ throw new Error("user_id 为必填参数");
54
+ }
55
+ const userId = effectiveUserId(filters);
56
+ return repo.list({ ...filters, user_id: userId });
57
+ },
58
+ async update(id, input) {
59
+ const existing = await repo.getById(id);
60
+ if (!existing) {
61
+ throw new Error("时间块不存在");
62
+ }
63
+ const checkUserId = input.target_user_id ?? existing.user_id;
64
+ const profileOk = await repo.userExists(checkUserId);
65
+ const gate = needsConfirmIfMissing(profileOk, checkUserId);
66
+ if (gate)
67
+ return gate;
68
+ if (input.rating !== undefined && (input.rating < 1 || input.rating > 5)) {
69
+ throw new Error("评分必须在 1-5 之间");
70
+ }
71
+ if (input.status !== undefined && !["planned", "unverified", "completed"].includes(input.status)) {
72
+ throw new Error("status 只能为 planned / unverified / completed(MV-COACH-3 Slice 4 用户主权模型)");
73
+ }
74
+ // Bug 1 修复(2026-07-31,MV-COACH-3 Slice 4 v6):
75
+ // 禁止 completed → unverified。实测证据:追问 cron-session LLM 在 7/30 14:15 把
76
+ // 已 completed 的 schedule(id 5097e1b9)改回了 unverified,破坏状态机可信度。
77
+ // 用户主权铁律:completed 是用户确认的终态,cron/LLM 不许往回改。
78
+ // 允许 completed → planned(用户主动改期/取消是合法的,保留旧测试通过)。
79
+ if (existing.status === "completed" &&
80
+ input.status === "unverified") {
81
+ throw new Error("不可从 completed 改回 unverified(用户主权终态保护·Bug 1)。" +
82
+ "completed 是用户已确认执行的状态,只有用户主动改期/撤回才能改 status。");
83
+ }
84
+ const newStart = input.start_time ?? existing.start_time;
85
+ const newEnd = input.end_time ?? existing.end_time;
86
+ if (newStart > newEnd) {
87
+ throw new Error("开始时间不能晚于结束时间");
88
+ }
89
+ const { target_user_id: _t, ...patch } = input;
90
+ void _t;
91
+ const row = await repo.update(id, patch);
92
+ return {
93
+ ...row,
94
+ target_user_label: labelFor(db, checkUserId),
95
+ };
96
+ },
97
+ async remove(id, opts) {
98
+ if (opts?.target_user_id) {
99
+ const profileOk = await repo.userExists(opts.target_user_id);
100
+ const gate = needsConfirmIfMissing(profileOk, opts.target_user_id);
101
+ if (gate)
102
+ return gate;
103
+ }
104
+ const existing = await repo.getById(id);
105
+ let labelUserId = opts?.target_user_id ?? existing?.user_id;
106
+ if (!opts?.target_user_id && existing) {
107
+ const profileOk = await repo.userExists(existing.user_id);
108
+ const gate = needsConfirmIfMissing(profileOk, existing.user_id);
109
+ if (gate)
110
+ return gate;
111
+ }
112
+ const exists = await repo.exists(id);
113
+ if (!exists) {
114
+ throw new Error("时间块不存在");
115
+ }
116
+ // Soft-deleted rows: getById is null; recover user_id for label via db
117
+ if (!labelUserId && db) {
118
+ const row = db
119
+ .prepare(`SELECT user_id FROM time_blocks WHERE id = ?`)
120
+ .get(id);
121
+ labelUserId = row?.user_id;
122
+ }
123
+ await repo.remove(id);
124
+ return {
125
+ target_user_label: labelFor(db, labelUserId ?? id),
126
+ };
127
+ },
128
+ async restore(id) {
129
+ return repo.restore(id);
130
+ },
131
+ /**
132
+ * S43(2026-08-07)+ S48(2026-08-11):扫描某用户过期未确认的 timeblock,分组返回。
133
+ *
134
+ * 用途:cron-session 每 30min 调一次,让 cron LLM 显式调 timeblock.update
135
+ * 升级状态 + 主动问。本工具**不**直接改 db(保留 brain/hand 分离 + 用户主权模型)。
136
+ *
137
+ * 判定逻辑(以 now 为基准):
138
+ * - end_time + overdue_min_to_unverified (默认 30min) 仍 planned → to_unverified
139
+ * - end_time + overdue_min_to_ask (默认 60min) 仍 unverified/planned,**且 asked_at IS NULL**(S48:每条只问一次)→ to_ask
140
+ * - completed / 未过期 / 软删 / asked_at 已标记的 → 都不进 to_ask
141
+ *
142
+ * §4.5 静默折叠声明:纯查询,无副作用,无折叠。caller 发完追问后必须调 markAsked 幂等标记。
143
+ */
144
+ async sweepStale(input) {
145
+ if (!input.user_id) {
146
+ throw new Error("user_id 为必填参数");
147
+ }
148
+ const nowIso = input.now ?? new Date().toISOString();
149
+ const nowMs = new Date(nowIso).getTime();
150
+ const thresholdUnverifiedMin = input.overdue_min_to_unverified ?? 30;
151
+ const thresholdAskMin = input.overdue_min_to_ask ?? 60;
152
+ const thresholdUnverifiedMs = thresholdUnverifiedMin * 60 * 1000;
153
+ const thresholdAskMs = thresholdAskMin * 60 * 1000;
154
+ // 用 list 拿到该用户所有非软删的块(list 默认会过滤 deleted_at)
155
+ const blocks = await repo.list({
156
+ user_id: input.user_id,
157
+ });
158
+ const to_unverified = [];
159
+ const to_ask = [];
160
+ for (const b of blocks) {
161
+ if (b.deleted_at)
162
+ continue;
163
+ if (b.status === "completed")
164
+ continue;
165
+ const endMs = new Date(b.end_time).getTime();
166
+ if (Number.isNaN(endMs))
167
+ continue;
168
+ const ageMs = nowMs - endMs;
169
+ if (ageMs <= 0)
170
+ continue; // 还没到 end_time
171
+ const overdueUnverified = ageMs >= thresholdUnverifiedMs;
172
+ const overdueAsk = ageMs >= thresholdAskMs;
173
+ if (overdueUnverified && b.status === "planned") {
174
+ to_unverified.push({
175
+ id: b.id,
176
+ title: b.title,
177
+ start_time: b.start_time,
178
+ end_time: b.end_time,
179
+ });
180
+ }
181
+ // S48 幂等:asked_at 已标记的不再进 to_ask(每条只被扫描 cron 主动问一次)
182
+ if (overdueAsk && (b.status === "unverified" || b.status === "planned") && !b.asked_at) {
183
+ to_ask.push({
184
+ id: b.id,
185
+ title: b.title,
186
+ start_time: b.start_time,
187
+ end_time: b.end_time,
188
+ status: b.status,
189
+ });
190
+ }
191
+ }
192
+ return { to_unverified, to_ask, now: nowIso };
193
+ },
194
+ /**
195
+ * S48(2026-08-11):标记扫描追问已发——幂等保护。
196
+ * caller(cron-scan skill)发完追问后必须调用,写入 asked_at 时间戳。
197
+ * 返回受影响行数(用于 caller 自检)。无副作用之外的折叠(asked_at 永久保留作审计)。
198
+ */
199
+ async markAsked(ids) {
200
+ if (!ids || ids.length === 0)
201
+ return { marked: 0 };
202
+ const marked = await repo.markAsked(ids);
203
+ return { marked };
204
+ },
205
+ };
206
+ }