<feed xmlns='http://www.w3.org/2005/Atom'>
<title>dotemacs/tests/test-gptel-tools-git-diff.el, branch main</title>
<subtitle>My Emacs configuration
</subtitle>
<id>https://git.cjennings.net/dotemacs/atom?h=main</id>
<link rel='self' href='https://git.cjennings.net/dotemacs/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/'/>
<updated>2026-05-16T16:30:04+00:00</updated>
<entry>
<title>feat(gptel-tools): harden path validation with file-truename realpath</title>
<updated>2026-05-16T16:30:04+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-16T16:30:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=244d4c56768fcc60bd1b23fe45df7a57c7b293ec'/>
<id>urn:sha1:244d4c56768fcc60bd1b23fe45df7a57c7b293ec</id>
<content type='text'>
Resolves PATH through file-truename before applying home-directory and
read/write checks across the path-handling tools (git_status, git_log,
git_diff, move_to_trash, read_text_file, update_text_file,
write_text_file, list_directory_files, read_buffer, web_fetch).
Without the resolve step, a symlink under HOME pointing outside HOME
would pass the prefix check but the tool would act on the real target
-- a symlink-escape.

move_to_trash also tightens the trash-bin construction (treats empty
file extensions correctly) and switches the "critical directories"
list to truename-resolved canonical forms so a symlinked ~/.config
can't be trashed via an aliased path.

update_text_file fixes an off-by-one in the line-count derivation
when the source content is empty.

Each source change pairs with tests in tests/test-gptel-tools-*.el
and tests/test-update-text-file.el covering the realpath escape
paths, the empty-extension trash case, and the empty-content line-
count edge.  Combined coverage is now 100% across all ten gptel-tools
source files: 516 / 516 executable lines, 217 tests.
</content>
</entry>
<entry>
<title>feat(gptel-tools): wire git_status / git_log / git_diff as local tools</title>
<updated>2026-05-16T09:26:20+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-16T09:26:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=ceeae9b5e2625e23e6e3792d06a6c8122a36d18b'/>
<id>urn:sha1:ceeae9b5e2625e23e6e3792d06a6c8122a36d18b</id>
<content type='text'>
Three read-only git context tools so gptel can see what's changed
without me pasting `git status` / `git log` / `git diff` output into
every chat turn.  Builds the first batch from the ADOPT bucket in
`docs/design/gptel-tools-shortlist.org`.

Shape per tool:

- `gptel-tools/git_status.el` — `git status --short --branch` for a
  directory inside a git working tree under HOME.  Returns the
  porcelain output, or a "Clean working tree" marker when only the
  branch line is present.
- `gptel-tools/git_log.el` — `git log --oneline -nN` with an optional
  `--since` filter.  N defaults to 20, capped at 100; nil / non-
  integer / out-of-range N falls back to the default.
- `gptel-tools/git_diff.el` — `git diff [REF1 [REF2]] [-- FILE]`.
  Output capped at ~500KB so a runaway diff can't blow up context;
  truncation is reported inline.

Validation is uniform: path must resolve under HOME, must be a
directory, must be inside a git working tree (verified via
`git rev-parse --is-inside-work-tree`).  Color is disabled via
`-c color.ui=false` at the git level (`git status` doesn't accept
`--no-color` directly).

Tests run against real temp git repos created via `process-file`,
not mocked — there's nothing in gptel-tools/git_*.el that's
process-mockable in a meaningful way, and a real `git init` + a
couple of commits is cheaper than building a fake.  31 tests total:
7 for git_status, 11 for git_log, 13 for git_diff.

Wired into `cj/gptel-local-tool-features` so gptel exposes the
three tools on next restart.
</content>
</entry>
</feed>
