doer-agent 0.7.9 → 0.8.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/dist/agent-git-rpc.js +47 -10
- package/dist/agent-notes-local.js +29 -0
- package/dist/agent-notes-rpc.js +6 -1
- package/dist/agent.js +2 -0
- package/package.json +1 -1
package/dist/agent-git-rpc.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
+
import path from "node:path";
|
|
2
3
|
import { StringCodec } from "nats";
|
|
3
4
|
const gitRpcCodec = StringCodec();
|
|
4
5
|
function runLocalCommand(command, args, cwd) {
|
|
@@ -43,6 +44,35 @@ function sanitizeGitPathspec(value) {
|
|
|
43
44
|
}
|
|
44
45
|
return trimmed;
|
|
45
46
|
}
|
|
47
|
+
function normalizeWorkspacePath(workspaceRoot, value) {
|
|
48
|
+
const trimmed = value.trim().replace(/\\/g, "/") || ".";
|
|
49
|
+
if (path.isAbsolute(trimmed)) {
|
|
50
|
+
throw new Error("absolute paths are not supported for agent git diff");
|
|
51
|
+
}
|
|
52
|
+
const abs = path.resolve(workspaceRoot, trimmed);
|
|
53
|
+
if (abs !== workspaceRoot && !abs.startsWith(workspaceRoot + path.sep)) {
|
|
54
|
+
throw new Error("path escapes workspace root");
|
|
55
|
+
}
|
|
56
|
+
return abs;
|
|
57
|
+
}
|
|
58
|
+
function pathspecsForRepo(args) {
|
|
59
|
+
const normalizedTargetPath = args.targetPath.trim().replace(/\\/g, "/").replace(/\/+$/g, "") || ".";
|
|
60
|
+
return args.pathspecs.map((pathspec) => {
|
|
61
|
+
if (path.isAbsolute(pathspec)) {
|
|
62
|
+
throw new Error("absolute pathspecs are not supported for agent git diff");
|
|
63
|
+
}
|
|
64
|
+
const normalizedPathspec = pathspec.trim().replace(/\\/g, "/").replace(/\/+$/g, "") || ".";
|
|
65
|
+
const workspaceAbs = normalizedPathspec === normalizedTargetPath
|
|
66
|
+
? args.targetPathAbs
|
|
67
|
+
: path.resolve(args.workspaceRoot, pathspec);
|
|
68
|
+
const repoRelRaw = path.relative(args.repoRootAbs, workspaceAbs).split(path.sep).join("/");
|
|
69
|
+
const repoRel = repoRelRaw || ".";
|
|
70
|
+
if (repoRel && repoRel !== ".." && !repoRel.startsWith("../")) {
|
|
71
|
+
return repoRel;
|
|
72
|
+
}
|
|
73
|
+
return pathspec;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
46
76
|
function normalizeGitRpcRequest(args) {
|
|
47
77
|
const requestId = typeof args.request.requestId === "string" ? args.request.requestId.trim() : "";
|
|
48
78
|
const responseSubject = typeof args.request.responseSubject === "string" ? args.request.responseSubject.trim() : "";
|
|
@@ -68,7 +98,7 @@ function normalizeGitRpcRequest(args) {
|
|
|
68
98
|
args.request.diffAlgorithm === "histogram"
|
|
69
99
|
? args.request.diffAlgorithm
|
|
70
100
|
: "default";
|
|
71
|
-
const contextRaw =
|
|
101
|
+
const contextRaw = typeof args.request.contextLines === "number" ? args.request.contextLines : Number.NaN;
|
|
72
102
|
const contextLines = Number.isFinite(contextRaw) ? Math.max(0, Math.min(200, Math.trunc(contextRaw))) : null;
|
|
73
103
|
const pathspecs = Array.isArray(args.request.pathspecs) ? args.request.pathspecs.map((item) => sanitizeGitPathspec(item)) : [];
|
|
74
104
|
return {
|
|
@@ -216,10 +246,9 @@ export async function handleGitRpcMessage(args) {
|
|
|
216
246
|
const request = normalizeGitRpcRequest({ request: payload, agentId: args.agentId });
|
|
217
247
|
requestId = request.requestId;
|
|
218
248
|
responseSubject = request.responseSubject;
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
const topLevelResult = await runLocalCommand("git", ["-C", request.targetPath, "rev-parse", "--show-toplevel"], request.targetPath);
|
|
249
|
+
const workspaceRoot = path.resolve(args.workspaceRoot);
|
|
250
|
+
const targetPathAbs = normalizeWorkspacePath(workspaceRoot, request.targetPath);
|
|
251
|
+
const topLevelResult = await runLocalCommand("git", ["-C", targetPathAbs, "rev-parse", "--show-toplevel"], targetPathAbs);
|
|
223
252
|
if (topLevelResult.code !== 0) {
|
|
224
253
|
publishGitRpcResponse({
|
|
225
254
|
nc: args.nc,
|
|
@@ -233,7 +262,6 @@ export async function handleGitRpcMessage(args) {
|
|
|
233
262
|
source: "agent",
|
|
234
263
|
agent: { id: args.agentId, name: null },
|
|
235
264
|
currentPath: request.targetPath,
|
|
236
|
-
repoRoot: null,
|
|
237
265
|
repoRelativePath: null,
|
|
238
266
|
branch: null,
|
|
239
267
|
gitDiff: {
|
|
@@ -249,17 +277,27 @@ export async function handleGitRpcMessage(args) {
|
|
|
249
277
|
return;
|
|
250
278
|
}
|
|
251
279
|
const repoRootAbs = topLevelResult.stdout.trim();
|
|
252
|
-
const
|
|
280
|
+
const repoRequest = {
|
|
281
|
+
...request,
|
|
282
|
+
pathspecs: pathspecsForRepo({
|
|
283
|
+
workspaceRoot,
|
|
284
|
+
repoRootAbs,
|
|
285
|
+
targetPath: request.targetPath,
|
|
286
|
+
targetPathAbs,
|
|
287
|
+
pathspecs: request.pathspecs,
|
|
288
|
+
}),
|
|
289
|
+
};
|
|
290
|
+
const prefixResult = await runLocalCommand("git", ["-C", targetPathAbs, "rev-parse", "--show-prefix"], targetPathAbs);
|
|
253
291
|
const repoRelativePath = prefixResult.code === 0 ? (prefixResult.stdout.trim().replace(/\/$/, "") || ".") : ".";
|
|
254
292
|
const branchResult = await runLocalCommand("git", ["-C", repoRootAbs, "symbolic-ref", "--quiet", "--short", "HEAD"], repoRootAbs);
|
|
255
293
|
const detachedResult = branchResult.code === 0 ? null : await runLocalCommand("git", ["-C", repoRootAbs, "rev-parse", "--short", "HEAD"], repoRootAbs);
|
|
256
294
|
const branch = branchResult.code === 0 ? branchResult.stdout.trim() || null : detachedResult && detachedResult.code === 0 ? detachedResult.stdout.trim() || null : null;
|
|
257
|
-
const gitDiffArgs = buildAgentGitDiffArgs(repoRootAbs,
|
|
295
|
+
const gitDiffArgs = buildAgentGitDiffArgs(repoRootAbs, repoRequest);
|
|
258
296
|
const gitDiffResult = await runLocalCommand("git", gitDiffArgs.args, repoRootAbs);
|
|
259
297
|
if (gitDiffResult.code !== 0) {
|
|
260
298
|
throw new Error(gitDiffResult.stderr.trim() || "Failed to run agent git diff");
|
|
261
299
|
}
|
|
262
|
-
const withUntracked = await appendAgentLocalUntrackedDiff(repoRootAbs,
|
|
300
|
+
const withUntracked = await appendAgentLocalUntrackedDiff(repoRootAbs, repoRequest, gitDiffResult.stdout);
|
|
263
301
|
publishGitRpcResponse({
|
|
264
302
|
nc: args.nc,
|
|
265
303
|
responseSubject,
|
|
@@ -272,7 +310,6 @@ export async function handleGitRpcMessage(args) {
|
|
|
272
310
|
source: "agent",
|
|
273
311
|
agent: { id: args.agentId, name: null },
|
|
274
312
|
currentPath: request.targetPath,
|
|
275
|
-
repoRoot: repoRootAbs,
|
|
276
313
|
repoRelativePath,
|
|
277
314
|
branch,
|
|
278
315
|
gitDiff: {
|
|
@@ -187,6 +187,35 @@ export async function listAgentNotesLocal(workspaceRoot) {
|
|
|
187
187
|
});
|
|
188
188
|
return notes;
|
|
189
189
|
}
|
|
190
|
+
export async function listAgentNotePatchesLocal(workspaceRoot, limit = 10) {
|
|
191
|
+
const rootAbs = workspacePath(workspaceRoot, PATCHES_ROOT);
|
|
192
|
+
const patches = [];
|
|
193
|
+
async function visit(absDir, relDir) {
|
|
194
|
+
const rows = await readdir(absDir, { withFileTypes: true }).catch(() => []);
|
|
195
|
+
await Promise.all(rows.map(async (row) => {
|
|
196
|
+
const childAbs = path.join(absDir, row.name);
|
|
197
|
+
const childRel = path.posix.join(relDir, row.name);
|
|
198
|
+
if (row.isDirectory()) {
|
|
199
|
+
await visit(childAbs, childRel);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (!row.isFile() || !row.name.endsWith(".patch")) {
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
const entry = await stat(childAbs);
|
|
206
|
+
patches.push({
|
|
207
|
+
id: childRel,
|
|
208
|
+
path: childRel,
|
|
209
|
+
name: row.name,
|
|
210
|
+
size: entry.size,
|
|
211
|
+
mtimeMs: entry.mtimeMs,
|
|
212
|
+
});
|
|
213
|
+
}));
|
|
214
|
+
}
|
|
215
|
+
await visit(rootAbs, PATCHES_ROOT);
|
|
216
|
+
patches.sort((a, b) => b.mtimeMs - a.mtimeMs || b.path.localeCompare(a.path));
|
|
217
|
+
return patches.slice(0, Math.max(0, Math.trunc(limit)));
|
|
218
|
+
}
|
|
190
219
|
export async function getAgentNoteLocal(workspaceRoot, noteId) {
|
|
191
220
|
const id = sanitizeNoteId(noteId);
|
|
192
221
|
const content = await readTextIfExists(workspacePath(workspaceRoot, noteRelPath(id)));
|
package/dist/agent-notes-rpc.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { StringCodec } from "nats";
|
|
2
|
-
import { agentNotesCapabilitiesLocal, createAgentNoteLocal, deleteAgentNoteLocal, getAgentNoteLocal, listAgentNotesLocal, renameAgentNoteLocal, saveAgentNoteLocal, } from "./agent-notes-local.js";
|
|
2
|
+
import { agentNotesCapabilitiesLocal, createAgentNoteLocal, deleteAgentNoteLocal, listAgentNotePatchesLocal, getAgentNoteLocal, listAgentNotesLocal, renameAgentNoteLocal, saveAgentNoteLocal, } from "./agent-notes-local.js";
|
|
3
3
|
const notesRpcCodec = StringCodec();
|
|
4
4
|
function parseAction(value) {
|
|
5
5
|
if (value === "capabilities" ||
|
|
6
6
|
value === "list" ||
|
|
7
|
+
value === "listPatches" ||
|
|
7
8
|
value === "get" ||
|
|
8
9
|
value === "create" ||
|
|
9
10
|
value === "save" ||
|
|
@@ -24,6 +25,10 @@ async function executeNotesRpc(workspaceRoot, request) {
|
|
|
24
25
|
if (action === "list") {
|
|
25
26
|
return { ok: true, action, notes: await listAgentNotesLocal(workspaceRoot) };
|
|
26
27
|
}
|
|
28
|
+
if (action === "listPatches") {
|
|
29
|
+
const limit = typeof request.limit === "number" && Number.isFinite(request.limit) ? request.limit : 10;
|
|
30
|
+
return { ok: true, action, patches: await listAgentNotePatchesLocal(workspaceRoot, limit) };
|
|
31
|
+
}
|
|
27
32
|
if (action === "get") {
|
|
28
33
|
const notes = await listAgentNotesLocal(workspaceRoot);
|
|
29
34
|
const noteId = stringValue(request.noteId) || notes[0]?.id || "";
|
package/dist/agent.js
CHANGED
|
@@ -84,6 +84,7 @@ function subscribeToGitRpc(args) {
|
|
|
84
84
|
msg,
|
|
85
85
|
nc: args.jetstream.nc,
|
|
86
86
|
agentId: args.agentId,
|
|
87
|
+
workspaceRoot: args.workspaceRoot,
|
|
87
88
|
onError: writeAgentError,
|
|
88
89
|
});
|
|
89
90
|
},
|
|
@@ -319,6 +320,7 @@ async function main() {
|
|
|
319
320
|
jetstream,
|
|
320
321
|
userId,
|
|
321
322
|
agentId: initialAgentId,
|
|
323
|
+
workspaceRoot: resolveWorkspaceRoot(),
|
|
322
324
|
});
|
|
323
325
|
subscribeToSkillRpc({
|
|
324
326
|
nc: jetstream.nc,
|