@kl-c/matrixos 0.2.1 → 0.2.6

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/index.js CHANGED
@@ -2163,7 +2163,7 @@ var package_default;
2163
2163
  var init_package = __esm(() => {
2164
2164
  package_default = {
2165
2165
  name: "@kl-c/matrixos",
2166
- version: "0.2.1",
2166
+ version: "0.2.6",
2167
2167
  description: "MaTrixOS \u2014 Agentic OS for OpenCode. Personalizable, communicating, self-improving, resilient.",
2168
2168
  main: "./dist/index.js",
2169
2169
  types: "dist/index.d.ts",
@@ -90353,11 +90353,22 @@ class TelegramAdapter {
90353
90353
  }
90354
90354
  const text = envelope.content.text ?? "";
90355
90355
  const result = await this.bot.api.sendMessage(chatId, text);
90356
- return String(result.message_id);
90356
+ const messageId = String(result.message_id);
90357
+ if (envelope.metadata?.onMessageId && typeof envelope.metadata.onMessageId === "function") {
90358
+ envelope.metadata.onMessageId(messageId);
90359
+ }
90360
+ return messageId;
90357
90361
  } catch (err) {
90358
90362
  throw new TelegramSendError(`Failed to send Telegram message: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
90359
90363
  }
90360
90364
  }
90365
+ async editMessage(recipientId, messageId, text) {
90366
+ try {
90367
+ await this.bot.api.editMessageText(recipientId, Number(messageId), text);
90368
+ } catch (err) {
90369
+ console.warn(`[telegram] editMessage failed: ${err instanceof Error ? err.message : String(err)}`);
90370
+ }
90371
+ }
90361
90372
  onMessage(handler) {
90362
90373
  this.messageHandler = handler;
90363
90374
  }
@@ -164418,6 +164429,351 @@ var require_picomatch2 = __commonJS((exports2, module2) => {
164418
164429
  module2.exports = picomatch;
164419
164430
  });
164420
164431
 
164432
+ // packages/omo-opencode/src/features/cron/store.ts
164433
+ function createCronStore() {
164434
+ const jobs = new Map;
164435
+ let counter = 0;
164436
+ return {
164437
+ add(input) {
164438
+ counter += 1;
164439
+ const now = new Date().toISOString();
164440
+ const job = {
164441
+ id: `cron-${counter}`,
164442
+ name: input.name,
164443
+ schedule: input.schedule,
164444
+ command: input.command,
164445
+ channel: input.channel,
164446
+ recipient: input.recipient,
164447
+ enabled: input.enabled ?? true,
164448
+ createdAt: now,
164449
+ updatedAt: now
164450
+ };
164451
+ CronJobSchema.parse(job);
164452
+ jobs.set(job.id, job);
164453
+ return job;
164454
+ },
164455
+ get(id) {
164456
+ return jobs.get(id);
164457
+ },
164458
+ list(filter) {
164459
+ const all = Array.from(jobs.values());
164460
+ return all.filter((j) => {
164461
+ if (filter?.enabled !== undefined && j.enabled !== filter.enabled)
164462
+ return false;
164463
+ if (filter?.channel && j.channel !== filter.channel)
164464
+ return false;
164465
+ return true;
164466
+ });
164467
+ },
164468
+ remove(id) {
164469
+ return jobs.delete(id);
164470
+ },
164471
+ size() {
164472
+ return jobs.size;
164473
+ }
164474
+ };
164475
+ }
164476
+ var CronJobSchema;
164477
+ var init_store = __esm(() => {
164478
+ init_zod();
164479
+ CronJobSchema = object({
164480
+ id: string2().min(1),
164481
+ name: string2().min(1).max(100),
164482
+ schedule: string2().min(1).max(100),
164483
+ command: string2().min(1),
164484
+ channel: _enum2(["telegram", "discord", "whatsapp"]).optional(),
164485
+ recipient: string2().optional(),
164486
+ enabled: boolean2().default(true),
164487
+ createdAt: string2(),
164488
+ updatedAt: string2()
164489
+ }).strict();
164490
+ });
164491
+
164492
+ // packages/task-ledger-core/src/schema.ts
164493
+ var TaskSourceSchema, TaskStatusSchema, TaskPrioritySchema, TaskSchema, TaskInsertSchema, TaskPatchSchema, TaskFilterSchema;
164494
+ var init_schema2 = __esm(() => {
164495
+ init_zod();
164496
+ TaskSourceSchema = _enum2(["webhook", "cron", "user", "kanban"]);
164497
+ TaskStatusSchema = _enum2([
164498
+ "pending",
164499
+ "running",
164500
+ "done",
164501
+ "failed",
164502
+ "cancelled"
164503
+ ]);
164504
+ TaskPrioritySchema = _enum2(["high", "medium", "low"]);
164505
+ TaskSchema = object({
164506
+ id: string2().min(1),
164507
+ source: TaskSourceSchema,
164508
+ context: string2().nullable(),
164509
+ status: TaskStatusSchema,
164510
+ priority: TaskPrioritySchema.nullable(),
164511
+ payload: string2(),
164512
+ agent_assigned: string2().nullable(),
164513
+ session_id: string2().nullable(),
164514
+ result: string2().nullable(),
164515
+ cost_tokens: number2().int().nonnegative().default(0),
164516
+ cost_usd: number2().nonnegative().default(0),
164517
+ created_at: number2().int(),
164518
+ started_at: number2().int().nullable(),
164519
+ completed_at: number2().int().nullable()
164520
+ }).strict();
164521
+ TaskInsertSchema = object({
164522
+ id: string2().min(1).optional(),
164523
+ source: TaskSourceSchema,
164524
+ context: string2().nullable().optional(),
164525
+ status: TaskStatusSchema.optional(),
164526
+ priority: TaskPrioritySchema.nullable().optional(),
164527
+ payload: string2(),
164528
+ agent_assigned: string2().nullable().optional(),
164529
+ session_id: string2().nullable().optional(),
164530
+ cost_tokens: number2().int().nonnegative().optional(),
164531
+ cost_usd: number2().nonnegative().optional()
164532
+ }).strict();
164533
+ TaskPatchSchema = object({
164534
+ status: TaskStatusSchema.optional(),
164535
+ priority: TaskPrioritySchema.nullable().optional(),
164536
+ agent_assigned: string2().nullable().optional(),
164537
+ session_id: string2().nullable().optional(),
164538
+ result: string2().nullable().optional(),
164539
+ cost_tokens: number2().int().nonnegative().optional(),
164540
+ cost_usd: number2().nonnegative().optional(),
164541
+ started_at: number2().int().nullable().optional(),
164542
+ completed_at: number2().int().nullable().optional()
164543
+ }).strict();
164544
+ TaskFilterSchema = object({
164545
+ source: TaskSourceSchema.optional(),
164546
+ context: string2().optional(),
164547
+ status: TaskStatusSchema.optional(),
164548
+ agent_assigned: string2().optional(),
164549
+ session_id: string2().optional(),
164550
+ priority: TaskPrioritySchema.optional()
164551
+ }).strict();
164552
+ });
164553
+
164554
+ // packages/task-ledger-core/src/ledger.ts
164555
+ import { randomUUID as randomUUID2 } from "crypto";
164556
+ function rowToTask(row) {
164557
+ return {
164558
+ id: row.id,
164559
+ source: row.source,
164560
+ context: row.context,
164561
+ status: row.status,
164562
+ priority: row.priority,
164563
+ payload: row.payload,
164564
+ agent_assigned: row.agent_assigned,
164565
+ session_id: row.session_id,
164566
+ result: row.result,
164567
+ cost_tokens: row.cost_tokens,
164568
+ cost_usd: row.cost_usd,
164569
+ created_at: row.created_at,
164570
+ started_at: row.started_at,
164571
+ completed_at: row.completed_at
164572
+ };
164573
+ }
164574
+ function createTaskLedger(db) {
164575
+ db.exec(CREATE_TABLE_SQL);
164576
+ db.exec(CREATE_INDEX_STATUS);
164577
+ db.exec(CREATE_INDEX_CONTEXT);
164578
+ db.exec(CREATE_INDEX_SOURCE);
164579
+ return {
164580
+ insert(input) {
164581
+ const now = Date.now();
164582
+ const task2 = TaskSchema.parse({
164583
+ id: input.id ?? randomUUID2(),
164584
+ source: input.source,
164585
+ context: input.context ?? null,
164586
+ status: input.status ?? "pending",
164587
+ priority: input.priority ?? null,
164588
+ payload: input.payload,
164589
+ agent_assigned: input.agent_assigned ?? null,
164590
+ session_id: input.session_id ?? null,
164591
+ result: null,
164592
+ cost_tokens: input.cost_tokens ?? 0,
164593
+ cost_usd: input.cost_usd ?? 0,
164594
+ created_at: now,
164595
+ started_at: null,
164596
+ completed_at: null
164597
+ });
164598
+ db.exec(INSERT_SQL, {
164599
+ $id: task2.id,
164600
+ $source: task2.source,
164601
+ $context: task2.context,
164602
+ $status: task2.status,
164603
+ $priority: task2.priority,
164604
+ $payload: task2.payload,
164605
+ $agent_assigned: task2.agent_assigned,
164606
+ $session_id: task2.session_id,
164607
+ $result: task2.result,
164608
+ $cost_tokens: task2.cost_tokens,
164609
+ $cost_usd: task2.cost_usd,
164610
+ $created_at: task2.created_at,
164611
+ $started_at: task2.started_at,
164612
+ $completed_at: task2.completed_at
164613
+ });
164614
+ return task2;
164615
+ },
164616
+ get(id) {
164617
+ const rows = db.query(SELECT_BY_ID_SQL, { $id: id });
164618
+ if (rows.length === 0)
164619
+ return null;
164620
+ return rowToTask(rows[0]);
164621
+ },
164622
+ list(filter) {
164623
+ const conditions = [];
164624
+ const params = {};
164625
+ if (filter?.source) {
164626
+ conditions.push("source = $source");
164627
+ params.$source = filter.source;
164628
+ }
164629
+ if (filter?.context) {
164630
+ conditions.push("context = $context");
164631
+ params.$context = filter.context;
164632
+ }
164633
+ if (filter?.status) {
164634
+ conditions.push("status = $status");
164635
+ params.$status = filter.status;
164636
+ }
164637
+ if (filter?.agent_assigned) {
164638
+ conditions.push("agent_assigned = $agent_assigned");
164639
+ params.$agent_assigned = filter.agent_assigned;
164640
+ }
164641
+ if (filter?.session_id) {
164642
+ conditions.push("session_id = $session_id");
164643
+ params.$session_id = filter.session_id;
164644
+ }
164645
+ if (filter?.priority) {
164646
+ conditions.push("priority = $priority");
164647
+ params.$priority = filter.priority;
164648
+ }
164649
+ const where = conditions.length > 0 ? ` WHERE ${conditions.join(" AND ")}` : "";
164650
+ const sql = `SELECT * FROM tasks${where} ORDER BY created_at DESC`;
164651
+ const rows = db.query(sql, params);
164652
+ return rows.map(rowToTask);
164653
+ },
164654
+ update(id, patch) {
164655
+ const existing = db.query(SELECT_BY_ID_SQL, { $id: id });
164656
+ if (existing.length === 0)
164657
+ return null;
164658
+ const params = { $id: id };
164659
+ if (patch.status !== undefined)
164660
+ params.$status = patch.status;
164661
+ if (patch.priority !== undefined)
164662
+ params.$priority = patch.priority;
164663
+ if (patch.agent_assigned !== undefined)
164664
+ params.$agent_assigned = patch.agent_assigned;
164665
+ if (patch.session_id !== undefined)
164666
+ params.$session_id = patch.session_id;
164667
+ if (patch.result !== undefined)
164668
+ params.$result = patch.result;
164669
+ if (patch.cost_tokens !== undefined)
164670
+ params.$cost_tokens = patch.cost_tokens;
164671
+ if (patch.cost_usd !== undefined)
164672
+ params.$cost_usd = patch.cost_usd;
164673
+ if (patch.started_at !== undefined)
164674
+ params.$started_at = patch.started_at;
164675
+ if (patch.completed_at !== undefined)
164676
+ params.$completed_at = patch.completed_at;
164677
+ db.exec(UPDATE_SQL, params);
164678
+ return this.get(id);
164679
+ },
164680
+ remove(id) {
164681
+ const before = db.query(SELECT_BY_ID_SQL, { $id: id });
164682
+ if (before.length === 0)
164683
+ return false;
164684
+ db.exec(DELETE_BY_ID_SQL, { $id: id });
164685
+ return true;
164686
+ },
164687
+ listPending() {
164688
+ const rows = db.query(`SELECT * FROM tasks WHERE status = 'pending' ORDER BY created_at ASC`);
164689
+ return rows.map(rowToTask);
164690
+ },
164691
+ listFailed() {
164692
+ const rows = db.query(`SELECT * FROM tasks WHERE status = 'failed' ORDER BY created_at ASC`);
164693
+ return rows.map(rowToTask);
164694
+ },
164695
+ listByContext(context) {
164696
+ const rows = db.query(`SELECT * FROM tasks WHERE context = $context ORDER BY created_at DESC`, { $context: context });
164697
+ return rows.map(rowToTask);
164698
+ },
164699
+ close() {
164700
+ db.close();
164701
+ }
164702
+ };
164703
+ }
164704
+ var CREATE_TABLE_SQL = `
164705
+ CREATE TABLE IF NOT EXISTS tasks (
164706
+ id TEXT PRIMARY KEY,
164707
+ source TEXT NOT NULL,
164708
+ context TEXT,
164709
+ status TEXT NOT NULL,
164710
+ priority TEXT,
164711
+ payload TEXT NOT NULL,
164712
+ agent_assigned TEXT,
164713
+ session_id TEXT,
164714
+ result TEXT,
164715
+ cost_tokens INTEGER DEFAULT 0,
164716
+ cost_usd REAL DEFAULT 0,
164717
+ created_at INTEGER NOT NULL,
164718
+ started_at INTEGER,
164719
+ completed_at INTEGER
164720
+ )
164721
+ `, CREATE_INDEX_STATUS = `CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status)`, CREATE_INDEX_CONTEXT = `CREATE INDEX IF NOT EXISTS idx_tasks_context ON tasks(context)`, CREATE_INDEX_SOURCE = `CREATE INDEX IF NOT EXISTS idx_tasks_source ON tasks(source)`, INSERT_SQL = `
164722
+ INSERT INTO tasks (id, source, context, status, priority, payload, agent_assigned, session_id, result, cost_tokens, cost_usd, created_at, started_at, completed_at)
164723
+ VALUES ($id, $source, $context, $status, $priority, $payload, $agent_assigned, $session_id, $result, $cost_tokens, $cost_usd, $created_at, $started_at, $completed_at)
164724
+ `, SELECT_BY_ID_SQL = `SELECT * FROM tasks WHERE id = $id`, DELETE_BY_ID_SQL = `DELETE FROM tasks WHERE id = $id`, UPDATE_SQL = `
164725
+ UPDATE tasks SET
164726
+ status = COALESCE($status, status),
164727
+ priority = COALESCE($priority, priority),
164728
+ agent_assigned = COALESCE($agent_assigned, agent_assigned),
164729
+ session_id = COALESCE($session_id, session_id),
164730
+ result = COALESCE($result, result),
164731
+ cost_tokens = COALESCE($cost_tokens, cost_tokens),
164732
+ cost_usd = COALESCE($cost_usd, cost_usd),
164733
+ started_at = COALESCE($started_at, started_at),
164734
+ completed_at = COALESCE($completed_at, completed_at)
164735
+ WHERE id = $id
164736
+ `;
164737
+ var init_ledger = __esm(() => {
164738
+ init_schema2();
164739
+ });
164740
+
164741
+ // packages/task-ledger-core/src/sqlite.ts
164742
+ import { Database as Database2 } from "bun:sqlite";
164743
+ function createSqliteDatabase(dbPath) {
164744
+ const db = new Database2(dbPath);
164745
+ db.exec("PRAGMA journal_mode = WAL");
164746
+ db.exec("PRAGMA foreign_keys = ON");
164747
+ return {
164748
+ exec(sql, ...params) {
164749
+ if (params.length === 0) {
164750
+ db.run(sql);
164751
+ } else {
164752
+ const named = params[0];
164753
+ db.run(sql, named);
164754
+ }
164755
+ },
164756
+ query(sql, ...params) {
164757
+ if (params.length === 0) {
164758
+ return db.prepare(sql).all();
164759
+ }
164760
+ const named = params[0];
164761
+ return db.prepare(sql).all(named);
164762
+ },
164763
+ close() {
164764
+ db.close();
164765
+ }
164766
+ };
164767
+ }
164768
+ var init_sqlite = () => {};
164769
+
164770
+ // packages/task-ledger-core/src/index.ts
164771
+ var init_src6 = __esm(() => {
164772
+ init_schema2();
164773
+ init_ledger();
164774
+ init_sqlite();
164775
+ });
164776
+
164421
164777
  // packages/omo-opencode/src/cli/generate.ts
164422
164778
  var exports_generate = {};
164423
164779
  __export(exports_generate, {
@@ -165020,6 +165376,264 @@ var init_export = __esm(() => {
165020
165376
  };
165021
165377
  });
165022
165378
 
165379
+ // packages/omo-opencode/src/project/project-context.ts
165380
+ var exports_project_context = {};
165381
+ __export(exports_project_context, {
165382
+ unarchiveProject: () => unarchiveProject,
165383
+ switchProject: () => switchProject,
165384
+ saveState: () => saveState,
165385
+ saveProjectMeta: () => saveProjectMeta,
165386
+ loadState: () => loadState,
165387
+ loadProjectMeta: () => loadProjectMeta,
165388
+ listProjects: () => listProjects,
165389
+ initProjectFiles: () => initProjectFiles,
165390
+ getStatePath: () => getStatePath,
165391
+ getProjectsDir: () => getProjectsDir,
165392
+ getProjectDir: () => getProjectDir,
165393
+ getMatrixOsDir: () => getMatrixOsDir,
165394
+ getActiveProject: () => getActiveProject,
165395
+ deleteProject: () => deleteProject,
165396
+ createProject: () => createProject,
165397
+ archiveProject: () => archiveProject
165398
+ });
165399
+ import { existsSync as existsSync75, mkdirSync as mkdirSync27, readFileSync as readFileSync60, writeFileSync as writeFileSync27, rmSync as rmSync8 } from "fs";
165400
+ import { join as join81 } from "path";
165401
+ function getMatrixOsDir(cwd = process.cwd()) {
165402
+ return join81(cwd, ".matrixos");
165403
+ }
165404
+ function getProjectsDir(cwd) {
165405
+ return join81(getMatrixOsDir(cwd), "projects");
165406
+ }
165407
+ function getProjectDir(slug, cwd) {
165408
+ return join81(getProjectsDir(cwd), slug);
165409
+ }
165410
+ function getStatePath(cwd) {
165411
+ return join81(getMatrixOsDir(cwd), "state.json");
165412
+ }
165413
+ function loadState(cwd) {
165414
+ const path29 = getStatePath(cwd);
165415
+ if (!existsSync75(path29))
165416
+ return {};
165417
+ try {
165418
+ return JSON.parse(readFileSync60(path29, "utf-8"));
165419
+ } catch {
165420
+ return {};
165421
+ }
165422
+ }
165423
+ function saveState(state2, cwd) {
165424
+ const path29 = getStatePath(cwd);
165425
+ mkdirSync27(getMatrixOsDir(cwd), { recursive: true });
165426
+ writeFileSync27(path29, JSON.stringify(state2, null, 2) + `
165427
+ `);
165428
+ }
165429
+ function loadProjectMeta(slug, cwd) {
165430
+ const path29 = join81(getProjectDir(slug, cwd), "meta.json");
165431
+ if (!existsSync75(path29))
165432
+ return null;
165433
+ try {
165434
+ return JSON.parse(readFileSync60(path29, "utf-8"));
165435
+ } catch {
165436
+ return null;
165437
+ }
165438
+ }
165439
+ function saveProjectMeta(slug, meta3, cwd) {
165440
+ const dir = getProjectDir(slug, cwd);
165441
+ mkdirSync27(dir, { recursive: true });
165442
+ const path29 = join81(dir, "meta.json");
165443
+ writeFileSync27(path29, JSON.stringify(meta3, null, 2) + `
165444
+ `);
165445
+ }
165446
+ function initProjectFiles(slug, cwd) {
165447
+ const dir = getProjectDir(slug, cwd);
165448
+ mkdirSync27(join81(dir, "kb"), { recursive: true });
165449
+ const kanbanPath = join81(dir, "kanban.json");
165450
+ if (!existsSync75(kanbanPath)) {
165451
+ writeFileSync27(kanbanPath, JSON.stringify({ columns: ["todo", "in-progress", "review", "done"], tasks: [] }, null, 2) + `
165452
+ `);
165453
+ }
165454
+ }
165455
+ function createProject(slug, options = {}) {
165456
+ if (!/^[a-z0-9_-]+$/.test(slug)) {
165457
+ throw new Error(`Invalid project slug "${slug}": only lowercase letters, numbers, - and _ are allowed.`);
165458
+ }
165459
+ const dir = getProjectDir(slug, options.cwd);
165460
+ if (existsSync75(dir)) {
165461
+ throw new Error(`Project "${slug}" already exists.`);
165462
+ }
165463
+ const now = new Date().toISOString();
165464
+ const meta3 = {
165465
+ slug,
165466
+ name: options.name || slug,
165467
+ description: options.description,
165468
+ createdAt: now
165469
+ };
165470
+ saveProjectMeta(slug, meta3, options.cwd);
165471
+ initProjectFiles(slug, options.cwd);
165472
+ const state2 = loadState(options.cwd);
165473
+ if (!state2.activeProject) {
165474
+ saveState({ ...state2, activeProject: slug }, options.cwd);
165475
+ }
165476
+ return { slug, meta: meta3, active: state2.activeProject === slug || !state2.activeProject };
165477
+ }
165478
+ function listProjects(cwd) {
165479
+ const state2 = loadState(cwd);
165480
+ const root = getProjectsDir(cwd);
165481
+ if (!existsSync75(root))
165482
+ return [];
165483
+ const fs24 = __require("fs");
165484
+ const items = [];
165485
+ for (const slug of fs24.readdirSync(root, { withFileTypes: true })) {
165486
+ if (!slug.isDirectory())
165487
+ continue;
165488
+ const meta3 = loadProjectMeta(slug.name, cwd);
165489
+ if (!meta3)
165490
+ continue;
165491
+ items.push({ slug: slug.name, meta: meta3, active: state2.activeProject === slug.name });
165492
+ }
165493
+ return items.sort((a2, b2) => a2.slug.localeCompare(b2.slug));
165494
+ }
165495
+ function switchProject(slug, cwd) {
165496
+ const meta3 = loadProjectMeta(slug, cwd);
165497
+ if (!meta3)
165498
+ throw new Error(`Project "${slug}" does not exist.`);
165499
+ if (meta3.archived)
165500
+ throw new Error(`Project "${slug}" is archived. Unarchive it before switching.`);
165501
+ const state2 = loadState(cwd);
165502
+ saveState({ ...state2, activeProject: slug }, cwd);
165503
+ return { slug, meta: meta3, active: true };
165504
+ }
165505
+ function archiveProject(slug, cwd) {
165506
+ const meta3 = loadProjectMeta(slug, cwd);
165507
+ if (!meta3)
165508
+ throw new Error(`Project "${slug}" does not exist.`);
165509
+ const now = new Date().toISOString();
165510
+ const next = { ...meta3, archived: true, archivedAt: now };
165511
+ saveProjectMeta(slug, next, cwd);
165512
+ const state2 = loadState(cwd);
165513
+ if (state2.activeProject === slug) {
165514
+ saveState({ ...state2, activeProject: undefined }, cwd);
165515
+ }
165516
+ return { slug, meta: next, active: false };
165517
+ }
165518
+ function unarchiveProject(slug, cwd) {
165519
+ const meta3 = loadProjectMeta(slug, cwd);
165520
+ if (!meta3)
165521
+ throw new Error(`Project "${slug}" does not exist.`);
165522
+ const { archived: _a3, archivedAt: _b, ...rest } = meta3;
165523
+ const next = rest;
165524
+ saveProjectMeta(slug, next, cwd);
165525
+ return { slug, meta: next, active: loadState(cwd).activeProject === slug };
165526
+ }
165527
+ function deleteProject(slug, cwd) {
165528
+ const dir = getProjectDir(slug, cwd);
165529
+ if (!existsSync75(dir))
165530
+ throw new Error(`Project "${slug}" does not exist.`);
165531
+ rmSync8(dir, { recursive: true, force: true });
165532
+ const state2 = loadState(cwd);
165533
+ if (state2.activeProject === slug) {
165534
+ saveState({ ...state2, activeProject: undefined }, cwd);
165535
+ }
165536
+ }
165537
+ function getActiveProject(cwd) {
165538
+ const state2 = loadState(cwd);
165539
+ if (!state2.activeProject)
165540
+ return null;
165541
+ const meta3 = loadProjectMeta(state2.activeProject, cwd);
165542
+ if (!meta3) {
165543
+ saveState({ ...state2, activeProject: undefined }, cwd);
165544
+ return null;
165545
+ }
165546
+ return { slug: state2.activeProject, meta: meta3, active: true };
165547
+ }
165548
+ var init_project_context = () => {};
165549
+
165550
+ // packages/omo-opencode/src/project/project-memory.ts
165551
+ var exports_project_memory = {};
165552
+ __export(exports_project_memory, {
165553
+ tagWithProject: () => tagWithProject,
165554
+ searchProject: () => searchProject,
165555
+ searchKb: () => searchKb,
165556
+ listKbDocuments: () => listKbDocuments,
165557
+ isProjectEpisode: () => isProjectEpisode,
165558
+ addKbDocument: () => addKbDocument
165559
+ });
165560
+ import { existsSync as existsSync76, mkdirSync as mkdirSync28, readFileSync as readFileSync61, readdirSync as readdirSync16, writeFileSync as writeFileSync28 } from "fs";
165561
+ import { join as join82 } from "path";
165562
+ function tagWithProject(metadata = {}, projectSlug, cwd) {
165563
+ const active = projectSlug ?? getActiveProject(cwd)?.slug;
165564
+ if (!active)
165565
+ return metadata;
165566
+ return { ...metadata, project: active };
165567
+ }
165568
+ function isProjectEpisode(ep, projectSlug, cwd) {
165569
+ const target = projectSlug ?? getActiveProject(cwd)?.slug;
165570
+ if (!target)
165571
+ return true;
165572
+ return ep.metadata?.project === target;
165573
+ }
165574
+ function listKbDocuments(projectSlug, cwd) {
165575
+ const kbDir = join82(getProjectDir(projectSlug, cwd), "kb");
165576
+ if (!existsSync76(kbDir))
165577
+ return [];
165578
+ const docs = [];
165579
+ for (const entry of readdirSync16(kbDir, { withFileTypes: true })) {
165580
+ if (!entry.isFile())
165581
+ continue;
165582
+ const path29 = join82(kbDir, entry.name);
165583
+ try {
165584
+ docs.push({ path: path29, content: readFileSync61(path29, "utf-8") });
165585
+ } catch {}
165586
+ }
165587
+ return docs;
165588
+ }
165589
+ function searchKb(projectSlug, query, cwd) {
165590
+ const needle = query.toLowerCase();
165591
+ const docs = listKbDocuments(projectSlug, cwd);
165592
+ const results = [];
165593
+ for (const doc2 of docs) {
165594
+ const content = doc2.content.toLowerCase();
165595
+ const matches = content.split(needle).length - 1;
165596
+ if (matches > 0) {
165597
+ results.push({
165598
+ project: projectSlug,
165599
+ source: "kb",
165600
+ path: doc2.path,
165601
+ content: doc2.content.slice(0, 240),
165602
+ score: matches
165603
+ });
165604
+ }
165605
+ }
165606
+ return results.sort((a2, b2) => b2.score - a2.score);
165607
+ }
165608
+ async function searchProject(query, options = {}) {
165609
+ const projectSlug = options.projectSlug ?? getActiveProject(options.cwd)?.slug;
165610
+ if (!projectSlug)
165611
+ return [];
165612
+ const kbHits = searchKb(projectSlug, query, options.cwd);
165613
+ let memoryHits = [];
165614
+ if (options.memoryStore) {
165615
+ const episodes = options.memoryStore.searchEpisodes?.({ textContains: query, limit: 20 }) ?? [];
165616
+ memoryHits = episodes.filter((ep) => ep.metadata?.project === projectSlug).map((ep) => ({
165617
+ project: projectSlug,
165618
+ source: "episode",
165619
+ summary: ep.summary,
165620
+ score: 1
165621
+ }));
165622
+ }
165623
+ return [...kbHits, ...memoryHits].sort((a2, b2) => b2.score - a2.score);
165624
+ }
165625
+ function addKbDocument(projectSlug, filename, content, cwd) {
165626
+ const kbDir = join82(getProjectDir(projectSlug, cwd), "kb");
165627
+ mkdirSync28(kbDir, { recursive: true });
165628
+ const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_");
165629
+ const path29 = join82(kbDir, safeName);
165630
+ writeFileSync28(path29, content, "utf-8");
165631
+ return path29;
165632
+ }
165633
+ var init_project_memory = __esm(() => {
165634
+ init_project_context();
165635
+ });
165636
+
165023
165637
  // packages/omo-opencode/src/cli/adopt.ts
165024
165638
  var exports_adopt = {};
165025
165639
  __export(exports_adopt, {
@@ -165141,6 +165755,13 @@ async function runAdopt(options = {}) {
165141
165755
  message: "Global adoption requires an interactive terminal. Run: matrixos adopt (no arguments)."
165142
165756
  };
165143
165757
  }
165758
+ if (!process.stdin.isTTY) {
165759
+ return {
165760
+ ok: false,
165761
+ message: `Cannot run interactive adoption: stdin is not a TTY.
165762
+ ` + "Run in a terminal, or use: matrixos gateway adopt telegram --token <token>"
165763
+ };
165764
+ }
165144
165765
  console.log(`
165145
165766
  === MaTrixOS Re-Adoption ===`);
165146
165767
  console.log(`You can reconfigure providers, channels, and profile.
@@ -165347,12 +165968,12 @@ __export(exports_gateway_start, {
165347
165968
  buildTelegramConfig: () => buildTelegramConfig,
165348
165969
  buildGatewayConfig: () => buildGatewayConfig
165349
165970
  });
165350
- import { readFileSync as readFileSync60, existsSync as existsSync75 } from "fs";
165971
+ import { readFileSync as readFileSync62, existsSync as existsSync77 } from "fs";
165351
165972
  import { resolve as resolve19 } from "path";
165352
165973
  function loadGatewayEnv(path29 = ENV_PATH) {
165353
- if (!existsSync75(path29))
165974
+ if (!existsSync77(path29))
165354
165975
  return {};
165355
- const text = readFileSync60(path29, "utf8");
165976
+ const text = readFileSync62(path29, "utf8");
165356
165977
  const out = {};
165357
165978
  for (const raw of text.split(/\r?\n/)) {
165358
165979
  const line = raw.trim();
@@ -165472,6 +166093,537 @@ var init_gateway_start = __esm(() => {
165472
166093
  ENV_PATH = resolve19(process.cwd(), ".klc-gateway.env");
165473
166094
  });
165474
166095
 
166096
+ // packages/omo-opencode/src/deployment/deployment-core.ts
166097
+ function registerTarget(target) {
166098
+ targets.set(target.name, target);
166099
+ }
166100
+ function getTarget(name2) {
166101
+ return targets.get(name2);
166102
+ }
166103
+ function listTargets() {
166104
+ return Array.from(targets.keys());
166105
+ }
166106
+ var targets;
166107
+ var init_deployment_core = __esm(() => {
166108
+ targets = new Map;
166109
+ });
166110
+
166111
+ // packages/omo-opencode/src/deployment/deploy-static.ts
166112
+ import { spawn as spawn6 } from "child_process";
166113
+ import { existsSync as existsSync78 } from "fs";
166114
+ import { resolve as resolve20 } from "path";
166115
+ function pushStage(stage, message, ok = true) {
166116
+ return { stage, message, ok };
166117
+ }
166118
+ function run2(cmd, args, cwd) {
166119
+ return new Promise((resolve21) => {
166120
+ let output = "";
166121
+ let error51 = "";
166122
+ const child = spawn6(cmd, args, { cwd, shell: false });
166123
+ child.stdout.on("data", (d) => output += d.toString());
166124
+ child.stderr.on("data", (d) => error51 += d.toString());
166125
+ child.on("close", (code) => resolve21({ ok: code === 0, output, error: error51 }));
166126
+ });
166127
+ }
166128
+ var deployStatic;
166129
+ var init_deploy_static = __esm(() => {
166130
+ deployStatic = {
166131
+ name: "static",
166132
+ async deploy(ctx, params) {
166133
+ const stages = [];
166134
+ const buildDir = resolve20(ctx.projectRoot, params.buildDir ?? "dist");
166135
+ const destination = params.destination;
166136
+ const prebuild = params.prebuild ?? "bun run build";
166137
+ try {
166138
+ if (!destination) {
166139
+ return { target: "static", ok: false, stages: [pushStage("build", "missing destination parameter", false)], error: "missing destination" };
166140
+ }
166141
+ if (ctx.environment === "production" && ctx.requireValidation && !params.force) {
166142
+ return {
166143
+ target: "static",
166144
+ ok: false,
166145
+ stages: [pushStage("build", "production deploy requires explicit validation (force=true or use staging)", false)],
166146
+ error: "validation required"
166147
+ };
166148
+ }
166149
+ if (!ctx.execute) {
166150
+ return {
166151
+ target: "static",
166152
+ ok: true,
166153
+ url: destination,
166154
+ stages: [
166155
+ pushStage("build", `dry-run: would run '${prebuild}' in ${ctx.projectRoot}`),
166156
+ pushStage("push", `dry-run: would rsync ${buildDir} to ${destination}`),
166157
+ pushStage("verify", "dry-run: would verify 200 from deployed URL")
166158
+ ]
166159
+ };
166160
+ }
166161
+ if (prebuild) {
166162
+ stages.push(pushStage("build", `running '${prebuild}'...`));
166163
+ const build = await run2(prebuild, [], ctx.projectRoot);
166164
+ if (!build.ok) {
166165
+ stages.push(pushStage("build", `build failed: ${build.error}`, false));
166166
+ return { target: "static", ok: false, stages, error: build.error };
166167
+ }
166168
+ stages.push(pushStage("build", "build succeeded"));
166169
+ }
166170
+ if (!existsSync78(buildDir)) {
166171
+ stages.push(pushStage("push", `build directory not found: ${buildDir}`, false));
166172
+ return { target: "static", ok: false, stages, error: "build directory missing" };
166173
+ }
166174
+ stages.push(pushStage("push", `syncing ${buildDir} to ${destination}...`));
166175
+ const rsync = await run2("rsync", ["-avz", "--delete", buildDir + "/", destination], ctx.projectRoot);
166176
+ if (!rsync.ok) {
166177
+ stages.push(pushStage("push", `rsync failed: ${rsync.error}`, false));
166178
+ return { target: "static", ok: false, stages, error: rsync.error };
166179
+ }
166180
+ stages.push(pushStage("push", "sync complete"));
166181
+ const url3 = params.verifyUrl;
166182
+ if (url3) {
166183
+ stages.push(pushStage("verify", `checking ${url3}...`));
166184
+ const check2 = await run2("curl", ["-sf", url3], ctx.projectRoot);
166185
+ if (!check2.ok) {
166186
+ stages.push(pushStage("verify", `verify failed: ${check2.error}`, false));
166187
+ return { target: "static", ok: false, stages, error: check2.error };
166188
+ }
166189
+ stages.push(pushStage("verify", "verify ok"));
166190
+ }
166191
+ return { target: "static", ok: true, url: url3, stages };
166192
+ } catch (err) {
166193
+ const error51 = err instanceof Error ? err.message : String(err);
166194
+ stages.push(pushStage("done", `unexpected error: ${error51}`, false));
166195
+ return { target: "static", ok: false, stages, error: error51 };
166196
+ }
166197
+ }
166198
+ };
166199
+ });
166200
+
166201
+ // packages/omo-opencode/src/deployment/deploy-vercel.ts
166202
+ import { spawn as spawn7 } from "child_process";
166203
+ function pushStage2(stage, message, ok = true) {
166204
+ return { stage, message, ok };
166205
+ }
166206
+ function run3(cmd, args, cwd, env5) {
166207
+ return new Promise((resolve21) => {
166208
+ let output = "";
166209
+ let error51 = "";
166210
+ const child = spawn7(cmd, args, { cwd, env: { ...process.env, ...env5 }, shell: false });
166211
+ child.stdout.on("data", (d) => output += d.toString());
166212
+ child.stderr.on("data", (d) => error51 += d.toString());
166213
+ child.on("close", (code) => resolve21({ ok: code === 0, output, error: error51 }));
166214
+ });
166215
+ }
166216
+ var deployVercel;
166217
+ var init_deploy_vercel = __esm(() => {
166218
+ deployVercel = {
166219
+ name: "vercel",
166220
+ async deploy(ctx, params) {
166221
+ const stages = [];
166222
+ const prod = ctx.environment === "production";
166223
+ const token = process.env.VERCEL_TOKEN || params.token;
166224
+ try {
166225
+ if (prod && ctx.requireValidation && !params.force) {
166226
+ return {
166227
+ target: "vercel",
166228
+ ok: false,
166229
+ stages: [pushStage2("build", "production deploy to Vercel requires explicit validation", false)],
166230
+ error: "validation required"
166231
+ };
166232
+ }
166233
+ if (!ctx.execute) {
166234
+ return {
166235
+ target: "vercel",
166236
+ ok: true,
166237
+ stages: [
166238
+ pushStage2("build", `dry-run: would run vercel deploy${prod ? " --prod" : ""}`),
166239
+ pushStage2("verify", "dry-run: would verify deployment URL")
166240
+ ]
166241
+ };
166242
+ }
166243
+ if (!token && prod) {
166244
+ stages.push(pushStage2("build", "VERCEL_TOKEN missing", false));
166245
+ return { target: "vercel", ok: false, stages, error: "missing VERCEL_TOKEN" };
166246
+ }
166247
+ const args = ["deploy"];
166248
+ if (prod)
166249
+ args.push("--prod");
166250
+ if (token)
166251
+ args.push("--token", token);
166252
+ if (params.scope)
166253
+ args.push("--scope", params.scope);
166254
+ stages.push(pushStage2("push", `vercel ${args.join(" ")}...`));
166255
+ const result = await run3("vercel", args, ctx.projectRoot, token ? { VERCEL_TOKEN: token } : undefined);
166256
+ if (!result.ok) {
166257
+ stages.push(pushStage2("push", `vercel deploy failed: ${result.error}`, false));
166258
+ return { target: "vercel", ok: false, stages, error: result.error };
166259
+ }
166260
+ const urlMatch = result.output.match(/https:\/\/[^\s]+\.vercel\.app/);
166261
+ const url3 = urlMatch?.[0];
166262
+ stages.push(pushStage2("verify", url3 ? `deployed to ${url3}` : "deployed (URL not parsed)"));
166263
+ return { target: "vercel", ok: true, url: url3, stages };
166264
+ } catch (err) {
166265
+ const error51 = err instanceof Error ? err.message : String(err);
166266
+ stages.push(pushStage2("done", `unexpected error: ${error51}`, false));
166267
+ return { target: "vercel", ok: false, stages, error: error51 };
166268
+ }
166269
+ }
166270
+ };
166271
+ });
166272
+
166273
+ // packages/omo-opencode/src/deployment/deploy-vps.ts
166274
+ import { spawn as spawn8 } from "child_process";
166275
+ function pushStage3(stage, message, ok = true) {
166276
+ return { stage, message, ok };
166277
+ }
166278
+ function run4(cmd, args, cwd, env5) {
166279
+ return new Promise((resolve21) => {
166280
+ let output = "";
166281
+ let error51 = "";
166282
+ const child = spawn8(cmd, args, { cwd, env: { ...process.env, ...env5 }, shell: false });
166283
+ child.stdout.on("data", (d) => output += d.toString());
166284
+ child.stderr.on("data", (d) => error51 += d.toString());
166285
+ child.on("close", (code) => resolve21({ ok: code === 0, output, error: error51 }));
166286
+ });
166287
+ }
166288
+ var deployVps;
166289
+ var init_deploy_vps = __esm(() => {
166290
+ deployVps = {
166291
+ name: "vps",
166292
+ async deploy(ctx, params) {
166293
+ const stages = [];
166294
+ const host = params.host;
166295
+ const user = params.user ?? "deploy";
166296
+ const remoteDir = params.remoteDir;
166297
+ const buildDir = params.buildDir ?? "dist";
166298
+ const service = params.service;
166299
+ const healthUrl = params.healthUrl;
166300
+ try {
166301
+ if (!host || !remoteDir) {
166302
+ return { target: "vps", ok: false, stages: [pushStage3("build", "missing host or remoteDir", false)], error: "missing parameters" };
166303
+ }
166304
+ if (ctx.environment === "production" && ctx.requireValidation && !params.force) {
166305
+ return {
166306
+ target: "vps",
166307
+ ok: false,
166308
+ stages: [pushStage3("build", "production deploy to VPS requires explicit validation", false)],
166309
+ error: "validation required"
166310
+ };
166311
+ }
166312
+ if (!ctx.execute) {
166313
+ return {
166314
+ target: "vps",
166315
+ ok: true,
166316
+ stages: [
166317
+ pushStage3("build", `dry-run: would build in ${ctx.projectRoot}`),
166318
+ pushStage3("push", `dry-run: would rsync ${buildDir} to ${user}@${host}:${remoteDir}`),
166319
+ pushStage3("verify", `dry-run: would restart ${service ?? "service"} + health check ${healthUrl ?? ""}`)
166320
+ ]
166321
+ };
166322
+ }
166323
+ stages.push(pushStage3("build", "building..."));
166324
+ const build = await run4("bun", ["run", "build"], ctx.projectRoot);
166325
+ if (!build.ok) {
166326
+ stages.push(pushStage3("build", `build failed: ${build.error}`, false));
166327
+ return { target: "vps", ok: false, stages, error: build.error };
166328
+ }
166329
+ stages.push(pushStage3("build", "build ok"));
166330
+ stages.push(pushStage3("push", `rsync to ${host}...`));
166331
+ const rsync = await run4("rsync", ["-avz", "--delete", `${buildDir}/`, `${user}@${host}:${remoteDir}/`], ctx.projectRoot);
166332
+ if (!rsync.ok) {
166333
+ stages.push(pushStage3("push", `rsync failed: ${rsync.error}`, false));
166334
+ return { target: "vps", ok: false, stages, error: rsync.error };
166335
+ }
166336
+ stages.push(pushStage3("push", "rsync ok"));
166337
+ if (service) {
166338
+ stages.push(pushStage3("verify", `restarting ${service}...`));
166339
+ const restart = await run4("ssh", [`${user}@${host}`, `sudo systemctl restart ${service}`], ctx.projectRoot);
166340
+ if (!restart.ok) {
166341
+ stages.push(pushStage3("verify", `restart failed: ${restart.error}`, false));
166342
+ return { target: "vps", ok: false, stages, error: restart.error };
166343
+ }
166344
+ stages.push(pushStage3("verify", "restart ok"));
166345
+ }
166346
+ if (healthUrl) {
166347
+ stages.push(pushStage3("verify", `health check ${healthUrl}...`));
166348
+ await new Promise((r2) => setTimeout(r2, 2000));
166349
+ const health = await run4("curl", ["-sf", healthUrl], ctx.projectRoot);
166350
+ if (!health.ok) {
166351
+ stages.push(pushStage3("verify", `health check failed: ${health.error}`, false));
166352
+ return { target: "vps", ok: false, stages, error: health.error };
166353
+ }
166354
+ stages.push(pushStage3("verify", "health ok"));
166355
+ }
166356
+ return { target: "vps", ok: true, url: healthUrl, stages };
166357
+ } catch (err) {
166358
+ const error51 = err instanceof Error ? err.message : String(err);
166359
+ stages.push(pushStage3("done", `unexpected error: ${error51}`, false));
166360
+ return { target: "vps", ok: false, stages, error: error51 };
166361
+ }
166362
+ }
166363
+ };
166364
+ });
166365
+
166366
+ // packages/omo-opencode/src/deployment/deploy-cli.ts
166367
+ import { resolve as resolve21 } from "path";
166368
+ async function runDeploy(options) {
166369
+ const target = getTarget(options.target);
166370
+ if (!target) {
166371
+ console.error(`Unknown deployment target: ${options.target}`);
166372
+ console.error(`Available: ${["static", "vercel", "vps", "docker", "wordpress"].join(", ")}`);
166373
+ return 1;
166374
+ }
166375
+ const project = options.projectRoot ? undefined : await getActiveProject();
166376
+ if (!options.projectRoot && !project) {
166377
+ console.error("No active project. Run `matrixos project switch <slug>` or pass --project-root.");
166378
+ return 1;
166379
+ }
166380
+ const projectRoot = resolve21(options.projectRoot ?? getProjectDir(project.slug));
166381
+ const ctx = {
166382
+ projectRoot,
166383
+ projectSlug: project?.slug,
166384
+ environment: options.environment ?? (options.dryRun ? "staging" : "production"),
166385
+ execute: !options.dryRun,
166386
+ requireValidation: true
166387
+ };
166388
+ const params = {};
166389
+ for (const p2 of options.params ?? []) {
166390
+ const [key, ...rest] = p2.split("=");
166391
+ if (key)
166392
+ params[key] = rest.join("=");
166393
+ }
166394
+ if (ctx.environment === "production" && ctx.requireValidation && !options.force) {
166395
+ console.warn("Production deployment. This action requires explicit validation.");
166396
+ console.warn("Re-run with --force to confirm, or use --env staging.");
166397
+ return 1;
166398
+ }
166399
+ const result = await target.deploy(ctx, params);
166400
+ if (result.ok) {
166401
+ console.log(`\u2713 Deployed to ${result.target}${result.url ? ` \u2192 ${result.url}` : ""}`);
166402
+ for (const s of result.stages) {
166403
+ console.log(` [${s.stage}] ${s.ok ? "\u2713" : "\u2717"} ${s.message}`);
166404
+ }
166405
+ return 0;
166406
+ }
166407
+ console.error(`\u2717 Deploy to ${result.target} failed: ${result.error ?? "unknown error"}`);
166408
+ for (const s of result.stages) {
166409
+ console.log(` [${s.stage}] ${s.ok ? "\u2713" : "\u2717"} ${s.message}`);
166410
+ }
166411
+ return 1;
166412
+ }
166413
+ var init_deploy_cli = __esm(() => {
166414
+ init_project_context();
166415
+ init_deployment_core();
166416
+ });
166417
+
166418
+ // packages/omo-opencode/src/deployment/index.ts
166419
+ var exports_deployment = {};
166420
+ __export(exports_deployment, {
166421
+ targets: () => targets,
166422
+ runDeploy: () => runDeploy,
166423
+ registerTarget: () => registerTarget,
166424
+ listTargets: () => listTargets,
166425
+ getTarget: () => getTarget,
166426
+ deployVps: () => deployVps,
166427
+ deployVercel: () => deployVercel,
166428
+ deployStatic: () => deployStatic
166429
+ });
166430
+ var init_deployment = __esm(() => {
166431
+ init_deployment_core();
166432
+ init_deploy_static();
166433
+ init_deploy_vercel();
166434
+ init_deploy_vps();
166435
+ init_deploy_static();
166436
+ init_deploy_vercel();
166437
+ init_deploy_vps();
166438
+ init_deploy_cli();
166439
+ init_deployment_core();
166440
+ registerTarget(deployStatic);
166441
+ registerTarget(deployVercel);
166442
+ registerTarget(deployVps);
166443
+ });
166444
+
166445
+ // packages/omo-opencode/src/audit/self-audit.ts
166446
+ import { existsSync as existsSync79, mkdirSync as mkdirSync29, readdirSync as readdirSync17, readFileSync as readFileSync63, writeFileSync as writeFileSync29 } from "fs";
166447
+ import { join as join83 } from "path";
166448
+ function getAuditDir(cwd = process.cwd()) {
166449
+ return join83(cwd, ".matrixos", "audits");
166450
+ }
166451
+ function getWeekString(date5 = new Date) {
166452
+ const d = new Date(Date.UTC(date5.getFullYear(), date5.getMonth(), date5.getDate()));
166453
+ const dayNum = d.getUTCDay() || 7;
166454
+ d.setUTCDate(d.getUTCDate() + 4 - dayNum);
166455
+ const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
166456
+ const weekNo = Math.ceil(((+d - +yearStart) / 86400000 + 1) / 7);
166457
+ return `${d.getUTCFullYear()}-W${String(weekNo).padStart(2, "0")}`;
166458
+ }
166459
+ function parseWeekDateRange(weekStr) {
166460
+ const [year, week] = weekStr.split("-W").map(Number);
166461
+ const jan4 = new Date(Date.UTC(year, 0, 4));
166462
+ const monday = new Date(Date.UTC(year, 0, 4 - ((jan4.getUTCDay() || 7) - 1) + (week - 1) * 7));
166463
+ const sunday = new Date(+monday + 6 * 86400000);
166464
+ return { from: monday.toISOString().slice(0, 10), to: sunday.toISOString().slice(0, 10) };
166465
+ }
166466
+ function generateAuditReport(tasks, signals, weekStr) {
166467
+ const week = weekStr ?? getWeekString();
166468
+ const period = parseWeekDateRange(week);
166469
+ const summary = {
166470
+ total: tasks.length,
166471
+ done: tasks.filter((t2) => t2.status === "done").length,
166472
+ failed: tasks.filter((t2) => t2.status === "failed").length,
166473
+ inProgress: tasks.filter((t2) => t2.status === "in-progress").length,
166474
+ blocked: tasks.filter((t2) => t2.status === "blocked").length
166475
+ };
166476
+ const byProject = {};
166477
+ for (const t2 of tasks) {
166478
+ const p2 = t2.project || "default";
166479
+ byProject[p2] = byProject[p2] || { done: 0, failed: 0, blocked: 0 };
166480
+ if (t2.status === "done")
166481
+ byProject[p2].done += 1;
166482
+ if (t2.status === "failed")
166483
+ byProject[p2].failed += 1;
166484
+ if (t2.status === "blocked")
166485
+ byProject[p2].blocked += 1;
166486
+ }
166487
+ const errorCounts = new Map;
166488
+ for (const s of signals) {
166489
+ if (s.type !== "error")
166490
+ continue;
166491
+ const key = `${s.project || "global"}: ${s.message}`;
166492
+ errorCounts.set(key, (errorCounts.get(key) || 0) + (s.count || 1));
166493
+ }
166494
+ const topErrors = [...errorCounts.entries()].sort((a2, b2) => b2[1] - a2[1]).slice(0, 5).map(([message, count]) => ({ type: "error", message, count }));
166495
+ const recommendations = [];
166496
+ if (summary.failed > 0) {
166497
+ recommendations.push(`Analyser ${summary.failed} t\xE2che(s) en \xE9chec et cr\xE9er une skill/r\xE8gle par pattern r\xE9current.`);
166498
+ }
166499
+ if (summary.blocked > 0) {
166500
+ recommendations.push(`D\xE9bloquer ${summary.blocked} t\xE2che(s) bloqu\xE9es avant le prochain sprint.`);
166501
+ }
166502
+ if (topErrors.length > 0) {
166503
+ recommendations.push(`Top erreur : "${topErrors[0].message}" \u2014 prioriser un guard/automated fix.`);
166504
+ }
166505
+ if (recommendations.length === 0) {
166506
+ recommendations.push("Semaine propre. Poursuivre la veille et la documentation des d\xE9cisions.");
166507
+ }
166508
+ return { week, period, summary, byProject, topErrors, recommendations };
166509
+ }
166510
+ function formatAuditReport(report) {
166511
+ const lines = [
166512
+ `# Auto-audit hebdomadaire \u2014 ${report.week}`,
166513
+ "",
166514
+ `**P\xE9riode** : ${report.period.from} \u2192 ${report.period.to}`,
166515
+ "",
166516
+ "## R\xE9sum\xE9",
166517
+ "",
166518
+ `| M\xE9trique | Valeur |`,
166519
+ `|----------|--------|`,
166520
+ `| Total | ${report.summary.total} |`,
166521
+ `| Termin\xE9es | ${report.summary.done} |`,
166522
+ `| \xC9chou\xE9es | ${report.summary.failed} |`,
166523
+ `| En cours | ${report.summary.inProgress} |`,
166524
+ `| Bloqu\xE9es | ${report.summary.blocked} |`,
166525
+ "",
166526
+ "## Par projet",
166527
+ "",
166528
+ `| Projet | Termin\xE9es | \xC9chou\xE9es | Bloqu\xE9es |`,
166529
+ `|--------|-----------|----------|----------|`
166530
+ ];
166531
+ for (const [project, stats] of Object.entries(report.byProject).sort()) {
166532
+ lines.push(`| ${project} | ${stats.done} | ${stats.failed} | ${stats.blocked} |`);
166533
+ }
166534
+ lines.push("");
166535
+ lines.push("## Top erreurs");
166536
+ lines.push("");
166537
+ if (report.topErrors.length === 0) {
166538
+ lines.push("Aucune erreur significative cette semaine.");
166539
+ } else {
166540
+ for (const err of report.topErrors) {
166541
+ lines.push(`- **${err.count}\xD7** ${err.message}`);
166542
+ }
166543
+ }
166544
+ lines.push("");
166545
+ lines.push("## Recommandations");
166546
+ lines.push("");
166547
+ for (const rec of report.recommendations) {
166548
+ lines.push(`- ${rec}`);
166549
+ }
166550
+ lines.push("");
166551
+ return lines.join(`
166552
+ `);
166553
+ }
166554
+ function writeAuditReport(report, cwd) {
166555
+ const dir = getAuditDir(cwd);
166556
+ mkdirSync29(dir, { recursive: true });
166557
+ const path29 = join83(dir, `${report.week}.md`);
166558
+ writeFileSync29(path29, formatAuditReport(report), "utf-8");
166559
+ return path29;
166560
+ }
166561
+ var init_self_audit = () => {};
166562
+
166563
+ // packages/omo-opencode/src/cli/self-audit-command.ts
166564
+ var exports_self_audit_command = {};
166565
+ __export(exports_self_audit_command, {
166566
+ normalizeStatus: () => normalizeStatus,
166567
+ executeSelfAuditCommand: () => executeSelfAuditCommand
166568
+ });
166569
+ async function executeSelfAuditCommand(options = {}) {
166570
+ if (options.installCron) {
166571
+ const store4 = createCronStore();
166572
+ const job = store4.add({
166573
+ name: "Weekly self-audit",
166574
+ schedule: "0 22 * * 0",
166575
+ command: "matrixos self-audit",
166576
+ channel: undefined,
166577
+ recipient: undefined,
166578
+ enabled: true
166579
+ });
166580
+ return { ok: true, message: `Weekly self-audit cron job installed: ${job.id}` };
166581
+ }
166582
+ const dbPath = options.tasksDb ?? process.env.TASK_LEDGER_DB ?? "/root/.matrixos/tasks.db";
166583
+ let tasks = [];
166584
+ let signals = [];
166585
+ try {
166586
+ const rawLedger = createTaskLedger(createSqliteDatabase(dbPath));
166587
+ const since = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString();
166588
+ const allTasks = rawLedger.list?.() ?? [];
166589
+ tasks = allTasks.filter((t2) => !t2.created_at || String(t2.created_at) >= since);
166590
+ } catch (err) {
166591
+ const detail = err instanceof Error ? err.message : String(err);
166592
+ return {
166593
+ ok: false,
166594
+ message: `Could not read task ledger at ${dbPath}: ${detail}`
166595
+ };
166596
+ }
166597
+ const report = generateAuditReport(tasks.map((t2) => ({
166598
+ id: String(t2.id ?? t2.task_id ?? "unknown"),
166599
+ title: String(t2.title ?? t2.summary ?? "untitled"),
166600
+ status: normalizeStatus(t2.status),
166601
+ project: t2.project || t2.context?.project || undefined,
166602
+ errorCount: t2.error_count || t2.errorCount || 0
166603
+ })), signals, options.week);
166604
+ const path29 = writeAuditReport(report);
166605
+ return { ok: true, path: path29, message: `Self-audit written to ${path29}`, report };
166606
+ }
166607
+ function normalizeStatus(status2) {
166608
+ if (!status2)
166609
+ return "in-progress";
166610
+ const s = String(status2).toLowerCase();
166611
+ if (["done", "completed", "finished", "closed"].includes(s))
166612
+ return "done";
166613
+ if (["fail", "failed", "error"].includes(s))
166614
+ return "failed";
166615
+ if (["blocked", "stuck"].includes(s))
166616
+ return "blocked";
166617
+ if (["in-progress", "in_progress", "wip", "active"].includes(s))
166618
+ return "in-progress";
166619
+ return s;
166620
+ }
166621
+ var init_self_audit_command = __esm(() => {
166622
+ init_src6();
166623
+ init_store();
166624
+ init_self_audit();
166625
+ });
166626
+
165475
166627
  // packages/omo-opencode/src/cli/rgpd-command.ts
165476
166628
  var exports_rgpd_command = {};
165477
166629
  __export(exports_rgpd_command, {
@@ -180196,64 +181348,8 @@ async function boulder(options) {
180196
181348
  `);
180197
181349
  return 0;
180198
181350
  }
180199
- // packages/omo-opencode/src/features/cron/store.ts
180200
- init_zod();
180201
- var CronJobSchema = object({
180202
- id: string2().min(1),
180203
- name: string2().min(1).max(100),
180204
- schedule: string2().min(1).max(100),
180205
- command: string2().min(1),
180206
- channel: _enum2(["telegram", "discord", "whatsapp"]).optional(),
180207
- recipient: string2().optional(),
180208
- enabled: boolean2().default(true),
180209
- createdAt: string2(),
180210
- updatedAt: string2()
180211
- }).strict();
180212
- function createCronStore() {
180213
- const jobs = new Map;
180214
- let counter = 0;
180215
- return {
180216
- add(input) {
180217
- counter += 1;
180218
- const now = new Date().toISOString();
180219
- const job = {
180220
- id: `cron-${counter}`,
180221
- name: input.name,
180222
- schedule: input.schedule,
180223
- command: input.command,
180224
- channel: input.channel,
180225
- recipient: input.recipient,
180226
- enabled: input.enabled ?? true,
180227
- createdAt: now,
180228
- updatedAt: now
180229
- };
180230
- CronJobSchema.parse(job);
180231
- jobs.set(job.id, job);
180232
- return job;
180233
- },
180234
- get(id) {
180235
- return jobs.get(id);
180236
- },
180237
- list(filter) {
180238
- const all = Array.from(jobs.values());
180239
- return all.filter((j) => {
180240
- if (filter?.enabled !== undefined && j.enabled !== filter.enabled)
180241
- return false;
180242
- if (filter?.channel && j.channel !== filter.channel)
180243
- return false;
180244
- return true;
180245
- });
180246
- },
180247
- remove(id) {
180248
- return jobs.delete(id);
180249
- },
180250
- size() {
180251
- return jobs.size;
180252
- }
180253
- };
180254
- }
180255
-
180256
181351
  // packages/omo-opencode/src/cli/cron.ts
181352
+ init_store();
180257
181353
  var store2 = createCronStore();
180258
181354
  function cronAdd(options) {
180259
181355
  const job = store2.add({
@@ -180406,289 +181502,12 @@ function createDailyBrief(opts) {
180406
181502
  };
180407
181503
  }
180408
181504
 
180409
- // packages/task-ledger-core/src/schema.ts
180410
- init_zod();
180411
- var TaskSourceSchema = _enum2(["webhook", "cron", "user", "kanban"]);
180412
- var TaskStatusSchema = _enum2([
180413
- "pending",
180414
- "running",
180415
- "done",
180416
- "failed",
180417
- "cancelled"
180418
- ]);
180419
- var TaskPrioritySchema = _enum2(["high", "medium", "low"]);
180420
- var TaskSchema = object({
180421
- id: string2().min(1),
180422
- source: TaskSourceSchema,
180423
- context: string2().nullable(),
180424
- status: TaskStatusSchema,
180425
- priority: TaskPrioritySchema.nullable(),
180426
- payload: string2(),
180427
- agent_assigned: string2().nullable(),
180428
- session_id: string2().nullable(),
180429
- result: string2().nullable(),
180430
- cost_tokens: number2().int().nonnegative().default(0),
180431
- cost_usd: number2().nonnegative().default(0),
180432
- created_at: number2().int(),
180433
- started_at: number2().int().nullable(),
180434
- completed_at: number2().int().nullable()
180435
- }).strict();
180436
- var TaskInsertSchema = object({
180437
- id: string2().min(1).optional(),
180438
- source: TaskSourceSchema,
180439
- context: string2().nullable().optional(),
180440
- status: TaskStatusSchema.optional(),
180441
- priority: TaskPrioritySchema.nullable().optional(),
180442
- payload: string2(),
180443
- agent_assigned: string2().nullable().optional(),
180444
- session_id: string2().nullable().optional(),
180445
- cost_tokens: number2().int().nonnegative().optional(),
180446
- cost_usd: number2().nonnegative().optional()
180447
- }).strict();
180448
- var TaskPatchSchema = object({
180449
- status: TaskStatusSchema.optional(),
180450
- priority: TaskPrioritySchema.nullable().optional(),
180451
- agent_assigned: string2().nullable().optional(),
180452
- session_id: string2().nullable().optional(),
180453
- result: string2().nullable().optional(),
180454
- cost_tokens: number2().int().nonnegative().optional(),
180455
- cost_usd: number2().nonnegative().optional(),
180456
- started_at: number2().int().nullable().optional(),
180457
- completed_at: number2().int().nullable().optional()
180458
- }).strict();
180459
- var TaskFilterSchema = object({
180460
- source: TaskSourceSchema.optional(),
180461
- context: string2().optional(),
180462
- status: TaskStatusSchema.optional(),
180463
- agent_assigned: string2().optional(),
180464
- session_id: string2().optional(),
180465
- priority: TaskPrioritySchema.optional()
180466
- }).strict();
180467
-
180468
- // packages/task-ledger-core/src/ledger.ts
180469
- import { randomUUID as randomUUID2 } from "crypto";
180470
- var CREATE_TABLE_SQL = `
180471
- CREATE TABLE IF NOT EXISTS tasks (
180472
- id TEXT PRIMARY KEY,
180473
- source TEXT NOT NULL,
180474
- context TEXT,
180475
- status TEXT NOT NULL,
180476
- priority TEXT,
180477
- payload TEXT NOT NULL,
180478
- agent_assigned TEXT,
180479
- session_id TEXT,
180480
- result TEXT,
180481
- cost_tokens INTEGER DEFAULT 0,
180482
- cost_usd REAL DEFAULT 0,
180483
- created_at INTEGER NOT NULL,
180484
- started_at INTEGER,
180485
- completed_at INTEGER
180486
- )
180487
- `;
180488
- var CREATE_INDEX_STATUS = `CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status)`;
180489
- var CREATE_INDEX_CONTEXT = `CREATE INDEX IF NOT EXISTS idx_tasks_context ON tasks(context)`;
180490
- var CREATE_INDEX_SOURCE = `CREATE INDEX IF NOT EXISTS idx_tasks_source ON tasks(source)`;
180491
- var INSERT_SQL = `
180492
- INSERT INTO tasks (id, source, context, status, priority, payload, agent_assigned, session_id, result, cost_tokens, cost_usd, created_at, started_at, completed_at)
180493
- VALUES ($id, $source, $context, $status, $priority, $payload, $agent_assigned, $session_id, $result, $cost_tokens, $cost_usd, $created_at, $started_at, $completed_at)
180494
- `;
180495
- var SELECT_BY_ID_SQL = `SELECT * FROM tasks WHERE id = $id`;
180496
- var DELETE_BY_ID_SQL = `DELETE FROM tasks WHERE id = $id`;
180497
- var UPDATE_SQL = `
180498
- UPDATE tasks SET
180499
- status = COALESCE($status, status),
180500
- priority = COALESCE($priority, priority),
180501
- agent_assigned = COALESCE($agent_assigned, agent_assigned),
180502
- session_id = COALESCE($session_id, session_id),
180503
- result = COALESCE($result, result),
180504
- cost_tokens = COALESCE($cost_tokens, cost_tokens),
180505
- cost_usd = COALESCE($cost_usd, cost_usd),
180506
- started_at = COALESCE($started_at, started_at),
180507
- completed_at = COALESCE($completed_at, completed_at)
180508
- WHERE id = $id
180509
- `;
180510
- function rowToTask(row) {
180511
- return {
180512
- id: row.id,
180513
- source: row.source,
180514
- context: row.context,
180515
- status: row.status,
180516
- priority: row.priority,
180517
- payload: row.payload,
180518
- agent_assigned: row.agent_assigned,
180519
- session_id: row.session_id,
180520
- result: row.result,
180521
- cost_tokens: row.cost_tokens,
180522
- cost_usd: row.cost_usd,
180523
- created_at: row.created_at,
180524
- started_at: row.started_at,
180525
- completed_at: row.completed_at
180526
- };
180527
- }
180528
- function createTaskLedger(db) {
180529
- db.exec(CREATE_TABLE_SQL);
180530
- db.exec(CREATE_INDEX_STATUS);
180531
- db.exec(CREATE_INDEX_CONTEXT);
180532
- db.exec(CREATE_INDEX_SOURCE);
180533
- return {
180534
- insert(input) {
180535
- const now = Date.now();
180536
- const task2 = TaskSchema.parse({
180537
- id: input.id ?? randomUUID2(),
180538
- source: input.source,
180539
- context: input.context ?? null,
180540
- status: input.status ?? "pending",
180541
- priority: input.priority ?? null,
180542
- payload: input.payload,
180543
- agent_assigned: input.agent_assigned ?? null,
180544
- session_id: input.session_id ?? null,
180545
- result: null,
180546
- cost_tokens: input.cost_tokens ?? 0,
180547
- cost_usd: input.cost_usd ?? 0,
180548
- created_at: now,
180549
- started_at: null,
180550
- completed_at: null
180551
- });
180552
- db.exec(INSERT_SQL, {
180553
- $id: task2.id,
180554
- $source: task2.source,
180555
- $context: task2.context,
180556
- $status: task2.status,
180557
- $priority: task2.priority,
180558
- $payload: task2.payload,
180559
- $agent_assigned: task2.agent_assigned,
180560
- $session_id: task2.session_id,
180561
- $result: task2.result,
180562
- $cost_tokens: task2.cost_tokens,
180563
- $cost_usd: task2.cost_usd,
180564
- $created_at: task2.created_at,
180565
- $started_at: task2.started_at,
180566
- $completed_at: task2.completed_at
180567
- });
180568
- return task2;
180569
- },
180570
- get(id) {
180571
- const rows = db.query(SELECT_BY_ID_SQL, { $id: id });
180572
- if (rows.length === 0)
180573
- return null;
180574
- return rowToTask(rows[0]);
180575
- },
180576
- list(filter) {
180577
- const conditions = [];
180578
- const params = {};
180579
- if (filter?.source) {
180580
- conditions.push("source = $source");
180581
- params.$source = filter.source;
180582
- }
180583
- if (filter?.context) {
180584
- conditions.push("context = $context");
180585
- params.$context = filter.context;
180586
- }
180587
- if (filter?.status) {
180588
- conditions.push("status = $status");
180589
- params.$status = filter.status;
180590
- }
180591
- if (filter?.agent_assigned) {
180592
- conditions.push("agent_assigned = $agent_assigned");
180593
- params.$agent_assigned = filter.agent_assigned;
180594
- }
180595
- if (filter?.session_id) {
180596
- conditions.push("session_id = $session_id");
180597
- params.$session_id = filter.session_id;
180598
- }
180599
- if (filter?.priority) {
180600
- conditions.push("priority = $priority");
180601
- params.$priority = filter.priority;
180602
- }
180603
- const where = conditions.length > 0 ? ` WHERE ${conditions.join(" AND ")}` : "";
180604
- const sql = `SELECT * FROM tasks${where} ORDER BY created_at DESC`;
180605
- const rows = db.query(sql, params);
180606
- return rows.map(rowToTask);
180607
- },
180608
- update(id, patch) {
180609
- const existing = db.query(SELECT_BY_ID_SQL, { $id: id });
180610
- if (existing.length === 0)
180611
- return null;
180612
- const params = { $id: id };
180613
- if (patch.status !== undefined)
180614
- params.$status = patch.status;
180615
- if (patch.priority !== undefined)
180616
- params.$priority = patch.priority;
180617
- if (patch.agent_assigned !== undefined)
180618
- params.$agent_assigned = patch.agent_assigned;
180619
- if (patch.session_id !== undefined)
180620
- params.$session_id = patch.session_id;
180621
- if (patch.result !== undefined)
180622
- params.$result = patch.result;
180623
- if (patch.cost_tokens !== undefined)
180624
- params.$cost_tokens = patch.cost_tokens;
180625
- if (patch.cost_usd !== undefined)
180626
- params.$cost_usd = patch.cost_usd;
180627
- if (patch.started_at !== undefined)
180628
- params.$started_at = patch.started_at;
180629
- if (patch.completed_at !== undefined)
180630
- params.$completed_at = patch.completed_at;
180631
- db.exec(UPDATE_SQL, params);
180632
- return this.get(id);
180633
- },
180634
- remove(id) {
180635
- const before = db.query(SELECT_BY_ID_SQL, { $id: id });
180636
- if (before.length === 0)
180637
- return false;
180638
- db.exec(DELETE_BY_ID_SQL, { $id: id });
180639
- return true;
180640
- },
180641
- listPending() {
180642
- const rows = db.query(`SELECT * FROM tasks WHERE status = 'pending' ORDER BY created_at ASC`);
180643
- return rows.map(rowToTask);
180644
- },
180645
- listFailed() {
180646
- const rows = db.query(`SELECT * FROM tasks WHERE status = 'failed' ORDER BY created_at ASC`);
180647
- return rows.map(rowToTask);
180648
- },
180649
- listByContext(context) {
180650
- const rows = db.query(`SELECT * FROM tasks WHERE context = $context ORDER BY created_at DESC`, { $context: context });
180651
- return rows.map(rowToTask);
180652
- },
180653
- close() {
180654
- db.close();
180655
- }
180656
- };
180657
- }
180658
-
180659
- // packages/task-ledger-core/src/sqlite.ts
180660
- import { Database as Database2 } from "bun:sqlite";
180661
- function createSqliteDatabase(dbPath) {
180662
- const db = new Database2(dbPath);
180663
- db.exec("PRAGMA journal_mode = WAL");
180664
- db.exec("PRAGMA foreign_keys = ON");
180665
- return {
180666
- exec(sql, ...params) {
180667
- if (params.length === 0) {
180668
- db.run(sql);
180669
- } else {
180670
- const named = params[0];
180671
- db.run(sql, named);
180672
- }
180673
- },
180674
- query(sql, ...params) {
180675
- if (params.length === 0) {
180676
- return db.prepare(sql).all();
180677
- }
180678
- const named = params[0];
180679
- return db.prepare(sql).all(named);
180680
- },
180681
- close() {
180682
- db.close();
180683
- }
180684
- };
180685
- }
180686
-
180687
181505
  // packages/omo-opencode/src/cli/daily-brief.ts
181506
+ init_src6();
180688
181507
  async function dailyBriefSend(options) {
180689
181508
  try {
180690
181509
  const rawLedger = createTaskLedger(createSqliteDatabase(process.env.TASK_LEDGER_DB ?? "/root/.matrixos/tasks.db"));
180691
- const ledger = {
181510
+ const ledger2 = {
180692
181511
  listPending: () => rawLedger.listPending(),
180693
181512
  listFailed: () => rawLedger.list({ status: "failed" })
180694
181513
  };
@@ -180713,7 +181532,7 @@ async function dailyBriefSend(options) {
180713
181532
  recipient_id: recipient,
180714
181533
  channel
180715
181534
  }),
180716
- ledger,
181535
+ ledger: ledger2,
180717
181536
  sender,
180718
181537
  now: () => Date.now()
180719
181538
  });
@@ -186007,7 +186826,7 @@ function createDataProvider(config5) {
186007
186826
  } catch {}
186008
186827
  if (entries.length > 0)
186009
186828
  return entries;
186010
- const types15 = ["episodic", "semantic", "procedural", "reflection"];
186829
+ const types16 = ["episodic", "semantic", "procedural", "reflection"];
186011
186830
  const mockContent = [
186012
186831
  "User prefers concise responses with bullet points",
186013
186832
  "Project MaTrixOS uses Bun runtime and TypeScript strict mode",
@@ -186021,7 +186840,7 @@ function createDataProvider(config5) {
186021
186840
  entries.push({
186022
186841
  id: `mem_${randomBetween(1000, 9999)}`,
186023
186842
  content: randomChoice(mockContent),
186024
- type: randomChoice(types15),
186843
+ type: randomChoice(types16),
186025
186844
  confidence: Math.round(randomBetween(60, 99)),
186026
186845
  created_at: new Date(Date.now() - randomBetween(0, 604800000)).toISOString()
186027
186846
  });
@@ -186597,6 +187416,9 @@ function configureRuntimeCommands(program2) {
186597
187416
  init_package();
186598
187417
  var VERSION4 = package_default.version;
186599
187418
  var program2 = new Command;
187419
+ function collectParams(value, previous) {
187420
+ return previous.concat([value]);
187421
+ }
186600
187422
  function resolveInstallArgs(options, invocationName = process.env.OMO_INVOCATION_NAME) {
186601
187423
  const defaultPlatform = invocationName === "lazycodex" || invocationName === "lazycodex-ai" ? "codex" : undefined;
186602
187424
  const platform2 = options.platform ?? defaultPlatform;
@@ -186791,6 +187613,63 @@ program2.command("export [name]").description("Export a mini-OS profile as a sta
186791
187613
  process.exit(result.exitCode);
186792
187614
  });
186793
187615
  program2.addCommand(createMcpOAuthCommand());
187616
+ var project = program2.command("project").description("Manage MaTrixOS projects (active context, kanban, knowledge base)");
187617
+ project.command("create <slug>").description("Create a new project").option("-n, --name <name>", "Display name").option("-d, --description <text>", "Short description").action(async (slug, options) => {
187618
+ const { createProject: createProject2 } = await Promise.resolve().then(() => (init_project_context(), exports_project_context));
187619
+ const info = createProject2(slug, { name: options.name, description: options.description });
187620
+ process.stdout.write(JSON.stringify(info, null, 2) + `
187621
+ `);
187622
+ });
187623
+ project.command("list").alias("ls").description("List all projects").action(async () => {
187624
+ const { listProjects: listProjects2 } = await Promise.resolve().then(() => (init_project_context(), exports_project_context));
187625
+ const list = listProjects2();
187626
+ process.stdout.write(JSON.stringify(list, null, 2) + `
187627
+ `);
187628
+ });
187629
+ project.command("switch <slug>").description("Switch the active project").action(async (slug) => {
187630
+ const { switchProject: switchProject2 } = await Promise.resolve().then(() => (init_project_context(), exports_project_context));
187631
+ const info = switchProject2(slug);
187632
+ process.stdout.write(JSON.stringify(info, null, 2) + `
187633
+ `);
187634
+ });
187635
+ project.command("active").description("Show the active project").action(async () => {
187636
+ const { getActiveProject: getActiveProject2 } = await Promise.resolve().then(() => (init_project_context(), exports_project_context));
187637
+ const info = getActiveProject2();
187638
+ process.stdout.write(JSON.stringify(info ?? null, null, 2) + `
187639
+ `);
187640
+ });
187641
+ project.command("archive <slug>").description("Archive a project (removes it from the active list)").action(async (slug) => {
187642
+ const { archiveProject: archiveProject2 } = await Promise.resolve().then(() => (init_project_context(), exports_project_context));
187643
+ const info = archiveProject2(slug);
187644
+ process.stdout.write(JSON.stringify(info, null, 2) + `
187645
+ `);
187646
+ });
187647
+ project.command("unarchive <slug>").description("Unarchive a project").action(async (slug) => {
187648
+ const { unarchiveProject: unarchiveProject2 } = await Promise.resolve().then(() => (init_project_context(), exports_project_context));
187649
+ const info = unarchiveProject2(slug);
187650
+ process.stdout.write(JSON.stringify(info, null, 2) + `
187651
+ `);
187652
+ });
187653
+ project.command("delete <slug>").description("Permanently delete a project").action(async (slug) => {
187654
+ const { deleteProject: deleteProject2 } = await Promise.resolve().then(() => (init_project_context(), exports_project_context));
187655
+ deleteProject2(slug);
187656
+ process.stdout.write(JSON.stringify({ ok: true, deleted: slug }, null, 2) + `
187657
+ `);
187658
+ });
187659
+ project.command("search <query>").description("Search the active project KB and memory").option("-p, --project <slug>", "Search a specific project instead of the active one").action(async (query, options) => {
187660
+ const { searchProject: searchProject2 } = await Promise.resolve().then(() => (init_project_memory(), exports_project_memory));
187661
+ const hits = await searchProject2(query, { projectSlug: options.project });
187662
+ process.stdout.write(JSON.stringify(hits, null, 2) + `
187663
+ `);
187664
+ });
187665
+ project.command("add-doc <slug> <file>").description("Copy a document into the project KB").action(async (slug, filePath) => {
187666
+ const { addKbDocument: addKbDocument2 } = await Promise.resolve().then(() => (init_project_memory(), exports_project_memory));
187667
+ const { readFileSync: readFileSync64 } = await import("fs");
187668
+ const content = readFileSync64(filePath, "utf-8");
187669
+ const dest = addKbDocument2(slug, filePath, content);
187670
+ process.stdout.write(JSON.stringify({ ok: true, dest }, null, 2) + `
187671
+ `);
187672
+ });
186794
187673
  var gateway2 = program2.command("gateway").description("Gateway configuration \u2014 bot token management");
186795
187674
  var gatewayAdopt = gateway2.command("adopt").description("Adopt a gateway channel (Telegram, Discord, WhatsApp)");
186796
187675
  var gatewayAdoptTelegram = gatewayAdopt.command("telegram").description("Set up the Telegram gateway: prompt for bot token, validate, write .klc-gateway.env").option("-t, --token <value>", "Bot token (non-interactive)").option("-c, --chat <id>", "Restrict to a single chat id").addHelpText("after", `
@@ -186854,13 +187733,48 @@ gateway2.command("status").description("Check gateway status (best-effort, inspe
186854
187733
  }, null, 2) + `
186855
187734
  `);
186856
187735
  });
186857
- program2.command("adopt").description("Re-run the MaTrixOS adoption wizard (providers, channels, profile)").addHelpText("after", `
187736
+ program2.command("deploy <target>").description("Deploy the active project (static, vercel, vps)").option("-e, --env <env>", "Environment (staging, production, preview)", "production").option("-n, --dry-run", "Show what would happen without executing").option("-f, --force", "Skip production validation prompt").option("-r, --project-root <path>", "Override project root directory").option("-p, --param <param>", "Target-specific parameter (key=value)", collectParams, []).action(async (target, options) => {
187737
+ const { runDeploy: runDeploy2 } = await Promise.resolve().then(() => (init_deployment(), exports_deployment));
187738
+ const env5 = options.env;
187739
+ const code = await runDeploy2({
187740
+ target,
187741
+ environment: env5,
187742
+ dryRun: options.dryRun,
187743
+ force: options.force,
187744
+ projectRoot: options.projectRoot,
187745
+ params: options.param
187746
+ });
187747
+ process.exit(code);
187748
+ });
187749
+ program2.command("self-audit").description("Generate the weekly self-audit report from task ledger and scanner signals").option("-w, --week <week>", "ISO week string, e.g. 2026-W30").option("-j, --json", "Output JSON instead of markdown").option("--tasks-db <path>", "Path to the task ledger SQLite DB").option("--install-cron", "Install the weekly cron job (Sunday 22:00)").action(async (options) => {
187750
+ const { executeSelfAuditCommand: executeSelfAuditCommand2 } = await Promise.resolve().then(() => (init_self_audit_command(), exports_self_audit_command));
187751
+ const result = await executeSelfAuditCommand2(options);
187752
+ if (options.json) {
187753
+ process.stdout.write(JSON.stringify(result, null, 2) + `
187754
+ `);
187755
+ } else if (result.path) {
187756
+ console.log(`Self-audit written to ${result.path}`);
187757
+ } else {
187758
+ console.log(result.message);
187759
+ }
187760
+ process.exit(result.ok ? 0 : 1);
187761
+ });
187762
+ program2.command("adopt").description("Re-run the MaTrixOS adoption wizard (providers, channels, profile)").argument("[channel]", "optional channel to adopt (telegram). Redirects to: matrixos gateway adopt <channel>").addHelpText("after", `
186858
187763
  Examples:
186859
187764
  $ matrixos adopt # interactive re-adoption (TUI)
187765
+ $ matrixos adopt telegram # alias for: matrixos gateway adopt telegram
186860
187766
 
186861
187767
  For channel-specific setup, use:
186862
187768
  $ matrixos gateway adopt telegram
186863
- `).action(async () => {
187769
+ `).action(async (channel) => {
187770
+ if (channel) {
187771
+ const { runAdopt: runAdopt3 } = await Promise.resolve().then(() => (init_adopt(), exports_adopt));
187772
+ const result2 = await runAdopt3({ channel, nonInteractive: true });
187773
+ console.log(result2.message);
187774
+ if (!result2.ok)
187775
+ process.exit(1);
187776
+ return;
187777
+ }
186864
187778
  const { runAdopt: runAdopt2 } = await Promise.resolve().then(() => (init_adopt(), exports_adopt));
186865
187779
  const result = await runAdopt2({});
186866
187780
  if (!result.ok)