@locusai/sdk 0.4.9 → 0.4.10

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.
@@ -433,40 +433,15 @@ class LocusClient {
433
433
  }
434
434
  }
435
435
 
436
- // src/index-node.ts
437
- var exports_index_node = {};
438
- __export(exports_index_node, {
439
- getLocusPath: () => getLocusPath,
440
- c: () => c,
441
- WorkspacesModule: () => WorkspacesModule,
442
- TasksModule: () => TasksModule,
443
- TaskExecutor: () => TaskExecutor,
444
- SprintsModule: () => SprintsModule,
445
- SprintPlanner: () => SprintPlanner,
446
- PromptBuilder: () => PromptBuilder,
447
- OrganizationsModule: () => OrganizationsModule,
448
- LocusEvent: () => LocusEvent,
449
- LocusEmitter: () => LocusEmitter,
450
- LocusClient: () => LocusClient,
451
- LOCUS_CONFIG: () => LOCUS_CONFIG,
452
- InvitationsModule: () => InvitationsModule,
453
- DocsModule: () => DocsModule,
454
- DEFAULT_MODEL: () => DEFAULT_MODEL,
455
- CodebaseIndexerService: () => CodebaseIndexerService,
456
- CodebaseIndexer: () => CodebaseIndexer,
457
- ClaudeRunner: () => ClaudeRunner,
458
- CiModule: () => CiModule,
459
- AuthModule: () => AuthModule,
460
- ArtifactSyncer: () => ArtifactSyncer,
461
- AnthropicClient: () => AnthropicClient,
462
- AgentWorker: () => AgentWorker,
463
- AgentOrchestrator: () => AgentOrchestrator
436
+ // src/agent/worker.ts
437
+ var exports_worker = {};
438
+ __export(exports_worker, {
439
+ AgentWorker: () => AgentWorker
464
440
  });
465
- module.exports = __toCommonJS(exports_index_node);
441
+ module.exports = __toCommonJS(exports_worker);
466
442
 
467
- // src/agent/artifact-syncer.ts
468
- var import_node_fs = require("node:fs");
469
- var import_node_path2 = require("node:path");
443
+ // src/ai/anthropic-client.ts
444
+ var import_sdk = __toESM(require("@anthropic-ai/sdk"));
470
445
 
471
446
  // src/core/config.ts
472
447
  var import_node_path = require("node:path");
@@ -485,7 +460,174 @@ function getLocusPath(projectPath, fileName) {
485
460
  return import_node_path.join(projectPath, LOCUS_CONFIG.dir, LOCUS_CONFIG[fileName]);
486
461
  }
487
462
 
463
+ // src/ai/anthropic-client.ts
464
+ class AnthropicClient {
465
+ client;
466
+ model;
467
+ constructor(config) {
468
+ this.client = new import_sdk.default({
469
+ apiKey: config.apiKey
470
+ });
471
+ this.model = config.model || DEFAULT_MODEL;
472
+ }
473
+ async run(options) {
474
+ const { systemPrompt, cacheableContext = [], userPrompt } = options;
475
+ const systemContent = [];
476
+ if (systemPrompt) {
477
+ systemContent.push({
478
+ type: "text",
479
+ text: systemPrompt
480
+ });
481
+ }
482
+ for (let i = 0;i < cacheableContext.length; i++) {
483
+ const isLast = i === cacheableContext.length - 1;
484
+ systemContent.push({
485
+ type: "text",
486
+ text: cacheableContext[i],
487
+ ...isLast && {
488
+ cache_control: { type: "ephemeral" }
489
+ }
490
+ });
491
+ }
492
+ const response = await this.client.messages.create({
493
+ model: this.model,
494
+ max_tokens: 8000,
495
+ system: systemContent,
496
+ messages: [
497
+ {
498
+ role: "user",
499
+ content: userPrompt
500
+ }
501
+ ]
502
+ });
503
+ const textBlocks = response.content.filter((block) => block.type === "text");
504
+ return textBlocks.map((block) => block.text).join(`
505
+ `);
506
+ }
507
+ async runSimple(prompt) {
508
+ return this.run({
509
+ userPrompt: prompt
510
+ });
511
+ }
512
+ }
513
+
514
+ // src/ai/claude-runner.ts
515
+ var import_node_child_process = require("node:child_process");
516
+ class ClaudeRunner {
517
+ projectPath;
518
+ model;
519
+ constructor(projectPath, model = DEFAULT_MODEL) {
520
+ this.projectPath = projectPath;
521
+ this.model = model;
522
+ }
523
+ async run(prompt, _isPlanning = false) {
524
+ const maxRetries = 3;
525
+ let lastError = null;
526
+ for (let attempt = 1;attempt <= maxRetries; attempt++) {
527
+ try {
528
+ return await this.executeRun(prompt);
529
+ } catch (error) {
530
+ const err = error;
531
+ lastError = err;
532
+ const isLastAttempt = attempt === maxRetries;
533
+ if (!isLastAttempt) {
534
+ const delay = Math.pow(2, attempt) * 1000;
535
+ console.warn(`Claude CLI attempt ${attempt} failed: ${err.message}. Retrying in ${delay}ms...`);
536
+ await new Promise((resolve) => setTimeout(resolve, delay));
537
+ }
538
+ }
539
+ }
540
+ throw lastError || new Error("Claude CLI failed after multiple attempts");
541
+ }
542
+ executeRun(prompt) {
543
+ return new Promise((resolve, reject) => {
544
+ const args = [
545
+ "--dangerously-skip-permissions",
546
+ "--print",
547
+ "--model",
548
+ this.model
549
+ ];
550
+ const claude = import_node_child_process.spawn("claude", args, {
551
+ cwd: this.projectPath,
552
+ stdio: ["pipe", "pipe", "pipe"],
553
+ env: process.env,
554
+ shell: true
555
+ });
556
+ let output = "";
557
+ let errorOutput = "";
558
+ claude.stdout.on("data", (data) => {
559
+ output += data.toString();
560
+ });
561
+ claude.stderr.on("data", (data) => {
562
+ errorOutput += data.toString();
563
+ });
564
+ claude.on("error", (err) => reject(new Error(`Failed to start Claude CLI (shell: true): ${err.message}. Please ensure the 'claude' command is available in your PATH.`)));
565
+ claude.on("close", (code) => {
566
+ if (code === 0)
567
+ resolve(output);
568
+ else {
569
+ const detail = errorOutput.trim();
570
+ const message = detail ? `Claude CLI error (exit code ${code}): ${detail}` : `Claude CLI exited with code ${code}. Please ensure the Claude CLI is installed and you are logged in (run 'claude' manually to check).`;
571
+ reject(new Error(message));
572
+ }
573
+ });
574
+ claude.stdin.write(prompt);
575
+ claude.stdin.end();
576
+ });
577
+ }
578
+ }
579
+
580
+ // src/utils/colors.ts
581
+ var ESC = "\x1B[";
582
+ var RESET = `${ESC}0m`;
583
+ var colors = {
584
+ reset: RESET,
585
+ bold: `${ESC}1m`,
586
+ dim: `${ESC}2m`,
587
+ italic: `${ESC}3m`,
588
+ underline: `${ESC}4m`,
589
+ black: `${ESC}30m`,
590
+ red: `${ESC}31m`,
591
+ green: `${ESC}32m`,
592
+ yellow: `${ESC}33m`,
593
+ blue: `${ESC}34m`,
594
+ magenta: `${ESC}35m`,
595
+ cyan: `${ESC}36m`,
596
+ white: `${ESC}37m`,
597
+ gray: `${ESC}90m`,
598
+ brightRed: `${ESC}91m`,
599
+ brightGreen: `${ESC}92m`,
600
+ brightYellow: `${ESC}93m`,
601
+ brightBlue: `${ESC}94m`,
602
+ brightMagenta: `${ESC}95m`,
603
+ brightCyan: `${ESC}96m`,
604
+ brightWhite: `${ESC}97m`
605
+ };
606
+ var c = {
607
+ text: (text, ...colorNames) => {
608
+ const codes = colorNames.map((name) => colors[name]).join("");
609
+ return `${codes}${text}${RESET}`;
610
+ },
611
+ bold: (t) => c.text(t, "bold"),
612
+ dim: (t) => c.text(t, "dim"),
613
+ red: (t) => c.text(t, "red"),
614
+ green: (t) => c.text(t, "green"),
615
+ yellow: (t) => c.text(t, "yellow"),
616
+ blue: (t) => c.text(t, "blue"),
617
+ magenta: (t) => c.text(t, "magenta"),
618
+ cyan: (t) => c.text(t, "cyan"),
619
+ gray: (t) => c.text(t, "gray"),
620
+ success: (t) => c.text(t, "green", "bold"),
621
+ error: (t) => c.text(t, "red", "bold"),
622
+ warning: (t) => c.text(t, "yellow", "bold"),
623
+ info: (t) => c.text(t, "cyan", "bold"),
624
+ primary: (t) => c.text(t, "blue", "bold"),
625
+ underline: (t) => c.text(t, "underline")
626
+ };
627
+
488
628
  // src/agent/artifact-syncer.ts
629
+ var import_node_fs = require("node:fs");
630
+ var import_node_path2 = require("node:path");
489
631
  class ArtifactSyncer {
490
632
  deps;
491
633
  constructor(deps) {
@@ -550,6 +692,7 @@ class ArtifactSyncer {
550
692
  }
551
693
  }
552
694
  }
695
+
553
696
  // src/core/indexer.ts
554
697
  var import_node_fs2 = require("node:fs");
555
698
  var import_node_path3 = require("node:path");
@@ -700,6 +843,7 @@ Return ONLY valid JSON, no markdown formatting.`;
700
843
  }
701
844
  }
702
845
  }
846
+
703
847
  // src/agent/sprint-planner.ts
704
848
  class SprintPlanner {
705
849
  deps;
@@ -761,6 +905,7 @@ ${taskList}
761
905
  }
762
906
  }
763
907
  }
908
+
764
909
  // src/core/prompt-builder.ts
765
910
  var import_node_fs3 = require("node:fs");
766
911
  var import_shared2 = require("@locusai/shared");
@@ -930,171 +1075,6 @@ When finished, output: <promise>COMPLETE</promise>`;
930
1075
  }
931
1076
  }
932
1077
  }
933
- // src/ai/anthropic-client.ts
934
- var import_sdk = __toESM(require("@anthropic-ai/sdk"));
935
- class AnthropicClient {
936
- client;
937
- model;
938
- constructor(config) {
939
- this.client = new import_sdk.default({
940
- apiKey: config.apiKey
941
- });
942
- this.model = config.model || DEFAULT_MODEL;
943
- }
944
- async run(options) {
945
- const { systemPrompt, cacheableContext = [], userPrompt } = options;
946
- const systemContent = [];
947
- if (systemPrompt) {
948
- systemContent.push({
949
- type: "text",
950
- text: systemPrompt
951
- });
952
- }
953
- for (let i = 0;i < cacheableContext.length; i++) {
954
- const isLast = i === cacheableContext.length - 1;
955
- systemContent.push({
956
- type: "text",
957
- text: cacheableContext[i],
958
- ...isLast && {
959
- cache_control: { type: "ephemeral" }
960
- }
961
- });
962
- }
963
- const response = await this.client.messages.create({
964
- model: this.model,
965
- max_tokens: 8000,
966
- system: systemContent,
967
- messages: [
968
- {
969
- role: "user",
970
- content: userPrompt
971
- }
972
- ]
973
- });
974
- const textBlocks = response.content.filter((block) => block.type === "text");
975
- return textBlocks.map((block) => block.text).join(`
976
- `);
977
- }
978
- async runSimple(prompt) {
979
- return this.run({
980
- userPrompt: prompt
981
- });
982
- }
983
- }
984
-
985
- // src/ai/claude-runner.ts
986
- var import_node_child_process = require("node:child_process");
987
- class ClaudeRunner {
988
- projectPath;
989
- model;
990
- constructor(projectPath, model = DEFAULT_MODEL) {
991
- this.projectPath = projectPath;
992
- this.model = model;
993
- }
994
- async run(prompt, _isPlanning = false) {
995
- const maxRetries = 3;
996
- let lastError = null;
997
- for (let attempt = 1;attempt <= maxRetries; attempt++) {
998
- try {
999
- return await this.executeRun(prompt);
1000
- } catch (error) {
1001
- const err = error;
1002
- lastError = err;
1003
- const isLastAttempt = attempt === maxRetries;
1004
- if (!isLastAttempt) {
1005
- const delay = Math.pow(2, attempt) * 1000;
1006
- console.warn(`Claude CLI attempt ${attempt} failed: ${err.message}. Retrying in ${delay}ms...`);
1007
- await new Promise((resolve) => setTimeout(resolve, delay));
1008
- }
1009
- }
1010
- }
1011
- throw lastError || new Error("Claude CLI failed after multiple attempts");
1012
- }
1013
- executeRun(prompt) {
1014
- return new Promise((resolve, reject) => {
1015
- const args = [
1016
- "--dangerously-skip-permissions",
1017
- "--print",
1018
- "--model",
1019
- this.model
1020
- ];
1021
- const claude = import_node_child_process.spawn("claude", args, {
1022
- cwd: this.projectPath,
1023
- stdio: ["pipe", "pipe", "pipe"],
1024
- env: process.env,
1025
- shell: true
1026
- });
1027
- let output = "";
1028
- let errorOutput = "";
1029
- claude.stdout.on("data", (data) => {
1030
- output += data.toString();
1031
- });
1032
- claude.stderr.on("data", (data) => {
1033
- errorOutput += data.toString();
1034
- });
1035
- claude.on("error", (err) => reject(new Error(`Failed to start Claude CLI (shell: true): ${err.message}. Please ensure the 'claude' command is available in your PATH.`)));
1036
- claude.on("close", (code) => {
1037
- if (code === 0)
1038
- resolve(output);
1039
- else {
1040
- const detail = errorOutput.trim();
1041
- const message = detail ? `Claude CLI error (exit code ${code}): ${detail}` : `Claude CLI exited with code ${code}. Please ensure the Claude CLI is installed and you are logged in (run 'claude' manually to check).`;
1042
- reject(new Error(message));
1043
- }
1044
- });
1045
- claude.stdin.write(prompt);
1046
- claude.stdin.end();
1047
- });
1048
- }
1049
- }
1050
-
1051
- // src/utils/colors.ts
1052
- var ESC = "\x1B[";
1053
- var RESET = `${ESC}0m`;
1054
- var colors = {
1055
- reset: RESET,
1056
- bold: `${ESC}1m`,
1057
- dim: `${ESC}2m`,
1058
- italic: `${ESC}3m`,
1059
- underline: `${ESC}4m`,
1060
- black: `${ESC}30m`,
1061
- red: `${ESC}31m`,
1062
- green: `${ESC}32m`,
1063
- yellow: `${ESC}33m`,
1064
- blue: `${ESC}34m`,
1065
- magenta: `${ESC}35m`,
1066
- cyan: `${ESC}36m`,
1067
- white: `${ESC}37m`,
1068
- gray: `${ESC}90m`,
1069
- brightRed: `${ESC}91m`,
1070
- brightGreen: `${ESC}92m`,
1071
- brightYellow: `${ESC}93m`,
1072
- brightBlue: `${ESC}94m`,
1073
- brightMagenta: `${ESC}95m`,
1074
- brightCyan: `${ESC}96m`,
1075
- brightWhite: `${ESC}97m`
1076
- };
1077
- var c = {
1078
- text: (text, ...colorNames) => {
1079
- const codes = colorNames.map((name) => colors[name]).join("");
1080
- return `${codes}${text}${RESET}`;
1081
- },
1082
- bold: (t) => c.text(t, "bold"),
1083
- dim: (t) => c.text(t, "dim"),
1084
- red: (t) => c.text(t, "red"),
1085
- green: (t) => c.text(t, "green"),
1086
- yellow: (t) => c.text(t, "yellow"),
1087
- blue: (t) => c.text(t, "blue"),
1088
- magenta: (t) => c.text(t, "magenta"),
1089
- cyan: (t) => c.text(t, "cyan"),
1090
- gray: (t) => c.text(t, "gray"),
1091
- success: (t) => c.text(t, "green", "bold"),
1092
- error: (t) => c.text(t, "red", "bold"),
1093
- warning: (t) => c.text(t, "yellow", "bold"),
1094
- info: (t) => c.text(t, "cyan", "bold"),
1095
- primary: (t) => c.text(t, "blue", "bold"),
1096
- underline: (t) => c.text(t, "underline")
1097
- };
1098
1078
 
1099
1079
  // src/agent/worker.ts
1100
1080
  class AgentWorker {
@@ -1302,6 +1282,37 @@ if (process.argv[1]?.includes("agent-worker") || process.argv[1]?.includes("work
1302
1282
  process.exit(1);
1303
1283
  });
1304
1284
  }
1285
+
1286
+ // src/index-node.ts
1287
+ var exports_index_node = {};
1288
+ __export(exports_index_node, {
1289
+ getLocusPath: () => getLocusPath,
1290
+ c: () => c,
1291
+ WorkspacesModule: () => WorkspacesModule,
1292
+ TasksModule: () => TasksModule,
1293
+ TaskExecutor: () => TaskExecutor,
1294
+ SprintsModule: () => SprintsModule,
1295
+ SprintPlanner: () => SprintPlanner,
1296
+ PromptBuilder: () => PromptBuilder,
1297
+ OrganizationsModule: () => OrganizationsModule,
1298
+ LocusEvent: () => LocusEvent,
1299
+ LocusEmitter: () => LocusEmitter,
1300
+ LocusClient: () => LocusClient,
1301
+ LOCUS_CONFIG: () => LOCUS_CONFIG,
1302
+ InvitationsModule: () => InvitationsModule,
1303
+ DocsModule: () => DocsModule,
1304
+ DEFAULT_MODEL: () => DEFAULT_MODEL,
1305
+ CodebaseIndexerService: () => CodebaseIndexerService,
1306
+ CodebaseIndexer: () => CodebaseIndexer,
1307
+ ClaudeRunner: () => ClaudeRunner,
1308
+ CiModule: () => CiModule,
1309
+ AuthModule: () => AuthModule,
1310
+ ArtifactSyncer: () => ArtifactSyncer,
1311
+ AnthropicClient: () => AnthropicClient,
1312
+ AgentWorker: () => AgentWorker,
1313
+ AgentOrchestrator: () => AgentOrchestrator
1314
+ });
1315
+ module.exports = __toCommonJS(exports_index_node);
1305
1316
  // src/orchestrator.ts
1306
1317
  var import_node_child_process2 = require("node:child_process");
1307
1318
  var import_node_fs4 = require("node:fs");
package/package.json CHANGED
@@ -1,21 +1,20 @@
1
1
  {
2
2
  "name": "@locusai/sdk",
3
- "version": "0.4.9",
4
- "source": "./src/index.ts",
3
+ "version": "0.4.10",
5
4
  "main": "./src/index.ts",
6
5
  "types": "./src/index.ts",
7
6
  "exports": {
8
7
  ".": {
9
- "types": "./dist/index.d.ts",
8
+ "types": "./src/index.ts",
10
9
  "development": "./src/index.ts",
11
- "import": "./dist/index.js",
12
- "default": "./dist/index.js"
10
+ "import": "./src/index.ts",
11
+ "default": "./src/index.ts"
13
12
  },
14
13
  "./node": {
15
- "types": "./dist/index-node.d.ts",
14
+ "types": "./src/index-node.ts",
16
15
  "development": "./src/index-node.ts",
17
- "import": "./dist/index-node.js",
18
- "default": "./dist/index-node.js"
16
+ "import": "./src/index-node.ts",
17
+ "default": "./src/index-node.ts"
19
18
  }
20
19
  },
21
20
  "files": [
@@ -23,14 +22,14 @@
23
22
  "README.md"
24
23
  ],
25
24
  "scripts": {
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",
25
+ "build": "bun build ./src/index.ts ./src/index-node.ts ./src/agent/worker.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",
27
26
  "dev": "tsc --watch",
28
27
  "lint": "biome lint .",
29
28
  "typecheck": "tsc --noEmit"
30
29
  },
31
30
  "dependencies": {
32
31
  "@anthropic-ai/sdk": "^0.71.2",
33
- "@locusai/shared": "^0.4.9",
32
+ "@locusai/shared": "^0.4.10",
34
33
  "axios": "^1.13.2",
35
34
  "events": "^3.3.0",
36
35
  "globby": "^14.0.2"