contribute-now 0.9.0-dev.30c88ec → 0.9.0-dev.8626d97

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.
Files changed (2) hide show
  1. package/dist/cli.js +45 -7
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -13705,7 +13705,7 @@ var import_picocolors12 = __toESM(require_picocolors(), 1);
13705
13705
  // package.json
13706
13706
  var package_default = {
13707
13707
  name: "contribute-now",
13708
- version: "0.9.0-dev.30c88ec",
13708
+ version: "0.9.0-dev.8626d97",
13709
13709
  description: "Developer CLI that automates git workflows \u2014 branching, syncing, committing, and PRs \u2014 with multi-workflow and commit convention support.",
13710
13710
  type: "module",
13711
13711
  bin: {
@@ -14282,8 +14282,8 @@ async function uninstallHook() {
14282
14282
 
14283
14283
  // src/commands/label.ts
14284
14284
  init_config();
14285
- init_gh();
14286
14285
  var import_picocolors14 = __toESM(require_picocolors(), 1);
14286
+ init_gh();
14287
14287
 
14288
14288
  // src/utils/label.ts
14289
14289
  import { existsSync as existsSync7, mkdirSync as mkdirSync6, readFileSync as readFileSync6, statSync as statSync4, writeFileSync as writeFileSync6 } from "fs";
@@ -14651,6 +14651,7 @@ function toBigrams(text) {
14651
14651
 
14652
14652
  // src/commands/label.ts
14653
14653
  init_logger2();
14654
+ init_tips();
14654
14655
  async function requireGitRepository() {
14655
14656
  if (!await isGitRepo()) {
14656
14657
  error("Not inside a git repository.");
@@ -14690,6 +14691,13 @@ function extractLabelsCsv(rawArgs) {
14690
14691
  function formatSourceNote(source) {
14691
14692
  return source === "clean-labels" ? "(source: Clean Labels dataset)" : "(source: repo labels)";
14692
14693
  }
14694
+ function getLabelCategory(label) {
14695
+ const match = /^\s*\[([^\]]+)\]/.exec(label.description ?? "");
14696
+ if (!match || !match[1]) {
14697
+ return null;
14698
+ }
14699
+ return match[1].trim().toLowerCase() || null;
14700
+ }
14693
14701
  function parsePositiveIntArg(value, fallback, fieldName) {
14694
14702
  if (value === undefined || value === null || value.trim() === "") {
14695
14703
  return fallback;
@@ -14755,7 +14763,24 @@ ${target.body}`, availableLabels);
14755
14763
  }
14756
14764
  }
14757
14765
  const existing = new Set(target.existingLabels.map((name) => normalizeLabelName(name)));
14758
- const selected = ranked.filter((item) => item.score >= minScore).filter((item) => !existing.has(normalizeLabelName(item.label.name))).slice(0, count);
14766
+ const candidates = ranked.filter((item) => item.score >= minScore).filter((item) => !existing.has(normalizeLabelName(item.label.name)));
14767
+ let selected = [];
14768
+ if (options.defaultPerCategory) {
14769
+ const seenCategories = new Set;
14770
+ for (const item of candidates) {
14771
+ const category = getLabelCategory(item.label);
14772
+ if (!category || seenCategories.has(category)) {
14773
+ continue;
14774
+ }
14775
+ selected.push(item);
14776
+ seenCategories.add(category);
14777
+ }
14778
+ if (selected.length === 0) {
14779
+ selected = candidates.slice(0, 1);
14780
+ }
14781
+ } else {
14782
+ selected = candidates.slice(0, count ?? 1);
14783
+ }
14759
14784
  if (selected.length === 0) {
14760
14785
  continue;
14761
14786
  }
@@ -15017,7 +15042,7 @@ var applyCommand = defineCommand({
15017
15042
  },
15018
15043
  count: {
15019
15044
  type: "string",
15020
- description: "Max labels to apply per item (default: 1)"
15045
+ description: "Max labels to apply per item (default: one per category when labels include [Category] tags, otherwise 1)"
15021
15046
  },
15022
15047
  "min-score": {
15023
15048
  type: "string",
@@ -15066,7 +15091,7 @@ var applyCommand = defineCommand({
15066
15091
  warn("--unlabeled-only has no effect in single-target mode (--issue / --pr).");
15067
15092
  }
15068
15093
  const limit = parsePositiveIntArg(args.limit, 20, "limit");
15069
- const count = parsePositiveIntArg(args.count, 1, "count");
15094
+ const count = args.count ? parsePositiveIntArg(args.count, 1, "count") : undefined;
15070
15095
  const minScore = parseNonNegativeIntArg(args["min-score"], 4, "min-score");
15071
15096
  const effectiveDryRun = Boolean(args["dry-run"]) || isBulk && !args.yes;
15072
15097
  const config = readConfig();
@@ -15146,12 +15171,25 @@ var applyCommand = defineCommand({
15146
15171
  return;
15147
15172
  }
15148
15173
  }
15174
+ const planSpinner = useAI ? createSpinner(isBulk ? `Generating AI label suggestions for ${targets.length} item(s)...` : "Generating AI label suggestions...", { tips: LOADING_TIPS }) : null;
15175
+ const defaultPerCategory = !count;
15149
15176
  const plans = await buildApplyPlan(targets, cacheRef.current.labels, count, minScore, {
15150
15177
  useAI,
15151
- model: args.model
15178
+ model: args.model,
15179
+ defaultPerCategory
15152
15180
  });
15181
+ if (planSpinner) {
15182
+ const aiBackedCount = plans.filter((plan) => plan.source === "ai").length;
15183
+ if (aiBackedCount > 0) {
15184
+ planSpinner.success(`AI label suggestions ready for ${aiBackedCount} item(s).`);
15185
+ } else {
15186
+ planSpinner.success("Label suggestions ready (heuristic fallback used).");
15187
+ }
15188
+ }
15153
15189
  if (plans.length === 0) {
15154
- info(`No labels qualified for auto-apply (count=${count}, min-score=${minScore}). Try lowering --min-score.`);
15190
+ const selectionMode = defaultPerCategory ? "per-category default" : `count=${count ?? 1}`;
15191
+ info(`No labels qualified for auto-apply (${selectionMode}, min-score=${minScore}).`);
15192
+ info("Try lowering --min-score or increasing --count.");
15155
15193
  return;
15156
15194
  }
15157
15195
  console.log();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "contribute-now",
3
- "version": "0.9.0-dev.30c88ec",
3
+ "version": "0.9.0-dev.8626d97",
4
4
  "description": "Developer CLI that automates git workflows — branching, syncing, committing, and PRs — with multi-workflow and commit convention support.",
5
5
  "type": "module",
6
6
  "bin": {