jawere 1.6.1 → 1.7.0

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 +97 -28
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -14387,6 +14387,25 @@ async function decrypt(encoded) {
14387
14387
  }
14388
14388
  }
14389
14389
  var KEY_FILE = join(homedir(), ".jawere", "key.enc");
14390
+ var CONFIG_FILE = join(homedir(), ".jawere", "config.json");
14391
+ async function saveConfig(config) {
14392
+ const dir = join(homedir(), ".jawere");
14393
+ await mkdir2(dir, { recursive: true });
14394
+ await writeFile2(CONFIG_FILE, JSON.stringify(config, null, 2), "utf-8");
14395
+ try {
14396
+ await chmod(CONFIG_FILE, 384);
14397
+ } catch {
14398
+ }
14399
+ }
14400
+ async function loadSavedConfig() {
14401
+ try {
14402
+ await access2(CONFIG_FILE, constants2.R_OK);
14403
+ const raw = await readFile2(CONFIG_FILE, "utf-8");
14404
+ return JSON.parse(raw);
14405
+ } catch {
14406
+ return null;
14407
+ }
14408
+ }
14390
14409
  async function saveKey(apiKey) {
14391
14410
  const dir = join(homedir(), ".jawere");
14392
14411
  await mkdir2(dir, { recursive: true });
@@ -14410,16 +14429,13 @@ async function loadKey() {
14410
14429
  return null;
14411
14430
  }
14412
14431
  }
14413
- async function hasKey() {
14414
- try {
14415
- await access2(KEY_FILE, constants2.R_OK);
14416
- return true;
14417
- } catch {
14418
- return false;
14419
- }
14420
- }
14421
14432
 
14422
14433
  // src/config.ts
14434
+ var PROVIDER_DEFAULTS = {
14435
+ deepseek: { baseURL: "https://api.deepseek.com/v1", model: "deepseek-v4-pro" },
14436
+ openai: { baseURL: "https://api.openai.com/v1", model: "gpt-4o" },
14437
+ custom: { baseURL: "https://api.openai.com/v1", model: "gpt-4o" }
14438
+ };
14423
14439
  function isDevMode() {
14424
14440
  if (process.env.NODE_ENV === "production") return false;
14425
14441
  if (process.env.NODE_ENV === "development") return true;
@@ -14441,12 +14457,26 @@ async function loadConfig() {
14441
14457
  keyFromFile = true;
14442
14458
  } else if (process.env.DEEPSEEK_API_KEY) {
14443
14459
  apiKey = process.env.DEEPSEEK_API_KEY;
14460
+ } else if (process.env.OPENAI_API_KEY) {
14461
+ apiKey = process.env.OPENAI_API_KEY;
14462
+ } else if (process.env.AI_API_KEY) {
14463
+ apiKey = process.env.AI_API_KEY;
14464
+ }
14465
+ let savedConfig = null;
14466
+ try {
14467
+ savedConfig = await loadSavedConfig();
14468
+ } catch {
14444
14469
  }
14470
+ const provider = process.env.AI_PROVIDER || savedConfig?.provider || "deepseek";
14471
+ const defaults2 = PROVIDER_DEFAULTS[provider] || PROVIDER_DEFAULTS.deepseek;
14472
+ const baseURL = process.env.AI_BASE_URL || savedConfig?.baseURL || defaults2.baseURL;
14473
+ const model = process.env.AI_MODEL || savedConfig?.model || defaults2.model;
14445
14474
  const isDev = isDevMode();
14446
14475
  cachedConfig = {
14447
- baseURL: "https://api.deepseek.com/v1",
14476
+ baseURL,
14448
14477
  apiKey,
14449
- model: process.env.DEEPSEEK_MODEL || "deepseek-v4-pro",
14478
+ model,
14479
+ provider,
14450
14480
  workDir: process.env.WORK_DIR || process.cwd(),
14451
14481
  keyFromFile,
14452
14482
  isDev
@@ -14865,7 +14895,7 @@ async function runAgent(userMessage, options = {}) {
14865
14895
  const config = await loadConfig();
14866
14896
  if (!config.apiKey) {
14867
14897
  throw new Error(
14868
- "No API key configured. Run with --setup to save your DeepSeek API key, or set DEEPSEEK_API_KEY env var."
14898
+ 'No API key configured. Run "jawere --setup" to configure your AI provider and key, or set AI_API_KEY env var.'
14869
14899
  );
14870
14900
  }
14871
14901
  const client = new openai_default({
@@ -15708,6 +15738,7 @@ function createPrompt() {
15708
15738
  // src/index.ts
15709
15739
  var G_GREEN = "\x1B[38;2;184;187;3m";
15710
15740
  var G_GRAY2 = "\x1B[38;2;146;131;116m";
15741
+ var G_AQUA = "\x1B[38;2;142;192;124m";
15711
15742
  var R3 = "\x1B[0m";
15712
15743
  function center(text, width) {
15713
15744
  const visible = text.replace(/\x1b\[[0-9;]*m/g, "");
@@ -15718,7 +15749,7 @@ function printBanner(config) {
15718
15749
  const cols = process.stdout.columns || 60;
15719
15750
  const sep = G_GRAY2 + "\u2500".repeat(Math.min(cols - 2, 50)) + R3;
15720
15751
  console.log("");
15721
- console.log(center(`${G_GRAY2}${config.model}${R3} ${G_GRAY2}${config.isDev ? "dev" : "prod"}${R3}`, cols));
15752
+ console.log(center(`${G_GRAY2}${config.provider} / ${config.model}${R3} ${G_GRAY2}${config.isDev ? "dev" : "prod"}${R3}`, cols));
15722
15753
  console.log(center(sep, cols));
15723
15754
  console.log("");
15724
15755
  }
@@ -15728,29 +15759,69 @@ ${G_GREEN}Commands:${R3}
15728
15759
  ${G_GRAY2}/help${R3} Show this help
15729
15760
 
15730
15761
  ${G_GRAY2}/key${R3} Show API key status
15731
- ${G_GRAY2}/setup${R3} Re-enter API key
15762
+ ${G_GRAY2}/setup${R3} Re-configure AI provider & key
15732
15763
  ${G_GRAY2}/clear${R3} Clear screen & start fresh session
15733
15764
  ${G_GRAY2}/exit${R3}, ${G_GRAY2}/quit${R3} Quit
15765
+
15766
+ ${G_GREEN}CLI flags:${R3}
15767
+ ${G_GRAY2}--setup${R3} Run setup wizard (provider, key, model)
15734
15768
  `);
15735
15769
  }
15736
15770
  async function setupKey() {
15737
15771
  const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
15738
- console.log("\nEnter your DeepSeek API key (starts with sk-):");
15739
- const key = await new Promise((resolve4) => {
15740
- rl.question("API Key: ", (answer) => {
15772
+ const ask = (q2) => new Promise((resolve4) => rl.question(q2, (a2) => resolve4(a2.trim())));
15773
+ console.log("");
15774
+ console.log(`${G_GREEN}\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557${R3}`);
15775
+ console.log(`${G_GREEN}\u2551 jawere \u2014 Setup \u2551${R3}`);
15776
+ console.log(`${G_GREEN}\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D${R3}`);
15777
+ console.log("");
15778
+ console.log("Select AI provider:");
15779
+ console.log(` ${G_AQUA}1.${R3} DeepSeek`);
15780
+ console.log(` ${G_AQUA}2.${R3} OpenAI`);
15781
+ console.log(` ${G_AQUA}3.${R3} Custom (enter base URL)`);
15782
+ console.log("");
15783
+ const choice = await ask(`Choice [1]: `) || "1";
15784
+ let provider = "deepseek";
15785
+ let baseURL;
15786
+ let defaultModel;
15787
+ if (choice === "2") {
15788
+ provider = "openai";
15789
+ defaultModel = "gpt-4o";
15790
+ } else if (choice === "3") {
15791
+ provider = "custom";
15792
+ console.log("");
15793
+ baseURL = await ask("Base URL (e.g. https://api.openai.com/v1): ");
15794
+ if (!baseURL) {
15795
+ console.log("No URL entered. Aborting setup.");
15741
15796
  rl.close();
15742
- resolve4(answer.trim());
15743
- });
15744
- });
15797
+ return;
15798
+ }
15799
+ defaultModel = "gpt-4o";
15800
+ } else {
15801
+ provider = "deepseek";
15802
+ defaultModel = "deepseek-v4-pro";
15803
+ }
15804
+ console.log("");
15805
+ const keyHint = provider === "openai" ? "sk-" : provider === "deepseek" ? "sk-" : "";
15806
+ const hintText = keyHint ? ` (starts with ${keyHint})` : "";
15807
+ console.log(`Enter your API key${hintText}:`);
15808
+ const key = await ask("API Key: ");
15745
15809
  if (!key) {
15746
15810
  console.log("No key entered. Aborting setup.");
15811
+ rl.close();
15747
15812
  return;
15748
15813
  }
15749
- if (!key.startsWith("sk-")) {
15750
- console.log('Warning: Key does not start with "sk-". Saving anyway...');
15751
- }
15814
+ console.log("");
15815
+ const model = await ask(`Model [${defaultModel}]: `) || defaultModel;
15752
15816
  await saveKey(key);
15753
- console.log(`API key encrypted and saved to ~/.jawere/key.enc`);
15817
+ await saveConfig({ provider, baseURL: baseURL || void 0, model });
15818
+ console.log("");
15819
+ console.log(`${G_GREEN}Setup complete!${R3}`);
15820
+ console.log(` Provider : ${G_AQUA}${provider}${R3}`);
15821
+ console.log(` Model : ${G_AQUA}${model}${R3}`);
15822
+ console.log(` Key saved: ~/.jawere/key.enc`);
15823
+ console.log("");
15824
+ rl.close();
15754
15825
  }
15755
15826
  async function main() {
15756
15827
  const setupMode = process.argv.includes("--setup");
@@ -15761,16 +15832,14 @@ async function main() {
15761
15832
  process.exit(0);
15762
15833
  }
15763
15834
  if (!config.apiKey) {
15764
- const hasExistingKey = await hasKey();
15765
15835
  console.log("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557");
15766
- console.log("\u2551 jawere \u2014 AI Coding Agent \u2551");
15836
+ console.log("\u2551 jawere \u2014 AI Coding Agent \u2551");
15767
15837
  console.log("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563");
15768
15838
  console.log("\u2551 No API key found. \u2551");
15769
15839
  console.log("\u2551 \u2551");
15770
- console.log("\u2551 Option 1: Set DEEPSEEK_API_KEY env var \u2551");
15771
- console.log("\u2551 Option 2: Run --setup to encrypt & save \u2551");
15840
+ console.log("\u2551 Option 1: Set AI_API_KEY env var \u2551");
15841
+ console.log("\u2551 Option 2: Run jawere --setup \u2551");
15772
15842
  console.log("\u2551 \u2551");
15773
- console.log("\u2551 npx tsx src/index.ts --setup \u2551");
15774
15843
  console.log("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D");
15775
15844
  process.exit(1);
15776
15845
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jawere",
3
- "version": "1.6.1",
3
+ "version": "1.7.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "jawere": "bin/jawere.js"