skill-home 0.2.0 → 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 (41) hide show
  1. package/SKILL.md +17 -17
  2. package/dist/cli/cmd_read.js +93 -26
  3. package/dist/cli/cmd_read.js.map +1 -1
  4. package/dist/cli/config.d.ts +16 -0
  5. package/dist/cli/config.d.ts.map +1 -0
  6. package/dist/cli/config.js +84 -0
  7. package/dist/cli/config.js.map +1 -0
  8. package/dist/cli/health.d.ts +7 -0
  9. package/dist/cli/health.d.ts.map +1 -0
  10. package/dist/cli/health.js +32 -0
  11. package/dist/cli/health.js.map +1 -0
  12. package/dist/config.d.ts +44 -0
  13. package/dist/config.d.ts.map +1 -0
  14. package/dist/config.js +65 -0
  15. package/dist/config.js.map +1 -0
  16. package/dist/fetch/archive.d.ts +13 -0
  17. package/dist/fetch/archive.d.ts.map +1 -0
  18. package/dist/fetch/archive.js +115 -0
  19. package/dist/fetch/archive.js.map +1 -0
  20. package/dist/fetch/backup.d.ts +77 -0
  21. package/dist/fetch/backup.d.ts.map +1 -0
  22. package/dist/fetch/backup.js +292 -0
  23. package/dist/fetch/backup.js.map +1 -0
  24. package/dist/fetch/index.d.ts +2 -1
  25. package/dist/fetch/index.d.ts.map +1 -1
  26. package/dist/fetch/index.js +3 -1
  27. package/dist/fetch/index.js.map +1 -1
  28. package/dist/fetch/paths.d.ts +5 -3
  29. package/dist/fetch/paths.d.ts.map +1 -1
  30. package/dist/fetch/paths.js +19 -24
  31. package/dist/fetch/paths.js.map +1 -1
  32. package/dist/health.d.ts +41 -0
  33. package/dist/health.d.ts.map +1 -0
  34. package/dist/health.js +507 -0
  35. package/dist/health.js.map +1 -0
  36. package/dist/help/helpFile.d.ts +1 -1
  37. package/dist/help/manifest.d.ts +7 -19
  38. package/dist/help/manifest.d.ts.map +1 -1
  39. package/dist/help/manifest.js +22 -7
  40. package/dist/help/manifest.js.map +1 -1
  41. package/package.json +2 -2
package/dist/health.js ADDED
@@ -0,0 +1,507 @@
1
+ /** 居家管家自己的配置体检(票 #706):一份只读的报告,回答「我配的东西现在通不通」。
2
+ *
3
+ * 口径(票面「开工前的形状裁定」):
4
+ * · **判据住技能侧**——每条的有效值(库在哪、产物落哪个目录、包内预置件在不在)只有本包算得出来;
5
+ * 插件包与总管只透传与渲染,不重写这里的任何一个字。
6
+ * · **只报不改**——不建目录、不写文件、不落那份默认配置;凡是要建目录才算得出的结论,一律当「不在」报。
7
+ * 所以本件**不许**调 `loadHomeConfig()`(文件不在即落一份默认件),配置一律本件只读解析
8
+ * (`base-link-core` 的受限子集解析器**没有对外**,见其包门只有四条)。
9
+ * · 报告形状见面板侧镜像 `packages/plugin-manager/src/health-contract.ts`(唯一消费者)。
10
+ *
11
+ * 检查项与检查表 `docs/research/check-table-671-life-panel-20260917.html` 逐条对应:
12
+ * 六家通用 5 条(配置文件本身/数据目录/库文件表数/产物目录/这个值从哪来)
13
+ * + 居家特有 4 条(产物根 vs 库根/种子分类/主密钥文件/包内模板目录)。
14
+ *
15
+ * **判据查的路径一律是新仓的**(票面第 2 条「缺配置会怎样按新仓+新机制写」):检查表里那些老仓
16
+ * 文件名(例:种子分类的老 `references/seed_categories.yaml`)只作注释里的出处,不进用户看到的报文。
17
+ *
18
+ * 本件与卡路里那份 `packages/skill-calorie/src/health.ts` 同形(同一套受限子集解析、同一套写探针、
19
+ * 同一个 `node:sqlite` 只读读表数),只换本家那份配置表与自有项——读的人一眼认得出是同一条链。
20
+ */
21
+ import { existsSync, readdirSync, readFileSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
22
+ import { homedir } from 'node:os';
23
+ import { dirname, join } from 'node:path';
24
+ import { fileURLToPath } from 'node:url';
25
+ import { DatabaseSync } from 'node:sqlite';
26
+ import { configPaths } from 'base-link-core';
27
+ import { HOME_CONFIG_DEFAULTS, HOME_CONFIG_STEM } from './config.js';
28
+ /** 库表数门槛:`src/fetch/db.ts` 的建表语句里那 16 张表齐了才算正常(少了报黄:还能用,但缺功能的表要重建)。 */
29
+ export const DB_TABLE_THRESHOLD = 16;
30
+ const SKILL = 'home';
31
+ /** 主密钥文件名(老 `accounts.py:32-56` 四级定位的那个文件名,逐字不变)。 */
32
+ const MASTER_KEY_NAME = '.master.key';
33
+ /** 包根:`dist/health.js` 上一级。 */
34
+ function packageRoot() {
35
+ return join(dirname(fileURLToPath(import.meta.url)), '..');
36
+ }
37
+ /** 人话里的路径一律用正斜杠:报告给页面看,也让跨平台读数可比。 */
38
+ function p(path) {
39
+ return path.replace(/\\/g, '/');
40
+ }
41
+ /**
42
+ * 只读解析那份配置文件(与 `base-link-core` 的受限子集同一套校验,口径逐条对齐):
43
+ * 剥 BOM、去 `\r`、空行与整行注释跳过、缩进只许 2 个空格且不许制表符、不支持列表、
44
+ * 一行须是「键: 值」、不许重复定义、顶层键冒号后没值即开一个组。
45
+ *
46
+ * 与 `loadConfig()` 的差别只有一处、也正是本件要的那一处:**文件不在时不落默认件**。
47
+ * 取值语义与它一致:文件里缺的项按默认值补。
48
+ */
49
+ export function readHomeConfigReadOnly() {
50
+ const file = configPaths(HOME_CONFIG_STEM).configFile;
51
+ if (!existsSync(file))
52
+ return { kind: 'missing' };
53
+ let text;
54
+ try {
55
+ text = readFileSync(file, 'utf8');
56
+ }
57
+ catch (e) {
58
+ return { kind: 'bad', message: '读配置文件失败:' + file + '(' + (e instanceof Error ? e.message : String(e)) + ')' };
59
+ }
60
+ const parsed = parseSubset(text, file);
61
+ if (!parsed.ok)
62
+ return { kind: 'bad', message: parsed.message };
63
+ return { kind: 'ok', values: projectOnDefaults(parsed.values), present: presentKeysOf(parsed.values) };
64
+ }
65
+ /** 文件里真写了哪些键(扁平成 `组.键`):给「这个值从哪来」那条判据用。
66
+ *
67
+ * 为什么不能直接看投到默认值表之后的值:**空串=按默认落点**——留空的项值看起来与默认值一样,
68
+ * 但它的来源是「用户写了空串」,不是「文件里没有这一项」。混起来就会把来源报错。 */
69
+ function presentKeysOf(values) {
70
+ const out = new Set();
71
+ for (const [group, got] of Object.entries(values)) {
72
+ if (typeof got !== 'object' || got === null) {
73
+ out.add(group);
74
+ continue;
75
+ }
76
+ for (const key of Object.keys(got))
77
+ out.add(group + '.' + key);
78
+ }
79
+ return out;
80
+ }
81
+ /** 受限子集的极简解析:只算值与行号,不算别的(校验口径与配置件同一套)。 */
82
+ function parseSubset(text, file) {
83
+ const source = text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
84
+ const lines = source.replace(/\r\n?/g, '\n').split('\n');
85
+ const values = {};
86
+ const lineOf = new Map();
87
+ let openGroup = null;
88
+ let openGroupLine = 0;
89
+ /** 标量解析的失败口:`parseScalar` 把报文写进 `scalarError`,调用处读它即可(不抛,免得类型糊)。 */
90
+ let scalarError = '';
91
+ const fail = (line, why) => ({ ok: false, message: '配置件第 ' + String(line) + ' 行:' + why + '(文件:' + file + ')' });
92
+ const closeGroup = () => {
93
+ if (openGroup !== null && Object.keys(values[openGroup]).length === 0) {
94
+ return fail(openGroupLine, '键「' + openGroup + '」冒号后没有值,也没有子项').message;
95
+ }
96
+ openGroup = null;
97
+ return null;
98
+ };
99
+ for (let i = 0; i < lines.length; i += 1) {
100
+ const lineNo = i + 1;
101
+ const raw = lines[i] ?? '';
102
+ if (raw.trim() === '')
103
+ continue;
104
+ if (/^\s*#/.test(raw))
105
+ continue;
106
+ const head = /^[ \t]*/.exec(raw)?.[0] ?? '';
107
+ const body = raw.slice(head.length);
108
+ if (head.includes('\t'))
109
+ return fail(lineNo, '缩进里有制表符:本子集只许空格,且嵌套缩进恰好 2 个空格');
110
+ if (body.startsWith('-'))
111
+ return fail(lineNo, '本子集不支持列表(「-」开头的行)');
112
+ const matched = /^([A-Za-z_][A-Za-z0-9_.-]*)[ \t]*:[ \t]*(.*)$/.exec(body);
113
+ if (matched === null)
114
+ return fail(lineNo, '不是「键: 值」形状:' + body.trim());
115
+ const key = matched[1];
116
+ const rest = (matched[2] ?? '').trim();
117
+ if (head.length > 0) {
118
+ if (head.length !== 2)
119
+ return fail(lineNo, '缩进必须恰好 2 个空格(本子集只支持一层嵌套),实为 ' + String(head.length) + ' 个空格');
120
+ if (openGroup === null)
121
+ return fail(lineNo, '缩进的子项「' + key + '」上面没有开着子的顶层键');
122
+ const group = values[openGroup];
123
+ if (Object.prototype.hasOwnProperty.call(group, key)) {
124
+ return fail(lineNo, '键「' + openGroup + '.' + key + '」重复定义(第 ' + String(lineOf.get(openGroup + '.' + key)) + ' 行已定义)');
125
+ }
126
+ if (rest === '')
127
+ return fail(lineNo, '键「' + openGroup + '.' + key + '」冒号后没有值');
128
+ const scalar = parseScalar(rest, lineNo, fail, (message) => {
129
+ scalarError = message;
130
+ });
131
+ if (scalarError !== '')
132
+ return { ok: false, message: scalarError };
133
+ group[key] = scalar;
134
+ lineOf.set(openGroup + '.' + key, lineNo);
135
+ continue;
136
+ }
137
+ const closedError = closeGroup();
138
+ if (closedError !== null)
139
+ return { ok: false, message: closedError };
140
+ if (Object.prototype.hasOwnProperty.call(values, key)) {
141
+ return fail(lineNo, '键「' + key + '」重复定义(第 ' + String(lineOf.get(key)) + ' 行已定义)');
142
+ }
143
+ lineOf.set(key, lineNo);
144
+ if (rest === '') {
145
+ values[key] = {};
146
+ openGroup = key;
147
+ openGroupLine = lineNo;
148
+ continue;
149
+ }
150
+ const scalar = parseScalar(rest, lineNo, fail, (message) => {
151
+ scalarError = message;
152
+ });
153
+ if (scalarError !== '')
154
+ return { ok: false, message: scalarError };
155
+ values[key] = scalar;
156
+ }
157
+ const tailError = closeGroup();
158
+ if (tailError !== null)
159
+ return { ok: false, message: tailError };
160
+ return { ok: true, values };
161
+ }
162
+ /** 标量:带引号/数字/布尔/裸字符串(值后的 `#` 注释照配置件同一口径切掉)。 */
163
+ function parseScalar(text, lineNo, fail, onError) {
164
+ const first = text[0];
165
+ if (first === '"' || first === "'") {
166
+ const quote = first;
167
+ let out = '';
168
+ let i = 1;
169
+ let closed = false;
170
+ for (; i < text.length; i += 1) {
171
+ const ch = text[i];
172
+ if (ch === quote) {
173
+ if (quote === "'" && text[i + 1] === "'") {
174
+ out += "'";
175
+ i += 1;
176
+ continue;
177
+ }
178
+ closed = true;
179
+ break;
180
+ }
181
+ if (quote === '"' && ch === '\\') {
182
+ const next = text[i + 1];
183
+ out += next === 'n' ? '\n' : next === 't' ? '\t' : (next ?? '');
184
+ i += 1;
185
+ continue;
186
+ }
187
+ out += ch;
188
+ }
189
+ if (!closed) {
190
+ onError(fail(lineNo, '引号没有闭合:' + text).message);
191
+ return '';
192
+ }
193
+ return out;
194
+ }
195
+ let cut = text.length;
196
+ for (let i = 0; i < text.length; i += 1) {
197
+ if (text[i] === '#' && (i === 0 || /\s/.test(text[i - 1]))) {
198
+ cut = i;
199
+ break;
200
+ }
201
+ }
202
+ const body = text.slice(0, cut).trim();
203
+ if (body === '') {
204
+ onError(fail(lineNo, '冒号后没有值(只有注释)').message);
205
+ return '';
206
+ }
207
+ if (body === 'true')
208
+ return true;
209
+ if (body === 'false')
210
+ return false;
211
+ if (/^-?(\d+\.?\d*|\.\d+)$/.test(body))
212
+ return Number(body);
213
+ return body;
214
+ }
215
+ /** 把文件里读到的取值投到默认值表的形状上(缺项补默认值;组内只取默认值表认得的键)。 */
216
+ function projectOnDefaults(values) {
217
+ const out = {};
218
+ for (const [group, def] of Object.entries(HOME_CONFIG_DEFAULTS)) {
219
+ const bucket = {};
220
+ const got = values[group];
221
+ const source = typeof got === 'object' && got !== null ? got : {};
222
+ for (const [key, defValue] of Object.entries(def)) {
223
+ const mine = source[key];
224
+ bucket[key] = typeof mine === typeof defValue ? mine : defValue;
225
+ }
226
+ out[group] = bucket;
227
+ }
228
+ return out;
229
+ }
230
+ /** 取值:一层嵌套按 `组.键` 读(缺层或类型不符回 undefined)。 */
231
+ function readValue(values, group, key) {
232
+ return values[group]?.[key];
233
+ }
234
+ /** 有值的字符串(空串=未配,按 `undefined` 处理,语义与各取用处一致)。 */
235
+ function textOf(value) {
236
+ return typeof value === 'string' && value.trim() !== '' ? value : '';
237
+ }
238
+ /** 「这个值从哪来」:真在文件里写了就是「配置文件」,否则按默认值(文件不存在则全按默认值)。 */
239
+ function sourceOf(present, key) {
240
+ return present.has(key) ? '配置文件' : '默认值';
241
+ }
242
+ /** 目录那一项的形状是**段串**(本家默认 `home_manager_html` 一段),段数与 `src/config.ts` 自己的
243
+ * `splitDirSegments` 同一口径。本件不 import 它:health 面与配置面互锁没有好处,而这条规则只有三行。 */
244
+ function splitDirSegments(value) {
245
+ return value.split(/[\\/]+/).filter((s) => s.length > 0);
246
+ }
247
+ /** 主密钥文件按老 `accounts.py:32-56` 那四级定位的**第一处存在**位置(照源码算,不猜):
248
+ * ① 数据目录(老技能里是 `SKILLS_DB_PATH` 那一档)→ ② 包根 → ③ 包根任一父目录下的 `.db/` → ④ 包根下的 `.db/`。
249
+ * 老实现在第 ① 档是「无论是否存在都用它」,新仓的数据目录恒有默认值,故这里仍按「四级里第一处真在的」
250
+ * 报;一处都没有时报第 ① 档那个落点(用它说明「该放哪」)。 */
251
+ function masterKeyCandidates(dataDir) {
252
+ const root = packageRoot();
253
+ const parents = [];
254
+ let now = dirname(root);
255
+ for (;;) {
256
+ parents.push(join(now, '.db', MASTER_KEY_NAME));
257
+ const up = dirname(now);
258
+ if (up === now)
259
+ break;
260
+ now = up;
261
+ }
262
+ return [join(dataDir, MASTER_KEY_NAME), join(root, MASTER_KEY_NAME), ...parents, join(root, '.db', MASTER_KEY_NAME)];
263
+ }
264
+ /** 目录能不能写:建一个探针文件再删掉(老技能三家同一套做法)。**不建目录本身**。 */
265
+ function writeProbe(dir) {
266
+ const probe = join(dir, '.ilife-health-probe-' + String(process.pid) + '-' + String(Date.now()));
267
+ try {
268
+ writeFileSync(probe, 'probe', { encoding: 'utf8', flag: 'wx' });
269
+ unlinkSync(probe);
270
+ return { ok: true, reason: '' };
271
+ }
272
+ catch (e) {
273
+ return { ok: false, reason: e instanceof Error ? e.message : String(e) };
274
+ }
275
+ }
276
+ /** 已算过的目录结论按路径记一份:同一份报告里同一个目录不重复起写探针。 */
277
+ const dirMemo = new Map();
278
+ function dirVerdict(dir) {
279
+ const memoized = dirMemo.get(dir);
280
+ if (memoized !== undefined)
281
+ return memoized;
282
+ const verdict = dirVerdictUncached(dir);
283
+ dirMemo.set(dir, verdict);
284
+ return verdict;
285
+ }
286
+ function dirVerdictUncached(dir) {
287
+ if (!existsSync(dir))
288
+ return { exists: false, writable: false, reason: '' };
289
+ try {
290
+ if (!statSync(dir).isDirectory())
291
+ return { exists: false, writable: false, reason: '同名文件占了它的位置' };
292
+ }
293
+ catch (e) {
294
+ return { exists: false, writable: false, reason: e instanceof Error ? e.message : String(e) };
295
+ }
296
+ const probe = writeProbe(dir);
297
+ return { exists: true, writable: probe.ok, reason: probe.reason };
298
+ }
299
+ /** 模板件数:把 `templates/` 数一遍(只数 `.html`,含子目录;读不出来的子树按 0 计)。
300
+ * 报文里给这个数,是为了让「包内模板目录在不在」这句话能自证——件数对不上就是包装不完整。 */
301
+ function templateFileCount(dir) {
302
+ let entries;
303
+ try {
304
+ entries = readdirSync(dir, { withFileTypes: true });
305
+ }
306
+ catch {
307
+ return 0;
308
+ }
309
+ let out = 0;
310
+ for (const entry of entries) {
311
+ out += entry.isDirectory()
312
+ ? templateFileCount(join(dir, entry.name))
313
+ : (entry.name.endsWith('.html') ? 1 : 0);
314
+ }
315
+ return out;
316
+ }
317
+ /** 开库读表数(只读打开,不建库、不迁移)。打不开即当作「读不出」。 */
318
+ function tableCount(file) {
319
+ let db = null;
320
+ try {
321
+ db = new DatabaseSync(file, { readOnly: true });
322
+ const rows = db.prepare("SELECT name FROM sqlite_master WHERE type = 'table'").all();
323
+ const names = rows.map((row) => String(row.name ?? '')).filter((name) => name !== '' && !name.startsWith('sqlite_'));
324
+ return { ok: true, count: names.length, reason: '' };
325
+ }
326
+ catch (e) {
327
+ return { ok: false, count: 0, reason: e instanceof Error ? e.message : String(e) };
328
+ }
329
+ finally {
330
+ try {
331
+ db?.close();
332
+ }
333
+ catch {
334
+ /* 关不掉不影响结论 */
335
+ }
336
+ }
337
+ }
338
+ /** 跑一次体检,返回整份报告。**只读**:任何一处都不落盘(只有写探针那一个文件,且当场删掉)。 */
339
+ export function buildHomeHealthReport() {
340
+ const paths = configPaths(HOME_CONFIG_STEM);
341
+ const items = [];
342
+ const read = readHomeConfigReadOnly();
343
+ const values = read.kind === 'ok' ? read.values : projectOnDefaults({});
344
+ const present = read.kind === 'ok' ? read.present : new Set();
345
+ // ① 配置文件本身:能不能解析;它落在默认位置还是被 ILIFE_CONFIG_DIR 指到别处(只陈述,不评价)。
346
+ const defaultConfigFile = join(homedir(), '.ilife', HOME_CONFIG_STEM + '.yaml');
347
+ const relocated = paths.configFile !== defaultConfigFile;
348
+ const where = relocated ? '位置被 ILIFE_CONFIG_DIR 指到这里' : '默认位置';
349
+ if (read.kind === 'bad') {
350
+ items.push({
351
+ id: 'config.file', title: '配置文件', status: 'red',
352
+ message: read.message,
353
+ action: '照报文指的行号改回「键: 值」的写法;改不动就删掉这个文件,让技能按默认值重落一份。',
354
+ source: '配置文件',
355
+ });
356
+ }
357
+ else if (read.kind === 'missing') {
358
+ items.push({
359
+ id: 'config.file', title: '配置文件', status: 'yellow',
360
+ message: '配置文件还不存在:' + p(paths.configFile) + '(现在跑的是默认值)。',
361
+ action: '在面板上保存一次即会落一份;也可点「重置为默认」。',
362
+ source: '默认值',
363
+ });
364
+ }
365
+ else {
366
+ items.push({
367
+ id: 'config.file', title: '配置文件', status: 'green',
368
+ message: '能解析:' + p(paths.configFile) + '(' + where + ')。',
369
+ action: '',
370
+ source: '配置文件',
371
+ });
372
+ }
373
+ // ② 数据目录:在不在、能不能写。
374
+ const dbDirConfigured = textOf(readValue(values, 'db', 'dir'));
375
+ const dataDir = dbDirConfigured !== '' ? dbDirConfigured : paths.dataDir;
376
+ const dataDirSource = sourceOf(present, 'db.dir');
377
+ const dataDirVerdict = dirVerdict(dataDir);
378
+ items.push({
379
+ id: 'db.dir', title: '数据目录',
380
+ status: !dataDirVerdict.exists || !dataDirVerdict.writable ? 'red' : 'green',
381
+ message: !dataDirVerdict.exists
382
+ ? '不在:' + p(dataDir) + (dataDirVerdict.reason !== '' ? '(' + dataDirVerdict.reason + ')' : '')
383
+ : dataDirVerdict.writable
384
+ ? '在且能写:' + p(dataDir) + '。'
385
+ : '在,但写不进去:' + p(dataDir) + '(' + dataDirVerdict.reason + ')。',
386
+ action: !dataDirVerdict.exists
387
+ ? '先建这个目录,或把配置里的「数据目录」改到一个已存在的位置。'
388
+ : dataDirVerdict.writable ? '' : '去掉这个目录的只读属性,或把「数据目录」改到别处。',
389
+ source: dataDirSource,
390
+ });
391
+ // ③ 库文件:在不在 + 表数够不够。
392
+ const dbNameConfigured = textOf(readValue(values, 'db', 'name'));
393
+ const dbName = dbNameConfigured !== '' ? dbNameConfigured : String(HOME_CONFIG_DEFAULTS.db.name);
394
+ const dbFile = join(dataDir, dbName);
395
+ const dbSource = sourceOf(present, 'db.name');
396
+ if (!existsSync(dbFile)) {
397
+ items.push({
398
+ id: 'db.file', title: '库文件', status: 'red',
399
+ message: '不在:' + p(dbFile) + '。',
400
+ action: '确认「数据目录」与「库文件名」对不对;新装的话,跑一条会写库的命令即会建库。',
401
+ source: dbSource,
402
+ });
403
+ }
404
+ else {
405
+ const tables = tableCount(dbFile);
406
+ if (!tables.ok) {
407
+ items.push({
408
+ id: 'db.file', title: '库文件', status: 'red',
409
+ message: '在,但打不开:' + p(dbFile) + '(' + tables.reason + ')。',
410
+ action: '这个文件可能不是库文件或已损坏;先备份,再看要不要让技能重建一份。',
411
+ source: dbSource,
412
+ });
413
+ }
414
+ else if (tables.count < DB_TABLE_THRESHOLD) {
415
+ items.push({
416
+ id: 'db.file', title: '库文件', status: 'yellow',
417
+ message: '在,但表不全:' + p(dbFile) + '(' + String(tables.count) + ' / ' + String(DB_TABLE_THRESHOLD) + ' 张表)。',
418
+ action: '缺表会让对应的功能报错;跑一次会写库的命令让它补齐,或从备份恢复。',
419
+ source: dbSource,
420
+ });
421
+ }
422
+ else {
423
+ items.push({
424
+ id: 'db.file', title: '库文件', status: 'green',
425
+ message: '在,' + String(tables.count) + ' 张表齐:' + p(dbFile) + '。',
426
+ action: '',
427
+ source: dbSource,
428
+ });
429
+ }
430
+ }
431
+ // ④ 产物目录:在不在、能不能写(还没建=绿:交付页面时才落这里,那时自动建)。
432
+ const htmlDirValue = textOf(readValue(values, 'html', 'dir'));
433
+ const htmlDir = join(dataDir, ...splitDirSegments(htmlDirValue !== '' ? htmlDirValue : String(HOME_CONFIG_DEFAULTS.html.dir)));
434
+ const htmlVerdict = dirVerdict(htmlDir);
435
+ const htmlSource = sourceOf(present, 'html.dir');
436
+ items.push({
437
+ id: 'html.dir', title: '产物目录',
438
+ status: !htmlVerdict.exists ? 'green' : htmlVerdict.writable ? 'green' : 'yellow',
439
+ message: !htmlVerdict.exists
440
+ ? '还没建:' + p(htmlDir) + '(交付页面时才落这里,那时自动建)。'
441
+ : htmlVerdict.writable
442
+ ? '在且能写:' + p(htmlDir) + '。'
443
+ : '在,但写不进去:' + p(htmlDir) + '(交付会转成内联回执,不再落盘)。',
444
+ action: !htmlVerdict.exists || htmlVerdict.writable ? '' : '去掉这个目录的只读属性,或把「HTML 产物目录名」改到别处。',
445
+ source: htmlSource,
446
+ });
447
+ // ⑤ 这个值从哪来:只陈述数据目录与库文件名的来源,不判好坏(六家通用最后一条)。
448
+ items.push({
449
+ id: 'value.source', title: '这个值从哪来', status: 'green',
450
+ message: '数据目录走「' + dataDirSource + '」,库文件名走「' + dbSource + '」'
451
+ + (read.kind === 'missing' ? '(配置文件还不存在,落点全按默认值)。' : '。'),
452
+ action: '', source: dataDirSource,
453
+ });
454
+ // ⑥ 产物根 vs 库根(居家特有):两处并排显示;不一样=黄(产物与库分离,不是故障),一样=绿。
455
+ const sameRoot = htmlDir === dataDir;
456
+ items.push({
457
+ id: 'paths.split', title: '产物根 vs 库根',
458
+ status: sameRoot ? 'green' : 'yellow',
459
+ message: sameRoot
460
+ ? '两处同一处:产物根 ' + p(htmlDir) + ',库根 ' + p(dataDir) + '。'
461
+ : '产物根 ' + p(htmlDir) + ',库根 ' + p(dataDir) + '(产物与库分离,不是故障)。',
462
+ action: sameRoot ? '' : '这是默认布局:页面产物落在库旁边的产物目录里,库文件仍在库根。想把产物也放库根,就把「HTML 产物目录名」留空或用 `.`。',
463
+ source: htmlSource,
464
+ });
465
+ // ⑦ 种子分类(居家特有):查的是**新仓这份口径的入口件**=`src/policy/category.ts`
466
+ // (`HOME_TOPS` 那 8 个顶级分类;老仓那个 `references/seed_categories.yaml` 只作注释里的出处,
467
+ // 不出现报文里——新仓没有 `references/` 这个目录)。不在=黄:包内源码件,缺了多半是包装坏了。
468
+ const seedSource = join(packageRoot(), 'src', 'policy', 'category.ts');
469
+ const seedExists = existsSync(seedSource);
470
+ items.push({
471
+ id: 'seed.file', title: '种子分类',
472
+ // 档位=检查表原话「不在=红」(`docs/research/check-table-671-life-panel-20260917.html` 居家那行)。
473
+ // 中间几轮曾按「新仓没有这个文件、缺的是包内源码件」下调成黄——那是**改判据**,对抗式审查两轴都点了;
474
+ // 按「判据是用户逐条划过的唯一真相」还原成红。
475
+ status: seedExists ? 'green' : 'red',
476
+ message: seedExists
477
+ ? '在:' + p(seedSource) + '(新仓的种子分类口径住这里)。'
478
+ : '不在:' + p(seedSource) + '(新仓的种子分类口径;包内源码件,缺了多半是包装坏了)。',
479
+ action: seedExists ? '' : '重装这个技能包即会补齐;缺了它建分类时没有顶级分类口径。',
480
+ });
481
+ // ⑧ 主密钥文件(居家特有):在=绿;不在=黄(只在用票据凭证/账号密码时才是红)。
482
+ const keyCandidates = masterKeyCandidates(dataDir);
483
+ const keyFile = keyCandidates.find((candidate) => existsSync(candidate)) ?? keyCandidates[0];
484
+ const keyExists = existsSync(keyFile);
485
+ items.push({
486
+ id: 'key.file', title: '主密钥文件',
487
+ status: keyExists ? 'green' : 'yellow',
488
+ message: keyExists
489
+ ? '在:' + p(keyFile) + '。'
490
+ : '不在:' + p(keyFile) + '(四级定位都没找到;只在用票据凭证/存账号密码时才是故障)。',
491
+ action: keyExists ? '' : '要用「存账号/看密码」就先把这个文件建出来(老技能用的是四级定位,任一处皆可)。',
492
+ });
493
+ // ⑨ 包内模板目录(居家特有):业务页模板是包内固定件,缺了页面就渲染不出来 ⇒ 红。报文给件数。
494
+ const templatesDir = join(packageRoot(), 'templates');
495
+ const templatesOk = existsSync(templatesDir);
496
+ const templateCount = templatesOk ? templateFileCount(templatesDir) : 0;
497
+ items.push({
498
+ id: 'templates.dir', title: '包内模板目录',
499
+ status: templatesOk ? 'green' : 'red',
500
+ message: templatesOk
501
+ ? '在,' + String(templateCount) + ' 件模板:' + p(templatesDir) + '。'
502
+ : '不在:' + p(templatesDir) + '。',
503
+ action: templatesOk ? '' : '技能包装得不完整:重装这个技能包,或跑一次它的构建。',
504
+ });
505
+ return { skill: SKILL, configPath: p(paths.configFile), dataDir: p(dataDir), items };
506
+ }
507
+ //# sourceMappingURL=health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.js","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"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"}
@@ -32,7 +32,7 @@ interface HomeHelpInitBanner {
32
32
  * `dbPath`/`fileExists` 为什么必须由调用方给:见件头「只读页不建库」。
33
33
  * `fileExists` 与 `existsSync` 参数同形(`no side effect` 的只读判据)。 */
34
34
  interface HomeHelpFileOptions {
35
- /** DB **文件**路径(调用方从 `SKILLS_DB_PATH` 解析后传入;缺位/为空 ⇒ 横幅照显)。
35
+ /** DB **文件**路径(调用方按配置项 `db.dir`(空串=数据目录)+库文件名解析后传入;缺位/为空 ⇒ 横幅照显)。
36
36
  * ⚠️ 不要传 `resolveDbPath()` 的返回值——那一步会 `mkdirSync`。 */
37
37
  readonly dbPath?: string;
38
38
  /** 库文件存在判据(可注入;缺省 `existsSync`;抛异常一律当「不存在」)。 */
@@ -1,23 +1,11 @@
1
- /** #190 · 居家管家 HELP 产物的**三个落点值**(零逻辑、零 IO;导出面按铁律五只出值,不出函数)。
2
- *
3
- * 三个值=调用者能给的最小信息:① 落点子目录名;② HELP 文件名主体;③ 速查支文件名主体。
4
- * 出口层(`src/cli/cmd_read.ts`)拿它拼出共用件 `base-paint/save-html` 要的 `{dir, stem}`,
5
- * 再交给 `src/help/output.ts` 那次调用——本件不碰 IO、不认 `SKILLS_DB_PATH`。
6
- *
7
- * ⚠️ **时间戳通式(`YYYYMMDD_HHMMSS`)/同秒 `_N` 递补/独占写(`wx` + `EEXIST`)/复用窗口/
8
- * 绝对路径回执一概不在这里**:`#237` 起唯一定义地是共用件 `saveHtmlFile`
9
- * (`packages/base-render/src/output/saveHtml.ts`,账单/卡路里/大厨/作息/备忘五家在用)。
10
- * 写在这里就是同一件事的第二份定义(铁律二)——账单旧版的 `nextExclusiveCandidate`/
11
- * `writeFileExclusiveWithRetry` 已经搬进共用件,**不许抄回来**。
12
- *
13
- * 老件对应物:老 `help_center.py` 的
14
- * `<SKILLS_DB_PATH>/home_manager_html/居家管家_HELP_<YYYYMMDD_HHMMSS>.html`(目录名逐字保留,无 `help/` 子层)。
15
- */
16
- /** 落点子目录名:产物=`<SKILLS_DB_PATH>/home_manager_html/…`(老家目录名逐字)。 */
17
- export declare const HELP_HTML_DIR_NAME: "home_manager_html";
1
+ /** 落点子目录的默认值:=改造前的代码常量 `HELP_HTML_DIR_NAME`(一段,老家目录名逐字)。 */
2
+ export declare const DEFAULT_HELP_DIR_NAME: "home_manager_html";
3
+ /** 落点子目录名(配置项 `html.dir`,空串=默认):产物=`<库目录>/<它>/…`。
4
+ * 家是**一段**目录,故段串经 `splitDirSegments` 归一再拼回一个名字(配置若给多段,`join` 照样吃得下)。 */
5
+ export declare function helpDirName(): string;
18
6
  /** HELP 文件名主体:产物=`居家管家_HELP_<YYYYMMDD_HHMMSS>[_N].html`(老通式逐字;递补起步值走共用件缺省)。 */
19
- export declare const HELP_FILE_STEM: "\u5C45\u5BB6\u7BA1\u5BB6_HELP";
7
+ export declare function helpFileStem(): string;
20
8
  /** 速查支的文件名主体:与 HELP 文件**分名**(照 #139 判法——别让用户按一个名字打开到另一个东西)。
21
9
  * 老家只有 HELP 一支、无老名可循;取名照样板图 #143(账单的 `饼干记账_速查表`/卡路里的 `卡路里_速查台`)同一后缀。 */
22
- export declare const LOOKUP_FILE_STEM: "\u5C45\u5BB6\u7BA1\u5BB6_\u901F\u67E5\u8868";
10
+ export declare function lookupFileStem(): string;
23
11
  //# sourceMappingURL=manifest.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/help/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,iEAAiE;AACjE,eAAO,MAAM,kBAAkB,EAAG,mBAA4B,CAAC;AAE/D,+EAA+E;AAC/E,eAAO,MAAM,cAAc,EAAG,+BAAoB,CAAC;AAEnD;yEACyE;AACzE,eAAO,MAAM,gBAAgB,EAAG,6CAAmB,CAAC"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/help/manifest.ts"],"names":[],"mappings":"AAqBA,4DAA4D;AAC5D,eAAO,MAAM,qBAAqB,EAAG,mBAA4B,CAAC;AAElE;yEACyE;AACzE,wBAAgB,WAAW,IAAI,MAAM,CAGpC;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;yEACyE;AACzE,wBAAgB,cAAc,IAAI,MAAM,CAEvC"}
@@ -1,8 +1,12 @@
1
- /** #190 · 居家管家 HELP 产物的**三个落点值**(零逻辑、零 IO;导出面按铁律五只出值,不出函数)。
1
+ /** #190 · 居家管家 HELP 产物的**三个落点值**(本技能自己的三个值;都是函数,值从配置文件取)。
2
2
  *
3
3
  * 三个值=调用者能给的最小信息:① 落点子目录名;② HELP 文件名主体;③ 速查支文件名主体。
4
4
  * 出口层(`src/cli/cmd_read.ts`)拿它拼出共用件 `base-paint/save-html` 要的 `{dir, stem}`,
5
- * 再交给 `src/help/output.ts` 那次调用——本件不碰 IO、不认 `SKILLS_DB_PATH`。
5
+ * 再交给 `src/help/output.ts` 那次调用——本件不碰 IO、不认环境变量。
6
+ *
7
+ * **#695 起值的唯一事实源是配置文件**(`~/.ilife/home.yaml`,默认值表住 `src/config.ts`):本件从配置取,
8
+ * 空串回落到默认;目录那一项是**段串**,段数由值自己决定——老技能里大厨/作息是两段,备忘/居家是**一段**
9
+ * (`home_manager_html`),同一套配置形状要能表达「几段」。
6
10
  *
7
11
  * ⚠️ **时间戳通式(`YYYYMMDD_HHMMSS`)/同秒 `_N` 递补/独占写(`wx` + `EEXIST`)/复用窗口/
8
12
  * 绝对路径回执一概不在这里**:`#237` 起唯一定义地是共用件 `saveHtmlFile`
@@ -11,13 +15,24 @@
11
15
  * `writeFileExclusiveWithRetry` 已经搬进共用件,**不许抄回来**。
12
16
  *
13
17
  * 老件对应物:老 `help_center.py` 的
14
- * `<SKILLS_DB_PATH>/home_manager_html/居家管家_HELP_<YYYYMMDD_HHMMSS>.html`(目录名逐字保留,无 `help/` 子层)。
18
+ * `<数据目录>/home_manager_html/居家管家_HELP_<YYYYMMDD_HHMMSS>.html`(目录名逐字保留,无 `help/` 子层)。
15
19
  */
16
- /** 落点子目录名:产物=`<SKILLS_DB_PATH>/home_manager_html/…`(老家目录名逐字)。 */
17
- export const HELP_HTML_DIR_NAME = 'home_manager_html';
20
+ import { loadHomeConfig, splitDirSegments } from '../config.js';
21
+ /** 落点子目录的默认值:=改造前的代码常量 `HELP_HTML_DIR_NAME`(一段,老家目录名逐字)。 */
22
+ export const DEFAULT_HELP_DIR_NAME = 'home_manager_html';
23
+ /** 落点子目录名(配置项 `html.dir`,空串=默认):产物=`<库目录>/<它>/…`。
24
+ * 家是**一段**目录,故段串经 `splitDirSegments` 归一再拼回一个名字(配置若给多段,`join` 照样吃得下)。 */
25
+ export function helpDirName() {
26
+ const dir = loadHomeConfig().values.html.dir;
27
+ return splitDirSegments(dir === '' ? DEFAULT_HELP_DIR_NAME : dir).join('/');
28
+ }
18
29
  /** HELP 文件名主体:产物=`居家管家_HELP_<YYYYMMDD_HHMMSS>[_N].html`(老通式逐字;递补起步值走共用件缺省)。 */
19
- export const HELP_FILE_STEM = '居家管家_HELP';
30
+ export function helpFileStem() {
31
+ return loadHomeConfig().values.files.help;
32
+ }
20
33
  /** 速查支的文件名主体:与 HELP 文件**分名**(照 #139 判法——别让用户按一个名字打开到另一个东西)。
21
34
  * 老家只有 HELP 一支、无老名可循;取名照样板图 #143(账单的 `饼干记账_速查表`/卡路里的 `卡路里_速查台`)同一后缀。 */
22
- export const LOOKUP_FILE_STEM = '居家管家_速查表';
35
+ export function lookupFileStem() {
36
+ return loadHomeConfig().values.files.lookup;
37
+ }
23
38
  //# sourceMappingURL=manifest.js.map