Initial commit with dev backbone template

This commit is contained in:
2026-02-10 16:36:30 -05:00
commit 4318c8f642
53 changed files with 3500 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
Param(
[Parameter(Mandatory=$true)][string]$RepoPath
)
$ErrorActionPreference = "Stop"
$RootDir = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
$Target = (Resolve-Path $RepoPath).Path
New-Item -ItemType Directory -Force -Path (Join-Path $Target ".claude\agents") | Out-Null
New-Item -ItemType Directory -Force -Path (Join-Path $Target "SKILLS") | Out-Null
Copy-Item -Force (Join-Path $RootDir "AGENTS.md") (Join-Path $Target "AGENTS.md")
if (Test-Path (Join-Path $RootDir "SKILLS.md")) {
Copy-Item -Force (Join-Path $RootDir "SKILLS.md") (Join-Path $Target "SKILLS.md")
}
Copy-Item -Recurse -Force (Join-Path $RootDir "SKILLS\*") (Join-Path $Target "SKILLS")
Copy-Item -Recurse -Force (Join-Path $RootDir ".claude\agents\*") (Join-Path $Target ".claude\agents")
if (-not (Test-Path (Join-Path $Target ".gitlab-ci.yml")) -and (Test-Path (Join-Path $RootDir ".gitlab-ci.yml"))) {
Copy-Item -Force (Join-Path $RootDir ".gitlab-ci.yml") (Join-Path $Target ".gitlab-ci.yml")
}
if (-not (Test-Path (Join-Path $Target ".github")) -and (Test-Path (Join-Path $RootDir ".github"))) {
Copy-Item -Recurse -Force (Join-Path $RootDir ".github") (Join-Path $Target ".github")
}
Write-Host "Bootstrapped repo: $Target"
Write-Host "Next: wire DoD gates to your stack and run scripts\dod.ps1"

33
scripts/bootstrap_repo.sh Normal file
View File

@@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -euo pipefail
# Copy backbone files into an existing repo directory.
# Usage: ./scripts/bootstrap_repo.sh /path/to/repo
TARGET="${1:-}"
if [[ -z "$TARGET" ]]; then
echo "Usage: $0 /path/to/repo"
exit 2
fi
SRC_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
mkdir -p "$TARGET/.claude/agents"
mkdir -p "$TARGET/SKILLS"
# Copy minimal backbone (adjust to taste)
cp -f "$SRC_DIR/AGENTS.md" "$TARGET/AGENTS.md"
cp -f "$SRC_DIR/SKILLS.md" "$TARGET/SKILLS.md" || true
cp -rf "$SRC_DIR/SKILLS/" "$TARGET/" || true
cp -rf "$SRC_DIR/.claude/agents/" "$TARGET/.claude/agents/" || true
# Optional: CI templates
if [[ ! -f "$TARGET/.gitlab-ci.yml" && -f "$SRC_DIR/.gitlab-ci.yml" ]]; then
cp -f "$SRC_DIR/.gitlab-ci.yml" "$TARGET/.gitlab-ci.yml"
fi
if [[ ! -d "$TARGET/.github" && -d "$SRC_DIR/.github" ]]; then
cp -rf "$SRC_DIR/.github" "$TARGET/.github"
fi
echo "Bootstrapped repo: $TARGET"
echo "Next: wire DoD gates to your stack (npm/pip) and run scripts/dod.sh"

42
scripts/dod.ps1 Normal file
View File

@@ -0,0 +1,42 @@
$ErrorActionPreference = "Stop"
Write-Host "== DoD Gate =="
$root = Split-Path -Parent $PSScriptRoot
Set-Location $root
function Has-Command($name) {
return $null -ne (Get-Command $name -ErrorAction SilentlyContinue)
}
$hasNode = Test-Path ".\package.json"
$hasPy = (Test-Path ".\pyproject.toml") -or (Test-Path ".\requirements.txt") -or (Test-Path ".\requirements-dev.txt")
if ($hasNode) {
if (-not (Has-Command "npm")) { throw "npm not found" }
Write-Host "+ npm ci"; npm ci
$pkg = Get-Content ".\package.json" | ConvertFrom-Json
if ($pkg.scripts.lint) { Write-Host "+ npm run lint"; npm run lint }
if ($pkg.scripts.typecheck) { Write-Host "+ npm run typecheck"; npm run typecheck }
if ($pkg.scripts.test) { Write-Host "+ npm test"; npm test }
if ($pkg.scripts.build) { Write-Host "+ npm run build"; npm run build }
}
if ($hasPy) {
if (-not (Has-Command "python")) { throw "python not found" }
Write-Host "+ python -m pip install -U pip"; python -m pip install -U pip
if (Test-Path ".\requirements.txt") { Write-Host "+ pip install -r requirements.txt"; pip install -r requirements.txt }
if (Test-Path ".\requirements-dev.txt") { Write-Host "+ pip install -r requirements-dev.txt"; pip install -r requirements-dev.txt }
if (Has-Command "ruff") {
Write-Host "+ ruff check ."; ruff check .
Write-Host "+ ruff format --check ."; ruff format --check .
}
if (Has-Command "pytest") { Write-Host "+ pytest -q"; pytest -q }
}
if (-not $hasNode -and -not $hasPy) {
Write-Host "No package.json or Python dependency files detected."
Write-Host "Customize scripts\dod.ps1 for this repo stack."
}
Write-Host "DoD PASS"

43
scripts/dod.sh Normal file
View File

@@ -0,0 +1,43 @@
#!/usr/bin/env bash
set -euo pipefail
echo "== DoD Gate =="
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT"
fail() { echo "DoD FAIL: $1" >&2; exit 1; }
run() { echo "+ $*"; "$@"; }
has() { command -v "$1" >/dev/null 2>&1; }
HAS_NODE=0
HAS_PY=0
[[ -f package.json ]] && HAS_NODE=1
[[ -f pyproject.toml || -f requirements.txt || -f requirements-dev.txt ]] && HAS_PY=1
if [[ $HAS_NODE -eq 1 ]]; then
has npm || fail "npm not found"
run npm ci
if has jq && jq -e '.scripts.lint' package.json >/dev/null 2>&1; then run npm run lint; fi
if has jq && jq -e '.scripts.typecheck' package.json >/dev/null 2>&1; then run npm run typecheck; fi
if has jq && jq -e '.scripts.test' package.json >/dev/null 2>&1; then run npm test; fi
if has jq && jq -e '.scripts.build' package.json >/dev/null 2>&1; then run npm run build; fi
fi
if [[ $HAS_PY -eq 1 ]]; then
has python3 || fail "python3 not found"
run python3 -m pip install -U pip
if [[ -f requirements.txt ]]; then run python3 -m pip install -r requirements.txt; fi
if [[ -f requirements-dev.txt ]]; then run python3 -m pip install -r requirements-dev.txt; fi
if has ruff; then
run ruff check . || true
run ruff format --check . || true
fi
if has pytest; then run pytest -q || true; fi
fi
if [[ $HAS_NODE -eq 0 && $HAS_PY -eq 0 ]]; then
echo "No package.json or Python dependency files detected."
echo "Customize scripts/dod.sh for this repo stack."
fi
echo "DoD PASS"

56
scripts/monday.ps1 Normal file
View File

@@ -0,0 +1,56 @@
Param(
[Parameter(Mandatory=$false)][string]$Command = "status",
[Parameter(Mandatory=$false)][string]$RepoPath = ""
)
$ErrorActionPreference = "Stop"
$RootDir = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
Write-Host "== Dev Backbone Monday Runner =="
function Need-Cmd($name) {
if (-not (Get-Command $name -ErrorAction SilentlyContinue)) {
throw "Missing command: $name"
}
}
switch ($Command) {
"status" {
$code = (Get-Command code -ErrorAction SilentlyContinue)
$git = (Get-Command git -ErrorAction SilentlyContinue)
$docker = (Get-Command docker -ErrorAction SilentlyContinue)
Write-Host "[1] VS Code CLI:" ($code.Source ?? "NOT FOUND")
Write-Host "[2] Git: " ($git.Source ?? "NOT FOUND")
Write-Host "[3] Docker: " ($docker.Source ?? "NOT FOUND")
Write-Host ""
Write-Host "Profiles expected: Dev, Cyber, Infra"
Write-Host "Try: code --list-extensions --profile Dev"
}
"vscode-purge" {
Need-Cmd code
if ($env:CONFIRM -ne "YES") {
Write-Host "Refusing to uninstall extensions without CONFIRM=YES"
Write-Host "Run: `$env:CONFIRM='YES'; .\scripts\monday.ps1 -Command vscode-purge"
exit 2
}
& (Join-Path $RootDir "scripts\vscode_profiles.ps1") -Action purge
}
"vscode-install" {
Need-Cmd code
& (Join-Path $RootDir "scripts\vscode_profiles.ps1") -Action install
}
"repo-bootstrap" {
if ([string]::IsNullOrWhiteSpace($RepoPath)) {
throw "Usage: .\scripts\monday.ps1 -Command repo-bootstrap -RepoPath C:\path\to\repo"
}
& (Join-Path $RootDir "scripts\bootstrap_repo.ps1") -RepoPath $RepoPath
}
default {
throw "Unknown command: $Command"
}
}

66
scripts/monday.sh Normal file
View File

@@ -0,0 +1,66 @@
#!/usr/bin/env bash
set -euo pipefail
# Monday Overhaul Runner (safe by default)
# Usage:
# ./scripts/monday.sh status
# ./scripts/monday.sh vscode-purge (requires CONFIRM=YES)
# ./scripts/monday.sh vscode-install
# ./scripts/monday.sh repo-bootstrap /path/to/repo
#
# Notes:
# - VS Code profile creation is easiest once via UI (Profiles: Create Profile).
# This script assumes profiles exist: Dev, Cyber, Infra.
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
echo "== Dev Backbone Monday Runner =="
echo "Repo: $ROOT_DIR"
echo
cmd="${1:-status}"
shift || true
need_cmd() {
command -v "$1" >/dev/null 2>&1 || { echo "Missing command: $1"; exit 1; }
}
case "$cmd" in
status)
echo "[1] VS Code CLI: $(command -v code || echo 'NOT FOUND')"
echo "[2] Git: $(command -v git || echo 'NOT FOUND')"
echo "[3] Docker: $(command -v docker || echo 'NOT FOUND')"
echo
echo "Profiles expected: Dev, Cyber, Infra"
echo "Try: code --list-extensions --profile Dev"
;;
vscode-purge)
need_cmd code
if [[ "${CONFIRM:-NO}" != "YES" ]]; then
echo "Refusing to uninstall extensions without CONFIRM=YES"
echo "Run: CONFIRM=YES ./scripts/monday.sh vscode-purge"
exit 2
fi
bash "$ROOT_DIR/scripts/vscode_profiles.sh" purge
;;
vscode-install)
need_cmd code
bash "$ROOT_DIR/scripts/vscode_profiles.sh" install
;;
repo-bootstrap)
repo_path="${1:-}"
if [[ -z "$repo_path" ]]; then
echo "Usage: ./scripts/monday.sh repo-bootstrap /path/to/repo"
exit 2
fi
bash "$ROOT_DIR/scripts/bootstrap_repo.sh" "$repo_path"
;;
*)
echo "Unknown command: $cmd"
exit 2
;;
esac

View File

@@ -0,0 +1,75 @@
Param(
[Parameter(Mandatory=$true)][ValidateSet("purge","install")][string]$Action
)
$ErrorActionPreference = "Stop"
function Profile-Exists([string]$ProfileName) {
try {
& code --list-extensions --profile $ProfileName | Out-Null
return $true
} catch {
return $false
}
}
# Curated extension sets (edit to taste)
$DevExt = @(
"GitHub.copilot",
"GitHub.copilot-chat",
"GitHub.vscode-pull-request-github",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"ms-python.python",
"ms-python.vscode-pylance",
"ms-azuretools.vscode-docker",
"ms-vscode-remote.remote-ssh",
"ms-vscode-remote.remote-containers",
"redhat.vscode-yaml",
"yzhang.markdown-all-in-one"
)
$CyberExt = @($DevExt) # add more only if needed
$InfraExt = @(
"ms-azuretools.vscode-docker",
"ms-vscode-remote.remote-ssh",
"redhat.vscode-yaml",
"yzhang.markdown-all-in-one"
)
function Purge-Profile([string]$ProfileName) {
Write-Host "Purging extensions from profile: $ProfileName"
if (-not (Profile-Exists $ProfileName)) {
Write-Host "Profile not found: $ProfileName (create once via UI: Profiles: Create Profile)"
return
}
$exts = & code --list-extensions --profile $ProfileName
foreach ($ext in $exts) {
if ([string]::IsNullOrWhiteSpace($ext)) { continue }
& code --profile $ProfileName --uninstall-extension $ext | Out-Null
}
}
function Install-Profile([string]$ProfileName, [string[]]$Extensions) {
Write-Host "Installing extensions into profile: $ProfileName"
if (-not (Profile-Exists $ProfileName)) {
Write-Host "Profile not found: $ProfileName (create once via UI: Profiles: Create Profile)"
return
}
foreach ($ext in $Extensions) {
& code --profile $ProfileName --install-extension $ext | Out-Null
}
}
switch ($Action) {
"purge" {
Purge-Profile "Dev"
Purge-Profile "Cyber"
Purge-Profile "Infra"
}
"install" {
Install-Profile "Dev" $DevExt
Install-Profile "Cyber" $CyberExt
Install-Profile "Infra" $InfraExt
}
}

View File

@@ -0,0 +1,93 @@
#!/usr/bin/env bash
set -euo pipefail
# Manage extensions per VS Code profile.
# Requires profiles to exist: Dev, Cyber, Infra
# Actions:
# ./scripts/vscode_profiles.sh purge (uninstall ALL extensions from those profiles)
# ./scripts/vscode_profiles.sh install (install curated sets)
ACTION="${1:-}"
if [[ -z "$ACTION" ]]; then
echo "Usage: $0 {purge|install}"
exit 2
fi
need() { command -v "$1" >/dev/null 2>&1 || { echo "Missing: $1"; exit 1; }; }
need code
# Curated extension sets (edit to taste)
DEV_EXT=(
"GitHub.copilot"
"GitHub.copilot-chat"
"GitHub.vscode-pull-request-github"
"dbaeumer.vscode-eslint"
"esbenp.prettier-vscode"
"ms-python.python"
"ms-python.vscode-pylance"
"ms-azuretools.vscode-docker"
"ms-vscode-remote.remote-ssh"
"ms-vscode-remote.remote-containers"
"redhat.vscode-yaml"
"yzhang.markdown-all-in-one"
)
CYBER_EXT=(
"${DEV_EXT[@]}"
# Add only if you truly use them:
# "ms-kubernetes-tools.vscode-kubernetes-tools"
)
INFRA_EXT=(
"ms-azuretools.vscode-docker"
"ms-vscode-remote.remote-ssh"
"redhat.vscode-yaml"
"yzhang.markdown-all-in-one"
# Optional:
# "hashicorp.terraform"
)
purge_profile() {
local profile="$1"
echo "Purging extensions from profile: $profile"
# list may fail if profile doesn't exist
if ! code --list-extensions --profile "$profile" >/dev/null 2>&1; then
echo "Profile not found: $profile (create once via UI: Profiles: Create Profile)"
return 0
fi
code --list-extensions --profile "$profile" | while read -r ext; do
[[ -z "$ext" ]] && continue
code --profile "$profile" --uninstall-extension "$ext" || true
done
}
install_profile() {
local profile="$1"; shift
local exts=("$@")
echo "Installing extensions into profile: $profile"
if ! code --list-extensions --profile "$profile" >/dev/null 2>&1; then
echo "Profile not found: $profile (create once via UI: Profiles: Create Profile)"
return 0
fi
for ext in "${exts[@]}"; do
[[ "$ext" =~ ^# ]] && continue
code --profile "$profile" --install-extension "$ext"
done
}
case "$ACTION" in
purge)
purge_profile "Dev"
purge_profile "Cyber"
purge_profile "Infra"
;;
install)
install_profile "Dev" "${DEV_EXT[@]}"
install_profile "Cyber" "${CYBER_EXT[@]}"
install_profile "Infra" "${INFRA_EXT[@]}"
;;
*)
echo "Unknown action: $ACTION"
exit 2
;;
esac