skill-schedule 0.1.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.
- package/dist/cli/cmd_read.d.ts +3 -0
- package/dist/cli/cmd_read.d.ts.map +1 -0
- package/dist/cli/cmd_read.js +312 -0
- package/dist/cli/cmd_read.js.map +1 -0
- package/dist/fetch/db.d.ts +97 -0
- package/dist/fetch/db.d.ts.map +1 -0
- package/dist/fetch/db.js +382 -0
- package/dist/fetch/db.js.map +1 -0
- package/dist/fetch/errors.d.ts +13 -0
- package/dist/fetch/errors.d.ts.map +1 -0
- package/dist/fetch/errors.js +18 -0
- package/dist/fetch/errors.js.map +1 -0
- package/dist/fetch/feishu.d.ts +36 -0
- package/dist/fetch/feishu.d.ts.map +1 -0
- package/dist/fetch/feishu.js +141 -0
- package/dist/fetch/feishu.js.map +1 -0
- package/dist/fetch/index.d.ts +7 -0
- package/dist/fetch/index.d.ts.map +1 -0
- package/dist/fetch/index.js +5 -0
- package/dist/fetch/index.js.map +1 -0
- package/dist/fetch/paths.d.ts +6 -0
- package/dist/fetch/paths.d.ts.map +1 -0
- package/dist/fetch/paths.js +31 -0
- package/dist/fetch/paths.js.map +1 -0
- package/dist/help/index.d.ts +3 -0
- package/dist/help/index.d.ts.map +1 -0
- package/dist/help/index.js +2 -0
- package/dist/help/index.js.map +1 -0
- package/dist/help/lookup.d.ts +11 -0
- package/dist/help/lookup.d.ts.map +1 -0
- package/dist/help/lookup.js +39 -0
- package/dist/help/lookup.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/policy/category.d.ts +29 -0
- package/dist/policy/category.d.ts.map +1 -0
- package/dist/policy/category.js +168 -0
- package/dist/policy/category.js.map +1 -0
- package/dist/policy/index.d.ts +10 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +6 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/plan.d.ts +26 -0
- package/dist/policy/plan.d.ts.map +1 -0
- package/dist/policy/plan.js +124 -0
- package/dist/policy/plan.js.map +1 -0
- package/dist/policy/record.d.ts +36 -0
- package/dist/policy/record.d.ts.map +1 -0
- package/dist/policy/record.js +189 -0
- package/dist/policy/record.js.map +1 -0
- package/dist/policy/routing.d.ts +13 -0
- package/dist/policy/routing.d.ts.map +1 -0
- package/dist/policy/routing.js +72 -0
- package/dist/policy/routing.js.map +1 -0
- package/dist/policy/wakewords.d.ts +14 -0
- package/dist/policy/wakewords.d.ts.map +1 -0
- package/dist/policy/wakewords.js +85 -0
- package/dist/policy/wakewords.js.map +1 -0
- package/dist/render/envelope.d.ts +6 -0
- package/dist/render/envelope.d.ts.map +1 -0
- package/dist/render/envelope.js +48 -0
- package/dist/render/envelope.js.map +1 -0
- package/dist/render/errors.d.ts +5 -0
- package/dist/render/errors.d.ts.map +1 -0
- package/dist/render/errors.js +9 -0
- package/dist/render/errors.js.map +1 -0
- package/dist/render/html.d.ts +13 -0
- package/dist/render/html.d.ts.map +1 -0
- package/dist/render/html.js +68 -0
- package/dist/render/html.js.map +1 -0
- package/dist/render/index.d.ts +8 -0
- package/dist/render/index.d.ts.map +1 -0
- package/dist/render/index.js +6 -0
- package/dist/render/index.js.map +1 -0
- package/dist/render/templates.d.ts +5 -0
- package/dist/render/templates.d.ts.map +1 -0
- package/dist/render/templates.js +42 -0
- package/dist/render/templates.js.map +1 -0
- package/dist/render/views.d.ts +78 -0
- package/dist/render/views.d.ts.map +1 -0
- package/dist/render/views.js +145 -0
- package/dist/render/views.js.map +1 -0
- package/package.json +32 -0
- package/templates/help.html +16 -0
- package/templates/plan_day.html +16 -0
- package/templates/plan_receipt.html +16 -0
- package/templates/record_compare.html +16 -0
- package/templates/record_day.html +16 -0
- package/templates/record_detail.html +16 -0
- package/templates/record_range.html +16 -0
- package/templates/record_receipt.html +16 -0
package/dist/fetch/db.js
ADDED
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
// 取数层·sqlite DB:老家 scripts/schedule_db.py 对应。
|
|
2
|
+
// 三表:schedule_records(作息记录)/ daily_summary(日摘)/ schedule_plans(事件型日程)。
|
|
3
|
+
// 旧版小时表沿老家 init 语义改名 schedule_plans_legacy_2026_06_29 保留数据;completion 列幂等补齐。
|
|
4
|
+
// 缺失/损坏大声失败,不返空。外置语录库 daily_recorder.db 不直连(以外置为准)。
|
|
5
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
6
|
+
import { ScheduleFetchError } from './errors.js';
|
|
7
|
+
export const SCHEMA_VERSION = 1;
|
|
8
|
+
const RECORDS_DDL = `CREATE TABLE IF NOT EXISTS schedule_records (
|
|
9
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
10
|
+
date TEXT NOT NULL,
|
|
11
|
+
time_start TEXT NOT NULL,
|
|
12
|
+
time_end TEXT NOT NULL,
|
|
13
|
+
duration_minutes INTEGER,
|
|
14
|
+
activity TEXT NOT NULL,
|
|
15
|
+
category TEXT NOT NULL,
|
|
16
|
+
source_contents TEXT,
|
|
17
|
+
source_timestamps TEXT,
|
|
18
|
+
analysis_reasoning TEXT,
|
|
19
|
+
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
20
|
+
updated_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
21
|
+
edit_count INTEGER NOT NULL DEFAULT 0
|
|
22
|
+
)`;
|
|
23
|
+
const SUMMARY_DDL = `CREATE TABLE IF NOT EXISTS daily_summary (
|
|
24
|
+
date TEXT NOT NULL,
|
|
25
|
+
category TEXT NOT NULL,
|
|
26
|
+
total_minutes INTEGER DEFAULT 0,
|
|
27
|
+
generated_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
28
|
+
PRIMARY KEY (date, category)
|
|
29
|
+
)`;
|
|
30
|
+
const PLANS_DDL = `CREATE TABLE IF NOT EXISTS schedule_plans (
|
|
31
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
32
|
+
date TEXT NOT NULL,
|
|
33
|
+
time_start TEXT NOT NULL,
|
|
34
|
+
time_end TEXT NOT NULL,
|
|
35
|
+
title TEXT NOT NULL,
|
|
36
|
+
notes TEXT,
|
|
37
|
+
category TEXT,
|
|
38
|
+
feishu_event_id TEXT,
|
|
39
|
+
last_synced_at TEXT,
|
|
40
|
+
is_active INTEGER NOT NULL DEFAULT 1,
|
|
41
|
+
completion TEXT DEFAULT NULL,
|
|
42
|
+
completion_note TEXT DEFAULT NULL,
|
|
43
|
+
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
44
|
+
updated_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
45
|
+
)`;
|
|
46
|
+
function tableColumns(db, table) {
|
|
47
|
+
try {
|
|
48
|
+
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
49
|
+
return rows.map((r) => r.name);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// 打开 DB:建三表(幂等)+ 旧版小时表改名 + completion 列补齐;失败 throw。
|
|
56
|
+
export function openScheduleDb(dbPath) {
|
|
57
|
+
if (typeof dbPath !== 'string' || dbPath.length === 0) {
|
|
58
|
+
throw new ScheduleFetchError('SCHEDULE_DB_MISSING', '作息 DB 路径未指定');
|
|
59
|
+
}
|
|
60
|
+
let db;
|
|
61
|
+
try {
|
|
62
|
+
db = new DatabaseSync(dbPath);
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
throw new ScheduleFetchError('SCHEDULE_DB_UNREADABLE', '作息 DB 打不开:' + dbPath, { cause: e });
|
|
66
|
+
}
|
|
67
|
+
let initialized = false;
|
|
68
|
+
try {
|
|
69
|
+
db.exec('PRAGMA journal_mode=WAL');
|
|
70
|
+
db.exec('PRAGMA busy_timeout=5000');
|
|
71
|
+
const before = tableColumns(db, 'schedule_records').length + tableColumns(db, 'schedule_plans').length;
|
|
72
|
+
db.exec(RECORDS_DDL);
|
|
73
|
+
db.exec(SUMMARY_DDL);
|
|
74
|
+
// 旧版小时表:若 schedule_plans 仍是旧形(无 time_start 列)先改名再建新表。
|
|
75
|
+
const cols = tableColumns(db, 'schedule_plans');
|
|
76
|
+
if (cols.length > 0 && !cols.includes('time_start')) {
|
|
77
|
+
db.exec('ALTER TABLE schedule_plans RENAME TO schedule_plans_legacy_2026_06_29');
|
|
78
|
+
}
|
|
79
|
+
db.exec(PLANS_DDL);
|
|
80
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_plans_date ON schedule_plans(date)');
|
|
81
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_plans_date_time ON schedule_plans(date, time_start)');
|
|
82
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_records_date ON schedule_records(date)');
|
|
83
|
+
const after = tableColumns(db, 'schedule_records').length + tableColumns(db, 'schedule_plans').length;
|
|
84
|
+
initialized = before === 0 && after > 0;
|
|
85
|
+
try {
|
|
86
|
+
db.exec('ALTER TABLE schedule_plans ADD COLUMN completion TEXT DEFAULT NULL');
|
|
87
|
+
}
|
|
88
|
+
catch { /* 已有 */ }
|
|
89
|
+
try {
|
|
90
|
+
db.exec('ALTER TABLE schedule_plans ADD COLUMN completion_note TEXT DEFAULT NULL');
|
|
91
|
+
}
|
|
92
|
+
catch { /* 已有 */ }
|
|
93
|
+
try {
|
|
94
|
+
db.exec('ALTER TABLE schedule_records ADD COLUMN updated_at TEXT DEFAULT CURRENT_TIMESTAMP');
|
|
95
|
+
}
|
|
96
|
+
catch { /* 已有 */ }
|
|
97
|
+
try {
|
|
98
|
+
db.exec('ALTER TABLE schedule_records ADD COLUMN edit_count INTEGER NOT NULL DEFAULT 0');
|
|
99
|
+
}
|
|
100
|
+
catch { /* 已有 */ }
|
|
101
|
+
}
|
|
102
|
+
catch (e) {
|
|
103
|
+
if (e instanceof ScheduleFetchError)
|
|
104
|
+
throw e;
|
|
105
|
+
throw new ScheduleFetchError('SCHEDULE_DB_UNREADABLE', '作息 DB 初始化失败:' + dbPath, { cause: e });
|
|
106
|
+
}
|
|
107
|
+
return { db, path: dbPath, initialized };
|
|
108
|
+
}
|
|
109
|
+
export function closeScheduleDb(handle) {
|
|
110
|
+
try {
|
|
111
|
+
handle.db.close();
|
|
112
|
+
}
|
|
113
|
+
catch { /* 关闭失败不谎报 */ }
|
|
114
|
+
}
|
|
115
|
+
function rowRecord(r) {
|
|
116
|
+
return r;
|
|
117
|
+
}
|
|
118
|
+
function rowPlan(r) {
|
|
119
|
+
return r;
|
|
120
|
+
}
|
|
121
|
+
// ---- 作息记录 ----
|
|
122
|
+
export function addRecord(handle, input) {
|
|
123
|
+
let id = 0;
|
|
124
|
+
try {
|
|
125
|
+
const r = handle.db.prepare('INSERT INTO schedule_records ' +
|
|
126
|
+
'(date, time_start, time_end, duration_minutes, activity, category, ' +
|
|
127
|
+
'source_contents, source_timestamps, analysis_reasoning) ' +
|
|
128
|
+
'VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING id').get(input.date, input.time_start, input.time_end, input.duration_minutes, input.activity, input.category, input.source_contents ?? null, input.source_timestamps ?? null, input.analysis_reasoning ?? null);
|
|
129
|
+
id = r.id;
|
|
130
|
+
}
|
|
131
|
+
catch (e) {
|
|
132
|
+
throw new ScheduleFetchError('SCHEDULE_DB_UNREADABLE', '作息记录写盘失败', { cause: e });
|
|
133
|
+
}
|
|
134
|
+
return getRecordById(handle, id);
|
|
135
|
+
}
|
|
136
|
+
// 修正:任一字段可改;edit_count 自增 + updated_at 更新(老家 #26 审计语义)。
|
|
137
|
+
export function amendRecord(handle, id, patch) {
|
|
138
|
+
const cur = getRecordById(handle, id);
|
|
139
|
+
const keys = [
|
|
140
|
+
'date', 'time_start', 'time_end', 'duration_minutes', 'activity', 'category',
|
|
141
|
+
'source_contents', 'source_timestamps', 'analysis_reasoning',
|
|
142
|
+
];
|
|
143
|
+
const sets = [];
|
|
144
|
+
const vals = [];
|
|
145
|
+
for (const k of keys) {
|
|
146
|
+
if (patch[k] !== undefined) {
|
|
147
|
+
sets.push(k + ' = ?');
|
|
148
|
+
vals.push(patch[k]);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (!sets.length)
|
|
152
|
+
return cur;
|
|
153
|
+
sets.push('edit_count = edit_count + 1');
|
|
154
|
+
sets.push('updated_at = CURRENT_TIMESTAMP');
|
|
155
|
+
try {
|
|
156
|
+
handle.db.prepare(`UPDATE schedule_records SET ${sets.join(', ')} WHERE id = ?`).run(...vals, id);
|
|
157
|
+
}
|
|
158
|
+
catch (e) {
|
|
159
|
+
throw new ScheduleFetchError('SCHEDULE_DB_UNREADABLE', '作息记录修正失败:' + id, { cause: e });
|
|
160
|
+
}
|
|
161
|
+
return getRecordById(handle, id);
|
|
162
|
+
}
|
|
163
|
+
export function getRecordById(handle, id) {
|
|
164
|
+
if (!Number.isInteger(id) || id <= 0) {
|
|
165
|
+
throw new ScheduleFetchError('SCHEDULE_RECORD_NOT_FOUND', '作息记录 id 非法:' + String(id));
|
|
166
|
+
}
|
|
167
|
+
let row = null;
|
|
168
|
+
try {
|
|
169
|
+
row = handle.db.prepare('SELECT * FROM schedule_records WHERE id = ?').get(id);
|
|
170
|
+
}
|
|
171
|
+
catch (e) {
|
|
172
|
+
throw new ScheduleFetchError('SCHEDULE_DB_UNREADABLE', '作息记录读取失败:' + id, { cause: e });
|
|
173
|
+
}
|
|
174
|
+
if (!row)
|
|
175
|
+
throw new ScheduleFetchError('SCHEDULE_RECORD_NOT_FOUND', '无此作息记录:' + id);
|
|
176
|
+
return rowRecord(row);
|
|
177
|
+
}
|
|
178
|
+
export function listRecordsByDate(handle, date) {
|
|
179
|
+
try {
|
|
180
|
+
const rows = handle.db.prepare('SELECT * FROM schedule_records WHERE date = ? ORDER BY time_start ASC, id ASC').all(date);
|
|
181
|
+
return rows.map(rowRecord);
|
|
182
|
+
}
|
|
183
|
+
catch (e) {
|
|
184
|
+
throw new ScheduleFetchError('SCHEDULE_DB_UNREADABLE', '作息记录查询失败:' + date, { cause: e });
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
export function listRecordsRange(handle, start, end) {
|
|
188
|
+
try {
|
|
189
|
+
const rows = handle.db.prepare('SELECT * FROM schedule_records WHERE date >= ? AND date <= ? ORDER BY date ASC, time_start ASC, id ASC').all(start, end);
|
|
190
|
+
return rows.map(rowRecord);
|
|
191
|
+
}
|
|
192
|
+
catch (e) {
|
|
193
|
+
throw new ScheduleFetchError('SCHEDULE_DB_UNREADABLE', '作息区间查询失败:' + start + '~' + end, { cause: e });
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
export function getLastRecord(handle) {
|
|
197
|
+
try {
|
|
198
|
+
const row = handle.db.prepare('SELECT * FROM schedule_records ORDER BY date DESC, time_end DESC, id DESC LIMIT 1').get();
|
|
199
|
+
return row ? rowRecord(row) : null;
|
|
200
|
+
}
|
|
201
|
+
catch (e) {
|
|
202
|
+
throw new ScheduleFetchError('SCHEDULE_DB_UNREADABLE', '游标读取失败', { cause: e });
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
export function getStatus(handle) {
|
|
206
|
+
try {
|
|
207
|
+
const r = handle.db.prepare('SELECT COUNT(*) AS n, COUNT(DISTINCT date) AS d, MIN(date) AS f, MAX(date) AS l FROM schedule_records').get();
|
|
208
|
+
return { records: r.n, days: r.d, firstDate: r.f, lastDate: r.l };
|
|
209
|
+
}
|
|
210
|
+
catch (e) {
|
|
211
|
+
throw new ScheduleFetchError('SCHEDULE_DB_UNREADABLE', '状态读取失败', { cause: e });
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
// ---- 每日摘要(#24 add-summary:按 date+category upsert) ----
|
|
215
|
+
export function addSummary(handle, date, category, totalMinutes) {
|
|
216
|
+
try {
|
|
217
|
+
handle.db.prepare('INSERT INTO daily_summary (date, category, total_minutes) VALUES (?, ?, ?) ' +
|
|
218
|
+
'ON CONFLICT(date, category) DO UPDATE SET total_minutes = excluded.total_minutes').run(date, category, totalMinutes);
|
|
219
|
+
}
|
|
220
|
+
catch (e) {
|
|
221
|
+
throw new ScheduleFetchError('SCHEDULE_DB_UNREADABLE', '摘要写盘失败:' + date + '/' + category, { cause: e });
|
|
222
|
+
}
|
|
223
|
+
return { date, category, total_minutes: totalMinutes };
|
|
224
|
+
}
|
|
225
|
+
export function getDailySummary(handle, date) {
|
|
226
|
+
try {
|
|
227
|
+
return handle.db.prepare('SELECT date, category, total_minutes FROM daily_summary WHERE date = ? ORDER BY total_minutes DESC').all(date);
|
|
228
|
+
}
|
|
229
|
+
catch (e) {
|
|
230
|
+
throw new ScheduleFetchError('SCHEDULE_DB_UNREADABLE', '摘要查询失败:' + date, { cause: e });
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
export function getSummariesRange(handle, start, end) {
|
|
234
|
+
try {
|
|
235
|
+
return handle.db.prepare('SELECT date, category, total_minutes FROM daily_summary WHERE date >= ? AND date <= ? ORDER BY date ASC').all(start, end);
|
|
236
|
+
}
|
|
237
|
+
catch (e) {
|
|
238
|
+
throw new ScheduleFetchError('SCHEDULE_DB_UNREADABLE', '摘要区间查询失败', { cause: e });
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
// ---- 日程计划(事件型) ----
|
|
242
|
+
export function listPlanEvents(handle, date, includeInactive = false) {
|
|
243
|
+
try {
|
|
244
|
+
const sql = includeInactive
|
|
245
|
+
? 'SELECT * FROM schedule_plans WHERE date = ? ORDER BY time_start ASC, id ASC'
|
|
246
|
+
: 'SELECT * FROM schedule_plans WHERE date = ? AND is_active = 1 ORDER BY time_start ASC, id ASC';
|
|
247
|
+
const rows = handle.db.prepare(sql).all(date);
|
|
248
|
+
return rows.map(rowPlan);
|
|
249
|
+
}
|
|
250
|
+
catch (e) {
|
|
251
|
+
throw new ScheduleFetchError('SCHEDULE_DB_UNREADABLE', '日程查询失败:' + date, { cause: e });
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
export function getPlanEventsRange(handle, start, end) {
|
|
255
|
+
try {
|
|
256
|
+
const rows = handle.db.prepare('SELECT * FROM schedule_plans WHERE date >= ? AND date <= ? AND is_active = 1 ORDER BY date ASC, time_start ASC').all(start, end);
|
|
257
|
+
return rows.map(rowPlan);
|
|
258
|
+
}
|
|
259
|
+
catch (e) {
|
|
260
|
+
throw new ScheduleFetchError('SCHEDULE_DB_UNREADABLE', '日程区间查询失败', { cause: e });
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
export function getPlanEvent(handle, id) {
|
|
264
|
+
if (!Number.isInteger(id) || id <= 0) {
|
|
265
|
+
throw new ScheduleFetchError('SCHEDULE_PLAN_NOT_FOUND', '日程事件 id 非法:' + String(id));
|
|
266
|
+
}
|
|
267
|
+
let row = null;
|
|
268
|
+
try {
|
|
269
|
+
row = handle.db.prepare('SELECT * FROM schedule_plans WHERE id = ?').get(id);
|
|
270
|
+
}
|
|
271
|
+
catch (e) {
|
|
272
|
+
throw new ScheduleFetchError('SCHEDULE_DB_UNREADABLE', '日程读取失败:' + id, { cause: e });
|
|
273
|
+
}
|
|
274
|
+
if (!row)
|
|
275
|
+
throw new ScheduleFetchError('SCHEDULE_PLAN_NOT_FOUND', '无此日程事件:' + id);
|
|
276
|
+
return rowPlan(row);
|
|
277
|
+
}
|
|
278
|
+
// 标题搜(#12 带标题:子串匹配;可选三元组 time_start/time_end 缩小)。
|
|
279
|
+
export function searchPlanEvent(handle, date, title, timeStart, timeEnd) {
|
|
280
|
+
if (!title || !title.trim())
|
|
281
|
+
throw new ScheduleFetchError('SCHEDULE_BAD_QUERY', '标题搜须给 title');
|
|
282
|
+
try {
|
|
283
|
+
let sql = 'SELECT * FROM schedule_plans WHERE date = ? AND is_active = 1 AND title LIKE ?';
|
|
284
|
+
const vals = [date, '%' + title.trim() + '%'];
|
|
285
|
+
if (timeStart !== undefined) {
|
|
286
|
+
sql += ' AND time_start = ?';
|
|
287
|
+
vals.push(timeStart);
|
|
288
|
+
}
|
|
289
|
+
if (timeEnd !== undefined) {
|
|
290
|
+
sql += ' AND time_end = ?';
|
|
291
|
+
vals.push(timeEnd);
|
|
292
|
+
}
|
|
293
|
+
sql += ' ORDER BY time_start ASC';
|
|
294
|
+
const rows = handle.db.prepare(sql).all(...vals);
|
|
295
|
+
return rows.map(rowPlan);
|
|
296
|
+
}
|
|
297
|
+
catch (e) {
|
|
298
|
+
if (e instanceof ScheduleFetchError)
|
|
299
|
+
throw e;
|
|
300
|
+
throw new ScheduleFetchError('SCHEDULE_DB_UNREADABLE', '标题搜失败', { cause: e });
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// 补计划(#13 ensure:按 date+time_start+time_end 三元组幂等,title 只展示不参与身份)。
|
|
304
|
+
export function ensurePlanEvent(handle, input) {
|
|
305
|
+
try {
|
|
306
|
+
const hit = handle.db.prepare('SELECT * FROM schedule_plans WHERE date = ? AND time_start = ? AND time_end = ? AND is_active = 1 LIMIT 1').get(input.date, input.time_start, input.time_end);
|
|
307
|
+
if (hit)
|
|
308
|
+
return { event: rowPlan(hit), created: false };
|
|
309
|
+
const r = handle.db.prepare('INSERT INTO schedule_plans (date, time_start, time_end, title, notes, category) ' +
|
|
310
|
+
'VALUES (?, ?, ?, ?, ?, ?) RETURNING id').get(input.date, input.time_start, input.time_end, input.title, input.notes ?? null, input.category ?? null);
|
|
311
|
+
return { event: getPlanEvent(handle, r.id), created: true };
|
|
312
|
+
}
|
|
313
|
+
catch (e) {
|
|
314
|
+
if (e instanceof ScheduleFetchError)
|
|
315
|
+
throw e;
|
|
316
|
+
throw new ScheduleFetchError('SCHEDULE_DB_UNREADABLE', '补计划失败', { cause: e });
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
// 商量计划落盘(#17 upsert:先整日软删再整批插入;调用方已过 24h 覆盖校验)。
|
|
320
|
+
export function upsertPlanEvents(handle, date, events) {
|
|
321
|
+
try {
|
|
322
|
+
handle.db.prepare('UPDATE schedule_plans SET is_active = 0 WHERE date = ? AND is_active = 1').run(date);
|
|
323
|
+
const out = [];
|
|
324
|
+
for (const e of events) {
|
|
325
|
+
const r = handle.db.prepare('INSERT INTO schedule_plans (date, time_start, time_end, title, notes, category) ' +
|
|
326
|
+
'VALUES (?, ?, ?, ?, ?, ?) RETURNING id').get(date, e.time_start, e.time_end, e.title, e.notes ?? null, e.category ?? null);
|
|
327
|
+
out.push(getPlanEvent(handle, r.id));
|
|
328
|
+
}
|
|
329
|
+
return out;
|
|
330
|
+
}
|
|
331
|
+
catch (e) {
|
|
332
|
+
if (e instanceof ScheduleFetchError)
|
|
333
|
+
throw e;
|
|
334
|
+
throw new ScheduleFetchError('SCHEDULE_DB_UNREADABLE', '商量计划落盘失败:' + date, { cause: e });
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
// 改计划(#18:可选字段;含 completion 复盘标记)。
|
|
338
|
+
export function updatePlanEvent(handle, id, patch) {
|
|
339
|
+
getPlanEvent(handle, id);
|
|
340
|
+
const keys = [
|
|
341
|
+
'title', 'notes', 'category', 'time_start', 'time_end', 'completion', 'completion_note', 'feishu_event_id',
|
|
342
|
+
];
|
|
343
|
+
const sets = [];
|
|
344
|
+
const vals = [];
|
|
345
|
+
for (const k of keys) {
|
|
346
|
+
if (patch[k] !== undefined) {
|
|
347
|
+
sets.push(k + ' = ?');
|
|
348
|
+
vals.push(patch[k]);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
if (!sets.length)
|
|
352
|
+
return getPlanEvent(handle, id);
|
|
353
|
+
sets.push('updated_at = CURRENT_TIMESTAMP');
|
|
354
|
+
try {
|
|
355
|
+
handle.db.prepare(`UPDATE schedule_plans SET ${sets.join(', ')} WHERE id = ?`).run(...vals, id);
|
|
356
|
+
}
|
|
357
|
+
catch (e) {
|
|
358
|
+
throw new ScheduleFetchError('SCHEDULE_DB_UNREADABLE', '改计划失败:' + id, { cause: e });
|
|
359
|
+
}
|
|
360
|
+
return getPlanEvent(handle, id);
|
|
361
|
+
}
|
|
362
|
+
// 删计划(#19:软删 is_active=0,飞书侧删除由调用方编排)。
|
|
363
|
+
export function deactivatePlanEvent(handle, id) {
|
|
364
|
+
getPlanEvent(handle, id);
|
|
365
|
+
try {
|
|
366
|
+
handle.db.prepare('UPDATE schedule_plans SET is_active = 0, updated_at = CURRENT_TIMESTAMP WHERE id = ?').run(id);
|
|
367
|
+
}
|
|
368
|
+
catch (e) {
|
|
369
|
+
throw new ScheduleFetchError('SCHEDULE_DB_UNREADABLE', '删计划失败:' + id, { cause: e });
|
|
370
|
+
}
|
|
371
|
+
return getPlanEvent(handle, id);
|
|
372
|
+
}
|
|
373
|
+
export function setFeishuEventId(handle, id, feishuEventId) {
|
|
374
|
+
try {
|
|
375
|
+
handle.db.prepare('UPDATE schedule_plans SET feishu_event_id = ?, last_synced_at = CURRENT_TIMESTAMP WHERE id = ?')
|
|
376
|
+
.run(feishuEventId, id);
|
|
377
|
+
}
|
|
378
|
+
catch (e) {
|
|
379
|
+
throw new ScheduleFetchError('SCHEDULE_DB_UNREADABLE', '飞书 id 回写失败:' + id, { cause: e });
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
//# sourceMappingURL=db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/fetch/db.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare class ScheduleFetchError extends Error {
|
|
2
|
+
readonly code: 'SCHEDULE_DB_MISSING' | 'SCHEDULE_DB_UNREADABLE' | 'SCHEDULE_RECORD_CORRUPT' | 'SCHEDULE_RECORD_NOT_FOUND' | 'SCHEDULE_PLAN_NOT_FOUND' | 'SCHEDULE_BAD_QUERY' | 'SCHEDULE_EMPTY_RANGE' | 'LARK_UNAVAILABLE' | 'LARK_NOT_LOGGED_IN' | 'LARK_DENIED' | 'LARK_TIMEOUT' | 'LARK_BAD_RESPONSE';
|
|
3
|
+
constructor(code: ScheduleFetchError['code'], message: string, options?: {
|
|
4
|
+
cause?: unknown;
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
export declare class SchedulePolicyError extends Error {
|
|
8
|
+
readonly code: 'POLICY_NO_MATCH' | 'POLICY_MISSING_SLOT' | 'POLICY_BAD_CATEGORY' | 'POLICY_BAD_DATE' | 'POLICY_BAD_TIME' | 'POLICY_BAD_COVERAGE' | 'POLICY_BAD_INPUT';
|
|
9
|
+
constructor(code: SchedulePolicyError['code'], message: string, options?: {
|
|
10
|
+
cause?: unknown;
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/fetch/errors.ts"],"names":[],"mappings":"AACA,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,IAAI,EACT,qBAAqB,GAAG,wBAAwB,GAAG,yBAAyB,GAC5E,2BAA2B,GAAG,yBAAyB,GAAG,oBAAoB,GAC9E,sBAAsB,GACtB,kBAAkB,GAAG,oBAAoB,GAAG,aAAa,GAAG,cAAc,GAAG,mBAAmB,CAAC;gBACzF,IAAI,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAK7F;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,EACT,iBAAiB,GAAG,qBAAqB,GAAG,qBAAqB,GACjE,iBAAiB,GAAG,iBAAiB,GAAG,qBAAqB,GAAG,kBAAkB,CAAC;gBAC3E,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAK9F"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// 取数/口径错误:坏输入与缺失一律 throw,永不返空数组冒充正常。
|
|
2
|
+
export class ScheduleFetchError extends Error {
|
|
3
|
+
code;
|
|
4
|
+
constructor(code, message, options) {
|
|
5
|
+
super(message, options);
|
|
6
|
+
this.name = 'ScheduleFetchError';
|
|
7
|
+
this.code = code;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export class SchedulePolicyError extends Error {
|
|
11
|
+
code;
|
|
12
|
+
constructor(code, message, options) {
|
|
13
|
+
super(message, options);
|
|
14
|
+
this.name = 'SchedulePolicyError';
|
|
15
|
+
this.code = code;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/fetch/errors.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAClC,IAAI,CAIwF;IACrG,YAAY,IAAgC,EAAE,OAAe,EAAE,OAA6B;QAC1F,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IACnC,IAAI,CAE0E;IACvF,YAAY,IAAiC,EAAE,OAAe,EAAE,OAA6B;QAC3F,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export declare const LARK_TIMEOUT_SHORT_MS = 15000;
|
|
2
|
+
export declare const LARK_TIMEOUT_NORMAL_MS = 30000;
|
|
3
|
+
export declare const LARK_TIMEOUT_LONG_MS = 60000;
|
|
4
|
+
export declare const LARK_CALENDAR_SCOPE = "calendar";
|
|
5
|
+
export declare function findLarkCli(): string | null;
|
|
6
|
+
export interface LarkRunOk {
|
|
7
|
+
ok: true;
|
|
8
|
+
stdout: string;
|
|
9
|
+
}
|
|
10
|
+
export interface LarkRunDenied {
|
|
11
|
+
ok: false;
|
|
12
|
+
exit: number | null;
|
|
13
|
+
stderr: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function runLark(cli: string, args: string[], timeoutMs?: number): LarkRunOk | LarkRunDenied;
|
|
16
|
+
export declare function larkVersion(cli: string): string;
|
|
17
|
+
export declare function authOpenId(cli: string): string;
|
|
18
|
+
export declare function checkCalendar(cli: string): boolean;
|
|
19
|
+
export interface LarkReady {
|
|
20
|
+
cliPath: string;
|
|
21
|
+
version: string;
|
|
22
|
+
openId: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function larkReady(): LarkReady;
|
|
25
|
+
export interface FeishuEvent {
|
|
26
|
+
eventId?: string;
|
|
27
|
+
summary?: string;
|
|
28
|
+
start?: string;
|
|
29
|
+
end?: string;
|
|
30
|
+
raw: unknown;
|
|
31
|
+
}
|
|
32
|
+
export declare function searchFeishuEvents(cli: string, start: string, end: string): unknown;
|
|
33
|
+
export declare function createFeishuEvent(cli: string, start: string, end: string, summary: string, description: string): unknown;
|
|
34
|
+
export declare function updateFeishuEvent(cli: string, eventId: string, start: string, end: string, summary: string): unknown;
|
|
35
|
+
export declare function deleteFeishuEvent(cli: string, calendarId: string, eventId: string): unknown;
|
|
36
|
+
//# sourceMappingURL=feishu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feishu.d.ts","sourceRoot":"","sources":["../../src/fetch/feishu.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAC3C,eAAO,MAAM,sBAAsB,QAAQ,CAAC;AAC5C,eAAO,MAAM,oBAAoB,QAAQ,CAAC;AAC1C,eAAO,MAAM,mBAAmB,aAAa,CAAC;AAG9C,wBAAgB,WAAW,IAAI,MAAM,GAAG,IAAI,CA0B3C;AAED,MAAM,WAAW,SAAS;IAAG,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;CAAE;AACxD,MAAM,WAAW,aAAa;IAAG,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;CAAE;AAGlF,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,SAAS,SAAyB,GAAG,SAAS,GAAG,aAAa,CAgBlH;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI/C;AAGD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAW9C;AAGD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAElD;AAED,MAAM,WAAW,SAAS;IAAG,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;CAAE;AAGhF,wBAAgB,SAAS,IAAI,SAAS,CAOrC;AAED,MAAM,WAAW,WAAW;IAAG,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,OAAO,CAAC;CAAE;AAShH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAEnF;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAMxH;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAMpH;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAE3F"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
// 取数层·飞书同步点:lark-cli 四门(存在+版本+登录+日历写权限),缺失即 throw。
|
|
2
|
+
// 老家对照 scripts/feishu_sync.py:7 条子命令(--version/auth status/calendar +create/+update/+search-event/+agenda/events delete)。
|
|
3
|
+
// 超时 15/30/60 三档;本模块不直连 DB(diff 编排在 cli 层)。
|
|
4
|
+
import { accessSync, constants } from 'node:fs';
|
|
5
|
+
import { execFileSync } from 'node:child_process';
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
import { ScheduleFetchError } from './errors.js';
|
|
8
|
+
export const LARK_TIMEOUT_SHORT_MS = 15000;
|
|
9
|
+
export const LARK_TIMEOUT_NORMAL_MS = 30000;
|
|
10
|
+
export const LARK_TIMEOUT_LONG_MS = 60000;
|
|
11
|
+
export const LARK_CALENDAR_SCOPE = 'calendar';
|
|
12
|
+
// 跨平台定位:显式覆盖 → Windows npm 全局 → where/which → 固定路径;找不到返 null。
|
|
13
|
+
export function findLarkCli() {
|
|
14
|
+
const over = process.env.LARK_CLI_PATH;
|
|
15
|
+
if (over) {
|
|
16
|
+
try {
|
|
17
|
+
accessSync(over, constants.X_OK);
|
|
18
|
+
return over;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
throw new ScheduleFetchError('LARK_UNAVAILABLE', 'LARK_CLI_PATH 不可用:' + over);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (process.platform === 'win32') {
|
|
25
|
+
const appdata = process.env.APPDATA;
|
|
26
|
+
if (appdata) {
|
|
27
|
+
const cand = join(appdata, 'npm', 'lark-cli.cmd');
|
|
28
|
+
try {
|
|
29
|
+
accessSync(cand, constants.X_OK);
|
|
30
|
+
return cand;
|
|
31
|
+
}
|
|
32
|
+
catch { /* 继续 */ }
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const out = execFileSync('where', ['lark-cli'], { stdio: 'pipe', encoding: 'utf8' }).split(/\r?\n/)[0].trim();
|
|
36
|
+
if (out)
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
catch { /* 继续 */ }
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
try {
|
|
43
|
+
const out = execFileSync('which', ['lark-cli'], { stdio: 'pipe', encoding: 'utf8' }).trim();
|
|
44
|
+
if (out)
|
|
45
|
+
return out.split('\n')[0];
|
|
46
|
+
}
|
|
47
|
+
catch { /* 继续 */ }
|
|
48
|
+
}
|
|
49
|
+
for (const cand of ['/usr/local/bin/lark-cli', '/usr/bin/lark-cli']) {
|
|
50
|
+
try {
|
|
51
|
+
accessSync(cand, constants.X_OK);
|
|
52
|
+
return cand;
|
|
53
|
+
}
|
|
54
|
+
catch { /* 继续 */ }
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
// 调 lark-cli:超时/缺失 throw;非 0 退出返 ok:false(供权限判定),不抛。
|
|
59
|
+
export function runLark(cli, args, timeoutMs = LARK_TIMEOUT_NORMAL_MS) {
|
|
60
|
+
let file = cli;
|
|
61
|
+
let argv = args;
|
|
62
|
+
if (process.platform === 'win32' && /\.cmd$/i.test(cli)) {
|
|
63
|
+
file = 'cmd.exe';
|
|
64
|
+
argv = ['/d', '/s', '/c', cli, ...args];
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const out = execFileSync(file, argv, { stdio: 'pipe', encoding: 'utf8', timeout: timeoutMs });
|
|
68
|
+
return { ok: true, stdout: out };
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
const err = e;
|
|
72
|
+
if (err.code === 'ENOENT')
|
|
73
|
+
throw new ScheduleFetchError('LARK_UNAVAILABLE', 'lark-cli 不可用:' + cli);
|
|
74
|
+
if (err.code === 'ETIMEDOUT')
|
|
75
|
+
throw new ScheduleFetchError('LARK_TIMEOUT', 'lark-cli 超时:' + args.join(' '));
|
|
76
|
+
return { ok: false, exit: err.status ?? null, stderr: String(err.stderr ?? err.message ?? e) };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export function larkVersion(cli) {
|
|
80
|
+
const r = runLark(cli, ['--version'], LARK_TIMEOUT_SHORT_MS);
|
|
81
|
+
if (!r.ok)
|
|
82
|
+
return 'unknown';
|
|
83
|
+
return r.stdout.trim().split('\n')[0] || 'unknown';
|
|
84
|
+
}
|
|
85
|
+
// 身份真值源:auth status 输出 identities.user.openId;无 openId 即未登录 throw。
|
|
86
|
+
export function authOpenId(cli) {
|
|
87
|
+
const r = runLark(cli, ['auth', 'status'], LARK_TIMEOUT_SHORT_MS);
|
|
88
|
+
if (!r.ok)
|
|
89
|
+
throw new ScheduleFetchError('LARK_NOT_LOGGED_IN', 'lark-cli auth status 失败(未登录?)');
|
|
90
|
+
let j = null;
|
|
91
|
+
try {
|
|
92
|
+
j = JSON.parse(r.stdout);
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
throw new ScheduleFetchError('LARK_BAD_RESPONSE', 'lark-cli auth status 非 JSON');
|
|
96
|
+
}
|
|
97
|
+
const id = j.identities?.user?.openId;
|
|
98
|
+
if (typeof id !== 'string' || id.length === 0) {
|
|
99
|
+
throw new ScheduleFetchError('LARK_NOT_LOGGED_IN', 'lark-cli 未登录(无 openId,先 auth login)');
|
|
100
|
+
}
|
|
101
|
+
return id;
|
|
102
|
+
}
|
|
103
|
+
// 日历写权限门:+agenda 可调即认为日历可达(老家 _probe_calendar_writable 对应)。
|
|
104
|
+
export function checkCalendar(cli) {
|
|
105
|
+
return runLark(cli, ['calendar', '+agenda'], LARK_TIMEOUT_NORMAL_MS).ok;
|
|
106
|
+
}
|
|
107
|
+
// 四门全绿才取数/同步:存在→版本→登录→日历;任一红 throw(调用方阻断,不返空)。
|
|
108
|
+
export function larkReady() {
|
|
109
|
+
const cli = findLarkCli();
|
|
110
|
+
if (!cli)
|
|
111
|
+
throw new ScheduleFetchError('LARK_UNAVAILABLE', 'lark-cli 未找到:缺失阻断同步');
|
|
112
|
+
const version = larkVersion(cli);
|
|
113
|
+
const openId = authOpenId(cli);
|
|
114
|
+
if (!checkCalendar(cli))
|
|
115
|
+
throw new ScheduleFetchError('LARK_DENIED', '日历不可达(缺授权?先 lark-cli auth login)');
|
|
116
|
+
return { cliPath: cli, version, openId };
|
|
117
|
+
}
|
|
118
|
+
function mustJson(cli, args, what) {
|
|
119
|
+
const r = runLark(cli, args, LARK_TIMEOUT_LONG_MS);
|
|
120
|
+
if (!r.ok)
|
|
121
|
+
throw new ScheduleFetchError('LARK_BAD_RESPONSE', '飞书' + what + '失败:' + r.stderr.slice(0, 200));
|
|
122
|
+
try {
|
|
123
|
+
return JSON.parse(r.stdout);
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
throw new ScheduleFetchError('LARK_BAD_RESPONSE', '飞书' + what + '返回非 JSON');
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
export function searchFeishuEvents(cli, start, end) {
|
|
130
|
+
return mustJson(cli, ['calendar', '+search-event', '--start', start, '--end', end], '查询');
|
|
131
|
+
}
|
|
132
|
+
export function createFeishuEvent(cli, start, end, summary, description) {
|
|
133
|
+
return mustJson(cli, ['calendar', '+create', '--start', start, '--end', end, '--summary', summary, '--description', description], '创建');
|
|
134
|
+
}
|
|
135
|
+
export function updateFeishuEvent(cli, eventId, start, end, summary) {
|
|
136
|
+
return mustJson(cli, ['calendar', '+update', '--event-id', eventId, '--start', start, '--end', end, '--summary', summary], '更新');
|
|
137
|
+
}
|
|
138
|
+
export function deleteFeishuEvent(cli, calendarId, eventId) {
|
|
139
|
+
return mustJson(cli, ['calendar', 'events', 'delete', '--calendar-id', calendarId, '--event-id', eventId], '删除');
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=feishu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feishu.js","sourceRoot":"","sources":["../../src/fetch/feishu.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,0HAA0H;AAC1H,4CAA4C;AAC5C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAC3C,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAC;AAC5C,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,CAAC;AAC1C,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC;AAE9C,8DAA8D;AAC9D,MAAM,UAAU,WAAW;IACzB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IACvC,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,CAAC;YAAC,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;QACtD,MAAM,CAAC;YAAC,MAAM,IAAI,kBAAkB,CAAC,kBAAkB,EAAE,oBAAoB,GAAG,IAAI,CAAC,CAAC;QAAC,CAAC;IAC1F,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;QACpC,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;YAClD,IAAI,CAAC;gBAAC,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;gBAAC,OAAO,IAAI,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC3E,CAAC;QACD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC9G,IAAI,GAAG;gBAAE,OAAO,GAAG,CAAC;QACtB,CAAC;QAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC;IACtB,CAAC;SAAM,CAAC;QACN,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAC5F,IAAI,GAAG;gBAAE,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC;IACtB,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,CAAC,yBAAyB,EAAE,mBAAmB,CAAC,EAAE,CAAC;QACpE,IAAI,CAAC;YAAC,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAKD,qDAAqD;AACrD,MAAM,UAAU,OAAO,CAAC,GAAW,EAAE,IAAc,EAAE,SAAS,GAAG,sBAAsB;IACrF,IAAI,IAAI,GAAG,GAAG,CAAC;IACf,IAAI,IAAI,GAAG,IAAI,CAAC;IAChB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACxD,IAAI,GAAG,SAAS,CAAC;QACjB,IAAI,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;QAC9F,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IACnC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,CAAmF,CAAC;QAChG,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,IAAI,kBAAkB,CAAC,kBAAkB,EAAE,eAAe,GAAG,GAAG,CAAC,CAAC;QACnG,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW;YAAE,MAAM,IAAI,kBAAkB,CAAC,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5G,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,IAAI,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,EAAE,CAAC;IACjG,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,qBAAqB,CAAC,CAAC;IAC7D,IAAI,CAAC,CAAC,CAAC,EAAE;QAAE,OAAO,SAAS,CAAC;IAC5B,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;AACrD,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,qBAAqB,CAAC,CAAC;IAClE,IAAI,CAAC,CAAC,CAAC,EAAE;QAAE,MAAM,IAAI,kBAAkB,CAAC,oBAAoB,EAAE,+BAA+B,CAAC,CAAC;IAC/F,IAAI,CAAC,GAAY,IAAI,CAAC;IACtB,IAAI,CAAC;QAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAAC,CAAC;IACjC,MAAM,CAAC;QAAC,MAAM,IAAI,kBAAkB,CAAC,mBAAmB,EAAE,6BAA6B,CAAC,CAAC;IAAC,CAAC;IAC3F,MAAM,EAAE,GAAI,CAAsD,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC;IAC5F,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,kBAAkB,CAAC,oBAAoB,EAAE,qCAAqC,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,sBAAsB,CAAC,CAAC,EAAE,CAAC;AAC1E,CAAC;AAID,+CAA+C;AAC/C,MAAM,UAAU,SAAS;IACvB,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;IAC1B,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,kBAAkB,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,CAAC;IAClF,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,kBAAkB,CAAC,aAAa,EAAE,kCAAkC,CAAC,CAAC;IACzG,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAC3C,CAAC;AAID,SAAS,QAAQ,CAAC,GAAW,EAAE,IAAc,EAAE,IAAY;IACzD,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,oBAAoB,CAAC,CAAC;IACnD,IAAI,CAAC,CAAC,CAAC,EAAE;QAAE,MAAM,IAAI,kBAAkB,CAAC,mBAAmB,EAAE,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAC3G,IAAI,CAAC;QAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAAC,CAAC;IACpC,MAAM,CAAC;QAAC,MAAM,IAAI,kBAAkB,CAAC,mBAAmB,EAAE,IAAI,GAAG,IAAI,GAAG,UAAU,CAAC,CAAC;IAAC,CAAC;AACxF,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAW,EAAE,KAAa,EAAE,GAAW;IACxE,OAAO,QAAQ,CAAC,GAAG,EAAE,CAAC,UAAU,EAAE,eAAe,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;AAC5F,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAW,EAAE,KAAa,EAAE,GAAW,EAAE,OAAe,EAAE,WAAmB;IAC7G,OAAO,QAAQ,CACb,GAAG,EACH,CAAC,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,CAAC,EAC3G,IAAI,CACL,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAW,EAAE,OAAe,EAAE,KAAa,EAAE,GAAW,EAAE,OAAe;IACzG,OAAO,QAAQ,CACb,GAAG,EACH,CAAC,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,OAAO,CAAC,EACpG,IAAI,CACL,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAW,EAAE,UAAkB,EAAE,OAAe;IAChF,OAAO,QAAQ,CAAC,GAAG,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC;AACnH,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { ScheduleFetchError, SchedulePolicyError } from './errors.js';
|
|
2
|
+
export { DB_FILENAME, resolveDbDir, resolveDbPath, assertWritablePath } from './paths.js';
|
|
3
|
+
export { SCHEMA_VERSION, openScheduleDb, closeScheduleDb, addRecord, amendRecord, getRecordById, listRecordsByDate, listRecordsRange, getLastRecord, getStatus, addSummary, getDailySummary, getSummariesRange, listPlanEvents, getPlanEventsRange, getPlanEvent, searchPlanEvent, ensurePlanEvent, upsertPlanEvents, updatePlanEvent, deactivatePlanEvent, setFeishuEventId, } from './db.js';
|
|
4
|
+
export type { ScheduleDb, ScheduleRecord, DailySummary, PlanEvent } from './db.js';
|
|
5
|
+
export { LARK_TIMEOUT_SHORT_MS, LARK_TIMEOUT_NORMAL_MS, LARK_TIMEOUT_LONG_MS, LARK_CALENDAR_SCOPE, findLarkCli, runLark, larkVersion, authOpenId, checkCalendar, larkReady, searchFeishuEvents, createFeishuEvent, updateFeishuEvent, deleteFeishuEvent, } from './feishu.js';
|
|
6
|
+
export type { LarkRunOk, LarkRunDenied, LarkReady, FeishuEvent } from './feishu.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|