omo-suites 1.5.2 → 1.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,18 @@ All notable changes to OMO Suites will be documented in this file.
5
5
  Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
  This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.5.4] - 2026-03-07
9
+
10
+ ### Added
11
+ - Auto-update on every CLI run — checks npm for new version, updates automatically
12
+ - 5-minute cooldown between checks to avoid spamming npm registry
13
+ - Disable with `OMOCS_NO_UPDATE=1` env var
14
+
15
+ ## [1.5.3] - 2026-03-07
16
+
17
+ ### Fixed
18
+ - `omocs doctor` now detects installed tools on Windows (was using `which` instead of `where`)
19
+
8
20
  ## [1.5.2] - 2026-03-07
9
21
 
10
22
  ### Fixed
package/dist/cli/omocs.js CHANGED
@@ -625,8 +625,8 @@ var init_utils = __esm(() => {
625
625
  });
626
626
 
627
627
  // src/tui/renderer.ts
628
- import { readFileSync } from "fs";
629
- import { dirname, resolve } from "path";
628
+ import { readFileSync as readFileSync2 } from "fs";
629
+ import { dirname, resolve as resolve2 } from "path";
630
630
  import { fileURLToPath } from "url";
631
631
  function renderScreen(ctx) {
632
632
  const { cols, rows } = getTerminalSize();
@@ -767,7 +767,7 @@ var init_renderer = __esm(() => {
767
767
  init_utils();
768
768
  __pkgDir = dirname(dirname(fileURLToPath(import.meta.url)));
769
769
  try {
770
- const pkg = JSON.parse(readFileSync(resolve(__pkgDir, "package.json"), "utf-8"));
770
+ const pkg = JSON.parse(readFileSync2(resolve2(__pkgDir, "package.json"), "utf-8"));
771
771
  VERSION = pkg.version;
772
772
  } catch {}
773
773
  MENU_ITEMS = ["Profile", "Agents", "MCP", "LSP", "Doctor", "Stats", "Launchboard"];
@@ -1248,9 +1248,9 @@ var init_profiles = __esm(() => {
1248
1248
  });
1249
1249
 
1250
1250
  // src/core/config.ts
1251
- import { mkdirSync, existsSync, readFileSync as readFileSync2, writeFileSync } from "fs";
1251
+ import { mkdirSync as mkdirSync2, existsSync as existsSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
1252
1252
  import { join } from "path";
1253
- import { homedir } from "os";
1253
+ import { homedir as homedir2 } from "os";
1254
1254
  function defaultConfig() {
1255
1255
  return {
1256
1256
  version: VERSION2,
@@ -1263,8 +1263,8 @@ function defaultConfig() {
1263
1263
  };
1264
1264
  }
1265
1265
  function ensureConfigDir() {
1266
- if (!existsSync(CONFIG_DIR)) {
1267
- mkdirSync(CONFIG_DIR, { recursive: true });
1266
+ if (!existsSync2(CONFIG_DIR)) {
1267
+ mkdirSync2(CONFIG_DIR, { recursive: true });
1268
1268
  }
1269
1269
  return CONFIG_DIR;
1270
1270
  }
@@ -1276,11 +1276,11 @@ function getConfigPath() {
1276
1276
  }
1277
1277
  async function readConfig() {
1278
1278
  ensureConfigDir();
1279
- if (!existsSync(CONFIG_FILE)) {
1279
+ if (!existsSync2(CONFIG_FILE)) {
1280
1280
  return defaultConfig();
1281
1281
  }
1282
1282
  try {
1283
- const text = readFileSync2(CONFIG_FILE, "utf-8");
1283
+ const text = readFileSync3(CONFIG_FILE, "utf-8");
1284
1284
  const parsed = JSON.parse(text);
1285
1285
  return { ...defaultConfig(), ...parsed };
1286
1286
  } catch {
@@ -1289,7 +1289,7 @@ async function readConfig() {
1289
1289
  }
1290
1290
  async function writeConfig(config) {
1291
1291
  ensureConfigDir();
1292
- writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
1292
+ writeFileSync2(CONFIG_FILE, JSON.stringify(config, null, 2));
1293
1293
  }
1294
1294
  async function updateConfig(updater) {
1295
1295
  const config = await readConfig();
@@ -1334,11 +1334,11 @@ async function removeAccount(provider, label) {
1334
1334
  return removed;
1335
1335
  }
1336
1336
  async function configExists() {
1337
- return existsSync(CONFIG_FILE);
1337
+ return existsSync2(CONFIG_FILE);
1338
1338
  }
1339
1339
  var CONFIG_DIR, CONFIG_FILE, VERSION2 = "1.0.0";
1340
1340
  var init_config = __esm(() => {
1341
- CONFIG_DIR = join(homedir(), ".omocs");
1341
+ CONFIG_DIR = join(homedir2(), ".omocs");
1342
1342
  CONFIG_FILE = join(CONFIG_DIR, "config.json");
1343
1343
  });
1344
1344
 
@@ -1473,7 +1473,7 @@ var init_profile = __esm(() => {
1473
1473
 
1474
1474
  // src/data/agents.ts
1475
1475
  import { join as join2, dirname as dirname2 } from "path";
1476
- import { readFileSync as readFileSync3 } from "fs";
1476
+ import { readFileSync as readFileSync4 } from "fs";
1477
1477
  import { fileURLToPath as fileURLToPath2 } from "url";
1478
1478
  function getAgentsDir() {
1479
1479
  const __dirname2 = typeof import.meta.dirname === "string" ? import.meta.dirname : dirname2(fileURLToPath2(import.meta.url));
@@ -1500,7 +1500,7 @@ function getAgentPromptPath(agent) {
1500
1500
  async function loadAgentPrompt(agent) {
1501
1501
  const path = getAgentPromptPath(agent);
1502
1502
  try {
1503
- return readFileSync3(path, "utf-8");
1503
+ return readFileSync4(path, "utf-8");
1504
1504
  } catch {
1505
1505
  return `System prompt for ${agent.name} — ${agent.description}`;
1506
1506
  }
@@ -1920,7 +1920,7 @@ var init_mcp_registry = __esm(() => {
1920
1920
  // src/utils/shell.ts
1921
1921
  import { spawn } from "child_process";
1922
1922
  async function run(command, args = [], options) {
1923
- return new Promise((resolve2) => {
1923
+ return new Promise((resolve3) => {
1924
1924
  try {
1925
1925
  const proc = spawn(command, args, {
1926
1926
  cwd: options?.cwd,
@@ -1936,7 +1936,7 @@ async function run(command, args = [], options) {
1936
1936
  stderr += data.toString();
1937
1937
  });
1938
1938
  proc.on("error", (error) => {
1939
- resolve2({
1939
+ resolve3({
1940
1940
  stdout: "",
1941
1941
  stderr: error.message,
1942
1942
  exitCode: 1,
@@ -1945,7 +1945,7 @@ async function run(command, args = [], options) {
1945
1945
  });
1946
1946
  proc.on("close", (code) => {
1947
1947
  const exitCode = code ?? 1;
1948
- resolve2({
1948
+ resolve3({
1949
1949
  stdout: stdout.trim(),
1950
1950
  stderr: stderr.trim(),
1951
1951
  exitCode,
@@ -1953,7 +1953,7 @@ async function run(command, args = [], options) {
1953
1953
  });
1954
1954
  });
1955
1955
  } catch (error) {
1956
- resolve2({
1956
+ resolve3({
1957
1957
  stdout: "",
1958
1958
  stderr: error instanceof Error ? error.message : String(error),
1959
1959
  exitCode: 1,
@@ -1963,7 +1963,8 @@ async function run(command, args = [], options) {
1963
1963
  });
1964
1964
  }
1965
1965
  async function commandExists(command) {
1966
- const result = await run("which", [command]);
1966
+ const isWindows = process.platform === "win32";
1967
+ const result = await run(isWindows ? "where" : "which", [command]);
1967
1968
  return result.success;
1968
1969
  }
1969
1970
  async function getCommandVersion(command, versionFlag = "--version") {
@@ -1977,21 +1978,21 @@ async function getCommandVersion(command, versionFlag = "--version") {
1977
1978
  var init_shell = () => {};
1978
1979
 
1979
1980
  // src/core/opencode.ts
1980
- import { existsSync as existsSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
1981
- import { join as join3, resolve as resolve2, dirname as dirname3 } from "path";
1982
- import { homedir as homedir2 } from "os";
1981
+ import { existsSync as existsSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "fs";
1982
+ import { join as join3, resolve as resolve3, dirname as dirname3 } from "path";
1983
+ import { homedir as homedir3 } from "os";
1983
1984
  function getConfigPaths() {
1984
1985
  return [
1985
1986
  join3(process.cwd(), ".opencode.json"),
1986
- join3(homedir2(), ".opencode.json"),
1987
- join3(homedir2(), ".config", "opencode", "config.json")
1987
+ join3(homedir3(), ".opencode.json"),
1988
+ join3(homedir3(), ".config", "opencode", "config.json")
1988
1989
  ];
1989
1990
  }
1990
1991
  async function readOpenCodeConfig() {
1991
1992
  for (const configPath of getConfigPaths()) {
1992
- if (existsSync2(configPath)) {
1993
+ if (existsSync3(configPath)) {
1993
1994
  try {
1994
- const text = readFileSync4(configPath, "utf-8");
1995
+ const text = readFileSync5(configPath, "utf-8");
1995
1996
  return { config: JSON.parse(text), path: configPath };
1996
1997
  } catch {
1997
1998
  continue;
@@ -2002,8 +2003,8 @@ async function readOpenCodeConfig() {
2002
2003
  }
2003
2004
  async function writeOpenCodeConfig(config, path) {
2004
2005
  const targetPath = path || join3(process.cwd(), ".opencode.json");
2005
- mkdirSync2(dirname3(targetPath), { recursive: true });
2006
- writeFileSync2(targetPath, JSON.stringify(config, null, 2));
2006
+ mkdirSync3(dirname3(targetPath), { recursive: true });
2007
+ writeFileSync3(targetPath, JSON.stringify(config, null, 2));
2007
2008
  return targetPath;
2008
2009
  }
2009
2010
  async function mergeProfile(profile) {
@@ -2017,8 +2018,8 @@ async function mergeProfile(profile) {
2017
2018
  config.autoCompact = profile.settings.autoCompact;
2018
2019
  }
2019
2020
  const configPath = existing?.path || join3(process.cwd(), ".opencode.json");
2020
- mkdirSync2(dirname3(configPath), { recursive: true });
2021
- writeFileSync2(configPath, JSON.stringify(config, null, 2));
2021
+ mkdirSync3(dirname3(configPath), { recursive: true });
2022
+ writeFileSync3(configPath, JSON.stringify(config, null, 2));
2022
2023
  return { config, path: configPath };
2023
2024
  }
2024
2025
  async function detectOpenCode() {
@@ -2065,22 +2066,22 @@ async function removeMcpFromConfig(name) {
2065
2066
  }
2066
2067
  function findOpencodeConfig() {
2067
2068
  const localPaths = [
2068
- resolve2(process.cwd(), "opencode.json"),
2069
- resolve2(process.cwd(), ".opencode.json")
2069
+ resolve3(process.cwd(), "opencode.json"),
2070
+ resolve3(process.cwd(), ".opencode.json")
2070
2071
  ];
2071
2072
  for (const p of localPaths) {
2072
- if (existsSync2(p))
2073
+ if (existsSync3(p))
2073
2074
  return p;
2074
2075
  }
2075
- const globalPath = resolve2(homedir2(), ".config", "opencode", "opencode.json");
2076
+ const globalPath = resolve3(homedir3(), ".config", "opencode", "opencode.json");
2076
2077
  return globalPath;
2077
2078
  }
2078
2079
  async function checkOhMyOpenCode() {
2079
2080
  const paths = [
2080
- resolve2(homedir2(), ".cache", "opencode", "node_modules", "oh-my-opencode"),
2081
- resolve2(homedir2(), ".config", "opencode", "node_modules", "oh-my-opencode")
2081
+ resolve3(homedir3(), ".cache", "opencode", "node_modules", "oh-my-opencode"),
2082
+ resolve3(homedir3(), ".config", "opencode", "node_modules", "oh-my-opencode")
2082
2083
  ];
2083
- return paths.some((p) => existsSync2(p));
2084
+ return paths.some((p) => existsSync3(p));
2084
2085
  }
2085
2086
  var init_opencode = __esm(() => {
2086
2087
  init_shell();
@@ -2540,21 +2541,21 @@ var init_doctor = __esm(() => {
2540
2541
  });
2541
2542
 
2542
2543
  // src/tui/views/stats.ts
2543
- import { existsSync as existsSync3, readFileSync as readFileSync5 } from "fs";
2544
+ import { existsSync as existsSync4, readFileSync as readFileSync6 } from "fs";
2544
2545
  import { join as join4 } from "path";
2545
- import { homedir as homedir3 } from "os";
2546
+ import { homedir as homedir4 } from "os";
2546
2547
  function initialStatsState() {
2547
2548
  return { loaded: false, data: null };
2548
2549
  }
2549
2550
  async function loadStats(state) {
2550
- const statsPath = join4(homedir3(), ".omocs", "stats.json");
2551
- if (!existsSync3(statsPath)) {
2551
+ const statsPath = join4(homedir4(), ".omocs", "stats.json");
2552
+ if (!existsSync4(statsPath)) {
2552
2553
  state.data = null;
2553
2554
  state.loaded = true;
2554
2555
  return;
2555
2556
  }
2556
2557
  try {
2557
- const text = readFileSync5(statsPath, "utf-8");
2558
+ const text = readFileSync6(statsPath, "utf-8");
2558
2559
  state.data = JSON.parse(text);
2559
2560
  state.loaded = true;
2560
2561
  } catch {
@@ -2934,11 +2935,11 @@ function lspCommand(args) {
2934
2935
  return [dim(`Usage: /lsp [detect|list]`)];
2935
2936
  }
2936
2937
  async function statsCommand() {
2937
- const { existsSync: existsSync4 } = await import("fs");
2938
+ const { existsSync: existsSync5 } = await import("fs");
2938
2939
  const { join: join5 } = await import("path");
2939
- const { homedir: homedir4 } = await import("os");
2940
- const statsPath = join5(homedir4(), ".omocs", "stats.json");
2941
- if (!existsSync4(statsPath)) {
2940
+ const { homedir: homedir5 } = await import("os");
2941
+ const statsPath = join5(homedir5(), ".omocs", "stats.json");
2942
+ if (!existsSync5(statsPath)) {
2942
2943
  return [
2943
2944
  goldBold("═══ Stats ═══"),
2944
2945
  "",
@@ -2950,8 +2951,8 @@ async function statsCommand() {
2950
2951
  ];
2951
2952
  }
2952
2953
  try {
2953
- const { readFileSync: readFileSync6 } = await import("fs");
2954
- const text = readFileSync6(statsPath, "utf-8");
2954
+ const { readFileSync: readFileSync7 } = await import("fs");
2955
+ const text = readFileSync7(statsPath, "utf-8");
2955
2956
  const data = JSON.parse(text);
2956
2957
  const lines = [goldBold("═══ Stats ═══"), ""];
2957
2958
  lines.push(` ${bold("Total Tokens:")} ${white(formatNumber2(data.totalTokens || 0))}`);
@@ -13129,13 +13130,13 @@ var PromisePolyfill;
13129
13130
  var init_promise_polyfill = __esm(() => {
13130
13131
  PromisePolyfill = class PromisePolyfill extends Promise {
13131
13132
  static withResolver() {
13132
- let resolve3;
13133
+ let resolve4;
13133
13134
  let reject;
13134
13135
  const promise = new Promise((res, rej) => {
13135
- resolve3 = res;
13136
+ resolve4 = res;
13136
13137
  reject = rej;
13137
13138
  });
13138
- return { promise, resolve: resolve3, reject };
13139
+ return { promise, resolve: resolve4, reject };
13139
13140
  }
13140
13141
  };
13141
13142
  });
@@ -13172,7 +13173,7 @@ function createPrompt(view) {
13172
13173
  output
13173
13174
  });
13174
13175
  const screen = new ScreenManager(rl);
13175
- const { promise, resolve: resolve3, reject } = PromisePolyfill.withResolver();
13176
+ const { promise, resolve: resolve4, reject } = PromisePolyfill.withResolver();
13176
13177
  const cancel = () => reject(new CancelPromptError);
13177
13178
  if (signal) {
13178
13179
  const abort = () => reject(new AbortPromptError({ cause: signal.reason }));
@@ -13199,7 +13200,7 @@ function createPrompt(view) {
13199
13200
  cycle(() => {
13200
13201
  try {
13201
13202
  const nextView = view(config, (value) => {
13202
- setImmediate(() => resolve3(value));
13203
+ setImmediate(() => resolve4(value));
13203
13204
  });
13204
13205
  if (nextView === undefined) {
13205
13206
  const callerFilename = callSites[1]?.getFileName();
@@ -19054,7 +19055,7 @@ var require_lib2 = __commonJS((exports) => {
19054
19055
  return matches;
19055
19056
  };
19056
19057
  exports.analyse = analyse;
19057
- var detectFile = (filepath, opts = {}) => new Promise((resolve3, reject) => {
19058
+ var detectFile = (filepath, opts = {}) => new Promise((resolve4, reject) => {
19058
19059
  let fd;
19059
19060
  const fs = (0, node_1.default)();
19060
19061
  const handler = (err, buffer) => {
@@ -19064,7 +19065,7 @@ var require_lib2 = __commonJS((exports) => {
19064
19065
  if (err) {
19065
19066
  reject(err);
19066
19067
  } else if (buffer) {
19067
- resolve3((0, exports.detect)(buffer));
19068
+ resolve4((0, exports.detect)(buffer));
19068
19069
  } else {
19069
19070
  reject(new Error("No error and no buffer received"));
19070
19071
  }
@@ -22818,7 +22819,7 @@ var init_RemoveFileError = __esm(() => {
22818
22819
 
22819
22820
  // node_modules/@inquirer/external-editor/dist/esm/index.js
22820
22821
  import { spawn as spawn2, spawnSync } from "child_process";
22821
- import { readFileSync as readFileSync6, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
22822
+ import { readFileSync as readFileSync7, unlinkSync, writeFileSync as writeFileSync4 } from "fs";
22822
22823
  import path from "node:path";
22823
22824
  import os2 from "node:os";
22824
22825
  import { randomUUID } from "node:crypto";
@@ -22927,14 +22928,14 @@ class ExternalEditor {
22927
22928
  if (Object.prototype.hasOwnProperty.call(this.fileOptions, "mode")) {
22928
22929
  opt.mode = this.fileOptions.mode;
22929
22930
  }
22930
- writeFileSync3(this.tempFile, this.text, opt);
22931
+ writeFileSync4(this.tempFile, this.text, opt);
22931
22932
  } catch (createFileError) {
22932
22933
  throw new CreateFileError(createFileError);
22933
22934
  }
22934
22935
  }
22935
22936
  readTemporaryFile() {
22936
22937
  try {
22937
- const tempFileBuffer = readFileSync6(this.tempFile);
22938
+ const tempFileBuffer = readFileSync7(this.tempFile);
22938
22939
  if (tempFileBuffer.length === 0) {
22939
22940
  this.text = "";
22940
22941
  } else {
@@ -24601,7 +24602,7 @@ var require_Observable = __commonJS((exports) => {
24601
24602
  Observable2.prototype.forEach = function(next, promiseCtor) {
24602
24603
  var _this = this;
24603
24604
  promiseCtor = getPromiseCtor(promiseCtor);
24604
- return new promiseCtor(function(resolve3, reject) {
24605
+ return new promiseCtor(function(resolve4, reject) {
24605
24606
  var subscriber = new Subscriber_1.SafeSubscriber({
24606
24607
  next: function(value) {
24607
24608
  try {
@@ -24612,7 +24613,7 @@ var require_Observable = __commonJS((exports) => {
24612
24613
  }
24613
24614
  },
24614
24615
  error: reject,
24615
- complete: resolve3
24616
+ complete: resolve4
24616
24617
  });
24617
24618
  _this.subscribe(subscriber);
24618
24619
  });
@@ -24634,14 +24635,14 @@ var require_Observable = __commonJS((exports) => {
24634
24635
  Observable2.prototype.toPromise = function(promiseCtor) {
24635
24636
  var _this = this;
24636
24637
  promiseCtor = getPromiseCtor(promiseCtor);
24637
- return new promiseCtor(function(resolve3, reject) {
24638
+ return new promiseCtor(function(resolve4, reject) {
24638
24639
  var value;
24639
24640
  _this.subscribe(function(x) {
24640
24641
  return value = x;
24641
24642
  }, function(err) {
24642
24643
  return reject(err);
24643
24644
  }, function() {
24644
- return resolve3(value);
24645
+ return resolve4(value);
24645
24646
  });
24646
24647
  });
24647
24648
  };
@@ -26669,11 +26670,11 @@ var require_isReadableStreamLike = __commonJS((exports) => {
26669
26670
  var require_innerFrom = __commonJS((exports) => {
26670
26671
  var __awaiter = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
26671
26672
  function adopt(value) {
26672
- return value instanceof P ? value : new P(function(resolve3) {
26673
- resolve3(value);
26673
+ return value instanceof P ? value : new P(function(resolve4) {
26674
+ resolve4(value);
26674
26675
  });
26675
26676
  }
26676
- return new (P || (P = Promise))(function(resolve3, reject) {
26677
+ return new (P || (P = Promise))(function(resolve4, reject) {
26677
26678
  function fulfilled(value) {
26678
26679
  try {
26679
26680
  step(generator.next(value));
@@ -26689,7 +26690,7 @@ var require_innerFrom = __commonJS((exports) => {
26689
26690
  }
26690
26691
  }
26691
26692
  function step(result) {
26692
- result.done ? resolve3(result.value) : adopt(result.value).then(fulfilled, rejected);
26693
+ result.done ? resolve4(result.value) : adopt(result.value).then(fulfilled, rejected);
26693
26694
  }
26694
26695
  step((generator = generator.apply(thisArg, _arguments || [])).next());
26695
26696
  });
@@ -26779,14 +26780,14 @@ var require_innerFrom = __commonJS((exports) => {
26779
26780
  }, i);
26780
26781
  function verb(n) {
26781
26782
  i[n] = o[n] && function(v) {
26782
- return new Promise(function(resolve3, reject) {
26783
- v = o[n](v), settle(resolve3, reject, v.done, v.value);
26783
+ return new Promise(function(resolve4, reject) {
26784
+ v = o[n](v), settle(resolve4, reject, v.done, v.value);
26784
26785
  });
26785
26786
  };
26786
26787
  }
26787
- function settle(resolve3, reject, d, v) {
26788
+ function settle(resolve4, reject, d, v) {
26788
26789
  Promise.resolve(v).then(function(v2) {
26789
- resolve3({ value: v2, done: d });
26790
+ resolve4({ value: v2, done: d });
26790
26791
  }, reject);
26791
26792
  }
26792
26793
  };
@@ -27362,7 +27363,7 @@ var require_lastValueFrom = __commonJS((exports) => {
27362
27363
  var EmptyError_1 = require_EmptyError();
27363
27364
  function lastValueFrom(source, config) {
27364
27365
  var hasConfig = typeof config === "object";
27365
- return new Promise(function(resolve3, reject) {
27366
+ return new Promise(function(resolve4, reject) {
27366
27367
  var _hasValue = false;
27367
27368
  var _value;
27368
27369
  source.subscribe({
@@ -27373,9 +27374,9 @@ var require_lastValueFrom = __commonJS((exports) => {
27373
27374
  error: reject,
27374
27375
  complete: function() {
27375
27376
  if (_hasValue) {
27376
- resolve3(_value);
27377
+ resolve4(_value);
27377
27378
  } else if (hasConfig) {
27378
- resolve3(config.defaultValue);
27379
+ resolve4(config.defaultValue);
27379
27380
  } else {
27380
27381
  reject(new EmptyError_1.EmptyError);
27381
27382
  }
@@ -27394,16 +27395,16 @@ var require_firstValueFrom = __commonJS((exports) => {
27394
27395
  var Subscriber_1 = require_Subscriber();
27395
27396
  function firstValueFrom(source, config) {
27396
27397
  var hasConfig = typeof config === "object";
27397
- return new Promise(function(resolve3, reject) {
27398
+ return new Promise(function(resolve4, reject) {
27398
27399
  var subscriber = new Subscriber_1.SafeSubscriber({
27399
27400
  next: function(value) {
27400
- resolve3(value);
27401
+ resolve4(value);
27401
27402
  subscriber.unsubscribe();
27402
27403
  },
27403
27404
  error: reject,
27404
27405
  complete: function() {
27405
27406
  if (hasConfig) {
27406
- resolve3(config.defaultValue);
27407
+ resolve4(config.defaultValue);
27407
27408
  } else {
27408
27409
  reject(new EmptyError_1.EmptyError);
27409
27410
  }
@@ -32868,14 +32869,14 @@ var require_run_async = __commonJS((exports, module) => {
32868
32869
  return function() {
32869
32870
  var args = arguments;
32870
32871
  var originalThis = this;
32871
- var promise = new Promise(function(resolve3, reject) {
32872
+ var promise = new Promise(function(resolve4, reject) {
32872
32873
  var resolved = false;
32873
32874
  const wrappedResolve = function(value) {
32874
32875
  if (resolved) {
32875
32876
  console.warn("Run-async promise already resolved.");
32876
32877
  }
32877
32878
  resolved = true;
32878
- resolve3(value);
32879
+ resolve4(value);
32879
32880
  };
32880
32881
  var rejected = false;
32881
32882
  const wrappedReject = function(value) {
@@ -33059,7 +33060,7 @@ class PromptsRunner {
33059
33060
  throw new Error(`Prompt for type ${question.type} not found`);
33060
33061
  }
33061
33062
  let cleanupSignal;
33062
- const promptFn = isPromptConstructor(prompt) ? (q, opt) => new Promise((resolve3, reject) => {
33063
+ const promptFn = isPromptConstructor(prompt) ? (q, opt) => new Promise((resolve4, reject) => {
33063
33064
  const { signal: signal2 } = opt;
33064
33065
  if (signal2.aborted) {
33065
33066
  reject(new AbortPromptError({ cause: signal2.reason }));
@@ -33096,7 +33097,7 @@ class PromptsRunner {
33096
33097
  signal2.removeEventListener("abort", abort);
33097
33098
  cleanupSignal = undefined;
33098
33099
  };
33099
- activePrompt.run().then(resolve3, reject).finally(cleanup2);
33100
+ activePrompt.run().then(resolve4, reject).finally(cleanup2);
33100
33101
  }) : prompt;
33101
33102
  let cleanupModuleSignal;
33102
33103
  const { signal: moduleSignal } = this.opt;
@@ -33263,28 +33264,28 @@ var ALGORITHM = "aes-256-gcm", KEY_LENGTH = 32, IV_LENGTH = 16, SALT_LENGTH = 32
33263
33264
  var init_crypto = () => {};
33264
33265
 
33265
33266
  // src/utils/detect.ts
33266
- import { existsSync as existsSync4, readdirSync, readFileSync as readFileSync7 } from "fs";
33267
+ import { existsSync as existsSync5, readdirSync, readFileSync as readFileSync8 } from "fs";
33267
33268
  import { join as join5 } from "path";
33268
33269
  function fileOrDirExists(base, name) {
33269
33270
  const full = join5(base, name);
33270
- return existsSync4(full);
33271
+ return existsSync5(full);
33271
33272
  }
33272
33273
  function detectPackageManager(base) {
33273
- if (existsSync4(join5(base, "bun.lockb")) || existsSync4(join5(base, "bun.lock")))
33274
+ if (existsSync5(join5(base, "bun.lockb")) || existsSync5(join5(base, "bun.lock")))
33274
33275
  return "bun";
33275
- if (existsSync4(join5(base, "pnpm-lock.yaml")))
33276
+ if (existsSync5(join5(base, "pnpm-lock.yaml")))
33276
33277
  return "pnpm";
33277
- if (existsSync4(join5(base, "yarn.lock")))
33278
+ if (existsSync5(join5(base, "yarn.lock")))
33278
33279
  return "yarn";
33279
- if (existsSync4(join5(base, "package-lock.json")))
33280
+ if (existsSync5(join5(base, "package-lock.json")))
33280
33281
  return "npm";
33281
- if (existsSync4(join5(base, "Pipfile.lock")))
33282
+ if (existsSync5(join5(base, "Pipfile.lock")))
33282
33283
  return "pipenv";
33283
- if (existsSync4(join5(base, "poetry.lock")))
33284
+ if (existsSync5(join5(base, "poetry.lock")))
33284
33285
  return "poetry";
33285
- if (existsSync4(join5(base, "Cargo.lock")))
33286
+ if (existsSync5(join5(base, "Cargo.lock")))
33286
33287
  return "cargo";
33287
- if (existsSync4(join5(base, "go.sum")))
33288
+ if (existsSync5(join5(base, "go.sum")))
33288
33289
  return "go";
33289
33290
  return null;
33290
33291
  }
@@ -33394,9 +33395,9 @@ var init_detect = __esm(() => {
33394
33395
  });
33395
33396
 
33396
33397
  // src/commands/init.ts
33397
- import { execSync as execSync2 } from "child_process";
33398
- import { existsSync as existsSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3 } from "fs";
33399
- import { resolve as resolve3, dirname as dirname4 } from "path";
33398
+ import { execSync as execSync3 } from "child_process";
33399
+ import { existsSync as existsSync6, readFileSync as readFileSync9, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4 } from "fs";
33400
+ import { resolve as resolve4, dirname as dirname4 } from "path";
33400
33401
  function registerInitCommand(program2) {
33401
33402
  program2.command("init").description("Interactive setup wizard — configure OMOCS for the first time").option("-f, --force", "Overwrite existing configuration").action(async (options) => {
33402
33403
  try {
@@ -33430,7 +33431,7 @@ function registerInitCommand(program2) {
33430
33431
  } else {
33431
33432
  ohmySpinner.text = "Installing oh-my-opencode...";
33432
33433
  try {
33433
- execSync2("npm install -g oh-my-opencode 2>/dev/null || bun add -g oh-my-opencode 2>/dev/null", { stdio: "pipe" });
33434
+ execSync3("npm install -g oh-my-opencode 2>/dev/null || bun add -g oh-my-opencode 2>/dev/null", { stdio: "pipe" });
33434
33435
  ohmySpinner.succeed("oh-my-opencode installed");
33435
33436
  } catch {
33436
33437
  ohmySpinner.warn("Could not auto-install oh-my-opencode. Add manually to opencode.json plugins.");
@@ -33441,8 +33442,8 @@ function registerInitCommand(program2) {
33441
33442
  try {
33442
33443
  const opencodeConfigPath = findOpencodeConfig();
33443
33444
  let opencodeConfig = {};
33444
- if (existsSync5(opencodeConfigPath)) {
33445
- opencodeConfig = JSON.parse(readFileSync8(opencodeConfigPath, "utf-8"));
33445
+ if (existsSync6(opencodeConfigPath)) {
33446
+ opencodeConfig = JSON.parse(readFileSync9(opencodeConfigPath, "utf-8"));
33446
33447
  }
33447
33448
  if (!opencodeConfig.plugin)
33448
33449
  opencodeConfig.plugin = [];
@@ -33453,10 +33454,10 @@ function registerInitCommand(program2) {
33453
33454
  opencodeConfig.plugin.push("omocs");
33454
33455
  }
33455
33456
  const configDir = dirname4(opencodeConfigPath);
33456
- if (!existsSync5(configDir)) {
33457
- mkdirSync3(configDir, { recursive: true });
33457
+ if (!existsSync6(configDir)) {
33458
+ mkdirSync4(configDir, { recursive: true });
33458
33459
  }
33459
- writeFileSync4(opencodeConfigPath, JSON.stringify(opencodeConfig, null, 2));
33460
+ writeFileSync5(opencodeConfigPath, JSON.stringify(opencodeConfig, null, 2));
33460
33461
  pluginSpinner.succeed("OMO Suites + oh-my-opencode registered in opencode.json");
33461
33462
  } catch (e) {
33462
33463
  pluginSpinner.warn("Could not auto-register plugins. Add manually to opencode.json");
@@ -33471,37 +33472,37 @@ function registerInitCommand(program2) {
33471
33472
  }]);
33472
33473
  setupLaunchboard = lbPrompt.setupLaunchboard;
33473
33474
  if (setupLaunchboard) {
33474
- const lbDir = resolve3(dirname4(new URL(import.meta.url).pathname), "../../packages/launchboard");
33475
- if (!existsSync5(lbDir)) {
33475
+ const lbDir = resolve4(dirname4(new URL(import.meta.url).pathname), "../../packages/launchboard");
33476
+ if (!existsSync6(lbDir)) {
33476
33477
  info("Launchboard package not found. Skipping.");
33477
33478
  setupLaunchboard = false;
33478
33479
  } else {
33479
33480
  const lbSpinner = ora("Installing Launchboard dependencies...").start();
33480
33481
  try {
33481
- execSync2("bun install", { cwd: lbDir, stdio: "pipe" });
33482
+ execSync3("bun install", { cwd: lbDir, stdio: "pipe" });
33482
33483
  lbSpinner.succeed("Backend dependencies installed");
33483
33484
  } catch (e) {
33484
33485
  lbSpinner.fail("Failed to install backend deps");
33485
33486
  }
33486
- const frontendDir = resolve3(lbDir, "frontend");
33487
- if (existsSync5(frontendDir)) {
33487
+ const frontendDir = resolve4(lbDir, "frontend");
33488
+ if (existsSync6(frontendDir)) {
33488
33489
  const feSpinner = ora("Installing frontend dependencies...").start();
33489
33490
  try {
33490
- execSync2("bun install", { cwd: frontendDir, stdio: "pipe" });
33491
+ execSync3("bun install", { cwd: frontendDir, stdio: "pipe" });
33491
33492
  feSpinner.succeed("Frontend dependencies installed");
33492
33493
  } catch {
33493
33494
  feSpinner.fail("Failed to install frontend deps");
33494
33495
  }
33495
33496
  }
33496
- const dbPath = resolve3(lbDir, "launchboard.db");
33497
- if (!existsSync5(dbPath)) {
33497
+ const dbPath = resolve4(lbDir, "launchboard.db");
33498
+ if (!existsSync6(dbPath)) {
33498
33499
  const dbSpinner = ora("Creating database...").start();
33499
33500
  try {
33500
- execSync2("bunx drizzle-kit push", { cwd: lbDir, stdio: "pipe" });
33501
+ execSync3("bunx drizzle-kit push", { cwd: lbDir, stdio: "pipe" });
33501
33502
  dbSpinner.succeed("Database created");
33502
33503
  const seedSpinner = ora("Seeding sample data...").start();
33503
33504
  try {
33504
- execSync2("bun run seed", { cwd: lbDir, stdio: "pipe" });
33505
+ execSync3("bun run seed", { cwd: lbDir, stdio: "pipe" });
33505
33506
  seedSpinner.succeed("Sample data seeded");
33506
33507
  } catch {
33507
33508
  seedSpinner.fail("Failed to seed sample data");
@@ -33689,7 +33690,7 @@ var init_init = __esm(() => {
33689
33690
 
33690
33691
  // src/commands/doctor.ts
33691
33692
  import { statSync as statSync2 } from "fs";
33692
- import { homedir as homedir4 } from "os";
33693
+ import { homedir as homedir5 } from "os";
33693
33694
  async function runChecks() {
33694
33695
  const results = [];
33695
33696
  const spinner = ora({ text: "Running health checks...", color: "cyan" }).start();
@@ -33835,7 +33836,7 @@ async function runChecks() {
33835
33836
  });
33836
33837
  spinner.text = "Checking disk space...";
33837
33838
  try {
33838
- const homeDir = homedir4();
33839
+ const homeDir = homedir5();
33839
33840
  const stats = statSync2(homeDir);
33840
33841
  results.push({
33841
33842
  name: "Disk Space",
@@ -34154,7 +34155,7 @@ var init_account = __esm(() => {
34154
34155
  });
34155
34156
 
34156
34157
  // src/core/store.ts
34157
- import { existsSync as existsSync7, readFileSync as readFileSync9, writeFileSync as writeFileSync5 } from "fs";
34158
+ import { existsSync as existsSync8, readFileSync as readFileSync10, writeFileSync as writeFileSync6 } from "fs";
34158
34159
  import { join as join6 } from "path";
34159
34160
 
34160
34161
  class Store {
@@ -34166,18 +34167,18 @@ class Store {
34166
34167
  this.defaults = defaults;
34167
34168
  }
34168
34169
  async read() {
34169
- if (!existsSync7(this.filePath)) {
34170
+ if (!existsSync8(this.filePath)) {
34170
34171
  return { ...this.defaults };
34171
34172
  }
34172
34173
  try {
34173
- const text = readFileSync9(this.filePath, "utf-8");
34174
+ const text = readFileSync10(this.filePath, "utf-8");
34174
34175
  return { ...this.defaults, ...JSON.parse(text) };
34175
34176
  } catch {
34176
34177
  return { ...this.defaults };
34177
34178
  }
34178
34179
  }
34179
34180
  async write(data) {
34180
- writeFileSync5(this.filePath, JSON.stringify(data, null, 2));
34181
+ writeFileSync6(this.filePath, JSON.stringify(data, null, 2));
34181
34182
  }
34182
34183
  async update(updater) {
34183
34184
  const data = await this.read();
@@ -34195,10 +34196,10 @@ class Store {
34195
34196
  });
34196
34197
  }
34197
34198
  async exists() {
34198
- return existsSync7(this.filePath);
34199
+ return existsSync8(this.filePath);
34199
34200
  }
34200
34201
  async delete() {
34201
- if (existsSync7(this.filePath)) {
34202
+ if (existsSync8(this.filePath)) {
34202
34203
  const { unlinkSync: unlinkSync2 } = await import("fs");
34203
34204
  unlinkSync2(this.filePath);
34204
34205
  }
@@ -34223,7 +34224,7 @@ var init_store = __esm(() => {
34223
34224
  });
34224
34225
 
34225
34226
  // src/commands/profile.ts
34226
- import { readFileSync as readFileSync10 } from "fs";
34227
+ import { readFileSync as readFileSync11 } from "fs";
34227
34228
  function registerProfileCommand(program2) {
34228
34229
  const profile = program2.command("profile").description("Manage model profiles");
34229
34230
  profile.command("list").description("List all available profiles").action(async () => {
@@ -34399,7 +34400,7 @@ function registerProfileCommand(program2) {
34399
34400
  });
34400
34401
  profile.command("import").description("Import a profile from JSON file").argument("<file>", "Path to JSON file").action(async (file) => {
34401
34402
  try {
34402
- const content = readFileSync10(file, "utf-8");
34403
+ const content = readFileSync11(file, "utf-8");
34403
34404
  const data = JSON.parse(content);
34404
34405
  if (!data.key || !data.name || !data.agents) {
34405
34406
  fail("Invalid profile format. Required: key, name, agents");
@@ -35278,13 +35279,13 @@ var require_backup = __commonJS((exports, module) => {
35278
35279
  var runBackup = (backup, handler) => {
35279
35280
  let rate = 0;
35280
35281
  let useDefault = true;
35281
- return new Promise((resolve4, reject) => {
35282
+ return new Promise((resolve5, reject) => {
35282
35283
  setImmediate(function step() {
35283
35284
  try {
35284
35285
  const progress = backup.transfer(rate);
35285
35286
  if (!progress.remainingPages) {
35286
35287
  backup.close();
35287
- resolve4(progress);
35288
+ resolve5(progress);
35288
35289
  return;
35289
35290
  }
35290
35291
  if (useDefault) {
@@ -35668,17 +35669,17 @@ var require_lib4 = __commonJS((exports, module) => {
35668
35669
  });
35669
35670
 
35670
35671
  // src/commands/stats.ts
35671
- import { existsSync as existsSync8, writeFileSync as writeFileSync6 } from "fs";
35672
+ import { existsSync as existsSync9, writeFileSync as writeFileSync7 } from "fs";
35672
35673
  import { join as join7 } from "path";
35673
- import { homedir as homedir5 } from "os";
35674
+ import { homedir as homedir6 } from "os";
35674
35675
  function findDatabase() {
35675
35676
  const locations = [
35676
35677
  join7(process.cwd(), ".opencode", "data.db"),
35677
- join7(homedir5(), ".opencode", "data.db"),
35678
- join7(homedir5(), ".config", "opencode", "data.db")
35678
+ join7(homedir6(), ".opencode", "data.db"),
35679
+ join7(homedir6(), ".config", "opencode", "data.db")
35679
35680
  ];
35680
35681
  for (const loc of locations) {
35681
- if (existsSync8(loc))
35682
+ if (existsSync9(loc))
35682
35683
  return loc;
35683
35684
  }
35684
35685
  return null;
@@ -35806,7 +35807,7 @@ function registerStatsCommand(program2) {
35806
35807
  "date,messages,input_tokens,output_tokens,total_tokens,estimated_cost",
35807
35808
  ...dailyStats.map((d) => `${d.date},${d.messages},${d.input_tokens},${d.output_tokens},${d.input_tokens + d.output_tokens},${estimateCost(d.input_tokens, d.output_tokens).toFixed(2)}`)
35808
35809
  ];
35809
- writeFileSync6(options.export, csvLines.join(`
35810
+ writeFileSync7(options.export, csvLines.join(`
35810
35811
  `));
35811
35812
  success(`Exported to ${options.export}`);
35812
35813
  }
@@ -35842,9 +35843,9 @@ var init_stats2 = __esm(() => {
35842
35843
  });
35843
35844
 
35844
35845
  // src/commands/launchboard.ts
35845
- import { execSync as execSync3 } from "child_process";
35846
- import { existsSync as existsSync9 } from "fs";
35847
- import { resolve as resolve4, dirname as dirname5 } from "path";
35846
+ import { execSync as execSync4 } from "child_process";
35847
+ import { existsSync as existsSync10 } from "fs";
35848
+ import { resolve as resolve5, dirname as dirname5 } from "path";
35848
35849
  import { fileURLToPath as fileURLToPath3 } from "url";
35849
35850
  function registerLaunchboardCommand(program2) {
35850
35851
  const lb = program2.command("launchboard").alias("lb").description("Manage Launchboard — AI-integrated Kanban board");
@@ -35852,40 +35853,40 @@ function registerLaunchboardCommand(program2) {
35852
35853
  console.log(source_default.hex("#d4a853").bold(`
35853
35854
  \uD83D\uDE80 Setting up Launchboard...
35854
35855
  `));
35855
- if (!existsSync9(LAUNCHBOARD_DIR)) {
35856
+ if (!existsSync10(LAUNCHBOARD_DIR)) {
35856
35857
  console.log(source_default.red("❌ Launchboard package not found at"), LAUNCHBOARD_DIR);
35857
35858
  return;
35858
35859
  }
35859
35860
  const spinner = ora("Installing dependencies...").start();
35860
35861
  try {
35861
- execSync3("bun install", { cwd: LAUNCHBOARD_DIR, stdio: "pipe" });
35862
+ execSync4("bun install", { cwd: LAUNCHBOARD_DIR, stdio: "pipe" });
35862
35863
  spinner.succeed("Dependencies installed");
35863
35864
  } catch (e) {
35864
35865
  spinner.fail("Failed to install dependencies");
35865
35866
  return;
35866
35867
  }
35867
- const frontendDir = resolve4(LAUNCHBOARD_DIR, "frontend");
35868
- if (existsSync9(frontendDir)) {
35868
+ const frontendDir = resolve5(LAUNCHBOARD_DIR, "frontend");
35869
+ if (existsSync10(frontendDir)) {
35869
35870
  spinner.start("Installing frontend dependencies...");
35870
35871
  try {
35871
- execSync3("bun install", { cwd: frontendDir, stdio: "pipe" });
35872
+ execSync4("bun install", { cwd: frontendDir, stdio: "pipe" });
35872
35873
  spinner.succeed("Frontend dependencies installed");
35873
35874
  } catch (e) {
35874
35875
  spinner.fail("Failed to install frontend dependencies");
35875
35876
  }
35876
35877
  }
35877
- const dbPath = resolve4(LAUNCHBOARD_DIR, "launchboard.db");
35878
- if (!existsSync9(dbPath)) {
35878
+ const dbPath = resolve5(LAUNCHBOARD_DIR, "launchboard.db");
35879
+ if (!existsSync10(dbPath)) {
35879
35880
  spinner.start("Creating database...");
35880
35881
  try {
35881
- execSync3("bunx drizzle-kit push", { cwd: LAUNCHBOARD_DIR, stdio: "pipe" });
35882
+ execSync4("bunx drizzle-kit push", { cwd: LAUNCHBOARD_DIR, stdio: "pipe" });
35882
35883
  spinner.succeed("Database created");
35883
35884
  } catch (e) {
35884
35885
  spinner.fail("Failed to create database");
35885
35886
  }
35886
35887
  spinner.start("Seeding sample data...");
35887
35888
  try {
35888
- execSync3("bun run seed", { cwd: LAUNCHBOARD_DIR, stdio: "pipe" });
35889
+ execSync4("bun run seed", { cwd: LAUNCHBOARD_DIR, stdio: "pipe" });
35889
35890
  spinner.succeed("Sample data seeded");
35890
35891
  } catch (e) {
35891
35892
  spinner.fail("Failed to seed data");
@@ -35905,23 +35906,23 @@ function registerLaunchboardCommand(program2) {
35905
35906
  console.log(source_default.hex("#d4a853").bold(`
35906
35907
  \uD83D\uDE80 Starting Launchboard...
35907
35908
  `));
35908
- if (!existsSync9(resolve4(LAUNCHBOARD_DIR, "node_modules"))) {
35909
+ if (!existsSync10(resolve5(LAUNCHBOARD_DIR, "node_modules"))) {
35909
35910
  console.log(source_default.yellow("⚠️ Dependencies not installed. Run: omocs launchboard setup"));
35910
35911
  return;
35911
35912
  }
35912
35913
  if (opts.backendOnly) {
35913
35914
  console.log(source_default.dim(" Backend:"), source_default.white("http://localhost:3030"));
35914
- execSync3("bun run start", { cwd: LAUNCHBOARD_DIR, stdio: "inherit" });
35915
+ execSync4("bun run start", { cwd: LAUNCHBOARD_DIR, stdio: "inherit" });
35915
35916
  } else if (opts.frontendOnly) {
35916
- const frontendDir = resolve4(LAUNCHBOARD_DIR, "frontend");
35917
+ const frontendDir = resolve5(LAUNCHBOARD_DIR, "frontend");
35917
35918
  console.log(source_default.dim(" Frontend:"), source_default.white("http://localhost:3040"));
35918
- execSync3("bun run dev", { cwd: frontendDir, stdio: "inherit" });
35919
+ execSync4("bun run dev", { cwd: frontendDir, stdio: "inherit" });
35919
35920
  } else {
35920
35921
  console.log(source_default.dim(" Backend:"), source_default.white("http://localhost:3030"));
35921
35922
  console.log(source_default.dim(" Frontend:"), source_default.white("http://localhost:3040"));
35922
35923
  console.log(source_default.dim(` Press Ctrl+C to stop
35923
35924
  `));
35924
- execSync3("bash setup.sh", { cwd: LAUNCHBOARD_DIR, stdio: "inherit" });
35925
+ execSync4("bash setup.sh", { cwd: LAUNCHBOARD_DIR, stdio: "inherit" });
35925
35926
  }
35926
35927
  });
35927
35928
  lb.command("status").description("Check if Launchboard is running").action(async () => {
@@ -35949,7 +35950,7 @@ var init_launchboard2 = __esm(() => {
35949
35950
  init_source();
35950
35951
  init_ora();
35951
35952
  __dirname2 = dirname5(fileURLToPath3(import.meta.url));
35952
- LAUNCHBOARD_DIR = resolve4(__dirname2, "../../packages/launchboard");
35953
+ LAUNCHBOARD_DIR = resolve5(__dirname2, "../../packages/launchboard");
35953
35954
  });
35954
35955
 
35955
35956
  // src/index.ts
@@ -35957,18 +35958,18 @@ var exports_src = {};
35957
35958
  __export(exports_src, {
35958
35959
  program: () => program2
35959
35960
  });
35960
- import { readFileSync as readFileSync11, existsSync as existsSync10 } from "fs";
35961
- import { dirname as dirname6, resolve as resolve5 } from "path";
35961
+ import { readFileSync as readFileSync12, existsSync as existsSync11 } from "fs";
35962
+ import { dirname as dirname6, resolve as resolve6 } from "path";
35962
35963
  import { fileURLToPath as fileURLToPath4 } from "url";
35963
35964
  function findPackageJson() {
35964
35965
  let dir = dirname6(fileURLToPath4(import.meta.url));
35965
35966
  for (let i = 0;i < 5; i++) {
35966
- const candidate = resolve5(dir, "package.json");
35967
- if (existsSync10(candidate))
35967
+ const candidate = resolve6(dir, "package.json");
35968
+ if (existsSync11(candidate))
35968
35969
  return candidate;
35969
35970
  dir = dirname6(dir);
35970
35971
  }
35971
- return resolve5(dirname6(dirname6(fileURLToPath4(import.meta.url))), "package.json");
35972
+ return resolve6(dirname6(dirname6(fileURLToPath4(import.meta.url))), "package.json");
35972
35973
  }
35973
35974
  var pkg, VERSION4, program2;
35974
35975
  var init_src = __esm(() => {
@@ -35983,7 +35984,7 @@ var init_src = __esm(() => {
35983
35984
  init_mcp2();
35984
35985
  init_stats2();
35985
35986
  init_launchboard2();
35986
- pkg = JSON.parse(readFileSync11(findPackageJson(), "utf-8"));
35987
+ pkg = JSON.parse(readFileSync12(findPackageJson(), "utf-8"));
35987
35988
  VERSION4 = pkg.version;
35988
35989
  program2 = new Command;
35989
35990
  program2.name("omocs").description("OMO Suites — CLI toolkit for OpenCode power users").version(VERSION4, "-v, --version", "Show version").hook("preAction", () => {
@@ -36009,7 +36010,121 @@ var init_src = __esm(() => {
36009
36010
  });
36010
36011
  });
36011
36012
 
36013
+ // src/utils/updater.ts
36014
+ init_source();
36015
+ import { execSync } from "child_process";
36016
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
36017
+ import { resolve } from "path";
36018
+ import { homedir } from "os";
36019
+ var CACHE_DIR = resolve(homedir(), ".omocs");
36020
+ var CACHE_FILE = resolve(CACHE_DIR, ".update-check");
36021
+ var CHECK_INTERVAL_MS = 5 * 60 * 1000;
36022
+ var PACKAGE_NAME = "omo-suites";
36023
+ function readCache() {
36024
+ try {
36025
+ if (existsSync(CACHE_FILE)) {
36026
+ return JSON.parse(readFileSync(CACHE_FILE, "utf-8"));
36027
+ }
36028
+ } catch {}
36029
+ return null;
36030
+ }
36031
+ function writeCache(cache) {
36032
+ try {
36033
+ if (!existsSync(CACHE_DIR)) {
36034
+ mkdirSync(CACHE_DIR, { recursive: true });
36035
+ }
36036
+ writeFileSync(CACHE_FILE, JSON.stringify(cache));
36037
+ } catch {}
36038
+ }
36039
+ function getLatestVersion() {
36040
+ try {
36041
+ const result = execSync(`npm view ${PACKAGE_NAME} version`, {
36042
+ encoding: "utf-8",
36043
+ timeout: 1e4,
36044
+ stdio: ["pipe", "pipe", "pipe"]
36045
+ });
36046
+ return result.trim();
36047
+ } catch {
36048
+ return null;
36049
+ }
36050
+ }
36051
+ function compareVersions(current, latest) {
36052
+ const a = current.split(".").map(Number);
36053
+ const b = latest.split(".").map(Number);
36054
+ for (let i = 0;i < 3; i++) {
36055
+ if ((a[i] || 0) < (b[i] || 0))
36056
+ return -1;
36057
+ if ((a[i] || 0) > (b[i] || 0))
36058
+ return 1;
36059
+ }
36060
+ return 0;
36061
+ }
36062
+ function doUpdate() {
36063
+ try {
36064
+ console.log(source_default.cyan("⬆ Updating omo-suites..."));
36065
+ execSync(`npm install -g ${PACKAGE_NAME}@latest`, {
36066
+ encoding: "utf-8",
36067
+ timeout: 60000,
36068
+ stdio: ["pipe", "pipe", "pipe"]
36069
+ });
36070
+ return true;
36071
+ } catch {
36072
+ return false;
36073
+ }
36074
+ }
36075
+ async function checkAndUpdate(currentVersion) {
36076
+ if (process.env.OMOCS_NO_UPDATE === "1" || process.env.CI) {
36077
+ return false;
36078
+ }
36079
+ const cache = readCache();
36080
+ const now = Date.now();
36081
+ let latestVersion = null;
36082
+ if (cache && now - cache.lastCheck < CHECK_INTERVAL_MS) {
36083
+ latestVersion = cache.latestVersion;
36084
+ } else {
36085
+ latestVersion = getLatestVersion();
36086
+ writeCache({ lastCheck: now, latestVersion });
36087
+ }
36088
+ if (!latestVersion)
36089
+ return false;
36090
+ if (compareVersions(currentVersion, latestVersion) < 0) {
36091
+ console.log(source_default.yellow(`
36092
+ ⬆ New version available: ${source_default.red(currentVersion)} → ${source_default.green(latestVersion)}`));
36093
+ const updated = doUpdate();
36094
+ if (updated) {
36095
+ console.log(source_default.green(`✅ Updated to v${latestVersion}. Restarting...
36096
+ `));
36097
+ try {
36098
+ execSync(`${process.argv[0]} ${process.argv.slice(1).join(" ")}`, {
36099
+ stdio: "inherit",
36100
+ env: { ...process.env, OMOCS_NO_UPDATE: "1" }
36101
+ });
36102
+ } catch {}
36103
+ process.exit(0);
36104
+ } else {
36105
+ console.log(source_default.yellow(`⚠ Auto-update failed. Run manually: ${source_default.cyan(`npm install -g ${PACKAGE_NAME}@latest`)}
36106
+ `));
36107
+ }
36108
+ }
36109
+ return false;
36110
+ }
36111
+
36012
36112
  // bin/omocs.ts
36113
+ import { readFileSync as readFileSync13, existsSync as existsSync12 } from "fs";
36114
+ import { dirname as dirname7, resolve as resolve7 } from "path";
36115
+ import { fileURLToPath as fileURLToPath5 } from "url";
36116
+ function findPackageJson2() {
36117
+ let dir = dirname7(fileURLToPath5(import.meta.url));
36118
+ for (let i = 0;i < 5; i++) {
36119
+ const candidate = resolve7(dir, "package.json");
36120
+ if (existsSync12(candidate))
36121
+ return candidate;
36122
+ dir = dirname7(dir);
36123
+ }
36124
+ return resolve7(dirname7(dirname7(fileURLToPath5(import.meta.url))), "package.json");
36125
+ }
36126
+ var pkg2 = JSON.parse(readFileSync13(findPackageJson2(), "utf-8"));
36127
+ await checkAndUpdate(pkg2.version);
36013
36128
  if (process.argv.length <= 2) {
36014
36129
  const { startTUI: startTUI2 } = await Promise.resolve().then(() => (init_tui(), exports_tui));
36015
36130
  await startTUI2();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omo-suites",
3
- "version": "1.5.2",
3
+ "version": "1.5.4",
4
4
  "description": "OMO Suites — OpenCode plugin + CLI toolkit. Multi-model orchestration, profiles, agent routing, MCP/LSP management.",
5
5
  "type": "module",
6
6
  "main": "dist/plugin.js",