-
Notifications
You must be signed in to change notification settings - Fork 0
feat: install Copilot CLI + seed MCP (WDIO) #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
ad2a7e3
165fb4d
5e8fb5c
ff19d4d
29bfb9b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| --- | ||
| name: analysisAgent | ||
| description: "Use when understanding/explaining the codebase and when refining or implementing code changes with validation. Keywords: explain code, trace logic, refactor, cleanup, improve, modify files, run checks." | ||
| tools: [read, search, edit, execute, todo] | ||
| user-invocable: true | ||
| --- | ||
| You are a focused coding specialist for code explanation, refinement, and safe implementation. | ||
|
|
||
| Your job is to: | ||
| - Understand existing project structure and behavior before making edits. | ||
| - Improve or refine code changes safely and with minimal regression risk. | ||
| - Explain code paths and implementation details when asked, including read-only analysis tasks. | ||
| - Automatically run targeted validation commands after edits when practical. | ||
|
|
||
| ## Constraints | ||
| - DO NOT make unrelated refactors outside the requested scope. | ||
| - DO NOT introduce unnecessary dependencies or broad architectural changes unless asked. | ||
| - DO NOT leave changes unverified when basic checks are available. | ||
| - ONLY make purposeful, traceable edits tied to the request. | ||
|
|
||
| ## Approach | ||
| 1. Clarify the requested outcome and identify affected files/components. | ||
| 2. Inspect existing code paths and conventions before editing. | ||
| 3. Implement minimal, high-confidence changes. | ||
| 4. Run relevant checks or tests and inspect errors. | ||
| 5. Report what changed, why, and any residual risks. | ||
|
|
||
| ## Output Format | ||
| Return: | ||
| 1. A brief result summary. | ||
| 2. Files changed with key modifications. | ||
| 3. Validation performed (commands/tests) and outcomes. | ||
| 4. Open risks, assumptions, or follow-up suggestions if needed. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,10 +15,11 @@ | |
|
|
||
| SHELL ["/bin/bash", "-c"] | ||
|
|
||
|
|
||
| # -------------------------------------------- | ||
| # ENV Defaults (override with Docker Compose or CLI) | ||
| # -------------------------------------------- | ||
| ENV LANGUAGES=node,python,java \ | ||
|
Check warning on line 22 in Dockerfile
|
||
| NODE_VERSION=20.11.1 \ | ||
| ASDF_VERSION=v0.14.0 \ | ||
| PYTHON_VERSION=3.12.1 \ | ||
|
|
@@ -28,7 +29,14 @@ | |
| VSCODE_PASSWORD=agent \ | ||
| OPENAI_API_KEY=your_openai_api_key_here \ | ||
| OPENAI_MODEL=gpt-4 \ | ||
| GITLAB_PERSONAL_ACCESS_TOKEN=your_gitlab_token_here | ||
| GITLAB_PERSONAL_ACCESS_TOKEN=your_gitlab_token_here \ | ||
| COPILOT_CLI_ENABLED=false \ | ||
| COPILOT_CLI_MCP_ENABLED=false \ | ||
| COPILOT_CLI_INSTALL_METHOD=auto \ | ||
| COPILOT_CLI_VERSION= \ | ||
| COPILOT_CLI_PREFIX=/usr/local \ | ||
| COPILOT_GITHUB_TOKEN=${COPILOT_GITHUB_TOKEN} \ | ||
| BROWSERS_ENABLED=false | ||
|
|
||
| # -------------------------------------------- | ||
| # Locale setup | ||
|
|
@@ -71,6 +79,11 @@ | |
| COPY src/scripts /opt/scripts/ | ||
| RUN chmod +x /opt/scripts/*.sh || true | ||
|
|
||
| # -------------------------------------------- | ||
| # Copilot CLI MCP templates | ||
| # -------------------------------------------- | ||
| COPY src/copilot /opt/copilot/ | ||
|
|
||
| # -------------------------------------------- | ||
| # Install languages | ||
| # -------------------------------------------- | ||
|
|
@@ -80,6 +93,12 @@ | |
| # Source bashrc to load asdf and installed languages | ||
| RUN . ~/.bashrc | ||
|
|
||
| # -------------------------------------------- | ||
| # Optional: browsers + Copilot CLI | ||
| # -------------------------------------------- | ||
| RUN bash /opt/scripts/install_browsers.sh | ||
| RUN bash /opt/scripts/install_copilot_cli.sh | ||
|
Comment on lines
+96
to
+100
|
||
|
|
||
| # -------------------------------------------- | ||
| # VS Code + extensions + MCPs + settings | ||
| # -------------------------------------------- | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -133,6 +133,61 @@ Each script should support: | |
|
|
||
| --- | ||
|
|
||
| ## 🤖 Copilot CLI + MCP (opt-in) | ||
|
|
||
| This image can optionally install GitHub Copilot CLI and seed a CLI-level MCP config for WebdriverIO MCP. | ||
|
|
||
| ### Enable during build | ||
|
|
||
| Use build args (recommended) to enable the install and seed the MCP config: | ||
|
|
||
| ```bash | ||
| COPILOT_CLI_ENABLED=true \ | ||
| COPILOT_CLI_MCP_ENABLED=true \ | ||
| docker compose -f docker-compose.yml up --build | ||
| ``` | ||
|
Comment on lines
+142
to
+148
|
||
|
|
||
| Optional build flags: | ||
|
|
||
| - `COPILOT_CLI_INSTALL_METHOD` = `auto` | `script` | `npm` | ||
| - `COPILOT_CLI_VERSION` = specific version (optional) | ||
| - `COPILOT_CLI_PREFIX` = install prefix (default `/usr/local`) | ||
| - `BROWSERS_ENABLED=true` to install Google Chrome (`google-chrome-stable`) for MCP browser automation | ||
|
|
||
| ### MCP seed template | ||
|
|
||
| The template lives at [src/copilot/mcp-config.json](src/copilot/mcp-config.json) and is copied to: | ||
|
|
||
| ``` | ||
| ~/.copilot/mcp-config.json | ||
| ``` | ||
|
|
||
| ### Authenticate and verify | ||
|
|
||
| Inside the container: | ||
|
|
||
| ```bash | ||
| copilot --version | ||
| copilot | ||
| ``` | ||
|
|
||
| If prompted, run `/login` and follow the instructions. You can also set `GH_TOKEN` or `GITHUB_TOKEN`. | ||
|
|
||
| ### Minimal demo (headless browser + screenshot) | ||
|
|
||
| With MCP seeded and browsers enabled, run a simple flow from Copilot CLI: | ||
|
|
||
| 1. Start a session | ||
| 2. Navigate to a URL | ||
| 3. Take a screenshot | ||
| 4. Close the session | ||
|
|
||
| Example prompt to Copilot CLI: | ||
|
|
||
| "Use wdio-mcp to open a headless browser, navigate to https://example.com, take a screenshot at /workspace/example.png, then close the session." | ||
|
|
||
| --- | ||
|
|
||
| --- | ||
|
|
||
| ## 📄 Roadmap | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,6 +17,12 @@ services: | |
| VSCODE_PASSWORD: "${VSCODE_PASSWORD}" | ||
| OPENAI_API_KEY: "${OPENAI_API_KEY}" | ||
| OPENAI_MODEL: "${OPENAI_MODEL}" | ||
| COPILOT_CLI_ENABLED: "${COPILOT_CLI_ENABLED:-false}" | ||
| COPILOT_CLI_MCP_ENABLED: "${COPILOT_CLI_MCP_ENABLED:-false}" | ||
| COPILOT_CLI_INSTALL_METHOD: "${COPILOT_CLI_INSTALL_METHOD:-auto}" | ||
| COPILOT_CLI_VERSION: "${COPILOT_CLI_VERSION:-}" | ||
| COPILOT_CLI_PREFIX: "${COPILOT_CLI_PREFIX:-/usr/local}" | ||
| BROWSERS_ENABLED: "${BROWSERS_ENABLED:-false}" | ||
|
Comment on lines
+20
to
+25
|
||
| GITLAB_PERSONAL_ACCESS_TOKEN: "${GITLAB_PERSONAL_ACCESS_TOKEN}" | ||
| volumes: | ||
| - ./src/workspace:/workspace | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| { | ||
| "mcpServers": { | ||
| "wdio-mcp": { | ||
| "type": "stdio", | ||
| "command": "npx", | ||
| "args": ["-y", "@wdio/mcp@0.1.0"], | ||
| "tools": [ | ||
| "start_browser", | ||
| "navigate", | ||
| "get_visible_elements", | ||
| "click_element", | ||
| "set_value", | ||
| "scroll", | ||
| "take_screenshot", | ||
| "close_session" | ||
| ] | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
|
|
||
| echo "Installing browser runtime (opt-in)" | ||
|
|
||
| : "${BROWSERS_ENABLED:=false}" | ||
|
|
||
| if [[ "${BROWSERS_ENABLED}" != "true" ]]; then | ||
| echo "BROWSERS_ENABLED is not true; skipping browser install." | ||
| exit 0 | ||
| fi | ||
|
|
||
| apt-get update | ||
|
|
||
| # Install Google Chrome from the official APT repository to avoid snap-based Chromium packages | ||
| apt-get install -y --no-install-recommends wget gnupg ca-certificates | ||
|
|
||
| install -m 0755 -d /etc/apt/keyrings | ||
| wget -qO- https://dl.google.com/linux/linux_signing_key.pub | gpg --dearmor -o /etc/apt/keyrings/google-chrome.gpg | ||
| echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/google-chrome.gpg] https://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list | ||
|
|
||
| apt-get update | ||
| apt-get install -y --no-install-recommends google-chrome-stable | ||
|
|
||
| apt-get clean && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| if command -v google-chrome >/dev/null 2>&1; then | ||
| echo "Google Chrome installed: $(google-chrome --version || true)" | ||
| elif command -v chromium-browser >/dev/null 2>&1; then | ||
| echo "Chromium installed: $(chromium-browser --version || true)" | ||
| elif command -v chromium >/dev/null 2>&1; then | ||
| echo "Chromium installed: $(chromium --version || true)" | ||
| else | ||
| echo "Browser install completed, but no supported browser binary found on PATH." >&2 | ||
| fi |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
|
|
||
| echo "Installing GitHub Copilot CLI (opt-in)" | ||
|
|
||
| : "${COPILOT_CLI_ENABLED:=false}" | ||
| : "${COPILOT_CLI_INSTALL_METHOD:=auto}" | ||
| : "${COPILOT_CLI_INSTALL_URL:=https://gh.io/copilot-install}" | ||
| : "${COPILOT_CLI_PREFIX:=/usr/local}" | ||
| : "${COPILOT_CLI_VERSION:=}" | ||
| : "${COPILOT_CLI_MCP_ENABLED:=false}" | ||
| : "${COPILOT_CLI_MCP_CONFIG_TEMPLATE:=/opt/copilot/mcp-config.json}" | ||
| : "${COPILOT_CLI_MCP_CONFIG_PATH:=/root/.copilot/mcp-config.json}" | ||
| : "${COPILOT_GITHUB_TOKEN:=your_github_personal_access_token_here }" | ||
|
|
||
|
Comment on lines
+14
to
+15
|
||
| if [[ "${COPILOT_CLI_ENABLED}" != "true" ]]; then | ||
| echo "COPILOT_CLI_ENABLED is not true; skipping Copilot CLI installation." | ||
| exit 0 | ||
| fi | ||
|
|
||
| install_via_script() { | ||
| echo "Installing Copilot CLI via official install script..." | ||
| if [[ -n "${COPILOT_CLI_VERSION}" ]]; then | ||
| curl -fsSL "${COPILOT_CLI_INSTALL_URL}" | VERSION="${COPILOT_CLI_VERSION}" PREFIX="${COPILOT_CLI_PREFIX}" bash | ||
| else | ||
| curl -fsSL "${COPILOT_CLI_INSTALL_URL}" | PREFIX="${COPILOT_CLI_PREFIX}" bash | ||
netzulo marked this conversation as resolved.
Show resolved
Hide resolved
Comment on lines
+24
to
+26
|
||
| fi | ||
| } | ||
|
|
||
| install_via_npm() { | ||
| echo "Installing Copilot CLI via npm..." | ||
| if ! command -v npm >/dev/null 2>&1; then | ||
| echo "npm not found; cannot install Copilot CLI via npm." >&2 | ||
| return 1 | ||
| fi | ||
| if [[ -n "${COPILOT_CLI_VERSION}" ]]; then | ||
| npm install -g "@github/copilot@${COPILOT_CLI_VERSION}" | ||
| else | ||
| npm install -g @github/copilot | ||
| fi | ||
| } | ||
|
|
||
| if [[ "${COPILOT_CLI_INSTALL_METHOD}" == "script" ]]; then | ||
| install_via_script | ||
| elif [[ "${COPILOT_CLI_INSTALL_METHOD}" == "npm" ]]; then | ||
| install_via_npm | ||
| else | ||
| install_via_script || install_via_npm | ||
| fi | ||
|
|
||
| if command -v copilot >/dev/null 2>&1; then | ||
| echo "Copilot CLI installed: $(copilot --version)" | ||
| else | ||
| echo "Copilot CLI installation finished, but 'copilot' is not on PATH." >&2 | ||
| fi | ||
|
|
||
| if [[ -n "${COPILOT_GITHUB_TOKEN}" && "${COPILOT_GITHUB_TOKEN}" != "your_github_personal_access_token_here" ]]; then | ||
| echo "Logging into Copilot CLI with provided GitHub token to cache credentials..." | ||
| echo "${COPILOT_GITHUB_TOKEN}" | copilot auth login --with-token || echo "Copilot CLI login failed; please check your token and login manually." >&2 | ||
| else | ||
|
Comment on lines
+57
to
+60
|
||
| echo "COPILOT_GITHUB_TOKEN is not set or is the default placeholder; skipping Copilot CLI login." | ||
| fi | ||
|
|
||
| if [[ "${COPILOT_CLI_MCP_ENABLED}" == "true" ]]; then | ||
| if [[ -f "${COPILOT_CLI_MCP_CONFIG_TEMPLATE}" ]]; then | ||
| echo "Seeding Copilot CLI MCP config..." | ||
| mkdir -p "$(dirname "${COPILOT_CLI_MCP_CONFIG_PATH}")" | ||
| cp "${COPILOT_CLI_MCP_CONFIG_TEMPLATE}" "${COPILOT_CLI_MCP_CONFIG_PATH}" | ||
| else | ||
| echo "MCP config template not found at ${COPILOT_CLI_MCP_CONFIG_TEMPLATE}; skipping seed." >&2 | ||
| fi | ||
| else | ||
| echo "COPILOT_CLI_MCP_ENABLED is not true; skipping MCP config seed." | ||
| fi | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
ENV COPILOT_GITHUB_TOKEN=${COPILOT_GITHUB_TOKEN}line bakes whateverCOPILOT_GITHUB_TOKENis set to at build time (including a real GitHub personal access token from the host environment or build args) directly into the final image. Anyone with access to the image or a running container can read this environment variable (e.g., viadocker inspector/proc), leading to credential theft and compromise of the associated GitHub account. Avoid persisting this token in the image and instead pass it only at runtime when needed, ensuring it is not stored in image layers or defaultENVvalues.