@keepgoingdev/cli 1.3.3 → 1.4.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 +3010 -279
  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) {
@@ -2436,14 +2804,14 @@ function renderEnrichedBriefingQuiet(briefing) {
2436
2804
  // src/updateCheck.ts
2437
2805
  import { spawn } from "child_process";
2438
2806
  import { readFileSync, existsSync } from "fs";
2439
- import path10 from "path";
2440
- import os4 from "os";
2441
- var CLI_VERSION = "1.3.3";
2807
+ import path11 from "path";
2808
+ import os5 from "os";
2809
+ var CLI_VERSION = "1.4.0";
2442
2810
  var NPM_REGISTRY_URL = "https://registry.npmjs.org/@keepgoingdev/cli/latest";
2443
2811
  var FETCH_TIMEOUT_MS = 5e3;
2444
2812
  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");
2813
+ var CACHE_DIR = path11.join(os5.homedir(), ".keepgoing");
2814
+ var CACHE_PATH = path11.join(CACHE_DIR, "update-check.json");
2447
2815
  function isNewerVersion(current, latest) {
2448
2816
  const cur = current.split(".").map(Number);
2449
2817
  const lat = latest.split(".").map(Number);
@@ -2558,7 +2926,7 @@ async function statusCommand(opts) {
2558
2926
  }
2559
2927
 
2560
2928
  // src/commands/save.ts
2561
- import path11 from "path";
2929
+ import path12 from "path";
2562
2930
  async function saveCommand(opts) {
2563
2931
  const { cwd, message, nextStepOverride, json, quiet, force } = opts;
2564
2932
  const isManual = !!message;
@@ -2587,9 +2955,9 @@ async function saveCommand(opts) {
2587
2955
  sessionStartTime: lastSession?.timestamp ?? now,
2588
2956
  lastActivityTime: now
2589
2957
  });
2590
- const summary = message ?? buildSmartSummary(events) ?? `Worked on ${touchedFiles.slice(0, 5).map((f) => path11.basename(f)).join(", ")}`;
2958
+ const summary = message ?? buildSmartSummary(events) ?? `Worked on ${touchedFiles.slice(0, 5).map((f) => path12.basename(f)).join(", ")}`;
2591
2959
  const nextStep = nextStepOverride ?? buildSmartNextStep(events);
2592
- const projectName = path11.basename(resolveStorageRoot(cwd));
2960
+ const projectName = path12.basename(resolveStorageRoot(cwd));
2593
2961
  const sessionId = generateSessionId({
2594
2962
  workspaceRoot: cwd,
2595
2963
  branch: gitBranch ?? void 0,
@@ -2622,17 +2990,17 @@ async function saveCommand(opts) {
2622
2990
  }
2623
2991
 
2624
2992
  // src/commands/hook.ts
2625
- import fs8 from "fs";
2626
- import path12 from "path";
2627
- import os5 from "os";
2628
- import { execSync } from "child_process";
2993
+ import fs9 from "fs";
2994
+ import path13 from "path";
2995
+ import os6 from "os";
2996
+ import { execSync as execSync2 } from "child_process";
2629
2997
  var HOOK_MARKER_START = "# keepgoing-hook-start";
2630
2998
  var HOOK_MARKER_END = "# keepgoing-hook-end";
2631
2999
  var POST_COMMIT_MARKER_START = "# keepgoing-post-commit-start";
2632
3000
  var POST_COMMIT_MARKER_END = "# keepgoing-post-commit-end";
2633
- var KEEPGOING_HOOKS_DIR = path12.join(os5.homedir(), ".keepgoing", "hooks");
2634
- var POST_COMMIT_HOOK_PATH = path12.join(KEEPGOING_HOOKS_DIR, "post-commit");
2635
- var KEEPGOING_MANAGED_MARKER = path12.join(KEEPGOING_HOOKS_DIR, ".keepgoing-managed");
3001
+ var KEEPGOING_HOOKS_DIR = path13.join(os6.homedir(), ".keepgoing", "hooks");
3002
+ var POST_COMMIT_HOOK_PATH = path13.join(KEEPGOING_HOOKS_DIR, "post-commit");
3003
+ var KEEPGOING_MANAGED_MARKER = path13.join(KEEPGOING_HOOKS_DIR, ".keepgoing-managed");
2636
3004
  var POST_COMMIT_HOOK = `#!/bin/sh
2637
3005
  ${POST_COMMIT_MARKER_START}
2638
3006
  # Runs after every git commit. Detects high-signal decisions.
@@ -2672,14 +3040,14 @@ if command -v keepgoing >/dev/null 2>&1
2672
3040
  end
2673
3041
  end
2674
3042
  ${HOOK_MARKER_END}`;
2675
- function detectShellRcFile(shellOverride) {
2676
- const home = os5.homedir();
3043
+ function detectShellInfo(shellOverride) {
3044
+ const home = os6.homedir();
2677
3045
  let shell;
2678
3046
  if (shellOverride) {
2679
3047
  shell = shellOverride.toLowerCase();
2680
3048
  } else {
2681
3049
  try {
2682
- const parentComm = execSync(`ps -o comm= -p ${process.ppid}`, {
3050
+ const parentComm = execSync2(`ps -o comm= -p ${process.ppid}`, {
2683
3051
  encoding: "utf-8",
2684
3052
  stdio: ["pipe", "pipe", "pipe"]
2685
3053
  }).trim();
@@ -2696,80 +3064,84 @@ function detectShellRcFile(shellOverride) {
2696
3064
  }
2697
3065
  }
2698
3066
  if (shell === "zsh") {
2699
- return { shell: "zsh", rcFile: path12.join(home, ".zshrc") };
3067
+ return { shell: "zsh", rcFile: path13.join(home, ".zshrc") };
2700
3068
  }
2701
3069
  if (shell === "bash") {
2702
- return { shell: "bash", rcFile: path12.join(home, ".bashrc") };
3070
+ return { shell: "bash", rcFile: path13.join(home, ".bashrc") };
2703
3071
  }
2704
3072
  if (shell === "fish") {
2705
- const xdgConfig = process.env["XDG_CONFIG_HOME"] || path12.join(home, ".config");
2706
- return { shell: "fish", rcFile: path12.join(xdgConfig, "fish", "config.fish") };
3073
+ const xdgConfig = process.env["XDG_CONFIG_HOME"] || path13.join(home, ".config");
3074
+ return { shell: "fish", rcFile: path13.join(xdgConfig, "fish", "config.fish") };
2707
3075
  }
2708
3076
  return void 0;
2709
3077
  }
3078
+ function performHookInstall(shellOverride) {
3079
+ const detected = detectShellInfo(shellOverride);
3080
+ if (!detected) {
3081
+ return { success: false, message: 'Could not detect your shell. Set $SHELL to "zsh", "bash", or "fish" and try again.' };
3082
+ }
3083
+ const { shell, rcFile } = detected;
3084
+ const hookBlock = shell === "zsh" ? ZSH_HOOK : shell === "fish" ? FISH_HOOK : BASH_HOOK;
3085
+ let existing = "";
3086
+ try {
3087
+ existing = fs9.readFileSync(rcFile, "utf-8");
3088
+ } catch {
3089
+ }
3090
+ if (existing.includes(HOOK_MARKER_START)) {
3091
+ return { success: true, message: `Shell hook already installed in ${rcFile}` };
3092
+ }
3093
+ fs9.appendFileSync(rcFile, `
3094
+ ${hookBlock}
3095
+ `, "utf-8");
3096
+ return { success: true, message: `Shell hook installed in ${rcFile}` };
3097
+ }
2710
3098
  function resolveGlobalGitignorePath() {
2711
3099
  try {
2712
- const configured = execSync("git config --global core.excludesfile", {
3100
+ const configured = execSync2("git config --global core.excludesfile", {
2713
3101
  encoding: "utf-8",
2714
3102
  stdio: ["pipe", "pipe", "pipe"]
2715
3103
  }).trim();
2716
3104
  if (configured) {
2717
- return configured.startsWith("~") ? path12.join(os5.homedir(), configured.slice(1)) : configured;
3105
+ return configured.startsWith("~") ? path13.join(os6.homedir(), configured.slice(1)) : configured;
2718
3106
  }
2719
3107
  } catch {
2720
3108
  }
2721
- return path12.join(os5.homedir(), ".gitignore_global");
3109
+ return path13.join(os6.homedir(), ".gitignore_global");
2722
3110
  }
2723
- function installGlobalGitignore() {
3111
+ function performGlobalGitignore() {
2724
3112
  const ignorePath = resolveGlobalGitignorePath();
2725
3113
  let existing = "";
2726
3114
  try {
2727
- existing = fs8.readFileSync(ignorePath, "utf-8");
3115
+ existing = fs9.readFileSync(ignorePath, "utf-8");
2728
3116
  } catch {
2729
3117
  }
2730
3118
  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}`);
3119
+ return { success: true, message: `Global gitignore: .keepgoing already present in ${ignorePath}` };
2737
3120
  }
3121
+ const suffix = existing.length > 0 && !existing.endsWith("\n") ? "\n" : "";
3122
+ fs9.appendFileSync(ignorePath, `${suffix}.keepgoing
3123
+ `, "utf-8");
2738
3124
  try {
2739
- execSync("git config --global core.excludesfile", {
3125
+ execSync2("git config --global core.excludesfile", {
2740
3126
  encoding: "utf-8",
2741
3127
  stdio: ["pipe", "pipe", "pipe"]
2742
3128
  }).trim();
2743
3129
  } catch {
2744
- execSync(`git config --global core.excludesfile "${ignorePath}"`, {
3130
+ execSync2(`git config --global core.excludesfile "${ignorePath}"`, {
2745
3131
  stdio: ["pipe", "pipe", "pipe"]
2746
3132
  });
2747
3133
  }
3134
+ return { success: true, message: `Global gitignore: .keepgoing added to ${ignorePath}` };
2748
3135
  }
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");
3136
+ function performPostCommitHook() {
3137
+ fs9.mkdirSync(KEEPGOING_HOOKS_DIR, { recursive: true });
3138
+ if (fs9.existsSync(POST_COMMIT_HOOK_PATH)) {
3139
+ const existing = fs9.readFileSync(POST_COMMIT_HOOK_PATH, "utf-8");
2768
3140
  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}
3141
+ return { success: true, message: `Git post-commit hook: already installed at ${POST_COMMIT_HOOK_PATH}` };
3142
+ }
3143
+ const suffix = existing.endsWith("\n") ? "" : "\n";
3144
+ const block = `${suffix}
2773
3145
  ${POST_COMMIT_MARKER_START}
2774
3146
  # Runs after every git commit. Detects high-signal decisions.
2775
3147
  if command -v keepgoing-mcp-server >/dev/null 2>&1; then
@@ -2777,40 +3149,45 @@ if command -v keepgoing-mcp-server >/dev/null 2>&1; then
2777
3149
  fi
2778
3150
  ${POST_COMMIT_MARKER_END}
2779
3151
  `;
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}`);
3152
+ fs9.appendFileSync(POST_COMMIT_HOOK_PATH, block, "utf-8");
3153
+ fs9.chmodSync(POST_COMMIT_HOOK_PATH, 493);
3154
+ return { success: true, message: `Git post-commit hook: appended to existing ${POST_COMMIT_HOOK_PATH}` };
2786
3155
  }
2787
- fs8.chmodSync(POST_COMMIT_HOOK_PATH, 493);
3156
+ fs9.writeFileSync(POST_COMMIT_HOOK_PATH, POST_COMMIT_HOOK, { mode: 493 });
3157
+ fs9.chmodSync(POST_COMMIT_HOOK_PATH, 493);
2788
3158
  let currentHooksPath;
2789
3159
  try {
2790
- currentHooksPath = execSync("git config --global core.hooksPath", {
3160
+ currentHooksPath = execSync2("git config --global core.hooksPath", {
2791
3161
  encoding: "utf-8",
2792
3162
  stdio: ["pipe", "pipe", "pipe"]
2793
3163
  }).trim();
2794
3164
  } catch {
2795
3165
  }
2796
3166
  if (currentHooksPath === KEEPGOING_HOOKS_DIR) {
2797
- console.log(`Git hooks path: already set to ${KEEPGOING_HOOKS_DIR}`);
3167
+ return { success: true, message: `Git post-commit hook: installed at ${POST_COMMIT_HOOK_PATH}` };
2798
3168
  } 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.`);
3169
+ return { success: true, message: `Git post-commit hook: saved to ${POST_COMMIT_HOOK_PATH} (core.hooksPath is ${currentHooksPath})` };
3170
+ }
3171
+ return { success: true, message: `Git post-commit hook: installed at ${POST_COMMIT_HOOK_PATH}` };
3172
+ }
3173
+ function uninstallGlobalGitignore() {
3174
+ const ignorePath = resolveGlobalGitignorePath();
3175
+ let existing = "";
3176
+ try {
3177
+ existing = fs9.readFileSync(ignorePath, "utf-8");
3178
+ } catch {
3179
+ return;
3180
+ }
3181
+ const lines = existing.split("\n");
3182
+ const filtered = lines.filter((line) => line.trim() !== ".keepgoing");
3183
+ if (filtered.length !== lines.length) {
3184
+ fs9.writeFileSync(ignorePath, filtered.join("\n"), "utf-8");
3185
+ console.log(`Global gitignore: .keepgoing removed from ${ignorePath}`);
2809
3186
  }
2810
3187
  }
2811
3188
  function uninstallPostCommitHook() {
2812
- if (fs8.existsSync(POST_COMMIT_HOOK_PATH)) {
2813
- const existing = fs8.readFileSync(POST_COMMIT_HOOK_PATH, "utf-8");
3189
+ if (fs9.existsSync(POST_COMMIT_HOOK_PATH)) {
3190
+ const existing = fs9.readFileSync(POST_COMMIT_HOOK_PATH, "utf-8");
2814
3191
  if (existing.includes(POST_COMMIT_MARKER_START)) {
2815
3192
  const pattern = new RegExp(
2816
3193
  `
@@ -2820,65 +3197,55 @@ function uninstallPostCommitHook() {
2820
3197
  );
2821
3198
  const updated = existing.replace(pattern, "").trim();
2822
3199
  if (!updated || updated === "#!/bin/sh") {
2823
- fs8.unlinkSync(POST_COMMIT_HOOK_PATH);
3200
+ fs9.unlinkSync(POST_COMMIT_HOOK_PATH);
2824
3201
  console.log(`Git post-commit hook: removed ${POST_COMMIT_HOOK_PATH}`);
2825
3202
  } else {
2826
- fs8.writeFileSync(POST_COMMIT_HOOK_PATH, updated + "\n", "utf-8");
3203
+ fs9.writeFileSync(POST_COMMIT_HOOK_PATH, updated + "\n", "utf-8");
2827
3204
  console.log(`Git post-commit hook: KeepGoing block removed from ${POST_COMMIT_HOOK_PATH}`);
2828
3205
  }
2829
3206
  }
2830
3207
  }
2831
3208
  try {
2832
- const currentHooksPath = execSync("git config --global core.hooksPath", {
3209
+ const currentHooksPath = execSync2("git config --global core.hooksPath", {
2833
3210
  encoding: "utf-8",
2834
3211
  stdio: ["pipe", "pipe", "pipe"]
2835
3212
  }).trim();
2836
3213
  if (currentHooksPath === KEEPGOING_HOOKS_DIR) {
2837
- execSync("git config --global --unset core.hooksPath", {
3214
+ execSync2("git config --global --unset core.hooksPath", {
2838
3215
  stdio: ["pipe", "pipe", "pipe"]
2839
3216
  });
2840
3217
  console.log("Git hooks path: global core.hooksPath unset");
2841
3218
  }
2842
3219
  } catch {
2843
3220
  }
2844
- if (fs8.existsSync(KEEPGOING_MANAGED_MARKER)) {
2845
- fs8.unlinkSync(KEEPGOING_MANAGED_MARKER);
3221
+ if (fs9.existsSync(KEEPGOING_MANAGED_MARKER)) {
3222
+ fs9.unlinkSync(KEEPGOING_MANAGED_MARKER);
2846
3223
  }
2847
3224
  }
2848
3225
  function hookInstallCommand(shellOverride) {
2849
- const detected = detectShellRcFile(shellOverride);
3226
+ const detected = detectShellInfo(shellOverride);
2850
3227
  if (!detected) {
2851
3228
  console.error(
2852
3229
  'Could not detect your shell. Set $SHELL to "zsh", "bash", or "fish" and try again.'
2853
3230
  );
2854
3231
  process.exit(1);
2855
3232
  }
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(`
3233
+ const { rcFile } = detected;
3234
+ const hookResult = performHookInstall(shellOverride);
3235
+ console.log(hookResult.message);
3236
+ const gitignoreResult = performGlobalGitignore();
3237
+ console.log(gitignoreResult.message);
3238
+ const postCommitResult = performPostCommitHook();
3239
+ console.log(postCommitResult.message);
3240
+ if (hookResult.message.includes("installed in")) {
3241
+ console.log(`
2876
3242
  Reload your shell config to activate it:
2877
3243
  `);
2878
- console.log(` source ${rcFile}`);
3244
+ console.log(` source ${rcFile}`);
3245
+ }
2879
3246
  }
2880
3247
  function hookUninstallCommand(shellOverride) {
2881
- const detected = detectShellRcFile(shellOverride);
3248
+ const detected = detectShellInfo(shellOverride);
2882
3249
  if (!detected) {
2883
3250
  console.error(
2884
3251
  'Could not detect your shell. Set $SHELL to "zsh", "bash", or "fish" and try again.'
@@ -2888,7 +3255,7 @@ function hookUninstallCommand(shellOverride) {
2888
3255
  const { rcFile } = detected;
2889
3256
  let existing = "";
2890
3257
  try {
2891
- existing = fs8.readFileSync(rcFile, "utf-8");
3258
+ existing = fs9.readFileSync(rcFile, "utf-8");
2892
3259
  } catch {
2893
3260
  console.log(`${rcFile} not found \u2014 nothing to remove.`);
2894
3261
  return;
@@ -2904,7 +3271,7 @@ function hookUninstallCommand(shellOverride) {
2904
3271
  "g"
2905
3272
  );
2906
3273
  const updated = existing.replace(pattern, "").replace(/\n{3,}/g, "\n\n");
2907
- fs8.writeFileSync(rcFile, updated, "utf-8");
3274
+ fs9.writeFileSync(rcFile, updated, "utf-8");
2908
3275
  console.log(`KeepGoing hook removed from ${rcFile}.`);
2909
3276
  uninstallGlobalGitignore();
2910
3277
  uninstallPostCommitHook();
@@ -3101,44 +3468,2380 @@ Everything was already configured. No changes made.
3101
3468
  }
3102
3469
  }
3103
3470
 
3104
- // src/commands/momentum.ts
3105
- async function momentumCommand(opts) {
3106
- const reader = new KeepGoingReader(opts.cwd);
3107
- if (!reader.exists()) {
3108
- if (!opts.quiet) {
3109
- renderNoData();
3471
+ // src/commands/setup.ts
3472
+ import fs10 from "fs";
3473
+ import path14 from "path";
3474
+ import os7 from "os";
3475
+ import { execSync as execSync3, exec as exec2 } from "child_process";
3476
+ import { promisify as promisify2 } from "util";
3477
+
3478
+ // ../../node_modules/@clack/prompts/dist/index.mjs
3479
+ var dist_exports = {};
3480
+ __export(dist_exports, {
3481
+ S_BAR: () => d2,
3482
+ S_BAR_END: () => E2,
3483
+ S_BAR_END_RIGHT: () => Ee,
3484
+ S_BAR_H: () => se,
3485
+ S_BAR_START: () => le,
3486
+ S_BAR_START_RIGHT: () => Ie,
3487
+ S_CHECKBOX_ACTIVE: () => te,
3488
+ S_CHECKBOX_INACTIVE: () => J2,
3489
+ S_CHECKBOX_SELECTED: () => U,
3490
+ S_CONNECT_LEFT: () => Ge,
3491
+ S_CORNER_BOTTOM_LEFT: () => de,
3492
+ S_CORNER_BOTTOM_RIGHT: () => $e,
3493
+ S_CORNER_TOP_LEFT: () => Oe,
3494
+ S_CORNER_TOP_RIGHT: () => ce,
3495
+ S_ERROR: () => ge,
3496
+ S_INFO: () => he,
3497
+ S_PASSWORD_MASK: () => xe,
3498
+ S_RADIO_ACTIVE: () => z2,
3499
+ S_RADIO_INACTIVE: () => H2,
3500
+ S_STEP_ACTIVE: () => _e,
3501
+ S_STEP_CANCEL: () => oe,
3502
+ S_STEP_ERROR: () => ue,
3503
+ S_STEP_SUBMIT: () => F2,
3504
+ S_SUCCESS: () => pe,
3505
+ S_WARN: () => me,
3506
+ autocomplete: () => Ae,
3507
+ autocompleteMultiselect: () => st2,
3508
+ box: () => at2,
3509
+ cancel: () => pt,
3510
+ confirm: () => ot2,
3511
+ date: () => ut,
3512
+ group: () => dt,
3513
+ groupMultiselect: () => ht,
3514
+ intro: () => mt,
3515
+ isCI: () => ae,
3516
+ isCancel: () => q,
3517
+ isTTY: () => Te,
3518
+ limitOptions: () => Y2,
3519
+ log: () => O2,
3520
+ multiselect: () => yt,
3521
+ note: () => wt,
3522
+ outro: () => gt,
3523
+ password: () => bt,
3524
+ path: () => St,
3525
+ progress: () => Tt,
3526
+ select: () => _t,
3527
+ selectKey: () => It,
3528
+ settings: () => u,
3529
+ spinner: () => fe,
3530
+ stream: () => K2,
3531
+ symbol: () => V2,
3532
+ symbolBar: () => ye,
3533
+ taskLog: () => Gt,
3534
+ tasks: () => Et,
3535
+ text: () => Ot,
3536
+ unicode: () => ee,
3537
+ unicodeOr: () => w2,
3538
+ updateSettings: () => K
3539
+ });
3540
+
3541
+ // ../../node_modules/@clack/core/dist/index.mjs
3542
+ import { styleText as y } from "util";
3543
+ import { stdout as S, stdin as $ } from "process";
3544
+ import * as _ from "readline";
3545
+ import P from "readline";
3546
+
3547
+ // ../../node_modules/fast-string-truncated-width/dist/utils.js
3548
+ var isAmbiguous = (x) => {
3549
+ 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;
3550
+ };
3551
+ var isFullWidth = (x) => {
3552
+ return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
3553
+ };
3554
+ var isWide = (x) => {
3555
+ 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;
3556
+ };
3557
+
3558
+ // ../../node_modules/fast-string-truncated-width/dist/index.js
3559
+ var ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/y;
3560
+ var CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
3561
+ var TAB_RE = /\t{1,1000}/y;
3562
+ 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");
3563
+ var LATIN_RE = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
3564
+ var MODIFIER_RE = new RegExp("\\p{M}+", "gu");
3565
+ var NO_TRUNCATION = { limit: Infinity, ellipsis: "" };
3566
+ var getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {}) => {
3567
+ const LIMIT = truncationOptions.limit ?? Infinity;
3568
+ const ELLIPSIS = truncationOptions.ellipsis ?? "";
3569
+ const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION, widthOptions).width : 0);
3570
+ const ANSI_WIDTH = widthOptions.ansiWidth ?? 0;
3571
+ const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;
3572
+ const TAB_WIDTH = widthOptions.tabWidth ?? 8;
3573
+ const AMBIGUOUS_WIDTH = widthOptions.ambiguousWidth ?? 1;
3574
+ const EMOJI_WIDTH = widthOptions.emojiWidth ?? 2;
3575
+ const FULL_WIDTH_WIDTH = widthOptions.fullWidthWidth ?? 2;
3576
+ const REGULAR_WIDTH = widthOptions.regularWidth ?? 1;
3577
+ const WIDE_WIDTH = widthOptions.wideWidth ?? 2;
3578
+ let indexPrev = 0;
3579
+ let index = 0;
3580
+ let length = input.length;
3581
+ let lengthExtra = 0;
3582
+ let truncationEnabled = false;
3583
+ let truncationIndex = length;
3584
+ let truncationLimit = Math.max(0, LIMIT - ELLIPSIS_WIDTH);
3585
+ let unmatchedStart = 0;
3586
+ let unmatchedEnd = 0;
3587
+ let width = 0;
3588
+ let widthExtra = 0;
3589
+ outer: while (true) {
3590
+ if (unmatchedEnd > unmatchedStart || index >= length && index > indexPrev) {
3591
+ const unmatched = input.slice(unmatchedStart, unmatchedEnd) || input.slice(indexPrev, index);
3592
+ lengthExtra = 0;
3593
+ for (const char of unmatched.replaceAll(MODIFIER_RE, "")) {
3594
+ const codePoint = char.codePointAt(0) || 0;
3595
+ if (isFullWidth(codePoint)) {
3596
+ widthExtra = FULL_WIDTH_WIDTH;
3597
+ } else if (isWide(codePoint)) {
3598
+ widthExtra = WIDE_WIDTH;
3599
+ } else if (AMBIGUOUS_WIDTH !== REGULAR_WIDTH && isAmbiguous(codePoint)) {
3600
+ widthExtra = AMBIGUOUS_WIDTH;
3601
+ } else {
3602
+ widthExtra = REGULAR_WIDTH;
3603
+ }
3604
+ if (width + widthExtra > truncationLimit) {
3605
+ truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);
3606
+ }
3607
+ if (width + widthExtra > LIMIT) {
3608
+ truncationEnabled = true;
3609
+ break outer;
3610
+ }
3611
+ lengthExtra += char.length;
3612
+ width += widthExtra;
3613
+ }
3614
+ unmatchedStart = unmatchedEnd = 0;
3110
3615
  }
3111
- return;
3616
+ if (index >= length)
3617
+ break;
3618
+ LATIN_RE.lastIndex = index;
3619
+ if (LATIN_RE.test(input)) {
3620
+ lengthExtra = LATIN_RE.lastIndex - index;
3621
+ widthExtra = lengthExtra * REGULAR_WIDTH;
3622
+ if (width + widthExtra > truncationLimit) {
3623
+ truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / REGULAR_WIDTH));
3624
+ }
3625
+ if (width + widthExtra > LIMIT) {
3626
+ truncationEnabled = true;
3627
+ break;
3628
+ }
3629
+ width += widthExtra;
3630
+ unmatchedStart = indexPrev;
3631
+ unmatchedEnd = index;
3632
+ index = indexPrev = LATIN_RE.lastIndex;
3633
+ continue;
3634
+ }
3635
+ ANSI_RE.lastIndex = index;
3636
+ if (ANSI_RE.test(input)) {
3637
+ if (width + ANSI_WIDTH > truncationLimit) {
3638
+ truncationIndex = Math.min(truncationIndex, index);
3639
+ }
3640
+ if (width + ANSI_WIDTH > LIMIT) {
3641
+ truncationEnabled = true;
3642
+ break;
3643
+ }
3644
+ width += ANSI_WIDTH;
3645
+ unmatchedStart = indexPrev;
3646
+ unmatchedEnd = index;
3647
+ index = indexPrev = ANSI_RE.lastIndex;
3648
+ continue;
3649
+ }
3650
+ CONTROL_RE.lastIndex = index;
3651
+ if (CONTROL_RE.test(input)) {
3652
+ lengthExtra = CONTROL_RE.lastIndex - index;
3653
+ widthExtra = lengthExtra * CONTROL_WIDTH;
3654
+ if (width + widthExtra > truncationLimit) {
3655
+ truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / CONTROL_WIDTH));
3656
+ }
3657
+ if (width + widthExtra > LIMIT) {
3658
+ truncationEnabled = true;
3659
+ break;
3660
+ }
3661
+ width += widthExtra;
3662
+ unmatchedStart = indexPrev;
3663
+ unmatchedEnd = index;
3664
+ index = indexPrev = CONTROL_RE.lastIndex;
3665
+ continue;
3666
+ }
3667
+ TAB_RE.lastIndex = index;
3668
+ if (TAB_RE.test(input)) {
3669
+ lengthExtra = TAB_RE.lastIndex - index;
3670
+ widthExtra = lengthExtra * TAB_WIDTH;
3671
+ if (width + widthExtra > truncationLimit) {
3672
+ truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / TAB_WIDTH));
3673
+ }
3674
+ if (width + widthExtra > LIMIT) {
3675
+ truncationEnabled = true;
3676
+ break;
3677
+ }
3678
+ width += widthExtra;
3679
+ unmatchedStart = indexPrev;
3680
+ unmatchedEnd = index;
3681
+ index = indexPrev = TAB_RE.lastIndex;
3682
+ continue;
3683
+ }
3684
+ EMOJI_RE.lastIndex = index;
3685
+ if (EMOJI_RE.test(input)) {
3686
+ if (width + EMOJI_WIDTH > truncationLimit) {
3687
+ truncationIndex = Math.min(truncationIndex, index);
3688
+ }
3689
+ if (width + EMOJI_WIDTH > LIMIT) {
3690
+ truncationEnabled = true;
3691
+ break;
3692
+ }
3693
+ width += EMOJI_WIDTH;
3694
+ unmatchedStart = indexPrev;
3695
+ unmatchedEnd = index;
3696
+ index = indexPrev = EMOJI_RE.lastIndex;
3697
+ continue;
3698
+ }
3699
+ index += 1;
3112
3700
  }
3113
- const { session: lastSession, isFallback } = reader.getScopedLastSession();
3114
- const currentBranch = reader.getCurrentBranch();
3115
- if (!lastSession) {
3116
- if (!opts.quiet) {
3117
- console.log("KeepGoing is set up but no session checkpoints exist yet.");
3701
+ return {
3702
+ width: truncationEnabled ? truncationLimit : width,
3703
+ index: truncationEnabled ? truncationIndex : length,
3704
+ truncated: truncationEnabled,
3705
+ ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH
3706
+ };
3707
+ };
3708
+ var dist_default = getStringTruncatedWidth;
3709
+
3710
+ // ../../node_modules/fast-string-width/dist/index.js
3711
+ var NO_TRUNCATION2 = {
3712
+ limit: Infinity,
3713
+ ellipsis: "",
3714
+ ellipsisWidth: 0
3715
+ };
3716
+ var fastStringWidth = (input, options = {}) => {
3717
+ return dist_default(input, NO_TRUNCATION2, options).width;
3718
+ };
3719
+ var dist_default2 = fastStringWidth;
3720
+
3721
+ // ../../node_modules/fast-wrap-ansi/lib/main.js
3722
+ var ESC = "\x1B";
3723
+ var CSI = "\x9B";
3724
+ var END_CODE = 39;
3725
+ var ANSI_ESCAPE_BELL = "\x07";
3726
+ var ANSI_CSI = "[";
3727
+ var ANSI_OSC = "]";
3728
+ var ANSI_SGR_TERMINATOR = "m";
3729
+ var ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
3730
+ var GROUP_REGEX = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`, "y");
3731
+ var getClosingCode = (openingCode) => {
3732
+ if (openingCode >= 30 && openingCode <= 37)
3733
+ return 39;
3734
+ if (openingCode >= 90 && openingCode <= 97)
3735
+ return 39;
3736
+ if (openingCode >= 40 && openingCode <= 47)
3737
+ return 49;
3738
+ if (openingCode >= 100 && openingCode <= 107)
3739
+ return 49;
3740
+ if (openingCode === 1 || openingCode === 2)
3741
+ return 22;
3742
+ if (openingCode === 3)
3743
+ return 23;
3744
+ if (openingCode === 4)
3745
+ return 24;
3746
+ if (openingCode === 7)
3747
+ return 27;
3748
+ if (openingCode === 8)
3749
+ return 28;
3750
+ if (openingCode === 9)
3751
+ return 29;
3752
+ if (openingCode === 0)
3753
+ return 0;
3754
+ return void 0;
3755
+ };
3756
+ var wrapAnsiCode = (code) => `${ESC}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
3757
+ var wrapAnsiHyperlink = (url) => `${ESC}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`;
3758
+ var wrapWord = (rows, word, columns) => {
3759
+ const characters = word[Symbol.iterator]();
3760
+ let isInsideEscape = false;
3761
+ let isInsideLinkEscape = false;
3762
+ let lastRow = rows.at(-1);
3763
+ let visible = lastRow === void 0 ? 0 : dist_default2(lastRow);
3764
+ let currentCharacter = characters.next();
3765
+ let nextCharacter = characters.next();
3766
+ let rawCharacterIndex = 0;
3767
+ while (!currentCharacter.done) {
3768
+ const character = currentCharacter.value;
3769
+ const characterLength = dist_default2(character);
3770
+ if (visible + characterLength <= columns) {
3771
+ rows[rows.length - 1] += character;
3772
+ } else {
3773
+ rows.push(character);
3774
+ visible = 0;
3775
+ }
3776
+ if (character === ESC || character === CSI) {
3777
+ isInsideEscape = true;
3778
+ isInsideLinkEscape = word.startsWith(ANSI_ESCAPE_LINK, rawCharacterIndex + 1);
3779
+ }
3780
+ if (isInsideEscape) {
3781
+ if (isInsideLinkEscape) {
3782
+ if (character === ANSI_ESCAPE_BELL) {
3783
+ isInsideEscape = false;
3784
+ isInsideLinkEscape = false;
3785
+ }
3786
+ } else if (character === ANSI_SGR_TERMINATOR) {
3787
+ isInsideEscape = false;
3788
+ }
3789
+ } else {
3790
+ visible += characterLength;
3791
+ if (visible === columns && !nextCharacter.done) {
3792
+ rows.push("");
3793
+ visible = 0;
3794
+ }
3118
3795
  }
3119
- return;
3796
+ currentCharacter = nextCharacter;
3797
+ nextCharacter = characters.next();
3798
+ rawCharacterIndex += character.length;
3120
3799
  }
3121
- const state = reader.getState();
3122
- const branchChanged = lastSession.gitBranch && currentBranch && lastSession.gitBranch !== currentBranch;
3123
- if (opts.json) {
3124
- console.log(JSON.stringify({
3125
- lastCheckpoint: lastSession.timestamp,
3126
- summary: lastSession.summary,
3127
- nextStep: lastSession.nextStep,
3128
- blocker: lastSession.blocker || null,
3129
- projectIntent: lastSession.projectIntent || null,
3130
- branch: currentBranch || null,
3131
- branchChanged: branchChanged ? lastSession.gitBranch : null,
3132
- touchedFiles: lastSession.touchedFiles,
3133
- derivedFocus: state?.derivedCurrentFocus || null,
3134
- isWorktree: reader.isWorktree,
3135
- isFallback
3136
- }, null, 2));
3137
- return;
3800
+ lastRow = rows.at(-1);
3801
+ if (!visible && lastRow !== void 0 && lastRow.length && rows.length > 1) {
3802
+ rows[rows.length - 2] += rows.pop();
3138
3803
  }
3139
- if (opts.quiet) {
3140
- renderMomentumQuiet(lastSession);
3141
- return;
3804
+ };
3805
+ var stringVisibleTrimSpacesRight = (string) => {
3806
+ const words = string.split(" ");
3807
+ let last = words.length;
3808
+ while (last) {
3809
+ if (dist_default2(words[last - 1])) {
3810
+ break;
3811
+ }
3812
+ last--;
3813
+ }
3814
+ if (last === words.length) {
3815
+ return string;
3816
+ }
3817
+ return words.slice(0, last).join(" ") + words.slice(last).join("");
3818
+ };
3819
+ var exec = (string, columns, options = {}) => {
3820
+ if (options.trim !== false && string.trim() === "") {
3821
+ return "";
3822
+ }
3823
+ let returnValue = "";
3824
+ let escapeCode;
3825
+ let escapeUrl;
3826
+ const words = string.split(" ");
3827
+ let rows = [""];
3828
+ let rowLength = 0;
3829
+ for (let index = 0; index < words.length; index++) {
3830
+ const word = words[index];
3831
+ if (options.trim !== false) {
3832
+ const row = rows.at(-1) ?? "";
3833
+ const trimmed = row.trimStart();
3834
+ if (row.length !== trimmed.length) {
3835
+ rows[rows.length - 1] = trimmed;
3836
+ rowLength = dist_default2(trimmed);
3837
+ }
3838
+ }
3839
+ if (index !== 0) {
3840
+ if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
3841
+ rows.push("");
3842
+ rowLength = 0;
3843
+ }
3844
+ if (rowLength || options.trim === false) {
3845
+ rows[rows.length - 1] += " ";
3846
+ rowLength++;
3847
+ }
3848
+ }
3849
+ const wordLength = dist_default2(word);
3850
+ if (options.hard && wordLength > columns) {
3851
+ const remainingColumns = columns - rowLength;
3852
+ const breaksStartingThisLine = 1 + Math.floor((wordLength - remainingColumns - 1) / columns);
3853
+ const breaksStartingNextLine = Math.floor((wordLength - 1) / columns);
3854
+ if (breaksStartingNextLine < breaksStartingThisLine) {
3855
+ rows.push("");
3856
+ }
3857
+ wrapWord(rows, word, columns);
3858
+ rowLength = dist_default2(rows.at(-1) ?? "");
3859
+ continue;
3860
+ }
3861
+ if (rowLength + wordLength > columns && rowLength && wordLength) {
3862
+ if (options.wordWrap === false && rowLength < columns) {
3863
+ wrapWord(rows, word, columns);
3864
+ rowLength = dist_default2(rows.at(-1) ?? "");
3865
+ continue;
3866
+ }
3867
+ rows.push("");
3868
+ rowLength = 0;
3869
+ }
3870
+ if (rowLength + wordLength > columns && options.wordWrap === false) {
3871
+ wrapWord(rows, word, columns);
3872
+ rowLength = dist_default2(rows.at(-1) ?? "");
3873
+ continue;
3874
+ }
3875
+ rows[rows.length - 1] += word;
3876
+ rowLength += wordLength;
3877
+ }
3878
+ if (options.trim !== false) {
3879
+ rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
3880
+ }
3881
+ const preString = rows.join("\n");
3882
+ let inSurrogate = false;
3883
+ for (let i = 0; i < preString.length; i++) {
3884
+ const character = preString[i];
3885
+ returnValue += character;
3886
+ if (!inSurrogate) {
3887
+ inSurrogate = character >= "\uD800" && character <= "\uDBFF";
3888
+ } else {
3889
+ continue;
3890
+ }
3891
+ if (character === ESC || character === CSI) {
3892
+ GROUP_REGEX.lastIndex = i + 1;
3893
+ const groupsResult = GROUP_REGEX.exec(preString);
3894
+ const groups = groupsResult?.groups;
3895
+ if (groups?.code !== void 0) {
3896
+ const code = Number.parseFloat(groups.code);
3897
+ escapeCode = code === END_CODE ? void 0 : code;
3898
+ } else if (groups?.uri !== void 0) {
3899
+ escapeUrl = groups.uri.length === 0 ? void 0 : groups.uri;
3900
+ }
3901
+ }
3902
+ if (preString[i + 1] === "\n") {
3903
+ if (escapeUrl) {
3904
+ returnValue += wrapAnsiHyperlink("");
3905
+ }
3906
+ const closingCode = escapeCode ? getClosingCode(escapeCode) : void 0;
3907
+ if (escapeCode && closingCode) {
3908
+ returnValue += wrapAnsiCode(closingCode);
3909
+ }
3910
+ } else if (character === "\n") {
3911
+ if (escapeCode && getClosingCode(escapeCode)) {
3912
+ returnValue += wrapAnsiCode(escapeCode);
3913
+ }
3914
+ if (escapeUrl) {
3915
+ returnValue += wrapAnsiHyperlink(escapeUrl);
3916
+ }
3917
+ }
3918
+ }
3919
+ return returnValue;
3920
+ };
3921
+ var CRLF_OR_LF = /\r?\n/;
3922
+ function wrapAnsi(string, columns, options) {
3923
+ return String(string).normalize().split(CRLF_OR_LF).map((line) => exec(line, columns, options)).join("\n");
3924
+ }
3925
+
3926
+ // ../../node_modules/@clack/core/dist/index.mjs
3927
+ var import_sisteransi = __toESM(require_src(), 1);
3928
+ import { ReadStream as D } from "tty";
3929
+ function d(r, t2, e) {
3930
+ if (!e.some((o) => !o.disabled)) return r;
3931
+ const s = r + t2, i = Math.max(e.length - 1, 0), n = s < 0 ? i : s > i ? 0 : s;
3932
+ return e[n].disabled ? d(n, t2 < 0 ? -1 : 1, e) : n;
3933
+ }
3934
+ var E = ["up", "down", "left", "right", "space", "enter", "cancel"];
3935
+ var G = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
3936
+ 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)}` } } };
3937
+ function K(r) {
3938
+ if (r.aliases !== void 0) {
3939
+ const t2 = r.aliases;
3940
+ for (const e in t2) {
3941
+ if (!Object.hasOwn(t2, e)) continue;
3942
+ const s = t2[e];
3943
+ u.actions.has(s) && (u.aliases.has(e) || u.aliases.set(e, s));
3944
+ }
3945
+ }
3946
+ if (r.messages !== void 0) {
3947
+ const t2 = r.messages;
3948
+ t2.cancel !== void 0 && (u.messages.cancel = t2.cancel), t2.error !== void 0 && (u.messages.error = t2.error);
3949
+ }
3950
+ if (r.withGuide !== void 0 && (u.withGuide = r.withGuide !== false), r.date !== void 0) {
3951
+ const t2 = r.date;
3952
+ 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));
3953
+ }
3954
+ }
3955
+ function V(r, t2) {
3956
+ if (typeof r == "string") return u.aliases.get(r) === t2;
3957
+ for (const e of r) if (e !== void 0 && V(e, t2)) return true;
3958
+ return false;
3959
+ }
3960
+ function j(r, t2) {
3961
+ if (r === t2) return;
3962
+ const e = r.split(`
3963
+ `), s = t2.split(`
3964
+ `), i = Math.max(e.length, s.length), n = [];
3965
+ for (let o = 0; o < i; o++) e[o] !== s[o] && n.push(o);
3966
+ return { lines: n, numLinesBefore: e.length, numLinesAfter: s.length, numLines: i };
3967
+ }
3968
+ var Y = globalThis.process.platform.startsWith("win");
3969
+ var C = /* @__PURE__ */ Symbol("clack:cancel");
3970
+ function q(r) {
3971
+ return r === C;
3972
+ }
3973
+ function w(r, t2) {
3974
+ const e = r;
3975
+ e.isTTY && e.setRawMode(t2);
3976
+ }
3977
+ function z({ input: r = $, output: t2 = S, overwrite: e = true, hideCursor: s = true } = {}) {
3978
+ const i = _.createInterface({ input: r, output: t2, prompt: "", tabSize: 1 });
3979
+ _.emitKeypressEvents(r, i), r instanceof D && r.isTTY && r.setRawMode(true);
3980
+ const n = (o, { name: a, sequence: h }) => {
3981
+ const l = String(o);
3982
+ if (V([l, a, h], "cancel")) {
3983
+ s && t2.write(import_sisteransi.cursor.show), process.exit(0);
3984
+ return;
3985
+ }
3986
+ if (!e) return;
3987
+ const f = a === "return" ? 0 : -1, v = a === "return" ? -1 : 0;
3988
+ _.moveCursor(t2, f, v, () => {
3989
+ _.clearLine(t2, 1, () => {
3990
+ r.once("keypress", n);
3991
+ });
3992
+ });
3993
+ };
3994
+ return s && t2.write(import_sisteransi.cursor.hide), r.once("keypress", n), () => {
3995
+ 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();
3996
+ };
3997
+ }
3998
+ var O = (r) => "columns" in r && typeof r.columns == "number" ? r.columns : 80;
3999
+ var A = (r) => "rows" in r && typeof r.rows == "number" ? r.rows : 20;
4000
+ function R(r, t2, e, s = e) {
4001
+ const i = O(r ?? S);
4002
+ return wrapAnsi(t2, i - e.length, { hard: true, trim: false }).split(`
4003
+ `).map((n, o) => `${o === 0 ? s : e}${n}`).join(`
4004
+ `);
4005
+ }
4006
+ var p = class {
4007
+ input;
4008
+ output;
4009
+ _abortSignal;
4010
+ rl;
4011
+ opts;
4012
+ _render;
4013
+ _track = false;
4014
+ _prevFrame = "";
4015
+ _subscribers = /* @__PURE__ */ new Map();
4016
+ _cursor = 0;
4017
+ state = "initial";
4018
+ error = "";
4019
+ value;
4020
+ userInput = "";
4021
+ constructor(t2, e = true) {
4022
+ const { input: s = $, output: i = S, render: n, signal: o, ...a } = t2;
4023
+ 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;
4024
+ }
4025
+ unsubscribe() {
4026
+ this._subscribers.clear();
4027
+ }
4028
+ setSubscriber(t2, e) {
4029
+ const s = this._subscribers.get(t2) ?? [];
4030
+ s.push(e), this._subscribers.set(t2, s);
4031
+ }
4032
+ on(t2, e) {
4033
+ this.setSubscriber(t2, { cb: e });
4034
+ }
4035
+ once(t2, e) {
4036
+ this.setSubscriber(t2, { cb: e, once: true });
4037
+ }
4038
+ emit(t2, ...e) {
4039
+ const s = this._subscribers.get(t2) ?? [], i = [];
4040
+ for (const n of s) n.cb(...e), n.once && i.push(() => s.splice(s.indexOf(n), 1));
4041
+ for (const n of i) n();
4042
+ }
4043
+ prompt() {
4044
+ return new Promise((t2) => {
4045
+ if (this._abortSignal) {
4046
+ if (this._abortSignal.aborted) return this.state = "cancel", this.close(), t2(C);
4047
+ this._abortSignal.addEventListener("abort", () => {
4048
+ this.state = "cancel", this.close();
4049
+ }, { once: true });
4050
+ }
4051
+ 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", () => {
4052
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), w(this.input, false), t2(this.value);
4053
+ }), this.once("cancel", () => {
4054
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), w(this.input, false), t2(C);
4055
+ });
4056
+ });
4057
+ }
4058
+ _isActionKey(t2, e) {
4059
+ return t2 === " ";
4060
+ }
4061
+ _setValue(t2) {
4062
+ this.value = t2, this.emit("value", this.value);
4063
+ }
4064
+ _setUserInput(t2, e) {
4065
+ this.userInput = t2 ?? "", this.emit("userInput", this.userInput), e && this._track && this.rl && (this.rl.write(this.userInput), this._cursor = this.rl.cursor);
4066
+ }
4067
+ _clearUserInput() {
4068
+ this.rl?.write(null, { ctrl: true, name: "u" }), this._setUserInput("");
4069
+ }
4070
+ onKeypress(t2, e) {
4071
+ 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") {
4072
+ if (this.opts.validate) {
4073
+ const s = this.opts.validate(this.value);
4074
+ s && (this.error = s instanceof Error ? s.message : s, this.state = "error", this.rl?.write(this.userInput));
4075
+ }
4076
+ this.state !== "error" && (this.state = "submit");
4077
+ }
4078
+ 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();
4079
+ }
4080
+ close() {
4081
+ this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
4082
+ `), w(this.input, false), this.rl?.close(), this.rl = void 0, this.emit(`${this.state}`, this.value), this.unsubscribe();
4083
+ }
4084
+ restoreCursor() {
4085
+ const t2 = wrapAnsi(this._prevFrame, process.stdout.columns, { hard: true, trim: false }).split(`
4086
+ `).length - 1;
4087
+ this.output.write(import_sisteransi.cursor.move(-999, t2 * -1));
4088
+ }
4089
+ render() {
4090
+ const t2 = wrapAnsi(this._render(this) ?? "", process.stdout.columns, { hard: true, trim: false });
4091
+ if (t2 !== this._prevFrame) {
4092
+ if (this.state === "initial") this.output.write(import_sisteransi.cursor.hide);
4093
+ else {
4094
+ const e = j(this._prevFrame, t2), s = A(this.output);
4095
+ if (this.restoreCursor(), e) {
4096
+ const i = Math.max(0, e.numLinesAfter - s), n = Math.max(0, e.numLinesBefore - s);
4097
+ let o = e.lines.find((a) => a >= i);
4098
+ if (o === void 0) {
4099
+ this._prevFrame = t2;
4100
+ return;
4101
+ }
4102
+ if (e.lines.length === 1) {
4103
+ this.output.write(import_sisteransi.cursor.move(0, o - n)), this.output.write(import_sisteransi.erase.lines(1));
4104
+ const a = t2.split(`
4105
+ `);
4106
+ this.output.write(a[o]), this._prevFrame = t2, this.output.write(import_sisteransi.cursor.move(0, a.length - o - 1));
4107
+ return;
4108
+ } else if (e.lines.length > 1) {
4109
+ if (i < n) o = i;
4110
+ else {
4111
+ const h = o - n;
4112
+ h > 0 && this.output.write(import_sisteransi.cursor.move(0, h));
4113
+ }
4114
+ this.output.write(import_sisteransi.erase.down());
4115
+ const a = t2.split(`
4116
+ `).slice(o);
4117
+ this.output.write(a.join(`
4118
+ `)), this._prevFrame = t2;
4119
+ return;
4120
+ }
4121
+ }
4122
+ this.output.write(import_sisteransi.erase.down());
4123
+ }
4124
+ this.output.write(t2), this.state === "initial" && (this.state = "active"), this._prevFrame = t2;
4125
+ }
4126
+ }
4127
+ };
4128
+ function W(r, t2) {
4129
+ if (r === void 0 || t2.length === 0) return 0;
4130
+ const e = t2.findIndex((s) => s.value === r);
4131
+ return e !== -1 ? e : 0;
4132
+ }
4133
+ function B(r, t2) {
4134
+ return (t2.label ?? String(t2.value)).toLowerCase().includes(r.toLowerCase());
4135
+ }
4136
+ function J(r, t2) {
4137
+ if (t2) return r ? t2 : t2[0];
4138
+ }
4139
+ var H = class extends p {
4140
+ filteredOptions;
4141
+ multiple;
4142
+ isNavigating = false;
4143
+ selectedValues = [];
4144
+ focusedValue;
4145
+ #e = 0;
4146
+ #o = "";
4147
+ #t;
4148
+ #n;
4149
+ #a;
4150
+ get cursor() {
4151
+ return this.#e;
4152
+ }
4153
+ get userInputWithCursor() {
4154
+ if (!this.userInput) return y(["inverse", "hidden"], "_");
4155
+ if (this._cursor >= this.userInput.length) return `${this.userInput}\u2588`;
4156
+ const t2 = this.userInput.slice(0, this._cursor), [e, ...s] = this.userInput.slice(this._cursor);
4157
+ return `${t2}${y("inverse", e)}${s.join("")}`;
4158
+ }
4159
+ get options() {
4160
+ return typeof this.#n == "function" ? this.#n() : this.#n;
4161
+ }
4162
+ constructor(t2) {
4163
+ super(t2), this.#n = t2.options, this.#a = t2.placeholder;
4164
+ const e = this.options;
4165
+ this.filteredOptions = [...e], this.multiple = t2.multiple === true, this.#t = typeof t2.options == "function" ? t2.filter : t2.filter ?? B;
4166
+ let s;
4167
+ 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) {
4168
+ const n = e.findIndex((o) => o.value === i);
4169
+ n !== -1 && (this.toggleSelected(i), this.#e = n);
4170
+ }
4171
+ this.focusedValue = this.options[this.#e]?.value, this.on("key", (i, n) => this.#s(i, n)), this.on("userInput", (i) => this.#i(i));
4172
+ }
4173
+ _isActionKey(t2, e) {
4174
+ return t2 === " " || this.multiple && this.isNavigating && e.name === "space" && t2 !== void 0 && t2 !== "";
4175
+ }
4176
+ #s(t2, e) {
4177
+ 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));
4178
+ if (e.name === "tab" && o && l) {
4179
+ this.userInput === " " && this._clearUserInput(), this._setUserInput(a, true), this.isNavigating = false;
4180
+ return;
4181
+ }
4182
+ 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);
4183
+ }
4184
+ deselectAll() {
4185
+ this.selectedValues = [];
4186
+ }
4187
+ toggleSelected(t2) {
4188
+ 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]);
4189
+ }
4190
+ #i(t2) {
4191
+ if (t2 !== this.#o) {
4192
+ this.#o = t2;
4193
+ const e = this.options;
4194
+ t2 && this.#t ? this.filteredOptions = e.filter((n) => this.#t?.(t2, n)) : this.filteredOptions = [...e];
4195
+ const s = W(this.focusedValue, this.filteredOptions);
4196
+ this.#e = d(s, 0, this.filteredOptions);
4197
+ const i = this.filteredOptions[this.#e];
4198
+ i && !i.disabled ? this.focusedValue = i.value : this.focusedValue = void 0, this.multiple || (this.focusedValue !== void 0 ? this.toggleSelected(this.focusedValue) : this.deselectAll());
4199
+ }
4200
+ }
4201
+ };
4202
+ var Q = class extends p {
4203
+ get cursor() {
4204
+ return this.value ? 0 : 1;
4205
+ }
4206
+ get _value() {
4207
+ return this.cursor === 0;
4208
+ }
4209
+ constructor(t2) {
4210
+ super(t2, false), this.value = !!t2.initialValue, this.on("userInput", () => {
4211
+ this.value = this._value;
4212
+ }), this.on("confirm", (e) => {
4213
+ this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = e, this.state = "submit", this.close();
4214
+ }), this.on("cursor", () => {
4215
+ this.value = !this.value;
4216
+ });
4217
+ }
4218
+ };
4219
+ var X = { Y: { type: "year", len: 4 }, M: { type: "month", len: 2 }, D: { type: "day", len: 2 } };
4220
+ function L(r) {
4221
+ return [...r].map((t2) => X[t2]);
4222
+ }
4223
+ function Z(r) {
4224
+ const t2 = new Intl.DateTimeFormat(r, { year: "numeric", month: "2-digit", day: "2-digit" }).formatToParts(new Date(2e3, 0, 15)), e = [];
4225
+ let s = "/";
4226
+ 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 });
4227
+ return { segments: e, separator: s };
4228
+ }
4229
+ function k(r) {
4230
+ return Number.parseInt((r || "0").replace(/_/g, "0"), 10) || 0;
4231
+ }
4232
+ function I(r) {
4233
+ return { year: k(r.year), month: k(r.month), day: k(r.day) };
4234
+ }
4235
+ function T(r, t2) {
4236
+ return new Date(r || 2001, t2 || 1, 0).getDate();
4237
+ }
4238
+ function F(r) {
4239
+ const { year: t2, month: e, day: s } = I(r);
4240
+ if (!t2 || t2 < 0 || t2 > 9999 || !e || e < 1 || e > 12 || !s || s < 1) return;
4241
+ const i = new Date(Date.UTC(t2, e - 1, s));
4242
+ if (!(i.getUTCFullYear() !== t2 || i.getUTCMonth() !== e - 1 || i.getUTCDate() !== s)) return { year: t2, month: e, day: s };
4243
+ }
4244
+ function N(r) {
4245
+ const t2 = F(r);
4246
+ return t2 ? new Date(Date.UTC(t2.year, t2.month - 1, t2.day)) : void 0;
4247
+ }
4248
+ function tt(r, t2, e, s) {
4249
+ 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;
4250
+ 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) };
4251
+ }
4252
+ var et = class extends p {
4253
+ #e;
4254
+ #o;
4255
+ #t;
4256
+ #n;
4257
+ #a;
4258
+ #s = { segmentIndex: 0, positionInSegment: 0 };
4259
+ #i = true;
4260
+ #r = null;
4261
+ inlineError = "";
4262
+ get segmentCursor() {
4263
+ return { ...this.#s };
4264
+ }
4265
+ get segmentValues() {
4266
+ return { ...this.#t };
4267
+ }
4268
+ get segments() {
4269
+ return this.#e;
4270
+ }
4271
+ get separator() {
4272
+ return this.#o;
4273
+ }
4274
+ get formattedValue() {
4275
+ return this.#c(this.#t);
4276
+ }
4277
+ #c(t2) {
4278
+ return this.#e.map((e) => t2[e.type]).join(this.#o);
4279
+ }
4280
+ #h() {
4281
+ this._setUserInput(this.#c(this.#t)), this._setValue(N(this.#t) ?? void 0);
4282
+ }
4283
+ constructor(t2) {
4284
+ 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);
4285
+ 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));
4286
+ }
4287
+ #u() {
4288
+ const t2 = Math.max(0, Math.min(this.#s.segmentIndex, this.#e.length - 1)), e = this.#e[t2];
4289
+ if (e) return this.#s.positionInSegment = Math.max(0, Math.min(this.#s.positionInSegment, e.len - 1)), { segment: e, index: t2 };
4290
+ }
4291
+ #l(t2) {
4292
+ this.inlineError = "", this.#r = null;
4293
+ const e = this.#u();
4294
+ e && (this.#s.segmentIndex = Math.max(0, Math.min(this.#e.length - 1, e.index + t2)), this.#s.positionInSegment = 0, this.#i = true);
4295
+ }
4296
+ #p(t2) {
4297
+ const e = this.#u();
4298
+ if (!e) return;
4299
+ 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);
4300
+ let h;
4301
+ 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();
4302
+ }
4303
+ #d(t2) {
4304
+ if (t2) switch (t2) {
4305
+ case "right":
4306
+ return this.#l(1);
4307
+ case "left":
4308
+ return this.#l(-1);
4309
+ case "up":
4310
+ return this.#p(1);
4311
+ case "down":
4312
+ return this.#p(-1);
4313
+ }
4314
+ }
4315
+ #f(t2, e) {
4316
+ if (e?.name === "backspace" || e?.sequence === "\x7F" || e?.sequence === "\b" || t2 === "\x7F" || t2 === "\b") {
4317
+ this.inlineError = "";
4318
+ const s = this.#u();
4319
+ if (!s) return;
4320
+ if (!this.#t[s.segment.type].replace(/_/g, "")) {
4321
+ this.#l(-1);
4322
+ return;
4323
+ }
4324
+ this.#t[s.segment.type] = "_".repeat(s.segment.len), this.#i = true, this.#s.positionInSegment = 0, this.#h();
4325
+ return;
4326
+ }
4327
+ if (e?.name === "tab") {
4328
+ this.inlineError = "";
4329
+ const s = this.#u();
4330
+ if (!s) return;
4331
+ const i = e.shift ? -1 : 1, n = s.index + i;
4332
+ n >= 0 && n < this.#e.length && (this.#s.segmentIndex = n, this.#s.positionInSegment = 0, this.#i = true);
4333
+ return;
4334
+ }
4335
+ if (t2 && /^[0-9]$/.test(t2)) {
4336
+ const s = this.#u();
4337
+ if (!s) return;
4338
+ const { segment: i } = s, n = !this.#t[i.type].replace(/_/g, "");
4339
+ if (this.#i && this.#r !== null && !n) {
4340
+ const m = this.#r + t2, g = { ...this.#t, [i.type]: m }, b = this.#m(g, i);
4341
+ if (b) {
4342
+ this.inlineError = b, this.#r = null, this.#i = false;
4343
+ return;
4344
+ }
4345
+ 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);
4346
+ return;
4347
+ }
4348
+ this.#i && !n && (this.#t[i.type] = "_".repeat(i.len), this.#s.positionInSegment = 0), this.#i = false, this.#r = null;
4349
+ const o = this.#t[i.type], a = o.indexOf("_"), h = a >= 0 ? a : Math.min(this.#s.positionInSegment, i.len - 1);
4350
+ if (h < 0 || h >= i.len) return;
4351
+ let l = o.slice(0, h) + t2 + o.slice(h + 1), f = false;
4352
+ if (h === 0 && o === "__" && (i.type === "month" || i.type === "day")) {
4353
+ const m = Number.parseInt(t2, 10);
4354
+ l = `0${t2}`, f = m <= (i.type === "month" ? 1 : 2);
4355
+ }
4356
+ if (i.type === "year" && (l = (o.replace(/_/g, "") + t2).padStart(i.len, "_")), !l.includes("_")) {
4357
+ const m = { ...this.#t, [i.type]: l }, g = this.#m(m, i);
4358
+ if (g) {
4359
+ this.inlineError = g;
4360
+ return;
4361
+ }
4362
+ }
4363
+ this.inlineError = "", this.#t[i.type] = l;
4364
+ const v = l.includes("_") ? void 0 : F(this.#t);
4365
+ if (v) {
4366
+ const { year: m, month: g } = v, b = T(m, g);
4367
+ 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") };
4368
+ }
4369
+ this.#h();
4370
+ const U2 = l.indexOf("_");
4371
+ 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);
4372
+ }
4373
+ }
4374
+ #m(t2, e) {
4375
+ const { month: s, day: i } = I(t2);
4376
+ if (e.type === "month" && (s < 0 || s > 12)) return u.date.messages.invalidMonth;
4377
+ if (e.type === "day" && (i < 0 || i > 31)) return u.date.messages.invalidDay(31, "any month");
4378
+ }
4379
+ #g(t2) {
4380
+ const { year: e, month: s, day: i } = I(this.#t);
4381
+ if (e && s && i) {
4382
+ const n = T(e, s);
4383
+ this.#t = { ...this.#t, day: String(Math.min(i, n)).padStart(2, "0") };
4384
+ }
4385
+ this.value = N(this.#t) ?? t2.defaultValue ?? void 0;
4386
+ }
4387
+ };
4388
+ var st = class extends p {
4389
+ options;
4390
+ cursor = 0;
4391
+ #e;
4392
+ getGroupItems(t2) {
4393
+ return this.options.filter((e) => e.group === t2);
4394
+ }
4395
+ isGroupSelected(t2) {
4396
+ const e = this.getGroupItems(t2), s = this.value;
4397
+ return s === void 0 ? false : e.every((i) => s.includes(i.value));
4398
+ }
4399
+ toggleValue() {
4400
+ const t2 = this.options[this.cursor];
4401
+ if (this.value === void 0 && (this.value = []), t2.group === true) {
4402
+ const e = t2.value, s = this.getGroupItems(e);
4403
+ 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));
4404
+ } else {
4405
+ const e = this.value.includes(t2.value);
4406
+ this.value = e ? this.value.filter((s) => s !== t2.value) : [...this.value, t2.value];
4407
+ }
4408
+ }
4409
+ constructor(t2) {
4410
+ super(t2, false);
4411
+ const { options: e } = t2;
4412
+ 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) => {
4413
+ switch (s) {
4414
+ case "left":
4415
+ case "up": {
4416
+ this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
4417
+ const i = this.options[this.cursor]?.group === true;
4418
+ !this.#e && i && (this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1);
4419
+ break;
4420
+ }
4421
+ case "down":
4422
+ case "right": {
4423
+ this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
4424
+ const i = this.options[this.cursor]?.group === true;
4425
+ !this.#e && i && (this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1);
4426
+ break;
4427
+ }
4428
+ case "space":
4429
+ this.toggleValue();
4430
+ break;
4431
+ }
4432
+ });
4433
+ }
4434
+ };
4435
+ var it = class extends p {
4436
+ options;
4437
+ cursor = 0;
4438
+ get _value() {
4439
+ return this.options[this.cursor].value;
4440
+ }
4441
+ get _enabledOptions() {
4442
+ return this.options.filter((t2) => t2.disabled !== true);
4443
+ }
4444
+ toggleAll() {
4445
+ const t2 = this._enabledOptions, e = this.value !== void 0 && this.value.length === t2.length;
4446
+ this.value = e ? [] : t2.map((s) => s.value);
4447
+ }
4448
+ toggleInvert() {
4449
+ const t2 = this.value;
4450
+ if (!t2) return;
4451
+ const e = this._enabledOptions.filter((s) => !t2.includes(s.value));
4452
+ this.value = e.map((s) => s.value);
4453
+ }
4454
+ toggleValue() {
4455
+ this.value === void 0 && (this.value = []);
4456
+ const t2 = this.value.includes(this._value);
4457
+ this.value = t2 ? this.value.filter((e) => e !== this._value) : [...this.value, this._value];
4458
+ }
4459
+ constructor(t2) {
4460
+ super(t2, false), this.options = t2.options, this.value = [...t2.initialValues ?? []];
4461
+ const e = Math.max(this.options.findIndex(({ value: s }) => s === t2.cursorAt), 0);
4462
+ this.cursor = this.options[e].disabled ? d(e, 1, this.options) : e, this.on("key", (s) => {
4463
+ s === "a" && this.toggleAll(), s === "i" && this.toggleInvert();
4464
+ }), this.on("cursor", (s) => {
4465
+ switch (s) {
4466
+ case "left":
4467
+ case "up":
4468
+ this.cursor = d(this.cursor, -1, this.options);
4469
+ break;
4470
+ case "down":
4471
+ case "right":
4472
+ this.cursor = d(this.cursor, 1, this.options);
4473
+ break;
4474
+ case "space":
4475
+ this.toggleValue();
4476
+ break;
4477
+ }
4478
+ });
4479
+ }
4480
+ };
4481
+ var rt = class extends p {
4482
+ _mask = "\u2022";
4483
+ get cursor() {
4484
+ return this._cursor;
4485
+ }
4486
+ get masked() {
4487
+ return this.userInput.replaceAll(/./g, this._mask);
4488
+ }
4489
+ get userInputWithCursor() {
4490
+ if (this.state === "submit" || this.state === "cancel") return this.masked;
4491
+ const t2 = this.userInput;
4492
+ if (this.cursor >= t2.length) return `${this.masked}${y(["inverse", "hidden"], "_")}`;
4493
+ const e = this.masked, s = e.slice(0, this.cursor), i = e.slice(this.cursor);
4494
+ return `${s}${y("inverse", i[0])}${i.slice(1)}`;
4495
+ }
4496
+ clear() {
4497
+ this._clearUserInput();
4498
+ }
4499
+ constructor({ mask: t2, ...e }) {
4500
+ super(e), this._mask = t2 ?? "\u2022", this.on("userInput", (s) => {
4501
+ this._setValue(s);
4502
+ });
4503
+ }
4504
+ };
4505
+ var nt = class extends p {
4506
+ options;
4507
+ cursor = 0;
4508
+ get _selectedValue() {
4509
+ return this.options[this.cursor];
4510
+ }
4511
+ changeValue() {
4512
+ this.value = this._selectedValue.value;
4513
+ }
4514
+ constructor(t2) {
4515
+ super(t2, false), this.options = t2.options;
4516
+ const e = this.options.findIndex(({ value: i }) => i === t2.initialValue), s = e === -1 ? 0 : e;
4517
+ this.cursor = this.options[s].disabled ? d(s, 1, this.options) : s, this.changeValue(), this.on("cursor", (i) => {
4518
+ switch (i) {
4519
+ case "left":
4520
+ case "up":
4521
+ this.cursor = d(this.cursor, -1, this.options);
4522
+ break;
4523
+ case "down":
4524
+ case "right":
4525
+ this.cursor = d(this.cursor, 1, this.options);
4526
+ break;
4527
+ }
4528
+ this.changeValue();
4529
+ });
4530
+ }
4531
+ };
4532
+ var ot = class extends p {
4533
+ options;
4534
+ cursor = 0;
4535
+ constructor(t2) {
4536
+ super(t2, false), this.options = t2.options;
4537
+ const e = t2.caseSensitive === true, s = this.options.map(({ value: [i] }) => e ? i : i?.toLowerCase());
4538
+ this.cursor = Math.max(s.indexOf(t2.initialValue), 0), this.on("key", (i, n) => {
4539
+ if (!i) return;
4540
+ const o = e && n.shift ? i.toUpperCase() : i;
4541
+ if (!s.includes(o)) return;
4542
+ const a = this.options.find(({ value: [h] }) => e ? h === o : h?.toLowerCase() === i);
4543
+ a && (this.value = a.value, this.state = "submit", this.emit("submit"));
4544
+ });
4545
+ }
4546
+ };
4547
+ var at = class extends p {
4548
+ get userInputWithCursor() {
4549
+ if (this.state === "submit") return this.userInput;
4550
+ const t2 = this.userInput;
4551
+ if (this.cursor >= t2.length) return `${this.userInput}\u2588`;
4552
+ const e = t2.slice(0, this.cursor), [s, ...i] = t2.slice(this.cursor);
4553
+ return `${e}${y("inverse", s)}${i.join("")}`;
4554
+ }
4555
+ get cursor() {
4556
+ return this._cursor;
4557
+ }
4558
+ constructor(t2) {
4559
+ super({ ...t2, initialUserInput: t2.initialUserInput ?? t2.initialValue }), this.on("userInput", (e) => {
4560
+ this._setValue(e);
4561
+ }), this.on("finalize", () => {
4562
+ this.value || (this.value = t2.defaultValue), this.value === void 0 && (this.value = "");
4563
+ });
4564
+ }
4565
+ };
4566
+
4567
+ // ../../node_modules/@clack/prompts/dist/index.mjs
4568
+ import { styleText as t, stripVTControlCharacters as ne } from "util";
4569
+ import P2 from "process";
4570
+ var import_sisteransi2 = __toESM(require_src(), 1);
4571
+ import { existsSync as Xe, lstatSync as we, readdirSync as ze } from "fs";
4572
+ import { dirname as be, join as Qe } from "path";
4573
+ function Ze() {
4574
+ 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";
4575
+ }
4576
+ var ee = Ze();
4577
+ var ae = () => process.env.CI === "true";
4578
+ var Te = (e) => e.isTTY === true;
4579
+ var w2 = (e, i) => ee ? e : i;
4580
+ var _e = w2("\u25C6", "*");
4581
+ var oe = w2("\u25A0", "x");
4582
+ var ue = w2("\u25B2", "x");
4583
+ var F2 = w2("\u25C7", "o");
4584
+ var le = w2("\u250C", "T");
4585
+ var d2 = w2("\u2502", "|");
4586
+ var E2 = w2("\u2514", "\u2014");
4587
+ var Ie = w2("\u2510", "T");
4588
+ var Ee = w2("\u2518", "\u2014");
4589
+ var z2 = w2("\u25CF", ">");
4590
+ var H2 = w2("\u25CB", " ");
4591
+ var te = w2("\u25FB", "[\u2022]");
4592
+ var U = w2("\u25FC", "[+]");
4593
+ var J2 = w2("\u25FB", "[ ]");
4594
+ var xe = w2("\u25AA", "\u2022");
4595
+ var se = w2("\u2500", "-");
4596
+ var ce = w2("\u256E", "+");
4597
+ var Ge = w2("\u251C", "+");
4598
+ var $e = w2("\u256F", "+");
4599
+ var de = w2("\u2570", "+");
4600
+ var Oe = w2("\u256D", "+");
4601
+ var he = w2("\u25CF", "\u2022");
4602
+ var pe = w2("\u25C6", "*");
4603
+ var me = w2("\u25B2", "!");
4604
+ var ge = w2("\u25A0", "x");
4605
+ var V2 = (e) => {
4606
+ switch (e) {
4607
+ case "initial":
4608
+ case "active":
4609
+ return t("cyan", _e);
4610
+ case "cancel":
4611
+ return t("red", oe);
4612
+ case "error":
4613
+ return t("yellow", ue);
4614
+ case "submit":
4615
+ return t("green", F2);
4616
+ }
4617
+ };
4618
+ var ye = (e) => {
4619
+ switch (e) {
4620
+ case "initial":
4621
+ case "active":
4622
+ return t("cyan", d2);
4623
+ case "cancel":
4624
+ return t("red", d2);
4625
+ case "error":
4626
+ return t("yellow", d2);
4627
+ case "submit":
4628
+ return t("green", d2);
4629
+ }
4630
+ };
4631
+ var et2 = (e, i, s, r, u2) => {
4632
+ let n = i, o = 0;
4633
+ for (let c2 = s; c2 < r; c2++) {
4634
+ const a = e[c2];
4635
+ if (n = n - a.length, o++, n <= u2) break;
4636
+ }
4637
+ return { lineCount: n, removals: o };
4638
+ };
4639
+ var Y2 = ({ cursor: e, options: i, style: s, output: r = process.stdout, maxItems: u2 = Number.POSITIVE_INFINITY, columnPadding: n = 0, rowPadding: o = 4 }) => {
4640
+ 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);
4641
+ let p2 = 0;
4642
+ e >= y2 - 3 && (p2 = Math.max(Math.min(e - y2 + 3, i.length - y2), 0));
4643
+ let m = y2 < i.length && p2 > 0, g = y2 < i.length && p2 + y2 < i.length;
4644
+ const S2 = Math.min(p2 + y2, i.length), h = [];
4645
+ let f = 0;
4646
+ m && f++, g && f++;
4647
+ const v = p2 + (m ? 1 : 0), T2 = S2 - (g ? 1 : 0);
4648
+ for (let b = v; b < T2; b++) {
4649
+ const x = wrapAnsi(s(i[b], b === e), c2, { hard: true, trim: false }).split(`
4650
+ `);
4651
+ h.push(x), f += x.length;
4652
+ }
4653
+ if (f > $2) {
4654
+ let b = 0, x = 0, G2 = f;
4655
+ const M2 = e - v, R2 = (j2, D2) => et2(h, G2, j2, D2, $2);
4656
+ 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));
4657
+ }
4658
+ const C2 = [];
4659
+ m && C2.push(l);
4660
+ for (const b of h) for (const x of b) C2.push(x);
4661
+ return g && C2.push(l), C2;
4662
+ };
4663
+ function Me(e) {
4664
+ return e.label ?? String(e.value ?? "");
4665
+ }
4666
+ function Re(e, i) {
4667
+ if (!e) return true;
4668
+ const s = (i.label ?? String(i.value ?? "")).toLowerCase(), r = (i.hint ?? "").toLowerCase(), u2 = String(i.value).toLowerCase(), n = e.toLowerCase();
4669
+ return s.includes(n) || r.includes(n) || u2.includes(n);
4670
+ }
4671
+ function tt2(e, i) {
4672
+ const s = [];
4673
+ for (const r of i) e.includes(r.value) && s.push(r);
4674
+ return s;
4675
+ }
4676
+ 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() {
4677
+ 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) => {
4678
+ const $2 = Me(a), y2 = a.hint && a.value === this.focusedValue ? t("dim", ` (${a.hint})`) : "";
4679
+ switch (l) {
4680
+ case "active":
4681
+ return `${t("green", z2)} ${$2}${y2}`;
4682
+ case "inactive":
4683
+ return `${t("dim", H2)} ${t("dim", $2)}`;
4684
+ case "disabled":
4685
+ return `${t("gray", H2)} ${t(["strikethrough", "gray"], $2)}`;
4686
+ }
4687
+ };
4688
+ switch (this.state) {
4689
+ case "submit": {
4690
+ const a = tt2(this.selectedValues, u2), l = a.length > 0 ? ` ${t("dim", a.map(Me).join(", "))}` : "", $2 = i ? t("gray", d2) : "";
4691
+ return `${s.join(`
4692
+ `)}
4693
+ ${$2}${l}`;
4694
+ }
4695
+ case "cancel": {
4696
+ const a = r ? ` ${t(["strikethrough", "dim"], r)}` : "", l = i ? t("gray", d2) : "";
4697
+ return `${s.join(`
4698
+ `)}
4699
+ ${l}${a}`;
4700
+ }
4701
+ default: {
4702
+ const a = this.state === "error" ? "yellow" : "cyan", l = i ? `${t(a, d2)} ` : "", $2 = i ? t(a, E2) : "";
4703
+ let y2 = "";
4704
+ if (this.isNavigating || o) {
4705
+ const v = o ? n : r;
4706
+ y2 = v !== "" ? ` ${t("dim", v)}` : "";
4707
+ } else y2 = ` ${this.userInputWithCursor}`;
4708
+ 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)}`] : [];
4709
+ i && s.push(`${l.trimEnd()}`), s.push(`${l}${t("dim", "Search:")}${y2}${p2}`, ...m, ...g);
4710
+ 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 });
4711
+ return [...s, ...f.map((v) => `${l}${v}`), ...h].join(`
4712
+ `);
4713
+ }
4714
+ }
4715
+ } }).prompt();
4716
+ var st2 = (e) => {
4717
+ const i = (r, u2, n, o) => {
4718
+ 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);
4719
+ return r.disabled ? `${t("gray", J2)} ${t(["strikethrough", "gray"], a)}` : u2 ? `${$2} ${a}${l}` : `${$2} ${t("dim", a)}`;
4720
+ }, s = new H({ options: e.options, multiple: true, placeholder: e.placeholder, filter: e.filter ?? ((r, u2) => Re(r, u2)), validate: () => {
4721
+ if (e.required && s.selectedValues.length === 0) return "Please select at least one item";
4722
+ }, initialValue: e.initialValues, signal: e.signal, input: e.input, output: e.output, render() {
4723
+ const r = e.withGuide ?? u.withGuide, u2 = `${r ? `${t("gray", d2)}
4724
+ ` : ""}${V2(this.state)} ${e.message}
4725
+ `, 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"})`) : "";
4726
+ switch (this.state) {
4727
+ case "submit":
4728
+ return `${u2}${r ? `${t("gray", d2)} ` : ""}${t("dim", `${this.selectedValues.length} items selected`)}`;
4729
+ case "cancel":
4730
+ return `${u2}${r ? `${t("gray", d2)} ` : ""}${t(["strikethrough", "dim"], n)}`;
4731
+ default: {
4732
+ 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(`
4733
+ `), `${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 });
4734
+ return [...f, ...T2.map((C2) => `${p2}${C2}`), ...v].join(`
4735
+ `);
4736
+ }
4737
+ }
4738
+ } });
4739
+ return s.prompt();
4740
+ };
4741
+ var rt2 = [Oe, ce, de, $e];
4742
+ var it2 = [le, Ie, E2, Ee];
4743
+ function Pe(e, i, s, r) {
4744
+ let u2 = s, n = s;
4745
+ return r === "center" ? u2 = Math.floor((i - e) / 2) : r === "right" && (u2 = i - e - s), n = i - u2 - e, [u2, n];
4746
+ }
4747
+ var nt2 = (e) => e;
4748
+ var at2 = (e = "", i = "", s) => {
4749
+ 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;
4750
+ let f = Math.floor(u2 * a) - g;
4751
+ if (s?.width === "auto") {
4752
+ const R2 = e.split(`
4753
+ `);
4754
+ let j2 = S2 + o * 2;
4755
+ for (const ie of R2) {
4756
+ const W2 = dist_default2(ie) + c2 * 2;
4757
+ W2 > j2 && (j2 = W2);
4758
+ }
4759
+ const D2 = j2 + n;
4760
+ D2 < f && (f = D2);
4761
+ }
4762
+ f % 2 !== 0 && (f < h ? f++ : f--);
4763
+ 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 });
4764
+ r.write(`${l}${y2[0]}${p2.repeat(b)}${C2}${p2.repeat(x)}${y2[1]}
4765
+ `);
4766
+ const M2 = G2.split(`
4767
+ `);
4768
+ for (const R2 of M2) {
4769
+ const [j2, D2] = Pe(dist_default2(R2), v, c2, s?.contentAlign);
4770
+ r.write(`${l}${m}${" ".repeat(j2)}${R2}${" ".repeat(D2)}${m}
4771
+ `);
4772
+ }
4773
+ r.write(`${l}${y2[2]}${p2.repeat(v)}${y2[3]}
4774
+ `);
4775
+ };
4776
+ var ot2 = (e) => {
4777
+ const i = e.active ?? "Yes", s = e.inactive ?? "No";
4778
+ return new Q({ active: i, inactive: s, signal: e.signal, input: e.input, output: e.output, initialValue: e.initialValue ?? true, render() {
4779
+ 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)}
4780
+ ` : ""}${o}
4781
+ `, a = this.value ? i : s;
4782
+ switch (this.state) {
4783
+ case "submit": {
4784
+ const l = r ? `${t("gray", d2)} ` : "";
4785
+ return `${c2}${l}${t("dim", a)}`;
4786
+ }
4787
+ case "cancel": {
4788
+ const l = r ? `${t("gray", d2)} ` : "";
4789
+ return `${c2}${l}${t(["strikethrough", "dim"], a)}${r ? `
4790
+ ${t("gray", d2)}` : ""}`;
4791
+ }
4792
+ default: {
4793
+ const l = r ? `${t("cyan", d2)} ` : "", $2 = r ? t("cyan", E2) : "";
4794
+ return `${c2}${l}${this.value ? `${t("green", z2)} ${i}` : `${t("dim", H2)} ${t("dim", i)}`}${e.vertical ? r ? `
4795
+ ${t("cyan", d2)} ` : `
4796
+ ` : ` ${t("dim", "/")} `}${this.value ? `${t("dim", H2)} ${t("dim", s)}` : `${t("green", z2)} ${s}`}
4797
+ ${$2}
4798
+ `;
4799
+ }
4800
+ }
4801
+ } }).prompt();
4802
+ };
4803
+ var ut = (e) => {
4804
+ const i = e.validate;
4805
+ return new et({ ...e, validate(s) {
4806
+ if (s === void 0) return e.defaultValue !== void 0 ? void 0 : i ? i(s) : u.date.messages.required;
4807
+ const r = (u2) => u2.toISOString().slice(0, 10);
4808
+ if (e.minDate && r(s) < r(e.minDate)) return u.date.messages.afterMin(e.minDate);
4809
+ if (e.maxDate && r(s) > r(e.maxDate)) return u.date.messages.beforeMax(e.maxDate);
4810
+ if (i) return i(s);
4811
+ }, render() {
4812
+ const s = (e?.withGuide ?? u.withGuide) !== false, r = `${`${s ? `${t("gray", d2)}
4813
+ ` : ""}${V2(this.state)} `}${e.message}
4814
+ `, u2 = this.state !== "initial" ? this.state : "active", n = lt(this, u2), o = this.value instanceof Date ? this.formattedValue : "";
4815
+ switch (this.state) {
4816
+ case "error": {
4817
+ const c2 = this.error ? ` ${t("yellow", this.error)}` : "", a = s ? `${t("yellow", d2)} ` : "", l = s ? t("yellow", E2) : "";
4818
+ return `${r.trim()}
4819
+ ${a}${n}
4820
+ ${l}${c2}
4821
+ `;
4822
+ }
4823
+ case "submit": {
4824
+ const c2 = o ? ` ${t("dim", o)}` : "", a = s ? t("gray", d2) : "";
4825
+ return `${r}${a}${c2}`;
4826
+ }
4827
+ case "cancel": {
4828
+ const c2 = o ? ` ${t(["strikethrough", "dim"], o)}` : "", a = s ? t("gray", d2) : "";
4829
+ return `${r}${a}${c2}${o.trim() ? `
4830
+ ${a}` : ""}`;
4831
+ }
4832
+ default: {
4833
+ const c2 = s ? `${t("cyan", d2)} ` : "", a = s ? t("cyan", E2) : "", l = s ? `${t("cyan", d2)} ` : "", $2 = this.inlineError ? `
4834
+ ${l}${t("yellow", this.inlineError)}` : "";
4835
+ return `${r}${c2}${n}${$2}
4836
+ ${a}
4837
+ `;
4838
+ }
4839
+ }
4840
+ } }).prompt();
4841
+ };
4842
+ function lt(e, i) {
4843
+ const s = e.segmentValues, r = e.segmentCursor;
4844
+ if (i === "submit" || i === "cancel") return e.formattedValue;
4845
+ const u2 = t("gray", e.separator);
4846
+ return e.segments.map((n, o) => {
4847
+ const c2 = o === r.segmentIndex && !["submit", "cancel"].includes(i), a = $t[n.type];
4848
+ return ct(s[n.type], { isActive: c2, label: a });
4849
+ }).join(u2);
4850
+ }
4851
+ function ct(e, i) {
4852
+ const s = !e || e.replace(/_/g, "") === "";
4853
+ return i.isActive ? t("inverse", s ? i.label : e.replace(/_/g, " ")) : s ? t("dim", i.label) : e.replace(/_/g, t("dim", " "));
4854
+ }
4855
+ var $t = { year: "yyyy", month: "mm", day: "dd" };
4856
+ var dt = async (e, i) => {
4857
+ const s = {}, r = Object.keys(e);
4858
+ for (const u2 of r) {
4859
+ const n = e[u2], o = await n({ results: s })?.catch((c2) => {
4860
+ throw c2;
4861
+ });
4862
+ if (typeof i?.onCancel == "function" && q(o)) {
4863
+ s[u2] = "canceled", i.onCancel({ results: s });
4864
+ continue;
4865
+ }
4866
+ s[u2] = o;
4867
+ }
4868
+ return s;
4869
+ };
4870
+ var ht = (e) => {
4871
+ const { selectableGroups: i = true, groupSpacing: s = 0 } = e, r = (n, o, c2 = []) => {
4872
+ 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} ` : " " : "";
4873
+ let m = "";
4874
+ if (s > 0 && !l) {
4875
+ const S2 = `
4876
+ ${t("cyan", d2)}`;
4877
+ m = `${S2.repeat(s - 1)}${S2} `;
4878
+ }
4879
+ if (o === "active") return `${m}${t("dim", p2)}${t("cyan", te)} ${a}${n.hint ? ` ${t("dim", `(${n.hint})`)}` : ""}`;
4880
+ if (o === "group-active") return `${m}${p2}${t("cyan", te)} ${t("dim", a)}`;
4881
+ if (o === "group-active-selected") return `${m}${p2}${t("green", U)} ${t("dim", a)}`;
4882
+ if (o === "selected") {
4883
+ const S2 = l || i ? t("green", U) : "";
4884
+ return `${m}${t("dim", p2)}${S2} ${t("dim", a)}${n.hint ? ` ${t("dim", `(${n.hint})`)}` : ""}`;
4885
+ }
4886
+ if (o === "cancelled") return `${t(["strikethrough", "dim"], a)}`;
4887
+ if (o === "active-selected") return `${m}${t("dim", p2)}${t("green", U)} ${a}${n.hint ? ` ${t("dim", `(${n.hint})`)}` : ""}`;
4888
+ if (o === "submitted") return `${t("dim", a)}`;
4889
+ const g = l || i ? t("dim", J2) : "";
4890
+ return `${m}${t("dim", p2)}${g} ${t("dim", a)}`;
4891
+ }, u2 = e.required ?? true;
4892
+ 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) {
4893
+ if (u2 && (n === void 0 || n.length === 0)) return `Please select at least one option.
4894
+ ${t("reset", t("dim", `Press ${t(["gray", "bgWhite", "inverse"], " space ")} to select, ${t("gray", t(["bgWhite", "inverse"], " enter "))} to submit`))}`;
4895
+ }, render() {
4896
+ const n = e.withGuide ?? u.withGuide, o = `${n ? `${t("gray", d2)}
4897
+ ` : ""}${V2(this.state)} ${e.message}
4898
+ `, c2 = this.value ?? [];
4899
+ switch (this.state) {
4900
+ case "submit": {
4901
+ const a = this.options.filter(({ value: $2 }) => c2.includes($2)).map(($2) => r($2, "submitted")), l = a.length === 0 ? "" : ` ${a.join(t("dim", ", "))}`;
4902
+ return `${o}${n ? t("gray", d2) : ""}${l}`;
4903
+ }
4904
+ case "cancel": {
4905
+ const a = this.options.filter(({ value: l }) => c2.includes(l)).map((l) => r(l, "cancelled")).join(t("dim", ", "));
4906
+ return `${o}${n ? `${t("gray", d2)} ` : ""}${a.trim() ? `${a}${n ? `
4907
+ ${t("gray", d2)}` : ""}` : ""}`;
4908
+ }
4909
+ case "error": {
4910
+ const a = this.error.split(`
4911
+ `).map((l, $2) => $2 === 0 ? `${n ? `${t("yellow", E2)} ` : ""}${t("yellow", l)}` : ` ${l}`).join(`
4912
+ `);
4913
+ return `${o}${n ? `${t("yellow", d2)} ` : ""}${this.options.map((l, $2, y2) => {
4914
+ const p2 = c2.includes(l.value) || l.group === true && this.isGroupSelected(`${l.value}`), m = $2 === this.cursor;
4915
+ 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);
4916
+ }).join(`
4917
+ ${n ? `${t("yellow", d2)} ` : ""}`)}
4918
+ ${a}
4919
+ `;
4920
+ }
4921
+ default: {
4922
+ const a = this.options.map(($2, y2, p2) => {
4923
+ 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;
4924
+ let h = "";
4925
+ 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(`
4926
+ `) ? " " : ""}${h}`;
4927
+ }).join(`
4928
+ ${n ? t("cyan", d2) : ""}`), l = a.startsWith(`
4929
+ `) ? "" : " ";
4930
+ return `${o}${n ? t("cyan", d2) : ""}${l}${a}
4931
+ ${n ? t("cyan", E2) : ""}
4932
+ `;
4933
+ }
4934
+ }
4935
+ } }).prompt();
4936
+ };
4937
+ var O2 = { message: (e = [], { symbol: i = t("gray", d2), secondarySymbol: s = t("gray", d2), output: r = process.stdout, spacing: u2 = 1, withGuide: n } = {}) => {
4938
+ const o = [], c2 = n ?? u.withGuide, a = c2 ? s : "", l = c2 ? `${i} ` : "", $2 = c2 ? `${s} ` : "";
4939
+ for (let p2 = 0; p2 < u2; p2++) o.push(a);
4940
+ const y2 = Array.isArray(e) ? e : e.split(`
4941
+ `);
4942
+ if (y2.length > 0) {
4943
+ const [p2, ...m] = y2;
4944
+ p2.length > 0 ? o.push(`${l}${p2}`) : o.push(c2 ? i : "");
4945
+ for (const g of m) g.length > 0 ? o.push(`${$2}${g}`) : o.push(c2 ? s : "");
4946
+ }
4947
+ r.write(`${o.join(`
4948
+ `)}
4949
+ `);
4950
+ }, info: (e, i) => {
4951
+ O2.message(e, { ...i, symbol: t("blue", he) });
4952
+ }, success: (e, i) => {
4953
+ O2.message(e, { ...i, symbol: t("green", pe) });
4954
+ }, step: (e, i) => {
4955
+ O2.message(e, { ...i, symbol: t("green", F2) });
4956
+ }, warn: (e, i) => {
4957
+ O2.message(e, { ...i, symbol: t("yellow", me) });
4958
+ }, warning: (e, i) => {
4959
+ O2.warn(e, i);
4960
+ }, error: (e, i) => {
4961
+ O2.message(e, { ...i, symbol: t("red", ge) });
4962
+ } };
4963
+ var pt = (e = "", i) => {
4964
+ const s = i?.output ?? process.stdout, r = i?.withGuide ?? u.withGuide ? `${t("gray", E2)} ` : "";
4965
+ s.write(`${r}${t("red", e)}
4966
+
4967
+ `);
4968
+ };
4969
+ var mt = (e = "", i) => {
4970
+ const s = i?.output ?? process.stdout, r = i?.withGuide ?? u.withGuide ? `${t("gray", le)} ` : "";
4971
+ s.write(`${r}${e}
4972
+ `);
4973
+ };
4974
+ var gt = (e = "", i) => {
4975
+ const s = i?.output ?? process.stdout, r = i?.withGuide ?? u.withGuide ? `${t("gray", d2)}
4976
+ ${t("gray", E2)} ` : "";
4977
+ s.write(`${r}${e}
4978
+
4979
+ `);
4980
+ };
4981
+ var Q2 = (e, i) => e.split(`
4982
+ `).map((s) => i(s)).join(`
4983
+ `);
4984
+ var yt = (e) => {
4985
+ const i = (r, u2) => {
4986
+ const n = r.label ?? String(r.value);
4987
+ 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))}`;
4988
+ }, s = e.required ?? true;
4989
+ 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) {
4990
+ if (s && (r === void 0 || r.length === 0)) return `Please select at least one option.
4991
+ ${t("reset", t("dim", `Press ${t(["gray", "bgWhite", "inverse"], " space ")} to select, ${t("gray", t("bgWhite", t("inverse", " enter ")))} to submit`))}`;
4992
+ }, render() {
4993
+ const r = e.withGuide ?? u.withGuide, u2 = R(e.output, e.message, r ? `${ye(this.state)} ` : "", `${V2(this.state)} `), n = `${r ? `${t("gray", d2)}
4994
+ ` : ""}${u2}
4995
+ `, o = this.value ?? [], c2 = (a, l) => {
4996
+ if (a.disabled) return i(a, "disabled");
4997
+ const $2 = o.includes(a.value);
4998
+ return l && $2 ? i(a, "active-selected") : $2 ? i(a, "selected") : i(a, l ? "active" : "inactive");
4999
+ };
5000
+ switch (this.state) {
5001
+ case "submit": {
5002
+ 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)} ` : "");
5003
+ return `${n}${l}`;
5004
+ }
5005
+ case "cancel": {
5006
+ const a = this.options.filter(({ value: $2 }) => o.includes($2)).map(($2) => i($2, "cancelled")).join(t("dim", ", "));
5007
+ if (a.trim() === "") return `${n}${t("gray", d2)}`;
5008
+ const l = R(e.output, a, r ? `${t("gray", d2)} ` : "");
5009
+ return `${n}${l}${r ? `
5010
+ ${t("gray", d2)}` : ""}`;
5011
+ }
5012
+ case "error": {
5013
+ const a = r ? `${t("yellow", d2)} ` : "", l = this.error.split(`
5014
+ `).map((p2, m) => m === 0 ? `${r ? `${t("yellow", E2)} ` : ""}${t("yellow", p2)}` : ` ${p2}`).join(`
5015
+ `), $2 = n.split(`
5016
+ `).length, y2 = l.split(`
5017
+ `).length + 1;
5018
+ 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(`
5019
+ ${a}`)}
5020
+ ${l}
5021
+ `;
5022
+ }
5023
+ default: {
5024
+ const a = r ? `${t("cyan", d2)} ` : "", l = n.split(`
5025
+ `).length, $2 = r ? 2 : 1;
5026
+ 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(`
5027
+ ${a}`)}
5028
+ ${r ? t("cyan", E2) : ""}
5029
+ `;
5030
+ }
5031
+ }
5032
+ } }).prompt();
5033
+ };
5034
+ var ft = (e) => t("dim", e);
5035
+ var vt = (e, i, s) => {
5036
+ const r = { hard: true, trim: false }, u2 = wrapAnsi(e, i, r).split(`
5037
+ `), 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);
5038
+ return wrapAnsi(e, c2, r);
5039
+ };
5040
+ var wt = (e = "", i = "", s) => {
5041
+ const r = s?.output ?? P2.stdout, u2 = s?.withGuide ?? u.withGuide, n = s?.format ?? ft, o = ["", ...vt(e, O(r) - 6, n).split(`
5042
+ `).map(n), ""], c2 = dist_default2(i), a = Math.max(o.reduce((p2, m) => {
5043
+ const g = dist_default2(m);
5044
+ return g > p2 ? g : p2;
5045
+ }, 0), c2) + 2, l = o.map((p2) => `${t("gray", d2)} ${p2}${" ".repeat(a - dist_default2(p2))}${t("gray", d2)}`).join(`
5046
+ `), $2 = u2 ? `${t("gray", d2)}
5047
+ ` : "", y2 = u2 ? Ge : de;
5048
+ r.write(`${$2}${t("green", F2)} ${t("reset", i)} ${t("gray", se.repeat(Math.max(a - c2 - 1, 1)) + ce)}
5049
+ ${l}
5050
+ ${t("gray", y2 + se.repeat(a + 2) + $e)}
5051
+ `);
5052
+ };
5053
+ var bt = (e) => new rt({ validate: e.validate, mask: e.mask ?? xe, signal: e.signal, input: e.input, output: e.output, render() {
5054
+ const i = e.withGuide ?? u.withGuide, s = `${i ? `${t("gray", d2)}
5055
+ ` : ""}${V2(this.state)} ${e.message}
5056
+ `, r = this.userInputWithCursor, u2 = this.masked;
5057
+ switch (this.state) {
5058
+ case "error": {
5059
+ const n = i ? `${t("yellow", d2)} ` : "", o = i ? `${t("yellow", E2)} ` : "", c2 = u2 ?? "";
5060
+ return e.clearOnError && this.clear(), `${s.trim()}
5061
+ ${n}${c2}
5062
+ ${o}${t("yellow", this.error)}
5063
+ `;
5064
+ }
5065
+ case "submit": {
5066
+ const n = i ? `${t("gray", d2)} ` : "", o = u2 ? t("dim", u2) : "";
5067
+ return `${s}${n}${o}`;
5068
+ }
5069
+ case "cancel": {
5070
+ const n = i ? `${t("gray", d2)} ` : "", o = u2 ? t(["strikethrough", "dim"], u2) : "";
5071
+ return `${s}${n}${o}${u2 && i ? `
5072
+ ${t("gray", d2)}` : ""}`;
5073
+ }
5074
+ default: {
5075
+ const n = i ? `${t("cyan", d2)} ` : "", o = i ? t("cyan", E2) : "";
5076
+ return `${s}${n}${r}
5077
+ ${o}
5078
+ `;
5079
+ }
5080
+ }
5081
+ } }).prompt();
5082
+ var St = (e) => {
5083
+ const i = e.validate;
5084
+ return Ae({ ...e, initialUserInput: e.initialValue ?? e.root ?? process.cwd(), maxItems: 5, validate(s) {
5085
+ if (!Array.isArray(s)) {
5086
+ if (!s) return "Please select a path";
5087
+ if (i) return i(s);
5088
+ }
5089
+ }, options() {
5090
+ const s = this.userInput;
5091
+ if (s === "") return [];
5092
+ try {
5093
+ let r;
5094
+ Xe(s) ? we(s).isDirectory() && (!e.directory || s.endsWith("/")) ? r = s : r = be(s) : r = be(s);
5095
+ const u2 = s.length > 1 && s.endsWith("/") ? s.slice(0, -1) : s;
5096
+ return ze(r).map((n) => {
5097
+ const o = Qe(r, n), c2 = we(o);
5098
+ return { name: n, path: o, isDirectory: c2.isDirectory() };
5099
+ }).filter(({ path: n, isDirectory: o }) => n.startsWith(u2) && (o || !e.directory)).map((n) => ({ value: n.path }));
5100
+ } catch {
5101
+ return [];
5102
+ }
5103
+ } });
5104
+ };
5105
+ var Ct = (e) => t("magenta", e);
5106
+ 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 } = {}) => {
5107
+ const l = ae();
5108
+ let $2, y2, p2 = false, m = false, g = "", S2, h = performance.now();
5109
+ const f = O(s), v = a?.styleFrame ?? Ct, T2 = (_2) => {
5110
+ const A2 = _2 > 1 ? u2 ?? u.messages.error : r ?? u.messages.cancel;
5111
+ m = _2 === 1, p2 && (W2(A2, _2), m && typeof i == "function" && i());
5112
+ }, C2 = () => T2(2), b = () => T2(1), x = () => {
5113
+ 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);
5114
+ }, G2 = () => {
5115
+ 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);
5116
+ }, M2 = () => {
5117
+ if (S2 === void 0) return;
5118
+ l && s.write(`
5119
+ `);
5120
+ const _2 = wrapAnsi(S2, f, { hard: true, trim: false }).split(`
5121
+ `);
5122
+ _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());
5123
+ }, R2 = (_2) => _2.replace(/\.+$/, ""), j2 = (_2) => {
5124
+ const A2 = (performance.now() - _2) / 1e3, k2 = Math.floor(A2 / 60), L2 = Math.floor(A2 % 60);
5125
+ return k2 > 0 ? `[${k2}m ${L2}s]` : `[${L2}s]`;
5126
+ }, D2 = a.withGuide ?? u.withGuide, ie = (_2 = "") => {
5127
+ p2 = true, $2 = z({ output: s }), g = R2(_2), h = performance.now(), D2 && s.write(`${t("gray", d2)}
5128
+ `);
5129
+ let A2 = 0, k2 = 0;
5130
+ x(), y2 = setInterval(() => {
5131
+ if (l && g === S2) return;
5132
+ M2(), S2 = g;
5133
+ const L2 = v(n[A2]);
5134
+ let Z2;
5135
+ if (l) Z2 = `${L2} ${g}...`;
5136
+ else if (e === "timer") Z2 = `${L2} ${g} ${j2(h)}`;
5137
+ else {
5138
+ const Be = ".".repeat(Math.floor(k2)).slice(0, 3);
5139
+ Z2 = `${L2} ${g}${Be}`;
5140
+ }
5141
+ const Ne = wrapAnsi(Z2, f, { hard: true, trim: false });
5142
+ s.write(Ne), A2 = A2 + 1 < n.length ? A2 + 1 : 0, k2 = k2 < 4 ? k2 + 0.125 : 0;
5143
+ }, o);
5144
+ }, W2 = (_2 = "", A2 = 0, k2 = false) => {
5145
+ if (!p2) return;
5146
+ p2 = false, clearInterval(y2), M2();
5147
+ const L2 = A2 === 0 ? t("green", F2) : A2 === 1 ? t("red", oe) : t("red", ue);
5148
+ g = _2 ?? g, k2 || (e === "timer" ? s.write(`${L2} ${g} ${j2(h)}
5149
+ `) : s.write(`${L2} ${g}
5150
+ `)), G2(), $2();
5151
+ };
5152
+ return { start: ie, stop: (_2 = "") => W2(_2, 0), message: (_2 = "") => {
5153
+ g = R2(_2 ?? g);
5154
+ }, cancel: (_2 = "") => W2(_2, 1), error: (_2 = "") => W2(_2, 2), clear: () => W2("", 0, true), get isCancelled() {
5155
+ return m;
5156
+ } };
5157
+ };
5158
+ var Ve = { light: w2("\u2500", "-"), heavy: w2("\u2501", "="), block: w2("\u2588", "#") };
5159
+ function Tt({ style: e = "heavy", max: i = 100, size: s = 40, ...r } = {}) {
5160
+ const u2 = fe(r);
5161
+ let n = 0, o = "";
5162
+ const c2 = Math.max(1, i), a = Math.max(1, s), l = (m) => {
5163
+ switch (m) {
5164
+ case "initial":
5165
+ case "active":
5166
+ return (g) => t("magenta", g);
5167
+ case "error":
5168
+ case "cancel":
5169
+ return (g) => t("red", g);
5170
+ case "submit":
5171
+ return (g) => t("green", g);
5172
+ default:
5173
+ return (g) => t("magenta", g);
5174
+ }
5175
+ }, $2 = (m, g) => {
5176
+ const S2 = Math.floor(n / c2 * a);
5177
+ return `${l(m)(Ve[e].repeat(S2))}${t("dim", Ve[e].repeat(a - S2))} ${g}`;
5178
+ }, y2 = (m = "") => {
5179
+ o = m, u2.start($2("initial", m));
5180
+ }, p2 = (m = 1, g) => {
5181
+ n = Math.min(c2, m + n), u2.message($2("active", g ?? o)), o = g ?? o;
5182
+ };
5183
+ 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) };
5184
+ }
5185
+ var re = (e, i) => e.includes(`
5186
+ `) ? e.split(`
5187
+ `).map((s) => i(s)).join(`
5188
+ `) : i(e);
5189
+ var _t = (e) => {
5190
+ const i = (s, r) => {
5191
+ const u2 = s.label ?? String(s.value);
5192
+ switch (r) {
5193
+ case "disabled":
5194
+ return `${t("gray", H2)} ${re(u2, (n) => t("gray", n))}${s.hint ? ` ${t("dim", `(${s.hint ?? "disabled"})`)}` : ""}`;
5195
+ case "selected":
5196
+ return `${re(u2, (n) => t("dim", n))}`;
5197
+ case "active":
5198
+ return `${t("green", z2)} ${u2}${s.hint ? ` ${t("dim", `(${s.hint})`)}` : ""}`;
5199
+ case "cancelled":
5200
+ return `${re(u2, (n) => t(["strikethrough", "dim"], n))}`;
5201
+ default:
5202
+ return `${t("dim", H2)} ${re(u2, (n) => t("dim", n))}`;
5203
+ }
5204
+ };
5205
+ return new nt({ options: e.options, signal: e.signal, input: e.input, output: e.output, initialValue: e.initialValue, render() {
5206
+ 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)}
5207
+ ` : ""}${n}
5208
+ `;
5209
+ switch (this.state) {
5210
+ case "submit": {
5211
+ const c2 = s ? `${t("gray", d2)} ` : "", a = R(e.output, i(this.options[this.cursor], "selected"), c2);
5212
+ return `${o}${a}`;
5213
+ }
5214
+ case "cancel": {
5215
+ const c2 = s ? `${t("gray", d2)} ` : "", a = R(e.output, i(this.options[this.cursor], "cancelled"), c2);
5216
+ return `${o}${a}${s ? `
5217
+ ${t("gray", d2)}` : ""}`;
5218
+ }
5219
+ default: {
5220
+ const c2 = s ? `${t("cyan", d2)} ` : "", a = s ? t("cyan", E2) : "", l = o.split(`
5221
+ `).length, $2 = s ? 2 : 1;
5222
+ 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(`
5223
+ ${c2}`)}
5224
+ ${a}
5225
+ `;
5226
+ }
5227
+ }
5228
+ } }).prompt();
5229
+ };
5230
+ var It = (e) => {
5231
+ const i = (s, r = "inactive") => {
5232
+ const u2 = s.label ?? String(s.value);
5233
+ 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})`)}` : ""}`;
5234
+ };
5235
+ return new ot({ options: e.options, signal: e.signal, input: e.input, output: e.output, initialValue: e.initialValue, caseSensitive: e.caseSensitive, render() {
5236
+ const s = e.withGuide ?? u.withGuide, r = `${s ? `${t("gray", d2)}
5237
+ ` : ""}${V2(this.state)} ${e.message}
5238
+ `;
5239
+ switch (this.state) {
5240
+ case "submit": {
5241
+ 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);
5242
+ return `${r}${o}`;
5243
+ }
5244
+ case "cancel": {
5245
+ const u2 = s ? `${t("gray", d2)} ` : "", n = R(e.output, i(this.options[0], "cancelled"), u2);
5246
+ return `${r}${n}${s ? `
5247
+ ${t("gray", d2)}` : ""}`;
5248
+ }
5249
+ default: {
5250
+ 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(`
5251
+ `);
5252
+ return `${r}${o}
5253
+ ${n}
5254
+ `;
5255
+ }
5256
+ }
5257
+ } }).prompt();
5258
+ };
5259
+ var je = `${t("gray", d2)} `;
5260
+ var K2 = { message: async (e, { symbol: i = t("gray", d2) } = {}) => {
5261
+ process.stdout.write(`${t("gray", d2)}
5262
+ ${i} `);
5263
+ let s = 3;
5264
+ for await (let r of e) {
5265
+ r = r.replace(/\n/g, `
5266
+ ${je}`), r.includes(`
5267
+ `) && (s = 3 + ne(r.slice(r.lastIndexOf(`
5268
+ `))).length);
5269
+ const u2 = ne(r).length;
5270
+ s + u2 < process.stdout.columns ? (s += u2, process.stdout.write(r)) : (process.stdout.write(`
5271
+ ${je}${r.trimStart()}`), s = 3 + ne(r.trimStart()).length);
5272
+ }
5273
+ process.stdout.write(`
5274
+ `);
5275
+ }, 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) }) };
5276
+ var Et = async (e, i) => {
5277
+ for (const s of e) {
5278
+ if (s.enabled === false) continue;
5279
+ const r = fe(i);
5280
+ r.start(s.title);
5281
+ const u2 = await s.task(r.message);
5282
+ r.stop(u2 || s.title);
5283
+ }
5284
+ };
5285
+ var xt = (e) => e.replace(/\x1b\[(?:\d+;)*\d*[ABCDEFGHfJKSTsu]|\x1b\[(s|u)/g, "");
5286
+ var Gt = (e) => {
5287
+ 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);
5288
+ i.write(`${r}
5289
+ `), i.write(`${t("green", F2)} ${e.title}
5290
+ `);
5291
+ for (let h = 0; h < u2; h++) i.write(`${r}
5292
+ `);
5293
+ const a = [{ value: "", full: "" }];
5294
+ let l = false;
5295
+ const $2 = (h) => {
5296
+ if (a.length === 0) return;
5297
+ let f = 0;
5298
+ h && (f += u2 + 2);
5299
+ for (const v of a) {
5300
+ const { value: T2, result: C2 } = v;
5301
+ let b = C2?.message ?? T2;
5302
+ if (b.length === 0) continue;
5303
+ C2 === void 0 && v.header !== void 0 && v.header !== "" && (b += `
5304
+ ${v.header}`);
5305
+ const x = b.split(`
5306
+ `).reduce((G2, M2) => M2 === "" ? G2 + 1 : G2 + Math.ceil((M2.length + n) / s), 0);
5307
+ f += x;
5308
+ }
5309
+ f > 0 && (f += 1, i.write(import_sisteransi2.erase.lines(f)));
5310
+ }, y2 = (h, f, v) => {
5311
+ const T2 = v ? `${h.full}
5312
+ ${h.value}` : h.value;
5313
+ h.header !== void 0 && h.header !== "" && O2.message(h.header.split(`
5314
+ `).map((C2) => t("bold", C2)), { output: i, secondarySymbol: r, symbol: r, spacing: 0 }), O2.message(T2.split(`
5315
+ `).map((C2) => t("dim", C2)), { output: i, secondarySymbol: r, symbol: r, spacing: f ?? u2 });
5316
+ }, p2 = () => {
5317
+ for (const h of a) {
5318
+ const { header: f, value: v, full: T2 } = h;
5319
+ (f === void 0 || f.length === 0) && v.length === 0 || y2(h, void 0, o === true && T2.length > 0);
5320
+ }
5321
+ }, m = (h, f, v) => {
5322
+ if ($2(false), (v?.raw !== true || !l) && h.value !== "" && (h.value += `
5323
+ `), h.value += xt(f), l = v?.raw === true, e.limit !== void 0) {
5324
+ const T2 = h.value.split(`
5325
+ `), C2 = T2.length - e.limit;
5326
+ if (C2 > 0) {
5327
+ const b = T2.splice(0, C2);
5328
+ o && (h.full += (h.full === "" ? "" : `
5329
+ `) + b.join(`
5330
+ `));
5331
+ }
5332
+ h.value = T2.join(`
5333
+ `);
5334
+ }
5335
+ c2 && g();
5336
+ }, g = () => {
5337
+ 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);
5338
+ }, S2 = (h, f) => {
5339
+ $2(false), h.result = f, c2 && g();
5340
+ };
5341
+ return { message(h, f) {
5342
+ m(a[0], h, f);
5343
+ }, group(h) {
5344
+ const f = { header: h, value: "", full: "" };
5345
+ return a.push(f), { message(v, T2) {
5346
+ m(f, v, T2);
5347
+ }, error(v) {
5348
+ S2(f, { status: "error", message: v });
5349
+ }, success(v) {
5350
+ S2(f, { status: "success", message: v });
5351
+ } };
5352
+ }, error(h, f) {
5353
+ $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 = "";
5354
+ }, success(h, f) {
5355
+ $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 = "";
5356
+ } };
5357
+ };
5358
+ 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() {
5359
+ const i = e?.withGuide ?? u.withGuide, s = `${`${i ? `${t("gray", d2)}
5360
+ ` : ""}${V2(this.state)} `}${e.message}
5361
+ `, 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 ?? "";
5362
+ switch (this.state) {
5363
+ case "error": {
5364
+ const o = this.error ? ` ${t("yellow", this.error)}` : "", c2 = i ? `${t("yellow", d2)} ` : "", a = i ? t("yellow", E2) : "";
5365
+ return `${s.trim()}
5366
+ ${c2}${u2}
5367
+ ${a}${o}
5368
+ `;
5369
+ }
5370
+ case "submit": {
5371
+ const o = n ? ` ${t("dim", n)}` : "", c2 = i ? t("gray", d2) : "";
5372
+ return `${s}${c2}${o}`;
5373
+ }
5374
+ case "cancel": {
5375
+ const o = n ? ` ${t(["strikethrough", "dim"], n)}` : "", c2 = i ? t("gray", d2) : "";
5376
+ return `${s}${c2}${o}${n.trim() ? `
5377
+ ${c2}` : ""}`;
5378
+ }
5379
+ default: {
5380
+ const o = i ? `${t("cyan", d2)} ` : "", c2 = i ? t("cyan", E2) : "";
5381
+ return `${s}${o}${u2}
5382
+ ${c2}
5383
+ `;
5384
+ }
5385
+ }
5386
+ } }).prompt();
5387
+
5388
+ // src/prompt.ts
5389
+ function isCancel(value) {
5390
+ return q(value);
5391
+ }
5392
+ function cancelAndExit() {
5393
+ pt("Setup cancelled.");
5394
+ process.exit(0);
5395
+ }
5396
+
5397
+ // src/commands/setup.ts
5398
+ var execAsync = promisify2(exec2);
5399
+ var VALID_PRESETS = ["vscode", "claude", "copilot", "cursor", "windsurf", "jetbrains"];
5400
+ var PRESET_DEFAULTS = {
5401
+ vscode: { ide: ["vscode"] },
5402
+ jetbrains: { ide: ["jetbrains"] },
5403
+ claude: { tools: ["claude-code"] },
5404
+ copilot: { tools: ["copilot"] },
5405
+ cursor: { tools: ["cursor"] },
5406
+ windsurf: { tools: ["windsurf"] }
5407
+ };
5408
+ var PRESET_LABELS = {
5409
+ vscode: "VS Code",
5410
+ jetbrains: "JetBrains",
5411
+ claude: "Claude Code",
5412
+ copilot: "GitHub Copilot",
5413
+ cursor: "Cursor",
5414
+ windsurf: "Windsurf"
5415
+ };
5416
+ var JETBRAINS_PLUGIN_URL = "https://plugins.jetbrains.com/plugin/30449-keepgoing";
5417
+ var JETBRAINS_PLUGIN_ID = "com.keepgoing.plugin";
5418
+ var JETBRAINS_IDES = [
5419
+ { app: "IntelliJ IDEA.app", label: "IntelliJ IDEA Ultimate" },
5420
+ { app: "IntelliJ IDEA CE.app", label: "IntelliJ IDEA Community" },
5421
+ { app: "WebStorm.app", label: "WebStorm" },
5422
+ { app: "PyCharm.app", label: "PyCharm Professional" },
5423
+ { app: "PyCharm CE.app", label: "PyCharm Community" },
5424
+ { app: "GoLand.app", label: "GoLand" },
5425
+ { app: "PhpStorm.app", label: "PhpStorm" },
5426
+ { app: "Rider.app", label: "Rider" },
5427
+ { app: "RubyMine.app", label: "RubyMine" },
5428
+ { app: "CLion.app", label: "CLion" },
5429
+ { app: "DataGrip.app", label: "DataGrip" },
5430
+ { app: "Android Studio.app", label: "Android Studio" }
5431
+ ];
5432
+ function detectJetBrainsIdes() {
5433
+ if (process.platform !== "darwin") return [];
5434
+ return JETBRAINS_IDES.filter((ide) => {
5435
+ try {
5436
+ return fs10.statSync(path14.join("/Applications", ide.app)).isDirectory();
5437
+ } catch {
5438
+ return false;
5439
+ }
5440
+ });
5441
+ }
5442
+ async function setupCommand(options) {
5443
+ const displayPath = options.cwd.startsWith(os7.homedir()) ? "~" + options.cwd.slice(os7.homedir().length) : options.cwd;
5444
+ const presetDefaults = options.preset ? PRESET_DEFAULTS[options.preset] : void 0;
5445
+ const presetLabel = options.preset ? PRESET_LABELS[options.preset] : void 0;
5446
+ dist_exports.intro(presetLabel ? `KeepGoing Setup - ${presetLabel}` : "KeepGoing Setup Wizard");
5447
+ dist_exports.log.info(`Project: ${displayPath}`);
5448
+ if (presetLabel) {
5449
+ dist_exports.log.info(`Preset: ${presetLabel}`);
5450
+ }
5451
+ const scope = await dist_exports.select({
5452
+ message: "Setup scope",
5453
+ options: [
5454
+ { label: "This project only", hint: ".claude/settings.json", value: "project" },
5455
+ { label: "All projects (global)", hint: "~/.claude/settings.json", value: "user" }
5456
+ ]
5457
+ });
5458
+ if (isCancel(scope)) cancelAndExit();
5459
+ let tools;
5460
+ if (presetDefaults?.tools) {
5461
+ tools = presetDefaults.tools;
5462
+ dist_exports.log.step(`AI tool: ${tools.map((t2) => t2 === "claude-code" ? "Claude Code" : t2.charAt(0).toUpperCase() + t2.slice(1)).join(", ")}`);
5463
+ const addMore = await dist_exports.multiselect({
5464
+ message: "Also configure any of these?",
5465
+ options: [
5466
+ ...!tools.includes("claude-code") ? [{ label: "Claude Code", value: "claude-code" }] : [],
5467
+ ...!tools.includes("copilot") ? [{ label: "GitHub Copilot", value: "copilot" }] : [],
5468
+ ...!tools.includes("cursor") ? [{ label: "Cursor", value: "cursor" }] : [],
5469
+ ...!tools.includes("windsurf") ? [{ label: "Windsurf", value: "windsurf" }] : []
5470
+ ],
5471
+ required: false
5472
+ });
5473
+ if (!isCancel(addMore) && addMore.length > 0) {
5474
+ tools = [...tools, ...addMore];
5475
+ }
5476
+ } else {
5477
+ const toolsAnswer = await dist_exports.multiselect({
5478
+ message: "Which AI coding tools do you use?",
5479
+ options: [
5480
+ { label: "Claude Code", value: "claude-code" },
5481
+ { label: "GitHub Copilot", value: "copilot" },
5482
+ { label: "Cursor", value: "cursor" },
5483
+ { label: "Windsurf", value: "windsurf" }
5484
+ ],
5485
+ required: true
5486
+ });
5487
+ if (isCancel(toolsAnswer)) cancelAndExit();
5488
+ tools = toolsAnswer;
5489
+ }
5490
+ let claudePlugin = false;
5491
+ if (tools.includes("claude-code")) {
5492
+ const pluginAnswer = await dist_exports.select({
5493
+ message: "How do you want to set up Claude Code?",
5494
+ initialValue: "plugin",
5495
+ options: [
5496
+ { label: "Plugin (recommended)", hint: "auto-hooks, skills, one command to install", value: "plugin" },
5497
+ { label: "Manual", hint: "write hooks + MCP registration yourself", value: "manual" }
5498
+ ]
5499
+ });
5500
+ if (isCancel(pluginAnswer)) cancelAndExit();
5501
+ claudePlugin = pluginAnswer === "plugin";
5502
+ }
5503
+ let ide;
5504
+ if (presetDefaults?.ide) {
5505
+ ide = presetDefaults.ide;
5506
+ dist_exports.log.step(`IDE: ${ide.map((i) => i === "vscode" ? "VS Code" : i === "jetbrains" ? "JetBrains" : "Terminal").join(", ")}`);
5507
+ const addMoreIde = await dist_exports.multiselect({
5508
+ message: "Also configure any of these?",
5509
+ options: [
5510
+ ...!ide.includes("vscode") ? [{ label: "VS Code", value: "vscode" }] : [],
5511
+ ...!ide.includes("jetbrains") ? [{ label: "JetBrains", hint: "IntelliJ, WebStorm, PyCharm, etc.", value: "jetbrains" }] : [],
5512
+ ...!ide.includes("terminal") ? [{ label: "Terminal only / other", value: "terminal" }] : []
5513
+ ],
5514
+ required: false
5515
+ });
5516
+ if (!isCancel(addMoreIde) && addMoreIde.length > 0) {
5517
+ ide = [...ide, ...addMoreIde];
5518
+ }
5519
+ } else {
5520
+ const ideAnswer = await dist_exports.multiselect({
5521
+ message: "Which IDE(s) do you use?",
5522
+ options: [
5523
+ { label: "VS Code", value: "vscode" },
5524
+ { label: "JetBrains", hint: "IntelliJ, WebStorm, PyCharm, etc.", value: "jetbrains" },
5525
+ { label: "Terminal only / other", value: "terminal" }
5526
+ ],
5527
+ required: true
5528
+ });
5529
+ if (isCancel(ideAnswer)) cancelAndExit();
5530
+ ide = ideAnswer;
5531
+ }
5532
+ const shellInfo = detectShellInfo();
5533
+ let installShellHook = false;
5534
+ if (shellInfo) {
5535
+ const hookAnswer = await dist_exports.confirm({
5536
+ message: `Install shell hook for ${shellInfo.shell}?`,
5537
+ initialValue: true,
5538
+ active: `Yes (adds to ${shellInfo.rcFile})`,
5539
+ inactive: "No"
5540
+ });
5541
+ if (isCancel(hookAnswer)) cancelAndExit();
5542
+ installShellHook = hookAnswer;
5543
+ } else {
5544
+ dist_exports.log.warn("Shell hook skipped (could not detect shell)");
5545
+ }
5546
+ const hasLicense = await dist_exports.confirm({
5547
+ message: "Do you have a Pro license key?",
5548
+ initialValue: false
5549
+ });
5550
+ if (isCancel(hasLicense)) cancelAndExit();
5551
+ const s = dist_exports.spinner();
5552
+ s.start("Configuring...");
5553
+ const results = [];
5554
+ let licensed = false;
5555
+ function classifySetupMessage(msg) {
5556
+ if (msg.startsWith("Warning")) return "warn";
5557
+ if (msg.includes("skipped") || msg.includes("Already")) return "message";
5558
+ return "success";
5559
+ }
5560
+ if (tools.includes("claude-code")) {
5561
+ if (claudePlugin) {
5562
+ const setupResult = setupProject({
5563
+ workspacePath: options.cwd,
5564
+ scope,
5565
+ sessionHooks: false
5566
+ });
5567
+ for (const msg of setupResult.messages) {
5568
+ results.push({ level: classifySetupMessage(msg), text: `Claude Code: ${msg}` });
5569
+ }
5570
+ 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" });
5571
+ } else {
5572
+ const setupResult = setupProject({
5573
+ workspacePath: options.cwd,
5574
+ scope,
5575
+ sessionHooks: true
5576
+ });
5577
+ for (const msg of setupResult.messages) {
5578
+ results.push({ level: classifySetupMessage(msg), text: `Claude Code: ${msg}` });
5579
+ }
5580
+ if (isClaudeCodeInstalled()) {
5581
+ s.message("Registering Claude Code MCP server...");
5582
+ const mcpResult = await registerClaudeCodeMcp(options.cwd);
5583
+ results.push({
5584
+ level: mcpResult.action === "created" ? "success" : "message",
5585
+ text: `Claude Code: ${mcpResult.message}`
5586
+ });
5587
+ } else {
5588
+ 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" });
5589
+ }
5590
+ }
5591
+ }
5592
+ if (tools.includes("copilot")) {
5593
+ const mcpResult = registerCopilotMcp(options.cwd);
5594
+ results.push({ level: mcpResult.action === "created" ? "success" : "message", text: `Copilot: ${mcpResult.message}` });
5595
+ const instrResult = writeCopilotInstructions(options.cwd);
5596
+ results.push({ level: instrResult.action === "created" ? "success" : "message", text: `Copilot: ${instrResult.message}` });
5597
+ }
5598
+ if (tools.includes("cursor")) {
5599
+ const result = registerCursorMcp();
5600
+ results.push({ level: result.action === "created" ? "success" : "message", text: `Cursor: ${result.message}` });
5601
+ }
5602
+ if (tools.includes("windsurf")) {
5603
+ const result = registerWindsurfMcp();
5604
+ results.push({ level: result.action === "created" ? "success" : "message", text: `Windsurf: ${result.message}` });
5605
+ }
5606
+ if (installShellHook) {
5607
+ const hookResult = performHookInstall();
5608
+ results.push({ level: hookResult.message.includes("already") ? "message" : "success", text: `Shell: ${hookResult.message}` });
5609
+ const gitignoreResult = performGlobalGitignore();
5610
+ results.push({ level: gitignoreResult.message.includes("already") ? "message" : "success", text: `Gitignore: ${gitignoreResult.message}` });
5611
+ const postCommitResult = performPostCommitHook();
5612
+ results.push({ level: postCommitResult.message.includes("already") ? "message" : "success", text: `Post-commit: ${postCommitResult.message}` });
5613
+ }
5614
+ s.stop("Configuration complete");
5615
+ const DIM5 = "\x1B[2m";
5616
+ const RESET5 = "\x1B[0m";
5617
+ for (const r of results) {
5618
+ if (r.level === "message") {
5619
+ dist_exports.log.message(`${DIM5}${r.text}${RESET5}`);
5620
+ } else {
5621
+ dist_exports.log[r.level](r.text);
5622
+ }
5623
+ }
5624
+ if (ide.includes("vscode")) {
5625
+ const installVscode = await dist_exports.confirm({
5626
+ message: "Install VS Code extension now?",
5627
+ initialValue: true,
5628
+ active: "Yes",
5629
+ inactive: "No, I'll do it later"
5630
+ });
5631
+ if (!isCancel(installVscode) && installVscode) {
5632
+ try {
5633
+ execSync3("code --install-extension keepgoing-dev.keepgoing", { stdio: "pipe" });
5634
+ dist_exports.log.success("VS Code: KeepGoing extension installed");
5635
+ } catch {
5636
+ dist_exports.log.warn("VS Code: Could not install automatically. Run this manually:\n code --install-extension keepgoing-dev.keepgoing");
5637
+ }
5638
+ } else {
5639
+ dist_exports.log.info("VS Code: Install later by running:\n code --install-extension keepgoing-dev.keepgoing");
5640
+ }
5641
+ }
5642
+ if (ide.includes("jetbrains")) {
5643
+ const detectedIdes = detectJetBrainsIdes();
5644
+ if (detectedIdes.length === 0) {
5645
+ dist_exports.log.info(`JetBrains: Install the KeepGoing plugin
5646
+ ${JETBRAINS_PLUGIN_URL}`);
5647
+ } else {
5648
+ const installJetbrains = await dist_exports.confirm({
5649
+ message: "Install JetBrains plugin now?",
5650
+ initialValue: true,
5651
+ active: "Yes",
5652
+ inactive: "No, I'll do it later"
5653
+ });
5654
+ if (isCancel(installJetbrains) || !installJetbrains) {
5655
+ dist_exports.log.info(`JetBrains: Install later from:
5656
+ ${JETBRAINS_PLUGIN_URL}`);
5657
+ } else {
5658
+ let selectedApps;
5659
+ if (detectedIdes.length === 1) {
5660
+ selectedApps = [detectedIdes[0].app];
5661
+ } else {
5662
+ const picked = await dist_exports.multiselect({
5663
+ message: "Which JetBrains IDEs should get the plugin?",
5664
+ options: detectedIdes.map((ide2) => ({ label: ide2.label, value: ide2.app })),
5665
+ required: true
5666
+ });
5667
+ if (isCancel(picked)) {
5668
+ dist_exports.log.info(`JetBrains: Install later from:
5669
+ ${JETBRAINS_PLUGIN_URL}`);
5670
+ selectedApps = [];
5671
+ } else {
5672
+ selectedApps = picked;
5673
+ }
5674
+ }
5675
+ if (selectedApps.length > 0) {
5676
+ const runningApps = selectedApps.filter((app) => {
5677
+ try {
5678
+ const result = execSync3(`pgrep -f "${app.replace(".app", "")}"`, { stdio: "pipe" }).toString();
5679
+ return result.trim().length > 0;
5680
+ } catch {
5681
+ return false;
5682
+ }
5683
+ });
5684
+ let proceed = true;
5685
+ if (runningApps.length > 0) {
5686
+ const runningLabels = runningApps.map((app) => JETBRAINS_IDES.find((i) => i.app === app)?.label ?? app).join(", ");
5687
+ dist_exports.log.warn(`Please close ${runningLabels} before continuing.`);
5688
+ const ready = await dist_exports.confirm({
5689
+ message: "IDE(s) closed and ready to install?",
5690
+ initialValue: true
5691
+ });
5692
+ if (isCancel(ready) || !ready) {
5693
+ dist_exports.log.info(`JetBrains: Install later from:
5694
+ ${JETBRAINS_PLUGIN_URL}`);
5695
+ proceed = false;
5696
+ }
5697
+ }
5698
+ if (proceed) {
5699
+ for (const app of selectedApps) {
5700
+ const label = JETBRAINS_IDES.find((i) => i.app === app)?.label ?? app;
5701
+ const is = dist_exports.spinner();
5702
+ is.start(`Installing plugin in ${label}...`);
5703
+ try {
5704
+ const binName = execSync3(
5705
+ `/usr/libexec/PlistBuddy -c "Print :CFBundleExecutable" "/Applications/${app}/Contents/Info.plist"`,
5706
+ { stdio: "pipe" }
5707
+ ).toString().trim();
5708
+ const { stdout, stderr } = await execAsync(
5709
+ `"/Applications/${app}/Contents/MacOS/${binName}" installPlugins ${JETBRAINS_PLUGIN_ID}`,
5710
+ { timeout: 6e4 }
5711
+ );
5712
+ const combined = (stdout || "") + (stderr || "");
5713
+ if (combined.includes("unknown plugins")) {
5714
+ is.stop(`${label}: Plugin not compatible with this IDE version`);
5715
+ dist_exports.log.warn(`Update your IDE or install manually:
5716
+ ${JETBRAINS_PLUGIN_URL}`);
5717
+ } else {
5718
+ is.stop(`${label}: KeepGoing plugin installed`);
5719
+ }
5720
+ } catch (err) {
5721
+ const combined = (err.stdout || "") + (err.stderr || "");
5722
+ if (combined.includes("unknown plugins")) {
5723
+ is.stop(`${label}: Plugin not compatible with this IDE version`);
5724
+ dist_exports.log.warn(`Update your IDE or install manually:
5725
+ ${JETBRAINS_PLUGIN_URL}`);
5726
+ } else {
5727
+ is.stop(`${label}: Could not install automatically`);
5728
+ dist_exports.log.warn(`Install from:
5729
+ ${JETBRAINS_PLUGIN_URL}`);
5730
+ }
5731
+ }
5732
+ }
5733
+ }
5734
+ }
5735
+ }
5736
+ }
5737
+ }
5738
+ if (hasLicense) {
5739
+ const key = await dist_exports.text({
5740
+ message: "Enter your license key",
5741
+ placeholder: "Decision Detection or Session Awareness key",
5742
+ validate: (val) => {
5743
+ if (!val.trim()) return "License key is required";
5744
+ }
5745
+ });
5746
+ if (!isCancel(key) && key) {
5747
+ const store = readLicenseStore();
5748
+ const existing = store.licenses.find(
5749
+ (l) => l.status === "active" && l.licenseKey === key
5750
+ );
5751
+ if (existing) {
5752
+ const label = getVariantLabel(existing.variantId);
5753
+ dist_exports.log.success(`${label} is already active.`);
5754
+ licensed = true;
5755
+ } else {
5756
+ const ls = dist_exports.spinner();
5757
+ ls.start("Activating license...");
5758
+ const result = await activateLicense(key, getDeviceId());
5759
+ if (result.valid) {
5760
+ const now = (/* @__PURE__ */ new Date()).toISOString();
5761
+ addLicenseEntry({
5762
+ licenseKey: result.licenseKey || key,
5763
+ instanceId: result.instanceId || getDeviceId(),
5764
+ status: "active",
5765
+ lastValidatedAt: now,
5766
+ activatedAt: now,
5767
+ variantId: result.variantId,
5768
+ customerName: result.customerName,
5769
+ productName: result.productName,
5770
+ variantName: result.variantName
5771
+ });
5772
+ const label = getVariantLabel(result.variantId);
5773
+ const who = result.customerName ? ` Welcome, ${result.customerName}!` : "";
5774
+ ls.stop(`${label} activated.${who}`);
5775
+ licensed = true;
5776
+ } else {
5777
+ ls.stop("License activation failed");
5778
+ dist_exports.log.warn(`${result.error ?? "unknown error"}
5779
+ Check your key at https://keepgoing.dev/add-ons`);
5780
+ }
5781
+ }
5782
+ if (licensed) {
5783
+ dist_exports.log.info("Have another add-on key? Run `keepgoing activate <key>` anytime.");
5784
+ }
5785
+ }
5786
+ }
5787
+ const profile = {
5788
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
5789
+ tools,
5790
+ ide,
5791
+ scope,
5792
+ shellHook: installShellHook,
5793
+ claudePlugin,
5794
+ licensed
5795
+ };
5796
+ const keepgoingDir = path14.join(os7.homedir(), ".keepgoing");
5797
+ fs10.mkdirSync(keepgoingDir, { recursive: true });
5798
+ fs10.writeFileSync(
5799
+ path14.join(keepgoingDir, "setup-profile.json"),
5800
+ JSON.stringify(profile, null, 2) + "\n",
5801
+ "utf-8"
5802
+ );
5803
+ dist_exports.log.success("Setup profile saved to ~/.keepgoing/setup-profile.json");
5804
+ dist_exports.outro("Done! Run `keepgoing status` to verify.");
5805
+ }
5806
+
5807
+ // src/commands/momentum.ts
5808
+ async function momentumCommand(opts) {
5809
+ const reader = new KeepGoingReader(opts.cwd);
5810
+ if (!reader.exists()) {
5811
+ if (!opts.quiet) {
5812
+ renderNoData();
5813
+ }
5814
+ return;
5815
+ }
5816
+ const { session: lastSession, isFallback } = reader.getScopedLastSession();
5817
+ const currentBranch = reader.getCurrentBranch();
5818
+ if (!lastSession) {
5819
+ if (!opts.quiet) {
5820
+ console.log("KeepGoing is set up but no session checkpoints exist yet.");
5821
+ }
5822
+ return;
5823
+ }
5824
+ const state = reader.getState();
5825
+ const branchChanged = lastSession.gitBranch && currentBranch && lastSession.gitBranch !== currentBranch;
5826
+ if (opts.json) {
5827
+ console.log(JSON.stringify({
5828
+ lastCheckpoint: lastSession.timestamp,
5829
+ summary: lastSession.summary,
5830
+ nextStep: lastSession.nextStep,
5831
+ blocker: lastSession.blocker || null,
5832
+ projectIntent: lastSession.projectIntent || null,
5833
+ branch: currentBranch || null,
5834
+ branchChanged: branchChanged ? lastSession.gitBranch : null,
5835
+ touchedFiles: lastSession.touchedFiles,
5836
+ derivedFocus: state?.derivedCurrentFocus || null,
5837
+ isWorktree: reader.isWorktree,
5838
+ isFallback
5839
+ }, null, 2));
5840
+ return;
5841
+ }
5842
+ if (opts.quiet) {
5843
+ renderMomentumQuiet(lastSession);
5844
+ return;
3142
5845
  }
3143
5846
  renderMomentum(lastSession, {
3144
5847
  currentBranch,
@@ -3188,21 +5891,21 @@ async function decisionsCommand(opts) {
3188
5891
  function parseDate(input) {
3189
5892
  const lower = input.toLowerCase().trim();
3190
5893
  if (lower === "today") {
3191
- const d2 = /* @__PURE__ */ new Date();
3192
- d2.setHours(0, 0, 0, 0);
3193
- return d2;
5894
+ const d4 = /* @__PURE__ */ new Date();
5895
+ d4.setHours(0, 0, 0, 0);
5896
+ return d4;
3194
5897
  }
3195
5898
  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;
5899
+ const d4 = /* @__PURE__ */ new Date();
5900
+ d4.setDate(d4.getDate() - 1);
5901
+ d4.setHours(0, 0, 0, 0);
5902
+ return d4;
3200
5903
  }
3201
5904
  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;
5905
+ const d4 = /* @__PURE__ */ new Date();
5906
+ d4.setDate(d4.getDate() - 7);
5907
+ d4.setHours(0, 0, 0, 0);
5908
+ return d4;
3206
5909
  }
3207
5910
  const agoMatch = lower.match(/^(\d+)\s+(second|minute|hour|day|week|month)s?\s+ago$/);
3208
5911
  if (agoMatch) {
@@ -3219,8 +5922,8 @@ function parseDate(input) {
3219
5922
  };
3220
5923
  return new Date(now.getTime() - n * (msPerUnit[unit] ?? 0));
3221
5924
  }
3222
- const d = new Date(input);
3223
- if (!isNaN(d.getTime())) return d;
5925
+ const d3 = new Date(input);
5926
+ if (!isNaN(d3.getTime())) return d3;
3224
5927
  return void 0;
3225
5928
  }
3226
5929
  function filterSessions(sessions, opts) {
@@ -3278,25 +5981,25 @@ function filterDecisions(decisions, opts) {
3278
5981
  }
3279
5982
  if (sinceDate) {
3280
5983
  const ts = sinceDate.getTime();
3281
- result = result.filter((d) => new Date(d.timestamp).getTime() >= ts);
5984
+ result = result.filter((d3) => new Date(d3.timestamp).getTime() >= ts);
3282
5985
  }
3283
5986
  if (opts.until) {
3284
5987
  const untilDate = parseDate(opts.until);
3285
5988
  if (untilDate) {
3286
5989
  const ts = untilDate.getTime();
3287
- result = result.filter((d) => new Date(d.timestamp).getTime() <= ts);
5990
+ result = result.filter((d3) => new Date(d3.timestamp).getTime() <= ts);
3288
5991
  }
3289
5992
  }
3290
5993
  if (opts.follow) {
3291
5994
  const file = opts.follow.toLowerCase();
3292
5995
  result = result.filter(
3293
- (d) => d.filesChanged?.some((f) => f.toLowerCase().includes(file))
5996
+ (d3) => d3.filesChanged?.some((f) => f.toLowerCase().includes(file))
3294
5997
  );
3295
5998
  }
3296
5999
  if (opts.search) {
3297
6000
  const term = opts.search.toLowerCase();
3298
- result = result.filter((d) => {
3299
- const haystack = [d.commitMessage, d.rationale].filter(Boolean).join(" ").toLowerCase();
6001
+ result = result.filter((d3) => {
6002
+ const haystack = [d3.commitMessage, d3.rationale].filter(Boolean).join(" ").toLowerCase();
3300
6003
  return haystack.includes(term);
3301
6004
  });
3302
6005
  }
@@ -3373,7 +6076,7 @@ async function logDecisions(reader, opts) {
3373
6076
  const { effectiveBranch } = reader.resolveBranchScope(opts.branch || void 0);
3374
6077
  let decisions = reader.getDecisions();
3375
6078
  if (effectiveBranch) {
3376
- decisions = decisions.filter((d) => d.gitBranch === effectiveBranch);
6079
+ decisions = decisions.filter((d3) => d3.gitBranch === effectiveBranch);
3377
6080
  }
3378
6081
  decisions.reverse();
3379
6082
  decisions = filterDecisions(decisions, opts);
@@ -3392,12 +6095,12 @@ async function logDecisions(reader, opts) {
3392
6095
  return;
3393
6096
  }
3394
6097
  if (opts.oneline) {
3395
- for (const d of displayed) {
3396
- renderLogDecisionOneline(d);
6098
+ for (const d3 of displayed) {
6099
+ renderLogDecisionOneline(d3);
3397
6100
  }
3398
6101
  } else {
3399
- for (const d of displayed) {
3400
- renderLogDecision(d, opts.stat);
6102
+ for (const d3 of displayed) {
6103
+ renderLogDecision(d3, opts.stat);
3401
6104
  }
3402
6105
  }
3403
6106
  if (totalFiltered > opts.count) {
@@ -3418,19 +6121,19 @@ async function logCommand(opts) {
3418
6121
  }
3419
6122
 
3420
6123
  // src/platform.ts
3421
- import { execSync as execSync2, spawnSync } from "child_process";
6124
+ import { execSync as execSync4, spawnSync } from "child_process";
3422
6125
  function copyToClipboard(text) {
3423
6126
  try {
3424
6127
  const platform = process.platform;
3425
6128
  if (platform === "darwin") {
3426
- execSync2("pbcopy", { input: text, stdio: ["pipe", "ignore", "ignore"] });
6129
+ execSync4("pbcopy", { input: text, stdio: ["pipe", "ignore", "ignore"] });
3427
6130
  } else if (platform === "win32") {
3428
- execSync2("clip.exe", { input: text, stdio: ["pipe", "ignore", "ignore"] });
6131
+ execSync4("clip.exe", { input: text, stdio: ["pipe", "ignore", "ignore"] });
3429
6132
  } else {
3430
6133
  try {
3431
- execSync2("xclip -selection clipboard", { input: text, stdio: ["pipe", "ignore", "ignore"] });
6134
+ execSync4("xclip -selection clipboard", { input: text, stdio: ["pipe", "ignore", "ignore"] });
3432
6135
  } catch {
3433
- execSync2("xsel --clipboard --input", { input: text, stdio: ["pipe", "ignore", "ignore"] });
6136
+ execSync4("xsel --clipboard --input", { input: text, stdio: ["pipe", "ignore", "ignore"] });
3434
6137
  }
3435
6138
  }
3436
6139
  return true;
@@ -3549,7 +6252,8 @@ keepgoing: resume side projects without the mental friction
3549
6252
  Usage: keepgoing <command> [options]
3550
6253
 
3551
6254
  Commands:
3552
- init Set up KeepGoing hooks and CLAUDE.md in this project
6255
+ setup [preset] Interactive setup wizard (recommended for first-time setup)
6256
+ init Set up KeepGoing hooks and CLAUDE.md (non-interactive)
3553
6257
  status Show the last checkpoint for this project
3554
6258
  momentum Show your current developer momentum
3555
6259
  briefing Get a re-entry briefing for this project
@@ -3583,13 +6287,28 @@ Options:
3583
6287
  --cwd <path> Override the working directory
3584
6288
  `,
3585
6289
  setup: `
3586
- keepgoing init: Set up KeepGoing hooks and CLAUDE.md in this project
6290
+ keepgoing setup: Interactive setup wizard
3587
6291
 
3588
- Usage: keepgoing init [options]
6292
+ Walks you through configuring KeepGoing for your AI tools, IDE, and shell.
6293
+ Configures Claude Code, GitHub Copilot, Cursor, and/or Windsurf in one go.
6294
+
6295
+ Usage: keepgoing setup [preset] [options]
6296
+
6297
+ Presets:
6298
+ claude Pre-select Claude Code
6299
+ copilot Pre-select GitHub Copilot
6300
+ cursor Pre-select Cursor
6301
+ windsurf Pre-select Windsurf
6302
+ vscode Pre-select VS Code IDE
6303
+ jetbrains Pre-select JetBrains IDE
3589
6304
 
3590
6305
  Options:
3591
- --scope <s> Scope: "project" (default) or "user" (global)
3592
6306
  --cwd <path> Override the working directory
6307
+
6308
+ Examples:
6309
+ keepgoing setup Full interactive wizard
6310
+ keepgoing setup claude Start with Claude Code pre-selected
6311
+ keepgoing setup vscode Start with VS Code pre-selected
3593
6312
  `,
3594
6313
  status: `
3595
6314
  keepgoing status: Show the last checkpoint for this project
@@ -3908,9 +6627,21 @@ async function main() {
3908
6627
  }
3909
6628
  switch (command) {
3910
6629
  case "init":
3911
- case "setup":
3912
6630
  initCommand({ cwd, scope });
3913
6631
  break;
6632
+ case "setup": {
6633
+ let preset;
6634
+ if (subcommand) {
6635
+ if (VALID_PRESETS.includes(subcommand)) {
6636
+ preset = subcommand;
6637
+ } else {
6638
+ console.error(`Unknown preset: "${subcommand}". Valid presets: ${VALID_PRESETS.join(", ")}`);
6639
+ process.exit(1);
6640
+ }
6641
+ }
6642
+ await setupCommand({ cwd, preset });
6643
+ break;
6644
+ }
3914
6645
  case "status":
3915
6646
  await statusCommand({ cwd, json, quiet });
3916
6647
  break;
@@ -3979,7 +6710,7 @@ async function main() {
3979
6710
  }
3980
6711
  break;
3981
6712
  case "version":
3982
- console.log(`keepgoing v${"1.3.3"}`);
6713
+ console.log(`keepgoing v${"1.4.0"}`);
3983
6714
  break;
3984
6715
  case "activate":
3985
6716
  await activateCommand({ licenseKey: subcommand });