From 10a38d56103dbda921358d166e3b0127134f9185 Mon Sep 17 00:00:00 2001 From: Tomeriko96 Date: Thu, 13 Aug 2026 10:56:13 +0200 Subject: [PATCH 1/2] feat: align tools with upstream, subscription Claude auth, per-user git identity - Add az, azcopy, azd, kubectl, helm, flux, sops, glab, aws, entire - Switch Claude auth from Foundry API key to subscription (claude auth login) - Add onboard wizard: gh -> opencode -> claude + git identity + entire enable - Enforce per-user git identity via user.useConfigOnly (issue #7) - Add claude/opencode skip-permissions aliases and opencode permission allow - Remove tdl/tdlm/tsl tmux layouts and secrets.sh; fix gh/glab credential helpers - Fix AWS CLI install with sha256 verification; document unpinned latest - Update README and docs to drop tdl/Foundry references --- .devcontainer/Dockerfile | 120 +++++++++++++- .devcontainer/devcontainer.json | 16 -- .devcontainer/onboard.sh | 233 +++++++++++++++++----------- .devcontainer/post-create.sh | 75 ++++++--- .devcontainer/tmux-dev-layouts.sh | 92 ----------- README.md | 18 +-- bash/.bashrc | 6 - bash/.config/bash/aliases | 5 + bash/.config/bash/functions | 52 +------ bash/.config/claude/secrets.sh | 5 - bash/.config/opencode/opencode.json | 4 + docs/ai.md | 68 +++----- docs/index.md | 31 ++-- docs/navigatie.md | 47 ++---- starship/.config/starship.toml | 28 ++-- 15 files changed, 389 insertions(+), 411 deletions(-) delete mode 100644 .devcontainer/tmux-dev-layouts.sh delete mode 100644 bash/.config/claude/secrets.sh create mode 100644 bash/.config/opencode/opencode.json diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 27cc93e..c3bd7d7 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -12,6 +12,13 @@ ARG STARSHIP_VERSION="1.24.2" ARG UV_VERSION="0.11.1" ARG ZOXIDE_VERSION="0.9.9" ARG MICROMAMBA_VERSION="2.8.1-0" +ARG AZCOPY_VERSION="10.26.0" +ARG AZD_VERSION="1.9.5" +ARG GLAB_VERSION="1.58.0" +ARG SOPS_VERSION="3.10.2" +ARG FLUX_VERSION="2.4.0" +ARG KUBECTL_VERSION="1.31.14" +ARG HELM_VERSION="3.16.0" # ───────────────────────────────────────────────────────────────────────────── # Resolve build architecture once; all subsequent RUN steps source /etc/arch_vars. @@ -64,6 +71,16 @@ RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \ rm -rf /var/lib/apt/lists/* && \ rm /etc/apt/sources.list.d/github-cli.list +# Install Azure CLI (az) +RUN mkdir -p /etc/apt/keyrings && \ + curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o /etc/apt/keyrings/microsoft.gpg && \ + echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/microsoft.gpg] https://packages.microsoft.com/repos/azure-cli/ bookworm main" \ + > /etc/apt/sources.list.d/azure-cli.list && \ + apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends azure-cli && \ + rm -rf /var/lib/apt/lists/* && \ + rm /etc/apt/sources.list.d/azure-cli.list /etc/apt/keyrings/microsoft.gpg + # Install lazygit RUN set -eux; . /etc/arch_vars; \ curl -Lo /tmp/lazygit.tar.gz \ @@ -89,6 +106,14 @@ RUN git config --system core.pager delta && \ git config --system merge.conflictStyle diff3 && \ git config --system diff.colorMoved default +# Configure git credential helpers (gh for GitHub, glab for GitLab/Custom) +# The "!" form makes git run a shell command as the helper (gh/glab have +# no standalone git-credential-* binary). gitlab.com is the default host; a +# self-hosted instance needs an extra `credential..helper` entry. +RUN git config --system init.defaultBranch main && \ + git config --system credential.https://github.com.helper "!gh auth git-credential" && \ + git config --system credential.https://gitlab.com.helper "!glab auth git-credential" + # Install ripgrep # No arm64 .deb is published; arm64 falls back to the gnu tarball. RUN set -eux; . /etc/arch_vars; \ @@ -163,6 +188,90 @@ RUN set -eux; . /etc/arch_vars; \ chmod +x /usr/local/bin/micromamba; \ micromamba --version +# Install azcopy (Azure Storage CLI) +RUN set -eux; . /etc/arch_vars; \ + curl -Lo /tmp/azcopy.tar.gz \ + "https://github.com/Azure/azure-storage-azcopy/releases/download/v${AZCOPY_VERSION}/azcopy_linux_${ARCH_DEB}_${AZCOPY_VERSION}.tar.gz"; \ + tar -C /tmp -xzf /tmp/azcopy.tar.gz; \ + AZCOPY_BIN=$(find /tmp -maxdepth 3 -type f -name azcopy | head -n1); \ + test -n "$AZCOPY_BIN"; \ + mv "$AZCOPY_BIN" /usr/local/bin/azcopy; \ + chmod +x /usr/local/bin/azcopy; \ + rm -rf /tmp/azcopy.tar.gz /tmp/azcopy_linux_${ARCH_DEB}_*; \ + azcopy --version + +# Install Azure Developer CLI (azd) +RUN set -eux; . /etc/arch_vars; \ + curl -Lo /tmp/azd.deb \ + "https://github.com/Azure/azure-dev/releases/download/azure-dev-cli_${AZD_VERSION}/azd_${AZD_VERSION}_${ARCH_DEB}.deb"; \ + dpkg -i /tmp/azd.deb; \ + rm -f /tmp/azd.deb; \ + azd version + +# Install kubectl (pinned upstream binary; avoids kubernetes apt repo version drift) +RUN set -eux; . /etc/arch_vars; \ + curl -fLo /usr/local/bin/kubectl \ + "https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/${ARCH_DEB}/kubectl"; \ + chmod +x /usr/local/bin/kubectl; \ + kubectl version --client + +# Install Helm (pinned upstream binary) +RUN set -eux; . /etc/arch_vars; \ + curl -Lo /tmp/helm.tar.gz \ + "https://get.helm.sh/helm-v${HELM_VERSION}-linux-${ARCH_DEB}.tar.gz"; \ + tar -C /tmp -xzf /tmp/helm.tar.gz; \ + HELM_BIN=$(find /tmp -maxdepth 3 -type f -name helm | head -n1); \ + test -n "$HELM_BIN"; \ + mv "$HELM_BIN" /usr/local/bin/helm; \ + chmod +x /usr/local/bin/helm; \ + rm -rf /tmp/helm.tar.gz /tmp/linux-${ARCH_DEB}; \ + helm version + +# Install sops (secrets encryption) +RUN set -eux; . /etc/arch_vars; \ + curl -Lo /tmp/sops \ + "https://github.com/getsops/sops/releases/download/v${SOPS_VERSION}/sops-v${SOPS_VERSION}.linux.${ARCH_DEB}"; \ + chmod +x /tmp/sops; \ + mv /tmp/sops /usr/local/bin/sops; \ + sops --version + +# Install glab (GitLab CLI; uses GitLab generic package API) +RUN set -eux; . /etc/arch_vars; \ + curl -Lo /tmp/glab.tar.gz \ + "https://gitlab.com/api/v4/projects/gitlab-org%2Fcli/packages/generic/glab/${GLAB_VERSION}/glab_${GLAB_VERSION}_linux_${ARCH_DEB}.tar.gz"; \ + tar -C /tmp -xzf /tmp/glab.tar.gz; \ + GLAB_BIN=$(find /tmp -type f -path '*/bin/glab' | head -n1); \ + test -n "$GLAB_BIN"; \ + mv "$GLAB_BIN" /usr/local/bin/glab; \ + chmod +x /usr/local/bin/glab; \ + rm -rf /tmp/glab.tar.gz /tmp/bin /tmp/glab_*; \ + glab version + +# Install Flux CD (pinned upstream binary) +RUN set -eux; . /etc/arch_vars; \ + curl -Lo /tmp/flux.tar.gz \ + "https://github.com/fluxcd/flux2/releases/download/v${FLUX_VERSION}/flux_${FLUX_VERSION}_linux_${ARCH_DEB}.tar.gz"; \ + tar -C /tmp -xzf /tmp/flux.tar.gz flux; \ + mv /tmp/flux /usr/local/bin/flux; \ + chmod +x /usr/local/bin/flux; \ + rm -f /tmp/flux.tar.gz; \ + flux --version + +# Install AWS CLI v2. The official installer only ships "latest", so we cannot +# pin a version at build time; the released checksum verifies integrity of the +# download. Track the actual version via post-create's tool-versions.txt. +RUN set -eux; . /etc/arch_vars; \ + curl -Lo /tmp/awscliv2.zip \ + "https://awscli.amazonaws.com/awscli-exe-linux-${ARCH_TAR}.zip"; \ + curl -Lo /tmp/awscliv2.zip.sha256 \ + "https://awscli.amazonaws.com/awscli-exe-linux-${ARCH_TAR}.zip.sha256"; \ + printf '%s %s\n' "$(cut -d' ' -f1 /tmp/awscliv2.zip.sha256)" "awscliv2.zip" | \ + sha256sum -c -; \ + unzip -q /tmp/awscliv2.zip -d /tmp; \ + /tmp/aws/install --bin-dir /usr/local/bin --install-dir /usr/local/aws-cli; \ + rm -rf /tmp/awscliv2.zip /tmp/awscliv2.zip.sha256 /tmp/aws; \ + aws --version + # Create non-root dev user ARG USERNAME=dev ARG UID=1000 @@ -188,8 +297,6 @@ COPY --chown=${USERNAME}:${USERNAME} bash/.bashrc /home/${USERNAME}/.bashrc COPY --chown=${USERNAME}:${USERNAME} bash/.config/ /home/${USERNAME}/.config/ COPY --chown=${USERNAME}:${USERNAME} starship/.config/starship.toml /home/${USERNAME}/.config/starship.toml COPY --chown=${USERNAME}:${USERNAME} .devcontainer/tmux.conf /home/${USERNAME}/.tmux.conf -COPY --chown=${USERNAME}:${USERNAME} .devcontainer/tmux-dev-layouts.sh /home/${USERNAME}/.tmux-dev-layouts.sh -RUN chmod +x /home/${USERNAME}/.tmux-dev-layouts.sh COPY --chown=${USERNAME}:${USERNAME} .devcontainer/onboard.sh /home/${USERNAME}/.onboard.sh RUN chmod +x /home/${USERNAME}/.onboard.sh COPY --chown=${USERNAME}:${USERNAME} .devcontainer/hooks/ /home/${USERNAME}/.claude/hooks/ @@ -202,12 +309,6 @@ USER ${USERNAME} ENV PATH="/home/${USERNAME}/.local/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/sbin:/bin" ENV FZF_DEFAULT_COMMAND="fdfind --type f" -# Claude / Anthropic environment (non-secret, baked in) -ENV CLAUDE_CODE_USE_FOUNDRY=1 \ - ANTHROPIC_DEFAULT_OPUS_MODEL=claude-opus-4-6 \ - ANTHROPIC_DEFAULT_SONNET_MODEL=claude-sonnet-4-6 \ - ANTHROPIC_DEFAULT_HAIKU_MODEL=claude-haiku-4-6 - ENV MAMBA_ROOT_PREFIX="/home/${USERNAME}/micromamba" # Wire micromamba shell hook into ~/.bashrc (appends eval block) @@ -219,6 +320,9 @@ RUN curl -fsSL https://opencode.ai/install | bash # Install Claude Code CLI (unpinned: install script does not expose a version flag) RUN curl -fsSL https://claude.ai/install.sh | bash +# Install Entire CLI (unpinned: install script does not expose a version flag) +RUN curl -fsSL https://entire.io/install.sh | bash + # Install uv RUN curl -LsSf https://astral.sh/uv/install.sh | UV_VERSION=${UV_VERSION} sh diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b21e982..70908ec 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -2,22 +2,6 @@ "name": "dev", "image": "ghcr.io/cedanl/dev-dots:latest", "remoteUser": "dev", - "mounts": [ - { - "source": "${localEnv:HOME}${localEnv:USERPROFILE}/.gitconfig", - "target": "/home/dev/.gitconfig", - "type": "bind", - "consistency": "cached", - "readonly": true - }, - { - "source": "${localEnv:HOME}${localEnv:USERPROFILE}/.ssh", - "target": "/home/dev/.ssh", - "type": "bind", - "consistency": "cached", - "readonly": true - } - ], "postCreateCommand": "bash .devcontainer/post-create.sh", "forwardPorts": [8000, 3030], "customizations": {} diff --git a/.devcontainer/onboard.sh b/.devcontainer/onboard.sh index 2df0f43..63cdbb9 100644 --- a/.devcontainer/onboard.sh +++ b/.devcontainer/onboard.sh @@ -2,12 +2,12 @@ # ============================================================================= # onboard.sh — Post-build onboarding wizard # ============================================================================= -# Guides you through the three authentication/setup steps needed after each -# fresh container build: +# Guides you through the three authentication steps needed after each fresh +# container build: # -# 1. gh auth login – primary GitHub account (git + gh CLI) -# 2. opencode auth login – secondary GitHub account (GitHub Copilot in OpenCode) -# 3. claude-setup – Anthropic Foundry API key & resource name +# 1. gh auth login — GitHub CLI authentication (+ git identity) +# 2. opencode auth login — GitHub Copilot in OpenCode +# 3. claude auth login — Claude Code CLI authentication (+ entire enable) # # Run via the shell function: onboard # Or directly: bash ~/.onboard.sh @@ -36,12 +36,14 @@ _yellow() { printf "${YELLOW}%s${RESET}" "$*"; } _cyan() { printf "${CYAN}%s${RESET}" "$*"; } # ── status helpers ──────────────────────────────────────────────────────────── -_done() { echo -e " ${GREEN}✔${RESET} $*"; } -_pending() { echo -e " ${YELLOW}◌${RESET} $*"; } -_skip() { echo -e " ${DIM}–${RESET} $* ${DIM}(skipped)${RESET}"; } -_info() { echo -e " ${CYAN}ℹ${RESET} $*"; } -_error() { echo -e " ${RED}✖${RESET} $*" >&2; } -_section() { echo -e "\n${BOLD}${CYAN}▶ $*${RESET}"; } +_done() { echo "[OK] $*"; } +_pending() { echo "[PENDING] $*"; } +_skip() { echo "[SKIPPED] $*"; } +_info() { echo "[INFO] $*"; } +_error() { echo "[ERROR] $*" >&2; } +_section() { echo ""; echo "================================================================================" + echo "$*" + echo "================================================================================"; } # ── check helpers ───────────────────────────────────────────────────────────── @@ -50,14 +52,6 @@ _gh_authed() { gh auth status &>/dev/null } -# Returns 0 if the Claude secrets file has non-empty key and resource values -_claude_configured() { - local secrets="$HOME/.claude/secrets.sh" - [[ -f "$secrets" ]] \ - && grep -qE 'ANTHROPIC_FOUNDRY_API_KEY="[^"]+"' "$secrets" \ - && grep -qE 'ANTHROPIC_FOUNDRY_RESOURCE="[^"]+"' "$secrets" -} - # Returns 0 if opencode appears to have auth credentials stored _opencode_authed() { # OpenCode stores provider config in ~/.config/opencode/config.json @@ -66,6 +60,11 @@ _opencode_authed() { [[ -f "$cfg" ]] && grep -qi '"copilot"\|"github_copilot"\|"github-copilot"' "$cfg" 2>/dev/null } +# Returns 0 if claude is authenticated (any account), non-zero otherwise +_claude_authed() { + claude auth status &>/dev/null +} + # ── prompt helpers ──────────────────────────────────────────────────────────── # Ask user a yes/no question; default answer shown in brackets. @@ -91,13 +90,53 @@ _ask_yn() { done } +# ── git identity (issue #7) ─────────────────────────────────────────────────── + +# Set an explicit per-user git identity from gh. Called after gh auth login. +setup_git_identity() { + _section "Git identity" + echo "" + _info "Deriving git identity from your GitHub account..." + echo "" + + if ! _gh_authed; then + _error "gh is not authenticated. Run 'gh auth login' first." + return 1 + fi + + local login name email + login=$(gh api user --jq '.login' 2>/dev/null || echo "") + name=$(gh api user --jq '.name' 2>/dev/null | sed 's/^null$//' || echo "") + email=$(gh api user --jq '.email' 2>/dev/null | sed 's/^null$//' || echo "") + # gh returns null for private/absent email; fall back to noreply address + [ -z "$email" ] && email="${login}@users.noreply.github.com" + + if [[ -z "$login" ]]; then + _error "Could not determine your GitHub login." + return 1 + fi + [ -z "$name" ] && name="$login" + + _info "Name: $(_bold "$name")" + _info "Email: $(_bold "$email")" + echo "" + if _ask_yn "Use this git identity?"; then + git config --global user.name "$name" + git config --global user.email "$email" + _done "git identity set (user.name / user.email)" + _info "user.useConfigOnly is enabled: commits without an identity fail." + else + _info "Setting git identity skipped. You can run 'onboard' again to set it." + fi +} + # ── step runners ────────────────────────────────────────────────────────────── run_gh_auth() { - _section "Step 1 / 3 — GitHub CLI authentication (primary account)" + _section "Step 1 / 3 — GitHub CLI authentication" echo "" - _info "This authenticates $(_bold 'gh') and $(_bold 'git') with your primary GitHub account." - _info "You will be prompted to choose a protocol (HTTPS/SSH) and login method." + _info "This authenticates gh CLI with your GitHub account." + _info "You will be prompted to choose a protocol (HTTPS) and login method." echo "" if _gh_authed; then @@ -116,6 +155,7 @@ run_gh_auth() { echo "" if [[ $rc -eq 0 ]]; then _done "gh auth login completed successfully." + setup_git_identity || true else _error "gh auth login exited with code $rc. You can retry with: $(_bold 'gh auth login')" fi @@ -123,10 +163,10 @@ run_gh_auth() { } run_opencode_auth() { - _section "Step 2 / 3 — OpenCode × GitHub Copilot (secondary account)" + _section "Step 2 / 3 — OpenCode × GitHub Copilot" echo "" - _info "This connects $(_bold 'opencode') to GitHub Copilot using your secondary GitHub account." - _info "OpenCode will open an interactive setup — select $(_bold 'GitHub Copilot') as the provider" + _info "This connects opencode to GitHub Copilot." + _info "OpenCode will open an interactive setup — select 'GitHub Copilot' as the provider" _info "and follow the browser / device-code flow to sign in." echo "" @@ -159,57 +199,77 @@ run_opencode_auth() { return $rc } -run_claude_setup() { - _section "Step 3 / 3 — Claude / Anthropic Foundry setup" +run_claude_auth() { + _section "Step 3 / 3 — Claude Code CLI authentication" echo "" - _info "This sets your $(_bold 'ANTHROPIC_FOUNDRY_API_KEY') and $(_bold 'ANTHROPIC_FOUNDRY_RESOURCE')" - _info "in $(_dim '~/.claude/secrets.sh') — they will be sourced into your shell when the wizard exits." + _info "This authenticates Claude Code CLI with your Anthropic account." + _info "Follow the browser or device-code flow to sign in." echo "" - if _claude_configured; then - _done "Claude secrets already configured in ~/.claude/secrets.sh" + if ! command -v claude &>/dev/null; then + _error "claude is not installed. Skipping." + return 1 + fi + + if _claude_authed; then + _done "Claude Code CLI is already authenticated." echo "" - if ! _ask_yn "Edit the secrets file again (rotate key / change resource)?"; then - _skip "claude-setup" + if ! _ask_yn "Re-authenticate (switch account or refresh token)?"; then + _skip "claude auth login" + setup_entire || true return 0 fi fi - # claude-setup is a shell function; if this script is sourced it's available, - # but if run as a subprocess we fall back to the inline implementation. - if declare -f claude-setup &>/dev/null; then - echo "" - claude-setup + echo "" + _info "Running: claude auth login" + echo "" + claude auth login + local rc=$? + echo "" + if [[ $rc -eq 0 ]]; then + _done "claude auth login completed successfully." + setup_entire || true else - _info "Opening ~/.claude/secrets.sh in nvim…" - local secrets="$HOME/.claude/secrets.sh" - if [[ ! -f "$secrets" ]]; then - mkdir -p "$(dirname -- "$secrets")" - cat >"$secrets" <<'TMPL' -# Claude Foundry secrets — fill these in after container creation -# Edit this file: use 'claude-setup' or edit directly at ~/.claude/secrets.sh -export ANTHROPIC_FOUNDRY_API_KEY="" -export ANTHROPIC_FOUNDRY_RESOURCE="" -TMPL - _info "Created template secrets file: $secrets" - fi - if command -v nvim &>/dev/null; then - nvim "$secrets" - else - _error "nvim not found. Please edit $secrets manually." - return 1 - fi - # Validate syntax before sourcing to avoid partial execution of a bad file - if ! bash -n "$secrets" 2>/dev/null; then - _error "Syntax error in $secrets. Please fix it and run 'claude-setup' again." - return 1 - fi - if source "$secrets"; then - _done "Claude secrets saved. They will be loaded into your shell when the wizard exits." + _error "claude auth login exited with code $rc." + _info "You can retry later with: claude auth login" + fi + return $rc +} + +# ── entire setup (issue #5) ─────────────────────────────────────────────────── + +# Enable Entire hooks for Claude Code right after claude auth succeeds. +setup_entire() { + _section "Entire CLI — session capture" + echo "" + _info "Enabling Entire hooks for Claude Code..." + echo "" + + if ! command -v entire &>/dev/null; then + _error "entire is not installed. Skipping." + return 1 + fi + + if ! git rev-parse --is-inside-work-tree &>/dev/null; then + _error "Not inside a git repository. Entire needs a repo; skipping." + return 1 + fi + + if _ask_yn "Enable Entire (capture AI sessions in this repo)?"; then + entire enable --agent claude-code + local rc=$? + echo "" + if [[ $rc -eq 0 ]]; then + _done "Entire enabled for Claude Code." else - _error "Failed to source $secrets. Please check the file for syntax errors." - return 1 + _error "entire enable exited with code $rc." + _info "You can retry later with: entire enable --agent claude-code" fi + return $rc + else + _skip "entire enable" + return 0 fi } @@ -217,30 +277,28 @@ TMPL print_summary() { echo "" - echo -e "${BOLD}${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" - echo -e "${BOLD} Onboarding summary${RESET}" - echo -e "${BOLD}${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" + echo "================================================================================" + echo "ONBOARDING SUMMARY" + echo "================================================================================" echo "" if _gh_authed; then - _done "gh / git — authenticated" + _done "gh / git authenticated" else - _pending "gh / git — $(_bold 'not authenticated') → run: $(_yellow 'gh auth login')" + _pending "gh / git not authenticated — run: gh auth login" fi if _opencode_authed; then - _done "opencode — Copilot provider configured" + _done "opencode Copilot provider configured" else - _pending "opencode — $(_bold 'not configured') → run: $(_yellow 'opencode auth login')" + _pending "opencode not configured — run: opencode auth login" fi - if _claude_configured; then - _done "claude — Foundry secrets configured" + if _claude_authed; then + _done "claude Code CLI authenticated" else - _pending "claude — $(_bold 'not configured') → run: $(_yellow 'claude-setup')" + _pending "claude not authenticated — run: claude auth login" fi - - echo "" } # ── main ────────────────────────────────────────────────────────────────────── @@ -248,19 +306,19 @@ print_summary() { main() { clear echo "" - echo -e "${BOLD}${CYAN}╔══════════════════════════════════════════════╗${RESET}" - echo -e "${BOLD}${CYAN}║ dev-dots — post-build onboarding ║${RESET}" - echo -e "${BOLD}${CYAN}╚══════════════════════════════════════════════╝${RESET}" + echo "================================================================================" + echo "DEV-DOTS ONBOARDING WIZARD" + echo "================================================================================" echo "" - echo -e " Welcome! This wizard walks you through the three auth/setup" - echo -e " steps needed after each fresh container build." + echo "Welcome! This wizard walks you through the three authentication steps" + echo "needed after each fresh container build." echo "" # Quick pre-flight status - echo -e "${BOLD} Current status:${RESET}" + echo "Current status:" if _gh_authed; then _done "gh auth login"; else _pending "gh auth login"; fi if _opencode_authed; then _done "opencode auth login"; else _pending "opencode auth login"; fi - if _claude_configured; then _done "claude-setup"; else _pending "claude-setup"; fi + if _claude_authed; then _done "claude auth login"; else _pending "claude auth login"; fi echo "" if _ask_yn "Run the wizard now?"; then @@ -273,14 +331,15 @@ main() { run_opencode_auth || true # Step 3 - run_claude_setup || true + run_claude_auth || true print_summary - echo -e " All done! Run ${BOLD}onboard${RESET} at any time to re-run individual steps." + echo "" + echo "All done! Run 'onboard' at any time to re-run individual steps." echo "" else echo "" - echo -e " Skipped. Run ${BOLD}onboard${RESET} at any time to start the wizard." + echo "Skipped. Run 'onboard' at any time to start the wizard." echo "" fi } diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index 50998fd..e8f1dea 100644 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -1,30 +1,37 @@ #!/usr/bin/env bash set -euo pipefail -echo "🔥 Starting post-create.sh..." -echo "👤 Running as: $(id)" - -# Install org-wide Claude/OpenCode skills from cedanl/.github -npx --yes skills add cedanl/.github --skill '*' -a claude-code -a opencode -a pi -y --copy -g +echo "" +echo "================================================================================" +echo "POST-CREATE SETUP STARTING" +echo "================================================================================" +echo "Running as: $(id)" +echo "" # Verify key CLIs are available (all installed via Dockerfile) -echo "✅ CLIs available:" -for cli in nvim opencode claude uv starship zoxide node npm csvlens micromamba; do - which "$cli" 2>/dev/null && echo " ✅ $cli: $(which $cli)" || echo " ⚠️ $cli: missing" +echo "================================================================================" +echo "CLIs AVAILABLE" +echo "================================================================================" +for cli in nvim opencode claude uv starship zoxide node npm csvlens micromamba az azcopy azd kubectl helm flux glab aws entire; do + which "$cli" 2>/dev/null && echo "[OK] $cli: $(which $cli)" || echo "[MISSING] $cli" done # Print git tooling summary echo "" -echo "🛠️ Git tooling available:" +echo "================================================================================" +echo "GIT TOOLING AVAILABLE" +echo "================================================================================" for cli in git lazygit gh delta; do - which "$cli" >/dev/null 2>&1 && echo " ✅ $cli: $(which $cli)" || echo " ❌ $cli: missing" + which "$cli" >/dev/null 2>&1 && echo "[OK] $cli: $(which $cli)" || echo "[MISSING] $cli" done # Collect all installed tool versions and write to tool-versions.txt # This file is .gitignore'd; useful for debugging when a build has issues. TOOL_VERSIONS_FILE="/workspace/tool-versions.txt" echo "" -echo "📋 Collecting tool versions → $TOOL_VERSIONS_FILE" +echo "================================================================================" +echo "COLLECTING TOOL VERSIONS" +echo "================================================================================" { echo "# Tool versions captured at devcontainer post-create" echo "# Date: $(date -u '+%Y-%m-%d %H:%M:%S UTC')" @@ -61,22 +68,29 @@ echo "📋 Collecting tool versions → $TOOL_VERSIONS_FILE" } > "$TOOL_VERSIONS_FILE" -echo " ✅ Written to $TOOL_VERSIONS_FILE" - +echo "Written to: $TOOL_VERSIONS_FILE" echo "" -echo "💡 Tip: Run 'gh auth login' to authenticate with GitHub" -echo "💡 Tip: Run 'lazygit' to open the lazygit TUI" -echo "💡 Tip: Run 'tdl opencode' to open a tmux dev layout with OpenCode" -echo "💡 Tip: Run 'claude-setup' to set your ANTHROPIC_FOUNDRY_API_KEY and ANTHROPIC_FOUNDRY_RESOURCE" -echo "📺 Tmux layouts: tdl , tdlm , tsl " +echo "================================================================================" +echo "TIPS & NEXT STEPS" +echo "================================================================================" +echo "Run 'az login' to authenticate with Azure (enables az, azcopy, azd)" +echo "Run 'lazygit' to open the lazygit TUI" echo "" -echo "🧭 Run 'onboard' to launch the interactive post-build checklist wizard" -echo " (gh auth login + opencode auth + claude-setup in one guided flow)" +echo "RUN 'onboard' for guided authentication setup" +echo " (Step 1: gh auth login)" +echo " (Step 2: opencode auth login)" +echo " (Step 3: claude auth login)" + +# ── Git identity guard ───────────────────────────────────────────────────────── +# Refuse to guess an identity; each user sets name/email via 'onboard'. +git config --global user.useConfigOnly true # ── Claude Code container-wide settings ────────────────────────────────────── echo "" -echo "🤖 Configuring Claude Code container-wide settings..." +echo "================================================================================" +echo "CONFIGURING CLAUDE CODE SETTINGS" +echo "================================================================================" CLAUDE_DIR="$HOME/.claude" CLAUDE_SETTINGS="$CLAUDE_DIR/settings.json" @@ -89,7 +103,7 @@ mkdir -p "$CLAUDE_HOOKS_DIR" if [ -d "$REPO_HOOKS_DIR" ]; then cp "$REPO_HOOKS_DIR"/*.sh "$CLAUDE_HOOKS_DIR/" 2>/dev/null && \ chmod +x "$CLAUDE_HOOKS_DIR"/*.sh - echo " ✅ Hooks installed to $CLAUDE_HOOKS_DIR" + echo "[OK] Hooks installed to $CLAUDE_HOOKS_DIR" fi # Container-wide settings to merge (hook + common permissions) @@ -139,8 +153,21 @@ if [ -f "$CLAUDE_SETTINGS" ]; then else echo "$CONTAINER_SETTINGS" > "$CLAUDE_SETTINGS" fi -echo " ✅ Container-wide settings merged into $CLAUDE_SETTINGS" +echo "[OK] Container-wide settings merged into $CLAUDE_SETTINGS" +# ── Load Claude/OpenCode skills ────────────────────────────────────────────── echo "" -echo "✅ Post-create complete. Run 'nvim .' or 'tdl opencode' to get started." +echo "================================================================================" +echo "LOADING CLAUDE SKILLS" +echo "================================================================================" + +npx --yes skills add cedanl/.github --skill '*' -a claude-code -a opencode -a pi -y --copy -g 2>/dev/null && \ + echo "[OK] Skills loaded from cedanl/.github" || \ + echo "[SKIPPED] Skills install (npx may not be available yet)" +echo "" +echo "================================================================================" +echo "POST-CREATE SETUP COMPLETE" +echo "================================================================================" +echo "Run 'onboard' to authenticate GitHub CLI, OpenCode and Claude" +echo "Run 'nvim .' to start editing" diff --git a/.devcontainer/tmux-dev-layouts.sh b/.devcontainer/tmux-dev-layouts.sh deleted file mode 100644 index bb46bd7..0000000 --- a/.devcontainer/tmux-dev-layouts.sh +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env bash - -# Tmux Dev Layouts - Create editor+AI tmux layouts -# Source this file or add to your .bashrc: source ~/.tmux-dev-layouts.sh - -# Create a Tmux Dev Layout with editor, ai, and terminal -# Usage: tdl [] -tdl() { - [[ -z $1 ]] && { echo "Usage: tdl []"; return 1; } - [[ -z $TMUX ]] && { echo "You must start tmux to use tdl."; return 1; } - - local current_dir="${PWD}" - local editor_pane ai_pane ai2_pane - local ai="$1" - local ai2="$2" - - editor_pane="$TMUX_PANE" - - tmux rename-window -t "$editor_pane" "$(basename "$current_dir")" - - tmux split-window -v -p 15 -t "$editor_pane" -c "$current_dir" - - ai_pane=$(tmux split-window -h -p 30 -t "$editor_pane" -c "$current_dir" -P -F '#{pane_id}') - - if [[ -n $ai2 ]]; then - ai2_pane=$(tmux split-window -v -t "$ai_pane" -c "$current_dir" -P -F '#{pane_id}') - tmux send-keys -t "$ai2_pane" "$ai2" C-m - fi - - tmux send-keys -t "$ai_pane" "$ai" C-m - - tmux send-keys -t "$editor_pane" "nvim ." C-m - - tmux select-pane -t "$editor_pane" -} - -# Create multiple tdl windows with one per subdirectory in the current directory -# Usage: tdlm [] -tdlm() { - [[ -z $1 ]] && { echo "Usage: tdlm []"; return 1; } - [[ -z $TMUX ]] && { echo "You must start tmux to use tdlm."; return 1; } - - local ai="$1" - local ai2="$2" - local base_dir="$PWD" - local first=true - - tmux rename-session "$(basename "$base_dir" | tr '.:' '--')" - - for dir in "$base_dir"/*/; do - [[ -d $dir ]] || continue - local dirpath="${dir%/}" - - if $first; then - tmux send-keys -t "$TMUX_PANE" "cd '$dirpath' && tdl $ai $ai2" C-m - first=false - else - local pane_id=$(tmux new-window -c "$dirpath" -P -F '#{pane_id}') - tmux send-keys -t "$pane_id" "tdl $ai $ai2" C-m - fi - done -} - -# Create a multi-pane swarm layout with the same command started in each pane (great for AI) -# Usage: tsl -tsl() { - [[ -z $1 || -z $2 ]] && { echo "Usage: tsl "; return 1; } - [[ -z $TMUX ]] && { echo "You must start tmux to use tsl."; return 1; } - - local count="$1" - local cmd="$2" - local current_dir="${PWD}" - local -a panes - - tmux rename-window -t "$TMUX_PANE" "$(basename "$current_dir")" - - panes+=("$TMUX_PANE") - - while (( ${#panes[@]} < count )); do - local new_pane - local split_target="${panes[-1]}" - new_pane=$(tmux split-window -h -t "$split_target" -c "$current_dir" -P -F '#{pane_id}') - panes+=("$new_pane") - tmux select-layout -t "${panes[0]}" tiled - done - - for pane in "${panes[@]}"; do - tmux send-keys -t "$pane" "$cmd" C-m - done - - tmux select-pane -t "${panes[0]}" -} diff --git a/README.md b/README.md index 892f12d..ddcdbad 100644 --- a/README.md +++ b/README.md @@ -7,27 +7,23 @@ Devcontainer voor dagelijks ontwikkelwerk — AI-first, reproduceerbaar, direct - **Base**: Debian bookworm-slim, `amd64` + `arm64` - **Shell**: bash, starship, zoxide, eza, fzf, bat, fd, ripgrep, jq - **Editor**: Neovim + LazyVim -- **Git**: lazygit, gh, delta +- **Git**: lazygit, gh, glab, delta - **Data**: csvlens -- **AI**: claude, opencode, org-skills via `cedanl/.github` +- **AI**: claude, opencode, entire, org-skills via `cedanl/.github` — met `--dangerously-skip-permissions` - **Python**: uv - **Node**: LTS +- **Cloud**: az, azcopy, azd, aws, kubectl, helm, flux, sops - **Media & automatisering**: ffmpeg, Playwright headless Chromium ## Snel starten 1. Open in VS Code → `Dev Containers: Reopen in Container` 2. Wacht op post-create -3. Voer `gh auth login` eenmalig uit -4. Aan de slag met `nvim .` of `tdl claude` +3. Voer `onboard` uit — begeleide authenticatie (gh, opencode, claude) + git-identiteit +4. Aan de slag met `nvim .` of `claude` -## tmux-layouts - -``` -tdl [tweede_ai] # editor + AI-venster(s) + terminal -tdlm [tweede_ai] # één venster per submap -tsl # commando parallel over n vensters -``` +> Claude Code en OpenCode starten met `--dangerously-skip-permissions` (ingebakken als shell-alias). +> Git gebruikt per user een expliciete identiteit (ingesteld door `onboard`) en `user.useConfigOnly true`. ## Screenshots en GIFs automatiseren diff --git a/bash/.bashrc b/bash/.bashrc index 2f74862..45a98a3 100644 --- a/bash/.bashrc +++ b/bash/.bashrc @@ -126,11 +126,5 @@ eval "$(starship init bash)" # uv shell completion eval "$(uv generate-shell-completion bash)" -# Tmux dev layout helpers (tdl / tdlm / tsl) -[[ -f "$HOME/.tmux-dev-layouts.sh" ]] && source "$HOME/.tmux-dev-layouts.sh" - -# Claude secrets (fill in ~/.claude/secrets.sh post-build) -[[ -f "$HOME/.claude/secrets.sh" ]] && source "$HOME/.claude/secrets.sh" - export PATH="$HOME/.devcontainers/bin:$PATH" export PATH="$HOME/.local/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/sbin:/bin:$PATH" diff --git a/bash/.config/bash/aliases b/bash/.config/bash/aliases index e798fc4..30fac2b 100644 --- a/bash/.config/bash/aliases +++ b/bash/.config/bash/aliases @@ -11,6 +11,11 @@ alias ..='cd ..' alias ...='cd ../..' alias ....='cd ../../..' +# ===================== +# Agents (skip permission prompts — safe inside devcontainer) +# ===================== +alias claude="claude --dangerously-skip-permissions" +alias opencode="opencode --dangerously-skip-permissions" # ===================== # Fuzzy Finder & Previews diff --git a/bash/.config/bash/functions b/bash/.config/bash/functions index 54c4caa..15ec259 100644 --- a/bash/.config/bash/functions +++ b/bash/.config/bash/functions @@ -3,61 +3,13 @@ # Onboarding Wizard # ===================== onboard() { - # Source the wizard script so that inner calls to claude-setup (a shell - # function defined in this file) work correctly inside the subprocess. + # Run the wizard script to set up authentication and configuration. local script="$HOME/.onboard.sh" if [[ ! -f "$script" ]]; then echo "[onboard] Wizard script not found at $script" >&2 return 1 fi - # Export claude-setup into the bash subprocess so that onboard.sh can detect - # and call it via 'declare -f claude-setup', falling back to its own inline - # implementation when the export is unavailable (e.g. older bash versions). - export -f claude-setup 2>/dev/null || true - bash "$script" - # The wizard runs in a subprocess and cannot export env vars back to us. - # Re-source the Claude secrets file here in the parent shell so that - # ANTHROPIC_FOUNDRY_API_KEY and ANTHROPIC_FOUNDRY_RESOURCE are available - # in the current interactive session after the wizard finishes. - local secrets="$HOME/.claude/secrets.sh" - if [[ -f "$secrets" ]] && bash -n "$secrets" 2>/dev/null; then - source "$secrets" - fi -} - -# ===================== -# Claude Setup -# ===================== -claude-setup() { - local secrets="$HOME/.claude/secrets.sh" - - # Ensure the secrets file exists - if [ ! -f "$secrets" ]; then - mkdir -p "$(dirname -- "$secrets")" - cat > "$secrets" <<'EOF' -# Claude Foundry secrets 4 fill these in after container creation -# Edit this file: Use 'claude-setup' or edit directly at ~/.claude/secrets.sh -export ANTHROPIC_FOUNDRY_API_KEY="" -export ANTHROPIC_FOUNDRY_RESOURCE="" -EOF - echo "[claude-setup] Created template secrets file: $secrets" - fi - - - # Always use nvim for editing - if ! command -v nvim >/dev/null 2>&1; then - echo "[claude-setup] Error: nvim (Neovim) is not installed. Please install it to proceed." >&2 - return 1 - fi - nvim "$secrets" - - # Source the secrets file - if source "$secrets"; then - echo "Claude secrets loaded." - else - echo "[claude-setup] Error: Failed to source secrets from $secrets. Please check syntax or permissions." >&2 - return 2 - fi + bash "$script" "$@" } # ===================== diff --git a/bash/.config/claude/secrets.sh b/bash/.config/claude/secrets.sh deleted file mode 100644 index 80eab33..0000000 --- a/bash/.config/claude/secrets.sh +++ /dev/null @@ -1,5 +0,0 @@ -# Claude Foundry secrets — fill these in after container creation -# Canonical path is ~/.claude/secrets.sh. You can edit directly or with 'claude-setup'. -# Edit this file: Run 'claude-setup' (uses nvim) or edit directly at ~/.claude/secrets.sh -export ANTHROPIC_FOUNDRY_API_KEY="" -export ANTHROPIC_FOUNDRY_RESOURCE="" diff --git a/bash/.config/opencode/opencode.json b/bash/.config/opencode/opencode.json new file mode 100644 index 0000000..356f5a6 --- /dev/null +++ b/bash/.config/opencode/opencode.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://opencode.ai/config.json", + "permission": "allow" +} \ No newline at end of file diff --git a/docs/ai.md b/docs/ai.md index cf4f2d9..32ea750 100644 --- a/docs/ai.md +++ b/docs/ai.md @@ -1,6 +1,6 @@ # AI-workflows -dev-dots is gebouwd rond AI-ondersteund ontwikkelen. Twee CLI-assistenten staan klaar: **Claude Code** (Anthropic) en **OpenCode** (OpenAI-compatible). De tmux-layouts zijn ontworpen om ze naadloos naast je editor te laten draaien. +dev-dots is gebouwd rond AI-ondersteund ontwikkelen. Twee CLI-assistenten staan klaar: **Claude Code** (Anthropic) en **OpenCode** (OpenAI-compatible). Beide starten met `--dangerously-skip-permissions` (ingebakken als shell-alias) — binnen de devcontainer de bedoelde workflow. --- @@ -12,82 +12,62 @@ Voer `onboard` uit voor een begeleide setup: onboard ``` -Of stel Claude Code handmatig in: +Dit authenticeert in drie stappen: -```bash -claude-setup # opent ~/.claude/secrets.sh in Neovim -``` - -Vul hier je `ANTHROPIC_FOUNDRY_API_KEY` en `ANTHROPIC_FOUNDRY_RESOURCE` in. De secrets worden automatisch geladen bij elke sessie. +1. **gh auth login** — GitHub CLI (en stelt je git-identiteit in via `gh api user`) +2. **opencode auth login** — GitHub Copilot in OpenCode +3. **claude auth login** — Claude Code CLI (subscription) --- ## Claude Code ```bash -claude # start Claude Code in de huidige map +claude # start Claude Code in de huidige map (skip-permissions alias) ``` Claude Code werkt als een autonome agent die bestanden leest, aanpast en commando's uitvoert. Geef een taak in gewone taal. +Authenticatie verloopt via subscription: `claude auth login` (browser / device-code flow). + +> De shell-alias zet `claude` om in `claude --dangerously-skip-permissions`. Een subcommando zoals `auth login` gaat dan óók door die alias: in zeldzame gevallen kan een leading flag een subcommando overschaduwen. Gebruik `command claude auth login` om de alias expliciet te omzeilen als het login-scherm niet opent. + --- ## OpenCode ```bash -opencode # start OpenCode in de huidige map +opencode # start OpenCode in de huidige map (skip-permissions alias) ``` OpenCode werkt op dezelfde manier maar is compatible met verschillende providers. Authenticeer via: ```bash -opencode auth +opencode auth login ``` ---- - -## tmux-layouts - -De layouts zijn de snelste manier om te werken. Ze openen Neovim, een AI en een vrije terminal in één venster. - -### `tdl` — standaard layout +De globale config staat in `~/.config/opencode/opencode.json` met `permission: "allow"` — naast de skip-permissions alias. -```bash -tdl claude # editor + Claude + terminal -tdl opencode # editor + OpenCode + terminal -tdl claude opencode # editor + Claude + OpenCode (geen losse terminal) -``` +--- -Het venster ziet er zo uit: +## Entire — AI-sessies vastleggen -``` -┌────────────────────┬──────────┐ -│ │ │ -│ nvim . │ claude │ -│ │ │ -├────────────────────┴──────────┤ -│ vrije terminal │ -└───────────────────────────────┘ -``` - -### `tdlm` — multi-project layout +`onboard` schakelt **Entire** in voor Claude Code direct na `claude auth login`: ```bash -tdlm claude +entire enable --agent claude-code ``` -Voer dit uit in een map met meerdere submappen. Voor elke submap komt er een tmux-venster met een volledige `tdl`-layout. Handig voor monorepo's of wanneer je meerdere services tegelijk wilt bijwerken. - -### `tsl` — parallelle zwerm +Entire legt AI-sessies vast naast je commits op een aparte `entire/checkpoints/v1`-branch, zodat je elke wijziging terug kunt voeren naar de prompt die hem veroorzaakte. ```bash -tsl 4 claude # vier Claude-sessies naast elkaar -tsl 3 opencode # drie OpenCode-sessies +entire status # sessiestatus +entire checkpoint explain # leg uit waarom code veranderd is +entire session resume # hervat een eerdere sessie ``` -Alle panelen starten hetzelfde commando, elk in de huidige map. Gebruik dit om taken parallel te laten draaien — bijvoorbeeld dezelfde prompt op meerdere subdirectories loslaten. - --- -!!! warning "tmux vereist" - `tdl`, `tdlm` en `tsl` werken alleen binnen een tmux-sessie. Start `tmux` voordat je ze aanroept. +## Git-identiteit per user + +`onboard` leidt na `gh auth login` je git-identiteit af (`user.name` / `user.email`) en zet `user.useConfigOnly true`. Commits zonder ingestelde identiteit falen met een duidelijke fout — zo wordt misattributie tussen collega's voorkomen. diff --git a/docs/index.md b/docs/index.md index e12cc57..00c18a3 100644 --- a/docs/index.md +++ b/docs/index.md @@ -13,7 +13,7 @@ Dit is geen grab-bag van willekeurige tools. Het is één consistent systeem, on | Editor | Neovim met LazyVim | | Terminal multiplexer | tmux | | Git TUI | lazygit | -| GitHub CLI | gh | +| GitHub CLI | gh, glab | | Git diffs | delta | | Fuzzy finder | fzf | | Moderne `ls` | eza | @@ -24,7 +24,9 @@ Dit is geen grab-bag van willekeurige tools. Het is één consistent systeem, on | CSV-viewer | csvlens | | AI (Anthropic) | Claude Code | | AI (OpenAI-compatible) | OpenCode | +| AI-sessies | entire | | Python packages | uv | +| Cloud & k8s | az, azcopy, azd, aws, kubectl, helm, flux, sops | | Schermopname & GIF | ffmpeg | | Headless browser | Playwright (Chromium) | @@ -34,7 +36,7 @@ Dit is geen grab-bag van willekeurige tools. Het is één consistent systeem, on Open de repository in VS Code en kies **Dev Containers: Reopen in Container**. Na de post-create setup ben je klaar. -Voer `onboard` uit voor een begeleide setup van GitHub-authenticatie en AI-sleutels: +Voer `onboard` uit voor een begeleide setup van GitHub-authenticatie, OpenCode, Claude en je git-identiteit: ```bash onboard @@ -43,11 +45,11 @@ onboard Start daarna een werksessie: ```bash -tmux -tdl claude +nvim . +claude ``` -Dat opent Neovim, een Claude Code-sessie en een vrije terminal — naast elkaar in één venster. +> Claude Code en OpenCode starten met `--dangerously-skip-permissions` (ingebakken als shell-alias) — binnen de devcontainer de bedoelde workflow. --- @@ -56,24 +58,21 @@ Dat opent Neovim, een Claude Code-sessie en een vrije terminal — naast elkaar Zo ziet een complete AI-codesessie eruit van begin tot eind: ```bash -# 1. Start tmux (houdt sessie levend ook als je venster sluit) -tmux - -# 2. Ga naar je project +# 1. Ga naar je project cd mijn-project -# 3. Open de AI-layout: Neovim + Claude Code + vrije terminal -tdl claude +# 2. Start Claude Code (skip-permissions alias) +claude -# 4. Geef Claude een taak (in het Claude-paneel rechts) +# 3. Geef Claude een taak # Claude leest je bestanden, schrijft code, voert tests uit -# 5. Review de wijzigingen in Neovim (linker paneel) +# 4. Review de wijzigingen in Neovim # Space g g → open lazygit # spatiebalk → stage bestanden # c → commit -# 6. Maak een pull request (in de vrije terminal onder) +# 5. Maak een pull request gh pr create ``` @@ -89,7 +88,7 @@ gh pr create | `~/.config/nvim/` (LazyVim) | Ja — ingebakken in de image | | LazyVim plugins (`~/.local/share/nvim`) | Nee — worden opnieuw gedownload bij eerste `nvim` | | Zoxide-geschiedenis | Nee — begint leeg na rebuild | -| AI-sleutels (`~/.claude/secrets.sh`) | Nee — opnieuw instellen via `claude-setup` | +| Git-identiteit (`user.name`, `user.email`) | Nee — opnieuw instellen via `onboard` | !!! tip "Eerste keer na rebuild" - Start `nvim` één keer en wacht tot alle plugins geladen zijn. Voer daarna `onboard` uit om GitHub en AI opnieuw in te stellen. + Start `nvim` één keer en wacht tot alle plugins geladen zijn. Voer daarna `onboard` uit om GitHub, OpenCode, Claude en je git-identiteit opnieuw in te stellen. diff --git a/docs/navigatie.md b/docs/navigatie.md index da4e3bd..5b2f6db 100644 --- a/docs/navigatie.md +++ b/docs/navigatie.md @@ -74,46 +74,17 @@ tmux gebruikt vi-stijl selectie in kopieermodus. Kopiëren werkt via **OSC 52**: --- -## AI-layouts +## Werksessie -Dit zijn de krachtigste commando's in dev-dots. Ze bouwen in één keer een complete werkomgeving op. - -### `tdl` — editor + AI + terminal +Zo ziet een complete AI-codesessie eruit: ```bash -tdl claude # Neovim + Claude Code + vrije terminal -tdl opencode # Neovim + OpenCode + vrije terminal -tdl claude opencode # Neovim + twee AI-assistenten -``` - -Het venster ziet er zo uit: - +cd mijn-project +claude # Claude Code (skip-permissions alias) +# Neovim erbij: +nvim . +# of start OpenCode: +opencode # skip-permissions alias ``` -┌────────────────────┬──────────┐ -│ │ │ -│ nvim . │ claude │ -│ │ │ -├────────────────────┴──────────┤ -│ vrije terminal │ -└───────────────────────────────┘ -``` - -### `tdlm` — één layout per submap - -```bash -tdlm claude -``` - -Voor elke submap van de huidige directory opent `tdlm` een apart tmux-venster met de volledige `tdl`-layout. Handig voor monorepo's of wanneer je meerdere services tegelijk wilt bijwerken. - -### `tsl` — parallelle zwerm - -```bash -tsl 4 claude # start Claude Code in 4 panelen tegelijk -tsl 3 opencode -``` - -Alle panelen krijgen hetzelfde commando. Gebruik dit om meerdere taken tegelijkertijd te laten draaien. -!!! tip - Al deze commando's vereisen een actieve tmux-sessie. Start `tmux` voordat je ze aanroept. +Wil je meerdere terminals naast elkaar, gebruik dan handmatig tmux-panelen (`Ctrl+b %` / `Ctrl+b "`) of splits in VS Code's terminal. diff --git a/starship/.config/starship.toml b/starship/.config/starship.toml index 15f714a..d6f10ca 100644 --- a/starship/.config/starship.toml +++ b/starship/.config/starship.toml @@ -3,12 +3,12 @@ command_timeout = 200 format = "[$directory]($style)[$git_branch]($style) [$git_status]($style)$character" [character] -error_symbol = "[✘](bold red)" -success_symbol = "[➜](bold green)" +error_symbol = "[x](bold red)" +success_symbol = "[>](bold green)" [directory] truncation_length = 3 -truncation_symbol = "…" +truncation_symbol = "..." repo_root_style = "bold magenta" repo_root_format = "[$repo_root]($repo_root_style)[$path]($style)[$read_only]($read_only_style) " style = "225" @@ -20,14 +20,14 @@ style = "italic yellow" [git_status] format = '[$all_status]($style)' style = "bold red" -ahead = "↑${count} " -diverged = "⇅${ahead_count}↓${behind_count} " -behind = "↓${count} " -conflicted = "⚔ " -up_to_date = "✓ " -untracked = "◌ " -modified = "✎ " -stashed = "📦 " -staged = "⦿ " -renamed = "➜ " -deleted = "✖ " +ahead = "+${count} " +diverged = "+${ahead_count}/-${behind_count} " +behind = "-${count} " +conflicted = "! " +up_to_date = "= " +untracked = "? " +modified = "* " +stashed = "$ " +staged = "+ " +renamed = "~ " +deleted = "- " \ No newline at end of file From ad84a1524da4cf7ddb31c12fc01666480f174fba Mon Sep 17 00:00:00 2001 From: Tomeriko96 Date: Thu, 13 Aug 2026 11:00:25 +0200 Subject: [PATCH 2/2] fix: drop nonexistent sha256 checksum from AWS CLI install --- .devcontainer/Dockerfile | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index c3bd7d7..4fe70d1 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -258,18 +258,14 @@ RUN set -eux; . /etc/arch_vars; \ flux --version # Install AWS CLI v2. The official installer only ships "latest", so we cannot -# pin a version at build time; the released checksum verifies integrity of the -# download. Track the actual version via post-create's tool-versions.txt. +# pin a version at build time (AWS publishes PGP .sig files, not sha256 sums). +# Track the actual version via post-create's tool-versions.txt. RUN set -eux; . /etc/arch_vars; \ curl -Lo /tmp/awscliv2.zip \ "https://awscli.amazonaws.com/awscli-exe-linux-${ARCH_TAR}.zip"; \ - curl -Lo /tmp/awscliv2.zip.sha256 \ - "https://awscli.amazonaws.com/awscli-exe-linux-${ARCH_TAR}.zip.sha256"; \ - printf '%s %s\n' "$(cut -d' ' -f1 /tmp/awscliv2.zip.sha256)" "awscliv2.zip" | \ - sha256sum -c -; \ unzip -q /tmp/awscliv2.zip -d /tmp; \ /tmp/aws/install --bin-dir /usr/local/bin --install-dir /usr/local/aws-cli; \ - rm -rf /tmp/awscliv2.zip /tmp/awscliv2.zip.sha256 /tmp/aws; \ + rm -rf /tmp/awscliv2.zip /tmp/aws; \ aws --version # Create non-root dev user