@forge-ts/cli 0.16.0 → 0.18.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/{chunk-DV33Y4E2.js → chunk-JVI2NAXX.js} +106 -38
- package/dist/chunk-JVI2NAXX.js.map +1 -0
- package/dist/index.d.ts +11 -3
- package/dist/index.js +278 -57
- package/dist/index.js.map +1 -1
- package/dist/{init-project-5AWZ2LAI.js → init-project-6CWF4CCX.js} +2 -2
- package/package.json +6 -6
- package/dist/chunk-DV33Y4E2.js.map +0 -1
- /package/dist/{init-project-5AWZ2LAI.js.map → init-project-6CWF4CCX.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
addScripts,
|
|
3
4
|
initProjectCommand,
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
readPkgJson,
|
|
6
|
+
runInitProject,
|
|
7
|
+
writePkgJson
|
|
8
|
+
} from "./chunk-JVI2NAXX.js";
|
|
6
9
|
import {
|
|
7
10
|
configureLogger,
|
|
8
11
|
forgeLogger
|
|
@@ -473,9 +476,22 @@ var bypassCommand = defineCommand3({
|
|
|
473
476
|
});
|
|
474
477
|
|
|
475
478
|
// src/commands/check.ts
|
|
479
|
+
import { execSync } from "child_process";
|
|
476
480
|
import { loadConfig as loadConfig3 } from "@forge-ts/core";
|
|
477
481
|
import { enforce } from "@forge-ts/enforcer";
|
|
478
482
|
import { defineCommand as defineCommand4 } from "citty";
|
|
483
|
+
function getStagedFiles(cwd) {
|
|
484
|
+
try {
|
|
485
|
+
const output = execSync("git diff --cached --name-only --diff-filter=d", {
|
|
486
|
+
cwd,
|
|
487
|
+
encoding: "utf8",
|
|
488
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
489
|
+
});
|
|
490
|
+
return output.split("\n").map((f) => f.trim()).filter((f) => f.length > 0 && (f.endsWith(".ts") || f.endsWith(".tsx")));
|
|
491
|
+
} catch {
|
|
492
|
+
return null;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
479
495
|
var RULE_NAMES = {
|
|
480
496
|
E001: "require-summary",
|
|
481
497
|
E002: "require-param",
|
|
@@ -634,27 +650,66 @@ async function runCheck(args) {
|
|
|
634
650
|
if (args.strict !== void 0) {
|
|
635
651
|
config.enforce.strict = args.strict;
|
|
636
652
|
}
|
|
653
|
+
const fileFilter = args.file;
|
|
654
|
+
let stagedPaths;
|
|
655
|
+
if (args.staged) {
|
|
656
|
+
const rootDir = config.rootDir;
|
|
657
|
+
const staged = getStagedFiles(rootDir);
|
|
658
|
+
if (staged !== null && staged.length > 0) {
|
|
659
|
+
stagedPaths = staged;
|
|
660
|
+
} else {
|
|
661
|
+
const data2 = {
|
|
662
|
+
success: true,
|
|
663
|
+
summary: { errors: 0, warnings: 0, files: 0, symbols: 0, duration: 0 }
|
|
664
|
+
};
|
|
665
|
+
return { operation: "check", success: true, data: data2, duration: 0 };
|
|
666
|
+
}
|
|
667
|
+
}
|
|
637
668
|
const result = await enforce(config);
|
|
638
669
|
const mviLevel = args.mvi ?? "standard";
|
|
639
670
|
const limit = args.limit ?? 20;
|
|
640
671
|
const offset = args.offset ?? 0;
|
|
641
|
-
const filters = { rule: args.rule, file:
|
|
672
|
+
const filters = { rule: args.rule, file: fileFilter };
|
|
673
|
+
const CROSS_FILE_RULES = /* @__PURE__ */ new Set([
|
|
674
|
+
"E005",
|
|
675
|
+
"E008",
|
|
676
|
+
"E009",
|
|
677
|
+
"E010",
|
|
678
|
+
"E011",
|
|
679
|
+
"E012",
|
|
680
|
+
"W007",
|
|
681
|
+
"W008",
|
|
682
|
+
"W009"
|
|
683
|
+
]);
|
|
684
|
+
let filteredErrors = result.errors;
|
|
685
|
+
let filteredWarnings = result.warnings;
|
|
686
|
+
if (stagedPaths && stagedPaths.length > 0) {
|
|
687
|
+
const stagedSet = new Set(stagedPaths);
|
|
688
|
+
const matchesStaged = (filePath) => stagedPaths?.some((sp) => filePath.endsWith(sp)) ?? false;
|
|
689
|
+
filteredErrors = result.errors.filter(
|
|
690
|
+
(e) => CROSS_FILE_RULES.has(e.code) || stagedSet.has(e.filePath) || matchesStaged(e.filePath)
|
|
691
|
+
);
|
|
692
|
+
filteredWarnings = result.warnings.filter(
|
|
693
|
+
(w) => CROSS_FILE_RULES.has(w.code) || stagedSet.has(w.filePath) || matchesStaged(w.filePath)
|
|
694
|
+
);
|
|
695
|
+
}
|
|
642
696
|
const exportedSymbolCount = result.symbols.filter((s) => s.exported).length;
|
|
643
697
|
const data = buildCheckResult(
|
|
644
|
-
|
|
645
|
-
|
|
698
|
+
filteredErrors,
|
|
699
|
+
filteredWarnings,
|
|
646
700
|
exportedSymbolCount,
|
|
647
701
|
result.duration,
|
|
648
|
-
|
|
702
|
+
filteredErrors.length === 0,
|
|
649
703
|
mviLevel,
|
|
650
704
|
filters,
|
|
651
705
|
limit,
|
|
652
706
|
offset
|
|
653
707
|
);
|
|
654
|
-
const
|
|
708
|
+
const checkSuccess = filteredErrors.length === 0;
|
|
709
|
+
const cliErrors = checkSuccess ? void 0 : [
|
|
655
710
|
{
|
|
656
711
|
code: "FORGE_CHECK_FAILED",
|
|
657
|
-
message: `TSDoc coverage check failed: ${
|
|
712
|
+
message: `TSDoc coverage check failed: ${filteredErrors.length} error(s), ${filteredWarnings.length} warning(s) across ${data.summary.files} file(s)`
|
|
658
713
|
}
|
|
659
714
|
];
|
|
660
715
|
const cliWarnings = config._configWarnings?.map((msg) => ({
|
|
@@ -666,7 +721,7 @@ async function runCheck(args) {
|
|
|
666
721
|
}));
|
|
667
722
|
return {
|
|
668
723
|
operation: "check",
|
|
669
|
-
success:
|
|
724
|
+
success: checkSuccess,
|
|
670
725
|
data,
|
|
671
726
|
errors: cliErrors,
|
|
672
727
|
warnings: cliWarnings,
|
|
@@ -769,6 +824,11 @@ var checkCommand = defineCommand4({
|
|
|
769
824
|
type: "string",
|
|
770
825
|
description: "Filter by file path (substring match)"
|
|
771
826
|
},
|
|
827
|
+
staged: {
|
|
828
|
+
type: "boolean",
|
|
829
|
+
description: "Only check symbols from git-staged .ts/.tsx files",
|
|
830
|
+
default: false
|
|
831
|
+
},
|
|
772
832
|
limit: {
|
|
773
833
|
type: "string",
|
|
774
834
|
description: "Max file groups in output (default: 20)"
|
|
@@ -805,6 +865,7 @@ var checkCommand = defineCommand4({
|
|
|
805
865
|
mvi: args.mvi,
|
|
806
866
|
rule: args.rule,
|
|
807
867
|
file: args.file,
|
|
868
|
+
staged: args.staged,
|
|
808
869
|
limit: args.limit ? parseInt(args.limit, 10) : void 0,
|
|
809
870
|
offset: args.offset ? parseInt(args.offset, 10) : void 0
|
|
810
871
|
});
|
|
@@ -880,6 +941,7 @@ var docsDevCommand = defineCommand5({
|
|
|
880
941
|
});
|
|
881
942
|
|
|
882
943
|
// src/commands/doctor.ts
|
|
944
|
+
import { execSync as execSync2 } from "child_process";
|
|
883
945
|
import { existsSync, readFileSync } from "fs";
|
|
884
946
|
import { mkdir, writeFile } from "fs/promises";
|
|
885
947
|
import { join } from "path";
|
|
@@ -899,18 +961,8 @@ var DEFAULT_CONFIG_CONTENT = `import { defineConfig } from "@forge-ts/core";
|
|
|
899
961
|
|
|
900
962
|
export default defineConfig({
|
|
901
963
|
rootDir: ".",
|
|
902
|
-
tsconfig: "tsconfig.json",
|
|
903
964
|
outDir: "docs/generated",
|
|
904
|
-
enforce: {
|
|
905
|
-
enabled: true,
|
|
906
|
-
minVisibility: "public",
|
|
907
|
-
strict: false,
|
|
908
|
-
},
|
|
909
965
|
gen: {
|
|
910
|
-
enabled: true,
|
|
911
|
-
formats: ["mdx"],
|
|
912
|
-
llmsTxt: true,
|
|
913
|
-
readmeSync: false,
|
|
914
966
|
ssgTarget: "mintlify",
|
|
915
967
|
},
|
|
916
968
|
});
|
|
@@ -1193,43 +1245,136 @@ async function runDoctor(args) {
|
|
|
1193
1245
|
});
|
|
1194
1246
|
}
|
|
1195
1247
|
const huskyPreCommit = join(rootDir, ".husky", "pre-commit");
|
|
1248
|
+
const huskyPrePush = join(rootDir, ".husky", "pre-push");
|
|
1196
1249
|
const lefthookYml = join(rootDir, "lefthook.yml");
|
|
1197
|
-
let
|
|
1198
|
-
let
|
|
1250
|
+
let hookManagerType = "none";
|
|
1251
|
+
let preCommitConfigured = false;
|
|
1252
|
+
let prePushConfigured = false;
|
|
1199
1253
|
if (existsSync(huskyPreCommit)) {
|
|
1254
|
+
hookManagerType = "husky";
|
|
1200
1255
|
try {
|
|
1201
1256
|
const content = readFileSync(huskyPreCommit, "utf8");
|
|
1202
1257
|
if (content.includes("forge-ts check")) {
|
|
1203
|
-
|
|
1204
|
-
|
|
1258
|
+
preCommitConfigured = true;
|
|
1259
|
+
}
|
|
1260
|
+
} catch {
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
if (hookManagerType === "husky" && existsSync(huskyPrePush)) {
|
|
1264
|
+
try {
|
|
1265
|
+
const content = readFileSync(huskyPrePush, "utf8");
|
|
1266
|
+
if (content.includes("forge-ts prepublish")) {
|
|
1267
|
+
prePushConfigured = true;
|
|
1205
1268
|
}
|
|
1206
1269
|
} catch {
|
|
1207
1270
|
}
|
|
1208
1271
|
}
|
|
1209
|
-
if (
|
|
1272
|
+
if (hookManagerType === "none" && existsSync(lefthookYml)) {
|
|
1273
|
+
hookManagerType = "lefthook";
|
|
1210
1274
|
try {
|
|
1211
1275
|
const content = readFileSync(lefthookYml, "utf8");
|
|
1212
1276
|
if (content.includes("forge-ts check")) {
|
|
1213
|
-
|
|
1214
|
-
|
|
1277
|
+
preCommitConfigured = true;
|
|
1278
|
+
}
|
|
1279
|
+
if (content.includes("forge-ts prepublish")) {
|
|
1280
|
+
prePushConfigured = true;
|
|
1215
1281
|
}
|
|
1216
1282
|
} catch {
|
|
1217
1283
|
}
|
|
1218
1284
|
}
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1285
|
+
let huskyInstalled = false;
|
|
1286
|
+
if (hookManagerType === "husky" || hookManagerType === "none") {
|
|
1287
|
+
const huskyBin = join(rootDir, "node_modules", ".bin", "husky");
|
|
1288
|
+
if (existsSync(huskyBin)) {
|
|
1289
|
+
huskyInstalled = true;
|
|
1290
|
+
} else {
|
|
1291
|
+
const pkgPathHooks = join(rootDir, "package.json");
|
|
1292
|
+
const hooksPkg = readJsonSafe(pkgPathHooks);
|
|
1293
|
+
if (hooksPkg) {
|
|
1294
|
+
const allDeps = { ...hooksPkg.dependencies, ...hooksPkg.devDependencies };
|
|
1295
|
+
if ("husky" in allDeps) {
|
|
1296
|
+
huskyInstalled = true;
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
let prepareScriptExists = false;
|
|
1302
|
+
{
|
|
1303
|
+
const pkgPathPrep = join(rootDir, "package.json");
|
|
1304
|
+
const prepPkg = readJsonSafe(pkgPathPrep);
|
|
1305
|
+
if (prepPkg?.scripts?.prepare) {
|
|
1306
|
+
prepareScriptExists = true;
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
if (hookManagerType === "husky") {
|
|
1310
|
+
try {
|
|
1311
|
+
execSync2("git config core.hooksPath", {
|
|
1312
|
+
cwd: rootDir,
|
|
1313
|
+
encoding: "utf8",
|
|
1314
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
1315
|
+
});
|
|
1316
|
+
} catch {
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
if (hookManagerType === "none" && !preCommitConfigured && !prePushConfigured) {
|
|
1227
1320
|
checks.push({
|
|
1228
1321
|
name: "Git hooks",
|
|
1229
1322
|
status: "warn",
|
|
1230
|
-
message: "Git hooks \u2014
|
|
1323
|
+
message: "Git hooks \u2014 no hook manager detected (run forge-ts init hooks)",
|
|
1231
1324
|
fixable: false
|
|
1232
1325
|
});
|
|
1326
|
+
} else if (hookManagerType === "husky") {
|
|
1327
|
+
if (!huskyInstalled) {
|
|
1328
|
+
checks.push({
|
|
1329
|
+
name: "Git hooks (husky)",
|
|
1330
|
+
status: "warn",
|
|
1331
|
+
message: "Git hooks \u2014 hook files exist but husky is not installed (run: npm install -D husky)",
|
|
1332
|
+
fixable: false
|
|
1333
|
+
});
|
|
1334
|
+
} else if (!prepareScriptExists) {
|
|
1335
|
+
checks.push({
|
|
1336
|
+
name: "Git hooks (husky)",
|
|
1337
|
+
status: "warn",
|
|
1338
|
+
message: 'Git hooks \u2014 husky installed but "prepare" script missing in package.json',
|
|
1339
|
+
fixable: false
|
|
1340
|
+
});
|
|
1341
|
+
} else if (preCommitConfigured && prePushConfigured) {
|
|
1342
|
+
checks.push({
|
|
1343
|
+
name: "Git hooks (husky)",
|
|
1344
|
+
status: "pass",
|
|
1345
|
+
message: "Git hooks \u2014 husky installed, prepare script wired, pre-commit and pre-push configured",
|
|
1346
|
+
fixable: false
|
|
1347
|
+
});
|
|
1348
|
+
} else {
|
|
1349
|
+
const missing = [];
|
|
1350
|
+
if (!preCommitConfigured) missing.push("pre-commit (forge-ts check)");
|
|
1351
|
+
if (!prePushConfigured) missing.push("pre-push (forge-ts prepublish)");
|
|
1352
|
+
checks.push({
|
|
1353
|
+
name: "Git hooks (husky)",
|
|
1354
|
+
status: "warn",
|
|
1355
|
+
message: `Git hooks \u2014 husky installed but missing: ${missing.join(", ")}`,
|
|
1356
|
+
fixable: false
|
|
1357
|
+
});
|
|
1358
|
+
}
|
|
1359
|
+
} else if (hookManagerType === "lefthook") {
|
|
1360
|
+
if (preCommitConfigured && prePushConfigured) {
|
|
1361
|
+
checks.push({
|
|
1362
|
+
name: "Git hooks (lefthook)",
|
|
1363
|
+
status: "pass",
|
|
1364
|
+
message: "Git hooks \u2014 lefthook pre-commit and pre-push configured",
|
|
1365
|
+
fixable: false
|
|
1366
|
+
});
|
|
1367
|
+
} else {
|
|
1368
|
+
const missing = [];
|
|
1369
|
+
if (!preCommitConfigured) missing.push("pre-commit (forge-ts check)");
|
|
1370
|
+
if (!prePushConfigured) missing.push("pre-push (forge-ts prepublish)");
|
|
1371
|
+
checks.push({
|
|
1372
|
+
name: "Git hooks (lefthook)",
|
|
1373
|
+
status: "warn",
|
|
1374
|
+
message: `Git hooks \u2014 lefthook detected but missing: ${missing.join(", ")}`,
|
|
1375
|
+
fixable: false
|
|
1376
|
+
});
|
|
1377
|
+
}
|
|
1233
1378
|
}
|
|
1234
1379
|
const summary = {
|
|
1235
1380
|
passed: checks.filter((c) => c.status === "pass").length,
|
|
@@ -1607,15 +1752,19 @@ function detectHookManager(rootDir) {
|
|
|
1607
1752
|
}
|
|
1608
1753
|
return "none";
|
|
1609
1754
|
}
|
|
1610
|
-
var HUSKY_PRE_COMMIT =
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
npx forge-ts check
|
|
1755
|
+
var HUSKY_PRE_COMMIT = `npx forge-ts check
|
|
1756
|
+
`;
|
|
1757
|
+
var HUSKY_PRE_PUSH = `npx forge-ts prepublish
|
|
1614
1758
|
`;
|
|
1615
1759
|
var LEFTHOOK_BLOCK = `pre-commit:
|
|
1616
1760
|
commands:
|
|
1617
1761
|
forge-ts-check:
|
|
1618
1762
|
run: npx forge-ts check
|
|
1763
|
+
|
|
1764
|
+
pre-push:
|
|
1765
|
+
commands:
|
|
1766
|
+
forge-ts-prepublish:
|
|
1767
|
+
run: npx forge-ts prepublish
|
|
1619
1768
|
`;
|
|
1620
1769
|
async function runInitHooks(args) {
|
|
1621
1770
|
const start = Date.now();
|
|
@@ -1626,54 +1775,125 @@ async function runInitHooks(args) {
|
|
|
1626
1775
|
const warnings = [];
|
|
1627
1776
|
const instructions = [];
|
|
1628
1777
|
if (hookManager === "husky" || hookManager === "none") {
|
|
1778
|
+
const huskyBin = join3(rootDir, "node_modules", ".bin", "husky");
|
|
1779
|
+
const pkg2 = readPkgJson(rootDir);
|
|
1780
|
+
const huskyInDeps = pkg2 !== null && ("husky" in (pkg2.obj.devDependencies ?? {}) || "husky" in (pkg2.obj.dependencies ?? {}));
|
|
1781
|
+
const huskyInstalled = existsSync3(huskyBin) || huskyInDeps;
|
|
1782
|
+
if (!huskyInstalled) {
|
|
1783
|
+
warnings.push({
|
|
1784
|
+
code: "HOOKS_HUSKY_NOT_INSTALLED",
|
|
1785
|
+
message: "husky not installed. Run: npm install -D husky"
|
|
1786
|
+
});
|
|
1787
|
+
instructions.push("husky is not installed. Run: npm install -D husky (or pnpm add -D husky)");
|
|
1788
|
+
}
|
|
1629
1789
|
const huskyDir = join3(rootDir, ".husky");
|
|
1630
|
-
const
|
|
1631
|
-
const
|
|
1632
|
-
if (existsSync3(
|
|
1633
|
-
const existing = await readFile(
|
|
1790
|
+
const preCommitPath = join3(huskyDir, "pre-commit");
|
|
1791
|
+
const preCommitRel = ".husky/pre-commit";
|
|
1792
|
+
if (existsSync3(preCommitPath) && !args.force) {
|
|
1793
|
+
const existing = await readFile(preCommitPath, "utf8");
|
|
1634
1794
|
if (existing.includes("forge-ts check")) {
|
|
1635
|
-
skippedFiles.push(
|
|
1795
|
+
skippedFiles.push(preCommitRel);
|
|
1636
1796
|
warnings.push({
|
|
1637
1797
|
code: "HOOKS_ALREADY_EXISTS",
|
|
1638
|
-
message: `${
|
|
1798
|
+
message: `${preCommitRel} already contains forge-ts check \u2014 skipping. Use --force to overwrite.`
|
|
1639
1799
|
});
|
|
1640
1800
|
} else {
|
|
1641
1801
|
const appended = `${existing.trimEnd()}
|
|
1642
1802
|
|
|
1643
1803
|
npx forge-ts check
|
|
1644
1804
|
`;
|
|
1645
|
-
await writeFile3(
|
|
1646
|
-
writtenFiles.push(
|
|
1805
|
+
await writeFile3(preCommitPath, appended, { mode: 493 });
|
|
1806
|
+
writtenFiles.push(preCommitRel);
|
|
1647
1807
|
}
|
|
1648
1808
|
} else {
|
|
1649
1809
|
await mkdir3(huskyDir, { recursive: true });
|
|
1650
|
-
await writeFile3(
|
|
1651
|
-
writtenFiles.push(
|
|
1810
|
+
await writeFile3(preCommitPath, HUSKY_PRE_COMMIT, { mode: 493 });
|
|
1811
|
+
writtenFiles.push(preCommitRel);
|
|
1812
|
+
}
|
|
1813
|
+
const prePushPath = join3(huskyDir, "pre-push");
|
|
1814
|
+
const prePushRel = ".husky/pre-push";
|
|
1815
|
+
if (existsSync3(prePushPath) && !args.force) {
|
|
1816
|
+
const existing = await readFile(prePushPath, "utf8");
|
|
1817
|
+
if (existing.includes("forge-ts prepublish")) {
|
|
1818
|
+
skippedFiles.push(prePushRel);
|
|
1819
|
+
warnings.push({
|
|
1820
|
+
code: "HOOKS_ALREADY_EXISTS",
|
|
1821
|
+
message: `${prePushRel} already contains forge-ts prepublish \u2014 skipping. Use --force to overwrite.`
|
|
1822
|
+
});
|
|
1823
|
+
} else {
|
|
1824
|
+
const appended = `${existing.trimEnd()}
|
|
1825
|
+
|
|
1826
|
+
npx forge-ts prepublish
|
|
1827
|
+
`;
|
|
1828
|
+
await writeFile3(prePushPath, appended, { mode: 493 });
|
|
1829
|
+
writtenFiles.push(prePushRel);
|
|
1830
|
+
}
|
|
1831
|
+
} else {
|
|
1832
|
+
await mkdir3(huskyDir, { recursive: true });
|
|
1833
|
+
await writeFile3(prePushPath, HUSKY_PRE_PUSH, { mode: 493 });
|
|
1834
|
+
writtenFiles.push(prePushRel);
|
|
1835
|
+
}
|
|
1836
|
+
const pkgData = readPkgJson(rootDir);
|
|
1837
|
+
if (pkgData) {
|
|
1838
|
+
const added = addScripts(pkgData, { prepare: "husky" });
|
|
1839
|
+
if (added.length > 0) {
|
|
1840
|
+
await writePkgJson(pkgData);
|
|
1841
|
+
writtenFiles.push("package.json (prepare script)");
|
|
1842
|
+
instructions.push('Added "prepare": "husky" script to package.json.');
|
|
1843
|
+
} else {
|
|
1844
|
+
skippedFiles.push("package.json (prepare script already exists)");
|
|
1845
|
+
}
|
|
1652
1846
|
}
|
|
1653
1847
|
if (hookManager === "none") {
|
|
1654
1848
|
instructions.push(
|
|
1655
|
-
"No hook manager detected. Wrote .husky/pre-commit as a starting point.",
|
|
1656
|
-
"Install husky to activate:
|
|
1849
|
+
"No hook manager detected. Wrote .husky/pre-commit and .husky/pre-push as a starting point.",
|
|
1850
|
+
"Install husky to activate: npm install -D husky && npx husky (or pnpm add -D husky && pnpm exec husky)"
|
|
1657
1851
|
);
|
|
1658
1852
|
} else {
|
|
1659
1853
|
instructions.push("Husky pre-commit hook configured to run forge-ts check.");
|
|
1854
|
+
instructions.push("Husky pre-push hook configured to run forge-ts prepublish.");
|
|
1660
1855
|
}
|
|
1661
1856
|
} else if (hookManager === "lefthook") {
|
|
1662
1857
|
const lefthookPath = join3(rootDir, "lefthook.yml");
|
|
1663
1858
|
const relativePath = "lefthook.yml";
|
|
1664
1859
|
if (existsSync3(lefthookPath)) {
|
|
1665
1860
|
const existing = await readFile(lefthookPath, "utf8");
|
|
1666
|
-
|
|
1861
|
+
const hasCheck = existing.includes("forge-ts check");
|
|
1862
|
+
const hasPrepublish = existing.includes("forge-ts prepublish");
|
|
1863
|
+
if (hasCheck && hasPrepublish && !args.force) {
|
|
1667
1864
|
skippedFiles.push(relativePath);
|
|
1668
1865
|
warnings.push({
|
|
1669
1866
|
code: "HOOKS_ALREADY_EXISTS",
|
|
1670
|
-
message: `${relativePath} already contains forge-ts check \u2014 skipping. Use --force to overwrite.`
|
|
1867
|
+
message: `${relativePath} already contains forge-ts check and prepublish \u2014 skipping. Use --force to overwrite.`
|
|
1671
1868
|
});
|
|
1672
|
-
} else if (
|
|
1869
|
+
} else if (hasCheck && !hasPrepublish && !args.force) {
|
|
1870
|
+
const prePushBlock = `
|
|
1871
|
+
pre-push:
|
|
1872
|
+
commands:
|
|
1873
|
+
forge-ts-prepublish:
|
|
1874
|
+
run: npx forge-ts prepublish
|
|
1875
|
+
`;
|
|
1673
1876
|
const appended = `${existing.trimEnd()}
|
|
1674
|
-
|
|
1675
|
-
|
|
1877
|
+
${prePushBlock}`;
|
|
1878
|
+
await writeFile3(lefthookPath, appended, "utf8");
|
|
1879
|
+
writtenFiles.push(relativePath);
|
|
1880
|
+
} else if (existing.includes("pre-commit:") && !args.force) {
|
|
1881
|
+
let appended = existing.trimEnd();
|
|
1882
|
+
if (!hasCheck) {
|
|
1883
|
+
appended += "\n forge-ts-check:\n run: npx forge-ts check";
|
|
1884
|
+
}
|
|
1885
|
+
if (!existing.includes("pre-push:")) {
|
|
1886
|
+
appended += `
|
|
1887
|
+
|
|
1888
|
+
pre-push:
|
|
1889
|
+
commands:
|
|
1890
|
+
forge-ts-prepublish:
|
|
1891
|
+
run: npx forge-ts prepublish
|
|
1676
1892
|
`;
|
|
1893
|
+
} else if (!hasPrepublish) {
|
|
1894
|
+
appended += "\n forge-ts-prepublish:\n run: npx forge-ts prepublish";
|
|
1895
|
+
}
|
|
1896
|
+
appended += "\n";
|
|
1677
1897
|
await writeFile3(lefthookPath, appended, "utf8");
|
|
1678
1898
|
writtenFiles.push(relativePath);
|
|
1679
1899
|
} else {
|
|
@@ -1688,6 +1908,7 @@ ${LEFTHOOK_BLOCK}`;
|
|
|
1688
1908
|
writtenFiles.push(relativePath);
|
|
1689
1909
|
}
|
|
1690
1910
|
instructions.push("Lefthook pre-commit hook configured to run forge-ts check.");
|
|
1911
|
+
instructions.push("Lefthook pre-push hook configured to run forge-ts prepublish.");
|
|
1691
1912
|
}
|
|
1692
1913
|
const data = {
|
|
1693
1914
|
success: true,
|
|
@@ -2351,7 +2572,7 @@ var initCommand2 = defineCommand13({
|
|
|
2351
2572
|
if (hasSubCommand) {
|
|
2352
2573
|
return;
|
|
2353
2574
|
}
|
|
2354
|
-
const { runInitProject: runInitProject2 } = await import("./init-project-
|
|
2575
|
+
const { runInitProject: runInitProject2 } = await import("./init-project-6CWF4CCX.js");
|
|
2355
2576
|
const { emitResult: emitResult2, resolveExitCode: resolveExitCode2 } = await import("./output-OSCHMPOX.js");
|
|
2356
2577
|
const { forgeLogger: forgeLogger2 } = await import("./forge-logger-RTOBEKWH.js");
|
|
2357
2578
|
const output = await runInitProject2({
|