Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion dot_files/ai-dev/Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,18 @@ RUN curl -fsSL https://claude.ai/install.sh | bash
RUN curl -fsSL https://antigravity.google/cli/install.sh | bash

# =============================================================================
# LAYER 3: Entrypoint script (sets PATH, execs command)
# LAYER 3: Ghostty terminfo (xterm-ghostty)
# =============================================================================
# Inherited from nvim-dev, but install explicitly so ai-dev still resolves
# TERM=xterm-ghostty if the base image ever changes. Prevents awkward escape
# sequences in the Claude Code / Antigravity TUIs.
USER root
RUN curl -fsSL https://raw.githubusercontent.com/ghostty-org/ghostty/main/src/terminfo/ghostty.terminfo \
| tic -x -o /etc/terminfo -

# =============================================================================
# LAYER 4: Entrypoint script (sets PATH, execs command)
# =============================================================================
COPY ai-entrypoint.sh /usr/local/bin/ai-entrypoint.sh
RUN chmod +x /usr/local/bin/ai-entrypoint.sh

Expand Down
20 changes: 13 additions & 7 deletions dot_files/ai-dev/ai-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,21 @@ if [ -n "$HOME" ] && [ "$HOME" != "/root" ]; then
sed -i "s|root:x:0:0:[^:]*:/root:|root:x:0:0:root:$HOME:|" /etc/passwd 2>/dev/null || true
fi

# Symlink native install paths to where the installers expect them at runtime
# (installed under /home/linuxbrew at build time, but $HOME differs at runtime)
if [ -n "$HOME" ] && [ "$HOME" != "/home/linuxbrew" ]; then
mkdir -p "$HOME/.local/bin" "$HOME/.local/share"
ln -sf /home/linuxbrew/.local/bin/claude "$HOME/.local/bin/claude" 2>/dev/null || true
ln -sf /home/linuxbrew/.local/share/claude "$HOME/.local/share/claude" 2>/dev/null || true
ln -sf /home/linuxbrew/.local/bin/agy "$HOME/.local/bin/agy" 2>/dev/null || true
# Make sure TERM resolves inside the container. The host usually runs Ghostty
# (TERM=xterm-ghostty); that terminfo is baked into the image. If an unknown or
# empty TERM is propagated, fall back to a sane default so programs don't emit
# raw/awkward escape sequences.
if [ -z "${TERM:-}" ] || ! infocmp "$TERM" >/dev/null 2>&1; then
export TERM=xterm-256color
fi

# Note: claude/agy are installed under /home/linuxbrew/.local/bin at build time.
# They are resolved at runtime via PATH (set below), NOT via symlinks into $HOME.
# Symlinking into $HOME was unsafe: when the wrappers mount the current directory
# (-v "$(pwd):$(pwd):rw") and the tool is run from the host home directory, those
# symlinks were written straight through to the host, clobbering the real
# ~/.local/bin/claude and ~/.local/bin/agy wrapper scripts.

# Ensure claude auth files are readable within the container
chmod -R a+rX "$HOME/.claude" 2>/dev/null || true
chmod a+rw "$HOME/.claude.json" 2>/dev/null || true
Expand Down
1 change: 1 addition & 0 deletions dot_files/ai-dev/scripts/agy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ exec podman run --rm -it --init \
--user 0:0 \
--security-opt label=disable \
-e HOME="$HOME" \
-e TERM="${TERM:-}" \
$env_flags \
-v "$(pwd):$(pwd):rw" \
-v "$HOME/.gemini:$HOME/.gemini:rw" \
Expand Down
1 change: 1 addition & 0 deletions dot_files/ai-dev/scripts/claude.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ exec podman run --rm -it --init \
--user 0:0 \
--security-opt label=disable \
-e HOME="$HOME" \
-e TERM="${TERM:-}" \
-v "$(pwd):$(pwd):rw" \
-v "$HOME/.claude:$HOME/.claude:rw" \
-v "$HOME/.claude.json:$HOME/.claude.json:rw" \
Expand Down
1 change: 1 addition & 0 deletions dot_files/ai-dev/scripts/enter.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ exec podman run --rm -it --init \
--user 0:0 \
--security-opt label=disable \
-e HOME="$HOME" \
-e TERM="${TERM:-}" \
$env_flags \
-v "$(pwd):$(pwd):rw" \
-v "$HOME/.claude:$HOME/.claude:rw" \
Expand Down
25 changes: 24 additions & 1 deletion dot_files/nvim/Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,10 @@ USER root
WORKDIR /

# =============================================================================
# LAYER 11: Terminal compatibility
# LAYER 11: Terminal compatibility (xterm-ghostty terminfo)
# =============================================================================
# Install Ghostty's terminfo so TERM=xterm-ghostty resolves inside the
# container and TUIs (nvim, lazygit, ...) don't emit awkward escape sequences.
RUN curl -fsSL https://raw.githubusercontent.com/ghostty-org/ghostty/main/src/terminfo/ghostty.terminfo \
| tic -x -o /etc/terminfo -

Expand All @@ -202,6 +204,27 @@ RUN curl -fsSL https://raw.githubusercontent.com/ghostty-org/ghostty/main/src/te
# all tool directories are accessible
RUN chmod -R 777 /home/linuxbrew

# =============================================================================
# LAYER 13: TERM fallback safety net (xterm-ghostty)
# =============================================================================
# distrobox shares the host TERM (usually xterm-ghostty) and the terminfo is
# installed above. As a safety net, if an unknown or empty TERM ever reaches an
# interactive shell, fall back to xterm-256color so programs don't emit raw
# escape sequences. Covers POSIX shells and fish (distrobox uses the host shell).
RUN mkdir -p /etc/profile.d /etc/fish/conf.d \
&& printf '%s\n' \
'# Fall back to a known-good TERM if the current one has no terminfo entry.' \
'if [ -n "${TERM:-}" ] && ! infocmp "$TERM" >/dev/null 2>&1; then' \
' export TERM=xterm-256color' \
'fi' \
> /etc/profile.d/10-term-fallback.sh \
&& printf '%s\n' \
'# Fall back to a known-good TERM if the current one has no terminfo entry.' \
'if test -n "$TERM"; and not infocmp "$TERM" >/dev/null 2>&1' \
' set -gx TERM xterm-256color' \
'end' \
> /etc/fish/conf.d/10-term-fallback.fish

# Labels for GitHub Container Registry
LABEL org.opencontainers.image.source="https://github.com/binarypie/hypercube"
LABEL org.opencontainers.image.description="Neovim development environment with LSPs, formatters, and tools"
Expand Down
Loading