@ftarganski/omni-ai 1.1.10 → 1.2.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/dist/cli/bin.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  } from "../chunk-AU3KUCI7.js";
9
9
 
10
10
  // ../../packages/cli/dist/bin.js
11
- import { dirname as dirname4, resolve as resolve17 } from "path";
11
+ import { dirname as dirname5, resolve as resolve17 } from "path";
12
12
  import { fileURLToPath as fileURLToPath3 } from "url";
13
13
  import { Command } from "commander";
14
14
  import { config as loadDotenv } from "dotenv";
@@ -1155,13 +1155,888 @@ async function exportCommand(sessionArg, opts) {
1155
1155
  ${messages.length} message(s) exported.`));
1156
1156
  }
1157
1157
 
1158
+ // ../../packages/cli/dist/commands/history/doctor.js
1159
+ import { existsSync } from "fs";
1160
+ import chalk5 from "chalk";
1161
+
1162
+ // ../../packages/history/dist/parsers/claude-code.js
1163
+ import { readdir as readdir4, readFile as readFile6, stat } from "fs/promises";
1164
+ import { homedir } from "os";
1165
+ import { join as join4 } from "path";
1166
+ import { glob } from "glob";
1167
+ function extractContent(message) {
1168
+ const raw = message?.content;
1169
+ if (typeof raw === "string")
1170
+ return { content: raw };
1171
+ if (Array.isArray(raw)) {
1172
+ const blocks = raw;
1173
+ const text = blocks.map((b) => {
1174
+ if (b.type === "text")
1175
+ return b.text ?? "";
1176
+ if (b.type === "tool_use")
1177
+ return `[tool_use:${b.name}] ${JSON.stringify(b.input ?? {})}`;
1178
+ if (b.type === "tool_result")
1179
+ return typeof b.content === "string" ? b.content : JSON.stringify(b.content);
1180
+ return "";
1181
+ }).filter(Boolean).join("\n");
1182
+ const toolUse = blocks.find((b) => b.type === "tool_use");
1183
+ return { content: text, toolName: toolUse?.name };
1184
+ }
1185
+ return { content: "" };
1186
+ }
1187
+ function defaultClaudeCodeRoot() {
1188
+ return join4(homedir(), ".claude", "projects");
1189
+ }
1190
+ async function parseTranscriptFile(file, provider, scope) {
1191
+ const raw = await readFile6(file, "utf-8");
1192
+ const lines = raw.split("\n").filter((l) => l.trim().length > 0);
1193
+ const events = [];
1194
+ const citations = [];
1195
+ let ordinal = 0;
1196
+ lines.forEach((line, lineIndex) => {
1197
+ let entry;
1198
+ try {
1199
+ entry = JSON.parse(line);
1200
+ } catch {
1201
+ return;
1202
+ }
1203
+ const type = typeof entry.type === "string" ? entry.type : void 0;
1204
+ const message = entry.message;
1205
+ if (!message || type !== "user" && type !== "assistant")
1206
+ return;
1207
+ const { content, toolName } = extractContent(message);
1208
+ if (!content)
1209
+ return;
1210
+ const timestamp = typeof entry.timestamp === "string" ? Date.parse(entry.timestamp) : Number.NaN;
1211
+ events.push({
1212
+ role: message.role ?? type ?? "user",
1213
+ content,
1214
+ toolName,
1215
+ ordinal: ordinal++,
1216
+ timestamp: Number.isNaN(timestamp) ? Date.now() : timestamp
1217
+ });
1218
+ citations.push({ sourcePath: file, sourceLine: lineIndex + 1 });
1219
+ });
1220
+ if (events.length === 0)
1221
+ return null;
1222
+ const sourceSessionId = file.replace(/\.jsonl$/, "").split(/[/\\]/).pop() ?? file;
1223
+ return {
1224
+ session: {
1225
+ id: `${provider}:${scope ?? ""}:${sourceSessionId}`,
1226
+ provider,
1227
+ sourceSessionId,
1228
+ importedAt: Date.now(),
1229
+ scope
1230
+ },
1231
+ events,
1232
+ citations
1233
+ };
1234
+ }
1235
+ var ClaudeCodeHistoryParser = class {
1236
+ provider = "claude-code";
1237
+ root;
1238
+ constructor(options = {}) {
1239
+ this.root = options.root ?? defaultClaudeCodeRoot();
1240
+ }
1241
+ async discover() {
1242
+ const id = `${this.provider}:${this.root}`;
1243
+ const base = {
1244
+ id,
1245
+ provider: this.provider,
1246
+ path: this.root,
1247
+ nativeImport: true
1248
+ };
1249
+ let entries;
1250
+ try {
1251
+ const info = await stat(this.root);
1252
+ if (!info.isDirectory()) {
1253
+ return [{ ...base, importable: false, reason: "path is not a directory" }];
1254
+ }
1255
+ entries = await readdir4(this.root, { withFileTypes: true });
1256
+ } catch {
1257
+ return [{ ...base, importable: false, reason: "history directory not found" }];
1258
+ }
1259
+ const sources = [];
1260
+ const looseFiles = await glob("*.jsonl", { cwd: this.root });
1261
+ if (looseFiles.length > 0) {
1262
+ sources.push({ ...base, importable: true });
1263
+ }
1264
+ for (const entry of entries) {
1265
+ if (!entry.isDirectory())
1266
+ continue;
1267
+ const dir = join4(this.root, entry.name);
1268
+ const files = await glob("**/*.jsonl", { cwd: dir });
1269
+ if (files.length === 0)
1270
+ continue;
1271
+ sources.push({
1272
+ id: `${this.provider}:${dir}`,
1273
+ provider: this.provider,
1274
+ path: dir,
1275
+ nativeImport: true,
1276
+ importable: true,
1277
+ scope: entry.name
1278
+ });
1279
+ }
1280
+ if (sources.length === 0) {
1281
+ return [{ ...base, importable: false, reason: "no .jsonl transcripts found" }];
1282
+ }
1283
+ return sources;
1284
+ }
1285
+ async import(source) {
1286
+ const files = await glob("**/*.jsonl", { cwd: source.path, absolute: true });
1287
+ const results = [];
1288
+ for (const file of files) {
1289
+ const result = await parseTranscriptFile(file, source.provider, source.scope);
1290
+ if (result)
1291
+ results.push(result);
1292
+ }
1293
+ return results;
1294
+ }
1295
+ };
1296
+
1297
+ // ../../packages/history/dist/parsers/codex.js
1298
+ import { readFile as readFile7, stat as stat2 } from "fs/promises";
1299
+ import { homedir as homedir2 } from "os";
1300
+ import { join as join5 } from "path";
1301
+ import { glob as glob2 } from "glob";
1302
+
1303
+ // ../../packages/history/dist/store.js
1304
+ import { mkdirSync } from "fs";
1305
+ import { dirname as dirname3 } from "path";
1306
+ import Database2 from "better-sqlite3";
1307
+ var sourceFromRow = (r) => ({
1308
+ id: r.id,
1309
+ provider: r.provider,
1310
+ path: r.path,
1311
+ nativeImport: Boolean(r.native_import),
1312
+ importable: Boolean(r.importable),
1313
+ reason: r.reason ?? void 0,
1314
+ scope: r.scope || void 0
1315
+ });
1316
+ var sessionFromRow = (r) => ({
1317
+ id: r.id,
1318
+ provider: r.provider,
1319
+ sourceSessionId: r.source_session_id,
1320
+ importedAt: r.imported_at,
1321
+ scope: r.scope || void 0
1322
+ });
1323
+ var eventFromRow = (r) => ({
1324
+ id: r.id,
1325
+ sessionId: r.session_id,
1326
+ role: r.role,
1327
+ content: r.content,
1328
+ toolName: r.tool_name ?? void 0,
1329
+ ordinal: r.ordinal,
1330
+ timestamp: r.ts
1331
+ });
1332
+ var HistoryStore = class {
1333
+ db;
1334
+ constructor(options = {}) {
1335
+ const path = options.path ?? "./omni-ai-history.db";
1336
+ mkdirSync(dirname3(path), { recursive: true });
1337
+ this.db = new Database2(path);
1338
+ this.db.pragma("journal_mode = WAL");
1339
+ this.migrate();
1340
+ }
1341
+ migrate() {
1342
+ this.db.exec(`
1343
+ CREATE TABLE IF NOT EXISTS sources (
1344
+ id TEXT PRIMARY KEY,
1345
+ provider TEXT NOT NULL,
1346
+ path TEXT NOT NULL,
1347
+ native_import INTEGER NOT NULL,
1348
+ importable INTEGER NOT NULL,
1349
+ reason TEXT,
1350
+ scope TEXT NOT NULL DEFAULT ''
1351
+ );
1352
+
1353
+ CREATE TABLE IF NOT EXISTS sessions (
1354
+ id TEXT PRIMARY KEY,
1355
+ provider TEXT NOT NULL,
1356
+ source_session_id TEXT NOT NULL,
1357
+ imported_at INTEGER NOT NULL,
1358
+ scope TEXT NOT NULL DEFAULT '',
1359
+ UNIQUE (provider, scope, source_session_id)
1360
+ );
1361
+ CREATE INDEX IF NOT EXISTS idx_sessions_scope ON sessions (scope);
1362
+
1363
+ CREATE TABLE IF NOT EXISTS events (
1364
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
1365
+ session_id TEXT NOT NULL REFERENCES sessions (id),
1366
+ role TEXT NOT NULL,
1367
+ content TEXT NOT NULL,
1368
+ tool_name TEXT,
1369
+ ordinal INTEGER NOT NULL,
1370
+ ts INTEGER NOT NULL
1371
+ );
1372
+ CREATE INDEX IF NOT EXISTS idx_events_session ON events (session_id, ordinal);
1373
+
1374
+ CREATE VIRTUAL TABLE IF NOT EXISTS events_fts USING fts5(
1375
+ content,
1376
+ content='events',
1377
+ content_rowid='id'
1378
+ );
1379
+
1380
+ CREATE TRIGGER IF NOT EXISTS events_ai AFTER INSERT ON events BEGIN
1381
+ INSERT INTO events_fts (rowid, content) VALUES (new.id, new.content);
1382
+ END;
1383
+
1384
+ CREATE TABLE IF NOT EXISTS citations (
1385
+ event_id INTEGER NOT NULL REFERENCES events (id),
1386
+ source_path TEXT NOT NULL,
1387
+ source_line INTEGER,
1388
+ PRIMARY KEY (event_id)
1389
+ );
1390
+ `);
1391
+ }
1392
+ upsertSource(source) {
1393
+ this.db.prepare(`INSERT INTO sources (id, provider, path, native_import, importable, reason, scope)
1394
+ VALUES (@id, @provider, @path, @nativeImport, @importable, @reason, @scope)
1395
+ ON CONFLICT (id) DO UPDATE SET
1396
+ provider = excluded.provider,
1397
+ path = excluded.path,
1398
+ native_import = excluded.native_import,
1399
+ importable = excluded.importable,
1400
+ reason = excluded.reason,
1401
+ scope = excluded.scope`).run({
1402
+ id: source.id,
1403
+ provider: source.provider,
1404
+ path: source.path,
1405
+ nativeImport: source.nativeImport ? 1 : 0,
1406
+ importable: source.importable ? 1 : 0,
1407
+ reason: source.reason ?? null,
1408
+ scope: source.scope ?? ""
1409
+ });
1410
+ }
1411
+ listSources(provider) {
1412
+ const rows = provider ? this.db.prepare(`SELECT * FROM sources WHERE provider = ? ORDER BY id`).all(provider) : this.db.prepare(`SELECT * FROM sources ORDER BY provider, id`).all();
1413
+ return rows.map(sourceFromRow);
1414
+ }
1415
+ /** Persists one imported session and its events/citations. Idempotent per (provider, scope, sourceSessionId). */
1416
+ saveImportResult(provider, sessionId, result) {
1417
+ const upsertSession = this.db.prepare(`INSERT INTO sessions (id, provider, source_session_id, imported_at, scope)
1418
+ VALUES (@id, @provider, @sourceSessionId, @importedAt, @scope)
1419
+ ON CONFLICT (provider, scope, source_session_id) DO UPDATE SET imported_at = excluded.imported_at`);
1420
+ const insertEvent = this.db.prepare(`INSERT INTO events (session_id, role, content, tool_name, ordinal, ts)
1421
+ VALUES (@sessionId, @role, @content, @toolName, @ordinal, @ts)`);
1422
+ const insertCitation = this.db.prepare(`INSERT INTO citations (event_id, source_path, source_line)
1423
+ VALUES (@eventId, @sourcePath, @sourceLine)
1424
+ ON CONFLICT (event_id) DO UPDATE SET source_path = excluded.source_path, source_line = excluded.source_line`);
1425
+ const deleteCitations = this.db.prepare(`DELETE FROM citations WHERE event_id IN (SELECT id FROM events WHERE session_id = ?)`);
1426
+ const deleteEvents = this.db.prepare(`DELETE FROM events WHERE session_id = ?`);
1427
+ const run = this.db.transaction(() => {
1428
+ upsertSession.run({
1429
+ id: sessionId,
1430
+ provider,
1431
+ sourceSessionId: result.session.sourceSessionId,
1432
+ importedAt: result.session.importedAt,
1433
+ scope: result.session.scope ?? ""
1434
+ });
1435
+ deleteCitations.run(sessionId);
1436
+ deleteEvents.run(sessionId);
1437
+ result.events.forEach((event, i) => {
1438
+ const info = insertEvent.run({
1439
+ sessionId,
1440
+ role: event.role,
1441
+ content: event.content,
1442
+ toolName: event.toolName ?? null,
1443
+ ordinal: event.ordinal,
1444
+ ts: event.timestamp
1445
+ });
1446
+ const citation = result.citations[i];
1447
+ if (citation) {
1448
+ insertCitation.run({
1449
+ eventId: info.lastInsertRowid,
1450
+ sourcePath: citation.sourcePath,
1451
+ sourceLine: citation.sourceLine ?? null
1452
+ });
1453
+ }
1454
+ });
1455
+ });
1456
+ run();
1457
+ }
1458
+ getSession(id) {
1459
+ const row = this.db.prepare(`SELECT * FROM sessions WHERE id = ?`).get(id);
1460
+ return row ? sessionFromRow(row) : null;
1461
+ }
1462
+ listSessions(options = {}) {
1463
+ const clauses = [];
1464
+ const params = [];
1465
+ if (options.provider) {
1466
+ clauses.push("provider = ?");
1467
+ params.push(options.provider);
1468
+ }
1469
+ if (options.scope) {
1470
+ clauses.push("scope = ?");
1471
+ params.push(options.scope);
1472
+ }
1473
+ const where = clauses.length > 0 ? `WHERE ${clauses.join(" AND ")}` : "";
1474
+ const rows = this.db.prepare(`SELECT * FROM sessions ${where} ORDER BY imported_at DESC`).all(...params);
1475
+ return rows.map(sessionFromRow);
1476
+ }
1477
+ listEvents(sessionId) {
1478
+ const rows = this.db.prepare(`SELECT * FROM events WHERE session_id = ? ORDER BY ordinal ASC`).all(sessionId);
1479
+ return rows.map(eventFromRow);
1480
+ }
1481
+ getEvent(id) {
1482
+ const row = this.db.prepare(`SELECT * FROM events WHERE id = ?`).get(id);
1483
+ return row ? eventFromRow(row) : null;
1484
+ }
1485
+ /** Events immediately before/after `id` within the same session, `id` included. */
1486
+ getEventWindow(id, window) {
1487
+ const center = this.getEvent(id);
1488
+ if (!center)
1489
+ return [];
1490
+ const rows = this.db.prepare(`SELECT * FROM events
1491
+ WHERE session_id = ? AND ordinal BETWEEN ? AND ?
1492
+ ORDER BY ordinal ASC`).all(center.sessionId, center.ordinal - window, center.ordinal + window);
1493
+ return rows.map(eventFromRow);
1494
+ }
1495
+ getCitation(eventId) {
1496
+ const row = this.db.prepare(`SELECT * FROM citations WHERE event_id = ?`).get(eventId);
1497
+ return row ? { eventId: row.event_id, sourcePath: row.source_path, sourceLine: row.source_line ?? void 0 } : null;
1498
+ }
1499
+ /**
1500
+ * Full-text search over event content. Session-diverse by default: at most `groupLimit`
1501
+ * hits per session so one large session can't crowd out the rest of the result page.
1502
+ *
1503
+ * Scoped by default in spirit — callers (CLI, MCP skills) are expected to pass `scope`
1504
+ * for project-aware providers so an agent working in one project never sees another
1505
+ * project's imported history. Omitting `scope` searches across every scope.
1506
+ */
1507
+ search(query, options = {}) {
1508
+ const limit = options.limit ?? 20;
1509
+ const groupLimit = options.groupLimit ?? 3;
1510
+ const clauses = ["fts.content MATCH @query"];
1511
+ const params = { query };
1512
+ if (options.sessionId) {
1513
+ clauses.push("e.session_id = @sessionId");
1514
+ params.sessionId = options.sessionId;
1515
+ }
1516
+ if (options.scope) {
1517
+ clauses.push("s.scope = @scope");
1518
+ params.scope = options.scope;
1519
+ }
1520
+ const rows = this.db.prepare(`SELECT e.*, rank AS score FROM events_fts fts
1521
+ JOIN events e ON e.id = fts.rowid
1522
+ JOIN sessions s ON s.id = e.session_id
1523
+ WHERE ${clauses.join(" AND ")}
1524
+ ORDER BY rank`).all(params);
1525
+ const perSession = /* @__PURE__ */ new Map();
1526
+ const sessionCache = /* @__PURE__ */ new Map();
1527
+ const hits = [];
1528
+ for (const row of rows) {
1529
+ if (hits.length >= limit)
1530
+ break;
1531
+ const count = perSession.get(row.session_id) ?? 0;
1532
+ if (count >= groupLimit)
1533
+ continue;
1534
+ let session = sessionCache.get(row.session_id);
1535
+ if (session === void 0) {
1536
+ session = this.getSession(row.session_id);
1537
+ sessionCache.set(row.session_id, session);
1538
+ }
1539
+ if (!session)
1540
+ continue;
1541
+ perSession.set(row.session_id, count + 1);
1542
+ hits.push({ event: eventFromRow(row), session, score: row.score });
1543
+ }
1544
+ return hits;
1545
+ }
1546
+ listCitations() {
1547
+ const rows = this.db.prepare(`SELECT * FROM citations`).all();
1548
+ return rows.map((r) => ({
1549
+ eventId: r.event_id,
1550
+ sourcePath: r.source_path,
1551
+ sourceLine: r.source_line ?? void 0
1552
+ }));
1553
+ }
1554
+ close() {
1555
+ this.db.close();
1556
+ }
1557
+ };
1558
+
1559
+ // ../../packages/history/dist/skills.js
1560
+ function defaultHistoryDbPath() {
1561
+ const home = process.env.HOME ?? process.env.USERPROFILE ?? ".";
1562
+ return `${home}/.omni-ai/history.db`;
1563
+ }
1564
+ function encodeProjectScope(absPath) {
1565
+ return absPath.replace(/[^a-zA-Z0-9]/g, "-");
1566
+ }
1567
+ var searchHistorySkill = {
1568
+ name: "search-history",
1569
+ description: "Full-text search over already-imported third-party AI agent history (run `omni history import` first to populate it). Scoped to the caller's own project by default \u2014 pass allProjects:true to search every imported project.",
1570
+ async execute(input5) {
1571
+ const scope = input5.allProjects ? void 0 : input5.scope ?? encodeProjectScope(process.cwd());
1572
+ const store = new HistoryStore({ path: defaultHistoryDbPath() });
1573
+ try {
1574
+ const hits = store.search(input5.query, { scope, limit: input5.limit });
1575
+ return { scope: scope ?? null, hits };
1576
+ } finally {
1577
+ store.close();
1578
+ }
1579
+ }
1580
+ };
1581
+ var showEventSkill = {
1582
+ name: "show-history-event",
1583
+ description: "Show one imported history event with N events of surrounding context. Refuses events that belong to a different project scope than the caller's, unless allProjects:true is passed.",
1584
+ async execute(input5) {
1585
+ const store = new HistoryStore({ path: defaultHistoryDbPath() });
1586
+ try {
1587
+ const center = store.getEvent(input5.eventId);
1588
+ if (!center)
1589
+ return { events: [] };
1590
+ if (!input5.allProjects) {
1591
+ const session = store.getSession(center.sessionId);
1592
+ const callerScope = encodeProjectScope(process.cwd());
1593
+ if (session?.scope && session.scope !== callerScope) {
1594
+ throw new Error(`Event ${input5.eventId} belongs to a different project scope ("${session.scope}"). Pass allProjects:true to override.`);
1595
+ }
1596
+ }
1597
+ return { events: store.getEventWindow(input5.eventId, input5.window ?? 3) };
1598
+ } finally {
1599
+ store.close();
1600
+ }
1601
+ }
1602
+ };
1603
+
1604
+ // ../../packages/history/dist/parsers/codex.js
1605
+ function defaultCodexRoot() {
1606
+ return join5(homedir2(), ".codex", "sessions");
1607
+ }
1608
+ var CodexHistoryParser = class {
1609
+ provider = "codex";
1610
+ root;
1611
+ constructor(options = {}) {
1612
+ this.root = options.root ?? defaultCodexRoot();
1613
+ }
1614
+ async discover() {
1615
+ const id = `${this.provider}:${this.root}`;
1616
+ const base = {
1617
+ id,
1618
+ provider: this.provider,
1619
+ path: this.root,
1620
+ nativeImport: true
1621
+ };
1622
+ try {
1623
+ const info = await stat2(this.root);
1624
+ if (!info.isDirectory()) {
1625
+ return [{ ...base, importable: false, reason: "path is not a directory" }];
1626
+ }
1627
+ } catch {
1628
+ return [{ ...base, importable: false, reason: "history directory not found" }];
1629
+ }
1630
+ const files = await glob2("*.json", { cwd: this.root });
1631
+ if (files.length === 0) {
1632
+ return [{ ...base, importable: false, reason: "no session state files found" }];
1633
+ }
1634
+ return [{ ...base, importable: true }];
1635
+ }
1636
+ async import(source) {
1637
+ const files = await glob2("*.json", { cwd: source.path, absolute: true });
1638
+ const results = [];
1639
+ for (const file of files) {
1640
+ let parsed;
1641
+ try {
1642
+ parsed = JSON.parse(await readFile7(file, "utf-8"));
1643
+ } catch {
1644
+ continue;
1645
+ }
1646
+ const messages = Array.isArray(parsed.messages) ? parsed.messages : [];
1647
+ const events = [];
1648
+ const citations = [];
1649
+ let ordinal = 0;
1650
+ for (const m of messages) {
1651
+ if (!m || typeof m.content !== "string" || !m.content)
1652
+ continue;
1653
+ const timestamp = typeof m.timestamp === "string" ? Date.parse(m.timestamp) : Number.NaN;
1654
+ events.push({
1655
+ role: m.role ?? "user",
1656
+ content: m.content,
1657
+ toolName: m.toolName,
1658
+ ordinal: ordinal++,
1659
+ timestamp: Number.isNaN(timestamp) ? Date.now() : timestamp
1660
+ });
1661
+ citations.push({ sourcePath: file });
1662
+ }
1663
+ if (events.length === 0)
1664
+ continue;
1665
+ const sourceSessionId = parsed.id ?? file.replace(/\.json$/, "").split(/[/\\]/).pop() ?? file;
1666
+ const scope = parsed.cwd ? encodeProjectScope(parsed.cwd) : void 0;
1667
+ results.push({
1668
+ session: {
1669
+ id: `${source.provider}:${scope ?? ""}:${sourceSessionId}`,
1670
+ provider: source.provider,
1671
+ sourceSessionId,
1672
+ importedAt: Date.now(),
1673
+ scope
1674
+ },
1675
+ events,
1676
+ citations
1677
+ });
1678
+ }
1679
+ return results;
1680
+ }
1681
+ };
1682
+
1683
+ // ../../packages/history/dist/registry.js
1684
+ var HistoryParserRegistry = class {
1685
+ parsers = /* @__PURE__ */ new Map();
1686
+ register(parser) {
1687
+ this.parsers.set(parser.provider, parser);
1688
+ }
1689
+ get(provider) {
1690
+ return this.parsers.get(provider);
1691
+ }
1692
+ list() {
1693
+ return [...this.parsers.values()];
1694
+ }
1695
+ };
1696
+
1697
+ // ../../packages/cli/dist/commands/history/shared.js
1698
+ function getHistoryDbPath() {
1699
+ const home = process.env.HOME ?? process.env.USERPROFILE ?? ".";
1700
+ return `${home}/.omni-ai/history.db`;
1701
+ }
1702
+ function buildHistoryRegistry() {
1703
+ const registry = new HistoryParserRegistry();
1704
+ registry.register(new ClaudeCodeHistoryParser());
1705
+ registry.register(new CodexHistoryParser());
1706
+ return registry;
1707
+ }
1708
+ function openHistoryStore() {
1709
+ return new HistoryStore({ path: getHistoryDbPath() });
1710
+ }
1711
+
1712
+ // ../../packages/cli/dist/commands/history/doctor.js
1713
+ async function historyDoctorCommand(opts) {
1714
+ const store = openHistoryStore();
1715
+ try {
1716
+ const sources = store.listSources();
1717
+ const sessions = store.listSessions();
1718
+ const citations = store.listCitations();
1719
+ const notImportable = sources.filter((s) => !s.importable);
1720
+ const pathExists = /* @__PURE__ */ new Map();
1721
+ let brokenCitations = 0;
1722
+ for (const citation of citations) {
1723
+ let exists = pathExists.get(citation.sourcePath);
1724
+ if (exists === void 0) {
1725
+ exists = existsSync(citation.sourcePath);
1726
+ pathExists.set(citation.sourcePath, exists);
1727
+ }
1728
+ if (!exists)
1729
+ brokenCitations++;
1730
+ }
1731
+ const report = {
1732
+ sources: sources.length,
1733
+ notImportable: notImportable.map((s) => ({ provider: s.provider, path: s.path, reason: s.reason })),
1734
+ sessions: sessions.length,
1735
+ events: citations.length,
1736
+ brokenCitations
1737
+ };
1738
+ if (opts.json) {
1739
+ console.log(JSON.stringify(report, null, 2));
1740
+ return;
1741
+ }
1742
+ console.log(chalk5.bold("omni history doctor\n"));
1743
+ console.log(` sources: ${report.sources}`);
1744
+ console.log(` not importable: ${notImportable.length}`);
1745
+ for (const s of notImportable) {
1746
+ console.log(` ${chalk5.yellow("-")} ${s.provider}: ${s.reason} (${s.path})`);
1747
+ }
1748
+ console.log(` sessions: ${report.sessions}`);
1749
+ console.log(` citations: ${report.events}`);
1750
+ console.log(` broken citations: ${brokenCitations > 0 ? chalk5.yellow(String(brokenCitations)) : chalk5.green("0")}`);
1751
+ } finally {
1752
+ store.close();
1753
+ }
1754
+ }
1755
+
1756
+ // ../../packages/cli/dist/commands/history/import.js
1757
+ import { basename } from "path";
1758
+ import chalk6 from "chalk";
1759
+ async function historyImportCommand(opts) {
1760
+ if (!opts.all && !opts.provider) {
1761
+ console.error(chalk6.red("Specify --provider <name> or --all."));
1762
+ process.exitCode = 1;
1763
+ return;
1764
+ }
1765
+ if (opts.path && (!opts.provider || opts.all)) {
1766
+ console.error(chalk6.red("--path requires a single --provider (not --all)."));
1767
+ process.exitCode = 1;
1768
+ return;
1769
+ }
1770
+ const registry = buildHistoryRegistry();
1771
+ const parsers = opts.all ? registry.list() : (() => {
1772
+ const parser = opts.provider ? registry.get(opts.provider) : void 0;
1773
+ return parser ? [parser] : [];
1774
+ })();
1775
+ if (parsers.length === 0) {
1776
+ const known = registry.list().map((p) => p.provider).join(", ");
1777
+ console.error(chalk6.red(`Unknown provider: "${opts.provider}". Registered: ${known || "(none)"}`));
1778
+ process.exitCode = 1;
1779
+ return;
1780
+ }
1781
+ const store = openHistoryStore();
1782
+ try {
1783
+ for (const parser of parsers) {
1784
+ const sources = opts.path ? [
1785
+ {
1786
+ id: `${parser.provider}:${opts.path}`,
1787
+ provider: parser.provider,
1788
+ path: opts.path,
1789
+ nativeImport: true,
1790
+ importable: true,
1791
+ scope: basename(opts.path)
1792
+ }
1793
+ ] : await parser.discover();
1794
+ for (const source of sources) {
1795
+ store.upsertSource(source);
1796
+ if (!source.importable) {
1797
+ console.log(chalk6.yellow(` - ${parser.provider}: skipped (${source.reason})`));
1798
+ continue;
1799
+ }
1800
+ const results = await parser.import(source);
1801
+ for (const result of results) {
1802
+ store.saveImportResult(parser.provider, result.session.id, result);
1803
+ }
1804
+ const eventCount = results.reduce((n, r) => n + r.events.length, 0);
1805
+ console.log(chalk6.green(` \u2713 ${parser.provider}: imported ${results.length} session(s), ${eventCount} event(s)`));
1806
+ }
1807
+ }
1808
+ } finally {
1809
+ store.close();
1810
+ }
1811
+ }
1812
+
1813
+ // ../../packages/cli/dist/commands/history/locate.js
1814
+ import { existsSync as existsSync2 } from "fs";
1815
+ import chalk7 from "chalk";
1816
+ async function historyLocateEventCommand(id, opts) {
1817
+ const store = openHistoryStore();
1818
+ try {
1819
+ const eventId = Number.parseInt(id, 10);
1820
+ const event = store.getEvent(eventId);
1821
+ if (!event) {
1822
+ console.error(chalk7.red(`Event ${id} not found.`));
1823
+ process.exitCode = 1;
1824
+ return;
1825
+ }
1826
+ const citation = store.getCitation(eventId);
1827
+ if (!citation) {
1828
+ console.error(chalk7.yellow(`No citation recorded for event ${id}.`));
1829
+ process.exitCode = 1;
1830
+ return;
1831
+ }
1832
+ const exists = existsSync2(citation.sourcePath);
1833
+ if (opts.json) {
1834
+ console.log(JSON.stringify({ citation, exists }, null, 2));
1835
+ return;
1836
+ }
1837
+ console.log(`${citation.sourcePath}${citation.sourceLine ? `:${citation.sourceLine}` : ""}`);
1838
+ if (!exists)
1839
+ console.log(chalk7.yellow(" ! source file no longer exists at this path"));
1840
+ } finally {
1841
+ store.close();
1842
+ }
1843
+ }
1844
+ async function historyLocateSessionCommand(sessionId, opts) {
1845
+ const store = openHistoryStore();
1846
+ try {
1847
+ const events = store.listEvents(sessionId);
1848
+ if (events.length === 0) {
1849
+ console.error(chalk7.red(`Session "${sessionId}" not found or has no events.`));
1850
+ process.exitCode = 1;
1851
+ return;
1852
+ }
1853
+ const citation = store.getCitation(events[0].id);
1854
+ if (!citation) {
1855
+ console.error(chalk7.yellow("No citation recorded for this session."));
1856
+ process.exitCode = 1;
1857
+ return;
1858
+ }
1859
+ const exists = existsSync2(citation.sourcePath);
1860
+ if (opts.json) {
1861
+ console.log(JSON.stringify({ citation, exists }, null, 2));
1862
+ return;
1863
+ }
1864
+ console.log(citation.sourcePath);
1865
+ if (!exists)
1866
+ console.log(chalk7.yellow(" ! source file no longer exists at this path"));
1867
+ } finally {
1868
+ store.close();
1869
+ }
1870
+ }
1871
+
1872
+ // ../../packages/cli/dist/commands/history/search.js
1873
+ import chalk8 from "chalk";
1874
+ async function refresh(mode, store, scope) {
1875
+ if (mode === "off")
1876
+ return { mode, ran: false };
1877
+ const registry = buildHistoryRegistry();
1878
+ try {
1879
+ for (const parser of registry.list()) {
1880
+ const sources = await parser.discover();
1881
+ const inScope = scope === void 0 ? sources : sources.filter((s) => s.scope === scope);
1882
+ for (const source of inScope) {
1883
+ store.upsertSource(source);
1884
+ if (!source.importable)
1885
+ continue;
1886
+ const results = await parser.import(source);
1887
+ for (const result of results)
1888
+ store.saveImportResult(parser.provider, result.session.id, result);
1889
+ }
1890
+ }
1891
+ return { mode, ran: true };
1892
+ } catch (err) {
1893
+ const message = err instanceof Error ? err.message : String(err);
1894
+ if (mode === "strict")
1895
+ throw new Error(message);
1896
+ return { mode, ran: false, error: message };
1897
+ }
1898
+ }
1899
+ function toFtsQuery(terms) {
1900
+ return terms.map((t) => `"${t.replace(/"/g, '""')}"`).join(" ");
1901
+ }
1902
+ async function historySearchCommand(query, opts) {
1903
+ const terms = opts.term && opts.term.length > 0 ? opts.term : query ? [query] : [];
1904
+ if (terms.length === 0) {
1905
+ console.error(chalk8.red('Provide a query, e.g. omni history search "retry handling", or repeatable --term.'));
1906
+ process.exitCode = 1;
1907
+ return;
1908
+ }
1909
+ const mode = opts.refresh ?? "auto";
1910
+ const scope = opts.allProjects ? void 0 : opts.scope ?? encodeProjectScope(process.cwd());
1911
+ const store = openHistoryStore();
1912
+ try {
1913
+ let freshness;
1914
+ try {
1915
+ freshness = await refresh(mode, store, scope);
1916
+ } catch (err) {
1917
+ console.error(chalk8.red(`Refresh failed (--refresh strict): ${err instanceof Error ? err.message : String(err)}`));
1918
+ process.exitCode = 1;
1919
+ return;
1920
+ }
1921
+ const hits = store.search(toFtsQuery(terms), {
1922
+ sessionId: opts.session,
1923
+ scope,
1924
+ limit: opts.limit ? Number.parseInt(opts.limit, 10) : void 0
1925
+ });
1926
+ if (opts.json) {
1927
+ console.log(JSON.stringify({ freshness, scope: scope ?? null, hits }, null, 2));
1928
+ return;
1929
+ }
1930
+ if (freshness.error) {
1931
+ console.log(chalk8.gray(` (refresh skipped: ${freshness.error})
1932
+ `));
1933
+ }
1934
+ console.log(chalk8.gray(` scope: ${scope ?? "(all projects)"}
1935
+ `));
1936
+ if (hits.length === 0) {
1937
+ console.log(chalk8.gray("No results."));
1938
+ return;
1939
+ }
1940
+ for (const hit of hits) {
1941
+ console.log(`${chalk8.cyan(`[${hit.session.provider}]`)} ${chalk8.gray(hit.session.id)} ${chalk8.gray(`#${hit.event.id}`)}`);
1942
+ console.log(` ${hit.event.content.slice(0, 200).replace(/\n/g, " ")}
1943
+ `);
1944
+ }
1945
+ } finally {
1946
+ store.close();
1947
+ }
1948
+ }
1949
+
1950
+ // ../../packages/cli/dist/commands/history/show.js
1951
+ import { writeFile as writeFile5 } from "fs/promises";
1952
+ import chalk9 from "chalk";
1953
+ async function historyShowEventCommand(id, opts) {
1954
+ const store = openHistoryStore();
1955
+ try {
1956
+ const eventId = Number.parseInt(id, 10);
1957
+ const window = opts.window ? Number.parseInt(opts.window, 10) : 3;
1958
+ const events = store.getEventWindow(eventId, window);
1959
+ if (events.length === 0) {
1960
+ console.error(chalk9.red(`Event ${id} not found.`));
1961
+ process.exitCode = 1;
1962
+ return;
1963
+ }
1964
+ for (const e of events) {
1965
+ const marker = e.id === eventId ? chalk9.bold.cyan(">") : " ";
1966
+ console.log(`${marker} ${chalk9.cyan(`#${e.id}`)} ${chalk9.gray(e.role.padEnd(10))} ${e.content.slice(0, 300)}`);
1967
+ }
1968
+ } finally {
1969
+ store.close();
1970
+ }
1971
+ }
1972
+ function formatSessionMarkdown(session, events) {
1973
+ const lines = [
1974
+ `# Session: ${session.provider} / ${session.sourceSessionId}`,
1975
+ `_Imported: ${new Date(session.importedAt).toISOString()}_`,
1976
+ ""
1977
+ ];
1978
+ for (const e of events) {
1979
+ lines.push(`### ${e.role} \u2014 #${e.id}`, "", e.content, "");
1980
+ }
1981
+ return lines.join("\n");
1982
+ }
1983
+ function formatSessionText(session, events) {
1984
+ const header = `Session: ${session.provider} / ${session.sourceSessionId}`;
1985
+ return [header, "", ...events.map((e) => `[${e.role}] ${e.content}`)].join("\n\n");
1986
+ }
1987
+ async function historyShowSessionCommand(sessionId, opts) {
1988
+ const store = openHistoryStore();
1989
+ try {
1990
+ const session = store.getSession(sessionId);
1991
+ if (!session) {
1992
+ console.error(chalk9.red(`Session "${sessionId}" not found.`));
1993
+ process.exitCode = 1;
1994
+ return;
1995
+ }
1996
+ const events = store.listEvents(sessionId);
1997
+ const format = opts.format ?? "text";
1998
+ const output = format === "markdown" ? formatSessionMarkdown(session, events) : formatSessionText(session, events);
1999
+ if (opts.out) {
2000
+ await writeFile5(opts.out, output, "utf-8");
2001
+ console.log(chalk9.green(`Session exported to: ${opts.out}`));
2002
+ } else {
2003
+ console.log(output);
2004
+ }
2005
+ } finally {
2006
+ store.close();
2007
+ }
2008
+ }
2009
+
2010
+ // ../../packages/cli/dist/commands/history/sources.js
2011
+ import chalk10 from "chalk";
2012
+ async function historySourcesCommand(opts) {
2013
+ const registry = buildHistoryRegistry();
2014
+ const sources = (await Promise.all(registry.list().map((p) => p.discover()))).flat();
2015
+ if (opts.json) {
2016
+ console.log(JSON.stringify({ sources }, null, 2));
2017
+ return;
2018
+ }
2019
+ if (sources.length === 0) {
2020
+ console.log(chalk10.gray("No known providers registered."));
2021
+ return;
2022
+ }
2023
+ console.log(chalk10.bold(`Sources (${sources.length}):
2024
+ `));
2025
+ for (const s of sources) {
2026
+ const status = s.importable ? chalk10.green("importable") : chalk10.yellow(`not importable (${s.reason})`);
2027
+ console.log(` ${chalk10.cyan(s.provider.padEnd(14))} ${s.path}`);
2028
+ console.log(` ${" ".repeat(14)} scope=${s.scope ?? "(unscoped)"} native_import=${s.nativeImport} ${status}
2029
+ `);
2030
+ }
2031
+ }
2032
+
1158
2033
  // ../../packages/cli/dist/commands/init.js
1159
- import { access, readFile as readFile6, writeFile as writeFile5 } from "fs/promises";
1160
- import { dirname as dirname3, resolve as resolve9 } from "path";
2034
+ import { access, readFile as readFile8, writeFile as writeFile6 } from "fs/promises";
2035
+ import { dirname as dirname4, resolve as resolve9 } from "path";
1161
2036
  import { fileURLToPath as fileURLToPath2 } from "url";
1162
2037
  import { checkbox, confirm, input, password, select } from "@inquirer/prompts";
1163
- import chalk5 from "chalk";
1164
- var __dirname = dirname3(fileURLToPath2(import.meta.url));
2038
+ import chalk11 from "chalk";
2039
+ var __dirname = dirname4(fileURLToPath2(import.meta.url));
1165
2040
  var OMNI_ROOT = resolve9(__dirname, "..", "..", "..", "..");
1166
2041
  var CONFIG_PATH = resolve9(OMNI_ROOT, "config", "omni-ai.yaml");
1167
2042
  var ENV_PATH = resolve9(OMNI_ROOT, ".env");
@@ -1176,7 +2051,7 @@ async function fileExists(path) {
1176
2051
  async function readEnvFile(path) {
1177
2052
  const map = /* @__PURE__ */ new Map();
1178
2053
  try {
1179
- const content = await readFile6(path, "utf-8");
2054
+ const content = await readFile8(path, "utf-8");
1180
2055
  for (const line of content.split("\n")) {
1181
2056
  const trimmed = line.trim();
1182
2057
  if (!trimmed || trimmed.startsWith("#"))
@@ -1259,9 +2134,9 @@ agents:
1259
2134
  }
1260
2135
  async function setupCopilot() {
1261
2136
  console.log();
1262
- console.log(chalk5.dim(" Para obter seu token GitHub:"));
1263
- console.log(chalk5.dim(" gh auth login # se ainda n\xE3o fez"));
1264
- console.log(chalk5.dim(" gh auth token # mostra o token atual"));
2137
+ console.log(chalk11.dim(" Para obter seu token GitHub:"));
2138
+ console.log(chalk11.dim(" gh auth login # se ainda n\xE3o fez"));
2139
+ console.log(chalk11.dim(" gh auth token # mostra o token atual"));
1265
2140
  console.log();
1266
2141
  const token = await password({
1267
2142
  message: "Cole seu GitHub token (ghp_... ou github_pat_...):",
@@ -1286,8 +2161,8 @@ async function setupCopilot() {
1286
2161
  }
1287
2162
  async function setupAnthropic() {
1288
2163
  console.log();
1289
- console.log(chalk5.dim(" Como obter: https://console.anthropic.com \u2192 API Keys \u2192 Create key"));
1290
- console.log(chalk5.dim(" Formato: sk-ant-api03-..."));
2164
+ console.log(chalk11.dim(" Como obter: https://console.anthropic.com \u2192 API Keys \u2192 Create key"));
2165
+ console.log(chalk11.dim(" Formato: sk-ant-api03-..."));
1291
2166
  console.log();
1292
2167
  const key = await password({
1293
2168
  message: "Cole sua Anthropic API key:",
@@ -1311,8 +2186,8 @@ async function setupAnthropic() {
1311
2186
  }
1312
2187
  async function setupOpenAI() {
1313
2188
  console.log();
1314
- console.log(chalk5.dim(" Como obter: https://platform.openai.com \u2192 API keys \u2192 Create new secret key"));
1315
- console.log(chalk5.dim(" Formato: sk-proj-... (novo) ou sk-... (legado)"));
2189
+ console.log(chalk11.dim(" Como obter: https://platform.openai.com \u2192 API keys \u2192 Create new secret key"));
2190
+ console.log(chalk11.dim(" Formato: sk-proj-... (novo) ou sk-... (legado)"));
1316
2191
  console.log();
1317
2192
  const key = await password({
1318
2193
  message: "Cole sua OpenAI API key:",
@@ -1337,10 +2212,10 @@ async function setupOpenAI() {
1337
2212
  }
1338
2213
  async function setupCustom() {
1339
2214
  console.log();
1340
- console.log(chalk5.dim(" Compat\xEDvel com qualquer endpoint OpenAI-like:"));
1341
- console.log(chalk5.dim(" Ollama: http://localhost:11434/v1"));
1342
- console.log(chalk5.dim(" Groq: https://api.groq.com/openai/v1"));
1343
- console.log(chalk5.dim(" Azure: https://<resource>.openai.azure.com"));
2215
+ console.log(chalk11.dim(" Compat\xEDvel com qualquer endpoint OpenAI-like:"));
2216
+ console.log(chalk11.dim(" Ollama: http://localhost:11434/v1"));
2217
+ console.log(chalk11.dim(" Groq: https://api.groq.com/openai/v1"));
2218
+ console.log(chalk11.dim(" Azure: https://<resource>.openai.azure.com"));
1344
2219
  console.log();
1345
2220
  const baseUrl = await input({
1346
2221
  message: "Base URL do endpoint:",
@@ -1392,16 +2267,16 @@ async function selectProvider(label) {
1392
2267
  }
1393
2268
  async function initCommand() {
1394
2269
  console.log();
1395
- console.log(chalk5.bold(" omni-ai \u2014 configura\xE7\xE3o inicial"));
1396
- console.log(chalk5.dim(" Isso vai criar config/omni-ai.yaml e atualizar o .env"));
2270
+ console.log(chalk11.bold(" omni-ai \u2014 configura\xE7\xE3o inicial"));
2271
+ console.log(chalk11.dim(" Isso vai criar config/omni-ai.yaml e atualizar o .env"));
1397
2272
  console.log();
1398
2273
  if (await fileExists(CONFIG_PATH)) {
1399
2274
  const overwrite = await confirm({
1400
- message: chalk5.yellow("config/omni-ai.yaml j\xE1 existe. Sobrescrever?"),
2275
+ message: chalk11.yellow("config/omni-ai.yaml j\xE1 existe. Sobrescrever?"),
1401
2276
  default: false
1402
2277
  });
1403
2278
  if (!overwrite) {
1404
- console.log(chalk5.dim("\n Opera\xE7\xE3o cancelada.\n"));
2279
+ console.log(chalk11.dim("\n Opera\xE7\xE3o cancelada.\n"));
1405
2280
  return;
1406
2281
  }
1407
2282
  }
@@ -1417,7 +2292,7 @@ async function initCommand() {
1417
2292
  if (second.name !== primary.name) {
1418
2293
  extras.push(second);
1419
2294
  } else {
1420
- console.log(chalk5.dim(" Mesmo provider \u2014 ignorado."));
2295
+ console.log(chalk11.dim(" Mesmo provider \u2014 ignorado."));
1421
2296
  }
1422
2297
  }
1423
2298
  const agentSets = await checkbox({
@@ -1444,92 +2319,92 @@ async function initCommand() {
1444
2319
  const envTemplatePath = resolve9(OMNI_ROOT, ".env.example");
1445
2320
  let envTemplate = "";
1446
2321
  try {
1447
- envTemplate = await readFile6(envTemplatePath, "utf-8");
2322
+ envTemplate = await readFile8(envTemplatePath, "utf-8");
1448
2323
  } catch {
1449
2324
  envTemplate = Array.from(envEntries.entries()).map(([k, v]) => `${k}=${v}`).join("\n");
1450
2325
  }
1451
2326
  const envContent = buildEnvFile(envEntries, envTemplate);
1452
2327
  const yamlContent = buildYaml(primary, extras);
1453
- await writeFile5(CONFIG_PATH, yamlContent, "utf-8");
1454
- await writeFile5(ENV_PATH, envContent, "utf-8");
2328
+ await writeFile6(CONFIG_PATH, yamlContent, "utf-8");
2329
+ await writeFile6(ENV_PATH, envContent, "utf-8");
1455
2330
  console.log();
1456
- console.log(`${chalk5.green(" \u2713")} config/omni-ai.yaml criado`);
1457
- console.log(`${chalk5.green(" \u2713")} .env atualizado`);
2331
+ console.log(`${chalk11.green(" \u2713")} config/omni-ai.yaml criado`);
2332
+ console.log(`${chalk11.green(" \u2713")} .env atualizado`);
1458
2333
  console.log();
1459
- console.log(chalk5.bold(" Pr\xF3ximos passos:"));
2334
+ console.log(chalk11.bold(" Pr\xF3ximos passos:"));
1460
2335
  console.log();
1461
- console.log(chalk5.cyan(" omni list agents") + chalk5.dim(" # ver todos os agentes dispon\xEDveis"));
1462
- console.log(chalk5.cyan(" omni run code-reviewer") + chalk5.dim(' "revise src/app.ts"'));
2336
+ console.log(chalk11.cyan(" omni list agents") + chalk11.dim(" # ver todos os agentes dispon\xEDveis"));
2337
+ console.log(chalk11.cyan(" omni run code-reviewer") + chalk11.dim(' "revise src/app.ts"'));
1463
2338
  console.log();
1464
2339
  if (agentSets.includes("backend")) {
1465
- console.log(chalk5.cyan(" omni run backend-dev") + chalk5.dim(' "crie o m\xF3dulo de pedidos"'));
2340
+ console.log(chalk11.cyan(" omni run backend-dev") + chalk11.dim(' "crie o m\xF3dulo de pedidos"'));
1466
2341
  }
1467
2342
  if (agentSets.includes("frontend")) {
1468
- console.log(chalk5.cyan(" omni run frontend-dev") + chalk5.dim(' "crie a p\xE1gina de listagem de pedidos"'));
2343
+ console.log(chalk11.cyan(" omni run frontend-dev") + chalk11.dim(' "crie a p\xE1gina de listagem de pedidos"'));
1469
2344
  }
1470
2345
  if (agentSets.includes("ux")) {
1471
- console.log(chalk5.cyan(" omni run ux-lead") + chalk5.dim(' "audite o componente OrderForm"'));
2346
+ console.log(chalk11.cyan(" omni run ux-lead") + chalk11.dim(' "audite o componente OrderForm"'));
1472
2347
  }
1473
2348
  if (agentSets.includes("qa")) {
1474
- console.log(chalk5.cyan(" omni run qa-lead") + chalk5.dim(' "valide src/orders/"'));
2349
+ console.log(chalk11.cyan(" omni run qa-lead") + chalk11.dim(' "valide src/orders/"'));
1475
2350
  }
1476
2351
  console.log();
1477
- console.log(chalk5.dim(" Para usar de outro projeto:"));
1478
- console.log(chalk5.dim(" cd /caminho/para/meu-projeto"));
1479
- console.log(chalk5.cyan(" omni run backend-dev") + chalk5.dim(' "..."'));
2352
+ console.log(chalk11.dim(" Para usar de outro projeto:"));
2353
+ console.log(chalk11.dim(" cd /caminho/para/meu-projeto"));
2354
+ console.log(chalk11.cyan(" omni run backend-dev") + chalk11.dim(' "..."'));
1480
2355
  console.log();
1481
2356
  }
1482
2357
 
1483
2358
  // ../../packages/cli/dist/commands/list.js
1484
- import chalk6 from "chalk";
2359
+ import chalk12 from "chalk";
1485
2360
  async function listCommand(target, opts) {
1486
2361
  const configPath = opts.config ?? resolveConfigPath();
1487
2362
  if (target === "providers") {
1488
2363
  await import("../dist-Z76P5KV4.js");
1489
2364
  await import("../dist-KBUP5623.js");
1490
2365
  const names = getRegisteredProviders();
1491
- console.log(chalk6.bold("Registered providers:"));
2366
+ console.log(chalk12.bold("Registered providers:"));
1492
2367
  for (const name of names) {
1493
- console.log(` ${chalk6.cyan("\xB7")} ${name}`);
2368
+ console.log(` ${chalk12.cyan("\xB7")} ${name}`);
1494
2369
  }
1495
2370
  return;
1496
2371
  }
1497
2372
  const runtime = await createRuntime({ configPath }).catch(() => null);
1498
2373
  if (target === "agents") {
1499
2374
  if (!runtime) {
1500
- console.error(chalk6.red("Could not load config. Run from the omni-ai directory or pass --config."));
2375
+ console.error(chalk12.red("Could not load config. Run from the omni-ai directory or pass --config."));
1501
2376
  process.exit(1);
1502
2377
  }
1503
2378
  const agents = await runtime.listAgents();
1504
2379
  if (agents.length === 0) {
1505
- console.log(chalk6.gray("No agents found."));
2380
+ console.log(chalk12.gray("No agents found."));
1506
2381
  return;
1507
2382
  }
1508
- console.log(chalk6.bold(`Agents (${agents.length}):
2383
+ console.log(chalk12.bold(`Agents (${agents.length}):
1509
2384
  `));
1510
2385
  for (const agent of agents) {
1511
- console.log(` ${chalk6.cyan(agent.name.padEnd(30))} ${chalk6.gray(agent.description)}`);
2386
+ console.log(` ${chalk12.cyan(agent.name.padEnd(30))} ${chalk12.gray(agent.description)}`);
1512
2387
  }
1513
2388
  return;
1514
2389
  }
1515
2390
  if (target === "skills") {
1516
2391
  if (!runtime) {
1517
- console.error(chalk6.red("Could not load config."));
2392
+ console.error(chalk12.red("Could not load config."));
1518
2393
  process.exit(1);
1519
2394
  }
1520
2395
  const skills2 = runtime.skills.all();
1521
2396
  if (skills2.length === 0) {
1522
- console.log(chalk6.gray("No skills registered."));
2397
+ console.log(chalk12.gray("No skills registered."));
1523
2398
  return;
1524
2399
  }
1525
- console.log(chalk6.bold(`Skills (${skills2.length}):
2400
+ console.log(chalk12.bold(`Skills (${skills2.length}):
1526
2401
  `));
1527
2402
  for (const skill of skills2) {
1528
- console.log(` ${chalk6.yellow(skill.name.padEnd(25))} ${chalk6.gray(skill.description)}`);
2403
+ console.log(` ${chalk12.yellow(skill.name.padEnd(25))} ${chalk12.gray(skill.description)}`);
1529
2404
  }
1530
2405
  return;
1531
2406
  }
1532
- console.error(chalk6.red(`Unknown list target: "${target}". Use: agents | skills | providers`));
2407
+ console.error(chalk12.red(`Unknown list target: "${target}". Use: agents | skills | providers`));
1533
2408
  process.exit(1);
1534
2409
  }
1535
2410
 
@@ -1583,7 +2458,7 @@ async function serveStdioMcp(skills2, options) {
1583
2458
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
1584
2459
 
1585
2460
  // ../../packages/skills/dist/backend/analyze-dynamo-schema.js
1586
- import { readFile as readFile7 } from "fs/promises";
2461
+ import { readFile as readFile9 } from "fs/promises";
1587
2462
  import { resolve as resolve10 } from "path";
1588
2463
  import { z as z13 } from "zod";
1589
2464
  var InputSchema12 = z13.object({
@@ -1651,7 +2526,7 @@ var analyzeDynamoSchemaSkill = {
1651
2526
  description: "Parse a OneTable *.model.ts file and extract the schema name, entity type, fields (with types and required flags), enums, and Typenames references. Use this before generating a service to understand the exact entity shape.",
1652
2527
  async execute(input5) {
1653
2528
  const { path } = InputSchema12.parse(input5);
1654
- const source = await readFile7(resolve10(path), "utf-8");
2529
+ const source = await readFile9(resolve10(path), "utf-8");
1655
2530
  return {
1656
2531
  schemaName: extractSchemaName(source),
1657
2532
  entityType: extractEntityType(source),
@@ -1663,7 +2538,7 @@ var analyzeDynamoSchemaSkill = {
1663
2538
  };
1664
2539
 
1665
2540
  // ../../packages/skills/dist/backend/analyze-graphql-schema.js
1666
- import { readFile as readFile8 } from "fs/promises";
2541
+ import { readFile as readFile10 } from "fs/promises";
1667
2542
  import { resolve as resolve11 } from "path";
1668
2543
  import { z as z14 } from "zod";
1669
2544
  var InputSchema13 = z14.object({
@@ -1705,7 +2580,7 @@ var analyzeGraphqlSchemaSkill = {
1705
2580
  description: "Parse a GraphQL SDL file and extract types, queries, mutations, inputs and enums. Use this before generating a resolver to understand what operations already exist and what the correct return types are.",
1706
2581
  async execute(input5) {
1707
2582
  const { path } = InputSchema13.parse(input5);
1708
- const source = await readFile8(resolve11(path), "utf-8");
2583
+ const source = await readFile10(resolve11(path), "utf-8");
1709
2584
  return {
1710
2585
  types: extractTypes(source),
1711
2586
  queries: extractOperations(source, "Query"),
@@ -1717,7 +2592,7 @@ var analyzeGraphqlSchemaSkill = {
1717
2592
  };
1718
2593
 
1719
2594
  // ../../packages/skills/dist/backend/analyze-nestjs-module.js
1720
- import { readFile as readFile9 } from "fs/promises";
2595
+ import { readFile as readFile11 } from "fs/promises";
1721
2596
  import { resolve as resolve12 } from "path";
1722
2597
  import { z as z15 } from "zod";
1723
2598
  var InputSchema14 = z15.object({
@@ -1739,7 +2614,7 @@ var analyzeNestjsModuleSkill = {
1739
2614
  description: "Parse a NestJS *.module.ts file and extract its imports, providers, exports and controllers. Use this to understand what a module exposes before adding new providers or resolving injection dependencies.",
1740
2615
  async execute(input5) {
1741
2616
  const { path } = InputSchema14.parse(input5);
1742
- const source = await readFile9(resolve12(path), "utf-8");
2617
+ const source = await readFile11(resolve12(path), "utf-8");
1743
2618
  return {
1744
2619
  moduleName: extractModuleName(source),
1745
2620
  imports: extractArrayItems(source, "imports"),
@@ -1751,8 +2626,8 @@ var analyzeNestjsModuleSkill = {
1751
2626
  };
1752
2627
 
1753
2628
  // ../../packages/skills/dist/backend/find-code-pattern.js
1754
- import { readdir as readdir4, readFile as readFile10 } from "fs/promises";
1755
- import { join as join4 } from "path";
2629
+ import { readdir as readdir5, readFile as readFile12 } from "fs/promises";
2630
+ import { join as join6 } from "path";
1756
2631
  import { z as z16 } from "zod";
1757
2632
  var patternSuffixes = {
1758
2633
  service: [".service.ts"],
@@ -1770,7 +2645,7 @@ var InputSchema15 = z16.object({
1770
2645
  async function walkForPattern(dir, suffixes, results, max) {
1771
2646
  if (results.length >= max)
1772
2647
  return;
1773
- const entries = await readdir4(dir, { withFileTypes: true }).catch(() => null);
2648
+ const entries = await readdir5(dir, { withFileTypes: true }).catch(() => null);
1774
2649
  if (!entries)
1775
2650
  return;
1776
2651
  for (const entry of entries) {
@@ -1778,11 +2653,11 @@ async function walkForPattern(dir, suffixes, results, max) {
1778
2653
  break;
1779
2654
  if (entry.name === "node_modules" || entry.name === "dist" || entry.name === ".git")
1780
2655
  continue;
1781
- const fullPath = join4(dir, entry.name);
2656
+ const fullPath = join6(dir, entry.name);
1782
2657
  if (entry.isDirectory()) {
1783
2658
  await walkForPattern(fullPath, suffixes, results, max);
1784
2659
  } else if (entry.isFile() && suffixes.some((s) => entry.name.endsWith(s))) {
1785
- const content = await readFile10(fullPath, "utf-8");
2660
+ const content = await readFile12(fullPath, "utf-8");
1786
2661
  results.push({ file: fullPath, content });
1787
2662
  }
1788
2663
  }
@@ -1800,7 +2675,7 @@ var findCodePatternSkill = {
1800
2675
  };
1801
2676
 
1802
2677
  // ../../packages/skills/dist/frontend/analyze-component.js
1803
- import { readFile as readFile11 } from "fs/promises";
2678
+ import { readFile as readFile13 } from "fs/promises";
1804
2679
  import { resolve as resolve13 } from "path";
1805
2680
  import { z as z17 } from "zod";
1806
2681
  var InputSchema16 = z17.object({
@@ -1834,7 +2709,7 @@ var analyzeComponentSkill = {
1834
2709
  description: "Parse a React component file and extract its name, props interface, hooks used, named exports, and whether it has a default export. Use this to understand an existing component's contract before creating a related component or hook.",
1835
2710
  async execute(input5) {
1836
2711
  const { path } = InputSchema16.parse(input5);
1837
- const source = await readFile11(resolve13(path), "utf-8");
2712
+ const source = await readFile13(resolve13(path), "utf-8");
1838
2713
  return {
1839
2714
  componentName: extractComponentName(source, path),
1840
2715
  propsInterface: extractPropsInterface(source),
@@ -1846,21 +2721,21 @@ var analyzeComponentSkill = {
1846
2721
  };
1847
2722
 
1848
2723
  // ../../packages/skills/dist/frontend/analyze-module-structure.js
1849
- import { readdir as readdir5 } from "fs/promises";
1850
- import { join as join5 } from "path";
2724
+ import { readdir as readdir6 } from "fs/promises";
2725
+ import { join as join7 } from "path";
1851
2726
  import { z as z18 } from "zod";
1852
2727
  var InputSchema17 = z18.object({
1853
2728
  directory: z18.string().describe("Root directory of the React module or feature folder")
1854
2729
  });
1855
2730
  async function collectFiles2(dir) {
1856
- const entries = await readdir5(dir, { withFileTypes: true }).catch(() => null);
2731
+ const entries = await readdir6(dir, { withFileTypes: true }).catch(() => null);
1857
2732
  if (!entries)
1858
2733
  return [];
1859
2734
  const files = [];
1860
2735
  for (const entry of entries) {
1861
2736
  if (entry.name === "node_modules" || entry.name === "dist")
1862
2737
  continue;
1863
- const fullPath = join5(dir, entry.name);
2738
+ const fullPath = join7(dir, entry.name);
1864
2739
  if (entry.isDirectory()) {
1865
2740
  files.push(...await collectFiles2(fullPath));
1866
2741
  } else if (entry.isFile() && /\.(tsx?|jsx?)$/.test(entry.name)) {
@@ -1899,8 +2774,8 @@ var analyzeModuleStructureSkill = {
1899
2774
  };
1900
2775
 
1901
2776
  // ../../packages/skills/dist/frontend/find-component-pattern.js
1902
- import { readdir as readdir6, readFile as readFile12 } from "fs/promises";
1903
- import { join as join6 } from "path";
2777
+ import { readdir as readdir7, readFile as readFile14 } from "fs/promises";
2778
+ import { join as join8 } from "path";
1904
2779
  import { z as z19 } from "zod";
1905
2780
  var patternFilters = {
1906
2781
  component: (name) => /^[A-Z]/.test(name) && (name.endsWith(".tsx") || name.endsWith(".ts")) && !name.includes(".spec."),
@@ -1916,7 +2791,7 @@ var InputSchema18 = z19.object({
1916
2791
  async function walkForComponent(dir, filter, results, max) {
1917
2792
  if (results.length >= max)
1918
2793
  return;
1919
- const entries = await readdir6(dir, { withFileTypes: true }).catch(() => null);
2794
+ const entries = await readdir7(dir, { withFileTypes: true }).catch(() => null);
1920
2795
  if (!entries)
1921
2796
  return;
1922
2797
  for (const entry of entries) {
@@ -1924,11 +2799,11 @@ async function walkForComponent(dir, filter, results, max) {
1924
2799
  break;
1925
2800
  if (entry.name === "node_modules" || entry.name === "dist" || entry.name === ".git")
1926
2801
  continue;
1927
- const fullPath = join6(dir, entry.name);
2802
+ const fullPath = join8(dir, entry.name);
1928
2803
  if (entry.isDirectory()) {
1929
2804
  await walkForComponent(fullPath, filter, results, max);
1930
2805
  } else if (entry.isFile() && filter(entry.name)) {
1931
- const content = await readFile12(fullPath, "utf-8");
2806
+ const content = await readFile14(fullPath, "utf-8");
1932
2807
  results.push({ file: fullPath, content });
1933
2808
  }
1934
2809
  }
@@ -1946,8 +2821,8 @@ var findComponentPatternSkill = {
1946
2821
  };
1947
2822
 
1948
2823
  // ../../packages/skills/dist/qa/analyze-test-coverage.js
1949
- import { readdir as readdir7 } from "fs/promises";
1950
- import { join as join7 } from "path";
2824
+ import { readdir as readdir8 } from "fs/promises";
2825
+ import { join as join9 } from "path";
1951
2826
  import { z as z20 } from "zod";
1952
2827
  var InputSchema19 = z20.object({
1953
2828
  directory: z20.string().describe("Root directory to scan for source files and their tests"),
@@ -1955,14 +2830,14 @@ var InputSchema19 = z20.object({
1955
2830
  ignorePatterns: z20.array(z20.string()).default(["index.ts", "index.tsx", ".spec.", ".test.", ".d.ts", ".module.ts"]).describe("Substrings that mark files to skip (index, spec, declaration, module files)")
1956
2831
  });
1957
2832
  async function collectFiles3(dir, exts, ignore) {
1958
- const entries = await readdir7(dir, { withFileTypes: true }).catch(() => null);
2833
+ const entries = await readdir8(dir, { withFileTypes: true }).catch(() => null);
1959
2834
  if (!entries)
1960
2835
  return [];
1961
2836
  const files = [];
1962
2837
  for (const entry of entries) {
1963
2838
  if (entry.name === "node_modules" || entry.name === "dist" || entry.name === ".git")
1964
2839
  continue;
1965
- const fullPath = join7(dir, entry.name);
2840
+ const fullPath = join9(dir, entry.name);
1966
2841
  if (entry.isDirectory()) {
1967
2842
  files.push(...await collectFiles3(fullPath, exts, ignore));
1968
2843
  } else if (entry.isFile() && exts.some((e) => entry.name.endsWith(e)) && !ignore.some((p) => entry.name.includes(p) || fullPath.includes(p))) {
@@ -2005,8 +2880,8 @@ var analyzeTestCoverageSkill = {
2005
2880
  };
2006
2881
 
2007
2882
  // ../../packages/skills/dist/qa/find-test-pattern.js
2008
- import { readdir as readdir8, readFile as readFile13 } from "fs/promises";
2009
- import { join as join8 } from "path";
2883
+ import { readdir as readdir9, readFile as readFile15 } from "fs/promises";
2884
+ import { join as join10 } from "path";
2010
2885
  import { z as z21 } from "zod";
2011
2886
  var patternFilters2 = {
2012
2887
  service: (name) => name.endsWith(".service.spec.ts"),
@@ -2022,7 +2897,7 @@ var InputSchema20 = z21.object({
2022
2897
  async function walkForTests(dir, filter, results, max) {
2023
2898
  if (results.length >= max)
2024
2899
  return;
2025
- const entries = await readdir8(dir, { withFileTypes: true }).catch(() => null);
2900
+ const entries = await readdir9(dir, { withFileTypes: true }).catch(() => null);
2026
2901
  if (!entries)
2027
2902
  return;
2028
2903
  for (const entry of entries) {
@@ -2030,11 +2905,11 @@ async function walkForTests(dir, filter, results, max) {
2030
2905
  break;
2031
2906
  if (entry.name === "node_modules" || entry.name === "dist" || entry.name === ".git")
2032
2907
  continue;
2033
- const fullPath = join8(dir, entry.name);
2908
+ const fullPath = join10(dir, entry.name);
2034
2909
  if (entry.isDirectory()) {
2035
2910
  await walkForTests(fullPath, filter, results, max);
2036
2911
  } else if (entry.isFile() && filter(entry.name)) {
2037
- const content = await readFile13(fullPath, "utf-8");
2912
+ const content = await readFile15(fullPath, "utf-8");
2038
2913
  results.push({ file: fullPath, content });
2039
2914
  }
2040
2915
  }
@@ -2052,7 +2927,7 @@ var findTestPatternSkill = {
2052
2927
  };
2053
2928
 
2054
2929
  // ../../packages/cli/dist/commands/mcp-serve.js
2055
- import chalk7 from "chalk";
2930
+ import chalk13 from "chalk";
2056
2931
  var skills = [
2057
2932
  readFileSkill,
2058
2933
  writeFileSkill,
@@ -2073,32 +2948,34 @@ var skills = [
2073
2948
  analyzeComponentSkill,
2074
2949
  analyzeModuleStructureSkill,
2075
2950
  findTestPatternSkill,
2076
- analyzeTestCoverageSkill
2951
+ analyzeTestCoverageSkill,
2952
+ searchHistorySkill,
2953
+ showEventSkill
2077
2954
  ];
2078
2955
  async function mcpServeCommand() {
2079
- process.stderr.write(chalk7.bold.cyan("\n\u25C6 omni mcp serve\n"));
2080
- process.stderr.write(chalk7.gray(` Transport: stdio
2956
+ process.stderr.write(chalk13.bold.cyan("\n\u25C6 omni mcp serve\n"));
2957
+ process.stderr.write(chalk13.gray(` Transport: stdio
2081
2958
  `));
2082
- process.stderr.write(chalk7.gray(` Skills: ${skills.length}
2959
+ process.stderr.write(chalk13.gray(` Skills: ${skills.length}
2083
2960
  `));
2084
- process.stderr.write(chalk7.gray("\n Waiting for MCP client connection\u2026\n\n"));
2961
+ process.stderr.write(chalk13.gray("\n Waiting for MCP client connection\u2026\n\n"));
2085
2962
  await serveStdioMcp(skills, { name: "omni-ai" });
2086
2963
  await new Promise(() => {
2087
2964
  });
2088
2965
  }
2089
2966
 
2090
2967
  // ../../packages/cli/dist/commands/new.js
2091
- import { readFile as readFile14 } from "fs/promises";
2092
- import { join as join12 } from "path";
2968
+ import { readFile as readFile16 } from "fs/promises";
2969
+ import { join as join14 } from "path";
2093
2970
  import { select as select4 } from "@inquirer/prompts";
2094
- import chalk11 from "chalk";
2971
+ import chalk17 from "chalk";
2095
2972
  import YAML from "yaml";
2096
2973
 
2097
2974
  // ../../packages/cli/dist/commands/new/scaffold-agent.js
2098
- import { access as access2, mkdir as mkdir2, writeFile as writeFile6 } from "fs/promises";
2099
- import { join as join9, resolve as resolve14 } from "path";
2975
+ import { access as access2, mkdir as mkdir2, writeFile as writeFile7 } from "fs/promises";
2976
+ import { join as join11, resolve as resolve14 } from "path";
2100
2977
  import { checkbox as checkbox2, confirm as confirm2, input as input2, select as select2 } from "@inquirer/prompts";
2101
- import chalk8 from "chalk";
2978
+ import chalk14 from "chalk";
2102
2979
 
2103
2980
  // ../../packages/cli/dist/commands/new/templates.js
2104
2981
  function kebabToPascal(s) {
@@ -2241,7 +3118,7 @@ var ALL_SKILLS = [
2241
3118
  ];
2242
3119
  async function writeAgentFile(params, agentsDir) {
2243
3120
  const dir = resolve14(process.cwd(), agentsDir, params.domain);
2244
- const filePath = join9(dir, `${params.domain}-${params.role}.yaml`);
3121
+ const filePath = join11(dir, `${params.domain}-${params.role}.yaml`);
2245
3122
  const content = generateAgentYaml({
2246
3123
  name: `${params.domain}-${params.role}`,
2247
3124
  description: params.description,
@@ -2251,7 +3128,7 @@ async function writeAgentFile(params, agentsDir) {
2251
3128
  temperature: 0.3
2252
3129
  });
2253
3130
  await mkdir2(dir, { recursive: true });
2254
- await writeFile6(filePath, content, "utf-8");
3131
+ await writeFile7(filePath, content, "utf-8");
2255
3132
  return filePath;
2256
3133
  }
2257
3134
  async function agentWizard(agentsDir) {
@@ -2283,38 +3160,38 @@ async function agentWizard(agentsDir) {
2283
3160
  });
2284
3161
  const outPath = resolve14(process.cwd(), agentsDir, domain, `${domain}-${role}.yaml`);
2285
3162
  console.log();
2286
- console.log(chalk8.dim(` Destino: ${outPath}`));
3163
+ console.log(chalk14.dim(` Destino: ${outPath}`));
2287
3164
  let shouldWrite = true;
2288
3165
  try {
2289
3166
  await access2(outPath);
2290
- shouldWrite = await confirm2({ message: chalk8.yellow("Arquivo j\xE1 existe. Sobrescrever?"), default: false });
3167
+ shouldWrite = await confirm2({ message: chalk14.yellow("Arquivo j\xE1 existe. Sobrescrever?"), default: false });
2291
3168
  } catch {
2292
3169
  }
2293
3170
  if (!shouldWrite) {
2294
- console.log(chalk8.dim("\n Opera\xE7\xE3o cancelada.\n"));
3171
+ console.log(chalk14.dim("\n Opera\xE7\xE3o cancelada.\n"));
2295
3172
  return;
2296
3173
  }
2297
3174
  const filePath = await writeAgentFile({ domain, role, description, systemPrompt, skills: skills2 }, agentsDir);
2298
3175
  console.log();
2299
- console.log(`${chalk8.green(" \u2713")} Agente criado: ${chalk8.cyan(filePath)}`);
2300
- console.log(chalk8.dim(" Adicione ao omni-ai.yaml (se\xE7\xE3o agents:) ou coloque no agentsDir para uso autom\xE1tico."));
2301
- console.log(chalk8.dim(` Testar: omni run ${domain}-${role} "sua tarefa aqui"`));
3176
+ console.log(`${chalk14.green(" \u2713")} Agente criado: ${chalk14.cyan(filePath)}`);
3177
+ console.log(chalk14.dim(" Adicione ao omni-ai.yaml (se\xE7\xE3o agents:) ou coloque no agentsDir para uso autom\xE1tico."));
3178
+ console.log(chalk14.dim(` Testar: omni run ${domain}-${role} "sua tarefa aqui"`));
2302
3179
  console.log();
2303
3180
  }
2304
3181
 
2305
3182
  // ../../packages/cli/dist/commands/new/scaffold-provider.js
2306
- import { access as access3, mkdir as mkdir3, writeFile as writeFile7 } from "fs/promises";
2307
- import { join as join10, resolve as resolve15 } from "path";
3183
+ import { access as access3, mkdir as mkdir3, writeFile as writeFile8 } from "fs/promises";
3184
+ import { join as join12, resolve as resolve15 } from "path";
2308
3185
  import { confirm as confirm3, input as input3 } from "@inquirer/prompts";
2309
- import chalk9 from "chalk";
3186
+ import chalk15 from "chalk";
2310
3187
  async function writeProviderFiles(params, providersDir) {
2311
3188
  const dir = resolve15(process.cwd(), providersDir, `provider-${params.kebabName}`, "src");
2312
3189
  const packageDir = resolve15(process.cwd(), providersDir, `provider-${params.kebabName}`);
2313
3190
  const { indexTs, packageJson, tsconfigJson } = generateProviderFiles(params);
2314
3191
  await mkdir3(dir, { recursive: true });
2315
- await writeFile7(join10(dir, "index.ts"), indexTs, "utf-8");
2316
- await writeFile7(join10(packageDir, "package.json"), packageJson, "utf-8");
2317
- await writeFile7(join10(packageDir, "tsconfig.json"), tsconfigJson, "utf-8");
3192
+ await writeFile8(join12(dir, "index.ts"), indexTs, "utf-8");
3193
+ await writeFile8(join12(packageDir, "package.json"), packageJson, "utf-8");
3194
+ await writeFile8(join12(packageDir, "tsconfig.json"), tsconfigJson, "utf-8");
2318
3195
  return packageDir;
2319
3196
  }
2320
3197
  async function providerWizard(providersDir) {
@@ -2332,43 +3209,43 @@ async function providerWizard(providersDir) {
2332
3209
  const hasEmbedding = await confirm3({ message: "Suporta embeddings?", default: false });
2333
3210
  const outDir = resolve15(process.cwd(), providersDir, `provider-${kebabName}`);
2334
3211
  console.log();
2335
- console.log(chalk9.dim(` Destino: ${outDir}/`));
3212
+ console.log(chalk15.dim(` Destino: ${outDir}/`));
2336
3213
  let shouldWrite = true;
2337
3214
  try {
2338
3215
  await access3(outDir);
2339
3216
  shouldWrite = await confirm3({
2340
- message: chalk9.yellow(`packages/provider-${kebabName}/ j\xE1 existe. Sobrescrever arquivos?`),
3217
+ message: chalk15.yellow(`packages/provider-${kebabName}/ j\xE1 existe. Sobrescrever arquivos?`),
2341
3218
  default: false
2342
3219
  });
2343
3220
  } catch {
2344
3221
  }
2345
3222
  if (!shouldWrite) {
2346
- console.log(chalk9.dim("\n Opera\xE7\xE3o cancelada.\n"));
3223
+ console.log(chalk15.dim("\n Opera\xE7\xE3o cancelada.\n"));
2347
3224
  return;
2348
3225
  }
2349
3226
  const packageDir = await writeProviderFiles({ kebabName, displayName, hasVision, hasEmbedding }, providersDir);
2350
3227
  console.log();
2351
- console.log(`${chalk9.green(" \u2713")} Provider criado: ${chalk9.cyan(`${packageDir}/`)}`);
2352
- console.log(chalk9.dim(" Pr\xF3ximos passos:"));
2353
- console.log(chalk9.dim(` 1. Implemente complete() em src/index.ts`));
2354
- console.log(chalk9.dim(` 2. Adicione \xE0 raiz tsconfig.json \u2192 references: { path: "./${providersDir}/provider-${kebabName}" }`));
2355
- console.log(chalk9.dim(` 3. Importe em packages/cli/src/commands/run.ts: import "@omni-ai/provider-${kebabName}";`));
2356
- console.log(chalk9.dim(` 4. Adicione a chave de API ao .env.example`));
3228
+ console.log(`${chalk15.green(" \u2713")} Provider criado: ${chalk15.cyan(`${packageDir}/`)}`);
3229
+ console.log(chalk15.dim(" Pr\xF3ximos passos:"));
3230
+ console.log(chalk15.dim(` 1. Implemente complete() em src/index.ts`));
3231
+ console.log(chalk15.dim(` 2. Adicione \xE0 raiz tsconfig.json \u2192 references: { path: "./${providersDir}/provider-${kebabName}" }`));
3232
+ console.log(chalk15.dim(` 3. Importe em packages/cli/src/commands/run.ts: import "@omni-ai/provider-${kebabName}";`));
3233
+ console.log(chalk15.dim(` 4. Adicione a chave de API ao .env.example`));
2357
3234
  console.log();
2358
3235
  }
2359
3236
 
2360
3237
  // ../../packages/cli/dist/commands/new/scaffold-skill.js
2361
- import { access as access4, mkdir as mkdir4, writeFile as writeFile8 } from "fs/promises";
2362
- import { join as join11, resolve as resolve16 } from "path";
3238
+ import { access as access4, mkdir as mkdir4, writeFile as writeFile9 } from "fs/promises";
3239
+ import { join as join13, resolve as resolve16 } from "path";
2363
3240
  import { confirm as confirm4, input as input4, select as select3 } from "@inquirer/prompts";
2364
- import chalk10 from "chalk";
3241
+ import chalk16 from "chalk";
2365
3242
  var DOMAINS = ["backend", "frontend", "qa", "fs", "git", "http", "multimodal", "ux"];
2366
3243
  async function writeSkillFile(params, skillsDir) {
2367
3244
  const dir = resolve16(process.cwd(), skillsDir, params.domain);
2368
- const filePath = join11(dir, `${params.kebabName}.ts`);
3245
+ const filePath = join13(dir, `${params.kebabName}.ts`);
2369
3246
  const content = generateSkillTs({ kebabName: params.kebabName, description: params.description });
2370
3247
  await mkdir4(dir, { recursive: true });
2371
- await writeFile8(filePath, content, "utf-8");
3248
+ await writeFile9(filePath, content, "utf-8");
2372
3249
  return filePath;
2373
3250
  }
2374
3251
  async function skillWizard(skillsDir) {
@@ -2387,24 +3264,24 @@ async function skillWizard(skillsDir) {
2387
3264
  });
2388
3265
  const outPath = resolve16(process.cwd(), skillsDir, domain, `${kebabName}.ts`);
2389
3266
  console.log();
2390
- console.log(chalk10.dim(` Destino: ${outPath}`));
3267
+ console.log(chalk16.dim(` Destino: ${outPath}`));
2391
3268
  let shouldWrite = true;
2392
3269
  try {
2393
3270
  await access4(outPath);
2394
- shouldWrite = await confirm4({ message: chalk10.yellow("Arquivo j\xE1 existe. Sobrescrever?"), default: false });
3271
+ shouldWrite = await confirm4({ message: chalk16.yellow("Arquivo j\xE1 existe. Sobrescrever?"), default: false });
2395
3272
  } catch {
2396
3273
  }
2397
3274
  if (!shouldWrite) {
2398
- console.log(chalk10.dim("\n Opera\xE7\xE3o cancelada.\n"));
3275
+ console.log(chalk16.dim("\n Opera\xE7\xE3o cancelada.\n"));
2399
3276
  return;
2400
3277
  }
2401
3278
  const filePath = await writeSkillFile({ domain, kebabName, description }, skillsDir);
2402
3279
  console.log();
2403
- console.log(`${chalk10.green(" \u2713")} Skill criada: ${chalk10.cyan(filePath)}`);
2404
- console.log(chalk10.dim(` Pr\xF3ximos passos:`));
2405
- console.log(chalk10.dim(` 1. Implemente a l\xF3gica em execute()`));
2406
- console.log(chalk10.dim(` 2. Exporte de ${skillsDir}/${domain}/index.ts`));
2407
- console.log(chalk10.dim(` 3. Registre em packages/cli/src/commands/run.ts`));
3280
+ console.log(`${chalk16.green(" \u2713")} Skill criada: ${chalk16.cyan(filePath)}`);
3281
+ console.log(chalk16.dim(` Pr\xF3ximos passos:`));
3282
+ console.log(chalk16.dim(` 1. Implemente a l\xF3gica em execute()`));
3283
+ console.log(chalk16.dim(` 2. Exporte de ${skillsDir}/${domain}/index.ts`));
3284
+ console.log(chalk16.dim(` 3. Registre em packages/cli/src/commands/run.ts`));
2408
3285
  console.log();
2409
3286
  }
2410
3287
 
@@ -2416,7 +3293,7 @@ var DEFAULTS = {
2416
3293
  };
2417
3294
  async function loadScaffoldConfig() {
2418
3295
  try {
2419
- const raw = await readFile14(join12(process.cwd(), "config", "omni-ai.yaml"), "utf-8");
3296
+ const raw = await readFile16(join14(process.cwd(), "config", "omni-ai.yaml"), "utf-8");
2420
3297
  const data = YAML.parse(raw);
2421
3298
  if (!data)
2422
3299
  return DEFAULTS;
@@ -2432,8 +3309,8 @@ async function loadScaffoldConfig() {
2432
3309
  }
2433
3310
  async function newCommand() {
2434
3311
  console.log();
2435
- console.log(chalk11.bold(" omni new \u2014 scaffold interativo"));
2436
- console.log(chalk11.dim(" Cria um agente, skill ou provider a partir de template"));
3312
+ console.log(chalk17.bold(" omni new \u2014 scaffold interativo"));
3313
+ console.log(chalk17.dim(" Cria um agente, skill ou provider a partir de template"));
2437
3314
  const config = await loadScaffoldConfig();
2438
3315
  const type = await select4({
2439
3316
  message: "O que deseja criar?",
@@ -2457,7 +3334,7 @@ async function newCommand() {
2457
3334
  }
2458
3335
 
2459
3336
  // ../../packages/cli/dist/commands/run.js
2460
- import { writeFile as writeFile9 } from "fs/promises";
3337
+ import { writeFile as writeFile10 } from "fs/promises";
2461
3338
  function parseSession(raw) {
2462
3339
  const [resourceId, ...rest] = raw.split(":");
2463
3340
  const threadId = rest.join(":") || "default";
@@ -2523,7 +3400,7 @@ ${result.output}
2523
3400
  }
2524
3401
  console.log(iterationLine(result.iterations));
2525
3402
  if (opts.output) {
2526
- await writeFile9(opts.output, result.output, "utf-8");
3403
+ await writeFile10(opts.output, result.output, "utf-8");
2527
3404
  console.log(savedLine(opts.output));
2528
3405
  }
2529
3406
  if (result.usage) {
@@ -2534,7 +3411,7 @@ ${result.output}
2534
3411
  }
2535
3412
 
2536
3413
  // ../../packages/cli/dist/commands/serve.js
2537
- import chalk12 from "chalk";
3414
+ import chalk18 from "chalk";
2538
3415
  import express from "express";
2539
3416
  function getDbPath3() {
2540
3417
  const home = process.env.HOME ?? process.env.USERPROFILE ?? ".";
@@ -2570,7 +3447,7 @@ async function serveCommand(opts) {
2570
3447
  analyzeTestCoverageSkill
2571
3448
  ];
2572
3449
  const runtime = await createRuntime({ configPath, skills: skills2 }).catch((err) => {
2573
- console.error(chalk12.red(`\u2716 Failed to load config: ${err instanceof Error ? err.message : String(err)}`));
3450
+ console.error(chalk18.red(`\u2716 Failed to load config: ${err instanceof Error ? err.message : String(err)}`));
2574
3451
  process.exit(1);
2575
3452
  });
2576
3453
  const app = express();
@@ -2638,21 +3515,21 @@ async function serveCommand(opts) {
2638
3515
  }
2639
3516
  });
2640
3517
  app.listen(port, () => {
2641
- console.log(chalk12.bold.cyan(`
3518
+ console.log(chalk18.bold.cyan(`
2642
3519
  \u25C6 omni serve`));
2643
- console.log(chalk12.gray(` Listening on http://localhost:${port}`));
2644
- console.log(chalk12.gray(` GET /health`));
2645
- console.log(chalk12.gray(` GET /agents`));
2646
- console.log(chalk12.gray(` POST /run \u2014 JSON response`));
2647
- console.log(chalk12.gray(` POST /run/stream \u2014 SSE stream`));
2648
- console.log(chalk12.gray("\n Press Ctrl+C to stop.\n"));
3520
+ console.log(chalk18.gray(` Listening on http://localhost:${port}`));
3521
+ console.log(chalk18.gray(` GET /health`));
3522
+ console.log(chalk18.gray(` GET /agents`));
3523
+ console.log(chalk18.gray(` POST /run \u2014 JSON response`));
3524
+ console.log(chalk18.gray(` POST /run/stream \u2014 SSE stream`));
3525
+ console.log(chalk18.gray("\n Press Ctrl+C to stop.\n"));
2649
3526
  });
2650
3527
  await new Promise(() => {
2651
3528
  });
2652
3529
  }
2653
3530
 
2654
3531
  // ../../packages/cli/dist/commands/watch.js
2655
- import chalk13 from "chalk";
3532
+ import chalk19 from "chalk";
2656
3533
  import chokidar from "chokidar";
2657
3534
  function buildDebounce(fn, ms) {
2658
3535
  let timer = null;
@@ -2704,28 +3581,28 @@ ${result.output}
2704
3581
  }
2705
3582
  async function watchCommand(agent, prompt, opts) {
2706
3583
  const configPath = opts.config ?? resolveConfigPath();
2707
- const glob = opts.glob ?? "src/**/*.{ts,js,yaml,json}";
3584
+ const glob3 = opts.glob ?? "src/**/*.{ts,js,yaml,json}";
2708
3585
  const debounceMs = opts.debounce ? Number.parseInt(opts.debounce, 10) : 500;
2709
- console.log(chalk13.bold.cyan(`
3586
+ console.log(chalk19.bold.cyan(`
2710
3587
  \u25C6 omni watch`));
2711
- console.log(chalk13.gray(` agent: ${agent}`));
2712
- console.log(chalk13.gray(` glob: ${glob}`));
2713
- console.log(chalk13.gray(` debounce: ${debounceMs}ms`));
2714
- console.log(chalk13.gray(" Press Ctrl+C to stop.\n"));
3588
+ console.log(chalk19.gray(` agent: ${agent}`));
3589
+ console.log(chalk19.gray(` glob: ${glob3}`));
3590
+ console.log(chalk19.gray(` debounce: ${debounceMs}ms`));
3591
+ console.log(chalk19.gray(" Press Ctrl+C to stop.\n"));
2715
3592
  await runOnce(agent, prompt, configPath, opts.stream ?? false);
2716
3593
  const trigger = buildDebounce(async () => {
2717
- console.log(chalk13.gray(`
3594
+ console.log(chalk19.gray(`
2718
3595
  \u21BB Rerunning ${agent}...`));
2719
3596
  await runOnce(agent, prompt, configPath, opts.stream ?? false);
2720
3597
  }, debounceMs);
2721
- const watcher = chokidar.watch(glob, { ignoreInitial: true, ignored: /node_modules/ });
3598
+ const watcher = chokidar.watch(glob3, { ignoreInitial: true, ignored: /node_modules/ });
2722
3599
  watcher.on("change", (file) => {
2723
- console.log(chalk13.gray(`
3600
+ console.log(chalk19.gray(`
2724
3601
  \u270E Changed: ${file}`));
2725
3602
  trigger();
2726
3603
  });
2727
3604
  watcher.on("add", (file) => {
2728
- console.log(chalk13.gray(`
3605
+ console.log(chalk19.gray(`
2729
3606
  + Added: ${file}`));
2730
3607
  trigger();
2731
3608
  });
@@ -2733,7 +3610,7 @@ async function watchCommand(agent, prompt, opts) {
2733
3610
  console.error(errorLine(`Watcher error: ${err}`));
2734
3611
  });
2735
3612
  process.on("SIGINT", async () => {
2736
- console.log(chalk13.gray("\n\n Stopping watcher..."));
3613
+ console.log(chalk19.gray("\n\n Stopping watcher..."));
2737
3614
  await watcher.close();
2738
3615
  process.exit(0);
2739
3616
  });
@@ -2742,7 +3619,7 @@ async function watchCommand(agent, prompt, opts) {
2742
3619
  }
2743
3620
 
2744
3621
  // ../../packages/cli/dist/bin.js
2745
- var __dirname2 = dirname4(fileURLToPath3(import.meta.url));
3622
+ var __dirname2 = dirname5(fileURLToPath3(import.meta.url));
2746
3623
  loadDotenv({ path: resolve17(__dirname2, "..", "..", "..", ".env") });
2747
3624
  var program = new Command();
2748
3625
  program.name("omni").description("omni-ai \u2014 provider-agnostic AI agents for developer workflows").version("0.1.0");
@@ -2756,6 +3633,17 @@ program.command("serve").description("Start a local HTTP server to run agents vi
2756
3633
  program.command("eval <agent> <dataset>").description("Evaluate an agent against a dataset of (input, expected) pairs").option("-c, --config <path>", "Path to omni-ai.yaml").option("--concurrency <n>", "Number of parallel evaluations (default: 3)").option("-o, --output <file>", "Save JSON report to file").action(evalCommand);
2757
3634
  var mcp = program.command("mcp").description("MCP (Model Context Protocol) integration");
2758
3635
  mcp.command("serve").description("Expose all registered skills as MCP tools over stdio").option("-c, --config <path>", "Path to omni-ai.yaml").action(mcpServeCommand);
3636
+ var history = program.command("history").description("Import, search and inspect third-party AI agent history");
3637
+ history.command("sources").description("List known history providers and whether they're importable on this machine").option("--json", "Output as JSON").action(historySourcesCommand);
3638
+ history.command("import").description("Import history from one or all registered providers").option("--provider <name>", "Import a single provider").option("--all", "Import every registered provider").option("--path <path>", "Override the discovered path (requires --provider)").action(historyImportCommand);
3639
+ history.command("search [query]").description('Full-text search over imported history, e.g. omni history search "retry handling"').option("--term <term>", "Search term (repeatable)", (value, prev) => [...prev, value], []).option("--session <id>", "Restrict search to one session").option("--scope <name>", "Restrict search to one project scope (default: current directory's project)").option("--all-projects", "Search across every imported project, not just the current one").option("--limit <n>", "Max results (default: 20)").option("--refresh <mode>", "auto | off | strict (default: auto)").option("--json", "Output as JSON").action(historySearchCommand);
3640
+ var historyShow = history.command("show").description("Show one event (with context) or a full session");
3641
+ historyShow.command("event <id>").description("Show one event with surrounding context").option("--window <n>", "Events of context before/after (default: 3)").action(historyShowEventCommand);
3642
+ historyShow.command("session <sessionId>").description("Show a full session").option("-f, --format <format>", "text | markdown (default: text)").option("-o, --out <path>", "Write to a file instead of stdout").action(historyShowSessionCommand);
3643
+ var historyLocate = history.command("locate").description("Report the original source location for an event/session");
3644
+ historyLocate.command("event <id>").description("Locate the source file/line an event was imported from").option("--json", "Output as JSON").action(historyLocateEventCommand);
3645
+ historyLocate.command("session <sessionId>").description("Locate the source file a session was imported from").option("--json", "Output as JSON").action(historyLocateSessionCommand);
3646
+ history.command("doctor").description("Diagnose non-importable sources and broken citations").option("--json", "Output as JSON").action(historyDoctorCommand);
2759
3647
  var list = program.command("list").description("List available resources");
2760
3648
  list.command("agents").description("List all available agents").option("-c, --config <path>", "Path to omni-ai.yaml").action((opts) => listCommand("agents", opts));
2761
3649
  list.command("skills").description("List registered skills").option("-c, --config <path>", "Path to omni-ai.yaml").action((opts) => listCommand("skills", opts));