open-agents-ai 0.34.3 → 0.34.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +79 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -90,7 +90,7 @@ function setConfigValue(key, value) {
90
90
  const configPath = join(dir, "config.json");
91
91
  const existing = loadConfigFile();
92
92
  existing[key] = coerceConfigValue(key, value);
93
- writeFileSync(configPath, JSON.stringify(existing, null, 2) + "\n", "utf8");
93
+ writeFileSync(configPath, JSON.stringify(existing, null, 2) + "\n", { encoding: "utf8", mode: 384 });
94
94
  }
95
95
  function coerceConfigValue(key, value) {
96
96
  const intKeys = /* @__PURE__ */ new Set(["maxRetries", "timeoutMs"]);
@@ -16181,6 +16181,17 @@ function initOaDirectory(repoRoot) {
16181
16181
  for (const sub of SUBDIRS) {
16182
16182
  mkdirSync6(join25(oaPath, sub), { recursive: true });
16183
16183
  }
16184
+ try {
16185
+ const gitignorePath = join25(repoRoot, ".gitignore");
16186
+ const settingsPattern = ".oa/settings.json";
16187
+ if (existsSync19(gitignorePath)) {
16188
+ const content = readFileSync13(gitignorePath, "utf-8");
16189
+ if (!content.includes(settingsPattern)) {
16190
+ writeFileSync6(gitignorePath, content.trimEnd() + "\n" + settingsPattern + "\n", "utf-8");
16191
+ }
16192
+ }
16193
+ } catch {
16194
+ }
16184
16195
  return oaPath;
16185
16196
  }
16186
16197
  function hasOaDirectory(repoRoot) {
@@ -16201,7 +16212,7 @@ function saveProjectSettings(repoRoot, settings) {
16201
16212
  mkdirSync6(oaPath, { recursive: true });
16202
16213
  const existing = loadProjectSettings(repoRoot);
16203
16214
  const merged = { ...existing, ...settings };
16204
- writeFileSync6(join25(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", "utf-8");
16215
+ writeFileSync6(join25(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
16205
16216
  }
16206
16217
  function loadGlobalSettings() {
16207
16218
  const settingsPath = join25(homedir9(), ".open-agents", "settings.json");
@@ -16218,7 +16229,7 @@ function saveGlobalSettings(settings) {
16218
16229
  mkdirSync6(dir, { recursive: true });
16219
16230
  const existing = loadGlobalSettings();
16220
16231
  const merged = { ...existing, ...settings };
16221
- writeFileSync6(join25(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", "utf-8");
16232
+ writeFileSync6(join25(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
16222
16233
  }
16223
16234
  function resolveSettings(repoRoot) {
16224
16235
  const global = loadGlobalSettings();
@@ -16670,6 +16681,49 @@ function ask(rl, question) {
16670
16681
  rl.question(question, (answer) => resolve23(answer.trim()));
16671
16682
  });
16672
16683
  }
16684
+ function askSecret(rl, question) {
16685
+ return new Promise((resolve23) => {
16686
+ process.stdout.write(question);
16687
+ let secret = "";
16688
+ const stdin = process.stdin;
16689
+ const hadRawMode = stdin.isRaw;
16690
+ if (typeof stdin.setRawMode === "function") {
16691
+ stdin.setRawMode(true);
16692
+ }
16693
+ stdin.resume();
16694
+ const onData = (chunk) => {
16695
+ const ch = chunk.toString("utf8");
16696
+ for (const c3 of ch) {
16697
+ if (c3 === "\r" || c3 === "\n") {
16698
+ stdin.removeListener("data", onData);
16699
+ if (typeof stdin.setRawMode === "function") {
16700
+ stdin.setRawMode(hadRawMode ?? false);
16701
+ }
16702
+ process.stdout.write("\n");
16703
+ resolve23(secret.trim());
16704
+ return;
16705
+ } else if (c3 === "") {
16706
+ stdin.removeListener("data", onData);
16707
+ if (typeof stdin.setRawMode === "function") {
16708
+ stdin.setRawMode(hadRawMode ?? false);
16709
+ }
16710
+ process.stdout.write("\n");
16711
+ resolve23("");
16712
+ return;
16713
+ } else if (c3 === "\x7F" || c3 === "\b") {
16714
+ if (secret.length > 0) {
16715
+ secret = secret.slice(0, -1);
16716
+ process.stdout.write("\b \b");
16717
+ }
16718
+ } else if (c3.charCodeAt(0) >= 32) {
16719
+ secret += c3;
16720
+ process.stdout.write("*");
16721
+ }
16722
+ }
16723
+ };
16724
+ stdin.on("data", onData);
16725
+ });
16726
+ }
16673
16727
  async function autoInstallOllama(rl) {
16674
16728
  const plat = platform();
16675
16729
  if (plat === "linux") {
@@ -16899,7 +16953,7 @@ async function promptForCustomEndpoint(config, rl) {
16899
16953
  ${c2.bold("Does this endpoint require an API key?")} (y/n) `);
16900
16954
  let apiKey = "";
16901
16955
  if (needsKey.toLowerCase() === "y" || needsKey.toLowerCase() === "yes") {
16902
- apiKey = await ask(rl, ` ${c2.bold("API key:")} `);
16956
+ apiKey = await askSecret(rl, ` ${c2.bold("API key:")} `);
16903
16957
  }
16904
16958
  process.stdout.write(`
16905
16959
  ${c2.cyan("\u25CF")} Enter the model name for this endpoint.
@@ -18353,7 +18407,7 @@ async function handleEndpoint(arg, ctx, local = false) {
18353
18407
  process.stdout.write(` ${c2.cyan("Type".padEnd(12))} ${backendType}
18354
18408
  `);
18355
18409
  if (apiKey) {
18356
- process.stdout.write(` ${c2.cyan("Auth".padEnd(12))} Bearer ${apiKey.slice(0, 8)}...
18410
+ process.stdout.write(` ${c2.cyan("Auth".padEnd(12))} Bearer ${apiKey.slice(0, 4)}...
18357
18411
  `);
18358
18412
  } else {
18359
18413
  process.stdout.write(` ${c2.cyan("Auth".padEnd(12))} ${provider.authRequired ? c2.yellow("none (may be required)") : "none"}
@@ -24654,12 +24708,18 @@ async function statusCommand(opts, config) {
24654
24708
  "OPEN_AGENTS_TIMEOUT_MS",
24655
24709
  "OPEN_AGENTS_DRY_RUN",
24656
24710
  "OPEN_AGENTS_VERBOSE",
24657
- "VLLM_BASE_URL"
24711
+ "VLLM_BASE_URL",
24712
+ "VLLM_API_KEY"
24658
24713
  ];
24714
+ const sensitiveEnvVars = /* @__PURE__ */ new Set([
24715
+ "OPEN_AGENTS_API_KEY",
24716
+ "VLLM_API_KEY"
24717
+ ]);
24659
24718
  for (const key of envVars) {
24660
24719
  const val = process.env[key];
24661
24720
  if (val !== void 0) {
24662
- printKeyValue(key, val.includes("key") || val.includes("KEY") ? "[redacted]" : val, 2);
24721
+ const display = sensitiveEnvVars.has(key) ? val.length > 4 ? `[set \u2014 ${val.slice(0, 4)}...]` : val.length > 0 ? "[set]" : "[empty]" : val;
24722
+ printKeyValue(key, display, 2);
24663
24723
  }
24664
24724
  }
24665
24725
  }
@@ -24777,6 +24837,12 @@ __export(config_exports, {
24777
24837
  import { join as join34, resolve as resolve22 } from "node:path";
24778
24838
  import { homedir as homedir13 } from "node:os";
24779
24839
  import { cwd as cwd3 } from "node:process";
24840
+ function redactIfSensitive(key, value) {
24841
+ if (SENSITIVE_KEYS.has(key) && typeof value === "string" && value.length > 0) {
24842
+ return value.length > 4 ? `[set \u2014 ${value.slice(0, 4)}...]` : "[set]";
24843
+ }
24844
+ return String(value);
24845
+ }
24780
24846
  function coerceForSettings(key, value) {
24781
24847
  if (INT_KEYS.has(key))
24782
24848
  return parseInt(value, 10);
@@ -24812,7 +24878,7 @@ function handleShow(opts, config) {
24812
24878
  if (projectKeys.length > 0) {
24813
24879
  printSection(`Project Overrides (.oa/settings.json)`);
24814
24880
  for (const [k, v] of projectKeys) {
24815
- printKeyValue(k, String(v), 2);
24881
+ printKeyValue(k, redactIfSensitive(k, v), 2);
24816
24882
  }
24817
24883
  } else {
24818
24884
  printSection("Project Overrides");
@@ -24823,7 +24889,7 @@ function handleShow(opts, config) {
24823
24889
  if (globalKeys.length > 0) {
24824
24890
  printSection("Global Settings (~/.open-agents/settings.json)");
24825
24891
  for (const [k, v] of globalKeys) {
24826
- printKeyValue(k, String(v), 2);
24892
+ printKeyValue(k, redactIfSensitive(k, v), 2);
24827
24893
  }
24828
24894
  }
24829
24895
  printSection("Config File");
@@ -24865,7 +24931,7 @@ function handleSet(opts, _config) {
24865
24931
  initOaDirectory(repoRoot);
24866
24932
  const coerced = coerceForSettings(key, value);
24867
24933
  saveProjectSettings(repoRoot, { [key]: coerced });
24868
- printSuccess(`Project override set: ${key} = ${value}`);
24934
+ printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
24869
24935
  printInfo(`Saved to ${join34(repoRoot, ".oa", "settings.json")}`);
24870
24936
  printInfo("This override applies only when running in this workspace.");
24871
24937
  } catch (err) {
@@ -24875,7 +24941,7 @@ function handleSet(opts, _config) {
24875
24941
  } else {
24876
24942
  try {
24877
24943
  setConfigValue(key, value);
24878
- printSuccess(`Config updated: ${key} = ${value}`);
24944
+ printSuccess(`Config updated: ${key} = ${redactIfSensitive(key, value)}`);
24879
24945
  printInfo(`Saved to ~/.open-agents/config.json`);
24880
24946
  printInfo("Tip: Use --local to set project-specific overrides.");
24881
24947
  } catch (err) {
@@ -24894,7 +24960,7 @@ function handleKeys() {
24894
24960
  printInfo(" oa config set model qwen3.5:122b # global default");
24895
24961
  printInfo(" oa config set model qwen3.5:122b --local # this project only");
24896
24962
  }
24897
- var CONFIG_KEYS, INT_KEYS, BOOL_KEYS;
24963
+ var CONFIG_KEYS, SENSITIVE_KEYS, INT_KEYS, BOOL_KEYS;
24898
24964
  var init_config3 = __esm({
24899
24965
  "packages/cli/dist/commands/config.js"() {
24900
24966
  "use strict";
@@ -24916,6 +24982,7 @@ var init_config3 = __esm({
24916
24982
  stream: "Enable real-time token streaming with pastel syntax highlighting (true/false)",
24917
24983
  bruteforce: "Brute-force mode: auto re-engage agent when turn limit hit (true/false)"
24918
24984
  };
24985
+ SENSITIVE_KEYS = /* @__PURE__ */ new Set(["apiKey", "api_key", "secret", "password", "token"]);
24919
24986
  INT_KEYS = /* @__PURE__ */ new Set(["maxRetries", "timeoutMs"]);
24920
24987
  BOOL_KEYS = /* @__PURE__ */ new Set(["dryRun", "verbose", "voice", "stream", "bruteforce"]);
24921
24988
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.34.3",
3
+ "version": "0.34.4",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",