@locusai/cli 0.4.0 → 0.4.2
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/locus.js +164 -50
- package/package.json +2 -2
package/bin/locus.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
2
|
-
// @bun
|
|
1
|
+
#!/usr/bin/env node
|
|
3
2
|
import { createRequire } from "node:module";
|
|
4
3
|
var __create = Object.create;
|
|
5
4
|
var __getProtoOf = Object.getPrototypeOf;
|
|
@@ -17646,13 +17645,21 @@ class CodebaseIndexer {
|
|
|
17646
17645
|
onProgress("Generating file tree...");
|
|
17647
17646
|
const files = await globby(["**/*"], {
|
|
17648
17647
|
cwd: this.projectPath,
|
|
17648
|
+
gitignore: true,
|
|
17649
17649
|
ignore: [
|
|
17650
17650
|
"**/node_modules/**",
|
|
17651
17651
|
"**/dist/**",
|
|
17652
17652
|
"**/build/**",
|
|
17653
|
+
"**/target/**",
|
|
17654
|
+
"**/bin/**",
|
|
17655
|
+
"**/obj/**",
|
|
17653
17656
|
"**/.next/**",
|
|
17657
|
+
"**/.svelte-kit/**",
|
|
17658
|
+
"**/.nuxt/**",
|
|
17659
|
+
"**/.cache/**",
|
|
17654
17660
|
"**/out/**",
|
|
17655
17661
|
"**/__tests__/**",
|
|
17662
|
+
"**/coverage/**",
|
|
17656
17663
|
"**/*.test.*",
|
|
17657
17664
|
"**/*.spec.*",
|
|
17658
17665
|
"**/*.d.ts",
|
|
@@ -17660,9 +17667,20 @@ class CodebaseIndexer {
|
|
|
17660
17667
|
"**/.locus/*.json",
|
|
17661
17668
|
"**/.locus/*.md",
|
|
17662
17669
|
"**/.locus/!(artifacts)/**",
|
|
17663
|
-
"
|
|
17664
|
-
"
|
|
17665
|
-
"
|
|
17670
|
+
"**/.git/**",
|
|
17671
|
+
"**/.svn/**",
|
|
17672
|
+
"**/.hg/**",
|
|
17673
|
+
"**/.vscode/**",
|
|
17674
|
+
"**/.idea/**",
|
|
17675
|
+
"**/.DS_Store",
|
|
17676
|
+
"**/bun.lock",
|
|
17677
|
+
"**/package-lock.json",
|
|
17678
|
+
"**/yarn.lock",
|
|
17679
|
+
"**/pnpm-lock.yaml",
|
|
17680
|
+
"**/Cargo.lock",
|
|
17681
|
+
"**/go.sum",
|
|
17682
|
+
"**/poetry.lock",
|
|
17683
|
+
"**/*.{png,jpg,jpeg,gif,svg,ico,mp4,webm,wav,mp3,woff,woff2,eot,ttf,otf,pdf,zip,tar.gz,rar}"
|
|
17666
17684
|
]
|
|
17667
17685
|
});
|
|
17668
17686
|
const treeString = files.join(`
|
|
@@ -21929,8 +21947,11 @@ class ClaudeRunner {
|
|
|
21929
21947
|
claude.on("close", (code) => {
|
|
21930
21948
|
if (code === 0)
|
|
21931
21949
|
resolve(output);
|
|
21932
|
-
else
|
|
21933
|
-
|
|
21950
|
+
else {
|
|
21951
|
+
const detail = errorOutput.trim();
|
|
21952
|
+
const message = detail ? `Claude CLI error: ${detail}` : `Claude CLI exited with code ${code}. Please ensure the Claude CLI is installed and you are logged in (run 'claude' manually to check).`;
|
|
21953
|
+
reject(new Error(message));
|
|
21954
|
+
}
|
|
21934
21955
|
});
|
|
21935
21956
|
claude.stdin.write(prompt);
|
|
21936
21957
|
claude.stdin.end();
|
|
@@ -30149,10 +30170,16 @@ var TasksResponseSchema = exports_external.object({
|
|
|
30149
30170
|
tasks: exports_external.array(TaskSchema)
|
|
30150
30171
|
});
|
|
30151
30172
|
// ../shared/src/models/workspace.ts
|
|
30173
|
+
var ChecklistItemSchema = exports_external.object({
|
|
30174
|
+
id: exports_external.string(),
|
|
30175
|
+
text: exports_external.string(),
|
|
30176
|
+
done: exports_external.boolean()
|
|
30177
|
+
});
|
|
30152
30178
|
var WorkspaceSchema = BaseEntitySchema.extend({
|
|
30153
30179
|
orgId: exports_external.string().uuid(),
|
|
30154
30180
|
name: exports_external.string().min(1, "Name is required").max(100),
|
|
30155
|
-
slug: exports_external.string().min(1, "Slug is required").regex(/^[a-z0-9-]+$/, "Slug must be lowercase alphanumeric with hyphens")
|
|
30181
|
+
slug: exports_external.string().min(1, "Slug is required").regex(/^[a-z0-9-]+$/, "Slug must be lowercase alphanumeric with hyphens"),
|
|
30182
|
+
defaultChecklist: exports_external.array(ChecklistItemSchema).nullable().optional()
|
|
30156
30183
|
});
|
|
30157
30184
|
var CreateWorkspaceSchema = exports_external.object({
|
|
30158
30185
|
name: exports_external.string().min(1, "Name is required").max(100),
|
|
@@ -30312,6 +30339,27 @@ class LocusClient {
|
|
|
30312
30339
|
this.invitations = new InvitationsModule(this.api, this.emitter);
|
|
30313
30340
|
this.docs = new DocsModule(this.api, this.emitter);
|
|
30314
30341
|
this.ci = new CiModule(this.api, this.emitter);
|
|
30342
|
+
if (config.retryOptions) {
|
|
30343
|
+
this.setupRetryInterceptor(config.retryOptions);
|
|
30344
|
+
}
|
|
30345
|
+
}
|
|
30346
|
+
setupRetryInterceptor(retryOptions) {
|
|
30347
|
+
this.api.interceptors.response.use(undefined, async (error2) => {
|
|
30348
|
+
const config = error2.config;
|
|
30349
|
+
if (!config || !retryOptions) {
|
|
30350
|
+
return Promise.reject(error2);
|
|
30351
|
+
}
|
|
30352
|
+
config._retryCount = config._retryCount || 0;
|
|
30353
|
+
const maxRetries = retryOptions.maxRetries ?? 3;
|
|
30354
|
+
const shouldRetry = config._retryCount < maxRetries && (retryOptions.retryCondition ? retryOptions.retryCondition(error2) : !error2.response || error2.response.status >= 500);
|
|
30355
|
+
if (shouldRetry) {
|
|
30356
|
+
config._retryCount++;
|
|
30357
|
+
const delay = Math.min((retryOptions.initialDelay ?? 1000) * Math.pow(retryOptions.factor ?? 2, config._retryCount - 1), retryOptions.maxDelay ?? 5000);
|
|
30358
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
30359
|
+
return this.api(config);
|
|
30360
|
+
}
|
|
30361
|
+
return Promise.reject(error2);
|
|
30362
|
+
});
|
|
30315
30363
|
}
|
|
30316
30364
|
setupInterceptors() {
|
|
30317
30365
|
this.api.interceptors.response.use((response) => {
|
|
@@ -30351,6 +30399,54 @@ class LocusClient {
|
|
|
30351
30399
|
}
|
|
30352
30400
|
}
|
|
30353
30401
|
|
|
30402
|
+
// ../sdk/src/utils/colors.ts
|
|
30403
|
+
var ESC = "\x1B[";
|
|
30404
|
+
var RESET = `${ESC}0m`;
|
|
30405
|
+
var colors = {
|
|
30406
|
+
reset: RESET,
|
|
30407
|
+
bold: `${ESC}1m`,
|
|
30408
|
+
dim: `${ESC}2m`,
|
|
30409
|
+
italic: `${ESC}3m`,
|
|
30410
|
+
underline: `${ESC}4m`,
|
|
30411
|
+
black: `${ESC}30m`,
|
|
30412
|
+
red: `${ESC}31m`,
|
|
30413
|
+
green: `${ESC}32m`,
|
|
30414
|
+
yellow: `${ESC}33m`,
|
|
30415
|
+
blue: `${ESC}34m`,
|
|
30416
|
+
magenta: `${ESC}35m`,
|
|
30417
|
+
cyan: `${ESC}36m`,
|
|
30418
|
+
white: `${ESC}37m`,
|
|
30419
|
+
gray: `${ESC}90m`,
|
|
30420
|
+
brightRed: `${ESC}91m`,
|
|
30421
|
+
brightGreen: `${ESC}92m`,
|
|
30422
|
+
brightYellow: `${ESC}93m`,
|
|
30423
|
+
brightBlue: `${ESC}94m`,
|
|
30424
|
+
brightMagenta: `${ESC}95m`,
|
|
30425
|
+
brightCyan: `${ESC}96m`,
|
|
30426
|
+
brightWhite: `${ESC}97m`
|
|
30427
|
+
};
|
|
30428
|
+
var c = {
|
|
30429
|
+
text: (text, ...colorNames) => {
|
|
30430
|
+
const codes = colorNames.map((name) => colors[name]).join("");
|
|
30431
|
+
return `${codes}${text}${RESET}`;
|
|
30432
|
+
},
|
|
30433
|
+
bold: (t) => c.text(t, "bold"),
|
|
30434
|
+
dim: (t) => c.text(t, "dim"),
|
|
30435
|
+
red: (t) => c.text(t, "red"),
|
|
30436
|
+
green: (t) => c.text(t, "green"),
|
|
30437
|
+
yellow: (t) => c.text(t, "yellow"),
|
|
30438
|
+
blue: (t) => c.text(t, "blue"),
|
|
30439
|
+
magenta: (t) => c.text(t, "magenta"),
|
|
30440
|
+
cyan: (t) => c.text(t, "cyan"),
|
|
30441
|
+
gray: (t) => c.text(t, "gray"),
|
|
30442
|
+
success: (t) => c.text(t, "green", "bold"),
|
|
30443
|
+
error: (t) => c.text(t, "red", "bold"),
|
|
30444
|
+
warning: (t) => c.text(t, "yellow", "bold"),
|
|
30445
|
+
info: (t) => c.text(t, "cyan", "bold"),
|
|
30446
|
+
primary: (t) => c.text(t, "blue", "bold"),
|
|
30447
|
+
underline: (t) => c.text(t, "underline")
|
|
30448
|
+
};
|
|
30449
|
+
|
|
30354
30450
|
// ../sdk/src/agent/worker.ts
|
|
30355
30451
|
class AgentWorker {
|
|
30356
30452
|
config;
|
|
@@ -30372,7 +30468,13 @@ class AgentWorker {
|
|
|
30372
30468
|
const projectPath = config.projectPath || process.cwd();
|
|
30373
30469
|
this.client = new LocusClient({
|
|
30374
30470
|
baseUrl: config.apiBase,
|
|
30375
|
-
token: config.apiKey
|
|
30471
|
+
token: config.apiKey,
|
|
30472
|
+
retryOptions: {
|
|
30473
|
+
maxRetries: 3,
|
|
30474
|
+
initialDelay: 1000,
|
|
30475
|
+
maxDelay: 5000,
|
|
30476
|
+
factor: 2
|
|
30477
|
+
}
|
|
30376
30478
|
});
|
|
30377
30479
|
this.claudeRunner = new ClaudeRunner(projectPath, config.model);
|
|
30378
30480
|
this.anthropicClient = config.anthropicApiKey ? new AnthropicClient({
|
|
@@ -30412,8 +30514,14 @@ class AgentWorker {
|
|
|
30412
30514
|
}
|
|
30413
30515
|
log(message, level = "info") {
|
|
30414
30516
|
const timestamp = new Date().toISOString().split("T")[1]?.slice(0, 8) ?? "";
|
|
30517
|
+
const colorFn = {
|
|
30518
|
+
info: c.cyan,
|
|
30519
|
+
success: c.green,
|
|
30520
|
+
warn: c.yellow,
|
|
30521
|
+
error: c.red
|
|
30522
|
+
}[level];
|
|
30415
30523
|
const prefix = { info: "ℹ", success: "✓", warn: "⚠", error: "✗" }[level];
|
|
30416
|
-
console.log(`[${timestamp}] [${this.config.agentId.slice(-8)}] ${prefix} ${message}`);
|
|
30524
|
+
console.log(`${c.dim(`[${timestamp}]`)} ${c.bold(`[${this.config.agentId.slice(-8)}]`)} ${colorFn(`${prefix} ${message}`)}`);
|
|
30417
30525
|
}
|
|
30418
30526
|
async getActiveSprint() {
|
|
30419
30527
|
try {
|
|
@@ -30569,11 +30677,11 @@ class AgentOrchestrator extends EventEmitter3 {
|
|
|
30569
30677
|
try {
|
|
30570
30678
|
const sprint2 = await this.client.sprints.getActive(this.config.workspaceId);
|
|
30571
30679
|
if (sprint2?.id) {
|
|
30572
|
-
console.log(`\uD83D\uDCCB Using active sprint: ${sprint2.name}`);
|
|
30680
|
+
console.log(c.info(`\uD83D\uDCCB Using active sprint: ${sprint2.name}`));
|
|
30573
30681
|
return sprint2.id;
|
|
30574
30682
|
}
|
|
30575
30683
|
} catch {}
|
|
30576
|
-
console.log("ℹ No sprint specified, working with all workspace tasks");
|
|
30684
|
+
console.log(c.dim("ℹ No sprint specified, working with all workspace tasks"));
|
|
30577
30685
|
return "";
|
|
30578
30686
|
}
|
|
30579
30687
|
async start() {
|
|
@@ -30599,18 +30707,18 @@ class AgentOrchestrator extends EventEmitter3 {
|
|
|
30599
30707
|
sprintId: this.resolvedSprintId
|
|
30600
30708
|
});
|
|
30601
30709
|
console.log(`
|
|
30602
|
-
\uD83E\uDD16 Locus Agent Orchestrator`);
|
|
30603
|
-
console.log("
|
|
30604
|
-
console.log(
|
|
30710
|
+
${c.primary("\uD83E\uDD16 Locus Agent Orchestrator")}`);
|
|
30711
|
+
console.log(c.dim("----------------------------------------------"));
|
|
30712
|
+
console.log(`${c.bold("Workspace:")} ${this.config.workspaceId}`);
|
|
30605
30713
|
if (this.resolvedSprintId) {
|
|
30606
|
-
console.log(
|
|
30714
|
+
console.log(`${c.bold("Sprint:")} ${this.resolvedSprintId}`);
|
|
30607
30715
|
}
|
|
30608
|
-
console.log(
|
|
30609
|
-
console.log(
|
|
30610
|
-
`);
|
|
30716
|
+
console.log(`${c.bold("API Base:")} ${this.config.apiBase}`);
|
|
30717
|
+
console.log(c.dim(`----------------------------------------------
|
|
30718
|
+
`));
|
|
30611
30719
|
const tasks2 = await this.getAvailableTasks();
|
|
30612
30720
|
if (tasks2.length === 0) {
|
|
30613
|
-
console.log("ℹ No available tasks found in the backlog.");
|
|
30721
|
+
console.log(c.dim("ℹ No available tasks found in the backlog."));
|
|
30614
30722
|
return;
|
|
30615
30723
|
}
|
|
30616
30724
|
await this.spawnAgent();
|
|
@@ -30622,7 +30730,7 @@ class AgentOrchestrator extends EventEmitter3 {
|
|
|
30622
30730
|
await this.sleep(2000);
|
|
30623
30731
|
}
|
|
30624
30732
|
console.log(`
|
|
30625
|
-
✅ Orchestrator finished`);
|
|
30733
|
+
${c.success("✅ Orchestrator finished")}`);
|
|
30626
30734
|
}
|
|
30627
30735
|
findPackageRoot(startPath) {
|
|
30628
30736
|
let currentDir = startPath;
|
|
@@ -30645,7 +30753,7 @@ class AgentOrchestrator extends EventEmitter3 {
|
|
|
30645
30753
|
lastHeartbeat: new Date
|
|
30646
30754
|
};
|
|
30647
30755
|
this.agents.set(agentId, agentState);
|
|
30648
|
-
console.log(
|
|
30756
|
+
console.log(`${c.primary("\uD83D\uDE80 Agent started:")} ${c.bold(agentId)}
|
|
30649
30757
|
`);
|
|
30650
30758
|
const potentialPaths = [];
|
|
30651
30759
|
try {
|
|
@@ -30681,7 +30789,7 @@ class AgentOrchestrator extends EventEmitter3 {
|
|
|
30681
30789
|
if (this.resolvedSprintId) {
|
|
30682
30790
|
workerArgs.push("--sprint-id", this.resolvedSprintId);
|
|
30683
30791
|
}
|
|
30684
|
-
const agentProcess = spawn2(
|
|
30792
|
+
const agentProcess = spawn2(process.execPath, [workerPath, ...workerArgs]);
|
|
30685
30793
|
agentState.process = agentProcess;
|
|
30686
30794
|
agentProcess.on("message", (msg) => {
|
|
30687
30795
|
if (msg.type === "stats") {
|
|
@@ -30886,16 +30994,22 @@ Return ONLY a JSON object with this structure:
|
|
|
30886
30994
|
File Tree:
|
|
30887
30995
|
${tree}`;
|
|
30888
30996
|
const claude = spawn3("claude", ["--print"], {
|
|
30889
|
-
stdio: ["pipe", "pipe", "
|
|
30997
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
30890
30998
|
cwd: this.projectPath
|
|
30891
30999
|
});
|
|
30892
31000
|
let output = "";
|
|
31001
|
+
let errorOutput = "";
|
|
30893
31002
|
claude.stdout.on("data", (data) => {
|
|
30894
31003
|
output += data.toString();
|
|
30895
31004
|
});
|
|
31005
|
+
claude.stderr.on("data", (data) => {
|
|
31006
|
+
errorOutput += data.toString();
|
|
31007
|
+
});
|
|
30896
31008
|
claude.on("close", (code) => {
|
|
30897
|
-
if (code !== 0)
|
|
30898
|
-
|
|
31009
|
+
if (code !== 0) {
|
|
31010
|
+
const errMsg = errorOutput.trim() || `Claude exited with code ${code}`;
|
|
31011
|
+
return reject(new Error(errMsg));
|
|
31012
|
+
}
|
|
30899
31013
|
try {
|
|
30900
31014
|
const jsonMatch = output.match(/\{[\s\S]*\}/);
|
|
30901
31015
|
if (jsonMatch)
|
|
@@ -30927,13 +31041,13 @@ function getVersion() {
|
|
|
30927
31041
|
}
|
|
30928
31042
|
var VERSION3 = getVersion();
|
|
30929
31043
|
function printBanner() {
|
|
30930
|
-
console.log(`
|
|
30931
|
-
|
|
30932
|
-
|
|
30933
|
-
|
|
30934
|
-
|
|
30935
|
-
|
|
30936
|
-
`);
|
|
31044
|
+
console.log(c.primary(`
|
|
31045
|
+
## ###### ###### ## ## ######
|
|
31046
|
+
## ## ## ## ## ## ##
|
|
31047
|
+
## ## ## ## ## ## ######
|
|
31048
|
+
## ## ## ## ## ## ##
|
|
31049
|
+
####### ###### ###### ###### ###### v${VERSION3}
|
|
31050
|
+
`));
|
|
30937
31051
|
}
|
|
30938
31052
|
function isProjectInitialized(projectPath) {
|
|
30939
31053
|
const locusDir = join6(projectPath, LOCUS_CONFIG.dir);
|
|
@@ -30943,12 +31057,12 @@ function isProjectInitialized(projectPath) {
|
|
|
30943
31057
|
function requireInitialization(projectPath, command) {
|
|
30944
31058
|
if (!isProjectInitialized(projectPath)) {
|
|
30945
31059
|
console.error(`
|
|
30946
|
-
❌ Error: Locus is not initialized in this directory.
|
|
31060
|
+
${c.error("❌ Error: Locus is not initialized in this directory.")}
|
|
30947
31061
|
|
|
30948
|
-
The '${command}' command requires a Locus project to be initialized.
|
|
31062
|
+
The '${c.bold(command)}' command requires a Locus project to be initialized.
|
|
30949
31063
|
|
|
30950
31064
|
To initialize Locus in this directory, run:
|
|
30951
|
-
locus init
|
|
31065
|
+
${c.primary("locus init")}
|
|
30952
31066
|
|
|
30953
31067
|
This will create a .locus directory with the necessary configuration.
|
|
30954
31068
|
`);
|
|
@@ -30975,7 +31089,7 @@ async function runCommand(args) {
|
|
|
30975
31089
|
const anthropicApiKey = values["anthropic-api-key"] || process.env.ANTHROPIC_API_KEY;
|
|
30976
31090
|
const workspaceId = values.workspace || process.env.LOCUS_WORKSPACE_ID;
|
|
30977
31091
|
if (!apiKey || !workspaceId) {
|
|
30978
|
-
console.error("Error: --api-key and --workspace are required");
|
|
31092
|
+
console.error(c.error("Error: --api-key and --workspace are required"));
|
|
30979
31093
|
process.exit(1);
|
|
30980
31094
|
}
|
|
30981
31095
|
const orchestrator = new AgentOrchestrator({
|
|
@@ -30991,7 +31105,7 @@ async function runCommand(args) {
|
|
|
30991
31105
|
orchestrator.on("task:assigned", (data) => console.log(`ℹ [CLAIMED] ${data.title}`));
|
|
30992
31106
|
orchestrator.on("task:completed", (data) => console.log(`✓ [COMPLETED] ${data.taskId}`));
|
|
30993
31107
|
orchestrator.on("task:failed", (data) => console.log(`✗ [FAILED] ${data.taskId}: ${data.error}`));
|
|
30994
|
-
console.log(
|
|
31108
|
+
console.log(`${c.primary("\uD83D\uDE80 Starting agent in")} ${c.bold(projectPath)}...`);
|
|
30995
31109
|
await orchestrator.start();
|
|
30996
31110
|
}
|
|
30997
31111
|
async function indexCommand(args) {
|
|
@@ -31004,18 +31118,18 @@ async function indexCommand(args) {
|
|
|
31004
31118
|
requireInitialization(projectPath, "index");
|
|
31005
31119
|
const summarizer = new TreeSummarizer(projectPath);
|
|
31006
31120
|
const indexer = new CodebaseIndexer(projectPath);
|
|
31007
|
-
console.log(
|
|
31008
|
-
const index = await indexer.index((msg) => console.log(` ${msg}`), (tree) => summarizer.summarize(tree));
|
|
31121
|
+
console.log(`${c.primary("\uD83D\uDD0D Indexing codebase in")} ${c.bold(projectPath)}...`);
|
|
31122
|
+
const index = await indexer.index((msg) => console.log(` ${c.dim(msg)}`), (tree) => summarizer.summarize(tree));
|
|
31009
31123
|
indexer.saveIndex(index);
|
|
31010
|
-
console.log("✅ Indexing complete!");
|
|
31124
|
+
console.log(c.success("✅ Indexing complete!"));
|
|
31011
31125
|
}
|
|
31012
31126
|
async function initCommand() {
|
|
31013
31127
|
const projectPath = process.cwd();
|
|
31014
31128
|
if (isProjectInitialized(projectPath)) {
|
|
31015
31129
|
console.log(`
|
|
31016
|
-
ℹ️ Locus is already initialized in this directory.
|
|
31130
|
+
${c.info("ℹ️ Locus is already initialized in this directory.")}
|
|
31017
31131
|
|
|
31018
|
-
Configuration found at: ${join6(projectPath, LOCUS_CONFIG.dir)}
|
|
31132
|
+
Configuration found at: ${c.bold(join6(projectPath, LOCUS_CONFIG.dir))}
|
|
31019
31133
|
|
|
31020
31134
|
If you want to reinitialize, please remove the .locus directory first.
|
|
31021
31135
|
`);
|
|
@@ -31023,18 +31137,18 @@ If you want to reinitialize, please remove the .locus directory first.
|
|
|
31023
31137
|
}
|
|
31024
31138
|
await new ConfigManager(projectPath).init(VERSION3);
|
|
31025
31139
|
console.log(`
|
|
31026
|
-
✨ Locus initialized successfully!
|
|
31140
|
+
${c.success("✨ Locus initialized successfully!")}
|
|
31027
31141
|
|
|
31028
31142
|
Created:
|
|
31029
|
-
\uD83D\uDCC1 .locus/ - Locus configuration directory
|
|
31030
|
-
\uD83D\uDCC4 .locus/config.json - Project configuration
|
|
31031
|
-
\uD83D\uDCDD CLAUDE.md - AI context file
|
|
31143
|
+
\uD83D\uDCC1 ${c.dim(".locus/")} - Locus configuration directory
|
|
31144
|
+
\uD83D\uDCC4 ${c.dim(".locus/config.json")} - Project configuration
|
|
31145
|
+
\uD83D\uDCDD ${c.dim("CLAUDE.md")} - AI context file
|
|
31032
31146
|
|
|
31033
31147
|
Next steps:
|
|
31034
|
-
1. Run 'locus index' to index your codebase
|
|
31035
|
-
2. Run 'locus run' to start an agent (requires --api-key and --workspace)
|
|
31148
|
+
1. Run '${c.primary("locus index")}' to index your codebase
|
|
31149
|
+
2. Run '${c.primary("locus run")}' to start an agent (requires --api-key and --workspace)
|
|
31036
31150
|
|
|
31037
|
-
For more information, visit: https://locus.dev/docs
|
|
31151
|
+
For more information, visit: ${c.underline("https://locus.dev/docs")}
|
|
31038
31152
|
`);
|
|
31039
31153
|
}
|
|
31040
31154
|
async function main() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@locusai/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Local-first AI development platform & engineering workspace",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"author": "",
|
|
32
32
|
"license": "MIT",
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@locusai/sdk": "^0.4.
|
|
34
|
+
"@locusai/sdk": "^0.4.2"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {}
|
|
37
37
|
}
|