fix(repos): gitea_repo_contents returns the path, not the file body #3

Closed
opened 2026-10-23 17:17:53 +00:00 by dsh · 1 comment
Owner

Symptom

gitea_repo_contents returns a filename, not the file:

  • path: AGENTS.md → AGENTS.md
  • path: README.md → README.md

So the tool cannot be used to read a file at all — which is its entire purpose, and the only fallback for an agent that cannot clone. path: "" additionally errors with invalid owner, repo, or filePath, so directories cannot be listed either.

Root cause

// lib/handlers/formatters.js:230
if (data.path) return [{ type: 'text', text: data.path }]

This branch fires before anything content-aware. The API payload is complete: GET /repos/pvlb-infra/vps-setup/contents/AGENTS.md returns encoding: "base64" plus content, size, html_url, download_url.

Separately, lib/gitea-client.js:494 rejects an empty path, so the root directory (where the API returns an array) is unreachable.

Fix

  • add a gitea_repo_contents formatter: decode base64 for files; truncate large bodies (say 20 KB) with an explicit note and always include html_url / download_url.
  • allow path: "" to list the root; the generic array formatter already handles {name, path} entries.
  • keep the path in the output so the reader knows what was fetched.

Acceptance

  • AGENTS.md → its first ~20 KB of text plus a download link.
  • root path → directory listing.
  • a 500 KB file returns a truncated body, not a 500 KB tool result.
## Symptom `gitea_repo_contents` returns a **filename, not the file**: - `path: AGENTS.md` → `AGENTS.md` - `path: README.md` → `README.md` So the tool cannot be used to read a file at all — which is its entire purpose, and the only fallback for an agent that cannot clone. `path: ""` additionally errors with `invalid owner, repo, or filePath`, so directories cannot be listed either. ## Root cause ```js // lib/handlers/formatters.js:230 if (data.path) return [{ type: 'text', text: data.path }] ``` This branch fires before anything content-aware. The API payload is complete: `GET /repos/pvlb-infra/vps-setup/contents/AGENTS.md` returns `encoding: "base64"` plus `content`, `size`, `html_url`, `download_url`. Separately, `lib/gitea-client.js:494` rejects an empty path, so the root directory (where the API returns an array) is unreachable. ## Fix - add a `gitea_repo_contents` formatter: decode base64 for files; truncate large bodies (say 20 KB) with an explicit note and always include `html_url` / `download_url`. - allow `path: ""` to list the root; the generic array formatter already handles `{name, path}` entries. - keep the `path` in the output so the reader knows what was fetched. ## Acceptance - [ ] `AGENTS.md` → its first ~20 KB of text plus a download link. - [ ] root path → directory listing. - [ ] a 500 KB file returns a truncated body, not a 500 KB tool result.
dsh closed this issue 2026-10-23 22:52:53 +00:00
Author
Owner

Fixed in 077ffc6 (PR #16).

gitea_repo_contents now decodes the API's base64 content and renders File: <path> (<size>, encoding) with html_url and download_url. Files larger than 20 000 chars are truncated with an explicit note and a download link. An empty path now requests /contents and lists the repository root; ../ traversal is still rejected.

Live through the running plugin:

  • AGENTS.md → File: AGENTS.md (38003 bytes, encoding: base64) + body, truncated at 20 000 chars with the raw download URL.
  • path: "" → root listing (.forgejo, AGENTS.md, lib, test, …).

Tests: test/repo-contents.test.mjs (body/links, unicode, truncation bound, empty/missing content, root request, path encoding/traversal); npm test 66/66.

Fixed in `077ffc6` (PR #16). `gitea_repo_contents` now decodes the API's base64 `content` and renders `File: <path> (<size>, encoding)` with `html_url` and `download_url`. Files larger than 20 000 chars are truncated with an explicit note and a download link. An empty `path` now requests `/contents` and lists the repository root; `../` traversal is still rejected. Live through the running plugin: - `AGENTS.md` → `File: AGENTS.md (38003 bytes, encoding: base64)` + body, truncated at 20 000 chars with the raw download URL. - `path: ""` → root listing (`.forgejo`, `AGENTS.md`, `lib`, `test`, …). Tests: `test/repo-contents.test.mjs` (body/links, unicode, truncation bound, empty/missing content, root request, path encoding/traversal); `npm test` 66/66.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
dsh-plugins/dsh-gitea#3
No description provided.