From f984f5f062852e6f66fb439469231c6ce92c9c39 Mon Sep 17 00:00:00 2001 From: Eric Coissac Date: Sat, 21 Feb 2026 16:34:17 +0100 Subject: [PATCH] Update devcontainer and Docker setup with new LLM API configuration Update devcontainer.json to set terminal shell and add empty features object Update docker-compose.yml to change port mapping and add environment variable for LOCAL_LLM_API Add new OpenCode configuration files for LLM settings and instructions Update Dockerfile to install additional tools and dependencies including Go, Rust, Node.js, and Python packages Modify docker-entrypoint.sh to handle MCP server initialization and shell configuration Update LM client readme to reflect new API endpoint configuration --- .devcontainer/devcontainer.json | 6 +++- .devcontainer/docker-compose.yml | 6 ++-- .opencode/config.json | 8 ++++++ .opencode/instructions.md | 43 ++++++++++++++-------------- .zed/settings.json | 3 +- Dockerfile | 48 ++++++++++++++++++++++---------- docker-compose.yml | 10 ------- docker-entrypoint.sh | 23 ++++++++++++--- opt/lm-client/readme.md | 4 +-- tools/install_latest_go.sh | 33 ++++++++++++++++++++++ 10 files changed, 125 insertions(+), 59 deletions(-) create mode 100644 .opencode/config.json delete mode 100644 docker-compose.yml create mode 100644 tools/install_latest_go.sh diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index e952670..9783747 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -3,5 +3,9 @@ "dockerComposeFile": "docker-compose.yml", "service": "pmocrazy-coder", "workspaceFolder": "/workspace", - "remoteUser": "devuser" + "remoteUser": "devuser", + "settings": { + "terminal.integrated.shell.linux": "/bin/bash", + }, + "features": {}, } diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index 0453cff..137ad90 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -1,5 +1,3 @@ -version: "3.8" - services: pmocrazy-coder: build: @@ -9,7 +7,9 @@ services: - ..:/workspace working_dir: /workspace ports: - - "1248:1248" + - "1249:1248" + environment: + - LOCAL_LLM_API=http://host.docker.internal:1248/v1 user: devuser entrypoint: ["/usr/local/bin/entrypoint.sh"] command: ["bash", "-c", "tail -f /dev/null"] diff --git a/.opencode/config.json b/.opencode/config.json new file mode 100644 index 0000000..140ffd8 --- /dev/null +++ b/.opencode/config.json @@ -0,0 +1,8 @@ +{ + "llm": { + "provider": "openai", + "model": "default", + "apiKey": "not-needed", + "baseURL": "${LOCAL_LLM_API:-http://host.docker.internal:1248/v1}" + } +} diff --git a/.opencode/instructions.md b/.opencode/instructions.md index f9b7a88..59260b6 100644 --- a/.opencode/instructions.md +++ b/.opencode/instructions.md @@ -1,29 +1,28 @@ -# OpenCode Global Instructions +# OpenCode Global Instructions – Optimized for Minimal Scope -## Path handling rules - -- Always use relative paths. -- Never generate absolute paths (e.g. /Users/..., /home/..., C:\...). -- Never assume a specific username, OS, or local filesystem layout. -- All paths must be relative to the project root unless explicitly specified. -- Do not guess the current working directory. -- If the working directory is ambiguous, ask for clarification instead of inventing one. +## Path handling +- Always use relative paths. Never generate absolute paths (e.g., /Users/..., /home/..., C:\...). +- All paths must be relative to the project root unless explicitly specified. +- Do not guess the current working directory. Ask for clarification if ambiguous. +- Only operate on files explicitly mentioned in the task. Never traverse directories not specified. ## Workspace assumptions +- Assume the workspace root is the repository root. +- Do not infer environment-specific values (machine, OS, home directory). +- Only read or reference files explicitly provided or mentioned. Ignore all others. -- Assume the workspace root is the repository root. -- Do not hardcode environment-specific values. -- Do not infer the machine, OS, or home directory. - -## File generation rules - -- Generate only the requested file. -- Do not modify unrelated files. -- Do not add additional configuration unless explicitly requested. -- Output valid JSON with no comments when JSON is requested. +## File generation +- Generate only the requested file. Do not modify unrelated files. +- Do not add extra files or configurations unless explicitly requested. +- Output valid JSON without comments when JSON is requested. +- When accessing a file, assume no knowledge of other files unless explicitly provided. ## Determinism +- Avoid creative alternatives. Produce a single, minimal, correct implementation. +- Do not propose multiple solutions unless explicitly asked. +- Do not speculate about missing files, directories, or dependencies. -- Avoid creative alternatives. -- Do not propose multiple solutions unless asked. -- Produce a single, minimal, correct implementation. +## Explicit scope limitation +- Operate strictly on files and paths explicitly mentioned in the prompt. +- Do not recursively explore the directory tree. +- Ask for clarification if necessary information is missing instead of assuming. diff --git a/.zed/settings.json b/.zed/settings.json index 3b0c2c6..db701ee 100644 --- a/.zed/settings.json +++ b/.zed/settings.json @@ -4,9 +4,8 @@ // see the documentation: https://zed.dev/docs/configuring-zed#settings-files { "inlay_hints": { - "enabled": true + "enabled": true, }, "colorize_brackets": true, "project_name": "PMO Crazy Coder", - "autosave": "on_window_change", } diff --git a/Dockerfile b/Dockerfile index e72f10c..29f1f16 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,40 @@ FROM debian:bookworm-slim RUN apt-get update && apt-get install -y \ - python3 python3-pip \ - golang-go rustc cargo \ - r-base \ - sqlite3 build-essential git curl wget \ - bash zsh \ + clang llvm-dev libclang-dev pkg-config build-essential git make curl nodejs npm \ + pylint black flake8 mypy isort logrotate sudo cmake libicu-dev zlib1g-dev \ + libcurl4-openssl-dev libssl-dev ruby-dev jq python3 python3-pip golang-go rustc cargo \ + r-base sqlite3 wget bash zsh libgit2-dev \ && apt-get clean && rm -rf /var/lib/apt/lists/* -# Installer jj -RUN curl -LO https://github.com/martinvonz/jj/releases/latest/download/jj-x86_64-unknown-linux-gnu \ - && chmod +x jj-x86_64-unknown-linux-gnu \ - && mv jj-x86_64-unknown-linux-gnu /opt/bin/jj +RUN echo "deb http://deb.debian.org/debian testing main" > /etc/apt/sources.list.d/testing.list -# Installer jj_lsp (si binaire séparé) -RUN curl -LO https://github.com/martinvonz/jj/releases/latest/download/jj_lsp-x86_64-unknown-linux-gnu \ - && chmod +x jj_lsp-x86_64-unknown-linux-gnu \ - && mv jj_lsp-x86_64-unknown-linux-gnu /opt/bin/jj_lsp +COPY tools/install_latest_go.sh /tmp/install_latest_go.sh +RUN bash /tmp/install_latest_go.sh && \ + echo "PATH=/usr/local/go/bin:$PATH" >> /root/.bashrc +ENV PATH=/usr/local/go/bin:$PATH + +ENV RUSTUP_HOME=/usr/local/rustup +ENV CARGO_HOME=/usr/local/cargo +ENV PATH=/usr/local/cargo/bin:$PATH +RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain stable && \ + rustup install nightly && \ + rustup component add rustfmt clippy rust-src rust-docs && \ + cargo install cargo-edit cargo-watch cargo-outdated cargo-make cargo-binstall + +RUN npm install -g typescript tsc @types/node eslint prettier + +RUN cargo binstall --strategies crate-meta-data jj-cli + +RUN cargo install --git https://github.com/nilskch/jj-lsp.git + +RUN gem install github-linguist + +RUN pip install --no-cache-dir --break-system-packages ruff fastmcp ipython + +RUN curl -fsSL https://opencode.ai/install | bash && \ + mkdir -p /root/.config/opencode && \ + mv /root/.opencode/bin/opencode /usr/local/bin/ COPY opt/bin/ /opt/bin/ COPY opt/dev-tools/ /opt/dev-tools/ @@ -27,8 +45,8 @@ ENV PATH="/opt/bin:/opt/dev-tools:/opt/lm-client:${PATH}" ARG USERNAME=devuser ARG USER_UID=1000 ARG USER_GID=1000 -RUN groupadd --gid $USER_GID $USERNAME \ - && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME +RUN groupadd --gid $USER_GID $USERNAME && \ + useradd --uid $USER_UID --gid $USER_GID -m $USERNAME COPY docker-entrypoint.sh /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/entrypoint.sh diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index d70da8b..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,10 +0,0 @@ -version: "3.8" - -services: - pmocrazy-coder: - build: . - volumes: - - .:/workspace - working_dir: /workspace - ports: - - "1248:1248" diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index e775281..2caedf1 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -1,14 +1,29 @@ #!/bin/bash # docker-entrypoint.sh +# --- Initialise .ai_index si nécessaire --- if [ ! -d "/workspace/.ai_index" ]; then mkdir -p /workspace/.ai_index/ast mkdir -p /workspace/.ai_index/embeddings touch /workspace/.ai_index/graph.db fi -/opt/bin/mcp-server > /workspace/.ai_index/mcp.log 2>&1 & -MCP_PID=$! -echo $MCP_PID > /workspace/.ai_index/mcp.pid +# --- Configure LOCAL_LLM_API pour Bash --- +if [ -n "$LOCAL_LLM_API" ]; then + if ! grep -q "LOCAL_LLM_API" /home/devuser/.bashrc; then + echo "export LOCAL_LLM_API=$LOCAL_LLM_API" >> /home/devuser/.bashrc + fi +fi -exec "$@" +# --- Lance MCP server en background si pas déjà lancé --- +if [ ! -f "/workspace/.ai_index/mcp.pid" ] || ! kill -0 $(cat /workspace/.ai_index/mcp.pid) 2>/dev/null; then + /opt/bin/mcp-server >/workspace/.ai_index/mcp.log 2>&1 & + echo $! >/workspace/.ai_index/mcp.pid +fi + +# --- Force Bash comme shell par défaut --- +if [ -z "$1" ]; then + exec /bin/bash +else + exec "$@" +fi diff --git a/opt/lm-client/readme.md b/opt/lm-client/readme.md index e8b016f..728fb7f 100644 --- a/opt/lm-client/readme.md +++ b/opt/lm-client/readme.md @@ -1,3 +1,3 @@ -LM Studio client for Qwen3-Coder-Next +Local LLM API client for Qwen3-Coder-Next Download from: https://lmstudio.ai/ -Configure to run on localhost:1248 +Configure to run on http://host.docker.internal:1248/v1 (or set LOCAL_LLM_API environment variable) diff --git a/tools/install_latest_go.sh b/tools/install_latest_go.sh new file mode 100644 index 0000000..1a48f72 --- /dev/null +++ b/tools/install_latest_go.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +URL="https://go.dev/dl/" + +OS=$(uname -a | awk '{print $1}') +ARCH=$(uname -m) + +if [[ "$ARCH" == "x86_64" ]] ; then + ARCH="amd64" +fi + +if [[ "$ARCH" == "aarch64" ]] ; then + ARCH="arm64" +fi + +GOFILE=$(curl "$URL" \ + | grep 'class="download"' \ + | grep "\.tar\.gz" \ + | sed -E 's@^.*/dl/(go[1-9].+\.tar\.gz)".*$@\1@' \ + | grep -i "$OS" \ + | grep -i "$ARCH" \ + | head -1) + +GOURL=$(curl "${URL}${GOFILE}" \ + | sed -E 's@^.*href="(.*\.tar\.gz)".*$@\1@') + +echo "Install GO from : $GOURL" 1>&2 + +mkdir -p /usr/local +cd /usr/local + +curl "$GOURL" \ + | tar zxf -