@git.zone/cli 6.0.0 → 6.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_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/helpers.workflow.d.ts +2 -0
- package/dist_ts/helpers.workflow.js +96 -25
- package/dist_ts/mod_config/index.js +176 -88
- package/dist_ts/mod_release/classes.releasejournal.d.ts +60 -10
- package/dist_ts/mod_release/classes.releasejournal.js +513 -21
- package/dist_ts/mod_release/helpers.npmartifact.js +4 -2
- package/dist_ts/mod_release/helpers.releasepublication.d.ts +5 -3
- package/dist_ts/mod_release/helpers.releasepublication.js +386 -13
- package/dist_ts/mod_release/helpers.tsdockerprotocol.d.ts +60 -0
- package/dist_ts/mod_release/helpers.tsdockerprotocol.js +442 -0
- package/dist_ts/mod_release/index.d.ts +1 -1
- package/dist_ts/mod_release/index.js +101 -19
- package/dist_ts/plugins.d.ts +5 -1
- package/dist_ts/plugins.js +5 -2
- package/package.json +2 -1
- package/readme.hints.md +43 -17
- package/readme.md +83 -75
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/helpers.workflow.ts +191 -49
- package/ts/mod_config/index.ts +320 -146
- package/ts/mod_release/classes.releasejournal.ts +939 -70
- package/ts/mod_release/helpers.npmartifact.ts +3 -1
- package/ts/mod_release/helpers.releasepublication.ts +780 -49
- package/ts/mod_release/helpers.tsdockerprotocol.ts +806 -0
- package/ts/mod_release/index.ts +231 -74
- package/ts/plugins.ts +20 -0
package/ts/mod_config/index.ts
CHANGED
|
@@ -19,13 +19,9 @@ import {
|
|
|
19
19
|
CURRENT_GITZONE_CLI_SCHEMA_VERSION,
|
|
20
20
|
migrateSmartconfigData,
|
|
21
21
|
} from "../helpers.smartconfigmigrations.js";
|
|
22
|
-
import {
|
|
23
|
-
formatTsdockerMinimumVersion,
|
|
24
|
-
getDeclaredTsdockerRange,
|
|
25
|
-
getTsdockerMinimumVersion,
|
|
26
|
-
supportsTsdockerMinimumVersion,
|
|
27
|
-
} from "../helpers.workflow.js";
|
|
22
|
+
import { getDeclaredTsdockerRange } from "../helpers.workflow.js";
|
|
28
23
|
import { hasInstalledProjectTsdockerBinary } from "../helpers.tsdocker.js";
|
|
24
|
+
import { TsdockerReleaseClient } from "../mod_release/helpers.tsdockerprotocol.js";
|
|
29
25
|
|
|
30
26
|
export { ReleaseConfig, CommitConfig };
|
|
31
27
|
|
|
@@ -269,7 +265,12 @@ async function handleShow(mode: ICliMode): Promise<void> {
|
|
|
269
265
|
["projectType", formatValue(cliConfig.projectType)],
|
|
270
266
|
["repository", formatRepository(cliConfig.module)],
|
|
271
267
|
["description", formatValue(cliConfig.module?.description)],
|
|
272
|
-
[
|
|
268
|
+
[
|
|
269
|
+
"npm package",
|
|
270
|
+
formatValue(
|
|
271
|
+
cliConfig.module?.npmPackagename || cliConfig.module?.npmPackageName,
|
|
272
|
+
),
|
|
273
|
+
],
|
|
273
274
|
["license", formatValue(cliConfig.module?.license)],
|
|
274
275
|
["keywords", formatList(cliConfig.module?.keywords)],
|
|
275
276
|
]);
|
|
@@ -309,12 +310,31 @@ async function handleShow(mode: ICliMode): Promise<void> {
|
|
|
309
310
|
const rawAssets = cliConfig.assets || {};
|
|
310
311
|
const assets = rawAssets.enabled === false ? {} : rawAssets;
|
|
311
312
|
printConfigSection("Managed Assets", [
|
|
312
|
-
[
|
|
313
|
+
[
|
|
314
|
+
"enabled",
|
|
315
|
+
formatValue(
|
|
316
|
+
rawAssets.enabled === false ? false : rawAssets.kind ? true : undefined,
|
|
317
|
+
),
|
|
318
|
+
],
|
|
313
319
|
["kind", formatValue(assets.kind)],
|
|
314
320
|
["cli name", formatValue(assets.cliName)],
|
|
315
|
-
[
|
|
321
|
+
[
|
|
322
|
+
"installer",
|
|
323
|
+
formatValue(
|
|
324
|
+
assets.installer?.enabled === false
|
|
325
|
+
? false
|
|
326
|
+
: assets.kind
|
|
327
|
+
? true
|
|
328
|
+
: undefined,
|
|
329
|
+
),
|
|
330
|
+
],
|
|
316
331
|
["npm wrapper", formatValue(assets.npmWrapper?.enabled)],
|
|
317
|
-
[
|
|
332
|
+
[
|
|
333
|
+
"release workflow",
|
|
334
|
+
formatValue(
|
|
335
|
+
assets.releaseWorkflow?.enabled ?? assets.releaseAssets?.enabled,
|
|
336
|
+
),
|
|
337
|
+
],
|
|
318
338
|
]);
|
|
319
339
|
|
|
320
340
|
console.log("Run `gitzone config doctor` to validate this configuration.");
|
|
@@ -379,7 +399,10 @@ async function handleRemove(
|
|
|
379
399
|
const registries = config.getRegistries();
|
|
380
400
|
|
|
381
401
|
if (registries.length === 0) {
|
|
382
|
-
plugins.logger.log(
|
|
402
|
+
plugins.logger.log(
|
|
403
|
+
"warn",
|
|
404
|
+
"No npm target registries configured to remove.",
|
|
405
|
+
);
|
|
383
406
|
return;
|
|
384
407
|
}
|
|
385
408
|
|
|
@@ -636,7 +659,9 @@ function showCommitHelp(): void {
|
|
|
636
659
|
|
|
637
660
|
async function handleProject(mode: ICliMode): Promise<void> {
|
|
638
661
|
if (!mode.interactive) {
|
|
639
|
-
throw new Error(
|
|
662
|
+
throw new Error(
|
|
663
|
+
"Project configuration requires interactive mode. Use `gitzone config set` for automation.",
|
|
664
|
+
);
|
|
640
665
|
}
|
|
641
666
|
|
|
642
667
|
const smartconfigData = await readSmartconfigFile();
|
|
@@ -680,7 +705,11 @@ async function handleProject(mode: ICliMode): Promise<void> {
|
|
|
680
705
|
type: "input",
|
|
681
706
|
name: "npmPackagename",
|
|
682
707
|
message: "npm package name:",
|
|
683
|
-
default:
|
|
708
|
+
default:
|
|
709
|
+
moduleConfig.npmPackagename ||
|
|
710
|
+
moduleConfig.npmPackageName ||
|
|
711
|
+
packageJson.name ||
|
|
712
|
+
"",
|
|
684
713
|
});
|
|
685
714
|
const license = await askValue<string>(interactInstance, {
|
|
686
715
|
type: "input",
|
|
@@ -699,7 +728,11 @@ async function handleProject(mode: ICliMode): Promise<void> {
|
|
|
699
728
|
: "",
|
|
700
729
|
});
|
|
701
730
|
|
|
702
|
-
setCliConfigValueInData(
|
|
731
|
+
setCliConfigValueInData(
|
|
732
|
+
smartconfigData,
|
|
733
|
+
"schemaVersion",
|
|
734
|
+
CURRENT_GITZONE_CLI_SCHEMA_VERSION,
|
|
735
|
+
);
|
|
703
736
|
setCliConfigValueInData(smartconfigData, "projectType", projectType);
|
|
704
737
|
setCliConfigValueInData(smartconfigData, "module", {
|
|
705
738
|
...moduleConfig,
|
|
@@ -718,7 +751,9 @@ async function handleProject(mode: ICliMode): Promise<void> {
|
|
|
718
751
|
|
|
719
752
|
async function handleCli(mode: ICliMode): Promise<void> {
|
|
720
753
|
if (!mode.interactive) {
|
|
721
|
-
throw new Error(
|
|
754
|
+
throw new Error(
|
|
755
|
+
"CLI behavior configuration requires interactive mode. Use `gitzone config set` for automation.",
|
|
756
|
+
);
|
|
722
757
|
}
|
|
723
758
|
|
|
724
759
|
const smartconfigData = await readSmartconfigFile();
|
|
@@ -745,7 +780,11 @@ async function handleCli(mode: ICliMode): Promise<void> {
|
|
|
745
780
|
default: cliConfig.checkUpdates ?? true,
|
|
746
781
|
});
|
|
747
782
|
|
|
748
|
-
setCliConfigValueInData(
|
|
783
|
+
setCliConfigValueInData(
|
|
784
|
+
smartconfigData,
|
|
785
|
+
"schemaVersion",
|
|
786
|
+
CURRENT_GITZONE_CLI_SCHEMA_VERSION,
|
|
787
|
+
);
|
|
749
788
|
setCliConfigValueInData(smartconfigData, "cli", {
|
|
750
789
|
output,
|
|
751
790
|
interactive,
|
|
@@ -758,11 +797,14 @@ async function handleCli(mode: ICliMode): Promise<void> {
|
|
|
758
797
|
|
|
759
798
|
async function handleRelease(mode: ICliMode): Promise<void> {
|
|
760
799
|
if (!mode.interactive) {
|
|
761
|
-
throw new Error(
|
|
800
|
+
throw new Error(
|
|
801
|
+
"Release configuration requires interactive mode. Use `gitzone config set` for automation.",
|
|
802
|
+
);
|
|
762
803
|
}
|
|
763
804
|
|
|
764
805
|
const smartconfigData = await readSmartconfigFile();
|
|
765
|
-
const currentRelease =
|
|
806
|
+
const currentRelease =
|
|
807
|
+
getCliConfigValueFromData(smartconfigData, "release") || {};
|
|
766
808
|
const currentTargets = currentRelease.targets || {};
|
|
767
809
|
const interactInstance = new plugins.smartinteract.SmartInteract();
|
|
768
810
|
|
|
@@ -865,13 +907,15 @@ async function handleRelease(mode: ICliMode): Promise<void> {
|
|
|
865
907
|
const registry = await askValue<string>(interactInstance, {
|
|
866
908
|
type: "input",
|
|
867
909
|
name: "dockerRegistry",
|
|
868
|
-
message:
|
|
910
|
+
message:
|
|
911
|
+
"Single tsdocker registry target (empty means all configured registries):",
|
|
869
912
|
default: currentTargets.docker?.registry || "",
|
|
870
913
|
});
|
|
871
914
|
const buildRegistries = await askValue<string>(interactInstance, {
|
|
872
915
|
type: "input",
|
|
873
916
|
name: "dockerBuildRegistries",
|
|
874
|
-
message:
|
|
917
|
+
message:
|
|
918
|
+
"Registries to authenticate before Docker builds (comma-separated, empty means all):",
|
|
875
919
|
default: Array.isArray(currentTargets.docker?.buildRegistries)
|
|
876
920
|
? currentTargets.docker.buildRegistries.join(", ")
|
|
877
921
|
: "",
|
|
@@ -879,7 +923,8 @@ async function handleRelease(mode: ICliMode): Promise<void> {
|
|
|
879
923
|
const patterns = await askValue<string>(interactInstance, {
|
|
880
924
|
type: "input",
|
|
881
925
|
name: "dockerPatterns",
|
|
882
|
-
message:
|
|
926
|
+
message:
|
|
927
|
+
"tsdocker Dockerfile patterns (comma-separated, empty means all):",
|
|
883
928
|
default: Array.isArray(currentTargets.docker?.patterns)
|
|
884
929
|
? currentTargets.docker.patterns.join(", ")
|
|
885
930
|
: "",
|
|
@@ -908,12 +953,6 @@ async function handleRelease(mode: ICliMode): Promise<void> {
|
|
|
908
953
|
message: "Docker context for tsdocker (empty for default):",
|
|
909
954
|
default: currentTargets.docker?.context || "",
|
|
910
955
|
});
|
|
911
|
-
const noBuild = await askValue<boolean>(interactInstance, {
|
|
912
|
-
type: "confirm",
|
|
913
|
-
name: "dockerNoBuild",
|
|
914
|
-
message: "Skip tsdocker build and only push existing local registry images?",
|
|
915
|
-
default: currentTargets.docker?.noBuild ?? false,
|
|
916
|
-
});
|
|
917
956
|
releaseTargets.docker = {
|
|
918
957
|
enabled: true,
|
|
919
958
|
engine: "tsdocker",
|
|
@@ -924,13 +963,16 @@ async function handleRelease(mode: ICliMode): Promise<void> {
|
|
|
924
963
|
cached,
|
|
925
964
|
parallel: parseDockerParallel(parallel),
|
|
926
965
|
context: context.trim() || undefined,
|
|
927
|
-
noBuild,
|
|
928
966
|
};
|
|
929
967
|
} else {
|
|
930
968
|
releaseTargets.docker = { enabled: false, engine: "tsdocker" };
|
|
931
969
|
}
|
|
932
970
|
|
|
933
|
-
setCliConfigValueInData(
|
|
971
|
+
setCliConfigValueInData(
|
|
972
|
+
smartconfigData,
|
|
973
|
+
"schemaVersion",
|
|
974
|
+
CURRENT_GITZONE_CLI_SCHEMA_VERSION,
|
|
975
|
+
);
|
|
934
976
|
const currentPreflight = { ...(currentRelease.preflight || {}) };
|
|
935
977
|
delete currentPreflight.requireCleanTree;
|
|
936
978
|
setCliConfigValueInData(smartconfigData, "release", {
|
|
@@ -959,7 +1001,8 @@ async function handleFix(argvArg: any, mode: ICliMode): Promise<void> {
|
|
|
959
1001
|
if (mode.json) {
|
|
960
1002
|
printJson({
|
|
961
1003
|
ok: false,
|
|
962
|
-
error:
|
|
1004
|
+
error:
|
|
1005
|
+
"JSON output is not supported for `gitzone config fix`. Use `gitzone config doctor --json` for machine-readable diagnostics.",
|
|
963
1006
|
});
|
|
964
1007
|
process.exitCode = 1;
|
|
965
1008
|
return;
|
|
@@ -980,12 +1023,15 @@ async function handleFix(argvArg: any, mode: ICliMode): Promise<void> {
|
|
|
980
1023
|
|
|
981
1024
|
if (!mode.yes) {
|
|
982
1025
|
if (!mode.interactive) {
|
|
983
|
-
throw new Error(
|
|
1026
|
+
throw new Error(
|
|
1027
|
+
"Config fix requires an interactive terminal or `-y` to run non-interactively.",
|
|
1028
|
+
);
|
|
984
1029
|
}
|
|
985
|
-
const confirmed =
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
1030
|
+
const confirmed =
|
|
1031
|
+
await plugins.smartinteract.SmartInteract.getCliConfirmation(
|
|
1032
|
+
`Run configuration fixes for .smartconfig.json? (${counts.error} error, ${counts.warn} warning)`,
|
|
1033
|
+
true,
|
|
1034
|
+
);
|
|
989
1035
|
if (!confirmed) {
|
|
990
1036
|
plugins.logger.log("info", "Config fix cancelled.");
|
|
991
1037
|
return;
|
|
@@ -996,7 +1042,12 @@ async function handleFix(argvArg: any, mode: ICliMode): Promise<void> {
|
|
|
996
1042
|
if (appliedKnownFixes) {
|
|
997
1043
|
findings = await collectDoctorFindings();
|
|
998
1044
|
counts = countDoctorFindings(findings);
|
|
999
|
-
if (
|
|
1045
|
+
if (
|
|
1046
|
+
counts.error === 0 &&
|
|
1047
|
+
counts.warn === 0 &&
|
|
1048
|
+
!extraInstructions &&
|
|
1049
|
+
!force
|
|
1050
|
+
) {
|
|
1000
1051
|
printDoctorResult(findings, mode);
|
|
1001
1052
|
return;
|
|
1002
1053
|
}
|
|
@@ -1032,7 +1083,9 @@ async function handleFix(argvArg: any, mode: ICliMode): Promise<void> {
|
|
|
1032
1083
|
stdio: "inherit",
|
|
1033
1084
|
});
|
|
1034
1085
|
} catch (error) {
|
|
1035
|
-
throw new Error(
|
|
1086
|
+
throw new Error(
|
|
1087
|
+
`Failed to run opencode: ${error instanceof Error ? error.message : String(error)}`,
|
|
1088
|
+
);
|
|
1036
1089
|
}
|
|
1037
1090
|
|
|
1038
1091
|
if (result.exitCode !== 0) {
|
|
@@ -1076,7 +1129,9 @@ async function applyKnownConfigFixes(mode: ICliMode): Promise<boolean> {
|
|
|
1076
1129
|
async function collectDoctorFindings(): Promise<IDoctorFinding[]> {
|
|
1077
1130
|
const findings: IDoctorFinding[] = [];
|
|
1078
1131
|
const smartconfigPath = getSmartconfigPath();
|
|
1079
|
-
const smartconfigExists = await plugins.smartfs
|
|
1132
|
+
const smartconfigExists = await plugins.smartfs
|
|
1133
|
+
.file(smartconfigPath)
|
|
1134
|
+
.exists();
|
|
1080
1135
|
|
|
1081
1136
|
if (!smartconfigExists) {
|
|
1082
1137
|
findings.push({
|
|
@@ -1108,7 +1163,13 @@ async function collectDoctorFindings(): Promise<IDoctorFinding[]> {
|
|
|
1108
1163
|
});
|
|
1109
1164
|
}
|
|
1110
1165
|
|
|
1111
|
-
for (const legacyNamespace of [
|
|
1166
|
+
for (const legacyNamespace of [
|
|
1167
|
+
"gitzone",
|
|
1168
|
+
"tsdoc",
|
|
1169
|
+
"npmdocker",
|
|
1170
|
+
"npmci",
|
|
1171
|
+
"szci",
|
|
1172
|
+
]) {
|
|
1112
1173
|
if (smartconfigData[legacyNamespace]) {
|
|
1113
1174
|
findings.push({
|
|
1114
1175
|
level: "warn",
|
|
@@ -1119,7 +1180,10 @@ async function collectDoctorFindings(): Promise<IDoctorFinding[]> {
|
|
|
1119
1180
|
}
|
|
1120
1181
|
|
|
1121
1182
|
if (cliConfig.schemaVersion === CURRENT_GITZONE_CLI_SCHEMA_VERSION) {
|
|
1122
|
-
findings.push({
|
|
1183
|
+
findings.push({
|
|
1184
|
+
level: "ok",
|
|
1185
|
+
message: `Schema version is current (${CURRENT_GITZONE_CLI_SCHEMA_VERSION})`,
|
|
1186
|
+
});
|
|
1123
1187
|
} else {
|
|
1124
1188
|
findings.push({
|
|
1125
1189
|
level: "warn",
|
|
@@ -1129,7 +1193,10 @@ async function collectDoctorFindings(): Promise<IDoctorFinding[]> {
|
|
|
1129
1193
|
}
|
|
1130
1194
|
|
|
1131
1195
|
if (["npm", "service", "wcc", "website"].includes(cliConfig.projectType)) {
|
|
1132
|
-
findings.push({
|
|
1196
|
+
findings.push({
|
|
1197
|
+
level: "ok",
|
|
1198
|
+
message: `Project type is ${cliConfig.projectType}`,
|
|
1199
|
+
});
|
|
1133
1200
|
} else {
|
|
1134
1201
|
findings.push({
|
|
1135
1202
|
level: "warn",
|
|
@@ -1286,7 +1353,10 @@ async function handleMigrate(
|
|
|
1286
1353
|
`Migrated .smartconfig.json from schema v${result.fromVersion} to v${result.toVersion}`,
|
|
1287
1354
|
);
|
|
1288
1355
|
} else {
|
|
1289
|
-
plugins.logger.log(
|
|
1356
|
+
plugins.logger.log(
|
|
1357
|
+
"info",
|
|
1358
|
+
`.smartconfig.json already at schema v${result.toVersion}`,
|
|
1359
|
+
);
|
|
1290
1360
|
}
|
|
1291
1361
|
}
|
|
1292
1362
|
|
|
@@ -1389,7 +1459,8 @@ function formatTarget(enabled: unknown, targetConfig: any): string {
|
|
|
1389
1459
|
if (Array.isArray(targetConfig.registries)) {
|
|
1390
1460
|
details.push(`registries=${targetConfig.registries.length}`);
|
|
1391
1461
|
}
|
|
1392
|
-
if (targetConfig.accessLevel)
|
|
1462
|
+
if (targetConfig.accessLevel)
|
|
1463
|
+
details.push(`access=${targetConfig.accessLevel}`);
|
|
1393
1464
|
if (targetConfig.engine) details.push(`engine=${targetConfig.engine}`);
|
|
1394
1465
|
if (Array.isArray(targetConfig.patterns)) {
|
|
1395
1466
|
details.push(`patterns=${targetConfig.patterns.length}`);
|
|
@@ -1397,14 +1468,10 @@ function formatTarget(enabled: unknown, targetConfig: any): string {
|
|
|
1397
1468
|
if (targetConfig.cached) details.push("cached=true");
|
|
1398
1469
|
if (targetConfig.parallel) details.push(`parallel=${targetConfig.parallel}`);
|
|
1399
1470
|
if (targetConfig.context) details.push(`context=${targetConfig.context}`);
|
|
1400
|
-
if (targetConfig.noBuild) details.push("noBuild=true");
|
|
1401
1471
|
return details.length > 0 ? `${state} (${details.join(", ")})` : state;
|
|
1402
1472
|
}
|
|
1403
1473
|
|
|
1404
|
-
async function askValue<T>(
|
|
1405
|
-
interactInstance: any,
|
|
1406
|
-
options: any,
|
|
1407
|
-
): Promise<T> {
|
|
1474
|
+
async function askValue<T>(interactInstance: any, options: any): Promise<T> {
|
|
1408
1475
|
const response = await interactInstance.askQuestion(options);
|
|
1409
1476
|
return response.value as T;
|
|
1410
1477
|
}
|
|
@@ -1452,7 +1519,10 @@ function formatDockerParallel(value: unknown): string {
|
|
|
1452
1519
|
|
|
1453
1520
|
function parseDockerParallel(value: string): boolean | number {
|
|
1454
1521
|
const normalizedValue = value.trim().toLowerCase();
|
|
1455
|
-
if (
|
|
1522
|
+
if (
|
|
1523
|
+
!normalizedValue ||
|
|
1524
|
+
["false", "no", "off", "0"].includes(normalizedValue)
|
|
1525
|
+
) {
|
|
1456
1526
|
return false;
|
|
1457
1527
|
}
|
|
1458
1528
|
if (["true", "yes", "on"].includes(normalizedValue)) {
|
|
@@ -1467,19 +1537,29 @@ function parseDockerParallel(value: string): boolean | number {
|
|
|
1467
1537
|
|
|
1468
1538
|
function normalizeRegistryUrl(url: string): string {
|
|
1469
1539
|
let normalizedUrl = url.trim();
|
|
1470
|
-
if (
|
|
1540
|
+
if (
|
|
1541
|
+
!normalizedUrl.startsWith("http://") &&
|
|
1542
|
+
!normalizedUrl.startsWith("https://")
|
|
1543
|
+
) {
|
|
1471
1544
|
normalizedUrl = `https://${normalizedUrl}`;
|
|
1472
1545
|
}
|
|
1473
|
-
return normalizedUrl.endsWith("/")
|
|
1546
|
+
return normalizedUrl.endsWith("/")
|
|
1547
|
+
? normalizedUrl.slice(0, -1)
|
|
1548
|
+
: normalizedUrl;
|
|
1474
1549
|
}
|
|
1475
1550
|
|
|
1476
|
-
function getDefaultEnabledTargets(
|
|
1551
|
+
function getDefaultEnabledTargets(
|
|
1552
|
+
currentTargets: Record<string, any>,
|
|
1553
|
+
): string[] {
|
|
1477
1554
|
const enabledTargets: string[] = [];
|
|
1478
1555
|
const npmRegistries = currentTargets.npm?.registries;
|
|
1479
1556
|
if (currentTargets.git?.enabled ?? true) {
|
|
1480
1557
|
enabledTargets.push("git");
|
|
1481
1558
|
}
|
|
1482
|
-
if (
|
|
1559
|
+
if (
|
|
1560
|
+
currentTargets.npm?.enabled ??
|
|
1561
|
+
(Array.isArray(npmRegistries) && npmRegistries.length > 0)
|
|
1562
|
+
) {
|
|
1483
1563
|
enabledTargets.push("npm");
|
|
1484
1564
|
}
|
|
1485
1565
|
if (currentTargets.docker?.enabled ?? false) {
|
|
@@ -1518,7 +1598,8 @@ function buildConfigFixPrompt(
|
|
|
1518
1598
|
`- Use schemaVersion ${CURRENT_GITZONE_CLI_SCHEMA_VERSION} for ` +
|
|
1519
1599
|
"`@git.zone/cli`.",
|
|
1520
1600
|
"- Use target-based release config: `release.targets.git`, `release.targets.npm`, and `release.targets.docker`.",
|
|
1521
|
-
|
|
1601
|
+
'- Docker release targets must use `release.targets.docker.engine = "tsdocker"`; Docker registries belong under `@git.zone/tsdocker`.',
|
|
1602
|
+
"- Remove `release.targets.docker.noBuild`; journaled Docker qualification always builds.",
|
|
1522
1603
|
"- Keep npm registries only at `@git.zone/cli.release.targets.npm.registries`.",
|
|
1523
1604
|
"- Do not add runtime legacy compatibility code. If legacy config exists, migrate it explicitly.",
|
|
1524
1605
|
"- Do not commit, release, install dependencies, or modify unrelated files.",
|
|
@@ -1558,7 +1639,9 @@ function printDoctorResult(findings: IDoctorFinding[], mode: ICliMode): void {
|
|
|
1558
1639
|
}
|
|
1559
1640
|
}
|
|
1560
1641
|
console.log("");
|
|
1561
|
-
console.log(
|
|
1642
|
+
console.log(
|
|
1643
|
+
`Summary: ${counts.ok} ok, ${counts.warn} warning, ${counts.error} error`,
|
|
1644
|
+
);
|
|
1562
1645
|
console.log("");
|
|
1563
1646
|
}
|
|
1564
1647
|
|
|
@@ -1572,8 +1655,14 @@ function validateCommitConfig(
|
|
|
1572
1655
|
findings: IDoctorFinding[],
|
|
1573
1656
|
): void {
|
|
1574
1657
|
const confirmation = commitConfig.confirmation;
|
|
1575
|
-
if (
|
|
1576
|
-
|
|
1658
|
+
if (
|
|
1659
|
+
confirmation === undefined ||
|
|
1660
|
+
validConfirmationModes.includes(confirmation)
|
|
1661
|
+
) {
|
|
1662
|
+
findings.push({
|
|
1663
|
+
level: "ok",
|
|
1664
|
+
message: "Commit confirmation mode is valid",
|
|
1665
|
+
});
|
|
1577
1666
|
} else {
|
|
1578
1667
|
findings.push({
|
|
1579
1668
|
level: "warn",
|
|
@@ -1584,7 +1673,10 @@ function validateCommitConfig(
|
|
|
1584
1673
|
|
|
1585
1674
|
const steps = commitConfig.steps;
|
|
1586
1675
|
if (steps === undefined) {
|
|
1587
|
-
findings.push({
|
|
1676
|
+
findings.push({
|
|
1677
|
+
level: "ok",
|
|
1678
|
+
message: "Commit workflow uses default steps",
|
|
1679
|
+
});
|
|
1588
1680
|
return;
|
|
1589
1681
|
}
|
|
1590
1682
|
if (!Array.isArray(steps) || steps.length === 0) {
|
|
@@ -1660,8 +1752,14 @@ async function validateReleaseConfig(
|
|
|
1660
1752
|
}
|
|
1661
1753
|
|
|
1662
1754
|
const confirmation = releaseConfig.confirmation;
|
|
1663
|
-
if (
|
|
1664
|
-
|
|
1755
|
+
if (
|
|
1756
|
+
confirmation === undefined ||
|
|
1757
|
+
validConfirmationModes.includes(confirmation)
|
|
1758
|
+
) {
|
|
1759
|
+
findings.push({
|
|
1760
|
+
level: "ok",
|
|
1761
|
+
message: "Release confirmation mode is valid",
|
|
1762
|
+
});
|
|
1665
1763
|
} else {
|
|
1666
1764
|
findings.push({
|
|
1667
1765
|
level: "warn",
|
|
@@ -1670,7 +1768,12 @@ async function validateReleaseConfig(
|
|
|
1670
1768
|
});
|
|
1671
1769
|
}
|
|
1672
1770
|
|
|
1673
|
-
if (
|
|
1771
|
+
if (
|
|
1772
|
+
releaseConfig.registries ||
|
|
1773
|
+
releaseConfig.accessLevel ||
|
|
1774
|
+
releaseConfig.steps ||
|
|
1775
|
+
releaseConfig.changelog
|
|
1776
|
+
) {
|
|
1674
1777
|
findings.push({
|
|
1675
1778
|
level: "warn",
|
|
1676
1779
|
message: "Legacy release keys are present outside release.targets",
|
|
@@ -1706,7 +1809,10 @@ async function validateAssetsConfig(
|
|
|
1706
1809
|
findings: IDoctorFinding[],
|
|
1707
1810
|
): Promise<void> {
|
|
1708
1811
|
if (rawAssetsConfig === undefined) {
|
|
1709
|
-
findings.push({
|
|
1812
|
+
findings.push({
|
|
1813
|
+
level: "ok",
|
|
1814
|
+
message: "Managed assets are not configured",
|
|
1815
|
+
});
|
|
1710
1816
|
return;
|
|
1711
1817
|
}
|
|
1712
1818
|
if (!isPlainObject(rawAssetsConfig)) {
|
|
@@ -1738,15 +1844,21 @@ async function validateAssetsConfig(
|
|
|
1738
1844
|
fix: "Set @git.zone/cli.assets.cliName.",
|
|
1739
1845
|
});
|
|
1740
1846
|
} else {
|
|
1741
|
-
findings.push({
|
|
1847
|
+
findings.push({
|
|
1848
|
+
level: "ok",
|
|
1849
|
+
message: `Managed denoBinaryCli assets target ${cliName}`,
|
|
1850
|
+
});
|
|
1742
1851
|
}
|
|
1743
1852
|
|
|
1744
1853
|
const tsdenoConfig = smartconfigData["@git.zone/tsdeno"];
|
|
1745
|
-
const binaryTargets =
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
?
|
|
1749
|
-
:
|
|
1854
|
+
const binaryTargets =
|
|
1855
|
+
isPlainObject(rawAssetsConfig.binary) &&
|
|
1856
|
+
Array.isArray(rawAssetsConfig.binary.targets)
|
|
1857
|
+
? rawAssetsConfig.binary.targets
|
|
1858
|
+
: isPlainObject(tsdenoConfig) &&
|
|
1859
|
+
Array.isArray(tsdenoConfig.compileTargets)
|
|
1860
|
+
? tsdenoConfig.compileTargets
|
|
1861
|
+
: [];
|
|
1750
1862
|
if (binaryTargets.length === 0) {
|
|
1751
1863
|
findings.push({
|
|
1752
1864
|
level: "error",
|
|
@@ -1754,22 +1866,37 @@ async function validateAssetsConfig(
|
|
|
1754
1866
|
fix: "Add @git.zone/tsdeno.compileTargets or @git.zone/cli.assets.binary.targets.",
|
|
1755
1867
|
});
|
|
1756
1868
|
} else {
|
|
1757
|
-
findings.push({
|
|
1869
|
+
findings.push({
|
|
1870
|
+
level: "ok",
|
|
1871
|
+
message: `Managed assets have ${binaryTargets.length} binary target(s)`,
|
|
1872
|
+
});
|
|
1758
1873
|
}
|
|
1759
1874
|
|
|
1760
1875
|
const npmWrapper = rawAssetsConfig.npmWrapper;
|
|
1761
|
-
if (
|
|
1876
|
+
if (
|
|
1877
|
+
isPlainObject(npmWrapper) &&
|
|
1878
|
+
npmWrapper.enabled === true &&
|
|
1879
|
+
typeof cliName === "string" &&
|
|
1880
|
+
cliName.trim()
|
|
1881
|
+
) {
|
|
1762
1882
|
const packageJson = await readPackageJson();
|
|
1763
1883
|
const binFile = npmWrapper.binFile || `bin/${cliName}-wrapper.js`;
|
|
1764
|
-
const postinstallFile =
|
|
1765
|
-
|
|
1884
|
+
const postinstallFile =
|
|
1885
|
+
npmWrapper.postinstallFile || "scripts/install-binary.js";
|
|
1886
|
+
if (
|
|
1887
|
+
!isPlainObject(packageJson.bin) ||
|
|
1888
|
+
packageJson.bin[cliName] !== `./${binFile}`
|
|
1889
|
+
) {
|
|
1766
1890
|
findings.push({
|
|
1767
1891
|
level: "warn",
|
|
1768
1892
|
message: `package.json bin entry for ${cliName} is missing or outdated`,
|
|
1769
1893
|
fix: "Run `gitzone format --only packagejson --write`.",
|
|
1770
1894
|
});
|
|
1771
1895
|
} else {
|
|
1772
|
-
findings.push({
|
|
1896
|
+
findings.push({
|
|
1897
|
+
level: "ok",
|
|
1898
|
+
message: `package.json bin entry points to ${binFile}`,
|
|
1899
|
+
});
|
|
1773
1900
|
}
|
|
1774
1901
|
if (packageJson.scripts?.postinstall !== `node ${postinstallFile}`) {
|
|
1775
1902
|
findings.push({
|
|
@@ -1778,7 +1905,10 @@ async function validateAssetsConfig(
|
|
|
1778
1905
|
fix: "Run `gitzone format --only packagejson --write`.",
|
|
1779
1906
|
});
|
|
1780
1907
|
} else {
|
|
1781
|
-
findings.push({
|
|
1908
|
+
findings.push({
|
|
1909
|
+
level: "ok",
|
|
1910
|
+
message: `package.json postinstall runs ${postinstallFile}`,
|
|
1911
|
+
});
|
|
1782
1912
|
}
|
|
1783
1913
|
}
|
|
1784
1914
|
}
|
|
@@ -1825,7 +1955,9 @@ async function validateNpmTarget(
|
|
|
1825
1955
|
npmTarget: Record<string, any>,
|
|
1826
1956
|
findings: IDoctorFinding[],
|
|
1827
1957
|
): Promise<void> {
|
|
1828
|
-
const registries = Array.isArray(npmTarget.registries)
|
|
1958
|
+
const registries = Array.isArray(npmTarget.registries)
|
|
1959
|
+
? npmTarget.registries
|
|
1960
|
+
: [];
|
|
1829
1961
|
const enabled = npmTarget.enabled ?? registries.length > 0;
|
|
1830
1962
|
if (!enabled) {
|
|
1831
1963
|
findings.push({ level: "ok", message: "npm release target is disabled" });
|
|
@@ -1841,14 +1973,20 @@ async function validateNpmTarget(
|
|
|
1841
1973
|
return;
|
|
1842
1974
|
}
|
|
1843
1975
|
|
|
1844
|
-
if (
|
|
1976
|
+
if (
|
|
1977
|
+
npmTarget.accessLevel &&
|
|
1978
|
+
!["public", "private"].includes(npmTarget.accessLevel)
|
|
1979
|
+
) {
|
|
1845
1980
|
findings.push({
|
|
1846
1981
|
level: "error",
|
|
1847
1982
|
message: `Invalid npm access level: ${npmTarget.accessLevel}`,
|
|
1848
1983
|
fix: "Use public or private.",
|
|
1849
1984
|
});
|
|
1850
1985
|
}
|
|
1851
|
-
if (
|
|
1986
|
+
if (
|
|
1987
|
+
npmTarget.alreadyPublished &&
|
|
1988
|
+
!["success", "error"].includes(npmTarget.alreadyPublished)
|
|
1989
|
+
) {
|
|
1852
1990
|
findings.push({
|
|
1853
1991
|
level: "error",
|
|
1854
1992
|
message: `Invalid npm alreadyPublished behavior: ${npmTarget.alreadyPublished}`,
|
|
@@ -1901,7 +2039,9 @@ async function validateNpmRegistry(
|
|
|
1901
2039
|
}
|
|
1902
2040
|
|
|
1903
2041
|
try {
|
|
1904
|
-
const result = await smartNetwork.checkEndpoint(normalizedRegistry, {
|
|
2042
|
+
const result = await smartNetwork.checkEndpoint(normalizedRegistry, {
|
|
2043
|
+
timeout: 5000,
|
|
2044
|
+
});
|
|
1905
2045
|
if (result.status >= 200 && result.status < 500) {
|
|
1906
2046
|
findings.push({
|
|
1907
2047
|
level: "ok",
|
|
@@ -1963,6 +2103,17 @@ async function validateDockerTarget(
|
|
|
1963
2103
|
smartconfigData: Record<string, any>,
|
|
1964
2104
|
findings: IDoctorFinding[],
|
|
1965
2105
|
): Promise<void> {
|
|
2106
|
+
if (
|
|
2107
|
+
dockerTarget.noBuild === true ||
|
|
2108
|
+
(dockerTarget.noBuild !== undefined &&
|
|
2109
|
+
typeof dockerTarget.noBuild !== "boolean")
|
|
2110
|
+
) {
|
|
2111
|
+
findings.push({
|
|
2112
|
+
level: "error",
|
|
2113
|
+
message: "Docker release target cannot bypass qualification builds",
|
|
2114
|
+
fix: "Remove release.targets.docker.noBuild or set it to false.",
|
|
2115
|
+
});
|
|
2116
|
+
}
|
|
1966
2117
|
if ("images" in dockerTarget) {
|
|
1967
2118
|
findings.push({
|
|
1968
2119
|
level: "error",
|
|
@@ -1973,7 +2124,10 @@ async function validateDockerTarget(
|
|
|
1973
2124
|
|
|
1974
2125
|
const enabled = dockerTarget.enabled ?? false;
|
|
1975
2126
|
if (!enabled) {
|
|
1976
|
-
findings.push({
|
|
2127
|
+
findings.push({
|
|
2128
|
+
level: "ok",
|
|
2129
|
+
message: "Docker release target is disabled",
|
|
2130
|
+
});
|
|
1977
2131
|
return;
|
|
1978
2132
|
}
|
|
1979
2133
|
|
|
@@ -1985,7 +2139,10 @@ async function validateDockerTarget(
|
|
|
1985
2139
|
});
|
|
1986
2140
|
}
|
|
1987
2141
|
|
|
1988
|
-
if (
|
|
2142
|
+
if (
|
|
2143
|
+
dockerTarget.patterns !== undefined &&
|
|
2144
|
+
!Array.isArray(dockerTarget.patterns)
|
|
2145
|
+
) {
|
|
1989
2146
|
findings.push({
|
|
1990
2147
|
level: "error",
|
|
1991
2148
|
message: "Docker release target patterns must be an array",
|
|
@@ -1994,10 +2151,10 @@ async function validateDockerTarget(
|
|
|
1994
2151
|
}
|
|
1995
2152
|
|
|
1996
2153
|
if (
|
|
1997
|
-
dockerTarget.registry !== undefined
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2154
|
+
dockerTarget.registry !== undefined &&
|
|
2155
|
+
(typeof dockerTarget.registry !== "string" ||
|
|
2156
|
+
!dockerTarget.registry.trim() ||
|
|
2157
|
+
/^https?:\/\//.test(dockerTarget.registry))
|
|
2001
2158
|
) {
|
|
2002
2159
|
findings.push({
|
|
2003
2160
|
level: "error",
|
|
@@ -2007,14 +2164,16 @@ async function validateDockerTarget(
|
|
|
2007
2164
|
}
|
|
2008
2165
|
|
|
2009
2166
|
if (
|
|
2010
|
-
dockerTarget.buildRegistries !== undefined
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2167
|
+
dockerTarget.buildRegistries !== undefined &&
|
|
2168
|
+
(!Array.isArray(dockerTarget.buildRegistries) ||
|
|
2169
|
+
dockerTarget.buildRegistries.some(
|
|
2170
|
+
(registryArg: unknown) =>
|
|
2171
|
+
typeof registryArg !== "string" ||
|
|
2172
|
+
!registryArg.trim() ||
|
|
2173
|
+
/^https?:\/\//.test(registryArg),
|
|
2174
|
+
) ||
|
|
2175
|
+
new Set(dockerTarget.buildRegistries).size !==
|
|
2176
|
+
dockerTarget.buildRegistries.length)
|
|
2018
2177
|
) {
|
|
2019
2178
|
findings.push({
|
|
2020
2179
|
level: "error",
|
|
@@ -2023,7 +2182,10 @@ async function validateDockerTarget(
|
|
|
2023
2182
|
});
|
|
2024
2183
|
}
|
|
2025
2184
|
|
|
2026
|
-
if (
|
|
2185
|
+
if (
|
|
2186
|
+
dockerTarget.test !== undefined &&
|
|
2187
|
+
typeof dockerTarget.test !== "boolean"
|
|
2188
|
+
) {
|
|
2027
2189
|
findings.push({
|
|
2028
2190
|
level: "error",
|
|
2029
2191
|
message: `Invalid tsdocker image test setting: ${formatValue(dockerTarget.test)}`,
|
|
@@ -2043,7 +2205,8 @@ async function validateDockerTarget(
|
|
|
2043
2205
|
if (!isPlainObject(tsdockerConfig)) {
|
|
2044
2206
|
findings.push({
|
|
2045
2207
|
level: "error",
|
|
2046
|
-
message:
|
|
2208
|
+
message:
|
|
2209
|
+
"Docker release target is enabled but @git.zone/tsdocker config is missing",
|
|
2047
2210
|
fix: "Add @git.zone/tsdocker.registries and optional registryRepoMap/platforms config.",
|
|
2048
2211
|
});
|
|
2049
2212
|
} else {
|
|
@@ -2073,10 +2236,12 @@ function isPlainObject(value: unknown): value is Record<string, any> {
|
|
|
2073
2236
|
}
|
|
2074
2237
|
|
|
2075
2238
|
function isValidDockerParallel(value: unknown): boolean {
|
|
2076
|
-
return
|
|
2239
|
+
return (
|
|
2240
|
+
value === undefined ||
|
|
2077
2241
|
value === false ||
|
|
2078
2242
|
value === true ||
|
|
2079
|
-
(typeof value === "number" && Number.isFinite(value) && value > 0)
|
|
2243
|
+
(typeof value === "number" && Number.isFinite(value) && value > 0)
|
|
2244
|
+
);
|
|
2080
2245
|
}
|
|
2081
2246
|
|
|
2082
2247
|
function validateTsdockerProjectConfig(
|
|
@@ -2138,13 +2303,16 @@ function validateTsdockerProjectConfig(
|
|
|
2138
2303
|
|
|
2139
2304
|
async function validateTsdockerCommand(
|
|
2140
2305
|
findings: IDoctorFinding[],
|
|
2141
|
-
|
|
2142
|
-
|
|
2306
|
+
_buildRegistriesArg: unknown,
|
|
2307
|
+
_imageTestsRequestedArg: boolean,
|
|
2143
2308
|
): Promise<void> {
|
|
2144
2309
|
let packageJson: unknown;
|
|
2145
2310
|
try {
|
|
2146
2311
|
packageJson = JSON.parse(
|
|
2147
|
-
await plugins.fs.readFile(
|
|
2312
|
+
await plugins.fs.readFile(
|
|
2313
|
+
plugins.path.join(process.cwd(), "package.json"),
|
|
2314
|
+
"utf8",
|
|
2315
|
+
),
|
|
2148
2316
|
);
|
|
2149
2317
|
} catch {
|
|
2150
2318
|
packageJson = undefined;
|
|
@@ -2152,7 +2320,8 @@ async function validateTsdockerCommand(
|
|
|
2152
2320
|
if (!getDeclaredTsdockerRange(packageJson)) {
|
|
2153
2321
|
findings.push({
|
|
2154
2322
|
level: "error",
|
|
2155
|
-
message:
|
|
2323
|
+
message:
|
|
2324
|
+
"Docker release target requires project-local @git.zone/tsdocker",
|
|
2156
2325
|
fix: "Run pnpm add --save-dev @git.zone/tsdocker.",
|
|
2157
2326
|
});
|
|
2158
2327
|
}
|
|
@@ -2168,43 +2337,22 @@ async function validateTsdockerCommand(
|
|
|
2168
2337
|
sourceFilePaths: [],
|
|
2169
2338
|
});
|
|
2170
2339
|
try {
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
Array.isArray(buildRegistriesArg) && buildRegistriesArg.length > 0,
|
|
2180
|
-
imageTestsRequestedArg,
|
|
2181
|
-
);
|
|
2182
|
-
if (
|
|
2183
|
-
minimumTsdockerVersion
|
|
2184
|
-
&& !supportsTsdockerMinimumVersion(
|
|
2185
|
-
result.combinedOutput,
|
|
2186
|
-
minimumTsdockerVersion,
|
|
2187
|
-
)
|
|
2188
|
-
) {
|
|
2189
|
-
const minimumVersion = formatTsdockerMinimumVersion(minimumTsdockerVersion);
|
|
2190
|
-
findings.push({
|
|
2191
|
-
level: "error",
|
|
2192
|
-
message: `Docker release options require @git.zone/tsdocker >= ${minimumVersion}`,
|
|
2193
|
-
fix: `Upgrade the project's @git.zone/tsdocker dev dependency to at least ${minimumVersion}.`,
|
|
2194
|
-
});
|
|
2195
|
-
}
|
|
2196
|
-
} else {
|
|
2197
|
-
findings.push({
|
|
2198
|
-
level: "error",
|
|
2199
|
-
message: "Project-local tsdocker command is not available",
|
|
2200
|
-
fix: "Install @git.zone/tsdocker as a project dev dependency.",
|
|
2201
|
-
});
|
|
2202
|
-
}
|
|
2340
|
+
await new TsdockerReleaseClient(
|
|
2341
|
+
smartshellInstance,
|
|
2342
|
+
process.cwd(),
|
|
2343
|
+
).assertCapabilities();
|
|
2344
|
+
findings.push({
|
|
2345
|
+
level: "ok",
|
|
2346
|
+
message: "Project-local tSDocker release protocol v1 is available",
|
|
2347
|
+
});
|
|
2203
2348
|
} catch (error) {
|
|
2204
2349
|
findings.push({
|
|
2205
2350
|
level: "error",
|
|
2206
|
-
message: "
|
|
2207
|
-
fix:
|
|
2351
|
+
message: "Project-local tSDocker release protocol is unavailable",
|
|
2352
|
+
fix:
|
|
2353
|
+
error instanceof Error
|
|
2354
|
+
? error.message
|
|
2355
|
+
: "Install @git.zone/tsdocker >= 3.5.1.",
|
|
2208
2356
|
});
|
|
2209
2357
|
}
|
|
2210
2358
|
}
|
|
@@ -2230,7 +2378,8 @@ async function validateDetectedProjectType(
|
|
|
2230
2378
|
if (hasPackageJson && validProjectTypes.includes(cliConfig.projectType)) {
|
|
2231
2379
|
findings.push({
|
|
2232
2380
|
level: "ok",
|
|
2233
|
-
message:
|
|
2381
|
+
message:
|
|
2382
|
+
"Detected project files match configured npm-compatible project type",
|
|
2234
2383
|
});
|
|
2235
2384
|
return;
|
|
2236
2385
|
}
|
|
@@ -2238,7 +2387,8 @@ async function validateDetectedProjectType(
|
|
|
2238
2387
|
if (hasDenoJson && !hasPackageJson) {
|
|
2239
2388
|
findings.push({
|
|
2240
2389
|
level: "warn",
|
|
2241
|
-
message:
|
|
2390
|
+
message:
|
|
2391
|
+
"Detected a Deno-only project, but guided config supports npm-compatible project types",
|
|
2242
2392
|
fix: "Use `gitzone config set projectType npm|service|wcc|website` only for npm-compatible projects.",
|
|
2243
2393
|
});
|
|
2244
2394
|
}
|
|
@@ -2257,9 +2407,15 @@ export function showHelp(mode?: ICliMode): void {
|
|
|
2257
2407
|
name: "show",
|
|
2258
2408
|
description: "Display current @git.zone/cli configuration",
|
|
2259
2409
|
},
|
|
2260
|
-
{
|
|
2410
|
+
{
|
|
2411
|
+
name: "project",
|
|
2412
|
+
description: "Configure project basics interactively",
|
|
2413
|
+
},
|
|
2261
2414
|
{ name: "cli", description: "Configure CLI behavior interactively" },
|
|
2262
|
-
{
|
|
2415
|
+
{
|
|
2416
|
+
name: "release",
|
|
2417
|
+
description: "Configure release workflow interactively",
|
|
2418
|
+
},
|
|
2263
2419
|
{ name: "doctor", description: "Validate .smartconfig.json" },
|
|
2264
2420
|
{
|
|
2265
2421
|
name: "fix [instructions]",
|
|
@@ -2269,8 +2425,14 @@ export function showHelp(mode?: ICliMode): void {
|
|
|
2269
2425
|
{ name: "get <path>", description: "Read a single config value" },
|
|
2270
2426
|
{ name: "set <path> <value>", description: "Write a config value" },
|
|
2271
2427
|
{ name: "unset <path>", description: "Delete a config value" },
|
|
2272
|
-
{
|
|
2273
|
-
|
|
2428
|
+
{
|
|
2429
|
+
name: "add [url]",
|
|
2430
|
+
description: "Add an npm release target registry",
|
|
2431
|
+
},
|
|
2432
|
+
{
|
|
2433
|
+
name: "remove [url]",
|
|
2434
|
+
description: "Remove an npm release target registry",
|
|
2435
|
+
},
|
|
2274
2436
|
{ name: "clear", description: "Clear npm release target registries" },
|
|
2275
2437
|
{
|
|
2276
2438
|
name: "access [public|private]",
|
|
@@ -2306,11 +2468,19 @@ export function showHelp(mode?: ICliMode): void {
|
|
|
2306
2468
|
console.log(
|
|
2307
2469
|
" show Display current @git.zone/cli configuration",
|
|
2308
2470
|
);
|
|
2309
|
-
console.log(
|
|
2310
|
-
|
|
2311
|
-
|
|
2471
|
+
console.log(
|
|
2472
|
+
" project Configure project basics interactively",
|
|
2473
|
+
);
|
|
2474
|
+
console.log(
|
|
2475
|
+
" cli Configure CLI behavior interactively",
|
|
2476
|
+
);
|
|
2477
|
+
console.log(
|
|
2478
|
+
" release Configure release workflow interactively",
|
|
2479
|
+
);
|
|
2312
2480
|
console.log(" doctor Validate .smartconfig.json");
|
|
2313
|
-
console.log(
|
|
2481
|
+
console.log(
|
|
2482
|
+
" fix [instructions] Repair .smartconfig.json via opencode",
|
|
2483
|
+
);
|
|
2314
2484
|
console.log(
|
|
2315
2485
|
" with -y, opencode runs with --dangerously-skip-permissions ⚠️",
|
|
2316
2486
|
);
|
|
@@ -2318,13 +2488,17 @@ export function showHelp(mode?: ICliMode): void {
|
|
|
2318
2488
|
console.log(" set <path> <value> Write a config value");
|
|
2319
2489
|
console.log(" unset <path> Delete a config value");
|
|
2320
2490
|
console.log(" add [url] Add an npm target registry URL");
|
|
2321
|
-
console.log(
|
|
2491
|
+
console.log(
|
|
2492
|
+
" remove [url] Remove an npm target registry URL",
|
|
2493
|
+
);
|
|
2322
2494
|
console.log(" clear Clear npm target registries");
|
|
2323
2495
|
console.log(
|
|
2324
2496
|
" access [public|private] Set npm target access level for publishing",
|
|
2325
2497
|
);
|
|
2326
2498
|
console.log(" commit [setting] [value] Configure commit options");
|
|
2327
|
-
console.log(
|
|
2499
|
+
console.log(
|
|
2500
|
+
" migrate [version] Run version-targeted smartconfig migrations",
|
|
2501
|
+
);
|
|
2328
2502
|
console.log(
|
|
2329
2503
|
" services Configure which services are enabled",
|
|
2330
2504
|
);
|