skill-memo-ilife 0.3.0 → 0.3.2

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 (253) hide show
  1. package/SKILL.md +10 -8
  2. package/dist/checkin/routes.d.ts +9 -0
  3. package/dist/checkin/routes.d.ts.map +1 -0
  4. package/dist/checkin/routes.js +29 -0
  5. package/dist/checkin/routes.js.map +1 -0
  6. package/dist/cli/cmd_read.js +75 -277
  7. package/dist/cli/cmd_read.js.map +1 -1
  8. package/dist/cli/config.d.ts +16 -2
  9. package/dist/cli/config.d.ts.map +1 -1
  10. package/dist/cli/config.js +10 -7
  11. package/dist/cli/config.js.map +1 -1
  12. package/dist/cli/health/configRead.d.ts +22 -0
  13. package/dist/cli/health/configRead.d.ts.map +1 -0
  14. package/dist/cli/health/configRead.js +207 -0
  15. package/dist/cli/health/configRead.js.map +1 -0
  16. package/dist/cli/health/index.d.ts +18 -0
  17. package/dist/cli/health/index.d.ts.map +1 -0
  18. package/dist/cli/health/index.js +16 -0
  19. package/dist/cli/health/index.js.map +1 -0
  20. package/dist/cli/health/items.d.ts +19 -0
  21. package/dist/cli/health/items.d.ts.map +1 -0
  22. package/dist/cli/health/items.js +205 -0
  23. package/dist/cli/health/items.js.map +1 -0
  24. package/dist/cli/health/probe.d.ts +33 -0
  25. package/dist/cli/health/probe.d.ts.map +1 -0
  26. package/dist/cli/health/probe.js +194 -0
  27. package/dist/cli/health/probe.js.map +1 -0
  28. package/dist/cli/health.d.ts.map +1 -1
  29. package/dist/cli/health.js +3 -2
  30. package/dist/cli/health.js.map +1 -1
  31. package/dist/cli/keys.d.ts +15 -0
  32. package/dist/cli/keys.d.ts.map +1 -0
  33. package/dist/cli/keys.js +64 -0
  34. package/dist/cli/keys.js.map +1 -0
  35. package/dist/cli/registry.d.ts +10 -0
  36. package/dist/cli/registry.d.ts.map +1 -0
  37. package/dist/cli/registry.js +29 -0
  38. package/dist/cli/registry.js.map +1 -0
  39. package/dist/config.d.ts +16 -9
  40. package/dist/config.d.ts.map +1 -1
  41. package/dist/config.js +91 -20
  42. package/dist/config.js.map +1 -1
  43. package/dist/fetch/auth.d.ts +1 -11
  44. package/dist/fetch/auth.d.ts.map +1 -1
  45. package/dist/fetch/auth.js +5 -77
  46. package/dist/fetch/auth.js.map +1 -1
  47. package/dist/fetch/db.d.ts +6 -0
  48. package/dist/fetch/db.d.ts.map +1 -1
  49. package/dist/fetch/db.js +19 -0
  50. package/dist/fetch/db.js.map +1 -1
  51. package/dist/fetch/feishu.d.ts +30 -0
  52. package/dist/fetch/feishu.d.ts.map +1 -1
  53. package/dist/fetch/feishu.js +121 -19
  54. package/dist/fetch/feishu.js.map +1 -1
  55. package/dist/fetch/index.d.ts +6 -5
  56. package/dist/fetch/index.d.ts.map +1 -1
  57. package/dist/fetch/index.js +4 -4
  58. package/dist/fetch/index.js.map +1 -1
  59. package/dist/fetch/paths.d.ts +34 -1
  60. package/dist/fetch/paths.d.ts.map +1 -1
  61. package/dist/fetch/paths.js +60 -7
  62. package/dist/fetch/paths.js.map +1 -1
  63. package/dist/fetch/sentinel.d.ts.map +1 -1
  64. package/dist/fetch/sentinel.js +2 -1
  65. package/dist/fetch/sentinel.js.map +1 -1
  66. package/dist/health.d.ts +15 -38
  67. package/dist/health.d.ts.map +1 -1
  68. package/dist/health.js +11 -589
  69. package/dist/health.js.map +1 -1
  70. package/dist/help/booklet.d.ts +49 -0
  71. package/dist/help/booklet.d.ts.map +1 -0
  72. package/dist/help/booklet.js +78 -0
  73. package/dist/help/booklet.js.map +1 -0
  74. package/dist/help/index.d.ts +2 -0
  75. package/dist/help/index.d.ts.map +1 -1
  76. package/dist/help/index.js +1 -0
  77. package/dist/help/index.js.map +1 -1
  78. package/dist/help/lookup.d.ts.map +1 -1
  79. package/dist/help/lookup.js +23 -4
  80. package/dist/help/lookup.js.map +1 -1
  81. package/dist/help/manifest.d.ts +4 -0
  82. package/dist/help/manifest.d.ts.map +1 -1
  83. package/dist/help/manifest.js +11 -5
  84. package/dist/help/manifest.js.map +1 -1
  85. package/dist/init/commands.d.ts +11 -0
  86. package/dist/init/commands.d.ts.map +1 -0
  87. package/dist/init/commands.js +13 -0
  88. package/dist/init/commands.js.map +1 -0
  89. package/dist/init/diagnosis.d.ts +43 -0
  90. package/dist/init/diagnosis.d.ts.map +1 -0
  91. package/dist/init/diagnosis.js +88 -0
  92. package/dist/init/diagnosis.js.map +1 -0
  93. package/dist/init/index.d.ts +31 -0
  94. package/dist/init/index.d.ts.map +1 -0
  95. package/dist/init/index.js +14 -0
  96. package/dist/init/index.js.map +1 -0
  97. package/dist/init/page.d.ts +16 -0
  98. package/dist/init/page.d.ts.map +1 -0
  99. package/dist/init/page.js +192 -0
  100. package/dist/init/page.js.map +1 -0
  101. package/dist/init/routes.d.ts +7 -0
  102. package/dist/init/routes.d.ts.map +1 -0
  103. package/dist/init/routes.js +10 -0
  104. package/dist/init/routes.js.map +1 -0
  105. package/dist/init/run.d.ts +12 -0
  106. package/dist/init/run.d.ts.map +1 -0
  107. package/dist/init/run.js +58 -0
  108. package/dist/init/run.js.map +1 -0
  109. package/dist/memo/commands.d.ts +19 -0
  110. package/dist/memo/commands.d.ts.map +1 -0
  111. package/dist/memo/commands.js +44 -0
  112. package/dist/memo/commands.js.map +1 -0
  113. package/dist/memo/index.d.ts +8 -0
  114. package/dist/memo/index.d.ts.map +1 -0
  115. package/dist/memo/index.js +8 -0
  116. package/dist/memo/index.js.map +1 -0
  117. package/dist/memo/routes.d.ts +11 -0
  118. package/dist/memo/routes.d.ts.map +1 -0
  119. package/dist/memo/routes.js +49 -0
  120. package/dist/memo/routes.js.map +1 -0
  121. package/dist/memo/run.d.ts +26 -0
  122. package/dist/memo/run.d.ts.map +1 -0
  123. package/dist/memo/run.js +292 -0
  124. package/dist/memo/run.js.map +1 -0
  125. package/dist/mood/routes.d.ts +9 -0
  126. package/dist/mood/routes.d.ts.map +1 -0
  127. package/dist/mood/routes.js +29 -0
  128. package/dist/mood/routes.js.map +1 -0
  129. package/dist/policy/media.d.ts +2 -3
  130. package/dist/policy/media.d.ts.map +1 -1
  131. package/dist/policy/media.js +9 -10
  132. package/dist/policy/media.js.map +1 -1
  133. package/dist/policy/wakewords.d.ts +1 -1
  134. package/dist/policy/wakewords.d.ts.map +1 -1
  135. package/dist/policy/wakewords.js +18 -4
  136. package/dist/policy/wakewords.js.map +1 -1
  137. package/dist/remind/commands.d.ts +19 -0
  138. package/dist/remind/commands.d.ts.map +1 -0
  139. package/dist/remind/commands.js +21 -0
  140. package/dist/remind/commands.js.map +1 -0
  141. package/dist/remind/index.d.ts +8 -0
  142. package/dist/remind/index.d.ts.map +1 -0
  143. package/dist/remind/index.js +8 -0
  144. package/dist/remind/index.js.map +1 -0
  145. package/dist/remind/routes.d.ts +9 -0
  146. package/dist/remind/routes.d.ts.map +1 -0
  147. package/dist/remind/routes.js +25 -0
  148. package/dist/remind/routes.js.map +1 -0
  149. package/dist/remind/run.d.ts +20 -0
  150. package/dist/remind/run.d.ts.map +1 -0
  151. package/dist/remind/run.js +90 -0
  152. package/dist/remind/run.js.map +1 -0
  153. package/dist/render/envelope.d.ts.map +1 -1
  154. package/dist/render/envelope.js +5 -1
  155. package/dist/render/envelope.js.map +1 -1
  156. package/dist/render/index.d.ts +3 -1
  157. package/dist/render/index.d.ts.map +1 -1
  158. package/dist/render/index.js +3 -1
  159. package/dist/render/index.js.map +1 -1
  160. package/dist/render/pages.d.ts +16 -0
  161. package/dist/render/pages.d.ts.map +1 -1
  162. package/dist/render/pages.js +45 -0
  163. package/dist/render/pages.js.map +1 -1
  164. package/dist/render/receipt.d.ts +37 -0
  165. package/dist/render/receipt.d.ts.map +1 -0
  166. package/dist/render/receipt.js +75 -0
  167. package/dist/render/receipt.js.map +1 -0
  168. package/dist/render/templates.d.ts +1 -1
  169. package/dist/render/templates.d.ts.map +1 -1
  170. package/dist/render/templates.js +3 -1
  171. package/dist/render/templates.js.map +1 -1
  172. package/dist/search/commands.d.ts +19 -0
  173. package/dist/search/commands.d.ts.map +1 -0
  174. package/dist/search/commands.js +22 -0
  175. package/dist/search/commands.js.map +1 -0
  176. package/dist/search/index.d.ts +10 -0
  177. package/dist/search/index.d.ts.map +1 -0
  178. package/dist/search/index.js +10 -0
  179. package/dist/search/index.js.map +1 -0
  180. package/dist/search/routes.d.ts +11 -0
  181. package/dist/search/routes.d.ts.map +1 -0
  182. package/dist/search/routes.js +56 -0
  183. package/dist/search/routes.js.map +1 -0
  184. package/dist/search/run.d.ts +17 -0
  185. package/dist/search/run.d.ts.map +1 -0
  186. package/dist/search/run.js +62 -0
  187. package/dist/search/run.js.map +1 -0
  188. package/dist/shared/commandSpec.d.ts +69 -0
  189. package/dist/shared/commandSpec.d.ts.map +1 -0
  190. package/dist/shared/commandSpec.js +2 -0
  191. package/dist/shared/commandSpec.js.map +1 -0
  192. package/dist/shared/exit.d.ts +10 -0
  193. package/dist/shared/exit.d.ts.map +1 -0
  194. package/dist/shared/exit.js +13 -0
  195. package/dist/shared/exit.js.map +1 -0
  196. package/dist/shared/rows.d.ts +13 -0
  197. package/dist/shared/rows.d.ts.map +1 -0
  198. package/dist/shared/rows.js +3 -0
  199. package/dist/shared/rows.js.map +1 -0
  200. package/dist/sync/commands.d.ts +19 -0
  201. package/dist/sync/commands.d.ts.map +1 -0
  202. package/dist/sync/commands.js +20 -0
  203. package/dist/sync/commands.js.map +1 -0
  204. package/dist/sync/index.d.ts +8 -0
  205. package/dist/sync/index.d.ts.map +1 -0
  206. package/dist/sync/index.js +8 -0
  207. package/dist/sync/index.js.map +1 -0
  208. package/dist/sync/routes.d.ts +8 -0
  209. package/dist/sync/routes.d.ts.map +1 -0
  210. package/dist/sync/routes.js +10 -0
  211. package/dist/sync/routes.js.map +1 -0
  212. package/dist/sync/run.d.ts +16 -0
  213. package/dist/sync/run.d.ts.map +1 -0
  214. package/dist/sync/run.js +44 -0
  215. package/dist/sync/run.js.map +1 -0
  216. package/dist/triggers/routeSpec.d.ts +35 -0
  217. package/dist/triggers/routeSpec.d.ts.map +1 -0
  218. package/dist/triggers/routeSpec.js +2 -0
  219. package/dist/triggers/routeSpec.js.map +1 -0
  220. package/dist/triggers/routes.generated.d.ts +9 -0
  221. package/dist/triggers/routes.generated.d.ts.map +1 -0
  222. package/dist/triggers/routes.generated.js +32 -0
  223. package/dist/triggers/routes.generated.js.map +1 -0
  224. package/dist/wish/commands.d.ts +11 -0
  225. package/dist/wish/commands.d.ts.map +1 -0
  226. package/dist/wish/commands.js +13 -0
  227. package/dist/wish/commands.js.map +1 -0
  228. package/dist/wish/complete.js +2 -2
  229. package/dist/wish/complete.js.map +1 -1
  230. package/dist/wish/ensure.d.ts +4 -0
  231. package/dist/wish/ensure.d.ts.map +1 -1
  232. package/dist/wish/ensure.js +8 -7
  233. package/dist/wish/ensure.js.map +1 -1
  234. package/dist/wish/gate.d.ts +3 -0
  235. package/dist/wish/gate.d.ts.map +1 -1
  236. package/dist/wish/gate.js +5 -1
  237. package/dist/wish/gate.js.map +1 -1
  238. package/dist/wish/index.d.ts +1 -0
  239. package/dist/wish/index.d.ts.map +1 -1
  240. package/dist/wish/index.js +2 -0
  241. package/dist/wish/index.js.map +1 -1
  242. package/dist/wish/reconcile.js +2 -2
  243. package/dist/wish/reconcile.js.map +1 -1
  244. package/dist/wish/routes.d.ts +12 -0
  245. package/dist/wish/routes.d.ts.map +1 -0
  246. package/dist/wish/routes.js +48 -0
  247. package/dist/wish/routes.js.map +1 -0
  248. package/dist/wish/run.d.ts +13 -0
  249. package/dist/wish/run.d.ts.map +1 -0
  250. package/dist/wish/run.js +57 -0
  251. package/dist/wish/run.js.map +1 -0
  252. package/package.json +3 -3
  253. package/templates/receipt.html +156 -0
@@ -1,3 +1,4 @@
1
+ import type { LarkTier } from '../fetch/feishu.js';
1
2
  /** 三个 key 的唯一定义地(插件侧镜像同值,见 `packages/plugin-memo-ilife/src/bridge.ts`)。 */
2
3
  export declare const CONFIG_KEYS: {
3
4
  readonly read: "memo.config.read";
@@ -9,8 +10,21 @@ export declare function isConfigKey(key: string): boolean;
9
10
  /**
10
11
  * 跑一个配置 key,返回整行 envelope JSON。
11
12
  *
12
- * 三个 key 的载荷:读 → `{path, dataDir, created, values}`;写 → 入参 `{values}`,回执 `{path, values}`;
13
- * 重置 → `{path, backupPath}`(`backupPath` 为 null 表示本来就没有配置文件)。
13
+ * 三个 key 的载荷:读 → `{path, dataDir, created, values, resolved, lark}`;写 → 入参 `{values}`,
14
+ * 回执 `{path, values}`;重置 → `{path, backupPath}`(`backupPath` 为 null 表示本来就没有配置文件)。
15
+ *
16
+ * `resolved`(#760,照 #749 样板)=一组**解析后的绝对路径**,给设置页的只读行显示用
17
+ * (算式唯一定义地=`src/fetch/paths.ts`,面板不自己拼路径)。
18
+ * `lark`(#760,定稿 #759)=飞书 CLI 三档读数 + 复制安装指引全文 + 官网行
19
+ * (判据唯一定义地=`src/fetch/feishu.ts` 的 `larkTierInfo`,面板只显示)。
14
20
  */
21
+ export interface MemoConfigReadLark {
22
+ readonly tier: LarkTier;
23
+ readonly cliPath: string | null;
24
+ readonly version: string | null;
25
+ readonly prompt: string;
26
+ readonly websiteLine: string;
27
+ readonly websiteUrl: string;
28
+ }
15
29
  export declare function runConfigKey(key: string, params: Record<string, unknown>): string;
16
30
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAeA,2EAA2E;AAC3E,eAAO,MAAM,WAAW;;;;CAId,CAAC;AAEX,yBAAyB;AACzB,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEhD;AAyCD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAejF"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,2EAA2E;AAC3E,eAAO,MAAM,WAAW;;;;CAId,CAAC;AAEX,yBAAyB;AACzB,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEhD;AAyCD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAsBjF"}
@@ -11,6 +11,8 @@
11
11
  */
12
12
  import { ENVELOPE_VERSION } from 'base-link-core';
13
13
  import { loadMemoConfig, resetMemoConfig, saveMemoConfig } from '../config.js';
14
+ import { resolvedMemoPaths } from '../fetch/paths.js';
15
+ import { larkTierInfo, larkSetupInfo, LARK_WEBSITE_URL } from '../fetch/feishu.js';
14
16
  /** 三个 key 的唯一定义地(插件侧镜像同值,见 `packages/plugin-memo-ilife/src/bridge.ts`)。 */
15
17
  export const CONFIG_KEYS = {
16
18
  read: 'memo.config.read',
@@ -58,16 +60,17 @@ function withHumanError(run) {
58
60
  fail(1, e instanceof Error ? e.message : String(e));
59
61
  }
60
62
  }
61
- /**
62
- * 跑一个配置 key,返回整行 envelope JSON。
63
- *
64
- * 三个 key 的载荷:读 → `{path, dataDir, created, values}`;写 → 入参 `{values}`,回执 `{path, values}`;
65
- * 重置 → `{path, backupPath}`(`backupPath` 为 null 表示本来就没有配置文件)。
66
- */
67
63
  export function runConfigKey(key, params) {
68
64
  if (key === CONFIG_KEYS.read) {
69
65
  const c = withHumanError(() => loadMemoConfig());
70
- return envelope(key, 'detail', { path: c.path, dataDir: c.dataDir, created: c.created, values: c.values });
66
+ const resolved = withHumanError(() => resolvedMemoPaths());
67
+ const tier = withHumanError(() => larkTierInfo());
68
+ const setup = larkSetupInfo();
69
+ const lark = {
70
+ tier: tier.tier, cliPath: tier.cliPath, version: tier.version,
71
+ prompt: setup.prompt, websiteLine: setup.websiteLine, websiteUrl: LARK_WEBSITE_URL,
72
+ };
73
+ return envelope(key, 'detail', { path: c.path, dataDir: c.dataDir, created: c.created, values: c.values, resolved, lark });
71
74
  }
72
75
  if (key === CONFIG_KEYS.write) {
73
76
  const raw = params['values'];
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/cli/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /** 只读解析结果:文件不在/读得出取值与「哪些键真在文件里」/读不出来(报文带行号与文件名)。 */
2
+ export type ConfigRead = {
3
+ readonly kind: 'missing';
4
+ } | {
5
+ readonly kind: 'ok';
6
+ readonly values: Record<string, Record<string, unknown>>;
7
+ readonly present: ReadonlySet<string>;
8
+ } | {
9
+ readonly kind: 'bad';
10
+ readonly message: string;
11
+ };
12
+ /** 只读解析那份配置文件(文件不在时不落默认件,其余口径与配置件同)。 */
13
+ export declare function readMemoConfigReadOnly(): ConfigRead;
14
+ /** 把文件里读到的取值投到默认值表的形状上(缺项补默认值;组内只取默认值表认得的键)。 */
15
+ export declare function projectOnDefaults(values: Record<string, unknown>): Record<string, Record<string, unknown>>;
16
+ /** 取值:一层嵌套按 `组.键` 读(缺层或类型不符回 undefined)。 */
17
+ export declare function readValue(values: Record<string, Record<string, unknown>>, group: string, key: string): unknown;
18
+ /** 有值的字符串(空串=未配,按 `undefined` 处理,语义与各取用处一致)。 */
19
+ export declare function textOf(value: unknown): string;
20
+ /** 「这个值从哪来」:真在文件里写了就是「配置文件」,否则按默认值(文件不存在则全按默认值)。 */
21
+ export declare function sourceOf(present: ReadonlySet<string>, key: string): string;
22
+ //# sourceMappingURL=configRead.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configRead.d.ts","sourceRoot":"","sources":["../../../src/cli/health/configRead.ts"],"names":[],"mappings":"AAaA,oDAAoD;AACpD,MAAM,MAAM,UAAU,GAClB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CAAE,GACxH;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvD,wCAAwC;AACxC,wBAAgB,sBAAsB,IAAI,UAAU,CAYnD;AAkJD,gDAAgD;AAChD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAa1G;AAED,4CAA4C;AAC5C,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAE9G;AAED,gDAAgD;AAChD,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE7C;AAED,oDAAoD;AACpD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1E"}
@@ -0,0 +1,207 @@
1
+ /** 配置体检 · **只读配置解析**(票 #706 判据,票 #855 从这里分件出来)。
2
+ *
3
+ * 与 `loadConfig()` 的差别只有一处、也正是体检要的那一处:**文件不在时不落默认件**;
4
+ * 取值语义与它一致(文件里缺的项按默认值补)。受限子集与 `base-link-core` 同一套校验,口径逐条对齐:
5
+ * 剥 BOM、去 `\r`、空行与整行注释跳过、缩进只许 2 个空格且不许制表符、不支持列表、
6
+ * 一行须是「键: 值」、不许重复定义、顶层键冒号后没值即开一个组。
7
+ *
8
+ * 谁在用:`src/cli/health/items.ts`(九条体检项)——本件不做判定、不下结论,只把文件读成取值。
9
+ */
10
+ import { existsSync, readFileSync } from 'node:fs';
11
+ import { configPaths } from 'base-link-core';
12
+ import { MEMO_CONFIG_DEFAULTS, MEMO_CONFIG_STEM } from '../../config.js';
13
+ /** 只读解析那份配置文件(文件不在时不落默认件,其余口径与配置件同)。 */
14
+ export function readMemoConfigReadOnly() {
15
+ const file = configPaths(MEMO_CONFIG_STEM).configFile;
16
+ if (!existsSync(file))
17
+ return { kind: 'missing' };
18
+ let text;
19
+ try {
20
+ text = readFileSync(file, 'utf8');
21
+ }
22
+ catch (e) {
23
+ return { kind: 'bad', message: '读配置文件失败:' + file + '(' + (e instanceof Error ? e.message : String(e)) + ')' };
24
+ }
25
+ const parsed = parseSubset(text, file);
26
+ if (!parsed.ok)
27
+ return { kind: 'bad', message: parsed.message };
28
+ return { kind: 'ok', values: projectOnDefaults(parsed.values), present: presentKeysOf(parsed.values) };
29
+ }
30
+ /** 文件里真写了哪些键(扁平成 `组.键`):给「这个值从哪来」那条判据用。
31
+ *
32
+ * 为什么不能直接看投到默认值表之后的值:**空串=按默认落点**——留空的项值看起来与默认值一样,
33
+ * 但它的来源是「用户写了空串」,不是「文件里没有这一项」。混起来就会把来源报错。 */
34
+ function presentKeysOf(values) {
35
+ const out = new Set();
36
+ for (const [group, got] of Object.entries(values)) {
37
+ if (typeof got !== 'object' || got === null) {
38
+ out.add(group);
39
+ continue;
40
+ }
41
+ for (const key of Object.keys(got))
42
+ out.add(group + '.' + key);
43
+ }
44
+ return out;
45
+ }
46
+ /** 受限子集的极简解析:只算值与行号,不算别的(校验口径与配置件同一套)。 */
47
+ function parseSubset(text, file) {
48
+ const source = text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
49
+ const lines = source.replace(/\r\n?/g, '\n').split('\n');
50
+ const values = {};
51
+ const lineOf = new Map();
52
+ let openGroup = null;
53
+ let openGroupLine = 0;
54
+ /** 标量解析的失败口:`parseScalar` 把报文写进 `scalarError`,调用处读它即可(不抛,免得类型糊)。 */
55
+ let scalarError = '';
56
+ const fail = (line, why) => ({ ok: false, message: '配置件第 ' + String(line) + ' 行:' + why + '(文件:' + file + ')' });
57
+ const closeGroup = () => {
58
+ if (openGroup !== null && Object.keys(values[openGroup]).length === 0) {
59
+ return fail(openGroupLine, '键「' + openGroup + '」冒号后没有值,也没有子项').message;
60
+ }
61
+ openGroup = null;
62
+ return null;
63
+ };
64
+ for (let i = 0; i < lines.length; i += 1) {
65
+ const lineNo = i + 1;
66
+ const raw = lines[i] ?? '';
67
+ if (raw.trim() === '')
68
+ continue;
69
+ if (/^\s*#/.test(raw))
70
+ continue;
71
+ const head = /^[ \t]*/.exec(raw)?.[0] ?? '';
72
+ const body = raw.slice(head.length);
73
+ if (head.includes('\t'))
74
+ return fail(lineNo, '缩进里有制表符:本子集只许空格,且嵌套缩进恰好 2 个空格');
75
+ if (body.startsWith('-'))
76
+ return fail(lineNo, '本子集不支持列表(「-」开头的行)');
77
+ const matched = /^([A-Za-z_][A-Za-z0-9_.-]*)[ \t]*:[ \t]*(.*)$/.exec(body);
78
+ if (matched === null)
79
+ return fail(lineNo, '不是「键: 值」形状:' + body.trim());
80
+ const key = matched[1];
81
+ const rest = (matched[2] ?? '').trim();
82
+ if (head.length > 0) {
83
+ if (head.length !== 2)
84
+ return fail(lineNo, '缩进必须恰好 2 个空格(本子集只支持一层嵌套),实为 ' + String(head.length) + ' 个空格');
85
+ if (openGroup === null)
86
+ return fail(lineNo, '缩进的子项「' + key + '」上面没有开着子的顶层键');
87
+ const group = values[openGroup];
88
+ if (Object.prototype.hasOwnProperty.call(group, key)) {
89
+ return fail(lineNo, '键「' + openGroup + '.' + key + '」重复定义(第 ' + String(lineOf.get(openGroup + '.' + key)) + ' 行已定义)');
90
+ }
91
+ if (rest === '')
92
+ return fail(lineNo, '键「' + openGroup + '.' + key + '」冒号后没有值');
93
+ const scalar = parseScalar(rest, lineNo, fail, (message) => {
94
+ scalarError = message;
95
+ });
96
+ if (scalarError !== '')
97
+ return { ok: false, message: scalarError };
98
+ group[key] = scalar;
99
+ lineOf.set(openGroup + '.' + key, lineNo);
100
+ continue;
101
+ }
102
+ const closedError = closeGroup();
103
+ if (closedError !== null)
104
+ return { ok: false, message: closedError };
105
+ if (Object.prototype.hasOwnProperty.call(values, key)) {
106
+ return fail(lineNo, '键「' + key + '」重复定义(第 ' + String(lineOf.get(key)) + ' 行已定义)');
107
+ }
108
+ lineOf.set(key, lineNo);
109
+ if (rest === '') {
110
+ values[key] = {};
111
+ openGroup = key;
112
+ openGroupLine = lineNo;
113
+ continue;
114
+ }
115
+ const scalar = parseScalar(rest, lineNo, fail, (message) => {
116
+ scalarError = message;
117
+ });
118
+ if (scalarError !== '')
119
+ return { ok: false, message: scalarError };
120
+ values[key] = scalar;
121
+ }
122
+ const tailError = closeGroup();
123
+ if (tailError !== null)
124
+ return { ok: false, message: tailError };
125
+ return { ok: true, values };
126
+ }
127
+ /** 标量:带引号/数字/布尔/裸字符串(值后的 `#` 注释照配置件同一口径切掉)。 */
128
+ function parseScalar(text, lineNo, fail, onError) {
129
+ const first = text[0];
130
+ if (first === '"' || first === "'") {
131
+ const quote = first;
132
+ let out = '';
133
+ let i = 1;
134
+ let closed = false;
135
+ for (; i < text.length; i += 1) {
136
+ const ch = text[i];
137
+ if (ch === quote) {
138
+ if (quote === "'" && text[i + 1] === "'") {
139
+ out += "'";
140
+ i += 1;
141
+ continue;
142
+ }
143
+ closed = true;
144
+ break;
145
+ }
146
+ if (quote === '"' && ch === '\\') {
147
+ const next = text[i + 1];
148
+ out += next === 'n' ? '\n' : next === 't' ? '\t' : (next ?? '');
149
+ i += 1;
150
+ continue;
151
+ }
152
+ out += ch;
153
+ }
154
+ if (!closed) {
155
+ onError(fail(lineNo, '引号没有闭合:' + text).message);
156
+ return '';
157
+ }
158
+ return out;
159
+ }
160
+ let cut = text.length;
161
+ for (let i = 0; i < text.length; i += 1) {
162
+ if (text[i] === '#' && (i === 0 || /\s/.test(text[i - 1]))) {
163
+ cut = i;
164
+ break;
165
+ }
166
+ }
167
+ const body = text.slice(0, cut).trim();
168
+ if (body === '') {
169
+ onError(fail(lineNo, '冒号后没有值(只有注释)').message);
170
+ return '';
171
+ }
172
+ if (body === 'true')
173
+ return true;
174
+ if (body === 'false')
175
+ return false;
176
+ if (/^-?(\d+\.?\d*|\.\d+)$/.test(body))
177
+ return Number(body);
178
+ return body;
179
+ }
180
+ /** 把文件里读到的取值投到默认值表的形状上(缺项补默认值;组内只取默认值表认得的键)。 */
181
+ export function projectOnDefaults(values) {
182
+ const out = {};
183
+ for (const [group, def] of Object.entries(MEMO_CONFIG_DEFAULTS)) {
184
+ const bucket = {};
185
+ const got = values[group];
186
+ const source = typeof got === 'object' && got !== null ? got : {};
187
+ for (const [key, defValue] of Object.entries(def)) {
188
+ const mine = source[key];
189
+ bucket[key] = typeof mine === typeof defValue ? mine : defValue;
190
+ }
191
+ out[group] = bucket;
192
+ }
193
+ return out;
194
+ }
195
+ /** 取值:一层嵌套按 `组.键` 读(缺层或类型不符回 undefined)。 */
196
+ export function readValue(values, group, key) {
197
+ return values[group]?.[key];
198
+ }
199
+ /** 有值的字符串(空串=未配,按 `undefined` 处理,语义与各取用处一致)。 */
200
+ export function textOf(value) {
201
+ return typeof value === 'string' && value.trim() !== '' ? value : '';
202
+ }
203
+ /** 「这个值从哪来」:真在文件里写了就是「配置文件」,否则按默认值(文件不存在则全按默认值)。 */
204
+ export function sourceOf(present, key) {
205
+ return present.has(key) ? '配置文件' : '默认值';
206
+ }
207
+ //# sourceMappingURL=configRead.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configRead.js","sourceRoot":"","sources":["../../../src/cli/health/configRead.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /** 配置体检 · **聚合位**(票 #855:`cli/health` 只留聚合与页外先拦)。
2
+ *
3
+ * 分工:
4
+ * - `configRead.ts` 只读配置解析(文件不在时不落默认件);
5
+ * - `probe.ts` 机器面探针(目录在不在/能不能写、模板件数、库表数、飞书 CLI 三档);
6
+ * - `items.ts` 九条体检项与报告组装;
7
+ * - `../health.ts`(`src/cli/health.ts`)=**页外先拦**:`memo.config.check` 这个只读命令在库目录
8
+ * 预检之前拦下(它要报的正是「库在哪、通不通」,不能先要求库已配)。
9
+ *
10
+ * 对外只转出报告构造与报告类型;跨包消费者按 `dist/health.js` 取报告的那条老路,由 `src/health.ts`
11
+ * 转发保持(包门只许收窄,老路不许悄悄断)。
12
+ */
13
+ export { buildMemoHealthReport } from './items.js';
14
+ export type { HealthItem, HealthStatus, MemoHealthReport } from './items.js';
15
+ export { DB_TABLE_THRESHOLD } from './probe.js';
16
+ export { readMemoConfigReadOnly } from './configRead.js';
17
+ export type { ConfigRead } from './configRead.js';
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/health/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,16 @@
1
+ /** 配置体检 · **聚合位**(票 #855:`cli/health` 只留聚合与页外先拦)。
2
+ *
3
+ * 分工:
4
+ * - `configRead.ts` 只读配置解析(文件不在时不落默认件);
5
+ * - `probe.ts` 机器面探针(目录在不在/能不能写、模板件数、库表数、飞书 CLI 三档);
6
+ * - `items.ts` 九条体检项与报告组装;
7
+ * - `../health.ts`(`src/cli/health.ts`)=**页外先拦**:`memo.config.check` 这个只读命令在库目录
8
+ * 预检之前拦下(它要报的正是「库在哪、通不通」,不能先要求库已配)。
9
+ *
10
+ * 对外只转出报告构造与报告类型;跨包消费者按 `dist/health.js` 取报告的那条老路,由 `src/health.ts`
11
+ * 转发保持(包门只许收窄,老路不许悄悄断)。
12
+ */
13
+ export { buildMemoHealthReport } from './items.js';
14
+ export { DB_TABLE_THRESHOLD } from './probe.js';
15
+ export { readMemoConfigReadOnly } from './configRead.js';
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/health/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,19 @@
1
+ /** 报告里的三档判据(与面板侧镜像同值)。 */
2
+ export type HealthStatus = 'red' | 'yellow' | 'green';
3
+ export interface HealthItem {
4
+ readonly id: string;
5
+ readonly title: string;
6
+ readonly status: HealthStatus;
7
+ readonly message: string;
8
+ readonly action: string;
9
+ readonly source?: string;
10
+ }
11
+ export interface MemoHealthReport {
12
+ readonly skill: string;
13
+ readonly configPath: string;
14
+ readonly dataDir: string;
15
+ readonly items: readonly HealthItem[];
16
+ }
17
+ /** 跑一次体检,返回整份报告。**只读**:任何一处都不落盘(只有写探针那一个文件,且当场删掉)。 */
18
+ export declare function buildMemoHealthReport(): MemoHealthReport;
19
+ //# sourceMappingURL=items.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"items.d.ts","sourceRoot":"","sources":["../../../src/cli/health/items.ts"],"names":[],"mappings":"AAkCA,0BAA0B;AAC1B,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEtD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;CACvC;AAID,sDAAsD;AACtD,wBAAgB,qBAAqB,IAAI,gBAAgB,CAuLxD"}
@@ -0,0 +1,205 @@
1
+ /** 配置体检 · **九条体检项**(票 #706 的检查表落地,票 #855 从这里分件出来)。
2
+ *
3
+ * 检查项与检查表 `docs/research/check-table-671-life-panel-20260917.html` 逐条对应:
4
+ * 六家通用 5 条(配置文件本身/数据目录/库文件表数/产物目录/这个值从哪来)
5
+ * + 备忘特有 4 条(附件目录/飞书 CLI/包内模板+公共组件/场景资产)。
6
+ * 「附件」那一项的形状跟着 #712 走:附件从「字符串前缀」改成**真目录 + 真包含判定**。
7
+ *
8
+ * 口径(票面「开工前的形状裁定」):
9
+ * · **判据住技能侧**——每条的有效值(库在哪、产物落哪个目录、包内预置件在不在)只有本包算得出来;
10
+ * 插件包与总管只透传与渲染,不重写这里的任何一个字。
11
+ * · **只报不改**——不建目录、不写文件、不落那份默认配置;因此**不许**调 `loadMemoConfig()`(文件不在即落默认件)。
12
+ * · 判据查的路径一律是**新仓的**:检查表里那些老仓文件名只作注释里的出处,不进用户看到的报文。
13
+ *
14
+ * 搬迁状态(#855):九条今天同住本件;按域归位(`src/<域>/health.ts`)随各域目录建立时落,届时本件只留聚合。
15
+ */
16
+ import { existsSync } from 'node:fs';
17
+ import { homedir } from 'node:os';
18
+ import { join } from 'node:path';
19
+ import { configPaths } from 'base-link-core';
20
+ import { MEMO_CONFIG_DEFAULTS, MEMO_CONFIG_STEM } from '../../config.js';
21
+ import { mediaDirOf } from '../../fetch/paths.js';
22
+ import { projectOnDefaults, readMemoConfigReadOnly, readValue, sourceOf, textOf } from './configRead.js';
23
+ import { DB_TABLE_THRESHOLD, dirVerdict, findLarkCli, larkTier, p, packageRoot, splitDirSegments, tableCount, templateFileCount, } from './probe.js';
24
+ const SKILL = 'memo';
25
+ /** 跑一次体检,返回整份报告。**只读**:任何一处都不落盘(只有写探针那一个文件,且当场删掉)。 */
26
+ export function buildMemoHealthReport() {
27
+ const paths = configPaths(MEMO_CONFIG_STEM);
28
+ const items = [];
29
+ const read = readMemoConfigReadOnly();
30
+ const values = read.kind === 'ok' ? read.values : projectOnDefaults({});
31
+ const present = read.kind === 'ok' ? read.present : new Set();
32
+ // ① 配置文件本身:能不能解析;它落在默认位置还是别处(只陈述,不评价)。
33
+ const defaultConfigFile = join(homedir(), '.ilife', MEMO_CONFIG_STEM + '.yaml');
34
+ const relocated = paths.configFile !== defaultConfigFile;
35
+ const where = relocated ? '位置与默认不同(见配置文件落点)' : '默认位置';
36
+ if (read.kind === 'bad') {
37
+ items.push({
38
+ id: 'config.file', title: '配置文件', status: 'red',
39
+ message: read.message,
40
+ action: '照报文指的行号改回「键: 值」的写法;改不动就删掉这个文件,让技能按默认值重落一份。',
41
+ source: '配置文件',
42
+ });
43
+ }
44
+ else if (read.kind === 'missing') {
45
+ items.push({
46
+ id: 'config.file', title: '配置文件', status: 'yellow',
47
+ message: '配置文件还不存在:' + p(paths.configFile) + '(现在跑的是默认值)。',
48
+ action: '在面板上保存一次即会落一份;也可点「重置为默认」。',
49
+ source: '默认值',
50
+ });
51
+ }
52
+ else {
53
+ items.push({
54
+ id: 'config.file', title: '配置文件', status: 'green',
55
+ message: '能解析:' + p(paths.configFile) + '(' + where + ')。',
56
+ action: '',
57
+ source: '配置文件',
58
+ });
59
+ }
60
+ // ② 数据目录:在不在、能不能写。
61
+ const dbDirConfigured = textOf(readValue(values, 'db', 'dir'));
62
+ const dataDir = dbDirConfigured !== '' ? dbDirConfigured : paths.dataDir;
63
+ const dataDirSource = sourceOf(present, 'db.dir');
64
+ const dataDirVerdict = dirVerdict(dataDir);
65
+ items.push({
66
+ id: 'db.dir', title: '数据目录',
67
+ status: !dataDirVerdict.exists || !dataDirVerdict.writable ? 'red' : 'green',
68
+ message: !dataDirVerdict.exists
69
+ ? '不在:' + p(dataDir) + (dataDirVerdict.reason !== '' ? '(' + dataDirVerdict.reason + ')' : '')
70
+ : dataDirVerdict.writable
71
+ ? '在且能写:' + p(dataDir) + '。'
72
+ : '在,但写不进去:' + p(dataDir) + '(' + dataDirVerdict.reason + ')。',
73
+ action: !dataDirVerdict.exists
74
+ ? '先建这个目录,或把配置里的「数据目录」改到一个已存在的位置。'
75
+ : dataDirVerdict.writable ? '' : '去掉这个目录的只读属性,或把「数据目录」改到别处。',
76
+ source: dataDirSource,
77
+ });
78
+ // ③ 库文件:在不在 + 表数够不够。
79
+ const dbNameConfigured = textOf(readValue(values, 'db', 'name'));
80
+ const dbName = dbNameConfigured !== '' ? dbNameConfigured : String(MEMO_CONFIG_DEFAULTS.db.name);
81
+ const dbFile = join(dataDir, dbName);
82
+ const dbSource = sourceOf(present, 'db.name');
83
+ if (!existsSync(dbFile)) {
84
+ items.push({
85
+ id: 'db.file', title: '库文件', status: 'red',
86
+ message: '不在:' + p(dbFile) + '。',
87
+ action: '确认「数据目录」与「库文件名」对不对(库文件名只读,要改请编辑配置文件);本技能直连老库、**不建空库**,所以要由老技能或初始化建出它。',
88
+ source: dbSource,
89
+ });
90
+ }
91
+ else {
92
+ const tables = tableCount(dbFile);
93
+ if (!tables.ok) {
94
+ items.push({
95
+ id: 'db.file', title: '库文件', status: 'red',
96
+ message: '在,但打不开:' + p(dbFile) + '(' + tables.reason + ')。',
97
+ action: '这个文件可能不是库文件或已损坏;先备份,再看要不要让技能重建一份。',
98
+ source: dbSource,
99
+ });
100
+ }
101
+ else if (tables.count < DB_TABLE_THRESHOLD) {
102
+ items.push({
103
+ id: 'db.file', title: '库文件', status: 'yellow',
104
+ message: '在,但表不全:' + p(dbFile) + '(' + String(tables.count) + ' / ' + String(DB_TABLE_THRESHOLD) + ' 张表)。',
105
+ action: '缺表会让对应的功能报错;跑一次会写库的命令让它补齐,或从备份恢复。',
106
+ source: dbSource,
107
+ });
108
+ }
109
+ else {
110
+ items.push({
111
+ id: 'db.file', title: '库文件', status: 'green',
112
+ message: '在,' + String(tables.count) + ' 张表齐:' + p(dbFile) + '。',
113
+ action: '',
114
+ source: dbSource,
115
+ });
116
+ }
117
+ }
118
+ // ④ 产物目录:在不在、能不能写(还没建=绿:交付页面时才落这里,那时自动建)。
119
+ const htmlDirValue = textOf(readValue(values, 'html', 'dir'));
120
+ const htmlDir = join(dataDir, ...splitDirSegments(htmlDirValue !== '' ? htmlDirValue : String(MEMO_CONFIG_DEFAULTS.html.dir)));
121
+ const htmlVerdict = dirVerdict(htmlDir);
122
+ const htmlSource = sourceOf(present, 'html.dir');
123
+ items.push({
124
+ id: 'html.dir', title: '产物目录',
125
+ status: !htmlVerdict.exists ? 'green' : htmlVerdict.writable ? 'green' : 'yellow',
126
+ message: !htmlVerdict.exists
127
+ ? '还没建:' + p(htmlDir) + '(交付页面时才落这里,那时自动建)。'
128
+ : htmlVerdict.writable
129
+ ? '在且能写:' + p(htmlDir) + '。'
130
+ : '在,但写不进去:' + p(htmlDir) + '(交付会转成内联回执,不再落盘)。',
131
+ action: !htmlVerdict.exists || htmlVerdict.writable ? '' : '去掉这个目录的只读属性,或改配置文件里的 html.dir(该项只读,面板上不给改)。',
132
+ source: htmlSource,
133
+ });
134
+ // ⑤ 这个值从哪来:只陈述数据目录与库文件名的来源,不判好坏(六家通用最后一条)。
135
+ items.push({
136
+ id: 'value.source', title: '这个值从哪来', status: 'green',
137
+ message: '数据目录走「' + dataDirSource + '」,库文件名走「' + dbSource + '」'
138
+ + (read.kind === 'missing' ? '(配置文件还不存在,落点全按默认值)。' : '。'),
139
+ action: '', source: dataDirSource,
140
+ });
141
+ // ⑥ 附件目录(备忘特有,#712 起的形状;#760 起默认=`<数据目录>/media`):没配≠未配——
142
+ // 空串即默认落点,判那个目录在不在;配了但目录不在=黄;在且能写=绿。显式相对值按进程工作目录解
143
+ // (与 `resolveMediaDir()` 同一算式 `mediaDirOf`,本件只调纯函数,不触发配置落盘)。
144
+ const mediaConfigured = textOf(readValue(values, 'media', 'dir'));
145
+ const mediaDir = mediaDirOf(dataDir, mediaConfigured);
146
+ const mediaVerdict = dirVerdict(mediaDir);
147
+ const mediaMissing = mediaConfigured === '' ? '默认落点目录不在:' : '配了但目录不在:';
148
+ items.push({
149
+ id: 'media.dir', title: '附件目录',
150
+ status: mediaVerdict.exists && mediaVerdict.writable ? 'green' : 'yellow',
151
+ message: !mediaVerdict.exists
152
+ ? mediaMissing + p(mediaDir) + '。'
153
+ : mediaVerdict.writable
154
+ ? '在且能写:' + p(mediaDir) + '。'
155
+ : '在,但写不进去:' + p(mediaDir) + '(' + mediaVerdict.reason + ')。',
156
+ action: mediaVerdict.exists && mediaVerdict.writable ? '' : '建出这个目录(或去掉只读),或把「附件目录」改到别处。',
157
+ source: sourceOf(present, 'media.dir'),
158
+ });
159
+ // ⑦ 飞书 CLI(备忘特有):三档——找不到=黄;找得到但没登录/没授权=黄;登录且 task 域可写=绿。
160
+ // #760 起 `lark:` 整组出配置表:来源固定按默认值,指引改指复制安装指引(授权三支已退役)。
161
+ const larkCli = findLarkCli('');
162
+ const tier = larkTier(larkCli);
163
+ const larkWhere = larkCli === null ? '' : p(larkCli);
164
+ items.push({
165
+ id: 'lark.cli', title: '飞书 CLI',
166
+ status: tier === 'full' ? 'green' : 'yellow',
167
+ message: tier === 'missing'
168
+ ? '找不到 lark-cli:飞书同步用不了(其余功能不受影响)。'
169
+ : tier === 'partial'
170
+ ? '找得到 lark-cli,但还没登录或没拿到 task 域授权:飞书同步用不了。'
171
+ : '已登录且 task 域可写:' + larkWhere + '。',
172
+ action: tier === 'missing'
173
+ ? '要用飞书同步就装它:npm install -g @larksuite/cli(官方包是 @larksuite/cli,bin 名恰为 lark-cli;npm 上的 lark-cli 是僵尸包,别装)。飞书CLI官网为:https://www.feishu.cn/feishu-cli。完整安装指引(含复制给 AI 的 prompt)见 memo.config.read 回执的 lark.prompt,面板「飞书 CLI」状态行有同一个复制按钮。'
174
+ : tier === 'partial' ? '补授权:照 memo.config.read 回执 lark.prompt 里那段做(登录后要能过 lark-cli auth check --scope task)。' : '',
175
+ source: '默认值',
176
+ });
177
+ // ⑧ 包内模板目录(备忘特有):整页交付模板是包内固定件,缺了页面就渲染不出来 ⇒ 红。报文给件数。
178
+ const templatesDir = join(packageRoot(), 'templates');
179
+ const templatesOk = existsSync(templatesDir);
180
+ const templateCount = templatesOk ? templateFileCount(templatesDir) : 0;
181
+ items.push({
182
+ id: 'templates.dir', title: '包内模板目录',
183
+ status: templatesOk ? 'green' : 'red',
184
+ message: templatesOk
185
+ ? '在,' + String(templateCount) + ' 件模板:' + p(templatesDir) + '。'
186
+ : '不在:' + p(templatesDir) + '。',
187
+ action: templatesOk ? '' : '技能包装得不完整:重装这个技能包,或跑一次它的构建。',
188
+ });
189
+ // ⑨ 场景资产(备忘特有):查的是**新仓这份事实源**=`src/help/sceneData.ts`(8 个域数据件
190
+ // `src/help/scenes/*.ts` 的组装件,生成器 `scripts/gen-help-assets.mjs` 读它;老仓那个
191
+ // `references/scenarios.yaml` 只作注释里的出处,不出现报文里——新仓没有 `references/` 这个目录)。
192
+ // 不在=红:缺的是 HELP 与场景面的事实源,重装包即补齐(档位=检查表原话「不在=红」)。
193
+ const scenariosFile = join(packageRoot(), 'src', 'help', 'sceneData.ts');
194
+ const scenariosExists = existsSync(scenariosFile);
195
+ items.push({
196
+ id: 'scenarios.file', title: '场景资产',
197
+ status: scenariosExists ? 'green' : 'red',
198
+ message: scenariosExists
199
+ ? '在:' + p(scenariosFile) + '(新仓的场景资产事实源住这里)。'
200
+ : '不在:' + p(scenariosFile) + '(新仓的场景资产事实源;缺了 HELP 与场景面取不到)。',
201
+ action: scenariosExists ? '' : '技能包装得不完整:重装这个技能包即会补齐。',
202
+ });
203
+ return { skill: SKILL, configPath: p(paths.configFile), dataDir: p(dataDir), items };
204
+ }
205
+ //# sourceMappingURL=items.js.map