@heyitsiveen/dotfiles 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +112 -85
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -186,12 +186,26 @@ async function deleteManifest() {
|
|
|
186
186
|
const manifestPath = getManifestPath();
|
|
187
187
|
if (await pathExists$2(manifestPath)) await remove(manifestPath);
|
|
188
188
|
}
|
|
189
|
+
const TERMINAL_DEFAULTS = {
|
|
190
|
+
WezTerm: {
|
|
191
|
+
file: "wezterm.lua",
|
|
192
|
+
content: "local wezterm = require 'wezterm'\nreturn {}\n"
|
|
193
|
+
},
|
|
194
|
+
Ghostty: {
|
|
195
|
+
file: "config",
|
|
196
|
+
content: "# defaults\n"
|
|
197
|
+
}
|
|
198
|
+
};
|
|
189
199
|
async function uninstallGroups(groups) {
|
|
190
200
|
const errors = [];
|
|
191
|
-
for (const group of groups)
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
201
|
+
for (const group of groups) {
|
|
202
|
+
const termDefault = TERMINAL_DEFAULTS[group.name];
|
|
203
|
+
for (const file of group.files) try {
|
|
204
|
+
if (await pathExists$2(file)) if (termDefault && file.endsWith(termDefault.file)) await writeFile(file, termDefault.content, "utf-8");
|
|
205
|
+
else await remove(file);
|
|
206
|
+
} catch (err) {
|
|
207
|
+
errors.push(`${file}: ${err instanceof Error ? err.message : String(err)}`);
|
|
208
|
+
}
|
|
195
209
|
}
|
|
196
210
|
return errors;
|
|
197
211
|
}
|
|
@@ -731,6 +745,7 @@ function showPrerequisites(platform) {
|
|
|
731
745
|
log.message(` ${pc.cyan(item.link)}`);
|
|
732
746
|
}
|
|
733
747
|
}
|
|
748
|
+
/** Detect tools and show status. Returns missing tools (no install). */
|
|
734
749
|
async function showToolStatus(groups, platform) {
|
|
735
750
|
const allTools = [];
|
|
736
751
|
const groupNames = new Set(groups.map((g) => g.name));
|
|
@@ -752,7 +767,7 @@ async function showToolStatus(groups, platform) {
|
|
|
752
767
|
installCmd: g.installCmd,
|
|
753
768
|
required: g.required
|
|
754
769
|
});
|
|
755
|
-
if (allTools.length === 0) return;
|
|
770
|
+
if (allTools.length === 0) return [];
|
|
756
771
|
const forGroupNames = new Set([...subTools.values()].flat().map((t) => t.name));
|
|
757
772
|
const requiredTools = [];
|
|
758
773
|
const optionalTools = [];
|
|
@@ -791,45 +806,26 @@ async function showToolStatus(groups, platform) {
|
|
|
791
806
|
const subs = subTools.get(t.name);
|
|
792
807
|
if (subs) for (const st of subs) showSubTool(st);
|
|
793
808
|
}
|
|
794
|
-
if (missing.length
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
log.message(` ${pc.dim("○")} Installing ${t.name}...`);
|
|
815
|
-
try {
|
|
816
|
-
execSync(t.installCmd, {
|
|
817
|
-
stdio: "pipe",
|
|
818
|
-
encoding: "utf-8",
|
|
819
|
-
timeout: 3e5
|
|
820
|
-
});
|
|
821
|
-
installed++;
|
|
822
|
-
log.message(` ${pc.green("◆")} ${t.name} installed`);
|
|
823
|
-
} catch (err) {
|
|
824
|
-
log.message(` ${pc.yellow("⚠")} ${t.name} failed`);
|
|
825
|
-
log.message(` ${pc.dim(t.installCmd)} — ${pc.dim(err instanceof Error ? err.message : String(err))}`);
|
|
826
|
-
}
|
|
827
|
-
}
|
|
828
|
-
log.message("");
|
|
829
|
-
if (installed === total) log.message(` ${pc.green("◆")} ${installed} tool${installed > 1 ? "s" : ""} installed successfully`);
|
|
830
|
-
else log.message(` ${pc.yellow("⚠")} ${installed}/${total} tools installed (${total - installed} failed)`);
|
|
831
|
-
}
|
|
832
|
-
} else log.success("All tools installed!");
|
|
809
|
+
if (missing.length === 0) log.success("All tools installed!");
|
|
810
|
+
return missing;
|
|
811
|
+
}
|
|
812
|
+
/** Show multiselect picker for missing tools. Returns tools to install (no execution). */
|
|
813
|
+
async function pickMissingTools(missing) {
|
|
814
|
+
const selectedNames = await multiselect({
|
|
815
|
+
message: "Install missing tools?",
|
|
816
|
+
options: missing.map((t) => ({
|
|
817
|
+
value: t.name,
|
|
818
|
+
label: t.name,
|
|
819
|
+
hint: t.installCmd
|
|
820
|
+
})),
|
|
821
|
+
initialValues: missing.map((t) => t.name),
|
|
822
|
+
required: false
|
|
823
|
+
});
|
|
824
|
+
handleCancel(selectedNames);
|
|
825
|
+
const toInstall = missing.filter((t) => selectedNames.includes(t.name));
|
|
826
|
+
const brewFirst = toInstall.filter((t) => t.name === "Homebrew");
|
|
827
|
+
const rest = toInstall.filter((t) => t.name !== "Homebrew");
|
|
828
|
+
return [...brewFirst, ...rest];
|
|
833
829
|
}
|
|
834
830
|
const groupCategories = {
|
|
835
831
|
"Shell & Terminal": [
|
|
@@ -884,9 +880,17 @@ function showReloadCommands(groups) {
|
|
|
884
880
|
break;
|
|
885
881
|
}
|
|
886
882
|
if (reloads.length > 0) {
|
|
887
|
-
log.
|
|
888
|
-
for (const r of reloads) log.message(`
|
|
883
|
+
log.info("Reload your configs:");
|
|
884
|
+
for (const r of reloads) log.message(` ${r.name.padEnd(12)} → ${pc.cyan(r.cmd)}`);
|
|
889
885
|
}
|
|
886
|
+
const restartMsg = "Restart your terminal for all changes to take effect.";
|
|
887
|
+
const w = 57;
|
|
888
|
+
log.message([
|
|
889
|
+
"",
|
|
890
|
+
` ${pc.dim("╭" + "─".repeat(w) + "╮")}`,
|
|
891
|
+
` ${pc.dim("│")} ${pc.bold(restartMsg)} ${pc.dim("│")}`,
|
|
892
|
+
` ${pc.dim("╰" + "─".repeat(w) + "╯")}`
|
|
893
|
+
].join("\n"));
|
|
890
894
|
}
|
|
891
895
|
async function resolvePlatform(flagPlatform) {
|
|
892
896
|
if (flagPlatform === "macos" || flagPlatform === "windows") return flagPlatform;
|
|
@@ -912,13 +916,29 @@ async function resolvePlatform(flagPlatform) {
|
|
|
912
916
|
handleCancel(chosen);
|
|
913
917
|
return chosen;
|
|
914
918
|
}
|
|
915
|
-
async function
|
|
919
|
+
async function showUpdateNotification(updatePromise) {
|
|
920
|
+
if (!updatePromise) return;
|
|
921
|
+
const latest = await updatePromise;
|
|
922
|
+
if (!latest) return;
|
|
923
|
+
const msg = `Update available: ${VERSION} → ${latest}`;
|
|
924
|
+
const cmd = "Run: bunx @heyitsiveen/dotfiles@latest";
|
|
925
|
+
const w = Math.max(msg.length, 38) + 4;
|
|
926
|
+
log.message([
|
|
927
|
+
` ${pc.dim("╭" + "─".repeat(w) + "╮")}`,
|
|
928
|
+
` ${pc.dim("│")} ${pc.yellow(msg.padEnd(w - 2))}${pc.dim("│")}`,
|
|
929
|
+
` ${pc.dim("│")} ${pc.cyan(cmd.padEnd(w - 2))}${pc.dim("│")}`,
|
|
930
|
+
` ${pc.dim("╰" + "─".repeat(w) + "╯")}`
|
|
931
|
+
].join("\n"));
|
|
932
|
+
}
|
|
933
|
+
async function firstRunFlow(flagPlatform, dryRun = false, updatePromise) {
|
|
916
934
|
showBanner();
|
|
917
935
|
intro(pc.bold("heyitsiveen"));
|
|
936
|
+
await showUpdateNotification(updatePromise);
|
|
918
937
|
const platform = await resolvePlatform(flagPlatform);
|
|
919
938
|
showPrerequisites(platform);
|
|
920
939
|
const allGroups = getDotfileGroups(platform);
|
|
921
|
-
await showToolStatus(allGroups, platform);
|
|
940
|
+
const missingTools = await showToolStatus(allGroups, platform);
|
|
941
|
+
const toolsToInstall = missingTools.length > 0 ? await pickMissingTools(missingTools) : [];
|
|
922
942
|
showOverview(allGroups);
|
|
923
943
|
const depTools = getDependencyTools(platform);
|
|
924
944
|
const selectedNames = await multiselect({
|
|
@@ -929,10 +949,11 @@ async function firstRunFlow(flagPlatform, dryRun = false) {
|
|
|
929
949
|
const warnings = [];
|
|
930
950
|
if (toolMissing) warnings.push("not installed");
|
|
931
951
|
if (missingDeps.length > 0) warnings.push(`${missingDeps.join(", ")} missing`);
|
|
932
|
-
const
|
|
952
|
+
const hint = warnings.length > 0 ? `⚠ ${warnings.join(", ")}` : g.description;
|
|
933
953
|
return {
|
|
934
954
|
value: g.name,
|
|
935
|
-
label:
|
|
955
|
+
label: g.name,
|
|
956
|
+
hint
|
|
936
957
|
};
|
|
937
958
|
}),
|
|
938
959
|
initialValues: allGroups.map((g) => g.name),
|
|
@@ -975,8 +996,27 @@ async function firstRunFlow(flagPlatform, dryRun = false) {
|
|
|
975
996
|
shouldBackup = doBackup;
|
|
976
997
|
}
|
|
977
998
|
if (dryRun) log.info(pc.yellow("Dry run — showing planned operations:"));
|
|
978
|
-
|
|
979
|
-
|
|
999
|
+
if (toolsToInstall.length > 0) {
|
|
1000
|
+
log.info("Installing tools...");
|
|
1001
|
+
let toolsInstalled = 0;
|
|
1002
|
+
for (const t of toolsToInstall) {
|
|
1003
|
+
log.message(` ${pc.dim("○")} ${t.name}...`);
|
|
1004
|
+
try {
|
|
1005
|
+
execSync(t.installCmd, {
|
|
1006
|
+
stdio: "pipe",
|
|
1007
|
+
encoding: "utf-8",
|
|
1008
|
+
timeout: 3e5
|
|
1009
|
+
});
|
|
1010
|
+
toolsInstalled++;
|
|
1011
|
+
log.message(` ${pc.green("◆")} ${t.name} installed`);
|
|
1012
|
+
} catch (err) {
|
|
1013
|
+
log.message(` ${pc.yellow("⚠")} ${t.name} failed`);
|
|
1014
|
+
log.message(` ${pc.dim(t.installCmd)} — ${pc.dim(err instanceof Error ? err.message : String(err))}`);
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
log.message(` ${pc.green("◆")} ${toolsInstalled}/${toolsToInstall.length} tools installed`);
|
|
1018
|
+
}
|
|
1019
|
+
log.info("Installing dotfiles...");
|
|
980
1020
|
const result = await install({
|
|
981
1021
|
platform,
|
|
982
1022
|
selectedGroups,
|
|
@@ -984,8 +1024,21 @@ async function firstRunFlow(flagPlatform, dryRun = false) {
|
|
|
984
1024
|
backup: shouldBackup,
|
|
985
1025
|
dryRun
|
|
986
1026
|
});
|
|
1027
|
+
for (const ig of result.installedGroups) log.message(` ${pc.green("◆")} ${ig.name} → ${pc.dim(ig.target)}`);
|
|
1028
|
+
log.message(` ${pc.green("◆")} ${result.installedGroups.length}/${selectedGroups.length} configs installed`);
|
|
987
1029
|
const themeGroups = selectedGroups.filter((g) => g.themeSupport);
|
|
988
|
-
if (themeGroups.length > 0)
|
|
1030
|
+
if (themeGroups.length > 0) {
|
|
1031
|
+
log.info("Applying theme...");
|
|
1032
|
+
const themeResults = await switchTheme(theme, result.installedGroups.filter((ig) => themeGroups.some((sg) => sg.name === ig.name)), platform, dryRun);
|
|
1033
|
+
for (const r of themeResults) log.message(` ${pc.green("◆")} ${r}`);
|
|
1034
|
+
log.message(` ${pc.green("◆")} Theme: ${theme} activated`);
|
|
1035
|
+
}
|
|
1036
|
+
if (result.backedUp.length > 0) {
|
|
1037
|
+
const unique = [...new Set(result.backedUp)];
|
|
1038
|
+
log.info("Backed up existing configs:");
|
|
1039
|
+
for (const name of unique) log.message(` ${pc.green("◆")} ${name}`);
|
|
1040
|
+
log.message(` ${pc.green("◆")} ${unique.length} configs → ${pc.dim("~/.config/heyitsiveen/dotfiles/backup/")}`);
|
|
1041
|
+
}
|
|
989
1042
|
if (!dryRun) await createManifest(result, {
|
|
990
1043
|
platform,
|
|
991
1044
|
selectedGroups,
|
|
@@ -993,27 +1046,14 @@ async function firstRunFlow(flagPlatform, dryRun = false) {
|
|
|
993
1046
|
backup: shouldBackup,
|
|
994
1047
|
dryRun
|
|
995
1048
|
});
|
|
996
|
-
s.stop("Installation complete!");
|
|
997
|
-
if (result.backedUp.length > 0) {
|
|
998
|
-
const unique = [...new Set(result.backedUp)];
|
|
999
|
-
log.message(` ${pc.green("◆")} Backed up ${unique.length} existing configs → ${pc.dim("~/.config/heyitsiveen/dotfiles/backup/")}`);
|
|
1000
|
-
}
|
|
1001
|
-
for (const [category, names] of Object.entries(groupCategories)) {
|
|
1002
|
-
const installed = result.installedGroups.filter((ig) => names.includes(ig.name));
|
|
1003
|
-
if (installed.length === 0) continue;
|
|
1004
|
-
log.message(` ${pc.bold(category)}`);
|
|
1005
|
-
for (const ig of installed) log.message(` ${pc.green("◆")} ${ig.name} → ${pc.dim(ig.target)}`);
|
|
1006
|
-
}
|
|
1007
|
-
log.message(` ${pc.green("◆")} Theme: ${theme} activated`);
|
|
1008
1049
|
if (result.errors.length > 0) for (const err of result.errors) log.message(` ${pc.yellow("⚠")} ${err.file}: ${pc.dim(err.error)}`);
|
|
1009
1050
|
showReloadCommands(selectedGroups);
|
|
1010
|
-
log.message("");
|
|
1011
|
-
log.info(pc.bold("Restart your terminal for all changes to take effect."));
|
|
1012
1051
|
outro("Done! Your dotfiles are installed.");
|
|
1013
1052
|
}
|
|
1014
|
-
async function reRunFlow(manifest, flagPlatform, dryRun = false) {
|
|
1053
|
+
async function reRunFlow(manifest, flagPlatform, dryRun = false, updatePromise) {
|
|
1015
1054
|
showBanner();
|
|
1016
1055
|
intro(pc.bold("heyitsiveen"));
|
|
1056
|
+
await showUpdateNotification(updatePromise);
|
|
1017
1057
|
showPrerequisites(manifest.platform);
|
|
1018
1058
|
log.info(`Existing installation detected (v${manifest.version}, installed ${manifest.installedAt.split("T")[0]})`);
|
|
1019
1059
|
const mode = await select({
|
|
@@ -1127,7 +1167,8 @@ async function uninstallFlow(manifest, dryRun = false) {
|
|
|
1127
1167
|
message: "Which configs to remove?",
|
|
1128
1168
|
options: manifest.groups.map((g) => ({
|
|
1129
1169
|
value: g.name,
|
|
1130
|
-
label:
|
|
1170
|
+
label: g.name,
|
|
1171
|
+
hint: g.target
|
|
1131
1172
|
})),
|
|
1132
1173
|
initialValues: manifest.groups.map((g) => g.name),
|
|
1133
1174
|
required: true
|
|
@@ -1418,22 +1459,8 @@ runMain(defineCommand({
|
|
|
1418
1459
|
await themeFlow(manifest, dryRun, args.theme);
|
|
1419
1460
|
return;
|
|
1420
1461
|
}
|
|
1421
|
-
if (manifest) await reRunFlow(manifest, args.platform, dryRun);
|
|
1422
|
-
else await firstRunFlow(args.platform, dryRun);
|
|
1423
|
-
const latest = await updatePromise;
|
|
1424
|
-
if (latest) {
|
|
1425
|
-
const msg = `Update available: ${VERSION} → ${latest}`;
|
|
1426
|
-
const cmd = "Run: bunx @heyitsiveen/dotfiles@latest";
|
|
1427
|
-
const w = Math.max(msg.length, 38) + 4;
|
|
1428
|
-
console.log([
|
|
1429
|
-
"",
|
|
1430
|
-
` ${pc.dim("╭" + "─".repeat(w) + "╮")}`,
|
|
1431
|
-
` ${pc.dim("│")} ${pc.yellow(msg.padEnd(w - 2))}${pc.dim("│")}`,
|
|
1432
|
-
` ${pc.dim("│")} ${pc.cyan(cmd.padEnd(w - 2))}${pc.dim("│")}`,
|
|
1433
|
-
` ${pc.dim("╰" + "─".repeat(w) + "╯")}`,
|
|
1434
|
-
""
|
|
1435
|
-
].join("\n"));
|
|
1436
|
-
}
|
|
1462
|
+
if (manifest) await reRunFlow(manifest, args.platform, dryRun, updatePromise);
|
|
1463
|
+
else await firstRunFlow(args.platform, dryRun, updatePromise);
|
|
1437
1464
|
} catch (err) {
|
|
1438
1465
|
if (err.code === "ERR_USE_AFTER_CLOSE") process.exit(0);
|
|
1439
1466
|
log.error(pc.red(err instanceof Error ? err.message : "An unexpected error occurred."));
|