github-labels-template 0.7.0-staging.63849e1 → 0.7.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/index.js +19 -187
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { defineCommand as
|
|
4
|
+
import { defineCommand as defineCommand6, runMain } from "citty";
|
|
5
5
|
|
|
6
6
|
// src/commands/apply.ts
|
|
7
7
|
import { defineCommand } from "citty";
|
|
@@ -621,24 +621,21 @@ var CATEGORY_NAMES = {
|
|
|
621
621
|
resolution: "Resolution",
|
|
622
622
|
area: "Area"
|
|
623
623
|
};
|
|
624
|
-
function buildSystemPrompt(category, count
|
|
624
|
+
function buildSystemPrompt(category, count) {
|
|
625
625
|
const categoryTitle = CATEGORY_NAMES[category] ?? category;
|
|
626
626
|
const existingLabels = labels_default[category] ?? [];
|
|
627
627
|
const existingList = existingLabels.map((l) => ` - "${l.name}" (${l.color}) — ${l.description}`).join(`
|
|
628
628
|
`);
|
|
629
|
-
const variationHint = attempt > 1 ? `IMPORTANT: This is attempt #${attempt}. You MUST generate completely different label names, colors, and descriptions than any previous suggestions. Be creative and explore new angles.` : null;
|
|
630
629
|
return [
|
|
631
|
-
`You are a GitHub label generator.
|
|
630
|
+
`You are a GitHub label generator. Generate exactly ${count} label suggestions for the "${categoryTitle}" category.`,
|
|
632
631
|
"",
|
|
633
|
-
"CRITICAL: Every suggestion MUST be relevant to the user's description. Do NOT generate generic or unrelated labels. Focus on what the user specifically asked for.",
|
|
634
|
-
...variationHint ? ["", variationHint, ""] : [""],
|
|
635
632
|
"Each label must follow this exact JSON format:",
|
|
636
633
|
"[",
|
|
637
634
|
` { "name": "label-name", "color": "hex123", "description": "[${categoryTitle}] Description text [scope]" }`,
|
|
638
635
|
"]",
|
|
639
636
|
"",
|
|
640
637
|
"Rules:",
|
|
641
|
-
"- name: lowercase, concise (1-3 words), use spaces for multi-word names
|
|
638
|
+
"- name: lowercase, concise (1-3 words), use spaces for multi-word names",
|
|
642
639
|
"- color: 6-character hex without #, choose colors that are visually distinct from existing labels",
|
|
643
640
|
`- description: MUST start with [${categoryTitle}] and end with [issues], [PRs], or [issues, PRs]`,
|
|
644
641
|
"- Do NOT duplicate any of these existing labels:",
|
|
@@ -648,17 +645,12 @@ function buildSystemPrompt(category, count, attempt = 1) {
|
|
|
648
645
|
].join(`
|
|
649
646
|
`);
|
|
650
647
|
}
|
|
651
|
-
function buildUserPrompt(description, refinement
|
|
648
|
+
function buildUserPrompt(description, refinement) {
|
|
652
649
|
let prompt = `I need a label for: ${description}`;
|
|
653
650
|
if (refinement) {
|
|
654
651
|
prompt += `
|
|
655
652
|
|
|
656
653
|
Refinement feedback: ${refinement}`;
|
|
657
|
-
}
|
|
658
|
-
if (attempt > 1) {
|
|
659
|
-
prompt += `
|
|
660
|
-
|
|
661
|
-
Generate different suggestions from previous attempts. This is attempt #${attempt}, so provide fresh and unique alternatives.`;
|
|
662
654
|
}
|
|
663
655
|
return prompt;
|
|
664
656
|
}
|
|
@@ -691,13 +683,13 @@ function parseLabelsResponse(text) {
|
|
|
691
683
|
});
|
|
692
684
|
}
|
|
693
685
|
async function generateLabels(options) {
|
|
694
|
-
const { category, description, count = 3, refinement, model
|
|
686
|
+
const { category, description, count = 3, refinement, model } = options;
|
|
695
687
|
const client = new CopilotClient;
|
|
696
688
|
await client.start();
|
|
697
689
|
try {
|
|
698
690
|
const sessionConfig = {
|
|
699
691
|
systemMessage: {
|
|
700
|
-
content: buildSystemPrompt(category, count
|
|
692
|
+
content: buildSystemPrompt(category, count)
|
|
701
693
|
}
|
|
702
694
|
};
|
|
703
695
|
if (model) {
|
|
@@ -705,7 +697,7 @@ async function generateLabels(options) {
|
|
|
705
697
|
}
|
|
706
698
|
const session = await client.createSession(sessionConfig);
|
|
707
699
|
try {
|
|
708
|
-
const userPrompt = buildUserPrompt(description, refinement
|
|
700
|
+
const userPrompt = buildUserPrompt(description, refinement);
|
|
709
701
|
const response = await session.sendAndWait({ content: userPrompt });
|
|
710
702
|
if (!response || !response.data?.content) {
|
|
711
703
|
throw new Error("No response received from Copilot");
|
|
@@ -826,7 +818,6 @@ var generate_default = defineCommand3({
|
|
|
826
818
|
});
|
|
827
819
|
let selectedLabel = null;
|
|
828
820
|
let refinement;
|
|
829
|
-
let attempt = 1;
|
|
830
821
|
while (!selectedLabel) {
|
|
831
822
|
info(refinement ? "Regenerating with your feedback..." : "Generating label suggestions...");
|
|
832
823
|
let suggestions;
|
|
@@ -836,8 +827,7 @@ var generate_default = defineCommand3({
|
|
|
836
827
|
description,
|
|
837
828
|
count: 3,
|
|
838
829
|
refinement,
|
|
839
|
-
model: args.model
|
|
840
|
-
attempt
|
|
830
|
+
model: args.model
|
|
841
831
|
});
|
|
842
832
|
} catch (err) {
|
|
843
833
|
error(`Failed to generate labels: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -847,7 +837,6 @@ var generate_default = defineCommand3({
|
|
|
847
837
|
});
|
|
848
838
|
if (retry) {
|
|
849
839
|
refinement = undefined;
|
|
850
|
-
attempt = 1;
|
|
851
840
|
continue;
|
|
852
841
|
}
|
|
853
842
|
return;
|
|
@@ -884,12 +873,10 @@ var generate_default = defineCommand3({
|
|
|
884
873
|
message: "What would you like to change?",
|
|
885
874
|
validate: (value) => value.trim().length > 0 || "Please provide feedback."
|
|
886
875
|
});
|
|
887
|
-
attempt++;
|
|
888
876
|
continue;
|
|
889
877
|
}
|
|
890
878
|
if (choice === "regenerate") {
|
|
891
879
|
refinement = undefined;
|
|
892
|
-
attempt++;
|
|
893
880
|
continue;
|
|
894
881
|
}
|
|
895
882
|
const pickIndex = parseInt(choice.replace("pick:", ""), 10);
|
|
@@ -1076,167 +1063,13 @@ var list_default = defineCommand5({
|
|
|
1076
1063
|
}
|
|
1077
1064
|
});
|
|
1078
1065
|
|
|
1079
|
-
// src/commands/check.ts
|
|
1080
|
-
import { defineCommand as defineCommand6 } from "citty";
|
|
1081
|
-
import pc7 from "picocolors";
|
|
1082
|
-
function statusIcon(status) {
|
|
1083
|
-
if (status === "match")
|
|
1084
|
-
return pc7.green("✔");
|
|
1085
|
-
if (status === "missing")
|
|
1086
|
-
return pc7.red("✘");
|
|
1087
|
-
return pc7.yellow("~");
|
|
1088
|
-
}
|
|
1089
|
-
function statusLabel(status) {
|
|
1090
|
-
switch (status) {
|
|
1091
|
-
case "match":
|
|
1092
|
-
return pc7.dim("match");
|
|
1093
|
-
case "color-mismatch":
|
|
1094
|
-
return pc7.yellow("color mismatch");
|
|
1095
|
-
case "desc-mismatch":
|
|
1096
|
-
return pc7.yellow("description mismatch");
|
|
1097
|
-
case "both-mismatch":
|
|
1098
|
-
return pc7.yellow("color + description mismatch");
|
|
1099
|
-
case "missing":
|
|
1100
|
-
return pc7.red("missing");
|
|
1101
|
-
}
|
|
1102
|
-
}
|
|
1103
|
-
function isFailing(status, strict) {
|
|
1104
|
-
if (status === "missing")
|
|
1105
|
-
return true;
|
|
1106
|
-
if (strict && status !== "match")
|
|
1107
|
-
return true;
|
|
1108
|
-
return false;
|
|
1109
|
-
}
|
|
1110
|
-
var check_default = defineCommand6({
|
|
1111
|
-
meta: {
|
|
1112
|
-
name: "check",
|
|
1113
|
-
description: "Check if a repository is using the Clean Label template"
|
|
1114
|
-
},
|
|
1115
|
-
args: {
|
|
1116
|
-
repo: {
|
|
1117
|
-
type: "string",
|
|
1118
|
-
alias: "r",
|
|
1119
|
-
description: "Target repository (owner/repo). Defaults to current repo."
|
|
1120
|
-
},
|
|
1121
|
-
category: {
|
|
1122
|
-
type: "string",
|
|
1123
|
-
alias: "c",
|
|
1124
|
-
description: 'Check specific category(ies) only. Comma-separated (e.g., --category "type,status")'
|
|
1125
|
-
},
|
|
1126
|
-
strict: {
|
|
1127
|
-
type: "boolean",
|
|
1128
|
-
alias: "s",
|
|
1129
|
-
default: false,
|
|
1130
|
-
description: "Strict mode — also flag labels with mismatched color or description"
|
|
1131
|
-
}
|
|
1132
|
-
},
|
|
1133
|
-
async run({ args }) {
|
|
1134
|
-
if (!await checkGhInstalled()) {
|
|
1135
|
-
error("gh CLI is not installed. Install it from https://cli.github.com");
|
|
1136
|
-
process.exit(1);
|
|
1137
|
-
}
|
|
1138
|
-
if (!await checkGhAuth()) {
|
|
1139
|
-
error("Not authenticated. Run `gh auth login` first.");
|
|
1140
|
-
process.exit(1);
|
|
1141
|
-
}
|
|
1142
|
-
const repo = args.repo || await detectRepo();
|
|
1143
|
-
if (!repo) {
|
|
1144
|
-
error("Could not detect repository. Use --repo <owner/repo> or run inside a git repo.");
|
|
1145
|
-
process.exit(1);
|
|
1146
|
-
}
|
|
1147
|
-
const strict = args.strict ?? false;
|
|
1148
|
-
info(`Target: ${repo}`);
|
|
1149
|
-
if (strict)
|
|
1150
|
-
info("Mode: strict (name + color + description)");
|
|
1151
|
-
const repoLabels = await listLabelsDetailed(repo);
|
|
1152
|
-
const repoMap = new Map(repoLabels.map((l) => [l.name.toLowerCase(), l]));
|
|
1153
|
-
const { entries: templateEntries } = filterLabels(labels_default, {
|
|
1154
|
-
category: args.category
|
|
1155
|
-
});
|
|
1156
|
-
const results = [];
|
|
1157
|
-
for (const [category, categoryLabels] of templateEntries) {
|
|
1158
|
-
for (const tmpl of categoryLabels) {
|
|
1159
|
-
const existing = repoMap.get(tmpl.name.toLowerCase());
|
|
1160
|
-
let status;
|
|
1161
|
-
let repoColor;
|
|
1162
|
-
let repoDesc;
|
|
1163
|
-
if (!existing) {
|
|
1164
|
-
status = "missing";
|
|
1165
|
-
} else {
|
|
1166
|
-
const colorMatch = existing.color.toLowerCase() === tmpl.color.toLowerCase();
|
|
1167
|
-
const descMatch = existing.description.trim() === tmpl.description.trim();
|
|
1168
|
-
if (colorMatch && descMatch) {
|
|
1169
|
-
status = "match";
|
|
1170
|
-
} else if (!colorMatch && !descMatch) {
|
|
1171
|
-
status = "both-mismatch";
|
|
1172
|
-
repoColor = existing.color;
|
|
1173
|
-
repoDesc = existing.description;
|
|
1174
|
-
} else if (!colorMatch) {
|
|
1175
|
-
status = "color-mismatch";
|
|
1176
|
-
repoColor = existing.color;
|
|
1177
|
-
} else {
|
|
1178
|
-
status = "desc-mismatch";
|
|
1179
|
-
repoDesc = existing.description;
|
|
1180
|
-
}
|
|
1181
|
-
}
|
|
1182
|
-
results.push({ template: tmpl, category, status, repoColor, repoDesc });
|
|
1183
|
-
}
|
|
1184
|
-
}
|
|
1185
|
-
const byCategory = new Map;
|
|
1186
|
-
for (const result of results) {
|
|
1187
|
-
if (!byCategory.has(result.category))
|
|
1188
|
-
byCategory.set(result.category, []);
|
|
1189
|
-
byCategory.get(result.category).push(result);
|
|
1190
|
-
}
|
|
1191
|
-
console.log("");
|
|
1192
|
-
for (const [category, catResults] of byCategory) {
|
|
1193
|
-
const catTitle = category.charAt(0).toUpperCase() + category.slice(1);
|
|
1194
|
-
const catFailing = catResults.filter((r) => isFailing(r.status, strict)).length;
|
|
1195
|
-
const catStatus = catFailing > 0 ? pc7.red(`${catFailing} issue${catFailing !== 1 ? "s" : ""}`) : pc7.green("all good");
|
|
1196
|
-
console.log(`${pc7.bold(catTitle)} ${pc7.dim(`(${catResults.length})`)} — ${catStatus}`);
|
|
1197
|
-
for (const result of catResults) {
|
|
1198
|
-
const icon = statusIcon(result.status);
|
|
1199
|
-
const name = result.template.name.padEnd(28);
|
|
1200
|
-
const color = pc7.dim(`#${result.template.color}`);
|
|
1201
|
-
const lbl = statusLabel(result.status);
|
|
1202
|
-
let line = ` ${icon} ${name} ${color} ${lbl}`;
|
|
1203
|
-
if (result.repoColor) {
|
|
1204
|
-
line += pc7.dim(` (repo: #${result.repoColor})`);
|
|
1205
|
-
}
|
|
1206
|
-
if (result.repoDesc) {
|
|
1207
|
-
line += pc7.dim(`
|
|
1208
|
-
repo desc: "${result.repoDesc}"`);
|
|
1209
|
-
}
|
|
1210
|
-
console.log(line);
|
|
1211
|
-
}
|
|
1212
|
-
console.log("");
|
|
1213
|
-
}
|
|
1214
|
-
const matched = results.filter((r) => r.status === "match").length;
|
|
1215
|
-
const missing = results.filter((r) => r.status === "missing").length;
|
|
1216
|
-
const mismatched = results.filter((r) => r.status !== "match" && r.status !== "missing").length;
|
|
1217
|
-
const total = results.length;
|
|
1218
|
-
const failing = results.filter((r) => isFailing(r.status, strict)).length;
|
|
1219
|
-
const mismatchedStr = mismatched > 0 ? pc7.yellow(`, ${mismatched} mismatched`) : "";
|
|
1220
|
-
const missingStr = missing > 0 ? pc7.red(`, ${missing} missing`) : "";
|
|
1221
|
-
const scoreStr = pc7.bold(`${matched}/${total}`);
|
|
1222
|
-
console.log(`${pc7.bold("Result:")} ${scoreStr} labels matched${mismatchedStr}${missingStr}`);
|
|
1223
|
-
if (failing === 0) {
|
|
1224
|
-
const mismatchHint = !strict && mismatched > 0 ? pc7.dim(` (${mismatched} mismatch${mismatched !== 1 ? "es" : ""} — use --strict to enforce)`) : "";
|
|
1225
|
-
console.log(`${pc7.bold("Compatible:")} ${pc7.green("✔ Yes")}${strict ? " (strict)" : ""}${mismatchHint}`);
|
|
1226
|
-
} else {
|
|
1227
|
-
console.log(`${pc7.bold("Compatible:")} ${pc7.red("✘ No")} — run ${pc7.bold("ghlt apply")} to fix`);
|
|
1228
|
-
process.exit(1);
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
});
|
|
1232
|
-
|
|
1233
1066
|
// src/ui/banner.ts
|
|
1234
1067
|
import figlet from "figlet";
|
|
1235
|
-
import
|
|
1068
|
+
import pc7 from "picocolors";
|
|
1236
1069
|
// package.json
|
|
1237
1070
|
var package_default = {
|
|
1238
1071
|
name: "github-labels-template",
|
|
1239
|
-
version: "0.7.0
|
|
1072
|
+
version: "0.7.0",
|
|
1240
1073
|
description: "A CLI tool to apply a curated GitHub labels template to any repository using gh CLI.",
|
|
1241
1074
|
type: "module",
|
|
1242
1075
|
bin: {
|
|
@@ -1301,15 +1134,15 @@ function getAuthor() {
|
|
|
1301
1134
|
return package_default.author ?? "unknown";
|
|
1302
1135
|
}
|
|
1303
1136
|
function showBanner(minimal = false) {
|
|
1304
|
-
console.log(
|
|
1137
|
+
console.log(pc7.cyan(`
|
|
1305
1138
|
` + LOGO));
|
|
1306
|
-
console.log(` ${
|
|
1139
|
+
console.log(` ${pc7.dim("v" + getVersion())} ${pc7.dim("—")} ${pc7.dim("Built by " + getAuthor())}`);
|
|
1307
1140
|
if (!minimal) {
|
|
1308
|
-
console.log(` ${
|
|
1141
|
+
console.log(` ${pc7.dim(package_default.description)}`);
|
|
1309
1142
|
console.log();
|
|
1310
|
-
console.log(` ${
|
|
1311
|
-
console.log(` ${
|
|
1312
|
-
console.log(` ${
|
|
1143
|
+
console.log(` ${pc7.yellow("Star")} ${pc7.cyan("https://gh.waren.build/github-labels-template")}`);
|
|
1144
|
+
console.log(` ${pc7.green("Contribute")} ${pc7.cyan("https://gh.waren.build/github-labels-template/blob/main/CONTRIBUTING.md")}`);
|
|
1145
|
+
console.log(` ${pc7.magenta("Sponsor")} ${pc7.cyan("https://warengonzaga.com/sponsor")}`);
|
|
1313
1146
|
}
|
|
1314
1147
|
console.log();
|
|
1315
1148
|
}
|
|
@@ -1317,7 +1150,7 @@ function showBanner(minimal = false) {
|
|
|
1317
1150
|
// src/index.ts
|
|
1318
1151
|
var isHelp = process.argv.includes("--help") || process.argv.includes("-h");
|
|
1319
1152
|
showBanner(isHelp);
|
|
1320
|
-
var main =
|
|
1153
|
+
var main = defineCommand6({
|
|
1321
1154
|
meta: {
|
|
1322
1155
|
name: "ghlt",
|
|
1323
1156
|
version: getVersion(),
|
|
@@ -1335,8 +1168,7 @@ var main = defineCommand7({
|
|
|
1335
1168
|
wipe: wipe_default,
|
|
1336
1169
|
migrate: migrate_default,
|
|
1337
1170
|
generate: generate_default,
|
|
1338
|
-
list: list_default
|
|
1339
|
-
check: check_default
|
|
1171
|
+
list: list_default
|
|
1340
1172
|
},
|
|
1341
1173
|
run({ args }) {
|
|
1342
1174
|
if (args.version) {
|