@fenglimg/fabric-cli 1.3.0 → 1.3.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.
- package/README.md +24 -22
- package/dist/{bootstrap-IUL4SAAK.js → bootstrap-3PUKUYTY.js} +4 -2
- package/dist/{chunk-N4DCTOXW.js → chunk-AZRKMFRY.js} +6 -6
- package/dist/{chunk-F2BXHPM5.js → chunk-N7EZORJZ.js} +9 -1
- package/dist/{chunk-6UUPKSDE.js → chunk-Q4LOVXML.js} +13 -8
- package/dist/{chunk-RUQCZA2Q.js → chunk-TKTWHAKV.js} +92 -115
- package/dist/{chunk-VMYPJPKV.js → chunk-VOQKQ6W2.js} +153 -21
- package/dist/{chunk-TO5RUB4R.js → chunk-XFSQM3LJ.js} +1 -1
- package/dist/{config-MKWKDE32.js → config-GINBGANU.js} +2 -2
- package/dist/index.js +11 -11
- package/dist/{init-BZ73IUHH.js → init-T3LGMGAO.js} +168 -52
- package/dist/{ledger-append-XZ5SX4O5.js → ledger-append-DULKJ6Q2.js} +1 -1
- package/dist/{pre-commit-AK55G73F.js → pre-commit-IK6SJOPT.js} +5 -5
- package/dist/{scan-WKDSKEBB.js → scan-43R3IBLR.js} +2 -2
- package/dist/{sync-meta-THZSEM7Y.js → sync-meta-LKVSO6TS.js} +1 -1
- package/dist/{update-JZPUJ36D.js → update-AN3FYF2O.js} +5 -5
- package/package.json +3 -3
- package/templates/agents-md/AGENTS.md.template +14 -13
- package/templates/agents-md/variants/cocos.md +20 -20
- package/templates/agents-md/variants/next.md +20 -20
- package/templates/agents-md/variants/vite.md +20 -20
- package/templates/bootstrap/CLAUDE.md +3 -5
- package/templates/bootstrap/GEMINI.md +3 -5
- package/templates/bootstrap/codex-AGENTS-header.md +3 -5
- package/templates/bootstrap/cursor-fabric-bootstrap.mdc +11 -11
- package/templates/bootstrap/roo-fabric.md +6 -6
- package/templates/bootstrap/windsurf-fabric.md +6 -6
- package/templates/claude-hooks/agents-md-init-reminder.cjs +18 -18
- package/templates/claude-skills/agents-md-init/SKILL.md +86 -86
- package/templates/fabric/human-lock.json +12 -12
- package/templates/husky/pre-commit +24 -24
- package/dist/{doctor-5KJGOV2P.js → doctor-QTSG2RWF.js} +3 -3
- package/dist/{serve-MMN4GYLM.js → serve-4J2CQY25.js} +4 -4
package/dist/index.js
CHANGED
|
@@ -8,17 +8,17 @@ import { defineCommand, runMain } from "citty";
|
|
|
8
8
|
|
|
9
9
|
// src/commands/index.ts
|
|
10
10
|
var allCommands = {
|
|
11
|
-
init: () => import("./init-
|
|
12
|
-
update: () => import("./update-
|
|
13
|
-
scan: () => import("./scan-
|
|
14
|
-
serve: () => import("./serve-
|
|
15
|
-
doctor: () => import("./doctor-
|
|
16
|
-
"sync-meta": () => import("./sync-meta-
|
|
11
|
+
init: () => import("./init-T3LGMGAO.js").then((module) => module.default),
|
|
12
|
+
update: () => import("./update-AN3FYF2O.js").then((module) => module.default),
|
|
13
|
+
scan: () => import("./scan-43R3IBLR.js").then((module) => module.default),
|
|
14
|
+
serve: () => import("./serve-4J2CQY25.js").then((module) => module.default),
|
|
15
|
+
doctor: () => import("./doctor-QTSG2RWF.js").then((module) => module.default),
|
|
16
|
+
"sync-meta": () => import("./sync-meta-LKVSO6TS.js").then((module) => module.default),
|
|
17
17
|
"human-lint": () => import("./human-lint-YSFOZHZ7.js").then((module) => module.default),
|
|
18
|
-
"ledger-append": () => import("./ledger-append-
|
|
19
|
-
"pre-commit": () => import("./pre-commit-
|
|
20
|
-
bootstrap: () => import("./bootstrap-
|
|
21
|
-
config: () => import("./config-
|
|
18
|
+
"ledger-append": () => import("./ledger-append-DULKJ6Q2.js").then((module) => module.default),
|
|
19
|
+
"pre-commit": () => import("./pre-commit-IK6SJOPT.js").then((module) => module.default),
|
|
20
|
+
bootstrap: () => import("./bootstrap-3PUKUYTY.js").then((module) => module.default),
|
|
21
|
+
config: () => import("./config-GINBGANU.js").then((module) => module.configCmd),
|
|
22
22
|
hooks: () => import("./hooks-ZSWVH2JD.js").then((module) => ({
|
|
23
23
|
...module.default,
|
|
24
24
|
meta: {
|
|
@@ -32,7 +32,7 @@ var allCommands = {
|
|
|
32
32
|
var main = defineCommand({
|
|
33
33
|
meta: {
|
|
34
34
|
name: "fabric",
|
|
35
|
-
version: "1.3.
|
|
35
|
+
version: "1.3.1",
|
|
36
36
|
description: 'Initialize and manage Fabric projects. Use "fabric init" for one-shot setup.'
|
|
37
37
|
},
|
|
38
38
|
subCommands: allCommands
|
|
@@ -1,25 +1,29 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
buildFabricBootstrapGuide,
|
|
3
4
|
installBootstrap
|
|
4
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-TKTWHAKV.js";
|
|
5
6
|
import {
|
|
6
|
-
createScanReport,
|
|
7
7
|
detectFramework
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-AZRKMFRY.js";
|
|
9
9
|
import {
|
|
10
10
|
installMcpClients
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import
|
|
11
|
+
} from "./chunk-XFSQM3LJ.js";
|
|
12
|
+
import {
|
|
13
|
+
detectClientSupports
|
|
14
|
+
} from "./chunk-VOQKQ6W2.js";
|
|
13
15
|
import {
|
|
14
16
|
installHooks
|
|
15
17
|
} from "./chunk-YDZJRLHL.js";
|
|
16
|
-
import {
|
|
17
|
-
paint
|
|
18
|
-
} from "./chunk-WWNXR34K.js";
|
|
19
18
|
import {
|
|
20
19
|
createDebugLogger,
|
|
21
20
|
resolveDevMode
|
|
22
21
|
} from "./chunk-AEOYCVBG.js";
|
|
22
|
+
import {
|
|
23
|
+
displayWidth,
|
|
24
|
+
padEnd,
|
|
25
|
+
paint
|
|
26
|
+
} from "./chunk-WWNXR34K.js";
|
|
23
27
|
import {
|
|
24
28
|
t
|
|
25
29
|
} from "./chunk-6ICJICVU.js";
|
|
@@ -852,7 +856,7 @@ function readProjectName(target) {
|
|
|
852
856
|
return basename(target);
|
|
853
857
|
}
|
|
854
858
|
function getCliVersion() {
|
|
855
|
-
return true ? "1.3.
|
|
859
|
+
return true ? "1.3.1" : "unknown";
|
|
856
860
|
}
|
|
857
861
|
function sortRecord(record) {
|
|
858
862
|
return Object.fromEntries(Object.entries(record).sort(([left], [right]) => left.localeCompare(right)));
|
|
@@ -862,11 +866,6 @@ function toPosixPath(path) {
|
|
|
862
866
|
}
|
|
863
867
|
|
|
864
868
|
// src/commands/init.ts
|
|
865
|
-
var AGENTS_TEMPLATE_BY_FRAMEWORK = {
|
|
866
|
-
"cocos-creator": "templates/agents-md/variants/cocos.md",
|
|
867
|
-
vite: "templates/agents-md/variants/vite.md",
|
|
868
|
-
next: "templates/agents-md/variants/next.md"
|
|
869
|
-
};
|
|
870
869
|
var CLAUDE_INIT_SKILL_TEMPLATE = "templates/claude-skills/agents-md-init/SKILL.md";
|
|
871
870
|
var CLAUDE_INIT_REMINDER_HOOK_TEMPLATE = "templates/claude-hooks/agents-md-init-reminder.cjs";
|
|
872
871
|
var CLAUDE_INIT_REMINDER_COMMAND = ".claude/hooks/agents-md-init-reminder.cjs";
|
|
@@ -907,6 +906,11 @@ var initCommand = defineCommand({
|
|
|
907
906
|
default: true,
|
|
908
907
|
negativeDescription: t("cli.init.args.no-hooks.description")
|
|
909
908
|
},
|
|
909
|
+
interactive: {
|
|
910
|
+
type: "boolean",
|
|
911
|
+
description: t("cli.init.args.interactive.description"),
|
|
912
|
+
default: true
|
|
913
|
+
},
|
|
910
914
|
"mcp-install": {
|
|
911
915
|
type: "string",
|
|
912
916
|
default: "global",
|
|
@@ -928,11 +932,16 @@ var initCommand = defineCommand({
|
|
|
928
932
|
for (const step of resolution.chain) {
|
|
929
933
|
logger(step);
|
|
930
934
|
}
|
|
935
|
+
const supports = detectClientSupports(target);
|
|
936
|
+
const interactive = args.interactive !== false && isInteractiveInit();
|
|
931
937
|
if (options.force) {
|
|
932
938
|
writeStderr(t("cli.init.force.warning", { path: target }));
|
|
933
939
|
}
|
|
940
|
+
if (interactive) {
|
|
941
|
+
printInitPlanSummary(target, options, mcpInstallMode, supports);
|
|
942
|
+
}
|
|
934
943
|
const created = initFabric(target, options);
|
|
935
|
-
console.log(formatInitPathAction(created.
|
|
944
|
+
console.log(formatInitPathAction(created.bootstrapPath, created.bootstrapAction));
|
|
936
945
|
console.log(formatInitPathAction(created.metaPath, created.metaAction));
|
|
937
946
|
console.log(formatInitPathAction(created.humanLockPath, created.humanLockAction));
|
|
938
947
|
console.log(formatInitPathAction(created.forensicPath, created.forensicAction));
|
|
@@ -1020,37 +1029,37 @@ var initCommand = defineCommand({
|
|
|
1020
1029
|
console.log(
|
|
1021
1030
|
t("cli.init.reason-message", {
|
|
1022
1031
|
label: reasonLabel(),
|
|
1023
|
-
message: paint.muted(
|
|
1032
|
+
message: paint.muted(formatInitReasonMessage(supports))
|
|
1024
1033
|
})
|
|
1025
1034
|
);
|
|
1026
1035
|
printInitStageSummary(stageResults);
|
|
1036
|
+
printInitCapabilitySummary(supports, stageResults, options);
|
|
1027
1037
|
}
|
|
1028
1038
|
});
|
|
1029
1039
|
var init_default = initCommand;
|
|
1030
1040
|
function initFabric(target, options) {
|
|
1031
1041
|
assertExistingDirectory2(target);
|
|
1032
|
-
const agentsPath = join2(target, "AGENTS.md");
|
|
1033
1042
|
const fabricDir = join2(target, ".fabric");
|
|
1043
|
+
const bootstrapPath = join2(fabricDir, "bootstrap", "README.md");
|
|
1034
1044
|
const forensicPath = join2(fabricDir, "forensic.json");
|
|
1035
1045
|
const claudeSkillPath = join2(target, ".claude", "skills", "agents-md-init", "SKILL.md");
|
|
1036
1046
|
const claudeHookPath = join2(target, ".claude", "hooks", "agents-md-init-reminder.cjs");
|
|
1037
1047
|
const claudeSettingsPath = join2(target, ".claude", "settings.json");
|
|
1038
|
-
const forensicGuardAction = prepareFreshPath(forensicPath, options);
|
|
1039
|
-
const agentsAction = prepareFreshPath(agentsPath, options);
|
|
1040
|
-
const fabricDirAction = prepareFreshPath(fabricDir, options);
|
|
1041
|
-
const forensicAction = forensicGuardAction === "overwritten" || fabricDirAction === "overwritten" ? "overwritten" : "created";
|
|
1042
|
-
const scanReport = createScanReport(target);
|
|
1043
|
-
const forensicReport = buildForensicReport(target);
|
|
1044
|
-
const template = readFileSync2(findAgentsTemplatePath(scanReport.framework.kind), "utf8");
|
|
1045
|
-
const humanLockTemplate = readFileSync2(findTemplatePath("templates/fabric/human-lock.json"), "utf8");
|
|
1046
|
-
const packageName = readPackageName(target) ?? parse(target).base;
|
|
1047
|
-
const agentsContent = template.replaceAll("{ projectName }", packageName).replaceAll("{ frameworkKind }", scanReport.framework.kind);
|
|
1048
|
-
const agentsHash = sha256(agentsContent);
|
|
1049
|
-
const meta = createInitialMeta(agentsHash);
|
|
1050
1048
|
const metaPath = join2(fabricDir, "agents.meta.json");
|
|
1051
1049
|
const humanLockPath = join2(fabricDir, "human-lock.json");
|
|
1052
|
-
|
|
1053
|
-
|
|
1050
|
+
prepareWritableDirectory(fabricDir, options);
|
|
1051
|
+
const bootstrapAction = prepareFreshPath(bootstrapPath, options);
|
|
1052
|
+
const metaAction = prepareFreshPath(metaPath, options);
|
|
1053
|
+
const humanLockAction = prepareFreshPath(humanLockPath, options);
|
|
1054
|
+
const forensicAction = prepareFreshPath(forensicPath, options);
|
|
1055
|
+
const forensicReport = buildForensicReport(target);
|
|
1056
|
+
const humanLockTemplate = readFileSync2(findTemplatePath("templates/fabric/human-lock.json"), "utf8");
|
|
1057
|
+
const bootstrapContent = buildFabricBootstrapGuide(target);
|
|
1058
|
+
const bootstrapHash = sha256(bootstrapContent);
|
|
1059
|
+
const meta = createInitialMeta(bootstrapHash);
|
|
1060
|
+
mkdirSync(fabricDir, { recursive: true });
|
|
1061
|
+
mkdirSync(dirname(bootstrapPath), { recursive: true });
|
|
1062
|
+
writeNewFile(bootstrapPath, bootstrapContent, options);
|
|
1054
1063
|
writeNewFile(metaPath, `${JSON.stringify(meta, null, 2)}
|
|
1055
1064
|
`, options);
|
|
1056
1065
|
writeNewFile(humanLockPath, humanLockTemplate.endsWith("\n") ? humanLockTemplate : `${humanLockTemplate}
|
|
@@ -1065,12 +1074,12 @@ function initFabric(target, options) {
|
|
|
1065
1074
|
);
|
|
1066
1075
|
const claudeSettingsAction = mergeClaudeStopHook(claudeSettingsPath, options);
|
|
1067
1076
|
return {
|
|
1068
|
-
|
|
1069
|
-
|
|
1077
|
+
bootstrapPath,
|
|
1078
|
+
bootstrapAction,
|
|
1070
1079
|
metaPath,
|
|
1071
|
-
metaAction
|
|
1080
|
+
metaAction,
|
|
1072
1081
|
humanLockPath,
|
|
1073
|
-
humanLockAction
|
|
1082
|
+
humanLockAction,
|
|
1074
1083
|
forensicPath,
|
|
1075
1084
|
forensicAction,
|
|
1076
1085
|
claudeSkillPath,
|
|
@@ -1081,10 +1090,6 @@ function initFabric(target, options) {
|
|
|
1081
1090
|
claudeSettingsAction
|
|
1082
1091
|
};
|
|
1083
1092
|
}
|
|
1084
|
-
function findAgentsTemplatePath(frameworkKind) {
|
|
1085
|
-
const relativePath = AGENTS_TEMPLATE_BY_FRAMEWORK[frameworkKind] ?? "templates/agents-md/AGENTS.md.template";
|
|
1086
|
-
return findTemplatePath(relativePath);
|
|
1087
|
-
}
|
|
1088
1093
|
function normalizeTarget2(targetInput) {
|
|
1089
1094
|
return isAbsolute2(targetInput) ? targetInput : resolve2(process.cwd(), targetInput);
|
|
1090
1095
|
}
|
|
@@ -1126,7 +1131,7 @@ function createInitialMeta(agentsHash) {
|
|
|
1126
1131
|
revision: sha256(agentsHash),
|
|
1127
1132
|
nodes: {
|
|
1128
1133
|
L0: {
|
|
1129
|
-
file: "
|
|
1134
|
+
file: ".fabric/bootstrap/README.md",
|
|
1130
1135
|
scope_glob: "**",
|
|
1131
1136
|
deps: [],
|
|
1132
1137
|
priority: "high",
|
|
@@ -1137,18 +1142,6 @@ function createInitialMeta(agentsHash) {
|
|
|
1137
1142
|
}
|
|
1138
1143
|
};
|
|
1139
1144
|
}
|
|
1140
|
-
function readPackageName(target) {
|
|
1141
|
-
const packageJsonPath = join2(target, "package.json");
|
|
1142
|
-
if (!existsSync2(packageJsonPath)) {
|
|
1143
|
-
return void 0;
|
|
1144
|
-
}
|
|
1145
|
-
try {
|
|
1146
|
-
const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
|
|
1147
|
-
return packageJson.name;
|
|
1148
|
-
} catch {
|
|
1149
|
-
return void 0;
|
|
1150
|
-
}
|
|
1151
|
-
}
|
|
1152
1145
|
function findTemplatePath(relativePath) {
|
|
1153
1146
|
const currentModuleDir = dirname(fileURLToPath(import.meta.url));
|
|
1154
1147
|
const candidates = [
|
|
@@ -1185,6 +1178,15 @@ function prepareFreshPath(path, options) {
|
|
|
1185
1178
|
rmSync(path, { recursive: true, force: true });
|
|
1186
1179
|
return "overwritten";
|
|
1187
1180
|
}
|
|
1181
|
+
function prepareWritableDirectory(path, options) {
|
|
1182
|
+
if (!existsSync2(path) || statSync2(path).isDirectory()) {
|
|
1183
|
+
return;
|
|
1184
|
+
}
|
|
1185
|
+
if (!options?.force) {
|
|
1186
|
+
throw new Error(t("cli.init.errors.abort-existing", { path }));
|
|
1187
|
+
}
|
|
1188
|
+
rmSync(path, { force: true });
|
|
1189
|
+
}
|
|
1188
1190
|
function writeNewFile(path, content, options) {
|
|
1189
1191
|
const existed = existsSync2(path);
|
|
1190
1192
|
if (existed && !options?.force) {
|
|
@@ -1329,6 +1331,120 @@ function collectInitStageNames(stageResults, disposition) {
|
|
|
1329
1331
|
function shouldPrintHooksNextStep(options, stageResults) {
|
|
1330
1332
|
return Boolean(options.skipHooks) || stageResults.some((stage) => stage.name === "hooks" && stage.disposition === "failed");
|
|
1331
1333
|
}
|
|
1334
|
+
function isInteractiveInit() {
|
|
1335
|
+
return Boolean(process.stdout.isTTY) && Boolean(process.stderr.isTTY);
|
|
1336
|
+
}
|
|
1337
|
+
function printInitPlanSummary(target, options, mcpInstallMode, supports) {
|
|
1338
|
+
console.log(t("cli.init.plan.title"));
|
|
1339
|
+
console.log(t("cli.init.plan.target", { target }));
|
|
1340
|
+
console.log(
|
|
1341
|
+
t("cli.init.plan.actions", {
|
|
1342
|
+
bootstrap: yesNoLabel(!options.skipBootstrap),
|
|
1343
|
+
mcp: yesNoLabel(!options.skipMcp),
|
|
1344
|
+
hooks: yesNoLabel(!options.skipHooks),
|
|
1345
|
+
mcpInstall: mcpInstallMode
|
|
1346
|
+
})
|
|
1347
|
+
);
|
|
1348
|
+
const detected = supports.filter((support) => support.detected);
|
|
1349
|
+
console.log(
|
|
1350
|
+
t("cli.init.plan.detected", {
|
|
1351
|
+
clients: detected.length > 0 ? detected.map((support) => support.label).join(", ") : t("cli.shared.none")
|
|
1352
|
+
})
|
|
1353
|
+
);
|
|
1354
|
+
console.log(t("cli.init.plan.writes"));
|
|
1355
|
+
console.log(` - ${target}/.fabric/bootstrap/README.md`);
|
|
1356
|
+
console.log(` - ${target}/.fabric/agents.meta.json`);
|
|
1357
|
+
console.log(` - ${target}/.fabric/human-lock.json`);
|
|
1358
|
+
console.log(` - ${target}/.fabric/forensic.json`);
|
|
1359
|
+
}
|
|
1360
|
+
function printInitCapabilitySummary(supports, stageResults, options) {
|
|
1361
|
+
const detected = supports.filter((support) => support.detected);
|
|
1362
|
+
if (detected.length === 0) {
|
|
1363
|
+
console.log(t("cli.init.capabilities.none"));
|
|
1364
|
+
return;
|
|
1365
|
+
}
|
|
1366
|
+
console.log(t("cli.init.capabilities.title"));
|
|
1367
|
+
const rows = detected.map((support) => toCapabilityRow(support, stageResults, options));
|
|
1368
|
+
const headers = {
|
|
1369
|
+
client: t("cli.init.capabilities.header.client"),
|
|
1370
|
+
bootstrap: t("cli.init.capabilities.header.bootstrap"),
|
|
1371
|
+
mcp: t("cli.init.capabilities.header.mcp"),
|
|
1372
|
+
hook: t("cli.init.capabilities.header.hook"),
|
|
1373
|
+
skill: t("cli.init.capabilities.header.skill"),
|
|
1374
|
+
followUp: t("cli.init.capabilities.header.follow-up")
|
|
1375
|
+
};
|
|
1376
|
+
const widths = {
|
|
1377
|
+
client: Math.max(displayWidth(headers.client), ...rows.map((row) => displayWidth(row.client))),
|
|
1378
|
+
bootstrap: Math.max(displayWidth(headers.bootstrap), ...rows.map((row) => displayWidth(row.bootstrap))),
|
|
1379
|
+
mcp: Math.max(displayWidth(headers.mcp), ...rows.map((row) => displayWidth(row.mcp))),
|
|
1380
|
+
hook: Math.max(displayWidth(headers.hook), ...rows.map((row) => displayWidth(row.hook))),
|
|
1381
|
+
skill: Math.max(displayWidth(headers.skill), ...rows.map((row) => displayWidth(row.skill))),
|
|
1382
|
+
followUp: Math.max(displayWidth(headers.followUp), ...rows.map((row) => displayWidth(row.followUp)))
|
|
1383
|
+
};
|
|
1384
|
+
console.log(formatCapabilityTableRow(headers, widths));
|
|
1385
|
+
console.log(formatCapabilityDivider(widths));
|
|
1386
|
+
for (const row of rows) {
|
|
1387
|
+
console.log(formatCapabilityTableRow(row, widths));
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
function toCapabilityRow(support, stageResults, options) {
|
|
1391
|
+
const stage = (name) => stageResults.find((entry) => entry.name === name)?.disposition ?? null;
|
|
1392
|
+
const bootstrap = support.capabilities.bootstrap ? capabilityStatus(options.skipBootstrap ? "skipped" : stage("bootstrap")) : t("cli.init.capabilities.status.na");
|
|
1393
|
+
const mcp = support.capabilities.mcp ? capabilityStatus(options.skipMcp ? "skipped" : stage("mcp")) : t("cli.init.capabilities.status.na");
|
|
1394
|
+
const hook = support.capabilities.hook ? capabilityStatus("ran") : t("cli.init.capabilities.status.na");
|
|
1395
|
+
const skill = support.capabilities.skill ? t("cli.init.capabilities.status.installed") : t("cli.init.capabilities.status.manual");
|
|
1396
|
+
return {
|
|
1397
|
+
client: support.label,
|
|
1398
|
+
bootstrap,
|
|
1399
|
+
mcp,
|
|
1400
|
+
hook,
|
|
1401
|
+
skill,
|
|
1402
|
+
followUp: support.capabilities.skill ? t("cli.init.capabilities.follow-up.ready") : t("cli.init.capabilities.follow-up.manual")
|
|
1403
|
+
};
|
|
1404
|
+
}
|
|
1405
|
+
function capabilityStatus(disposition) {
|
|
1406
|
+
switch (disposition) {
|
|
1407
|
+
case "ran":
|
|
1408
|
+
return t("cli.init.capabilities.status.ready");
|
|
1409
|
+
case "skipped":
|
|
1410
|
+
return t("cli.init.capabilities.status.skipped");
|
|
1411
|
+
case "failed":
|
|
1412
|
+
return t("cli.init.capabilities.status.failed");
|
|
1413
|
+
case null:
|
|
1414
|
+
return t("cli.init.capabilities.status.na");
|
|
1415
|
+
default:
|
|
1416
|
+
return t("cli.init.capabilities.status.ready");
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
function formatCapabilityTableRow(row, widths) {
|
|
1420
|
+
return [
|
|
1421
|
+
padEnd(row.client, widths.client),
|
|
1422
|
+
padEnd(row.bootstrap, widths.bootstrap),
|
|
1423
|
+
padEnd(row.mcp, widths.mcp),
|
|
1424
|
+
padEnd(row.hook, widths.hook),
|
|
1425
|
+
padEnd(row.skill, widths.skill),
|
|
1426
|
+
padEnd(row.followUp, widths.followUp)
|
|
1427
|
+
].join(" ");
|
|
1428
|
+
}
|
|
1429
|
+
function formatCapabilityDivider(widths) {
|
|
1430
|
+
return [
|
|
1431
|
+
"".padEnd(widths.client, "-"),
|
|
1432
|
+
"".padEnd(widths.bootstrap, "-"),
|
|
1433
|
+
"".padEnd(widths.mcp, "-"),
|
|
1434
|
+
"".padEnd(widths.hook, "-"),
|
|
1435
|
+
"".padEnd(widths.skill, "-"),
|
|
1436
|
+
"".padEnd(widths.followUp, "-")
|
|
1437
|
+
].join(" ");
|
|
1438
|
+
}
|
|
1439
|
+
function formatInitReasonMessage(supports) {
|
|
1440
|
+
if (supports.some((support) => support.detected && support.capabilities.skill)) {
|
|
1441
|
+
return t("cli.init.reason-message.body");
|
|
1442
|
+
}
|
|
1443
|
+
return t("cli.init.reason-message.manual-body");
|
|
1444
|
+
}
|
|
1445
|
+
function yesNoLabel(value) {
|
|
1446
|
+
return value ? t("cli.shared.yes") : t("cli.shared.no");
|
|
1447
|
+
}
|
|
1332
1448
|
function formatInitPathAction(path, action) {
|
|
1333
1449
|
return t("cli.init.created-path", { label: labelForInitWriteAction(action), path });
|
|
1334
1450
|
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
sync_meta_default
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-Q4LOVXML.js";
|
|
5
5
|
import {
|
|
6
6
|
human_lint_default
|
|
7
7
|
} from "./chunk-L43IGJ6X.js";
|
|
8
8
|
import {
|
|
9
9
|
ledger_append_default
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-WWNXR34K.js";
|
|
10
|
+
} from "./chunk-N7EZORJZ.js";
|
|
12
11
|
import {
|
|
13
12
|
resolveDevModeTarget
|
|
14
13
|
} from "./chunk-AEOYCVBG.js";
|
|
14
|
+
import "./chunk-WWNXR34K.js";
|
|
15
15
|
import {
|
|
16
16
|
t
|
|
17
17
|
} from "./chunk-6ICJICVU.js";
|
|
@@ -57,9 +57,9 @@ function tryReadAgentsMeta(target) {
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
function matchesFabricScope(stagedFiles, meta) {
|
|
60
|
-
const scopeGlobs = Object.values(meta.nodes).filter((node) => node.file !== "AGENTS.md").map((node) => node.scope_glob);
|
|
60
|
+
const scopeGlobs = Object.values(meta.nodes).filter((node) => node.file !== ".fabric/bootstrap/README.md" && node.file !== "AGENTS.md").map((node) => node.scope_glob);
|
|
61
61
|
return stagedFiles.some(
|
|
62
|
-
(file) => file === "AGENTS.md" || file === ".fabric/agents.meta.json" || file === ".fabric/human-lock.json" || file === ".intent-ledger.jsonl" || scopeGlobs.some((pattern) => minimatch(file, pattern, { dot: true }))
|
|
62
|
+
(file) => file === ".fabric/bootstrap/README.md" || file === "AGENTS.md" || file === ".fabric/agents.meta.json" || file === ".fabric/human-lock.json" || file === ".intent-ledger.jsonl" || scopeGlobs.some((pattern) => minimatch(file, pattern, { dot: true }))
|
|
63
63
|
);
|
|
64
64
|
}
|
|
65
65
|
var pre_commit_default = defineCommand({
|
|
@@ -3,9 +3,9 @@ import {
|
|
|
3
3
|
createScanReport,
|
|
4
4
|
scanCommand,
|
|
5
5
|
scan_default
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-WWNXR34K.js";
|
|
6
|
+
} from "./chunk-AZRKMFRY.js";
|
|
8
7
|
import "./chunk-AEOYCVBG.js";
|
|
8
|
+
import "./chunk-WWNXR34K.js";
|
|
9
9
|
import "./chunk-6ICJICVU.js";
|
|
10
10
|
export {
|
|
11
11
|
createScanReport,
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
installMcpClients
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-XFSQM3LJ.js";
|
|
5
|
+
import "./chunk-VOQKQ6W2.js";
|
|
6
6
|
import {
|
|
7
7
|
installHooks
|
|
8
8
|
} from "./chunk-YDZJRLHL.js";
|
|
9
|
-
import {
|
|
10
|
-
paint
|
|
11
|
-
} from "./chunk-WWNXR34K.js";
|
|
12
9
|
import {
|
|
13
10
|
resolveDevModeTarget
|
|
14
11
|
} from "./chunk-AEOYCVBG.js";
|
|
12
|
+
import {
|
|
13
|
+
paint
|
|
14
|
+
} from "./chunk-WWNXR34K.js";
|
|
15
15
|
import {
|
|
16
16
|
t
|
|
17
17
|
} from "./chunk-6ICJICVU.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fenglimg/fabric-cli",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"fab": "dist/index.js",
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
"minimatch": "^10.0.1",
|
|
19
19
|
"picocolors": "^1.1.1",
|
|
20
20
|
"string-width": "^7.2.0",
|
|
21
|
-
"@fenglimg/fabric-
|
|
22
|
-
"@fenglimg/fabric-
|
|
21
|
+
"@fenglimg/fabric-shared": "1.3.1",
|
|
22
|
+
"@fenglimg/fabric-server": "1.3.1"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@types/iarna__toml": "^2.0.5",
|
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
# { projectName } — Fabric Bootstrap Protocol
|
|
2
|
-
|
|
3
|
-
## CORE RULES (DO NOT TRANSLATE)
|
|
4
|
-
|
|
5
|
-
MUST: Treat this file as the Fabric Protocol bootstrap for this repository.
|
|
6
|
-
MUST: Treat `.fabric/agents/` as the authoritative home for all AI shadow constraints.
|
|
7
|
-
MUST: Before ANY code reading, architecture planning, or logic modification, call `fab_get_rules(path=<target file>)`.
|
|
8
|
-
MUST: When creating or changing an L1/L2 rule node, keep `.fabric/agents.meta.json` synchronized through Fabric tooling.
|
|
9
|
-
MUST: Preserve protected tokens exactly: `AGENTS.md`, `.fabric/agents/`, `.fabric/agents.meta.json`, `fab_get_rules`, `shadow constraints`, `Shadow Mirroring`, `MUST`, `NEVER`.
|
|
10
|
-
NEVER: Add import-style directive lines to this bootstrap file.
|
|
11
|
-
NEVER: Put framework, domain, repository rule bodies, or submodule rules in this file.
|
|
12
|
-
NEVER: Create colocated `AGENTS.md` rule files under source directories.
|
|
13
|
-
|
|
1
|
+
# { projectName } — Fabric Bootstrap Protocol
|
|
2
|
+
|
|
3
|
+
## CORE RULES (DO NOT TRANSLATE)
|
|
4
|
+
|
|
5
|
+
MUST: Treat this file as the Fabric Protocol bootstrap for this repository.
|
|
6
|
+
MUST: Treat `.fabric/agents/` as the authoritative home for all AI shadow constraints.
|
|
7
|
+
MUST: Before ANY code reading, architecture planning, or logic modification, call `fab_get_rules(path=<target file>)`.
|
|
8
|
+
MUST: When creating or changing an L1/L2 rule node, keep `.fabric/agents.meta.json` synchronized through Fabric tooling.
|
|
9
|
+
MUST: Preserve protected tokens exactly: `AGENTS.md`, `.fabric/agents/`, `.fabric/agents.meta.json`, `fab_get_rules`, `shadow constraints`, `Shadow Mirroring`, `MUST`, `NEVER`.
|
|
10
|
+
NEVER: Add import-style directive lines to this bootstrap file.
|
|
11
|
+
NEVER: Put framework, domain, repository rule bodies, or submodule rules in this file.
|
|
12
|
+
NEVER: Create colocated `AGENTS.md` rule files under source directories.
|
|
13
|
+
|
|
14
14
|
## 使用说明 / Explanation
|
|
15
15
|
|
|
16
16
|
- 本文件只负责启动 Fabric Bootstrap Protocol,不承载项目业务规则。
|
|
17
|
+
- 详细 bootstrap 说明位于 `.fabric/bootstrap/README.md`。
|
|
17
18
|
- Detected framework kind: `{ frameworkKind }`.
|
|
18
19
|
- This repository uses `Shadow Mirroring`: source directories contain ZERO rule files, while `.fabric/agents/` mirrors source paths for AI constraints.
|
|
19
20
|
- 根级规则应放在 `.fabric/agents/root.md`;跨领域规则应放在 `.fabric/agents/_cross/`。
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
# { projectName } — Fabric Bootstrap Protocol
|
|
2
|
-
|
|
3
|
-
## CORE RULES (DO NOT TRANSLATE)
|
|
4
|
-
|
|
5
|
-
MUST: Treat this file as the Fabric Protocol bootstrap for this repository.
|
|
6
|
-
MUST: Treat `.fabric/agents/` as the authoritative home for all AI shadow constraints.
|
|
7
|
-
MUST: Before ANY code reading, architecture planning, or logic modification, call `fab_get_rules(path=<target file>)`.
|
|
8
|
-
MUST: When creating or changing an L1/L2 rule node, keep `.fabric/agents.meta.json` synchronized through Fabric tooling.
|
|
9
|
-
MUST: Preserve protected tokens exactly: `AGENTS.md`, `.fabric/agents/`, `.fabric/agents.meta.json`, `fab_get_rules`, `shadow constraints`, `Shadow Mirroring`, `MUST`, `NEVER`.
|
|
10
|
-
NEVER: Add import-style directive lines to this bootstrap file.
|
|
11
|
-
NEVER: Put Cocos, asset, prefab, scene, repository rule bodies, or submodule rules in this file.
|
|
12
|
-
NEVER: Create colocated `AGENTS.md` rule files under source directories.
|
|
13
|
-
|
|
14
|
-
## 使用说明 / Explanation
|
|
15
|
-
|
|
16
|
-
- 本文件只负责启动 Fabric Bootstrap Protocol,不承载 Cocos 业务或编辑器规则。
|
|
17
|
-
- Detected framework kind: `cocos-creator`.
|
|
18
|
-
- This repository uses `Shadow Mirroring`: source directories contain ZERO rule files, while `.fabric/agents/` mirrors source paths for AI constraints.
|
|
19
|
-
- 根级规则应放在 `.fabric/agents/root.md`;跨领域规则应放在 `.fabric/agents/_cross/`。
|
|
20
|
-
- If `.fabric/agents/root.md` is missing, stop normal coding and run the initialization flow that creates shadow constraints.
|
|
1
|
+
# { projectName } — Fabric Bootstrap Protocol
|
|
2
|
+
|
|
3
|
+
## CORE RULES (DO NOT TRANSLATE)
|
|
4
|
+
|
|
5
|
+
MUST: Treat this file as the Fabric Protocol bootstrap for this repository.
|
|
6
|
+
MUST: Treat `.fabric/agents/` as the authoritative home for all AI shadow constraints.
|
|
7
|
+
MUST: Before ANY code reading, architecture planning, or logic modification, call `fab_get_rules(path=<target file>)`.
|
|
8
|
+
MUST: When creating or changing an L1/L2 rule node, keep `.fabric/agents.meta.json` synchronized through Fabric tooling.
|
|
9
|
+
MUST: Preserve protected tokens exactly: `AGENTS.md`, `.fabric/agents/`, `.fabric/agents.meta.json`, `fab_get_rules`, `shadow constraints`, `Shadow Mirroring`, `MUST`, `NEVER`.
|
|
10
|
+
NEVER: Add import-style directive lines to this bootstrap file.
|
|
11
|
+
NEVER: Put Cocos, asset, prefab, scene, repository rule bodies, or submodule rules in this file.
|
|
12
|
+
NEVER: Create colocated `AGENTS.md` rule files under source directories.
|
|
13
|
+
|
|
14
|
+
## 使用说明 / Explanation
|
|
15
|
+
|
|
16
|
+
- 本文件只负责启动 Fabric Bootstrap Protocol,不承载 Cocos 业务或编辑器规则。
|
|
17
|
+
- Detected framework kind: `cocos-creator`.
|
|
18
|
+
- This repository uses `Shadow Mirroring`: source directories contain ZERO rule files, while `.fabric/agents/` mirrors source paths for AI constraints.
|
|
19
|
+
- 根级规则应放在 `.fabric/agents/root.md`;跨领域规则应放在 `.fabric/agents/_cross/`。
|
|
20
|
+
- If `.fabric/agents/root.md` is missing, stop normal coding and run the initialization flow that creates shadow constraints.
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
# { projectName } — Fabric Bootstrap Protocol
|
|
2
|
-
|
|
3
|
-
## CORE RULES (DO NOT TRANSLATE)
|
|
4
|
-
|
|
5
|
-
MUST: Treat this file as the Fabric Protocol bootstrap for this repository.
|
|
6
|
-
MUST: Treat `.fabric/agents/` as the authoritative home for all AI shadow constraints.
|
|
7
|
-
MUST: Before ANY code reading, architecture planning, or logic modification, call `fab_get_rules(path=<target file>)`.
|
|
8
|
-
MUST: When creating or changing an L1/L2 rule node, keep `.fabric/agents.meta.json` synchronized through Fabric tooling.
|
|
9
|
-
MUST: Preserve protected tokens exactly: `AGENTS.md`, `.fabric/agents/`, `.fabric/agents.meta.json`, `fab_get_rules`, `shadow constraints`, `Shadow Mirroring`, `MUST`, `NEVER`.
|
|
10
|
-
NEVER: Add import-style directive lines to this bootstrap file.
|
|
11
|
-
NEVER: Put Next.js, route, repository rule bodies, or submodule rules in this file.
|
|
12
|
-
NEVER: Create colocated `AGENTS.md` rule files under source directories.
|
|
13
|
-
|
|
14
|
-
## 使用说明 / Explanation
|
|
15
|
-
|
|
16
|
-
- 本文件只负责启动 Fabric Bootstrap Protocol,不承载 Next.js 业务或路由规则。
|
|
17
|
-
- Detected framework kind: `next`.
|
|
18
|
-
- This repository uses `Shadow Mirroring`: source directories contain ZERO rule files, while `.fabric/agents/` mirrors source paths for AI constraints.
|
|
19
|
-
- 根级规则应放在 `.fabric/agents/root.md`;跨领域规则应放在 `.fabric/agents/_cross/`。
|
|
20
|
-
- If `.fabric/agents/root.md` is missing, stop normal coding and run the initialization flow that creates shadow constraints.
|
|
1
|
+
# { projectName } — Fabric Bootstrap Protocol
|
|
2
|
+
|
|
3
|
+
## CORE RULES (DO NOT TRANSLATE)
|
|
4
|
+
|
|
5
|
+
MUST: Treat this file as the Fabric Protocol bootstrap for this repository.
|
|
6
|
+
MUST: Treat `.fabric/agents/` as the authoritative home for all AI shadow constraints.
|
|
7
|
+
MUST: Before ANY code reading, architecture planning, or logic modification, call `fab_get_rules(path=<target file>)`.
|
|
8
|
+
MUST: When creating or changing an L1/L2 rule node, keep `.fabric/agents.meta.json` synchronized through Fabric tooling.
|
|
9
|
+
MUST: Preserve protected tokens exactly: `AGENTS.md`, `.fabric/agents/`, `.fabric/agents.meta.json`, `fab_get_rules`, `shadow constraints`, `Shadow Mirroring`, `MUST`, `NEVER`.
|
|
10
|
+
NEVER: Add import-style directive lines to this bootstrap file.
|
|
11
|
+
NEVER: Put Next.js, route, repository rule bodies, or submodule rules in this file.
|
|
12
|
+
NEVER: Create colocated `AGENTS.md` rule files under source directories.
|
|
13
|
+
|
|
14
|
+
## 使用说明 / Explanation
|
|
15
|
+
|
|
16
|
+
- 本文件只负责启动 Fabric Bootstrap Protocol,不承载 Next.js 业务或路由规则。
|
|
17
|
+
- Detected framework kind: `next`.
|
|
18
|
+
- This repository uses `Shadow Mirroring`: source directories contain ZERO rule files, while `.fabric/agents/` mirrors source paths for AI constraints.
|
|
19
|
+
- 根级规则应放在 `.fabric/agents/root.md`;跨领域规则应放在 `.fabric/agents/_cross/`。
|
|
20
|
+
- If `.fabric/agents/root.md` is missing, stop normal coding and run the initialization flow that creates shadow constraints.
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
# { projectName } — Fabric Bootstrap Protocol
|
|
2
|
-
|
|
3
|
-
## CORE RULES (DO NOT TRANSLATE)
|
|
4
|
-
|
|
5
|
-
MUST: Treat this file as the Fabric Protocol bootstrap for this repository.
|
|
6
|
-
MUST: Treat `.fabric/agents/` as the authoritative home for all AI shadow constraints.
|
|
7
|
-
MUST: Before ANY code reading, architecture planning, or logic modification, call `fab_get_rules(path=<target file>)`.
|
|
8
|
-
MUST: When creating or changing an L1/L2 rule node, keep `.fabric/agents.meta.json` synchronized through Fabric tooling.
|
|
9
|
-
MUST: Preserve protected tokens exactly: `AGENTS.md`, `.fabric/agents/`, `.fabric/agents.meta.json`, `fab_get_rules`, `shadow constraints`, `Shadow Mirroring`, `MUST`, `NEVER`.
|
|
10
|
-
NEVER: Add import-style directive lines to this bootstrap file.
|
|
11
|
-
NEVER: Put Vite, browser, repository rule bodies, or submodule rules in this file.
|
|
12
|
-
NEVER: Create colocated `AGENTS.md` rule files under source directories.
|
|
13
|
-
|
|
14
|
-
## 使用说明 / Explanation
|
|
15
|
-
|
|
16
|
-
- 本文件只负责启动 Fabric Bootstrap Protocol,不承载 Vite 业务或浏览器规则。
|
|
17
|
-
- Detected framework kind: `vite`.
|
|
18
|
-
- This repository uses `Shadow Mirroring`: source directories contain ZERO rule files, while `.fabric/agents/` mirrors source paths for AI constraints.
|
|
19
|
-
- 根级规则应放在 `.fabric/agents/root.md`;跨领域规则应放在 `.fabric/agents/_cross/`。
|
|
20
|
-
- If `.fabric/agents/root.md` is missing, stop normal coding and run the initialization flow that creates shadow constraints.
|
|
1
|
+
# { projectName } — Fabric Bootstrap Protocol
|
|
2
|
+
|
|
3
|
+
## CORE RULES (DO NOT TRANSLATE)
|
|
4
|
+
|
|
5
|
+
MUST: Treat this file as the Fabric Protocol bootstrap for this repository.
|
|
6
|
+
MUST: Treat `.fabric/agents/` as the authoritative home for all AI shadow constraints.
|
|
7
|
+
MUST: Before ANY code reading, architecture planning, or logic modification, call `fab_get_rules(path=<target file>)`.
|
|
8
|
+
MUST: When creating or changing an L1/L2 rule node, keep `.fabric/agents.meta.json` synchronized through Fabric tooling.
|
|
9
|
+
MUST: Preserve protected tokens exactly: `AGENTS.md`, `.fabric/agents/`, `.fabric/agents.meta.json`, `fab_get_rules`, `shadow constraints`, `Shadow Mirroring`, `MUST`, `NEVER`.
|
|
10
|
+
NEVER: Add import-style directive lines to this bootstrap file.
|
|
11
|
+
NEVER: Put Vite, browser, repository rule bodies, or submodule rules in this file.
|
|
12
|
+
NEVER: Create colocated `AGENTS.md` rule files under source directories.
|
|
13
|
+
|
|
14
|
+
## 使用说明 / Explanation
|
|
15
|
+
|
|
16
|
+
- 本文件只负责启动 Fabric Bootstrap Protocol,不承载 Vite 业务或浏览器规则。
|
|
17
|
+
- Detected framework kind: `vite`.
|
|
18
|
+
- This repository uses `Shadow Mirroring`: source directories contain ZERO rule files, while `.fabric/agents/` mirrors source paths for AI constraints.
|
|
19
|
+
- 根级规则应放在 `.fabric/agents/root.md`;跨领域规则应放在 `.fabric/agents/_cross/`。
|
|
20
|
+
- If `.fabric/agents/root.md` is missing, stop normal coding and run the initialization flow that creates shadow constraints.
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# Fabric Bootstrap
|
|
2
|
-
-
|
|
3
|
-
-
|
|
4
|
-
-
|
|
5
|
-
- 涉及 @HUMAN 段(`.fabric/human-lock.json` 中列出)时,必须停下来请示人类。
|
|
6
|
-
- 每次完整任务结束,调 `fab_append_intent` 写一条意图记录。
|
|
2
|
+
- 主说明文档已收敛到 `.fabric/bootstrap/README.md`。
|
|
3
|
+
- 项目级 bootstrap 入口仍然是 `AGENTS.md`。
|
|
4
|
+
- 修改任何文件前必须调用 `fab_get_rules(path=<被改文件>)`。
|
|
7
5
|
|
|
8
6
|
@AGENTS.md
|