@fenglimg/fabric-cli 0.1.4 → 1.1.0
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.
- package/dist/{bootstrap-HUDJ2E3Q.js → bootstrap-PMIA4W6G.js} +16 -12
- package/dist/chunk-6ICJICVU.js +10 -0
- package/dist/{chunk-T3WQUWW4.js → chunk-6UUPKSDE.js} +78 -36
- package/dist/chunk-AEOYCVBG.js +0 -0
- package/dist/{chunk-U376IPKT.js → chunk-F2BXHPM5.js} +11 -7
- package/dist/chunk-JWUO6TIS.js +220 -0
- package/dist/{chunk-CZ7U6ULM.js → chunk-L43IGJ6X.js} +17 -7
- package/dist/{chunk-N7TTCGJA.js → chunk-VMYPJPKV.js} +1 -0
- package/dist/chunk-WWNXR34K.js +49 -0
- package/dist/{config-YKDWIRCT.js → config-PXEEXWLM.js} +14 -11
- package/dist/doctor-QTSG2RWF.js +125 -0
- package/dist/{hooks-VXXO4VZP.js → hooks-5S5IRVQE.js} +15 -12
- package/dist/human-lint-YSFOZHZ7.js +13 -0
- package/dist/index.js +16 -11
- package/dist/init-R73E5YTG.js +1164 -0
- package/dist/{ledger-append-EGIKSMU5.js → ledger-append-XZ5SX4O5.js} +2 -1
- package/dist/{pre-commit-CXPH7BZH.js → pre-commit-BLSUMT3P.js} +14 -9
- package/dist/{scan-UASZQLQP.js → scan-JBGFRB7P.js} +3 -2
- package/dist/serve-4J2CQY25.js +112 -0
- package/dist/{sync-meta-YTG5V3Y6.js → sync-meta-THZSEM7Y.js} +6 -2
- package/package.json +12 -8
- package/templates/agents-md/AGENTS.md.template +20 -29
- package/templates/agents-md/variants/cocos.md +20 -0
- package/templates/agents-md/variants/next.md +20 -0
- package/templates/agents-md/variants/vite.md +20 -0
- package/templates/claude-hooks/agents-md-init-reminder.cjs +18 -0
- package/templates/claude-skills/agents-md-init/SKILL.md +86 -0
- package/dist/chunk-BWZHNZG6.js +0 -236
- package/dist/chunk-P4KVFB2T.js +0 -22
- package/dist/human-lint-II6TBGP4.js +0 -9
- package/dist/init-IBS7KO7A.js +0 -149
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
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
|
+
|
|
44
|
+
export {
|
|
45
|
+
paint,
|
|
46
|
+
symbol,
|
|
47
|
+
displayWidth,
|
|
48
|
+
padEnd
|
|
49
|
+
};
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
resolveClients
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-VMYPJPKV.js";
|
|
5
|
+
import {
|
|
6
|
+
t
|
|
7
|
+
} from "./chunk-6ICJICVU.js";
|
|
5
8
|
|
|
6
9
|
// src/commands/config.ts
|
|
7
10
|
import { existsSync } from "fs";
|
|
@@ -37,7 +40,7 @@ function parseClientFilter(value) {
|
|
|
37
40
|
const alias = rawClient.trim().toLowerCase();
|
|
38
41
|
const clientKind = CLIENT_ALIASES[alias];
|
|
39
42
|
if (clientKind === void 0) {
|
|
40
|
-
throw new Error(
|
|
43
|
+
throw new Error(t("cli.config.errors.unknown-client", { client: rawClient }));
|
|
41
44
|
}
|
|
42
45
|
clients.add(clientKind);
|
|
43
46
|
}
|
|
@@ -50,7 +53,7 @@ async function loadFabricConfig(workspaceRoot) {
|
|
|
50
53
|
}
|
|
51
54
|
const parsed = JSON.parse(await readFile(configPath, "utf8"));
|
|
52
55
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
53
|
-
throw new Error(
|
|
56
|
+
throw new Error(t("cli.config.errors.expected-object", { path: configPath }));
|
|
54
57
|
}
|
|
55
58
|
return parsed;
|
|
56
59
|
}
|
|
@@ -65,22 +68,22 @@ function writeStderr(message) {
|
|
|
65
68
|
var configCmd = defineCommand({
|
|
66
69
|
meta: {
|
|
67
70
|
name: "config",
|
|
68
|
-
description: "
|
|
71
|
+
description: t("cli.config.description")
|
|
69
72
|
},
|
|
70
73
|
subCommands: {
|
|
71
74
|
install: defineCommand({
|
|
72
75
|
meta: {
|
|
73
76
|
name: "install",
|
|
74
|
-
description: "
|
|
77
|
+
description: t("cli.config.install.description")
|
|
75
78
|
},
|
|
76
79
|
args: {
|
|
77
80
|
clients: {
|
|
78
81
|
type: "string",
|
|
79
|
-
description: "
|
|
82
|
+
description: t("cli.config.install.args.clients.description")
|
|
80
83
|
},
|
|
81
84
|
"dry-run": {
|
|
82
85
|
type: "boolean",
|
|
83
|
-
description: "
|
|
86
|
+
description: t("cli.config.install.args.dry-run.description"),
|
|
84
87
|
default: false
|
|
85
88
|
}
|
|
86
89
|
},
|
|
@@ -93,21 +96,21 @@ var configCmd = defineCommand({
|
|
|
93
96
|
(writer) => selectedClients === null ? true : selectedClients.has(writer.clientKind)
|
|
94
97
|
);
|
|
95
98
|
if (writers.length === 0) {
|
|
96
|
-
writeStderr("
|
|
99
|
+
writeStderr(t("cli.config.install.no-configs"));
|
|
97
100
|
return;
|
|
98
101
|
}
|
|
99
102
|
for (const writer of writers) {
|
|
100
103
|
const configPath = await writer.detect(workspaceRoot);
|
|
101
104
|
if (configPath === null) {
|
|
102
|
-
writeStderr(
|
|
105
|
+
writeStderr(t("cli.config.install.no-config-path", { client: writer.clientKind }));
|
|
103
106
|
continue;
|
|
104
107
|
}
|
|
105
108
|
if (args["dry-run"]) {
|
|
106
|
-
writeStderr(
|
|
109
|
+
writeStderr(t("cli.config.install.dry-run", { client: writer.clientKind, path: configPath }));
|
|
107
110
|
continue;
|
|
108
111
|
}
|
|
109
112
|
await writer.write(serverPath, workspaceRoot);
|
|
110
|
-
writeStderr(
|
|
113
|
+
writeStderr(t("cli.config.install.wrote", { client: writer.clientKind, path: configPath }));
|
|
111
114
|
}
|
|
112
115
|
}
|
|
113
116
|
})
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
resolveDevMode
|
|
4
|
+
} from "./chunk-AEOYCVBG.js";
|
|
5
|
+
import {
|
|
6
|
+
padEnd,
|
|
7
|
+
paint,
|
|
8
|
+
symbol
|
|
9
|
+
} from "./chunk-WWNXR34K.js";
|
|
10
|
+
import {
|
|
11
|
+
t
|
|
12
|
+
} from "./chunk-6ICJICVU.js";
|
|
13
|
+
|
|
14
|
+
// src/commands/doctor.ts
|
|
15
|
+
import { defineCommand } from "citty";
|
|
16
|
+
import { runDoctorAuditReport, runDoctorReport } from "@fenglimg/fabric-server";
|
|
17
|
+
var DEFAULT_AUDIT_WINDOW_MINUTES = 5;
|
|
18
|
+
var doctorCommand = defineCommand({
|
|
19
|
+
meta: {
|
|
20
|
+
name: "doctor",
|
|
21
|
+
description: t("cli.doctor.description")
|
|
22
|
+
},
|
|
23
|
+
args: {
|
|
24
|
+
target: {
|
|
25
|
+
type: "string",
|
|
26
|
+
description: t("cli.doctor.args.target.description")
|
|
27
|
+
},
|
|
28
|
+
audit: {
|
|
29
|
+
type: "boolean",
|
|
30
|
+
description: t("cli.doctor.args.audit.description"),
|
|
31
|
+
default: false
|
|
32
|
+
},
|
|
33
|
+
"window-minutes": {
|
|
34
|
+
type: "string",
|
|
35
|
+
description: t("cli.doctor.args.window-minutes.description"),
|
|
36
|
+
default: String(DEFAULT_AUDIT_WINDOW_MINUTES)
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
async run({ args }) {
|
|
40
|
+
const workspaceRoot = process.cwd();
|
|
41
|
+
const resolution = resolveDevMode(args.target, workspaceRoot);
|
|
42
|
+
const report = await runDoctorReport(resolution.target);
|
|
43
|
+
writeStdout(`${renderStatus(report.status)} ${paint.ai("fab doctor")} ${paint.human(resolution.target)}`);
|
|
44
|
+
for (const check of report.checks) {
|
|
45
|
+
writeStdout(`${renderStatus(check.status)} ${check.name}: ${check.message}`);
|
|
46
|
+
}
|
|
47
|
+
if (!args.audit) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const auditReport = await runDoctorAuditReport(resolution.target, {
|
|
51
|
+
force: true,
|
|
52
|
+
windowMs: parseWindowMinutes(args["window-minutes"])
|
|
53
|
+
});
|
|
54
|
+
if (auditReport.mode === "off") {
|
|
55
|
+
writeStderr(t("cli.doctor.audit.preview-only"));
|
|
56
|
+
}
|
|
57
|
+
if (auditReport.checkedPathCount === 0) {
|
|
58
|
+
writeStderr(t("cli.doctor.audit.none"));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (auditReport.violationCount === 0) {
|
|
62
|
+
writeStderr(
|
|
63
|
+
`${symbol.ok} ${t("cli.doctor.audit.clean", {
|
|
64
|
+
count: String(auditReport.checkedPathCount),
|
|
65
|
+
window: formatDuration(auditReport.windowMs)
|
|
66
|
+
})}`
|
|
67
|
+
);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const writer = auditReport.mode === "strict" ? console.error : console.warn;
|
|
71
|
+
writer(
|
|
72
|
+
t("cli.doctor.audit.violations", {
|
|
73
|
+
count: String(auditReport.violationCount),
|
|
74
|
+
window: formatDuration(auditReport.windowMs)
|
|
75
|
+
})
|
|
76
|
+
);
|
|
77
|
+
writeStderr(
|
|
78
|
+
`${padEnd(t("cli.doctor.audit.table.path"), 32)} ${padEnd(t("cli.doctor.audit.table.edit"), 22)} ${padEnd(t("cli.doctor.audit.table.rules"), 22)} ${t("cli.doctor.audit.table.intent")}`
|
|
79
|
+
);
|
|
80
|
+
for (const violation of auditReport.violations) {
|
|
81
|
+
writeStderr(
|
|
82
|
+
`${padEnd(violation.path, 32)} ${padEnd(new Date(violation.editTs).toISOString(), 22)} ${padEnd(formatRulesTs(violation.lastGetRulesTs), 22)} ${violation.intent}`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
if (auditReport.mode === "strict") {
|
|
86
|
+
process.exitCode = 1;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
var doctor_default = doctorCommand;
|
|
91
|
+
function renderStatus(status) {
|
|
92
|
+
if (status === "ok") {
|
|
93
|
+
return symbol.ok;
|
|
94
|
+
}
|
|
95
|
+
if (status === "warn") {
|
|
96
|
+
return symbol.warn;
|
|
97
|
+
}
|
|
98
|
+
return symbol.error;
|
|
99
|
+
}
|
|
100
|
+
function parseWindowMinutes(value) {
|
|
101
|
+
const minutes = Number.parseInt(value ?? String(DEFAULT_AUDIT_WINDOW_MINUTES), 10);
|
|
102
|
+
if (!Number.isInteger(minutes) || minutes < 1) {
|
|
103
|
+
throw new Error(t("cli.doctor.errors.invalid-window", { value: value ?? "<unset>" }));
|
|
104
|
+
}
|
|
105
|
+
return minutes * 60 * 1e3;
|
|
106
|
+
}
|
|
107
|
+
function formatDuration(durationMs) {
|
|
108
|
+
const minutes = Math.max(Math.floor(durationMs / (60 * 1e3)), 1);
|
|
109
|
+
return `${minutes}m`;
|
|
110
|
+
}
|
|
111
|
+
function formatRulesTs(value) {
|
|
112
|
+
return value === null ? t("cli.shared.none") : new Date(value).toISOString();
|
|
113
|
+
}
|
|
114
|
+
function writeStdout(message) {
|
|
115
|
+
process.stdout.write(`${message}
|
|
116
|
+
`);
|
|
117
|
+
}
|
|
118
|
+
function writeStderr(message) {
|
|
119
|
+
process.stderr.write(`${message}
|
|
120
|
+
`);
|
|
121
|
+
}
|
|
122
|
+
export {
|
|
123
|
+
doctor_default as default,
|
|
124
|
+
doctorCommand
|
|
125
|
+
};
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
t
|
|
4
|
+
} from "./chunk-6ICJICVU.js";
|
|
2
5
|
|
|
3
6
|
// src/commands/hooks.ts
|
|
4
7
|
import { chmodSync, existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "fs";
|
|
@@ -8,18 +11,18 @@ import { defineCommand } from "citty";
|
|
|
8
11
|
var hooksCommand = defineCommand({
|
|
9
12
|
meta: {
|
|
10
13
|
name: "hooks",
|
|
11
|
-
description: "
|
|
14
|
+
description: t("cli.hooks.description")
|
|
12
15
|
},
|
|
13
16
|
subCommands: {
|
|
14
17
|
install: defineCommand({
|
|
15
18
|
meta: {
|
|
16
19
|
name: "install",
|
|
17
|
-
description: "
|
|
20
|
+
description: t("cli.hooks.install.description")
|
|
18
21
|
},
|
|
19
22
|
args: {
|
|
20
23
|
target: {
|
|
21
24
|
type: "string",
|
|
22
|
-
description: "
|
|
25
|
+
description: t("cli.hooks.install.args.target.description"),
|
|
23
26
|
default: process.cwd()
|
|
24
27
|
}
|
|
25
28
|
},
|
|
@@ -30,7 +33,7 @@ var hooksCommand = defineCommand({
|
|
|
30
33
|
const hookPath = join(huskyDir, "pre-commit");
|
|
31
34
|
const packageJsonPath = join(target, "package.json");
|
|
32
35
|
if (!existsSync(packageJsonPath)) {
|
|
33
|
-
throw new Error(
|
|
36
|
+
throw new Error(t("cli.hooks.errors.package-json-required", { path: packageJsonPath }));
|
|
34
37
|
}
|
|
35
38
|
mkdirSync(huskyDir, { recursive: true });
|
|
36
39
|
const templateContent = readFileSync(findTemplatePath("templates/husky/pre-commit"), "utf8");
|
|
@@ -61,16 +64,16 @@ ${fabricBlock}`, "utf8");
|
|
|
61
64
|
`, "utf8");
|
|
62
65
|
}
|
|
63
66
|
if (hookAction === "skipped") {
|
|
64
|
-
writeStderr(
|
|
67
|
+
writeStderr(t("cli.hooks.install.hook-skipped", { path: hookPath }));
|
|
65
68
|
} else if (hookAction === "appended") {
|
|
66
|
-
writeStderr(
|
|
69
|
+
writeStderr(t("cli.hooks.install.hook-appended", { path: hookPath }));
|
|
67
70
|
} else {
|
|
68
|
-
writeStderr(
|
|
71
|
+
writeStderr(t("cli.hooks.install.hook-created", { path: hookPath }));
|
|
69
72
|
}
|
|
70
73
|
if (hadPrepare) {
|
|
71
|
-
writeStderr(
|
|
74
|
+
writeStderr(t("cli.hooks.install.prepare-left", { path: packageJsonPath }));
|
|
72
75
|
} else {
|
|
73
|
-
writeStderr(
|
|
76
|
+
writeStderr(t("cli.hooks.install.prepare-added", { path: packageJsonPath }));
|
|
74
77
|
}
|
|
75
78
|
}
|
|
76
79
|
})
|
|
@@ -82,7 +85,7 @@ function normalizeTarget(targetInput) {
|
|
|
82
85
|
}
|
|
83
86
|
function assertExistingDirectory(target) {
|
|
84
87
|
if (!existsSync(target) || !statSync(target).isDirectory()) {
|
|
85
|
-
throw new Error(
|
|
88
|
+
throw new Error(t("cli.shared.target-invalid", { target }));
|
|
86
89
|
}
|
|
87
90
|
}
|
|
88
91
|
function findTemplatePath(relativePath) {
|
|
@@ -96,7 +99,7 @@ function findTemplatePath(relativePath) {
|
|
|
96
99
|
return candidate;
|
|
97
100
|
}
|
|
98
101
|
}
|
|
99
|
-
throw new Error(
|
|
102
|
+
throw new Error(t("cli.shared.template-not-found", { path: relativePath }));
|
|
100
103
|
}
|
|
101
104
|
function templateCandidatesFrom(start, relativePath) {
|
|
102
105
|
const candidates = [];
|
|
@@ -109,7 +112,7 @@ function templateCandidatesFrom(start, relativePath) {
|
|
|
109
112
|
}
|
|
110
113
|
current = parent;
|
|
111
114
|
}
|
|
112
|
-
return candidates;
|
|
115
|
+
return candidates.reverse();
|
|
113
116
|
}
|
|
114
117
|
function writeStderr(message) {
|
|
115
118
|
process.stderr.write(`${message}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
humanLintCommand,
|
|
4
|
+
humanLockEntrySchema,
|
|
5
|
+
human_lint_default
|
|
6
|
+
} from "./chunk-L43IGJ6X.js";
|
|
7
|
+
import "./chunk-WWNXR34K.js";
|
|
8
|
+
import "./chunk-6ICJICVU.js";
|
|
9
|
+
export {
|
|
10
|
+
human_lint_default as default,
|
|
11
|
+
humanLintCommand,
|
|
12
|
+
humanLockEntrySchema
|
|
13
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
t
|
|
4
|
+
} from "./chunk-6ICJICVU.js";
|
|
2
5
|
|
|
3
6
|
// src/index.ts
|
|
4
7
|
import { realpathSync } from "fs";
|
|
@@ -8,23 +11,25 @@ import { defineCommand, runMain } from "citty";
|
|
|
8
11
|
|
|
9
12
|
// src/commands/index.ts
|
|
10
13
|
var allCommands = {
|
|
11
|
-
bootstrap: () => import("./bootstrap-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
bootstrap: () => import("./bootstrap-PMIA4W6G.js").then((module) => module.default),
|
|
15
|
+
doctor: () => import("./doctor-QTSG2RWF.js").then((module) => module.default),
|
|
16
|
+
init: () => import("./init-R73E5YTG.js").then((module) => module.default),
|
|
17
|
+
scan: () => import("./scan-JBGFRB7P.js").then((module) => module.default),
|
|
18
|
+
serve: () => import("./serve-4J2CQY25.js").then((module) => module.default),
|
|
19
|
+
"sync-meta": () => import("./sync-meta-THZSEM7Y.js").then((module) => module.default),
|
|
20
|
+
"human-lint": () => import("./human-lint-YSFOZHZ7.js").then((module) => module.default),
|
|
21
|
+
"ledger-append": () => import("./ledger-append-XZ5SX4O5.js").then((module) => module.default),
|
|
22
|
+
hooks: () => import("./hooks-5S5IRVQE.js").then((module) => module.default),
|
|
23
|
+
config: () => import("./config-PXEEXWLM.js").then((module) => module.configCmd),
|
|
24
|
+
"pre-commit": () => import("./pre-commit-BLSUMT3P.js").then((module) => module.default)
|
|
20
25
|
};
|
|
21
26
|
|
|
22
27
|
// src/index.ts
|
|
23
28
|
var main = defineCommand({
|
|
24
29
|
meta: {
|
|
25
30
|
name: "fab",
|
|
26
|
-
version: "
|
|
27
|
-
description: "
|
|
31
|
+
version: "1.1.0",
|
|
32
|
+
description: t("cli.main.description")
|
|
28
33
|
},
|
|
29
34
|
subCommands: allCommands
|
|
30
35
|
});
|