Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ghcr.io/framework-r-d/phlex-dev:latest
FROM ghcr.io/framework-r-d/phlex-dev:2026-06-24

# Validate Python site-packages symlink.
# Invoke bash explicitly: the script uses bash features (pipefail, arrays,
Expand Down Expand Up @@ -88,15 +88,26 @@ if [ "$(dpkg-divert --truename /usr/bin/man)" = "/usr/bin/man.REAL" ]; then
fi
INSTALL_MAN_TOOLS

# Install podman client and socat inside the container to support nested
# Install dev utils
# container communication and provide a 'docker' command alias.
RUN bash <<'INSTALL_PODMAN_CLIENT'
RUN bash <<'INSTALL_DEV_UTILS'
set -euo pipefail
apt-get update
apt-get install -y --no-install-recommends ssh podman socat
apt-get install -y --no-install-recommends jq podman ssh socat tree yq
apt purge nodejs npm -y && apt autoremove -y || true
sudo apt-get install -y curl
Comment on lines +96 to +98

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Look for any other reliance on `sudo` in the devcontainer setup.
rg -nP '\bsudo\b' .devcontainer/

Repository: Framework-R-D/phlex

Length of output: 214


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the relevant Dockerfile section with line numbers.
sed -n '1,140p' .devcontainer/Dockerfile | cat -n

printf '\n---\n'

# Check for any other apt/apt-get usage in the devcontainer Dockerfile.
rg -n '\bapt(-get)?\b|sudo\b|set -euo pipefail' .devcontainer/Dockerfile

Repository: Framework-R-D/phlex

Length of output: 6227


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the base image and early setup in case sudo availability depends on it.
sed -n '1,120p' .devcontainer/Dockerfile | cat -n

Repository: Framework-R-D/phlex

Length of output: 5597


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Focus on the package-install block around the comment.
sed -n '88,104p' .devcontainer/Dockerfile | cat -n

Repository: Framework-R-D/phlex

Length of output: 744


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '88,104p' .devcontainer/Dockerfile | cat -n
rg -n '\bapt(-get)?\b|sudo\b|set -euo pipefail' .devcontainer/Dockerfile

Repository: Framework-R-D/phlex

Length of output: 1369


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read the full relevant span to understand whether curl belongs in the same install block.
nl -ba .devcontainer/Dockerfile | sed -n '88,104p'

Repository: Framework-R-D/phlex

Length of output: 197


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the exact Dockerfile block around the review comment.
nl -ba .devcontainer/Dockerfile | sed -n '88,104p'

printf '\n---\n'

# Check whether this Dockerfile sets a shell mode that would make the command chain brittle.
rg -n 'set -euo pipefail|SHELL \[' .devcontainer/Dockerfile

printf '\n---\n'

# Confirm whether sudo is used anywhere else in the devcontainer setup.
rg -nP '\bsudo\b' .devcontainer/

Repository: Framework-R-D/phlex

Length of output: 197


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check the devcontainer config for how this Dockerfile is built and whether USER changes later.
rg -n 'phlex-dev:2026-06-24|Dockerfile|USER\b|sudo\b|apt purge|apt-get install -y curl|setup_26\.x' .devcontainer .github README.md

Repository: Framework-R-D/phlex

Length of output: 520


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read the devcontainer config to see whether the Dockerfile runs as root and how the image is referenced.
if [ -f .devcontainer/devcontainer.json ]; then
  cat -n .devcontainer/devcontainer.json
fi

Repository: Framework-R-D/phlex

Length of output: 5092


🌐 Web query:

Debian apt command line interface unstable use apt-get in scripts official documentation

💡 Result:

According to official Debian documentation, the apt command-line interface is designed primarily for interactive end-user use and is not guaranteed to have a stable interface for automated scripts [1][2]. Because the apt command may change its behavior or output format between versions to better suit interactive needs, Debian explicitly recommends using apt-get and apt-cache for scripting purposes [3][1][2]. Key points regarding this distinction include: - Stable Interface: The apt-get and apt-cache commands have a well-defined, stable public interface that provides guaranteed backward compatibility, making them the appropriate choice for shell scripts and automated tasks [4][1][5]. - Interactive Focus: The apt command acts as a high-level wrapper and, while it improves the user experience with features like colorized output or progress bars, it prioritizes interactive usability over script stability [1][2]. - Warning Messages: When used in non-interactive environments (such as pipes or scripts), the apt command may issue a warning stating: "WARNING: apt does not have a stable CLI interface. Use with caution in scripts" [5][6][7]. - Functionality: All core features available in apt are also provided by apt-get and apt-cache [1][2]. Therefore, for consistent and predictable behavior in scripts, developers should rely on the latter tools [3][4].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Confirm there is no USER override before the dev-utils block.
rg -n '^\s*USER\b' .devcontainer/Dockerfile

Repository: Framework-R-D/phlex

Length of output: 157


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the devcontainer compose file for any build-time user settings.
cat -n .devcontainer/docker-compose.yml

Repository: Framework-R-D/phlex

Length of output: 1449


Drop sudo and use apt-get in this heredoc

  • RUN already executes as root, so sudo is redundant here; add curl to the existing install list instead of a separate step.
  • apt purge / apt autoremove use the interactive apt CLI; switch those to apt-get purge -y ... && apt-get autoremove -y for Dockerfile scripting.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.devcontainer/Dockerfile around lines 96 - 98, The Dockerfile heredoc
currently mixes `apt` and `sudo` unnecessarily; update the `RUN` sequence to use
only non-interactive `apt-get` commands. In the install block around the `jq`,
`podman`, `ssh`, `socat`, `tree`, and `yq` step, add `curl` to that same
`apt-get install -y --no-install-recommends` invocation, and change the `apt
purge` / `apt autoremove` calls to `apt-get purge -y ... && apt-get autoremove
-y` so the script remains root-friendly and Docker-safe.

curl -fsSL https://deb.nodesource.com/setup_26.x | bash -
apt-get install -y nodejs
Comment thread
greenc-FNAL marked this conversation as resolved.
apt-get clean
rm -rf /var/lib/apt/lists/*
INSTALL_PODMAN_CLIENT
INSTALL_DEV_UTILS

RUN bash <<'INSTALL_NPM_PACKAGES'
set -euo pipefail
npm -g update
npm config set allow-scripts=@kilocode/cli --location=user
npm install -g @kilocode/cli
INSTALL_NPM_PACKAGES

# Wire up the root user's .bashrc to source the Spack environment via
# /entrypoint.sh on every interactive shell.
Expand Down
1 change: 0 additions & 1 deletion .devcontainer/codespace.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@
"extensions": {
"recommendations": [
"charliermarsh.ruff",
"github.copilot-chat",
"github.vscode-github-actions",
"github.vscode-pull-request-github",
"ms-vscode.cmake-tools",
Expand Down
40 changes: 3 additions & 37 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,47 +1,17 @@
{
"name": "Phlex CI Dev Container",
"build": {
"dockerfile": "Dockerfile"
},
"runArgs": [],
"dockerComposeFile": "docker-compose.yml",
"service": "phlex-dev",
"workspaceFolder": "/workspaces/phlex",
"remoteUser": "root",
"remoteEnv": {
// KILO_CONFIG_CONTENT_DOCKER rewrites 127.0.0.1:PORT to
// host.docker.internal:RELAY_PORT for the socat relay used when
// headroom runs as a local proxy. Passed through here so that
// post-create.sh can wire it into the container's .bashrc
// conditionally: if non-empty it sets KILO_CONFIG_CONTENT to this
// value; otherwise KILO_CONFIG_CONTENT is left unset and Kilo falls
// back to ~/.config/kilo/kilo.jsonc (bind-mounted from the host).
"KILO_CONFIG_CONTENT_DOCKER": "${localEnv:KILO_CONFIG_CONTENT_DOCKER}",
"KILO_API_KEY": "${localEnv:HEADROOM_UPSTREAM_KEY}"
},
"containerEnv": {
"CMAKE_GENERATOR": "Ninja",
"GH_CONFIG_DIR": "/root/.config/gh",
"DOCKER_HOST": "unix:///tmp/podman.sock",
"CONTAINER_HOST": "unix:///tmp/podman.sock",
"GNUPGHOME": "/root/.gnupg"
},
"mounts": [
"source=${localWorkspaceFolder}/../phlex-coding-guidelines,target=/workspaces/phlex-coding-guidelines,type=bind",
"source=${localWorkspaceFolder}/../phlex-design,target=/workspaces/phlex-design,type=bind",
"source=${localWorkspaceFolder}/../phlex-examples,target=/workspaces/phlex-examples,type=bind",
"source=${localWorkspaceFolder}/../phlex-spack-recipes,target=/workspaces/phlex-spack-recipes,type=bind",
"source=${localEnv:HOME}/.aws,target=/root/.aws,type=bind",
"source=${localEnv:HOME}/.config/gh,target=/root/.config/gh,type=bind,readonly",
"source=${localEnv:HOME}/.config/kilo,target=/root/.config/kilo,type=bind",
"source=${localEnv:HOME}/.gnupg,target=/root/.gnupg,type=bind",
"source=${localEnv:HOME}/.kiro,target=/root/.kiro,type=bind",
"source=phlex-kilo-data,target=/root/.local/share/kilo,type=volume",
"source=${localEnv:HOME}/.podman-proxy/podman.sock,target=/tmp/podman.sock,type=bind",
"source=${localEnv:HOME}/.vscode-remote-user-data,target=/root/.vscode-server-insiders/data/User,type=bind"
],
"initializeCommand": "bash .devcontainer/ensure-repos.sh",
"onCreateCommand": "bash .devcontainer/setup-repos.sh /workspaces",
"postCreateCommand": "bash -lc 'bash .devcontainer/post-create.sh'",
"customizations": {

"vscode": {
"settings": {
"terminal.integrated.defaultProfile.linux": "bash",
Expand Down Expand Up @@ -88,7 +58,6 @@
"**/.venv/**": true,
"**/py_virtual_env/**": true
},
"github.copilot-chat.usePreReleaseVersion": false,
"kilocode.new.extraCaCerts": ""
},
"extensions": [
Expand All @@ -99,7 +68,6 @@
"donjayamanne.githistory",
"dotjoshjohnson.xml",
"eamodio.gitlens",
"github.copilot-chat",
"github.vscode-github-actions",
"github.vscode-pull-request-github",
"jebbs.plantuml",
Expand All @@ -114,13 +82,11 @@
"ms-python.vscode-pylance",
"ms-python.vscode-python-envs",
"ms-vscode.cmake-tools",
"ms-vscode.cpptools",
"ms-vscode.cpptools-extension-pack",
"ms-vscode.cpptools-themes",
"ms-vscode.hexeditor",
"ms-vscode.live-server",
"ms-vscode.makefile-tools",
"ms-vscode.vscode-websearchforcopilot",
"redhat.vscode-yaml",
"shd101wyy.markdown-preview-enhanced",
"swyddfa.esbonio",
Expand Down
34 changes: 34 additions & 0 deletions .devcontainer/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
version: "3.8"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

version is a no-op in Compose v2.

The top-level version key has been obsolete since Compose v2 and just emits a "the attribute version is obsolete" warning on every up. Safe to drop it entirely.

🧹 Proposed change
-version: "3.8"
-
 services:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
version: "3.8"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.devcontainer/docker-compose.yml at line 1, Remove the obsolete top-level
version key from the docker-compose definition since Compose v2 ignores it and
warns on every up. Update the .devcontainer/docker-compose.yml content to rely
on the Compose spec without a version field, keeping the rest of the service
configuration unchanged.


services:
phlex-dev:
build:
context: .
dockerfile: Dockerfile
volumes:
- ..:/workspaces/phlex
- ../../phlex-coding-guidelines:/workspaces/phlex-coding-guidelines
- ../../phlex-design:/workspaces/phlex-design
- ../../phlex-examples:/workspaces/phlex-examples
- ../../phlex-spack-recipes:/workspaces/phlex-spack-recipes
- ${HOME}/.config/gh:/root/.config/gh:ro
- ${HOME}/.config/kilo:/root/.config/kilo
- ${HOME}/.gnupg:/root/.gnupg
- ${HOME}/.podman-proxy/podman.sock:/tmp/podman.sock
- phlex-kilo-data:/root/.local/share/kilo
- phlex-vscode-user-data:/root/.vscode-server-insiders/data/User
env_file:
- ${HOME}/.phlex-kilo.env
environment:
- CMAKE_GENERATOR=Ninja
- GH_CONFIG_DIR=/root/.config/gh
- DOCKER_HOST=unix:///tmp/podman.sock
- CONTAINER_HOST=unix:///tmp/podman.sock
- GNUPGHOME=/root/.gnupg
user: root
tty: true
stdin_open: true

volumes:
phlex-kilo-data:
phlex-vscode-user-data:
16 changes: 12 additions & 4 deletions .devcontainer/ensure-repos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ fi
HEADROOM_PORT="${HEADROOM_PORT:-9797}"
HEADROOM_RELAY_PORT=$(( HEADROOM_PORT + 10000 ))
HEADROOM_LOCAL="127.0.0.1:${HEADROOM_PORT}"

if ss -tlnp 2>/dev/null | grep -q "127.0.0.1:${HEADROOM_PORT}"; then
start_socat_relay \
"Headroom proxy" \
Expand All @@ -184,10 +183,19 @@ else
fi

# Ensure remaining source bind mount points exist.
ensure_bind_dir "$HOME/.aws"
ensure_bind_dir "$HOME/.config/"{gh,kilo}
ensure_bind_dir "$HOME/.gnupg"
ensure_bind_dir "$HOME/.kiro"
ensure_bind_dir "$HOME/.vscode-remote-user-data"

# Generate .env file for the devcontainer to provide KILO_CONFIG_CONTENT
# to the VS Code plugin. This must be done on the host because the plugin
# needs this environment variable at server startup.
if [ -f "${HOME}/.config/kilo/kilo.jsonc" ]; then
# Replace the baseURL for fnal-litellm specifically.
# The range /"fnal-litellm"/,/baseURL/ ensures we only modify the correct provider.
# We avoid stripping comments with sed to prevent corrupting URLs (https://),
# as the Kilo plugin's JSONC parser handles comments correctly.
KILO_CONFIG_CONTENT="$(perl -0777 -pe 's|("fnal-litellm".*?)"baseURL":\s*"[^"]*"|$1"baseURL": "http://host.docker.internal:'${HEADROOM_RELAY_PORT}'"|s; s/"[^"]*"(*SKIP)(*F)|\/\/.*//g; s/^\s+//gm; s/\n//g' "${HOME}/.config/kilo/kilo.jsonc")"
echo "KILO_CONFIG_CONTENT='${KILO_CONFIG_CONTENT}'" > "${HOME}/.phlex-kilo.env"
fi
Comment thread
Copilot marked this conversation as resolved.

echo "SUCCESS: .devcontainer/ensure-repos.sh completed successfully"
12 changes: 0 additions & 12 deletions .devcontainer/post-create.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,6 @@ EOF
# installation on every rebuild.
rm -f /root/.vscode-server-insiders/data/Machine/.installExtensionsMarker

# Set KILO_CONFIG_CONTENT for interactive shells. When KILO_CONFIG_CONTENT_DOCKER
# is non-empty (headroom local proxy via socat relay), use it so that the baseURL
# points at host.docker.internal rather than 127.0.0.1. Otherwise leave
# KILO_CONFIG_CONTENT unset so Kilo falls back to ~/.config/kilo/kilo.jsonc,
# which is bind-mounted from the host and may point at an external provider.
if [ -n "${KILO_CONFIG_CONTENT_DOCKER:-}" ]; then
printf 'export KILO_CONFIG_CONTENT=%q\n' "${KILO_CONFIG_CONTENT_DOCKER}" >> /root/.bashrc
fi

# Seed the Kilo Code auth token into the container-private data volume.
# The volume is not shared with the host to avoid SQLite conflicts between
# the Remote-SSH and devcontainer Kilo Code instances. The API key is
Expand Down Expand Up @@ -99,6 +90,3 @@ if command -v prek >/dev/null 2>&1; then
elif command -v pre-commit >/dev/null 2>&1; then
pre-commit install || true
fi

# Install kiro-cli and set up shell integrations.
curl -fsSL https://cli.kiro.dev/install | bash
26 changes: 26 additions & 0 deletions .github/workflows/actionlint-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,29 @@
echo "::error::actionlint check failed. Please review the output above for details."
exit 1
fi

gating_check:
needs: setup
if: >
always() && (
github.event_name == 'workflow_dispatch' ||
inputs.skip-relevance-check ||
needs.setup.outputs.has_changes == 'true'
)
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: ${{ needs.setup.outputs.ref }}
path: ${{ needs.setup.outputs.checkout_path }}
repository: ${{ needs.setup.outputs.repo }}
persist-credentials: false

- name: Verify gating-block consistency

Check warning

Code scanning / CodeQL

Checkout of untrusted code in a trusted context Medium

Potential unsafe checkout of untrusted pull request on privileged workflow.
Comment thread
greenc-FNAL marked this conversation as resolved.
Dismissed
env:
CHECKOUT_PATH: ${{ needs.setup.outputs.checkout_path }}
run: bash "${CHECKOUT_PATH}/scripts/check-gating-block.sh" "${CHECKOUT_PATH}/.github/workflows"
8 changes: 4 additions & 4 deletions .github/workflows/cmake-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ run-name: "${{ github.actor }} building and testing ${{ github.repository }}"
Default (if empty): Run `gcc/none`
required: false
default: ""
perfetto-heap-profile:
perfetto_heap_profile:
description: "Enable heap profiling for Perfetto runs"
required: false
type: boolean
default: false
perfetto-cpu-profile:
perfetto_cpu_profile:
description: "Enable CPU profiling for Perfetto runs"
required: false
type: boolean
Expand Down Expand Up @@ -228,9 +228,9 @@ jobs:
if: matrix.sanitizer == 'perfetto'
working-directory: ${{ needs.setup.outputs.build_path }}
env:
PERFETTO_HEAP_PROFILE: ${{ github.event.inputs.perfetto-heap-profile || 'false' }}
PERFETTO_HEAP_PROFILE: ${{ github.event.inputs.perfetto_heap_profile || 'false' }}
PERFETTO_CPU_PROFILE:
${{ (github.event.inputs.perfetto-cpu-profile != null && github.event.inputs.perfetto-cpu-profile) || true
${{ (github.event.inputs.perfetto_cpu_profile != null && github.event.inputs.perfetto_cpu_profile) || true
}}
run: |
. /entrypoint.sh
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql-comment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
if: success() && hashFiles('pr_comment_data/pr_number.txt') != ''
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
github-token: ${{ secrets.WORKFLOW_PAT }}
github-token: ${{ github.token }}
script: |
const fs = require('fs');
const path = require('path');
Expand Down
Loading
Loading