omo-suites 1.13.0 → 1.14.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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,20 @@ 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.14.0] - 2026-03-26
9
+
10
+ ### Added
11
+ - **Auto system** — automatic background checks run on every `omocs` command (non-blocking)
12
+ - **Auto-Doctor** — workspace health check on first run per day (missing config, AGENTS.md, .gitignore)
13
+ - **Auto-Index** — rebuild workspace index when file structure changes (new/renamed files detected)
14
+ - **Auto-Compact** — periodic cleanup of stale memory, stats, and orphaned indexes (every 7 days)
15
+ - **Auto-Template Suggest** — detect empty projects and suggest matching saved templates
16
+ - `omocs auto run` — manually trigger all auto checks
17
+ - `omocs auto status` — view auto check state and timings
18
+ - `omocs auto reset` — force re-run all checks
19
+ - `omocs auto suppress <warning>` — hide specific warnings
20
+ - Auto checks are silent unless there are warnings or fixes to report
21
+
8
22
  ## [1.13.0] - 2026-03-26
9
23
 
10
24
  ### Added
package/dist/cli/omocs.js CHANGED
@@ -41963,6 +41963,492 @@ var init_squad = __esm(() => {
41963
41963
  SQUAD_STATE = join22(SQUAD_DIR, "state.json");
41964
41964
  });
41965
41965
 
41966
+ // src/core/auto.ts
41967
+ import { existsSync as existsSync28, readFileSync as readFileSync29, writeFileSync as writeFileSync21, mkdirSync as mkdirSync17, statSync as statSync11, readdirSync as readdirSync11 } from "fs";
41968
+ import { join as join23, extname as extname2, basename as basename8 } from "path";
41969
+ import { homedir as homedir17 } from "os";
41970
+ import { createHash as createHash6 } from "crypto";
41971
+ function ensureDir5(dir) {
41972
+ if (!existsSync28(dir))
41973
+ mkdirSync17(dir, { recursive: true });
41974
+ }
41975
+ function readJsonSafe5(path2) {
41976
+ try {
41977
+ return JSON.parse(readFileSync29(path2, "utf-8"));
41978
+ } catch {
41979
+ return null;
41980
+ }
41981
+ }
41982
+ function getAutoState() {
41983
+ if (existsSync28(AUTO_STATE_FILE)) {
41984
+ const state2 = readJsonSafe5(AUTO_STATE_FILE);
41985
+ if (state2)
41986
+ return state2;
41987
+ }
41988
+ return {
41989
+ lastCompact: 0,
41990
+ lastIndex: {},
41991
+ lastDoctor: 0,
41992
+ structureHashes: {},
41993
+ suppressedWarnings: []
41994
+ };
41995
+ }
41996
+ function saveAutoState(state2) {
41997
+ ensureDir5(OMOCS_DIR2);
41998
+ writeFileSync21(AUTO_STATE_FILE, JSON.stringify(state2, null, 2), "utf-8");
41999
+ }
42000
+ function getWorkspaceHash3(cwd) {
42001
+ return createHash6("sha256").update(cwd).digest("hex").substring(0, 16);
42002
+ }
42003
+ function getStructureHash(cwd) {
42004
+ try {
42005
+ const entries = [];
42006
+ const scan = (dir, depth) => {
42007
+ if (depth > 2)
42008
+ return;
42009
+ const items = readdirSync11(dir, { withFileTypes: true });
42010
+ for (const item of items) {
42011
+ if (item.name.startsWith(".") || IGNORED_DIRS3.includes(item.name))
42012
+ continue;
42013
+ if (item.isDirectory()) {
42014
+ entries.push(`d:${item.name}`);
42015
+ scan(join23(dir, item.name), depth + 1);
42016
+ } else if (item.isFile() && WATCHED_EXTS2.includes(extname2(item.name))) {
42017
+ entries.push(`f:${item.name}`);
42018
+ }
42019
+ }
42020
+ };
42021
+ scan(cwd, 0);
42022
+ return createHash6("sha256").update(entries.join("|")).digest("hex").substring(0, 16);
42023
+ } catch {
42024
+ return "";
42025
+ }
42026
+ }
42027
+ function autoCompact(state2) {
42028
+ const results = [];
42029
+ const now = Date.now();
42030
+ if (now - state2.lastCompact < COMPACT_THRESHOLD_DAYS * 24 * 60 * 60 * 1000) {
42031
+ return results;
42032
+ }
42033
+ if (existsSync28(MEMORY_DIR3)) {
42034
+ try {
42035
+ const files = readdirSync11(MEMORY_DIR3).filter((f) => f.endsWith(".json"));
42036
+ let totalEntries = 0;
42037
+ let totalSize = 0;
42038
+ for (const file of files) {
42039
+ const filePath = join23(MEMORY_DIR3, file);
42040
+ totalSize += statSync11(filePath).size;
42041
+ const data = readJsonSafe5(filePath);
42042
+ if (data && Array.isArray(data.notes))
42043
+ totalEntries += data.notes.length;
42044
+ }
42045
+ if (totalEntries > COMPACT_MEMORY_MAX_ENTRIES) {
42046
+ for (const file of files) {
42047
+ const filePath = join23(MEMORY_DIR3, file);
42048
+ const data = readJsonSafe5(filePath);
42049
+ if (data && Array.isArray(data.notes) && data.notes.length > COMPACT_MEMORY_MAX_ENTRIES) {
42050
+ const archiveDir = join23(MEMORY_DIR3, "archive");
42051
+ ensureDir5(archiveDir);
42052
+ const removed = data.notes.splice(0, data.notes.length - COMPACT_MEMORY_MAX_ENTRIES);
42053
+ writeFileSync21(join23(archiveDir, `${basename8(file, ".json")}-auto-${now}.json`), JSON.stringify({ archived: new Date().toISOString(), notes: removed }, null, 2), "utf-8");
42054
+ writeFileSync21(filePath, JSON.stringify(data, null, 2), "utf-8");
42055
+ }
42056
+ }
42057
+ results.push({ action: "auto-compact-memory", status: "fixed", message: `Trimmed memory (${totalEntries} entries → ${COMPACT_MEMORY_MAX_ENTRIES} max per file)` });
42058
+ } else {
42059
+ results.push({ action: "auto-compact-memory", status: "ok", message: `Memory clean (${totalEntries} entries)` });
42060
+ }
42061
+ } catch {}
42062
+ }
42063
+ if (existsSync28(STATS_FILE2)) {
42064
+ try {
42065
+ const data = readJsonSafe5(STATS_FILE2);
42066
+ if (data && data.daily) {
42067
+ const cutoff = now - COMPACT_STATS_MAX_DAYS * 24 * 60 * 60 * 1000;
42068
+ const dates = Object.keys(data.daily);
42069
+ const old = dates.filter((d) => new Date(d).getTime() < cutoff);
42070
+ if (old.length > 0) {
42071
+ const archiveDir = join23(OMOCS_DIR2, "stats-archive");
42072
+ ensureDir5(archiveDir);
42073
+ const archived = {};
42074
+ for (const d of old) {
42075
+ archived[d] = data.daily[d];
42076
+ delete data.daily[d];
42077
+ }
42078
+ writeFileSync21(join23(archiveDir, `stats-auto-${now}.json`), JSON.stringify({ archivedAt: new Date().toISOString(), daily: archived }, null, 2), "utf-8");
42079
+ writeFileSync21(STATS_FILE2, JSON.stringify(data, null, 2), "utf-8");
42080
+ results.push({ action: "auto-compact-stats", status: "fixed", message: `Archived ${old.length} old stats entries` });
42081
+ }
42082
+ }
42083
+ } catch {}
42084
+ }
42085
+ if (existsSync28(INDEX_DIR3)) {
42086
+ try {
42087
+ const dirs = readdirSync11(INDEX_DIR3).filter((d) => {
42088
+ const p = join23(INDEX_DIR3, d);
42089
+ return statSync11(p).isDirectory();
42090
+ });
42091
+ let orphaned = 0;
42092
+ for (const dir of dirs) {
42093
+ const indexPath = join23(INDEX_DIR3, dir, "index.json");
42094
+ if (!existsSync28(indexPath))
42095
+ continue;
42096
+ const data = readJsonSafe5(indexPath);
42097
+ if (data && data.path && !existsSync28(data.path)) {
42098
+ const { unlinkSync: unlinkSync6 } = __require("fs");
42099
+ unlinkSync6(indexPath);
42100
+ orphaned++;
42101
+ }
42102
+ }
42103
+ if (orphaned > 0) {
42104
+ results.push({ action: "auto-compact-index", status: "fixed", message: `Removed ${orphaned} orphaned index(es)` });
42105
+ }
42106
+ } catch {}
42107
+ }
42108
+ state2.lastCompact = now;
42109
+ return results;
42110
+ }
42111
+ function autoIndex(cwd, state2) {
42112
+ const results = [];
42113
+ const wsHash = getWorkspaceHash3(cwd);
42114
+ const now = Date.now();
42115
+ const lastIndexTime = state2.lastIndex[wsHash] || 0;
42116
+ if (now - lastIndexTime < INDEX_STALE_HOURS * 60 * 60 * 1000) {
42117
+ return results;
42118
+ }
42119
+ const currentHash = getStructureHash(cwd);
42120
+ const lastHash = state2.structureHashes[wsHash] || "";
42121
+ if (currentHash && currentHash !== lastHash) {
42122
+ try {
42123
+ const indexDir = join23(INDEX_DIR3, wsHash);
42124
+ ensureDir5(indexDir);
42125
+ const techStack = [];
42126
+ const keyFiles = [];
42127
+ let fileCount = 0;
42128
+ const scan = (dir, depth) => {
42129
+ if (depth > 3)
42130
+ return;
42131
+ try {
42132
+ const items = readdirSync11(dir, { withFileTypes: true });
42133
+ for (const item of items) {
42134
+ if (item.name.startsWith(".") || IGNORED_DIRS3.includes(item.name))
42135
+ continue;
42136
+ if (item.isDirectory())
42137
+ scan(join23(dir, item.name), depth + 1);
42138
+ else if (item.isFile()) {
42139
+ fileCount++;
42140
+ const ext = extname2(item.name);
42141
+ if (ext === ".ts" || ext === ".tsx") {
42142
+ if (!techStack.includes("TypeScript"))
42143
+ techStack.push("TypeScript");
42144
+ }
42145
+ if (ext === ".py") {
42146
+ if (!techStack.includes("Python"))
42147
+ techStack.push("Python");
42148
+ }
42149
+ if (ext === ".go") {
42150
+ if (!techStack.includes("Go"))
42151
+ techStack.push("Go");
42152
+ }
42153
+ if (ext === ".rs") {
42154
+ if (!techStack.includes("Rust"))
42155
+ techStack.push("Rust");
42156
+ }
42157
+ if ([
42158
+ "package.json",
42159
+ "tsconfig.json",
42160
+ "Cargo.toml",
42161
+ "go.mod",
42162
+ "pyproject.toml",
42163
+ "Dockerfile",
42164
+ "docker-compose.yml",
42165
+ "next.config.ts",
42166
+ "next.config.js",
42167
+ "nest-cli.json",
42168
+ "opencode.json",
42169
+ "AGENTS.md"
42170
+ ].includes(item.name)) {
42171
+ keyFiles.push(join23(dir, item.name));
42172
+ }
42173
+ }
42174
+ }
42175
+ } catch {}
42176
+ };
42177
+ scan(cwd, 0);
42178
+ const index = {
42179
+ id: wsHash,
42180
+ path: cwd,
42181
+ builtAt: new Date().toISOString(),
42182
+ techStack,
42183
+ fileCount,
42184
+ keyFiles: keyFiles.map((f) => f.replace(cwd, ".")),
42185
+ autoBuilt: true
42186
+ };
42187
+ writeFileSync21(join23(indexDir, "index.json"), JSON.stringify(index, null, 2), "utf-8");
42188
+ state2.lastIndex[wsHash] = now;
42189
+ state2.structureHashes[wsHash] = currentHash;
42190
+ results.push({ action: "auto-index", status: "fixed", message: `Index rebuilt (${fileCount} files, ${techStack.join("/")})` });
42191
+ } catch {}
42192
+ }
42193
+ return results;
42194
+ }
42195
+ function autoDoctor(cwd, state2) {
42196
+ const results = [];
42197
+ const now = Date.now();
42198
+ if (now - state2.lastDoctor < 24 * 60 * 60 * 1000)
42199
+ return results;
42200
+ const warnings = [];
42201
+ const configLocations = ["opencode.json", join23(".opencode", "opencode.json")];
42202
+ const hasConfig = configLocations.some((l) => existsSync28(join23(cwd, l)));
42203
+ if (!hasConfig) {
42204
+ warnings.push("No opencode.json found — run `omocs init` to set up");
42205
+ }
42206
+ if (!existsSync28(join23(cwd, "AGENTS.md"))) {
42207
+ warnings.push("No AGENTS.md — run `omocs watch generate` or `omocs init-deep`");
42208
+ }
42209
+ const gitignorePath = join23(cwd, ".gitignore");
42210
+ if (existsSync28(gitignorePath)) {
42211
+ const gitignore = readFileSync29(gitignorePath, "utf-8");
42212
+ if (!gitignore.includes(".opencode")) {
42213
+ warnings.push(".opencode not in .gitignore — sessions/cache may be committed");
42214
+ }
42215
+ }
42216
+ if (existsSync28(OMOCS_DIR2)) {
42217
+ try {
42218
+ let totalSize = 0;
42219
+ const checkSize = (dir) => {
42220
+ const items = readdirSync11(dir, { withFileTypes: true });
42221
+ for (const item of items) {
42222
+ const p = join23(dir, item.name);
42223
+ if (item.isFile())
42224
+ totalSize += statSync11(p).size;
42225
+ else if (item.isDirectory())
42226
+ checkSize(p);
42227
+ }
42228
+ };
42229
+ checkSize(OMOCS_DIR2);
42230
+ if (totalSize > 50 * 1024 * 1024) {
42231
+ warnings.push(`~/.omocs is ${(totalSize / 1024 / 1024).toFixed(0)}MB — run \`omocs compact all --fix\``);
42232
+ }
42233
+ } catch {}
42234
+ }
42235
+ const unsuppressed = warnings.filter((w) => !state2.suppressedWarnings.includes(w));
42236
+ if (unsuppressed.length > 0) {
42237
+ results.push({
42238
+ action: "auto-doctor",
42239
+ status: "warn",
42240
+ message: unsuppressed.join("; ")
42241
+ });
42242
+ } else {
42243
+ results.push({ action: "auto-doctor", status: "ok", message: "Workspace healthy" });
42244
+ }
42245
+ state2.lastDoctor = now;
42246
+ return results;
42247
+ }
42248
+ function autoTemplateSuggest(cwd, state2) {
42249
+ const results = [];
42250
+ const configLocations = ["opencode.json", join23(".opencode", "opencode.json")];
42251
+ const hasConfig = configLocations.some((l) => existsSync28(join23(cwd, l)));
42252
+ if (hasConfig)
42253
+ return results;
42254
+ if (!existsSync28(TEMPLATE_DIR2))
42255
+ return results;
42256
+ try {
42257
+ const templates = readdirSync11(TEMPLATE_DIR2).filter((d) => {
42258
+ const manifestPath = join23(TEMPLATE_DIR2, d, "manifest.json");
42259
+ return existsSync28(manifestPath);
42260
+ });
42261
+ if (templates.length > 0) {
42262
+ let projectType = "unknown";
42263
+ if (existsSync28(join23(cwd, "package.json"))) {
42264
+ const pkg = readJsonSafe5(join23(cwd, "package.json"));
42265
+ if (pkg) {
42266
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
42267
+ if (deps["next"])
42268
+ projectType = "nextjs";
42269
+ else if (deps["@nestjs/core"])
42270
+ projectType = "nestjs";
42271
+ else if (deps["react"])
42272
+ projectType = "react";
42273
+ else if (deps["vue"])
42274
+ projectType = "vue";
42275
+ else
42276
+ projectType = "node";
42277
+ }
42278
+ } else if (existsSync28(join23(cwd, "Cargo.toml")))
42279
+ projectType = "rust";
42280
+ else if (existsSync28(join23(cwd, "go.mod")))
42281
+ projectType = "go";
42282
+ else if (existsSync28(join23(cwd, "pyproject.toml")))
42283
+ projectType = "python";
42284
+ for (const t of templates) {
42285
+ const manifest = readJsonSafe5(join23(TEMPLATE_DIR2, t, "manifest.json"));
42286
+ if (manifest && manifest.tags) {
42287
+ const tags = manifest.tags;
42288
+ if (tags.includes(projectType) || tags.includes("fullstack")) {
42289
+ results.push({
42290
+ action: "auto-template",
42291
+ status: "warn",
42292
+ message: `Template "${manifest.name}" matches this ${projectType} project → omocs template load ${manifest.name}`
42293
+ });
42294
+ break;
42295
+ }
42296
+ }
42297
+ }
42298
+ }
42299
+ } catch {}
42300
+ return results;
42301
+ }
42302
+ async function runAutoChecks(cwd, opts) {
42303
+ const state2 = getAutoState();
42304
+ const allResults = [];
42305
+ allResults.push(...autoDoctor(cwd, state2));
42306
+ allResults.push(...autoIndex(cwd, state2));
42307
+ if (!opts?.skipCompact) {
42308
+ allResults.push(...autoCompact(state2));
42309
+ }
42310
+ allResults.push(...autoTemplateSuggest(cwd, state2));
42311
+ saveAutoState(state2);
42312
+ if (!opts?.silent) {
42313
+ const warnings = allResults.filter((r) => r.status === "warn");
42314
+ const fixes = allResults.filter((r) => r.status === "fixed");
42315
+ if (warnings.length > 0 || fixes.length > 0) {
42316
+ console.log(source_default.dim(" ── omocs auto ──"));
42317
+ for (const r of fixes) {
42318
+ console.log(` ${source_default.green("⚡")} ${source_default.dim(r.message)}`);
42319
+ }
42320
+ for (const r of warnings) {
42321
+ console.log(` ${source_default.yellow("⚠")} ${source_default.dim(r.message)}`);
42322
+ }
42323
+ console.log("");
42324
+ }
42325
+ }
42326
+ return allResults;
42327
+ }
42328
+ function suppressWarning(warning) {
42329
+ const state2 = getAutoState();
42330
+ if (!state2.suppressedWarnings.includes(warning)) {
42331
+ state2.suppressedWarnings.push(warning);
42332
+ saveAutoState(state2);
42333
+ }
42334
+ }
42335
+ function resetAutoState() {
42336
+ const state2 = {
42337
+ lastCompact: 0,
42338
+ lastIndex: {},
42339
+ lastDoctor: 0,
42340
+ structureHashes: {},
42341
+ suppressedWarnings: []
42342
+ };
42343
+ saveAutoState(state2);
42344
+ }
42345
+ var OMOCS_DIR2, AUTO_STATE_FILE, INDEX_DIR3, MEMORY_DIR3, STATS_FILE2, TEMPLATE_DIR2, COMPACT_THRESHOLD_DAYS = 7, COMPACT_MEMORY_MAX_ENTRIES = 100, COMPACT_STATS_MAX_DAYS = 60, INDEX_STALE_HOURS = 24, IGNORED_DIRS3, WATCHED_EXTS2;
42346
+ var init_auto = __esm(() => {
42347
+ init_source();
42348
+ OMOCS_DIR2 = join23(homedir17(), ".omocs");
42349
+ AUTO_STATE_FILE = join23(OMOCS_DIR2, "auto-state.json");
42350
+ INDEX_DIR3 = join23(OMOCS_DIR2, "workspaces");
42351
+ MEMORY_DIR3 = join23(OMOCS_DIR2, "memory");
42352
+ STATS_FILE2 = join23(OMOCS_DIR2, "stats.json");
42353
+ TEMPLATE_DIR2 = join23(OMOCS_DIR2, "templates");
42354
+ IGNORED_DIRS3 = ["node_modules", ".git", "dist", "build", ".next", "__pycache__", "coverage", ".opencode", ".venv", "vendor"];
42355
+ WATCHED_EXTS2 = [".ts", ".tsx", ".js", ".jsx", ".py", ".go", ".rs", ".java", ".rb", ".php", ".vue", ".svelte"];
42356
+ });
42357
+
42358
+ // src/commands/auto.ts
42359
+ function registerAutoCommand(program2) {
42360
+ const auto = program2.command("auto").description("Manage automatic background checks (doctor, index, compact, template)");
42361
+ auto.command("run").description("Run all auto checks now").option("--verbose", "Show all results including OK statuses").action(async (opts) => {
42362
+ try {
42363
+ heading("⚡ Auto Checks");
42364
+ info(`Workspace: ${source_default.gray(process.cwd())}`);
42365
+ console.log("");
42366
+ const results = await runAutoChecks(process.cwd(), { silent: true });
42367
+ if (results.length === 0) {
42368
+ success("Nothing to check.");
42369
+ return;
42370
+ }
42371
+ for (const r of results) {
42372
+ if (r.status === "ok" && !opts.verbose)
42373
+ continue;
42374
+ const icon = r.status === "ok" ? source_default.green("✅") : r.status === "fixed" ? source_default.green("⚡") : source_default.yellow("⚠️");
42375
+ console.log(` ${icon} ${source_default.bold(r.action)} — ${r.message}`);
42376
+ }
42377
+ const ok = results.filter((r) => r.status === "ok").length;
42378
+ const fixed = results.filter((r) => r.status === "fixed").length;
42379
+ const warned = results.filter((r) => r.status === "warn").length;
42380
+ console.log("");
42381
+ info(`OK: ${ok} | Fixed: ${fixed} | Warnings: ${warned}`);
42382
+ } catch (err) {
42383
+ handleError(err);
42384
+ }
42385
+ });
42386
+ auto.command("reset").description("Reset auto state (force re-run all checks)").action(() => {
42387
+ try {
42388
+ resetAutoState();
42389
+ success("Auto state reset. All checks will re-run on next invocation.");
42390
+ } catch (err) {
42391
+ handleError(err);
42392
+ }
42393
+ });
42394
+ auto.command("suppress <warning>").description("Suppress a specific auto warning").action((warning) => {
42395
+ try {
42396
+ suppressWarning(warning);
42397
+ success(`Suppressed: "${warning}"`);
42398
+ } catch (err) {
42399
+ handleError(err);
42400
+ }
42401
+ });
42402
+ auto.command("status").description("Show auto check state").action(() => {
42403
+ try {
42404
+ heading("⚡ Auto Status");
42405
+ const { existsSync: existsSync29, readFileSync: readFileSync30 } = __require("fs");
42406
+ const { join: join24 } = __require("path");
42407
+ const { homedir: homedir18 } = __require("os");
42408
+ const stateFile = join24(homedir18(), ".omocs", "auto-state.json");
42409
+ if (!existsSync29(stateFile)) {
42410
+ info("No auto state yet. Run `omocs auto run` to initialize.");
42411
+ return;
42412
+ }
42413
+ const state2 = JSON.parse(readFileSync30(stateFile, "utf-8"));
42414
+ const formatTime2 = (ts) => ts ? new Date(ts).toLocaleString() : "never";
42415
+ console.log(` ${source_default.dim("Last compact:")} ${formatTime2(state2.lastCompact)}`);
42416
+ console.log(` ${source_default.dim("Last doctor:")} ${formatTime2(state2.lastDoctor)}`);
42417
+ console.log(` ${source_default.dim("Indexed workspaces:")} ${Object.keys(state2.lastIndex || {}).length}`);
42418
+ console.log(` ${source_default.dim("Suppressed warnings:")} ${(state2.suppressedWarnings || []).length}`);
42419
+ if (state2.suppressedWarnings?.length > 0) {
42420
+ console.log("");
42421
+ info("Suppressed:");
42422
+ for (const w of state2.suppressedWarnings) {
42423
+ console.log(` ${source_default.gray("•")} ${source_default.dim(w)}`);
42424
+ }
42425
+ }
42426
+ } catch (err) {
42427
+ handleError(err);
42428
+ }
42429
+ });
42430
+ auto.action(() => {
42431
+ heading("⚡ Auto Checks");
42432
+ infoBox("Auto", [
42433
+ "Automatic background checks run on every omocs command.",
42434
+ "",
42435
+ ` ${source_default.cyan("omocs auto run")} — run all checks now`,
42436
+ ` ${source_default.cyan("omocs auto status")} — show check state`,
42437
+ ` ${source_default.cyan("omocs auto reset")} — force re-run all`,
42438
+ ` ${source_default.cyan("omocs auto suppress")} — hide a warning`,
42439
+ "",
42440
+ "Checks: doctor, index rebuild, compact, template suggest",
42441
+ "Auto-runs on startup (non-blocking, max every 24h)."
42442
+ ].join(`
42443
+ `));
42444
+ });
42445
+ }
42446
+ var init_auto2 = __esm(() => {
42447
+ init_source();
42448
+ init_auto();
42449
+ init_ui();
42450
+ });
42451
+
41966
42452
  // src/index.ts
41967
42453
  var exports_src = {};
41968
42454
  __export(exports_src, {
@@ -42000,17 +42486,24 @@ var init_src = __esm(() => {
42000
42486
  init_watch();
42001
42487
  init_marketplace();
42002
42488
  init_squad();
42489
+ init_auto2();
42490
+ init_auto();
42003
42491
  init_find_package_json();
42004
42492
  pkg = readPackageJson(import.meta.url);
42005
42493
  VERSION3 = pkg.version;
42006
42494
  program2 = new Command;
42007
- program2.name("omocs").description("OMO Suites — CLI toolkit for OpenCode power users").version(VERSION3, "-v, --version", "Show version").hook("preAction", () => {
42495
+ program2.name("omocs").description("OMO Suites — CLI toolkit for OpenCode power users").version(VERSION3, "-v, --version", "Show version").hook("preAction", (thisCommand) => {
42008
42496
  process.on("uncaughtException", (error) => {
42009
42497
  handleError(error);
42010
42498
  });
42011
42499
  process.on("unhandledRejection", (error) => {
42012
42500
  handleError(error);
42013
42501
  });
42502
+ const cmdName = thisCommand.args?.[0] || thisCommand.name();
42503
+ const skipAuto = ["auto", "completion", "help"].includes(cmdName);
42504
+ if (!skipAuto) {
42505
+ runAutoChecks(process.cwd(), { silent: false }).catch(() => {});
42506
+ }
42014
42507
  });
42015
42508
  registerInitCommand(program2);
42016
42509
  registerDoctorCommand(program2);
@@ -42041,6 +42534,7 @@ var init_src = __esm(() => {
42041
42534
  registerWatchCommand(program2);
42042
42535
  registerMarketplaceCommand(program2);
42043
42536
  registerSquadCommand(program2);
42537
+ registerAutoCommand(program2);
42044
42538
  program2.action(() => {
42045
42539
  showBanner();
42046
42540
  program2.help();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omo-suites",
3
- "version": "1.13.0",
3
+ "version": "1.14.0",
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",