Compare commits
2 Commits
073cb91585
...
96d3178344
| Author | SHA1 | Date | |
|---|---|---|---|
| 96d3178344 | |||
| 08d10b16cf |
@@ -7,6 +7,7 @@ ARG TEA_VERSION=0.11.1
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Install base packages with proper caching
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/var/lib/apt/lists,sharing=locked \
|
||||
apt-get update \
|
||||
@@ -38,6 +39,16 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
libreadline-dev \
|
||||
wget \
|
||||
zsh \
|
||||
# Additional packages for better tool support
|
||||
unzip \
|
||||
zip \
|
||||
gnupg \
|
||||
software-properties-common \
|
||||
apt-transport-https \
|
||||
ca-certificates \
|
||||
curl \
|
||||
gnupg-agent \
|
||||
software-properties-common \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
@@ -119,6 +130,16 @@ RUN su - "${USERNAME}" -c 'mise exec -- npm install -g @just-every/code@0.4.6 @q
|
||||
# Ensure mise shims are properly generated for the installed tools
|
||||
su - "${USERNAME}" -c 'mise reshim'
|
||||
|
||||
# Install BATS for testing framework
|
||||
RUN git clone https://github.com/bats-core/bats-core.git /tmp/bats-core \
|
||||
&& cd /tmp/bats-core \
|
||||
&& git checkout v1.11.0 \
|
||||
&& ./install.sh /usr/local \
|
||||
&& rm -rf /tmp/bats-core
|
||||
|
||||
# Install additional testing tools
|
||||
RUN npm install -g bats@1.11.0
|
||||
|
||||
# Prepare workspace directory with appropriate ownership
|
||||
RUN mkdir -p /workspace \
|
||||
&& chown "${USER_ID}:${GROUP_ID}" /workspace
|
||||
|
||||
@@ -3,18 +3,37 @@ registries:
|
||||
- type: standard
|
||||
ref: v4.431.0
|
||||
packages:
|
||||
# GitHub CLI and related tools
|
||||
- name: cli/cli@v2.82.1
|
||||
- name: jesseduffield/lazygit@v0.55.1
|
||||
|
||||
# Environment and runtime management
|
||||
- name: direnv/direnv@v2.37.1
|
||||
- name: dandavison/delta@0.18.2
|
||||
- name: ajeetdsouza/zoxide@v0.9.8
|
||||
|
||||
# Development and build tools
|
||||
- name: casey/just@1.43.0
|
||||
- name: mikefarah/yq@v4.48.1
|
||||
- name: ducaale/xh@v0.25.0
|
||||
- name: rs/curlie@v1.8.2
|
||||
|
||||
# Configuration management
|
||||
- name: twpayne/chezmoi@v2.66.1
|
||||
|
||||
# Shell scripting tools
|
||||
- name: mvdan/sh@v3.12.0
|
||||
- name: koalaman/shellcheck@v0.11.0
|
||||
- name: mvdan/shfmt@v3.12.0
|
||||
|
||||
# Container and Docker tools
|
||||
- name: hadolint/hadolint@v2.14.0
|
||||
|
||||
# Python package management
|
||||
- name: astral-sh/uv@0.9.6
|
||||
|
||||
# File watching and automation
|
||||
- name: watchexec/watchexec@v2.3.2
|
||||
|
||||
# Diagram generation
|
||||
- name: yuzutech/kroki-cli@0.10.0
|
||||
|
||||
@@ -53,18 +53,33 @@ PUSH="${PUSH_OVERRIDE:-false}"
|
||||
echo "Building ${IMAGE_NAME} with UID=${USER_ID} GID=${GROUP_ID} USERNAME=${USERNAME}"
|
||||
echo "Primary tag: ${TAG}"
|
||||
|
||||
# Ensure builder exists
|
||||
if ! docker buildx inspect "${BUILDER_NAME}" >/dev/null 2>&1; then
|
||||
echo "Creating builder: ${BUILDER_NAME}"
|
||||
docker buildx create --driver docker-container --name "${BUILDER_NAME}" --use >/dev/null
|
||||
if ! docker buildx create --driver docker-container --name "${BUILDER_NAME}" --use >/dev/null; then
|
||||
echo "Error: Failed to create Docker buildx builder." >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "Using existing builder: ${BUILDER_NAME}"
|
||||
docker buildx use "${BUILDER_NAME}" >/dev/null
|
||||
if ! docker buildx use "${BUILDER_NAME}" >/dev/null; then
|
||||
echo "Error: Failed to use Docker buildx builder." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
mkdir -p "${CACHE_DIR}"
|
||||
# Ensure cache directory exists
|
||||
if ! mkdir -p "${CACHE_DIR}"; then
|
||||
echo "Error: Failed to create cache directory: ${CACHE_DIR}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Starting build..."
|
||||
docker buildx build \
|
||||
BUILD_OUTPUT=$(mktemp)
|
||||
trap 'rm -f "$BUILD_OUTPUT"' EXIT
|
||||
|
||||
# Build the image
|
||||
if ! docker buildx build \
|
||||
--builder "${BUILDER_NAME}" \
|
||||
--load \
|
||||
--progress=plain \
|
||||
@@ -75,27 +90,98 @@ docker buildx build \
|
||||
--cache-from "type=local,src=${CACHE_DIR}" \
|
||||
--cache-to "type=local,dest=${CACHE_DIR},mode=max" \
|
||||
--tag "${IMAGE_NAME}:${TAG}" \
|
||||
"${SCRIPT_DIR}"
|
||||
|
||||
if [[ "${PUSH}" == "true" ]]; then
|
||||
echo "Pushing ${IMAGE_NAME}:${TAG}"
|
||||
docker push "${IMAGE_NAME}:${TAG}"
|
||||
|
||||
if [[ "${TAG}" == "dev" && -n "${VERSION_TAG}" ]]; then
|
||||
docker tag "${IMAGE_NAME}:${TAG}" "${IMAGE_NAME}:${VERSION_TAG}"
|
||||
echo "Pushing ${IMAGE_NAME}:${VERSION_TAG}"
|
||||
docker push "${IMAGE_NAME}:${VERSION_TAG}"
|
||||
fi
|
||||
|
||||
if [[ "${TAG}" == "dev" ]]; then
|
||||
docker tag "${IMAGE_NAME}:${TAG}" "${IMAGE_NAME}:${RELEASE_TAG}"
|
||||
echo "Pushing ${IMAGE_NAME}:${RELEASE_TAG}"
|
||||
docker push "${IMAGE_NAME}:${RELEASE_TAG}"
|
||||
fi
|
||||
"${SCRIPT_DIR}" 2>&1 | tee "${BUILD_OUTPUT}"; then
|
||||
echo "Error: Docker build failed. Check output above for details." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Build completed successfully."
|
||||
|
||||
# Run post-build verification
|
||||
echo "Running post-build verification..."
|
||||
if ! docker run --rm "${IMAGE_NAME}:${TAG}" zsh -c 'echo "Container starts successfully"'; then
|
||||
echo "Error: Failed to start container with basic test." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify critical tools are available
|
||||
echo "Verifying critical tools..."
|
||||
CRITICAL_TOOLS=("zsh" "git" "curl" "jq" "fish" "fzf" "bat" "fd" "rg" "htop" "btop")
|
||||
for tool in "${CRITICAL_TOOLS[@]}"; do
|
||||
if ! docker run --rm "${IMAGE_NAME}:${TAG}" which "$tool" >/dev/null 2>&1; then
|
||||
echo "Error: Critical tool '$tool' not found in PATH." >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Verify aqua tools are available
|
||||
echo "Verifying aqua tools..."
|
||||
AQUA_TOOLS=("gh" "lazygit" "direnv" "delta" "zoxide" "just" "yq" "xh" "curlie" "chezmoi" "shfmt" "shellcheck" "hadolint" "uv" "uvx" "watchexec" "kroki")
|
||||
for tool in "${AQUA_TOOLS[@]}"; do
|
||||
if ! docker run --rm "${IMAGE_NAME}:${TAG}" which "$tool" >/dev/null 2>&1; then
|
||||
echo "Warning: Aqua tool '$tool' not found in PATH. Installing..." >&2
|
||||
# Try to install the missing tool
|
||||
if ! docker run --rm "${IMAGE_NAME}:${TAG}" zsh -c "aqua install $tool" >/dev/null 2>&1; then
|
||||
echo "Error: Failed to install aqua tool '$tool'." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Verify AI CLI tools are available
|
||||
echo "Verifying AI CLI tools..."
|
||||
AI_TOOLS=("code" "qwen" "gemini" "codex" "opencode")
|
||||
for tool in "${AI_TOOLS[@]}"; do
|
||||
if ! docker run --rm "${IMAGE_NAME}:${TAG}" which "$tool" >/dev/null 2>&1; then
|
||||
echo "Warning: AI CLI tool '$tool' not found in PATH." >&2
|
||||
# These might need node/mise setup, so we'll just warn
|
||||
fi
|
||||
done
|
||||
|
||||
# Verify testing tools are available
|
||||
echo "Verifying testing tools..."
|
||||
TESTING_TOOLS=("bats" "shellcheck" "shfmt" "hadolint")
|
||||
for tool in "${TESTING_TOOLS[@]}"; do
|
||||
if ! docker run --rm "${IMAGE_NAME}:${TAG}" which "$tool" >/dev/null 2>&1; then
|
||||
echo "Error: Testing tool '$tool' not found in PATH." >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
echo "All verifications passed."
|
||||
|
||||
if [[ "${PUSH}" == "true" ]]; then
|
||||
echo "Pushing ${IMAGE_NAME}:${TAG}"
|
||||
if ! docker push "${IMAGE_NAME}:${TAG}"; then
|
||||
echo "Error: Failed to push ${IMAGE_NAME}:${TAG}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${TAG}" == "dev" && -n "${VERSION_TAG}" ]]; then
|
||||
if ! docker tag "${IMAGE_NAME}:${TAG}" "${IMAGE_NAME}:${VERSION_TAG}"; then
|
||||
echo "Error: Failed to tag ${IMAGE_NAME}:${VERSION_TAG}" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Pushing ${IMAGE_NAME}:${VERSION_TAG}"
|
||||
if ! docker push "${IMAGE_NAME}:${VERSION_TAG}"; then
|
||||
echo "Error: Failed to push ${IMAGE_NAME}:${VERSION_TAG}" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${TAG}" == "dev" ]]; then
|
||||
if ! docker tag "${IMAGE_NAME}:${TAG}" "${IMAGE_NAME}:${RELEASE_TAG}"; then
|
||||
echo "Error: Failed to tag ${IMAGE_NAME}:${RELEASE_TAG}" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Pushing ${IMAGE_NAME}:${RELEASE_TAG}"
|
||||
if ! docker push "${IMAGE_NAME}:${RELEASE_TAG}"; then
|
||||
echo "Error: Failed to push ${IMAGE_NAME}:${RELEASE_TAG}" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Run security scan if TRIVY is available
|
||||
if command -v trivy &> /dev/null; then
|
||||
echo "Running security scan with Trivy..."
|
||||
@@ -103,3 +189,5 @@ if command -v trivy &> /dev/null; then
|
||||
else
|
||||
echo "Trivy not found. Install Trivy to perform security scanning."
|
||||
fi
|
||||
|
||||
echo "Build process completed successfully with all verifications."
|
||||
|
||||
@@ -29,3 +29,17 @@ services:
|
||||
- ${HOME}/.cache/qwen:/home/toolbox/.cache/qwen:rw
|
||||
- ${HOME}/.cache/code:/home/toolbox/.cache/code:rw
|
||||
- ${HOME}/.cache/opencode:/home/toolbox/.cache/opencode:rw
|
||||
# Additional AI tool directories
|
||||
- ${HOME}/.config/codex:/home/toolbox/.config/codex:rw
|
||||
- ${HOME}/.cache/codex:/home/toolbox/.cache/codex:rw
|
||||
# AI CLI tool configuration and cache directories
|
||||
- ${HOME}/.config/openai:/home/toolbox/.config/openai:rw
|
||||
- ${HOME}/.config/gemini:/home/toolbox/.config/gemini:rw
|
||||
- ${HOME}/.config/qwen:/home/toolbox/.config/qwen:rw
|
||||
- ${HOME}/.config/code:/home/toolbox/.config/code:rw
|
||||
- ${HOME}/.config/opencode:/home/toolbox/.config/opencode:rw
|
||||
- ${HOME}/.cache/openai:/home/toolbox/.cache/openai:rw
|
||||
- ${HOME}/.cache/gemini:/home/toolbox/.cache/gemini:rw
|
||||
- ${HOME}/.cache/qwen:/home/toolbox/.cache/qwen:rw
|
||||
- ${HOME}/.cache/code:/home/toolbox/.cache/code:rw
|
||||
- ${HOME}/.cache/opencode:/home/toolbox/.cache/opencode:rw
|
||||
|
||||
112
ToolboxStack/output/toolbox-base/test.sh
Normal file
112
ToolboxStack/output/toolbox-base/test.sh
Normal file
@@ -0,0 +1,112 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Test script to verify all tools are working properly in the toolbox-base image
|
||||
|
||||
IMAGE_NAME="${IMAGE_NAME_OVERRIDE:-tsysdevstack-toolboxstack-toolbox-base:release-current}"
|
||||
|
||||
echo "🧪 Testing all tools in ${IMAGE_NAME}"
|
||||
|
||||
# Function to test a command
|
||||
test_cmd() {
|
||||
local cmd="$1"
|
||||
local description="$2"
|
||||
|
||||
echo -n "Testing ${cmd} (${description})... "
|
||||
|
||||
if docker run --rm "${IMAGE_NAME}" "${cmd}" --version >/dev/null 2>&1; then
|
||||
echo "✅ PASS"
|
||||
return 0
|
||||
else
|
||||
echo "❌ FAIL"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to test a command with specific args
|
||||
test_cmd_args() {
|
||||
local cmd="$1"
|
||||
local args="$2"
|
||||
local description="$3"
|
||||
|
||||
echo -n "Testing ${cmd} ${args} (${description})... "
|
||||
|
||||
if docker run --rm "${IMAGE_NAME}" "${cmd}" ${args} >/dev/null 2>&1; then
|
||||
echo "✅ PASS"
|
||||
return 0
|
||||
else
|
||||
echo "❌ FAIL"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Counter for tracking results
|
||||
PASSED=0
|
||||
FAILED=0
|
||||
|
||||
# Test core tools
|
||||
echo "🔍 Testing core tools..."
|
||||
|
||||
test_cmd "zsh" "Z shell" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "git" "Git version control" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "curl" "cURL utility" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "jq" "JSON processor" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "fish" "Fish shell" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "fzf" "Fuzzy finder" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "bat" "Cat clone with wings" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "fd" "Simple, fast alternative to find" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "rg" "Ripgrep - line-oriented search tool" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "htop" "Interactive process viewer" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "btop" "Modern and colorful terminal monitor" && ((PASSED++)) || ((FAILED++))
|
||||
|
||||
# Test aqua installed tools
|
||||
echo "🔧 Testing aqua installed tools..."
|
||||
|
||||
test_cmd "gh" "GitHub CLI" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "lazygit" "Simple terminal UI for git commands" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "direnv" "Unclutter your .profile" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "delta" "Syntax-highlighting pager for git, diff, and grep output" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "zoxide" "Smarter cd command" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "just" "Just a command runner" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "yq" "Portable command-line YAML processor" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "xh" "Friendly and fast tool for sending HTTP requests" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "curlie" "The power of curl, the ease of use of httpie" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "chezmoi" "Manage your dotfiles across multiple machines" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "shfmt" "Shell formatter" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "shellcheck" "Shell script analysis tool" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "hadolint" "Dockerfile linter" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "uv" "Python package installer and resolver" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "watchexec" "Execute commands in response to file modifications" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "tea" "Gitea CLI" && ((PASSED++)) || ((FAILED++))
|
||||
|
||||
# Test AI CLI tools
|
||||
echo "🤖 Testing AI CLI tools..."
|
||||
|
||||
test_cmd_args "code" "--version" "just-every/code AI CLI" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd_args "qwen" "--version" "QwenLM/qwen-code AI CLI" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd_args "gemini" "--version" "google-gemini/gemini-cli AI CLI" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd_args "codex" "--version" "openai/codex AI CLI" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd_args "opencode" "--version" "sst/opencode AI CLI" && ((PASSED++)) || ((FAILED++))
|
||||
|
||||
# Test additional tools
|
||||
echo "🧰 Testing additional tools..."
|
||||
|
||||
test_cmd "starship" "Cross-shell prompt" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd "mise" "Polyglot runtime manager" && ((PASSED++)) || ((FAILED++))
|
||||
test_cmd_args "aqua" "--version" "Declarative CLI Version Manager" && ((PASSED++)) || ((FAILED++))
|
||||
|
||||
# Summary
|
||||
echo ""
|
||||
echo "📊 Test Results:"
|
||||
echo " Passed: ${PASSED}"
|
||||
echo " Failed: ${FAILED}"
|
||||
echo " Total: $((PASSED + FAILED))"
|
||||
|
||||
if [[ "${FAILED}" -eq 0 ]]; then
|
||||
echo "🎉 All tests passed!"
|
||||
exit 0
|
||||
else
|
||||
echo "💥 ${FAILED} tests failed!"
|
||||
exit 1
|
||||
fi
|
||||
@@ -11,4 +11,4 @@
|
||||
],
|
||||
"overrideCommand": false,
|
||||
"postCreateCommand": "zsh -lc 'starship --version >/dev/null'"
|
||||
}
|
||||
}
|
||||
@@ -5,14 +5,14 @@ You are Codex, collaborating with a human on the TSYSDevStack ToolboxStack proje
|
||||
- Start each session by reading it (`cat SEED`) and summarize progress or adjustments here in PROMPT.
|
||||
|
||||
Context snapshot ({{toolbox_name}}):
|
||||
- Working directory: TSYSDevStack/ToolboxStack/{{toolbox_name}}
|
||||
- Image: extends from tsysdevstack-toolboxstack-toolbox-base (Ubuntu 24.04 base)
|
||||
- Working directory: artifacts/ToolboxStack/{{toolbox_name}}
|
||||
- Image: tsysdevstack-toolboxstack-{{toolbox_name}} (extends from tsysdevstack-toolboxstack-toolbox-base:release-current)
|
||||
- Container user: toolbox (non-root, UID/GID mapped to host)
|
||||
- Mounted workspace: current repo at /workspace (rw)
|
||||
|
||||
Current state:
|
||||
- Extends from the standard toolbox-base image, inheriting shell tooling (zsh/bash/fish with Starship & oh-my-zsh), core CLI utilities, aqua, and mise.
|
||||
- aqua packages are baked into the base image during the build process for consistency and reproducibility.
|
||||
- Extends from the standard toolbox-base image, inheriting all base tooling (shells, CLIs, package managers).
|
||||
- aqua packages are baked into the base image during the build process for consistency, reproducibility and performance.
|
||||
- AI CLI tools from the base are available, with host directories mounted for configuration persistence.
|
||||
- See ../PROMPT for shared toolbox contribution expectations (documentation sync, build cadence, commit/push discipline, Conventional Commits, atomic history).
|
||||
|
||||
@@ -24,4 +24,4 @@ Collaboration checklist:
|
||||
5. Maintain UID/GID mapping and non-root execution.
|
||||
|
||||
Active focus:
|
||||
- Initialize {{toolbox_name}} using the toolbox-template scaffolding; evolve the Dockerfile/tooling inventory to satisfy the SEED goals while maintaining consistency with the base image.
|
||||
- Initialize {{toolbox_name}} using the toolbox-template scaffolding; evolve the Dockerfile/tooling inventory to satisfy the SEED goals.
|
||||
107
ToolboxStack/output/toolbox-template/README.md
Normal file
107
ToolboxStack/output/toolbox-template/README.md
Normal file
@@ -0,0 +1,107 @@
|
||||
# 🧰 TSYSDevStack Toolbox Template
|
||||
|
||||
Template for creating new toolboxes that extend from the `toolbox-base` image.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
1. **Create a new toolbox**
|
||||
```bash
|
||||
cp -r /path/to/toolbox-template /path/to/new-toolbox
|
||||
cd /path/to/new-toolbox
|
||||
```
|
||||
|
||||
2. **Customize the toolbox**
|
||||
- Edit `Dockerfile` to add toolbox-specific tooling
|
||||
- Modify `docker-compose.yml` to adjust service configuration
|
||||
- Update `SEED` to define the toolbox's purpose and goals
|
||||
|
||||
3. **Build the toolbox**
|
||||
```bash
|
||||
./build.sh
|
||||
```
|
||||
|
||||
4. **Start the toolbox**
|
||||
```bash
|
||||
./run.sh up
|
||||
```
|
||||
|
||||
5. **Access the toolbox**
|
||||
```bash
|
||||
docker exec -it tsysdevstack-toolboxstack-<toolbox-name> zsh
|
||||
```
|
||||
|
||||
6. **Stop the toolbox**
|
||||
```bash
|
||||
./run.sh down
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧱 Architecture
|
||||
|
||||
- **Base Image**: Extends from `tsysdevstack-toolboxstack-toolbox-base:release-current`
|
||||
- **User**: Runs as non-root `toolbox` user (UID/GID mapped to host)
|
||||
- **Workspace**: Mounts current directory to `/workspace` (read/write)
|
||||
- **Runtime**: Inherits all tooling from base plus toolbox-specific additions
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Customization
|
||||
|
||||
### Dockerfile
|
||||
Extend the base image with toolbox-specific tooling:
|
||||
```dockerfile
|
||||
# Extend from the toolbox-base image
|
||||
FROM tsysdevstack-toolboxstack-toolbox-base:release-current
|
||||
|
||||
# Add toolbox-specific packages or configurations
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
specific-package \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
```
|
||||
|
||||
### docker-compose.yml
|
||||
Adjust service configuration for toolbox-specific needs:
|
||||
```yaml
|
||||
services:
|
||||
my-toolbox:
|
||||
# Inherits all base configuration
|
||||
# Add toolbox-specific volumes, ports, etc.
|
||||
volumes:
|
||||
- ./custom-config:/home/toolbox/.config/custom-tool
|
||||
```
|
||||
|
||||
### SEED
|
||||
Define the toolbox's purpose and goals:
|
||||
```markdown
|
||||
- Describe what this toolbox should provide (languages, CLIs, workflows)
|
||||
- List required base image modifications or additional mounts
|
||||
- Note verification or testing expectations specific to this toolbox
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📂 Project Layout
|
||||
|
||||
| Path | Purpose |
|
||||
|------|---------|
|
||||
| `Dockerfile` | Extends base image with toolbox-specific tooling |
|
||||
| `docker-compose.yml` | Service configuration for the toolbox |
|
||||
| `build.sh` | Wrapper around `docker build` with host UID/GID mapping |
|
||||
| `run.sh` | Helper to bring the service up/down |
|
||||
| `.devcontainer/devcontainer.json` | VS Code remote container definition |
|
||||
| `SEED` | Defines the toolbox's purpose and goals |
|
||||
| `PROMPT` | LLM onboarding prompt for future contributors |
|
||||
|
||||
---
|
||||
|
||||
## 🤝 Collaboration Notes
|
||||
|
||||
- Inherits all collaboration policies from `toolbox-base`
|
||||
- Document toolbox-specific additions in `README.md` and `PROMPT`
|
||||
- Update `SEED` only when the high-level objectives change
|
||||
- Prefer aqua/mise for new tooling to keep installations reproducible
|
||||
- Keep documentation synchronized for future contributors
|
||||
@@ -1,6 +1,38 @@
|
||||
- This toolbox extends from the standard toolbox-base image, inheriting all base tooling (shells, CLIs, package managers).
|
||||
- Add {{toolbox_name}}-specific tools via aqua.yaml, Dockerfile, or mise configurations.
|
||||
- Document any additional host directory mounts needed in docker-compose.yml.
|
||||
- Ensure all tooling is compatible with the non-root toolbox user and UID/GID mapping.
|
||||
- Update README.md to document {{toolbox_name}}-specific features and tooling.
|
||||
- Follow the same build and run patterns as the base image for consistency.
|
||||
# Toolbox Template SEED
|
||||
|
||||
This SEED file defines the high-level objectives for all toolboxes created from this template.
|
||||
|
||||
## 🎯 Goals
|
||||
|
||||
- **Extensibility**: Each toolbox should extend from `toolbox-base` to inherit core tooling
|
||||
- **Consistency**: All toolboxes should follow the same patterns and conventions
|
||||
- **Reproducibility**: Toolbox builds should be deterministic and cache-efficient
|
||||
- **Security**: Toolboxes should run as non-root users with minimal privileges
|
||||
- **Portability**: Toolboxes should work identically across different host environments
|
||||
|
||||
## 🧰 Requirements
|
||||
|
||||
- **Base Image**: Extend from `tsysdevstack-toolboxstack-toolbox-base:release-current`
|
||||
- **User Model**: Run as non-root `toolbox` user (UID/GID mapped to host)
|
||||
- **Workspace**: Mount current directory to `/workspace` (read/write)
|
||||
- **Runtime**: Inherit all base tooling plus toolbox-specific additions
|
||||
- **Configuration**: Preserve user configs/mise toolchains via volume mounts
|
||||
|
||||
## 🛠️ Implementation
|
||||
|
||||
- **Dockerfile**: Extend from base with toolbox-specific tooling
|
||||
- **docker-compose.yml**: Configure service with inherited + custom settings
|
||||
- **build.sh**: Wrapper around `docker build` with UID/GID mapping
|
||||
- **run.sh**: Helper to bring service up/down with proper directory setup
|
||||
- **devcontainer.json**: VS Code remote container definition
|
||||
- **SEED**: Define toolbox-specific objectives (this file)
|
||||
- **PROMPT**: LLM onboarding prompt for future contributors
|
||||
|
||||
## ✅ Verification
|
||||
|
||||
- Toolboxes should build without errors
|
||||
- Toolboxes should start and run indefinitely
|
||||
- Toolboxes should be accessible via `docker exec`
|
||||
- Toolboxes should inherit all base tooling
|
||||
- Toolboxes should support toolbox-specific additions
|
||||
- Toolboxes should preserve user configurations across restarts
|
||||
@@ -4,6 +4,7 @@ services:
|
||||
image: tsysdevstack-toolboxstack-{{toolbox_name}}
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
USER_ID: ${LOCAL_UID:-1000}
|
||||
GROUP_ID: ${LOCAL_GID:-1000}
|
||||
@@ -29,3 +30,17 @@ services:
|
||||
- ${HOME}/.cache/qwen:/home/toolbox/.cache/qwen:rw
|
||||
- ${HOME}/.cache/code:/home/toolbox/.cache/code:rw
|
||||
- ${HOME}/.cache/opencode:/home/toolbox/.cache/opencode:rw
|
||||
# Additional AI tool directories
|
||||
- ${HOME}/.config/codex:/home/toolbox/.config/codex:rw
|
||||
- ${HOME}/.cache/codex:/home/toolbox/.cache/codex:rw
|
||||
# AI CLI tool configuration and cache directories
|
||||
- ${HOME}/.config/openai:/home/toolbox/.config/openai:rw
|
||||
- ${HOME}/.config/gemini:/home/toolbox/.config/gemini:rw
|
||||
- ${HOME}/.config/qwen:/home/toolbox/.config/qwen:rw
|
||||
- ${HOME}/.config/code:/home/toolbox/.config/code:rw
|
||||
- ${HOME}/.config/opencode:/home/toolbox/.config/opencode:rw
|
||||
- ${HOME}/.cache/openai:/home/toolbox/.cache/openai:rw
|
||||
- ${HOME}/.cache/gemini:/home/toolbox/.cache/gemini:rw
|
||||
- ${HOME}/.cache/qwen:/home/toolbox/.cache/qwen:rw
|
||||
- ${HOME}/.cache/code:/home/toolbox/.cache/code:rw
|
||||
- ${HOME}/.cache/opencode:/home/toolbox/.cache/opencode:rw
|
||||
|
||||
Reference in New Issue
Block a user