greptile 1.0.5 → 2.0.0

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.
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ const { execFileSync } = require('child_process')
3
+ const path = require('path')
4
+
5
+ const script = path.join(__dirname, '..', 'greptile-fix')
6
+ try {
7
+ execFileSync(script, process.argv.slice(2), { stdio: 'inherit' })
8
+ } catch (e) {
9
+ process.exit(e.status || 1)
10
+ }
package/build-app.sh ADDED
@@ -0,0 +1,50 @@
1
+ #!/bin/bash
2
+ #
3
+ # build-app.sh — Builds the Greptile Fix .app bundle from AppleScript.
4
+ #
5
+ # This compiles greptile-fix.applescript into a macOS .app bundle,
6
+ # adds the greptile:// URL scheme to its Info.plist, and registers it
7
+ # with Launch Services so macOS knows to open it for greptile:// URLs.
8
+ #
9
+ # Usage: ./build-app.sh [output_dir]
10
+ # output_dir defaults to the current directory
11
+
12
+ set -euo pipefail
13
+
14
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
15
+ OUTPUT_DIR="${1:-$SCRIPT_DIR}"
16
+ APP_NAME="Greptile Fix"
17
+ APP_PATH="$OUTPUT_DIR/$APP_NAME.app"
18
+
19
+ echo "Building $APP_NAME.app..."
20
+
21
+ # 1. Compile AppleScript into .app bundle
22
+ if [ -d "$APP_PATH" ]; then
23
+ rm -rf "$APP_PATH"
24
+ fi
25
+
26
+ osacompile -o "$APP_PATH" "$SCRIPT_DIR/greptile-fix.applescript"
27
+
28
+ # 2. Add URL scheme to Info.plist
29
+ PLIST="$APP_PATH/Contents/Info.plist"
30
+
31
+ /usr/libexec/PlistBuddy -c "Add :CFBundleURLTypes array" "$PLIST"
32
+ /usr/libexec/PlistBuddy -c "Add :CFBundleURLTypes:0 dict" "$PLIST"
33
+ /usr/libexec/PlistBuddy -c "Add :CFBundleURLTypes:0:CFBundleURLName string com.greptile.fix" "$PLIST"
34
+ /usr/libexec/PlistBuddy -c "Add :CFBundleURLTypes:0:CFBundleURLSchemes array" "$PLIST"
35
+ /usr/libexec/PlistBuddy -c "Add :CFBundleURLTypes:0:CFBundleURLSchemes:0 string greptile" "$PLIST"
36
+
37
+ # Set a bundle identifier
38
+ /usr/libexec/PlistBuddy -c "Add :CFBundleIdentifier string com.greptile.fix" "$PLIST" 2>/dev/null || \
39
+ /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier com.greptile.fix" "$PLIST"
40
+
41
+ echo "URL scheme added to Info.plist"
42
+
43
+ # 3. Register with Launch Services
44
+ /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -R "$APP_PATH"
45
+
46
+ echo "Registered with Launch Services"
47
+ echo ""
48
+ echo "Built: $APP_PATH"
49
+ echo ""
50
+ echo "To test: open 'greptile://claude-code?prompt=hello&repo=test/repo'"
package/greptile-fix ADDED
@@ -0,0 +1,222 @@
1
+ #!/bin/bash
2
+ #
3
+ # greptile-fix — Bridge script for "Fix in <IDE>" links.
4
+ #
5
+ # Receives greptile://<ide>?prompt=...&repo=... URLs from the macOS URL scheme handler,
6
+ # looks up the local repo path, and opens the appropriate CLI in Terminal with the prompt.
7
+ #
8
+ # Supported URL paths:
9
+ # greptile://claude-code?prompt=... → opens `claude` CLI
10
+ # greptile://codex?prompt=... → opens `codex` CLI
11
+ # greptile://fix?prompt=... → opens `claude` CLI (legacy)
12
+ #
13
+ # Repo path mappings are stored in ~/.greptile/repos.json.
14
+ # On first use for a repo, a Finder dialog asks the user to select the local folder.
15
+
16
+ set -euo pipefail
17
+
18
+ CONFIG_DIR="$HOME/.greptile"
19
+ REPOS_FILE="$CONFIG_DIR/repos.json"
20
+ LOG_FILE="/tmp/greptile-fix.log"
21
+
22
+ log() {
23
+ echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG_FILE"
24
+ }
25
+
26
+ # URL-decode a string (percent-decode)
27
+ urldecode() {
28
+ local encoded="$1"
29
+ # Use Python for reliable percent-decoding
30
+ python3 -c "import urllib.parse, sys; print(urllib.parse.unquote(sys.argv[1]))" "$encoded"
31
+ }
32
+
33
+ # Parse query parameters from a URL
34
+ parse_url_param() {
35
+ local url="$1"
36
+ local param_name="$2"
37
+
38
+ # Extract everything after '?'
39
+ local query_string="${url#*\?}"
40
+ if [ "$query_string" = "$url" ]; then
41
+ # No query string
42
+ return
43
+ fi
44
+
45
+ # Split by '&' and find the parameter
46
+ local IFS='&'
47
+ for pair in $query_string; do
48
+ local key="${pair%%=*}"
49
+ local value="${pair#*=}"
50
+ if [ "$key" = "$param_name" ]; then
51
+ urldecode "$value"
52
+ return
53
+ fi
54
+ done
55
+ }
56
+
57
+ # Ensure config directory exists
58
+ ensure_config_dir() {
59
+ if [ ! -d "$CONFIG_DIR" ]; then
60
+ mkdir -p "$CONFIG_DIR"
61
+ fi
62
+ if [ ! -f "$REPOS_FILE" ]; then
63
+ echo '{}' > "$REPOS_FILE"
64
+ fi
65
+ }
66
+
67
+ # Look up local path for a repo from repos.json
68
+ lookup_repo_path() {
69
+ local repo="$1"
70
+ python3 -c "
71
+ import json, sys, os
72
+ repos_file = os.path.expanduser(sys.argv[2])
73
+ try:
74
+ with open(repos_file) as f:
75
+ data = json.load(f)
76
+ path = data.get(sys.argv[1], '')
77
+ if path:
78
+ print(path)
79
+ except:
80
+ pass
81
+ " "$repo" "$REPOS_FILE"
82
+ }
83
+
84
+ # Save a repo path mapping
85
+ save_repo_path() {
86
+ local repo="$1"
87
+ local path="$2"
88
+ python3 -c "
89
+ import json, sys, os
90
+ repos_file = os.path.expanduser(sys.argv[3])
91
+ try:
92
+ with open(repos_file) as f:
93
+ data = json.load(f)
94
+ except:
95
+ data = {}
96
+ data[sys.argv[1]] = sys.argv[2]
97
+ with open(repos_file, 'w') as f:
98
+ json.dump(data, f, indent=2)
99
+ " "$repo" "$path" "$REPOS_FILE"
100
+ }
101
+
102
+ # Ask user to select a folder via macOS Finder dialog
103
+ ask_for_repo_folder() {
104
+ local repo="$1"
105
+ # Pass repo name safely via environment variable to avoid AppleScript injection
106
+ GREPTILE_REPO_NAME="$repo" osascript -e '
107
+ set repoName to system attribute "GREPTILE_REPO_NAME"
108
+ set chosenFolder to choose folder with prompt ("Select the local folder for " & repoName) default location (path to home folder)
109
+ return POSIX path of chosenFolder
110
+ ' 2>/dev/null
111
+ }
112
+
113
+ # Create a self-contained runner script that opens the CLI with the prompt.
114
+ # Prints the runner path to stdout so the caller (AppleScript) can execute it in Terminal.
115
+ create_runner_script() {
116
+ local repo_path="$1"
117
+ local prompt="$2"
118
+ local cli_cmd="$3"
119
+
120
+ # Write args to a temp file — avoids all shell quoting issues.
121
+ # Line 1: repo path, Line 2+: prompt (may be multiline)
122
+ local argsfile
123
+ argsfile=$(mktemp /tmp/greptile-fix-args-XXXXXX)
124
+ printf '%s\n' "$repo_path" > "$argsfile"
125
+ printf '%s' "$prompt" >> "$argsfile"
126
+
127
+ # Write a runner script that reads args from the file, then cleans up
128
+ local runner
129
+ runner=$(mktemp /tmp/greptile-fix-run-XXXXXX)
130
+ chmod +x "$runner"
131
+
132
+ # Note: $argsfile and $cli_cmd are safe to interpolate (mktemp path and validated CLI name)
133
+ cat > "$runner" <<RUNNER_EOF
134
+ #!/bin/bash
135
+ ARGSFILE="$argsfile"
136
+ REPO_PATH=\$(head -1 "\$ARGSFILE")
137
+ PROMPT=\$(tail -n +2 "\$ARGSFILE")
138
+ rm -f "\$ARGSFILE"
139
+ cd "\$REPO_PATH" || exit 1
140
+ $cli_cmd "\$PROMPT"
141
+ rm -f "\$0"
142
+ RUNNER_EOF
143
+
144
+ # Print the runner path — the AppleScript app will use this to open Terminal
145
+ echo "$runner"
146
+ }
147
+
148
+ # --- Main ---
149
+
150
+ log "greptile-fix invoked with: $*"
151
+
152
+ if [ $# -lt 1 ]; then
153
+ log "ERROR: No URL argument provided"
154
+ echo "Usage: greptile-fix 'greptile://claude-code?prompt=...&repo=...'" >&2
155
+ exit 1
156
+ fi
157
+
158
+ URL="$1"
159
+
160
+ # Determine IDE from URL path (greptile://<path>?...)
161
+ # Extract the path segment between :// and ?
162
+ URL_PATH="${URL#*://}" # remove scheme prefix
163
+ URL_PATH="${URL_PATH%%\?*}" # remove query string
164
+
165
+ case "$URL_PATH" in
166
+ codex) IDE="codex" ;;
167
+ claude-code) IDE="claude" ;;
168
+ *) IDE="claude" ;; # legacy "fix" path and fallback
169
+ esac
170
+
171
+ # Parse URL parameters
172
+ PROMPT=$(parse_url_param "$URL" "prompt")
173
+ REPO=$(parse_url_param "$URL" "repo")
174
+
175
+ if [ -z "$PROMPT" ]; then
176
+ log "ERROR: No prompt parameter in URL"
177
+ osascript -e 'display dialog "Greptile Fix: No prompt found in the URL." buttons {"OK"} default button "OK" with icon caution'
178
+ exit 1
179
+ fi
180
+
181
+ log "Prompt: ${PROMPT:0:100}..."
182
+ log "Repo: $REPO"
183
+
184
+ ensure_config_dir
185
+
186
+ # Determine local repo path
187
+ REPO_PATH=""
188
+ if [ -n "$REPO" ]; then
189
+ REPO_PATH=$(lookup_repo_path "$REPO")
190
+
191
+ if [ -z "$REPO_PATH" ] || [ ! -d "$REPO_PATH" ]; then
192
+ log "Repo path not found or invalid for $REPO, asking user..."
193
+ REPO_PATH=$(ask_for_repo_folder "$REPO")
194
+
195
+ if [ -z "$REPO_PATH" ]; then
196
+ log "User cancelled folder selection"
197
+ exit 0
198
+ fi
199
+
200
+ # Remove trailing slash if present
201
+ REPO_PATH="${REPO_PATH%/}"
202
+
203
+ save_repo_path "$REPO" "$REPO_PATH"
204
+ log "Saved repo path: $REPO -> $REPO_PATH"
205
+ fi
206
+ fi
207
+
208
+ # Fallback: if no repo was specified, use current directory
209
+ if [ -z "$REPO_PATH" ]; then
210
+ REPO_PATH="$HOME"
211
+ log "No repo specified, using home directory"
212
+ fi
213
+
214
+ log "Creating runner script for: $REPO_PATH (IDE: $IDE)"
215
+ RUNNER=$(create_runner_script "$REPO_PATH" "$PROMPT" "$IDE")
216
+ log "Runner script: $RUNNER"
217
+
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).
221
+ echo "$RUNNER"
222
+ log "Done"
@@ -0,0 +1,23 @@
1
+ -- greptile-fix.applescript
2
+ -- URL scheme handler for greptile:// protocol.
3
+ -- Compiled into a .app bundle that registers the URL scheme with macOS.
4
+ --
5
+ -- Flow:
6
+ -- 1. macOS sends us the greptile:// URL
7
+ -- 2. We call greptile-fix CLI to parse the URL, resolve the repo path, and create a runner script
8
+ -- 3. greptile-fix prints the runner script path to stdout
9
+ -- 4. We open Terminal with the runner script using "open -a Terminal" (no Automation permission needed)
10
+
11
+ on open location theURL
12
+ try
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"
15
+
16
+ if runnerPath is not "" then
17
+ -- Use "open -a Terminal" instead of "tell application Terminal" to avoid Automation permission
18
+ do shell script "open -a Terminal " & quoted form of runnerPath
19
+ end if
20
+ on error errMsg
21
+ do shell script "echo '[ERROR] " & errMsg & "' >> /tmp/greptile-fix.log"
22
+ end try
23
+ end open location
package/package.json CHANGED
@@ -1,45 +1,37 @@
1
1
  {
2
2
  "name": "greptile",
3
- "version": "1.0.5",
4
- "main": "index.js",
3
+ "version": "2.0.0",
4
+ "description": "Bridge for Greptile code review 'Fix in Claude Code' and 'Fix in Codex' links",
5
5
  "bin": {
6
- "greptile": "./bin/index.js"
6
+ "greptile-fix": "bin/greptile-fix.js"
7
7
  },
8
- "type": "module",
9
8
  "scripts": {
10
- "test": "echo \"Error: no test specified\" && exit 1"
9
+ "postinstall": "bash postinstall.sh",
10
+ "preuninstall": "bash preuninstall.sh"
11
11
  },
12
- "assets": [
13
- "bin/config.json"
12
+ "files": [
13
+ "greptile-fix",
14
+ "bin/",
15
+ "greptile-fix.applescript",
16
+ "build-app.sh",
17
+ "postinstall.sh",
18
+ "preuninstall.sh"
14
19
  ],
15
- "author": "greptile.com",
16
- "license": "ISC",
17
- "dependencies": {
18
- "@octokit/rest": "^20.0.2",
19
- "axios": "^1.6.7",
20
- "cli-spinners": "^2.9.2",
21
- "clipboardy": "^2.3.0",
22
- "express": "^4.18.2",
23
- "greptile": "^1.0.3",
24
- "js-base64": "^3.7.6",
25
- "node-fetch": "^2.7.0",
26
- "open": "^8.4.0",
27
- "ora": "^5.4.1",
28
- "punycode": "^2.3.1",
29
- "shelljs": "^0.8.4",
30
- "yargs": "^17.7.2"
31
- },
32
- "description": "",
33
- "pkg": {
34
- "targets": [
35
- "node14-linux-x64",
36
- "node14-macos-x64",
37
- "node14-win-x64"
38
- ],
39
- "outputPath": "release",
40
- "scripts": [
41
- "bin/index.js",
42
- "bin/config.json"
43
- ]
20
+ "os": [
21
+ "darwin"
22
+ ],
23
+ "keywords": [
24
+ "greptile",
25
+ "code-review",
26
+ "claude-code",
27
+ "codex",
28
+ "ide"
29
+ ],
30
+ "license": "MIT",
31
+ "homepage": "https://greptile.com",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git+https://github.com/greptileai/greptilia.git",
35
+ "directory": "tools/greptile-cli"
44
36
  }
45
37
  }
package/postinstall.sh ADDED
@@ -0,0 +1,28 @@
1
+ #!/bin/bash
2
+ #
3
+ # postinstall.sh — Builds and registers the Greptile Fix .app bundle after npm install.
4
+ #
5
+ # The .app bundle handles the greptile:// URL scheme on macOS.
6
+ # It is installed to ~/Applications so it persists independently of npm.
7
+
8
+ set -euo pipefail
9
+
10
+ # Only run on macOS
11
+ if [ "$(uname)" != "Darwin" ]; then
12
+ echo "greptile: Skipping .app bundle setup (macOS only)"
13
+ exit 0
14
+ fi
15
+
16
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
17
+ APP_DIR="$HOME/Applications"
18
+
19
+ # Ensure ~/Applications exists
20
+ mkdir -p "$APP_DIR"
21
+
22
+ # Build the .app bundle into ~/Applications
23
+ bash "$SCRIPT_DIR/build-app.sh" "$APP_DIR"
24
+
25
+ echo ""
26
+ echo "Repo path mappings are stored in ~/.greptile/repos.json."
27
+ echo "The first time you click 'Fix in Claude Code' for a repo,"
28
+ echo "you'll be asked to select the local folder for that repo."
@@ -0,0 +1,10 @@
1
+ #!/bin/bash
2
+ #
3
+ # preuninstall.sh — Removes the Greptile Fix .app bundle on npm uninstall.
4
+
5
+ APP_PATH="$HOME/Applications/Greptile Fix.app"
6
+
7
+ if [ -d "$APP_PATH" ]; then
8
+ rm -rf "$APP_PATH"
9
+ echo "Removed: $APP_PATH"
10
+ fi
package/README.md DELETED
@@ -1,114 +0,0 @@
1
-
2
- # Greptile CLI
3
-
4
- Greptile is a Command Line Interface (CLI) that enables developers to search and understand complex codebases in English. Learn more at [greptile.com](https://greptile.com).
5
-
6
- ## Quickstart
7
-
8
- 1. **Install greptile via `npm`:**
9
-
10
- ```bash
11
- npm install -g greptile
12
- greptile addPath
13
- ```
14
-
15
- This ensures Greptile is in your system's PATH for global usage. Without the addPath command, you will not be able to use the CLI tool..
16
-
17
- 2. **Authenticate with GitHub:**
18
-
19
- ```bash
20
- greptile auth
21
- ```
22
-
23
- 3. **Add repositories to the chat session:**
24
-
25
- ```bash
26
- greptile add [repo link or owner/repo]
27
- ```
28
-
29
- - For example:
30
-
31
- ```bash
32
- greptile add https://github.com/facebook/react
33
- ```
34
-
35
- - or
36
-
37
- ```bash
38
- greptile add facebook/react
39
- ```
40
-
41
- You can add up to 10 repositories to the session.
42
-
43
- 4. **Begin!**
44
-
45
- ```bash
46
- greptile start
47
- ```
48
-
49
- This launches a shell allowing you to ask questions to Greptile's AI with full context of the provided repositories.
50
-
51
- If you have any questions or comments, email us at founders@getonboardai.com.
52
-
53
- ## How to Run
54
-
55
- You can run Greptile using the following commands:
56
-
57
- ### Authentication
58
-
59
- To authenticate with GitHub, use the following command:
60
-
61
- ```bash
62
- greptile auth
63
- ```
64
-
65
- ### Adding a Repository
66
-
67
- To add a repository to the session, use the following command:
68
-
69
- ```bash
70
- greptile add <repository_link or owner/repo>
71
- ```
72
-
73
- Replace `<repository_link>` with the GitHub repository URL or `<owner/repo>` with the owner and repository name.
74
-
75
- ### Listing Repositories
76
-
77
- To list repositories in the current session, use the following command:
78
-
79
- ```bash
80
- greptile list
81
- ```
82
-
83
- ### Removing a Repository
84
-
85
- To remove a repository from the session, use the following command:
86
-
87
- ```bash
88
- greptile remove <repository_link or owner/repo>
89
- ```
90
-
91
- Replace `<repository_link>` with the GitHub repository URL or `<owner/repo>` with the owner and repository name.
92
-
93
- ### Starting Greptile
94
-
95
- To start the Greptile application and interact with the repositories, use the following command:
96
-
97
- ```bash
98
- greptile start
99
- ```
100
-
101
- Follow the prompts to ask questions and retrieve information from the added repositories.
102
-
103
- ### Help
104
-
105
- To display help information, use the following command:
106
-
107
- ```bash
108
- greptile help
109
- ```
110
-
111
- Feel free to explore and interact with Greptile to manage your repositories efficiently!
112
- ```
113
-
114
- This version focuses on the essential information and improves the overall organization.
package/addToPath.sh DELETED
@@ -1,13 +0,0 @@
1
- #!/bin/bash
2
-
3
- # Get the current directory
4
- CURRENT_DIR=$(dirname "$(readlink -f "$0")")
5
-
6
- # Check if the current directory is already in the PATH
7
- if [[ ":$PATH:" == *":$CURRENT_DIR:"* ]]; then
8
- echo "Current directory '$CURRENT_DIR' is already in the PATH."
9
- else
10
- # Add the current directory to the PATH in ~/.bashrc
11
- echo "export PATH=$CURRENT_DIR:\$PATH" >> ~/.bashrc
12
- echo "Current directory '$CURRENT_DIR' added to the PATH in ~/.bashrc. Changes will take effect after restarting the terminal."
13
- fi