@fenglimg/fabric-cli 1.6.0 → 1.8.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +8 -14
  2. package/dist/{chunk-QSAEGVKE.js → chunk-NMMUETVK.js} +4 -8
  3. package/dist/{chunk-AEOYCVBG.js → chunk-QPCRBQ5Y.js} +52 -5
  4. package/dist/doctor-F52XWWZC.js +98 -0
  5. package/dist/index.js +5 -20
  6. package/dist/{init-LBVOI2QI.js → init-AEO5JU7R.js} +1084 -167
  7. package/dist/{scan-QH76LC7Z.js → scan-NNBNGIZG.js} +2 -4
  8. package/dist/{serve-4J2CQY25.js → serve-466QXQ5Q.js} +17 -9
  9. package/package.json +5 -7
  10. package/templates/agents-md/AGENTS.md.template +7 -7
  11. package/templates/agents-md/variants/cocos.md +7 -7
  12. package/templates/agents-md/variants/next.md +7 -7
  13. package/templates/agents-md/variants/vite.md +7 -7
  14. package/templates/bootstrap/CLAUDE.md +3 -1
  15. package/templates/bootstrap/GEMINI.md +3 -1
  16. package/templates/bootstrap/codex-AGENTS-header.md +3 -1
  17. package/templates/bootstrap/cursor-fabric-bootstrap.mdc +5 -6
  18. package/templates/bootstrap/roo-fabric.md +5 -6
  19. package/templates/bootstrap/windsurf-fabric.md +5 -6
  20. package/templates/claude-skills/fabric-init/SKILL.md +163 -0
  21. package/templates/codex-skills/fabric-init/SKILL.md +153 -18
  22. package/templates/husky/pre-commit +9 -24
  23. package/templates/skill-source/fabric-init/SOURCE.md +157 -0
  24. package/templates/skill-source/fabric-init/clients.json +17 -0
  25. package/dist/approve-YT4DEABS.js +0 -138
  26. package/dist/bootstrap-VGL3AR26.js +0 -16
  27. package/dist/chunk-2YW5CJ32.js +0 -147
  28. package/dist/chunk-6ICJICVU.js +0 -10
  29. package/dist/chunk-BEKSXO5N.js +0 -442
  30. package/dist/chunk-BVTMVW5M.js +0 -159
  31. package/dist/chunk-KOAEIH72.js +0 -270
  32. package/dist/chunk-L43IGJ6X.js +0 -106
  33. package/dist/chunk-T2WJF5I3.js +0 -254
  34. package/dist/chunk-WWNXR34K.js +0 -49
  35. package/dist/chunk-YDZJRLHL.js +0 -155
  36. package/dist/config-EC5L2QNI.js +0 -16
  37. package/dist/doctor-4BPYHV7V.js +0 -134
  38. package/dist/hooks-ZSWVH2JD.js +0 -12
  39. package/dist/human-lint-YSFOZHZ7.js +0 -13
  40. package/dist/ledger-append-3MDNR3GU.js +0 -10
  41. package/dist/pre-commit-53ENJDRZ.js +0 -98
  42. package/dist/sync-meta-IZR2WLIL.js +0 -16
  43. package/dist/update-M5M5PYKE.js +0 -116
  44. package/templates/claude-skills/agents-md-init/SKILL.md +0 -86
  45. package/templates/fabric/human-lock.json +0 -12
package/README.md CHANGED
@@ -7,24 +7,18 @@
7
7
  1. 在 monorepo 根目录运行 `pnpm install`。
8
8
  2. 用 `pnpm --filter @fenglimg/fabric-cli build` 构建 CLI。
9
9
  3. 在目标项目运行 `fabric init`,完成一站式初始化。
10
- 4. 启动 `fabric serve`,再去客户端里验证 `fab_get_rules`。
10
+ 4. 启动 `fabric serve`,再去客户端里验证 `fab_plan_context` 和 `fab_get_rule_sections`。
11
11
 
12
- `fabric init` 会自动执行 `bootstrap install`、`config install` `hooks install`。只有在需要单独重跑某个阶段时,才需要单独调用它们。
13
-
14
- `fabric bootstrap install` 只会刷新 `.fabric/bootstrap/README.md` 里的内部初始化说明,不会再生成根级 `AGENTS.md`、`CLAUDE.md` 或 `GEMINI.md`。
12
+ `fabric init` 会自动准备 bootstrap、MCP 配置和 git hooks。公共命令面只保留 `init`、`scan`、`doctor`、`serve`。
15
13
 
16
14
  ## 常用命令
17
15
 
18
16
  - `fabric init`
17
+ - `fabric scan`
18
+ - `fabric doctor`
19
+ - `fabric doctor --json`
20
+ - `fabric doctor --strict`
21
+ - `fabric doctor --fix`
19
22
  - `fabric serve`
20
- - `fabric doctor --audit`
21
- - `fabric approve --interactive`
22
- - `fabric approve --all`
23
-
24
- ## 进阶命令
25
-
26
- - `fabric bootstrap install`
27
- - `fabric config install`
28
- - `fabric hooks install`
29
23
 
30
- `fabric approve` 会在审查完成后更新 `.fabric/human-lock.json` 中已经发生漂移的条目。需要逐项确认时使用 `--interactive`,只有在别处已经完成审查时才使用 `--all`。
24
+ `fabric doctor --fix` 只修复确定性的派生状态,例如 `.fabric/agents.meta.json`、`.fabric/rule-test.index.json`、缺失的 `.fabric/events.jsonl` stale hashes;语义冲突、缺失 rule section、未完成的初始化确认仍需要人工处理。
@@ -1,18 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  createDebugLogger,
4
- readFabricConfig,
5
- resolveDevMode
6
- } from "./chunk-AEOYCVBG.js";
7
- import {
8
4
  displayWidth,
9
5
  padEnd,
10
6
  paint,
11
- symbol
12
- } from "./chunk-WWNXR34K.js";
13
- import {
7
+ readFabricConfig,
8
+ resolveDevMode,
9
+ symbol,
14
10
  t
15
- } from "./chunk-6ICJICVU.js";
11
+ } from "./chunk-QPCRBQ5Y.js";
16
12
 
17
13
  // src/commands/scan.ts
18
14
  import { existsSync, readdirSync, readFileSync, statSync } from "fs";
@@ -1,5 +1,46 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ // src/colors.ts
4
+ import pc from "picocolors";
5
+ import stringWidth from "string-width";
6
+ function isColorEnabled() {
7
+ return !process.env.NO_COLOR && Boolean(process.stdout.isTTY) && Boolean(process.stderr.isTTY);
8
+ }
9
+ function colorize(painter) {
10
+ return (value) => isColorEnabled() ? painter(value) : value;
11
+ }
12
+ var paint = {
13
+ success: colorize(pc.green),
14
+ warn: colorize(pc.yellow),
15
+ error: colorize(pc.red),
16
+ drift: colorize(pc.magenta),
17
+ ai: colorize(pc.blue),
18
+ human: colorize(pc.cyan),
19
+ muted: colorize(pc.dim)
20
+ };
21
+ var symbol = {
22
+ get ok() {
23
+ return isColorEnabled() ? paint.success("\u2713") : "[ok]";
24
+ },
25
+ get warn() {
26
+ return isColorEnabled() ? paint.warn("!") : "[warn]";
27
+ },
28
+ get error() {
29
+ return isColorEnabled() ? paint.error("x") : "[error]";
30
+ }
31
+ };
32
+ function displayWidth(value) {
33
+ return stringWidth(value);
34
+ }
35
+ function padEnd(value, width, char = " ") {
36
+ const fill = char.length > 0 ? char : " ";
37
+ let result = value;
38
+ while (displayWidth(result) < width) {
39
+ result += fill;
40
+ }
41
+ return result;
42
+ }
43
+
3
44
  // src/dev-mode.ts
4
45
  import { existsSync, readFileSync } from "fs";
5
46
  import { isAbsolute, join, resolve } from "path";
@@ -36,9 +77,6 @@ function resolveDevMode(cliTarget, workspaceRoot = process.cwd()) {
36
77
  }
37
78
  return { target: workspaceRoot, source: "cwd", chain };
38
79
  }
39
- function resolveDevModeTarget(cliTarget) {
40
- return resolveDevMode(cliTarget).target;
41
- }
42
80
  function createDebugLogger(debug) {
43
81
  const enabled = debug === true || process.env.FABRIC_DEBUG === "1";
44
82
  return (message) => {
@@ -59,9 +97,18 @@ function formatResolutionStep(source, value) {
59
97
  return `${source}: ${value ?? "<unset>"}`;
60
98
  }
61
99
 
100
+ // src/i18n.ts
101
+ import { createTranslator, detectNodeLocale } from "@fenglimg/fabric-shared";
102
+ var locale = detectNodeLocale();
103
+ var t = createTranslator(locale);
104
+
62
105
  export {
106
+ paint,
107
+ symbol,
108
+ displayWidth,
109
+ padEnd,
63
110
  readFabricConfig,
64
111
  resolveDevMode,
65
- resolveDevModeTarget,
66
- createDebugLogger
112
+ createDebugLogger,
113
+ t
67
114
  };
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ paint,
4
+ resolveDevMode,
5
+ symbol,
6
+ t
7
+ } from "./chunk-QPCRBQ5Y.js";
8
+
9
+ // src/commands/doctor.ts
10
+ import { defineCommand } from "citty";
11
+ import { checkLockOrThrow, runDoctorFix, runDoctorReport } from "@fenglimg/fabric-server";
12
+ var doctorCommand = defineCommand({
13
+ meta: {
14
+ name: "doctor",
15
+ description: t("cli.doctor.description")
16
+ },
17
+ args: {
18
+ target: {
19
+ type: "string",
20
+ description: t("cli.doctor.args.target.description")
21
+ },
22
+ fix: {
23
+ type: "boolean",
24
+ description: t("cli.doctor.args.fix.description"),
25
+ default: false
26
+ },
27
+ json: {
28
+ type: "boolean",
29
+ description: t("cli.doctor.args.json.description"),
30
+ default: false
31
+ },
32
+ strict: {
33
+ type: "boolean",
34
+ description: t("cli.doctor.args.strict.description"),
35
+ default: false
36
+ },
37
+ force: {
38
+ type: "boolean",
39
+ description: t("cli.doctor.args.force.description"),
40
+ default: false
41
+ }
42
+ },
43
+ async run({ args }) {
44
+ const workspaceRoot = process.cwd();
45
+ const resolution = resolveDevMode(args.target, workspaceRoot);
46
+ checkLockOrThrow(resolution.target, { force: args.force });
47
+ const fixReport = args.fix === true ? await runDoctorFix(resolution.target) : null;
48
+ const report = fixReport?.report ?? await runDoctorReport(resolution.target);
49
+ if (args.json === true) {
50
+ writeStdout(JSON.stringify(fixReport ?? report, null, 2));
51
+ } else {
52
+ if (fixReport !== null) {
53
+ writeStdout(fixReport.message);
54
+ }
55
+ renderHumanReport(report);
56
+ }
57
+ if (report.status === "error" || args.strict === true && (report.status === "warn" || report.warnings.length > 0)) {
58
+ process.exitCode = 1;
59
+ }
60
+ }
61
+ });
62
+ var doctor_default = doctorCommand;
63
+ function renderHumanReport(report) {
64
+ writeStdout(`${renderStatus(report.status)} ${paint.ai("fabric doctor")} ${paint.human(report.summary.target)}`);
65
+ for (const check of report.checks) {
66
+ writeStdout(`${renderStatus(check.status)} ${check.name}: ${check.message}`);
67
+ }
68
+ writeIssueSection(t("doctor.section.fixable"), report.fixable_errors);
69
+ writeIssueSection(t("doctor.section.manual"), report.manual_errors);
70
+ writeIssueSection(t("doctor.section.warnings"), report.warnings);
71
+ }
72
+ function writeIssueSection(title, issues) {
73
+ if (issues.length === 0) {
74
+ return;
75
+ }
76
+ writeStdout("");
77
+ writeStdout(title);
78
+ for (const issue of issues) {
79
+ writeStdout(`- ${issue.code}: ${issue.message}`);
80
+ }
81
+ }
82
+ function renderStatus(status) {
83
+ if (status === "ok") {
84
+ return symbol.ok;
85
+ }
86
+ if (status === "warn") {
87
+ return symbol.warn;
88
+ }
89
+ return symbol.error;
90
+ }
91
+ function writeStdout(message) {
92
+ process.stdout.write(`${message}
93
+ `);
94
+ }
95
+ export {
96
+ doctor_default as default,
97
+ doctorCommand
98
+ };
package/dist/index.js CHANGED
@@ -8,32 +8,17 @@ import { defineCommand, runMain } from "citty";
8
8
 
9
9
  // src/commands/index.ts
10
10
  var allCommands = {
11
- approve: () => import("./approve-YT4DEABS.js").then((module) => module.default),
12
- init: () => import("./init-LBVOI2QI.js").then((module) => module.default),
13
- update: () => import("./update-M5M5PYKE.js").then((module) => module.default),
14
- scan: () => import("./scan-QH76LC7Z.js").then((module) => module.default),
15
- serve: () => import("./serve-4J2CQY25.js").then((module) => module.default),
16
- doctor: () => import("./doctor-4BPYHV7V.js").then((module) => module.default),
17
- "sync-meta": () => import("./sync-meta-IZR2WLIL.js").then((module) => module.default),
18
- "human-lint": () => import("./human-lint-YSFOZHZ7.js").then((module) => module.default),
19
- "ledger-append": () => import("./ledger-append-3MDNR3GU.js").then((module) => module.default),
20
- "pre-commit": () => import("./pre-commit-53ENJDRZ.js").then((module) => module.default),
21
- bootstrap: () => import("./bootstrap-VGL3AR26.js").then((module) => module.default),
22
- config: () => import("./config-EC5L2QNI.js").then((module) => module.configCmd),
23
- hooks: () => import("./hooks-ZSWVH2JD.js").then((module) => ({
24
- ...module.default,
25
- meta: {
26
- ...module.default.meta,
27
- hidden: true
28
- }
29
- }))
11
+ init: () => import("./init-AEO5JU7R.js").then((module) => module.default),
12
+ scan: () => import("./scan-NNBNGIZG.js").then((module) => module.default),
13
+ serve: () => import("./serve-466QXQ5Q.js").then((module) => module.default),
14
+ doctor: () => import("./doctor-F52XWWZC.js").then((module) => module.default)
30
15
  };
31
16
 
32
17
  // src/index.ts
33
18
  var main = defineCommand({
34
19
  meta: {
35
20
  name: "fabric",
36
- version: "1.6.0",
21
+ version: "1.8.0-rc.1",
37
22
  description: 'Initialize and manage Fabric projects. Use "fabric init" for one-shot setup.'
38
23
  },
39
24
  subCommands: allCommands