diff --git a/README.md b/README.md index 261978a..72562c7 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ A collection of [Dev Container Features](https://containers.dev/implementors/fea - [Flutter SDK](#flutter-sdk) - [Claude Code](#claude-code) - [Tree-sitter](#tree-sitter) + - [RTK](#rtk) - [Repository Structure](#repository-structure) - [Local Testing](#local-testing) - [Contributing](#contributing) @@ -197,6 +198,47 @@ Pin a specific version with all grammars: Tree-sitter CLI is added to `PATH` automatically. Compiled grammars are stored under `$TREE_SITTER_DIR`. +### RTK + +Installs [RTK](https://www.rtk-ai.app/), a token-optimized CLI proxy for AI coding agents. Reduces token usage by 60-90% on dev operations by filtering and compressing tool output. + +```jsonc +// devcontainer.json +{ + "features": { + "ghcr.io/awf-project/devcontainer-features/rtk:1": {} + } +} +``` + +#### Options + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| `version` | string | `latest` | Version to install: `latest` or a specific version (e.g. `0.5.0`) | + +#### Examples + +Pin a specific version: + +```jsonc +{ + "features": { + "ghcr.io/awf-project/devcontainer-features/rtk:1": { + "version": "0.5.0" + } + } +} +``` + +#### Architecture Support + +RTK supports Linux containers on both `x86_64` (amd64) and `aarch64` (arm64) architectures. The feature automatically detects the container architecture and downloads the appropriate binary. + +#### Global Initialization + +The feature runs `rtk init --global` during installation, setting up the global configuration for the container user. + --- ## Repository Structure @@ -212,6 +254,9 @@ src/ grepai/ # GrepAI feature devcontainer-feature.json install.sh + rtk/ # RTK feature + devcontainer-feature.json + install.sh tree-sitter/ # Tree-sitter feature devcontainer-feature.json install.sh @@ -225,6 +270,9 @@ test/ grepai/ # GrepAI tests scenarios.json test.sh + rtk/ # RTK tests + scenarios.json + test.sh tree-sitter/ # Tree-sitter tests scenarios.json test.sh diff --git a/src/rtk/devcontainer-feature.json b/src/rtk/devcontainer-feature.json new file mode 100644 index 0000000..b13ee52 --- /dev/null +++ b/src/rtk/devcontainer-feature.json @@ -0,0 +1,18 @@ +{ + "id": "rtk", + "version": "1.0.0", + "name": "RTK", + "description": "Installs RTK, a token-optimized CLI proxy for AI coding agents. Reduces token usage by 60-90% on dev operations.", + "documentationURL": "https://www.rtk-ai.app/", + "licenseURL": "https://github.com/rtk-ai/rtk/blob/master/LICENSE", + "options": { + "version": { + "type": "string", + "default": "latest", + "description": "Version to install: 'latest' or a specific version (e.g. '0.5.0')" + } + }, + "installsAfter": [ + "ghcr.io/devcontainers/features/common-utils" + ] +} diff --git a/src/rtk/install.sh b/src/rtk/install.sh new file mode 100755 index 0000000..7b3cda4 --- /dev/null +++ b/src/rtk/install.sh @@ -0,0 +1,85 @@ +#!/bin/bash +set -e + +# --- Options injected by devcontainer feature engine --- +VERSION="${VERSION:-latest}" + +echo "==> RTK feature: version=${VERSION}" + +# Ensure curl and tar are available (minimal images may not have them) +if ! command -v curl &>/dev/null || ! command -v tar &>/dev/null; then + echo "==> Installing missing dependencies..." + apt-get update -y + apt-get install -y --no-install-recommends curl ca-certificates tar +fi + +# Detect architecture — build candidate target triples to try. +# v0.23.0+ ships musl for x86_64; older releases use gnu. +ARCH=$(uname -m) +case "$ARCH" in + x86_64|amd64) TARGETS=("x86_64-unknown-linux-musl" "x86_64-unknown-linux-gnu") ;; + aarch64|arm64) TARGETS=("aarch64-unknown-linux-gnu") ;; + *) + echo "ERROR: unsupported architecture: $ARCH" + exit 1 + ;; +esac +echo "==> Detected architecture: ${ARCH}" + +# Resolve version +if [ "$VERSION" = "latest" ]; then + VERSION=$(curl -fsSL "https://api.github.com/repos/rtk-ai/rtk/releases/latest" \ + | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/') + if [ -z "$VERSION" ]; then + echo "ERROR: failed to resolve latest RTK version from GitHub API" + exit 1 + fi + echo "==> Resolved latest version: ${VERSION}" +fi + +# Ensure version has 'v' prefix (GitHub tags use v0.23.0 format) +case "$VERSION" in + v*) ;; + *) VERSION="v${VERSION}" ;; +esac + +# Download and install — try each target triple until one succeeds +TMP_DIR=$(mktemp -d) +trap 'rm -rf "$TMP_DIR"' EXIT + +DOWNLOADED=false +for TARGET in "${TARGETS[@]}"; do + TARBALL="rtk-${TARGET}.tar.gz" + DOWNLOAD_URL="https://github.com/rtk-ai/rtk/releases/download/${VERSION}/${TARBALL}" + echo "==> Trying ${DOWNLOAD_URL}..." + if curl -fsSL "$DOWNLOAD_URL" -o "${TMP_DIR}/${TARBALL}" 2>/dev/null; then + DOWNLOADED=true + break + fi +done + +if [ "$DOWNLOADED" = false ]; then + echo "ERROR: no compatible RTK binary found for ${ARCH} in release ${VERSION}" + exit 1 +fi + +tar -xzf "${TMP_DIR}/${TARBALL}" -C "$TMP_DIR" + +# The tarball contains a single 'rtk' binary at the root +if [ ! -f "${TMP_DIR}/rtk" ]; then + echo "ERROR: rtk binary not found in archive" + exit 1 +fi +install -m 0755 "${TMP_DIR}/rtk" /usr/local/bin/rtk + +echo "==> RTK $(rtk --version) installed at $(command -v rtk)" + +# Initialize RTK global configuration +echo "==> Running rtk init --global..." +if [ -n "${_REMOTE_USER:-}" ] && [ "$_REMOTE_USER" != "root" ]; then + su - "$_REMOTE_USER" -c "rtk init --global" +else + rtk init --global +fi + +echo "==> RTK feature install complete" diff --git a/test/rtk/install_rtk_specific_version.sh b/test/rtk/install_rtk_specific_version.sh new file mode 100755 index 0000000..4816a47 --- /dev/null +++ b/test/rtk/install_rtk_specific_version.sh @@ -0,0 +1,23 @@ +#!/bin/bash +set -e + +# Scenario: install a specific RTK version (0.23.0) + +echo "==> Testing RTK specific version scenario..." + +# rtk binary must be on PATH +if ! command -v rtk &>/dev/null; then + echo "FAIL: rtk not found on PATH" + exit 1 +fi +echo "PASS: rtk on PATH ($(command -v rtk))" + +# Verify the exact version matches +RTK_VERSION=$(rtk --version 2>&1) +if [[ "$RTK_VERSION" != *"0.22.2"* ]]; then + echo "FAIL: expected version 0.22.2, got: ${RTK_VERSION}" + exit 1 +fi +echo "PASS: rtk version matches 0.22.2 => ${RTK_VERSION}" + +echo "==> RTK specific version tests passed" diff --git a/test/rtk/scenarios.json b/test/rtk/scenarios.json new file mode 100644 index 0000000..6092b6b --- /dev/null +++ b/test/rtk/scenarios.json @@ -0,0 +1,10 @@ +{ + "install_rtk_specific_version": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "rtk": { + "version": "0.22.2" + } + } + } +} \ No newline at end of file diff --git a/test/rtk/test.sh b/test/rtk/test.sh new file mode 100755 index 0000000..f172fe7 --- /dev/null +++ b/test/rtk/test.sh @@ -0,0 +1,24 @@ +#!/bin/bash +set -e + +# Devcontainer feature test — run by devcontainers/action in CI +# Verifies RTK CLI is correctly installed and on PATH. + +echo "==> Testing RTK feature..." + +# rtk binary must be on PATH +if ! command -v rtk &>/dev/null; then + echo "FAIL: rtk not found on PATH" + exit 1 +fi +echo "PASS: rtk on PATH ($(command -v rtk))" + +# rtk --version must succeed and return a version string +RTK_VERSION=$(rtk --version 2>&1) +if [ -z "$RTK_VERSION" ]; then + echo "FAIL: rtk --version returned empty output" + exit 1 +fi +echo "PASS: rtk --version => ${RTK_VERSION}" + +echo "==> All RTK feature tests passed"