haoshoku 2.0.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 (100) hide show
  1. package/.github/workflows/publish-to-npm.yml +32 -0
  2. package/README.md +85 -0
  3. package/bun.lock +25 -0
  4. package/common/flatpacks_arch.txt +4 -0
  5. package/common/paru_applist.txt +52 -0
  6. package/configs/__init__.py +1 -0
  7. package/configs/alacritty/alacritty.toml +5 -0
  8. package/configs/fastfetch/config.jsonc +160 -0
  9. package/configs/fish/config.fish +66 -0
  10. package/configs/ghostty/config +6 -0
  11. package/configs/kde_shortcuts.kksrc +368 -0
  12. package/configs/kitty/kitty.conf +41 -0
  13. package/configs/vencord/trans.theme.css +90 -0
  14. package/deskback/20250228_234138~2.jpg +0 -0
  15. package/deskback/32977-1920x1080-desktop-full-hd-the-garden-of-words-wallpaper-photo.jpg +0 -0
  16. package/deskback/a_spring_night_by_bisbiswas_deekkf0.jpg +0 -0
  17. package/deskback/adia___east_hallegian_aurorae_by_rajavlitra_dasfxtu.png +0 -0
  18. package/deskback/anew_beginning_by_thekayeman_ddyp7ti.jpg +0 -0
  19. package/deskback/arachnophobia_by_bisbiswas_detjqyf.jpg +0 -0
  20. package/deskback/arise_by_bisbiswas_ddwcnjg.jpg +0 -0
  21. package/deskback/aurora_borealis__by_xxartymusexx_ddzt4e0.jpg +0 -0
  22. package/deskback/aurora_borealis_by_gaudibuendia_dajesxg.jpg +0 -0
  23. package/deskback/aurora_borealis_by_sephiroth_art_dawxmlz.jpg +0 -0
  24. package/deskback/aurora_by_rav89_dau22zv.jpg +0 -0
  25. package/deskback/aurora_lights_by_bisbiswas_dedov93.jpg +0 -0
  26. package/deskback/aurora_lights_by_bisbiswas_dedov93~3.jpg +0 -0
  27. package/deskback/bizarre_winter_night_by_bisbiswas_dfnsfxe.jpg +0 -0
  28. package/deskback/blazing_moon_by_bisbiswas_def6rgz.jpg +0 -0
  29. package/deskback/burning_tower_by_bisbiswas_dfciho6.jpg +0 -0
  30. package/deskback/christmas_night_commissioned__by_bisbiswas_deb2fgh.jpg +0 -0
  31. package/deskback/cold_night_drive_by_bisbiswas_dfqw4ev.jpg +0 -0
  32. package/deskback/creature_of_fantasyland_by_bisbiswas_dgjrpn6.jpg +0 -0
  33. package/deskback/crossing_road_by_bisbiswas_deksqsf.jpg +0 -0
  34. package/deskback/d9gpwju-04121643-6c14-4503-b2e3-60995901caf9.jpg +0 -0
  35. package/deskback/dreamy_night_by_bisbiswas_deaka30.jpg +0 -0
  36. package/deskback/emerald_moon_by_bisbiswas_demugqf.jpg +0 -0
  37. package/deskback/free_use_background__nebula__5400_by_ted_drakness_dfqq9bd.jpg +0 -0
  38. package/deskback/happy_new_year_2023_by_bisbiswas_dfly13l.jpg +0 -0
  39. package/deskback/hidden_between_the_mountans_by_bisbiswas_dhkgcji.jpg +0 -0
  40. package/deskback/long_night_drive_by_bisbiswas_defo5d1.jpg +0 -0
  41. package/deskback/magical_hour__commissioned__by_bisbiswas_dfi6fz5.jpg +0 -0
  42. package/deskback/magical_meteor_night1_by_bisbiswas_dfwosp2.jpg +0 -0
  43. package/deskback/melstrom_by_thekayeman_de0z6em.jpg +0 -0
  44. package/deskback/mermaid_s_arrival_by_bisbiswas_deko21g.jpg +0 -0
  45. package/deskback/meteor_shower_by_bisbiswas_deogvao.jpg +0 -0
  46. package/deskback/midnight_train_by_bisbiswas_dengl62.jpg +0 -0
  47. package/deskback/nebula_of_solitude_by_thekayeman_dedfpmk.jpg +0 -0
  48. package/deskback/night_lights_by_bisbiswas_de3gb5p.jpg +0 -0
  49. package/deskback/night_mirror_by_clearvector_d4s66cp.png +0 -0
  50. package/deskback/night_rider_by_bisbiswas_deiy9z0.jpg +0 -0
  51. package/deskback/nobara-41-1.png +0 -0
  52. package/deskback/nobara-41-2.png +0 -0
  53. package/deskback/nobara-41-3.png +0 -0
  54. package/deskback/nobara-41-4.png +0 -0
  55. package/deskback/nobara-41-5.png +0 -0
  56. package/deskback/northern_ambience_by_zizzyart_df0kj8f.jpg +0 -0
  57. package/deskback/northern_lights_by_goatsforbreakfast_de90t8s.jpg +0 -0
  58. package/deskback/northern_lights_by_lapis_lazuri_dcprksa.jpg +0 -0
  59. package/deskback/northern_magic_by_lapis_lazuri_dbm99nv.jpg +0 -0
  60. package/deskback/northern_splendour_by_lapis_lazuri_ddlygb0.jpg +0 -0
  61. package/deskback/old_lighthouse_by_bisbiswas_dg5he0x.jpg +0 -0
  62. package/deskback/on_a_spring_vacation_by_bisbiswas_dhv9h4o.jpg +0 -0
  63. package/deskback/polar_dreams_by_avogadium_de2s60i.jpg +0 -0
  64. package/deskback/purple_night_by_bisbiswas_de4ql0w.jpg +0 -0
  65. package/deskback/quiet_ocean_night_by_ebenezer42_de4h9nd.jpg +0 -0
  66. package/deskback/rail_gate_by_bisbiswas_dehq31u.jpg +0 -0
  67. package/deskback/the_aurora_stones_by_hyokka_dcyokk2 (1).png +0 -0
  68. package/deskback/the_aurora_stones_by_hyokka_dcyokk2.png +0 -0
  69. package/deskback/the_aurora_stones_by_hyokka_dcyokk2mirror (1).png +0 -0
  70. package/deskback/the_aurora_stones_by_hyokka_dcyokk2mirror.png +0 -0
  71. package/deskback/the_midnight_by_thekayeman_de36pew.jpg +0 -0
  72. package/deskback/through_the_haze_by_traemore_deqdnrp.png +0 -0
  73. package/deskback/tri_system_by_thekayeman_ddyfscv.jpg +0 -0
  74. package/deskback/verdant_moonlight__commissioned__by_bisbiswas_degzd3v.jpg +0 -0
  75. package/deskback/verdant_mountain_by_bisbiswas_derlepn.jpg +0 -0
  76. package/deskback/winter_scenery_by_bisbiswas_dgwj8rb.jpg +0 -0
  77. package/docs/haoshoku.md +47 -0
  78. package/haoshoku.js +88 -0
  79. package/icons/Gemini_Generated_Image_kwrza7kwrza7kwrz.png +0 -0
  80. package/icons/Google_Tasks_2021.svg +17 -0
  81. package/icons/artificial-intelligence.png +0 -0
  82. package/icons/chatgpt-icon.png +0 -0
  83. package/icons/favicon.svg +12 -0
  84. package/icons/icons8-chatgpt-50.png +0 -0
  85. package/icons/icons8-discord-96.png +0 -0
  86. package/icons/icons8-feed-64.png +0 -0
  87. package/icons/icons8-google-calendar-48.png +0 -0
  88. package/icons/icons8-messages-96.png +0 -0
  89. package/icons/icons8-notion-64.png +0 -0
  90. package/icons/icons8-whatsapp-96.png +0 -0
  91. package/icons/zed.png +0 -0
  92. package/info.txt +3 -0
  93. package/package.json +14 -0
  94. package/src/common/utils.js +46 -0
  95. package/src/helpers/configure_git.js +130 -0
  96. package/src/os_scripts/cachyos.js +342 -0
  97. package/src/os_scripts/debian_server.js +146 -0
  98. package/tests/test_cachyos.py +37 -0
  99. package/tests/test_common.py +73 -0
  100. package/tests/test_kde_config.py +69 -0
@@ -0,0 +1,47 @@
1
+ # Haoshoku: Color of the Supreme King
2
+
3
+ ## Overview
4
+
5
+ `haoshoku` is a JavaScript-based command-line tool designed to dominate the setup of your development environment. It is built to run with the **Bun** runtime for speed and efficiency.
6
+
7
+ The tool bundles a collection of OS-specific scripts. It intelligently detects the host operating system (or asks the user) and then executes the appropriate script to configure the system. This approach provides a consistent, reliable, and automated way to provision a new machine.
8
+
9
+ ---
10
+
11
+ ## How It Works: A Step-by-Step Guide
12
+
13
+ The script follows a clear, linear sequence of operations:
14
+
15
+ ### 1. **Initialization**
16
+ - The entry point is `haoshoku.js`.
17
+ - It uses `commander` to parse command-line arguments and define the CLI interface.
18
+
19
+ ### 2. **OS Determination**
20
+ - **Command-Line Argument (`--os`)**: The user can explicitly specify the target OS (e.g., `haoshoku --os cachyos`).
21
+ - **Automatic Detection**: If no argument is provided, the script reads `/etc/os-release` to detect the distribution ID (e.g., `cachyos`, `debian`).
22
+ - **Manual Selection**: If auto-detection fails, the script uses `prompts` to ask the user to select their OS.
23
+
24
+ ### 3. **Script Execution**
25
+ - Once the OS is determined, the corresponding setup function is imported dynamically from `src/os_scripts/`.
26
+ - The setup logic is executed, handling package installation, configuration copying, and system tweaks.
27
+ - Helper functions in `src/common/utils.js` handle command execution (`runCommand`), logging, and checks.
28
+
29
+ ---
30
+
31
+ ## Technical Details
32
+
33
+ The project is built using modern JavaScript (ES Modules) and runs on Bun.
34
+
35
+ ### Key Libraries
36
+
37
+ - **`commander`**: Handles CLI argument parsing and help generation.
38
+ - **`prompts`**: Provides interactive user prompts (selection, confirmation).
39
+ - **`chalk`**: Used for colorful terminal output and logging.
40
+
41
+ ### Architecture
42
+
43
+ - **`haoshoku.js`**: Main entry point. Handles OS detection and routing.
44
+ - **`src/os_scripts/`**: Contains the setup logic for each supported OS (e.g., `cachyos.js`, `debian_server.js`).
45
+ - **`src/common/utils.js`**: Shared utilities for running shell commands, logging, and checking for file/command existence.
46
+ - **`src/helpers/`**: Standalone helper scripts (e.g., `configure_git.js`).
47
+
package/haoshoku.js ADDED
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env bun
2
+ import { Command } from "commander";
3
+ import prompts from "prompts";
4
+ import { log } from "./src/common/utils.js";
5
+ import { runCachyOSSetup } from "./src/os_scripts/cachyos.js";
6
+ import { runDebianServerSetup } from "./src/os_scripts/debian_server.js";
7
+
8
+ import fs from "fs";
9
+
10
+ const program = new Command();
11
+
12
+ program
13
+ .name("haoshoku")
14
+ .description("Haoshoku: Color of the Supreme King. Dominate your setup.")
15
+ .version("2.0.0");
16
+
17
+ function detectOS() {
18
+ try {
19
+ const osRelease = fs.readFileSync("/etc/os-release", "utf-8");
20
+ const lines = osRelease.split("\n");
21
+ const info = {};
22
+ for (const line of lines) {
23
+ const [key, value] = line.split("=");
24
+ if (key && value) {
25
+ info[key] = value.replace(/"/g, "");
26
+ }
27
+ }
28
+
29
+ const id = info["ID"] ? info["ID"].toLowerCase() : "";
30
+ const idLike = info["ID_LIKE"] ? info["ID_LIKE"].toLowerCase() : "";
31
+
32
+ if (id.includes("cachyos") || idLike.includes("arch")) {
33
+ return "cachyos";
34
+ }
35
+ if (id.includes("debian") || idLike.includes("debian")) {
36
+ return "debian-server";
37
+ }
38
+ } catch (e) {
39
+ // Ignore error if file doesn't exist
40
+ }
41
+ return null;
42
+ }
43
+
44
+ program
45
+ .option("--os <type>", "Specify the target OS (cachyos, debian-server)")
46
+ .action(async (options) => {
47
+ let osType = options.os;
48
+
49
+ if (!osType) {
50
+ const detected = detectOS();
51
+ if (detected) {
52
+ log.info(`Detected OS: ${detected}`);
53
+ osType = detected;
54
+ } else {
55
+ const response = await prompts({
56
+ type: "select",
57
+ name: "os",
58
+ message: "Select the target operating system:",
59
+ choices: [
60
+ { title: "CachyOS", value: "cachyos" },
61
+ { title: "Debian Server", value: "debian-server" },
62
+ ],
63
+ });
64
+ osType = response.os;
65
+ }
66
+ }
67
+
68
+ if (!osType) {
69
+ log.error("No OS selected. Exiting.");
70
+ process.exit(1);
71
+ }
72
+
73
+ log.info(`Starting setup for: ${osType}`);
74
+
75
+ switch (osType) {
76
+ case "cachyos":
77
+ await runCachyOSSetup();
78
+ break;
79
+ case "debian-server":
80
+ await runDebianServerSetup();
81
+ break;
82
+ default:
83
+ log.error(`Unsupported OS: ${osType}`);
84
+ process.exit(1);
85
+ }
86
+ });
87
+
88
+ program.parse(process.argv);
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1"
4
+ id="svg8849" inkscape:version="1.1 (c68e22c387, 2021-05-23)" sodipodi:docname="google tasks.svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg"
5
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="527.1px" height="500px"
6
+ viewBox="0 0 527.1 500" enable-background="new 0 0 527.1 500" xml:space="preserve">
7
+ <sodipodi:namedview bordercolor="#eeeeee" borderopacity="1" id="namedview8851" inkscape:bbox-nodes="true" inkscape:bbox-paths="true" inkscape:current-layer="layer1" inkscape:cx="280.62992" inkscape:cy="277.14384" inkscape:document-units="mm" inkscape:object-paths="true" inkscape:pagecheckerboard="0" inkscape:pageopacity="0" inkscape:pageshadow="0" inkscape:snap-bbox="true" inkscape:snap-bbox-edge-midpoints="true" inkscape:snap-bbox-midpoints="true" inkscape:snap-center="true" inkscape:snap-global="true" inkscape:snap-intersection-paths="true" inkscape:snap-midpoints="true" inkscape:snap-object-midpoints="true" inkscape:snap-page="true" inkscape:snap-smooth-nodes="true" inkscape:snap-text-baseline="true" inkscape:window-height="1009" inkscape:window-maximized="1" inkscape:window-width="1920" inkscape:window-x="1912" inkscape:window-y="760" inkscape:zoom="1.4342733" pagecolor="#505050" showgrid="false" units="px">
8
+ </sodipodi:namedview>
9
+ <g>
10
+ <polygon fill="#0066DA" points="410.4,58.3 368.8,81.2 348.2,120.6 368.8,168.8 407.8,211 450,187.5 475.9,142.8 450,87.5 "/>
11
+ <path fill="#2684FC" d="M249.3,219.4l98.9-98.9c29.1,22.1,50.5,53.8,59.6,90.4L272.1,346.7c-12.2,12.2-32,12.2-44.2,0l-91.5-91.5
12
+ c-9.8-9.8-9.8-25.6,0-35.3l39-39c9.8-9.8,25.6-9.8,35.3,0L249.3,219.4z M519.8,63.6l-39.7-39.7c-9.7-9.7-25.6-9.7-35.3,0
13
+ l-34.4,34.4c27.5,23,49.9,51.8,65.5,84.5l43.9-43.9C529.6,89.2,529.6,73.3,519.8,63.6z M412.5,250c0,89.8-72.8,162.5-162.5,162.5
14
+ S87.5,339.8,87.5,250S160.2,87.5,250,87.5c36.9,0,70.9,12.3,98.2,33.1l62.2-62.2C367,21.9,311.1,0,250,0C111.9,0,0,111.9,0,250
15
+ s111.9,250,250,250s250-111.9,250-250c0-38.3-8.7-74.7-24.1-107.2L407.8,211C410.8,223.5,412.5,236.6,412.5,250z"/>
16
+ </g>
17
+ </svg>
Binary file
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" version="1.1" viewBox="0 0 500 500">
3
+ <!-- Generator: Adobe Illustrator 28.7.1, SVG Export Plug-In . SVG Version: 1.2.0 Build 142) -->
4
+ <g>
5
+ <g id="Layer_2">
6
+ <g>
7
+ <circle cx="246.93" cy="249.67" r="240"/>
8
+ <path d="M246.94,117.25c-83.4,0-151,67.04-151,149.77v71.7h27.83v-7.15c0-33.55,27.41-60.75,61.23-60.75s61.23,27.21,61.23,60.75v7.15h27.83v-7.15c0-48.8-39.89-88.33-89.07-88.33-19.15,0-36.89,5.99-51.42,16.21,15.2-29.97,46.51-50.53,82.65-50.53,51.06,0,92.46,41.07,92.46,91.71v38.1h27.84v-38.1c0-65.89-53.86-119.32-120.3-119.32-29.87,0-57.2,10.8-78.24,28.69,20.66-38.73,61.68-65.13,108.95-65.13,68.03,0,123.17,54.69,123.17,122.16v71.7h27.83v-71.7c0-82.72-67.6-149.77-151-149.77Z" fill="#fff"/>
9
+ </g>
10
+ </g>
11
+ </g>
12
+ </svg>
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/icons/zed.png ADDED
Binary file
package/info.txt ADDED
@@ -0,0 +1,3 @@
1
+ gtk- juno-ocean-v40
2
+ theme name ocean - https://store.kde.org/p/1427568/
3
+ cursor - Volantes
package/package.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "haoshoku",
3
+ "version": "2.0.0",
4
+ "module": "haoshoku.js",
5
+ "type": "module",
6
+ "bin": {
7
+ "haoshoku": "haoshoku.js"
8
+ },
9
+ "dependencies": {
10
+ "chalk": "^5.6.2",
11
+ "commander": "^14.0.2",
12
+ "prompts": "^2.4.2"
13
+ }
14
+ }
@@ -0,0 +1,46 @@
1
+ import { spawn } from "bun";
2
+ import chalk from "chalk";
3
+
4
+ export const log = {
5
+ info: (msg) => console.log(chalk.blue(msg)),
6
+ success: (msg) => console.log(chalk.green(msg)),
7
+ warning: (msg) => console.log(chalk.yellow(msg)),
8
+ error: (msg) => console.error(chalk.red(msg)),
9
+ dim: (msg) => console.log(chalk.dim(msg)),
10
+ };
11
+
12
+ export async function runCommand(
13
+ command,
14
+ options = { check: true }
15
+ ) {
16
+ log.dim(`Executing: ${command}`);
17
+
18
+ // Auto-detect shell usage if not explicitly set
19
+ const useShell = options.shell || ["|", "&&", ";", ">", "<", "*", "?", "$", '"', "'"].some(char => command.includes(char));
20
+
21
+ try {
22
+ const proc = spawn(useShell ? ["sh", "-c", command] : command.split(" "), {
23
+ cwd: options.cwd,
24
+ stdout: "inherit",
25
+ stderr: "inherit",
26
+ });
27
+
28
+ const exitCode = await proc.exited;
29
+
30
+ if (options.check && exitCode !== 0) {
31
+ log.error(`Command '${command}' failed with exit code ${exitCode}`);
32
+ return false;
33
+ }
34
+ return exitCode === 0;
35
+ } catch (error) {
36
+ log.error(`Failed to execute command: ${command}`);
37
+ console.error(error);
38
+ return false;
39
+ }
40
+ }
41
+
42
+ export async function commandExists(command) {
43
+ const proc = spawn(["which", command], { stdout: "ignore", stderr: "ignore" });
44
+ const exitCode = await proc.exited;
45
+ return exitCode === 0;
46
+ }
@@ -0,0 +1,130 @@
1
+ import { log, runCommand } from "../common/utils";
2
+ import prompts from "prompts";
3
+ import path from "path";
4
+ import fs from "fs";
5
+ import { homedir } from "os";
6
+
7
+ const HOME = homedir();
8
+ const SSH_DIR = path.join(HOME, ".ssh");
9
+
10
+ async function promptUser(message, initial = false) {
11
+ const response = await prompts({
12
+ type: "confirm",
13
+ name: "value",
14
+ message: message,
15
+ initial: initial,
16
+ });
17
+ return response.value;
18
+ }
19
+
20
+ async function createProfile(profileType) {
21
+ log.info(`--- Setting up ${profileType} Git profile ---`);
22
+ const profileDir = path.join(HOME, profileType);
23
+ fs.mkdirSync(profileDir, { recursive: true });
24
+
25
+ const response = await prompts([
26
+ {
27
+ type: "text",
28
+ name: "email",
29
+ message: `Enter ${profileType} email`,
30
+ },
31
+ {
32
+ type: "text",
33
+ name: "username",
34
+ message: `Enter ${profileType} username`,
35
+ },
36
+ {
37
+ type: "text",
38
+ name: "githubUser",
39
+ message: `Enter GitHub username for ${profileType}`,
40
+ },
41
+ ]);
42
+
43
+ if (!response.email || !response.username || !response.githubUser) {
44
+ log.error("Missing information. Skipping profile creation.");
45
+ return;
46
+ }
47
+
48
+ const keyPath = path.join(SSH_DIR, `${profileType}_key`);
49
+ const gitConfigPath = path.join(profileDir, `.gitconfig.${profileType}`);
50
+
51
+ // Generate SSH Key
52
+ log.info(`Generating SSH key for ${profileType}...`);
53
+ await runCommand(
54
+ `ssh-keygen -t ed25519 -C "${response.email}" -f ${keyPath} -N "" -q`
55
+ );
56
+
57
+ // Add to Agent
58
+ log.info(`Adding ${profileType} SSH key to agent...`);
59
+ await runCommand(`ssh-add ${keyPath}`);
60
+
61
+ // Create Git Config
62
+ const gitConfigContent = `[user]
63
+ email = ${response.email}
64
+ name = ${response.username}
65
+ signingkey = ${keyPath}
66
+
67
+ [github]
68
+ user = "${response.githubUser}"
69
+
70
+ [commit]
71
+ gpgsign = true
72
+
73
+ [gpg]
74
+ format = ssh
75
+
76
+ [core]
77
+ sshCommand = "ssh -i ${keyPath}"
78
+ `;
79
+
80
+ fs.writeFileSync(gitConfigPath, gitConfigContent);
81
+ log.info(`Created ${gitConfigPath}`);
82
+ }
83
+
84
+ export async function configureGit() {
85
+ log.info("Configuring Git...");
86
+ fs.mkdirSync(SSH_DIR, { mode: 0o700, recursive: true });
87
+
88
+ // Start SSH Agent
89
+ try {
90
+ const agentProc = Bun.spawn(["ssh-agent", "-s"]);
91
+ const output = await new Response(agentProc.stdout).text();
92
+ const match = output.match(/SSH_AUTH_SOCK=([^;]+);/);
93
+ if (match) {
94
+ process.env.SSH_AUTH_SOCK = match[1];
95
+ }
96
+ const pidMatch = output.match(/SSH_AGENT_PID=([^;]+);/);
97
+ if (pidMatch) {
98
+ process.env.SSH_AGENT_PID = pidMatch[1];
99
+ }
100
+ } catch (e) {
101
+ log.warning("Could not start ssh-agent.");
102
+ }
103
+
104
+ let workProfileCreated = false;
105
+ if (await promptUser("Do you want to create a work Git profile?", true)) {
106
+ await createProfile("work");
107
+ workProfileCreated = true;
108
+ }
109
+
110
+ await createProfile("personal");
111
+
112
+ // Global Config
113
+ let globalConfigContent = `[includeIf "gitdir:~/personal/"]
114
+ path = ~/personal/.gitconfig.personal
115
+ `;
116
+
117
+ if (workProfileCreated) {
118
+ globalConfigContent += `[includeIf "gitdir:~/work/"]
119
+ path = ~/work/.gitconfig.work
120
+ `;
121
+ }
122
+
123
+ const globalGitConfigPath = path.join(HOME, ".gitconfig");
124
+ fs.writeFileSync(globalGitConfigPath, globalConfigContent);
125
+
126
+ log.info(`Created global git config at ${globalGitConfigPath}`);
127
+ log.warning(
128
+ "ACTION REQUIRED: Copy the contents of the .pub files in ~/.ssh and add them to your GitHub accounts."
129
+ );
130
+ }