@locusai/cli 0.15.5 → 0.16.1
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 +0 -99
- package/bin/locus.js +85 -815
- package/package.json +3 -4
package/bin/locus.js
CHANGED
|
@@ -7055,7 +7055,6 @@ var init_resolve_bin = __esm(() => {
|
|
|
7055
7055
|
join4(homedir(), ".local", "bin"),
|
|
7056
7056
|
join4(homedir(), ".npm", "bin"),
|
|
7057
7057
|
join4(homedir(), ".npm-global", "bin"),
|
|
7058
|
-
join4(homedir(), ".npm-packages", "bin"),
|
|
7059
7058
|
join4(homedir(), ".yarn", "bin"),
|
|
7060
7059
|
join4(homedir(), ".bun", "bin"),
|
|
7061
7060
|
join4(homedir(), "Library", "pnpm"),
|
|
@@ -23353,29 +23352,6 @@ var init_sprints = __esm(() => {
|
|
|
23353
23352
|
};
|
|
23354
23353
|
});
|
|
23355
23354
|
|
|
23356
|
-
// ../sdk/src/modules/suggestions.ts
|
|
23357
|
-
var SuggestionsModule;
|
|
23358
|
-
var init_suggestions = __esm(() => {
|
|
23359
|
-
SuggestionsModule = class SuggestionsModule extends BaseModule {
|
|
23360
|
-
async create(workspaceId, data) {
|
|
23361
|
-
const { data: res } = await this.api.post(`/workspaces/${workspaceId}/suggestions`, data);
|
|
23362
|
-
return res.suggestion;
|
|
23363
|
-
}
|
|
23364
|
-
async list(workspaceId, params) {
|
|
23365
|
-
const { data } = await this.api.get(`/workspaces/${workspaceId}/suggestions`, { params });
|
|
23366
|
-
return data.suggestions;
|
|
23367
|
-
}
|
|
23368
|
-
async get(workspaceId, id) {
|
|
23369
|
-
const { data } = await this.api.get(`/workspaces/${workspaceId}/suggestions/${id}`);
|
|
23370
|
-
return data.suggestion;
|
|
23371
|
-
}
|
|
23372
|
-
async updateStatus(workspaceId, id, status) {
|
|
23373
|
-
const { data } = await this.api.patch(`/workspaces/${workspaceId}/suggestions/${id}/status`, status);
|
|
23374
|
-
return data.suggestion;
|
|
23375
|
-
}
|
|
23376
|
-
};
|
|
23377
|
-
});
|
|
23378
|
-
|
|
23379
23355
|
// ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/core/core.js
|
|
23380
23356
|
function $constructor(name, initializer, params) {
|
|
23381
23357
|
function init(inst, def) {
|
|
@@ -37691,75 +37667,6 @@ var init_auth2 = __esm(() => {
|
|
|
37691
37667
|
});
|
|
37692
37668
|
});
|
|
37693
37669
|
|
|
37694
|
-
// ../shared/src/models/autonomy.ts
|
|
37695
|
-
var RiskLevel, ChangeCategory, AutonomyRuleSchema, DEFAULT_AUTONOMY_RULES;
|
|
37696
|
-
var init_autonomy = __esm(() => {
|
|
37697
|
-
init_zod();
|
|
37698
|
-
((RiskLevel2) => {
|
|
37699
|
-
RiskLevel2["LOW"] = "LOW";
|
|
37700
|
-
RiskLevel2["HIGH"] = "HIGH";
|
|
37701
|
-
})(RiskLevel ||= {});
|
|
37702
|
-
((ChangeCategory2) => {
|
|
37703
|
-
ChangeCategory2["FIX"] = "FIX";
|
|
37704
|
-
ChangeCategory2["REFACTOR"] = "REFACTOR";
|
|
37705
|
-
ChangeCategory2["STYLE"] = "STYLE";
|
|
37706
|
-
ChangeCategory2["DEPENDENCY"] = "DEPENDENCY";
|
|
37707
|
-
ChangeCategory2["FEATURE"] = "FEATURE";
|
|
37708
|
-
ChangeCategory2["ARCHITECTURE"] = "ARCHITECTURE";
|
|
37709
|
-
ChangeCategory2["DATABASE"] = "DATABASE";
|
|
37710
|
-
ChangeCategory2["AUTH"] = "AUTH";
|
|
37711
|
-
ChangeCategory2["API"] = "API";
|
|
37712
|
-
})(ChangeCategory ||= {});
|
|
37713
|
-
AutonomyRuleSchema = exports_external.object({
|
|
37714
|
-
category: exports_external.enum(ChangeCategory),
|
|
37715
|
-
riskLevel: exports_external.enum(RiskLevel),
|
|
37716
|
-
autoExecute: exports_external.boolean()
|
|
37717
|
-
});
|
|
37718
|
-
DEFAULT_AUTONOMY_RULES = [
|
|
37719
|
-
{ category: "FIX" /* FIX */, riskLevel: "LOW" /* LOW */, autoExecute: true },
|
|
37720
|
-
{
|
|
37721
|
-
category: "REFACTOR" /* REFACTOR */,
|
|
37722
|
-
riskLevel: "LOW" /* LOW */,
|
|
37723
|
-
autoExecute: true
|
|
37724
|
-
},
|
|
37725
|
-
{
|
|
37726
|
-
category: "STYLE" /* STYLE */,
|
|
37727
|
-
riskLevel: "LOW" /* LOW */,
|
|
37728
|
-
autoExecute: true
|
|
37729
|
-
},
|
|
37730
|
-
{
|
|
37731
|
-
category: "DEPENDENCY" /* DEPENDENCY */,
|
|
37732
|
-
riskLevel: "LOW" /* LOW */,
|
|
37733
|
-
autoExecute: true
|
|
37734
|
-
},
|
|
37735
|
-
{
|
|
37736
|
-
category: "FEATURE" /* FEATURE */,
|
|
37737
|
-
riskLevel: "HIGH" /* HIGH */,
|
|
37738
|
-
autoExecute: false
|
|
37739
|
-
},
|
|
37740
|
-
{
|
|
37741
|
-
category: "ARCHITECTURE" /* ARCHITECTURE */,
|
|
37742
|
-
riskLevel: "HIGH" /* HIGH */,
|
|
37743
|
-
autoExecute: false
|
|
37744
|
-
},
|
|
37745
|
-
{
|
|
37746
|
-
category: "DATABASE" /* DATABASE */,
|
|
37747
|
-
riskLevel: "HIGH" /* HIGH */,
|
|
37748
|
-
autoExecute: false
|
|
37749
|
-
},
|
|
37750
|
-
{
|
|
37751
|
-
category: "AUTH" /* AUTH */,
|
|
37752
|
-
riskLevel: "HIGH" /* HIGH */,
|
|
37753
|
-
autoExecute: false
|
|
37754
|
-
},
|
|
37755
|
-
{
|
|
37756
|
-
category: "API" /* API */,
|
|
37757
|
-
riskLevel: "HIGH" /* HIGH */,
|
|
37758
|
-
autoExecute: false
|
|
37759
|
-
}
|
|
37760
|
-
];
|
|
37761
|
-
});
|
|
37762
|
-
|
|
37763
37670
|
// ../shared/src/models/aws-instance.ts
|
|
37764
37671
|
var InstanceAction, AwsCredentialsSchema, IntegrationSchema, AwsInstanceSchema, CreateAwsInstanceSchema, UpdateAwsInstanceSchema, SaveAwsCredentialsSchema, ProvisionAwsInstanceSchema, InstanceActionBodySchema, InstanceIdParamSchema, CIDR_REGEX, UpdateSecurityRulesSchema;
|
|
37765
37672
|
var init_aws_instance = __esm(() => {
|
|
@@ -38078,49 +37985,6 @@ var init_sprint = __esm(() => {
|
|
|
38078
37985
|
});
|
|
38079
37986
|
});
|
|
38080
37987
|
|
|
38081
|
-
// ../shared/src/models/suggestion.ts
|
|
38082
|
-
var SuggestionStatus, SuggestionType, SuggestionSchema, CreateSuggestionSchema, UpdateSuggestionStatusSchema;
|
|
38083
|
-
var init_suggestion = __esm(() => {
|
|
38084
|
-
init_zod();
|
|
38085
|
-
((SuggestionStatus2) => {
|
|
38086
|
-
SuggestionStatus2["NEW"] = "NEW";
|
|
38087
|
-
SuggestionStatus2["NOTIFIED"] = "NOTIFIED";
|
|
38088
|
-
SuggestionStatus2["ACTED_ON"] = "ACTED_ON";
|
|
38089
|
-
SuggestionStatus2["SKIPPED"] = "SKIPPED";
|
|
38090
|
-
SuggestionStatus2["EXPIRED"] = "EXPIRED";
|
|
38091
|
-
})(SuggestionStatus ||= {});
|
|
38092
|
-
((SuggestionType2) => {
|
|
38093
|
-
SuggestionType2["CODE_FIX"] = "CODE_FIX";
|
|
38094
|
-
SuggestionType2["DEPENDENCY_UPDATE"] = "DEPENDENCY_UPDATE";
|
|
38095
|
-
SuggestionType2["NEXT_STEP"] = "NEXT_STEP";
|
|
38096
|
-
SuggestionType2["REFACTOR"] = "REFACTOR";
|
|
38097
|
-
SuggestionType2["TEST_FIX"] = "TEST_FIX";
|
|
38098
|
-
})(SuggestionType ||= {});
|
|
38099
|
-
SuggestionSchema = exports_external.object({
|
|
38100
|
-
id: exports_external.string(),
|
|
38101
|
-
type: exports_external.enum(SuggestionType),
|
|
38102
|
-
status: exports_external.enum(SuggestionStatus),
|
|
38103
|
-
title: exports_external.string(),
|
|
38104
|
-
description: exports_external.string(),
|
|
38105
|
-
jobRunId: exports_external.string().optional(),
|
|
38106
|
-
workspaceId: exports_external.string(),
|
|
38107
|
-
createdAt: exports_external.string(),
|
|
38108
|
-
expiresAt: exports_external.string(),
|
|
38109
|
-
metadata: exports_external.record(exports_external.string(), exports_external.any()).optional()
|
|
38110
|
-
});
|
|
38111
|
-
CreateSuggestionSchema = exports_external.object({
|
|
38112
|
-
type: exports_external.enum(SuggestionType),
|
|
38113
|
-
title: exports_external.string().min(1, "Title is required"),
|
|
38114
|
-
description: exports_external.string().min(1, "Description is required"),
|
|
38115
|
-
jobRunId: exports_external.string().uuid().optional(),
|
|
38116
|
-
metadata: exports_external.record(exports_external.string(), exports_external.any()).optional(),
|
|
38117
|
-
expiresAt: exports_external.string().optional()
|
|
38118
|
-
});
|
|
38119
|
-
UpdateSuggestionStatusSchema = exports_external.object({
|
|
38120
|
-
status: exports_external.enum(SuggestionStatus)
|
|
38121
|
-
});
|
|
38122
|
-
});
|
|
38123
|
-
|
|
38124
37988
|
// ../shared/src/models/task.ts
|
|
38125
37989
|
var AcceptanceItemSchema, TaskSchema, CreateTaskSchema, UpdateTaskSchema, AddCommentSchema, DispatchTaskSchema, TaskIdParamSchema, TaskQuerySchema, TaskResponseSchema, TasksResponseSchema;
|
|
38126
37990
|
var init_task = __esm(() => {
|
|
@@ -38260,7 +38124,6 @@ var init_models = __esm(() => {
|
|
|
38260
38124
|
init_activity();
|
|
38261
38125
|
init_agent();
|
|
38262
38126
|
init_auth2();
|
|
38263
|
-
init_autonomy();
|
|
38264
38127
|
init_aws_instance();
|
|
38265
38128
|
init_ci2();
|
|
38266
38129
|
init_doc();
|
|
@@ -38268,7 +38131,6 @@ var init_models = __esm(() => {
|
|
|
38268
38131
|
init_invitation();
|
|
38269
38132
|
init_organization();
|
|
38270
38133
|
init_sprint();
|
|
38271
|
-
init_suggestion();
|
|
38272
38134
|
init_task();
|
|
38273
38135
|
init_user();
|
|
38274
38136
|
init_workspace();
|
|
@@ -38991,7 +38853,6 @@ class LocusClient {
|
|
|
38991
38853
|
docs;
|
|
38992
38854
|
ci;
|
|
38993
38855
|
instances;
|
|
38994
|
-
suggestions;
|
|
38995
38856
|
constructor(config2) {
|
|
38996
38857
|
this.emitter = new LocusEmitter;
|
|
38997
38858
|
this.api = axios_default.create({
|
|
@@ -39012,7 +38873,6 @@ class LocusClient {
|
|
|
39012
38873
|
this.docs = new DocsModule(this.api, this.emitter);
|
|
39013
38874
|
this.ci = new CiModule(this.api, this.emitter);
|
|
39014
38875
|
this.instances = new InstancesModule(this.api, this.emitter);
|
|
39015
|
-
this.suggestions = new SuggestionsModule(this.api, this.emitter);
|
|
39016
38876
|
if (config2.retryOptions) {
|
|
39017
38877
|
this.setupRetryInterceptor(config2.retryOptions);
|
|
39018
38878
|
}
|
|
@@ -39082,7 +38942,6 @@ var init_src2 = __esm(() => {
|
|
|
39082
38942
|
init_invitations();
|
|
39083
38943
|
init_organizations();
|
|
39084
38944
|
init_sprints();
|
|
39085
|
-
init_suggestions();
|
|
39086
38945
|
init_tasks();
|
|
39087
38946
|
init_workspaces();
|
|
39088
38947
|
init_discussion_types();
|
|
@@ -39094,7 +38953,6 @@ var init_src2 = __esm(() => {
|
|
|
39094
38953
|
init_invitations();
|
|
39095
38954
|
init_organizations();
|
|
39096
38955
|
init_sprints();
|
|
39097
|
-
init_suggestions();
|
|
39098
38956
|
init_tasks();
|
|
39099
38957
|
init_workspaces();
|
|
39100
38958
|
});
|
|
@@ -42037,22 +41895,6 @@ var init_planning = __esm(() => {
|
|
|
42037
41895
|
init_sprint_plan();
|
|
42038
41896
|
});
|
|
42039
41897
|
|
|
42040
|
-
// ../sdk/src/proposals/context-gatherer.ts
|
|
42041
|
-
var init_context_gatherer = () => {};
|
|
42042
|
-
|
|
42043
|
-
// ../sdk/src/proposals/proposal-engine.ts
|
|
42044
|
-
var init_proposal_engine = __esm(() => {
|
|
42045
|
-
init_src();
|
|
42046
|
-
init_factory();
|
|
42047
|
-
init_context_gatherer();
|
|
42048
|
-
});
|
|
42049
|
-
|
|
42050
|
-
// ../sdk/src/proposals/index.ts
|
|
42051
|
-
var init_proposals = __esm(() => {
|
|
42052
|
-
init_context_gatherer();
|
|
42053
|
-
init_proposal_engine();
|
|
42054
|
-
});
|
|
42055
|
-
|
|
42056
41898
|
// ../sdk/src/index-node.ts
|
|
42057
41899
|
var init_index_node = __esm(() => {
|
|
42058
41900
|
init_prompt_builder();
|
|
@@ -42067,7 +41909,6 @@ var init_index_node = __esm(() => {
|
|
|
42067
41909
|
init_git();
|
|
42068
41910
|
init_src2();
|
|
42069
41911
|
init_planning();
|
|
42070
|
-
init_proposals();
|
|
42071
41912
|
});
|
|
42072
41913
|
|
|
42073
41914
|
// src/utils/version.ts
|
|
@@ -42506,22 +42347,9 @@ class SettingsManager {
|
|
|
42506
42347
|
exists() {
|
|
42507
42348
|
return existsSync15(getSettingsPath(this.projectPath));
|
|
42508
42349
|
}
|
|
42509
|
-
getAutonomyRules() {
|
|
42510
|
-
const settings = this.load();
|
|
42511
|
-
const userRules = settings.autonomy?.rules ?? [];
|
|
42512
|
-
if (userRules.length === 0) {
|
|
42513
|
-
return DEFAULT_AUTONOMY_RULES;
|
|
42514
|
-
}
|
|
42515
|
-
const ruleMap = new Map(DEFAULT_AUTONOMY_RULES.map((r) => [r.category, r]));
|
|
42516
|
-
for (const rule of userRules) {
|
|
42517
|
-
ruleMap.set(rule.category, rule);
|
|
42518
|
-
}
|
|
42519
|
-
return Array.from(ruleMap.values());
|
|
42520
|
-
}
|
|
42521
42350
|
}
|
|
42522
42351
|
var init_settings_manager = __esm(() => {
|
|
42523
42352
|
init_index_node();
|
|
42524
|
-
init_src();
|
|
42525
42353
|
});
|
|
42526
42354
|
|
|
42527
42355
|
// src/workspace-resolver.ts
|
|
@@ -43126,19 +42954,31 @@ class ProgressRenderer {
|
|
|
43126
42954
|
toolDisplay = new ToolDisplay;
|
|
43127
42955
|
toolDisplayShown = false;
|
|
43128
42956
|
thinkingShown = false;
|
|
42957
|
+
animated;
|
|
43129
42958
|
spinnerInterval = null;
|
|
43130
42959
|
spinnerFrameIndex = 0;
|
|
43131
42960
|
thinkingStartTime = null;
|
|
43132
42961
|
isInTextBlock = false;
|
|
43133
42962
|
textBuffer = "";
|
|
42963
|
+
constructor(options = {}) {
|
|
42964
|
+
this.animated = options.animated ?? false;
|
|
42965
|
+
}
|
|
43134
42966
|
showThinkingStarted() {
|
|
43135
42967
|
if (this.isThinking)
|
|
43136
42968
|
return;
|
|
43137
42969
|
this.isThinking = true;
|
|
43138
42970
|
this.thinkingStartTime = Date.now();
|
|
43139
|
-
if (
|
|
43140
|
-
this.thinkingShown
|
|
43141
|
-
|
|
42971
|
+
if (this.animated) {
|
|
42972
|
+
if (!this.thinkingShown) {
|
|
42973
|
+
this.thinkingShown = true;
|
|
42974
|
+
this.startThinkingAnimation();
|
|
42975
|
+
}
|
|
42976
|
+
} else {
|
|
42977
|
+
if (!this.thinkingShown) {
|
|
42978
|
+
console.log(c.dim(`\uD83E\uDD14 Thinking...
|
|
42979
|
+
`));
|
|
42980
|
+
this.thinkingShown = true;
|
|
42981
|
+
}
|
|
43142
42982
|
}
|
|
43143
42983
|
}
|
|
43144
42984
|
showThinkingStopped() {
|
|
@@ -43169,7 +43009,7 @@ class ProgressRenderer {
|
|
|
43169
43009
|
clearInterval(this.spinnerInterval);
|
|
43170
43010
|
this.spinnerInterval = null;
|
|
43171
43011
|
}
|
|
43172
|
-
if (this.thinkingShown && this.isThinking) {
|
|
43012
|
+
if (this.animated && this.thinkingShown && this.isThinking) {
|
|
43173
43013
|
process.stdout.write(`${ANSI.MOVE_TO_START}${ANSI.CLEAR_LINE}
|
|
43174
43014
|
`);
|
|
43175
43015
|
}
|
|
@@ -43451,9 +43291,9 @@ var init_progress_renderer = __esm(() => {
|
|
|
43451
43291
|
});
|
|
43452
43292
|
|
|
43453
43293
|
// src/repl/image-detect.ts
|
|
43454
|
-
import { copyFileSync, existsSync as
|
|
43455
|
-
import { homedir as
|
|
43456
|
-
import { basename as basename2, join as
|
|
43294
|
+
import { copyFileSync, existsSync as existsSync18, mkdirSync as mkdirSync8 } from "node:fs";
|
|
43295
|
+
import { homedir as homedir2, tmpdir as tmpdir2 } from "node:os";
|
|
43296
|
+
import { basename as basename2, join as join18 } from "node:path";
|
|
43457
43297
|
function hasImageExtension(p) {
|
|
43458
43298
|
const dot = p.lastIndexOf(".");
|
|
43459
43299
|
if (dot === -1)
|
|
@@ -43466,16 +43306,16 @@ function resolvePath(raw) {
|
|
|
43466
43306
|
p = p.slice(1, -1);
|
|
43467
43307
|
}
|
|
43468
43308
|
if (p.startsWith("~/")) {
|
|
43469
|
-
p =
|
|
43309
|
+
p = homedir2() + p.slice(1);
|
|
43470
43310
|
}
|
|
43471
43311
|
return p;
|
|
43472
43312
|
}
|
|
43473
43313
|
function copyToStable(srcPath) {
|
|
43474
43314
|
try {
|
|
43475
|
-
|
|
43315
|
+
mkdirSync8(STABLE_IMAGE_DIR, { recursive: true });
|
|
43476
43316
|
const ts = Date.now();
|
|
43477
43317
|
const name = `${ts}-${basename2(srcPath)}`;
|
|
43478
|
-
const destPath =
|
|
43318
|
+
const destPath = join18(STABLE_IMAGE_DIR, name);
|
|
43479
43319
|
copyFileSync(srcPath, destPath);
|
|
43480
43320
|
return destPath;
|
|
43481
43321
|
} catch {
|
|
@@ -43495,7 +43335,7 @@ function detectImages(input) {
|
|
|
43495
43335
|
let exists = false;
|
|
43496
43336
|
let stablePath = normalized;
|
|
43497
43337
|
try {
|
|
43498
|
-
exists =
|
|
43338
|
+
exists = existsSync18(normalized);
|
|
43499
43339
|
} catch {}
|
|
43500
43340
|
if (exists) {
|
|
43501
43341
|
const copied = copyToStable(normalized);
|
|
@@ -43569,7 +43409,7 @@ var init_image_detect = __esm(() => {
|
|
|
43569
43409
|
".tif",
|
|
43570
43410
|
".tiff"
|
|
43571
43411
|
]);
|
|
43572
|
-
STABLE_IMAGE_DIR =
|
|
43412
|
+
STABLE_IMAGE_DIR = join18(tmpdir2(), "locus-images");
|
|
43573
43413
|
});
|
|
43574
43414
|
|
|
43575
43415
|
// src/repl/input-handler.ts
|
|
@@ -44112,7 +43952,7 @@ class InteractiveSession {
|
|
|
44112
43952
|
model: options.model
|
|
44113
43953
|
});
|
|
44114
43954
|
this.promptBuilder = new PromptBuilder(options.projectPath);
|
|
44115
|
-
this.renderer = new ProgressRenderer;
|
|
43955
|
+
this.renderer = new ProgressRenderer({ animated: true });
|
|
44116
43956
|
this.historyManager = new HistoryManager(options.projectPath);
|
|
44117
43957
|
this.projectPath = options.projectPath;
|
|
44118
43958
|
this.model = options.model;
|
|
@@ -44783,533 +44623,6 @@ async function configCommand(args) {
|
|
|
44783
44623
|
showConfigHelp();
|
|
44784
44624
|
}
|
|
44785
44625
|
}
|
|
44786
|
-
// src/commands/daemon.ts
|
|
44787
|
-
init_index_node();
|
|
44788
|
-
init_settings_manager();
|
|
44789
|
-
init_utils3();
|
|
44790
|
-
import { existsSync as existsSync19, mkdirSync as mkdirSync8, unlinkSync as unlinkSync6, writeFileSync as writeFileSync8 } from "node:fs";
|
|
44791
|
-
import { homedir as homedir3 } from "node:os";
|
|
44792
|
-
import { join as join19 } from "node:path";
|
|
44793
|
-
|
|
44794
|
-
// src/utils/process.ts
|
|
44795
|
-
import { spawn as spawn4 } from "node:child_process";
|
|
44796
|
-
import { existsSync as existsSync18, readdirSync as readdirSync6, readFileSync as readFileSync15 } from "node:fs";
|
|
44797
|
-
import { homedir as homedir2 } from "node:os";
|
|
44798
|
-
import { dirname as dirname4, join as join18 } from "node:path";
|
|
44799
|
-
function runShell(cmd, args) {
|
|
44800
|
-
return new Promise((resolve2) => {
|
|
44801
|
-
const proc = spawn4(cmd, args, { stdio: ["pipe", "pipe", "pipe"] });
|
|
44802
|
-
let stdout = "";
|
|
44803
|
-
let stderr = "";
|
|
44804
|
-
proc.stdout?.on("data", (d) => {
|
|
44805
|
-
stdout += d.toString();
|
|
44806
|
-
});
|
|
44807
|
-
proc.stderr?.on("data", (d) => {
|
|
44808
|
-
stderr += d.toString();
|
|
44809
|
-
});
|
|
44810
|
-
proc.on("close", (exitCode) => resolve2({ exitCode, stdout, stderr }));
|
|
44811
|
-
proc.on("error", (err) => resolve2({ exitCode: 1, stdout, stderr: err.message }));
|
|
44812
|
-
});
|
|
44813
|
-
}
|
|
44814
|
-
async function findTelegramBinary() {
|
|
44815
|
-
const result = await runShell("which", ["locus-telegram"]);
|
|
44816
|
-
const p = result.stdout.trim();
|
|
44817
|
-
return p?.startsWith?.("/") ? p : null;
|
|
44818
|
-
}
|
|
44819
|
-
async function findBinDir(binary) {
|
|
44820
|
-
const result = await runShell("which", [binary]);
|
|
44821
|
-
const p = result.stdout.trim();
|
|
44822
|
-
if (p?.startsWith?.("/"))
|
|
44823
|
-
return dirname4(p);
|
|
44824
|
-
return null;
|
|
44825
|
-
}
|
|
44826
|
-
function resolveNvmBinDir() {
|
|
44827
|
-
const nvmDir = process.env.NVM_DIR || join18(homedir2(), ".nvm");
|
|
44828
|
-
const versionsDir = join18(nvmDir, "versions", "node");
|
|
44829
|
-
if (!existsSync18(versionsDir))
|
|
44830
|
-
return null;
|
|
44831
|
-
let versions2;
|
|
44832
|
-
try {
|
|
44833
|
-
versions2 = readdirSync6(versionsDir).filter((d) => d.startsWith("v"));
|
|
44834
|
-
} catch {
|
|
44835
|
-
return null;
|
|
44836
|
-
}
|
|
44837
|
-
if (versions2.length === 0)
|
|
44838
|
-
return null;
|
|
44839
|
-
const currentNodeVersion = `v${process.versions.node}`;
|
|
44840
|
-
const currentBin = join18(versionsDir, currentNodeVersion, "bin");
|
|
44841
|
-
if (versions2.includes(currentNodeVersion) && existsSync18(currentBin)) {
|
|
44842
|
-
return currentBin;
|
|
44843
|
-
}
|
|
44844
|
-
const aliasPath = join18(nvmDir, "alias", "default");
|
|
44845
|
-
if (existsSync18(aliasPath)) {
|
|
44846
|
-
try {
|
|
44847
|
-
const alias = readFileSync15(aliasPath, "utf-8").trim();
|
|
44848
|
-
const match = versions2.find((v) => v === `v${alias}` || v.startsWith(`v${alias}.`));
|
|
44849
|
-
if (match) {
|
|
44850
|
-
const bin2 = join18(versionsDir, match, "bin");
|
|
44851
|
-
if (existsSync18(bin2))
|
|
44852
|
-
return bin2;
|
|
44853
|
-
}
|
|
44854
|
-
} catch {}
|
|
44855
|
-
}
|
|
44856
|
-
const sorted = versions2.sort((a, b) => {
|
|
44857
|
-
const pa = a.slice(1).split(".").map(Number);
|
|
44858
|
-
const pb = b.slice(1).split(".").map(Number);
|
|
44859
|
-
for (let i = 0;i < 3; i++) {
|
|
44860
|
-
if ((pa[i] || 0) !== (pb[i] || 0))
|
|
44861
|
-
return (pb[i] || 0) - (pa[i] || 0);
|
|
44862
|
-
}
|
|
44863
|
-
return 0;
|
|
44864
|
-
});
|
|
44865
|
-
const bin = join18(versionsDir, sorted[0], "bin");
|
|
44866
|
-
return existsSync18(bin) ? bin : null;
|
|
44867
|
-
}
|
|
44868
|
-
async function buildServicePath() {
|
|
44869
|
-
const home = homedir2();
|
|
44870
|
-
const dirs = new Set;
|
|
44871
|
-
dirs.add("/usr/local/bin");
|
|
44872
|
-
dirs.add("/usr/bin");
|
|
44873
|
-
dirs.add("/bin");
|
|
44874
|
-
const candidates = [
|
|
44875
|
-
join18(home, ".bun", "bin"),
|
|
44876
|
-
join18(home, ".local", "bin"),
|
|
44877
|
-
join18(home, ".npm", "bin"),
|
|
44878
|
-
join18(home, ".npm-global", "bin"),
|
|
44879
|
-
join18(home, ".yarn", "bin")
|
|
44880
|
-
];
|
|
44881
|
-
for (const d of candidates) {
|
|
44882
|
-
if (existsSync18(d))
|
|
44883
|
-
dirs.add(d);
|
|
44884
|
-
}
|
|
44885
|
-
const nvmBin = resolveNvmBinDir();
|
|
44886
|
-
if (nvmBin)
|
|
44887
|
-
dirs.add(nvmBin);
|
|
44888
|
-
const fnmCurrent = join18(home, ".fnm", "current", "bin");
|
|
44889
|
-
if (existsSync18(fnmCurrent))
|
|
44890
|
-
dirs.add(fnmCurrent);
|
|
44891
|
-
for (const bin of ["claude", "codex"]) {
|
|
44892
|
-
const dir = await findBinDir(bin);
|
|
44893
|
-
if (dir)
|
|
44894
|
-
dirs.add(dir);
|
|
44895
|
-
}
|
|
44896
|
-
return Array.from(dirs).join(":");
|
|
44897
|
-
}
|
|
44898
|
-
var SERVICE_NAME = "locus";
|
|
44899
|
-
var SYSTEMD_UNIT_PATH = `/etc/systemd/system/${SERVICE_NAME}.service`;
|
|
44900
|
-
var PLIST_LABEL = "com.locus.agent";
|
|
44901
|
-
function getPlistPath() {
|
|
44902
|
-
return join18(homedir2(), "Library/LaunchAgents", `${PLIST_LABEL}.plist`);
|
|
44903
|
-
}
|
|
44904
|
-
function getPlatform() {
|
|
44905
|
-
if (process.platform === "linux")
|
|
44906
|
-
return "linux";
|
|
44907
|
-
if (process.platform === "darwin")
|
|
44908
|
-
return "darwin";
|
|
44909
|
-
return null;
|
|
44910
|
-
}
|
|
44911
|
-
async function killOrphanedProcesses() {
|
|
44912
|
-
const result = await runShell("pgrep", ["-f", "locus-telegram"]);
|
|
44913
|
-
const pids = result.stdout.trim().split(`
|
|
44914
|
-
`).filter((p) => p.length > 0);
|
|
44915
|
-
if (pids.length === 0)
|
|
44916
|
-
return;
|
|
44917
|
-
console.log(` Killing ${pids.length} orphaned locus-telegram process${pids.length > 1 ? "es" : ""}...`);
|
|
44918
|
-
await runShell("pkill", ["-f", "locus-telegram"]);
|
|
44919
|
-
await new Promise((resolve2) => setTimeout(resolve2, 2000));
|
|
44920
|
-
const check2 = await runShell("pgrep", ["-f", "locus-telegram"]);
|
|
44921
|
-
if (check2.stdout.trim().length > 0) {
|
|
44922
|
-
await runShell("pkill", ["-9", "-f", "locus-telegram"]);
|
|
44923
|
-
}
|
|
44924
|
-
}
|
|
44925
|
-
async function isDaemonRunning() {
|
|
44926
|
-
const platform = getPlatform();
|
|
44927
|
-
if (platform === "linux") {
|
|
44928
|
-
const result = await runShell("systemctl", ["is-active", SERVICE_NAME]);
|
|
44929
|
-
return result.stdout.trim() === "active";
|
|
44930
|
-
}
|
|
44931
|
-
if (platform === "darwin") {
|
|
44932
|
-
const plistPath = getPlistPath();
|
|
44933
|
-
if (!existsSync18(plistPath))
|
|
44934
|
-
return false;
|
|
44935
|
-
const result = await runShell("launchctl", ["list"]);
|
|
44936
|
-
const match = result.stdout.split(`
|
|
44937
|
-
`).find((l) => l.includes(PLIST_LABEL));
|
|
44938
|
-
if (!match)
|
|
44939
|
-
return false;
|
|
44940
|
-
const pid = match.trim().split(/\s+/)[0];
|
|
44941
|
-
return pid !== "-";
|
|
44942
|
-
}
|
|
44943
|
-
return false;
|
|
44944
|
-
}
|
|
44945
|
-
async function restartDaemonIfRunning() {
|
|
44946
|
-
const platform = getPlatform();
|
|
44947
|
-
if (!platform)
|
|
44948
|
-
return false;
|
|
44949
|
-
const running = await isDaemonRunning();
|
|
44950
|
-
if (!running)
|
|
44951
|
-
return false;
|
|
44952
|
-
if (platform === "linux") {
|
|
44953
|
-
const result = await runShell("systemctl", ["restart", SERVICE_NAME]);
|
|
44954
|
-
return result.exitCode === 0;
|
|
44955
|
-
}
|
|
44956
|
-
if (platform === "darwin") {
|
|
44957
|
-
const plistPath = getPlistPath();
|
|
44958
|
-
await runShell("launchctl", ["unload", plistPath]);
|
|
44959
|
-
const result = await runShell("launchctl", ["load", plistPath]);
|
|
44960
|
-
return result.exitCode === 0;
|
|
44961
|
-
}
|
|
44962
|
-
return false;
|
|
44963
|
-
}
|
|
44964
|
-
|
|
44965
|
-
// src/commands/daemon.ts
|
|
44966
|
-
function showDaemonHelp() {
|
|
44967
|
-
console.log(`
|
|
44968
|
-
${c.header(" DAEMON ")}
|
|
44969
|
-
${c.primary("locus daemon")} ${c.dim("<subcommand>")}
|
|
44970
|
-
|
|
44971
|
-
${c.header(" SUBCOMMANDS ")}
|
|
44972
|
-
${c.success("start")} Install and start Locus as a background service
|
|
44973
|
-
${c.dim("Sets up systemd (Linux) or launchd (macOS)")}
|
|
44974
|
-
${c.success("stop")} Stop and remove the background service
|
|
44975
|
-
${c.success("restart")} Restart the background service
|
|
44976
|
-
${c.success("status")} Check if the service is running
|
|
44977
|
-
|
|
44978
|
-
${c.header(" EXAMPLES ")}
|
|
44979
|
-
${c.dim("$")} ${c.primary("locus daemon start")}
|
|
44980
|
-
${c.dim("$")} ${c.primary("locus daemon status")}
|
|
44981
|
-
${c.dim("$")} ${c.primary("locus daemon restart")}
|
|
44982
|
-
${c.dim("$")} ${c.primary("locus daemon stop")}
|
|
44983
|
-
`);
|
|
44984
|
-
}
|
|
44985
|
-
async function resolveBinaries() {
|
|
44986
|
-
const binaryPath = await findTelegramBinary();
|
|
44987
|
-
if (!binaryPath) {
|
|
44988
|
-
console.error(`
|
|
44989
|
-
${c.error("✖")} ${c.bold("Could not find locus-telegram binary.")}
|
|
44990
|
-
` + ` Install with: ${c.primary("npm install -g @locusai/telegram")}
|
|
44991
|
-
`);
|
|
44992
|
-
process.exit(1);
|
|
44993
|
-
}
|
|
44994
|
-
for (const bin of ["claude", "codex"]) {
|
|
44995
|
-
if (!await findBinDir(bin)) {
|
|
44996
|
-
console.warn(`
|
|
44997
|
-
${c.secondary("⚠")} ${c.bold(`Could not find '${bin}' CLI in PATH.`)}
|
|
44998
|
-
` + ` The service may need it to execute tasks.
|
|
44999
|
-
`);
|
|
45000
|
-
}
|
|
45001
|
-
}
|
|
45002
|
-
const servicePath = await buildServicePath();
|
|
45003
|
-
return { binaryPath, servicePath };
|
|
45004
|
-
}
|
|
45005
|
-
function requirePlatform() {
|
|
45006
|
-
const platform = getPlatform();
|
|
45007
|
-
if (!platform) {
|
|
45008
|
-
console.error(`
|
|
45009
|
-
${c.error("✖")} ${c.bold(`Unsupported platform: ${process.platform}`)}
|
|
45010
|
-
` + ` Daemon management is supported on Linux (systemd) and macOS (launchd).
|
|
45011
|
-
`);
|
|
45012
|
-
process.exit(1);
|
|
45013
|
-
}
|
|
45014
|
-
return platform;
|
|
45015
|
-
}
|
|
45016
|
-
function validateConfig(projectPath) {
|
|
45017
|
-
const manager = new SettingsManager(projectPath);
|
|
45018
|
-
const settings = manager.load();
|
|
45019
|
-
if (!settings.telegram?.botToken || !settings.telegram?.chatId) {
|
|
45020
|
-
console.error(`
|
|
45021
|
-
${c.error("✖")} ${c.bold("Telegram is not configured.")}
|
|
45022
|
-
` + ` Run ${c.primary("locus telegram setup")} first.
|
|
45023
|
-
`);
|
|
45024
|
-
process.exit(1);
|
|
45025
|
-
}
|
|
45026
|
-
if (!settings.apiKey) {
|
|
45027
|
-
console.error(`
|
|
45028
|
-
${c.error("✖")} ${c.bold("API key is not configured.")}
|
|
45029
|
-
` + ` Run ${c.primary("locus config setup --api-key <key>")} first.
|
|
45030
|
-
`);
|
|
45031
|
-
process.exit(1);
|
|
45032
|
-
}
|
|
45033
|
-
}
|
|
45034
|
-
function generateSystemdUnit(projectPath, user2, bins) {
|
|
45035
|
-
return `[Unit]
|
|
45036
|
-
Description=Locus AI Agent (Telegram bot + proposal scheduler)
|
|
45037
|
-
After=network-online.target
|
|
45038
|
-
Wants=network-online.target
|
|
45039
|
-
|
|
45040
|
-
[Service]
|
|
45041
|
-
Type=simple
|
|
45042
|
-
User=${user2}
|
|
45043
|
-
WorkingDirectory=${projectPath}
|
|
45044
|
-
ExecStart=${bins.binaryPath}
|
|
45045
|
-
Restart=on-failure
|
|
45046
|
-
RestartSec=10
|
|
45047
|
-
Environment=PATH=${bins.servicePath}
|
|
45048
|
-
Environment=HOME=${homedir3()}
|
|
45049
|
-
|
|
45050
|
-
[Install]
|
|
45051
|
-
WantedBy=multi-user.target
|
|
45052
|
-
`;
|
|
45053
|
-
}
|
|
45054
|
-
async function startSystemd(projectPath, bins) {
|
|
45055
|
-
const user2 = process.env.USER || "root";
|
|
45056
|
-
const unit = generateSystemdUnit(projectPath, user2, bins);
|
|
45057
|
-
console.log(`
|
|
45058
|
-
${c.info("▶")} Writing systemd unit to ${c.dim(SYSTEMD_UNIT_PATH)}`);
|
|
45059
|
-
writeFileSync8(SYSTEMD_UNIT_PATH, unit, "utf-8");
|
|
45060
|
-
console.log(` ${c.info("▶")} Reloading systemd daemon...`);
|
|
45061
|
-
await runShell("systemctl", ["daemon-reload"]);
|
|
45062
|
-
console.log(` ${c.info("▶")} Enabling and starting ${SERVICE_NAME}...`);
|
|
45063
|
-
await runShell("systemctl", ["enable", SERVICE_NAME]);
|
|
45064
|
-
const result = await runShell("systemctl", ["start", SERVICE_NAME]);
|
|
45065
|
-
if (result.exitCode !== 0) {
|
|
45066
|
-
console.error(`
|
|
45067
|
-
${c.error("✖")} Failed to start service: ${result.stderr.trim()}`);
|
|
45068
|
-
console.error(` ${c.dim("Check logs with:")} ${c.primary(`journalctl -u ${SERVICE_NAME} -f`)}`);
|
|
45069
|
-
return;
|
|
45070
|
-
}
|
|
45071
|
-
console.log(`
|
|
45072
|
-
${c.success("✔")} ${c.bold("Locus daemon started!")}
|
|
45073
|
-
|
|
45074
|
-
${c.bold("Service:")} ${SERVICE_NAME}
|
|
45075
|
-
${c.bold("Unit file:")} ${SYSTEMD_UNIT_PATH}
|
|
45076
|
-
|
|
45077
|
-
${c.bold("Useful commands:")}
|
|
45078
|
-
${c.dim("$")} ${c.primary(`sudo systemctl status ${SERVICE_NAME}`)}
|
|
45079
|
-
${c.dim("$")} ${c.primary(`journalctl -u ${SERVICE_NAME} -f`)}
|
|
45080
|
-
`);
|
|
45081
|
-
}
|
|
45082
|
-
async function stopSystemd() {
|
|
45083
|
-
if (!existsSync19(SYSTEMD_UNIT_PATH)) {
|
|
45084
|
-
console.log(`
|
|
45085
|
-
${c.dim("No systemd service found. Nothing to stop.")}
|
|
45086
|
-
`);
|
|
45087
|
-
await killOrphanedProcesses();
|
|
45088
|
-
return;
|
|
45089
|
-
}
|
|
45090
|
-
console.log(` ${c.info("▶")} Stopping and disabling ${SERVICE_NAME}...`);
|
|
45091
|
-
await runShell("systemctl", ["stop", SERVICE_NAME]);
|
|
45092
|
-
await runShell("systemctl", ["disable", SERVICE_NAME]);
|
|
45093
|
-
unlinkSync6(SYSTEMD_UNIT_PATH);
|
|
45094
|
-
await runShell("systemctl", ["daemon-reload"]);
|
|
45095
|
-
await killOrphanedProcesses();
|
|
45096
|
-
console.log(`
|
|
45097
|
-
${c.success("✔")} ${c.bold("Locus daemon stopped.")}
|
|
45098
|
-
`);
|
|
45099
|
-
}
|
|
45100
|
-
async function restartSystemd() {
|
|
45101
|
-
if (!existsSync19(SYSTEMD_UNIT_PATH)) {
|
|
45102
|
-
console.log(`
|
|
45103
|
-
${c.dim("No systemd service found. Use")} ${c.primary("locus daemon start")} ${c.dim("first.")}
|
|
45104
|
-
`);
|
|
45105
|
-
return;
|
|
45106
|
-
}
|
|
45107
|
-
console.log(` ${c.info("▶")} Restarting ${SERVICE_NAME}...`);
|
|
45108
|
-
const result = await runShell("systemctl", ["restart", SERVICE_NAME]);
|
|
45109
|
-
if (result.exitCode !== 0) {
|
|
45110
|
-
console.error(`
|
|
45111
|
-
${c.error("✖")} Failed to restart: ${result.stderr.trim()}
|
|
45112
|
-
`);
|
|
45113
|
-
return;
|
|
45114
|
-
}
|
|
45115
|
-
console.log(`
|
|
45116
|
-
${c.success("✔")} ${c.bold("Locus daemon restarted.")}
|
|
45117
|
-
`);
|
|
45118
|
-
}
|
|
45119
|
-
async function statusSystemd() {
|
|
45120
|
-
const result = await runShell("systemctl", ["is-active", SERVICE_NAME]);
|
|
45121
|
-
const state = result.stdout.trim();
|
|
45122
|
-
if (state === "active") {
|
|
45123
|
-
console.log(`
|
|
45124
|
-
${c.success("●")} ${c.bold("Locus daemon is running")} ${c.dim("(systemd)")}
|
|
45125
|
-
`);
|
|
45126
|
-
} else if (existsSync19(SYSTEMD_UNIT_PATH)) {
|
|
45127
|
-
console.log(`
|
|
45128
|
-
${c.secondary("●")} ${c.bold(`Locus daemon is ${state}`)} ${c.dim("(systemd)")}
|
|
45129
|
-
`);
|
|
45130
|
-
console.log(` ${c.dim("Start with:")} ${c.primary("locus daemon start")}
|
|
45131
|
-
`);
|
|
45132
|
-
} else {
|
|
45133
|
-
console.log(`
|
|
45134
|
-
${c.secondary("●")} ${c.bold("Locus daemon is not installed")}
|
|
45135
|
-
`);
|
|
45136
|
-
console.log(` ${c.dim("Start with:")} ${c.primary("locus daemon start")}
|
|
45137
|
-
`);
|
|
45138
|
-
}
|
|
45139
|
-
}
|
|
45140
|
-
function generatePlist(projectPath, bins) {
|
|
45141
|
-
const logDir = join19(homedir3(), "Library/Logs/Locus");
|
|
45142
|
-
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
45143
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
45144
|
-
<plist version="1.0">
|
|
45145
|
-
<dict>
|
|
45146
|
-
<key>Label</key>
|
|
45147
|
-
<string>${PLIST_LABEL}</string>
|
|
45148
|
-
<key>ProgramArguments</key>
|
|
45149
|
-
<array>
|
|
45150
|
-
<string>${bins.binaryPath}</string>
|
|
45151
|
-
</array>
|
|
45152
|
-
<key>WorkingDirectory</key>
|
|
45153
|
-
<string>${projectPath}</string>
|
|
45154
|
-
<key>RunAtLoad</key>
|
|
45155
|
-
<true/>
|
|
45156
|
-
<key>KeepAlive</key>
|
|
45157
|
-
<true/>
|
|
45158
|
-
<key>StandardOutPath</key>
|
|
45159
|
-
<string>${join19(logDir, "locus.log")}</string>
|
|
45160
|
-
<key>StandardErrorPath</key>
|
|
45161
|
-
<string>${join19(logDir, "locus-error.log")}</string>
|
|
45162
|
-
<key>EnvironmentVariables</key>
|
|
45163
|
-
<dict>
|
|
45164
|
-
<key>PATH</key>
|
|
45165
|
-
<string>${bins.servicePath}</string>
|
|
45166
|
-
</dict>
|
|
45167
|
-
</dict>
|
|
45168
|
-
</plist>
|
|
45169
|
-
`;
|
|
45170
|
-
}
|
|
45171
|
-
async function startLaunchd(projectPath, bins) {
|
|
45172
|
-
const plistPath = getPlistPath();
|
|
45173
|
-
if (existsSync19(plistPath)) {
|
|
45174
|
-
await runShell("launchctl", ["unload", plistPath]);
|
|
45175
|
-
}
|
|
45176
|
-
const logDir = join19(homedir3(), "Library/Logs/Locus");
|
|
45177
|
-
mkdirSync8(logDir, { recursive: true });
|
|
45178
|
-
mkdirSync8(join19(homedir3(), "Library/LaunchAgents"), { recursive: true });
|
|
45179
|
-
const plist = generatePlist(projectPath, bins);
|
|
45180
|
-
console.log(`
|
|
45181
|
-
${c.info("▶")} Writing plist to ${c.dim(plistPath)}`);
|
|
45182
|
-
writeFileSync8(plistPath, plist, "utf-8");
|
|
45183
|
-
console.log(` ${c.info("▶")} Loading service...`);
|
|
45184
|
-
const result = await runShell("launchctl", ["load", plistPath]);
|
|
45185
|
-
if (result.exitCode !== 0) {
|
|
45186
|
-
console.error(`
|
|
45187
|
-
${c.error("✖")} Failed to load service: ${result.stderr.trim()}`);
|
|
45188
|
-
return;
|
|
45189
|
-
}
|
|
45190
|
-
const logPath = join19(logDir, "locus.log");
|
|
45191
|
-
console.log(`
|
|
45192
|
-
${c.success("✔")} ${c.bold("Locus daemon started!")}
|
|
45193
|
-
|
|
45194
|
-
${c.bold("Plist:")} ${plistPath}
|
|
45195
|
-
${c.bold("Logs:")} ${logPath}
|
|
45196
|
-
|
|
45197
|
-
${c.bold("Useful commands:")}
|
|
45198
|
-
${c.dim("$")} ${c.primary(`launchctl list | grep ${PLIST_LABEL}`)}
|
|
45199
|
-
${c.dim("$")} ${c.primary(`tail -f ${logPath}`)}
|
|
45200
|
-
`);
|
|
45201
|
-
}
|
|
45202
|
-
async function stopLaunchd() {
|
|
45203
|
-
const plistPath = getPlistPath();
|
|
45204
|
-
if (!existsSync19(plistPath)) {
|
|
45205
|
-
console.log(`
|
|
45206
|
-
${c.dim("No launchd service found. Nothing to stop.")}
|
|
45207
|
-
`);
|
|
45208
|
-
await killOrphanedProcesses();
|
|
45209
|
-
return;
|
|
45210
|
-
}
|
|
45211
|
-
console.log(` ${c.info("▶")} Unloading service...`);
|
|
45212
|
-
await runShell("launchctl", ["unload", plistPath]);
|
|
45213
|
-
unlinkSync6(plistPath);
|
|
45214
|
-
await killOrphanedProcesses();
|
|
45215
|
-
console.log(`
|
|
45216
|
-
${c.success("✔")} ${c.bold("Locus daemon stopped.")}
|
|
45217
|
-
`);
|
|
45218
|
-
}
|
|
45219
|
-
async function restartLaunchd() {
|
|
45220
|
-
const plistPath = getPlistPath();
|
|
45221
|
-
if (!existsSync19(plistPath)) {
|
|
45222
|
-
console.log(`
|
|
45223
|
-
${c.dim("No launchd service found. Use")} ${c.primary("locus daemon start")} ${c.dim("first.")}
|
|
45224
|
-
`);
|
|
45225
|
-
return;
|
|
45226
|
-
}
|
|
45227
|
-
console.log(` ${c.info("▶")} Restarting service...`);
|
|
45228
|
-
await runShell("launchctl", ["unload", plistPath]);
|
|
45229
|
-
const result = await runShell("launchctl", ["load", plistPath]);
|
|
45230
|
-
if (result.exitCode !== 0) {
|
|
45231
|
-
console.error(`
|
|
45232
|
-
${c.error("✖")} Failed to restart: ${result.stderr.trim()}
|
|
45233
|
-
`);
|
|
45234
|
-
return;
|
|
45235
|
-
}
|
|
45236
|
-
console.log(`
|
|
45237
|
-
${c.success("✔")} ${c.bold("Locus daemon restarted.")}
|
|
45238
|
-
`);
|
|
45239
|
-
}
|
|
45240
|
-
async function statusLaunchd() {
|
|
45241
|
-
const plistPath = getPlistPath();
|
|
45242
|
-
if (!existsSync19(plistPath)) {
|
|
45243
|
-
console.log(`
|
|
45244
|
-
${c.secondary("●")} ${c.bold("Locus daemon is not installed")}
|
|
45245
|
-
`);
|
|
45246
|
-
console.log(` ${c.dim("Start with:")} ${c.primary("locus daemon start")}
|
|
45247
|
-
`);
|
|
45248
|
-
return;
|
|
45249
|
-
}
|
|
45250
|
-
const result = await runShell("launchctl", ["list"]);
|
|
45251
|
-
const match = result.stdout.split(`
|
|
45252
|
-
`).find((l) => l.includes(PLIST_LABEL));
|
|
45253
|
-
if (match) {
|
|
45254
|
-
const parts = match.trim().split(/\s+/);
|
|
45255
|
-
const pid = parts[0] === "-" ? null : parts[0];
|
|
45256
|
-
if (pid) {
|
|
45257
|
-
console.log(`
|
|
45258
|
-
${c.success("●")} ${c.bold("Locus daemon is running")} ${c.dim(`(PID ${pid}, launchd)`)}
|
|
45259
|
-
`);
|
|
45260
|
-
} else {
|
|
45261
|
-
console.log(`
|
|
45262
|
-
${c.secondary("●")} ${c.bold("Locus daemon is stopped")} ${c.dim("(launchd)")}
|
|
45263
|
-
`);
|
|
45264
|
-
console.log(` ${c.dim("Start with:")} ${c.primary("locus daemon start")}
|
|
45265
|
-
`);
|
|
45266
|
-
}
|
|
45267
|
-
} else {
|
|
45268
|
-
console.log(`
|
|
45269
|
-
${c.secondary("●")} ${c.bold("Locus daemon is not loaded")} ${c.dim("(plist exists but not loaded)")}
|
|
45270
|
-
`);
|
|
45271
|
-
console.log(` ${c.dim("Start with:")} ${c.primary("locus daemon start")}
|
|
45272
|
-
`);
|
|
45273
|
-
}
|
|
45274
|
-
}
|
|
45275
|
-
async function daemonCommand(args) {
|
|
45276
|
-
const projectPath = process.cwd();
|
|
45277
|
-
requireInitialization(projectPath, "daemon");
|
|
45278
|
-
const subcommand = args[0];
|
|
45279
|
-
const platform = subcommand ? requirePlatform() : null;
|
|
45280
|
-
const isLinux = platform === "linux";
|
|
45281
|
-
switch (subcommand) {
|
|
45282
|
-
case "start": {
|
|
45283
|
-
validateConfig(projectPath);
|
|
45284
|
-
const bins = await resolveBinaries();
|
|
45285
|
-
if (isLinux)
|
|
45286
|
-
await startSystemd(projectPath, bins);
|
|
45287
|
-
else
|
|
45288
|
-
await startLaunchd(projectPath, bins);
|
|
45289
|
-
break;
|
|
45290
|
-
}
|
|
45291
|
-
case "stop":
|
|
45292
|
-
if (isLinux)
|
|
45293
|
-
await stopSystemd();
|
|
45294
|
-
else
|
|
45295
|
-
await stopLaunchd();
|
|
45296
|
-
break;
|
|
45297
|
-
case "restart":
|
|
45298
|
-
if (isLinux)
|
|
45299
|
-
await restartSystemd();
|
|
45300
|
-
else
|
|
45301
|
-
await restartLaunchd();
|
|
45302
|
-
break;
|
|
45303
|
-
case "status":
|
|
45304
|
-
if (isLinux)
|
|
45305
|
-
await statusSystemd();
|
|
45306
|
-
else
|
|
45307
|
-
await statusLaunchd();
|
|
45308
|
-
break;
|
|
45309
|
-
default:
|
|
45310
|
-
showDaemonHelp();
|
|
45311
|
-
}
|
|
45312
|
-
}
|
|
45313
44626
|
// src/commands/discuss.ts
|
|
45314
44627
|
init_index_node();
|
|
45315
44628
|
init_progress_renderer();
|
|
@@ -45381,7 +44694,7 @@ async function discussCommand(args) {
|
|
|
45381
44694
|
console.log(` ${c.dim("Topic:")} ${c.bold(topic)}`);
|
|
45382
44695
|
console.log(` ${c.dim("Model:")} ${c.dim(`${model} (${provider})`)}
|
|
45383
44696
|
`);
|
|
45384
|
-
const renderer = new ProgressRenderer;
|
|
44697
|
+
const renderer = new ProgressRenderer({ animated: true });
|
|
45385
44698
|
let discussionId;
|
|
45386
44699
|
try {
|
|
45387
44700
|
renderer.showThinkingStarted();
|
|
@@ -45445,7 +44758,7 @@ async function discussCommand(args) {
|
|
|
45445
44758
|
}
|
|
45446
44759
|
if (lowerInput === "summary") {
|
|
45447
44760
|
isProcessing = true;
|
|
45448
|
-
const summaryRenderer = new ProgressRenderer;
|
|
44761
|
+
const summaryRenderer = new ProgressRenderer({ animated: true });
|
|
45449
44762
|
try {
|
|
45450
44763
|
summaryRenderer.showThinkingStarted();
|
|
45451
44764
|
const summary = await facilitator.summarizeDiscussion(discussionId);
|
|
@@ -45489,7 +44802,7 @@ async function discussCommand(args) {
|
|
|
45489
44802
|
const cleanedInput = stripImagePaths(trimmed, images);
|
|
45490
44803
|
const effectiveInput = cleanedInput + buildImageContext(images);
|
|
45491
44804
|
isProcessing = true;
|
|
45492
|
-
const chunkRenderer = new ProgressRenderer;
|
|
44805
|
+
const chunkRenderer = new ProgressRenderer({ animated: true });
|
|
45493
44806
|
try {
|
|
45494
44807
|
chunkRenderer.showThinkingStarted();
|
|
45495
44808
|
const stream4 = facilitator.continueDiscussionStream(discussionId, effectiveInput);
|
|
@@ -46358,17 +45671,11 @@ function showHelp2() {
|
|
|
46358
45671
|
${c.dim("sync Sync docs from API to .locus/documents")}
|
|
46359
45672
|
${c.success("review")} Review open Locus PRs on GitHub with AI
|
|
46360
45673
|
${c.dim("local Review staged changes locally (no GitHub)")}
|
|
46361
|
-
${c.success("telegram")}
|
|
46362
|
-
${c.dim("start Start the Telegram bot")}
|
|
45674
|
+
${c.success("telegram")} Configure the Telegram bot
|
|
46363
45675
|
${c.dim("setup Interactive bot token and chat ID setup")}
|
|
46364
45676
|
${c.dim("config Show current configuration")}
|
|
46365
45677
|
${c.dim("set <k> <v> Update a config value")}
|
|
46366
45678
|
${c.dim("remove Remove Telegram configuration")}
|
|
46367
|
-
${c.success("daemon")} Manage the Locus background service
|
|
46368
|
-
${c.dim("start Install and start the daemon")}
|
|
46369
|
-
${c.dim("stop Stop and remove the daemon")}
|
|
46370
|
-
${c.dim("restart Restart the daemon")}
|
|
46371
|
-
${c.dim("status Check if the daemon is running")}
|
|
46372
45679
|
${c.success("exec")} Run a prompt with repository context
|
|
46373
45680
|
${c.dim("--interactive, -i Start interactive REPL mode")}
|
|
46374
45681
|
${c.dim("--session, -s <id> Resume a previous session")}
|
|
@@ -46391,19 +45698,17 @@ function showHelp2() {
|
|
|
46391
45698
|
${c.header(" GETTING STARTED ")}
|
|
46392
45699
|
${c.dim("$")} ${c.primary("locus init")}
|
|
46393
45700
|
${c.dim("$")} ${c.primary("locus config setup")}
|
|
46394
|
-
${c.dim("$")} ${c.primary("locus
|
|
46395
|
-
${c.dim("$")} ${c.primary("locus daemon start")}
|
|
45701
|
+
${c.dim("$")} ${c.primary("locus run")}
|
|
46396
45702
|
|
|
46397
45703
|
${c.header(" EXAMPLES ")}
|
|
46398
45704
|
${c.dim("$")} ${c.primary("locus run")}
|
|
46399
45705
|
${c.dim("$")} ${c.primary("locus docs sync")}
|
|
46400
45706
|
${c.dim("$")} ${c.primary("locus review")}
|
|
46401
45707
|
${c.dim("$")} ${c.primary("locus review local")}
|
|
46402
|
-
${c.dim("$")} ${c.primary("locus telegram
|
|
45708
|
+
${c.dim("$")} ${c.primary("locus telegram setup")}
|
|
46403
45709
|
${c.dim("$")} ${c.primary('locus discuss "how should we design the auth system?"')}
|
|
46404
45710
|
${c.dim("$")} ${c.primary("locus exec sessions list")}
|
|
46405
45711
|
${c.dim("$")} ${c.primary("locus artifacts")}
|
|
46406
|
-
${c.dim("$")} ${c.primary("locus daemon start")}
|
|
46407
45712
|
|
|
46408
45713
|
For more information, visit: ${c.underline("https://docs.locusai.dev")}
|
|
46409
45714
|
`);
|
|
@@ -46548,8 +45853,8 @@ init_config_manager();
|
|
|
46548
45853
|
init_settings_manager();
|
|
46549
45854
|
init_utils3();
|
|
46550
45855
|
init_workspace_resolver();
|
|
46551
|
-
import { existsSync as
|
|
46552
|
-
import { join as
|
|
45856
|
+
import { existsSync as existsSync19, mkdirSync as mkdirSync9, writeFileSync as writeFileSync8 } from "node:fs";
|
|
45857
|
+
import { join as join19 } from "node:path";
|
|
46553
45858
|
import { parseArgs as parseArgs7 } from "node:util";
|
|
46554
45859
|
async function reviewCommand(args) {
|
|
46555
45860
|
const subcommand = args[0];
|
|
@@ -46688,13 +45993,13 @@ async function reviewLocalCommand(args) {
|
|
|
46688
45993
|
`);
|
|
46689
45994
|
return;
|
|
46690
45995
|
}
|
|
46691
|
-
const reviewsDir =
|
|
46692
|
-
if (!
|
|
46693
|
-
|
|
45996
|
+
const reviewsDir = join19(projectPath, LOCUS_CONFIG.dir, LOCUS_CONFIG.reviewsDir);
|
|
45997
|
+
if (!existsSync19(reviewsDir)) {
|
|
45998
|
+
mkdirSync9(reviewsDir, { recursive: true });
|
|
46694
45999
|
}
|
|
46695
46000
|
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
46696
|
-
const reportPath =
|
|
46697
|
-
|
|
46001
|
+
const reportPath = join19(reviewsDir, `review-${timestamp}.md`);
|
|
46002
|
+
writeFileSync8(reportPath, report, "utf-8");
|
|
46698
46003
|
console.log(`
|
|
46699
46004
|
${c.success("✔")} ${c.success("Review complete!")}`);
|
|
46700
46005
|
console.log(` ${c.dim("Report saved to:")} ${c.primary(reportPath)}
|
|
@@ -46787,30 +46092,12 @@ ${c.info(`Received ${signal}. Stopping agent and cleaning up...`)}`);
|
|
|
46787
46092
|
console.log(` ${c.dim("A PR will be opened when all tasks are done")}`);
|
|
46788
46093
|
await orchestrator.start();
|
|
46789
46094
|
}
|
|
46790
|
-
// src/commands/service.ts
|
|
46791
|
-
init_index_node();
|
|
46792
|
-
async function serviceCommand(args) {
|
|
46793
|
-
const subcommand = args[0];
|
|
46794
|
-
const mapping = {
|
|
46795
|
-
install: "start",
|
|
46796
|
-
uninstall: "stop",
|
|
46797
|
-
status: "status"
|
|
46798
|
-
};
|
|
46799
|
-
const mapped = subcommand ? mapping[subcommand] : undefined;
|
|
46800
|
-
if (mapped) {
|
|
46801
|
-
console.log(` ${c.dim(`Hint: 'locus service ${subcommand}' is now 'locus daemon ${mapped}'`)}
|
|
46802
|
-
`);
|
|
46803
|
-
await daemonCommand([mapped, ...args.slice(1)]);
|
|
46804
|
-
} else {
|
|
46805
|
-
await daemonCommand(args);
|
|
46806
|
-
}
|
|
46807
|
-
}
|
|
46808
46095
|
// src/commands/telegram.ts
|
|
46809
46096
|
init_index_node();
|
|
46810
46097
|
init_settings_manager();
|
|
46811
|
-
import { spawn as
|
|
46812
|
-
import { existsSync as
|
|
46813
|
-
import { join as
|
|
46098
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
46099
|
+
import { existsSync as existsSync20 } from "node:fs";
|
|
46100
|
+
import { join as join20 } from "node:path";
|
|
46814
46101
|
import { createInterface as createInterface2 } from "node:readline";
|
|
46815
46102
|
function ask2(question) {
|
|
46816
46103
|
const rl = createInterface2({
|
|
@@ -46836,7 +46123,7 @@ function showTelegramHelp() {
|
|
|
46836
46123
|
${c.primary("locus telegram")} ${c.dim("<subcommand> [options]")}
|
|
46837
46124
|
|
|
46838
46125
|
${c.header(" SUBCOMMANDS ")}
|
|
46839
|
-
${c.success("
|
|
46126
|
+
${c.success("run")} Start the Telegram bot
|
|
46840
46127
|
${c.success("setup")} Interactive Telegram bot setup (or pass flags below)
|
|
46841
46128
|
${c.success("config")} Show current Telegram configuration
|
|
46842
46129
|
${c.success("set")} Set a config value
|
|
@@ -46845,7 +46132,7 @@ function showTelegramHelp() {
|
|
|
46845
46132
|
${c.success("remove")} Remove Telegram configuration
|
|
46846
46133
|
|
|
46847
46134
|
${c.header(" EXAMPLES ")}
|
|
46848
|
-
${c.dim("$")} ${c.primary("locus telegram
|
|
46135
|
+
${c.dim("$")} ${c.primary("locus telegram run")}
|
|
46849
46136
|
${c.dim("$")} ${c.primary('locus telegram setup --token "123:ABC" --chat-id 987654')}
|
|
46850
46137
|
${c.dim("$")} ${c.primary("locus telegram config")}
|
|
46851
46138
|
${c.dim("$")} ${c.primary("locus telegram remove")}
|
|
@@ -46856,7 +46143,7 @@ function showTelegramHelp() {
|
|
|
46856
46143
|
${c.primary("locus config set <key> <value>")}
|
|
46857
46144
|
`);
|
|
46858
46145
|
}
|
|
46859
|
-
async function
|
|
46146
|
+
async function setupCommand2(args, projectPath) {
|
|
46860
46147
|
let token;
|
|
46861
46148
|
let chatId;
|
|
46862
46149
|
for (let i = 0;i < args.length; i++) {
|
|
@@ -46928,11 +46215,10 @@ async function setup(args, projectPath) {
|
|
|
46928
46215
|
${c.primary("Chat ID:")} ${parsedChatId}
|
|
46929
46216
|
|
|
46930
46217
|
${c.bold("Next steps:")}
|
|
46931
|
-
Start
|
|
46932
|
-
Or run manually: ${c.primary("locus telegram start")}
|
|
46218
|
+
Start the bot with: ${c.primary("locus telegram run")}
|
|
46933
46219
|
`);
|
|
46934
46220
|
}
|
|
46935
|
-
function
|
|
46221
|
+
function configCommand2(projectPath) {
|
|
46936
46222
|
const manager = new SettingsManager(projectPath);
|
|
46937
46223
|
const settings = manager.load();
|
|
46938
46224
|
const tg = settings.telegram;
|
|
@@ -46948,28 +46234,36 @@ function showConfig(projectPath) {
|
|
|
46948
46234
|
console.log(` ${c.dim("File: .locus/settings.json (telegram section)")}
|
|
46949
46235
|
`);
|
|
46950
46236
|
const entries = [];
|
|
46951
|
-
if (tg.botToken)
|
|
46237
|
+
if (tg.botToken) {
|
|
46952
46238
|
entries.push(["botToken", maskToken(tg.botToken)]);
|
|
46953
|
-
|
|
46239
|
+
}
|
|
46240
|
+
if (tg.chatId) {
|
|
46954
46241
|
entries.push(["chatId", String(tg.chatId)]);
|
|
46955
|
-
|
|
46242
|
+
}
|
|
46243
|
+
if (tg.testMode !== undefined) {
|
|
46956
46244
|
entries.push(["testMode", String(tg.testMode)]);
|
|
46957
|
-
|
|
46245
|
+
}
|
|
46246
|
+
if (settings.apiKey) {
|
|
46958
46247
|
entries.push(["apiKey (shared)", maskToken(settings.apiKey)]);
|
|
46959
|
-
|
|
46248
|
+
}
|
|
46249
|
+
if (settings.apiUrl) {
|
|
46960
46250
|
entries.push(["apiUrl (shared)", settings.apiUrl]);
|
|
46961
|
-
|
|
46251
|
+
}
|
|
46252
|
+
if (settings.provider) {
|
|
46962
46253
|
entries.push(["provider (shared)", settings.provider]);
|
|
46963
|
-
|
|
46254
|
+
}
|
|
46255
|
+
if (settings.model) {
|
|
46964
46256
|
entries.push(["model (shared)", settings.model]);
|
|
46965
|
-
|
|
46257
|
+
}
|
|
46258
|
+
if (settings.workspaceId) {
|
|
46966
46259
|
entries.push(["workspaceId (shared)", settings.workspaceId]);
|
|
46260
|
+
}
|
|
46967
46261
|
for (const [key, value] of entries) {
|
|
46968
46262
|
console.log(` ${c.primary(`${key}:`)} ${value}`);
|
|
46969
46263
|
}
|
|
46970
46264
|
console.log("");
|
|
46971
46265
|
}
|
|
46972
|
-
function
|
|
46266
|
+
function setCommand2(args, projectPath) {
|
|
46973
46267
|
const key = args[0]?.trim();
|
|
46974
46268
|
const value = args.slice(1).join(" ").trim();
|
|
46975
46269
|
if (!key || !value) {
|
|
@@ -47012,7 +46306,7 @@ function setValue(args, projectPath) {
|
|
|
47012
46306
|
${c.success("✔")} Set ${c.primary(key)} = ${displayValue}
|
|
47013
46307
|
`);
|
|
47014
46308
|
}
|
|
47015
|
-
function
|
|
46309
|
+
function removeCommand2(projectPath) {
|
|
47016
46310
|
const manager = new SettingsManager(projectPath);
|
|
47017
46311
|
const settings = manager.load();
|
|
47018
46312
|
if (!settings.telegram) {
|
|
@@ -47027,7 +46321,7 @@ function removeConfig(projectPath) {
|
|
|
47027
46321
|
${c.success("✔")} ${c.bold("Telegram configuration removed.")}
|
|
47028
46322
|
`);
|
|
47029
46323
|
}
|
|
47030
|
-
function
|
|
46324
|
+
function runBotCommand(projectPath) {
|
|
47031
46325
|
const manager = new SettingsManager(projectPath);
|
|
47032
46326
|
const settings = manager.load();
|
|
47033
46327
|
if (!settings.telegram?.botToken || !settings.telegram?.chatId) {
|
|
@@ -47037,14 +46331,22 @@ function startBot(projectPath) {
|
|
|
47037
46331
|
`);
|
|
47038
46332
|
process.exit(1);
|
|
47039
46333
|
}
|
|
47040
|
-
const
|
|
47041
|
-
const isMonorepo =
|
|
47042
|
-
|
|
47043
|
-
|
|
47044
|
-
|
|
46334
|
+
const monorepoTelegramEntry = join20(projectPath, "packages/telegram/src/index.ts");
|
|
46335
|
+
const isMonorepo = existsSync20(monorepoTelegramEntry);
|
|
46336
|
+
let cmd;
|
|
46337
|
+
let args;
|
|
46338
|
+
if (isMonorepo) {
|
|
46339
|
+
cmd = "bun";
|
|
46340
|
+
args = ["run", monorepoTelegramEntry];
|
|
46341
|
+
} else {
|
|
46342
|
+
cmd = "locus-telegram";
|
|
46343
|
+
args = [];
|
|
46344
|
+
}
|
|
46345
|
+
const env = { ...process.env };
|
|
46346
|
+
const child = spawn4(cmd, args, {
|
|
47045
46347
|
cwd: projectPath,
|
|
47046
46348
|
stdio: "inherit",
|
|
47047
|
-
env
|
|
46349
|
+
env
|
|
47048
46350
|
});
|
|
47049
46351
|
child.on("error", (err) => {
|
|
47050
46352
|
if (err.code === "ENOENT" && !isMonorepo) {
|
|
@@ -47065,23 +46367,22 @@ function startBot(projectPath) {
|
|
|
47065
46367
|
}
|
|
47066
46368
|
async function telegramCommand(args) {
|
|
47067
46369
|
const projectPath = process.cwd();
|
|
47068
|
-
const
|
|
46370
|
+
const subcommand = args[0];
|
|
47069
46371
|
switch (subcommand) {
|
|
47070
|
-
case "start":
|
|
47071
46372
|
case "run":
|
|
47072
|
-
|
|
46373
|
+
runBotCommand(projectPath);
|
|
47073
46374
|
break;
|
|
47074
46375
|
case "setup":
|
|
47075
|
-
await
|
|
46376
|
+
await setupCommand2(args, projectPath);
|
|
47076
46377
|
break;
|
|
47077
46378
|
case "config":
|
|
47078
|
-
|
|
46379
|
+
configCommand2(projectPath);
|
|
47079
46380
|
break;
|
|
47080
46381
|
case "set":
|
|
47081
|
-
|
|
46382
|
+
setCommand2(args, projectPath);
|
|
47082
46383
|
break;
|
|
47083
46384
|
case "remove":
|
|
47084
|
-
|
|
46385
|
+
removeCommand2(projectPath);
|
|
47085
46386
|
break;
|
|
47086
46387
|
default:
|
|
47087
46388
|
showTelegramHelp();
|
|
@@ -47117,7 +46418,6 @@ async function upgradeCommand() {
|
|
|
47117
46418
|
console.log(`
|
|
47118
46419
|
${c.header(" UPGRADE ")}
|
|
47119
46420
|
`);
|
|
47120
|
-
const daemonWasRunning = await isDaemonRunning();
|
|
47121
46421
|
try {
|
|
47122
46422
|
console.log(` ${c.dim("◌")} Cleaning npm cache...`);
|
|
47123
46423
|
execSync3("npm cache clean --force", {
|
|
@@ -47129,7 +46429,6 @@ async function upgradeCommand() {
|
|
|
47129
46429
|
console.log(` ${c.dim("⚠")} Could not clean npm cache, continuing...
|
|
47130
46430
|
`);
|
|
47131
46431
|
}
|
|
47132
|
-
let anyUpdated = false;
|
|
47133
46432
|
for (const pkg of PACKAGES) {
|
|
47134
46433
|
const current = getInstalledVersion(pkg);
|
|
47135
46434
|
const latest = getLatestVersion(pkg);
|
|
@@ -47152,27 +46451,12 @@ async function upgradeCommand() {
|
|
|
47152
46451
|
});
|
|
47153
46452
|
console.log(` ${c.success("✔")} ${c.bold(pkg)} updated to ${c.primary(`v${latest}`)}
|
|
47154
46453
|
`);
|
|
47155
|
-
anyUpdated = true;
|
|
47156
46454
|
} catch {
|
|
47157
46455
|
console.error(` ${c.error("✖")} Failed to update ${c.bold(pkg)}. Try manually:
|
|
47158
46456
|
` + ` ${c.primary(`npm install -g ${pkg}@latest`)}
|
|
47159
46457
|
`);
|
|
47160
46458
|
}
|
|
47161
46459
|
}
|
|
47162
|
-
if (daemonWasRunning && anyUpdated) {
|
|
47163
|
-
console.log(` ${c.info("▶")} Restarting locus daemon...`);
|
|
47164
|
-
const restarted = await restartDaemonIfRunning();
|
|
47165
|
-
if (restarted) {
|
|
47166
|
-
console.log(` ${c.success("✔")} Locus daemon restarted
|
|
47167
|
-
`);
|
|
47168
|
-
} else {
|
|
47169
|
-
console.log(` ${c.dim("⚠")} Could not restart daemon (may need sudo)
|
|
47170
|
-
`);
|
|
47171
|
-
}
|
|
47172
|
-
} else if (daemonWasRunning && !anyUpdated) {
|
|
47173
|
-
console.log(` ${c.dim("No updates — daemon left running")}
|
|
47174
|
-
`);
|
|
47175
|
-
}
|
|
47176
46460
|
console.log("");
|
|
47177
46461
|
}
|
|
47178
46462
|
// src/commands/version.ts
|
|
@@ -47244,12 +46528,6 @@ async function main() {
|
|
|
47244
46528
|
case "config":
|
|
47245
46529
|
await configCommand(args);
|
|
47246
46530
|
break;
|
|
47247
|
-
case "daemon":
|
|
47248
|
-
await daemonCommand(args);
|
|
47249
|
-
break;
|
|
47250
|
-
case "service":
|
|
47251
|
-
await serviceCommand(args);
|
|
47252
|
-
break;
|
|
47253
46531
|
case "docs":
|
|
47254
46532
|
await docsCommand(args);
|
|
47255
46533
|
break;
|
|
@@ -47278,11 +46556,3 @@ main().catch((err) => {
|
|
|
47278
46556
|
${c.error("✖ Fatal Error")} ${c.red(err.message)}`);
|
|
47279
46557
|
process.exit(1);
|
|
47280
46558
|
});
|
|
47281
|
-
|
|
47282
|
-
// index.ts
|
|
47283
|
-
var _emit = process.emit;
|
|
47284
|
-
process.emit = function(name, data, ...args) {
|
|
47285
|
-
if (name === "warning" && data?.code === "DEP0040")
|
|
47286
|
-
return false;
|
|
47287
|
-
return _emit.apply(process, [name, data, ...args]);
|
|
47288
|
-
};
|