@ricsam/r5d-api 0.0.60 → 0.0.61
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 +11 -7
- package/dist/cjs/index.cjs +107 -45
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/index.mjs +107 -45
- package/dist/mjs/package.json +1 -1
- package/dist/types/index.d.ts +148 -44
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,22 +58,26 @@ Trusted server-side callers that authenticate through custom headers, such as a
|
|
|
58
58
|
- `projects.env.get/update/remove(projectId, ...)`
|
|
59
59
|
- `projects.sessions.list(projectRef, { branch? })`
|
|
60
60
|
- `projects.sessions.create(projectRef, { branchName, name? })`
|
|
61
|
-
- `projects.
|
|
62
|
-
- `
|
|
61
|
+
- `projects.sessions.start(projectRef, { worker, model, prompt, requestId, worktree?, newWorktree?, source? })`
|
|
62
|
+
- `projects.worktrees.merge(projectRef, sourceWorktree, { worker?, conflictMode })`
|
|
63
|
+
- `projects.worktrees.finishMerge(projectRef, conflictWorktree, { worker, summary? })`
|
|
63
64
|
- `sessions.describe(sessionId)`
|
|
64
65
|
- `sessions.update(sessionId, { name })`
|
|
65
66
|
- `sessions.delete(sessionId)`
|
|
66
67
|
- `sessions.conversation(sessionId)`
|
|
68
|
+
- `sessions.events(sessionId, { signal? })`
|
|
67
69
|
- `sessions.conversationOverview(sessionId)`
|
|
68
70
|
- `sessions.inspectConversationNode(sessionId, nodeId)`
|
|
69
71
|
- `sessions.inspectConversationWork(sessionId, workId, { detail? })`
|
|
70
|
-
- `sessions.
|
|
71
|
-
- `sessions.
|
|
72
|
-
- `sessions.
|
|
72
|
+
- `sessions.status(sessionId)`
|
|
73
|
+
- `sessions.prompt(sessionId, { prompt, worker, mode, model, requestId })`
|
|
74
|
+
- `sessions.stop(sessionId)`
|
|
75
|
+
- `sessions.answerQuestions(sessionId, { answers, worker, mode, model, requestId })`
|
|
76
|
+
- `sessions.answerEnvRequest(sessionId, { envs?, additionalContext?, worker, mode, model, requestId })`
|
|
73
77
|
|
|
74
|
-
`
|
|
78
|
+
`sessions.prompt(...)` returns `promptDisposition: "queued" | "started"`, so callers can distinguish delivery to an active generation from a newly started generation. Session commands never rebind a session to another worker implicitly.
|
|
75
79
|
|
|
76
|
-
`projects.
|
|
80
|
+
`projects.sessions.start(...)` selects either an existing `worktree`, or a `newWorktree` plus `source: { type: "worktree", branchName }`. Session events are exposed as an authenticated async iterable over the raw `/api/sessions/:sessionId/events` SSE stream.
|
|
77
81
|
|
|
78
82
|
## Errors
|
|
79
83
|
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -49,6 +49,56 @@ function withQuery(path, query) {
|
|
|
49
49
|
const queryString = params.toString();
|
|
50
50
|
return queryString.length > 0 ? `${path}?${queryString}` : path;
|
|
51
51
|
}
|
|
52
|
+
function parseSseFrame(frame) {
|
|
53
|
+
const dataLines = [];
|
|
54
|
+
let eventType;
|
|
55
|
+
for (const line of frame.split(/\r?\n/)) {
|
|
56
|
+
if (line.length === 0 || line.startsWith(":")) continue;
|
|
57
|
+
const separator = line.indexOf(":");
|
|
58
|
+
const field = separator < 0 ? line : line.slice(0, separator);
|
|
59
|
+
const value = separator < 0 ? "" : line.slice(separator + 1).replace(/^ /, "");
|
|
60
|
+
if (field === "event") eventType = value;
|
|
61
|
+
if (field === "data") dataLines.push(value);
|
|
62
|
+
}
|
|
63
|
+
if (dataLines.length === 0) return null;
|
|
64
|
+
const parsed = safeJsonParse(dataLines.join("\n"));
|
|
65
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
66
|
+
const record = parsed;
|
|
67
|
+
if (typeof record.type !== "string" && eventType) record.type = eventType;
|
|
68
|
+
if (typeof record.type === "string") return record;
|
|
69
|
+
}
|
|
70
|
+
return eventType ? { type: eventType, data: parsed } : null;
|
|
71
|
+
}
|
|
72
|
+
async function* parseSseStream(stream) {
|
|
73
|
+
const reader = stream.getReader();
|
|
74
|
+
const decoder = new TextDecoder();
|
|
75
|
+
let buffer = "";
|
|
76
|
+
let completed = false;
|
|
77
|
+
try {
|
|
78
|
+
while (true) {
|
|
79
|
+
const { done, value } = await reader.read();
|
|
80
|
+
buffer += decoder.decode(value, { stream: !done });
|
|
81
|
+
let boundary = buffer.search(/\r?\n\r?\n/);
|
|
82
|
+
while (boundary >= 0) {
|
|
83
|
+
const frame = buffer.slice(0, boundary);
|
|
84
|
+
const separator = buffer.slice(boundary).match(/^\r?\n\r?\n/)?.[0] ?? "\n\n";
|
|
85
|
+
buffer = buffer.slice(boundary + separator.length);
|
|
86
|
+
const event2 = parseSseFrame(frame);
|
|
87
|
+
if (event2) yield event2;
|
|
88
|
+
boundary = buffer.search(/\r?\n\r?\n/);
|
|
89
|
+
}
|
|
90
|
+
if (done) {
|
|
91
|
+
completed = true;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const event = parseSseFrame(buffer);
|
|
96
|
+
if (event) yield event;
|
|
97
|
+
} finally {
|
|
98
|
+
if (!completed) await reader.cancel().catch(() => void 0);
|
|
99
|
+
reader.releaseLock();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
52
102
|
class R5dctlClient {
|
|
53
103
|
fetchImpl;
|
|
54
104
|
baseUrl;
|
|
@@ -76,26 +126,25 @@ class R5dctlClient {
|
|
|
76
126
|
resolveBearerToken() {
|
|
77
127
|
return this.token ?? this.apiKey;
|
|
78
128
|
}
|
|
79
|
-
|
|
80
|
-
const
|
|
129
|
+
authHeaders(path, accept, auth = "auto") {
|
|
130
|
+
const headers = { ...this.extraHeaders, Accept: accept };
|
|
131
|
+
if (auth === "none") return headers;
|
|
81
132
|
const bearerToken = this.resolveBearerToken();
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
throw new R5dctlApiError("Authentication required. Set token or apiKey in R5dctlClient.", {
|
|
90
|
-
status: 401,
|
|
91
|
-
path: input.path,
|
|
92
|
-
body: { error: "Missing credentials" }
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
} else {
|
|
96
|
-
headers.Authorization = `Bearer ${bearerToken}`;
|
|
133
|
+
if (!bearerToken) {
|
|
134
|
+
if (this.authMode !== "headers") {
|
|
135
|
+
throw new R5dctlApiError("Authentication required. Set token or apiKey in R5dctlClient.", {
|
|
136
|
+
status: 401,
|
|
137
|
+
path,
|
|
138
|
+
body: { error: "Missing credentials" }
|
|
139
|
+
});
|
|
97
140
|
}
|
|
141
|
+
} else {
|
|
142
|
+
headers.Authorization = `Bearer ${bearerToken}`;
|
|
98
143
|
}
|
|
144
|
+
return headers;
|
|
145
|
+
}
|
|
146
|
+
async request(input) {
|
|
147
|
+
const headers = this.authHeaders(input.path, "application/json", input.auth ?? "auto");
|
|
99
148
|
const hasBody = input.body !== void 0;
|
|
100
149
|
if (hasBody) {
|
|
101
150
|
headers["Content-Type"] = "application/json";
|
|
@@ -118,6 +167,24 @@ class R5dctlClient {
|
|
|
118
167
|
}
|
|
119
168
|
return payload;
|
|
120
169
|
}
|
|
170
|
+
async *events(sessionId, input = {}) {
|
|
171
|
+
const path = `/api/sessions/${encodeURIComponent(sessionId)}/events`;
|
|
172
|
+
const response = await this.fetchImpl(`${this.baseUrl}${path}`, {
|
|
173
|
+
method: "GET",
|
|
174
|
+
headers: this.authHeaders(path, "text/event-stream"),
|
|
175
|
+
signal: input.signal
|
|
176
|
+
});
|
|
177
|
+
if (!response.ok) {
|
|
178
|
+
const text = await response.text();
|
|
179
|
+
const payload = text.length > 0 ? safeJsonParse(text) : null;
|
|
180
|
+
const message = typeof payload === "object" && payload && "error" in payload && typeof payload.error === "string" ? payload.error : `Request failed (${response.status})`;
|
|
181
|
+
throw new R5dctlApiError(message, { status: response.status, path, body: payload });
|
|
182
|
+
}
|
|
183
|
+
if (!response.body) {
|
|
184
|
+
throw new R5dctlApiError("Session event stream returned no body", { status: response.status, path, body: null });
|
|
185
|
+
}
|
|
186
|
+
yield* parseSseStream(response.body);
|
|
187
|
+
}
|
|
121
188
|
auth = {
|
|
122
189
|
deviceStart: (input) => this.request({
|
|
123
190
|
method: "POST",
|
|
@@ -294,41 +361,26 @@ class R5dctlClient {
|
|
|
294
361
|
method: "POST",
|
|
295
362
|
path: `/api/r5dctl/projects/${encodeURIComponent(projectRef)}/sessions`,
|
|
296
363
|
body: input
|
|
364
|
+
}),
|
|
365
|
+
start: (projectRef, input) => this.request({
|
|
366
|
+
method: "POST",
|
|
367
|
+
path: `/api/r5dctl/projects/${encodeURIComponent(projectRef)}/sessions/start`,
|
|
368
|
+
body: input
|
|
297
369
|
})
|
|
298
370
|
},
|
|
299
|
-
|
|
300
|
-
|
|
371
|
+
worktrees: {
|
|
372
|
+
merge: (projectRef, sourceWorktree, input) => this.request({
|
|
301
373
|
method: "POST",
|
|
302
|
-
path: `/api/r5dctl/projects/${encodeURIComponent(projectRef)}/
|
|
374
|
+
path: `/api/r5dctl/projects/${encodeURIComponent(projectRef)}/worktrees/${encodeURIComponent(sourceWorktree)}/merge`,
|
|
375
|
+
body: input
|
|
376
|
+
}),
|
|
377
|
+
finishMerge: (projectRef, conflictWorktree, input) => this.request({
|
|
378
|
+
method: "POST",
|
|
379
|
+
path: `/api/r5dctl/projects/${encodeURIComponent(projectRef)}/worktrees/${encodeURIComponent(conflictWorktree)}/merge/finish`,
|
|
303
380
|
body: input
|
|
304
381
|
})
|
|
305
382
|
}
|
|
306
383
|
};
|
|
307
|
-
agents = {
|
|
308
|
-
status: (sessionId) => this.request({
|
|
309
|
-
method: "GET",
|
|
310
|
-
path: `/api/r5dctl/agents/${encodeURIComponent(sessionId)}`
|
|
311
|
-
}),
|
|
312
|
-
sendPrompt: (sessionId, input) => this.request({
|
|
313
|
-
method: "POST",
|
|
314
|
-
path: `/api/r5dctl/agents/${encodeURIComponent(sessionId)}/prompt`,
|
|
315
|
-
body: input
|
|
316
|
-
}),
|
|
317
|
-
merge: (sessionId, input) => this.request({
|
|
318
|
-
method: "POST",
|
|
319
|
-
path: `/api/r5dctl/agents/${encodeURIComponent(sessionId)}/merge`,
|
|
320
|
-
body: input
|
|
321
|
-
}),
|
|
322
|
-
stop: (sessionId) => this.request({
|
|
323
|
-
method: "POST",
|
|
324
|
-
path: `/api/r5dctl/agents/${encodeURIComponent(sessionId)}/stop`
|
|
325
|
-
}),
|
|
326
|
-
finishMerge: (sessionId, input) => this.request({
|
|
327
|
-
method: "POST",
|
|
328
|
-
path: `/api/r5dctl/agents/${encodeURIComponent(sessionId)}/finish-merge`,
|
|
329
|
-
body: input
|
|
330
|
-
})
|
|
331
|
-
};
|
|
332
384
|
sessions = {
|
|
333
385
|
recent: (input = {}) => this.request({
|
|
334
386
|
method: "GET",
|
|
@@ -348,6 +400,11 @@ class R5dctlClient {
|
|
|
348
400
|
method: "DELETE",
|
|
349
401
|
path: `/api/r5dctl/sessions/${encodeURIComponent(sessionId)}`
|
|
350
402
|
}),
|
|
403
|
+
status: (sessionId) => this.request({
|
|
404
|
+
method: "GET",
|
|
405
|
+
path: `/api/r5dctl/sessions/${encodeURIComponent(sessionId)}/status`
|
|
406
|
+
}),
|
|
407
|
+
events: (sessionId, input = {}) => this.events(sessionId, input),
|
|
351
408
|
conversation: (sessionId, input = {}) => this.request({
|
|
352
409
|
method: "GET",
|
|
353
410
|
path: `/api/r5dctl/sessions/${encodeURIComponent(sessionId)}/conversation`,
|
|
@@ -377,6 +434,11 @@ class R5dctlClient {
|
|
|
377
434
|
path: `/api/r5dctl/sessions/${encodeURIComponent(sessionId)}/prompt`,
|
|
378
435
|
body: input
|
|
379
436
|
}),
|
|
437
|
+
stop: (sessionId) => this.request({
|
|
438
|
+
method: "POST",
|
|
439
|
+
path: `/api/r5dctl/sessions/${encodeURIComponent(sessionId)}/stop`,
|
|
440
|
+
body: {}
|
|
441
|
+
}),
|
|
380
442
|
answerQuestions: (sessionId, input) => this.request({
|
|
381
443
|
method: "POST",
|
|
382
444
|
path: `/api/r5dctl/sessions/${encodeURIComponent(sessionId)}/answer-questions`,
|
package/dist/cjs/package.json
CHANGED
package/dist/mjs/index.mjs
CHANGED
|
@@ -25,6 +25,56 @@ function withQuery(path, query) {
|
|
|
25
25
|
const queryString = params.toString();
|
|
26
26
|
return queryString.length > 0 ? `${path}?${queryString}` : path;
|
|
27
27
|
}
|
|
28
|
+
function parseSseFrame(frame) {
|
|
29
|
+
const dataLines = [];
|
|
30
|
+
let eventType;
|
|
31
|
+
for (const line of frame.split(/\r?\n/)) {
|
|
32
|
+
if (line.length === 0 || line.startsWith(":")) continue;
|
|
33
|
+
const separator = line.indexOf(":");
|
|
34
|
+
const field = separator < 0 ? line : line.slice(0, separator);
|
|
35
|
+
const value = separator < 0 ? "" : line.slice(separator + 1).replace(/^ /, "");
|
|
36
|
+
if (field === "event") eventType = value;
|
|
37
|
+
if (field === "data") dataLines.push(value);
|
|
38
|
+
}
|
|
39
|
+
if (dataLines.length === 0) return null;
|
|
40
|
+
const parsed = safeJsonParse(dataLines.join("\n"));
|
|
41
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
42
|
+
const record = parsed;
|
|
43
|
+
if (typeof record.type !== "string" && eventType) record.type = eventType;
|
|
44
|
+
if (typeof record.type === "string") return record;
|
|
45
|
+
}
|
|
46
|
+
return eventType ? { type: eventType, data: parsed } : null;
|
|
47
|
+
}
|
|
48
|
+
async function* parseSseStream(stream) {
|
|
49
|
+
const reader = stream.getReader();
|
|
50
|
+
const decoder = new TextDecoder();
|
|
51
|
+
let buffer = "";
|
|
52
|
+
let completed = false;
|
|
53
|
+
try {
|
|
54
|
+
while (true) {
|
|
55
|
+
const { done, value } = await reader.read();
|
|
56
|
+
buffer += decoder.decode(value, { stream: !done });
|
|
57
|
+
let boundary = buffer.search(/\r?\n\r?\n/);
|
|
58
|
+
while (boundary >= 0) {
|
|
59
|
+
const frame = buffer.slice(0, boundary);
|
|
60
|
+
const separator = buffer.slice(boundary).match(/^\r?\n\r?\n/)?.[0] ?? "\n\n";
|
|
61
|
+
buffer = buffer.slice(boundary + separator.length);
|
|
62
|
+
const event2 = parseSseFrame(frame);
|
|
63
|
+
if (event2) yield event2;
|
|
64
|
+
boundary = buffer.search(/\r?\n\r?\n/);
|
|
65
|
+
}
|
|
66
|
+
if (done) {
|
|
67
|
+
completed = true;
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const event = parseSseFrame(buffer);
|
|
72
|
+
if (event) yield event;
|
|
73
|
+
} finally {
|
|
74
|
+
if (!completed) await reader.cancel().catch(() => void 0);
|
|
75
|
+
reader.releaseLock();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
28
78
|
class R5dctlClient {
|
|
29
79
|
fetchImpl;
|
|
30
80
|
baseUrl;
|
|
@@ -52,26 +102,25 @@ class R5dctlClient {
|
|
|
52
102
|
resolveBearerToken() {
|
|
53
103
|
return this.token ?? this.apiKey;
|
|
54
104
|
}
|
|
55
|
-
|
|
56
|
-
const
|
|
105
|
+
authHeaders(path, accept, auth = "auto") {
|
|
106
|
+
const headers = { ...this.extraHeaders, Accept: accept };
|
|
107
|
+
if (auth === "none") return headers;
|
|
57
108
|
const bearerToken = this.resolveBearerToken();
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
throw new R5dctlApiError("Authentication required. Set token or apiKey in R5dctlClient.", {
|
|
66
|
-
status: 401,
|
|
67
|
-
path: input.path,
|
|
68
|
-
body: { error: "Missing credentials" }
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
} else {
|
|
72
|
-
headers.Authorization = `Bearer ${bearerToken}`;
|
|
109
|
+
if (!bearerToken) {
|
|
110
|
+
if (this.authMode !== "headers") {
|
|
111
|
+
throw new R5dctlApiError("Authentication required. Set token or apiKey in R5dctlClient.", {
|
|
112
|
+
status: 401,
|
|
113
|
+
path,
|
|
114
|
+
body: { error: "Missing credentials" }
|
|
115
|
+
});
|
|
73
116
|
}
|
|
117
|
+
} else {
|
|
118
|
+
headers.Authorization = `Bearer ${bearerToken}`;
|
|
74
119
|
}
|
|
120
|
+
return headers;
|
|
121
|
+
}
|
|
122
|
+
async request(input) {
|
|
123
|
+
const headers = this.authHeaders(input.path, "application/json", input.auth ?? "auto");
|
|
75
124
|
const hasBody = input.body !== void 0;
|
|
76
125
|
if (hasBody) {
|
|
77
126
|
headers["Content-Type"] = "application/json";
|
|
@@ -94,6 +143,24 @@ class R5dctlClient {
|
|
|
94
143
|
}
|
|
95
144
|
return payload;
|
|
96
145
|
}
|
|
146
|
+
async *events(sessionId, input = {}) {
|
|
147
|
+
const path = `/api/sessions/${encodeURIComponent(sessionId)}/events`;
|
|
148
|
+
const response = await this.fetchImpl(`${this.baseUrl}${path}`, {
|
|
149
|
+
method: "GET",
|
|
150
|
+
headers: this.authHeaders(path, "text/event-stream"),
|
|
151
|
+
signal: input.signal
|
|
152
|
+
});
|
|
153
|
+
if (!response.ok) {
|
|
154
|
+
const text = await response.text();
|
|
155
|
+
const payload = text.length > 0 ? safeJsonParse(text) : null;
|
|
156
|
+
const message = typeof payload === "object" && payload && "error" in payload && typeof payload.error === "string" ? payload.error : `Request failed (${response.status})`;
|
|
157
|
+
throw new R5dctlApiError(message, { status: response.status, path, body: payload });
|
|
158
|
+
}
|
|
159
|
+
if (!response.body) {
|
|
160
|
+
throw new R5dctlApiError("Session event stream returned no body", { status: response.status, path, body: null });
|
|
161
|
+
}
|
|
162
|
+
yield* parseSseStream(response.body);
|
|
163
|
+
}
|
|
97
164
|
auth = {
|
|
98
165
|
deviceStart: (input) => this.request({
|
|
99
166
|
method: "POST",
|
|
@@ -270,41 +337,26 @@ class R5dctlClient {
|
|
|
270
337
|
method: "POST",
|
|
271
338
|
path: `/api/r5dctl/projects/${encodeURIComponent(projectRef)}/sessions`,
|
|
272
339
|
body: input
|
|
340
|
+
}),
|
|
341
|
+
start: (projectRef, input) => this.request({
|
|
342
|
+
method: "POST",
|
|
343
|
+
path: `/api/r5dctl/projects/${encodeURIComponent(projectRef)}/sessions/start`,
|
|
344
|
+
body: input
|
|
273
345
|
})
|
|
274
346
|
},
|
|
275
|
-
|
|
276
|
-
|
|
347
|
+
worktrees: {
|
|
348
|
+
merge: (projectRef, sourceWorktree, input) => this.request({
|
|
277
349
|
method: "POST",
|
|
278
|
-
path: `/api/r5dctl/projects/${encodeURIComponent(projectRef)}/
|
|
350
|
+
path: `/api/r5dctl/projects/${encodeURIComponent(projectRef)}/worktrees/${encodeURIComponent(sourceWorktree)}/merge`,
|
|
351
|
+
body: input
|
|
352
|
+
}),
|
|
353
|
+
finishMerge: (projectRef, conflictWorktree, input) => this.request({
|
|
354
|
+
method: "POST",
|
|
355
|
+
path: `/api/r5dctl/projects/${encodeURIComponent(projectRef)}/worktrees/${encodeURIComponent(conflictWorktree)}/merge/finish`,
|
|
279
356
|
body: input
|
|
280
357
|
})
|
|
281
358
|
}
|
|
282
359
|
};
|
|
283
|
-
agents = {
|
|
284
|
-
status: (sessionId) => this.request({
|
|
285
|
-
method: "GET",
|
|
286
|
-
path: `/api/r5dctl/agents/${encodeURIComponent(sessionId)}`
|
|
287
|
-
}),
|
|
288
|
-
sendPrompt: (sessionId, input) => this.request({
|
|
289
|
-
method: "POST",
|
|
290
|
-
path: `/api/r5dctl/agents/${encodeURIComponent(sessionId)}/prompt`,
|
|
291
|
-
body: input
|
|
292
|
-
}),
|
|
293
|
-
merge: (sessionId, input) => this.request({
|
|
294
|
-
method: "POST",
|
|
295
|
-
path: `/api/r5dctl/agents/${encodeURIComponent(sessionId)}/merge`,
|
|
296
|
-
body: input
|
|
297
|
-
}),
|
|
298
|
-
stop: (sessionId) => this.request({
|
|
299
|
-
method: "POST",
|
|
300
|
-
path: `/api/r5dctl/agents/${encodeURIComponent(sessionId)}/stop`
|
|
301
|
-
}),
|
|
302
|
-
finishMerge: (sessionId, input) => this.request({
|
|
303
|
-
method: "POST",
|
|
304
|
-
path: `/api/r5dctl/agents/${encodeURIComponent(sessionId)}/finish-merge`,
|
|
305
|
-
body: input
|
|
306
|
-
})
|
|
307
|
-
};
|
|
308
360
|
sessions = {
|
|
309
361
|
recent: (input = {}) => this.request({
|
|
310
362
|
method: "GET",
|
|
@@ -324,6 +376,11 @@ class R5dctlClient {
|
|
|
324
376
|
method: "DELETE",
|
|
325
377
|
path: `/api/r5dctl/sessions/${encodeURIComponent(sessionId)}`
|
|
326
378
|
}),
|
|
379
|
+
status: (sessionId) => this.request({
|
|
380
|
+
method: "GET",
|
|
381
|
+
path: `/api/r5dctl/sessions/${encodeURIComponent(sessionId)}/status`
|
|
382
|
+
}),
|
|
383
|
+
events: (sessionId, input = {}) => this.events(sessionId, input),
|
|
327
384
|
conversation: (sessionId, input = {}) => this.request({
|
|
328
385
|
method: "GET",
|
|
329
386
|
path: `/api/r5dctl/sessions/${encodeURIComponent(sessionId)}/conversation`,
|
|
@@ -353,6 +410,11 @@ class R5dctlClient {
|
|
|
353
410
|
path: `/api/r5dctl/sessions/${encodeURIComponent(sessionId)}/prompt`,
|
|
354
411
|
body: input
|
|
355
412
|
}),
|
|
413
|
+
stop: (sessionId) => this.request({
|
|
414
|
+
method: "POST",
|
|
415
|
+
path: `/api/r5dctl/sessions/${encodeURIComponent(sessionId)}/stop`,
|
|
416
|
+
body: {}
|
|
417
|
+
}),
|
|
356
418
|
answerQuestions: (sessionId, input) => this.request({
|
|
357
419
|
method: "POST",
|
|
358
420
|
path: `/api/r5dctl/sessions/${encodeURIComponent(sessionId)}/answer-questions`,
|
package/dist/mjs/package.json
CHANGED
package/dist/types/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export type ChatMode = "ask" | "plan" | "build" | "agent" | "
|
|
1
|
+
export type ChatMode = "ask" | "plan" | "build" | "agent" | "security_review" | "large_diff_remediation" | "merge_conflict_resolution";
|
|
2
|
+
export type R5dctlSessionMode = "ask" | "plan" | "build" | "agent";
|
|
2
3
|
export type ModelTier = "low" | "medium" | "high" | "max";
|
|
3
|
-
export type
|
|
4
|
-
export type R5dctlAgentSource = {
|
|
4
|
+
export type R5dctlWorktreeSource = {
|
|
5
5
|
type: "worktree";
|
|
6
6
|
branchName: string;
|
|
7
7
|
};
|
|
@@ -69,6 +69,86 @@ export type R5dctlConversationResponse = {
|
|
|
69
69
|
pendingQuestions: R5dctlPendingQuestion[];
|
|
70
70
|
requestedEnvs: R5dctlRequestedEnv[];
|
|
71
71
|
};
|
|
72
|
+
export type R5dctlSessionEvent = {
|
|
73
|
+
type: "text_delta";
|
|
74
|
+
text: string;
|
|
75
|
+
} | {
|
|
76
|
+
type: "thinking_delta";
|
|
77
|
+
text: string;
|
|
78
|
+
} | {
|
|
79
|
+
type: "tool_use_start";
|
|
80
|
+
toolCallId: string;
|
|
81
|
+
toolName: string;
|
|
82
|
+
} | {
|
|
83
|
+
type: "input_json_delta";
|
|
84
|
+
toolCallId: string;
|
|
85
|
+
partial_json: string;
|
|
86
|
+
} | {
|
|
87
|
+
type: "stream_reset";
|
|
88
|
+
attempt: number;
|
|
89
|
+
maxAttempts: number;
|
|
90
|
+
} | {
|
|
91
|
+
type: "tool_call";
|
|
92
|
+
data: unknown;
|
|
93
|
+
} | {
|
|
94
|
+
type: "tool_progress";
|
|
95
|
+
toolCallId: string;
|
|
96
|
+
progress: unknown;
|
|
97
|
+
} | {
|
|
98
|
+
type: "response";
|
|
99
|
+
data: {
|
|
100
|
+
node: unknown;
|
|
101
|
+
optimisticResponseId?: string;
|
|
102
|
+
conversationRevision: number;
|
|
103
|
+
};
|
|
104
|
+
} | {
|
|
105
|
+
type: "session";
|
|
106
|
+
data: unknown;
|
|
107
|
+
} | {
|
|
108
|
+
type: "status";
|
|
109
|
+
status: unknown;
|
|
110
|
+
statusVersion: number;
|
|
111
|
+
} | {
|
|
112
|
+
type: "files_updated";
|
|
113
|
+
files: unknown[];
|
|
114
|
+
} | {
|
|
115
|
+
type: "token_usage";
|
|
116
|
+
input: number;
|
|
117
|
+
output: number;
|
|
118
|
+
contextWindow?: number;
|
|
119
|
+
} | {
|
|
120
|
+
type: "queue_updated";
|
|
121
|
+
queue: unknown;
|
|
122
|
+
queueVersion: unknown;
|
|
123
|
+
} | {
|
|
124
|
+
type: "done";
|
|
125
|
+
} | {
|
|
126
|
+
type: "stopped";
|
|
127
|
+
} | {
|
|
128
|
+
type: "error";
|
|
129
|
+
message: string;
|
|
130
|
+
} | {
|
|
131
|
+
type: "agent_running";
|
|
132
|
+
running: boolean;
|
|
133
|
+
} | {
|
|
134
|
+
type: "context_continued";
|
|
135
|
+
sessionId: string;
|
|
136
|
+
target: unknown;
|
|
137
|
+
partNumber: number;
|
|
138
|
+
} | {
|
|
139
|
+
type: "context_handoff_failed";
|
|
140
|
+
message: string;
|
|
141
|
+
} | {
|
|
142
|
+
type: "shell_result";
|
|
143
|
+
stdout: string;
|
|
144
|
+
stderr: string;
|
|
145
|
+
exitCode: number;
|
|
146
|
+
fileChanges: unknown[];
|
|
147
|
+
cwd: string;
|
|
148
|
+
} | {
|
|
149
|
+
type: string;
|
|
150
|
+
[key: string]: unknown;
|
|
151
|
+
};
|
|
72
152
|
export type R5dctlConversationWorkDetail = "compact" | "summary" | "full";
|
|
73
153
|
export type R5dctlConversationWorkMetadata = {
|
|
74
154
|
id: string;
|
|
@@ -98,31 +178,31 @@ export type R5dctlConversationWorkResponse = {
|
|
|
98
178
|
detail: R5dctlConversationWorkDetail;
|
|
99
179
|
workText: string;
|
|
100
180
|
};
|
|
101
|
-
export type
|
|
102
|
-
export type
|
|
103
|
-
status: "merged" | "up_to_date" | "conflicts" | "resolving" | "failed" | "stale";
|
|
181
|
+
export type R5dctlSessionRunStatus = "idle" | "provisioning" | "queued" | "running" | "completed" | "failed" | "stopped";
|
|
182
|
+
export type R5dctlWorktreeMergeResponse = {
|
|
183
|
+
status: "merged" | "up_to_date" | "conflicts" | "conflict_worktree_created" | "resolving" | "failed" | "stale";
|
|
104
184
|
attemptId?: string;
|
|
105
|
-
|
|
106
|
-
|
|
185
|
+
sourceWorktree: string;
|
|
186
|
+
targetWorktree: string;
|
|
187
|
+
conflictWorktree?: string;
|
|
107
188
|
commitHash?: string;
|
|
108
189
|
resolverSessionId?: string;
|
|
109
|
-
resolverBranch?: string;
|
|
110
190
|
folderPath?: string;
|
|
111
191
|
worker?: string;
|
|
112
192
|
conflictedFiles?: string[];
|
|
113
193
|
failureReason?: string;
|
|
114
194
|
message?: string;
|
|
115
195
|
};
|
|
116
|
-
export type
|
|
196
|
+
export type R5dctlMergeConflictMode = "none" | "worktree" | "agent";
|
|
197
|
+
export type R5dctlSessionRunResponse = {
|
|
117
198
|
sessionId: string;
|
|
118
199
|
branchName: string;
|
|
119
|
-
source: R5dctlAgentSource;
|
|
120
200
|
baselineCommit: string | null;
|
|
121
201
|
workspaceHead: string | null;
|
|
122
202
|
worker: string;
|
|
123
|
-
status:
|
|
124
|
-
runStatus:
|
|
125
|
-
|
|
203
|
+
status: R5dctlSessionRunStatus;
|
|
204
|
+
runStatus: R5dctlSessionRunStatus;
|
|
205
|
+
generation: number;
|
|
126
206
|
createdAt: string;
|
|
127
207
|
updatedAt: string;
|
|
128
208
|
queuedAt?: string;
|
|
@@ -137,12 +217,31 @@ export type R5dctlAgentStatusResponse = {
|
|
|
137
217
|
diffSummary: string;
|
|
138
218
|
sessionPath: string;
|
|
139
219
|
sessionUrl?: string;
|
|
140
|
-
merge?: R5dctlAgentMergeStatus;
|
|
141
220
|
};
|
|
142
|
-
export type
|
|
143
|
-
export type
|
|
221
|
+
export type R5dctlSessionStartResponse = R5dctlSessionRunResponse;
|
|
222
|
+
export type R5dctlSessionStatusResponse = R5dctlSessionRunResponse;
|
|
223
|
+
export type R5dctlSessionPromptResponse = R5dctlSessionRunResponse & {
|
|
144
224
|
promptDisposition: "queued" | "started";
|
|
145
225
|
};
|
|
226
|
+
export type R5dctlSessionStopResponse = {
|
|
227
|
+
sessionId: string;
|
|
228
|
+
status: "stopped";
|
|
229
|
+
};
|
|
230
|
+
type R5dctlSessionStartBaseInput = {
|
|
231
|
+
worker: string;
|
|
232
|
+
model: ModelTier;
|
|
233
|
+
prompt: string;
|
|
234
|
+
requestId: string;
|
|
235
|
+
};
|
|
236
|
+
export type R5dctlSessionStartInput = R5dctlSessionStartBaseInput & ({
|
|
237
|
+
worktree: string;
|
|
238
|
+
newWorktree?: never;
|
|
239
|
+
source?: never;
|
|
240
|
+
} | {
|
|
241
|
+
worktree?: never;
|
|
242
|
+
newWorktree: string;
|
|
243
|
+
source: R5dctlWorktreeSource;
|
|
244
|
+
});
|
|
146
245
|
export type DeviceAuthorizationStartResponse = {
|
|
147
246
|
requestId: string;
|
|
148
247
|
deviceCode: string;
|
|
@@ -432,7 +531,9 @@ export declare class R5dctlClient {
|
|
|
432
531
|
setToken(token?: string): void;
|
|
433
532
|
setApiKey(apiKey?: string): void;
|
|
434
533
|
private resolveBearerToken;
|
|
534
|
+
private authHeaders;
|
|
435
535
|
private request;
|
|
536
|
+
private events;
|
|
436
537
|
readonly auth: {
|
|
437
538
|
deviceStart: (input: {
|
|
438
539
|
deviceName: string;
|
|
@@ -535,32 +636,19 @@ export declare class R5dctlClient {
|
|
|
535
636
|
branch?: string;
|
|
536
637
|
}) => Promise<R5dctlSessionSummary[]>;
|
|
537
638
|
create: (projectRef: string, input: R5dctlSessionCreateInput) => Promise<R5dctlSessionDescription>;
|
|
639
|
+
start: (projectRef: string, input: R5dctlSessionStartInput) => Promise<R5dctlSessionRunResponse>;
|
|
538
640
|
};
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
641
|
+
worktrees: {
|
|
642
|
+
merge: (projectRef: string, sourceWorktree: string, input: {
|
|
643
|
+
worker?: string;
|
|
644
|
+
conflictMode: R5dctlMergeConflictMode;
|
|
645
|
+
}) => Promise<R5dctlWorktreeMergeResponse>;
|
|
646
|
+
finishMerge: (projectRef: string, conflictWorktree: string, input: {
|
|
544
647
|
worker: string;
|
|
545
|
-
|
|
546
|
-
}) => Promise<
|
|
648
|
+
summary?: string;
|
|
649
|
+
}) => Promise<R5dctlWorktreeMergeResponse>;
|
|
547
650
|
};
|
|
548
651
|
};
|
|
549
|
-
readonly agents: {
|
|
550
|
-
status: (sessionId: string) => Promise<R5dctlAgentStatusResponse>;
|
|
551
|
-
sendPrompt: (sessionId: string, input: {
|
|
552
|
-
prompt: string;
|
|
553
|
-
worker: string;
|
|
554
|
-
}) => Promise<R5dctlAgentPromptResponse>;
|
|
555
|
-
merge: (sessionId: string, input: {
|
|
556
|
-
worker: string;
|
|
557
|
-
}) => Promise<R5dctlAgentStatusResponse>;
|
|
558
|
-
stop: (sessionId: string) => Promise<R5dctlAgentStatusResponse>;
|
|
559
|
-
finishMerge: (sessionId: string, input: {
|
|
560
|
-
worker: string;
|
|
561
|
-
summary: string;
|
|
562
|
-
}) => Promise<R5dctlAgentStatusResponse>;
|
|
563
|
-
};
|
|
564
652
|
readonly sessions: {
|
|
565
653
|
recent: (input?: {
|
|
566
654
|
limit?: number;
|
|
@@ -570,6 +658,10 @@ export declare class R5dctlClient {
|
|
|
570
658
|
delete: (sessionId: string) => Promise<{
|
|
571
659
|
success: boolean;
|
|
572
660
|
}>;
|
|
661
|
+
status: (sessionId: string) => Promise<R5dctlSessionRunResponse>;
|
|
662
|
+
events: (sessionId: string, input?: {
|
|
663
|
+
signal?: AbortSignal;
|
|
664
|
+
}) => AsyncGenerator<R5dctlSessionEvent, any, any>;
|
|
573
665
|
conversation: (sessionId: string, input?: R5dctlConversationRenderOptions) => Promise<R5dctlConversationResponse>;
|
|
574
666
|
conversationOverview: (sessionId: string) => Promise<R5dctlConversationOverviewResponse>;
|
|
575
667
|
inspectConversationNode: (sessionId: string, nodeId: string) => Promise<R5dctlConversationNodeResponse>;
|
|
@@ -577,16 +669,28 @@ export declare class R5dctlClient {
|
|
|
577
669
|
detail?: R5dctlConversationWorkDetail;
|
|
578
670
|
}) => Promise<R5dctlConversationWorkResponse>;
|
|
579
671
|
prompt: (sessionId: string, input: {
|
|
580
|
-
|
|
581
|
-
|
|
672
|
+
prompt: string;
|
|
673
|
+
worker: string;
|
|
674
|
+
mode: R5dctlSessionMode;
|
|
582
675
|
model: ModelTier;
|
|
583
|
-
|
|
676
|
+
requestId: string;
|
|
677
|
+
}) => Promise<R5dctlSessionPromptResponse>;
|
|
678
|
+
stop: (sessionId: string) => Promise<R5dctlSessionStopResponse>;
|
|
584
679
|
answerQuestions: (sessionId: string, input: {
|
|
585
680
|
answers: string[];
|
|
586
|
-
|
|
681
|
+
worker: string;
|
|
682
|
+
mode: ChatMode;
|
|
683
|
+
model: ModelTier;
|
|
684
|
+
requestId: string;
|
|
685
|
+
}) => Promise<R5dctlSessionPromptResponse>;
|
|
587
686
|
answerEnvRequest: (sessionId: string, input: {
|
|
588
687
|
envs?: string[];
|
|
589
688
|
additionalContext?: string;
|
|
590
|
-
|
|
689
|
+
worker: string;
|
|
690
|
+
mode: ChatMode;
|
|
691
|
+
model: ModelTier;
|
|
692
|
+
requestId: string;
|
|
693
|
+
}) => Promise<R5dctlSessionPromptResponse>;
|
|
591
694
|
};
|
|
592
695
|
}
|
|
696
|
+
export {};
|