contribute-now 0.5.0-dev.914e35d → 0.5.0-dev.9ad3d01

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/index.js +191 -446
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import { createRequire } from "node:module";
3
3
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
4
4
 
5
5
  // src/index.ts
6
- import { defineCommand as defineCommand16, runMain } from "citty";
6
+ import { defineCommand as defineCommand14, runMain } from "citty";
7
7
 
8
8
  // src/commands/branch.ts
9
9
  import { defineCommand } from "citty";
@@ -2268,7 +2268,7 @@ import pc7 from "picocolors";
2268
2268
  // package.json
2269
2269
  var package_default = {
2270
2270
  name: "contribute-now",
2271
- version: "0.5.0-dev.914e35d",
2271
+ version: "0.5.0-dev.9ad3d01",
2272
2272
  description: "Developer CLI that automates git workflows — branching, syncing, committing, and PRs — with multi-workflow and commit convention support.",
2273
2273
  type: "module",
2274
2274
  bin: {
@@ -3090,161 +3090,9 @@ function colorizeSubject(subject) {
3090
3090
  return pc9.white(subject);
3091
3091
  }
3092
3092
 
3093
- // src/commands/save.ts
3093
+ // src/commands/setup.ts
3094
3094
  import { defineCommand as defineCommand7 } from "citty";
3095
3095
  import pc10 from "picocolors";
3096
- import { execFile as execFileCb4 } from "node:child_process";
3097
- function gitRun(args) {
3098
- return new Promise((resolve) => {
3099
- execFileCb4("git", args, (err, stdout, stderr) => {
3100
- resolve({
3101
- exitCode: err ? err.code === "ENOENT" ? 127 : err.status ?? 1 : 0,
3102
- stdout: stdout ?? "",
3103
- stderr: stderr ?? ""
3104
- });
3105
- });
3106
- });
3107
- }
3108
- var save_default = defineCommand7({
3109
- meta: {
3110
- name: "save",
3111
- description: "Save, restore, or manage uncommitted changes"
3112
- },
3113
- args: {
3114
- action: {
3115
- type: "positional",
3116
- description: "Action: save (default), restore, list, drop",
3117
- required: false
3118
- },
3119
- message: {
3120
- type: "string",
3121
- alias: "m",
3122
- description: "Description for saved changes"
3123
- }
3124
- },
3125
- async run({ args }) {
3126
- if (!await isGitRepo()) {
3127
- error("Not inside a git repository.");
3128
- process.exit(1);
3129
- }
3130
- const action = args.action ?? "save";
3131
- switch (action) {
3132
- case "save":
3133
- await handleSave(args.message);
3134
- break;
3135
- case "restore":
3136
- await handleRestore();
3137
- break;
3138
- case "list":
3139
- await handleList();
3140
- break;
3141
- case "drop":
3142
- await handleDrop();
3143
- break;
3144
- default:
3145
- error(`Unknown action: ${action}. Use save, restore, list, or drop.`);
3146
- process.exit(1);
3147
- }
3148
- }
3149
- });
3150
- async function handleSave(message) {
3151
- heading("\uD83D\uDCBE contrib save");
3152
- const currentBranch = await getCurrentBranch();
3153
- const label = message ?? `work-in-progress on ${currentBranch ?? "unknown"}`;
3154
- const stashMsg = `contrib-save: ${label}`;
3155
- const result = await gitRun(["stash", "push", "-m", stashMsg]);
3156
- if (result.exitCode !== 0) {
3157
- error(`Failed to save: ${result.stderr}`);
3158
- process.exit(1);
3159
- }
3160
- if (result.stdout.includes("No local changes to save")) {
3161
- info("No uncommitted changes to save.");
3162
- return;
3163
- }
3164
- success(`Saved: ${pc10.dim(label)}`);
3165
- info(`Use ${pc10.bold("contrib save restore")} to bring them back.`);
3166
- }
3167
- async function handleRestore() {
3168
- heading("\uD83D\uDCBE contrib save restore");
3169
- const stashes = await getStashList();
3170
- if (stashes.length === 0) {
3171
- info("No saved changes found.");
3172
- return;
3173
- }
3174
- if (stashes.length === 1) {
3175
- const result2 = await gitRun(["stash", "pop", "stash@{0}"]);
3176
- if (result2.exitCode !== 0) {
3177
- error(`Failed to restore: ${result2.stderr}`);
3178
- warn("You may have conflicts. Resolve them and run `git stash drop` when done.");
3179
- process.exit(1);
3180
- }
3181
- success(`Restored: ${pc10.dim(stashes[0].message)}`);
3182
- return;
3183
- }
3184
- const choices = stashes.map((s) => `${s.index} ${s.message}`);
3185
- const selected = await selectPrompt("Which save to restore?", choices);
3186
- const idx = selected.split(/\s{2,}/)[0].trim();
3187
- const result = await gitRun(["stash", "pop", `stash@{${idx}}`]);
3188
- if (result.exitCode !== 0) {
3189
- error(`Failed to restore: ${result.stderr}`);
3190
- warn("You may have conflicts. Resolve them and run `git stash drop` when done.");
3191
- process.exit(1);
3192
- }
3193
- const match = stashes.find((s) => String(s.index) === idx);
3194
- success(`Restored: ${pc10.dim(match?.message ?? "saved changes")}`);
3195
- }
3196
- async function handleList() {
3197
- heading("\uD83D\uDCBE contrib save list");
3198
- const stashes = await getStashList();
3199
- if (stashes.length === 0) {
3200
- info("No saved changes.");
3201
- return;
3202
- }
3203
- console.log();
3204
- for (const s of stashes) {
3205
- const idx = pc10.dim(`[${s.index}]`);
3206
- const msg = s.message;
3207
- console.log(` ${idx} ${msg}`);
3208
- }
3209
- console.log();
3210
- info(`Use ${pc10.bold("contrib save restore")} to bring changes back.`);
3211
- info(`Use ${pc10.bold("contrib save drop")} to discard saved changes.`);
3212
- }
3213
- async function handleDrop() {
3214
- heading("\uD83D\uDCBE contrib save drop");
3215
- const stashes = await getStashList();
3216
- if (stashes.length === 0) {
3217
- info("No saved changes to drop.");
3218
- return;
3219
- }
3220
- const choices = stashes.map((s) => `${s.index} ${s.message}`);
3221
- const selected = await selectPrompt("Which save to drop?", choices);
3222
- const idx = selected.split(/\s{2,}/)[0].trim();
3223
- const result = await gitRun(["stash", "drop", `stash@{${idx}}`]);
3224
- if (result.exitCode !== 0) {
3225
- error(`Failed to drop: ${result.stderr}`);
3226
- process.exit(1);
3227
- }
3228
- const match = stashes.find((s) => String(s.index) === idx);
3229
- success(`Dropped: ${pc10.dim(match?.message ?? "saved changes")}`);
3230
- }
3231
- async function getStashList() {
3232
- const result = await gitRun(["stash", "list"]);
3233
- if (result.exitCode !== 0 || !result.stdout.trim())
3234
- return [];
3235
- return result.stdout.trimEnd().split(`
3236
- `).filter(Boolean).map((line) => {
3237
- const idxMatch = line.match(/^stash@\{(\d+)\}/);
3238
- const index = idxMatch ? Number.parseInt(idxMatch[1], 10) : 0;
3239
- const parts = line.split(": ");
3240
- const message = parts.length > 2 ? parts.slice(2).join(": ") : parts[parts.length - 1];
3241
- return { index, message };
3242
- });
3243
- }
3244
-
3245
- // src/commands/setup.ts
3246
- import { defineCommand as defineCommand8 } from "citty";
3247
- import pc11 from "picocolors";
3248
3096
  async function shouldContinueSetupWithExistingConfig(options) {
3249
3097
  const {
3250
3098
  existingConfig,
@@ -3282,7 +3130,7 @@ async function shouldContinueSetupWithExistingConfig(options) {
3282
3130
  }
3283
3131
  return true;
3284
3132
  }
3285
- var setup_default = defineCommand8({
3133
+ var setup_default = defineCommand7({
3286
3134
  meta: {
3287
3135
  name: "setup",
3288
3136
  description: "Initialize contribute-now config for this repo (.contributerc.json)"
@@ -3317,7 +3165,7 @@ var setup_default = defineCommand8({
3317
3165
  workflow = "github-flow";
3318
3166
  else if (workflowChoice.startsWith("Git Flow"))
3319
3167
  workflow = "git-flow";
3320
- info(`Workflow: ${pc11.bold(WORKFLOW_DESCRIPTIONS[workflow])}`);
3168
+ info(`Workflow: ${pc10.bold(WORKFLOW_DESCRIPTIONS[workflow])}`);
3321
3169
  const conventionChoice = await selectPrompt("Which commit convention should this project use?", [
3322
3170
  `${CONVENTION_DESCRIPTIONS["clean-commit"]} (recommended)`,
3323
3171
  CONVENTION_DESCRIPTIONS.conventional,
@@ -3381,15 +3229,15 @@ var setup_default = defineCommand8({
3381
3229
  detectedRole = roleChoice;
3382
3230
  detectionSource = "user selection";
3383
3231
  } else {
3384
- info(`Detected role: ${pc11.bold(detectedRole)} (via ${detectionSource})`);
3385
- const confirmed = await confirmPrompt(`Role detected as ${pc11.bold(detectedRole)}. Is this correct?`);
3232
+ info(`Detected role: ${pc10.bold(detectedRole)} (via ${detectionSource})`);
3233
+ const confirmed = await confirmPrompt(`Role detected as ${pc10.bold(detectedRole)}. Is this correct?`);
3386
3234
  if (!confirmed) {
3387
3235
  const roleChoice = await selectPrompt("Select your role:", ["maintainer", "contributor"]);
3388
3236
  detectedRole = roleChoice;
3389
3237
  }
3390
3238
  }
3391
3239
  const defaultConfig = getDefaultConfig();
3392
- info(pc11.dim("Tip: press Enter to keep the default branch name shown in each prompt."));
3240
+ info(pc10.dim("Tip: press Enter to keep the default branch name shown in each prompt."));
3393
3241
  const mainBranchDefault = defaultConfig.mainBranch;
3394
3242
  const mainBranch = await inputPrompt(`Main branch name (default: ${mainBranchDefault} — press Enter to keep)`, mainBranchDefault);
3395
3243
  let devBranch;
@@ -3415,7 +3263,7 @@ var setup_default = defineCommand8({
3415
3263
  error("Setup cannot continue without the upstream remote for contributors.");
3416
3264
  process.exit(1);
3417
3265
  }
3418
- success(`Added remote ${pc11.bold(upstreamRemote)} → ${upstreamUrl}`);
3266
+ success(`Added remote ${pc10.bold(upstreamRemote)} → ${upstreamUrl}`);
3419
3267
  } else {
3420
3268
  error("An upstream remote URL is required for contributors.");
3421
3269
  info("Add it manually: git remote add upstream <url>");
@@ -3436,17 +3284,17 @@ var setup_default = defineCommand8({
3436
3284
  writeConfig(config);
3437
3285
  success(`✅ Config written to .contributerc.json`);
3438
3286
  const syncRemote = config.role === "contributor" ? config.upstream : config.origin;
3439
- info(`Fetching ${pc11.bold(syncRemote)} to verify branch configuration...`);
3287
+ info(`Fetching ${pc10.bold(syncRemote)} to verify branch configuration...`);
3440
3288
  await fetchRemote(syncRemote);
3441
3289
  const mainRef = `${syncRemote}/${config.mainBranch}`;
3442
3290
  if (!await refExists(mainRef)) {
3443
- warn(`Main branch ref ${pc11.bold(mainRef)} not found on remote.`);
3291
+ warn(`Main branch ref ${pc10.bold(mainRef)} not found on remote.`);
3444
3292
  warn("Config was saved — verify the branch name and re-run setup if needed.");
3445
3293
  }
3446
3294
  if (config.devBranch) {
3447
3295
  const devRef = `${syncRemote}/${config.devBranch}`;
3448
3296
  if (!await refExists(devRef)) {
3449
- warn(`Dev branch ref ${pc11.bold(devRef)} not found on remote.`);
3297
+ warn(`Dev branch ref ${pc10.bold(devRef)} not found on remote.`);
3450
3298
  warn("Config was saved — verify the branch name and re-run setup if needed.");
3451
3299
  }
3452
3300
  }
@@ -3454,33 +3302,33 @@ var setup_default = defineCommand8({
3454
3302
  info("Added .contributerc.json to .gitignore to avoid committing personal config.");
3455
3303
  }
3456
3304
  console.log();
3457
- info(`Workflow: ${pc11.bold(WORKFLOW_DESCRIPTIONS[config.workflow])}`);
3458
- info(`Convention: ${pc11.bold(CONVENTION_DESCRIPTIONS[config.commitConvention])}`);
3459
- info(`Role: ${pc11.bold(config.role)}`);
3305
+ info(`Workflow: ${pc10.bold(WORKFLOW_DESCRIPTIONS[config.workflow])}`);
3306
+ info(`Convention: ${pc10.bold(CONVENTION_DESCRIPTIONS[config.commitConvention])}`);
3307
+ info(`Role: ${pc10.bold(config.role)}`);
3460
3308
  if (config.devBranch) {
3461
- info(`Main: ${pc11.bold(config.mainBranch)} | Dev: ${pc11.bold(config.devBranch)}`);
3309
+ info(`Main: ${pc10.bold(config.mainBranch)} | Dev: ${pc10.bold(config.devBranch)}`);
3462
3310
  } else {
3463
- info(`Main: ${pc11.bold(config.mainBranch)}`);
3311
+ info(`Main: ${pc10.bold(config.mainBranch)}`);
3464
3312
  }
3465
- info(`Origin: ${pc11.bold(config.origin)}${config.role === "contributor" ? ` | Upstream: ${pc11.bold(config.upstream)}` : ""}`);
3313
+ info(`Origin: ${pc10.bold(config.origin)}${config.role === "contributor" ? ` | Upstream: ${pc10.bold(config.upstream)}` : ""}`);
3466
3314
  }
3467
3315
  });
3468
3316
  function logConfigSummary(config) {
3469
- info(`Workflow: ${pc11.bold(WORKFLOW_DESCRIPTIONS[config.workflow])}`);
3470
- info(`Convention: ${pc11.bold(CONVENTION_DESCRIPTIONS[config.commitConvention])}`);
3471
- info(`Role: ${pc11.bold(config.role)}`);
3317
+ info(`Workflow: ${pc10.bold(WORKFLOW_DESCRIPTIONS[config.workflow])}`);
3318
+ info(`Convention: ${pc10.bold(CONVENTION_DESCRIPTIONS[config.commitConvention])}`);
3319
+ info(`Role: ${pc10.bold(config.role)}`);
3472
3320
  if (config.devBranch) {
3473
- info(`Main: ${pc11.bold(config.mainBranch)} | Dev: ${pc11.bold(config.devBranch)}`);
3321
+ info(`Main: ${pc10.bold(config.mainBranch)} | Dev: ${pc10.bold(config.devBranch)}`);
3474
3322
  } else {
3475
- info(`Main: ${pc11.bold(config.mainBranch)}`);
3323
+ info(`Main: ${pc10.bold(config.mainBranch)}`);
3476
3324
  }
3477
- info(`Origin: ${pc11.bold(config.origin)}${config.role === "contributor" ? ` | Upstream: ${pc11.bold(config.upstream)}` : ""}`);
3325
+ info(`Origin: ${pc10.bold(config.origin)}${config.role === "contributor" ? ` | Upstream: ${pc10.bold(config.upstream)}` : ""}`);
3478
3326
  }
3479
3327
 
3480
3328
  // src/commands/start.ts
3481
- import { defineCommand as defineCommand9 } from "citty";
3482
- import pc12 from "picocolors";
3483
- var start_default = defineCommand9({
3329
+ import { defineCommand as defineCommand8 } from "citty";
3330
+ import pc11 from "picocolors";
3331
+ var start_default = defineCommand8({
3484
3332
  meta: {
3485
3333
  name: "start",
3486
3334
  description: "Create a new feature branch from the latest base branch"
@@ -3536,8 +3384,8 @@ var start_default = defineCommand9({
3536
3384
  if (suggested) {
3537
3385
  spinner.success("Branch name suggestion ready.");
3538
3386
  console.log(`
3539
- ${pc12.dim("AI suggestion:")} ${pc12.bold(pc12.cyan(suggested))}`);
3540
- const accepted = await confirmPrompt(`Use ${pc12.bold(suggested)} as your branch name?`);
3387
+ ${pc11.dim("AI suggestion:")} ${pc11.bold(pc11.cyan(suggested))}`);
3388
+ const accepted = await confirmPrompt(`Use ${pc11.bold(suggested)} as your branch name?`);
3541
3389
  if (accepted) {
3542
3390
  branchName = suggested;
3543
3391
  } else {
@@ -3548,28 +3396,28 @@ var start_default = defineCommand9({
3548
3396
  }
3549
3397
  }
3550
3398
  if (!hasPrefix(branchName, branchPrefixes)) {
3551
- const prefix = await selectPrompt(`Choose a branch type for ${pc12.bold(branchName)}:`, branchPrefixes);
3399
+ const prefix = await selectPrompt(`Choose a branch type for ${pc11.bold(branchName)}:`, branchPrefixes);
3552
3400
  branchName = formatBranchName(prefix, branchName);
3553
3401
  }
3554
3402
  if (!isValidBranchName(branchName)) {
3555
3403
  error("Invalid branch name. Use only alphanumeric characters, dots, hyphens, underscores, and slashes.");
3556
3404
  process.exit(1);
3557
3405
  }
3558
- info(`Creating branch: ${pc12.bold(branchName)}`);
3406
+ info(`Creating branch: ${pc11.bold(branchName)}`);
3559
3407
  if (await branchExists(branchName)) {
3560
- error(`Branch ${pc12.bold(branchName)} already exists.`);
3561
- info(` Use ${pc12.bold(`git checkout ${branchName}`)} to switch to it, or choose a different name.`);
3408
+ error(`Branch ${pc11.bold(branchName)} already exists.`);
3409
+ info(` Use ${pc11.bold(`git checkout ${branchName}`)} to switch to it, or choose a different name.`);
3562
3410
  process.exit(1);
3563
3411
  }
3564
3412
  await fetchRemote(syncSource.remote);
3565
3413
  if (!await refExists(syncSource.ref)) {
3566
- warn(`Remote ref ${pc12.bold(syncSource.ref)} not found. Creating branch from local ${pc12.bold(baseBranch)}.`);
3414
+ warn(`Remote ref ${pc11.bold(syncSource.ref)} not found. Creating branch from local ${pc11.bold(baseBranch)}.`);
3567
3415
  }
3568
3416
  const currentBranch = await getCurrentBranch();
3569
3417
  if (currentBranch === baseBranch && await refExists(syncSource.ref)) {
3570
3418
  const ahead = await countCommitsAhead(baseBranch, syncSource.ref);
3571
3419
  if (ahead > 0) {
3572
- warn(`You are on ${pc12.bold(baseBranch)} with ${pc12.bold(String(ahead))} local commit${ahead > 1 ? "s" : ""} not in ${pc12.bold(syncSource.ref)}.`);
3420
+ warn(`You are on ${pc11.bold(baseBranch)} with ${pc11.bold(String(ahead))} local commit${ahead > 1 ? "s" : ""} not in ${pc11.bold(syncSource.ref)}.`);
3573
3421
  info(" Syncing will discard those commits. Consider backing them up first (e.g. create a branch).");
3574
3422
  const proceed = await confirmPrompt("Discard local commits and sync to remote?");
3575
3423
  if (!proceed) {
@@ -3586,10 +3434,10 @@ var start_default = defineCommand9({
3586
3434
  error(`Failed to create branch: ${result2.stderr}`);
3587
3435
  process.exit(1);
3588
3436
  }
3589
- success(`✅ Created ${pc12.bold(branchName)} from ${pc12.bold(syncSource.ref)}`);
3437
+ success(`✅ Created ${pc11.bold(branchName)} from ${pc11.bold(syncSource.ref)}`);
3590
3438
  return;
3591
3439
  }
3592
- error(`Failed to update ${pc12.bold(baseBranch)}: ${updateResult.stderr}`);
3440
+ error(`Failed to update ${pc11.bold(baseBranch)}: ${updateResult.stderr}`);
3593
3441
  info("Make sure your base branch exists locally or the remote ref is available.");
3594
3442
  process.exit(1);
3595
3443
  }
@@ -3598,14 +3446,14 @@ var start_default = defineCommand9({
3598
3446
  error(`Failed to create branch: ${result.stderr}`);
3599
3447
  process.exit(1);
3600
3448
  }
3601
- success(`✅ Created ${pc12.bold(branchName)} from latest ${pc12.bold(baseBranch)}`);
3449
+ success(`✅ Created ${pc11.bold(branchName)} from latest ${pc11.bold(baseBranch)}`);
3602
3450
  }
3603
3451
  });
3604
3452
 
3605
3453
  // src/commands/status.ts
3606
- import { defineCommand as defineCommand10 } from "citty";
3607
- import pc13 from "picocolors";
3608
- var status_default = defineCommand10({
3454
+ import { defineCommand as defineCommand9 } from "citty";
3455
+ import pc12 from "picocolors";
3456
+ var status_default = defineCommand9({
3609
3457
  meta: {
3610
3458
  name: "status",
3611
3459
  description: "Show sync status of branches"
@@ -3621,8 +3469,8 @@ var status_default = defineCommand10({
3621
3469
  process.exit(1);
3622
3470
  }
3623
3471
  heading("\uD83D\uDCCA contribute-now status");
3624
- console.log(` ${pc13.dim("Workflow:")} ${pc13.bold(WORKFLOW_DESCRIPTIONS[config.workflow])}`);
3625
- console.log(` ${pc13.dim("Role:")} ${pc13.bold(config.role)}`);
3472
+ console.log(` ${pc12.dim("Workflow:")} ${pc12.bold(WORKFLOW_DESCRIPTIONS[config.workflow])}`);
3473
+ console.log(` ${pc12.dim("Role:")} ${pc12.bold(config.role)}`);
3626
3474
  console.log();
3627
3475
  await fetchAll();
3628
3476
  const currentBranch = await getCurrentBranch();
@@ -3631,7 +3479,7 @@ var status_default = defineCommand10({
3631
3479
  const isContributor = config.role === "contributor";
3632
3480
  const [dirty, fileStatus] = await Promise.all([hasUncommittedChanges(), getFileStatus()]);
3633
3481
  if (dirty) {
3634
- console.log(` ${pc13.yellow("⚠")} ${pc13.yellow("Uncommitted changes in working tree")}`);
3482
+ console.log(` ${pc12.yellow("⚠")} ${pc12.yellow("Uncommitted changes in working tree")}`);
3635
3483
  console.log();
3636
3484
  }
3637
3485
  const mainRemote = `${origin}/${mainBranch}`;
@@ -3650,82 +3498,82 @@ var status_default = defineCommand10({
3650
3498
  if (isFeatureBranch) {
3651
3499
  const branchDiv = await getDivergence(currentBranch, baseBranch);
3652
3500
  const branchLine = formatStatus(currentBranch, baseBranch, branchDiv.ahead, branchDiv.behind);
3653
- console.log(branchLine + pc13.dim(` (current ${pc13.green("*")})`));
3501
+ console.log(branchLine + pc12.dim(` (current ${pc12.green("*")})`));
3654
3502
  branchStatus = await detectBranchStatus(currentBranch, baseBranch);
3655
3503
  if (branchStatus.merged) {
3656
- console.log(` ${pc13.green("✓")} ${pc13.green("Branch merged")} — ${pc13.dim(branchStatus.mergedReason ?? "all commits reachable from base")}`);
3504
+ console.log(` ${pc12.green("✓")} ${pc12.green("Branch merged")} — ${pc12.dim(branchStatus.mergedReason ?? "all commits reachable from base")}`);
3657
3505
  }
3658
3506
  if (branchStatus.stale) {
3659
- console.log(` ${pc13.yellow("⏳")} ${pc13.yellow("Branch is stale")} — ${pc13.dim(`last commit ${branchStatus.staleDaysAgo} days ago`)}`);
3507
+ console.log(` ${pc12.yellow("⏳")} ${pc12.yellow("Branch is stale")} — ${pc12.dim(`last commit ${branchStatus.staleDaysAgo} days ago`)}`);
3660
3508
  }
3661
3509
  } else if (currentBranch) {
3662
- console.log(pc13.dim(` (on ${pc13.bold(currentBranch)} branch)`));
3510
+ console.log(pc12.dim(` (on ${pc12.bold(currentBranch)} branch)`));
3663
3511
  }
3664
3512
  const hasFiles = fileStatus.staged.length > 0 || fileStatus.modified.length > 0 || fileStatus.untracked.length > 0;
3665
3513
  if (hasFiles) {
3666
3514
  console.log();
3667
3515
  if (fileStatus.staged.length > 0) {
3668
- console.log(` ${pc13.green("Staged for commit:")}`);
3516
+ console.log(` ${pc12.green("Staged for commit:")}`);
3669
3517
  for (const { file, status } of fileStatus.staged) {
3670
- console.log(` ${pc13.green("+")} ${pc13.dim(`${status}:`)} ${file}`);
3518
+ console.log(` ${pc12.green("+")} ${pc12.dim(`${status}:`)} ${file}`);
3671
3519
  }
3672
3520
  }
3673
3521
  if (fileStatus.modified.length > 0) {
3674
- console.log(` ${pc13.yellow("Unstaged changes:")}`);
3522
+ console.log(` ${pc12.yellow("Unstaged changes:")}`);
3675
3523
  for (const { file, status } of fileStatus.modified) {
3676
- console.log(` ${pc13.yellow("~")} ${pc13.dim(`${status}:`)} ${file}`);
3524
+ console.log(` ${pc12.yellow("~")} ${pc12.dim(`${status}:`)} ${file}`);
3677
3525
  }
3678
3526
  }
3679
3527
  if (fileStatus.untracked.length > 0) {
3680
- console.log(` ${pc13.red("Untracked files:")}`);
3528
+ console.log(` ${pc12.red("Untracked files:")}`);
3681
3529
  for (const file of fileStatus.untracked) {
3682
- console.log(` ${pc13.red("?")} ${file}`);
3530
+ console.log(` ${pc12.red("?")} ${file}`);
3683
3531
  }
3684
3532
  }
3685
3533
  } else if (!dirty) {
3686
- console.log(` ${pc13.green("✓")} ${pc13.dim("Working tree clean")}`);
3534
+ console.log(` ${pc12.green("✓")} ${pc12.dim("Working tree clean")}`);
3687
3535
  }
3688
3536
  const tips = [];
3689
3537
  if (fileStatus.staged.length > 0) {
3690
- tips.push(`Run ${pc13.bold("contrib commit")} to commit staged changes`);
3538
+ tips.push(`Run ${pc12.bold("contrib commit")} to commit staged changes`);
3691
3539
  }
3692
3540
  if (fileStatus.modified.length > 0 || fileStatus.untracked.length > 0) {
3693
- tips.push(`Run ${pc13.bold("contrib commit")} to stage and commit changes`);
3541
+ tips.push(`Run ${pc12.bold("contrib commit")} to stage and commit changes`);
3694
3542
  }
3695
3543
  if (isFeatureBranch && branchStatus) {
3696
3544
  if (branchStatus.merged) {
3697
- tips.push(`Run ${pc13.bold("contrib clean")} to delete this merged branch`);
3545
+ tips.push(`Run ${pc12.bold("contrib clean")} to delete this merged branch`);
3698
3546
  } else if (branchStatus.stale) {
3699
- tips.push(`Run ${pc13.bold("contrib sync")} to rebase on latest changes, or ${pc13.bold("contrib clean")} if no longer needed`);
3547
+ tips.push(`Run ${pc12.bold("contrib sync")} to rebase on latest changes, or ${pc12.bold("contrib clean")} if no longer needed`);
3700
3548
  } else if (fileStatus.staged.length === 0 && fileStatus.modified.length === 0 && fileStatus.untracked.length === 0) {
3701
3549
  const branchDiv = await getDivergence(currentBranch, `${origin}/${currentBranch}`);
3702
3550
  if (branchDiv.ahead > 0) {
3703
- tips.push(`Run ${pc13.bold("contrib submit")} to push and create/update your PR`);
3551
+ tips.push(`Run ${pc12.bold("contrib submit")} to push and create/update your PR`);
3704
3552
  }
3705
3553
  }
3706
3554
  }
3707
3555
  if (tips.length > 0) {
3708
3556
  console.log();
3709
- console.log(` ${pc13.dim("\uD83D\uDCA1 Tip:")}`);
3557
+ console.log(` ${pc12.dim("\uD83D\uDCA1 Tip:")}`);
3710
3558
  for (const tip of tips) {
3711
- console.log(` ${pc13.dim(tip)}`);
3559
+ console.log(` ${pc12.dim(tip)}`);
3712
3560
  }
3713
3561
  }
3714
3562
  console.log();
3715
3563
  }
3716
3564
  });
3717
3565
  function formatStatus(branch, base, ahead, behind) {
3718
- const label = pc13.bold(branch.padEnd(20));
3566
+ const label = pc12.bold(branch.padEnd(20));
3719
3567
  if (ahead === 0 && behind === 0) {
3720
- return ` ${pc13.green("✓")} ${label} ${pc13.dim(`in sync with ${base}`)}`;
3568
+ return ` ${pc12.green("✓")} ${label} ${pc12.dim(`in sync with ${base}`)}`;
3721
3569
  }
3722
3570
  if (ahead > 0 && behind === 0) {
3723
- return ` ${pc13.yellow("↑")} ${label} ${pc13.yellow(`${ahead} commit${ahead !== 1 ? "s" : ""} ahead of ${base}`)}`;
3571
+ return ` ${pc12.yellow("↑")} ${label} ${pc12.yellow(`${ahead} commit${ahead !== 1 ? "s" : ""} ahead of ${base}`)}`;
3724
3572
  }
3725
3573
  if (behind > 0 && ahead === 0) {
3726
- return ` ${pc13.red("↓")} ${label} ${pc13.red(`${behind} commit${behind !== 1 ? "s" : ""} behind ${base}`)}`;
3574
+ return ` ${pc12.red("↓")} ${label} ${pc12.red(`${behind} commit${behind !== 1 ? "s" : ""} behind ${base}`)}`;
3727
3575
  }
3728
- return ` ${pc13.red("⚡")} ${label} ${pc13.yellow(`${ahead} ahead`)}${pc13.dim(", ")}${pc13.red(`${behind} behind`)} ${pc13.dim(base)}`;
3576
+ return ` ${pc12.red("⚡")} ${label} ${pc12.yellow(`${ahead} ahead`)}${pc12.dim(", ")}${pc12.red(`${behind} behind`)} ${pc12.dim(base)}`;
3729
3577
  }
3730
3578
  var STALE_THRESHOLD_DAYS = 14;
3731
3579
  async function detectBranchStatus(branch, baseBranch) {
@@ -3771,16 +3619,16 @@ async function detectBranchStatus(branch, baseBranch) {
3771
3619
  }
3772
3620
 
3773
3621
  // src/commands/submit.ts
3774
- import { defineCommand as defineCommand11 } from "citty";
3775
- import pc14 from "picocolors";
3622
+ import { defineCommand as defineCommand10 } from "citty";
3623
+ import pc13 from "picocolors";
3776
3624
  async function performSquashMerge(origin, baseBranch, featureBranch, options) {
3777
- info(`Checking out ${pc14.bold(baseBranch)}...`);
3625
+ info(`Checking out ${pc13.bold(baseBranch)}...`);
3778
3626
  const coResult = await checkoutBranch(baseBranch);
3779
3627
  if (coResult.exitCode !== 0) {
3780
3628
  error(`Failed to checkout ${baseBranch}: ${coResult.stderr}`);
3781
3629
  process.exit(1);
3782
3630
  }
3783
- info(`Squash merging ${pc14.bold(featureBranch)} into ${pc14.bold(baseBranch)}...`);
3631
+ info(`Squash merging ${pc13.bold(featureBranch)} into ${pc13.bold(baseBranch)}...`);
3784
3632
  const mergeResult = await mergeSquash(featureBranch);
3785
3633
  if (mergeResult.exitCode !== 0) {
3786
3634
  error(`Squash merge failed: ${mergeResult.stderr}`);
@@ -3797,7 +3645,7 @@ async function performSquashMerge(origin, baseBranch, featureBranch, options) {
3797
3645
  message = aiMsg;
3798
3646
  spinner.success("AI commit message generated.");
3799
3647
  console.log(`
3800
- ${pc14.dim("AI suggestion:")} ${pc14.bold(pc14.cyan(message))}`);
3648
+ ${pc13.dim("AI suggestion:")} ${pc13.bold(pc13.cyan(message))}`);
3801
3649
  } else {
3802
3650
  spinner.fail("AI did not return a commit message.");
3803
3651
  }
@@ -3826,7 +3674,7 @@ async function performSquashMerge(origin, baseBranch, featureBranch, options) {
3826
3674
  message = regen;
3827
3675
  spinner.success("Commit message regenerated.");
3828
3676
  console.log(`
3829
- ${pc14.dim("AI suggestion:")} ${pc14.bold(pc14.cyan(regen))}`);
3677
+ ${pc13.dim("AI suggestion:")} ${pc13.bold(pc13.cyan(regen))}`);
3830
3678
  } else {
3831
3679
  spinner.fail("Regeneration failed.");
3832
3680
  finalMsg = await inputPrompt("Enter commit message");
@@ -3843,13 +3691,13 @@ async function performSquashMerge(origin, baseBranch, featureBranch, options) {
3843
3691
  error(`Commit failed: ${commitResult.stderr}`);
3844
3692
  process.exit(1);
3845
3693
  }
3846
- info(`Pushing ${pc14.bold(baseBranch)} to ${origin}...`);
3694
+ info(`Pushing ${pc13.bold(baseBranch)} to ${origin}...`);
3847
3695
  const pushResult = await pushBranch(origin, baseBranch);
3848
3696
  if (pushResult.exitCode !== 0) {
3849
3697
  error(`Failed to push ${baseBranch}: ${pushResult.stderr}`);
3850
3698
  process.exit(1);
3851
3699
  }
3852
- info(`Deleting local branch ${pc14.bold(featureBranch)}...`);
3700
+ info(`Deleting local branch ${pc13.bold(featureBranch)}...`);
3853
3701
  const delLocal = await forceDeleteBranch(featureBranch);
3854
3702
  if (delLocal.exitCode !== 0) {
3855
3703
  warn(`Could not delete local branch: ${delLocal.stderr.trim()}`);
@@ -3857,16 +3705,16 @@ async function performSquashMerge(origin, baseBranch, featureBranch, options) {
3857
3705
  const remoteBranchRef = `${origin}/${featureBranch}`;
3858
3706
  const remoteExists = await branchExists(remoteBranchRef);
3859
3707
  if (remoteExists) {
3860
- info(`Deleting remote branch ${pc14.bold(featureBranch)}...`);
3708
+ info(`Deleting remote branch ${pc13.bold(featureBranch)}...`);
3861
3709
  const delRemote = await deleteRemoteBranch(origin, featureBranch);
3862
3710
  if (delRemote.exitCode !== 0) {
3863
3711
  warn(`Could not delete remote branch: ${delRemote.stderr.trim()}`);
3864
3712
  }
3865
3713
  }
3866
- success(`✅ Squash merged ${pc14.bold(featureBranch)} into ${pc14.bold(baseBranch)} and pushed.`);
3867
- info(`Run ${pc14.bold("contrib start")} to begin a new feature.`);
3714
+ success(`✅ Squash merged ${pc13.bold(featureBranch)} into ${pc13.bold(baseBranch)} and pushed.`);
3715
+ info(`Run ${pc13.bold("contrib start")} to begin a new feature.`);
3868
3716
  }
3869
- var submit_default = defineCommand11({
3717
+ var submit_default = defineCommand10({
3870
3718
  meta: {
3871
3719
  name: "submit",
3872
3720
  description: "Push current branch and create a pull request"
@@ -3908,7 +3756,7 @@ var submit_default = defineCommand11({
3908
3756
  }
3909
3757
  if (protectedBranches.includes(currentBranch)) {
3910
3758
  heading("\uD83D\uDE80 contrib submit");
3911
- warn(`You're on ${pc14.bold(currentBranch)}, which is a protected branch. PRs should come from feature branches.`);
3759
+ warn(`You're on ${pc13.bold(currentBranch)}, which is a protected branch. PRs should come from feature branches.`);
3912
3760
  await fetchAll();
3913
3761
  const remoteRef = `${origin}/${currentBranch}`;
3914
3762
  const localWork = await hasLocalWork(origin, currentBranch);
@@ -3917,11 +3765,11 @@ var submit_default = defineCommand11({
3917
3765
  const hasAnything = hasCommits || dirty;
3918
3766
  if (!hasAnything) {
3919
3767
  error("No local changes or commits to move. Switch to a feature branch first.");
3920
- info(` Run ${pc14.bold("contrib start")} to create a new feature branch.`);
3768
+ info(` Run ${pc13.bold("contrib start")} to create a new feature branch.`);
3921
3769
  process.exit(1);
3922
3770
  }
3923
3771
  if (hasCommits) {
3924
- info(`Found ${pc14.bold(String(localWork.unpushedCommits))} unpushed commit${localWork.unpushedCommits !== 1 ? "s" : ""} on ${pc14.bold(currentBranch)}.`);
3772
+ info(`Found ${pc13.bold(String(localWork.unpushedCommits))} unpushed commit${localWork.unpushedCommits !== 1 ? "s" : ""} on ${pc13.bold(currentBranch)}.`);
3925
3773
  }
3926
3774
  if (dirty) {
3927
3775
  info("You also have uncommitted changes in the working tree.");
@@ -3937,7 +3785,7 @@ var submit_default = defineCommand11({
3937
3785
  info("No changes made. You are still on your current branch.");
3938
3786
  return;
3939
3787
  }
3940
- info(pc14.dim("Tip: Describe what you're going to work on in plain English and we'll generate a branch name."));
3788
+ info(pc13.dim("Tip: Describe what you're going to work on in plain English and we'll generate a branch name."));
3941
3789
  const description = await inputPrompt("What are you going to work on?");
3942
3790
  let newBranchName = description;
3943
3791
  if (looksLikeNaturalLanguage(description)) {
@@ -3948,8 +3796,8 @@ var submit_default = defineCommand11({
3948
3796
  if (suggested) {
3949
3797
  spinner.success("Branch name suggestion ready.");
3950
3798
  console.log(`
3951
- ${pc14.dim("AI suggestion:")} ${pc14.bold(pc14.cyan(suggested))}`);
3952
- const accepted = await confirmPrompt(`Use ${pc14.bold(suggested)} as your branch name?`);
3799
+ ${pc13.dim("AI suggestion:")} ${pc13.bold(pc13.cyan(suggested))}`);
3800
+ const accepted = await confirmPrompt(`Use ${pc13.bold(suggested)} as your branch name?`);
3953
3801
  newBranchName = accepted ? suggested : await inputPrompt("Enter branch name", description);
3954
3802
  } else {
3955
3803
  spinner.fail("AI did not return a suggestion.");
@@ -3958,7 +3806,7 @@ var submit_default = defineCommand11({
3958
3806
  }
3959
3807
  }
3960
3808
  if (!hasPrefix(newBranchName, config.branchPrefixes)) {
3961
- const prefix = await selectPrompt(`Choose a branch type for ${pc14.bold(newBranchName)}:`, config.branchPrefixes);
3809
+ const prefix = await selectPrompt(`Choose a branch type for ${pc13.bold(newBranchName)}:`, config.branchPrefixes);
3962
3810
  newBranchName = formatBranchName(prefix, newBranchName);
3963
3811
  }
3964
3812
  if (!isValidBranchName(newBranchName)) {
@@ -3966,7 +3814,7 @@ var submit_default = defineCommand11({
3966
3814
  process.exit(1);
3967
3815
  }
3968
3816
  if (await branchExists(newBranchName)) {
3969
- error(`Branch ${pc14.bold(newBranchName)} already exists. Choose a different name.`);
3817
+ error(`Branch ${pc13.bold(newBranchName)} already exists. Choose a different name.`);
3970
3818
  process.exit(1);
3971
3819
  }
3972
3820
  const branchResult = await createBranch(newBranchName);
@@ -3974,12 +3822,12 @@ var submit_default = defineCommand11({
3974
3822
  error(`Failed to create branch: ${branchResult.stderr}`);
3975
3823
  process.exit(1);
3976
3824
  }
3977
- success(`Created ${pc14.bold(newBranchName)} with your changes.`);
3825
+ success(`Created ${pc13.bold(newBranchName)} with your changes.`);
3978
3826
  await updateLocalBranch(currentBranch, remoteRef);
3979
- info(`Reset ${pc14.bold(currentBranch)} back to ${pc14.bold(remoteRef)} — no damage done.`);
3827
+ info(`Reset ${pc13.bold(currentBranch)} back to ${pc13.bold(remoteRef)} — no damage done.`);
3980
3828
  console.log();
3981
- success(`You're now on ${pc14.bold(newBranchName)} with all your work intact.`);
3982
- info(`Run ${pc14.bold("contrib submit")} again to push and create your PR.`);
3829
+ success(`You're now on ${pc13.bold(newBranchName)} with all your work intact.`);
3830
+ info(`Run ${pc13.bold("contrib submit")} again to push and create your PR.`);
3983
3831
  return;
3984
3832
  }
3985
3833
  heading("\uD83D\uDE80 contrib submit");
@@ -3988,7 +3836,7 @@ var submit_default = defineCommand11({
3988
3836
  if (ghInstalled && ghAuthed) {
3989
3837
  const mergedPR = await getMergedPRForBranch(currentBranch);
3990
3838
  if (mergedPR) {
3991
- warn(`PR #${mergedPR.number} (${pc14.bold(mergedPR.title)}) was already merged.`);
3839
+ warn(`PR #${mergedPR.number} (${pc13.bold(mergedPR.title)}) was already merged.`);
3992
3840
  const localWork = await hasLocalWork(origin, currentBranch);
3993
3841
  const hasWork = localWork.uncommitted || localWork.unpushedCommits > 0;
3994
3842
  if (hasWork) {
@@ -3996,7 +3844,7 @@ var submit_default = defineCommand11({
3996
3844
  warn("You have uncommitted changes in your working tree.");
3997
3845
  }
3998
3846
  if (localWork.unpushedCommits > 0) {
3999
- warn(`You have ${pc14.bold(String(localWork.unpushedCommits))} local commit${localWork.unpushedCommits !== 1 ? "s" : ""} not in the merged PR.`);
3847
+ warn(`You have ${pc13.bold(String(localWork.unpushedCommits))} local commit${localWork.unpushedCommits !== 1 ? "s" : ""} not in the merged PR.`);
4000
3848
  }
4001
3849
  const SAVE_NEW_BRANCH = "Save changes to a new branch";
4002
3850
  const DISCARD = "Discard all changes and clean up";
@@ -4007,7 +3855,7 @@ var submit_default = defineCommand11({
4007
3855
  return;
4008
3856
  }
4009
3857
  if (action === SAVE_NEW_BRANCH) {
4010
- info(pc14.dim("Tip: Describe what you're going to work on in plain English and we'll generate a branch name."));
3858
+ info(pc13.dim("Tip: Describe what you're going to work on in plain English and we'll generate a branch name."));
4011
3859
  const description = await inputPrompt("What are you going to work on?");
4012
3860
  let newBranchName = description;
4013
3861
  if (!args["no-ai"] && looksLikeNaturalLanguage(description)) {
@@ -4016,8 +3864,8 @@ var submit_default = defineCommand11({
4016
3864
  if (suggested) {
4017
3865
  spinner.success("Branch name suggestion ready.");
4018
3866
  console.log(`
4019
- ${pc14.dim("AI suggestion:")} ${pc14.bold(pc14.cyan(suggested))}`);
4020
- const accepted = await confirmPrompt(`Use ${pc14.bold(suggested)} as your branch name?`);
3867
+ ${pc13.dim("AI suggestion:")} ${pc13.bold(pc13.cyan(suggested))}`);
3868
+ const accepted = await confirmPrompt(`Use ${pc13.bold(suggested)} as your branch name?`);
4021
3869
  newBranchName = accepted ? suggested : await inputPrompt("Enter branch name", description);
4022
3870
  } else {
4023
3871
  spinner.fail("AI did not return a suggestion.");
@@ -4025,7 +3873,7 @@ var submit_default = defineCommand11({
4025
3873
  }
4026
3874
  }
4027
3875
  if (!hasPrefix(newBranchName, config.branchPrefixes)) {
4028
- const prefix = await selectPrompt(`Choose a branch type for ${pc14.bold(newBranchName)}:`, config.branchPrefixes);
3876
+ const prefix = await selectPrompt(`Choose a branch type for ${pc13.bold(newBranchName)}:`, config.branchPrefixes);
4029
3877
  newBranchName = formatBranchName(prefix, newBranchName);
4030
3878
  }
4031
3879
  if (!isValidBranchName(newBranchName)) {
@@ -4035,7 +3883,7 @@ var submit_default = defineCommand11({
4035
3883
  const staleUpstream = await getUpstreamRef();
4036
3884
  const staleUpstreamHash = staleUpstream ? await getCommitHash(staleUpstream) : null;
4037
3885
  if (await branchExists(newBranchName)) {
4038
- error(`Branch ${pc14.bold(newBranchName)} already exists. Choose a different name.`);
3886
+ error(`Branch ${pc13.bold(newBranchName)} already exists. Choose a different name.`);
4039
3887
  process.exit(1);
4040
3888
  }
4041
3889
  const renameResult = await renameBranch(currentBranch, newBranchName);
@@ -4043,10 +3891,10 @@ var submit_default = defineCommand11({
4043
3891
  error(`Failed to rename branch: ${renameResult.stderr}`);
4044
3892
  process.exit(1);
4045
3893
  }
4046
- success(`Renamed ${pc14.bold(currentBranch)} → ${pc14.bold(newBranchName)}`);
3894
+ success(`Renamed ${pc13.bold(currentBranch)} → ${pc13.bold(newBranchName)}`);
4047
3895
  await unsetUpstream();
4048
3896
  const syncSource2 = getSyncSource(config);
4049
- info(`Syncing ${pc14.bold(newBranchName)} with latest ${pc14.bold(baseBranch)}...`);
3897
+ info(`Syncing ${pc13.bold(newBranchName)} with latest ${pc13.bold(baseBranch)}...`);
4050
3898
  await fetchRemote(syncSource2.remote);
4051
3899
  let rebaseResult;
4052
3900
  if (staleUpstreamHash) {
@@ -4057,17 +3905,17 @@ var submit_default = defineCommand11({
4057
3905
  }
4058
3906
  if (rebaseResult.exitCode !== 0) {
4059
3907
  warn("Rebase encountered conflicts. Resolve them manually, then run:");
4060
- info(` ${pc14.bold("git rebase --continue")}`);
3908
+ info(` ${pc13.bold("git rebase --continue")}`);
4061
3909
  } else {
4062
- success(`Rebased ${pc14.bold(newBranchName)} onto ${pc14.bold(syncSource2.ref)}.`);
3910
+ success(`Rebased ${pc13.bold(newBranchName)} onto ${pc13.bold(syncSource2.ref)}.`);
4063
3911
  }
4064
- info(`All your changes are preserved. Run ${pc14.bold("contrib submit")} when ready to create a new PR.`);
3912
+ info(`All your changes are preserved. Run ${pc13.bold("contrib submit")} when ready to create a new PR.`);
4065
3913
  return;
4066
3914
  }
4067
3915
  warn("Discarding local changes...");
4068
3916
  }
4069
3917
  const syncSource = getSyncSource(config);
4070
- info(`Switching to ${pc14.bold(baseBranch)} and syncing...`);
3918
+ info(`Switching to ${pc13.bold(baseBranch)} and syncing...`);
4071
3919
  await fetchRemote(syncSource.remote);
4072
3920
  await resetHard("HEAD");
4073
3921
  const coResult = await checkoutBranch(baseBranch);
@@ -4076,23 +3924,23 @@ var submit_default = defineCommand11({
4076
3924
  process.exit(1);
4077
3925
  }
4078
3926
  await updateLocalBranch(baseBranch, syncSource.ref);
4079
- success(`Synced ${pc14.bold(baseBranch)} with ${pc14.bold(syncSource.ref)}.`);
4080
- info(`Deleting stale branch ${pc14.bold(currentBranch)}...`);
3927
+ success(`Synced ${pc13.bold(baseBranch)} with ${pc13.bold(syncSource.ref)}.`);
3928
+ info(`Deleting stale branch ${pc13.bold(currentBranch)}...`);
4081
3929
  const delResult = await forceDeleteBranch(currentBranch);
4082
3930
  if (delResult.exitCode === 0) {
4083
- success(`Deleted ${pc14.bold(currentBranch)}.`);
3931
+ success(`Deleted ${pc13.bold(currentBranch)}.`);
4084
3932
  } else {
4085
3933
  warn(`Could not delete branch: ${delResult.stderr.trim()}`);
4086
3934
  }
4087
3935
  console.log();
4088
- info(`You're now on ${pc14.bold(baseBranch)}. Run ${pc14.bold("contrib start")} to begin a new feature.`);
3936
+ info(`You're now on ${pc13.bold(baseBranch)}. Run ${pc13.bold("contrib start")} to begin a new feature.`);
4089
3937
  return;
4090
3938
  }
4091
3939
  }
4092
3940
  if (ghInstalled && ghAuthed) {
4093
3941
  const existingPR = await getPRForBranch(currentBranch);
4094
3942
  if (existingPR) {
4095
- info(`Pushing ${pc14.bold(currentBranch)} to ${origin}...`);
3943
+ info(`Pushing ${pc13.bold(currentBranch)} to ${origin}...`);
4096
3944
  const pushResult2 = await pushSetUpstream(origin, currentBranch);
4097
3945
  if (pushResult2.exitCode !== 0) {
4098
3946
  error(`Failed to push: ${pushResult2.stderr}`);
@@ -4103,8 +3951,8 @@ var submit_default = defineCommand11({
4103
3951
  }
4104
3952
  process.exit(1);
4105
3953
  }
4106
- success(`Pushed changes to existing PR #${existingPR.number}: ${pc14.bold(existingPR.title)}`);
4107
- console.log(` ${pc14.cyan(existingPR.url)}`);
3954
+ success(`Pushed changes to existing PR #${existingPR.number}: ${pc13.bold(existingPR.title)}`);
3955
+ console.log(` ${pc13.cyan(existingPR.url)}`);
4108
3956
  return;
4109
3957
  }
4110
3958
  }
@@ -4124,10 +3972,10 @@ var submit_default = defineCommand11({
4124
3972
  prBody = result.body;
4125
3973
  spinner.success("PR description generated.");
4126
3974
  console.log(`
4127
- ${pc14.dim("AI title:")} ${pc14.bold(pc14.cyan(prTitle))}`);
3975
+ ${pc13.dim("AI title:")} ${pc13.bold(pc13.cyan(prTitle))}`);
4128
3976
  console.log(`
4129
- ${pc14.dim("AI body preview:")}`);
4130
- console.log(pc14.dim(prBody.slice(0, 300) + (prBody.length > 300 ? "..." : "")));
3977
+ ${pc13.dim("AI body preview:")}`);
3978
+ console.log(pc13.dim(prBody.slice(0, 300) + (prBody.length > 300 ? "..." : "")));
4131
3979
  } else {
4132
3980
  spinner.fail("AI did not return a PR description.");
4133
3981
  }
@@ -4215,7 +4063,7 @@ ${pc14.dim("AI body preview:")}`);
4215
4063
  });
4216
4064
  return;
4217
4065
  }
4218
- info(`Pushing ${pc14.bold(currentBranch)} to ${origin}...`);
4066
+ info(`Pushing ${pc13.bold(currentBranch)} to ${origin}...`);
4219
4067
  const pushResult = await pushSetUpstream(origin, currentBranch);
4220
4068
  if (pushResult.exitCode !== 0) {
4221
4069
  error(`Failed to push: ${pushResult.stderr}`);
@@ -4234,7 +4082,7 @@ ${pc14.dim("AI body preview:")}`);
4234
4082
  const prUrl = `https://github.com/${repoInfo.owner}/${repoInfo.repo}/compare/${baseBranch}...${currentBranch}?expand=1`;
4235
4083
  console.log();
4236
4084
  info("Create your PR manually:");
4237
- console.log(` ${pc14.cyan(prUrl)}`);
4085
+ console.log(` ${pc13.cyan(prUrl)}`);
4238
4086
  } else {
4239
4087
  info("gh CLI not available. Create your PR manually on GitHub.");
4240
4088
  }
@@ -4267,109 +4115,10 @@ ${pc14.dim("AI body preview:")}`);
4267
4115
  }
4268
4116
  });
4269
4117
 
4270
- // src/commands/switch.ts
4271
- import { defineCommand as defineCommand12 } from "citty";
4272
- import pc15 from "picocolors";
4273
- var switch_default = defineCommand12({
4274
- meta: {
4275
- name: "switch",
4276
- description: "Switch to another branch with stash protection for uncommitted changes"
4277
- },
4278
- args: {
4279
- name: {
4280
- type: "positional",
4281
- description: "Branch name to switch to (interactive picker if omitted)",
4282
- required: false
4283
- }
4284
- },
4285
- async run({ args }) {
4286
- if (!await isGitRepo()) {
4287
- error("Not inside a git repository.");
4288
- process.exit(1);
4289
- }
4290
- const config = readConfig();
4291
- const protectedBranches = config ? getProtectedBranches(config) : ["main", "master"];
4292
- const currentBranch = await getCurrentBranch();
4293
- heading("\uD83D\uDD00 contrib switch");
4294
- let targetBranch = args.name;
4295
- if (!targetBranch) {
4296
- const localBranches = await getLocalBranches();
4297
- if (localBranches.length === 0) {
4298
- error("No local branches found.");
4299
- process.exit(1);
4300
- }
4301
- const choices = localBranches.filter((b) => b.name !== currentBranch).map((b) => {
4302
- const labels = [];
4303
- if (protectedBranches.includes(b.name))
4304
- labels.push(pc15.red("protected"));
4305
- if (b.upstream)
4306
- labels.push(pc15.dim(`→ ${b.upstream}`));
4307
- if (b.gone)
4308
- labels.push(pc15.red("remote gone"));
4309
- const suffix = labels.length > 0 ? ` ${labels.join(" · ")}` : "";
4310
- return `${b.name}${suffix}`;
4311
- });
4312
- if (choices.length === 0) {
4313
- info("You are already on the only local branch.");
4314
- process.exit(0);
4315
- }
4316
- const selected = await selectPrompt("Switch to which branch?", choices);
4317
- targetBranch = selected.split(/\s{2,}/)[0].trim();
4318
- }
4319
- if (targetBranch === currentBranch) {
4320
- info(`Already on ${pc15.bold(targetBranch)}.`);
4321
- return;
4322
- }
4323
- if (await hasUncommittedChanges()) {
4324
- warn("You have uncommitted changes.");
4325
- const action = await selectPrompt("How would you like to handle them?", [
4326
- "Save changes and switch",
4327
- "Cancel"
4328
- ]);
4329
- if (action === "Cancel") {
4330
- info("Switch cancelled.");
4331
- return;
4332
- }
4333
- const { execFile } = await import("node:child_process");
4334
- const { promisify } = await import("node:util");
4335
- const exec = promisify(execFile);
4336
- const stashMsg = `contrib-save: auto-save from ${currentBranch}`;
4337
- try {
4338
- await exec("git", ["stash", "push", "-m", stashMsg]);
4339
- info(`Saved changes: ${pc15.dim(stashMsg)}`);
4340
- } catch {
4341
- error("Failed to save changes. Please commit or save manually.");
4342
- process.exit(1);
4343
- }
4344
- const result2 = await checkoutBranch(targetBranch);
4345
- if (result2.exitCode !== 0) {
4346
- error(`Failed to switch to ${targetBranch}: ${result2.stderr}`);
4347
- try {
4348
- await exec("git", ["stash", "pop"]);
4349
- info("Restored saved changes.");
4350
- } catch {
4351
- warn("Could not restore save automatically. Use `contrib save restore` to recover.");
4352
- }
4353
- process.exit(1);
4354
- }
4355
- success(`Switched to ${pc15.bold(targetBranch)}`);
4356
- info(`Your changes from ${pc15.bold(currentBranch ?? "previous branch")} are saved.`);
4357
- info(`Use ${pc15.bold("contrib save restore")} to bring them back.`);
4358
- return;
4359
- }
4360
- const result = await checkoutBranch(targetBranch);
4361
- if (result.exitCode !== 0) {
4362
- error(`Failed to switch to ${targetBranch}: ${result.stderr}`);
4363
- process.exit(1);
4364
- }
4365
- success(`Switched to ${pc15.bold(targetBranch)}`);
4366
- }
4367
- });
4368
-
4369
4118
  // src/commands/sync.ts
4370
- import { defineCommand as defineCommand13 } from "citty";
4371
- import pc16 from "picocolors";
4372
- var sync_default = defineCommand13({
4119
+ import { defineCommand as defineCommand11 } from "citty";
4120
+ import pc14 from "picocolors";
4121
+ var sync_default = defineCommand11({
4373
4122
  meta: {
4374
4123
  name: "sync",
4375
4124
  description: "Sync your local branches with the remote"
@@ -4420,24 +4169,24 @@ var sync_default = defineCommand13({
4420
4169
  await fetchRemote(origin);
4421
4170
  }
4422
4171
  if (!await refExists(syncSource.ref)) {
4423
- error(`Remote ref ${pc16.bold(syncSource.ref)} does not exist.`);
4172
+ error(`Remote ref ${pc14.bold(syncSource.ref)} does not exist.`);
4424
4173
  info("This can happen if the branch was renamed or deleted on the remote.");
4425
- info(`Check your config: the base branch may need updating via ${pc16.bold("contrib setup")}.`);
4174
+ info(`Check your config: the base branch may need updating via ${pc14.bold("contrib setup")}.`);
4426
4175
  process.exit(1);
4427
4176
  }
4428
4177
  let allowMergeCommit = false;
4429
4178
  const div = await getDivergence(baseBranch, syncSource.ref);
4430
4179
  if (div.ahead > 0 || div.behind > 0) {
4431
- info(`${pc16.bold(baseBranch)} is ${pc16.yellow(`${div.ahead} ahead`)} and ${pc16.red(`${div.behind} behind`)} ${syncSource.ref}`);
4180
+ info(`${pc14.bold(baseBranch)} is ${pc14.yellow(`${div.ahead} ahead`)} and ${pc14.red(`${div.behind} behind`)} ${syncSource.ref}`);
4432
4181
  } else {
4433
- info(`${pc16.bold(baseBranch)} is already in sync with ${syncSource.ref}`);
4182
+ info(`${pc14.bold(baseBranch)} is already in sync with ${syncSource.ref}`);
4434
4183
  }
4435
4184
  if (div.ahead > 0) {
4436
4185
  const currentBranch = await getCurrentBranch();
4437
4186
  const protectedBranches = getProtectedBranches(config);
4438
4187
  const isOnProtected = currentBranch && protectedBranches.includes(currentBranch);
4439
4188
  if (isOnProtected) {
4440
- warn(`You have ${pc16.bold(String(div.ahead))} local commit${div.ahead !== 1 ? "s" : ""} on ${pc16.bold(baseBranch)} that aren't on the remote.`);
4189
+ warn(`You have ${pc14.bold(String(div.ahead))} local commit${div.ahead !== 1 ? "s" : ""} on ${pc14.bold(baseBranch)} that aren't on the remote.`);
4441
4190
  info("Pulling now could create a merge commit, which breaks clean history.");
4442
4191
  console.log();
4443
4192
  const MOVE_BRANCH = "Move my commits to a new feature branch, then sync";
@@ -4453,7 +4202,7 @@ var sync_default = defineCommand13({
4453
4202
  return;
4454
4203
  }
4455
4204
  if (action === MOVE_BRANCH) {
4456
- info(pc16.dim("Tip: Describe what you're going to work on in plain English and we'll generate a branch name."));
4205
+ info(pc14.dim("Tip: Describe what you're going to work on in plain English and we'll generate a branch name."));
4457
4206
  const description = await inputPrompt("What are you going to work on?");
4458
4207
  let newBranchName = description;
4459
4208
  if (!args["no-ai"] && looksLikeNaturalLanguage(description)) {
@@ -4464,8 +4213,8 @@ var sync_default = defineCommand13({
4464
4213
  if (suggested) {
4465
4214
  spinner.success("Branch name suggestion ready.");
4466
4215
  console.log(`
4467
- ${pc16.dim("AI suggestion:")} ${pc16.bold(pc16.cyan(suggested))}`);
4468
- const accepted = await confirmPrompt(`Use ${pc16.bold(suggested)} as your branch name?`);
4216
+ ${pc14.dim("AI suggestion:")} ${pc14.bold(pc14.cyan(suggested))}`);
4217
+ const accepted = await confirmPrompt(`Use ${pc14.bold(suggested)} as your branch name?`);
4469
4218
  newBranchName = accepted ? suggested : await inputPrompt("Enter branch name", description);
4470
4219
  } else {
4471
4220
  spinner.fail("AI did not return a suggestion.");
@@ -4474,7 +4223,7 @@ var sync_default = defineCommand13({
4474
4223
  }
4475
4224
  }
4476
4225
  if (!hasPrefix(newBranchName, config.branchPrefixes)) {
4477
- const prefix = await selectPrompt(`Choose a branch type for ${pc16.bold(newBranchName)}:`, config.branchPrefixes);
4226
+ const prefix = await selectPrompt(`Choose a branch type for ${pc14.bold(newBranchName)}:`, config.branchPrefixes);
4478
4227
  newBranchName = formatBranchName(prefix, newBranchName);
4479
4228
  }
4480
4229
  if (!isValidBranchName(newBranchName)) {
@@ -4482,7 +4231,7 @@ var sync_default = defineCommand13({
4482
4231
  process.exit(1);
4483
4232
  }
4484
4233
  if (await branchExists(newBranchName)) {
4485
- error(`Branch ${pc16.bold(newBranchName)} already exists. Choose a different name.`);
4234
+ error(`Branch ${pc14.bold(newBranchName)} already exists. Choose a different name.`);
4486
4235
  process.exit(1);
4487
4236
  }
4488
4237
  const branchResult = await createBranch(newBranchName);
@@ -4490,7 +4239,7 @@ var sync_default = defineCommand13({
4490
4239
  error(`Failed to create branch: ${branchResult.stderr}`);
4491
4240
  process.exit(1);
4492
4241
  }
4493
- success(`Created ${pc16.bold(newBranchName)} with your commits.`);
4242
+ success(`Created ${pc14.bold(newBranchName)} with your commits.`);
4494
4243
  const coResult2 = await checkoutBranch(baseBranch);
4495
4244
  if (coResult2.exitCode !== 0) {
4496
4245
  error(`Failed to checkout ${baseBranch}: ${coResult2.stderr}`);
@@ -4498,11 +4247,11 @@ var sync_default = defineCommand13({
4498
4247
  }
4499
4248
  const remoteRef = syncSource.ref;
4500
4249
  await updateLocalBranch(baseBranch, remoteRef);
4501
- success(`Reset ${pc16.bold(baseBranch)} to ${pc16.bold(remoteRef)}.`);
4502
- success(`✅ ${pc16.bold(baseBranch)} is now in sync with ${syncSource.ref}`);
4250
+ success(`Reset ${pc14.bold(baseBranch)} to ${pc14.bold(remoteRef)}.`);
4251
+ success(`✅ ${pc14.bold(baseBranch)} is now in sync with ${syncSource.ref}`);
4503
4252
  console.log();
4504
- info(`Your commits are safe on ${pc16.bold(newBranchName)}.`);
4505
- info(`Run ${pc16.bold(`git checkout ${newBranchName}`)} then ${pc16.bold("contrib update")} to rebase onto the synced ${pc16.bold(baseBranch)}.`);
4253
+ info(`Your commits are safe on ${pc14.bold(newBranchName)}.`);
4254
+ info(`Run ${pc14.bold(`git checkout ${newBranchName}`)} then ${pc14.bold("contrib update")} to rebase onto the synced ${pc14.bold(baseBranch)}.`);
4506
4255
  return;
4507
4256
  }
4508
4257
  allowMergeCommit = true;
@@ -4510,7 +4259,7 @@ var sync_default = defineCommand13({
4510
4259
  }
4511
4260
  }
4512
4261
  if (!args.yes) {
4513
- const ok = await confirmPrompt(`This will pull ${pc16.bold(syncSource.ref)} into local ${pc16.bold(baseBranch)}.`);
4262
+ const ok = await confirmPrompt(`This will pull ${pc14.bold(syncSource.ref)} into local ${pc14.bold(baseBranch)}.`);
4514
4263
  if (!ok)
4515
4264
  process.exit(0);
4516
4265
  }
@@ -4524,8 +4273,8 @@ var sync_default = defineCommand13({
4524
4273
  if (allowMergeCommit) {
4525
4274
  error(`Pull failed: ${pullResult.stderr.trim()}`);
4526
4275
  } else {
4527
- error(`Fast-forward pull failed. Your local ${pc16.bold(baseBranch)} may have diverged.`);
4528
- info(`Use ${pc16.bold("contrib sync")} again and choose "Move my commits to a new feature branch" to fix this.`);
4276
+ error(`Fast-forward pull failed. Your local ${pc14.bold(baseBranch)} may have diverged.`);
4277
+ info(`Use ${pc14.bold("contrib sync")} again and choose "Move my commits to a new feature branch" to fix this.`);
4529
4278
  }
4530
4279
  process.exit(1);
4531
4280
  }
@@ -4533,7 +4282,7 @@ var sync_default = defineCommand13({
4533
4282
  if (hasDevBranch(workflow) && role === "maintainer") {
4534
4283
  const mainDiv = await getDivergence(config.mainBranch, `${origin}/${config.mainBranch}`);
4535
4284
  if (mainDiv.behind > 0) {
4536
- info(`Also syncing ${pc16.bold(config.mainBranch)}...`);
4285
+ info(`Also syncing ${pc14.bold(config.mainBranch)}...`);
4537
4286
  const mainCoResult = await checkoutBranch(config.mainBranch);
4538
4287
  if (mainCoResult.exitCode === 0) {
4539
4288
  const mainPullResult = await pullFastForwardOnly(origin, config.mainBranch);
@@ -4549,9 +4298,9 @@ var sync_default = defineCommand13({
4549
4298
 
4550
4299
  // src/commands/update.ts
4551
4300
  import { readFileSync as readFileSync4 } from "node:fs";
4552
- import { defineCommand as defineCommand14 } from "citty";
4553
- import pc17 from "picocolors";
4554
- var update_default = defineCommand14({
4301
+ import { defineCommand as defineCommand12 } from "citty";
4302
+ import pc15 from "picocolors";
4303
+ var update_default = defineCommand12({
4555
4304
  meta: {
4556
4305
  name: "update",
4557
4306
  description: "Rebase current branch onto the latest base branch"
@@ -4588,7 +4337,7 @@ var update_default = defineCommand14({
4588
4337
  }
4589
4338
  if (protectedBranches.includes(currentBranch)) {
4590
4339
  heading("\uD83D\uDD03 contrib update");
4591
- warn(`You're on ${pc17.bold(currentBranch)}, which is a protected branch. Updates (rebase) apply to feature branches.`);
4340
+ warn(`You're on ${pc15.bold(currentBranch)}, which is a protected branch. Updates (rebase) apply to feature branches.`);
4592
4341
  await fetchAll();
4593
4342
  const { origin } = config;
4594
4343
  const remoteRef = `${origin}/${currentBranch}`;
@@ -4597,12 +4346,12 @@ var update_default = defineCommand14({
4597
4346
  const hasCommits = localWork.unpushedCommits > 0;
4598
4347
  const hasAnything = hasCommits || dirty;
4599
4348
  if (!hasAnything) {
4600
- info(`No local changes found on ${pc17.bold(currentBranch)}.`);
4601
- info(`Use ${pc17.bold("contrib sync")} to sync protected branches, or ${pc17.bold("contrib start")} to create a feature branch.`);
4349
+ info(`No local changes found on ${pc15.bold(currentBranch)}.`);
4350
+ info(`Use ${pc15.bold("contrib sync")} to sync protected branches, or ${pc15.bold("contrib start")} to create a feature branch.`);
4602
4351
  process.exit(1);
4603
4352
  }
4604
4353
  if (hasCommits) {
4605
- info(`Found ${pc17.bold(String(localWork.unpushedCommits))} unpushed commit${localWork.unpushedCommits !== 1 ? "s" : ""} on ${pc17.bold(currentBranch)}.`);
4354
+ info(`Found ${pc15.bold(String(localWork.unpushedCommits))} unpushed commit${localWork.unpushedCommits !== 1 ? "s" : ""} on ${pc15.bold(currentBranch)}.`);
4606
4355
  }
4607
4356
  if (dirty) {
4608
4357
  info("You also have uncommitted changes in the working tree.");
@@ -4618,7 +4367,7 @@ var update_default = defineCommand14({
4618
4367
  info("No changes made. You are still on your current branch.");
4619
4368
  return;
4620
4369
  }
4621
- info(pc17.dim("Tip: Describe what you're going to work on in plain English and we'll generate a branch name."));
4370
+ info(pc15.dim("Tip: Describe what you're going to work on in plain English and we'll generate a branch name."));
4622
4371
  const description = await inputPrompt("What are you going to work on?");
4623
4372
  let newBranchName = description;
4624
4373
  if (!args["no-ai"] && looksLikeNaturalLanguage(description)) {
@@ -4629,8 +4378,8 @@ var update_default = defineCommand14({
4629
4378
  if (suggested) {
4630
4379
  spinner.success("Branch name suggestion ready.");
4631
4380
  console.log(`
4632
- ${pc17.dim("AI suggestion:")} ${pc17.bold(pc17.cyan(suggested))}`);
4633
- const accepted = await confirmPrompt(`Use ${pc17.bold(suggested)} as your branch name?`);
4381
+ ${pc15.dim("AI suggestion:")} ${pc15.bold(pc15.cyan(suggested))}`);
4382
+ const accepted = await confirmPrompt(`Use ${pc15.bold(suggested)} as your branch name?`);
4634
4383
  newBranchName = accepted ? suggested : await inputPrompt("Enter branch name", description);
4635
4384
  } else {
4636
4385
  spinner.fail("AI did not return a suggestion.");
@@ -4639,7 +4388,7 @@ var update_default = defineCommand14({
4639
4388
  }
4640
4389
  }
4641
4390
  if (!hasPrefix(newBranchName, config.branchPrefixes)) {
4642
- const prefix = await selectPrompt(`Choose a branch type for ${pc17.bold(newBranchName)}:`, config.branchPrefixes);
4391
+ const prefix = await selectPrompt(`Choose a branch type for ${pc15.bold(newBranchName)}:`, config.branchPrefixes);
4643
4392
  newBranchName = formatBranchName(prefix, newBranchName);
4644
4393
  }
4645
4394
  if (!isValidBranchName(newBranchName)) {
@@ -4651,12 +4400,12 @@ var update_default = defineCommand14({
4651
4400
  error(`Failed to create branch: ${branchResult.stderr}`);
4652
4401
  process.exit(1);
4653
4402
  }
4654
- success(`Created ${pc17.bold(newBranchName)} with your changes.`);
4403
+ success(`Created ${pc15.bold(newBranchName)} with your changes.`);
4655
4404
  await updateLocalBranch(currentBranch, remoteRef);
4656
- info(`Reset ${pc17.bold(currentBranch)} back to ${pc17.bold(remoteRef)} — no damage done.`);
4405
+ info(`Reset ${pc15.bold(currentBranch)} back to ${pc15.bold(remoteRef)} — no damage done.`);
4657
4406
  console.log();
4658
- success(`You're now on ${pc17.bold(newBranchName)} with all your work intact.`);
4659
- info(`Run ${pc17.bold("contrib update")} again to rebase onto latest ${pc17.bold(baseBranch)}.`);
4407
+ success(`You're now on ${pc15.bold(newBranchName)} with all your work intact.`);
4408
+ info(`Run ${pc15.bold("contrib update")} again to rebase onto latest ${pc15.bold(baseBranch)}.`);
4660
4409
  return;
4661
4410
  }
4662
4411
  if (await hasUncommittedChanges()) {
@@ -4666,8 +4415,8 @@ var update_default = defineCommand14({
4666
4415
  heading("\uD83D\uDD03 contrib update");
4667
4416
  const mergedPR = await getMergedPRForBranch(currentBranch);
4668
4417
  if (mergedPR) {
4669
- warn(`PR #${mergedPR.number} (${pc17.bold(mergedPR.title)}) has already been merged.`);
4670
- info(`Link: ${pc17.underline(mergedPR.url)}`);
4418
+ warn(`PR #${mergedPR.number} (${pc15.bold(mergedPR.title)}) has already been merged.`);
4419
+ info(`Link: ${pc15.underline(mergedPR.url)}`);
4671
4420
  const localWork = await hasLocalWork(syncSource.remote, currentBranch);
4672
4421
  const hasWork = localWork.uncommitted || localWork.unpushedCommits > 0;
4673
4422
  if (hasWork) {
@@ -4680,13 +4429,13 @@ var update_default = defineCommand14({
4680
4429
  const SAVE_NEW_BRANCH = "Save changes to a new branch";
4681
4430
  const DISCARD = "Discard all changes and clean up";
4682
4431
  const CANCEL = "Cancel";
4683
- const action = await selectPrompt(`${pc17.bold(currentBranch)} is stale but has local work. What would you like to do?`, [SAVE_NEW_BRANCH, DISCARD, CANCEL]);
4432
+ const action = await selectPrompt(`${pc15.bold(currentBranch)} is stale but has local work. What would you like to do?`, [SAVE_NEW_BRANCH, DISCARD, CANCEL]);
4684
4433
  if (action === CANCEL) {
4685
4434
  info("No changes made. You are still on your current branch.");
4686
4435
  return;
4687
4436
  }
4688
4437
  if (action === SAVE_NEW_BRANCH) {
4689
- info(pc17.dim("Tip: Describe what you're going to work on in plain English and we'll generate a branch name."));
4438
+ info(pc15.dim("Tip: Describe what you're going to work on in plain English and we'll generate a branch name."));
4690
4439
  const description = await inputPrompt("What are you going to work on?");
4691
4440
  let newBranchName = description;
4692
4441
  if (!args["no-ai"] && looksLikeNaturalLanguage(description)) {
@@ -4695,8 +4444,8 @@ var update_default = defineCommand14({
4695
4444
  if (suggested) {
4696
4445
  spinner.success("Branch name suggestion ready.");
4697
4446
  console.log(`
4698
- ${pc17.dim("AI suggestion:")} ${pc17.bold(pc17.cyan(suggested))}`);
4699
- const accepted = await confirmPrompt(`Use ${pc17.bold(suggested)} as your branch name?`);
4447
+ ${pc15.dim("AI suggestion:")} ${pc15.bold(pc15.cyan(suggested))}`);
4448
+ const accepted = await confirmPrompt(`Use ${pc15.bold(suggested)} as your branch name?`);
4700
4449
  newBranchName = accepted ? suggested : await inputPrompt("Enter branch name", description);
4701
4450
  } else {
4702
4451
  spinner.fail("AI did not return a suggestion.");
@@ -4704,7 +4453,7 @@ var update_default = defineCommand14({
4704
4453
  }
4705
4454
  }
4706
4455
  if (!hasPrefix(newBranchName, config.branchPrefixes)) {
4707
- const prefix = await selectPrompt(`Choose a branch type for ${pc17.bold(newBranchName)}:`, config.branchPrefixes);
4456
+ const prefix = await selectPrompt(`Choose a branch type for ${pc15.bold(newBranchName)}:`, config.branchPrefixes);
4708
4457
  newBranchName = formatBranchName(prefix, newBranchName);
4709
4458
  }
4710
4459
  if (!isValidBranchName(newBranchName)) {
@@ -4714,7 +4463,7 @@ var update_default = defineCommand14({
4714
4463
  const staleUpstream = await getUpstreamRef();
4715
4464
  const staleUpstreamHash = staleUpstream ? await getCommitHash(staleUpstream) : null;
4716
4465
  if (await branchExists(newBranchName)) {
4717
- error(`Branch ${pc17.bold(newBranchName)} already exists. Choose a different name.`);
4466
+ error(`Branch ${pc15.bold(newBranchName)} already exists. Choose a different name.`);
4718
4467
  process.exit(1);
4719
4468
  }
4720
4469
  const renameResult = await renameBranch(currentBranch, newBranchName);
@@ -4722,7 +4471,7 @@ var update_default = defineCommand14({
4722
4471
  error(`Failed to rename branch: ${renameResult.stderr}`);
4723
4472
  process.exit(1);
4724
4473
  }
4725
- success(`Renamed ${pc17.bold(currentBranch)} → ${pc17.bold(newBranchName)}`);
4474
+ success(`Renamed ${pc15.bold(currentBranch)} → ${pc15.bold(newBranchName)}`);
4726
4475
  await unsetUpstream();
4727
4476
  await fetchRemote(syncSource.remote);
4728
4477
  let rebaseResult2;
@@ -4734,11 +4483,11 @@ var update_default = defineCommand14({
4734
4483
  }
4735
4484
  if (rebaseResult2.exitCode !== 0) {
4736
4485
  warn("Rebase encountered conflicts. Resolve them manually, then run:");
4737
- info(` ${pc17.bold("git rebase --continue")}`);
4486
+ info(` ${pc15.bold("git rebase --continue")}`);
4738
4487
  } else {
4739
- success(`Rebased ${pc17.bold(newBranchName)} onto ${pc17.bold(syncSource.ref)}.`);
4488
+ success(`Rebased ${pc15.bold(newBranchName)} onto ${pc15.bold(syncSource.ref)}.`);
4740
4489
  }
4741
- info(`All your changes are preserved. Run ${pc17.bold("contrib submit")} when ready to create a new PR.`);
4490
+ info(`All your changes are preserved. Run ${pc15.bold("contrib submit")} when ready to create a new PR.`);
4742
4491
  return;
4743
4492
  }
4744
4493
  warn("Discarding local changes...");
@@ -4751,24 +4500,24 @@ var update_default = defineCommand14({
4751
4500
  process.exit(1);
4752
4501
  }
4753
4502
  await updateLocalBranch(baseBranch, syncSource.ref);
4754
- success(`Synced ${pc17.bold(baseBranch)} with ${pc17.bold(syncSource.ref)}.`);
4755
- info(`Deleting stale branch ${pc17.bold(currentBranch)}...`);
4503
+ success(`Synced ${pc15.bold(baseBranch)} with ${pc15.bold(syncSource.ref)}.`);
4504
+ info(`Deleting stale branch ${pc15.bold(currentBranch)}...`);
4756
4505
  await forceDeleteBranch(currentBranch);
4757
- success(`Deleted ${pc17.bold(currentBranch)}.`);
4758
- info(`Run ${pc17.bold("contrib start")} to begin a new feature branch.`);
4506
+ success(`Deleted ${pc15.bold(currentBranch)}.`);
4507
+ info(`Run ${pc15.bold("contrib start")} to begin a new feature branch.`);
4759
4508
  return;
4760
4509
  }
4761
- info(`Updating ${pc17.bold(currentBranch)} with latest ${pc17.bold(baseBranch)}...`);
4510
+ info(`Updating ${pc15.bold(currentBranch)} with latest ${pc15.bold(baseBranch)}...`);
4762
4511
  await fetchRemote(syncSource.remote);
4763
4512
  if (!await refExists(syncSource.ref)) {
4764
- error(`Remote ref ${pc17.bold(syncSource.ref)} does not exist.`);
4513
+ error(`Remote ref ${pc15.bold(syncSource.ref)} does not exist.`);
4765
4514
  error("Run `git fetch --all` and verify your remote configuration.");
4766
4515
  process.exit(1);
4767
4516
  }
4768
4517
  await updateLocalBranch(baseBranch, syncSource.ref);
4769
4518
  const rebaseStrategy = await determineRebaseStrategy(currentBranch, syncSource.ref);
4770
4519
  if (rebaseStrategy.strategy === "onto" && rebaseStrategy.ontoOldBase) {
4771
- info(pc17.dim(`Using --onto rebase (branch was based on a different ref)`));
4520
+ info(pc15.dim(`Using --onto rebase (branch was based on a different ref)`));
4772
4521
  }
4773
4522
  const rebaseResult = rebaseStrategy.strategy === "onto" && rebaseStrategy.ontoOldBase ? await rebaseOnto(syncSource.ref, rebaseStrategy.ontoOldBase) : await rebase(syncSource.ref);
4774
4523
  if (rebaseResult.exitCode !== 0) {
@@ -4797,10 +4546,10 @@ ${content.slice(0, 2000)}
4797
4546
  if (suggestion) {
4798
4547
  spinner.success("AI conflict guidance ready.");
4799
4548
  console.log(`
4800
- ${pc17.bold("\uD83D\uDCA1 AI Conflict Resolution Guidance:")}`);
4801
- console.log(pc17.dim("─".repeat(60)));
4549
+ ${pc15.bold("\uD83D\uDCA1 AI Conflict Resolution Guidance:")}`);
4550
+ console.log(pc15.dim("─".repeat(60)));
4802
4551
  console.log(suggestion);
4803
- console.log(pc17.dim("─".repeat(60)));
4552
+ console.log(pc15.dim("─".repeat(60)));
4804
4553
  console.log();
4805
4554
  } else {
4806
4555
  spinner.fail("AI could not analyze the conflicts.");
@@ -4808,22 +4557,22 @@ ${pc17.bold("\uD83D\uDCA1 AI Conflict Resolution Guidance:")}`);
4808
4557
  }
4809
4558
  }
4810
4559
  }
4811
- console.log(pc17.bold("To resolve:"));
4560
+ console.log(pc15.bold("To resolve:"));
4812
4561
  console.log(` 1. Fix conflicts in the affected files`);
4813
- console.log(` 2. ${pc17.cyan("git add <resolved-files>")}`);
4814
- console.log(` 3. ${pc17.cyan("git rebase --continue")}`);
4562
+ console.log(` 2. ${pc15.cyan("git add <resolved-files>")}`);
4563
+ console.log(` 3. ${pc15.cyan("git rebase --continue")}`);
4815
4564
  console.log();
4816
- console.log(` Or abort: ${pc17.cyan("git rebase --abort")}`);
4565
+ console.log(` Or abort: ${pc15.cyan("git rebase --abort")}`);
4817
4566
  process.exit(1);
4818
4567
  }
4819
- success(`✅ ${pc17.bold(currentBranch)} has been rebased onto latest ${pc17.bold(baseBranch)}`);
4568
+ success(`✅ ${pc15.bold(currentBranch)} has been rebased onto latest ${pc15.bold(baseBranch)}`);
4820
4569
  }
4821
4570
  });
4822
4571
 
4823
4572
  // src/commands/validate.ts
4824
- import { defineCommand as defineCommand15 } from "citty";
4825
- import pc18 from "picocolors";
4826
- var validate_default = defineCommand15({
4573
+ import { defineCommand as defineCommand13 } from "citty";
4574
+ import pc16 from "picocolors";
4575
+ var validate_default = defineCommand13({
4827
4576
  meta: {
4828
4577
  name: "validate",
4829
4578
  description: "Validate a commit message against the configured convention"
@@ -4853,7 +4602,7 @@ var validate_default = defineCommand15({
4853
4602
  }
4854
4603
  const errors = getValidationError(convention);
4855
4604
  for (const line of errors) {
4856
- console.error(pc18.red(` ✗ ${line}`));
4605
+ console.error(pc16.red(` ✗ ${line}`));
4857
4606
  }
4858
4607
  process.exit(1);
4859
4608
  }
@@ -4861,7 +4610,7 @@ var validate_default = defineCommand15({
4861
4610
 
4862
4611
  // src/ui/banner.ts
4863
4612
  import figlet from "figlet";
4864
- import pc19 from "picocolors";
4613
+ import pc17 from "picocolors";
4865
4614
  var LOGO_BIG;
4866
4615
  try {
4867
4616
  LOGO_BIG = figlet.textSync(`Contribute
@@ -4883,14 +4632,14 @@ function getAuthor() {
4883
4632
  }
4884
4633
  function showBanner(variant = "small") {
4885
4634
  const logo = variant === "big" ? LOGO_BIG : LOGO_SMALL;
4886
- console.log(pc19.cyan(`
4635
+ console.log(pc17.cyan(`
4887
4636
  ${logo}`));
4888
- console.log(` ${pc19.dim(`v${getVersion()}`)} ${pc19.dim("—")} ${pc19.dim(`Built by ${getAuthor()}`)}`);
4637
+ console.log(` ${pc17.dim(`v${getVersion()}`)} ${pc17.dim("—")} ${pc17.dim(`Built by ${getAuthor()}`)}`);
4889
4638
  if (variant === "big") {
4890
4639
  console.log();
4891
- console.log(` ${pc19.yellow("Star")} ${pc19.cyan("https://github.com/warengonzaga/contribute-now")}`);
4892
- console.log(` ${pc19.green("Contribute")} ${pc19.cyan("https://github.com/warengonzaga/contribute-now/blob/main/CONTRIBUTING.md")}`);
4893
- console.log(` ${pc19.magenta("Sponsor")} ${pc19.cyan("https://warengonzaga.com/sponsor")}`);
4640
+ console.log(` ${pc17.yellow("Star")} ${pc17.cyan("https://github.com/warengonzaga/contribute-now")}`);
4641
+ console.log(` ${pc17.green("Contribute")} ${pc17.cyan("https://github.com/warengonzaga/contribute-now/blob/main/CONTRIBUTING.md")}`);
4642
+ console.log(` ${pc17.magenta("Sponsor")} ${pc17.cyan("https://warengonzaga.com/sponsor")}`);
4894
4643
  }
4895
4644
  console.log();
4896
4645
  }
@@ -4905,8 +4654,6 @@ if (!isVersion) {
4905
4654
  "commit",
4906
4655
  "update",
4907
4656
  "submit",
4908
- "switch",
4909
- "save",
4910
4657
  "clean",
4911
4658
  "status",
4912
4659
  "log",
@@ -4920,7 +4667,7 @@ if (!isVersion) {
4920
4667
  const useBigBanner = isHelp || !hasSubCommand;
4921
4668
  showBanner(useBigBanner ? "big" : "small");
4922
4669
  }
4923
- var main = defineCommand16({
4670
+ var main = defineCommand14({
4924
4671
  meta: {
4925
4672
  name: "contrib",
4926
4673
  version: getVersion(),
@@ -4940,8 +4687,6 @@ var main = defineCommand16({
4940
4687
  commit: commit_default,
4941
4688
  update: update_default,
4942
4689
  submit: submit_default,
4943
- switch: switch_default,
4944
- save: save_default,
4945
4690
  branch: branch_default,
4946
4691
  clean: clean_default,
4947
4692
  status: status_default,