lovecode-ai 0.1.6 → 0.1.8

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.
Files changed (2) hide show
  1. package/dist/index.js +692 -281
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -82,7 +82,7 @@ import {
82
82
 
83
83
  // src/index.ts
84
84
  import { Command as Command17 } from "commander";
85
- import chalk43 from "chalk";
85
+ import chalk44 from "chalk";
86
86
 
87
87
  // src/commands/chat.ts
88
88
  import { Command } from "commander";
@@ -4990,8 +4990,121 @@ configCommand.action(cmdShow);
4990
4990
 
4991
4991
  // src/commands/env.ts
4992
4992
  import { Command as Command5 } from "commander";
4993
- import chalk24 from "chalk";
4993
+ import chalk25 from "chalk";
4994
4994
  import inquirer from "inquirer";
4995
+
4996
+ // src/platform/detect.ts
4997
+ import * as fs17 from "fs";
4998
+ import * as os from "os";
4999
+ var _isTermux = null;
5000
+ var _isCodespaces = null;
5001
+ var _isTouch = null;
5002
+ function isTermux() {
5003
+ if (_isTermux !== null) return _isTermux;
5004
+ _isTermux = fs17.existsSync("/data/data/com.termux") || process.env.PREFIX === "/data/data/com.termux/files/usr" || !!process.env.TERMUX_VERSION || process.env.TERMUX_APK_RELEASE !== void 0 || false;
5005
+ return _isTermux;
5006
+ }
5007
+ function isTouchDevice() {
5008
+ if (_isTouch !== null) return _isTouch;
5009
+ _isTouch = isTermux() || process.env.LOVECODE_TOUCH === "true" || process.env.TERMUX_VERSION !== void 0 || false;
5010
+ return _isTouch;
5011
+ }
5012
+ function isCodespaces() {
5013
+ if (_isCodespaces !== null) return _isCodespaces;
5014
+ _isCodespaces = process.env.CODESPACES === "true" || !!process.env.CODESPACE_NAME || fs17.existsSync("/.codespaces") || false;
5015
+ return _isCodespaces;
5016
+ }
5017
+ function lowRamMode() {
5018
+ const totalMem = os.totalmem();
5019
+ const memMb = totalMem / (1024 * 1024);
5020
+ return memMb < 1024 || process.env.LOVECODE_LOW_RAM === "true" || isTermux();
5021
+ }
5022
+ function recommendedMaxMemory() {
5023
+ const totalMem = os.totalmem();
5024
+ const memMb = totalMem / (1024 * 1024);
5025
+ if (isTermux()) return 128;
5026
+ if (memMb < 1024) return 128;
5027
+ if (memMb < 2048) return 256;
5028
+ if (memMb < 4096) return 512;
5029
+ return 1024;
5030
+ }
5031
+ function termuxInfo() {
5032
+ if (!isTermux()) return [];
5033
+ const info = [];
5034
+ info.push(`Termux version: ${process.env.TERMUX_VERSION || "unknown"}`);
5035
+ info.push(`Touch optimized: ${isTouchDevice() ? "yes" : "no"}`);
5036
+ info.push(`Low RAM mode: ${lowRamMode() ? "enabled" : "disabled"}`);
5037
+ info.push(`Max memory: ${recommendedMaxMemory()}MB`);
5038
+ info.push(`Cache TTL: ${cacheTTL()}ms`);
5039
+ return info;
5040
+ }
5041
+ function cacheTTL() {
5042
+ return isTermux() ? 12e4 : 3e5;
5043
+ }
5044
+ function platformInfo() {
5045
+ const info = [];
5046
+ info.push(`OS: ${os.platform()} ${os.release()}`);
5047
+ info.push(`CPU: ${os.cpus().length} cores`);
5048
+ info.push(`RAM: ${(os.totalmem() / 1024 ** 3).toFixed(1)} GB total, ${(os.freemem() / 1024 ** 3).toFixed(1)} GB free`);
5049
+ info.push(`Node: ${process.version}`);
5050
+ if (isTermux()) info.push(`Platform: Termux (Android) ${process.env.TERMUX_VERSION || ""}`);
5051
+ if (isCodespaces()) info.push("Platform: GitHub Codespaces");
5052
+ return info;
5053
+ }
5054
+
5055
+ // src/utils/select.ts
5056
+ import * as readline5 from "readline";
5057
+ import chalk24 from "chalk";
5058
+ async function numberedSelect(choices, options) {
5059
+ const termux = options?.termux ?? isTermux();
5060
+ const pageSize = options?.pageSize || 15;
5061
+ const message = options?.message || "Select an option:";
5062
+ console.log(`
5063
+ ${chalk24.bold(message)}
5064
+ `);
5065
+ const display = choices.slice(0, pageSize);
5066
+ for (let i = 0; i < display.length; i++) {
5067
+ const num = chalk24.cyan(`${i + 1}`.padStart(3));
5068
+ const desc = display[i].description ? chalk24.dim(` \u2014 ${display[i].description}`) : "";
5069
+ console.log(` ${num}. ${display[i].name}${desc}`);
5070
+ }
5071
+ if (choices.length > pageSize) {
5072
+ console.log(` ${chalk24.dim(`... and ${choices.length - pageSize} more. Use \`lovecode env set\` directly.`)}`);
5073
+ }
5074
+ const rl = readline5.createInterface({ input: process.stdin, output: process.stdout });
5075
+ return new Promise((resolve5) => {
5076
+ const prompt = termux ? `
5077
+ ${chalk24.cyan("?")} Enter number (1-${display.length}): ` : `
5078
+ ${chalk24.cyan("?")} Enter number (1-${display.length}), or press Enter for 1: `;
5079
+ rl.question(prompt, (answer) => {
5080
+ rl.close();
5081
+ const trimmed = answer.trim();
5082
+ if (!trimmed && !termux) {
5083
+ resolve5(display[0].value);
5084
+ return;
5085
+ }
5086
+ const num = parseInt(trimmed, 10);
5087
+ if (isNaN(num) || num < 1 || num > display.length) {
5088
+ console.log(chalk24.red(` Invalid selection. Please enter a number between 1 and ${display.length}.`));
5089
+ resolve5(numberedSelect(choices, options));
5090
+ return;
5091
+ }
5092
+ resolve5(display[num - 1].value);
5093
+ });
5094
+ });
5095
+ }
5096
+ async function promptInput(question, defaultValue) {
5097
+ const rl = readline5.createInterface({ input: process.stdin, output: process.stdout });
5098
+ const prompt = defaultValue ? ` ${chalk24.cyan("?")} ${question} ${chalk24.dim(`(${defaultValue})`)}: ` : ` ${chalk24.cyan("?")} ${question}: `;
5099
+ return new Promise((resolve5) => {
5100
+ rl.question(prompt, (answer) => {
5101
+ rl.close();
5102
+ resolve5(answer.trim() || defaultValue || "");
5103
+ });
5104
+ });
5105
+ }
5106
+
5107
+ // src/commands/env.ts
4995
5108
  async function cmdEnvShow(options) {
4996
5109
  console.log(formatEnvStatus(options.dir));
4997
5110
  }
@@ -4999,46 +5112,65 @@ async function cmdEnvSet(key, value, options) {
4999
5112
  const vars = loadEnv(options.dir);
5000
5113
  vars[key.toUpperCase()] = value;
5001
5114
  saveEnv(vars, options.dir);
5002
- console.log(chalk24.green(`Set ${key.toUpperCase()}`));
5115
+ console.log(chalk25.green(`Set ${key.toUpperCase()}`));
5003
5116
  console.log(formatEnvStatus(options.dir));
5004
5117
  }
5005
5118
  async function cmdEnvUnset(key, options) {
5006
5119
  const vars = loadEnv(options.dir);
5007
5120
  delete vars[key.toUpperCase()];
5008
5121
  saveEnv(vars, options.dir);
5009
- console.log(chalk24.yellow(`Unset ${key.toUpperCase()}`));
5122
+ console.log(chalk25.yellow(`Unset ${key.toUpperCase()}`));
5010
5123
  }
5011
5124
  async function cmdEnvSelect(options) {
5012
5125
  const vars = loadEnv(options.dir);
5013
5126
  const choices = KNOWN_ENV_VARS.map((v) => {
5014
5127
  const current = vars[v.key] || process.env[v.key] || "";
5015
- const status = current ? chalk24.green("\u2713 set") : chalk24.dim("\u25CB empty");
5128
+ const status = current ? chalk25.green("\u2713 set") : chalk25.dim("\u25CB empty");
5016
5129
  const masked = current && v.key.includes("KEY") ? current.slice(0, 8) + "*".repeat(Math.min(current.length - 8, 12)) : current || "";
5017
5130
  return {
5018
- name: `${v.key.padEnd(28)} ${status} ${chalk24.dim(v.description)}${masked ? chalk24.dim(` (${masked})`) : ""}`,
5131
+ name: `${v.key.padEnd(28)} ${status}`,
5019
5132
  value: v.key,
5020
- short: v.key
5133
+ description: masked ? `${v.description} (${masked})` : v.description
5021
5134
  };
5022
5135
  });
5023
- const { key } = await inquirer.prompt([{
5024
- type: "list",
5025
- name: "key",
5026
- message: "Select an environment variable to set:",
5027
- choices,
5028
- pageSize: 15
5029
- }]);
5136
+ const useTermuxStyle = isTermux() || isTouchDevice();
5137
+ let key;
5138
+ if (useTermuxStyle) {
5139
+ key = await numberedSelect(choices, {
5140
+ message: "Select an environment variable to set:",
5141
+ termux: true
5142
+ });
5143
+ } else {
5144
+ const result = await inquirer.prompt([{
5145
+ type: "list",
5146
+ name: "key",
5147
+ message: "Select an environment variable to set:",
5148
+ choices: choices.map((c) => ({ name: c.name, value: c.value })),
5149
+ pageSize: 15
5150
+ }]);
5151
+ key = result.key;
5152
+ }
5030
5153
  const existing = vars[key] || "";
5031
5154
  const description = KNOWN_ENV_VARS.find((v) => v.key === key)?.description || "";
5032
- const { value } = await inquirer.prompt([{
5033
- type: "input",
5034
- name: "value",
5035
- message: `Enter value for ${chalk24.cyan(key)} (${description}):`,
5036
- default: existing || void 0,
5037
- validate: (input) => input.length > 0 || "Value cannot be empty"
5038
- }]);
5155
+ let value;
5156
+ if (useTermuxStyle) {
5157
+ value = await promptInput(`Enter value for ${key} (${description})`, existing || void 0);
5158
+ } else {
5159
+ const result = await inquirer.prompt([{
5160
+ type: "input",
5161
+ name: "value",
5162
+ message: `Enter value for ${chalk25.cyan(key)} (${description}):`,
5163
+ default: existing || void 0
5164
+ }]);
5165
+ value = result.value;
5166
+ }
5167
+ if (!value) {
5168
+ console.log(chalk25.yellow("\nNo value entered. Skipping."));
5169
+ return;
5170
+ }
5039
5171
  vars[key] = value;
5040
5172
  saveEnv(vars, options.dir);
5041
- console.log(chalk24.green(`
5173
+ console.log(chalk25.green(`
5042
5174
  \u2713 ${key} saved`));
5043
5175
  console.log(formatEnvStatus(options.dir));
5044
5176
  }
@@ -5048,6 +5180,8 @@ var envCommand = new Command5("env").alias("environment").description("Manage en
5048
5180
  lovecode env select Interactive variable selection
5049
5181
  lovecode env set GROQ_API_KEY gsk_xxx
5050
5182
  lovecode env unset GROQ_API_KEY
5183
+
5184
+ On Termux/Android: uses numbered input instead of arrow keys
5051
5185
  `);
5052
5186
  envCommand.command("set").description("Set an environment variable").argument("<key>", "Variable name").argument("<value>", "Variable value").option("--dir <path>", "Project directory").action(cmdEnvSet);
5053
5187
  envCommand.command("unset").description("Remove an environment variable").argument("<key>", "Variable name").option("--dir <path>", "Project directory").action(cmdEnvUnset);
@@ -5058,57 +5192,28 @@ envCommand.action(cmdEnvShow);
5058
5192
  import { Command as Command6 } from "commander";
5059
5193
 
5060
5194
  // src/platform/optimize.ts
5061
- import chalk25 from "chalk";
5062
-
5063
- // src/platform/detect.ts
5064
- import * as fs17 from "fs";
5065
- import * as os from "os";
5066
- var _isTermux = null;
5067
- var _isCodespaces = null;
5068
- function isTermux() {
5069
- if (_isTermux !== null) return _isTermux;
5070
- _isTermux = fs17.existsSync("/data/data/com.termux") || process.env.PREFIX === "/data/data/com.termux/files/usr" || !!process.env.TERMUX_VERSION;
5071
- return _isTermux;
5072
- }
5073
- function isCodespaces() {
5074
- if (_isCodespaces !== null) return _isCodespaces;
5075
- _isCodespaces = process.env.CODESPACES === "true" || !!process.env.CODESPACE_NAME || fs17.existsSync("/.codespaces");
5076
- return _isCodespaces;
5077
- }
5078
- function lowRamMode() {
5079
- const totalMem = os.totalmem();
5080
- const memMb = totalMem / (1024 * 1024);
5081
- return memMb < 1024 || process.env.LOVECODE_LOW_RAM === "true" || isTermux();
5082
- }
5083
- function recommendedMaxMemory() {
5084
- const totalMem = os.totalmem();
5085
- const memMb = totalMem / (1024 * 1024);
5086
- if (memMb < 1024) return 128;
5087
- if (memMb < 2048) return 256;
5088
- if (memMb < 4096) return 512;
5089
- return 1024;
5090
- }
5091
- function platformInfo() {
5092
- const info = [];
5093
- info.push(`OS: ${os.platform()} ${os.release()}`);
5094
- info.push(`CPU: ${os.cpus().length} cores`);
5095
- info.push(`RAM: ${(os.totalmem() / 1024 ** 3).toFixed(1)} GB total, ${(os.freemem() / 1024 ** 3).toFixed(1)} GB free`);
5096
- info.push(`Node: ${process.version}`);
5097
- if (isTermux()) info.push("Platform: Termux (Android)");
5098
- if (isCodespaces()) info.push("Platform: GitHub Codespaces");
5099
- return info;
5100
- }
5101
-
5102
- // src/platform/optimize.ts
5195
+ import chalk26 from "chalk";
5103
5196
  function formatPlatformStatus() {
5104
- const lines = [chalk25.bold("\n Platform Status")];
5105
- lines.push(` Termux: ${isTermux() ? chalk25.green("\u2713") : chalk25.dim("\u2014")}`);
5106
- lines.push(` Codespaces: ${isCodespaces() ? chalk25.green("\u2713") : chalk25.dim("\u2014")}`);
5107
- lines.push(` Low RAM: ${lowRamMode() ? chalk25.yellow("\u2713") : chalk25.dim("\u2014")}`);
5108
- lines.push(` Max Mem: ${recommendedMaxMemory()}MB`);
5197
+ const lines = [chalk26.bold("\n Platform Status")];
5198
+ lines.push(` Termux: ${isTermux() ? chalk26.green("\u2713") : chalk26.dim("\u2014")}`);
5199
+ lines.push(` Touch: ${isTouchDevice() ? chalk26.green("\u2713") : chalk26.dim("\u2014")}`);
5200
+ lines.push(` Codespaces: ${isCodespaces() ? chalk26.green("\u2713") : chalk26.dim("\u2014")}`);
5201
+ lines.push(` Low RAM: ${lowRamMode() ? chalk26.yellow("active") : chalk26.dim("no")}`);
5202
+ lines.push(` Max Mem: ${recommendedMaxMemory()}MB`);
5109
5203
  lines.push("");
5204
+ if (isTermux()) {
5205
+ lines.push(chalk26.bold(" Termux Details:"));
5206
+ for (const t of termuxInfo()) {
5207
+ lines.push(` ${t}`);
5208
+ }
5209
+ lines.push("");
5210
+ }
5110
5211
  for (const line of platformInfo()) {
5111
- lines.push(` ${chalk25.dim(line)}`);
5212
+ lines.push(` ${chalk26.dim(line)}`);
5213
+ }
5214
+ if (isTouchDevice()) {
5215
+ lines.push("");
5216
+ lines.push(chalk26.dim(" Tip: Use numbered selections instead of arrow keys"));
5112
5217
  }
5113
5218
  return lines.join("\n");
5114
5219
  }
@@ -5121,14 +5226,14 @@ var platformCommand = new Command6("platform").alias("sys").alias("info").descri
5121
5226
 
5122
5227
  // src/commands/telemetry.ts
5123
5228
  import { Command as Command7 } from "commander";
5124
- import chalk27 from "chalk";
5229
+ import chalk28 from "chalk";
5125
5230
 
5126
5231
  // src/telemetry/telemetry.ts
5127
5232
  import * as fs18 from "fs";
5128
5233
  import * as path17 from "path";
5129
5234
  import * as os2 from "os";
5130
5235
  import { createRequire as createRequire2 } from "module";
5131
- import chalk26 from "chalk";
5236
+ import chalk27 from "chalk";
5132
5237
  var _require2 = createRequire2(import.meta.url);
5133
5238
  var TELEMETRY_DIR = ".lovecode/telemetry";
5134
5239
  var _enabled = null;
@@ -5209,16 +5314,16 @@ function clearTelemetryData(rootDir) {
5209
5314
  }
5210
5315
  }
5211
5316
  function formatTelemetryStatus(enabled, data) {
5212
- const lines = [chalk26.bold("\n Telemetry Status")];
5213
- lines.push(` Status: ${enabled ? chalk26.yellow("ENABLED") : chalk26.green("DISABLED")}`);
5317
+ const lines = [chalk27.bold("\n Telemetry Status")];
5318
+ lines.push(` Status: ${enabled ? chalk27.yellow("ENABLED") : chalk27.green("DISABLED")}`);
5214
5319
  lines.push(` Events: ${data.events.length}`);
5215
5320
  lines.push(` Crashes: ${data.crashes.length}`);
5216
5321
  if (data.events.length > 0) {
5217
- lines.push(chalk26.dim(`
5322
+ lines.push(chalk27.dim(`
5218
5323
  Recent Events:`));
5219
5324
  for (const e of data.events.slice(-5)) {
5220
5325
  const date = new Date(e.timestamp).toLocaleString();
5221
- lines.push(` ${chalk26.dim(date)} ${e.event}`);
5326
+ lines.push(` ${chalk27.dim(date)} ${e.event}`);
5222
5327
  }
5223
5328
  }
5224
5329
  return lines.join("\n");
@@ -5232,17 +5337,17 @@ async function cmdTelemetryStatus(options) {
5232
5337
  }
5233
5338
  async function cmdTelemetryEnable(options) {
5234
5339
  enableTelemetry(options.dir);
5235
- console.log(chalk27.yellow("Telemetry enabled."));
5236
- console.log(chalk27.dim(" Anonymous usage data will be collected to improve LoveCode."));
5237
- console.log(chalk27.dim(" No personal or project data is ever sent."));
5340
+ console.log(chalk28.yellow("Telemetry enabled."));
5341
+ console.log(chalk28.dim(" Anonymous usage data will be collected to improve LoveCode."));
5342
+ console.log(chalk28.dim(" No personal or project data is ever sent."));
5238
5343
  }
5239
5344
  async function cmdTelemetryDisable(options) {
5240
5345
  disableTelemetry(options.dir);
5241
- console.log(chalk27.green("Telemetry disabled."));
5346
+ console.log(chalk28.green("Telemetry disabled."));
5242
5347
  }
5243
5348
  async function cmdTelemetryClear(options) {
5244
5349
  clearTelemetryData(options.dir);
5245
- console.log(chalk27.green("Telemetry data cleared."));
5350
+ console.log(chalk28.green("Telemetry data cleared."));
5246
5351
  }
5247
5352
  var telemetryCommand = new Command7("telemetry").alias("analytics").description("Manage anonymous telemetry and crash reporting").option("--dir <path>", "Project directory", process.cwd()).addHelpText("after", `
5248
5353
  Privacy-first by default. Telemetry is disabled unless explicitly enabled.
@@ -5260,13 +5365,13 @@ telemetryCommand.action(cmdTelemetryStatus);
5260
5365
 
5261
5366
  // src/commands/install.ts
5262
5367
  import { Command as Command8 } from "commander";
5263
- import chalk29 from "chalk";
5368
+ import chalk30 from "chalk";
5264
5369
 
5265
5370
  // src/installers/install.ts
5266
5371
  import * as fs19 from "fs";
5267
5372
  import * as path18 from "path";
5268
5373
  import { execSync as execSync4 } from "child_process";
5269
- import chalk28 from "chalk";
5374
+ import chalk29 from "chalk";
5270
5375
  function detectInstallMethod() {
5271
5376
  if (process.env.npm_config_user_agent?.startsWith("npm")) return "npm";
5272
5377
  if (process.env.npm_config_user_agent?.startsWith("yarn")) return "yarn";
@@ -5292,16 +5397,26 @@ function isGloballyInstalled() {
5292
5397
  }
5293
5398
  }
5294
5399
  function printInstallInstructions() {
5295
- console.log(chalk28.bold.cyan("\n LoveCode AI - Installation\n"));
5296
- console.log(chalk28.bold(" Quick Install:\n"));
5297
- console.log(` ${chalk28.green("NPM:")}`);
5400
+ console.log(chalk29.bold.cyan("\n LoveCode AI - Installation\n"));
5401
+ console.log(chalk29.bold(" Quick Install:\n"));
5402
+ console.log(` ${chalk29.green("NPM:")}`);
5298
5403
  console.log(` npm install -g lovecode-ai
5299
5404
  `);
5300
- console.log(` ${chalk28.green("Curl:")}`);
5405
+ console.log(` ${chalk29.green("Curl:")}`);
5301
5406
  console.log(` curl -fsSL https://lovecode.sh | bash
5302
5407
  `);
5303
- console.log(` ${chalk28.green("Verify:")}`);
5408
+ console.log(` ${chalk29.green("Verify:")}`);
5304
5409
  console.log(` lovecode --version
5410
+ `);
5411
+ console.log(chalk29.bold(" Termux (Android):\n"));
5412
+ console.log(` pkg install nodejs`);
5413
+ console.log(` npm install -g lovecode-ai`);
5414
+ console.log(` lovecode init
5415
+ `);
5416
+ console.log(` ${chalk29.dim("LoveCode auto-detects Termux and enables:")}`);
5417
+ console.log(` ${chalk29.dim(" \u2022 Low RAM mode (128MB max)")}`);
5418
+ console.log(` ${chalk29.dim(" \u2022 Touch-optimized input")}`);
5419
+ console.log(` ${chalk29.dim(" \u2022 Reduced cache TTL (120s)")}
5305
5420
  `);
5306
5421
  }
5307
5422
  function createInstallScript(rootDir) {
@@ -5374,20 +5489,20 @@ echo ""
5374
5489
  async function cmdInstallStatus() {
5375
5490
  const info = getInstallerInfo();
5376
5491
  const global = isGloballyInstalled();
5377
- console.log(chalk29.bold("\n Install Status"));
5378
- console.log(` Method: ${chalk29.cyan(info.method)}`);
5492
+ console.log(chalk30.bold("\n Install Status"));
5493
+ console.log(` Method: ${chalk30.cyan(info.method)}`);
5379
5494
  console.log(` Version: ${info.version}`);
5380
5495
  console.log(` Node: ${info.nodeVersion}`);
5381
5496
  console.log(` Platform: ${info.platform}`);
5382
- console.log(` Global CLI: ${global ? chalk29.green("\u2713") : chalk29.dim("\u2014")}`);
5497
+ console.log(` Global CLI: ${global ? chalk30.green("\u2713") : chalk30.dim("\u2014")}`);
5383
5498
  }
5384
5499
  async function cmdInstallGuide() {
5385
5500
  printInstallInstructions();
5386
5501
  }
5387
5502
  async function cmdInstallScript(options) {
5388
5503
  createInstallScript(options.dir);
5389
- console.log(chalk29.green(` \u2713 install.sh created in ${options.dir || process.cwd()}`));
5390
- console.log(chalk29.dim(" Run: bash install.sh"));
5504
+ console.log(chalk30.green(` \u2713 install.sh created in ${options.dir || process.cwd()}`));
5505
+ console.log(chalk30.dim(" Run: bash install.sh"));
5391
5506
  }
5392
5507
  var installCommand = new Command8("install").alias("installer").description("Installation management and instructions").option("--dir <path>", "Project directory", process.cwd()).addHelpText("after", `
5393
5508
  Examples:
@@ -5401,7 +5516,7 @@ installCommand.action(cmdInstallStatus);
5401
5516
 
5402
5517
  // src/commands/models.ts
5403
5518
  import { Command as Command9 } from "commander";
5404
- import chalk30 from "chalk";
5519
+ import chalk31 from "chalk";
5405
5520
  var modelsCommand = new Command9("models").description("Manage AI models and providers").addCommand(
5406
5521
  new Command9("list").alias("ls").description("List all available models and providers").action(() => {
5407
5522
  console.log(printProviders());
@@ -5410,8 +5525,8 @@ var modelsCommand = new Command9("models").description("Manage AI models and pro
5410
5525
  new Command9("use").description("Set the default model to use").argument("<model>", "Model name or provider name").action((model) => {
5411
5526
  const result = setDefaultModel(model);
5412
5527
  if (result) {
5413
- console.log(chalk30.green(`
5414
- \u2713 Default set to ${chalk30.cyan(result.provider)}/${chalk30.cyan(result.model)}
5528
+ console.log(chalk31.green(`
5529
+ \u2713 Default set to ${chalk31.cyan(result.provider)}/${chalk31.cyan(result.model)}
5415
5530
  `));
5416
5531
  }
5417
5532
  })
@@ -5420,20 +5535,20 @@ var modelsCommand = new Command9("models").description("Manage AI models and pro
5420
5535
  if (provider) {
5421
5536
  const entry = getProvider(provider);
5422
5537
  if (!entry) {
5423
- console.log(chalk30.red(`
5538
+ console.log(chalk31.red(`
5424
5539
  Unknown provider: "${provider}"
5425
5540
  `));
5426
5541
  return;
5427
5542
  }
5428
- const tag = entry.local ? chalk30.green(" LOCAL ") : chalk30.blue(" CLOUD ");
5543
+ const tag = entry.local ? chalk31.green(" LOCAL ") : chalk31.blue(" CLOUD ");
5429
5544
  console.log(`
5430
- ${tag} ${chalk30.cyan(entry.name)}`);
5431
- console.log(chalk30.dim(` Default model: ${entry.defaultModel}`));
5432
- console.log(chalk30.dim(` Priority: ${entry.priority}`));
5433
- console.log(chalk30.dim(` Models:`));
5545
+ ${tag} ${chalk31.cyan(entry.name)}`);
5546
+ console.log(chalk31.dim(` Default model: ${entry.defaultModel}`));
5547
+ console.log(chalk31.dim(` Priority: ${entry.priority}`));
5548
+ console.log(chalk31.dim(` Models:`));
5434
5549
  for (const m of entry.models) {
5435
5550
  const isDefault = m === entry.defaultModel;
5436
- console.log(` ${isDefault ? chalk30.green("\u2605") : " "} ${m}${isDefault ? chalk30.dim(" (default)") : ""}`);
5551
+ console.log(` ${isDefault ? chalk31.green("\u2605") : " "} ${m}${isDefault ? chalk31.dim(" (default)") : ""}`);
5437
5552
  }
5438
5553
  console.log("");
5439
5554
  } else {
@@ -5444,13 +5559,13 @@ var modelsCommand = new Command9("models").description("Manage AI models and pro
5444
5559
  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) => {
5445
5560
  const entry = getProvider(provider);
5446
5561
  if (!entry) {
5447
- console.log(chalk30.red(`
5562
+ console.log(chalk31.red(`
5448
5563
  Unknown provider: "${provider}"
5449
5564
  `));
5450
5565
  return;
5451
5566
  }
5452
5567
  const model = options.model || entry.defaultModel;
5453
- console.log(chalk30.dim(`
5568
+ console.log(chalk31.dim(`
5454
5569
  Testing ${entry.name}/${model}...`));
5455
5570
  try {
5456
5571
  const config = entry.getConfig?.(model) || {
@@ -5463,9 +5578,9 @@ var modelsCommand = new Command9("models").description("Manage AI models and pro
5463
5578
  [{ role: "user", content: "Reply with exactly: OK" }],
5464
5579
  config
5465
5580
  );
5466
- console.log(chalk30.green(` \u2713 ${entry.name}/${model} responded: ${result.slice(0, 50)}`));
5581
+ console.log(chalk31.green(` \u2713 ${entry.name}/${model} responded: ${result.slice(0, 50)}`));
5467
5582
  } catch (err) {
5468
- console.log(chalk30.red(` \u2717 ${entry.name}/${model} failed: ${err.message}`));
5583
+ console.log(chalk31.red(` \u2717 ${entry.name}/${model} failed: ${err.message}`));
5469
5584
  }
5470
5585
  console.log("");
5471
5586
  })
@@ -5473,12 +5588,12 @@ var modelsCommand = new Command9("models").description("Manage AI models and pro
5473
5588
 
5474
5589
  // src/commands/analyze.ts
5475
5590
  import { Command as Command10 } from "commander";
5476
- import chalk32 from "chalk";
5591
+ import chalk33 from "chalk";
5477
5592
 
5478
5593
  // src/repo/search.ts
5479
5594
  import * as fs20 from "fs";
5480
5595
  import * as path19 from "path";
5481
- import chalk31 from "chalk";
5596
+ import chalk32 from "chalk";
5482
5597
  function chunkFile(content, maxLines = 50) {
5483
5598
  const lines = content.split("\n");
5484
5599
  const chunks = [];
@@ -5611,23 +5726,23 @@ function readFileSafe(filePath) {
5611
5726
  }
5612
5727
  }
5613
5728
  function printSemanticResults(results, query) {
5614
- const lines = [chalk31.bold(`
5729
+ const lines = [chalk32.bold(`
5615
5730
  Semantic Search: "${query}"`), ""];
5616
5731
  if (results.length === 0) {
5617
- lines.push(chalk31.dim(" No results found."));
5732
+ lines.push(chalk32.dim(" No results found."));
5618
5733
  lines.push("");
5619
5734
  return lines.join("\n");
5620
5735
  }
5621
5736
  for (let i = 0; i < results.length; i++) {
5622
5737
  const r = results[i];
5623
5738
  const barLen = Math.round(r.score * 30);
5624
- const bar = chalk31.cyan("\u2588".repeat(barLen)) + chalk31.dim("\u2591".repeat(30 - barLen));
5625
- lines.push(` ${chalk31.cyan(String(i + 1).padEnd(3))} ${chalk31.dim(r.relativePath)}`);
5626
- lines.push(` ${bar} ${chalk31.bold(String(Math.round(r.score * 100)))}%`);
5739
+ const bar = chalk32.cyan("\u2588".repeat(barLen)) + chalk32.dim("\u2591".repeat(30 - barLen));
5740
+ lines.push(` ${chalk32.cyan(String(i + 1).padEnd(3))} ${chalk32.dim(r.relativePath)}`);
5741
+ lines.push(` ${bar} ${chalk32.bold(String(Math.round(r.score * 100)))}%`);
5627
5742
  if (r.matches.length > 0) {
5628
5743
  const top = r.matches.slice(0, 2);
5629
5744
  for (const m of top) {
5630
- lines.push(` ${chalk31.dim(`L${m.line}:`)} ${m.content.slice(0, 100)}`);
5745
+ lines.push(` ${chalk32.dim(`L${m.line}:`)} ${m.content.slice(0, 100)}`);
5631
5746
  }
5632
5747
  }
5633
5748
  }
@@ -5643,27 +5758,27 @@ var analyzeCommand = new Command10("analyze").alias("a").description("Analyze an
5643
5758
  })
5644
5759
  ).addCommand(
5645
5760
  new Command10("deps").alias("d").description("Analyze dependencies and import graph").option("--dir <path>", "Project directory", process.cwd()).action((options) => {
5646
- console.log(chalk32.dim("\n Analyzing dependencies..."));
5761
+ console.log(chalk33.dim("\n Analyzing dependencies..."));
5647
5762
  const graph = analyzeDependencies(options.dir);
5648
5763
  console.log(printDepGraph(graph));
5649
5764
  const circles = findCircularDeps(graph);
5650
5765
  if (circles.length > 0) {
5651
- console.log(chalk32.yellow(` \u26A0 Found ${circles.length} circular dependenc${circles.length > 1 ? "ies" : "y"}`));
5766
+ console.log(chalk33.yellow(` \u26A0 Found ${circles.length} circular dependenc${circles.length > 1 ? "ies" : "y"}`));
5652
5767
  for (const circle of circles.slice(0, 5)) {
5653
- console.log(` ${chalk32.red("\u21BB")} ${circle.join(" \u2192 ")}`);
5768
+ console.log(` ${chalk33.red("\u21BB")} ${circle.join(" \u2192 ")}`);
5654
5769
  }
5655
5770
  console.log("");
5656
5771
  }
5657
5772
  })
5658
5773
  ).addCommand(
5659
5774
  new Command10("summary").alias("s").description("Generate a full repo architecture summary").option("--dir <path>", "Project directory", process.cwd()).action((options) => {
5660
- console.log(chalk32.dim("\n Generating repository summary...\n"));
5775
+ console.log(chalk33.dim("\n Generating repository summary...\n"));
5661
5776
  const summary = generateSummary(options.dir);
5662
5777
  console.log(printSummary(summary));
5663
5778
  })
5664
5779
  ).addCommand(
5665
5780
  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) => {
5666
- console.log(chalk32.dim(`
5781
+ console.log(chalk33.dim(`
5667
5782
  Searching for: "${query}"
5668
5783
  `));
5669
5784
  const results = await semanticSearch2(options.dir, query, {
@@ -5689,36 +5804,36 @@ var analyzeCommand = new Command10("analyze").alias("a").description("Analyze an
5689
5804
 
5690
5805
  // src/commands/memory.ts
5691
5806
  import { Command as Command11 } from "commander";
5692
- import chalk33 from "chalk";
5807
+ import chalk34 from "chalk";
5693
5808
  async function cmdSessions(options) {
5694
5809
  const sessions = listSessions(options.dir);
5695
5810
  if (sessions.length === 0) {
5696
- console.log(chalk33.yellow("No sessions found."));
5811
+ console.log(chalk34.yellow("No sessions found."));
5697
5812
  return;
5698
5813
  }
5699
- console.log(chalk33.bold(`
5814
+ console.log(chalk34.bold(`
5700
5815
  Sessions (${sessions.length}):
5701
5816
  `));
5702
5817
  for (const s of sessions) {
5703
5818
  const date = new Date(s.updated).toLocaleString();
5704
5819
  const msgCount = s.entries.length;
5705
- console.log(` ${chalk33.cyan(s.id.slice(0, 12))} ${chalk33.bold(s.title)}`);
5706
- console.log(` ${chalk33.dim(`${msgCount} msgs \u2022 ${date} \u2022 ${s.model}`)}`);
5820
+ console.log(` ${chalk34.cyan(s.id.slice(0, 12))} ${chalk34.bold(s.title)}`);
5821
+ console.log(` ${chalk34.dim(`${msgCount} msgs \u2022 ${date} \u2022 ${s.model}`)}`);
5707
5822
  }
5708
5823
  }
5709
5824
  async function cmdShowSession(id, options) {
5710
5825
  const session = loadSession(id, options.dir);
5711
5826
  if (!session) {
5712
- console.log(chalk33.red(`Session "${id}" not found.`));
5827
+ console.log(chalk34.red(`Session "${id}" not found.`));
5713
5828
  return;
5714
5829
  }
5715
- console.log(chalk33.bold(`
5830
+ console.log(chalk34.bold(`
5716
5831
  Session: ${session.title}`));
5717
- console.log(chalk33.dim(` ID: ${session.id} \u2022 Model: ${session.model} \u2022 ${session.entries.length} messages`));
5718
- console.log(chalk33.dim(` Created: ${new Date(session.created).toLocaleString()}`));
5832
+ console.log(chalk34.dim(` ID: ${session.id} \u2022 Model: ${session.model} \u2022 ${session.entries.length} messages`));
5833
+ console.log(chalk34.dim(` Created: ${new Date(session.created).toLocaleString()}`));
5719
5834
  console.log("");
5720
5835
  for (const entry of session.entries.slice(-20)) {
5721
- const role = entry.role === "user" ? chalk33.green("You") : entry.role === "assistant" ? chalk33.cyan("LoveCode") : chalk33.yellow("System");
5836
+ const role = entry.role === "user" ? chalk34.green("You") : entry.role === "assistant" ? chalk34.cyan("LoveCode") : chalk34.yellow("System");
5722
5837
  const preview = entry.content.length > 200 ? entry.content.slice(0, 200) + "..." : entry.content;
5723
5838
  console.log(` ${role}: ${preview}
5724
5839
  `);
@@ -5727,15 +5842,15 @@ async function cmdShowSession(id, options) {
5727
5842
  async function cmdSearchSessions(query, options) {
5728
5843
  const results = searchSessions(query, options.dir);
5729
5844
  if (results.length === 0) {
5730
- console.log(chalk33.yellow(`No sessions matching "${query}".`));
5845
+ console.log(chalk34.yellow(`No sessions matching "${query}".`));
5731
5846
  return;
5732
5847
  }
5733
- console.log(chalk33.bold(`
5848
+ console.log(chalk34.bold(`
5734
5849
  Search results for "${query}" (${results.length}):
5735
5850
  `));
5736
5851
  for (const s of results) {
5737
5852
  const date = new Date(s.updated).toLocaleString();
5738
- console.log(` ${chalk33.cyan(s.id.slice(0, 12))} ${chalk33.bold(s.title)} ${chalk33.dim(date)}`);
5853
+ console.log(` ${chalk34.cyan(s.id.slice(0, 12))} ${chalk34.bold(s.title)} ${chalk34.dim(date)}`);
5739
5854
  }
5740
5855
  }
5741
5856
  async function cmdPreferences(options) {
@@ -5755,7 +5870,7 @@ async function cmdPreferences(options) {
5755
5870
  else prefs[k] = v;
5756
5871
  }
5757
5872
  const saved = savePreferences(prefs, options.dir);
5758
- console.log(chalk33.green("Preferences updated:"));
5873
+ console.log(chalk34.green("Preferences updated:"));
5759
5874
  console.log(formatPreferences(saved));
5760
5875
  } else {
5761
5876
  const prefs = getPreferences(options.dir);
@@ -5765,7 +5880,7 @@ async function cmdPreferences(options) {
5765
5880
  async function cmdRepoMemory(options) {
5766
5881
  if (options.note) {
5767
5882
  const updated = addRepoNote(options.note, options.dir);
5768
- console.log(chalk33.green("Note added to repo memory."));
5883
+ console.log(chalk34.green("Note added to repo memory."));
5769
5884
  console.log(formatRepoMemory(updated));
5770
5885
  } else {
5771
5886
  const mem = getRepoMemory(options.dir);
@@ -5785,31 +5900,31 @@ async function cmdWorkflows(options) {
5785
5900
  used: Date.now()
5786
5901
  };
5787
5902
  saveWorkflow(workflow, options.dir);
5788
- console.log(chalk33.green(`Workflow "${options.name}" saved (${steps.length} steps).`));
5903
+ console.log(chalk34.green(`Workflow "${options.name}" saved (${steps.length} steps).`));
5789
5904
  return;
5790
5905
  }
5791
5906
  if (options.delete) {
5792
5907
  const ok = deleteWorkflow(options.delete, options.dir);
5793
- console.log(ok ? chalk33.green(`Workflow "${options.delete}" deleted.`) : chalk33.yellow(`Workflow "${options.delete}" not found.`));
5908
+ console.log(ok ? chalk34.green(`Workflow "${options.delete}" deleted.`) : chalk34.yellow(`Workflow "${options.delete}" not found.`));
5794
5909
  return;
5795
5910
  }
5796
5911
  if (wf.workflows.length === 0) {
5797
- console.log(chalk33.yellow("No saved workflows."));
5912
+ console.log(chalk34.yellow("No saved workflows."));
5798
5913
  return;
5799
5914
  }
5800
- console.log(chalk33.bold(`
5915
+ console.log(chalk34.bold(`
5801
5916
  Workflows (${wf.workflows.length}):
5802
5917
  `));
5803
5918
  for (const w of wf.workflows) {
5804
5919
  const date = new Date(w.used).toLocaleString();
5805
- console.log(` ${chalk33.cyan(w.name)} ${chalk33.dim(w.description || "(no description)")}`);
5806
- console.log(` ${chalk33.dim(`${w.steps.length} steps \u2022 last used ${date}`)}`);
5920
+ console.log(` ${chalk34.cyan(w.name)} ${chalk34.dim(w.description || "(no description)")}`);
5921
+ console.log(` ${chalk34.dim(`${w.steps.length} steps \u2022 last used ${date}`)}`);
5807
5922
  }
5808
5923
  }
5809
5924
  async function cmdVectorStore(options) {
5810
5925
  if (options.clear) {
5811
5926
  clearVectors(options.dir);
5812
- console.log(chalk33.green("Vector memory cleared."));
5927
+ console.log(chalk34.green("Vector memory cleared."));
5813
5928
  return;
5814
5929
  }
5815
5930
  if (options.count) {
@@ -5818,8 +5933,8 @@ async function cmdVectorStore(options) {
5818
5933
  }
5819
5934
  if (options.store) {
5820
5935
  const entry = await storeVector(options.store, {}, options.dir);
5821
- console.log(chalk33.green(`Stored: "${options.store.slice(0, 80)}..."`));
5822
- console.log(chalk33.dim(` ID: ${entry.id}`));
5936
+ console.log(chalk34.green(`Stored: "${options.store.slice(0, 80)}..."`));
5937
+ console.log(chalk34.dim(` ID: ${entry.id}`));
5823
5938
  return;
5824
5939
  }
5825
5940
  if (options.query) {
@@ -5827,32 +5942,32 @@ async function cmdVectorStore(options) {
5827
5942
  console.log(formatVectorResults(results));
5828
5943
  return;
5829
5944
  }
5830
- console.log(chalk33.yellow("Specify --query, --store, --count, or --clear."));
5945
+ console.log(chalk34.yellow("Specify --query, --store, --count, or --clear."));
5831
5946
  }
5832
5947
  async function cmdChatLogs(options) {
5833
5948
  const logs = listChatLogs(options.dir);
5834
5949
  if (logs.length === 0) {
5835
- console.log(chalk33.yellow("No chat logs found."));
5950
+ console.log(chalk34.yellow("No chat logs found."));
5836
5951
  return;
5837
5952
  }
5838
5953
  const totalSize = logs.reduce((acc, l) => acc + l.size, 0);
5839
5954
  const sizeStr = totalSize > 1024 ? `${(totalSize / 1024).toFixed(1)} KB` : `${totalSize} B`;
5840
- console.log(chalk33.bold(`
5955
+ console.log(chalk34.bold(`
5841
5956
  Chat Logs (${logs.length}, ${sizeStr}):
5842
5957
  `));
5843
5958
  for (const log of logs.slice(0, 20)) {
5844
5959
  const date = log.modified.toLocaleString();
5845
5960
  const size = log.size > 1024 ? `${(log.size / 1024).toFixed(1)} KB` : `${log.size} B`;
5846
- console.log(` ${chalk33.dim(log.name.slice(0, 50).padEnd(52))} ${chalk33.yellow(size.padStart(8))} ${chalk33.dim(date)}`);
5961
+ console.log(` ${chalk34.dim(log.name.slice(0, 50).padEnd(52))} ${chalk34.yellow(size.padStart(8))} ${chalk34.dim(date)}`);
5847
5962
  }
5848
5963
  if (logs.length > 20) {
5849
- console.log(chalk33.dim(` ... and ${logs.length - 20} more`));
5964
+ console.log(chalk34.dim(` ... and ${logs.length - 20} more`));
5850
5965
  }
5851
5966
  }
5852
5967
  async function cmdClearAll(options) {
5853
5968
  clearAllMemory(options.dir);
5854
5969
  clearVectors(options.dir);
5855
- console.log(chalk33.green("All memory data cleared."));
5970
+ console.log(chalk34.green("All memory data cleared."));
5856
5971
  }
5857
5972
  var memoryCommand = new Command11("memory").alias("mem").description("Manage sessions, memory, and chat logs").option("--dir <path>", "Project directory", process.cwd()).addCommand(
5858
5973
  new Command11("sessions").alias("s").description("List all persistent sessions").option("--dir <path>", "Project directory").action(cmdSessions)
@@ -5894,14 +6009,14 @@ var memoryCommand = new Command11("memory").alias("mem").description("Manage ses
5894
6009
 
5895
6010
  // src/commands/git.ts
5896
6011
  import { Command as Command12 } from "commander";
5897
- import chalk34 from "chalk";
6012
+ import chalk35 from "chalk";
5898
6013
  function requireGit(cwd) {
5899
6014
  if (!isGitAvailable()) {
5900
- console.log(chalk34.red(" \u2717 Git is not installed or not in PATH."));
6015
+ console.log(chalk35.red(" \u2717 Git is not installed or not in PATH."));
5901
6016
  return false;
5902
6017
  }
5903
6018
  if (!isRepo(cwd)) {
5904
- console.log(chalk34.red(" \u2717 Not a git repository."));
6019
+ console.log(chalk35.red(" \u2717 Not a git repository."));
5905
6020
  return false;
5906
6021
  }
5907
6022
  return true;
@@ -5915,39 +6030,39 @@ async function cmdCommit(opts) {
5915
6030
  }
5916
6031
  const status = getStatus(root || dir);
5917
6032
  if (status.clean && !opts.message) {
5918
- console.log(chalk34.yellow(" Nothing to commit. Working tree clean."));
6033
+ console.log(chalk35.yellow(" Nothing to commit. Working tree clean."));
5919
6034
  return;
5920
6035
  }
5921
6036
  let commitMessage = opts.message;
5922
6037
  if (!commitMessage && opts.generate) {
5923
- console.log(chalk34.dim(" Generating commit message..."));
6038
+ console.log(chalk35.dim(" Generating commit message..."));
5924
6039
  commitMessage = await generateCommitMessage();
5925
- console.log(chalk34.cyan(` Generated: ${commitMessage.split("\n")[0]}
6040
+ console.log(chalk35.cyan(` Generated: ${commitMessage.split("\n")[0]}
5926
6041
  `));
5927
6042
  }
5928
6043
  if (!commitMessage) {
5929
- console.log(chalk34.yellow(" No commit message provided. Use --message or --generate."));
5930
- console.log(chalk34.dim(" Examples:"));
5931
- console.log(chalk34.dim(' lovecode commit -m "feat: add login"'));
5932
- console.log(chalk34.dim(" lovecode commit --generate"));
6044
+ console.log(chalk35.yellow(" No commit message provided. Use --message or --generate."));
6045
+ console.log(chalk35.dim(" Examples:"));
6046
+ console.log(chalk35.dim(' lovecode commit -m "feat: add login"'));
6047
+ console.log(chalk35.dim(" lovecode commit --generate"));
5933
6048
  return;
5934
6049
  }
5935
6050
  if (opts.all) {
5936
- console.log(chalk34.dim(" Staging all changes..."));
6051
+ console.log(chalk35.dim(" Staging all changes..."));
5937
6052
  }
5938
6053
  const result = commit(commitMessage, root || dir);
5939
6054
  if (result.success) {
5940
- console.log(chalk34.green(` \u2713 Committed${result.hash ? ` (${result.hash.slice(0, 8)})` : ""}`));
6055
+ console.log(chalk35.green(` \u2713 Committed${result.hash ? ` (${result.hash.slice(0, 8)})` : ""}`));
5941
6056
  if (result.output) {
5942
6057
  const lines = result.output.split("\n").filter(Boolean);
5943
6058
  for (const line of lines) {
5944
6059
  if (line.includes("changed") || line.includes("insertion") || line.includes("deletion")) {
5945
- console.log(chalk34.dim(` ${line}`));
6060
+ console.log(chalk35.dim(` ${line}`));
5946
6061
  }
5947
6062
  }
5948
6063
  }
5949
6064
  } else {
5950
- console.log(chalk34.red(` \u2717 ${result.output}`));
6065
+ console.log(chalk35.red(` \u2717 ${result.output}`));
5951
6066
  }
5952
6067
  }
5953
6068
  async function cmdStatus(options) {
@@ -5955,8 +6070,8 @@ async function cmdStatus(options) {
5955
6070
  const dir = options.dir || process.cwd();
5956
6071
  const root = getGitRoot(dir);
5957
6072
  const status = getStatus(root || dir);
5958
- console.log(chalk34.bold(`
5959
- Git Status \u2014 ${chalk34.cyan(status.branch)}`));
6073
+ console.log(chalk35.bold(`
6074
+ Git Status \u2014 ${chalk35.cyan(status.branch)}`));
5960
6075
  console.log(` ${formatStatus(status)}`);
5961
6076
  console.log("");
5962
6077
  }
@@ -5966,39 +6081,39 @@ async function cmdBranch(action, name, options) {
5966
6081
  const gitRoot = getGitRoot(dir);
5967
6082
  if (!action || action === "list") {
5968
6083
  const branches = getBranches(gitRoot || dir);
5969
- console.log(chalk34.bold(`
6084
+ console.log(chalk35.bold(`
5970
6085
  Branches (${branches.length}):`));
5971
6086
  console.log(` ${formatBranches(branches)}`);
5972
6087
  console.log("");
5973
6088
  return;
5974
6089
  }
5975
6090
  if (!name) {
5976
- console.log(chalk34.yellow(" Branch name required."));
6091
+ console.log(chalk35.yellow(" Branch name required."));
5977
6092
  return;
5978
6093
  }
5979
6094
  switch (action) {
5980
6095
  case "create": {
5981
6096
  const ok = createBranch(name, gitRoot || dir);
5982
- console.log(ok ? chalk34.green(` \u2713 Created and switched to "${name}"`) : chalk34.red(` \u2717 Failed to create branch "${name}"`));
6097
+ console.log(ok ? chalk35.green(` \u2713 Created and switched to "${name}"`) : chalk35.red(` \u2717 Failed to create branch "${name}"`));
5983
6098
  break;
5984
6099
  }
5985
6100
  case "switch": {
5986
6101
  const result = switchBranch(name, gitRoot || dir);
5987
- console.log(result.success ? chalk34.green(` \u2713 Switched to "${name}"`) : chalk34.red(` \u2717 ${result.output}`));
6102
+ console.log(result.success ? chalk35.green(` \u2713 Switched to "${name}"`) : chalk35.red(` \u2717 ${result.output}`));
5988
6103
  break;
5989
6104
  }
5990
6105
  case "delete": {
5991
6106
  const result = deleteBranch(name, options.force, gitRoot || dir);
5992
- console.log(result.success ? chalk34.green(` \u2713 Deleted branch "${name}"`) : chalk34.red(` \u2717 ${result.output}`));
6107
+ console.log(result.success ? chalk35.green(` \u2713 Deleted branch "${name}"`) : chalk35.red(` \u2717 ${result.output}`));
5993
6108
  break;
5994
6109
  }
5995
6110
  case "cleanup": {
5996
- console.log(chalk34.dim(" Cleaning up merged branches..."));
6111
+ console.log(chalk35.dim(" Cleaning up merged branches..."));
5997
6112
  const deleted = cleanupMergedBranches(gitRoot || dir);
5998
6113
  if (deleted.length === 0) {
5999
- console.log(chalk34.yellow(" No merged branches to clean up."));
6114
+ console.log(chalk35.yellow(" No merged branches to clean up."));
6000
6115
  } else {
6001
- console.log(chalk34.green(` \u2713 Deleted ${deleted.length} merged branc${deleted.length > 1 ? "hes" : "h"}:`));
6116
+ console.log(chalk35.green(` \u2713 Deleted ${deleted.length} merged branc${deleted.length > 1 ? "hes" : "h"}:`));
6002
6117
  for (const b of deleted) {
6003
6118
  console.log(` \u2022 ${b}`);
6004
6119
  }
@@ -6006,7 +6121,7 @@ async function cmdBranch(action, name, options) {
6006
6121
  break;
6007
6122
  }
6008
6123
  default:
6009
- console.log(chalk34.yellow(` Unknown action: ${action}. Use: create, switch, delete, cleanup, or list.`));
6124
+ console.log(chalk35.yellow(` Unknown action: ${action}. Use: create, switch, delete, cleanup, or list.`));
6010
6125
  }
6011
6126
  }
6012
6127
  async function cmdLog(options) {
@@ -6016,10 +6131,10 @@ async function cmdLog(options) {
6016
6131
  const count = parseInt(options.count || "10", 10);
6017
6132
  const log = getLog(count, root || dir);
6018
6133
  if (log.length === 0) {
6019
- console.log(chalk34.yellow(" No commits found."));
6134
+ console.log(chalk35.yellow(" No commits found."));
6020
6135
  return;
6021
6136
  }
6022
- console.log(chalk34.bold(`
6137
+ console.log(chalk35.bold(`
6023
6138
  Recent Commits (${log.length}):`));
6024
6139
  console.log(` ${formatLog(log)}`);
6025
6140
  console.log("");
@@ -6027,7 +6142,7 @@ async function cmdLog(options) {
6027
6142
  async function cmdPRSummary(baseBranch, options) {
6028
6143
  if (!requireGit(options.dir)) return;
6029
6144
  const base = baseBranch || "main";
6030
- console.log(chalk34.dim(` Generating PR summary (${base}...HEAD)...`));
6145
+ console.log(chalk35.dim(` Generating PR summary (${base}...HEAD)...`));
6031
6146
  const summary = await generatePRSummary(base);
6032
6147
  console.log(`
6033
6148
  ${summary}
@@ -6053,19 +6168,19 @@ async function cmdDiff(options) {
6053
6168
  const root = getGitRoot(dir);
6054
6169
  const diff = options.staged ? (await import("./git-FZPRJVFI.js")).getStagedDiff(root || dir) : getDiff(root || dir);
6055
6170
  if (!diff) {
6056
- console.log(chalk34.yellow(" No changes to show."));
6171
+ console.log(chalk35.yellow(" No changes to show."));
6057
6172
  return;
6058
6173
  }
6059
6174
  const lines = diff.split("\n");
6060
6175
  for (const line of lines) {
6061
6176
  if (line.startsWith("+")) {
6062
- process.stdout.write(chalk34.green(line) + "\n");
6177
+ process.stdout.write(chalk35.green(line) + "\n");
6063
6178
  } else if (line.startsWith("-")) {
6064
- process.stdout.write(chalk34.red(line) + "\n");
6179
+ process.stdout.write(chalk35.red(line) + "\n");
6065
6180
  } else if (line.startsWith("@@")) {
6066
- process.stdout.write(chalk34.cyan(line) + "\n");
6181
+ process.stdout.write(chalk35.cyan(line) + "\n");
6067
6182
  } else if (line.startsWith("diff --git")) {
6068
- process.stdout.write(chalk34.bold(line) + "\n");
6183
+ process.stdout.write(chalk35.bold(line) + "\n");
6069
6184
  } else {
6070
6185
  process.stdout.write(line + "\n");
6071
6186
  }
@@ -6109,7 +6224,7 @@ gitCommand.command("diff").description("Show diff").option("--staged", "Show sta
6109
6224
 
6110
6225
  // src/commands/tui.ts
6111
6226
  import { Command as Command13 } from "commander";
6112
- import chalk35 from "chalk";
6227
+ import chalk36 from "chalk";
6113
6228
 
6114
6229
  // src/tui/index.ts
6115
6230
  import React4 from "react";
@@ -6888,19 +7003,293 @@ function startTUI(props) {
6888
7003
  }
6889
7004
 
6890
7005
  // src/commands/tui.ts
7006
+ var TOOL_SYSTEM_PROMPT = `You are LoveCode AI, a terminal-native coding assistant with full access to the project filesystem.
7007
+
7008
+ You can read, write, edit, and search files using tool tags:
7009
+
7010
+ <tool name="read_file">
7011
+ path=<file path>
7012
+ </tool>
7013
+
7014
+ <tool name="write_file">
7015
+ path=<file path>
7016
+ content=<file content>
7017
+ </tool>
7018
+
7019
+ <tool name="edit_file">
7020
+ path=<file path>
7021
+ oldString=<text to replace>
7022
+ newString=<replacement text>
7023
+ </tool>
7024
+
7025
+ <tool name="create_file">
7026
+ path=<file path>
7027
+ </tool>
7028
+
7029
+ <tool name="delete_file">
7030
+ path=<file path>
7031
+ </tool>
7032
+
7033
+ <tool name="append_file">
7034
+ path=<file path>
7035
+ content=<text to append>
7036
+ </tool>
7037
+
7038
+ <tool name="grep_search">
7039
+ pattern=<regex pattern>
7040
+ </tool>
7041
+
7042
+ <tool name="glob_search">
7043
+ pattern=<glob pattern>
7044
+ </tool>
7045
+
7046
+ <tool name="read_dir">
7047
+ path=<directory path>
7048
+ </tool>
7049
+
7050
+ <tool name="execute_command">
7051
+ command=<shell command>
7052
+ </tool>
7053
+
7054
+ When you need to access files, use the appropriate tool tag.
7055
+ After getting results, continue helping the user.`;
7056
+ async function loadAIProvider() {
7057
+ try {
7058
+ const { loadEnv: loadEnv2 } = await import("./env-HJQWWL6N.js");
7059
+ const { loadConfig: loadConfig2 } = await import("./config-FJNTTKR3.js");
7060
+ const { resolveModel } = await import("./registry-ADSIKXA4.js");
7061
+ loadEnv2();
7062
+ const cfg = loadConfig2();
7063
+ if (!cfg.provider) {
7064
+ console.log(chalk36.yellow("No AI provider configured. Use `lovecode init` to set one up."));
7065
+ return null;
7066
+ }
7067
+ const resolved = resolveModel(cfg.provider);
7068
+ if (!resolved) {
7069
+ console.log(chalk36.yellow(`Provider "${cfg.provider}" not found. Use \`lovecode init\` to reconfigure.`));
7070
+ return null;
7071
+ }
7072
+ const provider = resolved.entry.provider;
7073
+ const model = resolved.model;
7074
+ const config = {
7075
+ model,
7076
+ temperature: cfg.model_params?.temperature ?? 0.2,
7077
+ maxTokens: cfg.model_params?.max_tokens ?? 4096,
7078
+ baseUrl: cfg.api?.base_url
7079
+ };
7080
+ return { provider, config };
7081
+ } catch (err) {
7082
+ console.log(chalk36.red(`Failed to load AI provider: ${err.message}`));
7083
+ return null;
7084
+ }
7085
+ }
7086
+ async function processToolCalls(response, workingDir) {
7087
+ const outputs = [];
7088
+ const toolRegex = /<tool\s+name="([^"]+)">\n?([\s\S]*?)<\/tool>/g;
7089
+ let match;
7090
+ while ((match = toolRegex.exec(response)) !== null) {
7091
+ const toolName = match[1];
7092
+ const argsBlock = match[2].trim();
7093
+ const args = {};
7094
+ for (const line of argsBlock.split("\n")) {
7095
+ const eqIdx = line.indexOf("=");
7096
+ if (eqIdx > 0) {
7097
+ const key = line.slice(0, eqIdx).trim();
7098
+ const value = line.slice(eqIdx + 1).trim();
7099
+ args[key] = value;
7100
+ }
7101
+ }
7102
+ try {
7103
+ const tool = await getTool2(toolName);
7104
+ if (!tool) {
7105
+ outputs.push(`Unknown tool: ${toolName}`);
7106
+ continue;
7107
+ }
7108
+ const result = await tool.execute(workingDir, args);
7109
+ const output = result.success ? `[${toolName}] result:
7110
+ ${result.output.slice(0, 3e3)}` : `[${toolName}] error: ${result.error || result.output}`;
7111
+ outputs.push(output);
7112
+ } catch (err) {
7113
+ outputs.push(`[${toolName}] exception: ${err.message}`);
7114
+ }
7115
+ }
7116
+ return outputs;
7117
+ }
7118
+ async function getTool2(name) {
7119
+ if (name === "read_file") {
7120
+ const { readFileSync: readFileSync18, existsSync: existsSync16 } = await import("fs");
7121
+ const { resolve: resolve5 } = await import("path");
7122
+ return {
7123
+ execute: async (workingDir, args) => {
7124
+ const filePath = resolve5(workingDir, args.path || ".");
7125
+ if (!existsSync16(filePath)) return { success: false, output: "", error: `File not found: ${args.path}` };
7126
+ const content = readFileSync18(filePath, "utf-8");
7127
+ const lines = content.split("\n");
7128
+ const numbered = lines.map((l, i) => `${String(i + 1).padStart(4, " ")} | ${l}`).join("\n");
7129
+ return { success: true, output: numbered };
7130
+ }
7131
+ };
7132
+ }
7133
+ if (name === "write_file") {
7134
+ const { writeFileSync: writeFileSync11, mkdirSync: mkdirSync10 } = await import("fs");
7135
+ const { resolve: resolve5, dirname: dirname6 } = await import("path");
7136
+ return {
7137
+ execute: async (workingDir, args) => {
7138
+ const filePath = resolve5(workingDir, args.path || "");
7139
+ mkdirSync10(dirname6(filePath), { recursive: true });
7140
+ writeFileSync11(filePath, args.content || "", "utf-8");
7141
+ return { success: true, output: `Wrote ${filePath}` };
7142
+ }
7143
+ };
7144
+ }
7145
+ if (name === "edit_file") {
7146
+ const { readFileSync: readFileSync18, writeFileSync: writeFileSync11, existsSync: existsSync16 } = await import("fs");
7147
+ const { resolve: resolve5 } = await import("path");
7148
+ return {
7149
+ execute: async (workingDir, args) => {
7150
+ const filePath = resolve5(workingDir, args.path || "");
7151
+ if (!existsSync16(filePath)) return { success: false, output: "", error: `File not found: ${args.path}` };
7152
+ const content = readFileSync18(filePath, "utf-8");
7153
+ if (!args.oldString) return { success: false, output: "", error: "oldString required" };
7154
+ const escaped = args.oldString.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
7155
+ const count = (content.match(new RegExp(escaped, "g")) || []).length;
7156
+ if (count === 0) return { success: false, output: "", error: `oldString not found in ${args.path}` };
7157
+ const updated = content.replaceAll(args.oldString, args.newString || "");
7158
+ writeFileSync11(filePath, updated, "utf-8");
7159
+ return { success: true, output: `Edited ${filePath} (${count} replacement${count > 1 ? "s" : ""})` };
7160
+ }
7161
+ };
7162
+ }
7163
+ if (name === "create_file") {
7164
+ const { writeFileSync: writeFileSync11, mkdirSync: mkdirSync10, existsSync: existsSync16 } = await import("fs");
7165
+ const { resolve: resolve5, dirname: dirname6 } = await import("path");
7166
+ return {
7167
+ execute: async (workingDir, args) => {
7168
+ const filePath = resolve5(workingDir, args.path || "");
7169
+ if (existsSync16(filePath)) return { success: false, output: "", error: `File exists: ${args.path}` };
7170
+ mkdirSync10(dirname6(filePath), { recursive: true });
7171
+ writeFileSync11(filePath, "", "utf-8");
7172
+ return { success: true, output: `Created ${filePath}` };
7173
+ }
7174
+ };
7175
+ }
7176
+ if (name === "delete_file") {
7177
+ const { unlinkSync: unlinkSync7, existsSync: existsSync16 } = await import("fs");
7178
+ const { resolve: resolve5 } = await import("path");
7179
+ return {
7180
+ execute: async (workingDir, args) => {
7181
+ const filePath = resolve5(workingDir, args.path || "");
7182
+ if (!existsSync16(filePath)) return { success: false, output: "", error: `File not found: ${args.path}` };
7183
+ unlinkSync7(filePath);
7184
+ return { success: true, output: `Deleted ${filePath}` };
7185
+ }
7186
+ };
7187
+ }
7188
+ if (name === "append_file") {
7189
+ const { appendFileSync: appendFileSync2, mkdirSync: mkdirSync10 } = await import("fs");
7190
+ const { resolve: resolve5, dirname: dirname6 } = await import("path");
7191
+ return {
7192
+ execute: async (workingDir, args) => {
7193
+ const filePath = resolve5(workingDir, args.path || "");
7194
+ mkdirSync10(dirname6(filePath), { recursive: true });
7195
+ appendFileSync2(filePath, (args.content || "") + "\n", "utf-8");
7196
+ return { success: true, output: `Appended to ${filePath}` };
7197
+ }
7198
+ };
7199
+ }
7200
+ if (name === "grep_search") {
7201
+ const { execSync: execSync5 } = await import("child_process");
7202
+ return {
7203
+ execute: async (workingDir, args) => {
7204
+ try {
7205
+ const pattern = args.pattern || "";
7206
+ const cmd = `rg -n '${pattern.replace(/'/g, "'\\''")}' 2>/dev/null || echo "(no matches)"`;
7207
+ const output = execSync5(cmd, { cwd: workingDir, encoding: "utf-8", maxBuffer: 1024 * 1024 });
7208
+ return { success: true, output: output.trim() };
7209
+ } catch {
7210
+ return { success: true, output: "(no matches)" };
7211
+ }
7212
+ }
7213
+ };
7214
+ }
7215
+ if (name === "glob_search") {
7216
+ const { execSync: execSync5 } = await import("child_process");
7217
+ return {
7218
+ execute: async (workingDir, args) => {
7219
+ try {
7220
+ const pattern = args.pattern || "*";
7221
+ const cmd = `ls -1 ${pattern} 2>/dev/null || echo "(no files found)"`;
7222
+ const output = execSync5(cmd, { cwd: workingDir, encoding: "utf-8", maxBuffer: 1024 * 1024 });
7223
+ return { success: true, output: output.trim() };
7224
+ } catch {
7225
+ return { success: true, output: "(no files found)" };
7226
+ }
7227
+ }
7228
+ };
7229
+ }
7230
+ if (name === "read_dir") {
7231
+ const { readdirSync: readdirSync13, existsSync: existsSync16 } = await import("fs");
7232
+ const { resolve: resolve5 } = await import("path");
7233
+ return {
7234
+ execute: async (workingDir, args) => {
7235
+ const dirPath = resolve5(workingDir, args.path || ".");
7236
+ if (!existsSync16(dirPath)) return { success: false, output: "", error: `Directory not found: ${args.path}` };
7237
+ const entries = readdirSync13(dirPath, { withFileTypes: true });
7238
+ const output = entries.map((e) => e.isDirectory() ? `${e.name}/` : e.name).join("\n");
7239
+ return { success: true, output };
7240
+ }
7241
+ };
7242
+ }
7243
+ if (name === "execute_command") {
7244
+ const { execSync: execSync5 } = await import("child_process");
7245
+ return {
7246
+ execute: async (workingDir, args) => {
7247
+ try {
7248
+ const command = args.command || "";
7249
+ const timeout = parseInt(args.timeout || "30000", 10);
7250
+ const output = execSync5(command, {
7251
+ cwd: workingDir,
7252
+ encoding: "utf-8",
7253
+ maxBuffer: 1024 * 1024,
7254
+ timeout
7255
+ });
7256
+ return { success: true, output: output.trim() };
7257
+ } catch (err) {
7258
+ const e = err;
7259
+ return { success: false, output: e.stderr || e.message, error: e.message };
7260
+ }
7261
+ }
7262
+ };
7263
+ }
7264
+ return null;
7265
+ }
6891
7266
  async function cmdTUI(options) {
6892
- console.log(chalk35.dim("Starting LoveCode TUI..."));
7267
+ const workingDir = options.dir || process.cwd();
7268
+ console.log(chalk36.dim("Starting LoveCode TUI..."));
6893
7269
  if (options.theme) {
6894
7270
  const mod = await import("./theme-ZRZYRB2Q.js");
6895
7271
  const names = mod.getThemeNames();
6896
- const themeName = options.theme;
6897
- const n = themeName;
6898
- if (names.includes(themeName)) {
6899
- mod.setTheme(n);
6900
- } else {
6901
- console.log(chalk35.yellow(`Unknown theme "${options.theme}". Using default. Available: ${names.join(", ")}`));
6902
- }
7272
+ if (names.includes(options.theme)) {
7273
+ mod.setTheme(options.theme);
7274
+ }
7275
+ }
7276
+ const ai = await loadAIProvider();
7277
+ if (!ai) {
7278
+ startTUI({
7279
+ projectName: "LoveCode AI",
7280
+ branch: "main",
7281
+ fileCount: 142,
7282
+ language: "TypeScript",
7283
+ framework: "Node.js",
7284
+ repoStatus: "clean",
7285
+ messages: [],
7286
+ onSendMessage: async () => "No AI provider configured. Run `lovecode init` to set one up.",
7287
+ onRunCommand: async () => "No AI provider configured."
7288
+ });
7289
+ return;
6903
7290
  }
7291
+ const { provider, config } = ai;
7292
+ const messages = [{ role: "system", content: TOOL_SYSTEM_PROMPT }];
6904
7293
  startTUI({
6905
7294
  projectName: "LoveCode AI",
6906
7295
  branch: "main",
@@ -6909,13 +7298,32 @@ async function cmdTUI(options) {
6909
7298
  framework: "Node.js",
6910
7299
  repoStatus: "clean",
6911
7300
  messages: [],
7301
+ provider: provider.name,
7302
+ model: config.model,
6912
7303
  onSendMessage: async (msg) => {
6913
- return `You said: ${msg}
6914
-
6915
- This is a simulated AI response. Connect to a real AI provider for actual responses.`;
7304
+ messages.push({ role: "user", content: msg });
7305
+ for (let round = 0; round < 5; round++) {
7306
+ const response = await provider.chat(messages, config);
7307
+ messages.push({ role: "assistant", content: response });
7308
+ const toolOutputs = await processToolCalls(response, workingDir);
7309
+ if (toolOutputs.length === 0) {
7310
+ return response;
7311
+ }
7312
+ for (const output of toolOutputs) {
7313
+ messages.push({ role: "user", content: output });
7314
+ }
7315
+ }
7316
+ return "Max tool call rounds reached. Please try again with a simpler request.";
6916
7317
  },
6917
- onRunCommand: async (cmd) => {
6918
- return `Simulated output for: ${cmd}`;
7318
+ onRunCommand: async (command) => {
7319
+ const { execSync: execSync5 } = await import("child_process");
7320
+ try {
7321
+ const output = execSync5(command, { cwd: workingDir, encoding: "utf-8", timeout: 6e4 });
7322
+ return output.trim();
7323
+ } catch (err) {
7324
+ const e = err;
7325
+ return e.stderr || e.message;
7326
+ }
6919
7327
  }
6920
7328
  });
6921
7329
  }
@@ -6925,20 +7333,23 @@ var tuiCommand = new Command13("tui").alias("ui").description("Launch the Termin
6925
7333
  Escape Enter vim normal mode
6926
7334
  i Enter vim insert mode
6927
7335
  j/k Scroll up/down (vim normal mode)
6928
- Ctrl+N/P Next/previous pane
6929
7336
 
6930
7337
  Slash commands:
6931
7338
  /help Show help
6932
7339
  /clear Clear messages
6933
- /theme <n> Change theme (default, dark, light, ocean, solarized)
6934
- /vim Toggle vim mode
7340
+ /theme <n> Change theme
7341
+ /connect Show providers
7342
+ /model Show AI config
7343
+ /export Save chat to file
6935
7344
  /!<cmd> Run a shell command
6936
7345
  /exit Quit TUI
7346
+
7347
+ The AI can read, write, and edit files in the project directory.
6937
7348
  `);
6938
7349
 
6939
7350
  // src/commands/plugin.ts
6940
7351
  import { Command as Command14 } from "commander";
6941
- import chalk36 from "chalk";
7352
+ import chalk37 from "chalk";
6942
7353
  async function cmdListPlugins() {
6943
7354
  const { listPlugins: listPlugins2, formatPluginList } = await import("./registry-MW5ISDO7.js");
6944
7355
  const plugins = listPlugins2();
@@ -6947,12 +7358,12 @@ async function cmdListPlugins() {
6947
7358
  async function cmdEnablePlugin(name) {
6948
7359
  const { enablePlugin: enablePlugin2 } = await import("./registry-MW5ISDO7.js");
6949
7360
  const ok = enablePlugin2(name);
6950
- console.log(ok ? chalk36.green(`Enabled plugin: ${name}`) : chalk36.red(`Plugin not found: ${name}`));
7361
+ console.log(ok ? chalk37.green(`Enabled plugin: ${name}`) : chalk37.red(`Plugin not found: ${name}`));
6951
7362
  }
6952
7363
  async function cmdDisablePlugin(name) {
6953
7364
  const { disablePlugin: disablePlugin2 } = await import("./registry-MW5ISDO7.js");
6954
7365
  const ok = disablePlugin2(name);
6955
- console.log(ok ? chalk36.yellow(`Disabled plugin: ${name}`) : chalk36.red(`Plugin not found: ${name}`));
7366
+ console.log(ok ? chalk37.yellow(`Disabled plugin: ${name}`) : chalk37.red(`Plugin not found: ${name}`));
6956
7367
  }
6957
7368
  async function cmdSearchMarketplace(query) {
6958
7369
  const { searchMarketplace, formatMarketplace } = await import("./registry-MW5ISDO7.js");
@@ -6973,37 +7384,37 @@ pluginCommand.command("search").description("Search plugin marketplace").argumen
6973
7384
 
6974
7385
  // src/commands/browser.ts
6975
7386
  import { Command as Command15 } from "commander";
6976
- import chalk37 from "chalk";
7387
+ import chalk38 from "chalk";
6977
7388
  async function cmdStart(options) {
6978
7389
  const { launchBrowser } = await import("./playwright-N7OAVW2N.js");
6979
7390
  try {
6980
7391
  await launchBrowser({ headless: options.headless !== false });
6981
- console.log(chalk37.green("Browser launched."));
7392
+ console.log(chalk38.green("Browser launched."));
6982
7393
  } catch (err) {
6983
- console.log(chalk37.red(`Failed: ${err.message}`));
7394
+ console.log(chalk38.red(`Failed: ${err.message}`));
6984
7395
  }
6985
7396
  }
6986
7397
  async function cmdStop() {
6987
7398
  const { closeBrowser } = await import("./playwright-N7OAVW2N.js");
6988
7399
  await closeBrowser();
6989
- console.log(chalk37.yellow("Browser closed."));
7400
+ console.log(chalk38.yellow("Browser closed."));
6990
7401
  }
6991
7402
  async function cmdGoto(url) {
6992
7403
  const { goto: goto2 } = await import("./playwright-N7OAVW2N.js");
6993
7404
  try {
6994
7405
  const result = await goto2(url);
6995
- console.log(chalk37.green(result));
7406
+ console.log(chalk38.green(result));
6996
7407
  } catch (err) {
6997
- console.log(chalk37.red(`Error: ${err.message}`));
7408
+ console.log(chalk38.red(`Error: ${err.message}`));
6998
7409
  }
6999
7410
  }
7000
7411
  async function cmdClick(selector) {
7001
7412
  const { click: click2 } = await import("./playwright-N7OAVW2N.js");
7002
7413
  try {
7003
7414
  const result = await click2(selector);
7004
- console.log(chalk37.green(result));
7415
+ console.log(chalk38.green(result));
7005
7416
  } catch (err) {
7006
- console.log(chalk37.red(`Error: ${err.message}`));
7417
+ console.log(chalk38.red(`Error: ${err.message}`));
7007
7418
  }
7008
7419
  }
7009
7420
  async function cmdType(selector, text, options) {
@@ -7011,18 +7422,18 @@ async function cmdType(selector, text, options) {
7011
7422
  const value = text || options.text || "";
7012
7423
  try {
7013
7424
  const result = await type2(selector, value);
7014
- console.log(chalk37.green(result));
7425
+ console.log(chalk38.green(result));
7015
7426
  } catch (err) {
7016
- console.log(chalk37.red(`Error: ${err.message}`));
7427
+ console.log(chalk38.red(`Error: ${err.message}`));
7017
7428
  }
7018
7429
  }
7019
7430
  async function cmdScreenshot(options) {
7020
7431
  const { screenshot: screenshot2, formatScreenshotResult: formatScreenshotResult2 } = await import("./playwright-N7OAVW2N.js");
7021
7432
  try {
7022
7433
  const result = await screenshot2(options.name);
7023
- console.log(chalk37.green(formatScreenshotResult2(result)));
7434
+ console.log(chalk38.green(formatScreenshotResult2(result)));
7024
7435
  } catch (err) {
7025
- console.log(chalk37.red(`Error: ${err.message}`));
7436
+ console.log(chalk38.red(`Error: ${err.message}`));
7026
7437
  }
7027
7438
  }
7028
7439
  async function cmdInspect(selector) {
@@ -7032,10 +7443,10 @@ async function cmdInspect(selector) {
7032
7443
  if (el) {
7033
7444
  console.log(formatDOMElement2(el));
7034
7445
  } else {
7035
- console.log(chalk37.yellow(`Element not found: ${selector}`));
7446
+ console.log(chalk38.yellow(`Element not found: ${selector}`));
7036
7447
  }
7037
7448
  } catch (err) {
7038
- console.log(chalk37.red(`Error: ${err.message}`));
7449
+ console.log(chalk38.red(`Error: ${err.message}`));
7039
7450
  }
7040
7451
  }
7041
7452
  async function cmdActions(actions, options) {
@@ -7051,10 +7462,10 @@ async function cmdActions(actions, options) {
7051
7462
  try {
7052
7463
  const results = await runActions(parsedActions);
7053
7464
  for (const r of results) {
7054
- console.log(chalk37.cyan(` \u2192 ${r.slice(0, 200)}`));
7465
+ console.log(chalk38.cyan(` \u2192 ${r.slice(0, 200)}`));
7055
7466
  }
7056
7467
  } catch (err) {
7057
- console.log(chalk37.red(`Error: ${err.message}`));
7468
+ console.log(chalk38.red(`Error: ${err.message}`));
7058
7469
  }
7059
7470
  }
7060
7471
  var browserCommand = new Command15("browser").alias("br").description("Browser automation \u2014 Playwright-powered").addHelpText("after", `
@@ -7081,10 +7492,10 @@ browserCommand.command("actions").description("Run a sequence of browser actions
7081
7492
 
7082
7493
  // src/commands/security.ts
7083
7494
  import { Command as Command16 } from "commander";
7084
- import chalk42 from "chalk";
7495
+ import chalk43 from "chalk";
7085
7496
 
7086
7497
  // src/security/risk.ts
7087
- import chalk38 from "chalk";
7498
+ import chalk39 from "chalk";
7088
7499
  var COMMAND_RULES = [
7089
7500
  { pattern: /^rm\s+-rf\s+(\/|\/\w+|\.)/, score: 100, reason: "Destructive recursive delete" },
7090
7501
  { pattern: /^rm\s+-rf/, score: 80, reason: "Recursive force delete" },
@@ -7195,21 +7606,21 @@ function scoreToAction(score) {
7195
7606
  }
7196
7607
  function formatRisk(risk) {
7197
7608
  const colors = {
7198
- safe: chalk38.green,
7199
- low: chalk38.cyan,
7200
- medium: chalk38.yellow,
7201
- high: chalk38.red,
7202
- critical: chalk38.bgRed.white
7609
+ safe: chalk39.green,
7610
+ low: chalk39.cyan,
7611
+ medium: chalk39.yellow,
7612
+ high: chalk39.red,
7613
+ critical: chalk39.bgRed.white
7203
7614
  };
7204
- const color = colors[risk.level] || chalk38.dim;
7615
+ const color = colors[risk.level] || chalk39.dim;
7205
7616
  const label = risk.level.toUpperCase().padEnd(10);
7206
- const action = risk.suggestedAction === "auto" ? chalk38.green(risk.suggestedAction) : risk.suggestedAction === "confirm" ? chalk38.yellow(risk.suggestedAction) : chalk38.bgRed.white(` ${risk.suggestedAction} `);
7207
- return ` ${color(label)} score=${risk.score} action=${action} ${chalk38.dim(risk.reasons.join(", "))}`;
7617
+ const action = risk.suggestedAction === "auto" ? chalk39.green(risk.suggestedAction) : risk.suggestedAction === "confirm" ? chalk39.yellow(risk.suggestedAction) : chalk39.bgRed.white(` ${risk.suggestedAction} `);
7618
+ return ` ${color(label)} score=${risk.score} action=${action} ${chalk39.dim(risk.reasons.join(", "))}`;
7208
7619
  }
7209
7620
 
7210
7621
  // src/security/secrets.ts
7211
7622
  import * as fs21 from "fs";
7212
- import chalk39 from "chalk";
7623
+ import chalk40 from "chalk";
7213
7624
  var SECRET_RULES = [
7214
7625
  { type: "aws_key", pattern: /(?:AKIA|ASIA)[0-9A-Z]{16}/g, severity: "critical", description: "AWS Access Key ID" },
7215
7626
  { type: "gcp_key", pattern: /AIza[0-9A-Za-z\-_]{35}/g, severity: "critical", description: "GCP API Key" },
@@ -7294,30 +7705,30 @@ function scanDirectory2(dirPath, maxFiles = 100) {
7294
7705
  }
7295
7706
  function formatSecretMatch(match) {
7296
7707
  const severityColor = {
7297
- low: chalk39.cyan,
7298
- medium: chalk39.yellow,
7299
- high: chalk39.red,
7300
- critical: chalk39.bgRed.white
7708
+ low: chalk40.cyan,
7709
+ medium: chalk40.yellow,
7710
+ high: chalk40.red,
7711
+ critical: chalk40.bgRed.white
7301
7712
  };
7302
- const sev = severityColor[match.severity] || chalk39.dim;
7303
- const fileInfo = match.file ? `${chalk39.dim(match.file)}:${match.line}:${match.column}` : `line ${match.line}:${match.column}`;
7713
+ const sev = severityColor[match.severity] || chalk40.dim;
7714
+ const fileInfo = match.file ? `${chalk40.dim(match.file)}:${match.line}:${match.column}` : `line ${match.line}:${match.column}`;
7304
7715
  return ` ${sev(match.severity.toUpperCase().padEnd(10))} ${match.type.padEnd(20)} ${match.value.padEnd(30)} ${fileInfo}
7305
- ${chalk39.dim(match.context)}`;
7716
+ ${chalk40.dim(match.context)}`;
7306
7717
  }
7307
7718
  function formatSecretSummary(matches) {
7308
- if (matches.length === 0) return chalk39.green("No secrets detected.");
7719
+ if (matches.length === 0) return chalk40.green("No secrets detected.");
7309
7720
  const bySeverity = /* @__PURE__ */ new Map();
7310
7721
  for (const m of matches) {
7311
7722
  const arr = bySeverity.get(m.severity) || [];
7312
7723
  arr.push(m);
7313
7724
  bySeverity.set(m.severity, arr);
7314
7725
  }
7315
- const lines = [chalk39.bold(`
7726
+ const lines = [chalk40.bold(`
7316
7727
  Secrets Detected (${matches.length}):`)];
7317
7728
  for (const [severity, ms] of bySeverity) {
7318
7729
  const label = severity.toUpperCase();
7319
7730
  lines.push(`
7320
- ${chalk39.bold(label)} (${ms.length}):`);
7731
+ ${chalk40.bold(label)} (${ms.length}):`);
7321
7732
  for (const m of ms.slice(0, 10)) {
7322
7733
  lines.push(formatSecretMatch(m));
7323
7734
  }
@@ -7327,7 +7738,7 @@ function formatSecretSummary(matches) {
7327
7738
  }
7328
7739
 
7329
7740
  // src/security/sandbox.ts
7330
- import chalk40 from "chalk";
7741
+ import chalk41 from "chalk";
7331
7742
  var PROFILES = {
7332
7743
  isolated: {
7333
7744
  name: "isolated",
@@ -7456,10 +7867,10 @@ function checkCommand(command, cwd, profileName) {
7456
7867
  return { allowed: true };
7457
7868
  }
7458
7869
  function formatProfile(profile) {
7459
- const yes = chalk40.green("\u2713");
7460
- const no = chalk40.red("\u2717");
7870
+ const yes = chalk41.green("\u2713");
7871
+ const no = chalk41.red("\u2717");
7461
7872
  return [
7462
- `${chalk40.bold(profile.name.toUpperCase())}`,
7873
+ `${chalk41.bold(profile.name.toUpperCase())}`,
7463
7874
  ` Network: ${profile.allowNetwork ? yes : no}`,
7464
7875
  ` File Read: ${profile.allowFileRead ? yes : no}`,
7465
7876
  ` File Write: ${profile.allowFileWrite ? yes : no}`,
@@ -7473,7 +7884,7 @@ function formatProfile(profile) {
7473
7884
  // src/security/permissions.ts
7474
7885
  import * as fs22 from "fs";
7475
7886
  import * as path20 from "path";
7476
- import chalk41 from "chalk";
7887
+ import chalk42 from "chalk";
7477
7888
  var PERMISSION_FILE = ".lovecode/permissions.json";
7478
7889
  var DEFAULT_PERMISSIONS = {
7479
7890
  version: 1,
@@ -7586,24 +7997,24 @@ function resetPermissions(rootDir) {
7586
7997
  cachedPermissions = null;
7587
7998
  }
7588
7999
  function formatPermissions(perms) {
7589
- const lines = [chalk41.bold("\n Permission Settings")];
7590
- lines.push(` ${chalk41.dim("File Read:")} ${formatAction(perms.defaults.fileRead)}`);
7591
- lines.push(` ${chalk41.dim("File Write:")} ${formatAction(perms.defaults.fileWrite)}`);
7592
- lines.push(` ${chalk41.dim("Network:")} ${formatAction(perms.defaults.networkAccess)}`);
7593
- lines.push(` ${chalk41.dim("Commands:")} ${formatAction(perms.defaults.commandExecution)}`);
7594
- lines.push(` ${chalk41.dim("Environment:")} ${formatAction(perms.defaults.environmentAccess)}`);
8000
+ const lines = [chalk42.bold("\n Permission Settings")];
8001
+ lines.push(` ${chalk42.dim("File Read:")} ${formatAction(perms.defaults.fileRead)}`);
8002
+ lines.push(` ${chalk42.dim("File Write:")} ${formatAction(perms.defaults.fileWrite)}`);
8003
+ lines.push(` ${chalk42.dim("Network:")} ${formatAction(perms.defaults.networkAccess)}`);
8004
+ lines.push(` ${chalk42.dim("Commands:")} ${formatAction(perms.defaults.commandExecution)}`);
8005
+ lines.push(` ${chalk42.dim("Environment:")} ${formatAction(perms.defaults.environmentAccess)}`);
7595
8006
  if (perms.entries.length > 0) {
7596
8007
  lines.push(`
7597
- ${chalk41.bold("Specific Permissions:")}`);
8008
+ ${chalk42.bold("Specific Permissions:")}`);
7598
8009
  for (const e of perms.entries) {
7599
- lines.push(` ${formatAction(e.action)} ${e.resource}${e.reason ? ` ${chalk41.dim(`(${e.reason})`)}` : ""}`);
8010
+ lines.push(` ${formatAction(e.action)} ${e.resource}${e.reason ? ` ${chalk42.dim(`(${e.reason})`)}` : ""}`);
7600
8011
  }
7601
8012
  }
7602
8013
  if (perms.trustedSources.length > 0) {
7603
8014
  lines.push(`
7604
- ${chalk41.bold("Trusted Sources:")}`);
8015
+ ${chalk42.bold("Trusted Sources:")}`);
7605
8016
  for (const s of perms.trustedSources) {
7606
- lines.push(` ${chalk41.green("\u2713")} ${s}`);
8017
+ lines.push(` ${chalk42.green("\u2713")} ${s}`);
7607
8018
  }
7608
8019
  }
7609
8020
  return lines.join("\n");
@@ -7611,11 +8022,11 @@ function formatPermissions(perms) {
7611
8022
  function formatAction(action) {
7612
8023
  switch (action) {
7613
8024
  case "allow":
7614
- return chalk41.green("ALLOW");
8025
+ return chalk42.green("ALLOW");
7615
8026
  case "deny":
7616
- return chalk41.red("DENY");
8027
+ return chalk42.red("DENY");
7617
8028
  case "ask":
7618
- return chalk41.yellow("ASK");
8029
+ return chalk42.yellow("ASK");
7619
8030
  }
7620
8031
  }
7621
8032
 
@@ -7624,8 +8035,8 @@ async function cmdAssessRisk(command, options) {
7624
8035
  if (command) {
7625
8036
  const risk = assessCommandRisk(command);
7626
8037
  console.log(`
7627
- ${chalk42.bold("Command Risk Assessment")}`);
7628
- console.log(` ${chalk42.dim(command)}`);
8038
+ ${chalk43.bold("Command Risk Assessment")}`);
8039
+ console.log(` ${chalk43.dim(command)}`);
7629
8040
  console.log(formatRisk(risk));
7630
8041
  } else if (options.tool) {
7631
8042
  let args;
@@ -7638,11 +8049,11 @@ async function cmdAssessRisk(command, options) {
7638
8049
  }
7639
8050
  const risk = assessToolRisk(options.tool, args);
7640
8051
  console.log(`
7641
- ${chalk42.bold("Tool Risk Assessment")}`);
7642
- console.log(` ${chalk42.dim(`${options.tool}${args ? " " + JSON.stringify(args) : ""}`)}`);
8052
+ ${chalk43.bold("Tool Risk Assessment")}`);
8053
+ console.log(` ${chalk43.dim(`${options.tool}${args ? " " + JSON.stringify(args) : ""}`)}`);
7643
8054
  console.log(formatRisk(risk));
7644
8055
  } else {
7645
- console.log(chalk42.yellow("Provide a command string or --tool."));
8056
+ console.log(chalk43.yellow("Provide a command string or --tool."));
7646
8057
  }
7647
8058
  }
7648
8059
  async function cmdScanSecrets(options) {
@@ -7651,16 +8062,16 @@ async function cmdScanSecrets(options) {
7651
8062
  console.log(formatSecretSummary(matches));
7652
8063
  } else if (options.dir) {
7653
8064
  const max = parseInt(options.max || "100", 10);
7654
- console.log(chalk42.dim(`Scanning ${options.dir} for secrets...`));
8065
+ console.log(chalk43.dim(`Scanning ${options.dir} for secrets...`));
7655
8066
  const matches = scanDirectory2(options.dir, max);
7656
8067
  console.log(formatSecretSummary(matches));
7657
8068
  } else {
7658
- console.log(chalk42.yellow("Provide --text or --dir."));
8069
+ console.log(chalk43.yellow("Provide --text or --dir."));
7659
8070
  }
7660
8071
  }
7661
8072
  async function cmdProfiles() {
7662
8073
  const profiles = listProfiles();
7663
- console.log(chalk42.bold("\n Sandbox Profiles:\n"));
8074
+ console.log(chalk43.bold("\n Sandbox Profiles:\n"));
7664
8075
  for (const p of profiles) {
7665
8076
  console.log(formatProfile(p));
7666
8077
  console.log("");
@@ -7669,35 +8080,35 @@ async function cmdProfiles() {
7669
8080
  async function cmdSandbox(command, options) {
7670
8081
  const result = checkCommand(command, process.cwd(), options.profile);
7671
8082
  if (result.allowed) {
7672
- console.log(chalk42.green(`
7673
- Allowed: ${chalk42.dim(command)}`));
8083
+ console.log(chalk43.green(`
8084
+ Allowed: ${chalk43.dim(command)}`));
7674
8085
  } else {
7675
- console.log(chalk42.red(`
7676
- Blocked: ${chalk42.dim(command)}`));
7677
- console.log(` ${chalk42.yellow(result.reason)}`);
8086
+ console.log(chalk43.red(`
8087
+ Blocked: ${chalk43.dim(command)}`));
8088
+ console.log(` ${chalk43.yellow(result.reason)}`);
7678
8089
  }
7679
8090
  }
7680
8091
  async function cmdPermissions(options) {
7681
8092
  if (options.set && options.action) {
7682
8093
  const defaults = ["fileRead", "fileWrite", "networkAccess", "commandExecution", "environmentAccess"];
7683
8094
  if (!defaults.includes(options.set)) {
7684
- console.log(chalk42.red(`Invalid default: ${options.set}. Options: ${defaults.join(", ")}`));
8095
+ console.log(chalk43.red(`Invalid default: ${options.set}. Options: ${defaults.join(", ")}`));
7685
8096
  return;
7686
8097
  }
7687
8098
  const perms = setDefault(options.set, options.action, options.dir);
7688
- console.log(chalk42.green(`Default "${options.set}" set to "${options.action}".`));
8099
+ console.log(chalk43.green(`Default "${options.set}" set to "${options.action}".`));
7689
8100
  console.log(formatPermissions(perms));
7690
8101
  } else if (options.add && options.action) {
7691
8102
  const action = options.action;
7692
8103
  const perms = addPermission(options.add, action, void 0, options.dir);
7693
- console.log(chalk42.green(`Permission added: ${options.add} \u2192 ${action}`));
8104
+ console.log(chalk43.green(`Permission added: ${options.add} \u2192 ${action}`));
7694
8105
  console.log(formatPermissions(perms));
7695
8106
  } else if (options.remove) {
7696
8107
  const ok = removePermission(options.remove, options.dir);
7697
- console.log(ok ? chalk42.green(`Removed permission: ${options.remove}`) : chalk42.yellow(`Permission not found: ${options.remove}`));
8108
+ console.log(ok ? chalk43.green(`Removed permission: ${options.remove}`) : chalk43.yellow(`Permission not found: ${options.remove}`));
7698
8109
  } else if (options.source) {
7699
8110
  addTrustedSource(options.source, options.dir);
7700
- console.log(chalk42.green(`Trusted source added: ${options.source}`));
8111
+ console.log(chalk43.green(`Trusted source added: ${options.source}`));
7701
8112
  } else {
7702
8113
  const perms = loadPermissions(options.dir);
7703
8114
  console.log(formatPermissions(perms));
@@ -7706,16 +8117,16 @@ async function cmdPermissions(options) {
7706
8117
  async function cmdCheckPermission(resource, options) {
7707
8118
  const category = options.category || "fileRead";
7708
8119
  const result = checkPermission(resource, category, options.dir);
7709
- const color = result === "allow" ? chalk42.green : result === "deny" ? chalk42.red : chalk42.yellow;
7710
- console.log(` ${color(result.toUpperCase())} ${chalk42.dim(resource)} (${category})`);
8120
+ const color = result === "allow" ? chalk43.green : result === "deny" ? chalk43.red : chalk43.yellow;
8121
+ console.log(` ${color(result.toUpperCase())} ${chalk43.dim(resource)} (${category})`);
7711
8122
  }
7712
8123
  async function cmdReset(options) {
7713
8124
  resetPermissions(options.dir);
7714
- console.log(chalk42.green("Permissions reset to defaults."));
8125
+ console.log(chalk43.green("Permissions reset to defaults."));
7715
8126
  }
7716
8127
  async function cmdRemoveSource(source, options) {
7717
8128
  const ok = removeTrustedSource(source, options.dir);
7718
- console.log(ok ? chalk42.green(`Removed trusted source: ${source}`) : chalk42.yellow(`Source not found: ${source}`));
8129
+ console.log(ok ? chalk43.green(`Removed trusted source: ${source}`) : chalk43.yellow(`Source not found: ${source}`));
7719
8130
  }
7720
8131
  var securityCommand = new Command16("security").alias("sec").alias("secure").description("Security tools: risk assessment, secret detection, sandbox, permissions").addHelpText("after", `
7721
8132
  Examples:
@@ -7750,7 +8161,7 @@ var pkg = {
7750
8161
  description: "Terminal-native autonomous coding agent powered by free AI models"
7751
8162
  };
7752
8163
  var program = new Command17();
7753
- program.name(pkg.name).description(chalk43.cyan(pkg.description)).version(pkg.version, "-v, --version", "Output the current version");
8164
+ program.name(pkg.name).description(chalk44.cyan(pkg.description)).version(pkg.version, "-v, --version", "Output the current version");
7754
8165
  program.addCommand(chatCommand);
7755
8166
  program.addCommand(runCommand);
7756
8167
  program.addCommand(initCommand);