skill-schedule 0.3.3 → 0.3.12

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 (182) hide show
  1. package/SKILL.md +12 -3
  2. package/dist/.gen-inputs.json +4 -4
  3. package/dist/admin/adminDocs.d.ts +57 -0
  4. package/dist/admin/adminDocs.d.ts.map +1 -0
  5. package/dist/admin/adminDocs.js +190 -0
  6. package/dist/admin/adminDocs.js.map +1 -0
  7. package/dist/admin/adminParts.d.ts +37 -0
  8. package/dist/admin/adminParts.d.ts.map +1 -0
  9. package/dist/admin/adminParts.js +83 -0
  10. package/dist/admin/adminParts.js.map +1 -0
  11. package/dist/admin/handlers.d.ts.map +1 -1
  12. package/dist/admin/handlers.js +196 -6
  13. package/dist/admin/handlers.js.map +1 -1
  14. package/dist/admin/routes.d.ts +10 -1
  15. package/dist/admin/routes.d.ts.map +1 -1
  16. package/dist/admin/routes.js +2 -0
  17. package/dist/admin/routes.js.map +1 -1
  18. package/dist/analyze/analyzeDocs.d.ts +51 -0
  19. package/dist/analyze/analyzeDocs.d.ts.map +1 -0
  20. package/dist/analyze/analyzeDocs.js +442 -0
  21. package/dist/analyze/analyzeDocs.js.map +1 -0
  22. package/dist/analyze/analyzeParts.d.ts +53 -0
  23. package/dist/analyze/analyzeParts.d.ts.map +1 -0
  24. package/dist/analyze/analyzeParts.js +229 -0
  25. package/dist/analyze/analyzeParts.js.map +1 -0
  26. package/dist/analyze/handlers.d.ts.map +1 -1
  27. package/dist/analyze/handlers.js +41 -4
  28. package/dist/analyze/handlers.js.map +1 -1
  29. package/dist/cli/cmd_read.js +8 -2
  30. package/dist/cli/cmd_read.js.map +1 -1
  31. package/dist/fetch/feishu.d.ts +6 -0
  32. package/dist/fetch/feishu.d.ts.map +1 -1
  33. package/dist/fetch/feishu.js +18 -7
  34. package/dist/fetch/feishu.js.map +1 -1
  35. package/dist/fetch/index.d.ts +1 -1
  36. package/dist/fetch/index.d.ts.map +1 -1
  37. package/dist/fetch/index.js +1 -1
  38. package/dist/fetch/index.js.map +1 -1
  39. package/dist/health.d.ts.map +1 -1
  40. package/dist/health.js +8 -5
  41. package/dist/health.js.map +1 -1
  42. package/dist/help/index.d.ts +1 -0
  43. package/dist/help/index.d.ts.map +1 -1
  44. package/dist/help/index.js +3 -0
  45. package/dist/help/index.js.map +1 -1
  46. package/dist/plan/discussDocs.d.ts +8 -0
  47. package/dist/plan/discussDocs.d.ts.map +1 -0
  48. package/dist/plan/discussDocs.js +321 -0
  49. package/dist/plan/discussDocs.js.map +1 -0
  50. package/dist/plan/feishuDocs.d.ts +19 -0
  51. package/dist/plan/feishuDocs.d.ts.map +1 -0
  52. package/dist/plan/feishuDocs.js +257 -0
  53. package/dist/plan/feishuDocs.js.map +1 -0
  54. package/dist/plan/handlers.d.ts.map +1 -1
  55. package/dist/plan/handlers.js +107 -3
  56. package/dist/plan/handlers.js.map +1 -1
  57. package/dist/plan/index.d.ts +2 -0
  58. package/dist/plan/index.d.ts.map +1 -1
  59. package/dist/plan/index.js +16 -9
  60. package/dist/plan/index.js.map +1 -1
  61. package/dist/plan/iso.d.ts +2 -0
  62. package/dist/plan/iso.d.ts.map +1 -1
  63. package/dist/plan/iso.js +6 -2
  64. package/dist/plan/iso.js.map +1 -1
  65. package/dist/plan/planDocs.d.ts +47 -0
  66. package/dist/plan/planDocs.d.ts.map +1 -0
  67. package/dist/plan/planDocs.js +159 -0
  68. package/dist/plan/planDocs.js.map +1 -0
  69. package/dist/plan/planParts.d.ts +38 -0
  70. package/dist/plan/planParts.d.ts.map +1 -0
  71. package/dist/plan/planParts.js +96 -0
  72. package/dist/plan/planParts.js.map +1 -0
  73. package/dist/plan/probe.d.ts +28 -0
  74. package/dist/plan/probe.d.ts.map +1 -0
  75. package/dist/plan/probe.js +114 -0
  76. package/dist/plan/probe.js.map +1 -0
  77. package/dist/plan/receipt.d.ts +12 -0
  78. package/dist/plan/receipt.d.ts.map +1 -1
  79. package/dist/plan/receipt.js +17 -0
  80. package/dist/plan/receipt.js.map +1 -1
  81. package/dist/plan/receiptDocs.d.ts +26 -0
  82. package/dist/plan/receiptDocs.d.ts.map +1 -0
  83. package/dist/plan/receiptDocs.js +341 -0
  84. package/dist/plan/receiptDocs.js.map +1 -0
  85. package/dist/plan/replayDocs.d.ts +165 -0
  86. package/dist/plan/replayDocs.d.ts.map +1 -0
  87. package/dist/plan/replayDocs.js +226 -0
  88. package/dist/plan/replayDocs.js.map +1 -0
  89. package/dist/plan/replaySections.d.ts +5 -0
  90. package/dist/plan/replaySections.d.ts.map +1 -0
  91. package/dist/plan/replaySections.js +471 -0
  92. package/dist/plan/replaySections.js.map +1 -0
  93. package/dist/plan/reviewDocs.d.ts +4 -0
  94. package/dist/plan/reviewDocs.d.ts.map +1 -0
  95. package/dist/plan/reviewDocs.js +130 -0
  96. package/dist/plan/reviewDocs.js.map +1 -0
  97. package/dist/plan/sync.d.ts.map +1 -1
  98. package/dist/plan/sync.js +5 -0
  99. package/dist/plan/sync.js.map +1 -1
  100. package/dist/policy/index.d.ts +1 -1
  101. package/dist/policy/index.d.ts.map +1 -1
  102. package/dist/policy/index.js +1 -1
  103. package/dist/policy/index.js.map +1 -1
  104. package/dist/policy/plan.d.ts +8 -0
  105. package/dist/policy/plan.d.ts.map +1 -1
  106. package/dist/policy/plan.js +20 -0
  107. package/dist/policy/plan.js.map +1 -1
  108. package/dist/query/handlers.d.ts +3 -0
  109. package/dist/query/handlers.d.ts.map +1 -1
  110. package/dist/query/handlers.js +86 -12
  111. package/dist/query/handlers.js.map +1 -1
  112. package/dist/query/queryDocs.d.ts +64 -0
  113. package/dist/query/queryDocs.d.ts.map +1 -0
  114. package/dist/query/queryDocs.js +554 -0
  115. package/dist/query/queryDocs.js.map +1 -0
  116. package/dist/query/routes.d.ts +11 -1
  117. package/dist/query/routes.d.ts.map +1 -1
  118. package/dist/query/routes.js +5 -1
  119. package/dist/query/routes.js.map +1 -1
  120. package/dist/render/copyArea.d.ts +61 -0
  121. package/dist/render/copyArea.d.ts.map +1 -0
  122. package/dist/render/copyArea.js +80 -0
  123. package/dist/render/copyArea.js.map +1 -0
  124. package/dist/render/html.d.ts.map +1 -1
  125. package/dist/render/html.js +3 -1
  126. package/dist/render/html.js.map +1 -1
  127. package/dist/render/index.d.ts +3 -0
  128. package/dist/render/index.d.ts.map +1 -1
  129. package/dist/render/index.js +2 -0
  130. package/dist/render/index.js.map +1 -1
  131. package/dist/shared/dayPage.d.ts +67 -0
  132. package/dist/shared/dayPage.d.ts.map +1 -0
  133. package/dist/shared/dayPage.js +92 -0
  134. package/dist/shared/dayPage.js.map +1 -0
  135. package/dist/shared/detailPage.d.ts +55 -0
  136. package/dist/shared/detailPage.d.ts.map +1 -0
  137. package/dist/shared/detailPage.js +65 -0
  138. package/dist/shared/detailPage.js.map +1 -0
  139. package/dist/shared/docPage.d.ts +22 -0
  140. package/dist/shared/docPage.d.ts.map +1 -0
  141. package/dist/shared/docPage.js +52 -0
  142. package/dist/shared/docPage.js.map +1 -0
  143. package/dist/shared/overviewPage.d.ts +52 -0
  144. package/dist/shared/overviewPage.d.ts.map +1 -0
  145. package/dist/shared/overviewPage.js +65 -0
  146. package/dist/shared/overviewPage.js.map +1 -0
  147. package/dist/shared/pageNav.d.ts +24 -0
  148. package/dist/shared/pageNav.d.ts.map +1 -0
  149. package/dist/shared/pageNav.js +70 -0
  150. package/dist/shared/pageNav.js.map +1 -0
  151. package/dist/shared/pageParts.d.ts +45 -0
  152. package/dist/shared/pageParts.d.ts.map +1 -0
  153. package/dist/shared/pageParts.js +154 -0
  154. package/dist/shared/pageParts.js.map +1 -0
  155. package/dist/shared/planPage.d.ts +49 -0
  156. package/dist/shared/planPage.d.ts.map +1 -0
  157. package/dist/shared/planPage.js +48 -0
  158. package/dist/shared/planPage.js.map +1 -0
  159. package/dist/shared/rangePage.d.ts +44 -0
  160. package/dist/shared/rangePage.d.ts.map +1 -0
  161. package/dist/shared/rangePage.js +50 -0
  162. package/dist/shared/rangePage.js.map +1 -0
  163. package/dist/shared/weekPage.d.ts +36 -0
  164. package/dist/shared/weekPage.d.ts.map +1 -0
  165. package/dist/shared/weekPage.js +42 -0
  166. package/dist/shared/weekPage.js.map +1 -0
  167. package/dist/triggers/routes.generated.d.ts +23 -1
  168. package/dist/triggers/routes.generated.d.ts.map +1 -1
  169. package/dist/triggers/routes.generated.js +4 -1
  170. package/dist/triggers/routes.generated.js.map +1 -1
  171. package/dist/write/handlers.d.ts.map +1 -1
  172. package/dist/write/handlers.js +101 -5
  173. package/dist/write/handlers.js.map +1 -1
  174. package/dist/write/writeDocs.d.ts +27 -0
  175. package/dist/write/writeDocs.d.ts.map +1 -0
  176. package/dist/write/writeDocs.js +423 -0
  177. package/dist/write/writeDocs.js.map +1 -0
  178. package/dist/write/writeParts.d.ts +54 -0
  179. package/dist/write/writeParts.d.ts.map +1 -0
  180. package/dist/write/writeParts.js +117 -0
  181. package/dist/write/writeParts.js.map +1 -0
  182. package/package.json +3 -3
@@ -0,0 +1,257 @@
1
+ /** #788 · 飞书两条唤醒词的**两张页**:能力探测(只读)与日程管家同步(回执)。
2
+ *
3
+ * 为什么两张分开(照老侧的分工,也与 #787 的接缝对上):
4
+ * · 「飞书探测」(`op=sync` + `dryRun`)——**先看**:三档能力门探一遍,一门写都不发;
5
+ * · 「日程管家同步」(`op=sync`)——**执行**:回填标识、补齐远端、清孤儿,然后把这一趟做了什么
6
+ * 分格报出来。老侧那种「写之前先问一句」的交互,落在这两张页的分工上:要问就先跑探测,
7
+ * 要写就说同步(#787 的证据件把这一问划给了本票)。
8
+ *
9
+ * **页上文案纪律**:不出现命令键、库列名、参数名、票号与远端对象标识(那一串是内部标识,只进回执,
10
+ * 不进页);并列关系用读数卡与表格表达,不拿 `·`/`;`/`|`/`、`/`~` 顶替。
11
+ */
12
+ import { renderCaliberLine, renderConclusionBar, renderDataTable, renderFeedbackBlock, renderKpiGrid, renderListRows, renderPreBlock, } from 'base-paint/blocks';
13
+ import { renderFactStrip } from 'base-paint';
14
+ import { listPlanEvents, shortLarkVersion } from '../fetch/index.js';
15
+ import { fmtDurShort, l1Of } from '../policy/index.js';
16
+ import { scheduleCopyArea } from '../render/copyArea.js';
17
+ import { assembleDocPage } from '../shared/docPage.js';
18
+ import { pageSections } from '../shared/pageNav.js';
19
+ import { minutesOfDayEnd } from './planDocs.js';
20
+ import { planPartsCss, renderSectionTitle } from './planParts.js';
21
+ import { REMOTE_LABEL, planCopyArea } from './receipt.js';
22
+ import { TIER_CN, TIER_NEXT, TIER_VALUE } from './probe.js';
23
+ const EYEBROW = '作息管家 日程与计划';
24
+ /** 外部来的原话(命令行 stderr、回执 message、错误串)上屏前过分隔符门(#516):
25
+ * 页自己的文案本来就照纪律写,这几处是**别的进程吐出来的字**——真让它把 `/`/`、` 带上屏,
26
+ * 就是设计债进门。做法是把那几种并列符号换成行文逗号,只动上屏这一份,回执载荷一字不改。 */
27
+ function plain(text) {
28
+ return text
29
+ .replace(/[·;;||//、+~~]/g, ',')
30
+ .replace(/,{2,}/g, ',')
31
+ .replace(/,([))】」])/g, '$1');
32
+ }
33
+ /** 事实条「命令行版本」只印数字(口径唯一定义地是 `fetch` 门的 `shortLarkVersion`)。
34
+ * `null`(没装)印「没装」,`unknown`/无数字印「读不到」。 */
35
+ /** 同步回执的分格(`runSync` 的 `counts`)在页上的名字与读法,一处定义。 */
36
+ const COUNT_LABELS = [
37
+ { key: 'backfilled', label: '回填标识', hint: '远端本来就有但本地缺标识的,这一趟认回来的' },
38
+ { key: 'created', label: '远端新建', hint: '本地有但远端没有,这一趟补上去的' },
39
+ { key: 'updated', label: '远端改动', hint: '两边标题或备注不一样,按本地那一条改过去的' },
40
+ { key: 'timeSynced', label: '时段回写', hint: '你在飞书里改过时段,尊重你,把它写回本地的' },
41
+ { key: 'deleted', label: '远端清理', hint: '孤儿与同槽冗余,这一趟清掉的' },
42
+ { key: 'pastSkipped', label: '过去日期跳过', hint: '昨天以前的计划不补建,免得死灰复燃' },
43
+ { key: 'duplicates', label: '同槽冗余', hint: '同一时段里历史留下的重复对象' },
44
+ { key: 'failed', label: '失败', hint: '这一趟没成的那几件' },
45
+ ];
46
+ function eventRows(events) {
47
+ return events.map((p) => ({
48
+ time: p.time_start + ' 至 ' + p.time_end,
49
+ title: p.title,
50
+ category: l1Of(p.category ?? ''),
51
+ remote: p.feishu_event_id === null ? '没同步过' : '已同步飞书',
52
+ }));
53
+ }
54
+ function localCounts(handle, date) {
55
+ const events = listPlanEvents(handle, date);
56
+ return {
57
+ total: events.length,
58
+ synced: events.filter((p) => p.feishu_event_id !== null).length,
59
+ minutes: events.reduce((sum, p) => sum + Math.max(0, minutesOfDayEnd(p.time_end) - minutesOfDayEnd(p.time_start)), 0),
60
+ };
61
+ }
62
+ /* ─────────────────────── ① 飞书探测(只读,三档) ─────────────────────── */
63
+ /** 「飞书探测」整页:三档结论 + 下一步 + 本地这一天的账(**这一趟没写任何对象**)。
64
+ *
65
+ * #896 · 「授权登录过」与进度条读 `report.authenticated`(布尔位),不读 `report.openId` 原值:
66
+ * 回执不带 openId 原串(隐私),`handlers.ts` 重建时 `openId` 置 null 仅占形状,显示以布尔位为准。
67
+ */
68
+ export function probePage(handle, date, report) {
69
+ const local = localCounts(handle, date);
70
+ const kpis = [
71
+ { label: '能力档位', value: TIER_VALUE[report.tier], detail: plain(report.why) },
72
+ { label: '这一天本地计划', value: String(local.total), unit: '条', detail: '共 ' + fmtDurShort(local.minutes) },
73
+ { label: '带远端标识的', value: String(local.synced), unit: '条', detail: '同步过的那些' },
74
+ {
75
+ label: '这一趟写了几笔',
76
+ value: '0',
77
+ detail: '只读探测,远端一行没动',
78
+ // 三档全通时给满,其余档按三门过了几门给(读数同源:探测结果那一份)。
79
+ // #896 · 读 authenticated 布尔位,不读 openId 原值(回执不带原串,见 probe.ts 件头)。
80
+ bar: { pct: Math.round(([report.cliPath === null ? 0 : 1, report.authenticated ? 1 : 0, report.calendar ? 1 : 0]
81
+ .reduce((a, b) => a + b, 0) / 3) * 100) },
82
+ },
83
+ ];
84
+ const head = {
85
+ docTitle: '作息管家 飞书探测',
86
+ eyebrow: EYEBROW,
87
+ title: '飞书探测',
88
+ subtitle: '看本机的飞书能力到哪一档,以及 ' + date + ' 这一天本地排了什么。这一步只读,不写任何对象。',
89
+ };
90
+ const steps = [
91
+ { step: '装有命令行', state: report.cliPath === null ? '没找到' : '在场', why: report.cliPath === null ? '家目录与查找路径里都没有' : '找到了可执行文件' },
92
+ { step: '授权登录过', state: report.authenticated ? '过了' : '没过', why: report.authenticated ? '查到了登录身份' : '终端里查不到登录身份' },
93
+ { step: '日历拉得动', state: report.calendar ? '拉得动' : '拉不动', why: report.calendar ? '今日议程这一问有回应' : '今日议程那一问没成' },
94
+ ];
95
+ const { toc, body } = pageSections([
96
+ { navText: '这一趟探测的结论', html: renderKpiGrid(kpis, { title: '这一趟探测的结论' }) },
97
+ { html: renderConclusionBar('飞书能力:' + TIER_CN[report.tier] + '。' + plain(report.why)
98
+ + '。要动远端就说「日程管家同步」,要留个只读的快照就是这一页。') },
99
+ { navText: '三道门逐道看', html: renderSectionTitle('三道门逐道看')
100
+ + renderDataTable({
101
+ columns: [
102
+ { key: 'step', label: '探什么' },
103
+ { key: 'state', label: '结果' },
104
+ { key: 'why', label: '怎么看出来的' },
105
+ ],
106
+ rows: steps,
107
+ }) },
108
+ { html: renderFactStrip({
109
+ items: [
110
+ { label: '命令行版本', value: report.version === null ? '没装' : shortLarkVersion(report.version) },
111
+ { label: '探测日期', value: date },
112
+ { label: '本地这一天的计划', value: String(local.total) + ' 条' },
113
+ { label: '远端这一趟', value: '没碰' },
114
+ ],
115
+ }) },
116
+ { navText: '下一步怎么走', html: renderSectionTitle('下一步怎么走')
117
+ + renderListRows({
118
+ items: TIER_NEXT[report.tier].map((text) => ({ main: text })),
119
+ emptyText: '没有下一步',
120
+ }) },
121
+ { navText: '本地这一天的账', html: renderSectionTitle('本地这一天的账')
122
+ + '<p class="sch-pl-note">这一份读的是本地库:这一天排了几条计划,其中几条已经带上远端标识。远端那一边这一趟没拉,故不报对方的条数。</p>'
123
+ + renderDataTable({
124
+ columns: [
125
+ { key: 'time', label: '时段' },
126
+ { key: 'title', label: '计划' },
127
+ { key: 'category', label: '分类' },
128
+ { key: 'remote', label: '远端标识' },
129
+ ],
130
+ rows: eventRows(listPlanEvents(handle, date)),
131
+ emptyText: '这一天本地没有计划',
132
+ })
133
+ + renderCaliberLine('探测只读,三道门都只问不写,本地库这一趟也没动过') },
134
+ { html: renderPreBlock({
135
+ label: '要真同步就说这一句',
136
+ command: '同步 ' + date + ' 的日程到飞书',
137
+ actionId: 'ilife-sch-probe-copy-next',
138
+ copyLabel: '复制这句话',
139
+ }) },
140
+ { navText: '复制与留档', html: scheduleCopyArea({
141
+ title: '复制与留档',
142
+ dataActionId: 'ilife-sch-probe-copy-data',
143
+ logActionId: 'ilife-sch-probe-copy-log',
144
+ ...planCopyArea({
145
+ message: '飞书探测:日期 ' + date + ',档位 ' + TIER_CN[report.tier] + ',原因 ' + report.why
146
+ + ',本地这一天计划 ' + String(local.total) + ' 条、带远端标识 ' + String(local.synced) + ' 条,这一趟写入 0 笔',
147
+ command: 'schedule-cmd-read schedule.plan.write --params {"op":"sync","dryRun":true,"date":"' + date + '"}',
148
+ source: '本机命令行探测与本地日程计划表',
149
+ }),
150
+ }) },
151
+ ]);
152
+ return assembleDocPage({ head, content: toc + body, extraCss: planPartsCss() });
153
+ }
154
+ /** 这一趟的结论(页自己的句子,不照抄回执那一串以并列符号分隔的计数):
155
+ * 远端在场就报对齐结果,远端没成/跳过也照实说,失败数单独点名。 */
156
+ function syncConclusion(payload) {
157
+ const c = payload.counts;
158
+ const moved = (c.backfilled ?? 0) + (c.created ?? 0) + (c.updated ?? 0) + (c.timeSynced ?? 0) + (c.deleted ?? 0);
159
+ const head = payload.remote === 'unavailable'
160
+ ? '这一趟远端没成,本地那边没有改动。'
161
+ : (moved === 0 ? '两边本来就是对得上,这一趟没有要动的东西。' : '这一趟一共动了 ' + String(moved) + ' 处。');
162
+ const parts = [
163
+ '回填标识 ' + String(c.backfilled ?? 0) + ' 笔',
164
+ '远端新建 ' + String(c.created ?? 0) + ' 笔',
165
+ '远端改动 ' + String(c.updated ?? 0) + ' 笔',
166
+ '时段回写 ' + String(c.timeSynced ?? 0) + ' 笔',
167
+ '远端清理 ' + String(c.deleted ?? 0) + ' 笔',
168
+ ].join(',');
169
+ const tail = (c.failed ?? 0) === 0
170
+ ? '失败 0 笔。'
171
+ : '失败 ' + String(c.failed ?? 0) + ' 笔,逐条在下面。';
172
+ return head + parts + '。' + tail;
173
+ }
174
+ /** 「日程管家同步」整页:这一趟做了什么分格报出来,没成的逐条点名。 */
175
+ export function syncPage(handle, date, payload) {
176
+ const events = listPlanEvents(handle, date);
177
+ const failed = payload.counts.failed ?? 0;
178
+ const kpis = COUNT_LABELS.map((c) => ({
179
+ label: c.label,
180
+ value: String(payload.counts[c.key] ?? 0),
181
+ unit: '笔',
182
+ detail: c.hint,
183
+ }));
184
+ const { toc, body } = pageSections([
185
+ { navText: '这一趟的账', html: renderKpiGrid(kpis, { title: '这一趟的账' }) },
186
+ { html: renderConclusionBar(syncConclusion(payload)) },
187
+ { html: renderFactStrip({
188
+ items: [
189
+ { label: '同步的日期', value: date },
190
+ { label: '远端侧', value: REMOTE_LABEL[payload.remote] },
191
+ { label: '本地这一天的计划', value: String(events.length) + ' 条' },
192
+ { label: '没成的', value: String(failed) + ' 笔' },
193
+ ],
194
+ }) },
195
+ { navText: '这一趟的结果', html: renderFeedbackBlock({
196
+ title: '这一趟的结果',
197
+ toast: failed === 0
198
+ ? { icon: payload.remote === 'unavailable' ? 'warn' : 'ok', msg: plain(payload.message) }
199
+ : { icon: 'danger', msg: plain(payload.message), lines: payload.errors.map(plain) },
200
+ staticNotice: true,
201
+ }) },
202
+ { navText: payload.notes.length === 0 ? '' : '顺带记下的', html: payload.notes.length === 0 ? '' : renderSectionTitle('顺带记下的')
203
+ + renderListRows({ items: payload.notes.map((text) => ({ main: plain(text) })), emptyText: '没有顺带记下的' }) },
204
+ { navText: payload.errors.length === 0 ? '' : '没成的逐条名单', html: payload.errors.length === 0 ? '' : renderSectionTitle('没成的逐条名单')
205
+ + renderListRows({ items: payload.errors.map((text) => ({ main: plain(text) })), emptyText: '没有没成的' }) },
206
+ { navText: '本地这一天的排布', html: renderSectionTitle('本地这一天的排布')
207
+ + renderCaliberLine('远端只动带归属标记的对象,你在飞书日历上自己加的那些一律不碰')
208
+ + renderDataTable({
209
+ columns: [
210
+ { key: 'time', label: '时段' },
211
+ { key: 'title', label: '计划' },
212
+ { key: 'category', label: '分类' },
213
+ { key: 'remote', label: '远端标识' },
214
+ ],
215
+ rows: eventRows(events),
216
+ emptyText: '这一天本地没有计划',
217
+ }) },
218
+ { navText: '下一步', html: renderSectionTitle('下一步')
219
+ + renderListRows({
220
+ items: [
221
+ { main: '要看另一天的差异,把日期一并说清楚,比如「同步 2026-09-22 的日程」。' },
222
+ { main: '只想先看一眼而不动远端,就说「飞书探测」,那一页只读。' },
223
+ ],
224
+ emptyText: '没有下一步',
225
+ }) },
226
+ { html: renderPreBlock({
227
+ label: '再同步一天就说这一句',
228
+ command: '同步 ' + date + ' 的日程到飞书',
229
+ actionId: 'ilife-sch-sync-copy-next',
230
+ copyLabel: '复制这句话',
231
+ }) },
232
+ { navText: '复制与留档', html: scheduleCopyArea({
233
+ title: '复制与留档',
234
+ dataActionId: 'ilife-sch-sync-copy-data',
235
+ logActionId: 'ilife-sch-sync-copy-log',
236
+ ...planCopyArea({
237
+ message: '日程管家同步:日期 ' + date + ',' + payload.message + ','
238
+ + COUNT_LABELS.map((c) => c.label + ' ' + String(payload.counts[c.key] ?? 0) + ' 笔').join(',')
239
+ + (payload.errors.length === 0 ? '' : ',没成的 ' + payload.errors.join(',')),
240
+ command: 'schedule-cmd-read schedule.plan.write --params {"op":"sync","date":"' + date + '"}',
241
+ source: '本地日程计划表与飞书日历',
242
+ ok: payload.errors.length === 0,
243
+ }),
244
+ }) },
245
+ ]);
246
+ return assembleDocPage({
247
+ head: {
248
+ docTitle: '作息管家 日程管家同步',
249
+ eyebrow: EYEBROW,
250
+ title: '日程管家同步',
251
+ subtitle: date + ' 这一天本地与飞书对了一遍,这一页报的是这一趟真做了什么。',
252
+ },
253
+ content: toc + body,
254
+ extraCss: planPartsCss(),
255
+ });
256
+ }
257
+ //# sourceMappingURL=feishuDocs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feishuDocs.js","sourceRoot":"","sources":["../../src/plan/feishuDocs.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/plan/handlers.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAc7D,eAAO,MAAM,SAAS,EAAE,YAKvB,CAAC"}
1
+ {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/plan/handlers.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AA6H7D,eAAO,MAAM,SAAS,EAAE,YAMvB,CAAC"}
@@ -2,10 +2,23 @@
2
2
  *
3
3
  * 逐字搬自 `src/cli/cmd_read.ts` 的 switch 一臂 + 远端门(行为零改动)。
4
4
  * 写 op 全部统一成合成写(裁定 A6③):本地 +(可选)远端一条命令走完,回执分字段、退出码报达成与否。
5
+ *
6
+ * **#787 起这一臂多出「出页」那一半**(照 #783 写域的先例):写库之后各支出一张真页
7
+ * (`./receiptDocs.ts` 与 `./discussDocs.ts` 装配,件序列见那两件头)。回执载荷(`data`)与退出码口径
8
+ * 一行不改,追加的分字段只多不少。
9
+ *
10
+ * 页要的东西分两处拿:**写之前**的样貌(改前那一条、落盘前这一天的排布)在这一臂里先留一份
11
+ * (写完之后库里已经不是那个样子了);**写之后**的读数从回执载荷与库里现读。
5
12
  */
6
- import { larkReady } from '../fetch/index.js';
7
- import { parseFeishuMode, parsePlanOp } from '../policy/index.js';
13
+ import { getPlanEvent, larkReady, listPlanEvents } from '../fetch/index.js';
14
+ import { parseFeishuMode, parsePlanOp, resolveDateParam, validateUpdateInput, validateUpsertInput, } from '../policy/index.js';
8
15
  import { runPlanOp } from './index.js';
16
+ import { deactivateReceiptPage, ensureBatchReceiptPage, ensureReceiptPage, updateReceiptPage, } from './receiptDocs.js';
17
+ import { previewPage, resultPage } from './discussDocs.js';
18
+ import { replayPage } from './replaySections.js';
19
+ import { replayWindowOf } from './replayDocs.js';
20
+ import { reviewPage } from './reviewDocs.js';
21
+ import { probePage, syncPage } from './feishuDocs.js';
9
22
  /** 哪些 op 要碰远端(其余 op 连 lark-cli 都不探——探测本身是三次子进程)。 */
10
23
  const REMOTE_OPS = ['ensure', 'upsert', 'update', 'deactivate', 'sync', 'check'];
11
24
  /** 远端门:过了给 cliPath;没过给「为什么不在场」——**不拦本地写**,只如实进回执与退出码。 */
@@ -22,10 +35,101 @@ function remoteGate(op, params) {
22
35
  return { cli: null, why: e.message };
23
36
  }
24
37
  }
38
+ function preStateOf(op, params, handle) {
39
+ const none = { candidates: null, locked: [], beforeEvent: null, patchKeys: [] };
40
+ try {
41
+ if (op === 'preview' || op === 'upsert') {
42
+ const v = validateUpsertInput(params);
43
+ return { ...none, candidates: v, locked: listPlanEvents(handle, v.date) };
44
+ }
45
+ if (op === 'update') {
46
+ const v = validateUpdateInput(params);
47
+ return { ...none, beforeEvent: getPlanEvent(handle, v.id), patchKeys: Object.keys(v.patch) };
48
+ }
49
+ if (op === 'deactivate') {
50
+ return { ...none, beforeEvent: getPlanEvent(handle, Number(params.id)) };
51
+ }
52
+ }
53
+ catch {
54
+ // 参数不对时由各 op 自己的校验报那一句原话(本件只少出一块,不抢着报错)。
55
+ return none;
56
+ }
57
+ return none;
58
+ }
59
+ const remoteOf = (data) => (data.remote ?? 'none');
60
+ /** 各 op 写完之后那张页(不落页的两支——复盘与飞书那两条——回空串,照旧走模板页)。
61
+ *
62
+ * #788 起「复盘」与「飞书」两条各接上自己的整页:复盘按粒度分两族(裸词那一档是单日逐条标记,
63
+ * 四档是跨域对照与趋势那一张一体页),飞书按 `probe` 那一格分探测(只读)与同步回执两张。 */
64
+ function pageOf(op, handle, data, pre, params) {
65
+ if (op === 'preview' && pre.candidates !== null) {
66
+ return previewPage(handle, pre.candidates.date, pre.candidates.events);
67
+ }
68
+ if (op === 'upsert' && pre.candidates !== null) {
69
+ return resultPage(handle, pre.candidates.date, pre.candidates.events, pre.locked, remoteOf(data));
70
+ }
71
+ if (op === 'ensure') {
72
+ if (Array.isArray(data.items)) {
73
+ const days = data.items.map((d) => ({
74
+ date: String(d.date),
75
+ id: Number(d.id),
76
+ created: d.local === 'created',
77
+ remote: remoteOf(d),
78
+ achieved: d.achieved !== false,
79
+ }));
80
+ return ensureBatchReceiptPage(handle, days);
81
+ }
82
+ return ensureReceiptPage(handle, {
83
+ id: Number(data.id),
84
+ date: String(data.date),
85
+ created: data.local === 'created',
86
+ remote: remoteOf(data),
87
+ });
88
+ }
89
+ if (op === 'update' && pre.beforeEvent !== null) {
90
+ return updateReceiptPage(handle, pre.beforeEvent, getPlanEvent(handle, pre.beforeEvent.id), pre.patchKeys, remoteOf(data));
91
+ }
92
+ if (op === 'deactivate' && pre.beforeEvent !== null) {
93
+ return deactivateReceiptPage(handle, pre.beforeEvent, remoteOf(data));
94
+ }
95
+ if (op === 'review') {
96
+ // 裸词「复盘」=单日逐条标记那一张;四档(今日/本周/本月/区间)=一体页。
97
+ const granularity = params.granularity;
98
+ if (typeof granularity === 'string')
99
+ return replayPage(handle, replayWindowOf(granularity, params));
100
+ return reviewPage(handle, resolveDateParam(params));
101
+ }
102
+ if (op === 'sync') {
103
+ const date = resolveDateParam(params);
104
+ if (data.probe === true) {
105
+ return probePage(handle, date, {
106
+ tier: (data.tier ?? 'missing'),
107
+ cliPath: typeof data.cliPath === 'string' ? data.cliPath : null,
108
+ version: typeof data.cliVersion === 'string' ? data.cliVersion : null,
109
+ // #896 · openId 原串不进回执(隐私),重建置 null 仅占形状——页上「授权登录过」与进度条
110
+ // 读 `authenticated`(来自 `data.authReady`),不读它。写死 null 本身不是 bug,
111
+ // bug 是此前根本没传布尔位、页上又去读 openId 是否 null。
112
+ openId: null,
113
+ authenticated: data.authReady === true,
114
+ calendar: data.calendarReady === true,
115
+ why: String(data.tierWhy ?? ''),
116
+ });
117
+ }
118
+ return syncPage(handle, date, {
119
+ message: String(data.message ?? ''),
120
+ remote: remoteOf(data),
121
+ counts: (data.counts ?? {}),
122
+ notes: Array.isArray(data.notes) ? data.notes : [],
123
+ errors: Array.isArray(data.errors) ? data.errors : [],
124
+ });
125
+ }
126
+ return '';
127
+ }
25
128
  export const writePlan = (params, handle) => {
26
129
  const op = parsePlanOp(params);
27
130
  const gate = remoteGate(op, params);
131
+ const pre = preStateOf(op, params, handle);
28
132
  const out = runPlanOp(op, { handle, params, cli: gate.cli, remoteWhy: gate.why });
29
- return { data: out.data, html: '', exitCode: out.exitCode };
133
+ return { data: out.data, html: pageOf(op, handle, out.data, pre, params), exitCode: out.exitCode };
30
134
  };
31
135
  //# sourceMappingURL=handlers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/plan/handlers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,WAAW,EAAoB,MAAM,oBAAoB,CAAC;AACpF,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAIvC,oDAAoD;AACpD,MAAM,UAAU,GAAkB,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAEhG,yDAAyD;AACzD,SAAS,UAAU,CAAC,EAAe,EAAE,MAA+B;IAClE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;IAC9D,4DAA4D;IAC5D,IAAI,EAAE,KAAK,MAAM,IAAI,EAAE,KAAK,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,KAAK,MAAM;QAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;IAC3G,IAAI,CAAC;QAAC,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;IAAC,CAAC;IACvD,OAAO,CAAC,EAAE,CAAC;QAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC;IAAC,CAAC;AAChE,CAAC;AAED,MAAM,CAAC,MAAM,SAAS,GAAiB,CAAC,MAAM,EAAE,MAAkB,EAAE,EAAE;IACpE,MAAM,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG,UAAU,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,SAAS,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAClF,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;AAC9D,CAAC,CAAC"}
1
+ {"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/plan/handlers.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,8 @@ import { type PlanOpCtx, type PlanOpResult } from './context.js';
5
5
  export type { PlanOpCtx, PlanOpResult } from './context.js';
6
6
  export { buildPlanOverview } from './overview.js';
7
7
  export type { PlanOverviewPayload, PlanDayRow, PlanHourRow } from './overview.js';
8
+ export { eventsInWindow, renderPlanDayPage } from './planDocs.js';
9
+ export type { PlanDayPageOptions, PlanDaySearch } from './planDocs.js';
8
10
  /** `schedule.plan.write` 的唯一入口:把 op 分给各件,回执与退出码由各件给。 */
9
11
  export declare function runPlanOp(op: PlanWriteOp, ctx: PlanOpCtx): PlanOpResult;
10
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plan/index.ts"],"names":[],"mappings":"AAQA,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAE5B,OAAO,EAA0D,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC9G,OAAO,EAAiB,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAQhF,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,YAAY,EAAE,mBAAmB,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAoBlF,wDAAwD;AACxD,wBAAgB,SAAS,CAAC,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,SAAS,GAAG,YAAY,CAiBvE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plan/index.ts"],"names":[],"mappings":"AAQA,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAE5B,OAAO,EAA0D,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC9G,OAAO,EAAiB,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAShF,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,YAAY,EAAE,mBAAmB,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAGlF,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClE,YAAY,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAuBvE,wDAAwD;AACxD,wBAAgB,SAAS,CAAC,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE,SAAS,GAAG,YAAY,CAiBvE"}
@@ -9,7 +9,7 @@
9
9
  export * from './commands.js';
10
10
  export * from './routes.js';
11
11
  import { getPlanEventsRange, SchedulePolicyError } from '../fetch/index.js';
12
- import { resolveDateParam, resolveRangeParam, VALID_COMPLETIONS } from '../policy/index.js';
12
+ import { VALID_COMPLETIONS } from '../policy/index.js';
13
13
  import { receiptResult } from './context.js';
14
14
  import { buildReceipt } from './receipt.js';
15
15
  import { runEnsure, runEnsureBatch } from './ensure.js';
@@ -17,23 +17,30 @@ import { runPreview, runUpsert } from './upsert.js';
17
17
  import { runUpdate, runDeactivate } from './single.js';
18
18
  import { runSync } from './sync.js';
19
19
  import { runCheck } from './check.js';
20
+ import { dayWindow, replayWindowOf } from './replayDocs.js';
20
21
  export { buildPlanOverview } from './overview.js';
21
- /** #14 复盘:本地读,不碰远端(四粒度:day/week/month/range)。 */
22
+ // #786 · 「查日程」那一张页的口径(空档推算住本域:`plan` 侧与 `query` 侧都要用——f10 查日程页与
23
+ // f12 商量计划预览的空档提示是同一件事)经能力门出门,`query` 侧只走这个门、不深引用内部件。
24
+ export { eventsInWindow, renderPlanDayPage } from './planDocs.js';
25
+ /** #14 复盘:本地读,不碰远端(四粒度:day/week/month/range)。
26
+ *
27
+ * #788 起窗口口径**与页同源**:这一支的窗口与页装配件都走 `replayWindowOf`(页上画哪一段,
28
+ * 回执里就报哪一段)。此前这一支只按 `date` 参数算单日,于是「复盘本周」的页画了这一周、
29
+ * 回执却报当天——两处对不上。 */
22
30
  function runReview(ctx) {
23
- const { start, end } = ctx.params.granularity === 'range' || ctx.params.start !== undefined
24
- ? resolveRangeParam(ctx.params)
25
- : { start: resolveDateParam(ctx.params), end: resolveDateParam(ctx.params) };
26
- const events = getPlanEventsRange(ctx.handle, start, end);
31
+ const g = ctx.params.granularity;
32
+ const win = typeof g === 'string' ? replayWindowOf(g, ctx.params) : dayWindow(ctx.params);
33
+ const events = getPlanEventsRange(ctx.handle, win.start, win.end);
27
34
  const counts = {};
28
35
  for (const e of events)
29
36
  counts[e.completion || '未复盘'] = (counts[e.completion || '未复盘'] || 0) + 1;
30
37
  const parts = VALID_COMPLETIONS.filter((k) => counts[k]).map((k) => k + counts[k]);
31
38
  const message = events.length
32
- ? '已复盘 ' + start + '~' + end + ':' + events.length + ' 个事件(' + parts.join('、') + ')'
33
- : '复盘空:' + start + '~' + end + ' 没有日程事件(不是故障,是这天没排)';
39
+ ? '已复盘 ' + win.start + ' 至 ' + win.end + ':' + events.length + ' 个事件(' + parts.join(',') + ')'
40
+ : '复盘空:' + win.start + ' 至 ' + win.end + ' 没有日程事件(不是故障,是这一段没排)';
34
41
  return receiptResult(buildReceipt({
35
42
  op: 'review', message, local: 'reviewed', remote: 'none', remoteId: null,
36
- errors: [], date: start, dates: [start, end], counts: { events: events.length },
43
+ errors: [], date: win.start, dates: [win.start, win.end], counts: { events: events.length },
37
44
  }));
38
45
  }
39
46
  /** `schedule.plan.write` 的唯一入口:把 op 分给各件,回执与退出码由各件给。 */
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plan/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plan/index.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,8 @@
1
1
  export declare const TZ_SUFFIX = "+08:00";
2
2
  /** 分片拉取的窗口宽度(小时)。老家 `feishu_sync.py:522` 的 `timedelta(hours=6)`。 */
3
3
  export declare const SHARD_HOURS = 6;
4
+ /** 日期挪一天(正负都走这一个公式;`nextDay` 与历史窗口都用它,别处不许再抄一遍)。 */
5
+ export declare function shiftDay(date: string, delta: number): string;
4
6
  export declare function nextDay(date: string): string;
5
7
  /** 本地 (日期, HH:MM) → 飞书 ISO。`24:00` 换到次日 `00:00`(飞书日历不接受 24:00)。 */
6
8
  export declare function toFeishuISO(date: string, hhmm: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"iso.d.ts","sourceRoot":"","sources":["../../src/plan/iso.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,SAAS,WAAW,CAAC;AAClC,oEAAoE;AACpE,eAAO,MAAM,WAAW,IAAI,CAAC;AAI7B,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK5C;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAA2C;AAC5F,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAA2C;AAE1F,iCAAiC;AACjC,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI7C;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAA6B;AAE3E;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAI7F;AAED,mDAAmD;AACnD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,CAU3E;AAED,yCAAyC;AACzC,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAmD"}
1
+ {"version":3,"file":"iso.d.ts","sourceRoot":"","sources":["../../src/plan/iso.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,SAAS,WAAW,CAAC;AAClC,oEAAoE;AACpE,eAAO,MAAM,WAAW,IAAI,CAAC;AAI7B,oDAAoD;AACpD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAK5D;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAA2C;AAC5F,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAA2C;AAE1F,iCAAiC;AACjC,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI7C;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAA6B;AAE3E;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAI7F;AAED,mDAAmD;AACnD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,CAU3E;AAED,yCAAyC;AACzC,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAmD"}
package/dist/plan/iso.js CHANGED
@@ -6,12 +6,16 @@ export const TZ_SUFFIX = '+08:00';
6
6
  /** 分片拉取的窗口宽度(小时)。老家 `feishu_sync.py:522` 的 `timedelta(hours=6)`。 */
7
7
  export const SHARD_HOURS = 6;
8
8
  function pad(n) { return String(n).padStart(2, '0'); }
9
- export function nextDay(date) {
9
+ /** 日期挪一天(正负都走这一个公式;`nextDay` 与历史窗口都用它,别处不许再抄一遍)。 */
10
+ export function shiftDay(date, delta) {
10
11
  const [y, m, d] = date.split('-').map(Number);
11
12
  const t = new Date(y, m - 1, d);
12
- t.setDate(t.getDate() + 1);
13
+ t.setDate(t.getDate() + delta);
13
14
  return t.getFullYear() + '-' + pad(t.getMonth() + 1) + '-' + pad(t.getDate());
14
15
  }
16
+ export function nextDay(date) {
17
+ return shiftDay(date, 1);
18
+ }
15
19
  /** 本地 (日期, HH:MM) → 飞书 ISO。`24:00` 换到次日 `00:00`(飞书日历不接受 24:00)。 */
16
20
  export function toFeishuISO(date, hhmm) {
17
21
  if (hhmm === '24:00')
@@ -1 +1 @@
1
- {"version":3,"file":"iso.js","sourceRoot":"","sources":["../../src/plan/iso.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"iso.js","sourceRoot":"","sources":["../../src/plan/iso.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import type { PlanEvent } from '../fetch/db.js';
2
+ /** 钟点 → 分钟,且**这一天末尾那一格**按 24:00 算:末段写 `23:59` 与写 `24:00` 是同一件事
3
+ * (校验口径 `assertCoverage24h` 的原话:「末事件 time_end 必须为 24:00,当前 23:59 视同」),
4
+ * 而落盘的候选是**归一过**的(`normalizeTime` 把 `24:00` 改写成 `23:59`)。整日覆盖、空隙、
5
+ * 时长三处都按这一条算,否则「整天接满」会被读成「还差一分钟」。定义只此一处。 */
6
+ export declare const minutesOfDayEnd: (hhmm: string) => number;
7
+ /** 空档:未排事件的连续时段(按时间先后扫一遍,游标只前进;相邻或重叠都不断档)。
8
+ * #787 起本件对外给这一条:f12「商量计划预览」的**空隙提示**与 f10「查日程」的空档是同一件事,
9
+ * 两个用法都在本能力目录里,故仍只此一处(收的只是「有起止的东西」,不要求是库行)。 */
10
+ export declare function gapsOf(events: readonly {
11
+ readonly time_start: string;
12
+ readonly time_end: string;
13
+ }[]): {
14
+ readonly start: number;
15
+ readonly end: number;
16
+ }[];
17
+ /** 分钟数 → `HH:MM` 钟点(`24:00` 收尾):页上空档与空隙两处共用的写法,只此一处。 */
18
+ export declare const clockOf: (minutes: number) => string;
19
+ /** 按标题搜或按时段查重(本票两支,老侧都只出 JSON)。
20
+ *
21
+ * 为什么同一张页:两个查法都落在 `schedule.plan.today` 这一枚 key 上,出口只按 key 分派
22
+ * (路由表没给它们各自的预设),下游分不出是哪种查法——故一张页把两支都答全,
23
+ * 页头与结论条如实写明这一趟的查法,不让人猜这一页为什么只有几件。 */
24
+ export interface PlanDaySearch {
25
+ /** 按标题搜索时命中的那个词(原样上屏)。 */
26
+ readonly title?: string;
27
+ /** 按时段查重时那一对钟点。 */
28
+ readonly window?: {
29
+ readonly start: string;
30
+ readonly end: string;
31
+ };
32
+ /** 命中集合(进列表的那几行);全天的色带/空档/读数仍按 `events` 算。 */
33
+ readonly list: readonly PlanEvent[];
34
+ }
35
+ /** `renderPlanDayPage` 的可选位(不给=#782 那张样张页的件序列与读数)。 */
36
+ export interface PlanDayPageOptions {
37
+ /** 这一天**已软删**的事件(`is_active = 0`):上同一张页、行尾标「已软删」,结论条报条数。 */
38
+ readonly inactive?: readonly PlanEvent[];
39
+ readonly search?: PlanDaySearch;
40
+ }
41
+ /** 这一时段里有哪几件:与窗口**重叠**即算(起在前、止在后都算)。查重用,故不要求整段包住。 */
42
+ export declare function eventsInWindow(events: readonly PlanEvent[], start: string, end: string): PlanEvent[];
43
+ /** 「查日程」整页(形状=A 覆盖条+事件卡;老侧 f10 的三个必现块都在)。
44
+ *
45
+ * `events` 是**这一天的活跃事件**(读数/色带/空档都按它算);`opts.search.list` 只换列表那一段。 */
46
+ export declare function renderPlanDayPage(events: readonly PlanEvent[], date: string, opts?: PlanDayPageOptions): string;
47
+ //# sourceMappingURL=planDocs.d.ts.map