@keepgoingdev/cli 1.3.3 → 1.5.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.
Files changed (2) hide show
  1. package/dist/index.js +3154 -344
  2. package/package.json +3 -2
package/dist/index.js CHANGED
@@ -1,4 +1,89 @@
1
1
  #!/usr/bin/env node
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __commonJS = (cb, mod) => function __require() {
9
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
+ };
11
+ var __export = (target, all) => {
12
+ for (var name in all)
13
+ __defProp(target, name, { get: all[name], enumerable: true });
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (let key of __getOwnPropNames(from))
18
+ if (!__hasOwnProp.call(to, key) && key !== except)
19
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
+ }
21
+ return to;
22
+ };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
+ // If the importer is in node compatibility mode or this is not an ESM
25
+ // file that has been converted to a CommonJS file using a Babel-
26
+ // compatible transform (i.e. "__esModule" has not been set), then set
27
+ // "default" to the CommonJS "module.exports" for node compatibility.
28
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
29
+ mod
30
+ ));
31
+
32
+ // ../../node_modules/sisteransi/src/index.js
33
+ var require_src = __commonJS({
34
+ "../../node_modules/sisteransi/src/index.js"(exports, module) {
35
+ "use strict";
36
+ var ESC2 = "\x1B";
37
+ var CSI2 = `${ESC2}[`;
38
+ var beep = "\x07";
39
+ var cursor = {
40
+ to(x, y2) {
41
+ if (!y2) return `${CSI2}${x + 1}G`;
42
+ return `${CSI2}${y2 + 1};${x + 1}H`;
43
+ },
44
+ move(x, y2) {
45
+ let ret = "";
46
+ if (x < 0) ret += `${CSI2}${-x}D`;
47
+ else if (x > 0) ret += `${CSI2}${x}C`;
48
+ if (y2 < 0) ret += `${CSI2}${-y2}A`;
49
+ else if (y2 > 0) ret += `${CSI2}${y2}B`;
50
+ return ret;
51
+ },
52
+ up: (count = 1) => `${CSI2}${count}A`,
53
+ down: (count = 1) => `${CSI2}${count}B`,
54
+ forward: (count = 1) => `${CSI2}${count}C`,
55
+ backward: (count = 1) => `${CSI2}${count}D`,
56
+ nextLine: (count = 1) => `${CSI2}E`.repeat(count),
57
+ prevLine: (count = 1) => `${CSI2}F`.repeat(count),
58
+ left: `${CSI2}G`,
59
+ hide: `${CSI2}?25l`,
60
+ show: `${CSI2}?25h`,
61
+ save: `${ESC2}7`,
62
+ restore: `${ESC2}8`
63
+ };
64
+ var scroll = {
65
+ up: (count = 1) => `${CSI2}S`.repeat(count),
66
+ down: (count = 1) => `${CSI2}T`.repeat(count)
67
+ };
68
+ var erase = {
69
+ screen: `${CSI2}2J`,
70
+ up: (count = 1) => `${CSI2}1J`.repeat(count),
71
+ down: (count = 1) => `${CSI2}J`.repeat(count),
72
+ line: `${CSI2}2K`,
73
+ lineEnd: `${CSI2}K`,
74
+ lineStart: `${CSI2}1K`,
75
+ lines(count) {
76
+ let clear = "";
77
+ for (let i = 0; i < count; i++)
78
+ clear += this.line + (i < count - 1 ? cursor.up() : "");
79
+ if (count)
80
+ clear += cursor.left;
81
+ return clear;
82
+ }
83
+ };
84
+ module.exports = { cursor, scroll, erase, beep };
85
+ }
86
+ });
2
87
 
3
88
  // ../../packages/shared/src/session.ts
4
89
  import { randomUUID } from "crypto";
@@ -466,7 +551,7 @@ function inferFocusFromFiles(files) {
466
551
  const dirs = files.map((f) => {
467
552
  const parts = f.replace(/\\/g, "/").split("/");
468
553
  return parts.length > 1 ? parts.slice(0, -1).join("/") : "";
469
- }).filter((d) => d.length > 0);
554
+ }).filter((d3) => d3.length > 0);
470
555
  if (dirs.length > 0) {
471
556
  const counts = /* @__PURE__ */ new Map();
472
557
  for (const dir of dirs) {
@@ -493,6 +578,33 @@ function inferFocusFromFiles(files) {
493
578
 
494
579
  // ../../packages/shared/src/continueOn.ts
495
580
  import path2 from "path";
581
+ var NOISE_SUMMARY_PATTERN = /^(Merge |Release:|Bump |chore\(release\))/i;
582
+ function findMeaningfulCheckpoint(checkpoints) {
583
+ for (const cp of checkpoints) {
584
+ if (cp.source === "auto" && !cp.nextStep && NOISE_SUMMARY_PATTERN.test(cp.summary || "")) {
585
+ continue;
586
+ }
587
+ if (!cp.summary) {
588
+ continue;
589
+ }
590
+ return cp;
591
+ }
592
+ return void 0;
593
+ }
594
+ function filterNoiseDecisions(decisions) {
595
+ return decisions.filter(
596
+ (d3) => d3.classification.category !== "deploy" && d3.classification.confidence >= 0.6
597
+ );
598
+ }
599
+ function aggregateTouchedFiles(checkpoints) {
600
+ const freq = /* @__PURE__ */ new Map();
601
+ for (const cp of checkpoints) {
602
+ for (const f of cp.touchedFiles) {
603
+ freq.set(f, (freq.get(f) ?? 0) + 1);
604
+ }
605
+ }
606
+ return [...freq.entries()].sort((a, b) => b[1] - a[1]).map(([file]) => file);
607
+ }
496
608
  function gatherContinueOnContext(reader, workspacePath) {
497
609
  const projectName = path2.basename(workspacePath);
498
610
  const gitBranch = reader.getCurrentBranch();
@@ -503,106 +615,244 @@ function gatherContinueOnContext(reader, workspacePath) {
503
615
  recentCheckpoints: [],
504
616
  recentDecisions: [],
505
617
  currentTasks: [],
506
- recentCommitMessages: []
618
+ recentCommitMessages: [],
619
+ aggregatedTouchedFiles: []
507
620
  };
508
621
  }
509
622
  const { session: lastCheckpoint } = reader.getScopedLastSession();
510
623
  const recentCheckpoints = reader.getScopedRecentSessions(5);
511
- const recentDecisions = reader.getScopedRecentDecisions(3);
624
+ const recentDecisions = reader.getScopedRecentDecisions(5);
512
625
  const currentTasks = reader.getCurrentTasks();
513
626
  const state = reader.getState() ?? {};
627
+ const projectMeta = reader.getMeta();
514
628
  const sinceTimestamp = lastCheckpoint?.timestamp;
515
629
  const recentCommitMessages = sinceTimestamp ? getCommitMessagesSince(workspacePath, sinceTimestamp) : [];
516
- const briefing = generateBriefing(
517
- lastCheckpoint,
518
- recentCheckpoints,
519
- state,
630
+ const allSessions = reader.getSessions();
631
+ const enrichedBriefing = generateEnrichedBriefing({
632
+ tier: "full",
633
+ lastSession: lastCheckpoint,
634
+ recentSessions: recentCheckpoints,
635
+ projectState: state,
520
636
  gitBranch,
521
- recentCommitMessages
522
- );
637
+ recentCommits: recentCommitMessages,
638
+ decisions: recentDecisions,
639
+ allTouchedFiles: lastCheckpoint?.touchedFiles,
640
+ allSessions,
641
+ fileConflicts: reader.detectFileConflicts(),
642
+ branchOverlaps: reader.detectBranchOverlap(),
643
+ isWorktree: reader.isWorktree
644
+ });
645
+ const aggregatedTouchedFiles = aggregateTouchedFiles(recentCheckpoints);
523
646
  return {
524
647
  projectName,
525
648
  gitBranch,
526
- briefing,
649
+ briefing: enrichedBriefing?.core,
650
+ enrichedBriefing,
527
651
  lastCheckpoint,
528
652
  recentCheckpoints,
529
653
  recentDecisions,
530
654
  currentTasks,
531
- recentCommitMessages
655
+ recentCommitMessages,
656
+ projectMeta,
657
+ aggregatedTouchedFiles
532
658
  };
533
659
  }
534
660
  function formatContinueOnPrompt(context, options) {
535
661
  const opts = { includeCommits: true, includeFiles: true, ...options };
536
- const lines = [];
537
- lines.push(`# Project Context: ${context.projectName}`);
538
- lines.push("");
539
- lines.push("I'm continuing work on a project. Here is my development context from KeepGoing.");
540
- lines.push("");
541
- lines.push("## Current Status");
662
+ const meaningfulCheckpoint = findMeaningfulCheckpoint(context.recentCheckpoints) ?? context.lastCheckpoint;
663
+ const briefing = context.briefing;
664
+ const enriched = context.enrichedBriefing;
665
+ const sections = [];
666
+ sections.push({
667
+ priority: 0,
668
+ content: buildHeader(context)
669
+ });
670
+ const projectSection = buildProjectSection(context);
671
+ if (projectSection) {
672
+ sections.push({ priority: 1, content: projectSection });
673
+ }
674
+ const leftOffSection = buildLeftOffSection(meaningfulCheckpoint, briefing);
675
+ if (leftOffSection) {
676
+ sections.push({ priority: 2, content: leftOffSection });
677
+ }
678
+ const sessionsSection = buildRecentSessionsSection(context.recentCheckpoints);
679
+ if (sessionsSection) {
680
+ sections.push({ priority: 4, content: sessionsSection });
681
+ }
682
+ const activeSection = buildActiveWorkSection(context.currentTasks);
683
+ if (activeSection) {
684
+ sections.push({ priority: 3, content: activeSection });
685
+ }
686
+ const decisionsSection = buildDecisionsSection(context.recentDecisions);
687
+ if (decisionsSection) {
688
+ sections.push({ priority: 5, content: decisionsSection });
689
+ }
690
+ if (opts.includeFiles) {
691
+ const hotFilesSection = buildHotFilesSection(context.aggregatedTouchedFiles);
692
+ if (hotFilesSection) {
693
+ sections.push({ priority: 7, content: hotFilesSection });
694
+ }
695
+ }
696
+ if (opts.includeCommits) {
697
+ const commitsSection = buildRecentCommitsSection(
698
+ enriched?.recentCommits ?? context.recentCommitMessages
699
+ );
700
+ if (commitsSection) {
701
+ sections.push({ priority: 8, content: commitsSection });
702
+ }
703
+ }
704
+ const nextStep = resolveNextStep(meaningfulCheckpoint, briefing);
705
+ sections.push({
706
+ priority: 9,
707
+ content: `---
708
+ Please help me continue this work. My next step is: ${nextStep}.`
709
+ });
710
+ return applySmartTruncation(sections, opts.maxLength);
711
+ }
712
+ function buildHeader(context) {
713
+ return [
714
+ `# Project Context: ${context.projectName}`,
715
+ "",
716
+ "I'm continuing work on a project. Here is my development context."
717
+ ].join("\n");
718
+ }
719
+ function buildProjectSection(context) {
720
+ const lines = ["", "## Project"];
721
+ let hasContent = false;
542
722
  if (context.gitBranch) {
543
723
  lines.push(`- **Branch:** ${context.gitBranch}`);
724
+ hasContent = true;
725
+ }
726
+ if (context.projectMeta?.createdAt) {
727
+ lines.push(`- **Tracking since:** ${formatRelativeTime(context.projectMeta.createdAt)}`);
728
+ hasContent = true;
544
729
  }
545
- if (context.briefing) {
730
+ if (context.briefing?.lastWorked) {
546
731
  lines.push(`- **Last worked:** ${context.briefing.lastWorked}`);
547
- lines.push(`- **Focus:** ${context.briefing.currentFocus}`);
548
- } else if (context.lastCheckpoint) {
549
- lines.push(`- **Last worked:** ${formatRelativeTime(context.lastCheckpoint.timestamp)}`);
550
- if (context.lastCheckpoint.summary) {
551
- lines.push(`- **Focus:** ${context.lastCheckpoint.summary}`);
552
- }
732
+ hasContent = true;
553
733
  }
554
- if (context.lastCheckpoint) {
555
- lines.push("");
556
- lines.push("## Last Session");
557
- if (context.lastCheckpoint.summary) {
558
- lines.push(`- **Summary:** ${context.lastCheckpoint.summary}`);
559
- }
560
- if (context.lastCheckpoint.nextStep) {
561
- lines.push(`- **Next step:** ${context.lastCheckpoint.nextStep}`);
562
- }
563
- if (context.lastCheckpoint.blocker) {
564
- lines.push(`- **Blocker:** ${context.lastCheckpoint.blocker}`);
565
- }
566
- if (opts.includeFiles && context.lastCheckpoint.touchedFiles.length > 0) {
567
- const files = context.lastCheckpoint.touchedFiles.slice(0, 10).join(", ");
568
- const extra = context.lastCheckpoint.touchedFiles.length > 10 ? ` (+${context.lastCheckpoint.touchedFiles.length - 10} more)` : "";
569
- lines.push(`- **Files touched:** ${files}${extra}`);
570
- }
734
+ return hasContent ? lines.join("\n") : null;
735
+ }
736
+ function buildLeftOffSection(checkpoint, briefing) {
737
+ if (!checkpoint && !briefing) return null;
738
+ const lines = ["", "## Where I Left Off"];
739
+ let hasContent = false;
740
+ if (checkpoint?.summary) {
741
+ lines.push(`- **Summary:** ${checkpoint.summary}`);
742
+ hasContent = true;
571
743
  }
572
- const activeTasks = context.currentTasks.filter((t) => t.sessionActive);
573
- if (activeTasks.length > 0) {
574
- lines.push("");
575
- lines.push("## Active Sessions");
576
- for (const task of activeTasks) {
577
- const label = task.agentLabel || "Unknown agent";
578
- const branch = task.branch ? ` on \`${task.branch}\`` : "";
579
- lines.push(`- **${label}**${branch}: ${task.taskSummary || "Working"}`);
580
- }
744
+ const nextStep = checkpoint?.nextStep || briefing?.smallNextStep;
745
+ if (nextStep) {
746
+ lines.push(`- **Next step:** ${nextStep}`);
747
+ hasContent = true;
581
748
  }
582
- if (context.recentDecisions.length > 0) {
583
- lines.push("");
584
- lines.push("## Recent Decisions");
585
- for (const d of context.recentDecisions) {
586
- lines.push(`- ${d.classification.category}: ${d.commitMessage}`);
587
- }
749
+ if (checkpoint?.blocker) {
750
+ lines.push(`- **Blocker:** ${checkpoint.blocker}`);
751
+ hasContent = true;
588
752
  }
589
- if (opts.includeCommits && context.recentCommitMessages.length > 0) {
590
- lines.push("");
591
- lines.push("## Recent Commits");
592
- const commits = context.recentCommitMessages.slice(0, 10);
593
- for (const msg of commits) {
594
- lines.push(`- ${msg}`);
753
+ return hasContent ? lines.join("\n") : null;
754
+ }
755
+ function buildRecentSessionsSection(checkpoints) {
756
+ const meaningful = checkpoints.filter((cp) => {
757
+ if (cp.source === "auto" && !cp.nextStep && NOISE_SUMMARY_PATTERN.test(cp.summary || "")) {
758
+ return false;
595
759
  }
760
+ return !!cp.summary;
761
+ });
762
+ if (meaningful.length <= 1) return null;
763
+ const lines = ["", "## Recent Sessions"];
764
+ for (const cp of meaningful) {
765
+ const when = formatRelativeTime(cp.timestamp);
766
+ const summary = cp.summary.length > 100 ? cp.summary.slice(0, 97) + "..." : cp.summary;
767
+ lines.push(`- ${when}: ${summary}`);
768
+ }
769
+ return lines.join("\n");
770
+ }
771
+ function buildActiveWorkSection(tasks) {
772
+ const activeTasks = tasks.filter((t2) => t2.sessionActive);
773
+ if (activeTasks.length === 0) return null;
774
+ const lines = ["", "## Active Work"];
775
+ for (const task of activeTasks) {
776
+ const label = task.agentLabel || "Unknown agent";
777
+ const branch = task.branch ? ` on \`${task.branch}\`` : "";
778
+ lines.push(`- **${label}**${branch}: ${task.taskSummary || "Working"}`);
779
+ if (task.nextStep) {
780
+ lines.push(` - Next: ${task.nextStep}`);
781
+ }
782
+ if (task.lastFileEdited) {
783
+ lines.push(` - Last file: ${task.lastFileEdited}`);
784
+ }
785
+ }
786
+ return lines.join("\n");
787
+ }
788
+ function buildDecisionsSection(decisions) {
789
+ const filtered = filterNoiseDecisions(decisions);
790
+ if (filtered.length === 0) return null;
791
+ const lines = ["", "## Key Decisions"];
792
+ for (const d3 of filtered) {
793
+ lines.push(`- ${d3.classification.category}: ${d3.commitMessage}`);
794
+ }
795
+ return lines.join("\n");
796
+ }
797
+ function buildHotFilesSection(files) {
798
+ if (files.length === 0) return null;
799
+ const display = files.slice(0, 15);
800
+ const extra = files.length > 15 ? ` (+${files.length - 15} more)` : "";
801
+ return ["", "## Hot Files", display.join(", ") + extra].join("\n");
802
+ }
803
+ function buildRecentCommitsSection(commits) {
804
+ if (commits.length === 0) return null;
805
+ const lines = ["", "## Recent Commits"];
806
+ const display = commits.slice(0, 10);
807
+ for (const msg of display) {
808
+ lines.push(`- ${msg}`);
809
+ }
810
+ return lines.join("\n");
811
+ }
812
+ function resolveNextStep(checkpoint, briefing) {
813
+ if (checkpoint?.nextStep) return checkpoint.nextStep;
814
+ if (briefing?.smallNextStep) return briefing.smallNextStep;
815
+ if (briefing?.suggestedNext) return briefing.suggestedNext;
816
+ return "continue where I left off";
817
+ }
818
+ function applySmartTruncation(sections, maxLength) {
819
+ if (!maxLength) {
820
+ return sections.sort((a, b) => a.priority - b.priority).map((s) => s.content).join("\n");
821
+ }
822
+ let sorted = [...sections].sort((a, b) => a.priority - b.priority);
823
+ const join = (s) => s.map((x) => x.content).join("\n");
824
+ if (join(sorted).length <= maxLength) {
825
+ return join(sorted);
826
+ }
827
+ const dropOrder = [8, 7];
828
+ for (const prio of dropOrder) {
829
+ sorted = sorted.filter((s) => s.priority !== prio);
830
+ if (join(sorted).length <= maxLength) {
831
+ return join(sorted);
832
+ }
833
+ }
834
+ sorted = sorted.map((s) => {
835
+ if (s.priority === 4 && s.content.includes("## Recent Sessions")) {
836
+ const lines = s.content.split("\n");
837
+ const header = lines.slice(0, 2);
838
+ const entries = lines.slice(2, 5);
839
+ return { ...s, content: [...header, ...entries].join("\n") };
840
+ }
841
+ return s;
842
+ });
843
+ if (join(sorted).length <= maxLength) {
844
+ return join(sorted);
596
845
  }
597
- lines.push("");
598
- lines.push("---");
599
- const nextStep = context.lastCheckpoint?.nextStep || context.briefing?.suggestedNext || "continue where I left off";
600
- lines.push(`Please help me continue this work. My next step is: ${nextStep}.`);
601
- let result = lines.join("\n");
602
- if (opts.maxLength && result.length > opts.maxLength) {
603
- result = result.slice(0, opts.maxLength - 3) + "...";
846
+ sorted = sorted.filter((s) => s.priority !== 5);
847
+ if (join(sorted).length <= maxLength) {
848
+ return join(sorted);
604
849
  }
605
- return result;
850
+ sorted = sorted.filter((s) => s.priority !== 4);
851
+ if (join(sorted).length <= maxLength) {
852
+ return join(sorted);
853
+ }
854
+ const result = join(sorted);
855
+ return result.slice(0, maxLength - 3) + "...";
606
856
  }
607
857
 
608
858
  // ../../packages/shared/src/reader.ts
@@ -788,7 +1038,7 @@ function readTrayConfigProjects() {
788
1038
  if (fs2.existsSync(TRAY_CONFIG_FILE)) {
789
1039
  const raw = JSON.parse(fs2.readFileSync(TRAY_CONFIG_FILE, "utf-8"));
790
1040
  if (raw && Array.isArray(raw.projects)) {
791
- return raw.projects.filter((p) => typeof p === "string");
1041
+ return raw.projects.filter((p2) => typeof p2 === "string");
792
1042
  }
793
1043
  }
794
1044
  } catch {
@@ -820,7 +1070,7 @@ function registerProject(projectPath, projectName) {
820
1070
  const data = readKnownProjects();
821
1071
  const now = (/* @__PURE__ */ new Date()).toISOString();
822
1072
  const name = projectName || path4.basename(projectPath);
823
- const existingIdx = data.projects.findIndex((p) => p.path === projectPath);
1073
+ const existingIdx = data.projects.findIndex((p2) => p2.path === projectPath);
824
1074
  if (existingIdx >= 0) {
825
1075
  data.projects[existingIdx].lastSeen = now;
826
1076
  if (projectName) {
@@ -830,7 +1080,7 @@ function registerProject(projectPath, projectName) {
830
1080
  data.projects.push({ path: projectPath, name, lastSeen: now });
831
1081
  }
832
1082
  const cutoff = Date.now() - STALE_PROJECT_MS;
833
- data.projects = data.projects.filter((p) => new Date(p.lastSeen).getTime() > cutoff && fs2.existsSync(p.path));
1083
+ data.projects = data.projects.filter((p2) => new Date(p2.lastSeen).getTime() > cutoff && fs2.existsSync(p2.path));
834
1084
  writeKnownProjects(data);
835
1085
  } catch {
836
1086
  }
@@ -845,8 +1095,8 @@ var CURRENT_TASKS_FILE = "current-tasks.json";
845
1095
  var STALE_SESSION_MS = 2 * 60 * 60 * 1e3;
846
1096
  function pruneStaleTasks(tasks) {
847
1097
  const now = Date.now();
848
- return tasks.filter((t) => {
849
- const updatedAt = new Date(t.updatedAt).getTime();
1098
+ return tasks.filter((t2) => {
1099
+ const updatedAt = new Date(t2.updatedAt).getTime();
850
1100
  return !isNaN(updatedAt) && now - updatedAt < STALE_SESSION_MS;
851
1101
  });
852
1102
  }
@@ -977,7 +1227,7 @@ var KeepGoingWriter = class {
977
1227
  if (update.sessionLabel) update.sessionLabel = stripAgentTags(update.sessionLabel);
978
1228
  const sessionId = update.sessionId || generateSessionId(update);
979
1229
  const tasks = this.readAllTasksRaw();
980
- const existingIdx = tasks.findIndex((t) => t.sessionId === sessionId);
1230
+ const existingIdx = tasks.findIndex((t2) => t2.sessionId === sessionId);
981
1231
  let merged;
982
1232
  if (existingIdx >= 0) {
983
1233
  const existing = tasks[existingIdx];
@@ -993,16 +1243,16 @@ var KeepGoingWriter = class {
993
1243
  }
994
1244
  /** Remove a specific session by ID. */
995
1245
  removeSession(sessionId) {
996
- const tasks = this.readAllTasksRaw().filter((t) => t.sessionId !== sessionId);
1246
+ const tasks = this.readAllTasksRaw().filter((t2) => t2.sessionId !== sessionId);
997
1247
  this.writeTasksFile(tasks);
998
1248
  }
999
1249
  /** Get all active sessions (sessionActive=true and within stale threshold). */
1000
1250
  getActiveSessions() {
1001
- return this.readCurrentTasks().filter((t) => t.sessionActive);
1251
+ return this.readCurrentTasks().filter((t2) => t2.sessionActive);
1002
1252
  }
1003
1253
  /** Get a specific session by ID. */
1004
1254
  getSession(sessionId) {
1005
- return this.readCurrentTasks().find((t) => t.sessionId === sessionId);
1255
+ return this.readCurrentTasks().find((t2) => t2.sessionId === sessionId);
1006
1256
  }
1007
1257
  // ---------------------------------------------------------------------------
1008
1258
  // Private helpers
@@ -1145,11 +1395,11 @@ var KeepGoingReader = class {
1145
1395
  }
1146
1396
  /** Get only active sessions (sessionActive=true and within stale threshold). */
1147
1397
  getActiveTasks() {
1148
- return this.getCurrentTasks().filter((t) => t.sessionActive);
1398
+ return this.getCurrentTasks().filter((t2) => t2.sessionActive);
1149
1399
  }
1150
1400
  /** Get a specific session by ID. */
1151
1401
  getTaskBySessionId(sessionId) {
1152
- return this.getCurrentTasks().find((t) => t.sessionId === sessionId);
1402
+ return this.getCurrentTasks().find((t2) => t2.sessionId === sessionId);
1153
1403
  }
1154
1404
  /**
1155
1405
  * Detect files being edited by multiple sessions simultaneously.
@@ -1215,7 +1465,7 @@ var KeepGoingReader = class {
1215
1465
  }
1216
1466
  /** Returns the last N decisions for a specific branch, newest first. */
1217
1467
  getRecentDecisionsForBranch(branch, count) {
1218
- const filtered = this.getDecisions().filter((d) => d.gitBranch === branch);
1468
+ const filtered = this.getDecisions().filter((d3) => d3.gitBranch === branch);
1219
1469
  return filtered.slice(-count).reverse();
1220
1470
  }
1221
1471
  /** Whether the workspace is inside a git worktree. */
@@ -1366,7 +1616,7 @@ function categorizeCommits(messages) {
1366
1616
  function inferWorkAreas(files) {
1367
1617
  const areas = /* @__PURE__ */ new Map();
1368
1618
  for (const file of files) {
1369
- if (NOISE_PATTERNS.some((p) => file.includes(p))) {
1619
+ if (NOISE_PATTERNS.some((p2) => file.includes(p2))) {
1370
1620
  continue;
1371
1621
  }
1372
1622
  const parts = file.split("/").filter(Boolean);
@@ -1394,7 +1644,7 @@ function buildSessionEvents(opts) {
1394
1644
  filesChanged: getFilesChangedInCommit(wsPath, hash),
1395
1645
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
1396
1646
  }));
1397
- const committedFiles = new Set(commits.flatMap((c) => c.filesChanged));
1647
+ const committedFiles = new Set(commits.flatMap((c2) => c2.filesChanged));
1398
1648
  return {
1399
1649
  commits,
1400
1650
  branchSwitches: [],
@@ -1417,7 +1667,7 @@ function buildSmartSummary(events) {
1417
1667
  }
1418
1668
  const parts = [];
1419
1669
  if (commits.length > 0) {
1420
- const messages = commits.map((c) => c.message);
1670
+ const messages = commits.map((c2) => c2.message);
1421
1671
  const groups = categorizeCommits(messages);
1422
1672
  const phrases = [];
1423
1673
  for (const [prefix, bodies] of groups) {
@@ -1650,7 +1900,7 @@ var MOMENTUM_RANK = { hot: 0, warm: 1, cold: 2 };
1650
1900
  function generateCrossProjectSummary() {
1651
1901
  const registry = readKnownProjects();
1652
1902
  const trayPaths = readTrayConfigProjects();
1653
- const seenPaths = new Set(registry.projects.map((p) => p.path));
1903
+ const seenPaths = new Set(registry.projects.map((p2) => p2.path));
1654
1904
  const allEntries = [...registry.projects];
1655
1905
  for (const tp of trayPaths) {
1656
1906
  if (!seenPaths.has(tp)) {
@@ -1754,16 +2004,26 @@ var SESSION_END_HOOK = {
1754
2004
  }
1755
2005
  ]
1756
2006
  };
1757
- var KEEPGOING_RULES_VERSION = 3;
2007
+ var CLAUDE_MD_SECTION = `
2008
+ ## KeepGoing
2009
+
2010
+ After completing a task or meaningful piece of work, call the \`save_checkpoint\` MCP tool with:
2011
+ - \`summary\`: 1 sentence, max 140 chars. What changed and why, no file paths.
2012
+ - \`nextStep\`: Max 100 chars. What to do next.
2013
+ - \`blocker\`: Max 100 chars. Any blocker (if applicable).
2014
+ `;
2015
+ var KEEPGOING_RULES_VERSION = 4;
1758
2016
  var KEEPGOING_RULES_CONTENT = `<!-- @keepgoingdev/mcp-server v${KEEPGOING_RULES_VERSION} -->
1759
2017
  ## KeepGoing
1760
2018
 
1761
2019
  When you see KeepGoing momentum data in your session context (from a SessionStart hook), share a brief welcome with the user that includes: what was last worked on, the suggested next step, and any blockers.
1762
2020
 
1763
2021
  After completing a task or meaningful piece of work, call the \`save_checkpoint\` MCP tool with:
1764
- - \`summary\`: 1-2 sentences. What changed and why, no file paths, no implementation details (those are captured from git).
1765
- - \`nextStep\`: What to do next
1766
- - \`blocker\`: Any blocker (if applicable)
2022
+ - \`summary\`: 1 sentence, max 140 chars. What changed and why, no file paths or implementation details.
2023
+ - \`nextStep\`: Max 100 chars. What to do next.
2024
+ - \`blocker\`: Max 100 chars. Any blocker (if applicable).
2025
+
2026
+ Keep checkpoint text concise. Git diffs and file lists are captured automatically.
1767
2027
 
1768
2028
  When working in plan mode (investigating, designing, iterating on an approach before any edits), call \`save_checkpoint\` when you reach a significant milestone or conclusion. Use the summary to capture what was investigated and decided. This preserves planning context for future sessions.
1769
2029
  `;
@@ -1955,6 +2215,114 @@ function setupProject(options) {
1955
2215
  return { messages, changed };
1956
2216
  }
1957
2217
 
2218
+ // ../../packages/shared/src/mcpRegistration.ts
2219
+ import fs8 from "fs";
2220
+ import path10 from "path";
2221
+ import os4 from "os";
2222
+ import { execSync, execFile as execFile2 } from "child_process";
2223
+ var MCP_SERVER_ENTRY = {
2224
+ type: "stdio",
2225
+ command: "npx",
2226
+ args: ["-y", "@keepgoingdev/mcp-server"]
2227
+ };
2228
+ function isClaudeCodeInstalled() {
2229
+ try {
2230
+ execSync("which claude", { stdio: ["pipe", "pipe", "pipe"] });
2231
+ return true;
2232
+ } catch {
2233
+ return false;
2234
+ }
2235
+ }
2236
+ function registerCopilotMcp(workspacePath) {
2237
+ const vscodeDirPath = path10.join(workspacePath, ".vscode");
2238
+ const mcpJsonPath = path10.join(vscodeDirPath, "mcp.json");
2239
+ let config = {};
2240
+ if (fs8.existsSync(mcpJsonPath)) {
2241
+ try {
2242
+ config = JSON.parse(fs8.readFileSync(mcpJsonPath, "utf-8"));
2243
+ } catch {
2244
+ return { action: "already_configured", message: "Failed to parse .vscode/mcp.json. Fix the JSON and try again." };
2245
+ }
2246
+ }
2247
+ if (!config.servers) {
2248
+ config.servers = {};
2249
+ }
2250
+ const servers = config.servers;
2251
+ if (servers["keepgoing"]) {
2252
+ return { action: "already_configured", message: "GitHub Copilot MCP already configured in .vscode/mcp.json" };
2253
+ }
2254
+ servers["keepgoing"] = MCP_SERVER_ENTRY;
2255
+ fs8.mkdirSync(vscodeDirPath, { recursive: true });
2256
+ fs8.writeFileSync(mcpJsonPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
2257
+ return { action: "created", message: ".vscode/mcp.json written" };
2258
+ }
2259
+ function writeCopilotInstructions(workspacePath) {
2260
+ const githubDir = path10.join(workspacePath, ".github");
2261
+ const instructionsPath = path10.join(githubDir, "copilot-instructions.md");
2262
+ let existing = "";
2263
+ if (fs8.existsSync(instructionsPath)) {
2264
+ existing = fs8.readFileSync(instructionsPath, "utf-8");
2265
+ }
2266
+ if (existing.includes("## KeepGoing")) {
2267
+ return { action: "already_configured", message: "copilot-instructions.md already has KeepGoing section" };
2268
+ }
2269
+ fs8.mkdirSync(githubDir, { recursive: true });
2270
+ fs8.writeFileSync(instructionsPath, existing + CLAUDE_MD_SECTION, "utf-8");
2271
+ return { action: "created", message: ".github/copilot-instructions.md written" };
2272
+ }
2273
+ function registerCursorMcp() {
2274
+ const configPath = path10.join(os4.homedir(), ".cursor", "mcp.json");
2275
+ return registerGlobalMcp(configPath, "mcpServers", "Cursor");
2276
+ }
2277
+ function registerWindsurfMcp() {
2278
+ const configPath = path10.join(os4.homedir(), ".codeium", "windsurf", "mcp_config.json");
2279
+ return registerGlobalMcp(configPath, "mcpServers", "Windsurf");
2280
+ }
2281
+ function registerGlobalMcp(configPath, serversKey, toolName) {
2282
+ let config = {};
2283
+ if (fs8.existsSync(configPath)) {
2284
+ try {
2285
+ config = JSON.parse(fs8.readFileSync(configPath, "utf-8"));
2286
+ } catch {
2287
+ return { action: "already_configured", message: `Failed to parse ${configPath}. Fix the JSON and try again.` };
2288
+ }
2289
+ }
2290
+ if (!config[serversKey]) {
2291
+ config[serversKey] = {};
2292
+ }
2293
+ const servers = config[serversKey];
2294
+ if (servers["keepgoing"]) {
2295
+ return { action: "already_configured", message: `${toolName} MCP already configured` };
2296
+ }
2297
+ servers["keepgoing"] = {
2298
+ command: "npx",
2299
+ args: ["-y", "@keepgoingdev/mcp-server"]
2300
+ };
2301
+ fs8.mkdirSync(path10.dirname(configPath), { recursive: true });
2302
+ fs8.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
2303
+ return { action: "created", message: `${toolName} MCP config written to ${configPath}` };
2304
+ }
2305
+ function registerClaudeCodeMcp(workspacePath) {
2306
+ return new Promise((resolve) => {
2307
+ execFile2(
2308
+ "claude",
2309
+ ["mcp", "add", "keepgoing", "--scope", "project", "--", "npx", "-y", "@keepgoingdev/mcp-server"],
2310
+ { timeout: 1e4, cwd: workspacePath },
2311
+ (error) => {
2312
+ if (error) {
2313
+ if (error.code === "ENOENT") {
2314
+ resolve({ action: "already_configured", message: "Claude Code CLI not found. Install from https://claude.ai/code" });
2315
+ } else {
2316
+ resolve({ action: "already_configured", message: `Failed to register MCP: ${error.message}` });
2317
+ }
2318
+ } else {
2319
+ resolve({ action: "created", message: "Claude Code MCP server registered" });
2320
+ }
2321
+ }
2322
+ );
2323
+ });
2324
+ }
2325
+
1958
2326
  // ../../packages/shared/src/licenseClient.ts
1959
2327
  var BASE_URL = "https://api.lemonsqueezy.com/v1/licenses";
1960
2328
  var REQUEST_TIMEOUT_MS = 15e3;
@@ -2231,12 +2599,12 @@ function renderDecisions(decisions, scopeLabel) {
2231
2599
  console.log(`
2232
2600
  ${BOLD}KeepGoing Decisions${RESET} ${DIM}(last ${decisions.length}, ${scopeLabel})${RESET}
2233
2601
  `);
2234
- for (const d of decisions) {
2235
- const relTime = formatRelativeTime(d.timestamp);
2236
- const confidence = `${(d.classification.confidence * 100).toFixed(0)}%`;
2237
- console.log(` ${label(d.classification.category + ":")} ${d.commitMessage} ${DIM}${confidence} \xB7 ${relTime}${RESET}`);
2238
- if (d.classification.reasons.length > 0) {
2239
- console.log(` ${DIM}Signals: ${d.classification.reasons.join("; ")}${RESET}`);
2602
+ for (const d3 of decisions) {
2603
+ const relTime = formatRelativeTime(d3.timestamp);
2604
+ const confidence = `${(d3.classification.confidence * 100).toFixed(0)}%`;
2605
+ console.log(` ${label(d3.classification.category + ":")} ${d3.commitMessage} ${DIM}${confidence} \xB7 ${relTime}${RESET}`);
2606
+ if (d3.classification.reasons.length > 0) {
2607
+ console.log(` ${DIM}Signals: ${d3.classification.reasons.join("; ")}${RESET}`);
2240
2608
  }
2241
2609
  }
2242
2610
  console.log("");
@@ -2374,9 +2742,9 @@ ${BOLD}KeepGoing Re-entry Briefing${RESET} ${DIM}(${tier})${RESET}
2374
2742
  if (briefing.decisions && briefing.decisions.length > 0) {
2375
2743
  console.log(`
2376
2744
  ${label("Recent decisions:")}`);
2377
- for (const d of briefing.decisions) {
2378
- const relTime = formatRelativeTime(d.timestamp);
2379
- console.log(` ${d.classification.category}: ${d.commitMessage} ${DIM}(${relTime})${RESET}`);
2745
+ for (const d3 of briefing.decisions) {
2746
+ const relTime = formatRelativeTime(d3.timestamp);
2747
+ console.log(` ${d3.classification.category}: ${d3.commitMessage} ${DIM}(${relTime})${RESET}`);
2380
2748
  }
2381
2749
  }
2382
2750
  if (briefing.touchedFiles && briefing.touchedFiles.length > 0) {
@@ -2413,9 +2781,9 @@ ${BOLD}KeepGoing Re-entry Briefing${RESET} ${DIM}(${tier})${RESET}
2413
2781
  if (briefing.fileConflicts && briefing.fileConflicts.length > 0) {
2414
2782
  console.log(`
2415
2783
  ${YELLOW}File conflicts:${RESET}`);
2416
- for (const c of briefing.fileConflicts) {
2417
- const labels = c.sessions.map((s) => s.agentLabel || s.sessionId).join(", ");
2418
- console.log(` ${c.file}: ${labels}`);
2784
+ for (const c2 of briefing.fileConflicts) {
2785
+ const labels = c2.sessions.map((s) => s.agentLabel || s.sessionId).join(", ");
2786
+ console.log(` ${c2.file}: ${labels}`);
2419
2787
  }
2420
2788
  }
2421
2789
  if (briefing.branchOverlaps && briefing.branchOverlaps.length > 0) {
@@ -2433,96 +2801,7 @@ function renderEnrichedBriefingQuiet(briefing) {
2433
2801
  console.log(`KeepGoing \xB7 ${core.lastWorked} \xB7 Focus: ${core.currentFocus} \xB7 Next: ${core.smallNextStep}`);
2434
2802
  }
2435
2803
 
2436
- // src/updateCheck.ts
2437
- import { spawn } from "child_process";
2438
- import { readFileSync, existsSync } from "fs";
2439
- import path10 from "path";
2440
- import os4 from "os";
2441
- var CLI_VERSION = "1.3.3";
2442
- var NPM_REGISTRY_URL = "https://registry.npmjs.org/@keepgoingdev/cli/latest";
2443
- var FETCH_TIMEOUT_MS = 5e3;
2444
- var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
2445
- var CACHE_DIR = path10.join(os4.homedir(), ".keepgoing");
2446
- var CACHE_PATH = path10.join(CACHE_DIR, "update-check.json");
2447
- function isNewerVersion(current, latest) {
2448
- const cur = current.split(".").map(Number);
2449
- const lat = latest.split(".").map(Number);
2450
- for (let i = 0; i < 3; i++) {
2451
- if ((lat[i] ?? 0) > (cur[i] ?? 0)) return true;
2452
- if ((lat[i] ?? 0) < (cur[i] ?? 0)) return false;
2453
- }
2454
- return false;
2455
- }
2456
- function getCachedUpdateInfo() {
2457
- try {
2458
- if (!existsSync(CACHE_PATH)) return null;
2459
- const raw = readFileSync(CACHE_PATH, "utf-8");
2460
- const cache = JSON.parse(raw);
2461
- if (!cache.latest || !cache.checkedAt) return null;
2462
- const age = Date.now() - new Date(cache.checkedAt).getTime();
2463
- if (age > CHECK_INTERVAL_MS || cache.current !== CLI_VERSION) return null;
2464
- return {
2465
- current: CLI_VERSION,
2466
- latest: cache.latest,
2467
- updateAvailable: isNewerVersion(CLI_VERSION, cache.latest)
2468
- };
2469
- } catch {
2470
- return null;
2471
- }
2472
- }
2473
- function spawnBackgroundCheck() {
2474
- try {
2475
- if (existsSync(CACHE_PATH)) {
2476
- const raw = readFileSync(CACHE_PATH, "utf-8");
2477
- const cache = JSON.parse(raw);
2478
- const age = Date.now() - new Date(cache.checkedAt).getTime();
2479
- if (age < CHECK_INTERVAL_MS && cache.current === CLI_VERSION) return;
2480
- }
2481
- } catch {
2482
- }
2483
- const script = `
2484
- const https = require('https');
2485
- const fs = require('fs');
2486
- const path = require('path');
2487
- const os = require('os');
2488
-
2489
- const url = ${JSON.stringify(NPM_REGISTRY_URL)};
2490
- const cacheDir = path.join(os.homedir(), '.keepgoing');
2491
- const cachePath = path.join(cacheDir, 'update-check.json');
2492
- const currentVersion = ${JSON.stringify(CLI_VERSION)};
2493
-
2494
- const req = https.get(url, { timeout: ${FETCH_TIMEOUT_MS} }, (res) => {
2495
- let data = '';
2496
- res.on('data', (chunk) => { data += chunk; });
2497
- res.on('end', () => {
2498
- try {
2499
- const latest = JSON.parse(data).version;
2500
- if (!latest) process.exit(0);
2501
- if (!fs.existsSync(cacheDir)) fs.mkdirSync(cacheDir, { recursive: true });
2502
- fs.writeFileSync(cachePath, JSON.stringify({
2503
- latest,
2504
- current: currentVersion,
2505
- checkedAt: new Date().toISOString(),
2506
- }));
2507
- } catch {}
2508
- process.exit(0);
2509
- });
2510
- });
2511
- req.on('error', () => process.exit(0));
2512
- req.on('timeout', () => { req.destroy(); process.exit(0); });
2513
- `;
2514
- const child = spawn(process.execPath, ["-e", script], {
2515
- detached: true,
2516
- stdio: "ignore",
2517
- env: { ...process.env }
2518
- });
2519
- child.unref();
2520
- }
2521
-
2522
2804
  // src/commands/status.ts
2523
- var RESET2 = "\x1B[0m";
2524
- var BOLD2 = "\x1B[1m";
2525
- var DIM2 = "\x1B[2m";
2526
2805
  async function statusCommand(opts) {
2527
2806
  const reader = new KeepGoingReader(opts.cwd);
2528
2807
  if (!reader.exists()) {
@@ -2550,11 +2829,6 @@ async function statusCommand(opts) {
2550
2829
  (Date.now() - new Date(lastSession.timestamp).getTime()) / (1e3 * 60 * 60 * 24)
2551
2830
  );
2552
2831
  renderCheckpoint(lastSession, daysSince);
2553
- const cached = getCachedUpdateInfo();
2554
- if (cached?.updateAvailable) {
2555
- console.log(`${DIM2}Update available: ${cached.current} \u2192 ${cached.latest}. Run: ${RESET2}${BOLD2}npm install -g @keepgoingdev/cli@latest${RESET2}`);
2556
- }
2557
- spawnBackgroundCheck();
2558
2832
  }
2559
2833
 
2560
2834
  // src/commands/save.ts
@@ -2622,10 +2896,10 @@ async function saveCommand(opts) {
2622
2896
  }
2623
2897
 
2624
2898
  // src/commands/hook.ts
2625
- import fs8 from "fs";
2899
+ import fs9 from "fs";
2626
2900
  import path12 from "path";
2627
2901
  import os5 from "os";
2628
- import { execSync } from "child_process";
2902
+ import { execSync as execSync2 } from "child_process";
2629
2903
  var HOOK_MARKER_START = "# keepgoing-hook-start";
2630
2904
  var HOOK_MARKER_END = "# keepgoing-hook-end";
2631
2905
  var POST_COMMIT_MARKER_START = "# keepgoing-post-commit-start";
@@ -2672,14 +2946,14 @@ if command -v keepgoing >/dev/null 2>&1
2672
2946
  end
2673
2947
  end
2674
2948
  ${HOOK_MARKER_END}`;
2675
- function detectShellRcFile(shellOverride) {
2949
+ function detectShellInfo(shellOverride) {
2676
2950
  const home = os5.homedir();
2677
2951
  let shell;
2678
2952
  if (shellOverride) {
2679
2953
  shell = shellOverride.toLowerCase();
2680
2954
  } else {
2681
2955
  try {
2682
- const parentComm = execSync(`ps -o comm= -p ${process.ppid}`, {
2956
+ const parentComm = execSync2(`ps -o comm= -p ${process.ppid}`, {
2683
2957
  encoding: "utf-8",
2684
2958
  stdio: ["pipe", "pipe", "pipe"]
2685
2959
  }).trim();
@@ -2707,9 +2981,29 @@ function detectShellRcFile(shellOverride) {
2707
2981
  }
2708
2982
  return void 0;
2709
2983
  }
2984
+ function performHookInstall(shellOverride) {
2985
+ const detected = detectShellInfo(shellOverride);
2986
+ if (!detected) {
2987
+ return { success: false, message: 'Could not detect your shell. Set $SHELL to "zsh", "bash", or "fish" and try again.' };
2988
+ }
2989
+ const { shell, rcFile } = detected;
2990
+ const hookBlock = shell === "zsh" ? ZSH_HOOK : shell === "fish" ? FISH_HOOK : BASH_HOOK;
2991
+ let existing = "";
2992
+ try {
2993
+ existing = fs9.readFileSync(rcFile, "utf-8");
2994
+ } catch {
2995
+ }
2996
+ if (existing.includes(HOOK_MARKER_START)) {
2997
+ return { success: true, message: `Shell hook already installed in ${rcFile}` };
2998
+ }
2999
+ fs9.appendFileSync(rcFile, `
3000
+ ${hookBlock}
3001
+ `, "utf-8");
3002
+ return { success: true, message: `Shell hook installed in ${rcFile}` };
3003
+ }
2710
3004
  function resolveGlobalGitignorePath() {
2711
3005
  try {
2712
- const configured = execSync("git config --global core.excludesfile", {
3006
+ const configured = execSync2("git config --global core.excludesfile", {
2713
3007
  encoding: "utf-8",
2714
3008
  stdio: ["pipe", "pipe", "pipe"]
2715
3009
  }).trim();
@@ -2720,56 +3014,40 @@ function resolveGlobalGitignorePath() {
2720
3014
  }
2721
3015
  return path12.join(os5.homedir(), ".gitignore_global");
2722
3016
  }
2723
- function installGlobalGitignore() {
3017
+ function performGlobalGitignore() {
2724
3018
  const ignorePath = resolveGlobalGitignorePath();
2725
3019
  let existing = "";
2726
3020
  try {
2727
- existing = fs8.readFileSync(ignorePath, "utf-8");
3021
+ existing = fs9.readFileSync(ignorePath, "utf-8");
2728
3022
  } catch {
2729
3023
  }
2730
3024
  if (existing.split("\n").some((line) => line.trim() === ".keepgoing")) {
2731
- console.log(`Global gitignore: .keepgoing already present in ${ignorePath}`);
2732
- } else {
2733
- const suffix = existing.length > 0 && !existing.endsWith("\n") ? "\n" : "";
2734
- fs8.appendFileSync(ignorePath, `${suffix}.keepgoing
2735
- `, "utf-8");
2736
- console.log(`Global gitignore: .keepgoing added to ${ignorePath}`);
3025
+ return { success: true, message: `Global gitignore: .keepgoing already present in ${ignorePath}` };
2737
3026
  }
3027
+ const suffix = existing.length > 0 && !existing.endsWith("\n") ? "\n" : "";
3028
+ fs9.appendFileSync(ignorePath, `${suffix}.keepgoing
3029
+ `, "utf-8");
2738
3030
  try {
2739
- execSync("git config --global core.excludesfile", {
3031
+ execSync2("git config --global core.excludesfile", {
2740
3032
  encoding: "utf-8",
2741
3033
  stdio: ["pipe", "pipe", "pipe"]
2742
3034
  }).trim();
2743
3035
  } catch {
2744
- execSync(`git config --global core.excludesfile "${ignorePath}"`, {
3036
+ execSync2(`git config --global core.excludesfile "${ignorePath}"`, {
2745
3037
  stdio: ["pipe", "pipe", "pipe"]
2746
3038
  });
2747
3039
  }
3040
+ return { success: true, message: `Global gitignore: .keepgoing added to ${ignorePath}` };
2748
3041
  }
2749
- function uninstallGlobalGitignore() {
2750
- const ignorePath = resolveGlobalGitignorePath();
2751
- let existing = "";
2752
- try {
2753
- existing = fs8.readFileSync(ignorePath, "utf-8");
2754
- } catch {
2755
- return;
2756
- }
2757
- const lines = existing.split("\n");
2758
- const filtered = lines.filter((line) => line.trim() !== ".keepgoing");
2759
- if (filtered.length !== lines.length) {
2760
- fs8.writeFileSync(ignorePath, filtered.join("\n"), "utf-8");
2761
- console.log(`Global gitignore: .keepgoing removed from ${ignorePath}`);
2762
- }
2763
- }
2764
- function installPostCommitHook() {
2765
- fs8.mkdirSync(KEEPGOING_HOOKS_DIR, { recursive: true });
2766
- if (fs8.existsSync(POST_COMMIT_HOOK_PATH)) {
2767
- const existing = fs8.readFileSync(POST_COMMIT_HOOK_PATH, "utf-8");
3042
+ function performPostCommitHook() {
3043
+ fs9.mkdirSync(KEEPGOING_HOOKS_DIR, { recursive: true });
3044
+ if (fs9.existsSync(POST_COMMIT_HOOK_PATH)) {
3045
+ const existing = fs9.readFileSync(POST_COMMIT_HOOK_PATH, "utf-8");
2768
3046
  if (existing.includes(POST_COMMIT_MARKER_START)) {
2769
- console.log(`Git post-commit hook: already installed at ${POST_COMMIT_HOOK_PATH}`);
2770
- } else {
2771
- const suffix = existing.endsWith("\n") ? "" : "\n";
2772
- const block = `${suffix}
3047
+ return { success: true, message: `Git post-commit hook: already installed at ${POST_COMMIT_HOOK_PATH}` };
3048
+ }
3049
+ const suffix = existing.endsWith("\n") ? "" : "\n";
3050
+ const block = `${suffix}
2773
3051
  ${POST_COMMIT_MARKER_START}
2774
3052
  # Runs after every git commit. Detects high-signal decisions.
2775
3053
  if command -v keepgoing-mcp-server >/dev/null 2>&1; then
@@ -2777,40 +3055,45 @@ if command -v keepgoing-mcp-server >/dev/null 2>&1; then
2777
3055
  fi
2778
3056
  ${POST_COMMIT_MARKER_END}
2779
3057
  `;
2780
- fs8.appendFileSync(POST_COMMIT_HOOK_PATH, block, "utf-8");
2781
- console.log(`Git post-commit hook: appended to existing ${POST_COMMIT_HOOK_PATH}`);
2782
- }
2783
- } else {
2784
- fs8.writeFileSync(POST_COMMIT_HOOK_PATH, POST_COMMIT_HOOK, { mode: 493 });
2785
- console.log(`Git post-commit hook: installed at ${POST_COMMIT_HOOK_PATH}`);
3058
+ fs9.appendFileSync(POST_COMMIT_HOOK_PATH, block, "utf-8");
3059
+ fs9.chmodSync(POST_COMMIT_HOOK_PATH, 493);
3060
+ return { success: true, message: `Git post-commit hook: appended to existing ${POST_COMMIT_HOOK_PATH}` };
2786
3061
  }
2787
- fs8.chmodSync(POST_COMMIT_HOOK_PATH, 493);
3062
+ fs9.writeFileSync(POST_COMMIT_HOOK_PATH, POST_COMMIT_HOOK, { mode: 493 });
3063
+ fs9.chmodSync(POST_COMMIT_HOOK_PATH, 493);
2788
3064
  let currentHooksPath;
2789
3065
  try {
2790
- currentHooksPath = execSync("git config --global core.hooksPath", {
3066
+ currentHooksPath = execSync2("git config --global core.hooksPath", {
2791
3067
  encoding: "utf-8",
2792
3068
  stdio: ["pipe", "pipe", "pipe"]
2793
3069
  }).trim();
2794
3070
  } catch {
2795
3071
  }
2796
3072
  if (currentHooksPath === KEEPGOING_HOOKS_DIR) {
2797
- console.log(`Git hooks path: already set to ${KEEPGOING_HOOKS_DIR}`);
3073
+ return { success: true, message: `Git post-commit hook: installed at ${POST_COMMIT_HOOK_PATH}` };
2798
3074
  } else if (currentHooksPath) {
2799
- console.log(`Git hooks path: set to ${currentHooksPath}`);
2800
- console.log(` To use KeepGoing's post-commit hook, add the following to ${currentHooksPath}/post-commit:`);
2801
- console.log(` if command -v keepgoing-mcp-server >/dev/null 2>&1; then`);
2802
- console.log(` keepgoing-mcp-server --detect-decisions 2>/dev/null &`);
2803
- console.log(` fi`);
2804
- } else {
2805
- console.log(`Git post-commit hook: saved to ${POST_COMMIT_HOOK_PATH}`);
2806
- console.log(` To activate it globally, run:`);
2807
- console.log(` git config --global core.hooksPath "${KEEPGOING_HOOKS_DIR}"`);
2808
- console.log(` Note: this overrides per-repo .git/hooks/ for all repositories.`);
3075
+ return { success: true, message: `Git post-commit hook: saved to ${POST_COMMIT_HOOK_PATH} (core.hooksPath is ${currentHooksPath})` };
3076
+ }
3077
+ return { success: true, message: `Git post-commit hook: installed at ${POST_COMMIT_HOOK_PATH}` };
3078
+ }
3079
+ function uninstallGlobalGitignore() {
3080
+ const ignorePath = resolveGlobalGitignorePath();
3081
+ let existing = "";
3082
+ try {
3083
+ existing = fs9.readFileSync(ignorePath, "utf-8");
3084
+ } catch {
3085
+ return;
3086
+ }
3087
+ const lines = existing.split("\n");
3088
+ const filtered = lines.filter((line) => line.trim() !== ".keepgoing");
3089
+ if (filtered.length !== lines.length) {
3090
+ fs9.writeFileSync(ignorePath, filtered.join("\n"), "utf-8");
3091
+ console.log(`Global gitignore: .keepgoing removed from ${ignorePath}`);
2809
3092
  }
2810
3093
  }
2811
3094
  function uninstallPostCommitHook() {
2812
- if (fs8.existsSync(POST_COMMIT_HOOK_PATH)) {
2813
- const existing = fs8.readFileSync(POST_COMMIT_HOOK_PATH, "utf-8");
3095
+ if (fs9.existsSync(POST_COMMIT_HOOK_PATH)) {
3096
+ const existing = fs9.readFileSync(POST_COMMIT_HOOK_PATH, "utf-8");
2814
3097
  if (existing.includes(POST_COMMIT_MARKER_START)) {
2815
3098
  const pattern = new RegExp(
2816
3099
  `
@@ -2820,65 +3103,55 @@ function uninstallPostCommitHook() {
2820
3103
  );
2821
3104
  const updated = existing.replace(pattern, "").trim();
2822
3105
  if (!updated || updated === "#!/bin/sh") {
2823
- fs8.unlinkSync(POST_COMMIT_HOOK_PATH);
3106
+ fs9.unlinkSync(POST_COMMIT_HOOK_PATH);
2824
3107
  console.log(`Git post-commit hook: removed ${POST_COMMIT_HOOK_PATH}`);
2825
3108
  } else {
2826
- fs8.writeFileSync(POST_COMMIT_HOOK_PATH, updated + "\n", "utf-8");
3109
+ fs9.writeFileSync(POST_COMMIT_HOOK_PATH, updated + "\n", "utf-8");
2827
3110
  console.log(`Git post-commit hook: KeepGoing block removed from ${POST_COMMIT_HOOK_PATH}`);
2828
3111
  }
2829
3112
  }
2830
3113
  }
2831
3114
  try {
2832
- const currentHooksPath = execSync("git config --global core.hooksPath", {
3115
+ const currentHooksPath = execSync2("git config --global core.hooksPath", {
2833
3116
  encoding: "utf-8",
2834
3117
  stdio: ["pipe", "pipe", "pipe"]
2835
3118
  }).trim();
2836
3119
  if (currentHooksPath === KEEPGOING_HOOKS_DIR) {
2837
- execSync("git config --global --unset core.hooksPath", {
3120
+ execSync2("git config --global --unset core.hooksPath", {
2838
3121
  stdio: ["pipe", "pipe", "pipe"]
2839
3122
  });
2840
3123
  console.log("Git hooks path: global core.hooksPath unset");
2841
3124
  }
2842
3125
  } catch {
2843
3126
  }
2844
- if (fs8.existsSync(KEEPGOING_MANAGED_MARKER)) {
2845
- fs8.unlinkSync(KEEPGOING_MANAGED_MARKER);
3127
+ if (fs9.existsSync(KEEPGOING_MANAGED_MARKER)) {
3128
+ fs9.unlinkSync(KEEPGOING_MANAGED_MARKER);
2846
3129
  }
2847
3130
  }
2848
3131
  function hookInstallCommand(shellOverride) {
2849
- const detected = detectShellRcFile(shellOverride);
3132
+ const detected = detectShellInfo(shellOverride);
2850
3133
  if (!detected) {
2851
3134
  console.error(
2852
3135
  'Could not detect your shell. Set $SHELL to "zsh", "bash", or "fish" and try again.'
2853
3136
  );
2854
3137
  process.exit(1);
2855
3138
  }
2856
- const { shell, rcFile } = detected;
2857
- const hookBlock = shell === "zsh" ? ZSH_HOOK : shell === "fish" ? FISH_HOOK : BASH_HOOK;
2858
- let existing = "";
2859
- try {
2860
- existing = fs8.readFileSync(rcFile, "utf-8");
2861
- } catch {
2862
- }
2863
- if (existing.includes(HOOK_MARKER_START)) {
2864
- console.log(`KeepGoing hook is already installed in ${rcFile}.`);
2865
- installGlobalGitignore();
2866
- installPostCommitHook();
2867
- return;
2868
- }
2869
- fs8.appendFileSync(rcFile, `
2870
- ${hookBlock}
2871
- `, "utf-8");
2872
- console.log(`KeepGoing hook installed in ${rcFile}.`);
2873
- installGlobalGitignore();
2874
- installPostCommitHook();
2875
- console.log(`
3139
+ const { rcFile } = detected;
3140
+ const hookResult = performHookInstall(shellOverride);
3141
+ console.log(hookResult.message);
3142
+ const gitignoreResult = performGlobalGitignore();
3143
+ console.log(gitignoreResult.message);
3144
+ const postCommitResult = performPostCommitHook();
3145
+ console.log(postCommitResult.message);
3146
+ if (hookResult.message.includes("installed in")) {
3147
+ console.log(`
2876
3148
  Reload your shell config to activate it:
2877
3149
  `);
2878
- console.log(` source ${rcFile}`);
3150
+ console.log(` source ${rcFile}`);
3151
+ }
2879
3152
  }
2880
3153
  function hookUninstallCommand(shellOverride) {
2881
- const detected = detectShellRcFile(shellOverride);
3154
+ const detected = detectShellInfo(shellOverride);
2882
3155
  if (!detected) {
2883
3156
  console.error(
2884
3157
  'Could not detect your shell. Set $SHELL to "zsh", "bash", or "fish" and try again.'
@@ -2888,7 +3161,7 @@ function hookUninstallCommand(shellOverride) {
2888
3161
  const { rcFile } = detected;
2889
3162
  let existing = "";
2890
3163
  try {
2891
- existing = fs8.readFileSync(rcFile, "utf-8");
3164
+ existing = fs9.readFileSync(rcFile, "utf-8");
2892
3165
  } catch {
2893
3166
  console.log(`${rcFile} not found \u2014 nothing to remove.`);
2894
3167
  return;
@@ -2904,7 +3177,7 @@ function hookUninstallCommand(shellOverride) {
2904
3177
  "g"
2905
3178
  );
2906
3179
  const updated = existing.replace(pattern, "").replace(/\n{3,}/g, "\n\n");
2907
- fs8.writeFileSync(rcFile, updated, "utf-8");
3180
+ fs9.writeFileSync(rcFile, updated, "utf-8");
2908
3181
  console.log(`KeepGoing hook removed from ${rcFile}.`);
2909
3182
  uninstallGlobalGitignore();
2910
3183
  uninstallPostCommitHook();
@@ -3059,12 +3332,12 @@ async function briefingCommand(opts) {
3059
3332
  }
3060
3333
 
3061
3334
  // src/commands/init.ts
3062
- var RESET3 = "\x1B[0m";
3063
- var BOLD3 = "\x1B[1m";
3335
+ var RESET2 = "\x1B[0m";
3336
+ var BOLD2 = "\x1B[1m";
3064
3337
  var GREEN2 = "\x1B[32m";
3065
3338
  var YELLOW2 = "\x1B[33m";
3066
3339
  var CYAN2 = "\x1B[36m";
3067
- var DIM3 = "\x1B[2m";
3340
+ var DIM2 = "\x1B[2m";
3068
3341
  function initCommand(options) {
3069
3342
  const scope = options.scope === "user" ? "user" : "project";
3070
3343
  const result = setupProject({
@@ -3072,7 +3345,7 @@ function initCommand(options) {
3072
3345
  scope
3073
3346
  });
3074
3347
  console.log(`
3075
- ${BOLD3}KeepGoing Init${RESET3} ${DIM3}(${scope} scope)${RESET3}
3348
+ ${BOLD2}KeepGoing Init${RESET2} ${DIM2}(${scope} scope)${RESET2}
3076
3349
  `);
3077
3350
  for (const msg of result.messages) {
3078
3351
  const colonIdx = msg.indexOf(":");
@@ -3080,25 +3353,2361 @@ ${BOLD3}KeepGoing Init${RESET3} ${DIM3}(${scope} scope)${RESET3}
3080
3353
  console.log(` ${msg}`);
3081
3354
  continue;
3082
3355
  }
3083
- const label = msg.slice(0, colonIdx + 1);
3084
- const body = msg.slice(colonIdx + 1);
3085
- if (label.startsWith("Warning")) {
3086
- console.log(` ${YELLOW2}${label}${RESET3}${body}`);
3087
- } else if (body.includes("Added")) {
3088
- console.log(` ${GREEN2}${label}${RESET3}${body}`);
3089
- } else {
3090
- console.log(` ${CYAN2}${label}${RESET3}${body}`);
3356
+ const label = msg.slice(0, colonIdx + 1);
3357
+ const body = msg.slice(colonIdx + 1);
3358
+ if (label.startsWith("Warning")) {
3359
+ console.log(` ${YELLOW2}${label}${RESET2}${body}`);
3360
+ } else if (body.includes("Added")) {
3361
+ console.log(` ${GREEN2}${label}${RESET2}${body}`);
3362
+ } else {
3363
+ console.log(` ${CYAN2}${label}${RESET2}${body}`);
3364
+ }
3365
+ }
3366
+ if (result.changed) {
3367
+ console.log(`
3368
+ ${GREEN2}Done!${RESET2} KeepGoing is set up for this project.
3369
+ `);
3370
+ } else {
3371
+ console.log(`
3372
+ Everything was already configured. No changes made.
3373
+ `);
3374
+ }
3375
+ }
3376
+
3377
+ // src/commands/setup.ts
3378
+ import fs10 from "fs";
3379
+ import path13 from "path";
3380
+ import os6 from "os";
3381
+ import { execSync as execSync3, exec as exec2 } from "child_process";
3382
+ import { promisify as promisify2 } from "util";
3383
+
3384
+ // ../../node_modules/@clack/prompts/dist/index.mjs
3385
+ var dist_exports = {};
3386
+ __export(dist_exports, {
3387
+ S_BAR: () => d2,
3388
+ S_BAR_END: () => E2,
3389
+ S_BAR_END_RIGHT: () => Ee,
3390
+ S_BAR_H: () => se,
3391
+ S_BAR_START: () => le,
3392
+ S_BAR_START_RIGHT: () => Ie,
3393
+ S_CHECKBOX_ACTIVE: () => te,
3394
+ S_CHECKBOX_INACTIVE: () => J2,
3395
+ S_CHECKBOX_SELECTED: () => U,
3396
+ S_CONNECT_LEFT: () => Ge,
3397
+ S_CORNER_BOTTOM_LEFT: () => de,
3398
+ S_CORNER_BOTTOM_RIGHT: () => $e,
3399
+ S_CORNER_TOP_LEFT: () => Oe,
3400
+ S_CORNER_TOP_RIGHT: () => ce,
3401
+ S_ERROR: () => ge,
3402
+ S_INFO: () => he,
3403
+ S_PASSWORD_MASK: () => xe,
3404
+ S_RADIO_ACTIVE: () => z2,
3405
+ S_RADIO_INACTIVE: () => H2,
3406
+ S_STEP_ACTIVE: () => _e,
3407
+ S_STEP_CANCEL: () => oe,
3408
+ S_STEP_ERROR: () => ue,
3409
+ S_STEP_SUBMIT: () => F2,
3410
+ S_SUCCESS: () => pe,
3411
+ S_WARN: () => me,
3412
+ autocomplete: () => Ae,
3413
+ autocompleteMultiselect: () => st2,
3414
+ box: () => at2,
3415
+ cancel: () => pt,
3416
+ confirm: () => ot2,
3417
+ date: () => ut,
3418
+ group: () => dt,
3419
+ groupMultiselect: () => ht,
3420
+ intro: () => mt,
3421
+ isCI: () => ae,
3422
+ isCancel: () => q,
3423
+ isTTY: () => Te,
3424
+ limitOptions: () => Y2,
3425
+ log: () => O2,
3426
+ multiselect: () => yt,
3427
+ note: () => wt,
3428
+ outro: () => gt,
3429
+ password: () => bt,
3430
+ path: () => St,
3431
+ progress: () => Tt,
3432
+ select: () => _t,
3433
+ selectKey: () => It,
3434
+ settings: () => u,
3435
+ spinner: () => fe,
3436
+ stream: () => K2,
3437
+ symbol: () => V2,
3438
+ symbolBar: () => ye,
3439
+ taskLog: () => Gt,
3440
+ tasks: () => Et,
3441
+ text: () => Ot,
3442
+ unicode: () => ee,
3443
+ unicodeOr: () => w2,
3444
+ updateSettings: () => K
3445
+ });
3446
+
3447
+ // ../../node_modules/@clack/core/dist/index.mjs
3448
+ import { styleText as y } from "util";
3449
+ import { stdout as S, stdin as $ } from "process";
3450
+ import * as _ from "readline";
3451
+ import P from "readline";
3452
+
3453
+ // ../../node_modules/fast-string-truncated-width/dist/utils.js
3454
+ var isAmbiguous = (x) => {
3455
+ return x === 161 || x === 164 || x === 167 || x === 168 || x === 170 || x === 173 || x === 174 || x >= 176 && x <= 180 || x >= 182 && x <= 186 || x >= 188 && x <= 191 || x === 198 || x === 208 || x === 215 || x === 216 || x >= 222 && x <= 225 || x === 230 || x >= 232 && x <= 234 || x === 236 || x === 237 || x === 240 || x === 242 || x === 243 || x >= 247 && x <= 250 || x === 252 || x === 254 || x === 257 || x === 273 || x === 275 || x === 283 || x === 294 || x === 295 || x === 299 || x >= 305 && x <= 307 || x === 312 || x >= 319 && x <= 322 || x === 324 || x >= 328 && x <= 331 || x === 333 || x === 338 || x === 339 || x === 358 || x === 359 || x === 363 || x === 462 || x === 464 || x === 466 || x === 468 || x === 470 || x === 472 || x === 474 || x === 476 || x === 593 || x === 609 || x === 708 || x === 711 || x >= 713 && x <= 715 || x === 717 || x === 720 || x >= 728 && x <= 731 || x === 733 || x === 735 || x >= 768 && x <= 879 || x >= 913 && x <= 929 || x >= 931 && x <= 937 || x >= 945 && x <= 961 || x >= 963 && x <= 969 || x === 1025 || x >= 1040 && x <= 1103 || x === 1105 || x === 8208 || x >= 8211 && x <= 8214 || x === 8216 || x === 8217 || x === 8220 || x === 8221 || x >= 8224 && x <= 8226 || x >= 8228 && x <= 8231 || x === 8240 || x === 8242 || x === 8243 || x === 8245 || x === 8251 || x === 8254 || x === 8308 || x === 8319 || x >= 8321 && x <= 8324 || x === 8364 || x === 8451 || x === 8453 || x === 8457 || x === 8467 || x === 8470 || x === 8481 || x === 8482 || x === 8486 || x === 8491 || x === 8531 || x === 8532 || x >= 8539 && x <= 8542 || x >= 8544 && x <= 8555 || x >= 8560 && x <= 8569 || x === 8585 || x >= 8592 && x <= 8601 || x === 8632 || x === 8633 || x === 8658 || x === 8660 || x === 8679 || x === 8704 || x === 8706 || x === 8707 || x === 8711 || x === 8712 || x === 8715 || x === 8719 || x === 8721 || x === 8725 || x === 8730 || x >= 8733 && x <= 8736 || x === 8739 || x === 8741 || x >= 8743 && x <= 8748 || x === 8750 || x >= 8756 && x <= 8759 || x === 8764 || x === 8765 || x === 8776 || x === 8780 || x === 8786 || x === 8800 || x === 8801 || x >= 8804 && x <= 8807 || x === 8810 || x === 8811 || x === 8814 || x === 8815 || x === 8834 || x === 8835 || x === 8838 || x === 8839 || x === 8853 || x === 8857 || x === 8869 || x === 8895 || x === 8978 || x >= 9312 && x <= 9449 || x >= 9451 && x <= 9547 || x >= 9552 && x <= 9587 || x >= 9600 && x <= 9615 || x >= 9618 && x <= 9621 || x === 9632 || x === 9633 || x >= 9635 && x <= 9641 || x === 9650 || x === 9651 || x === 9654 || x === 9655 || x === 9660 || x === 9661 || x === 9664 || x === 9665 || x >= 9670 && x <= 9672 || x === 9675 || x >= 9678 && x <= 9681 || x >= 9698 && x <= 9701 || x === 9711 || x === 9733 || x === 9734 || x === 9737 || x === 9742 || x === 9743 || x === 9756 || x === 9758 || x === 9792 || x === 9794 || x === 9824 || x === 9825 || x >= 9827 && x <= 9829 || x >= 9831 && x <= 9834 || x === 9836 || x === 9837 || x === 9839 || x === 9886 || x === 9887 || x === 9919 || x >= 9926 && x <= 9933 || x >= 9935 && x <= 9939 || x >= 9941 && x <= 9953 || x === 9955 || x === 9960 || x === 9961 || x >= 9963 && x <= 9969 || x === 9972 || x >= 9974 && x <= 9977 || x === 9979 || x === 9980 || x === 9982 || x === 9983 || x === 10045 || x >= 10102 && x <= 10111 || x >= 11094 && x <= 11097 || x >= 12872 && x <= 12879 || x >= 57344 && x <= 63743 || x >= 65024 && x <= 65039 || x === 65533 || x >= 127232 && x <= 127242 || x >= 127248 && x <= 127277 || x >= 127280 && x <= 127337 || x >= 127344 && x <= 127373 || x === 127375 || x === 127376 || x >= 127387 && x <= 127404 || x >= 917760 && x <= 917999 || x >= 983040 && x <= 1048573 || x >= 1048576 && x <= 1114109;
3456
+ };
3457
+ var isFullWidth = (x) => {
3458
+ return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
3459
+ };
3460
+ var isWide = (x) => {
3461
+ return x >= 4352 && x <= 4447 || x === 8986 || x === 8987 || x === 9001 || x === 9002 || x >= 9193 && x <= 9196 || x === 9200 || x === 9203 || x === 9725 || x === 9726 || x === 9748 || x === 9749 || x >= 9800 && x <= 9811 || x === 9855 || x === 9875 || x === 9889 || x === 9898 || x === 9899 || x === 9917 || x === 9918 || x === 9924 || x === 9925 || x === 9934 || x === 9940 || x === 9962 || x === 9970 || x === 9971 || x === 9973 || x === 9978 || x === 9981 || x === 9989 || x === 9994 || x === 9995 || x === 10024 || x === 10060 || x === 10062 || x >= 10067 && x <= 10069 || x === 10071 || x >= 10133 && x <= 10135 || x === 10160 || x === 10175 || x === 11035 || x === 11036 || x === 11088 || x === 11093 || x >= 11904 && x <= 11929 || x >= 11931 && x <= 12019 || x >= 12032 && x <= 12245 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12353 && x <= 12438 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12771 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 19903 || x >= 19968 && x <= 42124 || x >= 42128 && x <= 42182 || x >= 43360 && x <= 43388 || x >= 44032 && x <= 55203 || x >= 63744 && x <= 64255 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 94176 && x <= 94180 || x === 94192 || x === 94193 || x >= 94208 && x <= 100343 || x >= 100352 && x <= 101589 || x >= 101632 && x <= 101640 || x >= 110576 && x <= 110579 || x >= 110581 && x <= 110587 || x === 110589 || x === 110590 || x >= 110592 && x <= 110882 || x === 110898 || x >= 110928 && x <= 110930 || x === 110933 || x >= 110948 && x <= 110951 || x >= 110960 && x <= 111355 || x === 126980 || x === 127183 || x === 127374 || x >= 127377 && x <= 127386 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x === 127568 || x === 127569 || x >= 127584 && x <= 127589 || x >= 127744 && x <= 127776 || x >= 127789 && x <= 127797 || x >= 127799 && x <= 127868 || x >= 127870 && x <= 127891 || x >= 127904 && x <= 127946 || x >= 127951 && x <= 127955 || x >= 127968 && x <= 127984 || x === 127988 || x >= 127992 && x <= 128062 || x === 128064 || x >= 128066 && x <= 128252 || x >= 128255 && x <= 128317 || x >= 128331 && x <= 128334 || x >= 128336 && x <= 128359 || x === 128378 || x === 128405 || x === 128406 || x === 128420 || x >= 128507 && x <= 128591 || x >= 128640 && x <= 128709 || x === 128716 || x >= 128720 && x <= 128722 || x >= 128725 && x <= 128727 || x >= 128732 && x <= 128735 || x === 128747 || x === 128748 || x >= 128756 && x <= 128764 || x >= 128992 && x <= 129003 || x === 129008 || x >= 129292 && x <= 129338 || x >= 129340 && x <= 129349 || x >= 129351 && x <= 129535 || x >= 129648 && x <= 129660 || x >= 129664 && x <= 129672 || x >= 129680 && x <= 129725 || x >= 129727 && x <= 129733 || x >= 129742 && x <= 129755 || x >= 129760 && x <= 129768 || x >= 129776 && x <= 129784 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
3462
+ };
3463
+
3464
+ // ../../node_modules/fast-string-truncated-width/dist/index.js
3465
+ var ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/y;
3466
+ var CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
3467
+ var TAB_RE = /\t{1,1000}/y;
3468
+ var EMOJI_RE = new RegExp("[\\u{1F1E6}-\\u{1F1FF}]{2}|\\u{1F3F4}[\\u{E0061}-\\u{E007A}]{2}[\\u{E0030}-\\u{E0039}\\u{E0061}-\\u{E007A}]{1,3}\\u{E007F}|(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation})(?:\\u200D(?:\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation}|\\p{Emoji}\\uFE0F\\u20E3?))*", "yu");
3469
+ var LATIN_RE = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
3470
+ var MODIFIER_RE = new RegExp("\\p{M}+", "gu");
3471
+ var NO_TRUNCATION = { limit: Infinity, ellipsis: "" };
3472
+ var getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {}) => {
3473
+ const LIMIT = truncationOptions.limit ?? Infinity;
3474
+ const ELLIPSIS = truncationOptions.ellipsis ?? "";
3475
+ const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION, widthOptions).width : 0);
3476
+ const ANSI_WIDTH = widthOptions.ansiWidth ?? 0;
3477
+ const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;
3478
+ const TAB_WIDTH = widthOptions.tabWidth ?? 8;
3479
+ const AMBIGUOUS_WIDTH = widthOptions.ambiguousWidth ?? 1;
3480
+ const EMOJI_WIDTH = widthOptions.emojiWidth ?? 2;
3481
+ const FULL_WIDTH_WIDTH = widthOptions.fullWidthWidth ?? 2;
3482
+ const REGULAR_WIDTH = widthOptions.regularWidth ?? 1;
3483
+ const WIDE_WIDTH = widthOptions.wideWidth ?? 2;
3484
+ let indexPrev = 0;
3485
+ let index = 0;
3486
+ let length = input.length;
3487
+ let lengthExtra = 0;
3488
+ let truncationEnabled = false;
3489
+ let truncationIndex = length;
3490
+ let truncationLimit = Math.max(0, LIMIT - ELLIPSIS_WIDTH);
3491
+ let unmatchedStart = 0;
3492
+ let unmatchedEnd = 0;
3493
+ let width = 0;
3494
+ let widthExtra = 0;
3495
+ outer: while (true) {
3496
+ if (unmatchedEnd > unmatchedStart || index >= length && index > indexPrev) {
3497
+ const unmatched = input.slice(unmatchedStart, unmatchedEnd) || input.slice(indexPrev, index);
3498
+ lengthExtra = 0;
3499
+ for (const char of unmatched.replaceAll(MODIFIER_RE, "")) {
3500
+ const codePoint = char.codePointAt(0) || 0;
3501
+ if (isFullWidth(codePoint)) {
3502
+ widthExtra = FULL_WIDTH_WIDTH;
3503
+ } else if (isWide(codePoint)) {
3504
+ widthExtra = WIDE_WIDTH;
3505
+ } else if (AMBIGUOUS_WIDTH !== REGULAR_WIDTH && isAmbiguous(codePoint)) {
3506
+ widthExtra = AMBIGUOUS_WIDTH;
3507
+ } else {
3508
+ widthExtra = REGULAR_WIDTH;
3509
+ }
3510
+ if (width + widthExtra > truncationLimit) {
3511
+ truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);
3512
+ }
3513
+ if (width + widthExtra > LIMIT) {
3514
+ truncationEnabled = true;
3515
+ break outer;
3516
+ }
3517
+ lengthExtra += char.length;
3518
+ width += widthExtra;
3519
+ }
3520
+ unmatchedStart = unmatchedEnd = 0;
3521
+ }
3522
+ if (index >= length)
3523
+ break;
3524
+ LATIN_RE.lastIndex = index;
3525
+ if (LATIN_RE.test(input)) {
3526
+ lengthExtra = LATIN_RE.lastIndex - index;
3527
+ widthExtra = lengthExtra * REGULAR_WIDTH;
3528
+ if (width + widthExtra > truncationLimit) {
3529
+ truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / REGULAR_WIDTH));
3530
+ }
3531
+ if (width + widthExtra > LIMIT) {
3532
+ truncationEnabled = true;
3533
+ break;
3534
+ }
3535
+ width += widthExtra;
3536
+ unmatchedStart = indexPrev;
3537
+ unmatchedEnd = index;
3538
+ index = indexPrev = LATIN_RE.lastIndex;
3539
+ continue;
3540
+ }
3541
+ ANSI_RE.lastIndex = index;
3542
+ if (ANSI_RE.test(input)) {
3543
+ if (width + ANSI_WIDTH > truncationLimit) {
3544
+ truncationIndex = Math.min(truncationIndex, index);
3545
+ }
3546
+ if (width + ANSI_WIDTH > LIMIT) {
3547
+ truncationEnabled = true;
3548
+ break;
3549
+ }
3550
+ width += ANSI_WIDTH;
3551
+ unmatchedStart = indexPrev;
3552
+ unmatchedEnd = index;
3553
+ index = indexPrev = ANSI_RE.lastIndex;
3554
+ continue;
3555
+ }
3556
+ CONTROL_RE.lastIndex = index;
3557
+ if (CONTROL_RE.test(input)) {
3558
+ lengthExtra = CONTROL_RE.lastIndex - index;
3559
+ widthExtra = lengthExtra * CONTROL_WIDTH;
3560
+ if (width + widthExtra > truncationLimit) {
3561
+ truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / CONTROL_WIDTH));
3562
+ }
3563
+ if (width + widthExtra > LIMIT) {
3564
+ truncationEnabled = true;
3565
+ break;
3566
+ }
3567
+ width += widthExtra;
3568
+ unmatchedStart = indexPrev;
3569
+ unmatchedEnd = index;
3570
+ index = indexPrev = CONTROL_RE.lastIndex;
3571
+ continue;
3572
+ }
3573
+ TAB_RE.lastIndex = index;
3574
+ if (TAB_RE.test(input)) {
3575
+ lengthExtra = TAB_RE.lastIndex - index;
3576
+ widthExtra = lengthExtra * TAB_WIDTH;
3577
+ if (width + widthExtra > truncationLimit) {
3578
+ truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / TAB_WIDTH));
3579
+ }
3580
+ if (width + widthExtra > LIMIT) {
3581
+ truncationEnabled = true;
3582
+ break;
3583
+ }
3584
+ width += widthExtra;
3585
+ unmatchedStart = indexPrev;
3586
+ unmatchedEnd = index;
3587
+ index = indexPrev = TAB_RE.lastIndex;
3588
+ continue;
3589
+ }
3590
+ EMOJI_RE.lastIndex = index;
3591
+ if (EMOJI_RE.test(input)) {
3592
+ if (width + EMOJI_WIDTH > truncationLimit) {
3593
+ truncationIndex = Math.min(truncationIndex, index);
3594
+ }
3595
+ if (width + EMOJI_WIDTH > LIMIT) {
3596
+ truncationEnabled = true;
3597
+ break;
3598
+ }
3599
+ width += EMOJI_WIDTH;
3600
+ unmatchedStart = indexPrev;
3601
+ unmatchedEnd = index;
3602
+ index = indexPrev = EMOJI_RE.lastIndex;
3603
+ continue;
3604
+ }
3605
+ index += 1;
3606
+ }
3607
+ return {
3608
+ width: truncationEnabled ? truncationLimit : width,
3609
+ index: truncationEnabled ? truncationIndex : length,
3610
+ truncated: truncationEnabled,
3611
+ ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH
3612
+ };
3613
+ };
3614
+ var dist_default = getStringTruncatedWidth;
3615
+
3616
+ // ../../node_modules/fast-string-width/dist/index.js
3617
+ var NO_TRUNCATION2 = {
3618
+ limit: Infinity,
3619
+ ellipsis: "",
3620
+ ellipsisWidth: 0
3621
+ };
3622
+ var fastStringWidth = (input, options = {}) => {
3623
+ return dist_default(input, NO_TRUNCATION2, options).width;
3624
+ };
3625
+ var dist_default2 = fastStringWidth;
3626
+
3627
+ // ../../node_modules/fast-wrap-ansi/lib/main.js
3628
+ var ESC = "\x1B";
3629
+ var CSI = "\x9B";
3630
+ var END_CODE = 39;
3631
+ var ANSI_ESCAPE_BELL = "\x07";
3632
+ var ANSI_CSI = "[";
3633
+ var ANSI_OSC = "]";
3634
+ var ANSI_SGR_TERMINATOR = "m";
3635
+ var ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
3636
+ var GROUP_REGEX = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`, "y");
3637
+ var getClosingCode = (openingCode) => {
3638
+ if (openingCode >= 30 && openingCode <= 37)
3639
+ return 39;
3640
+ if (openingCode >= 90 && openingCode <= 97)
3641
+ return 39;
3642
+ if (openingCode >= 40 && openingCode <= 47)
3643
+ return 49;
3644
+ if (openingCode >= 100 && openingCode <= 107)
3645
+ return 49;
3646
+ if (openingCode === 1 || openingCode === 2)
3647
+ return 22;
3648
+ if (openingCode === 3)
3649
+ return 23;
3650
+ if (openingCode === 4)
3651
+ return 24;
3652
+ if (openingCode === 7)
3653
+ return 27;
3654
+ if (openingCode === 8)
3655
+ return 28;
3656
+ if (openingCode === 9)
3657
+ return 29;
3658
+ if (openingCode === 0)
3659
+ return 0;
3660
+ return void 0;
3661
+ };
3662
+ var wrapAnsiCode = (code) => `${ESC}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
3663
+ var wrapAnsiHyperlink = (url) => `${ESC}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`;
3664
+ var wrapWord = (rows, word, columns) => {
3665
+ const characters = word[Symbol.iterator]();
3666
+ let isInsideEscape = false;
3667
+ let isInsideLinkEscape = false;
3668
+ let lastRow = rows.at(-1);
3669
+ let visible = lastRow === void 0 ? 0 : dist_default2(lastRow);
3670
+ let currentCharacter = characters.next();
3671
+ let nextCharacter = characters.next();
3672
+ let rawCharacterIndex = 0;
3673
+ while (!currentCharacter.done) {
3674
+ const character = currentCharacter.value;
3675
+ const characterLength = dist_default2(character);
3676
+ if (visible + characterLength <= columns) {
3677
+ rows[rows.length - 1] += character;
3678
+ } else {
3679
+ rows.push(character);
3680
+ visible = 0;
3681
+ }
3682
+ if (character === ESC || character === CSI) {
3683
+ isInsideEscape = true;
3684
+ isInsideLinkEscape = word.startsWith(ANSI_ESCAPE_LINK, rawCharacterIndex + 1);
3685
+ }
3686
+ if (isInsideEscape) {
3687
+ if (isInsideLinkEscape) {
3688
+ if (character === ANSI_ESCAPE_BELL) {
3689
+ isInsideEscape = false;
3690
+ isInsideLinkEscape = false;
3691
+ }
3692
+ } else if (character === ANSI_SGR_TERMINATOR) {
3693
+ isInsideEscape = false;
3694
+ }
3695
+ } else {
3696
+ visible += characterLength;
3697
+ if (visible === columns && !nextCharacter.done) {
3698
+ rows.push("");
3699
+ visible = 0;
3700
+ }
3701
+ }
3702
+ currentCharacter = nextCharacter;
3703
+ nextCharacter = characters.next();
3704
+ rawCharacterIndex += character.length;
3705
+ }
3706
+ lastRow = rows.at(-1);
3707
+ if (!visible && lastRow !== void 0 && lastRow.length && rows.length > 1) {
3708
+ rows[rows.length - 2] += rows.pop();
3709
+ }
3710
+ };
3711
+ var stringVisibleTrimSpacesRight = (string) => {
3712
+ const words = string.split(" ");
3713
+ let last = words.length;
3714
+ while (last) {
3715
+ if (dist_default2(words[last - 1])) {
3716
+ break;
3717
+ }
3718
+ last--;
3719
+ }
3720
+ if (last === words.length) {
3721
+ return string;
3722
+ }
3723
+ return words.slice(0, last).join(" ") + words.slice(last).join("");
3724
+ };
3725
+ var exec = (string, columns, options = {}) => {
3726
+ if (options.trim !== false && string.trim() === "") {
3727
+ return "";
3728
+ }
3729
+ let returnValue = "";
3730
+ let escapeCode;
3731
+ let escapeUrl;
3732
+ const words = string.split(" ");
3733
+ let rows = [""];
3734
+ let rowLength = 0;
3735
+ for (let index = 0; index < words.length; index++) {
3736
+ const word = words[index];
3737
+ if (options.trim !== false) {
3738
+ const row = rows.at(-1) ?? "";
3739
+ const trimmed = row.trimStart();
3740
+ if (row.length !== trimmed.length) {
3741
+ rows[rows.length - 1] = trimmed;
3742
+ rowLength = dist_default2(trimmed);
3743
+ }
3744
+ }
3745
+ if (index !== 0) {
3746
+ if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
3747
+ rows.push("");
3748
+ rowLength = 0;
3749
+ }
3750
+ if (rowLength || options.trim === false) {
3751
+ rows[rows.length - 1] += " ";
3752
+ rowLength++;
3753
+ }
3754
+ }
3755
+ const wordLength = dist_default2(word);
3756
+ if (options.hard && wordLength > columns) {
3757
+ const remainingColumns = columns - rowLength;
3758
+ const breaksStartingThisLine = 1 + Math.floor((wordLength - remainingColumns - 1) / columns);
3759
+ const breaksStartingNextLine = Math.floor((wordLength - 1) / columns);
3760
+ if (breaksStartingNextLine < breaksStartingThisLine) {
3761
+ rows.push("");
3762
+ }
3763
+ wrapWord(rows, word, columns);
3764
+ rowLength = dist_default2(rows.at(-1) ?? "");
3765
+ continue;
3766
+ }
3767
+ if (rowLength + wordLength > columns && rowLength && wordLength) {
3768
+ if (options.wordWrap === false && rowLength < columns) {
3769
+ wrapWord(rows, word, columns);
3770
+ rowLength = dist_default2(rows.at(-1) ?? "");
3771
+ continue;
3772
+ }
3773
+ rows.push("");
3774
+ rowLength = 0;
3775
+ }
3776
+ if (rowLength + wordLength > columns && options.wordWrap === false) {
3777
+ wrapWord(rows, word, columns);
3778
+ rowLength = dist_default2(rows.at(-1) ?? "");
3779
+ continue;
3780
+ }
3781
+ rows[rows.length - 1] += word;
3782
+ rowLength += wordLength;
3783
+ }
3784
+ if (options.trim !== false) {
3785
+ rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
3786
+ }
3787
+ const preString = rows.join("\n");
3788
+ let inSurrogate = false;
3789
+ for (let i = 0; i < preString.length; i++) {
3790
+ const character = preString[i];
3791
+ returnValue += character;
3792
+ if (!inSurrogate) {
3793
+ inSurrogate = character >= "\uD800" && character <= "\uDBFF";
3794
+ } else {
3795
+ continue;
3796
+ }
3797
+ if (character === ESC || character === CSI) {
3798
+ GROUP_REGEX.lastIndex = i + 1;
3799
+ const groupsResult = GROUP_REGEX.exec(preString);
3800
+ const groups = groupsResult?.groups;
3801
+ if (groups?.code !== void 0) {
3802
+ const code = Number.parseFloat(groups.code);
3803
+ escapeCode = code === END_CODE ? void 0 : code;
3804
+ } else if (groups?.uri !== void 0) {
3805
+ escapeUrl = groups.uri.length === 0 ? void 0 : groups.uri;
3806
+ }
3807
+ }
3808
+ if (preString[i + 1] === "\n") {
3809
+ if (escapeUrl) {
3810
+ returnValue += wrapAnsiHyperlink("");
3811
+ }
3812
+ const closingCode = escapeCode ? getClosingCode(escapeCode) : void 0;
3813
+ if (escapeCode && closingCode) {
3814
+ returnValue += wrapAnsiCode(closingCode);
3815
+ }
3816
+ } else if (character === "\n") {
3817
+ if (escapeCode && getClosingCode(escapeCode)) {
3818
+ returnValue += wrapAnsiCode(escapeCode);
3819
+ }
3820
+ if (escapeUrl) {
3821
+ returnValue += wrapAnsiHyperlink(escapeUrl);
3822
+ }
3823
+ }
3824
+ }
3825
+ return returnValue;
3826
+ };
3827
+ var CRLF_OR_LF = /\r?\n/;
3828
+ function wrapAnsi(string, columns, options) {
3829
+ return String(string).normalize().split(CRLF_OR_LF).map((line) => exec(line, columns, options)).join("\n");
3830
+ }
3831
+
3832
+ // ../../node_modules/@clack/core/dist/index.mjs
3833
+ var import_sisteransi = __toESM(require_src(), 1);
3834
+ import { ReadStream as D } from "tty";
3835
+ function d(r, t2, e) {
3836
+ if (!e.some((o) => !o.disabled)) return r;
3837
+ const s = r + t2, i = Math.max(e.length - 1, 0), n = s < 0 ? i : s > i ? 0 : s;
3838
+ return e[n].disabled ? d(n, t2 < 0 ? -1 : 1, e) : n;
3839
+ }
3840
+ var E = ["up", "down", "left", "right", "space", "enter", "cancel"];
3841
+ var G = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
3842
+ var u = { actions: new Set(E), aliases: /* @__PURE__ */ new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"], ["", "cancel"], ["escape", "cancel"]]), messages: { cancel: "Canceled", error: "Something went wrong" }, withGuide: true, date: { monthNames: [...G], messages: { required: "Please enter a valid date", invalidMonth: "There are only 12 months in a year", invalidDay: (r, t2) => `There are only ${r} days in ${t2}`, afterMin: (r) => `Date must be on or after ${r.toISOString().slice(0, 10)}`, beforeMax: (r) => `Date must be on or before ${r.toISOString().slice(0, 10)}` } } };
3843
+ function K(r) {
3844
+ if (r.aliases !== void 0) {
3845
+ const t2 = r.aliases;
3846
+ for (const e in t2) {
3847
+ if (!Object.hasOwn(t2, e)) continue;
3848
+ const s = t2[e];
3849
+ u.actions.has(s) && (u.aliases.has(e) || u.aliases.set(e, s));
3850
+ }
3851
+ }
3852
+ if (r.messages !== void 0) {
3853
+ const t2 = r.messages;
3854
+ t2.cancel !== void 0 && (u.messages.cancel = t2.cancel), t2.error !== void 0 && (u.messages.error = t2.error);
3855
+ }
3856
+ if (r.withGuide !== void 0 && (u.withGuide = r.withGuide !== false), r.date !== void 0) {
3857
+ const t2 = r.date;
3858
+ t2.monthNames !== void 0 && (u.date.monthNames = [...t2.monthNames]), t2.messages !== void 0 && (t2.messages.required !== void 0 && (u.date.messages.required = t2.messages.required), t2.messages.invalidMonth !== void 0 && (u.date.messages.invalidMonth = t2.messages.invalidMonth), t2.messages.invalidDay !== void 0 && (u.date.messages.invalidDay = t2.messages.invalidDay), t2.messages.afterMin !== void 0 && (u.date.messages.afterMin = t2.messages.afterMin), t2.messages.beforeMax !== void 0 && (u.date.messages.beforeMax = t2.messages.beforeMax));
3859
+ }
3860
+ }
3861
+ function V(r, t2) {
3862
+ if (typeof r == "string") return u.aliases.get(r) === t2;
3863
+ for (const e of r) if (e !== void 0 && V(e, t2)) return true;
3864
+ return false;
3865
+ }
3866
+ function j(r, t2) {
3867
+ if (r === t2) return;
3868
+ const e = r.split(`
3869
+ `), s = t2.split(`
3870
+ `), i = Math.max(e.length, s.length), n = [];
3871
+ for (let o = 0; o < i; o++) e[o] !== s[o] && n.push(o);
3872
+ return { lines: n, numLinesBefore: e.length, numLinesAfter: s.length, numLines: i };
3873
+ }
3874
+ var Y = globalThis.process.platform.startsWith("win");
3875
+ var C = /* @__PURE__ */ Symbol("clack:cancel");
3876
+ function q(r) {
3877
+ return r === C;
3878
+ }
3879
+ function w(r, t2) {
3880
+ const e = r;
3881
+ e.isTTY && e.setRawMode(t2);
3882
+ }
3883
+ function z({ input: r = $, output: t2 = S, overwrite: e = true, hideCursor: s = true } = {}) {
3884
+ const i = _.createInterface({ input: r, output: t2, prompt: "", tabSize: 1 });
3885
+ _.emitKeypressEvents(r, i), r instanceof D && r.isTTY && r.setRawMode(true);
3886
+ const n = (o, { name: a, sequence: h }) => {
3887
+ const l = String(o);
3888
+ if (V([l, a, h], "cancel")) {
3889
+ s && t2.write(import_sisteransi.cursor.show), process.exit(0);
3890
+ return;
3891
+ }
3892
+ if (!e) return;
3893
+ const f = a === "return" ? 0 : -1, v = a === "return" ? -1 : 0;
3894
+ _.moveCursor(t2, f, v, () => {
3895
+ _.clearLine(t2, 1, () => {
3896
+ r.once("keypress", n);
3897
+ });
3898
+ });
3899
+ };
3900
+ return s && t2.write(import_sisteransi.cursor.hide), r.once("keypress", n), () => {
3901
+ r.off("keypress", n), s && t2.write(import_sisteransi.cursor.show), r instanceof D && r.isTTY && !Y && r.setRawMode(false), i.terminal = false, i.close();
3902
+ };
3903
+ }
3904
+ var O = (r) => "columns" in r && typeof r.columns == "number" ? r.columns : 80;
3905
+ var A = (r) => "rows" in r && typeof r.rows == "number" ? r.rows : 20;
3906
+ function R(r, t2, e, s = e) {
3907
+ const i = O(r ?? S);
3908
+ return wrapAnsi(t2, i - e.length, { hard: true, trim: false }).split(`
3909
+ `).map((n, o) => `${o === 0 ? s : e}${n}`).join(`
3910
+ `);
3911
+ }
3912
+ var p = class {
3913
+ input;
3914
+ output;
3915
+ _abortSignal;
3916
+ rl;
3917
+ opts;
3918
+ _render;
3919
+ _track = false;
3920
+ _prevFrame = "";
3921
+ _subscribers = /* @__PURE__ */ new Map();
3922
+ _cursor = 0;
3923
+ state = "initial";
3924
+ error = "";
3925
+ value;
3926
+ userInput = "";
3927
+ constructor(t2, e = true) {
3928
+ const { input: s = $, output: i = S, render: n, signal: o, ...a } = t2;
3929
+ this.opts = a, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = n.bind(this), this._track = e, this._abortSignal = o, this.input = s, this.output = i;
3930
+ }
3931
+ unsubscribe() {
3932
+ this._subscribers.clear();
3933
+ }
3934
+ setSubscriber(t2, e) {
3935
+ const s = this._subscribers.get(t2) ?? [];
3936
+ s.push(e), this._subscribers.set(t2, s);
3937
+ }
3938
+ on(t2, e) {
3939
+ this.setSubscriber(t2, { cb: e });
3940
+ }
3941
+ once(t2, e) {
3942
+ this.setSubscriber(t2, { cb: e, once: true });
3943
+ }
3944
+ emit(t2, ...e) {
3945
+ const s = this._subscribers.get(t2) ?? [], i = [];
3946
+ for (const n of s) n.cb(...e), n.once && i.push(() => s.splice(s.indexOf(n), 1));
3947
+ for (const n of i) n();
3948
+ }
3949
+ prompt() {
3950
+ return new Promise((t2) => {
3951
+ if (this._abortSignal) {
3952
+ if (this._abortSignal.aborted) return this.state = "cancel", this.close(), t2(C);
3953
+ this._abortSignal.addEventListener("abort", () => {
3954
+ this.state = "cancel", this.close();
3955
+ }, { once: true });
3956
+ }
3957
+ this.rl = P.createInterface({ input: this.input, tabSize: 2, prompt: "", escapeCodeTimeout: 50, terminal: true }), this.rl.prompt(), this.opts.initialUserInput !== void 0 && this._setUserInput(this.opts.initialUserInput, true), this.input.on("keypress", this.onKeypress), w(this.input, true), this.output.on("resize", this.render), this.render(), this.once("submit", () => {
3958
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), w(this.input, false), t2(this.value);
3959
+ }), this.once("cancel", () => {
3960
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), w(this.input, false), t2(C);
3961
+ });
3962
+ });
3963
+ }
3964
+ _isActionKey(t2, e) {
3965
+ return t2 === " ";
3966
+ }
3967
+ _setValue(t2) {
3968
+ this.value = t2, this.emit("value", this.value);
3969
+ }
3970
+ _setUserInput(t2, e) {
3971
+ this.userInput = t2 ?? "", this.emit("userInput", this.userInput), e && this._track && this.rl && (this.rl.write(this.userInput), this._cursor = this.rl.cursor);
3972
+ }
3973
+ _clearUserInput() {
3974
+ this.rl?.write(null, { ctrl: true, name: "u" }), this._setUserInput("");
3975
+ }
3976
+ onKeypress(t2, e) {
3977
+ if (this._track && e.name !== "return" && (e.name && this._isActionKey(t2, e) && this.rl?.write(null, { ctrl: true, name: "h" }), this._cursor = this.rl?.cursor ?? 0, this._setUserInput(this.rl?.line)), this.state === "error" && (this.state = "active"), e?.name && (!this._track && u.aliases.has(e.name) && this.emit("cursor", u.aliases.get(e.name)), u.actions.has(e.name) && this.emit("cursor", e.name)), t2 && (t2.toLowerCase() === "y" || t2.toLowerCase() === "n") && this.emit("confirm", t2.toLowerCase() === "y"), this.emit("key", t2?.toLowerCase(), e), e?.name === "return") {
3978
+ if (this.opts.validate) {
3979
+ const s = this.opts.validate(this.value);
3980
+ s && (this.error = s instanceof Error ? s.message : s, this.state = "error", this.rl?.write(this.userInput));
3981
+ }
3982
+ this.state !== "error" && (this.state = "submit");
3983
+ }
3984
+ V([t2, e?.name, e?.sequence], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
3985
+ }
3986
+ close() {
3987
+ this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
3988
+ `), w(this.input, false), this.rl?.close(), this.rl = void 0, this.emit(`${this.state}`, this.value), this.unsubscribe();
3989
+ }
3990
+ restoreCursor() {
3991
+ const t2 = wrapAnsi(this._prevFrame, process.stdout.columns, { hard: true, trim: false }).split(`
3992
+ `).length - 1;
3993
+ this.output.write(import_sisteransi.cursor.move(-999, t2 * -1));
3994
+ }
3995
+ render() {
3996
+ const t2 = wrapAnsi(this._render(this) ?? "", process.stdout.columns, { hard: true, trim: false });
3997
+ if (t2 !== this._prevFrame) {
3998
+ if (this.state === "initial") this.output.write(import_sisteransi.cursor.hide);
3999
+ else {
4000
+ const e = j(this._prevFrame, t2), s = A(this.output);
4001
+ if (this.restoreCursor(), e) {
4002
+ const i = Math.max(0, e.numLinesAfter - s), n = Math.max(0, e.numLinesBefore - s);
4003
+ let o = e.lines.find((a) => a >= i);
4004
+ if (o === void 0) {
4005
+ this._prevFrame = t2;
4006
+ return;
4007
+ }
4008
+ if (e.lines.length === 1) {
4009
+ this.output.write(import_sisteransi.cursor.move(0, o - n)), this.output.write(import_sisteransi.erase.lines(1));
4010
+ const a = t2.split(`
4011
+ `);
4012
+ this.output.write(a[o]), this._prevFrame = t2, this.output.write(import_sisteransi.cursor.move(0, a.length - o - 1));
4013
+ return;
4014
+ } else if (e.lines.length > 1) {
4015
+ if (i < n) o = i;
4016
+ else {
4017
+ const h = o - n;
4018
+ h > 0 && this.output.write(import_sisteransi.cursor.move(0, h));
4019
+ }
4020
+ this.output.write(import_sisteransi.erase.down());
4021
+ const a = t2.split(`
4022
+ `).slice(o);
4023
+ this.output.write(a.join(`
4024
+ `)), this._prevFrame = t2;
4025
+ return;
4026
+ }
4027
+ }
4028
+ this.output.write(import_sisteransi.erase.down());
4029
+ }
4030
+ this.output.write(t2), this.state === "initial" && (this.state = "active"), this._prevFrame = t2;
4031
+ }
4032
+ }
4033
+ };
4034
+ function W(r, t2) {
4035
+ if (r === void 0 || t2.length === 0) return 0;
4036
+ const e = t2.findIndex((s) => s.value === r);
4037
+ return e !== -1 ? e : 0;
4038
+ }
4039
+ function B(r, t2) {
4040
+ return (t2.label ?? String(t2.value)).toLowerCase().includes(r.toLowerCase());
4041
+ }
4042
+ function J(r, t2) {
4043
+ if (t2) return r ? t2 : t2[0];
4044
+ }
4045
+ var H = class extends p {
4046
+ filteredOptions;
4047
+ multiple;
4048
+ isNavigating = false;
4049
+ selectedValues = [];
4050
+ focusedValue;
4051
+ #e = 0;
4052
+ #o = "";
4053
+ #t;
4054
+ #n;
4055
+ #a;
4056
+ get cursor() {
4057
+ return this.#e;
4058
+ }
4059
+ get userInputWithCursor() {
4060
+ if (!this.userInput) return y(["inverse", "hidden"], "_");
4061
+ if (this._cursor >= this.userInput.length) return `${this.userInput}\u2588`;
4062
+ const t2 = this.userInput.slice(0, this._cursor), [e, ...s] = this.userInput.slice(this._cursor);
4063
+ return `${t2}${y("inverse", e)}${s.join("")}`;
4064
+ }
4065
+ get options() {
4066
+ return typeof this.#n == "function" ? this.#n() : this.#n;
4067
+ }
4068
+ constructor(t2) {
4069
+ super(t2), this.#n = t2.options, this.#a = t2.placeholder;
4070
+ const e = this.options;
4071
+ this.filteredOptions = [...e], this.multiple = t2.multiple === true, this.#t = typeof t2.options == "function" ? t2.filter : t2.filter ?? B;
4072
+ let s;
4073
+ if (t2.initialValue && Array.isArray(t2.initialValue) ? this.multiple ? s = t2.initialValue : s = t2.initialValue.slice(0, 1) : !this.multiple && this.options.length > 0 && (s = [this.options[0].value]), s) for (const i of s) {
4074
+ const n = e.findIndex((o) => o.value === i);
4075
+ n !== -1 && (this.toggleSelected(i), this.#e = n);
4076
+ }
4077
+ this.focusedValue = this.options[this.#e]?.value, this.on("key", (i, n) => this.#s(i, n)), this.on("userInput", (i) => this.#i(i));
4078
+ }
4079
+ _isActionKey(t2, e) {
4080
+ return t2 === " " || this.multiple && this.isNavigating && e.name === "space" && t2 !== void 0 && t2 !== "";
4081
+ }
4082
+ #s(t2, e) {
4083
+ const s = e.name === "up", i = e.name === "down", n = e.name === "return", o = this.userInput === "" || this.userInput === " ", a = this.#a, h = this.options, l = a !== void 0 && a !== "" && h.some((f) => !f.disabled && (this.#t ? this.#t(a, f) : true));
4084
+ if (e.name === "tab" && o && l) {
4085
+ this.userInput === " " && this._clearUserInput(), this._setUserInput(a, true), this.isNavigating = false;
4086
+ return;
4087
+ }
4088
+ s || i ? (this.#e = d(this.#e, s ? -1 : 1, this.filteredOptions), this.focusedValue = this.filteredOptions[this.#e]?.value, this.multiple || (this.selectedValues = [this.focusedValue]), this.isNavigating = true) : n ? this.value = J(this.multiple, this.selectedValues) : this.multiple ? this.focusedValue !== void 0 && (e.name === "tab" || this.isNavigating && e.name === "space") ? this.toggleSelected(this.focusedValue) : this.isNavigating = false : (this.focusedValue && (this.selectedValues = [this.focusedValue]), this.isNavigating = false);
4089
+ }
4090
+ deselectAll() {
4091
+ this.selectedValues = [];
4092
+ }
4093
+ toggleSelected(t2) {
4094
+ this.filteredOptions.length !== 0 && (this.multiple ? this.selectedValues.includes(t2) ? this.selectedValues = this.selectedValues.filter((e) => e !== t2) : this.selectedValues = [...this.selectedValues, t2] : this.selectedValues = [t2]);
4095
+ }
4096
+ #i(t2) {
4097
+ if (t2 !== this.#o) {
4098
+ this.#o = t2;
4099
+ const e = this.options;
4100
+ t2 && this.#t ? this.filteredOptions = e.filter((n) => this.#t?.(t2, n)) : this.filteredOptions = [...e];
4101
+ const s = W(this.focusedValue, this.filteredOptions);
4102
+ this.#e = d(s, 0, this.filteredOptions);
4103
+ const i = this.filteredOptions[this.#e];
4104
+ i && !i.disabled ? this.focusedValue = i.value : this.focusedValue = void 0, this.multiple || (this.focusedValue !== void 0 ? this.toggleSelected(this.focusedValue) : this.deselectAll());
4105
+ }
4106
+ }
4107
+ };
4108
+ var Q = class extends p {
4109
+ get cursor() {
4110
+ return this.value ? 0 : 1;
4111
+ }
4112
+ get _value() {
4113
+ return this.cursor === 0;
4114
+ }
4115
+ constructor(t2) {
4116
+ super(t2, false), this.value = !!t2.initialValue, this.on("userInput", () => {
4117
+ this.value = this._value;
4118
+ }), this.on("confirm", (e) => {
4119
+ this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = e, this.state = "submit", this.close();
4120
+ }), this.on("cursor", () => {
4121
+ this.value = !this.value;
4122
+ });
4123
+ }
4124
+ };
4125
+ var X = { Y: { type: "year", len: 4 }, M: { type: "month", len: 2 }, D: { type: "day", len: 2 } };
4126
+ function L(r) {
4127
+ return [...r].map((t2) => X[t2]);
4128
+ }
4129
+ function Z(r) {
4130
+ const t2 = new Intl.DateTimeFormat(r, { year: "numeric", month: "2-digit", day: "2-digit" }).formatToParts(new Date(2e3, 0, 15)), e = [];
4131
+ let s = "/";
4132
+ for (const i of t2) i.type === "literal" ? s = i.value.trim() || i.value : (i.type === "year" || i.type === "month" || i.type === "day") && e.push({ type: i.type, len: i.type === "year" ? 4 : 2 });
4133
+ return { segments: e, separator: s };
4134
+ }
4135
+ function k(r) {
4136
+ return Number.parseInt((r || "0").replace(/_/g, "0"), 10) || 0;
4137
+ }
4138
+ function I(r) {
4139
+ return { year: k(r.year), month: k(r.month), day: k(r.day) };
4140
+ }
4141
+ function T(r, t2) {
4142
+ return new Date(r || 2001, t2 || 1, 0).getDate();
4143
+ }
4144
+ function F(r) {
4145
+ const { year: t2, month: e, day: s } = I(r);
4146
+ if (!t2 || t2 < 0 || t2 > 9999 || !e || e < 1 || e > 12 || !s || s < 1) return;
4147
+ const i = new Date(Date.UTC(t2, e - 1, s));
4148
+ if (!(i.getUTCFullYear() !== t2 || i.getUTCMonth() !== e - 1 || i.getUTCDate() !== s)) return { year: t2, month: e, day: s };
4149
+ }
4150
+ function N(r) {
4151
+ const t2 = F(r);
4152
+ return t2 ? new Date(Date.UTC(t2.year, t2.month - 1, t2.day)) : void 0;
4153
+ }
4154
+ function tt(r, t2, e, s) {
4155
+ const i = e ? { year: e.getUTCFullYear(), month: e.getUTCMonth() + 1, day: e.getUTCDate() } : null, n = s ? { year: s.getUTCFullYear(), month: s.getUTCMonth() + 1, day: s.getUTCDate() } : null;
4156
+ return r === "year" ? { min: i?.year ?? 1, max: n?.year ?? 9999 } : r === "month" ? { min: i && t2.year === i.year ? i.month : 1, max: n && t2.year === n.year ? n.month : 12 } : { min: i && t2.year === i.year && t2.month === i.month ? i.day : 1, max: n && t2.year === n.year && t2.month === n.month ? n.day : T(t2.year, t2.month) };
4157
+ }
4158
+ var et = class extends p {
4159
+ #e;
4160
+ #o;
4161
+ #t;
4162
+ #n;
4163
+ #a;
4164
+ #s = { segmentIndex: 0, positionInSegment: 0 };
4165
+ #i = true;
4166
+ #r = null;
4167
+ inlineError = "";
4168
+ get segmentCursor() {
4169
+ return { ...this.#s };
4170
+ }
4171
+ get segmentValues() {
4172
+ return { ...this.#t };
4173
+ }
4174
+ get segments() {
4175
+ return this.#e;
4176
+ }
4177
+ get separator() {
4178
+ return this.#o;
4179
+ }
4180
+ get formattedValue() {
4181
+ return this.#c(this.#t);
4182
+ }
4183
+ #c(t2) {
4184
+ return this.#e.map((e) => t2[e.type]).join(this.#o);
4185
+ }
4186
+ #h() {
4187
+ this._setUserInput(this.#c(this.#t)), this._setValue(N(this.#t) ?? void 0);
4188
+ }
4189
+ constructor(t2) {
4190
+ const e = t2.format ? { segments: L(t2.format), separator: t2.separator ?? "/" } : Z(t2.locale), s = t2.separator ?? e.separator, i = t2.format ? L(t2.format) : e.segments, n = t2.initialValue ?? t2.defaultValue, o = n ? { year: String(n.getUTCFullYear()).padStart(4, "0"), month: String(n.getUTCMonth() + 1).padStart(2, "0"), day: String(n.getUTCDate()).padStart(2, "0") } : { year: "____", month: "__", day: "__" }, a = i.map((h) => o[h.type]).join(s);
4191
+ super({ ...t2, initialUserInput: a }, false), this.#e = i, this.#o = s, this.#t = o, this.#n = t2.minDate, this.#a = t2.maxDate, this.#h(), this.on("cursor", (h) => this.#d(h)), this.on("key", (h, l) => this.#f(h, l)), this.on("finalize", () => this.#g(t2));
4192
+ }
4193
+ #u() {
4194
+ const t2 = Math.max(0, Math.min(this.#s.segmentIndex, this.#e.length - 1)), e = this.#e[t2];
4195
+ if (e) return this.#s.positionInSegment = Math.max(0, Math.min(this.#s.positionInSegment, e.len - 1)), { segment: e, index: t2 };
4196
+ }
4197
+ #l(t2) {
4198
+ this.inlineError = "", this.#r = null;
4199
+ const e = this.#u();
4200
+ e && (this.#s.segmentIndex = Math.max(0, Math.min(this.#e.length - 1, e.index + t2)), this.#s.positionInSegment = 0, this.#i = true);
4201
+ }
4202
+ #p(t2) {
4203
+ const e = this.#u();
4204
+ if (!e) return;
4205
+ const { segment: s } = e, i = this.#t[s.type], n = !i || i.replace(/_/g, "") === "", o = Number.parseInt((i || "0").replace(/_/g, "0"), 10) || 0, a = tt(s.type, I(this.#t), this.#n, this.#a);
4206
+ let h;
4207
+ n ? h = t2 === 1 ? a.min : a.max : h = Math.max(Math.min(a.max, o + t2), a.min), this.#t = { ...this.#t, [s.type]: h.toString().padStart(s.len, "0") }, this.#i = true, this.#r = null, this.#h();
4208
+ }
4209
+ #d(t2) {
4210
+ if (t2) switch (t2) {
4211
+ case "right":
4212
+ return this.#l(1);
4213
+ case "left":
4214
+ return this.#l(-1);
4215
+ case "up":
4216
+ return this.#p(1);
4217
+ case "down":
4218
+ return this.#p(-1);
4219
+ }
4220
+ }
4221
+ #f(t2, e) {
4222
+ if (e?.name === "backspace" || e?.sequence === "\x7F" || e?.sequence === "\b" || t2 === "\x7F" || t2 === "\b") {
4223
+ this.inlineError = "";
4224
+ const s = this.#u();
4225
+ if (!s) return;
4226
+ if (!this.#t[s.segment.type].replace(/_/g, "")) {
4227
+ this.#l(-1);
4228
+ return;
4229
+ }
4230
+ this.#t[s.segment.type] = "_".repeat(s.segment.len), this.#i = true, this.#s.positionInSegment = 0, this.#h();
4231
+ return;
4232
+ }
4233
+ if (e?.name === "tab") {
4234
+ this.inlineError = "";
4235
+ const s = this.#u();
4236
+ if (!s) return;
4237
+ const i = e.shift ? -1 : 1, n = s.index + i;
4238
+ n >= 0 && n < this.#e.length && (this.#s.segmentIndex = n, this.#s.positionInSegment = 0, this.#i = true);
4239
+ return;
4240
+ }
4241
+ if (t2 && /^[0-9]$/.test(t2)) {
4242
+ const s = this.#u();
4243
+ if (!s) return;
4244
+ const { segment: i } = s, n = !this.#t[i.type].replace(/_/g, "");
4245
+ if (this.#i && this.#r !== null && !n) {
4246
+ const m = this.#r + t2, g = { ...this.#t, [i.type]: m }, b = this.#m(g, i);
4247
+ if (b) {
4248
+ this.inlineError = b, this.#r = null, this.#i = false;
4249
+ return;
4250
+ }
4251
+ this.inlineError = "", this.#t[i.type] = m, this.#r = null, this.#i = false, this.#h(), s.index < this.#e.length - 1 && (this.#s.segmentIndex = s.index + 1, this.#s.positionInSegment = 0, this.#i = true);
4252
+ return;
4253
+ }
4254
+ this.#i && !n && (this.#t[i.type] = "_".repeat(i.len), this.#s.positionInSegment = 0), this.#i = false, this.#r = null;
4255
+ const o = this.#t[i.type], a = o.indexOf("_"), h = a >= 0 ? a : Math.min(this.#s.positionInSegment, i.len - 1);
4256
+ if (h < 0 || h >= i.len) return;
4257
+ let l = o.slice(0, h) + t2 + o.slice(h + 1), f = false;
4258
+ if (h === 0 && o === "__" && (i.type === "month" || i.type === "day")) {
4259
+ const m = Number.parseInt(t2, 10);
4260
+ l = `0${t2}`, f = m <= (i.type === "month" ? 1 : 2);
4261
+ }
4262
+ if (i.type === "year" && (l = (o.replace(/_/g, "") + t2).padStart(i.len, "_")), !l.includes("_")) {
4263
+ const m = { ...this.#t, [i.type]: l }, g = this.#m(m, i);
4264
+ if (g) {
4265
+ this.inlineError = g;
4266
+ return;
4267
+ }
4268
+ }
4269
+ this.inlineError = "", this.#t[i.type] = l;
4270
+ const v = l.includes("_") ? void 0 : F(this.#t);
4271
+ if (v) {
4272
+ const { year: m, month: g } = v, b = T(m, g);
4273
+ this.#t = { year: String(Math.max(0, Math.min(9999, m))).padStart(4, "0"), month: String(Math.max(1, Math.min(12, g))).padStart(2, "0"), day: String(Math.max(1, Math.min(b, v.day))).padStart(2, "0") };
4274
+ }
4275
+ this.#h();
4276
+ const U2 = l.indexOf("_");
4277
+ f ? (this.#i = true, this.#r = t2) : U2 >= 0 ? this.#s.positionInSegment = U2 : a >= 0 && s.index < this.#e.length - 1 ? (this.#s.segmentIndex = s.index + 1, this.#s.positionInSegment = 0, this.#i = true) : this.#s.positionInSegment = Math.min(h + 1, i.len - 1);
4278
+ }
4279
+ }
4280
+ #m(t2, e) {
4281
+ const { month: s, day: i } = I(t2);
4282
+ if (e.type === "month" && (s < 0 || s > 12)) return u.date.messages.invalidMonth;
4283
+ if (e.type === "day" && (i < 0 || i > 31)) return u.date.messages.invalidDay(31, "any month");
4284
+ }
4285
+ #g(t2) {
4286
+ const { year: e, month: s, day: i } = I(this.#t);
4287
+ if (e && s && i) {
4288
+ const n = T(e, s);
4289
+ this.#t = { ...this.#t, day: String(Math.min(i, n)).padStart(2, "0") };
4290
+ }
4291
+ this.value = N(this.#t) ?? t2.defaultValue ?? void 0;
4292
+ }
4293
+ };
4294
+ var st = class extends p {
4295
+ options;
4296
+ cursor = 0;
4297
+ #e;
4298
+ getGroupItems(t2) {
4299
+ return this.options.filter((e) => e.group === t2);
4300
+ }
4301
+ isGroupSelected(t2) {
4302
+ const e = this.getGroupItems(t2), s = this.value;
4303
+ return s === void 0 ? false : e.every((i) => s.includes(i.value));
4304
+ }
4305
+ toggleValue() {
4306
+ const t2 = this.options[this.cursor];
4307
+ if (this.value === void 0 && (this.value = []), t2.group === true) {
4308
+ const e = t2.value, s = this.getGroupItems(e);
4309
+ this.isGroupSelected(e) ? this.value = this.value.filter((i) => s.findIndex((n) => n.value === i) === -1) : this.value = [...this.value, ...s.map((i) => i.value)], this.value = Array.from(new Set(this.value));
4310
+ } else {
4311
+ const e = this.value.includes(t2.value);
4312
+ this.value = e ? this.value.filter((s) => s !== t2.value) : [...this.value, t2.value];
4313
+ }
4314
+ }
4315
+ constructor(t2) {
4316
+ super(t2, false);
4317
+ const { options: e } = t2;
4318
+ this.#e = t2.selectableGroups !== false, this.options = Object.entries(e).flatMap(([s, i]) => [{ value: s, group: true, label: s }, ...i.map((n) => ({ ...n, group: s }))]), this.value = [...t2.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: s }) => s === t2.cursorAt), this.#e ? 0 : 1), this.on("cursor", (s) => {
4319
+ switch (s) {
4320
+ case "left":
4321
+ case "up": {
4322
+ this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
4323
+ const i = this.options[this.cursor]?.group === true;
4324
+ !this.#e && i && (this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1);
4325
+ break;
4326
+ }
4327
+ case "down":
4328
+ case "right": {
4329
+ this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
4330
+ const i = this.options[this.cursor]?.group === true;
4331
+ !this.#e && i && (this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1);
4332
+ break;
4333
+ }
4334
+ case "space":
4335
+ this.toggleValue();
4336
+ break;
4337
+ }
4338
+ });
4339
+ }
4340
+ };
4341
+ var it = class extends p {
4342
+ options;
4343
+ cursor = 0;
4344
+ get _value() {
4345
+ return this.options[this.cursor].value;
4346
+ }
4347
+ get _enabledOptions() {
4348
+ return this.options.filter((t2) => t2.disabled !== true);
4349
+ }
4350
+ toggleAll() {
4351
+ const t2 = this._enabledOptions, e = this.value !== void 0 && this.value.length === t2.length;
4352
+ this.value = e ? [] : t2.map((s) => s.value);
4353
+ }
4354
+ toggleInvert() {
4355
+ const t2 = this.value;
4356
+ if (!t2) return;
4357
+ const e = this._enabledOptions.filter((s) => !t2.includes(s.value));
4358
+ this.value = e.map((s) => s.value);
4359
+ }
4360
+ toggleValue() {
4361
+ this.value === void 0 && (this.value = []);
4362
+ const t2 = this.value.includes(this._value);
4363
+ this.value = t2 ? this.value.filter((e) => e !== this._value) : [...this.value, this._value];
4364
+ }
4365
+ constructor(t2) {
4366
+ super(t2, false), this.options = t2.options, this.value = [...t2.initialValues ?? []];
4367
+ const e = Math.max(this.options.findIndex(({ value: s }) => s === t2.cursorAt), 0);
4368
+ this.cursor = this.options[e].disabled ? d(e, 1, this.options) : e, this.on("key", (s) => {
4369
+ s === "a" && this.toggleAll(), s === "i" && this.toggleInvert();
4370
+ }), this.on("cursor", (s) => {
4371
+ switch (s) {
4372
+ case "left":
4373
+ case "up":
4374
+ this.cursor = d(this.cursor, -1, this.options);
4375
+ break;
4376
+ case "down":
4377
+ case "right":
4378
+ this.cursor = d(this.cursor, 1, this.options);
4379
+ break;
4380
+ case "space":
4381
+ this.toggleValue();
4382
+ break;
4383
+ }
4384
+ });
4385
+ }
4386
+ };
4387
+ var rt = class extends p {
4388
+ _mask = "\u2022";
4389
+ get cursor() {
4390
+ return this._cursor;
4391
+ }
4392
+ get masked() {
4393
+ return this.userInput.replaceAll(/./g, this._mask);
4394
+ }
4395
+ get userInputWithCursor() {
4396
+ if (this.state === "submit" || this.state === "cancel") return this.masked;
4397
+ const t2 = this.userInput;
4398
+ if (this.cursor >= t2.length) return `${this.masked}${y(["inverse", "hidden"], "_")}`;
4399
+ const e = this.masked, s = e.slice(0, this.cursor), i = e.slice(this.cursor);
4400
+ return `${s}${y("inverse", i[0])}${i.slice(1)}`;
4401
+ }
4402
+ clear() {
4403
+ this._clearUserInput();
4404
+ }
4405
+ constructor({ mask: t2, ...e }) {
4406
+ super(e), this._mask = t2 ?? "\u2022", this.on("userInput", (s) => {
4407
+ this._setValue(s);
4408
+ });
4409
+ }
4410
+ };
4411
+ var nt = class extends p {
4412
+ options;
4413
+ cursor = 0;
4414
+ get _selectedValue() {
4415
+ return this.options[this.cursor];
4416
+ }
4417
+ changeValue() {
4418
+ this.value = this._selectedValue.value;
4419
+ }
4420
+ constructor(t2) {
4421
+ super(t2, false), this.options = t2.options;
4422
+ const e = this.options.findIndex(({ value: i }) => i === t2.initialValue), s = e === -1 ? 0 : e;
4423
+ this.cursor = this.options[s].disabled ? d(s, 1, this.options) : s, this.changeValue(), this.on("cursor", (i) => {
4424
+ switch (i) {
4425
+ case "left":
4426
+ case "up":
4427
+ this.cursor = d(this.cursor, -1, this.options);
4428
+ break;
4429
+ case "down":
4430
+ case "right":
4431
+ this.cursor = d(this.cursor, 1, this.options);
4432
+ break;
4433
+ }
4434
+ this.changeValue();
4435
+ });
4436
+ }
4437
+ };
4438
+ var ot = class extends p {
4439
+ options;
4440
+ cursor = 0;
4441
+ constructor(t2) {
4442
+ super(t2, false), this.options = t2.options;
4443
+ const e = t2.caseSensitive === true, s = this.options.map(({ value: [i] }) => e ? i : i?.toLowerCase());
4444
+ this.cursor = Math.max(s.indexOf(t2.initialValue), 0), this.on("key", (i, n) => {
4445
+ if (!i) return;
4446
+ const o = e && n.shift ? i.toUpperCase() : i;
4447
+ if (!s.includes(o)) return;
4448
+ const a = this.options.find(({ value: [h] }) => e ? h === o : h?.toLowerCase() === i);
4449
+ a && (this.value = a.value, this.state = "submit", this.emit("submit"));
4450
+ });
4451
+ }
4452
+ };
4453
+ var at = class extends p {
4454
+ get userInputWithCursor() {
4455
+ if (this.state === "submit") return this.userInput;
4456
+ const t2 = this.userInput;
4457
+ if (this.cursor >= t2.length) return `${this.userInput}\u2588`;
4458
+ const e = t2.slice(0, this.cursor), [s, ...i] = t2.slice(this.cursor);
4459
+ return `${e}${y("inverse", s)}${i.join("")}`;
4460
+ }
4461
+ get cursor() {
4462
+ return this._cursor;
4463
+ }
4464
+ constructor(t2) {
4465
+ super({ ...t2, initialUserInput: t2.initialUserInput ?? t2.initialValue }), this.on("userInput", (e) => {
4466
+ this._setValue(e);
4467
+ }), this.on("finalize", () => {
4468
+ this.value || (this.value = t2.defaultValue), this.value === void 0 && (this.value = "");
4469
+ });
4470
+ }
4471
+ };
4472
+
4473
+ // ../../node_modules/@clack/prompts/dist/index.mjs
4474
+ import { styleText as t, stripVTControlCharacters as ne } from "util";
4475
+ import P2 from "process";
4476
+ var import_sisteransi2 = __toESM(require_src(), 1);
4477
+ import { existsSync as Xe, lstatSync as we, readdirSync as ze } from "fs";
4478
+ import { dirname as be, join as Qe } from "path";
4479
+ function Ze() {
4480
+ return P2.platform !== "win32" ? P2.env.TERM !== "linux" : !!P2.env.CI || !!P2.env.WT_SESSION || !!P2.env.TERMINUS_SUBLIME || P2.env.ConEmuTask === "{cmd::Cmder}" || P2.env.TERM_PROGRAM === "Terminus-Sublime" || P2.env.TERM_PROGRAM === "vscode" || P2.env.TERM === "xterm-256color" || P2.env.TERM === "alacritty" || P2.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
4481
+ }
4482
+ var ee = Ze();
4483
+ var ae = () => process.env.CI === "true";
4484
+ var Te = (e) => e.isTTY === true;
4485
+ var w2 = (e, i) => ee ? e : i;
4486
+ var _e = w2("\u25C6", "*");
4487
+ var oe = w2("\u25A0", "x");
4488
+ var ue = w2("\u25B2", "x");
4489
+ var F2 = w2("\u25C7", "o");
4490
+ var le = w2("\u250C", "T");
4491
+ var d2 = w2("\u2502", "|");
4492
+ var E2 = w2("\u2514", "\u2014");
4493
+ var Ie = w2("\u2510", "T");
4494
+ var Ee = w2("\u2518", "\u2014");
4495
+ var z2 = w2("\u25CF", ">");
4496
+ var H2 = w2("\u25CB", " ");
4497
+ var te = w2("\u25FB", "[\u2022]");
4498
+ var U = w2("\u25FC", "[+]");
4499
+ var J2 = w2("\u25FB", "[ ]");
4500
+ var xe = w2("\u25AA", "\u2022");
4501
+ var se = w2("\u2500", "-");
4502
+ var ce = w2("\u256E", "+");
4503
+ var Ge = w2("\u251C", "+");
4504
+ var $e = w2("\u256F", "+");
4505
+ var de = w2("\u2570", "+");
4506
+ var Oe = w2("\u256D", "+");
4507
+ var he = w2("\u25CF", "\u2022");
4508
+ var pe = w2("\u25C6", "*");
4509
+ var me = w2("\u25B2", "!");
4510
+ var ge = w2("\u25A0", "x");
4511
+ var V2 = (e) => {
4512
+ switch (e) {
4513
+ case "initial":
4514
+ case "active":
4515
+ return t("cyan", _e);
4516
+ case "cancel":
4517
+ return t("red", oe);
4518
+ case "error":
4519
+ return t("yellow", ue);
4520
+ case "submit":
4521
+ return t("green", F2);
4522
+ }
4523
+ };
4524
+ var ye = (e) => {
4525
+ switch (e) {
4526
+ case "initial":
4527
+ case "active":
4528
+ return t("cyan", d2);
4529
+ case "cancel":
4530
+ return t("red", d2);
4531
+ case "error":
4532
+ return t("yellow", d2);
4533
+ case "submit":
4534
+ return t("green", d2);
4535
+ }
4536
+ };
4537
+ var et2 = (e, i, s, r, u2) => {
4538
+ let n = i, o = 0;
4539
+ for (let c2 = s; c2 < r; c2++) {
4540
+ const a = e[c2];
4541
+ if (n = n - a.length, o++, n <= u2) break;
4542
+ }
4543
+ return { lineCount: n, removals: o };
4544
+ };
4545
+ var Y2 = ({ cursor: e, options: i, style: s, output: r = process.stdout, maxItems: u2 = Number.POSITIVE_INFINITY, columnPadding: n = 0, rowPadding: o = 4 }) => {
4546
+ const c2 = O(r) - n, a = A(r), l = t("dim", "..."), $2 = Math.max(a - o, 0), y2 = Math.max(Math.min(u2, $2), 5);
4547
+ let p2 = 0;
4548
+ e >= y2 - 3 && (p2 = Math.max(Math.min(e - y2 + 3, i.length - y2), 0));
4549
+ let m = y2 < i.length && p2 > 0, g = y2 < i.length && p2 + y2 < i.length;
4550
+ const S2 = Math.min(p2 + y2, i.length), h = [];
4551
+ let f = 0;
4552
+ m && f++, g && f++;
4553
+ const v = p2 + (m ? 1 : 0), T2 = S2 - (g ? 1 : 0);
4554
+ for (let b = v; b < T2; b++) {
4555
+ const x = wrapAnsi(s(i[b], b === e), c2, { hard: true, trim: false }).split(`
4556
+ `);
4557
+ h.push(x), f += x.length;
4558
+ }
4559
+ if (f > $2) {
4560
+ let b = 0, x = 0, G2 = f;
4561
+ const M2 = e - v, R2 = (j2, D2) => et2(h, G2, j2, D2, $2);
4562
+ m ? ({ lineCount: G2, removals: b } = R2(0, M2), G2 > $2 && ({ lineCount: G2, removals: x } = R2(M2 + 1, h.length))) : ({ lineCount: G2, removals: x } = R2(M2 + 1, h.length), G2 > $2 && ({ lineCount: G2, removals: b } = R2(0, M2))), b > 0 && (m = true, h.splice(0, b)), x > 0 && (g = true, h.splice(h.length - x, x));
4563
+ }
4564
+ const C2 = [];
4565
+ m && C2.push(l);
4566
+ for (const b of h) for (const x of b) C2.push(x);
4567
+ return g && C2.push(l), C2;
4568
+ };
4569
+ function Me(e) {
4570
+ return e.label ?? String(e.value ?? "");
4571
+ }
4572
+ function Re(e, i) {
4573
+ if (!e) return true;
4574
+ const s = (i.label ?? String(i.value ?? "")).toLowerCase(), r = (i.hint ?? "").toLowerCase(), u2 = String(i.value).toLowerCase(), n = e.toLowerCase();
4575
+ return s.includes(n) || r.includes(n) || u2.includes(n);
4576
+ }
4577
+ function tt2(e, i) {
4578
+ const s = [];
4579
+ for (const r of i) e.includes(r.value) && s.push(r);
4580
+ return s;
4581
+ }
4582
+ var Ae = (e) => new H({ options: e.options, initialValue: e.initialValue ? [e.initialValue] : void 0, initialUserInput: e.initialUserInput, placeholder: e.placeholder, filter: e.filter ?? ((i, s) => Re(i, s)), signal: e.signal, input: e.input, output: e.output, validate: e.validate, render() {
4583
+ const i = e.withGuide ?? u.withGuide, s = i ? [`${t("gray", d2)}`, `${V2(this.state)} ${e.message}`] : [`${V2(this.state)} ${e.message}`], r = this.userInput, u2 = this.options, n = e.placeholder, o = r === "" && n !== void 0, c2 = (a, l) => {
4584
+ const $2 = Me(a), y2 = a.hint && a.value === this.focusedValue ? t("dim", ` (${a.hint})`) : "";
4585
+ switch (l) {
4586
+ case "active":
4587
+ return `${t("green", z2)} ${$2}${y2}`;
4588
+ case "inactive":
4589
+ return `${t("dim", H2)} ${t("dim", $2)}`;
4590
+ case "disabled":
4591
+ return `${t("gray", H2)} ${t(["strikethrough", "gray"], $2)}`;
4592
+ }
4593
+ };
4594
+ switch (this.state) {
4595
+ case "submit": {
4596
+ const a = tt2(this.selectedValues, u2), l = a.length > 0 ? ` ${t("dim", a.map(Me).join(", "))}` : "", $2 = i ? t("gray", d2) : "";
4597
+ return `${s.join(`
4598
+ `)}
4599
+ ${$2}${l}`;
4600
+ }
4601
+ case "cancel": {
4602
+ const a = r ? ` ${t(["strikethrough", "dim"], r)}` : "", l = i ? t("gray", d2) : "";
4603
+ return `${s.join(`
4604
+ `)}
4605
+ ${l}${a}`;
4606
+ }
4607
+ default: {
4608
+ const a = this.state === "error" ? "yellow" : "cyan", l = i ? `${t(a, d2)} ` : "", $2 = i ? t(a, E2) : "";
4609
+ let y2 = "";
4610
+ if (this.isNavigating || o) {
4611
+ const v = o ? n : r;
4612
+ y2 = v !== "" ? ` ${t("dim", v)}` : "";
4613
+ } else y2 = ` ${this.userInputWithCursor}`;
4614
+ const p2 = this.filteredOptions.length !== u2.length ? t("dim", ` (${this.filteredOptions.length} match${this.filteredOptions.length === 1 ? "" : "es"})`) : "", m = this.filteredOptions.length === 0 && r ? [`${l}${t("yellow", "No matches found")}`] : [], g = this.state === "error" ? [`${l}${t("yellow", this.error)}`] : [];
4615
+ i && s.push(`${l.trimEnd()}`), s.push(`${l}${t("dim", "Search:")}${y2}${p2}`, ...m, ...g);
4616
+ const S2 = [`${t("dim", "\u2191/\u2193")} to select`, `${t("dim", "Enter:")} confirm`, `${t("dim", "Type:")} to search`], h = [`${l}${S2.join(" \u2022 ")}`, $2], f = this.filteredOptions.length === 0 ? [] : Y2({ cursor: this.cursor, options: this.filteredOptions, columnPadding: i ? 3 : 0, rowPadding: s.length + h.length, style: (v, T2) => c2(v, v.disabled ? "disabled" : T2 ? "active" : "inactive"), maxItems: e.maxItems, output: e.output });
4617
+ return [...s, ...f.map((v) => `${l}${v}`), ...h].join(`
4618
+ `);
4619
+ }
4620
+ }
4621
+ } }).prompt();
4622
+ var st2 = (e) => {
4623
+ const i = (r, u2, n, o) => {
4624
+ const c2 = n.includes(r.value), a = r.label ?? String(r.value ?? ""), l = r.hint && o !== void 0 && r.value === o ? t("dim", ` (${r.hint})`) : "", $2 = c2 ? t("green", U) : t("dim", J2);
4625
+ return r.disabled ? `${t("gray", J2)} ${t(["strikethrough", "gray"], a)}` : u2 ? `${$2} ${a}${l}` : `${$2} ${t("dim", a)}`;
4626
+ }, s = new H({ options: e.options, multiple: true, placeholder: e.placeholder, filter: e.filter ?? ((r, u2) => Re(r, u2)), validate: () => {
4627
+ if (e.required && s.selectedValues.length === 0) return "Please select at least one item";
4628
+ }, initialValue: e.initialValues, signal: e.signal, input: e.input, output: e.output, render() {
4629
+ const r = e.withGuide ?? u.withGuide, u2 = `${r ? `${t("gray", d2)}
4630
+ ` : ""}${V2(this.state)} ${e.message}
4631
+ `, n = this.userInput, o = e.placeholder, c2 = n === "" && o !== void 0, a = this.isNavigating || c2 ? t("dim", c2 ? o : n) : this.userInputWithCursor, l = this.options, $2 = this.filteredOptions.length !== l.length ? t("dim", ` (${this.filteredOptions.length} match${this.filteredOptions.length === 1 ? "" : "es"})`) : "";
4632
+ switch (this.state) {
4633
+ case "submit":
4634
+ return `${u2}${r ? `${t("gray", d2)} ` : ""}${t("dim", `${this.selectedValues.length} items selected`)}`;
4635
+ case "cancel":
4636
+ return `${u2}${r ? `${t("gray", d2)} ` : ""}${t(["strikethrough", "dim"], n)}`;
4637
+ default: {
4638
+ const y2 = this.state === "error" ? "yellow" : "cyan", p2 = r ? `${t(y2, d2)} ` : "", m = r ? t(y2, E2) : "", g = [`${t("dim", "\u2191/\u2193")} to navigate`, `${t("dim", this.isNavigating ? "Space/Tab:" : "Tab:")} select`, `${t("dim", "Enter:")} confirm`, `${t("dim", "Type:")} to search`], S2 = this.filteredOptions.length === 0 && n ? [`${p2}${t("yellow", "No matches found")}`] : [], h = this.state === "error" ? [`${p2}${t("yellow", this.error)}`] : [], f = [...`${u2}${r ? t(y2, d2) : ""}`.split(`
4639
+ `), `${p2}${t("dim", "Search:")} ${a}${$2}`, ...S2, ...h], v = [`${p2}${g.join(" \u2022 ")}`, m], T2 = Y2({ cursor: this.cursor, options: this.filteredOptions, style: (C2, b) => i(C2, b, this.selectedValues, this.focusedValue), maxItems: e.maxItems, output: e.output, rowPadding: f.length + v.length });
4640
+ return [...f, ...T2.map((C2) => `${p2}${C2}`), ...v].join(`
4641
+ `);
4642
+ }
4643
+ }
4644
+ } });
4645
+ return s.prompt();
4646
+ };
4647
+ var rt2 = [Oe, ce, de, $e];
4648
+ var it2 = [le, Ie, E2, Ee];
4649
+ function Pe(e, i, s, r) {
4650
+ let u2 = s, n = s;
4651
+ return r === "center" ? u2 = Math.floor((i - e) / 2) : r === "right" && (u2 = i - e - s), n = i - u2 - e, [u2, n];
4652
+ }
4653
+ var nt2 = (e) => e;
4654
+ var at2 = (e = "", i = "", s) => {
4655
+ const r = s?.output ?? process.stdout, u2 = O(r), n = 2, o = s?.titlePadding ?? 1, c2 = s?.contentPadding ?? 2, a = s?.width === void 0 || s.width === "auto" ? 1 : Math.min(1, s.width), l = s?.withGuide ?? u.withGuide ? `${d2} ` : "", $2 = s?.formatBorder ?? nt2, y2 = (s?.rounded ? rt2 : it2).map($2), p2 = $2(se), m = $2(d2), g = dist_default2(l), S2 = dist_default2(i), h = u2 - g;
4656
+ let f = Math.floor(u2 * a) - g;
4657
+ if (s?.width === "auto") {
4658
+ const R2 = e.split(`
4659
+ `);
4660
+ let j2 = S2 + o * 2;
4661
+ for (const ie of R2) {
4662
+ const W2 = dist_default2(ie) + c2 * 2;
4663
+ W2 > j2 && (j2 = W2);
4664
+ }
4665
+ const D2 = j2 + n;
4666
+ D2 < f && (f = D2);
4667
+ }
4668
+ f % 2 !== 0 && (f < h ? f++ : f--);
4669
+ const v = f - n, T2 = v - o * 2, C2 = S2 > T2 ? `${i.slice(0, T2 - 3)}...` : i, [b, x] = Pe(dist_default2(C2), v, o, s?.titleAlign), G2 = wrapAnsi(e, v - c2 * 2, { hard: true, trim: false });
4670
+ r.write(`${l}${y2[0]}${p2.repeat(b)}${C2}${p2.repeat(x)}${y2[1]}
4671
+ `);
4672
+ const M2 = G2.split(`
4673
+ `);
4674
+ for (const R2 of M2) {
4675
+ const [j2, D2] = Pe(dist_default2(R2), v, c2, s?.contentAlign);
4676
+ r.write(`${l}${m}${" ".repeat(j2)}${R2}${" ".repeat(D2)}${m}
4677
+ `);
4678
+ }
4679
+ r.write(`${l}${y2[2]}${p2.repeat(v)}${y2[3]}
4680
+ `);
4681
+ };
4682
+ var ot2 = (e) => {
4683
+ const i = e.active ?? "Yes", s = e.inactive ?? "No";
4684
+ return new Q({ active: i, inactive: s, signal: e.signal, input: e.input, output: e.output, initialValue: e.initialValue ?? true, render() {
4685
+ const r = e.withGuide ?? u.withGuide, u2 = `${V2(this.state)} `, n = r ? `${t("gray", d2)} ` : "", o = R(e.output, e.message, n, u2), c2 = `${r ? `${t("gray", d2)}
4686
+ ` : ""}${o}
4687
+ `, a = this.value ? i : s;
4688
+ switch (this.state) {
4689
+ case "submit": {
4690
+ const l = r ? `${t("gray", d2)} ` : "";
4691
+ return `${c2}${l}${t("dim", a)}`;
4692
+ }
4693
+ case "cancel": {
4694
+ const l = r ? `${t("gray", d2)} ` : "";
4695
+ return `${c2}${l}${t(["strikethrough", "dim"], a)}${r ? `
4696
+ ${t("gray", d2)}` : ""}`;
4697
+ }
4698
+ default: {
4699
+ const l = r ? `${t("cyan", d2)} ` : "", $2 = r ? t("cyan", E2) : "";
4700
+ return `${c2}${l}${this.value ? `${t("green", z2)} ${i}` : `${t("dim", H2)} ${t("dim", i)}`}${e.vertical ? r ? `
4701
+ ${t("cyan", d2)} ` : `
4702
+ ` : ` ${t("dim", "/")} `}${this.value ? `${t("dim", H2)} ${t("dim", s)}` : `${t("green", z2)} ${s}`}
4703
+ ${$2}
4704
+ `;
4705
+ }
4706
+ }
4707
+ } }).prompt();
4708
+ };
4709
+ var ut = (e) => {
4710
+ const i = e.validate;
4711
+ return new et({ ...e, validate(s) {
4712
+ if (s === void 0) return e.defaultValue !== void 0 ? void 0 : i ? i(s) : u.date.messages.required;
4713
+ const r = (u2) => u2.toISOString().slice(0, 10);
4714
+ if (e.minDate && r(s) < r(e.minDate)) return u.date.messages.afterMin(e.minDate);
4715
+ if (e.maxDate && r(s) > r(e.maxDate)) return u.date.messages.beforeMax(e.maxDate);
4716
+ if (i) return i(s);
4717
+ }, render() {
4718
+ const s = (e?.withGuide ?? u.withGuide) !== false, r = `${`${s ? `${t("gray", d2)}
4719
+ ` : ""}${V2(this.state)} `}${e.message}
4720
+ `, u2 = this.state !== "initial" ? this.state : "active", n = lt(this, u2), o = this.value instanceof Date ? this.formattedValue : "";
4721
+ switch (this.state) {
4722
+ case "error": {
4723
+ const c2 = this.error ? ` ${t("yellow", this.error)}` : "", a = s ? `${t("yellow", d2)} ` : "", l = s ? t("yellow", E2) : "";
4724
+ return `${r.trim()}
4725
+ ${a}${n}
4726
+ ${l}${c2}
4727
+ `;
4728
+ }
4729
+ case "submit": {
4730
+ const c2 = o ? ` ${t("dim", o)}` : "", a = s ? t("gray", d2) : "";
4731
+ return `${r}${a}${c2}`;
4732
+ }
4733
+ case "cancel": {
4734
+ const c2 = o ? ` ${t(["strikethrough", "dim"], o)}` : "", a = s ? t("gray", d2) : "";
4735
+ return `${r}${a}${c2}${o.trim() ? `
4736
+ ${a}` : ""}`;
4737
+ }
4738
+ default: {
4739
+ const c2 = s ? `${t("cyan", d2)} ` : "", a = s ? t("cyan", E2) : "", l = s ? `${t("cyan", d2)} ` : "", $2 = this.inlineError ? `
4740
+ ${l}${t("yellow", this.inlineError)}` : "";
4741
+ return `${r}${c2}${n}${$2}
4742
+ ${a}
4743
+ `;
4744
+ }
4745
+ }
4746
+ } }).prompt();
4747
+ };
4748
+ function lt(e, i) {
4749
+ const s = e.segmentValues, r = e.segmentCursor;
4750
+ if (i === "submit" || i === "cancel") return e.formattedValue;
4751
+ const u2 = t("gray", e.separator);
4752
+ return e.segments.map((n, o) => {
4753
+ const c2 = o === r.segmentIndex && !["submit", "cancel"].includes(i), a = $t[n.type];
4754
+ return ct(s[n.type], { isActive: c2, label: a });
4755
+ }).join(u2);
4756
+ }
4757
+ function ct(e, i) {
4758
+ const s = !e || e.replace(/_/g, "") === "";
4759
+ return i.isActive ? t("inverse", s ? i.label : e.replace(/_/g, " ")) : s ? t("dim", i.label) : e.replace(/_/g, t("dim", " "));
4760
+ }
4761
+ var $t = { year: "yyyy", month: "mm", day: "dd" };
4762
+ var dt = async (e, i) => {
4763
+ const s = {}, r = Object.keys(e);
4764
+ for (const u2 of r) {
4765
+ const n = e[u2], o = await n({ results: s })?.catch((c2) => {
4766
+ throw c2;
4767
+ });
4768
+ if (typeof i?.onCancel == "function" && q(o)) {
4769
+ s[u2] = "canceled", i.onCancel({ results: s });
4770
+ continue;
4771
+ }
4772
+ s[u2] = o;
4773
+ }
4774
+ return s;
4775
+ };
4776
+ var ht = (e) => {
4777
+ const { selectableGroups: i = true, groupSpacing: s = 0 } = e, r = (n, o, c2 = []) => {
4778
+ const a = n.label ?? String(n.value), l = typeof n.group == "string", $2 = l && (c2[c2.indexOf(n) + 1] ?? { group: true }), y2 = l && $2 && $2.group === true, p2 = l ? i ? `${y2 ? E2 : d2} ` : " " : "";
4779
+ let m = "";
4780
+ if (s > 0 && !l) {
4781
+ const S2 = `
4782
+ ${t("cyan", d2)}`;
4783
+ m = `${S2.repeat(s - 1)}${S2} `;
4784
+ }
4785
+ if (o === "active") return `${m}${t("dim", p2)}${t("cyan", te)} ${a}${n.hint ? ` ${t("dim", `(${n.hint})`)}` : ""}`;
4786
+ if (o === "group-active") return `${m}${p2}${t("cyan", te)} ${t("dim", a)}`;
4787
+ if (o === "group-active-selected") return `${m}${p2}${t("green", U)} ${t("dim", a)}`;
4788
+ if (o === "selected") {
4789
+ const S2 = l || i ? t("green", U) : "";
4790
+ return `${m}${t("dim", p2)}${S2} ${t("dim", a)}${n.hint ? ` ${t("dim", `(${n.hint})`)}` : ""}`;
4791
+ }
4792
+ if (o === "cancelled") return `${t(["strikethrough", "dim"], a)}`;
4793
+ if (o === "active-selected") return `${m}${t("dim", p2)}${t("green", U)} ${a}${n.hint ? ` ${t("dim", `(${n.hint})`)}` : ""}`;
4794
+ if (o === "submitted") return `${t("dim", a)}`;
4795
+ const g = l || i ? t("dim", J2) : "";
4796
+ return `${m}${t("dim", p2)}${g} ${t("dim", a)}`;
4797
+ }, u2 = e.required ?? true;
4798
+ return new st({ options: e.options, signal: e.signal, input: e.input, output: e.output, initialValues: e.initialValues, required: u2, cursorAt: e.cursorAt, selectableGroups: i, validate(n) {
4799
+ if (u2 && (n === void 0 || n.length === 0)) return `Please select at least one option.
4800
+ ${t("reset", t("dim", `Press ${t(["gray", "bgWhite", "inverse"], " space ")} to select, ${t("gray", t(["bgWhite", "inverse"], " enter "))} to submit`))}`;
4801
+ }, render() {
4802
+ const n = e.withGuide ?? u.withGuide, o = `${n ? `${t("gray", d2)}
4803
+ ` : ""}${V2(this.state)} ${e.message}
4804
+ `, c2 = this.value ?? [];
4805
+ switch (this.state) {
4806
+ case "submit": {
4807
+ const a = this.options.filter(({ value: $2 }) => c2.includes($2)).map(($2) => r($2, "submitted")), l = a.length === 0 ? "" : ` ${a.join(t("dim", ", "))}`;
4808
+ return `${o}${n ? t("gray", d2) : ""}${l}`;
4809
+ }
4810
+ case "cancel": {
4811
+ const a = this.options.filter(({ value: l }) => c2.includes(l)).map((l) => r(l, "cancelled")).join(t("dim", ", "));
4812
+ return `${o}${n ? `${t("gray", d2)} ` : ""}${a.trim() ? `${a}${n ? `
4813
+ ${t("gray", d2)}` : ""}` : ""}`;
4814
+ }
4815
+ case "error": {
4816
+ const a = this.error.split(`
4817
+ `).map((l, $2) => $2 === 0 ? `${n ? `${t("yellow", E2)} ` : ""}${t("yellow", l)}` : ` ${l}`).join(`
4818
+ `);
4819
+ return `${o}${n ? `${t("yellow", d2)} ` : ""}${this.options.map((l, $2, y2) => {
4820
+ const p2 = c2.includes(l.value) || l.group === true && this.isGroupSelected(`${l.value}`), m = $2 === this.cursor;
4821
+ return !m && typeof l.group == "string" && this.options[this.cursor].value === l.group ? r(l, p2 ? "group-active-selected" : "group-active", y2) : m && p2 ? r(l, "active-selected", y2) : p2 ? r(l, "selected", y2) : r(l, m ? "active" : "inactive", y2);
4822
+ }).join(`
4823
+ ${n ? `${t("yellow", d2)} ` : ""}`)}
4824
+ ${a}
4825
+ `;
4826
+ }
4827
+ default: {
4828
+ const a = this.options.map(($2, y2, p2) => {
4829
+ const m = c2.includes($2.value) || $2.group === true && this.isGroupSelected(`${$2.value}`), g = y2 === this.cursor, S2 = !g && typeof $2.group == "string" && this.options[this.cursor].value === $2.group;
4830
+ let h = "";
4831
+ return S2 ? h = r($2, m ? "group-active-selected" : "group-active", p2) : g && m ? h = r($2, "active-selected", p2) : m ? h = r($2, "selected", p2) : h = r($2, g ? "active" : "inactive", p2), `${y2 !== 0 && !h.startsWith(`
4832
+ `) ? " " : ""}${h}`;
4833
+ }).join(`
4834
+ ${n ? t("cyan", d2) : ""}`), l = a.startsWith(`
4835
+ `) ? "" : " ";
4836
+ return `${o}${n ? t("cyan", d2) : ""}${l}${a}
4837
+ ${n ? t("cyan", E2) : ""}
4838
+ `;
4839
+ }
4840
+ }
4841
+ } }).prompt();
4842
+ };
4843
+ var O2 = { message: (e = [], { symbol: i = t("gray", d2), secondarySymbol: s = t("gray", d2), output: r = process.stdout, spacing: u2 = 1, withGuide: n } = {}) => {
4844
+ const o = [], c2 = n ?? u.withGuide, a = c2 ? s : "", l = c2 ? `${i} ` : "", $2 = c2 ? `${s} ` : "";
4845
+ for (let p2 = 0; p2 < u2; p2++) o.push(a);
4846
+ const y2 = Array.isArray(e) ? e : e.split(`
4847
+ `);
4848
+ if (y2.length > 0) {
4849
+ const [p2, ...m] = y2;
4850
+ p2.length > 0 ? o.push(`${l}${p2}`) : o.push(c2 ? i : "");
4851
+ for (const g of m) g.length > 0 ? o.push(`${$2}${g}`) : o.push(c2 ? s : "");
4852
+ }
4853
+ r.write(`${o.join(`
4854
+ `)}
4855
+ `);
4856
+ }, info: (e, i) => {
4857
+ O2.message(e, { ...i, symbol: t("blue", he) });
4858
+ }, success: (e, i) => {
4859
+ O2.message(e, { ...i, symbol: t("green", pe) });
4860
+ }, step: (e, i) => {
4861
+ O2.message(e, { ...i, symbol: t("green", F2) });
4862
+ }, warn: (e, i) => {
4863
+ O2.message(e, { ...i, symbol: t("yellow", me) });
4864
+ }, warning: (e, i) => {
4865
+ O2.warn(e, i);
4866
+ }, error: (e, i) => {
4867
+ O2.message(e, { ...i, symbol: t("red", ge) });
4868
+ } };
4869
+ var pt = (e = "", i) => {
4870
+ const s = i?.output ?? process.stdout, r = i?.withGuide ?? u.withGuide ? `${t("gray", E2)} ` : "";
4871
+ s.write(`${r}${t("red", e)}
4872
+
4873
+ `);
4874
+ };
4875
+ var mt = (e = "", i) => {
4876
+ const s = i?.output ?? process.stdout, r = i?.withGuide ?? u.withGuide ? `${t("gray", le)} ` : "";
4877
+ s.write(`${r}${e}
4878
+ `);
4879
+ };
4880
+ var gt = (e = "", i) => {
4881
+ const s = i?.output ?? process.stdout, r = i?.withGuide ?? u.withGuide ? `${t("gray", d2)}
4882
+ ${t("gray", E2)} ` : "";
4883
+ s.write(`${r}${e}
4884
+
4885
+ `);
4886
+ };
4887
+ var Q2 = (e, i) => e.split(`
4888
+ `).map((s) => i(s)).join(`
4889
+ `);
4890
+ var yt = (e) => {
4891
+ const i = (r, u2) => {
4892
+ const n = r.label ?? String(r.value);
4893
+ return u2 === "disabled" ? `${t("gray", J2)} ${Q2(n, (o) => t(["strikethrough", "gray"], o))}${r.hint ? ` ${t("dim", `(${r.hint ?? "disabled"})`)}` : ""}` : u2 === "active" ? `${t("cyan", te)} ${n}${r.hint ? ` ${t("dim", `(${r.hint})`)}` : ""}` : u2 === "selected" ? `${t("green", U)} ${Q2(n, (o) => t("dim", o))}${r.hint ? ` ${t("dim", `(${r.hint})`)}` : ""}` : u2 === "cancelled" ? `${Q2(n, (o) => t(["strikethrough", "dim"], o))}` : u2 === "active-selected" ? `${t("green", U)} ${n}${r.hint ? ` ${t("dim", `(${r.hint})`)}` : ""}` : u2 === "submitted" ? `${Q2(n, (o) => t("dim", o))}` : `${t("dim", J2)} ${Q2(n, (o) => t("dim", o))}`;
4894
+ }, s = e.required ?? true;
4895
+ return new it({ options: e.options, signal: e.signal, input: e.input, output: e.output, initialValues: e.initialValues, required: s, cursorAt: e.cursorAt, validate(r) {
4896
+ if (s && (r === void 0 || r.length === 0)) return `Please select at least one option.
4897
+ ${t("reset", t("dim", `Press ${t(["gray", "bgWhite", "inverse"], " space ")} to select, ${t("gray", t("bgWhite", t("inverse", " enter ")))} to submit`))}`;
4898
+ }, render() {
4899
+ const r = e.withGuide ?? u.withGuide, u2 = R(e.output, e.message, r ? `${ye(this.state)} ` : "", `${V2(this.state)} `), n = `${r ? `${t("gray", d2)}
4900
+ ` : ""}${u2}
4901
+ `, o = this.value ?? [], c2 = (a, l) => {
4902
+ if (a.disabled) return i(a, "disabled");
4903
+ const $2 = o.includes(a.value);
4904
+ return l && $2 ? i(a, "active-selected") : $2 ? i(a, "selected") : i(a, l ? "active" : "inactive");
4905
+ };
4906
+ switch (this.state) {
4907
+ case "submit": {
4908
+ const a = this.options.filter(({ value: $2 }) => o.includes($2)).map(($2) => i($2, "submitted")).join(t("dim", ", ")) || t("dim", "none"), l = R(e.output, a, r ? `${t("gray", d2)} ` : "");
4909
+ return `${n}${l}`;
4910
+ }
4911
+ case "cancel": {
4912
+ const a = this.options.filter(({ value: $2 }) => o.includes($2)).map(($2) => i($2, "cancelled")).join(t("dim", ", "));
4913
+ if (a.trim() === "") return `${n}${t("gray", d2)}`;
4914
+ const l = R(e.output, a, r ? `${t("gray", d2)} ` : "");
4915
+ return `${n}${l}${r ? `
4916
+ ${t("gray", d2)}` : ""}`;
4917
+ }
4918
+ case "error": {
4919
+ const a = r ? `${t("yellow", d2)} ` : "", l = this.error.split(`
4920
+ `).map((p2, m) => m === 0 ? `${r ? `${t("yellow", E2)} ` : ""}${t("yellow", p2)}` : ` ${p2}`).join(`
4921
+ `), $2 = n.split(`
4922
+ `).length, y2 = l.split(`
4923
+ `).length + 1;
4924
+ return `${n}${a}${Y2({ output: e.output, options: this.options, cursor: this.cursor, maxItems: e.maxItems, columnPadding: a.length, rowPadding: $2 + y2, style: c2 }).join(`
4925
+ ${a}`)}
4926
+ ${l}
4927
+ `;
4928
+ }
4929
+ default: {
4930
+ const a = r ? `${t("cyan", d2)} ` : "", l = n.split(`
4931
+ `).length, $2 = r ? 2 : 1;
4932
+ return `${n}${a}${Y2({ output: e.output, options: this.options, cursor: this.cursor, maxItems: e.maxItems, columnPadding: a.length, rowPadding: l + $2, style: c2 }).join(`
4933
+ ${a}`)}
4934
+ ${r ? t("cyan", E2) : ""}
4935
+ `;
4936
+ }
4937
+ }
4938
+ } }).prompt();
4939
+ };
4940
+ var ft = (e) => t("dim", e);
4941
+ var vt = (e, i, s) => {
4942
+ const r = { hard: true, trim: false }, u2 = wrapAnsi(e, i, r).split(`
4943
+ `), n = u2.reduce((a, l) => Math.max(dist_default2(l), a), 0), o = u2.map(s).reduce((a, l) => Math.max(dist_default2(l), a), 0), c2 = i - (o - n);
4944
+ return wrapAnsi(e, c2, r);
4945
+ };
4946
+ var wt = (e = "", i = "", s) => {
4947
+ const r = s?.output ?? P2.stdout, u2 = s?.withGuide ?? u.withGuide, n = s?.format ?? ft, o = ["", ...vt(e, O(r) - 6, n).split(`
4948
+ `).map(n), ""], c2 = dist_default2(i), a = Math.max(o.reduce((p2, m) => {
4949
+ const g = dist_default2(m);
4950
+ return g > p2 ? g : p2;
4951
+ }, 0), c2) + 2, l = o.map((p2) => `${t("gray", d2)} ${p2}${" ".repeat(a - dist_default2(p2))}${t("gray", d2)}`).join(`
4952
+ `), $2 = u2 ? `${t("gray", d2)}
4953
+ ` : "", y2 = u2 ? Ge : de;
4954
+ r.write(`${$2}${t("green", F2)} ${t("reset", i)} ${t("gray", se.repeat(Math.max(a - c2 - 1, 1)) + ce)}
4955
+ ${l}
4956
+ ${t("gray", y2 + se.repeat(a + 2) + $e)}
4957
+ `);
4958
+ };
4959
+ var bt = (e) => new rt({ validate: e.validate, mask: e.mask ?? xe, signal: e.signal, input: e.input, output: e.output, render() {
4960
+ const i = e.withGuide ?? u.withGuide, s = `${i ? `${t("gray", d2)}
4961
+ ` : ""}${V2(this.state)} ${e.message}
4962
+ `, r = this.userInputWithCursor, u2 = this.masked;
4963
+ switch (this.state) {
4964
+ case "error": {
4965
+ const n = i ? `${t("yellow", d2)} ` : "", o = i ? `${t("yellow", E2)} ` : "", c2 = u2 ?? "";
4966
+ return e.clearOnError && this.clear(), `${s.trim()}
4967
+ ${n}${c2}
4968
+ ${o}${t("yellow", this.error)}
4969
+ `;
4970
+ }
4971
+ case "submit": {
4972
+ const n = i ? `${t("gray", d2)} ` : "", o = u2 ? t("dim", u2) : "";
4973
+ return `${s}${n}${o}`;
4974
+ }
4975
+ case "cancel": {
4976
+ const n = i ? `${t("gray", d2)} ` : "", o = u2 ? t(["strikethrough", "dim"], u2) : "";
4977
+ return `${s}${n}${o}${u2 && i ? `
4978
+ ${t("gray", d2)}` : ""}`;
4979
+ }
4980
+ default: {
4981
+ const n = i ? `${t("cyan", d2)} ` : "", o = i ? t("cyan", E2) : "";
4982
+ return `${s}${n}${r}
4983
+ ${o}
4984
+ `;
4985
+ }
4986
+ }
4987
+ } }).prompt();
4988
+ var St = (e) => {
4989
+ const i = e.validate;
4990
+ return Ae({ ...e, initialUserInput: e.initialValue ?? e.root ?? process.cwd(), maxItems: 5, validate(s) {
4991
+ if (!Array.isArray(s)) {
4992
+ if (!s) return "Please select a path";
4993
+ if (i) return i(s);
4994
+ }
4995
+ }, options() {
4996
+ const s = this.userInput;
4997
+ if (s === "") return [];
4998
+ try {
4999
+ let r;
5000
+ Xe(s) ? we(s).isDirectory() && (!e.directory || s.endsWith("/")) ? r = s : r = be(s) : r = be(s);
5001
+ const u2 = s.length > 1 && s.endsWith("/") ? s.slice(0, -1) : s;
5002
+ return ze(r).map((n) => {
5003
+ const o = Qe(r, n), c2 = we(o);
5004
+ return { name: n, path: o, isDirectory: c2.isDirectory() };
5005
+ }).filter(({ path: n, isDirectory: o }) => n.startsWith(u2) && (o || !e.directory)).map((n) => ({ value: n.path }));
5006
+ } catch {
5007
+ return [];
5008
+ }
5009
+ } });
5010
+ };
5011
+ var Ct = (e) => t("magenta", e);
5012
+ var fe = ({ indicator: e = "dots", onCancel: i, output: s = process.stdout, cancelMessage: r, errorMessage: u2, frames: n = ee ? ["\u25D2", "\u25D0", "\u25D3", "\u25D1"] : ["\u2022", "o", "O", "0"], delay: o = ee ? 80 : 120, signal: c2, ...a } = {}) => {
5013
+ const l = ae();
5014
+ let $2, y2, p2 = false, m = false, g = "", S2, h = performance.now();
5015
+ const f = O(s), v = a?.styleFrame ?? Ct, T2 = (_2) => {
5016
+ const A2 = _2 > 1 ? u2 ?? u.messages.error : r ?? u.messages.cancel;
5017
+ m = _2 === 1, p2 && (W2(A2, _2), m && typeof i == "function" && i());
5018
+ }, C2 = () => T2(2), b = () => T2(1), x = () => {
5019
+ process.on("uncaughtExceptionMonitor", C2), process.on("unhandledRejection", C2), process.on("SIGINT", b), process.on("SIGTERM", b), process.on("exit", T2), c2 && c2.addEventListener("abort", b);
5020
+ }, G2 = () => {
5021
+ process.removeListener("uncaughtExceptionMonitor", C2), process.removeListener("unhandledRejection", C2), process.removeListener("SIGINT", b), process.removeListener("SIGTERM", b), process.removeListener("exit", T2), c2 && c2.removeEventListener("abort", b);
5022
+ }, M2 = () => {
5023
+ if (S2 === void 0) return;
5024
+ l && s.write(`
5025
+ `);
5026
+ const _2 = wrapAnsi(S2, f, { hard: true, trim: false }).split(`
5027
+ `);
5028
+ _2.length > 1 && s.write(import_sisteransi2.cursor.up(_2.length - 1)), s.write(import_sisteransi2.cursor.to(0)), s.write(import_sisteransi2.erase.down());
5029
+ }, R2 = (_2) => _2.replace(/\.+$/, ""), j2 = (_2) => {
5030
+ const A2 = (performance.now() - _2) / 1e3, k2 = Math.floor(A2 / 60), L2 = Math.floor(A2 % 60);
5031
+ return k2 > 0 ? `[${k2}m ${L2}s]` : `[${L2}s]`;
5032
+ }, D2 = a.withGuide ?? u.withGuide, ie = (_2 = "") => {
5033
+ p2 = true, $2 = z({ output: s }), g = R2(_2), h = performance.now(), D2 && s.write(`${t("gray", d2)}
5034
+ `);
5035
+ let A2 = 0, k2 = 0;
5036
+ x(), y2 = setInterval(() => {
5037
+ if (l && g === S2) return;
5038
+ M2(), S2 = g;
5039
+ const L2 = v(n[A2]);
5040
+ let Z2;
5041
+ if (l) Z2 = `${L2} ${g}...`;
5042
+ else if (e === "timer") Z2 = `${L2} ${g} ${j2(h)}`;
5043
+ else {
5044
+ const Be = ".".repeat(Math.floor(k2)).slice(0, 3);
5045
+ Z2 = `${L2} ${g}${Be}`;
5046
+ }
5047
+ const Ne = wrapAnsi(Z2, f, { hard: true, trim: false });
5048
+ s.write(Ne), A2 = A2 + 1 < n.length ? A2 + 1 : 0, k2 = k2 < 4 ? k2 + 0.125 : 0;
5049
+ }, o);
5050
+ }, W2 = (_2 = "", A2 = 0, k2 = false) => {
5051
+ if (!p2) return;
5052
+ p2 = false, clearInterval(y2), M2();
5053
+ const L2 = A2 === 0 ? t("green", F2) : A2 === 1 ? t("red", oe) : t("red", ue);
5054
+ g = _2 ?? g, k2 || (e === "timer" ? s.write(`${L2} ${g} ${j2(h)}
5055
+ `) : s.write(`${L2} ${g}
5056
+ `)), G2(), $2();
5057
+ };
5058
+ return { start: ie, stop: (_2 = "") => W2(_2, 0), message: (_2 = "") => {
5059
+ g = R2(_2 ?? g);
5060
+ }, cancel: (_2 = "") => W2(_2, 1), error: (_2 = "") => W2(_2, 2), clear: () => W2("", 0, true), get isCancelled() {
5061
+ return m;
5062
+ } };
5063
+ };
5064
+ var Ve = { light: w2("\u2500", "-"), heavy: w2("\u2501", "="), block: w2("\u2588", "#") };
5065
+ function Tt({ style: e = "heavy", max: i = 100, size: s = 40, ...r } = {}) {
5066
+ const u2 = fe(r);
5067
+ let n = 0, o = "";
5068
+ const c2 = Math.max(1, i), a = Math.max(1, s), l = (m) => {
5069
+ switch (m) {
5070
+ case "initial":
5071
+ case "active":
5072
+ return (g) => t("magenta", g);
5073
+ case "error":
5074
+ case "cancel":
5075
+ return (g) => t("red", g);
5076
+ case "submit":
5077
+ return (g) => t("green", g);
5078
+ default:
5079
+ return (g) => t("magenta", g);
5080
+ }
5081
+ }, $2 = (m, g) => {
5082
+ const S2 = Math.floor(n / c2 * a);
5083
+ return `${l(m)(Ve[e].repeat(S2))}${t("dim", Ve[e].repeat(a - S2))} ${g}`;
5084
+ }, y2 = (m = "") => {
5085
+ o = m, u2.start($2("initial", m));
5086
+ }, p2 = (m = 1, g) => {
5087
+ n = Math.min(c2, m + n), u2.message($2("active", g ?? o)), o = g ?? o;
5088
+ };
5089
+ return { start: y2, stop: u2.stop, cancel: u2.cancel, error: u2.error, clear: u2.clear, advance: p2, isCancelled: u2.isCancelled, message: (m) => p2(0, m) };
5090
+ }
5091
+ var re = (e, i) => e.includes(`
5092
+ `) ? e.split(`
5093
+ `).map((s) => i(s)).join(`
5094
+ `) : i(e);
5095
+ var _t = (e) => {
5096
+ const i = (s, r) => {
5097
+ const u2 = s.label ?? String(s.value);
5098
+ switch (r) {
5099
+ case "disabled":
5100
+ return `${t("gray", H2)} ${re(u2, (n) => t("gray", n))}${s.hint ? ` ${t("dim", `(${s.hint ?? "disabled"})`)}` : ""}`;
5101
+ case "selected":
5102
+ return `${re(u2, (n) => t("dim", n))}`;
5103
+ case "active":
5104
+ return `${t("green", z2)} ${u2}${s.hint ? ` ${t("dim", `(${s.hint})`)}` : ""}`;
5105
+ case "cancelled":
5106
+ return `${re(u2, (n) => t(["strikethrough", "dim"], n))}`;
5107
+ default:
5108
+ return `${t("dim", H2)} ${re(u2, (n) => t("dim", n))}`;
5109
+ }
5110
+ };
5111
+ return new nt({ options: e.options, signal: e.signal, input: e.input, output: e.output, initialValue: e.initialValue, render() {
5112
+ const s = e.withGuide ?? u.withGuide, r = `${V2(this.state)} `, u2 = `${ye(this.state)} `, n = R(e.output, e.message, u2, r), o = `${s ? `${t("gray", d2)}
5113
+ ` : ""}${n}
5114
+ `;
5115
+ switch (this.state) {
5116
+ case "submit": {
5117
+ const c2 = s ? `${t("gray", d2)} ` : "", a = R(e.output, i(this.options[this.cursor], "selected"), c2);
5118
+ return `${o}${a}`;
5119
+ }
5120
+ case "cancel": {
5121
+ const c2 = s ? `${t("gray", d2)} ` : "", a = R(e.output, i(this.options[this.cursor], "cancelled"), c2);
5122
+ return `${o}${a}${s ? `
5123
+ ${t("gray", d2)}` : ""}`;
5124
+ }
5125
+ default: {
5126
+ const c2 = s ? `${t("cyan", d2)} ` : "", a = s ? t("cyan", E2) : "", l = o.split(`
5127
+ `).length, $2 = s ? 2 : 1;
5128
+ return `${o}${c2}${Y2({ output: e.output, cursor: this.cursor, options: this.options, maxItems: e.maxItems, columnPadding: c2.length, rowPadding: l + $2, style: (y2, p2) => i(y2, y2.disabled ? "disabled" : p2 ? "active" : "inactive") }).join(`
5129
+ ${c2}`)}
5130
+ ${a}
5131
+ `;
5132
+ }
5133
+ }
5134
+ } }).prompt();
5135
+ };
5136
+ var It = (e) => {
5137
+ const i = (s, r = "inactive") => {
5138
+ const u2 = s.label ?? String(s.value);
5139
+ return r === "selected" ? `${t("dim", u2)}` : r === "cancelled" ? `${t(["strikethrough", "dim"], u2)}` : r === "active" ? `${t(["bgCyan", "gray"], ` ${s.value} `)} ${u2}${s.hint ? ` ${t("dim", `(${s.hint})`)}` : ""}` : `${t(["gray", "bgWhite", "inverse"], ` ${s.value} `)} ${u2}${s.hint ? ` ${t("dim", `(${s.hint})`)}` : ""}`;
5140
+ };
5141
+ return new ot({ options: e.options, signal: e.signal, input: e.input, output: e.output, initialValue: e.initialValue, caseSensitive: e.caseSensitive, render() {
5142
+ const s = e.withGuide ?? u.withGuide, r = `${s ? `${t("gray", d2)}
5143
+ ` : ""}${V2(this.state)} ${e.message}
5144
+ `;
5145
+ switch (this.state) {
5146
+ case "submit": {
5147
+ const u2 = s ? `${t("gray", d2)} ` : "", n = this.options.find((c2) => c2.value === this.value) ?? e.options[0], o = R(e.output, i(n, "selected"), u2);
5148
+ return `${r}${o}`;
5149
+ }
5150
+ case "cancel": {
5151
+ const u2 = s ? `${t("gray", d2)} ` : "", n = R(e.output, i(this.options[0], "cancelled"), u2);
5152
+ return `${r}${n}${s ? `
5153
+ ${t("gray", d2)}` : ""}`;
5154
+ }
5155
+ default: {
5156
+ const u2 = s ? `${t("cyan", d2)} ` : "", n = s ? t("cyan", E2) : "", o = this.options.map((c2, a) => R(e.output, i(c2, a === this.cursor ? "active" : "inactive"), u2)).join(`
5157
+ `);
5158
+ return `${r}${o}
5159
+ ${n}
5160
+ `;
5161
+ }
3091
5162
  }
5163
+ } }).prompt();
5164
+ };
5165
+ var je = `${t("gray", d2)} `;
5166
+ var K2 = { message: async (e, { symbol: i = t("gray", d2) } = {}) => {
5167
+ process.stdout.write(`${t("gray", d2)}
5168
+ ${i} `);
5169
+ let s = 3;
5170
+ for await (let r of e) {
5171
+ r = r.replace(/\n/g, `
5172
+ ${je}`), r.includes(`
5173
+ `) && (s = 3 + ne(r.slice(r.lastIndexOf(`
5174
+ `))).length);
5175
+ const u2 = ne(r).length;
5176
+ s + u2 < process.stdout.columns ? (s += u2, process.stdout.write(r)) : (process.stdout.write(`
5177
+ ${je}${r.trimStart()}`), s = 3 + ne(r.trimStart()).length);
5178
+ }
5179
+ process.stdout.write(`
5180
+ `);
5181
+ }, info: (e) => K2.message(e, { symbol: t("blue", he) }), success: (e) => K2.message(e, { symbol: t("green", pe) }), step: (e) => K2.message(e, { symbol: t("green", F2) }), warn: (e) => K2.message(e, { symbol: t("yellow", me) }), warning: (e) => K2.warn(e), error: (e) => K2.message(e, { symbol: t("red", ge) }) };
5182
+ var Et = async (e, i) => {
5183
+ for (const s of e) {
5184
+ if (s.enabled === false) continue;
5185
+ const r = fe(i);
5186
+ r.start(s.title);
5187
+ const u2 = await s.task(r.message);
5188
+ r.stop(u2 || s.title);
3092
5189
  }
3093
- if (result.changed) {
3094
- console.log(`
3095
- ${GREEN2}Done!${RESET3} KeepGoing is set up for this project.
5190
+ };
5191
+ var xt = (e) => e.replace(/\x1b\[(?:\d+;)*\d*[ABCDEFGHfJKSTsu]|\x1b\[(s|u)/g, "");
5192
+ var Gt = (e) => {
5193
+ const i = e.output ?? process.stdout, s = O(i), r = t("gray", d2), u2 = e.spacing ?? 1, n = 3, o = e.retainLog === true, c2 = !ae() && Te(i);
5194
+ i.write(`${r}
5195
+ `), i.write(`${t("green", F2)} ${e.title}
3096
5196
  `);
3097
- } else {
3098
- console.log(`
3099
- Everything was already configured. No changes made.
5197
+ for (let h = 0; h < u2; h++) i.write(`${r}
5198
+ `);
5199
+ const a = [{ value: "", full: "" }];
5200
+ let l = false;
5201
+ const $2 = (h) => {
5202
+ if (a.length === 0) return;
5203
+ let f = 0;
5204
+ h && (f += u2 + 2);
5205
+ for (const v of a) {
5206
+ const { value: T2, result: C2 } = v;
5207
+ let b = C2?.message ?? T2;
5208
+ if (b.length === 0) continue;
5209
+ C2 === void 0 && v.header !== void 0 && v.header !== "" && (b += `
5210
+ ${v.header}`);
5211
+ const x = b.split(`
5212
+ `).reduce((G2, M2) => M2 === "" ? G2 + 1 : G2 + Math.ceil((M2.length + n) / s), 0);
5213
+ f += x;
5214
+ }
5215
+ f > 0 && (f += 1, i.write(import_sisteransi2.erase.lines(f)));
5216
+ }, y2 = (h, f, v) => {
5217
+ const T2 = v ? `${h.full}
5218
+ ${h.value}` : h.value;
5219
+ h.header !== void 0 && h.header !== "" && O2.message(h.header.split(`
5220
+ `).map((C2) => t("bold", C2)), { output: i, secondarySymbol: r, symbol: r, spacing: 0 }), O2.message(T2.split(`
5221
+ `).map((C2) => t("dim", C2)), { output: i, secondarySymbol: r, symbol: r, spacing: f ?? u2 });
5222
+ }, p2 = () => {
5223
+ for (const h of a) {
5224
+ const { header: f, value: v, full: T2 } = h;
5225
+ (f === void 0 || f.length === 0) && v.length === 0 || y2(h, void 0, o === true && T2.length > 0);
5226
+ }
5227
+ }, m = (h, f, v) => {
5228
+ if ($2(false), (v?.raw !== true || !l) && h.value !== "" && (h.value += `
5229
+ `), h.value += xt(f), l = v?.raw === true, e.limit !== void 0) {
5230
+ const T2 = h.value.split(`
5231
+ `), C2 = T2.length - e.limit;
5232
+ if (C2 > 0) {
5233
+ const b = T2.splice(0, C2);
5234
+ o && (h.full += (h.full === "" ? "" : `
5235
+ `) + b.join(`
5236
+ `));
5237
+ }
5238
+ h.value = T2.join(`
3100
5239
  `);
5240
+ }
5241
+ c2 && g();
5242
+ }, g = () => {
5243
+ for (const h of a) h.result ? h.result.status === "error" ? O2.error(h.result.message, { output: i, secondarySymbol: r, spacing: 0 }) : O2.success(h.result.message, { output: i, secondarySymbol: r, spacing: 0 }) : h.value !== "" && y2(h, 0);
5244
+ }, S2 = (h, f) => {
5245
+ $2(false), h.result = f, c2 && g();
5246
+ };
5247
+ return { message(h, f) {
5248
+ m(a[0], h, f);
5249
+ }, group(h) {
5250
+ const f = { header: h, value: "", full: "" };
5251
+ return a.push(f), { message(v, T2) {
5252
+ m(f, v, T2);
5253
+ }, error(v) {
5254
+ S2(f, { status: "error", message: v });
5255
+ }, success(v) {
5256
+ S2(f, { status: "success", message: v });
5257
+ } };
5258
+ }, error(h, f) {
5259
+ $2(true), O2.error(h, { output: i, secondarySymbol: r, spacing: 1 }), f?.showLog !== false && p2(), a.splice(1, a.length - 1), a[0].value = "", a[0].full = "";
5260
+ }, success(h, f) {
5261
+ $2(true), O2.success(h, { output: i, secondarySymbol: r, spacing: 1 }), f?.showLog === true && p2(), a.splice(1, a.length - 1), a[0].value = "", a[0].full = "";
5262
+ } };
5263
+ };
5264
+ var Ot = (e) => new at({ validate: e.validate, placeholder: e.placeholder, defaultValue: e.defaultValue, initialValue: e.initialValue, output: e.output, signal: e.signal, input: e.input, render() {
5265
+ const i = e?.withGuide ?? u.withGuide, s = `${`${i ? `${t("gray", d2)}
5266
+ ` : ""}${V2(this.state)} `}${e.message}
5267
+ `, r = e.placeholder ? t("inverse", e.placeholder[0]) + t("dim", e.placeholder.slice(1)) : t(["inverse", "hidden"], "_"), u2 = this.userInput ? this.userInputWithCursor : r, n = this.value ?? "";
5268
+ switch (this.state) {
5269
+ case "error": {
5270
+ const o = this.error ? ` ${t("yellow", this.error)}` : "", c2 = i ? `${t("yellow", d2)} ` : "", a = i ? t("yellow", E2) : "";
5271
+ return `${s.trim()}
5272
+ ${c2}${u2}
5273
+ ${a}${o}
5274
+ `;
5275
+ }
5276
+ case "submit": {
5277
+ const o = n ? ` ${t("dim", n)}` : "", c2 = i ? t("gray", d2) : "";
5278
+ return `${s}${c2}${o}`;
5279
+ }
5280
+ case "cancel": {
5281
+ const o = n ? ` ${t(["strikethrough", "dim"], n)}` : "", c2 = i ? t("gray", d2) : "";
5282
+ return `${s}${c2}${o}${n.trim() ? `
5283
+ ${c2}` : ""}`;
5284
+ }
5285
+ default: {
5286
+ const o = i ? `${t("cyan", d2)} ` : "", c2 = i ? t("cyan", E2) : "";
5287
+ return `${s}${o}${u2}
5288
+ ${c2}
5289
+ `;
5290
+ }
5291
+ }
5292
+ } }).prompt();
5293
+
5294
+ // src/prompt.ts
5295
+ function isCancel(value) {
5296
+ return q(value);
5297
+ }
5298
+ function cancelAndExit() {
5299
+ pt("Setup cancelled.");
5300
+ process.exit(0);
5301
+ }
5302
+
5303
+ // src/commands/setup.ts
5304
+ var execAsync = promisify2(exec2);
5305
+ var VALID_PRESETS = ["vscode", "claude", "copilot", "cursor", "windsurf", "jetbrains"];
5306
+ var PRESET_DEFAULTS = {
5307
+ vscode: { ide: ["vscode"] },
5308
+ jetbrains: { ide: ["jetbrains"] },
5309
+ claude: { tools: ["claude-code"] },
5310
+ copilot: { tools: ["copilot"] },
5311
+ cursor: { tools: ["cursor"] },
5312
+ windsurf: { tools: ["windsurf"] }
5313
+ };
5314
+ var PRESET_LABELS = {
5315
+ vscode: "VS Code",
5316
+ jetbrains: "JetBrains",
5317
+ claude: "Claude Code",
5318
+ copilot: "GitHub Copilot",
5319
+ cursor: "Cursor",
5320
+ windsurf: "Windsurf"
5321
+ };
5322
+ var JETBRAINS_PLUGIN_URL = "https://plugins.jetbrains.com/plugin/30449-keepgoing";
5323
+ var JETBRAINS_PLUGIN_ID = "com.keepgoing.plugin";
5324
+ var JETBRAINS_IDES = [
5325
+ { app: "IntelliJ IDEA.app", label: "IntelliJ IDEA Ultimate" },
5326
+ { app: "IntelliJ IDEA CE.app", label: "IntelliJ IDEA Community" },
5327
+ { app: "WebStorm.app", label: "WebStorm" },
5328
+ { app: "PyCharm.app", label: "PyCharm Professional" },
5329
+ { app: "PyCharm CE.app", label: "PyCharm Community" },
5330
+ { app: "GoLand.app", label: "GoLand" },
5331
+ { app: "PhpStorm.app", label: "PhpStorm" },
5332
+ { app: "Rider.app", label: "Rider" },
5333
+ { app: "RubyMine.app", label: "RubyMine" },
5334
+ { app: "CLion.app", label: "CLion" },
5335
+ { app: "DataGrip.app", label: "DataGrip" },
5336
+ { app: "Android Studio.app", label: "Android Studio" }
5337
+ ];
5338
+ function detectJetBrainsIdes() {
5339
+ if (process.platform !== "darwin") return [];
5340
+ return JETBRAINS_IDES.filter((ide) => {
5341
+ try {
5342
+ return fs10.statSync(path13.join("/Applications", ide.app)).isDirectory();
5343
+ } catch {
5344
+ return false;
5345
+ }
5346
+ });
5347
+ }
5348
+ async function setupCommand(options) {
5349
+ const displayPath = options.cwd.startsWith(os6.homedir()) ? "~" + options.cwd.slice(os6.homedir().length) : options.cwd;
5350
+ const presetDefaults = options.preset ? PRESET_DEFAULTS[options.preset] : void 0;
5351
+ const presetLabel = options.preset ? PRESET_LABELS[options.preset] : void 0;
5352
+ dist_exports.intro(presetLabel ? `KeepGoing Setup - ${presetLabel}` : "KeepGoing Setup Wizard");
5353
+ dist_exports.log.info(`Project: ${displayPath}`);
5354
+ if (presetLabel) {
5355
+ dist_exports.log.info(`Preset: ${presetLabel}`);
5356
+ }
5357
+ const scope = await dist_exports.select({
5358
+ message: "Setup scope",
5359
+ options: [
5360
+ { label: "This project only", hint: ".claude/settings.json", value: "project" },
5361
+ { label: "All projects (global)", hint: "~/.claude/settings.json", value: "user" }
5362
+ ]
5363
+ });
5364
+ if (isCancel(scope)) cancelAndExit();
5365
+ let tools;
5366
+ if (presetDefaults?.tools) {
5367
+ tools = presetDefaults.tools;
5368
+ dist_exports.log.step(`AI tool: ${tools.map((t2) => t2 === "claude-code" ? "Claude Code" : t2.charAt(0).toUpperCase() + t2.slice(1)).join(", ")}`);
5369
+ const addMore = await dist_exports.multiselect({
5370
+ message: "Also configure any of these?",
5371
+ options: [
5372
+ ...!tools.includes("claude-code") ? [{ label: "Claude Code", value: "claude-code" }] : [],
5373
+ ...!tools.includes("copilot") ? [{ label: "GitHub Copilot", value: "copilot" }] : [],
5374
+ ...!tools.includes("cursor") ? [{ label: "Cursor", value: "cursor" }] : [],
5375
+ ...!tools.includes("windsurf") ? [{ label: "Windsurf", value: "windsurf" }] : []
5376
+ ],
5377
+ required: false
5378
+ });
5379
+ if (!isCancel(addMore) && addMore.length > 0) {
5380
+ tools = [...tools, ...addMore];
5381
+ }
5382
+ } else {
5383
+ const toolsAnswer = await dist_exports.multiselect({
5384
+ message: "Which AI coding tools do you use?",
5385
+ options: [
5386
+ { label: "Claude Code", value: "claude-code" },
5387
+ { label: "GitHub Copilot", value: "copilot" },
5388
+ { label: "Cursor", value: "cursor" },
5389
+ { label: "Windsurf", value: "windsurf" }
5390
+ ],
5391
+ required: true
5392
+ });
5393
+ if (isCancel(toolsAnswer)) cancelAndExit();
5394
+ tools = toolsAnswer;
5395
+ }
5396
+ let claudePlugin = false;
5397
+ if (tools.includes("claude-code")) {
5398
+ const pluginAnswer = await dist_exports.select({
5399
+ message: "How do you want to set up Claude Code?",
5400
+ initialValue: "plugin",
5401
+ options: [
5402
+ { label: "Plugin (recommended)", hint: "auto-hooks, skills, one command to install", value: "plugin" },
5403
+ { label: "Manual", hint: "write hooks + MCP registration yourself", value: "manual" }
5404
+ ]
5405
+ });
5406
+ if (isCancel(pluginAnswer)) cancelAndExit();
5407
+ claudePlugin = pluginAnswer === "plugin";
5408
+ }
5409
+ let ide;
5410
+ if (presetDefaults?.ide) {
5411
+ ide = presetDefaults.ide;
5412
+ dist_exports.log.step(`IDE: ${ide.map((i) => i === "vscode" ? "VS Code" : i === "jetbrains" ? "JetBrains" : "Terminal").join(", ")}`);
5413
+ const addMoreIde = await dist_exports.multiselect({
5414
+ message: "Also configure any of these?",
5415
+ options: [
5416
+ ...!ide.includes("vscode") ? [{ label: "VS Code", value: "vscode" }] : [],
5417
+ ...!ide.includes("jetbrains") ? [{ label: "JetBrains", hint: "IntelliJ, WebStorm, PyCharm, etc.", value: "jetbrains" }] : [],
5418
+ ...!ide.includes("terminal") ? [{ label: "Terminal only / other", value: "terminal" }] : []
5419
+ ],
5420
+ required: false
5421
+ });
5422
+ if (!isCancel(addMoreIde) && addMoreIde.length > 0) {
5423
+ ide = [...ide, ...addMoreIde];
5424
+ }
5425
+ } else {
5426
+ const ideAnswer = await dist_exports.multiselect({
5427
+ message: "Which IDE(s) do you use?",
5428
+ options: [
5429
+ { label: "VS Code", value: "vscode" },
5430
+ { label: "JetBrains", hint: "IntelliJ, WebStorm, PyCharm, etc.", value: "jetbrains" },
5431
+ { label: "Terminal only / other", value: "terminal" }
5432
+ ],
5433
+ required: true
5434
+ });
5435
+ if (isCancel(ideAnswer)) cancelAndExit();
5436
+ ide = ideAnswer;
5437
+ }
5438
+ const shellInfo = detectShellInfo();
5439
+ let installShellHook = false;
5440
+ if (shellInfo) {
5441
+ const hookAnswer = await dist_exports.confirm({
5442
+ message: `Install shell hook for ${shellInfo.shell}?`,
5443
+ initialValue: true,
5444
+ active: `Yes (adds to ${shellInfo.rcFile})`,
5445
+ inactive: "No"
5446
+ });
5447
+ if (isCancel(hookAnswer)) cancelAndExit();
5448
+ installShellHook = hookAnswer;
5449
+ } else {
5450
+ dist_exports.log.warn("Shell hook skipped (could not detect shell)");
5451
+ }
5452
+ const hasLicense = await dist_exports.confirm({
5453
+ message: "Do you have a Pro license key?",
5454
+ initialValue: false
5455
+ });
5456
+ if (isCancel(hasLicense)) cancelAndExit();
5457
+ const s = dist_exports.spinner();
5458
+ s.start("Configuring...");
5459
+ const results = [];
5460
+ let licensed = false;
5461
+ function classifySetupMessage(msg) {
5462
+ if (msg.startsWith("Warning")) return "warn";
5463
+ if (msg.includes("skipped") || msg.includes("Already")) return "message";
5464
+ return "success";
5465
+ }
5466
+ if (tools.includes("claude-code")) {
5467
+ if (claudePlugin) {
5468
+ const setupResult = setupProject({
5469
+ workspacePath: options.cwd,
5470
+ scope,
5471
+ sessionHooks: false
5472
+ });
5473
+ for (const msg of setupResult.messages) {
5474
+ results.push({ level: classifySetupMessage(msg), text: `Claude Code: ${msg}` });
5475
+ }
5476
+ results.push({ level: "info", text: "Claude Code: Install the plugin in Claude Code by running:\n 1. /plugin marketplace add keepgoing-dev/claude-plugin\n 2. /plugin install keepgoing@keepgoing-dev" });
5477
+ } else {
5478
+ const setupResult = setupProject({
5479
+ workspacePath: options.cwd,
5480
+ scope,
5481
+ sessionHooks: true
5482
+ });
5483
+ for (const msg of setupResult.messages) {
5484
+ results.push({ level: classifySetupMessage(msg), text: `Claude Code: ${msg}` });
5485
+ }
5486
+ if (isClaudeCodeInstalled()) {
5487
+ s.message("Registering Claude Code MCP server...");
5488
+ const mcpResult = await registerClaudeCodeMcp(options.cwd);
5489
+ results.push({
5490
+ level: mcpResult.action === "created" ? "success" : "message",
5491
+ text: `Claude Code: ${mcpResult.message}`
5492
+ });
5493
+ } else {
5494
+ results.push({ level: "info", text: "Claude Code: CLI not found. Install from https://claude.ai/code, then run:\n claude mcp add keepgoing -- npx -y @keepgoingdev/mcp-server" });
5495
+ }
5496
+ }
5497
+ }
5498
+ if (tools.includes("copilot")) {
5499
+ const mcpResult = registerCopilotMcp(options.cwd);
5500
+ results.push({ level: mcpResult.action === "created" ? "success" : "message", text: `Copilot: ${mcpResult.message}` });
5501
+ const instrResult = writeCopilotInstructions(options.cwd);
5502
+ results.push({ level: instrResult.action === "created" ? "success" : "message", text: `Copilot: ${instrResult.message}` });
5503
+ }
5504
+ if (tools.includes("cursor")) {
5505
+ const result = registerCursorMcp();
5506
+ results.push({ level: result.action === "created" ? "success" : "message", text: `Cursor: ${result.message}` });
5507
+ }
5508
+ if (tools.includes("windsurf")) {
5509
+ const result = registerWindsurfMcp();
5510
+ results.push({ level: result.action === "created" ? "success" : "message", text: `Windsurf: ${result.message}` });
5511
+ }
5512
+ if (installShellHook) {
5513
+ const hookResult = performHookInstall();
5514
+ results.push({ level: hookResult.message.includes("already") ? "message" : "success", text: `Shell: ${hookResult.message}` });
5515
+ const gitignoreResult = performGlobalGitignore();
5516
+ results.push({ level: gitignoreResult.message.includes("already") ? "message" : "success", text: `Gitignore: ${gitignoreResult.message}` });
5517
+ const postCommitResult = performPostCommitHook();
5518
+ results.push({ level: postCommitResult.message.includes("already") ? "message" : "success", text: `Post-commit: ${postCommitResult.message}` });
5519
+ }
5520
+ s.stop("Configuration complete");
5521
+ const DIM5 = "\x1B[2m";
5522
+ const RESET5 = "\x1B[0m";
5523
+ for (const r of results) {
5524
+ if (r.level === "message") {
5525
+ dist_exports.log.message(`${DIM5}${r.text}${RESET5}`);
5526
+ } else {
5527
+ dist_exports.log[r.level](r.text);
5528
+ }
5529
+ }
5530
+ if (ide.includes("vscode")) {
5531
+ const installVscode = await dist_exports.confirm({
5532
+ message: "Install VS Code extension now?",
5533
+ initialValue: true,
5534
+ active: "Yes",
5535
+ inactive: "No, I'll do it later"
5536
+ });
5537
+ if (!isCancel(installVscode) && installVscode) {
5538
+ try {
5539
+ execSync3("code --install-extension keepgoing-dev.keepgoing", { stdio: "pipe" });
5540
+ dist_exports.log.success("VS Code: KeepGoing extension installed");
5541
+ } catch {
5542
+ dist_exports.log.warn("VS Code: Could not install automatically. Run this manually:\n code --install-extension keepgoing-dev.keepgoing");
5543
+ }
5544
+ } else {
5545
+ dist_exports.log.info("VS Code: Install later by running:\n code --install-extension keepgoing-dev.keepgoing");
5546
+ }
5547
+ }
5548
+ if (ide.includes("jetbrains")) {
5549
+ const detectedIdes = detectJetBrainsIdes();
5550
+ if (detectedIdes.length === 0) {
5551
+ dist_exports.log.info(`JetBrains: Install the KeepGoing plugin
5552
+ ${JETBRAINS_PLUGIN_URL}`);
5553
+ } else {
5554
+ const installJetbrains = await dist_exports.confirm({
5555
+ message: "Install JetBrains plugin now?",
5556
+ initialValue: true,
5557
+ active: "Yes",
5558
+ inactive: "No, I'll do it later"
5559
+ });
5560
+ if (isCancel(installJetbrains) || !installJetbrains) {
5561
+ dist_exports.log.info(`JetBrains: Install later from:
5562
+ ${JETBRAINS_PLUGIN_URL}`);
5563
+ } else {
5564
+ let selectedApps;
5565
+ if (detectedIdes.length === 1) {
5566
+ selectedApps = [detectedIdes[0].app];
5567
+ } else {
5568
+ const picked = await dist_exports.multiselect({
5569
+ message: "Which JetBrains IDEs should get the plugin?",
5570
+ options: detectedIdes.map((ide2) => ({ label: ide2.label, value: ide2.app })),
5571
+ required: true
5572
+ });
5573
+ if (isCancel(picked)) {
5574
+ dist_exports.log.info(`JetBrains: Install later from:
5575
+ ${JETBRAINS_PLUGIN_URL}`);
5576
+ selectedApps = [];
5577
+ } else {
5578
+ selectedApps = picked;
5579
+ }
5580
+ }
5581
+ if (selectedApps.length > 0) {
5582
+ const runningApps = selectedApps.filter((app) => {
5583
+ try {
5584
+ const result = execSync3(`pgrep -f "${app.replace(".app", "")}"`, { stdio: "pipe" }).toString();
5585
+ return result.trim().length > 0;
5586
+ } catch {
5587
+ return false;
5588
+ }
5589
+ });
5590
+ let proceed = true;
5591
+ if (runningApps.length > 0) {
5592
+ const runningLabels = runningApps.map((app) => JETBRAINS_IDES.find((i) => i.app === app)?.label ?? app).join(", ");
5593
+ dist_exports.log.warn(`Please close ${runningLabels} before continuing.`);
5594
+ const ready = await dist_exports.confirm({
5595
+ message: "IDE(s) closed and ready to install?",
5596
+ initialValue: true
5597
+ });
5598
+ if (isCancel(ready) || !ready) {
5599
+ dist_exports.log.info(`JetBrains: Install later from:
5600
+ ${JETBRAINS_PLUGIN_URL}`);
5601
+ proceed = false;
5602
+ }
5603
+ }
5604
+ if (proceed) {
5605
+ for (const app of selectedApps) {
5606
+ const label = JETBRAINS_IDES.find((i) => i.app === app)?.label ?? app;
5607
+ const is = dist_exports.spinner();
5608
+ is.start(`Installing plugin in ${label}...`);
5609
+ try {
5610
+ const binName = execSync3(
5611
+ `/usr/libexec/PlistBuddy -c "Print :CFBundleExecutable" "/Applications/${app}/Contents/Info.plist"`,
5612
+ { stdio: "pipe" }
5613
+ ).toString().trim();
5614
+ const { stdout, stderr } = await execAsync(
5615
+ `"/Applications/${app}/Contents/MacOS/${binName}" installPlugins ${JETBRAINS_PLUGIN_ID}`,
5616
+ { timeout: 6e4 }
5617
+ );
5618
+ const combined = (stdout || "") + (stderr || "");
5619
+ if (combined.includes("unknown plugins")) {
5620
+ is.stop(`${label}: Plugin not compatible with this IDE version`);
5621
+ dist_exports.log.warn(`Update your IDE or install manually:
5622
+ ${JETBRAINS_PLUGIN_URL}`);
5623
+ } else {
5624
+ is.stop(`${label}: KeepGoing plugin installed`);
5625
+ }
5626
+ } catch (err) {
5627
+ const combined = (err.stdout || "") + (err.stderr || "");
5628
+ if (combined.includes("unknown plugins")) {
5629
+ is.stop(`${label}: Plugin not compatible with this IDE version`);
5630
+ dist_exports.log.warn(`Update your IDE or install manually:
5631
+ ${JETBRAINS_PLUGIN_URL}`);
5632
+ } else {
5633
+ is.stop(`${label}: Could not install automatically`);
5634
+ dist_exports.log.warn(`Install from:
5635
+ ${JETBRAINS_PLUGIN_URL}`);
5636
+ }
5637
+ }
5638
+ }
5639
+ }
5640
+ }
5641
+ }
5642
+ }
5643
+ }
5644
+ if (hasLicense) {
5645
+ const key = await dist_exports.text({
5646
+ message: "Enter your license key",
5647
+ placeholder: "Decision Detection or Session Awareness key",
5648
+ validate: (val) => {
5649
+ if (!val.trim()) return "License key is required";
5650
+ }
5651
+ });
5652
+ if (!isCancel(key) && key) {
5653
+ const store = readLicenseStore();
5654
+ const existing = store.licenses.find(
5655
+ (l) => l.status === "active" && l.licenseKey === key
5656
+ );
5657
+ if (existing) {
5658
+ const label = getVariantLabel(existing.variantId);
5659
+ dist_exports.log.success(`${label} is already active.`);
5660
+ licensed = true;
5661
+ } else {
5662
+ const ls = dist_exports.spinner();
5663
+ ls.start("Activating license...");
5664
+ const result = await activateLicense(key, getDeviceId());
5665
+ if (result.valid) {
5666
+ const now = (/* @__PURE__ */ new Date()).toISOString();
5667
+ addLicenseEntry({
5668
+ licenseKey: result.licenseKey || key,
5669
+ instanceId: result.instanceId || getDeviceId(),
5670
+ status: "active",
5671
+ lastValidatedAt: now,
5672
+ activatedAt: now,
5673
+ variantId: result.variantId,
5674
+ customerName: result.customerName,
5675
+ productName: result.productName,
5676
+ variantName: result.variantName
5677
+ });
5678
+ const label = getVariantLabel(result.variantId);
5679
+ const who = result.customerName ? ` Welcome, ${result.customerName}!` : "";
5680
+ ls.stop(`${label} activated.${who}`);
5681
+ licensed = true;
5682
+ } else {
5683
+ ls.stop("License activation failed");
5684
+ dist_exports.log.warn(`${result.error ?? "unknown error"}
5685
+ Check your key at https://keepgoing.dev/add-ons`);
5686
+ }
5687
+ }
5688
+ if (licensed) {
5689
+ dist_exports.log.info("Have another add-on key? Run `keepgoing activate <key>` anytime.");
5690
+ }
5691
+ }
3101
5692
  }
5693
+ const profile = {
5694
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
5695
+ tools,
5696
+ ide,
5697
+ scope,
5698
+ shellHook: installShellHook,
5699
+ claudePlugin,
5700
+ licensed
5701
+ };
5702
+ const keepgoingDir = path13.join(os6.homedir(), ".keepgoing");
5703
+ fs10.mkdirSync(keepgoingDir, { recursive: true });
5704
+ fs10.writeFileSync(
5705
+ path13.join(keepgoingDir, "setup-profile.json"),
5706
+ JSON.stringify(profile, null, 2) + "\n",
5707
+ "utf-8"
5708
+ );
5709
+ dist_exports.log.success("Setup profile saved to ~/.keepgoing/setup-profile.json");
5710
+ dist_exports.outro("Done! Run `keepgoing status` to verify.");
3102
5711
  }
3103
5712
 
3104
5713
  // src/commands/momentum.ts
@@ -3188,21 +5797,21 @@ async function decisionsCommand(opts) {
3188
5797
  function parseDate(input) {
3189
5798
  const lower = input.toLowerCase().trim();
3190
5799
  if (lower === "today") {
3191
- const d2 = /* @__PURE__ */ new Date();
3192
- d2.setHours(0, 0, 0, 0);
3193
- return d2;
5800
+ const d4 = /* @__PURE__ */ new Date();
5801
+ d4.setHours(0, 0, 0, 0);
5802
+ return d4;
3194
5803
  }
3195
5804
  if (lower === "yesterday") {
3196
- const d2 = /* @__PURE__ */ new Date();
3197
- d2.setDate(d2.getDate() - 1);
3198
- d2.setHours(0, 0, 0, 0);
3199
- return d2;
5805
+ const d4 = /* @__PURE__ */ new Date();
5806
+ d4.setDate(d4.getDate() - 1);
5807
+ d4.setHours(0, 0, 0, 0);
5808
+ return d4;
3200
5809
  }
3201
5810
  if (lower === "last week") {
3202
- const d2 = /* @__PURE__ */ new Date();
3203
- d2.setDate(d2.getDate() - 7);
3204
- d2.setHours(0, 0, 0, 0);
3205
- return d2;
5811
+ const d4 = /* @__PURE__ */ new Date();
5812
+ d4.setDate(d4.getDate() - 7);
5813
+ d4.setHours(0, 0, 0, 0);
5814
+ return d4;
3206
5815
  }
3207
5816
  const agoMatch = lower.match(/^(\d+)\s+(second|minute|hour|day|week|month)s?\s+ago$/);
3208
5817
  if (agoMatch) {
@@ -3219,8 +5828,8 @@ function parseDate(input) {
3219
5828
  };
3220
5829
  return new Date(now.getTime() - n * (msPerUnit[unit] ?? 0));
3221
5830
  }
3222
- const d = new Date(input);
3223
- if (!isNaN(d.getTime())) return d;
5831
+ const d3 = new Date(input);
5832
+ if (!isNaN(d3.getTime())) return d3;
3224
5833
  return void 0;
3225
5834
  }
3226
5835
  function filterSessions(sessions, opts) {
@@ -3278,25 +5887,25 @@ function filterDecisions(decisions, opts) {
3278
5887
  }
3279
5888
  if (sinceDate) {
3280
5889
  const ts = sinceDate.getTime();
3281
- result = result.filter((d) => new Date(d.timestamp).getTime() >= ts);
5890
+ result = result.filter((d3) => new Date(d3.timestamp).getTime() >= ts);
3282
5891
  }
3283
5892
  if (opts.until) {
3284
5893
  const untilDate = parseDate(opts.until);
3285
5894
  if (untilDate) {
3286
5895
  const ts = untilDate.getTime();
3287
- result = result.filter((d) => new Date(d.timestamp).getTime() <= ts);
5896
+ result = result.filter((d3) => new Date(d3.timestamp).getTime() <= ts);
3288
5897
  }
3289
5898
  }
3290
5899
  if (opts.follow) {
3291
5900
  const file = opts.follow.toLowerCase();
3292
5901
  result = result.filter(
3293
- (d) => d.filesChanged?.some((f) => f.toLowerCase().includes(file))
5902
+ (d3) => d3.filesChanged?.some((f) => f.toLowerCase().includes(file))
3294
5903
  );
3295
5904
  }
3296
5905
  if (opts.search) {
3297
5906
  const term = opts.search.toLowerCase();
3298
- result = result.filter((d) => {
3299
- const haystack = [d.commitMessage, d.rationale].filter(Boolean).join(" ").toLowerCase();
5907
+ result = result.filter((d3) => {
5908
+ const haystack = [d3.commitMessage, d3.rationale].filter(Boolean).join(" ").toLowerCase();
3300
5909
  return haystack.includes(term);
3301
5910
  });
3302
5911
  }
@@ -3304,8 +5913,8 @@ function filterDecisions(decisions, opts) {
3304
5913
  }
3305
5914
 
3306
5915
  // src/commands/log.ts
3307
- var RESET4 = "\x1B[0m";
3308
- var DIM4 = "\x1B[2m";
5916
+ var RESET3 = "\x1B[0m";
5917
+ var DIM3 = "\x1B[2m";
3309
5918
  function logSessions(reader, opts) {
3310
5919
  const { effectiveBranch } = reader.resolveBranchScope(opts.branch || void 0);
3311
5920
  let sessions = reader.getSessions();
@@ -3316,7 +5925,7 @@ function logSessions(reader, opts) {
3316
5925
  sessions = filterSessions(sessions, opts);
3317
5926
  const totalFiltered = sessions.length;
3318
5927
  if (totalFiltered === 0) {
3319
- console.log(`${DIM4}No checkpoints match the given filters.${RESET4}`);
5928
+ console.log(`${DIM3}No checkpoints match the given filters.${RESET3}`);
3320
5929
  return;
3321
5930
  }
3322
5931
  const displayed = sessions.slice(0, opts.count);
@@ -3340,7 +5949,7 @@ function logSessions(reader, opts) {
3340
5949
  }
3341
5950
  }
3342
5951
  if (totalFiltered > opts.count) {
3343
- console.log(`${DIM4}(showing ${displayed.length} of ${totalFiltered} checkpoints)${RESET4}`);
5952
+ console.log(`${DIM3}(showing ${displayed.length} of ${totalFiltered} checkpoints)${RESET3}`);
3344
5953
  }
3345
5954
  }
3346
5955
  function renderGrouped(sessions, showStat) {
@@ -3373,13 +5982,13 @@ async function logDecisions(reader, opts) {
3373
5982
  const { effectiveBranch } = reader.resolveBranchScope(opts.branch || void 0);
3374
5983
  let decisions = reader.getDecisions();
3375
5984
  if (effectiveBranch) {
3376
- decisions = decisions.filter((d) => d.gitBranch === effectiveBranch);
5985
+ decisions = decisions.filter((d3) => d3.gitBranch === effectiveBranch);
3377
5986
  }
3378
5987
  decisions.reverse();
3379
5988
  decisions = filterDecisions(decisions, opts);
3380
5989
  const totalFiltered = decisions.length;
3381
5990
  if (totalFiltered === 0) {
3382
- console.log(`${DIM4}No decisions match the given filters.${RESET4}`);
5991
+ console.log(`${DIM3}No decisions match the given filters.${RESET3}`);
3383
5992
  return;
3384
5993
  }
3385
5994
  const displayed = decisions.slice(0, opts.count);
@@ -3392,16 +6001,16 @@ async function logDecisions(reader, opts) {
3392
6001
  return;
3393
6002
  }
3394
6003
  if (opts.oneline) {
3395
- for (const d of displayed) {
3396
- renderLogDecisionOneline(d);
6004
+ for (const d3 of displayed) {
6005
+ renderLogDecisionOneline(d3);
3397
6006
  }
3398
6007
  } else {
3399
- for (const d of displayed) {
3400
- renderLogDecision(d, opts.stat);
6008
+ for (const d3 of displayed) {
6009
+ renderLogDecision(d3, opts.stat);
3401
6010
  }
3402
6011
  }
3403
6012
  if (totalFiltered > opts.count) {
3404
- console.log(`${DIM4}(showing ${displayed.length} of ${totalFiltered} decisions)${RESET4}`);
6013
+ console.log(`${DIM3}(showing ${displayed.length} of ${totalFiltered} decisions)${RESET3}`);
3405
6014
  }
3406
6015
  }
3407
6016
  async function logCommand(opts) {
@@ -3418,19 +6027,19 @@ async function logCommand(opts) {
3418
6027
  }
3419
6028
 
3420
6029
  // src/platform.ts
3421
- import { execSync as execSync2, spawnSync } from "child_process";
6030
+ import { execSync as execSync4, spawnSync } from "child_process";
3422
6031
  function copyToClipboard(text) {
3423
6032
  try {
3424
6033
  const platform = process.platform;
3425
6034
  if (platform === "darwin") {
3426
- execSync2("pbcopy", { input: text, stdio: ["pipe", "ignore", "ignore"] });
6035
+ execSync4("pbcopy", { input: text, stdio: ["pipe", "ignore", "ignore"] });
3427
6036
  } else if (platform === "win32") {
3428
- execSync2("clip.exe", { input: text, stdio: ["pipe", "ignore", "ignore"] });
6037
+ execSync4("clip.exe", { input: text, stdio: ["pipe", "ignore", "ignore"] });
3429
6038
  } else {
3430
6039
  try {
3431
- execSync2("xclip -selection clipboard", { input: text, stdio: ["pipe", "ignore", "ignore"] });
6040
+ execSync4("xclip -selection clipboard", { input: text, stdio: ["pipe", "ignore", "ignore"] });
3432
6041
  } catch {
3433
- execSync2("xsel --clipboard --input", { input: text, stdio: ["pipe", "ignore", "ignore"] });
6042
+ execSync4("xsel --clipboard --input", { input: text, stdio: ["pipe", "ignore", "ignore"] });
3434
6043
  }
3435
6044
  }
3436
6045
  return true;
@@ -3542,6 +6151,154 @@ function hotCommand(opts) {
3542
6151
  }
3543
6152
  }
3544
6153
 
6154
+ // src/commands/update.ts
6155
+ import { execSync as execSync5 } from "child_process";
6156
+
6157
+ // src/updateCheck.ts
6158
+ import { spawn } from "child_process";
6159
+ import { readFileSync, existsSync } from "fs";
6160
+ import path14 from "path";
6161
+ import os7 from "os";
6162
+ var CLI_VERSION = "1.5.0";
6163
+ var NPM_REGISTRY_URL = "https://registry.npmjs.org/@keepgoingdev/cli/latest";
6164
+ var FETCH_TIMEOUT_MS = 5e3;
6165
+ var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
6166
+ var CACHE_DIR = path14.join(os7.homedir(), ".keepgoing");
6167
+ var CACHE_PATH = path14.join(CACHE_DIR, "update-check.json");
6168
+ function isNewerVersion(current, latest) {
6169
+ const cur = current.split(".").map(Number);
6170
+ const lat = latest.split(".").map(Number);
6171
+ for (let i = 0; i < 3; i++) {
6172
+ if ((lat[i] ?? 0) > (cur[i] ?? 0)) return true;
6173
+ if ((lat[i] ?? 0) < (cur[i] ?? 0)) return false;
6174
+ }
6175
+ return false;
6176
+ }
6177
+ function getCachedUpdateInfo() {
6178
+ try {
6179
+ if (!existsSync(CACHE_PATH)) return null;
6180
+ const raw = readFileSync(CACHE_PATH, "utf-8");
6181
+ const cache = JSON.parse(raw);
6182
+ if (!cache.latest || !cache.checkedAt) return null;
6183
+ const age = Date.now() - new Date(cache.checkedAt).getTime();
6184
+ if (age > CHECK_INTERVAL_MS || cache.current !== CLI_VERSION) return null;
6185
+ return {
6186
+ current: CLI_VERSION,
6187
+ latest: cache.latest,
6188
+ updateAvailable: isNewerVersion(CLI_VERSION, cache.latest)
6189
+ };
6190
+ } catch {
6191
+ return null;
6192
+ }
6193
+ }
6194
+ function spawnBackgroundCheck() {
6195
+ try {
6196
+ if (existsSync(CACHE_PATH)) {
6197
+ const raw = readFileSync(CACHE_PATH, "utf-8");
6198
+ const cache = JSON.parse(raw);
6199
+ const age = Date.now() - new Date(cache.checkedAt).getTime();
6200
+ if (age < CHECK_INTERVAL_MS && cache.current === CLI_VERSION) return;
6201
+ }
6202
+ } catch {
6203
+ }
6204
+ const script = `
6205
+ const https = require('https');
6206
+ const fs = require('fs');
6207
+ const path = require('path');
6208
+ const os = require('os');
6209
+
6210
+ const url = ${JSON.stringify(NPM_REGISTRY_URL)};
6211
+ const cacheDir = path.join(os.homedir(), '.keepgoing');
6212
+ const cachePath = path.join(cacheDir, 'update-check.json');
6213
+ const currentVersion = ${JSON.stringify(CLI_VERSION)};
6214
+
6215
+ const req = https.get(url, { timeout: ${FETCH_TIMEOUT_MS} }, (res) => {
6216
+ let data = '';
6217
+ res.on('data', (chunk) => { data += chunk; });
6218
+ res.on('end', () => {
6219
+ try {
6220
+ const latest = JSON.parse(data).version;
6221
+ if (!latest) process.exit(0);
6222
+ if (!fs.existsSync(cacheDir)) fs.mkdirSync(cacheDir, { recursive: true });
6223
+ fs.writeFileSync(cachePath, JSON.stringify({
6224
+ latest,
6225
+ current: currentVersion,
6226
+ checkedAt: new Date().toISOString(),
6227
+ }));
6228
+ } catch {}
6229
+ process.exit(0);
6230
+ });
6231
+ });
6232
+ req.on('error', () => process.exit(0));
6233
+ req.on('timeout', () => { req.destroy(); process.exit(0); });
6234
+ `;
6235
+ const child = spawn(process.execPath, ["-e", script], {
6236
+ detached: true,
6237
+ stdio: "ignore",
6238
+ env: { ...process.env }
6239
+ });
6240
+ child.unref();
6241
+ }
6242
+
6243
+ // src/commands/update.ts
6244
+ var RESET4 = "\x1B[0m";
6245
+ var BOLD3 = "\x1B[1m";
6246
+ var DIM4 = "\x1B[2m";
6247
+ var GREEN3 = "\x1B[32m";
6248
+ var YELLOW3 = "\x1B[33m";
6249
+ var CLI_VERSION2 = "1.5.0";
6250
+ async function updateCommand() {
6251
+ console.log(`
6252
+ ${BOLD3}KeepGoing CLI${RESET4} ${DIM4}v${CLI_VERSION2}${RESET4}
6253
+ `);
6254
+ console.log(`${DIM4}Checking for updates...${RESET4}`);
6255
+ let latest;
6256
+ try {
6257
+ latest = execSync5("npm view @keepgoingdev/cli version", {
6258
+ encoding: "utf-8",
6259
+ timeout: 1e4,
6260
+ stdio: ["pipe", "pipe", "pipe"]
6261
+ }).trim();
6262
+ } catch {
6263
+ console.error(`${YELLOW3}Could not reach the npm registry. Check your network connection.${RESET4}
6264
+ `);
6265
+ process.exit(1);
6266
+ }
6267
+ if (!latest) {
6268
+ console.error(`${YELLOW3}Could not determine the latest version.${RESET4}
6269
+ `);
6270
+ process.exit(1);
6271
+ }
6272
+ const current = CLI_VERSION2;
6273
+ const updateAvailable = isNewerVersion(current, latest);
6274
+ if (!updateAvailable) {
6275
+ console.log(`${GREEN3}Already up to date.${RESET4}
6276
+ `);
6277
+ return;
6278
+ }
6279
+ console.log(`${YELLOW3}Update available:${RESET4} ${DIM4}${current}${RESET4} -> ${BOLD3}${latest}${RESET4}
6280
+ `);
6281
+ console.log(`${DIM4}Installing @keepgoingdev/cli@${latest}...${RESET4}
6282
+ `);
6283
+ try {
6284
+ execSync5(`npm install -g @keepgoingdev/cli@${latest}`, {
6285
+ encoding: "utf-8",
6286
+ timeout: 6e4,
6287
+ stdio: "inherit"
6288
+ });
6289
+ console.log(`
6290
+ ${GREEN3}Updated to v${latest}${RESET4}
6291
+ `);
6292
+ } catch {
6293
+ console.error(`
6294
+ ${YELLOW3}Update failed.${RESET4} Try manually:
6295
+ `);
6296
+ console.error(` ${BOLD3}npm install -g @keepgoingdev/cli@latest${RESET4}
6297
+ `);
6298
+ process.exit(1);
6299
+ }
6300
+ }
6301
+
3545
6302
  // src/index.ts
3546
6303
  var HELP_TEXT = `
3547
6304
  keepgoing: resume side projects without the mental friction
@@ -3549,7 +6306,8 @@ keepgoing: resume side projects without the mental friction
3549
6306
  Usage: keepgoing <command> [options]
3550
6307
 
3551
6308
  Commands:
3552
- init Set up KeepGoing hooks and CLAUDE.md in this project
6309
+ setup [preset] Interactive setup wizard (recommended for first-time setup)
6310
+ init Set up KeepGoing hooks and CLAUDE.md (non-interactive)
3553
6311
  status Show the last checkpoint for this project
3554
6312
  momentum Show your current developer momentum
3555
6313
  briefing Get a re-entry briefing for this project
@@ -3560,6 +6318,7 @@ Commands:
3560
6318
  continue Export context for use in another AI tool
3561
6319
  save Save a checkpoint (auto-generates from git)
3562
6320
  hook Manage the shell hook (zsh, bash, fish)
6321
+ update Update the CLI to the latest version
3563
6322
  activate <key> Activate a Pro license on this device
3564
6323
  deactivate Deactivate the Pro license from this device
3565
6324
 
@@ -3583,13 +6342,28 @@ Options:
3583
6342
  --cwd <path> Override the working directory
3584
6343
  `,
3585
6344
  setup: `
3586
- keepgoing init: Set up KeepGoing hooks and CLAUDE.md in this project
6345
+ keepgoing setup: Interactive setup wizard
3587
6346
 
3588
- Usage: keepgoing init [options]
6347
+ Walks you through configuring KeepGoing for your AI tools, IDE, and shell.
6348
+ Configures Claude Code, GitHub Copilot, Cursor, and/or Windsurf in one go.
6349
+
6350
+ Usage: keepgoing setup [preset] [options]
6351
+
6352
+ Presets:
6353
+ claude Pre-select Claude Code
6354
+ copilot Pre-select GitHub Copilot
6355
+ cursor Pre-select Cursor
6356
+ windsurf Pre-select Windsurf
6357
+ vscode Pre-select VS Code IDE
6358
+ jetbrains Pre-select JetBrains IDE
3589
6359
 
3590
6360
  Options:
3591
- --scope <s> Scope: "project" (default) or "user" (global)
3592
6361
  --cwd <path> Override the working directory
6362
+
6363
+ Examples:
6364
+ keepgoing setup Full interactive wizard
6365
+ keepgoing setup claude Start with Claude Code pre-selected
6366
+ keepgoing setup vscode Start with VS Code pre-selected
3593
6367
  `,
3594
6368
  status: `
3595
6369
  keepgoing status: Show the last checkpoint for this project
@@ -3709,6 +6483,13 @@ Usage: keepgoing activate <key>
3709
6483
 
3710
6484
  Example:
3711
6485
  keepgoing activate XXXX-XXXX-XXXX-XXXX
6486
+ `,
6487
+ update: `
6488
+ keepgoing update: Update the CLI to the latest version
6489
+
6490
+ Usage: keepgoing update
6491
+
6492
+ Checks the npm registry for a newer version and installs it globally.
3712
6493
  `,
3713
6494
  deactivate: `
3714
6495
  keepgoing deactivate: Deactivate the Pro license from this device
@@ -3908,9 +6689,21 @@ async function main() {
3908
6689
  }
3909
6690
  switch (command) {
3910
6691
  case "init":
3911
- case "setup":
3912
6692
  initCommand({ cwd, scope });
3913
6693
  break;
6694
+ case "setup": {
6695
+ let preset;
6696
+ if (subcommand) {
6697
+ if (VALID_PRESETS.includes(subcommand)) {
6698
+ preset = subcommand;
6699
+ } else {
6700
+ console.error(`Unknown preset: "${subcommand}". Valid presets: ${VALID_PRESETS.join(", ")}`);
6701
+ process.exit(1);
6702
+ }
6703
+ }
6704
+ await setupCommand({ cwd, preset });
6705
+ break;
6706
+ }
3914
6707
  case "status":
3915
6708
  await statusCommand({ cwd, json, quiet });
3916
6709
  break;
@@ -3978,8 +6771,11 @@ async function main() {
3978
6771
  console.log(COMMAND_HELP.hook);
3979
6772
  }
3980
6773
  break;
6774
+ case "update":
6775
+ await updateCommand();
6776
+ break;
3981
6777
  case "version":
3982
- console.log(`keepgoing v${"1.3.3"}`);
6778
+ console.log(`keepgoing v${"1.5.0"}`);
3983
6779
  break;
3984
6780
  case "activate":
3985
6781
  await activateCommand({ licenseKey: subcommand });
@@ -3994,6 +6790,20 @@ async function main() {
3994
6790
  console.error(`Unknown command: "${command}". Run "keepgoing --help" for usage.`);
3995
6791
  process.exit(1);
3996
6792
  }
6793
+ if (command && command !== "update" && command !== "version" && command !== "help" && !json && !quiet && !parsed.help) {
6794
+ showUpdateHint();
6795
+ }
6796
+ }
6797
+ function showUpdateHint() {
6798
+ const cached = getCachedUpdateInfo();
6799
+ if (cached?.updateAvailable) {
6800
+ const DIM5 = "\x1B[2m";
6801
+ const BOLD4 = "\x1B[1m";
6802
+ const RESET5 = "\x1B[0m";
6803
+ console.log(`
6804
+ ${DIM5}Update available: ${cached.current} -> ${cached.latest}. Run:${RESET5} ${BOLD4}keepgoing update${RESET5}`);
6805
+ }
6806
+ spawnBackgroundCheck();
3997
6807
  }
3998
6808
  main().catch((err) => {
3999
6809
  console.error(err instanceof Error ? err.message : String(err));