greptile 2.2.0 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/com.greptile.health.plist +23 -0
- package/greptile-fix +3 -39
- package/greptile-fix.applescript +34 -8
- package/health-server.js +60 -0
- package/package.json +4 -2
- package/postinstall.sh +23 -0
- package/preuninstall.sh +8 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>Label</key>
|
|
6
|
+
<string>com.greptile.health</string>
|
|
7
|
+
<key>ProgramArguments</key>
|
|
8
|
+
<array>
|
|
9
|
+
<string>/usr/local/bin/node</string>
|
|
10
|
+
<string>health-server.js</string>
|
|
11
|
+
</array>
|
|
12
|
+
<key>WorkingDirectory</key>
|
|
13
|
+
<string>__PACKAGE_DIR__</string>
|
|
14
|
+
<key>RunAtLoad</key>
|
|
15
|
+
<true/>
|
|
16
|
+
<key>KeepAlive</key>
|
|
17
|
+
<true/>
|
|
18
|
+
<key>StandardOutPath</key>
|
|
19
|
+
<string>/tmp/greptile-health.log</string>
|
|
20
|
+
<key>StandardErrorPath</key>
|
|
21
|
+
<string>/tmp/greptile-health.log</string>
|
|
22
|
+
</dict>
|
|
23
|
+
</plist>
|
package/greptile-fix
CHANGED
|
@@ -215,44 +215,8 @@ log "Creating runner script for: $REPO_PATH (IDE: $IDE)"
|
|
|
215
215
|
RUNNER=$(create_runner_script "$REPO_PATH" "$PROMPT" "$IDE")
|
|
216
216
|
log "Runner script: $RUNNER"
|
|
217
217
|
|
|
218
|
-
#
|
|
219
|
-
#
|
|
220
|
-
|
|
221
|
-
# Map of process names to "open -a" app names
|
|
222
|
-
local process_names=("iTerm2" "Ghostty" "Warp" "kitty" "WezTerm" "Alacritty" "Terminal")
|
|
223
|
-
local app_names=( "iTerm" "Ghostty" "Warp" "kitty" "WezTerm" "Alacritty" "Terminal")
|
|
224
|
-
|
|
225
|
-
# Check if frontmost app is a terminal
|
|
226
|
-
local front_asn
|
|
227
|
-
front_asn=$(lsappinfo front 2>/dev/null)
|
|
228
|
-
if [ -n "$front_asn" ]; then
|
|
229
|
-
local front_name
|
|
230
|
-
front_name=$(lsappinfo info -only name "$front_asn" 2>/dev/null | sed 's/.*="\(.*\)"/\1/')
|
|
231
|
-
for i in "${!process_names[@]}"; do
|
|
232
|
-
if [ "$front_name" = "${process_names[$i]}" ]; then
|
|
233
|
-
echo "${app_names[$i]}"
|
|
234
|
-
return
|
|
235
|
-
fi
|
|
236
|
-
done
|
|
237
|
-
fi
|
|
238
|
-
|
|
239
|
-
# Check for first running terminal
|
|
240
|
-
local running
|
|
241
|
-
running=$(lsappinfo list 2>/dev/null)
|
|
242
|
-
for i in "${!process_names[@]}"; do
|
|
243
|
-
if echo "$running" | grep -q "\"${process_names[$i]}\""; then
|
|
244
|
-
echo "${app_names[$i]}"
|
|
245
|
-
return
|
|
246
|
-
fi
|
|
247
|
-
done
|
|
248
|
-
|
|
249
|
-
echo "Terminal"
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
TERM_APP=$(detect_terminal)
|
|
253
|
-
log "Detected terminal: $TERM_APP"
|
|
254
|
-
|
|
255
|
-
# Print terminal app and runner path (two lines) — the AppleScript reads both.
|
|
256
|
-
echo "$TERM_APP"
|
|
218
|
+
# Print the runner path to stdout — the AppleScript app reads this
|
|
219
|
+
# and uses it to open Terminal (which requires Automation permission
|
|
220
|
+
# that only the .app bundle has).
|
|
257
221
|
echo "$RUNNER"
|
|
258
222
|
log "Done"
|
package/greptile-fix.applescript
CHANGED
|
@@ -5,19 +5,45 @@
|
|
|
5
5
|
-- Flow:
|
|
6
6
|
-- 1. macOS sends us the greptile:// URL
|
|
7
7
|
-- 2. We call greptile-fix CLI to parse the URL, resolve the repo path, and create a runner script
|
|
8
|
-
-- 3. greptile-fix
|
|
9
|
-
--
|
|
10
|
-
-- line 2: runner script path
|
|
11
|
-
-- 4. We open the runner script with "open -a <terminal>"
|
|
8
|
+
-- 3. greptile-fix prints the runner script path to stdout
|
|
9
|
+
-- 4. We detect the user's terminal and open the runner script with "open -a <terminal>"
|
|
12
10
|
|
|
13
11
|
on open location theURL
|
|
14
12
|
try
|
|
15
|
-
-- Call greptile-fix
|
|
16
|
-
set
|
|
17
|
-
|
|
18
|
-
set {termApp, runnerPath} to {paragraph 1 of outputLines, paragraph 2 of outputLines}
|
|
13
|
+
-- Call greptile-fix to parse URL and create runner script; it prints the runner path to stdout
|
|
14
|
+
set runnerPath to do shell script "PATH=/opt/homebrew/bin:/usr/local/bin:$PATH greptile-fix " & quoted form of theURL & " 2>> /tmp/greptile-fix.log"
|
|
19
15
|
|
|
20
16
|
if runnerPath is not "" then
|
|
17
|
+
-- Detect terminal app: prefer frontmost if it's a terminal, else first running terminal, else Terminal.app
|
|
18
|
+
set termApp to "Terminal"
|
|
19
|
+
set knownTerminals to {"iTerm2", "Ghostty", "Warp", "kitty", "WezTerm", "Alacritty", "Terminal"}
|
|
20
|
+
-- Map process names to the app name expected by "open -a"
|
|
21
|
+
-- (iTerm2's process name is "iTerm2" but the app name is "iTerm")
|
|
22
|
+
set termAppNames to {"iTerm", "Ghostty", "Warp", "kitty", "WezTerm", "Alacritty", "Terminal"}
|
|
23
|
+
try
|
|
24
|
+
tell application "System Events"
|
|
25
|
+
set frontName to name of first application process whose frontmost is true
|
|
26
|
+
set runningApps to name of every application process whose background only is false
|
|
27
|
+
end tell
|
|
28
|
+
-- If the frontmost app is a known terminal, use it
|
|
29
|
+
set foundFront to false
|
|
30
|
+
repeat with i from 1 to count of knownTerminals
|
|
31
|
+
if frontName is equal to item i of knownTerminals then
|
|
32
|
+
set termApp to item i of termAppNames
|
|
33
|
+
set foundFront to true
|
|
34
|
+
exit repeat
|
|
35
|
+
end if
|
|
36
|
+
end repeat
|
|
37
|
+
-- Otherwise pick the first running terminal we recognize
|
|
38
|
+
if not foundFront then
|
|
39
|
+
repeat with i from 1 to count of knownTerminals
|
|
40
|
+
if item i of knownTerminals is in runningApps then
|
|
41
|
+
set termApp to item i of termAppNames
|
|
42
|
+
exit repeat
|
|
43
|
+
end if
|
|
44
|
+
end repeat
|
|
45
|
+
end if
|
|
46
|
+
end try
|
|
21
47
|
do shell script "open -a " & quoted form of termApp & " " & quoted form of runnerPath
|
|
22
48
|
end if
|
|
23
49
|
on error errMsg
|
package/health-server.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const http = require('http')
|
|
3
|
+
const fs = require('fs')
|
|
4
|
+
const path = require('path')
|
|
5
|
+
|
|
6
|
+
const PORT = 4747
|
|
7
|
+
|
|
8
|
+
// Self-destruct: if the package has been uninstalled (package.json gone),
|
|
9
|
+
// clean up the LaunchAgent and exit so the health server doesn't linger.
|
|
10
|
+
const PACKAGE_MARKER = path.join(__dirname, 'package.json')
|
|
11
|
+
const SELF_CHECK_INTERVAL_MS = 30_000
|
|
12
|
+
|
|
13
|
+
function selfCheck() {
|
|
14
|
+
if (!fs.existsSync(PACKAGE_MARKER)) {
|
|
15
|
+
console.log('Package uninstalled — cleaning up and exiting.')
|
|
16
|
+
const plistPath = path.join(
|
|
17
|
+
process.env.HOME || '',
|
|
18
|
+
'Library/LaunchAgents/com.greptile.health.plist'
|
|
19
|
+
)
|
|
20
|
+
try { fs.unlinkSync(plistPath) } catch {}
|
|
21
|
+
server.close()
|
|
22
|
+
process.exit(0)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const server = http.createServer((req, res) => {
|
|
27
|
+
res.setHeader('Access-Control-Allow-Origin', '*')
|
|
28
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS')
|
|
29
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type')
|
|
30
|
+
|
|
31
|
+
if (req.method === 'OPTIONS') {
|
|
32
|
+
res.writeHead(204)
|
|
33
|
+
res.end()
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (req.method === 'GET' && req.url === '/health') {
|
|
38
|
+
res.writeHead(200, { 'Content-Type': 'application/json' })
|
|
39
|
+
res.end(JSON.stringify({ status: 'ok' }))
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
res.writeHead(404)
|
|
44
|
+
res.end()
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
server.on('error', (err) => {
|
|
48
|
+
if (err.code === 'EADDRINUSE') {
|
|
49
|
+
console.error(`Port ${PORT} is already in use. Exiting.`)
|
|
50
|
+
process.exit(0) // Exit cleanly so launchd KeepAlive doesn't restart in a tight loop
|
|
51
|
+
}
|
|
52
|
+
console.error('Health server error:', err.message)
|
|
53
|
+
process.exit(1)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
server.listen(PORT, '127.0.0.1', () => {
|
|
57
|
+
console.log(`Greptile health server listening on http://127.0.0.1:${PORT}`)
|
|
58
|
+
// Start self-check loop after server is up
|
|
59
|
+
setInterval(selfCheck, SELF_CHECK_INTERVAL_MS)
|
|
60
|
+
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "greptile",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.2",
|
|
4
4
|
"description": "Bridge for Greptile code review 'Fix in Claude Code' and 'Fix in Codex' links",
|
|
5
5
|
"bin": {
|
|
6
6
|
"greptile-fix": "bin/greptile-fix.js"
|
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
"greptile-fix.applescript",
|
|
16
16
|
"build-app.sh",
|
|
17
17
|
"postinstall.sh",
|
|
18
|
-
"preuninstall.sh"
|
|
18
|
+
"preuninstall.sh",
|
|
19
|
+
"health-server.js",
|
|
20
|
+
"com.greptile.health.plist"
|
|
19
21
|
],
|
|
20
22
|
"os": [
|
|
21
23
|
"darwin"
|
package/postinstall.sh
CHANGED
|
@@ -22,6 +22,29 @@ mkdir -p "$APP_DIR"
|
|
|
22
22
|
# Build the .app bundle into ~/Applications
|
|
23
23
|
bash "$SCRIPT_DIR/build-app.sh" "$APP_DIR"
|
|
24
24
|
|
|
25
|
+
# --- Health server LaunchAgent ---
|
|
26
|
+
PLIST_NAME="com.greptile.health.plist"
|
|
27
|
+
PLIST_SRC="$SCRIPT_DIR/$PLIST_NAME"
|
|
28
|
+
PLIST_DST="$HOME/Library/LaunchAgents/$PLIST_NAME"
|
|
29
|
+
|
|
30
|
+
if [ -f "$PLIST_SRC" ]; then
|
|
31
|
+
# Ensure LaunchAgents directory exists
|
|
32
|
+
mkdir -p "$HOME/Library/LaunchAgents"
|
|
33
|
+
|
|
34
|
+
# Resolve the node binary path
|
|
35
|
+
NODE_BIN="$(command -v node 2>/dev/null || echo "/usr/local/bin/node")"
|
|
36
|
+
|
|
37
|
+
# Create a configured copy with the correct paths
|
|
38
|
+
sed -e "s|__PACKAGE_DIR__|$SCRIPT_DIR|g" \
|
|
39
|
+
-e "s|/usr/local/bin/node|$NODE_BIN|g" \
|
|
40
|
+
"$PLIST_SRC" > "$PLIST_DST"
|
|
41
|
+
|
|
42
|
+
# Load the agent (unload first in case it's already loaded)
|
|
43
|
+
launchctl unload "$PLIST_DST" 2>/dev/null || true
|
|
44
|
+
launchctl load "$PLIST_DST"
|
|
45
|
+
echo "Greptile health server installed and started."
|
|
46
|
+
fi
|
|
47
|
+
|
|
25
48
|
echo ""
|
|
26
49
|
echo "Repo path mappings are stored in ~/.greptile/repos.json."
|
|
27
50
|
echo "The first time you click 'Fix in Claude Code' for a repo,"
|
package/preuninstall.sh
CHANGED
|
@@ -13,3 +13,11 @@ if [ -d "$APP_PATH" ]; then
|
|
|
13
13
|
rm -rf "$APP_PATH"
|
|
14
14
|
echo "Removed: $APP_PATH"
|
|
15
15
|
fi
|
|
16
|
+
|
|
17
|
+
# --- Health server LaunchAgent ---
|
|
18
|
+
PLIST_PATH="$HOME/Library/LaunchAgents/com.greptile.health.plist"
|
|
19
|
+
if [ -f "$PLIST_PATH" ]; then
|
|
20
|
+
launchctl unload "$PLIST_PATH" 2>/dev/null || true
|
|
21
|
+
rm -f "$PLIST_PATH"
|
|
22
|
+
echo "Removed Greptile health server LaunchAgent."
|
|
23
|
+
fi
|