feat(toolbox): update toolbox configuration and scripts
- Update collab/TSYSDevStack-toolbox-prompt.md with latest guidelines - Update output/PROMPT with improved instructions for AI collaboration - Update output/toolbox-base/PROMPT with enhanced development guidelines - Update output/toolbox-base/README.md with current documentation - Update output/toolbox-base/build.sh with improved build process - Update output/toolbox-base/docker-compose.yml with refined service definitions - Update output/toolbox-base/run.sh with enhanced runtime configuration - Add output/toolbox-base/release.sh for release management processes These changes improve the developer workspace experience and ensure consistent tooling across the TSYSDevStack project.
This commit is contained in:
		| @@ -25,7 +25,7 @@ The TSYSDevStack consists of four categories: | |||||||
| - mise | - mise | ||||||
| - zsh / oh-my-zsh / completions / | - zsh / oh-my-zsh / completions / | ||||||
| -  | -  | ||||||
| - See `output/PROMPT` for shared toolbox contributor guidance, `output/toolbox-base/PROMPT` for the image-specific snapshot, and `output/NewToolbox.sh` for bootstrapping new toolboxes from the template (edit each toolbox's `SEED` once to set goals, then load its PROMPT when starting work). | - See `output/PROMPT` for shared toolbox contributor guidance, `output/toolbox-base/PROMPT` for the image-specific snapshot, and `output/NewToolbox.sh` for bootstrapping new toolboxes from the template (edit each toolbox's `SEED` once to set goals, then load its PROMPT when starting work). Toolbox images follow a `dev` → `release-current` → `vX.Y.Z` tagging scheme; use `build.sh` for local iteration and `release.sh <semver>` (clean tree) to promote builds (details in README). | ||||||
|  |  | ||||||
| ## toolbox-gis | ## toolbox-gis | ||||||
| ## toolbox-weather | ## toolbox-weather | ||||||
|   | |||||||
| @@ -6,6 +6,8 @@ Global toolbox guidance: | |||||||
| - Keep aqua/mise usage consistent across the family; prefer aqua-managed CLIs and mise-managed runtimes. | - Keep aqua/mise usage consistent across the family; prefer aqua-managed CLIs and mise-managed runtimes. | ||||||
| - Reference toolbox-template when bootstrapping a new toolbox. Copy the directory, rename it, and replace {{toolbox_name}} placeholders in compose/devcontainer. | - Reference toolbox-template when bootstrapping a new toolbox. Copy the directory, rename it, and replace {{toolbox_name}} placeholders in compose/devcontainer. | ||||||
| - Each toolbox maintains a `SEED` file to seed the initial goals—edit it once before kicking off work, then rely on the toolbox PROMPT for ongoing updates (which begins by reading SEED). | - Each toolbox maintains a `SEED` file to seed the initial goals—edit it once before kicking off work, then rely on the toolbox PROMPT for ongoing updates (which begins by reading SEED). | ||||||
|  | - Default build workflow: `./build.sh` produces a `:dev` tag; `./release.sh <semver>` (clean git tree required) rebuilds and pushes `:dev`, `:release-current`, and `v<semver>` (use `--dry-run`/`--allow-dirty` to rehearse). | ||||||
|  | - Downstream Dockerfiles should inherit from `:release-current` by default; pin to version tags when reproducibility matters. | ||||||
|  |  | ||||||
| Commit discipline: | Commit discipline: | ||||||
| - Craft atomic commits with clear intent; do not mix unrelated changes. | - Craft atomic commits with clear intent; do not mix unrelated changes. | ||||||
|   | |||||||
| @@ -12,14 +12,14 @@ Current state: | |||||||
| - mise handles language/tool runtimes; activation wired into zsh, bash, and fish. | - mise handles language/tool runtimes; activation wired into zsh, bash, and fish. | ||||||
| - docker-compose.yml runs container with host UID/GID, `sleep infinity`, and docker socket mount; run via run.sh/build.sh. Host directories `~/.local/share/mise` and `~/.cache/mise` are mounted for persistent runtimes. | - docker-compose.yml runs container with host UID/GID, `sleep infinity`, and docker socket mount; run via run.sh/build.sh. Host directories `~/.local/share/mise` and `~/.cache/mise` are mounted for persistent runtimes. | ||||||
| - Devcontainer config ( .devcontainer/devcontainer.json ) references the compose service. | - Devcontainer config ( .devcontainer/devcontainer.json ) references the compose service. | ||||||
| - Documentation: README.md (tooling inventory & workflow) and this PROMPT must stay current, and both should stay aligned with the shared guidance in ../PROMPT. README also notes that build.sh now uses docker buildx with a local cache directory. | - Documentation: README.md (tooling inventory & workflow) and this PROMPT must stay current, and both should stay aligned with the shared guidance in ../PROMPT. README also notes that build.sh now uses docker buildx with a local cache directory and documents the `dev` → `release-current` → semantic tagging workflow. | ||||||
|  |  | ||||||
| Collaboration guidelines: | Collaboration guidelines: | ||||||
| 1. Default to non-destructive operations; respect existing scripts run.sh/build.sh. | 1. Default to non-destructive operations; respect existing scripts run.sh/build.sh. | ||||||
| 2. Any tooling changes require updating README.md (inventory) and this prompt summary, rebuilding via ./build.sh, then committing (Conventional Commits, atomic diffs) and pushing after a successful build per ../PROMPT. | 2. Any tooling changes require updating README.md (inventory) and this prompt summary, rebuilding via `./build.sh` (local dev tag), then committing (Conventional Commits, atomic diffs) and pushing after a successful build per ../PROMPT. Use `./release.sh <semver>` (clean git tree required; `--dry-run`/`--allow-dirty` only for rehearsal) to promote to `release-current` + semantic tag. | ||||||
| 3. Keep configurations reproducible: prefer aqua/mise for new CLI/runtimes over apt unless prerequisites. | 3. Keep configurations reproducible: prefer aqua/mise for new CLI/runtimes over apt unless prerequisites. | ||||||
| 4. Mention verification steps (build/test) after changes. | 4. Mention verification steps (build/test) after changes and note which tag was built/pushed. | ||||||
| 5. Maintain UID/GID mapping and non-root execution. | 5. Downstream consumers should inherit from `:release-current` (or a pinned semantic tag); maintain UID/GID mapping and non-root execution. | ||||||
|  |  | ||||||
| Active focus: | Active focus: | ||||||
| - Extend toolbox-base as a "daily driver" dev container while preserving reproducibility and documentation. | - Extend toolbox-base as a "daily driver" dev container while preserving reproducibility and documentation. | ||||||
|   | |||||||
| @@ -6,16 +6,16 @@ Daily-driver development container for ToolboxStack work. It provides a reproduc | |||||||
|  |  | ||||||
| ## 🚀 Quick Start | ## 🚀 Quick Start | ||||||
|  |  | ||||||
| 1. **Build the image** | 1. **Build the image (local dev tag)** | ||||||
|    ```bash |    ```bash | ||||||
|    ./build.sh |    ./build.sh | ||||||
|    ``` |    ``` | ||||||
|    > Uses `docker buildx` with a local cache at `.build-cache/` for faster rebuilds. |    > Builds and tags the image as `tsysdevstack-toolboxstack-toolbox-base:dev`. Uses `docker buildx` with a local cache at `.build-cache/` for faster rebuilds. | ||||||
| 2. **Start the container** | 2. **Start the container** | ||||||
|    ```bash |    ```bash | ||||||
|    ./run.sh up |    ./run.sh up | ||||||
|    ``` |    ``` | ||||||
|    > Mise runtimes persist to your host in `~/.local/share/mise` and `~/.cache/mise` so language/tool downloads are shared across projects. |    > Defaults to the `release-current` tag; override with `TOOLBOX_IMAGE_OVERRIDE=...` when testing other tags. Mise runtimes persist to your host in `~/.local/share/mise` and `~/.cache/mise` so language/tool downloads are shared across projects. | ||||||
| 3. **Attach to a shell** | 3. **Attach to a shell** | ||||||
|    ```bash |    ```bash | ||||||
|    docker exec -it tsysdevstack-toolboxstack-toolbox-base zsh |    docker exec -it tsysdevstack-toolboxstack-toolbox-base zsh | ||||||
| @@ -30,6 +30,15 @@ The compose service mounts the current repo to `/workspace` (read/write) and run | |||||||
|  |  | ||||||
| --- | --- | ||||||
|  |  | ||||||
|  | ## 🏷️ Image Tagging & Releases | ||||||
|  |  | ||||||
|  | - `./build.sh` (no overrides) ⇒ builds `:dev` for active development. | ||||||
|  | - `./release.sh <semver>` ⇒ rebuilds, retags, and pushes `:dev`, `:release-current`, and `v<semver>` (e.g., `./release.sh 0.2.0`). Requires a clean git tree. | ||||||
|  | - Add `--dry-run` to rehearse the release without pushing (optionally `--allow-dirty` for experimentation only). | ||||||
|  | - Downstream Dockerfiles should inherit from `tsysdevstack-toolboxstack-toolbox-base:release-current` (or pin to a semantic tag for reproducibility). | ||||||
|  |  | ||||||
|  | --- | ||||||
|  |  | ||||||
| ## 🧩 Tooling Inventory | ## 🧩 Tooling Inventory | ||||||
|  |  | ||||||
| | Category | Tooling | Notes | | | Category | Tooling | Notes | | ||||||
|   | |||||||
| @@ -11,8 +11,13 @@ USERNAME="${USERNAME_OVERRIDE:-toolbox}" | |||||||
| TEA_VERSION="${TEA_VERSION_OVERRIDE:-0.11.1}" | TEA_VERSION="${TEA_VERSION_OVERRIDE:-0.11.1}" | ||||||
| BUILDER_NAME="${BUILDER_NAME:-tsysdevstack-toolboxstack-builder}" | BUILDER_NAME="${BUILDER_NAME:-tsysdevstack-toolboxstack-builder}" | ||||||
| CACHE_DIR="${SCRIPT_DIR}/.build-cache" | CACHE_DIR="${SCRIPT_DIR}/.build-cache" | ||||||
|  | TAG="${TAG_OVERRIDE:-dev}" | ||||||
|  | RELEASE_TAG="${RELEASE_TAG_OVERRIDE:-release-current}" | ||||||
|  | VERSION_TAG="${VERSION_TAG_OVERRIDE:-}" | ||||||
|  | PUSH="${PUSH_OVERRIDE:-false}" | ||||||
|  |  | ||||||
| echo "Building ${IMAGE_NAME} with UID=${USER_ID} GID=${GROUP_ID} USERNAME=${USERNAME}" | echo "Building ${IMAGE_NAME} with UID=${USER_ID} GID=${GROUP_ID} USERNAME=${USERNAME}" | ||||||
|  | echo "Primary tag: ${TAG}" | ||||||
|  |  | ||||||
| if ! docker buildx inspect "${BUILDER_NAME}" >/dev/null 2>&1; then | if ! docker buildx inspect "${BUILDER_NAME}" >/dev/null 2>&1; then | ||||||
|     docker buildx create --driver docker-container --name "${BUILDER_NAME}" --use >/dev/null |     docker buildx create --driver docker-container --name "${BUILDER_NAME}" --use >/dev/null | ||||||
| @@ -32,5 +37,22 @@ docker buildx build \ | |||||||
|     --build-arg TEA_VERSION="${TEA_VERSION}" \ |     --build-arg TEA_VERSION="${TEA_VERSION}" \ | ||||||
|     --cache-from "type=local,src=${CACHE_DIR}" \ |     --cache-from "type=local,src=${CACHE_DIR}" \ | ||||||
|     --cache-to "type=local,dest=${CACHE_DIR},mode=max" \ |     --cache-to "type=local,dest=${CACHE_DIR},mode=max" \ | ||||||
|     --tag "${IMAGE_NAME}" \ |     --tag "${IMAGE_NAME}:${TAG}" \ | ||||||
|     "${SCRIPT_DIR}" |     "${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 | ||||||
|  | fi | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| services: | services: | ||||||
|   toolbox-base: |   toolbox-base: | ||||||
|     container_name: tsysdevstack-toolboxstack-toolbox-base |     container_name: tsysdevstack-toolboxstack-toolbox-base | ||||||
|     image: tsysdevstack-toolboxstack-toolbox-base |     image: ${TOOLBOX_IMAGE:-tsysdevstack-toolboxstack-toolbox-base:release-current} | ||||||
|     build: |     build: | ||||||
|       context: . |       context: . | ||||||
|       args: |       args: | ||||||
|   | |||||||
							
								
								
									
										90
									
								
								ToolboxStack/output/toolbox-base/release.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										90
									
								
								ToolboxStack/output/toolbox-base/release.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,90 @@ | |||||||
|  | #!/usr/bin/env bash | ||||||
|  |  | ||||||
|  | set -euo pipefail | ||||||
|  |  | ||||||
|  | usage() { | ||||||
|  |     cat <<'EOU' | ||||||
|  | Usage: ./release.sh [--dry-run] [--allow-dirty] <semver> | ||||||
|  |  | ||||||
|  | Examples: | ||||||
|  |   ./release.sh 0.2.0 | ||||||
|  |   ./release.sh --dry-run 0.2.0 | ||||||
|  |  | ||||||
|  | This script rebuilds the toolbox-base image, tags it as: | ||||||
|  |   - tsysdevstack-toolboxstack-toolbox-base:dev | ||||||
|  |   - tsysdevstack-toolboxstack-toolbox-base:release-current | ||||||
|  |   - tsysdevstack-toolboxstack-toolbox-base:v<semver> | ||||||
|  |  | ||||||
|  | When run without --dry-run it pushes all three tags. | ||||||
|  | EOU | ||||||
|  | } | ||||||
|  |  | ||||||
|  | DRY_RUN=false | ||||||
|  | ALLOW_DIRTY=false | ||||||
|  | VERSION="" | ||||||
|  |  | ||||||
|  | while (( $# > 0 )); do | ||||||
|  |     case "$1" in | ||||||
|  |         --dry-run) | ||||||
|  |             DRY_RUN=true | ||||||
|  |             shift | ||||||
|  |             ;; | ||||||
|  |         --allow-dirty) | ||||||
|  |             ALLOW_DIRTY=true | ||||||
|  |             shift | ||||||
|  |             ;; | ||||||
|  |         -h|--help) | ||||||
|  |             usage | ||||||
|  |             exit 0 | ||||||
|  |             ;; | ||||||
|  |         -*) | ||||||
|  |             echo "Unknown option: $1" >&2 | ||||||
|  |             usage | ||||||
|  |             exit 1 | ||||||
|  |             ;; | ||||||
|  |         *) | ||||||
|  |             VERSION="$1" | ||||||
|  |             shift | ||||||
|  |             ;; | ||||||
|  |     esac | ||||||
|  | done | ||||||
|  |  | ||||||
|  | if [[ -z "${VERSION}" ]]; then | ||||||
|  |     echo "Error: semantic version is required." >&2 | ||||||
|  |     usage | ||||||
|  |     exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | if [[ "${VERSION}" =~ ^v?([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then | ||||||
|  |     SEMVER="v${BASH_REMATCH[1]}.${BASH_REMATCH[2]}.${BASH_REMATCH[3]}" | ||||||
|  | else | ||||||
|  |     echo "Error: version must be semantic (e.g., 0.2.0 or v0.2.0)." >&2 | ||||||
|  |     exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||||||
|  | REPO_ROOT="$(cd "${SCRIPT_DIR}" && git rev-parse --show-toplevel 2>/dev/null || true)" | ||||||
|  |  | ||||||
|  | if [[ -n "${REPO_ROOT}" && "${ALLOW_DIRTY}" != "true" ]]; then | ||||||
|  |     if ! git -C "${REPO_ROOT}" diff --quiet --ignore-submodules --exit-code; then | ||||||
|  |         echo "Error: git working tree has uncommitted changes. Please commit or stash before releasing." >&2 | ||||||
|  |         exit 1 | ||||||
|  |     fi | ||||||
|  | elif [[ -z "${REPO_ROOT}" ]]; then | ||||||
|  |     echo "Warning: unable to resolve git repository root; skipping clean tree check." >&2 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | echo "Preparing release for ${SEMVER}" | ||||||
|  | echo "  dry-run: ${DRY_RUN}" | ||||||
|  | echo "  allow-dirty: ${ALLOW_DIRTY}" | ||||||
|  |  | ||||||
|  | if [[ "${DRY_RUN}" == "true" ]]; then | ||||||
|  |     VERSION_TAG_OVERRIDE="${SEMVER}" PUSH_OVERRIDE=false "${SCRIPT_DIR}/build.sh" | ||||||
|  |     echo "[dry-run] Skipped pushing tags." | ||||||
|  | else | ||||||
|  |     VERSION_TAG_OVERRIDE="${SEMVER}" PUSH_OVERRIDE=true "${SCRIPT_DIR}/build.sh" | ||||||
|  |     echo "Release ${SEMVER} pushed as:" | ||||||
|  |     echo "  - tsysdevstack-toolboxstack-toolbox-base:dev" | ||||||
|  |     echo "  - tsysdevstack-toolboxstack-toolbox-base:release-current" | ||||||
|  |     echo "  - tsysdevstack-toolboxstack-toolbox-base:${SEMVER}" | ||||||
|  | fi | ||||||
| @@ -8,6 +8,7 @@ COMPOSE_FILE="${SCRIPT_DIR}/docker-compose.yml" | |||||||
| export LOCAL_UID="${USER_ID_OVERRIDE:-$(id -u)}" | export LOCAL_UID="${USER_ID_OVERRIDE:-$(id -u)}" | ||||||
| export LOCAL_GID="${GROUP_ID_OVERRIDE:-$(id -g)}" | export LOCAL_GID="${GROUP_ID_OVERRIDE:-$(id -g)}" | ||||||
| export LOCAL_USERNAME="${USERNAME_OVERRIDE:-toolbox}" | export LOCAL_USERNAME="${USERNAME_OVERRIDE:-toolbox}" | ||||||
|  | export TOOLBOX_IMAGE="${TOOLBOX_IMAGE_OVERRIDE:-tsysdevstack-toolboxstack-toolbox-base:release-current}" | ||||||
|  |  | ||||||
| if [[ ! -f "${COMPOSE_FILE}" ]]; then | if [[ ! -f "${COMPOSE_FILE}" ]]; then | ||||||
|     echo "Error: docker-compose.yml not found at ${COMPOSE_FILE}" >&2 |     echo "Error: docker-compose.yml not found at ${COMPOSE_FILE}" >&2 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user