@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.
Files changed (90) hide show
  1. package/dist/agent/artifact-syncer.d.ts +1 -1
  2. package/dist/agent/artifact-syncer.d.ts.map +1 -1
  3. package/dist/agent/artifact-syncer.js +1 -1
  4. package/dist/agent/codebase-indexer-service.d.ts +2 -2
  5. package/dist/agent/codebase-indexer-service.d.ts.map +1 -1
  6. package/dist/agent/codebase-indexer-service.js +1 -1
  7. package/dist/agent/index.d.ts +5 -5
  8. package/dist/agent/index.d.ts.map +1 -1
  9. package/dist/agent/index.js +5 -5
  10. package/dist/agent/sprint-planner.d.ts +2 -2
  11. package/dist/agent/sprint-planner.d.ts.map +1 -1
  12. package/dist/agent/sprint-planner.js +25 -19
  13. package/dist/agent/task-executor.d.ts +2 -2
  14. package/dist/agent/task-executor.d.ts.map +1 -1
  15. package/dist/agent/task-executor.js +12 -8
  16. package/dist/agent/worker.d.ts.map +1 -1
  17. package/dist/agent/worker.js +32 -25
  18. package/dist/ai/anthropic-client.js +1 -1
  19. package/dist/ai/claude-runner.d.ts +1 -0
  20. package/dist/ai/claude-runner.d.ts.map +1 -1
  21. package/dist/ai/claude-runner.js +25 -4
  22. package/dist/ai/index.d.ts +2 -2
  23. package/dist/ai/index.d.ts.map +1 -1
  24. package/dist/ai/index.js +2 -2
  25. package/dist/core/index.d.ts +3 -3
  26. package/dist/core/index.d.ts.map +1 -1
  27. package/dist/core/index.js +3 -3
  28. package/dist/core/prompt-builder.d.ts +1 -1
  29. package/dist/core/prompt-builder.d.ts.map +1 -1
  30. package/dist/core/prompt-builder.js +24 -28
  31. package/dist/events.d.ts +1 -1
  32. package/dist/events.d.ts.map +1 -1
  33. package/dist/index-node.d.ts +6 -6
  34. package/dist/index-node.d.ts.map +1 -1
  35. package/dist/index-node.js +6 -6
  36. package/dist/index.d.ts +18 -18
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +18 -18
  39. package/dist/modules/auth.d.ts +1 -1
  40. package/dist/modules/auth.d.ts.map +1 -1
  41. package/dist/modules/auth.js +1 -1
  42. package/dist/modules/base.d.ts +1 -1
  43. package/dist/modules/base.d.ts.map +1 -1
  44. package/dist/modules/ci.d.ts +1 -1
  45. package/dist/modules/ci.d.ts.map +1 -1
  46. package/dist/modules/ci.js +1 -1
  47. package/dist/modules/docs.d.ts +1 -1
  48. package/dist/modules/docs.d.ts.map +1 -1
  49. package/dist/modules/docs.js +1 -1
  50. package/dist/modules/invitations.d.ts +1 -1
  51. package/dist/modules/invitations.d.ts.map +1 -1
  52. package/dist/modules/invitations.js +1 -1
  53. package/dist/modules/organizations.d.ts +1 -1
  54. package/dist/modules/organizations.d.ts.map +1 -1
  55. package/dist/modules/organizations.js +1 -1
  56. package/dist/modules/sprints.d.ts +1 -1
  57. package/dist/modules/sprints.d.ts.map +1 -1
  58. package/dist/modules/sprints.js +1 -1
  59. package/dist/modules/tasks.d.ts +1 -1
  60. package/dist/modules/tasks.d.ts.map +1 -1
  61. package/dist/modules/tasks.js +1 -1
  62. package/dist/modules/workspaces.d.ts +1 -1
  63. package/dist/modules/workspaces.d.ts.map +1 -1
  64. package/dist/modules/workspaces.js +1 -1
  65. package/dist/orchestrator.js +2 -2
  66. package/package.json +2 -2
  67. package/src/agent/artifact-syncer.ts +2 -2
  68. package/src/agent/codebase-indexer-service.ts +3 -3
  69. package/src/agent/index.ts +5 -5
  70. package/src/agent/sprint-planner.ts +31 -23
  71. package/src/agent/task-executor.ts +18 -10
  72. package/src/agent/worker.ts +41 -32
  73. package/src/ai/anthropic-client.ts +1 -1
  74. package/src/ai/claude-runner.ts +30 -4
  75. package/src/ai/index.ts +2 -2
  76. package/src/core/index.ts +3 -3
  77. package/src/core/prompt-builder.ts +24 -33
  78. package/src/events.ts +1 -1
  79. package/src/index-node.ts +6 -6
  80. package/src/index.ts +19 -19
  81. package/src/modules/auth.ts +1 -1
  82. package/src/modules/base.ts +1 -1
  83. package/src/modules/ci.ts +1 -1
  84. package/src/modules/docs.ts +1 -1
  85. package/src/modules/invitations.ts +1 -1
  86. package/src/modules/organizations.ts +1 -1
  87. package/src/modules/sprints.ts +1 -1
  88. package/src/modules/tasks.ts +1 -1
  89. package/src/modules/workspaces.ts +1 -1
  90. package/src/orchestrator.ts +2 -2
@@ -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
- process.stdout.write(data.toString());
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
- if (task.assigneeRole) {
13
- prompt += `## Role\nYou are acting as a ${task.assigneeRole} engineer.\n\n`;
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
- try {
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 task.comments) {
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
- private formatIndex(index: CodebaseIndex, task: Task): string {
77
- let section = `## Codebase Overview\nThis codebase has been indexed to help you navigate.\n\n`;
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
- // Relevant symbols
89
- const keywords = `${task.title} ${task.description}`.toLowerCase();
90
- const symbols = Object.entries(index.symbols || {})
91
- .filter(([symbol]) => keywords.includes(symbol.toLowerCase()))
92
- .slice(0, 10);
93
-
94
- if (symbols.length > 0) {
95
- section += `### Potentially Relevant Symbols\n${symbols.map(([s, f]) => `- \`${s}\` is defined in: ${Array.isArray(f) ? f.join(", ") : f}`).join("\n")}\n\n`;
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
@@ -1,6 +1,6 @@
1
1
  import { EventEmitter } from "events";
2
2
 
3
- import { RetryOptions } from "./utils/retry";
3
+ import { RetryOptions } from "./utils/retry.js";
4
4
 
5
5
  export enum LocusEvent {
6
6
  TOKEN_EXPIRED = "TOKEN_EXPIRED",
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;
@@ -4,7 +4,7 @@ import {
4
4
  User,
5
5
  VerifyOtp,
6
6
  } from "@locusai/shared";
7
- import { BaseModule } from "./base";
7
+ import { BaseModule } from "./base.js";
8
8
 
9
9
  export class AuthModule extends BaseModule {
10
10
  async getMe(): Promise<User> {
@@ -1,5 +1,5 @@
1
1
  import { AxiosInstance } from "axios";
2
- import { LocusEmitter } from "../events";
2
+ import { LocusEmitter } from "../events.js";
3
3
 
4
4
  export abstract class BaseModule {
5
5
  constructor(
package/src/modules/ci.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ReportCiResult } from "@locusai/shared";
2
- import { BaseModule } from "./base";
2
+ import { BaseModule } from "./base.js";
3
3
 
4
4
  export class CiModule extends BaseModule {
5
5
  async report(body: ReportCiResult): Promise<{ success: boolean }> {
@@ -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> {
@@ -7,7 +7,7 @@ import {
7
7
  OrganizationResponse,
8
8
  OrganizationsResponse,
9
9
  } from "@locusai/shared";
10
- import { BaseModule } from "./base";
10
+ import { BaseModule } from "./base.js";
11
11
 
12
12
  export interface ApiKey {
13
13
  id: string;
@@ -5,7 +5,7 @@ import {
5
5
  SprintsResponse,
6
6
  UpdateSprint,
7
7
  } from "@locusai/shared";
8
- import { BaseModule } from "./base";
8
+ import { BaseModule } from "./base.js";
9
9
 
10
10
  export class SprintsModule extends BaseModule {
11
11
  async list(workspaceId: string): Promise<Sprint[]> {
@@ -9,7 +9,7 @@ import {
9
9
  TasksResponse,
10
10
  UpdateTask,
11
11
  } from "@locusai/shared";
12
- import { BaseModule } from "./base";
12
+ import { BaseModule } from "./base.js";
13
13
 
14
14
  export interface TaskListOptions {
15
15
  sprintId?: string;
@@ -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[]> {
@@ -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;