@locusai/sdk 0.4.5 → 0.4.9
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/index-node.js +1590 -20
- package/dist/index.js +429 -121
- package/dist/orchestrator.d.ts.map +1 -1
- package/package.json +12 -23
- package/dist/agent/artifact-syncer.js +0 -77
- package/dist/agent/codebase-indexer-service.js +0 -55
- package/dist/agent/index.js +0 -5
- package/dist/agent/sprint-planner.js +0 -68
- package/dist/agent/task-executor.js +0 -60
- package/dist/agent/worker.js +0 -252
- package/dist/ai/anthropic-client.js +0 -70
- package/dist/ai/claude-runner.js +0 -71
- package/dist/ai/index.js +0 -2
- package/dist/core/config.js +0 -15
- package/dist/core/index.js +0 -3
- package/dist/core/indexer.js +0 -113
- package/dist/core/prompt-builder.js +0 -83
- package/dist/events.js +0 -15
- package/dist/modules/auth.js +0 -23
- package/dist/modules/base.js +0 -8
- package/dist/modules/ci.js +0 -7
- package/dist/modules/docs.js +0 -38
- package/dist/modules/invitations.js +0 -22
- package/dist/modules/organizations.js +0 -39
- package/dist/modules/sprints.js +0 -34
- package/dist/modules/tasks.js +0 -56
- package/dist/modules/workspaces.js +0 -49
- package/dist/orchestrator.js +0 -356
- package/dist/utils/colors.js +0 -54
- package/dist/utils/retry.js +0 -37
- package/src/agent/artifact-syncer.ts +0 -111
- package/src/agent/codebase-indexer-service.ts +0 -71
- package/src/agent/index.ts +0 -5
- package/src/agent/sprint-planner.ts +0 -86
- package/src/agent/task-executor.ts +0 -85
- package/src/agent/worker.ts +0 -322
- package/src/ai/anthropic-client.ts +0 -93
- package/src/ai/claude-runner.ts +0 -86
- package/src/ai/index.ts +0 -2
- package/src/core/config.ts +0 -21
- package/src/core/index.ts +0 -3
- package/src/core/indexer.ts +0 -131
- package/src/core/prompt-builder.ts +0 -91
- package/src/events.ts +0 -35
- package/src/index-node.ts +0 -23
- package/src/index.ts +0 -159
- package/src/modules/auth.ts +0 -48
- package/src/modules/base.ts +0 -9
- package/src/modules/ci.ts +0 -12
- package/src/modules/docs.ts +0 -84
- package/src/modules/invitations.ts +0 -45
- package/src/modules/organizations.ts +0 -90
- package/src/modules/sprints.ts +0 -69
- package/src/modules/tasks.ts +0 -110
- package/src/modules/workspaces.ts +0 -94
- package/src/orchestrator.ts +0 -473
- package/src/utils/colors.ts +0 -63
- package/src/utils/retry.ts +0 -56
package/dist/index.js
CHANGED
|
@@ -1,126 +1,434 @@
|
|
|
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
|
-
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
19
|
+
var __toCommonJS = (from) => {
|
|
20
|
+
var entry = __moduleCache.get(from), desc;
|
|
21
|
+
if (entry)
|
|
22
|
+
return entry;
|
|
23
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
24
|
+
if (from && typeof from === "object" || typeof from === "function")
|
|
25
|
+
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
26
|
+
get: () => from[key],
|
|
27
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
28
|
+
}));
|
|
29
|
+
__moduleCache.set(from, entry);
|
|
30
|
+
return entry;
|
|
31
|
+
};
|
|
32
|
+
var __export = (target, all) => {
|
|
33
|
+
for (var name in all)
|
|
34
|
+
__defProp(target, name, {
|
|
35
|
+
get: all[name],
|
|
36
|
+
enumerable: true,
|
|
37
|
+
configurable: true,
|
|
38
|
+
set: (newValue) => all[name] = () => newValue
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// src/index.ts
|
|
43
|
+
var exports_src = {};
|
|
44
|
+
__export(exports_src, {
|
|
45
|
+
WorkspacesModule: () => WorkspacesModule,
|
|
46
|
+
TasksModule: () => TasksModule,
|
|
47
|
+
SprintsModule: () => SprintsModule,
|
|
48
|
+
OrganizationsModule: () => OrganizationsModule,
|
|
49
|
+
LocusEvent: () => LocusEvent,
|
|
50
|
+
LocusEmitter: () => LocusEmitter,
|
|
51
|
+
LocusClient: () => LocusClient,
|
|
52
|
+
InvitationsModule: () => InvitationsModule,
|
|
53
|
+
DocsModule: () => DocsModule,
|
|
54
|
+
CiModule: () => CiModule,
|
|
55
|
+
AuthModule: () => AuthModule
|
|
56
|
+
});
|
|
57
|
+
module.exports = __toCommonJS(exports_src);
|
|
58
|
+
var import_axios = __toESM(require("axios"));
|
|
59
|
+
|
|
60
|
+
// src/events.ts
|
|
61
|
+
var import_events = require("events");
|
|
62
|
+
var LocusEvent;
|
|
63
|
+
((LocusEvent2) => {
|
|
64
|
+
LocusEvent2["TOKEN_EXPIRED"] = "TOKEN_EXPIRED";
|
|
65
|
+
LocusEvent2["AUTH_ERROR"] = "AUTH_ERROR";
|
|
66
|
+
LocusEvent2["REQUEST_ERROR"] = "REQUEST_ERROR";
|
|
67
|
+
})(LocusEvent ||= {});
|
|
68
|
+
|
|
69
|
+
class LocusEmitter extends import_events.EventEmitter {
|
|
70
|
+
on(event, listener) {
|
|
71
|
+
return super.on(event, listener);
|
|
72
|
+
}
|
|
73
|
+
emit(event, ...args) {
|
|
74
|
+
return super.emit(event, ...args);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// src/modules/base.ts
|
|
79
|
+
class BaseModule {
|
|
80
|
+
api;
|
|
81
|
+
emitter;
|
|
82
|
+
constructor(api, emitter) {
|
|
83
|
+
this.api = api;
|
|
84
|
+
this.emitter = emitter;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// src/modules/auth.ts
|
|
89
|
+
class AuthModule extends BaseModule {
|
|
90
|
+
async getMe() {
|
|
91
|
+
const { data } = await this.api.get("/auth/me");
|
|
92
|
+
return data;
|
|
93
|
+
}
|
|
94
|
+
async requestRegisterOtp(email) {
|
|
95
|
+
const { data } = await this.api.post("/auth/register-otp", { email });
|
|
96
|
+
return data;
|
|
97
|
+
}
|
|
98
|
+
async requestLoginOtp(email) {
|
|
99
|
+
const { data } = await this.api.post("/auth/login-otp", { email });
|
|
100
|
+
return data;
|
|
101
|
+
}
|
|
102
|
+
async verifyLogin(body) {
|
|
103
|
+
const { data } = await this.api.post("/auth/verify-login", body);
|
|
104
|
+
return data;
|
|
105
|
+
}
|
|
106
|
+
async completeRegistration(body) {
|
|
107
|
+
const { data } = await this.api.post("/auth/complete-registration", body);
|
|
108
|
+
return data;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// src/modules/ci.ts
|
|
113
|
+
class CiModule extends BaseModule {
|
|
114
|
+
async report(body) {
|
|
115
|
+
const { data } = await this.api.post("/ci/report", body);
|
|
116
|
+
return data;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// src/modules/docs.ts
|
|
121
|
+
class DocsModule extends BaseModule {
|
|
122
|
+
async create(workspaceId, body) {
|
|
123
|
+
const { data } = await this.api.post(`/workspaces/${workspaceId}/docs`, body);
|
|
124
|
+
return data.doc;
|
|
125
|
+
}
|
|
126
|
+
async list(workspaceId) {
|
|
127
|
+
const { data } = await this.api.get(`/workspaces/${workspaceId}/docs`);
|
|
128
|
+
return data.docs;
|
|
129
|
+
}
|
|
130
|
+
async getById(id, workspaceId) {
|
|
131
|
+
const { data } = await this.api.get(`/workspaces/${workspaceId}/docs/${id}`);
|
|
132
|
+
return data.doc;
|
|
133
|
+
}
|
|
134
|
+
async update(id, workspaceId, body) {
|
|
135
|
+
const { data } = await this.api.put(`/workspaces/${workspaceId}/docs/${id}`, body);
|
|
136
|
+
return data.doc;
|
|
137
|
+
}
|
|
138
|
+
async delete(id, workspaceId) {
|
|
139
|
+
await this.api.delete(`/workspaces/${workspaceId}/docs/${id}`);
|
|
140
|
+
}
|
|
141
|
+
async listGroups(workspaceId) {
|
|
142
|
+
const { data } = await this.api.get(`/workspaces/${workspaceId}/doc-groups`);
|
|
143
|
+
return data.groups;
|
|
144
|
+
}
|
|
145
|
+
async createGroup(workspaceId, body) {
|
|
146
|
+
const { data } = await this.api.post(`/workspaces/${workspaceId}/doc-groups`, body);
|
|
147
|
+
return data.group;
|
|
148
|
+
}
|
|
149
|
+
async updateGroup(id, workspaceId, body) {
|
|
150
|
+
const { data } = await this.api.patch(`/workspaces/${workspaceId}/doc-groups/${id}`, body);
|
|
151
|
+
return data.group;
|
|
152
|
+
}
|
|
153
|
+
async deleteGroup(id, workspaceId) {
|
|
154
|
+
await this.api.delete(`/workspaces/${workspaceId}/doc-groups/${id}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// src/modules/invitations.ts
|
|
159
|
+
class InvitationsModule extends BaseModule {
|
|
160
|
+
async create(orgId, body) {
|
|
161
|
+
const { data } = await this.api.post(`/org/${orgId}/invitations`, body);
|
|
162
|
+
return data.invitation;
|
|
163
|
+
}
|
|
164
|
+
async list(orgId) {
|
|
165
|
+
const { data } = await this.api.get(`/org/${orgId}/invitations`);
|
|
166
|
+
return data.invitations;
|
|
167
|
+
}
|
|
168
|
+
async verify(token) {
|
|
169
|
+
const { data } = await this.api.get(`/invitations/verify/${token}`);
|
|
170
|
+
return data;
|
|
171
|
+
}
|
|
172
|
+
async accept(body) {
|
|
173
|
+
const { data } = await this.api.post("/invitations/accept", body);
|
|
174
|
+
return data;
|
|
175
|
+
}
|
|
176
|
+
async revoke(orgId, id) {
|
|
177
|
+
await this.api.delete(`/org/${orgId}/invitations/${id}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// src/modules/organizations.ts
|
|
182
|
+
class OrganizationsModule extends BaseModule {
|
|
183
|
+
async list() {
|
|
184
|
+
const { data } = await this.api.get("/organizations");
|
|
185
|
+
return data.organizations;
|
|
186
|
+
}
|
|
187
|
+
async getById(id) {
|
|
188
|
+
const { data } = await this.api.get(`/organizations/${id}`);
|
|
189
|
+
return data.organization;
|
|
190
|
+
}
|
|
191
|
+
async listMembers(id) {
|
|
192
|
+
const { data } = await this.api.get(`/organizations/${id}/members`);
|
|
193
|
+
return data.members;
|
|
194
|
+
}
|
|
195
|
+
async addMember(id, body) {
|
|
196
|
+
const { data } = await this.api.post(`/organizations/${id}/members`, body);
|
|
197
|
+
return data.membership;
|
|
198
|
+
}
|
|
199
|
+
async removeMember(orgId, userId) {
|
|
200
|
+
await this.api.delete(`/organizations/${orgId}/members/${userId}`);
|
|
201
|
+
}
|
|
202
|
+
async delete(orgId) {
|
|
203
|
+
await this.api.delete(`/organizations/${orgId}`);
|
|
204
|
+
}
|
|
205
|
+
async listApiKeys(orgId) {
|
|
206
|
+
const { data } = await this.api.get(`/organizations/${orgId}/api-keys`);
|
|
207
|
+
return data.apiKeys;
|
|
208
|
+
}
|
|
209
|
+
async createApiKey(orgId, name) {
|
|
210
|
+
const { data } = await this.api.post(`/organizations/${orgId}/api-keys`, { name });
|
|
211
|
+
return data.apiKey;
|
|
212
|
+
}
|
|
213
|
+
async deleteApiKey(orgId, keyId) {
|
|
214
|
+
await this.api.delete(`/organizations/${orgId}/api-keys/${keyId}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// src/modules/sprints.ts
|
|
219
|
+
class SprintsModule extends BaseModule {
|
|
220
|
+
async list(workspaceId) {
|
|
221
|
+
const { data } = await this.api.get(`/workspaces/${workspaceId}/sprints`);
|
|
222
|
+
return data.sprints;
|
|
223
|
+
}
|
|
224
|
+
async getActive(workspaceId) {
|
|
225
|
+
const { data } = await this.api.get(`/workspaces/${workspaceId}/sprints/active`);
|
|
226
|
+
return data.sprint;
|
|
227
|
+
}
|
|
228
|
+
async getById(id, workspaceId) {
|
|
229
|
+
const { data } = await this.api.get(`/workspaces/${workspaceId}/sprints/${id}`);
|
|
230
|
+
return data.sprint;
|
|
231
|
+
}
|
|
232
|
+
async create(workspaceId, body) {
|
|
233
|
+
const { data } = await this.api.post(`/workspaces/${workspaceId}/sprints`, body);
|
|
234
|
+
return data.sprint;
|
|
235
|
+
}
|
|
236
|
+
async update(id, workspaceId, body) {
|
|
237
|
+
const { data } = await this.api.patch(`/workspaces/${workspaceId}/sprints/${id}`, body);
|
|
238
|
+
return data.sprint;
|
|
239
|
+
}
|
|
240
|
+
async delete(id, workspaceId) {
|
|
241
|
+
await this.api.delete(`/workspaces/${workspaceId}/sprints/${id}`);
|
|
242
|
+
}
|
|
243
|
+
async start(id, workspaceId) {
|
|
244
|
+
const { data } = await this.api.post(`/workspaces/${workspaceId}/sprints/${id}/start`);
|
|
245
|
+
return data.sprint;
|
|
246
|
+
}
|
|
247
|
+
async complete(id, workspaceId) {
|
|
248
|
+
const { data } = await this.api.post(`/workspaces/${workspaceId}/sprints/${id}/complete`);
|
|
249
|
+
return data.sprint;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// src/modules/tasks.ts
|
|
254
|
+
var import_shared = require("@locusai/shared");
|
|
255
|
+
class TasksModule extends BaseModule {
|
|
256
|
+
async list(workspaceId, options) {
|
|
257
|
+
const { data } = await this.api.get(`/workspaces/${workspaceId}/tasks`);
|
|
258
|
+
let tasks = data.tasks;
|
|
259
|
+
if (options?.sprintId) {
|
|
260
|
+
tasks = tasks.filter((t) => t.sprintId === options.sprintId);
|
|
55
261
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (!config || !retryOptions) {
|
|
60
|
-
return Promise.reject(error);
|
|
61
|
-
}
|
|
62
|
-
config._retryCount = config._retryCount || 0;
|
|
63
|
-
const maxRetries = retryOptions.maxRetries ?? 3;
|
|
64
|
-
const shouldRetry = config._retryCount < maxRetries &&
|
|
65
|
-
(retryOptions.retryCondition
|
|
66
|
-
? retryOptions.retryCondition(error)
|
|
67
|
-
: !error.response || error.response.status >= 500);
|
|
68
|
-
if (shouldRetry) {
|
|
69
|
-
config._retryCount++;
|
|
70
|
-
const delay = Math.min((retryOptions.initialDelay ?? 1000) *
|
|
71
|
-
Math.pow(retryOptions.factor ?? 2, config._retryCount - 1), retryOptions.maxDelay ?? 5000);
|
|
72
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
73
|
-
return this.api(config);
|
|
74
|
-
}
|
|
75
|
-
return Promise.reject(error);
|
|
76
|
-
});
|
|
262
|
+
if (options?.status) {
|
|
263
|
+
const statuses = Array.isArray(options.status) ? options.status : [options.status];
|
|
264
|
+
tasks = tasks.filter((t) => statuses.includes(t.status));
|
|
77
265
|
}
|
|
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
|
-
|
|
266
|
+
return tasks;
|
|
267
|
+
}
|
|
268
|
+
async getAvailable(workspaceId, sprintId) {
|
|
269
|
+
const tasks = await this.list(workspaceId, {
|
|
270
|
+
sprintId
|
|
271
|
+
});
|
|
272
|
+
return tasks.filter((t) => t.status === import_shared.TaskStatus.BACKLOG || t.status === import_shared.TaskStatus.IN_PROGRESS && !t.assignedTo);
|
|
273
|
+
}
|
|
274
|
+
async getById(id, workspaceId) {
|
|
275
|
+
const { data } = await this.api.get(`/workspaces/${workspaceId}/tasks/${id}`);
|
|
276
|
+
return data.task;
|
|
277
|
+
}
|
|
278
|
+
async create(workspaceId, body) {
|
|
279
|
+
const { data } = await this.api.post(`/workspaces/${workspaceId}/tasks`, body);
|
|
280
|
+
return data.task;
|
|
281
|
+
}
|
|
282
|
+
async update(id, workspaceId, body) {
|
|
283
|
+
const { data } = await this.api.patch(`/workspaces/${workspaceId}/tasks/${id}`, body);
|
|
284
|
+
return data.task;
|
|
285
|
+
}
|
|
286
|
+
async delete(id, workspaceId) {
|
|
287
|
+
await this.api.delete(`/workspaces/${workspaceId}/tasks/${id}`);
|
|
288
|
+
}
|
|
289
|
+
async getBacklog(workspaceId) {
|
|
290
|
+
const { data } = await this.api.get(`/workspaces/${workspaceId}/tasks/backlog`);
|
|
291
|
+
return data.tasks;
|
|
292
|
+
}
|
|
293
|
+
async addComment(id, workspaceId, body) {
|
|
294
|
+
const { data } = await this.api.post(`/workspaces/${workspaceId}/tasks/${id}/comment`, body);
|
|
295
|
+
return data.comment;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// src/modules/workspaces.ts
|
|
300
|
+
class WorkspacesModule extends BaseModule {
|
|
301
|
+
async listAll() {
|
|
302
|
+
const { data } = await this.api.get("/workspaces");
|
|
303
|
+
return data.workspaces;
|
|
304
|
+
}
|
|
305
|
+
async listByOrg(orgId) {
|
|
306
|
+
const { data } = await this.api.get(`/workspaces/org/${orgId}`);
|
|
307
|
+
return data.workspaces;
|
|
308
|
+
}
|
|
309
|
+
async create(body) {
|
|
310
|
+
const { orgId, ...bodyWithoutOrgId } = body;
|
|
311
|
+
const { data } = await this.api.post(`/workspaces/org/${orgId}`, bodyWithoutOrgId);
|
|
312
|
+
return data.workspace;
|
|
313
|
+
}
|
|
314
|
+
async createWithAutoOrg(body) {
|
|
315
|
+
const { data } = await this.api.post("/workspaces", body);
|
|
316
|
+
return data.workspace;
|
|
317
|
+
}
|
|
318
|
+
async getById(id) {
|
|
319
|
+
const { data } = await this.api.get(`/workspaces/${id}`);
|
|
320
|
+
return data.workspace;
|
|
321
|
+
}
|
|
322
|
+
async update(id, body) {
|
|
323
|
+
const { data } = await this.api.put(`/workspaces/${id}`, body);
|
|
324
|
+
return data.workspace;
|
|
325
|
+
}
|
|
326
|
+
async delete(id) {
|
|
327
|
+
await this.api.delete(`/workspaces/${id}`);
|
|
328
|
+
}
|
|
329
|
+
async getStats(id) {
|
|
330
|
+
const { data } = await this.api.get(`/workspaces/${id}/stats`);
|
|
331
|
+
return data;
|
|
332
|
+
}
|
|
333
|
+
async getActivity(id, limit) {
|
|
334
|
+
const { data } = await this.api.get(`/workspaces/${id}/activity`, {
|
|
335
|
+
params: { limit }
|
|
336
|
+
});
|
|
337
|
+
return data.activity;
|
|
338
|
+
}
|
|
339
|
+
async dispatch(id, workerId, sprintId) {
|
|
340
|
+
const { data } = await this.api.post(`/workspaces/${id}/dispatch`, { workerId, sprintId });
|
|
341
|
+
return data.task;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// src/index.ts
|
|
346
|
+
class LocusClient {
|
|
347
|
+
api;
|
|
348
|
+
emitter;
|
|
349
|
+
auth;
|
|
350
|
+
tasks;
|
|
351
|
+
sprints;
|
|
352
|
+
workspaces;
|
|
353
|
+
organizations;
|
|
354
|
+
invitations;
|
|
355
|
+
docs;
|
|
356
|
+
ci;
|
|
357
|
+
constructor(config) {
|
|
358
|
+
this.emitter = new LocusEmitter;
|
|
359
|
+
this.api = import_axios.default.create({
|
|
360
|
+
baseURL: config.baseUrl,
|
|
361
|
+
timeout: config.timeout || 1e4,
|
|
362
|
+
headers: {
|
|
363
|
+
"Content-Type": "application/json",
|
|
364
|
+
...config.token ? { Authorization: `Bearer ${config.token}` } : {}
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
this.setupInterceptors();
|
|
368
|
+
this.auth = new AuthModule(this.api, this.emitter);
|
|
369
|
+
this.tasks = new TasksModule(this.api, this.emitter);
|
|
370
|
+
this.sprints = new SprintsModule(this.api, this.emitter);
|
|
371
|
+
this.workspaces = new WorkspacesModule(this.api, this.emitter);
|
|
372
|
+
this.organizations = new OrganizationsModule(this.api, this.emitter);
|
|
373
|
+
this.invitations = new InvitationsModule(this.api, this.emitter);
|
|
374
|
+
this.docs = new DocsModule(this.api, this.emitter);
|
|
375
|
+
this.ci = new CiModule(this.api, this.emitter);
|
|
376
|
+
if (config.retryOptions) {
|
|
377
|
+
this.setupRetryInterceptor(config.retryOptions);
|
|
117
378
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
379
|
+
}
|
|
380
|
+
setupRetryInterceptor(retryOptions) {
|
|
381
|
+
this.api.interceptors.response.use(undefined, async (error) => {
|
|
382
|
+
const config = error.config;
|
|
383
|
+
if (!config || !retryOptions) {
|
|
384
|
+
return Promise.reject(error);
|
|
385
|
+
}
|
|
386
|
+
config._retryCount = config._retryCount || 0;
|
|
387
|
+
const maxRetries = retryOptions.maxRetries ?? 3;
|
|
388
|
+
const shouldRetry = config._retryCount < maxRetries && (retryOptions.retryCondition ? retryOptions.retryCondition(error) : !error.response || error.response.status >= 500);
|
|
389
|
+
if (shouldRetry) {
|
|
390
|
+
config._retryCount++;
|
|
391
|
+
const delay = Math.min((retryOptions.initialDelay ?? 1000) * Math.pow(retryOptions.factor ?? 2, config._retryCount - 1), retryOptions.maxDelay ?? 5000);
|
|
392
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
393
|
+
return this.api(config);
|
|
394
|
+
}
|
|
395
|
+
return Promise.reject(error);
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
setupInterceptors() {
|
|
399
|
+
this.api.interceptors.response.use((response) => {
|
|
400
|
+
if (response.data && typeof response.data === "object" && "data" in response.data) {
|
|
401
|
+
response.data = response.data.data;
|
|
402
|
+
}
|
|
403
|
+
return response;
|
|
404
|
+
}, (error) => {
|
|
405
|
+
const status = error.response?.status;
|
|
406
|
+
let message;
|
|
407
|
+
if (error.response?.data?.error?.message && typeof error.response.data.error.message === "string") {
|
|
408
|
+
message = error.response.data.error.message;
|
|
409
|
+
} else if (error.response?.data?.message && typeof error.response.data.message === "string") {
|
|
410
|
+
message = error.response.data.message;
|
|
411
|
+
} else if (error.message && typeof error.message === "string") {
|
|
412
|
+
message = error.message;
|
|
413
|
+
} else {
|
|
414
|
+
message = "An error occurred";
|
|
415
|
+
}
|
|
416
|
+
const enhancedError = new Error(message);
|
|
417
|
+
enhancedError.name = `HTTP${status || "Error"}`;
|
|
418
|
+
if (status === 401) {
|
|
419
|
+
this.emitter.emit("TOKEN_EXPIRED" /* TOKEN_EXPIRED */);
|
|
420
|
+
this.emitter.emit("AUTH_ERROR" /* AUTH_ERROR */, enhancedError);
|
|
421
|
+
} else {
|
|
422
|
+
this.emitter.emit("REQUEST_ERROR" /* REQUEST_ERROR */, enhancedError);
|
|
423
|
+
}
|
|
424
|
+
return Promise.reject(enhancedError);
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
setToken(token) {
|
|
428
|
+
if (token) {
|
|
429
|
+
this.api.defaults.headers.common.Authorization = `Bearer ${token}`;
|
|
430
|
+
} else {
|
|
431
|
+
delete this.api.defaults.headers.common.Authorization;
|
|
125
432
|
}
|
|
433
|
+
}
|
|
126
434
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAS,MAAM,oBAAoB,CAAC;AAGzD,OAAO,EAAE,IAAI,EAA4B,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAItC,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;IACpD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,iBAAkB,SAAQ,YAAY;IACjD,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,MAAM,CAAsC;IACpD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,cAAc,CAA0B;IAChD,OAAO,CAAC,gBAAgB,CAAuB;gBAEnC,MAAM,EAAE,kBAAkB;IAStC;;OAEG;YACW,eAAe;IAwB7B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB5B;;OAEG;YACW,iBAAiB;IA4C/B;;OAEG;IACH,OAAO,CAAC,eAAe;IAYvB;;OAEG;YACW,UAAU;
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAS,MAAM,oBAAoB,CAAC;AAGzD,OAAO,EAAE,IAAI,EAA4B,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAItC,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;IACpD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,iBAAkB,SAAQ,YAAY;IACjD,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,MAAM,CAAsC;IACpD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,cAAc,CAA0B;IAChD,OAAO,CAAC,gBAAgB,CAAuB;gBAEnC,MAAM,EAAE,kBAAkB;IAStC;;OAEG;YACW,eAAe;IAwB7B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB5B;;OAEG;YACW,iBAAiB;IA4C/B;;OAEG;IACH,OAAO,CAAC,eAAe;IAYvB;;OAEG;YACW,UAAU;IA+HxB;;OAEG;YACW,UAAU;IAKxB;;OAEG;YACW,iBAAiB;IAc/B;;OAEG;IACG,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IA2C9D;;OAEG;IACG,YAAY,CAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IA4BhB;;OAEG;IACG,QAAQ,CACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC;IAyBhB;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B;;OAEG;YACW,OAAO;IAWrB;;OAEG;IACH,QAAQ;;;;;;IAeR,OAAO,CAAC,KAAK;CAGd"}
|
package/package.json
CHANGED
|
@@ -1,47 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@locusai/sdk",
|
|
3
|
-
"version": "0.4.
|
|
4
|
-
"
|
|
3
|
+
"version": "0.4.9",
|
|
4
|
+
"source": "./src/index.ts",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": {
|
|
9
|
-
"types": "./
|
|
10
|
-
"
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"development": "./src/index.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
11
13
|
},
|
|
12
14
|
"./node": {
|
|
13
|
-
"types": "./
|
|
14
|
-
"
|
|
15
|
+
"types": "./dist/index-node.d.ts",
|
|
16
|
+
"development": "./src/index-node.ts",
|
|
17
|
+
"import": "./dist/index-node.js",
|
|
18
|
+
"default": "./dist/index-node.js"
|
|
15
19
|
}
|
|
16
20
|
},
|
|
17
21
|
"files": [
|
|
18
22
|
"dist",
|
|
19
|
-
"src",
|
|
20
23
|
"README.md"
|
|
21
24
|
],
|
|
22
|
-
"publishConfig": {
|
|
23
|
-
"main": "./dist/index.js",
|
|
24
|
-
"types": "./dist/index.d.ts",
|
|
25
|
-
"exports": {
|
|
26
|
-
".": {
|
|
27
|
-
"types": "./dist/index.d.ts",
|
|
28
|
-
"default": "./dist/index.js"
|
|
29
|
-
},
|
|
30
|
-
"./node": {
|
|
31
|
-
"types": "./dist/index-node.d.ts",
|
|
32
|
-
"default": "./dist/index-node.js"
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
25
|
"scripts": {
|
|
37
|
-
"build": "tsc",
|
|
26
|
+
"build": "bun build ./src/index.ts ./src/index-node.ts --outdir ./dist --target node --format cjs --external @anthropic-ai/sdk --external axios --external events --external globby --external @locusai/shared && tsc -p tsconfig.build.json --emitDeclarationOnly",
|
|
38
27
|
"dev": "tsc --watch",
|
|
39
28
|
"lint": "biome lint .",
|
|
40
29
|
"typecheck": "tsc --noEmit"
|
|
41
30
|
},
|
|
42
31
|
"dependencies": {
|
|
43
32
|
"@anthropic-ai/sdk": "^0.71.2",
|
|
44
|
-
"@locusai/shared": "^0.4.
|
|
33
|
+
"@locusai/shared": "^0.4.9",
|
|
45
34
|
"axios": "^1.13.2",
|
|
46
35
|
"events": "^3.3.0",
|
|
47
36
|
"globby": "^14.0.2"
|