1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
|
.Dd October 23, 2025
.Dt AGENT-LAST-POSITION 1
.Os
.Sh NAME
.Nm agent-last-position
.Nd track and jump to AI agent's last edited file position
.Sh SYNOPSIS
.Nm
.Cm server
.Nm
.Cm set
.Ar path
.Ar line
.Nm
.Cm get
.Nm
.Cm open
.Nm
.Cm info
.Nm
.Cm hook
.Nm
.Cm prev
.Ar path
.Ar line
.Nm
.Cm next
.Ar path
.Ar line
.Sh DESCRIPTION
.Nm
is a Varlink-based IPC service that tracks a history of file positions edited
by AI agents (OpenCode, Claude, etc.). It enables quick navigation backward and forward through edit
locations via editor integration and shell keybindings.
.Pp
The service maintains an in-memory history of positions (file path and line number)
and communicates over a Unix socket at
.Pa /run/user/<uid>/de.Profpatsch.AgentLastPosition .
When an AI agent edits multiple blocks in a single file, each block is recorded as a
separate history entry for fine-grained navigation.
.Pp
The following subcommands are available:
.Bl -tag -width Ds
.It Cm server
Start the Varlink service daemon. The service listens on a Unix socket and
maintains the last edited position in memory. This should typically be run as
a systemd user service.
.It Cm set Ar path Ar line
Update the tracked position to the specified file path and line number. This
is typically called automatically by AI agent hooks after file edits.
.It Cm get
Retrieve the current tracked position as JSON output with
.Ic path
and
.Ic line
fields.
.It Cm open
Open the last edited position in the editor specified by
.Ev EDITOR .
Automatically detects and uses the correct line-jump syntax for vim, emacs,
and VSCode. Falls back to generic
.Ic +line
syntax for other editors.
.It Cm info
Display service information including version and available Varlink interfaces.
.It Cm hook
Parse Claude Code hook JSON payload from stdin and add positions to history.
For Edit tools, extracts line numbers from each hunk in the structured patch,
creating multiple history entries for edits in different file locations.
Designed to be used directly as a Claude Code hook command.
.It Cm prev Ar path Ar line
Navigate to the previous position in edit history relative to the given location.
Outputs the previous position in
.Ic path:line
format. Returns exit code 1 if at the beginning of history.
.It Cm next Ar path Ar line
Navigate to the next position in edit history relative to the given location.
Outputs the next position in
.Ic path:line
format. Returns exit code 1 if at the end of history.
.El
.Sh INSTALLATION
.Ss Build and Install
Build and install using Nix flakes:
.Bd -literal -offset indent
$ nix profile install git+https://codeberg.org/Profpatsch/Profpatsch?ref=canon#claude-last-position
.Ed
.Pp
This installs
.Ic claude-last-position
and the man page to your Nix profile.
.Ss Install systemd Service
Copy the service file and enable it for automatic startup:
.Bd -literal -offset indent
$ cp ~/kot/Profpatsch/users/Profpatsch/claude-last-position/\\
claude-last-position.service ~/.config/systemd/user/
$ systemctl --user daemon-reload
$ systemctl --user enable claude-last-position.service
$ systemctl --user start claude-last-position.service
.Ed
.Sh CLAUDE CODE INTEGRATION
.Ss Hook Configuration
Add hooks to
.Pa ~/.claude/settings.json
to automatically track edits:
.Bd -literal -offset indent
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "claude-last-position hook"
}
]
},
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "claude-last-position hook"
}
]
}
]
}
}
.Ed
.Pp
The
.Cm hook
command reads JSON event data from stdin and extracts accurate line numbers from
the structured patch information.
.Ss Shell Keybindings
.Sy Bash/Zsh
.Pq Pa ~/.bashrc No or Pa ~/.zshrc :
.Bd -literal -offset indent
bind -x '"\eC-xp": claude-last-position open'
.Ed
.Pp
.Sy Fish
.Pq Pa ~/.config/fish/config.fish :
.Bd -literal -offset indent
function binding_claude_last_position_open
commandline -r "claude-last-position open"
commandline -f execute
end
bind \eco binding_claude_last_position_open
.Ed
.Pp
The fish binding uses
.Ic commandline -f execute
to ensure the editor receives proper terminal control.
.Sh VARLINK INTERFACE
The service implements the following Varlink interface:
.Bd -literal -offset indent
interface de.profpatsch.ClaudeLastPosition
type Action (
method: string,
description: string,
prefilled_parameters: object
)
method SetLastPosition(path: string, line: int) -> ()
method GetLastPosition() -> (path: string, line: int, available_actions: []Action)
.Ed
.Pp
The interface follows HATEOAS principles: GetLastPosition returns
.Ic available_actions
that describe what operations are available from the current state. External clients
discover navigation operations (previous/next) through these actions rather than
hardcoded API knowledge. The
.Cm prev
and
.Cm next
CLI commands use internal implementation methods for efficient editor integration.
.Sh EXAMPLES
.Ss Start the Service Manually
.Dl $ claude-last-position server
.Ss Track a Position
.Dl $ claude-last-position set /path/to/file.go 42
.Ss Query Current Position
.Dl $ claude-last-position get
.Dl {"path": "/path/to/file.go", "line": 42}
.Ss Jump to Last Edit
.Dl $ claude-last-position open
.Pp
This opens
.Ev EDITOR
at the tracked file and line.
.Ss Navigate Edit History
.Dl $ claude-last-position prev /path/to/file.go 42
.Dl /path/to/other.go:15
.Dl $ claude-last-position next /path/to/other.go 15
.Dl /path/to/file.go:42
.Pp
These commands enable backward and forward navigation through the edit history,
useful for editor plugin integration.
.Sh ENVIRONMENT
.Bl -tag -width Ds
.It Ev EDITOR
Editor command to use for the
.Cm open
subcommand. Defaults to
.Ic vim
if not set. Supported editors include vim, neovim, emacs, and VSCode.
.El
.Sh FILES
.Bl -tag -width Ds
.It Pa /run/user/<uid>/de.Profpatsch.ClaudeLastPosition
Unix domain socket where the Varlink service listens for client connections.
.It Pa ~/.config/systemd/user/claude-last-position.service
Systemd user service file for automatic startup.
.It Pa .claude/settings.json
Claude Code settings file where hooks are configured.
.El
.Sh EXIT STATUS
.Ex -std
.Sh SEE ALSO
.Xr systemctl 1 ,
.Xr varlink 7
.Pp
Varlink Protocol:
.Lk https://varlink.org
.Sh AUTHORS
.An Profpatsch
.Pp
.Nm
was created with
.An Claude Code .
.Sh IMPLEMENTATION NOTES
.Bl -bullet
.It
Thread-safe: Uses
.Ic sync.RWMutex
for concurrent access to the position history
.It
In-memory history: Maintains a list of edit positions for backward/forward navigation.
Consecutive duplicate positions are automatically deduplicated.
.It
Multi-hunk support: Each hunk in a Claude Code Edit creates a separate history entry,
enabling navigation to each individual edit location within a file.
.It
Zero dependencies: Pure Go stdlib with included Varlink protocol implementation
.It
Editor detection: Automatically uses correct line-jump syntax based on
.Ev EDITOR
value
.El
|