@fenglimg/fabric-shared 2.3.0-rc.1 → 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.
@@ -313,7 +313,26 @@ var _recallEntrySchema = z3.object({
313
313
  store: z3.object({ alias: z3.string() }).optional(),
314
314
  // true when this entry's body is ALSO injected at SessionStart (broad
315
315
  // model/guideline "ALWAYS-ACTIVE") — skip the Read, it is already in context.
316
- body_in_context: z3.boolean().optional()
316
+ body_in_context: z3.boolean().optional(),
317
+ // P1 recall-observability: the fused relevance score this entry scored during
318
+ // the plan-context sort (was computed internally but dropped before this wave).
319
+ // Optional + additive — backward-compatible. MUST be declared here or zod
320
+ // .strip() silently drops it at the MCP boundary (KT-PIT-0005).
321
+ score: z3.number().optional(),
322
+ // P1 recall-observability: numbers-only decomposition of `score` into its
323
+ // weighted signal contributions. NEVER carries body/description text — preserves
324
+ // the lean read_path contract (KT-DEC-0019 / KT-GLD-0005). bm25_rank/vector_rank
325
+ // are reserved for a later RRF wave (declared so the wire never strips them).
326
+ score_breakdown: z3.object({
327
+ final: z3.number(),
328
+ bm25: z3.number().optional(),
329
+ bm25_rank: z3.number().optional(),
330
+ vector: z3.number().optional(),
331
+ vector_rank: z3.number().optional(),
332
+ salience: z3.number(),
333
+ recency: z3.number(),
334
+ locality: z3.number()
335
+ }).optional()
317
336
  });
318
337
  var recallOutputSchema = z3.object({
319
338
  revision_hash: z3.string(),
@@ -151,11 +151,15 @@ var mountedStoreSchema = z.object({
151
151
  // Git remote locator for this clone, if any. Absent = local-only store
152
152
  // (valid; doctor nudges to add a remote for backup — R5#5, P6).
153
153
  remote: z.string().min(1).optional(),
154
- // v2.1.0-rc.1 P3: marks the implicit personal store (the one minted by
155
- // `install --global`). Exactly one mounted store carries personal=true; it
156
- // is the write target for personal-scope entries (R5#3) and always in the
157
- // read-set (S11). Optional (no default) so the output type stays a plain
158
- // optional consumers coalesce `?? false` when building resolver input.
154
+ // v2.1.0-rc.1 P3: marks a personal store (the kind minted by
155
+ // `install --global`). 语义 A (multi-personal): MULTIPLE mounted stores may
156
+ // carry personal=true a machine can mount several personal stores and
157
+ // switch which is ACTIVE via globalConfig.active_personal_store. The ACTIVE
158
+ // personal is the write target for personal-scope entries (R5#3) and the one
159
+ // in the read-set (S11); non-active personal stores stay mounted but out of
160
+ // the read-set. Absent active pointer ⇒ resolver falls back to the first
161
+ // mounted personal (back-compat). Optional (no default) so the output type
162
+ // stays a plain optional — consumers coalesce `?? false`.
159
163
  personal: z.boolean().optional(),
160
164
  // Whether writes are accepted into this store from this machine. Optional;
161
165
  // consumers coalesce `?? true`. Shared stores cloned read-only set false.
@@ -174,7 +178,14 @@ var globalConfigSchema = z.object({
174
178
  // All stores mounted on this machine. The implicit personal store is
175
179
  // included here once initialized. Default empty so a fresh global config
176
180
  // (before `install --global`) parses cleanly.
177
- stores: z.array(mountedStoreSchema).optional().default([])
181
+ stores: z.array(mountedStoreSchema).optional().default([]),
182
+ // 语义 A (multi-personal): alias/UUID of the ACTIVE personal store among the
183
+ // possibly-many `personal:true` stores in `stores[]`. Machine-wide (personal
184
+ // is uid-scoped identity, KT-DEC-0020) — switching it in any repo takes
185
+ // effect everywhere. Set by `fabric store switch-personal <alias>` and the
186
+ // install personal slot. Absent ⇒ the resolver falls back to the first
187
+ // mounted personal, so legacy single-personal configs are unchanged.
188
+ active_personal_store: z.string().min(1).optional()
178
189
  }).passthrough();
179
190
 
180
191
  // src/store/global-config-io.ts
@@ -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/templates/bootstrap-canonical.ts
6
6
  var BOOTSTRAP_MARKER_BEGIN = "<!-- fabric:bootstrap:begin -->";
@@ -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 = {
@@ -557,6 +557,9 @@ var enMessages = {
557
557
  "cli.install.args.dry-run.description": "Print the install plan without writing files or running follow-up stages",
558
558
  "cli.install.args.enable-embed.description": "Opt in to vector semantic search (sets embed_enabled + embed_model; prints fastembed install steps)",
559
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",
560
563
  // rc.35 TASK-08 (P0-5/6): --force-skills-only.
561
564
  "cli.install.args.force-skills-only.description": "Skip bootstrap / MCP / hooks / settings; refresh ONLY the fabric Skill template copies (.claude/.codex/skills/*).",
562
565
  "cli.install.force-skills-only.banner": "Refreshing fabric Skill templates only",
@@ -585,7 +588,26 @@ var enMessages = {
585
588
  "cli.install.steps.bootstrap-claude": "Updated CLAUDE.md with @-import directives",
586
589
  "cli.install.steps.bootstrap-codex": "Updated AGENTS.md with fabric:bootstrap managed block",
587
590
  "cli.install.stages.mcp": "Configuring MCP clients...",
588
- "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.",
589
611
  "cli.install.stages.skipped": "skipped",
590
612
  "cli.install.stages.completed": "completed",
591
613
  "cli.install.stages.failed": "failed",
@@ -595,6 +617,12 @@ var enMessages = {
595
617
  "cli.install.pipeline.title": "Fabric Install",
596
618
  "cli.install.pipeline.complete": "Fabric Install Complete",
597
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",
598
626
  "cli.install.pipeline.label.preflight": "Preflight check",
599
627
  "cli.install.pipeline.label.env": "Environment setup",
600
628
  "cli.install.pipeline.label.store": "Store configuration",
@@ -638,6 +666,10 @@ var enMessages = {
638
666
  "cli.install.wizard.invalid-select": "Invalid value. Use one of: {options}.",
639
667
  "cli.install.wizard.cancelled": "Fabric install cancelled before execution.",
640
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).",
641
673
  // v2.0.0-rc.37 NEW-22: post-install restart banner. The MCP server is
642
674
  // spawned by the client; already-running Claude Code / Codex
643
675
  // sessions won't pick up the new mcp config until they restart.
@@ -659,6 +691,25 @@ var enMessages = {
659
691
  "cli.install.store.setup.prompt": "Set up a knowledge store for this project?",
660
692
  "cli.install.store.setup.bind-label": "bind mounted: {alias}",
661
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}",
662
713
  "cli.install.store.skip-label": "skip",
663
714
  "cli.install.store.bind-mounted.skip-hint": "leave mounted stores unbound for now",
664
715
  "cli.install.store.project-coordinate": "Project coordinate in store '{store}':",
@@ -680,6 +731,9 @@ var enMessages = {
680
731
  "cli.install.store.unbound-note": "Note: The following stores are mounted but not bound to this project: {aliases}.",
681
732
  "cli.install.store.unbound-hint": " Run 'fabric store bind {first}' to bind one.",
682
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:",
683
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?",
684
738
  "cli.install.store.personal.new-label": "create local (default)",
685
739
  "cli.install.store.personal.new-hint": "a fresh empty personal store",
@@ -732,34 +786,47 @@ var enMessages = {
732
786
  "cli.uninstall.args.target.description": "Target project path. Defaults to --target, then EXTERNAL_FIXTURE_PATH, then cwd.",
733
787
  "cli.uninstall.args.debug.description": "Print target resolution details to stderr.",
734
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.",
735
791
  "cli.uninstall.args.dry-run.description": "Print the uninstall plan without removing files or running follow-up stages.",
736
792
  "cli.uninstall.plan.title": "Fabric uninstall plan",
737
793
  // C3: mirror install's phase banner ("Fabric install 将按 N 个阶段执行").
738
794
  "cli.uninstall.plan.phase-banner": "Fabric uninstall runs in {total} phases",
739
795
  "cli.uninstall.plan.target": "Target: {target}",
740
- "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}",
741
797
  "cli.uninstall.plan.detected": "Detected clients: {clients}",
742
798
  "cli.uninstall.plan.preserves": "Preserves:",
743
799
  "cli.uninstall.plan.preserves.stores": "global knowledge stores, never deleted by project uninstall",
744
800
  "cli.uninstall.plan.preview-title": "Fabric uninstall dry run",
745
- "cli.uninstall.plan.preview-result": "scaffold={scaffold} bootstrap={bootstrap} mcp={mcp}",
746
801
  "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...",
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",
750
810
  "cli.uninstall.stages.completed": "completed",
751
811
  "cli.uninstall.stages.completed-with-errors": "completed with errors",
752
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",
753
817
  "cli.uninstall.summary.title": "Uninstall summary",
754
818
  "cli.uninstall.summary.body": "removed={removed} skipped={skipped} errors={errors}",
819
+ "cli.uninstall.healthcheck.title": "\u2713 Fabric already absent \xB7 nothing to remove",
755
820
  "cli.uninstall.wizard.intro": "Fabric uninstall",
756
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)",
757
822
  "cli.uninstall.wizard.select.scaffold.label": "Scaffold artifacts",
758
823
  "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",
824
+ "cli.uninstall.wizard.select.bootstrap.label": "Skills & hooks",
825
+ "cli.uninstall.wizard.select.bootstrap.hint": "Per-client skills and hook scripts + config",
761
826
  "cli.uninstall.wizard.select.mcp.label": "MCP client registration",
762
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",
763
830
  "cli.uninstall.wizard.execute.confirm": "Execute this uninstall plan now? [Y/n]",
764
831
  "cli.uninstall.wizard.outro": "Uninstall plan accepted. Running Fabric uninstall...",
765
832
  "cli.uninstall.wizard.cancelled": "Fabric uninstall cancelled before execution.",
@@ -990,6 +1057,7 @@ var enMessages = {
990
1057
  "cli.store.detached": "detached '{alias}' \u2014 on-disk store tree left intact (detach \u2260 delete)",
991
1058
  "cli.store.bound": "bound required store '{id}' ({count} required)",
992
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",
993
1061
  "cli.store.routed": "write route: scope '{scope}' \u2192 store '{alias}'",
994
1062
  "cli.sync.deferred": "{count} store(s) offline \u2014 push deferred; re-run `fabric sync` when online",
995
1063
  "cli.sync.paused": "sync paused on a conflict \u2014 resolve it, then run `fabric sync --continue` (or `--abort`)",
@@ -1557,6 +1625,8 @@ var zhCNMessages = {
1557
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",
1558
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)",
1559
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",
1560
1630
  // rc.35 TASK-08 (P0-5/6): --force-skills-only。
1561
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",
1562
1632
  "cli.install.force-skills-only.banner": "\u53EA\u5237\u65B0 fabric Skill \u6A21\u677F",
@@ -1585,7 +1655,26 @@ var zhCNMessages = {
1585
1655
  "cli.install.steps.bootstrap-claude": "\u5DF2\u66F4\u65B0 CLAUDE.md \u7684 @-import \u5F15\u7528",
1586
1656
  "cli.install.steps.bootstrap-codex": "\u5DF2\u66F4\u65B0 AGENTS.md \u7684 fabric:bootstrap managed block",
1587
1657
  "cli.install.stages.mcp": "\u6B63\u5728\u914D\u7F6E MCP \u5BA2\u6237\u7AEF...",
1588
- "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",
1589
1678
  "cli.install.stages.skipped": "\u5DF2\u8DF3\u8FC7",
1590
1679
  "cli.install.stages.completed": "\u5DF2\u5B8C\u6210",
1591
1680
  "cli.install.stages.failed": "\u5931\u8D25",
@@ -1595,6 +1684,12 @@ var zhCNMessages = {
1595
1684
  "cli.install.pipeline.title": "Fabric \u5B89\u88C5",
1596
1685
  "cli.install.pipeline.complete": "Fabric \u5B89\u88C5\u5B8C\u6210",
1597
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",
1598
1693
  "cli.install.pipeline.label.preflight": "\u5168\u5C40\u4E0E\u9879\u76EE\u9884\u68C0",
1599
1694
  "cli.install.pipeline.label.env": "\u9879\u76EE\u73AF\u5883\u521D\u59CB\u5316",
1600
1695
  "cli.install.pipeline.label.store": "\u77E5\u8BC6\u5E93\u62D3\u6251",
@@ -1638,6 +1733,9 @@ var zhCNMessages = {
1638
1733
  "cli.install.wizard.invalid-select": "\u65E0\u6548\u8F93\u5165\u3002\u53EF\u9009\u503C\uFF1A{options}\u3002",
1639
1734
  "cli.install.wizard.cancelled": "Fabric \u5B89\u88C5\u5DF2\u5728\u6267\u884C\u524D\u53D6\u6D88\u3002",
1640
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",
1641
1739
  // v2.0.0-rc.37 NEW-22: post-install 重启提示。MCP server 在 client 启动
1642
1740
  // 时 spawn, 已运行的 Claude Code / Codex session 不会自动加载
1643
1741
  // 新 mcp config — 必须重启才能拿到 Fabric tools。
@@ -1659,6 +1757,24 @@ var zhCNMessages = {
1659
1757
  "cli.install.store.setup.prompt": "\u4E3A\u672C\u9879\u76EE\u8BBE\u7F6E\u77E5\u8BC6 store\uFF1F",
1660
1758
  "cli.install.store.setup.bind-label": "\u7ED1\u5B9A\u5DF2\u6302\u8F7D: {alias}",
1661
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}",
1662
1778
  "cli.install.store.skip-label": "\u8DF3\u8FC7",
1663
1779
  "cli.install.store.bind-mounted.skip-hint": "\u6682\u4E0D\u7ED1\u5B9A\u5DF2\u6302\u8F7D\u7684 store",
1664
1780
  "cli.install.store.project-coordinate": "\u5728 store '{store}' \u4E2D\u7684\u9879\u76EE\u5750\u6807 (project coordinate):",
@@ -1680,6 +1796,9 @@ var zhCNMessages = {
1680
1796
  "cli.install.store.unbound-note": "\u6CE8\u610F: \u4EE5\u4E0B store \u5DF2\u6302\u8F7D\u4F46\u672A\u7ED1\u5B9A\u5230\u672C\u9879\u76EE: {aliases}\u3002",
1681
1797
  "cli.install.store.unbound-hint": " \u8FD0\u884C 'fabric store bind {first}' \u7ED1\u5B9A\u5176\u4E00\u3002",
1682
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:",
1683
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",
1684
1803
  "cli.install.store.personal.new-label": "\u65B0\u5EFA\u672C\u5730 (\u9ED8\u8BA4)",
1685
1804
  "cli.install.store.personal.new-hint": "\u5168\u65B0\u7A7A personal store",
@@ -1732,34 +1851,47 @@ var zhCNMessages = {
1732
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",
1733
1852
  "cli.uninstall.args.debug.description": "\u5C06\u76EE\u6807\u89E3\u6790\u7EC6\u8282\u8F93\u51FA\u5230 stderr\u3002",
1734
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",
1735
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",
1736
1857
  "cli.uninstall.plan.title": "Fabric \u5378\u8F7D\u8BA1\u5212",
1737
1858
  // C3: 镜像 install 的阶段提示 (install 用 "Fabric install 将按 N 个阶段执行")。
1738
1859
  "cli.uninstall.plan.phase-banner": "Fabric uninstall \u5C06\u6309 {total} \u4E2A\u9636\u6BB5\u6267\u884C",
1739
1860
  "cli.uninstall.plan.target": "\u76EE\u6807\uFF1A{target}",
1740
- "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}",
1741
1862
  "cli.uninstall.plan.detected": "\u68C0\u6D4B\u5230\u7684\u5BA2\u6237\u7AEF\uFF1A{clients}",
1742
1863
  "cli.uninstall.plan.preserves": "\u4FDD\u7559\u9879\uFF1A",
1743
1864
  "cli.uninstall.plan.preserves.stores": "\u5168\u5C40\u77E5\u8BC6 stores\uFF0C\u9879\u76EE\u5378\u8F7D\u6C38\u4E0D\u5220\u9664",
1744
1865
  "cli.uninstall.plan.preview-title": "Fabric \u5378\u8F7D dry run",
1745
- "cli.uninstall.plan.preview-result": "scaffold={scaffold} bootstrap={bootstrap} mcp={mcp}",
1746
1866
  "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...",
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",
1750
1875
  "cli.uninstall.stages.completed": "\u5DF2\u5B8C\u6210",
1751
1876
  "cli.uninstall.stages.completed-with-errors": "\u5B8C\u6210\u4F46\u6709\u9519\u8BEF",
1752
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",
1753
1882
  "cli.uninstall.summary.title": "\u5378\u8F7D\u6458\u8981",
1754
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",
1755
1885
  "cli.uninstall.wizard.intro": "\u5378\u8F7D Fabric",
1756
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)",
1757
1887
  "cli.uninstall.wizard.select.scaffold.label": "scaffold \u4EA7\u7269",
1758
1888
  "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",
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",
1761
1891
  "cli.uninstall.wizard.select.mcp.label": "MCP \u5BA2\u6237\u7AEF\u6CE8\u518C",
1762
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",
1763
1895
  "cli.uninstall.wizard.execute.confirm": "\u73B0\u5728\u6267\u884C\u8BE5\u5378\u8F7D\u8BA1\u5212\uFF1F[Y/n]",
1764
1896
  "cli.uninstall.wizard.outro": "\u5378\u8F7D\u8BA1\u5212\u5DF2\u786E\u8BA4\uFF0C\u5F00\u59CB\u6267\u884C Fabric uninstall...",
1765
1897
  "cli.uninstall.wizard.cancelled": "Fabric \u5378\u8F7D\u5DF2\u5728\u6267\u884C\u524D\u53D6\u6D88\u3002",
@@ -1989,6 +2121,7 @@ var zhCNMessages = {
1989
2121
  "cli.store.detached": "\u5DF2\u5206\u79BB '{alias}' \u2014\u2014 \u78C1\u76D8\u4E0A\u7684 store \u76EE\u5F55\u4FDD\u7559 (\u5206\u79BB \u2260 \u5220\u9664)",
1990
2122
  "cli.store.bound": "\u5DF2\u7ED1\u5B9A\u5FC5\u9700 store '{id}' (\u5171 {count} \u4E2A\u5FC5\u9700)",
1991
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}'",
1992
2125
  "cli.store.routed": "\u5199\u5165\u8DEF\u7531:scope '{scope}' \u2192 store '{alias}'",
1993
2126
  "cli.sync.deferred": "{count} \u4E2A store \u79BB\u7EBF \u2014\u2014 push \u5DF2\u5EF6\u540E; \u8054\u7F51\u540E\u91CD\u65B0\u8FD0\u884C `fabric sync`",
1994
2127
  "cli.sync.paused": "sync \u56E0\u51B2\u7A81\u6682\u505C \u2014\u2014 \u89E3\u51B3\u540E\u8FD0\u884C `fabric sync --continue` (\u6216 `--abort`)",
@@ -5,12 +5,12 @@ import {
5
5
  enMessages,
6
6
  resolveFabricLocale,
7
7
  zhCNMessages
8
- } from "../chunk-IFMFEX3V.js";
8
+ } from "../chunk-ZYBWITH7.js";
9
9
  import {
10
10
  detectNodeLocale,
11
11
  normalizeLocale,
12
12
  resolveGlobalLocale
13
- } from "../chunk-2GLIAZ5M.js";
13
+ } from "../chunk-ANUDBQBK.js";
14
14
  export {
15
15
  PROTECTED_TOKENS,
16
16
  createTranslator,