diff --git a/.gitignore b/.gitignore index e43b0f9..646ac51 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .DS_Store +node_modules/ diff --git a/README.md b/README.md index 8e0c642..9827253 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ sh -c "$(curl -fsLS https://raw.githubusercontent.com/willmruzek/dotfiles/master chezmoi init --apply willmruzek ``` +**Note:** The installation scripts use [google/zx](https://github.com/google/zx) for better shell scripting. Node.js will be installed automatically if not present. + ## What's Included - **Git configuration** (`.gitconfig`) @@ -74,13 +76,13 @@ Minimal helpers to move VS Code user settings between your Mac and this repo. Re - Export local → repo: ```bash - ./home/.scripts/export-vscode-settings.sh + ./home/.scripts/export-vscode-settings.mjs ``` - Import repo → local (preview first by default): ```bash - ./home/.scripts/import-vscode-settings.sh + ./home/.scripts/import-vscode-settings.mjs # flags: -n/--dry-run (preview only), -y/--yes (auto-approve) ``` diff --git a/home/.chezmoiscripts/run_once_after_99_setup-complete.sh b/home/.chezmoiscripts/run_once_after_99_setup-complete.sh deleted file mode 100644 index 42d5cae..0000000 --- a/home/.chezmoiscripts/run_once_after_99_setup-complete.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -set -e - -echo "✨ Setup complete!" diff --git a/home/.chezmoiscripts/run_once_after_99_setup-complete.ts b/home/.chezmoiscripts/run_once_after_99_setup-complete.ts new file mode 100755 index 0000000..6f64d8d --- /dev/null +++ b/home/.chezmoiscripts/run_once_after_99_setup-complete.ts @@ -0,0 +1,3 @@ +#!/usr/bin/env zx + +echo`✨ Setup complete!` diff --git a/home/.chezmoiscripts/run_once_before_00_setup-start.sh b/home/.chezmoiscripts/run_once_before_00_setup-start.sh old mode 100644 new mode 100755 diff --git a/home/.chezmoiscripts/run_once_before_01_install-homebrew.sh b/home/.chezmoiscripts/run_once_before_01_install-homebrew.sh old mode 100644 new mode 100755 index 7fb8605..ec72abf --- a/home/.chezmoiscripts/run_once_before_01_install-homebrew.sh +++ b/home/.chezmoiscripts/run_once_before_01_install-homebrew.sh @@ -17,8 +17,10 @@ if ! command -v brew &> /dev/null; then echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile eval "$(/opt/homebrew/bin/brew shellenv)" fi + echo "✅ Homebrew installed" else echo "⏭️ Skipping Homebrew installation" + exit 0 fi else echo "✅ Homebrew is already installed" diff --git a/home/.chezmoiscripts/run_once_before_02_configure-touch-id-for-sudo.sh b/home/.chezmoiscripts/run_once_before_02_configure-touch-id-for-sudo.sh deleted file mode 100644 index e4a386f..0000000 --- a/home/.chezmoiscripts/run_once_before_02_configure-touch-id-for-sudo.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -set -e - -# Configure Touch ID for sudo -if [ ! -f /etc/pam.d/sudo_local ]; then - echo "🔐 Setting up Touch ID for sudo..." - sudo cp /etc/pam.d/sudo_local.template /etc/pam.d/sudo_local - echo "auth sufficient pam_tid.so" | sudo tee -a /etc/pam.d/sudo_local - echo "✅ Touch ID for sudo configured" -elif ! grep -q "pam_tid.so" /etc/pam.d/sudo_local; then - echo "🔐 Adding Touch ID authentication to existing sudo_local..." - echo "auth sufficient pam_tid.so" | sudo tee -a /etc/pam.d/sudo_local - echo "✅ Touch ID for sudo configured" -else - echo "✅ Touch ID for sudo already configured" -fi diff --git a/home/.chezmoiscripts/run_once_before_02_install-brewfile-packages.sh b/home/.chezmoiscripts/run_once_before_02_install-brewfile-packages.sh new file mode 100755 index 0000000..cf99291 --- /dev/null +++ b/home/.chezmoiscripts/run_once_before_02_install-brewfile-packages.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Install packages from Brewfile if it exists (only if Homebrew is available) +if command -v brew &> /dev/null && [ -f "$HOME/.Brewfile" ]; then + echo "📋 Installing packages from Brewfile..." + export HOMEBREW_BUNDLE_FILE="$HOME/.Brewfile" + brew bundle install +elif ! command -v brew &> /dev/null; then + echo "⚠️ Homebrew not available, skipping package installation" +else + echo "⚠️ No Brewfile found, skipping package installation" +fi diff --git a/home/.chezmoiscripts/run_once_before_03_install-zx.sh b/home/.chezmoiscripts/run_once_before_03_install-zx.sh new file mode 100755 index 0000000..01d6ced --- /dev/null +++ b/home/.chezmoiscripts/run_once_before_03_install-zx.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +set -e + +# Verify zx is available after npm install +# zx is installed as a dependency in package.json + +if command -v npx &> /dev/null; then + echo "✅ npx is available" + + # Check if zx is available via npx + if npx zx --version &> /dev/null; then + echo "✅ zx is available via npx" + else + echo "⚠️ zx not yet available via npx (will be installed by npm install)" + fi +else + echo "❌ npx not found. Node.js must be installed first." + echo " Please install Node.js before running this script." + exit 1 +fi diff --git a/home/.chezmoiscripts/run_once_before_04_install-npm-dependencies.sh b/home/.chezmoiscripts/run_once_before_04_install-npm-dependencies.sh new file mode 100755 index 0000000..e695441 --- /dev/null +++ b/home/.chezmoiscripts/run_once_before_04_install-npm-dependencies.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +set -e + +# Check if npm is available +if ! command -v npm &> /dev/null; then + echo "⚠️ npm not available, skipping dependency installation" + exit 0 +fi + +# Find the repository root by looking for package.json +# Start from the current directory and walk up +CURRENT_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="" + +while [ "$CURRENT_DIR" != "/" ]; do + if [ -f "$CURRENT_DIR/package.json" ]; then + REPO_ROOT="$CURRENT_DIR" + break + fi + CURRENT_DIR="$(dirname "$CURRENT_DIR")" +done + +# Check if we found the repository root +if [ -z "$REPO_ROOT" ]; then + echo "⚠️ package.json not found in any parent directory, skipping dependency installation" + exit 0 +fi + +echo "📦 Installing npm dependencies..." +cd "$REPO_ROOT" +npm install + +echo "✅ npm dependencies installed" diff --git a/home/.chezmoiscripts/run_once_before_05_configure-touch-id-for-sudo.ts b/home/.chezmoiscripts/run_once_before_05_configure-touch-id-for-sudo.ts new file mode 100755 index 0000000..2849550 --- /dev/null +++ b/home/.chezmoiscripts/run_once_before_05_configure-touch-id-for-sudo.ts @@ -0,0 +1,80 @@ +#!/usr/bin/env zx + +import { ResultAsync, err, ok } from 'neverthrow' + +// Configure Touch ID for sudo +const sudoLocalPath = "/etc/pam.d/sudo_local" + +// Helper to check if file exists +const fileExists = (path: string): ResultAsync => + ResultAsync.fromPromise( + fs.access(path).then(() => true), + () => new Error(`File does not exist: ${path}`) + ).orElse(() => ok(false)) + +// Helper to read file content +const readFile = (path: string): ResultAsync => + ResultAsync.fromPromise( + fs.readFile(path, 'utf8'), + (e) => new Error(`Failed to read file: ${e}`) + ) + +// Helper to execute shell command +const runCommand = (command: ProcessPromise): ResultAsync => + ResultAsync.fromPromise( + command.then(() => undefined), + (e) => new Error(`Command failed: ${e}`) + ) + +// Main logic +const configureTouchID = async () => { + const exists = await fileExists(sudoLocalPath) + + if (exists.isErr()) { + return exists + } + + if (exists.value) { + // File exists, check if pam_tid.so is already configured + const contentResult = await readFile(sudoLocalPath) + + if (contentResult.isErr()) { + return contentResult + } + + if (!contentResult.value.includes("pam_tid.so")) { + echo`🔐 Adding Touch ID authentication to existing sudo_local...` + const result = await runCommand($`echo "auth sufficient pam_tid.so" | sudo tee -a ${sudoLocalPath}`) + if (result.isErr()) { + return result + } + echo`✅ Touch ID for sudo configured` + } else { + echo`✅ Touch ID for sudo already configured` + } + } else { + // File doesn't exist + echo`🔐 Setting up Touch ID for sudo...` + const copyResult = await runCommand($`sudo cp /etc/pam.d/sudo_local.template ${sudoLocalPath}`) + if (copyResult.isErr()) { + return copyResult + } + + const appendResult = await runCommand($`echo "auth sufficient pam_tid.so" | sudo tee -a ${sudoLocalPath}`) + if (appendResult.isErr()) { + return appendResult + } + + echo`✅ Touch ID for sudo configured` + } + + return ok(undefined) +} + +// Execute and handle result +const result = await configureTouchID() + +if (result.isErr()) { + echo`❌ Error: ${result.error.message}` + process.exit(1) +} diff --git a/home/.chezmoiscripts/run_onchange_after_00_install-brewfile-packages.sh.tmpl b/home/.chezmoiscripts/run_onchange_after_00_install-brewfile-packages.sh.tmpl old mode 100644 new mode 100755 diff --git a/home/.scripts/export-vscode-settings.sh b/home/.scripts/export-vscode-settings.sh deleted file mode 100755 index 7190aa1..0000000 --- a/home/.scripts/export-vscode-settings.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -# export-vscode-settings.sh - Export VS Code settings from local VS Code User directory into the repo -# -# Usage: -# ./export-vscode-settings.sh -# -# Exports: -# - mcp.json -# - keybindings.json -# - settings.json -# - prompts/ (recursive) - -# Ensure git is available -if ! command -v git >/dev/null 2>&1; then - echo "Error: git not found. Install git." >&2 - exit 1 -fi - -# Ensure rsync is available -if ! command -v rsync >/dev/null 2>&1; then - echo "Error: rsync not found. Install rsync." >&2 - exit 1 -fi - -# Centralized include patterns for rsync -INCLUDES=( - /mcp.json - /keybindings.json - /settings.json - /prompts/*** -) -INCLUDE_ARGS=() -for p in "${INCLUDES[@]}"; do - INCLUDE_ARGS+=("--include=$p") -done - -script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd -P)" -repo_root="$(git -C "$script_dir" rev-parse --show-toplevel 2>/dev/null)" - -if [[ -z "${repo_root}" ]]; then - echo "Error: Could not determine destination path" >&2 - exit 1 -fi - -dest="$repo_root/home/.vscode" -src="$HOME/Library/Application Support/Code/User" - -# Skip gracefully if source directory does not exist -if [[ ! -d "$src" ]]; then - echo "Error: Source VS Code User directory not found: $src." >&2 - exit 1 -fi - -mkdir -p "$dest" - -rsync -a --delete \ - "${INCLUDE_ARGS[@]}" \ - --exclude='*' \ - "$src/" "$dest/" - -echo "VS Code settings exported successfully." diff --git a/home/.scripts/export-vscode-settings.ts b/home/.scripts/export-vscode-settings.ts new file mode 100755 index 0000000..f7af596 --- /dev/null +++ b/home/.scripts/export-vscode-settings.ts @@ -0,0 +1,63 @@ +#!/usr/bin/env zx + +// export-vscode-settings.ts - Export VS Code settings from local VS Code User directory into the repo +// +// Usage: +// ./export-vscode-settings.ts +// +// Exports: +// - mcp.json +// - keybindings.json +// - settings.json +// - prompts/ (recursive) + +// Ensure git is available +try { + await $`command -v git` +} catch (error) { + echo`Error: git not found. Install git.` + process.exit(1) +} + +// Ensure rsync is available +try { + await $`command -v rsync` +} catch (error) { + echo`Error: rsync not found. Install rsync.` + process.exit(1) +} + +// Centralized include patterns for rsync +const includes = [ + '/mcp.json', + '/keybindings.json', + '/settings.json', + '/prompts/***' +] + +const includeArgs = includes.flatMap(p => ['--include', p]) + +const scriptDir = __dirname +const repoRoot = (await $`git -C ${scriptDir} rev-parse --show-toplevel`).stdout + +if (!repoRoot) { + echo`Error: Could not determine destination path` + process.exit(1) +} + +const dest = `${repoRoot}/home/.vscode` +const src = `${process.env.HOME}/Library/Application Support/Code/User` + +// Skip gracefully if source directory does not exist +try { + await fs.access(src) +} catch (error) { + echo`Error: Source VS Code User directory not found: ${src}.` + process.exit(1) +} + +await fs.mkdir(dest, { recursive: true }) + +await $`rsync -a --delete ${includeArgs} --exclude='*' ${src}/ ${dest}/` + +echo`VS Code settings exported successfully.` diff --git a/home/.scripts/import-vscode-settings.sh b/home/.scripts/import-vscode-settings.sh deleted file mode 100755 index 484f107..0000000 --- a/home/.scripts/import-vscode-settings.sh +++ /dev/null @@ -1,144 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -# import-vscode-settings.sh - Import VS Code settings from repo into the local VS Code User directory -# -# Usage: -# ./import-vscode-settings.sh [--dry-run|-n] [--yes|-y] -# -# Options: -# -n, --dry-run Preview diffs only; no backup or changes -# -y, --yes Auto-approve import (non-interactive) -# -# Imports: -# - mcp.json -# - keybindings.json -# - settings.json -# - prompts/ (recursive) - -# Ensure git is available -if ! command -v git >/dev/null 2>&1; then - echo "Error: git not found. Install git." >&2 - exit 1 -fi - -# Ensure rsync is available -if ! command -v rsync >/dev/null 2>&1; then - echo "Error: rsync not found. Install rsync." >&2 - exit 1 -fi - -# Flags -AUTO_YES=0 -DRY_RUN=0 -for arg in "$@"; do - case "$arg" in - --yes|-y) AUTO_YES=1 ;; - --dry-run|-n) DRY_RUN=1 ;; - esac -done - -# Centralized include patterns for rsync -INCLUDES=( - /mcp.json - /keybindings.json - /settings.json - /prompts/*** -) -INCLUDE_ARGS=() -for p in "${INCLUDES[@]}"; do - INCLUDE_ARGS+=("--include=$p") -done - -script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd -P)" -repo_root="$(git -C "$script_dir" rev-parse --show-toplevel 2>/dev/null)" - -# Ensure repo root is determined -if [[ -z "${repo_root}" ]]; then - echo "Error: Could not determine source path" >&2 - exit 1 -fi - -src="$repo_root/home/.vscode" -dest="$HOME/Library/Application Support/Code/User" - -# Ensure source directory exists -if [[ ! -d "$src" ]]; then - echo "Error: Source repo VS Code directory not found: $src." >&2 - exit 1 -fi - -# Ensure VS Code User directory exists -if [[ ! -d "$dest" ]]; then - echo "Error: Destination VS Code User directory not found: $dest." >&2 - exit 1 -fi - -# If dry-run, note it early -if [[ $DRY_RUN -eq 1 ]]; then - echo "Dry run: will preview changes only. No backup or import will be performed." >&2 -fi - -# Backup existing settings into $dest/.dotfiles_backup/ -if [[ $DRY_RUN -eq 0 ]]; then - backup_root="$dest/.dotfiles_backup" - backup_dir="$backup_root/$(date +%Y%m%d-%H%M%S)" - mkdir -p "$backup_dir" - rsync -a \ - "${INCLUDE_ARGS[@]}" \ - --exclude='/.dotfiles_backup/***' \ - --exclude='*' \ - "$dest/" "$backup_dir/" - echo "Backup created at: $backup_dir" >&2 -fi - -# Preview planned changes using git-style color diff and require approval -changes=0 -json_files=(mcp keybindings settings) - -echo "Planned changes:" >&2 -echo "" >&2 -for f in "${json_files[@]}"; do - src_f="$src/$f.json" - dest_f="$dest/$f.json" - if [[ -f "$src_f" || -f "$dest_f" ]]; then - if ! git --no-pager diff --no-index --quiet -- "$dest_f" "$src_f"; then - changes=1 - git --no-pager diff --no-index --color -- "$dest_f" "$src_f" || true - fi - fi -done - -if [[ -d "$src/prompts" || -d "$dest/prompts" ]]; then - if ! git --no-pager diff --no-index --quiet -- "$dest/prompts" "$src/prompts"; then - changes=1 - git --no-pager diff --no-index --color -- "$dest/prompts" "$src/prompts" || true - fi -fi - -if [[ $changes -eq 0 ]]; then - echo "No changes to import. Exiting." >&2 - exit 0 -fi - -# If dry-run, stop here after preview -if [[ $DRY_RUN -eq 1 ]]; then - echo "Dry run complete. Changes were not applied." >&2 - exit 0 -fi - -# Confirm import unless auto-approved -if [[ $AUTO_YES -eq 0 ]]; then - read -r -p "Proceed with import? [y/N]: " _ans &2; exit 1;; - esac -fi - -# Import from repo into local VS Code User directory -rsync -a \ - "${INCLUDE_ARGS[@]}" \ - --exclude='*' \ - "$src/" "$dest/" diff --git a/home/.scripts/import-vscode-settings.ts b/home/.scripts/import-vscode-settings.ts new file mode 100755 index 0000000..d9fdd05 --- /dev/null +++ b/home/.scripts/import-vscode-settings.ts @@ -0,0 +1,183 @@ +#!/usr/bin/env zx + +// import-vscode-settings.ts - Import VS Code settings from repo into the local VS Code User directory +// +// Usage: +// ./import-vscode-settings.ts [--dry-run|-n] [--yes|-y] +// +// Options: +// -n, --dry-run Preview diffs only; no backup or changes +// -y, --yes Auto-approve import (non-interactive) +// +// Imports: +// - mcp.json +// - keybindings.json +// - settings.json +// - prompts/ (recursive) + +// Ensure git is available +try { + await $`command -v git` +} catch (error) { + echo`Error: git not found. Install git.` + process.exit(1) +} + +// Ensure rsync is available +try { + await $`command -v rsync` +} catch (error) { + echo`Error: rsync not found. Install rsync.` + process.exit(1) +} + +// Parse flags +let autoYes = false +let dryRun = false + +for (const arg of process.argv.slice(3)) { + if (arg === '--yes' || arg === '-y') { + autoYes = true + } else if (arg === '--dry-run' || arg === '-n') { + dryRun = true + } +} + +// Centralized include patterns for rsync +const includes = [ + '/mcp.json', + '/keybindings.json', + '/settings.json', + '/prompts/***' +] + +const includeArgs = includes.flatMap(p => ['--include', p]) + +const scriptDir = __dirname +const repoRoot = (await $`git -C ${scriptDir} rev-parse --show-toplevel`).stdout.trim() + +// Ensure repo root is determined +if (!repoRoot) { + echo`Error: Could not determine source path` + process.exit(1) +} + +const src = `${repoRoot}/home/.vscode` +const dest = `${process.env.HOME}/Library/Application Support/Code/User` + +// Ensure source directory exists +try { + await fs.access(src) +} catch (error) { + echo`Error: Source repo VS Code directory not found: ${src}.` + process.exit(1) +} + +// Ensure VS Code User directory exists +try { + await fs.access(dest) +} catch (error) { + echo`Error: Destination VS Code User directory not found: ${dest}.` + process.exit(1) +} + +// If dry-run, note it early +if (dryRun) { + echo`Dry run: will preview changes only. No backup or import will be performed.` +} + +// Backup existing settings into $dest/.dotfiles_backup/ +if (!dryRun) { + const backupRoot = `${dest}/.dotfiles_backup` + const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19).replace('T', '-') + const backupDir = `${backupRoot}/${timestamp}` + await fs.mkdir(backupDir, { recursive: true }) + + await $`rsync -a ${includeArgs} --exclude='/.dotfiles_backup/***' --exclude='*' ${dest}/ ${backupDir}/` + echo`Backup created at: ${backupDir}` +} + +// Preview planned changes using git-style color diff and require approval +let changes = 0 +const jsonFiles = ['mcp', 'keybindings', 'settings'] + +echo`Planned changes:` +echo`` + +for (const f of jsonFiles) { + const srcFile = `${src}/${f}.json` + const destFile = `${dest}/${f}.json` + + try { + await fs.access(srcFile) + const hasFile = true + } catch (e) { + const hasFile = false + } + + try { + await fs.access(destFile) + const hasFile = true + } catch (e) { + const hasFile = false + } + + try { + await $`git --no-pager diff --no-index --quiet -- ${destFile} ${srcFile}` + } catch (error) { + changes = 1 + try { + await $`git --no-pager diff --no-index --color -- ${destFile} ${srcFile}` + } catch (e) { + // Diff returned non-zero, which is expected + } + } +} + +try { + await fs.access(`${src}/prompts`) + const hasSrcPrompts = true +} catch (e) { + const hasSrcPrompts = false +} + +try { + await fs.access(`${dest}/prompts`) + const hasDestPrompts = true +} catch (e) { + const hasDestPrompts = false +} + +try { + await $`git --no-pager diff --no-index --quiet -- ${dest}/prompts ${src}/prompts` +} catch (error) { + changes = 1 + try { + await $`git --no-pager diff --no-index --color -- ${dest}/prompts ${src}/prompts` + } catch (e) { + // Diff returned non-zero, which is expected + } +} + +if (changes === 0) { + echo`No changes to import. Exiting.` + process.exit(0) +} + +// If dry-run, stop here after preview +if (dryRun) { + echo`Dry run complete. Changes were not applied.` + process.exit(0) +} + +// Confirm import unless auto-approved +if (!autoYes) { + const answer = await question("Proceed with import? [y/N]: ") + if (!answer.match(/^[yY]([eE][sS])?$/)) { + echo`Aborted.` + process.exit(1) + } +} + +// Import from repo into local VS Code User directory +await $`rsync -a ${includeArgs} --exclude='*' ${src}/ ${dest}/` diff --git a/home/dot_Brewfile.tmpl b/home/dot_Brewfile.tmpl index 118ae6a..7b66457 100644 --- a/home/dot_Brewfile.tmpl +++ b/home/dot_Brewfile.tmpl @@ -3,6 +3,7 @@ brew "starship" brew "fzf" brew "gh" brew "tree" +brew "node@24" {{- if eq .machineType "personal" }} brew "gpg" brew "mas" diff --git a/install.sh b/install.sh index 48a248a..985d226 100755 --- a/install.sh +++ b/install.sh @@ -2,13 +2,14 @@ set -e # -e: exit on error +# Install chezmoi if not present if [ ! "$(command -v chezmoi)" ]; then bin_dir="$HOME/.local/bin" chezmoi="$bin_dir/chezmoi" if [ "$(command -v curl)" ]; then - sh -c "$(curl -fsSL https://git.io/chezmoi)" -- -b "$bin_dir" + sh -c "$(curl -fsLS get.chezmoi.io)" -- -b "$bin_dir" elif [ "$(command -v wget)" ]; then - sh -c "$(wget -qO- https://git.io/chezmoi)" -- -b "$bin_dir" + sh -c "$(wget -qO- get.chezmoi.io)" -- -b "$bin_dir" else echo "To install chezmoi, you must have curl or wget installed." >&2 exit 1 @@ -19,7 +20,6 @@ fi # POSIX way to get script's dir: https://stackoverflow.com/a/29834779/12156188 script_dir="$(cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P)" -echo $script_dir # exec: replace current process with chezmoi init exec "$chezmoi" init --apply "--source=$script_dir" diff --git a/package.json b/package.json new file mode 100644 index 0000000..53fff45 --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "dotfiles", + "version": "1.0.0", + "description": "Personal dotfiles managed with chezmoi and zx", + "type": "module", + "scripts": { + "export-vscode": "zx home/.scripts/export-vscode-settings.ts", + "import-vscode": "zx home/.scripts/import-vscode-settings.ts" + }, + "dependencies": { + "neverthrow": "^8.1.1", + "zx": "^8.2.4" + }, + "devDependencies": { + "@types/node": "^22.10.1", + "typescript": "^5.7.2" + }, + "engines": { + "node": ">=24.0.0" + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..2c8d6fc --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "lib": ["ES2024"], + "module": "nodenext", + "target": "ES2024", + "moduleResolution": "nodenext", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "noEmit": true, + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "types": ["node"] + }, + "include": [ + "home/.scripts/**/*.ts", + "home/.chezmoiscripts/**/*.ts" + ] +}