lovecode-ai 0.1.3 → 0.1.4
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 +363 -536
- package/dist/registry-ADSIKXA4.js +22 -0
- package/package.json +1 -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,14 @@ 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";
|
|
5324
5121
|
async function cmdEnvShow(options) {
|
|
5325
5122
|
console.log(formatEnvStatus(options.dir));
|
|
5326
5123
|
}
|
|
@@ -5328,14 +5125,14 @@ async function cmdEnvSet(key, value, options) {
|
|
|
5328
5125
|
const vars = loadEnv(options.dir);
|
|
5329
5126
|
vars[key.toUpperCase()] = value;
|
|
5330
5127
|
saveEnv(vars, options.dir);
|
|
5331
|
-
console.log(
|
|
5128
|
+
console.log(chalk24.green(`Set ${key.toUpperCase()}`));
|
|
5332
5129
|
console.log(formatEnvStatus(options.dir));
|
|
5333
5130
|
}
|
|
5334
5131
|
async function cmdEnvUnset(key, options) {
|
|
5335
5132
|
const vars = loadEnv(options.dir);
|
|
5336
5133
|
delete vars[key.toUpperCase()];
|
|
5337
5134
|
saveEnv(vars, options.dir);
|
|
5338
|
-
console.log(
|
|
5135
|
+
console.log(chalk24.yellow(`Unset ${key.toUpperCase()}`));
|
|
5339
5136
|
}
|
|
5340
5137
|
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
5138
|
Examples:
|
|
@@ -5352,21 +5149,21 @@ envCommand.action(cmdEnvShow);
|
|
|
5352
5149
|
import { Command as Command6 } from "commander";
|
|
5353
5150
|
|
|
5354
5151
|
// src/platform/optimize.ts
|
|
5355
|
-
import
|
|
5152
|
+
import chalk25 from "chalk";
|
|
5356
5153
|
|
|
5357
5154
|
// src/platform/detect.ts
|
|
5358
|
-
import * as
|
|
5155
|
+
import * as fs19 from "fs";
|
|
5359
5156
|
import * as os from "os";
|
|
5360
5157
|
var _isTermux = null;
|
|
5361
5158
|
var _isCodespaces = null;
|
|
5362
5159
|
function isTermux() {
|
|
5363
5160
|
if (_isTermux !== null) return _isTermux;
|
|
5364
|
-
_isTermux =
|
|
5161
|
+
_isTermux = fs19.existsSync("/data/data/com.termux") || process.env.PREFIX === "/data/data/com.termux/files/usr" || !!process.env.TERMUX_VERSION;
|
|
5365
5162
|
return _isTermux;
|
|
5366
5163
|
}
|
|
5367
5164
|
function isCodespaces() {
|
|
5368
5165
|
if (_isCodespaces !== null) return _isCodespaces;
|
|
5369
|
-
_isCodespaces = process.env.CODESPACES === "true" || !!process.env.CODESPACE_NAME ||
|
|
5166
|
+
_isCodespaces = process.env.CODESPACES === "true" || !!process.env.CODESPACE_NAME || fs19.existsSync("/.codespaces");
|
|
5370
5167
|
return _isCodespaces;
|
|
5371
5168
|
}
|
|
5372
5169
|
function lowRamMode() {
|
|
@@ -5395,14 +5192,14 @@ function platformInfo() {
|
|
|
5395
5192
|
|
|
5396
5193
|
// src/platform/optimize.ts
|
|
5397
5194
|
function formatPlatformStatus() {
|
|
5398
|
-
const lines = [
|
|
5399
|
-
lines.push(` Termux: ${isTermux() ?
|
|
5400
|
-
lines.push(` Codespaces: ${isCodespaces() ?
|
|
5401
|
-
lines.push(` Low RAM: ${lowRamMode() ?
|
|
5195
|
+
const lines = [chalk25.bold("\n Platform Status")];
|
|
5196
|
+
lines.push(` Termux: ${isTermux() ? chalk25.green("\u2713") : chalk25.dim("\u2014")}`);
|
|
5197
|
+
lines.push(` Codespaces: ${isCodespaces() ? chalk25.green("\u2713") : chalk25.dim("\u2014")}`);
|
|
5198
|
+
lines.push(` Low RAM: ${lowRamMode() ? chalk25.yellow("\u2713") : chalk25.dim("\u2014")}`);
|
|
5402
5199
|
lines.push(` Max Mem: ${recommendedMaxMemory()}MB`);
|
|
5403
5200
|
lines.push("");
|
|
5404
5201
|
for (const line of platformInfo()) {
|
|
5405
|
-
lines.push(` ${
|
|
5202
|
+
lines.push(` ${chalk25.dim(line)}`);
|
|
5406
5203
|
}
|
|
5407
5204
|
return lines.join("\n");
|
|
5408
5205
|
}
|
|
@@ -5415,19 +5212,19 @@ var platformCommand = new Command6("platform").alias("sys").alias("info").descri
|
|
|
5415
5212
|
|
|
5416
5213
|
// src/commands/telemetry.ts
|
|
5417
5214
|
import { Command as Command7 } from "commander";
|
|
5418
|
-
import
|
|
5215
|
+
import chalk27 from "chalk";
|
|
5419
5216
|
|
|
5420
5217
|
// src/telemetry/telemetry.ts
|
|
5421
|
-
import * as
|
|
5422
|
-
import * as
|
|
5218
|
+
import * as fs20 from "fs";
|
|
5219
|
+
import * as path19 from "path";
|
|
5423
5220
|
import * as os2 from "os";
|
|
5424
5221
|
import { createRequire as createRequire2 } from "module";
|
|
5425
|
-
import
|
|
5222
|
+
import chalk26 from "chalk";
|
|
5426
5223
|
var _require2 = createRequire2(import.meta.url);
|
|
5427
5224
|
var TELEMETRY_DIR = ".lovecode/telemetry";
|
|
5428
5225
|
var _enabled = null;
|
|
5429
5226
|
function telemetryDir(rootDir) {
|
|
5430
|
-
return
|
|
5227
|
+
return path19.resolve(rootDir || process.cwd(), TELEMETRY_DIR);
|
|
5431
5228
|
}
|
|
5432
5229
|
function isTelemetryEnabled(rootDir) {
|
|
5433
5230
|
if (_enabled !== null) return _enabled;
|
|
@@ -5439,8 +5236,8 @@ function isTelemetryEnabled(rootDir) {
|
|
|
5439
5236
|
_enabled = false;
|
|
5440
5237
|
return false;
|
|
5441
5238
|
}
|
|
5442
|
-
const configPath =
|
|
5443
|
-
if (
|
|
5239
|
+
const configPath = path19.resolve(rootDir || process.cwd(), ".lovecode/config.yaml");
|
|
5240
|
+
if (fs20.existsSync(configPath)) {
|
|
5444
5241
|
try {
|
|
5445
5242
|
const { loadConfig: loadConfig2 } = _require2("../config/config.js");
|
|
5446
5243
|
const config = loadConfig2(rootDir);
|
|
@@ -5481,10 +5278,10 @@ function getTelemetryData(rootDir) {
|
|
|
5481
5278
|
const dir = telemetryDir(rootDir);
|
|
5482
5279
|
const events = [];
|
|
5483
5280
|
const crashes = [];
|
|
5484
|
-
if (!
|
|
5485
|
-
for (const file of
|
|
5281
|
+
if (!fs20.existsSync(dir)) return { events, crashes };
|
|
5282
|
+
for (const file of fs20.readdirSync(dir)) {
|
|
5486
5283
|
try {
|
|
5487
|
-
const content =
|
|
5284
|
+
const content = fs20.readFileSync(path19.join(dir, file), "utf-8");
|
|
5488
5285
|
const data = JSON.parse(content);
|
|
5489
5286
|
if (file.startsWith("crash-")) {
|
|
5490
5287
|
crashes.push(data);
|
|
@@ -5498,21 +5295,21 @@ function getTelemetryData(rootDir) {
|
|
|
5498
5295
|
}
|
|
5499
5296
|
function clearTelemetryData(rootDir) {
|
|
5500
5297
|
const dir = telemetryDir(rootDir);
|
|
5501
|
-
if (
|
|
5502
|
-
|
|
5298
|
+
if (fs20.existsSync(dir)) {
|
|
5299
|
+
fs20.rmSync(dir, { recursive: true, force: true });
|
|
5503
5300
|
}
|
|
5504
5301
|
}
|
|
5505
5302
|
function formatTelemetryStatus(enabled, data) {
|
|
5506
|
-
const lines = [
|
|
5507
|
-
lines.push(` Status: ${enabled ?
|
|
5303
|
+
const lines = [chalk26.bold("\n Telemetry Status")];
|
|
5304
|
+
lines.push(` Status: ${enabled ? chalk26.yellow("ENABLED") : chalk26.green("DISABLED")}`);
|
|
5508
5305
|
lines.push(` Events: ${data.events.length}`);
|
|
5509
5306
|
lines.push(` Crashes: ${data.crashes.length}`);
|
|
5510
5307
|
if (data.events.length > 0) {
|
|
5511
|
-
lines.push(
|
|
5308
|
+
lines.push(chalk26.dim(`
|
|
5512
5309
|
Recent Events:`));
|
|
5513
5310
|
for (const e of data.events.slice(-5)) {
|
|
5514
5311
|
const date = new Date(e.timestamp).toLocaleString();
|
|
5515
|
-
lines.push(` ${
|
|
5312
|
+
lines.push(` ${chalk26.dim(date)} ${e.event}`);
|
|
5516
5313
|
}
|
|
5517
5314
|
}
|
|
5518
5315
|
return lines.join("\n");
|
|
@@ -5526,17 +5323,17 @@ async function cmdTelemetryStatus(options) {
|
|
|
5526
5323
|
}
|
|
5527
5324
|
async function cmdTelemetryEnable(options) {
|
|
5528
5325
|
enableTelemetry(options.dir);
|
|
5529
|
-
console.log(
|
|
5530
|
-
console.log(
|
|
5531
|
-
console.log(
|
|
5326
|
+
console.log(chalk27.yellow("Telemetry enabled."));
|
|
5327
|
+
console.log(chalk27.dim(" Anonymous usage data will be collected to improve LoveCode."));
|
|
5328
|
+
console.log(chalk27.dim(" No personal or project data is ever sent."));
|
|
5532
5329
|
}
|
|
5533
5330
|
async function cmdTelemetryDisable(options) {
|
|
5534
5331
|
disableTelemetry(options.dir);
|
|
5535
|
-
console.log(
|
|
5332
|
+
console.log(chalk27.green("Telemetry disabled."));
|
|
5536
5333
|
}
|
|
5537
5334
|
async function cmdTelemetryClear(options) {
|
|
5538
5335
|
clearTelemetryData(options.dir);
|
|
5539
|
-
console.log(
|
|
5336
|
+
console.log(chalk27.green("Telemetry data cleared."));
|
|
5540
5337
|
}
|
|
5541
5338
|
var telemetryCommand = new Command7("telemetry").alias("analytics").description("Manage anonymous telemetry and crash reporting").option("--dir <path>", "Project directory", process.cwd()).addHelpText("after", `
|
|
5542
5339
|
Privacy-first by default. Telemetry is disabled unless explicitly enabled.
|
|
@@ -5554,13 +5351,13 @@ telemetryCommand.action(cmdTelemetryStatus);
|
|
|
5554
5351
|
|
|
5555
5352
|
// src/commands/install.ts
|
|
5556
5353
|
import { Command as Command8 } from "commander";
|
|
5557
|
-
import
|
|
5354
|
+
import chalk29 from "chalk";
|
|
5558
5355
|
|
|
5559
5356
|
// src/installers/install.ts
|
|
5560
|
-
import * as
|
|
5561
|
-
import * as
|
|
5357
|
+
import * as fs21 from "fs";
|
|
5358
|
+
import * as path20 from "path";
|
|
5562
5359
|
import { execSync as execSync4 } from "child_process";
|
|
5563
|
-
import
|
|
5360
|
+
import chalk28 from "chalk";
|
|
5564
5361
|
function detectInstallMethod() {
|
|
5565
5362
|
if (process.env.npm_config_user_agent?.startsWith("npm")) return "npm";
|
|
5566
5363
|
if (process.env.npm_config_user_agent?.startsWith("yarn")) return "yarn";
|
|
@@ -5586,21 +5383,21 @@ function isGloballyInstalled() {
|
|
|
5586
5383
|
}
|
|
5587
5384
|
}
|
|
5588
5385
|
function printInstallInstructions() {
|
|
5589
|
-
console.log(
|
|
5590
|
-
console.log(
|
|
5591
|
-
console.log(` ${
|
|
5386
|
+
console.log(chalk28.bold.cyan("\n LoveCode AI - Installation\n"));
|
|
5387
|
+
console.log(chalk28.bold(" Quick Install:\n"));
|
|
5388
|
+
console.log(` ${chalk28.green("NPM:")}`);
|
|
5592
5389
|
console.log(` npm install -g lovecode-ai
|
|
5593
5390
|
`);
|
|
5594
|
-
console.log(` ${
|
|
5391
|
+
console.log(` ${chalk28.green("Curl:")}`);
|
|
5595
5392
|
console.log(` curl -fsSL https://lovecode.sh | bash
|
|
5596
5393
|
`);
|
|
5597
|
-
console.log(` ${
|
|
5394
|
+
console.log(` ${chalk28.green("Verify:")}`);
|
|
5598
5395
|
console.log(` lovecode --version
|
|
5599
5396
|
`);
|
|
5600
5397
|
}
|
|
5601
5398
|
function createInstallScript(rootDir) {
|
|
5602
5399
|
const dir = rootDir || process.cwd();
|
|
5603
|
-
const scriptPath =
|
|
5400
|
+
const scriptPath = path20.join(dir, "install.sh");
|
|
5604
5401
|
const script = `#!/usr/bin/env bash
|
|
5605
5402
|
set -euo pipefail
|
|
5606
5403
|
|
|
@@ -5655,11 +5452,11 @@ echo " Run: lovecode setup Interactive configuration"
|
|
|
5655
5452
|
echo " Run: lovecode Start the AI agent"
|
|
5656
5453
|
echo ""
|
|
5657
5454
|
`;
|
|
5658
|
-
const scriptDir =
|
|
5659
|
-
if (!
|
|
5660
|
-
|
|
5455
|
+
const scriptDir = path20.dirname(scriptPath);
|
|
5456
|
+
if (!fs21.existsSync(scriptDir)) fs21.mkdirSync(scriptDir, { recursive: true });
|
|
5457
|
+
fs21.writeFileSync(scriptPath, script, "utf-8");
|
|
5661
5458
|
try {
|
|
5662
|
-
|
|
5459
|
+
fs21.chmodSync(scriptPath, "755");
|
|
5663
5460
|
} catch {
|
|
5664
5461
|
}
|
|
5665
5462
|
}
|
|
@@ -5668,20 +5465,20 @@ echo ""
|
|
|
5668
5465
|
async function cmdInstallStatus() {
|
|
5669
5466
|
const info = getInstallerInfo();
|
|
5670
5467
|
const global = isGloballyInstalled();
|
|
5671
|
-
console.log(
|
|
5672
|
-
console.log(` Method: ${
|
|
5468
|
+
console.log(chalk29.bold("\n Install Status"));
|
|
5469
|
+
console.log(` Method: ${chalk29.cyan(info.method)}`);
|
|
5673
5470
|
console.log(` Version: ${info.version}`);
|
|
5674
5471
|
console.log(` Node: ${info.nodeVersion}`);
|
|
5675
5472
|
console.log(` Platform: ${info.platform}`);
|
|
5676
|
-
console.log(` Global CLI: ${global ?
|
|
5473
|
+
console.log(` Global CLI: ${global ? chalk29.green("\u2713") : chalk29.dim("\u2014")}`);
|
|
5677
5474
|
}
|
|
5678
5475
|
async function cmdInstallGuide() {
|
|
5679
5476
|
printInstallInstructions();
|
|
5680
5477
|
}
|
|
5681
5478
|
async function cmdInstallScript(options) {
|
|
5682
5479
|
createInstallScript(options.dir);
|
|
5683
|
-
console.log(
|
|
5684
|
-
console.log(
|
|
5480
|
+
console.log(chalk29.green(` \u2713 install.sh created in ${options.dir || process.cwd()}`));
|
|
5481
|
+
console.log(chalk29.dim(" Run: bash install.sh"));
|
|
5685
5482
|
}
|
|
5686
5483
|
var installCommand = new Command8("install").alias("installer").description("Installation management and instructions").option("--dir <path>", "Project directory", process.cwd()).addHelpText("after", `
|
|
5687
5484
|
Examples:
|
|
@@ -5695,7 +5492,7 @@ installCommand.action(cmdInstallStatus);
|
|
|
5695
5492
|
|
|
5696
5493
|
// src/commands/models.ts
|
|
5697
5494
|
import { Command as Command9 } from "commander";
|
|
5698
|
-
import
|
|
5495
|
+
import chalk30 from "chalk";
|
|
5699
5496
|
var modelsCommand = new Command9("models").description("Manage AI models and providers").addCommand(
|
|
5700
5497
|
new Command9("list").alias("ls").description("List all available models and providers").action(() => {
|
|
5701
5498
|
console.log(printProviders());
|
|
@@ -5704,8 +5501,8 @@ var modelsCommand = new Command9("models").description("Manage AI models and pro
|
|
|
5704
5501
|
new Command9("use").description("Set the default model to use").argument("<model>", "Model name or provider name").action((model) => {
|
|
5705
5502
|
const result = setDefaultModel(model);
|
|
5706
5503
|
if (result) {
|
|
5707
|
-
console.log(
|
|
5708
|
-
\u2713 Default set to ${
|
|
5504
|
+
console.log(chalk30.green(`
|
|
5505
|
+
\u2713 Default set to ${chalk30.cyan(result.provider)}/${chalk30.cyan(result.model)}
|
|
5709
5506
|
`));
|
|
5710
5507
|
}
|
|
5711
5508
|
})
|
|
@@ -5714,20 +5511,20 @@ var modelsCommand = new Command9("models").description("Manage AI models and pro
|
|
|
5714
5511
|
if (provider) {
|
|
5715
5512
|
const entry = getProvider(provider);
|
|
5716
5513
|
if (!entry) {
|
|
5717
|
-
console.log(
|
|
5514
|
+
console.log(chalk30.red(`
|
|
5718
5515
|
Unknown provider: "${provider}"
|
|
5719
5516
|
`));
|
|
5720
5517
|
return;
|
|
5721
5518
|
}
|
|
5722
|
-
const tag = entry.local ?
|
|
5519
|
+
const tag = entry.local ? chalk30.green(" LOCAL ") : chalk30.blue(" CLOUD ");
|
|
5723
5520
|
console.log(`
|
|
5724
|
-
${tag} ${
|
|
5725
|
-
console.log(
|
|
5726
|
-
console.log(
|
|
5727
|
-
console.log(
|
|
5521
|
+
${tag} ${chalk30.cyan(entry.name)}`);
|
|
5522
|
+
console.log(chalk30.dim(` Default model: ${entry.defaultModel}`));
|
|
5523
|
+
console.log(chalk30.dim(` Priority: ${entry.priority}`));
|
|
5524
|
+
console.log(chalk30.dim(` Models:`));
|
|
5728
5525
|
for (const m of entry.models) {
|
|
5729
5526
|
const isDefault = m === entry.defaultModel;
|
|
5730
|
-
console.log(` ${isDefault ?
|
|
5527
|
+
console.log(` ${isDefault ? chalk30.green("\u2605") : " "} ${m}${isDefault ? chalk30.dim(" (default)") : ""}`);
|
|
5731
5528
|
}
|
|
5732
5529
|
console.log("");
|
|
5733
5530
|
} else {
|
|
@@ -5738,13 +5535,13 @@ var modelsCommand = new Command9("models").description("Manage AI models and pro
|
|
|
5738
5535
|
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
5536
|
const entry = getProvider(provider);
|
|
5740
5537
|
if (!entry) {
|
|
5741
|
-
console.log(
|
|
5538
|
+
console.log(chalk30.red(`
|
|
5742
5539
|
Unknown provider: "${provider}"
|
|
5743
5540
|
`));
|
|
5744
5541
|
return;
|
|
5745
5542
|
}
|
|
5746
5543
|
const model = options.model || entry.defaultModel;
|
|
5747
|
-
console.log(
|
|
5544
|
+
console.log(chalk30.dim(`
|
|
5748
5545
|
Testing ${entry.name}/${model}...`));
|
|
5749
5546
|
try {
|
|
5750
5547
|
const config = entry.getConfig?.(model) || {
|
|
@@ -5757,9 +5554,9 @@ var modelsCommand = new Command9("models").description("Manage AI models and pro
|
|
|
5757
5554
|
[{ role: "user", content: "Reply with exactly: OK" }],
|
|
5758
5555
|
config
|
|
5759
5556
|
);
|
|
5760
|
-
console.log(
|
|
5557
|
+
console.log(chalk30.green(` \u2713 ${entry.name}/${model} responded: ${result.slice(0, 50)}`));
|
|
5761
5558
|
} catch (err) {
|
|
5762
|
-
console.log(
|
|
5559
|
+
console.log(chalk30.red(` \u2717 ${entry.name}/${model} failed: ${err.message}`));
|
|
5763
5560
|
}
|
|
5764
5561
|
console.log("");
|
|
5765
5562
|
})
|
|
@@ -5767,12 +5564,12 @@ var modelsCommand = new Command9("models").description("Manage AI models and pro
|
|
|
5767
5564
|
|
|
5768
5565
|
// src/commands/analyze.ts
|
|
5769
5566
|
import { Command as Command10 } from "commander";
|
|
5770
|
-
import
|
|
5567
|
+
import chalk32 from "chalk";
|
|
5771
5568
|
|
|
5772
5569
|
// src/repo/search.ts
|
|
5773
|
-
import * as
|
|
5774
|
-
import * as
|
|
5775
|
-
import
|
|
5570
|
+
import * as fs22 from "fs";
|
|
5571
|
+
import * as path21 from "path";
|
|
5572
|
+
import chalk31 from "chalk";
|
|
5776
5573
|
function chunkFile(content, maxLines = 50) {
|
|
5777
5574
|
const lines = content.split("\n");
|
|
5778
5575
|
const chunks = [];
|
|
@@ -5808,7 +5605,7 @@ async function semanticSearch2(rootDir, query, options = { rootDir: "", query: "
|
|
|
5808
5605
|
const queryEmbedding = await getEmbedding(query);
|
|
5809
5606
|
const files = collectTextFiles(rootDir, 200);
|
|
5810
5607
|
for (const filePath of files) {
|
|
5811
|
-
const relativePath =
|
|
5608
|
+
const relativePath = path21.relative(rootDir, filePath).replace(/\\/g, "/");
|
|
5812
5609
|
const content = readFileSafe(filePath);
|
|
5813
5610
|
if (!content) continue;
|
|
5814
5611
|
const chunks = chunkFile(content, 30);
|
|
@@ -5878,14 +5675,14 @@ function collectTextFiles(dir, max) {
|
|
|
5878
5675
|
function walk(dir2) {
|
|
5879
5676
|
if (results.length >= max) return;
|
|
5880
5677
|
try {
|
|
5881
|
-
const entries =
|
|
5678
|
+
const entries = fs22.readdirSync(dir2, { withFileTypes: true });
|
|
5882
5679
|
for (const entry of entries) {
|
|
5883
5680
|
if (results.length >= max) return;
|
|
5884
5681
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === ".git") continue;
|
|
5885
|
-
const fullPath =
|
|
5682
|
+
const fullPath = path21.join(dir2, entry.name);
|
|
5886
5683
|
if (entry.isDirectory()) {
|
|
5887
5684
|
walk(fullPath);
|
|
5888
|
-
} else if (extSet.has(
|
|
5685
|
+
} else if (extSet.has(path21.extname(entry.name).toLowerCase())) {
|
|
5889
5686
|
results.push(fullPath);
|
|
5890
5687
|
}
|
|
5891
5688
|
}
|
|
@@ -5897,31 +5694,31 @@ function collectTextFiles(dir, max) {
|
|
|
5897
5694
|
}
|
|
5898
5695
|
function readFileSafe(filePath) {
|
|
5899
5696
|
try {
|
|
5900
|
-
const stats =
|
|
5697
|
+
const stats = fs22.statSync(filePath);
|
|
5901
5698
|
if (stats.size > 5e5) return null;
|
|
5902
|
-
return
|
|
5699
|
+
return fs22.readFileSync(filePath, "utf-8");
|
|
5903
5700
|
} catch {
|
|
5904
5701
|
return null;
|
|
5905
5702
|
}
|
|
5906
5703
|
}
|
|
5907
5704
|
function printSemanticResults(results, query) {
|
|
5908
|
-
const lines = [
|
|
5705
|
+
const lines = [chalk31.bold(`
|
|
5909
5706
|
Semantic Search: "${query}"`), ""];
|
|
5910
5707
|
if (results.length === 0) {
|
|
5911
|
-
lines.push(
|
|
5708
|
+
lines.push(chalk31.dim(" No results found."));
|
|
5912
5709
|
lines.push("");
|
|
5913
5710
|
return lines.join("\n");
|
|
5914
5711
|
}
|
|
5915
5712
|
for (let i = 0; i < results.length; i++) {
|
|
5916
5713
|
const r = results[i];
|
|
5917
5714
|
const barLen = Math.round(r.score * 30);
|
|
5918
|
-
const bar =
|
|
5919
|
-
lines.push(` ${
|
|
5920
|
-
lines.push(` ${bar} ${
|
|
5715
|
+
const bar = chalk31.cyan("\u2588".repeat(barLen)) + chalk31.dim("\u2591".repeat(30 - barLen));
|
|
5716
|
+
lines.push(` ${chalk31.cyan(String(i + 1).padEnd(3))} ${chalk31.dim(r.relativePath)}`);
|
|
5717
|
+
lines.push(` ${bar} ${chalk31.bold(String(Math.round(r.score * 100)))}%`);
|
|
5921
5718
|
if (r.matches.length > 0) {
|
|
5922
5719
|
const top = r.matches.slice(0, 2);
|
|
5923
5720
|
for (const m of top) {
|
|
5924
|
-
lines.push(` ${
|
|
5721
|
+
lines.push(` ${chalk31.dim(`L${m.line}:`)} ${m.content.slice(0, 100)}`);
|
|
5925
5722
|
}
|
|
5926
5723
|
}
|
|
5927
5724
|
}
|
|
@@ -5937,27 +5734,27 @@ var analyzeCommand = new Command10("analyze").alias("a").description("Analyze an
|
|
|
5937
5734
|
})
|
|
5938
5735
|
).addCommand(
|
|
5939
5736
|
new Command10("deps").alias("d").description("Analyze dependencies and import graph").option("--dir <path>", "Project directory", process.cwd()).action((options) => {
|
|
5940
|
-
console.log(
|
|
5737
|
+
console.log(chalk32.dim("\n Analyzing dependencies..."));
|
|
5941
5738
|
const graph = analyzeDependencies(options.dir);
|
|
5942
5739
|
console.log(printDepGraph(graph));
|
|
5943
5740
|
const circles = findCircularDeps(graph);
|
|
5944
5741
|
if (circles.length > 0) {
|
|
5945
|
-
console.log(
|
|
5742
|
+
console.log(chalk32.yellow(` \u26A0 Found ${circles.length} circular dependenc${circles.length > 1 ? "ies" : "y"}`));
|
|
5946
5743
|
for (const circle of circles.slice(0, 5)) {
|
|
5947
|
-
console.log(` ${
|
|
5744
|
+
console.log(` ${chalk32.red("\u21BB")} ${circle.join(" \u2192 ")}`);
|
|
5948
5745
|
}
|
|
5949
5746
|
console.log("");
|
|
5950
5747
|
}
|
|
5951
5748
|
})
|
|
5952
5749
|
).addCommand(
|
|
5953
5750
|
new Command10("summary").alias("s").description("Generate a full repo architecture summary").option("--dir <path>", "Project directory", process.cwd()).action((options) => {
|
|
5954
|
-
console.log(
|
|
5751
|
+
console.log(chalk32.dim("\n Generating repository summary...\n"));
|
|
5955
5752
|
const summary = generateSummary(options.dir);
|
|
5956
5753
|
console.log(printSummary(summary));
|
|
5957
5754
|
})
|
|
5958
5755
|
).addCommand(
|
|
5959
5756
|
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(
|
|
5757
|
+
console.log(chalk32.dim(`
|
|
5961
5758
|
Searching for: "${query}"
|
|
5962
5759
|
`));
|
|
5963
5760
|
const results = await semanticSearch2(options.dir, query, {
|
|
@@ -5983,36 +5780,36 @@ var analyzeCommand = new Command10("analyze").alias("a").description("Analyze an
|
|
|
5983
5780
|
|
|
5984
5781
|
// src/commands/memory.ts
|
|
5985
5782
|
import { Command as Command11 } from "commander";
|
|
5986
|
-
import
|
|
5783
|
+
import chalk33 from "chalk";
|
|
5987
5784
|
async function cmdSessions(options) {
|
|
5988
5785
|
const sessions = listSessions(options.dir);
|
|
5989
5786
|
if (sessions.length === 0) {
|
|
5990
|
-
console.log(
|
|
5787
|
+
console.log(chalk33.yellow("No sessions found."));
|
|
5991
5788
|
return;
|
|
5992
5789
|
}
|
|
5993
|
-
console.log(
|
|
5790
|
+
console.log(chalk33.bold(`
|
|
5994
5791
|
Sessions (${sessions.length}):
|
|
5995
5792
|
`));
|
|
5996
5793
|
for (const s of sessions) {
|
|
5997
5794
|
const date = new Date(s.updated).toLocaleString();
|
|
5998
5795
|
const msgCount = s.entries.length;
|
|
5999
|
-
console.log(` ${
|
|
6000
|
-
console.log(` ${
|
|
5796
|
+
console.log(` ${chalk33.cyan(s.id.slice(0, 12))} ${chalk33.bold(s.title)}`);
|
|
5797
|
+
console.log(` ${chalk33.dim(`${msgCount} msgs \u2022 ${date} \u2022 ${s.model}`)}`);
|
|
6001
5798
|
}
|
|
6002
5799
|
}
|
|
6003
5800
|
async function cmdShowSession(id, options) {
|
|
6004
5801
|
const session = loadSession(id, options.dir);
|
|
6005
5802
|
if (!session) {
|
|
6006
|
-
console.log(
|
|
5803
|
+
console.log(chalk33.red(`Session "${id}" not found.`));
|
|
6007
5804
|
return;
|
|
6008
5805
|
}
|
|
6009
|
-
console.log(
|
|
5806
|
+
console.log(chalk33.bold(`
|
|
6010
5807
|
Session: ${session.title}`));
|
|
6011
|
-
console.log(
|
|
6012
|
-
console.log(
|
|
5808
|
+
console.log(chalk33.dim(` ID: ${session.id} \u2022 Model: ${session.model} \u2022 ${session.entries.length} messages`));
|
|
5809
|
+
console.log(chalk33.dim(` Created: ${new Date(session.created).toLocaleString()}`));
|
|
6013
5810
|
console.log("");
|
|
6014
5811
|
for (const entry of session.entries.slice(-20)) {
|
|
6015
|
-
const role = entry.role === "user" ?
|
|
5812
|
+
const role = entry.role === "user" ? chalk33.green("You") : entry.role === "assistant" ? chalk33.cyan("LoveCode") : chalk33.yellow("System");
|
|
6016
5813
|
const preview = entry.content.length > 200 ? entry.content.slice(0, 200) + "..." : entry.content;
|
|
6017
5814
|
console.log(` ${role}: ${preview}
|
|
6018
5815
|
`);
|
|
@@ -6021,15 +5818,15 @@ async function cmdShowSession(id, options) {
|
|
|
6021
5818
|
async function cmdSearchSessions(query, options) {
|
|
6022
5819
|
const results = searchSessions(query, options.dir);
|
|
6023
5820
|
if (results.length === 0) {
|
|
6024
|
-
console.log(
|
|
5821
|
+
console.log(chalk33.yellow(`No sessions matching "${query}".`));
|
|
6025
5822
|
return;
|
|
6026
5823
|
}
|
|
6027
|
-
console.log(
|
|
5824
|
+
console.log(chalk33.bold(`
|
|
6028
5825
|
Search results for "${query}" (${results.length}):
|
|
6029
5826
|
`));
|
|
6030
5827
|
for (const s of results) {
|
|
6031
5828
|
const date = new Date(s.updated).toLocaleString();
|
|
6032
|
-
console.log(` ${
|
|
5829
|
+
console.log(` ${chalk33.cyan(s.id.slice(0, 12))} ${chalk33.bold(s.title)} ${chalk33.dim(date)}`);
|
|
6033
5830
|
}
|
|
6034
5831
|
}
|
|
6035
5832
|
async function cmdPreferences(options) {
|
|
@@ -6049,7 +5846,7 @@ async function cmdPreferences(options) {
|
|
|
6049
5846
|
else prefs[k] = v;
|
|
6050
5847
|
}
|
|
6051
5848
|
const saved = savePreferences(prefs, options.dir);
|
|
6052
|
-
console.log(
|
|
5849
|
+
console.log(chalk33.green("Preferences updated:"));
|
|
6053
5850
|
console.log(formatPreferences(saved));
|
|
6054
5851
|
} else {
|
|
6055
5852
|
const prefs = getPreferences(options.dir);
|
|
@@ -6059,7 +5856,7 @@ async function cmdPreferences(options) {
|
|
|
6059
5856
|
async function cmdRepoMemory(options) {
|
|
6060
5857
|
if (options.note) {
|
|
6061
5858
|
const updated = addRepoNote(options.note, options.dir);
|
|
6062
|
-
console.log(
|
|
5859
|
+
console.log(chalk33.green("Note added to repo memory."));
|
|
6063
5860
|
console.log(formatRepoMemory(updated));
|
|
6064
5861
|
} else {
|
|
6065
5862
|
const mem = getRepoMemory(options.dir);
|
|
@@ -6079,31 +5876,31 @@ async function cmdWorkflows(options) {
|
|
|
6079
5876
|
used: Date.now()
|
|
6080
5877
|
};
|
|
6081
5878
|
saveWorkflow(workflow, options.dir);
|
|
6082
|
-
console.log(
|
|
5879
|
+
console.log(chalk33.green(`Workflow "${options.name}" saved (${steps.length} steps).`));
|
|
6083
5880
|
return;
|
|
6084
5881
|
}
|
|
6085
5882
|
if (options.delete) {
|
|
6086
5883
|
const ok = deleteWorkflow(options.delete, options.dir);
|
|
6087
|
-
console.log(ok ?
|
|
5884
|
+
console.log(ok ? chalk33.green(`Workflow "${options.delete}" deleted.`) : chalk33.yellow(`Workflow "${options.delete}" not found.`));
|
|
6088
5885
|
return;
|
|
6089
5886
|
}
|
|
6090
5887
|
if (wf.workflows.length === 0) {
|
|
6091
|
-
console.log(
|
|
5888
|
+
console.log(chalk33.yellow("No saved workflows."));
|
|
6092
5889
|
return;
|
|
6093
5890
|
}
|
|
6094
|
-
console.log(
|
|
5891
|
+
console.log(chalk33.bold(`
|
|
6095
5892
|
Workflows (${wf.workflows.length}):
|
|
6096
5893
|
`));
|
|
6097
5894
|
for (const w of wf.workflows) {
|
|
6098
5895
|
const date = new Date(w.used).toLocaleString();
|
|
6099
|
-
console.log(` ${
|
|
6100
|
-
console.log(` ${
|
|
5896
|
+
console.log(` ${chalk33.cyan(w.name)} ${chalk33.dim(w.description || "(no description)")}`);
|
|
5897
|
+
console.log(` ${chalk33.dim(`${w.steps.length} steps \u2022 last used ${date}`)}`);
|
|
6101
5898
|
}
|
|
6102
5899
|
}
|
|
6103
5900
|
async function cmdVectorStore(options) {
|
|
6104
5901
|
if (options.clear) {
|
|
6105
5902
|
clearVectors(options.dir);
|
|
6106
|
-
console.log(
|
|
5903
|
+
console.log(chalk33.green("Vector memory cleared."));
|
|
6107
5904
|
return;
|
|
6108
5905
|
}
|
|
6109
5906
|
if (options.count) {
|
|
@@ -6112,8 +5909,8 @@ async function cmdVectorStore(options) {
|
|
|
6112
5909
|
}
|
|
6113
5910
|
if (options.store) {
|
|
6114
5911
|
const entry = await storeVector(options.store, {}, options.dir);
|
|
6115
|
-
console.log(
|
|
6116
|
-
console.log(
|
|
5912
|
+
console.log(chalk33.green(`Stored: "${options.store.slice(0, 80)}..."`));
|
|
5913
|
+
console.log(chalk33.dim(` ID: ${entry.id}`));
|
|
6117
5914
|
return;
|
|
6118
5915
|
}
|
|
6119
5916
|
if (options.query) {
|
|
@@ -6121,32 +5918,32 @@ async function cmdVectorStore(options) {
|
|
|
6121
5918
|
console.log(formatVectorResults(results));
|
|
6122
5919
|
return;
|
|
6123
5920
|
}
|
|
6124
|
-
console.log(
|
|
5921
|
+
console.log(chalk33.yellow("Specify --query, --store, --count, or --clear."));
|
|
6125
5922
|
}
|
|
6126
5923
|
async function cmdChatLogs(options) {
|
|
6127
5924
|
const logs = listChatLogs(options.dir);
|
|
6128
5925
|
if (logs.length === 0) {
|
|
6129
|
-
console.log(
|
|
5926
|
+
console.log(chalk33.yellow("No chat logs found."));
|
|
6130
5927
|
return;
|
|
6131
5928
|
}
|
|
6132
5929
|
const totalSize = logs.reduce((acc, l) => acc + l.size, 0);
|
|
6133
5930
|
const sizeStr = totalSize > 1024 ? `${(totalSize / 1024).toFixed(1)} KB` : `${totalSize} B`;
|
|
6134
|
-
console.log(
|
|
5931
|
+
console.log(chalk33.bold(`
|
|
6135
5932
|
Chat Logs (${logs.length}, ${sizeStr}):
|
|
6136
5933
|
`));
|
|
6137
5934
|
for (const log of logs.slice(0, 20)) {
|
|
6138
5935
|
const date = log.modified.toLocaleString();
|
|
6139
5936
|
const size = log.size > 1024 ? `${(log.size / 1024).toFixed(1)} KB` : `${log.size} B`;
|
|
6140
|
-
console.log(` ${
|
|
5937
|
+
console.log(` ${chalk33.dim(log.name.slice(0, 50).padEnd(52))} ${chalk33.yellow(size.padStart(8))} ${chalk33.dim(date)}`);
|
|
6141
5938
|
}
|
|
6142
5939
|
if (logs.length > 20) {
|
|
6143
|
-
console.log(
|
|
5940
|
+
console.log(chalk33.dim(` ... and ${logs.length - 20} more`));
|
|
6144
5941
|
}
|
|
6145
5942
|
}
|
|
6146
5943
|
async function cmdClearAll(options) {
|
|
6147
5944
|
clearAllMemory(options.dir);
|
|
6148
5945
|
clearVectors(options.dir);
|
|
6149
|
-
console.log(
|
|
5946
|
+
console.log(chalk33.green("All memory data cleared."));
|
|
6150
5947
|
}
|
|
6151
5948
|
var memoryCommand = new Command11("memory").alias("mem").description("Manage sessions, memory, and chat logs").option("--dir <path>", "Project directory", process.cwd()).addCommand(
|
|
6152
5949
|
new Command11("sessions").alias("s").description("List all persistent sessions").option("--dir <path>", "Project directory").action(cmdSessions)
|
|
@@ -6188,14 +5985,14 @@ var memoryCommand = new Command11("memory").alias("mem").description("Manage ses
|
|
|
6188
5985
|
|
|
6189
5986
|
// src/commands/git.ts
|
|
6190
5987
|
import { Command as Command12 } from "commander";
|
|
6191
|
-
import
|
|
5988
|
+
import chalk34 from "chalk";
|
|
6192
5989
|
function requireGit(cwd) {
|
|
6193
5990
|
if (!isGitAvailable()) {
|
|
6194
|
-
console.log(
|
|
5991
|
+
console.log(chalk34.red(" \u2717 Git is not installed or not in PATH."));
|
|
6195
5992
|
return false;
|
|
6196
5993
|
}
|
|
6197
5994
|
if (!isRepo(cwd)) {
|
|
6198
|
-
console.log(
|
|
5995
|
+
console.log(chalk34.red(" \u2717 Not a git repository."));
|
|
6199
5996
|
return false;
|
|
6200
5997
|
}
|
|
6201
5998
|
return true;
|
|
@@ -6209,39 +6006,39 @@ async function cmdCommit(opts) {
|
|
|
6209
6006
|
}
|
|
6210
6007
|
const status = getStatus(root || dir);
|
|
6211
6008
|
if (status.clean && !opts.message) {
|
|
6212
|
-
console.log(
|
|
6009
|
+
console.log(chalk34.yellow(" Nothing to commit. Working tree clean."));
|
|
6213
6010
|
return;
|
|
6214
6011
|
}
|
|
6215
6012
|
let commitMessage = opts.message;
|
|
6216
6013
|
if (!commitMessage && opts.generate) {
|
|
6217
|
-
console.log(
|
|
6014
|
+
console.log(chalk34.dim(" Generating commit message..."));
|
|
6218
6015
|
commitMessage = await generateCommitMessage();
|
|
6219
|
-
console.log(
|
|
6016
|
+
console.log(chalk34.cyan(` Generated: ${commitMessage.split("\n")[0]}
|
|
6220
6017
|
`));
|
|
6221
6018
|
}
|
|
6222
6019
|
if (!commitMessage) {
|
|
6223
|
-
console.log(
|
|
6224
|
-
console.log(
|
|
6225
|
-
console.log(
|
|
6226
|
-
console.log(
|
|
6020
|
+
console.log(chalk34.yellow(" No commit message provided. Use --message or --generate."));
|
|
6021
|
+
console.log(chalk34.dim(" Examples:"));
|
|
6022
|
+
console.log(chalk34.dim(' lovecode commit -m "feat: add login"'));
|
|
6023
|
+
console.log(chalk34.dim(" lovecode commit --generate"));
|
|
6227
6024
|
return;
|
|
6228
6025
|
}
|
|
6229
6026
|
if (opts.all) {
|
|
6230
|
-
console.log(
|
|
6027
|
+
console.log(chalk34.dim(" Staging all changes..."));
|
|
6231
6028
|
}
|
|
6232
6029
|
const result = commit(commitMessage, root || dir);
|
|
6233
6030
|
if (result.success) {
|
|
6234
|
-
console.log(
|
|
6031
|
+
console.log(chalk34.green(` \u2713 Committed${result.hash ? ` (${result.hash.slice(0, 8)})` : ""}`));
|
|
6235
6032
|
if (result.output) {
|
|
6236
6033
|
const lines = result.output.split("\n").filter(Boolean);
|
|
6237
6034
|
for (const line of lines) {
|
|
6238
6035
|
if (line.includes("changed") || line.includes("insertion") || line.includes("deletion")) {
|
|
6239
|
-
console.log(
|
|
6036
|
+
console.log(chalk34.dim(` ${line}`));
|
|
6240
6037
|
}
|
|
6241
6038
|
}
|
|
6242
6039
|
}
|
|
6243
6040
|
} else {
|
|
6244
|
-
console.log(
|
|
6041
|
+
console.log(chalk34.red(` \u2717 ${result.output}`));
|
|
6245
6042
|
}
|
|
6246
6043
|
}
|
|
6247
6044
|
async function cmdStatus(options) {
|
|
@@ -6249,8 +6046,8 @@ async function cmdStatus(options) {
|
|
|
6249
6046
|
const dir = options.dir || process.cwd();
|
|
6250
6047
|
const root = getGitRoot(dir);
|
|
6251
6048
|
const status = getStatus(root || dir);
|
|
6252
|
-
console.log(
|
|
6253
|
-
Git Status \u2014 ${
|
|
6049
|
+
console.log(chalk34.bold(`
|
|
6050
|
+
Git Status \u2014 ${chalk34.cyan(status.branch)}`));
|
|
6254
6051
|
console.log(` ${formatStatus(status)}`);
|
|
6255
6052
|
console.log("");
|
|
6256
6053
|
}
|
|
@@ -6260,39 +6057,39 @@ async function cmdBranch(action, name, options) {
|
|
|
6260
6057
|
const gitRoot = getGitRoot(dir);
|
|
6261
6058
|
if (!action || action === "list") {
|
|
6262
6059
|
const branches = getBranches(gitRoot || dir);
|
|
6263
|
-
console.log(
|
|
6060
|
+
console.log(chalk34.bold(`
|
|
6264
6061
|
Branches (${branches.length}):`));
|
|
6265
6062
|
console.log(` ${formatBranches(branches)}`);
|
|
6266
6063
|
console.log("");
|
|
6267
6064
|
return;
|
|
6268
6065
|
}
|
|
6269
6066
|
if (!name) {
|
|
6270
|
-
console.log(
|
|
6067
|
+
console.log(chalk34.yellow(" Branch name required."));
|
|
6271
6068
|
return;
|
|
6272
6069
|
}
|
|
6273
6070
|
switch (action) {
|
|
6274
6071
|
case "create": {
|
|
6275
6072
|
const ok = createBranch(name, gitRoot || dir);
|
|
6276
|
-
console.log(ok ?
|
|
6073
|
+
console.log(ok ? chalk34.green(` \u2713 Created and switched to "${name}"`) : chalk34.red(` \u2717 Failed to create branch "${name}"`));
|
|
6277
6074
|
break;
|
|
6278
6075
|
}
|
|
6279
6076
|
case "switch": {
|
|
6280
6077
|
const result = switchBranch(name, gitRoot || dir);
|
|
6281
|
-
console.log(result.success ?
|
|
6078
|
+
console.log(result.success ? chalk34.green(` \u2713 Switched to "${name}"`) : chalk34.red(` \u2717 ${result.output}`));
|
|
6282
6079
|
break;
|
|
6283
6080
|
}
|
|
6284
6081
|
case "delete": {
|
|
6285
6082
|
const result = deleteBranch(name, options.force, gitRoot || dir);
|
|
6286
|
-
console.log(result.success ?
|
|
6083
|
+
console.log(result.success ? chalk34.green(` \u2713 Deleted branch "${name}"`) : chalk34.red(` \u2717 ${result.output}`));
|
|
6287
6084
|
break;
|
|
6288
6085
|
}
|
|
6289
6086
|
case "cleanup": {
|
|
6290
|
-
console.log(
|
|
6087
|
+
console.log(chalk34.dim(" Cleaning up merged branches..."));
|
|
6291
6088
|
const deleted = cleanupMergedBranches(gitRoot || dir);
|
|
6292
6089
|
if (deleted.length === 0) {
|
|
6293
|
-
console.log(
|
|
6090
|
+
console.log(chalk34.yellow(" No merged branches to clean up."));
|
|
6294
6091
|
} else {
|
|
6295
|
-
console.log(
|
|
6092
|
+
console.log(chalk34.green(` \u2713 Deleted ${deleted.length} merged branc${deleted.length > 1 ? "hes" : "h"}:`));
|
|
6296
6093
|
for (const b of deleted) {
|
|
6297
6094
|
console.log(` \u2022 ${b}`);
|
|
6298
6095
|
}
|
|
@@ -6300,7 +6097,7 @@ async function cmdBranch(action, name, options) {
|
|
|
6300
6097
|
break;
|
|
6301
6098
|
}
|
|
6302
6099
|
default:
|
|
6303
|
-
console.log(
|
|
6100
|
+
console.log(chalk34.yellow(` Unknown action: ${action}. Use: create, switch, delete, cleanup, or list.`));
|
|
6304
6101
|
}
|
|
6305
6102
|
}
|
|
6306
6103
|
async function cmdLog(options) {
|
|
@@ -6310,10 +6107,10 @@ async function cmdLog(options) {
|
|
|
6310
6107
|
const count = parseInt(options.count || "10", 10);
|
|
6311
6108
|
const log = getLog(count, root || dir);
|
|
6312
6109
|
if (log.length === 0) {
|
|
6313
|
-
console.log(
|
|
6110
|
+
console.log(chalk34.yellow(" No commits found."));
|
|
6314
6111
|
return;
|
|
6315
6112
|
}
|
|
6316
|
-
console.log(
|
|
6113
|
+
console.log(chalk34.bold(`
|
|
6317
6114
|
Recent Commits (${log.length}):`));
|
|
6318
6115
|
console.log(` ${formatLog(log)}`);
|
|
6319
6116
|
console.log("");
|
|
@@ -6321,7 +6118,7 @@ async function cmdLog(options) {
|
|
|
6321
6118
|
async function cmdPRSummary(baseBranch, options) {
|
|
6322
6119
|
if (!requireGit(options.dir)) return;
|
|
6323
6120
|
const base = baseBranch || "main";
|
|
6324
|
-
console.log(
|
|
6121
|
+
console.log(chalk34.dim(` Generating PR summary (${base}...HEAD)...`));
|
|
6325
6122
|
const summary = await generatePRSummary(base);
|
|
6326
6123
|
console.log(`
|
|
6327
6124
|
${summary}
|
|
@@ -6345,21 +6142,21 @@ async function cmdDiff(options) {
|
|
|
6345
6142
|
if (!requireGit(options.dir)) return;
|
|
6346
6143
|
const dir = options.dir || process.cwd();
|
|
6347
6144
|
const root = getGitRoot(dir);
|
|
6348
|
-
const diff = options.staged ? (await import("./git-
|
|
6145
|
+
const diff = options.staged ? (await import("./git-FZPRJVFI.js")).getStagedDiff(root || dir) : getDiff(root || dir);
|
|
6349
6146
|
if (!diff) {
|
|
6350
|
-
console.log(
|
|
6147
|
+
console.log(chalk34.yellow(" No changes to show."));
|
|
6351
6148
|
return;
|
|
6352
6149
|
}
|
|
6353
6150
|
const lines = diff.split("\n");
|
|
6354
6151
|
for (const line of lines) {
|
|
6355
6152
|
if (line.startsWith("+")) {
|
|
6356
|
-
process.stdout.write(
|
|
6153
|
+
process.stdout.write(chalk34.green(line) + "\n");
|
|
6357
6154
|
} else if (line.startsWith("-")) {
|
|
6358
|
-
process.stdout.write(
|
|
6155
|
+
process.stdout.write(chalk34.red(line) + "\n");
|
|
6359
6156
|
} else if (line.startsWith("@@")) {
|
|
6360
|
-
process.stdout.write(
|
|
6157
|
+
process.stdout.write(chalk34.cyan(line) + "\n");
|
|
6361
6158
|
} else if (line.startsWith("diff --git")) {
|
|
6362
|
-
process.stdout.write(
|
|
6159
|
+
process.stdout.write(chalk34.bold(line) + "\n");
|
|
6363
6160
|
} else {
|
|
6364
6161
|
process.stdout.write(line + "\n");
|
|
6365
6162
|
}
|
|
@@ -6403,7 +6200,7 @@ gitCommand.command("diff").description("Show diff").option("--staged", "Show sta
|
|
|
6403
6200
|
|
|
6404
6201
|
// src/commands/tui.ts
|
|
6405
6202
|
import { Command as Command13 } from "commander";
|
|
6406
|
-
import
|
|
6203
|
+
import chalk35 from "chalk";
|
|
6407
6204
|
|
|
6408
6205
|
// src/tui/index.ts
|
|
6409
6206
|
import React4 from "react";
|
|
@@ -6842,6 +6639,34 @@ function App({
|
|
|
6842
6639
|
setFocus(focus === "chat" ? "command" : focus === "command" ? "repo" : focus === "repo" ? "chat" : "chat");
|
|
6843
6640
|
}
|
|
6844
6641
|
});
|
|
6642
|
+
async function handleConnect() {
|
|
6643
|
+
try {
|
|
6644
|
+
const { getAllProviders } = await import("./registry-ADSIKXA4.js");
|
|
6645
|
+
const { loadConfig: loadConfig2 } = await import("./config-FJNTTKR3.js");
|
|
6646
|
+
const { loadEnv: loadEnv2 } = await import("./env-HJQWWL6N.js");
|
|
6647
|
+
loadEnv2();
|
|
6648
|
+
const providers = getAllProviders();
|
|
6649
|
+
const config = loadConfig2();
|
|
6650
|
+
let info = "\u26A1 **Connect to an AI Provider**\n\n";
|
|
6651
|
+
info += "**Current config:**\n";
|
|
6652
|
+
info += ` Provider: ${config.provider || "not set"}
|
|
6653
|
+
`;
|
|
6654
|
+
info += ` Model: ${config.model || "not set"}
|
|
6655
|
+
|
|
6656
|
+
`;
|
|
6657
|
+
info += "**Available providers:**\n";
|
|
6658
|
+
for (const p of providers) {
|
|
6659
|
+
const tag = p.local ? "(local)" : "(cloud)";
|
|
6660
|
+
const configured = config.provider === p.name ? " \u2190 active" : "";
|
|
6661
|
+
info += ` ${p.name} ${tag}${configured}
|
|
6662
|
+
`;
|
|
6663
|
+
}
|
|
6664
|
+
info += "\n**To configure:** use `lovecode init` in your terminal, then restart TUI";
|
|
6665
|
+
setMessages((prev) => [...prev, { role: "assistant", content: info }]);
|
|
6666
|
+
} catch (err) {
|
|
6667
|
+
setMessages((prev) => [...prev, { role: "system", content: `Error loading providers: ${err.message}` }]);
|
|
6668
|
+
}
|
|
6669
|
+
}
|
|
6845
6670
|
async function handleSend(text) {
|
|
6846
6671
|
const userMsg = { role: "user", content: text };
|
|
6847
6672
|
setMessages((prev) => [...prev, userMsg]);
|
|
@@ -6866,7 +6691,9 @@ function App({
|
|
|
6866
6691
|
function handleCommand(text) {
|
|
6867
6692
|
const cmd = text.slice(1).toLowerCase();
|
|
6868
6693
|
if (cmd === "help") {
|
|
6869
|
-
setMessages((prev) => [...prev, { role: "system", content: "Commands: /help, /clear, /theme <name>, /vim, /exit" }]);
|
|
6694
|
+
setMessages((prev) => [...prev, { role: "system", content: "Commands: /help, /clear, /theme <name>, /connect, /vim, /exit" }]);
|
|
6695
|
+
} else if (cmd === "connect") {
|
|
6696
|
+
handleConnect();
|
|
6870
6697
|
} else if (cmd === "clear") {
|
|
6871
6698
|
setMessages([]);
|
|
6872
6699
|
} else if (cmd.startsWith("theme ")) {
|
|
@@ -6964,7 +6791,7 @@ function startTUI(props) {
|
|
|
6964
6791
|
|
|
6965
6792
|
// src/commands/tui.ts
|
|
6966
6793
|
async function cmdTUI(options) {
|
|
6967
|
-
console.log(
|
|
6794
|
+
console.log(chalk35.dim("Starting LoveCode TUI..."));
|
|
6968
6795
|
if (options.theme) {
|
|
6969
6796
|
const mod = await import("./theme-ZRZYRB2Q.js");
|
|
6970
6797
|
const names = mod.getThemeNames();
|
|
@@ -6973,7 +6800,7 @@ async function cmdTUI(options) {
|
|
|
6973
6800
|
if (names.includes(themeName)) {
|
|
6974
6801
|
mod.setTheme(n);
|
|
6975
6802
|
} else {
|
|
6976
|
-
console.log(
|
|
6803
|
+
console.log(chalk35.yellow(`Unknown theme "${options.theme}". Using default. Available: ${names.join(", ")}`));
|
|
6977
6804
|
}
|
|
6978
6805
|
}
|
|
6979
6806
|
startTUI({
|
|
@@ -7013,7 +6840,7 @@ var tuiCommand = new Command13("tui").alias("ui").description("Launch the Termin
|
|
|
7013
6840
|
|
|
7014
6841
|
// src/commands/plugin.ts
|
|
7015
6842
|
import { Command as Command14 } from "commander";
|
|
7016
|
-
import
|
|
6843
|
+
import chalk36 from "chalk";
|
|
7017
6844
|
async function cmdListPlugins() {
|
|
7018
6845
|
const { listPlugins: listPlugins2, formatPluginList } = await import("./registry-MW5ISDO7.js");
|
|
7019
6846
|
const plugins = listPlugins2();
|
|
@@ -7022,12 +6849,12 @@ async function cmdListPlugins() {
|
|
|
7022
6849
|
async function cmdEnablePlugin(name) {
|
|
7023
6850
|
const { enablePlugin: enablePlugin2 } = await import("./registry-MW5ISDO7.js");
|
|
7024
6851
|
const ok = enablePlugin2(name);
|
|
7025
|
-
console.log(ok ?
|
|
6852
|
+
console.log(ok ? chalk36.green(`Enabled plugin: ${name}`) : chalk36.red(`Plugin not found: ${name}`));
|
|
7026
6853
|
}
|
|
7027
6854
|
async function cmdDisablePlugin(name) {
|
|
7028
6855
|
const { disablePlugin: disablePlugin2 } = await import("./registry-MW5ISDO7.js");
|
|
7029
6856
|
const ok = disablePlugin2(name);
|
|
7030
|
-
console.log(ok ?
|
|
6857
|
+
console.log(ok ? chalk36.yellow(`Disabled plugin: ${name}`) : chalk36.red(`Plugin not found: ${name}`));
|
|
7031
6858
|
}
|
|
7032
6859
|
async function cmdSearchMarketplace(query) {
|
|
7033
6860
|
const { searchMarketplace, formatMarketplace } = await import("./registry-MW5ISDO7.js");
|
|
@@ -7048,37 +6875,37 @@ pluginCommand.command("search").description("Search plugin marketplace").argumen
|
|
|
7048
6875
|
|
|
7049
6876
|
// src/commands/browser.ts
|
|
7050
6877
|
import { Command as Command15 } from "commander";
|
|
7051
|
-
import
|
|
6878
|
+
import chalk37 from "chalk";
|
|
7052
6879
|
async function cmdStart(options) {
|
|
7053
6880
|
const { launchBrowser } = await import("./playwright-N7OAVW2N.js");
|
|
7054
6881
|
try {
|
|
7055
6882
|
await launchBrowser({ headless: options.headless !== false });
|
|
7056
|
-
console.log(
|
|
6883
|
+
console.log(chalk37.green("Browser launched."));
|
|
7057
6884
|
} catch (err) {
|
|
7058
|
-
console.log(
|
|
6885
|
+
console.log(chalk37.red(`Failed: ${err.message}`));
|
|
7059
6886
|
}
|
|
7060
6887
|
}
|
|
7061
6888
|
async function cmdStop() {
|
|
7062
6889
|
const { closeBrowser } = await import("./playwright-N7OAVW2N.js");
|
|
7063
6890
|
await closeBrowser();
|
|
7064
|
-
console.log(
|
|
6891
|
+
console.log(chalk37.yellow("Browser closed."));
|
|
7065
6892
|
}
|
|
7066
6893
|
async function cmdGoto(url) {
|
|
7067
6894
|
const { goto: goto2 } = await import("./playwright-N7OAVW2N.js");
|
|
7068
6895
|
try {
|
|
7069
6896
|
const result = await goto2(url);
|
|
7070
|
-
console.log(
|
|
6897
|
+
console.log(chalk37.green(result));
|
|
7071
6898
|
} catch (err) {
|
|
7072
|
-
console.log(
|
|
6899
|
+
console.log(chalk37.red(`Error: ${err.message}`));
|
|
7073
6900
|
}
|
|
7074
6901
|
}
|
|
7075
6902
|
async function cmdClick(selector) {
|
|
7076
6903
|
const { click: click2 } = await import("./playwright-N7OAVW2N.js");
|
|
7077
6904
|
try {
|
|
7078
6905
|
const result = await click2(selector);
|
|
7079
|
-
console.log(
|
|
6906
|
+
console.log(chalk37.green(result));
|
|
7080
6907
|
} catch (err) {
|
|
7081
|
-
console.log(
|
|
6908
|
+
console.log(chalk37.red(`Error: ${err.message}`));
|
|
7082
6909
|
}
|
|
7083
6910
|
}
|
|
7084
6911
|
async function cmdType(selector, text, options) {
|
|
@@ -7086,18 +6913,18 @@ async function cmdType(selector, text, options) {
|
|
|
7086
6913
|
const value = text || options.text || "";
|
|
7087
6914
|
try {
|
|
7088
6915
|
const result = await type2(selector, value);
|
|
7089
|
-
console.log(
|
|
6916
|
+
console.log(chalk37.green(result));
|
|
7090
6917
|
} catch (err) {
|
|
7091
|
-
console.log(
|
|
6918
|
+
console.log(chalk37.red(`Error: ${err.message}`));
|
|
7092
6919
|
}
|
|
7093
6920
|
}
|
|
7094
6921
|
async function cmdScreenshot(options) {
|
|
7095
6922
|
const { screenshot: screenshot2, formatScreenshotResult: formatScreenshotResult2 } = await import("./playwright-N7OAVW2N.js");
|
|
7096
6923
|
try {
|
|
7097
6924
|
const result = await screenshot2(options.name);
|
|
7098
|
-
console.log(
|
|
6925
|
+
console.log(chalk37.green(formatScreenshotResult2(result)));
|
|
7099
6926
|
} catch (err) {
|
|
7100
|
-
console.log(
|
|
6927
|
+
console.log(chalk37.red(`Error: ${err.message}`));
|
|
7101
6928
|
}
|
|
7102
6929
|
}
|
|
7103
6930
|
async function cmdInspect(selector) {
|
|
@@ -7107,18 +6934,18 @@ async function cmdInspect(selector) {
|
|
|
7107
6934
|
if (el) {
|
|
7108
6935
|
console.log(formatDOMElement2(el));
|
|
7109
6936
|
} else {
|
|
7110
|
-
console.log(
|
|
6937
|
+
console.log(chalk37.yellow(`Element not found: ${selector}`));
|
|
7111
6938
|
}
|
|
7112
6939
|
} catch (err) {
|
|
7113
|
-
console.log(
|
|
6940
|
+
console.log(chalk37.red(`Error: ${err.message}`));
|
|
7114
6941
|
}
|
|
7115
6942
|
}
|
|
7116
6943
|
async function cmdActions(actions, options) {
|
|
7117
6944
|
const { runActions } = await import("./playwright-N7OAVW2N.js");
|
|
7118
6945
|
let parsedActions;
|
|
7119
6946
|
if (options.file) {
|
|
7120
|
-
const
|
|
7121
|
-
const content =
|
|
6947
|
+
const fs25 = await import("fs");
|
|
6948
|
+
const content = fs25.readFileSync(options.file, "utf-8");
|
|
7122
6949
|
parsedActions = JSON.parse(content);
|
|
7123
6950
|
} else {
|
|
7124
6951
|
parsedActions = actions.map((a) => JSON.parse(a));
|
|
@@ -7126,10 +6953,10 @@ async function cmdActions(actions, options) {
|
|
|
7126
6953
|
try {
|
|
7127
6954
|
const results = await runActions(parsedActions);
|
|
7128
6955
|
for (const r of results) {
|
|
7129
|
-
console.log(
|
|
6956
|
+
console.log(chalk37.cyan(` \u2192 ${r.slice(0, 200)}`));
|
|
7130
6957
|
}
|
|
7131
6958
|
} catch (err) {
|
|
7132
|
-
console.log(
|
|
6959
|
+
console.log(chalk37.red(`Error: ${err.message}`));
|
|
7133
6960
|
}
|
|
7134
6961
|
}
|
|
7135
6962
|
var browserCommand = new Command15("browser").alias("br").description("Browser automation \u2014 Playwright-powered").addHelpText("after", `
|
|
@@ -7156,10 +6983,10 @@ browserCommand.command("actions").description("Run a sequence of browser actions
|
|
|
7156
6983
|
|
|
7157
6984
|
// src/commands/security.ts
|
|
7158
6985
|
import { Command as Command16 } from "commander";
|
|
7159
|
-
import
|
|
6986
|
+
import chalk42 from "chalk";
|
|
7160
6987
|
|
|
7161
6988
|
// src/security/risk.ts
|
|
7162
|
-
import
|
|
6989
|
+
import chalk38 from "chalk";
|
|
7163
6990
|
var COMMAND_RULES = [
|
|
7164
6991
|
{ pattern: /^rm\s+-rf\s+(\/|\/\w+|\.)/, score: 100, reason: "Destructive recursive delete" },
|
|
7165
6992
|
{ pattern: /^rm\s+-rf/, score: 80, reason: "Recursive force delete" },
|
|
@@ -7270,21 +7097,21 @@ function scoreToAction(score) {
|
|
|
7270
7097
|
}
|
|
7271
7098
|
function formatRisk(risk) {
|
|
7272
7099
|
const colors = {
|
|
7273
|
-
safe:
|
|
7274
|
-
low:
|
|
7275
|
-
medium:
|
|
7276
|
-
high:
|
|
7277
|
-
critical:
|
|
7100
|
+
safe: chalk38.green,
|
|
7101
|
+
low: chalk38.cyan,
|
|
7102
|
+
medium: chalk38.yellow,
|
|
7103
|
+
high: chalk38.red,
|
|
7104
|
+
critical: chalk38.bgRed.white
|
|
7278
7105
|
};
|
|
7279
|
-
const color = colors[risk.level] ||
|
|
7106
|
+
const color = colors[risk.level] || chalk38.dim;
|
|
7280
7107
|
const label = risk.level.toUpperCase().padEnd(10);
|
|
7281
|
-
const action = risk.suggestedAction === "auto" ?
|
|
7282
|
-
return ` ${color(label)} score=${risk.score} action=${action} ${
|
|
7108
|
+
const action = risk.suggestedAction === "auto" ? chalk38.green(risk.suggestedAction) : risk.suggestedAction === "confirm" ? chalk38.yellow(risk.suggestedAction) : chalk38.bgRed.white(` ${risk.suggestedAction} `);
|
|
7109
|
+
return ` ${color(label)} score=${risk.score} action=${action} ${chalk38.dim(risk.reasons.join(", "))}`;
|
|
7283
7110
|
}
|
|
7284
7111
|
|
|
7285
7112
|
// src/security/secrets.ts
|
|
7286
|
-
import * as
|
|
7287
|
-
import
|
|
7113
|
+
import * as fs23 from "fs";
|
|
7114
|
+
import chalk39 from "chalk";
|
|
7288
7115
|
var SECRET_RULES = [
|
|
7289
7116
|
{ type: "aws_key", pattern: /(?:AKIA|ASIA)[0-9A-Z]{16}/g, severity: "critical", description: "AWS Access Key ID" },
|
|
7290
7117
|
{ type: "gcp_key", pattern: /AIza[0-9A-Za-z\-_]{35}/g, severity: "critical", description: "GCP API Key" },
|
|
@@ -7332,7 +7159,7 @@ function scanText(text, fileName) {
|
|
|
7332
7159
|
}
|
|
7333
7160
|
function scanFile(filePath) {
|
|
7334
7161
|
try {
|
|
7335
|
-
const content =
|
|
7162
|
+
const content = fs23.readFileSync(filePath, "utf-8");
|
|
7336
7163
|
return scanText(content, filePath);
|
|
7337
7164
|
} catch {
|
|
7338
7165
|
return [];
|
|
@@ -7344,7 +7171,7 @@ function scanDirectory2(dirPath, maxFiles = 100) {
|
|
|
7344
7171
|
function walk(dir) {
|
|
7345
7172
|
if (count >= maxFiles) return;
|
|
7346
7173
|
try {
|
|
7347
|
-
const entries =
|
|
7174
|
+
const entries = fs23.readdirSync(dir, { withFileTypes: true });
|
|
7348
7175
|
for (const entry of entries) {
|
|
7349
7176
|
if (count >= maxFiles) return;
|
|
7350
7177
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist") continue;
|
|
@@ -7369,30 +7196,30 @@ function scanDirectory2(dirPath, maxFiles = 100) {
|
|
|
7369
7196
|
}
|
|
7370
7197
|
function formatSecretMatch(match) {
|
|
7371
7198
|
const severityColor = {
|
|
7372
|
-
low:
|
|
7373
|
-
medium:
|
|
7374
|
-
high:
|
|
7375
|
-
critical:
|
|
7199
|
+
low: chalk39.cyan,
|
|
7200
|
+
medium: chalk39.yellow,
|
|
7201
|
+
high: chalk39.red,
|
|
7202
|
+
critical: chalk39.bgRed.white
|
|
7376
7203
|
};
|
|
7377
|
-
const sev = severityColor[match.severity] ||
|
|
7378
|
-
const fileInfo = match.file ? `${
|
|
7204
|
+
const sev = severityColor[match.severity] || chalk39.dim;
|
|
7205
|
+
const fileInfo = match.file ? `${chalk39.dim(match.file)}:${match.line}:${match.column}` : `line ${match.line}:${match.column}`;
|
|
7379
7206
|
return ` ${sev(match.severity.toUpperCase().padEnd(10))} ${match.type.padEnd(20)} ${match.value.padEnd(30)} ${fileInfo}
|
|
7380
|
-
${
|
|
7207
|
+
${chalk39.dim(match.context)}`;
|
|
7381
7208
|
}
|
|
7382
7209
|
function formatSecretSummary(matches) {
|
|
7383
|
-
if (matches.length === 0) return
|
|
7210
|
+
if (matches.length === 0) return chalk39.green("No secrets detected.");
|
|
7384
7211
|
const bySeverity = /* @__PURE__ */ new Map();
|
|
7385
7212
|
for (const m of matches) {
|
|
7386
7213
|
const arr = bySeverity.get(m.severity) || [];
|
|
7387
7214
|
arr.push(m);
|
|
7388
7215
|
bySeverity.set(m.severity, arr);
|
|
7389
7216
|
}
|
|
7390
|
-
const lines = [
|
|
7217
|
+
const lines = [chalk39.bold(`
|
|
7391
7218
|
Secrets Detected (${matches.length}):`)];
|
|
7392
7219
|
for (const [severity, ms] of bySeverity) {
|
|
7393
7220
|
const label = severity.toUpperCase();
|
|
7394
7221
|
lines.push(`
|
|
7395
|
-
${
|
|
7222
|
+
${chalk39.bold(label)} (${ms.length}):`);
|
|
7396
7223
|
for (const m of ms.slice(0, 10)) {
|
|
7397
7224
|
lines.push(formatSecretMatch(m));
|
|
7398
7225
|
}
|
|
@@ -7402,7 +7229,7 @@ function formatSecretSummary(matches) {
|
|
|
7402
7229
|
}
|
|
7403
7230
|
|
|
7404
7231
|
// src/security/sandbox.ts
|
|
7405
|
-
import
|
|
7232
|
+
import chalk40 from "chalk";
|
|
7406
7233
|
var PROFILES = {
|
|
7407
7234
|
isolated: {
|
|
7408
7235
|
name: "isolated",
|
|
@@ -7531,10 +7358,10 @@ function checkCommand(command, cwd, profileName) {
|
|
|
7531
7358
|
return { allowed: true };
|
|
7532
7359
|
}
|
|
7533
7360
|
function formatProfile(profile) {
|
|
7534
|
-
const yes =
|
|
7535
|
-
const no =
|
|
7361
|
+
const yes = chalk40.green("\u2713");
|
|
7362
|
+
const no = chalk40.red("\u2717");
|
|
7536
7363
|
return [
|
|
7537
|
-
`${
|
|
7364
|
+
`${chalk40.bold(profile.name.toUpperCase())}`,
|
|
7538
7365
|
` Network: ${profile.allowNetwork ? yes : no}`,
|
|
7539
7366
|
` File Read: ${profile.allowFileRead ? yes : no}`,
|
|
7540
7367
|
` File Write: ${profile.allowFileWrite ? yes : no}`,
|
|
@@ -7546,9 +7373,9 @@ function formatProfile(profile) {
|
|
|
7546
7373
|
}
|
|
7547
7374
|
|
|
7548
7375
|
// src/security/permissions.ts
|
|
7549
|
-
import * as
|
|
7550
|
-
import * as
|
|
7551
|
-
import
|
|
7376
|
+
import * as fs24 from "fs";
|
|
7377
|
+
import * as path22 from "path";
|
|
7378
|
+
import chalk41 from "chalk";
|
|
7552
7379
|
var PERMISSION_FILE = ".lovecode/permissions.json";
|
|
7553
7380
|
var DEFAULT_PERMISSIONS = {
|
|
7554
7381
|
version: 1,
|
|
@@ -7564,18 +7391,18 @@ var DEFAULT_PERMISSIONS = {
|
|
|
7564
7391
|
};
|
|
7565
7392
|
var cachedPermissions = null;
|
|
7566
7393
|
function getPermPath(rootDir) {
|
|
7567
|
-
return
|
|
7394
|
+
return path22.join(rootDir || process.cwd(), PERMISSION_FILE);
|
|
7568
7395
|
}
|
|
7569
7396
|
function loadPermissions(rootDir) {
|
|
7570
7397
|
if (cachedPermissions) return cachedPermissions;
|
|
7571
7398
|
const filePath = getPermPath(rootDir);
|
|
7572
|
-
if (!
|
|
7399
|
+
if (!fs24.existsSync(filePath)) {
|
|
7573
7400
|
savePermissions(DEFAULT_PERMISSIONS, rootDir);
|
|
7574
7401
|
cachedPermissions = { ...DEFAULT_PERMISSIONS };
|
|
7575
7402
|
return cachedPermissions;
|
|
7576
7403
|
}
|
|
7577
7404
|
try {
|
|
7578
|
-
const raw =
|
|
7405
|
+
const raw = fs24.readFileSync(filePath, "utf-8");
|
|
7579
7406
|
cachedPermissions = JSON.parse(raw);
|
|
7580
7407
|
return cachedPermissions;
|
|
7581
7408
|
} catch {
|
|
@@ -7585,11 +7412,11 @@ function loadPermissions(rootDir) {
|
|
|
7585
7412
|
}
|
|
7586
7413
|
function savePermissions(perms, rootDir) {
|
|
7587
7414
|
const filePath = getPermPath(rootDir);
|
|
7588
|
-
const dir =
|
|
7589
|
-
if (!
|
|
7590
|
-
|
|
7415
|
+
const dir = path22.dirname(filePath);
|
|
7416
|
+
if (!fs24.existsSync(dir)) {
|
|
7417
|
+
fs24.mkdirSync(dir, { recursive: true });
|
|
7591
7418
|
}
|
|
7592
|
-
|
|
7419
|
+
fs24.writeFileSync(filePath, JSON.stringify(perms, null, 2), "utf-8");
|
|
7593
7420
|
cachedPermissions = perms;
|
|
7594
7421
|
}
|
|
7595
7422
|
function setDefault(key, value, rootDir) {
|
|
@@ -7655,30 +7482,30 @@ function removeTrustedSource(source, rootDir) {
|
|
|
7655
7482
|
}
|
|
7656
7483
|
function resetPermissions(rootDir) {
|
|
7657
7484
|
const filePath = getPermPath(rootDir);
|
|
7658
|
-
if (
|
|
7659
|
-
|
|
7485
|
+
if (fs24.existsSync(filePath)) {
|
|
7486
|
+
fs24.unlinkSync(filePath);
|
|
7660
7487
|
}
|
|
7661
7488
|
cachedPermissions = null;
|
|
7662
7489
|
}
|
|
7663
7490
|
function formatPermissions(perms) {
|
|
7664
|
-
const lines = [
|
|
7665
|
-
lines.push(` ${
|
|
7666
|
-
lines.push(` ${
|
|
7667
|
-
lines.push(` ${
|
|
7668
|
-
lines.push(` ${
|
|
7669
|
-
lines.push(` ${
|
|
7491
|
+
const lines = [chalk41.bold("\n Permission Settings")];
|
|
7492
|
+
lines.push(` ${chalk41.dim("File Read:")} ${formatAction(perms.defaults.fileRead)}`);
|
|
7493
|
+
lines.push(` ${chalk41.dim("File Write:")} ${formatAction(perms.defaults.fileWrite)}`);
|
|
7494
|
+
lines.push(` ${chalk41.dim("Network:")} ${formatAction(perms.defaults.networkAccess)}`);
|
|
7495
|
+
lines.push(` ${chalk41.dim("Commands:")} ${formatAction(perms.defaults.commandExecution)}`);
|
|
7496
|
+
lines.push(` ${chalk41.dim("Environment:")} ${formatAction(perms.defaults.environmentAccess)}`);
|
|
7670
7497
|
if (perms.entries.length > 0) {
|
|
7671
7498
|
lines.push(`
|
|
7672
|
-
${
|
|
7499
|
+
${chalk41.bold("Specific Permissions:")}`);
|
|
7673
7500
|
for (const e of perms.entries) {
|
|
7674
|
-
lines.push(` ${formatAction(e.action)} ${e.resource}${e.reason ? ` ${
|
|
7501
|
+
lines.push(` ${formatAction(e.action)} ${e.resource}${e.reason ? ` ${chalk41.dim(`(${e.reason})`)}` : ""}`);
|
|
7675
7502
|
}
|
|
7676
7503
|
}
|
|
7677
7504
|
if (perms.trustedSources.length > 0) {
|
|
7678
7505
|
lines.push(`
|
|
7679
|
-
${
|
|
7506
|
+
${chalk41.bold("Trusted Sources:")}`);
|
|
7680
7507
|
for (const s of perms.trustedSources) {
|
|
7681
|
-
lines.push(` ${
|
|
7508
|
+
lines.push(` ${chalk41.green("\u2713")} ${s}`);
|
|
7682
7509
|
}
|
|
7683
7510
|
}
|
|
7684
7511
|
return lines.join("\n");
|
|
@@ -7686,11 +7513,11 @@ function formatPermissions(perms) {
|
|
|
7686
7513
|
function formatAction(action) {
|
|
7687
7514
|
switch (action) {
|
|
7688
7515
|
case "allow":
|
|
7689
|
-
return
|
|
7516
|
+
return chalk41.green("ALLOW");
|
|
7690
7517
|
case "deny":
|
|
7691
|
-
return
|
|
7518
|
+
return chalk41.red("DENY");
|
|
7692
7519
|
case "ask":
|
|
7693
|
-
return
|
|
7520
|
+
return chalk41.yellow("ASK");
|
|
7694
7521
|
}
|
|
7695
7522
|
}
|
|
7696
7523
|
|
|
@@ -7699,8 +7526,8 @@ async function cmdAssessRisk(command, options) {
|
|
|
7699
7526
|
if (command) {
|
|
7700
7527
|
const risk = assessCommandRisk(command);
|
|
7701
7528
|
console.log(`
|
|
7702
|
-
${
|
|
7703
|
-
console.log(` ${
|
|
7529
|
+
${chalk42.bold("Command Risk Assessment")}`);
|
|
7530
|
+
console.log(` ${chalk42.dim(command)}`);
|
|
7704
7531
|
console.log(formatRisk(risk));
|
|
7705
7532
|
} else if (options.tool) {
|
|
7706
7533
|
let args;
|
|
@@ -7713,11 +7540,11 @@ async function cmdAssessRisk(command, options) {
|
|
|
7713
7540
|
}
|
|
7714
7541
|
const risk = assessToolRisk(options.tool, args);
|
|
7715
7542
|
console.log(`
|
|
7716
|
-
${
|
|
7717
|
-
console.log(` ${
|
|
7543
|
+
${chalk42.bold("Tool Risk Assessment")}`);
|
|
7544
|
+
console.log(` ${chalk42.dim(`${options.tool}${args ? " " + JSON.stringify(args) : ""}`)}`);
|
|
7718
7545
|
console.log(formatRisk(risk));
|
|
7719
7546
|
} else {
|
|
7720
|
-
console.log(
|
|
7547
|
+
console.log(chalk42.yellow("Provide a command string or --tool."));
|
|
7721
7548
|
}
|
|
7722
7549
|
}
|
|
7723
7550
|
async function cmdScanSecrets(options) {
|
|
@@ -7726,16 +7553,16 @@ async function cmdScanSecrets(options) {
|
|
|
7726
7553
|
console.log(formatSecretSummary(matches));
|
|
7727
7554
|
} else if (options.dir) {
|
|
7728
7555
|
const max = parseInt(options.max || "100", 10);
|
|
7729
|
-
console.log(
|
|
7556
|
+
console.log(chalk42.dim(`Scanning ${options.dir} for secrets...`));
|
|
7730
7557
|
const matches = scanDirectory2(options.dir, max);
|
|
7731
7558
|
console.log(formatSecretSummary(matches));
|
|
7732
7559
|
} else {
|
|
7733
|
-
console.log(
|
|
7560
|
+
console.log(chalk42.yellow("Provide --text or --dir."));
|
|
7734
7561
|
}
|
|
7735
7562
|
}
|
|
7736
7563
|
async function cmdProfiles() {
|
|
7737
7564
|
const profiles = listProfiles();
|
|
7738
|
-
console.log(
|
|
7565
|
+
console.log(chalk42.bold("\n Sandbox Profiles:\n"));
|
|
7739
7566
|
for (const p of profiles) {
|
|
7740
7567
|
console.log(formatProfile(p));
|
|
7741
7568
|
console.log("");
|
|
@@ -7744,35 +7571,35 @@ async function cmdProfiles() {
|
|
|
7744
7571
|
async function cmdSandbox(command, options) {
|
|
7745
7572
|
const result = checkCommand(command, process.cwd(), options.profile);
|
|
7746
7573
|
if (result.allowed) {
|
|
7747
|
-
console.log(
|
|
7748
|
-
Allowed: ${
|
|
7574
|
+
console.log(chalk42.green(`
|
|
7575
|
+
Allowed: ${chalk42.dim(command)}`));
|
|
7749
7576
|
} else {
|
|
7750
|
-
console.log(
|
|
7751
|
-
Blocked: ${
|
|
7752
|
-
console.log(` ${
|
|
7577
|
+
console.log(chalk42.red(`
|
|
7578
|
+
Blocked: ${chalk42.dim(command)}`));
|
|
7579
|
+
console.log(` ${chalk42.yellow(result.reason)}`);
|
|
7753
7580
|
}
|
|
7754
7581
|
}
|
|
7755
7582
|
async function cmdPermissions(options) {
|
|
7756
7583
|
if (options.set && options.action) {
|
|
7757
7584
|
const defaults = ["fileRead", "fileWrite", "networkAccess", "commandExecution", "environmentAccess"];
|
|
7758
7585
|
if (!defaults.includes(options.set)) {
|
|
7759
|
-
console.log(
|
|
7586
|
+
console.log(chalk42.red(`Invalid default: ${options.set}. Options: ${defaults.join(", ")}`));
|
|
7760
7587
|
return;
|
|
7761
7588
|
}
|
|
7762
7589
|
const perms = setDefault(options.set, options.action, options.dir);
|
|
7763
|
-
console.log(
|
|
7590
|
+
console.log(chalk42.green(`Default "${options.set}" set to "${options.action}".`));
|
|
7764
7591
|
console.log(formatPermissions(perms));
|
|
7765
7592
|
} else if (options.add && options.action) {
|
|
7766
7593
|
const action = options.action;
|
|
7767
7594
|
const perms = addPermission(options.add, action, void 0, options.dir);
|
|
7768
|
-
console.log(
|
|
7595
|
+
console.log(chalk42.green(`Permission added: ${options.add} \u2192 ${action}`));
|
|
7769
7596
|
console.log(formatPermissions(perms));
|
|
7770
7597
|
} else if (options.remove) {
|
|
7771
7598
|
const ok = removePermission(options.remove, options.dir);
|
|
7772
|
-
console.log(ok ?
|
|
7599
|
+
console.log(ok ? chalk42.green(`Removed permission: ${options.remove}`) : chalk42.yellow(`Permission not found: ${options.remove}`));
|
|
7773
7600
|
} else if (options.source) {
|
|
7774
7601
|
addTrustedSource(options.source, options.dir);
|
|
7775
|
-
console.log(
|
|
7602
|
+
console.log(chalk42.green(`Trusted source added: ${options.source}`));
|
|
7776
7603
|
} else {
|
|
7777
7604
|
const perms = loadPermissions(options.dir);
|
|
7778
7605
|
console.log(formatPermissions(perms));
|
|
@@ -7781,16 +7608,16 @@ async function cmdPermissions(options) {
|
|
|
7781
7608
|
async function cmdCheckPermission(resource, options) {
|
|
7782
7609
|
const category = options.category || "fileRead";
|
|
7783
7610
|
const result = checkPermission(resource, category, options.dir);
|
|
7784
|
-
const color = result === "allow" ?
|
|
7785
|
-
console.log(` ${color(result.toUpperCase())} ${
|
|
7611
|
+
const color = result === "allow" ? chalk42.green : result === "deny" ? chalk42.red : chalk42.yellow;
|
|
7612
|
+
console.log(` ${color(result.toUpperCase())} ${chalk42.dim(resource)} (${category})`);
|
|
7786
7613
|
}
|
|
7787
7614
|
async function cmdReset(options) {
|
|
7788
7615
|
resetPermissions(options.dir);
|
|
7789
|
-
console.log(
|
|
7616
|
+
console.log(chalk42.green("Permissions reset to defaults."));
|
|
7790
7617
|
}
|
|
7791
7618
|
async function cmdRemoveSource(source, options) {
|
|
7792
7619
|
const ok = removeTrustedSource(source, options.dir);
|
|
7793
|
-
console.log(ok ?
|
|
7620
|
+
console.log(ok ? chalk42.green(`Removed trusted source: ${source}`) : chalk42.yellow(`Source not found: ${source}`));
|
|
7794
7621
|
}
|
|
7795
7622
|
var securityCommand = new Command16("security").alias("sec").alias("secure").description("Security tools: risk assessment, secret detection, sandbox, permissions").addHelpText("after", `
|
|
7796
7623
|
Examples:
|
|
@@ -7825,7 +7652,7 @@ var pkg = {
|
|
|
7825
7652
|
description: "Terminal-native autonomous coding agent powered by free AI models"
|
|
7826
7653
|
};
|
|
7827
7654
|
var program = new Command17();
|
|
7828
|
-
program.name(pkg.name).description(
|
|
7655
|
+
program.name(pkg.name).description(chalk43.cyan(pkg.description)).version(pkg.version, "-v, --version", "Output the current version");
|
|
7829
7656
|
program.addCommand(chatCommand);
|
|
7830
7657
|
program.addCommand(runCommand);
|
|
7831
7658
|
program.addCommand(initCommand);
|