@locusai/cli 0.7.0 → 0.7.3
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/bin/agent/worker.js +107 -19
- package/bin/locus.js +210 -69
- package/package.json +2 -2
package/bin/agent/worker.js
CHANGED
|
@@ -17065,7 +17065,15 @@ var colors = {
|
|
|
17065
17065
|
brightBlue: `${ESC}94m`,
|
|
17066
17066
|
brightMagenta: `${ESC}95m`,
|
|
17067
17067
|
brightCyan: `${ESC}96m`,
|
|
17068
|
-
brightWhite: `${ESC}97m
|
|
17068
|
+
brightWhite: `${ESC}97m`,
|
|
17069
|
+
bgBlack: `${ESC}40m`,
|
|
17070
|
+
bgRed: `${ESC}41m`,
|
|
17071
|
+
bgGreen: `${ESC}42m`,
|
|
17072
|
+
bgYellow: `${ESC}43m`,
|
|
17073
|
+
bgBlue: `${ESC}44m`,
|
|
17074
|
+
bgMagenta: `${ESC}45m`,
|
|
17075
|
+
bgCyan: `${ESC}46m`,
|
|
17076
|
+
bgWhite: `${ESC}47m`
|
|
17069
17077
|
};
|
|
17070
17078
|
var c = {
|
|
17071
17079
|
text: (text, ...colorNames) => {
|
|
@@ -17081,11 +17089,17 @@ var c = {
|
|
|
17081
17089
|
magenta: (t) => c.text(t, "magenta"),
|
|
17082
17090
|
cyan: (t) => c.text(t, "cyan"),
|
|
17083
17091
|
gray: (t) => c.text(t, "gray"),
|
|
17092
|
+
white: (t) => c.text(t, "white"),
|
|
17093
|
+
brightBlue: (t) => c.text(t, "brightBlue"),
|
|
17094
|
+
bgBlue: (t) => c.text(t, "bgBlue", "white", "bold"),
|
|
17084
17095
|
success: (t) => c.text(t, "green", "bold"),
|
|
17085
17096
|
error: (t) => c.text(t, "red", "bold"),
|
|
17086
17097
|
warning: (t) => c.text(t, "yellow", "bold"),
|
|
17087
17098
|
info: (t) => c.text(t, "cyan", "bold"),
|
|
17088
17099
|
primary: (t) => c.text(t, "blue", "bold"),
|
|
17100
|
+
secondary: (t) => c.text(t, "magenta", "bold"),
|
|
17101
|
+
header: (t) => c.text(` ${t} `, "bgBlue", "white", "bold"),
|
|
17102
|
+
step: (t) => c.text(` ${t} `, "bgCyan", "black", "bold"),
|
|
17089
17103
|
underline: (t) => c.text(t, "underline")
|
|
17090
17104
|
};
|
|
17091
17105
|
|
|
@@ -17213,7 +17227,6 @@ class ClaudeRunner {
|
|
|
17213
17227
|
if (type === "content_block_start" && content_block) {
|
|
17214
17228
|
if (content_block.type === "tool_use" && content_block.name) {
|
|
17215
17229
|
this.log?.(`
|
|
17216
|
-
|
|
17217
17230
|
${c.primary("[Claude]")} ${c.bold(`Running ${content_block.name}...`)}
|
|
17218
17231
|
`, "info");
|
|
17219
17232
|
}
|
|
@@ -20814,6 +20827,13 @@ class AIModule extends BaseModule {
|
|
|
20814
20827
|
async deleteSession(workspaceId, sessionId) {
|
|
20815
20828
|
await this.api.delete(`/ai/${workspaceId}/session/${sessionId}`);
|
|
20816
20829
|
}
|
|
20830
|
+
async shareSession(workspaceId, sessionId, body) {
|
|
20831
|
+
await this.api.post(`/ai/${workspaceId}/session/${sessionId}/share`, body);
|
|
20832
|
+
}
|
|
20833
|
+
async getSharedSession(sessionId) {
|
|
20834
|
+
const { data } = await this.api.get(`/ai/shared/${sessionId}`);
|
|
20835
|
+
return data;
|
|
20836
|
+
}
|
|
20817
20837
|
}
|
|
20818
20838
|
|
|
20819
20839
|
// ../sdk/src/modules/auth.ts
|
|
@@ -34834,6 +34854,9 @@ var ChatResponseSchema = exports_external.object({
|
|
|
34834
34854
|
sessionId: exports_external.string(),
|
|
34835
34855
|
history: exports_external.array(AIMessageSchema).optional()
|
|
34836
34856
|
});
|
|
34857
|
+
var ShareChatRequestSchema = exports_external.object({
|
|
34858
|
+
isShared: exports_external.boolean()
|
|
34859
|
+
});
|
|
34837
34860
|
// ../shared/src/models/user.ts
|
|
34838
34861
|
var UserSchema = BaseEntitySchema.extend({
|
|
34839
34862
|
email: exports_external.string().email(),
|
|
@@ -36110,13 +36133,10 @@ class CodebaseIndexer {
|
|
|
36110
36133
|
`);
|
|
36111
36134
|
const newTreeHash = this.hashTree(treeString);
|
|
36112
36135
|
const existingIndex = this.loadIndex();
|
|
36113
|
-
if (!force && existingIndex?.treeHash === newTreeHash) {
|
|
36114
|
-
onProgress?.("No file changes detected, skipping reindex");
|
|
36115
|
-
return null;
|
|
36116
|
-
}
|
|
36117
36136
|
const currentHashes = this.computeFileHashes(currentFiles);
|
|
36118
36137
|
const existingHashes = existingIndex?.fileHashes;
|
|
36119
|
-
const
|
|
36138
|
+
const hasExistingContent = existingIndex && (Object.keys(existingIndex.symbols).length > 0 || Object.keys(existingIndex.responsibilities).length > 0);
|
|
36139
|
+
const canIncremental = !force && existingIndex && existingHashes && hasExistingContent;
|
|
36120
36140
|
if (canIncremental) {
|
|
36121
36141
|
onProgress?.("Performing incremental update");
|
|
36122
36142
|
const { added, deleted, modified } = this.diffFiles(currentHashes, existingHashes);
|
|
@@ -36149,8 +36169,12 @@ class CodebaseIndexer {
|
|
|
36149
36169
|
}
|
|
36150
36170
|
}
|
|
36151
36171
|
onProgress?.("AI is analyzing codebase structure...");
|
|
36152
|
-
|
|
36153
|
-
|
|
36172
|
+
try {
|
|
36173
|
+
const index = await treeSummarizer(treeString);
|
|
36174
|
+
return this.applyIndexMetadata(index, currentHashes, newTreeHash);
|
|
36175
|
+
} catch (error48) {
|
|
36176
|
+
throw new Error(`AI analysis failed: ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
36177
|
+
}
|
|
36154
36178
|
}
|
|
36155
36179
|
async getFileTree() {
|
|
36156
36180
|
const gitmodulesPath = join4(this.projectPath, ".gitmodules");
|
|
@@ -36501,6 +36525,76 @@ ${comment.text}
|
|
|
36501
36525
|
2. **Artifact Management**: If you create any high-level documentation (PRDs, technical drafts, architecture docs), you MUST save them in \`.locus/artifacts/\`. Do NOT create them in the root directory.
|
|
36502
36526
|
3. **Paths**: Use relative paths from the project root at all times. Do NOT use absolute local paths (e.g., /Users/...).
|
|
36503
36527
|
4. When finished successfully, output: <promise>COMPLETE</promise>
|
|
36528
|
+
`;
|
|
36529
|
+
return prompt;
|
|
36530
|
+
}
|
|
36531
|
+
async buildGenericPrompt(query) {
|
|
36532
|
+
let prompt = `# Direct Execution
|
|
36533
|
+
|
|
36534
|
+
`;
|
|
36535
|
+
prompt += `## Prompt
|
|
36536
|
+
${query}
|
|
36537
|
+
|
|
36538
|
+
`;
|
|
36539
|
+
const projectConfig = this.getProjectConfig();
|
|
36540
|
+
if (projectConfig) {
|
|
36541
|
+
prompt += `## Project Metadata
|
|
36542
|
+
`;
|
|
36543
|
+
prompt += `- Version: ${projectConfig.version || "Unknown"}
|
|
36544
|
+
`;
|
|
36545
|
+
prompt += `- Created At: ${projectConfig.createdAt || "Unknown"}
|
|
36546
|
+
|
|
36547
|
+
`;
|
|
36548
|
+
}
|
|
36549
|
+
const contextPath = getLocusPath(this.projectPath, "contextFile");
|
|
36550
|
+
let hasLocalContext = false;
|
|
36551
|
+
if (existsSync4(contextPath)) {
|
|
36552
|
+
try {
|
|
36553
|
+
const context = readFileSync4(contextPath, "utf-8");
|
|
36554
|
+
if (context.trim().length > 20) {
|
|
36555
|
+
prompt += `## Project Context (Local)
|
|
36556
|
+
${context}
|
|
36557
|
+
|
|
36558
|
+
`;
|
|
36559
|
+
hasLocalContext = true;
|
|
36560
|
+
}
|
|
36561
|
+
} catch (err) {
|
|
36562
|
+
console.warn(`Warning: Could not read context file: ${err}`);
|
|
36563
|
+
}
|
|
36564
|
+
}
|
|
36565
|
+
if (!hasLocalContext) {
|
|
36566
|
+
const fallback = this.getFallbackContext();
|
|
36567
|
+
if (fallback) {
|
|
36568
|
+
prompt += `## Project Context (README Fallback)
|
|
36569
|
+
${fallback}
|
|
36570
|
+
|
|
36571
|
+
`;
|
|
36572
|
+
}
|
|
36573
|
+
}
|
|
36574
|
+
prompt += this.getProjectStructure();
|
|
36575
|
+
prompt += this.getSkillsInfo();
|
|
36576
|
+
prompt += `## Project Knowledge Base
|
|
36577
|
+
`;
|
|
36578
|
+
prompt += `You have access to the following documentation directories for context:
|
|
36579
|
+
`;
|
|
36580
|
+
prompt += `- Artifacts: \`.locus/artifacts\`
|
|
36581
|
+
`;
|
|
36582
|
+
prompt += `- Documents: \`.locus/documents\`
|
|
36583
|
+
`;
|
|
36584
|
+
prompt += `If you need more information about the project strategies, plans, or architecture, please read files in these directories.
|
|
36585
|
+
|
|
36586
|
+
`;
|
|
36587
|
+
const indexPath = getLocusPath(this.projectPath, "indexFile");
|
|
36588
|
+
if (existsSync4(indexPath)) {
|
|
36589
|
+
prompt += `## Codebase Overview
|
|
36590
|
+
There is an index file in the .locus/codebase-index.json and if you need you can check it.
|
|
36591
|
+
|
|
36592
|
+
`;
|
|
36593
|
+
}
|
|
36594
|
+
prompt += `## Instructions
|
|
36595
|
+
1. Execute the prompt based on the provided project context.
|
|
36596
|
+
2. **Paths**: Use relative paths from the project root at all times. Do NOT use absolute local paths (e.g., /Users/...).
|
|
36597
|
+
3. When finished successfully, output: <promise>COMPLETE</promise>
|
|
36504
36598
|
`;
|
|
36505
36599
|
return prompt;
|
|
36506
36600
|
}
|
|
@@ -36642,16 +36736,12 @@ class TaskExecutor {
|
|
|
36642
36736
|
});
|
|
36643
36737
|
try {
|
|
36644
36738
|
let plan = null;
|
|
36645
|
-
|
|
36646
|
-
|
|
36647
|
-
} else {
|
|
36648
|
-
this.deps.log("Phase 1: Planning (CLI)...", "info");
|
|
36649
|
-
const planningPrompt = `${basePrompt}
|
|
36739
|
+
this.deps.log("Phase 1: Planning (CLI)...", "info");
|
|
36740
|
+
const planningPrompt = `${basePrompt}
|
|
36650
36741
|
|
|
36651
36742
|
## Phase 1: Planning
|
|
36652
36743
|
Analyze and create a detailed plan for THIS SPECIFIC TASK. Do NOT execute changes yet.`;
|
|
36653
|
-
|
|
36654
|
-
}
|
|
36744
|
+
plan = await this.deps.aiRunner.run(planningPrompt, true);
|
|
36655
36745
|
this.deps.log("Starting Execution...", "info");
|
|
36656
36746
|
let executionPrompt = basePrompt;
|
|
36657
36747
|
if (plan != null) {
|
|
@@ -36740,7 +36830,6 @@ class AgentWorker {
|
|
|
36740
36830
|
this.taskExecutor = new TaskExecutor({
|
|
36741
36831
|
aiRunner: this.aiRunner,
|
|
36742
36832
|
projectPath,
|
|
36743
|
-
skipPlanning: config2.skipPlanning,
|
|
36744
36833
|
log
|
|
36745
36834
|
});
|
|
36746
36835
|
const providerLabel = provider === "codex" ? "Codex" : "Claude";
|
|
@@ -36871,8 +36960,7 @@ if (process.argv[1]?.includes("agent-worker") || process.argv[1]?.includes("work
|
|
|
36871
36960
|
if (value && !value.startsWith("--"))
|
|
36872
36961
|
i++;
|
|
36873
36962
|
config2.provider = resolveProvider(value);
|
|
36874
|
-
}
|
|
36875
|
-
config2.skipPlanning = true;
|
|
36963
|
+
}
|
|
36876
36964
|
}
|
|
36877
36965
|
if (!config2.agentId || !config2.workspaceId || !config2.apiBase || !config2.apiKey || !config2.projectPath) {
|
|
36878
36966
|
console.error("Missing required arguments");
|
package/bin/locus.js
CHANGED
|
@@ -30874,6 +30874,9 @@ var ChatResponseSchema = exports_external.object({
|
|
|
30874
30874
|
sessionId: exports_external.string(),
|
|
30875
30875
|
history: exports_external.array(AIMessageSchema).optional()
|
|
30876
30876
|
});
|
|
30877
|
+
var ShareChatRequestSchema = exports_external.object({
|
|
30878
|
+
isShared: exports_external.boolean()
|
|
30879
|
+
});
|
|
30877
30880
|
// ../shared/src/models/user.ts
|
|
30878
30881
|
var UserSchema = BaseEntitySchema.extend({
|
|
30879
30882
|
email: exports_external.string().email(),
|
|
@@ -31961,13 +31964,10 @@ class CodebaseIndexer {
|
|
|
31961
31964
|
`);
|
|
31962
31965
|
const newTreeHash = this.hashTree(treeString);
|
|
31963
31966
|
const existingIndex = this.loadIndex();
|
|
31964
|
-
if (!force && existingIndex?.treeHash === newTreeHash) {
|
|
31965
|
-
onProgress?.("No file changes detected, skipping reindex");
|
|
31966
|
-
return null;
|
|
31967
|
-
}
|
|
31968
31967
|
const currentHashes = this.computeFileHashes(currentFiles);
|
|
31969
31968
|
const existingHashes = existingIndex?.fileHashes;
|
|
31970
|
-
const
|
|
31969
|
+
const hasExistingContent = existingIndex && (Object.keys(existingIndex.symbols).length > 0 || Object.keys(existingIndex.responsibilities).length > 0);
|
|
31970
|
+
const canIncremental = !force && existingIndex && existingHashes && hasExistingContent;
|
|
31971
31971
|
if (canIncremental) {
|
|
31972
31972
|
onProgress?.("Performing incremental update");
|
|
31973
31973
|
const { added, deleted, modified } = this.diffFiles(currentHashes, existingHashes);
|
|
@@ -32000,8 +32000,12 @@ class CodebaseIndexer {
|
|
|
32000
32000
|
}
|
|
32001
32001
|
}
|
|
32002
32002
|
onProgress?.("AI is analyzing codebase structure...");
|
|
32003
|
-
|
|
32004
|
-
|
|
32003
|
+
try {
|
|
32004
|
+
const index = await treeSummarizer(treeString);
|
|
32005
|
+
return this.applyIndexMetadata(index, currentHashes, newTreeHash);
|
|
32006
|
+
} catch (error48) {
|
|
32007
|
+
throw new Error(`AI analysis failed: ${error48 instanceof Error ? error48.message : String(error48)}`);
|
|
32008
|
+
}
|
|
32005
32009
|
}
|
|
32006
32010
|
async getFileTree() {
|
|
32007
32011
|
const gitmodulesPath = join3(this.projectPath, ".gitmodules");
|
|
@@ -32351,6 +32355,76 @@ ${comment.text}
|
|
|
32351
32355
|
2. **Artifact Management**: If you create any high-level documentation (PRDs, technical drafts, architecture docs), you MUST save them in \`.locus/artifacts/\`. Do NOT create them in the root directory.
|
|
32352
32356
|
3. **Paths**: Use relative paths from the project root at all times. Do NOT use absolute local paths (e.g., /Users/...).
|
|
32353
32357
|
4. When finished successfully, output: <promise>COMPLETE</promise>
|
|
32358
|
+
`;
|
|
32359
|
+
return prompt;
|
|
32360
|
+
}
|
|
32361
|
+
async buildGenericPrompt(query) {
|
|
32362
|
+
let prompt = `# Direct Execution
|
|
32363
|
+
|
|
32364
|
+
`;
|
|
32365
|
+
prompt += `## Prompt
|
|
32366
|
+
${query}
|
|
32367
|
+
|
|
32368
|
+
`;
|
|
32369
|
+
const projectConfig = this.getProjectConfig();
|
|
32370
|
+
if (projectConfig) {
|
|
32371
|
+
prompt += `## Project Metadata
|
|
32372
|
+
`;
|
|
32373
|
+
prompt += `- Version: ${projectConfig.version || "Unknown"}
|
|
32374
|
+
`;
|
|
32375
|
+
prompt += `- Created At: ${projectConfig.createdAt || "Unknown"}
|
|
32376
|
+
|
|
32377
|
+
`;
|
|
32378
|
+
}
|
|
32379
|
+
const contextPath = getLocusPath(this.projectPath, "contextFile");
|
|
32380
|
+
let hasLocalContext = false;
|
|
32381
|
+
if (existsSync3(contextPath)) {
|
|
32382
|
+
try {
|
|
32383
|
+
const context = readFileSync3(contextPath, "utf-8");
|
|
32384
|
+
if (context.trim().length > 20) {
|
|
32385
|
+
prompt += `## Project Context (Local)
|
|
32386
|
+
${context}
|
|
32387
|
+
|
|
32388
|
+
`;
|
|
32389
|
+
hasLocalContext = true;
|
|
32390
|
+
}
|
|
32391
|
+
} catch (err) {
|
|
32392
|
+
console.warn(`Warning: Could not read context file: ${err}`);
|
|
32393
|
+
}
|
|
32394
|
+
}
|
|
32395
|
+
if (!hasLocalContext) {
|
|
32396
|
+
const fallback = this.getFallbackContext();
|
|
32397
|
+
if (fallback) {
|
|
32398
|
+
prompt += `## Project Context (README Fallback)
|
|
32399
|
+
${fallback}
|
|
32400
|
+
|
|
32401
|
+
`;
|
|
32402
|
+
}
|
|
32403
|
+
}
|
|
32404
|
+
prompt += this.getProjectStructure();
|
|
32405
|
+
prompt += this.getSkillsInfo();
|
|
32406
|
+
prompt += `## Project Knowledge Base
|
|
32407
|
+
`;
|
|
32408
|
+
prompt += `You have access to the following documentation directories for context:
|
|
32409
|
+
`;
|
|
32410
|
+
prompt += `- Artifacts: \`.locus/artifacts\`
|
|
32411
|
+
`;
|
|
32412
|
+
prompt += `- Documents: \`.locus/documents\`
|
|
32413
|
+
`;
|
|
32414
|
+
prompt += `If you need more information about the project strategies, plans, or architecture, please read files in these directories.
|
|
32415
|
+
|
|
32416
|
+
`;
|
|
32417
|
+
const indexPath = getLocusPath(this.projectPath, "indexFile");
|
|
32418
|
+
if (existsSync3(indexPath)) {
|
|
32419
|
+
prompt += `## Codebase Overview
|
|
32420
|
+
There is an index file in the .locus/codebase-index.json and if you need you can check it.
|
|
32421
|
+
|
|
32422
|
+
`;
|
|
32423
|
+
}
|
|
32424
|
+
prompt += `## Instructions
|
|
32425
|
+
1. Execute the prompt based on the provided project context.
|
|
32426
|
+
2. **Paths**: Use relative paths from the project root at all times. Do NOT use absolute local paths (e.g., /Users/...).
|
|
32427
|
+
3. When finished successfully, output: <promise>COMPLETE</promise>
|
|
32354
32428
|
`;
|
|
32355
32429
|
return prompt;
|
|
32356
32430
|
}
|
|
@@ -32492,16 +32566,12 @@ class TaskExecutor {
|
|
|
32492
32566
|
});
|
|
32493
32567
|
try {
|
|
32494
32568
|
let plan = null;
|
|
32495
|
-
|
|
32496
|
-
|
|
32497
|
-
} else {
|
|
32498
|
-
this.deps.log("Phase 1: Planning (CLI)...", "info");
|
|
32499
|
-
const planningPrompt = `${basePrompt}
|
|
32569
|
+
this.deps.log("Phase 1: Planning (CLI)...", "info");
|
|
32570
|
+
const planningPrompt = `${basePrompt}
|
|
32500
32571
|
|
|
32501
32572
|
## Phase 1: Planning
|
|
32502
32573
|
Analyze and create a detailed plan for THIS SPECIFIC TASK. Do NOT execute changes yet.`;
|
|
32503
|
-
|
|
32504
|
-
}
|
|
32574
|
+
plan = await this.deps.aiRunner.run(planningPrompt, true);
|
|
32505
32575
|
this.deps.log("Starting Execution...", "info");
|
|
32506
32576
|
let executionPrompt = basePrompt;
|
|
32507
32577
|
if (plan != null) {
|
|
@@ -32559,7 +32629,15 @@ var colors = {
|
|
|
32559
32629
|
brightBlue: `${ESC}94m`,
|
|
32560
32630
|
brightMagenta: `${ESC}95m`,
|
|
32561
32631
|
brightCyan: `${ESC}96m`,
|
|
32562
|
-
brightWhite: `${ESC}97m
|
|
32632
|
+
brightWhite: `${ESC}97m`,
|
|
32633
|
+
bgBlack: `${ESC}40m`,
|
|
32634
|
+
bgRed: `${ESC}41m`,
|
|
32635
|
+
bgGreen: `${ESC}42m`,
|
|
32636
|
+
bgYellow: `${ESC}43m`,
|
|
32637
|
+
bgBlue: `${ESC}44m`,
|
|
32638
|
+
bgMagenta: `${ESC}45m`,
|
|
32639
|
+
bgCyan: `${ESC}46m`,
|
|
32640
|
+
bgWhite: `${ESC}47m`
|
|
32563
32641
|
};
|
|
32564
32642
|
var c = {
|
|
32565
32643
|
text: (text, ...colorNames) => {
|
|
@@ -32575,11 +32653,17 @@ var c = {
|
|
|
32575
32653
|
magenta: (t) => c.text(t, "magenta"),
|
|
32576
32654
|
cyan: (t) => c.text(t, "cyan"),
|
|
32577
32655
|
gray: (t) => c.text(t, "gray"),
|
|
32656
|
+
white: (t) => c.text(t, "white"),
|
|
32657
|
+
brightBlue: (t) => c.text(t, "brightBlue"),
|
|
32658
|
+
bgBlue: (t) => c.text(t, "bgBlue", "white", "bold"),
|
|
32578
32659
|
success: (t) => c.text(t, "green", "bold"),
|
|
32579
32660
|
error: (t) => c.text(t, "red", "bold"),
|
|
32580
32661
|
warning: (t) => c.text(t, "yellow", "bold"),
|
|
32581
32662
|
info: (t) => c.text(t, "cyan", "bold"),
|
|
32582
32663
|
primary: (t) => c.text(t, "blue", "bold"),
|
|
32664
|
+
secondary: (t) => c.text(t, "magenta", "bold"),
|
|
32665
|
+
header: (t) => c.text(` ${t} `, "bgBlue", "white", "bold"),
|
|
32666
|
+
step: (t) => c.text(` ${t} `, "bgCyan", "black", "bold"),
|
|
32583
32667
|
underline: (t) => c.text(t, "underline")
|
|
32584
32668
|
};
|
|
32585
32669
|
|
|
@@ -32707,7 +32791,6 @@ class ClaudeRunner {
|
|
|
32707
32791
|
if (type === "content_block_start" && content_block) {
|
|
32708
32792
|
if (content_block.type === "tool_use" && content_block.name) {
|
|
32709
32793
|
this.log?.(`
|
|
32710
|
-
|
|
32711
32794
|
${c.primary("[Claude]")} ${c.bold(`Running ${content_block.name}...`)}
|
|
32712
32795
|
`, "info");
|
|
32713
32796
|
}
|
|
@@ -36308,6 +36391,13 @@ class AIModule extends BaseModule {
|
|
|
36308
36391
|
async deleteSession(workspaceId, sessionId) {
|
|
36309
36392
|
await this.api.delete(`/ai/${workspaceId}/session/${sessionId}`);
|
|
36310
36393
|
}
|
|
36394
|
+
async shareSession(workspaceId, sessionId, body) {
|
|
36395
|
+
await this.api.post(`/ai/${workspaceId}/session/${sessionId}/share`, body);
|
|
36396
|
+
}
|
|
36397
|
+
async getSharedSession(sessionId) {
|
|
36398
|
+
const { data } = await this.api.get(`/ai/shared/${sessionId}`);
|
|
36399
|
+
return data;
|
|
36400
|
+
}
|
|
36311
36401
|
}
|
|
36312
36402
|
|
|
36313
36403
|
// ../sdk/src/modules/auth.ts
|
|
@@ -36746,7 +36836,6 @@ class AgentWorker {
|
|
|
36746
36836
|
this.taskExecutor = new TaskExecutor({
|
|
36747
36837
|
aiRunner: this.aiRunner,
|
|
36748
36838
|
projectPath,
|
|
36749
|
-
skipPlanning: config2.skipPlanning,
|
|
36750
36839
|
log
|
|
36751
36840
|
});
|
|
36752
36841
|
const providerLabel = provider === "codex" ? "Codex" : "Claude";
|
|
@@ -36877,8 +36966,7 @@ if (process.argv[1]?.includes("agent-worker") || process.argv[1]?.includes("work
|
|
|
36877
36966
|
if (value && !value.startsWith("--"))
|
|
36878
36967
|
i++;
|
|
36879
36968
|
config2.provider = resolveProvider(value);
|
|
36880
|
-
}
|
|
36881
|
-
config2.skipPlanning = true;
|
|
36969
|
+
}
|
|
36882
36970
|
}
|
|
36883
36971
|
if (!config2.agentId || !config2.workspaceId || !config2.apiBase || !config2.apiKey || !config2.projectPath) {
|
|
36884
36972
|
console.error("Missing required arguments");
|
|
@@ -37012,9 +37100,6 @@ ${c.success("✅ Orchestrator finished")}`);
|
|
|
37012
37100
|
if (this.config.provider) {
|
|
37013
37101
|
workerArgs.push("--provider", this.config.provider);
|
|
37014
37102
|
}
|
|
37015
|
-
if (this.config.skipPlanning) {
|
|
37016
|
-
workerArgs.push("--skip-planning");
|
|
37017
|
-
}
|
|
37018
37103
|
if (this.resolvedSprintId) {
|
|
37019
37104
|
workerArgs.push("--sprint-id", this.resolvedSprintId);
|
|
37020
37105
|
}
|
|
@@ -37613,12 +37698,12 @@ function getVersion() {
|
|
|
37613
37698
|
var VERSION2 = getVersion();
|
|
37614
37699
|
function printBanner() {
|
|
37615
37700
|
console.log(c.primary(`
|
|
37616
|
-
|
|
37617
|
-
|
|
37618
|
-
|
|
37619
|
-
|
|
37620
|
-
|
|
37621
|
-
`));
|
|
37701
|
+
_ ____ ____ _ _ ____
|
|
37702
|
+
| | / __ \\ / ___| | | |/ ___|
|
|
37703
|
+
| | | | | | | | | | |\\___ \\
|
|
37704
|
+
| |___| |__| | |___| |_| |___) |
|
|
37705
|
+
|_____|\\____/ \\____|\\___/|____/ ${c.dim(`v${VERSION2}`)}
|
|
37706
|
+
`));
|
|
37622
37707
|
}
|
|
37623
37708
|
function isProjectInitialized(projectPath) {
|
|
37624
37709
|
const locusDir = join8(projectPath, LOCUS_CONFIG.dir);
|
|
@@ -37628,14 +37713,14 @@ function isProjectInitialized(projectPath) {
|
|
|
37628
37713
|
function requireInitialization(projectPath, command) {
|
|
37629
37714
|
if (!isProjectInitialized(projectPath)) {
|
|
37630
37715
|
console.error(`
|
|
37631
|
-
${c.error("
|
|
37716
|
+
${c.error("✖ Error")} ${c.red(`Locus is not initialized in this directory.`)}
|
|
37632
37717
|
|
|
37633
|
-
The '${c.bold(command)}' command requires a Locus project to be initialized.
|
|
37718
|
+
The '${c.bold(command)}' command requires a Locus project to be initialized.
|
|
37634
37719
|
|
|
37635
|
-
To initialize Locus in this directory, run:
|
|
37636
|
-
|
|
37720
|
+
To initialize Locus in this directory, run:
|
|
37721
|
+
${c.primary("locus init")}
|
|
37637
37722
|
|
|
37638
|
-
This will create a .locus directory with the necessary configuration.
|
|
37723
|
+
This will create a ${c.dim(".locus")} directory with the necessary configuration.
|
|
37639
37724
|
`);
|
|
37640
37725
|
process.exit(1);
|
|
37641
37726
|
}
|
|
@@ -37696,12 +37781,11 @@ async function runCommand(args) {
|
|
|
37696
37781
|
apiBase,
|
|
37697
37782
|
maxIterations: 100,
|
|
37698
37783
|
projectPath,
|
|
37699
|
-
apiKey
|
|
37700
|
-
skipPlanning: Boolean(values["skip-planning"])
|
|
37784
|
+
apiKey
|
|
37701
37785
|
});
|
|
37702
|
-
orchestrator.on("task:assigned", (data) => console.log(
|
|
37703
|
-
orchestrator.on("task:completed", (data) => console.log(
|
|
37704
|
-
orchestrator.on("task:failed", (data) => console.log(
|
|
37786
|
+
orchestrator.on("task:assigned", (data) => console.log(` ${c.info("●")} ${c.bold("Claimed:")} ${data.title}`));
|
|
37787
|
+
orchestrator.on("task:completed", (data) => console.log(` ${c.success("✔")} ${c.success("Completed:")} ${c.dim(data.taskId)}`));
|
|
37788
|
+
orchestrator.on("task:failed", (data) => console.log(` ${c.error("✖")} ${c.error("Failed:")} ${c.bold(data.taskId)}: ${data.error}`));
|
|
37705
37789
|
const handleSignal = async (signal) => {
|
|
37706
37790
|
console.log(`
|
|
37707
37791
|
${c.info(`Received ${signal}. Stopping agents...`)}`);
|
|
@@ -37710,7 +37794,8 @@ ${c.info(`Received ${signal}. Stopping agents...`)}`);
|
|
|
37710
37794
|
};
|
|
37711
37795
|
process.on("SIGINT", () => handleSignal("SIGINT"));
|
|
37712
37796
|
process.on("SIGTERM", () => handleSignal("SIGTERM"));
|
|
37713
|
-
console.log(
|
|
37797
|
+
console.log(`
|
|
37798
|
+
${c.primary("\uD83D\uDE80")} ${c.bold("Starting Locus agent in")} ${c.primary(projectPath)}...`);
|
|
37714
37799
|
await orchestrator.start();
|
|
37715
37800
|
}
|
|
37716
37801
|
async function indexCommand(args) {
|
|
@@ -37734,12 +37819,63 @@ async function indexCommand(args) {
|
|
|
37734
37819
|
});
|
|
37735
37820
|
const summarizer = new TreeSummarizer(aiRunner);
|
|
37736
37821
|
const indexer = new CodebaseIndexer(projectPath);
|
|
37737
|
-
console.log(
|
|
37738
|
-
|
|
37739
|
-
|
|
37740
|
-
indexer.
|
|
37822
|
+
console.log(`
|
|
37823
|
+
${c.step(" INDEX ")} ${c.primary("Analyzing codebase in")} ${c.bold(projectPath)}...`);
|
|
37824
|
+
try {
|
|
37825
|
+
const index = await indexer.index((msg) => console.log(` ${c.dim(msg)}`), (tree) => summarizer.summarize(tree));
|
|
37826
|
+
if (index) {
|
|
37827
|
+
indexer.saveIndex(index);
|
|
37828
|
+
}
|
|
37829
|
+
} catch (error48) {
|
|
37830
|
+
console.error(`
|
|
37831
|
+
${c.error("✖")} ${c.error("Indexing failed:")} ${c.red(error48 instanceof Error ? error48.message : String(error48))}`);
|
|
37832
|
+
console.error(c.dim(` The agent might have limited context until indexing succeeds.
|
|
37833
|
+
`));
|
|
37834
|
+
}
|
|
37835
|
+
console.log(`
|
|
37836
|
+
${c.success("✔")} ${c.success("Indexing complete!")}
|
|
37837
|
+
`);
|
|
37838
|
+
}
|
|
37839
|
+
async function execCommand(args) {
|
|
37840
|
+
const { values, positionals } = parseArgs({
|
|
37841
|
+
args,
|
|
37842
|
+
options: {
|
|
37843
|
+
model: { type: "string" },
|
|
37844
|
+
provider: { type: "string" },
|
|
37845
|
+
dir: { type: "string" }
|
|
37846
|
+
},
|
|
37847
|
+
strict: false
|
|
37848
|
+
});
|
|
37849
|
+
const promptInput = positionals.join(" ");
|
|
37850
|
+
if (!promptInput) {
|
|
37851
|
+
console.error(c.error('Error: Prompt is required. Usage: locus exec "your prompt"'));
|
|
37852
|
+
process.exit(1);
|
|
37853
|
+
}
|
|
37854
|
+
const projectPath = values.dir || process.cwd();
|
|
37855
|
+
requireInitialization(projectPath, "exec");
|
|
37856
|
+
const provider = resolveProvider2(values.provider);
|
|
37857
|
+
const model = values.model || DEFAULT_MODEL[provider];
|
|
37858
|
+
const aiRunner = createAiRunner(provider, {
|
|
37859
|
+
projectPath,
|
|
37860
|
+
model
|
|
37861
|
+
});
|
|
37862
|
+
const builder = new PromptBuilder(projectPath);
|
|
37863
|
+
const fullPrompt = await builder.buildGenericPrompt(promptInput);
|
|
37864
|
+
console.log(`
|
|
37865
|
+
${c.primary("\uD83D\uDE80")} ${c.bold("Executing prompt with repository context...")}
|
|
37866
|
+
`);
|
|
37867
|
+
try {
|
|
37868
|
+
const result = await aiRunner.run(fullPrompt);
|
|
37869
|
+
console.log(result);
|
|
37870
|
+
console.log(`
|
|
37871
|
+
${c.success("✔")} ${c.success("Execution finished!")}
|
|
37872
|
+
`);
|
|
37873
|
+
} catch (error48) {
|
|
37874
|
+
console.error(`
|
|
37875
|
+
${c.error("✖")} ${c.error("Execution failed:")} ${c.red(error48 instanceof Error ? error48.message : String(error48))}
|
|
37876
|
+
`);
|
|
37877
|
+
process.exit(1);
|
|
37741
37878
|
}
|
|
37742
|
-
console.log(c.success("✅ Indexing complete!"));
|
|
37743
37879
|
}
|
|
37744
37880
|
async function initCommand() {
|
|
37745
37881
|
const projectPath = process.cwd();
|
|
@@ -37755,19 +37891,19 @@ If you want to reinitialize, please remove the .locus directory first.
|
|
|
37755
37891
|
}
|
|
37756
37892
|
await new ConfigManager(projectPath).init(VERSION2);
|
|
37757
37893
|
console.log(`
|
|
37758
|
-
${c.success("✨ Locus initialized successfully!")}
|
|
37894
|
+
${c.success("✨ Locus initialized successfully!")}
|
|
37759
37895
|
|
|
37760
|
-
Created:
|
|
37761
|
-
|
|
37762
|
-
|
|
37763
|
-
|
|
37764
|
-
|
|
37896
|
+
${c.bold("Created:")}
|
|
37897
|
+
${c.primary("\uD83D\uDCC1")} ${c.bold(".locus/")} ${c.dim("Configuration directory")}
|
|
37898
|
+
${c.primary("\uD83D\uDCC4")} ${c.bold(".locus/config.json")} ${c.dim("Project settings")}
|
|
37899
|
+
${c.primary("\uD83D\uDCDD")} ${c.bold("CLAUDE.md")} ${c.dim("AI instructions & context")}
|
|
37900
|
+
${c.primary("\uD83D\uDCC1")} ${c.bold(".agent/skills/")} ${c.dim("Domain-specific agent skills")}
|
|
37765
37901
|
|
|
37766
|
-
Next steps:
|
|
37767
|
-
|
|
37768
|
-
|
|
37902
|
+
${c.bold("Next steps:")}
|
|
37903
|
+
1. Run '${c.primary("locus index")}' to index your codebase
|
|
37904
|
+
2. Run '${c.primary("locus run")}' to start an agent (requires --api-key)
|
|
37769
37905
|
|
|
37770
|
-
For more information, visit: ${c.underline("https://locusai.dev/docs")}
|
|
37906
|
+
For more information, visit: ${c.underline("https://locusai.dev/docs")}
|
|
37771
37907
|
`);
|
|
37772
37908
|
}
|
|
37773
37909
|
async function main() {
|
|
@@ -37784,30 +37920,35 @@ async function main() {
|
|
|
37784
37920
|
case "init":
|
|
37785
37921
|
await initCommand();
|
|
37786
37922
|
break;
|
|
37923
|
+
case "exec":
|
|
37924
|
+
await execCommand(args);
|
|
37925
|
+
break;
|
|
37787
37926
|
default:
|
|
37788
37927
|
console.log(`
|
|
37789
|
-
|
|
37928
|
+
${c.header(" USAGE ")}
|
|
37929
|
+
${c.primary("locus")} ${c.dim("<command> [options]")}
|
|
37790
37930
|
|
|
37791
|
-
|
|
37792
|
-
|
|
37793
|
-
|
|
37794
|
-
|
|
37931
|
+
${c.header(" COMMANDS ")}
|
|
37932
|
+
${c.success("init")} Initialize Locus in the current directory
|
|
37933
|
+
${c.success("index")} Index the codebase for AI context
|
|
37934
|
+
${c.success("run")} Start an agent to work on tasks
|
|
37935
|
+
${c.success("exec")} Run a prompt with repository context
|
|
37795
37936
|
|
|
37796
|
-
|
|
37797
|
-
|
|
37798
|
-
|
|
37799
|
-
--skip-planning Skip the planning phase (CLI planning)
|
|
37937
|
+
${c.header(" OPTIONS ")}
|
|
37938
|
+
${c.secondary("--help")} Show this help message
|
|
37939
|
+
${c.secondary("--provider")} <name> AI provider: ${c.dim("claude")} or ${c.dim("codex")} (default: ${c.dim("claude")})
|
|
37800
37940
|
|
|
37801
|
-
|
|
37802
|
-
|
|
37803
|
-
|
|
37804
|
-
|
|
37941
|
+
${c.header(" EXAMPLES ")}
|
|
37942
|
+
${c.dim("$")} ${c.primary("locus init")}
|
|
37943
|
+
${c.dim("$")} ${c.primary("locus index")}
|
|
37944
|
+
${c.dim("$")} ${c.primary("locus run --api-key YOUR_KEY")}
|
|
37805
37945
|
|
|
37806
|
-
For more information, visit: https://locusai.dev/docs
|
|
37946
|
+
For more information, visit: ${c.underline("https://locusai.dev/docs")}
|
|
37807
37947
|
`);
|
|
37808
37948
|
}
|
|
37809
37949
|
}
|
|
37810
37950
|
main().catch((err) => {
|
|
37811
|
-
console.error(`
|
|
37951
|
+
console.error(`
|
|
37952
|
+
${c.error("✖ Fatal Error")} ${c.red(err.message)}`);
|
|
37812
37953
|
process.exit(1);
|
|
37813
37954
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@locusai/cli",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.3",
|
|
4
4
|
"description": "CLI for Locus - AI-native project management platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"author": "",
|
|
33
33
|
"license": "MIT",
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@locusai/sdk": "^0.7.
|
|
35
|
+
"@locusai/sdk": "^0.7.3"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {}
|
|
38
38
|
}
|