@fenglimg/fabric-shared 2.2.0 → 2.3.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveGlobalLocale
3
- } from "./chunk-2GLIAZ5M.js";
3
+ } from "./chunk-ANUDBQBK.js";
4
4
 
5
5
  // src/i18n/locales/en.ts
6
6
  var enMessages = {
@@ -24,19 +24,15 @@ var enMessages = {
24
24
  "cli.shared.invalid-host-empty": "Invalid host: <empty>",
25
25
  "cli.shared.invalid-port": "Invalid port: {value}",
26
26
  "cli.shared.error": "Error",
27
- // EPIC-011: Grouped help display i18n keys
28
- "cli.help.group.setup.install": "Initialize Fabric in this repository",
29
- "cli.help.group.setup.config": "Configure Fabric settings",
30
- "cli.help.group.daily.sync": "Sync team knowledge with remote stores",
31
- "cli.help.group.daily.info": "Show project status",
32
- "cli.help.group.diagnostic.doctor": "Check Fabric health and repair issues",
33
- "cli.help.group.advanced.store": "Manage knowledge stores (see: fabric store --help)",
34
- "cli.help.group.advanced.whoami": "Show machine identity",
35
- "cli.help.group.advanced.whoami.deprecated": "deprecated \u2192 info --global",
36
- "cli.help.group.advanced.status": "Show project status",
37
- "cli.help.group.advanced.status.deprecated": "deprecated \u2192 info",
38
- "cli.help.group.advanced.scope-explain": "Explain scope",
39
- "cli.help.group.advanced.scope-explain.deprecated": "deprecated \u2192 info scope",
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)",
40
36
  // v2.1 hidden-command i18n keys cleanup: approve/bootstrap/hooks/human-lint/
41
37
  // ledger-append/pre-commit/scan/sync-meta/update commands removed from CLI
42
38
  // surface in v2.0.0-rc.18. Keys intentionally retained for backward compat
@@ -316,6 +312,11 @@ var enMessages = {
316
312
  "doctor.check.skill_ref_mirror.ok": "All `.claude/skills/<slug>/ref/` and `.codex/skills/<slug>/ref/` files are byte-identical.",
317
313
  "doctor.check.skill_ref_mirror.message": "{count} skill ref file(s) differ between `.claude/skills/` and `.codex/skills/` (paths: {list}). One client was hand-edited or partially installed.",
318
314
  "doctor.check.skill_ref_mirror.remediation": "Run `fabric install` to rewrite both client subtrees from the canonical templates and restore parity.",
315
+ // ux-w2-2: retired-reference (stale-pointer) lint.
316
+ "doctor.check.retired_reference.name": "Retired reference",
317
+ "doctor.check.retired_reference.ok": "No retired tool/field names linger in the bootstrap, SKILL.md, or installed hooks.",
318
+ "doctor.check.retired_reference.message": "{count} stale pointer(s) to retired tool/field names in agent-facing text: {sample}",
319
+ "doctor.check.retired_reference.remediation": "Update the flagged text to the replacement token (or remove it), then re-run `fabric install` to resync the dogfood mirrors.",
319
320
  // v2.0.0-rc.33 W3-6 (P1-13): SKILL.md token budget lint. warn > 5K / error > 10K tokens (chars/3 estimate). Anthropic recommends SKILL.md hot path stay ~3K; over 5K hurts progressive disclosure; over 10K is blocking (wasted model context + load latency).
320
321
  "doctor.check.skill_token_budget.name": "Skill token budget",
321
322
  "doctor.check.skill_token_budget.ok": "All .claude/skills/<slug>/SKILL.md files are within token budget (warn 5K / error 10K).",
@@ -343,7 +344,7 @@ var enMessages = {
343
344
  // rc.36 TASK-05 (P0-8): empty-tags ratio warn.
344
345
  "doctor.check.knowledge_tags_empty.name": "Knowledge tags coverage",
345
346
  "doctor.check.knowledge_tags_empty.ok": "empty-tag ratio is healthy (\u2264 50%, or workspace too small to compute).",
346
- "doctor.check.knowledge_tags_empty.message": "{emptyCount}/{totalCount} ({pct}%) canonical knowledge entries have empty `tags:` \u2014 topical clustering and cross-entry retrieval degrade. The fabric-archive / fabric-import skills should produce 2-4 tags per entry.",
347
+ "doctor.check.knowledge_tags_empty.message": "{emptyCount}/{totalCount} ({pct}%) canonical knowledge entries have empty `tags:` \u2014 topical clustering and cross-entry retrieval degrade. The fabric-archive skill should produce 2-4 tags per entry.",
347
348
  "doctor.check.knowledge_tags_empty.remediation": "On the next archive/import run, populate `tags:` in the frontmatter with 2-4 kebab-case keywords. To backfill existing entries in bulk, use `/fabric-review` with the modify flow.",
348
349
  // rc.36 TASK-09 (P1-NEW1): drift_detected events unconsumed by demote.
349
350
  "doctor.check.drift_unconsumed.name": "Knowledge drift unconsumed",
@@ -395,7 +396,7 @@ var enMessages = {
395
396
  "doctor.check.underseeded.ok": "Knowledge corpus has {count} canonical entries (>= {threshold}).",
396
397
  "doctor.check.underseeded.message.singular": "Knowledge corpus has only {count} canonical entry (< {threshold} threshold). The plan_context retrieval surface is below its useful floor.",
397
398
  "doctor.check.underseeded.message.plural": "Knowledge corpus has only {count} canonical entries (< {threshold} threshold). The plan_context retrieval surface is below its useful floor.",
398
- "doctor.check.underseeded.remediation": "Run the fabric-import Skill (`/fabric-import`) to backfill knowledge from git history and existing docs.",
399
+ "doctor.check.underseeded.remediation": "Run the fabric-archive skill's source mode (`/fabric-archive`) to backfill knowledge from git history and existing docs.",
399
400
  "doctor.check.session_hints_stale.name": "Knowledge session-hints stale",
400
401
  "doctor.check.session_hints_stale.ok": "No session-hints cache files older than {days} days under .fabric/.cache/.",
401
402
  "doctor.check.session_hints_stale.message.singular": "{count} session-hints cache file under .fabric/.cache/ is older than {days} days. First: {detail}.",
@@ -438,7 +439,7 @@ var enMessages = {
438
439
  // rc.31 BUG-G2/G5: promote-ledger invariant check.
439
440
  "doctor.check.promote_ledger_invariant.name": "Promote ledger invariant",
440
441
  "doctor.check.promote_ledger_invariant.ok": "knowledge_proposed={proposed} >= knowledge_promote_started={started} >= knowledge_promoted={promoted}; ledger invariant holds.",
441
- "doctor.check.promote_ledger_invariant.message.proposed-lt-started": "knowledge_proposed={proposed} is less than knowledge_promote_started={started} (ledger invariant violated; some pending entries were approved without going through fab_extract_knowledge, so no propose event was emitted for them).",
442
+ "doctor.check.promote_ledger_invariant.message.proposed-lt-started": "knowledge_proposed={proposed} is less than knowledge_promote_started={started} (ledger invariant violated; some pending entries were approved without going through fab_propose, so no propose event was emitted for them).",
442
443
  "doctor.check.promote_ledger_invariant.message.started-lt-promoted": "knowledge_promote_started={started} is less than knowledge_promoted={promoted} (ledger invariant violated; unpaired promoted events exist, possibly from doctor filesystem-edit fallback or external writers).",
443
444
  "doctor.check.promote_ledger_invariant.remediation": "Starting in rc.31, review.approve synthesizes a knowledge_proposed event to keep the invariant; re-run fabric doctor after the next approve to settle. Historical imbalance is observability-only and does not affect KB function.",
444
445
  // rc.35 TASK-04 (P0-9.b): global_cli_outdated.
@@ -458,7 +459,7 @@ var enMessages = {
458
459
  "doctor.check.store_scope_lint.name": "Store scope lint",
459
460
  "doctor.check.store_scope_lint.ok": "All read-set store entries carry valid scope metadata (semantic_scope + visibility_store, no personal leak, no dangling project).",
460
461
  "doctor.check.store_scope_lint.message": "{total} store scope issue(s): {breakdown}. e.g. {sample}.",
461
- "doctor.check.store_scope_lint.remediation": "Run `fabric store backfill-scope` to add missing semantic_scope/visibility_store; `fabric store re-scope` to fix a dangling project: coordinate; move any personal-scope entry out of a shared store (personal knowledge lives only in your personal store, R5#3).",
462
+ "doctor.check.store_scope_lint.remediation": "Run `fabric store migrate backfill` to add missing semantic_scope/visibility_store; `fabric store migrate scope` to fix a dangling project: coordinate; move any personal-scope entry out of a shared store (personal knowledge lives only in your personal store, R5#3).",
462
463
  // v2.2 Goal B (G-INTEGRITY): store stable_id collision + layer mismatch lints.
463
464
  "doctor.check.stable_id_collision.name": "Stable ID collision",
464
465
  "doctor.check.stable_id_collision.message.singular": 'stable_id "{stableId}" is declared in {fileCount} files: {files}. Edit one of the knowledge files to use a unique stable_id.',
@@ -493,7 +494,7 @@ var enMessages = {
493
494
  "doctor.check.broad_index_drift.ok": "No store's broad-scope entry count reaches the drift threshold ({threshold} of backstop {backstop}).",
494
495
  "doctor.check.broad_index_drift.message.singular": "{count} store's broad-scope index has reached {threshold} (80% of backstop {backstop}) \u2014 the SessionStart banner is close to truncating broad entries. First: {detail}.",
495
496
  "doctor.check.broad_index_drift.message.plural": "{count} stores' broad-scope indexes have reached {threshold} (80% of backstop {backstop}) \u2014 the SessionStart banner is close to truncating broad entries. First: {detail}.",
496
- "doctor.check.broad_index_drift.remediation": "Run the `fabric-audit` skill to prune or demote stale broad-scope entries in the flagged store, or raise `broad_index_backstop` in .fabric/fabric-config.json if the corpus is legitimately large.",
497
+ "doctor.check.broad_index_drift.remediation": "Run the `fabric-review` skill's retire sub-flow to prune or demote stale broad-scope entries in the flagged store, or raise `broad_index_backstop` in .fabric/fabric-config.json if the corpus is legitimately large.",
497
498
  // v2.2 Goal B (G-AGE): knowledge decay lints (orphan_demote + stale_archive).
498
499
  "doctor.check.orphan_demote.name": "Knowledge orphan demote",
499
500
  "doctor.check.orphan_demote.ok": "No canonical knowledge entries exceed their maturity-keyed inactivity threshold.",
@@ -505,6 +506,18 @@ var enMessages = {
505
506
  "doctor.check.stale_archive.message.singular": "{count} draft knowledge entry is stale beyond the demote+{additionalDays}d additional quiet window. First: {detail}.",
506
507
  "doctor.check.stale_archive.message.plural": "{count} draft knowledge entries are stale beyond the demote+{additionalDays}d additional quiet window. First: {detail}.",
507
508
  "doctor.check.stale_archive.remediation": "Archive the stale draft via `/fabric-review reject <id>`, or revive it if still relevant. (Moving store-backed files is the store-write flow's job \u2014 this read-side lint only surfaces the staleness.)",
509
+ // v2.2 C1: knowledge promotion lint (promotion_candidate, info kind).
510
+ "doctor.check.promotion_candidate.name": "Knowledge promotion candidate",
511
+ "doctor.check.promotion_candidate.ok": "No verified knowledge entries reach the related in-degree threshold for proven promotion.",
512
+ "doctor.check.promotion_candidate.message.singular": "{count} verified knowledge entry has related in-degree \u2265{threshold} (structurally central) and is worth reviewing for promotion to proven. First: {detail}.",
513
+ "doctor.check.promotion_candidate.message.plural": "{count} verified knowledge entries have related in-degree \u2265{threshold} (structurally central) and are worth reviewing for promotion to proven. First: {detail}.",
514
+ "doctor.check.promotion_candidate.remediation": "Review these entries via `/fabric-review` and (after confirming 0 dismissals, cold-eval self-sufficiency, and foundational value) `modify <id>` to proven. (The promotion judgment is the store-write review's job \u2014 this read-side lint only surfaces the structurally-central candidates.)",
515
+ // v2.2 C1: broad review-recheck lint (broad_review_recheck, info kind).
516
+ "doctor.check.broad_review_recheck.name": "Knowledge broad review recheck",
517
+ "doctor.check.broad_review_recheck.ok": "No broad-scope knowledge entries are overdue for a review re-confirmation.",
518
+ "doctor.check.broad_review_recheck.message.singular": "{count} broad-scope knowledge entry has gone {thresholdDays}d+ without a fab-review re-confirmation and is worth a recheck (broad is exempt from usage-age decay, so this is its review clock). First: {detail}.",
519
+ "doctor.check.broad_review_recheck.message.plural": "{count} broad-scope knowledge entries have gone {thresholdDays}d+ without a fab-review re-confirmation and are worth a recheck (broad is exempt from usage-age decay, so this is its review clock). First: {detail}.",
520
+ "doctor.check.broad_review_recheck.remediation": "Re-confirm each entry via `/fabric-review` (approve/modify stamps a fresh review timestamp), or demote/reject it if it no longer holds. This is a non-blocking nudge, never an auto-demote \u2014 broad knowledge stays surfaced until a reviewer acts.",
508
521
  // project-scope binding backfill lint (unbound_project).
509
522
  "doctor.check.unbound_project.name": "Project-scope binding",
510
523
  "doctor.check.unbound_project.ok": "The bound write store carries a project coordinate (project_id + active_project), so project-scope recall/writes route correctly.",
@@ -515,11 +528,6 @@ var enMessages = {
515
528
  "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}.",
516
529
  "doctor.check.skill_md_yaml_invalid.message.plural": "{count} SKILL.md frontmatter values contain an unquoted ': ' that strict YAML parsers reject (Claude Code tolerates it; Codex CLI drops the skill at load). First: {detail}.",
517
530
  "doctor.check.skill_md_yaml_invalid.remediation": 'Quote the value with double quotes (`description: "\u2026"`) or rewrite the inner `key: value` token to `key=value`.',
518
- "doctor.check.router_chain_ref.name": "Router chain refs",
519
- "doctor.check.router_chain_ref.ok": "Every fabric-* reference in the fabric/ router S_CHAIN points at an installed leaf skill.",
520
- "doctor.check.router_chain_ref.message.singular": "{count} S_CHAIN reference in the fabric/ router points at a skill not in the install set: {list}. The chain step will dead-end at runtime.",
521
- "doctor.check.router_chain_ref.message.plural": "{count} S_CHAIN references in the fabric/ router point at skills not in the install set: {list}. Those chain steps will dead-end at runtime.",
522
- "doctor.check.router_chain_ref.remediation": "Edit the S_CHAIN table in templates/skills/fabric/SKILL.md to reference a real leaf skill (one of the installed fabric-* skills), or remove the stale chain row.",
523
531
  "doctor.check.onboard_coverage.name": "Onboard coverage",
524
532
  "doctor.check.onboard_coverage.ok.complete": "Onboard coverage: {filledCount}/{total} \u2713 (opted-out: {optedOutCount}).",
525
533
  "doctor.check.onboard_coverage.message.incomplete": "Onboard slots not yet covered: [{missingSlots}]. {filledCount}/{total} filled; {optedOutCount} opted-out.",
@@ -549,6 +557,9 @@ var enMessages = {
549
557
  "cli.install.args.dry-run.description": "Print the install plan without writing files or running follow-up stages",
550
558
  "cli.install.args.enable-embed.description": "Opt in to vector semantic search (sets embed_enabled + embed_model; prints fastembed install steps)",
551
559
  "cli.install.args.embed-model.description": "With --enable-embed: override the pinned embed model (default fast-bge-small-zh-v1.5)",
560
+ // TASK-004: --verbose expands the per-phase detail a collapsed re-install would
561
+ // fold, and prints the full per-client capability table.
562
+ "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",
552
563
  // rc.35 TASK-08 (P0-5/6): --force-skills-only.
553
564
  "cli.install.args.force-skills-only.description": "Skip bootstrap / MCP / hooks / settings; refresh ONLY the fabric Skill template copies (.claude/.codex/skills/*).",
554
565
  "cli.install.force-skills-only.banner": "Refreshing fabric Skill templates only",
@@ -577,7 +588,26 @@ var enMessages = {
577
588
  "cli.install.steps.bootstrap-claude": "Updated CLAUDE.md with @-import directives",
578
589
  "cli.install.steps.bootstrap-codex": "Updated AGENTS.md with fabric:bootstrap managed block",
579
590
  "cli.install.stages.mcp": "Configuring MCP clients...",
580
- "cli.install.stages.hooks": "Installing git hooks...",
591
+ "cli.install.stages.hooks": "Installing hooks & skills...",
592
+ "cli.install.preflight.error.no-home": "Cannot determine home directory for global root",
593
+ "cli.install.preflight.error.not-dir": "Global Fabric root is not a directory: {path}",
594
+ "cli.install.preflight.error.parent-not-dir": "Global Fabric root parent is not a directory: {path}",
595
+ "cli.install.preflight.error.not-writable": "{label} is not writable: {path} ({reason})",
596
+ "cli.install.preflight.error.git-required": "git is required for --url installs but was not available: {reason}",
597
+ "cli.install.preflight.label.target": "Target",
598
+ "cli.install.preflight.label.global-root": "Global Fabric root",
599
+ "cli.install.preflight.label.global-root-parent": "Global Fabric root parent",
600
+ "cli.install.guidance.more": "More: docs/surfaces.md explains when to use CLI vs Skill vs MCP.",
601
+ "cli.install.validate.passed": "Validation passed \u2713 (config / hook paths / events all ready)",
602
+ "cli.install.validate.failed": "Validation failed: {count} error(s)",
603
+ "cli.install.validate.failed-item": " - {error}",
604
+ "cli.install.hooks.uptodate": "hooks & skills already up to date ({count} items)",
605
+ "cli.install.hooks.installed": "installed skill\xD7{skills} + hook\xD7{hooks}",
606
+ "cli.install.mcp.configured": "MCP configured: {clients}",
607
+ "cli.install.mcp.none": "no MCP clients to configure",
608
+ "cli.install.scan.finding.framework": "Detected: {framework} project",
609
+ "cli.install.scan.finding.scale": "Scale: {files} files \xB7 {entries} entry points",
610
+ "cli.install.rollback.feedback": "Rolled back {count} change(s); project left unchanged.",
581
611
  "cli.install.stages.skipped": "skipped",
582
612
  "cli.install.stages.completed": "completed",
583
613
  "cli.install.stages.failed": "failed",
@@ -587,6 +617,12 @@ var enMessages = {
587
617
  "cli.install.pipeline.title": "Fabric Install",
588
618
  "cli.install.pipeline.complete": "Fabric Install Complete",
589
619
  "cli.install.pipeline.running": "Running {count} stages...",
620
+ // TASK-004: a first-ever install gets an onboarding-tone intro; a re-install
621
+ // keeps the terse "Running N stages" line. {count} = total stages.
622
+ "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.",
623
+ // TASK-004: the single collapsed health-check card title for a fully-idempotent
624
+ // re-install. {count} = total stages. Detail is behind --verbose.
625
+ "cli.install.healthcheck.title": "\u2713 Fabric is up to date \xB7 {count} stages ready \xB7 no changes",
590
626
  "cli.install.pipeline.label.preflight": "Preflight check",
591
627
  "cli.install.pipeline.label.env": "Environment setup",
592
628
  "cli.install.pipeline.label.store": "Store configuration",
@@ -630,11 +666,15 @@ var enMessages = {
630
666
  "cli.install.wizard.invalid-select": "Invalid value. Use one of: {options}.",
631
667
  "cli.install.wizard.cancelled": "Fabric install cancelled before execution.",
632
668
  "cli.install.capabilities.title": "Client capability summary",
669
+ // C-006 (TASK-004): print a single one-line capability summary by default and
670
+ // let the summary card lead the closing impression; the full 4×6 per-client
671
+ // table only renders under --verbose. {count} = detected client count.
672
+ "cli.install.capabilities.summaryLine": "Detected {count} client(s) and configured their capabilities (run with --verbose for the per-client table).",
633
673
  // v2.0.0-rc.37 NEW-22: post-install restart banner. The MCP server is
634
674
  // spawned by the client; already-running Claude Code / Codex
635
675
  // sessions won't pick up the new mcp config until they restart.
636
676
  "cli.install.restart-banner": "Restart hint: any already-running Claude Code / Codex CLI session must restart to pick up the new MCP server config; new sessions will autoload the Fabric tools.",
637
- "cli.install.next-steps": 'Next steps \u2014 get your first value:\n 1. Restart your AI client (Claude Code / Codex). It now auto-surfaces this project\'s knowledge to the assistant.\n 2. Seed knowledge: just work normally \u2014 when you make a decision or hit a pitfall, the fabric-archive skill proposes an entry. Or run the fabric-import skill to backfill from git history.\n 3. Verify it works: ask your AI "what does Fabric know about this repo?", or run `fabric doctor` to check health.',
677
+ "cli.install.next-steps": "Next steps \u2014 get your first value:\n 1. Restart your AI client (Claude Code / Codex). It now auto-surfaces this project's knowledge to the assistant.\n 2. Seed knowledge: just work normally \u2014 when you make a decision or hit a pitfall, the fabric-archive skill proposes an entry. Or run the fabric-archive skill's source mode to backfill from git history.\n 3. Verify it works: ask your AI \"what does Fabric know about this repo?\", or run `fabric doctor` to check health.",
638
678
  "cli.install.store-bind-nudge": "\u{1F4A1} Mounted store(s) not bound to this project: {aliases}. Run `fabric store bind {first}` to read their knowledge here, then `fabric store switch-write {first}` to write team knowledge into it.",
639
679
  // C1/C5: semantic-search interactive copy routed through t().
640
680
  "cli.install.semantic.prompt": "Enable vector semantic search? (the first recall downloads an embedding model)",
@@ -651,6 +691,25 @@ var enMessages = {
651
691
  "cli.install.store.setup.prompt": "Set up a knowledge store for this project?",
652
692
  "cli.install.store.setup.bind-label": "bind mounted: {alias}",
653
693
  "cli.install.store.setup.already-bound": "already bound to this project: {aliases} \u2713",
694
+ // W2 dual-slot (TASK-002): personal slot + team slot status / prompt copy. The
695
+ // team slot is named by CATEGORY (team-class), and rows show the store's REAL
696
+ // alias — the copy MUST NOT imply the store has to be aliased literally `team`
697
+ // (KT-MOD-0001 naming-axis trap).
698
+ "cli.install.store.slot.personal.status": "Personal store (machine-wide): '{alias}' \u2713",
699
+ "cli.install.store.slot.personal.absent": "Personal store (machine-wide): not set up yet",
700
+ "cli.install.store.slot.personal.multi-none": "Personal store (machine-wide): {count} mounted, none active yet",
701
+ "cli.install.store.slot.personal.multi-prompt": "Pick this machine's active personal store:",
702
+ "cli.install.store.slot.personal.multi-active-label": "'{alias}' (current active)",
703
+ "cli.install.store.slot.personal.multi-switch-label": "switch to '{alias}'",
704
+ "cli.install.store.slot.personal.multi-new-label": "create a new local personal store",
705
+ "cli.install.store.slot.personal.multi-new-hint": "a fresh empty personal store, set as active",
706
+ "cli.install.store.slot.personal.new-alias": "alias for the new personal store:",
707
+ "cli.install.store.slot.personal.switched": "active personal store switched to '{alias}'",
708
+ "cli.install.store.slot.team.status": "Team store (team-class): '{alias}' \u2713",
709
+ "cli.install.store.slot.team.empty": "Team store (team-class): none bound yet",
710
+ "cli.install.store.slot.team.prompt": "Team store (team-class) for this project \u2014 pick one, or join/create/skip:",
711
+ "cli.install.store.slot.team.bound-label": "keep current: {alias}",
712
+ "cli.install.store.slot.team.switch-label": "switch to mounted: {alias}",
654
713
  "cli.install.store.skip-label": "skip",
655
714
  "cli.install.store.bind-mounted.skip-hint": "leave mounted stores unbound for now",
656
715
  "cli.install.store.project-coordinate": "Project coordinate in store '{store}':",
@@ -672,6 +731,9 @@ var enMessages = {
672
731
  "cli.install.store.unbound-note": "Note: The following stores are mounted but not bound to this project: {aliases}.",
673
732
  "cli.install.store.unbound-hint": " Run 'fabric store bind {first}' to bind one.",
674
733
  // C4: personal store clone-or-new.
734
+ // TASK-004: prefixed onto a first-install one-time prompt (language / personal
735
+ // store onboarding) so the user knows these questions only appear at first setup.
736
+ "cli.install.store.firstRunContext": "First-time setup \u2014 the following are one-time choices that appear only on first install:",
675
737
  "cli.install.store.personal.prompt": "No personal store on this machine yet. Create a fresh one, or clone your existing one from a remote?",
676
738
  "cli.install.store.personal.new-label": "create local (default)",
677
739
  "cli.install.store.personal.new-hint": "a fresh empty personal store",
@@ -724,34 +786,47 @@ var enMessages = {
724
786
  "cli.uninstall.args.target.description": "Target project path. Defaults to --target, then EXTERNAL_FIXTURE_PATH, then cwd.",
725
787
  "cli.uninstall.args.debug.description": "Print target resolution details to stderr.",
726
788
  "cli.uninstall.args.yes.description": "Accept the current uninstall plan and run without the TTY wizard.",
789
+ "cli.uninstall.args.verbose.description": "Show per-path detail counts for each stage instead of the condensed result line.",
790
+ "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.",
727
791
  "cli.uninstall.args.dry-run.description": "Print the uninstall plan without removing files or running follow-up stages.",
728
792
  "cli.uninstall.plan.title": "Fabric uninstall plan",
729
793
  // C3: mirror install's phase banner ("Fabric install 将按 N 个阶段执行").
730
794
  "cli.uninstall.plan.phase-banner": "Fabric uninstall runs in {total} phases",
731
795
  "cli.uninstall.plan.target": "Target: {target}",
732
- "cli.uninstall.plan.actions": "Plan: scaffold={scaffold} bootstrap={bootstrap} mcp={mcp}",
796
+ "cli.uninstall.plan.actions": "Plan: bootstrap={bootstrap} mcp={mcp} scaffold={scaffold} unbind-store={store}",
733
797
  "cli.uninstall.plan.detected": "Detected clients: {clients}",
734
798
  "cli.uninstall.plan.preserves": "Preserves:",
735
799
  "cli.uninstall.plan.preserves.stores": "global knowledge stores, never deleted by project uninstall",
736
800
  "cli.uninstall.plan.preview-title": "Fabric uninstall dry run",
737
- "cli.uninstall.plan.preview-result": "scaffold={scaffold} bootstrap={bootstrap} mcp={mcp}",
738
801
  "cli.uninstall.plan.scaffold-entries.title": "Scaffold entries:",
739
- "cli.uninstall.stages.scaffold": "Removing scaffold artifacts...",
740
- "cli.uninstall.stages.bootstrap": "Removing bootstrap (Skills + hooks)...",
741
- "cli.uninstall.stages.mcp": "Un-registering MCP clients...",
802
+ // W4: shared OutputRenderer pipeline — section bar title + per-stage labels,
803
+ // the symmetric inverse of cli.install.pipeline.*.
804
+ "cli.uninstall.pipeline.title": "Fabric Uninstall",
805
+ "cli.uninstall.pipeline.label.bootstrap": "Skills & hooks",
806
+ "cli.uninstall.pipeline.label.mcp": "MCP server",
807
+ "cli.uninstall.pipeline.label.store": "Store unbind",
808
+ "cli.uninstall.pipeline.label.scaffold": "Scaffold cleanup",
809
+ "cli.uninstall.pipeline.label.validate": "Verify cleared",
742
810
  "cli.uninstall.stages.completed": "completed",
743
811
  "cli.uninstall.stages.completed-with-errors": "completed with errors",
744
812
  "cli.uninstall.stages.failed": "failed",
813
+ "cli.uninstall.stages.failed-hint": "Check the error details above. Run with --debug for more information.",
814
+ "cli.uninstall.stages.uptodate": "nothing to remove ({count} already absent)",
815
+ "cli.uninstall.stages.summary": "removed={removed} skipped={skipped} errors={errors}",
816
+ "cli.uninstall.stages.removed-count": "{count} removed",
745
817
  "cli.uninstall.summary.title": "Uninstall summary",
746
818
  "cli.uninstall.summary.body": "removed={removed} skipped={skipped} errors={errors}",
819
+ "cli.uninstall.healthcheck.title": "\u2713 Fabric already absent \xB7 nothing to remove",
747
820
  "cli.uninstall.wizard.intro": "Fabric uninstall",
748
821
  "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)",
749
822
  "cli.uninstall.wizard.select.scaffold.label": "Scaffold artifacts",
750
823
  "cli.uninstall.wizard.select.scaffold.hint": "Scaffolded files under .fabric/",
751
- "cli.uninstall.wizard.select.bootstrap.label": "Bootstrap (Skills + hooks)",
752
- "cli.uninstall.wizard.select.bootstrap.hint": "Per-client skills and git hooks",
824
+ "cli.uninstall.wizard.select.bootstrap.label": "Skills & hooks",
825
+ "cli.uninstall.wizard.select.bootstrap.hint": "Per-client skills and hook scripts + config",
753
826
  "cli.uninstall.wizard.select.mcp.label": "MCP client registration",
754
827
  "cli.uninstall.wizard.select.mcp.hint": "Un-register the fabric MCP server from clients",
828
+ "cli.uninstall.wizard.select.store.label": "Unbind team store (this project)",
829
+ "cli.uninstall.wizard.select.store.hint": "Clears this project's store binding; the global store is never deleted",
755
830
  "cli.uninstall.wizard.execute.confirm": "Execute this uninstall plan now? [Y/n]",
756
831
  "cli.uninstall.wizard.outro": "Uninstall plan accepted. Running Fabric uninstall...",
757
832
  "cli.uninstall.wizard.cancelled": "Fabric uninstall cancelled before execution.",
@@ -982,6 +1057,8 @@ var enMessages = {
982
1057
  "cli.store.detached": "detached '{alias}' \u2014 on-disk store tree left intact (detach \u2260 delete)",
983
1058
  "cli.store.bound": "bound required store '{id}' ({count} required)",
984
1059
  "cli.store.switch-write": "active write store set to '{alias}' for this project",
1060
+ "cli.store.switch-personal": "active personal store set to '{alias}' for this machine",
1061
+ "cli.store.routed": "write route: scope '{scope}' \u2192 store '{alias}'",
985
1062
  "cli.sync.deferred": "{count} store(s) offline \u2014 push deferred; re-run `fabric sync` when online",
986
1063
  "cli.sync.paused": "sync paused on a conflict \u2014 resolve it, then run `fabric sync --continue` (or `--abort`)",
987
1064
  "cli.metrics.invalid-since": '--since: invalid duration "{raw}" (expected e.g. 24h, 7d, 30m)',
@@ -1029,19 +1106,15 @@ var zhCNMessages = {
1029
1106
  "cli.shared.invalid-host-empty": "\u65E0\u6548 host\uFF1A<empty>",
1030
1107
  "cli.shared.invalid-port": "\u65E0\u6548\u7AEF\u53E3\uFF1A{value}",
1031
1108
  "cli.shared.error": "\u9519\u8BEF",
1032
- // EPIC-011: 分组帮助显示 i18n 键
1033
- "cli.help.group.setup.install": "\u5728\u5F53\u524D\u4ED3\u5E93\u521D\u59CB\u5316 Fabric",
1034
- "cli.help.group.setup.config": "\u914D\u7F6E Fabric \u8BBE\u7F6E",
1035
- "cli.help.group.daily.sync": "\u4E0E\u8FDC\u7A0B store \u540C\u6B65\u56E2\u961F\u77E5\u8BC6",
1036
- "cli.help.group.daily.info": "\u663E\u793A\u9879\u76EE\u72B6\u6001",
1037
- "cli.help.group.diagnostic.doctor": "\u68C0\u67E5 Fabric \u5065\u5EB7\u72B6\u6001\u5E76\u4FEE\u590D\u95EE\u9898",
1038
- "cli.help.group.advanced.store": "\u7BA1\u7406\u77E5\u8BC6 store (\u8BE6\u89C1: fabric store --help)",
1039
- "cli.help.group.advanced.whoami": "\u663E\u793A\u673A\u5668\u6807\u8BC6",
1040
- "cli.help.group.advanced.whoami.deprecated": "\u5DF2\u5F03\u7528 \u2192 info --global",
1041
- "cli.help.group.advanced.status": "\u663E\u793A\u9879\u76EE\u72B6\u6001",
1042
- "cli.help.group.advanced.status.deprecated": "\u5DF2\u5F03\u7528 \u2192 info",
1043
- "cli.help.group.advanced.scope-explain": "\u89E3\u91CA scope",
1044
- "cli.help.group.advanced.scope-explain.deprecated": "\u5DF2\u5F03\u7528 \u2192 info scope",
1109
+ // EPIC-011 / W3-F: 分组帮助显示 i18n 键 (Knowledge/Project/Maintain)
1110
+ "cli.help.group.knowledge.store": "\u7BA1\u7406\u77E5\u8BC6 store (\u8BE6\u89C1: fabric store --help)",
1111
+ "cli.help.group.knowledge.sync": "\u4E0E\u8FDC\u7A0B store \u540C\u6B65\u56E2\u961F\u77E5\u8BC6",
1112
+ "cli.help.group.project.install": "\u5728\u5F53\u524D\u4ED3\u5E93\u521D\u59CB\u5316 Fabric",
1113
+ "cli.help.group.project.config": "\u914D\u7F6E Fabric \u8BBE\u7F6E",
1114
+ "cli.help.group.project.info": "\u663E\u793A\u9879\u76EE\u72B6\u6001",
1115
+ "cli.help.group.project.inspect": "\u663E\u793A\u672C\u4F1A\u8BDD SessionStart \u6CE8\u5165\u4E86\u4EC0\u4E48",
1116
+ "cli.help.group.maintain.doctor": "\u68C0\u67E5 Fabric \u5065\u5EB7\u72B6\u6001\u5E76\u4FEE\u590D\u95EE\u9898",
1117
+ "cli.help.group.maintain.audit": "\u77E5\u8BC6\u4E0E\u9065\u6D4B\u5BA1\u8BA1 (cite/conflicts/history/metrics)",
1045
1118
  "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",
1046
1119
  "cli.config.args.target.description": "\u76EE\u6807\u9879\u76EE\u76EE\u5F55\uFF08\u9ED8\u8BA4\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF09\u3002",
1047
1120
  "cli.config.clients.claude": "Claude Code CLI",
@@ -1309,6 +1382,11 @@ var zhCNMessages = {
1309
1382
  "doctor.check.skill_ref_mirror.ok": "`.claude/skills/<slug>/ref/` \u4E0E `.codex/skills/<slug>/ref/` \u5B57\u8282\u4E00\u81F4\u3002",
1310
1383
  "doctor.check.skill_ref_mirror.message": "\u6709 {count} \u4E2A ref \u6587\u4EF6\u5728 `.claude/skills/` \u4E0E `.codex/skills/` \u4E4B\u95F4\u4E0D\u4E00\u81F4\uFF08\u8DEF\u5F84: {list}\uFF09\u3002\u53EF\u80FD\u67D0\u7AEF\u88AB\u624B\u52A8\u7F16\u8F91\u6216 install \u5199\u5165\u5931\u8D25\u3002",
1311
1384
  "doctor.check.skill_ref_mirror.remediation": "\u8DD1 `fabric install` \u4ECE canonical templates \u91CD\u5199\u4E24\u7AEF ref \u5B50\u6811\u4EE5\u6062\u590D\u4E00\u81F4\u3002",
1385
+ // ux-w2-2: retired-reference (stale pointer) lint。
1386
+ "doctor.check.retired_reference.name": "\u9000\u5F79\u5F15\u7528",
1387
+ "doctor.check.retired_reference.ok": "bootstrap\u3001SKILL.md\u3001\u5DF2\u5B89\u88C5 hooks \u4E2D\u65E0\u6B8B\u7559\u7684\u9000\u5F79\u5DE5\u5177/\u5B57\u6BB5\u540D\u3002",
1388
+ "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}",
1389
+ "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",
1312
1390
  // 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 浪费 + 加载延迟)。
1313
1391
  "doctor.check.skill_token_budget.name": "Skill token budget",
1314
1392
  "doctor.check.skill_token_budget.ok": "\u6240\u6709 .claude/skills/<slug>/SKILL.md \u5728 token budget \u5185 (warn 5K / error 10K)\u3002",
@@ -1336,7 +1414,7 @@ var zhCNMessages = {
1336
1414
  // rc.36 TASK-05 (P0-8): empty-tags ratio warn.
1337
1415
  "doctor.check.knowledge_tags_empty.name": "Knowledge tags coverage",
1338
1416
  "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",
1339
- "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 / fabric-import skill \u5E94\u6BCF\u4E2A entry \u4EA7 2-4 \u4E2A tag\u3002",
1417
+ "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",
1340
1418
  "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",
1341
1419
  // rc.36 TASK-09 (P1-NEW1): drift_detected 未消化告警。
1342
1420
  "doctor.check.drift_unconsumed.name": "Knowledge drift unconsumed",
@@ -1388,7 +1466,7 @@ var zhCNMessages = {
1388
1466
  "doctor.check.underseeded.ok": "\u77E5\u8BC6\u5E93\u5DF2\u6709 {count} \u4E2A canonical entries\uFF08>= {threshold}\uFF09\u3002",
1389
1467
  "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",
1390
1468
  "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",
1391
- "doctor.check.underseeded.remediation": "\u8FD0\u884C fabric-import Skill\uFF08`/fabric-import`\uFF09\u4ECE git history \u4E0E\u73B0\u6709\u6587\u6863\u56DE\u586B knowledge\u3002",
1469
+ "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",
1392
1470
  "doctor.check.session_hints_stale.name": "Knowledge session-hints stale",
1393
1471
  "doctor.check.session_hints_stale.ok": ".fabric/.cache/ \u4E0B\u6CA1\u6709\u8D85\u8FC7 {days} \u5929\u7684 session-hints cache files\u3002",
1394
1472
  "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",
@@ -1431,7 +1509,7 @@ var zhCNMessages = {
1431
1509
  // rc.31 BUG-G2/G5: promote-ledger invariant check.
1432
1510
  "doctor.check.promote_ledger_invariant.name": "Promote ledger invariant",
1433
1511
  "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",
1434
- "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_extract_knowledge \u2192 \u7F3A\u5C11 propose \u4E8B\u4EF6\uFF09\u3002",
1512
+ "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",
1435
1513
  "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",
1436
1514
  "doctor.check.promote_ledger_invariant.remediation": "rc.31 \u8D77 review.approve \u4F1A\u8865\u53D1 knowledge_proposed \u4E8B\u4EF6\u4EE5\u7EF4\u62A4\u4E0D\u53D8\u91CF\uFF1B\u65B0 approve \u540E\u518D\u8DD1\u4E00\u6B21 fabric doctor \u5373\u53EF\u6062\u590D\u3002\u5386\u53F2\u5931\u8861\u4EC5\u662F\u53EF\u89C2\u6D4B\u6027\u6307\u793A\uFF0C\u4E0D\u5F71\u54CD KB \u529F\u80FD\u3002",
1437
1515
  // rc.35 TASK-04 (P0-9.b): global_cli_outdated.
@@ -1451,7 +1529,7 @@ var zhCNMessages = {
1451
1529
  "doctor.check.store_scope_lint.name": "Store scope lint",
1452
1530
  "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",
1453
1531
  "doctor.check.store_scope_lint.message": "{total} \u4E2A store scope \u95EE\u9898: {breakdown}\u3002\u4F8B\u5982 {sample}\u3002",
1454
- "doctor.check.store_scope_lint.remediation": "\u8C03 `fabric store backfill-scope` \u8865\u7F3A\u5931\u7684 semantic_scope/visibility_store;`fabric store re-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",
1532
+ "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",
1455
1533
  // v2.2 Goal B (G-INTEGRITY): store stable_id collision + layer mismatch lints。
1456
1534
  "doctor.check.stable_id_collision.name": "Stable ID collision",
1457
1535
  "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',
@@ -1486,7 +1564,7 @@ var zhCNMessages = {
1486
1564
  "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",
1487
1565
  "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",
1488
1566
  "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",
1489
- "doctor.check.broad_index_drift.remediation": "\u8DD1 `fabric-audit` skill \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",
1567
+ "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",
1490
1568
  // v2.2 Goal B (G-AGE): knowledge decay lints (orphan_demote + stale_archive)。
1491
1569
  "doctor.check.orphan_demote.name": "Knowledge orphan demote",
1492
1570
  "doctor.check.orphan_demote.ok": "\u6CA1\u6709 canonical knowledge entries \u8D85\u8FC7\u6309 maturity \u8BBE\u5B9A\u7684 inactivity threshold\u3002",
@@ -1498,6 +1576,18 @@ var zhCNMessages = {
1498
1576
  "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",
1499
1577
  "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",
1500
1578
  "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)",
1579
+ // v2.2 C1: knowledge promotion lint (promotion_candidate, info kind)。
1580
+ "doctor.check.promotion_candidate.name": "Knowledge promotion candidate",
1581
+ "doctor.check.promotion_candidate.ok": "\u6CA1\u6709 verified knowledge entries \u8FBE\u5230 proven \u664B\u5347\u7684 related \u5165\u5EA6\u95E8\u69DB\u3002",
1582
+ "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",
1583
+ "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",
1584
+ "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)",
1585
+ // v2.2 C1: broad review-recheck lint (broad_review_recheck, info kind)。
1586
+ "doctor.check.broad_review_recheck.name": "Knowledge broad review recheck",
1587
+ "doctor.check.broad_review_recheck.ok": "\u6CA1\u6709 broad-scope knowledge entries \u8D85\u671F\u672A\u505A review \u518D\u786E\u8BA4\u3002",
1588
+ "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",
1589
+ "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",
1590
+ "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",
1501
1591
  // project-scope binding 回填 lint (unbound_project)。
1502
1592
  "doctor.check.unbound_project.name": "Project-scope binding",
1503
1593
  "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",
@@ -1508,11 +1598,6 @@ var zhCNMessages = {
1508
1598
  "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",
1509
1599
  "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",
1510
1600
  "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',
1511
- "doctor.check.router_chain_ref.name": "Router chain refs",
1512
- "doctor.check.router_chain_ref.ok": "fabric/ \u8DEF\u7531\u5668 S_CHAIN \u91CC\u7684\u6BCF\u4E2A fabric-* \u5F15\u7528\u90FD\u6307\u5411\u5DF2\u5B89\u88C5\u7684 leaf skill\u3002",
1513
- "doctor.check.router_chain_ref.message.singular": "{count} \u4E2A fabric/ \u8DEF\u7531\u5668 S_CHAIN \u5F15\u7528\u6307\u5411\u4E0D\u5728 install set \u7684 skill\uFF1A{list}\u3002\u8BE5 chain \u6B65\u9AA4\u5728\u8FD0\u884C\u65F6\u4F1A\u65AD\u94FE\u3002",
1514
- "doctor.check.router_chain_ref.message.plural": "{count} \u4E2A fabric/ \u8DEF\u7531\u5668 S_CHAIN \u5F15\u7528\u6307\u5411\u4E0D\u5728 install set \u7684 skill\uFF1A{list}\u3002\u8FD9\u4E9B chain \u6B65\u9AA4\u5728\u8FD0\u884C\u65F6\u4F1A\u65AD\u94FE\u3002",
1515
- "doctor.check.router_chain_ref.remediation": "\u7F16\u8F91 templates/skills/fabric/SKILL.md \u7684 S_CHAIN \u8868\uFF0C\u6539\u4E3A\u5F15\u7528\u771F\u5B9E\u7684 leaf skill\uFF08\u5DF2\u5B89\u88C5\u7684 fabric-* \u4E4B\u4E00\uFF09\uFF0C\u6216\u5220\u9664\u8BE5\u9648\u65E7 chain \u884C\u3002",
1516
1601
  "doctor.check.onboard_coverage.name": "Onboard coverage",
1517
1602
  "doctor.check.onboard_coverage.ok.complete": "Onboard coverage\uFF1A{filledCount}/{total} \u2713\uFF08opted-out\uFF1A{optedOutCount}\uFF09\u3002",
1518
1603
  "doctor.check.onboard_coverage.message.incomplete": "\u5C1A\u672A\u8986\u76D6\u7684 onboard slots\uFF1A[{missingSlots}]\u3002{filledCount}/{total} filled\uFF1B{optedOutCount} opted-out\u3002",
@@ -1540,6 +1625,8 @@ var zhCNMessages = {
1540
1625
  "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",
1541
1626
  "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)",
1542
1627
  "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)",
1628
+ // TASK-004: --verbose 展开重装折叠的逐 phase 明细 + 完整客户端能力表。
1629
+ "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",
1543
1630
  // rc.35 TASK-08 (P0-5/6): --force-skills-only。
1544
1631
  "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",
1545
1632
  "cli.install.force-skills-only.banner": "\u53EA\u5237\u65B0 fabric Skill \u6A21\u677F",
@@ -1568,7 +1655,26 @@ var zhCNMessages = {
1568
1655
  "cli.install.steps.bootstrap-claude": "\u5DF2\u66F4\u65B0 CLAUDE.md \u7684 @-import \u5F15\u7528",
1569
1656
  "cli.install.steps.bootstrap-codex": "\u5DF2\u66F4\u65B0 AGENTS.md \u7684 fabric:bootstrap managed block",
1570
1657
  "cli.install.stages.mcp": "\u6B63\u5728\u914D\u7F6E MCP \u5BA2\u6237\u7AEF...",
1571
- "cli.install.stages.hooks": "\u6B63\u5728\u5B89\u88C5 git hooks...",
1658
+ "cli.install.stages.hooks": "\u6B63\u5728\u5B89\u88C5 hook \u4E0E skill...",
1659
+ "cli.install.preflight.error.no-home": "\u65E0\u6CD5\u786E\u5B9A global root \u7684 home \u76EE\u5F55",
1660
+ "cli.install.preflight.error.not-dir": "\u5168\u5C40 Fabric root \u4E0D\u662F\u76EE\u5F55: {path}",
1661
+ "cli.install.preflight.error.parent-not-dir": "\u5168\u5C40 Fabric root \u7684\u7236\u76EE\u5F55\u4E0D\u662F\u76EE\u5F55: {path}",
1662
+ "cli.install.preflight.error.not-writable": "{label} \u4E0D\u53EF\u5199: {path} ({reason})",
1663
+ "cli.install.preflight.error.git-required": "--url \u5B89\u88C5\u9700\u8981 git,\u4F46\u5F53\u524D\u4E0D\u53EF\u7528: {reason}",
1664
+ "cli.install.preflight.label.target": "\u76EE\u6807\u76EE\u5F55",
1665
+ "cli.install.preflight.label.global-root": "\u5168\u5C40 Fabric root",
1666
+ "cli.install.preflight.label.global-root-parent": "\u5168\u5C40 Fabric root \u7684\u7236\u76EE\u5F55",
1667
+ "cli.install.guidance.more": "\u66F4\u591A: docs/surfaces.md \u8BF4\u660E\u4F55\u65F6\u7528 CLI / Skill / MCP\u3002",
1668
+ "cli.install.validate.passed": "\u5B89\u88C5\u6821\u9A8C\u901A\u8FC7 \u2713(config / hooks \u8DEF\u5F84 / events \u5747\u5C31\u7EEA)",
1669
+ "cli.install.validate.failed": "\u5B89\u88C5\u6821\u9A8C\u5931\u8D25:{count} \u4E2A\u95EE\u9898",
1670
+ "cli.install.validate.failed-item": " - {error}",
1671
+ "cli.install.hooks.uptodate": "hook \u4E0E skill \u5DF2\u6700\u65B0,\u65E0\u9700\u6539\u52A8({count} \u9879)",
1672
+ "cli.install.hooks.installed": "\u5DF2\u88C5 skill\xD7{skills} + hook\xD7{hooks}",
1673
+ "cli.install.mcp.configured": "\u5DF2\u914D\u7F6E MCP:{clients}",
1674
+ "cli.install.mcp.none": "\u65E0\u9700\u914D\u7F6E MCP \u5BA2\u6237\u7AEF",
1675
+ "cli.install.scan.finding.framework": "\u68C0\u6D4B\u5230: {framework} \u9879\u76EE",
1676
+ "cli.install.scan.finding.scale": "\u89C4\u6A21: {files} \u6587\u4EF6 \xB7 {entries} \u4E2A\u5165\u53E3",
1677
+ "cli.install.rollback.feedback": "\u5DF2\u56DE\u6EDA {count} \u9879\u6539\u52A8,\u9879\u76EE\u4FDD\u6301\u539F\u72B6\u3002",
1572
1678
  "cli.install.stages.skipped": "\u5DF2\u8DF3\u8FC7",
1573
1679
  "cli.install.stages.completed": "\u5DF2\u5B8C\u6210",
1574
1680
  "cli.install.stages.failed": "\u5931\u8D25",
@@ -1578,6 +1684,12 @@ var zhCNMessages = {
1578
1684
  "cli.install.pipeline.title": "Fabric \u5B89\u88C5",
1579
1685
  "cli.install.pipeline.complete": "Fabric \u5B89\u88C5\u5B8C\u6210",
1580
1686
  "cli.install.pipeline.running": "\u5C06\u6309 {count} \u4E2A\u9636\u6BB5\u6267\u884C",
1687
+ // TASK-004: 首装走 onboarding 定调(欢迎语 + 一次性设置说明);重装保持简洁的
1688
+ // "将按 N 阶段执行"。{count} = 阶段总数。
1689
+ "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",
1690
+ // TASK-004: 重装且全程幂等(无任何 install)时折叠成的单张体检卡片标题。
1691
+ // {count} = 阶段总数。明细走 --verbose。
1692
+ "cli.install.healthcheck.title": "\u2713 Fabric \u5DF2\u662F\u6700\u65B0 \xB7 {count} \u9636\u6BB5\u5C31\u7EEA \xB7 \u65E0\u6539\u52A8",
1581
1693
  "cli.install.pipeline.label.preflight": "\u5168\u5C40\u4E0E\u9879\u76EE\u9884\u68C0",
1582
1694
  "cli.install.pipeline.label.env": "\u9879\u76EE\u73AF\u5883\u521D\u59CB\u5316",
1583
1695
  "cli.install.pipeline.label.store": "\u77E5\u8BC6\u5E93\u62D3\u6251",
@@ -1621,11 +1733,14 @@ var zhCNMessages = {
1621
1733
  "cli.install.wizard.invalid-select": "\u65E0\u6548\u8F93\u5165\u3002\u53EF\u9009\u503C\uFF1A{options}\u3002",
1622
1734
  "cli.install.wizard.cancelled": "Fabric \u5B89\u88C5\u5DF2\u5728\u6267\u884C\u524D\u53D6\u6D88\u3002",
1623
1735
  "cli.install.capabilities.title": "\u5BA2\u6237\u7AEF\u80FD\u529B\u6458\u8981",
1736
+ // C-006 (TASK-004):默认只打一行能力摘要,让收尾的 summary card 主导收口印象;
1737
+ // 完整 4×6 能力表只在 --verbose 下展开。{count} = 检测到的客户端数。
1738
+ "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",
1624
1739
  // v2.0.0-rc.37 NEW-22: post-install 重启提示。MCP server 在 client 启动
1625
1740
  // 时 spawn, 已运行的 Claude Code / Codex session 不会自动加载
1626
1741
  // 新 mcp config — 必须重启才能拿到 Fabric tools。
1627
1742
  "cli.install.restart-banner": "\u91CD\u542F\u63D0\u793A: \u5DF2\u8FD0\u884C\u7684 Claude Code / Codex CLI session \u9700\u91CD\u542F\u624D\u80FD\u52A0\u8F7D\u65B0 MCP server \u914D\u7F6E;\u65B0\u4F1A\u8BDD\u4F1A\u81EA\u52A8\u4F7F\u7528 Fabric tools\u3002",
1628
- "cli.install.next-steps": "\u4E0B\u4E00\u6B65 \u2014\u2014 \u62FF\u5230\u7B2C\u4E00\u4EFD\u4EF7\u503C:\n 1. \u91CD\u542F\u4F60\u7684 AI \u5BA2\u6237\u7AEF (Claude Code / Codex)\u3002\u5B83\u73B0\u5728\u4F1A\u81EA\u52A8\u628A\u672C\u9879\u76EE\u7684\u77E5\u8BC6 surface (\u4E3B\u52A8\u5448\u73B0) \u7ED9\u52A9\u624B\u3002\n 2. \u6C89\u6DC0\u77E5\u8BC6: \u6B63\u5E38\u5E72\u6D3B\u5373\u53EF \u2014\u2014 \u5F53\u4F60\u505A\u51B3\u7B56\u6216\u8E29\u5751\u65F6, fabric-archive skill \u4F1A\u63D0\u8BAE\u5165\u5E93; \u6216\u8DD1 fabric-import skill \u4ECE git \u5386\u53F2\u56DE\u704C\u3002\n 3. \u9A8C\u8BC1\u751F\u6548: \u95EE\u4F60\u7684 AI\u300CFabric \u5BF9\u8FD9\u4E2A repo \u77E5\u9053\u4E9B\u4EC0\u4E48?\u300D, \u6216\u8DD1 `fabric doctor` \u67E5\u5065\u5EB7\u3002",
1743
+ "cli.install.next-steps": "\u4E0B\u4E00\u6B65 \u2014\u2014 \u62FF\u5230\u7B2C\u4E00\u4EFD\u4EF7\u503C:\n 1. \u91CD\u542F\u4F60\u7684 AI \u5BA2\u6237\u7AEF (Claude Code / Codex)\u3002\u5B83\u73B0\u5728\u4F1A\u81EA\u52A8\u628A\u672C\u9879\u76EE\u7684\u77E5\u8BC6 surface (\u4E3B\u52A8\u5448\u73B0) \u7ED9\u52A9\u624B\u3002\n 2. \u6C89\u6DC0\u77E5\u8BC6: \u6B63\u5E38\u5E72\u6D3B\u5373\u53EF \u2014\u2014 \u5F53\u4F60\u505A\u51B3\u7B56\u6216\u8E29\u5751\u65F6, fabric-archive skill \u4F1A\u63D0\u8BAE\u5165\u5E93; \u6216\u8DD1 fabric-archive skill \u7684 source mode \u4ECE git \u5386\u53F2\u56DE\u704C\u3002\n 3. \u9A8C\u8BC1\u751F\u6548: \u95EE\u4F60\u7684 AI\u300CFabric \u5BF9\u8FD9\u4E2A repo \u77E5\u9053\u4E9B\u4EC0\u4E48?\u300D, \u6216\u8DD1 `fabric doctor` \u67E5\u5065\u5EB7\u3002",
1629
1744
  "cli.install.store-bind-nudge": "\u{1F4A1} \u68C0\u6D4B\u5230\u5DF2\u6302\u8F7D\u4F46\u672A\u7ED1\u5B9A\u672C\u9879\u76EE\u7684\u77E5\u8BC6 store: {aliases}\u3002\u8FD0\u884C `fabric store bind {first}` \u628A\u5B83\u7684\u77E5\u8BC6\u63A5\u5165\u672C\u9879\u76EE, \u518D `fabric store switch-write {first}` \u8BBE\u4E3A\u56E2\u961F\u77E5\u8BC6\u7684\u5199\u5165\u76EE\u6807\u3002",
1630
1745
  // C1/C5: 语义搜索交互文案统一走 t(),英文术语首现加中文 gloss。
1631
1746
  "cli.install.semantic.prompt": "\u542F\u7528\u5411\u91CF\u8BED\u4E49\u641C\u7D22 (vector semantic search)\uFF1F(\u9996\u6B21\u53EC\u56DE recall \u65F6\u624D\u4F1A\u4E0B\u8F7D\u5D4C\u5165\u6A21\u578B)",
@@ -1642,6 +1757,24 @@ var zhCNMessages = {
1642
1757
  "cli.install.store.setup.prompt": "\u4E3A\u672C\u9879\u76EE\u8BBE\u7F6E\u77E5\u8BC6 store\uFF1F",
1643
1758
  "cli.install.store.setup.bind-label": "\u7ED1\u5B9A\u5DF2\u6302\u8F7D: {alias}",
1644
1759
  "cli.install.store.setup.already-bound": "\u5DF2\u7ED1\u5B9A\u672C\u9879\u76EE: {aliases} \u2713",
1760
+ // W2 dual-slot (TASK-002): 个人库槽 + 团队库槽 的状态 / 提示文案。团队库槽按
1761
+ // 「类别」命名(team 类),候选项显示 store 的真实 alias —— 文案 MUST NOT 暗示
1762
+ // 该库必须叫 'team'(team 是类别非别名,守 KT-MOD-0001 命名撞轴)。
1763
+ "cli.install.store.slot.personal.status": "\u4E2A\u4EBA\u5E93(\u672C\u673A\u5168\u5C40): '{alias}' \u2713",
1764
+ "cli.install.store.slot.personal.absent": "\u4E2A\u4EBA\u5E93(\u672C\u673A\u5168\u5C40): \u5C1A\u672A\u5EFA\u7ACB",
1765
+ "cli.install.store.slot.personal.multi-none": "\u4E2A\u4EBA\u5E93(\u672C\u673A\u5168\u5C40): \u5DF2\u6302 {count} \u4E2A,\u5C1A\u672A\u9009\u5B9A active",
1766
+ "cli.install.store.slot.personal.multi-prompt": "\u9009\u62E9\u672C\u673A\u5F53\u524D\u8981\u7528\u7684 personal store(active):",
1767
+ "cli.install.store.slot.personal.multi-active-label": "'{alias}'(\u5F53\u524D active)",
1768
+ "cli.install.store.slot.personal.multi-switch-label": "\u5207\u5230 '{alias}'",
1769
+ "cli.install.store.slot.personal.multi-new-label": "\u65B0\u5EFA\u672C\u5730 personal store",
1770
+ "cli.install.store.slot.personal.multi-new-hint": "\u5168\u65B0\u7A7A personal store,\u5E76\u8BBE\u4E3A active",
1771
+ "cli.install.store.slot.personal.new-alias": "\u65B0 personal store \u7684\u522B\u540D:",
1772
+ "cli.install.store.slot.personal.switched": "\u5DF2\u5C06\u672C\u673A\u6D3B\u52A8 personal store \u5207\u5230 '{alias}'",
1773
+ "cli.install.store.slot.team.status": "\u56E2\u961F\u5E93(team \u7C7B): '{alias}' \u2713",
1774
+ "cli.install.store.slot.team.empty": "\u56E2\u961F\u5E93(team \u7C7B): \u5C1A\u672A\u7ED1\u5B9A",
1775
+ "cli.install.store.slot.team.prompt": "\u4E3A\u672C\u9879\u76EE\u6311\u9009\u56E2\u961F\u5E93(team \u7C7B) \u2014\u2014 \u9009\u4E00\u4E2A,\u6216\u52A0\u5165\u5DF2\u6709/\u65B0\u5EFA/\u8DF3\u8FC7:",
1776
+ "cli.install.store.slot.team.bound-label": "\u4FDD\u6301\u5F53\u524D: {alias}",
1777
+ "cli.install.store.slot.team.switch-label": "\u5207\u5230\u5DF2\u6302\u8F7D: {alias}",
1645
1778
  "cli.install.store.skip-label": "\u8DF3\u8FC7",
1646
1779
  "cli.install.store.bind-mounted.skip-hint": "\u6682\u4E0D\u7ED1\u5B9A\u5DF2\u6302\u8F7D\u7684 store",
1647
1780
  "cli.install.store.project-coordinate": "\u5728 store '{store}' \u4E2D\u7684\u9879\u76EE\u5750\u6807 (project coordinate):",
@@ -1663,6 +1796,9 @@ var zhCNMessages = {
1663
1796
  "cli.install.store.unbound-note": "\u6CE8\u610F: \u4EE5\u4E0B store \u5DF2\u6302\u8F7D\u4F46\u672A\u7ED1\u5B9A\u5230\u672C\u9879\u76EE: {aliases}\u3002",
1664
1797
  "cli.install.store.unbound-hint": " \u8FD0\u884C 'fabric store bind {first}' \u7ED1\u5B9A\u5176\u4E00\u3002",
1665
1798
  // C4: personal store clone-or-new。
1799
+ // TASK-004: 首装时为额外的一次性提问(语言 / 个人库 onboarding)加的语境前缀,
1800
+ // 让用户知道这些问题只在首次设置时出现。
1801
+ "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:",
1666
1802
  "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",
1667
1803
  "cli.install.store.personal.new-label": "\u65B0\u5EFA\u672C\u5730 (\u9ED8\u8BA4)",
1668
1804
  "cli.install.store.personal.new-hint": "\u5168\u65B0\u7A7A personal store",
@@ -1715,34 +1851,47 @@ var zhCNMessages = {
1715
1851
  "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",
1716
1852
  "cli.uninstall.args.debug.description": "\u5C06\u76EE\u6807\u89E3\u6790\u7EC6\u8282\u8F93\u51FA\u5230 stderr\u3002",
1717
1853
  "cli.uninstall.args.yes.description": "\u63A5\u53D7\u5F53\u524D\u5378\u8F7D\u8BA1\u5212\u5E76\u8DF3\u8FC7 TTY \u5411\u5BFC\u76F4\u63A5\u6267\u884C\u3002",
1854
+ "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",
1855
+ "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",
1718
1856
  "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",
1719
1857
  "cli.uninstall.plan.title": "Fabric \u5378\u8F7D\u8BA1\u5212",
1720
1858
  // C3: 镜像 install 的阶段提示 (install 用 "Fabric install 将按 N 个阶段执行")。
1721
1859
  "cli.uninstall.plan.phase-banner": "Fabric uninstall \u5C06\u6309 {total} \u4E2A\u9636\u6BB5\u6267\u884C",
1722
1860
  "cli.uninstall.plan.target": "\u76EE\u6807\uFF1A{target}",
1723
- "cli.uninstall.plan.actions": "\u8BA1\u5212\uFF1Ascaffold={scaffold} bootstrap={bootstrap} mcp={mcp}",
1861
+ "cli.uninstall.plan.actions": "\u8BA1\u5212\uFF1Abootstrap={bootstrap} mcp={mcp} scaffold={scaffold} unbind-store={store}",
1724
1862
  "cli.uninstall.plan.detected": "\u68C0\u6D4B\u5230\u7684\u5BA2\u6237\u7AEF\uFF1A{clients}",
1725
1863
  "cli.uninstall.plan.preserves": "\u4FDD\u7559\u9879\uFF1A",
1726
1864
  "cli.uninstall.plan.preserves.stores": "\u5168\u5C40\u77E5\u8BC6 stores\uFF0C\u9879\u76EE\u5378\u8F7D\u6C38\u4E0D\u5220\u9664",
1727
1865
  "cli.uninstall.plan.preview-title": "Fabric \u5378\u8F7D dry run",
1728
- "cli.uninstall.plan.preview-result": "scaffold={scaffold} bootstrap={bootstrap} mcp={mcp}",
1729
1866
  "cli.uninstall.plan.scaffold-entries.title": "Scaffold \u5F85\u6E05\u7406\u9879\uFF1A",
1730
- "cli.uninstall.stages.scaffold": "\u6B63\u5728\u6E05\u7406 scaffold \u4EA7\u7269...",
1731
- "cli.uninstall.stages.bootstrap": "\u6B63\u5728\u79FB\u9664 bootstrap\uFF08Skills + hooks\uFF09...",
1732
- "cli.uninstall.stages.mcp": "\u6B63\u5728\u53CD\u6CE8\u518C MCP \u5BA2\u6237\u7AEF...",
1867
+ // W4: 共享 OutputRenderer pipeline —— section bar 标题 + 各阶段标签,install
1868
+ // pipeline 的对称逆。
1869
+ "cli.uninstall.pipeline.title": "Fabric \u5378\u8F7D",
1870
+ "cli.uninstall.pipeline.label.bootstrap": "Skills \u4E0E hooks",
1871
+ "cli.uninstall.pipeline.label.mcp": "MCP server",
1872
+ "cli.uninstall.pipeline.label.store": "\u89E3\u7ED1 store",
1873
+ "cli.uninstall.pipeline.label.scaffold": "\u6E05\u7406\u811A\u624B\u67B6",
1874
+ "cli.uninstall.pipeline.label.validate": "\u6821\u9A8C\u5DF2\u6E05\u7406",
1733
1875
  "cli.uninstall.stages.completed": "\u5DF2\u5B8C\u6210",
1734
1876
  "cli.uninstall.stages.completed-with-errors": "\u5B8C\u6210\u4F46\u6709\u9519\u8BEF",
1735
1877
  "cli.uninstall.stages.failed": "\u5931\u8D25",
1878
+ "cli.uninstall.stages.failed-hint": "\u67E5\u770B\u4E0A\u65B9\u9519\u8BEF\u8BE6\u60C5\u3002\u52A0 --debug \u83B7\u53D6\u66F4\u591A\u4FE1\u606F\u3002",
1879
+ "cli.uninstall.stages.uptodate": "\u65E0\u53EF\u79FB\u9664\uFF08{count} \u9879\u5DF2\u4E0D\u5B58\u5728\uFF09",
1880
+ "cli.uninstall.stages.summary": "removed={removed} skipped={skipped} errors={errors}",
1881
+ "cli.uninstall.stages.removed-count": "\u5DF2\u79FB\u9664 {count} \u9879",
1736
1882
  "cli.uninstall.summary.title": "\u5378\u8F7D\u6458\u8981",
1737
1883
  "cli.uninstall.summary.body": "removed={removed} skipped={skipped} errors={errors}",
1884
+ "cli.uninstall.healthcheck.title": "\u2713 Fabric \u5DF2\u4E0D\u5B58\u5728 \xB7 \u65E0\u53EF\u79FB\u9664",
1738
1885
  "cli.uninstall.wizard.intro": "\u5378\u8F7D Fabric",
1739
1886
  "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)",
1740
1887
  "cli.uninstall.wizard.select.scaffold.label": "scaffold \u4EA7\u7269",
1741
1888
  "cli.uninstall.wizard.select.scaffold.hint": ".fabric/ \u4E0B\u7684\u811A\u624B\u67B6\u6587\u4EF6",
1742
- "cli.uninstall.wizard.select.bootstrap.label": "bootstrap (Skills + hooks)",
1743
- "cli.uninstall.wizard.select.bootstrap.hint": "\u5404\u5BA2\u6237\u7AEF\u7684 skills \u4E0E git hooks",
1889
+ "cli.uninstall.wizard.select.bootstrap.label": "Skills \u4E0E hooks",
1890
+ "cli.uninstall.wizard.select.bootstrap.hint": "\u5404\u5BA2\u6237\u7AEF\u7684 skills \u4E0E hook \u811A\u672C + \u914D\u7F6E",
1744
1891
  "cli.uninstall.wizard.select.mcp.label": "MCP \u5BA2\u6237\u7AEF\u6CE8\u518C",
1745
1892
  "cli.uninstall.wizard.select.mcp.hint": "\u4ECE\u5404\u5BA2\u6237\u7AEF\u53CD\u6CE8\u518C fabric MCP server",
1893
+ "cli.uninstall.wizard.select.store.label": "\u89E3\u7ED1\u56E2\u961F store\uFF08\u672C\u9879\u76EE\uFF09",
1894
+ "cli.uninstall.wizard.select.store.hint": "\u6E05\u7A7A\u672C\u9879\u76EE\u7684 store \u7ED1\u5B9A\uFF1B\u5168\u5C40 store \u6C38\u4E0D\u5220\u9664",
1746
1895
  "cli.uninstall.wizard.execute.confirm": "\u73B0\u5728\u6267\u884C\u8BE5\u5378\u8F7D\u8BA1\u5212\uFF1F[Y/n]",
1747
1896
  "cli.uninstall.wizard.outro": "\u5378\u8F7D\u8BA1\u5212\u5DF2\u786E\u8BA4\uFF0C\u5F00\u59CB\u6267\u884C Fabric uninstall...",
1748
1897
  "cli.uninstall.wizard.cancelled": "Fabric \u5378\u8F7D\u5DF2\u5728\u6267\u884C\u524D\u53D6\u6D88\u3002",
@@ -1972,6 +2121,8 @@ var zhCNMessages = {
1972
2121
  "cli.store.detached": "\u5DF2\u5206\u79BB '{alias}' \u2014\u2014 \u78C1\u76D8\u4E0A\u7684 store \u76EE\u5F55\u4FDD\u7559 (\u5206\u79BB \u2260 \u5220\u9664)",
1973
2122
  "cli.store.bound": "\u5DF2\u7ED1\u5B9A\u5FC5\u9700 store '{id}' (\u5171 {count} \u4E2A\u5FC5\u9700)",
1974
2123
  "cli.store.switch-write": "\u5DF2\u5C06\u672C\u9879\u76EE\u7684\u6D3B\u52A8\u5199\u5165 store \u8BBE\u4E3A '{alias}'",
2124
+ "cli.store.switch-personal": "\u5DF2\u5C06\u672C\u673A\u6D3B\u52A8 personal store \u8BBE\u4E3A '{alias}'",
2125
+ "cli.store.routed": "\u5199\u5165\u8DEF\u7531:scope '{scope}' \u2192 store '{alias}'",
1975
2126
  "cli.sync.deferred": "{count} \u4E2A store \u79BB\u7EBF \u2014\u2014 push \u5DF2\u5EF6\u540E; \u8054\u7F51\u540E\u91CD\u65B0\u8FD0\u884C `fabric sync`",
1976
2127
  "cli.sync.paused": "sync \u56E0\u51B2\u7A81\u6682\u505C \u2014\u2014 \u89E3\u51B3\u540E\u8FD0\u884C `fabric sync --continue` (\u6216 `--abort`)",
1977
2128
  "cli.metrics.invalid-since": '--since: \u65E0\u6548\u7684\u65F6\u957F "{raw}" (\u793A\u4F8B: 24h\u30017d\u300130m)',
@@ -2026,7 +2177,7 @@ var PROTECTED_TOKENS = [
2026
2177
  "fab_recall",
2027
2178
  "fab_plan_context",
2028
2179
  "fab_get_knowledge_sections",
2029
- "fab_extract_knowledge",
2180
+ "fab_propose",
2030
2181
  "fab_review",
2031
2182
  // Project convergence point + knowledge tree paths
2032
2183
  "AGENTS.md",
@@ -2043,7 +2194,7 @@ var PROTECTED_TOKENS = [
2043
2194
  // Phase 1.5 scope enum values (rc.9 — TASK-008 D1)
2044
2195
  "narrow",
2045
2196
  "broad",
2046
- // v2.0.0-rc.7 T5/T6 fab_extract_knowledge contract fields (TASK-008 D1)
2197
+ // v2.0.0-rc.7 T5/T6 fab_propose contract fields (TASK-008 D1)
2047
2198
  "source_sessions",
2048
2199
  "proposed_reason",
2049
2200
  "session_context",