open-agents-ai 0.2.0 → 0.3.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 +236 -43
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -225,6 +225,108 @@ var init_output = __esm({
225
225
  }
226
226
  });
227
227
 
228
+ // packages/cli/dist/updater.js
229
+ import { execSync } from "node:child_process";
230
+ import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
231
+ import { join as join2 } from "node:path";
232
+ import { homedir as homedir2 } from "node:os";
233
+ function parseVersion(v) {
234
+ const parts = v.replace(/^v/, "").split(".").map(Number);
235
+ return [parts[0] ?? 0, parts[1] ?? 0, parts[2] ?? 0];
236
+ }
237
+ function isNewer(latest, current) {
238
+ const [lMaj, lMin, lPat] = parseVersion(latest);
239
+ const [cMaj, cMin, cPat] = parseVersion(current);
240
+ if (lMaj !== cMaj)
241
+ return lMaj > cMaj;
242
+ if (lMin !== cMin)
243
+ return lMin > cMin;
244
+ return lPat > cPat;
245
+ }
246
+ function loadCache() {
247
+ try {
248
+ if (existsSync2(CACHE_FILE)) {
249
+ return JSON.parse(readFileSync2(CACHE_FILE, "utf8"));
250
+ }
251
+ } catch {
252
+ }
253
+ return { lastCheck: 0, latestVersion: null };
254
+ }
255
+ function saveCache(cache) {
256
+ try {
257
+ mkdirSync2(CACHE_DIR, { recursive: true });
258
+ writeFileSync2(CACHE_FILE, JSON.stringify(cache), "utf8");
259
+ } catch {
260
+ }
261
+ }
262
+ async function fetchLatestVersion() {
263
+ try {
264
+ const resp = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`, {
265
+ signal: AbortSignal.timeout(5e3),
266
+ headers: { Accept: "application/json" }
267
+ });
268
+ if (!resp.ok)
269
+ return null;
270
+ const data = await resp.json();
271
+ return data.version ?? null;
272
+ } catch {
273
+ return null;
274
+ }
275
+ }
276
+ async function checkForUpdate(currentVersion) {
277
+ const cache = loadCache();
278
+ const now = Date.now();
279
+ let latest = cache.latestVersion;
280
+ if (now - cache.lastCheck > CHECK_INTERVAL_MS) {
281
+ latest = await fetchLatestVersion();
282
+ saveCache({ lastCheck: now, latestVersion: latest });
283
+ }
284
+ if (!latest)
285
+ return null;
286
+ if (!isNewer(latest, currentVersion))
287
+ return null;
288
+ return {
289
+ updateAvailable: true,
290
+ currentVersion,
291
+ latestVersion: latest
292
+ };
293
+ }
294
+ function performUpdate() {
295
+ try {
296
+ execSync(`npm install -g ${PACKAGE_NAME}@latest`, {
297
+ stdio: "inherit",
298
+ timeout: 12e4
299
+ });
300
+ return true;
301
+ } catch {
302
+ return false;
303
+ }
304
+ }
305
+ function restartProcess() {
306
+ const args = process.argv.slice(1);
307
+ try {
308
+ execSync([process.execPath, ...args].map((a) => `"${a}"`).join(" "), { stdio: "inherit", timeout: 0 });
309
+ } catch {
310
+ }
311
+ process.exit(0);
312
+ }
313
+ function formatUpdateBanner(info) {
314
+ return `
315
+ Update available: v${info.currentVersion} \u2192 v${info.latestVersion}
316
+ Run: npm i -g ${PACKAGE_NAME} or use /update in the REPL
317
+ `;
318
+ }
319
+ var PACKAGE_NAME, CHECK_INTERVAL_MS, CACHE_DIR, CACHE_FILE;
320
+ var init_updater = __esm({
321
+ "packages/cli/dist/updater.js"() {
322
+ "use strict";
323
+ PACKAGE_NAME = "open-agents-ai";
324
+ CHECK_INTERVAL_MS = 60 * 60 * 1e3;
325
+ CACHE_DIR = join2(homedir2(), ".open-agents");
326
+ CACHE_FILE = join2(CACHE_DIR, "update-check.json");
327
+ }
328
+ });
329
+
228
330
  // packages/cli/dist/ui/spinner.js
229
331
  var FRAMES, INTERVAL_MS, Spinner;
230
332
  var init_spinner = __esm({
@@ -1626,7 +1728,7 @@ var init_file_edit = __esm({
1626
1728
 
1627
1729
  // packages/execution/dist/tools/memory-read.js
1628
1730
  import { readFile as readFile3 } from "node:fs/promises";
1629
- import { resolve as resolve6, join as join2 } from "node:path";
1731
+ import { resolve as resolve6, join as join3 } from "node:path";
1630
1732
  var MemoryReadTool;
1631
1733
  var init_memory_read = __esm({
1632
1734
  "packages/execution/dist/tools/memory-read.js"() {
@@ -1658,7 +1760,7 @@ var init_memory_read = __esm({
1658
1760
  const start = performance.now();
1659
1761
  try {
1660
1762
  const memoryDir = resolve6(this.workingDir, ".open-agents", "memory");
1661
- const topicFile = join2(memoryDir, `${topic}.json`);
1763
+ const topicFile = join3(memoryDir, `${topic}.json`);
1662
1764
  let raw;
1663
1765
  try {
1664
1766
  raw = await readFile3(topicFile, "utf-8");
@@ -1704,7 +1806,7 @@ var init_memory_read = __esm({
1704
1806
 
1705
1807
  // packages/execution/dist/tools/memory-write.js
1706
1808
  import { readFile as readFile4, writeFile as writeFile3, mkdir as mkdir2 } from "node:fs/promises";
1707
- import { resolve as resolve7, join as join3 } from "node:path";
1809
+ import { resolve as resolve7, join as join4 } from "node:path";
1708
1810
  var MemoryWriteTool;
1709
1811
  var init_memory_write = __esm({
1710
1812
  "packages/execution/dist/tools/memory-write.js"() {
@@ -1742,7 +1844,7 @@ var init_memory_write = __esm({
1742
1844
  try {
1743
1845
  const memoryDir = resolve7(this.workingDir, ".open-agents", "memory");
1744
1846
  await mkdir2(memoryDir, { recursive: true });
1745
- const topicFile = join3(memoryDir, `${topic}.json`);
1847
+ const topicFile = join4(memoryDir, `${topic}.json`);
1746
1848
  let entries = {};
1747
1849
  try {
1748
1850
  const raw = await readFile4(topicFile, "utf-8");
@@ -1774,7 +1876,7 @@ var init_memory_write = __esm({
1774
1876
 
1775
1877
  // packages/execution/dist/tools/list-directory.js
1776
1878
  import { readdirSync, statSync } from "node:fs";
1777
- import { resolve as resolve8, join as join4 } from "node:path";
1879
+ import { resolve as resolve8, join as join5 } from "node:path";
1778
1880
  var EXCLUDED, MAX_ENTRIES, ListDirectoryTool;
1779
1881
  var init_list_directory = __esm({
1780
1882
  "packages/execution/dist/tools/list-directory.js"() {
@@ -1813,7 +1915,7 @@ var init_list_directory = __esm({
1813
1915
  }
1814
1916
  let size = 0;
1815
1917
  try {
1816
- size = statSync(join4(fullPath, entry.name)).size;
1918
+ size = statSync(join5(fullPath, entry.name)).size;
1817
1919
  } catch {
1818
1920
  }
1819
1921
  return `${prefix} ${entry.name} ${size}`;
@@ -3057,7 +3159,7 @@ var init_code_retriever = __esm({
3057
3159
  import { execFile as execFile5 } from "node:child_process";
3058
3160
  import { promisify as promisify5 } from "node:util";
3059
3161
  import { readFile as readFile5, readdir, stat } from "node:fs/promises";
3060
- import { join as join5, extname } from "node:path";
3162
+ import { join as join6, extname } from "node:path";
3061
3163
  async function searchByPath(pathPattern, options) {
3062
3164
  const allFiles = await collectFiles(options.rootDir, options.includeGlobs ?? DEFAULT_INCLUDE_GLOBS, options.excludeGlobs ?? DEFAULT_EXCLUDE_GLOBS);
3063
3165
  const pattern = options.caseInsensitive ? pathPattern.toLowerCase() : pathPattern;
@@ -3199,7 +3301,7 @@ async function walkForFiles(rootDir, dir, excludeGlobs, results) {
3199
3301
  continue;
3200
3302
  if (excludeGlobs.some((g) => entry.name === g || matchesGlob(entry.name, g)))
3201
3303
  continue;
3202
- const absPath = join5(dir, entry.name);
3304
+ const absPath = join6(dir, entry.name);
3203
3305
  if (entry.isDirectory()) {
3204
3306
  await walkForFiles(rootDir, absPath, excludeGlobs, results);
3205
3307
  } else if (entry.isFile()) {
@@ -3374,7 +3476,7 @@ var init_graphExpand = __esm({
3374
3476
 
3375
3477
  // packages/retrieval/dist/snippetPacker.js
3376
3478
  import { readFile as readFile6 } from "node:fs/promises";
3377
- import { join as join6 } from "node:path";
3479
+ import { join as join7 } from "node:path";
3378
3480
  async function packSnippets(requests, opts = {}) {
3379
3481
  const maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;
3380
3482
  const contextLines = opts.contextLines ?? DEFAULT_CONTEXT_LINES;
@@ -3400,7 +3502,7 @@ async function packSnippets(requests, opts = {}) {
3400
3502
  return { packed, dropped, totalTokens };
3401
3503
  }
3402
3504
  async function extractSnippet(req, repoRoot, contextLines = DEFAULT_CONTEXT_LINES) {
3403
- const absPath = req.filePath.startsWith("/") ? req.filePath : join6(repoRoot, req.filePath);
3505
+ const absPath = req.filePath.startsWith("/") ? req.filePath : join7(repoRoot, req.filePath);
3404
3506
  let content;
3405
3507
  try {
3406
3508
  content = await readFile6(absPath, "utf-8");
@@ -5073,6 +5175,7 @@ function renderSlashHelp() {
5073
5175
  ["/endpoint <url>", "Set backend URL (auto-detects type)"],
5074
5176
  ["/endpoint <url> --auth <t>", "Set endpoint with Bearer auth"],
5075
5177
  ["/config", "Show current configuration"],
5178
+ ["/update", "Check for updates and auto-install"],
5076
5179
  ["/verbose", "Toggle verbose mode"],
5077
5180
  ["/clear", "Clear the screen"],
5078
5181
  ["/help", "Show this help"],
@@ -5267,6 +5370,10 @@ async function handleSlashCommand(input, ctx) {
5267
5370
  case "ep":
5268
5371
  await handleEndpoint(arg, ctx);
5269
5372
  return "handled";
5373
+ case "update":
5374
+ case "upgrade":
5375
+ await handleUpdate();
5376
+ return "handled";
5270
5377
  default:
5271
5378
  renderWarning(`Unknown command: /${cmd}. Type /help for available commands.`);
5272
5379
  return "handled";
@@ -5376,6 +5483,44 @@ async function handleEndpoint(arg, ctx) {
5376
5483
  }
5377
5484
  process.stdout.write("\n");
5378
5485
  }
5486
+ async function handleUpdate() {
5487
+ let currentVersion = "0.0.0";
5488
+ try {
5489
+ const { createRequire: createRequire2 } = await import("node:module");
5490
+ const { fileURLToPath: fileURLToPath2 } = await import("node:url");
5491
+ const { dirname: dirname3, join: join13 } = await import("node:path");
5492
+ const require2 = createRequire2(import.meta.url);
5493
+ const pkgPath = join13(dirname3(fileURLToPath2(import.meta.url)), "..", "package.json");
5494
+ const pkg = require2(pkgPath);
5495
+ currentVersion = pkg.version ?? "0.0.0";
5496
+ } catch {
5497
+ }
5498
+ process.stdout.write(`
5499
+ ${c2.cyan("\u25CF")} Checking for updates...
5500
+ `);
5501
+ const info = await checkForUpdate(currentVersion);
5502
+ if (!info) {
5503
+ process.stdout.write(` ${c2.green("\u2714")} You're on the latest version (v${currentVersion}).
5504
+
5505
+ `);
5506
+ return;
5507
+ }
5508
+ process.stdout.write(` ${c2.yellow("\u26A0")} Update available: v${info.currentVersion} \u2192 v${c2.bold(c2.green(info.latestVersion))}
5509
+ `);
5510
+ process.stdout.write(` ${c2.cyan("\u25CF")} Installing update...
5511
+
5512
+ `);
5513
+ const success = performUpdate();
5514
+ if (!success) {
5515
+ renderError("Update failed. Try manually: npm i -g open-agents-ai");
5516
+ return;
5517
+ }
5518
+ process.stdout.write(`
5519
+ ${c2.green("\u2714")} Updated to v${info.latestVersion}. Restarting...
5520
+
5521
+ `);
5522
+ restartProcess();
5523
+ }
5379
5524
  async function switchModel(query, ctx) {
5380
5525
  try {
5381
5526
  const models = await fetchOllamaModels(ctx.config.backendUrl);
@@ -5401,22 +5546,23 @@ var init_commands = __esm({
5401
5546
  init_model_picker();
5402
5547
  init_render();
5403
5548
  init_config();
5549
+ init_updater();
5404
5550
  }
5405
5551
  });
5406
5552
 
5407
5553
  // packages/cli/dist/tui/setup.js
5408
5554
  import * as readline from "node:readline";
5409
- import { execSync } from "node:child_process";
5410
- import { existsSync as existsSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
5411
- import { join as join7 } from "node:path";
5412
- import { homedir as homedir2 } from "node:os";
5555
+ import { execSync as execSync2 } from "node:child_process";
5556
+ import { existsSync as existsSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "node:fs";
5557
+ import { join as join8 } from "node:path";
5558
+ import { homedir as homedir3 } from "node:os";
5413
5559
  function detectSystemSpecs() {
5414
5560
  let totalRamGB = 0;
5415
5561
  let availableRamGB = 0;
5416
5562
  let gpuVramGB = 0;
5417
5563
  let gpuName = "";
5418
5564
  try {
5419
- const memInfo = execSync("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
5565
+ const memInfo = execSync2("free -b 2>/dev/null || sysctl -n hw.memsize 2>/dev/null", {
5420
5566
  encoding: "utf8",
5421
5567
  timeout: 5e3
5422
5568
  });
@@ -5436,7 +5582,7 @@ function detectSystemSpecs() {
5436
5582
  } catch {
5437
5583
  }
5438
5584
  try {
5439
- const nvidiaSmi = execSync("nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
5585
+ const nvidiaSmi = execSync2("nvidia-smi --query-gpu=memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 5e3 });
5440
5586
  const lines = nvidiaSmi.trim().split("\n");
5441
5587
  if (lines.length > 0) {
5442
5588
  for (const line of lines) {
@@ -5496,6 +5642,52 @@ function ask(rl, question) {
5496
5642
  rl.question(question, (answer) => resolve11(answer.trim()));
5497
5643
  });
5498
5644
  }
5645
+ function pullModelWithAutoUpdate(tag) {
5646
+ try {
5647
+ execSync2(`ollama pull ${tag}`, {
5648
+ stdio: "inherit",
5649
+ timeout: 36e5
5650
+ // 1 hour max
5651
+ });
5652
+ } catch (err) {
5653
+ const errMsg = err instanceof Error ? err.message : String(err);
5654
+ const stderr = err?.stderr?.toString?.() ?? errMsg;
5655
+ const combined = errMsg + "\n" + stderr;
5656
+ if (combined.includes("412") || combined.includes("newer version") || combined.includes("requires a newer version")) {
5657
+ process.stdout.write(`
5658
+ ${c2.yellow("\u26A0")} Ollama needs to be updated for this model.
5659
+ `);
5660
+ process.stdout.write(` ${c2.cyan("\u25CF")} Updating Ollama via official install script...
5661
+
5662
+ `);
5663
+ try {
5664
+ execSync2("curl -fsSL https://ollama.com/install.sh | sh", {
5665
+ stdio: "inherit",
5666
+ timeout: 3e5
5667
+ // 5 min max for install
5668
+ });
5669
+ process.stdout.write(`
5670
+ ${c2.green("\u2714")} Ollama updated successfully.
5671
+ `);
5672
+ process.stdout.write(` ${c2.cyan("\u25CF")} Retrying pull of ${c2.bold(tag)}...
5673
+
5674
+ `);
5675
+ execSync2(`ollama pull ${tag}`, {
5676
+ stdio: "inherit",
5677
+ timeout: 36e5
5678
+ });
5679
+ } catch (updateErr) {
5680
+ const updateMsg = updateErr instanceof Error ? updateErr.message : String(updateErr);
5681
+ throw new Error(`Failed to update Ollama and retry pull: ${updateMsg}
5682
+ Try manually:
5683
+ curl -fsSL https://ollama.com/install.sh | sh
5684
+ ollama pull ${tag}`);
5685
+ }
5686
+ } else {
5687
+ throw err;
5688
+ }
5689
+ }
5690
+ }
5499
5691
  async function runSetupWizard(config) {
5500
5692
  const rl = readline.createInterface({
5501
5693
  input: process.stdin,
@@ -5630,11 +5822,7 @@ async function doSetup(config, rl) {
5630
5822
  ${c2.cyan("\u25CF")} Pulling ${c2.bold(selectedVariant.tag)}... (this may take a while)
5631
5823
  `);
5632
5824
  try {
5633
- execSync(`ollama pull ${selectedVariant.tag}`, {
5634
- stdio: "inherit",
5635
- timeout: 36e5
5636
- // 1 hour max
5637
- });
5825
+ pullModelWithAutoUpdate(selectedVariant.tag);
5638
5826
  process.stdout.write(`
5639
5827
  ${c2.green("\u2714")} Model ${c2.bold(selectedVariant.tag)} pulled successfully.
5640
5828
 
@@ -5662,12 +5850,12 @@ async function doSetup(config, rl) {
5662
5850
  `PARAMETER num_predict 16384`,
5663
5851
  `PARAMETER stop "<|endoftext|>"`
5664
5852
  ].join("\n");
5665
- const modelDir = join7(homedir2(), ".open-agents", "models");
5666
- mkdirSync2(modelDir, { recursive: true });
5667
- const modelfilePath = join7(modelDir, `Modelfile.${customName}`);
5668
- writeFileSync2(modelfilePath, modelfileContent + "\n", "utf8");
5853
+ const modelDir = join8(homedir3(), ".open-agents", "models");
5854
+ mkdirSync3(modelDir, { recursive: true });
5855
+ const modelfilePath = join8(modelDir, `Modelfile.${customName}`);
5856
+ writeFileSync3(modelfilePath, modelfileContent + "\n", "utf8");
5669
5857
  process.stdout.write(` ${c2.dim("Creating model...")} `);
5670
- execSync(`ollama create ${customName} -f ${modelfilePath}`, {
5858
+ execSync2(`ollama create ${customName} -f ${modelfilePath}`, {
5671
5859
  stdio: "pipe",
5672
5860
  timeout: 12e4
5673
5861
  });
@@ -5710,7 +5898,7 @@ async function isModelAvailable(config) {
5710
5898
  }
5711
5899
  function isFirstRun() {
5712
5900
  try {
5713
- return !existsSync2(join7(homedir2(), ".open-agents", "config.json"));
5901
+ return !existsSync3(join8(homedir3(), ".open-agents", "config.json"));
5714
5902
  } catch {
5715
5903
  return true;
5716
5904
  }
@@ -6010,7 +6198,7 @@ import { glob } from "glob";
6010
6198
  import ignore from "ignore";
6011
6199
  import { readFile as readFile7, stat as stat2 } from "node:fs/promises";
6012
6200
  import { createHash } from "node:crypto";
6013
- import { join as join8, relative, extname as extname2, basename } from "node:path";
6201
+ import { join as join9, relative, extname as extname2, basename } from "node:path";
6014
6202
  var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
6015
6203
  var init_codebase_indexer = __esm({
6016
6204
  "packages/indexer/dist/codebase-indexer.js"() {
@@ -6054,7 +6242,7 @@ var init_codebase_indexer = __esm({
6054
6242
  const ig = ignore.default();
6055
6243
  if (this.config.respectGitignore) {
6056
6244
  try {
6057
- const gitignoreContent = await readFile7(join8(this.config.rootDir, ".gitignore"), "utf-8");
6245
+ const gitignoreContent = await readFile7(join9(this.config.rootDir, ".gitignore"), "utf-8");
6058
6246
  ig.add(gitignoreContent);
6059
6247
  } catch {
6060
6248
  }
@@ -6069,7 +6257,7 @@ var init_codebase_indexer = __esm({
6069
6257
  for (const relativePath of files) {
6070
6258
  if (ig.ignores(relativePath))
6071
6259
  continue;
6072
- const fullPath = join8(this.config.rootDir, relativePath);
6260
+ const fullPath = join9(this.config.rootDir, relativePath);
6073
6261
  try {
6074
6262
  const fileStat = await stat2(fullPath);
6075
6263
  if (fileStat.size > this.config.maxFileSize)
@@ -6115,7 +6303,7 @@ var init_codebase_indexer = __esm({
6115
6303
  if (!child) {
6116
6304
  child = {
6117
6305
  name: part,
6118
- path: join8(current.path, part),
6306
+ path: join9(current.path, part),
6119
6307
  type: "directory",
6120
6308
  children: []
6121
6309
  };
@@ -6190,13 +6378,13 @@ __export(index_repo_exports, {
6190
6378
  indexRepoCommand: () => indexRepoCommand
6191
6379
  });
6192
6380
  import { resolve as resolve10 } from "node:path";
6193
- import { existsSync as existsSync3, statSync as statSync2 } from "node:fs";
6381
+ import { existsSync as existsSync4, statSync as statSync2 } from "node:fs";
6194
6382
  import { cwd as cwd2 } from "node:process";
6195
6383
  async function indexRepoCommand(opts, _config) {
6196
6384
  const repoRoot = resolve10(opts.repoPath ?? cwd2());
6197
6385
  printHeader("Index Repository");
6198
6386
  printInfo(`Indexing: ${repoRoot}`);
6199
- if (!existsSync3(repoRoot)) {
6387
+ if (!existsSync4(repoRoot)) {
6200
6388
  printError(`Path does not exist: ${repoRoot}`);
6201
6389
  process.exit(1);
6202
6390
  }
@@ -6442,8 +6630,8 @@ var config_exports = {};
6442
6630
  __export(config_exports, {
6443
6631
  configCommand: () => configCommand
6444
6632
  });
6445
- import { join as join9 } from "node:path";
6446
- import { homedir as homedir3 } from "node:os";
6633
+ import { join as join10 } from "node:path";
6634
+ import { homedir as homedir4 } from "node:os";
6447
6635
  async function configCommand(opts, config) {
6448
6636
  if (opts.subCommand === "set") {
6449
6637
  return handleSet(opts, config);
@@ -6465,7 +6653,7 @@ function handleShow(opts, config) {
6465
6653
  printKeyValue("verbose", String(config.verbose), 2);
6466
6654
  printKeyValue("dbPath", config.dbPath, 2);
6467
6655
  printSection("Config File");
6468
- printInfo(`~/.open-agents/config.json (${join9(homedir3(), ".open-agents", "config.json")})`);
6656
+ printInfo(`~/.open-agents/config.json (${join10(homedir4(), ".open-agents", "config.json")})`);
6469
6657
  printSection("Environment Variables");
6470
6658
  printInfo("OPEN_AGENTS_BACKEND_URL \u2014 override backendUrl");
6471
6659
  printInfo("OPEN_AGENTS_MODEL \u2014 override model");
@@ -6697,8 +6885,8 @@ __export(eval_exports, {
6697
6885
  evalCommand: () => evalCommand
6698
6886
  });
6699
6887
  import { tmpdir } from "node:os";
6700
- import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "node:fs";
6701
- import { join as join10 } from "node:path";
6888
+ import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "node:fs";
6889
+ import { join as join11 } from "node:path";
6702
6890
  async function evalCommand(opts, config) {
6703
6891
  const suiteName = opts.suite ?? "basic";
6704
6892
  const suite = SUITES[suiteName];
@@ -6819,9 +7007,9 @@ async function evalCommand(opts, config) {
6819
7007
  process.exit(failed > 0 ? 1 : 0);
6820
7008
  }
6821
7009
  function createTempEvalRepo() {
6822
- const dir = join10(tmpdir(), `open-agents-eval-${Date.now()}`);
6823
- mkdirSync3(dir, { recursive: true });
6824
- writeFileSync3(join10(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
7010
+ const dir = join11(tmpdir(), `open-agents-eval-${Date.now()}`);
7011
+ mkdirSync4(dir, { recursive: true });
7012
+ writeFileSync4(join11(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
6825
7013
  return dir;
6826
7014
  }
6827
7015
  var BASIC_SUITE, FULL_SUITE, SUITES;
@@ -6877,10 +7065,11 @@ var init_eval = __esm({
6877
7065
  // packages/cli/dist/index.js
6878
7066
  init_config();
6879
7067
  init_output();
7068
+ init_updater();
6880
7069
  import { parseArgs as nodeParseArgs2 } from "node:util";
6881
7070
  import { createRequire } from "node:module";
6882
7071
  import { fileURLToPath } from "node:url";
6883
- import { dirname as dirname2, join as join11 } from "node:path";
7072
+ import { dirname as dirname2, join as join12 } from "node:path";
6884
7073
 
6885
7074
  // packages/cli/dist/cli.js
6886
7075
  import { createInterface } from "node:readline";
@@ -6987,7 +7176,7 @@ init_output();
6987
7176
  function getVersion() {
6988
7177
  try {
6989
7178
  const require2 = createRequire(import.meta.url);
6990
- const pkgPath = join11(dirname2(fileURLToPath(import.meta.url)), "..", "package.json");
7179
+ const pkgPath = join12(dirname2(fileURLToPath(import.meta.url)), "..", "package.json");
6991
7180
  const pkg = require2(pkgPath);
6992
7181
  return pkg.version;
6993
7182
  } catch {
@@ -7142,6 +7331,10 @@ async function main() {
7142
7331
  printHelp2(version);
7143
7332
  return;
7144
7333
  }
7334
+ const updateInfo = await checkForUpdate(version);
7335
+ if (updateInfo) {
7336
+ process.stderr.write(formatUpdateBanner(updateInfo));
7337
+ }
7145
7338
  const baseConfig = loadConfig();
7146
7339
  const config = mergeConfig(baseConfig, {
7147
7340
  ...parsed.model ? { model: parsed.model } : {},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — Claude Code-style TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",