@mrkaran/hodor 0.4.1 → 0.6.1
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/README.md +177 -53
- package/dist/chunk-AMUK6GDX.js +23 -0
- package/dist/chunk-AMUK6GDX.js.map +1 -0
- package/dist/chunk-DVJVQTVW.js +731 -0
- package/dist/chunk-DVJVQTVW.js.map +1 -0
- package/dist/{chunk-QGUJENIG.js → chunk-JSLG7EOX.js} +916 -471
- package/dist/chunk-JSLG7EOX.js.map +1 -0
- package/dist/cli.js +111 -22
- package/dist/cli.js.map +1 -1
- package/dist/codequality-DTJK2LGF.js +42 -0
- package/dist/codequality-DTJK2LGF.js.map +1 -0
- package/dist/gitlab-5TWHYHEP.js +33 -0
- package/dist/gitlab-5TWHYHEP.js.map +1 -0
- package/dist/index.d.ts +21 -13
- package/dist/index.js +5 -2
- package/package.json +13 -13
- package/templates/tool-review.md +39 -5
- package/dist/chunk-QGUJENIG.js.map +0 -1
package/README.md
CHANGED
|
@@ -2,100 +2,166 @@
|
|
|
2
2
|
|
|
3
3
|
# Hodor
|
|
4
4
|
|
|
5
|
-
> Agentic code reviewer for GitHub PRs, GitLab MRs, and local diffs. Powered by the [pi-coding-agent](https://github.com/badlogic/pi-mono) SDK.
|
|
5
|
+
> Agentic code reviewer for GitHub PRs, GitLab MRs, Gitea/Forgejo PRs, and local diffs. Powered by the [pi-coding-agent](https://github.com/badlogic/pi-mono) SDK.
|
|
6
6
|
|
|
7
7
|
Hodor runs as a stateful agent with tools (`bash`, `grep`, `read`, `git diff`) to autonomously analyze code changes, find bugs, and post structured reviews.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
#
|
|
12
|
+
# Just run it (zero install, always latest)
|
|
13
13
|
npx @mrkaran/hodor <PR_URL>
|
|
14
14
|
|
|
15
|
-
#
|
|
15
|
+
# Or install globally
|
|
16
16
|
npm install -g @mrkaran/hodor
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Docker images are also available at `ghcr.io/mr-karan/hodor:latest` for CI environments.
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
docker pull ghcr.io/mr-karan/hodor:latest
|
|
21
|
+
## Setup
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
```bash
|
|
24
|
+
# Set an API key for your LLM provider
|
|
25
|
+
export ANTHROPIC_API_KEY=sk-... # Anthropic (default)
|
|
26
|
+
export OPENAI_API_KEY=sk-... # OpenAI
|
|
27
|
+
export OPENROUTER_API_KEY=sk-or-... # OpenRouter (e.g., Kimi K2.6)
|
|
28
|
+
export AWS_PROFILE=default # AWS Bedrock (no API key needed)
|
|
29
|
+
|
|
30
|
+
# For posting reviews as comments
|
|
31
|
+
gh auth login # GitHub
|
|
32
|
+
glab auth login # GitLab
|
|
33
|
+
|
|
34
|
+
# For Gitea/Forgejo private repos or posting comments
|
|
35
|
+
export GITEA_TOKEN=your-token # or FORGEJO_TOKEN
|
|
24
36
|
```
|
|
25
37
|
|
|
26
38
|
## Usage
|
|
27
39
|
|
|
28
40
|
```bash
|
|
29
41
|
# Review a GitHub PR
|
|
30
|
-
hodor https://github.com/owner/repo/pull/123
|
|
42
|
+
npx @mrkaran/hodor https://github.com/owner/repo/pull/123
|
|
31
43
|
|
|
32
44
|
# Review a GitLab MR (including self-hosted)
|
|
33
|
-
hodor https://gitlab.example.com/org/project/-/merge_requests/42
|
|
45
|
+
npx @mrkaran/hodor https://gitlab.example.com/org/project/-/merge_requests/42
|
|
34
46
|
|
|
35
|
-
#
|
|
36
|
-
hodor
|
|
47
|
+
# Review a Gitea or Forgejo PR
|
|
48
|
+
npx @mrkaran/hodor https://git.example.com/owner/repo/pulls/123
|
|
37
49
|
|
|
38
|
-
#
|
|
39
|
-
hodor --
|
|
40
|
-
hodor --local --diff-against HEAD~1 # diff against specific ref
|
|
41
|
-
hodor --local --diff-against feature-branch
|
|
50
|
+
# Post the review as a PR/MR comment
|
|
51
|
+
npx @mrkaran/hodor <PR_URL> --post
|
|
42
52
|
|
|
43
53
|
# Use a different model
|
|
44
|
-
hodor <PR_URL> --model openai/gpt-5
|
|
45
|
-
hodor <PR_URL> --model bedrock/converse/anthropic.claude-sonnet-4-5-v2
|
|
54
|
+
npx @mrkaran/hodor <PR_URL> --model openai/gpt-5
|
|
55
|
+
npx @mrkaran/hodor <PR_URL> --model bedrock/converse/anthropic.claude-sonnet-4-5-v2
|
|
46
56
|
|
|
47
57
|
# Extended reasoning for complex PRs
|
|
48
|
-
hodor <PR_URL> --reasoning-effort high
|
|
49
|
-
hodor <PR_URL> --ultrathink
|
|
58
|
+
npx @mrkaran/hodor <PR_URL> --reasoning-effort high
|
|
50
59
|
|
|
51
60
|
# Custom review instructions
|
|
52
|
-
hodor <PR_URL> --prompt "Focus on SQL injection and auth bypasses"
|
|
53
|
-
hodor <PR_URL> --prompt-file .hodor/security-review.md
|
|
61
|
+
npx @mrkaran/hodor <PR_URL> --prompt "Focus on SQL injection and auth bypasses"
|
|
54
62
|
|
|
55
63
|
# Verbose mode (watch the agent think)
|
|
56
|
-
hodor <PR_URL> -v
|
|
64
|
+
npx @mrkaran/hodor <PR_URL> -v
|
|
57
65
|
```
|
|
58
66
|
|
|
59
|
-
|
|
67
|
+
> If you installed globally with `npm install -g`, replace `npx @mrkaran/hodor` with `hodor`.
|
|
68
|
+
|
|
69
|
+
## Local Mode
|
|
70
|
+
|
|
71
|
+
Review local git changes without a PR URL. Useful for pre-push reviews, Bitbucket PRs, or any git repo.
|
|
72
|
+
|
|
60
73
|
```bash
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
74
|
+
# Review uncommitted changes against origin/main (default)
|
|
75
|
+
npx @mrkaran/hodor --local
|
|
76
|
+
|
|
77
|
+
# Review against a specific branch or ref
|
|
78
|
+
npx @mrkaran/hodor --local --diff-against develop
|
|
79
|
+
npx @mrkaran/hodor --local --diff-against HEAD~3
|
|
80
|
+
|
|
81
|
+
# Review a feature branch against main
|
|
82
|
+
git checkout feature-branch
|
|
83
|
+
npx @mrkaran/hodor --local --diff-against origin/main
|
|
84
|
+
|
|
85
|
+
# Use a specific workspace directory
|
|
86
|
+
npx @mrkaran/hodor --local --workspace /path/to/repo
|
|
87
|
+
|
|
88
|
+
# Combine with other flags
|
|
89
|
+
npx @mrkaran/hodor --local --diff-against origin/main --model openai/gpt-5 -v
|
|
66
90
|
```
|
|
67
91
|
|
|
68
|
-
|
|
92
|
+
Local mode:
|
|
93
|
+
- Includes **uncommitted changes** (staged + unstaged), not just commits
|
|
94
|
+
- Auto-resolves to the **git repo root** (works from subdirectories)
|
|
95
|
+
- Skips PR metadata fetching and workspace cloning
|
|
96
|
+
- `--post` is disabled (no remote to post to)
|
|
69
97
|
|
|
70
|
-
|
|
98
|
+
## CLI Flags
|
|
71
99
|
|
|
72
100
|
| Flag | Default | Description |
|
|
73
101
|
|------|---------|-------------|
|
|
74
|
-
| `--model` | `anthropic/claude-sonnet-4-5` | LLM model
|
|
102
|
+
| `--model` | `anthropic/claude-sonnet-4-5-20250929` | LLM model as `provider/model-id`. Recommended: Anthropic, OpenAI, Bedrock, OpenRouter. Other pi-ai providers (e.g., Mistral, Gemini, xAI, Groq) are best-effort. See [docs/MODELS.md](./docs/MODELS.md). |
|
|
75
103
|
| `--reasoning-effort` | – | Extended thinking: `low`, `medium`, `high` |
|
|
76
104
|
| `--ultrathink` | Off | Maximum reasoning effort |
|
|
77
|
-
| `--local` | Off | Review local changes (no PR URL required) |
|
|
78
|
-
| `--diff-against` | `origin/main` | Git ref to diff against in local mode |
|
|
79
|
-
| `--post` | Off | Post review comment
|
|
105
|
+
| `--local` | Off | Review local git changes (no PR URL required) |
|
|
106
|
+
| `--diff-against` | `origin/main` | Git ref to diff against in `--local` mode |
|
|
107
|
+
| `--post` | Off | Post review as a comment on the PR/MR |
|
|
108
|
+
| `--review-style` | `hybrid` | GitLab posting style: `summary`, `inline`, or `hybrid` |
|
|
109
|
+
| `--code-quality` | – | Write a CodeClimate JSON artifact for GitLab code quality reports |
|
|
110
|
+
| `--commit-status` | Off | Post a pass/fail commit status to the GitLab MR head SHA |
|
|
80
111
|
| `--prompt` | – | Append custom instructions to the review prompt |
|
|
81
|
-
| `--prompt-file` | – |
|
|
82
|
-
| `--workspace` | Temp dir | Workspace directory (
|
|
112
|
+
| `--prompt-file` | – | Use a custom prompt file |
|
|
113
|
+
| `--workspace` | Temp dir | Workspace directory (reuse for faster multi-PR reviews) |
|
|
83
114
|
| `--bedrock-tags` | – | JSON cost allocation tags for AWS Bedrock |
|
|
84
|
-
| `--prometheus-push` | – | Push metrics to a Prometheus Pushgateway
|
|
115
|
+
| `--prometheus-push` | – | Push review metrics to a Prometheus Pushgateway or VictoriaMetrics import endpoint |
|
|
85
116
|
| `-v, --verbose` | Off | Stream agent reasoning and tool calls |
|
|
86
117
|
|
|
87
|
-
|
|
118
|
+
## Environment Variables
|
|
88
119
|
|
|
89
120
|
| Variable | Purpose |
|
|
90
121
|
|----------|---------|
|
|
91
122
|
| `ANTHROPIC_API_KEY` | Claude API key |
|
|
92
123
|
| `OPENAI_API_KEY` | OpenAI API key |
|
|
93
|
-
| `
|
|
94
|
-
|
|
|
124
|
+
| `OPENROUTER_API_KEY` | OpenRouter API key (for `openrouter/...` models, e.g. `openrouter/moonshotai/kimi-k2.6`) |
|
|
125
|
+
| Provider-specific keys | For best-effort pi-ai providers, use the env var pi-ai expects (e.g. `MISTRAL_API_KEY`, `GEMINI_API_KEY`, `XAI_API_KEY`, `GROQ_API_KEY`) |
|
|
126
|
+
| `LLM_API_KEY` | Generic fallback (when provider-specific key is not set) |
|
|
127
|
+
| `GITHUB_TOKEN` / `GITLAB_TOKEN` | Post comments to GitHub PRs / GitLab MRs (with `--post`) |
|
|
128
|
+
| `GITEA_TOKEN` / `FORGEJO_TOKEN` | Read private repos and post comments on Gitea/Forgejo PRs |
|
|
129
|
+
| `GITEA_HOST` / `FORGEJO_HOST` | Hostname for Gitea/Forgejo when not inferable from a full PR URL |
|
|
95
130
|
| `AWS_PROFILE` or `AWS_ACCESS_KEY_ID` | AWS Bedrock auth (no API key needed) |
|
|
96
131
|
|
|
132
|
+
See [docs/MODELS.md](./docs/MODELS.md) for the full model/provider matrix and [docs/OPENROUTER.md](./docs/OPENROUTER.md) for an end-to-end Kimi K2.6 example.
|
|
133
|
+
|
|
134
|
+
## Gitea / Forgejo
|
|
135
|
+
|
|
136
|
+
Hodor supports Gitea and Forgejo pull request URLs in this format:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
npx @mrkaran/hodor https://git.example.com/owner/repo/pulls/123
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
For public repositories, metadata fetching may work without a token. Set `GITEA_TOKEN` or `FORGEJO_TOKEN` for private repositories, higher API limits, and `--post`:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
export GITEA_TOKEN=your-token
|
|
146
|
+
npx @mrkaran/hodor https://git.example.com/owner/repo/pulls/123 --post
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Fork PRs are checked out from the PR source repository when Gitea exposes the source clone URL. If the source branch or fork has been deleted, checkout will fail with a workspace error.
|
|
150
|
+
|
|
97
151
|
## CI/CD
|
|
98
152
|
|
|
153
|
+
### Metrics in CI
|
|
154
|
+
|
|
155
|
+
Hodor can push per-review metrics at the end of a CI run to either a Prometheus Pushgateway base URL or a VictoriaMetrics Prometheus import endpoint (`/api/v1/import/prometheus`):
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
hodor "$MR_OR_PR_URL" --prometheus-push "$METRICS_PUSH_URL"
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
In CI, set `METRICS_PUSH_URL` as a secret/variable and add `--prometheus-push "$METRICS_PUSH_URL"` to the Hodor command. Metrics are best-effort: push failures are logged as warnings and do not fail the review job.
|
|
162
|
+
|
|
163
|
+
Each metric is labeled with `platform`, `model`, `verdict`, and for PR/MR URLs also `project` (`owner/repo`) and `mr_iid`/PR number. Exported metrics include token usage, cache read/write tokens, cache hit ratio, cost, turns, tool calls, duration, and findings by priority (`P0`–`P3`). A generic Grafana dashboard is available in [`docs/grafana/`](./docs/grafana/).
|
|
164
|
+
|
|
99
165
|
### GitHub Actions
|
|
100
166
|
|
|
101
167
|
```yaml
|
|
@@ -113,42 +179,66 @@ jobs:
|
|
|
113
179
|
env:
|
|
114
180
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
115
181
|
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
182
|
+
METRICS_PUSH_URL: ${{ secrets.METRICS_PUSH_URL }} # optional
|
|
116
183
|
run: |
|
|
117
|
-
|
|
184
|
+
EXTRA_ARGS=""
|
|
185
|
+
if [ -n "${METRICS_PUSH_URL:-}" ]; then EXTRA_ARGS="--prometheus-push $METRICS_PUSH_URL"; fi
|
|
186
|
+
bun run /app/dist/cli.js "https://github.com/${{ github.repository }}/pull/${{ github.event.pull_request.number }}" --post $EXTRA_ARGS
|
|
118
187
|
```
|
|
119
188
|
|
|
120
189
|
### GitLab CI
|
|
121
190
|
|
|
122
191
|
```yaml
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
192
|
+
# .gitlab-ci.yml
|
|
193
|
+
workflow:
|
|
194
|
+
rules:
|
|
195
|
+
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
|
127
196
|
|
|
128
197
|
hodor-review:
|
|
129
|
-
|
|
198
|
+
stage: test
|
|
199
|
+
image:
|
|
200
|
+
name: ghcr.io/mr-karan/hodor:latest
|
|
201
|
+
entrypoint: [""]
|
|
202
|
+
variables:
|
|
203
|
+
HODOR_MODEL: "anthropic/claude-sonnet-4-5-20250929"
|
|
204
|
+
before_script:
|
|
205
|
+
- glab auth login --hostname $CI_SERVER_HOST --token $GITLAB_TOKEN
|
|
206
|
+
script:
|
|
207
|
+
- MR_URL="${CI_PROJECT_URL}/-/merge_requests/${CI_MERGE_REQUEST_IID}"
|
|
208
|
+
- |
|
|
209
|
+
EXTRA_ARGS=""
|
|
210
|
+
if [ -n "${METRICS_PUSH_URL:-}" ]; then EXTRA_ARGS="--prometheus-push $METRICS_PUSH_URL"; fi
|
|
211
|
+
bun run /app/dist/cli.js "$MR_URL" --model "$HODOR_MODEL" --post --code-quality gl-code-quality-report.json --commit-status $EXTRA_ARGS
|
|
212
|
+
artifacts:
|
|
213
|
+
reports:
|
|
214
|
+
codequality: gl-code-quality-report.json
|
|
215
|
+
when: always
|
|
216
|
+
allow_failure: true
|
|
217
|
+
timeout: 15m
|
|
130
218
|
```
|
|
131
219
|
|
|
220
|
+
This posts inline comments on the diff, a summary note, a pass/fail commit status, and a code quality report visible in the MR widget.
|
|
221
|
+
|
|
132
222
|
See [AUTOMATED_REVIEWS.md](./docs/AUTOMATED_REVIEWS.md) for advanced workflows.
|
|
133
223
|
|
|
134
224
|
## Token Optimization
|
|
135
225
|
|
|
136
226
|
Hodor automatically optimizes token usage:
|
|
137
227
|
|
|
138
|
-
- **Diff embedding**: For PRs under 200KB, the diff is embedded directly in the prompt, cutting turns from ~60 to ~5.
|
|
139
|
-
- **Incremental reviews**: On re-runs, only reviews changes since the last hodor comment (detected via SHA markers).
|
|
140
|
-
- **Compaction**: SDK auto-summarizes older turns when context grows too large.
|
|
228
|
+
- **Diff embedding**: For PRs under 200KB, the diff is embedded directly in the prompt, cutting agent turns from ~60 to ~5.
|
|
229
|
+
- **Incremental reviews**: On re-runs, only reviews changes since the last hodor comment (detected via SHA markers in posted comments).
|
|
230
|
+
- **Compaction**: SDK auto-summarizes older conversation turns when context grows too large.
|
|
141
231
|
|
|
142
232
|
## Skills
|
|
143
233
|
|
|
144
|
-
Hodor discovers repository-specific review guidelines from `.
|
|
234
|
+
Hodor discovers repository-specific review guidelines from `.agents/skills/`, the cross-client Agent Skills convention:
|
|
145
235
|
|
|
146
236
|
```bash
|
|
147
|
-
mkdir -p .
|
|
237
|
+
mkdir -p .agents/skills/review-guidelines
|
|
148
238
|
```
|
|
149
239
|
|
|
150
240
|
```markdown
|
|
151
|
-
# .
|
|
241
|
+
# .agents/skills/review-guidelines/SKILL.md
|
|
152
242
|
---
|
|
153
243
|
name: review-guidelines
|
|
154
244
|
description: Security and performance review checklist.
|
|
@@ -170,6 +260,40 @@ bun run test # Run tests
|
|
|
170
260
|
bun run dev -- <url> # Run from source
|
|
171
261
|
```
|
|
172
262
|
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Architecture
|
|
266
|
+
|
|
267
|
+
Hodor is written in TypeScript and runs on [Bun](https://bun.sh). Key components:
|
|
268
|
+
|
|
269
|
+
| Module | Purpose |
|
|
270
|
+
|--------|---------|
|
|
271
|
+
| `src/cli.ts` | Commander.js CLI entry point |
|
|
272
|
+
| `src/agent.ts` | Core review orchestration, URL parsing, comment posting |
|
|
273
|
+
| `src/workspace.ts` | CI detection, repo cloning, branch checkout |
|
|
274
|
+
| `src/prompt.ts` | Prompt template building and interpolation |
|
|
275
|
+
| `src/model.ts` | Model string parsing, API key resolution |
|
|
276
|
+
| `src/gitlab.ts` | GitLab API via `glab` CLI (comments, inline notes, draft notes, commit status) |
|
|
277
|
+
| `src/github.ts` | GitHub API via `gh` CLI |
|
|
278
|
+
| `src/render.ts` | JSON review output → markdown rendering |
|
|
279
|
+
| `src/codequality.ts` | CodeClimate JSON artifact for GitLab code quality widget |
|
|
280
|
+
| `src/metrics.ts` | Token usage and cost formatting |
|
|
281
|
+
| `templates/` | Review prompt template (JSON schema) |
|
|
282
|
+
|
|
283
|
+
The agent runtime is provided by [`@mariozechner/pi-coding-agent`](https://github.com/badlogic/pi-mono) with [`@mariozechner/pi-ai`](https://github.com/badlogic/pi-mono) for LLM access. The agent session gets read-only tools (bash, read, grep, find, ls) and a review prompt, then autonomously analyzes the PR.
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## Learn More
|
|
288
|
+
|
|
289
|
+
### Hodor Documentation
|
|
290
|
+
- **[SKILLS.md](./docs/SKILLS.md)** - Creating repository-specific review guidelines
|
|
291
|
+
- **[AUTOMATED_REVIEWS.md](./docs/AUTOMATED_REVIEWS.md)** - Advanced CI/CD workflows
|
|
292
|
+
|
|
293
|
+
### Contributing
|
|
294
|
+
Found a bug? Want to add a feature? Open an issue at https://github.com/mr-karan/hodor/issues.
|
|
295
|
+
|
|
296
|
+
---
|
|
173
297
|
## License
|
|
174
298
|
|
|
175
299
|
MIT
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// src/utils/path.ts
|
|
2
|
+
function relativizeWorkspacePath(absolutePath, workspacePrefix) {
|
|
3
|
+
let filePath = absolutePath;
|
|
4
|
+
const prefix = workspacePrefix ?? process.env.CI_PROJECT_DIR;
|
|
5
|
+
if (prefix) {
|
|
6
|
+
const trimmed = prefix.replace(/\/+$/, "");
|
|
7
|
+
if (filePath.startsWith(`${trimmed}/`)) {
|
|
8
|
+
return filePath.slice(trimmed.length + 1);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
const buildsMatch = filePath.match(/\/builds\/[^/]+\/[^/]+\/(.+)/);
|
|
12
|
+
if (buildsMatch) return buildsMatch[1];
|
|
13
|
+
if (filePath.includes("/workspace/")) {
|
|
14
|
+
return filePath.slice(filePath.indexOf("/workspace/") + "/workspace/".length);
|
|
15
|
+
}
|
|
16
|
+
const stripped = filePath.replace(/^.*\/hodor-review-[^/]+\//, "");
|
|
17
|
+
return stripped !== filePath ? stripped : filePath;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export {
|
|
21
|
+
relativizeWorkspacePath
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=chunk-AMUK6GDX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/path.ts"],"sourcesContent":["/**\n * Strip workspace/CI prefixes from an absolute path so it becomes repo-relative.\n *\n * Used both for inline-comment paths posted to GitLab (must match the diff path)\n * and for the CodeClimate code quality artifact (GitLab compares against repo\n * paths, not the temp-dir absolute paths Hodor sees during a review).\n *\n * Honors `CI_PROJECT_DIR` first when set (GitLab CI sets it to the checkout root).\n * Otherwise, falls through generic patterns: GitLab `/builds/<group>/<project>/...`,\n * a `/workspace/...` segment, and Hodor's own `/tmp/hodor-review-<id>/...` temp dirs.\n */\nexport function relativizeWorkspacePath(absolutePath: string, workspacePrefix?: string): string {\n let filePath = absolutePath;\n\n const prefix = workspacePrefix ?? process.env.CI_PROJECT_DIR;\n if (prefix) {\n const trimmed = prefix.replace(/\\/+$/, \"\");\n if (filePath.startsWith(`${trimmed}/`)) {\n return filePath.slice(trimmed.length + 1);\n }\n }\n\n const buildsMatch = filePath.match(/\\/builds\\/[^/]+\\/[^/]+\\/(.+)/);\n if (buildsMatch) return buildsMatch[1];\n\n if (filePath.includes(\"/workspace/\")) {\n return filePath.slice(filePath.indexOf(\"/workspace/\") + \"/workspace/\".length);\n }\n\n const stripped = filePath.replace(/^.*\\/hodor-review-[^/]+\\//, \"\");\n return stripped !== filePath ? stripped : filePath;\n}\n"],"mappings":";AAWO,SAAS,wBAAwB,cAAsB,iBAAkC;AAC9F,MAAI,WAAW;AAEf,QAAM,SAAS,mBAAmB,QAAQ,IAAI;AAC9C,MAAI,QAAQ;AACV,UAAM,UAAU,OAAO,QAAQ,QAAQ,EAAE;AACzC,QAAI,SAAS,WAAW,GAAG,OAAO,GAAG,GAAG;AACtC,aAAO,SAAS,MAAM,QAAQ,SAAS,CAAC;AAAA,IAC1C;AAAA,EACF;AAEA,QAAM,cAAc,SAAS,MAAM,8BAA8B;AACjE,MAAI,YAAa,QAAO,YAAY,CAAC;AAErC,MAAI,SAAS,SAAS,aAAa,GAAG;AACpC,WAAO,SAAS,MAAM,SAAS,QAAQ,aAAa,IAAI,cAAc,MAAM;AAAA,EAC9E;AAEA,QAAM,WAAW,SAAS,QAAQ,6BAA6B,EAAE;AACjE,SAAO,aAAa,WAAW,WAAW;AAC5C;","names":[]}
|