@fenglimg/fabric-shared 2.3.0-rc.1 → 2.3.0-rc.10

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.
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  resolveGlobalLocale
3
- } from "./chunk-2GLIAZ5M.js";
3
+ } from "./chunk-ASS2KBB7.js";
4
4
 
5
5
  // src/i18n/locales/en.ts
6
6
  var enMessages = {
7
- "cli.main.description": "Fabric CLI \u2014 feeds your project's decisions, pitfalls & conventions to your AI assistant automatically, so it stops re-learning them every session.\n\nThree-step mental model:\n Install (\u88C5) - fabric install one-shot project setup\n Configure (\u914D) - fabric config interactive configuration panel\n Maintain (\u8DD1) - fabric doctor run target-state diagnostics\n fabric sync sync mounted knowledge stores\n\nExamples:\n fabric install install Fabric in the current project\n fabric config open the interactive configuration panel\n fabric doctor --fix repair derived Fabric state\n fabric doctor --fix-knowledge repair knowledge entry state\n fabric sync pull/rebase and push mounted stores\n fabric uninstall --dry-run preview uninstall without removing files",
7
+ "cli.main.description": "Fabric CLI \u2014 feeds your project's decisions, pitfalls & conventions to your AI assistant automatically. First time? Run: fabric install",
8
8
  "cli.shared.created": "Created",
9
9
  "cli.shared.skipped": "Skipped",
10
10
  "cli.shared.next": "Next",
@@ -18,27 +18,80 @@ var enMessages = {
18
18
  "cli.shared.none": "none",
19
19
  "cli.shared.loading": "loading",
20
20
  "cli.shared.refresh": "Refresh",
21
+ // flat-design-system Wave4 (TASK-004): gutter-free ✓/x receipt printed after a
22
+ // clack control (select/multiselect/confirm/text) resolves. The clack control
23
+ // stays native (C-006); the receipt is a separate flat line.
24
+ "cli.prompt.receipt.selected": "Selected",
25
+ "cli.prompt.receipt.set": "Set",
26
+ "cli.prompt.receipt.cancelled": "Cancelled",
21
27
  "cli.shared.target-invalid": "Target must be an existing directory: {target}",
22
28
  "cli.shared.target-invalid.action-hint": "Choose an existing project directory, or create it before running the command again.",
23
29
  "cli.shared.template-not-found": "Template not found: {path}",
24
30
  "cli.shared.invalid-host-empty": "Invalid host: <empty>",
25
31
  "cli.shared.invalid-port": "Invalid port: {value}",
26
32
  "cli.shared.error": "Error",
27
- // EPIC-011 / W3-F: Grouped help display i18n keys (Knowledge/Project/Maintain).
28
- "cli.help.group.knowledge.store": "Manage knowledge stores (see: fabric store --help)",
29
- "cli.help.group.knowledge.sync": "Sync team knowledge with remote stores",
30
- "cli.help.group.project.install": "Initialize Fabric in this repository",
31
- "cli.help.group.project.config": "Configure Fabric settings",
32
- "cli.help.group.project.info": "Show project status",
33
- "cli.help.group.project.inspect": "Show what SessionStart injects this session",
34
- "cli.help.group.maintain.doctor": "Check Fabric health and repair issues",
35
- "cli.help.group.maintain.audit": "Knowledge & telemetry audit (cite/conflicts/history/metrics)",
33
+ // Top-level command summaries (one concise line each citty renders these in
34
+ // the root `fabric --help` COMMANDS table AND as the header of each command's
35
+ // own `--help`, so they MUST stay single-line; verbose example blocks were
36
+ // removed when the bespoke grouped help retired in favour of citty's renderer).
37
+ "cli.store.description": "Manage mounted knowledge stores (setup via fabric install)",
38
+ "cli.sync.description": "Sync mounted knowledge stores (pull --rebase + push)",
39
+ "cli.info.description": "Show Fabric identity, project status & recall health",
40
+ "cli.inspect.description": "Show what Fabric injects at SessionStart",
41
+ // `fabric inspect` arg descriptions + --explain provenance overlay + error.
42
+ "cli.inspect.arg.render": "Which sink to show: 'human' (systemMessage) or 'ai' (additionalContext). Default: both.",
43
+ "cli.inspect.arg.explain": "Append a per-entry provenance section (id \xB7 type \xB7 maturity \xB7 scope \xB7 why-surfaced).",
44
+ "cli.inspect.arg.target": "Override the project root (defaults to cwd / dev-mode resolution).",
45
+ "cli.inspect.explain.title": "explain \xB7 provenance (not injected)",
46
+ "cli.inspect.explain.always": "always-active \xB7 body injected",
47
+ "cli.inspect.explain.reference": "reference \xB7 read on demand",
48
+ "cli.inspect.explain.census": "census",
49
+ "cli.inspect.explain.census-total": "total {total}",
50
+ "cli.inspect.error": "inspect failed: {message}",
51
+ "cli.audit.description": "Knowledge & telemetry audit (cite/conflicts/history/metrics)",
52
+ // `fabric audit cite` — 0%-recall-coverage self-diagnosis hints.
53
+ "cli.audit.cite.recall-mismatch-hint": "recall coverage is 0 despite {recalls} recall(s) across {sessions} session(s) \u2014 none shared a session with an edit. The recall caller is likely passing a non-client session_id (correlation is session-scoped). See AGENTS.md: pass the real client session_id to fab_recall.",
54
+ "cli.audit.cite.recall-none-hint": "recall coverage is 0 \u2014 no in-session fab_recall preceded these edits. Recall before editing, and pass the real client session_id (correlation is session-scoped). See AGENTS.md.",
55
+ // `fabric audit --help` — filtered help (i18n'd subcommand listing).
56
+ "cli.audit.help.tagline": "Knowledge & telemetry audit surfaces (read-only)",
57
+ "cli.audit.help.sub.cite": "Cite-policy adherence report",
58
+ "cli.audit.help.sub.conflicts": "Knowledge-conflict lint",
59
+ "cli.audit.help.sub.history": "Maintenance history rollup (archive | fix | all)",
60
+ "cli.audit.help.sub.descriptions": "Back-fill description-grade frontmatter fields",
61
+ "cli.audit.help.sub.retired": "Scan agent surfaces for retired tool/field references",
62
+ "cli.audit.help.sub.why": "Diagnose why a knowledge entry isn't surfacing",
63
+ "cli.audit.help.example.cite": "cite-coverage over the last 7 days",
64
+ "cli.audit.help.example.conflicts": "scan for conflicting / duplicate entries",
65
+ "cli.audit.help.footer": "Run `fabric audit <subcommand> --help` for per-command flags.",
66
+ // `fabric audit retired` — flat renderer copy.
67
+ "cli.audit.retired.skipped": "Retired-reference scan skipped \u2014 no agent-consumed surfaces found.",
68
+ "cli.audit.retired.clean": "No retired references \u2014 scanned {count} agent surface(s).",
69
+ "cli.audit.retired.found": "{hits} retired reference(s) across {files} scanned file(s)",
70
+ "cli.audit.retired.removed": "(removed)",
71
+ // `fabric audit why-not-surfaced <id>` — three-axis diagnosis (store / scope / timing).
72
+ "cli.audit.why.not-found": "'{id}' not found in any mounted store. Check the id (try `fabric store list`).",
73
+ "cli.audit.why.store-unbound": "'{id}' lives in store '{store}', which is NOT bound to this project.",
74
+ "cli.audit.why.store-unbound.hint": "bind it: fabric store bind {store}",
75
+ "cli.audit.why.project-mismatch": "'{id}' is scoped to '{scope}', but this repo is bound to 'project:{project}'.",
76
+ "cli.audit.why.project-mismatch.hint": "it surfaces only in repos bound to '{scope}' (semantic_scope axis).",
77
+ "cli.audit.why.narrow-timing": "'{id}' is relevance_scope=narrow \u2014 it surfaces via the PreToolUse hint when you EDIT a matching file, not at SessionStart.",
78
+ "cli.audit.why.narrow-timing.hint": "broad entries are the always-on spine; narrow ones are edit-time only (timing axis).",
79
+ "cli.audit.why.should-surface": "'{id}' should be surfacing \u2014 store '{store}' bound, scope matches, relevance_scope=broad.",
80
+ "cli.audit.why.should-surface.hint": "if it isn't, the SessionStart snapshot may be stale: start a fresh session or re-run `fabric install`.",
81
+ // `fabric info --help` — flag + scope-subcommand descriptions.
82
+ "cli.info.args.global.description": "Show global identity (whoami) instead of project status",
83
+ "cli.info.args.recall.description": "Show recall-engine detail (fusion strategy + embedding state)",
84
+ "cli.info.args.warm.description": "With --recall: load the embedder now (downloads the model to ~/.fabric/cache/embed on first run)",
85
+ "cli.info.args.json.description": "Emit machine-readable JSON instead of text",
86
+ "cli.info.scope.description": "(advanced/skill) Resolve a scope coordinate's read-set + write target as JSON",
87
+ "cli.info.scope.args.coord.description": "Scope coordinate (e.g. team, project:x, personal)",
88
+ "cli.info.scope.args.json.description": "Emit machine-readable JSON (scope always emits JSON)",
36
89
  // v2.1 hidden-command i18n keys cleanup: approve/bootstrap/hooks/human-lint/
37
90
  // ledger-append/pre-commit/scan/sync-meta/update commands removed from CLI
38
91
  // surface in v2.0.0-rc.18. Keys intentionally retained for backward compat
39
92
  // with external tooling that may still reference them. Remove in v2.2
40
93
  // if no external consumers surface.
41
- "cli.config.description": "Open the interactive Fabric configuration panel (language, knowledge layer, audit mode, hint windows, MCP client wiring, etc.).\n\nExamples:\n fabric config open the interactive panel\n fabric config --target /path edit configuration for a specific project",
94
+ "cli.config.description": "Open the interactive Fabric configuration panel (language, knowledge layer, audit mode, MCP client wiring, etc.)",
42
95
  "cli.config.args.target.description": "Target project directory (defaults to cwd).",
43
96
  "cli.config.clients.claude": "Claude Code CLI",
44
97
  "cli.config.install.description": "Install Fabric MCP server entries into detected client configs.",
@@ -54,6 +107,9 @@ var enMessages = {
54
107
  // Keys consumed by packages/cli/src/commands/config.ts (menu loop +
55
108
  // per-field prompts) and by getPanelFields() (label_i18n_key references).
56
109
  "cli.config.intro": "Fabric Configuration",
110
+ // flat-design-system Wave5 (TASK-005): B-横线 title above the flat key/value
111
+ // panel printed before the clack edit menu.
112
+ "cli.config.panel.title": "Current configuration",
57
113
  "cli.config.outro": "Configuration saved.",
58
114
  "cli.config.outro-no-changes": "No changes made.",
59
115
  "cli.config.cancel": "Cancelled.",
@@ -64,8 +120,17 @@ var enMessages = {
64
120
  "cli.config.value.default-marker": "(default)",
65
121
  "cli.config.prompt.select": "Choose a new value for {key} (current: {current}):",
66
122
  "cli.config.prompt.text": "Enter a new value for {key} (current: {current}):",
67
- "cli.config.write.success": "Saved {key} = {value}",
123
+ "cli.config.write.success": "{key} = {value}",
124
+ "cli.config.panel.edited": "Edited this session ({count}): {keys}",
68
125
  "cli.config.write.failure": "Failed to write fabric-config.json: {message}",
126
+ "cli.config.slot.errors.missing": "Missing required <slot> argument. Valid slots: {slots}.",
127
+ "cli.config.slot.errors.unknown": 'Unknown slot "{slot}". Valid slots: {slots}.',
128
+ "cli.config.slot.dismiss.already": 'Slot "{slot}" already opted out; no-op.',
129
+ "cli.config.slot.dismiss.done": 'Dismissed onboard slot "{slot}". Run `fabric config onboard-reset {slot}` to re-open.',
130
+ "cli.config.slot.dismiss.failed": "dismiss-slot failed: {message}",
131
+ "cli.config.slot.reset.not-opted": 'Slot "{slot}" not opted out; no-op.',
132
+ "cli.config.slot.reset.done": 'Reset onboard slot "{slot}"; it will appear in `fabric onboard-coverage` as missing again.',
133
+ "cli.config.slot.reset.failed": "onboard-reset failed: {message}",
69
134
  "cli.config.errors.uninit-workspace.message": "Workspace not initialized. Run `fabric install` first.",
70
135
  "cli.config.errors.invalid-int": "Must be a positive integer.",
71
136
  "cli.config.errors.unknown-field": "Unknown field selection \u2014 skipping.",
@@ -96,12 +161,55 @@ var enMessages = {
96
161
  "cli.config.fields.nudge_mode.label": "Nudge level",
97
162
  "cli.config.fields.nudge_mode.description": "Preset for human-visible nudges (silent / minimal / normal / verbose). Governs only the human channel \u2014 never the knowledge injected to the AI.",
98
163
  "cli.config.fields.embed_enabled.label": "Vector semantic search",
99
- "cli.config.fields.embed_enabled.description": "Enable vector semantic recall (true / false). Note: turning this on also needs `fabric install --enable-embed` for the host-side setup (fastembed + model cache); flipping it here alone does not enable it.",
100
- "cli.doctor.description": "Run Fabric target-state diagnostics (meta sync, knowledge index, bootstrap, events ledger, human-lock drift).\n\nExamples:\n fabric doctor read-only diagnostics report\n fabric doctor --fix repair derived state (meta + indexes)\n fabric doctor --fix-knowledge apply lint mutations (counter / archive / cache)\n fabric doctor --json machine-readable output",
164
+ "cli.config.fields.embed_enabled.description": "Enable vector semantic recall (true / false). Note: true is just intent \u2014 it only takes effect when the running server can resolve the fastembed package AND the model is downloaded (auto-fetched to ~/.fabric/cache/embed on first recall). Check actual state with `fabric info recall`.",
165
+ "cli.config.fields.fusion.label": "Recall fusion strategy",
166
+ "cli.config.fields.fusion.description": "How the signals combine into one score: additive = weighted sum (BM25-led, small vector weight) / rrf = Reciprocal Rank Fusion (BM25 and vector on equal footing, so semantics actually count) / auto = adaptive (default: rrf when the vector channel is scoring, else additive \u2014 avoids degenerate single-channel rrf being worse).",
167
+ "cli.doctor.description": "Run Fabric target-state diagnostics (meta sync, knowledge index, bootstrap, events ledger, human-lock drift)",
101
168
  "doctor.section.fixable": "Fixable errors:",
102
169
  "doctor.section.manual": "Manual errors:",
103
170
  "doctor.section.warnings": "Warnings:",
104
171
  "doctor.section.fix-knowledge-mutations": "Fix-knowledge mutations:",
172
+ // flat-design follow-up: the remaining doctor UI-shell strings (TL;DR header,
173
+ // --fix mutation plan, filtered --help) move off hardcoded English into i18n so
174
+ // the whole `fabric doctor` surface honours the machine locale. USAGE/OPTIONS/
175
+ // EXAMPLES labels stay English to match citty's own renderUsage in the other
176
+ // commands' --help.
177
+ "doctor.digest.todo": "To fix ({count})",
178
+ "doctor.digest.clean": "all {count} checks passed \u2014 nothing to fix",
179
+ "doctor.digest.summary": "{todo} to fix \xB7 {ok} passed \xB7 contributor diagnostics \u2192 --verbose",
180
+ "doctor.digest.more-verbose": "{count} contributor finding(s) hidden \u2014 see --verbose",
181
+ // store diagnostics (multi-store health, the `● 存储健康` group) — i18n parity
182
+ // with doctor.check.*; messages carry store alias / counts via interpolation.
183
+ "doctor.store.no-global-config": "no global Fabric config \u2014 run `fabric install --global <url>`",
184
+ "doctor.store.missing-required": "required store '{id}' is not mounted; run `fabric store mount`",
185
+ "doctor.store.unbound": "store '{alias}' is mounted but not bound to this project; run `fabric store bind {alias}` to read its knowledge here (then `fabric store switch-write {alias}` to write team knowledge into it)",
186
+ "doctor.store.alias-drift": "by-alias readability link(s) out of sync for {refs}; run `fabric doctor --fix` to repair ~/.fabric/stores/by-alias/",
187
+ "doctor.store.local-only": "store '{alias}' is local-only; add a git remote to back it up",
188
+ "doctor.store.executable": "store '{alias}' contains executable/script files ({files}) \u2014 stores are data-only; Fabric never runs them (S65)",
189
+ "doctor.store.active-personal-invalid": "active personal store '{store}' is not a mounted personal store; run `fabric store switch-personal <alias>` or `fabric doctor --fix`",
190
+ "doctor.store.active-personal-unset": "{count} personal stores are mounted but none is active; run `fabric store switch-personal <alias>` to pick one (or `fabric doctor --fix` to default to the first)",
191
+ "doctor.store.related-broken": "{count} broken `related` link(s) point at ids absent from the corpus: {samples}{overflow} \u2014 fix the related edges via `fab_review` (modify) or edit the entry frontmatter",
192
+ "doctor.store.related-hub": "related graph hubs (top {shown} of {total} referenced): {top}",
193
+ "doctor.store.unreachable": "store '{alias}' is in the read-set but unreachable on disk ({reason}); run `fabric store mount` / re-clone it, then `fabric doctor`",
194
+ "doctor.store.consumption-heatmap": "top consumed (last {days}d, {consumed}/{total} entries read across {windows} window(s)): {top}",
195
+ "doctor.store.consumption-zero": "{count} entries never consumed in the last {days}d: {sample}{overflow} \u2014 review for retirement via `fab_review` (consumption is one signal, not proof of rot)",
196
+ "doctor.store.overflow-more": ", \u2026(+{count} more)",
197
+ "doctor.fix-plan.header": "fix-knowledge mutation plan ({count} total)",
198
+ "doctor.fix-plan.preview": "preview:",
199
+ "doctor.fix-plan.more": "... and {count} more",
200
+ "doctor.help.tagline": "Diagnose and fix Fabric workspace issues",
201
+ "doctor.help.flag.target": "Override project root (defaults to cwd)",
202
+ "doctor.help.flag.fix": "Auto-fix issues (derived-state + knowledge frontmatter/git mv)",
203
+ "doctor.help.flag.json": "Output as JSON for programmatic consumption",
204
+ "doctor.help.flag.verbose": "Show maintainer-audience action hints",
205
+ "doctor.help.example.run": "Run diagnostics",
206
+ "doctor.help.example.fix": "Fix derived-state + knowledge issues",
207
+ "doctor.help.footer": "Run `fabric doctor` to see a full diagnostic report. Audits \u2192 `fabric audit`.",
208
+ // flat-design-system Wave5 (TASK-005): C-圆点 group headers for the reskinned
209
+ // doctor surface (`● Store Health` / `● Checks`), replacing the old hardcoded
210
+ // sectionBar literals so the wording is localized in both locales.
211
+ "doctor.group.store-health": "Store Health",
212
+ "doctor.group.checks": "Checks",
105
213
  // v2.0.0-rc.29 REVIEW (codex LOW-2): F2's payload-limit defaults reach the JSON
106
214
  // envelope but never surfaced in the human renderer, so operators tuning
107
215
  // `mcpPayloadLimits` had no fast `fabric doctor` confirmation that their config
@@ -323,12 +431,17 @@ var enMessages = {
323
431
  "doctor.check.skill_token_budget.message.singular": "{count} SKILL.md exceeds the token budget: {list}. Sink detail into ref/ for progressive disclosure.",
324
432
  "doctor.check.skill_token_budget.message.plural": "{count} SKILL.md files exceed the token budget: {list}. Sink detail into ref/ for progressive disclosure.",
325
433
  "doctor.check.skill_token_budget.remediation": "Move detailed phase / worked-examples / decision tables out of the SKILL.md hot path into `templates/skills/<slug>/ref/*.md`. Keep SKILL.md focused on trigger-gate + key-phase summaries; see W1 progressive disclosure split. Re-run `fabric install` to sync both client subtrees.",
326
- // v2.0.0-rc.33 W3-7 (P1-14): SKILL.md description structural lint. Proxy for trigger-recall (a live-LLM recall test requires a model — W1 ran gemini for that). This lint catches regression: missing description / >60 tokens / no Chinese trigger / no English trigger.
434
+ // v2.0.0-rc.33 W3-7 (P1-14): SKILL.md description structural lint. Proxy for trigger-recall (a live-LLM recall test requires a model — W1 ran gemini for that). This lint catches regression: missing description / >60 tokens / no Chinese trigger / no English trigger / no anti-trigger boundary.
327
435
  "doctor.check.skill_description.name": "Skill description quality",
328
- "doctor.check.skill_description.ok": "All SKILL.md description fields are well-structured (non-empty, <60 tokens, bilingual triggers).",
436
+ "doctor.check.skill_description.ok": "All SKILL.md description fields are well-structured (non-empty, <60 tokens, bilingual triggers, explicit anti-trigger boundary).",
329
437
  "doctor.check.skill_description.message.singular": "{count} SKILL.md description structural issue: {list}. The description field is the host's primary auto-invoke matching signal.",
330
438
  "doctor.check.skill_description.message.plural": "{count} SKILL.md description structural issues: {list}. The description field is the host's primary auto-invoke matching signal.",
331
- "doctor.check.skill_description.remediation": "Edit the `description:` field in `packages/cli/templates/skills/<slug>/SKILL.md` frontmatter: (1) non-empty; (2) <60 tokens (chars/3 estimate, ~180 chars); (3) at least one Chinese trigger phrase; (4) at least one English trigger phrase. See W1 description rewrite style. Re-run `fabric install` to sync both client subtrees. For recall verification, run the W1 gemini delegate (see .workflow/.scratchpad/rc33-plan/W1-VERIFY-RESULT.md).",
439
+ "doctor.check.skill_description.remediation": "Edit the `description:` field in `packages/cli/templates/skills/<slug>/SKILL.md` frontmatter: (1) non-empty; (2) <60 tokens (chars/3 estimate, ~180 chars); (3) at least one Chinese trigger phrase; (4) at least one English trigger phrase; (5) an explicit anti-trigger such as `NOT PR review` / `NOT code review` / `\u4E0D\u662F...`. See W1 description rewrite style. Re-run `fabric install` to sync both client subtrees. For recall verification, run the W1 gemini delegate (see .workflow/.scratchpad/rc33-plan/W1-VERIFY-RESULT.md).",
440
+ "doctor.check.skill_contract.name": "Skill contract integrity",
441
+ "doctor.check.skill_contract.ok": "Fabric SKILL.md contracts are intact: hard-rule anchors, MCP-only write paths, thin shims, and ref entry points are present.",
442
+ "doctor.check.skill_contract.message.singular": "{count} Fabric skill contract issue: {list}.",
443
+ "doctor.check.skill_contract.message.plural": "{count} Fabric skill contract issues: {list}.",
444
+ "doctor.check.skill_contract.remediation": "Restore the missing contract text in `packages/cli/templates/skills/<slug>/SKILL.md` and referenced `ref/*.md` files, then run `fabric install` to resync `.claude/skills` and `.codex/skills`. Archive/review must keep DISPLAY/WRITE hard rules and MCP-only mutation paths; store/sync must remain thin CLI shims.",
332
445
  // v2.0.0-rc.33 W3-3 (P1-3): cite-policy Goodhart pattern detection. Scans 7d of assistant_turn_observed events for 3 anti-patterns (G1 ritual / G2 dismissal abuse / G5 placeholder cite). Warning severity — heuristics can false-positive; advisory only.
333
446
  "doctor.check.cite_goodhart.name": "Cite-policy Goodhart",
334
447
  "doctor.check.cite_goodhart.ok": "No cite-policy Goodhart patterns detected over the last 7 days.",
@@ -381,6 +494,13 @@ var enMessages = {
381
494
  "doctor.check.store_orphan.message.plural": "{count} stores exist on disk but are not registered in the global registry (first: {detail}); recall / bind cannot see them. Run `fabric doctor --fix` to adopt them (re-register \u2014 never deletes the on-disk tree).",
382
495
  "doctor.check.store_orphan.remediation": "Run `fabric doctor --fix` to adopt the orphan store(s) into the registry (re-register by store_uuid, alias auto-disambiguated on clash; rescue-before-delete \u2014 registers, never deletes on disk).",
383
496
  "doctor.check.store_orphan.ok": "No unregistered orphan stores under ~/.fabric/stores.",
497
+ // W2 (F-003): project-registry drift — projects.json ↔ projects/ folder tree.
498
+ "doctor.check.project_registry_drift.name": "Project registry drift",
499
+ "doctor.check.project_registry_drift.ok": "Every knowledge/projects/<id>/ folder is registered in projects.json and no registered folder is empty.",
500
+ "doctor.check.project_registry_drift.message.unregistered": "{total} project registry drift issue(s): {breakdown}. e.g. projects/{projectId}/ in store '{storeAlias}' holds knowledge but is not registered in projects.json (unrouted). Run `fabric doctor --fix` to register it (rescue-before-delete \u2014 never deletes the folder).",
501
+ "doctor.check.project_registry_drift.message.orphan": "{total} project registry drift issue(s): {breakdown}. e.g. projects/{projectId}/ in store '{storeAlias}' exists on disk but is not registered in projects.json. Run `fabric doctor --fix` to register it (rescue \u2014 never deletes the folder).",
502
+ "doctor.check.project_registry_drift.message.empty": "{total} project registry drift issue(s): {breakdown}. e.g. registered project '{projectId}' in store '{storeAlias}' has an empty projects/{projectId}/ folder (zero entries). Run `fabric doctor --fix` to prune the empty folder.",
503
+ "doctor.check.project_registry_drift.remediation": "Run `fabric doctor --fix` to reconcile: orphan / unregistered-write folders are rescue-registered into projects.json (never deleted, even when non-empty); only genuinely-empty registered folders are pruned. A ghost registration (registered id with no folder) is legal (lazy creation) and needs no action.",
384
504
  "doctor.check.preexisting_root_files.name": "Preexisting root markdown",
385
505
  "doctor.check.preexisting_root_files.ok": "No CLAUDE.md or AGENTS.md detected at project root.",
386
506
  "doctor.check.preexisting_root_files.message": "{files} detected at project root. These root files are not auto-loaded by Fabric MCP.",
@@ -523,6 +643,11 @@ var enMessages = {
523
643
  "doctor.check.unbound_project.ok": "The bound write store carries a project coordinate (project_id + active_project), so project-scope recall/writes route correctly.",
524
644
  "doctor.check.unbound_project.message": "Store '{alias}' is bound as the write target but the project coordinate is incomplete (missing {missing}); project-scope recall/writes fall back to team scope.",
525
645
  "doctor.check.unbound_project.remediation": "Run `fabric doctor --fix` to backfill the project binding (mints project_id, registers the project in the store, sets active_project). Idempotent \u2014 a second run is a no-op.",
646
+ // write_route_target_unbound — static check that write_routes survived the single-team-slot migration.
647
+ "doctor.check.write_route_target_unbound.name": "Write route target",
648
+ "doctor.check.write_route_target_unbound.ok": "Every write_routes[*].store is present in required_stores; the scope\u2192store routing is statically consistent.",
649
+ "doctor.check.write_route_target_unbound.message": '{count} write_route(s) point at an unbound store ({routes}); fab_propose on those scopes will report "no write-target store resolved".',
650
+ "doctor.check.write_route_target_unbound.remediation": "Either \u2460 `fabric store bind <store>` to add the target to required_stores (under the single team slot rule this replaces the current one), or \u2461 edit `.fabric/fabric-config.json` to remove the stale write_route.",
526
651
  "doctor.check.skill_md_yaml_invalid.name": "Skill markdown YAML",
527
652
  "doctor.check.skill_md_yaml_invalid.ok": "All .claude/.codex SKILL.md frontmatter values parse as strict YAML.",
528
653
  "doctor.check.skill_md_yaml_invalid.message.singular": "{count} SKILL.md frontmatter value contains an unquoted ': ' that strict YAML parsers reject (Claude Code tolerates it; Codex CLI drops the skill at load). First: {detail}.",
@@ -550,13 +675,18 @@ var enMessages = {
550
675
  "cli.doctor.errors.invalid-history-mode": "Invalid --history mode '{input}'. Use archive | fix | all.",
551
676
  "doctor.history.header": "Doctor history (mode={mode}, last {sinceLabel}, {days} day(s))",
552
677
  "doctor.history.empty": "No doctor or archive activity within the --since={sinceLabel} window (mode={mode}).",
553
- "cli.install.description": "Install Fabric in the target project (scaffold .fabric/, bootstrap templates, MCP client wiring, git hooks).\n\nExamples:\n fabric install interactive install in the current project\n fabric install --yes accept defaults, skip the TTY wizard\n fabric install --dry-run preview the install plan without writing files",
678
+ "cli.install.description": "Install Fabric in the target project (scaffold .fabric/, bootstrap templates, MCP client wiring, git hooks)",
554
679
  "cli.install.args.target.description": "Target project path. Defaults to --target, then EXTERNAL_FIXTURE_PATH, then cwd.",
555
680
  "cli.install.args.debug.description": "Print target resolution details to stderr.",
556
681
  "cli.install.args.yes.description": "Accept the current install plan and run without the TTY wizard",
557
682
  "cli.install.args.dry-run.description": "Print the install plan without writing files or running follow-up stages",
558
683
  "cli.install.args.enable-embed.description": "Opt in to vector semantic search (sets embed_enabled + embed_model; prints fastembed install steps)",
559
684
  "cli.install.args.embed-model.description": "With --enable-embed: override the pinned embed model (default fast-bge-small-zh-v1.5)",
685
+ "cli.install.args.global.description": "Set up global Fabric (~/.fabric: uid + personal store + config)",
686
+ "cli.install.args.url.description": "Clone + mount a shared store remote. In a project install: also binds it to this project and sets it as the write target. With --global: mounts it machine-wide only.",
687
+ // TASK-004: --verbose expands the per-phase detail a collapsed re-install would
688
+ // fold, and prints the full per-client capability table.
689
+ "cli.install.args.verbose.description": "Show full detail: don't collapse an idempotent re-install into a health-check card, and print the per-client capability table",
560
690
  // rc.35 TASK-08 (P0-5/6): --force-skills-only.
561
691
  "cli.install.args.force-skills-only.description": "Skip bootstrap / MCP / hooks / settings; refresh ONLY the fabric Skill template copies (.claude/.codex/skills/*).",
562
692
  "cli.install.force-skills-only.banner": "Refreshing fabric Skill templates only",
@@ -585,7 +715,31 @@ var enMessages = {
585
715
  "cli.install.steps.bootstrap-claude": "Updated CLAUDE.md with @-import directives",
586
716
  "cli.install.steps.bootstrap-codex": "Updated AGENTS.md with fabric:bootstrap managed block",
587
717
  "cli.install.stages.mcp": "Configuring MCP clients...",
588
- "cli.install.stages.hooks": "Installing git hooks...",
718
+ "cli.install.stages.hooks": "Installing hooks & skills...",
719
+ "cli.install.preflight.error.no-home": "Cannot determine home directory for global root",
720
+ "cli.install.preflight.error.not-dir": "Global Fabric root is not a directory: {path}",
721
+ "cli.install.preflight.error.parent-not-dir": "Global Fabric root parent is not a directory: {path}",
722
+ "cli.install.preflight.error.not-writable": "{label} is not writable: {path} ({reason})",
723
+ "cli.install.preflight.error.git-required": "git is required for --url installs but was not available: {reason}",
724
+ "cli.install.preflight.label.target": "Target",
725
+ "cli.install.preflight.label.global-root": "Global Fabric root",
726
+ "cli.install.preflight.label.global-root-parent": "Global Fabric root parent",
727
+ "cli.install.guidance.more": "More: docs/surfaces.md explains when to use CLI vs Skill vs MCP.",
728
+ "cli.install.validate.passed": "Validation passed \u2713 (config / hook paths / events all ready)",
729
+ "cli.install.validate.failed": "Validation failed: {count} error(s)",
730
+ "cli.install.validate.failed-item": " - {error}",
731
+ "cli.install.hooks.uptodate": "hooks & skills already up to date ({count} items)",
732
+ "cli.install.hooks.installed": "installed skill\xD7{skills} + hook\xD7{hooks}",
733
+ "cli.install.mcp.configured": "MCP configured: {clients}",
734
+ "cli.install.mcp.none": "no MCP clients to configure",
735
+ "cli.install.scan.finding.framework": "Detected: {framework} project",
736
+ "cli.install.scan.finding.scale": "Scale: {files} files \xB7 {entries} entry points",
737
+ // flat-design: scan result folded into ONE human line (framework + scale); the
738
+ // version is suppressed when it resolved to "unknown"; falls back to plain when
739
+ // no framework was detected.
740
+ "cli.install.scan.summary.framework": "Detected {framework} project \xB7 {files} files \xB7 {entries} entry points",
741
+ "cli.install.scan.summary.plain": "Scan complete \xB7 {files} files \xB7 {entries} entry points",
742
+ "cli.install.rollback.feedback": "Rolled back {count} change(s); project left unchanged.",
589
743
  "cli.install.stages.skipped": "skipped",
590
744
  "cli.install.stages.completed": "completed",
591
745
  "cli.install.stages.failed": "failed",
@@ -595,6 +749,29 @@ var enMessages = {
595
749
  "cli.install.pipeline.title": "Fabric Install",
596
750
  "cli.install.pipeline.complete": "Fabric Install Complete",
597
751
  "cli.install.pipeline.running": "Running {count} stages...",
752
+ // TASK-002 (G1): summary-card completion + count words. Formerly hardcoded
753
+ // English in ConsoleOutputRenderer (Done! / succeeded / skipped / failed /
754
+ // "All steps completed successfully"); routed through t() + dual-locale tables
755
+ // so locale-parity.test.ts guards both en + zh-CN carry every key.
756
+ "cli.summary.done": "Done!",
757
+ "cli.summary.all-ok": "All steps completed successfully",
758
+ "cli.summary.n-failed": "{count} step(s) failed",
759
+ "cli.summary.all-resolved": "all resolved \xB7 {done} done / {skipped} skipped",
760
+ "cli.summary.count.succeeded": "succeeded",
761
+ "cli.summary.count.skipped": "skipped",
762
+ "cli.summary.count.failed": "failed",
763
+ // TASK-004: a first-ever install gets an onboarding-tone intro; a re-install
764
+ // keeps the terse "Running N stages" line. {count} = total stages.
765
+ "cli.install.pipeline.intro.firstRun": "Welcome to Fabric \u2014 this is your first install. I'll walk you through a one-time setup ({count} stages); later runs skip anything already in place.",
766
+ // TASK-004: the single collapsed health-check card title for a fully-idempotent
767
+ // re-install. {count} = total stages. Detail is behind --verbose.
768
+ "cli.install.healthcheck.title": "\u2713 Fabric is up to date \xB7 {count} stages ready \xB7 no changes",
769
+ // TASK-003 (G2 root a): the per-stage summary-detail status word now branches on
770
+ // r.changed (not installed.length) — a no-change re-ensure says "up to date"
771
+ // instead of misreporting "N installed". installed-count is used only when the
772
+ // stage actually changed something.
773
+ "cli.install.stage.uptodate": "up to date",
774
+ "cli.install.stage.installed-count": "{count} installed",
598
775
  "cli.install.pipeline.label.preflight": "Preflight check",
599
776
  "cli.install.pipeline.label.env": "Environment setup",
600
777
  "cli.install.pipeline.label.store": "Store configuration",
@@ -604,6 +781,14 @@ var enMessages = {
604
781
  "cli.install.pipeline.label.guidance": "Next steps",
605
782
  "cli.install.pipeline.desc.store": "Bind the current project's read/write store; refresh the resolved-bindings snapshot.",
606
783
  "cli.install.next-step": "{label} {message}",
784
+ // TASK-002 (G6): a single golden-action anchor that closes the summary card.
785
+ // The verbose capability table is gated behind --verbose; this one line is the
786
+ // honest "what to do next" footer. {action} = the concrete next command.
787
+ "cli.install.next-step.anchor": "Next \u2192 {action}",
788
+ // flat-design (G6): the real next action after install is restarting the client
789
+ // so its MCP server loads — that is the default anchor; the --reapply maintenance
790
+ // hint moves to --verbose.
791
+ "cli.install.next-step.restart": "restart any open Claude Code / Codex session to load Fabric (new sessions pick it up automatically).",
607
792
  "cli.install.reason-message": "{label} {message}",
608
793
  "cli.install.language.prompt": "Choose the Fabric language (used for both UI and knowledge; change later via `fabric config`):",
609
794
  "cli.install.language.option.zh-CN": "\u7B80\u4F53\u4E2D\u6587 (zh-CN)",
@@ -631,6 +816,10 @@ var enMessages = {
631
816
  "cli.install.wizard.stage.bootstrap": "Install bootstrap templates? [{defaultValue}]",
632
817
  "cli.install.wizard.stage.mcp": "Configure MCP clients? [{defaultValue}]",
633
818
  "cli.install.wizard.stage.hooks": "Install git hooks? [{defaultValue}]",
819
+ // flat-design-system Wave4 (TASK-004): short stage labels for the post-group ✓ receipt.
820
+ "cli.install.wizard.stage.bootstrap.short": "bootstrap templates",
821
+ "cli.install.wizard.stage.mcp.short": "MCP clients",
822
+ "cli.install.wizard.stage.hooks.short": "git hooks",
634
823
  "cli.install.wizard.mcp-install": "MCP server install scope (global/local) [{defaultValue}]",
635
824
  "cli.install.wizard.execute.confirm": "Execute this install plan now? [Y/n]",
636
825
  "cli.install.wizard.outro": "Install plan accepted. Running Fabric install...",
@@ -638,6 +827,10 @@ var enMessages = {
638
827
  "cli.install.wizard.invalid-select": "Invalid value. Use one of: {options}.",
639
828
  "cli.install.wizard.cancelled": "Fabric install cancelled before execution.",
640
829
  "cli.install.capabilities.title": "Client capability summary",
830
+ // C-006 (TASK-004): print a single one-line capability summary by default and
831
+ // let the summary card lead the closing impression; the full 4×6 per-client
832
+ // table only renders under --verbose. {count} = detected client count.
833
+ "cli.install.capabilities.summaryLine": "Detected {count} client(s) and configured their capabilities (run with --verbose for the per-client table).",
641
834
  // v2.0.0-rc.37 NEW-22: post-install restart banner. The MCP server is
642
835
  // spawned by the client; already-running Claude Code / Codex
643
836
  // sessions won't pick up the new mcp config until they restart.
@@ -659,6 +852,29 @@ var enMessages = {
659
852
  "cli.install.store.setup.prompt": "Set up a knowledge store for this project?",
660
853
  "cli.install.store.setup.bind-label": "bind mounted: {alias}",
661
854
  "cli.install.store.setup.already-bound": "already bound to this project: {aliases} \u2713",
855
+ // W2 dual-slot (TASK-002): personal slot + team slot status / prompt copy. The
856
+ // team slot is named by CATEGORY (team-class), and rows show the store's REAL
857
+ // alias — the copy MUST NOT imply the store has to be aliased literally `team`
858
+ // (KT-MOD-0001 naming-axis trap).
859
+ "cli.install.store.slot.personal.status": "Personal store (machine-wide): '{alias}' \u2713",
860
+ "cli.install.store.slot.personal.absent": "Personal store (machine-wide): not set up yet",
861
+ "cli.install.store.slot.personal.multi-none": "Personal store (machine-wide): {count} mounted, none active yet",
862
+ "cli.install.store.slot.personal.multi-prompt": "Pick this machine's active personal store:",
863
+ "cli.install.store.slot.personal.multi-active-label": "'{alias}' (current active)",
864
+ "cli.install.store.slot.personal.multi-switch-label": "switch to '{alias}'",
865
+ "cli.install.store.slot.personal.multi-new-label": "create a new local personal store",
866
+ "cli.install.store.slot.personal.multi-new-hint": "a fresh empty personal store, set as active",
867
+ "cli.install.store.slot.personal.new-alias": "alias for the new personal store:",
868
+ "cli.install.store.slot.personal.switched": "active personal store switched to '{alias}'",
869
+ "cli.install.store.slot.team.status": "Team store (team-class): '{alias}'{source} \u2713",
870
+ "cli.install.store.slot.team.empty": "Team store (team-class): none bound yet",
871
+ "cli.install.store.slot.team.prompt": "Choose the team knowledge store (team-class) for this project:",
872
+ "cli.install.store.slot.team.bound-label": "keep current: {alias}",
873
+ "cli.install.store.slot.team.switch-label": "switch to mounted: {alias}",
874
+ // flat-design store menu: "keep current" and "skip" are merged — when a team is
875
+ // bound the SKIP row renders as keep-label (no change), otherwise as plain skip.
876
+ "cli.install.store.slot.team.keep-label": "keep current: {alias} \xB7 no change",
877
+ "cli.install.store.slot.team.keep-hint": "{source}stay on this team store; leave the binding unchanged",
662
878
  "cli.install.store.skip-label": "skip",
663
879
  "cli.install.store.bind-mounted.skip-hint": "leave mounted stores unbound for now",
664
880
  "cli.install.store.project-coordinate": "Project coordinate in store '{store}':",
@@ -680,6 +896,9 @@ var enMessages = {
680
896
  "cli.install.store.unbound-note": "Note: The following stores are mounted but not bound to this project: {aliases}.",
681
897
  "cli.install.store.unbound-hint": " Run 'fabric store bind {first}' to bind one.",
682
898
  // C4: personal store clone-or-new.
899
+ // TASK-004: prefixed onto a first-install one-time prompt (language / personal
900
+ // store onboarding) so the user knows these questions only appear at first setup.
901
+ "cli.install.store.firstRunContext": "First-time setup \u2014 the following are one-time choices that appear only on first install:",
683
902
  "cli.install.store.personal.prompt": "No personal store on this machine yet. Create a fresh one, or clone your existing one from a remote?",
684
903
  "cli.install.store.personal.new-label": "create local (default)",
685
904
  "cli.install.store.personal.new-hint": "a fresh empty personal store",
@@ -728,38 +947,61 @@ var enMessages = {
728
947
  "cli.install.diff.state.present-canonical": "canonical",
729
948
  "cli.install.diff.state.drifted": "drifted",
730
949
  "cli.install.diff.state.user-modified": "user-modified",
731
- "cli.uninstall.description": "Uninstall Fabric from the target project. Global knowledge stores under ~/.fabric/stores/ are never deleted by project uninstall.\n\nExamples:\n fabric uninstall interactive uninstall in the current project\n fabric uninstall --yes accept defaults, skip the TTY wizard\n fabric uninstall --dry-run preview the uninstall plan without removing files",
950
+ "cli.uninstall.description": "Uninstall Fabric from the target project (global stores under ~/.fabric/stores/ are never deleted)",
732
951
  "cli.uninstall.args.target.description": "Target project path. Defaults to --target, then EXTERNAL_FIXTURE_PATH, then cwd.",
733
952
  "cli.uninstall.args.debug.description": "Print target resolution details to stderr.",
734
953
  "cli.uninstall.args.yes.description": "Accept the current uninstall plan and run without the TTY wizard.",
954
+ "cli.uninstall.args.verbose.description": "Show per-path detail counts for each stage instead of the condensed result line.",
955
+ "cli.uninstall.args.unbind-store.description": "Also unbind this project from its team store (clears the binding in .fabric/fabric-config.json). The global store under ~/.fabric/stores/ is never deleted.",
735
956
  "cli.uninstall.args.dry-run.description": "Print the uninstall plan without removing files or running follow-up stages.",
736
957
  "cli.uninstall.plan.title": "Fabric uninstall plan",
737
958
  // C3: mirror install's phase banner ("Fabric install 将按 N 个阶段执行").
738
959
  "cli.uninstall.plan.phase-banner": "Fabric uninstall runs in {total} phases",
739
960
  "cli.uninstall.plan.target": "Target: {target}",
740
- "cli.uninstall.plan.actions": "Plan: scaffold={scaffold} bootstrap={bootstrap} mcp={mcp}",
961
+ // flat-design-system Wave5 (TASK-004 G3): the plan preview speaks human action
962
+ // sentences, one per ENABLED stage, instead of the `key=yes/no` jargon line.
963
+ "cli.uninstall.plan.will-remove": "Will remove:",
964
+ "cli.uninstall.plan.will-keep": "Will keep:",
965
+ "cli.uninstall.plan.action.bootstrap": "client skills & hook scripts",
966
+ "cli.uninstall.plan.action.mcp": "MCP server registration",
967
+ "cli.uninstall.plan.action.scaffold": "project scaffold files",
968
+ "cli.uninstall.plan.action.store": "team store binding (this project)",
741
969
  "cli.uninstall.plan.detected": "Detected clients: {clients}",
742
970
  "cli.uninstall.plan.preserves": "Preserves:",
743
971
  "cli.uninstall.plan.preserves.stores": "global knowledge stores, never deleted by project uninstall",
744
972
  "cli.uninstall.plan.preview-title": "Fabric uninstall dry run",
745
- "cli.uninstall.plan.preview-result": "scaffold={scaffold} bootstrap={bootstrap} mcp={mcp}",
746
973
  "cli.uninstall.plan.scaffold-entries.title": "Scaffold entries:",
747
- "cli.uninstall.stages.scaffold": "Removing scaffold artifacts...",
748
- "cli.uninstall.stages.bootstrap": "Removing bootstrap (Skills + hooks)...",
749
- "cli.uninstall.stages.mcp": "Un-registering MCP clients...",
974
+ // W4: shared OutputRenderer pipeline — section bar title + per-stage labels,
975
+ // the symmetric inverse of cli.install.pipeline.*.
976
+ "cli.uninstall.pipeline.title": "Fabric Uninstall",
977
+ "cli.uninstall.pipeline.label.bootstrap": "Skills & hooks",
978
+ "cli.uninstall.pipeline.label.mcp": "MCP server",
979
+ "cli.uninstall.pipeline.label.store": "Store unbind",
980
+ "cli.uninstall.pipeline.label.scaffold": "Scaffold cleanup",
981
+ "cli.uninstall.pipeline.label.validate": "Verify cleared",
750
982
  "cli.uninstall.stages.completed": "completed",
751
983
  "cli.uninstall.stages.completed-with-errors": "completed with errors",
752
984
  "cli.uninstall.stages.failed": "failed",
985
+ "cli.uninstall.stages.failed-hint": "Check the error details above. Run with --debug for more information.",
986
+ "cli.uninstall.stages.uptodate": "nothing to remove ({count} already absent)",
987
+ "cli.uninstall.stages.summary": "removed={removed} skipped={skipped} errors={errors}",
988
+ "cli.uninstall.stages.removed-count": "{count} removed",
989
+ // flat-design-system Wave5 (TASK-006 G3): human result words for the summary
990
+ // card detail rows, symmetric with install's `{count} installed` / `up to date`.
991
+ "cli.uninstall.stage.cleaned-count": "{count} cleaned",
753
992
  "cli.uninstall.summary.title": "Uninstall summary",
754
993
  "cli.uninstall.summary.body": "removed={removed} skipped={skipped} errors={errors}",
994
+ "cli.uninstall.healthcheck.title": "\u2713 Fabric already absent \xB7 nothing to remove",
755
995
  "cli.uninstall.wizard.intro": "Fabric uninstall",
756
996
  "cli.uninstall.wizard.select.prompt": "What should be removed from {target}? (space to toggle / enter to confirm; global knowledge stores under ~/.fabric/stores/ are never deleted)",
757
997
  "cli.uninstall.wizard.select.scaffold.label": "Scaffold artifacts",
758
998
  "cli.uninstall.wizard.select.scaffold.hint": "Scaffolded files under .fabric/",
759
- "cli.uninstall.wizard.select.bootstrap.label": "Bootstrap (Skills + hooks)",
760
- "cli.uninstall.wizard.select.bootstrap.hint": "Per-client skills and git hooks",
999
+ "cli.uninstall.wizard.select.bootstrap.label": "Skills & hooks",
1000
+ "cli.uninstall.wizard.select.bootstrap.hint": "Per-client skills and hook scripts + config",
761
1001
  "cli.uninstall.wizard.select.mcp.label": "MCP client registration",
762
1002
  "cli.uninstall.wizard.select.mcp.hint": "Un-register the fabric MCP server from clients",
1003
+ "cli.uninstall.wizard.select.store.label": "Unbind team store (this project)",
1004
+ "cli.uninstall.wizard.select.store.hint": "Clears this project's store binding; the global store is never deleted",
763
1005
  "cli.uninstall.wizard.execute.confirm": "Execute this uninstall plan now? [Y/n]",
764
1006
  "cli.uninstall.wizard.outro": "Uninstall plan accepted. Running Fabric uninstall...",
765
1007
  "cli.uninstall.wizard.cancelled": "Fabric uninstall cancelled before execution.",
@@ -982,6 +1224,62 @@ var enMessages = {
982
1224
  "cli.whoami.stores-none": "stores: (none mounted)",
983
1225
  "cli.whoami.stores-label": "stores:",
984
1226
  "cli.shared.local-only": "(local-only)",
1227
+ // `fabric info` (flat-design) — identity / status / recall titles + field labels.
1228
+ "cli.info.field.uid": "uid",
1229
+ "cli.info.identity.title": "Fabric Identity",
1230
+ "cli.info.status.title": "Project Status",
1231
+ "cli.info.status.group.machine": "This machine",
1232
+ "cli.info.status.group.project": "Current project",
1233
+ "cli.info.status.field.project": "project",
1234
+ "cli.info.status.field.mounted": "mounted stores",
1235
+ "cli.info.status.field.bound": "bound stores",
1236
+ "cli.info.status.value.unset": "(unset)",
1237
+ "cli.info.status.value.not-project": "(not a Fabric project)",
1238
+ "cli.info.status.value.no-global": "(no global config)",
1239
+ "cli.info.recall.title": "Recall Engine",
1240
+ "cli.info.recall.summary.on": "semantic search on \u2014 details: fabric info --recall",
1241
+ "cli.info.recall.summary.off": "keyword mode \xB7 semantic search off \u2014 details: fabric info --recall",
1242
+ "cli.info.recall.mode.additive": "additive (keyword mode)",
1243
+ "cli.info.recall.mode.rrf": "rrf (keyword + semantic)",
1244
+ "cli.info.recall.reason.forced-additive": "fixed to keyword mode (additive) by config",
1245
+ "cli.info.recall.reason.auto-additive": "vector channel not ready \u2014 auto-falls back to keyword mode",
1246
+ "cli.info.recall.reason.auto-rrf": "vector channel ready \u2014 blending keyword + semantic (rrf)",
1247
+ "cli.info.recall.reason.rrf-ready": "fixed to rrf by config; vector channel ready",
1248
+ "cli.info.recall.reason.rrf-warn": "fixed to rrf by config, but the vector channel is not ready \u2014 single-channel rrf is worse than keyword mode",
1249
+ "cli.info.recall.install-hint": "install it to enable semantic search: npm i -g fastembed",
1250
+ "cli.info.recall.field.fusion-config": "fusion (config)",
1251
+ "cli.info.recall.field.fusion-effective": "fusion (in use)",
1252
+ "cli.info.recall.field.embed-enabled": "embed enabled",
1253
+ "cli.info.recall.field.embed-model": "embed model",
1254
+ "cli.info.recall.field.fastembed": "fastembed pkg",
1255
+ "cli.info.recall.field.cache-dir": "model cache",
1256
+ "cli.info.recall.field.model-cached": "model cached",
1257
+ "cli.info.recall.field.vector": "vector channel",
1258
+ "cli.info.recall.fastembed.yes": "resolvable",
1259
+ "cli.info.recall.fastembed.no": "not installed (optional dep)",
1260
+ "cli.info.recall.cached.no": "not cached \u2014 downloads on first recall (or `fabric info --recall --warm`)",
1261
+ "cli.info.recall.vector.ready": "READY",
1262
+ "cli.info.recall.vector.not-ready": "not ready \u2014 recall falls back to keyword mode (BM25 / additive)",
1263
+ "cli.info.recall.warm.ok": "embedder warm: model '{model}' loaded (vector dim {dim}), cached at {dir}",
1264
+ "cli.info.recall.warm.fail": "embedder unavailable \u2014 the optional 'fastembed' package is not resolvable or the model failed to load.\n Recall falls back to keyword mode (BM25 / additive). Install fastembed where the server resolves modules, then retry.",
1265
+ "cli.store.list.description": "List mounted knowledge stores",
1266
+ // Footer note appended to `fabric store --help` — explains where the advanced
1267
+ // (meta.hidden) operations went so the list-only listing isn't a dead end.
1268
+ "cli.store.help.folded-note": "Advanced operations (create / bind / switch-write / migrate, etc.) are folded \u2014 they're driven by fabric install and the fabric-store skill. Run `fabric store <command> --help` directly when you need one.",
1269
+ "cli.store.list.title": "Mounted stores",
1270
+ "cli.store.project.list.title": "Projects in store '{store}'",
1271
+ "cli.store.project.list.empty": "(no registered projects)",
1272
+ "cli.store.project.created": "registered project '{id}' in store '{store}'",
1273
+ "cli.store.migrate.title": "Knowledge scope migration",
1274
+ "cli.store.backfill.noop": "scope backfill: nothing to do ({count} already consistent)",
1275
+ "cli.store.backfill.summary": "scope backfill: {changed} updated, {unchanged} unchanged",
1276
+ "cli.store.backfill.scope-note": "{count} entries defaulted to semantic_scope: team. Demote project-specific ones with `fabric store migrate scope <store> --to project:<id> --id <id>`.",
1277
+ "cli.store.rescope.noop": "re-scope: nothing to do ({count} already at '{scope}')",
1278
+ "cli.store.rescope.summary": "re-scope \u2192 {scope}: {changed} updated, {unchanged} unchanged",
1279
+ "cli.store.rescope.refused": "{count} entries refused",
1280
+ "cli.store.reroot.noop": "reroot: nothing to relocate ({skipped} entries stay flat)",
1281
+ "cli.store.reroot.summary": "reroot: {moved} project entries relocated into knowledge/projects/<id>/",
1282
+ "cli.store.reroot.provenance-gap": "{count} moved via fs rename (untracked / non-git) \u2014 git blame history was NOT preserved for these",
985
1283
  "cli.store.none-mounted": "(no stores mounted)",
986
1284
  "cli.store.mounted": "mounted '{alias}' ({count} store(s) total)",
987
1285
  "cli.store.created": "created store '{alias}' ({uuid}) at {dir}",
@@ -990,15 +1288,34 @@ var enMessages = {
990
1288
  "cli.store.detached": "detached '{alias}' \u2014 on-disk store tree left intact (detach \u2260 delete)",
991
1289
  "cli.store.bound": "bound required store '{id}' ({count} required)",
992
1290
  "cli.store.switch-write": "active write store set to '{alias}' for this project",
1291
+ "cli.store.switch-personal": "active personal store set to '{alias}' for this machine",
993
1292
  "cli.store.routed": "write route: scope '{scope}' \u2192 store '{alias}'",
994
1293
  "cli.sync.deferred": "{count} store(s) offline \u2014 push deferred; re-run `fabric sync` when online",
995
1294
  "cli.sync.paused": "sync paused on a conflict \u2014 resolve it, then run `fabric sync --continue` (or `--abort`)",
1295
+ // flat-design (spec §0.4): `fabric sync` command-level title + per-store rows +
1296
+ // aggregate summary. State labels are shared between the per-store rows and the
1297
+ // summary count cells.
1298
+ "cli.sync.args.continue.description": "Resume after resolving a rebase conflict",
1299
+ "cli.sync.args.abort.description": "Abort the conflicted store's rebase",
1300
+ "cli.sync.title": "Sync stores",
1301
+ "cli.sync.summary.title": "Sync summary",
1302
+ "cli.sync.none": "no remote-backed stores to sync",
1303
+ "cli.sync.all-synced": "all stores synced",
1304
+ "cli.sync.state.synced": "synced",
1305
+ "cli.sync.state.offline": "offline",
1306
+ "cli.sync.state.conflict": "conflict",
1307
+ "cli.sync.state.aborted": "aborted",
1308
+ "cli.sync.state.pending": "pending",
996
1309
  "cli.metrics.invalid-since": '--since: invalid duration "{raw}" (expected e.g. 24h, 7d, 30m)',
997
1310
  "cli.metrics.window": "Fabric metrics \u2014 window: {window}",
998
1311
  "cli.metrics.window-all-time": "all-time",
999
1312
  "cli.metrics.rows-range": " rows: {count} ({start} \u2192 {end})",
1000
1313
  "cli.metrics.rows": " rows: {count}",
1001
1314
  "cli.metrics.no-activity": " (no counter activity in window \u2014 server may be idle or just started)",
1315
+ "cli.metrics.col.counter": "counter",
1316
+ "cli.metrics.col.total": "total",
1317
+ "cli.metrics.col.entry": "entry",
1318
+ "cli.metrics.section.perEntry": "Top per-entry consumed (knowledge_consumed:<id>)",
1002
1319
  // W3-09 (ISS-035): forensic project scan progress (stderr, TTY-only).
1003
1320
  "cli.install.scanning": "scanning project for client/framework signals\u2026",
1004
1321
  "cli.install.scan-complete": " project scan complete",
@@ -1018,7 +1335,7 @@ var enMessages = {
1018
1335
 
1019
1336
  // src/i18n/locales/zh-CN.ts
1020
1337
  var zhCNMessages = {
1021
- "cli.main.description": "Fabric CLI \u2014 \u81EA\u52A8\u628A\u672C\u9879\u76EE\u7684\u51B3\u7B56 / \u8E29\u5751 / \u89C4\u8303\u5582\u7ED9\u4F60\u7684 AI \u52A9\u624B\uFF0C\u8BA9\u5B83\u4E0D\u5FC5\u6BCF\u6B21\u4F1A\u8BDD\u91CD\u65B0\u5B66\u3002\n\n\u4E09\u6B65\u5FC3\u667A\u6A21\u578B\uFF1A\n \u88C5 (install) - fabric install \u4E00\u952E\u5B8C\u6210\u9879\u76EE\u521D\u59CB\u5316\n \u914D (config) - fabric config \u6253\u5F00\u4EA4\u4E92\u5F0F\u914D\u7F6E\u9762\u677F\n \u7EF4\u62A4 (run) - fabric doctor \u8FD0\u884C\u76EE\u6807\u6001\u8BCA\u65AD\n fabric sync \u540C\u6B65\u5DF2\u6302\u8F7D\u7684\u77E5\u8BC6 store\n\n\u793A\u4F8B\uFF1A\n fabric install \u5728\u5F53\u524D\u9879\u76EE\u4E2D\u5B89\u88C5 Fabric\n fabric config \u6253\u5F00\u4EA4\u4E92\u5F0F\u914D\u7F6E\u9762\u677F\n fabric doctor --fix \u4FEE\u590D Fabric \u6D3E\u751F\u72B6\u6001\n fabric doctor --fix-knowledge \u4FEE\u590D\u77E5\u8BC6\u6761\u76EE\u72B6\u6001\n fabric sync pull/rebase \u5E76 push \u5DF2\u6302\u8F7D store\n fabric uninstall --dry-run \u9884\u89C8\u5378\u8F7D\uFF0C\u4E0D\u5220\u9664\u6587\u4EF6",
1338
+ "cli.main.description": "Fabric CLI \u2014 \u81EA\u52A8\u628A\u672C\u9879\u76EE\u7684\u51B3\u7B56 / \u8E29\u5751 / \u89C4\u8303\u5582\u7ED9\u4F60\u7684 AI \u52A9\u624B\uFF0C\u8BA9\u5B83\u4E0D\u5FC5\u6BCF\u6B21\u4F1A\u8BDD\u91CD\u65B0\u5B66\u3002\u9996\u6B21\u4F7F\u7528?\u8FD0\u884C: fabric install",
1022
1339
  "cli.shared.created": "\u5DF2\u521B\u5EFA",
1023
1340
  "cli.shared.skipped": "\u5DF2\u8DF3\u8FC7",
1024
1341
  "cli.shared.next": "\u4E0B\u4E00\u6B65",
@@ -1032,22 +1349,73 @@ var zhCNMessages = {
1032
1349
  "cli.shared.none": "\u65E0",
1033
1350
  "cli.shared.loading": "\u52A0\u8F7D\u4E2D",
1034
1351
  "cli.shared.refresh": "\u5237\u65B0",
1352
+ // flat-design-system Wave4 (TASK-004): clack 控件(select/multiselect/confirm/text)
1353
+ // 落定后打印的平铺无沟槽 ✓/x 回执行。控件保持原生(C-006),回执是独立的一行。
1354
+ "cli.prompt.receipt.selected": "\u5DF2\u9009",
1355
+ "cli.prompt.receipt.set": "\u5DF2\u8BBE\u7F6E",
1356
+ "cli.prompt.receipt.cancelled": "\u5DF2\u53D6\u6D88",
1035
1357
  "cli.shared.target-invalid": "\u76EE\u6807\u5FC5\u987B\u662F\u5DF2\u5B58\u5728\u7684\u76EE\u5F55\uFF1A{target}",
1036
1358
  "cli.shared.target-invalid.action-hint": "\u8BF7\u9009\u62E9\u4E00\u4E2A\u5DF2\u5B58\u5728\u7684\u9879\u76EE\u76EE\u5F55\uFF0C\u6216\u5148\u521B\u5EFA\u8BE5\u76EE\u5F55\u540E\u518D\u91CD\u65B0\u8FD0\u884C\u547D\u4EE4\u3002",
1037
1359
  "cli.shared.template-not-found": "\u672A\u627E\u5230\u6A21\u677F\uFF1A{path}",
1038
1360
  "cli.shared.invalid-host-empty": "\u65E0\u6548 host\uFF1A<empty>",
1039
1361
  "cli.shared.invalid-port": "\u65E0\u6548\u7AEF\u53E3\uFF1A{value}",
1040
1362
  "cli.shared.error": "\u9519\u8BEF",
1041
- // EPIC-011 / W3-F: 分组帮助显示 i18n (Knowledge/Project/Maintain)
1042
- "cli.help.group.knowledge.store": "\u7BA1\u7406\u77E5\u8BC6 store (\u8BE6\u89C1: fabric store --help)",
1043
- "cli.help.group.knowledge.sync": "\u4E0E\u8FDC\u7A0B store \u540C\u6B65\u56E2\u961F\u77E5\u8BC6",
1044
- "cli.help.group.project.install": "\u5728\u5F53\u524D\u4ED3\u5E93\u521D\u59CB\u5316 Fabric",
1045
- "cli.help.group.project.config": "\u914D\u7F6E Fabric \u8BBE\u7F6E",
1046
- "cli.help.group.project.info": "\u663E\u793A\u9879\u76EE\u72B6\u6001",
1047
- "cli.help.group.project.inspect": "\u663E\u793A\u672C\u4F1A\u8BDD SessionStart \u6CE8\u5165\u4E86\u4EC0\u4E48",
1048
- "cli.help.group.maintain.doctor": "\u68C0\u67E5 Fabric \u5065\u5EB7\u72B6\u6001\u5E76\u4FEE\u590D\u95EE\u9898",
1049
- "cli.help.group.maintain.audit": "\u77E5\u8BC6\u4E0E\u9065\u6D4B\u5BA1\u8BA1 (cite/conflicts/history/metrics)",
1050
- "cli.config.description": "\u6253\u5F00 Fabric \u4EA4\u4E92\u5F0F\u914D\u7F6E\u9762\u677F\uFF08\u8BED\u8A00\u3001\u77E5\u8BC6\u5C42\u3001\u5BA1\u8BA1\u6A21\u5F0F\u3001\u63D0\u793A\u7A97\u53E3\u3001MCP \u5BA2\u6237\u7AEF\u914D\u7F6E\u7B49\uFF09\u3002\n\n\u793A\u4F8B\uFF1A\n fabric config \u6253\u5F00\u4EA4\u4E92\u5F0F\u9762\u677F\n fabric config --target /path \u7F16\u8F91\u6307\u5B9A\u9879\u76EE\u7684\u914D\u7F6E",
1363
+ // 顶层命令摘要(每条一句精简单行 —— citty 在根 `fabric --help` 的 COMMANDS
1364
+ // 表与各命令自身 `--help` 头部都用它,必须保持单行;退掉自建分组帮助、改走
1365
+ // citty 渲染器后,原先的多行示例块已移除)
1366
+ "cli.store.description": "\u7BA1\u7406\u5DF2\u6302\u8F7D\u7684\u77E5\u8BC6 store(\u5EFA\u5E93\u8D70 fabric install)",
1367
+ "cli.sync.description": "\u540C\u6B65\u5DF2\u6302\u8F7D\u7684\u77E5\u8BC6 store(pull --rebase + push)",
1368
+ "cli.info.description": "\u663E\u793A Fabric \u8EAB\u4EFD\u3001\u9879\u76EE\u72B6\u6001\u4E0E\u53EC\u56DE\u5065\u5EB7",
1369
+ "cli.inspect.description": "\u663E\u793A Fabric \u5728 SessionStart \u6CE8\u5165\u4E86\u4EC0\u4E48",
1370
+ // `fabric inspect` 参数说明 + --explain 溯源覆盖层 + 错误。
1371
+ "cli.inspect.arg.render": "\u663E\u793A\u54EA\u4E2A sink:'human'(systemMessage)\u6216 'ai'(additionalContext)\u3002\u9ED8\u8BA4\u4E24\u4E2A\u90FD\u663E\u793A\u3002",
1372
+ "cli.inspect.arg.explain": "\u8FFD\u52A0\u9010\u6761\u6765\u6E90\u6EAF\u6E90\u6BB5(id \xB7 type \xB7 maturity \xB7 scope \xB7 \u6D6E\u73B0\u539F\u56E0)\u3002",
1373
+ "cli.inspect.arg.target": "\u8986\u76D6\u9879\u76EE\u6839\u76EE\u5F55(\u9ED8\u8BA4\u53D6 cwd / dev \u6A21\u5F0F\u89E3\u6790)\u3002",
1374
+ "cli.inspect.explain.title": "explain \xB7 \u6765\u6E90\u6EAF\u6E90(\u975E\u6CE8\u5165\u5185\u5BB9)",
1375
+ "cli.inspect.explain.always": "\u5E38\u9A7B\u751F\u6548 \xB7 \u6B63\u6587\u5DF2\u6CE8\u5165",
1376
+ "cli.inspect.explain.reference": "\u53C2\u8003\u5019\u9009 \xB7 \u6309\u9700\u9605\u8BFB",
1377
+ "cli.inspect.explain.census": "\u5168\u96C6\u666E\u67E5",
1378
+ "cli.inspect.explain.census-total": "\u603B\u8BA1 {total}",
1379
+ "cli.inspect.error": "inspect \u5931\u8D25:{message}",
1380
+ "cli.audit.description": "\u77E5\u8BC6\u4E0E\u9065\u6D4B\u5BA1\u8BA1 (cite/conflicts/history/metrics)",
1381
+ // `fabric audit cite` — recall 覆盖率为 0 的自诊断提示。
1382
+ "cli.audit.cite.recall-mismatch-hint": "recall \u8986\u76D6\u7387\u4E3A 0,\u4F46\u672C\u7A97\u53E3\u6709 {recalls} \u6B21 recall(\u5206\u5E03\u5728 {sessions} \u4E2A\u4F1A\u8BDD)\u2014\u2014 \u6CA1\u6709\u4E00\u4E2A\u4E0E\u7F16\u8F91\u5171\u4EAB\u4F1A\u8BDD\u3002\u591A\u534A\u662F fab_recall \u8C03\u7528\u65B9\u4F20\u4E86\u975E\u5BA2\u6237\u7AEF session_id(\u5173\u8054\u6309\u4F1A\u8BDD\u9694\u79BB)\u3002\u89C1 AGENTS.md:fab_recall \u5FC5\u987B\u4F20\u5165\u771F\u5B9E\u5BA2\u6237\u7AEF session_id\u3002",
1383
+ "cli.audit.cite.recall-none-hint": "recall \u8986\u76D6\u7387\u4E3A 0 \u2014\u2014 \u8FD9\u4E9B\u7F16\u8F91\u524D\u6CA1\u6709\u540C\u4F1A\u8BDD\u7684 fab_recall\u3002\u6539\u524D\u5148 recall,\u4E14\u4F20\u5165\u771F\u5B9E\u5BA2\u6237\u7AEF session_id(\u5173\u8054\u6309\u4F1A\u8BDD\u9694\u79BB)\u3002\u89C1 AGENTS.md\u3002",
1384
+ // `fabric audit --help` — 过滤式帮助(i18n 子命令清单)。
1385
+ "cli.audit.help.tagline": "\u77E5\u8BC6\u4E0E\u9065\u6D4B\u5BA1\u8BA1\u9762(\u53EA\u8BFB)",
1386
+ "cli.audit.help.sub.cite": "Cite \u653F\u7B56\u9075\u5FAA\u5EA6\u62A5\u544A",
1387
+ "cli.audit.help.sub.conflicts": "\u77E5\u8BC6\u51B2\u7A81\u4F53\u68C0",
1388
+ "cli.audit.help.sub.history": "\u7EF4\u62A4\u5386\u53F2\u6C47\u603B(archive | fix | all)",
1389
+ "cli.audit.help.sub.descriptions": "\u56DE\u586B\u63CF\u8FF0\u7EA7 frontmatter \u5B57\u6BB5",
1390
+ "cli.audit.help.sub.retired": "\u626B\u63CF agent \u9762\u4E2D\u7684\u5E9F\u5F03\u5DE5\u5177/\u5B57\u6BB5\u5F15\u7528",
1391
+ "cli.audit.help.sub.why": "\u8BCA\u65AD\u67D0\u6761\u77E5\u8BC6\u4E3A\u4F55\u6CA1\u6D6E\u73B0",
1392
+ "cli.audit.help.example.cite": "\u8FD1 7 \u5929\u7684 cite \u8986\u76D6\u7387",
1393
+ "cli.audit.help.example.conflicts": "\u626B\u63CF\u77DB\u76FE / \u91CD\u590D\u6761\u76EE",
1394
+ "cli.audit.help.footer": "\u8FD0\u884C `fabric audit <subcommand> --help` \u67E5\u770B\u5404\u5B50\u547D\u4EE4\u53C2\u6570\u3002",
1395
+ // `fabric audit retired` — 平铺渲染文案。
1396
+ "cli.audit.retired.skipped": "\u5DF2\u8DF3\u8FC7 retired \u5F15\u7528\u626B\u63CF \u2014\u2014 \u672A\u53D1\u73B0 agent \u6D88\u8D39\u9762\u3002",
1397
+ "cli.audit.retired.clean": "\u65E0 retired \u5F15\u7528 \u2014\u2014 \u5DF2\u626B\u63CF {count} \u4E2A agent \u9762\u3002",
1398
+ "cli.audit.retired.found": "\u5728 {files} \u4E2A\u6587\u4EF6\u4E2D\u53D1\u73B0 {hits} \u5904 retired \u5F15\u7528",
1399
+ "cli.audit.retired.removed": "\uFF08\u5DF2\u79FB\u9664\uFF09",
1400
+ // `fabric audit why-not-surfaced <id>` — 三轴诊断(store / scope / timing)。
1401
+ "cli.audit.why.not-found": "\u672A\u5728\u4EFB\u4F55\u5DF2\u6302\u8F7D store \u4E2D\u627E\u5230 '{id}'\u3002\u8BF7\u6838\u5BF9 id(\u53EF\u8BD5 `fabric store list`)\u3002",
1402
+ "cli.audit.why.store-unbound": "'{id}' \u4F4D\u4E8E store '{store}',\u4F46\u8BE5 store \u672A\u7ED1\u5B9A\u5230\u672C\u9879\u76EE\u3002",
1403
+ "cli.audit.why.store-unbound.hint": "\u7ED1\u5B9A\u5B83:fabric store bind {store}",
1404
+ "cli.audit.why.project-mismatch": "'{id}' \u7684 scope \u662F '{scope}',\u4F46\u672C\u4ED3\u5E93\u7ED1\u5B9A\u7684\u662F 'project:{project}'\u3002",
1405
+ "cli.audit.why.project-mismatch.hint": "\u5B83\u53EA\u5728\u7ED1\u5B9A\u4E86 '{scope}' \u7684\u4ED3\u5E93\u4E2D\u6D6E\u73B0(semantic_scope \u8F74)\u3002",
1406
+ "cli.audit.why.narrow-timing": "'{id}' \u662F relevance_scope=narrow \u2014\u2014 \u4EC5\u5728\u4F60\u7F16\u8F91\u5339\u914D\u6587\u4EF6\u65F6\u7531 PreToolUse \u63D0\u793A\u6D6E\u73B0,\u4E0D\u5728 SessionStart\u3002",
1407
+ "cli.audit.why.narrow-timing.hint": "broad \u6761\u76EE\u662F\u5E38\u9A7B\u810A\u67F1;narrow \u4EC5\u5728\u7F16\u8F91\u65F6\u6D6E\u73B0(timing \u8F74)\u3002",
1408
+ "cli.audit.why.should-surface": "'{id}' \u5E94\u5F53\u6B63\u5728\u6D6E\u73B0 \u2014\u2014 store '{store}' \u5DF2\u7ED1\u5B9A\u3001scope \u5339\u914D\u3001relevance_scope=broad\u3002",
1409
+ "cli.audit.why.should-surface.hint": "\u82E5\u4ECD\u6CA1\u6D6E\u73B0,\u53EF\u80FD\u662F SessionStart \u5FEB\u7167\u8FC7\u671F:\u5F00\u4E2A\u65B0\u4F1A\u8BDD\u6216\u91CD\u8DD1 `fabric install`\u3002",
1410
+ // `fabric info --help` —— flag 与 scope 子命令描述。
1411
+ "cli.info.args.global.description": "\u663E\u793A\u5168\u5C40\u8EAB\u4EFD(whoami)\u800C\u975E\u9879\u76EE\u72B6\u6001",
1412
+ "cli.info.args.recall.description": "\u663E\u793A\u53EC\u56DE\u5F15\u64CE\u8BE6\u60C5(\u878D\u5408\u7B56\u7565 + \u5411\u91CF\u5D4C\u5165\u72B6\u6001)",
1413
+ "cli.info.args.warm.description": "\u914D\u5408 --recall:\u7ACB\u5373\u52A0\u8F7D embedder(\u9996\u6B21\u4F1A\u628A\u6A21\u578B\u4E0B\u8F7D\u5230 ~/.fabric/cache/embed)",
1414
+ "cli.info.args.json.description": "\u8F93\u51FA\u673A\u5668\u53EF\u8BFB\u7684 JSON \u800C\u975E\u6587\u672C",
1415
+ "cli.info.scope.description": "(\u8FDB\u9636/skill)\u628A\u4E00\u4E2A scope \u5750\u6807\u89E3\u6790\u6210 read-set + \u5199\u5165\u76EE\u6807\u7684 JSON",
1416
+ "cli.info.scope.args.coord.description": "Scope \u5750\u6807(\u5982 team\u3001project:x\u3001personal)",
1417
+ "cli.info.scope.args.json.description": "\u8F93\u51FA\u673A\u5668\u53EF\u8BFB\u7684 JSON(scope \u59CB\u7EC8\u8F93\u51FA JSON)",
1418
+ "cli.config.description": "\u6253\u5F00 Fabric \u4EA4\u4E92\u5F0F\u914D\u7F6E\u9762\u677F\uFF08\u8BED\u8A00\u3001\u77E5\u8BC6\u5C42\u3001\u5BA1\u8BA1\u6A21\u5F0F\u3001MCP \u5BA2\u6237\u7AEF\u914D\u7F6E\u7B49\uFF09",
1051
1419
  "cli.config.args.target.description": "\u76EE\u6807\u9879\u76EE\u76EE\u5F55\uFF08\u9ED8\u8BA4\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF09\u3002",
1052
1420
  "cli.config.clients.claude": "Claude Code CLI",
1053
1421
  "cli.config.install.description": "\u5C06 Fabric MCP \u670D\u52A1\u7AEF\u6761\u76EE\u5B89\u88C5\u5230\u68C0\u6D4B\u5230\u7684\u5BA2\u6237\u7AEF\u914D\u7F6E\u4E2D\u3002",
@@ -1063,6 +1431,9 @@ var zhCNMessages = {
1063
1431
  // 由 packages/cli/src/commands/config.ts(菜单循环 + 字段编辑)以及
1064
1432
  // getPanelFields() 的 label_i18n_key 引用消费。
1065
1433
  "cli.config.intro": "Fabric \u914D\u7F6E",
1434
+ // flat-design-system Wave5 (TASK-005): clack 编辑菜单前那块平铺键值面板的
1435
+ // B-横线标题。
1436
+ "cli.config.panel.title": "\u5F53\u524D\u914D\u7F6E",
1066
1437
  "cli.config.outro": "\u914D\u7F6E\u5DF2\u4FDD\u5B58\u3002",
1067
1438
  "cli.config.outro-no-changes": "\u672A\u505A\u4EFB\u4F55\u4FEE\u6539\u3002",
1068
1439
  "cli.config.cancel": "\u5DF2\u53D6\u6D88\u3002",
@@ -1073,8 +1444,17 @@ var zhCNMessages = {
1073
1444
  "cli.config.value.default-marker": "\uFF08\u9ED8\u8BA4\uFF09",
1074
1445
  "cli.config.prompt.select": "\u4E3A {key} \u9009\u62E9\u65B0\u503C\uFF08\u5F53\u524D\uFF1A{current}\uFF09\uFF1A",
1075
1446
  "cli.config.prompt.text": "\u4E3A {key} \u8F93\u5165\u65B0\u503C\uFF08\u5F53\u524D\uFF1A{current}\uFF09\uFF1A",
1076
- "cli.config.write.success": "\u5DF2\u4FDD\u5B58 {key} = {value}",
1447
+ "cli.config.write.success": "{key} = {value}",
1448
+ "cli.config.panel.edited": "\u672C\u6B21\u5DF2\u6539\uFF08{count} \u9879\uFF09\uFF1A{keys}",
1077
1449
  "cli.config.write.failure": "\u5199\u5165 fabric-config.json \u5931\u8D25\uFF1A{message}",
1450
+ "cli.config.slot.errors.missing": "\u7F3A\u5C11\u5FC5\u586B\u7684 <slot> \u53C2\u6570\u3002\u53EF\u7528\u69FD\u4F4D\uFF1A{slots}\u3002",
1451
+ "cli.config.slot.errors.unknown": '\u672A\u77E5\u69FD\u4F4D "{slot}"\u3002\u53EF\u7528\u69FD\u4F4D\uFF1A{slots}\u3002',
1452
+ "cli.config.slot.dismiss.already": '\u69FD\u4F4D "{slot}" \u5DF2\u5FFD\u7565\uFF0C\u65E0\u9700\u64CD\u4F5C\u3002',
1453
+ "cli.config.slot.dismiss.done": '\u5DF2\u5FFD\u7565 onboard \u69FD\u4F4D "{slot}"\u3002\u8FD0\u884C `fabric config onboard-reset {slot}` \u53EF\u91CD\u65B0\u5F00\u542F\u3002',
1454
+ "cli.config.slot.dismiss.failed": "dismiss-slot \u5931\u8D25\uFF1A{message}",
1455
+ "cli.config.slot.reset.not-opted": '\u69FD\u4F4D "{slot}" \u672A\u88AB\u5FFD\u7565\uFF0C\u65E0\u9700\u64CD\u4F5C\u3002',
1456
+ "cli.config.slot.reset.done": '\u5DF2\u91CD\u7F6E onboard \u69FD\u4F4D "{slot}"\uFF1B\u5B83\u5C06\u5728 `fabric onboard-coverage` \u4E2D\u91CD\u65B0\u663E\u793A\u4E3A\u7F3A\u5931\u3002',
1457
+ "cli.config.slot.reset.failed": "onboard-reset \u5931\u8D25\uFF1A{message}",
1078
1458
  "cli.config.errors.uninit-workspace.message": "\u5DE5\u4F5C\u533A\u5C1A\u672A\u521D\u59CB\u5316\u3002\u8BF7\u5148\u8FD0\u884C `fabric install`\u3002",
1079
1459
  "cli.config.errors.invalid-int": "\u5FC5\u987B\u662F\u6B63\u6574\u6570\u3002",
1080
1460
  "cli.config.errors.unknown-field": "\u672A\u77E5\u5B57\u6BB5\u9009\u62E9 \u2014 \u5DF2\u8DF3\u8FC7\u3002",
@@ -1105,12 +1485,52 @@ var zhCNMessages = {
1105
1485
  "cli.config.fields.nudge_mode.label": "\u63D0\u793A\u6863\u4F4D",
1106
1486
  "cli.config.fields.nudge_mode.description": "\u4EBA\u7C7B\u53EF\u89C1 nudge \u7684\u603B\u6863\u4F4D\uFF08silent \u9759\u9ED8 / minimal \u7CBE\u7B80 / normal \u6B63\u5E38 / verbose \u8BE6\u5C3D\uFF09\uFF1B\u4EC5\u63A7\u4EBA\u7C7B\u63D0\u793A\u901A\u9053\uFF0C\u4E0D\u5F71\u54CD\u6CE8\u5165\u7ED9 AI \u7684\u77E5\u8BC6\u3002",
1107
1487
  "cli.config.fields.embed_enabled.label": "\u5411\u91CF\u8BED\u4E49\u68C0\u7D22",
1108
- "cli.config.fields.embed_enabled.description": "\u662F\u5426\u542F\u7528\u5411\u91CF\u8BED\u4E49\u68C0\u7D22\uFF08true / false\uFF09\u3002\u6CE8\u610F\uFF1A\u5F00\u542F\u8FD8\u9700 `fabric install --enable-embed` \u5B8C\u6210\u4E3B\u673A\u4FA7\u5B89\u88C5\uFF08fastembed + \u6A21\u578B\u7F13\u5B58\uFF09\uFF0C\u4EC5\u5728\u6B64\u7F6E true \u4E0D\u4F1A\u81EA\u52A8\u751F\u6548\u3002",
1109
- "cli.doctor.description": "\u8FD0\u884C Fabric \u76EE\u6807\u6001\u8BCA\u65AD\uFF08meta \u540C\u6B65\u3001\u77E5\u8BC6\u7D22\u5F15\u3001bootstrap\u3001events ledger\u3001human-lock \u6F02\u79FB\uFF09\u3002\n\n\u793A\u4F8B\uFF1A\n fabric doctor \u53EA\u8BFB\u8BCA\u65AD\u62A5\u544A\n fabric doctor --fix \u4FEE\u590D\u6D3E\u751F\u72B6\u6001\uFF08meta + \u7D22\u5F15\uFF09\n fabric doctor --fix-knowledge \u5E94\u7528\u77E5\u8BC6\u5E93 lint \u53D8\u66F4\uFF08\u8BA1\u6570\u5668 / \u5F52\u6863 / \u7F13\u5B58\uFF09\n fabric doctor --json \u673A\u5668\u53EF\u8BFB\u8F93\u51FA",
1488
+ "cli.config.fields.embed_enabled.description": "\u662F\u5426\u542F\u7528\u5411\u91CF\u8BED\u4E49\u68C0\u7D22\uFF08true / false\uFF09\u3002\u6CE8\u610F\uFF1Atrue \u53EA\u662F\u610F\u56FE\u5F00\u5173\u2014\u2014\u771F\u6B63\u751F\u6548\u8FD8\u9700\u8FD0\u884C\u4E2D\u7684 server \u80FD\u89E3\u6790\u5230 fastembed \u5305\u3001\u4E14\u6A21\u578B\u5DF2\u4E0B\u8F7D\uFF08\u9996\u6B21\u53EC\u56DE\u65F6\u81EA\u52A8\u4E0B\u5230 ~/.fabric/cache/embed\uFF09\u3002\u7528 `fabric info recall` \u67E5\u5B9E\u9645\u72B6\u6001\u3002",
1489
+ "cli.config.fields.fusion.label": "\u53EC\u56DE\u878D\u5408\u7B56\u7565",
1490
+ "cli.config.fields.fusion.description": "\u591A\u4FE1\u53F7\u5408\u6210\u603B\u5206\u7684\u7B97\u6CD5\uFF1Aadditive \u52A0\u6743\u6C42\u548C\uFF08BM25 \u4E3B\u5BFC\uFF0C\u5411\u91CF\u6743\u91CD\u5C0F\uFF09/ rrf \u5012\u6570\u6392\u540D\u878D\u5408\uFF08BM25 \u4E0E\u5411\u91CF\u5E73\u8D77\u5E73\u5750\uFF0C\u8BED\u4E49\u624D\u771F\u6B63\u751F\u6548\uFF09/ auto \u81EA\u9002\u5E94\uFF08\u9ED8\u8BA4\uFF1A\u5411\u91CF\u5728\u51FA\u5206\u65F6\u7528 rrf\uFF0C\u5426\u5219\u56DE\u843D additive\u2014\u2014\u907F\u514D\u65E0\u5411\u91CF\u65F6 rrf \u9000\u5316\u53CD\u800C\u66F4\u5DEE\uFF09\u3002",
1491
+ "cli.doctor.description": "\u8FD0\u884C Fabric \u76EE\u6807\u6001\u8BCA\u65AD\uFF08meta \u540C\u6B65\u3001\u77E5\u8BC6\u7D22\u5F15\u3001bootstrap\u3001events ledger\u3001human-lock \u6F02\u79FB\uFF09",
1110
1492
  "doctor.section.fixable": "\u53EF\u4FEE\u590D\u9519\u8BEF\uFF1A",
1111
1493
  "doctor.section.manual": "\u9700\u624B\u52A8\u4FEE\u590D\uFF1A",
1112
1494
  "doctor.section.warnings": "\u8B66\u544A\uFF1A",
1113
1495
  "doctor.section.fix-knowledge-mutations": "Fix-knowledge \u53D8\u66F4\uFF1A",
1496
+ // flat-design follow-up: doctor 剩余的 UI-shell 文案(TL;DR 头、--fix 变更计划、
1497
+ // 过滤版 --help)从硬编码英文搬进 i18n,让整个 `fabric doctor` 输出跟随机器语言。
1498
+ // USAGE/OPTIONS/EXAMPLES 标签保持英文,与其它命令 --help 的 citty renderUsage 对齐。
1499
+ "doctor.digest.todo": "\u5F85\u5904\u7406 ({count})",
1500
+ "doctor.digest.clean": "\u5168\u90E8 {count} \u9879\u68C0\u67E5\u901A\u8FC7 \u2014\u2014 \u65E0\u9700\u5904\u7406",
1501
+ "doctor.digest.summary": "{todo} \u9879\u5F85\u5904\u7406 \xB7 {ok} \u9879\u901A\u8FC7 \xB7 \u8D21\u732E\u8005\u8BCA\u65AD\u89C1 --verbose",
1502
+ "doctor.digest.more-verbose": "\u53E6\u6709 {count} \u9879\u8D21\u732E\u8005\u8BCA\u65AD \u2014\u2014 \u89C1 --verbose",
1503
+ // store 诊断(多 store 健康,即 `● 存储健康` 分组)—— 与 doctor.check.* 对齐 i18n;
1504
+ // 文案通过插值带上 store alias / 计数。
1505
+ "doctor.store.no-global-config": "\u65E0\u5168\u5C40 Fabric \u914D\u7F6E \u2014\u2014 \u8FD0\u884C `fabric install --global <url>`",
1506
+ "doctor.store.missing-required": "\u5FC5\u9700 store '{id}' \u672A\u6302\u8F7D;\u8FD0\u884C `fabric store mount`",
1507
+ "doctor.store.unbound": "store '{alias}' \u5DF2\u6302\u8F7D\u4F46\u672A\u7ED1\u5B9A\u5230\u672C\u9879\u76EE;\u8FD0\u884C `fabric store bind {alias}` \u5373\u53EF\u5728\u6B64\u8BFB\u53D6\u5B83\u7684\u77E5\u8BC6(\u518D\u7528 `fabric store switch-write {alias}` \u628A\u56E2\u961F\u77E5\u8BC6\u5199\u5165\u5B83)",
1508
+ "doctor.store.alias-drift": "by-alias \u53EF\u8BFB\u6027\u8F6F\u94FE\u4E0E\u6CE8\u518C\u8868\u4E0D\u540C\u6B65:{refs};\u8FD0\u884C `fabric doctor --fix` \u4FEE\u590D ~/.fabric/stores/by-alias/",
1509
+ "doctor.store.local-only": "store '{alias}' \u4EC5\u672C\u5730;\u52A0\u4E00\u4E2A git remote \u4EE5\u5907\u4EFD",
1510
+ "doctor.store.executable": "store '{alias}' \u542B\u53EF\u6267\u884C/\u811A\u672C\u6587\u4EF6({files})\u2014\u2014 store \u4EC5\u5B58\u6570\u636E;Fabric \u4ECE\u4E0D\u8FD0\u884C\u5B83\u4EEC (S65)",
1511
+ "doctor.store.active-personal-invalid": "\u6D3B\u52A8 personal store '{store}' \u4E0D\u662F\u5DF2\u6302\u8F7D\u7684 personal store;\u8FD0\u884C `fabric store switch-personal <alias>` \u6216 `fabric doctor --fix`",
1512
+ "doctor.store.active-personal-unset": "\u5DF2\u6302\u8F7D {count} \u4E2A personal store \u4F46\u65E0\u6D3B\u52A8\u6307\u9488;\u8FD0\u884C `fabric store switch-personal <alias>` \u9009\u4E00\u4E2A(\u6216 `fabric doctor --fix` \u9ED8\u8BA4\u53D6\u7B2C\u4E00\u4E2A)",
1513
+ "doctor.store.related-broken": "{count} \u6761 `related` \u94FE\u63A5\u6307\u5411\u8BED\u6599\u4E2D\u4E0D\u5B58\u5728\u7684 id:{samples}{overflow} \u2014\u2014 \u901A\u8FC7 `fab_review` (modify) \u4FEE\u590D related \u8FB9,\u6216\u7F16\u8F91\u6761\u76EE frontmatter",
1514
+ "doctor.store.related-hub": "related \u56FE\u8C31\u67A2\u7EBD(\u524D {shown} / \u5171 {total} \u4E2A\u88AB\u5F15\u7528):{top}",
1515
+ "doctor.store.unreachable": "store '{alias}' \u5728 read-set \u4E2D\u4F46\u78C1\u76D8\u4E0A\u4E0D\u53EF\u8FBE({reason});\u8FD0\u884C `fabric store mount` / \u91CD\u65B0 clone,\u518D\u8DD1 `fabric doctor`",
1516
+ "doctor.store.consumption-heatmap": "\u6D88\u8D39\u70ED\u533A(\u8FD1 {days}d,{consumed}/{total} \u6761\u88AB\u8BFB,\u8DE8 {windows} \u4E2A\u7A97\u53E3):{top}",
1517
+ "doctor.store.consumption-zero": "{count} \u6761\u5728\u8FD1 {days}d \u5185\u4ECE\u672A\u88AB\u6D88\u8D39:{sample}{overflow} \u2014\u2014 \u901A\u8FC7 `fab_review` \u8003\u8651\u6DD8\u6C70(\u6D88\u8D39\u91CF\u53EA\u662F\u4FE1\u53F7\u4E4B\u4E00,\u975E\u9648\u65E7\u7684\u8BC1\u636E)",
1518
+ "doctor.store.overflow-more": ", \u2026(+{count} \u6761)",
1519
+ "doctor.fix-plan.header": "fix-knowledge \u53D8\u66F4\u8BA1\u5212(\u5171 {count} \u9879)",
1520
+ "doctor.fix-plan.preview": "\u9884\u89C8:",
1521
+ "doctor.fix-plan.more": "... \u8FD8\u6709 {count} \u9879",
1522
+ "doctor.help.tagline": "\u8BCA\u65AD\u5E76\u4FEE\u590D Fabric \u5DE5\u4F5C\u533A\u95EE\u9898",
1523
+ "doctor.help.flag.target": "\u8986\u76D6\u9879\u76EE\u6839\u76EE\u5F55(\u9ED8\u8BA4\u5F53\u524D\u76EE\u5F55)",
1524
+ "doctor.help.flag.fix": "\u81EA\u52A8\u4FEE\u590D(\u6D3E\u751F\u72B6\u6001 + \u77E5\u8BC6 frontmatter/git mv)",
1525
+ "doctor.help.flag.json": "\u4EE5 JSON \u8F93\u51FA\u4F9B\u7A0B\u5E8F\u6D88\u8D39",
1526
+ "doctor.help.flag.verbose": "\u663E\u793A\u9762\u5411\u7EF4\u62A4\u8005\u7684\u64CD\u4F5C\u63D0\u793A",
1527
+ "doctor.help.example.run": "\u8FD0\u884C\u8BCA\u65AD",
1528
+ "doctor.help.example.fix": "\u4FEE\u590D\u6D3E\u751F\u72B6\u6001 + \u77E5\u8BC6\u95EE\u9898",
1529
+ "doctor.help.footer": "\u8FD0\u884C `fabric doctor` \u67E5\u770B\u5B8C\u6574\u8BCA\u65AD\u62A5\u544A\u3002\u5BA1\u8BA1 \u2192 `fabric audit`\u3002",
1530
+ // flat-design-system Wave5 (TASK-005): 重排后的 doctor C-圆点分组标题
1531
+ // (`● 存储健康` / `● 检查项`),取代原硬编码 sectionBar 字面量。
1532
+ "doctor.group.store-health": "\u5B58\u50A8\u5065\u5EB7",
1533
+ "doctor.group.checks": "\u68C0\u67E5\u9879",
1114
1534
  // v2.0.0-rc.29 REVIEW (codex LOW-2): F2 的 payload 阈值之前只出现在 JSON envelope,
1115
1535
  // 人类输出看不到,导致改了 mcpPayloadLimits 之后没法用 `fabric doctor` 快速确认是否生效。
1116
1536
  "doctor.section.payload-limits": "MCP payload \u9608\u503C\uFF1A",
@@ -1119,25 +1539,25 @@ var zhCNMessages = {
1119
1539
  "doctor.section.cite-coverage": "Cite \u8986\u76D6\u7387:",
1120
1540
  "doctor.cite.header": "\u8D77\u59CB {since} (\u653F\u7B56\u6FC0\u6D3B\u65F6\u95F4 {marker})",
1121
1541
  "doctor.cite.warning.justActivated": "\u672C\u6B21\u9996\u6B21\u6FC0\u6D3B Cite policy,\u6682\u65E0\u5386\u53F2\u6570\u636E\u3002",
1122
- "doctor.cite.metric.editsTouched": "Edit \u89E6\u8FBE\u6570",
1123
- "doctor.cite.metric.qualifyingCites": "\u5408\u683C cite",
1124
- "doctor.cite.metric.recalledUnverified": "applied \u4F46\u672A\u9A8C\u8BC1",
1542
+ "doctor.cite.metric.editsTouched": "\u7F16\u8F91\u89E6\u8FBE\u6570",
1543
+ "doctor.cite.metric.qualifyingCites": "\u5408\u683C cite \u6570",
1544
+ "doctor.cite.metric.recalledUnverified": "\u5DF2\u6807\u6CE8 applied \u4F46\u672A\u9A8C\u8BC1",
1125
1545
  "doctor.cite.metric.expectedButMissed": "\u5E94\u67E5\u6CA1\u67E5",
1126
1546
  "doctor.cite.metric.totalTurns": "\u603B\u56DE\u5408\u6570",
1127
- "doctor.cite.metric.complianceRate": "cite \u5408\u89C4\u7387 (\u542B KB:none[reason])",
1128
- "doctor.cite.metric.complianceNA": "N/A (\u65E0\u5E94 cite \u56DE\u5408)",
1129
- "doctor.cite.metric.uncorrelatableEdits": "\u65E0\u6CD5\u5173\u8054\u7684 edit (\u7F3A session_id \u2014 hook \u8FC7\u671F? \u8BF7\u8DD1 `fabric install`)",
1130
- "doctor.cite.metric.recallCoverage": "recall \u8986\u76D6\u7387 (\u6539\u524D\u6709\u76F8\u5173 fab_recall \u7684 edit \u5360\u6BD4)",
1131
- "doctor.cite.metric.recallCoverageNA": "N/A (\u65E0\u53EF\u5173\u8054 edit)",
1547
+ "doctor.cite.metric.complianceRate": "cite \u5408\u89C4\u7387\uFF08\u542B KB:none[reason]\uFF09",
1548
+ "doctor.cite.metric.complianceNA": "N/A\uFF08\u65E0\u5E94 cite \u56DE\u5408\uFF09",
1549
+ "doctor.cite.metric.uncorrelatableEdits": "\u65E0\u6CD5\u5173\u8054\u7684\u7F16\u8F91\uFF08\u7F3A session_id \u2014\u2014 hook \u8FC7\u671F?\u8BF7\u8DD1 `fabric install`\uFF09",
1550
+ "doctor.cite.metric.recallCoverage": "recall \u8986\u76D6\u7387\uFF08\u6539\u524D\u6709\u76F8\u5173 fab_recall \u7684\u7F16\u8F91\u5360\u6BD4\uFF09",
1551
+ "doctor.cite.metric.recallCoverageNA": "N/A\uFF08\u65E0\u53EF\u5173\u8054\u7F16\u8F91\uFF09",
1132
1552
  // v2.2.0-rc.1 W1-T3 (cite 诚实拆分): 弱辅助信号, 与真遵循率分列展示。括注必须
1133
1553
  // 明确「不计入真遵循度」(诚实铁律)。
1134
- "doctor.cite.metric.exposedAndMutated": "\u66DD\u5149\u4E14\u8DEF\u5F84\u53D8\u66F4 (\u5F31\u8F85\u52A9\u4FE1\u53F7 \u2014 \u4E0D\u8BA1\u5165\u771F\u9075\u5FAA\u5EA6)",
1554
+ "doctor.cite.metric.exposedAndMutated": "\u66DD\u5149\u4E14\u8DEF\u5F84\u53D8\u66F4\uFF08\u5F31\u8F85\u52A9\u4FE1\u53F7 \u2014\u2014 \u4E0D\u8BA1\u5165\u771F\u9075\u5FAA\u5EA6\uFF09",
1135
1555
  // lifecycle-refactor W2-T4 (§5 row7/row2): PostToolUse mutation funnel +
1136
1556
  // SessionEnd 边界。均为可观测性 marker, 不计入真遵循度。
1137
- "doctor.cite.metric.mutationsObserved": "mutation \u89C2\u6D4B\u6570 (PostToolUse file_mutated \u2014 \u6743\u5A01\u4FE1\u53F7, \u4E0D\u8BA1\u5165\u771F\u9075\u5FAA\u5EA6)",
1138
- "doctor.cite.metric.mutationPool": "mutation \u5F52\u56E0\u6C60 (\u7ECF source_event_id \u7684 low-confidence \u5F52\u56E0)",
1139
- "doctor.cite.metric.sessionsClosed": "\u5DF2\u95ED\u5408 session \u6570 (SessionEnd marker \u2014 funnel \u8FB9\u754C)",
1140
- "doctor.cite.metric.byStore": "\u6309 store \u62C6\u5206\u7684\u5408\u89C4 cite \u6570 (\u8BCA\u65AD\u62C6\u5206 \u2014 \u4E0D\u8BA1\u5165\u771F\u9075\u5FAA\u5EA6; 'local' = \u672C\u9879\u76EE)",
1557
+ "doctor.cite.metric.mutationsObserved": "mutation \u89C2\u6D4B\u6570\uFF08PostToolUse file_mutated \u2014\u2014 \u6743\u5A01\u4FE1\u53F7,\u4E0D\u8BA1\u5165\u771F\u9075\u5FAA\u5EA6\uFF09",
1558
+ "doctor.cite.metric.mutationPool": "mutation \u5F52\u56E0\u6C60\uFF08\u7ECF source_event_id \u7684\u4F4E\u7F6E\u4FE1\u5F52\u56E0\uFF09",
1559
+ "doctor.cite.metric.sessionsClosed": "\u5DF2\u95ED\u5408\u4F1A\u8BDD\u6570\uFF08SessionEnd marker \u2014\u2014 funnel \u8FB9\u754C\uFF09",
1560
+ "doctor.cite.metric.byStore": "\u6309 store \u62C6\u5206\u7684\u5408\u89C4 cite \u6570\uFF08\u8BCA\u65AD\u62C6\u5206 \u2014\u2014 \u4E0D\u8BA1\u5165\u771F\u9075\u5FAA\u5EA6;'local' = \u672C\u9879\u76EE\uFF09",
1141
1561
  "doctor.cite.section.perClient": "\u6309\u5BA2\u6237\u7AEF\u62C6\u5206",
1142
1562
  "doctor.cite.section.dismissedReasons": "\u9A73\u56DE\u539F\u56E0\u5206\u5E03",
1143
1563
  "doctor.cite.dismissed.scope-mismatch": "\u8303\u56F4\u4E0D\u7B26",
@@ -1223,30 +1643,30 @@ var zhCNMessages = {
1223
1643
  "cli.doctor.errors.enrich-descriptions-mutex": "--enrich-descriptions \u4E0D\u80FD\u4E0E --fix / --fix-knowledge / --cite-coverage \u540C\u65F6\u4F7F\u7528,\u8BF7\u5206\u522B\u8FD0\u884C\u3002",
1224
1644
  "doctor.enrich.allComplete": "\u6240\u6709\u6B63\u5F0F\u77E5\u8BC6\u6761\u76EE\u5747\u5DF2\u5305\u542B intent_clues / tech_stack / impact / must_read_if\u3002",
1225
1645
  // rc.26 TASK-02a: doctor foundation-batch check messages.
1226
- "doctor.check.bootstrap_snapshot_drift.name": "Bootstrap snapshot drift",
1646
+ "doctor.check.bootstrap_snapshot_drift.name": "Bootstrap \u5FEB\u7167\u6F02\u79FB",
1227
1647
  "doctor.check.bootstrap_snapshot_drift.message.drift": ".fabric/AGENTS.md \u5185\u5BB9\u4E0E BOOTSTRAP_CANONICAL \u9010\u5B57\u8282\u4E0D\u4E00\u81F4\u3002",
1228
1648
  "doctor.check.bootstrap_snapshot_drift.remediation.drift": "\u8FD0\u884C `fabric doctor --fix` \u6062\u590D canonical bootstrap snapshot",
1229
1649
  "doctor.check.bootstrap_snapshot_drift.ok.ok": ".fabric/AGENTS.md \u4E0E BOOTSTRAP_CANONICAL \u9010\u5B57\u8282\u4E00\u81F4\u3002",
1230
1650
  "doctor.check.bootstrap_snapshot_drift.ok.missing_delegated": ".fabric/AGENTS.md \u4E0D\u5B58\u5728\uFF0C\u5DF2\u4EA4\u7531 bootstrap_anchor_missing \u62A5\u544A\u3002",
1231
- "doctor.check.managed_block_drift.name": "Managed block drift",
1651
+ "doctor.check.managed_block_drift.name": "Managed block \u6F02\u79FB",
1232
1652
  "doctor.check.managed_block_drift.message.singular": "{count} \u4E2A three-end managed block \u4E0E\u671F\u671B\u5185\u5BB9\uFF08snapshot + \u53EF\u9009 project-rules concat\uFF09\u4E0D\u4E00\u81F4\uFF1A{list}\u3002",
1233
1653
  "doctor.check.managed_block_drift.message.plural": "{count} \u4E2A three-end managed block \u4E0E\u671F\u671B\u5185\u5BB9\uFF08snapshot + \u53EF\u9009 project-rules concat\uFF09\u4E0D\u4E00\u81F4\uFF1A{list}\u3002",
1234
1654
  "doctor.check.managed_block_drift.remediation": "\u8FD0\u884C `fabric doctor --fix` \u4ECE canonical \u6062\u590D three-end managed blocks",
1235
1655
  "doctor.check.managed_block_drift.ok.ok": "Three-end managed blocks \u4E0E expectedBody \u9010\u5B57\u8282\u4E00\u81F4\u3002",
1236
1656
  "doctor.check.managed_block_drift.ok.no_managed_block": "\u672A\u68C0\u6D4B\u5230 three-end managed blocks\uFF1B\u53EF\u80FD\u5C1A\u672A\u4F20\u64AD\uFF0C\u6216\u4ECD\u5904\u4E8E legacy-marker \u72B6\u6001\u3002",
1237
- "doctor.check.bootstrap_anchor.name": "Bootstrap anchor",
1657
+ "doctor.check.bootstrap_anchor.name": "Bootstrap \u951A\u70B9",
1238
1658
  "doctor.check.bootstrap_anchor.message.missing": "repo root \u4E0B AGENTS.md \u4E0E CLAUDE.md \u90FD\u4E0D\u5B58\u5728\u3002Fabric \u9700\u8981\u5728\u9879\u76EE\u6839\u76EE\u5F55\u5B58\u5728 bootstrap anchor \u6587\u4EF6\u3002",
1239
1659
  "doctor.check.bootstrap_anchor.remediation.missing": "\u8FD0\u884C `fabric install` \u5728 repo root \u751F\u6210 AGENTS.md / CLAUDE.md bootstrap anchor\u3002",
1240
1660
  "doctor.check.bootstrap_anchor.ok": "repo root \u4E0B\u5DF2\u5B58\u5728 Bootstrap anchor\uFF1A{present}\u3002",
1241
1661
  // v2.0.0-rc.33 W3-2 (T6 #5): 文案显式引用 message 内已列出的 detail (file 名), 让用户直接 rm 而非自己去 grep 找。baseline pipeline 已 rc.23 移除, 没有 auto-fix。
1242
- "doctor.check.forensic.name": "Scan evidence",
1662
+ "doctor.check.forensic.name": "\u626B\u63CF\u8BC1\u636E",
1243
1663
  "doctor.check.forensic.message.missing.singular": "{error} \u5B9E\u65F6\u626B\u63CF\u68C0\u6D4B\u5230 {frameworkKind}\uFF0C\u5171\u6709 {count} \u4E2A\u5165\u53E3\u70B9\u3002",
1244
1664
  "doctor.check.forensic.message.missing.plural": "{error} \u5B9E\u65F6\u626B\u63CF\u68C0\u6D4B\u5230 {frameworkKind}\uFF0C\u5171\u6709 {count} \u4E2A\u5165\u53E3\u70B9\u3002",
1245
1665
  "doctor.check.forensic.message.missing-default": ".fabric/forensic.json \u7F3A\u5931\u3002",
1246
1666
  "doctor.check.forensic.message.invalid-default": ".fabric/forensic.json \u65E0\u6548\u3002",
1247
1667
  "doctor.check.forensic.remediation": "\u8FD0\u884C `fabric install` \u91CD\u65B0\u751F\u6210 .fabric/forensic.json\u3002",
1248
1668
  "doctor.check.forensic.ok": ".fabric/forensic.json \u5BF9 {frameworkKind} \u6709\u6548\u3002",
1249
- "doctor.check.agents_meta.name": "Agents metadata",
1669
+ "doctor.check.agents_meta.name": "Agents \u5143\u6570\u636E",
1250
1670
  "doctor.check.agents_meta.message.missing": ".fabric/agents.meta.json \u7F3A\u5931\u3002",
1251
1671
  "doctor.check.agents_meta.remediation.missing": "store-backed knowledge \u4E0B\u65E0\u9700\u5904\u7406\uFF1B\u9879\u76EE\u672C\u5730 agents.meta \u91CD\u5EFA\u8DEF\u5F84\u5DF2\u9000\u4F11\u3002",
1252
1672
  "doctor.check.agents_meta.message.invalid-default": ".fabric/agents.meta.json \u65E0\u6548\u3002",
@@ -1258,7 +1678,7 @@ var zhCNMessages = {
1258
1678
  "doctor.check.agents_meta.message.stale_hash_equal": ".fabric/agents.meta.json \u5DF2\u4E0E\u5DF2\u9000\u4F11\u7684\u672C\u5730\u6D3E\u751F revision {revision} \u5BF9\u9F50\uFF1B\u8BE5\u68C0\u67E5\u4EC5\u4F5C\u5386\u53F2\u517C\u5BB9\u3002",
1259
1679
  "doctor.check.agents_meta.remediation.stale": "\u4E0D\u518D\u6267\u884C\u9879\u76EE\u672C\u5730 reconcile\uFF1Bmounted stores \u4F1A\u88AB\u76F4\u63A5\u8BFB\u53D6\u3002",
1260
1680
  "doctor.check.agents_meta.ok": "\u68C0\u6D4B\u5230 legacy agents.meta revision {revision}\uFF1Bstore-backed knowledge \u4E0D\u4F9D\u8D56\u5B83\u3002",
1261
- "doctor.check.rule_content_refs.name": "Rule content refs",
1681
+ "doctor.check.rule_content_refs.name": "Rule \u5185\u5BB9\u5F15\u7528",
1262
1682
  "doctor.check.rule_content_refs.message.unavailable": "agents.meta.json \u6709\u6548\u524D\uFF0C\u65E0\u6CD5\u68C0\u67E5 content_ref entries\u3002",
1263
1683
  "doctor.check.rule_content_refs.remediation.unavailable": "\u5148\u4FEE\u590D agents.meta.json\uFF1A\u8FD0\u884C `fabric doctor --fix`\u3002",
1264
1684
  "doctor.check.rule_content_refs.message.outside.singular": "{count} \u4E2A legacy content_ref entry \u4F4D\u4E8E\u5DF2\u9000\u4F11\u7684\u672C\u5730 knowledge root \u5916\u90E8\u3002",
@@ -1269,7 +1689,7 @@ var zhCNMessages = {
1269
1689
  "doctor.check.rule_content_refs.message.missing.plural": "{count} \u4E2A content_ref targets \u7F3A\u5931\u3002\u8FD0\u884C `fabric doctor --fix` \u6267\u884C reconcile\u3002",
1270
1690
  "doctor.check.rule_content_refs.remediation.missing": "\u9879\u76EE\u672C\u5730 content_ref reconcile \u5DF2\u9000\u4F11\uFF1B\u8BF7\u7ED1\u5B9A\u5E76\u8BFB\u53D6 mounted stores\u3002",
1271
1691
  "doctor.check.rule_content_refs.ok": "\u6240\u6709 legacy content_ref entries \u90FD\u80FD\u89E3\u6790\uFF1Bstore-backed knowledge \u4ECE mounted stores \u8BFB\u53D6\u3002",
1272
- "doctor.check.knowledge_test_index.name": "Knowledge-test index",
1692
+ "doctor.check.knowledge_test_index.name": "\u77E5\u8BC6\u6D4B\u8BD5\u7D22\u5F15",
1273
1693
  "doctor.check.knowledge_test_index.remediation.missing": "\u8FD0\u884C `fabric doctor --fix` \u91CD\u5EFA .fabric/.cache/knowledge-test.index.json\u3002",
1274
1694
  "doctor.check.knowledge_test_index.remediation.invalid": "\u5220\u9664 .fabric/.cache/knowledge-test.index.json \u5E76\u8FD0\u884C `fabric doctor --fix` \u91CD\u65B0\u751F\u6210\u3002",
1275
1695
  "doctor.check.knowledge_test_index.message.stale": ".fabric/.cache/knowledge-test.index.json \u5DF2\u8FC7\u671F\u3002",
@@ -1278,7 +1698,7 @@ var zhCNMessages = {
1278
1698
  "doctor.check.knowledge_test_index.ok.link_singular.orphan_plural": "\u5DF2\u7D22\u5F15 {linkCount} \u4E2A link \u548C {orphanCount} \u4E2A orphan annotation\u3002",
1279
1699
  "doctor.check.knowledge_test_index.ok.link_plural.orphan_singular": "\u5DF2\u7D22\u5F15 {linkCount} \u4E2A link \u548C {orphanCount} \u4E2A orphan annotation\u3002",
1280
1700
  "doctor.check.knowledge_test_index.ok.link_plural.orphan_plural": "\u5DF2\u7D22\u5F15 {linkCount} \u4E2A link \u548C {orphanCount} \u4E2A orphan annotation\u3002",
1281
- "doctor.check.event_ledger.name": "Event ledger",
1701
+ "doctor.check.event_ledger.name": "\u4E8B\u4EF6\u8D26\u672C",
1282
1702
  "doctor.check.event_ledger.message.missing": ".fabric/events.jsonl \u7F3A\u5931\u3002",
1283
1703
  "doctor.check.event_ledger.remediation.missing": "\u8FD0\u884C `fabric doctor --fix` \u521B\u5EFA .fabric/events.jsonl\u3002",
1284
1704
  "doctor.check.event_ledger.message.not_writable-default": ".fabric/events.jsonl \u4E0D\u53EF\u5199\u3002",
@@ -1289,20 +1709,20 @@ var zhCNMessages = {
1289
1709
  "doctor.check.event_ledger.ok": ".fabric/events.jsonl \u5DF2\u5B58\u5728\uFF0C\u53EF\u5199\uFF0C\u4E14\u53EF\u89E3\u6790\u3002",
1290
1710
  // v2.0.0-rc.37 Wave B (B5): 复合 hard-gate 检查 events.jsonl/metrics.jsonl 健康
1291
1711
  // (G7 size / G8 metric_leak / G9 metrics_stale / G10 rotation_overdue)。
1292
- "doctor.check.events_jsonl_health.name": "Events ledger \u5065\u5EB7 (rc.37 Plan B 5 hard gate)",
1712
+ "doctor.check.events_jsonl_health.name": "\u4E8B\u4EF6\u8D26\u672C\u5065\u5EB7",
1293
1713
  "doctor.check.events_jsonl_health.ok": ".fabric/events.jsonl \u5927\u5C0F\u3001\u65B0\u9C9C\u5EA6\u3001metric \u9694\u79BB\u5168\u90E8\u6B63\u5E38\u3002",
1294
1714
  "doctor.check.events_jsonl_health.message.size": ".fabric/events.jsonl \u5DF2 {sizeMb} MB\uFF0C\u8D85\u8FC7 10 MB \u9608\u503C\u3002",
1295
1715
  "doctor.check.events_jsonl_health.message.metric_leak": ".fabric/events.jsonl \u542B {count} \u884C metric-counter \u7C7B event_type ({samples})\u3002\u8FD9\u4E9B event \u5E94\u7531 metrics.jsonl \u8BA1\u6570, \u4E0D\u518D\u8FDB\u5165 audit ledger\u3002",
1296
1716
  "doctor.check.events_jsonl_health.message.metrics_stale": ".fabric/metrics.jsonl \u5DF2 {minutes} \u5206\u949F\u672A\u66F4\u65B0\uFF1Bserver-side 60s flush \u53EF\u80FD stalled\u3002",
1297
1717
  "doctor.check.events_jsonl_health.message.rotation_overdue": ".fabric/events.jsonl \u5DF2 {days} \u5929\u672A rotate\uFF1B6h rotation tick \u53EF\u80FD\u672A\u8FD0\u884C\u3002",
1298
1718
  "doctor.check.events_jsonl_health.remediation": "\u8FD0\u884C `fabric doctor --fix` \u2014\u2014 \u5B83\u4F1A\u89E6\u53D1 rotation \u5E76 flush metrics.jsonl(rc.2 F16: \u65E0\u9700\u91CD\u542F server \u5373\u53EF\u6E05\u51FA idle \u671F\u672A\u5237\u7684 metric counter)\u3002\u82E5\u544A\u8B66\u4ECD\u6301\u7EED, \u518D\u91CD\u542F MCP server \u8BA9 startMetricsFlush + startRotationTick \u91CD\u65B0\u8C03\u5EA6\u3002\u82E5 metric_leak \u547D\u4E2D, \u68C0\u67E5\u6700\u8FD1\u4EE3\u7801\u6539\u52A8\u662F\u5426\u7ED5\u8FC7 bumpCounter API \u76F4\u63A5 appendEventLedgerEvent \u5199\u4E86 4 \u4E2A metric-managed event_type \u4E4B\u4E00\u3002",
1299
- "doctor.check.event_ledger_partial_write.name": "Event ledger partial write",
1719
+ "doctor.check.event_ledger_partial_write.name": "\u4E8B\u4EF6\u8D26\u672C\u534A\u622A\u5199\u5165",
1300
1720
  "doctor.check.event_ledger_partial_write.ok.skipped": "\u65E0\u9700\u6267\u884C partial-write \u68C0\u67E5\uFF08ledger \u7F3A\u5931\u6216\u4E0D\u53EF\u5199\uFF09\u3002",
1301
1721
  "doctor.check.event_ledger_partial_write.message": "events.jsonl \u5728 byte offset {byteOffset} \u5904\u5B58\u5728 partial write\uFF08{byteLength} \u4E2A corrupted bytes\uFF09\u3002\u8FD0\u884C --fix \u622A\u65AD\u5E76\u4FDD\u7559 corrupted bytes\u3002",
1302
1722
  "doctor.check.event_ledger_partial_write.remediation": "\u8FD0\u884C `fabric doctor --fix` \u622A\u65AD partial write \u5E76\u5C06 events.jsonl \u6062\u590D\u5230\u6709\u6548\u72B6\u6001\u3002",
1303
1723
  "doctor.check.event_ledger_partial_write.ok.clean": "events.jsonl \u6CA1\u6709 partial trailing write\u3002",
1304
1724
  // v2.0.0-rc.27 TASK-010 (audit §2.24): schema-compat 向前兼容警告类别。
1305
- "doctor.check.event_ledger_schema_compat.name": "Event ledger schema \u517C\u5BB9\u6027",
1725
+ "doctor.check.event_ledger_schema_compat.name": "\u4E8B\u4EF6\u8D26\u672C schema \u517C\u5BB9\u6027",
1306
1726
  "doctor.check.event_ledger_schema_compat.ok.skipped": "\u65E0\u9700\u505A schema \u517C\u5BB9\u6027\u68C0\u67E5\uFF08events.jsonl \u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u5199\uFF09\u3002",
1307
1727
  "doctor.check.event_ledger_schema_compat.ok.clean": "events.jsonl \u6240\u6709\u884C\u90FD\u80FD\u89E3\u6790\u4E3A\u5F53\u524D schema\u3002",
1308
1728
  "doctor.check.event_ledger_schema_compat.message.schema_version": "events.jsonl \u542B {count} \u884C `schema_version` \u4E0D\u88AB\u5F53\u524D CLI \u8BC6\u522B\uFF08\u6837\u672C: {samples}\uFF09\u3002",
@@ -1320,17 +1740,22 @@ var zhCNMessages = {
1320
1740
  "doctor.check.retired_reference.message": "agent \u53EF\u89C1\u6587\u672C\u4E2D\u6709 {count} \u5904\u6307\u5411\u9000\u5F79\u5DE5\u5177/\u5B57\u6BB5\u540D\u7684 stale pointer: {sample}",
1321
1741
  "doctor.check.retired_reference.remediation": "\u628A\u547D\u4E2D\u6587\u672C\u6539\u4E3A\u66FF\u4EE3 token (\u6216\u5220\u9664), \u518D\u8DD1 `fabric install` \u91CD\u540C\u6B65 dogfood \u955C\u50CF\u3002",
1322
1742
  // v2.0.0-rc.33 W3-6 (P1-13): SKILL.md token budget lint。warn > 5K / error > 10K token (chars/3 估算)。基于 Anthropic 推荐 SKILL.md 热路径 ~3K, 超过 5K 已影响 progressive disclosure;超过 10K 是阻断级 (model context 浪费 + 加载延迟)。
1323
- "doctor.check.skill_token_budget.name": "Skill token budget",
1743
+ "doctor.check.skill_token_budget.name": "Skill token \u9884\u7B97",
1324
1744
  "doctor.check.skill_token_budget.ok": "\u6240\u6709 .claude/skills/<slug>/SKILL.md \u5728 token budget \u5185 (warn 5K / error 10K)\u3002",
1325
1745
  "doctor.check.skill_token_budget.message.singular": "{count} \u4E2A SKILL.md \u8D85\u51FA token budget: {list}\u3002\u5EFA\u8BAE\u628A\u8BE6\u7EC6\u5185\u5BB9\u4E0B\u6C89\u5230 ref/ progressive disclosure\u3002",
1326
1746
  "doctor.check.skill_token_budget.message.plural": "{count} \u4E2A SKILL.md \u8D85\u51FA token budget: {list}\u3002\u5EFA\u8BAE\u628A\u8BE6\u7EC6\u5185\u5BB9\u4E0B\u6C89\u5230 ref/ progressive disclosure\u3002",
1327
1747
  "doctor.check.skill_token_budget.remediation": "\u5C06\u8D85\u6807 SKILL.md \u4E2D\u7684\u8BE6\u7EC6 phase / worked-examples / decision \u8868\u79FB\u5230 `templates/skills/<slug>/ref/*.md`,SKILL.md \u70ED\u8DEF\u5F84\u53EA\u7559 trigger gate + \u5173\u952E phase \u6982\u8981;\u53C2\u8003 W1 progressive disclosure \u62C6\u5206\u6A21\u5F0F\u3002\u91CD\u65B0\u8DD1 `fabric install` \u540C\u6B65\u4E24\u7AEF\u3002",
1328
- // v2.0.0-rc.33 W3-7 (P1-14): SKILL.md description 结构 lint。代理 trigger-recall (真 LLM 测要 live model, W1 已用 gemini 跑过);本 lint 抓回归: description 缺失 / 超 60 token / 缺中文 trigger / 缺英文 trigger
1329
- "doctor.check.skill_description.name": "Skill description quality",
1330
- "doctor.check.skill_description.ok": "\u6240\u6709 SKILL.md description \u5B57\u6BB5\u7ED3\u6784\u826F\u597D (\u975E\u7A7A / <60 token / \u4E2D\u82F1\u53CC\u8BED trigger)\u3002",
1748
+ // v2.0.0-rc.33 W3-7 (P1-14): SKILL.md description 结构 lint。代理 trigger-recall (真 LLM 测要 live model, W1 已用 gemini 跑过);本 lint 抓回归: description 缺失 / 超 60 token / 缺中文 trigger / 缺英文 trigger / 缺 anti-trigger 边界。
1749
+ "doctor.check.skill_description.name": "Skill description \u8D28\u91CF",
1750
+ "doctor.check.skill_description.ok": "\u6240\u6709 SKILL.md description \u5B57\u6BB5\u7ED3\u6784\u826F\u597D (\u975E\u7A7A / <60 token / \u4E2D\u82F1\u53CC\u8BED trigger / \u660E\u786E anti-trigger \u8FB9\u754C)\u3002",
1331
1751
  "doctor.check.skill_description.message.singular": "{count} \u4E2A SKILL.md description \u7ED3\u6784\u95EE\u9898: {list}\u3002description \u662F host \u7AEF auto-invoke \u7684\u4E3B\u8981\u5339\u914D\u4FE1\u53F7\u3002",
1332
1752
  "doctor.check.skill_description.message.plural": "{count} \u4E2A SKILL.md description \u7ED3\u6784\u95EE\u9898: {list}\u3002description \u662F host \u7AEF auto-invoke \u7684\u4E3B\u8981\u5339\u914D\u4FE1\u53F7\u3002",
1333
- "doctor.check.skill_description.remediation": "\u7F16\u8F91 `packages/cli/templates/skills/<slug>/SKILL.md` frontmatter `description:` \u5B57\u6BB5: (1) \u975E\u7A7A; (2) <60 token (chars/3 \u4F30\u7B97, \u7EA6 180 \u5B57\u7B26); (3) \u81F3\u5C11 1 \u4E2A\u4E2D\u6587 trigger \u77ED\u8BED; (4) \u81F3\u5C11 1 \u4E2A\u82F1\u6587 trigger \u77ED\u8BED\u3002\u53C2\u8003 W1 description rewrite \u98CE\u683C\u3002\u91CD\u65B0\u8DD1 `fabric install` \u540C\u6B65\u4E24\u7AEF\u3002\u5982\u9700\u9A8C\u8BC1 recall, \u8DD1 W1 \u7684 gemini delegate (\u89C1 .workflow/.scratchpad/rc33-plan/W1-VERIFY-RESULT.md)\u3002",
1753
+ "doctor.check.skill_description.remediation": "\u7F16\u8F91 `packages/cli/templates/skills/<slug>/SKILL.md` frontmatter `description:` \u5B57\u6BB5: (1) \u975E\u7A7A; (2) <60 token (chars/3 \u4F30\u7B97, \u7EA6 180 \u5B57\u7B26); (3) \u81F3\u5C11 1 \u4E2A\u4E2D\u6587 trigger \u77ED\u8BED; (4) \u81F3\u5C11 1 \u4E2A\u82F1\u6587 trigger \u77ED\u8BED; (5) \u660E\u786E anti-trigger,\u5982 `NOT PR review` / `NOT code review` / `\u4E0D\u662F...`\u3002\u53C2\u8003 W1 description rewrite \u98CE\u683C\u3002\u91CD\u65B0\u8DD1 `fabric install` \u540C\u6B65\u4E24\u7AEF\u3002\u5982\u9700\u9A8C\u8BC1 recall, \u8DD1 W1 \u7684 gemini delegate (\u89C1 .workflow/.scratchpad/rc33-plan/W1-VERIFY-RESULT.md)\u3002",
1754
+ "doctor.check.skill_contract.name": "Skill contract \u5B8C\u6574\u6027",
1755
+ "doctor.check.skill_contract.ok": "Fabric SKILL.md contract \u5B8C\u6574: hard-rule anchors\u3001MCP-only write path\u3001thin shim \u4E0E ref \u5165\u53E3\u5747\u5B58\u5728\u3002",
1756
+ "doctor.check.skill_contract.message.singular": "{count} \u4E2A Fabric skill contract \u95EE\u9898: {list}\u3002",
1757
+ "doctor.check.skill_contract.message.plural": "{count} \u4E2A Fabric skill contract \u95EE\u9898: {list}\u3002",
1758
+ "doctor.check.skill_contract.remediation": "\u5728 `packages/cli/templates/skills/<slug>/SKILL.md` \u4E0E\u5BF9\u5E94 `ref/*.md` \u4E2D\u6062\u590D\u7F3A\u5931\u7684 contract \u6587\u672C,\u518D\u8DD1 `fabric install` \u540C\u6B65 `.claude/skills` \u4E0E `.codex/skills`\u3002archive/review \u5FC5\u987B\u4FDD\u7559 DISPLAY/WRITE hard rules \u4E0E MCP-only mutation path;store/sync \u5FC5\u987B\u4FDD\u6301 thin CLI shim\u3002",
1334
1759
  // v2.0.0-rc.33 W3-3 (P1-3): cite-policy Goodhart 模式检测。扫 7d 内 assistant_turn_observed 事件, 3 个 anti-pattern (G1 仪式化 / G2 抄底引用 / G5 placeholder cite)。warning 级 (启发式有 false-positive, 不阻断)。
1335
1760
  "doctor.check.cite_goodhart.name": "Cite-policy Goodhart",
1336
1761
  "doctor.check.cite_goodhart.ok": "\u8FC7\u53BB 7d \u672A\u68C0\u6D4B\u5230 cite-policy Goodhart \u53CD\u6A21\u5F0F\u3002",
@@ -1338,22 +1763,22 @@ var zhCNMessages = {
1338
1763
  "doctor.check.cite_goodhart.message.plural": "\u68C0\u6D4B\u5230 {count} \u4E2A cite-policy Goodhart \u6A21\u5F0F: {list}\u3002",
1339
1764
  "doctor.check.cite_goodhart.remediation": "\u5BA1\u9605\u89E6\u53D1\u7684 pattern: G1 \u4EEA\u5F0F\u5316 \u2192 \u540C\u4E00 [applied] cite \u91CD\u590D\u7528,\u8BE5\u628A KB \u771F\u6B63\u843D\u5230 contract; G2 \u6284\u5E95\u5F15\u7528 \u2192 > 60% applied \u7528 skip: \u662F\u7ED5\u8FC7 contract, review skip reason \u771F\u5B9E\u6027; G5 placeholder cite \u2192 'KB: none' / [unspecified] \u592A\u591A, \u8BE5\u7528\u5177\u4F53 sentinel \u5982 [no-relevant] / [not-applicable]\u3002\u8BE6\u7EC6\u6570\u636E\u8DD1 `fabric doctor --cite-coverage --since=7d`\u3002",
1340
1765
  // v2.0.0-rc.33 W4-A4 (T5 P2): draft-backlog lint。rc.32 baseline 92% entry 卡在 draft, 揭示 promote 断流。> 50% draft 触发 warning (workspace 必须 >= 10 entries 才计算比率, 避免小语料噪音)。
1341
- "doctor.check.draft_backlog.name": "Knowledge draft backlog",
1766
+ "doctor.check.draft_backlog.name": "\u77E5\u8BC6 draft \u79EF\u538B",
1342
1767
  "doctor.check.draft_backlog.ok": "canonical knowledge entries \u4E2D draft \u5360\u6BD4\u6B63\u5E38 (< 50%, \u6216 workspace \u592A\u5C0F\u4E0D\u8BC4)\u3002",
1343
1768
  "doctor.check.draft_backlog.message": "{draftCount}/{totalCount} ({pct}%) canonical knowledge entries \u5361\u5728 draft maturity \u2014 promote \u65AD\u6D41 (rc.32 baseline 92%)\u3002",
1344
1769
  "doctor.check.draft_backlog.remediation": "\u8C03 `/fabric-review` \u6279\u91CF\u5BA1 draft entries: approve \u5347 verified/proven, reject \u4E22, modify \u4FEE\u3002draft \u957F\u671F\u5806\u79EF\u901A\u5E38\u610F\u5473\u7740 archive skill \u4EA7 draft \u592A\u5FEB\u6216 review skill \u6CA1\u8DDF\u4E0A\u3002",
1345
1770
  // rc.37 NEW-38: knowledge auto-promote (info surface; --fix 执行).
1346
1771
  // rc.36 TASK-05 (P0-8): empty-tags ratio warn.
1347
- "doctor.check.knowledge_tags_empty.name": "Knowledge tags coverage",
1772
+ "doctor.check.knowledge_tags_empty.name": "\u77E5\u8BC6 tags \u8986\u76D6\u7387",
1348
1773
  "doctor.check.knowledge_tags_empty.ok": "canonical knowledge entries \u4E2D empty tags \u5360\u6BD4\u6B63\u5E38 (\u2264 50%, \u6216 workspace \u592A\u5C0F\u4E0D\u8BC4)\u3002",
1349
1774
  "doctor.check.knowledge_tags_empty.message": "{emptyCount}/{totalCount} ({pct}%) canonical knowledge entries \u7684 `tags:` \u4E3A\u7A7A \u2014 \u4E3B\u9898\u805A\u7C7B\u4E0E\u8DE8\u6761\u76EE\u68C0\u7D22\u9000\u5316\u3002fabric-archive skill \u5E94\u6BCF\u4E2A entry \u4EA7 2-4 \u4E2A tag\u3002",
1350
1775
  "doctor.check.knowledge_tags_empty.remediation": "\u4E0B\u4E00\u8F6E archive/import \u65F6,\u5728 frontmatter `tags:` \u5199 2-4 \u4E2A kebab-case \u4E3B\u9898\u8BCD;\u6279\u91CF\u8865\u65E7 entry tag \u7528 `/fabric-review` modify \u6D41\u3002",
1351
1776
  // rc.36 TASK-09 (P1-NEW1): drift_detected 未消化告警。
1352
- "doctor.check.drift_unconsumed.name": "Knowledge drift unconsumed",
1777
+ "doctor.check.drift_unconsumed.name": "\u77E5\u8BC6\u6F02\u79FB\u672A\u6D88\u5316",
1353
1778
  "doctor.check.drift_unconsumed.ok": "\u8FD1 30 \u5929\u5185 knowledge_drift_detected \u4E8B\u4EF6\u5DF2\u88AB\u5BF9\u5E94 knowledge_demoted \u6D88\u5316,\u6216\u4E8B\u4EF6\u6570\u592A\u5C11\u4E0D\u8BC4\u3002",
1354
1779
  "doctor.check.drift_unconsumed.message": "\u8FD1 30 \u5929\u5185 knowledge_drift_detected \u4E8B\u4EF6 {driftCount} \u6B21,knowledge_demoted \u4E8B\u4EF6 {demoteCount} \u6B21\u3002drift > demote \u81F3\u5C11 5 \u2192 \u90E8\u5206 drift \u6CA1\u88AB\u6D88\u5316,KB \u4F1A\u7F13\u6162\u5931\u6D3B\u3002",
1355
1780
  "doctor.check.drift_unconsumed.remediation": "\u8C03 `/fabric-review` \u5BA1 drift \u6807\u8BB0\u7684\u6761\u76EE \u2014 \u901A\u8FC7 store \u5199\u4FA7 review \u6D41\u7A0B\u964D\u7EA7\u6216\u5F52\u6863\u5B83\u4EEC\u3002(doctor \u7684 orphan_demote / stale_archive lint \u53EA\u4E0A\u62A5\u8870\u51CF,\u4E0D\u81EA\u6108 store \u77E5\u8BC6\u3002)",
1356
- "doctor.check.meta_manually_diverged.name": "Meta manual divergence",
1781
+ "doctor.check.meta_manually_diverged.name": "Meta \u624B\u52A8\u504F\u79BB",
1357
1782
  "doctor.check.meta_manually_diverged.ok.unreadable": "agents.meta.json \u4E0D\u53EF\u8BFB\uFF0C\u8DF3\u8FC7 divergence \u68C0\u67E5\u3002",
1358
1783
  "doctor.check.meta_manually_diverged.message.extra.singular": "agents.meta.json \u4E2D\u6709 {count} \u4E2A entry \u5728\u78C1\u76D8\u4E0A\u6CA1\u6709\u5BF9\u5E94\u6587\u4EF6\u3002\u8FD0\u884C --fix \u6267\u884C reconcile\u3002",
1359
1784
  "doctor.check.meta_manually_diverged.message.extra.plural": "agents.meta.json \u4E2D\u6709 {count} \u4E2A entries \u5728\u78C1\u76D8\u4E0A\u6CA1\u6709\u5BF9\u5E94\u6587\u4EF6\u3002\u8FD0\u884C --fix \u6267\u884C reconcile\u3002",
@@ -1362,53 +1787,60 @@ var zhCNMessages = {
1362
1787
  "doctor.check.meta_manually_diverged.message.hash.plural": "agents.meta.json \u4E2D\u6709 {count} \u4E2A entries \u7684 hash \u4E0E\u78C1\u76D8\u6587\u4EF6\u4E0D\u5339\u914D\u3002\u8FD0\u884C --fix \u6267\u884C reconcile\u3002",
1363
1788
  "doctor.check.meta_manually_diverged.remediation.hash": "\u9879\u76EE\u672C\u5730 agents.meta reconcile \u5DF2\u9000\u4F11\uFF1Bmounted stores \u662F source of truth\u3002",
1364
1789
  "doctor.check.meta_manually_diverged.ok.consistent": "agents.meta.json \u4E0E\u78C1\u76D8\u4E0A\u7684 rule files \u4E00\u81F4\u3002",
1365
- "doctor.check.knowledge_dir_unindexed.name": "Knowledge dir unindexed",
1790
+ "doctor.check.knowledge_dir_unindexed.name": "\u77E5\u8BC6\u76EE\u5F55\u672A\u7D22\u5F15",
1366
1791
  "doctor.check.knowledge_dir_unindexed.message.singular": "\u68C0\u6D4B\u5230 {count} \u4E2A legacy local knowledge .md file \u672A\u7D22\u5F15\u3002\u8BF7\u79FB\u5165 mounted store\uFF1B\u975E store knowledge root \u5DF2\u9000\u4F11\u3002",
1367
1792
  "doctor.check.knowledge_dir_unindexed.message.plural": "\u68C0\u6D4B\u5230 {count} \u4E2A legacy local knowledge .md files \u672A\u7D22\u5F15\u3002\u8BF7\u79FB\u5165 mounted store\uFF1B\u975E store knowledge root \u5DF2\u9000\u4F11\u3002",
1368
1793
  "doctor.check.knowledge_dir_unindexed.remediation": "\u4F7F\u7528 `fabric store bind` / `fabric store switch-write`\uFF0C\u7136\u540E\u628A knowledge \u8FC1\u5165 store \u7684 knowledge/ tree\u3002",
1369
1794
  "doctor.check.knowledge_dir_unindexed.ok": "\u65E0\u9700\u6267\u884C legacy local knowledge \u7D22\u5F15\u52A8\u4F5C\u3002",
1370
1795
  // v2.0.0-rc.33 W3-2 (T6 #27): 走 fabric-review modify 流程让 canonical id allocator 重新分配, 而非让用户自己选 id (易撞 counter, 难手算)。
1371
- "doctor.check.counter_desync.name": "Knowledge counter desync",
1796
+ "doctor.check.counter_desync.name": "\u77E5\u8BC6\u8BA1\u6570\u5668\u5931\u540C\u6B65",
1372
1797
  "doctor.check.counter_desync.message.singular": "{count} \u4E2A knowledge counter \u4E0E\u89C2\u6D4B\u5230\u7684 stable_ids \u4E0D\u540C\u6B65\u3002{counterPath} = {current}\uFF0C\u4F46\u68C0\u6D4B\u5230 {observedId}\u3002\u8FD0\u884C `fabric doctor --fix` bump counters\u3002",
1373
1798
  "doctor.check.counter_desync.message.plural": "{count} \u4E2A knowledge counters \u4E0E\u89C2\u6D4B\u5230\u7684 stable_ids \u4E0D\u540C\u6B65\u3002{counterPath} = {current}\uFF0C\u4F46\u68C0\u6D4B\u5230 {observedId}\u3002\u8FD0\u884C `fabric doctor --fix` bump counters\u3002",
1374
1799
  "doctor.check.counter_desync.remediation": "\u8FD0\u884C `fabric doctor --fix` \u5C06 agents.meta.json counters \u63D0\u5347\u5230\u89C2\u6D4B\u5230\u7684\u6700\u5927 counter \u503C\u3002",
1375
1800
  "doctor.check.counter_desync.ok": "agents.meta.json counters envelope \u4E0E\u89C2\u6D4B\u5230\u7684 stable_ids \u4E00\u81F4\u3002",
1376
- "doctor.check.store_counter_drift.name": "Store counter drift",
1801
+ "doctor.check.store_counter_drift.name": "Store \u8BA1\u6570\u5668\u6F02\u79FB",
1377
1802
  "doctor.check.store_counter_drift.message.singular": "{count} \u4E2A store counter \u4F4E\u4E8E\u78C1\u76D8\u4E0A\u7684\u6700\u5927 stable_id\uFF08{detail}\uFF09\u3002\u8BE5 store \u4E0B\u4E00\u6B21\u94F8\u53F7\u4F1A\u590D\u7528\u5DF2\u5B58\u5728\u7684 id\u3002\u8FD0\u884C `fabric doctor --fix` \u5C06 store counters.json \u63D0\u5347\u5230\u78C1\u76D8\u6700\u5927\u503C\u3002",
1378
1803
  "doctor.check.store_counter_drift.message.plural": "{count} \u4E2A store counter \u4F4E\u4E8E\u78C1\u76D8\u4E0A\u7684\u6700\u5927 stable_id\uFF08{detail}\uFF09\u3002\u8FD9\u4E9B store \u4E0B\u4E00\u6B21\u94F8\u53F7\u4F1A\u590D\u7528\u5DF2\u5B58\u5728\u7684 id\u3002\u8FD0\u884C `fabric doctor --fix` \u5C06 store counters.json \u63D0\u5347\u5230\u78C1\u76D8\u6700\u5927\u503C\u3002",
1379
1804
  "doctor.check.store_counter_drift.remediation": "\u8FD0\u884C `fabric doctor --fix` \u5C06\u6BCF\u4E2A store \u7684 counters.json \u63D0\u5347\uFF08floor\uFF09\u5230\u78C1\u76D8\u4E0A\u89C2\u6D4B\u5230\u7684\u6700\u5927 stable_id\uFF08floor \u53EA\u5347\u4E0D\u964D\u2014\u2014KT-DEC-0004 \u5355\u8C03\u4E0D\u53D8\u91CF\uFF09\u3002",
1380
1805
  "doctor.check.store_counter_drift.ok": "read-set \u5185\u6BCF\u4E2A store \u7684 counters.json \u90FD\u5DF2 floor \u5230\u78C1\u76D8\u6700\u5927 stable_id\u3002",
1381
- "doctor.check.store_orphan.name": "Store orphan",
1806
+ "doctor.check.store_orphan.name": "Store \u5B64\u513F",
1382
1807
  "doctor.check.store_orphan.message.singular": "{count} \u4E2A store \u5728\u78C1\u76D8\u4E0A\u5B58\u5728\u4F46\u672A\u767B\u8BB0\u5230\u5168\u5C40 registry\uFF08{detail}\uFF09\uFF0Crecall / bind \u90FD\u770B\u4E0D\u5230\u5B83\u3002\u8FD0\u884C `fabric doctor --fix` \u628A\u5B83\u6536\u7F16\uFF08\u91CD\u65B0\u767B\u8BB0\uFF0C\u7EDD\u4E0D\u5220\u9664\u78C1\u76D8\u6587\u4EF6\uFF09\u3002",
1383
1808
  "doctor.check.store_orphan.message.plural": "{count} \u4E2A store \u5728\u78C1\u76D8\u4E0A\u5B58\u5728\u4F46\u672A\u767B\u8BB0\u5230\u5168\u5C40 registry\uFF08\u9996\u4E2A\uFF1A{detail}\uFF09\uFF0Crecall / bind \u90FD\u770B\u4E0D\u5230\u5B83\u4EEC\u3002\u8FD0\u884C `fabric doctor --fix` \u628A\u5B83\u4EEC\u6536\u7F16\uFF08\u91CD\u65B0\u767B\u8BB0,\u7EDD\u4E0D\u5220\u9664\u78C1\u76D8\u6587\u4EF6\uFF09\u3002",
1384
1809
  "doctor.check.store_orphan.remediation": "\u8FD0\u884C `fabric doctor --fix` \u628A\u8FD9\u4E9B\u5B64\u513F store \u6536\u7F16\u8FDB registry(\u6309 store_uuid \u91CD\u65B0\u767B\u8BB0\u3001alias \u649E\u5E93\u81EA\u52A8\u6D88\u6B67;rescue-before-delete\u2014\u2014\u53EA\u767B\u8BB0\u4E0D\u5220\u76D8)\u3002",
1385
1810
  "doctor.check.store_orphan.ok": "~/.fabric/stores \u4E0B\u6CA1\u6709\u672A\u767B\u8BB0\u7684\u5B64\u513F store\u3002",
1386
- "doctor.check.preexisting_root_files.name": "Preexisting root markdown",
1811
+ // W2 (F-003): 项目注册表漂移 —— projects.json ↔ projects/ 文件夹树。
1812
+ "doctor.check.project_registry_drift.name": "\u9879\u76EE\u6CE8\u518C\u8868\u6F02\u79FB",
1813
+ "doctor.check.project_registry_drift.ok": "\u6BCF\u4E2A knowledge/projects/<id>/ \u6587\u4EF6\u5939\u90FD\u5DF2\u5728 projects.json \u6CE8\u518C,\u4E14\u6CA1\u6709\u5DF2\u6CE8\u518C\u6587\u4EF6\u5939\u4E3A\u7A7A\u3002",
1814
+ "doctor.check.project_registry_drift.message.unregistered": "{total} \u5904\u9879\u76EE\u6CE8\u518C\u8868\u6F02\u79FB:{breakdown}\u3002\u4F8B\u5982 store '{storeAlias}' \u7684 projects/{projectId}/ \u6709\u77E5\u8BC6\u6761\u76EE\u4F46\u672A\u5728 projects.json \u6CE8\u518C(\u5199\u5165\u672A\u8DEF\u7531)\u3002\u8FD0\u884C `fabric doctor --fix` \u8865\u767B\u8BB0(rescue-before-delete\u2014\u2014\u4ECE\u4E0D\u5220\u6587\u4EF6\u5939)\u3002",
1815
+ "doctor.check.project_registry_drift.message.orphan": "{total} \u5904\u9879\u76EE\u6CE8\u518C\u8868\u6F02\u79FB:{breakdown}\u3002\u4F8B\u5982 store '{storeAlias}' \u7684 projects/{projectId}/ \u78C1\u76D8\u5B58\u5728\u4F46\u672A\u5728 projects.json \u6CE8\u518C\u3002\u8FD0\u884C `fabric doctor --fix` \u8865\u767B\u8BB0(rescue\u2014\u2014\u4ECE\u4E0D\u5220\u6587\u4EF6\u5939)\u3002",
1816
+ "doctor.check.project_registry_drift.message.empty": "{total} \u5904\u9879\u76EE\u6CE8\u518C\u8868\u6F02\u79FB:{breakdown}\u3002\u4F8B\u5982 store '{storeAlias}' \u5DF2\u6CE8\u518C\u9879\u76EE '{projectId}' \u7684 projects/{projectId}/ \u6587\u4EF6\u5939\u4E3A\u7A7A(\u96F6\u6761\u76EE)\u3002\u8FD0\u884C `fabric doctor --fix` \u6E05\u7406\u7A7A\u6587\u4EF6\u5939\u3002",
1817
+ "doctor.check.project_registry_drift.remediation": "\u8FD0\u884C `fabric doctor --fix` \u5BF9\u8D26:orphan / \u672A\u6CE8\u518C\u5199\u5165\u7684\u6587\u4EF6\u5939\u4F1A\u88AB rescue-register \u8FDB projects.json(\u5373\u4F7F\u975E\u7A7A\u4E5F\u4ECE\u4E0D\u5220\u9664);\u4EC5\u771F\u6B63\u4E3A\u7A7A\u7684\u5DF2\u6CE8\u518C\u6587\u4EF6\u5939\u624D\u88AB\u6E05\u7406\u3002ghost \u6CE8\u518C(\u5DF2\u6CE8\u518C id \u4F46\u65E0\u6587\u4EF6\u5939)\u662F\u5408\u6CD5\u7684(lazy \u521B\u5EFA),\u65E0\u9700\u5904\u7406\u3002",
1818
+ "doctor.check.preexisting_root_files.name": "\u9884\u5B58\u6839\u76EE\u5F55 markdown",
1387
1819
  "doctor.check.preexisting_root_files.ok": "project root \u672A\u68C0\u6D4B\u5230 CLAUDE.md \u6216 AGENTS.md\u3002",
1388
1820
  "doctor.check.preexisting_root_files.message": "project root \u68C0\u6D4B\u5230 {files}\u3002\u8FD9\u4E9B root files \u4E0D\u4F1A\u88AB Fabric MCP \u81EA\u52A8\u52A0\u8F7D\u3002",
1389
1821
  "doctor.check.preexisting_root_files.remediation": "\u5982\u679C\u5E0C\u671B\u8FD9\u4E9B knowledge \u5185\u5BB9\u5728 MCP \u54CD\u5E94\u4E2D\u53EF\u7528\uFF0C\u8BF7\u5C06\u5176\u79FB\u52A8\u5230 mounted store \u7684 `knowledge/{type}/` tree\u3002",
1390
1822
  // v2.0.0-rc.33 W3-2 (T6 #34): 同 stable_id_collision — 走 fabric-review modify 让 allocator 分配新 id, 不让用户手算。
1391
1823
  // v2.0.0-rc.33 W3-2 (T6 #35): 加 skill 入口 (`/fabric-review modify <id>`) 让用户知道怎么 invoke。
1392
- "doctor.check.index_drift.name": "Knowledge index drift",
1824
+ "doctor.check.index_drift.name": "\u77E5\u8BC6\u7D22\u5F15\u6F02\u79FB",
1393
1825
  "doctor.check.index_drift.ok": "agents.meta.json counters envelope \u5BF9\u6BCF\u4E2A (layer, type) pair \u90FD\u5927\u4E8E\u6216\u7B49\u4E8E\u73B0\u6709 canonical counter \u6700\u5927\u503C\u3002",
1394
1826
  "doctor.check.index_drift.message.singular": "{count} \u4E2A (layer, type) counter slot \u5DF2\u4F4E\u4E8E\u89C2\u6D4B\u5230\u7684 canonical maximum\uFF08next allocate would collide\uFF09\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1395
1827
  "doctor.check.index_drift.message.plural": "{count} \u4E2A (layer, type) counter slots \u5DF2\u4F4E\u4E8E\u89C2\u6D4B\u5230\u7684 canonical maximum\uFF08next allocate would collide\uFF09\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1396
1828
  "doctor.check.index_drift.remediation": "\u8FD0\u884C `fabric doctor --fix-knowledge`\u5C06 agents.meta.json counters \u63D0\u5347\u5230 max_observed + 1\u3002",
1397
- "doctor.check.underseeded.name": "Knowledge underseeded",
1829
+ "doctor.check.underseeded.name": "\u77E5\u8BC6\u79CD\u5B50\u4E0D\u8DB3",
1398
1830
  "doctor.check.underseeded.ok": "\u77E5\u8BC6\u5E93\u5DF2\u6709 {count} \u4E2A canonical entries\uFF08>= {threshold}\uFF09\u3002",
1399
1831
  "doctor.check.underseeded.message.singular": "\u77E5\u8BC6\u5E93\u4EC5\u6709 {count} \u4E2A canonical entry\uFF08< {threshold} threshold\uFF09\u3002plan_context \u68C0\u7D22\u9762\u4F4E\u4E8E\u53EF\u7528\u4E0B\u9650\u3002",
1400
1832
  "doctor.check.underseeded.message.plural": "\u77E5\u8BC6\u5E93\u4EC5\u6709 {count} \u4E2A canonical entries\uFF08< {threshold} threshold\uFF09\u3002plan_context \u68C0\u7D22\u9762\u4F4E\u4E8E\u53EF\u7528\u4E0B\u9650\u3002",
1401
1833
  "doctor.check.underseeded.remediation": "\u8FD0\u884C fabric-archive skill \u7684 source mode\uFF08`/fabric-archive`\uFF09\u4ECE git history \u4E0E\u73B0\u6709\u6587\u6863\u56DE\u586B knowledge\u3002",
1402
- "doctor.check.session_hints_stale.name": "Knowledge session-hints stale",
1834
+ "doctor.check.session_hints_stale.name": "\u77E5\u8BC6 session-hints \u9648\u65E7",
1403
1835
  "doctor.check.session_hints_stale.ok": ".fabric/.cache/ \u4E0B\u6CA1\u6709\u8D85\u8FC7 {days} \u5929\u7684 session-hints cache files\u3002",
1404
1836
  "doctor.check.session_hints_stale.message.singular": ".fabric/.cache/ \u4E0B\u6709 {count} \u4E2A session-hints cache file \u8D85\u8FC7 {days} \u5929\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1405
1837
  "doctor.check.session_hints_stale.message.plural": ".fabric/.cache/ \u4E0B\u6709 {count} \u4E2A session-hints cache files \u8D85\u8FC7 {days} \u5929\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1406
1838
  "doctor.check.session_hints_stale.remediation": "\u8FD0\u884C `fabric doctor --fix-knowledge` \u5220\u9664\u8FC7\u671F\u7684 session-hints cache files\u3002",
1407
- "doctor.check.hook_cache_writable.name": "Hook cache writable",
1839
+ "doctor.check.hook_cache_writable.name": "Hook \u7F13\u5B58\u53EF\u5199",
1408
1840
  "doctor.check.hook_cache_writable.ok": "Hook sidecar cache \u8DEF\u5F84 {path} \u53EF\u5199\u5165\u63A2\u9488\u6587\u4EF6\u3002",
1409
1841
  "doctor.check.hook_cache_writable.message": "Hook sidecar cache \u8DEF\u5F84 {path} \u4E0D\u53EF\u5199\uFF1Bhook state updates \u4F1A\u9759\u9ED8\u5931\u8D25\u3002\u9519\u8BEF\uFF1A{error}\u3002",
1410
1842
  "doctor.check.hook_cache_writable.remediation": "\u6062\u590D {path} \u5199\u6743\u9650\uFF0C\u79FB\u9664\u5360\u7528\u8BE5\u8DEF\u5F84\u7684\u963B\u585E\u6587\u4EF6\uFF0C\u6216\u4FEE\u590D\u6587\u4EF6\u7CFB\u7EDF\u72B6\u6001\u540E\u91CD\u65B0\u8FD0\u884C `fabric install`\u3002",
1411
- "doctor.check.stale_serve_lock.name": "Serve lock",
1843
+ "doctor.check.stale_serve_lock.name": "Serve \u9501",
1412
1844
  "doctor.check.stale_serve_lock.ok.no_lock": "\u672A\u53D1\u73B0 .fabric/.serve.lock\u3002",
1413
1845
  "doctor.check.stale_serve_lock.ok.live_pid": ".fabric/.serve.lock \u7531 live PID {pid} \u6301\u6709\u3002",
1414
1846
  "doctor.check.stale_serve_lock.age.day.singular": "{count} \u5929\u524D",
@@ -1418,7 +1850,7 @@ var zhCNMessages = {
1418
1850
  "doctor.check.stale_serve_lock.message.dead_pid": "[advisory] .fabric/.serve.lock \u6301\u6709 dead PID {pid}\uFF08acquired {acquiredAgo}\uFF09\u3002\u8FD0\u884C `fabric doctor --fix` \u79FB\u9664\u3002",
1419
1851
  "doctor.check.stale_serve_lock.remediation.dead_pid": "\u8FD0\u884C `fabric doctor --fix` \u79FB\u9664\u8FC7\u671F\u7684 .fabric/.serve.lock\u3002",
1420
1852
  // rc.31 BUG-M3/NEW-4: hooks_wired observability.
1421
- "doctor.check.hooks_wired.name": "Claude Code hooks wired",
1853
+ "doctor.check.hooks_wired.name": "Claude Code hooks \u6CE8\u5165",
1422
1854
  "doctor.check.hooks_wired.ok.skipped": "\u9879\u76EE\u672A\u542F\u7528 Claude Code\uFF08\u65E0 .claude/ \u76EE\u5F55\uFF09\uFF1B\u8DF3\u8FC7 hooks_wired \u68C0\u67E5\u3002",
1423
1855
  "doctor.check.hooks_wired.ok.wired": ".claude/settings.json \u5DF2\u6CE8\u5165 Stop:fabric-hint / SessionStart:knowledge-hint-broad / PreToolUse:knowledge-hint-narrow \u4E09\u4E2A fabric hook\u3002",
1424
1856
  "doctor.check.hooks_wired.message.missing_settings": ".claude/ \u76EE\u5F55\u5B58\u5728\u4F46 .claude/settings.json \u7F3A\u5931\u6216\u65E0\u6CD5\u89E3\u6790\uFF1Bfabric install \u53EF\u80FD\u4ECE\u672A\u8DD1\u6210\u529F\uFF0C\u6216\u6587\u4EF6\u88AB\u5916\u90E8\u6E05\u7A7A\u3002",
@@ -1439,7 +1871,7 @@ var zhCNMessages = {
1439
1871
  "doctor.check.hooks_content_drift.message": "{count} \u4E2A hook basename \u5728 client \u4E4B\u95F4\u5185\u5BB9 drift\uFF1B\u9996\u4F8B\uFF1A{first_basename}\uFF08\u6D89\u53CA {first_clients}\uFF09\u3002`fabric install` \u590D\u5236\u540C\u4E00\u6A21\u677F\u5230\u4E09 client\uFF0Cdrift \u901A\u5E38\u6765\u81EA\u624B\u52A8\u7F16\u8F91\u3002",
1440
1872
  "doctor.check.hooks_content_drift.remediation": "\u8FD0\u884C `fabric install` \u628A\u6240\u6709 client \u7684 hook \u526F\u672C\u6062\u590D\u5230 canonical \u6A21\u677F\u3002\u82E5\u4F60\u786E\u5B9E\u9700\u8981 client-specific hook \u884C\u4E3A\uFF0C\u5EFA\u8BAE\u6539 lib/ \u5171\u4EAB\u811A\u672C\u6216 templates/hooks/configs/ \u914D\u7F6E\u800C\u975E\u76F4\u63A5\u7F16\u8F91\u5B89\u88C5\u540E\u7684 .cjs\u3002",
1441
1873
  // rc.31 BUG-G2/G5: promote-ledger invariant check.
1442
- "doctor.check.promote_ledger_invariant.name": "Promote ledger invariant",
1874
+ "doctor.check.promote_ledger_invariant.name": "\u664B\u5347\u8D26\u672C\u4E0D\u53D8\u91CF",
1443
1875
  "doctor.check.promote_ledger_invariant.ok": "knowledge_proposed={proposed} \u2265 knowledge_promote_started={started} \u2265 knowledge_promoted={promoted}\uFF0Cledger \u4E0D\u53D8\u91CF\u6301\u6709\u3002",
1444
1876
  "doctor.check.promote_ledger_invariant.message.proposed-lt-started": "knowledge_proposed={proposed} \u5C0F\u4E8E knowledge_promote_started={started}\uFF08ledger \u4E0D\u53D8\u91CF\u88AB\u7834\u574F\uFF1B\u90E8\u5206 pending \u5728 approve \u65F6\u672A\u7ECF\u8FC7 fab_propose \u2192 \u7F3A\u5C11 propose \u4E8B\u4EF6\uFF09\u3002",
1445
1877
  "doctor.check.promote_ledger_invariant.message.started-lt-promoted": "knowledge_promote_started={started} \u5C0F\u4E8E knowledge_promoted={promoted}\uFF08ledger \u4E0D\u53D8\u91CF\u88AB\u7834\u574F\uFF1B\u5B58\u5728\u672A\u914D\u5BF9\u7684 promoted \u4E8B\u4EF6\uFF0C\u53EF\u80FD\u6765\u81EA doctor filesystem-edit fallback \u6216\u5916\u90E8\u5199\u5165\uFF09\u3002",
@@ -1458,79 +1890,84 @@ var zhCNMessages = {
1458
1890
  "doctor.check.knowledge_summary_opaque.message.warn": "{opaque}/{total} \u4E2A entry ({pct}%) \u7684 description.summary \u7B49\u4E8E stable_id\uFF0C\u8D85\u8FC7 {threshold}% \u9608\u503C\u3002narrow hint \u8F93\u51FA\u4F1A\u53D8\u6210 `<id> \xB7 <id>` \u800C\u975E\u771F\u5B9E\u6982\u8981\uFF0CAI \u770B\u4E0D\u5230\u4FE1\u606F\u4F1A\u4E3B\u52A8\u8DF3\u8FC7 fetch\u3002\u9996\u6279\u4E0D\u900F\u660E: {sample}\u3002",
1459
1891
  "doctor.check.knowledge_summary_opaque.remediation": "\u8C03 fabric-review skill \u91CD\u5199\u4E0D\u900F\u660E summary \u4E3A\u4E00\u53E5\u4EBA\u7C7B\u53EF\u8BFB\u7684\u6982\u8981\u3002rc.35 hint renderer fallback (TASK-06) \u4E5F\u4F1A\u4ECE entry \u7684 `## Summary` \u6BB5\u81EA\u52A8\u5408\u6210\u4E34\u65F6 summary\u3002",
1460
1892
  // v2.2 W4 (G-GUARD / A6): store scope lint。
1461
- "doctor.check.store_scope_lint.name": "Store scope lint",
1893
+ "doctor.check.store_scope_lint.name": "Store scope \u68C0\u67E5",
1462
1894
  "doctor.check.store_scope_lint.ok": "read-set \u5185\u6240\u6709 store \u6761\u76EE scope \u5143\u6570\u636E\u9F50\u5907(semantic_scope + visibility_store,\u65E0 personal \u6CC4\u6F0F,\u65E0 dangling project)\u3002",
1463
1895
  "doctor.check.store_scope_lint.message": "{total} \u4E2A store scope \u95EE\u9898: {breakdown}\u3002\u4F8B\u5982 {sample}\u3002",
1464
1896
  "doctor.check.store_scope_lint.remediation": "\u8C03 `fabric store migrate backfill` \u8865\u7F3A\u5931\u7684 semantic_scope/visibility_store;`fabric store migrate scope` \u4FEE dangling \u7684 project: \u5750\u6807;\u628A personal-scope \u6761\u76EE\u79FB\u51FA shared store(personal \u77E5\u8BC6\u53EA\u5B58\u4E2A\u4EBA store,R5#3)\u3002",
1465
1897
  // v2.2 Goal B (G-INTEGRITY): store stable_id collision + layer mismatch lints。
1466
- "doctor.check.stable_id_collision.name": "Stable ID collision",
1898
+ "doctor.check.stable_id_collision.name": "Stable ID \u51B2\u7A81",
1467
1899
  "doctor.check.stable_id_collision.message.singular": 'stable_id "{stableId}" \u88AB\u58F0\u660E\u5728 {fileCount} \u4E2A\u6587\u4EF6\u4E2D:{files}\u3002\u8BF7\u7F16\u8F91\u5176\u4E2D\u4E00\u4E2A knowledge file,\u6539\u7528\u552F\u4E00 stable_id\u3002',
1468
1900
  "doctor.check.stable_id_collision.message.plural": '\u68C0\u6D4B\u5230 {count} \u4E2A stable_id collisions\u3002\u9996\u4E2A:"{stableId}" \u4F4D\u4E8E {files}\u3002\u8BF7\u7F16\u8F91\u5176\u4E2D\u4E00\u4E2A knowledge file,\u6539\u7528\u552F\u4E00 stable_id\u3002',
1469
1901
  "doctor.check.stable_id_collision.remediation": "\u8C03 `/fabric-review modify <message \u4E2D\u5217\u51FA\u7684 colliding id \u4E4B\u4E00>`, \u8BA9 canonical id allocator \u81EA\u52A8\u91CD\u5206\u914D id (\u4F1A\u540C\u6B65\u66F4\u65B0 frontmatter + counters + \u5386\u53F2 cross-ref)\u3002\u4E25\u7981\u624B\u5DE5\u7F16\u8F91 id frontmatter \u2014 \u4F1A\u649E counter\u3002",
1470
1902
  "doctor.check.stable_id_collision.ok": "mounted store knowledge \u4E2D\u672A\u53D1\u73B0\u5DF2\u58F0\u660E\u7684 stable_id collisions\u3002",
1471
- "doctor.check.layer_mismatch.name": "Knowledge layer mismatch",
1903
+ "doctor.check.layer_mismatch.name": "\u77E5\u8BC6 layer \u4E0D\u5339\u914D",
1472
1904
  "doctor.check.layer_mismatch.ok": "\u6240\u6709 canonical knowledge files \u90FD\u4F4D\u4E8E stable_id prefix \u58F0\u660E\u7684 layer \u4E0B\u3002",
1473
1905
  "doctor.check.layer_mismatch.message.singular": "{count} \u4E2A canonical knowledge file \u4E0E\u5176 stable_id layer prefix \u7684\u7269\u7406\u4F4D\u7F6E\u4E0D\u4E00\u81F4(KT-* must live under team/, KP-* under personal/)\u3002\u9996\u4E2A:{detail}\u3002",
1474
1906
  "doctor.check.layer_mismatch.message.plural": "{count} \u4E2A canonical knowledge files \u4E0E\u5176 stable_id layer prefix \u7684\u7269\u7406\u4F4D\u7F6E\u4E0D\u4E00\u81F4(KT-* must live under team/, KP-* under personal/)\u3002\u9996\u4E2A:{detail}\u3002",
1475
1907
  "doctor.check.layer_mismatch.remediation": "\u5C06\u6587\u4EF6\u79FB\u52A8\u5230\u6B63\u786E\u7684 write-target store,\u6216\u8C03 `/fabric-review modify <message \u4E2D\u5217\u51FA\u7684 id>` \u5207\u6362\u5176 layer (\u4F1A\u76F8\u5E94\u91CD\u547D\u540D stable_id prefix)\u3002",
1476
1908
  // v2.2 Goal B (G-RELEVANCE): store relevance_paths hygiene (dangling + drift)。
1477
- "doctor.check.relevance_paths_dangling.name": "Knowledge relevance_paths dangling",
1909
+ "doctor.check.relevance_paths_dangling.name": "\u77E5\u8BC6 relevance_paths \u60AC\u7A7A",
1478
1910
  "doctor.check.relevance_paths_dangling.ok": "\u6240\u6709 relevance_paths globs \u90FD\u80FD\u5728 workspace root \u4E0B\u89E3\u6790\u5230\u81F3\u5C11 1 \u4E2A\u6587\u4EF6\u3002",
1479
1911
  "doctor.check.relevance_paths_dangling.message.singular": "{count} \u4E2A relevance_paths glob \u5728\u5F53\u524D workspace \u4E2D\u89E3\u6790\u5230 0 \u4E2A\u6587\u4EF6\u3002\u9996\u4E2A:{detail}\u3002",
1480
1912
  "doctor.check.relevance_paths_dangling.message.plural": "{count} \u4E2A relevance_paths globs \u5728\u5F53\u524D workspace \u4E2D\u89E3\u6790\u5230 0 \u4E2A\u6587\u4EF6\u3002\u9996\u4E2A:{detail}\u3002",
1481
1913
  "doctor.check.relevance_paths_dangling.remediation": "\u66F4\u65B0 entry \u7684 relevance_paths,\u79FB\u9664\u4E0D\u518D\u5339\u914D\u4EFB\u4F55\u6587\u4EF6\u7684 globs,\u6216\u4F7F\u7528 `fab_review.modify` \u91CD\u5199 anchor set\u3002",
1482
- "doctor.check.relevance_paths_drift.name": "Knowledge relevance_paths drift",
1914
+ "doctor.check.relevance_paths_drift.name": "\u77E5\u8BC6 relevance_paths \u6F02\u79FB",
1483
1915
  "doctor.check.relevance_paths_drift.ok.skipped": "\u5DF2\u8DF3\u8FC7(git history unavailable;\u65E0\u6CD5\u8BC4\u4F30 {windowDays}d drift window)\u3002",
1484
1916
  "doctor.check.relevance_paths_drift.ok.fresh": "\u6240\u6709 narrow-scope canonical entries \u90FD\u81F3\u5C11\u6709 1 \u4E2A relevance_path \u5728\u6700\u8FD1 {windowDays}d \u5185\u88AB\u89E6\u78B0\u3002",
1485
1917
  "doctor.check.relevance_paths_drift.message.singular": "{count} \u4E2A narrow-scope canonical entry \u7684 relevance_paths globs \u6CA1\u6709\u5339\u914D\u5230\u6700\u8FD1 {windowDays}d git history \u4E2D\u89E6\u78B0\u8FC7\u7684\u6587\u4EF6\u3002\u9996\u4E2A:{detail}\u3002",
1486
1918
  "doctor.check.relevance_paths_drift.message.plural": "{count} \u4E2A narrow-scope canonical entries \u7684 relevance_paths globs \u6CA1\u6709\u5339\u914D\u5230\u6700\u8FD1 {windowDays}d git history \u4E2D\u89E6\u78B0\u8FC7\u7684\u6587\u4EF6\u3002\u9996\u4E2A:{detail}\u3002",
1487
1919
  "doctor.check.relevance_paths_drift.remediation": "\u5BA1\u9605\u8BE5 entry \u662F\u5426\u4ECD\u7136\u76F8\u5173 \u2014 \u4F7F\u7528 `fab_review.modify` \u5237\u65B0 anchors,\u6216\u4F7F\u7528 `fab_review.reject` \u5F52\u6863\u3002",
1488
1920
  // W4-3 (KT-MOD-0001): narrow scope 但 relevance_paths 为空。
1489
- "doctor.check.narrow_no_paths.name": "Knowledge narrow scope \u7F3A\u8DEF\u5F84",
1921
+ "doctor.check.narrow_no_paths.name": "\u77E5\u8BC6 narrow scope \u7F3A\u8DEF\u5F84",
1490
1922
  "doctor.check.narrow_no_paths.ok": "\u6BCF\u6761 narrow scope canonical entry \u90FD\u81F3\u5C11\u5E26\u4E00\u4E2A relevance_path\u3002",
1491
1923
  "doctor.check.narrow_no_paths.message.singular": "{count} \u6761 narrow scope entry \u7684 relevance_paths \u4E3A\u7A7A \u2014 \u6C38\u8FDC\u65E0\u6CD5\u8DEF\u5F84\u5339\u914D,\u56E0\u6B64\u6C38\u4E0D\u6D6E\u51FA(\u6B7B\u6761\u76EE)\u3002\u9996\u6761: {detail}\u3002",
1492
1924
  "doctor.check.narrow_no_paths.message.plural": "{count} \u6761 narrow scope entry \u7684 relevance_paths \u4E3A\u7A7A \u2014 \u6C38\u8FDC\u65E0\u6CD5\u8DEF\u5F84\u5339\u914D,\u56E0\u6B64\u6C38\u4E0D\u6D6E\u51FA(\u6B7B\u6761\u76EE)\u3002\u9996\u6761: {detail}\u3002",
1493
1925
  "doctor.check.narrow_no_paths.remediation": "\u7528 `fab_review.modify` \u8865 relevance_paths glob \u951A\u5B9A\u8BE5 entry,\u6216\u82E5\u672C\u610F\u662F\u5E38\u9A7B\u5219\u628A relevance_scope \u6539\u4E3A `broad`\u3002",
1494
1926
  // W4-2 (KT-DEC-0028): 单 store broad 索引接近 backstop。
1495
- "doctor.check.broad_index_drift.name": "Knowledge broad \u7D22\u5F15\u6F02\u79FB",
1927
+ "doctor.check.broad_index_drift.name": "\u77E5\u8BC6 broad \u7D22\u5F15\u6F02\u79FB",
1496
1928
  "doctor.check.broad_index_drift.ok": "\u6CA1\u6709 store \u7684 broad scope \u6761\u76EE\u6570\u8FBE\u5230\u6F02\u79FB\u9608\u503C({threshold},backstop {backstop} \u7684 80%)\u3002",
1497
1929
  "doctor.check.broad_index_drift.message.singular": "{count} \u4E2A store \u7684 broad \u7D22\u5F15\u5DF2\u8FBE {threshold}(backstop {backstop} \u7684 80%) \u2014 SessionStart banner \u63A5\u8FD1\u622A\u65AD broad \u6761\u76EE\u3002\u9996\u6761: {detail}\u3002",
1498
1930
  "doctor.check.broad_index_drift.message.plural": "{count} \u4E2A store \u7684 broad \u7D22\u5F15\u5DF2\u8FBE {threshold}(backstop {backstop} \u7684 80%) \u2014 SessionStart banner \u63A5\u8FD1\u622A\u65AD broad \u6761\u76EE\u3002\u9996\u6761: {detail}\u3002",
1499
1931
  "doctor.check.broad_index_drift.remediation": "\u8DD1 `fabric-review` skill \u7684 retire \u5B50\u6D41\u7A0B\u5728\u544A\u8B66 store \u5185 prune/\u964D\u7EA7\u9648\u65E7 broad \u6761\u76EE,\u6216\u82E5\u8BED\u6599\u786E\u5B9E\u5927\u5219\u5728 .fabric/fabric-config.json \u8C03\u9AD8 `broad_index_backstop`\u3002",
1500
1932
  // v2.2 Goal B (G-AGE): knowledge decay lints (orphan_demote + stale_archive)。
1501
- "doctor.check.orphan_demote.name": "Knowledge orphan demote",
1933
+ "doctor.check.orphan_demote.name": "\u77E5\u8BC6\u5B64\u513F\u964D\u7EA7",
1502
1934
  "doctor.check.orphan_demote.ok": "\u6CA1\u6709 canonical knowledge entries \u8D85\u8FC7\u6309 maturity \u8BBE\u5B9A\u7684 inactivity threshold\u3002",
1503
1935
  "doctor.check.orphan_demote.message.singular": "{count} \u4E2A canonical knowledge entry \u8D85\u8FC7\u6309 maturity \u8BBE\u5B9A\u7684 inactivity threshold(proven={provenDays}d / verified={verifiedDays}d / draft={draftDays}d)\u3002\u9996\u4E2A:{detail}\u3002",
1504
1936
  "doctor.check.orphan_demote.message.plural": "{count} \u4E2A canonical knowledge entries \u8D85\u8FC7\u6309 maturity \u8BBE\u5B9A\u7684 inactivity threshold(proven={provenDays}d / verified={verifiedDays}d / draft={draftDays}d)\u3002\u9996\u4E2A:{detail}\u3002",
1505
1937
  "doctor.check.orphan_demote.remediation": "\u901A\u8FC7 `/fabric-review modify <id>` \u5C06\u8BE5 entry \u964D\u7EA7\u4E00\u4E2A maturity tier,\u6216\u91CD\u65B0\u4F7F\u7528\u5B83\u4EE5\u8BB0\u5F55\u65B0\u6D3B\u52A8\u3002(\u6539\u5199 store \u77E5\u8BC6\u662F store \u5199\u4FA7\u6D41\u7A0B\u7684\u804C\u8D23 \u2014 \u8FD9\u4E2A\u8BFB\u4FA7 lint \u53EA\u8D1F\u8D23\u66B4\u9732\u8870\u51CF\u3002)",
1506
- "doctor.check.stale_archive.name": "Knowledge stale archive",
1938
+ "doctor.check.stale_archive.name": "\u77E5\u8BC6\u9648\u65E7\u5F52\u6863",
1507
1939
  "doctor.check.stale_archive.ok": "\u6CA1\u6709 draft knowledge entries \u8D85\u8FC7\u989D\u5916\u7684 stale-archive quiet window\u3002",
1508
1940
  "doctor.check.stale_archive.message.singular": "{count} \u4E2A draft knowledge entry \u5DF2\u8D85\u8FC7 demote+{additionalDays}d \u989D\u5916 quiet window\u3002\u9996\u4E2A:{detail}\u3002",
1509
1941
  "doctor.check.stale_archive.message.plural": "{count} \u4E2A draft knowledge entries \u5DF2\u8D85\u8FC7 demote+{additionalDays}d \u989D\u5916 quiet window\u3002\u9996\u4E2A:{detail}\u3002",
1510
1942
  "doctor.check.stale_archive.remediation": "\u901A\u8FC7 `/fabric-review reject <id>` \u5F52\u6863\u8BE5 stale draft,\u6216\u82E5\u4ECD\u76F8\u5173\u5219\u590D\u6D3B\u5B83\u3002(\u79FB\u52A8 store \u6587\u4EF6\u662F store \u5199\u4FA7\u6D41\u7A0B\u7684\u804C\u8D23 \u2014 \u8FD9\u4E2A\u8BFB\u4FA7 lint \u53EA\u8D1F\u8D23\u66B4\u9732\u9648\u65E7\u3002)",
1511
1943
  // v2.2 C1: knowledge promotion lint (promotion_candidate, info kind)。
1512
- "doctor.check.promotion_candidate.name": "Knowledge promotion candidate",
1944
+ "doctor.check.promotion_candidate.name": "\u77E5\u8BC6\u664B\u5347\u5019\u9009",
1513
1945
  "doctor.check.promotion_candidate.ok": "\u6CA1\u6709 verified knowledge entries \u8FBE\u5230 proven \u664B\u5347\u7684 related \u5165\u5EA6\u95E8\u69DB\u3002",
1514
1946
  "doctor.check.promotion_candidate.message.singular": "{count} \u4E2A verified knowledge entry \u7684 related \u5165\u5EA6 \u2265{threshold},\u7ED3\u6784\u4E0A\u591F\u4E2D\u5FC3,\u503C\u5F97 review \u664B\u5347\u5230 proven\u3002\u9996\u4E2A:{detail}\u3002",
1515
1947
  "doctor.check.promotion_candidate.message.plural": "{count} \u4E2A verified knowledge entries \u7684 related \u5165\u5EA6 \u2265{threshold},\u7ED3\u6784\u4E0A\u591F\u4E2D\u5FC3,\u503C\u5F97 review \u664B\u5347\u5230 proven\u3002\u9996\u4E2A:{detail}\u3002",
1516
1948
  "doctor.check.promotion_candidate.remediation": "\u901A\u8FC7 `/fabric-review` \u590D\u6838\u8FD9\u4E9B entry,\u786E\u8BA4 0 dismiss\u3001cold-eval \u81EA\u8DB3\u3001\u5C5E\u5730\u57FA\u7EA7\u540E `modify <id>` \u5347\u5230 proven\u3002(\u664B\u5347\u5224\u5B9A\u662F store \u5199\u4FA7 review \u7684\u804C\u8D23 \u2014 \u8FD9\u4E2A\u8BFB\u4FA7 lint \u53EA surface \u7ED3\u6784\u4E2D\u5FC3\u7684\u5019\u9009\u3002)",
1517
1949
  // v2.2 C1: broad review-recheck lint (broad_review_recheck, info kind)。
1518
- "doctor.check.broad_review_recheck.name": "Knowledge broad review recheck",
1950
+ "doctor.check.broad_review_recheck.name": "\u77E5\u8BC6 broad review \u590D\u67E5",
1519
1951
  "doctor.check.broad_review_recheck.ok": "\u6CA1\u6709 broad-scope knowledge entries \u8D85\u671F\u672A\u505A review \u518D\u786E\u8BA4\u3002",
1520
1952
  "doctor.check.broad_review_recheck.message.singular": "{count} \u4E2A broad-scope knowledge entry \u5DF2 {thresholdDays}d+ \u6CA1\u7ECF\u8FC7 fab-review \u518D\u786E\u8BA4,\u503C\u5F97\u590D\u67E5(broad \u8C41\u514D usage-age \u964D\u7EA7,\u8FD9\u662F\u5B83\u7684 review \u65F6\u949F)\u3002\u9996\u4E2A:{detail}\u3002",
1521
1953
  "doctor.check.broad_review_recheck.message.plural": "{count} \u4E2A broad-scope knowledge entries \u5DF2 {thresholdDays}d+ \u6CA1\u7ECF\u8FC7 fab-review \u518D\u786E\u8BA4,\u503C\u5F97\u590D\u67E5(broad \u8C41\u514D usage-age \u964D\u7EA7,\u8FD9\u662F\u5B83\u7684 review \u65F6\u949F)\u3002\u9996\u4E2A:{detail}\u3002",
1522
1954
  "doctor.check.broad_review_recheck.remediation": "\u901A\u8FC7 `/fabric-review` \u518D\u786E\u8BA4\u6BCF\u6761(approve/modify \u4F1A\u76D6\u4E00\u4E2A\u65B0\u7684 review \u65F6\u95F4\u6233),\u6216\u82E5\u4E0D\u518D\u6210\u7ACB\u5219\u964D\u7EA7/\u9A73\u56DE\u3002\u8FD9\u662F\u975E\u963B\u585E\u63D0\u793A,\u7EDD\u4E0D\u81EA\u52A8\u964D\u7EA7 \u2014 broad \u77E5\u8BC6\u5728 reviewer \u52A8\u624B\u524D\u6301\u7EED surface\u3002",
1523
1955
  // project-scope binding 回填 lint (unbound_project)。
1524
- "doctor.check.unbound_project.name": "Project-scope binding",
1956
+ "doctor.check.unbound_project.name": "Project-scope \u7ED1\u5B9A",
1525
1957
  "doctor.check.unbound_project.ok": "\u5DF2\u7ED1\u5199\u5165 store \u5E26\u6709 project \u5750\u6807(project_id + active_project),project-scope \u7684 recall/\u5199\u5165\u8DEF\u7531\u6B63\u5E38\u3002",
1526
1958
  "doctor.check.unbound_project.message": "store '{alias}' \u5DF2\u7ED1\u4E3A\u5199\u5165\u76EE\u6807\u4F46 project \u5750\u6807\u4E0D\u5B8C\u6574(\u7F3A {missing});project-scope \u7684 recall/\u5199\u5165\u4F1A fallback \u5230 team scope\u3002",
1527
1959
  "doctor.check.unbound_project.remediation": "\u8C03 `fabric doctor --fix` \u56DE\u586B project \u7ED1\u5B9A(\u94F8 project_id\u3001\u628A project \u6CE8\u518C\u8FDB store\u3001\u8BBE active_project)\u3002\u5E42\u7B49 \u2014\u2014 \u4E8C\u6B21\u8DD1\u4E3A no-op\u3002",
1960
+ // write_route_target_unbound — 单 team 槽迁移后 write_routes 悬空的静态检查。
1961
+ "doctor.check.write_route_target_unbound.name": "\u5199\u5165\u8DEF\u7531\u76EE\u6807",
1962
+ "doctor.check.write_route_target_unbound.ok": "\u6240\u6709 write_routes \u7684\u76EE\u6807 store \u90FD\u5728 required_stores \u5185,scope\u2192store \u8DEF\u7531\u9759\u6001\u4E00\u81F4\u3002",
1963
+ "doctor.check.write_route_target_unbound.message": '{count} \u6761 write_route \u6307\u5411\u672A\u7ED1\u5B9A\u7684 store({routes});fab_propose \u5728\u8FD9\u4E9B scope \u4E0A\u4F1A\u62A5 "no write-target store resolved"\u3002',
1964
+ "doctor.check.write_route_target_unbound.remediation": "\u4E8C\u9009\u4E00:\u2460 `fabric store bind <store>` \u628A\u76EE\u6807 store \u52A0\u8FDB required_stores(\u5355 team \u69FD = \u9700\u66FF\u6362\u6389\u5F53\u524D\u7684),\u6216 \u2461 \u7F16\u8F91 `.fabric/fabric-config.json` \u5220\u6389\u8FD9\u6761 write_route\u3002",
1528
1965
  "doctor.check.skill_md_yaml_invalid.name": "Skill markdown YAML",
1529
1966
  "doctor.check.skill_md_yaml_invalid.ok": "\u6240\u6709 .claude/.codex SKILL.md frontmatter values \u90FD\u80FD\u6309 strict YAML \u89E3\u6790\u3002",
1530
1967
  "doctor.check.skill_md_yaml_invalid.message.singular": "{count} \u4E2A SKILL.md frontmatter value \u5305\u542B\u672A\u52A0\u5F15\u53F7\u7684 ': '\uFF0Cstrict YAML parsers \u4F1A\u62D2\u7EDD\uFF08Claude Code tolerates it\uFF1BCodex CLI drops the skill at load\uFF09\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1531
1968
  "doctor.check.skill_md_yaml_invalid.message.plural": "{count} \u4E2A SKILL.md frontmatter values \u5305\u542B\u672A\u52A0\u5F15\u53F7\u7684 ': '\uFF0Cstrict YAML parsers \u4F1A\u62D2\u7EDD\uFF08Claude Code tolerates it\uFF1BCodex CLI drops the skill at load\uFF09\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1532
1969
  "doctor.check.skill_md_yaml_invalid.remediation": '\u4F7F\u7528\u53CC\u5F15\u53F7\u5305\u88F9\u8BE5 value\uFF08`description: "\u2026"`\uFF09\uFF0C\u6216\u5C06\u5185\u90E8\u7684 `key: value` token \u6539\u5199\u4E3A `key=value`\u3002',
1533
- "doctor.check.onboard_coverage.name": "Onboard coverage",
1970
+ "doctor.check.onboard_coverage.name": "Onboard \u8986\u76D6\u7387",
1534
1971
  "doctor.check.onboard_coverage.ok.complete": "Onboard coverage\uFF1A{filledCount}/{total} \u2713\uFF08opted-out\uFF1A{optedOutCount}\uFF09\u3002",
1535
1972
  "doctor.check.onboard_coverage.message.incomplete": "\u5C1A\u672A\u8986\u76D6\u7684 onboard slots\uFF1A[{missingSlots}]\u3002{filledCount}/{total} filled\uFF1B{optedOutCount} opted-out\u3002",
1536
1973
  "doctor.check.onboard_coverage.remediation.incomplete": "\u8FD0\u884C /fabric-archive \u6267\u884C onboard \u2014 Skill's first-run phase \u4F1A\u904D\u5386\u9879\u76EE\uFF0C\u5E76\u4E3A\u6BCF\u4E2A unclaimed slot \u63D0\u8BAE pending entries\u3002",
@@ -1550,13 +1987,17 @@ var zhCNMessages = {
1550
1987
  "cli.doctor.errors.invalid-history-mode": "\u65E0\u6548\u7684 --history mode '{input}'\u3002\u53EF\u9009: archive | fix | all\u3002",
1551
1988
  "doctor.history.header": "Doctor \u5386\u53F2 (mode={mode}, \u8FD1 {sinceLabel}, \u5171 {days} \u5929)",
1552
1989
  "doctor.history.empty": "--since={sinceLabel} \u7A97\u53E3\u5185\u65E0 doctor \u6216 archive \u6D3B\u52A8 (mode={mode})\u3002",
1553
- "cli.install.description": "\u5728\u76EE\u6807\u9879\u76EE\u4E2D\u5B89\u88C5 Fabric\uFF08\u811A\u624B\u67B6 .fabric/\u3001bootstrap \u6A21\u677F\u3001MCP \u5BA2\u6237\u7AEF\u914D\u7F6E\u3001git hooks\uFF09\u3002\n\n\u793A\u4F8B\uFF1A\n fabric install \u5728\u5F53\u524D\u9879\u76EE\u4E2D\u4EE5\u4EA4\u4E92\u6A21\u5F0F\u5B89\u88C5\n fabric install --yes \u63A5\u53D7\u9ED8\u8BA4\u503C\uFF0C\u8DF3\u8FC7 TTY \u5411\u5BFC\n fabric install --dry-run \u4EC5\u9884\u89C8\u5B89\u88C5\u8BA1\u5212\uFF0C\u4E0D\u5199\u5165\u6587\u4EF6",
1990
+ "cli.install.description": "\u5728\u76EE\u6807\u9879\u76EE\u4E2D\u5B89\u88C5 Fabric\uFF08\u811A\u624B\u67B6 .fabric/\u3001bootstrap \u6A21\u677F\u3001MCP \u5BA2\u6237\u7AEF\u914D\u7F6E\u3001git hooks\uFF09",
1554
1991
  "cli.install.args.target.description": "\u76EE\u6807\u9879\u76EE\u8DEF\u5F84\u3002\u9ED8\u8BA4\u4F9D\u6B21\u4F7F\u7528 --target\u3001EXTERNAL_FIXTURE_PATH\u3001\u5F53\u524D\u76EE\u5F55\u3002",
1555
1992
  "cli.install.args.debug.description": "\u5C06\u76EE\u6807\u89E3\u6790\u7EC6\u8282\u8F93\u51FA\u5230 stderr\u3002",
1556
1993
  "cli.install.args.yes.description": "\u63A5\u53D7\u5F53\u524D\u5B89\u88C5\u8BA1\u5212\u5E76\u8DF3\u8FC7 TTY \u5411\u5BFC\u76F4\u63A5\u6267\u884C",
1557
1994
  "cli.install.args.dry-run.description": "\u4EC5\u8F93\u51FA\u5B89\u88C5\u8BA1\u5212\uFF0C\u4E0D\u5199\u6587\u4EF6\u4E5F\u4E0D\u6267\u884C\u540E\u7EED\u9636\u6BB5",
1558
1995
  "cli.install.args.enable-embed.description": "\u542F\u7528\u5411\u91CF\u8BED\u4E49\u641C\u7D22 (\u8BBE embed_enabled + embed_model;\u6253\u5370 fastembed \u5B89\u88C5\u6B65\u9AA4)",
1559
1996
  "cli.install.args.embed-model.description": "\u914D\u5408 --enable-embed:\u8986\u76D6\u56FA\u5B9A\u7684 embed \u6A21\u578B (\u9ED8\u8BA4 fast-bge-small-zh-v1.5)",
1997
+ "cli.install.args.global.description": "\u914D\u7F6E\u5168\u5C40 Fabric (~/.fabric:uid + personal store + \u914D\u7F6E)",
1998
+ "cli.install.args.url.description": "\u514B\u9686\u5E76\u6302\u8F7D\u4E00\u4E2A\u5171\u4EAB store \u8FDC\u7A0B\u5E93\u3002\u9879\u76EE\u5B89\u88C5\u65F6:\u540C\u65F6\u7ED1\u5B9A\u5230\u672C\u9879\u76EE\u5E76\u8BBE\u4E3A\u5199\u5165\u76EE\u6807\u3002\u914D\u5408 --global:\u4EC5\u6302\u8F7D\u5230\u672C\u673A\u3002",
1999
+ // TASK-004: --verbose 展开重装折叠的逐 phase 明细 + 完整客户端能力表。
2000
+ "cli.install.args.verbose.description": "\u5C55\u5F00\u5B8C\u6574\u660E\u7EC6:\u91CD\u88C5\u5E42\u7B49\u65F6\u4E0D\u6298\u53E0\u4E3A\u4F53\u68C0\u5361\u7247,\u5E76\u6253\u5370\u9010\u5BA2\u6237\u7AEF\u80FD\u529B\u8868",
1560
2001
  // rc.35 TASK-08 (P0-5/6): --force-skills-only。
1561
2002
  "cli.install.args.force-skills-only.description": "\u8DF3\u8FC7 bootstrap / MCP / hooks / settings,\u53EA\u91CD\u65B0\u5237\u65B0 fabric Skill \u6A21\u677F (.claude/.codex/skills/*)\u3002",
1562
2003
  "cli.install.force-skills-only.banner": "\u53EA\u5237\u65B0 fabric Skill \u6A21\u677F",
@@ -1585,7 +2026,30 @@ var zhCNMessages = {
1585
2026
  "cli.install.steps.bootstrap-claude": "\u5DF2\u66F4\u65B0 CLAUDE.md \u7684 @-import \u5F15\u7528",
1586
2027
  "cli.install.steps.bootstrap-codex": "\u5DF2\u66F4\u65B0 AGENTS.md \u7684 fabric:bootstrap managed block",
1587
2028
  "cli.install.stages.mcp": "\u6B63\u5728\u914D\u7F6E MCP \u5BA2\u6237\u7AEF...",
1588
- "cli.install.stages.hooks": "\u6B63\u5728\u5B89\u88C5 git hooks...",
2029
+ "cli.install.stages.hooks": "\u6B63\u5728\u5B89\u88C5 hook \u4E0E skill...",
2030
+ "cli.install.preflight.error.no-home": "\u65E0\u6CD5\u786E\u5B9A global root \u7684 home \u76EE\u5F55",
2031
+ "cli.install.preflight.error.not-dir": "\u5168\u5C40 Fabric root \u4E0D\u662F\u76EE\u5F55: {path}",
2032
+ "cli.install.preflight.error.parent-not-dir": "\u5168\u5C40 Fabric root \u7684\u7236\u76EE\u5F55\u4E0D\u662F\u76EE\u5F55: {path}",
2033
+ "cli.install.preflight.error.not-writable": "{label} \u4E0D\u53EF\u5199: {path} ({reason})",
2034
+ "cli.install.preflight.error.git-required": "--url \u5B89\u88C5\u9700\u8981 git,\u4F46\u5F53\u524D\u4E0D\u53EF\u7528: {reason}",
2035
+ "cli.install.preflight.label.target": "\u76EE\u6807\u76EE\u5F55",
2036
+ "cli.install.preflight.label.global-root": "\u5168\u5C40 Fabric root",
2037
+ "cli.install.preflight.label.global-root-parent": "\u5168\u5C40 Fabric root \u7684\u7236\u76EE\u5F55",
2038
+ "cli.install.guidance.more": "\u66F4\u591A: docs/surfaces.md \u8BF4\u660E\u4F55\u65F6\u7528 CLI / Skill / MCP\u3002",
2039
+ "cli.install.validate.passed": "\u5B89\u88C5\u6821\u9A8C\u901A\u8FC7 \u2713(config / hooks \u8DEF\u5F84 / events \u5747\u5C31\u7EEA)",
2040
+ "cli.install.validate.failed": "\u5B89\u88C5\u6821\u9A8C\u5931\u8D25:{count} \u4E2A\u95EE\u9898",
2041
+ "cli.install.validate.failed-item": " - {error}",
2042
+ "cli.install.hooks.uptodate": "hook \u4E0E skill \u5DF2\u6700\u65B0,\u65E0\u9700\u6539\u52A8({count} \u9879)",
2043
+ "cli.install.hooks.installed": "\u5DF2\u88C5 skill\xD7{skills} + hook\xD7{hooks}",
2044
+ "cli.install.mcp.configured": "\u5DF2\u914D\u7F6E MCP:{clients}",
2045
+ "cli.install.mcp.none": "\u65E0\u9700\u914D\u7F6E MCP \u5BA2\u6237\u7AEF",
2046
+ "cli.install.scan.finding.framework": "\u68C0\u6D4B\u5230: {framework} \u9879\u76EE",
2047
+ "cli.install.scan.finding.scale": "\u89C4\u6A21: {files} \u6587\u4EF6 \xB7 {entries} \u4E2A\u5165\u53E3",
2048
+ // flat-design: 扫描结果合成一行人话(框架 + 规模);版本为 unknown 时隐去,
2049
+ // 没识别出框架时退到 plain。
2050
+ "cli.install.scan.summary.framework": "\u68C0\u6D4B\u5230 {framework} \u9879\u76EE \xB7 {files} \u6587\u4EF6 \xB7 {entries} \u5165\u53E3",
2051
+ "cli.install.scan.summary.plain": "\u626B\u63CF\u5B8C\u6210 \xB7 {files} \u6587\u4EF6 \xB7 {entries} \u5165\u53E3",
2052
+ "cli.install.rollback.feedback": "\u5DF2\u56DE\u6EDA {count} \u9879\u6539\u52A8,\u9879\u76EE\u4FDD\u6301\u539F\u72B6\u3002",
1589
2053
  "cli.install.stages.skipped": "\u5DF2\u8DF3\u8FC7",
1590
2054
  "cli.install.stages.completed": "\u5DF2\u5B8C\u6210",
1591
2055
  "cli.install.stages.failed": "\u5931\u8D25",
@@ -1595,15 +2059,43 @@ var zhCNMessages = {
1595
2059
  "cli.install.pipeline.title": "Fabric \u5B89\u88C5",
1596
2060
  "cli.install.pipeline.complete": "Fabric \u5B89\u88C5\u5B8C\u6210",
1597
2061
  "cli.install.pipeline.running": "\u5C06\u6309 {count} \u4E2A\u9636\u6BB5\u6267\u884C",
1598
- "cli.install.pipeline.label.preflight": "\u5168\u5C40\u4E0E\u9879\u76EE\u9884\u68C0",
1599
- "cli.install.pipeline.label.env": "\u9879\u76EE\u73AF\u5883\u521D\u59CB\u5316",
1600
- "cli.install.pipeline.label.store": "\u77E5\u8BC6\u5E93\u62D3\u6251",
1601
- "cli.install.pipeline.label.hooks": "Hook \u4E0E skill \u5B89\u88C5",
1602
- "cli.install.pipeline.label.mcp": "MCP \u670D\u52A1\u914D\u7F6E",
2062
+ // TASK-002 (G1):总结卡收尾 + 计数词。原先在 ConsoleOutputRenderer 中硬编码英文
2063
+ // (Done! / succeeded / skipped / failed / "All steps completed successfully"),
2064
+ // 全部收进 t() + 双语表,locale-parity.test.ts 守护 en + zh-CN 每个 key 齐备。
2065
+ "cli.summary.done": "\u5B8C\u6210!",
2066
+ "cli.summary.all-ok": "\u5168\u90E8\u6B65\u9AA4\u5DF2\u5B8C\u6210",
2067
+ "cli.summary.n-failed": "{count} \u4E2A\u6B65\u9AA4\u5931\u8D25",
2068
+ "cli.summary.all-resolved": "\u5168\u90E8\u5DF2\u5904\u7406 \xB7 {done} \u6267\u884C / {skipped} \u8DF3\u8FC7",
2069
+ "cli.summary.count.succeeded": "\u6210\u529F",
2070
+ "cli.summary.count.skipped": "\u8DF3\u8FC7",
2071
+ "cli.summary.count.failed": "\u5931\u8D25",
2072
+ // TASK-004: 首装走 onboarding 定调(欢迎语 + 一次性设置说明);重装保持简洁的
2073
+ // "将按 N 阶段执行"。{count} = 阶段总数。
2074
+ "cli.install.pipeline.intro.firstRun": "\u6B22\u8FCE\u4F7F\u7528 Fabric \u2014\u2014 \u8FD9\u662F\u9996\u6B21\u5B89\u88C5,\u6211\u4F1A\u5F15\u5BFC\u4F60\u5B8C\u6210\u4E00\u6B21\u6027\u8BBE\u7F6E(\u5171 {count} \u4E2A\u9636\u6BB5);\u4E4B\u540E\u518D\u8DD1\u4F1A\u81EA\u52A8\u8DF3\u8FC7\u5DF2\u5C31\u7EEA\u9879\u3002",
2075
+ // TASK-004: 重装且全程幂等(无任何 install)时折叠成的单张体检卡片标题。
2076
+ // {count} = 阶段总数。明细走 --verbose。
2077
+ "cli.install.healthcheck.title": "\u2713 Fabric \u5DF2\u662F\u6700\u65B0 \xB7 {count} \u9636\u6BB5\u5C31\u7EEA \xB7 \u65E0\u6539\u52A8",
2078
+ // TASK-003 (G2 root a):每阶段总结明细的状态词改按 r.changed 判定(不再用
2079
+ // installed.length)—— 无改动的重装走"已最新",不再误报"N 项已安装"。
2080
+ // installed-count 仅在该阶段确有改动时使用。
2081
+ "cli.install.stage.uptodate": "\u5DF2\u6700\u65B0",
2082
+ "cli.install.stage.installed-count": "{count} \u9879\u5DF2\u5B89\u88C5",
2083
+ // flat-design: 阶段标签收短,让 `● 名称 ✓` 列对齐、读着清爽(原全称偏长)。
2084
+ "cli.install.pipeline.label.preflight": "\u73AF\u5883\u9884\u68C0",
2085
+ "cli.install.pipeline.label.env": "\u73AF\u5883\u521D\u59CB\u5316",
2086
+ "cli.install.pipeline.label.store": "\u77E5\u8BC6\u5E93",
2087
+ "cli.install.pipeline.label.hooks": "Hook \u4E0E skill",
2088
+ "cli.install.pipeline.label.mcp": "MCP \u670D\u52A1",
1603
2089
  "cli.install.pipeline.label.validate": "\u5B89\u88C5\u6821\u9A8C",
1604
2090
  "cli.install.pipeline.label.guidance": "\u540E\u7EED\u6307\u5F15",
1605
2091
  "cli.install.pipeline.desc.store": "\u7ED1\u5B9A\u5F53\u524D\u9879\u76EE\u7684 read/write store\uFF0C\u5237\u65B0 resolved-bindings snapshot\u3002",
1606
2092
  "cli.install.next-step": "{label} {message}",
2093
+ // TASK-002 (G6): 收口总结卡的单一黄金动作锚点。能力明细表收进 --verbose,
2094
+ // 这一行才是诚实的「下一步做什么」。{action} = 具体下一条命令。
2095
+ "cli.install.next-step.anchor": "\u4E0B\u4E00\u6B65 \u2192 {action}",
2096
+ // flat-design (G6): 装完最该做的事是重启客户端让 MCP 生效 —— 这才是默认锚点动作;
2097
+ // --reapply 维护提示退到 --verbose。
2098
+ "cli.install.next-step.restart": "\u91CD\u542F\u5DF2\u5F00\u7684 Claude Code / Codex \u4F1A\u8BDD\u4EE5\u52A0\u8F7D Fabric(\u65B0\u4F1A\u8BDD\u81EA\u52A8\u751F\u6548)\u3002",
1607
2099
  "cli.install.reason-message": "{label} {message}",
1608
2100
  "cli.install.language.prompt": "\u9009\u62E9 Fabric \u8BED\u8A00\uFF08\u754C\u9762\u4E0E\u77E5\u8BC6\u7EDF\u4E00\u4F7F\u7528\uFF0C\u4E4B\u540E\u53EF\u7528 fabric config \u4FEE\u6539\uFF09\uFF1A",
1609
2101
  "cli.install.language.option.zh-CN": "\u7B80\u4F53\u4E2D\u6587 (zh-CN)",
@@ -1631,6 +2123,10 @@ var zhCNMessages = {
1631
2123
  "cli.install.wizard.stage.bootstrap": "\u662F\u5426\u5B89\u88C5 bootstrap \u6A21\u677F\uFF1F[{defaultValue}]",
1632
2124
  "cli.install.wizard.stage.mcp": "\u662F\u5426\u914D\u7F6E MCP \u5BA2\u6237\u7AEF\uFF1F[{defaultValue}]",
1633
2125
  "cli.install.wizard.stage.hooks": "\u662F\u5426\u5B89\u88C5 git hooks\uFF1F[{defaultValue}]",
2126
+ // flat-design-system Wave4 (TASK-004): post-group ✓ 回执用的短阶段标签。
2127
+ "cli.install.wizard.stage.bootstrap.short": "bootstrap \u6A21\u677F",
2128
+ "cli.install.wizard.stage.mcp.short": "MCP \u5BA2\u6237\u7AEF",
2129
+ "cli.install.wizard.stage.hooks.short": "git hooks",
1634
2130
  "cli.install.wizard.mcp-install": "MCP \u670D\u52A1\u7AEF\u5B89\u88C5\u8303\u56F4\uFF08global/local\uFF09[{defaultValue}]",
1635
2131
  "cli.install.wizard.execute.confirm": "\u73B0\u5728\u6267\u884C\u8BE5\u5B89\u88C5\u8BA1\u5212\uFF1F[Y/n]",
1636
2132
  "cli.install.wizard.outro": "\u5B89\u88C5\u8BA1\u5212\u5DF2\u786E\u8BA4\uFF0C\u5F00\u59CB\u6267\u884C Fabric install...",
@@ -1638,6 +2134,9 @@ var zhCNMessages = {
1638
2134
  "cli.install.wizard.invalid-select": "\u65E0\u6548\u8F93\u5165\u3002\u53EF\u9009\u503C\uFF1A{options}\u3002",
1639
2135
  "cli.install.wizard.cancelled": "Fabric \u5B89\u88C5\u5DF2\u5728\u6267\u884C\u524D\u53D6\u6D88\u3002",
1640
2136
  "cli.install.capabilities.title": "\u5BA2\u6237\u7AEF\u80FD\u529B\u6458\u8981",
2137
+ // C-006 (TASK-004):默认只打一行能力摘要,让收尾的 summary card 主导收口印象;
2138
+ // 完整 4×6 能力表只在 --verbose 下展开。{count} = 检测到的客户端数。
2139
+ "cli.install.capabilities.summaryLine": "\u5DF2\u68C0\u6D4B\u5230 {count} \u4E2A\u5BA2\u6237\u7AEF\u5E76\u5B8C\u6210\u80FD\u529B\u914D\u7F6E(\u52A0 --verbose \u67E5\u770B\u9010\u5BA2\u6237\u7AEF\u660E\u7EC6\u8868)\u3002",
1641
2140
  // v2.0.0-rc.37 NEW-22: post-install 重启提示。MCP server 在 client 启动
1642
2141
  // 时 spawn, 已运行的 Claude Code / Codex session 不会自动加载
1643
2142
  // 新 mcp config — 必须重启才能拿到 Fabric tools。
@@ -1659,6 +2158,28 @@ var zhCNMessages = {
1659
2158
  "cli.install.store.setup.prompt": "\u4E3A\u672C\u9879\u76EE\u8BBE\u7F6E\u77E5\u8BC6 store\uFF1F",
1660
2159
  "cli.install.store.setup.bind-label": "\u7ED1\u5B9A\u5DF2\u6302\u8F7D: {alias}",
1661
2160
  "cli.install.store.setup.already-bound": "\u5DF2\u7ED1\u5B9A\u672C\u9879\u76EE: {aliases} \u2713",
2161
+ // W2 dual-slot (TASK-002): 个人库槽 + 团队库槽 的状态 / 提示文案。团队库槽按
2162
+ // 「类别」命名(team 类),候选项显示 store 的真实 alias —— 文案 MUST NOT 暗示
2163
+ // 该库必须叫 'team'(team 是类别非别名,守 KT-MOD-0001 命名撞轴)。
2164
+ "cli.install.store.slot.personal.status": "\u4E2A\u4EBA\u5E93(\u672C\u673A\u5168\u5C40): '{alias}' \u2713",
2165
+ "cli.install.store.slot.personal.absent": "\u4E2A\u4EBA\u5E93(\u672C\u673A\u5168\u5C40): \u5C1A\u672A\u5EFA\u7ACB",
2166
+ "cli.install.store.slot.personal.multi-none": "\u4E2A\u4EBA\u5E93(\u672C\u673A\u5168\u5C40): \u5DF2\u6302 {count} \u4E2A,\u5C1A\u672A\u9009\u5B9A active",
2167
+ "cli.install.store.slot.personal.multi-prompt": "\u9009\u62E9\u672C\u673A\u5F53\u524D\u8981\u7528\u7684 personal store(active):",
2168
+ "cli.install.store.slot.personal.multi-active-label": "'{alias}'(\u5F53\u524D active)",
2169
+ "cli.install.store.slot.personal.multi-switch-label": "\u5207\u5230 '{alias}'",
2170
+ "cli.install.store.slot.personal.multi-new-label": "\u65B0\u5EFA\u672C\u5730 personal store",
2171
+ "cli.install.store.slot.personal.multi-new-hint": "\u5168\u65B0\u7A7A personal store,\u5E76\u8BBE\u4E3A active",
2172
+ "cli.install.store.slot.personal.new-alias": "\u65B0 personal store \u7684\u522B\u540D:",
2173
+ "cli.install.store.slot.personal.switched": "\u5DF2\u5C06\u672C\u673A\u6D3B\u52A8 personal store \u5207\u5230 '{alias}'",
2174
+ "cli.install.store.slot.team.status": "\u56E2\u961F\u5E93(team \u7C7B): '{alias}'{source} \u2713",
2175
+ "cli.install.store.slot.team.empty": "\u56E2\u961F\u5E93(team \u7C7B): \u5C1A\u672A\u7ED1\u5B9A",
2176
+ "cli.install.store.slot.team.prompt": "\u4E3A\u672C\u9879\u76EE\u9009\u62E9\u56E2\u961F\u77E5\u8BC6\u5E93(team \u7C7B):",
2177
+ "cli.install.store.slot.team.bound-label": "\u4FDD\u6301\u5F53\u524D: {alias}",
2178
+ "cli.install.store.slot.team.switch-label": "\u5207\u5230\u5DF2\u6302\u8F7D: {alias}",
2179
+ // flat-design store menu:「保持当前」与「跳过」语义合并 —— 已绑定时 SKIP 行显示
2180
+ // 为 keep-label(保持当前 · 不改动),未绑定时为「跳过 · 仅用 personal store」。
2181
+ "cli.install.store.slot.team.keep-label": "\u4FDD\u6301\u5F53\u524D: {alias} \xB7 \u4E0D\u6539\u52A8",
2182
+ "cli.install.store.slot.team.keep-hint": "{source}\u7EE7\u7EED\u7528\u8FD9\u4E2A\u56E2\u961F\u5E93,\u672C\u6B21\u4E0D\u6539\u52A8\u7ED1\u5B9A",
1662
2183
  "cli.install.store.skip-label": "\u8DF3\u8FC7",
1663
2184
  "cli.install.store.bind-mounted.skip-hint": "\u6682\u4E0D\u7ED1\u5B9A\u5DF2\u6302\u8F7D\u7684 store",
1664
2185
  "cli.install.store.project-coordinate": "\u5728 store '{store}' \u4E2D\u7684\u9879\u76EE\u5750\u6807 (project coordinate):",
@@ -1680,6 +2201,9 @@ var zhCNMessages = {
1680
2201
  "cli.install.store.unbound-note": "\u6CE8\u610F: \u4EE5\u4E0B store \u5DF2\u6302\u8F7D\u4F46\u672A\u7ED1\u5B9A\u5230\u672C\u9879\u76EE: {aliases}\u3002",
1681
2202
  "cli.install.store.unbound-hint": " \u8FD0\u884C 'fabric store bind {first}' \u7ED1\u5B9A\u5176\u4E00\u3002",
1682
2203
  // C4: personal store clone-or-new。
2204
+ // TASK-004: 首装时为额外的一次性提问(语言 / 个人库 onboarding)加的语境前缀,
2205
+ // 让用户知道这些问题只在首次设置时出现。
2206
+ "cli.install.store.firstRunContext": "\u9996\u6B21\u8BBE\u7F6E\u4E2D \u2014\u2014 \u4EE5\u4E0B\u4E3A\u4EC5\u9996\u88C5\u51FA\u73B0\u7684\u4E00\u6B21\u6027\u9009\u62E9:",
1683
2207
  "cli.install.store.personal.prompt": "\u672C\u673A\u8FD8\u6CA1\u6709 personal store (\u4E2A\u4EBA\u77E5\u8BC6\u5E93)\u3002\u65B0\u5EFA\u4E00\u4E2A\uFF0C\u8FD8\u662F\u4ECE remote \u514B\u9686\u4F60\u5DF2\u6709\u7684\uFF1F",
1684
2208
  "cli.install.store.personal.new-label": "\u65B0\u5EFA\u672C\u5730 (\u9ED8\u8BA4)",
1685
2209
  "cli.install.store.personal.new-hint": "\u5168\u65B0\u7A7A personal store",
@@ -1728,38 +2252,61 @@ var zhCNMessages = {
1728
2252
  "cli.install.diff.state.present-canonical": "\u89C4\u8303",
1729
2253
  "cli.install.diff.state.drifted": "\u6F02\u79FB",
1730
2254
  "cli.install.diff.state.user-modified": "\u7528\u6237\u4FEE\u6539",
1731
- "cli.uninstall.description": "\u4ECE\u76EE\u6807\u9879\u76EE\u4E2D\u5378\u8F7D Fabric\u3002\u9879\u76EE\u5378\u8F7D\u6C38\u8FDC\u4E0D\u4F1A\u5220\u9664 ~/.fabric/stores/ \u4E0B\u7684\u5168\u5C40\u77E5\u8BC6 store\u3002\n\n\u793A\u4F8B\uFF1A\n fabric uninstall \u5728\u5F53\u524D\u9879\u76EE\u4E2D\u4EE5\u4EA4\u4E92\u6A21\u5F0F\u5378\u8F7D\n fabric uninstall --yes \u63A5\u53D7\u9ED8\u8BA4\u503C\uFF0C\u8DF3\u8FC7 TTY \u5411\u5BFC\n fabric uninstall --dry-run \u4EC5\u9884\u89C8\u5378\u8F7D\u8BA1\u5212\uFF0C\u4E0D\u5220\u9664\u6587\u4EF6",
2255
+ "cli.uninstall.description": "\u4ECE\u76EE\u6807\u9879\u76EE\u4E2D\u5378\u8F7D Fabric\uFF08~/.fabric/stores/ \u4E0B\u7684\u5168\u5C40 store \u6C38\u4E0D\u5220\u9664\uFF09",
1732
2256
  "cli.uninstall.args.target.description": "\u76EE\u6807\u9879\u76EE\u8DEF\u5F84\u3002\u9ED8\u8BA4\u4F9D\u6B21\u4F7F\u7528 --target\u3001EXTERNAL_FIXTURE_PATH\u3001\u5F53\u524D\u76EE\u5F55\u3002",
1733
2257
  "cli.uninstall.args.debug.description": "\u5C06\u76EE\u6807\u89E3\u6790\u7EC6\u8282\u8F93\u51FA\u5230 stderr\u3002",
1734
2258
  "cli.uninstall.args.yes.description": "\u63A5\u53D7\u5F53\u524D\u5378\u8F7D\u8BA1\u5212\u5E76\u8DF3\u8FC7 TTY \u5411\u5BFC\u76F4\u63A5\u6267\u884C\u3002",
2259
+ "cli.uninstall.args.verbose.description": "\u663E\u793A\u6BCF\u4E2A\u9636\u6BB5\u7684\u9010\u8DEF\u5F84\u660E\u7EC6\u8BA1\u6570\uFF0C\u800C\u975E\u7CBE\u7B80\u7ED3\u679C\u884C\u3002",
2260
+ "cli.uninstall.args.unbind-store.description": "\u540C\u65F6\u89E3\u7ED1\u672C\u9879\u76EE\u5BF9\u56E2\u961F store \u7684\u7ED1\u5B9A\uFF08\u6E05\u7A7A .fabric/fabric-config.json \u4E2D\u7684\u7ED1\u5B9A\uFF09\u3002~/.fabric/stores/ \u4E0B\u7684\u5168\u5C40 store \u6C38\u4E0D\u5220\u9664\u3002",
1735
2261
  "cli.uninstall.args.dry-run.description": "\u4EC5\u8F93\u51FA\u5378\u8F7D\u8BA1\u5212\uFF0C\u4E0D\u5220\u9664\u6587\u4EF6\u4E5F\u4E0D\u6267\u884C\u540E\u7EED\u9636\u6BB5\u3002",
1736
2262
  "cli.uninstall.plan.title": "Fabric \u5378\u8F7D\u8BA1\u5212",
1737
2263
  // C3: 镜像 install 的阶段提示 (install 用 "Fabric install 将按 N 个阶段执行")。
1738
2264
  "cli.uninstall.plan.phase-banner": "Fabric uninstall \u5C06\u6309 {total} \u4E2A\u9636\u6BB5\u6267\u884C",
1739
2265
  "cli.uninstall.plan.target": "\u76EE\u6807\uFF1A{target}",
1740
- "cli.uninstall.plan.actions": "\u8BA1\u5212\uFF1Ascaffold={scaffold} bootstrap={bootstrap} mcp={mcp}",
2266
+ // flat-design-system Wave5 (TASK-004 G3): 计划预览用人话动作句,按启用的阶段逐条列,
2267
+ // 不再输出 `key=是/否` 黑话行。
2268
+ "cli.uninstall.plan.will-remove": "\u5C06\u79FB\u9664\uFF1A",
2269
+ "cli.uninstall.plan.will-keep": "\u5C06\u4FDD\u7559\uFF1A",
2270
+ "cli.uninstall.plan.action.bootstrap": "\u5BA2\u6237\u7AEF\u6280\u80FD\u4E0E hook \u811A\u672C",
2271
+ "cli.uninstall.plan.action.mcp": "MCP \u670D\u52A1\u6CE8\u518C",
2272
+ "cli.uninstall.plan.action.scaffold": "\u9879\u76EE\u811A\u624B\u67B6\u6587\u4EF6",
2273
+ "cli.uninstall.plan.action.store": "\u56E2\u961F store \u7ED1\u5B9A\uFF08\u672C\u9879\u76EE\uFF09",
1741
2274
  "cli.uninstall.plan.detected": "\u68C0\u6D4B\u5230\u7684\u5BA2\u6237\u7AEF\uFF1A{clients}",
1742
2275
  "cli.uninstall.plan.preserves": "\u4FDD\u7559\u9879\uFF1A",
1743
2276
  "cli.uninstall.plan.preserves.stores": "\u5168\u5C40\u77E5\u8BC6 stores\uFF0C\u9879\u76EE\u5378\u8F7D\u6C38\u4E0D\u5220\u9664",
1744
2277
  "cli.uninstall.plan.preview-title": "Fabric \u5378\u8F7D dry run",
1745
- "cli.uninstall.plan.preview-result": "scaffold={scaffold} bootstrap={bootstrap} mcp={mcp}",
1746
2278
  "cli.uninstall.plan.scaffold-entries.title": "Scaffold \u5F85\u6E05\u7406\u9879\uFF1A",
1747
- "cli.uninstall.stages.scaffold": "\u6B63\u5728\u6E05\u7406 scaffold \u4EA7\u7269...",
1748
- "cli.uninstall.stages.bootstrap": "\u6B63\u5728\u79FB\u9664 bootstrap\uFF08Skills + hooks\uFF09...",
1749
- "cli.uninstall.stages.mcp": "\u6B63\u5728\u53CD\u6CE8\u518C MCP \u5BA2\u6237\u7AEF...",
2279
+ // W4: 共享 OutputRenderer pipeline —— section bar 标题 + 各阶段标签,install
2280
+ // pipeline 的对称逆。
2281
+ "cli.uninstall.pipeline.title": "Fabric \u5378\u8F7D",
2282
+ "cli.uninstall.pipeline.label.bootstrap": "Skills \u4E0E hooks",
2283
+ "cli.uninstall.pipeline.label.mcp": "MCP server",
2284
+ "cli.uninstall.pipeline.label.store": "\u89E3\u7ED1 store",
2285
+ "cli.uninstall.pipeline.label.scaffold": "\u6E05\u7406\u811A\u624B\u67B6",
2286
+ "cli.uninstall.pipeline.label.validate": "\u6821\u9A8C\u5DF2\u6E05\u7406",
1750
2287
  "cli.uninstall.stages.completed": "\u5DF2\u5B8C\u6210",
1751
2288
  "cli.uninstall.stages.completed-with-errors": "\u5B8C\u6210\u4F46\u6709\u9519\u8BEF",
1752
2289
  "cli.uninstall.stages.failed": "\u5931\u8D25",
2290
+ "cli.uninstall.stages.failed-hint": "\u67E5\u770B\u4E0A\u65B9\u9519\u8BEF\u8BE6\u60C5\u3002\u52A0 --debug \u83B7\u53D6\u66F4\u591A\u4FE1\u606F\u3002",
2291
+ "cli.uninstall.stages.uptodate": "\u65E0\u53EF\u79FB\u9664\uFF08{count} \u9879\u5DF2\u4E0D\u5B58\u5728\uFF09",
2292
+ "cli.uninstall.stages.summary": "removed={removed} skipped={skipped} errors={errors}",
2293
+ "cli.uninstall.stages.removed-count": "\u5DF2\u79FB\u9664 {count} \u9879",
2294
+ // flat-design-system Wave5 (TASK-006 G3): 总结卡明细行的人话结果词,与 install 的
2295
+ // `已安装 {count} 项` / `已最新` 对称。
2296
+ "cli.uninstall.stage.cleaned-count": "\u5DF2\u6E05\u7406 {count} \u9879",
1753
2297
  "cli.uninstall.summary.title": "\u5378\u8F7D\u6458\u8981",
1754
2298
  "cli.uninstall.summary.body": "removed={removed} skipped={skipped} errors={errors}",
2299
+ "cli.uninstall.healthcheck.title": "\u2713 Fabric \u5DF2\u4E0D\u5B58\u5728 \xB7 \u65E0\u53EF\u79FB\u9664",
1755
2300
  "cli.uninstall.wizard.intro": "\u5378\u8F7D Fabric",
1756
2301
  "cli.uninstall.wizard.select.prompt": "\u8981\u4ECE {target} \u5378\u8F7D\u54EA\u4E9B\u90E8\u5206\uFF1F(\u7A7A\u683C\u52FE\u9009 / \u56DE\u8F66\u786E\u8BA4\uFF1B~/.fabric/stores/ \u4E0B\u7684\u5168\u5C40\u77E5\u8BC6 store \u6C38\u4E0D\u5220\u9664)",
1757
2302
  "cli.uninstall.wizard.select.scaffold.label": "scaffold \u4EA7\u7269",
1758
2303
  "cli.uninstall.wizard.select.scaffold.hint": ".fabric/ \u4E0B\u7684\u811A\u624B\u67B6\u6587\u4EF6",
1759
- "cli.uninstall.wizard.select.bootstrap.label": "bootstrap (Skills + hooks)",
1760
- "cli.uninstall.wizard.select.bootstrap.hint": "\u5404\u5BA2\u6237\u7AEF\u7684 skills \u4E0E git hooks",
2304
+ "cli.uninstall.wizard.select.bootstrap.label": "Skills \u4E0E hooks",
2305
+ "cli.uninstall.wizard.select.bootstrap.hint": "\u5404\u5BA2\u6237\u7AEF\u7684 skills \u4E0E hook \u811A\u672C + \u914D\u7F6E",
1761
2306
  "cli.uninstall.wizard.select.mcp.label": "MCP \u5BA2\u6237\u7AEF\u6CE8\u518C",
1762
2307
  "cli.uninstall.wizard.select.mcp.hint": "\u4ECE\u5404\u5BA2\u6237\u7AEF\u53CD\u6CE8\u518C fabric MCP server",
2308
+ "cli.uninstall.wizard.select.store.label": "\u89E3\u7ED1\u56E2\u961F store\uFF08\u672C\u9879\u76EE\uFF09",
2309
+ "cli.uninstall.wizard.select.store.hint": "\u6E05\u7A7A\u672C\u9879\u76EE\u7684 store \u7ED1\u5B9A\uFF1B\u5168\u5C40 store \u6C38\u4E0D\u5220\u9664",
1763
2310
  "cli.uninstall.wizard.execute.confirm": "\u73B0\u5728\u6267\u884C\u8BE5\u5378\u8F7D\u8BA1\u5212\uFF1F[Y/n]",
1764
2311
  "cli.uninstall.wizard.outro": "\u5378\u8F7D\u8BA1\u5212\u5DF2\u786E\u8BA4\uFF0C\u5F00\u59CB\u6267\u884C Fabric uninstall...",
1765
2312
  "cli.uninstall.wizard.cancelled": "Fabric \u5378\u8F7D\u5DF2\u5728\u6267\u884C\u524D\u53D6\u6D88\u3002",
@@ -1981,6 +2528,62 @@ var zhCNMessages = {
1981
2528
  "cli.whoami.stores-none": "stores: (\u672A\u6302\u8F7D\u4EFB\u4F55 store)",
1982
2529
  "cli.whoami.stores-label": "stores:",
1983
2530
  "cli.shared.local-only": "(\u4EC5\u672C\u5730)",
2531
+ // `fabric info`(平铺风)—— 身份 / 项目状态 / 召回引擎 标题与字段标签。
2532
+ "cli.info.field.uid": "uid",
2533
+ "cli.info.identity.title": "Fabric \u8EAB\u4EFD",
2534
+ "cli.info.status.title": "\u9879\u76EE\u72B6\u6001",
2535
+ "cli.info.status.group.machine": "\u672C\u673A",
2536
+ "cli.info.status.group.project": "\u5F53\u524D\u9879\u76EE",
2537
+ "cli.info.status.field.project": "\u9879\u76EE",
2538
+ "cli.info.status.field.mounted": "\u5DF2\u6302\u8F7D\u5E93",
2539
+ "cli.info.status.field.bound": "\u7ED1\u5B9A\u5E93",
2540
+ "cli.info.status.value.unset": "(\u672A\u8BBE\u7F6E)",
2541
+ "cli.info.status.value.not-project": "(\u975E Fabric \u9879\u76EE)",
2542
+ "cli.info.status.value.no-global": "(\u65E0\u5168\u5C40\u914D\u7F6E)",
2543
+ "cli.info.recall.title": "\u53EC\u56DE\u5F15\u64CE",
2544
+ "cli.info.recall.summary.on": "\u8BED\u4E49\u641C\u7D22\u5DF2\u5F00 \u2014\u2014 \u8BE6\u60C5 fabric info --recall",
2545
+ "cli.info.recall.summary.off": "\u5173\u952E\u8BCD\u6A21\u5F0F \xB7 \u8BED\u4E49\u641C\u7D22\u672A\u5F00 \u2014\u2014 \u8BE6\u60C5 fabric info --recall",
2546
+ "cli.info.recall.mode.additive": "additive(\u5173\u952E\u8BCD\u6A21\u5F0F)",
2547
+ "cli.info.recall.mode.rrf": "rrf(\u5173\u952E\u8BCD+\u8BED\u4E49)",
2548
+ "cli.info.recall.reason.forced-additive": "\u914D\u7F6E\u56FA\u5B9A\u4E3A\u5173\u952E\u8BCD\u6A21\u5F0F(additive)",
2549
+ "cli.info.recall.reason.auto-additive": "\u5411\u91CF\u901A\u9053\u672A\u5C31\u7EEA,\u81EA\u52A8\u56DE\u9000\u5230\u5173\u952E\u8BCD\u6A21\u5F0F",
2550
+ "cli.info.recall.reason.auto-rrf": "\u5411\u91CF\u901A\u9053\u5C31\u7EEA,\u4F7F\u7528\u5173\u952E\u8BCD+\u8BED\u4E49\u878D\u5408(rrf)",
2551
+ "cli.info.recall.reason.rrf-ready": "\u914D\u7F6E\u56FA\u5B9A\u4E3A rrf,\u5411\u91CF\u901A\u9053\u5C31\u7EEA",
2552
+ "cli.info.recall.reason.rrf-warn": "\u914D\u7F6E\u56FA\u5B9A\u4E3A rrf,\u4F46\u5411\u91CF\u901A\u9053\u672A\u5C31\u7EEA \u2014\u2014 \u5355\u901A\u9053 rrf \u53CD\u800C\u6BD4\u5173\u952E\u8BCD\u6A21\u5F0F\u5DEE",
2553
+ "cli.info.recall.install-hint": "\u88C5\u5B83\u5F00\u542F\u8BED\u4E49\u641C\u7D22:npm i -g fastembed",
2554
+ "cli.info.recall.field.fusion-config": "\u878D\u5408\u7B56\u7565(\u914D\u7F6E)",
2555
+ "cli.info.recall.field.fusion-effective": "\u878D\u5408\u7B56\u7565(\u5B9E\u9645)",
2556
+ "cli.info.recall.field.embed-enabled": "embed \u5F00\u542F",
2557
+ "cli.info.recall.field.embed-model": "embed \u6A21\u578B",
2558
+ "cli.info.recall.field.fastembed": "fastembed \u5305",
2559
+ "cli.info.recall.field.cache-dir": "\u6A21\u578B\u7F13\u5B58",
2560
+ "cli.info.recall.field.model-cached": "\u6A21\u578B\u5DF2\u7F13\u5B58",
2561
+ "cli.info.recall.field.vector": "\u5411\u91CF\u901A\u9053",
2562
+ "cli.info.recall.fastembed.yes": "\u53EF\u89E3\u6790",
2563
+ "cli.info.recall.fastembed.no": "\u672A\u5B89\u88C5(\u53EF\u9009\u4F9D\u8D56)",
2564
+ "cli.info.recall.cached.no": "\u672A\u7F13\u5B58 \u2014\u2014 \u9996\u6B21\u53EC\u56DE\u65F6\u4E0B\u8F7D(\u6216\u8FD0\u884C `fabric info --recall --warm`)",
2565
+ "cli.info.recall.vector.ready": "\u5C31\u7EEA",
2566
+ "cli.info.recall.vector.not-ready": "\u672A\u5C31\u7EEA \u2014\u2014 \u53EC\u56DE\u56DE\u9000\u5230\u5173\u952E\u8BCD\u6A21\u5F0F(BM25 / additive)",
2567
+ "cli.info.recall.warm.ok": "embedder \u5DF2\u9884\u70ED:\u6A21\u578B '{model}' \u5DF2\u52A0\u8F7D(\u5411\u91CF\u7EF4\u5EA6 {dim}),\u7F13\u5B58\u4E8E {dir}",
2568
+ "cli.info.recall.warm.fail": "embedder \u4E0D\u53EF\u7528 \u2014\u2014 \u53EF\u9009\u7684 'fastembed' \u5305\u65E0\u6CD5\u89E3\u6790,\u6216\u6A21\u578B\u52A0\u8F7D\u5931\u8D25\u3002\n \u53EC\u56DE\u56DE\u9000\u5230\u5173\u952E\u8BCD\u6A21\u5F0F(BM25 / additive)\u3002\u8BF7\u5728 server \u80FD\u89E3\u6790\u6A21\u5757\u7684\u4F4D\u7F6E\u5B89\u88C5 fastembed \u540E\u91CD\u8BD5\u3002",
2569
+ "cli.store.list.description": "\u5217\u51FA\u6302\u8F7D\u7684 store",
2570
+ // 追加在 `fabric store --help` 末尾的说明 —— 交代进阶(meta.hidden)操作去哪了,
2571
+ // 否则只剩 list 一行会让用户以为 store 没别的能力。
2572
+ "cli.store.help.folded-note": "\u8FDB\u9636\u64CD\u4F5C(create / bind / switch-write / migrate \u7B49)\u5DF2\u6298\u53E0 \u2014\u2014 \u7531 fabric install \u4E0E fabric-store skill \u9A71\u52A8;\u9700\u8981\u65F6\u76F4\u63A5 `fabric store <\u547D\u4EE4> --help` \u67E5\u770B\u3002",
2573
+ "cli.store.list.title": "\u5DF2\u6302\u8F7D\u77E5\u8BC6\u5E93",
2574
+ "cli.store.project.list.title": "store '{store}' \u4E2D\u7684\u9879\u76EE",
2575
+ "cli.store.project.list.empty": "(\u65E0\u5DF2\u6CE8\u518C\u9879\u76EE)",
2576
+ "cli.store.project.created": "\u5DF2\u5728 store '{store}' \u6CE8\u518C\u9879\u76EE '{id}'",
2577
+ "cli.store.migrate.title": "\u77E5\u8BC6\u5750\u6807\u8FC1\u79FB",
2578
+ "cli.store.backfill.noop": "scope \u56DE\u586B:\u65E0\u9700\u6539\u52A8({count} \u6761\u5DF2\u4E00\u81F4)",
2579
+ "cli.store.backfill.summary": "scope \u56DE\u586B:{changed} \u6761\u5DF2\u66F4\u65B0,{unchanged} \u6761\u672A\u53D8",
2580
+ "cli.store.backfill.scope-note": "{count} \u6761\u9ED8\u8BA4\u8BBE\u4E3A semantic_scope: team\u3002\u7528 `fabric store migrate scope <store> --to project:<id> --id <id>` \u628A\u9879\u76EE\u4E13\u5C5E\u7684\u964D\u7EA7\u3002",
2581
+ "cli.store.rescope.noop": "\u91CD\u5B9A scope:\u65E0\u9700\u6539\u52A8({count} \u6761\u5DF2\u662F '{scope}')",
2582
+ "cli.store.rescope.summary": "\u91CD\u5B9A scope \u2192 {scope}:{changed} \u6761\u5DF2\u66F4\u65B0,{unchanged} \u6761\u672A\u53D8",
2583
+ "cli.store.rescope.refused": "{count} \u6761\u88AB\u62D2\u7EDD",
2584
+ "cli.store.reroot.noop": "reroot:\u65E0\u9700\u8FC1\u79FB({skipped} \u6761\u4FDD\u6301\u5E73\u94FA)",
2585
+ "cli.store.reroot.summary": "reroot:{moved} \u6761\u9879\u76EE\u6761\u76EE\u5DF2\u8FC1\u5165 knowledge/projects/<id>/",
2586
+ "cli.store.reroot.provenance-gap": "{count} \u6761\u7ECF fs rename \u8FC1\u79FB(\u672A\u8DDF\u8E2A / \u975E git)\u2014\u2014 \u8FD9\u4E9B\u6761\u76EE\u7684 git blame \u5386\u53F2\u672A\u4FDD\u7559",
1984
2587
  "cli.store.none-mounted": "(\u672A\u6302\u8F7D\u4EFB\u4F55 store)",
1985
2588
  "cli.store.mounted": "\u5DF2\u6302\u8F7D '{alias}' (\u5171 {count} \u4E2A store)",
1986
2589
  "cli.store.created": "\u5DF2\u521B\u5EFA store '{alias}' ({uuid}) \u4E8E {dir}",
@@ -1989,15 +2592,33 @@ var zhCNMessages = {
1989
2592
  "cli.store.detached": "\u5DF2\u5206\u79BB '{alias}' \u2014\u2014 \u78C1\u76D8\u4E0A\u7684 store \u76EE\u5F55\u4FDD\u7559 (\u5206\u79BB \u2260 \u5220\u9664)",
1990
2593
  "cli.store.bound": "\u5DF2\u7ED1\u5B9A\u5FC5\u9700 store '{id}' (\u5171 {count} \u4E2A\u5FC5\u9700)",
1991
2594
  "cli.store.switch-write": "\u5DF2\u5C06\u672C\u9879\u76EE\u7684\u6D3B\u52A8\u5199\u5165 store \u8BBE\u4E3A '{alias}'",
2595
+ "cli.store.switch-personal": "\u5DF2\u5C06\u672C\u673A\u6D3B\u52A8 personal store \u8BBE\u4E3A '{alias}'",
1992
2596
  "cli.store.routed": "\u5199\u5165\u8DEF\u7531:scope '{scope}' \u2192 store '{alias}'",
1993
2597
  "cli.sync.deferred": "{count} \u4E2A store \u79BB\u7EBF \u2014\u2014 push \u5DF2\u5EF6\u540E; \u8054\u7F51\u540E\u91CD\u65B0\u8FD0\u884C `fabric sync`",
1994
2598
  "cli.sync.paused": "sync \u56E0\u51B2\u7A81\u6682\u505C \u2014\u2014 \u89E3\u51B3\u540E\u8FD0\u884C `fabric sync --continue` (\u6216 `--abort`)",
2599
+ // flat-design (spec §0.4):`fabric sync` 命令级标题 + 每个 store 单行 + 聚合摘要。
2600
+ // state 文案在 store 行与摘要计数格之间共用。
2601
+ "cli.sync.args.continue.description": "\u89E3\u51B3 rebase \u51B2\u7A81\u540E\u7EE7\u7EED\u540C\u6B65",
2602
+ "cli.sync.args.abort.description": "\u4E2D\u6B62\u53D1\u751F\u51B2\u7A81\u7684 store \u7684 rebase",
2603
+ "cli.sync.title": "\u540C\u6B65\u77E5\u8BC6\u5E93",
2604
+ "cli.sync.summary.title": "\u540C\u6B65\u6458\u8981",
2605
+ "cli.sync.none": "\u6CA1\u6709\u53EF\u540C\u6B65\u7684\u8FDC\u7A0B store",
2606
+ "cli.sync.all-synced": "\u5168\u90E8 store \u5DF2\u540C\u6B65",
2607
+ "cli.sync.state.synced": "\u5DF2\u540C\u6B65",
2608
+ "cli.sync.state.offline": "\u79BB\u7EBF",
2609
+ "cli.sync.state.conflict": "\u51B2\u7A81",
2610
+ "cli.sync.state.aborted": "\u5DF2\u4E2D\u6B62",
2611
+ "cli.sync.state.pending": "\u5F85\u5904\u7406",
1995
2612
  "cli.metrics.invalid-since": '--since: \u65E0\u6548\u7684\u65F6\u957F "{raw}" (\u793A\u4F8B: 24h\u30017d\u300130m)',
1996
2613
  "cli.metrics.window": "Fabric \u6307\u6807 \u2014\u2014 \u65F6\u95F4\u7A97: {window}",
1997
2614
  "cli.metrics.window-all-time": "\u5168\u90E8\u65F6\u95F4",
1998
2615
  "cli.metrics.rows-range": " \u884C\u6570: {count} ({start} \u2192 {end})",
1999
2616
  "cli.metrics.rows": " \u884C\u6570: {count}",
2000
2617
  "cli.metrics.no-activity": " (\u65F6\u95F4\u7A97\u5185\u65E0\u8BA1\u6570\u6D3B\u52A8 \u2014\u2014 server \u53EF\u80FD\u7A7A\u95F2\u6216\u521A\u542F\u52A8)",
2618
+ "cli.metrics.col.counter": "\u8BA1\u6570\u5668",
2619
+ "cli.metrics.col.total": "\u603B\u8BA1",
2620
+ "cli.metrics.col.entry": "\u6761\u76EE",
2621
+ "cli.metrics.section.perEntry": "\u6309\u6761\u76EE\u6D88\u8D39\u6392\u884C (knowledge_consumed:<id>)",
2001
2622
  // W3-09 (ISS-035): forensic 项目扫描进度 (stderr, 仅 TTY)。
2002
2623
  "cli.install.scanning": "\u6B63\u5728\u626B\u63CF\u9879\u76EE\u7684\u5BA2\u6237\u7AEF/\u6846\u67B6\u7279\u5F81\u2026",
2003
2624
  "cli.install.scan-complete": " \u9879\u76EE\u626B\u63CF\u5B8C\u6210",