Add CLAUDE.md, SPEC.md and bootstrap scripts
This commit is contained in:
parent
8e413ab06d
commit
fb74a820dc
6 changed files with 1042 additions and 0 deletions
121
CLAUDE.md
Normal file
121
CLAUDE.md
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
# CLAUDE.md - Instructions for Claude Code
|
||||
|
||||
## Project context
|
||||
|
||||
MSP deployment script for X9.cz - automated preparation of new Windows 10/11 computers for clients.
|
||||
Replaces ~3 hours of manual setup with a single PowerShell script.
|
||||
|
||||
**Key parameters:**
|
||||
- Target OS: Windows 10 and Windows 11 (x64), including unsupported HW
|
||||
- Execution: as Administrator on already-installed Windows (not WinPE/autounattend)
|
||||
- Volume: ~20 machines per month, various clients
|
||||
- Operator: MSP technician on-site at client
|
||||
|
||||
---
|
||||
|
||||
## Repo structure
|
||||
|
||||
```
|
||||
windows-deployment/
|
||||
├── CLAUDE.md <- this file
|
||||
├── SPEC.md <- technical specification
|
||||
├── Deploy-Windows.ps1 <- master script (entry point)
|
||||
├── scripts/
|
||||
│ ├── 01-bloatware.ps1 <- remove AppX, Capabilities, Features
|
||||
│ ├── 02-software.ps1 <- winget installs + Adobe PDF default
|
||||
│ ├── 03-system-registry.ps1 <- HKLM tweaks
|
||||
│ ├── 04-default-profile.ps1 <- C:\Users\Default\NTUSER.DAT changes
|
||||
│ ├── 05-personalization.ps1 <- colors, wallpaper, theme
|
||||
│ ├── 06-scheduled-tasks.ps1 <- register scheduled tasks
|
||||
│ └── 07-desktop-info.ps1 <- custom desktop info (replaces BackInfo)
|
||||
├── config/
|
||||
│ └── config.json <- per-client config (future)
|
||||
├── assets/
|
||||
│ └── DesktopInfo/ <- resources for desktop info script
|
||||
└── tests/
|
||||
└── Test-Deployment.ps1 <- post-deployment verification
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Conventions and rules
|
||||
|
||||
### PowerShell
|
||||
- Always `#Requires -RunAsAdministrator` in master script
|
||||
- `$ErrorActionPreference = "Continue"` - script must survive partial failures
|
||||
- Log every step to `C:\Windows\Setup\Scripts\Deploy.log`
|
||||
- Logging via `Write-Log` function defined in master script
|
||||
- `Invoke-Step` function wraps every step - catches errors, logs, continues
|
||||
- Comments in English, code in English
|
||||
- NO diacritics - no accented characters anywhere: not in comments, not in user messages, not in log output
|
||||
- NO emoticons - not in comments, not in output messages
|
||||
- Reason: encoding issues across systems, log readability, compatibility
|
||||
|
||||
### Master script structure
|
||||
```powershell
|
||||
# 1. Load config.json
|
||||
# 2. Run individual scripts in order
|
||||
# 3. Print summary report at end (OK/ERROR counts)
|
||||
```
|
||||
|
||||
### Master script switches
|
||||
| Switch | Behavior |
|
||||
|---|---|
|
||||
| `-SkipBloatware` | Skip step 1 |
|
||||
| `-SkipSoftware` | Skip step 2 |
|
||||
| `-SkipDefaultProfile` | Skip step 4 |
|
||||
| `-DryRun` | Run without changes, log only |
|
||||
|
||||
### Testing
|
||||
- Test VM: Windows 10/11 x64 on VMware ESXi (X9.cz internal infrastructure)
|
||||
- Before each test: take snapshot
|
||||
- After test: revert snapshot
|
||||
- Dev environment: x64 VM only - NOT ARM (no Parallels/Apple Silicon for testing)
|
||||
|
||||
---
|
||||
|
||||
## Important notes
|
||||
|
||||
### BackInfo replacement - custom solution
|
||||
BackInfo.exe is NOT used. Instead: custom scheduled task DesktopInfo:
|
||||
- Triggers on every user logon
|
||||
- PS script reads: hostname, IP, Windows version, username, install date
|
||||
- Renders text onto desktop via WPF/System.Drawing -> saves as BMP -> sets as wallpaper
|
||||
- Works on Win10 and Win11 without registry hacks
|
||||
|
||||
### Adobe Reader as default PDF app
|
||||
- After install: set .pdf -> AcroRd32 association
|
||||
- Scheduled task PDF-DefaultApp restores association on every logon (guard against Edge overwriting it)
|
||||
|
||||
### Default Profile
|
||||
- Changes to C:\Users\Default\NTUSER.DAT via reg load / reg unload
|
||||
- Applies to all new users - critical for MSP deployment
|
||||
- Currently logged-in user gets changes via direct write to HKCU
|
||||
|
||||
### Winget
|
||||
- Always use --accept-package-agreements --accept-source-agreements
|
||||
- Check winget availability before running installs
|
||||
- Log result of every install
|
||||
|
||||
---
|
||||
|
||||
## DO NOT
|
||||
|
||||
- Do not use $ErrorActionPreference = "Stop" - script must survive partial failure
|
||||
- Do not remove Calculator (Microsoft.WindowsCalculator) - intentionally kept
|
||||
- Do not use ARM VM for testing
|
||||
- Do not write scripts depending on specific username - script is universal
|
||||
- Do not use hardcoded paths that do not exist on clean Windows
|
||||
- NO diacritics - no accented characters in any part of any script
|
||||
- NO emoticons - none in comments, log messages or output
|
||||
|
||||
---
|
||||
|
||||
## Open questions
|
||||
|
||||
| # | Question | Status |
|
||||
|---|---|---|
|
||||
| 1 | BackInfo replacement | DONE - custom PS scheduled task DesktopInfo |
|
||||
| 2 | Complete SW list for winget | TODO - list incomplete |
|
||||
| 3 | Per-client variability via config.json | FUTURE |
|
||||
| 4 | Admin account adminx9 - script or manual? | OPEN |
|
||||
137
Remove-ClaudeCode.ps1
Normal file
137
Remove-ClaudeCode.ps1
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
#Requires -Version 5.1
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Claude Code - odstraneni citlivych dat a volitelne cele instalace
|
||||
.USAGE
|
||||
# Jen citliva data (API key + repo):
|
||||
.\Remove-ClaudeCode.ps1 -RepoPath "C:\Projects\windows-deployment"
|
||||
|
||||
# Vse vcetne Claude Code a Node.js:
|
||||
.\Remove-ClaudeCode.ps1 -RepoPath "C:\Projects\windows-deployment" -Full
|
||||
#>
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string] $RepoPath,
|
||||
|
||||
[switch] $Full
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Continue"
|
||||
|
||||
function Write-Step { param([string]$Msg) Write-Host "`n[REMOVE] $Msg" -ForegroundColor Yellow }
|
||||
function Write-OK { param([string]$Msg) Write-Host " OK: $Msg" -ForegroundColor Green }
|
||||
function Write-Skip { param([string]$Msg) Write-Host " SKIP: $Msg" -ForegroundColor DarkGray }
|
||||
|
||||
Write-Host "`n========================================" -ForegroundColor Red
|
||||
Write-Host " Claude Code Cleanup" -ForegroundColor Red
|
||||
Write-Host "========================================`n" -ForegroundColor Red
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# 1. API KEY
|
||||
# ------------------------------------------------------------
|
||||
Write-Step "Removing ANTHROPIC_API_KEY..."
|
||||
|
||||
[System.Environment]::SetEnvironmentVariable("ANTHROPIC_API_KEY", $null, "User")
|
||||
[System.Environment]::SetEnvironmentVariable("ANTHROPIC_API_KEY", $null, "Machine")
|
||||
$env:ANTHROPIC_API_KEY = $null
|
||||
Write-OK "API key removed from environment variables"
|
||||
|
||||
# Claude Code si uklada API key take v ~/.claude
|
||||
$claudeConfig = Join-Path $HOME ".claude"
|
||||
if (Test-Path $claudeConfig) {
|
||||
Remove-Item $claudeConfig -Recurse -Force
|
||||
Write-OK "Removed ~/.claude config directory"
|
||||
} else {
|
||||
Write-Skip "~/.claude not found"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# 2. REPO
|
||||
# ------------------------------------------------------------
|
||||
Write-Step "Removing repository at $RepoPath..."
|
||||
|
||||
if (Test-Path $RepoPath) {
|
||||
# Nejdriv over ze je to skutecne git repo - pojistka
|
||||
$gitDir = Join-Path $RepoPath ".git"
|
||||
if (Test-Path $gitDir) {
|
||||
Remove-Item $RepoPath -Recurse -Force
|
||||
Write-OK "Repository removed"
|
||||
} else {
|
||||
Write-Host " WARN: $RepoPath does not look like a git repo. Skipping for safety." -ForegroundColor Yellow
|
||||
}
|
||||
} else {
|
||||
Write-Skip "Repo path not found: $RepoPath"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# 3. GIT CREDENTIALS (pokud byly ulozeny)
|
||||
# ------------------------------------------------------------
|
||||
Write-Step "Clearing git credentials for repo..."
|
||||
|
||||
try {
|
||||
git credential reject | Out-Null
|
||||
} catch {}
|
||||
|
||||
# Windows Credential Manager - GitHub tokeny
|
||||
try {
|
||||
$creds = cmdkey /list 2>$null | Select-String "github"
|
||||
foreach ($cred in $creds) {
|
||||
$target = ($cred -split '\s+') | Where-Object { $_ -like "*github*" } | Select-Object -First 1
|
||||
if ($target) {
|
||||
cmdkey /delete:$target | Out-Null
|
||||
Write-OK "Removed credential: $target"
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Write-Skip "No GitHub credentials found in Credential Manager"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# 4. VOLITELNE - Claude Code + Node.js
|
||||
# ------------------------------------------------------------
|
||||
if ($Full) {
|
||||
Write-Step "Uninstalling Claude Code..."
|
||||
try {
|
||||
npm uninstall -g @anthropic-ai/claude-code
|
||||
Write-OK "Claude Code uninstalled"
|
||||
} catch {
|
||||
Write-Skip "Claude Code not installed via npm or npm not available"
|
||||
}
|
||||
|
||||
Write-Step "Uninstalling Node.js..."
|
||||
try {
|
||||
winget uninstall OpenJS.NodeJS.LTS --silent
|
||||
Write-OK "Node.js uninstalled"
|
||||
} catch {
|
||||
Write-Skip "Node.js not found via winget - remove manually if needed"
|
||||
}
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# 5. POWERSHELL HISTORY (muze obsahovat API key z parametru)
|
||||
# ------------------------------------------------------------
|
||||
Write-Step "Clearing PowerShell history..."
|
||||
|
||||
$historyPath = (Get-PSReadlineOption).HistorySavePath
|
||||
if ($historyPath -and (Test-Path $historyPath)) {
|
||||
# Vymaz pouze radky obsahujici ApiKey / sk-ant
|
||||
$lines = Get-Content $historyPath | Where-Object { $_ -notmatch 'ApiKey|sk-ant-|ANTHROPIC' }
|
||||
$lines | Set-Content $historyPath
|
||||
Write-OK "Sensitive lines removed from PS history"
|
||||
} else {
|
||||
Write-Skip "PS history file not found"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# SUMMARY
|
||||
# ------------------------------------------------------------
|
||||
Write-Host "`n========================================" -ForegroundColor Green
|
||||
Write-Host " Cleanup complete!" -ForegroundColor Green
|
||||
if ($Full) {
|
||||
Write-Host " Removed: API key, repo, ~/.claude, Node.js, Claude Code" -ForegroundColor White
|
||||
} else {
|
||||
Write-Host " Removed: API key, repo, ~/.claude config" -ForegroundColor White
|
||||
Write-Host " Node.js and Claude Code kept (use -Full to remove)" -ForegroundColor DarkGray
|
||||
}
|
||||
Write-Host "========================================`n" -ForegroundColor Green
|
||||
273
SPEC.md
Normal file
273
SPEC.md
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
# MSP Windows Deployment - Specification (SPEC.md)
|
||||
|
||||
> Version: 0.2 (draft)
|
||||
> Author: X9.cz
|
||||
> Purpose: Automated preparation of new Windows 10/11 computers for clients
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Script replaces ~3 hours of manual computer setup. Run once as Administrator on
|
||||
already-installed Windows, performs everything automatically, saves result to Default
|
||||
Profile so settings apply to every subsequent user.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Windows 10 or Windows 11 (x64)
|
||||
- Run as Administrator
|
||||
- Internet connection (for winget installs)
|
||||
- Computer received either as clean OEM install or with manufacturer pre-installed Windows
|
||||
|
||||
---
|
||||
|
||||
## What the script does NOT do
|
||||
|
||||
- Does not install Windows (not an autounattend.xml for clean install)
|
||||
- Does not create images
|
||||
- Does not manage the computer ongoing (one-time deployment)
|
||||
|
||||
---
|
||||
|
||||
## Script structure
|
||||
|
||||
Script is divided into steps. Each step logs its result. Steps can be skipped with switches.
|
||||
|
||||
---
|
||||
|
||||
## STEP 1 - Bloatware removal
|
||||
|
||||
### 1a - AppX packages (UWP apps)
|
||||
|
||||
Removed for all users (-AllUsers) and from provisioned packages (so they do not return for new users).
|
||||
|
||||
| Package | Description |
|
||||
|---|---|
|
||||
| Microsoft.Microsoft3DViewer | 3D Viewer |
|
||||
| Microsoft.BingSearch | Bing Search |
|
||||
| Microsoft.WindowsCamera | Camera |
|
||||
| Clipchamp.Clipchamp | Clipchamp video editor |
|
||||
| Microsoft.WindowsAlarms | Clock / Alarm |
|
||||
| Microsoft.Copilot | Copilot AI |
|
||||
| Microsoft.549981C3F5F10 | Cortana |
|
||||
| Microsoft.Windows.DevHome | Dev Home |
|
||||
| MicrosoftCorporationII.MicrosoftFamily | Family Safety |
|
||||
| Microsoft.WindowsFeedbackHub | Feedback Hub |
|
||||
| Microsoft.Edge.GameAssist | Game Assist |
|
||||
| Microsoft.GetHelp | Help |
|
||||
| Microsoft.Getstarted | Tips / Get Started |
|
||||
| microsoft.windowscommunicationsapps | Mail and Calendar |
|
||||
| Microsoft.WindowsMaps | Maps |
|
||||
| Microsoft.MixedReality.Portal | Mixed Reality |
|
||||
| Microsoft.BingNews | News |
|
||||
| Microsoft.MicrosoftOfficeHub | Office Hub |
|
||||
| Microsoft.Office.OneNote | OneNote |
|
||||
| Microsoft.OutlookForWindows | Outlook (new) |
|
||||
| Microsoft.Paint | Paint (new UWP) |
|
||||
| Microsoft.MSPaint | Paint (legacy) |
|
||||
| Microsoft.People | People |
|
||||
| Microsoft.Windows.Photos | Photos |
|
||||
| Microsoft.PowerAutomateDesktop | Power Automate |
|
||||
| MicrosoftCorporationII.QuickAssist | Quick Assist |
|
||||
| Microsoft.SkypeApp | Skype |
|
||||
| Microsoft.ScreenSketch | Snipping Tool |
|
||||
| Microsoft.MicrosoftSolitaireCollection | Solitaire |
|
||||
| Microsoft.MicrosoftStickyNotes | Sticky Notes |
|
||||
| MicrosoftTeams / MSTeams | Teams (personal) |
|
||||
| Microsoft.Todos | To Do |
|
||||
| Microsoft.WindowsSoundRecorder | Voice Recorder |
|
||||
| Microsoft.Wallet | Wallet |
|
||||
| Microsoft.BingWeather | Weather |
|
||||
| Microsoft.WindowsTerminal | Windows Terminal |
|
||||
| Microsoft.Xbox.TCUI | Xbox UI |
|
||||
| Microsoft.XboxApp | Xbox |
|
||||
| Microsoft.XboxGameOverlay | Xbox Game Overlay |
|
||||
| Microsoft.XboxGamingOverlay | Xbox Gaming Overlay |
|
||||
| Microsoft.XboxIdentityProvider | Xbox Identity |
|
||||
| Microsoft.XboxSpeechToTextOverlay | Xbox Speech |
|
||||
| Microsoft.GamingApp | Gaming App |
|
||||
| Microsoft.YourPhone | Phone Link |
|
||||
| Microsoft.ZuneMusic | Music |
|
||||
| Microsoft.ZuneVideo | Movies and TV |
|
||||
|
||||
NOTE: Microsoft.WindowsCalculator is intentionally KEPT.
|
||||
|
||||
### 1b - Windows Capabilities
|
||||
|
||||
| Capability | Description |
|
||||
|---|---|
|
||||
| Print.Fax.Scan | Fax and Scan |
|
||||
| Language.Handwriting | Handwriting |
|
||||
| Browser.InternetExplorer | Internet Explorer |
|
||||
| MathRecognizer | Math Input |
|
||||
| OneCoreUAP.OneSync | OneSync |
|
||||
| OpenSSH.Client | OpenSSH client |
|
||||
| Microsoft.Windows.MSPaint | Paint (Win32) |
|
||||
| Microsoft.Windows.PowerShell.ISE | PowerShell ISE |
|
||||
| App.Support.QuickAssist | Quick Assist |
|
||||
| Microsoft.Windows.SnippingTool | Snipping Tool |
|
||||
| App.StepsRecorder | Steps Recorder |
|
||||
| Hello.Face.* | Windows Hello face |
|
||||
| Media.WindowsMediaPlayer | Windows Media Player |
|
||||
| Microsoft.Windows.WordPad | WordPad |
|
||||
|
||||
### 1c - Windows Optional Features
|
||||
|
||||
| Feature | Description |
|
||||
|---|---|
|
||||
| MediaPlayback | Media playback |
|
||||
| MicrosoftWindowsPowerShellV2Root | PowerShell 2.0 |
|
||||
| Microsoft-RemoteDesktopConnection | RDP client |
|
||||
| Recall | Windows Recall (AI) |
|
||||
| Microsoft-SnippingTool | Snipping Tool (feature) |
|
||||
|
||||
---
|
||||
|
||||
## STEP 2 - Software installation (winget)
|
||||
|
||||
| Software | Winget ID | Notes |
|
||||
|---|---|---|
|
||||
| 7-Zip | `7zip.7zip` | OK |
|
||||
| Adobe Acrobat Reader | `Adobe.Acrobat.Reader.64-bit` | OK, see note |
|
||||
| OpenVPN Connect | `OpenVPNTechnologies.OpenVPNConnect` | OK |
|
||||
| ... | ... | TODO: complete list |
|
||||
|
||||
> Adobe Acrobat Reader: After install, script sets .pdf -> AcroRd32 as default.
|
||||
> Scheduled task PDF-DefaultApp restores this association on every logon as a guard
|
||||
> against Edge overwriting it.
|
||||
|
||||
> BackInfo: NOT used. Replaced by custom PowerShell scheduled task DesktopInfo.
|
||||
> See STEP 7.
|
||||
|
||||
---
|
||||
|
||||
## STEP 3 - System settings (HKLM - applies to whole system)
|
||||
|
||||
| Setting | Value | Notes |
|
||||
|---|---|---|
|
||||
| Disable NRO (bypass network check) | HKLM\...\OOBE\BypassNRO = 1 | |
|
||||
| Disable auto-install of Teams | ConfigureChatAutoInstall = 0 | |
|
||||
| Disable Cloud Optimized Content | DisableCloudOptimizedContent = 1 | |
|
||||
| Disable Widgets (News and Interests) | HKLM\...\Dsh\AllowNewsAndInterests = 0 | |
|
||||
| Edge - hide First Run Experience | HKLM\Policies\Edge\HideFirstRunExperience = 1 | |
|
||||
| Passwords - no expiration | net accounts /maxpwage:UNLIMITED | |
|
||||
| Time zone | Central Europe Standard Time | |
|
||||
| OneDrive - remove | Delete OneDriveSetup.exe + Start Menu lnk | |
|
||||
| Outlook (new) - disable auto-install | Delete UScheduler registry key | |
|
||||
| Disable GameDVR | AppCaptureEnabled = 0 | |
|
||||
|
||||
---
|
||||
|
||||
## STEP 4 - Default Profile (NTUSER.DAT)
|
||||
|
||||
Settings applied to C:\Users\Default\NTUSER.DAT - inherited by every new user on first logon.
|
||||
|
||||
Method: script loads Default hive (reg load), makes changes, unloads (reg unload).
|
||||
|
||||
| Setting | Key / Value | Description |
|
||||
|---|---|---|
|
||||
| Taskbar - align left | TaskbarAl = 0 | Win11 default is center |
|
||||
| Taskbar - hide Search box | SearchboxTaskbarMode = 0 | |
|
||||
| Taskbar - hide Copilot button | ShowCopilotButton = 0 | |
|
||||
| Taskbar - hide Task View button | ShowTaskViewButton = 0 | |
|
||||
| Taskbar - hide Widgets | TaskbarDa = 0 | |
|
||||
| Taskbar - hide Chat/Teams button | TaskbarMn = 0 | |
|
||||
| Taskbar - show all tray icons | Scheduled task ShowAllTrayIcons | Runs on every logon |
|
||||
| Taskbar - empty pinlist | TaskbarLayoutModification.xml | Removes default pinned apps |
|
||||
| Explorer - show file extensions | HideFileExt = 0 | |
|
||||
| Explorer - open to This PC | LaunchTo = 1 | Instead of Quick Access |
|
||||
| Start menu - empty pins | ConfigureStartPins = {"pinnedList":[]} | Win11 |
|
||||
| Start menu - disable Bing results | DisableSearchBoxSuggestions = 1 | |
|
||||
| Copilot - disable | TurnOffWindowsCopilot = 1 | |
|
||||
| GameDVR - disable | AppCaptureEnabled = 0 | |
|
||||
| OneDrive - remove RunOnce key | Delete OneDriveSetup from Run | |
|
||||
| Num Lock on startup - enable | InitialKeyboardIndicators = 2 | |
|
||||
| Accent color on title bars | ColorPrevalence = 1 | |
|
||||
|
||||
---
|
||||
|
||||
## STEP 5 - Personalization (colors, wallpaper)
|
||||
|
||||
Applied to both Default Profile and currently logged-in user.
|
||||
|
||||
| Setting | Value |
|
||||
|---|---|
|
||||
| System theme (taskbar, Start) | Dark |
|
||||
| App theme | Light |
|
||||
| Accent color | #223B47 (dark blue-gray) |
|
||||
| Accent color on Start and taskbar | Yes |
|
||||
| Accent color on title bars | Yes |
|
||||
| Transparency | Disabled |
|
||||
| Wallpaper | Solid color #223B47 (no image) |
|
||||
|
||||
NOTE: DesktopInfo scheduled task (STEP 7) will overwrite the wallpaper with a system
|
||||
info BMP. The solid color here is only a fallback if DesktopInfo is not running.
|
||||
|
||||
---
|
||||
|
||||
## STEP 6 - Scheduled Tasks
|
||||
|
||||
| Task | Trigger | Purpose |
|
||||
|---|---|---|
|
||||
| ShowAllTrayIcons | Every logon, every 1 min | Show all icons in system tray (Win11) |
|
||||
| UnlockStartLayout | Once after layout is applied | Unlock Start menu layout |
|
||||
| PDF-DefaultApp | Every logon | Restore .pdf -> Adobe Reader if Edge overwrote it |
|
||||
| DesktopInfo | Every logon | Render system info onto desktop wallpaper |
|
||||
|
||||
---
|
||||
|
||||
## STEP 7 - DesktopInfo (BackInfo replacement)
|
||||
|
||||
Custom PowerShell scheduled task. No external dependencies.
|
||||
|
||||
**What it displays:**
|
||||
- Computer name (hostname)
|
||||
- IP address
|
||||
- Windows version and build
|
||||
- Logged-in username
|
||||
- Deployment date
|
||||
|
||||
**How it works:**
|
||||
1. PS script collects system info
|
||||
2. Renders text onto bitmap via WPF / System.Drawing
|
||||
3. Saves BMP to C:\Windows\Setup\Scripts\desktopinfo.bmp
|
||||
4. Sets BMP as desktop wallpaper via SystemParametersInfo
|
||||
5. Runs on every user logon via Scheduled Task
|
||||
|
||||
**Why not BackInfo:**
|
||||
- BackInfo has Win11 rendering issues requiring registry hacks
|
||||
- External EXE dependency is hard to distribute
|
||||
- Custom PS solution = full control, no dependencies, works on Win10 and Win11
|
||||
|
||||
---
|
||||
|
||||
## STEP 8 - Logging and output
|
||||
|
||||
- Every step writes to C:\Windows\Setup\Scripts\Deploy.log
|
||||
- Format: [HH:mm:ss] Step description - OK / ERROR: ...
|
||||
- At end: summary report (how many steps OK, how many failed)
|
||||
- Log stays on disk for diagnostics
|
||||
|
||||
---
|
||||
|
||||
## Script switches
|
||||
|
||||
| Switch | Behavior |
|
||||
|---|---|
|
||||
| `-SkipBloatware` | Skip step 1 |
|
||||
| `-SkipSoftware` | Skip step 2 |
|
||||
| `-SkipDefaultProfile` | Skip step 4 |
|
||||
| `-DryRun` | Run through steps without changes, log only |
|
||||
|
||||
---
|
||||
|
||||
## Open questions
|
||||
|
||||
| # | Question | Status |
|
||||
|---|---|---|
|
||||
| 1 | BackInfo replacement | DONE - custom PS scheduled task DesktopInfo |
|
||||
| 2 | Complete SW list for winget | TODO |
|
||||
| 3 | Per-client variability via config.json | FUTURE |
|
||||
| 4 | Admin account adminx9 - script or manual? | OPEN |
|
||||
140
Setup-ClaudeCode.ps1
Normal file
140
Setup-ClaudeCode.ps1
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
#Requires -Version 5.1
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Claude Code - rychla instalace a nastaveni prostredi
|
||||
.USAGE
|
||||
# Windows PS:
|
||||
.\Setup-ClaudeCode.ps1 -ApiKey "sk-ant-..." -RepoUrl "https://github.com/org/repo"
|
||||
|
||||
# S volitelnym cilove adresarem:
|
||||
.\Setup-ClaudeCode.ps1 -ApiKey "sk-ant-..." -RepoUrl "https://github.com/org/repo" -WorkDir "C:\Projects"
|
||||
#>
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string] $ApiKey,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[string] $RepoUrl,
|
||||
|
||||
[string] $WorkDir = "$HOME\Projects"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
function Write-Step { param([string]$Msg) Write-Host "`n[SETUP] $Msg" -ForegroundColor Cyan }
|
||||
function Write-OK { param([string]$Msg) Write-Host " OK: $Msg" -ForegroundColor Green }
|
||||
function Write-Fail { param([string]$Msg) Write-Host " ERR: $Msg" -ForegroundColor Red; exit 1 }
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# 1. NODE.JS
|
||||
# ------------------------------------------------------------
|
||||
Write-Step "Checking Node.js..."
|
||||
|
||||
$nodeOk = $false
|
||||
try {
|
||||
$nodeVer = node --version 2>$null
|
||||
if ($nodeVer -match 'v(\d+)' -and [int]$Matches[1] -ge 18) {
|
||||
Write-OK "Node.js $nodeVer already installed"
|
||||
$nodeOk = $true
|
||||
}
|
||||
} catch {}
|
||||
|
||||
if (-not $nodeOk) {
|
||||
Write-Step "Installing Node.js via winget..."
|
||||
try {
|
||||
winget install OpenJS.NodeJS.LTS --accept-package-agreements --accept-source-agreements --silent
|
||||
# Reload PATH
|
||||
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" +
|
||||
[System.Environment]::GetEnvironmentVariable("Path","User")
|
||||
Write-OK "Node.js installed"
|
||||
} catch {
|
||||
Write-Fail "Node.js install failed: $_. Install manually from https://nodejs.org"
|
||||
}
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# 2. CLAUDE CODE
|
||||
# ------------------------------------------------------------
|
||||
Write-Step "Checking Claude Code..."
|
||||
|
||||
$ccOk = $false
|
||||
try {
|
||||
$ccVer = claude --version 2>$null
|
||||
Write-OK "Claude Code $ccVer already installed"
|
||||
$ccOk = $true
|
||||
} catch {}
|
||||
|
||||
if (-not $ccOk) {
|
||||
Write-Step "Installing Claude Code..."
|
||||
try {
|
||||
npm install -g @anthropic-ai/claude-code
|
||||
Write-OK "Claude Code installed"
|
||||
} catch {
|
||||
Write-Fail "Claude Code install failed: $_"
|
||||
}
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# 3. API KEY
|
||||
# ------------------------------------------------------------
|
||||
Write-Step "Setting ANTHROPIC_API_KEY..."
|
||||
|
||||
[System.Environment]::SetEnvironmentVariable("ANTHROPIC_API_KEY", $ApiKey, "User")
|
||||
$env:ANTHROPIC_API_KEY = $ApiKey
|
||||
Write-OK "API key set (User environment variable)"
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# 4. GIT
|
||||
# ------------------------------------------------------------
|
||||
Write-Step "Checking Git..."
|
||||
|
||||
try {
|
||||
git --version | Out-Null
|
||||
Write-OK "Git available"
|
||||
} catch {
|
||||
Write-Step "Installing Git via winget..."
|
||||
try {
|
||||
winget install Git.Git --accept-package-agreements --accept-source-agreements --silent
|
||||
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" +
|
||||
[System.Environment]::GetEnvironmentVariable("Path","User")
|
||||
Write-OK "Git installed"
|
||||
} catch {
|
||||
Write-Fail "Git install failed: $_. Install manually from https://git-scm.com"
|
||||
}
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# 5. CLONE REPO
|
||||
# ------------------------------------------------------------
|
||||
Write-Step "Cloning repository..."
|
||||
|
||||
New-Item -ItemType Directory -Path $WorkDir -Force | Out-Null
|
||||
|
||||
$repoName = ($RepoUrl -split '/')[-1] -replace '\.git$', ''
|
||||
$targetPath = Join-Path $WorkDir $repoName
|
||||
|
||||
if (Test-Path $targetPath) {
|
||||
Write-OK "Repo already exists at $targetPath — pulling latest..."
|
||||
Push-Location $targetPath
|
||||
git pull
|
||||
Pop-Location
|
||||
} else {
|
||||
git clone $RepoUrl $targetPath
|
||||
Write-OK "Cloned to $targetPath"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# 6. LAUNCH
|
||||
# ------------------------------------------------------------
|
||||
Write-Host "`n========================================" -ForegroundColor Green
|
||||
Write-Host " Setup complete!" -ForegroundColor Green
|
||||
Write-Host " Repo: $targetPath" -ForegroundColor White
|
||||
Write-Host " Run: cd '$targetPath' && claude" -ForegroundColor White
|
||||
Write-Host "========================================`n" -ForegroundColor Green
|
||||
|
||||
$launch = Read-Host "Launch Claude Code now? (Y/n)"
|
||||
if ($launch -ne 'n') {
|
||||
Set-Location $targetPath
|
||||
claude
|
||||
}
|
||||
157
setup.ps1
Normal file
157
setup.ps1
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
# setup.ps1 - Claude Code bootstrap for Windows
|
||||
# Usage:
|
||||
# irm https://gist.githubusercontent.com/YOUR_GIST_URL/raw/setup.ps1 | iex
|
||||
#
|
||||
# Or with parameters (paste as one line):
|
||||
# $env:CC_API_KEY="sk-ant-..."; $env:CC_REPO="https://github.com/org/repo"; irm https://gist.../raw/setup.ps1 | iex
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
function Write-Step { param([string]$Msg) Write-Host "[SETUP] $Msg" -ForegroundColor Cyan }
|
||||
function Write-OK { param([string]$Msg) Write-Host " OK: $Msg" -ForegroundColor Green }
|
||||
function Write-Fail { param([string]$Msg) Write-Host " ERR: $Msg" -ForegroundColor Red; exit 1 }
|
||||
|
||||
Write-Host ""
|
||||
Write-Host " Claude Code Bootstrap - X9.cz" -ForegroundColor Cyan
|
||||
Write-Host " ==============================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# API KEY
|
||||
# ------------------------------------------------------------
|
||||
$apiKey = $env:CC_API_KEY
|
||||
if (-not $apiKey) {
|
||||
$apiKey = Read-Host "Enter Anthropic API key (sk-ant-...)"
|
||||
}
|
||||
if (-not $apiKey -or -not $apiKey.StartsWith("sk-")) {
|
||||
Write-Fail "Invalid API key"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# REPO URL
|
||||
# ------------------------------------------------------------
|
||||
$repoUrl = $env:CC_REPO
|
||||
if (-not $repoUrl) {
|
||||
$repoUrl = Read-Host "Enter repo URL (https://github.com/org/repo)"
|
||||
}
|
||||
if (-not $repoUrl) {
|
||||
Write-Fail "No repo URL provided"
|
||||
}
|
||||
|
||||
$workDir = if ($env:CC_WORKDIR) { $env:CC_WORKDIR } else { "$HOME\Projects" }
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# NODE.JS
|
||||
# ------------------------------------------------------------
|
||||
Write-Step "Checking Node.js..."
|
||||
|
||||
$nodeOk = $false
|
||||
try {
|
||||
$nodeVer = & node --version 2>$null
|
||||
if ($nodeVer -match 'v(\d+)' -and [int]$Matches[1] -ge 18) {
|
||||
Write-OK "Node.js $nodeVer"
|
||||
$nodeOk = $true
|
||||
}
|
||||
} catch {}
|
||||
|
||||
if (-not $nodeOk) {
|
||||
Write-Step "Installing Node.js via winget..."
|
||||
try {
|
||||
winget install OpenJS.NodeJS.LTS --accept-package-agreements --accept-source-agreements --silent
|
||||
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" +
|
||||
[System.Environment]::GetEnvironmentVariable("Path","User")
|
||||
Write-OK "Node.js installed"
|
||||
} catch {
|
||||
Write-Fail "Node.js install failed. Install manually: https://nodejs.org"
|
||||
}
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# GIT
|
||||
# ------------------------------------------------------------
|
||||
Write-Step "Checking Git..."
|
||||
|
||||
$gitOk = $false
|
||||
try { git --version | Out-Null; $gitOk = $true; Write-OK "Git available" } catch {}
|
||||
|
||||
if (-not $gitOk) {
|
||||
Write-Step "Installing Git via winget..."
|
||||
try {
|
||||
winget install Git.Git --accept-package-agreements --accept-source-agreements --silent
|
||||
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" +
|
||||
[System.Environment]::GetEnvironmentVariable("Path","User")
|
||||
Write-OK "Git installed"
|
||||
} catch {
|
||||
Write-Fail "Git install failed. Install manually: https://git-scm.com"
|
||||
}
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# CLAUDE CODE
|
||||
# ------------------------------------------------------------
|
||||
Write-Step "Checking Claude Code..."
|
||||
|
||||
$ccOk = $false
|
||||
try { $ccVer = claude --version 2>$null; Write-OK "Claude Code $ccVer"; $ccOk = $true } catch {}
|
||||
|
||||
if (-not $ccOk) {
|
||||
Write-Step "Installing Claude Code..."
|
||||
try {
|
||||
npm install -g @anthropic-ai/claude-code
|
||||
Write-OK "Claude Code installed"
|
||||
} catch {
|
||||
Write-Fail "Claude Code install failed"
|
||||
}
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# API KEY - ulozit
|
||||
# ------------------------------------------------------------
|
||||
Write-Step "Saving API key..."
|
||||
[System.Environment]::SetEnvironmentVariable("ANTHROPIC_API_KEY", $apiKey, "User")
|
||||
$env:ANTHROPIC_API_KEY = $apiKey
|
||||
# Vymazat z env aby nezustal v historii procesu
|
||||
Remove-Item Env:\CC_API_KEY -ErrorAction SilentlyContinue
|
||||
Write-OK "API key saved"
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# CLONE / PULL REPO
|
||||
# ------------------------------------------------------------
|
||||
Write-Step "Setting up repository..."
|
||||
New-Item -ItemType Directory -Path $workDir -Force | Out-Null
|
||||
|
||||
$repoName = ($repoUrl -split '/')[-1] -replace '\.git$', ''
|
||||
$targetPath = Join-Path $workDir $repoName
|
||||
|
||||
if (Test-Path (Join-Path $targetPath ".git")) {
|
||||
Write-Step "Repo exists, pulling latest..."
|
||||
Push-Location $targetPath
|
||||
git pull
|
||||
Pop-Location
|
||||
} else {
|
||||
git clone $repoUrl $targetPath
|
||||
Write-OK "Cloned to $targetPath"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# CLEAN PS HISTORY - odstranit radky s API key
|
||||
# ------------------------------------------------------------
|
||||
try {
|
||||
$histPath = (Get-PSReadlineOption).HistorySavePath
|
||||
if ($histPath -and (Test-Path $histPath)) {
|
||||
$clean = Get-Content $histPath | Where-Object { $_ -notmatch 'sk-ant-|CC_API_KEY|ANTHROPIC' }
|
||||
$clean | Set-Content $histPath
|
||||
}
|
||||
} catch {}
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# LAUNCH
|
||||
# ------------------------------------------------------------
|
||||
Write-Host ""
|
||||
Write-Host " ==============================" -ForegroundColor Green
|
||||
Write-Host " Ready! Repo: $targetPath" -ForegroundColor Green
|
||||
Write-Host " ==============================" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
Set-Location $targetPath
|
||||
claude
|
||||
214
setup.sh
Executable file
214
setup.sh
Executable file
|
|
@ -0,0 +1,214 @@
|
|||
#!/usr/bin/env bash
|
||||
# setup.sh - Claude Code bootstrap for macOS / Linux
|
||||
# Usage:
|
||||
# curl -fsSL https://gist.githubusercontent.com/YOUR_GIST_URL/raw/setup.sh | bash
|
||||
#
|
||||
# Or with parameters:
|
||||
# CC_API_KEY="sk-ant-..." CC_REPO="https://github.com/org/repo" bash <(curl -fsSL https://gist.../raw/setup.sh)
|
||||
|
||||
set -e
|
||||
|
||||
CYAN='\033[0;36m'
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
GRAY='\033[0;90m'
|
||||
NC='\033[0m'
|
||||
|
||||
step() { echo -e "\n${CYAN}[SETUP] $1${NC}"; }
|
||||
ok() { echo -e " ${GREEN}OK: $1${NC}"; }
|
||||
fail() { echo -e " ${RED}ERR: $1${NC}"; exit 1; }
|
||||
skip() { echo -e " ${GRAY}SKIP: $1${NC}"; }
|
||||
|
||||
echo ""
|
||||
echo -e "${CYAN} Claude Code Bootstrap - X9.cz"
|
||||
echo -e " ==============================${NC}"
|
||||
echo ""
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# API KEY
|
||||
# ------------------------------------------------------------
|
||||
API_KEY="${CC_API_KEY:-}"
|
||||
if [ -z "$API_KEY" ]; then
|
||||
read -rsp "Enter Anthropic API key (sk-ant-...): " API_KEY
|
||||
echo ""
|
||||
fi
|
||||
if [[ ! "$API_KEY" == sk-* ]]; then
|
||||
fail "Invalid API key"
|
||||
fi
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# REPO URL
|
||||
# ------------------------------------------------------------
|
||||
REPO_URL="${CC_REPO:-}"
|
||||
if [ -z "$REPO_URL" ]; then
|
||||
read -rp "Enter repo URL (https://github.com/org/repo): " REPO_URL
|
||||
fi
|
||||
if [ -z "$REPO_URL" ]; then
|
||||
fail "No repo URL provided"
|
||||
fi
|
||||
|
||||
WORK_DIR="${CC_WORKDIR:-$HOME/Projects}"
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# DETECT OS
|
||||
# ------------------------------------------------------------
|
||||
OS="$(uname -s)"
|
||||
step "Detected OS: $OS"
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# NODE.JS
|
||||
# ------------------------------------------------------------
|
||||
step "Checking Node.js..."
|
||||
|
||||
node_ok=false
|
||||
if command -v node &>/dev/null; then
|
||||
NODE_VER=$(node --version | sed 's/v//' | cut -d. -f1)
|
||||
if [ "$NODE_VER" -ge 18 ]; then
|
||||
ok "Node.js $(node --version)"
|
||||
node_ok=true
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$node_ok" = false ]; then
|
||||
step "Installing Node.js..."
|
||||
case "$OS" in
|
||||
Darwin)
|
||||
if command -v brew &>/dev/null; then
|
||||
brew install node
|
||||
else
|
||||
step "Installing Homebrew first..."
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
brew install node
|
||||
fi
|
||||
;;
|
||||
Linux)
|
||||
# Node via NodeSource
|
||||
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
|
||||
if command -v apt-get &>/dev/null; then
|
||||
sudo apt-get install -y nodejs
|
||||
elif command -v dnf &>/dev/null; then
|
||||
sudo dnf install -y nodejs
|
||||
elif command -v yum &>/dev/null; then
|
||||
sudo yum install -y nodejs
|
||||
else
|
||||
fail "Cannot detect package manager. Install Node.js manually: https://nodejs.org"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
fail "Unsupported OS: $OS. Install Node.js manually: https://nodejs.org"
|
||||
;;
|
||||
esac
|
||||
ok "Node.js installed"
|
||||
fi
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# GIT
|
||||
# ------------------------------------------------------------
|
||||
step "Checking Git..."
|
||||
|
||||
if command -v git &>/dev/null; then
|
||||
ok "Git available"
|
||||
else
|
||||
step "Installing Git..."
|
||||
case "$OS" in
|
||||
Darwin) brew install git ;;
|
||||
Linux)
|
||||
if command -v apt-get &>/dev/null; then sudo apt-get install -y git
|
||||
elif command -v dnf &>/dev/null; then sudo dnf install -y git
|
||||
elif command -v yum &>/dev/null; then sudo yum install -y git
|
||||
else fail "Cannot install Git automatically"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
ok "Git installed"
|
||||
fi
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# CLAUDE CODE
|
||||
# ------------------------------------------------------------
|
||||
step "Checking Claude Code..."
|
||||
|
||||
if command -v claude &>/dev/null; then
|
||||
ok "Claude Code $(claude --version)"
|
||||
else
|
||||
step "Installing Claude Code..."
|
||||
npm install -g @anthropic-ai/claude-code
|
||||
ok "Claude Code installed"
|
||||
fi
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# API KEY - ulozit
|
||||
# ------------------------------------------------------------
|
||||
step "Saving API key..."
|
||||
|
||||
SHELL_RC=""
|
||||
case "$SHELL" in
|
||||
*/zsh) SHELL_RC="$HOME/.zshrc" ;;
|
||||
*/bash)
|
||||
if [ "$OS" = "Darwin" ]; then
|
||||
SHELL_RC="$HOME/.bash_profile"
|
||||
else
|
||||
SHELL_RC="$HOME/.bashrc"
|
||||
fi
|
||||
;;
|
||||
*) SHELL_RC="$HOME/.profile" ;;
|
||||
esac
|
||||
|
||||
# Odstrante stary zaznam pokud existuje
|
||||
if [ -f "$SHELL_RC" ]; then
|
||||
grep -v 'ANTHROPIC_API_KEY' "$SHELL_RC" > "${SHELL_RC}.tmp" && mv "${SHELL_RC}.tmp" "$SHELL_RC"
|
||||
fi
|
||||
|
||||
echo "export ANTHROPIC_API_KEY=\"$API_KEY\"" >> "$SHELL_RC"
|
||||
export ANTHROPIC_API_KEY="$API_KEY"
|
||||
unset CC_API_KEY
|
||||
ok "API key saved to $SHELL_RC"
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# CLONE / PULL REPO
|
||||
# ------------------------------------------------------------
|
||||
step "Setting up repository..."
|
||||
mkdir -p "$WORK_DIR"
|
||||
|
||||
REPO_NAME=$(basename "$REPO_URL" .git)
|
||||
TARGET_PATH="$WORK_DIR/$REPO_NAME"
|
||||
|
||||
if [ -d "$TARGET_PATH/.git" ]; then
|
||||
step "Repo exists, pulling latest..."
|
||||
git -C "$TARGET_PATH" pull
|
||||
else
|
||||
git clone "$REPO_URL" "$TARGET_PATH"
|
||||
ok "Cloned to $TARGET_PATH"
|
||||
fi
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# CLEAN SHELL HISTORY - odstranit radky s API key
|
||||
# ------------------------------------------------------------
|
||||
HIST_FILE="${HISTFILE:-$HOME/.bash_history}"
|
||||
if [ -f "$HIST_FILE" ]; then
|
||||
grep -v 'sk-ant-\|CC_API_KEY\|ANTHROPIC' "$HIST_FILE" > "${HIST_FILE}.tmp" && mv "${HIST_FILE}.tmp" "$HIST_FILE"
|
||||
fi
|
||||
# zsh history
|
||||
ZSH_HIST="$HOME/.zsh_history"
|
||||
if [ -f "$ZSH_HIST" ]; then
|
||||
grep -v 'sk-ant-\|CC_API_KEY\|ANTHROPIC' "$ZSH_HIST" > "${ZSH_HIST}.tmp" && mv "${ZSH_HIST}.tmp" "$ZSH_HIST"
|
||||
fi
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# LAUNCH
|
||||
# ------------------------------------------------------------
|
||||
echo ""
|
||||
echo -e "${GREEN} =============================="
|
||||
echo -e " Ready! Repo: $TARGET_PATH"
|
||||
echo -e " ==============================${NC}"
|
||||
echo ""
|
||||
echo -e " Run: ${CYAN}source $SHELL_RC && cd $TARGET_PATH && claude${NC}"
|
||||
echo ""
|
||||
|
||||
# Pokud je skript spusten primo (ne pres pipe), rovnou spustit
|
||||
if [ -t 0 ]; then
|
||||
cd "$TARGET_PATH"
|
||||
# shellcheck disable=SC1090
|
||||
source "$SHELL_RC"
|
||||
claude
|
||||
fi
|
||||
Loading…
Reference in a new issue