@fenglimg/fabric-cli 2.0.0-rc.10 → 2.0.0-rc.13

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.
@@ -2,17 +2,18 @@
2
2
  import {
3
3
  hooksCommand,
4
4
  installHooks
5
- } from "./chunk-WPTA74BY.js";
5
+ } from "./chunk-Q72D24BG.js";
6
6
  import {
7
+ detectExistingLanguage,
7
8
  detectFramework,
8
9
  runInitScan
9
- } from "./chunk-MT3R57VG.js";
10
+ } from "./chunk-FDRLV5PL.js";
10
11
  import {
11
12
  detectClientSupports,
12
13
  resolveClients
13
- } from "./chunk-HQLEHH4O.js";
14
+ } from "./chunk-OHWQNSLH.js";
14
15
  import {
15
- addArchiveSkillPointer,
16
+ addFabricKnowledgeBaseSection,
16
17
  installArchiveHintHook,
17
18
  installFabricArchiveSkill,
18
19
  installFabricImportSkill,
@@ -21,8 +22,9 @@ import {
21
22
  installKnowledgeHintNarrowHook,
22
23
  mergeClaudeCodeHookConfig,
23
24
  mergeCodexHookConfig,
24
- mergeCursorHookConfig
25
- } from "./chunk-AW3G7ZH5.js";
25
+ mergeCursorHookConfig,
26
+ readFabricLanguagePreference
27
+ } from "./chunk-X7QPY5KH.js";
26
28
  import {
27
29
  displayWidth,
28
30
  padEnd,
@@ -36,7 +38,7 @@ import {
36
38
  t
37
39
  } from "./chunk-6ICJICVU.js";
38
40
 
39
- // src/commands/init.ts
41
+ // src/commands/install.ts
40
42
  import { randomUUID } from "crypto";
41
43
  import { homedir } from "os";
42
44
  import * as childProcess from "child_process";
@@ -1292,7 +1294,7 @@ function readProjectName(target) {
1292
1294
  return basename(target);
1293
1295
  }
1294
1296
  function getCliVersion() {
1295
- return true ? "2.0.0-rc.10" : "unknown";
1297
+ return true ? "2.0.0-rc.13" : "unknown";
1296
1298
  }
1297
1299
  function sortRecord(record) {
1298
1300
  return Object.fromEntries(Object.entries(record).sort(([left], [right]) => left.localeCompare(right)));
@@ -1301,7 +1303,7 @@ function toPosixPath(path) {
1301
1303
  return path.split(sep).join("/");
1302
1304
  }
1303
1305
 
1304
- // src/commands/init.ts
1306
+ // src/commands/install.ts
1305
1307
  var AGENTS_MD_DEFAULT_CONTENT = `# Project Knowledge
1306
1308
 
1307
1309
  This project uses [Fabric](https://github.com/fenglimg/fabric) for cross-client AI knowledge management.
@@ -1314,76 +1316,76 @@ See \`.fabric/knowledge/\` for project decisions, pitfalls, guidelines, models,
1314
1316
  var LOCAL_FABRIC_SERVER_PATH = join2("node_modules", "@fenglimg", "fabric-server", "dist", "index.js");
1315
1317
  var FABRIC_SERVER_PACKAGE = "@fenglimg/fabric-server";
1316
1318
  var INIT_WIZARD_GROUP_CANCELLED = /* @__PURE__ */ Symbol("init-wizard-group-cancelled");
1317
- var initCommand = defineCommand2({
1319
+ var installCommand = defineCommand2({
1318
1320
  meta: {
1319
- name: "init",
1320
- description: t("cli.init.description")
1321
+ name: "install",
1322
+ description: t("cli.install.description")
1321
1323
  },
1322
1324
  args: {
1323
1325
  target: {
1324
1326
  type: "string",
1325
- description: t("cli.init.args.target.description")
1327
+ description: t("cli.install.args.target.description")
1326
1328
  },
1327
1329
  debug: {
1328
1330
  type: "boolean",
1329
- description: t("cli.init.args.debug.description"),
1331
+ description: t("cli.install.args.debug.description"),
1330
1332
  default: false
1331
1333
  },
1332
1334
  force: {
1333
1335
  type: "boolean",
1334
- description: t("cli.init.args.force.description"),
1336
+ description: t("cli.install.args.force.description"),
1335
1337
  default: false
1336
1338
  },
1337
1339
  yes: {
1338
1340
  type: "boolean",
1339
- description: t("cli.init.args.yes.description"),
1341
+ description: t("cli.install.args.yes.description"),
1340
1342
  default: false
1341
1343
  },
1342
1344
  plan: {
1343
1345
  type: "boolean",
1344
- description: t("cli.init.args.plan.description"),
1346
+ description: t("cli.install.args.plan.description"),
1345
1347
  default: false
1346
1348
  },
1347
1349
  reapply: {
1348
1350
  type: "boolean",
1349
- description: t("cli.init.args.reapply.description"),
1351
+ description: t("cli.install.args.reapply.description"),
1350
1352
  default: false
1351
1353
  },
1352
1354
  bootstrap: {
1353
1355
  type: "boolean",
1354
1356
  default: true,
1355
- negativeDescription: t("cli.init.args.no-bootstrap.description")
1357
+ negativeDescription: t("cli.install.args.no-bootstrap.description")
1356
1358
  },
1357
1359
  mcp: {
1358
1360
  type: "boolean",
1359
1361
  default: true,
1360
- negativeDescription: t("cli.init.args.no-mcp.description")
1362
+ negativeDescription: t("cli.install.args.no-mcp.description")
1361
1363
  },
1362
1364
  hooks: {
1363
1365
  type: "boolean",
1364
1366
  default: true,
1365
- negativeDescription: t("cli.init.args.no-hooks.description")
1367
+ negativeDescription: t("cli.install.args.no-hooks.description")
1366
1368
  },
1367
1369
  interactive: {
1368
1370
  type: "boolean",
1369
- description: t("cli.init.args.interactive.description"),
1371
+ description: t("cli.install.args.interactive.description"),
1370
1372
  default: true
1371
1373
  },
1372
1374
  "mcp-install": {
1373
1375
  type: "string",
1374
1376
  default: "global",
1375
- description: t("cli.init.mcp.install.prompt")
1377
+ description: t("cli.install.mcp.install.prompt")
1376
1378
  },
1377
1379
  scope: {
1378
1380
  type: "string",
1379
- description: t("cli.init.mcp.scope.description")
1381
+ description: t("cli.install.mcp.scope.description")
1380
1382
  }
1381
1383
  },
1382
1384
  async run({ args }) {
1383
1385
  await runInitCommand(args);
1384
1386
  }
1385
1387
  });
1386
- var init_default = initCommand;
1388
+ var install_default = installCommand;
1387
1389
  async function runInitCommand(args) {
1388
1390
  const logger = createDebugLogger(args.debug);
1389
1391
  const resolution = resolveDevMode(args.target, process.cwd());
@@ -1396,13 +1398,13 @@ async function runInitCommand(args) {
1396
1398
  logger(step);
1397
1399
  }
1398
1400
  if (intent.options.planOnly) {
1399
- writeStderr2(t("cli.init.compat.plan"));
1401
+ writeStderr2(t("cli.install.compat.plan"));
1400
1402
  }
1401
1403
  if (args.interactive === false) {
1402
- writeStderr2(t("cli.init.compat.interactive"));
1404
+ writeStderr2(t("cli.install.compat.interactive"));
1403
1405
  }
1404
1406
  if (args.bootstrap === false || args.mcp === false || args.hooks === false) {
1405
- writeStderr2(t("cli.init.compat.legacy-stage-flags"));
1407
+ writeStderr2(t("cli.install.compat.legacy-stage-flags"));
1406
1408
  }
1407
1409
  const supports = detectClientSupports(intent.target);
1408
1410
  const basePlan = await buildInitExecutionPlan({
@@ -1424,14 +1426,16 @@ async function runInitCommand(args) {
1424
1426
  }
1425
1427
  return result;
1426
1428
  }
1427
- function writeDefaultFabricConfig(fabricDir) {
1429
+ function writeDefaultFabricConfig(fabricDir, targetRoot) {
1428
1430
  const target = join2(fabricDir, "fabric-config.json");
1429
1431
  if (existsSync3(target)) return;
1432
+ const detectedLanguage = detectExistingLanguage(targetRoot);
1430
1433
  const FABRIC_CONFIG_DEFAULTS = {
1431
- // Scan/import language policy. `match-existing` lets init resolve the
1432
- // effective language from project content; explicit `zh-CN` / `en`
1433
- // lock the policy. See packages/shared/src/schemas/fabric-config.ts.
1434
- knowledge_language: "match-existing",
1434
+ // Scan/import language policy. Fixated at init time by probing
1435
+ // README.md + docs/*.md (CJK ratio > 0.3 → "zh-CN", else "en"). Users
1436
+ // can edit `.fabric/fabric-config.json` to override. See
1437
+ // packages/shared/src/schemas/fabric-config.ts for the enum.
1438
+ fabric_language: detectedLanguage,
1435
1439
  // fabric-hint Stop hook Signal A (archive): time-branch threshold, hours
1436
1440
  // since last knowledge_proposed event.
1437
1441
  archive_hint_hours: 24,
@@ -1452,10 +1456,44 @@ function writeDefaultFabricConfig(fabricDir) {
1452
1456
  archive_edit_threshold: 20,
1453
1457
  // fabric-hint Stop hook Signal C (import) + doctor lint #22: canonical
1454
1458
  // knowledge node count below this value flags an underseeded workspace.
1455
- underseed_node_threshold: 10
1459
+ underseed_node_threshold: 10,
1460
+ // rc.9+ (skill-contract-fix B1): fabric-import first-run git-history
1461
+ // window in months. Default 60 captures the bulk of a mature repo's
1462
+ // signal in one pass; lower to 12-24 for fresh / small repos.
1463
+ import_window_first_run_months: 60,
1464
+ // rc.9+ (skill-contract-fix B1): fabric-import rerun window in months.
1465
+ // Default 2; raise to 6 if the workspace pauses imports for long stretches.
1466
+ import_window_rerun_months: 2,
1467
+ // rc.9+ (skill-contract-fix B1): hard cap on pending entries produced
1468
+ // per fabric-import invocation. Default 10 matches one-sitting triage.
1469
+ import_max_pending_per_run: 10,
1470
+ // rc.9+ (skill-contract-fix B1): hard cap on commits scanned per
1471
+ // fabric-import invocation. Default 500 covers ~2 months of typical churn.
1472
+ import_max_commits_scan: 500,
1473
+ // rc.9+ (skill-contract-fix B1): canonical-node count above which
1474
+ // fabric-import suggests review over importing more. Default 50.
1475
+ import_skip_canonical_threshold: 50,
1476
+ // rc.9+ (skill-contract-fix B1): max candidates per fabric-archive batch.
1477
+ // Default 8 keeps each batch reviewable in one sitting.
1478
+ archive_max_candidates_per_batch: 8,
1479
+ // rc.9+ (skill-contract-fix B1): max recently-touched paths in
1480
+ // fabric-archive's relevance digest. Default 20.
1481
+ archive_max_recent_paths: 20,
1482
+ // rc.9+ (skill-contract-fix B1): max prior fabric-archive sessions
1483
+ // summarised in the digest the skill loads on start. Default 10.
1484
+ archive_digest_max_sessions: 10,
1485
+ // rc.9+ (skill-contract-fix B1): max review results per topic cluster
1486
+ // in fabric-review. Default 8.
1487
+ review_topic_result_cap: 8,
1488
+ // rc.9+ (skill-contract-fix B1): age (days) above which a pending entry
1489
+ // is considered stale by fabric-review. Default 14.
1490
+ review_stale_pending_days: 14
1456
1491
  };
1457
1492
  mkdirSync(fabricDir, { recursive: true });
1458
1493
  writeFileSync(target, JSON.stringify(FABRIC_CONFIG_DEFAULTS, null, 2) + "\n", "utf8");
1494
+ log.info(
1495
+ `Detected and fixated fabric_language = ${detectedLanguage}; edit ${target} to override.`
1496
+ );
1459
1497
  }
1460
1498
  function resolveInitCliIntent(args, targetInput) {
1461
1499
  const target = normalizeTarget2(targetInput);
@@ -1488,7 +1526,7 @@ function resolveClaudeMcpScope(raw) {
1488
1526
  if (raw === "user") {
1489
1527
  return "user";
1490
1528
  }
1491
- writeStderr2(t("cli.init.mcp.scope.invalid", { value: raw }));
1529
+ writeStderr2(t("cli.install.mcp.scope.invalid", { value: raw }));
1492
1530
  return "project";
1493
1531
  }
1494
1532
  async function buildInitExecutionPlan(input) {
@@ -1528,7 +1566,7 @@ async function buildInitExecutionPlan(input) {
1528
1566
  }
1529
1567
  async function executeInitExecutionPlan(plan) {
1530
1568
  if (plan.options.force) {
1531
- writeStderr2(t("cli.init.force.warning", { path: plan.target }));
1569
+ writeStderr2(t("cli.install.force.warning", { path: plan.target }));
1532
1570
  }
1533
1571
  if (plan.options.reapply && !plan.options.planOnly && !plan.interactive) {
1534
1572
  writeStderr2(formatInitModeBanner(plan.options));
@@ -1623,7 +1661,7 @@ async function executeInitFabricPlan(plan) {
1623
1661
  rmSync(plan.fabricDir, { force: true });
1624
1662
  }
1625
1663
  mkdirSync(plan.fabricDir, { recursive: true });
1626
- writeDefaultFabricConfig(plan.fabricDir);
1664
+ writeDefaultFabricConfig(plan.fabricDir, plan.target);
1627
1665
  if (plan.agentsMdAction === "created" && !existsSync3(plan.agentsMdPath)) {
1628
1666
  await atomicWriteText(plan.agentsMdPath, AGENTS_MD_DEFAULT_CONTENT);
1629
1667
  }
@@ -1735,27 +1773,31 @@ function printInitScaffoldResult(created) {
1735
1773
  function printInitPostSetup(plan, stageResults, finalSupports) {
1736
1774
  if (shouldPrintHooksNextStep(plan.options, stageResults)) {
1737
1775
  console.log(
1738
- t("cli.init.next-step", {
1776
+ t("cli.install.next-step", {
1739
1777
  label: nextLabel(),
1740
- message: paint.muted(t("cli.init.next-step.message"))
1778
+ message: paint.muted(t("cli.install.next-step.message"))
1741
1779
  })
1742
1780
  );
1743
1781
  }
1744
1782
  console.log(
1745
- t("cli.init.reason-message", {
1783
+ t("cli.install.reason-message", {
1746
1784
  label: reasonLabel(),
1747
1785
  message: paint.muted(formatInitReasonMessage(finalSupports))
1748
1786
  })
1749
1787
  );
1750
1788
  printInitStageSummary(stageResults);
1751
1789
  printInitCapabilitySummary(finalSupports, stageResults, plan.options);
1790
+ const fabricLanguage = readFabricLanguagePreference(plan.target);
1791
+ console.log(
1792
+ paint.muted(t("cli.install.language_preference_hint", { value: fabricLanguage }))
1793
+ );
1752
1794
  }
1753
1795
  function printInitPlanPreview(plan) {
1754
- console.log(t("cli.init.plan.preview-title"));
1796
+ console.log(t("cli.install.plan.preview-title"));
1755
1797
  printInitPlanSummary(plan.target, plan.options, plan.mcpInstallMode, plan.supports);
1756
1798
  console.log(
1757
- t("cli.init.plan.preview-result", {
1758
- mode: plan.options.reapply ? t("cli.init.mode.reapply") : t("cli.init.mode.default"),
1799
+ t("cli.install.plan.preview-result", {
1800
+ mode: plan.options.reapply ? t("cli.install.mode.reapply") : t("cli.install.mode.default"),
1759
1801
  bootstrap: yesNoLabel(!plan.options.skipBootstrap),
1760
1802
  mcp: yesNoLabel(!plan.options.skipMcp),
1761
1803
  hooks: yesNoLabel(!plan.options.skipHooks)
@@ -1785,7 +1827,7 @@ async function executeInitStagePlan(plan, stageName) {
1785
1827
  if (stage.skipped) {
1786
1828
  return { name: stageName, disposition: "skipped" };
1787
1829
  }
1788
- console.log(formatInitStageHeader(t(`cli.init.stages.${stageName}`)));
1830
+ console.log(formatInitStageHeader(t(`cli.install.stages.${stageName}`)));
1789
1831
  try {
1790
1832
  switch (stage.name) {
1791
1833
  case "bootstrap": {
@@ -1799,7 +1841,8 @@ async function executeInitStagePlan(plan, stageName) {
1799
1841
  installResults.push(await runBestEffortSingle("claude-hook-config", () => mergeClaudeCodeHookConfig(plan.target)));
1800
1842
  installResults.push(await runBestEffortSingle("codex-hook-config", () => mergeCodexHookConfig(plan.target)));
1801
1843
  installResults.push(await runBestEffortSingle("cursor-hook-config", () => mergeCursorHookConfig(plan.target)));
1802
- installResults.push(...await runBestEffort("pointer", () => addArchiveSkillPointer(plan.target)));
1844
+ const fabricLanguage = readFabricLanguagePreference(plan.target);
1845
+ installResults.push(...await runBestEffort("section", () => addFabricKnowledgeBaseSection(plan.target, fabricLanguage)));
1803
1846
  const installedCount = installResults.filter((r) => r.status === "written").length;
1804
1847
  const skippedCount = installResults.filter((r) => r.status === "skipped").length;
1805
1848
  const errorCount = installResults.filter((r) => r.status === "error").length;
@@ -1815,12 +1858,12 @@ async function executeInitStagePlan(plan, stageName) {
1815
1858
  case "mcp": {
1816
1859
  if (stage.installMode === "local") {
1817
1860
  const manager = stage.packageManager ?? detectPackageManager(plan.target);
1818
- writeStderr2(t("cli.init.mcp.install.local"));
1819
- writeStderr2(t("cli.init.mcp.local.installing", { manager }));
1861
+ writeStderr2(t("cli.install.mcp.install.local"));
1862
+ writeStderr2(t("cli.install.mcp.local.installing", { manager }));
1820
1863
  installLocalFabricServer(plan.target, manager);
1821
- writeStderr2(t("cli.init.mcp.local.installed"));
1864
+ writeStderr2(t("cli.install.mcp.local.installed"));
1822
1865
  } else {
1823
- writeStderr2(t("cli.init.mcp.install.global"));
1866
+ writeStderr2(t("cli.install.mcp.install.global"));
1824
1867
  }
1825
1868
  const result = await installMcpClients(plan.target, {
1826
1869
  force: plan.options.force,
@@ -1855,7 +1898,7 @@ function shouldReplaceWritableDirectory(path, options) {
1855
1898
  return false;
1856
1899
  }
1857
1900
  if (!options?.force) {
1858
- throw new Error(t("cli.init.errors.abort-existing", { path }));
1901
+ throw new Error(t("cli.install.errors.abort-existing", { path }));
1859
1902
  }
1860
1903
  return true;
1861
1904
  }
@@ -1864,7 +1907,7 @@ function planFreshPath(path, options) {
1864
1907
  return "created";
1865
1908
  }
1866
1909
  if (!options?.force) {
1867
- throw new Error(t("cli.init.errors.abort-existing", { path }));
1910
+ throw new Error(t("cli.install.errors.abort-existing", { path }));
1868
1911
  }
1869
1912
  return "overwritten";
1870
1913
  }
@@ -1877,59 +1920,59 @@ function preparePlannedPath(path, action) {
1877
1920
  function createDefaultInitWizardAdapter() {
1878
1921
  return {
1879
1922
  async run(context) {
1880
- intro(t("cli.init.wizard.intro"));
1923
+ intro(t("cli.install.wizard.intro"));
1881
1924
  note(
1882
- t("cli.init.wizard.overview.body", {
1925
+ t("cli.install.wizard.overview.body", {
1883
1926
  target: context.target,
1884
1927
  mode: formatInitModeBadge(context.options)
1885
1928
  }),
1886
- t("cli.init.wizard.overview.title")
1929
+ t("cli.install.wizard.overview.title")
1887
1930
  );
1888
1931
  printInitPlanSummary(context.target, context.options, context.mcpInstallMode, context.supports);
1889
- log.step(t("cli.init.wizard.step.target"));
1932
+ log.step(t("cli.install.wizard.step.target"));
1890
1933
  const continueWithTarget = await confirm({
1891
- message: t("cli.init.wizard.target.confirm", { target: context.target }),
1934
+ message: t("cli.install.wizard.target.confirm", { target: context.target }),
1892
1935
  initialValue: true
1893
1936
  });
1894
1937
  if (isCancel(continueWithTarget) || !continueWithTarget) {
1895
1938
  emitInitWizardCancellation();
1896
1939
  return null;
1897
1940
  }
1898
- log.step(t("cli.init.wizard.step.plan"));
1941
+ log.step(t("cli.install.wizard.step.plan"));
1899
1942
  let groupedSelection;
1900
1943
  try {
1901
1944
  groupedSelection = await group(
1902
1945
  {
1903
1946
  bootstrap: async () => context.lockedStages.includes("bootstrap") ? false : confirmInGroup({
1904
- message: t("cli.init.wizard.stage.bootstrap", {
1947
+ message: t("cli.install.wizard.stage.bootstrap", {
1905
1948
  defaultValue: formatPromptDefault(!context.options.skipBootstrap)
1906
1949
  }),
1907
1950
  initialValue: !context.options.skipBootstrap
1908
1951
  }),
1909
1952
  mcp: async () => context.lockedStages.includes("mcp") ? false : confirmInGroup({
1910
- message: t("cli.init.wizard.stage.mcp", {
1953
+ message: t("cli.install.wizard.stage.mcp", {
1911
1954
  defaultValue: formatPromptDefault(!context.options.skipMcp)
1912
1955
  }),
1913
1956
  initialValue: !context.options.skipMcp
1914
1957
  }),
1915
1958
  mcpInstallMode: async ({ results }) => results.mcp ? selectMcpInstallModeInGroup({
1916
- message: t("cli.init.wizard.mcp-install", { defaultValue: context.mcpInstallMode }),
1959
+ message: t("cli.install.wizard.mcp-install", { defaultValue: context.mcpInstallMode }),
1917
1960
  initialValue: context.mcpInstallMode,
1918
1961
  options: [
1919
- { value: "global", label: "global", hint: t("cli.init.mcp.install.global") },
1920
- { value: "local", label: "local", hint: t("cli.init.mcp.install.local") }
1962
+ { value: "global", label: "global", hint: t("cli.install.mcp.install.global") },
1963
+ { value: "local", label: "local", hint: t("cli.install.mcp.install.local") }
1921
1964
  ]
1922
1965
  }) : context.mcpInstallMode,
1923
1966
  claudeMcpScope: async ({ results }) => results.mcp ? selectClaudeMcpScopeInGroup({
1924
- message: t("cli.init.wizard.mcp-scope", { defaultValue: context.claudeMcpScope }),
1967
+ message: t("cli.install.wizard.mcp-scope", { defaultValue: context.claudeMcpScope }),
1925
1968
  initialValue: context.claudeMcpScope,
1926
1969
  options: [
1927
- { value: "project", label: "project", hint: t("cli.init.mcp.scope.project") },
1928
- { value: "user", label: "user", hint: t("cli.init.mcp.scope.user") }
1970
+ { value: "project", label: "project", hint: t("cli.install.mcp.scope.project") },
1971
+ { value: "user", label: "user", hint: t("cli.install.mcp.scope.user") }
1929
1972
  ]
1930
1973
  }) : context.claudeMcpScope,
1931
1974
  hooks: async () => context.lockedStages.includes("hooks") ? false : confirmInGroup({
1932
- message: t("cli.init.wizard.stage.hooks", {
1975
+ message: t("cli.install.wizard.stage.hooks", {
1933
1976
  defaultValue: formatPromptDefault(!context.options.skipHooks)
1934
1977
  }),
1935
1978
  initialValue: !context.options.skipHooks
@@ -1958,23 +2001,23 @@ function createDefaultInitWizardAdapter() {
1958
2001
  skipMcp: !groupedSelection.mcp,
1959
2002
  skipHooks: !groupedSelection.hooks
1960
2003
  };
1961
- log.step(t("cli.init.wizard.step.review"));
2004
+ log.step(t("cli.install.wizard.step.review"));
1962
2005
  printInitPlanSummary(context.target, previewOptions, groupedSelection.mcpInstallMode, context.supports);
1963
2006
  const confirmed = await confirm({
1964
- message: t("cli.init.wizard.execute.confirm"),
2007
+ message: t("cli.install.wizard.execute.confirm"),
1965
2008
  initialValue: true
1966
2009
  });
1967
2010
  if (isCancel(confirmed) || !confirmed) {
1968
2011
  emitInitWizardCancellation();
1969
2012
  return null;
1970
2013
  }
1971
- outro(t("cli.init.wizard.outro"));
2014
+ outro(t("cli.install.wizard.outro"));
1972
2015
  return groupedSelection;
1973
2016
  }
1974
2017
  };
1975
2018
  }
1976
2019
  function emitInitWizardCancellation() {
1977
- cancel(t("cli.init.wizard.cancelled"));
2020
+ cancel(t("cli.install.wizard.cancelled"));
1978
2021
  }
1979
2022
  async function confirmInGroup(options) {
1980
2023
  const result = await confirm(options);
@@ -2023,27 +2066,27 @@ function formatPromptDefault(value) {
2023
2066
  }
2024
2067
  function formatInitModeBanner(options) {
2025
2068
  if (options.planOnly && options.reapply) {
2026
- return t("cli.init.plan.mode-banner.plan-reapply");
2069
+ return t("cli.install.plan.mode-banner.plan-reapply");
2027
2070
  }
2028
2071
  if (options.planOnly) {
2029
- return t("cli.init.plan.mode-banner.plan");
2072
+ return t("cli.install.plan.mode-banner.plan");
2030
2073
  }
2031
2074
  if (options.reapply) {
2032
- return t("cli.init.plan.mode-banner.reapply");
2075
+ return t("cli.install.plan.mode-banner.reapply");
2033
2076
  }
2034
- return t("cli.init.plan.mode-banner.default");
2077
+ return t("cli.install.plan.mode-banner.default");
2035
2078
  }
2036
2079
  function formatInitModeBadge(options) {
2037
2080
  if (options.planOnly && options.reapply) {
2038
- return t("cli.init.mode.badge.plan-reapply");
2081
+ return t("cli.install.mode.badge.plan-reapply");
2039
2082
  }
2040
2083
  if (options.planOnly) {
2041
- return t("cli.init.mode.badge.plan");
2084
+ return t("cli.install.mode.badge.plan");
2042
2085
  }
2043
2086
  if (options.reapply) {
2044
- return t("cli.init.mode.badge.reapply");
2087
+ return t("cli.install.mode.badge.reapply");
2045
2088
  }
2046
- return t("cli.init.mode.badge.default");
2089
+ return t("cli.install.mode.badge.default");
2047
2090
  }
2048
2091
  function normalizeTarget2(targetInput) {
2049
2092
  return isAbsolute2(targetInput) ? targetInput : resolve3(process.cwd(), targetInput);
@@ -2070,7 +2113,7 @@ function resolveMcpInstallMode(rawMode) {
2070
2113
  if (rawMode === void 0 || rawMode === "global" || rawMode === "local") {
2071
2114
  return rawMode ?? "global";
2072
2115
  }
2073
- writeStderr2(t("cli.init.mcp.install.invalid", { value: rawMode }));
2116
+ writeStderr2(t("cli.install.mcp.install.invalid", { value: rawMode }));
2074
2117
  return "global";
2075
2118
  }
2076
2119
  function installLocalFabricServer(target, manager) {
@@ -2146,7 +2189,7 @@ function printInitStageSummary(stageResults) {
2146
2189
  console.log(formatInitStageSummaryLine("failed", collectInitStageNames(stageResults, "failed")));
2147
2190
  }
2148
2191
  function formatInitStageSummaryLine(disposition, stages) {
2149
- const label = disposition === "ran" ? paint.success(t("cli.init.stages.summary.ran")) : disposition === "skipped" ? paint.muted(t("cli.init.stages.summary.skipped")) : paint.error(t("cli.init.stages.summary.failed"));
2192
+ const label = disposition === "ran" ? paint.success(t("cli.install.stages.summary.ran")) : disposition === "skipped" ? paint.muted(t("cli.install.stages.summary.skipped")) : paint.error(t("cli.install.stages.summary.failed"));
2150
2193
  return `${label}: ${stages.length > 0 ? stages.join(", ") : t("cli.shared.none")}`;
2151
2194
  }
2152
2195
  function collectInitStageNames(stageResults, disposition) {
@@ -2159,11 +2202,11 @@ function isInteractiveInit() {
2159
2202
  return Boolean(process.stdin.isTTY) && Boolean(process.stdout.isTTY) && Boolean(process.stderr.isTTY);
2160
2203
  }
2161
2204
  function printInitPlanSummary(target, options, mcpInstallMode, supports) {
2162
- console.log(t("cli.init.plan.title"));
2205
+ console.log(t("cli.install.plan.title"));
2163
2206
  console.log(formatInitModeBanner(options));
2164
- console.log(t("cli.init.plan.target", { target }));
2207
+ console.log(t("cli.install.plan.target", { target }));
2165
2208
  console.log(
2166
- t("cli.init.plan.actions", {
2209
+ t("cli.install.plan.actions", {
2167
2210
  bootstrap: yesNoLabel(!options.skipBootstrap),
2168
2211
  mcp: yesNoLabel(!options.skipMcp),
2169
2212
  hooks: yesNoLabel(!options.skipHooks),
@@ -2172,11 +2215,11 @@ function printInitPlanSummary(target, options, mcpInstallMode, supports) {
2172
2215
  );
2173
2216
  const detected = supports.filter((support) => support.detected);
2174
2217
  console.log(
2175
- t("cli.init.plan.detected", {
2218
+ t("cli.install.plan.detected", {
2176
2219
  clients: detected.length > 0 ? detected.map((support) => support.label).join(", ") : t("cli.shared.none")
2177
2220
  })
2178
2221
  );
2179
- console.log(t("cli.init.plan.writes"));
2222
+ console.log(t("cli.install.plan.writes"));
2180
2223
  console.log(` - ${target}/.fabric/knowledge/{decisions,pitfalls,guidelines,models,processes,pending}/`);
2181
2224
  console.log(` - ${target}/.fabric/agents.meta.json`);
2182
2225
  console.log(` - ${target}/.fabric/events.jsonl`);
@@ -2186,18 +2229,18 @@ function printInitPlanSummary(target, options, mcpInstallMode, supports) {
2186
2229
  function printInitCapabilitySummary(supports, stageResults, options) {
2187
2230
  const detected = supports.filter((support) => support.detected);
2188
2231
  if (detected.length === 0) {
2189
- console.log(t("cli.init.capabilities.none"));
2232
+ console.log(t("cli.install.capabilities.none"));
2190
2233
  return;
2191
2234
  }
2192
- console.log(t("cli.init.capabilities.title"));
2235
+ console.log(t("cli.install.capabilities.title"));
2193
2236
  const rows = detected.map((support) => toCapabilityRow(support, stageResults, options));
2194
2237
  const headers = {
2195
- client: t("cli.init.capabilities.header.client"),
2196
- bootstrap: t("cli.init.capabilities.header.bootstrap"),
2197
- mcp: t("cli.init.capabilities.header.mcp"),
2198
- hook: t("cli.init.capabilities.header.hook"),
2199
- skill: t("cli.init.capabilities.header.skill"),
2200
- followUp: t("cli.init.capabilities.header.follow-up")
2238
+ client: t("cli.install.capabilities.header.client"),
2239
+ bootstrap: t("cli.install.capabilities.header.bootstrap"),
2240
+ mcp: t("cli.install.capabilities.header.mcp"),
2241
+ hook: t("cli.install.capabilities.header.hook"),
2242
+ skill: t("cli.install.capabilities.header.skill"),
2243
+ followUp: t("cli.install.capabilities.header.follow-up")
2201
2244
  };
2202
2245
  const widths = {
2203
2246
  client: Math.max(displayWidth(headers.client), ...rows.map((row) => displayWidth(row.client))),
@@ -2215,8 +2258,8 @@ function printInitCapabilitySummary(supports, stageResults, options) {
2215
2258
  }
2216
2259
  function toCapabilityRow(support, stageResults, options) {
2217
2260
  const stage = (name) => stageResults.find((entry) => entry.name === name)?.disposition ?? null;
2218
- const bootstrap = support.capabilities.bootstrap ? capabilityStatus(options.skipBootstrap ? "skipped" : stage("bootstrap")) : t("cli.init.capabilities.status.na");
2219
- const mcp = support.capabilities.mcp ? capabilityStatus(options.skipMcp ? "skipped" : stage("mcp")) : t("cli.init.capabilities.status.na");
2261
+ const bootstrap = support.capabilities.bootstrap ? capabilityStatus(options.skipBootstrap ? "skipped" : stage("bootstrap")) : t("cli.install.capabilities.status.na");
2262
+ const mcp = support.capabilities.mcp ? capabilityStatus(options.skipMcp ? "skipped" : stage("mcp")) : t("cli.install.capabilities.status.na");
2220
2263
  const hook = capabilityInstallStatus(support, "hook");
2221
2264
  const skill = capabilityInstallStatus(support, "skill");
2222
2265
  return {
@@ -2225,14 +2268,14 @@ function toCapabilityRow(support, stageResults, options) {
2225
2268
  mcp,
2226
2269
  hook,
2227
2270
  skill,
2228
- followUp: hasInstalledCapability(support, "skill") ? t("cli.init.capabilities.follow-up.ready") : support.capabilities.skill ? t("cli.init.capabilities.follow-up.install") : t("cli.init.capabilities.follow-up.manual")
2271
+ followUp: hasInstalledCapability(support, "skill") ? t("cli.install.capabilities.follow-up.ready") : support.capabilities.skill ? t("cli.install.capabilities.follow-up.install") : t("cli.install.capabilities.follow-up.manual")
2229
2272
  };
2230
2273
  }
2231
2274
  function capabilityInstallStatus(support, capability) {
2232
2275
  if (!support.capabilities[capability]) {
2233
- return t("cli.init.capabilities.status.na");
2276
+ return t("cli.install.capabilities.status.na");
2234
2277
  }
2235
- return hasInstalledCapability(support, capability) ? t("cli.init.capabilities.status.installed") : t("cli.init.capabilities.status.supported");
2278
+ return hasInstalledCapability(support, capability) ? t("cli.install.capabilities.status.installed") : t("cli.install.capabilities.status.supported");
2236
2279
  }
2237
2280
  function hasInstalledCapability(support, capability) {
2238
2281
  return support.installedCapabilities?.[capability] === true;
@@ -2240,15 +2283,15 @@ function hasInstalledCapability(support, capability) {
2240
2283
  function capabilityStatus(disposition) {
2241
2284
  switch (disposition) {
2242
2285
  case "ran":
2243
- return t("cli.init.capabilities.status.ready");
2286
+ return t("cli.install.capabilities.status.ready");
2244
2287
  case "skipped":
2245
- return t("cli.init.capabilities.status.skipped");
2288
+ return t("cli.install.capabilities.status.skipped");
2246
2289
  case "failed":
2247
- return t("cli.init.capabilities.status.failed");
2290
+ return t("cli.install.capabilities.status.failed");
2248
2291
  case null:
2249
- return t("cli.init.capabilities.status.na");
2292
+ return t("cli.install.capabilities.status.na");
2250
2293
  default:
2251
- return t("cli.init.capabilities.status.ready");
2294
+ return t("cli.install.capabilities.status.ready");
2252
2295
  }
2253
2296
  }
2254
2297
  function formatCapabilityTableRow(row, widths) {
@@ -2274,21 +2317,21 @@ function formatCapabilityDivider(widths) {
2274
2317
  function formatInitReasonMessage(supports) {
2275
2318
  const detected = supports.filter((support) => support.detected);
2276
2319
  if (detected.some((support) => support.capabilities.skill)) {
2277
- return t("cli.init.reason-message.installable-body");
2320
+ return t("cli.install.reason-message.installable-body");
2278
2321
  }
2279
- return t("cli.init.reason-message.manual-body");
2322
+ return t("cli.install.reason-message.manual-body");
2280
2323
  }
2281
2324
  function yesNoLabel(value) {
2282
2325
  return value ? t("cli.shared.yes") : t("cli.shared.no");
2283
2326
  }
2284
2327
  function formatInitPathAction(path, action) {
2285
- return t("cli.init.created-path", { label: labelForInitWriteAction(action), path });
2328
+ return t("cli.install.created-path", { label: labelForInitWriteAction(action), path });
2286
2329
  }
2287
2330
  function formatAgentsMdAction(path, action) {
2288
2331
  if (action === "preserved") {
2289
- return t("cli.init.skipped-existing-path", { label: skippedLabel(), path });
2332
+ return t("cli.install.skipped-existing-path", { label: skippedLabel(), path });
2290
2333
  }
2291
- return t("cli.init.created-path", { label: createdLabel(), path });
2334
+ return t("cli.install.created-path", { label: createdLabel(), path });
2292
2335
  }
2293
2336
  function labelForInitWriteAction(action) {
2294
2337
  return action === "overwritten" ? overwrittenLabel() : createdLabel();
@@ -2306,16 +2349,16 @@ function reasonLabel() {
2306
2349
  return paint.human(t("cli.shared.reason"));
2307
2350
  }
2308
2351
  function overwrittenLabel() {
2309
- return paint.warn(t("cli.init.force.overwritten"));
2352
+ return paint.warn(t("cli.install.force.overwritten"));
2310
2353
  }
2311
2354
  function completedStageLabel() {
2312
- return paint.success(t("cli.init.stages.completed"));
2355
+ return paint.success(t("cli.install.stages.completed"));
2313
2356
  }
2314
2357
  function skippedStageLabel() {
2315
- return paint.muted(t("cli.init.stages.skipped"));
2358
+ return paint.muted(t("cli.install.stages.skipped"));
2316
2359
  }
2317
2360
  function failedStageLabel() {
2318
- return paint.error(t("cli.init.stages.failed"));
2361
+ return paint.error(t("cli.install.stages.failed"));
2319
2362
  }
2320
2363
  function writeStderr2(message) {
2321
2364
  process.stderr.write(`${message}
@@ -2325,12 +2368,12 @@ export {
2325
2368
  buildInitExecutionPlan,
2326
2369
  buildInitFabricPlan,
2327
2370
  createDefaultInitWizardAdapter,
2328
- init_default as default,
2371
+ install_default as default,
2329
2372
  detectPackageManager,
2330
2373
  executeInitExecutionPlan,
2331
2374
  executeInitFabricPlan,
2332
- initCommand,
2333
2375
  initFabric,
2376
+ installCommand,
2334
2377
  resolveInitExecutionPlanWithWizard,
2335
2378
  runInitCommand,
2336
2379
  shouldUseInitWizard