Skip to content

Commit e0438bc

Browse files
committed
Release Monk plugin v0.1.50
Generated from monk-agent 3635c276716aafc308a6893b0c881aa50af29400.
1 parent 189e22a commit e0438bc

42 files changed

Lines changed: 1209 additions & 198 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.antigravity-plugin/hooks/ensure-monk-agent.ps1

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,15 @@ if (Get-Command bash -ErrorAction SilentlyContinue) { exit 0 }
1818

1919
$Port = if ($env:MONK_AGENT_PORT) { $env:MONK_AGENT_PORT } else { "7419" }
2020
$AgentHost = if ($env:MONK_AGENT_HOST) { $env:MONK_AGENT_HOST } else { "127.0.0.1" }
21-
$HealthUrl = "http://${AgentHost}:$Port/.well-known/oauth-protected-resource"
21+
# IPv6 loopback hosts (e.g. ::1, an explicit MONK_AGENT_HOST override) must be
22+
# bracketed in a URL authority or the port separator is ambiguous.
23+
$UrlHost = if ($AgentHost.Contains(":") -and -not ($AgentHost.StartsWith("[") -and $AgentHost.EndsWith("]"))) {
24+
"[$AgentHost]"
25+
} else {
26+
$AgentHost
27+
}
28+
$HealthUrl = "http://${UrlHost}:$Port/.well-known/oauth-protected-resource"
29+
$HealthResource = "http://${UrlHost}:$Port/mcp"
2230

2331
function Write-Json {
2432
param([object]$Object)
@@ -27,8 +35,12 @@ function Write-Json {
2735

2836
function Test-AgentRunning {
2937
try {
30-
$Response = Invoke-WebRequest -Uri $HealthUrl -UseBasicParsing -TimeoutSec 2
31-
return $Response.Content -match '"resource"'
38+
$Response = Invoke-WebRequest -Uri $HealthUrl -UseBasicParsing -TimeoutSec 2 -NoProxy
39+
# Require the resource field to equal our own MCP endpoint, not merely be
40+
# present — an unrelated service on the same port could otherwise be
41+
# mistaken for monk-agent.
42+
$Document = $Response.Content | ConvertFrom-Json -ErrorAction Stop
43+
return [string]$Document.resource -ceq $HealthResource
3244
} catch {
3345
return $false
3446
}
@@ -70,10 +82,16 @@ if (-not (Test-Path $AgentPath)) {
7082

7183
# Binary present but not running - start it directly (do not wait).
7284
$MonkHome = if ($env:MONK_AGENT_HOME) { $env:MONK_AGENT_HOME } else { Join-Path $HOME ".monk" }
73-
$LogDir = Join-Path $MonkHome "agent\launcher\logs"
74-
New-Item -ItemType Directory -Force -Path $LogDir | Out-Null
85+
$AgentDataDir = Join-Path $MonkHome "agent\launcher"
86+
$LogDir = Join-Path $AgentDataDir "logs"
87+
$RunDir = Join-Path $AgentDataDir "run"
88+
New-Item -ItemType Directory -Force -Path $LogDir, $RunDir | Out-Null
7589
$LogOut = Join-Path $LogDir "monk-agent.out.log"
7690
$LogErr = Join-Path $LogDir "monk-agent.err.log"
91+
# Write the PID file the official uninstaller looks for (Stop-ManagedAgent in
92+
# scripts/uninstall-monk-agent.ps1) so a companion this hook starts in the
93+
# background is found and stopped on uninstall instead of surviving it.
94+
$PidFile = Join-Path $RunDir "monk-agent.pid"
7795

7896
$env:MONK_AUTH_URL = if ($env:MONK_AUTH_URL) { $env:MONK_AUTH_URL } else { "https://auth.monk.io" }
7997
$env:MONK_AGENT_AUTH_CLIENT_ID = if ($env:MONK_AGENT_AUTH_CLIENT_ID) { $env:MONK_AGENT_AUTH_CLIENT_ID } else { "UW84YWcJME3buMSLfqLX8IbBsYdNWi47" }
@@ -92,6 +110,10 @@ try {
92110
} catch {
93111
}
94112

113+
if ($Process) {
114+
Set-Content -Path $PidFile -Value $Process.Id -NoNewline:$false -ErrorAction SilentlyContinue
115+
}
116+
95117
# Wait briefly for the agent to become reachable. If the process exits early or
96118
# the health endpoint never responds, report an attempted start with a pointer
97119
# to the logs instead of a false "has been started".

.antigravity-plugin/hooks/ensure-monk-agent.sh

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,30 @@ set -eu
1111

1212
port="${MONK_AGENT_PORT:-7419}"
1313
host="${MONK_AGENT_HOST:-127.0.0.1}"
14-
health_url="http://$host:$port/.well-known/oauth-protected-resource"
14+
# IPv6 loopback hosts (e.g. ::1, an explicit MONK_AGENT_HOST override) must be
15+
# bracketed in a URL authority or the port separator is ambiguous.
16+
url_host="$host"
17+
case "$url_host" in
18+
\[*\]) ;;
19+
*:*) url_host="[$url_host]" ;;
20+
esac
21+
health_url="http://$url_host:$port/.well-known/oauth-protected-resource"
22+
health_resource="http://$url_host:$port/mcp"
1523

1624
is_running() {
25+
response=""
1726
if command -v curl >/dev/null 2>&1; then
18-
curl -fsS --max-time 2 "$health_url" 2>/dev/null | grep -q '"resource"'
19-
return $?
27+
response="$(curl -fsS --noproxy '*' --max-time 2 "$health_url" 2>/dev/null)" || return 1
28+
elif command -v wget >/dev/null 2>&1; then
29+
response="$(env -u http_proxy -u https_proxy -u all_proxy -u HTTP_PROXY -u HTTPS_PROXY -u ALL_PROXY wget -q -T 2 -O - "$health_url" 2>/dev/null)" || return 1
30+
else
31+
return 1
2032
fi
21-
if command -v wget >/dev/null 2>&1; then
22-
wget -q -T 2 -O - "$health_url" 2>/dev/null | grep -q '"resource"'
23-
return $?
24-
fi
25-
return 1
33+
# Require the resource field to equal our own MCP endpoint, not merely be
34+
# present — an unrelated service on the same port could otherwise be
35+
# mistaken for monk-agent.
36+
resource="$(printf '%s\n' "$response" | sed -n 's/.*"resource"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -n 1)"
37+
[ "$resource" = "$health_resource" ]
2638
}
2739

2840
# Emit an Antigravity injectSteps payload carrying a single ephemeral message.
@@ -63,9 +75,15 @@ if [ ! -x "$agent_path" ]; then
6375
fi
6476

6577
# Binary present but not running — start it directly
66-
log_dir="${MONK_AGENT_HOME:-"$HOME/.monk"}/agent/launcher/logs"
67-
mkdir -p "$log_dir"
78+
agent_data_dir="${MONK_AGENT_HOME:-"$HOME/.monk"}/agent/launcher"
79+
log_dir="$agent_data_dir/logs"
80+
run_dir="$agent_data_dir/run"
81+
mkdir -p "$log_dir" "$run_dir"
6882
log_file="$log_dir/monk-agent.log"
83+
# Write the pid file the official uninstaller looks for (see stop_agent() in
84+
# scripts/uninstall-monk-agent.sh) so a companion this hook starts in the
85+
# background is found and stopped on uninstall instead of surviving it.
86+
pid_file="$run_dir/monk-agent.pid"
6987

7088
export MONK_AUTH_URL="${MONK_AUTH_URL:-https://auth.monk.io}"
7189
export MONK_AGENT_AUTH_CLIENT_ID="${MONK_AGENT_AUTH_CLIENT_ID:-UW84YWcJME3buMSLfqLX8IbBsYdNWi47}"
@@ -80,6 +98,7 @@ else
8098
"$agent_path" serve --host "$host" --port "$port" >>"$log_file" 2>&1 </dev/null &
8199
fi
82100
agent_pid=$!
101+
printf '%s\n' "$agent_pid" >"$pid_file"
83102

84103
# Wait briefly for the agent to become reachable. If the process exits early or
85104
# the health endpoint never responds, report an attempted start with a pointer

.antigravity-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
22
"name": "monk",
3-
"version": "0.1.49"
3+
"version": "0.1.50"
44
}

.antigravity-plugin/scripts/ensure-monk-agent.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ Invoke-WebRequest -Uri $ChecksumUrl -OutFile $ChecksumTmp
115115

116116
$Expected = ((Get-Content -Raw $ChecksumTmp).Trim() -split "\s+")[0].ToLowerInvariant()
117117

118-
if ((Test-Path $Target) -and (Test-Path $ChecksumInstalled)) {
118+
if ((Test-Path $Target) -and (Get-Item $Target).Length -gt 0 -and (Test-Path $ChecksumInstalled)) {
119119
$Installed = ((Get-Content -Raw $ChecksumInstalled).Trim() -split "\s+")[0].ToLowerInvariant()
120120
if ($Installed -eq $Expected) {
121121
Remove-Item -Force $ChecksumTmp

.antigravity-plugin/scripts/ensure-monk-agent.sh

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,29 @@ esac
3939

4040
url="$download_base/$platform_path/$artifact"
4141
checksum_url="$url.sha256"
42-
archive_tmp="$install_dir/.monk-agent.tmp.tar.gz"
43-
checksum_tmp="$install_dir/.monk-agent.tmp.sha256"
44-
extract_dir="$install_dir/.monk-agent.extract"
42+
archive_tmp="$install_dir/.monk-agent.tmp.$$.tar.gz"
43+
checksum_tmp="$install_dir/.monk-agent.tmp.$$.sha256"
44+
extract_dir="$install_dir/.monk-agent.extract.$$"
45+
lock_file="$install_dir/.monk-agent.lock"
4546
mkdir -p "$install_dir"
4647

48+
cleanup() {
49+
rm -rf "$extract_dir" "$archive_tmp" "$checksum_tmp"
50+
}
51+
trap cleanup EXIT
52+
53+
# Serialize concurrent installs so they don't race on the shared install dir.
54+
# flock is standard on Linux; macOS lacks it by default, so skip locking there
55+
# rather than fail -- per-PID scratch paths below still keep each invocation's
56+
# download/extract isolated even without the lock.
57+
if command -v flock >/dev/null 2>&1; then
58+
exec 3>"$lock_file"
59+
if ! flock -n 3; then
60+
echo "Another monk-agent install is in progress; waiting..." >&2
61+
flock 3
62+
fi
63+
fi
64+
4765
if [ "$auto_update" = "0" ] || [ "$auto_update" = "false" ]; then
4866
if command -v monk-agent >/dev/null 2>&1; then
4967
command -v monk-agent
@@ -66,7 +84,7 @@ fi
6684

6785
expected="$(awk '{print $1}' "$checksum_tmp")"
6886

69-
if [ -x "$target" ] && [ -f "$checksum_installed" ]; then
87+
if [ -x "$target" ] && [ -s "$target" ] && [ -f "$checksum_installed" ]; then
7088
installed="$(awk '{print $1}' "$checksum_installed")"
7189
if [ "$installed" = "$expected" ]; then
7290
rm -f "$checksum_tmp"
@@ -102,5 +120,4 @@ tar -xzf "$archive_tmp" -C "$extract_dir"
102120
chmod 0755 "$extract_dir/monk-agent"
103121
mv "$extract_dir/monk-agent" "$target"
104122
printf '%s %s\n' "$expected" "$artifact" >"$checksum_installed"
105-
rm -rf "$extract_dir" "$archive_tmp" "$checksum_tmp"
106123
printf '%s\n' "$target"

.antigravity-plugin/scripts/plugin-version.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
# in telemetry (MONK_PLUGIN_VERSION). Sets the process env var so the value both
44
# is readable here and is inherited by the spawned agent — the PowerShell
55
# counterpart of plugin-version.sh.
6-
$env:MONK_PLUGIN_VERSION = "0.1.49"
6+
$env:MONK_PLUGIN_VERSION = "0.1.50"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#!/bin/sh
22
# Generated at plugin render time. Sourced by start-monk-agent.sh so the agent
33
# can report the real plugin version in telemetry (MONK_PLUGIN_VERSION).
4-
MONK_PLUGIN_VERSION="0.1.49"
4+
MONK_PLUGIN_VERSION="0.1.50"

.antigravity-plugin/scripts/run-powershell.cmd

100644100755
Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,30 @@
1+
:; exit 0
12
@echo off
3+
rem The first line is a POSIX guard, not decoration. To cmd.exe it is a label -
4+
rem skipped, and never echoed, since label lines are not echoed even with ECHO ON
5+
rem - while /bin/sh reads it as a no-op followed by "exit 0". It is needed because
6+
rem Claude Code runs EVERY hook entry in a hooks.json array on every platform: it
7+
rem has no commandWindows support at all, verified against the 2.1.220 binary, so
8+
rem the Windows entry - this shim - is also spawned on macOS and Linux. Before the
9+
rem guard, /bin/sh there failed with 126 "Permission denied" on a non-executable
10+
rem .cmd and Claude Code printed a "PreToolUse:Bash hook error" banner on every
11+
rem single Bash tool call. The shim now ships executable, so sh runs it as a
12+
rem script and it exits 0 in silence; the sibling .sh hook entry does the real
13+
rem work on those platforms. Keep the rest of this file sh-parseable as well - no
14+
rem parentheses, no backticks, no unbalanced quotes - so a shell that reads ahead
15+
rem past the exit cannot trip over the batch body. plugin/src/check.ts enforces
16+
rem the guard line, the executable bit, and sh -n. ENG-441 follow-up.
17+
rem
218
rem ENG-441 shim: launch Windows PowerShell from an absolute, OS-controlled path.
319
rem
4-
rem Host hook runners do NOT reliably expand %SystemRoot% (or ${SystemRoot} /
5-
rem $SystemRoot) inside the hook JSON command string - Claude Code, verified,
6-
rem leaves it literal - so an inline "%SystemRoot%\...\powershell.exe" fails to
7-
rem resolve and the hook silently no-ops. This .cmd is instead executed by
8-
rem cmd.exe, where %SystemRoot% DOES expand to a non-writable location, so the pin
9-
rem stays correct AND robust to a non-standard system root. A bare `powershell.exe`
10-
rem would be resolved via the current directory before PATH, letting a planted
11-
rem binary hijack the hook; an absolute path defeats that.
20+
rem Host hook runners do NOT reliably expand %SystemRoot% - or the shell-style
21+
rem SystemRoot variants - inside the hook JSON command string. Claude Code,
22+
rem verified, leaves it literal, so an inline "%SystemRoot%\...\powershell.exe"
23+
rem fails to resolve and the hook silently no-ops. This .cmd is instead executed
24+
rem by cmd.exe, where %SystemRoot% DOES expand to a non-writable location, so the
25+
rem pin stays correct AND robust to a non-standard system root. A bare
26+
rem powershell.exe would be resolved via the current directory before PATH,
27+
rem letting a planted binary hijack the hook; an absolute path defeats that.
1228
rem
1329
rem The first argument is the .ps1 to run; any remaining arguments are forwarded.
1430
"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -ExecutionPolicy Bypass -File %*

0 commit comments

Comments
 (0)