oh-my-knowledge 0.36.0 → 0.38.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 (135) hide show
  1. package/README.md +6 -4
  2. package/README.zh.md +6 -4
  3. package/dist/assets/agent-skills/omk/SKILL.md +5 -3
  4. package/dist/assets/agent-skills/omk/references/commands.md +107 -15
  5. package/dist/authoring/evolver.d.ts +4 -1
  6. package/dist/authoring/evolver.js +13 -8
  7. package/dist/cli/commands/doctor.d.ts +1 -0
  8. package/dist/cli/commands/doctor.js +45 -10
  9. package/dist/cli/commands/eval/gold/compare.js +7 -4
  10. package/dist/cli/commands/eval/index.d.ts +1 -0
  11. package/dist/cli/commands/eval/index.js +14 -3
  12. package/dist/cli/commands/evolve.d.ts +12 -0
  13. package/dist/cli/commands/evolve.js +150 -5
  14. package/dist/cli/commands/init.js +18 -6
  15. package/dist/cli/commands/list.d.ts +3 -26
  16. package/dist/cli/commands/list.js +14 -144
  17. package/dist/cli/commands/observe/inbox.d.ts +1 -0
  18. package/dist/cli/commands/observe/inbox.js +14 -4
  19. package/dist/cli/commands/observe/index.d.ts +11 -0
  20. package/dist/cli/commands/observe/index.js +35 -12
  21. package/dist/cli/commands/observe/ingest.d.ts +1 -0
  22. package/dist/cli/commands/observe/ingest.js +13 -4
  23. package/dist/cli/commands/observe/show.d.ts +1 -0
  24. package/dist/cli/commands/observe/show.js +12 -2
  25. package/dist/cli/commands/promote.d.ts +24 -0
  26. package/dist/cli/commands/promote.js +157 -0
  27. package/dist/cli/commands/rollback.d.ts +20 -0
  28. package/dist/cli/commands/rollback.js +95 -0
  29. package/dist/cli/commands/sample.d.ts +1 -0
  30. package/dist/cli/commands/sample.js +25 -13
  31. package/dist/cli/commands/studio.d.ts +2 -0
  32. package/dist/cli/commands/studio.js +62 -12
  33. package/dist/cli/lib/cell-format.d.ts +17 -0
  34. package/dist/cli/lib/cell-format.js +19 -0
  35. package/dist/cli/lib/cmd-flags.d.ts +9 -0
  36. package/dist/cli/lib/i18n-dict/common.d.ts +1 -1
  37. package/dist/cli/lib/i18n-dict/common.js +9 -1
  38. package/dist/cli/lib/i18n-dict/evolve.d.ts +1 -1
  39. package/dist/cli/lib/i18n-dict/evolve.js +8 -0
  40. package/dist/cli/lib/i18n-dict/help.js +27 -45
  41. package/dist/cli/lib/i18n-dict/init.js +2 -2
  42. package/dist/cli/lib/i18n-dict/list.d.ts +1 -1
  43. package/dist/cli/lib/i18n-dict/list.js +4 -0
  44. package/dist/cli/lib/i18n-dict/promote.d.ts +3 -0
  45. package/dist/cli/lib/i18n-dict/promote.js +54 -0
  46. package/dist/cli/lib/i18n-dict/rollback.d.ts +3 -0
  47. package/dist/cli/lib/i18n-dict/rollback.js +22 -0
  48. package/dist/cli/lib/i18n-dict.d.ts +3 -1
  49. package/dist/cli/lib/i18n-dict.js +4 -0
  50. package/dist/cli/lib/parse-run-config.d.ts +0 -1
  51. package/dist/cli/lib/parse-run-config.js +6 -4
  52. package/dist/cli/lib/progress.d.ts +3 -0
  53. package/dist/cli/lib/progress.js +22 -0
  54. package/dist/cli/lib/record-evolve-outcome.d.ts +31 -0
  55. package/dist/cli/lib/record-evolve-outcome.js +110 -0
  56. package/dist/cli/lib/resolve-skill-input.d.ts +6 -0
  57. package/dist/cli/lib/resolve-skill-input.js +4 -2
  58. package/dist/cli/lib/source-probe.d.ts +15 -0
  59. package/dist/cli/lib/source-probe.js +129 -0
  60. package/dist/diagnosis/types.js +1 -1
  61. package/dist/doctor/endpoint-rule.d.ts +60 -0
  62. package/dist/doctor/endpoint-rule.js +381 -0
  63. package/dist/doctor/health/load-custom-dimensions.d.ts +6 -0
  64. package/dist/doctor/health/load-custom-dimensions.js +43 -3
  65. package/dist/doctor/index.js +12 -2
  66. package/dist/eval-core/artifact-index.d.ts +106 -0
  67. package/dist/eval-core/artifact-index.js +277 -0
  68. package/dist/eval-core/default-dirs.d.ts +34 -0
  69. package/dist/eval-core/default-dirs.js +36 -0
  70. package/dist/eval-core/evaluation-execution.js +3 -3
  71. package/dist/eval-core/evaluation-reporting.d.ts +7 -0
  72. package/dist/eval-core/evaluation-reporting.js +20 -5
  73. package/dist/eval-core/execution-strategy.js +3 -3
  74. package/dist/eval-core/measurement-dirs.d.ts +18 -0
  75. package/dist/eval-core/measurement-dirs.js +76 -0
  76. package/dist/eval-workflows/batch-evaluation-workflow.js +2 -1
  77. package/dist/eval-workflows/evaluation-pipeline/run-state.js +2 -1
  78. package/dist/eval-workflows/run-evaluation.js +5 -2
  79. package/dist/executors/codex-cli.js +7 -3
  80. package/dist/executors/script.js +43 -4
  81. package/dist/inputs/materialize-copy.d.ts +1 -1
  82. package/dist/inputs/materialize-copy.js +3 -3
  83. package/dist/inputs/skill-loader.d.ts +1 -1
  84. package/dist/inputs/skill-loader.js +1 -1
  85. package/dist/managed/index.d.ts +3 -0
  86. package/dist/managed/index.js +3 -0
  87. package/dist/managed/list-query.d.ts +7 -0
  88. package/dist/managed/list-query.js +11 -0
  89. package/dist/managed/list-view.d.ts +3 -0
  90. package/dist/managed/list-view.js +8 -4
  91. package/dist/managed/promote-gate.d.ts +40 -0
  92. package/dist/managed/promote-gate.js +37 -0
  93. package/dist/managed/source-probe.d.ts +15 -0
  94. package/dist/managed/source-probe.js +129 -0
  95. package/dist/managed/store.d.ts +35 -2
  96. package/dist/managed/store.js +117 -5
  97. package/dist/observability/inbox.js +6 -3
  98. package/dist/observability/skill-health-analyzer.d.ts +3 -0
  99. package/dist/observability/skill-health-analyzer.js +2 -0
  100. package/dist/renderer/doctor-detail-renderer.d.ts +9 -0
  101. package/dist/renderer/doctor-detail-renderer.js +114 -0
  102. package/dist/renderer/html-renderer.d.ts +3 -2
  103. package/dist/renderer/html-renderer.js +103 -101
  104. package/dist/renderer/icons.d.ts +29 -0
  105. package/dist/renderer/icons.js +66 -0
  106. package/dist/renderer/layout.js +81 -68
  107. package/dist/renderer/managed-history-renderer.d.ts +5 -0
  108. package/dist/renderer/managed-history-renderer.js +255 -0
  109. package/dist/renderer/observation-inbox/styles.d.ts +1 -1
  110. package/dist/renderer/observation-inbox/styles.js +53 -53
  111. package/dist/renderer/observation-inbox-renderer.js +19 -19
  112. package/dist/renderer/report-shell.d.ts +77 -0
  113. package/dist/renderer/report-shell.js +223 -0
  114. package/dist/renderer/skill-detail-renderer.js +164 -360
  115. package/dist/renderer/skill-health-renderer.js +50 -73
  116. package/dist/renderer/skill-list-renderer.js +359 -306
  117. package/dist/renderer/summary.js +272 -162
  118. package/dist/renderer/test-view.d.ts +4 -3
  119. package/dist/renderer/test-view.js +386 -135
  120. package/dist/server/indexed-report-store.d.ts +8 -0
  121. package/dist/server/indexed-report-store.js +130 -0
  122. package/dist/server/job-store.d.ts +0 -1
  123. package/dist/server/job-store.js +0 -2
  124. package/dist/server/report-server.d.ts +17 -3
  125. package/dist/server/report-server.js +357 -97
  126. package/dist/server/report-store.d.ts +14 -8
  127. package/dist/server/report-store.js +46 -0
  128. package/dist/server/skill-index.d.ts +7 -1
  129. package/dist/server/skill-index.js +48 -12
  130. package/dist/types/doctor.d.ts +22 -0
  131. package/dist/types/executor.d.ts +4 -2
  132. package/dist/types/managed.d.ts +17 -3
  133. package/dist/types/report.d.ts +15 -0
  134. package/dist/types/skill-index.d.ts +3 -0
  135. package/package.json +1 -1
@@ -4,7 +4,9 @@ import { LANG_FLAG, bilingual } from '../oclif/i18n.js';
4
4
  import { BaseCommand } from '../oclif/base-command.js';
5
5
  import { integerStringParser } from '../oclif/parsers.js';
6
6
  import { tCli } from '../lib/i18n.js';
7
- import { DEFAULT_REPORTS_DIR } from '../lib/parse-run-config.js';
7
+ import { resolveManagedDir, managedDir } from '../../managed/index.js';
8
+ import { resolveObserveHealthDir, projectObserveHealthDir, globalObserveHealthDir, resolveDoctorsDir, projectDoctorsDir, globalDoctorsDir, globalReportsDir, } from '../../eval-core/measurement-dirs.js';
9
+ import { DEFAULT_GLOBAL_OBSERVATIONS_DIR } from '../../observability/inbox.js';
8
10
  async function openWorkbench(url, lang) {
9
11
  const { execFile } = await import('node:child_process');
10
12
  const { platform } = await import('node:os');
@@ -29,7 +31,13 @@ async function openWorkbench(url, lang) {
29
31
  // import 直接调用。把业务作为 module-level helper export 从 Command file 暴露,
30
32
  // 既保留 test 兼容又让产品命令树语义干净(无 legacy commands directory)。
31
33
  export async function runStudio(_args, flags, lang) {
32
- const reportsDir = flags['reports-dir'] ?? DEFAULT_REPORTS_DIR;
34
+ // reports 读取目录:显式 --reports-dir 固定该目录;--global 钉全局;默认 = undefined,交给
35
+ // createReportServer 建 indexed(机器级聚合:当前项目 + 全局 live ∪ 别项目索引卡片)。
36
+ const reportsDirOpt = flags['reports-dir']
37
+ ? resolve(flags['reports-dir'])
38
+ : flags.global
39
+ ? globalReportsDir()
40
+ : undefined;
33
41
  if (flags.dev && !process.env.__OMK_DEV_CHILD) {
34
42
  const { spawn } = await import('node:child_process');
35
43
  const { fileURLToPath } = await import('node:url');
@@ -44,14 +52,22 @@ export async function runStudio(_args, flags, lang) {
44
52
  'studio',
45
53
  '--port', flags.port,
46
54
  ...(flags.host ? ['--host', flags.host] : []),
47
- '--reports-dir', reportsDir,
48
55
  ];
56
+ if (flags['reports-dir']) {
57
+ childArgs.push('--reports-dir', flags['reports-dir']);
58
+ }
49
59
  if (flags['analyses-dir']) {
50
60
  childArgs.push('--analyses-dir', flags['analyses-dir']);
51
61
  }
62
+ if (flags['doctors-dir']) {
63
+ childArgs.push('--doctors-dir', flags['doctors-dir']);
64
+ }
52
65
  if (flags['observations-dir']) {
53
66
  childArgs.push('--observations-dir', flags['observations-dir']);
54
67
  }
68
+ if (flags.global) {
69
+ childArgs.push('--global');
70
+ }
55
71
  if (flags['no-open']) {
56
72
  childArgs.push('--no-open');
57
73
  }
@@ -69,9 +85,31 @@ export async function runStudio(_args, flags, lang) {
69
85
  const server = createReportServer({
70
86
  port: Number(flags.port),
71
87
  ...(flags.host ? { host: flags.host } : {}),
72
- reportsDir: resolve(reportsDir),
73
- ...(flags['analyses-dir'] ? { analysesDir: resolve(flags['analyses-dir']) } : {}),
74
- ...(flags['observations-dir'] ? { observationsDir: resolve(flags['observations-dir']) } : {}),
88
+ // reportsDir 缺省 undefined → server 建 indexed(机器级:当前项目 + 全局 + 别项目索引卡片);
89
+ // 显式 --reports-dir / --global 固定单目录(逃生舱,不走聚合)。
90
+ ...(reportsDirOpt !== undefined ? { reportsDir: reportsDirOpt } : {}),
91
+ // 测量产物(observe-health / doctors)默认按请求项目优先→全局兜底(同 managed);
92
+ // 显式 --analyses-dir/--doctors-dir 固定该目录;--global 钉全局目录。
93
+ analysesDir: flags['analyses-dir']
94
+ ? resolve(flags['analyses-dir'])
95
+ : (flags.global ? globalObserveHealthDir : () => resolveObserveHealthDir(projectObserveHealthDir())),
96
+ doctorsDir: flags['doctors-dir']
97
+ ? resolve(flags['doctors-dir'])
98
+ : (flags.global ? globalDoctorsDir : () => resolveDoctorsDir(projectDoctorsDir())),
99
+ // 只有默认机器级模式才合别项目的索引卡片;--global / 显式 --analyses-dir / --doctors-dir 是逃生舱,
100
+ // 只看固定目录(与 reports 的 --reports-dir 关闭 indexed store 对称)。observe / doctor 各自独立判定。
101
+ includeObserveCards: !flags.global && !flags['analyses-dir'],
102
+ includeDoctorCards: !flags.global && !flags['doctors-dir'],
103
+ // observe-inbox 缺省按请求项目优先→全局兜底(report-server 默认即此);显式 --observations-dir 固定该目录;
104
+ // --global 钉全局(与 observe-health / doctors 的 --global 一致)。
105
+ ...(flags['observations-dir']
106
+ ? { observationsDir: resolve(flags['observations-dir']) }
107
+ : flags.global
108
+ ? { observationsDir: DEFAULT_GLOBAL_OBSERVATIONS_DIR }
109
+ : {}),
110
+ // 传解析器而非解析结果:Studio 是长会话,受管根目录要按请求解析(项目首次 install 后从 global 切回
111
+ // project),与 omk list 同口径;若在此处一次性解析、冻结进 server,长会话里会与 CLI 分叉。
112
+ managedDir: () => resolveManagedDir(managedDir()),
75
113
  });
76
114
  const url = await server.start();
77
115
  console.log(tCli('cli.studio.started', lang, { url }));
@@ -116,20 +154,32 @@ export default class Studio extends BaseCommand {
116
154
  }),
117
155
  'reports-dir': Flags.string({
118
156
  description: bilingual({
119
- zh: '报告目录,默认 ~/.oh-my-knowledge/reports',
120
- en: 'Reports dir, default ~/.oh-my-knowledge/reports',
157
+ zh: '只看指定报告目录(可选;默认机器级聚合:当前项目 + 全局 + 别项目索引)',
158
+ en: 'View only this reports dir (optional; default aggregates machine-wide: current project + global + other projects via index)',
121
159
  }),
122
160
  }),
123
161
  'analyses-dir': Flags.string({
124
162
  description: bilingual({
125
- zh: '分析数据目录(可选)',
126
- en: 'Analyses dir (optional)',
163
+ zh: '观测健康报告目录(可选,默认项目级 .omk/observe-health,空则全局兜底)',
164
+ en: 'Observe-health reports dir (optional, default project .omk/observe-health, falls back to global)',
165
+ }),
166
+ }),
167
+ 'doctors-dir': Flags.string({
168
+ description: bilingual({
169
+ zh: '体检报告目录(可选,默认项目级 .omk/doctors,空则全局兜底)',
170
+ en: 'Doctor reports dir (optional, default project .omk/doctors, falls back to global)',
127
171
  }),
128
172
  }),
129
173
  'observations-dir': Flags.string({
130
174
  description: bilingual({
131
- zh: '观测数据目录(可选)',
132
- en: 'Observations dir (optional)',
175
+ zh: '观测收件箱数据目录(可选,默认 .omk/observe-inbox)',
176
+ en: 'Observe-inbox data dir (optional, default .omk/observe-inbox)',
177
+ }),
178
+ }),
179
+ global: Flags.boolean({
180
+ description: bilingual({
181
+ zh: '只看全局 reports / observe-health / doctors / observe-inbox 目录(~/.oh-my-knowledge/*),而非机器级聚合 / 项目优先;managed 不受影响',
182
+ en: 'View only global reports / observe-health / doctors / observe-inbox dirs (~/.oh-my-knowledge/*) instead of machine-wide / project-first; does not affect managed',
133
183
  }),
134
184
  }),
135
185
  'no-open': Flags.boolean({
@@ -0,0 +1,17 @@
1
+ /**
2
+ * 终端展示前的不可信字符洗白——`omk list` 与 `omk promote` 共用。受管 JSON 可随仓库分发、用户可手改
3
+ * (store.ts validator 只收窄到「是字符串」,不卡内容),把它的字段(name / verdict / judgePromptHash /
4
+ * reportId / sourceLabel 等)塞进终端输出前必须先洗,否则 ANSI / OSC 转义、BiDi 重排、零宽分割会破坏排版
5
+ * 甚至伪造输出(清屏、改窗口标题、覆盖历史行误导审计)。一律映射到可见 U+FFFD;`--json` 路径保留原值
6
+ * (JSON.stringify 自带控制符转义,脚本消费要的是原始值)。
7
+ *
8
+ * 用 Unicode **属性类**而非手列码点 —— 手列清单天然有缺口(BiDi、U+2028 / 2029、Tags 块都曾漏一轮补一轮),
9
+ * 属性类一次覆盖整类、新码点自动纳入:
10
+ * - `\p{Cc}` 控制符(C0 / C1 / DEL,含 ESC / 换行 / 回车 / TAB)→ 杀 ANSI / OSC 转义与终端控制;
11
+ * - `\p{Cf}` 格式符(BiDi 重排 / 隔离、零宽、joiners、BOM、Tags、interlinear)→ 防 Trojan-Source 视觉伪造与零宽隐藏 / 分割;
12
+ * - `\p{Zl}` / `\p{Zp}` 行 / 段分隔(U+2028 / 2029)→ LF 的 Unicode 孪生,防换行伪造;
13
+ * - `\p{Mn}` / `\p{Me}` 非间距 / 封闭组合附加符 → 变可见,避免零前进宽度令列宽与终端错位
14
+ * (间距组合符 `\p{Mc}` 合法占 1 列,保留);
15
+ * - Hangul filler(U+115F / U+1160 / U+3164,属 Lo 不在上述任何类)→ 零宽显示诡计,补列。
16
+ */
17
+ export declare function sanitizeCell(s: string): string;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * 终端展示前的不可信字符洗白——`omk list` 与 `omk promote` 共用。受管 JSON 可随仓库分发、用户可手改
3
+ * (store.ts validator 只收窄到「是字符串」,不卡内容),把它的字段(name / verdict / judgePromptHash /
4
+ * reportId / sourceLabel 等)塞进终端输出前必须先洗,否则 ANSI / OSC 转义、BiDi 重排、零宽分割会破坏排版
5
+ * 甚至伪造输出(清屏、改窗口标题、覆盖历史行误导审计)。一律映射到可见 U+FFFD;`--json` 路径保留原值
6
+ * (JSON.stringify 自带控制符转义,脚本消费要的是原始值)。
7
+ *
8
+ * 用 Unicode **属性类**而非手列码点 —— 手列清单天然有缺口(BiDi、U+2028 / 2029、Tags 块都曾漏一轮补一轮),
9
+ * 属性类一次覆盖整类、新码点自动纳入:
10
+ * - `\p{Cc}` 控制符(C0 / C1 / DEL,含 ESC / 换行 / 回车 / TAB)→ 杀 ANSI / OSC 转义与终端控制;
11
+ * - `\p{Cf}` 格式符(BiDi 重排 / 隔离、零宽、joiners、BOM、Tags、interlinear)→ 防 Trojan-Source 视觉伪造与零宽隐藏 / 分割;
12
+ * - `\p{Zl}` / `\p{Zp}` 行 / 段分隔(U+2028 / 2029)→ LF 的 Unicode 孪生,防换行伪造;
13
+ * - `\p{Mn}` / `\p{Me}` 非间距 / 封闭组合附加符 → 变可见,避免零前进宽度令列宽与终端错位
14
+ * (间距组合符 `\p{Mc}` 合法占 1 列,保留);
15
+ * - Hangul filler(U+115F / U+1160 / U+3164,属 Lo 不在上述任何类)→ 零宽显示诡计,补列。
16
+ */
17
+ export function sanitizeCell(s) {
18
+ return s.replace(/[\p{Cc}\p{Cf}\p{Zl}\p{Zp}\p{Mn}\p{Me}ᅟᅠㅤ]/gu, '�');
19
+ }
@@ -76,6 +76,8 @@ export interface EvalFlags {
76
76
  executor?: string;
77
77
  'judge-models'?: string;
78
78
  'output-dir'?: string;
79
+ /** 报告写全局而非项目 .omk/reports(写入侧 escape;读取侧 studio / 复用走 overlay 兜底)。 */
80
+ global?: boolean;
79
81
  'no-judge'?: boolean;
80
82
  'no-cache'?: boolean;
81
83
  'dry-run'?: boolean;
@@ -140,6 +142,7 @@ export interface EvolveFlags {
140
142
  'edit-budget': string;
141
143
  'no-edit-budget': boolean;
142
144
  'no-reject-memory': boolean;
145
+ 'snapshot-only': boolean;
143
146
  }
144
147
  export interface SampleArgs {
145
148
  skillPath?: string;
@@ -149,6 +152,7 @@ export interface SampleFlags {
149
152
  batch: boolean;
150
153
  count?: string;
151
154
  model: string;
155
+ executor?: string;
152
156
  'skill-dir': string;
153
157
  focus?: string;
154
158
  'no-mock': boolean;
@@ -199,11 +203,13 @@ export interface ObserveIngestArgs {
199
203
  export interface ObserveIngestFlags {
200
204
  lang: Lang;
201
205
  'output-dir'?: string;
206
+ global: boolean;
202
207
  }
203
208
  export type ObserveInboxArgs = Record<string, never>;
204
209
  export interface ObserveInboxFlags {
205
210
  lang: Lang;
206
211
  'input-dir'?: string;
212
+ global: boolean;
207
213
  skill?: string;
208
214
  limit?: string;
209
215
  explore?: string;
@@ -221,6 +227,7 @@ export interface ObserveShowArgs {
221
227
  export interface ObserveShowFlags {
222
228
  lang: Lang;
223
229
  'input-dir'?: string;
230
+ global: boolean;
224
231
  }
225
232
  export type StudioArgs = Record<string, never>;
226
233
  export interface StudioFlags {
@@ -229,7 +236,9 @@ export interface StudioFlags {
229
236
  host?: string;
230
237
  'reports-dir'?: string;
231
238
  'analyses-dir'?: string;
239
+ 'doctors-dir'?: string;
232
240
  'observations-dir'?: string;
241
+ global?: boolean;
233
242
  'no-open': boolean;
234
243
  dev: boolean;
235
244
  }
@@ -1,3 +1,3 @@
1
1
  import type { CliMessage } from './types.js';
2
- export type CommonMessageKey = 'cli.common.unknown_domain' | 'cli.common.error_prefix' | 'cli.common.skill_dir_not_found' | 'cli.common.skill_file_not_found' | 'cli.common.skill_dir_no_skill_md' | 'cli.common.report_not_found' | 'cli.common.no_judge_model' | 'cli.common.judge_models_single_only' | 'cli.common.warn_load_samples_failed' | 'cli.update.new_version_available' | 'cli.update.box_title' | 'cli.update.box_version_line' | 'cli.update.box_upgrade_line' | 'cli.update.box_silence_line' | 'cli.observe.view_hint' | 'cli.studio.started' | 'cli.studio.stop_hint' | 'cli.studio.open_failed' | 'cli.doctor.no_skill_found' | 'cli.doctor.samples_detected';
2
+ export type CommonMessageKey = 'cli.common.unknown_domain' | 'cli.common.error_prefix' | 'cli.common.skill_dir_not_found' | 'cli.common.skill_file_not_found' | 'cli.common.skill_dir_no_skill_md' | 'cli.common.report_not_found' | 'cli.common.no_judge_model' | 'cli.common.judge_models_single_only' | 'cli.common.warn_load_samples_failed' | 'cli.update.new_version_available' | 'cli.update.box_title' | 'cli.update.box_version_line' | 'cli.update.box_upgrade_line' | 'cli.update.box_silence_line' | 'cli.observe.view_hint' | 'cli.studio.started' | 'cli.studio.stop_hint' | 'cli.studio.open_failed' | 'cli.doctor.no_skill_found' | 'cli.doctor.samples_detected' | 'cli.doctor.progress_skill_start' | 'cli.doctor.progress_skill_done';
3
3
  export declare const commonDict: Record<CommonMessageKey, CliMessage>;
@@ -56,7 +56,7 @@ export const commonDict = {
56
56
  en: 'Silence: set {env} to disable',
57
57
  },
58
58
  'cli.observe.view_hint': {
59
- zh: '分析 JSON 已写入 output-dir;后续可用 omk observe 持续生成日报。',
59
+ zh: '分析 JSON 已写入 output-dir;后续可用 omk observe 持续生成健康报告。',
60
60
  en: 'Analysis JSON written to output-dir; use omk observe to keep producing health reports.',
61
61
  },
62
62
  'cli.studio.started': {
@@ -79,4 +79,12 @@ export const commonDict = {
79
79
  zh: '✓ 使用评测用例文件:{path}',
80
80
  en: '✓ Using eval samples file: {path}',
81
81
  },
82
+ 'cli.doctor.progress_skill_start': {
83
+ zh: '{prefix}{skill} ⏳ 体检中...\n',
84
+ en: '{prefix}{skill} ⏳ checking...\n',
85
+ },
86
+ 'cli.doctor.progress_skill_done': {
87
+ zh: '{prefix}{skill} {result}({ms}ms)\n',
88
+ en: '{prefix}{skill} {result} ({ms}ms)\n',
89
+ },
82
90
  };
@@ -1,3 +1,3 @@
1
1
  import type { CliMessage } from './types.js';
2
- export type EvolveMessageKey = 'cli.evolve.specify_skill_path' | 'cli.evolve.section_header' | 'cli.evolve.round_baseline' | 'cli.evolve.round_baseline_reused' | 'cli.evolve.round_error' | 'cli.evolve.round_done' | 'cli.evolve.summary' | 'cli.evolve.best_path' | 'cli.evolve.versions_saved' | 'cli.evolve.report_link' | 'cli.evolve.holdout_active' | 'cli.evolve.holdout_disabled' | 'cli.evolve.gate_underpowered' | 'cli.evolve.generalization' | 'cli.evolve.test_disabled' | 'cli.evolve.reject_not_significant';
2
+ export type EvolveMessageKey = 'cli.evolve.specify_skill_path' | 'cli.evolve.section_header' | 'cli.evolve.round_baseline' | 'cli.evolve.round_baseline_reused' | 'cli.evolve.round_error' | 'cli.evolve.round_done' | 'cli.evolve.summary' | 'cli.evolve.best_path' | 'cli.evolve.versions_saved' | 'cli.evolve.report_link' | 'cli.evolve.holdout_active' | 'cli.evolve.holdout_disabled' | 'cli.evolve.gate_underpowered' | 'cli.evolve.generalization' | 'cli.evolve.test_disabled' | 'cli.evolve.reject_not_significant' | 'cli.evolve.evidence_recorded_managed' | 'cli.evolve.snapshot_only_hint';
3
3
  export declare const evolveDict: Record<EvolveMessageKey, CliMessage>;
@@ -39,6 +39,14 @@ export const evolveDict = {
39
39
  zh: '📊 查看报告:omk studio(报告 ID:{id})\n',
40
40
  en: '📊 View report: omk studio (report id: {id})\n',
41
41
  },
42
+ 'cli.evolve.evidence_recorded_managed': {
43
+ zh: '📌 已记入受管记录:{name}(verdict={verdict})→ measurable。运行 omk promote {name} 接受为 promoted。\n',
44
+ en: '📌 Recorded to managed record: {name} (verdict={verdict}) → measurable. Run omk promote {name} to accept as promoted.\n',
45
+ },
46
+ 'cli.evolve.snapshot_only_hint': {
47
+ zh: '📎 --snapshot-only:未写回 source,候选留在 {dir}/。挑选后手动应用,再 omk eval / omk promote。\n',
48
+ en: '📎 --snapshot-only: source not modified; candidates kept in {dir}/. Apply your pick manually, then omk eval / omk promote.\n',
49
+ },
42
50
  'cli.evolve.holdout_active': {
43
51
  zh: '🔀 holdout 切分:训练 {train} / 验收 {holdout},accept 看 holdout 分(防 train-on-test)\n',
44
52
  en: '🔀 Holdout split: {train} train / {holdout} holdout; accepted on holdout score (guards train-on-test)\n',
@@ -1,13 +1,10 @@
1
1
  export const helpDict = {
2
2
  'cli.help.observe': {
3
3
  zh: `
4
- omk observe——分析真实 session trace,生成 skill 健康度日报
4
+ omk observe——分析真实 session trace,生成 skill 健康度报告
5
5
 
6
6
  用法:
7
7
  omk observe <sessions-dir> [options]
8
- omk observe ingest <sessions-dir> [options]
9
- omk observe inbox [options]
10
- omk observe show <inbox_id> [options]
11
8
 
12
9
  选项:
13
10
  --kb <path> 知识库根路径(默认:从 trace cwd 推断)
@@ -15,27 +12,16 @@ omk observe——分析真实 session trace,生成 skill 健康度日报
15
12
  --from <iso> 窗口起点,优先级高于 --last
16
13
  --to <iso> 窗口终点,优先级高于 --last
17
14
  --skills <n1,n2,...> 只分析指定 skill
18
- --output-dir <path> 输出目录(默认:~/.oh-my-knowledge/analyses)
19
-
20
- Inbox:
21
- ingest --output-dir <path> 写入 observe inbox 数据(默认:.omk/observations;读取时兜底到 ~/.oh-my-knowledge/observations)
22
- inbox --input-dir <path> 读取 observe inbox 数据
23
- inbox --limit <n> 展示 top N(默认:20)
24
- inbox --skill <name> 只看指定 skill
25
- inbox --explore <n> 从最近 50 条 medium/low 问题里抽样查看长尾
26
- inbox --include-noise --explore 时显式包含 noise 桶
27
- inbox --by-skill 按 skill 输出资产看板
28
- inbox --json 输出 JSON
29
- show <inbox_id> --input-dir <path> 查看单条 observation 的前后上下文
15
+ --output-dir <path> 输出目录(默认:项目级 .omk/observe-health)
16
+ --global 写全局 ~/.oh-my-knowledge/observe-health,而非项目 .omk/
17
+
18
+ 观测收件箱(observe inbox)是另一条线,见 omk observe inbox --help。
30
19
  `,
31
20
  en: `
32
21
  omk observe — analyze production session traces and produce skill health reports
33
22
 
34
23
  Usage:
35
24
  omk observe <sessions-dir> [options]
36
- omk observe ingest <sessions-dir> [options]
37
- omk observe inbox [options]
38
- omk observe show <inbox_id> [options]
39
25
 
40
26
  Options:
41
27
  --kb <path> Knowledge base root (default: infer from trace cwd)
@@ -43,18 +29,10 @@ Options:
43
29
  --from <iso> Window start, overrides --last
44
30
  --to <iso> Window end, overrides --last
45
31
  --skills <n1,n2,...> Only analyze selected skills
46
- --output-dir <path> Output directory (default: ~/.oh-my-knowledge/analyses)
47
-
48
- Inbox:
49
- ingest --output-dir <path> Write observe inbox data (default: .omk/observations; read fallback: ~/.oh-my-knowledge/observations)
50
- inbox --input-dir <path> Read observe inbox data
51
- inbox --limit <n> Show top N (default: 20)
52
- inbox --skill <name> Only show one skill
53
- inbox --explore <n> Sample long-tail issues from the latest 50 medium/low items
54
- inbox --include-noise Explicitly include the noise bucket with --explore
55
- inbox --by-skill Print the skill-level asset board
56
- inbox --json Print JSON
57
- show <inbox_id> --input-dir <path> Show context around one observation
32
+ --output-dir <path> Output directory (default: project-level .omk/observe-health)
33
+ --global Write to global ~/.oh-my-knowledge/observe-health instead of project .omk/
34
+
35
+ The observe inbox is a separate line; see omk observe inbox --help.
58
36
  `,
59
37
  },
60
38
  'cli.help.observe_ingest': {
@@ -65,7 +43,7 @@ omk observe ingest — 读取真实 session trace,写入 observe inbox 数据
65
43
  omk observe ingest <sessions-dir-or-file> [options]
66
44
 
67
45
  选项:
68
- --output-dir <path> 输出目录(默认:.omk/observations;读取时兜底到 ~/.oh-my-knowledge/observations)
46
+ --output-dir <path> 输出目录(默认:.omk/observe-inbox;读取时兜底到 ~/.oh-my-knowledge/observe-inbox)
69
47
 
70
48
  支持:
71
49
  Claude Code JSONL
@@ -78,7 +56,7 @@ Usage:
78
56
  omk observe ingest <sessions-dir-or-file> [options]
79
57
 
80
58
  Options:
81
- --output-dir <path> Output directory (default: .omk/observations; read fallback: ~/.oh-my-knowledge/observations)
59
+ --output-dir <path> Output directory (default: .omk/observe-inbox; read fallback: ~/.oh-my-knowledge/observe-inbox)
82
60
 
83
61
  Supported:
84
62
  Claude Code JSONL
@@ -93,7 +71,7 @@ omk observe inbox — 查看已写入的 observe inbox 问题列表
93
71
  omk observe inbox [options]
94
72
 
95
73
  选项:
96
- --input-dir <path> 读取目录(默认:.omk/observations;兜底到 ~/.oh-my-knowledge/observations)
74
+ --input-dir <path> 读取目录(默认:.omk/observe-inbox;兜底到 ~/.oh-my-knowledge/observe-inbox)
97
75
  --limit <n> 展示 top N(默认:20)
98
76
  --skill <name> 只看指定 skill
99
77
  --explore <n> 从最近 50 条 medium/low 问题里抽样查看长尾
@@ -112,7 +90,7 @@ Usage:
112
90
  omk observe inbox [options]
113
91
 
114
92
  Options:
115
- --input-dir <path> Input directory (default: .omk/observations; fallback: ~/.oh-my-knowledge/observations)
93
+ --input-dir <path> Input directory (default: .omk/observe-inbox; fallback: ~/.oh-my-knowledge/observe-inbox)
116
94
  --limit <n> Show top N (default: 20)
117
95
  --skill <name> Only show one skill
118
96
  --explore <n> Sample long-tail issues from the latest 50 medium/low items
@@ -133,7 +111,7 @@ omk observe show — 查看单条 observation 的原始上下文
133
111
  omk observe show <inbox_id> [options]
134
112
 
135
113
  选项:
136
- --input-dir <path> 读取目录(默认:.omk/observations;兜底到 ~/.oh-my-knowledge/observations)
114
+ --input-dir <path> 读取目录(默认:.omk/observe-inbox;兜底到 ~/.oh-my-knowledge/observe-inbox)
137
115
  `,
138
116
  en: `
139
117
  omk observe show — inspect the raw context around one observation
@@ -142,7 +120,7 @@ Usage:
142
120
  omk observe show <inbox_id> [options]
143
121
 
144
122
  Options:
145
- --input-dir <path> Input directory (default: .omk/observations; fallback: ~/.oh-my-knowledge/observations)
123
+ --input-dir <path> Input directory (default: .omk/observe-inbox; fallback: ~/.oh-my-knowledge/observe-inbox)
146
124
  `,
147
125
  },
148
126
  'cli.help.evolve': {
@@ -243,16 +221,18 @@ omk studio——打开本地知识工作台
243
221
  选项:
244
222
  --port <n> 本地服务端口(默认:7799)
245
223
  --host <host> 监听地址(默认:127.0.0.1;局域网访问可用 0.0.0.0)
246
- --reports-dir <path> 报告目录(默认:~/.oh-my-knowledge/reports)
247
- --analyses-dir <path> 观测分析目录
248
- --observations-dir <path> observe inbox 数据目录(默认:.omk/observations)
224
+ --reports-dir <path> 只看指定报告目录(默认机器级聚合:当前项目 + 全局 + 别项目索引)
225
+ --analyses-dir <path> 观测健康报告目录(默认:项目级 .omk/observe-health,空则全局兜底)
226
+ --doctors-dir <path> 体检报告目录(默认:项目级 .omk/doctors,空则全局兜底)
227
+ --observations-dir <path> observe inbox 数据目录(默认:.omk/observe-inbox)
228
+ --global 只看全局 reports / observe-health / doctors 目录(~/.oh-my-knowledge/*),而非机器级聚合 / 项目优先;managed / observe-inbox 不受影响
249
229
  --no-open 只启动服务,不自动打开浏览器
250
230
  --dev 开发模式:文件变化时自动重启
251
231
 
252
232
  示例:
253
233
  omk studio
254
234
  omk studio --port 7798
255
- omk studio --host 0.0.0.0 --observations-dir .omk/observations
235
+ omk studio --host 0.0.0.0 --observations-dir .omk/observe-inbox
256
236
  omk studio --no-open
257
237
  `,
258
238
  en: `
@@ -264,16 +244,18 @@ Usage:
264
244
  Options:
265
245
  --port <n> Local server port (default: 7799)
266
246
  --host <host> Listen address (default: 127.0.0.1; use 0.0.0.0 for LAN access)
267
- --reports-dir <path> Reports directory (default: ~/.oh-my-knowledge/reports)
268
- --analyses-dir <path> Observation analyses directory
269
- --observations-dir <path> Observe inbox data directory (default: .omk/observations)
247
+ --reports-dir <path> View only this reports dir (default aggregates machine-wide: current project + global + other projects via index)
248
+ --analyses-dir <path> Observe-health reports dir (default: project .omk/observe-health, falls back to global)
249
+ --doctors-dir <path> Doctor reports dir (default: project .omk/doctors, falls back to global)
250
+ --observations-dir <path> Observe inbox data directory (default: .omk/observe-inbox)
251
+ --global View only global reports / observe-health / doctors dirs (~/.oh-my-knowledge/*) instead of machine-wide / project-first; does not affect managed / observe-inbox
270
252
  --no-open Start the server without opening a browser
271
253
  --dev Dev mode: restart on file changes
272
254
 
273
255
  Examples:
274
256
  omk studio
275
257
  omk studio --port 7798
276
- omk studio --host 0.0.0.0 --observations-dir .omk/observations
258
+ omk studio --host 0.0.0.0 --observations-dir .omk/observe-inbox
277
259
  omk studio --no-open
278
260
  `,
279
261
  },
@@ -1,7 +1,7 @@
1
1
  export const initDict = {
2
2
  'cli.init.scaffolded': {
3
- zh: '已初始化测评项目: {dir}',
4
- en: 'Eval project scaffolded at: {dir}',
3
+ zh: '已初始化 omk 项目: {dir}',
4
+ en: 'omk project initialized at: {dir}',
5
5
  },
6
6
  'cli.init.next_steps_title': {
7
7
  zh: '下一步:',
@@ -1,3 +1,3 @@
1
1
  import type { CliMessage } from './types.js';
2
- export type ListMessageKey = 'cli.list.header' | 'cli.list.empty' | 'cli.list.empty_hint' | 'cli.list.col_name' | 'cli.list.col_kind' | 'cli.list.col_state' | 'cli.list.col_verdict' | 'cli.list.col_evidence' | 'cli.list.col_source' | 'cli.list.drift_note' | 'cli.list.unreachable_note' | 'cli.list.legend';
2
+ export type ListMessageKey = 'cli.list.header' | 'cli.list.empty' | 'cli.list.empty_hint' | 'cli.list.col_name' | 'cli.list.col_kind' | 'cli.list.col_state' | 'cli.list.col_verdict' | 'cli.list.col_evidence' | 'cli.list.col_source' | 'cli.list.drift_note' | 'cli.list.unreachable_note' | 'cli.list.promoted_note' | 'cli.list.legend';
3
3
  export declare const listDict: Record<ListMessageKey, CliMessage>;
@@ -25,6 +25,10 @@ export const listDict = {
25
25
  zh: '? = 源此处不可达 / 拒读,drift 未核(非 stale);本地 git 源请在原仓库根目录跑 omk list。\n',
26
26
  en: '? = source unreachable / refused here, drift unchecked (not stale); for a local git source run omk list from the original repo root.\n',
27
27
  },
28
+ 'cli.list.promoted_note': {
29
+ zh: '✓ = 当前版本已按证据人工接受为 promoted(omk promote)。\n',
30
+ en: '✓ = current version accepted as promoted on evidence (omk promote).\n',
31
+ },
28
32
  'cli.list.legend': {
29
33
  zh: '证据列 = 当前有效 / 全部(历史含旧内容证据,供回滚)。\n',
30
34
  en: 'EVIDENCE column = current / total (history keeps old-content evidence for rollback).\n',
@@ -0,0 +1,3 @@
1
+ import type { CliMessage } from './types.js';
2
+ export type PromoteMessageKey = 'cli.promote.kind_unsupported' | 'cli.promote.not_managed' | 'cli.promote.blocked_header' | 'cli.promote.drifted' | 'cli.promote.no_current_evidence' | 'cli.promote.incomparable' | 'cli.promote.incomparable_unverified' | 'cli.promote.verdict_blocked' | 'cli.promote.force_hint' | 'cli.promote.force_reason_required' | 'cli.promote.promoted' | 'cli.promote.forced_override' | 'cli.promote.already_promoted';
3
+ export declare const promoteDict: Record<PromoteMessageKey, CliMessage>;
@@ -0,0 +1,54 @@
1
+ export const promoteDict = {
2
+ 'cli.promote.kind_unsupported': {
3
+ zh: 'promote 暂仅支持 kind=skill;收到 {kind}。',
4
+ en: 'promote supports only kind=skill today; got {kind}.',
5
+ },
6
+ 'cli.promote.not_managed': {
7
+ zh: '未找到受管记录 {name}(kind={kind})。先用 omk install 纳管、omk eval 取证,再 promote。',
8
+ en: 'No managed record {name} (kind={kind}). Run omk install to register, omk eval to gather evidence, then promote.',
9
+ },
10
+ 'cli.promote.blocked_header': {
11
+ zh: 'promote 被门禁拦下({name}):',
12
+ en: 'promote was blocked by the gate ({name}):',
13
+ },
14
+ 'cli.promote.drifted': {
15
+ zh: '· 源已漂移或不可达:当前源内容与受管基线不一致,证据对应的是旧内容。重跑 omk eval 重新取证。',
16
+ en: '· source drifted or unreachable: current source content differs from the managed baseline; the evidence is for old content. Re-run omk eval.',
17
+ },
18
+ 'cli.promote.no_current_evidence': {
19
+ zh: '· 当前内容没有评测证据,无法 promote(force 也不行)。先跑 omk eval 取证(omk list 看证据状态)。',
20
+ en: '· no evaluation evidence for the current content; cannot promote (not even with --force). Run omk eval first (omk list shows evidence status).',
21
+ },
22
+ 'cli.promote.incomparable': {
23
+ zh: '· 证据的评委提示词指纹 {judgePromptHash} 不是当前评委:judge prompt 已变、旧 verdict 不可比。重跑 omk eval。',
24
+ en: '· evidence judge-prompt fingerprint {judgePromptHash} is not the current judge: the judge prompt changed, the old verdict is incomparable. Re-run omk eval.',
25
+ },
26
+ 'cli.promote.incomparable_unverified': {
27
+ zh: '⚠️ 证据缺评委提示词指纹,无法核对可比性(按未核处理,不拦门禁)。',
28
+ en: '⚠️ evidence has no judge-prompt fingerprint; comparability cannot be verified (treated as unchecked, not blocking).',
29
+ },
30
+ 'cli.promote.verdict_blocked': {
31
+ zh: '· 当前证据 verdict={verdict},不在接受集(默认仅 PROGRESS;CAUTIOUS 需 --accept-cautious)。',
32
+ en: '· current evidence verdict={verdict} is not in the accepted set (default PROGRESS only; CAUTIOUS needs --accept-cautious).',
33
+ },
34
+ 'cli.promote.force_hint': {
35
+ zh: '如确需越门,加 --force 并用 --reason 写明理由(会记为人工 override 决定)。',
36
+ en: 'To override anyway, pass --force with --reason (recorded as a human override decision).',
37
+ },
38
+ 'cli.promote.force_reason_required': {
39
+ zh: '--force 必须同时提供非空 --reason,说明人工越门理由。',
40
+ en: '--force requires a non-empty --reason explaining the human override.',
41
+ },
42
+ 'cli.promote.promoted': {
43
+ zh: '已 promote {name}:接受内容 {hash}(verdict={verdict},report={reportId})。',
44
+ en: 'Promoted {name}: accepted content {hash} (verdict={verdict}, report={reportId}).',
45
+ },
46
+ 'cli.promote.forced_override': {
47
+ zh: '⚠️ 已 --force 越门 promote {name}:接受内容 {hash}(被越过的 verdict={verdict})。越门已记为人工决定。',
48
+ en: '⚠️ force-promoted {name}: accepted content {hash} (overridden verdict={verdict}). The override is recorded as a human decision.',
49
+ },
50
+ 'cli.promote.already_promoted': {
51
+ zh: '{name} 的当前内容已 promote 过,无需重复(幂等,未改动记录)。',
52
+ en: '{name} current content is already promoted; nothing to do (idempotent, record untouched).',
53
+ },
54
+ };
@@ -0,0 +1,3 @@
1
+ import type { CliMessage } from './types.js';
2
+ export type RollbackMessageKey = 'cli.rollback.kind_unsupported' | 'cli.rollback.not_managed' | 'cli.rollback.not_promoted' | 'cli.rollback.rolled_back' | 'cli.rollback.already_rolled_back';
3
+ export declare const rollbackDict: Record<RollbackMessageKey, CliMessage>;
@@ -0,0 +1,22 @@
1
+ export const rollbackDict = {
2
+ 'cli.rollback.kind_unsupported': {
3
+ zh: 'rollback 暂仅支持 kind=skill;收到 {kind}。',
4
+ en: 'rollback supports only kind=skill today; got {kind}.',
5
+ },
6
+ 'cli.rollback.not_managed': {
7
+ zh: '未找到受管记录 {name}(kind={kind})。omk rollback 只作用于已 install 的 skill。',
8
+ en: 'No managed record {name} (kind={kind}). omk rollback only operates on installed skills.',
9
+ },
10
+ 'cli.rollback.not_promoted': {
11
+ zh: '{name} 的当前内容未处于 promoted 态,无可回退(omk list 看生命周期状态)。',
12
+ en: '{name} current content is not promoted; nothing to roll back (omk list shows the lifecycle state).',
13
+ },
14
+ 'cli.rollback.rolled_back': {
15
+ zh: '已回退 {name}:撤销当前内容 {hash} 的 promoted 接受(已记为人工决定)。源仍匹配受管基线则 omk list 回到 measurable,源已漂移则仍为 stale。',
16
+ en: 'Rolled back {name}: revoked the promoted acceptance of current content {hash} (recorded as a human decision). omk list shows measurable if the source still matches the managed baseline, or stale if it has drifted.',
17
+ },
18
+ 'cli.rollback.already_rolled_back': {
19
+ zh: '{name} 的当前内容本就未 promoted,无需回退(幂等,未改动记录)。',
20
+ en: '{name} current content is already not promoted; nothing to do (idempotent, record untouched).',
21
+ },
22
+ };
@@ -57,8 +57,10 @@ import { type HelpMessageKey } from './i18n-dict/help.js';
57
57
  import { type InitMessageKey } from './i18n-dict/init.js';
58
58
  import { type InstallMessageKey } from './i18n-dict/install.js';
59
59
  import { type ListMessageKey } from './i18n-dict/list.js';
60
+ import { type PromoteMessageKey } from './i18n-dict/promote.js';
61
+ import { type RollbackMessageKey } from './i18n-dict/rollback.js';
60
62
  import { type RunMessageKey } from './i18n-dict/run.js';
61
63
  import type { CliMessage } from './i18n-dict/types.js';
62
64
  export type { CliMessage } from './i18n-dict/types.js';
63
- export type CliMessageKey = CommonMessageKey | EvolveMessageKey | GenMessageKey | HelpMessageKey | InitMessageKey | InstallMessageKey | ListMessageKey | RunMessageKey;
65
+ export type CliMessageKey = CommonMessageKey | EvolveMessageKey | GenMessageKey | HelpMessageKey | InitMessageKey | InstallMessageKey | ListMessageKey | PromoteMessageKey | RollbackMessageKey | RunMessageKey;
64
66
  export declare const CLI_DICT: Record<CliMessageKey, CliMessage>;
@@ -57,6 +57,8 @@ import { helpDict } from './i18n-dict/help.js';
57
57
  import { initDict } from './i18n-dict/init.js';
58
58
  import { installDict } from './i18n-dict/install.js';
59
59
  import { listDict } from './i18n-dict/list.js';
60
+ import { promoteDict } from './i18n-dict/promote.js';
61
+ import { rollbackDict } from './i18n-dict/rollback.js';
60
62
  import { runDict } from './i18n-dict/run.js';
61
63
  export const CLI_DICT = {
62
64
  ...commonDict,
@@ -66,5 +68,7 @@ export const CLI_DICT = {
66
68
  ...initDict,
67
69
  ...installDict,
68
70
  ...listDict,
71
+ ...promoteDict,
72
+ ...rollbackDict,
69
73
  ...runDict,
70
74
  };
@@ -83,7 +83,6 @@ export interface ParseRunConfigResult {
83
83
  * (e.g. repeat / judgeRepeat / bootstrap — handled in `commands/eval-runner.ts` for input validation). */
84
84
  evalConfig: EvalConfig | null;
85
85
  }
86
- export declare const DEFAULT_REPORTS_DIR: string;
87
86
  /**
88
87
  * 接 typed flags(来自 oclif Command.parse() 输出)。oclif strict 模式已经在
89
88
  * 上游对未知 flag 拦截 exit 2,这里不再 parseArgs。eval-runner 等业务 caller