@locusai/sdk 0.4.4 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/artifact-syncer.d.ts +1 -1
- package/dist/agent/artifact-syncer.d.ts.map +1 -1
- package/dist/agent/artifact-syncer.js +1 -1
- package/dist/agent/codebase-indexer-service.d.ts +2 -2
- package/dist/agent/codebase-indexer-service.d.ts.map +1 -1
- package/dist/agent/codebase-indexer-service.js +1 -1
- package/dist/agent/index.d.ts +5 -5
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +5 -5
- package/dist/agent/sprint-planner.d.ts +2 -2
- package/dist/agent/sprint-planner.d.ts.map +1 -1
- package/dist/agent/sprint-planner.js +25 -19
- package/dist/agent/task-executor.d.ts +2 -2
- package/dist/agent/task-executor.d.ts.map +1 -1
- package/dist/agent/task-executor.js +12 -8
- package/dist/agent/worker.d.ts.map +1 -1
- package/dist/agent/worker.js +32 -25
- package/dist/ai/anthropic-client.js +1 -1
- package/dist/ai/claude-runner.d.ts +1 -0
- package/dist/ai/claude-runner.d.ts.map +1 -1
- package/dist/ai/claude-runner.js +25 -4
- package/dist/ai/index.d.ts +2 -2
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +2 -2
- package/dist/core/index.d.ts +3 -3
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +3 -3
- package/dist/core/prompt-builder.d.ts +1 -1
- package/dist/core/prompt-builder.d.ts.map +1 -1
- package/dist/core/prompt-builder.js +24 -28
- package/dist/events.d.ts +1 -1
- package/dist/events.d.ts.map +1 -1
- package/dist/index-node.d.ts +6 -6
- package/dist/index-node.d.ts.map +1 -1
- package/dist/index-node.js +6 -6
- package/dist/index.d.ts +18 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -18
- package/dist/modules/auth.d.ts +1 -1
- package/dist/modules/auth.d.ts.map +1 -1
- package/dist/modules/auth.js +1 -1
- package/dist/modules/base.d.ts +1 -1
- package/dist/modules/base.d.ts.map +1 -1
- package/dist/modules/ci.d.ts +1 -1
- package/dist/modules/ci.d.ts.map +1 -1
- package/dist/modules/ci.js +1 -1
- package/dist/modules/docs.d.ts +1 -1
- package/dist/modules/docs.d.ts.map +1 -1
- package/dist/modules/docs.js +1 -1
- package/dist/modules/invitations.d.ts +1 -1
- package/dist/modules/invitations.d.ts.map +1 -1
- package/dist/modules/invitations.js +1 -1
- package/dist/modules/organizations.d.ts +1 -1
- package/dist/modules/organizations.d.ts.map +1 -1
- package/dist/modules/organizations.js +1 -1
- package/dist/modules/sprints.d.ts +1 -1
- package/dist/modules/sprints.d.ts.map +1 -1
- package/dist/modules/sprints.js +1 -1
- package/dist/modules/tasks.d.ts +1 -1
- package/dist/modules/tasks.d.ts.map +1 -1
- package/dist/modules/tasks.js +1 -1
- package/dist/modules/workspaces.d.ts +1 -1
- package/dist/modules/workspaces.d.ts.map +1 -1
- package/dist/modules/workspaces.js +1 -1
- package/dist/orchestrator.js +2 -2
- package/package.json +2 -2
- package/src/agent/artifact-syncer.ts +2 -2
- package/src/agent/codebase-indexer-service.ts +3 -3
- package/src/agent/index.ts +5 -5
- package/src/agent/sprint-planner.ts +31 -23
- package/src/agent/task-executor.ts +18 -10
- package/src/agent/worker.ts +41 -32
- package/src/ai/anthropic-client.ts +1 -1
- package/src/ai/claude-runner.ts +30 -4
- package/src/ai/index.ts +2 -2
- package/src/core/index.ts +3 -3
- package/src/core/prompt-builder.ts +24 -33
- package/src/events.ts +1 -1
- package/src/index-node.ts +6 -6
- package/src/index.ts +19 -19
- package/src/modules/auth.ts +1 -1
- package/src/modules/base.ts +1 -1
- package/src/modules/ci.ts +1 -1
- package/src/modules/docs.ts +1 -1
- package/src/modules/invitations.ts +1 -1
- package/src/modules/organizations.ts +1 -1
- package/src/modules/sprints.ts +1 -1
- package/src/modules/tasks.ts +1 -1
- package/src/modules/workspaces.ts +1 -1
- package/src/orchestrator.ts +2 -2
package/src/ai/claude-runner.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
-
import { DEFAULT_MODEL } from "../core/config";
|
|
2
|
+
import { DEFAULT_MODEL } from "../core/config.js";
|
|
3
3
|
|
|
4
4
|
export class ClaudeRunner {
|
|
5
5
|
constructor(
|
|
@@ -7,7 +7,32 @@ export class ClaudeRunner {
|
|
|
7
7
|
private model: string = DEFAULT_MODEL
|
|
8
8
|
) {}
|
|
9
9
|
|
|
10
|
-
run(prompt: string, _isPlanning = false): Promise<string> {
|
|
10
|
+
async run(prompt: string, _isPlanning = false): Promise<string> {
|
|
11
|
+
const maxRetries = 3;
|
|
12
|
+
let lastError: Error | null = null;
|
|
13
|
+
|
|
14
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
15
|
+
try {
|
|
16
|
+
return await this.executeRun(prompt);
|
|
17
|
+
} catch (error) {
|
|
18
|
+
const err = error as Error;
|
|
19
|
+
lastError = err;
|
|
20
|
+
const isLastAttempt = attempt === maxRetries;
|
|
21
|
+
|
|
22
|
+
if (!isLastAttempt) {
|
|
23
|
+
const delay = Math.pow(2, attempt) * 1000; // 2s, 4s, 8s
|
|
24
|
+
console.warn(
|
|
25
|
+
`Claude CLI attempt ${attempt} failed: ${err.message}. Retrying in ${delay}ms...`
|
|
26
|
+
);
|
|
27
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
throw lastError || new Error("Claude CLI failed after multiple attempts");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
private executeRun(prompt: string): Promise<string> {
|
|
11
36
|
return new Promise((resolve, reject) => {
|
|
12
37
|
const args = [
|
|
13
38
|
"--dangerously-skip-permissions",
|
|
@@ -28,11 +53,12 @@ export class ClaudeRunner {
|
|
|
28
53
|
|
|
29
54
|
claude.stdout.on("data", (data) => {
|
|
30
55
|
output += data.toString();
|
|
31
|
-
|
|
56
|
+
// Only write to stdout if we're not retrying or if logic dictates
|
|
57
|
+
// process.stdout.write(data.toString());
|
|
32
58
|
});
|
|
33
59
|
claude.stderr.on("data", (data) => {
|
|
34
60
|
errorOutput += data.toString();
|
|
35
|
-
process.stderr.write(data.toString());
|
|
61
|
+
// process.stderr.write(data.toString());
|
|
36
62
|
});
|
|
37
63
|
|
|
38
64
|
claude.on("error", (err) =>
|
package/src/ai/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { AnthropicClient } from "./anthropic-client";
|
|
2
|
-
export { ClaudeRunner } from "./claude-runner";
|
|
1
|
+
export { AnthropicClient } from "./anthropic-client.js";
|
|
2
|
+
export { ClaudeRunner } from "./claude-runner.js";
|
package/src/core/index.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { DEFAULT_MODEL, getLocusPath, LOCUS_CONFIG } from "./config";
|
|
2
|
-
export { type CodebaseIndex, CodebaseIndexer } from "./indexer";
|
|
3
|
-
export { PromptBuilder } from "./prompt-builder";
|
|
1
|
+
export { DEFAULT_MODEL, getLocusPath, LOCUS_CONFIG } from "./config.js";
|
|
2
|
+
export { type CodebaseIndex, CodebaseIndexer } from "./indexer.js";
|
|
3
|
+
export { PromptBuilder } from "./prompt-builder.js";
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
-
import { Task } from "@locusai/shared";
|
|
3
|
-
import { getLocusPath } from "./config";
|
|
4
|
-
import { CodebaseIndex } from "./indexer";
|
|
2
|
+
import { AssigneeRole, Task } from "@locusai/shared";
|
|
3
|
+
import { getLocusPath } from "./config.js";
|
|
5
4
|
|
|
6
5
|
export class PromptBuilder {
|
|
7
6
|
constructor(private projectPath: string) {}
|
|
@@ -9,8 +8,9 @@ export class PromptBuilder {
|
|
|
9
8
|
async build(task: Task): Promise<string> {
|
|
10
9
|
let prompt = `# Task: ${task.title}\n\n`;
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
const roleText = this.roleToText(task.assigneeRole);
|
|
12
|
+
if (roleText) {
|
|
13
|
+
prompt += `## Role\nYou are acting as a ${roleText}.\n\n`;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
prompt += `## Description\n${task.description || "No description provided."}\n\n`;
|
|
@@ -29,13 +29,7 @@ export class PromptBuilder {
|
|
|
29
29
|
// 2. Add Codebase Index context
|
|
30
30
|
const indexPath = getLocusPath(this.projectPath, "indexFile");
|
|
31
31
|
if (existsSync(indexPath)) {
|
|
32
|
-
|
|
33
|
-
const indexContent = readFileSync(indexPath, "utf-8");
|
|
34
|
-
const index = JSON.parse(indexContent) as CodebaseIndex;
|
|
35
|
-
prompt += this.formatIndex(index, task);
|
|
36
|
-
} catch (err) {
|
|
37
|
-
console.warn(`Warning: Could not read codebase index: ${err}`);
|
|
38
|
-
}
|
|
32
|
+
prompt += `## Codebase Overview\nThere is an index file in the .locus/codebase-index.json and if you need you can check it.\n\n`;
|
|
39
33
|
}
|
|
40
34
|
|
|
41
35
|
// 3. Add Documents
|
|
@@ -57,9 +51,10 @@ export class PromptBuilder {
|
|
|
57
51
|
|
|
58
52
|
// 5. Add Comments & Feedback
|
|
59
53
|
if (task.comments && task.comments.length > 0) {
|
|
54
|
+
const comments = task.comments.slice(0, 5);
|
|
60
55
|
prompt += `## Task History & Feedback\n`;
|
|
61
56
|
prompt += `Review the following comments for context or rejection feedback:\n\n`;
|
|
62
|
-
for (const comment of
|
|
57
|
+
for (const comment of comments) {
|
|
63
58
|
const date = new Date(comment.createdAt).toLocaleString();
|
|
64
59
|
prompt += `### ${comment.author} (${date})\n${comment.text}\n\n`;
|
|
65
60
|
}
|
|
@@ -73,28 +68,24 @@ export class PromptBuilder {
|
|
|
73
68
|
return prompt;
|
|
74
69
|
}
|
|
75
70
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
// Structural directories
|
|
80
|
-
const structuralDirs = Object.entries(index.responsibilities || {})
|
|
81
|
-
.filter(([path]) => !path.includes(".") || path.split("/").length <= 2)
|
|
82
|
-
.slice(0, 15);
|
|
83
|
-
|
|
84
|
-
if (structuralDirs.length > 0) {
|
|
85
|
-
section += `### Project Structure\n${structuralDirs.map(([p, d]) => `- \`${p}\`: ${d}`).join("\n")}\n\n`;
|
|
71
|
+
roleToText(role: Task["assigneeRole"]): string | null {
|
|
72
|
+
if (!role) {
|
|
73
|
+
return null;
|
|
86
74
|
}
|
|
87
75
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
76
|
+
switch (role) {
|
|
77
|
+
case AssigneeRole.BACKEND:
|
|
78
|
+
return "Backend Engineer";
|
|
79
|
+
case AssigneeRole.FRONTEND:
|
|
80
|
+
return "Frontend Engineer";
|
|
81
|
+
case AssigneeRole.PM:
|
|
82
|
+
return "Product Manager";
|
|
83
|
+
case AssigneeRole.QA:
|
|
84
|
+
return "QA Engineer";
|
|
85
|
+
case AssigneeRole.DESIGN:
|
|
86
|
+
return "Product Designer";
|
|
87
|
+
default:
|
|
88
|
+
return "engineer";
|
|
96
89
|
}
|
|
97
|
-
|
|
98
|
-
return section;
|
|
99
90
|
}
|
|
100
91
|
}
|
package/src/events.ts
CHANGED
package/src/index-node.ts
CHANGED
|
@@ -8,16 +8,16 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
// Node.js-only: Agent system
|
|
11
|
-
export * from "./agent";
|
|
11
|
+
export * from "./agent/index.js";
|
|
12
12
|
// Node.js-only: AI clients
|
|
13
|
-
export * from "./ai";
|
|
13
|
+
export * from "./ai/index.js";
|
|
14
14
|
// Node.js-only: Core utilities (uses fs)
|
|
15
|
-
export * from "./core";
|
|
15
|
+
export * from "./core/index.js";
|
|
16
16
|
// Re-export everything from main index (browser-safe)
|
|
17
|
-
export * from "./index";
|
|
17
|
+
export * from "./index.js";
|
|
18
18
|
|
|
19
19
|
// Node.js-only: Orchestrator
|
|
20
|
-
export { AgentOrchestrator, type OrchestratorConfig } from "./orchestrator";
|
|
20
|
+
export { AgentOrchestrator, type OrchestratorConfig } from "./orchestrator.js";
|
|
21
21
|
|
|
22
22
|
// Utilities
|
|
23
|
-
export { c } from "./utils/colors";
|
|
23
|
+
export { c } from "./utils/colors.js";
|
package/src/index.ts
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import axios, { AxiosInstance, InternalAxiosRequestConfig } from "axios";
|
|
2
|
-
import { LocusConfig, LocusEmitter, LocusEvent } from "./events";
|
|
3
|
-
import { AuthModule } from "./modules/auth";
|
|
4
|
-
import { CiModule } from "./modules/ci";
|
|
5
|
-
import { DocsModule } from "./modules/docs";
|
|
6
|
-
import { InvitationsModule } from "./modules/invitations";
|
|
7
|
-
import { OrganizationsModule } from "./modules/organizations";
|
|
8
|
-
import { SprintsModule } from "./modules/sprints";
|
|
9
|
-
import { TasksModule } from "./modules/tasks";
|
|
10
|
-
import { WorkspacesModule } from "./modules/workspaces";
|
|
11
|
-
import { RetryOptions } from "./utils/retry";
|
|
2
|
+
import { LocusConfig, LocusEmitter, LocusEvent } from "./events.js";
|
|
3
|
+
import { AuthModule } from "./modules/auth.js";
|
|
4
|
+
import { CiModule } from "./modules/ci.js";
|
|
5
|
+
import { DocsModule } from "./modules/docs.js";
|
|
6
|
+
import { InvitationsModule } from "./modules/invitations.js";
|
|
7
|
+
import { OrganizationsModule } from "./modules/organizations.js";
|
|
8
|
+
import { SprintsModule } from "./modules/sprints.js";
|
|
9
|
+
import { TasksModule } from "./modules/tasks.js";
|
|
10
|
+
import { WorkspacesModule } from "./modules/workspaces.js";
|
|
11
|
+
import { RetryOptions } from "./utils/retry.js";
|
|
12
12
|
|
|
13
13
|
// Browser-safe exports only
|
|
14
|
-
export * from "./events";
|
|
15
|
-
export * from "./modules/auth";
|
|
16
|
-
export * from "./modules/ci";
|
|
17
|
-
export * from "./modules/docs";
|
|
18
|
-
export * from "./modules/invitations";
|
|
19
|
-
export * from "./modules/organizations";
|
|
20
|
-
export * from "./modules/sprints";
|
|
21
|
-
export * from "./modules/tasks";
|
|
22
|
-
export * from "./modules/workspaces";
|
|
14
|
+
export * from "./events.js";
|
|
15
|
+
export * from "./modules/auth.js";
|
|
16
|
+
export * from "./modules/ci.js";
|
|
17
|
+
export * from "./modules/docs.js";
|
|
18
|
+
export * from "./modules/invitations.js";
|
|
19
|
+
export * from "./modules/organizations.js";
|
|
20
|
+
export * from "./modules/sprints.js";
|
|
21
|
+
export * from "./modules/tasks.js";
|
|
22
|
+
export * from "./modules/workspaces.js";
|
|
23
23
|
|
|
24
24
|
export class LocusClient {
|
|
25
25
|
private readonly api: AxiosInstance;
|
package/src/modules/auth.ts
CHANGED
package/src/modules/base.ts
CHANGED
package/src/modules/ci.ts
CHANGED
package/src/modules/docs.ts
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
UpdateDoc,
|
|
11
11
|
UpdateDocGroup,
|
|
12
12
|
} from "@locusai/shared";
|
|
13
|
-
import { BaseModule } from "./base";
|
|
13
|
+
import { BaseModule } from "./base.js";
|
|
14
14
|
|
|
15
15
|
export class DocsModule extends BaseModule {
|
|
16
16
|
async create(workspaceId: string, body: CreateDoc): Promise<Doc> {
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
InvitationResponse,
|
|
7
7
|
InvitationsResponse,
|
|
8
8
|
} from "@locusai/shared";
|
|
9
|
-
import { BaseModule } from "./base";
|
|
9
|
+
import { BaseModule } from "./base.js";
|
|
10
10
|
|
|
11
11
|
export class InvitationsModule extends BaseModule {
|
|
12
12
|
async create(orgId: string, body: CreateInvitation): Promise<Invitation> {
|
package/src/modules/sprints.ts
CHANGED
package/src/modules/tasks.ts
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
WorkspaceStats,
|
|
11
11
|
WorkspacesResponse,
|
|
12
12
|
} from "@locusai/shared";
|
|
13
|
-
import { BaseModule } from "./base";
|
|
13
|
+
import { BaseModule } from "./base.js";
|
|
14
14
|
|
|
15
15
|
export class WorkspacesModule extends BaseModule {
|
|
16
16
|
async listAll(): Promise<Workspace[]> {
|
package/src/orchestrator.ts
CHANGED
|
@@ -3,8 +3,8 @@ import { existsSync } from "node:fs";
|
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
import { Task, TaskPriority, TaskStatus } from "@locusai/shared";
|
|
5
5
|
import { EventEmitter } from "events";
|
|
6
|
-
import { LocusClient } from "./index";
|
|
7
|
-
import { c } from "./utils/colors";
|
|
6
|
+
import { LocusClient } from "./index.js";
|
|
7
|
+
import { c } from "./utils/colors.js";
|
|
8
8
|
|
|
9
9
|
export interface AgentConfig {
|
|
10
10
|
id: string;
|