Compare commits

..

18 Commits

Author SHA1 Message Date
Asher e950669f93 Use AgentAPI for additional Claude status reporting (#150)
Is it OK to add the flag like this or do we need to check the cli
version to determine whether the new flag is available? Or I could just
throw in an `||` to run the command again without the flag if it fails.

Blocked on adding AgentAPI to Claude.

Will need to do the same for Goose.
2025-06-17 19:14:42 +02:00
DevCats 3d78f5e262 Merge branch 'main' into claude-code-web 2025-06-16 20:02:40 -05:00
DevCats 960ec18d35 fix: clean up version-bump workflow script output handling (#153)
## Description

Removed unnecessary comments and added commands to reset the working
directory and clean untracked files in the version-bump workflow. This
improves the script's reliability by ensuring a clean state after
executing version checks.

---

## Type of Change

- [ ] New module
- [X] Bug fix
- [ ] Feature/enhancement
- [ ] Documentation
- [ ] Other

---

## Related Issues

None
2025-06-16 19:52:56 -05:00
DevCats eae64160bd fix: update GitHub Actions permissions in version-bump workflow (#152)
## Description

update GitHub Actions permissions in version-bump workflow by adding
issues permission for commenting on PR's

---

## Type of Change

- [ ] New module
- [X] Bug fix
- [ ] Feature/enhancement
- [ ] Documentation
- [ ] Other

---

## Related Issues

None
2025-06-16 14:32:09 -05:00
Spike Curtis b58bfebcf3 fix: disable UDP connections on windows-rdp module (#149)
## Description

Relates to 

Fixes an issue where RDP doesn't function properly over Coder Connect,
by disabling UDP and relying only on TCP. c.f.
https://github.com/coder/internal/issues/608#issuecomment-2965923672 for
a detailed description of the problem.

---

## Type of Change

- [ ] New module
- [X] Bug fix
- [ ] Feature/enhancement
- [ ] Documentation
- [ ] Other

---

## Module Information

<!-- Delete this section if not applicable -->

**Path:** `registry/coder/modules/windows-rdp`  
**New version:** `v1.0.19`  
**Breaking change:** [ ] Yes [x] No

---

## Testing & Validation

- [x] Tests pass (`bun test`)
- [x] Code formatted (`bun run fmt`)
- [x] Changes tested locally

---

## Related Issues

https://github.com/coder/internal/issues/608

Closes #

---------

Signed-off-by: Spike Curtis <spike@coder.com>
2025-06-13 06:18:11 +00:00
Hugo Dutka 1469373a50 uncomment the claude code app 2025-06-05 18:56:48 +02:00
Hugo Dutka 1551c17413 comment out the claude-code app temporarily 2025-06-05 18:53:36 +02:00
Hugo Dutka eac3e55537 add healthcheck to claude code web 2025-06-05 18:26:37 +02:00
Hugo Dutka c301da7e6b remove tee pipes - they make claude ignore actual terminal width and render 80 char lines 2025-06-04 19:03:41 +02:00
Hugo Dutka 7d64e7ea84 use agentapi attach 2025-06-04 17:53:07 +02:00
Hugo Dutka b5937c06a9 adjust agentapi terminal width and height 2025-06-04 15:41:33 +02:00
Hugo Dutka d2b91ae1a8 adjust agentapi terminal width and height 2025-06-04 14:32:27 +02:00
Hugo Dutka bd05d06a3b change claude code web app url 2025-06-04 13:19:05 +02:00
Ben Potter e340affe95 fix another typo 2025-06-03 18:36:50 -05:00
Ben Potter 16892d806e fix typo 2025-06-03 18:31:30 -05:00
Ben Potter 056f4b5a68 remove duplicate app 2025-06-03 18:29:28 -05:00
Ben Potter 1c99c57b6e add agentapi 2025-06-03 18:27:29 -05:00
BrunoQuaresma a0c1a051ed feat: add claude_code_web in claude-code 2025-06-03 20:54:58 +00:00
4 changed files with 127 additions and 186 deletions
+70 -177
View File
@@ -3,6 +3,8 @@ name: Version Bump
on:
pull_request:
types: [labeled]
paths:
- "registry/**/modules/**"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -13,8 +15,9 @@ jobs:
if: github.event.label.name == 'version:patch' || github.event.label.name == 'version:minor' || github.event.label.name == 'version:major'
runs-on: ubuntu-latest
permissions:
contents: write
contents: read
pull-requests: write
issues: write
steps:
- name: Checkout code
uses: actions/checkout@v4
@@ -22,195 +25,85 @@ jobs:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Git
- name: Extract bump type from label
id: bump-type
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Detect version bump type
id: version-type
case "${{ github.event.label.name }}" in
"version:patch")
echo "type=patch" >> $GITHUB_OUTPUT
;;
"version:minor")
echo "type=minor" >> $GITHUB_OUTPUT
;;
"version:major")
echo "type=major" >> $GITHUB_OUTPUT
;;
*)
echo "Invalid version label: ${{ github.event.label.name }}"
exit 1
;;
esac
- name: Check version bump requirements
id: version-check
run: |
if [[ "${{ github.event.label.name }}" == "version:patch" ]]; then
echo "bump_type=patch" >> $GITHUB_OUTPUT
elif [[ "${{ github.event.label.name }}" == "version:minor" ]]; then
echo "bump_type=minor" >> $GITHUB_OUTPUT
elif [[ "${{ github.event.label.name }}" == "version:major" ]]; then
echo "bump_type=major" >> $GITHUB_OUTPUT
output_file=$(mktemp)
if ./.github/scripts/version-bump.sh "${{ steps.bump-type.outputs.type }}" origin/main > "$output_file" 2>&1; then
echo "Script completed successfully"
else
echo "Invalid version label: ${{ github.event.label.name }}"
echo "Script failed"
cat "$output_file"
exit 1
fi
- name: Detect modified modules
id: detect-modules
run: |
CHANGED_FILES=$(git diff --name-only origin/main...HEAD)
MODULES=$(echo "$CHANGED_FILES" | grep -E '^registry/[^/]+/modules/[^/]+/' | cut -d'/' -f1-4 | sort -u)
if [ -z "$MODULES" ]; then
echo "No modules detected in changes"
{
echo "output<<EOF"
cat "$output_file"
echo "EOF"
} >> $GITHUB_OUTPUT
cat "$output_file"
if git diff --quiet; then
echo "versions_up_to_date=true" >> $GITHUB_OUTPUT
echo "✅ All module versions are already up to date"
else
echo "versions_up_to_date=false" >> $GITHUB_OUTPUT
echo "❌ Module versions need to be updated"
echo "Files that would be changed:"
git diff --name-only
echo ""
echo "Diff preview:"
git diff
git checkout .
git clean -fd
exit 1
fi
echo "Found modules:"
echo "$MODULES"
echo "modules<<EOF" >> $GITHUB_OUTPUT
echo "$MODULES" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Process version bumps
id: process-bumps
run: |
BUMP_TYPE="${{ steps.version-type.outputs.bump_type }}"
BUMPED_MODULES=""
UPDATED_READMES=""
UNTAGGED_MODULES=""
while IFS= read -r module_path; do
if [ -z "$module_path" ]; then continue; fi
NAMESPACE=$(echo "$module_path" | cut -d'/' -f2)
MODULE_NAME=$(echo "$module_path" | cut -d'/' -f4)
echo "Processing: $NAMESPACE/$MODULE_NAME"
LATEST_TAG=$(git tag -l "release/${NAMESPACE}/${MODULE_NAME}/v*" | sort -V | tail -1)
README_PATH="$module_path/README.md"
if [ -z "$LATEST_TAG" ]; then
# No tag found, check if README has version references
if [ -f "$README_PATH" ] && grep -q 'version\s*=\s*"' "$README_PATH"; then
# Extract version from README
README_VERSION=$(grep 'version\s*=\s*"' "$README_PATH" | head -1 | sed 's/.*version\s*=\s*"\([^"]*\)".*/\1/')
echo "No git tag found, but README shows version: $README_VERSION"
# Validate extracted version format
if ! [[ "$README_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "❌ Invalid README version format: '$README_VERSION'. Expected X.Y.Z format."
echo "Starting from v1.0.0 instead"
CURRENT_VERSION="1.0.0"
else
CURRENT_VERSION="$README_VERSION"
UNTAGGED_MODULES="$UNTAGGED_MODULES\n- $NAMESPACE/$MODULE_NAME (README: v$README_VERSION)"
fi
else
echo "No existing tags or version references found for $NAMESPACE/$MODULE_NAME, starting from v1.0.0"
CURRENT_VERSION="1.0.0"
fi
else
CURRENT_VERSION=$(echo "$LATEST_TAG" | sed 's/.*\/v//')
echo "Found git tag: $LATEST_TAG (v$CURRENT_VERSION)"
fi
echo "Current version: $CURRENT_VERSION"
# Validate version format (semantic versioning: X.Y.Z)
if ! [[ "$CURRENT_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "❌ Invalid version format: '$CURRENT_VERSION'. Expected X.Y.Z format."
exit 1
fi
IFS='.' read -r major minor patch <<< "$CURRENT_VERSION"
# Validate that components are numeric
if ! [[ "$major" =~ ^[0-9]+$ ]] || ! [[ "$minor" =~ ^[0-9]+$ ]] || ! [[ "$patch" =~ ^[0-9]+$ ]]; then
echo "❌ Version components must be numeric: major='$major' minor='$minor' patch='$patch'"
exit 1
fi
case "$BUMP_TYPE" in
"patch")
NEW_VERSION="$major.$minor.$((patch + 1))"
;;
"minor")
NEW_VERSION="$major.$((minor + 1)).0"
;;
"major")
NEW_VERSION="$((major + 1)).0.0"
;;
esac
echo "New version: $NEW_VERSION"
if [ -f "$README_PATH" ]; then
# Check if README contains version references for this specific module
MODULE_SOURCE="registry.coder.com/${NAMESPACE}/${MODULE_NAME}/coder"
if grep -q "source.*${MODULE_SOURCE}" "$README_PATH"; then
echo "Updating version references for $NAMESPACE/$MODULE_NAME in $README_PATH"
# Use awk to only update versions that follow the specific module source
awk -v module_source="$MODULE_SOURCE" -v new_version="$NEW_VERSION" '
/source.*=.*/ {
if ($0 ~ module_source) {
in_target_module = 1
} else {
in_target_module = 0
}
}
/version.*=.*"/ {
if (in_target_module) {
gsub(/version[[:space:]]*=[[:space:]]*"[^"]*"/, "version = \"" new_version "\"")
in_target_module = 0
}
}
{ print }
' "$README_PATH" > "${README_PATH}.tmp" && mv "${README_PATH}.tmp" "$README_PATH"
UPDATED_READMES="$UPDATED_READMES\n- $NAMESPACE/$MODULE_NAME"
elif grep -q 'version\s*=\s*"' "$README_PATH"; then
echo "⚠️ Found version references but no module source match for $NAMESPACE/$MODULE_NAME"
fi
fi
BUMPED_MODULES="$BUMPED_MODULES\n- $NAMESPACE/$MODULE_NAME: v$CURRENT_VERSION → v$NEW_VERSION"
done <<< "${{ steps.detect-modules.outputs.modules }}"
echo "bumped_modules<<EOF" >> $GITHUB_OUTPUT
echo -e "$BUMPED_MODULES" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "updated_readmes<<EOF" >> $GITHUB_OUTPUT
echo -e "$UPDATED_READMES" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "untagged_modules<<EOF" >> $GITHUB_OUTPUT
echo -e "$UNTAGGED_MODULES" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Commit changes
run: |
# Check if any README files were modified
if git diff --quiet 'registry/*/modules/*/README.md'; then
echo "No README changes to commit"
else
echo "Committing README changes..."
git diff --name-only 'registry/*/modules/*/README.md'
git add registry/*/modules/*/README.md
git commit -m "chore: bump module versions (${{ steps.version-type.outputs.bump_type }})"
git push
fi
- name: Comment on PR
- name: Comment on PR - Failure
if: failure() && steps.version-check.outputs.versions_up_to_date == 'false'
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const bumpedModules = `${{ steps.process-bumps.outputs.bumped_modules }}`;
const updatedReadmes = `${{ steps.process-bumps.outputs.updated_readmes }}`;
const untaggedModules = `${{ steps.process-bumps.outputs.untagged_modules }}`;
const bumpType = `${{ steps.version-type.outputs.bump_type }}`;
let comment = `## 🚀 Version Bump Summary\n\n`;
const output = `${{ steps.version-check.outputs.output }}`;
const bumpType = `${{ steps.bump-type.outputs.type }}`;
let comment = `## ❌ Version Bump Validation Failed\n\n`;
comment += `**Bump Type:** \`${bumpType}\`\n\n`;
comment += `**Modules Updated:**\n${bumpedModules}\n\n`;
if (updatedReadmes.trim()) {
comment += `**READMEs Updated:**\n${updatedReadmes}\n\n`;
}
if (untaggedModules.trim()) {
comment += `⚠️ **Modules Without Git Tags:**\n${untaggedModules}\n\n`;
comment += `> These modules were versioned based on README content. Consider creating proper release tags after merging.\n\n`;
}
comment += `> Versions have been automatically updated in module READMEs where applicable.`;
comment += `Module versions need to be updated but haven't been bumped yet.\n\n`;
comment += `**Required Actions:**\n`;
comment += `1. Run the version bump script locally: \`./.github/scripts/version-bump.sh ${bumpType}\`\n`;
comment += `2. Commit the changes: \`git add . && git commit -m "chore: bump module versions (${bumpType})"\`\n`;
comment += `3. Push the changes: \`git push\`\n\n`;
comment += `### Script Output:\n\`\`\`\n${output}\n\`\`\`\n\n`;
comment += `> Please update the module versions and push the changes to continue.`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});
});
+48 -5
View File
@@ -131,9 +131,14 @@ resource "coder_script" "claude_code" {
npm install -g @anthropic-ai/claude-code@${var.claude_code_version}
fi
# Hardcoded for now: install AgentAPI
wget https://github.com/coder/agentapi/releases/download/preview/agentapi-linux-amd64
chmod +x agentapi-linux-amd64
sudo mv agentapi-linux-amd64 /usr/local/bin/agentapi
if [ "${var.experiment_report_tasks}" = "true" ]; then
echo "Configuring Claude Code to report tasks via Coder MCP..."
coder exp mcp configure claude-code ${var.folder}
coder exp mcp configure claude-code ${var.folder} --ai-agentapi-url http://localhost:3284
fi
# Run post-install script if provided
@@ -166,8 +171,24 @@ resource "coder_script" "claude_code" {
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
# Create a new tmux session in detached mode
tmux new-session -d -s claude-code -c ${var.folder} "claude --dangerously-skip-permissions \"$CODER_MCP_CLAUDE_TASK_PROMPT\""
# use low width to fit in the tasks UI sidebar. height is adjusted to ~match the default 80k (80x1000) characters
# visible in the terminal screen.
tmux new-session -d -s claude-code-agentapi -c ${var.folder} 'agentapi server --term-width 67 --term-height 1190 -- bash -c "claude --dangerously-skip-permissions \"$CODER_MCP_CLAUDE_TASK_PROMPT\""; exec bash'
echo "Waiting for agentapi server to start on port 3284..."
for i in $(seq 1 15); do
if lsof -i :3284 | grep -q 'LISTEN'; then
echo "agentapi server started on port 3284."
break
fi
echo "Waiting... ($i/15)"
sleep 1
done
if ! lsof -i :3284 | grep -q 'LISTEN'; then
echo "Error: agentapi server did not start on port 3284 after 15 seconds."
exit 1
fi
tmux new-session -d -s claude-code -c ${var.folder} "agentapi attach"
fi
@@ -217,6 +238,20 @@ resource "coder_script" "claude_code" {
run_on_start = true
}
resource "coder_app" "claude_code_web" {
slug = "claude-code-web"
display_name = "Claude Code Web"
agent_id = var.agent_id
url = "http://localhost:3284/"
icon = var.icon
subdomain = true
healthcheck {
url = "http://localhost:3284/status"
interval = 5
threshold = 3
}
}
resource "coder_app" "claude_code" {
slug = "claude-code"
display_name = "Claude Code"
@@ -229,12 +264,20 @@ resource "coder_app" "claude_code" {
export LC_ALL=en_US.UTF-8
if [ "${var.experiment_use_tmux}" = "true" ]; then
if ! tmux has-session -t claude-code-agentapi 2>/dev/null; then
echo "Starting a new Claude Code agentapi tmux session." | tee -a "$HOME/.claude-code.log"
# use low width to fit in the tasks UI sidebar. height is adjusted to ~match the default 80k (80x1000) characters
# visible in the terminal screen.
tmux new-session -d -s claude-code-agentapi -c ${var.folder} 'agentapi server --term-width 67 --term-height 1190 -- bash -c "claude --dangerously-skip-permissions"; exec bash'
fi
if tmux has-session -t claude-code 2>/dev/null; then
echo "Attaching to existing Claude Code tmux session." | tee -a "$HOME/.claude-code.log"
tmux attach-session -t claude-code
else
echo "Starting a new Claude Code tmux session." | tee -a "$HOME/.claude-code.log"
tmux new-session -s claude-code -c ${var.folder} "claude --dangerously-skip-permissions | tee -a \"$HOME/.claude-code.log\"; exec bash"
tmux new-session -s claude-code -c ${var.folder} "agentapi attach; exec bash"
fi
elif [ "${var.experiment_use_screen}" = "true" ]; then
if screen -list | grep -q "claude-code"; then
@@ -242,7 +285,7 @@ resource "coder_app" "claude_code" {
screen -xRR claude-code
else
echo "Starting a new Claude Code screen session." | tee -a "$HOME/.claude-code.log"
screen -S claude-code bash -c 'claude --dangerously-skip-permissions | tee -a "$HOME/.claude-code.log"; exec bash'
screen -S claude-code bash -c 'agentapi attach; exec bash'
fi
else
cd ${var.folder}
+4 -4
View File
@@ -16,7 +16,7 @@ Enable Remote Desktop + a web based client on Windows workspaces, powered by [de
module "windows_rdp" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/windows-rdp/coder"
version = "1.2.0"
version = "1.2.1"
agent_id = resource.coder_agent.main.id
resource_id = resource.aws_instance.dev.id
}
@@ -34,7 +34,7 @@ module "windows_rdp" {
module "windows_rdp" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/windows-rdp/coder"
version = "1.2.0"
version = "1.2.1"
agent_id = resource.coder_agent.main.id
resource_id = resource.aws_instance.dev.id
}
@@ -46,7 +46,7 @@ module "windows_rdp" {
module "windows_rdp" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/windows-rdp/coder"
version = "1.2.0"
version = "1.2.1"
agent_id = resource.coder_agent.main.id
resource_id = resource.google_compute_instance.dev[0].id
}
@@ -58,7 +58,7 @@ module "windows_rdp" {
module "windows_rdp" {
count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/windows-rdp/coder"
version = "1.2.0"
version = "1.2.1"
agent_id = resource.coder_agent.main.id
resource_id = resource.aws_instance.dev.id
devolutions_gateway_version = "2025.1.6" # Specify a specific version
@@ -16,6 +16,11 @@ function Configure-RDP {
New-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -Name "SecurityLayer" -Value 1 -PropertyType DWORD -Force
# Enable RDP through Windows Firewall
Enable-NetFirewallRule -DisplayGroup "Remote Desktop"
# Disable UDP. It doesn't work via `coder port-forward` and is broken due to MTU issues in Coder Connect.
# Requires a restart to take effect. c.f. https://github.com/coder/internal/issues/608#issuecomment-2965923672
New-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' -Name "SelectTransport" -Value 1 -PropertyType DWORD -Force
Restart-Service -Name "TermService" -Force
}
function Install-DevolutionsGateway {