@pstdio/sdk 0.6.0 → 0.8.0
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/api/extensions.d.ts +1 -1
- package/dist/api/index.d.ts +2 -1
- package/dist/api/sessions.d.ts +1 -1
- package/dist/api/settings.d.ts +1 -0
- package/dist/client/client.d.ts +4 -0
- package/dist/client/index.d.ts +5 -2
- package/dist/client/index.js +285 -19
- package/dist/client/request.d.ts +9 -0
- package/dist/client/sessions.d.ts +27 -5
- package/dist/client/settings.d.ts +7 -0
- package/dist/client/sse.d.ts +15 -0
- package/dist/client/sync.d.ts +35 -0
- package/dist/client/tickets.d.ts +4 -1
- package/dist/extensions/index.d.ts +1 -1
- package/dist/extensions/index.js +31 -0
- package/dist/extensions/kernel-slots.d.ts +124 -4
- package/dist/extensions/types/context.d.ts +34 -6
- package/dist/extensions/types/extension.d.ts +1 -1
- package/dist/plugins/helpers/followup-session.d.ts +6 -0
- package/dist/resources/index.d.ts +3 -0
- package/dist/resources/index.js +26 -0
- package/dist/resources/known-agents.d.ts +12 -0
- package/dist/resources/settings.d.ts +1 -0
- package/package.json +1 -1
package/dist/api/extensions.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export type { UpdateInstalledExtensionTemplateInput, UpdateInstalledExtensionTemplateResponse, } from "pstdio-api-contracts";
|
|
1
|
+
export type { CommandExecuteRequest, CommandExecuteResponse, DashboardExtensionMetadata, ExtensionCommandRecord, ExtensionDiagnostic, ExtensionMenuContribution, ExtensionNavigationRecord, ExtensionRecord, ExtensionRouteRecord, ExtensionSettingsPanelRecord, ExtensionViewRecord, ListExtensionAppearanceResponse, ListExtensionCommandsResponse, ListProjectExtensionsResponse, ProjectExtensionInstance, UpdateInstalledExtensionTemplateInput, UpdateInstalledExtensionTemplateResponse, } from "pstdio-api-contracts";
|
package/dist/api/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export type { ActionResult, ExecuteActionInput } from "./actions";
|
|
2
2
|
export type { SetupAgentInput, SetupAvailableAgentsInput, UpdateAgentInput } from "./agents";
|
|
3
|
-
export type { UpdateInstalledExtensionTemplateInput, UpdateInstalledExtensionTemplateResponse } from "./extensions";
|
|
3
|
+
export type { CommandExecuteRequest, CommandExecuteResponse, DashboardExtensionMetadata, ExtensionCommandRecord, ExtensionDiagnostic, ExtensionMenuContribution, ExtensionNavigationRecord, ExtensionRecord, ExtensionRouteRecord, ExtensionSettingsPanelRecord, ExtensionViewRecord, ListExtensionAppearanceResponse, ListExtensionCommandsResponse, ListProjectExtensionsResponse, ProjectExtensionInstance, UpdateInstalledExtensionTemplateInput, UpdateInstalledExtensionTemplateResponse, } from "./extensions";
|
|
4
4
|
export type { CreateProjectInput, RegisterRepoInput } from "./projects";
|
|
5
5
|
export type { ApprovalInput, CreateSessionInput, FollowUpInput, ResolveSessionIdInput, ResolveSessionIdResponse, SessionConversationResponse, } from "./sessions";
|
|
6
|
+
export type { Settings, UpdateSettingsInput } from "./settings";
|
|
6
7
|
export type { UpdateSkillInput } from "./skills";
|
|
7
8
|
export type { CreateAttemptStatusInput, CreateStatusInput } from "./statuses";
|
|
8
9
|
export type { CreateTagInput, CreateTagOptionInput, UpdateTagInput, UpdateTagOptionInput } from "./tags";
|
package/dist/api/sessions.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export type { ApprovalInput, CreateSessionInput, FollowUpInput, ListSessionActivityInput, ListSessionActivityResponse, ResolveSessionIdInput, ResolveSessionIdResponse, SessionConversationResponse, } from "pstdio-api-contracts";
|
|
1
|
+
export type { ApprovalInput, CreateSessionInput, FollowUpDecision, FollowUpInput, FollowUpResponse, ListSessionActivityInput, ListSessionActivityResponse, ResolveSessionIdInput, ResolveSessionIdResponse, SessionConversationResponse, } from "pstdio-api-contracts";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { Settings, UpdateSettingsInput } from "pstdio-api-contracts";
|
package/dist/client/client.d.ts
CHANGED
|
@@ -4,8 +4,10 @@ import { type ExtensionClient } from "./extensions";
|
|
|
4
4
|
import { type ProjectClient } from "./projects";
|
|
5
5
|
import type { ClientOptions } from "./request";
|
|
6
6
|
import { type SessionClient } from "./sessions";
|
|
7
|
+
import { type SettingsClient } from "./settings";
|
|
7
8
|
import { type SkillClient } from "./skills";
|
|
8
9
|
import { type StatusClient } from "./statuses";
|
|
10
|
+
import { type SyncClient } from "./sync";
|
|
9
11
|
import { type TagClient } from "./tags";
|
|
10
12
|
import { type TemplateClient } from "./templates";
|
|
11
13
|
import { type TicketClient } from "./tickets";
|
|
@@ -22,5 +24,7 @@ export type PstdioClient = {
|
|
|
22
24
|
agents: AgentClient;
|
|
23
25
|
actions: ActionClient;
|
|
24
26
|
extensions: ExtensionClient;
|
|
27
|
+
settings: SettingsClient;
|
|
28
|
+
sync: SyncClient;
|
|
25
29
|
};
|
|
26
30
|
export declare const createClient: (options?: ClientOptions) => PstdioClient;
|
package/dist/client/index.d.ts
CHANGED
|
@@ -3,10 +3,13 @@ export type { AgentClient } from "./agents";
|
|
|
3
3
|
export { createClient, type PstdioClient } from "./client";
|
|
4
4
|
export type { ExtensionClient } from "./extensions";
|
|
5
5
|
export type { ProjectClient } from "./projects";
|
|
6
|
-
export { type ClientOptions, createRequest, PstdioApiError, type RequestFn } from "./request";
|
|
7
|
-
export type { SessionClient } from "./sessions";
|
|
6
|
+
export { type ClientOptions, createRequest, PstdioApiError, type RequestFn, type RequestOptions, } from "./request";
|
|
7
|
+
export type { ListSessionsInput, SessionClient, SessionStreamConnection, SessionStreamHandlers } from "./sessions";
|
|
8
|
+
export type { SettingsClient } from "./settings";
|
|
8
9
|
export type { SkillClient } from "./skills";
|
|
10
|
+
export type { SseEvent } from "./sse";
|
|
9
11
|
export type { StatusClient } from "./statuses";
|
|
12
|
+
export { applySyncEvent, parseSyncDeleteEvent, type StartSyncInput, type SyncClient, type SyncConnection, type SyncRow, type SyncWriter, type SyncWriterProvider, } from "./sync";
|
|
10
13
|
export type { TagClient } from "./tags";
|
|
11
14
|
export type { TemplateClient } from "./templates";
|
|
12
15
|
export type { TicketClient } from "./tickets";
|
package/dist/client/index.js
CHANGED
|
@@ -107,20 +107,32 @@ ${hookOutput}` : message;
|
|
|
107
107
|
}
|
|
108
108
|
return `Request failed: ${status}`;
|
|
109
109
|
};
|
|
110
|
+
var resolveBaseUrl = (options) => options.baseUrl ?? (typeof process !== "undefined" ? process.env.PSTDIO_API_URL : undefined) ?? "http://localhost:19840";
|
|
111
|
+
var resolveClientUrl = (baseUrl, path) => path.startsWith("http://") || path.startsWith("https://") ? path : `${baseUrl}${path}`;
|
|
112
|
+
var resolveFetch = (options) => options.fetch ?? globalThis.fetch;
|
|
113
|
+
var createRequestHeaders = (options, reqOpts = {}) => {
|
|
114
|
+
const headers = new Headers(reqOpts.headers);
|
|
115
|
+
if (reqOpts.hasJsonBody && !headers.has("content-type"))
|
|
116
|
+
headers.set("content-type", "application/json");
|
|
117
|
+
if (options.token)
|
|
118
|
+
headers.set("authorization", `Bearer ${options.token}`);
|
|
119
|
+
return headers;
|
|
120
|
+
};
|
|
110
121
|
var createRequest = (options) => {
|
|
111
|
-
const baseUrl = options
|
|
112
|
-
const fetchFn = options
|
|
122
|
+
const baseUrl = resolveBaseUrl(options);
|
|
123
|
+
const fetchFn = resolveFetch(options);
|
|
113
124
|
return async (path, reqOpts = {}) => {
|
|
114
|
-
const headers = {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const response = await fetchFn(
|
|
125
|
+
const headers = createRequestHeaders(options, {
|
|
126
|
+
headers: reqOpts.headers,
|
|
127
|
+
hasJsonBody: reqOpts.body !== undefined
|
|
128
|
+
});
|
|
129
|
+
const url = resolveClientUrl(baseUrl, path);
|
|
130
|
+
const response = await fetchFn(url, {
|
|
120
131
|
method: reqOpts.method ?? "GET",
|
|
121
|
-
headers,
|
|
132
|
+
headers: Object.fromEntries(headers.entries()),
|
|
122
133
|
body: reqOpts.body !== undefined ? JSON.stringify(reqOpts.body) : undefined,
|
|
123
|
-
signal: reqOpts.signal
|
|
134
|
+
signal: reqOpts.signal,
|
|
135
|
+
cache: reqOpts.cache
|
|
124
136
|
});
|
|
125
137
|
if (!response.ok) {
|
|
126
138
|
const errorBody = await response.json().catch(() => null);
|
|
@@ -133,8 +145,105 @@ var createRequest = (options) => {
|
|
|
133
145
|
};
|
|
134
146
|
};
|
|
135
147
|
|
|
148
|
+
// src/client/sse.ts
|
|
149
|
+
var parseSseEvent = (part) => {
|
|
150
|
+
let event = "message";
|
|
151
|
+
const data = [];
|
|
152
|
+
for (const line of part.split(`
|
|
153
|
+
`)) {
|
|
154
|
+
if (line.startsWith("event: ")) {
|
|
155
|
+
event = line.slice(7);
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (line.startsWith("data: ")) {
|
|
159
|
+
data.push(line.slice(6));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (!event || data.length === 0)
|
|
163
|
+
return null;
|
|
164
|
+
return { event, data: data.join(`
|
|
165
|
+
`) };
|
|
166
|
+
};
|
|
167
|
+
var consumeSseBuffer = (buffer) => {
|
|
168
|
+
const parts = buffer.split(`
|
|
169
|
+
|
|
170
|
+
`);
|
|
171
|
+
const remainder = parts.pop() ?? "";
|
|
172
|
+
const events = parts.map((part) => parseSseEvent(part)).filter((event) => event !== null);
|
|
173
|
+
return { remainder, events };
|
|
174
|
+
};
|
|
175
|
+
var readSseStream = async (body, onEvent, options = {}) => {
|
|
176
|
+
const reader = body.getReader();
|
|
177
|
+
const decoder = new TextDecoder;
|
|
178
|
+
let buffer = "";
|
|
179
|
+
const abort = () => {
|
|
180
|
+
reader.cancel();
|
|
181
|
+
};
|
|
182
|
+
options.signal?.addEventListener("abort", abort, { once: true });
|
|
183
|
+
try {
|
|
184
|
+
while (!options.signal?.aborted) {
|
|
185
|
+
const { done, value } = await reader.read();
|
|
186
|
+
if (done)
|
|
187
|
+
break;
|
|
188
|
+
buffer += decoder.decode(value, { stream: true });
|
|
189
|
+
const { remainder, events } = consumeSseBuffer(buffer);
|
|
190
|
+
buffer = remainder;
|
|
191
|
+
for (const event of events) {
|
|
192
|
+
onEvent(event);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
} finally {
|
|
196
|
+
options.signal?.removeEventListener("abort", abort);
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
|
|
136
200
|
// src/client/sessions.ts
|
|
137
|
-
var
|
|
201
|
+
var buildSessionsQuery = (projectId, input = {}) => {
|
|
202
|
+
const params = new URLSearchParams({ project_id: projectId });
|
|
203
|
+
if (input.status)
|
|
204
|
+
params.append("status", input.status);
|
|
205
|
+
if (input.agent)
|
|
206
|
+
params.append("agent", input.agent);
|
|
207
|
+
if (input.archived)
|
|
208
|
+
params.append("archived", "true");
|
|
209
|
+
return params.toString();
|
|
210
|
+
};
|
|
211
|
+
var buildSessionStreamPath = (sessionId, attempt) => {
|
|
212
|
+
const path = `/v1/sessions/${sessionId}/stream`;
|
|
213
|
+
return attempt === undefined ? path : `${path}?attempt=${attempt}`;
|
|
214
|
+
};
|
|
215
|
+
var parseEventData = (data) => {
|
|
216
|
+
if (data.length === 0)
|
|
217
|
+
return null;
|
|
218
|
+
return JSON.parse(data);
|
|
219
|
+
};
|
|
220
|
+
var streamSessionEvents = async (clientOptions, path, onEvent, options = {}) => {
|
|
221
|
+
const response = await resolveFetch(clientOptions)(resolveClientUrl(resolveBaseUrl(clientOptions), path), {
|
|
222
|
+
headers: Object.fromEntries(createRequestHeaders(clientOptions).entries()),
|
|
223
|
+
signal: options.signal
|
|
224
|
+
});
|
|
225
|
+
if (!response.ok || !response.body)
|
|
226
|
+
throw new Error(`Connection failed: ${response.status}`);
|
|
227
|
+
await readSseStream(response.body, onEvent, { signal: options.signal });
|
|
228
|
+
};
|
|
229
|
+
var dispatchSessionStreamEvent = (event, handlers) => {
|
|
230
|
+
if (event.event === "ready") {
|
|
231
|
+
handlers.onReady?.(parseEventData(event.data));
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
if (event.event === "patch") {
|
|
235
|
+
handlers.onPatch?.(parseEventData(event.data));
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
if (event.event === "approval_request") {
|
|
239
|
+
handlers.onApprovalRequest?.(parseEventData(event.data));
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
if (event.event === "end") {
|
|
243
|
+
handlers.onEnd?.(parseEventData(event.data));
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
var createSessionClient = (request, clientOptions) => ({
|
|
138
247
|
listActivity: (sessionId, input = {}) => {
|
|
139
248
|
const params = new URLSearchParams;
|
|
140
249
|
if (input.event_type)
|
|
@@ -150,7 +259,7 @@ var createSessionClient = (request) => ({
|
|
|
150
259
|
const query = params.toString();
|
|
151
260
|
return request(`/v1/sessions/${sessionId}/activity${query ? `?${query}` : ""}`);
|
|
152
261
|
},
|
|
153
|
-
list: (projectId) => request(`/v1/sessions
|
|
262
|
+
list: (projectId, input) => request(`/v1/sessions?${buildSessionsQuery(projectId, input)}`),
|
|
154
263
|
get: (sessionId) => request(`/v1/sessions/${sessionId}`),
|
|
155
264
|
create: (input) => request("/v1/sessions", { method: "POST", body: input }),
|
|
156
265
|
archive: (sessionId) => request(`/v1/sessions/${sessionId}/archive`, { method: "POST" }),
|
|
@@ -158,7 +267,29 @@ var createSessionClient = (request) => ({
|
|
|
158
267
|
approve: (sessionId, input) => request(`/v1/sessions/${sessionId}/approve`, { method: "POST", body: input }),
|
|
159
268
|
getConversation: (sessionId) => request(`/v1/sessions/${sessionId}/conversation`),
|
|
160
269
|
resolveSessionId: (input) => request("/v1/sessions/resolve-session-id", { method: "POST", body: input }),
|
|
161
|
-
updateStatus: (sessionId, status) => request(`/v1/sessions/${sessionId}/status`, { method: "PATCH", body: { status } })
|
|
270
|
+
updateStatus: (sessionId, status) => request(`/v1/sessions/${sessionId}/status`, { method: "PATCH", body: { status } }),
|
|
271
|
+
stream: (sessionId, onEvent, options = {}) => streamSessionEvents(clientOptions, buildSessionStreamPath(sessionId), onEvent, options),
|
|
272
|
+
connectStream: (sessionId, handlers, options = {}) => {
|
|
273
|
+
const abortController = new AbortController;
|
|
274
|
+
let closed = false;
|
|
275
|
+
streamSessionEvents(clientOptions, buildSessionStreamPath(sessionId, options.attempt), (event) => dispatchSessionStreamEvent(event, handlers), { signal: abortController.signal }).catch((error) => {
|
|
276
|
+
if (closed || error.name === "AbortError")
|
|
277
|
+
return;
|
|
278
|
+
handlers.onError?.(error);
|
|
279
|
+
});
|
|
280
|
+
return {
|
|
281
|
+
close: () => {
|
|
282
|
+
closed = true;
|
|
283
|
+
abortController.abort();
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
// src/client/settings.ts
|
|
290
|
+
var createSettingsClient = (request) => ({
|
|
291
|
+
get: () => request("/v1/settings"),
|
|
292
|
+
update: (input) => request("/v1/settings", { method: "PATCH", body: input })
|
|
162
293
|
});
|
|
163
294
|
|
|
164
295
|
// src/client/skills.ts
|
|
@@ -181,6 +312,137 @@ var createStatusClient = (request) => ({
|
|
|
181
312
|
deleteAttemptStatus: (projectId, statusId) => request(`/v1/projects/${projectId}/attempt-statuses/${statusId}`, { method: "DELETE" })
|
|
182
313
|
});
|
|
183
314
|
|
|
315
|
+
// src/client/sync.ts
|
|
316
|
+
var DEFAULT_HEARTBEAT_INTERVAL_MS = 1e4;
|
|
317
|
+
var DEFAULT_HEARTBEAT_THRESHOLD = 3;
|
|
318
|
+
var DEFAULT_RECONNECT_DELAY_MS = 1000;
|
|
319
|
+
var parseSyncDeleteEvent = (data) => {
|
|
320
|
+
const parsed = JSON.parse(data);
|
|
321
|
+
const id = parsed.id ?? parsed.data?.id;
|
|
322
|
+
if (!id) {
|
|
323
|
+
throw new Error("Missing id in sync:delete event.");
|
|
324
|
+
}
|
|
325
|
+
return {
|
|
326
|
+
table: parsed.table,
|
|
327
|
+
id,
|
|
328
|
+
seq: parsed.seq
|
|
329
|
+
};
|
|
330
|
+
};
|
|
331
|
+
var applySyncEvent = (event, data, writers) => {
|
|
332
|
+
if (event === "init") {
|
|
333
|
+
const parsed = JSON.parse(data);
|
|
334
|
+
for (const [table, rows] of Object.entries(parsed.tables)) {
|
|
335
|
+
writers.getWriter(table)?.truncateAndWrite(rows);
|
|
336
|
+
}
|
|
337
|
+
return parsed.seq;
|
|
338
|
+
}
|
|
339
|
+
if (event === "sync:set") {
|
|
340
|
+
const parsed = JSON.parse(data);
|
|
341
|
+
writers.getWriter(parsed.table)?.upsert(parsed.data);
|
|
342
|
+
return parsed.seq;
|
|
343
|
+
}
|
|
344
|
+
if (event === "sync:delete") {
|
|
345
|
+
const parsed = parseSyncDeleteEvent(data);
|
|
346
|
+
writers.getWriter(parsed.table)?.remove(parsed.id);
|
|
347
|
+
return parsed.seq;
|
|
348
|
+
}
|
|
349
|
+
if (event === "heartbeat") {
|
|
350
|
+
return JSON.parse(data).seq;
|
|
351
|
+
}
|
|
352
|
+
return null;
|
|
353
|
+
};
|
|
354
|
+
var createHeartbeatMonitor = (input) => {
|
|
355
|
+
let missedHeartbeats = 0;
|
|
356
|
+
let timer = null;
|
|
357
|
+
return {
|
|
358
|
+
recordHeartbeat: () => {
|
|
359
|
+
missedHeartbeats = 0;
|
|
360
|
+
},
|
|
361
|
+
start: () => {
|
|
362
|
+
timer = setInterval(() => {
|
|
363
|
+
missedHeartbeats += 1;
|
|
364
|
+
if (missedHeartbeats >= input.threshold) {
|
|
365
|
+
input.onConnectionLost?.();
|
|
366
|
+
}
|
|
367
|
+
}, input.intervalMs);
|
|
368
|
+
},
|
|
369
|
+
stop: () => {
|
|
370
|
+
if (timer)
|
|
371
|
+
clearInterval(timer);
|
|
372
|
+
timer = null;
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
};
|
|
376
|
+
var buildSyncStreamPath = (lastSeq) => lastSeq > 0 ? `/v1/sync/stream?since=${lastSeq}` : "/v1/sync/stream";
|
|
377
|
+
var createSyncClient = (clientOptions) => ({
|
|
378
|
+
start: (input) => {
|
|
379
|
+
let lastSeq = 0;
|
|
380
|
+
let abortController = null;
|
|
381
|
+
let reconnectTimer = null;
|
|
382
|
+
let closed = false;
|
|
383
|
+
const state = { close: () => {}, connected: false };
|
|
384
|
+
const heartbeatMonitor = createHeartbeatMonitor({
|
|
385
|
+
intervalMs: input.heartbeatIntervalMs ?? DEFAULT_HEARTBEAT_INTERVAL_MS,
|
|
386
|
+
threshold: input.heartbeatThreshold ?? DEFAULT_HEARTBEAT_THRESHOLD,
|
|
387
|
+
onConnectionLost: input.onConnectionLost
|
|
388
|
+
});
|
|
389
|
+
const setConnected = () => {
|
|
390
|
+
const wasConnected = state.connected;
|
|
391
|
+
state.connected = true;
|
|
392
|
+
if (!wasConnected)
|
|
393
|
+
input.onConnected?.();
|
|
394
|
+
};
|
|
395
|
+
const setDisconnected = () => {
|
|
396
|
+
const wasConnected = state.connected;
|
|
397
|
+
state.connected = false;
|
|
398
|
+
if (wasConnected)
|
|
399
|
+
input.onDisconnected?.();
|
|
400
|
+
};
|
|
401
|
+
const handleEvent = (event, data) => {
|
|
402
|
+
heartbeatMonitor.recordHeartbeat();
|
|
403
|
+
const nextSeq = applySyncEvent(event, data, input);
|
|
404
|
+
if (nextSeq !== null)
|
|
405
|
+
lastSeq = Math.max(lastSeq, nextSeq);
|
|
406
|
+
if (event === "init")
|
|
407
|
+
setConnected();
|
|
408
|
+
};
|
|
409
|
+
const connect = async () => {
|
|
410
|
+
if (closed)
|
|
411
|
+
return;
|
|
412
|
+
abortController = new AbortController;
|
|
413
|
+
try {
|
|
414
|
+
const response = await resolveFetch(clientOptions)(resolveClientUrl(resolveBaseUrl(clientOptions), buildSyncStreamPath(lastSeq)), {
|
|
415
|
+
headers: Object.fromEntries(createRequestHeaders(clientOptions).entries()),
|
|
416
|
+
signal: abortController.signal
|
|
417
|
+
});
|
|
418
|
+
if (!response.ok || !response.body)
|
|
419
|
+
throw new Error("SSE connection failed");
|
|
420
|
+
await readSseStream(response.body, ({ event, data }) => handleEvent(event, data), {
|
|
421
|
+
signal: abortController.signal
|
|
422
|
+
});
|
|
423
|
+
} catch (err) {
|
|
424
|
+
if (closed || err.name === "AbortError")
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
if (closed)
|
|
428
|
+
return;
|
|
429
|
+
setDisconnected();
|
|
430
|
+
reconnectTimer = setTimeout(connect, input.reconnectDelayMs ?? DEFAULT_RECONNECT_DELAY_MS);
|
|
431
|
+
};
|
|
432
|
+
heartbeatMonitor.start();
|
|
433
|
+
connect();
|
|
434
|
+
state.close = () => {
|
|
435
|
+
closed = true;
|
|
436
|
+
state.connected = false;
|
|
437
|
+
heartbeatMonitor.stop();
|
|
438
|
+
abortController?.abort();
|
|
439
|
+
if (reconnectTimer)
|
|
440
|
+
clearTimeout(reconnectTimer);
|
|
441
|
+
};
|
|
442
|
+
return state;
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
|
|
184
446
|
// src/client/tags.ts
|
|
185
447
|
var createTagClient = (request) => ({
|
|
186
448
|
list: (projectId) => request(`/v1/projects/${projectId}/ticket-tags`),
|
|
@@ -202,7 +464,7 @@ var createTemplateClient = (request) => ({
|
|
|
202
464
|
});
|
|
203
465
|
|
|
204
466
|
// src/client/tickets.ts
|
|
205
|
-
var
|
|
467
|
+
var resolveBaseUrl2 = (options) => options.baseUrl ?? (typeof process !== "undefined" ? process.env.PSTDIO_API_URL : undefined) ?? "http://localhost:19840";
|
|
206
468
|
var readErrorMessage2 = async (response) => {
|
|
207
469
|
const errorBody = await response.json().catch(() => null);
|
|
208
470
|
if (errorBody && typeof errorBody === "object" && errorBody !== null && "error" in errorBody) {
|
|
@@ -265,13 +527,13 @@ var createTicketClient = (request, options = {}) => ({
|
|
|
265
527
|
},
|
|
266
528
|
updateWhenAttemptStatus: (ticketId, input) => request(`/v1/tickets/${ticketId}/update-when-attempt-status`, { method: "POST", body: input }),
|
|
267
529
|
listFiles: (ticketId) => request(`/v1/tickets/${ticketId}/files`),
|
|
268
|
-
getFileContent: async (ticketId, fileId) => {
|
|
269
|
-
const baseUrl =
|
|
530
|
+
getFileContent: async (ticketId, fileId, requestOptions = {}) => {
|
|
531
|
+
const baseUrl = resolveBaseUrl2(options);
|
|
270
532
|
const fetchFn = options.fetch ?? globalThis.fetch;
|
|
271
533
|
const headers = {};
|
|
272
534
|
if (options.token)
|
|
273
535
|
headers.authorization = `Bearer ${options.token}`;
|
|
274
|
-
const response = await fetchFn(`${baseUrl}/v1/tickets/${encodeURIComponent(ticketId)}/files/${encodeURIComponent(fileId)}/content`, { headers });
|
|
536
|
+
const response = await fetchFn(`${baseUrl}/v1/tickets/${encodeURIComponent(ticketId)}/files/${encodeURIComponent(fileId)}/content`, { cache: requestOptions.cache, headers, signal: requestOptions.signal });
|
|
275
537
|
if (!response.ok) {
|
|
276
538
|
throw new PstdioApiError(await readErrorMessage2(response), response.status);
|
|
277
539
|
}
|
|
@@ -313,18 +575,22 @@ var createClient = (options = {}) => {
|
|
|
313
575
|
projects: createProjectClient(request),
|
|
314
576
|
tickets: createTicketClient(request, options),
|
|
315
577
|
workspaces: createWorkspaceClient(request),
|
|
316
|
-
sessions: createSessionClient(request),
|
|
578
|
+
sessions: createSessionClient(request, options),
|
|
317
579
|
statuses: createStatusClient(request),
|
|
318
580
|
tags: createTagClient(request),
|
|
319
581
|
templates: createTemplateClient(request),
|
|
320
582
|
skills: createSkillClient(request),
|
|
321
583
|
agents: createAgentClient(request),
|
|
322
584
|
actions: createActionClient(request),
|
|
323
|
-
extensions: createExtensionClient(request)
|
|
585
|
+
extensions: createExtensionClient(request),
|
|
586
|
+
settings: createSettingsClient(request),
|
|
587
|
+
sync: createSyncClient(options)
|
|
324
588
|
};
|
|
325
589
|
};
|
|
326
590
|
export {
|
|
591
|
+
parseSyncDeleteEvent,
|
|
327
592
|
createRequest,
|
|
328
593
|
createClient,
|
|
594
|
+
applySyncEvent,
|
|
329
595
|
PstdioApiError
|
|
330
596
|
};
|
package/dist/client/request.d.ts
CHANGED
|
@@ -11,6 +11,15 @@ export type RequestOptions = {
|
|
|
11
11
|
method?: string;
|
|
12
12
|
body?: unknown;
|
|
13
13
|
signal?: AbortSignal;
|
|
14
|
+
headers?: HeadersInit;
|
|
15
|
+
cache?: RequestCache;
|
|
14
16
|
};
|
|
15
17
|
export type RequestFn = <T>(path: string, options?: RequestOptions) => Promise<T>;
|
|
18
|
+
export declare const resolveBaseUrl: (options: ClientOptions) => string;
|
|
19
|
+
export declare const resolveClientUrl: (baseUrl: string, path: string) => string;
|
|
20
|
+
export declare const resolveFetch: (options: ClientOptions) => typeof fetch;
|
|
21
|
+
export declare const createRequestHeaders: (options: ClientOptions, reqOpts?: {
|
|
22
|
+
headers?: HeadersInit;
|
|
23
|
+
hasJsonBody?: boolean;
|
|
24
|
+
}) => Headers;
|
|
16
25
|
export declare const createRequest: (options: ClientOptions) => RequestFn;
|
|
@@ -1,16 +1,38 @@
|
|
|
1
|
-
import type { ApprovalInput, CreateSessionInput, FollowUpInput, ListSessionActivityInput, ListSessionActivityResponse, ResolveSessionIdInput, ResolveSessionIdResponse, SessionConversationResponse } from "pstdio-api-contracts";
|
|
1
|
+
import type { ApprovalInput, CreateSessionInput, FollowUpInput, FollowUpResponse, ListSessionActivityInput, ListSessionActivityResponse, ResolveSessionIdInput, ResolveSessionIdResponse, SessionConversationResponse } from "pstdio-api-contracts";
|
|
2
2
|
import type { Session } from "../resources";
|
|
3
|
-
import type
|
|
3
|
+
import { type ClientOptions, type RequestFn } from "./request";
|
|
4
|
+
import { type SseEvent } from "./sse";
|
|
5
|
+
export type ListSessionsInput = {
|
|
6
|
+
status?: string;
|
|
7
|
+
agent?: string;
|
|
8
|
+
archived?: boolean;
|
|
9
|
+
};
|
|
4
10
|
export type SessionClient = {
|
|
5
|
-
list(projectId: string): Promise<Session[]>;
|
|
11
|
+
list(projectId: string, input?: ListSessionsInput): Promise<Session[]>;
|
|
6
12
|
get(sessionId: string): Promise<Session>;
|
|
7
13
|
create(input: CreateSessionInput): Promise<Session>;
|
|
8
14
|
archive(sessionId: string): Promise<void>;
|
|
9
|
-
followUp(sessionId: string, input: FollowUpInput): Promise<
|
|
15
|
+
followUp(sessionId: string, input: FollowUpInput): Promise<FollowUpResponse>;
|
|
10
16
|
approve(sessionId: string, input: ApprovalInput): Promise<void>;
|
|
11
17
|
getConversation(sessionId: string): Promise<SessionConversationResponse>;
|
|
12
18
|
resolveSessionId(input: ResolveSessionIdInput): Promise<ResolveSessionIdResponse>;
|
|
13
19
|
updateStatus(sessionId: string, status: string): Promise<Session>;
|
|
14
20
|
listActivity(sessionId: string, input?: ListSessionActivityInput): Promise<ListSessionActivityResponse>;
|
|
21
|
+
stream(sessionId: string, onEvent: (event: SseEvent) => void, options?: {
|
|
22
|
+
signal?: AbortSignal;
|
|
23
|
+
}): Promise<void>;
|
|
24
|
+
connectStream(sessionId: string, handlers: SessionStreamHandlers, options?: {
|
|
25
|
+
attempt?: number;
|
|
26
|
+
}): SessionStreamConnection;
|
|
27
|
+
};
|
|
28
|
+
export type SessionStreamHandlers = {
|
|
29
|
+
onReady?: (data: unknown) => void;
|
|
30
|
+
onPatch?: (data: unknown) => void;
|
|
31
|
+
onApprovalRequest?: (data: unknown) => void;
|
|
32
|
+
onEnd?: (data: unknown) => void;
|
|
33
|
+
onError?: (error: unknown) => void;
|
|
34
|
+
};
|
|
35
|
+
export type SessionStreamConnection = {
|
|
36
|
+
close: () => void;
|
|
15
37
|
};
|
|
16
|
-
export declare const createSessionClient: (request: RequestFn) => SessionClient;
|
|
38
|
+
export declare const createSessionClient: (request: RequestFn, clientOptions: ClientOptions) => SessionClient;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Settings, UpdateSettingsInput } from "../api/settings";
|
|
2
|
+
import type { RequestFn } from "./request";
|
|
3
|
+
export type SettingsClient = {
|
|
4
|
+
get(): Promise<Settings>;
|
|
5
|
+
update(input: UpdateSettingsInput): Promise<Settings>;
|
|
6
|
+
};
|
|
7
|
+
export declare const createSettingsClient: (request: RequestFn) => SettingsClient;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type SseEvent = {
|
|
2
|
+
event: string;
|
|
3
|
+
data: string;
|
|
4
|
+
};
|
|
5
|
+
export declare const parseSseEvent: (part: string) => {
|
|
6
|
+
event: string;
|
|
7
|
+
data: string;
|
|
8
|
+
} | null;
|
|
9
|
+
export declare const consumeSseBuffer: (buffer: string) => {
|
|
10
|
+
remainder: string;
|
|
11
|
+
events: SseEvent[];
|
|
12
|
+
};
|
|
13
|
+
export declare const readSseStream: (body: ReadableStream<Uint8Array>, onEvent: (event: SseEvent) => void, options?: {
|
|
14
|
+
signal?: AbortSignal;
|
|
15
|
+
}) => Promise<void>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type ClientOptions } from "./request";
|
|
2
|
+
export type SyncRow = {
|
|
3
|
+
id: string;
|
|
4
|
+
[key: string]: unknown;
|
|
5
|
+
};
|
|
6
|
+
export type SyncWriter = {
|
|
7
|
+
truncateAndWrite: (rows: SyncRow[]) => void;
|
|
8
|
+
upsert: (row: SyncRow) => void;
|
|
9
|
+
remove: (id: string) => void;
|
|
10
|
+
};
|
|
11
|
+
export type SyncWriterProvider = {
|
|
12
|
+
getWriter: (table: string) => SyncWriter | undefined;
|
|
13
|
+
};
|
|
14
|
+
export type SyncConnection = {
|
|
15
|
+
close: () => void;
|
|
16
|
+
connected: boolean;
|
|
17
|
+
};
|
|
18
|
+
export type StartSyncInput = SyncWriterProvider & {
|
|
19
|
+
onConnected?: () => void;
|
|
20
|
+
onDisconnected?: () => void;
|
|
21
|
+
onConnectionLost?: () => void;
|
|
22
|
+
heartbeatIntervalMs?: number;
|
|
23
|
+
heartbeatThreshold?: number;
|
|
24
|
+
reconnectDelayMs?: number;
|
|
25
|
+
};
|
|
26
|
+
export type SyncClient = {
|
|
27
|
+
start: (input: StartSyncInput) => SyncConnection;
|
|
28
|
+
};
|
|
29
|
+
export declare const parseSyncDeleteEvent: (data: string) => {
|
|
30
|
+
table: string;
|
|
31
|
+
id: string;
|
|
32
|
+
seq: number;
|
|
33
|
+
};
|
|
34
|
+
export declare const applySyncEvent: (event: string, data: string, writers: SyncWriterProvider) => number | null;
|
|
35
|
+
export declare const createSyncClient: (clientOptions: ClientOptions) => SyncClient;
|
package/dist/client/tickets.d.ts
CHANGED
|
@@ -12,7 +12,10 @@ export type TicketClient = {
|
|
|
12
12
|
listProjectActivity(projectId: string, input?: ListProjectActivityForTicketsInput): Promise<ListTicketActivityResponse>;
|
|
13
13
|
updateWhenAttemptStatus(ticketId: string, input: UpdateWhenAttemptStatusInput): Promise<UpdateWhenAttemptStatusResponse>;
|
|
14
14
|
listFiles(ticketId: string): Promise<TicketFile[]>;
|
|
15
|
-
getFileContent(ticketId: string, fileId: string
|
|
15
|
+
getFileContent(ticketId: string, fileId: string, options?: {
|
|
16
|
+
cache?: RequestCache;
|
|
17
|
+
signal?: AbortSignal;
|
|
18
|
+
}): Promise<Uint8Array>;
|
|
16
19
|
uploadFile(ticketId: string, input: UploadTicketFileInput): Promise<TicketFile>;
|
|
17
20
|
deleteFile(ticketId: string, fileId: string): Promise<void>;
|
|
18
21
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { defineCommand, defineHook, defineMiddleware } from "./define-command";
|
|
2
2
|
export { defineExtension } from "./define-extension";
|
|
3
3
|
export { defineExtensionView, type ExtensionViewModule, type ExtensionViewRender, type ExtensionViewRenderContext, type GuestHost, type PropsStore, } from "./define-extension-view";
|
|
4
|
-
export { projectEvents, projectSlots, sessionEvents, sessionSlots, workspaceEvents, workspaceSlots, } from "./kernel-slots";
|
|
4
|
+
export { attemptStatusEvents, gitEvents, projectEvents, projectSlots, sessionEvents, sessionSlots, ticketEvents, workspaceCommands, workspaceEvents, workspaceSlots, worktreeEvents, } from "./kernel-slots";
|
|
5
5
|
export { packageAsset } from "./package-asset";
|
|
6
6
|
export { params } from "./params";
|
|
7
7
|
export { commandEvent, commandRef, commandsOf, eventRef } from "./refs";
|
package/dist/extensions/index.js
CHANGED
|
@@ -60,13 +60,39 @@ var projectEvents = {
|
|
|
60
60
|
};
|
|
61
61
|
var sessionEvents = {
|
|
62
62
|
started: eventRef("session.started"),
|
|
63
|
+
resumed: eventRef("session.resumed"),
|
|
64
|
+
awaitingInput: eventRef("session.awaitingInput"),
|
|
65
|
+
succeeded: eventRef("session.succeeded"),
|
|
66
|
+
failed: eventRef("session.failed"),
|
|
63
67
|
completed: eventRef("session.completed")
|
|
64
68
|
};
|
|
69
|
+
var ticketEvents = {
|
|
70
|
+
created: eventRef("ticket.created"),
|
|
71
|
+
statusChanged: eventRef("ticket.statusChanged"),
|
|
72
|
+
archived: eventRef("ticket.archived"),
|
|
73
|
+
deleted: eventRef("ticket.deleted")
|
|
74
|
+
};
|
|
65
75
|
var workspaceEvents = {
|
|
66
76
|
created: eventRef("workspace.created"),
|
|
67
77
|
archived: eventRef("workspace.archived"),
|
|
68
78
|
deleted: eventRef("workspace.deleted")
|
|
69
79
|
};
|
|
80
|
+
var worktreeEvents = {
|
|
81
|
+
created: eventRef("worktree.created"),
|
|
82
|
+
removed: eventRef("worktree.removed")
|
|
83
|
+
};
|
|
84
|
+
var gitEvents = {
|
|
85
|
+
committed: eventRef("git.committed"),
|
|
86
|
+
rebased: eventRef("git.rebased"),
|
|
87
|
+
merged: eventRef("git.merged"),
|
|
88
|
+
conflicted: eventRef("git.conflicted")
|
|
89
|
+
};
|
|
90
|
+
var attemptStatusEvents = {
|
|
91
|
+
changed: eventRef("attemptStatus.changed")
|
|
92
|
+
};
|
|
93
|
+
var workspaceCommands = {
|
|
94
|
+
setAttemptStatus: commandRef("kernel.workspace.setAttemptStatus")
|
|
95
|
+
};
|
|
70
96
|
// src/extensions/package-asset.ts
|
|
71
97
|
var packageAsset = (path, baseUrl) => ({
|
|
72
98
|
kind: "package-asset",
|
|
@@ -115,14 +141,18 @@ var WEBVIEW_HOST_CAPABILITIES = [
|
|
|
115
141
|
...ALWAYS_AVAILABLE_WEBVIEW_CAPABILITIES
|
|
116
142
|
];
|
|
117
143
|
export {
|
|
144
|
+
worktreeEvents,
|
|
118
145
|
workspaceSlots,
|
|
119
146
|
workspaceEvents,
|
|
147
|
+
workspaceCommands,
|
|
148
|
+
ticketEvents,
|
|
120
149
|
sessionSlots,
|
|
121
150
|
sessionEvents,
|
|
122
151
|
projectSlots,
|
|
123
152
|
projectEvents,
|
|
124
153
|
params,
|
|
125
154
|
packageAsset,
|
|
155
|
+
gitEvents,
|
|
126
156
|
eventRef,
|
|
127
157
|
defineSlot,
|
|
128
158
|
defineMiddleware,
|
|
@@ -133,6 +163,7 @@ export {
|
|
|
133
163
|
commandsOf,
|
|
134
164
|
commandRef,
|
|
135
165
|
commandEvent,
|
|
166
|
+
attemptStatusEvents,
|
|
136
167
|
WEBVIEW_HOST_CAPABILITY_VERSION,
|
|
137
168
|
WEBVIEW_HOST_CAPABILITIES,
|
|
138
169
|
WEBVIEW_DECLARABLE_CAPABILITIES,
|
|
@@ -1,5 +1,101 @@
|
|
|
1
|
+
import type { SetAttemptStatusInput, SetAttemptStatusResult } from "./types/context";
|
|
1
2
|
import type { JsonObject } from "./types/json";
|
|
2
3
|
import type { ResourceAnchor } from "./types/resources";
|
|
4
|
+
export interface TicketArchivedEventPayload {
|
|
5
|
+
projectId: string;
|
|
6
|
+
ticket: {
|
|
7
|
+
id: string;
|
|
8
|
+
shorthand: string;
|
|
9
|
+
displayTitle: string | null;
|
|
10
|
+
userPrompt: string | null;
|
|
11
|
+
parentId: string | null;
|
|
12
|
+
draft: boolean;
|
|
13
|
+
archived: boolean;
|
|
14
|
+
status: string | null;
|
|
15
|
+
tagIds: string[];
|
|
16
|
+
tagNames: string[];
|
|
17
|
+
fileIds: string[];
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export interface WorktreeCreatedEventPayload {
|
|
21
|
+
projectId: string;
|
|
22
|
+
repoPath: string;
|
|
23
|
+
worktreePath: string;
|
|
24
|
+
branch: string;
|
|
25
|
+
workspace: string;
|
|
26
|
+
workspaceId: string;
|
|
27
|
+
ticket: string;
|
|
28
|
+
}
|
|
29
|
+
export interface TicketLifecyclePayload {
|
|
30
|
+
projectId: string;
|
|
31
|
+
ticket: JsonObject;
|
|
32
|
+
}
|
|
33
|
+
export interface TicketStatusChangePayload {
|
|
34
|
+
projectId: string;
|
|
35
|
+
ticket: JsonObject;
|
|
36
|
+
fromStatus: string | null;
|
|
37
|
+
toStatus: string;
|
|
38
|
+
}
|
|
39
|
+
export interface AttemptStatusChangePayload {
|
|
40
|
+
projectId: string;
|
|
41
|
+
workspaceId: string;
|
|
42
|
+
ticket: JsonObject | null;
|
|
43
|
+
fromStatus: string | null;
|
|
44
|
+
toStatus: string;
|
|
45
|
+
statusChangeId?: string;
|
|
46
|
+
sessionId: string | null;
|
|
47
|
+
originalSessionId: string | null;
|
|
48
|
+
worktreePath: string | null;
|
|
49
|
+
workspace: JsonObject;
|
|
50
|
+
}
|
|
51
|
+
export interface SessionLifecyclePayload {
|
|
52
|
+
projectId: string;
|
|
53
|
+
sessionId: string;
|
|
54
|
+
sessionStatus?: string;
|
|
55
|
+
originalSessionId?: string;
|
|
56
|
+
workspace?: JsonObject;
|
|
57
|
+
workspaceId?: string;
|
|
58
|
+
worktreePath?: string;
|
|
59
|
+
branch?: string;
|
|
60
|
+
ticket?: JsonObject;
|
|
61
|
+
attemptStatus?: string;
|
|
62
|
+
}
|
|
63
|
+
export interface WorktreeRemovedPayload {
|
|
64
|
+
projectId: string;
|
|
65
|
+
repoPath?: string;
|
|
66
|
+
worktreePath: string;
|
|
67
|
+
workspace?: JsonObject;
|
|
68
|
+
workspaceId?: string;
|
|
69
|
+
ticket?: JsonObject | string;
|
|
70
|
+
}
|
|
71
|
+
export interface CommitPayload {
|
|
72
|
+
projectId: string;
|
|
73
|
+
repoPath?: string;
|
|
74
|
+
worktreePath?: string;
|
|
75
|
+
branch?: string;
|
|
76
|
+
commitSha?: string;
|
|
77
|
+
workspace?: JsonObject;
|
|
78
|
+
ticket?: JsonObject | string;
|
|
79
|
+
}
|
|
80
|
+
export interface RebasePayload {
|
|
81
|
+
projectId: string;
|
|
82
|
+
repoPath?: string;
|
|
83
|
+
worktreePath?: string;
|
|
84
|
+
branch?: string;
|
|
85
|
+
workspace?: JsonObject;
|
|
86
|
+
ticket?: JsonObject | string;
|
|
87
|
+
}
|
|
88
|
+
export interface MergePayload extends CommitPayload {
|
|
89
|
+
}
|
|
90
|
+
export interface ConflictPayload {
|
|
91
|
+
projectId: string;
|
|
92
|
+
operation: "rebase" | "merge";
|
|
93
|
+
repoPath?: string;
|
|
94
|
+
worktreePath?: string;
|
|
95
|
+
branch?: string;
|
|
96
|
+
workspace?: JsonObject;
|
|
97
|
+
ticket?: JsonObject | string;
|
|
98
|
+
}
|
|
3
99
|
export declare const projectSlots: {
|
|
4
100
|
sidebarNav: import("./types").SlotRef<object, "navigation">;
|
|
5
101
|
sidebar: import("./types").SlotRef<object, "view">;
|
|
@@ -25,15 +121,23 @@ export declare const projectEvents: {
|
|
|
25
121
|
}>;
|
|
26
122
|
};
|
|
27
123
|
export declare const sessionEvents: {
|
|
28
|
-
started: import("./types").EventRef<{
|
|
29
|
-
sessionId: string;
|
|
124
|
+
started: import("./types").EventRef<SessionLifecyclePayload & {
|
|
30
125
|
anchors?: ResourceAnchor[];
|
|
31
126
|
}>;
|
|
32
|
-
|
|
33
|
-
|
|
127
|
+
resumed: import("./types").EventRef<SessionLifecyclePayload>;
|
|
128
|
+
awaitingInput: import("./types").EventRef<SessionLifecyclePayload>;
|
|
129
|
+
succeeded: import("./types").EventRef<SessionLifecyclePayload>;
|
|
130
|
+
failed: import("./types").EventRef<SessionLifecyclePayload>;
|
|
131
|
+
completed: import("./types").EventRef<SessionLifecyclePayload & {
|
|
34
132
|
anchors?: ResourceAnchor[];
|
|
35
133
|
}>;
|
|
36
134
|
};
|
|
135
|
+
export declare const ticketEvents: {
|
|
136
|
+
created: import("./types").EventRef<TicketLifecyclePayload>;
|
|
137
|
+
statusChanged: import("./types").EventRef<TicketStatusChangePayload>;
|
|
138
|
+
archived: import("./types").EventRef<TicketArchivedEventPayload>;
|
|
139
|
+
deleted: import("./types").EventRef<TicketLifecyclePayload>;
|
|
140
|
+
};
|
|
37
141
|
export declare const workspaceEvents: {
|
|
38
142
|
created: import("./types").EventRef<{
|
|
39
143
|
workspace: JsonObject;
|
|
@@ -45,3 +149,19 @@ export declare const workspaceEvents: {
|
|
|
45
149
|
workspace: JsonObject;
|
|
46
150
|
}>;
|
|
47
151
|
};
|
|
152
|
+
export declare const worktreeEvents: {
|
|
153
|
+
created: import("./types").EventRef<WorktreeCreatedEventPayload>;
|
|
154
|
+
removed: import("./types").EventRef<WorktreeRemovedPayload>;
|
|
155
|
+
};
|
|
156
|
+
export declare const gitEvents: {
|
|
157
|
+
committed: import("./types").EventRef<CommitPayload>;
|
|
158
|
+
rebased: import("./types").EventRef<RebasePayload>;
|
|
159
|
+
merged: import("./types").EventRef<MergePayload>;
|
|
160
|
+
conflicted: import("./types").EventRef<ConflictPayload>;
|
|
161
|
+
};
|
|
162
|
+
export declare const attemptStatusEvents: {
|
|
163
|
+
changed: import("./types").EventRef<AttemptStatusChangePayload>;
|
|
164
|
+
};
|
|
165
|
+
export declare const workspaceCommands: {
|
|
166
|
+
setAttemptStatus: import("./types").CommandRef<SetAttemptStatusInput, SetAttemptStatusResult>;
|
|
167
|
+
};
|
|
@@ -82,11 +82,36 @@ export interface ExtensionSessionsApi {
|
|
|
82
82
|
vars?: JsonObject;
|
|
83
83
|
}): Promise<void>;
|
|
84
84
|
}
|
|
85
|
+
export interface SetAttemptStatusInput {
|
|
86
|
+
workspaceId: string;
|
|
87
|
+
status: string;
|
|
88
|
+
sessionId?: string;
|
|
89
|
+
}
|
|
90
|
+
export interface SetAttemptStatusResult {
|
|
91
|
+
id: string;
|
|
92
|
+
attempt_status_id: string | null;
|
|
93
|
+
from_status: string | null;
|
|
94
|
+
to_status: string;
|
|
95
|
+
status_change_id: string;
|
|
96
|
+
}
|
|
85
97
|
export interface ExtensionWorkspacesApi {
|
|
86
98
|
get(id: string): Promise<unknown>;
|
|
87
99
|
create(input: JsonObject): Promise<unknown>;
|
|
88
100
|
archive(id: string): Promise<void>;
|
|
89
101
|
delete(id: string): Promise<void>;
|
|
102
|
+
setAttemptStatus(input: SetAttemptStatusInput): Promise<SetAttemptStatusResult>;
|
|
103
|
+
}
|
|
104
|
+
export interface BootstrapWorktreeInput {
|
|
105
|
+
repoPath: string;
|
|
106
|
+
worktreePath: string;
|
|
107
|
+
ticketId?: string;
|
|
108
|
+
}
|
|
109
|
+
export interface RemoveWorktreesForTicketInput {
|
|
110
|
+
ticketId?: string;
|
|
111
|
+
}
|
|
112
|
+
export interface ExtensionWorktreesApi {
|
|
113
|
+
bootstrap(input: BootstrapWorktreeInput): Promise<void>;
|
|
114
|
+
removeAllForTicket(input: RemoveWorktreesForTicketInput): Promise<number>;
|
|
90
115
|
}
|
|
91
116
|
export interface ExtensionReposApi {
|
|
92
117
|
list(): Promise<RepoContext[]>;
|
|
@@ -117,13 +142,15 @@ export interface ProcessRunResult {
|
|
|
117
142
|
stdout: string;
|
|
118
143
|
stderr: string;
|
|
119
144
|
}
|
|
145
|
+
export interface ProcessRunInput {
|
|
146
|
+
command: string[];
|
|
147
|
+
cwd?: string;
|
|
148
|
+
env?: Record<string, string>;
|
|
149
|
+
timeoutMs?: number;
|
|
150
|
+
}
|
|
120
151
|
export interface ExtensionProcessApi {
|
|
121
|
-
run(input:
|
|
122
|
-
|
|
123
|
-
cwd?: string;
|
|
124
|
-
env?: Record<string, string>;
|
|
125
|
-
timeoutMs?: number;
|
|
126
|
-
}): Promise<ProcessRunResult>;
|
|
152
|
+
run(input: ProcessRunInput): Promise<ProcessRunResult>;
|
|
153
|
+
runOrThrow(input: ProcessRunInput): Promise<ProcessRunResult>;
|
|
127
154
|
spawnDetached(input: {
|
|
128
155
|
command: string[];
|
|
129
156
|
cwd?: string;
|
|
@@ -160,6 +187,7 @@ export interface ExtensionContextBase {
|
|
|
160
187
|
files: ExtensionFilesApi;
|
|
161
188
|
sessions: ExtensionSessionsApi;
|
|
162
189
|
workspaces: ExtensionWorkspacesApi;
|
|
190
|
+
worktrees: ExtensionWorktreesApi;
|
|
163
191
|
repos: ExtensionReposApi;
|
|
164
192
|
commands: CommandHelpersApi;
|
|
165
193
|
events: ExtensionEventsApi;
|
|
@@ -164,5 +164,5 @@ export interface ExtensionLifecycle {
|
|
|
164
164
|
export interface ExtensionDefinition extends UiContributions, BehaviourContributions, AssetContributions, ProviderContributions, ExtensionLifecycle {
|
|
165
165
|
settings?: ParamObjectSchema;
|
|
166
166
|
}
|
|
167
|
-
export type ExtensionSourceKind = "local" | "package"
|
|
167
|
+
export type ExtensionSourceKind = "local" | "package";
|
|
168
168
|
export {};
|
|
@@ -19,5 +19,11 @@ export declare const followupSession: (ctx: PluginHelperContext, input: Followup
|
|
|
19
19
|
cwd: string | null;
|
|
20
20
|
created_at: string;
|
|
21
21
|
updated_at: string;
|
|
22
|
+
follow_up: {
|
|
23
|
+
status: "dispatched";
|
|
24
|
+
} | {
|
|
25
|
+
status: "queued";
|
|
26
|
+
queue_position: number;
|
|
27
|
+
};
|
|
22
28
|
}>;
|
|
23
29
|
export {};
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
export type { Repo } from "pstdio-api-contracts";
|
|
2
2
|
export type { AgentAvailabilityType, AgentConfig, AgentInfo, AgentModel } from "./agent";
|
|
3
3
|
export type { FileRecord } from "./file";
|
|
4
|
+
export type { KnownAgent, KnownAgentId } from "./known-agents";
|
|
5
|
+
export { findAgent, isKnownAgentId, KNOWN_AGENT_IDS, KNOWN_AGENTS } from "./known-agents";
|
|
4
6
|
export type { Project } from "./project";
|
|
5
7
|
export type { Session, SessionStatus } from "./session";
|
|
8
|
+
export type { Settings } from "./settings";
|
|
6
9
|
export type { Skill, SkillFile, SkillWithContent } from "./skill";
|
|
7
10
|
export type { AttemptStatus, Status } from "./status";
|
|
8
11
|
export type { Tag, TagOption } from "./tag";
|
package/dist/resources/index.js
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// src/resources/known-agents.ts
|
|
2
|
+
var KNOWN_AGENTS = [
|
|
3
|
+
{
|
|
4
|
+
id: "claude-code",
|
|
5
|
+
name: "Claude Code",
|
|
6
|
+
binary: "claude",
|
|
7
|
+
skillsDir: ".claude/skills",
|
|
8
|
+
globalSkillsDir: ".claude/skills"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
id: "opencode",
|
|
12
|
+
name: "OpenCode",
|
|
13
|
+
binary: "opencode",
|
|
14
|
+
skillsDir: ".opencode/skills",
|
|
15
|
+
globalSkillsDir: ".opencode/skills"
|
|
16
|
+
}
|
|
17
|
+
];
|
|
18
|
+
var KNOWN_AGENT_IDS = KNOWN_AGENTS.map((agent) => agent.id);
|
|
19
|
+
var findAgent = (id) => KNOWN_AGENTS.find((agent) => agent.id === id) ?? null;
|
|
20
|
+
var isKnownAgentId = (id) => KNOWN_AGENT_IDS.includes(id);
|
|
21
|
+
export {
|
|
22
|
+
isKnownAgentId,
|
|
23
|
+
findAgent,
|
|
24
|
+
KNOWN_AGENT_IDS,
|
|
25
|
+
KNOWN_AGENTS
|
|
26
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type KnownAgentId = "claude-code" | "opencode" | "fake";
|
|
2
|
+
export type KnownAgent = {
|
|
3
|
+
id: KnownAgentId;
|
|
4
|
+
name: string;
|
|
5
|
+
binary: string;
|
|
6
|
+
skillsDir: string;
|
|
7
|
+
globalSkillsDir: string;
|
|
8
|
+
};
|
|
9
|
+
export declare const KNOWN_AGENTS: KnownAgent[];
|
|
10
|
+
export declare const KNOWN_AGENT_IDS: KnownAgentId[];
|
|
11
|
+
export declare const findAgent: (id: string) => KnownAgent | null;
|
|
12
|
+
export declare const isKnownAgentId: (id: string) => id is KnownAgentId;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { Settings } from "pstdio-api-contracts";
|