lovecode-ai 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-3AHNSXQX.js +86 -0
- package/dist/{chunk-G7VQGYJW.js → chunk-7CT3XDH6.js} +5 -352
- package/dist/chunk-LJ7HTOIK.js +154 -0
- package/dist/chunk-Y3HADLWO.js +366 -0
- package/dist/config-FJNTTKR3.js +16 -0
- package/dist/env-HJQWWL6N.js +14 -0
- package/dist/{git-TBOGPTY4.js → git-FZPRJVFI.js} +2 -1
- package/dist/index.js +400 -537
- package/dist/registry-ADSIKXA4.js +22 -0
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
getTheme,
|
|
3
|
+
getThemeNames,
|
|
4
|
+
setTheme
|
|
5
|
+
} from "./chunk-FMT77EJQ.js";
|
|
6
|
+
import {
|
|
3
7
|
cleanupMergedBranches,
|
|
4
8
|
commit,
|
|
5
9
|
createBranch,
|
|
@@ -18,17 +22,20 @@ import {
|
|
|
18
22
|
getFullDiff,
|
|
19
23
|
getGitRoot,
|
|
20
24
|
getLog,
|
|
21
|
-
getProvider,
|
|
22
25
|
getStagedDiff,
|
|
23
26
|
getStatus,
|
|
24
27
|
isGitAvailable,
|
|
25
28
|
isRepo,
|
|
26
|
-
printProviders,
|
|
27
|
-
setDefaultModel,
|
|
28
29
|
stageAll,
|
|
29
30
|
suggestResolutions,
|
|
30
31
|
switchBranch
|
|
31
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-7CT3XDH6.js";
|
|
33
|
+
import {
|
|
34
|
+
OllamaProvider,
|
|
35
|
+
getProvider,
|
|
36
|
+
printProviders,
|
|
37
|
+
setDefaultModel
|
|
38
|
+
} from "./chunk-Y3HADLWO.js";
|
|
32
39
|
import "./chunk-LKUWOZUZ.js";
|
|
33
40
|
import {
|
|
34
41
|
click,
|
|
@@ -48,14 +55,22 @@ import {
|
|
|
48
55
|
loadBuiltinPlugins
|
|
49
56
|
} from "./chunk-MOZHR2QY.js";
|
|
50
57
|
import {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
58
|
+
formatConfig,
|
|
59
|
+
getDefaults,
|
|
60
|
+
loadConfig,
|
|
61
|
+
saveConfig
|
|
62
|
+
} from "./chunk-LJ7HTOIK.js";
|
|
63
|
+
import {
|
|
64
|
+
KNOWN_ENV_VARS,
|
|
65
|
+
formatEnvStatus,
|
|
66
|
+
loadEnv,
|
|
67
|
+
saveEnv,
|
|
68
|
+
saveEnvExample
|
|
69
|
+
} from "./chunk-3AHNSXQX.js";
|
|
55
70
|
|
|
56
71
|
// src/index.ts
|
|
57
72
|
import { Command as Command17 } from "commander";
|
|
58
|
-
import
|
|
73
|
+
import chalk43 from "chalk";
|
|
59
74
|
|
|
60
75
|
// src/commands/chat.ts
|
|
61
76
|
import { Command } from "commander";
|
|
@@ -786,7 +801,7 @@ import * as readline from "readline";
|
|
|
786
801
|
import { createRequire } from "module";
|
|
787
802
|
var _require = createRequire(import.meta.url);
|
|
788
803
|
function readMasked(prompt) {
|
|
789
|
-
return new Promise((
|
|
804
|
+
return new Promise((resolve5) => {
|
|
790
805
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
791
806
|
const stdin = process.stdin;
|
|
792
807
|
const onData = (char) => {
|
|
@@ -794,7 +809,7 @@ function readMasked(prompt) {
|
|
|
794
809
|
if (code === 3) {
|
|
795
810
|
rl.close();
|
|
796
811
|
stdin.removeListener("data", onData);
|
|
797
|
-
|
|
812
|
+
resolve5("");
|
|
798
813
|
return;
|
|
799
814
|
}
|
|
800
815
|
stdin.write("\x1B[2K\x1B[200D" + prompt + "*".repeat(rl.line.length + 1));
|
|
@@ -804,16 +819,16 @@ function readMasked(prompt) {
|
|
|
804
819
|
stdin.removeListener("data", onData);
|
|
805
820
|
stdin.write("\n");
|
|
806
821
|
rl.close();
|
|
807
|
-
|
|
822
|
+
resolve5(answer);
|
|
808
823
|
});
|
|
809
824
|
});
|
|
810
825
|
}
|
|
811
826
|
function readInput(prompt) {
|
|
812
|
-
return new Promise((
|
|
827
|
+
return new Promise((resolve5) => {
|
|
813
828
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
814
829
|
rl.question(prompt, (answer) => {
|
|
815
830
|
rl.close();
|
|
816
|
-
|
|
831
|
+
resolve5(answer.trim());
|
|
817
832
|
});
|
|
818
833
|
});
|
|
819
834
|
}
|
|
@@ -1063,14 +1078,14 @@ var SlashHandler = class {
|
|
|
1063
1078
|
// src/chat/input.ts
|
|
1064
1079
|
import * as readline2 from "readline";
|
|
1065
1080
|
function createSimpleInput(prompt = "") {
|
|
1066
|
-
return new Promise((
|
|
1081
|
+
return new Promise((resolve5) => {
|
|
1067
1082
|
const rl = readline2.createInterface({
|
|
1068
1083
|
input: process.stdin,
|
|
1069
1084
|
output: process.stdout
|
|
1070
1085
|
});
|
|
1071
1086
|
rl.question(prompt, (answer) => {
|
|
1072
1087
|
rl.close();
|
|
1073
|
-
|
|
1088
|
+
resolve5(answer);
|
|
1074
1089
|
});
|
|
1075
1090
|
});
|
|
1076
1091
|
}
|
|
@@ -1560,9 +1575,9 @@ var chatCommand = new Command("chat").alias("c").description("Start an interacti
|
|
|
1560
1575
|
const saveLog = () => {
|
|
1561
1576
|
if (!dirty) return;
|
|
1562
1577
|
try {
|
|
1563
|
-
const
|
|
1578
|
+
const path23 = writeChatLog(session.id, session.title, session.entries);
|
|
1564
1579
|
console.log(chalk4.dim(`
|
|
1565
|
-
Chat log saved: ${
|
|
1580
|
+
Chat log saved: ${path23}`));
|
|
1566
1581
|
} catch {
|
|
1567
1582
|
}
|
|
1568
1583
|
};
|
|
@@ -1756,7 +1771,7 @@ function classifyTool(toolName, args) {
|
|
|
1756
1771
|
return "warning";
|
|
1757
1772
|
}
|
|
1758
1773
|
function askApproval(description, toolName, level) {
|
|
1759
|
-
return new Promise((
|
|
1774
|
+
return new Promise((resolve5) => {
|
|
1760
1775
|
const label = level === "dangerous" ? chalk6.bgRed.white(" DANGEROUS ") : chalk6.bgYellow.black(" WARNING ");
|
|
1761
1776
|
console.log(`
|
|
1762
1777
|
${label} ${chalk6.dim(toolName)}: ${description}`);
|
|
@@ -1772,7 +1787,7 @@ function askApproval(description, toolName, level) {
|
|
|
1772
1787
|
} else {
|
|
1773
1788
|
console.log(chalk6.yellow(" \u2717 Skipped\n"));
|
|
1774
1789
|
}
|
|
1775
|
-
|
|
1790
|
+
resolve5(allowed);
|
|
1776
1791
|
});
|
|
1777
1792
|
});
|
|
1778
1793
|
}
|
|
@@ -2831,7 +2846,7 @@ var CommandExecutor = class extends EventEmitter {
|
|
|
2831
2846
|
cancelled: false
|
|
2832
2847
|
};
|
|
2833
2848
|
}
|
|
2834
|
-
return new Promise((
|
|
2849
|
+
return new Promise((resolve5) => {
|
|
2835
2850
|
const shell = process.platform === "win32" ? "cmd.exe" : "/bin/bash";
|
|
2836
2851
|
const shellFlag = process.platform === "win32" ? "/c" : "-c";
|
|
2837
2852
|
try {
|
|
@@ -2842,7 +2857,7 @@ var CommandExecutor = class extends EventEmitter {
|
|
|
2842
2857
|
signal
|
|
2843
2858
|
});
|
|
2844
2859
|
} catch (err) {
|
|
2845
|
-
|
|
2860
|
+
resolve5({
|
|
2846
2861
|
success: false,
|
|
2847
2862
|
exitCode: null,
|
|
2848
2863
|
stdout: "",
|
|
@@ -2854,7 +2869,7 @@ var CommandExecutor = class extends EventEmitter {
|
|
|
2854
2869
|
}
|
|
2855
2870
|
const timer = setTimeout(() => {
|
|
2856
2871
|
this.kill();
|
|
2857
|
-
|
|
2872
|
+
resolve5({
|
|
2858
2873
|
success: false,
|
|
2859
2874
|
exitCode: null,
|
|
2860
2875
|
stdout: this.stdoutBuffer,
|
|
@@ -2880,7 +2895,7 @@ var CommandExecutor = class extends EventEmitter {
|
|
|
2880
2895
|
const duration = Date.now() - this.startTime;
|
|
2881
2896
|
options.onExit?.(exitCode);
|
|
2882
2897
|
this.emit("exit", exitCode);
|
|
2883
|
-
|
|
2898
|
+
resolve5({
|
|
2884
2899
|
success: exitCode === 0 && !this.aborted,
|
|
2885
2900
|
exitCode,
|
|
2886
2901
|
stdout: this.stdoutBuffer,
|
|
@@ -2892,7 +2907,7 @@ var CommandExecutor = class extends EventEmitter {
|
|
|
2892
2907
|
this.process.on("error", (err) => {
|
|
2893
2908
|
clearTimeout(timer);
|
|
2894
2909
|
this.emit("error", err);
|
|
2895
|
-
|
|
2910
|
+
resolve5({
|
|
2896
2911
|
success: false,
|
|
2897
2912
|
exitCode: null,
|
|
2898
2913
|
stdout: this.stdoutBuffer,
|
|
@@ -3523,7 +3538,7 @@ function findCircularDeps(graph) {
|
|
|
3523
3538
|
const visited = /* @__PURE__ */ new Set();
|
|
3524
3539
|
const recursionStack = /* @__PURE__ */ new Set();
|
|
3525
3540
|
const circles = [];
|
|
3526
|
-
function dfs(node,
|
|
3541
|
+
function dfs(node, path23) {
|
|
3527
3542
|
visited.add(node);
|
|
3528
3543
|
recursionStack.add(node);
|
|
3529
3544
|
const nodeData = graph.nodes.get(node);
|
|
@@ -3535,9 +3550,9 @@ function findCircularDeps(graph) {
|
|
|
3535
3550
|
const target = resolveImportInGraph(imp, node, graph);
|
|
3536
3551
|
if (target && graph.nodes.has(target)) {
|
|
3537
3552
|
if (!visited.has(target)) {
|
|
3538
|
-
dfs(target, [...
|
|
3553
|
+
dfs(target, [...path23, target]);
|
|
3539
3554
|
} else if (recursionStack.has(target)) {
|
|
3540
|
-
const cycle = [...
|
|
3555
|
+
const cycle = [...path23.slice(path23.indexOf(target)), target];
|
|
3541
3556
|
circles.push(cycle);
|
|
3542
3557
|
}
|
|
3543
3558
|
}
|
|
@@ -4915,248 +4930,30 @@ var runCommand = new Command2("run").alias("r").description("Run LoveCode AI on
|
|
|
4915
4930
|
|
|
4916
4931
|
// src/commands/init.ts
|
|
4917
4932
|
import { Command as Command3 } from "commander";
|
|
4918
|
-
import
|
|
4919
|
-
import * as fs20 from "fs";
|
|
4920
|
-
import * as path20 from "path";
|
|
4921
|
-
|
|
4922
|
-
// src/config/config.ts
|
|
4933
|
+
import chalk22 from "chalk";
|
|
4923
4934
|
import * as fs18 from "fs";
|
|
4924
|
-
import * as path17 from "path";
|
|
4925
|
-
import * as YAML from "js-yaml";
|
|
4926
|
-
import chalk21 from "chalk";
|
|
4927
|
-
var DEFAULT_CONFIG = {
|
|
4928
|
-
model: "deepseek",
|
|
4929
|
-
theme: "neon",
|
|
4930
|
-
approval_mode: "smart",
|
|
4931
|
-
performance: {
|
|
4932
|
-
lazy_load: true,
|
|
4933
|
-
cache_ttl: 3e5,
|
|
4934
|
-
max_memory_mb: 200
|
|
4935
|
-
},
|
|
4936
|
-
termux: {
|
|
4937
|
-
low_ram: false,
|
|
4938
|
-
touch_optimized: false
|
|
4939
|
-
},
|
|
4940
|
-
telemetry: {
|
|
4941
|
-
enabled: false,
|
|
4942
|
-
crash_reports: false
|
|
4943
|
-
},
|
|
4944
|
-
security: {
|
|
4945
|
-
profile: "standard",
|
|
4946
|
-
scan_secrets: true
|
|
4947
|
-
}
|
|
4948
|
-
};
|
|
4949
|
-
var cachedConfig = null;
|
|
4950
|
-
function configDir(rootDir) {
|
|
4951
|
-
return path17.resolve(rootDir || process.cwd(), ".lovecode");
|
|
4952
|
-
}
|
|
4953
|
-
function yamlPath(rootDir) {
|
|
4954
|
-
return path17.resolve(configDir(rootDir), "config.yaml");
|
|
4955
|
-
}
|
|
4956
|
-
function jsonPath(rootDir) {
|
|
4957
|
-
return path17.resolve(configDir(rootDir), "config.json");
|
|
4958
|
-
}
|
|
4959
|
-
function loadConfig(rootDir) {
|
|
4960
|
-
if (cachedConfig) return cachedConfig;
|
|
4961
|
-
const merged = { ...DEFAULT_CONFIG };
|
|
4962
|
-
const yml = yamlPath(rootDir);
|
|
4963
|
-
const json = jsonPath(rootDir);
|
|
4964
|
-
let fileConfig = {};
|
|
4965
|
-
if (fs18.existsSync(yml)) {
|
|
4966
|
-
try {
|
|
4967
|
-
const raw = fs18.readFileSync(yml, "utf-8");
|
|
4968
|
-
const parsed = YAML.load(raw);
|
|
4969
|
-
if (parsed) fileConfig = parsed;
|
|
4970
|
-
} catch (err) {
|
|
4971
|
-
console.error(chalk21.yellow(`Warning: Failed to parse ${yml}: ${err}`));
|
|
4972
|
-
}
|
|
4973
|
-
} else if (fs18.existsSync(json)) {
|
|
4974
|
-
try {
|
|
4975
|
-
fileConfig = JSON.parse(fs18.readFileSync(json, "utf-8"));
|
|
4976
|
-
} catch {
|
|
4977
|
-
}
|
|
4978
|
-
}
|
|
4979
|
-
Object.assign(merged, fileConfig);
|
|
4980
|
-
if (process.env.LOVECODE_MODEL) merged.model = process.env.LOVECODE_MODEL;
|
|
4981
|
-
if (process.env.LOVECODE_THEME) merged.theme = process.env.LOVECODE_THEME;
|
|
4982
|
-
if (process.env.LOVECODE_APPROVAL_MODE) merged.approval_mode = process.env.LOVECODE_APPROVAL_MODE;
|
|
4983
|
-
cachedConfig = merged;
|
|
4984
|
-
return merged;
|
|
4985
|
-
}
|
|
4986
|
-
function saveConfig(config, rootDir) {
|
|
4987
|
-
const dir = configDir(rootDir);
|
|
4988
|
-
if (!fs18.existsSync(dir)) fs18.mkdirSync(dir, { recursive: true });
|
|
4989
|
-
const yml = {
|
|
4990
|
-
model: config.model,
|
|
4991
|
-
theme: config.theme,
|
|
4992
|
-
approval_mode: config.approval_mode,
|
|
4993
|
-
...config.provider ? { provider: config.provider } : {},
|
|
4994
|
-
...config.model_params ? { model_params: config.model_params } : {},
|
|
4995
|
-
...config.api ? { api: config.api } : {},
|
|
4996
|
-
...config.performance ? { performance: config.performance } : {},
|
|
4997
|
-
...config.termux ? { termux: config.termux } : {},
|
|
4998
|
-
...config.telemetry ? { telemetry: config.telemetry } : {},
|
|
4999
|
-
...config.security ? { security: config.security } : {}
|
|
5000
|
-
};
|
|
5001
|
-
fs18.writeFileSync(yamlPath(rootDir), YAML.dump(yml, { indent: 2, lineWidth: 120 }), "utf-8");
|
|
5002
|
-
cachedConfig = config;
|
|
5003
|
-
}
|
|
5004
|
-
function getDefaults() {
|
|
5005
|
-
return { ...DEFAULT_CONFIG };
|
|
5006
|
-
}
|
|
5007
|
-
function formatConfig(config) {
|
|
5008
|
-
const lines = [chalk21.bold("\n LoveCode Configuration")];
|
|
5009
|
-
lines.push(`
|
|
5010
|
-
${chalk21.dim("Model:")} ${chalk21.cyan(config.model)}`);
|
|
5011
|
-
lines.push(` ${chalk21.dim("Theme:")} ${chalk21.magenta(config.theme)}`);
|
|
5012
|
-
lines.push(` ${chalk21.dim("Approval Mode:")} ${approvalColor(config.approval_mode)}`);
|
|
5013
|
-
if (config.provider) lines.push(` ${chalk21.dim("Provider:")} ${config.provider}`);
|
|
5014
|
-
if (config.model_params) {
|
|
5015
|
-
lines.push(`
|
|
5016
|
-
${chalk21.bold("Model Params:")}`);
|
|
5017
|
-
if (config.model_params.temperature !== void 0) lines.push(` temperature: ${config.model_params.temperature}`);
|
|
5018
|
-
if (config.model_params.top_p !== void 0) lines.push(` top_p: ${config.model_params.top_p}`);
|
|
5019
|
-
if (config.model_params.max_tokens !== void 0) lines.push(` max_tokens: ${config.model_params.max_tokens}`);
|
|
5020
|
-
}
|
|
5021
|
-
if (config.performance) {
|
|
5022
|
-
lines.push(`
|
|
5023
|
-
${chalk21.bold("Performance:")}`);
|
|
5024
|
-
lines.push(` lazy_load: ${config.performance.lazy_load ? chalk21.green("\u2713") : chalk21.red("\u2717")}`);
|
|
5025
|
-
lines.push(` cache_ttl: ${config.performance.cache_ttl}ms`);
|
|
5026
|
-
lines.push(` max_memory: ${config.performance.max_memory_mb}MB`);
|
|
5027
|
-
}
|
|
5028
|
-
if (config.telemetry) {
|
|
5029
|
-
lines.push(`
|
|
5030
|
-
${chalk21.bold("Telemetry:")}`);
|
|
5031
|
-
lines.push(` enabled: ${config.telemetry.enabled ? chalk21.yellow("ON") : chalk21.green("OFF")}`);
|
|
5032
|
-
lines.push(` crash_reports:${config.telemetry.crash_reports ? chalk21.yellow("ON") : chalk21.green("OFF")}`);
|
|
5033
|
-
}
|
|
5034
|
-
if (config.security) {
|
|
5035
|
-
lines.push(`
|
|
5036
|
-
${chalk21.bold("Security:")}`);
|
|
5037
|
-
lines.push(` profile: ${config.security.profile}`);
|
|
5038
|
-
lines.push(` scan_secrets: ${config.security.scan_secrets ? chalk21.green("\u2713") : chalk21.red("\u2717")}`);
|
|
5039
|
-
}
|
|
5040
|
-
if (config.termux) {
|
|
5041
|
-
lines.push(`
|
|
5042
|
-
${chalk21.bold("Termux:")}`);
|
|
5043
|
-
lines.push(` low_ram: ${config.termux.low_ram ? chalk21.yellow("\u2713") : chalk21.red("\u2717")}`);
|
|
5044
|
-
lines.push(` touch_opt: ${config.termux.touch_optimized ? chalk21.green("\u2713") : chalk21.red("\u2717")}`);
|
|
5045
|
-
}
|
|
5046
|
-
return lines.join("\n");
|
|
5047
|
-
}
|
|
5048
|
-
function approvalColor(mode) {
|
|
5049
|
-
switch (mode) {
|
|
5050
|
-
case "strict":
|
|
5051
|
-
return chalk21.red(mode);
|
|
5052
|
-
case "smart":
|
|
5053
|
-
return chalk21.yellow(mode);
|
|
5054
|
-
case "permissive":
|
|
5055
|
-
return chalk21.green(mode);
|
|
5056
|
-
default:
|
|
5057
|
-
return mode;
|
|
5058
|
-
}
|
|
5059
|
-
}
|
|
5060
|
-
|
|
5061
|
-
// src/config/env.ts
|
|
5062
|
-
import * as fs19 from "fs";
|
|
5063
4935
|
import * as path18 from "path";
|
|
5064
|
-
import chalk22 from "chalk";
|
|
5065
|
-
var ENV_FILENAME = ".env";
|
|
5066
|
-
var ENV_EXAMPLE = ".env.example";
|
|
5067
|
-
var KNOWN_ENV_VARS = [
|
|
5068
|
-
{ key: "GROQ_API_KEY", value: "", description: "Groq API key for LLM access", required: false },
|
|
5069
|
-
{ key: "OPENROUTER_API_KEY", value: "", description: "OpenRouter API key for LLM access", required: false },
|
|
5070
|
-
{ key: "TOGETHER_API_KEY", value: "", description: "Together AI API key", required: false },
|
|
5071
|
-
{ key: "HUGGINGFACE_API_KEY", value: "", description: "HuggingFace API key", required: false },
|
|
5072
|
-
{ key: "OPENAI_API_KEY", value: "", description: "OpenAI API key (fallback)", required: false },
|
|
5073
|
-
{ key: "OLLAMA_URL", value: "http://localhost:11434", description: "Ollama server URL", required: false },
|
|
5074
|
-
{ key: "LOVECODE_LOG_LEVEL", value: "info", description: "Log level (debug|info|warn|error)", required: false },
|
|
5075
|
-
{ key: "LOVECODE_MODEL", value: "", description: "Override default model", required: false },
|
|
5076
|
-
{ key: "LOVECODE_THEME", value: "", description: "Override default theme", required: false },
|
|
5077
|
-
{ key: "LOVECODE_APPROVAL_MODE", value: "", description: "Override approval mode (smart|strict|permissive)", required: false },
|
|
5078
|
-
{ key: "LOVECODE_TELEMETRY", value: "", description: "Enable telemetry (true|false)", required: false }
|
|
5079
|
-
];
|
|
5080
|
-
function loadEnv(rootDir) {
|
|
5081
|
-
const envPath = path18.resolve(rootDir || process.cwd(), ENV_FILENAME);
|
|
5082
|
-
const vars = {};
|
|
5083
|
-
if (fs19.existsSync(envPath)) {
|
|
5084
|
-
const content = fs19.readFileSync(envPath, "utf-8");
|
|
5085
|
-
for (const line of content.split("\n")) {
|
|
5086
|
-
const trimmed = line.trim();
|
|
5087
|
-
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
5088
|
-
const eqIdx = trimmed.indexOf("=");
|
|
5089
|
-
if (eqIdx > 0) {
|
|
5090
|
-
const key = trimmed.slice(0, eqIdx).trim();
|
|
5091
|
-
let value = trimmed.slice(eqIdx + 1).trim();
|
|
5092
|
-
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
5093
|
-
value = value.slice(1, -1);
|
|
5094
|
-
}
|
|
5095
|
-
vars[key] = value;
|
|
5096
|
-
}
|
|
5097
|
-
}
|
|
5098
|
-
}
|
|
5099
|
-
for (const v of KNOWN_ENV_VARS) {
|
|
5100
|
-
const envVal = process.env[v.key];
|
|
5101
|
-
if (envVal) vars[v.key] = envVal;
|
|
5102
|
-
}
|
|
5103
|
-
return vars;
|
|
5104
|
-
}
|
|
5105
|
-
function saveEnv(vars, rootDir) {
|
|
5106
|
-
const envPath = path18.resolve(rootDir || process.cwd(), ENV_FILENAME);
|
|
5107
|
-
const dir = path18.dirname(envPath);
|
|
5108
|
-
if (!fs19.existsSync(dir)) fs19.mkdirSync(dir, { recursive: true });
|
|
5109
|
-
const lines = ["# LoveCode AI - Environment Configuration", `# Created: ${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`, ""];
|
|
5110
|
-
for (const v of KNOWN_ENV_VARS) {
|
|
5111
|
-
const value = vars[v.key] !== void 0 ? vars[v.key] : v.value;
|
|
5112
|
-
lines.push(`# ${v.description}`);
|
|
5113
|
-
lines.push(`${v.key}=${value}`);
|
|
5114
|
-
lines.push("");
|
|
5115
|
-
}
|
|
5116
|
-
fs19.writeFileSync(envPath, lines.join("\n"), "utf-8");
|
|
5117
|
-
}
|
|
5118
|
-
function saveEnvExample(rootDir) {
|
|
5119
|
-
const exPath = path18.resolve(rootDir || process.cwd(), ENV_EXAMPLE);
|
|
5120
|
-
const lines = ["# LoveCode AI - Environment Configuration Example", "# Copy this file to .env and fill in your values", ""];
|
|
5121
|
-
for (const v of KNOWN_ENV_VARS) {
|
|
5122
|
-
lines.push(`# ${v.description}`);
|
|
5123
|
-
lines.push(v.required ? `${v.key}=` : `# ${v.key}=`);
|
|
5124
|
-
lines.push("");
|
|
5125
|
-
}
|
|
5126
|
-
fs19.writeFileSync(exPath, lines.join("\n"), "utf-8");
|
|
5127
|
-
}
|
|
5128
|
-
function formatEnvStatus(rootDir) {
|
|
5129
|
-
const vars = loadEnv(rootDir);
|
|
5130
|
-
const lines = [chalk22.bold("\n Environment Variables")];
|
|
5131
|
-
for (const v of KNOWN_ENV_VARS) {
|
|
5132
|
-
const val = vars[v.key] || process.env[v.key] || "";
|
|
5133
|
-
const set = val.length > 0;
|
|
5134
|
-
const masked = set && v.key.includes("KEY") ? val.slice(0, 8) + "*".repeat(Math.min(val.length - 8, 20)) : val || "(not set)";
|
|
5135
|
-
lines.push(` ${set ? chalk22.green("\u2713") : chalk22.dim("\u25CB")} ${chalk22.dim(v.key.padEnd(25))} ${masked}`);
|
|
5136
|
-
}
|
|
5137
|
-
return lines.join("\n");
|
|
5138
|
-
}
|
|
5139
4936
|
|
|
5140
4937
|
// src/config/setup.ts
|
|
5141
|
-
import * as
|
|
5142
|
-
import
|
|
4938
|
+
import * as path17 from "path";
|
|
4939
|
+
import chalk21 from "chalk";
|
|
5143
4940
|
var MODELS = ["deepseek", "llama3", "codellama", "mistral", "mixtral", "qwen", "phi", "gpt-4o-mini", "claude-3-haiku"];
|
|
5144
4941
|
var PROVIDERS = ["ollama", "groq", "openrouter", "togetherai", "huggingface"];
|
|
5145
4942
|
var THEMES = ["neon", "dark", "light", "ocean", "forest", "midnight", "sunset"];
|
|
5146
4943
|
function ask(q, options) {
|
|
5147
|
-
return new Promise((
|
|
4944
|
+
return new Promise((resolve5) => {
|
|
5148
4945
|
const { stdin, stdout } = process;
|
|
5149
4946
|
const def = options?.default ? ` [${options.default}]` : "";
|
|
5150
4947
|
const choices = options?.choices ? ` (${options.choices.join("/")})` : "";
|
|
5151
|
-
stdout.write(` ${
|
|
4948
|
+
stdout.write(` ${chalk21.cyan("?")} ${q}${choices}${def}: `);
|
|
5152
4949
|
stdin.once("data", (data) => {
|
|
5153
4950
|
let answer = data.toString().trim();
|
|
5154
4951
|
if (options?.password) {
|
|
5155
4952
|
stdout.write("\r" + " ".repeat(80) + "\r");
|
|
5156
|
-
stdout.write(` ${
|
|
4953
|
+
stdout.write(` ${chalk21.green("\u2713")} ${q}: ${"*".repeat(answer.length)}
|
|
5157
4954
|
`);
|
|
5158
4955
|
} else {
|
|
5159
|
-
stdout.write(` ${
|
|
4956
|
+
stdout.write(` ${chalk21.green("\u2713")} ${q}: ${answer || def || "(skipped)"}
|
|
5160
4957
|
`);
|
|
5161
4958
|
}
|
|
5162
4959
|
if (!answer && def) answer = def;
|
|
@@ -5164,27 +4961,27 @@ function ask(q, options) {
|
|
|
5164
4961
|
const match = options.choices.find((c) => c.toLowerCase().startsWith(answer.toLowerCase()));
|
|
5165
4962
|
if (match) answer = match;
|
|
5166
4963
|
}
|
|
5167
|
-
|
|
4964
|
+
resolve5(answer);
|
|
5168
4965
|
});
|
|
5169
4966
|
});
|
|
5170
4967
|
}
|
|
5171
4968
|
async function confirm(q, defaultYes = true) {
|
|
5172
|
-
return new Promise((
|
|
4969
|
+
return new Promise((resolve5) => {
|
|
5173
4970
|
const hint = defaultYes ? "Y/n" : "y/N";
|
|
5174
|
-
process.stdout.write(` ${
|
|
4971
|
+
process.stdout.write(` ${chalk21.cyan("?")} ${q} (${hint}): `);
|
|
5175
4972
|
process.stdin.once("data", (data) => {
|
|
5176
4973
|
const answer = data.toString().trim().toLowerCase();
|
|
5177
|
-
process.stdout.write(` ${
|
|
4974
|
+
process.stdout.write(` ${chalk21.green("\u2713")} ${q}: ${answer || (defaultYes ? "yes" : "no")}
|
|
5178
4975
|
`);
|
|
5179
|
-
if (!answer)
|
|
5180
|
-
else
|
|
4976
|
+
if (!answer) resolve5(defaultYes);
|
|
4977
|
+
else resolve5(answer === "y" || answer === "yes");
|
|
5181
4978
|
});
|
|
5182
4979
|
});
|
|
5183
4980
|
}
|
|
5184
4981
|
async function runSetup(rootDir) {
|
|
5185
|
-
console.log(
|
|
5186
|
-
console.log(
|
|
5187
|
-
console.log(
|
|
4982
|
+
console.log(chalk21.bold.cyan("\n \u26A1 LoveCode AI Setup Wizard\n"));
|
|
4983
|
+
console.log(chalk21.dim(" This will configure LoveCode for your environment.\n"));
|
|
4984
|
+
console.log(chalk21.dim(" Press Enter to accept defaults.\n"));
|
|
5188
4985
|
const dir = rootDir || process.cwd();
|
|
5189
4986
|
const existing = loadConfig(dir);
|
|
5190
4987
|
const defaults = getDefaults();
|
|
@@ -5212,8 +5009,8 @@ async function runSetup(rootDir) {
|
|
|
5212
5009
|
telemetry: { enabled: telemetry, crash_reports: false }
|
|
5213
5010
|
};
|
|
5214
5011
|
saveConfig(config, dir);
|
|
5215
|
-
console.log(
|
|
5216
|
-
\u2713 Config saved to ${
|
|
5012
|
+
console.log(chalk21.green(`
|
|
5013
|
+
\u2713 Config saved to ${path17.join(dir, ".lovecode/config.yaml")}`));
|
|
5217
5014
|
if (createEnv) {
|
|
5218
5015
|
const envVars = {};
|
|
5219
5016
|
if (apiKey && provider !== "ollama") {
|
|
@@ -5221,33 +5018,33 @@ async function runSetup(rootDir) {
|
|
|
5221
5018
|
if (envKey) envVars[envKey.key] = apiKey;
|
|
5222
5019
|
}
|
|
5223
5020
|
saveEnv(envVars, dir);
|
|
5224
|
-
console.log(
|
|
5021
|
+
console.log(chalk21.green(` \u2713 Environment saved to ${path17.join(dir, ".env")}`));
|
|
5225
5022
|
}
|
|
5226
|
-
console.log(
|
|
5023
|
+
console.log(chalk21.dim("\n Final configuration:"));
|
|
5227
5024
|
console.log(formatConfig(loadConfig(dir)));
|
|
5228
|
-
console.log(
|
|
5025
|
+
console.log(chalk21.bold.cyan('\n Setup complete! Run "lovecode" to start.\n'));
|
|
5229
5026
|
}
|
|
5230
5027
|
|
|
5231
5028
|
// src/commands/init.ts
|
|
5232
5029
|
var initCommand = new Command3("init").alias("i").description("Initialize LoveCode AI in the current project").option("-f, --force", "Overwrite existing configuration").option("--dir <path>", "Project directory", process.cwd()).action(async (options) => {
|
|
5233
5030
|
const dir = options.dir || process.cwd();
|
|
5234
|
-
const configPath =
|
|
5031
|
+
const configPath = path18.join(dir, ".lovecode/config.yaml");
|
|
5235
5032
|
const force = options.force;
|
|
5236
|
-
if (
|
|
5237
|
-
console.log(
|
|
5033
|
+
if (fs18.existsSync(configPath) && !force) {
|
|
5034
|
+
console.log(chalk22.yellow(`
|
|
5238
5035
|
Config already exists at ${configPath}`));
|
|
5239
|
-
console.log(
|
|
5036
|
+
console.log(chalk22.dim(' Use --force to overwrite, or run "lovecode setup" for interactive setup.\n'));
|
|
5240
5037
|
return;
|
|
5241
5038
|
}
|
|
5242
5039
|
const config = getDefaults();
|
|
5243
5040
|
saveConfig(config, dir);
|
|
5244
5041
|
saveEnvExample(dir);
|
|
5245
|
-
console.log(
|
|
5246
|
-
console.log(
|
|
5247
|
-
console.log(
|
|
5042
|
+
console.log(chalk22.bold.cyan("\n LoveCode AI \u26A1 Initialized\n"));
|
|
5043
|
+
console.log(chalk22.green(` \u2713 ${configPath}`));
|
|
5044
|
+
console.log(chalk22.green(` \u2713 ${path18.join(dir, ".env.example")}`));
|
|
5248
5045
|
console.log(formatConfig(config));
|
|
5249
|
-
console.log(
|
|
5250
|
-
console.log(
|
|
5046
|
+
console.log(chalk22.dim('\n Run "lovecode setup" for interactive configuration,'));
|
|
5047
|
+
console.log(chalk22.dim(" or edit .lovecode/config.yaml directly.\n"));
|
|
5251
5048
|
});
|
|
5252
5049
|
var setupCommand = new Command3("setup").alias("configure").description("Run the interactive setup wizard").option("--dir <path>", "Project directory", process.cwd()).action(async (options) => {
|
|
5253
5050
|
await runSetup(options.dir);
|
|
@@ -5255,7 +5052,7 @@ var setupCommand = new Command3("setup").alias("configure").description("Run the
|
|
|
5255
5052
|
|
|
5256
5053
|
// src/commands/config.ts
|
|
5257
5054
|
import { Command as Command4 } from "commander";
|
|
5258
|
-
import
|
|
5055
|
+
import chalk23 from "chalk";
|
|
5259
5056
|
async function cmdShow(options) {
|
|
5260
5057
|
const config = loadConfig(options.dir);
|
|
5261
5058
|
console.log(formatConfig(config));
|
|
@@ -5264,31 +5061,31 @@ async function cmdSetModel(model, options) {
|
|
|
5264
5061
|
const config = loadConfig(options.dir);
|
|
5265
5062
|
config.model = model;
|
|
5266
5063
|
saveConfig(config, options.dir);
|
|
5267
|
-
console.log(
|
|
5064
|
+
console.log(chalk23.green(`Model set to: ${model}`));
|
|
5268
5065
|
console.log(formatConfig(loadConfig(options.dir)));
|
|
5269
5066
|
}
|
|
5270
5067
|
async function cmdSetTheme(theme, options) {
|
|
5271
5068
|
const config = loadConfig(options.dir);
|
|
5272
5069
|
config.theme = theme;
|
|
5273
5070
|
saveConfig(config, options.dir);
|
|
5274
|
-
console.log(
|
|
5071
|
+
console.log(chalk23.green(`Theme set to: ${theme}`));
|
|
5275
5072
|
}
|
|
5276
5073
|
async function cmdSetApproval(mode, options) {
|
|
5277
5074
|
const valid = ["smart", "strict", "permissive"];
|
|
5278
5075
|
if (!valid.includes(mode)) {
|
|
5279
|
-
console.log(
|
|
5076
|
+
console.log(chalk23.red(`Invalid mode: ${mode}. Options: ${valid.join(", ")}`));
|
|
5280
5077
|
return;
|
|
5281
5078
|
}
|
|
5282
5079
|
const config = loadConfig(options.dir);
|
|
5283
5080
|
config.approval_mode = mode;
|
|
5284
5081
|
saveConfig(config, options.dir);
|
|
5285
|
-
console.log(
|
|
5082
|
+
console.log(chalk23.green(`Approval mode set to: ${mode}`));
|
|
5286
5083
|
}
|
|
5287
5084
|
async function cmdSetProvider(provider, options) {
|
|
5288
5085
|
const config = loadConfig(options.dir);
|
|
5289
5086
|
config.provider = provider;
|
|
5290
5087
|
saveConfig(config, options.dir);
|
|
5291
|
-
console.log(
|
|
5088
|
+
console.log(chalk23.green(`Provider set to: ${provider}`));
|
|
5292
5089
|
}
|
|
5293
5090
|
var configCommand = new Command4("config").alias("cfg").description("View or modify LoveCode configuration").option("--dir <path>", "Project directory", process.cwd()).addHelpText("after", `
|
|
5294
5091
|
Examples:
|
|
@@ -5313,14 +5110,15 @@ configCommand.command("set").description("Set a configuration value").argument("
|
|
|
5313
5110
|
await cmdSetProvider(value, options);
|
|
5314
5111
|
break;
|
|
5315
5112
|
default:
|
|
5316
|
-
console.log(
|
|
5113
|
+
console.log(chalk23.red(`Unknown config key: ${key}. Valid keys: model, theme, approval, provider`));
|
|
5317
5114
|
}
|
|
5318
5115
|
});
|
|
5319
5116
|
configCommand.action(cmdShow);
|
|
5320
5117
|
|
|
5321
5118
|
// src/commands/env.ts
|
|
5322
5119
|
import { Command as Command5 } from "commander";
|
|
5323
|
-
import
|
|
5120
|
+
import chalk24 from "chalk";
|
|
5121
|
+
import inquirer from "inquirer";
|
|
5324
5122
|
async function cmdEnvShow(options) {
|
|
5325
5123
|
console.log(formatEnvStatus(options.dir));
|
|
5326
5124
|
}
|
|
@@ -5328,45 +5126,80 @@ async function cmdEnvSet(key, value, options) {
|
|
|
5328
5126
|
const vars = loadEnv(options.dir);
|
|
5329
5127
|
vars[key.toUpperCase()] = value;
|
|
5330
5128
|
saveEnv(vars, options.dir);
|
|
5331
|
-
console.log(
|
|
5129
|
+
console.log(chalk24.green(`Set ${key.toUpperCase()}`));
|
|
5332
5130
|
console.log(formatEnvStatus(options.dir));
|
|
5333
5131
|
}
|
|
5334
5132
|
async function cmdEnvUnset(key, options) {
|
|
5335
5133
|
const vars = loadEnv(options.dir);
|
|
5336
5134
|
delete vars[key.toUpperCase()];
|
|
5337
5135
|
saveEnv(vars, options.dir);
|
|
5338
|
-
console.log(
|
|
5136
|
+
console.log(chalk24.yellow(`Unset ${key.toUpperCase()}`));
|
|
5137
|
+
}
|
|
5138
|
+
async function cmdEnvSelect(options) {
|
|
5139
|
+
const vars = loadEnv(options.dir);
|
|
5140
|
+
const choices = KNOWN_ENV_VARS.map((v) => {
|
|
5141
|
+
const current = vars[v.key] || process.env[v.key] || "";
|
|
5142
|
+
const status = current ? chalk24.green("\u2713 set") : chalk24.dim("\u25CB empty");
|
|
5143
|
+
const masked = current && v.key.includes("KEY") ? current.slice(0, 8) + "*".repeat(Math.min(current.length - 8, 12)) : current || "";
|
|
5144
|
+
return {
|
|
5145
|
+
name: `${v.key.padEnd(28)} ${status} ${chalk24.dim(v.description)}${masked ? chalk24.dim(` (${masked})`) : ""}`,
|
|
5146
|
+
value: v.key,
|
|
5147
|
+
short: v.key
|
|
5148
|
+
};
|
|
5149
|
+
});
|
|
5150
|
+
const { key } = await inquirer.prompt([{
|
|
5151
|
+
type: "list",
|
|
5152
|
+
name: "key",
|
|
5153
|
+
message: "Select an environment variable to set:",
|
|
5154
|
+
choices,
|
|
5155
|
+
pageSize: 15
|
|
5156
|
+
}]);
|
|
5157
|
+
const existing = vars[key] || "";
|
|
5158
|
+
const description = KNOWN_ENV_VARS.find((v) => v.key === key)?.description || "";
|
|
5159
|
+
const { value } = await inquirer.prompt([{
|
|
5160
|
+
type: "input",
|
|
5161
|
+
name: "value",
|
|
5162
|
+
message: `Enter value for ${chalk24.cyan(key)} (${description}):`,
|
|
5163
|
+
default: existing || void 0,
|
|
5164
|
+
validate: (input) => input.length > 0 || "Value cannot be empty"
|
|
5165
|
+
}]);
|
|
5166
|
+
vars[key] = value;
|
|
5167
|
+
saveEnv(vars, options.dir);
|
|
5168
|
+
console.log(chalk24.green(`
|
|
5169
|
+
\u2713 ${key} saved`));
|
|
5170
|
+
console.log(formatEnvStatus(options.dir));
|
|
5339
5171
|
}
|
|
5340
5172
|
var envCommand = new Command5("env").alias("environment").description("Manage environment variables for API keys and settings").option("--dir <path>", "Project directory", process.cwd()).addHelpText("after", `
|
|
5341
5173
|
Examples:
|
|
5342
5174
|
lovecode env Show current environment
|
|
5175
|
+
lovecode env select Interactive variable selection
|
|
5343
5176
|
lovecode env set GROQ_API_KEY gsk_xxx
|
|
5344
|
-
lovecode env set OPENROUTER_API_KEY sk-or-xxx
|
|
5345
5177
|
lovecode env unset GROQ_API_KEY
|
|
5346
5178
|
`);
|
|
5347
5179
|
envCommand.command("set").description("Set an environment variable").argument("<key>", "Variable name").argument("<value>", "Variable value").option("--dir <path>", "Project directory").action(cmdEnvSet);
|
|
5348
5180
|
envCommand.command("unset").description("Remove an environment variable").argument("<key>", "Variable name").option("--dir <path>", "Project directory").action(cmdEnvUnset);
|
|
5181
|
+
envCommand.command("select").alias("pick").description("Interactively select and set an environment variable").option("--dir <path>", "Project directory").action(cmdEnvSelect);
|
|
5349
5182
|
envCommand.action(cmdEnvShow);
|
|
5350
5183
|
|
|
5351
5184
|
// src/commands/platform.ts
|
|
5352
5185
|
import { Command as Command6 } from "commander";
|
|
5353
5186
|
|
|
5354
5187
|
// src/platform/optimize.ts
|
|
5355
|
-
import
|
|
5188
|
+
import chalk25 from "chalk";
|
|
5356
5189
|
|
|
5357
5190
|
// src/platform/detect.ts
|
|
5358
|
-
import * as
|
|
5191
|
+
import * as fs19 from "fs";
|
|
5359
5192
|
import * as os from "os";
|
|
5360
5193
|
var _isTermux = null;
|
|
5361
5194
|
var _isCodespaces = null;
|
|
5362
5195
|
function isTermux() {
|
|
5363
5196
|
if (_isTermux !== null) return _isTermux;
|
|
5364
|
-
_isTermux =
|
|
5197
|
+
_isTermux = fs19.existsSync("/data/data/com.termux") || process.env.PREFIX === "/data/data/com.termux/files/usr" || !!process.env.TERMUX_VERSION;
|
|
5365
5198
|
return _isTermux;
|
|
5366
5199
|
}
|
|
5367
5200
|
function isCodespaces() {
|
|
5368
5201
|
if (_isCodespaces !== null) return _isCodespaces;
|
|
5369
|
-
_isCodespaces = process.env.CODESPACES === "true" || !!process.env.CODESPACE_NAME ||
|
|
5202
|
+
_isCodespaces = process.env.CODESPACES === "true" || !!process.env.CODESPACE_NAME || fs19.existsSync("/.codespaces");
|
|
5370
5203
|
return _isCodespaces;
|
|
5371
5204
|
}
|
|
5372
5205
|
function lowRamMode() {
|
|
@@ -5395,14 +5228,14 @@ function platformInfo() {
|
|
|
5395
5228
|
|
|
5396
5229
|
// src/platform/optimize.ts
|
|
5397
5230
|
function formatPlatformStatus() {
|
|
5398
|
-
const lines = [
|
|
5399
|
-
lines.push(` Termux: ${isTermux() ?
|
|
5400
|
-
lines.push(` Codespaces: ${isCodespaces() ?
|
|
5401
|
-
lines.push(` Low RAM: ${lowRamMode() ?
|
|
5231
|
+
const lines = [chalk25.bold("\n Platform Status")];
|
|
5232
|
+
lines.push(` Termux: ${isTermux() ? chalk25.green("\u2713") : chalk25.dim("\u2014")}`);
|
|
5233
|
+
lines.push(` Codespaces: ${isCodespaces() ? chalk25.green("\u2713") : chalk25.dim("\u2014")}`);
|
|
5234
|
+
lines.push(` Low RAM: ${lowRamMode() ? chalk25.yellow("\u2713") : chalk25.dim("\u2014")}`);
|
|
5402
5235
|
lines.push(` Max Mem: ${recommendedMaxMemory()}MB`);
|
|
5403
5236
|
lines.push("");
|
|
5404
5237
|
for (const line of platformInfo()) {
|
|
5405
|
-
lines.push(` ${
|
|
5238
|
+
lines.push(` ${chalk25.dim(line)}`);
|
|
5406
5239
|
}
|
|
5407
5240
|
return lines.join("\n");
|
|
5408
5241
|
}
|
|
@@ -5415,19 +5248,19 @@ var platformCommand = new Command6("platform").alias("sys").alias("info").descri
|
|
|
5415
5248
|
|
|
5416
5249
|
// src/commands/telemetry.ts
|
|
5417
5250
|
import { Command as Command7 } from "commander";
|
|
5418
|
-
import
|
|
5251
|
+
import chalk27 from "chalk";
|
|
5419
5252
|
|
|
5420
5253
|
// src/telemetry/telemetry.ts
|
|
5421
|
-
import * as
|
|
5422
|
-
import * as
|
|
5254
|
+
import * as fs20 from "fs";
|
|
5255
|
+
import * as path19 from "path";
|
|
5423
5256
|
import * as os2 from "os";
|
|
5424
5257
|
import { createRequire as createRequire2 } from "module";
|
|
5425
|
-
import
|
|
5258
|
+
import chalk26 from "chalk";
|
|
5426
5259
|
var _require2 = createRequire2(import.meta.url);
|
|
5427
5260
|
var TELEMETRY_DIR = ".lovecode/telemetry";
|
|
5428
5261
|
var _enabled = null;
|
|
5429
5262
|
function telemetryDir(rootDir) {
|
|
5430
|
-
return
|
|
5263
|
+
return path19.resolve(rootDir || process.cwd(), TELEMETRY_DIR);
|
|
5431
5264
|
}
|
|
5432
5265
|
function isTelemetryEnabled(rootDir) {
|
|
5433
5266
|
if (_enabled !== null) return _enabled;
|
|
@@ -5439,8 +5272,8 @@ function isTelemetryEnabled(rootDir) {
|
|
|
5439
5272
|
_enabled = false;
|
|
5440
5273
|
return false;
|
|
5441
5274
|
}
|
|
5442
|
-
const configPath =
|
|
5443
|
-
if (
|
|
5275
|
+
const configPath = path19.resolve(rootDir || process.cwd(), ".lovecode/config.yaml");
|
|
5276
|
+
if (fs20.existsSync(configPath)) {
|
|
5444
5277
|
try {
|
|
5445
5278
|
const { loadConfig: loadConfig2 } = _require2("../config/config.js");
|
|
5446
5279
|
const config = loadConfig2(rootDir);
|
|
@@ -5481,10 +5314,10 @@ function getTelemetryData(rootDir) {
|
|
|
5481
5314
|
const dir = telemetryDir(rootDir);
|
|
5482
5315
|
const events = [];
|
|
5483
5316
|
const crashes = [];
|
|
5484
|
-
if (!
|
|
5485
|
-
for (const file of
|
|
5317
|
+
if (!fs20.existsSync(dir)) return { events, crashes };
|
|
5318
|
+
for (const file of fs20.readdirSync(dir)) {
|
|
5486
5319
|
try {
|
|
5487
|
-
const content =
|
|
5320
|
+
const content = fs20.readFileSync(path19.join(dir, file), "utf-8");
|
|
5488
5321
|
const data = JSON.parse(content);
|
|
5489
5322
|
if (file.startsWith("crash-")) {
|
|
5490
5323
|
crashes.push(data);
|
|
@@ -5498,21 +5331,21 @@ function getTelemetryData(rootDir) {
|
|
|
5498
5331
|
}
|
|
5499
5332
|
function clearTelemetryData(rootDir) {
|
|
5500
5333
|
const dir = telemetryDir(rootDir);
|
|
5501
|
-
if (
|
|
5502
|
-
|
|
5334
|
+
if (fs20.existsSync(dir)) {
|
|
5335
|
+
fs20.rmSync(dir, { recursive: true, force: true });
|
|
5503
5336
|
}
|
|
5504
5337
|
}
|
|
5505
5338
|
function formatTelemetryStatus(enabled, data) {
|
|
5506
|
-
const lines = [
|
|
5507
|
-
lines.push(` Status: ${enabled ?
|
|
5339
|
+
const lines = [chalk26.bold("\n Telemetry Status")];
|
|
5340
|
+
lines.push(` Status: ${enabled ? chalk26.yellow("ENABLED") : chalk26.green("DISABLED")}`);
|
|
5508
5341
|
lines.push(` Events: ${data.events.length}`);
|
|
5509
5342
|
lines.push(` Crashes: ${data.crashes.length}`);
|
|
5510
5343
|
if (data.events.length > 0) {
|
|
5511
|
-
lines.push(
|
|
5344
|
+
lines.push(chalk26.dim(`
|
|
5512
5345
|
Recent Events:`));
|
|
5513
5346
|
for (const e of data.events.slice(-5)) {
|
|
5514
5347
|
const date = new Date(e.timestamp).toLocaleString();
|
|
5515
|
-
lines.push(` ${
|
|
5348
|
+
lines.push(` ${chalk26.dim(date)} ${e.event}`);
|
|
5516
5349
|
}
|
|
5517
5350
|
}
|
|
5518
5351
|
return lines.join("\n");
|
|
@@ -5526,17 +5359,17 @@ async function cmdTelemetryStatus(options) {
|
|
|
5526
5359
|
}
|
|
5527
5360
|
async function cmdTelemetryEnable(options) {
|
|
5528
5361
|
enableTelemetry(options.dir);
|
|
5529
|
-
console.log(
|
|
5530
|
-
console.log(
|
|
5531
|
-
console.log(
|
|
5362
|
+
console.log(chalk27.yellow("Telemetry enabled."));
|
|
5363
|
+
console.log(chalk27.dim(" Anonymous usage data will be collected to improve LoveCode."));
|
|
5364
|
+
console.log(chalk27.dim(" No personal or project data is ever sent."));
|
|
5532
5365
|
}
|
|
5533
5366
|
async function cmdTelemetryDisable(options) {
|
|
5534
5367
|
disableTelemetry(options.dir);
|
|
5535
|
-
console.log(
|
|
5368
|
+
console.log(chalk27.green("Telemetry disabled."));
|
|
5536
5369
|
}
|
|
5537
5370
|
async function cmdTelemetryClear(options) {
|
|
5538
5371
|
clearTelemetryData(options.dir);
|
|
5539
|
-
console.log(
|
|
5372
|
+
console.log(chalk27.green("Telemetry data cleared."));
|
|
5540
5373
|
}
|
|
5541
5374
|
var telemetryCommand = new Command7("telemetry").alias("analytics").description("Manage anonymous telemetry and crash reporting").option("--dir <path>", "Project directory", process.cwd()).addHelpText("after", `
|
|
5542
5375
|
Privacy-first by default. Telemetry is disabled unless explicitly enabled.
|
|
@@ -5554,13 +5387,13 @@ telemetryCommand.action(cmdTelemetryStatus);
|
|
|
5554
5387
|
|
|
5555
5388
|
// src/commands/install.ts
|
|
5556
5389
|
import { Command as Command8 } from "commander";
|
|
5557
|
-
import
|
|
5390
|
+
import chalk29 from "chalk";
|
|
5558
5391
|
|
|
5559
5392
|
// src/installers/install.ts
|
|
5560
|
-
import * as
|
|
5561
|
-
import * as
|
|
5393
|
+
import * as fs21 from "fs";
|
|
5394
|
+
import * as path20 from "path";
|
|
5562
5395
|
import { execSync as execSync4 } from "child_process";
|
|
5563
|
-
import
|
|
5396
|
+
import chalk28 from "chalk";
|
|
5564
5397
|
function detectInstallMethod() {
|
|
5565
5398
|
if (process.env.npm_config_user_agent?.startsWith("npm")) return "npm";
|
|
5566
5399
|
if (process.env.npm_config_user_agent?.startsWith("yarn")) return "yarn";
|
|
@@ -5586,21 +5419,21 @@ function isGloballyInstalled() {
|
|
|
5586
5419
|
}
|
|
5587
5420
|
}
|
|
5588
5421
|
function printInstallInstructions() {
|
|
5589
|
-
console.log(
|
|
5590
|
-
console.log(
|
|
5591
|
-
console.log(` ${
|
|
5422
|
+
console.log(chalk28.bold.cyan("\n LoveCode AI - Installation\n"));
|
|
5423
|
+
console.log(chalk28.bold(" Quick Install:\n"));
|
|
5424
|
+
console.log(` ${chalk28.green("NPM:")}`);
|
|
5592
5425
|
console.log(` npm install -g lovecode-ai
|
|
5593
5426
|
`);
|
|
5594
|
-
console.log(` ${
|
|
5427
|
+
console.log(` ${chalk28.green("Curl:")}`);
|
|
5595
5428
|
console.log(` curl -fsSL https://lovecode.sh | bash
|
|
5596
5429
|
`);
|
|
5597
|
-
console.log(` ${
|
|
5430
|
+
console.log(` ${chalk28.green("Verify:")}`);
|
|
5598
5431
|
console.log(` lovecode --version
|
|
5599
5432
|
`);
|
|
5600
5433
|
}
|
|
5601
5434
|
function createInstallScript(rootDir) {
|
|
5602
5435
|
const dir = rootDir || process.cwd();
|
|
5603
|
-
const scriptPath =
|
|
5436
|
+
const scriptPath = path20.join(dir, "install.sh");
|
|
5604
5437
|
const script = `#!/usr/bin/env bash
|
|
5605
5438
|
set -euo pipefail
|
|
5606
5439
|
|
|
@@ -5655,11 +5488,11 @@ echo " Run: lovecode setup Interactive configuration"
|
|
|
5655
5488
|
echo " Run: lovecode Start the AI agent"
|
|
5656
5489
|
echo ""
|
|
5657
5490
|
`;
|
|
5658
|
-
const scriptDir =
|
|
5659
|
-
if (!
|
|
5660
|
-
|
|
5491
|
+
const scriptDir = path20.dirname(scriptPath);
|
|
5492
|
+
if (!fs21.existsSync(scriptDir)) fs21.mkdirSync(scriptDir, { recursive: true });
|
|
5493
|
+
fs21.writeFileSync(scriptPath, script, "utf-8");
|
|
5661
5494
|
try {
|
|
5662
|
-
|
|
5495
|
+
fs21.chmodSync(scriptPath, "755");
|
|
5663
5496
|
} catch {
|
|
5664
5497
|
}
|
|
5665
5498
|
}
|
|
@@ -5668,20 +5501,20 @@ echo ""
|
|
|
5668
5501
|
async function cmdInstallStatus() {
|
|
5669
5502
|
const info = getInstallerInfo();
|
|
5670
5503
|
const global = isGloballyInstalled();
|
|
5671
|
-
console.log(
|
|
5672
|
-
console.log(` Method: ${
|
|
5504
|
+
console.log(chalk29.bold("\n Install Status"));
|
|
5505
|
+
console.log(` Method: ${chalk29.cyan(info.method)}`);
|
|
5673
5506
|
console.log(` Version: ${info.version}`);
|
|
5674
5507
|
console.log(` Node: ${info.nodeVersion}`);
|
|
5675
5508
|
console.log(` Platform: ${info.platform}`);
|
|
5676
|
-
console.log(` Global CLI: ${global ?
|
|
5509
|
+
console.log(` Global CLI: ${global ? chalk29.green("\u2713") : chalk29.dim("\u2014")}`);
|
|
5677
5510
|
}
|
|
5678
5511
|
async function cmdInstallGuide() {
|
|
5679
5512
|
printInstallInstructions();
|
|
5680
5513
|
}
|
|
5681
5514
|
async function cmdInstallScript(options) {
|
|
5682
5515
|
createInstallScript(options.dir);
|
|
5683
|
-
console.log(
|
|
5684
|
-
console.log(
|
|
5516
|
+
console.log(chalk29.green(` \u2713 install.sh created in ${options.dir || process.cwd()}`));
|
|
5517
|
+
console.log(chalk29.dim(" Run: bash install.sh"));
|
|
5685
5518
|
}
|
|
5686
5519
|
var installCommand = new Command8("install").alias("installer").description("Installation management and instructions").option("--dir <path>", "Project directory", process.cwd()).addHelpText("after", `
|
|
5687
5520
|
Examples:
|
|
@@ -5695,7 +5528,7 @@ installCommand.action(cmdInstallStatus);
|
|
|
5695
5528
|
|
|
5696
5529
|
// src/commands/models.ts
|
|
5697
5530
|
import { Command as Command9 } from "commander";
|
|
5698
|
-
import
|
|
5531
|
+
import chalk30 from "chalk";
|
|
5699
5532
|
var modelsCommand = new Command9("models").description("Manage AI models and providers").addCommand(
|
|
5700
5533
|
new Command9("list").alias("ls").description("List all available models and providers").action(() => {
|
|
5701
5534
|
console.log(printProviders());
|
|
@@ -5704,8 +5537,8 @@ var modelsCommand = new Command9("models").description("Manage AI models and pro
|
|
|
5704
5537
|
new Command9("use").description("Set the default model to use").argument("<model>", "Model name or provider name").action((model) => {
|
|
5705
5538
|
const result = setDefaultModel(model);
|
|
5706
5539
|
if (result) {
|
|
5707
|
-
console.log(
|
|
5708
|
-
\u2713 Default set to ${
|
|
5540
|
+
console.log(chalk30.green(`
|
|
5541
|
+
\u2713 Default set to ${chalk30.cyan(result.provider)}/${chalk30.cyan(result.model)}
|
|
5709
5542
|
`));
|
|
5710
5543
|
}
|
|
5711
5544
|
})
|
|
@@ -5714,20 +5547,20 @@ var modelsCommand = new Command9("models").description("Manage AI models and pro
|
|
|
5714
5547
|
if (provider) {
|
|
5715
5548
|
const entry = getProvider(provider);
|
|
5716
5549
|
if (!entry) {
|
|
5717
|
-
console.log(
|
|
5550
|
+
console.log(chalk30.red(`
|
|
5718
5551
|
Unknown provider: "${provider}"
|
|
5719
5552
|
`));
|
|
5720
5553
|
return;
|
|
5721
5554
|
}
|
|
5722
|
-
const tag = entry.local ?
|
|
5555
|
+
const tag = entry.local ? chalk30.green(" LOCAL ") : chalk30.blue(" CLOUD ");
|
|
5723
5556
|
console.log(`
|
|
5724
|
-
${tag} ${
|
|
5725
|
-
console.log(
|
|
5726
|
-
console.log(
|
|
5727
|
-
console.log(
|
|
5557
|
+
${tag} ${chalk30.cyan(entry.name)}`);
|
|
5558
|
+
console.log(chalk30.dim(` Default model: ${entry.defaultModel}`));
|
|
5559
|
+
console.log(chalk30.dim(` Priority: ${entry.priority}`));
|
|
5560
|
+
console.log(chalk30.dim(` Models:`));
|
|
5728
5561
|
for (const m of entry.models) {
|
|
5729
5562
|
const isDefault = m === entry.defaultModel;
|
|
5730
|
-
console.log(` ${isDefault ?
|
|
5563
|
+
console.log(` ${isDefault ? chalk30.green("\u2605") : " "} ${m}${isDefault ? chalk30.dim(" (default)") : ""}`);
|
|
5731
5564
|
}
|
|
5732
5565
|
console.log("");
|
|
5733
5566
|
} else {
|
|
@@ -5738,13 +5571,13 @@ var modelsCommand = new Command9("models").description("Manage AI models and pro
|
|
|
5738
5571
|
new Command9("test").description("Test a provider connection").argument("[provider]", "Provider name to test", "ollama").option("-m, --model <name>", "Model to test with").action(async (provider, options) => {
|
|
5739
5572
|
const entry = getProvider(provider);
|
|
5740
5573
|
if (!entry) {
|
|
5741
|
-
console.log(
|
|
5574
|
+
console.log(chalk30.red(`
|
|
5742
5575
|
Unknown provider: "${provider}"
|
|
5743
5576
|
`));
|
|
5744
5577
|
return;
|
|
5745
5578
|
}
|
|
5746
5579
|
const model = options.model || entry.defaultModel;
|
|
5747
|
-
console.log(
|
|
5580
|
+
console.log(chalk30.dim(`
|
|
5748
5581
|
Testing ${entry.name}/${model}...`));
|
|
5749
5582
|
try {
|
|
5750
5583
|
const config = entry.getConfig?.(model) || {
|
|
@@ -5757,9 +5590,9 @@ var modelsCommand = new Command9("models").description("Manage AI models and pro
|
|
|
5757
5590
|
[{ role: "user", content: "Reply with exactly: OK" }],
|
|
5758
5591
|
config
|
|
5759
5592
|
);
|
|
5760
|
-
console.log(
|
|
5593
|
+
console.log(chalk30.green(` \u2713 ${entry.name}/${model} responded: ${result.slice(0, 50)}`));
|
|
5761
5594
|
} catch (err) {
|
|
5762
|
-
console.log(
|
|
5595
|
+
console.log(chalk30.red(` \u2717 ${entry.name}/${model} failed: ${err.message}`));
|
|
5763
5596
|
}
|
|
5764
5597
|
console.log("");
|
|
5765
5598
|
})
|
|
@@ -5767,12 +5600,12 @@ var modelsCommand = new Command9("models").description("Manage AI models and pro
|
|
|
5767
5600
|
|
|
5768
5601
|
// src/commands/analyze.ts
|
|
5769
5602
|
import { Command as Command10 } from "commander";
|
|
5770
|
-
import
|
|
5603
|
+
import chalk32 from "chalk";
|
|
5771
5604
|
|
|
5772
5605
|
// src/repo/search.ts
|
|
5773
|
-
import * as
|
|
5774
|
-
import * as
|
|
5775
|
-
import
|
|
5606
|
+
import * as fs22 from "fs";
|
|
5607
|
+
import * as path21 from "path";
|
|
5608
|
+
import chalk31 from "chalk";
|
|
5776
5609
|
function chunkFile(content, maxLines = 50) {
|
|
5777
5610
|
const lines = content.split("\n");
|
|
5778
5611
|
const chunks = [];
|
|
@@ -5808,7 +5641,7 @@ async function semanticSearch2(rootDir, query, options = { rootDir: "", query: "
|
|
|
5808
5641
|
const queryEmbedding = await getEmbedding(query);
|
|
5809
5642
|
const files = collectTextFiles(rootDir, 200);
|
|
5810
5643
|
for (const filePath of files) {
|
|
5811
|
-
const relativePath =
|
|
5644
|
+
const relativePath = path21.relative(rootDir, filePath).replace(/\\/g, "/");
|
|
5812
5645
|
const content = readFileSafe(filePath);
|
|
5813
5646
|
if (!content) continue;
|
|
5814
5647
|
const chunks = chunkFile(content, 30);
|
|
@@ -5878,14 +5711,14 @@ function collectTextFiles(dir, max) {
|
|
|
5878
5711
|
function walk(dir2) {
|
|
5879
5712
|
if (results.length >= max) return;
|
|
5880
5713
|
try {
|
|
5881
|
-
const entries =
|
|
5714
|
+
const entries = fs22.readdirSync(dir2, { withFileTypes: true });
|
|
5882
5715
|
for (const entry of entries) {
|
|
5883
5716
|
if (results.length >= max) return;
|
|
5884
5717
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === ".git") continue;
|
|
5885
|
-
const fullPath =
|
|
5718
|
+
const fullPath = path21.join(dir2, entry.name);
|
|
5886
5719
|
if (entry.isDirectory()) {
|
|
5887
5720
|
walk(fullPath);
|
|
5888
|
-
} else if (extSet.has(
|
|
5721
|
+
} else if (extSet.has(path21.extname(entry.name).toLowerCase())) {
|
|
5889
5722
|
results.push(fullPath);
|
|
5890
5723
|
}
|
|
5891
5724
|
}
|
|
@@ -5897,31 +5730,31 @@ function collectTextFiles(dir, max) {
|
|
|
5897
5730
|
}
|
|
5898
5731
|
function readFileSafe(filePath) {
|
|
5899
5732
|
try {
|
|
5900
|
-
const stats =
|
|
5733
|
+
const stats = fs22.statSync(filePath);
|
|
5901
5734
|
if (stats.size > 5e5) return null;
|
|
5902
|
-
return
|
|
5735
|
+
return fs22.readFileSync(filePath, "utf-8");
|
|
5903
5736
|
} catch {
|
|
5904
5737
|
return null;
|
|
5905
5738
|
}
|
|
5906
5739
|
}
|
|
5907
5740
|
function printSemanticResults(results, query) {
|
|
5908
|
-
const lines = [
|
|
5741
|
+
const lines = [chalk31.bold(`
|
|
5909
5742
|
Semantic Search: "${query}"`), ""];
|
|
5910
5743
|
if (results.length === 0) {
|
|
5911
|
-
lines.push(
|
|
5744
|
+
lines.push(chalk31.dim(" No results found."));
|
|
5912
5745
|
lines.push("");
|
|
5913
5746
|
return lines.join("\n");
|
|
5914
5747
|
}
|
|
5915
5748
|
for (let i = 0; i < results.length; i++) {
|
|
5916
5749
|
const r = results[i];
|
|
5917
5750
|
const barLen = Math.round(r.score * 30);
|
|
5918
|
-
const bar =
|
|
5919
|
-
lines.push(` ${
|
|
5920
|
-
lines.push(` ${bar} ${
|
|
5751
|
+
const bar = chalk31.cyan("\u2588".repeat(barLen)) + chalk31.dim("\u2591".repeat(30 - barLen));
|
|
5752
|
+
lines.push(` ${chalk31.cyan(String(i + 1).padEnd(3))} ${chalk31.dim(r.relativePath)}`);
|
|
5753
|
+
lines.push(` ${bar} ${chalk31.bold(String(Math.round(r.score * 100)))}%`);
|
|
5921
5754
|
if (r.matches.length > 0) {
|
|
5922
5755
|
const top = r.matches.slice(0, 2);
|
|
5923
5756
|
for (const m of top) {
|
|
5924
|
-
lines.push(` ${
|
|
5757
|
+
lines.push(` ${chalk31.dim(`L${m.line}:`)} ${m.content.slice(0, 100)}`);
|
|
5925
5758
|
}
|
|
5926
5759
|
}
|
|
5927
5760
|
}
|
|
@@ -5937,27 +5770,27 @@ var analyzeCommand = new Command10("analyze").alias("a").description("Analyze an
|
|
|
5937
5770
|
})
|
|
5938
5771
|
).addCommand(
|
|
5939
5772
|
new Command10("deps").alias("d").description("Analyze dependencies and import graph").option("--dir <path>", "Project directory", process.cwd()).action((options) => {
|
|
5940
|
-
console.log(
|
|
5773
|
+
console.log(chalk32.dim("\n Analyzing dependencies..."));
|
|
5941
5774
|
const graph = analyzeDependencies(options.dir);
|
|
5942
5775
|
console.log(printDepGraph(graph));
|
|
5943
5776
|
const circles = findCircularDeps(graph);
|
|
5944
5777
|
if (circles.length > 0) {
|
|
5945
|
-
console.log(
|
|
5778
|
+
console.log(chalk32.yellow(` \u26A0 Found ${circles.length} circular dependenc${circles.length > 1 ? "ies" : "y"}`));
|
|
5946
5779
|
for (const circle of circles.slice(0, 5)) {
|
|
5947
|
-
console.log(` ${
|
|
5780
|
+
console.log(` ${chalk32.red("\u21BB")} ${circle.join(" \u2192 ")}`);
|
|
5948
5781
|
}
|
|
5949
5782
|
console.log("");
|
|
5950
5783
|
}
|
|
5951
5784
|
})
|
|
5952
5785
|
).addCommand(
|
|
5953
5786
|
new Command10("summary").alias("s").description("Generate a full repo architecture summary").option("--dir <path>", "Project directory", process.cwd()).action((options) => {
|
|
5954
|
-
console.log(
|
|
5787
|
+
console.log(chalk32.dim("\n Generating repository summary...\n"));
|
|
5955
5788
|
const summary = generateSummary(options.dir);
|
|
5956
5789
|
console.log(printSummary(summary));
|
|
5957
5790
|
})
|
|
5958
5791
|
).addCommand(
|
|
5959
5792
|
new Command10("search").alias("q").description("Semantically search code in the repository").argument("<query>", "The search query").option("--dir <path>", "Project directory", process.cwd()).option("--max <number>", "Maximum results", "10").action(async (query, options) => {
|
|
5960
|
-
console.log(
|
|
5793
|
+
console.log(chalk32.dim(`
|
|
5961
5794
|
Searching for: "${query}"
|
|
5962
5795
|
`));
|
|
5963
5796
|
const results = await semanticSearch2(options.dir, query, {
|
|
@@ -5983,36 +5816,36 @@ var analyzeCommand = new Command10("analyze").alias("a").description("Analyze an
|
|
|
5983
5816
|
|
|
5984
5817
|
// src/commands/memory.ts
|
|
5985
5818
|
import { Command as Command11 } from "commander";
|
|
5986
|
-
import
|
|
5819
|
+
import chalk33 from "chalk";
|
|
5987
5820
|
async function cmdSessions(options) {
|
|
5988
5821
|
const sessions = listSessions(options.dir);
|
|
5989
5822
|
if (sessions.length === 0) {
|
|
5990
|
-
console.log(
|
|
5823
|
+
console.log(chalk33.yellow("No sessions found."));
|
|
5991
5824
|
return;
|
|
5992
5825
|
}
|
|
5993
|
-
console.log(
|
|
5826
|
+
console.log(chalk33.bold(`
|
|
5994
5827
|
Sessions (${sessions.length}):
|
|
5995
5828
|
`));
|
|
5996
5829
|
for (const s of sessions) {
|
|
5997
5830
|
const date = new Date(s.updated).toLocaleString();
|
|
5998
5831
|
const msgCount = s.entries.length;
|
|
5999
|
-
console.log(` ${
|
|
6000
|
-
console.log(` ${
|
|
5832
|
+
console.log(` ${chalk33.cyan(s.id.slice(0, 12))} ${chalk33.bold(s.title)}`);
|
|
5833
|
+
console.log(` ${chalk33.dim(`${msgCount} msgs \u2022 ${date} \u2022 ${s.model}`)}`);
|
|
6001
5834
|
}
|
|
6002
5835
|
}
|
|
6003
5836
|
async function cmdShowSession(id, options) {
|
|
6004
5837
|
const session = loadSession(id, options.dir);
|
|
6005
5838
|
if (!session) {
|
|
6006
|
-
console.log(
|
|
5839
|
+
console.log(chalk33.red(`Session "${id}" not found.`));
|
|
6007
5840
|
return;
|
|
6008
5841
|
}
|
|
6009
|
-
console.log(
|
|
5842
|
+
console.log(chalk33.bold(`
|
|
6010
5843
|
Session: ${session.title}`));
|
|
6011
|
-
console.log(
|
|
6012
|
-
console.log(
|
|
5844
|
+
console.log(chalk33.dim(` ID: ${session.id} \u2022 Model: ${session.model} \u2022 ${session.entries.length} messages`));
|
|
5845
|
+
console.log(chalk33.dim(` Created: ${new Date(session.created).toLocaleString()}`));
|
|
6013
5846
|
console.log("");
|
|
6014
5847
|
for (const entry of session.entries.slice(-20)) {
|
|
6015
|
-
const role = entry.role === "user" ?
|
|
5848
|
+
const role = entry.role === "user" ? chalk33.green("You") : entry.role === "assistant" ? chalk33.cyan("LoveCode") : chalk33.yellow("System");
|
|
6016
5849
|
const preview = entry.content.length > 200 ? entry.content.slice(0, 200) + "..." : entry.content;
|
|
6017
5850
|
console.log(` ${role}: ${preview}
|
|
6018
5851
|
`);
|
|
@@ -6021,15 +5854,15 @@ async function cmdShowSession(id, options) {
|
|
|
6021
5854
|
async function cmdSearchSessions(query, options) {
|
|
6022
5855
|
const results = searchSessions(query, options.dir);
|
|
6023
5856
|
if (results.length === 0) {
|
|
6024
|
-
console.log(
|
|
5857
|
+
console.log(chalk33.yellow(`No sessions matching "${query}".`));
|
|
6025
5858
|
return;
|
|
6026
5859
|
}
|
|
6027
|
-
console.log(
|
|
5860
|
+
console.log(chalk33.bold(`
|
|
6028
5861
|
Search results for "${query}" (${results.length}):
|
|
6029
5862
|
`));
|
|
6030
5863
|
for (const s of results) {
|
|
6031
5864
|
const date = new Date(s.updated).toLocaleString();
|
|
6032
|
-
console.log(` ${
|
|
5865
|
+
console.log(` ${chalk33.cyan(s.id.slice(0, 12))} ${chalk33.bold(s.title)} ${chalk33.dim(date)}`);
|
|
6033
5866
|
}
|
|
6034
5867
|
}
|
|
6035
5868
|
async function cmdPreferences(options) {
|
|
@@ -6049,7 +5882,7 @@ async function cmdPreferences(options) {
|
|
|
6049
5882
|
else prefs[k] = v;
|
|
6050
5883
|
}
|
|
6051
5884
|
const saved = savePreferences(prefs, options.dir);
|
|
6052
|
-
console.log(
|
|
5885
|
+
console.log(chalk33.green("Preferences updated:"));
|
|
6053
5886
|
console.log(formatPreferences(saved));
|
|
6054
5887
|
} else {
|
|
6055
5888
|
const prefs = getPreferences(options.dir);
|
|
@@ -6059,7 +5892,7 @@ async function cmdPreferences(options) {
|
|
|
6059
5892
|
async function cmdRepoMemory(options) {
|
|
6060
5893
|
if (options.note) {
|
|
6061
5894
|
const updated = addRepoNote(options.note, options.dir);
|
|
6062
|
-
console.log(
|
|
5895
|
+
console.log(chalk33.green("Note added to repo memory."));
|
|
6063
5896
|
console.log(formatRepoMemory(updated));
|
|
6064
5897
|
} else {
|
|
6065
5898
|
const mem = getRepoMemory(options.dir);
|
|
@@ -6079,31 +5912,31 @@ async function cmdWorkflows(options) {
|
|
|
6079
5912
|
used: Date.now()
|
|
6080
5913
|
};
|
|
6081
5914
|
saveWorkflow(workflow, options.dir);
|
|
6082
|
-
console.log(
|
|
5915
|
+
console.log(chalk33.green(`Workflow "${options.name}" saved (${steps.length} steps).`));
|
|
6083
5916
|
return;
|
|
6084
5917
|
}
|
|
6085
5918
|
if (options.delete) {
|
|
6086
5919
|
const ok = deleteWorkflow(options.delete, options.dir);
|
|
6087
|
-
console.log(ok ?
|
|
5920
|
+
console.log(ok ? chalk33.green(`Workflow "${options.delete}" deleted.`) : chalk33.yellow(`Workflow "${options.delete}" not found.`));
|
|
6088
5921
|
return;
|
|
6089
5922
|
}
|
|
6090
5923
|
if (wf.workflows.length === 0) {
|
|
6091
|
-
console.log(
|
|
5924
|
+
console.log(chalk33.yellow("No saved workflows."));
|
|
6092
5925
|
return;
|
|
6093
5926
|
}
|
|
6094
|
-
console.log(
|
|
5927
|
+
console.log(chalk33.bold(`
|
|
6095
5928
|
Workflows (${wf.workflows.length}):
|
|
6096
5929
|
`));
|
|
6097
5930
|
for (const w of wf.workflows) {
|
|
6098
5931
|
const date = new Date(w.used).toLocaleString();
|
|
6099
|
-
console.log(` ${
|
|
6100
|
-
console.log(` ${
|
|
5932
|
+
console.log(` ${chalk33.cyan(w.name)} ${chalk33.dim(w.description || "(no description)")}`);
|
|
5933
|
+
console.log(` ${chalk33.dim(`${w.steps.length} steps \u2022 last used ${date}`)}`);
|
|
6101
5934
|
}
|
|
6102
5935
|
}
|
|
6103
5936
|
async function cmdVectorStore(options) {
|
|
6104
5937
|
if (options.clear) {
|
|
6105
5938
|
clearVectors(options.dir);
|
|
6106
|
-
console.log(
|
|
5939
|
+
console.log(chalk33.green("Vector memory cleared."));
|
|
6107
5940
|
return;
|
|
6108
5941
|
}
|
|
6109
5942
|
if (options.count) {
|
|
@@ -6112,8 +5945,8 @@ async function cmdVectorStore(options) {
|
|
|
6112
5945
|
}
|
|
6113
5946
|
if (options.store) {
|
|
6114
5947
|
const entry = await storeVector(options.store, {}, options.dir);
|
|
6115
|
-
console.log(
|
|
6116
|
-
console.log(
|
|
5948
|
+
console.log(chalk33.green(`Stored: "${options.store.slice(0, 80)}..."`));
|
|
5949
|
+
console.log(chalk33.dim(` ID: ${entry.id}`));
|
|
6117
5950
|
return;
|
|
6118
5951
|
}
|
|
6119
5952
|
if (options.query) {
|
|
@@ -6121,32 +5954,32 @@ async function cmdVectorStore(options) {
|
|
|
6121
5954
|
console.log(formatVectorResults(results));
|
|
6122
5955
|
return;
|
|
6123
5956
|
}
|
|
6124
|
-
console.log(
|
|
5957
|
+
console.log(chalk33.yellow("Specify --query, --store, --count, or --clear."));
|
|
6125
5958
|
}
|
|
6126
5959
|
async function cmdChatLogs(options) {
|
|
6127
5960
|
const logs = listChatLogs(options.dir);
|
|
6128
5961
|
if (logs.length === 0) {
|
|
6129
|
-
console.log(
|
|
5962
|
+
console.log(chalk33.yellow("No chat logs found."));
|
|
6130
5963
|
return;
|
|
6131
5964
|
}
|
|
6132
5965
|
const totalSize = logs.reduce((acc, l) => acc + l.size, 0);
|
|
6133
5966
|
const sizeStr = totalSize > 1024 ? `${(totalSize / 1024).toFixed(1)} KB` : `${totalSize} B`;
|
|
6134
|
-
console.log(
|
|
5967
|
+
console.log(chalk33.bold(`
|
|
6135
5968
|
Chat Logs (${logs.length}, ${sizeStr}):
|
|
6136
5969
|
`));
|
|
6137
5970
|
for (const log of logs.slice(0, 20)) {
|
|
6138
5971
|
const date = log.modified.toLocaleString();
|
|
6139
5972
|
const size = log.size > 1024 ? `${(log.size / 1024).toFixed(1)} KB` : `${log.size} B`;
|
|
6140
|
-
console.log(` ${
|
|
5973
|
+
console.log(` ${chalk33.dim(log.name.slice(0, 50).padEnd(52))} ${chalk33.yellow(size.padStart(8))} ${chalk33.dim(date)}`);
|
|
6141
5974
|
}
|
|
6142
5975
|
if (logs.length > 20) {
|
|
6143
|
-
console.log(
|
|
5976
|
+
console.log(chalk33.dim(` ... and ${logs.length - 20} more`));
|
|
6144
5977
|
}
|
|
6145
5978
|
}
|
|
6146
5979
|
async function cmdClearAll(options) {
|
|
6147
5980
|
clearAllMemory(options.dir);
|
|
6148
5981
|
clearVectors(options.dir);
|
|
6149
|
-
console.log(
|
|
5982
|
+
console.log(chalk33.green("All memory data cleared."));
|
|
6150
5983
|
}
|
|
6151
5984
|
var memoryCommand = new Command11("memory").alias("mem").description("Manage sessions, memory, and chat logs").option("--dir <path>", "Project directory", process.cwd()).addCommand(
|
|
6152
5985
|
new Command11("sessions").alias("s").description("List all persistent sessions").option("--dir <path>", "Project directory").action(cmdSessions)
|
|
@@ -6188,14 +6021,14 @@ var memoryCommand = new Command11("memory").alias("mem").description("Manage ses
|
|
|
6188
6021
|
|
|
6189
6022
|
// src/commands/git.ts
|
|
6190
6023
|
import { Command as Command12 } from "commander";
|
|
6191
|
-
import
|
|
6024
|
+
import chalk34 from "chalk";
|
|
6192
6025
|
function requireGit(cwd) {
|
|
6193
6026
|
if (!isGitAvailable()) {
|
|
6194
|
-
console.log(
|
|
6027
|
+
console.log(chalk34.red(" \u2717 Git is not installed or not in PATH."));
|
|
6195
6028
|
return false;
|
|
6196
6029
|
}
|
|
6197
6030
|
if (!isRepo(cwd)) {
|
|
6198
|
-
console.log(
|
|
6031
|
+
console.log(chalk34.red(" \u2717 Not a git repository."));
|
|
6199
6032
|
return false;
|
|
6200
6033
|
}
|
|
6201
6034
|
return true;
|
|
@@ -6209,39 +6042,39 @@ async function cmdCommit(opts) {
|
|
|
6209
6042
|
}
|
|
6210
6043
|
const status = getStatus(root || dir);
|
|
6211
6044
|
if (status.clean && !opts.message) {
|
|
6212
|
-
console.log(
|
|
6045
|
+
console.log(chalk34.yellow(" Nothing to commit. Working tree clean."));
|
|
6213
6046
|
return;
|
|
6214
6047
|
}
|
|
6215
6048
|
let commitMessage = opts.message;
|
|
6216
6049
|
if (!commitMessage && opts.generate) {
|
|
6217
|
-
console.log(
|
|
6050
|
+
console.log(chalk34.dim(" Generating commit message..."));
|
|
6218
6051
|
commitMessage = await generateCommitMessage();
|
|
6219
|
-
console.log(
|
|
6052
|
+
console.log(chalk34.cyan(` Generated: ${commitMessage.split("\n")[0]}
|
|
6220
6053
|
`));
|
|
6221
6054
|
}
|
|
6222
6055
|
if (!commitMessage) {
|
|
6223
|
-
console.log(
|
|
6224
|
-
console.log(
|
|
6225
|
-
console.log(
|
|
6226
|
-
console.log(
|
|
6056
|
+
console.log(chalk34.yellow(" No commit message provided. Use --message or --generate."));
|
|
6057
|
+
console.log(chalk34.dim(" Examples:"));
|
|
6058
|
+
console.log(chalk34.dim(' lovecode commit -m "feat: add login"'));
|
|
6059
|
+
console.log(chalk34.dim(" lovecode commit --generate"));
|
|
6227
6060
|
return;
|
|
6228
6061
|
}
|
|
6229
6062
|
if (opts.all) {
|
|
6230
|
-
console.log(
|
|
6063
|
+
console.log(chalk34.dim(" Staging all changes..."));
|
|
6231
6064
|
}
|
|
6232
6065
|
const result = commit(commitMessage, root || dir);
|
|
6233
6066
|
if (result.success) {
|
|
6234
|
-
console.log(
|
|
6067
|
+
console.log(chalk34.green(` \u2713 Committed${result.hash ? ` (${result.hash.slice(0, 8)})` : ""}`));
|
|
6235
6068
|
if (result.output) {
|
|
6236
6069
|
const lines = result.output.split("\n").filter(Boolean);
|
|
6237
6070
|
for (const line of lines) {
|
|
6238
6071
|
if (line.includes("changed") || line.includes("insertion") || line.includes("deletion")) {
|
|
6239
|
-
console.log(
|
|
6072
|
+
console.log(chalk34.dim(` ${line}`));
|
|
6240
6073
|
}
|
|
6241
6074
|
}
|
|
6242
6075
|
}
|
|
6243
6076
|
} else {
|
|
6244
|
-
console.log(
|
|
6077
|
+
console.log(chalk34.red(` \u2717 ${result.output}`));
|
|
6245
6078
|
}
|
|
6246
6079
|
}
|
|
6247
6080
|
async function cmdStatus(options) {
|
|
@@ -6249,8 +6082,8 @@ async function cmdStatus(options) {
|
|
|
6249
6082
|
const dir = options.dir || process.cwd();
|
|
6250
6083
|
const root = getGitRoot(dir);
|
|
6251
6084
|
const status = getStatus(root || dir);
|
|
6252
|
-
console.log(
|
|
6253
|
-
Git Status \u2014 ${
|
|
6085
|
+
console.log(chalk34.bold(`
|
|
6086
|
+
Git Status \u2014 ${chalk34.cyan(status.branch)}`));
|
|
6254
6087
|
console.log(` ${formatStatus(status)}`);
|
|
6255
6088
|
console.log("");
|
|
6256
6089
|
}
|
|
@@ -6260,39 +6093,39 @@ async function cmdBranch(action, name, options) {
|
|
|
6260
6093
|
const gitRoot = getGitRoot(dir);
|
|
6261
6094
|
if (!action || action === "list") {
|
|
6262
6095
|
const branches = getBranches(gitRoot || dir);
|
|
6263
|
-
console.log(
|
|
6096
|
+
console.log(chalk34.bold(`
|
|
6264
6097
|
Branches (${branches.length}):`));
|
|
6265
6098
|
console.log(` ${formatBranches(branches)}`);
|
|
6266
6099
|
console.log("");
|
|
6267
6100
|
return;
|
|
6268
6101
|
}
|
|
6269
6102
|
if (!name) {
|
|
6270
|
-
console.log(
|
|
6103
|
+
console.log(chalk34.yellow(" Branch name required."));
|
|
6271
6104
|
return;
|
|
6272
6105
|
}
|
|
6273
6106
|
switch (action) {
|
|
6274
6107
|
case "create": {
|
|
6275
6108
|
const ok = createBranch(name, gitRoot || dir);
|
|
6276
|
-
console.log(ok ?
|
|
6109
|
+
console.log(ok ? chalk34.green(` \u2713 Created and switched to "${name}"`) : chalk34.red(` \u2717 Failed to create branch "${name}"`));
|
|
6277
6110
|
break;
|
|
6278
6111
|
}
|
|
6279
6112
|
case "switch": {
|
|
6280
6113
|
const result = switchBranch(name, gitRoot || dir);
|
|
6281
|
-
console.log(result.success ?
|
|
6114
|
+
console.log(result.success ? chalk34.green(` \u2713 Switched to "${name}"`) : chalk34.red(` \u2717 ${result.output}`));
|
|
6282
6115
|
break;
|
|
6283
6116
|
}
|
|
6284
6117
|
case "delete": {
|
|
6285
6118
|
const result = deleteBranch(name, options.force, gitRoot || dir);
|
|
6286
|
-
console.log(result.success ?
|
|
6119
|
+
console.log(result.success ? chalk34.green(` \u2713 Deleted branch "${name}"`) : chalk34.red(` \u2717 ${result.output}`));
|
|
6287
6120
|
break;
|
|
6288
6121
|
}
|
|
6289
6122
|
case "cleanup": {
|
|
6290
|
-
console.log(
|
|
6123
|
+
console.log(chalk34.dim(" Cleaning up merged branches..."));
|
|
6291
6124
|
const deleted = cleanupMergedBranches(gitRoot || dir);
|
|
6292
6125
|
if (deleted.length === 0) {
|
|
6293
|
-
console.log(
|
|
6126
|
+
console.log(chalk34.yellow(" No merged branches to clean up."));
|
|
6294
6127
|
} else {
|
|
6295
|
-
console.log(
|
|
6128
|
+
console.log(chalk34.green(` \u2713 Deleted ${deleted.length} merged branc${deleted.length > 1 ? "hes" : "h"}:`));
|
|
6296
6129
|
for (const b of deleted) {
|
|
6297
6130
|
console.log(` \u2022 ${b}`);
|
|
6298
6131
|
}
|
|
@@ -6300,7 +6133,7 @@ async function cmdBranch(action, name, options) {
|
|
|
6300
6133
|
break;
|
|
6301
6134
|
}
|
|
6302
6135
|
default:
|
|
6303
|
-
console.log(
|
|
6136
|
+
console.log(chalk34.yellow(` Unknown action: ${action}. Use: create, switch, delete, cleanup, or list.`));
|
|
6304
6137
|
}
|
|
6305
6138
|
}
|
|
6306
6139
|
async function cmdLog(options) {
|
|
@@ -6310,10 +6143,10 @@ async function cmdLog(options) {
|
|
|
6310
6143
|
const count = parseInt(options.count || "10", 10);
|
|
6311
6144
|
const log = getLog(count, root || dir);
|
|
6312
6145
|
if (log.length === 0) {
|
|
6313
|
-
console.log(
|
|
6146
|
+
console.log(chalk34.yellow(" No commits found."));
|
|
6314
6147
|
return;
|
|
6315
6148
|
}
|
|
6316
|
-
console.log(
|
|
6149
|
+
console.log(chalk34.bold(`
|
|
6317
6150
|
Recent Commits (${log.length}):`));
|
|
6318
6151
|
console.log(` ${formatLog(log)}`);
|
|
6319
6152
|
console.log("");
|
|
@@ -6321,7 +6154,7 @@ async function cmdLog(options) {
|
|
|
6321
6154
|
async function cmdPRSummary(baseBranch, options) {
|
|
6322
6155
|
if (!requireGit(options.dir)) return;
|
|
6323
6156
|
const base = baseBranch || "main";
|
|
6324
|
-
console.log(
|
|
6157
|
+
console.log(chalk34.dim(` Generating PR summary (${base}...HEAD)...`));
|
|
6325
6158
|
const summary = await generatePRSummary(base);
|
|
6326
6159
|
console.log(`
|
|
6327
6160
|
${summary}
|
|
@@ -6345,21 +6178,21 @@ async function cmdDiff(options) {
|
|
|
6345
6178
|
if (!requireGit(options.dir)) return;
|
|
6346
6179
|
const dir = options.dir || process.cwd();
|
|
6347
6180
|
const root = getGitRoot(dir);
|
|
6348
|
-
const diff = options.staged ? (await import("./git-
|
|
6181
|
+
const diff = options.staged ? (await import("./git-FZPRJVFI.js")).getStagedDiff(root || dir) : getDiff(root || dir);
|
|
6349
6182
|
if (!diff) {
|
|
6350
|
-
console.log(
|
|
6183
|
+
console.log(chalk34.yellow(" No changes to show."));
|
|
6351
6184
|
return;
|
|
6352
6185
|
}
|
|
6353
6186
|
const lines = diff.split("\n");
|
|
6354
6187
|
for (const line of lines) {
|
|
6355
6188
|
if (line.startsWith("+")) {
|
|
6356
|
-
process.stdout.write(
|
|
6189
|
+
process.stdout.write(chalk34.green(line) + "\n");
|
|
6357
6190
|
} else if (line.startsWith("-")) {
|
|
6358
|
-
process.stdout.write(
|
|
6191
|
+
process.stdout.write(chalk34.red(line) + "\n");
|
|
6359
6192
|
} else if (line.startsWith("@@")) {
|
|
6360
|
-
process.stdout.write(
|
|
6193
|
+
process.stdout.write(chalk34.cyan(line) + "\n");
|
|
6361
6194
|
} else if (line.startsWith("diff --git")) {
|
|
6362
|
-
process.stdout.write(
|
|
6195
|
+
process.stdout.write(chalk34.bold(line) + "\n");
|
|
6363
6196
|
} else {
|
|
6364
6197
|
process.stdout.write(line + "\n");
|
|
6365
6198
|
}
|
|
@@ -6403,7 +6236,7 @@ gitCommand.command("diff").description("Show diff").option("--staged", "Show sta
|
|
|
6403
6236
|
|
|
6404
6237
|
// src/commands/tui.ts
|
|
6405
6238
|
import { Command as Command13 } from "commander";
|
|
6406
|
-
import
|
|
6239
|
+
import chalk35 from "chalk";
|
|
6407
6240
|
|
|
6408
6241
|
// src/tui/index.ts
|
|
6409
6242
|
import React4 from "react";
|
|
@@ -6842,6 +6675,34 @@ function App({
|
|
|
6842
6675
|
setFocus(focus === "chat" ? "command" : focus === "command" ? "repo" : focus === "repo" ? "chat" : "chat");
|
|
6843
6676
|
}
|
|
6844
6677
|
});
|
|
6678
|
+
async function handleConnect() {
|
|
6679
|
+
try {
|
|
6680
|
+
const { getAllProviders } = await import("./registry-ADSIKXA4.js");
|
|
6681
|
+
const { loadConfig: loadConfig2 } = await import("./config-FJNTTKR3.js");
|
|
6682
|
+
const { loadEnv: loadEnv2 } = await import("./env-HJQWWL6N.js");
|
|
6683
|
+
loadEnv2();
|
|
6684
|
+
const providers = getAllProviders();
|
|
6685
|
+
const config = loadConfig2();
|
|
6686
|
+
let info = "\u26A1 **Connect to an AI Provider**\n\n";
|
|
6687
|
+
info += "**Current config:**\n";
|
|
6688
|
+
info += ` Provider: ${config.provider || "not set"}
|
|
6689
|
+
`;
|
|
6690
|
+
info += ` Model: ${config.model || "not set"}
|
|
6691
|
+
|
|
6692
|
+
`;
|
|
6693
|
+
info += "**Available providers:**\n";
|
|
6694
|
+
for (const p of providers) {
|
|
6695
|
+
const tag = p.local ? "(local)" : "(cloud)";
|
|
6696
|
+
const configured = config.provider === p.name ? " \u2190 active" : "";
|
|
6697
|
+
info += ` ${p.name} ${tag}${configured}
|
|
6698
|
+
`;
|
|
6699
|
+
}
|
|
6700
|
+
info += "\n**To configure:** use `lovecode init` in your terminal, then restart TUI";
|
|
6701
|
+
setMessages((prev) => [...prev, { role: "assistant", content: info }]);
|
|
6702
|
+
} catch (err) {
|
|
6703
|
+
setMessages((prev) => [...prev, { role: "system", content: `Error loading providers: ${err.message}` }]);
|
|
6704
|
+
}
|
|
6705
|
+
}
|
|
6845
6706
|
async function handleSend(text) {
|
|
6846
6707
|
const userMsg = { role: "user", content: text };
|
|
6847
6708
|
setMessages((prev) => [...prev, userMsg]);
|
|
@@ -6866,7 +6727,9 @@ function App({
|
|
|
6866
6727
|
function handleCommand(text) {
|
|
6867
6728
|
const cmd = text.slice(1).toLowerCase();
|
|
6868
6729
|
if (cmd === "help") {
|
|
6869
|
-
setMessages((prev) => [...prev, { role: "system", content: "Commands: /help, /clear, /theme <name>, /vim, /exit" }]);
|
|
6730
|
+
setMessages((prev) => [...prev, { role: "system", content: "Commands: /help, /clear, /theme <name>, /connect, /vim, /exit" }]);
|
|
6731
|
+
} else if (cmd === "connect") {
|
|
6732
|
+
handleConnect();
|
|
6870
6733
|
} else if (cmd === "clear") {
|
|
6871
6734
|
setMessages([]);
|
|
6872
6735
|
} else if (cmd.startsWith("theme ")) {
|
|
@@ -6964,7 +6827,7 @@ function startTUI(props) {
|
|
|
6964
6827
|
|
|
6965
6828
|
// src/commands/tui.ts
|
|
6966
6829
|
async function cmdTUI(options) {
|
|
6967
|
-
console.log(
|
|
6830
|
+
console.log(chalk35.dim("Starting LoveCode TUI..."));
|
|
6968
6831
|
if (options.theme) {
|
|
6969
6832
|
const mod = await import("./theme-ZRZYRB2Q.js");
|
|
6970
6833
|
const names = mod.getThemeNames();
|
|
@@ -6973,7 +6836,7 @@ async function cmdTUI(options) {
|
|
|
6973
6836
|
if (names.includes(themeName)) {
|
|
6974
6837
|
mod.setTheme(n);
|
|
6975
6838
|
} else {
|
|
6976
|
-
console.log(
|
|
6839
|
+
console.log(chalk35.yellow(`Unknown theme "${options.theme}". Using default. Available: ${names.join(", ")}`));
|
|
6977
6840
|
}
|
|
6978
6841
|
}
|
|
6979
6842
|
startTUI({
|
|
@@ -7013,7 +6876,7 @@ var tuiCommand = new Command13("tui").alias("ui").description("Launch the Termin
|
|
|
7013
6876
|
|
|
7014
6877
|
// src/commands/plugin.ts
|
|
7015
6878
|
import { Command as Command14 } from "commander";
|
|
7016
|
-
import
|
|
6879
|
+
import chalk36 from "chalk";
|
|
7017
6880
|
async function cmdListPlugins() {
|
|
7018
6881
|
const { listPlugins: listPlugins2, formatPluginList } = await import("./registry-MW5ISDO7.js");
|
|
7019
6882
|
const plugins = listPlugins2();
|
|
@@ -7022,12 +6885,12 @@ async function cmdListPlugins() {
|
|
|
7022
6885
|
async function cmdEnablePlugin(name) {
|
|
7023
6886
|
const { enablePlugin: enablePlugin2 } = await import("./registry-MW5ISDO7.js");
|
|
7024
6887
|
const ok = enablePlugin2(name);
|
|
7025
|
-
console.log(ok ?
|
|
6888
|
+
console.log(ok ? chalk36.green(`Enabled plugin: ${name}`) : chalk36.red(`Plugin not found: ${name}`));
|
|
7026
6889
|
}
|
|
7027
6890
|
async function cmdDisablePlugin(name) {
|
|
7028
6891
|
const { disablePlugin: disablePlugin2 } = await import("./registry-MW5ISDO7.js");
|
|
7029
6892
|
const ok = disablePlugin2(name);
|
|
7030
|
-
console.log(ok ?
|
|
6893
|
+
console.log(ok ? chalk36.yellow(`Disabled plugin: ${name}`) : chalk36.red(`Plugin not found: ${name}`));
|
|
7031
6894
|
}
|
|
7032
6895
|
async function cmdSearchMarketplace(query) {
|
|
7033
6896
|
const { searchMarketplace, formatMarketplace } = await import("./registry-MW5ISDO7.js");
|
|
@@ -7048,37 +6911,37 @@ pluginCommand.command("search").description("Search plugin marketplace").argumen
|
|
|
7048
6911
|
|
|
7049
6912
|
// src/commands/browser.ts
|
|
7050
6913
|
import { Command as Command15 } from "commander";
|
|
7051
|
-
import
|
|
6914
|
+
import chalk37 from "chalk";
|
|
7052
6915
|
async function cmdStart(options) {
|
|
7053
6916
|
const { launchBrowser } = await import("./playwright-N7OAVW2N.js");
|
|
7054
6917
|
try {
|
|
7055
6918
|
await launchBrowser({ headless: options.headless !== false });
|
|
7056
|
-
console.log(
|
|
6919
|
+
console.log(chalk37.green("Browser launched."));
|
|
7057
6920
|
} catch (err) {
|
|
7058
|
-
console.log(
|
|
6921
|
+
console.log(chalk37.red(`Failed: ${err.message}`));
|
|
7059
6922
|
}
|
|
7060
6923
|
}
|
|
7061
6924
|
async function cmdStop() {
|
|
7062
6925
|
const { closeBrowser } = await import("./playwright-N7OAVW2N.js");
|
|
7063
6926
|
await closeBrowser();
|
|
7064
|
-
console.log(
|
|
6927
|
+
console.log(chalk37.yellow("Browser closed."));
|
|
7065
6928
|
}
|
|
7066
6929
|
async function cmdGoto(url) {
|
|
7067
6930
|
const { goto: goto2 } = await import("./playwright-N7OAVW2N.js");
|
|
7068
6931
|
try {
|
|
7069
6932
|
const result = await goto2(url);
|
|
7070
|
-
console.log(
|
|
6933
|
+
console.log(chalk37.green(result));
|
|
7071
6934
|
} catch (err) {
|
|
7072
|
-
console.log(
|
|
6935
|
+
console.log(chalk37.red(`Error: ${err.message}`));
|
|
7073
6936
|
}
|
|
7074
6937
|
}
|
|
7075
6938
|
async function cmdClick(selector) {
|
|
7076
6939
|
const { click: click2 } = await import("./playwright-N7OAVW2N.js");
|
|
7077
6940
|
try {
|
|
7078
6941
|
const result = await click2(selector);
|
|
7079
|
-
console.log(
|
|
6942
|
+
console.log(chalk37.green(result));
|
|
7080
6943
|
} catch (err) {
|
|
7081
|
-
console.log(
|
|
6944
|
+
console.log(chalk37.red(`Error: ${err.message}`));
|
|
7082
6945
|
}
|
|
7083
6946
|
}
|
|
7084
6947
|
async function cmdType(selector, text, options) {
|
|
@@ -7086,18 +6949,18 @@ async function cmdType(selector, text, options) {
|
|
|
7086
6949
|
const value = text || options.text || "";
|
|
7087
6950
|
try {
|
|
7088
6951
|
const result = await type2(selector, value);
|
|
7089
|
-
console.log(
|
|
6952
|
+
console.log(chalk37.green(result));
|
|
7090
6953
|
} catch (err) {
|
|
7091
|
-
console.log(
|
|
6954
|
+
console.log(chalk37.red(`Error: ${err.message}`));
|
|
7092
6955
|
}
|
|
7093
6956
|
}
|
|
7094
6957
|
async function cmdScreenshot(options) {
|
|
7095
6958
|
const { screenshot: screenshot2, formatScreenshotResult: formatScreenshotResult2 } = await import("./playwright-N7OAVW2N.js");
|
|
7096
6959
|
try {
|
|
7097
6960
|
const result = await screenshot2(options.name);
|
|
7098
|
-
console.log(
|
|
6961
|
+
console.log(chalk37.green(formatScreenshotResult2(result)));
|
|
7099
6962
|
} catch (err) {
|
|
7100
|
-
console.log(
|
|
6963
|
+
console.log(chalk37.red(`Error: ${err.message}`));
|
|
7101
6964
|
}
|
|
7102
6965
|
}
|
|
7103
6966
|
async function cmdInspect(selector) {
|
|
@@ -7107,18 +6970,18 @@ async function cmdInspect(selector) {
|
|
|
7107
6970
|
if (el) {
|
|
7108
6971
|
console.log(formatDOMElement2(el));
|
|
7109
6972
|
} else {
|
|
7110
|
-
console.log(
|
|
6973
|
+
console.log(chalk37.yellow(`Element not found: ${selector}`));
|
|
7111
6974
|
}
|
|
7112
6975
|
} catch (err) {
|
|
7113
|
-
console.log(
|
|
6976
|
+
console.log(chalk37.red(`Error: ${err.message}`));
|
|
7114
6977
|
}
|
|
7115
6978
|
}
|
|
7116
6979
|
async function cmdActions(actions, options) {
|
|
7117
6980
|
const { runActions } = await import("./playwright-N7OAVW2N.js");
|
|
7118
6981
|
let parsedActions;
|
|
7119
6982
|
if (options.file) {
|
|
7120
|
-
const
|
|
7121
|
-
const content =
|
|
6983
|
+
const fs25 = await import("fs");
|
|
6984
|
+
const content = fs25.readFileSync(options.file, "utf-8");
|
|
7122
6985
|
parsedActions = JSON.parse(content);
|
|
7123
6986
|
} else {
|
|
7124
6987
|
parsedActions = actions.map((a) => JSON.parse(a));
|
|
@@ -7126,10 +6989,10 @@ async function cmdActions(actions, options) {
|
|
|
7126
6989
|
try {
|
|
7127
6990
|
const results = await runActions(parsedActions);
|
|
7128
6991
|
for (const r of results) {
|
|
7129
|
-
console.log(
|
|
6992
|
+
console.log(chalk37.cyan(` \u2192 ${r.slice(0, 200)}`));
|
|
7130
6993
|
}
|
|
7131
6994
|
} catch (err) {
|
|
7132
|
-
console.log(
|
|
6995
|
+
console.log(chalk37.red(`Error: ${err.message}`));
|
|
7133
6996
|
}
|
|
7134
6997
|
}
|
|
7135
6998
|
var browserCommand = new Command15("browser").alias("br").description("Browser automation \u2014 Playwright-powered").addHelpText("after", `
|
|
@@ -7156,10 +7019,10 @@ browserCommand.command("actions").description("Run a sequence of browser actions
|
|
|
7156
7019
|
|
|
7157
7020
|
// src/commands/security.ts
|
|
7158
7021
|
import { Command as Command16 } from "commander";
|
|
7159
|
-
import
|
|
7022
|
+
import chalk42 from "chalk";
|
|
7160
7023
|
|
|
7161
7024
|
// src/security/risk.ts
|
|
7162
|
-
import
|
|
7025
|
+
import chalk38 from "chalk";
|
|
7163
7026
|
var COMMAND_RULES = [
|
|
7164
7027
|
{ pattern: /^rm\s+-rf\s+(\/|\/\w+|\.)/, score: 100, reason: "Destructive recursive delete" },
|
|
7165
7028
|
{ pattern: /^rm\s+-rf/, score: 80, reason: "Recursive force delete" },
|
|
@@ -7270,21 +7133,21 @@ function scoreToAction(score) {
|
|
|
7270
7133
|
}
|
|
7271
7134
|
function formatRisk(risk) {
|
|
7272
7135
|
const colors = {
|
|
7273
|
-
safe:
|
|
7274
|
-
low:
|
|
7275
|
-
medium:
|
|
7276
|
-
high:
|
|
7277
|
-
critical:
|
|
7136
|
+
safe: chalk38.green,
|
|
7137
|
+
low: chalk38.cyan,
|
|
7138
|
+
medium: chalk38.yellow,
|
|
7139
|
+
high: chalk38.red,
|
|
7140
|
+
critical: chalk38.bgRed.white
|
|
7278
7141
|
};
|
|
7279
|
-
const color = colors[risk.level] ||
|
|
7142
|
+
const color = colors[risk.level] || chalk38.dim;
|
|
7280
7143
|
const label = risk.level.toUpperCase().padEnd(10);
|
|
7281
|
-
const action = risk.suggestedAction === "auto" ?
|
|
7282
|
-
return ` ${color(label)} score=${risk.score} action=${action} ${
|
|
7144
|
+
const action = risk.suggestedAction === "auto" ? chalk38.green(risk.suggestedAction) : risk.suggestedAction === "confirm" ? chalk38.yellow(risk.suggestedAction) : chalk38.bgRed.white(` ${risk.suggestedAction} `);
|
|
7145
|
+
return ` ${color(label)} score=${risk.score} action=${action} ${chalk38.dim(risk.reasons.join(", "))}`;
|
|
7283
7146
|
}
|
|
7284
7147
|
|
|
7285
7148
|
// src/security/secrets.ts
|
|
7286
|
-
import * as
|
|
7287
|
-
import
|
|
7149
|
+
import * as fs23 from "fs";
|
|
7150
|
+
import chalk39 from "chalk";
|
|
7288
7151
|
var SECRET_RULES = [
|
|
7289
7152
|
{ type: "aws_key", pattern: /(?:AKIA|ASIA)[0-9A-Z]{16}/g, severity: "critical", description: "AWS Access Key ID" },
|
|
7290
7153
|
{ type: "gcp_key", pattern: /AIza[0-9A-Za-z\-_]{35}/g, severity: "critical", description: "GCP API Key" },
|
|
@@ -7332,7 +7195,7 @@ function scanText(text, fileName) {
|
|
|
7332
7195
|
}
|
|
7333
7196
|
function scanFile(filePath) {
|
|
7334
7197
|
try {
|
|
7335
|
-
const content =
|
|
7198
|
+
const content = fs23.readFileSync(filePath, "utf-8");
|
|
7336
7199
|
return scanText(content, filePath);
|
|
7337
7200
|
} catch {
|
|
7338
7201
|
return [];
|
|
@@ -7344,7 +7207,7 @@ function scanDirectory2(dirPath, maxFiles = 100) {
|
|
|
7344
7207
|
function walk(dir) {
|
|
7345
7208
|
if (count >= maxFiles) return;
|
|
7346
7209
|
try {
|
|
7347
|
-
const entries =
|
|
7210
|
+
const entries = fs23.readdirSync(dir, { withFileTypes: true });
|
|
7348
7211
|
for (const entry of entries) {
|
|
7349
7212
|
if (count >= maxFiles) return;
|
|
7350
7213
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist") continue;
|
|
@@ -7369,30 +7232,30 @@ function scanDirectory2(dirPath, maxFiles = 100) {
|
|
|
7369
7232
|
}
|
|
7370
7233
|
function formatSecretMatch(match) {
|
|
7371
7234
|
const severityColor = {
|
|
7372
|
-
low:
|
|
7373
|
-
medium:
|
|
7374
|
-
high:
|
|
7375
|
-
critical:
|
|
7235
|
+
low: chalk39.cyan,
|
|
7236
|
+
medium: chalk39.yellow,
|
|
7237
|
+
high: chalk39.red,
|
|
7238
|
+
critical: chalk39.bgRed.white
|
|
7376
7239
|
};
|
|
7377
|
-
const sev = severityColor[match.severity] ||
|
|
7378
|
-
const fileInfo = match.file ? `${
|
|
7240
|
+
const sev = severityColor[match.severity] || chalk39.dim;
|
|
7241
|
+
const fileInfo = match.file ? `${chalk39.dim(match.file)}:${match.line}:${match.column}` : `line ${match.line}:${match.column}`;
|
|
7379
7242
|
return ` ${sev(match.severity.toUpperCase().padEnd(10))} ${match.type.padEnd(20)} ${match.value.padEnd(30)} ${fileInfo}
|
|
7380
|
-
${
|
|
7243
|
+
${chalk39.dim(match.context)}`;
|
|
7381
7244
|
}
|
|
7382
7245
|
function formatSecretSummary(matches) {
|
|
7383
|
-
if (matches.length === 0) return
|
|
7246
|
+
if (matches.length === 0) return chalk39.green("No secrets detected.");
|
|
7384
7247
|
const bySeverity = /* @__PURE__ */ new Map();
|
|
7385
7248
|
for (const m of matches) {
|
|
7386
7249
|
const arr = bySeverity.get(m.severity) || [];
|
|
7387
7250
|
arr.push(m);
|
|
7388
7251
|
bySeverity.set(m.severity, arr);
|
|
7389
7252
|
}
|
|
7390
|
-
const lines = [
|
|
7253
|
+
const lines = [chalk39.bold(`
|
|
7391
7254
|
Secrets Detected (${matches.length}):`)];
|
|
7392
7255
|
for (const [severity, ms] of bySeverity) {
|
|
7393
7256
|
const label = severity.toUpperCase();
|
|
7394
7257
|
lines.push(`
|
|
7395
|
-
${
|
|
7258
|
+
${chalk39.bold(label)} (${ms.length}):`);
|
|
7396
7259
|
for (const m of ms.slice(0, 10)) {
|
|
7397
7260
|
lines.push(formatSecretMatch(m));
|
|
7398
7261
|
}
|
|
@@ -7402,7 +7265,7 @@ function formatSecretSummary(matches) {
|
|
|
7402
7265
|
}
|
|
7403
7266
|
|
|
7404
7267
|
// src/security/sandbox.ts
|
|
7405
|
-
import
|
|
7268
|
+
import chalk40 from "chalk";
|
|
7406
7269
|
var PROFILES = {
|
|
7407
7270
|
isolated: {
|
|
7408
7271
|
name: "isolated",
|
|
@@ -7531,10 +7394,10 @@ function checkCommand(command, cwd, profileName) {
|
|
|
7531
7394
|
return { allowed: true };
|
|
7532
7395
|
}
|
|
7533
7396
|
function formatProfile(profile) {
|
|
7534
|
-
const yes =
|
|
7535
|
-
const no =
|
|
7397
|
+
const yes = chalk40.green("\u2713");
|
|
7398
|
+
const no = chalk40.red("\u2717");
|
|
7536
7399
|
return [
|
|
7537
|
-
`${
|
|
7400
|
+
`${chalk40.bold(profile.name.toUpperCase())}`,
|
|
7538
7401
|
` Network: ${profile.allowNetwork ? yes : no}`,
|
|
7539
7402
|
` File Read: ${profile.allowFileRead ? yes : no}`,
|
|
7540
7403
|
` File Write: ${profile.allowFileWrite ? yes : no}`,
|
|
@@ -7546,9 +7409,9 @@ function formatProfile(profile) {
|
|
|
7546
7409
|
}
|
|
7547
7410
|
|
|
7548
7411
|
// src/security/permissions.ts
|
|
7549
|
-
import * as
|
|
7550
|
-
import * as
|
|
7551
|
-
import
|
|
7412
|
+
import * as fs24 from "fs";
|
|
7413
|
+
import * as path22 from "path";
|
|
7414
|
+
import chalk41 from "chalk";
|
|
7552
7415
|
var PERMISSION_FILE = ".lovecode/permissions.json";
|
|
7553
7416
|
var DEFAULT_PERMISSIONS = {
|
|
7554
7417
|
version: 1,
|
|
@@ -7564,18 +7427,18 @@ var DEFAULT_PERMISSIONS = {
|
|
|
7564
7427
|
};
|
|
7565
7428
|
var cachedPermissions = null;
|
|
7566
7429
|
function getPermPath(rootDir) {
|
|
7567
|
-
return
|
|
7430
|
+
return path22.join(rootDir || process.cwd(), PERMISSION_FILE);
|
|
7568
7431
|
}
|
|
7569
7432
|
function loadPermissions(rootDir) {
|
|
7570
7433
|
if (cachedPermissions) return cachedPermissions;
|
|
7571
7434
|
const filePath = getPermPath(rootDir);
|
|
7572
|
-
if (!
|
|
7435
|
+
if (!fs24.existsSync(filePath)) {
|
|
7573
7436
|
savePermissions(DEFAULT_PERMISSIONS, rootDir);
|
|
7574
7437
|
cachedPermissions = { ...DEFAULT_PERMISSIONS };
|
|
7575
7438
|
return cachedPermissions;
|
|
7576
7439
|
}
|
|
7577
7440
|
try {
|
|
7578
|
-
const raw =
|
|
7441
|
+
const raw = fs24.readFileSync(filePath, "utf-8");
|
|
7579
7442
|
cachedPermissions = JSON.parse(raw);
|
|
7580
7443
|
return cachedPermissions;
|
|
7581
7444
|
} catch {
|
|
@@ -7585,11 +7448,11 @@ function loadPermissions(rootDir) {
|
|
|
7585
7448
|
}
|
|
7586
7449
|
function savePermissions(perms, rootDir) {
|
|
7587
7450
|
const filePath = getPermPath(rootDir);
|
|
7588
|
-
const dir =
|
|
7589
|
-
if (!
|
|
7590
|
-
|
|
7451
|
+
const dir = path22.dirname(filePath);
|
|
7452
|
+
if (!fs24.existsSync(dir)) {
|
|
7453
|
+
fs24.mkdirSync(dir, { recursive: true });
|
|
7591
7454
|
}
|
|
7592
|
-
|
|
7455
|
+
fs24.writeFileSync(filePath, JSON.stringify(perms, null, 2), "utf-8");
|
|
7593
7456
|
cachedPermissions = perms;
|
|
7594
7457
|
}
|
|
7595
7458
|
function setDefault(key, value, rootDir) {
|
|
@@ -7655,30 +7518,30 @@ function removeTrustedSource(source, rootDir) {
|
|
|
7655
7518
|
}
|
|
7656
7519
|
function resetPermissions(rootDir) {
|
|
7657
7520
|
const filePath = getPermPath(rootDir);
|
|
7658
|
-
if (
|
|
7659
|
-
|
|
7521
|
+
if (fs24.existsSync(filePath)) {
|
|
7522
|
+
fs24.unlinkSync(filePath);
|
|
7660
7523
|
}
|
|
7661
7524
|
cachedPermissions = null;
|
|
7662
7525
|
}
|
|
7663
7526
|
function formatPermissions(perms) {
|
|
7664
|
-
const lines = [
|
|
7665
|
-
lines.push(` ${
|
|
7666
|
-
lines.push(` ${
|
|
7667
|
-
lines.push(` ${
|
|
7668
|
-
lines.push(` ${
|
|
7669
|
-
lines.push(` ${
|
|
7527
|
+
const lines = [chalk41.bold("\n Permission Settings")];
|
|
7528
|
+
lines.push(` ${chalk41.dim("File Read:")} ${formatAction(perms.defaults.fileRead)}`);
|
|
7529
|
+
lines.push(` ${chalk41.dim("File Write:")} ${formatAction(perms.defaults.fileWrite)}`);
|
|
7530
|
+
lines.push(` ${chalk41.dim("Network:")} ${formatAction(perms.defaults.networkAccess)}`);
|
|
7531
|
+
lines.push(` ${chalk41.dim("Commands:")} ${formatAction(perms.defaults.commandExecution)}`);
|
|
7532
|
+
lines.push(` ${chalk41.dim("Environment:")} ${formatAction(perms.defaults.environmentAccess)}`);
|
|
7670
7533
|
if (perms.entries.length > 0) {
|
|
7671
7534
|
lines.push(`
|
|
7672
|
-
${
|
|
7535
|
+
${chalk41.bold("Specific Permissions:")}`);
|
|
7673
7536
|
for (const e of perms.entries) {
|
|
7674
|
-
lines.push(` ${formatAction(e.action)} ${e.resource}${e.reason ? ` ${
|
|
7537
|
+
lines.push(` ${formatAction(e.action)} ${e.resource}${e.reason ? ` ${chalk41.dim(`(${e.reason})`)}` : ""}`);
|
|
7675
7538
|
}
|
|
7676
7539
|
}
|
|
7677
7540
|
if (perms.trustedSources.length > 0) {
|
|
7678
7541
|
lines.push(`
|
|
7679
|
-
${
|
|
7542
|
+
${chalk41.bold("Trusted Sources:")}`);
|
|
7680
7543
|
for (const s of perms.trustedSources) {
|
|
7681
|
-
lines.push(` ${
|
|
7544
|
+
lines.push(` ${chalk41.green("\u2713")} ${s}`);
|
|
7682
7545
|
}
|
|
7683
7546
|
}
|
|
7684
7547
|
return lines.join("\n");
|
|
@@ -7686,11 +7549,11 @@ function formatPermissions(perms) {
|
|
|
7686
7549
|
function formatAction(action) {
|
|
7687
7550
|
switch (action) {
|
|
7688
7551
|
case "allow":
|
|
7689
|
-
return
|
|
7552
|
+
return chalk41.green("ALLOW");
|
|
7690
7553
|
case "deny":
|
|
7691
|
-
return
|
|
7554
|
+
return chalk41.red("DENY");
|
|
7692
7555
|
case "ask":
|
|
7693
|
-
return
|
|
7556
|
+
return chalk41.yellow("ASK");
|
|
7694
7557
|
}
|
|
7695
7558
|
}
|
|
7696
7559
|
|
|
@@ -7699,8 +7562,8 @@ async function cmdAssessRisk(command, options) {
|
|
|
7699
7562
|
if (command) {
|
|
7700
7563
|
const risk = assessCommandRisk(command);
|
|
7701
7564
|
console.log(`
|
|
7702
|
-
${
|
|
7703
|
-
console.log(` ${
|
|
7565
|
+
${chalk42.bold("Command Risk Assessment")}`);
|
|
7566
|
+
console.log(` ${chalk42.dim(command)}`);
|
|
7704
7567
|
console.log(formatRisk(risk));
|
|
7705
7568
|
} else if (options.tool) {
|
|
7706
7569
|
let args;
|
|
@@ -7713,11 +7576,11 @@ async function cmdAssessRisk(command, options) {
|
|
|
7713
7576
|
}
|
|
7714
7577
|
const risk = assessToolRisk(options.tool, args);
|
|
7715
7578
|
console.log(`
|
|
7716
|
-
${
|
|
7717
|
-
console.log(` ${
|
|
7579
|
+
${chalk42.bold("Tool Risk Assessment")}`);
|
|
7580
|
+
console.log(` ${chalk42.dim(`${options.tool}${args ? " " + JSON.stringify(args) : ""}`)}`);
|
|
7718
7581
|
console.log(formatRisk(risk));
|
|
7719
7582
|
} else {
|
|
7720
|
-
console.log(
|
|
7583
|
+
console.log(chalk42.yellow("Provide a command string or --tool."));
|
|
7721
7584
|
}
|
|
7722
7585
|
}
|
|
7723
7586
|
async function cmdScanSecrets(options) {
|
|
@@ -7726,16 +7589,16 @@ async function cmdScanSecrets(options) {
|
|
|
7726
7589
|
console.log(formatSecretSummary(matches));
|
|
7727
7590
|
} else if (options.dir) {
|
|
7728
7591
|
const max = parseInt(options.max || "100", 10);
|
|
7729
|
-
console.log(
|
|
7592
|
+
console.log(chalk42.dim(`Scanning ${options.dir} for secrets...`));
|
|
7730
7593
|
const matches = scanDirectory2(options.dir, max);
|
|
7731
7594
|
console.log(formatSecretSummary(matches));
|
|
7732
7595
|
} else {
|
|
7733
|
-
console.log(
|
|
7596
|
+
console.log(chalk42.yellow("Provide --text or --dir."));
|
|
7734
7597
|
}
|
|
7735
7598
|
}
|
|
7736
7599
|
async function cmdProfiles() {
|
|
7737
7600
|
const profiles = listProfiles();
|
|
7738
|
-
console.log(
|
|
7601
|
+
console.log(chalk42.bold("\n Sandbox Profiles:\n"));
|
|
7739
7602
|
for (const p of profiles) {
|
|
7740
7603
|
console.log(formatProfile(p));
|
|
7741
7604
|
console.log("");
|
|
@@ -7744,35 +7607,35 @@ async function cmdProfiles() {
|
|
|
7744
7607
|
async function cmdSandbox(command, options) {
|
|
7745
7608
|
const result = checkCommand(command, process.cwd(), options.profile);
|
|
7746
7609
|
if (result.allowed) {
|
|
7747
|
-
console.log(
|
|
7748
|
-
Allowed: ${
|
|
7610
|
+
console.log(chalk42.green(`
|
|
7611
|
+
Allowed: ${chalk42.dim(command)}`));
|
|
7749
7612
|
} else {
|
|
7750
|
-
console.log(
|
|
7751
|
-
Blocked: ${
|
|
7752
|
-
console.log(` ${
|
|
7613
|
+
console.log(chalk42.red(`
|
|
7614
|
+
Blocked: ${chalk42.dim(command)}`));
|
|
7615
|
+
console.log(` ${chalk42.yellow(result.reason)}`);
|
|
7753
7616
|
}
|
|
7754
7617
|
}
|
|
7755
7618
|
async function cmdPermissions(options) {
|
|
7756
7619
|
if (options.set && options.action) {
|
|
7757
7620
|
const defaults = ["fileRead", "fileWrite", "networkAccess", "commandExecution", "environmentAccess"];
|
|
7758
7621
|
if (!defaults.includes(options.set)) {
|
|
7759
|
-
console.log(
|
|
7622
|
+
console.log(chalk42.red(`Invalid default: ${options.set}. Options: ${defaults.join(", ")}`));
|
|
7760
7623
|
return;
|
|
7761
7624
|
}
|
|
7762
7625
|
const perms = setDefault(options.set, options.action, options.dir);
|
|
7763
|
-
console.log(
|
|
7626
|
+
console.log(chalk42.green(`Default "${options.set}" set to "${options.action}".`));
|
|
7764
7627
|
console.log(formatPermissions(perms));
|
|
7765
7628
|
} else if (options.add && options.action) {
|
|
7766
7629
|
const action = options.action;
|
|
7767
7630
|
const perms = addPermission(options.add, action, void 0, options.dir);
|
|
7768
|
-
console.log(
|
|
7631
|
+
console.log(chalk42.green(`Permission added: ${options.add} \u2192 ${action}`));
|
|
7769
7632
|
console.log(formatPermissions(perms));
|
|
7770
7633
|
} else if (options.remove) {
|
|
7771
7634
|
const ok = removePermission(options.remove, options.dir);
|
|
7772
|
-
console.log(ok ?
|
|
7635
|
+
console.log(ok ? chalk42.green(`Removed permission: ${options.remove}`) : chalk42.yellow(`Permission not found: ${options.remove}`));
|
|
7773
7636
|
} else if (options.source) {
|
|
7774
7637
|
addTrustedSource(options.source, options.dir);
|
|
7775
|
-
console.log(
|
|
7638
|
+
console.log(chalk42.green(`Trusted source added: ${options.source}`));
|
|
7776
7639
|
} else {
|
|
7777
7640
|
const perms = loadPermissions(options.dir);
|
|
7778
7641
|
console.log(formatPermissions(perms));
|
|
@@ -7781,16 +7644,16 @@ async function cmdPermissions(options) {
|
|
|
7781
7644
|
async function cmdCheckPermission(resource, options) {
|
|
7782
7645
|
const category = options.category || "fileRead";
|
|
7783
7646
|
const result = checkPermission(resource, category, options.dir);
|
|
7784
|
-
const color = result === "allow" ?
|
|
7785
|
-
console.log(` ${color(result.toUpperCase())} ${
|
|
7647
|
+
const color = result === "allow" ? chalk42.green : result === "deny" ? chalk42.red : chalk42.yellow;
|
|
7648
|
+
console.log(` ${color(result.toUpperCase())} ${chalk42.dim(resource)} (${category})`);
|
|
7786
7649
|
}
|
|
7787
7650
|
async function cmdReset(options) {
|
|
7788
7651
|
resetPermissions(options.dir);
|
|
7789
|
-
console.log(
|
|
7652
|
+
console.log(chalk42.green("Permissions reset to defaults."));
|
|
7790
7653
|
}
|
|
7791
7654
|
async function cmdRemoveSource(source, options) {
|
|
7792
7655
|
const ok = removeTrustedSource(source, options.dir);
|
|
7793
|
-
console.log(ok ?
|
|
7656
|
+
console.log(ok ? chalk42.green(`Removed trusted source: ${source}`) : chalk42.yellow(`Source not found: ${source}`));
|
|
7794
7657
|
}
|
|
7795
7658
|
var securityCommand = new Command16("security").alias("sec").alias("secure").description("Security tools: risk assessment, secret detection, sandbox, permissions").addHelpText("after", `
|
|
7796
7659
|
Examples:
|
|
@@ -7825,7 +7688,7 @@ var pkg = {
|
|
|
7825
7688
|
description: "Terminal-native autonomous coding agent powered by free AI models"
|
|
7826
7689
|
};
|
|
7827
7690
|
var program = new Command17();
|
|
7828
|
-
program.name(pkg.name).description(
|
|
7691
|
+
program.name(pkg.name).description(chalk43.cyan(pkg.description)).version(pkg.version, "-v, --version", "Output the current version");
|
|
7829
7692
|
program.addCommand(chatCommand);
|
|
7830
7693
|
program.addCommand(runCommand);
|
|
7831
7694
|
program.addCommand(initCommand);
|